summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/PC/BIOS/orgs.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/PC/BIOS/orgs.asm')
-rw-r--r--src/VBox/Devices/PC/BIOS/orgs.asm259
1 files changed, 172 insertions, 87 deletions
diff --git a/src/VBox/Devices/PC/BIOS/orgs.asm b/src/VBox/Devices/PC/BIOS/orgs.asm
index 4d455b85..a380ea2f 100644
--- a/src/VBox/Devices/PC/BIOS/orgs.asm
+++ b/src/VBox/Devices/PC/BIOS/orgs.asm
@@ -126,6 +126,7 @@ extrn _ata_detect:near
extrn _cdemu_init:near
extrn _keyboard_init:near
extrn _print_bios_banner:near
+extrn _inv_op_handler:near
;; Symbols referenced from C code
@@ -214,22 +215,42 @@ eoi_master_pic:
out PIC_MASTER, al
ret
+ ;; routine to write the pointer in DX:AX to memory starting
+ ;; at DS:BX (repeat CX times)
+ ;; - modifies BX, CX
+set_int_vects proc near
+
+ mov [bx], ax
+ mov [bx+2], dx
+ add bx, 4
+ loop set_int_vects
+ ret
+
+set_int_vects endp
+
;; --------------------------------------------------------
;; POST entry point
;; --------------------------------------------------------
BIOSORG 0E05Bh
post:
- xor ax, ax
-
- ;; reset the DMA controllers
- out 00Dh, al
- out 0DAh, al
+ cli
- ;; then initialize the DMA controllers
- mov al, 0C0h
- out 0D6h, al ; enable channel 4 cascade
- mov al, 0
- out 0D4h, al ; unmask channel 4
+ ;; Check if in protected (V86) mode. If so, the CPU needs
+ ;; to be reset.
+ smsw ax
+ test ax, 1
+ jz in_real_mode
+
+ ;; Reset processor to get out of protected mode. Use system
+ ;; port instead of KBC.
+ ;; NB: We only need bit 0 to be set in AL, which we just
+ ;; determined to be the case.
+ out 92h, al
+ jmp $ ; not strictly necessary in a VM
+
+
+in_real_mode:
+ ;; TODO: Check KBC system flag first
;; read the CMOS shutdown status
mov al, 0Fh
@@ -237,7 +258,7 @@ post:
in al, CMOS_DATA
;; save status
- mov bl, al
+ xchg ah, al
;; reset the shutdown status in CMOS
mov al, 0Fh
@@ -245,14 +266,38 @@ post:
mov al, 0
out CMOS_DATA, al
+ ;; pre-check the shutdown status - shutdown codes 9/A leave
+ ;; the hardware alone
+ mov al, ah
+ cmp al, 09h
+ jz check_shutdown
+ cmp al, 0Ah
+ jz check_shutdown
+
+ xor al, al
+
+ ;; reset the DMA controllers
+ out 00Dh, al
+ out 0DAh, al
+
+ ;; then initialize the DMA controllers
+ mov al, 0C0h
+ out 0D6h, al ; enable channel 4 cascade
+ mov al, 0
+ out 0D4h, al ; unmask channel 4
+
+check_shutdown:
;; examine the shutdown status code
- mov al, bl
+ mov al, ah
cmp al, 0
jz normal_post
+
cmp al, 0Dh
jae normal_post
cmp al, 9
- je normal_post ;; TODO: really?!
+ jne check_next_std
+ jmp return_blkmove
+check_next_std:
;; 05h = EOI + jump through 40:67
cmp al, 5
@@ -262,23 +307,9 @@ post:
;; OpenSolaris sets the status to 0Ah in some cases?
jmp normal_post
-
- ;; routine to write the pointer in DX:AX to memory starting
- ;; at DS:BX (repeat CX times)
- ;; - modifies BX, CX
-set_int_vects proc near
-
- mov [bx], ax
- mov [bx+2], dx
- add bx, 4
- loop set_int_vects
- ret
-
-set_int_vects endp
-
normal_post:
;; shutdown code 0: normal startup
- cli
+
;; Set up the stack top at 0:7800h. The stack should not be
;; located above 0:7C00h; that conflicts with PXE, which
;; considers anything above that address to be fair game.
@@ -350,6 +381,7 @@ memory_cleared:
;; set up various service vectors
;; TODO: This should use the table at FEF3h instead
+ SET_INT_VECTOR 06h, BIOSSEG, int06_handler
SET_INT_VECTOR 11h, BIOSSEG, int11_handler
SET_INT_VECTOR 12h, BIOSSEG, int12_handler
SET_INT_VECTOR 15h, BIOSSEG, int15_handler
@@ -461,43 +493,7 @@ memory_cleared:
call rom_scan
- C_SETUP
- ;; ATA/ATAPI driver setup
- call _ata_init
- call _ata_detect
-
-ifdef VBOX_WITH_AHCI
- ; AHCI driver setup
- call _ahci_init
-endif
-
-ifdef VBOX_WITH_SCSI
- ; SCSI driver setup
- call _scsi_init
-endif
-
- ;; floppy setup
- call floppy_post
-
- ;; hard drive setup
- call hard_drive_post
-
- C_SETUP ; in case assembly code changed things
- call _print_bios_banner
-
- ;; El Torito floppy/hard disk emulation
- call _cdemu_init
-
- ; TODO: what's the point of enabling interrupts here??
- sti ; enable interrupts
- int 19h
- ;; does not return here
- sti
-wait_forever:
- hlt
- jmp wait_forever
- cli
- hlt
+ jmp norm_post_cont
;; --------------------------------------------------------
@@ -518,11 +514,6 @@ int75_handler:
hard_drive_post proc near
- ;; TODO Why? And what about secondary controllers?
- mov al, 0Ah ; disable IRQ 14
- mov dx, 03F6h
- out dx, al
-
xor ax, ax
mov ds, ax
;; TODO: Didn't we just clear the entire EBDA?
@@ -546,6 +537,78 @@ hard_drive_post proc near
hard_drive_post endp
+norm_post_cont:
+ C_SETUP
+ ;; ATA/ATAPI driver setup
+ call _ata_init
+ call _ata_detect
+
+ifdef VBOX_WITH_AHCI
+ ; AHCI driver setup
+ call _ahci_init
+endif
+
+ifdef VBOX_WITH_SCSI
+ ; SCSI driver setup
+ call _scsi_init
+endif
+
+ ;; floppy setup
+ call floppy_post
+
+ ;; hard drive setup
+ call hard_drive_post
+
+ C_SETUP ; in case assembly code changed things
+ call _print_bios_banner
+
+ ;; El Torito floppy/hard disk emulation
+ call _cdemu_init
+
+ ; TODO: what's the point of enabling interrupts here??
+ sti ; enable interrupts
+ int 19h
+ ;; does not return here
+ sti
+wait_forever:
+ hlt
+ jmp wait_forever
+ cli
+ hlt
+
+
+;;
+;; Return from block move (shutdown code 09h). Care must be taken to disturb
+;; register and memory state as little as possible.
+;;
+return_blkmove:
+ mov ax, 40h
+ mov ds, ax
+ ;; restore user stack
+ mov ss, ds:[69h]
+ mov sp, ds:[67h]
+ ;; reset A20 gate
+ in al, 92h
+ and al, 0FDh
+ out 92h, al
+ ;; ensure proper real mode IDT
+ lidt fword ptr cs:_rmode_IDT
+ ;; restore user segments
+ pop ds
+ pop es
+ ;; set up BP
+ mov bp, sp
+ ;; restore status code
+ in al, 80h
+ mov [bp+15], al
+ ;; set ZF/CF
+ cmp ah,al ; AH is zero here!
+ ;; restore registers and return
+ popa
+ sti
+ retf 2
+
+
;; --------------------------------------------------------
;; INT 13h handler - Disk services
;; --------------------------------------------------------
@@ -917,6 +980,21 @@ int09_finish:
;; --------------------------------------------------------
+;; INT 06h handler - Invalid Opcode Exception
+;; --------------------------------------------------------
+
+int06_handler:
+ pusha
+ push es
+ push ds
+ C_SETUP
+ call _inv_op_handler
+ pop ds
+ pop es
+ popa
+ iret
+
+;; --------------------------------------------------------
;; INT 13h handler - Diskette service
;; --------------------------------------------------------
BIOSORG 0EC59h
@@ -1536,6 +1614,8 @@ int15_handler:
je int15_handler32
cmp ah, 0E8h
je int15_handler32
+ cmp ah, 0d0h
+ je int15_handler32
pusha
cmp ah, 53h ; APM function?
je apm_call
@@ -1700,23 +1780,11 @@ int08_handler:
sti
push eax
push ds
- xor ax, ax
- mov ds, ax
-
- ;; time to turn off floppy driv motor(s)?
- mov al, ds:[440h]
- or al, al
- jz int08_floppy_off
- ;; turn motor(s) off
push dx
- mov dx, 03F2h
- in al, dx
- and al, 0CFh
- out dx, al
- pop dx
+ mov ax, 40h
+ mov ds, ax
-int08_floppy_off:
- mov eax, ds:[46Ch] ; get ticks dword
+ mov eax, ds:[6Ch] ; get ticks dword
inc eax
;; compare eax to one day's worth of ticks (at 18.2 Hz)
@@ -1724,13 +1792,30 @@ int08_floppy_off:
jb int08_store_ticks
;; there has been a midnight rollover
xor eax, eax
- inc byte ptr ds:[470h] ; increment rollover flag
+ inc byte ptr ds:[70h] ; increment rollover flag
int08_store_ticks:
- mov ds:[46Ch], eax
+ mov ds:[6Ch], eax
+
+ ;; time to turn off floppy drive motor(s)?
+ mov al, ds:[40h]
+ or al, al
+ jz int08_floppy_off
+ dec al
+ mov ds:[40h], al
+ jnz int08_floppy_off
+ ;; turn motor(s) off
+ mov dx, 03F2h
+ in al, dx
+ and al, 0CFh
+ out dx, al
+int08_floppy_off:
+
int 1Ch ; call the user timer handler
+
cli
call eoi_master_pic
+ pop dx
pop ds
pop eax
.286