aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-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
-rw-r--r--doc/syslinux.txt12
14 files changed, 126 insertions, 150 deletions
diff --git a/NEWS b/NEWS
index 5e9be215..c7fddff5 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@ Changes in 3.81:
* Shuffler: fix bug in real-mode entry. This affected a
number of modules, probably in relatively unimportant ways,
but it completely broke linux.c32.
+ * Improved performance.
+ * Attempt to halt the processor while idle. This can cause
+ bad reponsiveness when using a serial console especially for
+ automated input; if that ends up being a problem, use the
+ new "NOHALT 1" configuration command.
Changes in 3.80:
* New shuffler mechanism and API.
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
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index 94141415..f654bffd 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -339,6 +339,7 @@ SERIAL port [[baudrate] flowcontrol]
"flowcontrol" is a combination of the following bits:
0x001 - Assert DTR
0x002 - Assert RTS
+ 0x008 - Enable interrupts
0x010 - Wait for CTS assertion
0x020 - Wait for DSR assertion
0x040 - Wait for RI assertion
@@ -366,6 +367,17 @@ SERIAL port [[baudrate] flowcontrol]
ports detected by the BIOS. They may or may not correspond to
the legacy port values 0x3F8, 0x2F8, 0x3E8, 0x2E8.
+ Enabling interrupts (setting the 0x008 bit) may give better
+ responsiveness without setting the NOHALT option, but could
+ potentially cause problems with buggy BIOSes.
+
+NOHALT flag_val
+ If flag_val is 1, don't halt the processor while idle.
+ Halting the processor while idle significantly reduces the
+ power consumption, but can cause poor responsiveness to the
+ serial console, especially when using scripts to drive the
+ serial console, as opposed to human interaction.
+
CONSOLE flag_val
If flag_val is 0, disable output to the normal video console.
If flag_val is 1, enable output to the video console (this is