[OpenBIOS] r802 - dev/geode

svn at openbios.org svn at openbios.org
Fri Feb 1 00:34:01 CET 2008


Author: wmb
Date: 2008-02-01 00:34:01 +0100 (Fri, 01 Feb 2008)
New Revision: 802

Modified:
   dev/geode/smi.fth
Log:
Geode SMI handler - Another round of tuning.  Hopefully the last stylistic pass.


Modified: dev/geode/smi.fth
===================================================================
--- dev/geode/smi.fth	2008-01-31 19:01:35 UTC (rev 801)
+++ dev/geode/smi.fth	2008-01-31 23:34:01 UTC (rev 802)
@@ -9,64 +9,85 @@
 
 previous definitions
 
+\ The general naming convention here is that smm-* refers to
+\ addresses within the memory that is set aside for SMI handling.
+\ smi-* refers to stuff in the Forth domain.
+
 h#    f.f000 constant smm-base
 h#      1000 constant smm-size  \ We use about 3K of this, 2K for stacks
-: +smm  ( offset -- adr )  smm-base +  ;
+: +smm  ( segment-relative-adr -- adr )  smm-base +  ;
+: -smm  ( adr -- segment-relative-adr )  smm-base -  ;
 
-h# 30 constant /smm-gdt
+h# 28 constant /smm-gdt
+h#  8 constant smm-c16
+h# 10 constant smm-d16
+h# 18 constant smm-c32
+h# 20 constant smm-d32
 
