[OpenBIOS] r799 - dev/geode

svn at openbios.org svn at openbios.org
Thu Jan 31 11:15:59 CET 2008


Author: wmb
Date: 2008-01-31 11:15:58 +0100 (Thu, 31 Jan 2008)
New Revision: 799

Modified:
   dev/geode/smi.fth
Log:
Geode SMI handler - the code is pretty tight now, using only one page of SMM RAM.


Modified: dev/geode/smi.fth
===================================================================
--- dev/geode/smi.fth	2008-01-31 05:16:56 UTC (rev 798)
+++ dev/geode/smi.fth	2008-01-31 10:15:58 UTC (rev 799)
@@ -9,74 +9,65 @@
 
 previous definitions
 
-h# 4000.0000 constant smm-base
-h#    1.0000 constant smm-size
+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 +  ;
 
-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     la1+
+h# 28 constant /smm-gdt
+
+\ The handler code takes about h# 140 bytes
+
+\ 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+
 
-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     la1+
-dup constant smm-sp      wa1+
-drop
+\ 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
 
-: 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!         ( )
+h# 300 constant smm-header
+
+: set-descr  ( base limit d.type sel -- )
+   >r  format-descriptor   ( 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 w!   \ GDT limit
+\   smm-base -1 code32 format-descriptor  smm-gdt 8 + +smm d!  \ Boosted code32
+   smm-base smm-size 1- code16 h# 08 set-descr
+   smm-base smm-size 1- data16 h# 10 set-descr
+   0 -1 code32 h# 18 set-descr
+   0 -1 data32 h# 20 set-descr
+   /smm-gdt 1-   smm-gdtp +smm      w!  \ GDT limit
    smm-gdt +smm  smm-gdtp +smm wa1+ l!  \ GDT base
 ;
 
 nuser smi-sp0
 nuser smi-rp0
-defer smi-return
-: smi-exec  ( -- )
-   ." Forth SMI handler" cr
-   quit
-   smi-return
-;
 
 label smm-handler
    16-bit
 
-   cs: ds      smm-ds #)  svdc
-   cs: smm-data16 #)  ds  rsdc   \ Now we have a data segment
+   cs: ds  smm-save-seg d# 00 +  #)  svdc
+   cs: smm-gdt h# 10 + #)  ds  rsdc   \ Now we have a 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
 
-   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
+   smm-gdt h# 10 + #)  ss  rsdc
 
-   op: sp  smm-esp #)  mov
+   op: sp  smm-save-esp #)  mov
    smm-stack #  sp  mov      \ Now we have a stack
 
    op: pusha
@@ -88,30 +79,18 @@
    cr3 ax mov  op: ax push
    sp  smm-sp #)  mov
 
-\ ---
 \ 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
+   cr0 ax mov  1 # al or  ax cr0 mov   \ Enter protected mode
+   op: here 7 + smm-handler - +smm  h# 18 #)  far jmp
    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
+   op: h# 20 # ax mov
+   ax ds mov  ax es mov  ax fs mov  ax gs mov  ax ss mov
 
    \ Turn on paging
    smm-pdir +smm   #)  ax  mov
@@ -121,6 +100,7 @@
 \ Beginning of Forth-specific stuff
    smm-forth-origin +smm #)  bx  mov
    smm-forth-up     +smm #)  up  mov
+   smm-forth-entry  +smm #)  ip  mov
 
    \ Exchange the stack and return stack pointer with the smi versions
    'user sp0  sp  mov
@@ -132,13 +112,10 @@
    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;
-code (smi-return)
+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
@@ -149,30 +126,24 @@
    sp  'user sp0  mov
    rp  'user rp0  mov
 
-\ End of Forth-specific stuff
+   \ End of Forth-specific stuff
 
    \ 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
+   smm-save-seg d# 50 + +smm #)  cs  rsdc
    16-bit
-   here 2 + #) jmp  \ 16-bit JMP zeros EIP[31:16]
+   op:  here 5 +  smm-base - #) jmp  \ Decrease IP while increasing the segment register
 
-\ >Test
+   \ Reload data segment registers
+   cs: smm-gdt h# 10 + #)  ss  rsdc
+   cs: smm-gdt h# 10 + #)  ds  rsdc
 
    op: smm-save-gdt #) lgdt
 
-\ ---
    smm-sp #)  sp  mov
    op: ax pop  ax cr3 mov
 
@@ -182,86 +153,74 @@
 
    op: popa
 
-   op: smm-esp #)  sp  mov
+   op: smm-save-esp #)  sp  mov
 
-   smm-ss #)  ss  rsdc
-   smm-gs #)  gs  rsdc
-   smm-fs #)  fs  rsdc
-   smm-es #)  es  rsdc
-   smm-ds #)  ds  rsdc
+   smm-save-seg d# 40 + #)  ss  rsdc
+   smm-save-seg d# 30 + #)  gs  rsdc
+   smm-save-seg d# 20 + #)  fs  rsdc
+   smm-save-seg d# 10 + #)  es  rsdc
+   smm-save-seg d# 00 + #)  ds  rsdc
 
    rsm
 end-code
 here smm-handler - constant /smm-handler
 
+: smi-return  ( -- )  [ ' (smi-return) smm-handler -  +smm ] literal  execute  ;
+defer handle-smi  ' noop is handle-smi
+create smm-exec  ] handle-smi smi-return [
+
 : setup-smi  ( -- )
-   \ Map the SMM region to physical memory at e.0000
+   \ 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.0000 , i.e. 64K
-   h# 2.c00e0.40000.ffff0. h# 1000.0026 msr!
+   \ The mask is ffff.f000 , i.e. 4K
 
-   \ Put 64K SMM memory at 4000.0000 in the processor linear address space
+   \ 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
-   h# 4000f.0.00.40000.1.01. h# 180e msr!
+   \ 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!
+   \ The limit here must be large enough to cover the code address
+   \ between the time that we reenter real mode and the time we
+   \ reestablish the boosted descriptor.
    smm-base  -1  h# 133b msr!   \ Big limit
 
-   smm-base smm-size + 0   h# 132b msr!  \ Offset of SMM Header
+   smm-base smm-header + 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
+   \ Unnecessary if already in mapped memory
+   \ smm-base dup  smm-size  -1 mmu-map
 
    smm-handler smm-base  /smm-handler  move
 
+   \ Relocate the code field of the code word that is embedded in the sequence
    ['] (smi-return) smm-handler -  +smm  ( cfa-adr )
    dup ta1+ swap token!
 
    set-smm-descs
    cr3@ smm-pdir +smm l!
+
    origin smm-forth-origin +smm l!
+   smm-exec smm-forth-entry +smm l!
    up@ smm-forth-up +smm l!
-   h# 1000 +smm smi-sp0 !
-   h# 2000 +smm smi-rp0 !
+   h# 800 +smm smi-sp0 !
+   h# c00 +smm smi-rp0 !
 ;
-: do-smi-return  ( -- )
-   ['] (smi-return) smm-handler -  +smm  execute
-;
-' do-smi-return is smi-return
 
+: smi-interact  ( -- )  ." In SMI" cr  quit  ;
+' smi-interact is handle-smi
+
 : 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
-[then]
-   
-[ifdef] notyet
-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  ;
+code smi  smint  c;




More information about the OpenBIOS mailing list