Merge branch 'master' into core32
authorH. Peter Anvin <hpa@zytor.com>
Sun, 24 May 2009 02:44:46 +0000 (19:44 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Sun, 24 May 2009 02:45:46 +0000 (19:45 -0700)
Conflicts:
core/bcopy32.inc
core/cleanup.inc
core/conio.inc

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
1  2 
core/cleanup.inc
core/conio.inc
core/head.inc
core/layout.inc
core/parseconfig.inc
core/serirq.inc

@@@ -49,8 -49,7 +49,10 @@@ cleanup_hardware
                int 10h
  .no_vmware:
  %endif
 +
 +              call comboot_cleanup_api
 +
                popad
-               ret
+               ; If we enabled serial port interrupts, clean them up now
+               jmp sirq_cleanup
diff --cc core/conio.inc
@@@ -387,15 -412,20 +412,21 @@@ ScreenSize      equ 
  VidCols         resb 1                        ; Columns on screen-1
  VidRows         resb 1                        ; Rows on screen-1
  
- ; Serial console stuff...
- BaudDivisor   resw 1                  ; Baud rate divisor
+ ; Serial console stuff; don't put this in .config becasue we don't want
+ ; loading a new config file to undo this setting.
 -              section .data
 -              alignz 4
++              section .data16
++              alignb 4
+ SerialPort    dw 0                    ; Serial port base (or 0 for no serial port)
+ BaudDivisor   dw 115200/9600          ; Baud rate divisor
  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
+ FlowOutput    db 0                    ; Outputs to assert for serial flow
+ FlowInput     db 0                    ; Input bits for serial flow
+ FlowIgnore    db 0                    ; Ignore input unless these bits set
+ FlowDummy     db 0                    ; Unused
  
 -              section .bss
++              section .bss16
  TextAttribute   resb 1                        ; Text attribute for message file
  DisplayMask   resb 1                  ; Display modes mask
  
 +              section .text16
+ %include "serirq.inc"
diff --cc core/head.inc
Simple merge
diff --cc core/layout.inc
@@@ -91,19 -89,19 +91,23 @@@ RBFG_brainfuck:    resb 2048               ; Bigger tha
  ; failure!
  ;
  ; 0000h - main code/data segment (and BIOS segment)
 -
 -xfer_buf_seg  equ 1000h
 -aux_seg               equ 2000h
 +;
 +; This stuff really should come from the linker...
 +;
 +              global  xfer_buf_seg
 +xfer_buf_seg  equ 2000h
  
+ serial_buf_size       equ 4096                ; Should be a power of 2
  ;
  ; Contents of aux_seg
  ;
 +              extern aux_seg          ; Actual segment assigned by linker
 +
                struc aux
  .fontbuf      resb 8192
+ .serial               resb serial_buf_size
                alignb 4096             ; Align the next segment to 4K
                endstruc
  
Simple merge
diff --cc core/serirq.inc
index 0000000,579c42b..a0cf9bf
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,191 +1,191 @@@
 -              section .text
+ ;; -----------------------------------------------------------------------
+ ;;
+ ;;   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., 53 Temple Place Ste 330,
+ ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
+ ;;   (at your option) any later version; incorporated herein by reference.
+ ;;
+ ;; -----------------------------------------------------------------------
+ ;;
+ ;; serirq.inc
+ ;;
+ ;; Serial port IRQ code
+ ;;
+ ;; We don't know what IRQ, if any, we have, so map all of them...
+ ;;
 -              section .bss
++              section .text16
+               bits 16
+               align 8
 -              section .text
++              section .bss16
+               alignb 8
+ %assign n 0
+ %rep 16
 -              section .bss
++              section .text16
+ serstub_irq %+ n :
+               push dword [cs:oldirq %+ n]
+               jmp short irq_common
 -              section .text
++              section .bss16
+ oldirq %+ n   resd 1
+ %assign n n+1
+ %endrep
 -              section .data
++              section .text16
+ irq_common:
+               pushf
+               push ax
+               push dx
+               mov dx,[cs:SerialPort]
+               add dx,5                        ; DX -> LSR
+               in al,dx
+               test al,1                       ; Received data
+               jnz .data
+ .done:
+               pop dx
+               pop ax
+               popf
+               retf                            ; Chain to next handler
+ .data:
+               push es
+               push di
+               mov ax,aux_seg + (aux.serial >> 4)
+               mov es,ax
+               mov di,[cs:SerialHead]
+ .loop:
+               mov dx,[cs:SerialPort]          ; DX -> RDR
+               in al,dx
+               stosb
+               mov ah,[cs:FlowIgnore]
+               add dx,5                        ; DX -> LSR
+               in al,dx
+               push ax
+               and al,ah
+               cmp al,ah
+               jne .drop
+               and di,serial_buf_size-1        ; Wrap around if necessary
+               cmp di,[cs:SerialTail]          ; Would this cause overflow?
+               je .drop                        ; If so, just drop the data
+               mov [cs:SerialHead],di
+ .drop:
+               pop ax
+               test al,1                       ; More data?
+               jnz .loop
+ .full:
+               pop di
+               pop es
+               jmp .done
 -SerialIRQPort dw 0                    ; Serial port w IRQ service
 -SerialHead    dw 0                    ; Head of serial port rx buffer
 -SerialTail    dw 0                    ; Tail of serial port rx buffer
++              section .bss16
+ ;
+ ; SerialIRQPort will generally track SerialPort, but will be 0 when an
+ ; IRQ service is not installed.
+ ;
 -              section .text
++SerialIRQPort resw 1                  ; Serial port w IRQ service
++SerialHead    resw 1                  ; Head of serial port rx buffer
++SerialTail    resw 1                  ; Tail of serial port rx buffer
 -              section .text
++              section .text16
+ sirq_install:
+               pushad
+               call sirq_cleanup
+               ; Save the old interrupt vectors
+               mov si,4*08h
+               mov di,oldirq0
+               mov cx,8
+               rep movsd
+               mov si,4*70h
+               mov cx,8
+               rep movsd
+               ; Install new interrupt vectors
+               mov di,4*08h
+               mov cx,8
+               mov eax,serstub_irq0
+ .pic0:
+               stosd
+               add ax,serstub_irq1 - serstub_irq0
+               loop .pic0
+               mov di,4*70h
+               mov cx,8
+ .pic1:
+               stosd
+               add ax,serstub_irq1 - serstub_irq0
+               loop .pic1
+               mov bx,[SerialPort]
+               mov [SerialIRQPort],bx
+               lea dx,[bx+5]           ; DX -> LCR
+               mov al,03h              ; Clear DLAB (should already be...)
+               slow_out dx,al
+               lea dx,[bx+1]           ; DX -> IER
+               mov al,1                ; Enable receive interrupt
+               slow_out dx,al
+               popad
+               ret
+ sirq_cleanup_nowipe:
+               pushad
+               push ds
+               push es
+               xor ax,ax
+               mov ds,ax
+               mov es,ax
+               mov bx,[SerialIRQPort]
+               and bx,bx
+               jz .done
+               lea dx,[bx+5]           ; DX -> LCR
+               mov al,03h              ; Clear DLAB (should already be...)
+               slow_out dx,al
+               lea dx,[bx+1]           ; DX -> IER
+               xor ax,ax
+               slow_out dx,al          ; Clear IER
+               ; Restore the original interrupt vectors
+               mov si,oldirq0
+               mov di,4*08h
+               mov cx,8
+               rep movsd
+               mov di,4*70h
+               mov cx,8
+               rep movsd
+ .done:
+               pop es
+               pop ds
+               popad
+               ret
+ sirq_cleanup:
+               call sirq_cleanup_nowipe
+               pushad
+               push es
+               ; Just in case it might contain a password, erase the
+               ; serial port receive buffer...
+               mov ax,aux_seg + (aux.serial >> 4)
+               mov es,ax
+               xor eax,eax
+               mov [cs:SerialHead],eax
+               mov cx,serial_buf_size >> 2
+               xor di,di
+               rep stosd
+               pop es
+               popad
+               ret
++              section .text16