-\ The handler code takes about h# 140 bytes
+\ For stuff that grows down - add the offset first
+: rm-stack ( offset len "name" -- offset' )  + dup      constant  ;
+: pm-stack ( offset len "name" -- offset' )  + dup +smm constant  ;
 
-\ The following save area + the SMM_HEADER (h# 30) takes about h# 100
-h# 200     
-dup constant smm-save-gdt      8 +
-dup constant smm-gdtp          8 +
-dup constant smm-gdt           /smm-gdt +
-dup constant smm-pdir          la1+
-dup constant smm-forth-origin  la1+
-dup constant smm-forth-up      la1+
-dup constant smm-forth-entry   la1+
+\ For individual data items - add the offset afterwards
+: pm-data  ( offset len "name" -- offset' )  over +smm constant  +  ;
+: rm-data  ( offset len "name" -- offset' )  over      constant  +  ;
 
-\ 10 bytes for each of 6 segment registers
-dup constant smm-save-seg      d# 60 +
-dup constant smm-save-esp      la1+
-dup constant smm-sp            la1+
-   \ 8x 4-byte general registers + config adr + cs3 + spare
-h# 38 + constant smm-stack
+\ Layout of SMM memory area:
+0                            \ Entry/exit handler code goes here, at the origin
+h# 180 rm-data smm-gdt       \ The GDT is embedded in the code wad
+                             \ The handler code takes about h# 160 bytes
 
-h# 300 constant smm-header
+\ The following locations are for saving/restoring registers
+\ d# 60 rm-data smm-save-seg   \ 6 10-byte segment registers
+d# 50 rm-data smm-save-seg   \ 6 10-byte segment registers
+/l    rm-data smm-save-esp   \ Caller's stack pointer
+6     rm-data smm-save-gdt   \ Caller's GDT pointer
 
-: set-descr  ( base limit d.type sel -- )
-   >r  format-descriptor   ( d.descr r: sel )
-   r> smm-gdt + +smm d!    ( )
-;
+0         pm-data  smm-regs  \ Alternate name, for use by Forth
+0         rm-data  smm-sp    \ Real-mode sp after saving registers
+d# 10 /l* rm-stack smm-stack \ CR3, portCF8, 8 general registers
 
-: set-smm-descs  ( -- )
-\   smm-base -1 code32 format-descriptor  smm-gdt 8 + +smm d!  \ Boosted code32
-   smm-base smm-size 1- code16 h# 10 set-descr
-   smm-base smm-size 1- data16 h# 18 set-descr
-   0 -1 code32 h# 20 set-descr
-   0 -1 data32 h# 28 set-descr
-   /smm-gdt 1-   smm-gdtp +smm      w!  \ GDT limit
-   smm-gdt +smm  smm-gdtp +smm wa1+ l!  \ GDT base
-;
+h# 30 pm-stack smm-header     \ Top address where hardware puts the SMM info frame
 
-nuser smi-sp0
-nuser smi-rp0
+\ These locations are set once at installation time.  The entry code reads them.
+[ifdef] virtual-mode
+/l  pm-data smm-pdir         \ Page directory pointer so we can enable paging
+[then]
+/l  pm-data smm-forth-base   \ Base address of the Forth dictionary
+/l  pm-data smm-forth-up     \ Base address of the Forth user area
+/l  pm-data smm-forth-entry  \ Entry address of Forth SMI handler
+/l  pm-data smm-save-sp0     \ Exchanged with sp0 user variable
+/l  pm-data smm-save-rp0     \ Exchanged with rp0 user variable
 
-label smm-handler
+h# 400 pm-stack smm-sp0      \ SMM Forth data stack
+h# 400 pm-stack smm-rp0      \ SMM Forth return stack
+drop
+
+label smi-handler
    16-bit
+  
+   \ GDT (with jump tucked in at the beginning)
+   \ We put the GDT right at the beginning and use the first entry (which
+   \ cannot be used as a selector) for a 2-byte jmp and the 6-byte GDT pointer
+   here /smm-gdt + #) jmp           \ Jump past GDT - 2 bytes
+   /smm-gdt 1- w,   smm-base l,     \ GDT pointer - limit.w base.l
 
+   smm-base smm-size 1- code16 format-descriptor  swap l, l,  \  8 - smm-c16
+   smm-base smm-size 1- data16 format-descriptor  swap l, l,  \ 10 - smm-d16
+   0                 -1 code32 format-descriptor  swap l, l,  \ 18 - smm-c32
+   0                 -1 data32 format-descriptor  swap l, l,  \ 20 - smm-d32
+   \ End of GDT
+
    cs: ds  smm-save-seg d# 00 +  #)  svdc
-   cs: smm-gdt h# 18 + #)  ds  rsdc   \ GDT reference
+   cs: smm-gdt smm-d16 + #)  ds  rsdc
    \ Now we can use the data segment
    es  smm-save-seg d# 10 +  #)  svdc
    fs  smm-save-seg d# 20 +  #)  svdc
    gs  smm-save-seg d# 30 +  #)  svdc
    ss  smm-save-seg d# 40 +  #)  svdc
-   cs  smm-save-seg d# 50 +  #)  svdc       \ So we can get back to the boost segment
+\   cs  smm-save-seg d# 50 +  #)  svdc       \ So we can get back to the boost segment
 
-   smm-gdt h# 18 + #)  ss  rsdc  \ GDT reference
+   smm-gdt smm-d16 + #)  ss  rsdc
 
    op: sp  smm-save-esp #)  mov
    smm-stack #  sp  mov      \ Now we have a stack
@@ -78,72 +99,65 @@
    op: ax         push
 
    cr3 ax mov  op: ax push
-   sp  smm-sp #)  mov
+   \ The real-mode stack pointer is now at a known location
 
 \ 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
+   op: smm-gdt 2+ #) lgdt
 
    cr0 ax mov  1 # al or  ax cr0 mov   \ Enter protected mode
-   op: here 7 + smm-handler - +smm  h# 20 #)  far jmp  \ GDT reference
+   op: here 7 + smi-handler - +smm smm-c32 #)  far jmp
    32-bit
 
    \ Reload segment registers with protected mode bits
-   op: h# 28 # ax mov   \ GDT reference
+   op: smm-d32 # ax mov
    ax ds mov  ax es mov  ax fs mov  ax gs mov  ax ss mov
 
+[ifdef] virtual-mode
    \ Turn on paging
-   smm-pdir +smm   #)  ax  mov
+   smm-pdir #)  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
+[then]
 
 \ Beginning of Forth-specific stuff
-   smm-forth-origin +smm #)  bx  mov
-   smm-forth-up     +smm #)  up  mov
-   smm-forth-entry  +smm #)  ip  mov
+   smm-forth-base  #)  bx  mov
+   smm-forth-up    #)  up  mov
+   smm-forth-entry #)  ip  mov
 
    \ Exchange the stack and return stack pointer with the smi versions
-   'user sp0  sp  mov
-   'user rp0  rp  mov
+   'user sp0 sp mov  smm-save-sp0 #) sp xchg  sp 'user sp0 mov
+   'user rp0 rp mov  smm-save-rp0 #) rp xchg  rp 'user rp0 mov
 
-   'user smi-sp0  sp  xchg
-   'user smi-rp0  rp  xchg
-
-   sp  'user sp0  mov
-   rp  'user rp0  mov
-
-
    cld
 c;
 code (smi-return)   \ This code field must be relocated after copying to SMM memory
    \ Exchange the stack and return stack pointer with the smi versions
-   'user sp0  sp  mov
-   'user rp0  rp  mov
+   'user sp0 sp mov  smm-save-sp0 #) sp xchg  sp 'user sp0 mov
+   'user rp0 rp mov  smm-save-rp0 #) rp xchg  rp 'user rp0 mov
 
-   'user smi-sp0  sp  xchg
-   'user smi-rp0  rp  xchg
-
-   sp  'user sp0  mov
-   rp  'user rp0  mov
-
    \ End of Forth-specific stuff
 
+[ifdef] virtual-mode
    \ Turn off paging
    cr0 ax mov  h# 8000.0000 invert # ax and  ax cr0 mov	 \ Turn off Paging Enable bit
+[then]
 
-   here 7 +  smm-handler -  h# 08 #)  far jmp     \ Get into the boosted segment
+   here 7 +  smi-handler -  smm-c16 #)  far jmp     \ Get into the boosted segment
    16-bit
 
+   smm-d16 # ax mov  ax ss mov  ax ds mov      \ Reload data and stack segments
+
    cr0 ax mov  1 invert # al and  ax cr0 mov   \ Exit protected mode
 
    \ Reload data segment registers
-   cs: smm-gdt h# 18 + #)  ss  rsdc   \ GDT reference
-   cs: smm-gdt h# 18 + #)  ds  rsdc   \ GDT reference
+\   cs: smm-gdt smm-d16 + #)  ss  rsdc
+\   cs: smm-gdt smm-d16 + #)  ds  rsdc
 
    op: smm-save-gdt #) lgdt
 
-   smm-sp #)  sp  mov
+   smm-sp #  sp  mov
    op: ax pop  ax cr3 mov
 
    op: ax        pop
@@ -162,9 +176,9 @@
 
    rsm
 end-code
-here smm-handler - constant /smm-handler
+here smi-handler - constant /smi-handler
 
-: smi-return  ( -- )  [ ' (smi-return) smm-handler -  +smm ] literal  execute  ;
+: smi-return  ( -- )  [ ' (smi-return) smi-handler -  +smm ] literal  execute  ;
 defer handle-smi  ' noop is handle-smi
 create smm-exec  ] handle-smi smi-return [
 
@@ -192,27 +206,28 @@
    \  Base     Limit
    smm-base  smm-size 1-  h# 133b msr!
 
-   smm-base smm-header + 0   h# 132b msr!  \ Offset of SMM Header
+   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
 
-   smm-handler smm-base  /smm-handler  move
+   smi-handler smm-base  /smi-handler  move
 
    \ Relocate the code field of the code word that is embedded in the sequence
-   ['] (smi-return) smm-handler -  +smm  ( cfa-adr )
+   ['] (smi-return) smi-handler -  +smm  ( cfa-adr )
    dup ta1+ swap token!
 
-   set-smm-descs
-   cr3@ smm-pdir +smm l!
+[ifdef] virtual-mode
+   cr3@ smm-pdir l!
+[then]
 
-   origin smm-forth-origin +smm l!
-   smm-exec smm-forth-entry +smm l!
-   up@ smm-forth-up +smm l!
-   h# 800 +smm smi-sp0 !
-   h# c00 +smm smi-rp0 !
+   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
 ;
@@ -220,18 +235,19 @@
 : smi-interact  ( -- )  ." In SMI" cr  quit  ;
 ' smi-interact is handle-smi
 
-: smm-cs-base   ( -- l )      smm-header h# 1c - +smm l@  ;
-: smm-eip       ( -- l )      smm-header h# 10 - +smm l@  ;
-: smm-next-eip  ( -- l )      smm-header h# 14 - +smm l@  ;
-: smm-flags     ( -- w )      smm-header h# 24 - +smm w@  ;
-: smm-io-port   ( -- port# )  smm-header h# 28 - +smm w@  ;
-: smm-io-size   ( -- size )   smm-header h# 26 - +smm w@  ;
-: smm-io-data   ( -- data )   smm-header h# 2c - +smm l@  ;
+\ : smm-cs-base   ( -- l )      smm-header h# 1c - l@  ;
+\ : smm-eip       ( -- l )      smm-header h# 10 - l@  ;
+\ : smm-next-eip  ( -- l )      smm-header h# 14 - l@  ;
+: smm-flags     ( -- w )      smm-header h# 24 - w@  ;
+: smm-io-port   ( -- port# )  smm-header h# 28 - w@  ;
+: smm-io-size   ( -- size )   smm-header h# 26 - w@  ;
+: smm-io-data   ( -- data )   smm-header h# 2c - l@  ;
+\ Stacked registers:  0:CR3, 1:portCF8, 2:DI, 3:SI, 4:BP, 5:SP, 6:BX, 7:DX, 8:CX, 9:AX
 : smm-config-adr  ( -- adr )
-   smm-sp +smm w@ +smm la1+ @ h# 7fff.fffc and
+   smm-regs la1+ @ h# 7fff.fffc and
    smm-io-port 3 and  or
 ;
-: smm-eax       ( -- adr )  smm-sp +smm w@ +smm 9 la+  ;
+: smm-eax       ( -- adr )  smm-regs 9 la+  ;
 
 : vr-spoof?  ( -- handled? )  false  ;
 : config-spoof?  ( -- handled? )




More information about the OpenBIOS mailing list