Author: wmb
Date: 2009-10-06 23:36:16 +0200 (Tue, 06 Oct 2009)
New Revision: 1397
Modified:
cpu/x86/pc/olpc/via/acpi.fth
cpu/x86/pc/olpc/via/addrs.fth
cpu/x86/pc/olpc/via/resume.bth
cpu/x86/pc/olpc/via/romreset.bth
Log:
Via - implement X_firmware_waking_vector support in early startup code,
and use it in the Forth resume code to eliminate hardcoded addresses.
Modified: cpu/x86/pc/olpc/via/acpi.fth
===================================================================
--- cpu/x86/pc/olpc/via/acpi.fth 2009-10-06 11:07:53 UTC (rev 1396)
+++ cpu/x86/pc/olpc/via/acpi.fth 2009-10-06 21:36:16 UTC (rev 1397)
@@ -249,20 +249,20 @@
0 w, 0 w, \ Room for the segment:offset pointer
then
- op: ax bx mov
- h# 0f # ax and ax cx mov
- op: 4 # bx shr
+ op: ax bx mov \ Get linear address to jump to - must be < 1M
+ h# 0f # ax and ax cx mov \ CX: low 4 bits for offset of seg:off address
+ op: 4 # bx shr \ BX: high 16 bits for segment of seg:off
\ Set data segment for storing offset and segment below
ax ax xor ds16 # al mov ax ds mov \ 16-bit data segment
- cx wake-adr wa1+ #) mov \ Offset
- bx wake-adr la1+ #) mov \ Segment
+ cx wake-adr wa1+ #) mov \ Put offset at wake-adr+2
+ bx wake-adr la1+ #) mov \ Put segment at wake-adr+4
cr0 ax mov h# fe # al and ax cr0 mov \ Enter real mode
here 5 + do-acpi-wake - wake-adr + lwsplit d# 12 lshift #) far jmp \ Jump to set cs
- cs: wake-adr wa1+ lwsplit drop s#) far jmp
+ cs: wake-adr wa1+ lwsplit drop s#) far jmp \ Jump to seg:off address stored at wake-adr+2
end-code
here do-acpi-wake - constant /do-acpi-wake
Modified: cpu/x86/pc/olpc/via/addrs.fth
===================================================================
--- cpu/x86/pc/olpc/via/addrs.fth 2009-10-06 11:07:53 UTC (rev 1396)
+++ cpu/x86/pc/olpc/via/addrs.fth 2009-10-06 21:36:16 UTC (rev 1397)
@@ -43,7 +43,6 @@
0 value dma-base \ Set in probemem.fth
h# f.0000 constant suspend-base \ In the DOS hole
-h# f.0008 constant resume-entry
h# f.1000 constant resume-data
\ If you change these, also change {g/l}xmsrs.fth and {g/l}xearly.fth
Modified: cpu/x86/pc/olpc/via/resume.bth
===================================================================
--- cpu/x86/pc/olpc/via/resume.bth 2009-10-06 11:07:53 UTC (rev 1396)
+++ cpu/x86/pc/olpc/via/resume.bth 2009-10-06 21:36:16 UTC (rev 1397)
@@ -32,6 +32,7 @@
;
start-assembling \ Turn on the target assembler
+suspend-base to asm-origin \ This code will be copied to a fixed location
protected-mode
\ Suspend code - called as a subroutine, with return address on the stack
@@ -41,15 +42,6 @@
\ is used as a memory pointer before and after the paging turn-off.
label suspend-entry \ h# f.0000 - entry point at fixed location, called by OS
- here h# 10 + #) jmp \ Jump to offset 10
- 8 pad-to
-
-label resume-entry \ h# f.0008 - entry point at fixed location, called by resume
- e9 c, 0 , \ To be patched later
- nop \ Aligns to even, for the benefit of the disassembler
- h# 10 pad-to
-
-label suspend-save \ h# f.0010 (Page directory VA in ax)
pusha
pushf cli
ds push
@@ -66,9 +58,10 @@
0 [si] cx mov forget-msr \ Save old PDIR entry 0
h# 83 # 0 [ax] mov \ Punch a 4M mapping 0->0 into the page directory
cr3 ax mov ax cr3 mov \ Invalidate the TLB to activate the mapping
- h# f0060 # ax mov ax jmp \ Jump to suspend-physical, disabling paging
- h# 60 pad-to
+ \ Jump to the physical address of the next instruction, disabling paging
+ here 7 + asm-base - asm-origin + # ax mov ax jmp
+
\ We have to be running from a virtual=physical mapping here, otherwise we
\ die on the instruction after paging is turned off.
cr0 ax mov ax bx mov \ CR0 saved in BX
@@ -93,9 +86,9 @@
h# a [bp] sidt \ Interrupt descriptor table register
h# 10 [bp] sgdt \ Global descriptor table register
- bx h# 18 [bp] mov
- cr3 ax mov ax h# 1c [bp] mov
- cr4 ax mov ax h# 20 [bp] mov
+ bx h# 18 [bp] mov \ CR0
+ cr3 ax mov ax h# 1c [bp] mov \ CR3
+ cr4 ax mov ax h# 20 [bp] mov \ CR4
cx h# 24 [bp] mov \ PDIR entry 0
si h# 28 [bp] mov \ PDIR VA
di h# 2c [bp] mov \ Address offset
@@ -216,6 +209,10 @@
h# fe resume-progress
+ \ Set the resume address
+label resume-adr-loc
+ h# 0 # facs-adr h# 18 + #) mov \ Value will be patched below
+
wbinvd \ Flush the cache
[ifdef] delete-me
@@ -242,7 +239,7 @@
h# 3f # al mov al h# 70 # out h# 71 # al in al inc al h# 71 # out
\ Resume code
-here resume-entry put-branch
+here asm-base - asm-origin + resume-adr-loc 6 + !
\ Assumptions:
\ Processor is in protected mode
@@ -474,9 +471,9 @@
h# 2c [bp] di mov \ VA of suspend-base in di
h# 28 [bp] si mov \ PDIR VA
h# 24 [bp] cx mov forget-msr \ PDIR entry 0
- h# 20 [bp] ax mov ax cr4 mov
- h# 1c [bp] ax mov ax cr3 mov
- h# 18 [bp] ax mov
+ h# 20 [bp] ax mov ax cr4 mov \ Restore CR4
+ h# 1c [bp] ax mov ax cr3 mov \ Restore CR3
+ h# 18 [bp] ax mov \ Get CR0 for a few lines later
h# 10 [bp] lgdt \ Global descriptor table register
h# a [bp] lidt \ Interrupt descriptor table register
Modified: cpu/x86/pc/olpc/via/romreset.bth
===================================================================
--- cpu/x86/pc/olpc/via/romreset.bth 2009-10-06 11:07:53 UTC (rev 1396)
+++ cpu/x86/pc/olpc/via/romreset.bth 2009-10-06 21:36:16 UTC (rev 1397)
@@ -227,15 +227,16 @@
cli
+ facs-adr h# 18 + #) ax mov ax ax or 0<> if \ X_Firmware_Waking_Vector
+ ax jmp \ Jump in 32-bit protected mode
+ then
+
facs-adr h# c + #) ax mov ax ax or 0<> if
\ Resume in real mode for ACPI operating systems
\ Linear wakeup address is in EAX
wake-adr lwsplit drop cs16 #) far jmp
- else
- \ Resume in 32-bit protected mode for OFW
- resume-data # sp mov
- resume-entry # ax mov ax call \ This might return if checksumming fails
then
+
char x report
then \ Not a wakeup from S3