Author: wmb Date: 2008-07-18 01:24:29 +0200 (Fri, 18 Jul 2008) New Revision: 851
Modified: cpu/x86/pc/biosints.fth cpu/x86/pc/olpc/acpi.fth cpu/x86/pc/olpc/addrs.fth cpu/x86/pc/olpc/config.fth cpu/x86/pc/olpc/crypto.fth cpu/x86/pc/olpc/gxearly.fth cpu/x86/pc/olpc/lxearly.fth cpu/x86/pc/olpc/lxmsrs.fth cpu/x86/pc/olpc/resume.bth cpu/x86/pc/olpc/romstart.bth cpu/x86/pc/olpc/suspend.fth cpu/x86/pc/olpc/versions.fth cpu/x86/pc/rmtools.fth dev/geode/draminit.fth dev/geode/smi.fth dev/geode/startmacros.fth dev/mmc/sdhci/sdhci.fth Log: OLPC - big checkin to make XP suspend/resume work.
Modified: cpu/x86/pc/biosints.fth =================================================================== --- cpu/x86/pc/biosints.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/biosints.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -573,14 +573,15 @@
h# e0000. d, h# 20000. d, 2 l, \ 3c reserved h# 100000. d, 0. d, 1 l, \ 50 available - 0. d, 0. d, 4 l, \ 64 don't reclaim (yet) +\ 0. d, 0. d, 4 l, \ 64 don't reclaim (yet) + 0. d, 0. d, 2 l, \ 64 reserved fw memory h# fff00000. d, h# 100000. d, 2 l, \ 78 reserved (ROM) here memdescs - constant /memdescs
: populate-memory-map ( -- ) memory-limit h# 100000 - memdescs h# 58 + l! \ Size of memory above 1M memory-limit memdescs h# 64 + l! \ Base of firmware memory - allmem memory-limit - memdescs h# 6c + l! \ Size of firmware memory + allmem fbsize - memory-limit - memdescs h# 6c + l! \ Size of firmware memory ;
: system-memory-map ( -- ) \ E820 @@ -912,13 +913,13 @@
" keyboard" open-dev to kbd-ih populate-memory-map + rm-platform-fixup ; -: close-bios-disk ( -- ) disk-ih close-dev 0 to disk-ih ; +: close-bios-disk ( -- ) disk-ih ?dup if close-dev 0 to disk-ih then ; ' close-bios-disk to quiesce-devices
: rm-go ( -- ) prep-rm - rm-platform-fixup open-bios-disk get-mbr \ Load boot image at 7c00 usb-quiet
Modified: cpu/x86/pc/olpc/acpi.fth =================================================================== --- cpu/x86/pc/olpc/acpi.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/acpi.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -1,15 +1,5 @@ \ Make some ACPI descriptor tables
-h# 9.fc00 constant 'ebda \ Extended BIOS Data Area, which we co-opt for our real-mode workspace - -h# e0000 constant rsdp-adr -h# e0040 constant rsdt-adr -h# e0080 constant fadt-adr -h# e0180 constant facs-adr -h# e01c0 constant dbgp-adr - -h# fc000 constant dsdt-adr -h# fd000 constant ssdt-adr h# 0. 2constant xsdt-adr
create fadt
Modified: cpu/x86/pc/olpc/addrs.fth =================================================================== --- cpu/x86/pc/olpc/addrs.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/addrs.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -101,6 +101,16 @@ h# fe02.8000 constant camera-pci-base h# efc0.0000 constant uoc-pci-base
+h# 9.fc00 constant 'ebda \ Extended BIOS Data Area, which we co-opt for our real-mode workspace + +h# e0000 constant rsdp-adr +h# e0040 constant rsdt-adr +h# e0080 constant fadt-adr +h# e0180 constant facs-adr +h# e01c0 constant dbgp-adr +h# fc000 constant dsdt-adr +h# fd000 constant ssdt-adr + fload ${BP}/cpu/x86/pc/virtaddr.fth [ifndef] virtual-mode h# ff80.0000 to fw-virt-base \ Override the usual setting; we use an MSR to double-map some memory up high
Modified: cpu/x86/pc/olpc/config.fth =================================================================== --- cpu/x86/pc/olpc/config.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/config.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -43,6 +43,7 @@ create basic-isa create isa-dma-only create use-ega +create save-msrs
create use-null-nvram \ Don't store configuration variables \ create use-flash-nvram \ Store configuration variables in SPI FLASH
Modified: cpu/x86/pc/olpc/crypto.fth =================================================================== --- cpu/x86/pc/olpc/crypto.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/crypto.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -4,6 +4,7 @@ h# c0000 constant verify-base \ The address the code is linked to run at h# d0000 constant verify-bss \ The address the code is linked to run at h# 10000 constant /verify-bss +h# 9c000 constant verify-stack
0 value crypto-loaded? : load-crypto ( -- error? ) @@ -19,7 +20,7 @@ : signature-bad? ( data$ sig$ key$ hashname$ -- mismatch? ) $cstr verify-bss /verify-bss erase ( data$ sig$ key$ 'hashname ) - verify-base dup h# 10 - sp-call >r 3drop 4drop r> ( result ) + verify-base verify-stack sp-call >r 3drop 4drop r> ( result ) ;
\ This is a hack that saves a lot of memory. The crypto verifier
Modified: cpu/x86/pc/olpc/gxearly.fth =================================================================== --- cpu/x86/pc/olpc/gxearly.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/gxearly.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -39,6 +39,8 @@ \ Some of these don't really have to be set here, and could be \ moved to the big table of MSR values, except that the table \ slammer is dumb and can't handle conditionals. + 20000000.000fff00. 10000020 set-msr \ memory - 0..fffff + 1030 port-rl 4 bitand 0<> if \ 128 MiB 25fff002.1077e000. 1808 set-msr 2c7be040.400fffe0. 10000026 set-msr
Modified: cpu/x86/pc/olpc/lxearly.fth =================================================================== --- cpu/x86/pc/olpc/lxearly.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/lxearly.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -31,6 +31,9 @@
\ The LX devel board has only 512M ROM, but assigning 1M of address space is harmless 25fff002.10f00000. 1808 set-msr \ 1M ROM at fff0.0000, system RAM limit at 0f00.0000, fbsize + 20000000.000fff80. 10000020 set-msr \ memory - 0..7ffff + 20000000.080fffe0. 10000026 set-msr \ memory - 80000..9ffff (a0000..bffff is for VGA) + 20000000.0c0fffc0. 10000027 set-msr \ memory - c0000..fffff 2000000e.fff00100. 10000028 set-msr \ Range - Top of memory at 0eff.ffff, fbsize 212000fd.ffffd000. 10000029 set-msr \ Range Offset - Frame buffer at PA fd00.0000 maps to RAM at 0f00.0000, fbsize 20f400ff.bffff800. 1000002b set-msr \ Range Offset - OFW area ff80.0000 maps to RAM at 0ec0.0000, fbsize
Modified: cpu/x86/pc/olpc/lxmsrs.fth =================================================================== --- cpu/x86/pc/olpc/lxmsrs.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/lxmsrs.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -312,6 +312,83 @@ msr: 5120.000b 00000002.efc00000. \ USB UOC Base Address - 5536 page 266
\ Clear possible spurious USB Short Serial detect bit per 5536 erratum 57 - msr: 5120.0015 00000010.00000000. \ USB_GLD_MSR_DIAG + msr: 5120.0005 00000010.00000000. \ USB_GLD_MSR_DIAG
here lx-msr-init - constant /lx-msr-init + +[ifdef] save-msrs +hex +: msrloop c, l, ; +create msr-ranges + 1100 1 msrloop + 1210 1 msrloop + 1700 1 msrloop + 1808 1 msrloop + 180a e msrloop + 1900 2 msrloop + 1920 1 msrloop + 1930 1 msrloop + 1980 4 msrloop + 1a00 1 msrloop + 2000 6 msrloop +10002000 6 msrloop +10000020 d msrloop +10000080 c msrloop +100000a0 f msrloop +100000c0 8 msrloop +100000d0 10 msrloop +100000e0 9 msrloop +40002000 6 msrloop +40000020 e msrloop +40000080 c msrloop +400000a0 f msrloop +400000c0 8 msrloop +400000d0 10 msrloop +400000e0 9 msrloop +20002000 6 msrloop +20000012 d msrloop +2000001f 2 msrloop +a0002000 6 msrloop +80002000 6 msrloop +80002010 3 msrloop +c0002000 6 msrloop +c0002010 2 msrloop +48002000 6 msrloop +48002010 2 msrloop +4c002001 5 msrloop +4c000008 c msrloop \ Omit 14 and 15; handled separately +4c000016 1 msrloop +4c000023 1 msrloop +50002000 6 msrloop +50002010 10 msrloop +54002000 6 msrloop +54002010 6 msrloop +58002000 7 msrloop +51000000 6 msrloop +51000010 1 msrloop +51000020 15 msrloop +51010000 6 msrloop +51010020 7 msrloop +51010080 d msrloop +510100a0 b msrloop +510100c0 2 msrloop +510100d0 4 msrloop +510100e0 12 msrloop +51024004 1 msrloop +51200000 5 msrloop +51200008 4 msrloop +51300000 6 msrloop +51300008 1 msrloop +51300010 6 msrloop +51400000 6 msrloop +51400008 2 msrloop +5140000b 1b msrloop +51400028 3 msrloop +51400037 a msrloop +5140004e 3 msrloop +51400054 4 msrloop +51500000 6 msrloop +51700000 6 msrloop +51700008 10 msrloop +0 c, +[then]
Modified: cpu/x86/pc/olpc/resume.bth =================================================================== --- cpu/x86/pc/olpc/resume.bth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/resume.bth 2008-07-17 23:24:29 UTC (rev 851) @@ -101,12 +101,34 @@ cld h# 38 [bp] di lea \ Save area
+[ifdef] save-msrs + h# 30 [bp] si mov \ MSR table + 0 [si] bl mov + + begin + 1 [si] cx mov + 5 # si add + begin + \ loop count in bl, msr# in cx + rdmsr + \ msr.lo in ax, msr.hi in dx + ax stos dx ax mov ax stos + cx inc + bl dec + 0= until + 0 [si] bl mov + bl bl and + 0= until +[else] \ Video MSRs that change between VGA and flat panel - h# 4c00.0014 rmsr ax stos dx ax mov ax stos \ RSTPLL - h# 4c00.0015 rmsr ax stos dx ax mov ax stos \ DOTPLL h# c000.2001 rmsr ax stos dx ax mov ax stos \ Video output format h# c000.2011 rmsr ax stos dx ax mov ax stos \ TFTP pad select +[then]
+ \ Do these separately because they need special bit sequencing + h# 4c00.0014 rmsr ax stos dx ax mov ax stos \ RSTPLL + h# 4c00.0015 rmsr ax stos dx ax mov ax stos \ DOTPLL + [ifdef] save-display \ Freeze image by clearing the DCONLOAD bit (0x800) in the GPIO output register h# 0800.0000 h# 1000 port-wl @@ -118,6 +140,11 @@
h# 5140.000c rmsr ax bx mov
+ h# ec [bx] dx lea dx ax in ax stos \ GPIO_MAP_W + h# e8 [bx] dx lea dx ax in ax stos \ GPIO_MAP_X + h# e4 [bx] dx lea dx ax in ax stos \ GPIO_MAP_Y + h# e0 [bx] dx lea dx ax in ax stos \ GPIO_MAP_Z + h# 38 [bx] dx lea \ Low bank - first contiguous GPIO register h# 3c /l / # cx mov \ Register count (stop at lock register) begin @@ -205,8 +232,7 @@ rdmsr al stos \ PIT Counter 0 Command Word - not sure how this works rdmsr al stos \ PIT Counter 1 Command Word rdmsr al stos \ PIT Counter 2 Command Word - h# 43 # al in al stos \ Read back register 43 directly - h# 61 # al in al stos \ Read back register 43 directly + h# 61 # al in al stos \ Read back register 61 directly h# 5140.0037 rmsr al stos \ PIT Count Enable MSR
\ SMBUS controller @@ -235,13 +261,19 @@ h# 24 [bx] ax mov ax stos \ NAND Timing1 h# 28 [bx] ax mov ax stos \ NAND Timing2 h# 2c [bx] ax mov ax stos \ NAND Timing3 - h# 6004 config-rw ax stos \ NAND enables - + h# 6004 config-rw op: ax stos \ NAND enables + + h# 6104 config-rw op: ax stos \ SDHCI enables + h# 0 h# 618c config-ww \ Set power state to 0 so reads will work h# 6110 config-rl ax stos \ SDHCI BAR ax bx mov \ Base address + 6 h# 6104 config-ww \ Enable access + op: h# 3004 [bx] ax mov op: ax stos \ Clock config + h# 300c [bx] ax mov ax stos \ Interrupt config h# 3038 [bx] ax mov ax stos \ GPIO Config h# 315c [bx] ax mov ax stos \ GPIO Data - h# 6104 config-rw ax stos \ SDHCI enables + h# 610d config-rb al stos \ SDHCI latency timer + h# 613c config-rb al stos \ SDHCI IRQ
h# 6210 config-rl ax stos \ Camera BAR h# 6204 config-rw ax stos \ SDHCI enables @@ -339,6 +371,7 @@
h# 20 resume-progress
+[ifndef] save-msrs \ MSR init h# 30 [bp] si mov \ MSR table start address si bx mov @@ -351,6 +384,7 @@ wrmsr si bx cmp = until +[then]
h# 21 resume-progress
@@ -365,12 +399,33 @@
h# 38 [bp] si lea \ Save area
+[ifdef] save-msrs + h# 30 [bp] di mov \ MSR table start address + 0 [di] bl mov + + begin + 1 [di] cx mov + 5 # di add + begin + \ loop count in bl, msr# in cx + ax lods ax dx mov ax lods ax dx xchg + \ msr.lo in ax, msr.hi in dx + wrmsr + cx inc + bl dec + 0= until + 0 [di] bl mov + bl bl and + 0= until + h# 10.00000000. h# 5120.0005 set-msr \ Clear possible spurious error per 5536 erratum 57 +[else] + ax lods ax dx xchg ax lods ax dx xchg h# c000.2001 wmsr \ Video output format + ax lods ax dx xchg ax lods ax dx xchg h# c000.2011 wmsr \ TFTP pad select +[then] ax lods ax dx xchg ax lods ax dx xchg h# 4c00.0014 wmsr \ RSTPLL ax lods ax dx xchg ax lods ax dx xchg 1 bitset h# 4c00.0015 wmsr \ DOTPLL - reset to make it take the new value 1 bitclr h# 4c00.0015 wmsr \ DOTPLL - release reset - ax lods ax dx xchg ax lods ax dx xchg h# c000.2001 wmsr \ Video output format - ax lods ax dx xchg ax lods ax dx xchg h# c000.2011 wmsr \ TFTP pad select
h# 22 resume-progress
@@ -415,6 +470,12 @@ h# 23 resume-progress
h# 5140.000c rmsr ax bx mov + + ax lods h# ec [bx] dx lea ax dx out \ GPIO_MAP_W + ax lods h# e8 [bx] dx lea ax dx out \ GPIO_MAP_X + ax lods h# e4 [bx] dx lea ax dx out \ GPIO_MAP_Y + ax lods h# e0 [bx] dx lea ax dx out \ GPIO_MAP_Z + h# 38 [bx] dx lea \ Low bank - first contiguous GPIO register h# 3c /l / # cx mov \ Register count (stop at lock register) begin @@ -543,20 +604,39 @@
h# 26 resume-progress
+[ifdef] notdef \ Restore PIT (timer) - h# 30 # al mov al h# 43 # out \ Load LSB,MSB for counter 0 - al lods al h# 40 out - al lods al h# 40 out - h# 70 # al mov al h# 43 # out \ Load LSB,MSB for counter 1 - al lods al h# 41 out - al lods al h# 41 out - h# b0 # al mov al h# 43 # out \ Load LSB,MSB for counter 2 - al lods al h# 42 # out - al lods al h# 42 # out + \ h# 30 # al mov al h# 43 # out \ Load LSB,MSB for counter 0 + al lods \ al h# 40 out + al lods \ al h# 40 out + \ h# 70 # al mov al h# 43 # out \ Load LSB,MSB for counter 1 + al lods \ al h# 41 out + al lods \ al h# 41 out + \ h# b0 # al mov al h# 43 # out \ Load LSB,MSB for counter 2 + al lods \ al h# 42 # out + al lods \ al h# 42 # out al lods \ Command word for counter 0 al lods \ Command word for counter 1 al lods \ Command word for counter 2 - al lods al h# 43 # out +[else] + 6 [esi] ah mov ah ah or 0<> if + ah al mov h# 3f # al and al h# 43 # out + h# 10 # ah test 0<> if 0 [esi] al mov al h# 40 # out then + h# 20 # ah test 0<> if 1 [esi] al mov al h# 40 # out then + then + 7 [esi] ah mov ah ah or 0<> if + ah al mov h# 3f # al and h# 40 # al or al h# 43 # out + h# 10 # ah test 0<> if 2 [esi] al mov al h# 41 # out then + h# 20 # ah test 0<> if 3 [esi] al mov al h# 41 # out then + then + 8 [esi] ah mov ah ah or 0<> if + ah al mov h# 3f # al and h# 80 # al or al h# 43 # out + h# 10 # ah test 0<> if 4 [esi] al mov al h# 42 # out then + h# 20 # ah test 0<> if 5 [esi] al mov al h# 42 # out then + then + + 9 # esi add +[then] al lods al h# 61 # out al lods h# 5140.0037 wmsr \ PIT Count Enable MSR - high bits irrelevant
@@ -648,17 +728,26 @@ ax lods ax h# 24 [bx] mov \ NAND Timing 1 ax lods ax h# 28 [bx] mov \ NAND Timing 2 ax lods ax h# 2c [bx] mov \ NAND Timing 3 - h# 6004 config-setup ax lods op: ax dx out \ NAND enables + h# 6004 config-setup op: ax lods op: ax dx out \ NAND enables
+ op: ax lods ax cx mov \ SDHCI enables - save for later h# 6110 config-setup ax lods ax dx out \ SDHCI BAR ax bx mov \ Base address 6 h# 6104 config-ww \ Enable access + op: ax lods op: ax h# 3004 [bx] mov \ Clock config + ax lods ax h# 300c [bx] mov \ Interrupt config ax lods ax h# 3038 [bx] mov \ GPIO Config ax lods ax h# 315c [bx] mov \ GPIO Data + op: h# 00c0 # h# 34 [bx] mov \ Enable card detection - Marvell chip bug \ The next two values can't be saved/restored; the registers aren't readable + \ Empirically, they are readable! op: h# 0004 # h# 6a [bx] mov \ Magic recipe from Marvell op: h# 7fff # h# 60 [bx] mov \ Magic recipe from Marvell h# 6104 config-setup ax lods op: ax dx out \ SDHCI enables + h# 610d config-setup al lods al dx out \ SDHCI latency timer + h# 613c config-setup al lods al dx out \ SDHCI IRQ + h# 6104 config-setup cx ax mov op: ax dx out \ Set SDHCI enables after restoring mapped registers + \ Don't save/restore the power state because if you set it to D3, it clears register 34
h# 6210 config-setup ax lods ax dx out \ Camera BAR h# 6204 config-setup ax lods op: ax dx out \ Camera enables
Modified: cpu/x86/pc/olpc/romstart.bth =================================================================== --- cpu/x86/pc/olpc/romstart.bth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/romstart.bth 2008-07-17 23:24:29 UTC (rev 851) @@ -64,7 +64,9 @@ \ pulse-tp
\ GLIU0 P2D Base Mask Descriptors - page 85 - 20000000.000fff00. 10000020 set-msr \ memory - 0..fffff + 20000000.000fff80. 10000020 set-msr \ memory - 0..7ffff + 20000000.080fffe0. 10000026 set-msr \ memory - 80000..9ffff + 20000000.0c0fffc0. 10000027 set-msr \ memory - c0000..fffff
\ EXTMSR - page 449 \ Use PCI device #F for port 2 00000000.00000f00. 5000201e set-msr \ cs5536_setup_extmsr(void)
Modified: cpu/x86/pc/olpc/suspend.fth =================================================================== --- cpu/x86/pc/olpc/suspend.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/suspend.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -4,9 +4,14 @@ stand-init: Suspend/resume " resume" find-drop-in if suspend-base swap move +[ifdef] save-msrs + msr-ranges ( adr ) +[else] msr-init-range ( adr len ) resume-data h# 34 + ! ( adr ) +[then] >physical resume-data h# 30 + ! ( ) +[then] then ;
@@ -45,9 +50,9 @@ \ sum-forth ; : suspend - " video-save" stdout @ $call-method \ Freeze display + " video-save" screen-ih $call-method \ Freeze display s3 - " video-restore" stdout @ $call-method \ Unfreeze display + " video-restore" screen-ih $call-method \ Unfreeze display " /usb@f,5" open-dev ?dup if " do-resume" 2 pick $call-method close-dev then ; alias s suspend
Modified: cpu/x86/pc/olpc/versions.fth =================================================================== --- cpu/x86/pc/olpc/versions.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/olpc/versions.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -2,7 +2,7 @@
\ The overall firmware revision macro: FW_MAJOR E -macro: FW_MINOR 10 +macro: FW_MINOR 11x
\ The EC microcode macro: EC_VERSION d13
Modified: cpu/x86/pc/rmtools.fth =================================================================== --- cpu/x86/pc/rmtools.fth 2008-07-09 16:42:21 UTC (rev 850) +++ cpu/x86/pc/rmtools.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -1,7 +1,6 @@ purpose: Convert between segment:offset and linear addresses
-: >seg:off ( linear -- offset segment ) lwsplit d# 12 lshift ; +: >seg:off ( linear -- offset segment ) dup h# f and swap 4 rshift ; : seg:off! ( linear adr -- ) >r >seg:off r@ wa1+ w! r> w! ; : seg:off> ( offset segment -- linear ) 4 lshift + ; : seg:off@ ( adr -- linear ) dup w@ swap wa1+ w@ seg:off> ; -: >off ( linear -- 16-bit offset ) >seg:off drop ;
Modified: dev/geode/draminit.fth =================================================================== --- dev/geode/draminit.fth 2008-07-09 16:42:21 UTC (rev 850) +++ dev/geode/draminit.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -36,9 +36,7 @@ 1 bitset 20000018 wmsr 1 bitclr 20000018 wmsr
- \ Set up a descriptor to give access to memory - \ GLIU0 P2D Base Mask Descriptors - page 85 - 20000000.000fff00. 10000020 set-msr \ memory - 0..fffff + \ Earlier code has set up an MSR so the fxxxx address range hits memory
\ The RAM DLL needs a write to lock on ax h# ffff0 #) mov
Modified: dev/geode/smi.fth =================================================================== --- dev/geode/smi.fth 2008-07-09 16:42:21 UTC (rev 850) +++ dev/geode/smi.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -293,6 +293,9 @@ defer handle-smi ' noop is handle-smi create smm-exec ] handle-smi smi-return [
+false value smi-debug? +false value resume-debug? + false value vpci-debug? : enable-virtual-pci ( -- ) \ Virtualize devices f and 1, or all devices if debugging @@ -403,6 +406,7 @@ : vr-spoof? ( -- handled? ) false ;
: pci-smi ( event-mask -- ) + smi-debug? if ." PCI" cr then 8 and 0= if exit then smm-io-port 3 invert and h# cfc <> if exit then vpci-debug? if h# 5000.2012 msr@ 2>r 0. h# 5000.2012 msr! then @@ -443,6 +447,7 @@ 0 value crc-status : start-crc ( -- ) ( XXX ) ; : dc-smi ( event-mask -- ) + smi-debug? if ." DC" cr then h# 10.0000 and 0= if exit then \ So far we only care about extended CRTC registers smm-flags 2 and if \ Write smm-eax-c@ @@ -540,6 +545,7 @@ then ; : gliu0-smi ( event-mask -- ) + smi-debug? if ." GLIU" cr then 1 and 0= if exit then \ We only care about virtual register accesses
smm-io-port h# fff0 and h# 30 = if @@ -558,16 +564,138 @@
\ We just discard the event about I/O registers because we handle it in sb-smi . \ We don't have to deal with statistics counters because we don't enable them -: cgliu-smi ( event-mask -- ) drop ; +: cgliu-smi ( event-mask -- ) smi-debug? if ." CGLIU" cr then drop ;
+code smi smint c; + +-1 value rm-entry-adr +: rm-run ( eip -- ) to rm-entry-adr smi ; + +: smm-stack-w! ( w offset -- ) smm-sp +smm + w! ; +: smm-stack-l! ( l offset -- ) smm-sp +smm + l! ; +\ : smi-to-forth ( ip -- ) + +\ exit-smi is tricky. It replaces the SMM saved state with the +\ current Forth engine state so that the "smi-return" returns +\ to the caller of this word as if nothing happened, expect that +\ the system is no longer in SMM state. This is used in only +\ one place - the Windows "go to S3 power state" code. It's +\ needed because the Geode hardware won't suspend from SMM state, +\ ignoring the "2000 18 acpi-l!" (actually the machine code +\ equivalent) in resume.bth. So we get out of SMM state, staying +\ in Forth, then call the Forth suspend word that invokes the +\ low-level suspend routine. Doing it this way, instead of writing +\ new machine code, is easier, in part because it also make its +\ easier to return to Windows upon resume. The ACPI resume interface +\ requires that the final transition be done in real mode; we can +\ do that from Forth by calling rm-run . + +: exit-smi ( -- ) + sp0 @ smm-save-sp0 ! + rp0 @ smm-save-rp0 ! + smm-gdt 2+ +smm smm-save-gdt +smm 6 move + gs@ h# 8 smm-stack-w! + fs@ h# a smm-stack-w! + es@ h# c smm-stack-w! + ds@ h# e smm-stack-w! + + ['] exit >body smm-next-eip! \ PC (unnest) + + \ 10 di 14 si 18 bp 1c xsp 20 bx 24 dx 28 cx 2c ax + up@ h# 10 smm-stack-l! \ EDI +\ ( ip ) h# 14 smm-stack-l! \ ESI Pointless as EIP points to "exit" + rp@ h# 18 smm-stack-l! \ EBP + sp@ smm-save-esp +smm l! \ ESP + ss@ smm-save-ss +smm w! \ SS + + smm-d32 smm-save-seg d# 08 + +smm w! \ DS + smm-d32 smm-save-seg d# 18 + +smm w! \ ES + smm-d32 smm-save-seg d# 28 + +smm w! \ FS + smm-d32 smm-save-seg d# 38 + +smm w! \ GS + smm-d32 smm-save-seg d# 48 + +smm w! \ SS + +\ smm-gdt smm-d32 + +smm smm-save-seg d# 10 + +smm 8 move +\ smm-gdt smm-d32 + +smm smm-save-seg d# 20 + +smm 8 move +\ smm-gdt smm-d32 + +smm smm-save-seg d# 30 + +smm 8 move +\ smm-gdt smm-d32 + +smm smm-save-seg d# 40 + +smm 8 move + + h# 82 smm-header h# 08 - l! \ smm-eflags (interrupts off) + h# 11 smm-header h# 0c - l! \ smm-cr0 + h# c09b smm-header h# 16 - w! \ smm-cs-flags + smm-c32 smm-header h# 18 - w! \ smm-cs-sel + 0 smm-header h# 1c - l! \ smm-cs-base + h# fffff smm-header h# 20 - l! \ smm-cs-limit + + smi-return +; + +: setup-smi ( -- ) + \ This is how you would map the SMM region to physical memory at 4000.0000 + \ This is a Base Mask Offset descriptor - the base address + \ is 4000.0000 and to that is added the offset c00e.0000 + \ to give the address 000e.0000 in the GLMC address space. + \ The mask is ffff.f000 , i.e. 4K + + \ This is unnecessary if the SMM memory is in a region that is + \ already mapped with a descriptor + \ h# 2.c00e0.40000.fffff. h# 1000.0026 msr! + + \ Put 4K SMM memory at 000f.f000 in the processor linear address space + \ Cacheable in SMM mode, non-cacheable otherwise + \ Depends on smm-base and smm-size + h# 000ff.0.00.000ff.1.01. h# 180e msr! + + \ Base Limit + smm-base smm-size 1- h# 133b msr! + + smm-header 0 h# 132b msr! \ Offset of SMM Header + + h# 18. h# 1301 msr! \ Enable IO and software SMI + + \ Unnecessary if already in mapped memory + \ smm-base dup smm-size -1 mmu-map + + smi-handler smm-base /smi-handler move + + \ Relocate the code field of the code word that is embedded in the sequence + ['] (smi-return) smi-handler - +smm ( cfa-adr ) + dup ta1+ swap token! + +[ifdef] virtual-mode + cr3@ smm-pdir l! +[then] + + origin smm-forth-base l! + smm-exec smm-forth-entry l! + up@ smm-forth-up l! + smm-sp0 smm-save-sp0 ! + smm-rp0 smm-save-rp0 ! + + enable-virtual-pci + enable-io-smis +; + +: win-s3 ( -- ) + \ The trick here is to transfer to "non-smi-s3" while leaving + \ System Management Mode. We won't need to return to the caller + \ that got us here, so we can overwrite any of the saved state. + resume-debug? if debug-me then + exit-smi + resume-debug? if ." enter s3" cr then + s3 +\ ." Return from S3" cr interact +\ noop + setup-smi + facs-adr h# c + l@ rm-run +; + : power-mode ( value offset -- ) - over 1 and if ( value offset ) - dup acpi-l@ 1 and 0= if quiesce-devices then ( value offset ) - then ( value offset ) + over 1 and if quiesce-devices then ( value offset )
over h# 2000 and if ( value offset ) drop d# 10 rshift 7 and case ( c:power-state ) 5 of power-off endof ( ) + 3 of win-s3 ." returned from s3 - shouldn't happen" cr endof ( default ) ." Requested power state " dup . endcase ( ) else ( value offset ) @@ -575,13 +703,17 @@ then ( ) ;
-: divil-smi ( event-mask -- ) h# 80 and if bye then ; +: divil-smi ( event-mask -- ) + smi-debug? if ." DIVIL" cr then + h# 80 and if bye then +;
: sb-smi ( event-mask -- ) + smi-debug? if ." SB" cr then 4 and 0= if exit then \ We only care about virtualized I/O registers
smm-flags h# 40 and if - ." Flags " smm-flags . 0 acpi-l@ . 8 acpi-l@ . 18 acpi-l@ . 1c acpi-l@ . cr +\ ." Flags " smm-flags . 0 acpi-l@ . 8 acpi-l@ . 18 acpi-l@ . 1c acpi-l@ . cr \ 0 acpi-l@ 1 and if 0 acpi-l@ 0 acpi-l! exit else interact then exit then @@ -611,7 +743,7 @@ smm-io-size case 1 of ( value acpi-offset ) acpi-b! - \ ." W8 " smm-io-port . smm-eax c@ . cr + vr-debug? if ." VW8 " smm-io-port . smm-eax c@ . cr then \ smm-io-port h# 9c1f = smm-eax c@ h# c0 = and if debug-me then endof 3 of ( value acpi-offset ) @@ -619,38 +751,40 @@ \ Workaround for 5536 errata - 16-bit writes to APCI registers \ 0 and 2 corrupt other registers 0 of drop 2 acpi-w@ wljoin 0 acpi-l! endof - 2 of drop 0 acpi-w@ swap wljoin 0 acpi-l! endof + \ When writing to register 2, we mustn't read register 0 and + \ merge in its value, because its bits are "write 1 to clear". + 2 of drop 0 swap wljoin 0 acpi-l! endof +\ 2 of drop 0 acpi-w@ swap wljoin 0 acpi-l! endof 8 of power-mode endof ( default: value port-adr acpi-offset ) -rot acpi-w! endcase - \ ." W16 " smm-io-port . smm-eax w@ . cr + vr-debug? if ." VW16 " smm-io-port . smm-eax w@ . cr then endof h# f of dup 8 = if power-mode else acpi-l! then - \ ." W32 " smm-io-port . smm-eax w@ . cr + vr-debug? if ." VW32 " smm-io-port . smm-eax w@ . cr then endof endcase else ( acpi-offset ) smm-io-size case 1 of ( acpi-offset ) acpi-b@ smm-eax c! - \ ." R8 " smm-io-port . smm-eax c@ . cr + vr-debug? if ." VR8 " smm-io-port . smm-eax c@ . cr then endof 3 of ( acpi-offset ) acpi-w@ smm-eax w! - \ ." R16 " smm-io-port . smm-eax w@ . cr + vr-debug? if ." VR16 " smm-io-port . smm-eax w@ . cr then \ smm-io-port h# 9c00 = if ." ." then endof h# f of ( acpi-offset ) acpi-l@ smm-eax l! + vr-debug? if ." VR32 " smm-io-port . smm-eax l@ . cr then \ smm-io-port h# 9c10 <> if ." R32 " smm-io-port . smm-eax l@ . cr then endof endcase then ;
-code smi smint c; - variable sbpval variable sbpadr sbpadr off defer sbp-hook @@ -741,6 +875,7 @@ h# ffff l!++ h# 9300 l!++ 0 w!++ \ FS h# ffff l!++ h# 9300 l!++ 0 w!++ \ GS h# ffff l!++ h# 9300 l!++ 0 w!++ \ SS + drop
h# ffff smm-rmidt w! 0 smm-rmidt wa1+ l! \ Limit and base
@@ -749,10 +884,8 @@ ; \ : rm-init-program ( eip -- ) rm-init-program rm-return ;
--1 value rm-entry-adr -: rm-run ( eip -- ) to rm-entry-adr smi ; - : soft-smi ( -- ) + smi-debug? if ." SOFT" cr then rm-entry-adr -1 <> if rm-entry-adr rm-setup -1 to rm-entry-adr @@ -774,6 +907,7 @@ smi-interact then ; + \ smm-flags values in various cases: \ 8080 (VGA) - ac1c read (VR), extended CRT register (dc-smi) \ 8020 (Mem read) - 9cxx (power management) register (sb-smi) @@ -825,52 +959,6 @@ ;
-: setup-smi ( -- ) - \ This is how you would map the SMM region to physical memory at 4000.0000 - \ This is a Base Mask Offset descriptor - the base address - \ is 4000.0000 and to that is added the offset c00e.0000 - \ to give the address 000e.0000 in the GLMC address space. - \ The mask is ffff.f000 , i.e. 4K - - \ This is unnecessary if the SMM memory is in a region that is - \ already mapped with a descriptor - \ h# 2.c00e0.40000.fffff. h# 1000.0026 msr! - - \ Put 4K SMM memory at 000f.f000 in the processor linear address space - \ Cacheable in SMM mode, non-cacheable otherwise - \ Depends on smm-base and smm-size - h# 000ff.0.00.000ff.1.01. h# 180e msr! - - \ Base Limit - smm-base smm-size 1- h# 133b msr! - - smm-header 0 h# 132b msr! \ Offset of SMM Header - - h# 18. h# 1301 msr! \ Enable IO and software SMI - - \ Unnecessary if already in mapped memory - \ smm-base dup smm-size -1 mmu-map - - smi-handler smm-base /smi-handler move - - \ Relocate the code field of the code word that is embedded in the sequence - ['] (smi-return) smi-handler - +smm ( cfa-adr ) - dup ta1+ swap token! - -[ifdef] virtual-mode - cr3@ smm-pdir l! -[then] - - origin smm-forth-base l! - smm-exec smm-forth-entry l! - up@ smm-forth-up l! - smm-sp0 smm-save-sp0 ! - smm-rp0 smm-save-rp0 ! - - enable-virtual-pci - enable-io-smis -; - 0 [if] SMI sources: LX:
Modified: dev/geode/startmacros.fth =================================================================== --- dev/geode/startmacros.fth 2008-07-09 16:42:21 UTC (rev 850) +++ dev/geode/startmacros.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -94,11 +94,16 @@ op: # ax mov ( ) op: ax dx out ; -: config-rw ( config-adr -- ) \ Returns value AX +: config-rw ( config-adr -- ) \ Returns value in AX config-setup ( ) ax ax xor op: dx ax in ; +: config-rb ( config-adr -- ) \ Returns value in AL + config-setup ( ) + ax ax xor + dx al in +;
: set-base ( adr -- ) # bx mov ; : reg-save ( offset -- ) [bx] ax mov ax stos ;
Modified: dev/mmc/sdhci/sdhci.fth =================================================================== --- dev/mmc/sdhci/sdhci.fth 2008-07-09 16:42:21 UTC (rev 850) +++ dev/mmc/sdhci/sdhci.fth 2008-07-17 23:24:29 UTC (rev 851) @@ -70,6 +70,14 @@ : esr! ( w -- ) h# 32 cw! ;
[ifdef] marvell +: vendor-modes ( -- ) + \ One-time initialization of Marvell CaFe SD interface. + \ Marvell told us to do this once after reset. + \ The sw-reset command resets the registers, so you have + \ to do it after that, in addition to after power-up. + h# 0004 h# 6a cw! \ Enable data CRC check + h# 7fff h# 60 cw! \ Disable internal pull-up/down on DATA3 +; : enable-sd-int ( -- ) h# 300c cl@ h# 8000.0002 or h# 300c cl! ; @@ -82,6 +90,8 @@ : disable-sd-clk ( -- ) h# 3004 cw@ h# 2000 invert and h# 3004 cw! ; +[else] +: vendor-modes ; [then]
: clear-interrupts ( -- ) @@ -100,6 +110,7 @@ : reset-host ( -- ) 0 to sd-clk 1 sw-reset \ RESET_ALL + vendor-modes ;
: host-high-speed ( -- ) h# 28 cb@ 4 or h# 28 cb! ; @@ -623,10 +634,7 @@
: init ( -- ) map-regs - \ One-time initialization of Marvell CaFe SD interface. - \ Marvell told us to do this, but didn't say why. - h# 0004 h# 6a cw! - h# 7fff h# 60 cw! + vendor-modes unmap-regs ;