[OpenBIOS] r797 - dev/geode

svn at openbios.org svn at openbios.org
Thu Jan 31 03:37:25 CET 2008


Author: wmb
Date: 2008-01-31 03:37:24 +0100 (Thu, 31 Jan 2008)
New Revision: 797

Added:
   dev/geode/smi.fth
Log:
Geode SMI handler - first checkpoint.


Added: dev/geode/smi.fth
===================================================================
--- dev/geode/smi.fth	                        (rev 0)
+++ dev/geode/smi.fth	2008-01-31 02:37:24 UTC (rev 797)
@@ -0,0 +1,239 @@
+purpose: SMI setup and handler for Geode LX
+
+also assembler definitions
+
+: smint  ( -- )  prefix-0f  h# 38 asm8,  ;
+: rsm    ( -- )  prefix-0f  h# aa asm8,  ;
+: svdc  ( sr m80 -- )  prefix-0f  h# 78 asm8,  rot r/m,  ;
+: rsdc  ( m80 sr -- )  prefix-0f  h# 79 asm8,  r/m,   ;
+
+previous definitions
+
+h# 4000.0000 constant smm-base
+h#    1.0000 constant smm-size
+: +smm  ( offset -- adr )  smm-base +  ;
+
+h# 30 constant /smm-gdt
+smm-size h# 100 -
+dup constant smm-stack
+dup constant smm-save-gdt 8 +
+dup constant smm-gdtp     8 +
+dup constant smm-gdt      /smm-gdt +
+dup constant smm-pdir     4 +
+
+dup constant smm-code16  h# a +
+dup constant smm-data16  h# a +
+dup constant smm-code32  h# a +
+dup constant smm-data32  h# a +
+dup constant smm-ds      h# a +
+dup constant smm-es      h# a +
+dup constant smm-fs      h# a +
+dup constant smm-gs      h# a +
+dup constant smm-ss      h# a +
+dup constant smm-cs      h# a +
+dup constant smm-esp     4 +
+drop
+
+: set-descr  ( base limit d.type sel offset -- )
+   +smm 2>r  format-descriptor  ( d.descr r: sel adr )
+   2r@ 8 + w!                   ( d.descr r: sel adr )
+   2dup r> d!                   ( d.descr r: sel )
+   r> smm-gdt + +smm d!         ( )
+;
+
+: set-smm-descs  ( -- )
+   smm-base -1 code32 format-descriptor  smm-gdt 8 + +smm d!  \ Boosted code32
+
+   smm-base smm-size 1- code16 h# 10 smm-code16 set-descr
+   smm-base smm-size 1- data16 h# 18 smm-data16 set-descr
+   0 -1 code32 h# 20 smm-code32 set-descr
+   0 -1 data32 h# 28 smm-data32 set-descr
+   /smm-gdt 1-   smm-gdtp +smm 4 + w!   \ GDT limit
+   smm-gdt +smm  smm-gdtp +smm l!       \ GDT base
+;
+
+label smm-handler
+   16-bit
+
+   cs: ds      smm-ds #)  svdc
+   cs: smm-data16 #)  ds  rsdc   \ Now we have a data segment
+
+   es  smm-es #)  svdc
+   fs  smm-fs #)  svdc
+   gs  smm-gs #)  svdc
+   ss  smm-ss #)  svdc
+   smm-data16 #)  ss  rsdc   \ Now we have a data segment
+
+   op: sp  smm-esp #)  mov
+   smm-stack #  sp  mov      \ Now we have a stack
+
+   op: pusha
+
+   h# cf8 #  dx   mov   \ Save/restore PCI config address
+   op: dx    ax   in
+   op: ax         push
+
+   cr3 ax mov  op: ax push
+
+\ ---
+\ Get into protected mode using the same segments 
+\ Don't bother with the IDT; we won't enable interrupts
+   op: smm-save-gdt #) sgdt
+   op: smm-gdtp     #) lgdt
+
+\ Test<
+   \ Get into the 4G flat code-32 address space
+   cs  smm-cs  #)  svdc       \ So we can get back
+   smm-code32  #)  cs  rsdc   \ 4G flat address space for code
+   32-bit
+   here 5 + +smm #) jmp       \ Into unboosted segment
+
+nop nop nop nop nop nop nop 
+
+   cr0 ax mov  1 # al or  ax cr0 mov   \ Enter protected mode
+   here 2 + #) jmp
+
+   \ Reload segment registers with protected mode bits
+   cs: smm-data32 +smm #)  ds  rsdc
+   smm-data32 +smm #)  ss  rsdc
+   smm-data32 +smm #)  es  rsdc
+   smm-data32 +smm #)  fs  rsdc
+   smm-data32 +smm #)  gs  rsdc
+
+   \ Turn on paging
+   smm-pdir +smm   #)  ax  mov
+   ax cr3  mov	\ Set Page Directory Base Register
+   cr0 ax mov  h# 8000.0000 # ax or  ax cr0 mov	 \ Turn on Paging Enable bit
+
+
+\   op:  here 7 + smm-handler - smm-base +  h# 20 #)  far jmp
+\   op:  here 7 + smm-handler -   8 #)  far jmp
+
+\ Put Forth stuff here  
+
+\   smm-code16 +smm #)  cs  rsdc
+\   smm-code16 +smm #)  cs  rsdc   \ 64K boosted
+
+   nop nop nop nop nop nop nop nop nop nop 
+
+   \ Turn off paging
+   cr0 ax mov  h# 8000.0000 invert # ax and  ax cr0 mov	 \ Turn off Paging Enable bit
+
+
+   cr0 ax mov  1 invert # al and  ax cr0 mov   \ Enter real mode
+   here 2 + #) jmp
+
+
+   \ Reload segment registers with real mode bits
+   cs: smm-data16 +smm #)  ss  rsdc
+   cs: smm-data16 +smm #)  ds  rsdc
+
+
+   \ Return to the boosted code-16 address space
+   smm-cs  #)  cs  rsdc
+   16-bit
+   here 2 + #) jmp  \ 16-bit JMP zeros EIP[31:16]
+
+\ >Test
+
+
+   op: smm-save-gdt #) lgdt
+
+\ ---
+   op: ax pop  ax cr3 mov
+
+   op: ax        pop
+   h# cf8 #  dx  mov   \ Save/restore PCI config address
+   op: ax    dx  out
+
+   op: popa
+
+   op: smm-esp #)  sp  mov
+
+   smm-ss #)  ss  rsdc
+   smm-gs #)  gs  rsdc
+   smm-fs #)  fs  rsdc
+   smm-es #)  es  rsdc
+   smm-ds #)  ds  rsdc
+
+   rsm
+end-code
+here smm-handler - constant /smm-handler
+
+: setup-smi  ( -- )
+   \ Map the SMM region to physical memory at e.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.0000 , i.e. 64K
+   h# 2.c00e0.40000.ffff0. h# 1000.0026 msr!
+
+   \ Put 64K SMM memory at 4000.0000 in the processor linear address space
+   \ Cacheable in SMM mode, non-cacheable otherwise
+   h# 4000f.0.00.40000.1.01. h# 180e msr!
+
+   \  Base     Limit
+\   smm-base  smm-size 1-  h# 133b msr!
+   smm-base  -1  h# 133b msr!   \ Big limit
+
+   smm-base smm-size + 0   h# 132b msr!  \ Offset of SMM Header
+
+   h# 18.  h# 1301 msr!       \ Enable IO and software SMI
+
+   smm-base dup  smm-size  -1 mmu-map
+
+   smm-handler smm-base  /smm-handler  move
+   set-smm-descs
+   cr3@ smm-pdir +smm l!
+;
+
+: enable-virtual-pci  ( -- )
+   h# 5000.2012 msr@  swap h# 8002 or   swap  h# 5000.2002 msr!  \ Virtualize devices f and 1
+   h# 5000.2002 msr@  swap 8 invert and swap  h# 5000.2002 msr!  \ Enable SSMI for config accesses
+;
+
+
+code smi  smint  ax push  c;
+
+\ Forth stuff
+[ifdef] notyet
+   op: smm-forth-origin #)  bx  mov
+   op: smm-forth-up     #)  up  mov
+[then]
+   
+[ifdef] notyet
+   \ Exchange the stack and return stack pointer with the smi versions
+   'user sp0  sp  mov
+   'user rp0  rp  mov
+
+   'user smi-sp0  sp  xchg
+   'user smi-rp0  rp  xchg
+
+   sp  'user sp0  mov
+   rp  'user rp0  mov
+
+   \ Set the interpreter pointer
+   'body smi-exec origin - # ip mov
+   bx ip add				\ add current origin
+
+   cld
+c;
+XXX code to return from Forth
+[then]
+
+[ifdef] notyet
+   \ We are running in a segment that is identity mapped
+   cr0 ax mov  h# 8000.0000 invert # ax and  ax cr0  mov  \ Turn off Paging Enable bit
+[then]
+
+label emita
+   op: dx dx xor   dx dx xor
+   h# 3fd # dx mov
+   begin dx al in h# 20 # al and 0<> until
+   h# 41 # al mov  h# f8 # dl mov  al dx out
+   begin again
+\   h# 3fd # dx mov
+\   begin dx al in h# 20 # al and 0<> until
+end-code
+here emita - constant /emita
+: puta  ( adr -- )  emita swap /emita move  ;




More information about the OpenBIOS mailing list