aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-18 13:42:19 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-05-18 13:44:35 -0700
commit4826c90afd85d3bc8ee963de0bf1438340db865a (patch)
tree5975a83deef10ec240c35bcdafed5a168c49be55 /core
parent208721a5fa25e5a12d31e7a51488bf5ea7e2a680 (diff)
downloadsyslinux.git-4826c90afd85d3bc8ee963de0bf1438340db865a.tar.gz
syslinux.git-4826c90afd85d3bc8ee963de0bf1438340db865a.tar.xz
syslinux.git-4826c90afd85d3bc8ee963de0bf1438340db865a.zip
Try to HLT the processor during idlesyslinux-3.81-pre4
Try to HLT the processor during idle. All the events we care about should have interrupts associated with them, except possibly the serial console. Try to deal with the serial console by waiting some time before going into HLT, and giving the user the option of enabling the serial console interrupt, on the assumption that the BIOS will simply IRET. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'core')
-rw-r--r--core/comboot.inc30
-rw-r--r--core/conio.inc11
-rw-r--r--core/extlinux.asm11
-rw-r--r--core/idle.inc50
-rw-r--r--core/isolinux.asm11
-rw-r--r--core/keywords1
-rw-r--r--core/keywords.inc1
-rw-r--r--core/ldlinux.asm11
-rw-r--r--core/parseconfig.inc13
-rw-r--r--core/pxeidle.inc34
-rw-r--r--core/pxelinux.asm82
-rw-r--r--core/ui.inc4
12 files changed, 109 insertions, 150 deletions
diff --git a/core/comboot.inc b/core/comboot.inc
index 4db0b3e0..bbb0ad71 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -385,24 +385,11 @@ comboot_getchar:
;
; INT 28h - DOS idle
;
-%ifdef HAVE_IDLE
comboot_int28:
cli
cld
- pushad
- xor ax,ax
- push ds
- push es
- mov ds,ax
- mov es,ax
- DO_IDLE
- pop es
- pop ds
- popad
+ call do_idle
iret
-%else
-comboot_int28 equ comboot_iret
-%endif
;
; INT 29h - DOS fast write character
@@ -718,22 +705,11 @@ comapi_dnsresolv equ comapi_err
;
; INT 22h AX=0013h Idle call
;
-;
-; *** FIX THIS ***
-; The idle call seems to have detrimental effects on some machines when
-; called from a COM32 context (WHY?) -- disable it for now.
-; *** IS THIS STILL TRUE? ***
-;
-%ifdef HAVE_IDLE
comapi_idle:
- DO_IDLE
+ call do_idle
clc
ret
-%else
-comapi_idle equ comapi_err
-%endif
-
;
; INT 22h AX=0014h Local boot
;
@@ -1061,7 +1037,7 @@ zero_string db 0 ; Empty, null-terminated string
; in pxe_detect_nic_type
;
feature_flags:
- db 3 ; Have local boot, idle is noop
+ db 1 ; Have local boot, idle is not noop
feature_flags_len equ ($-feature_flags)
err_notdos db ': attempted DOS system call INT ',0
diff --git a/core/conio.inc b/core/conio.inc
index 8f5a2922..d1b92f54 100644
--- a/core/conio.inc
+++ b/core/conio.inc
@@ -286,7 +286,7 @@ write_serial_str:
;
pollchar:
pushad
- DO_IDLE
+ call do_idle
mov ah,11h ; Poll keyboard
int 16h
jnz .done ; Keyboard response
@@ -312,7 +312,7 @@ pollchar:
;
getchar:
.again:
- DO_IDLE
+ call do_idle
mov ah,11h ; Poll keyboard
int 16h
jnz .kbd ; Keyboard input?
@@ -330,8 +330,10 @@ getchar:
cmp al,ah
jne .again
.serial: xor ah,ah ; Avoid confusion
- xchg dx,bx ; Data port
+ mov dx,bx ; Data port
in al,dx
+ lea dx,[bx+2] ; DX -> IIR
+ in al,dx ; Read IIR to discard any IRQ bits
ret
.kbd: mov ah,10h ; Get keyboard input
int 16h
@@ -344,7 +346,7 @@ getchar:
mov bx,KbdMap ; Convert character sets
xlatb
.func_key:
- RESET_IDLE ; Character received
+ call reset_idle ; Character received
ret
%ifdef DEBUG_TRACERS
@@ -392,6 +394,7 @@ FlowControl equ $
FlowOutput resb 1 ; Outputs to assert for serial flow
FlowInput resb 1 ; Input bits for serial flow
FlowIgnore resb 1 ; Ignore input unless these bits set
+FlowDummy resb 1 ; Unused
TextAttribute resb 1 ; Text attribute for message file
DisplayMask resb 1 ; Display modes mask
diff --git a/core/extlinux.asm b/core/extlinux.asm
index d54bad51..46faac55 100644
--- a/core/extlinux.asm
+++ b/core/extlinux.asm
@@ -47,16 +47,6 @@ ROOT_DIR_WORD equ 0x002F
CUR_DIR_DWORD equ 0x00002F2E
;
-; This is what we need to do when idle
-;
-%macro RESET_IDLE 0
- ; Nothing
-%endmacro
-%macro DO_IDLE 0
- ; Nothing
-%endmacro
-
-;
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
@@ -891,6 +881,7 @@ build_curdir_str:
%include "strcpy.inc" ; strcpy()
%include "strecpy.inc" ; strcpy with end pointer check
%include "cache.inc" ; Metadata disk cache
+%include "idle.inc" ; Idle handling
%include "adv.inc" ; Auxillary Data Vector
%include "localboot.inc" ; Disk-based local boot
diff --git a/core/idle.inc b/core/idle.inc
new file mode 100644
index 00000000..c2ce1348
--- /dev/null
+++ b/core/idle.inc
@@ -0,0 +1,50 @@
+;; -*- fundamental -*- ---------------------------------------------------
+;;
+;; Copyright 2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+;; Boston MA 02110-1301, USA; either version 2 of the License, or
+;; (at your option) any later version; incorporated herein by reference.
+;;
+;; -----------------------------------------------------------------------
+
+ section .text
+TICKS_TO_IDLE equ 4
+
+reset_idle:
+ push ax
+ mov ax,[cs:BIOS_timer]
+ mov [cs:IdleTimer],ax
+ pop ax
+ ret
+
+do_idle:
+ push ax
+ push ds
+ push es
+ mov ax,cs
+ mov ds,ax
+ mov es,ax
+ mov ax,[BIOS_timer]
+ sub ax,[IdleTimer]
+ cmp ax,TICKS_TO_IDLE
+ jb .done
+ call [IdleHook]
+ cmp word [NoHalt],0
+ jne .done
+ hlt
+.done:
+ pop es
+ pop ds
+ pop ax
+.ret: ret
+
+ section .data
+NoHalt dw 0
+IdleHook dw do_idle.ret
+
+ section .bss
+IdleTimer resw 1
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 62b1a9ce..cc97f479 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -40,16 +40,6 @@ SECTOR_SIZE equ (1 << SECTOR_SHIFT)
ROOT_DIR_WORD equ 0x002F
;
-; This is what we need to do when idle
-;
-%macro RESET_IDLE 0
- ; Nothing
-%endmacro
-%macro DO_IDLE 0
- ; Nothing
-%endmacro
-
-;
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
@@ -1707,6 +1697,7 @@ getfssec:
%include "highmem.inc" ; High memory sizing
%include "strcpy.inc" ; strcpy()
%include "rawcon.inc" ; Console I/O w/o using the console functions
+%include "idle.inc" ; Idle handling
%include "adv.inc" ; Auxillary Data Vector
%include "localboot.inc" ; Disk-based local boot
diff --git a/core/keywords b/core/keywords
index aeafb96d..c289ae29 100644
--- a/core/keywords
+++ b/core/keywords
@@ -32,6 +32,7 @@ ontimeout
onerror
noescape
nocomplete
+nohalt
f0
f1
f2
diff --git a/core/keywords.inc b/core/keywords.inc
index 4923441f..d0f7db36 100644
--- a/core/keywords.inc
+++ b/core/keywords.inc
@@ -77,6 +77,7 @@ keywd_table:
keyword allowoptions, pc_setint16, AllowOptions
keyword noescape, pc_setint16, NoEscape
keyword nocomplete, pc_setint16, NoComplete
+ keyword nohalt, pc_setint16, NoHalt
keyword f1, pc_filename, FKeyN(1)
keyword f2, pc_filename, FKeyN(2)
keyword f3, pc_filename, FKeyN(3)
diff --git a/core/ldlinux.asm b/core/ldlinux.asm
index 4da9c153..ba7e8040 100644
--- a/core/ldlinux.asm
+++ b/core/ldlinux.asm
@@ -51,16 +51,6 @@ DIRENT_SIZE equ (1 << DIRENT_SHIFT)
ROOT_DIR_WORD equ 0x002F
;
-; This is what we need to do when idle
-;
-%macro RESET_IDLE 0
- ; Nothing
-%endmacro
-%macro DO_IDLE 0
- ; Nothing
-%endmacro
-
-;
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
@@ -1385,6 +1375,7 @@ getfatsector:
%include "highmem.inc" ; High memory sizing
%include "strcpy.inc" ; strcpy()
%include "cache.inc" ; Metadata disk cache
+%include "idle.inc" ; Idle handling
%include "adv.inc" ; Auxillary Data Vector
%include "localboot.inc" ; Disk-based local boot
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
index fd1c6511..61e7b330 100644
--- a/core/parseconfig.inc
+++ b/core/parseconfig.inc
@@ -178,9 +178,8 @@ pc_include: inc word [IncludeLevel]
pc_serial: call getint
jc .err
push bx ; Serial port #
- xor ax,ax
- mov [FlowControl],ax ; Default to no flow control
- mov [FlowIgnore],al
+ xor eax,eax
+ mov [FlowControl],eax ; Default to no flow control
call skipspace
jc .nobaud
call ungetc
@@ -200,7 +199,7 @@ pc_serial: call getint
shl bh,4
mov [FlowIgnore],bh
mov bh,bl
- and bx,0F003h ; Valid bits
+ and bx,0F00Bh ; Valid bits
mov [FlowControl],bx
pop ebx ; Baud rate
jmp short .parse_baud
@@ -247,7 +246,8 @@ pc_serial: call getint
jne .err ; Assume serial port busted
dec dx
dec dx ; DX -> IER
- xor al,al ; IRQ disable
+ test byte [FlowOutput],8
+ setnz al ; Bit 0 -> input available IRQ
call slow_out
inc dx ; DX -> FCR/IIR
@@ -262,8 +262,7 @@ pc_serial: call getint
inc dx
inc dx ; DX -> MCR
- in al,dx
- or al,[FlowOutput] ; Assert bits
+ mov al,[FlowOutput] ; Assert bits
call slow_out
; Show some life
diff --git a/core/pxeidle.inc b/core/pxeidle.inc
index 0e0e8b28..f661b57a 100644
--- a/core/pxeidle.inc
+++ b/core/pxeidle.inc
@@ -1,6 +1,7 @@
;; -*- fundamental -*- ---------------------------------------------------
;;
;; Copyright 2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -48,7 +49,7 @@ pxe_detect_nic_type:
ret
.found_device:
- and byte [feature_flags],~2
+ mov word [IdleHook],check_for_arp
jmp .done
;;
@@ -90,3 +91,34 @@ pxenv_get_nic_type:
.sdid: resw 1
section .text
+;
+; Call the receive loop while idle. This is done mostly so we can respond to
+; ARP messages, but perhaps in the future this can be used to do network
+; console.
+;
+; hpa sez: people using automatic control on the serial port get very
+; unhappy if we poll for ARP too often (the PXE stack is pretty slow,
+; typically.) Therefore, only poll if at least 4 BIOS timer ticks have
+; passed since the last poll, and reset this when a character is
+; received (call reset_idle).
+;
+; Note: we only do this if pxe_detect_nic_type has set the IdleHook
+; to point to this routine.
+;
+check_for_arp:
+ pushad
+ mov di,packet_buf
+ 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
+ mov eax,[MyIP]
+ mov [pxe_udp_read_pkt.dip],eax
+ mov word [pxe_udp_read_pkt.lport],htons(9) ; discard port
+ mov di,pxe_udp_read_pkt
+ mov bx,PXENV_UDP_READ
+ call pxenv
+ ; Ignore result...
+ pop es
+ pop ds
+ popad
+ ret
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 3a73e103..ad1686c1 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -53,24 +53,6 @@ TFTP_BLOCKSIZE equ (1 << TFTP_BLOCKSIZE_LG2)
SECTOR_SHIFT equ TFTP_BLOCKSIZE_LG2
SECTOR_SIZE equ TFTP_BLOCKSIZE
-%define HAVE_IDLE 1 ; idle is not a noop
-
-%if HAVE_IDLE
-%macro RESET_IDLE 0
- call reset_idle
-%endmacro
-%macro DO_IDLE 0
- call check_for_arp
-%endmacro
-%else
-%macro RESET_IDLE 0
- ; Nothing
-%endmacro
-%macro DO_IDLE 0
- ; Nothing
-%endmacro
-%endif
-
;
; TFTP operation codes
;
@@ -195,7 +177,6 @@ PXEStack resd 1 ; Saved stack during PXE call
RebootTime resd 1 ; Reboot timeout, if set by option
StrucPtr resd 1 ; Pointer to PXENV+ or !PXE structure
APIVer resw 1 ; PXE API version found
-IdleTimer resw 1 ; Time to check for ARP?
LocalBootType resw 1 ; Local boot return code
RealBaseMem resw 1 ; Amount of DOS memory after freeing
OverLoad resb 1 ; Set if DHCP packet uses "overloading"
@@ -619,7 +600,7 @@ udp_init:
; Detect NIC type and initialize the idle mechanism
;
call pxe_detect_nic_type
- RESET_IDLE
+ call reset_idle
;
; Now we're all set to start with our *real* business. First load the
@@ -2546,64 +2527,6 @@ genipopt:
popad
ret
-;
-; Call the receive loop while idle. This is done mostly so we can respond to
-; ARP messages, but perhaps in the future this can be used to do network
-; console.
-;
-; hpa sez: people using automatic control on the serial port get very
-; unhappy if we poll for ARP too often (the PXE stack is pretty slow,
-; typically.) Therefore, only poll if at least 4 BIOS timer ticks have
-; 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:
- push ax
- mov ax,[cs:BIOS_timer]
- mov [cs:IdleTimer],ax
- pop ax
- 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
-.need_poll: pushad
- push ds
- push es
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov di,packet_buf
- 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
- mov eax,[MyIP]
- mov [pxe_udp_read_pkt.dip],eax
- mov word [pxe_udp_read_pkt.lport],htons(9) ; discard port
- mov di,pxe_udp_read_pkt
- mov bx,PXENV_UDP_READ
- call pxenv
- ; Ignore result...
- pop es
- pop ds
- popad
- RESET_IDLE
- ret
-
-%endif ; HAVE_IDLE
-
; -----------------------------------------------------------------------------
; Common modules
; -----------------------------------------------------------------------------
@@ -2624,7 +2547,8 @@ writestr_early equ writestr
%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 "idle.inc" ; Idle handling
+%include "pxeidle.inc" ; PXE-specific idle mechanism
%include "adv.inc" ; Auxillary Data Vector
; -----------------------------------------------------------------------------
diff --git a/core/ui.inc b/core/ui.inc
index c85383a6..a12233c2 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -523,7 +523,7 @@ kernel_corrupt: mov si,err_notkernel
;
getchar_timeout:
call vgashowcursor
- RESET_IDLE
+ call reset_idle
.loop:
push word [BIOS_timer]
@@ -532,7 +532,7 @@ getchar_timeout:
pop ax
cmp ax,[BIOS_timer] ; Has the timer advanced?
je .loop
- DO_IDLE
+ call do_idle
dec dword [ThisKbdTo]
jz .timeout