PXELINUX: Enable idle calls on select platforms
authorH. Peter Anvin <hpa@zytor.com>
Mon, 9 Jun 2008 23:16:31 +0000 (16:16 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 9 Jun 2008 23:16:31 +0000 (16:16 -0700)
Enable idle calls on select platforms, based on device ID.
In particular, certain Broadcom chips need them to avoid FIFO stalls.

core/comboot.inc
core/conio.inc
core/pxelinux.asm

index df9bb00..b843372 100644 (file)
@@ -971,14 +971,12 @@ zero_string       db 0                    ; Empty, null-terminated string
 
 ;
 ; This is the feature flag array for INT 22h AX=0015h
+;
+; Note: PXELINUX clears the idle is noop flag if appropriate
+; in pxe_detect_nic_type
+;
 feature_flags:
-%if IS_PXELINUX
-               db 1                    ; Have local boot, idle not noop
-%elif IS_ISOLINUX
                db 3                    ; Have local boot, idle is noop
-%else
-               db 2                    ; No local boot, idle is noop
-%endif
 feature_flags_len equ ($-feature_flags)
 
 err_notdos     db ': attempted DOS system call', CR, LF, 0
index 4700596..0dc3f1d 100644 (file)
@@ -282,6 +282,7 @@ write_serial_str:
 ;
 pollchar:
                pushad
+               DO_IDLE
                mov ah,11h              ; Poll keyboard
                int 16h
                jnz .done               ; Keyboard response
@@ -306,7 +307,6 @@ pollchar:
 ; getchar: Read a character from keyboard or serial port
 ;
 getchar:
-               RESET_IDLE
 .again:
                DO_IDLE
                mov ah,11h              ; Poll keyboard
@@ -339,7 +339,9 @@ getchar:
                jz .func_key
                mov bx,KbdMap           ; Convert character sets
                xlatb
-.func_key:     ret
+.func_key:
+               RESET_IDLE              ; Character received
+               ret
 
 %ifdef DEBUG_TRACERS
 ;
index fccf82f..9e2d2fb 100644 (file)
@@ -54,12 +54,7 @@ TFTP_BLOCKSIZE       equ (1 << TFTP_BLOCKSIZE_LG2)
 SECTOR_SHIFT   equ TFTP_BLOCKSIZE_LG2
 SECTOR_SIZE    equ TFTP_BLOCKSIZE
 
-;
-; This is what we need to do when idle
-; *** This is disabled because some PXE stacks wait for unacceptably
-; *** long if there are no packets receivable.
-
-%define HAVE_IDLE 0                    ; idle is not a noop
+%define HAVE_IDLE 1                    ; idle is not a noop
 
 %if HAVE_IDLE
 %macro RESET_IDLE 0
@@ -651,6 +646,12 @@ udp_init:
 ;
 %include "cpuinit.inc"
 
+;
+; Detect NIC type and initialize the idle mechanism
+;
+               call pxe_detect_nic_type
+               RESET_IDLE
+
 ;
 ; Now we're all set to start with our *real* business. First load the
 ; configuration file (if any) and parse it.
@@ -1091,7 +1092,6 @@ searchdir:
                mov bx,[bx]
                push bx                 ; [bp-8]  - TID (local port no)
 
-               mov [pxe_udp_write_pkt.status],byte 0
                mov [pxe_udp_write_pkt.sip],eax
                ; Now figure out the gateway
                xor eax,[MyIP]
@@ -1127,7 +1127,6 @@ searchdir:
 
 .pkt_loop:     mov bx,[bp-8]           ; TID
                mov di,packet_buf
-               mov word [pxe_udp_read_pkt.status],0
                mov [pxe_udp_read_pkt.buffer],di
                mov [pxe_udp_read_pkt.buffer+2],ds
                mov word [pxe_udp_read_pkt.buffersize],packet_buf_size
@@ -1691,6 +1690,9 @@ pxenv:
                mov [cs:PXEStack+2],ss
                lss sp,[cs:InitStack]
 %endif
+               ; Pre-clear the Status field
+               mov word [es:di],cs
+
                ; This works either for the PXENV+ or the !PXE calling
                ; convention, as long as we ignore CF (which is redundant
                ; with AX anyway.)
@@ -2621,6 +2623,9 @@ genipopt:
 ; passed since the last poll, and reset this when a character is
 ; received (RESET_IDLE).
 ;
+; Note: we only do this if pxe_detect_nic_type has cleared the
+; "idle is noop" bit in feature_flags.
+;
 %if HAVE_IDLE
 
 reset_idle:
@@ -2631,13 +2636,15 @@ reset_idle:
                ret
 
 check_for_arp:
+               test byte [cs:feature_flags],2
+               jnz .ret
                push ax
                mov ax,[cs:BIOS_timer]
                sub ax,[cs:IdleTimer]
                cmp ax,4
                pop ax
                jae .need_poll
-               ret
+.ret:          ret
 .need_poll:    pushad
                push ds
                push es
@@ -2645,7 +2652,6 @@ check_for_arp:
                mov ds,ax
                mov es,ax
                mov di,packet_buf
-               mov [pxe_udp_read_pkt.status],al        ; 0
                mov [pxe_udp_read_pkt.buffer],di
                mov [pxe_udp_read_pkt.buffer+2],ds
                mov word [pxe_udp_read_pkt.buffersize],packet_buf_size
@@ -2684,6 +2690,7 @@ writestr  equ cwritestr
 %include "strcpy.inc"          ; strcpy()
 %include "rawcon.inc"          ; Console I/O w/o using the console functions
 %include "dnsresolv.inc"       ; DNS resolver
+%include "pxeidle.inc"         ; Idle mechanism
 %include "adv.inc"             ; Auxillary Data Vector
 
 ; -----------------------------------------------------------------------------