[openfirmware] r843 - cpu/ppc/build cpu/x86 cpu/x86/build cpu/x86/pc cpu/x86/pc/biosload cpu/x86/pc/olpc dev dev/geode dev/geode/display dev/mmc/sdhci dev/olpc/keyboard dev/pci dev/video/common dev/video/controlr ofw/fs ofw/fs/fatfs

svn at openfirmware.info svn at openfirmware.info
Thu Jul 3 22:25:28 CEST 2008


Author: wmb
Date: 2008-07-03 22:25:27 +0200 (Thu, 03 Jul 2008)
New Revision: 843

Added:
   cpu/x86/pc/apic.fth
   cpu/x86/pc/biosints.fth
   cpu/x86/pc/biosload/callvbe.fth
   cpu/x86/pc/biosload/config-i945.fth
   cpu/x86/pc/biosload/config-usbkey.fth
   cpu/x86/pc/olpc/acpi.fth
   cpu/x86/pc/olpc/dsdt.bth
   cpu/x86/pc/olpc/dsdt.dsl
   cpu/x86/pc/olpc/gxearly.fth
   cpu/x86/pc/olpc/inituart.fth
   cpu/x86/pc/olpc/lxearly.fth
   cpu/x86/pc/olpc/smbios.fth
   cpu/x86/pc/olpc/ssdt.fth
   cpu/x86/pc/olpc/vga.fth
   cpu/x86/pc/rmtools.fth
   cpu/x86/pc/tsccal1.fth
   dev/geode/display/gxvga.fth
   dev/geode/msr.fth
   dev/pci/intmap.fth
   ofw/fs/romfs.fth
Modified:
   cpu/ppc/build/builder.dic
   cpu/x86/assem.fth
   cpu/x86/build/builder.dic
   cpu/x86/code.fth
   cpu/x86/descr.fth
   cpu/x86/disassem.fth
   cpu/x86/dtacc.fth
   cpu/x86/pc/biosload/addrs.fth
   cpu/x86/pc/biosload/biostart.bth
   cpu/x86/pc/biosload/bootsec.fth
   cpu/x86/pc/biosload/callbios.fth
   cpu/x86/pc/biosload/fw.bth
   cpu/x86/pc/biosload/reset.bth
   cpu/x86/pc/biosload/rmenter.fth
   cpu/x86/pc/biosload/start.bth
   cpu/x86/pc/linux.fth
   cpu/x86/pc/mmusetup.fth
   cpu/x86/pc/olpc/addrs.fth
   cpu/x86/pc/olpc/chipinit.fth
   cpu/x86/pc/olpc/config.fth
   cpu/x86/pc/olpc/countdwn.fth
   cpu/x86/pc/olpc/devices.fth
   cpu/x86/pc/olpc/devsmall.fth
   cpu/x86/pc/olpc/fw.bth
   cpu/x86/pc/olpc/fwsmall.bth
   cpu/x86/pc/olpc/gui.fth
   cpu/x86/pc/olpc/linuxserial.fth
   cpu/x86/pc/olpc/loaddropins.fth
   cpu/x86/pc/olpc/lxmsrs.fth
   cpu/x86/pc/olpc/mfgdata.fth
   cpu/x86/pc/olpc/olpc.bth
   cpu/x86/pc/olpc/probemem.fth
   cpu/x86/pc/olpc/reset.bth
   cpu/x86/pc/olpc/resume.bth
   cpu/x86/pc/olpc/rmstart.fth
   cpu/x86/pc/olpc/romreset.bth
   cpu/x86/pc/olpc/rtcwake.fth
   cpu/x86/pc/olpc/security.fth
   cpu/x86/pc/olpc/start.bth
   cpu/x86/pc/olpc/suspend.fth
   cpu/x86/pc/olpc/versions.fth
   cpu/x86/pc/olpc/vsapci.fth
   cpu/x86/pc/resetend.fth
   cpu/x86/pc/tsccal.fth
   dev/egatext.fth
   dev/geode/acpi.fth
   dev/geode/display/gxfb.fth
   dev/geode/smi.fth
   dev/geode/usb.fth
   dev/mmc/sdhci/sdhci.fth
   dev/mmc/sdhci/sdmmc.fth
   dev/olpc/keyboard/selftest.fth
   dev/video/common/textmode.fth
   dev/video/controlr/vga.fth
   ofw/fs/fatfs/partition.fth
Log:
OLPC - Omnibus checkin of new stuff for OFW2.


Modified: cpu/x86/assem.fth
===================================================================
--- cpu/x86/assem.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/assem.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -33,6 +33,8 @@
 
 : real-mode	  ( - bool )         real-mode# is memory-mode  ;
 : protected-mode  ( - bool )    protected-mode# is memory-mode  ;
+alias 16-bit real-mode
+alias 32-bit protected-mode
 
 : real?		( - bool )   memory-mode      real-mode# =  ;
 : protected?	( - bool )   memory-mode protected-mode# =  ;
@@ -71,6 +73,8 @@
 : ad:   ( -- )   true is address-ov  h# 67 asm8,  ;
 : clear-ov   ( -- )   false is data-ov   false is address-ov  ;
 
+: op16?  ( -- flag )  real? data-ov xor  ;
+
 : (asm,)  ( flag -- )  real? xor if   asm16,   else   asm32,   then  ;
 : adr,    ( n -- )  address-ov (asm,)  ;
 : asm,    ( n -- )  data-ov    (asm,)  ;
@@ -340,7 +344,7 @@
 	 swap asm8, asm8,
       else				( op disp )
 	 prefix-0f  swap h# 10 + asm8,
-	 real? if  2  else  4  then  -	 adr,
+	 op16? if  2  else  4  then  -	 adr,
       then
       normal
 ;
@@ -429,13 +433,13 @@
    OVER #) =  IF                                ( dst mode apf )
       NIP C@ INTER @  IF                        ( offset segment code )
          1 AND  IF  352  ELSE  232  THEN  ASM8, ( offset segment )
-         SWAP ADR, ASM16,  INTER OFF            ( )
+         SWAP asm, ASM16,  INTER OFF            ( )
       ELSE					( dst code )
          SWAP HERE 2+ -  SWAP                   ( rel-dst code )
          2DUP 1 AND SWAP BIG? 0= AND  IF        ( rel-dst code )
             2 OP,  ASM8,                        ( )
          ELSE                                   ( rel-dst code )
-	    ASM8,  real? if
+	    ASM8,  op16? if
 	       1- asm16,
 	    else
 	       3 - asm32,

Modified: cpu/x86/code.fth
===================================================================
--- cpu/x86/code.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/code.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -2,7 +2,7 @@
 purpose: Defining words for code definitions
 
 only forth also assembler also forth definitions
-: entercode  ( -- ) !csp also assembler  ;
+: entercode  ( -- ) !csp also assembler  protected-mode  ;
 : code   \ name  ( -- )
    create  here here 4 - token!  do-entercode
 ;

Modified: cpu/x86/descr.fth
===================================================================
--- cpu/x86/descr.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/descr.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -73,6 +73,24 @@
    8 +loop
    r> base !
 ;
+: dump-gdt  ( -- )  gdtr@ nip 1+ 0 dump-dt  ;
+: format-descriptor  ( base limit 16|32 type -- low high )
+   >r >r  dup h# 100000 u>=  if         ( base limit r: type 16|32 )
+      \ 4K granularity - scale limit and set G bit
+      d# 12 rshift  h# 80.0000 or       ( base limit' r: type 16|32 )
+   then                                 ( base limit r: type 16|32 )
+   r> d# 32 =  if  h# 40.0000 or  then  ( base limit r: type )
+   lwsplit  >r >r                       ( base r: type limit.hi limit.lo )
+   lwsplit                              ( base.lo base.hi r: type limit.hi limit.lo )
+   r> rot wljoin swap                   ( descr.lo base.hi  r: type limit.hi )
+   wbsplit                              ( descr.lo base.hl base.hh  r: type limit.hi )
+   2r> rot bljoin                       ( descr.lo descr.hi )
+;
+d# 16 h# 9a 2constant code16
+d# 16 h# 92 2constant data16
+d# 32 h# 9a 2constant code32
+d# 32 h# 92 2constant data32
+
 \ LICENSE_BEGIN
 \ Copyright (c) 2006 FirmWorks
 \ 

Modified: cpu/x86/disassem.fth
===================================================================
--- cpu/x86/disassem.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/disassem.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -56,16 +56,16 @@
 : ?+  ( -- )
    ea-text c@ 1 >  if  " +" $add-text  then
 ;
-: ?-  ( -- )
-   ea-text c@ 1 >  if  " -" $add-text  then
+: ?-  ( disp -- )
+   ea-text c@ 1 >  if  " -" $add-text  negate  then
 ;
 : get-disp  ( mod -- adr len )
    case
    0  of  " "  exit    endof
    1  of  op8@ bext     endof
-   2  of  adv@ wext     endof
+   2  of  adv@  ad32? 0=  if  wext  then  endof
    endcase
-   dup 0>=  if  ?+  else  ?-  negate  then  
+   dup 0>=  if  ?+  else  ?-  then  
    (u.) disp-buf pack  count
 ;
 \ Used when "w" field contains 0
@@ -85,6 +85,7 @@
 end-string-array
 
 : >reg  ( -- adr len )  >regw count  op32? 0=  if  1 /string  then  ;
+: >areg  ( -- adr len )  >regw count  ad32? 0=  if  1 /string  then  ;
 
 : >greg  ( -- adr len )  wbit  if  >reg  else  >reg8 count  then  ;
 
@@ -101,7 +102,7 @@
       drop                               ( scale )
       if  ?+  " UNDEF" $add-text  then   ( )
    else                                  ( scale index-reg )
-      ?+  >reg $add-text                 ( scale )
+      ?+  >areg $add-text                ( scale )
       >scale count  $add-text            ( )
    then                                  ( )
 ;
@@ -110,7 +111,7 @@
 : add-disp  ( sib? reg mod -- )
    .[                            ( sib? reg mod )
    2dup 0<>  swap 5 <>  or  if   ( sib? reg mod )   \ D32
-      swap >reg $add-text        ( sib? mod )
+      swap >areg $add-text       ( sib? mod )
    else                          ( sib? reg mod )
       2drop 2                    ( sib? mod=2 )
    then                          ( sib? mod )
@@ -195,6 +196,7 @@
 end-string-array
 
 : .segment  ( -- )  3 2 ibits  >segment ".  ;
+
 string-array >adjust
    ," daa"  ," das"  ," aaa"  ," aas"
 end-string-array
@@ -203,6 +205,8 @@
 0 value reg-field
 : get-ea  ( -- )  get-op  midbits  is reg-field  ;
 
+: sreg  ( -- )  reg-field  >segment ".  ;
+
 : gb/v  ( -- )  reg-field  >greg type  ;
 : ib    ( -- )  op8@ bext  (.) type  ;
 : ,ib  ( -- )  .,  ib  ;
@@ -232,7 +236,7 @@
 end-string-array
 
 : showbranch  ( offset -- )
-   pc @  ad32?  if  ( offset pc )
+   pc @  op32?  if  ( offset pc )
       +                    ( pc' )
    else                    ( offset pc )
       lwsplit  -rot        ( pc.high offset pc.low )
@@ -242,7 +246,7 @@
    dup branch-target !  showaddr
 ;
 : jb  ( -- )  op8@ bext  showbranch  ;
-: jv  ( -- )  adv@  showbranch  ;
+: jv  ( -- )  opv@  showbranch  ;
 
 : .jcc  ( -- )  ." j"  low4bits >cond ".  op-col jb  ;
 : ea,g  ( -- )  get-ea  .ea ., gb/v  ;
@@ -308,7 +312,7 @@
       7 of  ." cmpxchg" op-col          ea,g  endof
       8 of  .push  ." gs"  endof
       9 of  .pop   ." gs"  endof
-   \  a of  ???
+      a of  ." rsm"  end-found on  endof
       b of  ." bt"   op-col             ea,g  endof
       c of  ." shrd" op-col  1 is wbit  ea,g  ,ib  endof
       d of  ." shrd" op-col  1 is wbit  ea,g  ,cl  endof
@@ -353,11 +357,19 @@
          then
    endcase
 ;
+: 2b7op  ( -- )
+   low4bits  case
+      8 of  ." svdc"  op-col get-ea  1 is wbit  .ea  ., sreg endof
+      9 of  ." rsdc"  op-col get-ea  1 is wbit  sreg ., .ea  endof
+      .unimp
+   endcase
+;
 : msrop  ( -- )
    low4bits case
       0 of  ." wrmsr"  endof
       1 of  ." rdtsc"  endof
       2 of  ." rdmsr"  endof
+      8 of  ." smint"  endof
       .unimp
    endcase
 ;
@@ -367,6 +379,7 @@
       0 of  2b0op  endof
       2 of  movspec  endof
       3 of  msrop    endof
+      7 of  2b7op    endof
       8 of  ." j"   low4bits >cond ".  op-col  jv  endof
       9 of  ." set" low4bits >cond ".  op-col  0 is wbit  get-ea  .ea  endof
       a of  2baop  endof
@@ -433,7 +446,6 @@
 : grp1op  ( -- )  get-ea  midbits .binop  ;
 : .test  ( -- )  ." test" op-col  ;
 
-: sreg  ( -- )  reg-field  >segment ".  ;
 : .op8  ( -- )
    low4bits  case
       0 of  grp1op    .byte .ea ., iub  endof
@@ -461,9 +473,10 @@
 
 : .4x  ( n -- )  push-hex <# u# u# u# u# u#> type pop-base  ;
 : ap  ( -- )
-   adv@ ." far "
+   opv@ ." far "
    op16@ push-hex (.) type pop-base
-   ." :"  ad32?  if  showaddr  else  .4x  then
+   ." :"  op32?  if  showaddr  else  .4x  then
+   end-found on
 ;
 
 string-array >8line-ops
@@ -512,8 +525,8 @@
       3 of  .ret           .near            endof
       4 of  ." les"        .lfp             endof
       5 of  ." lds"        .lfp             endof
-      6 of  .mov      op-col get-ea  ?.byte .ea  ,ib/v  endof
-      7 of  .mov      op-col get-ea         .ea  ,ib/v  endof
+      6 of  .mov           get-ea  ?.byte .ea  ,ib/v  endof
+      7 of  .mov           get-ea         .ea  ,ib/v  endof
       8 of  ." enter" op-col  iw ,ib        endof
       9 of  ." leave"                       endof
       a of  .ret             .far  iw       endof
@@ -552,7 +565,7 @@
 : .in    ( -- )  ." in"   op-col  ;
 : .out   ( -- )  ." out"  op-col  ;
 : .call  ( -- )  ." call" op-col  ;
-: .jmp   ( -- )  ." jmp"  op-col  ;
+: .jmp   ( -- )  ." jmp"  op-col  end-found on  ;
 : dx  ( -- )  ." edx"  ;
 
 : ub    ( -- )  op8@  (.) type  ;

Modified: cpu/x86/dtacc.fth
===================================================================
--- cpu/x86/dtacc.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/dtacc.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -29,9 +29,19 @@
       init-exceptions
    then
 ;
+\ Move the global descriptor table into the Forth region, thus freeing
+\ the low memory it currently occupies
+: move-gdt   ( -- )
+   gdtr@ 1+                       ( pa size )
+   h# 800 alloc-mem 8 round-up    ( pa size va )  \ Give it plenty of space
+   dup h# 800 erase               ( pa size va )
+   3dup swap move                 ( pa size va )
+   swap 1- gdtr!                  ( pa )
+   drop
+;
 
 stand-init: Exceptions
-   make-idt  stand-set-idt
+   make-idt  stand-set-idt  move-gdt
 ;
 
 \ LICENSE_BEGIN

Added: cpu/x86/pc/apic.fth
===================================================================
--- cpu/x86/pc/apic.fth	                        (rev 0)
+++ cpu/x86/pc/apic.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,68 @@
+purpose: Advanced Programmable Interrupt Controller (APIC) driver
+\ See license at end of file
+
+: apic@  ( index -- l )  h# fec0.0000 c!  h# fec0.0010 l@  ;
+: apic!  ( l index -- )  h# fec0.0000 c!  h# fec0.0010 l!  ;
+: apic-eoi  ( vector -- )  h# fec0.0040 l!  ;
+
+: .apic-mode  ( low -- )
+   8 rshift 7 and  case
+      0 of  ." Fixed  "  endof
+      1 of  ." LowPri "  endof
+      2 of  ." SMI    "  endof
+      3 of  ." Res3   "  endof
+      4 of  ." NMI    "  endof
+      5 of  ." Init   "  endof
+      6 of  ." Res6   "  endof
+      7 of  ." Ext    "  endof
+   endcase
+;
+
+: .apic-irq  ( int# -- )
+   2* h# 10 + dup apic@
+   ." Vec: "  dup h# ff and 2 u.r space
+   dup .apic-mode
+   dup h#  800 and  if  ." Logical  "  else  ." Physical "  then
+   dup h# 1000 and  if  ." Pending "  else  ." Idle    "  then
+   dup h# 2000 and  if  ." Low  "  else  ." High "  then
+   dup h# 8000 and  if
+      ." Level "  dup h# 4000 and  if  ." IRR "  else  ." EOI "  then
+   else  ." Edge      "  then
+   h# 10000 and  if  ." Masked "  else  ." Open   "  then
+   1+ apic@
+   ." EDID: " dup d# 16 rshift h# ff and  2 u.r
+   ."  Dest: " d# 24 rshift h# ff and 2 u.r
+   cr
+;
+: .apic-irqs  ( -- )
+   push-hex
+   1 apic@ d# 16 rshift h# ff and 1+  0  do
+      i 2 u.r space  i .apic-irq
+   loop
+   pop-base
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
+

Added: cpu/x86/pc/biosints.fth
===================================================================
--- cpu/x86/pc/biosints.fth	                        (rev 0)
+++ cpu/x86/pc/biosints.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,1074 @@
+
+[ifdef] syslinux-loaded   : disk-name  ( -- $ )  " /pci/ide at 0"  ;  [then]
+[ifdef] preof-loaded      : disk-name  ( -- $ )  " /pci/ide at 0"  ;  [then]
+[ifdef] rom-loaded        : disk-name  ( -- $ )  " sd:0"  ;        [then]
+
+struct
+  2 field >rm-gs
+  2 field >rm-fs
+  2 field >rm-es
+  2 field >rm-ds
+  4 field >rm-edi
+  4 field >rm-esi
+  4 field >rm-ebp
+  4 field >rm-exx
+  4 field >rm-ebx
+  4 field >rm-edx
+  4 field >rm-ecx
+  4 field >rm-eax
+  4 field >rm-retaddr
+  2 field >rm-flags
+drop
+
+: rm-es@  caller-regs >rm-es w@  ;
+: rm-es!  caller-regs >rm-es w!  ;
+
+: rm-ds@  caller-regs >rm-ds w@  ;
+: rm-ds!  caller-regs >rm-ds w!  ;
+
+: rm-ah@  caller-regs >rm-eax 1+ c@  ;
+: rm-ah!  caller-regs >rm-eax 1+ c!  ;
+: rm-al@  caller-regs >rm-eax c@  ;
+: rm-al!  caller-regs >rm-eax c!  ;
+: rm-ax@  caller-regs >rm-eax w@  ;
+: rm-ax!  caller-regs >rm-eax w!  ;
+: rm-eax@  caller-regs >rm-eax l@  ;
+: rm-eax!  caller-regs >rm-eax l!  ;
+
+: rm-bh@  caller-regs >rm-ebx 1+ c@  ;
+: rm-bh!  caller-regs >rm-ebx 1+ c!  ;
+: rm-bl@  caller-regs >rm-ebx c@  ;
+: rm-bl!  caller-regs >rm-ebx c!  ;
+: rm-bx@  caller-regs >rm-ebx w@  ;
+: rm-bx!  caller-regs >rm-ebx w!  ;
+
+: rm-ch@  caller-regs >rm-ecx 1+ c@  ;
+: rm-ch!  caller-regs >rm-ecx 1+ c!  ;
+: rm-cl@  caller-regs >rm-ecx c@  ;
+: rm-cl!  caller-regs >rm-ecx c!  ;
+: rm-cx@  caller-regs >rm-ecx w@  ;
+: rm-cx!  caller-regs >rm-ecx w!  ;
+
+: rm-dh@  caller-regs >rm-edx 1+ c@  ;
+: rm-dh!  caller-regs >rm-edx 1+ c!  ;
+: rm-dl@  caller-regs >rm-edx c@  ;
+: rm-dl!  caller-regs >rm-edx c!  ;
+: rm-dx@  caller-regs >rm-edx w@  ;
+: rm-dx!  caller-regs >rm-edx w!  ;
+
+: rm-edx@  caller-regs >rm-edx l@  ;
+: rm-edx!  caller-regs >rm-edx l!  ;
+
+: rm-ebx@  caller-regs >rm-ebx l@  ;
+: rm-ebx!  caller-regs >rm-ebx l!  ;
+
+: rm-ebp@  caller-regs >rm-ebp l@  ;
+: rm-ebp!  caller-regs >rm-ebp l!  ;
+
+: rm-ecx@  caller-regs >rm-ecx l@  ;
+: rm-ecx!  caller-regs >rm-ecx l!  ;
+
+: rm-edi@  caller-regs >rm-edi l@  ;
+: rm-edi!  caller-regs >rm-edi l!  ;
+
+: rm-esi@  caller-regs >rm-esi l@  ;
+: rm-esi!  caller-regs >rm-esi l!  ;
+
+: rm-retaddr@  caller-regs >rm-retaddr seg:off@  ;
+
+: rm-flags@  caller-regs >rm-flags w@  ;
+: rm-flags!  caller-regs >rm-flags w!  ;
+
+: rm-set-cf  rm-flags@  1 or  rm-flags!  ;
+: rm-clr-cf  rm-flags@  1 invert and  rm-flags!  ;
+
+true value show-rm-int?
+: noshow  false to show-rm-int?  ;
+variable save-eax
+: snap-int
+   true to show-rm-int?  rm-eax@ save-eax !
+;
+: showint
+  ." INT " rm-int@ .  save-eax @ wbsplit ." AH " .  ." AL " .
+  ." from " rm-retaddr@ . cr
+;
+: ?showint  show-rm-int?  if  showint  then  ;
+
+: !font  ( adr -- )
+   >seg:off  rm-es!  rm-ebp!
+   h# 10 rm-cx!  h# 18 rm-dx!     
+;
+: get-font  ( -- )
+   noshow
+   rm-al@ h# 30 =  if
+\      ." Int 10 get-font called - BH = " rm-bh@ .  cr
+      rm-bh@ case
+\ These numbers are cheats, pointing into the VIA BIOS
+         2 of  h# c69e0 !font   endof
+         3 of  h# c6138 !font   endof
+         4 of  h# c6538 !font   endof
+         5 of  h# c69e0 !font   endof
+         6 of  h# c77e0 !font   endof
+         7 of  h# c77e0 !font   
+\ Not sure why I did the ungrab thing
+\ h# 10 ungrab-rm-vector
+\ h# 15 ungrab-rm-vector
+         endof
+         ( default )  ." Unsupported get font - BH = " dup . cr  rm-set-cf
+      endcase
+   else
+      ." Int 10 set-font called"  cr
+   then
+;
+
+: set-mode3  ( -- )
+   stdout @  if
+      " text-mode3" stdout @ $call-method
+      stdout off
+   then
+;
+\ VBE status: AL = 4f -> function supported  else not supported
+\ AH = 0: success  1: fail  2: not supported in this config  3: invalid in this mode
+\ Mode: D[0:8] mode - bit 8=1 for VESA modes
+\   D11 -  (800) 0: BIOS default refresh rate  1: User CRTC values for refresh
+\   D14 - (4000) 0: Banked frame buffer        1: Linear frame buffer
+\   D15 - (8000) 0: Clear display memory       1: Don't clear
+
+create vbe-info
+   " VESA" here swap move  4 allot
+   h# 0300 w,
+   1 l,
+here vbe-info - constant /vbe-info
+
+\ This returns a 32-bit logical (virtual) address.  It needs
+\ to be converted to physical before accessing data, but the
+\ virtual version is also needed for things like relocating
+\ pointers embedded within the data.
+
+: vbebuf  ( -- ladr )  caller-regs >rm-edi w@  rm-es@ seg:off>  ;
+: >vbe-pa  ( offset -- padr )  vbebuf + >caller-physical  ;
+: vbedata  ( -- ladr )  vbebuf h# 100 +  ;
+
+: ?vbe2  ( -- )
+   0 >vbe-pa l@ h# 32454256 <>  if
+      ." Old-style VESA BIOS call not supported" cr
+      interact
+   then
+;
+
+\ oem-adr is the logical address in the OEM buffer area
+\ $ is the data to move into the OEM buffer
+\ vbe-offset is the location within the VESA struct for the far pointer
+\ Mode.w
+\ WinAAttrs.b  WinBAttrs.b  WinGranularity.w  WinSize.w
+\ WinASegment.w  WinBSegment.w  WinFunctPtr.l
+\ BytesPerScanLine.w
+
+\ Xres.w (pix or chr)
+\ Yres.w (pix or chr)
+\ Xcharsize.b (pixels)
+\ Ycharsize.b (pixels)
+\ NumPlanes.b
+\ BPP.b
+\ NumBanks.b
+\ MemModel.b
+\ BankSize.b (KiB)
+\ NumImagePages.b
+\ Res.b  1
+
+\ RedMaskSize.b   RedFieldPos.b   GrnMaskSize.b   GrnFieldPos.b
+\ BlueMaskSize.b  BlueFieldPos.b  RsvdMaskSize.b  RsvdFieldPos.b
+\ DirectColorModeInfo.b
+
+\ PhysBasePtr.l   Res.l 0   Res.w 0
+
+\ LinBytesPerScanLine.w
+\ BnkNumImagePages.b
+\ LinNumImagePages.b
+\ LinRedMaskSize.b   LinRedFieldPos.b   LinGrnMaskSize.b   LinGrnFieldPos.b
+\ LinBlueMaskSize.b  LinBlueFieldPos.b  LinRsvdMaskSize.b  LinRsvdFieldPos.b
+\ MaxPixelClock.d
+\ 189 reserved
+
+create mode3-info \ w b b w w w w d w   w w b b b b b b b b b 
+   h#  b w,  \ Windowed, (VGA), (Text), Color, no TTY Output, D1=1, hardware-supported
+     
+create mode12-info \ w b b w w w w d w   w w b b b b b b b b b 
+   h# db w,  \ Linear, (VGA), Graphics, Color, no TTY Output, D1=1, hardware-supported
+
+create mode-115-info
+   h# fb w,    \ Linear, NotVGA, Graphics, Color, no TTY Output, D1=1, hardware-supported
+   0 c,  0 c,  0 w,  d# 64 w,  0 w,  0 w,  0 l,  \ Not windowed
+   0 w,        \ BytesPerScanLine irrelevant in linear mode
+   d#  800 w,  d# 600 w,  \ X, Y res
+   d#   15 c,  d#  18 w,  \ Char width, height (sort of irrelevant)
+   1 c,        \ NumPlanes (irrelevant for linear?)
+   d# 24 c,    \ Bits/pixel
+   1 c,        \ NumBanks
+   6 c,        \ MemModel - DirectColor (?)
+   0 c,        \ Bank size (not banked)
+   0 c,        \ NumImagePages
+   1 c,        \ Reserved
+
+   \ Banked Color info
+   8 c, d# 16 c,    8 c, 8 c,   8 c,  0 c,   0 c,  0 c,  \ {RGBX}{Bits,Pos}
+   0 c,        \ Gamma fixed (change if we implement function 9)
+
+   fb-pci-base l,  0 l,  0 w,   \ Framebuffer address
+
+   \ Linear info
+   d# 4096 /w*  w,    \ Bytes per scan line
+   0 c,               \ No banks
+   
+\  fbsize  d# 1200 /  d# 900 /  2/  c,
+   3 c,               \ Number of images that will fit in framebuffer
+
+   8 c, d# 16 c,   8 c, 8 c,   8 c,  0 c,   0 c,  0 c,  \ {RGBX}{Bits,Pos}
+
+   d# 56,200,000 l,  \ Max pixel clock
+here mode-115-info -  constant /mode-115-info
+
+create mode-118-info
+   h# fb w,    \ Linear, NotVGA, Graphics, Color, no TTY Output, D1=1, hardware-supported
+   0 c,  0 c,  0 w,  d# 64 w,  0 w,  0 w,  0 l,  \ Not windowed
+   0 w,        \ BytesPerScanLine irrelevant in linear mode
+   d# 1024 w,  d# 768 w,  \ X, Y res
+   d#   15 c,  d#  18 w,  \ Char width, height (sort of irrelevant)
+   1 c,        \ NumPlanes (irrelevant for linear?)
+   d# 24 c,    \ Bits/pixel
+   1 c,        \ NumBanks
+   6 c,        \ MemModel - DirectColor (?)
+   0 c,        \ Bank size (not banked)
+   0 c,        \ NumImagePages
+   1 c,        \ Reserved
+
+   \ Banked Color info
+   8 c, d# 16 c,    8 c, 8 c,   8 c,  0 c,   0 c,  0 c,  \ {RGBX}{Bits,Pos}
+   0 c,        \ Gamma fixed (change if we implement function 9)
+
+   fb-pci-base l,  0 l,  0 w,   \ Framebuffer address
+
+   \ Linear info
+   d# 4096 /w*  w,    \ Bytes per scan line
+   0 c,               \ No banks
+   
+\  fbsize  d# 1200 /  d# 900 /  2/  c,
+   3 c,               \ Number of images that will fit in framebuffer
+
+   8 c, d# 16 c,   8 c, 8 c,   8 c,  0 c,   0 c,  0 c,  \ {RGBX}{Bits,Pos}
+
+   d# 56,200,000 l,  \ Max pixel clock
+here mode-118-info -  constant /mode-118-info
+
+create mode-120-info
+   h# fb w,    \ Linear, NotVGA, Graphics, Color, no TTY Output, D1=1, hardware-supported
+   0 c,  0 c,  0 w,  d# 64 w,  0 w,  0 w,  0 l,  \ Not windowed
+   0 w,        \ BytesPerScanLine irrelevant in linear mode
+   d# 1200 w,  d# 900 w,  \ X, Y res
+   d#   15 c,  d#  18 w,  \ Char width, height (sort of irrelevant)
+   1 c,        \ NumPlanes (irrelevant for linear?)
+   d# 16 c,    \ Bits/pixel
+   1 c,        \ NumBanks
+   6 c,        \ MemModel - DirectColor (?)
+   0 c,        \ Bank size (not banked)
+   0 c,        \ NumImagePages
+   1 c,        \ Reserved
+
+   \ Banked Color info
+   5 c, d# 11 c,   6 c, 5 c,   5 c,  0 c,   0 c,  0 c,  \ {RGBX}{Bits,Pos}
+   0 c,        \ Gamma fixed (change if we implement function 9)
+
+   fb-pci-base l,  0 l,  0 w,   \ Framebuffer address
+
+   \ Linear info
+   d# 1200 /w*  w,    \ Bytes per scan line
+   0 c,               \ No banks
+   
+\  fbsize  d# 1200 /  d# 900 /  2/  c,
+   7 c,               \ Number of images that will fit in framebuffer
+
+   5 c, d# 11 c,   6 c, 5 c,   5 c,  0 c,   0 c,  0 c,  \ {RGBX}{Bits,Pos}
+
+   d# 56,200,000 l,  \ Max pixel clock
+here mode-120-info -  constant /mode-120-info
+
+
+: vbe-farptr!  ( oem-adr  $  vbe-offset -- oem-adr' )
+   >r rot                    ( adr len oem-adr  r: vbe-offset )
+   dup  r> >vbe-pa seg:off!  ( adr len oem-adr )  \ Set VbeFarPtr
+   2>r                       ( adr r: len oem-adr )
+   2r@  >caller-physical place-cstr drop  ( r: len oem-adr )
+   2r> + 1+
+;
+
+
+
+: vbe-ok  ( -- )  h# 4f rm-ax!  ;
+: vbe-modes  ( -- )
+   ?vbe2
+   h# 41534556              0 >vbe-pa l!   \ VbeSignature
+   h# 0300                  4 >vbe-pa w!   \ VbeVersion
+   1                    d# 10 >vbe-pa l!   \ Capabilities - 8-bit DACs
+   vbebuf d# 34 +       d# 14 >vbe-pa seg:off!   \ VbeFarPtr to mode list
+   fbsize d# 16 rshift  d# 18 >vbe-pa w!   \ TotalMemory
+   h# 0200              d# 20 >vbe-pa w!   \ OemSoftwareRev
+
+   vbedata                    ( oem-adr )
+   " OLPC"     6 vbe-farptr!  ( oem-adr' ) \ OEMString
+   " OLPC" d# 22 vbe-farptr!  ( oem-adr' ) \ OEMVendorName
+   " XO"   d# 26 vbe-farptr!  ( oem-adr' ) \ OEMProductName
+   " 1a"   d# 30 vbe-farptr!  ( oem-adr' ) \ OEMProductRev
+   drop
+
+   \ Mode list
+   d# 34 >vbe-pa
+\        3 w!++  \ Text mode 3
+\   h#  12 w!++  \ Graphics mode 12
+   h# 115 w!++  \ 800x600x24
+   h# 118 w!++  \ 1024x768x24
+   h# 120 w!++  \ OLPC native mode
+   -1 swap w!   \ End of list
+
+   vbe-ok
+;
+: vbe-get-mode  ( -- )
+    rm-cx@  case
+       h# 115 of  mode-115-info /mode-115-info  endof
+       h# 118 of  mode-118-info /mode-118-info  endof
+       h# 120 of  mode-120-info /mode-120-info  endof
+       ( default )  ." Bad VBE mode number " dup . cr  0 0 rot  
+    endcase   ( adr len )
+
+   0 >vbe-pa h# 100 erase
+   0 >vbe-pa swap move
+;
+: vbe-set-mode  ( -- )
+   ." VBE set mode " rm-cx@ .  cr
+   debug-me
+;
+: vesa-bios  ( -- )
+   rm-al@  case
+      h# 00  of  vbe-modes      endof
+      h# 01  of  vbe-get-mode   endof
+      h# 02  of  vbe-set-mode   endof
+      ( default )  ." Unsupported VBE function" dup .x  cr
+   endcase
+;
+
+: set-mode12  ( -- )
+   " graphics-mode12" " screen-ih" eval $call-method
+   stdout off
+;
+: set-video-mode  ( mode -- )
+   case
+           3 of  set-mode3   endof
+       h# 12 of  set-mode12  endof
+       ( default )  ." Unsupported video mode " dup .x  cr  rm-set-cf
+   endcase
+;
+
+: set-cursor  ( -- )  rm-dh@  rm-dl@  ( row column ) 2drop  ;
+: get-ega-info  ( -- )
+   0 rm-bh!  3 rm-bl!   \ Color, 256K memory
+   0 rm-ch!  7 rm-cl!   \ Feature Bits, Primary EGA+ 80x25
+;
+
+: video-int  ( -- )  \ INT 10
+   noshow
+   rm-ah@  case
+      h#  0  of  rm-al@ set-video-mode  endof  \ Set mode - Should blank the screen
+      h#  2  of  set-cursor    endof
+      h#  a  of  rm-al@ emit   endof   \ Write character
+      h#  e  of  rm-al@ emit   endof   \ Write character
+      h# 11  of  get-font      endof   \ get or set font
+      h# 12  of  get-ega-info  endof   \ Get EGA Info (Alternate Select)
+      h# 20  of  endof
+      h# 4f  of  vesa-bios     endof
+
+      ( default )  ." Unimplemented video int - AH = " dup . cr  rm-set-cf
+   endcase
+;
+
+[ifdef] use-bios
+: bios-video-int  debug-me use-bios  ;
+[then]
+
+: sysinfo-int  ( -- )  \ INT 11
+   noshow
+   \ h# 4226 rm-eax!   \ to report 1 parallel and 1 serial port
+   h# 26 rm-eax!   \ 32 bits
+;
+
+0 value disk-ih
+false value show-reads?
+-1 value read-match
+
+: disk-read-sectors  ( adr sector# #sectors -- #read )
+   noshow
+   over read-match = if  ." Reading block " read-match .  debug-me  then
+
+   show-reads?  if  ." Read " 2 pick . over . dup .  ." -- "  then
+   " read-blocks" disk-ih $call-method
+   show-reads?  if  dup .  cr  then
+
+;
+
+0 value entry-count
+: ?hack
+   entry-count dup 1+ to entry-count  1 =  if
+      hack-fix-mode
+   then
+;
+
+: disk-write-sectors  ( adr sector# #sectors -- #read )
+\   ?hack
+   noshow
+
+\ ." Write " 2 pick . over . dup .  ." -- "
+\ over h# 8b74aaa =  if  debug-me  then
+   " write-blocks" disk-ih $call-method
+\ dup .  cr
+;
+
+: check-drive  ( -- error? )
+   rm-dl@  h# 80 <>  if  rm-set-cf  7 rm-ah!  true exit  then
+   disk-ih  0=  dup  if  rm-set-cf  h# aa rm-ah!   then
+;
+: read-sectors  ( -- )
+   check-drive  if  exit  then
+   disk-ih  0=  if  rm-set-cf  h# aa rm-ah! exit  then
+   rm-ch@  rm-cl@ 6 rshift  bwjoin  ( cylinder# )
+   h# ff *   rm-dh@ +               ( trk# )     \ 255 heads
+   h# 3f *  rm-cl@ h# 3f and 1-  +  ( sector# )  \ 63 is max sector#
+
+   rm-bx@  rm-es@  seg:off>  ( sector# adr )
+   swap  rm-al@                             ( adr sector# #sectors )
+   disk-read-sectors  rm-al!
+;
+: write-sectors  ( -- )
+   check-drive  if  exit  then
+   disk-ih  0=  if  rm-set-cf  h# aa rm-ah! exit  then
+   rm-ch@  rm-cl@ 6 rshift  bwjoin  ( cylinder# )
+   h# ff *   rm-dh@ +               ( trk# )     \ 255 heads
+   h# 3f *  rm-cl@ h# 3f and 1-  +  ( sector# )  \ 63 is max sector#
+
+   rm-bx@  rm-es@  seg:off>  ( sector# adr )
+   swap  rm-al@                             ( adr sector# #sectors )
+   disk-write-sectors  rm-al!
+;
+: drive-sectors  ( -- n )  " #blocks" disk-ih $call-method  ;
+: drive-params  ( -- )
+   noshow
+   check-drive  if  exit  then
+   drive-sectors                      ( #sectors )
+   h# 3f /                            ( #tracks )
+   h# ff / 1-                         ( maxcyl )  \ Max 255 heads is traditional
+\ dup ." MAXCYL " .  cr
+   wbsplit                            ( maxcyl.lo maxcyl.hi )
+   3 min  6 lshift  h# 3f or  rm-cl!  ( maxcyl.lo )  \ High cyl, max sector
+   rm-ch!                             ( ) \ Low byte of max cylinder
+   h# fe rm-dh!                       ( ) \ Max head number
+   h# 01 rm-dl!                       ( ) \ Number of drives
+   rm-clr-cf
+;
+
+: ds:si  ( -- adr )  rm-esi@  rm-ds@  seg:off>  ;
+: lba-read  ( -- )
+   check-drive  if  exit  then
+   ds:si  ( packet-adr )
+   >r  r@ 4 + seg:off@  r@ 8 + l@   r@ 2+ w@     ( adr sector# #sectors )
+\ ." LBA "
+   disk-read-sectors  r> 2+ w!
+;
+: lba-write  ( -- )
+   check-drive  if  exit  then
+   ds:si  ( packet-adr )
+   >r  r@ 4 + seg:off@  r@ 8 + l@   r@ 2+ w@     ( adr sector# #sectors )
+\ ." LBA "
+   disk-write-sectors  r> 2+ w!
+;
+
+: check-disk-extensions  ( -- )
+   noshow
+   check-drive  if  0 rm-bx! exit  then
+   rm-bx@  h# 55aa <>  if  exit  then
+   h# aa55 rm-bx!
+   h# 20 rm-ah!  1 rm-cx!
+;
+: ext-get-drive-params  ( -- )
+   noshow
+   check-drive  if  exit  then
+   0 rm-ah!
+   ds:si  >r    ( adr )
+   r@ 2 +  h# 0e  erase   \ CHS info not valid
+   drive-sectors r@ h# 10 + l!  0 r@ h# 14 + l!  \ Total #sectors
+   h# 200 r@ h# 18 + w!   \ Sector len
+   h# 1a                  ( written-length )
+   r@ w@  h# 1e >=  if
+      -1  r@ h# 1a + l!      \ No EDD
+      4 +                 ( written-length' )
+   then                   ( written-length )
+   r@ w@  h# 20 >=  if    ( written-length )
+      0 r@ h# 1e + w!        \ Ensure that device path info not interpreted
+      \ Don't claim these bytes
+   then                   ( written-length )
+   r> w!                  \ Number of bytes written
+   rm-clr-cf
+;
+
+: get-disk-type  ( -- )
+   noshow
+   check-drive  if  exit  then
+   3 rm-ah!
+   drive-sectors lwsplit rm-cx!  rm-dx!
+   rm-clr-cf
+;
+: reset-disks  ( -- )  noshow  ;
+
+: disk-int  ( -- )  \ INT 13 handler
+   rm-ah@ case
+      h# 00  of  reset-disks            endof  \ Reset disk system
+      h# 02  of  read-sectors           endof
+      h# 03  of  write-sectors          endof
+      h# 08  of  drive-params           endof
+      h# 15  of  get-disk-type          endof
+      h# 41  of  check-disk-extensions  endof
+      h# 42  of  lba-read   endof
+      h# 43  of  lba-write  endof
+      h# 48  of  ext-get-drive-params  endof
+      ( default )  ." Unsupported disk INT 13 - AH = " dup . cr
+   endcase
+;
+
+: /1k  d# 10 rshift  ;
+: bigmem-16bit  ( -- )
+   memory-limit
+   dup h# 100.0000  min  h# 10.0000 -  0 max  /1k  dup rm-ax!  rm-cx!
+   h# 100.0000 -  0 max  d# 16 rshift  dup rm-bx!  rm-dx!
+;
+: allmem  ( -- n )
+   " /memory" find-package 0= abort" No /memory node"  ( phandle )
+   " reg" rot get-package-property abort" No available property"  ( $ )
+   decode-int drop  get-encoded-int  h# 10.0000 round-up
+;
+
+\ E820 Address range descriptor format:
+\ 0: baseaddress.64b  8: length.64b  h#10: type.32b as below
+\    1 = AddressRangeMemory, available to OS
+\    2 = AddressRangeReserved, not available
+\    3 = AddressRangeACPI, available to OS
+\    4 = AddressRangeNVS, not available to OS
+\    Other = Not defined, not available
+
+create memdescs
+\  h#          0. d,                 'ebda 0  d,  1 l,  \  0 available
+\  'ebda       0  d,   h# a0000   'ebda  - 0  d,  3 l,  \ 14 reclaimable
+
+\ Test version
+   h#          0. d,              h# 80000 0  d,  1 l,  \  0 available
+\      h# 80000 0  d,   h# 9fc00 h# 80000 - 0  d,  3 l,  \ 14 reclaimable
+      h# 80000 0  d,   h# 9fc00 h# 80000 - 0  d,  1 l,  \ 14 available
+      h# 9fc00 0  d,   h# a0000 h# 9fc00 - 0  d,  2 l,  \ 28 reserved
+\ End test
+
+   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)
+   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
+;
+
+: system-memory-map  ( -- )  \ E820
+   rm-clr-cf              \ Possibly superfluous
+   rm-edx@  rm-eax!       \ Propagate "SMAP" signature to return register
+
+   \ Continue from address in EBX; if is is 0, start at the beginning
+   rm-ebx@  ?dup 0=  if  memdescs  then                ( adr )
+
+   \ At the end of the table, return 0 in ECX
+   dup  memdescs /memdescs +  =  if  drop  0 rm-ecx!  exit  then
+ 
+   \ Otherwise copy out the next table entry, return length in ECX and next address in EBX
+   dup  rm-edi@ h# ffff and rm-es@  seg:off>  ( adr dst )
+   rm-ecx@  move                              ( adr )
+   rm-ecx@ +  rm-ebx!                         ( )  \ Continuation
+;
+
+: bigmem-int  ( -- )
+   rm-clr-cf
+   rm-al@ case
+      h# 01 of  bigmem-16bit   endof
+      h# 20 of  system-memory-map  endof
+\     h# 81 of  pm-system-memory-map  endof
+      ( default )  rm-set-cf
+         ." Unsupported Bigmem int 15 AH=e8 AL=" dup . cr
+   endcase
+;
+
+: apm-power-status  ( -- )
+   1 rm-bh!  \ AC adapter on-line
+   0 rm-bl!  \ Battery high
+   1 rm-ch!  \ Battery high
+   d# 99 rm-cl!  \ Battery percentage
+   h# 8100 rm-dx!  \ Remaining battery life
+   1 rm-esi!  \ Number of batteries installed (only needed if bh is 80 on entry)
+;
+: apm-get-event  ( -- )
+   h# 80 rm-bx!  \ No events (3 for normal resume)
+;
+0 value apm-driver-version
+0 [if]
+: apm  ( -- )
+   rm-clr-cf
+\  ." APM - " rm-al@ . cr
+   rm-al@  case
+      h# 00 of  h# 101 rm-ax!  [char] P rm-bh!  [char] M rm-bl!  0 rm-cx!  endof  \ Query
+      h# 01 of  endof                       \ Connect real mode
+      h# 02 of  6 rm-ah!  rm-set-cf  endof  \ Connect PM16 (not supported)
+      h# 03 of  8 rm-ah!  rm-set-cf  endof  \ Connect PM32 (not supported)
+      h# 04 of  endof                       \ Disconnect
+      h# 05 of  noop  endof                 \ CPU is Idle
+      h# 06 of  noop  endof                 \ CPU is Busy
+      h# 07 of  ." Set power state " rm-bx@ . rm-cx@ . cr  interact  endof
+      h# 08 of  noop  endof                 \ Enable/Disable PM
+      h# 09 of  noop  endof                 \ Restore Power-On Defaults
+      h# 0a of  apm-power-status  endof
+      h# 0b of  apm-get-event   endof
+      h# 0c of  0 rm-cx!    endof    \ Power state APM enabled
+      h# 0d of  noop  endof                 \ Enable/Disable PM for a device
+      h# 0e of  rm-cx@ to apm-driver-version  h# 101 rm-ah!  endof        \ Reports APM driver version, returns APM BIOS version
+      h# 0f of  noop  endof                 \ Engage/disengage PM for devices
+      h# 10 of  1 rm-bl!  3 rm-cx!  endof   \ 1.2 Capabilities - 1 battery, standby and suspend, no resume timers
+      h# 11 of  h# c rm-ah!  rm-set-cf  endof  \ 1.2 Set resume timer
+      h# 12 of  h# c rm-ah!  rm-set-cf  endof  \ 1.2 Set resume on ring
+      h# 13 of  noop   endof                   \ 1.2 Enable/disable timer-based requests
+      h# 80 of  0 rm-ah!     rm-set-cf  endof  \ OEM installation check
+   endcase
+;
+[else]
+: apm  ( -- )  rm-set-cf  ;   \ Not supported; superseded by ACPI
+[then]
+
+\ System configure
+create sysconf
+  8 w,       \ 8 bytes following
+  h# fc c,   \ model
+  1 c,       \ Submodel
+  0 c,       \ BIOS rev
+  h# 74 c,   \ Feature - second 8259, RTC, INT 9 calls INT 15/4F, extended BIOS area
+  0 c,
+  0 c,
+  0 c,
+  0 c,
+
+: get-conf  ( -- )
+   sysconf rm-buf 8 move
+   rm-buf >seg:off  0 rm-es!  rm-bx! 
+   0 rm-ax!
+;
+
+: handle-mouse  ( -- )
+   rm-al@ case
+      1 of  rm-clr-cf  endof   \ Reset mouse
+      ( default )  ." Unsupported mouse INT 15 AH c2 AL " dup . cr   rm-set-cf
+   endcase
+;
+
+: system-int  ( -- )  \ INT 15 handler
+   noshow
+   rm-clr-cf
+   rm-ah@ case
+      h# 91 of  noshow 0 rm-ah!  endof   \ "pause" while waiting for I/O
+noop
+      h# 53 of  apm  endof
+      h# 86 of  rm-dx@  rm-cx@ wljoin us  endof  \ Delay microseconds
+      h# 8a of  memory-limit h# 400.0000 - 0 max  /1k  lwsplit rm-dx! rm-ax!  endof
+      h# 88 of  h# fffc rm-ax!  endof  \ Extended memory - at least 64 MB
+      h# c0 of  get-conf  endof
+      \ We use the extended BIOS data area as our workspace when loaded from another BIOS
+\      h# c1 of  rm-set-cf h# 86 rm-ah!  endof  \ No extended BIOS data area
+      h# c1 of  'ebda 4 rshift rm-es!  endof  \ Segment address of extended BIOS data area
+      h# c2 of  handle-mouse  endof
+      h# e8 of  bigmem-int  endof
+\     h# e9 of  endof   \ Don't know what this is.  Ralf Brown's interrupt list says
+\                       \ PhysTechSoft PTS ROM-DOS, but I doubt that is right
+      ( default )  rm-set-cf
+         ." Unsupported INT 15 AH=" dup . cr
+   endcase
+;
+
+0 value the-key
+0 value kbd-ih
+
+: poll-key  ( -- false | scan,ascii true )
+   the-key  ?dup  if  true exit  then
+   d# 50 ms   \ I don't know why this is necessary, but without it, you don't see the key
+   0 " get-scancode" kbd-ih $call-method  if    ( scancode )
+      dup h# 80 and  if                         ( scancode )
+         \ Discard release events and escapes (e0)
+         drop false                             ( false )
+      else
+         dup " scancode->char" kbd-ih $call-method  0=  if  0  then  ( scancode ascii )
+         dup h# 80 and  if  drop 0  then        \ Don't return e.g. 9B for arrows
+         swap bwjoin to the-key
+         the-key true
+      then
+   else
+      false
+   then
+;
+
+0 value polled?
+: poll-keystroke  ( -- )
+   noshow
+   polled?  0=  if  ." ? "  then
+   true to polled?
+   poll-key  if  ( scancode,ascii )
+      rm-ax!
+      rm-flags@ h# 40 invert and rm-flags!
+   else
+      rm-flags@ h# 40 or rm-flags!
+   then
+;
+: get-keystroke  ( -- )
+   noshow
+
+   begin  poll-key  until   ( scancode,ascii )
+   0 to the-key
+   rm-ax!
+
+   rm-al@ [char] q =  if  debug-me  then
+   false to polled?
+;
+
+: keyboard-int  ( -- )  \ INT 16 handler
+   rm-ah@ case
+      0 of  get-keystroke  endof
+      1 of  poll-keystroke  endof
+      2 of  noshow  0 rm-al!  endof  \ Claim that no shift keys are active
+      5 of  rm-cx@ to the-key  endof  \ Put keystroke in buffer
+      ( bit 7:sysrq  6:capslock  5:numlock 4:scrlock 3:ralt 2:rctrl 1:lalt 0:lctrl )
+      ( default )  ." Keyboard INT called with AH = " dup . cr
+   endcase
+;
+
+: cfgadr  ( -- adr )
+   rm-edi@  h# ff and   rm-bx@  8 lshift  or
+;
+: pcibios-installed  ( -- )
+   noshow
+   h# 20494350 rm-edx!   \ "PCI " in little-endian
+   0 rm-ah!              \ must be 0 to indicate PCI BIOS present
+   1 rm-al!              \ Config method 1
+   h# 201 rm-bx!         \ Version 2.1
+   0 rm-cl!              \ Number of last PCI bus - XXX get this from PCI node
+;
+: pcibios  ( -- )  \ INT 1a
+   noshow
+   rm-clr-cf
+   rm-al@ case
+      h# 01 of  pcibios-installed  endof
+\     h# 02 of  find-pci-device ( cx:devid dx:vendid si:index -> bh:bus# bl:devfn )   endof  
+\     h# 03 of  find-pci-class-code ( ecx:0,classcode si:index -> bh:bus# bl:devfn )  endof
+\     h# 06 of  pci-special-cycle  ( bh:bus# edx:special_cycle_data )  endof
+      h# 08 of  cfgadr config-b@ rm-cl!  endof
+      h# 09 of  cfgadr config-w@ rm-cx!  endof
+      h# 0a of  cfgadr config-l@ rm-ecx!  endof
+      h# 0b of  rm-cl@  cfgadr config-b!  endof
+      h# 0c of  rm-cx@  cfgadr config-w!  endof
+      h# 0d of  rm-ecx@ cfgadr config-l!  endof
+ \    h# 0e of  pci-int-rout  endof
+ \    h# 0f of  set-pci-int   endof
+
+      ( default )     h# 81 rm-ah!     rm-set-cf
+         ." Unimplemented PCI BIOS INT 1a AH b1 - AL = " dup . cr
+   endcase
+;
+
+: get-timer-ticks  ( -- )
+   noshow
+   get-msecs d# 55 /  lwsplit  rm-cx!  rm-dx!
+   0 rm-al!  \ Should be nonzero if midnight happened since last call
+;
+
+: int-1a  ( -- )
+   rm-ah@  case
+      h#  0  of  get-timer-ticks  noshow  endof
+\      h#  4  of  rm-clr-cf  get-rtc-date  endof  \ ch century   cl year  dh month  dl day
+      h# b1  of  pcibios          endof
+      ( default )  ." Unimplemented INT 1a - AH = " dup .  cr  rm-set-cf
+   endcase
+;
+
+: printer-int  ( -- )
+   rm-ah@  1 2 between  if
+      noshow  h# 30 rm-ah!
+   else
+      ." Printer INT AH = " rm-ah@ .  cr
+   then
+;
+
+: (handle-bios-call)  ( -- )
+   snap-int
+
+   rm-int@ irq-vector-base -  dup  0  h# 10 within  if
+      dispatch-interrupt
+      ukey?  if  debug-me  then
+      exit
+   then
+   drop
+
+   rm-int@  case
+      h# 10  of  video-int     endof
+      h# 11  of  sysinfo-int   endof
+      h# 13  of  disk-int      endof
+      h# 16  of  keyboard-int  endof
+      h# 15  of  system-int    endof
+      h# 12  of  'ebda /1k rm-ax!  endof  \ Low memory size
+      h# 1a  of  int-1a        endof
+      h# 18  of  ." Entering Open Firmware" cr  interact    endof
+      h# 19  of  ." Rebooting" cr  bye    endof
+      h# 17  of  printer-int  endof
+      h# 1c  of  noshow  0 dispatch-interrupt    endof  \ Timer bounce vector
+      ( default )  ." Interrupt " dup . cr  interact
+   endcase
+   ?showint
+;
+' (handle-bios-call) to handle-bios-call
+
+h# 7c00 constant mbr-base
+: get-mbr  ( -- )
+\   mbr-base h# 3f 1  disk-read-sectors 1 <> abort" Didn't read MBR"
+   mbr-base 0 1  disk-read-sectors 1 <> abort" Didn't read MBR"
+;
+
+: make-bda  ( -- )
+   h# 400 h# 200 erase
+   'ebda h# 400 erase
+   h# 3f8 h# 400 w!
+   'ebda 4 rshift h# 40e w!
+   h# 26 h# 410 w!   \ Equipment list reported by INT 11
+   d# 640 h# 413 w!  \ Low memory size in KiB
+   3 h# 449 c!       \ Current video mode
+   d# 80 h# 44a w!   \ Characters per text row
+   d# 80 d# 25 * h# 44c w!  \ Characters per screen
+   0 h# 44e w!       \ display page offset
+   \ Some more VGA stuff in 450 .. 466
+   \ 46c.l is tick count, 470.b is midnight flag
+   \ 4701.b bit 0x80 is ctrl-break flag
+   h# 1234 h# 472 w!  \ Skip memory test
+   d# 25 1- h# 484 c! \ Screen max row #
+   d# 16   h# 485 w!  \ Character height
+   h# 100.0000 h# 487 l!  \ Video RAM size
+
+   1 'ebda w!         \ Size of EBDA in KiB
+   \ 'ebda h# 3d +   ..  HD0 parameter table
+   \ 'ebda h# 4d +   ..  HD1 parameter table
+   1 'ebda h# 70 + c!   \ Number of hard disks
+;
+
+label bounce-timer  \ Redirect the timer interrupt through INT 1c
+   16-bit
+   ax   push
+   h# 20 # ax mov
+   al   h# 20 #  out
+   ax   pop
+   cs:  h# 72 #)  push
+   cs:  h# 70 #)  push
+   far ret
+end-code
+here bounce-timer - constant /bounce-timer
+
+: setup-timer-vector  ( -- )
+   \ Put the ISA timer bounce vector at INT 30  (h# c0).  It overlays
+   \ INTs 30-32, which aren't used by anything interesting.
+   bounce-timer h# c0  /bounce-timer  move
+
+   \ Change INT 20 (the timer tick) to point to the bounce vector with CS=0
+   0 h# 82 w!  h# c0 h# 80 w!  \ CS = 0, IP = h# c0 = INT 30
+;
+
+: open-bios-disk  ( -- )
+   disk-ih  if  exit  then
+   disk-name open-dev to disk-ih
+;
+
+0 value rm-prepped?
+: prep-rm  ( -- )
+   rm-prepped?  if  exit  then   true to rm-prepped?
+   setup-smi
+   make-bda
+   setup-acpi
+   setup-smbios
+   setup-rm-gateway
+   setup-timer-vector
+
+   'ebda 4 rshift  h# 40e w!   \ Extended BIOS data area segment address
+
+   " keyboard"   open-dev to kbd-ih
+   populate-memory-map
+;
+: close-bios-disk  ( -- )  disk-ih close-dev   0 to disk-ih  ;
+' 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
+   mbr-base rm-run
+;
+
+: is-mbr?  ( adr len -- flag )
+   h# 200 <>  if  drop false exit  then
+   h# 1fe + w@  h# aa55 = 
+;
+: init-program  ( -- )
+   loaded is-mbr?  if
+      prep-rm
+      load-base mbr-base h# 200 move
+      exit
+   then
+   init-program
+;
+
+\ " rm-go"  ' boot-command  set-config-string-default
+: execute-buffer  ( adr len -- )
+   rm-prepped?  if      ( adr len )
+      2drop             ( )
+      usb-quiet         ( )
+      mbr-base rm-run   ( )
+      exit  \ Precautionary; rm-run shouldn't return
+   then
+   execute-buffer
+;
+
+0 0 " " " /" begin-package
+   " xp" device-name
+   : open
+      " sd:1" open-dev  ?dup  0=  if  false exit  then  ( ih )
+      >r
+      load-base h# 200 " read" r@ $call-method          ( #read )
+      r> close-dev
+      h# 200 <>  if  false exit  then
+      load-base 3 +  " NTFS    "  comp  if  false exit  then
+      true
+   ;
+   : close ;
+   \ Possible change: load at adr, then have init-program do all
+   \ the other fixups (prep-rm) and move the MBR to mbr-base
+   : load  ( adr -- 0 )
+      open-bios-disk
+      0 1  disk-read-sectors h# 200 *
+   ;      
+end-package
+
+label xx  h# 99 # al mov  al h# 80 # out  begin again  end-code
+here xx - constant /xx
+: put-xx  ( adr -- )  xx swap /xx move  ;
+: .lreg  ( adr -- adr' )  4 -  dup l@ 9 u.r   ;
+: .wreg  ( adr -- adr' )  2 -  dup w@ 5 u.r   ;
+: .caller-regs  ( -- )
+   ."        AX       CX       DX       BX       SP       BP       SI       DI" cr
+   caller-regs >rm-eax 4 +  8 0 do  .lreg  loop  cr
+   cr
+   ."    DS   ES   FS   GS       PC  FLAGS" cr
+   4 0 do  .wreg  loop  
+   drop
+   rm-retaddr@ 9 u.r  2 spaces
+   rm-flags@ 5 u.r cr
+;
+
+: egadump  ( -- )
+   d# 25  0  do
+      d# 80 0  do
+         j d# 80 *  i + 2*  h# b8000 + c@  emit
+      loop
+      cr
+   loop
+;
+
+0 [if]
+\   h# 3fd #  dx  mov  begin  dx al in   h# 20 # al test  0<> until
+\   h# 3f8 #  dx  mov  h# 41 #  al mov   al  dx out
+
+stdout off stdin off
+label cifxxx  ( -- )
+   h# 55555555 # ax mov   h# fd00.0000 # edi mov  h# 40000 # cx  mov  rep ax stos
+   begin  again
+end-code
+patch cifxxx cif-handler set-parameters
+\ patch 0 cif-handler set-parameters
+
+\ here foo -  constant /foo    h# ff000 constant cifxxx  : set-foo  foo  cifxxx  /foo move  ;
+\ set-foo  .( CIF )
+\ patch 0 cif-handler set-parameters
+\ patch cifxxx cif-handler (init-program)
+
+stdout off stdin off
+
+h# 100 alloc-mem  gdtr@ 1+  2 pick swap move   h# ff gdtr!
+
+1000 1000 mem-claim cr3!  cr3@ 1000 erase  ff80.0083 cr3@ ff8 + !  cr4@ 10 or cr4!
+
+\ verbose-cif
+load u:\tvmlinuz ro console=tty0 fbcon=font:SUN12x22
+
+
+
+
+stdout off stdin off
+h# 100 h# 10 mem-claim   gdtr@ 1+  2 pick swap move   h# ff gdtr!
+
+h# 40.0000 constant 4m  h# 1000 constant 4k
+: (set-pdes)   do  dup 3 +  cr3@ i d# 22 rshift la+ l!  4k +  4m +loop  drop  ;
+: set-pdes-uc
+   3dup  do  i h# 13 or  over l!  la1+  4k +loop  drop  ( base high low ) (set-pdes)
+;
+: set-pdes  ( pte-base  high low -- )
+   3dup  do  i h# 3 or  over l!  la1+  4k +loop  drop  ( base high low )  (set-pdes)
+;
+: set-pt  ( -- )
+ ( G )  4k  4k  mem-claim cr3!  cr3@ 4k erase
+   h# 40000  4k mem-claim  h# f00.0000  0  set-pdes  \ All of memory
+\   h# 2000  4k mem-claim  h# f00.0000  h# e80.0000  set-pdes  \ OFW RAM area + some DMA
+\ ( G )  4k  4k mem-claim  h# f00.0000  h# ec0.0000  set-pdes  \ OFW RAM area
+   4k0  4k mem-claim  h# 0  h# fc00.0000  set-pdes-uc        \ IO
+\   cr0@ h# 8000.0000 or  cr0!    ( cr4@ h# 10 or  cr4!  )
+;
+set-pt .( PTES )
+verbose-cif
+load u:\tvmlinuz ro console=tty0 fbcon=font:SUN12x22
+100011 3 90 fill  \ Nop-out lea that puts ESP in a bad place for the debugger
+100061 till
+--bp  71638c till
+--bp
+
+\ 716394 till
+\ 400074 till
+6e4000 till
+6 steps
+\ 6e401a till
+cr3@ @ ff invert and 400 + c00 erase
+c040c5af till  \ after return from _mmx_memcpy in zap_low_mappings
+
+c06eef8e till  \ mem_init
+c06eeff7 till
+\ c06e4944 till  \ call trap_init
+\ 714dcb till
+c040c5af till   \ in zap_low_mappings
+
+code switch-seg
+  op: h# 18 # ax mov   ax ds mov  ax es mov  ax fs mov ax gs mov  ax ss mov
+  h# 10 #  push
+  here 6 + #  push
+  far ret
+c;
+
+[then]

Modified: cpu/x86/pc/biosload/addrs.fth
===================================================================
--- cpu/x86/pc/biosload/addrs.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/addrs.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -30,6 +30,19 @@
 \needs dropin-size  h#   8.0000 constant dropin-size
 \needs ResetBase    dropin-base h# 20 +  constant ResetBase	\ Location of "reset" dropin in ROM
 
+[ifdef] syslinux-loaded
+\ This fits nicely with my VIA board that has "only" 256 MiB of memory
+\needs fw-pa      h# 1d80.0000 constant fw-pa     \ OFW dictionary location
+\needs /fw-ram    h#   20.0000 constant /fw-ram
+
+\needs heap-base  h# 1da0.0000 constant heap-base \ Dynamic allocation heap
+\needs heap-size  h#   20.0000 constant heap-size
+
+\needs dma-base   h# 1dc0.0000 constant dma-base  \ DMA heap
+\needs dma-size   h#   20.0000 constant dma-size
+[then]
+
+[ifndef] fw-pa
 \ This is considerably more memory than Open Firmware needs
 \ on platforms where you have a well bounded set of I/O devices.
 
@@ -41,6 +54,7 @@
 
 \needs dma-base   h# 1e0.0000 constant dma-base  \ DMA heap
 \needs dma-size   h#  20.0000 constant dma-size
+[then]
 
 \ Where OFW initially loads an OS that is is going to boot
 

Modified: cpu/x86/pc/biosload/biostart.bth
===================================================================
--- cpu/x86/pc/biosload/biostart.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/biostart.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -42,9 +42,9 @@
 
 start-assembling
 
-real-mode
 
 label my-entry
+16-bit
    e9 c,  0 le-w,  \ Branch instruction; patch later
 end-code
 
@@ -81,7 +81,7 @@
 \ ------->>>>> Startup code.  DOS sends us here.
 
 label dos-rm-start
-real-mode
+   16-bit
    c 3f2  risa-c!	\ Turn off floppy motor
 
 ascii 0 vr-report
@@ -198,16 +198,11 @@
 
       eb c,  0 c,		\ Flush prefetch queue
 
-\ The switch to protected mode does not occur until the far jmp has
-\ executed, but we need to compile the "far jmp" with a 32-bit offset,
-\ (because it uses op:), so we put the "protected-mode" (which is a
-\ misnomer; it should be "use32") here instead of after the "far jmp".
-protected-mode
-
       \ Execute a far jump to following code to reload CS with a
       \ protected mode selector.  The offset portion of the address
       \ (here asm-base - 7 +) has been relocated by the code above.
       op:  here asm-base - 7 +  10 #)  far jmp
+      32-bit
 
       \ The following 2 lines execute at compile time, patching the
       \ address portions of earlier "mov" instructions so that they
@@ -256,6 +251,7 @@
 writing biostart.img
 asm-base /dos-image ofd @ fputs
 ofd @ fclose
+
 \ LICENSE_BEGIN
 \ Copyright (c) 2006 FirmWorks
 \ 

Modified: cpu/x86/pc/biosload/bootsec.fth
===================================================================
--- cpu/x86/pc/biosload/bootsec.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/bootsec.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -60,12 +60,12 @@
 [then]
 
 start-assembling
-real-mode
 
 \ ***************************************************************************
 \ sector 0
 
 label my-entry0
+   16-bit
    e9 c,  0 le-w,  \ Branch instruction; patch later
 end-code
 
@@ -197,7 +197,7 @@
 \ ---------------------------------------------------------------------------
 \ subroutines
 label compute-start  ( -- )
-
+   16-bit
    bp-res asm-base - #) ax mov		\ Compute sector# of FAT
    dx dx xor
    bp-nhidlo asm-base - #) ax add
@@ -231,6 +231,7 @@
 end-code
 
 label hd-tk-sec ( dx:ax: sector# -- )
+   16-bit
    bp-spt asm-base - #) dx cmp
    u>=  if  stc ret  then
    bp-spt asm-base - #)  div
@@ -245,6 +246,7 @@
 end-code
 
 label read-sector  ( es:bx: address -- )
+   16-bit
    201 # ax mov			\ read 1 sector
    track asm-base - #) cx mov
    6 # ch shl
@@ -257,6 +259,7 @@
 end-code
 
 label display-str  ( si: msg -- )
+   16-bit
    begin
       al lodsb
       al al or
@@ -270,6 +273,7 @@
 end-code
 
 label error-exit  ( -- )
+   16-bit
    boot-seg # bx mov
    bx ds mov
    err-msg asm-base - #  si  mov
@@ -284,17 +288,20 @@
 end-code
 
 label use-floppy  ( -- ds: boot-seg )
+   16-bit
    boot-seg # push
    ds pop
 end-code
 
 label floppy-entry  ( -- )
+   16-bit
    e9 c, 0 le-w,		\ Branch to load from floppy; patch later
 end-code
 
 \ ---------------------------------------------------------------------------
 \ entry point
 label start0  ( dl: drive# -- )
+   16-bit
    cli
 
 [ifdef] debug-dos
@@ -388,6 +395,7 @@
 end-code
 
 label my-entry1
+   16-bit
    e9 c, 0 le-w,	\ Branch to next sector; patch later
 end-code
 
@@ -405,6 +413,7 @@
 \ ---------------------------------------------------------------------------
 \ subroutines
 label read-fat  ( ax: fat-sector-offset -- )
+   16-bit
    pusha
    ax s-cfat asm-base - #) mov		\ Save sector offset
    dx dx xor
@@ -433,6 +442,7 @@
 end-code
 
 label ?read-fat  ( ax: fat-sector-offset dx: byte-offset -- bx: byte-offset )
+   16-bit
    dx push
    s-cfat asm-base - #) dx mov
    dx ax cmp
@@ -456,6 +466,7 @@
 
 
 label cluster12>next  ( es: fat-seg ax: cluster# -- flags ax: next-cluster#  )
+   16-bit
    bx push  cx push  dx push
 
    ax push
@@ -493,6 +504,7 @@
 end-code
 
 label cluster16>next  ( es: fat-seg ax: cluster# -- flags ax: next-cluster# )
+   16-bit
    bx push  cx push  dx push
 
    dx dx xor				\ Compute fat sector, offset
@@ -509,6 +521,7 @@
 end-code
 
 label cluster>next  ( ax: cluster# -- flags ax: next-cluster# )
+   16-bit
    es push
    bx push
    fat-seg # bx mov
@@ -532,6 +545,7 @@
 end-code
 
 label cluster>sec  ( ax: cluster# -- dx:ax: sector# )
+   16-bit
    ax dec ax dec
    bx push
    bx bx xor
@@ -546,6 +560,7 @@
 end-code
 
 label find-ofw ( es: -- bx: directory address )
+   16-bit
    20 # ax mov				\ Compute # of sectors in root directory
    bp-ndirs asm-base - #) mul
    bp-bps asm-base - #) bx mov
@@ -594,6 +609,7 @@
 \ ---------------------------------------------------------------------------
 \ entry point (continue from start0)  C: only code
 label start1
+   16-bit
 
 \ ascii t reportc
 
@@ -639,6 +655,7 @@
 end-code
 
 label floppy-start  ( ds: boot-seg for floppy or hd-seg for c: )
+   16-bit
 
 \ ascii v reportc
 

Modified: cpu/x86/pc/biosload/callbios.fth
===================================================================
--- cpu/x86/pc/biosload/callbios.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/callbios.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -44,7 +44,7 @@
 bios-retloc la1+  constant bios-rflags  \ Flags in case of return via IRET
 
 label bios-call
-   real-mode
+   16-bit
    \ This must be copied to low memory
 
    rm-data-desc #  ax  mov  \ 16-bit data segment
@@ -71,6 +71,8 @@
 here bios-call - constant /bios-call
 
 label bios-ret
+   16-bit
+
    bios-target #  sp  mov   \ Set the stack pointer to the top of the rm reg area
 
    \ Copy the real-mode registers to the buffer
@@ -84,7 +86,7 @@
 
    here 5 +  bios-ret -  'bios-ret +  pm-code-desc #)  far jmp
 
-   protected-mode
+   32-bit
 
    pm-data-desc # ax mov  ax ds mov  ax es mov  ax gs mov  ax gs mov  ax ss mov
    pm-idt-save #) lidt
@@ -107,11 +109,6 @@
    'bios-call  rm-code-desc #) far jmp
 c;
 
-: >seg:off  ( linear -- offset segment )  lwsplit  d# 12 lshift  ;
-: seg:off!  ( linear adr -- )  >r  >seg:off  r@ 2+ w!  r> w!  ;
-: seg:off>  ( offset segment -- linear )  4 lshift +  ;
-: seg:off@  ( adr -- linear )  dup w@ swap wa1+ w@  seg:off>  ;
-
 0 value bios-prepped?
 : ?prep-bios-call  ( -- )
    bios-prepped?  if  exit  then   true to bios-prepped?

Added: cpu/x86/pc/biosload/callvbe.fth
===================================================================
--- cpu/x86/pc/biosload/callvbe.fth	                        (rev 0)
+++ cpu/x86/pc/biosload/callvbe.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,24 @@
+\ Call VESA BIOS from a syslinux-loaded ".c32" image
+\ COM32 arguments are at 0 @ 4 +
+
+code vesa-mode  ( mode# -- )
+   cx pop
+
+   si push  di push  bp push
+   0 #)  ax mov  \ Pointer to COM32 args
+   d# 16 [ax]  bx  mov  \ COM32 intcall helper function
+   d# 20 [ax]  dx  mov  \ bounce buffer address
+
+   4f02 #  d# 36 [dx]  mov  \ AX
+   cx      d# 24 [dx]  mov  \ BX
+
+   \ dx push
+   0 # push
+   dx push
+   h# 10 # push
+
+   bx call
+   ax pop  ax pop  ax pop
+
+   bp pop  di pop  si pop
+c;

Added: cpu/x86/pc/biosload/config-i945.fth
===================================================================
--- cpu/x86/pc/biosload/config-i945.fth	                        (rev 0)
+++ cpu/x86/pc/biosload/config-i945.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,114 @@
+\ See license at end of file
+purpose: Establish configuration definitions - version for i945 chipset
+
+\ create pc		\ Demo version for generic PC
+\ create pc-linux	\ Demo version for generic PC and Linux
+\ create pc-serial	\ Demo version for generic PC
+
+\ --- The environment that "boots" OFW ---
+\ - Image Format - Example Media - previous stage bootloader
+
+\ - (Syslinux) COM32 format - USB Key w/ FAT FS - Syslinux
+\ create syslinux-loaded
+
+\ - Linux kernel format - USB Key w/ FAT FS - LinuxBIOS w/ stripped Linux payload
+\ create bzimage-loaded
+
+\ - ELF format w/ Multiboot signature - various - GRUB
+\ create grub-loaded
+\ create etherboot-variant  \ Enable additional tweaks for Etherboot
+
+\ - ELF format (no pheader) - ROM - LinuxBIOS direct
+\ create linuxbios-loaded
+
+\ Load and run in qemu
+\ create qemu-loaded 
+
+\ Load from ROM by preOF code from Intel
+create preof-loaded 
+
+[ifdef] pc-serial
+create serial-console
+create pc
+[then]
+
+[ifdef] qemu-loaded  \ LinuxBIOS+OFW under QEMU currently doesn't do VGA right
+create serial-console
+[then]
+
+[ifdef] etherboot-variant
+create debug-startup
+create serial-console
+[then]
+
+[ifdef] pc-linux
+\ In virtual mode, OFW runs with the MMU on.  The advantages are
+\ that OFW can automatically locate itself out of the way, at the
+\ top of physical memory, it can dynamically allocate exactly as
+\ much physical memory as it needs, and it can remain alive after
+\ the OS starts.  The disadvantage is that it is more confusing -
+\ you always have to be aware of the distinction between virtual
+\ and physical addresses.
+
+\ Here we use virtual mode for Linux, so that we can debug past
+\ the point where Linux starts using the MMU.  It isn't strictly
+\ necessary to use virtual mode if you just want to boot Linux
+\ and then have OFW disappear.
+create virtual-mode
+create pc
+create linux-support
+[then]
+
+[ifdef] pc
+\ create pseudo-nvram
+create resident-packages
+create addresses-assigned  \ Don't reassign PCI addresses
+\ create virtual-mode
+create use-root-isa
+create use-isa-ide
+create use-ega
+create use-elf
+create use-ne2000
+create use-watch-all
+create use-null-nvram
+create no-floppy-node
+[then]
+
+[ifdef] preof-loaded
+create serial-console
+create use-timestamp-counter
+create resident-packages
+create addresses-assigned  \ Don't reassign PCI addresses
+\ create virtual-mode
+create use-root-isa
+create use-isa-ide
+create use-elf
+create use-watch-all
+create use-null-nvram
+create no-floppy-node
+[then]
+
+fload ${BP}/cpu/x86/pc/biosload/addrs.fth
+\ LICENSE_BEGIN
+\ Copyright (c) 2006 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Added: cpu/x86/pc/biosload/config-usbkey.fth
===================================================================
--- cpu/x86/pc/biosload/config-usbkey.fth	                        (rev 0)
+++ cpu/x86/pc/biosload/config-usbkey.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,114 @@
+\ See license at end of file
+purpose: Configuration for loading from a USB key via Syslinux
+
+\ create pc		\ Demo version for generic PC
+\ create pc-linux	\ Demo version for generic PC and Linux
+create pc-serial	\ Demo version for generic PC
+
+\ --- The environment that "boots" OFW ---
+\ - Image Format - Example Media - previous stage bootloader
+
+\ - (Syslinux) COM32 format - USB Key w/ FAT FS - Syslinux
+create syslinux-loaded
+
+\ - Linux kernel format - USB Key w/ FAT FS - LinuxBIOS w/ stripped Linux payload
+\ create bzimage-loaded
+
+\ - ELF format w/ Multiboot signature - various - GRUB
+\ create grub-loaded
+\ create etherboot-variant  \ Enable additional tweaks for Etherboot
+
+\ - ELF format (no pheader) - ROM - LinuxBIOS direct
+\ create linuxbios-loaded
+
+\ Load and run in qemu
+\ create qemu-loaded 
+
+\ Load from ROM by preOF code from Intel
+\ create preof-loaded 
+
+[ifdef] pc-serial
+create serial-console
+create pc
+[then]
+
+[ifdef] qemu-loaded  \ LinuxBIOS+OFW under QEMU currently doesn't do VGA right
+create serial-console
+[then]
+
+[ifdef] etherboot-variant
+create debug-startup
+create serial-console
+[then]
+
+[ifdef] pc-linux
+\ In virtual mode, OFW runs with the MMU on.  The advantages are
+\ that OFW can automatically locate itself out of the way, at the
+\ top of physical memory, it can dynamically allocate exactly as
+\ much physical memory as it needs, and it can remain alive after
+\ the OS starts.  The disadvantage is that it is more confusing -
+\ you always have to be aware of the distinction between virtual
+\ and physical addresses.
+
+\ Here we use virtual mode for Linux, so that we can debug past
+\ the point where Linux starts using the MMU.  It isn't strictly
+\ necessary to use virtual mode if you just want to boot Linux
+\ and then have OFW disappear.
+create virtual-mode
+create pc
+create linux-support
+[then]
+
+[ifdef] pc
+\ create pseudo-nvram
+create resident-packages
+create addresses-assigned  \ Don't reassign PCI addresses
+\ create virtual-mode
+create use-root-isa
+create use-isa-ide
+create use-ega
+create use-elf
+create use-ne2000
+create use-watch-all
+create use-null-nvram
+create no-floppy-node
+[then]
+
+[ifdef] preof-loaded
+create serial-console
+create use-timestamp-counter
+create resident-packages
+create addresses-assigned  \ Don't reassign PCI addresses
+\ create virtual-mode
+create use-root-isa
+create use-isa-ide
+create use-elf
+create use-watch-all
+create use-null-nvram
+create no-floppy-node
+[then]
+
+fload ${BP}/cpu/x86/pc/biosload/addrs.fth
+\ LICENSE_BEGIN
+\ Copyright (c) 2006 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Modified: cpu/x86/pc/biosload/fw.bth
===================================================================
--- cpu/x86/pc/biosload/fw.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/fw.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -20,8 +20,6 @@
 : \Tags [compile] \  ; immediate
 : \NotTags [compile] \  ; immediate
 
-fload ${BP}/cpu/x86/pc/segments.fth     \ Segment selectors (address spaces)
-
 : RAMbase  ( -- adr )  fw-virt-base  ;
 : RAMtop  ( -- adr )  RAMbase /fw-ram +  ;
 
@@ -206,6 +204,7 @@
 ;
 
 fload ${BP}/cpu/x86/pc/biosload/usb.fth
+fload ${BP}/cpu/x86/pc/rmtools.fth
 fload ${BP}/cpu/x86/pc/biosload/callbios.fth
 fload ${BP}/cpu/x86/pc/biosload/rmenter.fth
 

Modified: cpu/x86/pc/biosload/reset.bth
===================================================================
--- cpu/x86/pc/biosload/reset.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/reset.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -22,7 +22,6 @@
 h#  30.0000 constant workspace
 
 start-assembling
-protected-mode
 
 label my-entry
    e9 c,  0 ,				\ To be patched later

Modified: cpu/x86/pc/biosload/rmenter.fth
===================================================================
--- cpu/x86/pc/biosload/rmenter.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/rmenter.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -1,17 +1,24 @@
-[ifndef] >seg:off
-: >seg:off  ( linear -- offset segment )  lwsplit  d# 12 lshift  ;
-: 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>  ;
-[then]
-: >off  ( linear -- 16-bit offset )  >seg:off drop  ;
+\ Exports:
+\  setup-rm-gateway  ( -- ) Init this module
+\  caller-regs  ( -- adr )  Base address of incoming registers
+\  rm-int@      ( -- n )    Incoming interrupt number
+\  rm-buf       ( -- adr )  Base address of a real-mode accessible buffer
+\  rm-init-program  ( eip -- )  Setup to enter real mode program on next rm-return
+\  rm-return    ( -- )      Resume execution of real-mode caller.  Returns when program does a BIOS INT.
+\ Sequence:
+\  setup-rm-gateway  ( eip ) rm-enter  begin  handle-bios-call rm-return  again
+\ An alternate way would be:
+\  setup-rm-gateway  ['] handle-bios-call ( eip ) rm-enter
+\ Then a BIOS INT would invoke handle-bios-call, which would return by calling rm-return
 
-h# 9.0000 constant rm-base
-h# 9.0000 constant rm-avail
+\ h# 9.0000 constant rm-base
+h# f.0000 constant rm-base
 h#   ff00 constant rm-base2
-h# 9.fc00 constant 'ebda  \ Extended BIOS Data Area, which we co-opt for our real-mode workspace
-'ebda constant new-gdt-pa
 
+\ 'ebda constant new-gdt-pa
+h# e.8000 constant new-gdt-pa
+
+
 [ifdef] syslinux-loaded
 h#  8 constant rm-cs
 h# 18 constant rm-ds
@@ -47,13 +54,37 @@
 ;
 [then]
 
+[ifdef] rom-loaded
+h# 38 constant rm-cs
+h# 30 constant rm-ds
+h# 60 constant pm-cs
+h# 68 constant pm-ds
+: fix-gdt 
+   \ 16-bit 64K code segment starting at rm-base
+   rm-base lbsplit                   ( adr.0 adr.1 adr.2 adr.3 )
+   2swap h# ffff -rot bwjoin wljoin  ( adr.2 adr.3 desc.lo )
+   -rot                              ( desc.lo adr.2 adr.3 )
+   >r  h# 9a 0  r>   bljoin          ( desc.lo desc.hi )
+   gdtr@ drop rm-cs + d!             ( )
 
+   \ 16-bit 64K data segment starting at rm-base
+   rm-base lbsplit                   ( adr.0 adr.1 adr.2 adr.3 )
+   2swap h# ffff -rot bwjoin wljoin  ( adr.2 adr.3 desc.lo )
+   -rot                              ( desc.lo adr.2 adr.3 )
+   >r  h# 93 0  r>   bljoin          ( desc.lo desc.hi )
+   gdtr@ drop rm-ds + d!             ( )
+;
+[then]
+
 : +rm  ( offset -- adr )  rm-base +  rm-base2 +  ;
 
 \ Place for the initial registers upon entry to real mode.
 \ The real-mode stack pointer will start here, so the registers
 \ can be loaded by popping the stack
+
 h# 00 +rm constant 'rm-regs
+'rm-regs value rm-buf
+
 \ (00) 4 * 2: GS,FS,ES,DS
 \ (08) 8 * 4: EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX
 \ (28) 1 * 4: CS:IP of return address
@@ -72,70 +103,9 @@
 h# f0 +rm constant 'rm-enter
 
 : caller-regs  'rm-sp seg:off@  ;
-struct
-  2 field >rm-gs
-  2 field >rm-fs
-  2 field >rm-es
-  2 field >rm-ds
-  4 field >rm-edi
-  4 field >rm-esi
-  4 field >rm-ebp
-  4 field >rm-exx
-  4 field >rm-ebx
-  4 field >rm-edx
-  4 field >rm-ecx
-  4 field >rm-eax
-  4 field >rm-retaddr
-  2 field >rm-flags
-drop
 
-: rm-ah@  caller-regs >rm-eax 1+ c@  ;
-: rm-ah!  caller-regs >rm-eax 1+ c!  ;
-: rm-al@  caller-regs >rm-eax c@  ;
-: rm-al!  caller-regs >rm-eax c!  ;
-: rm-ax@  caller-regs >rm-eax w@  ;
-: rm-ax!  caller-regs >rm-eax w!  ;
-
-: rm-bh@  caller-regs >rm-ebx 1+ c@  ;
-: rm-bh!  caller-regs >rm-ebx 1+ c!  ;
-: rm-bl@  caller-regs >rm-ebx c@  ;
-: rm-bl!  caller-regs >rm-ebx c!  ;
-: rm-bx@  caller-regs >rm-ebx w@  ;
-: rm-bx!  caller-regs >rm-ebx w!  ;
-
-: rm-ch@  caller-regs >rm-ecx 1+ c@  ;
-: rm-ch!  caller-regs >rm-ecx 1+ c!  ;
-: rm-cl@  caller-regs >rm-ecx c@  ;
-: rm-cl!  caller-regs >rm-ecx c!  ;
-: rm-cx@  caller-regs >rm-ecx w@  ;
-: rm-cx!  caller-regs >rm-ecx w!  ;
-
-: rm-dh@  caller-regs >rm-edx 1+ c@  ;
-: rm-dh!  caller-regs >rm-edx 1+ c!  ;
-: rm-dl@  caller-regs >rm-edx c@  ;
-: rm-dl!  caller-regs >rm-edx c!  ;
-: rm-dx@  caller-regs >rm-edx w@  ;
-: rm-dx!  caller-regs >rm-edx w!  ;
-
-: rm-flags@  caller-regs >rm-flags w@  ;
-: rm-flags!  caller-regs >rm-flags w!  ;
-
-: rm-set-cf  rm-flags@  1 or  rm-flags!  ;
-: rm-clr-cf  rm-flags@  1 invert and  rm-flags!  ;
-
 : rm-int@  'rm-int w@  h# ff and  ;
 
-true value show-rm-int?
-: noshow  false to show-rm-int?  ;
-variable save-eax
-: snap-int
-   true to show-rm-int?  caller-regs >rm-eax @ save-eax !
-;
-: showint
-  ." INT " rm-int@ .  save-eax @ wbsplit ." AH " .  ." AL " .  cr
-;
-: ?showint  show-rm-int?  if  showint  then  ;
-
 h# 80 constant /vectors
 
 /vectors buffer: saved-rm-vectors
@@ -166,18 +136,8 @@
    h# 100 0 do  i grab-rm-vector  loop
 ;
 
-label timer-off
-   real-mode
-   ax push
-   h# 21 # al in
-   1 # al or
-   al h# 21 # out
-   ax pop
-   iret
-end-code
-
 label rm-to-pm
-   real-mode
+   16-bit
 
    \ Stack: (high address)
    \ flags                 (from INT)
@@ -197,16 +157,13 @@
    op: 'pm-gdt  >off  #) lgdt
    cr0 ax mov  1 # al or  ax cr0 mov   \ Enter protected mode
 
-   \ The assembler gyrations here are subtle.  We need to jump to an address
-   \ that may be larger than 16 bits, but we are currently running from a
-   \ 16-bit code segment.  So we have to tell the assembler to go into
-   \ "protected mode" (a misnomer; that assembler directive really means
-   \ to assemble for the 32-bit instruction set) so it will put down a
-   \ ptr16:32 operand.  But we also need the op: prefix, so the processor
-   \ will interpret the operand as a ptr16:32 instead of a ptr16:16
+   \ We are still running in 16-bit mode, but the target address might
+   \ not fit in 16 bits, so we need the operand override to force the
+   \ ptr16:32 target form.
 
-   protected-mode
+\   ad:  here 7 +  rm-to-pm -  'rm-to-pm +  pm-cs #)  far jmp
    op:  here 7 +  rm-to-pm -  'rm-to-pm +  pm-cs #)  far jmp
+   32-bit
 
    ax ax xor  pm-ds # al mov  ax ds mov  ax es mov  ax gs mov  ax gs mov  ax ss mov
    'rm-idt #) sidt
@@ -222,8 +179,7 @@
    \ Interrupts must be off.  We don't have a stack at the moment.
    \ We got here via a far jmp to a 16-bit code segment, so we are
    \ using the 16-bit instruction set, but we're not yet in real mode
-   \ The assembler uses "real-mode" to mean "16-bit code".
-   real-mode
+   16-bit
 
    \ This must be copied to low memory
 
@@ -250,7 +206,7 @@
 here pm-to-rm - constant /pm-to-rm
 
 code rm-return  ( -- )
-   protected-mode
+   32-bit
    pushf
    pusha
    sp 'pm-sp #) mov
@@ -260,16 +216,23 @@
    'pm-to-rm >off  rm-cs #) far jmp
 end-code
 
+: rm-init-program  ( pc -- )
+   'rm-regs  h# 2e  erase        ( pc )
+   'rm-regs  h# 28 +  seg:off!   ( )
+   'rm-regs 'rm-sp seg:off!      \ Initial stack pointer must be below regs
+;
+
+
+
 \ This is the common target of all the real-mode interrupt vectors.
-\ It lives at 8.0ff0.  Upon entry, the code segment register contains
+\ It lives at 9.fff0.  Upon entry, the code segment register contains
 \ 80xx where xx is the vector number, and the IP contains 0yy0 where
 \ yy is ff - vector_number.
 label rm-enter
-   real-mode
+   16-bit
    op: pusha  ds push  es push  fs push  gs push
    cs push                        \ Save the Code Segment value
    'rm-to-pm >seg:off #) far jmp  \ Normalize the CS value
-   protected-mode
 end-code
 here rm-enter - constant /rm-enter
 
@@ -277,7 +240,6 @@
    saved-rm-vectors  over la+ l@   swap /l* l!
 ;
 
-0 value rm-prepped?
 : move-gdt  ( -- )
    gdtr@ 1+                    ( gdt-adr gdt-len )
 
@@ -286,7 +248,6 @@
    swap  2dup 2>r  move   2r>  ( new-gdt gdt-len )
    1- gdtr!
 ;
-0 value kbd-ih
 
 : bios-vectors  ( -- )
    0  saved-ofw-vectors  /vectors  move
@@ -296,6 +257,7 @@
 \   0  saved-ofw-vectors  /vectors  move
    saved-ofw-vectors  0 /vectors move
 ;
+[ifndef] rom-loaded
 : regs>bios  ( -- )
    caller-regs bios-regs d# 40 move
    rm-flags@ bios-flags l!
@@ -313,9 +275,8 @@
    bios>regs
    ofw-vectors
 ;
-
-: prep-rm  ( -- )
-   rm-prepped?  if  exit  then   true to rm-prepped?
+[then]
+: setup-rm-gateway  ( -- )
    fix-gdt
 
    move-gdt
@@ -339,502 +300,20 @@
 [else]
    make-vector-table
 
+[ifndef] rom-loaded
    saved-rm-vectors     8 la+ l@  0     8 la+ l!  \ Use BIOS timer tick handler
    saved-rm-vectors h# 1c la+ l@  0 h# 1c la+ l!  \ Timer handler chain
 [then]
+[then]
 
-\   \ Set up a rudimentary handler for the ISA timer
-\   timer-off 'rm-timer-off  /rm-timer-off move
-\   'rm-timer-off  0 8 la+ seg:off!
-
    h# ffff 'rm-idt w!  0 'rm-idt wa1+ l!  \ Limit and base
-
-   " keyboard" open-dev to kbd-ih
 ;
 
-: rm-init-program  ( pc -- )
-   prep-rm
-   'rm-regs  h# 2e  erase        ( pc )
-   'rm-regs  h# 28 +  seg:off!   ( )
-   'rm-regs 'rm-sp seg:off!      \ Initial stack pointer must be below regs
-;
-
-: !font  ( adr -- )
-   >seg:off  caller-regs >rm-es w!  caller-regs >rm-ebp l!
-   h# 10 rm-cx!  h# 18 rm-dx!     
-;
-: get-font  ( -- )
-   noshow
-   rm-al@ h# 30 =  if
-\      ." Int 10 get-font called - BH = " rm-bh@ .  cr
-      rm-bh@ case
-\ These numbers are cheats, pointing into the VIA BIOS
-         2 of  h# c69e0 !font   endof
-         3 of  h# c6138 !font   endof
-         4 of  h# c6538 !font   endof
-         5 of  h# c69e0 !font   endof
-         6 of  h# c77e0 !font   endof
-         7 of  h# c77e0 !font   
-h# 10 ungrab-rm-vector
-h# 15 ungrab-rm-vector
-endof
-         ( default )  ." Unsupported get font - BH = " dup . cr  rm-set-cf
-      endcase
-   else
-      ." Int 10 set-font called"  cr
-   then
-;
-
-: set-cursor  ( -- )  rm-dh@  rm-dl@  ( row column ) 2drop  ;
-
-: video-int  ( -- )  \ INT 10
-   rm-ah@  case
-      h#  0  of  ( rm-al@ set-video-mode )  endof  \ Set mode - Should blank the screen
-      h#  2  of  set-cursor    endof
-      h#  a  of  rm-al@ emit   endof   \ Write character
-      h#  e  of  rm-al@ emit   endof   \ Write character
-      h# 11  of  get-font      endof   \ get or set font
-      h# 12  of  0 rm-bx!      endof   \ Attribute for blanked lines while scrolling - Wrong, I think
-      h# 20  of  endof
-
-      ( default )  ." Unimplemented video int - AH = " dup . cr  rm-set-cf
-   endcase
-;
-: bios-video-int  debug-me use-bios  ;
-
-: sysinfo-int  ( -- )  \ INT 11
-   \ h# 4226 caller-regs >rm-eax !   \ to report 1 parallel and 1 serial port
-   h# 26 caller-regs >rm-eax !   \ 32 bits
-;
-
-0 value disk-ih
-: disk-read-sectors  ( adr sector# #sectors -- #read )
-noshow
-\ ." Read " 2 pick . over . dup .  ." -- "
-\ over h# 8b74aaa =  if  debug-me  then
-   " read-blocks" disk-ih $call-method
-\ dup .  cr
-;
-
-: disk-write-sectors  ( adr sector# #sectors -- #read )
-\ ." Write " 2 pick . over . dup .  ." -- "
-\ over h# 8b74aaa =  if  debug-me  then
-   " write-blocks" disk-ih $call-method
-\ dup .  cr
-;
-
-0 [if]
-h# 200 constant /sector
-: disk-seek  ( sector#  -- error? )
-   /sector um*                               ( adr len d.byte# )
-   " seek"  disk-ih  $call-method  dup  if   ( error? )
-      rm-set-cf  4 rm-ah!                    ( error? )
-   then                                      ( error? )
-;
-: disk-read  ( adr #sectors -- #sectors-read )
-   /sector *                       ( adr #bytes )
-   " read" disk-ih $call-method    ( #bytes-read )
-   /sector /                       ( #sectors-read )
-;
-[then]
-
-: check-drive  ( -- error? )
-   rm-dl@  h# 80 <>  if  rm-set-cf  7 rm-ah!  true exit  then
-   disk-ih  if  false exit  then
-\   " disk:0" open-dev to disk-ih
-   " /pci/ide at 0" open-dev to disk-ih
-   disk-ih  dup 0=  if  rm-set-cf  h# aa rm-ah!   then   
-   false
-;
-: read-sectors  ( -- )
-   check-drive  if  exit  then
-   disk-ih  0=  if  rm-set-cf  h# aa rm-ah! exit  then
-   rm-ch@  rm-cl@ 6 rshift  bwjoin  ( cylinder# )
-   h# ff *   rm-dh@ +               ( trk# )     \ 255 heads
-   h# 3f *  rm-cl@ h# 3f and 1-  +  ( sector# )  \ 63 is max sector#
-
-   rm-bx@  caller-regs >rm-es w@  seg:off>  ( sector# adr )
-   swap  rm-al@                             ( adr sector# #sectors )
-   disk-read-sectors  rm-al!
-
-\   disk-seek  if  exit  then
-\   rm-bx@  caller-regs >rm-es w@  seg:off>  rm-al@  ( adr #sectors )
-\   disk-read  rm-al!
-;
-: drive-sectors  ( -- n )  " #blocks" disk-ih $call-method  ;
-: drive-params  ( -- )
-   check-drive  if  exit  then
-\   " size" disk-ih $call-method       ( d.#bytes )
-\   /sector um/mod  nip                ( #sectors )
-   drive-sectors                      ( #sectors )
-   h# 3f /                            ( #tracks )
-   h# ff / 1-                         ( maxcyl )  \ Max 255 heads is traditional
-\ dup ." MAXCYL " .  cr
-   wbsplit                            ( maxcyl.lo maxcyl.hi )
-   3 min  6 lshift  h# 3f or  rm-cl!  ( maxcyl.lo )  \ High cyl, max sector
-   rm-ch!                             ( ) \ Low byte of max cylinder
-   h# fe rm-dh!                       ( ) \ Max head number
-   h# 01 rm-dl!                       ( ) \ Number of drives
-   rm-clr-cf
-;
-
-: ds:si  ( -- adr )
-   caller-regs >rm-esi w@  caller-regs >rm-ds w@  seg:off>
-;
-: lba-read  ( -- )
-   check-drive  if  exit  then
-   ds:si  ( packet-adr )
-   >r  r@ 4 + seg:off@  r@ 8 + l@   r@ 2+ w@     ( adr sector# #sectors )
-\ ." LBA "
-   disk-read-sectors  r> 2+ w!
-\   dup 8 + l@   ( packet-adr sector# )
-\   disk-seek  if  drop exit  then  ( packet-adr )
-\   dup 4 + seg:off@  over 2+ w@    ( packet-adr adr #sectors )
-\   disk-read
-\   swap 2+ w!   
-;
-: lba-write  ( -- )
-   check-drive  if  exit  then
-   ds:si  ( packet-adr )
-   >r  r@ 4 + seg:off@  r@ 8 + l@   r@ 2+ w@     ( adr sector# #sectors )
-\ ." LBA "
-   disk-write-sectors  r> 2+ w!
-\   dup 8 + l@   ( packet-adr sector# )
-\   disk-seek  if  drop exit  then  ( packet-adr )
-\   dup 4 + seg:off@  over 2+ w@    ( packet-adr adr #sectors )
-\   disk-read
-\   swap 2+ w!   
-;
-
-: check-disk-extensions  ( -- )
-   check-drive  if  0 rm-bx! exit  then
-   rm-bx@  h# 55aa <>  if  exit  then
-   h# aa55 rm-bx!
-   h# 20 rm-ah!  1 rm-cx!
-;
-: ext-get-drive-params  ( -- )
-   check-drive  if  exit  then
-   0 rm-ah!
-   ds:si  >r    ( adr )
-   r@ 2 +  h# 0e  erase   \ CHS info not valid
-   drive-sectors r@ h# 10 + l!  0 r@ h# 14 + l!  \ Total #sectors
-   h# 200 r@ h# 18 + w!   \ Sector len
-   h# 1a                  ( written-length )
-   r@ w@  h# 1e >=  if
-      -1  r@ h# 1a + l!      \ No EDD
-      4 +                 ( written-length' )
-   then                   ( written-length )
-   r@ w@  h# 20 >=  if    ( written-length )
-      0 r@ h# 1e + w!        \ Ensure that device path info not interpreted
-      \ Don't claim these bytes
-   then                   ( written-length )
-   r> w!                  \ Number of bytes written
-   rm-clr-cf
-;
-
-: get-disk-type  ( -- )
-   check-drive  if  exit  then
-   3 rm-ah!
-   drive-sectors lwsplit rm-cx!  rm-dx!
-   rm-clr-cf
-;
-
-: disk-int  ( -- )  \ INT 13 handler
-   rm-ah@ case
-      h# 02  of  noshow read-sectors    endof
-      h# 08  of  drive-params           endof
-      h# 15  of  get-disk-type          endof
-      h# 41  of  check-disk-extensions  endof
-      h# 42  of  lba-read   endof
-      h# 43  of  lba-write  endof
-      h# 48  of  ext-get-drive-params  endof
-      ( default )  ." Unsupported disk INT 13 - AH = " dup . cr
-   endcase
-;
-
-: memory-limit  ( -- limit )
-   " /memory" find-package 0= abort" No /memory node"  ( phandle )
-   " available" rot get-package-property abort" No available property"  ( $ )
-   -1 >r                              ( $ )  ( r: limit )
-   begin  dup 0>  while               ( $ )
-      decode-int >r decode-int  r> +  ( $ piece-end )
-      dup 1meg u<=  if  drop   else   ( $ piece-end )
-         r> umin >r                   ( $ )  ( r: limit' )
-      then                            ( $ )
-   repeat                             ( $ )
-   2drop  r>                          ( limit )
-;
-
-: /1k  d# 10 rshift  ;
-: bigmem-16bit  ( -- )
-   memory-limit
-   dup h# 100.0000  min  h# 10.0000 -  0 max  /1k  dup rm-ax!  rm-cx!
-   h# 100.0000 -  0 max  d# 16 rshift  dup rm-bx!  rm-dx!
-;
-: allmem  ( -- n )
-   " /memory" find-package 0= abort" No /memory node"  ( phandle )
-   " reg" rot get-package-property abort" No available property"  ( $ )
-   decode-int drop  get-encoded-int  h# 10.0000 round-up
-;
-
-0 [if]
-Entry:
-  EBX Continuation value
-  ES:DI Address of Address Range Descriptor
-  ECX Length of Address Range Descriptor  (=> 20 bytes)
-  EDX "SMAP" signature
-Exit:
-  Carry 0 = E820 Supported
-  EAX "SMAP" signature
-  ES:DI Same value as entry
-  ECX Length of actual reported information in bytes
-  EBX Continuation value
-  Structure of Address Range Descriptor:
-  Bytes 0-3 Low 32 bits of Base Address
-  Bytes 4-7 High 32 bits of Base Address
-  Bytes 8-11 Low 32 bits of Length in bytes
-  Bytes 12-15 High 32 bits of Length in bytes
-  Bytes 16-20 Type of Address Range:
-    1 = AddressRangeMemory, available to OS
-    2 = AddressRangeReserved, not available
-    3 = AddressRangeACPI, available to OS
-    4 = AddressRangeNVS, not available to OS
-    Other = Not defined, not available
-
-d.base d.len l.type
-[then]
-
-create memdescs
-   h#         0. d, rm-avail 0  d,  1 l,  \ 0
-\  h# rm-avail 0 d,   h# 60000. d,  2 l,  \ 14
-   h#     f0000. d,   h# 10000. d,  2 l,  \ 14
-   h#    100000. d,          0. d,  1 l,  \ 28
-\             0. d,          0. d,  2 l,  \ 3c
-   h# ffff0000.  d,   h# 10000. d,  2 l,  \ 40
-here memdescs - constant /memdescs
-
-: system-memory-map  ( -- )
-   caller-regs >rm-edx @  caller-regs >rm-eax !
-   caller-regs >rm-ebx @  ?dup 0=  if
-      memory-limit  h# 100000 -  memdescs h# 30 + l!
-\      memory-limit  memdescs h# 3c +  l!
-\      allmem memory-limit -  memdescs h# 44 + l!
-      memdescs
-   then   ( adr )
-
-   dup  memdescs /memdescs +  =  if
-      drop
-      0 caller-regs >rm-ecx !
-      exit
-   then
- 
-   dup  caller-regs >rm-edi w@  caller-regs >rm-es w@  seg:off>  ( adr dst )
-   caller-regs >rm-ecx @  move                     ( adr )
-   caller-regs >rm-ecx @ +  caller-regs >rm-ebx !  ( )  \ Continuation
-   rm-clr-cf
-;
-
-: bigmem-int  ( -- )
-   rm-clr-cf
-   rm-al@ case
-      h# 01 of  bigmem-16bit   endof
-      h# 20 of  system-memory-map  endof
-\     h# 81 of  pm-system-memory-map  endof
-      ( default )  rm-set-cf
-         ." Unsupported Bigmem int 15 AH=e8 AL=" dup . cr
-   endcase
-;
-
-: apm  ( -- )
-   ." APM not supported yet" cr
-   rm-set-cf  h# 86 rm-ah!
-;
-
-\ System configure
-create sysconf
-  8 w,       \ 8 bytes following
-  h# fc c,   \ model
-  1 c,       \ Submodel
-  0 c,       \ BIOS rev
-  h# 74 c,   \ Feature - second 8259, RTC, INT 9 calls INT 15/4F, extended BIOS area
-  0 c,
-  0 c,
-  0 c,
-  0 c,
-
-: get-conf  ( -- )
-   sysconf 'rm-regs 8 move
-   'rm-regs >seg:off  0 caller-regs >rm-es w!  rm-bx!  
-   0 rm-ax!
-;
-
-: handle-mouse  ( -- )
-   rm-al@ case
-      1 of  rm-clr-cf  endof   \ Reset mouse
-      ( default )  ." Unsupported mouse INT 15 AH c2 AL " dup . cr   rm-set-cf
-   endcase
-;
-
-: system-int  ( -- )  \ INT 15 handler
-   rm-clr-cf
-   rm-ah@ case
-      h# 91 of  noshow 0 rm-ah!  endof   \ "pause" while waiting for I/O
-noop
-      h# 53 of  apm  endof
-      h# 86 of  rm-dx@  rm-cx@ wljoin us  endof  \ Delay microseconds
-      h# 8a of  memory-limit h# 400.0000 - 0 max  /1k  lwsplit rm-dx! rm-ax!  endof
-      h# 88 of  h# fffc rm-ax!  endof  \ Extended memory - at least 64 MB
-      h# c0 of  get-conf  endof
-      \ We use the extended BIOS data area as our workspace when loaded from another BIOS
-\      h# c1 of  rm-set-cf h# 86 rm-ah!  endof  \ No extended BIOS data area
-      h# c1 of  'ebda 4 rshift caller-regs >rm-es w!  endof  \ Segment address of extended BIOS data area
-      h# c2 of  handle-mouse  endof
-      h# e8 of  bigmem-int  endof
-      ( default )  rm-set-cf
-         ." Unsupported INT 15 AH=" dup . cr
-   endcase
-;
-
-0 value the-key
-
-: poll-key  ( -- false | scan,ascii true )
-   the-key  ?dup  if  true exit  then
-   d# 50 ms   \ I don't know why this is necessary, but without it, you don't see the key
-   0 " get-scancode" kbd-ih $call-method  if    ( scancode )
-      dup h# 80 and  if                         ( scancode )
-         \ Discard release events and escapes (e0)
-         drop false                             ( false )
-      else
-         dup " scancode->char" kbd-ih $call-method  0=  if  0  then  ( scancode ascii )
-         dup h# 80 and  if  drop 0  then        \ Don't return e.g. 9B for arrows
-         swap bwjoin to the-key
-         the-key true
-      then
-   else
-      false
-   then
-;
-
-0 value polled?
-: poll-keystroke  ( -- )
-   noshow
-   polled?  0=  if  ." ? "  then
-   true to polled?
-   poll-key  if  ( scancode,ascii )
-      rm-ax!
-      rm-flags@ h# 40 invert and rm-flags!
-   else
-      rm-flags@ h# 40 or rm-flags!
-   then
-;
-: get-keystroke  ( -- )
-   noshow
-
-   begin  poll-key  until   ( scancode,ascii )
-   0 to the-key
-   rm-ax!
-
-   rm-al@ [char] q =  if  debug-me  then
-   false to polled?
-;
-
-: keyboard-int  ( -- )  \ INT 16 handler
-   rm-ah@ case
-      0 of  get-keystroke  endof
-      1 of  poll-keystroke  endof
-      2 of  0 rm-al!  endof  \ Claim that no shift keys are active
-      5 of  rm-cx@ to the-key  endof  \ Put keystroke in buffer
-      ( bit 7:sysrq  6:capslock  5:numlock 4:scrlock 3:ralt 2:rctrl 1:lalt 0:lctrl )
-      ( default )  ." Keyboard INT called with AH = " dup . cr
-   endcase
-;
-
-: cfgadr  ( -- adr )
-   caller-regs >rm-edi c@  rm-bx@ 8 lshift or
-;
-: pcibios-installed  ( -- )
-   h# 20494350 caller-regs >rm-edx !   \ "PCI " in little-endian
-   1 rm-al!                            \ Config method 1
-   h# 201 rm-bx!                       \ Version 2.1
-   1 rm-cl!                            \ Number of last PCI bus - XXX get this from PCI node
-;
-: pcibios  ( -- )  \ INT 1a
-   rm-clr-cf
-   rm-al@ case
-      h# 01 of  pcibios-installed  endof
-\     h# 02 of  find-pci-device ( cx:devid dx:vendid si:index -> bh:bus# bl:devfn )   endof  
-\     h# 03 of  find-pci-class-code ( ecx:0,classcode si:index -> bh:bus# bl:devfn )  endof
-\     h# 06 of  pci-special-cycle  ( bh:bus# edx:special_cycle_data )  endof
-      h# 08 of  cfgadr config-b@ rm-cl!  endof
-      h# 09 of  cfgadr config-w@ rm-cx!  endof
-      h# 0a of  cfgadr config-l@ caller-regs >rm-ecx l!  endof
-      h# 0b of  rm-cl@  cfgadr config-b!  endof
-      h# 0c of  rm-cx@  cfgadr config-w!  endof
-      h# 0d of  caller-regs >rm-ecx l@ cfgadr config-l!  endof
- \    h# 0e of  pci-int-rout  endof
- \    h# 0f of  set-pci-int   endof
-
-      ( default )     h# 81 rm-ah!     rm-set-cf
-         ." Unimplemented PCI BIOS INT 1a AH b1 - AL = " dup . cr
-   endcase
-;
-
-: get-timer-ticks  ( -- )
-   get-msecs d# 55 /  lwsplit  rm-cx!  rm-dx!
-   0 rm-al!  \ Should be nonzero if midnight happened since last call
-;
-
-: int-1a  ( -- )
-   rm-ah@  case
-      h#  0  of  get-timer-ticks  noshow  endof
-\      h#  4  of  rm-clr-cf  get-rtc-date  endof  \ ch century   cl year  dh month  dl day
-      h# b1  of  pcibios          endof
-      ( default )  ." Unimplemented INT 1a - AH = " dup .  cr  rm-set-cf
-   endcase
-;
-
-: handle-bios-call  ( -- )
-   snap-int
-   rm-int@  case
-      h# 10  of  video-int     endof
-      h# 11  of  sysinfo-int   endof
-      h# 13  of  noshow disk-int      endof
-      h# 16  of  keyboard-int  endof
-      h# 15  of  system-int    endof
-      h# 12  of  rm-avail /1k rm-ax!  endof  \ Low memory size
-      h# 1a  of  int-1a        endof
-      h# 18  of  ." Entering Open Firmware" cr  interact    endof
-      h# 19  of  ." Rebooting" cr  bye    endof
-      ( default )  ." Interrupt " dup . cr  interact
-   endcase
-   ?showint
-;
-: get-mbr
-   " /pci/ide at 0" open-dev >r
-   h# 7c00 h# 3f 1 " read-blocks" r@ $call-method 1 <> abort" Didn't read MBR"
-   r> close-dev
-;
-: rm-go   ( -- )
-   get-mbr
-   usb-quiet
-   \ Load boot image at 7c00
-   h# 7c00 rm-init-program
+defer handle-bios-call
+: rm-run  ( adr -- )
+   rm-init-program
    begin
       rm-return
       handle-bios-call
    again
 ;
-label xx  h# 99 # al mov  al h# 80 # out  begin again  end-code
-here xx - constant /xx
-: put-xx  ( adr -- )  xx swap /xx move  ;
-: .lreg  ( adr -- adr' )  4 -  dup l@ 9 u.r   ;
-: .wreg  ( adr -- adr' )  2 -  dup w@ 5 u.r   ;
-: .caller-regs  ( -- )
-   ."        AX       CX       DX       BX       SP       BP       SI       DI" cr
-   caller-regs >rm-eax 4 +  8 0 do  .lreg  loop  cr
-   cr
-   ."    DS   ES   FS   GS       PC  FLAGS" cr
-   4 0 do  .wreg  loop  
-   caller-regs >rm-retaddr seg:off@ 9 u.r  2 spaces
-   caller-regs >rm-flags w@ 5 u.r cr
-;

Modified: cpu/x86/pc/biosload/start.bth
===================================================================
--- cpu/x86/pc/biosload/start.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/biosload/start.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -16,7 +16,6 @@
 fload ${BP}/cpu/x86/pc/biosload/config.fth
 
 start-assembling
-protected-mode
 
 label my-entry
 

Modified: cpu/x86/pc/linux.fth
===================================================================
--- cpu/x86/pc/linux.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/linux.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -126,6 +126,16 @@
    cmdline-offset +lp  h# 228 +lp  l!  \ New command line address
 ;
 
+\ If we are running in physical address mode, make a page directory
+\ that will map up when the kernel turns on paging.
+: make-ofw-pdir  ( -- )
+   cr3@  if  exit  then
+   h# 1000  h# 1000  mem-claim cr3!
+   cr3@  h# 1000 erase
+   fw-virt-base h# 83 or  cr3@ fw-virt-base d# 22 rshift la+ l!
+   cr4@  h# 10 or  cr4!
+;
+
 : linux-fixup  ( -- )
 [ifdef] linux-logo  linux-logo  [then]
    args-buf cscount set-parameters          ( )
@@ -133,6 +143,7 @@
 
    linux-base  linux-params  (init-program)
    linux-params to %esi
+   make-ofw-pdir
 ;
 
 d# 256 buffer: ramdisk-buf

Modified: cpu/x86/pc/mmusetup.fth
===================================================================
--- cpu/x86/pc/mmusetup.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/mmusetup.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -11,17 +11,6 @@
 
 0 value pt-pa
 
-\ Move the global descriptor table into the Forth region, thus freeing
-\ the low memory it currently occupies
-: move-gdt   ( -- )
-   gdtr@ 1+                       ( pa size )
-   h# 800 alloc-mem 8 round-up    ( pa size va )  \ Give it plenty of space
-   dup h# 800 erase               ( pa size va )
-   3dup swap move                 ( pa size va )
-   swap 1- gdtr!                  ( pa )
-   drop
-;
-
 : >p  ( va -- pa )  (translate)  0= abort" Not mapped"  drop  ;
 
 : (initial-mmu-setup)  ( -- )	\ Locate the page directory
@@ -66,9 +55,6 @@
 
    RAMtop to pdir-va                              ( old-pdir-va )
 
-   \ Move the Global Descriptor Table into high memory
-   move-gdt
-
 \   0   h# 10.0000  2dup unmap 	release			\ Release old mapping
 ;
 ' (initial-map) to initial-map

Added: cpu/x86/pc/olpc/acpi.fth
===================================================================
--- cpu/x86/pc/olpc/acpi.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/acpi.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,206 @@
+\ 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
+( 000 4 )  " FACP"     $, \ Signature
+( 004 4 )  h#   84     l, \ Table Length
+( 008 1 )  h#   02     c, \ Revision (supports reset adr)
+( 009 1 )  h#   00     c, \ Checksum
+( 00A 6 )  " OLPC  "   $, \ Oem ID
+( 010 8 )  " OLPC_000" $, \ Oem Table ID
+( 018 4 )  " 0000"     $, \ Oem Revision
+( 01C 4 )  " OLPC"     $, \ Asl Compiler ID
+( 020 4 )  " 0000"     $, \ Asl Compiler Revision
+( 024 4 )  facs-adr l,    \ FACS Address
+( 028 4 )  dsdt-adr l,    \ DSDT Address
+( 02C 1 )  h#   00 c,     \ Was Model, now reserved
+( 02D 1 )  h#   00 c,     \ PM Profile
+( 02E 2 )  h# 0003 w,     \ SCI Interrupt
+
+\ These are the values that AMD uses
+\ ( 030 4 )  h# 9c3c l,     \ SMI Command Port
+\ ( 034 1 )  h#   a1 c,     \ ACPI Enable Value
+\ ( 035 1 )  h#   a2 c,     \ ACPI Disable Value
+
+\ These values appear to work, but aren't really necessary if we don't support Legacy SMI PM mode
+\ ( 030 4 )  h# 9c08 l,     \ SMI Command Port
+\ ( 034 1 )  h#    1 c,     \ ACPI Enable Value
+\ ( 035 1 )  h#    0 c,     \ ACPI Disable Value
+
+\ Setting all of these to 0 tells the OS that the system is always in ACPI mode
+( 030 4 )  h#    0 l,     \ SMI Command Port
+( 034 1 )  h#    0 c,     \ ACPI Enable Value
+( 035 1 )  h#    0 c,     \ ACPI Disable Value
+
+( 036 1 )  h#   00 c,     \ S4BIOS Command
+( 037 1 )  h#   00 c,     \ P-State Control
+( 038 4 )  h# 9c00 l,     \ PM1A Event Block Address
+( 03C 4 )  h#    0 l,     \ PM1B Event Block Address
+\ ( 040 4 )  h# 9c28 l,     \ PM1A Control Block Address
+( 040 4 )  h# 9c08 l,     \ PM1A Control Block Address
+( 044 4 )  h#    0 l,     \ PM1B Control Block Address
+( 048 4 )  h# 9c0c l,     \ PM2 Control Block Address
+\ ( 04C 4 )  h# 9c10 l,     \ PM Timer Block Address
+( 04C 4 )  h# 1850 l,     \ PM Timer Block Address
+( 050 4 )  h# 9c18 l,     \ GPE0 Block Address
+( 054 4 )  h#    0 l,     \ GPE1 Block Address
+( 058 1 )  h#    4 c,     \ PM1 Event Block Length
+( 059 1 )  h#    2 c,     \ PM1 Control Block Length
+( 05A 1 )  h#    2 c,     \ PM2 Control Block Length
+( 05B 1 )  h#    4 c,     \ PM Timer Block Length
+( 05C 1 )  h#    8 c,     \ GPE0 Block Length
+( 05D 1 )  h#    0 c,     \ GPE1 Block Length
+( 05E 1 )  h#    0 c,     \ GPE1 Base Offset
+( 05F 1 )  h#    0 c,     \ _CST Support
+( 060 2 )  h#   63 w,     \ C2 Latency
+( 062 2 )  h# 9999 w,     \ C3 Latency
+( 064 2 )  h#    0 w,     \ CPU Cache Size
+( 066 2 )  h#    0 w,     \ Cache Flush Stride
+( 068 1 )  h#    0 c,     \ Duty Cycle Offset
+( 069 1 )  h#    4 c,     \ Duty Cycle Width
+( 06A 1 )  h#   3d c,     \ RTC Day Alarm Index
+( 06B 1 )  h#   3e c,     \ RTC Month Alarm Index
+( 06C 1 )  h#   32 c,     \ RTC Century Index : 
+( 06D 2 )  h#    0 w,     \ Boot Architecture Flags
+( 06F 1 )  h#    0 c,     \ Reserved
+( 070 4 )  h#  5a5 l,     \ Flags
+( 074 12 ) 1 c, 8 c, 0 c, 1 c,  h# 92. d,   \ Reset register - I/O, 8 bits, 0 offset, byte access
+
+( 080 1 )  h#    1 c,     \ Reset value
+( 081 3 )  0 c, 0 c, 0 c, \ Reserved
+here fadt - constant /fadt
+
+\ FADT Flags:
+\      WBINVD is operational : 1
+\ WBINVD does not invalidate : 0
+\        All CPUs support C1 : 1
+\      C2 works on MP system : 0
+\    Power button is generic : 0
+\    Sleep button is generic : 1
+\       RTC wakeup not fixed : 0
+\ RTC wakeup/S4 not possible : 1
+\            32-bit PM Timer : 1
+\          Docking Supported : 0
+
+create rsdp
+( 00 8 )  " RSD PTR " $,  \ Signature
+( 08 1 )       00     c,  \ Checksum
+( 09 6 )  " OLPC  "   $,  \ Oem Id
+( 0f 1 )        2     c,  \ ACPI revision (3.0b)
+( 10 4 )  rsdt-adr    l,  \ RSDT Address
+
+( 14 4 )    d# 36     l,  \ Length for extended version
+( 18 8 )  xsdt-adr    d,  \ XSDT Address
+( 20 1 )        0     c,  \ extended checksum
+( 21 3 )  0 c, 0 c, 0 c,  \ reserved
+here rsdp - constant /rsdp
+
+create rsdt
+( 00 4 )  " RSDT"     $,  \ Signature
+( 04 4 )  h#   34     l,  \ Length
+\ ( 04 4 )  h#   30     l,  \ Length
+( 08 1 )        1     c,  \ Revision
+( 09 1 )       00     c,  \ Checksum
+( 0a 6 )  " OLPC  "   $,  \ Oem Id
+( 10 8 )  " OLPC_000" $,  \ Oem Table Id
+( 18 4 )  " 0000"     $,  \ Oem revision
+( 1c 4 )  " OLPC"     $,  \ Creator ID
+( 20 4 )  " 0000"     $,  \ Creator revision
+( 24 4 )  fadt-adr    l,  \ FADT Address
+( 28 4 )  dsdt-adr    l,  \ DSDT Address
+( 2c 4 )  dbgp-adr    l,  \ DBGP Address
+( 30 4 )  ssdt-adr    l,  \ SSDT Address
+\ ( 30 4 )  prtn-adr    l,  \ PRTN Address
+here rsdt - constant /rsdt
+
+create dbgp
+( 00 4 )  " DBGP"     $,  \ Signature
+( 04 4 )  d#   52     l,  \ Length
+( 08 1 )        1     c,  \ Revision
+( 09 1 )       00     c,  \ Checksum
+( 0a 6 )  " OLPC  "   $,  \ Oem Id
+( 10 8 )  " OLPC_000" $,  \ Oem Table Id
+( 18 4 )  " 0000"     $,  \ Oem revision
+( 1c 4 )  " OLPC"     $,  \ Creator ID
+( 20 4 )  " 0000"     $,  \ Creator revision
+( 24 1 )       0      c,  \ Full 16550 interface
+( 25 3 )  0 c, 0 c, 0 c,  \ reserved
+( 28 c )  1 c, 8 c, 0 c, 1 c,  h# 3f8 l, 0 l,   \ Port base address (generic register descriptor)
+here dbgp - constant /dbgp
+
+create facs
+( 00 4 )  " FACS"     $,  \ Signature
+( 04 4 )  h#   40     l,  \ Length
+( 08 4 )  h# 1234     l,  \ Hardware signature
+( 0c 4 )        0     l,  \ Waking vector
+( 10 4 )        0     l,  \ Global lock
+( 14 4 )        0     l,  \ Flags
+( 18 8 )        0.    d,  \ 64-bit waking vector
+( 20 1 )        1     c,  \ Version
+( 21 1f )  here  d# 31 dup allot  erase
+here facs - constant /facs
+
+: fix-checksum  ( table /table checksum-offset -- )
+   >r over >r      ( table /table r: cksum-offset table )
+   0 -rot   bounds  ?do  i c@ +  loop   ( sum )
+   negate h# ff and  r> r> + c!
+;
+
+: memory-limit  ( -- limit )
+   " /memory" find-package 0= abort" No /memory node"  ( phandle )
+   " available" rot get-package-property abort" No available property"  ( $ )
+   -1 >r                              ( $ )  ( r: limit )
+   begin  dup 0>  while               ( $ )
+      decode-int >r decode-int  r> +  ( $ piece-end )
+      dup 1meg u<=  if  drop   else   ( $ piece-end )
+         r> umin >r                   ( $ )  ( r: limit' )
+      then                            ( $ )
+   repeat                             ( $ )
+   2drop  r>                          ( limit )
+   h# 1000 -   \ Safety page
+;
+
+: setup-acpi  ( -- )
+   \ This has to agree with the _SB's _INI method, which gets the memory size
+   \ from offset h# 180 in the EBDA
+   memory-limit d# 10 rshift  'ebda h# 180 + l!
+
+   \ Copy rsdt and fadt to low memory
+   rsdp  rsdp-adr  /rsdp move  rsdp-adr h# 14 8 fix-checksum   rsdp-adr /rsdp h# 20 fix-checksum  
+   rsdt  rsdt-adr  /rsdt move  rsdt-adr /rsdt 9 fix-checksum
+   fadt  fadt-adr  /fadt move  fadt-adr /fadt 9 fix-checksum
+   dbgp  dbgp-adr  /dbgp move  dbgp-adr /dbgp 9 fix-checksum
+   facs  facs-adr  /facs move
+
+   \ Copy in the DSDT
+   \ I suppose we could point to it in FLASH - if so don't compress it,
+   \ and fixup the address in the fadt and rechecksum the fadt
+   " dsdt" find-drop-in  0= abort" No DSDT "  ( adr len )
+   2dup dsdt-adr swap  move  free-mem
+
+   \ Copy in the SSDT
+   \ I suppose we could point to it in FLASH - if so don't compress it,
+   \ and fixup the address in the fadt and rechecksum the fadt
+   " ssdt" find-drop-in  0= abort" No SSDT "  ( adr len )
+   2dup ssdt-adr swap  move  free-mem
+
+   1 8 acpi-w!  \ Set SCI_EN bit
+   h# ffffffff  h# 18 acpi-l!  \ Ack all leftover events
+;
+
+h# 6000 constant xp-smbus-base
+: rm-platform-fixup  ( -- )
+   xp-smbus-base h# f001   h# 5140.000b  3dup msr!  find-msr-entry  2!
+   xp-smbus-base 1+  h# 10 isa-hdr  >hdr-value  l!
+;

Modified: cpu/x86/pc/olpc/addrs.fth
===================================================================
--- cpu/x86/pc/olpc/addrs.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/addrs.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -23,7 +23,7 @@
 
 dropin-base h# 20 +  constant ResetBase	\ Location of "reset" dropin in ROM
 
-h#  1c0.0000 constant fw-pa
+h#  ec0.0000 constant fw-pa
 h#   20.0000 constant /fw-ram
 [then]
 
@@ -71,8 +71,13 @@
 h#  80.0000 constant def-load-base      \ Convenient for initrd
 
 \ The heap starts at RAMtop, which on this system is "fw-pa /fw-ram +"
-h#  20.0000 constant heap-size
 
+\ We leave some memory in the /memory available list above the heap
+\ for DMA allocation by the sound and USB driver.  OFW's normal memory
+\ usage thus fits in one 4M page-directory mapping region.
+
+h#  18.0000 constant heap-size
+
 h# 300.0000 constant jffs2-dirent-base
 h# 500.0000 constant jffs2-inode-base
 h# 700.0000 constant dma-base
@@ -82,8 +87,27 @@
 h# f.0008 constant resume-entry
 h# f.0800 constant resume-data
 
+\ If you change these, also change {g/l}xmsrs.fth and {g/l}xearly.fth
+h# fd00.0000 constant fb-pci-base
+h# fe00.0000 constant gp-pci-base
+h# fe00.4000 constant dc-pci-base
+h# fe00.8000 constant vp-pci-base
+h# fe00.c000 constant vip-pci-base
+h# fe01.0000 constant aes-pci-base
+h# fe01.a000 constant ohci-pci-base
+h# fe01.b000 constant ehci-pci-base
+h# fe02.0000 constant nand-pci-base
+h# fe02.4000 constant sd-pci-base
+h# fe02.8000 constant camera-pci-base
+h# efc0.0000 constant uoc-pci-base
+
 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
+h#   40.0000 to fw-virt-size
+[then]
 
+
 \ LICENSE_BEGIN
 \ Copyright (c) 2006 FirmWorks
 \ 

Modified: cpu/x86/pc/olpc/chipinit.fth
===================================================================
--- cpu/x86/pc/olpc/chipinit.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/chipinit.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -38,6 +38,14 @@
       gx-msr-init /gx-msr-init
    then
 ;
+: find-msr-entry  ( msr# -- 'data )
+   msr-init-range  bounds  ?do      ( msr# )
+      dup i l@ =  if                ( msr# )
+         drop  i la1+  unloop exit
+      then                          ( msr# )
+   3 /l* +loop                      ( msr# )
+   drop true abort" No MSR entry"
+;
 \ [ifdef] lx-devel
 \  msr: 5000.201f 00000000.0000007b.  \ Posted writes for Legacy IDE registers
 \  msr: 5101.00e0 60000000.1f0ffff8.  \ IOD_BM Descriptor 0 ATA IO address
@@ -69,20 +77,20 @@
    bp pop
 c;
 
-h# fd00.0000 value fb-base
-h# fe00.0000 value gp-base
-h# fe00.4000 value dc-base
-h# fe00.8000 value vp-base
+: map-v=p  ( phys size -- )
+   2dup 0  mmu-claim drop   ( phys size )
+   over swap  -1  mmu-map   ( )
+;
 
 : video-map
 [ifdef] virtual-mode
-   gp-base h# c000 0  mmu-claim drop
-   gp-base dup  h# c000  -1  mmu-map
+   \ Map GP+DC+VP all at once with a large size
+   gp-pci-base h# c000 map-v=p
 [then]
 
    \ Unlock the display controller registers
 \ write_vg_32(DC_UNLOCK, DC_UNLOCK_VALUE);
-   h# 4758 dc-base 0 + l!
+   h# 4758 dc-pci-base 0 + l!
 
 \ Set up the DV Address offset in the DC_DV_CTL register to the offset from frame 
 \ buffer descriptor.  First, get the frame buffer descriptor so we can set the 
@@ -96,21 +104,20 @@
 \ write_vg_32(DC_DV_CTL, mVal.high);
 
    \ The base address of the frame buffer in physical memory
-   h# 1808 msr@ drop  4 lshift  h# fff invert and  ( fb-pa )
-   h# 88 dc-base + l!   \ DV_CTL register, undocumented
+   fb-offset  h# 88 dc-pci-base + l!   \ DV_CTL register, undocumented
 
 \ hw_fb_map_init(PCI_FB_BASE);
 \ Initialize the frame buffer base related stuff.
 
-   h# fd00.0000 h#  84 dc-base + l!   \ GLIU0 Memory offset
-   h# fd00.0000 h#  4c gp-base + l!   \ GP base
-   h# fd80.0000 h# 460 vp-base + l!   \ Flat panel base (reserved on LX)
+   fb-pci-base h#  84 dc-pci-base + l!   \ GLIU0 Memory offset
+   fb-pci-base h#  4c gp-pci-base + l!   \ GP base
+   fb-pci-base h# 80.0000 + h# 460 vp-pci-base + l!   \ Flat panel base (reserved on LX)
 
    \ VGdata.hw_vga_base = h# fd7.c000
    \ VGdata.hw_cursor_base = h# fd7.bc00
    \ VGdata.hw_icon_base = h# fd7.bc00 - MAX_ICON;
 [ifdef] virtual-mode
-   gp-base h# c000  mmu-unmap
+   gp-pci-base h# c000  mmu-unmap
 [then]
 ;
 

Modified: cpu/x86/pc/olpc/config.fth
===================================================================
--- cpu/x86/pc/olpc/config.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/config.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -22,7 +22,7 @@
 \ create syslinux-loaded
 
 
-create virtual-mode
+\ create virtual-mode
 create addresses-assigned  \ Define if base addresses are already assigned
 \ create serial-console      \ Define to default to serial port for console
 create pc
@@ -42,6 +42,7 @@
 create use-pci-isa
 create basic-isa
 create isa-dma-only
+create use-ega
 
 create use-null-nvram  \ Don't store configuration variables
 \ create use-flash-nvram  \ Store configuration variables in SPI FLASH

Modified: cpu/x86/pc/olpc/countdwn.fth
===================================================================
--- cpu/x86/pc/olpc/countdwn.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/countdwn.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -23,8 +23,10 @@
         then
 [ifdef] ukey
          ukey? if
-            ukey drop
+\            ukey drop
+          ukey  h# 1b =  if
             true unloop unloop exit
+          then
          then
 [then]
 
@@ -34,7 +36,8 @@
    false
 ;
 : (interrupt-auto-boot?)  ( -- flag )
-   5
+\   5
+   2
    ." Type the Esc key to interrupt automatic startup" cr
    show-countdown
 ;

Modified: cpu/x86/pc/olpc/devices.fth
===================================================================
--- cpu/x86/pc/olpc/devices.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/devices.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -4,6 +4,7 @@
 : gx?  ( -- flag )  h# 4c000017 msr@ drop  4 rshift  2 =  ;
 : lx?  ( -- flag )  h# 4c000017 msr@ drop  4 rshift  3 =  ;
 
+fload ${BP}/dev/geode/msr.fth
 fload ${BP}/cpu/x86/pc/isaio.fth
 
 [ifdef] rom-loaded
@@ -42,6 +43,13 @@
    d# 1000 rounded-/      to us-factor                  ( )
 ;
 
+[ifdef] use-ega
+0 0 " " " /" begin-package
+   fload ${BP}/dev/egatext.fth
+end-package
+\ devalias screen /ega-text
+[then]
+
 [ifdef] use-root-isa
 0 0  " "  " /" begin-package
    fload ${BP}/cpu/x86/pc/isabus.fth	\ ISA Bus Bridge under root node
@@ -67,11 +75,6 @@
 fload ${BP}/cpu/x86/pc/olpc/timertest.fth  \ Selftest for PIT timer
 
 1 [if]
-dev /interrupt-controller
-h# 20 to vector-base0
-h# 28 to vector-base1
-device-end
-
 warning @ warning off
 : probe-pci  ( -- )
    probe-pci
@@ -113,6 +116,11 @@
 fload ${BP}/dev/isa/irq.fth		\ ISA interrupt dispatcher
 fload ${BP}/cpu/x86/pc/isatick.fth	        \ Use ISA timer as the alarm tick timer
 
+dev /interrupt-controller
+irq-vector-base to vector-base0
+vector-base0 8 + to vector-base1
+device-end
+
 [ifdef] resident-packages
 support-package: 16550
 fload ${BP}/dev/16550pkg/16550.fth  \ Serial port support package
@@ -255,6 +263,12 @@
 
 fload ${BP}/cpu/x86/pc/olpc/boardrev.fth   \ Board revision decoding
 
+: cpu-mhz  ( -- n )
+   " /cpu at 0" find-package drop	( phandle )
+   " clock-frequency" rot get-package-property  if  0 exit  then  ( adr )
+   decode-int nip nip  d# 1000000 /  
+;
+
 stand-init: Date to EC
    time&date d# 2000 -  ['] ec-date! catch  if  3drop  then
    3drop
@@ -298,6 +312,11 @@
 
 : +i encode-int encode+  ;  : 0+i  0 +i  ;
 
+[ifdef] rom-loaded
+fload ${BP}/cpu/x86/pc/olpc/gpioinit.fth
+fload ${BP}/cpu/x86/pc/olpc/chipinit.fth
+[then]
+
 fload ${BP}/cpu/x86/fb16-ops.fth
 fload ${BP}/ofw/termemu/fb16.fth
 0 0  " 1,1"  " /pci" begin-package
@@ -306,11 +325,11 @@
    fload ${BP}/dev/geode/display/loadpkg.fth     \ Geode display
 
    0 0 encode-bytes
-   h# 8200.0910 +i  0+i h# fd00.0000 +i  0+i h# 0080.0000 +i  \ Frame buffer
-   h# 8200.0914 +i  0+i h# fe00.0000 +i  0+i h# 0000.4000 +i  \ GP
-   h# 8200.0918 +i  0+i h# fe00.4000 +i  0+i h# 0000.4000 +i  \ DC
-   h# 8200.091c +i  0+i h# fe00.8000 +i  0+i h# 0000.4000 +i  \ VP
-   h# 8200.0920 +i  0+i h# fe00.c000 +i  0+i h# 0000.4000 +i  \ VIP (LX only)
+   h# 8200.0910 +i  0+i fb-pci-base  +i  0+i h# 0080.0000 +i  \ Frame buffer
+   h# 8200.0914 +i  0+i gp-pci-base  +i  0+i h# 0000.4000 +i  \ GP
+   h# 8200.0918 +i  0+i dc-pci-base  +i  0+i h# 0000.4000 +i  \ DC
+   h# 8200.091c +i  0+i vp-pci-base  +i  0+i h# 0000.4000 +i  \ VP
+   h# 8200.0920 +i  0+i vip-pci-base +i  0+i h# 0000.4000 +i  \ VIP (LX only)
    " assigned-addresses" property
 
 end-package
@@ -319,11 +338,6 @@
 
 fload ${BP}/cpu/x86/adpcm.fth            \ ADPCM decoding
 
-[ifdef] rom-loaded
-fload ${BP}/cpu/x86/pc/olpc/gpioinit.fth
-fload ${BP}/cpu/x86/pc/olpc/chipinit.fth
-[then]
-
 warning @ warning off
 : stand-init
    stand-init

Modified: cpu/x86/pc/olpc/devsmall.fth
===================================================================
--- cpu/x86/pc/olpc/devsmall.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/devsmall.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -172,11 +172,11 @@
    fload ${BP}/dev/geode/display/loadpkg.fth     \ Geode display
 
    0 0 encode-bytes
-   h# 8200.0910 +i  0+i h# fd00.0000 +i  0+i h# 0080.0000 +i  \ Frame buffer
-   h# 8200.0914 +i  0+i h# fe00.0000 +i  0+i h# 0000.4000 +i  \ GP
-   h# 8200.0918 +i  0+i h# fe00.4000 +i  0+i h# 0000.4000 +i  \ DC
-   h# 8200.091c +i  0+i h# fe00.8000 +i  0+i h# 0000.4000 +i  \ VP
-   h# 8200.0920 +i  0+i h# fe00.c000 +i  0+i h# 0000.4000 +i  \ VIP (LX only)
+   h# 8200.0910 +i  0+i h# fb-pci-base  +i  0+i h# 0080.0000 +i  \ Frame buffer
+   h# 8200.0914 +i  0+i h# gp-pci-base  +i  0+i h# 0000.4000 +i  \ GP
+   h# 8200.0918 +i  0+i h# dc-pci-base  +i  0+i h# 0000.4000 +i  \ DC
+   h# 8200.091c +i  0+i h# vp-pci-base  +i  0+i h# 0000.4000 +i  \ VP
+   h# 8200.0920 +i  0+i h# vip-pci-base +i  0+i h# 0000.4000 +i  \ VIP (LX only)
    " assigned-addresses" property
 
 end-package

Added: cpu/x86/pc/olpc/dsdt.bth
===================================================================
--- cpu/x86/pc/olpc/dsdt.bth	                        (rev 0)
+++ cpu/x86/pc/olpc/dsdt.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,8 @@
+purpose: Build the ACPI tables
+
+command: &builder &this
+build-now
+
+" iasl -vi -vr -vs ../dsdt.dsl" expand$ $sh
+\ " iasl -vi -vr -vs ../fadt.dsl" expand$ $sh
+" iasl -vi -vr -vs ../ssdt.dsl" expand$ $sh

Added: cpu/x86/pc/olpc/dsdt.dsl
===================================================================
--- cpu/x86/pc/olpc/dsdt.dsl	                        (rev 0)
+++ cpu/x86/pc/olpc/dsdt.dsl	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,751 @@
+/*
+ XXX need an entry for the DCON (IRQ 6)
+ XXX define the EC somehow (IRQ 3, registers, etc)
+ XXX define the lid switch (IRQ 3)
+ XXX sort out sleep button vs. power button distinction
+ XXX battery device
+ VRs
+ ac1c..ac1f
+ 9e00..9e05 p_blk section 4.7.3.5 p 96
+ 9c2c power control
+ Assumes GPIOs mapped at 0x6100
+ VR 0x14, 1 or 2 probes UARTS 1,2.  Return 0 for "not present"
+ */
+DefinitionBlock ("dsdt.aml", "DSDT", 3, "OLPC  ", "XO-1    ", 0x00001000) {
+    Name (VERS, Package (0x02) {
+        "OLPC XO-1", 
+        "$Id$"
+    })
+    OperationRegion (VSA1, SystemIO, 0xAC1C, 0x04)
+    Field (VSA1, WordAcc, NoLock, Preserve) {
+        VSA2,   16, 
+        VSA3,   16
+    }
+
+    Mutex (VSA4, 0x00)
+
+    Method (VSAR, 1, Serialized) {    // VSAR  (index -- resword )
+        Name (VRRR, Zero)
+        Acquire (VSA4, 0xFFFF)
+        Store (0xFC53, VSA2) // Unlock
+        Store (Arg0, VSA2)
+        Store (VSA3, Local1)
+        Release (VSA4)
+        Store (Local1, VRRR)
+        Return (VRRR)
+    }
+
+    Method (VSAW, 2, Serialized) {  // VSAW ( index value -- )
+        Acquire (VSA4, 0xFFFF)
+        Store (0xFC53, VSA2) // Unlock
+        Store (Arg0, VSA2)
+        Store (Arg1, VSA3)
+        Release (VSA4)
+    }
+
+    Scope (_PR) {
+        Processor (CPU0, 0x01, 0x00000000, 0x00) {}
+//        Processor (CPU0, 0x01, 0x00009E00, 0x06) {
+//            Name (_PCT, Package (0x02) {
+//                ResourceTemplate () {
+//                    Register (SystemIO, 0x08, 0x00, 0x0000000000009C2C, ,)
+//                }, 
+//
+//                ResourceTemplate () {
+//                    Register (SystemIO, 0x08, 0x00, 0x0000000000009C2C, ,)
+//                }
+//            })
+//            // Question: Why have two identical performance states?
+//            Name (_PSS, Package (0x02) {
+//                Package (0x06) { 0x01B1, 0x03BF, 0x2D, Zero, 0x0D, 0x0D }, 
+//                Package (0x06) { 0x01B1, 0x03BF, 0x2D, Zero, 0x0D, 0x0D }
+//            })
+//            Name (_PPC, Zero)
+//        }
+    }
+
+    Name (_S0, Package (0x04) { Zero, Zero, Zero, Zero })  // Values for PM1a,b_CNT.SLP_TYP registers
+    Name (_S1, Package (0x04) { One, One, Zero, Zero })
+    Name (_S3, Package (0x04) { 0x03, 0x03, Zero, Zero })
+    Name (_S5, Package (0x04) { 0x05, 0x05, Zero, Zero })
+    Name (_SB.ZZY2, Zero)
+    Name (ZZY1, Zero)  // Current state - see _SST page 298 for values
+    Name (ZZY3, Zero)  // "Already inited" flag
+    Name (ZZY4, Zero)  // EBDA base address in bytes
+//  Name (ZZY5, Zero)  // Set to EBDA length in bytes - unused
+    Name (ZZY6, Zero)  // Set to memory size in Kbytes
+
+    Method (_PTS, 1, NotSerialized) {
+// VSAW(0, 0xc)
+ Store (Arg0, \_SB.ZZY2) }
+
+//    Method (_GTS, 1, NotSerialized) {  /* VSAW(0, 0xb) */  }  // GoingToSleep
+//    Method (_BFS, 1, NotSerialized) {  /* VSAW(0, 0xa) */   }  // Back from sleep
+
+    Method (_WAK, 1, NotSerialized) {  // Arg is the sleeping state
+// VSAW(0, 9)
+        Store (Zero, \_SB.ZZY2)
+        Switch (ToInteger(Arg0)) {
+            Case (One) {
+                Notify (\_SB.PCI0.USB0, Zero)
+                Notify (\_SB.PCI0.USB1, Zero)
+//                Notify (\_SB.PCI0.SBF0.KBC, Zero)
+//                Notify (\_SB.PCI0.SBF0.PS2M, Zero)
+            }
+            Case (0x03) {
+                Notify (\_SB.PCI0, Zero)
+            }
+        }
+        Return (Zero)  /* Success */
+    }
+
+    Scope (_GPE) {                          // General Purpose Events
+
+        // pdf p 162 has Notify argument values
+        Method (_L00, 0, NotSerialized) {            // Level-triggered event 0
+// VSAW(0, 8)
+            If (LEqual (ZZY1, One)) {                // no state or working state
+//                Notify (\_SB.PCI0.SBF0.KBC, 0x02)
+//                Notify (\_SB.PCI0.SBF0.PS2M, 0x02)
+                Notify (\_SB.PCI0.SBF0, 0x02)
+            }
+        }
+
+        // Likely unnecessary
+//        Method (_L05, 0, NotSerialized)
+//        {
+//            // DDD geoderom guards this with If (LEqual (ZZY1, One))
+//            Notify (\_SB.PCI0.USB0, 0x02)
+//        }
+
+        // XXX probably pointless as power is off
+        Method (_L06, 0, NotSerialized) {            // USB event
+// VSAW(0, 7)
+            If (LEqual (ZZY1, One)) {                // no state or working state
+                Notify (\_SB.PCI0.USB0, 0x02)
+            }
+
+            Notify (\_SB.PCI0.USB1, 0x02)
+        }
+        
+// XXX ??? Do we need a battery event at _L15 ?
+
+        // XXX probably pointless as power is off
+        Method (_L1E, 0, NotSerialized) {            // Comes from IRQ/PME Mapper bit 6 - LID switch
+// VSAW(0, 6)
+            If (LEqual (\_SB.ZZY2, Zero)) {
+                If (LLess (ZZY1, 0x02)) {            // no state or working state or waking
+//                    Notify (\_SB.SLPB, 0x80)         // XXX ??? Should this be LID switch instead?
+                    Notify (\_SB.LIDS, 0x80)         // Request to go to sleep
+                }
+            } Else {
+                Notify (\_SB.LIDS, 0x02)             // Request to wake up
+            }
+        }
+
+        Method (_L1F, 0, NotSerialized) {            // Comes from IRQ/PME Mapper bit 7 - SCI
+// VSAW(0, 5)
+            Notify (\_SB.PCI0, 0x02)                 // Request to wake up from EC
+        }
+    }
+
+    // This is an indicator method - it sets LEDs based on the sleep state
+    Scope (_SI) {
+        Method (_SST, 1, NotSerialized) {
+// VSAW(1, Arg0)
+// XXX ??? need to set LEDs by doing VR accesses - or probably the EC does it automatically
+            Store (Arg0, ZZY1)
+        }
+    }
+
+    Scope (_SB) {
+        Method (_INI, 0, NotSerialized) {
+            If (LEqual (ZZY3, One)) {
+                Return
+            }
+            Store (One, ZZY3)
+
+            CreateWordField (^LNKA._PRS, One, IBMA)
+            CreateWordField (^LNKB._PRS, One, IBMB)
+            CreateWordField (^LNKC._PRS, One, IBMC)
+            CreateWordField (^LNKD._PRS, One, IBMD)
+
+            OperationRegion (QQH1, SystemMemory, 0x040E, 0x02)
+            Field (QQH1, WordAcc, NoLock, Preserve) {
+                QQH2,   16
+            }
+
+            Store (QQH2, Local0)   // Memory address 0x40e - EBDA address from BIOS data area
+            ShiftLeft (Local0, 0x04, ZZY4)
+            OperationRegion (EBDA, SystemMemory, ZZY4, 0x0400)
+
+            Field (EBDA, AnyAcc, NoLock, Preserve) {
+                        AccessAs (ByteAcc, 0x00), 
+                QQE1,   8, 
+                        Offset (0x180), 
+                        AccessAs (DWordAcc, 0x00), 
+                QQE2,   32
+            }
+
+//          Store (QQE1, Local0)
+//          Multiply (Local0, 0x0400, ZZY5)  // Unused
+            Store (QQE2, ZZY6)
+//    VSAW(0, 1)
+        }
+
+        OperationRegion (GPIO, SystemIO, 0x6100, 0x0100)
+        Field (GPIO, DWordAcc, NoLock, Preserve) {
+//                    Offset (0x38), 
+//            GLEE,   32
+                    Offset (0xB0),    // DDD geoderom doesn't have this IMPORTANT - High bank read back
+                ,   10, 
+            LSWI,   1                 // Lid switch bit
+        }
+
+        Device (LNKA) {
+            Name (_HID, EisaId ("PNP0C0F"))
+            Name (_UID, One)
+            Method (_DIS, 0, NotSerialized) { }
+            Name (_CRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, _Y00) {11} })
+            Name (_PRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared,     ) {11} })
+            Name (_STA, 0x09)
+        }
+
+        Device (LNKB) {
+            Name (_HID, EisaId ("PNP0C0F"))
+            Name (_UID, 0x02)
+            Method (_DIS, 0, NotSerialized) { }
+            Name (_CRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, _Y01) {5} })
+            Name (_PRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared,     ) {5} })
+            Name (_STA, 0x09)
+        }
+
+        Device (LNKC) {
+            Name (_HID, EisaId ("PNP0C0F"))
+            Name (_UID, 0x03)
+            Method (_DIS, 0, NotSerialized) { }
+            Name (_CRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, _Y02) {14} })
+            Name (_PRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared,     ) {14} })
+            Name (_STA, 0x09)
+        }
+
+        Device (LNKD) {
+            Name (_HID, EisaId ("PNP0C0F"))
+            Name (_UID, 0x04)
+            Method (_DIS, 0, NotSerialized) { }
+            Name (_CRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, _Y03) {10} })
+            Name (_PRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared,     ) {10} })
+            Name (_STA, 0x09)
+        }
+
+        Device (AC) {  /* AC adapter */
+            Name (_HID, "ACPI0003")
+            Name (_PCL, Package (0x01) { _SB })  // Power consumer list - points to main system bus
+
+            // Power Source - XXX this is a stub - it doesn't really tell you if the AC is on-line
+// XXX ??? Make the AC adapter check actually do something
+            Name (_PSR, One)
+
+//            Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) { Return (0x0F) }
+        }
+
+        // DDD geoderom has no battery stuff
+        Name (BIFP, Package (0x0D)  // Battery info (static)  p 342
+        {
+            One,           // Power units - 1 : mAh / mA
+            0x0ED8,        // Design capacity
+            0x0BB8,        // Last Full Charge capacity
+            One,           // rechargable
+            0x1770,        // Full voltage in mV
+            0x01C2,        // warning capacity
+            0x0F,          // low capacity
+            0x01B3,        // granularity between low and warning
+            0x09F6,        // granularity between warning and full
+            "NiMH (GP) ",  // Model number
+            "MIT OLPC ",   // serial number
+            "NiMH",        // type
+            "OLPC "        // OEM info
+        })
+        Name (BSTP, Package (0x04)  // Battery status (dynamic) p 343
+        {
+            Zero,          // state - bitmask 1: discharging 2: charging 4: critical
+            0x02F8,        // current flow
+            0x0B5E,        // remaining capacity
+            0x5B0A         // voltage in mV
+        })
+        Device (BATT)
+        {
+            Name (_HID, EisaId ("PNP0C0A"))
+            Name (_UID, One)
+            Name (_PCL, Package (0x01)
+            {
+                _SB
+            })
+            Method (_STA, 0, NotSerialized)   // Battery Status
+            {
+                If (LEqual (ZZY2, 0x03))
+                {
+                    Return (0x0F)
+                }
+
+//                If (LNot (Acquire (MUT0, 0x1400)))
+//                {
+//                    Store (RDEC (0xFAA4), Local0)
+//                    Release (MUT0)
+//                }
+
+//                If (And (Local0, One))
+//                {
+                      Return (0x1F)
+//                }
+//                Else
+//                {
+//                    Return (0x0F)
+//                }
+            }
+
+            Method (_BIF, 0, NotSerialized)         // Battery Info
+            {
+//                If (LNot (Acquire (MUT0, 0x1400)))
+//                {
+//                    Store (RDEC (0xFB5F), Local0)
+//                    Store (RDEC (0xF929), Local1)
+//                    Store (Local0, _T00)
+//                    If (LEqual (0x22, _T00))
+//                    {
+//                        Store (0x0ED8, Index (BIFP, One))
+//                        Store (0x0BB8, Index (BIFP, 0x02))
+//                        Store (0x1770, Index (BIFP, 0x04))
+//                        Multiply (Local1, 0x1E, Local1)
+//                        Store (Local1, Index (BIFP, 0x05))
+//                        Store (0x0F, Index (BIFP, 0x06))
+//                        Subtract (Local1, 0x0F, Local2)
+//                        Store (Local2, Index (BIFP, 0x07))
+//                        Subtract (0x0BB8, Local1, Local3)
+//                        Store (Local3, Index (BIFP, 0x08))
+//                        Store ("NiMH (GP) ", Index (BIFP, 0x09))
+//                        Store ("MIT OLPC ", Index (BIFP, 0x0A))
+//                    }
+//                    Else
+//                    {
+//                        If (LEqual (0x11, _T00))
+//                        {
+//                            Store (0x0DDE, Index (BIFP, One))
+//                            Store (0x0C1C, Index (BIFP, 0x02))
+//                            Store (0x1964, Index (BIFP, 0x04))
+//                            Multiply (Local1, 0x1F, Local1)
+//                            Store (Local1, Index (BIFP, 0x05))
+//                            Store (0x0F, Index (BIFP, 0x06))
+//                            Subtract (Local1, 0x0F, Local2)
+//                            Store (Local2, Index (BIFP, 0x07))
+//                            Subtract (0x0C1C, Local1, Local3)
+//                            Store (Local3, Index (BIFP, 0x08))
+//                            Store ("LiFePo4 (BYD) ", Index (BIFP, 0x09))
+//                            Store ("MIT OLPC ", Index (BIFP, 0x0A))
+//                        }
+//                        Else
+//                        {
+//                            If (LEqual (0x12, _T00))
+//                            {
+//                                Store (0x0BB8, Index (BIFP, One))
+//                                Store (0x0AF0, Index (BIFP, 0x02))
+//                                Store (0x1770, Index (BIFP, 0x04))
+//                                Multiply (Local1, 0x1C, Local1)
+//                                Store (Local1, Index (BIFP, 0x05))
+//                                Store (0x0E, Index (BIFP, 0x06))
+//                                Subtract (Local1, 0x0E, Local2)
+//                                Store (Local2, Index (BIFP, 0x07))
+//                                Subtract (0x0AF0, Local1, Local3)
+//                                Store (Local3, Index (BIFP, 0x08))
+//                                Store ("LiFePo4 (GP) ", Index (BIFP, 0x09))
+//                                Store ("MIT OLPC ", Index (BIFP, 0x0A))
+//                            }
+//                        }
+//                    }
+//
+//                    Store (RDEC (0xFAA5), Local0)
+//                    If (And (Local0, 0x08))
+//                    {
+//                        Store ("NiMH", Index (BIFP, 0x0B))
+//                    }
+//                    Else
+//                    {
+//                        Store ("LiON", Index (BIFP, 0x0B))
+//                    }
+//
+//                    Store ("OLPC ", Index (BIFP, 0x0C))
+//                    Release (MUT0)
+//                }
+
+                Return (BIFP)
+            }
+
+            Method (_BST, 0, NotSerialized)
+            {
+//                If (LNot (Acquire (MUT0, 0x1400)))
+//                {
+//                    Store (RDEC (0xFAA5), Local0)
+//                    If (And (Local0, One))
+//                    {
+//                        Store (0x02, Local1)
+//                    }
+//                    Else
+//                    {
+//                        Store (One, Local1)
+//                    }
+//
+//                    Sleep (0x0F)
+//                    Store (RDEC (0xF910), Local0)
+//                    If (LLess (Local0, 0x0F))
+//                    {
+//                        Or (Local1, 0x04, Local1)
+//                    }
+//
+//                    Store (Local1, Index (BSTP, Zero))
+//                    Sleep (0x0F)
+//                    Store (RDEC (0xFB5F), Local1)
+//                    Sleep (0x0F)
+//                    Store (Local1, _T01)
+//                    If (LEqual (0x22, _T01))
+//                    {
+//                        Store (0x02F8, Index (BSTP, One))
+//                        Multiply (Local0, 0x1E, Local2)
+//                    }
+//                    Else
+//                    {
+//                        If (LEqual (0x11, _T01))
+//                        {
+//                            Store (0x05DC, Index (BSTP, One))
+//                            Multiply (Local0, 0x1F, Local2)
+//                        }
+//                        Else
+//                        {
+//                            If (LEqual (0x12, _T01))
+//                            {
+//                                Store (0x05DC, Index (BSTP, One))
+//                                Multiply (Local0, 0x1C, Local2)
+//                            }
+//                        }
+//                    }
+//
+//                    Store (Local2, Index (BSTP, 0x02))
+//                    Release (MUT0)
+//                }
+
+                Return (BSTP)
+            }
+        }
+
+// XXX ??? Need battery device with static and dynamic info
+
+        Device (LIDS) {
+            Name (_HID, EisaId ("PNP0C0D"))
+            Name (_PRW, Package (0x02) {  0x1e, 0x03 })            // Event 1e, wakes from S3
+            Method (_LID, 0, NotSerialized) {  Return (LSWI)  }    // Lid switch bit
+        }
+
+        Device (PCI0) {
+            Name (_HID, EisaId ("PNP0A03"))
+            Name (_ADR, Zero)
+
+            // XXX Probably should be sleep state 0 - can't wake from PCI as power is off
+//            Name (_PRW, Package (0x02) { 0x1f, 0x05 })
+            Name (_PRW, Package (0x02) { 0x1f, 0x03 })
+
+//            Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) { Return (0x0F) }
+
+            /*
+             I simplified this by omitting the LNKx devices, setting the source
+             field to Zero, and putting the IRQ# in the source index field.
+             See pdf p 208.  Programmable interrupt routing is useless on OLPC.
+             */
+            
+            Name (_PRT, Package (0x15) {
+                                 /* Address, pin#, source, source index */
+//                Package (0x04) { 0x0001FFFF, Zero, Zero, 14 },  // Slot1 pin 0 - AES - IRQ 14
+//                Package (0x04) { 0x000FFFFF,  One, Zero, 05 },  // SlotF pin 1 - Audio - IRQ 5
+//                Package (0x04) { 0x000FFFFF, 0x03, Zero, 10 },  // SlotF pin 3 - UHCI and EHCI - IRQ 10
+//                Package (0x04) { 0x000CFFFF, Zero, Zero, 11 },  // SlotC pin 1 - CaFe - IRQ 11
+
+// XXX need an assignment of IRQ 14 to the AES device at dev 1, function 2 (INTA)
+                  Package (0x04) { 0x0001FFFF, Zero, LNKC, Zero },  // Slot1 pin 0 - AES - IRQ 14
+                  Package (0x04) { 0x0001FFFF, 0x02, LNKC, Zero },  // Slot1 pin 0 - AES - IRQ 14
+                  Package (0x04) { 0x000FFFFF,  One, LNKB, Zero },  // SlotF pin 1 - Audio - IRQ 5
+                  Package (0x04) { 0x000FFFFF, 0x03, LNKD, Zero },  // SlotF pin 3 - UHCI and EHCI - IRQ 10
+                  Package (0x04) { 0x000CFFFF, Zero, LNKA, Zero },  // SlotC pin 1 - CaFe - IRQ 11
+           })
+            Name (CRES, ResourceTemplate () {
+                WordBusNumber (ResourceConsumer, MinNotFixed, MaxNotFixed, PosDecode,
+                    0x0000,             // Granularity
+                    0x0000,             // Range Minimum
+                    0x00FF,             // Range Maximum
+                    0x0000,             // Translation Offset
+                    0x0100,             // Length
+                    ,, )
+                IO (Decode16, 0x0CF8, 0x0CF8, 0x01, 0x08, )
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8,
+                    ,, , TypeStatic)
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000, 0x0D00, 0xAC17, 0x0000, 0x9F18,
+                    ,, , TypeStatic)
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+                    0x0000, 0xAC20, 0xFFFF, 0x0000, 0x53E0,
+                    ,, , TypeStatic)
+
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                    0x00000000, 0x000A0000, 0x000BFFFF, 0x00000000, 0x00020000,
+                    ,, , AddressRangeMemory, TypeStatic)
+
+//                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+//                    0x00000000, 0x000C0000, 0x000DFFFF, 0x00000000, 0x00020000,
+//                    ,, , AddressRangeMemory, TypeStatic)
+
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                    0x00000000, 0x000C8000, 0x000DFFFF, 0x00000000, 0x00018000,
+                    ,, , AddressRangeMemory, TypeStatic)
+
+
+// This is a template, edited by _CRS, for the address space that PCI claims between the top of main memory and
+// the bottom of (SMM memory)?.
+//                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+//                    0x00000000, 0x04000000, 0x403FFFFF, 0x00000000, 0x3C400000,
+//                    ,, _Y04, AddressRangeMemory, TypeStatic)
+
+// This is a template, edited by _CRS, for the address space that PCI claims abover the top of SMM memory
+//                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+//                    0x00000000, 0x40500000, 0xEFFFFFFF, 0x00000000, 0xAFB00000,
+//                    ,, _Y05, AddressRangeMemory, TypeStatic)
+
+//                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+//                    0x00000000, 0xB0000000, 0xbfFFFFFF, 0x00000000, 0x10000000,
+//                    ,, , AddressRangeMemory, TypeStatic)
+
+// Since we can't plug in PCI devices, there is no need for an allocation pool of PCI address space
+// We just declare a modest amount of PCI space and preassign device addresses in the firmware
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+                    0x00000000, 0xfd000000, 0xfeFFFFFF, 0x00000000, 0x02000000,
+                    ,, , AddressRangeMemory, TypeStatic)
+
+//                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+//                    0x00000000, 0xF0000000, 0xFEFFFFFF, 0x00000000, 0x0f000000,
+//                    ,, , AddressRangeMemory, TypeStatic)
+
+            })
+            Method (_CRS, 0, NotSerialized) {
+//    VSAW(0, 2)
+//                CreateDWordField (CRES, \_SB.PCI0._Y04._MIN, RMIN)
+//                CreateDWordField (CRES, \_SB.PCI0._Y04._MAX, RMAX)
+//                CreateDWordField (CRES, \_SB.PCI0._Y04._LEN, RLEN)
+//                CreateDWordField (CRES, \_SB.PCI0._Y05._MIN, PMIN)
+//                CreateDWordField (CRES, \_SB.PCI0._Y05._MAX, PMAX)
+//                CreateDWordField (CRES, \_SB.PCI0._Y05._LEN, PLEN)
+//                Store (ZZY6, Local0)             // size from EBDA[0x180]
+//                Add (Local0, 0x40, Local0)       // + 64
+//                ShiftLeft (Local0, 0x0A, RMIN)   // * 1024 -> RMIN above
+//                Subtract (0x80400000, One, RMAX) // 803f.ffff -> RMAX above
+//                Subtract (RMAX, RMIN, Local1)
+//                Increment (Local1)
+//                Store (Local1, RLEN)                   // -> RLEN above
+//                Add (0x80400000, 0x00100000, PMIN)     // -> PMIN
+//                Add (Subtract (PMAX, PMIN), One, PLEN) // -> PLEN
+                Return (CRES)
+            }
+
+            Device (SBF0) {   /* Southbridge function 0 */
+                Name (_ADR, 0x000F0000)                          // PCI dev F, fn 0
+                Method (_INI, 0, NotSerialized) {
+  ^^^_INI () 
+//    VSAW(0, 3)
+}  // Call root _INI ?  Parent: PCI0 Grandparent: system bus
+
+                Device (RTC0) {
+//   Method (_INI, 0, NotSerialized) { VSAW(1, 0x55) }
+
+                    Name (_HID, EisaId ("PNP0B00"))
+                    Name (_UID, Zero)
+//                    Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(1, 0x56)
+ Return (0x0F) }
+
+                    Name (_CRS, ResourceTemplate () {
+                        IRQNoFlags () {8}
+                        IO (Decode16, 0x0070, 0x0070, 0x00, 0x04, )
+                    })
+                }
+
+                Device (TMR) {
+//   Method (_INI, 0, NotSerialized) { VSAW(2, 0x55) }
+                    Name (_HID, EisaId ("PNP0100"))
+//                    Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(2, 0x56)
+ Return (0x0F) }
+                    Name (_CRS, ResourceTemplate () {
+                        IRQNoFlags () {0}
+                        IO (Decode16, 0x0040, 0x0040, 0x00, 0x04, )
+                        IO (Decode16, 0x0048, 0x0048, 0x00, 0x04, )
+                    })
+                }
+
+// Elided speaker
+
+// XXX ??? Do we need to reinstate this MEM node???
+
+                Device (MEM) {
+//   Method (_INI, 0, NotSerialized) { VSAW(3, 0x55) }
+                    Name (_HID, EisaId ("PNP0C01"))
+                    Name (_UID, One)
+                    Method (_CRS, 0, NotSerialized) {
+// VSAW(0, 4)
+                        Name (MBRB, ResourceTemplate () {
+                            Memory32Fixed (ReadWrite, 0x00000000, 0x000A0000, )
+                            Memory32Fixed (ReadOnly,  0x000E0000, 0x00020000, )
+                            Memory32Fixed (ReadWrite, 0x00100000, 0x00000000, _Y06)  // Edited below
+                            // Assumes that the SMM memory is at 8040.0000, I think
+               //           Memory32Fixed (ReadOnly, 0x80400000, 0x00040000, )
+                            Memory32Fixed (ReadOnly, 0xFFF00000, 0x00100000, )  // GeodeROM has f0000000,10000000
+
+                            IO (Decode16, 0x0092, 0x0092, 0x00, 0x01, )
+                        })
+                        CreateDWordField (MBRB, \_SB.PCI0.SBF0.MEM._CRS._Y06._LEN, EM1L)
+                        Store (ZZY6, Local0)                // Memory size in Kbytes (from EBDA)
+                        Subtract (Local0, 0x0400, Local0)   // Subtract 1024 (for below 1M mem)
+                        ShiftLeft (Local0, 0x0A, Local0)    // Multiply by 1K to convert to bytes
+                        Store (Local0, EM1L)                // Punch into the data structure
+                        Return (MBRB)
+                    }
+                }
+
+                Device (PIC)
+                {
+//   Method (_INI, 0, NotSerialized) { VSAW(4, 0x55) }
+                    Name (_HID, EisaId ("PNP0000"))
+//                    Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(4, 0x56)
+ Return (0x0F) }
+                    Name (_CRS, ResourceTemplate () {
+                        IRQNoFlags () {2}
+                        IO (Decode16, 0x0020, 0x0020, 0x00, 0x02, )
+                        IO (Decode16, 0x00A0, 0x00A0, 0x00, 0x02, )
+                        IO (Decode16, 0x04D0, 0x04D0, 0x10, 0x02, )
+                    })
+                }
+
+                Device (MAD)
+                {
+//   Method (_INI, 0, NotSerialized) { VSAW(5, 0x55) }
+                    Name (_HID, EisaId ("PNP0200"))
+//                    Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(5, 0x56)
+ Return (0x0F) }
+                    Name (_CRS, ResourceTemplate () {
+                        DMA (Compatibility, BusMaster, Transfer8, ) {4}
+                        IO (Decode16, 0x0000, 0x0000, 0x10, 0x10, )
+                        IO (Decode16, 0x0080, 0x0080, 0x10, 0x10, )
+                        IO (Decode16, 0x00C0, 0x00C0, 0x10, 0x20, )
+                        IO (Decode16, 0x0480, 0x0480, 0x10, 0x10, )
+                    })
+                }
+
+                Device (COPR) {
+//   Method (_INI, 0, NotSerialized) { VSAW(6, 0x55) }
+                    Name (_HID, EisaId ("PNP0C04"))
+                    Name (_CRS, ResourceTemplate () {
+                        IO (Decode16, 0x00F0, 0x00F0, 0x10, 0x10, )
+                        IRQNoFlags () {13}
+                    })
+                }
+
+// Elided UART
+
+// Elided superio
+
+// XXX ??? Maybe this should be moved out a level so it's not under SB F0
+                Device (KBC) {
+//   Method (_INI, 0, NotSerialized) { VSAW(7, 0x55) }
+                    Name (_HID, EisaId ("PNP0303"))
+                    Name (_CID, 0x0B03D041)
+
+                    // Return this one if can wake from keyboard - XXX maybe need to be 3 instead of One
+                    Name (_PRW, Package (0x02) { Zero, One })
+
+// XXX ??? do we need a _PSW method?
+                Method (_PSW, 1, NotSerialized) { }
+
+                    // XXX Can we control whether or not the keyboard can wake us up?
+                    Name (_CRS, ResourceTemplate () {
+                        IRQNoFlags () {1}
+                        IO (Decode16, 0x0060, 0x0060, 0x00, 0x01, )
+                        IO (Decode16, 0x0064, 0x0064, 0x00, 0x01, )
+                    })
+//                    Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(7, 0x56)
+ Return (0x0F) }
+                }
+
+                Device (PS2M) {
+//   Method (_INI, 0, NotSerialized) { VSAW(0xc, 0x55) }
+//                    Name (_HID, EisaId ("PNP0F13"))     // Microsoft Intellipoint
+                    Name (_HID, EisaId ("PNP0F03"))     // ALPS Pointing device
+                    Name (_CID, 0x130FD041)
+                    Name (_PRW, Package (0x02) { Zero, One })
+// XXX ??? do we need a _PSW method?
+                    Method (_PSW, 1, NotSerialized) { }
+                    Name (_CRS, ResourceTemplate () { IRQNoFlags () {12} })
+//                    Name (_STA, 0x0F )
+Method (_STA, 0, NotSerialized) {
+// VSAW(0xc, 0x56)
+ Return (0x0F) }
+                }
+// Elided FDC0
+// Elided SuperIO UART
+// Elided LPT
+// Elided IDE
+            }
+
+            Device (USB0) {
+//   Method (_INI, 0, NotSerialized) { VSAW(8, 0x55) }
+                Name (_ADR, 0x000F0004)
+                Name (_STR, Unicode ("CS553x USB Controller 0"))
+//                Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(8, 0x56)
+ Return (0x0F) }
+
+                Name (_PRW, Package (0x02) { 0x06, One })
+            }
+
+            Device (USB1) {
+//   Method (_INI, 0, NotSerialized) { VSAW(9, 0x55) }
+                Name (_ADR, 0x000F0005)
+                Name (_STR, Unicode ("CS553x USB Controller 1"))
+//                Name (_STA, 0x0F)
+Method (_STA, 0, NotSerialized) {
+// VSAW(9, 0x56)
+ Return (0x0F) }
+                Name (_PRW, Package (0x02) { 0x06, One })
+            }
+
+//            Device (USB2) {
+//   Method (_INI, 0, NotSerialized) { VSAW(0xa, 0x55) }
+//                Name (_ADR, 0x000F0006)
+//                Name (_STR, Unicode ("CS5536 USB Controller 2 (UDC)"))
+//                Name (_STA, 0x0F)
+//            }
+
+//            Device (USB3) {
+//   Method (_INI, 0, NotSerialized) { VSAW(0xb, 0x55) }
+//                Name (_ADR, 0x000F0007)
+//                Name (_STR, Unicode ("CS5536 USB Controller 3 (OTG)"))
+//                Name (_STA, 0x0F)
+//            }
+        }
+    }
+}

Modified: cpu/x86/pc/olpc/fw.bth
===================================================================
--- cpu/x86/pc/olpc/fw.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/fw.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -20,8 +20,6 @@
 : \Tags [compile] \  ; immediate
 : \NotTags [compile] \  ; immediate
 
-fload ${BP}/cpu/x86/pc/segments.fth     \ Segment selectors (address spaces)
-
 : RAMbase  ( -- adr )  fw-virt-base  ;
 : RAMtop  ( -- adr )  RAMbase /fw-ram +  ;
 
@@ -73,6 +71,11 @@
 fload ${BP}/ofw/core/clntmem1.fth	\ client services for memory
 [else]
 fload ${BP}/ofw/core/clntphy1.fth	\ client services for memory
+: >physical  ( va -- pa )
+   dup fw-virt-base - fw-virt-size u<  if   ( va )
+      fw-virt-base -  fw-pa +
+   then
+;
 [then]
 fload ${BP}/ofw/core/memlist.fth	\ Resource list common routines
 fload ${BP}/ofw/core/showlist.fth	\ Linked list display tool
@@ -340,6 +343,14 @@
 fload ${BP}/cpu/x86/pc/olpc/gamekeys.fth
 fload ${BP}/cpu/x86/pc/linux.fth
 fload ${BP}/cpu/x86/pc/olpc/memtest.fth
+
+fload ${BP}/cpu/x86/pc/rmtools.fth
+fload ${BP}/dev/geode/smi.fth
+fload ${BP}/cpu/x86/pc/olpc/acpi.fth
+fload ${BP}/cpu/x86/pc/olpc/smbios.fth
+\ fload ${BP}/cpu/x86/pc/biosload/rmenter.fth
+fload ${BP}/cpu/x86/pc/biosints.fth
+
 fload ${BP}/cpu/x86/pc/olpc/setwp.fth
 fload ${BP}/cpu/x86/pc/olpc/security.fth
 fload ${BP}/cpu/x86/pc/olpc/fsupdate.fth
@@ -353,13 +364,22 @@
 ' gx-power-off to power-off
 [then]
 
-" disk:\boot\olpc.fth sd:\boot\olpc.fth nand:\boot\olpc.fth /prober /usb/ethernet /usb/wlan"
+[ifdef] use-ega
+: ega-output  ( -- )
+   \ This only works if stdout is currently /display
+   stdout @  if
+      " text-mode3" screen-ih $call-method
+   then
+   " /ega-text" output
+;
+[then]
+
+" /xp disk:\boot\olpc.fth sd:\boot\olpc.fth nand:\boot\olpc.fth /prober /usb/ethernet /usb/wlan"
    ' boot-device  set-config-string-default
 
 \needs ramdisk  " " d# 128 config-string ramdisk
 " "   ' boot-file      set-config-string-default   \ Let the boot script set the cmdline
 
-
 : dimmer  ( -- )  screen-ih  if  " dimmer" screen-ih $call-method  then  ;
 : brighter  ( -- )  screen-ih  if  " brighter" screen-ih $call-method  then  ;
 

Modified: cpu/x86/pc/olpc/fwsmall.bth
===================================================================
--- cpu/x86/pc/olpc/fwsmall.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/fwsmall.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -186,7 +186,7 @@
 ;
 
 [ifdef] linux-support
-fload ${BP}/cpu/x86/pc/olpc/linux.fth
+fload ${BP}/cpu/x86/pc/linux.fth
 [then]
 
 fload ${BP}/dev/null.fth

Modified: cpu/x86/pc/olpc/gui.fth
===================================================================
--- cpu/x86/pc/olpc/gui.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/gui.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -179,11 +179,7 @@
    until
 ;
 
-: .cpu-data  ( -- )
-   " /cpu at 0" find-package drop	( phandle )
-   " clock-frequency" rot get-package-property  if  exit  then  ( adr )
-   decode-int nip nip  d# 1000000 /  ." CPU Speed:  "  .d ."  MHz" cr
-;
+: .cpu-data  ( -- )  cpu-mhz ." CPU Speed:  "  .d ."  MHz" cr  ;
 
 : .usb  ( -- )
    " /usb" find-package 0=  if  exit  then

Added: cpu/x86/pc/olpc/gxearly.fth
===================================================================
--- cpu/x86/pc/olpc/gxearly.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/gxearly.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,84 @@
+\ Included from romreset.bth - early core MSR setup for the Geode GX
+
+   11. 1100 set-msr        \ Enable branch target buffer and near call return stack GX page 116
+
+   \ The next few MSRs allow us to access the 5536
+   \ EXTMSR - page 449   \ Use PCI device #F for port 2
+   00000000.00000f00.   5000201e set-msr  \ cs5536_setup_extmsr(void)
+
+   \ write IDSEL to the write once register at address 0x0000
+   \ 02000000 0 port-wl  \ This is the default value so we need not set it
+
+   \ setup CPU interface serial to mode C on both sides
+   44000020.00200013. 51000010 set-msr   \ 5536 p 229
+
+   \ Tell the GX what kind of companion chip is attached.
+   \ The GX datasheet is incorrect; 2 means 5536, not a reserved value
+   00000000.00000002.   54002010 set-msr
+
+   \ Set up GPIO base register
+   0000f001.00001000.   5140000c set-msr  \ GPIO BAR
+
+fload ${BP}/cpu/x86/pc/olpc/inituart.fth
+
+   h# 11 # al mov  al h# 80 # out
+   h# 1430 # dx mov  dx ax in  h# 9999 # ax cmp  =  if
+      h# 34 #  al mov    al  h# 70 #  out   \ Write to CMOS 0x34
+      h# 10 #  al mov    al  h# 71 #  out   \ Write value 01
+   then
+
+ \ Init memory controller
+
+   \ sdram_initialize,generic_sdram.c
+   \ sdram_set_spdregisters(),auto.c
+ 
+   \ gpio_init,auto.c
+   4 1020 port-wl          \ Enable the GPIO bit that reports DRAM size (ticket 151)
+
+   \ Refresh and SDRAM program MSR GX page 205
+   \ 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.
+   1030 port-rl 4 bitand  0<> if  \ 128 MiB
+      25fff002.1077e000.      1808 set-msr
+      2c7be040.400fffe0.  10000026 set-msr
+      20000007.7df00100.  10000028 set-msr \ Top of memory
+      20a7e0fd.7fffd000.  10000029 set-msr \ Frame buffer
+      10075012.00003400.  20000018 set-msr
+      20000007.7df00100.  40000029 set-msr \ top of memory.
+      077df000.00100130.  50002019 set-msr
+   else                           \ 256 MiB
+      25fff002.10f7e000.      1808 set-msr
+      2cfbe040.400fffe0.  10000026 set-msr
+      2000000f.7df00100.  10000028 set-msr \ Top of memory
+      2127e0fd.7fffd000.  10000029 set-msr \ Frame buffer
+      10076013.00003400.  20000018 set-msr
+      2000000f.7df00100.  40000029 set-msr \ top of memory.
+      0f7df000.00100130.  50002019 set-msr
+   then
+
+   \ 20000019 rmsr            \ SDRAM timing and mode program
+   18000108.286332a3.   20000019 set-msr
+
+   \ The RAM controller is now set up
+
+ \ Init the SDRAMs
+ \ sdram_enable,src/northbridge/amd/gx2/raminit.c
+
+   \ Clock gating for PMode
+   \ Clocks always on in mode 1, hardware gating in mode 0
+\   20002004 rmsr  4 bitclr  1 bitset  20002004 wmsr  \ GX p 199
+   1. 20002004 set-msr  \ GX p 199
+
+   \ Delay on exit from power mode 1, use unbuffered RAM
+   101. 2000001a set-msr    \ MC_CF1017_DATA GX p 210
+
+   \ Unmask CKE1 and CKE0
+   0. 2000001d set-msr   \ MC_CFCLK_DBG Clear 300 bits
+
+   \ load RDSYNC
+   \ Empirically, the recommended setting of 0xff310.00000000. causes RAM errors
+   00000310.00000000.   2000001f set-msr  \ GX page 215
+
+   \ set delay control.  The exact value below is specified in the GX manual.
+   830d415a.8ea0ad6a.   4c00000f set-msr

Added: cpu/x86/pc/olpc/inituart.fth
===================================================================
--- cpu/x86/pc/olpc/inituart.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/inituart.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,43 @@
+purpose: Common code fragment for setting up Geode serial port in early init
+
+   \ Set the UART TX line high - this prevents a low-going glitch that
+   \ the receiver interprets as a character.
+   100.0000 1010 port-wl   \ Output AUX1 select - UART TX as GPIO for now
+        100 1000 port-wl   \ high
+        100 1004 port-wl   \ GPIO1 - output enable
+
+   \ The UART init sequence takes 550 uS running from ROM
+ [ifdef] use-uart2
+   \ cs5536_setup_onchipuart,cs5536_early_setup.c:205.14
+   0.00000012.   5140003e set-msr  \ enable UART2
+
+   \ GPIO1 - UART2 TX
+   10 1004 port-wl   \ GPIO4 - output enable - UART2 TX
+   10 1010 port-wl   \ Output AUX1 select - UART2 TX
+    8 1020 port-wl   \ Input enable UART2 RX
+    8 1034 port-wl   \ Input AUX1 select - UART2 RX
+   0.8070.0003  51400014 set-msr  \ MDD_LEG_IO  UART2 at COM1 address
+ [else]
+   \ cs5536_setup_onchipuart,cs5536_early_setup.c:205.14
+   0.00000012.   5140003a set-msr  \ enable COM1
+
+   \ GPIO1 - UART1 TX
+   100 1004 port-wl   \ GPIO1 - output enable
+   100 1010 port-wl   \ Output AUX1 select - UART TX
+   200 1020 port-wl   \ Input enable UART RX
+   200 1034 port-wl   \ Input AUX1 select - UART RX
+   0.8007.0003.  51400014 set-msr  \ MDD_LEG_IO  legacy IO
+ [then]
+
+   \ uart_init,serial.c
+   \ This is a garden-variety 8250 UART setup sequence
+    0 3f9 port-wb
+    1 3fa port-wb
+   83 3fb port-wb  \ DLAB
+    1 3f8 port-wb  \ 115200 divisor low
+    0 3f9 port-wb  \ 115200 divisor high
+    3 3fb port-wb  \ !DLAB
+   \ At this point we could send characters out the serial port
+   \ End of serial init
+
+   char + 3f8 port-wb  begin  3fd port-rb 40 bitand  0<> until

Modified: cpu/x86/pc/olpc/linuxserial.fth
===================================================================
--- cpu/x86/pc/olpc/linuxserial.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/linuxserial.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -32,7 +32,7 @@
 ;
 
 : $open-serial  ( dev$ -- )  \ e.g. " /dev/ttyS0"
-   serial-fd -1 <>  if  2drop  then
+   serial-fd -1 <>  if  2drop exit  then
    $cstr  0 2 rot  8 syscall  3drop retval  to serial-fd
    serial-fd 0< abort" Can't open serial device"
    raw  8n1  blocking

Modified: cpu/x86/pc/olpc/loaddropins.fth
===================================================================
--- cpu/x86/pc/olpc/loaddropins.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/loaddropins.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -50,6 +50,9 @@
    " ${BP}/cpu/x86/pc/olpc/images/sd.565"       " sd.565"        $add-deflated-dropin
 
    " ${BP}/ofw/termemu/gallant.obf"             " font"          $add-deflated-dropin
+[ifdef] use-ega
+   " ${BP}/ofw/termemu/cp881-16.obf"            " pcfont"        $add-deflated-dropin
+[then]
 
    " verify.img"                                " verify"        $add-deflated-dropin
    " os.public"                                 " ospubkey"      $add-dropin \ Incompressible

Added: cpu/x86/pc/olpc/lxearly.fth
===================================================================
--- cpu/x86/pc/olpc/lxearly.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/lxearly.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,107 @@
+\ Included from romreset.bth - early core MSR setup for the Geode LX
+
+   \ The next few MSRs allow us to access the 5536
+   \ EXTMSR - page 449   \ Use PCI device #F for port 2
+   00000000.00000f00.   5000201e set-msr  \ cs5536_setup_extmsr(void)
+
+   \ write IDSEL to the write once register at address 0x0000
+   \ 02000000 0 port-wl  \ This is the default value so we need not set it
+
+   \ setup CPU interface serial to mode C on both sides
+   44000020.00200013. 51000010 set-msr   \ 5536 p 229
+
+   \ Set up GPIO base register
+   0000f001.00001000.   5140000c set-msr  \ GPIO BAR
+
+ \ Init UART
+[ifndef] lx-devel
+fload ${BP}/cpu/x86/pc/olpc/inituart.fth
+[then]  \ lx-devel
+
+   h# 11 # al mov  al h# 80 # out
+   h# 1430 # dx mov  dx ax in  h# 9999 # ax cmp  =  if
+      h# 34 #  al mov    al  h# 70 #  out   \ Write to CMOS 0x34
+      h# 11 #  al mov    al  h# 71 #  out   \ Write value 0x11
+   then
+
+ \ Init memory controller
+
+   \ sdram_initialize,generic_sdram.c
+   \ sdram_set_spdregisters(),auto.c
+ 
+   \ 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
+   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
+   ffbff000.ff800100.      1817 set-msr  \ Region config - OFW area cacheable
+   10076013.00005040.  20000018 set-msr  \ DIMM1 empty, DIMM0 256 MB, 1 module bank, 8K pages
+   2000000e.fff00100.  4000002c set-msr  \ DMA to memory from 1M to RAM limit at 0f00.0000
+   0efff000.00100130.  50002019 set-msr  \ PCI DMA to memory from 1M to RAM limit at 0f00.0000, fbsize
+
+   \ 20000019 rmsr            \ SDRAM timing and mode program
+   00000000.2814d352.   00001981 set-msr  \ Memory delay values
+   00000000.1068334d.   00001982 set-msr  \ Memory delay values
+   00000106.83104104.   00001983 set-msr  \ Memory delay values
+   00000000.00000001.   00001980 set-msr  \ Enable memory delays
+
+[ifdef] cmos-startup-control
+   h# 61 #  al mov    al  h# 70 #  out   h# 71 #  al in  \ Read CMOS 0x61
+   al al test  0= if
+[then]
+      18000100.6a7332a0.   20000019 set-msr
+
+      \ The RAM controller is now set up
+
+    \ Init the SDRAMs
+    \ sdram_enable,src/northbridge/amd/gx2/raminit.c
+
+      \ Clock gating for PMode
+      \ Clocks always on in mode 1, hardware gating in mode 0
+  \   20002004 rmsr  4 bitclr  1 bitset  20002004 wmsr  \ GX p 199
+      1. 20002004 set-msr  \ GX p 199
+
+      \ Delay on exit from power mode 1, use unbuffered RAM
+      130cd801. 2000001a set-msr    \ MC_CF1017_DATA  LX p 231
+[ifdef] cmos-startup-control
+   else
+      al dec  al h# 71 # out            \ Decrement safety counter
+
+      h# 64 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
+      h# 65 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
+      d# 16 # bx shl
+      h# 62 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
+      h# 63 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
+      
+      h# 18000100 # dx mov  bx ax mov  h# 20000019 wmsr
+
+      \ The RAM controller is now set up
+
+    \ Init the SDRAMs
+    \ sdram_enable,src/northbridge/amd/gx2/raminit.c
+
+      \ Clock gating for PMode
+      \ Clocks always on in mode 1, hardware gating in mode 0
+  \   20002004 rmsr  4 bitclr  1 bitset  20002004 wmsr  \ GX p 199
+      1. 20002004 set-msr  \ GX p 199
+
+      \ Delay on exit from power mode 1, use unbuffered RAM
+      h# 68 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
+      h# 69 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
+      d# 16 # bx shl
+      h# 66 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
+      h# 67 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
+
+      dx dx xor  bx ax mov  2000001a wmsr    \ MC_CF1017_DATA  LX p 231
+   then
+[then]
+
+   00000200.00000000. 20000020 set-msr   \ Power mode entry and exit delays
+
+   \ Unmask CKE1 and CKE0
+   1000. 2000001d set-msr   \ MC_CFCLK_DBG Clear 300 bits, don't tristate in IDLE
+
+   \ Reset memory controller
+   20000018 rmsr    \ MC_CF07_DATA
+   2 bitset  20000018 wmsr
+   2 bitclr  20000018 wmsr

Modified: cpu/x86/pc/olpc/lxmsrs.fth
===================================================================
--- cpu/x86/pc/olpc/lxmsrs.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/lxmsrs.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -1,5 +1,6 @@
 purpose: Table of MSR values to setup Geode LX processor on OLPC
 
+hex
 create lx-msr-init
 \ Memsize-dependent MSRs are set in the early startup code
 
@@ -15,16 +16,29 @@
   msr: 0000.1a00 00000000.00000001.  \ Imprecise exceptions
 
 \ northbridgeinit: GLIUS
+\ \ 1000.0020   0  80000  2  >p2d-bm  msr,
 \ msr: 1000.0020 20000000.000fff80.   \ 0 - 7.ffff low RAM Early startup
-\ msr: 1000.0024 000000ff.fff00000.   \ Unmapped - default
+
+\ 1000.0022  gp-pci-base  4000  a  >p2d-bm msr,  \ GP  - local to GLIU0
+\ 1000.0023  vp-pci-base  4000  4  >p2d-bm msr,  \ VP  - via GLIU1
+\ 1000.0024 vip-pci-base  4000  4  >p2d-bm msr,  \ VIP - via GLIU1
+\ 1000.0025 aes-pci-base  4000  4  >p2d-bm msr,  \ AES - via GLIU1
+
   msr: 1000.0022 a00000fe.000ffffc.   \ fe00.0000 - fe00.3fff GP
-  msr: 1000.0023 400000fe.008ffff8.   \ fe00.8000 - fe00.bfff VP + VIP in GLIU1
-  msr: 1000.0024 400000fe.010ffffc.   \ fe01.0000 - fe01.3fff security block in GLIU1
-\ msr: 1000.0025 000000ff.fff00000.   \ Unmapped - default
-\ msr: 1000.0026 000000ff.fff00000.   \ Unmapped - default
+  msr: 1000.0023 400000fe.008ffffc.   \ fe00.8000 - fe00.bfff VP in GLIU1
+  msr: 1000.0024 400000fe.00cffffc.   \ fe00.c000 - fe00.ffff VIP in GLIU1
+  msr: 1000.0025 400000fe.010ffffc.   \ fe01.0000 - fe01.3fff security block in GLIU1
 
+\ msr: 1000.0026 000000ff.fff00000.   \ BMO Unmapped - default (used for low mem in gxvga.fth)
+\ msr: 1000.0027 000000ff.fff00000.   \ BMO Unmapped - default (used for low mem in gxvga.fth)
+
+\ msr: 1000.0028 2000000e.fff00100.   \ Main memory from 1M to top, fbsize
+
 \ Graphics
+\ 1000.0029 fb-pci-base fb-size fb-offset  2  >p2d-range-offset  msr,  \ fd00.0000 - fdff.ffff mapped to f00.0000 Memsize dependent, fbsize dependent
 \ msr: 1000.0029 20a7e0fd.ffffd000.   \ fd00.0000 - fdff.ffff mapped to f00.0000 Memsize dependent, fbsize dependent
+
+\ 1000.002a dc-pci-base  4000 0  8  >p2d-range-offset  msr,
   msr: 1000.002a 801ffcfe.007fe004.   \ fe00.4000 - fe00.7fff mapped to 0 in DC space
 
 \ msr: 1000.002b 00000000.000fffff.   \ Unmapped - default
@@ -44,19 +58,34 @@
   msr: 1000.2004 00000000.00000005.   \ Clock gating
 
 \ DMA incoming maps
+\ 4000.0020  0 10.0000 2 >p2d-bm  msr, \ 0 - f.ffff low RAM, route to GLIU0
   msr: 4000.0020 20000000.000fff00.   \ 0 - f.ffff low RAM, route to GLIU0
+
+\ 4000.0022  gp-pci-base  4000  2  >p2d-bm msr,  \ GP, route to GLIU0
+\ 4000.0024  dc-pci-base  4000  2  >p2d-bm msr,  \ DC, route to GLIU0
+\ 4000.0025  vp-pci-base  4000  4  >p2d-bm msr,  \ VP, route to VP in GLIU1
+\ 4000.0026 vip-pci-base  4000  a  >p2d-bm msr,  \ VIP, route to VIP in GLIU1
+
   msr: 4000.0022 200000fe.000ffffc.   \ fe00.0000 - fe00.03ff GP, route to GLIU0
 \ msr: 4000.0023 000000ff.fff00000.   \ Unmapped - default
+
   msr: 4000.0024 200000fe.004ffffc.   \ fe00.4000 - fe00.7fff DC, route to GLIU0
   msr: 4000.0025 400000fe.008ffffc.   \ fe00.8000 - fe00.bfff VP, route to VP in GLIU1
   msr: 4000.0026 a00000fe.00cffffc.   \ fe00.c000 - fe00.ffff VIP, route to VIP in GLIU1
 \ msr: 4000.0027 000000ff.fff00000.   \ Unmapped - default
 \ msr: 4000.0028 000000ff.fff00000.   \ Unmapped - default
 \ msr: 4000.0029 000000ff.fff00000.   \ Unmapped - default
+
+\ 4000.002a fb-pci-base  fb-size 2 >p2d-range msr,  \ frame buffer - route to GLIU0, fbsize
+\ 4000.002b aes-pci-base    4000 c >p2d-range msr,  \ Security Block
+
   msr: 4000.002a 200000fd.ffffd000.   \ frame buffer - fd00.0000 .. fdff.ffff, route to GLIU0, fbsize
   msr: 4000.002b c00000fe.013fe010.   \ Security Block - fe01.0000 .. fe01.3fff
+
+\ 4000.002c 10.0000 fb-offset over -  2 >p2d-range msr,  \ 10.0000 - sysram-top - Memsize dependent
 \ msr: 4000.002c 20000007.7ff00100.   \ 10.0000 - 0f7f.ffff High RAM - Memsize dependent
 \ msr: 4000.002d 00000000.000fffff.   \ Unmapped - default
+
   msr: 4000.0080 00000000.00000001.   \ Route coherency snoops from GLIU1 to GLIU0
   msr: 4000.0081 00000000.0000c77f.   \ Port active enable
   msr: 4000.0082 80000000.00000000.   \ Arbitration scheduling
@@ -91,12 +120,21 @@
   msr: 0000.180d 00000000.00000000.  \ Cache e0000-fffff
 \ msr: 0000.180e 00000001.00000001.  \ SMM off - default
 \ msr: 0000.180f 00000001.00000001.  \ DMM off - default
+
+\ 0000.1810 fb-pci-base  fb-size 111 >rconf msr,  \ Video (write through), fbsize
+\ 0000.1811 gp-pci-base     4000 101 >rconf msr,  \ GP registers non-cacheable
+\ 0000.1812 dc-pci-base     4000 101 >rconf msr,  \ DC registers non-cacheable
+\ 0000.1813 vp-pci-base     4000 101 >rconf msr,  \ VP registers non-cacheable
+\ 0000.1814 vip-pci-base    4000 101 >rconf msr,  \ VIP registers non-cacheable
+\ 0000.1815 aes-pci-base    4000 101 >rconf msr,  \ AES registers non-cacheable
+
   msr: 0000.1810 fdfff000.fd000111.  \ Video (write through), fbsize
-  msr: 0000.1811 fe013000.fe000101.  \ GP + DC + VP + VIP + AES registers non-cacheable
-\ msr: 0000.1812 00000000.00000000.  \ Disabled - default
-\ msr: 0000.1813 00000000.00000000.  \ Disabled - default
-\ msr: 0000.1814 00000000.00000000.  \ Disabled - default
-\ msr: 0000.1815 00000000.00000000.  \ Disabled - default
+  msr: 0000.1811 fe003000.fe000101.  \ GP registers non-cacheable
+  msr: 0000.1812 fe007000.fe004101.  \ DC registers non-cacheable
+  msr: 0000.1813 fe00b000.fe008101.  \ VP registers non-cacheable
+  msr: 0000.1814 fe00f000.fe00c101.  \ VIP registers non-cacheable
+  msr: 0000.1815 fe013000.fe010101.  \ AES registers non-cacheable
+
 \ msr: 0000.1816 00000000.00000000.  \ Disabled - default
 \ msr: 0000.1817 00000000.00000000.  \ Disabled - default
 
@@ -136,17 +174,17 @@
 \ chipsetinit(nb);
 
 \ Set the prefetch policy for various devices
-  msr: 5150.0001 00000000.00008f000.   \ AC97
-  msr: 5140.0001 00000000.00000f000.   \ DIVIL
+  msr: 5150.0001 00000000.0008f000.   \ AC97
+  msr: 5140.0001 00000000.0000f000.   \ DIVIL
 
 \  Set up Hardware Clock Gating
-  msr: 5102.4004 00000000.000000004.  \ GLIU_SB_GLD_MSR_PM
-  msr: 5100.0004 00000000.000000005.  \ GLPCI_SB_GLD_MSR_PM
-  msr: 5170.0004 00000000.000000004.  \ GLCP_SB_GLD_MSR_PM
+  msr: 5102.4004 00000000.00000004.  \ GLIU_SB_GLD_MSR_PM
+  msr: 5100.0004 00000000.00000005.  \ GLPCI_SB_GLD_MSR_PM
+  msr: 5170.0004 00000000.00000004.  \ GLCP_SB_GLD_MSR_PM
 \ SMBus clock gating errata (PBZ 2226 & SiBZ 3977)
-  msr: 5140.0004 00000000.050554111.  \ DIVIL
-  msr: 5130.0004 00000000.000000005.  \ ATA
-  msr: 5150.0004 00000000.000000005.  \ AC97
+  msr: 5140.0004 00000000.50554111.  \ DIVIL
+  msr: 5130.0004 00000000.00000005.  \ ATA
+  msr: 5150.0004 00000000.00000005.  \ AC97
 
 \ setup_gx2();
 
@@ -189,21 +227,36 @@
   msr: 5101.0002 0000000f.0000000f.  \ Disable SMIs
 
 \ msr: 5100.0010 44000020.00020013.  \ PCI timings - already set
-  msr: 5100.0020 018b4001.018b0001.  \ Region configs
+
+\ XXX convert to >rconf form - need an IO version
+\  msr: 5100.0020 018b4001.018b0001.  \ Region configs
+  msr: 5100.0020 06004001.06000001.  \ Region configs
   msr: 5100.0021 010fc001.01000001.  \ GPIO
   msr: 5100.0022 0183c001.01800001.  \ MFGPT
   msr: 5100.0023 0189c001.01880001.  \ IRQ mapper
   msr: 5100.0024 0147c001.01400001.  \ PMS
   msr: 5100.0025 0187c001.01840001.  \ ACPI
   msr: 5100.0026 014fc001.01480001.  \ AC97 128 bytes (0x80)
+
+\ 5100.0027 ohci-pci-base  1000  1 >rconf msr,  \ OHCI
+\ 5100.0028 ehci-pci-base  1000  1 >rconf msr,  \ EHCI
+\ 5100.0029 uoc-pci-base   1000  1 >rconf msr,  \ UOC
+
   msr: 5100.0027 fe01a000.fe01a001.  \ OHCI
   msr: 5100.0028 fe01b000.fe01b001.  \ EHCI
   msr: 5100.0029 efc00000.efc00001.  \ UOC
+
   msr: 5100.002b 018ac001.018a0001.  \ IDE bus master
   msr: 5100.002f 00084001.00084009.  \ Port 84 (what??)
+
+\ 5101.0020 uoc-pci-base   1000 4 >p2d-bm msr,  \ P2D_BM0 UOC
+\ 5101.0023 ohci-pci-base  1000 5 >p2d-bm msr,  \ P2D_BMK OHCI
+\ 5101.0024 ehci-pci-base  1000 4 >p2d-bm msr,  \ P2D_BMK EHCI
+
   msr: 5101.0020 400000ef.c00fffff.  \ P2D_BM0 UOC
   msr: 5101.0023 500000fe.01afffff.  \ P2D_BMK Descriptor 0 OHCI
   msr: 5101.0024 400000fe.01bfffff.  \ P2D_BMK Descriptor 1 EHCI
+
   msr: 5101.0083 00000000.0000ff00.  \ Disable SMIs
   msr: 5101.00e0 60000000.1f0ffff8.  \ IOD_BM Descriptor 0 ATA IO address
   msr: 5101.00e1 a0000001.480fff80.  \ IOD_BM Descriptor 1 AC97
@@ -216,6 +269,7 @@
   msr: 5140.0002 0000fbff.00000000.  \ Disable SMIs
 
   msr: 5140.0008 0000f001.00001880.  \ LBAR_IRQ
+\ 5140.0009 ohci-pci-base 1000 1 >usb-kel msr,  \ LBAR_KEL (USB)
   msr: 5140.0009 fffff001.fe01a000.  \ LBAR_KEL (USB)
   msr: 5140.000b     f001.000018b0.  \ LBAR_SMB
   msr: 5140.000c     f001.00001000.  \ LBAR_GPIO
@@ -246,7 +300,13 @@
   msr: 5140.0057 00000000.00000032.  \ RTC century (offset into CMOS RAM)
 
 \ USB host controller
+
   msr: 5120.0001 0000000b.00000000.  \ USB_GLD_MSR_CONFIG - 5536 page 262
+
+\ 5120.0008 ohci-pci-base  e msr,    \ USB OHC Base Address - 5536 page 266
+\ 5120.0009 ehci-pci-base  e msr,    \ USB EHC Base Address - 5536 page 266 FLADJ set
+\ 5120.000b uoc-pci-base   2 msr,    \ USB UOC Base Address - 5536 page 266
+
   msr: 5120.0008 0000000e.fe01a000.  \ USB OHC Base Address - 5536 page 266
   msr: 5120.0009 0000200e.fe01b000.  \ USB EHC Base Address - 5536 page 266 FLADJ set
   msr: 5120.000b 00000002.efc00000.  \ USB UOC Base Address - 5536 page 266

Modified: cpu/x86/pc/olpc/mfgdata.fth
===================================================================
--- cpu/x86/pc/olpc/mfgdata.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/mfgdata.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -64,6 +64,14 @@
    r> 2drop false
 ;
 
+\ Remove bogus null characters from the end of mfg data tags (old machines
+\ have malformed tags)
+: ?-null  ( adr len -- adr' len' )
+   dup  if
+      2dup + 1- c@  0=  if  1-  then        ( adr len' )
+   then
+;
+
 : ?erased  ( adr len -- )
    bounds  ?do  i c@  h# ff <> abort" Not erased"  loop
 ;

Modified: cpu/x86/pc/olpc/olpc.bth
===================================================================
--- cpu/x86/pc/olpc/olpc.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/olpc.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -3,7 +3,7 @@
 command: &builder &this
 in: ${BP}/cpu/x86/pc/olpc/build/ec.img
 in: ${BP}/cpu/x86/pc/olpc/build/romreset.di
-in: ${BP}/cpu/x86/pc/olpc/build/romstart.di
+\ in: ${BP}/cpu/x86/pc/olpc/build/romstart.di
 in: ${BP}/cpu/x86/pc/olpc/build/resume.di
 in: ${BP}/cpu/x86/pc/olpc/build/rmstart.img
 in: ${BP}/cpu/x86/pc/olpc/build/paging.di
@@ -79,6 +79,8 @@
 [ifdef] lx-devel
    " ${BP}/dev/pci/build/pcibridg.fc"           " class060400"     $add-deflated-dropin
 [then]
+   " ${BP}/cpu/x86/pc/olpc/build/dsdt.aml"      " dsdt"            $add-deflated-dropin
+   " ${BP}/cpu/x86/pc/olpc/build/ssdt.aml"      " ssdt"            $add-deflated-dropin
 
    /rom h# 400 - pad-file	\ rmstart image must start 0x400 from end
    " rmstart.img"    $add-file

Modified: cpu/x86/pc/olpc/probemem.fth
===================================================================
--- cpu/x86/pc/olpc/probemem.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/probemem.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -1,37 +1,52 @@
 \ See license at end of file
 purpose: Create memory node properties and lists
 
-dev /memory
+\ All RAM, including that assigned to the frame buffer
+: total-ram  ( -- ramsize )
+   h# 20000018 msr@ nip         ( msr.hi )
+   dup d# 12 rshift  h# f and   ( msr.hi dimm0size-code )
+   d# 22 + 1 swap lshift        ( msr.hi dimm0size )
+   swap  dup h# f0000 and  h#  70000 =  if  ( dimm0size msr.hi )
+      \ DIMM1 Not Installed
+      drop                      ( total-size )
+   else                         ( dimm0size msr.hi )
+      d# 28 rshift  h# f and    ( dimm0size dimm1size-code )
+      d# 22 + 1 swap lshift     ( dimm0size dimm1size )
+      +                         ( total-size )
+   then
+;
 
-h# f70.0000 constant /ram   \ 256 MB
+\ Offset of frame buffer/display memory within the memory array
+: fb-offset  ( -- offset )  h# 1808 msr@ drop h# 0fffff00 and  4 lshift  ;
 
-: release-range  ( start-adr end-adr -- )  over - release  ;
-
-: ram-limit  ( -- addr )  mem-info-pa la1+ l@  ;
-
-: ram-range  ( -- extant avail )
+\ Excludes RAM assigned to the frame buffer
+: system-ram  ( -- extant avail )
 [ifdef] lx-devel
-   h# 1000.0000  h# f70.0000 exit
+   h# f70.0000 exit
 [then]
-   gpio-data@ 4 and  if
-      h#  800.0000  h# 770.0000
-   else
-      h# 1000.0000  h# f70.0000
-   then
+   fb-offset
 ;
 
+\ This may require adjustment if we steal additional SMI memory
+: fbsize  ( -- )  total-ram system-ram -  ;
+
+dev /memory
+
+\ Excludes RAM already used for page tables
+: ram-limit  ( -- addr )  mem-info-pa la1+ l@  ;
+
+: release-range  ( start-adr end-adr -- )  over - release  ;
+
 : probe  ( -- )
-   ram-range to /ram    ( total-ram )
+   0 total-ram  reg   \ Report extant memory
 
-   0 swap  reg   \ Report extant memory
-
    \ Put h# 10.0000-1f.ffff and 28.0000-memsize in pool,
    \ reserving 0..10.0000 for the firmware
    \ and 20.0000-27.ffff for the "flash"
 
 \   h#  0.0000  h# 02.0000  release   \ A little bit of DMA space, we hope
 \   h# 10.0000  h# 0f.ffff  release
-\   h# 28.0000  h# 80.0000 h# 28.0000 -  release
+\   h# 28.0000  h# 80.0000  release-range
 
 \ Release some of the first meg, between the page tables and the DOS hole,
 \ for use as DMA memory.
@@ -41,30 +56,22 @@
    \ Release from 1M up to the amount of unallocated (so far) memory
    dropin-base ram-limit u<   if
       \ Except for the area that contains the dropins, if they are in RAM
-      h# 10.0000  dropin-base over -  release
-      dropin-base dropin-size +  ram-limit  over -  release
+      h# 10.0000  dropin-base  release-range
+      dropin-base dropin-size +  ram-limit  release-range
    else
-      h# 10.0000  ram-limit  over -  release
+      h# 10.0000  ram-limit  release-range
    then
 [else]
-   h# 10.0000                             ( free-bot )
-   fw-pa                                  ( free-bot free-top )
+   h# 10.0000  system-ram  release-range
 
-   \ Account for the dropin area if it is in RAM
-   dropin-base  /ram  u<  if              ( free-bot free-top )
-      dropin-base umin                    ( free-bot free-top' )
-   then                                   ( free-bot free-top )
+   fw-pa /fw-ram 0 claim  drop
 
-   over -  release
-
-   fw-pa /fw-ram +                        ( piece2-base )
-
    \ Account for the dropin area if it is in RAM
-   dropin-base  /ram u<  if               ( piece2-base )
-      dropin-base dropin-size +  umax     ( piece2-base' )
-   then                                   ( piece2-base )
+   dropin-base  system-ram  u<  if
+      dropin-base dropin-size 0 claim
+   then
 
-   /ram  over -  release
+   initial-heap  swap >physical swap  0 claim  drop
 [then]
 ;
 

Modified: cpu/x86/pc/olpc/reset.bth
===================================================================
--- cpu/x86/pc/olpc/reset.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/reset.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -21,7 +21,6 @@
 h#  30.0000 constant workspace
 
 start-assembling
-protected-mode
 
 label my-entry
    e9 c,  0 ,				\ To be patched later

Modified: cpu/x86/pc/olpc/resume.bth
===================================================================
--- cpu/x86/pc/olpc/resume.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/resume.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -25,14 +25,6 @@
 \ create restore-usb-power
 \ create checksum-test
 
-h# fe00.0000 constant gp-pa
-h# fe00.4000 constant dc-pa
-h# fe00.8000 constant vp-pa
-h# fe01.a000 constant ohci-pa
-h# fe01.b000 constant ehci-pa
-h# efc0.0000 constant uoc-pa
-h#      1000 constant gpio-port
-
 : resume-progress  ( byte -- )
    " h# 34 # al mov   al h# 70 # out  ( byte ) # al mov  al h# 71 # out" eval
 ;
@@ -124,7 +116,9 @@
    \ We do this in top-down order to configure the AUX select
    \ registers before setting the output enables and values.
 
-   gpio-port h# 38 + #  dx  mov  \ Low bank - first contiguous GPIO register
+   h# 5140.000c rmsr  ax bx mov
+
+   h# 38 [bx]  dx  lea   \ Low bank - first contiguous GPIO register
    h# 3c /l / #  cx  mov  \ Register count (stop at lock register)
    begin
       dx  ax   in   \ Read GPIO control register
@@ -132,11 +126,13 @@
       4 #  dx  sub  \ Next port address
    loopa
 
-   gpio-port h# 40 + # dx mov  dx ax in  ax stos  \ Pos edge enable
-   gpio-port h# 44 + # dx mov  dx ax in  ax stos  \ Neg edge enable
-   gpio-port h# 3c + # dx mov  dx ax in  ax stos  \ Low bank lock
+   h# 40 [bx] dx lea  dx ax in  ax stos  \ Pos edge enable
+   h# 44 [bx] dx lea  dx ax in  ax stos  \ Neg edge enable
+   h# 3c [bx] dx lea  dx ax in  ax stos  \ Low bank lock
 
-   gpio-port h# b8 + #  dx  mov  \ High bank - first contiguous GPIO register
+[ifndef] omit-high-gpio-restore
+   \ This is probably unnecessary, as these registers may be in the suspend well
+   h# b8 [bx] dx lea  \ High bank - first contiguous GPIO register
    h# 3c /l / #  cx  mov  \ Register count (stop at lock register)
    begin
       ax   dx  in   \ Read GPIO control register
@@ -144,26 +140,27 @@
       4 #  dx  sub  \ Next port address
    loopa
 
-   gpio-port h# c0 + # dx mov  dx ax in  ax stos  \ Pos edge enable
-   gpio-port h# c4 + # dx mov  dx ax in  ax stos  \ Neg edge enable
-   gpio-port h# bc + # dx mov  dx ax in  ax stos  \ High bank lock
+   h# c0 [bx] dx lea  dx ax in  ax stos  \ Pos edge enable
+   h# c4 [bx] dx lea  dx ax in  ax stos  \ Neg edge enable
+   h# bc [bx] dx lea  dx ax in  ax stos  \ High bank lock
+[then]
 
    \ Switch the THRM_ALARM# pin to GPIO during suspend, so it doesn't trigger falsely.
    \ THRM_ALARM# is in the standby power well
-   h# 0400.0000 # ax mov  gpio-port h# 34 + # dx mov  ax dx out  \ GPIO, not THRM_ALARM#
+   h# 0400.0000 # ax mov  h# 34 [bx] dx lea  ax dx out  \ GPIO, not THRM_ALARM#
 
 [ifdef] save-display
 \ \ h# 3c 0  do  i gp@ l!+  4 +loop  h# 4c gp@ l!+
-\  h# f # cx mov  gp-pa set-base  begin  0 [bx] ax mov  ax stos  4 # bx add  loopa
-\  gp-pa h# 4c + #) ax mov  ax stos
+\  h# f # cx mov  gp-pci-base set-base  begin  0 [bx] ax mov  ax stos  4 # bx add  loopa
+\  gp-pci-base h# 4c + #) ax mov  ax stos
 
-   vp-pa set-base
+   vp-pci-base set-base
    h# 400 reg-save  h# 408 reg-save  h# 418 reg-save
    h#   8 reg-save
    0 # h# 38 [bx] mov  h# 100 # cx mov  begin  h# 40 reg-save  loopa  \ Gamma
    h# 410 reg-save
 
-   dc-pa set-base
+   dc-pci-base set-base
    h# 10 reg-save  h# 14 reg-save  h# 18 reg-save  h# 1c reg-save
 
    h# 20 reg-save  h# 24 reg-save  h# 28 reg-save
@@ -213,7 +210,8 @@
    h# 5140.0037 rmsr  al stos  \ PIT Count Enable MSR
 
    \ SMBUS controller
-   h# 18b3 # dx mov  \ SMBUS base port
+   
+   h# 5140.000b rmsr  3 [ax] dx lea \ SMBUS reg 3
            dx al in   al stos   \ Reg 3
    dx inc  dx al in   al stos   \ Reg 4
    dx inc  dx al in   al bl mov  h# fe # al and  al stos   \ Reg 5 w/o enable bit
@@ -271,8 +269,8 @@
 [then]
 
    \ Stop video refresh
-   h# 4758 #  h# fe00.4000 #)  mov  \ Unlock DC registers
-   h#    0 #  h# fe00.4004 #)  mov  \ Turn off access to display memory
+   h# 4758 #  dc-pci-base     #)  mov  \ Unlock DC registers
+   h#    0 #  dc-pci-base 4 + #)  mov  \ Turn off access to display memory
 
    h# 4000.0e00 h# 1410 port-wl   \ Assert SLP_CLK_EN# 1 mS after SUSPA#
 \  This is pointless because register 14 is in the working power domain
@@ -333,7 +331,7 @@
 \   Running from a 32-bit identity-mapped code segment
 \   Using physical addresses
 
-\ char < 3f8 port-wb  begin  3fd port-rb 20 bitand  0<> until
+ char < 3f8 port-wb  begin  3fd port-rb 20 bitand  0<> until
 
    resume-data #  bp  mov
 
@@ -379,13 +377,14 @@
 [ifdef] reset-smbus-bitbang
    \ GPIO15 is SMB_DATA
    \ GPIO14 is SMB_CLOCK
+   h# 5140.000c rmsr  ax bx  mov
    h#     c000 # ax mov         \ Mask to set SMB_DATA and SMB_CLOCK
-   h# 1000 # dx mov  ax dx out  \ Set output values to high
-   h# 1004 # dx mov  ax dx out  \ Set pins to output
+   h# 00 [bx] dx lea  ax dx out  \ Set output values to high
+   h# 04 [bx] dx lea  ax dx out  \ Set pins to output
    h# c0000000 # ax mov         \ Mask to clear SMB_DATA and SMB_CLOCK
-   h# 1010 # dx mov  ax dx out  \ Deselect OUT AUX1
-   h# 1014 # dx mov  ax dx out  \ Deselect OUT AUX2
-   h# 1034 # dx mov  ax dx out  \ Deselect IN AUX1
+   h# 10 [bx] dx lea  ax dx out  \ Deselect OUT AUX1
+   h# 14 [bx] dx lea  ax dx out  \ Deselect OUT AUX2
+   h# 34 [bx] dx lea  ax dx out  \ Deselect IN AUX1
 
    d# 16 # cx mov  \ Generate 8 low pulses on SMB_CLOCK
    begin
@@ -393,15 +392,19 @@
       rdtsc  ax bx mov  d# 5 d# 500 * #  bx  add
       begin  rdtsc  bx ax sub  0>= until
 
-      h# 1000 # dx mov             \ Output value register
+      cx bx mov                          \ Save cx for use by rmsr
+      h# 5140.000c rmsr  ax dx  mov      \ GPIO output register
       h# 40000000 # ax mov  ax dx out    \ Clear SMB_CLOCK
+      bx cx mov                          \ Restore cx
 
       \ 5 uS delay (slightly longer for GX)
       rdtsc  ax bx mov  d# 5 d# 500 * #  bx  add
       begin  rdtsc  bx ax sub  0>= until
 
-      h# 1000 # dx mov             \ Output value register
+      cx bx mov                          \ Save cx for use by rmsr
+      h# 5140.000c rmsr  ax dx  mov      \ GPIO output register
       h#     4000 # ax mov  ax dx out    \ Set SMB_CLOCK
+      bx cx mov                          \ Restore cx
    loopa
 
    \ 5 uS delay (slightly longer for GX)
@@ -411,7 +414,8 @@
 
    h# 23 resume-progress
 
-   h# 1038 #     dx  mov  \ Low bank - first contiguous GPIO register
+   h# 5140.000c rmsr  ax bx mov
+   h# 38 [bx]  dx  lea   \ Low bank - first contiguous GPIO register
    h# 3c /l / #  cx  mov  \ Register count (stop at lock register)
    begin
       ax lods
@@ -421,14 +425,16 @@
 
    \ Clear edge detects for GPIO pins that are not powered during suspend
    h# ffff # ax mov
-   h# 1048 # dx mov  ax dx out  \ Pos edge status
-   h# 104c # dx mov  ax dx out  \ Neg edge status
+   h# 48 [bx] dx lea  ax dx out  \ Pos edge status
+   h# 4c [bx] dx lea  ax dx out  \ Neg edge status
 
-   ax lods  h# 1040 # dx mov  ax dx out  \ Pos edge enable
-   ax lods  h# 1044 # dx mov  ax dx out  \ Neg edge enable
-   ax lods  h# 103c # dx mov  ax dx out  \ Low bank lock
+   ax lods  h# 40 [bx] dx lea  ax dx out  \ Pos edge enable
+   ax lods  h# 44 [bx] dx lea  ax dx out  \ Neg edge enable
+   ax lods  h# 3c [bx] dx lea  ax dx out  \ Low bank lock
 
-   h# 10b8 #     dx  mov  \ High bank - first contiguous GPIO register
+[ifndef] omit-high-gpio-restore
+   \ This is probably unnecessary, as these registers may be in the suspend well
+   h# b8 [bx]    dx  lea  \ High bank - first contiguous GPIO register
    h# 3c /l / #  cx  mov  \ Register count (stop at lock register)
    begin
       ax lods
@@ -439,27 +445,28 @@
    \ Clear edge detects for GPIO pins that are not powered during suspend
    \ GPIOs 28:24 are in the suspend power well.  GPIOs 31:29 don't exist.
    h# e0ff # ax mov
-   h# 10c8 # dx mov  ax dx out  \ Pos edge status
-   h# 10cc # dx mov  ax dx out  \ Neg edge status
+   h# c8 [bx] dx lea  ax dx out  \ Pos edge status
+   h# cc [bx] dx lea  ax dx out  \ Neg edge status
 
-   ax lods  h# 10c0 # dx mov  ax dx out  \ Pos edge enable
-   ax lods  h# 10c4 # dx mov  ax dx out  \ Neg edge enable
-   ax lods  h# 10bc # dx mov  ax dx out  \ High bank lock
+   ax lods  h# c0 [bx] dx lea  ax dx out  \ Pos edge enable
+   ax lods  h# c4 [bx] dx lea  ax dx out  \ Neg edge enable
+   ax lods  h# bc [bx] dx lea  ax dx out  \ High bank lock
+[then]
 
    h# 24 resume-progress
 
 [ifdef] save-display
 
 \ \ h# 3c 0  do  l at + i gp!  4 +loop   l at + h# 4c gp! 
-\  h# f # cx mov   gp-pa set-base  begin  ax lods  ax 0 [bx] mov  4 # bx add  loopa
-\  ax lods  ax  gp-pa h# 4c + #)  mov
+\  h# f # cx mov   gp-pci-base set-base  begin  ax lods  ax 0 [bx] mov  4 # bx add  loopa
+\  ax lods  ax  gp-pci-base h# 4c + #)  mov
 
 \ Synchronize the flat panel turn-on with the DCON blanking
 \   d# 50,000 # cx mov  \ 50K spins is about 40 mS
 \   h# 1030 # dx mov  \ GPIO data port
 \   begin  dx ax in  h# 1000 # ax test  loope  \ Wait for blanking
 
-   vp-pa set-base
+   vp-pci-base set-base
    0 #  h# 50 [bx] mov  \ Power on for DACs, enable gamma correction 
    h# 400 reg-restore
    h# 408 reg-restore
@@ -470,7 +477,7 @@
 
 \   d# 1,000,000 # cx mov  begin  h# 410 [bx] ax mov  1 # al test  loope  \ Panel power up
 
-   dc-pa set-base
+   dc-pci-base set-base
    
    h# 4758 #  0 [bx]  mov  \ Unlock
    h# 10 reg-restore   h# 14 reg-restore   h# 18 reg-restore   h# 1c reg-restore
@@ -485,25 +492,26 @@
 
 \ Synchronize the VGA turn-on with the DCON blanking
    d# 50,000 # cx mov  \ 50K spins is about 40 mS
-   h# 1030 # dx mov  \ GPIO data port
+   h# 5140.000c rmsr  h# 30 [ax] dx lea       \ GPIO data port
    begin  dx ax in  h# 1000 # ax test  loope  \ Wait for blanking
 
    h#  8 reg-restore   h#  4 reg-restore
 
-   0 #  dc-pa #)  mov  \ Lock
+   0 #  dc-pci-base #)  mov  \ Lock
 
 \   d# 100,000 # cx mov  begin  h# 80 #  ax in  loopa  \ Delay about 100 ms
 
    d# 80,000 # cx mov  begin  h# 80 # a in  loopa  \ Wait for panel power up
 
    \ Unfreeze image by setting the DCONLOAD bit (0x800) in the GPIO output register
-   h# 0800 h# 1000 port-wl
+   h# 5140.000c rmsr  ax dx mov   \ GPIO output register
+   h# 0800 # ax mov   ax dx out
 [else]
    \ Turn on the flat panel power as soon as possible
    \ The 400.0000 bit make the panel power-up timers use the 14 MHz clock
    \ instead of the 32 kHz clock.  That is supposed to be only for simulation,
    \ but we have DCON between the CPU and the panel, so we don't need delays.
-   h# 500.0000 #  vp-pa h# 410 + #)  mov
+   h# 500.0000 #  vp-pci-base h# 410 + #)  mov
 [then]
 
    h# 25 resume-progress
@@ -555,7 +563,7 @@
    h# 27 resume-progress
 
    \ SMBUS controller
-   h# 18b3 # dx mov  \ SMBUS base port
+   h# 5140.000b rmsr  3 [ax] dx lea  \ SMBUS reg 3
    al lods          al dx out  \ Reg 3
    al lods  dx inc  al dx out  \ Reg 4
    al lods  dx inc  al dx out  \ Reg 5 without the enable bit
@@ -564,8 +572,9 @@
 
 [ifdef] reset-smbus
    \ This little dance resets the DCON's SMbus interface
-   h#    1 # al mov  \ START
-   h# 18b3 # dx mov  \ SMBUS control 1
+   \ We start with dx pointing to SMBUS reg 5
+   dx dec  dx dec    \ Point back to smbus reg3 (control 1)
+   h# 1 #  al mov    \ START
    al dx out         \ Initiate an SMBUS cycle to the DCON
 
    \ We could split here and move the following down, so as to overlap
@@ -573,30 +582,30 @@
    \ later CaFe chip setup will stall anyway.
 
    d#   32 # cx mov  \ Loop count (usually ready in 20 uS)
-   h# 18b1 # dx mov  \ SMBUS status
+   dx dec  dx dec    \ SMBUS reg1 (status)
    begin
       dx al in
       h# 40 # al test
    loope             \ Wait for ready to accept byte or timeout
 
    h#   1a # al mov  \ Address byte
-   h# 18b0 # dx mov  \ SMBUS data   
+   dx dec            \ SMBUS reg0 (data)
    al dx out         \ Initiate address out cycle
 
    \ Another possible split point, in case we should need to overlap
    d#  256 # cx mov  \ Loop count (usually ready in 172 uS)
-   h# 18b1 # dx mov  \ SMBUS status
+   dx inc            \ SMBUS reg1 (status)
    begin
       dx al in
       h# 50 # al test
    loope             \ Wait for done or error or timeout
 
    h#    2 # al mov  \ Stop
-   h# 18b3 # dx mov  \ SMBUS status
+   dx inc  dx inc    \ SMBUS reg3 (control 1)
    al dx out         \ Initiate STOP
 
    h#   10 # al mov  \ Ack NEGACK
-   h# 18b1 # dx mov  \ SMBUS status
+   dx dec  dx dec    \ SMBUS reg1 (status)
    al dx out         \ While acking the NEGACK
    \ End of DCON SMbus reset dance
 [then]
@@ -619,11 +628,11 @@
    \ h# 8000 h# 4000.0000 or h# 1440 pl!  \ Fail-safe delay
 
    \ USB Power-to-Port assignment
-   h# 3ab #  uoc-pa     #) mov
-   h#   2 #  uoc-pa 4 + #) mov
+   h# 3ab #  uoc-pci-base     #) mov
+   h#   2 #  uoc-pci-base 4 + #) mov
 
 [ifdef] restore-usb-power
-   ohci-pa set-base
+   ohci-pci-base set-base
    h#       1 #  h# 08 [bx]  mov  \ HcCommandStatus register - Reset host controller
    h# 1e.0000 #  h# 4c [bx]  mov  \ HcRhDescriptorB register - Individual port power
    h#     100 #  h# 58 [bx]  mov  \ HcRhPortStatus[2] register - Power on
@@ -655,7 +664,7 @@
    h# 6204 config-setup  ax lods  op: ax dx out    \ Camera enables
 
 [ifdef] restore-usb-power
-   ohci-pa set-base
+   ohci-pci-base set-base
    \ Do this after the CaFe setup to stagger the power-on.  The staggering
    \ might not be necessary for B3 and later.
    h#     100 #  h# 54 [bx]  mov  \ HcRhPortStatus[1] register - Power on
@@ -668,16 +677,16 @@
    h# 2b resume-progress
 
    \ Display stuff
-   h# 4758 #  h# fe00.4000 #)  mov  \ Unlock display controller registers
+   h# 4758 #  dc-pci-base #)  mov  \ Unlock display controller registers
 
    h# 1808 rmsr              \ Get default region config register - low in ax
    d#  8 # ax shr            \ Discard region type bits
    d# 12 # ax shl            \ Convert page number to address
-   ax  h# fe00.4088 #)  mov  \ DV_CTL register - sets framebuffer phys base
+   ax  dc-pci-base h# 88 + #)  mov  \ DV_CTL register - sets framebuffer mem offset
 
-   h# fd00.0000 #  h# fe00.4084 #)  mov   \ GLIU0 Memory offset
-   h# fd00.0000 #  h# fe00.004c #)  mov   \ GP base
-   h# fd80.0000 #  h# fe00.8460 #)  mov   \ Flat panel base
+   fb-pci-base #  dc-pci-base h#  84 + #)  mov   \ GLIU0 Memory offset
+   fb-pci-base #  gp-pci-base h#  4c + #)  mov   \ GP base
+   fb-pci-base h# 80.0000 + #  vp-pci-base h# 460 + #)  mov   \ Flat panel base (GX only)
 
    \ There is a lot of other stuff that must be done to turn on the
    \ video - but we will let the gx driver take care of that.
@@ -721,7 +730,7 @@
 
    \ Identity mapping of low memory might not exist now
 
-\  char > 3f8 port-wb  begin  3fd port-rb 20 bitand  0<> until
+  char > 3f8 port-wb  begin  3fd port-rb 20 bitand  0<> until
 
    gs pop
 

Modified: cpu/x86/pc/olpc/rmstart.fth
===================================================================
--- cpu/x86/pc/olpc/rmstart.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/rmstart.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -33,7 +33,6 @@
 hex
 
 start-assembling
-protected-mode
 hex
 
 \ Addresses where the following items will be located in the processor's
@@ -124,7 +123,7 @@
    here		\ Mark the beginning of this code so its size may be determined
 		\ and so that a jump to it may be assembled later.
 
-   real-mode
+   16-bit
 
    h# 01 # al mov  al h# 80 # out
 
@@ -298,8 +297,6 @@
 
    op: ad: ResetBase h# 10 #)  far jmp	\ Jump to Forth startup
 
-   real-mode
-
    \ Pad the startup code so that the main entry point ends up at the
    \ correct address.
 
@@ -320,6 +317,8 @@
    \ ffff.fff0 - This is the hardwired address where the processor jumps
    \             when it comes out of reset
 
+   16-bit
+
    cli cld		\ Turn off interrupts (does not affect NMI)
    #) jmp		\ Relative jump back to ffff.fc28
    0 w, 0 c,		\ align "pad" to end of ROM

Modified: cpu/x86/pc/olpc/romreset.bth
===================================================================
--- cpu/x86/pc/olpc/romreset.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/romreset.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -37,7 +37,6 @@
 
 
 start-assembling
-protected-mode
 
 label my-entry
    e9 c,  0 ,				\ To be patched later
@@ -54,296 +53,25 @@
 
    h# 1430 # dx mov  dx ax in  h# 9999 # ax cmp  =  if
       h# 34 #  al mov    al  h# 70 #  out   \ Write to CMOS 0x34
-      h# 10 #  al mov    al  h# 71 #  out   \ Write value 01
+      h# 10 #  al mov    al  h# 71 #  out   \ Write value 0x10
    then
 
- long-offsets on
- h# 4c000017 rmsr  h# 10 bitand  0<>  if   \ LX branch
+   long-offsets on
+   h# 4c000017 rmsr  h# 10 bitand  0<>  if   \ LX branch
 
-   \ The next few MSRs allow us to access the 5536
-   \ EXTMSR - page 449   \ Use PCI device #F for port 2
-   00000000.00000f00.   5000201e set-msr  \ cs5536_setup_extmsr(void)
+fload ${BP}/cpu/x86/pc/olpc/lxearly.fth
 
-   \ write IDSEL to the write once register at address 0x0000
-   \ 02000000 0 port-wl  \ This is the default value so we need not set it
+   else  \ GX branch
 
-   \ setup CPU interface serial to mode C on both sides
-   44000020.00200013. 51000010 set-msr   \ 5536 p 229
+fload ${BP}/cpu/x86/pc/olpc/gxearly.fth
 
-   \ Set up GPIO base register
-   0000f001.00001000.   5140000c set-msr  \ GPIO BAR
-
- \ Init UART
-[ifndef] lx-devel
-1 [if]
- 1 [if]
-   \ Set the UART TX line high - this prevents a low-going glitch that
-   \ the receiver interprets as a character.
-   100.0000 1010 port-wl   \ Output AUX1 select - UART TX as GPIO for now
-        100 1000 port-wl   \ high
-        100 1004 port-wl   \ GPIO1 - output enable
- [then]
-
-   \ The UART init sequence takes 550 uS running from ROM
- [ifdef] use-uart2
-   \ cs5536_setup_onchipuart,cs5536_early_setup.c:205.14
-   0.00000012.   5140003e set-msr  \ enable UART2
-
-   \ GPIO1 - UART2 TX
-   10 1004 port-wl   \ GPIO4 - output enable - UART2 TX
-   10 1010 port-wl   \ Output AUX1 select - UART2 TX
-    8 1020 port-wl   \ Input enable UART2 RX
-    8 1034 port-wl   \ Input AUX1 select - UART2 RX
-   0.8070.0003  51400014 set-msr  \ MDD_LEG_IO  UART2 at COM1 address
- [else]
-   \ cs5536_setup_onchipuart,cs5536_early_setup.c:205.14
-   0.00000012.   5140003a set-msr  \ enable COM1
-
-   \ GPIO1 - UART1 TX
-   100 1004 port-wl   \ GPIO1 - output enable
-   100 1010 port-wl   \ Output AUX1 select - UART TX
-   200 1020 port-wl   \ Input enable UART RX
-   200 1034 port-wl   \ Input AUX1 select - UART RX
-   0.8007.0003.  51400014 set-msr  \ MDD_LEG_IO  legacy IO
- [then]
-
-   \ uart_init,serial.c
-   \ This is a garden-variety 8250 UART setup sequence
-    0 3f9 port-wb
-    1 3fa port-wb
-   83 3fb port-wb  \ DLAB
-    1 3f8 port-wb  \ 115200 divisor low
-    0 3f9 port-wb  \ 115200 divisor high
-    3 3fb port-wb  \ !DLAB
-   \ At this point we could send characters out the serial port
-   \ End of serial init
-
-   char + 3f8 port-wb  begin  3fd port-rb 40 bitand  0<> until
-[then]
-[then]  \ lx-devel
-
-   h# 11 # al mov  al h# 80 # out
-   h# 1430 # dx mov  dx ax in  h# 9999 # ax cmp  =  if
-      h# 34 #  al mov    al  h# 70 #  out   \ Write to CMOS 0x34
-      h# 11 #  al mov    al  h# 71 #  out   \ Write value 01
    then
 
- \ Init memory controller
-
-   \ sdram_initialize,generic_sdram.c
-   \ sdram_set_spdregisters(),auto.c
- 
-   \ 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
-   2000000e.fff00100.  10000028 set-msr  \ Top of memory at 0eff.ffff, fbsize
-   212000fd.ffffd000.  10000029 set-msr  \ Frame buffer at PA fd00.0000 maps to RAM at 0f00.0000, fbsize
-   10076013.00005040.  20000018 set-msr  \ DIMM1 empty, DIMM0 256 MB, 1 module bank, 8K pages
-   2000000e.fff00100.  4000002c set-msr  \ DMA to memory from 1M to RAM limit at 0f00.0000
-   0efff000.00100130.  50002019 set-msr  \ PCI DMA to memory from 1M to RAM limit at 0f00.0000, fbsize
-
-   \ 20000019 rmsr            \ SDRAM timing and mode program
-   00000000.2814d352.   00001981 set-msr  \ Memory delay values
-   00000000.1068334d.   00001982 set-msr  \ Memory delay values
-   00000106.83104104.   00001983 set-msr  \ Memory delay values
-   00000000.00000001.   00001980 set-msr  \ Enable memory delays
-
-[ifdef] cmos-startup-control
-   h# 61 #  al mov    al  h# 70 #  out   h# 71 #  al in  \ Read CMOS 0x61
-   al al test  0= if
-[then]
-      18000100.6a7332a0.   20000019 set-msr
-
-      \ The RAM controller is now set up
-
-    \ Init the SDRAMs
-    \ sdram_enable,src/northbridge/amd/gx2/raminit.c
-
-      \ Clock gating for PMode
-      \ Clocks always on in mode 1, hardware gating in mode 0
-  \   20002004 rmsr  4 bitclr  1 bitset  20002004 wmsr  \ GX p 199
-      1. 20002004 set-msr  \ GX p 199
-
-      \ Delay on exit from power mode 1, use unbuffered RAM
-      130cd801. 2000001a set-msr    \ MC_CF1017_DATA  LX p 231
-[ifdef] cmos-startup-control
-   else
-      al dec  al h# 71 # out            \ Decrement safety counter
-
-      h# 64 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
-      h# 65 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
-      d# 16 # bx shl
-      h# 62 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
-      h# 63 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
-      
-      h# 18000100 # dx mov  bx ax mov  h# 20000019 wmsr
-
-      \ The RAM controller is now set up
-
-    \ Init the SDRAMs
-    \ sdram_enable,src/northbridge/amd/gx2/raminit.c
-
-      \ Clock gating for PMode
-      \ Clocks always on in mode 1, hardware gating in mode 0
-  \   20002004 rmsr  4 bitclr  1 bitset  20002004 wmsr  \ GX p 199
-      1. 20002004 set-msr  \ GX p 199
-
-      \ Delay on exit from power mode 1, use unbuffered RAM
-      h# 68 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
-      h# 69 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
-      d# 16 # bx shl
-      h# 66 # al mov  al h# 70 # out  h# 71 # al in   al bl mov
-      h# 67 # al mov  al h# 70 # out  h# 71 # al in   al bh mov
-
-      dx dx xor  bx ax mov  2000001a wmsr    \ MC_CF1017_DATA  LX p 231
-   then
-[then]
-
-   00000200.00000000. 20000020 set-msr   \ Power mode entry and exit delays
-
-   \ Unmask CKE1 and CKE0
-   1000. 2000001d set-msr   \ MC_CFCLK_DBG Clear 300 bits, don't tristate in IDLE
-
-   \ Reset memory controller
-   20000018 rmsr    \ MC_CF07_DATA
-   2 bitset  20000018 wmsr
-   2 bitclr  20000018 wmsr
-
- else  \ GX branch
-
-   11. 1100 set-msr        \ Enable branch target buffer and near call return stack GX page 116
-
-   \ The next few MSRs allow us to access the 5536
-   \ EXTMSR - page 449   \ Use PCI device #F for port 2
-   00000000.00000f00.   5000201e set-msr  \ cs5536_setup_extmsr(void)
-
-   \ write IDSEL to the write once register at address 0x0000
-   \ 02000000 0 port-wl  \ This is the default value so we need not set it
-
-   \ setup CPU interface serial to mode C on both sides
-   44000020.00200013. 51000010 set-msr   \ 5536 p 229
-
-   \ Tell the GX what kind of companion chip is attached.
-   \ The GX datasheet is incorrect; 2 means 5536, not a reserved value
-   00000000.00000002.   54002010 set-msr
-
-   \ Set up GPIO base register
-   0000f001.00001000.   5140000c set-msr  \ GPIO BAR
-
- \ Init UART
-1 [if]
- 1 [if]
-   \ Set the UART TX line high - this prevents a low-going glitch that
-   \ the receiver interprets as a character.
-   100.0000 1010 port-wl   \ Output AUX1 select - UART TX as GPIO for now
-        100 1000 port-wl   \ high
-        100 1004 port-wl   \ GPIO1 - output enable
- [then]
-
-   \ The UART init sequence takes 550 uS running from ROM
- [ifdef] use-uart2
-   \ cs5536_setup_onchipuart,cs5536_early_setup.c:205.14
-   0.00000012.   5140003e set-msr  \ enable UART2
-
-   \ GPIO1 - UART2 TX
-   10 1004 port-wl   \ GPIO4 - output enable - UART2 TX
-   10 1010 port-wl   \ Output AUX1 select - UART2 TX
-    8 1020 port-wl   \ Input enable UART2 RX
-    8 1034 port-wl   \ Input AUX1 select - UART2 RX
-   0.8070.0003  51400014 set-msr  \ MDD_LEG_IO  UART2 at COM1 address
- [else]
-   \ cs5536_setup_onchipuart,cs5536_early_setup.c:205.14
-   0.00000012.   5140003a set-msr  \ enable COM1
-
-   \ GPIO1 - UART1 TX
-   100 1004 port-wl   \ GPIO1 - output enable
-   100 1010 port-wl   \ Output AUX1 select - UART TX
-   200 1020 port-wl   \ Input enable UART RX
-   200 1034 port-wl   \ Input AUX1 select - UART RX
-   0.8007.0003.  51400014 set-msr  \ MDD_LEG_IO  legacy IO
- [then]
-
-   \ uart_init,serial.c
-   \ This is a garden-variety 8250 UART setup sequence
-    0 3f9 port-wb
-    1 3fa port-wb
-   83 3fb port-wb  \ DLAB
-    1 3f8 port-wb  \ 115200 divisor low
-    0 3f9 port-wb  \ 115200 divisor high
-    3 3fb port-wb  \ !DLAB
-   \ At this point we could send characters out the serial port
-   \ End of serial init
-
-   char + 3f8 port-wb  begin  3fd port-rb 40 bitand  0<> until
-[then]
-
-   h# 11 # al mov  al h# 80 # out
-   h# 1430 # dx mov  dx ax in  h# 9999 # ax cmp  =  if
-      h# 34 #  al mov    al  h# 70 #  out   \ Write to CMOS 0x34
-      h# 10 #  al mov    al  h# 71 #  out   \ Write value 01
-   then
-
- \ Init memory controller
-
-   \ sdram_initialize,generic_sdram.c
-   \ sdram_set_spdregisters(),auto.c
- 
-   \ gpio_init,auto.c
-   4 1020 port-wl          \ Enable the GPIO bit that reports DRAM size (ticket 151)
-
-   \ Refresh and SDRAM program MSR GX page 205
-   \ 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.
-   1030 port-rl 4 bitand  0<> if  \ 128 MiB
-      25fff002.1077e000.      1808 set-msr
-      2c7be040.400fffe0.  10000026 set-msr
-      20000007.7df00100.  10000028 set-msr \ Top of memory
-      20a7e0fd.7fffd000.  10000029 set-msr \ Frame buffer
-      10075012.00003400.  20000018 set-msr
-      20000007.7df00100.  40000029 set-msr \ top of memory.
-      077df000.00100130.  50002019 set-msr
-   else                           \ 256 MiB
-      25fff002.10f7e000.      1808 set-msr
-      2cfbe040.400fffe0.  10000026 set-msr
-      2000000f.7df00100.  10000028 set-msr \ Top of memory
-      2127e0fd.7fffd000.  10000029 set-msr \ Frame buffer
-      10076013.00003400.  20000018 set-msr
-      2000000f.7df00100.  40000029 set-msr \ top of memory.
-      0f7df000.00100130.  50002019 set-msr
-   then
-
-   \ 20000019 rmsr            \ SDRAM timing and mode program
-   18000108.286332a3.   20000019 set-msr
-
-   \ The RAM controller is now set up
-
- \ Init the SDRAMs
- \ sdram_enable,src/northbridge/amd/gx2/raminit.c
-
-   \ Clock gating for PMode
-   \ Clocks always on in mode 1, hardware gating in mode 0
-\   20002004 rmsr  4 bitclr  1 bitset  20002004 wmsr  \ GX p 199
-   1. 20002004 set-msr  \ GX p 199
-
-   \ Delay on exit from power mode 1, use unbuffered RAM
-   101. 2000001a set-msr    \ MC_CF1017_DATA GX p 210
-
-   \ Unmask CKE1 and CKE0
-   0. 2000001d set-msr   \ MC_CFCLK_DBG Clear 300 bits
-
-   \ load RDSYNC
-   \ Empirically, the recommended setting of 0xff310.00000000. causes RAM errors
-   00000310.00000000.   2000001f set-msr  \ GX page 215
-
-   \ set delay control.  The exact value below is specified in the GX manual.
-   830d415a.8ea0ad6a.   4c00000f set-msr
- then
-
    \ char b 3f8 port-wb  begin  3fd port-rb 40 bitand  0<> until
    h# 12 # al mov  al h# 80 # out
    h# 1430 # dx mov  dx ax in  h# 9999 # ax cmp  =  if
       h# 34 #  al mov    al  h# 70 #  out   \ Write to CMOS 0x34
-      h# 12 #  al mov    al  h# 71 #  out   \ Write value 01
+      h# 12 #  al mov    al  h# 71 #  out   \ Write value 0x12
    then
 
 fload ${BP}/dev/geode/draminit.fth

Modified: cpu/x86/pc/olpc/rtcwake.fth
===================================================================
--- cpu/x86/pc/olpc/rtcwake.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/rtcwake.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -57,7 +57,7 @@
 ;
 
 stand-init: Century
-   d# 20 cmos-century cmos!
+   h# 20 cmos-century cmos!   \ The century is in BCD, hence h#
 ;
 
 \ LICENSE_BEGIN

Modified: cpu/x86/pc/olpc/security.fth
===================================================================
--- cpu/x86/pc/olpc/security.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/security.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -345,14 +345,6 @@
 d# 1024 constant /sec-line-max
 /sec-line-max buffer: sec-line-buf
 
-\ Remove bogus null characters from the end of mfg data tags (old machines
-\ have malformed tags)
-: ?-null  ( adr len -- adr' len' )
-   dup  if
-      2dup + 1- c@  0=  if  1-  then        ( adr len' )
-   then
-;
-
 \ machine-id-buf is a buffer into which the machine signature string,
 \ including serial number, UUID, and expiration time, is place.
 \ That string is the signed object for lease and developer key verification.

Added: cpu/x86/pc/olpc/smbios.fth
===================================================================
--- cpu/x86/pc/olpc/smbios.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/smbios.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,453 @@
+\ Make SMBIOS tables
+
+h# ffc00 constant 'smbios
+
+0 [if]
+h# ffbc0 constant 'pciirq
+\ http://www.microsoft.com/whdc/archive/pciirq.mspx
+\ create pciirq-header
+\    h# 52495024 l, \ $PIR
+\    h# 0100 w,     \ version 1.0
+\    h# 0040 w,     \ Total size
+\ 
+\    0 c,  0 c,     \ Bus#, DevFunc#
+\    0 w,           \ Exclusive IRQs
+\    0 l,           \ Compatible router
+\    0 l,           \ miniport data
+\    0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c,  \ res
+\    h# b0 c,       \ checksum
+\    \ Table data goes here
+
+: make-pciirq-table  ( -- )
+   'pciirq h# 40 erase
+   h# 52495024  'pciirq l!            \ $PIR
+   h# 0100      'pciirq la1+ w!       \ version
+   h# 0040      'pciirq la1+ wa1+ w!  \ total size
+   h# b0        'pciirq h# 1f + c!    \ checksum
+   \ The rest of the table is 0 because the actual routing
+   \ is now done by ACPI
+;
+[then]
+
+: c$,  $, 0 c, ;
+
+0 value #smbios-tables
+: copy-smbios-table  ( dst-adr table -- dst-adr' )
+   #smbios-tables 1+ to #smbios-tables
+   2dup 1+ c@       ( dst-adr  table dst-adr len )
+   dup >r  move     ( dst-adr  r: len )
+   r> +             ( dst-adr' )
+;
+
+: smbios-c,  ( dst-adr b -- dst-adr' )  over c!  1+  ;
+: smbios-w,  ( dst-adr w -- dst-adr' )  over le-w!  wa1+  ;
+: smbios-l,  ( dst-adr l -- dst-adr' )  over le-l!  la+  ;
+: smbios-null  ( dst-adr -- dst-adr' )  0 smbios-c,  ;
+: end-smbios-table  ( dst-adr -- dst-adr' )  smbios-null  ;
+: +smbios$  ( dst-adr adr len -- dst-adr' )
+   3dup rot  swap move   ( dst-adr adr len )
+   nip +  smbios-null
+;
+
+0 value uuid-adr
+
+create smbios-entry
+( 00 )   " _SM_" $,
+( 04 )        0  c,  \ Byte checksum - structure must sum to 0 SETME
+( 05 )    h# 1f  c,  \ Entry structure length
+( 06 )    h# 02  c,  \ Major version
+( 07 )    h# 01  c,  \ Minor version
+( 08 )   h# 100  w,  \ Maximum size of a structure
+( 0a )    h# 00  c,  \ Entry point revision
+( 0b )  0 c, 0 c, 0 c, 0 c, 0 c,  \ Formatted area
+( 10 )  " _DMI_" $,  \ Intermediate anchor string
+( 15 )        0  c,  \ Intermediate checksum  SETME
+( 16 )        0  w,  \ Structure table length SETME
+( 18 )        0  l,  \ Structure table address SETME
+\ ( 1c )    d# 11  w,  \ Number of structures
+( 1c )    d# 12  w,  \ Number of structures
+( 1e )    h# 21  c,  \ BCD revision
+
+create bios-info
+( 00 )         0 c,  \ BIOS info type code
+( 01 )     h# 13 c,  \ Length (one BIOS characteristic extension byte)
+( 02 )   h# 0000 w,  \ Handle
+( 04 )         1 c,  \ Vendor string index
+( 05 )         2 c,  \ Version string index
+( 06 )   h# f000 w,  \ BIOS starting address segment
+( 08 )         3 c,  \ Release date index
+( 09 )     h# 0f c,  \ BIOS ROM size in 64K chunks, minus 1
+( 0a )  h# 91880 l,  \ BIOS characteristics - PCI, Reflash, selectable boot, EDD
+( 0e )         0 l,  \ Vendor and system specific BIOS characteristics
+( 12 )         1 c,  \ ACPI is supported
+\        " OLPC" c$,  \ Vendor string
+\       " Q2E00" c$,  \ Version string
+\  " 04/01/2008" c$,  \ Release date string
+\               0 c,  \ End
+
+create system-info
+( 00 )         1 c,  \ System info type code
+( 01 )     h# 19 c,  \ Length (for v2.1)
+( 02 )   h# 0100 w,  \ Handle
+( 04 )         1 c,  \ Manufacturer string index
+( 05 )         2 c,  \ Product name string index
+( 06 )         3 c,  \ Version string index
+( 07 )         0 c,  \ Serial number string index
+( 08 )  here to uuid-adr  h# 10 allot  \ SETME
+( 18 )         6 c,  \ Wake up type
+\       " OLPC" c$,  \ 1: Manufacturer
+\         " XO" c$,  \ 2: Product Name
+\          " 1" c$,  \ 3: Version
+\              0 c,
+
+create base-board-info
+( 00 )         2 c,  \ System info type code
+( 01 )     h#  8 c,  \ Length (for v2.1)
+( 02 )   h# 0200 w,  \ Handle
+( 04 )         1 c,  \ Manufacturer string index
+( 05 )         2 c,  \ Product string index
+( 06 )         3 c,  \ Version string index
+( 07 )         4 c,  \ Serial number string index
+\       " OLPC" c$,  \ 1: Manufacturer
+\         " XO" c$,  \ 2: Product Name
+\          " 1" c$,  \ 3: Version
+
+
+create system-enclosure
+( 00 )         3 c,  \ System enclosure type code
+( 01 )     h# 0d c,  \ Length (for v2.1)
+( 02 )   h# 0300 w,  \ Handle
+( 04 )         1 c,  \ Manufacturer string index
+( 05 )         9 c,  \ Type - laptop
+( 06 )         2 c,  \ Version number string index
+( 07 )         0 c,  \ Serial number string index
+( 08 )         0 c,  \ Asset tag string index
+( 09 )         3 c,  \ Boot-up state
+( 0a )         3 c,  \ Power Supply State
+( 0b )         3 c,  \ Thermal State
+( 0c )         5 c,  \ Security Status - XXX set to 4 in secure mode
+\       " OLPC" c$,  \ 2: Manufacturer
+\          " 1" c$,  \ 3: Version
+\              0 c,
+
+create processor-info
+( 00 )         4 c,  \ Processor info type code
+( 01 )     h# 20 c,  \ Length (for v2.1)
+( 02 )   h# 0400 w,  \ Handle
+( 04 )         0 c,  \ Reference designator string index
+( 05 )         3 c,  \ Type - CPU
+( 06 )         1 c,  \ Family - other
+( 07 )         1 c,  \ Manufacturer
+( 08 )  h# 5a2 l,  h# 88a93d l,  \ CPUID results - SETME dynamically
+( 10 )         2 c,  \ Processor version string index
+( 11 )     h# 8c c,  \ Processor voltage (h# 80 + 1.2V/10)
+( 12 )    d#  33 w,  \ External clock (main bus clock)
+( 14 )    d# 433 w,  \ Max speed
+( 16 )    d# 433 w,  \ Current speed
+( 18 )     h# 41 c,  \ CPU present and enabled
+( 19 )         6 c,  \ Processor upgrade - None
+( 1a )   h# 0701 w,  \ L1 Cache Handle
+( 1c )   h# 0703 w,  \ L2 Cache Handle
+( 1e )   h# ffff w,  \ L3 Cache Handle
+\        " AuthenticAMD" c$,  \ 1: Manufacturer
+\              0 c,
+
+create l1-icache-info
+( 00 )        7 c,   \ Cache info type code
+( 01 )    h# 13 c,   \ Length
+( 02 )  h# 0701 w,   \ Handle
+( 04 )        0 c,   \ Socket string index
+( 05 )   h# 181 w,   \ Writeback, enabled, internal, not socketed, L1
+( 07 )  h# 8002 w,   \ Max size - 128K
+( 09 )  h# 8002 w,   \ Installed size - 128K
+( 0b )        1 w,   \ Supported SRAM type - unknown
+( 0d )        1 w,   \ Installed SRAM type - unknown
+( 0f )        0 c,   \ Speed (NS)
+( 10 )        1 c,   \ ECC - other
+( 11 )        5 c,   \ Type - Unified (actually it is split I and D but they are coherent)
+( 12 )        8 c,   \ Associativity - 16-way set-associative
+\             0 w,
+
+0 [if]
+create l1-dcache-info
+( 00 )        7 c,   \ Cache info type code
+( 01 )    h# 13 c,   \ Length
+( 02 )  h# 0702 w,   \ Handle
+( 04 )        0 c,   \ Socket string index
+( 05 )   h# 181 w,   \ Writeback, enabled, internal, not socketed, L1
+( 07 )  h# 8001 w,   \ Max size - 64K
+( 09 )  h# 8001 w,   \ Installed size - 64K
+( 0b )        1 w,   \ Supported SRAM type - unknown
+( 0d )        1 w,   \ Installed SRAM type - unknown
+( 0f )        0 c,   \ Speed (NS)
+( 10 )        3 c,   \ ECC - none
+( 11 )        4 c,   \ Type - Data
+( 12 )        8 c,   \ Associativity - 16-way set-associative
+\             0 w,
+[then]
+
+create l2-cache-info
+( 00 )        7 c,   \ Cache info type code
+( 01 )    h# 13 c,   \ Length
+( 02 )  h# 0703 w,   \ Handle
+( 04 )        0 c,   \ Socket string index
+( 05 )   h# 182 w,   \ Writeback, enabled, internal, not socketed, L2
+( 07 )  h# 8002 w,   \ Max size - 128K
+( 09 )  h# 8002 w,   \ Installed size - 128K
+( 0b )        1 w,   \ Supported SRAM type - unknown
+( 0d )        1 w,   \ Installed SRAM type - unknown
+( 0f )        0 c,   \ Speed (NS)
+\ ( 10 )        3 c,   \ ECC - none
+( 10 )        1 c,   \ ECC - other
+( 11 )        5 c,   \ Type - Unified
+( 12 )        5 c,   \ Associativity - 16-way set-associative
+\             0 w,
+
+0 value portinfo#
+: make-smbios-port  ( dst-adr connectortype porttype name$ -- dst-adr' )
+   #smbios-tables 1+ to #smbios-tables
+   2>r >r >r
+   8 smbios-c,  9 smbios-c,
+   portinfo# h# 800 + smbios-w,  portinfo# 1+ to portinfo#
+   0 smbios-c,  0 smbios-c,  \ Internal Refdes and Internal Connector Type
+   1 smbios-c,               \ String index
+   r> smbios-c,              \ Connector type
+   r> smbios-c,              \ Port type
+   2r> +smbios$              \ Reference designator string
+   end-smbios-table
+;
+
+create sd-slot-array
+( 00 )    d#  9 c,   \ physical-memory-array type code
+( 01 )    h# 0d c,   \ Length
+( 02 )  h#  d01 w,   \ Handle
+( 04 )        1 c,   \ Refdes
+( 05 )     h# b c,   \ Slot type - proprietary
+( 06 )        1 c,   \ Bus width - other
+( 07 )        4 c,   \ Usage - in use
+( 08 )        3 c,   \ Length - short
+( 09 )  h# 0000 w,   \ ID - meaningless
+( 0b )        4 c,   \ Characteristics 1 - 3.3V
+( 0c )        2 c,   \ Characteristics 2 - hot plug
+
+create video-array
+( 00 )    d# 10 c,   \ onboard device type code
+( 01 )    h# 06 c,   \ Length
+( 02 )  h#  a01 w,   \ Handle
+( 04 )    h# 83 c,   \ Enabled, type 3 (video)
+( 05 )        1 c,   \ Description string
+
+create bios-lang-array
+( 00 )    d# 13 c,   \ BIOS language type code
+( 01 )    h# 16 c,   \ Length
+( 02 )  h#  d01 w,   \ Handle
+( 04 )        1 c,   \ Number of languages
+( 05 )        1 c,   \ Flags - abbreviated format
+( 06 )   0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c, 0 c,  \ Res
+( 15 )        1 c,   \ Currrent language string
+
+create main-memory-array
+( 00 )    d# 16 c,   \ physical-memory-array type code
+( 01 )    h# 0f c,   \ Length
+( 02 )  h# 1001 w,   \ Handle
+( 04 )        3 c,   \ Location - onboard
+( 05 )        3 c,   \ Use - system memory
+( 06 )        3 c,   \ ECC - none
+( 07 ) h# 40000 l,   \ Maximum size - 256K KiB
+( 0b )  h# fffe w,   \ Memory Error Info Handle - not provided
+( 0d )        1 w,   \ Number of devices
+\             0 w,
+
+create memory-device
+( 00 )    d# 17 c,   \ physical-memory-array type code
+( 01 )    h# 15 c,   \ Length
+( 02 )  h# 1101 w,   \ Handle
+( 04 )  h# 1001 w,   \ Handle of "parent" memory array
+( 06 )  h# fffe w,   \ Memory Error Info Handle - not provided
+( 08 )    d# 64 w,   \ Total width
+( 0a )    d# 64 w,   \ Data width
+( 0c )   h# 100 w,   \ Size - 256 MB
+( 0e )    h# 0b c,   \ Form factor - row of chips
+( 0f )        0 c,   \ Set - not part of a set
+( 10 )        1 c,   \ Device Locator string index
+( 11 )        0 c,   \ Bank Locator string index
+( 12 )    h# 12 c,   \ Memory type - DDR
+( 13 )  h# 0080 w,   \ Memory type detail - Synchronous
+\  " Soldered" c$,
+\             0 w,
+
+create ma-mapped-address
+( 00 )    d# 19 c,   \ memory-array-mapped-address type code
+( 01 )    h# 0f c,   \ Length
+( 02 )  h# 1301 w,   \ Handle
+( 04 )        0 l,   \ Starting address - first KiB
+( 08 ) h# 3ffff l,   \ Ending address - last KiB
+( 0c )    h# 31 w,   \ Handle of "parent" memory array
+( 0e )    h#  1 c,   \ Partition width
+\             0 w,
+
+create pointing-device
+( 00 )    d# 21 c,   \ system boot info type code
+( 01 )    h# 07 c,   \ Length
+( 02 )  h# 1501 w,   \ Handle
+( 04 )        7 c,   \ Type - touchpad
+( 05 )        4 c,   \ Interface - PS/2
+( 06 )        2 c,   \ #buttons - 2
+
+
+create system-boot-info
+( 00 )    d# 32 c,   \ system boot info type code
+( 01 )    h# 0b c,   \ Length
+( 02 )  h# 2000 w,   \ Handle
+( 04 )  0 l,  0 w,   \ 6 reseved bytes
+( 0a )        0 c,   \ Boot status - no errors
+\             0 w,
+
+create end-array
+( 00 )    h# 7f c,   \ End type code
+( 01 )    h# 04 c,   \ Length
+( 02 )  h# 7f01 w,   \ Handle
+
+
+: fw-version$  ( -- $ )
+   " /openprom" find-package if
+      " model" rot get-package-property  0=  if
+         get-encoded-string   ( adr len )
+         dup d# 16 =  if
+            \ We just want the "Q2E00" part
+            drop 6 +  5  exit
+         then
+         2drop
+      then
+   then
+   " Unknown"
+;
+d# 10 buffer: fw-date-buf
+
+\ Convert build-date format "2008-04-14" to SMBIOS format "04/14/2008"
+: fw-date$  ( -- $ )
+   " xx/xx/xxxx" fw-date-buf swap move
+   " build-date" evaluate drop   ( adr )
+   dup      fw-date-buf 6 +  4 move  ( adr )  \ Year
+   dup 5 +  fw-date-buf      2 move  ( adr )  \ Month
+   8 +      fw-date-buf 3 +  2 move  ( )      \ Day
+   fw-date-buf d# 10
+;
+: get-tag$  ( tag$ -- value$ )  find-tag  0=  if  " Not Available"  then  ?-null  ;
+
+: too-long?  ( dst-adr -- dst-adr flag )  dup pad - d# 10 >=  ;
+: (uuid)  ( -- true | adr len false )
+   " U#" find-tag   if     ( adr len )
+      pad  -rot            ( dst-adr adr len )
+      bounds  ?do                      ( dst-adr )
+         too-long?  if  drop true unloop exit  then
+         i c@ h# 10 digit  if          ( dst-adr digith )
+            i 1+ c@  h# 10 digit  if   ( dst-adr digith digitl )
+               swap bwjoin  over c!    ( dst-adr )
+               1+                      ( dst-adr' )
+            else                       ( dst-adr digith char )
+               3drop true unloop exit
+            then                       ( dst-adr )
+         else                          ( dst-adr char )
+            [char] - <>  if  drop true unloop exit  then
+         then                          ( dst-adr )
+      loop                             ( dst-adr )
+      pad tuck -                       ( adr len )
+      dup h# 10 =  if                  ( adr len )
+         false   \ Good UUID           ( adr len false )
+      else                             ( adr len )
+         2drop true                    ( true )
+      then                             ( true | adr len false )
+   else                                ( )
+      true                             ( true )
+   then                                ( true | adr len false )
+;
+: get-uuid  ( -- uuid$ )
+   (uuid)  if  " "(00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff)"  then
+;
+
+code get-cpuid  ( code -- eax ebx ecx edx )
+   ax pop  cpuid  ax push  bx push  cx push  dx push
+c;
+: +OLPC  ( adr -- adr' )  " OLPC" +smbios$  ;
+: setup-smbios  ( -- )
+   0 to #smbios-tables
+   0 to portinfo#
+
+   smbios-entry  'smbios  h# 1f  move
+   'smbios h# 1f +                   ( adr )
+
+   bios-info copy-smbios-table       ( adr )
+      +OLPC
+      fw-version$ +smbios$
+      fw-date$    +smbios$
+   end-smbios-table
+
+   dup >r                            ( adr  r: adr )
+   system-info copy-smbios-table     ( adr  r: adr )
+      get-uuid  r> 8 +  swap move    ( adr )   
+      +OLPC
+      " XO" +smbios$
+      " 1" +smbios$    \ Version
+   end-smbios-table
+
+   base-board-info copy-smbios-table        ( adr )
+      +OLPC
+      " XO" +smbios$
+      " 1" +smbios$    \ Version
+      " SN" get-tag$ +smbios$
+   end-smbios-table
+
+   \ XXX might need to amend the security status field
+   system-enclosure copy-smbios-table       ( adr )
+      +OLPC
+      " 1" +smbios$    \ Version
+   end-smbios-table
+
+   dup >r                                   ( adr  r: adr )
+   processor-info copy-smbios-table         ( adr' r: adr )
+      1 get-cpuid  nip nip                  ( adr' eax edx r: adr )
+      r@ h# c + l!  r> 8 + l!               ( adr' )
+      " AuthenticAMD" +smbios$
+      " Geode LX Rev. C3" +smbios$
+   end-smbios-table
+
+   l1-icache-info copy-smbios-table  smbios-null  end-smbios-table
+\   l1-dcache-info copy-smbios-table  smbios-null  end-smbios-table
+   l2-cache-info  copy-smbios-table  smbios-null  end-smbios-table
+
+[ifdef] notdef  \ Why bother - XP doesn't collect these
+   h# 1f h# 1d " Microphone" make-smbios-port
+   h# 1f h# 1d " Headphone"  make-smbios-port
+   h# 12 h# 10 " USB1" make-smbios-port
+   h# 12 h# 10 " USB2" make-smbios-port
+   h# 12 h# 10 " USB3" make-smbios-port
+
+   sd-slot-array      copy-smbios-table  " SD Slot" +smbios$   end-smbios-table
+   bios-lang-array    copy-smbios-table  " enUS"    +smbios$   end-smbios-table
+[then]
+   video-array        copy-smbios-table  " CON"     +smbios$   end-smbios-table
+
+   main-memory-array  copy-smbios-table  smbios-null           end-smbios-table
+   memory-device      copy-smbios-table  " Soldered" +smbios$  end-smbios-table
+   ma-mapped-address  copy-smbios-table  smbios-null           end-smbios-table
+
+\ XP ignores it
+\  pointing-device    copy-smbios-table  smbios-null           end-smbios-table
+
+   \ PORTABLE BATTERY (TYPE 22)
+
+\ XP ignores it
+\   system-boot-info   copy-smbios-table  smbios-null           end-smbios-table
+
+   end-array          copy-smbios-table  smbios-null           end-smbios-table   ( adr' )
+
+   \ Fixup the entry structure
+   'smbios h# 1f +   tuck -         ( tables-adr tables-len )
+   'smbios h# 16 +  w!              ( tables-adr )
+   'smbios h# 18 +  l!              ( )
+   #smbios-tables 'smbios h# 1c + w!
+
+   'smbios          h# 1f  4  fix-checksum  \ Overall checksum
+   'smbios h# 10 +  h# 0f  5  fix-checksum  \ Intermediate checksum
+;

Added: cpu/x86/pc/olpc/ssdt.fth
===================================================================
--- cpu/x86/pc/olpc/ssdt.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/ssdt.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,230 @@
+purpose: Make dynamic SSDT with NAND partition info
+
+h# 1.0000.0000. 2constant nand-size
+
+h# 100 circular-stack: acpi-stack
+
+: acpi-nameseg  ( $ -- )
+   4 min
+   tuck  bounds ?do  i c@ c,  loop   ( len )
+   4 swap  ?do  [char] _ c,  loop
+;
+: acpi-name  ( $ -- )  8 c, acpi-nameseg  ;
+
+\needs le-w,  : le-w,  ( w -- )  wbsplit  swap c, c,  ;
+: acpi-byte  ( b -- )  h# a c,  c,  ;
+: acpi-word  ( w -- )  h# b c,  le-w,  ;
+: acpi-dword  ( l -- )  h# c c,  le-l,  ;
+: acpi-qword  ( l -- )  h# e c,  swap le-l, le-l,  ;
+: acpi-string  ( $ -- )  h# d c,  bounds  ?do  i c@ c,  loop  0 c,  ;
+
+\ This always uses the 2-byte form of pkglen (max len 4K) and
+\ a 2-byte buffer size.  That potentially wastes a couple of
+\ bytes for short buffers, but the code to optimize it would
+\ cost more space than the typical savings.
+: buffer{  ( n -- )
+   h# 11 c,
+   here acpi-stack push
+   0 le-w,    \ PkgLength (2-byte form, max 4K bytes)
+   h# b c,    \ Word Prefix for Buffer Size 
+   0 le-w,    \ Buffer Size
+;
+: }buffer  ( -- )
+   acpi-stack pop                    ( pkg-len-adr )
+   here over -                       ( pkg-len-adr pkg-len )
+   \ Set first byte containing pkglen byte count and low 4 bits
+   2dup h# f and h# 40 or  swap c!   ( pkg-len-adr pkg-len )
+   \ Set second byte containing bits 11..4
+   2dup 4 rshift  swap 1+ c!         ( pkg-len-adr pkg-len )
+   \ Set buffer size word
+   5 -  swap 3 + le-w!
+;
+
+: pkg3{  ( -- )
+   here acpi-stack push
+   0 c, 0 c, 0 c,   \ 3-byte length
+;
+
+: }pkg3  ( -- )
+   acpi-stack pop          ( start )
+   here over -                      ( start len )
+   2dup h# f and h# 80 or  swap c!  ( start len )
+   4 rshift swap 1+ le-w!           ( )
+;
+: acpi-namepath  ( path$ -- )
+   dup 0=  if  2drop exit  then
+
+   over c@  [char] \ =  if        ( path$ )
+      [char] \ c,                 ( path$ )
+      1 /string                   ( path$' )
+   then                           ( path$ )
+
+   begin                          ( path$ )
+      dup 0=  if  2drop exit  then
+      over c@  [char] ^  =
+   while                          ( path$ )
+      [char] ^ c,                 ( path$ )
+      1 /string                   ( path$' )
+   repeat                         ( path$ )
+
+   dup 0=  if  2drop 0 c,  exit   then       \ NullName format
+
+   [char] . left-parse-string     ( rem$ name0$ )
+   2 pick 0=  if                  ( null$ name0$ )
+      \ One name component
+      acpi-nameseg  2drop exit  
+   then                           ( rem$ name0$ )
+
+   2>r                            ( rem$ r: name0$ )
+   [char] . left-parse-string     ( rem$' name1$ r: name0$ )
+   2 pick 0=  if                  ( rem$ name1$ r: name0$ )
+      \ DualNamePath format
+      h# 2e c,                    ( rem$ name1$ r: name0$ )
+      2r> acpi-nameseg            ( rem$ name1$ )
+      acpi-nameseg                ( rem$ )
+      2drop exit  
+   then                           ( rem$ name1$ r: name0$ )
+
+   \ MultiNamePath format
+   h# 2f c,                       ( rem$ name1$ r: name0$ )
+   2r>                            ( rem$ name1$ name0$ )
+
+   here >r                        ( rem$ name1$ name0$ r: 'segcount )
+   2 c,                           ( rem$ name1$ name0$ r: 'segcount )
+   acpi-nameseg acpi-nameseg      ( rem$ )
+   begin  dup  while              ( rem$ )
+      [char] . left-parse-string  ( rem$' name$ )
+      dup  0=  abort" Bad ACPI Path" cr
+      acpi-nameseg                ( rem$ )
+      r@ c@ 1+ r@ c!              ( rem$ )
+   repeat                         ( rem$ )
+   2drop
+   r> drop
+;
+
+: scope{  ( path$ -- )  h# 10 c,   pkg3{  acpi-namepath  ;
+: }scope  ( -- )  }pkg3  ;
+: device{  ( name$ -- )  h# 5b c, h# 82 c,  pkg3{  acpi-nameseg  ;
+: }device  ( -- )  }pkg3  ;
+
+: large-item{  ( type -- )
+   h# 80 or c,
+   here acpi-stack push  0 le-w,  
+;
+: }large-item  ( -- )
+   acpi-stack pop  here over -  2-  swap le-w!  
+;
+
+
+: resource{  ( -- )
+   buffer{
+   here acpi-stack push
+;
+
+: }resource  ( -- )
+   acpi-stack pop          ( start )
+   here over -             ( start len )
+   0 -rot  bounds ?do  i c@ +  loop  ( sum )
+   negate h# ff and        ( checksum )
+   h# 79 c,  c,            ( )
+   }buffer
+;
+
+: acpi-unicode  ( $ -- )  buffer{  bounds  ?do  i c@ le-w,  loop  0 le-w,  }buffer  ;
+
+: acpi-int  ( n -- )
+   dup -1 1 between  if  c, exit  then
+   dup h# 100 < if  acpi-byte exit  then
+   dup h# 10000 <  if  acpi-word exit  then
+   acpi-dword
+;
+
+
+0 value ssdt
+
+: ssdt{  ( -- r: ssdt )
+   here to ssdt
+   " SSDT" $,      \ Signature
+   h# 00000000 l,  \ Length, patched later
+   3 c,            \ Revision
+   0 c,            \ Checksum, patched later
+   " OLPC  " $,    \ OEM ID
+   " XO-1    " $,  \ OEM Table ID
+   h# 00000100 l,  \ OEM Revision
+   " OLPC" $,      \ Creator
+   h# 00000100 l,  \ Creator Revision
+;
+: }ssdt  ( -- )
+   ssdt  here over -   ( table-adr len )
+   2dup swap 4 + l!    ( table-adr len )  \ Set length
+   9 fix-checksum
+;
+: fixed-qword-space  ( d.begin d.len consumer? oem-id -- )
+   c,                       ( d.begin d.len consumer? )
+   1 and h# c or c,         ( d.begin d.len )
+   0 c,                     ( d.begin d.len )  \ Type-specific flags
+   0. d,                    ( d.begin d.len )  \ Granularity
+   2over d,                 ( d.begin d.len )  \ Min
+   2swap 2over d+ 1. d- d,  ( d.len )          \ Max
+   0. d,                    ( d.len )          \ Offset
+   d,                                          \ Length
+;
+h# c0 constant resource-id
+0 constant producer
+1 constant consumer
+0 value next-partition#
+: make-partition  ( d.start d.len name$ boot-status -- )
+   next-partition# <# u# " PRT" hold$ u#> device{     ( d.s d.l name$ stat )
+      dup 0>=  if                                     ( d.s d.l name$ stat )
+         " BTS" acpi-name  acpi-int                   ( d.s d.l name$ )
+      else                                            ( d.s d.l name$ stat )
+         drop                                         ( d.s d.l name$ )
+      then                                            ( d.s d.l name$ )
+      " _ADR" acpi-name  next-partition# acpi-int     ( d.s d.l name$ )
+      " _UID" acpi-name  acpi-unicode                 ( d.s d.l )
+      " _CRS" acpi-name
+      resource{   h# a large-item{                    ( d.s d.l )
+         consumer  resource-id  fixed-qword-space     ( )
+      }large-item  }resource                          ( )
+   }device                                            ( )
+   next-partition# 1+ to next-partition#
+;
+4 constant #bbt-blocks
+h# 20000 value /eblock
+: bbt-partition  ( -- d.start d.len )
+   nand-size  #bbt-blocks /eblock um*  d-   ( d.start )
+   #bbt-blocks /eblock um*                  ( d.len )
+;
+: win-partition  ( -- d.start d.len )     h# 0.0408.0000.  h# 0.a000.0000.  ;
+: make-partitions  ( -- )
+   \ XXX this should be automated from the partition map
+   bbt-partition  " BadBlockTable"  -1  make-partition
+   h#  10.0000.  h#  200.0000.  " WindowsBoot0"    1  make-partition
+   h# 210.0000.  h#  200.0000.  " WindowsBoot1"    0  make-partition
+   h# 410.0000.  h# a000.0000.  " WindowsSystem"  -1  make-partition
+;
+: make-ssdt  ( -- )
+   0 to next-partition#
+   ssdt{
+      " \_SB.PCI0" scope{
+         " NF0" device{
+            " _ADR" acpi-name  h# c.0000 acpi-int
+            " _STA" acpi-name  h# f acpi-int
+            " _CRS" acpi-name
+            resource{
+               h# a large-item{
+                  0.  nand-size  producer  resource-id  fixed-qword-space
+               }large-item
+            }resource
+
+            make-partitions
+
+         }device
+      }scope
+   }ssdt
+;
+
+make-ssdt
+writing test.aml
+ssdt  here over -  ofd @ fputs
+ofd @ fclose

Modified: cpu/x86/pc/olpc/start.bth
===================================================================
--- cpu/x86/pc/olpc/start.bth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/start.bth	2008-07-03 20:25:27 UTC (rev 843)
@@ -16,7 +16,6 @@
 fload ${BP}/cpu/x86/pc/olpc/config.fth
 
 start-assembling
-protected-mode
 
 label my-entry
 

Modified: cpu/x86/pc/olpc/suspend.fth
===================================================================
--- cpu/x86/pc/olpc/suspend.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/suspend.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -37,7 +37,11 @@
    h#      ffff h# cc gpio!  \ Clear negative edge status bits
 
 \  sum-forth
+[ifdef] virtual-mode
    [ also dev /mmu ]  pdir-va  h# f0000 ax-call  [ previous definitions ]
+[else]
+   sp@ 4 -  h# f0000 ax-call  \ sp@ 4 - is a dummy pdir-va location
+[then]
 \  sum-forth
 ;
 : suspend

Modified: cpu/x86/pc/olpc/versions.fth
===================================================================
--- cpu/x86/pc/olpc/versions.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/versions.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -1,8 +1,8 @@
 \ Version numbers of items included in the OLPC firmware image
 
 \ The overall firmware revision
-macro: FW_MAJOR D
-macro: FW_MINOR 16
+macro: FW_MAJOR E
+macro: FW_MINOR 10
 
 \ The EC microcode
 macro: EC_VERSION d13

Added: cpu/x86/pc/olpc/vga.fth
===================================================================
--- cpu/x86/pc/olpc/vga.fth	                        (rev 0)
+++ cpu/x86/pc/olpc/vga.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,64 @@
+screen-ih iselect  stdout off
+
+2000.0000.000f.ff80. 1000.0020 msr!  \ Shrink low mem from 1M to 80000
+2000.0000.080f.ffe0. 1000.0025 msr!  \ Add back 80000-9ffff
+\ 2000.0000.0c0f.ffc0. 1000.0026 msr!  \ Add back c0000-fffff \ 26 is a BMO type descriptor
+8000.0000.0a0f.ffe0. 1000.0021 msr!  \ Enable VGA frame buffer
+
+8000.0000.3c0f.ffe0. 1000.00e0 msr!  \ Enable VGA I/O regs
+
+0101.0101.0101.0101. 0000.180b msr!  \ Uncache frame buffer
+\ 1919.1919.1919.1919. 0000.180b msr!  \ Write-burstable frame buffer
+
+
+
+unlock
+\ 45681 4 dc!  \ Enable vga with fixed timing
+5600 4 dc!  \ Enable vga with fixed timing
+45680 4 dc!  \ Enable vga with fixed timing
+45681 4 dc!  \ Enable vga with fixed timing
+c200.0019 8 dc!  \ drop down to 8bpp mode
+
+
+dl
+vh
+^D
+dl
+tm
+^D
+
+
+\ XX 3 3c2 pc!    \ map some registers at 3dx  \ 67 misc! instead
+: seq!  3c4 pc! 3c5 pc!  ;
+: seq@  3c4 pc! 3c5 pc@  ;
+3 0 seq!  \ display enable
+f 2 seq!  \ enable writing to frame buffer
+
+: crt! 3d4 pc! 3d5 pc! ;
+: crt@ 3d4 pc! 3d5 pc@ ;
+
+uncache this
+  msr: 0000.180b 00000000.00000000.  \ Cache a0000-bffff
+
+
+: mode3-crtc
+     \  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f 10 11 12 13 14 15 16 17 18
+   " "(5f 4f 50 82 51 9e bf 1f 00 4f 0d 0e 00 00 00 00 9b 8d 8f 28 1f 97 b9 a3 ff)"  ;
+: set-crcs  ( -- )
+   mode3-crtc  0  do  dup i + c@  i crt!  loop
+;
+
+: vga@ 3ce pc! 3cf pc@ ;
+: vga! 3ce pc! 3cf pc! ;
+
+c0 6 vga!
+
+: attr@  3da pc@ drop  3c0 pc! 3c1 pc@  ;
+: attr!  3da pc@ drop  3c0 pc! 3c0 pc!  ;
+
+set ega colors with 10 0 do nn i attr! 
+: en-palette  20 3c0 pc!  ;
+
+
+
+000E0h = 1000|0000|0000|0000|0000|0000|0000|0000|0011|1100|0000|1111|1111|1111|1111|0000b

Modified: cpu/x86/pc/olpc/vsapci.fth
===================================================================
--- cpu/x86/pc/olpc/vsapci.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/olpc/vsapci.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -17,8 +17,29 @@
 \ 0: vendor  2: device  4: command  6: status
 \ 8.1: rev  9.3: class  c: /cache-line  d: latency  e: header  f: BIST
 
+: >bar-info  ( mask-adr -- base-adr size )
+   dup l@   swap h# 30 + l@    ( mask bar-value )
+   over and                    ( mask base-adr )
+   swap negate                 ( base-adr size )
+;
+
 hex
+: +methods  ( object -- data-adr )  2 ta+  ;
+: set-cmd-reg  ( object value -- adr value )
+   swap +methods    ( value adr )
+   2dup h# 24 + w!  ( value adr )
+   swap             ( adr value )
+;
+: >hdr-value  ( reg# object -- adr )  +methods  h# 20 +  +  ;
+
+: noop-cmd-reg  ( object value -- )  set-cmd-reg 2drop  ;
+: noop-bar  ( object value -- )  2drop  ;
+
+\ To support changing the SMI address, change MSR 1000.00e3 and some
+\ hardcoded constants in smi.fth
+
 create nb-hdr  \ All R/O except cmd/stat, cache line size, latency
+  ' noop-cmd-reg token,    ' >hdr-value token,  
   fffffffc ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
@@ -30,12 +51,114 @@
          0 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
+: unmap-gxfb  ( -- )
+   h# 1000.0029 p2d-range-off
+   h# 4000.002a p2d-range-off
+   h#      1820 rconf-off
+   0. h# a000.2001 msr!   \ CBASE
+
+   h# 1000.0022  p2d-bm-off
+   h# 4000.0022  p2d-bm-off
+   h#      1811  rconf-off
+   d# 15 ms
+   h# 1000.002a  p2d-bm-off
+   h# 4000.0024  p2d-bm-off
+   h#      1812  rconf-off
+   h# 1000.0023  p2d-bm-off
+   h# 4000.0025  p2d-bm-off
+   h#      1813  rconf-off
+   h# 1000.0024  p2d-bm-off
+   h# 4000.0026  p2d-bm-off
+   h#      1814  rconf-off
+;
+
+\ There are registers inside the display controller and the graphics processor
+\ that need to know the address routing of the frame buffer
+0 value fb-current
+0 value gp-current
+0 value dc-current
+0 value vp-current
+: do-fb-fixups  ( -- )
+[ifdef] virtual-mode
+   gp-current h# 4000 map-v=p
+   dc-current h# 4000 map-v=p
+[then]
+
+   fb-current  dc-current h# 84 +  l!
+   fb-current  gp-current h# 4c +  l!
+
+[ifdef] virtual-mode
+   gp-current h# 4000 mmu-unmap
+   dc-current h# 4000 mmu-unmap
+[then]
+;
+
+: gxfb-cmd-reg  ( object value -- )
+   set-cmd-reg  2 and  if      ( adr )
+      dup h# 30 + l@  h# f invert and  ( adr base-adr )
+      dup to fb-current
+      ?dup  if       \ FB 910  ( adr base-adr )
+         fbsize                ( adr base-adr size )
+         2dup  fb-offset   h# 2  h# 1000.0029 set-p2d-range-offset  ( adr base-adr size )
+         2dup              h# 2  h# 4000.002a set-p2d-range         ( adr base-adr size )
+         2dup            h# 111  h#      1820 set-rconf             ( adr base-adr size )
+         + h# 200000 -  4 rshift  0  h# a000.2001 msr!  \ CBASE ( adr )
+\ XXX need to set dc_base+88.l
+\ See also video-map in chipinit.fth
+      then
+      la1+                      ( adr' )
+
+      dup >bar-info  \ GP 914   ( adr base-adr size )
+      over to gp-current
+      over  if
+         2dup  h#  a  h# 1000.0022  set-p2d-bm
+         2dup  h#  2  h# 4000.0022  set-p2d-bm
+              h# 101  h#      1811  set-rconf
+      else  2drop  then
+      la1+                      ( adr' )
+
+      dup >bar-info   \ DC 918  ( adr base-adr size )
+      over to dc-current
+      over  if
+         2dup  0  h# 8  h# 1000.002a  set-p2d-range-offset
+         2dup     h# 2  h# 4000.0024  set-p2d-bm
+                h# 101  h#      1812  set-rconf
+      else  2drop  then
+      la1+                      ( adr' )
+
+      dup >bar-info   \ VP 91c  ( adr base-adr size )
+      over to vp-current
+      over  if
+         2dup  h# 4  h# 1000.0023  set-p2d-bm
+         2dup  h# 4  h# 4000.0025  set-p2d-bm
+              h# 101  h#      1813  set-rconf
+      else  2drop  then
+      la1+                      ( adr' )
+
+      dup >bar-info  \ VIP 920  ( adr base-adr size )
+      over  if
+         2dup  h#  4  h# 1000.0024  set-p2d-bm
+         2dup  h#  a  h# 4000.0026  set-p2d-bm
+              h# 101  h#      1814  set-rconf
+      else  2drop  then         ( adr )
+
+      drop
+      do-fb-fixups
+   else
+      drop
+
+\     Unmapping wrecks the display
+\     unmap-gxfb
+   then
+;
+
 create gxfb-hdr  \ All R/O except cmd/stat and cache line size
-  ff800000 , fffff000 , fffff000 , fffff000 ,
+  ' gxfb-cmd-reg token,    ' >hdr-value token,  
+  ff000000 , ffffc000 , ffffc000 , ffffc000 ,
          0 ,        0 ,        0 ,        0 ,
 
     30100b ,  2200002 ,  3000000 ,        8 ,
-  fd000000 , fe000000 , fe004000 , fe008000 , \ FB, GP, VG, DF
+  fb-pci-base , gp-pci-base , dc-pci-base , vp-pci-base , \ FB, GP, DC, VP
          0 ,        0 ,        0 ,   30100b , \ VIP (LX only)
          0 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 , \ Interrupt goes at 5c for LX
@@ -43,6 +166,8 @@
          0 ,        0 ,        0 ,        0 ,
 
 create isa-hdr
+  ' noop-cmd-reg token,    ' >hdr-value token,  
+
   fffffff8 , ffffff00 , ffffffc0 , ffffffe0 ,
   ffffff80 , ffffffc0 ,        0 ,        0 ,
 
@@ -54,12 +179,28 @@
          0 ,        0 ,        0 ,     aa5b , \ interrupt steering
          0 ,        0 ,        0 ,        0 ,
 
+: aes-cmd-reg  ( object value -- )
+   set-cmd-reg  2 and  if
+      >bar-info                               ( base-adr size )
+      2dup h#   c h# 4000.002b set-p2d-range  ( base-adr size )
+      2dup h#   4 h# 1000.0025 set-p2d-bm     ( base-adr size )
+           h# 101 h#      1815 set-rconf      
+   else
+      drop
+      h# 1815 rconf-off
+      h# 1000.0025 p2d-bm-off
+      h# 4000.002b p2d-range-off
+   then
+;
+
 create aes-hdr  \ LX security block
+  ' aes-cmd-reg token,    ' >hdr-value token,  
+
   ffffc000 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
   20821022 ,  2a00006 , 10100000 ,        8 ,
-  fe010000 ,        0 ,        0 ,        0 ,  \ I/O BAR - base of virtual registers
+  aes-pci-base ,    0 ,        0 ,        0 ,  \ BAR
          0 ,        0 ,        0 , 20821022 ,
          0 ,        0 ,        0 ,      10e ,  \ INTA, IRQ 14
          0 ,        0 ,        0 ,        0 ,
@@ -68,21 +209,54 @@
 
 0 [if]  \ Turned off
 create nand-hdr  \ Doesn't appear as a PCI device, and kernel doesn't care
+[then]
 
+: ide-cmd-reg  ( object value -- )
+   set-cmd-reg  1 and  if                  ( adr )
+      >bar-info                            ( base-adr size )
+      2dup h# 1 h# 5100.002b set-rconf     ( base-adr size )
+      drop 0    h# 5130.0008 msr!          ( )
+      h# 4002.  h# 5130.0010 msr!          ( )
+   else                                    ( adr )
+      drop                                 ( )
+      h# 5100.002b rconf-off
+      h# 0. h# 5130.0010 msr!              ( )
+   then                                    ( )
+;
+
 create ide-hdr
+  ' ide-cmd-reg token,    ' >hdr-value token,  
+
          0 ,        0 ,        0 ,        0 ,
   fffffff0 ,        0 ,        0 ,        0 , \ Maybe wrong
 
-  209a1022 ,  2a00041 ,  1018001 ,     f800 ,
+  209a1022 ,  2a00040 ,  1018001 ,     f800 ,
          0 ,        0 ,        0 ,        0 ,
       18a1 ,        0 ,        0 , 209a1022 ,
          0 ,        0 ,        0 ,        0 ,
          0 ,        0 , a8a8a8a8 , ffff00ff ,
    3030303 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
-[then]
 
+: ?bus-master  ( cmd-reg mask -- )
+   h# 51010081 2 pick  4 and  if  msr-set  else  msr-clr  then
+;
+: ac97-cmd-reg  ( object value -- )
+   set-cmd-reg           ( adr value )
+
+   h# 300 ?bus-master    ( adr value )
+
+   2drop
+   \ The MSRs are:
+   \ 5101.00e1  a0000001.480fff80.  IOD_BM
+   \ 5100.0026  014f0001.01480001.  io-rconf
+   \ 5150.0004  00000000.00000005.  clock gating
+   \ 5150.0001  00000000.0008f000.  prefetch policy
+;
+
 create ac97-hdr
+  ' ac97-cmd-reg token,    ' >hdr-value token,  
+
   ffffff80 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
@@ -94,24 +268,58 @@
          0 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
+: ohci-cmd-reg  ( object value -- )
+   set-cmd-reg  2 and  if                  ( adr )
+      >bar-info                            ( base-adr size )
+      2dup h# 5 h# 5101.0023 set-p2d-bm    ( base-adr size )
+      2dup h# 1 h# 5100.0027 set-rconf     ( base-adr size )
+      2dup h# 1 h# 5140.0009 set-usb-kel   ( base-adr size )
+      drop h# e h# 5120.0008 set-usb-base  ( )
+   else                                    ( adr )
+      drop                                 ( )
+      h# 5101.0023 p2d-bm-off
+      h# 5100.0027 rconf-off
+      h# 5140.0009 usb-kel-off
+      h# 5120.0008 usb-base-off
+   then                                    ( )
+;
+
 create ohci-hdr
+  ' ohci-cmd-reg token,    ' >hdr-value token,  
+
   fffff000 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
   20941022 ,  2300006 ,  c031002 ,        0 ,
-  fe01a000 ,        0 ,        0 ,        0 , \ MEMBAR-1000
+  ohci-pci-base ,   0 ,        0 ,        0 , \ MEMBAR-1000
          0 ,        0 ,        0 , 20941022 ,
          0 ,       40 ,        0 ,      40a , \ CapPtr  INT-D, IRQ A
   c8020001 ,        0 ,        0 ,        0 , \ Capabilities - 40 is R/O, 44 is mask 8103 (power control)
          0 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
+: ehci-cmd-reg  ( object value -- )
+   set-cmd-reg  2 and  if                     ( adr )
+      >bar-info                               ( base-adr size )
+      2dup h#   04 h# 5101.0024 set-p2d-bm    ( base-adr size )
+      2dup h#   01 h# 5100.0028 set-rconf     ( base-adr size )
+      drop h# 200e h# 5120.0009 set-usb-base  ( )
+   else                                       ( adr )
+      drop                                    ( )
+      h# 5101.0024 p2d-bm-off
+      h# 5100.0028 rconf-off
+      h# 5120.0009 usb-base-off
+   then                                       ( )
+;
+
 create ehci-hdr
+  ' ehci-cmd-reg token,    ' >hdr-value token,  
+
   fffff000 ,        0 ,        0 ,        0 ,
          0 ,        0 ,        0 ,        0 ,
 
-  20951022 ,  2300000 ,  c032002 ,        0 ,
-  fe01b000 ,        0 ,        0 ,        0 , \ MEMBAR-1000
+  20951022 ,  2300006 ,  c032002 ,        0 ,
+  ehci-pci-base ,   0 ,        0 ,        0 , \ MEMBAR-1000
          0 ,        0 ,        0 , 20951022 ,
          0 ,       40 ,        0 ,      40a , \ CapPtr  INT-D, IRQ A
   c8020001 ,        0 ,        0 ,        0 , \ Capabilities - 40 is R/O, 44 is mask 8103 (power control)
@@ -122,6 +330,13 @@
 create ff-loc  -1 ,
 create 00-loc   0 ,
 
+: null-cmd-reg  ( object value -- )  2drop  ;
+: >00-loc  ( reg# object -- adr )  2drop 00-loc  ;
+: >ff-loc  ( reg# object -- adr )  2drop ff-loc  ;
+
+create ff-hdr  ' null-cmd-reg token,   ' >ff-loc token,
+create 00-hdr  ' null-cmd-reg token,   ' >00-loc token,
+
 variable hdr-offset
 variable bar-probing
 
@@ -141,12 +356,13 @@
    then
    bar-probing off
 ;
-: geode-map  ( adr -- data-adr )
+
+: geode-map  ( adr -- offset struct-adr )
    dup h# f0 and  h# 70 >=  if  drop 00-loc exit  then  ( adr )
    dup h# 7f and  swap  h# ff00 and  case    ( offset )
       h# 7800  of  isa-hdr   endof
 \     h# 7900  of  nand-hdr  endof
-\     h# 7a00  of  ide-loc   endof
+      h# 7a00  of  ide-hdr   endof
       h# 7b00  of  ac97-hdr  endof
       h# 7c00  of  ohci-hdr  endof
       h# 7d00  of  ehci-hdr  endof
@@ -155,9 +371,114 @@
       h#  a00  of  gx?  if  drop ff-loc exit  else  aes-hdr  then  endof
       ( default )  2drop ff-loc exit
    endcase
-   +hdr
 ;
 
+: case-within  ( val low high+ -- val ~val | offset 0 0 )
+   3dup within  if       ( val low high+ )
+      drop  -  0 0       ( val low high+ )
+   else                  ( val low high+ )
+      2drop  dup invert  ( val ~val )
+   then
+;
+
+: do-bar  ( object value mask bar-offset -- )
+   \ Noop if the write size is not 32 bits
+   swap  h# ffffffff <>  if  3drop exit  then   ( object value bar-offset )
+
+   rot                                    ( value bar-offset object )
+   +methods  +  >r                        ( value r: adr' )
+
+   \ Mask the value with the size mask that says which bits are writeable
+   r@ l@                                  ( value size-mask r: adr )
+   and                                    ( value' r: adr )
+
+   \ Get the address of the current value
+   r>  h# 30 +  >r                        ( value  r: adr' )
+
+   \ Merge in the existing low attribute bits
+   \ I/O base registers have 2 low attribute bits -   01
+   \ Mem base registers have 4 low attribute bits - xxx0
+   r@ l@                                 ( value old-value  r: adr )
+\  dup 1 and  if  3  else  h# f  then    ( value old-value lowmask  r: adr )
+   dup 1 and  if  3  else  h# 7  then    ( value old-value lowmask  r: adr )
+   and  or                               ( value'  r: adr )
+
+   r>  l!
+;
+
+\ Write to reg 7.b
+: do-status-clear  ( object value mask -- )
+   h# ff <>  if   2drop exit   then   \ Bad size  ( object value )
+
+   \ For now we don't implement status bits
+   2drop
+;
+
+\ Write to reg 6 (possibly including reg 7.b)
+: do-status-reg  ( object value mask -- )
+   \ Reg 6.b is RO, so we only have to do something if the write also includes 7.b
+   h# ffff <>  if  2drop exit  then   ( object value )
+
+   \ Extract the high byte and call the reg 7.b handler
+   wbsplit nip  h# ff  do-status-clear
+;
+
+: cmd-reg-only  ( object value -- )  over token@ execute  ;
+
+\ Write to reg 4 (possibly including reg 6.w)
+: do-command-reg  ( object value mask -- )
+   case  ( object value )
+      h# ffffffff of    ( object value )
+         wbsplit                             ( object value.lo value.hi )
+         2 pick swap h# ffff do-status-reg   ( object value.lo )
+         cmd-reg-only                        ( )
+      endof
+
+      h#     ffff of  cmd-reg-only   endof
+      ( default )  nip nip
+   endcase
+;
+
+: do-cache-line-size  ( object value mask -- )  3drop  ;
+: do-latency-timer  ( object value mask -- )  3drop  ;
+
+: vpci!  ( value reg# object mask -- )
+   over dup ff-loc =   swap 00-loc =  or  if  4drop exit  then
+
+   rot >r            ( value object mask r: reg# )
+   rot swap          ( object value mask r: reg# )
+   r> case  
+      h#  4 of  do-command-reg      endof
+      h#  6 of  do-status-reg       endof
+      h#  7 of  do-status-clear     endof
+      h#  c of  do-cache-line-size  endof
+      h#  d of  do-latency-timer    endof
+      h# 10 h# 2c case-within  of  do-bar  endof
+
+      ( default - read-only )  nip nip nip
+   endcase
+;
+
+: +rhdr  ( reg# object -- adr )  dup ta1+ token@ execute  ;
+
+: >hdr-object  ( adr -- reg# hdr-object )
+   dup h# f0 and  h# 70 >=  if  drop 0 00-hdr exit  then  ( adr )
+   dup h# 7f and  swap  h# ff00 and  case    ( reg# )
+      h# 7800  of  isa-hdr   endof
+\     h# 7900  of  nand-hdr  endof
+\     h# 7a00  of  ide-hdr   endof
+
+      h# 7b00  of  ac97-hdr  endof
+\ h# 7b00  of  ff-hdr  endof
+      h# 7c00  of  ohci-hdr  endof
+      h# 7d00  of  ehci-hdr  endof
+      h#  800  of  nb-hdr    endof
+      h#  900  of  gxfb-hdr  endof
+      h#  a00  of  gx?  if  drop 0 ff-hdr exit  else  aes-hdr  then  endof
+      ( default )  2drop 0 ff-hdr exit
+   endcase
+;
+
 \ The standard cf8/cfc dance
 : config-map-m1  ( config-adr -- port )
    dup  3 invert and  h# 8000.0000 or  h# cf8 pl!  ( config-adr )
@@ -173,23 +494,23 @@
    drop true
 ;
 
-: config-setup  ( a1 -- a2 special? )
+: config-setup  ( a1 -- adr false  |  reg# object true )
    dup  virtual-pci-slot?   ( a1 special )
-   if  geode-map true  else  config-map-m1 false  then
+   if  >hdr-object true  else  config-map-m1 false  then
 ;
 
-: config-b@  ( a -- b )  config-setup  drop  rb@  ;
-: config-w@  ( a -- w )  config-setup  drop  rw@  ;
-: config-l@  ( a -- l )  config-setup  drop  rl@  ;
+: config-b@  ( a -- b )  config-setup  if  +rhdr  then  rb@  ;
+: config-w@  ( a -- w )  config-setup  if  +rhdr  then  rw@  ;
+: config-l@  ( a -- l )  config-setup  if  +rhdr  then  rl@  ;
 
-: config-b!  ( b a -- )  config-setup  if  do-special  else  rb!  then   ;
-: config-w!  ( w a -- )  config-setup  if  do-special  else  rw!  then   ;
-: config-l!  ( l a -- )  config-setup  if  do-special  else  rl!  then   ;
+: config-b!  ( b a -- )  config-setup  if  h#       ff vpci!  else  rb!  then  ;
+: config-w!  ( w a -- )  config-setup  if  h#     ffff vpci!  else  rw!  then  ;
+: config-l!  ( l a -- )  config-setup  if  h# ffffffff vpci!  else  rl!  then  ;
 
 : assign-cafe  ( -- )
-   h# fe020000  h# 6010 config-l!
-   h# fe024000  h# 6110 config-l!
-   h# fe028000  h# 6210 config-l!
+   nand-pci-base    h# 6010 config-l!
+   sd-pci-base      h# 6110 config-l!
+   camera-pci-base  h# 6210 config-l!
 ;
 warning @ warning off
 : stand-init  ( -- )
@@ -197,15 +518,15 @@
 
    lx?  if
       \ Amend the fake PCI headers for the LX settings
-      h# 20801022   nb-hdr h# 20 + l!  \ Vendor/device ID - AMD 
-      h# 20801022   nb-hdr h# 4c + l!  \ Vendor/device ID - AMD 
+      h# 20801022    nb-hdr +methods h# 20 + l!  \ Vendor/device ID - AMD 
+      h# 20801022    nb-hdr +methods h# 4c + l!  \ Vendor/device ID - AMD 
 
-      h# ff000008 gxfb-hdr h#  0 + l!  \ BAR0 MASK - FB
-      h# ffffc000 gxfb-hdr h# 10 + l!  \ BAR4 MASK - VIP
-      h# 20811022 gxfb-hdr h# 20 + l!  \ Vendor/device ID - AMD 
-      h# fe00c000 gxfb-hdr h# 40 + l!  \ BAR4 address - VIP 
-      h# 20811022 gxfb-hdr h# 4c + l!  \ Vendor/device ID - AMD 
-      h#      10e gxfb-hdr h# 5c + w!  \ Interrupt pin and line - INTA, IRQ 14
+      h# ff000008  gxfb-hdr +methods h#  0 + l!  \ BAR0 MASK - FB
+      h# ffffc000  gxfb-hdr +methods h# 10 + l!  \ BAR4 MASK - VIP
+      h# 20811022  gxfb-hdr +methods h# 20 + l!  \ Vendor/device ID - AMD 
+      vip-pci-base gxfb-hdr +methods h# 40 + l!  \ BAR4 address - VIP 
+      h# 20811022  gxfb-hdr +methods h# 4c + l!  \ Vendor/device ID - AMD 
+      h#      10e  gxfb-hdr +methods h# 5c + w!  \ Interrupt pin and line - INTA, IRQ 14
    then
 
 [ifdef] lx-devel  exit  [then]

Modified: cpu/x86/pc/resetend.fth
===================================================================
--- cpu/x86/pc/resetend.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/resetend.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -35,10 +35,12 @@
 
    \ qemu hangs when trying to do this
    here asm-base - ResetBase +  7 +   h# 60  #)  far jmp  \ 7-byte instruction
+\   here asm-base - ResetBase +  7 +   h# 10  #)  far jmp  \ 7-byte instruction
    \ nop nop nop nop
 
 \ begin again
    h# 68 # ax mov
+\   h# 18 # ax mov
    ax ds  mov
    ax es  mov
    ax fs  mov

Added: cpu/x86/pc/rmtools.fth
===================================================================
--- cpu/x86/pc/rmtools.fth	                        (rev 0)
+++ cpu/x86/pc/rmtools.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,7 @@
+purpose: Convert between segment:offset and linear addresses
+
+: >seg:off  ( linear -- offset segment )  lwsplit  d# 12 lshift  ;
+: 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: cpu/x86/pc/tsccal.fth
===================================================================
--- cpu/x86/pc/tsccal.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ cpu/x86/pc/tsccal.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -1,5 +1,5 @@
 \ See license at end of file
-purpose: Calibrate Time Stamp Counter against ISA timer
+purpose: Calibrate Time Stamp Counter against ISA timer using interrupts
 
 \ This code works only for processors that have a Time Stamp Counter register
 

Added: cpu/x86/pc/tsccal1.fth
===================================================================
--- cpu/x86/pc/tsccal1.fth	                        (rev 0)
+++ cpu/x86/pc/tsccal1.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,70 @@
+\ See license at end of file
+purpose: Calibrate Time Stamp Counter against ISA timer - without interrupts
+
+\ This code works only for processors that have a Time Stamp Counter register
+
+code calibrate-loop  ( -- tscdelta )
+   \ setup timer 0 to interrupt when the count goes to 0
+
+   \ TTRR.MMMB Timer 0, r/w=lsb,msb, mode 0, binary
+   h# 30 #  al  mov   al  h# 43 #  out	\ Start setting timer
+
+   d# 11932 wbsplit swap     ( tick-cnt-high tick-cnt-low )
+   #  al  mov   al  h# 40 #  out	\ Set tick limit low  ( tick-cnt-high )
+					\ The timer should now be stopped
+
+   h# f c,  h# 31 c,	\ Get time-stamp counter value into DX,AX
+   ax cx mov		\ Save the low part in CX; the high part is not needed
+
+   #  al  mov   al  h# 40 #  out	\ Set tick limit high to start timer
+
+   begin
+      ax ax xor  al  h# 43 #  out	\ Latch timer
+      h# 40 # al in
+      al ah mov
+      h# 40 # al in
+      al ah xchg
+      d# 5 #  ax  cmp
+   < until
+   
+   h# f c,  h# 31 c,	\ Get time-stamp counter value into DX,AX
+   cx ax sub		\ Subtract the low parts
+   
+   ax push
+c;
+
+
+\needs ms-factor -1 value ms-factor
+\needs us-factor -1 value us-factor
+: calibrate-ms  ( -- )
+   disable-interrupts
+   calibrate-loop   dup d# 10 / to ms-factor  ( count-value )
+   d# 10000 / to us-factor   \ Divide by 1000 with rounding
+;
+stand-init: Calibrating millisecond timer
+   calibrate-ms
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2006 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Modified: dev/egatext.fth
===================================================================
--- dev/egatext.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/egatext.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -136,6 +136,9 @@
    set-attributes
 
 \ Accessing the hardware cursor is a lot of trouble.
+\ There are two things that can go wrong:
+\ 1) The I/O space enable can be off in the display's PCI config register
+\ 2) The CRT registers can be locked
 \   d# 0 h# a crt!  d# 15 h# b crt!   \ Block cursor
 
    #ega-columns to #columns  #ega-lines to #lines

Modified: dev/geode/acpi.fth
===================================================================
--- dev/geode/acpi.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/geode/acpi.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -4,6 +4,8 @@
 0 value acpi-base
 0 value pm-base
 
+: acpi-b@  ( offset -- b )  acpi-base +  pc@ ;
+: acpi-b!  ( b offset -- )  acpi-base +  pc! ;
 : acpi-w@  ( offset -- w )  acpi-base +  pw@ ;
 : acpi-w!  ( w offset -- )  acpi-base +  pw! ;
 : acpi-l@  ( offset -- l )  acpi-base +  pl@ ;

Modified: dev/geode/display/gxfb.fth
===================================================================
--- dev/geode/display/gxfb.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/geode/display/gxfb.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -58,16 +58,15 @@
 : unlock  ( -- ) 4758 0 dc!  ;
 : lock    ( -- )  0 0 dc!  ;
 
-: video-off ( -- )
-   unlock  0000.0000 8 vp!  lock	\ disable syncs, etc
-;
-: video-on  ( -- )
-   unlock
+: video-off ( -- )  0000.0000 8 vp!  ;	\ disable syncs, etc
+
+defer video-on
+: gxvideo-on  ( -- )
    0 h# 50 vp!          \ Power on for DACs, enable gamma correction 
    \ Supposed to be 1.030f but the scope says otherwise
    h# 0001.000f 8 vp!  \ SYNC_SKEW_DFL, -HSYNC, -VSYNC, enable DAC_BL,HS,VS,CRT
-   lock
 ;
+' gxvideo-on to video-on
 
 \ 1024x768-75 VESA
 \  refr xres yres pixclk Lmar Rmar Tmar Bmar Hslen Vslen  SyncPol
@@ -271,6 +270,8 @@
    0 h# 18 dc!     \ Clear cursor buffer offset
    0 h# 1c dc!     \ Clear icon buffer offset
 
+   0 h# 94 dc!     \ Turn off scaling
+
    set-timing
 
    \ Turn on timing generator
@@ -286,17 +287,13 @@
 ;
 
 : display-on  ( -- )
-   unlock
    8 dc@  1 or  8 dc!      \ Enable timing generator
    4 dc@  1 or  4 dc!      \ Enable FIFO
-   lock
 ;
 
 : display-off  ( -- )
-    unlock
     4 dc@  1 invert and  4 dc!  \ DC_GENERAL_CFG - disable FIFO load
     8 dc@  1 invert and  8 dc!  \ DC_DISPLAY_CFG - disable timing generator
-    lock
 ;
 
 h# 300 /n* buffer: video-state
@@ -346,13 +343,12 @@
    drop
    \ video-state - /l / . cr
 
-   unlock
    0 4 dc!  \ Turn off video memory access
    d# 25 ms \ Wait for a frame time to make sure the display is quiet
 ;
 
 : video-restore
-   h# 4758 0 dc!  \ Unlock
+   unlock
 
    video-state
    l at + h# 10 dc!
@@ -478,8 +474,8 @@
 
 : init-controller  ( -- )
 \   " dcon-present?" evaluate to dcon?
+   unlock
    video-off
-   unlock
    
    probe-dcon
 
@@ -497,8 +493,6 @@
       d# 1024 bytes/pixel * to /scanline
       d#  768 to #scanlines
    then
-
-   lock
 ;
 
 : init-hook  ( -- )
@@ -512,13 +506,25 @@
    0 swap 3 /
 ;
 
+\ These are deferred so they can be overridden when switching to VGA mode
+defer plt!     ( color -- )  \ Set color palette entry
+defer plt@     ( -- color )  \ Get color palette entry
+defer windex!  ( index -- )  \ Set color palette write index
+defer rindex!  ( index -- )  \ Set color palette read index
+
+: (plt!)  ( color -- )  h# 74 dc!  ;
+: (plt@)  ( -- color )  h# 74 dc@  ;
+' (plt!) to plt!
+' (plt@) to plt@
+
 : pindex!  ( index -- )  h# 70 dc!  ;
-: plt!  ( color -- )  h# 74 dc!  ;
-: plt@  ( color -- )  h# 74 dc@  ;
+' pindex! to windex!
+' pindex! to rindex!
+
 : rgb>color  ( r g b -- l )  swap rot 0 bljoin  ;
 : color>rgb  ( l -- r g b )  lbsplit drop swap rot  ;
-: color@  ( index -- r g b )  pindex! plt@  color>rgb  ;
-: color!  ( r g b index -- )  >r  rgb>color  r> pindex! plt!  ;
+: color@  ( index -- r g b )  rindex! plt@  color>rgb  ;
+: color!  ( r g b index -- )  >r  rgb>color  r> windex! plt!  ;
 
 : set-colors  ( adr index #indices -- )
    swap pindex!

Added: dev/geode/display/gxvga.fth
===================================================================
--- dev/geode/display/gxvga.fth	                        (rev 0)
+++ dev/geode/display/gxvga.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,691 @@
+purpose: Put the Geode display in VGA mode to use text mode 3
+\ See license at end of file
+
+hex
+create hfilter
+1284A7D5 , 000017D5 ,          \  -43,  297,  296,  -43,    5
+12A497D7 , 000013D6 ,          \  -41,  293,  298,  -42,    4
+12D48BD7 , 000013D6 ,          \  -41,  290,  301,  -42,    4
+13147FD7 , 000013D5 ,          \  -41,  287,  305,  -43,    4
+133473D8 , 000013D5 ,          \  -40,  284,  307,  -43,    4
+136467D8 , 000013D5 ,          \  -40,  281,  310,  -43,    4
+13945FD8 , 000013D4 ,          \  -40,  279,  313,  -44,    4
+13B453D9 , 000013D4 ,          \  -39,  276,  315,  -44,    4
+13E447D9 , 000013D4 ,          \  -39,  273,  318,  -44,    4
+14143BDA , 000013D3 ,          \  -38,  270,  321,  -45,    4
+143433DA , 000013D3 ,          \  -38,  268,  323,  -45,    4
+146427DA , 000013D3 ,          \  -38,  265,  326,  -45,    4
+14941BDB , 000013D2 ,          \  -37,  262,  329,  -46,    4
+14C40FDB , 000013D2 ,          \  -37,  259,  332,  -46,    4
+14F407DA , 000017D1 ,          \  -38,  257,  335,  -47,    5
+1503FBDC , 000013D2 ,          \  -36,  254,  336,  -46,    4
+1543F3DB , 000017D0 ,          \  -37,  252,  340,  -48,    5
+1563E3DD , 000013D1 ,          \  -35,  248,  342,  -47,    4
+1593D7DD , 000013D1 ,          \  -35,  245,  345,  -47,    4
+15B3CFDD , 000013D1 ,          \  -35,  243,  347,  -47,    4
+15E3C3DE , 000013D0 ,          \  -34,  240,  350,  -48,    4
+1613B7DE , 000013D0 ,          \  -34,  237,  353,  -48,    4
+1633ABDF , 000013D0 ,          \  -33,  234,  355,  -48,    4
+16639FDF , 000013D0 ,          \  -33,  231,  358,  -48,    4
+167397E0 , 000013D0 ,          \  -32,  229,  359,  -48,    4
+16B38BE0 , 000013CF ,          \  -32,  226,  363,  -49,    4
+16E383DF , 000017CE ,          \  -33,  224,  366,  -50,    5
+170373E1 , 000013CF ,          \  -31,  220,  368,  -49,    4
+17236BE1 , 000013CF ,          \  -31,  218,  370,  -49,    4
+17435FE2 , 000013CF ,          \  -30,  215,  372,  -49,    4
+177353E2 , 000013CF ,          \  -30,  212,  375,  -49,    4
+17B34BE1 , 000017CD ,          \  -31,  210,  379,  -51,    5
+17C33FE3 , 000013CE ,          \  -29,  207,  380,  -50,    4
+17F333E3 , 000013CE ,          \  -29,  204,  383,  -50,    4
+181327E4 , 000013CE ,          \  -28,  201,  385,  -50,    4
+18431FE3 , 000017CD ,          \  -29,  199,  388,  -51,    5
+186313E4 , 000013CE ,          \  -28,  196,  390,  -50,    4
+188307E5 , 000013CE ,          \  -27,  193,  392,  -50,    4
+18B2FBE5 , 000013CE ,          \  -27,  190,  395,  -50,    4
+18C2F3E6 , 000013CE ,          \  -26,  188,  396,  -50,    4
+18F2E7E6 , 000013CE ,          \  -26,  185,  399,  -50,    4
+1912DBE7 , 000013CE ,          \  -25,  182,  401,  -50,    4
+1952D3E6 , 000017CC ,          \  -26,  180,  405,  -52,    5
+1972CBE6 , 000017CC ,          \  -26,  178,  407,  -52,    5
+1992BFE7 , 000017CC ,          \  -25,  175,  409,  -52,    5
+19C2B3E7 , 000017CC ,          \  -25,  172,  412,  -52,    5
+19D2A7E9 , 000013CD ,          \  -23,  169,  413,  -51,    4
+1A029FE8 , 000017CC ,          \  -24,  167,  416,  -52,    5
+1A1293E9 , 000013CE ,          \  -23,  164,  417,  -50,    4
+1A3287EA , 000013CE ,          \  -22,  161,  419,  -50,    4
+1A627FE9 , 000017CD ,          \  -23,  159,  422,  -51,    5
+1A7273EB , 000013CE ,          \  -21,  156,  423,  -50,    4
+1AA267EB , 000013CE ,          \  -21,  153,  426,  -50,    4
+1AC25FEB , 000013CE ,          \  -21,  151,  428,  -50,    4
+1AE253EC , 000013CE ,          \  -20,  148,  430,  -50,    4
+1B124BEB , 000017CD ,          \  -21,  146,  433,  -51,    5
+1B223FED , 000013CE ,          \  -19,  143,  434,  -50,    4
+1B5237EC , 000017CD ,          \  -20,  141,  437,  -51,    5
+1B622BED , 000013CF ,          \  -19,  138,  438,  -49,    4
+1B821FEE , 000013CF ,          \  -18,  135,  440,  -49,    4
+1BA217EE , 000013CF ,          \  -18,  133,  442,  -49,    4
+1BC20BEF , 000013CF ,          \  -17,  130,  444,  -49,    4
+1BE203EF , 000013CF ,          \  -17,  128,  446,  -49,    4
+1C01FBEE , 000017CF ,          \  -18,  126,  448,  -49,    5
+1C11EFF0 , 000013D0 ,          \  -16,  123,  449,  -48,    4
+1C41E7EF , 000017CF ,          \  -17,  121,  452,  -49,    5
+1C61DFEF , 000017CF ,          \  -17,  119,  454,  -49,    5
+1C61D3F1 , 000013D1 ,          \  -15,  116,  454,  -47,    4
+1C91CBF0 , 000017D0 ,          \  -16,  114,  457,  -48,    5
+1CA1BFF2 , 000013D1 ,          \  -14,  111,  458,  -47,    4
+1CC1B3F2 , 000013D2 ,          \  -14,  108,  460,  -46,    4
+1CE1AFF1 , 000017D1 ,          \  -15,  107,  462,  -47,    5
+1CF1A3F3 , 000013D2 ,          \  -13,  104,  463,  -46,    4
+1D1197F3 , 000013D3 ,          \  -13,  101,  465,  -45,    4
+1D3197F2 , 000013D2 ,          \  -14,  101,  467,  -46,    4
+1D518BF3 , 000013D2 ,          \  -13,   98,  469,  -46,    4
+1D6183F3 , 000013D3 ,          \  -13,   96,  470,  -45,    4
+1D817BF3 , 000013D3 ,          \  -13,   94,  472,  -45,    4
+1D916FF4 , 000013D4 ,          \  -12,   91,  473,  -44,    4
+1DB167F4 , 000013D4 ,          \  -12,   89,  475,  -44,    4
+1DC15FF4 , 000013D5 ,          \  -12,   87,  476,  -43,    4
+1DE153F5 , 000013D5 ,          \  -11,   84,  478,  -43,    4
+1DF14BF5 , 000013D6 ,          \  -11,   82,  479,  -42,    4
+1E1143F5 , 000013D6 ,          \  -11,   80,  481,  -42,    4
+1E1137F7 , 00000FD8 ,          \   -9,   77,  481,  -40,    3
+1E3133F6 , 000013D7 ,          \  -10,   76,  483,  -41,    4
+1E412BF6 , 000013D8 ,          \  -10,   74,  484,  -40,    4
+1E611FF7 , 000013D8 ,          \   -9,   71,  486,  -40,    4
+1E7117F7 , 000013D9 ,          \   -9,   69,  487,  -39,    4
+1E810FF7 , 000013DA ,          \   -9,   67,  488,  -38,    4
+1E9107F8 , 000013DA ,          \   -8,   65,  489,  -38,    4
+1EA0FFF8 , 000013DB ,          \   -8,   63,  490,  -37,    4
+1EB0F3F9 , 00000FDD ,          \   -7,   60,  491,  -35,    3
+1ED0EFF8 , 000013DC ,          \   -8,   59,  493,  -36,    4
+1EE0E7F9 , 00000FDD ,          \   -7,   57,  494,  -35,    3
+1EF0DFF9 , 00000FDE ,          \   -7,   55,  495,  -34,    3
+1F00D7F9 , 00000FDF ,          \   -7,   53,  496,  -33,    3
+1F10CFFA , 00000FDF ,          \   -6,   51,  497,  -33,    3
+1F20C7FA , 00000FE0 ,          \   -6,   49,  498,  -32,    3
+1F20C3FA , 00000FE1 ,          \   -6,   48,  498,  -31,    3
+1F30BBFA , 00000FE2 ,          \   -6,   46,  499,  -30,    3
+1F40AFFB , 00000FE3 ,          \   -5,   43,  500,  -29,    3
+1F50A7FB , 00000FE4 ,          \   -5,   41,  501,  -28,    3
+1F60A3FB , 00000FE4 ,          \   -5,   40,  502,  -28,    3
+1F709BFB , 00000FE5 ,          \   -5,   38,  503,  -27,    3
+1F7093FC , 00000FE6 ,          \   -4,   36,  503,  -26,    3
+1F808FFC , 00000BE7 ,          \   -4,   35,  504,  -25,    2
+1F9087FC , 00000BE8 ,          \   -4,   33,  505,  -24,    2
+1F9083FC , 00000BE9 ,          \   -4,   32,  505,  -23,    2
+1FA077FD , 00000BEA ,          \   -3,   29,  506,  -22,    2
+1FA073FD , 00000BEB ,          \   -3,   28,  506,  -21,    2
+1FB06BFD , 00000BEC ,          \   -3,   26,  507,  -20,    2
+1FC063FD , 00000BED ,          \   -3,   24,  508,  -19,    2
+1FC05BFE , 00000BEE ,          \   -2,   22,  508,  -18,    2
+1FC057FE , 00000BEF ,          \   -2,   21,  508,  -17,    2
+1FD053FE , 000007F0 ,          \   -2,   20,  509,  -16,    1
+1FD04BFE , 000007F2 ,          \   -2,   18,  509,  -14,    1
+1FE043FE , 000007F3 ,          \   -2,   16,  510,  -13,    1
+1FE03BFF , 000007F4 ,          \   -1,   14,  510,  -12,    1
+1FE037FF , 000007F5 ,          \   -1,   13,  510,  -11,    1
+1FE033FF , 000007F6 ,          \   -1,   12,  510,  -10,    1
+1FF02BFF , 000007F7 ,          \   -1,   10,  511,   -9,    1
+1FF027FF , 000003F9 ,          \   -1,    9,  511,   -7,    0
+1FF01C00 , 000003FA ,          \    0,    7,  511,   -6,    0
+1FF01800 , 000003FB ,          \    0,    6,  511,   -5,    0
+1FF01400 , 000003FC ,          \    0,    5,  511,   -4,    0
+1FF00C00 , 000003FE ,          \    0,    3,  511,   -2,    0
+1FF00800 , 000003FF ,          \    0,    2,  511,   -1,    0
+1FF00400 , 00000000 ,          \    0,    1,  511,    0,    0
+1FFFFC00 , 00000002 ,          \    0,   -1,  511,    2,    0
+1FFFF800 , 00000003 ,          \    0,   -2,  511,    3,    0
+1FFFF000 , 00000005 ,          \    0,   -4,  511,    5,    0
+1FFFEC00 , 00000006 ,          \    0,   -5,  511,    6,    0
+1FFFE800 , 00000007 ,          \    0,   -6,  511,    7,    0
+1FFFE400 , 000FFC09 ,          \    0,   -7,  511,    9,   -1
+1FFFDC01 , 000FFC0A ,          \    1,   -9,  511,   10,   -1
+1FEFDC01 , 000FFC0B ,          \    1,   -9,  510,   11,   -1
+1FEFD401 , 000FFC0D ,          \    1,  -11,  510,   13,   -1
+1FEFD001 , 000FFC0E ,          \    1,  -12,  510,   14,   -1
+1FEFCC01 , 000FF810 ,          \    1,  -13,  510,   16,   -2
+1FDFCC01 , 000FF811 ,          \    1,  -13,  509,   17,   -2
+1FDFC401 , 000FF813 ,          \    1,  -15,  509,   19,   -2
+1FCFC002 , 000FF814 ,          \    2,  -16,  508,   20,   -2
+1FCFB802 , 000FF816 ,          \    2,  -18,  508,   22,   -2
+1FCFB402 , 000FF418 ,          \    2,  -19,  508,   24,   -3
+1FBFB402 , 000FF419 ,          \    2,  -19,  507,   25,   -3
+1FAFB002 , 000FF41B ,          \    2,  -20,  506,   27,   -3
+1FAFA802 , 000FF41D ,          \    2,  -22,  506,   29,   -3
+1F9FA802 , 000FF01F ,          \    2,  -22,  505,   31,   -4
+1F9FA402 , 000FF020 ,          \    2,  -23,  505,   32,   -4
+1F8FA002 , 000FF022 ,          \    2,  -24,  504,   34,   -4
+1F7F9803 , 000FF024 ,          \    3,  -26,  503,   36,   -4
+1F7F9403 , 000FEC26 ,          \    3,  -27,  503,   38,   -5
+1F6F9003 , 000FEC28 ,          \    3,  -28,  502,   40,   -5
+1F5F9003 , 000FEC29 ,          \    3,  -28,  501,   41,   -5
+1F4F8C03 , 000FEC2B ,          \    3,  -29,  500,   43,   -5
+1F3F8C03 , 000FE82D ,          \    3,  -29,  499,   45,   -6
+1F2F8803 , 000FE82F ,          \    3,  -30,  498,   47,   -6
+1F2F8003 , 000FE831 ,          \    3,  -32,  498,   49,   -6
+1F1F7C03 , 000FE833 ,          \    3,  -33,  497,   51,   -6
+1F0F7C03 , 000FE435 ,          \    3,  -33,  496,   53,   -7
+1EFF7803 , 000FE437 ,          \    3,  -34,  495,   55,   -7
+1EEF7403 , 000FE439 ,          \    3,  -35,  494,   57,   -7
+1EDF7004 , 000FE03B ,          \    4,  -36,  493,   59,   -8
+1EBF7403 , 000FE43C ,          \    3,  -35,  491,   60,   -7
+1EAF6C04 , 000FE03F ,          \    4,  -37,  490,   63,   -8
+1E9F6804 , 000FE041 ,          \    4,  -38,  489,   65,   -8
+1E8F6804 , 000FDC43 ,          \    4,  -38,  488,   67,   -9
+1E7F6404 , 000FDC45 ,          \    4,  -39,  487,   69,   -9
+1E6F6004 , 000FDC47 ,          \    4,  -40,  486,   71,   -9
+1E4F6404 , 000FD849 ,          \    4,  -39,  484,   73,  -10
+1E3F6004 , 000FD84B ,          \    4,  -40,  483,   75,  -10
+1E1F6003 , 000FDC4D ,          \    3,  -40,  481,   77,   -9
+1E1F5804 , 000FD450 ,          \    4,  -42,  481,   80,  -11
+1DFF5804 , 000FD452 ,          \    4,  -42,  479,   82,  -11
+1DEF5404 , 000FD454 ,          \    4,  -43,  478,   84,  -11
+1DCF5804 , 000FD056 ,          \    4,  -42,  476,   86,  -12
+1DBF5004 , 000FD059 ,          \    4,  -44,  475,   89,  -12
+1D9F5004 , 000FD05B ,          \    4,  -44,  473,   91,  -12
+1D8F5004 , 000FCC5D ,          \    4,  -44,  472,   93,  -13
+1D6F5004 , 000FCC5F ,          \    4,  -44,  470,   95,  -13
+1D5F4804 , 000FCC62 ,          \    4,  -46,  469,   98,  -13
+1D3F4C04 , 000FC864 ,          \    4,  -45,  467,  100,  -14
+1D1F4C04 , 000FCC65 ,          \    4,  -45,  465,  101,  -13
+1CFF4804 , 000FCC68 ,          \    4,  -46,  463,  104,  -13
+1CEF4405 , 000FC46B ,          \    5,  -47,  462,  107,  -15
+1CCF4804 , 000FC86C ,          \    4,  -46,  460,  108,  -14
+1CAF4404 , 000FC86F ,          \    4,  -47,  458,  111,  -14
+1C9F4005 , 000FC072 ,          \    5,  -48,  457,  114,  -16
+1C6F4404 , 000FC474 ,          \    4,  -47,  454,  116,  -15
+1C6F3C05 , 000FBC77 ,          \    5,  -49,  454,  119,  -17
+1C4F3C05 , 000FBC79 ,          \    5,  -49,  452,  121,  -17
+1C1F4004 , 000FC07B ,          \    4,  -48,  449,  123,  -16
+1C0F3C05 , 000FB87E ,          \    5,  -49,  448,  126,  -18
+1BEF3C04 , 000FBC80 ,          \    4,  -49,  446,  128,  -17
+1BCF3C04 , 000FBC82 ,          \    4,  -49,  444,  130,  -17
+1BAF3C04 , 000FB885 ,          \    4,  -49,  442,  133,  -18
+1B8F3C04 , 000FB887 ,          \    4,  -49,  440,  135,  -18
+1B6F3C04 , 000FB48A ,          \    4,  -49,  438,  138,  -19
+1B5F3405 , 000FB08D ,          \    5,  -51,  437,  141,  -20
+1B2F3804 , 000FB48F ,          \    4,  -50,  434,  143,  -19
+1B1F3405 , 000FAC92 ,          \    5,  -51,  433,  146,  -21
+1AEF3804 , 000FB094 ,          \    4,  -50,  430,  148,  -20
+1ACF3804 , 000FAC97 ,          \    4,  -50,  428,  151,  -21
+1AAF3804 , 000FAC99 ,          \    4,  -50,  426,  153,  -21
+1A7F3804 , 000FAC9C ,          \    4,  -50,  423,  156,  -21
+1A6F3405 , 000FA49F ,          \    5,  -51,  422,  159,  -23
+1A3F3804 , 000FA8A1 ,          \    4,  -50,  419,  161,  -22
+1A1F3804 , 000FA4A4 ,          \    4,  -50,  417,  164,  -23
+1A0F3005 , 000FA0A7 ,          \    5,  -52,  416,  167,  -24
+19DF3404 , 000FA4A9 ,          \    4,  -51,  413,  169,  -23
+19CF3005 , 000F9CAC ,          \    5,  -52,  412,  172,  -25
+199F3005 , 000F9CAF ,          \    5,  -52,  409,  175,  -25
+197F3005 , 000F98B2 ,          \    5,  -52,  407,  178,  -26
+195F3005 , 000F98B4 ,          \    5,  -52,  405,  180,  -26
+191F3804 , 000F9CB6 ,          \    4,  -50,  401,  182,  -25
+18FF3804 , 000F98B9 ,          \    4,  -50,  399,  185,  -26
+18CF3804 , 000F98BC ,          \    4,  -50,  396,  188,  -26
+18BF3804 , 000F94BE ,          \    4,  -50,  395,  190,  -27
+188F3804 , 000F94C1 ,          \    4,  -50,  392,  193,  -27
+186F3804 , 000F90C4 ,          \    4,  -50,  390,  196,  -28
+184F3405 , 000F8CC7 ,          \    5,  -51,  388,  199,  -29
+181F3804 , 000F90C9 ,          \    4,  -50,  385,  201,  -28
+17FF3804 , 000F8CCC ,          \    4,  -50,  383,  204,  -29
+17CF3804 , 000F8CCF ,          \    4,  -50,  380,  207,  -29
+17BF3405 , 000F84D2 ,          \    5,  -51,  379,  210,  -31
+177F3C04 , 000F88D4 ,          \    4,  -49,  375,  212,  -30
+174F3C04 , 000F88D7 ,          \    4,  -49,  372,  215,  -30
+172F3C04 , 000F84DA ,          \    4,  -49,  370,  218,  -31
+170F3C04 , 000F84DC ,          \    4,  -49,  368,  220,  -31
+16EF3805 , 000F7CE0 ,          \    5,  -50,  366,  224,  -33
+16BF3C04 , 000F80E2 ,          \    4,  -49,  363,  226,  -32
+167F4004 , 000F80E5 ,          \    4,  -48,  359,  229,  -32
+166F4004 , 000F7CE7 ,          \    4,  -48,  358,  231,  -33
+163F4004 , 000F7CEA ,          \    4,  -48,  355,  234,  -33
+161F4004 , 000F78ED ,          \    4,  -48,  353,  237,  -34
+15EF4004 , 000F78F0 ,          \    4,  -48,  350,  240,  -34
+15BF4404 , 000F74F3 ,          \    4,  -47,  347,  243,  -35
+159F4404 , 000F74F5 ,          \    4,  -47,  345,  245,  -35
+156F4404 , 000F74F8 ,          \    4,  -47,  342,  248,  -35
+154F4005 , 000F6CFC ,          \    5,  -48,  340,  252,  -37
+150F4804 , 000F70FE ,          \    4,  -46,  336,  254,  -36
+14FF4405 , 000F6901 ,          \    5,  -47,  335,  257,  -38
+14CF4804 , 000F6D03 ,          \    4,  -46,  332,  259,  -37
+149F4804 , 000F6D06 ,          \    4,  -46,  329,  262,  -37
+146F4C04 , 000F6909 ,          \    4,  -45,  326,  265,  -38
+143F4C04 , 000F690C ,          \    4,  -45,  323,  268,  -38
+141F4C04 , 000F690E ,          \    4,  -45,  321,  270,  -38
+13EF5004 , 000F6511 ,          \    4,  -44,  318,  273,  -39
+13BF5004 , 000F6514 ,          \    4,  -44,  315,  276,  -39
+139F5004 , 000F6117 ,          \    4,  -44,  313,  279,  -40
+136F5404 , 000F6119 ,          \    4,  -43,  310,  281,  -40
+133F5404 , 000F611C ,          \    4,  -43,  307,  284,  -40
+131F5404 , 000F5D1F ,          \    4,  -43,  305,  287,  -41
+12DF5C04 , 000F5D21 ,          \    4,  -41,  301,  289,  -41
+12AF5C04 , 000F5D24 ,          \    4,  -41,  298,  292,  -41
+
+create vfilter
+3F840D05 ,                        \ 261, 259,  -8
+3F841D01 ,                        \ 257, 263,  -8
+3F8428FE ,                        \ 254, 266,  -8
+3F8438FA ,                        \ 250, 270,  -8
+3F8444F7 ,                        \ 247, 273,  -8
+3F8450F4 ,                        \ 244, 276,  -8
+3F845CF1 ,                        \ 241, 279,  -8
+3F8468EE ,                        \ 238, 282,  -8
+3F8474EB ,                        \ 235, 285,  -8
+3F8480E8 ,                        \ 232, 288,  -8
+3F7490E5 ,                        \ 229, 292,  -9
+3F749CE2 ,                        \ 226, 295,  -9
+3F74ACDE ,                        \ 222, 299,  -9
+3F74B8DB ,                        \ 219, 302,  -9
+3F74C0D9 ,                        \ 217, 304,  -9
+3F74CCD6 ,                        \ 214, 307,  -9
+3F74D8D3 ,                        \ 211, 310,  -9
+3F74E8CF ,                        \ 207, 314,  -9
+3F74F4CC ,                        \ 204, 317,  -9
+3F7500C9 ,                        \ 201, 320,  -9
+3F750CC6 ,                        \ 198, 323,  -9
+3F7518C3 ,                        \ 195, 326,  -9
+3F7520C1 ,                        \ 193, 328,  -9
+3F7530BD ,                        \ 189, 332,  -9
+3F753CBA ,                        \ 186, 335,  -9
+3F7548B7 ,                        \ 183, 338,  -9
+3F6558B4 ,                        \ 180, 342, -10
+3F6560B2 ,                        \ 178, 344, -10
+3F656CAF ,                        \ 175, 347, -10
+3F6578AC ,                        \ 172, 350, -10
+3F6584A9 ,                        \ 169, 353, -10
+3F658CA7 ,                        \ 167, 355, -10
+3F6598A4 ,                        \ 164, 358, -10
+3F65A8A0 ,                        \ 160, 362, -10
+3F65B09E ,                        \ 158, 364, -10
+3F65BC9B ,                        \ 155, 367, -10
+3F65C499 ,                        \ 153, 369, -10
+3F65D096 ,                        \ 150, 372, -10
+3F55E093 ,                        \ 147, 376, -11
+3F55E891 ,                        \ 145, 378, -11
+3F55F48E ,                        \ 142, 381, -11
+3F56008B ,                        \ 139, 384, -11
+3F560C88 ,                        \ 136, 387, -11
+3F561486 ,                        \ 134, 389, -11
+3F562083 ,                        \ 131, 392, -11
+3F562881 ,                        \ 129, 394, -11
+3F56347E ,                        \ 126, 397, -11
+3F56407B ,                        \ 123, 400, -11
+3F564879 ,                        \ 121, 402, -11
+3F465876 ,                        \ 118, 406, -12
+3F466074 ,                        \ 116, 408, -12
+3F466872 ,                        \ 114, 410, -12
+3F46746F ,                        \ 111, 413, -12
+3F467C6D ,                        \ 109, 415, -12
+3F46846B ,                        \ 107, 417, -12
+3F468C69 ,                        \ 105, 419, -12
+3F469866 ,                        \ 102, 422, -12
+3F46A064 ,                        \ 100, 424, -12
+3F46AC61 ,                        \  97, 427, -12
+3F46B45F ,                        \  95, 429, -12
+3F46BC5D ,                        \  93, 431, -12
+3F46C45B ,                        \  91, 433, -12
+3F46CC59 ,                        \  89, 435, -12
+3F36DC56 ,                        \  86, 439, -13
+3F36E454 ,                        \  84, 441, -13
+3F36EC52 ,                        \  82, 443, -13
+3F36F450 ,                        \  80, 445, -13
+3F36FC4E ,                        \  78, 447, -13
+3F37004D ,                        \  77, 448, -13
+3F370C4A ,                        \  74, 451, -13
+3F371448 ,                        \  72, 453, -13
+3F371C46 ,                        \  70, 455, -13
+3F372444 ,                        \  68, 457, -13
+3F372C42 ,                        \  66, 459, -13
+3F373440 ,                        \  64, 461, -13
+3F37383F ,                        \  63, 462, -13
+3F37403D ,                        \  61, 464, -13
+3F37483B ,                        \  59, 466, -13
+3F375039 ,                        \  57, 468, -13
+3F375438 ,                        \  56, 469, -13
+3F375C36 ,                        \  54, 471, -13
+3F376434 ,                        \  52, 473, -13
+3F376833 ,                        \  51, 474, -13
+3F377031 ,                        \  49, 476, -13
+3F377430 ,                        \  48, 477, -13
+3F377C2E ,                        \  46, 479, -13
+3F37842C ,                        \  44, 481, -13
+3F37882B ,                        \  43, 482, -13
+3F47882A ,                        \  42, 482, -12
+3F479028 ,                        \  40, 484, -12
+3F479427 ,                        \  39, 485, -12
+3F479C25 ,                        \  37, 487, -12
+3F47A024 ,                        \  36, 488, -12
+3F47A822 ,                        \  34, 490, -12
+3F47AC21 ,                        \  33, 491, -12
+3F47B020 ,                        \  32, 492, -12
+3F57B01F ,                        \  31, 492, -11
+3F57B81D ,                        \  29, 494, -11
+3F57BC1C ,                        \  28, 495, -11
+3F57C01B ,                        \  27, 496, -11
+3F57C41A ,                        \  26, 497, -11
+3F67C818 ,                        \  24, 498, -10
+3F67CC17 ,                        \  23, 499, -10
+3F67D016 ,                        \  22, 500, -10
+3F67D415 ,                        \  21, 501, -10
+3F67D814 ,                        \  20, 502, -10
+3F77D813 ,                        \  19, 502,  -9
+3F77DC12 ,                        \  18, 503,  -9
+3F77E011 ,                        \  17, 504,  -9
+3F87E010 ,                        \  16, 504,  -8
+3F87E40F ,                        \  15, 505,  -8
+3F87E80E ,                        \  14, 506,  -8
+3F97E80D ,                        \  13, 506,  -7
+3F97EC0C ,                        \  12, 507,  -7
+3F97F00B ,                        \  11, 508,  -7
+3FA7F00A ,                        \  10, 508,  -6
+3FA7F409 ,                        \   9, 509,  -6
+3FB7F408 ,                        \   8, 509,  -5
+3FB7F408 ,                        \   8, 509,  -5
+3FC7F806 ,                        \   6, 510,  -4
+3FC7F806 ,                        \   6, 510,  -4
+3FD7F805 ,                        \   5, 510,  -3
+3FD7FC04 ,                        \   4, 511,  -3
+3FE7FC03 ,                        \   3, 511,  -2
+3FE7FC03 ,                        \   3, 511,  -2
+3FF7FC02 ,                        \   2, 511,  -1
+3FF7FC02 ,                        \   2, 511,  -1
+0007FC01 ,                        \   1, 511,   0
+0007FC01 ,                        \   1, 511,   0
+0007FC01 ,                        \   1, 511,   0
+0027FFFF ,                        \  -1, 511,   2
+0027FFFF ,                        \  -1, 511,   2
+0037FFFE ,                        \  -2, 511,   3
+0037FFFE ,                        \  -2, 511,   3
+0047FFFD ,                        \  -3, 511,   4
+0047FBFE ,                        \  -2, 510,   4
+0057FBFD ,                        \  -3, 510,   5
+0067FBFC ,                        \  -4, 510,   6
+0077F7FC ,                        \  -4, 509,   7
+0077F7FC ,                        \  -4, 509,   7
+0087F7FB ,                        \  -5, 509,   8
+0097F3FB ,                        \  -5, 508,   9
+00A7F3FA ,                        \  -6, 508,  10
+00B7EFFA ,                        \  -6, 507,  11
+00C7EBFA ,                        \  -6, 506,  12
+00D7EBF9 ,                        \  -7, 506,  13
+00E7E7F9 ,                        \  -7, 505,  14
+00F7E3F9 ,                        \  -7, 504,  15
+0107E3F8 ,                        \  -8, 504,  16
+0117DFF8 ,                        \  -8, 503,  17
+0127DBF8 ,                        \  -8, 502,  18
+0137DBF7 ,                        \  -9, 502,  19
+0147D7F7 ,                        \  -9, 501,  20
+0157D3F7 ,                        \  -9, 500,  21
+0167CFF7 ,                        \  -9, 499,  22
+0177CBF7 ,                        \  -9, 498,  23
+0197C7F6 ,                        \ -10, 497,  25
+01A7C3F6 ,                        \ -10, 496,  26
+01B7BFF6 ,                        \ -10, 495,  27
+01C7BBF6 ,                        \ -10, 494,  28
+01E7B3F6 ,                        \ -10, 492,  30
+01F7B3F5 ,                        \ -11, 492,  31
+0207AFF5 ,                        \ -11, 491,  32
+0217ABF5 ,                        \ -11, 490,  33
+0237A3F5 ,                        \ -11, 488,  35
+02479FF5 ,                        \ -11, 487,  36
+026797F5 ,                        \ -11, 485,  38
+027793F5 ,                        \ -11, 484,  39
+02978BF5 ,                        \ -11, 482,  41
+02A78BF4 ,                        \ -12, 482,  42
+02B787F4 ,                        \ -12, 481,  43
+02D77FF4 ,                        \ -12, 479,  45
+02F777F4 ,                        \ -12, 477,  47
+030773F4 ,                        \ -12, 476,  48
+03276BF4 ,                        \ -12, 474,  50
+033767F4 ,                        \ -12, 473,  51
+03575FF4 ,                        \ -12, 471,  53
+037757F4 ,                        \ -12, 469,  55
+038753F4 ,                        \ -12, 468,  56
+03A74BF4 ,                        \ -12, 466,  58
+03C743F4 ,                        \ -12, 464,  60
+03E73BF4 ,                        \ -12, 462,  62
+040737F3 ,                        \ -13, 461,  64
+04272FF3 ,                        \ -13, 459,  66
+044727F3 ,                        \ -13, 457,  68
+04671FF3 ,                        \ -13, 455,  70
+048717F3 ,                        \ -13, 453,  72
+04A70FF3 ,                        \ -13, 451,  74
+04C703F4 ,                        \ -12, 448,  76
+04D6FFF4 ,                        \ -12, 447,  77
+04F6F7F4 ,                        \ -12, 445,  79
+0516EFF4 ,                        \ -12, 443,  81
+0536E7F4 ,                        \ -12, 441,  83
+0556DFF4 ,                        \ -12, 439,  85
+0586CFF5 ,                        \ -11, 435,  88
+05A6C7F5 ,                        \ -11, 433,  90
+05C6BFF5 ,                        \ -11, 431,  92
+05F6B7F4 ,                        \ -12, 429,  95
+0616AFF4 ,                        \ -12, 427,  97
+0636A3F5 ,                        \ -11, 424,  99
+06569BF5 ,                        \ -11, 422, 101
+06868FF5 ,                        \ -11, 419, 104
+06A687F5 ,                        \ -11, 417, 106
+06C67FF5 ,                        \ -11, 415, 108
+06E677F5 ,                        \ -11, 413, 110
+07166BF5 ,                        \ -11, 410, 113
+073663F5 ,                        \ -11, 408, 115
+07665BF4 ,                        \ -12, 406, 118
+07964BF5 ,                        \ -11, 402, 121
+07B643F5 ,                        \ -11, 400, 123
+07D637F6 ,                        \ -10, 397, 125
+08062BF6 ,                        \ -10, 394, 128
+082623F6 ,                        \ -10, 392, 130
+085617F6 ,                        \ -10, 389, 133
+08760FF6 ,                        \ -10, 387, 135
+08B603F5 ,                        \ -11, 384, 139
+08D5F7F6 ,                        \ -10, 381, 141
+0905EBF6 ,                        \ -10, 378, 144
+0925E3F6 ,                        \ -10, 376, 146
+0955D3F7 ,                        \  -9, 372, 149
+0985C7F7 ,                        \  -9, 369, 152
+09A5BFF7 ,                        \  -9, 367, 154
+09D5B3F7 ,                        \  -9, 364, 157
+0A05ABF6 ,                        \ -10, 362, 160
+0A359BF7 ,                        \  -9, 358, 163
+0A658FF7 ,                        \  -9, 355, 166
+0A9587F6 ,                        \ -10, 353, 169
+0AB57BF7 ,                        \  -9, 350, 171
+0AE56FF7 ,                        \  -9, 347, 174
+0B1563F7 ,                        \  -9, 344, 177
+0B455BF6 ,                        \ -10, 342, 180
+0B754BF7 ,                        \  -9, 338, 183
+0BA53FF7 ,                        \  -9, 335, 186
+0BD533F7 ,                        \  -9, 332, 189
+0C0523F8 ,                        \  -8, 328, 192
+0C251BF8 ,                        \  -8, 326, 194
+0C550FF8 ,                        \  -8, 323, 197
+0C9503F7 ,                        \  -9, 320, 201
+0CC4F7F7 ,                        \  -9, 317, 204
+0CF4EBF7 ,                        \  -9, 314, 207
+0D24DBF8 ,                        \  -8, 310, 210
+0D54CFF8 ,                        \  -8, 307, 213
+0D84C3F8 ,                        \  -8, 304, 216
+0DB4BBF7 ,                        \  -9, 302, 219
+0DE4AFF7 ,                        \  -9, 299, 222
+0E149FF8 ,                        \  -8, 295, 225
+0E4493F8 ,                        \  -8, 292, 228
+0E7483F9 ,                        \  -7, 288, 231
+0EA477F9 ,                        \  -7, 285, 234
+0ED46BF9 ,                        \  -7, 282, 237
+0F045FF9 ,                        \  -7, 279, 240
+0F4453F8 ,                        \  -8, 276, 244
+0F7447F8 ,                        \  -8, 273, 247
+0FA43BF8 ,                        \  -8, 270, 250
+0FD42BF9 ,                        \  -7, 266, 253
+10041FF9 ,                        \  -7, 263, 256
+
+: filter-taps
+   h# 100 0  do
+      i h# 400 or  h# 94 dc!
+      hfilter i 3 lshift +  dup l@ h# 98 dc!  la1+ l@ h# 9c dc!
+   loop
+
+   h# 100 0  do
+      i   h# 94 dc!
+      vfilter i la+ l@  h# 98 dc!
+   loop
+;
+
+: vga-mode-msrs
+   2000.0000.000f.ff80. 1000.0020 msr!  \ Shrink low mem from 1M to 80000
+   2000.0000.080f.ffe0. 1000.0026 msr!  \ Add back 80000-9ffff
+   2000.0000.0c0f.ffc0. 1000.0027 msr!  \ Add back c0000-fffff
+   8000.0000.0a0f.ffe0. 1000.0021 msr!  \ Enable VGA frame buffer
+
+   8000.0000.3c0f.ffe0. 1000.00e0 msr!  \ Enable VGA I/O regs
+
+   0101.0101.0101.0101. 0000.180b msr!  \ Uncache frame buffer
+   \ 1919.1919.1919.1919. 0000.180b msr!  \ Write-burstable frame buffer
+;
+
+: all-off
+   unlock
+   4 dc@ 2000.00e0 invert and 4 dc! \ Compr. line buf (2000.0000), Video (8), Color cursor (4), Cursor (2)
+   8 dc@ 1 invert and 8 dc!   \ Timing generator
+   1 ms                       \ Let memory accesses finish
+   4 dc@ 1 invert and 4 dc!   \ Turn off FIFO load
+; 
+: 8bpp  c200.0019 8 dc!  ;  \ drop down to 8bpp mode
+: vga-start
+   8 dc@ 1 or 8 dc!         \ Timing generator
+   4 dc@ 40080 or  4 dc!    \ VGA mode (80), VGA Fixed Timing (40000)
+;
+
+: display-lfb  ( -- )  5601 4 dc!  ;  \ Enable linear framebuffer
+
+: setup-filter-mode3
+
+\   d# 400 1-  d# 640 1-  wljoin  h# 5c dc!
+   d# 400 1-  d# 720 1-  wljoin  h# 5c dc!
+
+   1c802666 90 dc!
+\   1c802222 90 dc!
+\   30003000 90 dc!
+   filter-taps
+\   1aaa3000 90 dc!
+;
+: setup-filter-mode12
+
+\   d# 400 1-  d# 640 1-  wljoin  h# 5c dc!
+   d# 480 1-  d# 640 1-  wljoin  h# 5c dc!
+
+   22222222 90 dc!
+\   1c802222 90 dc!
+\   30003000 90 dc!
+   filter-taps
+\   1aaa3000 90 dc!
+;
+: filteron  1000 94 dc!  ;
+: filteroff
+  40004000 90 dc!  
+  000 94 dc!
+;
+
+\ XXX get these from video/common/defer.fth
+\ false instance value 6-bit-primaries?	\ Indicate if DAC only supports 6bpp
+\ defer ext-textmode  ' noop to ext-textmode
+\ These are just to make vga.fth happy.  They are ba
+\ defer rs@   defer rs!
+\ defer idac@ defer idac!
+\ defer xvideo-on
+\ From graphics.fth
+
+: ext-textmode ;
+defer rmr@  defer rmr!
+
+: (set-colors)  ( adr index #indices -- )
+   swap windex!
+   3 *  bounds  ?do  i c@  plt!  loop
+;
+
+fload ${BP}/dev/video/controlr/vga.fth
+fload ${BP}/dev/video/common/textmode.fth
+
+0 value pc-font-adr
+: (pc-font)  ( -- fontparams )
+   pc-font-adr 0=  if
+      " pcfont" " find-drop-in" evaluate  if  ( adr len )
+         drop to pc-font-adr
+      else
+         default-font exit
+      then
+   then
+
+   " /packages/terminal-emulator" find-package  if  ( phandle )
+      " decode-font" rot find-method  if   ( xt )
+         pc-font-adr swap execute          ( font-params )
+         exit
+      then
+   then
+
+   \ Fallback
+   default-font
+;
+' (pc-font) to pc-font
+
+: switch-to-vga-mode3  ( -- )
+   vga-mode-msrs
+
+   \ The filter must be turned on before turning on the VGA,
+   \ otherwise the filter and the VGA don't synchronize to the
+   \ frame and the sequencer shuts off after one frame.
+   \ That can be fixed with all-off vga-start
+   setup-filter-mode3 filteron
+
+   all-off  8bpp  vga-start
+   use-vga-dac
+   ['] gxvideo-on to video-on        \ Install Geode-specific video-on routine
+;
+: switch-to-vga-mode12  ( -- )
+   vga-mode-msrs
+
+   \ The filter must be turned on before turning on the VGA,
+   \ otherwise the filter and the VGA don't synchronize to the
+   \ frame and the sequencer shuts off after one frame.
+   \ That can be fixed with all-off vga-start
+\   filteroff
+   setup-filter-mode12 filteron
+
+   all-off  8bpp  vga-start
+   use-vga-dac
+   ['] gxvideo-on to video-on        \ Install Geode-specific video-on routine
+;
+
+warning @ warning off
+: text-mode3  ( -- )
+   switch-to-vga-mode3  text-mode3
+   h# ff h# e crt!  h# ff h# f crt!  \ Move the hardware cursor off-screen
+;
+: graphics-mode12  ( -- )
+   switch-to-vga-mode12  graphics-mode12
+;
+warning !
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
+

Added: dev/geode/msr.fth
===================================================================
--- dev/geode/msr.fth	                        (rev 0)
+++ dev/geode/msr.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,106 @@
+purpose: Encode various Geode address routing MSRs
+\ See license at end of file
+
+: msr-clr  ( bitmask msr# -- )  >r  invert  r@  msr@  -rot  and  swap r> msr!  ;
+: msr-set  ( bitmask msr# -- )  >r  r@  msr@  -rot  or  swap r> msr!  ;
+
+: page#  ( adr -- page# )  d# 12 rshift  ;
+
+: p2d-format  ( low high offset type -- msr.low msr.high )
+   d# 28 lshift               ( low high offset type<< )
+   swap 8 lshift or           ( low high offset,type )
+   over d# 12 rshift  or  >r  ( low high r: msr.high )
+   d# 20 lshift or  r>        ( msr.low msr.high )
+;
+
+: >p2d-range  ( base size type -- d.msrval )
+   >r                    ( base size            r: type )
+   bounds  page#         ( end base-page        r: type )
+   swap page# 1-         ( base-page last-page  r: type )
+   0  r>  p2d-format     ( msr.low msr.hi' )
+;
+: >p2d-range-offset  ( base size dst-base type -- d.msrval )
+   >r                    ( base size                         r: type )
+   2 pick - page# -rot   ( offset-page base size             r: type )
+   bounds  page#         ( offset-page end base-page         r: type )
+   swap page# 1-         ( offset-page base-page last-page   r: type )
+   rot  r>  p2d-format   ( msr.low msr.hi' )
+;
+h# fffff. 2constant p2d-range-disabled
+
+: set-p2d-range  ( base size type msr# -- )  >r  >p2d-range  r> msr!  ;
+
+: set-p2d-range-offset  ( base size dst-base type msr# -- )
+   >r  >p2d-range-offset  r> msr!
+;
+
+: p2d-range-off  ( msr# -- )  p2d-range-disabled  rot msr!  ;
+
+: >p2d-bm  ( ( base size type -- d.msrval )
+   >r                 ( base size               r: type )
+   negate page#       ( base mask-page       r: type )
+   swap page#         ( base-page mask-page  r: type )
+   0  r>  p2d-format  ( msr.low msr.hi' )
+;
+: >p2d-bm-offset  ( base size dst-base type -- d.msrval )
+   >r                    ( base size dst-base              r: type )
+   2 pick - page#  -rot  ( offset-page base size           r: type )
+   negate page#          ( offset-page base mask-page      r: type )
+   swap page#            ( offset-page mask-page base-page r: type )
+   rot  r>  p2d-format   ( msr.low msr.hi )
+;
+h# ff.fff00000. 2constant p2d-bm-disabled
+
+: set-p2d-bm  ( base size type msr# -- )   >r  >p2d-bm  r> msr!  ;
+
+: set-p2d-bm-offset  ( base size dst-base type msr# -- )
+   >r >p2d-bm-offset  r> msr!
+;
+
+: p2d-bm-off  ( msr# -- )  p2d-bm-disabled  rot msr!  ;
+
+: >rconf  ( base-adr size mode -- d.msrval )
+   >r                ( base-adr size     r: mode )
+   bounds            ( end-adr base-adr  r: mode )
+   r> or             ( end-adr msr.low  )
+   swap h# 1000 -    ( msr.low msr.high )
+;
+0. 2constant rconf-disabled
+
+: set-rconf  ( base-adr size mode msr# -- )  >r >rconf r> msr!  ;
+
+: rconf-off  ( msr# -- )  rconf-disabled  rot msr!  ;
+
+
+: >usb-kel  ( base-adr size ena -- d.msrval )
+   >r            ( base-adr size  r: type )
+   negate r> or  ( msr.lo msr.hi )
+;
+: set-usb-kel   ( base-adr size ena msr# -- )  >r >usb-kel r> msr!  ;
+: set-usb-base  ( base-adr type msr# -- )  msr!  ;
+: usb-base-off  ( msr# -- )  0. rot  msr!  ;
+: usb-kel-off   ( msr# -- )  0. rot  msr!  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Modified: dev/geode/smi.fth
===================================================================
--- dev/geode/smi.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/geode/smi.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -18,6 +18,28 @@
 : +smm  ( segment-relative-adr -- adr )  smm-base +  ;
 : -smm  ( adr -- segment-relative-adr )  smm-base -  ;
 
+label int-entry
+   16-bit
+   al  h# 30 #  out  iret  nop
+   al  h# 31 #  out  iret  nop
+   al  h# 32 #  out  iret  nop
+   al  h# 33 #  out  iret  nop
+   al  h# 34 #  out  iret  nop
+   al  h# 35 #  out  iret  nop
+   al  h# 36 #  out  iret  nop
+   al  h# 37 #  out  iret  nop
+   al  h# 38 #  out  iret  nop
+   al  h# 39 #  out  iret  nop
+   al  h# 3a #  out  iret  nop
+   al  h# 3b #  out  iret  nop
+   al  h# 3c #  out  iret  nop
+   al  h# 3d #  out  iret  nop
+   al  h# 3e #  out  iret  nop
+   al  h# 3f #  out  iret  nop
+end-code
+here int-entry -  constant /int-entry
+
+
 h# 28 constant /smm-gdt
 h#  8 constant smm-c16
 h# 10 constant smm-d16
@@ -42,13 +64,29 @@
 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
+2     rm-data smm-save-ds    \ Temporary DS
+2     rm-data smm-save-ss    \ Saved SS
 
-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
+0     rm-data  smm-sp        \ Real-mode sp after saving registers
+/l    pm-data  smm-cr3       \ Alternate name, for use by Forth
+/l    pm-data  smm-cf8       \ Alternate name, for use by Forth
 
-h# 30 pm-stack smm-header     \ Top address where hardware puts the SMM info frame
+0     pm-data  caller-regs
+4 /w* pm-data  smm-sregs     \ GS, FS, ES, DS
+8 /l* pm-data  smm-gregs     \ EDI, ESI, EBP, Exx, EBX, EDX, ECX, EAX
+0     rm-data  smm-stack
 
+/l    pm-data  smm-retaddr   \ EIP
+/l    pm-data  smm-rmeflags  \ EFLAGS
+
+0     pm-data  smm-rmidt     \ IDT
+8     pm-data  rm-buf
+
+
+h# 30 pm-stack smm-header    \ Top address where hardware puts the SMM info frame
+
+/int-entry pm-data 'int10-dispatch
+
 \ 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
@@ -79,21 +117,27 @@
    \ End of GDT
 
    cs: ds  smm-save-seg d# 00 +  #)  svdc
+   cs: ds  smm-save-ds           #)  mov
    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
 
+   ss  smm-save-ss           #)  mov
    smm-gdt smm-d16 + #)  ss  rsdc
 
    op: sp  smm-save-esp #)  mov
    smm-stack #  sp  mov      \ Now we have a stack
 
    op: pusha
+   smm-save-ds #)  ax  mov
+   ax  push
+   es push  fs push  gs push
 
+
    h# cf8 #  dx   mov   \ Save/restore PCI config address
    op: dx    ax   in
    op: ax         push
@@ -114,6 +158,8 @@
    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 #)  ax  mov
@@ -133,6 +179,8 @@
    cld
 c;
 code (smi-return)   \ This code field must be relocated after copying to SMM memory
+   cli
+
    \ Exchange the stack and return stack pointer with the smi versions
    '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
@@ -164,29 +212,619 @@
    h# cf8 #  dx  mov   \ Save/restore PCI config address
    op: ax    dx  out
 
+   gs pop  fs pop  es pop
+   ax pop  ax smm-save-ds #) mov
    op: popa
 
    op: smm-save-esp #)  sp  mov
 
+   smm-save-ss #)  ss  mov
+
    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
-
+   
+\   cs: smm-save-ds #)           ds  mov
    rsm
 end-code
 here smi-handler - constant /smi-handler
 
+: smm-dr7       ( -- l )      smm-header h#  4 - l@  ;
+: smm-eflags    ( -- l )      smm-header h#  8 - l@  ;
+: smm-cr0       ( -- l )      smm-header h#  c - l@  ;
+: smm-eip       ( -- l )      smm-header h# 10 - l@  ;
+: smm-next-eip  ( -- l )      smm-header h# 14 - l@  ;
+: smm-next-eip! ( l -- )      smm-header h# 14 - l!  ;
+: smm-cs-flags  ( -- w )      smm-header h# 16 - w@  ;
+: smm-cs-sel    ( -- w )      smm-header h# 18 - w@  ;
+: smm-cs-base   ( -- l )      smm-header h# 1c - l@  ;
+: smm-ss-flags  ( -- w )      smm-header h# 22 - w@  ;
+: 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@  ;
+: smm-pc        ( -- padr )   smm-eip smm-cs-base +  ;
+
+\ 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-cf8 @ h# 7fff.fffc and
+   smm-io-port 3 and  or
+;
+\ Address of segment registers
+: smm-eax  ( -- adr )  smm-gregs  7 la+  ;
+: smm-ebp  ( -- adr )  smm-gregs  2 la+  ;
+
+: >ptable  ( table vadr shift -- table' unmapped? )
+   rshift  h# ffc and + l@
+   dup h# fff invert and  swap 1 and 0=
+;
+
+\ XXX need to handle mapped-at-pde-level
+defer smm>physical
+: (smm>physical)  ( vadr -- padr )
+\   smm-cr0  h# 8000.0000 and  0=  if  exit  then
+   cr3@                                  ( vadr pdir )
+   over d# 20 >ptable  abort" Unmapped"  ( vadr ptab )
+   over d# 10 >ptable  abort" Unmapped"  ( vadr pframe )
+   swap h# fff and +
+;
+' (smm>physical) to smm>physical
+
+: smm-map?  ( vadr -- )  smm>physical  .  ;
+
+\ Programs that write to the caller's data space should use this,
+\ as it works when called from paged V86 mode.
+: >caller-physical  ( vadr -- padr )
+   smm-cr0  h# 8000.0000 and  if  (smm>physical)  then
+;
+
+\ Turn address translation on or off for the following commands,
+\ so they can be used either for non-paged calling code like
+\ early bootloaders or for paged code that calls to us via a
+\ real mode gateway.
+
+: use-physical  ( -- )  ['] noop to smm>physical  ;
+: use-virtual   ( -- )  ['] (smm>physical) to smm>physical  ;
+
+
 : smi-return  ( -- )  [ ' (smi-return) smi-handler -  +smm ] literal  execute  ;
 defer handle-smi  ' noop is handle-smi
 create smm-exec  ] handle-smi smi-return [
 
+false value vpci-debug?
 : enable-virtual-pci  ( -- )
-   h# 5000.2012 msr@  swap h# 8002 or   swap  h# 5000.2012 msr!  \ Virtualize devices f and 1
+   \ Virtualize devices f and 1, or all devices if debugging
+   vpci-debug?  if  h# ffff  else  h# 8002  then  >r
+   h# 5000.2012 msr@  swap r>  or       swap  h# 5000.2012 msr!
    h# 5000.2002 msr@  swap 8 invert and swap  h# 5000.2002 msr!  \ Enable SSMI for config accesses
 ;
 
+\ : msr-ack  ( msr# -- )  >r  r@  msr@  r> msr!  ;
+code msr-ack  ( msr# -- )  cx pop  rdmsr  wrmsr  c;
+code msr@!  ( msr# -- d.value )  cx pop  rdmsr  wrmsr  ax push  dx push  c;
+code msr-sense32  ( err-msr# -- false | statbits statbits )
+   cx pop  rdmsr wrmsr
+   cx dec  rdmsr wrmsr
+   ax not  dx ax and  ax push
+   0<>  if  ax push  then
+c;
+code msr-sense32p  ( err-msr# -- false | statbits statbits )
+   cx pop  rdmsr wrmsr
+   cx dec  rdmsr wrmsr
+   dx ax and  ax push
+   0<>  if  ax push  then
+c;
+code msr-sense16  ( err-msr# -- false | statbits statbits )
+   cx pop  rdmsr wrmsr
+   cx dec  rdmsr wrmsr
+   ax dx mov   d# 16 # dx shr
+   h# ffff # ax and
+   ax not  dx ax and  ax push
+   0<>  if  ax push  then
+c;
+code msr-sense16p  ( err-msr# -- false | statbits statbits )
+   cx pop  rdmsr wrmsr
+   cx dec  rdmsr wrmsr
+   ax dx mov   d# 16 # dx shr
+   h# ffff # ax and
+   dx ax and  ax push
+   0<>  if  ax push  then
+c;
+
+alias msr. .msr
+: enable-io-smis  ( -- )
+   \ XXX these settings need to be folded into the MSR table for resume
+   h# 0000.0009.c00fffc0. h# 5101.00e4 msr!  \ Virtualize ACPI registers
+   1 h# 5101.0002 msr-clr  \ Enable SSMI in GLIU_GLD_MSR_SMI
+   4 h# 5100.0002 msr-set  \ Enable SSMI in GLPCI_GLD_MSR_SMI
+
+   \ Virtual registers
+   h#    f030ac18. h# 1000.00e3 msr!   \ AC1C..AC1F
+   h# 0.030f.fff0. h# 1000.00e2 msr!   \ 30..3f - for bouncing INTs to SMIs
+   h#          80. h# 5140.0002 msr!   \ Port 92 INIT (bit 0 - reset)
+
+   1 h# 1000.2002 msr-clr  \ AC1C generates SMI
+   1 h# 1000.2003 msr-set  \ AC1C does not generate ERR
+   1 h# 4000.2002 msr-clr
+
+   h# 11 h# 4c00.2002 msr-clr  \   h# 10 h# 4c00.2002 msr-clr
+
+   0. h# 1000.0083 msr!  \ Enable ASMIs in LX GLIU0
+   0. h# 5101.0083 msr!  \ Enable ASMIs in 5536 GLIU0
+
+   h# ff00  h# 1000.0082 msr-clr   h# ff00  h# 1000.0083 msr-clr
+   h# ff00  h# 4000.0082 msr-clr   h# ff00  h# 4000.0083 msr-clr
+   h# 38. h# 1301 msr!
+;
+\ 10002002 records ac1c accesses in bit 0  (1)
+\ 51010002 records 9c00 accesses in bit 32 (1.0000.0000)
+\ 51000002 records 9c00 accesses in bit 18 (     4.0000)
+\ 4c002002 records 9c00 accesses in bit 20 (    10.0000)
+: msr..    ( msr# -- )  dup 8 u.r space msr.  ."   "  ;
+: .msr16s  ( msrhigh -- )  dup 8 u.r space msr@  drop 8 u.r ."   "  ;
+: .msr2  ( msrhigh -- )
+   dup 4 u.r  ." : "  >r
+   h# 2002 dup 4 u.r space r@ wljoin  msr.  ."  "
+   h# 2003 dup 4 u.r space r@ wljoin  msr.  ."  "
+   r> drop  cr
+;
+: .msr4  ( msrhigh -- )
+   dup 4 u.r  ." : "  >r
+   h# 2002 dup 4 u.r space r@ wljoin  msr.  ."  "
+   h# 2003 dup 4 u.r space r@ wljoin  msr.  ."  "
+   h#   83 dup 2 u.r space r@ wljoin  msr@ drop 8 u.r  ."  "
+   h#   84 dup 2 u.r space r@ wljoin  msr@ drop 8 u.r  ."  "
+   r> drop  cr
+;
+: .msrs
+   h# 5100 .msr2    \ PCI Southbridge  - XXX check RCONFs
+   h# 5101 .msr4    \ GLIU
+
+   h# 4c00 .msr2    \ GLCP - interface to 5536
+   h# 1000 .msr4
+   h# 4000 .msr4
+   ."   " h# 1301 msr..   cr
+;
+: ma
+   h# 10002002 msr-ack  h# 10002003 msr-ack 
+   h# 40002002 msr-ack  h# 40002003 msr-ack 
+   h# 51010002 msr-ack  h# 51010003 msr-ack
+   h# 51000002 msr-ack  h# 51000003 msr-ack
+   h# 4c002002 msr-ack  h# 4c002003 msr-ack
+   \ h# 10000083 msr-ack  h# 40000083 msr-ack \ These have no status bits; nothing to ack
+   \ h# 51010083 msr-ack \ This one has status bits, but they are RO
+;
+
+: smi-interact  ( -- )  ." In SMI" cr  interact  ;
+' smi-interact is handle-smi
+
+: vr-spoof?  ( -- handled? )  false  ;
+
+: pci-smi  ( event-mask -- )
+   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
+
+   \ The existing Forth config spoofer does the hard work
+   smm-flags 2 and  if  \ Write
+      smm-io-data  smm-config-adr   ( data config-adr )
+      vpci-debug?  if  ." PW" smm-io-size . over . dup . cr  then
+      smm-io-size case
+         1 of  config-b!  endof
+         3 of  config-w!  endof
+         h# f of  config-l!  endof
+      endcase
+   else
+      smm-config-adr                 ( config-adr )
+      false  if  ." PR " dup . cr  then
+      smm-io-size case
+         1 of  config-b@ smm-eax c!  endof
+         3 of  config-w@ smm-eax w!  endof
+         h# f of  config-l@ smm-eax l!  endof
+      endcase
+   then
+   vpci-debug?  if  2r> h# 5000.2012 msr!  then
+;
+: smm-eax-c!  ( b -- )  smm-eax c!  ;
+: smm-eax-c@  ( -- b )  smm-eax c@  ;
+0 value requested-mode
+0 value color-depth   \ 1:8bpp 2:XRGB444 3:RGB555 4:RGB565 5:24bpp
+0 value refresh-rate
+0 value display-enable-reg  \ 01: FlatPanelEna  02: CRTEna  04: FixTimingEna 10: HSYNCDis 20: VSYNCDis
+: do-display-enable   ;   \ XXX implement me
+0 value ext-offset-low
+0 value ext-offset-high
+0 value ext-start-addr
+: do-mode-switch  ( -- )
+   1 and  if  ( XXX )  then
+;
+0 value crc-status
+: start-crc  ( -- )   ( XXX )  ;
+: dc-smi  ( event-mask -- )
+   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@
+      h# 3d4 pc@  case
+         h# 33 of  start-crc              endof  \ CRC Command
+         h# 34 of  drop                   endof  \ CRC Data
+         h# 3f of  do-mode-switch         endof  \ Mode Switch start
+         h# 40 of  to requested-mode      endof  \ Mode Number
+         h# 46 of  to color-depth         endof  \ Extended Color Control
+         h# 4f of  to refresh-rate        endof  \ Refresh rate
+         h# 50 of  to display-enable-reg  do-display-enable  endof  \ Display Enable
+         h# 51 of  to ext-offset-low   endof  \ Ext offset low
+         h# 52 of  to ext-offset-high  endof  \ Ext offset high
+         h# 54 of  to ext-start-addr   endof  \ Ext start
+      endcase
+   else                 \ Read
+      h# 3d4 pc@  case
+         h# 33 of  crc-status            endof  \ CRC Command
+         h# 34 of  0                     endof  \ CRC Data
+         h# 35 of  [char] A              endof  \ SoftVG ID1
+         h# 36 of  [char] M              endof  \ SoftVG ID2
+         h# 37 of  2                     endof  \ Major Version
+         h# 38 of  d# 10                 endof  \ Minor Version
+         h# 3e of  fbsize d# 19 rshift   endof  \ Graphics memory size
+         h# 3f of  h# 82                 endof  \ Mode Switch start (Rev2silicon, FlatPanel)
+         h# 40 of  requested-mode        endof  \ Mode Number
+         h# 46 of  color-depth           endof  \ Extended Color Control
+         h# 4f of  refresh-rate          endof  \ Refresh rate
+         h# 50 of  display-enable-reg    endof  \ Display Enable
+         h# 51 of  ext-offset-low        endof  \ Ext offset low
+         h# 52 of  ext-offset-high       endof  \ Ext offset high
+         h# 54 of  ext-start-addr        endof  \ Ext start
+      endcase
+      smm-eax-c!
+   then
+;
+
+0 [if]
+: vs  ( -- handled? )
+   smm-io-port h# ac1c =  if
+      ." V"
+      h# 1000.2002 msr-ack
+      \ h# 1000.2003 msr-ack  h# 4c00.2000 msr-ack  \ Don't need this; we suppress ERRs
+      true exit
+   then
+   smm-io-port . cr
+   h# 5100.0002 msr-ack  \ Ack in 5536 PCI SouthBridge (       4.0000 bit )
+   h# 5101.0002 msr-ack  \ Ack in 5536 GLIU            (  1.0000.0000 bit )
+   h# 4c00.2002 msr-ack  \ Ack in LX                   (      10.0000 bit )
+   true exit
+;
+[then]
+
+0 value vr-index
+false value vr-debug?
+
+true value vr-locked?
+
+0 value rm-int@
+
+defer handle-bios-call
+
+: enable-softvg  ( -- )
+   h# 10 h# 8000.2002 msr-clr  \ Enable SMI for invalid CRTC register
+;
+: rm-sp  ( -- adr )  smm-save-esp +smm w@  smm-save-ss +smm w@ seg:off>  ;
+: do-vr  ( -- )
+   \ ." VR "
+   smm-io-port h# ac1c =  if
+      smm-io-size  h# f  =  if
+         smm-eax @  lwsplit  h# fc53 <>  to vr-locked?  ( low-word )
+      else
+         smm-eax w@  dup h# fc53 =  if  false to vr-locked?  then
+      then      
+      to vr-index
+      exit
+   then
+   smm-io-size  h# 3 <>  if  true to vr-locked?  exit  then
+   smm-flags 2 and  if
+      vr-index case
+         h#  200 of  ( enable-softvg )  endof
+         ( default )
+            ." VR Write " vr-index .  smm-eax @ .  cr
+            false to exit-interact?  interact
+      endcase
+   else
+      vr-index case
+\         h# 200 of  fbsize d# 19 rshift  h# 8300 or  smm-eax w!  endof
+         h#  200 of  fbsize d# 20 rshift  h# 8300 or  smm-eax w!  endof
+         h#  211 of  d# 1199 smm-eax w!  endof
+         h#  217 of  d#  899 smm-eax w!  endof
+         h# 1201 of  cpu-mhz smm-eax w!  endof
+         ( default )  ." VR Read " dup .   false to exit-interact?  interact
+      endcase
+   then
+;
+: gliu0-smi  ( event-mask -- )
+   1 and 0=  if  exit  then     \ We only care about virtual register accesses
+
+   smm-io-port h# fff0 and  h# 30 =  if
+      smm-io-port h# 20 -  to rm-int@
+      rm-sp la1+ >caller-physical w@  smm-rmeflags w!
+      handle-bios-call
+      smm-rmeflags w@  rm-sp la1+ >caller-physical w!
+      exit
+   then
+
+   smm-io-port h# fffd and  h# ac1c <>  if  exit  then
+   do-vr
+;
+
+defer quiesce-devices  ' noop to quiesce-devices
+
+\ 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  ;
+
+: 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 h# 2000 and  if                              ( value offset )
+      drop  d# 10 rshift  7 and case                 ( c:power-state )
+         5 of  power-off  endof                      ( )
+         ( default )  ." Requested power state " dup .
+      endcase                                        ( )
+   else                                              ( value offset )
+      acpi-w!                                        ( )
+   then                                              ( )
+;
+
+: divil-smi  ( event-mask -- )  h# 80 and  if  bye  then  ;
+
+: sb-smi  ( event-mask -- )
+   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
+\      0 acpi-l@ 1 and  if  0 acpi-l@  0 acpi-l!  exit  else  interact  then
+      exit
+   then
+
+   smm-io-port h# 9c00 -          ( acpi-offset )
+   dup h# 40 u>= if
+      drop
+      ." I/O " smm-io-port .  interact
+      exit
+   then                           ( acpi-offset )
+
+[ifdef] notdef
+   dup h# 3c =  if                ( acpi-offset )
+      drop                        ( )
+      smm-flags 2 and  if         
+         smm-eax c@  case
+            h# a1 =  of  8 acpi-w@  1 or          8 acpi-w!  endof
+            h# a2 =  of  8 acpi-w@  1 invert and  8 acpi-w!  endof
+         endcase
+      then
+      exit
+   then
+[then]
+
+   smm-flags 2 and  if  \ Write   ( acpi-offset offset )
+      smm-eax l@  swap            ( value acpi-offset )
+      smm-io-size case
+         1 of                     ( value acpi-offset )
+              acpi-b!
+              \ ." W8 " smm-io-port .  smm-eax c@ .  cr  
+              \ smm-io-port h# 9c1f =  smm-eax c@ h# c0 =  and  if  debug-me  then
+         endof
+         3 of                     ( value acpi-offset )
+              dup case   ( value acpi-offset [acpi-offset] )
+                 \ 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
+                 8 of  power-mode  endof
+                 ( default: value port-adr acpi-offset )  -rot acpi-w!
+              endcase
+              \ ." W16 " smm-io-port .  smm-eax w@ . cr
+         endof
+         h# f of
+              dup 8 =  if  power-mode  else  acpi-l!  then
+              \ ." W32 " smm-io-port .  smm-eax w@ .  cr
+         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
+         endof
+         3 of                     ( acpi-offset )
+               acpi-w@  smm-eax w!
+               \ ." R16 " smm-io-port .  smm-eax w@  .  cr
+               \ smm-io-port h# 9c00 =  if  ." ."  then
+         endof
+         h# f of                  ( acpi-offset )
+               acpi-l@  smm-eax l!
+               \ 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
+
+: .9x  push-hex  9 u.r  pop-base  ;
+: .smir   ( n -- )   smm-gregs swap la+  l@ .9x  ;
+: .smiregs   ( -- )
+   ."       EAX      EBX      ECX      EDX      ESI      EDI      EBP      ESP" cr
+        7 .smir  4 .smir  6 .smir  5 .smir  1 .smir  0 .smir  2 .smir  smm-save-esp +smm l@ .9x
+   cr
+   ." CS: " smm-cs-sel 5 u.r
+   ."  DS: " smm-sregs 6 + w@ 5 u.r
+   ."  ES: " smm-sregs 4 + w@ 5 u.r
+   ."  FS: " smm-sregs 2 + w@ 5 u.r
+   ."  GS: " smm-sregs 0 + w@ 5 u.r
+   ."  SS: " smm-save-ss +smm w@ 5 u.r
+   cr
+;
+: .smipc  ( -- )  ." SMI at " smm-pc .9x cr ;
+' .smipc to sbp-hook
+
+: .callto  ( retadr -- )
+   dup  ['] smm>physical  catch  if  2drop exit  then  ( retadr pretadr )
+   dup 5 - c@ h# e8 <>  if  2drop exit  then           ( retadr pretadr )
+   4 - l@ + 9 u.r
+;
+: smm-trace  ( -- )
+   ."      EBP   RETADR   CALLTO" cr
+   smm-ebp
+   begin  ?dup  while                           ( ebp )
+      dup 8 u.r  smm>physical                   ( padr )
+      dup la1+ l@ dup 9 u.r  .callto  cr        ( padr )
+      l@                                        ( ebp' )
+   repeat
+;
+
+: fixsbp  ( -- )
+   sbpadr @  if
+      sbpval @  sbpadr @ smm>physical  w!
+      sbpadr off
+   then
+;
+
+: unboost  ( adr -- adr' )  h# 7fff.ffff and  ;
+: sbp  ( adr -- )
+   fixsbp
+   dup smm>physical w@  sbpval !  dup sbpadr !
+   h# 380f swap smm>physical w!
+;
+: sdis  ( -- )  smm-pc smm>physical dis  ;
+: sgo  ( -- )  smm-pc smm-next-eip!   resume  ;
+
+h# 806f1a41 constant 'bioscall
+: hack-fix-mode  ( -- )
+   'bioscall smm>physical  5  h# 90  fill   \ Nop-out "call hal!HalpBiosCall" that dies
+   'bioscall sbp
+;
+
+: l!++  ( adr l -- adr' )  over l!  la1+  ;
+: w!++  ( adr w -- adr' )  over w!  wa1+  ;
+
+code rm-lidt  ( -- )  smm-rmidt #) lidt  c;
+
+: rm-setup  ( eip -- )
+   >seg:off 2>r   ( r: off seg )
+
+   smm-header h# 30 -
+   h#      38  l!++          \ SMM_CTL
+   0           l!++          \ I/O DATA
+   0           l!++          \ I/O ADDRESS, I/O SIZE
+   h#  938009  l!++          \ SS_FLAGS, SMM Flags
+   h#    ffff  l!++          \ CS_LIMIT
+   r@ 4 lshift l!++          \ CS_BASE
+   r>  h# 9a wljoin l!++     \ CS_FLAGS.CS_INDEX
+   r>          l!++          \ NEXT_IP
+   0           l!++          \ CURRENT_IP
+   h# 10       l!++          \ CR0
+   h# 2        l!++          \ EFLAGS
+   h# 400      l!++          \ DR7
+   drop
+
+   smm-sregs 4 /w* erase  smm-gregs 8 /l* erase
+   0 smm-save-esp +smm  l!
+
+   smm-save-seg +smm
+   h# ffff l!++  h# 9300 l!++  0 w!++  \ DS
+   h# ffff l!++  h# 9300 l!++  0 w!++  \ ES
+   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
+
+   h# ffff smm-rmidt w!  0 smm-rmidt wa1+ l!  \ Limit and base
+
+   \ Interrupts are off because we are in SMM
+   rm-lidt
+;
+\ : rm-init-program   ( eip -- )  rm-init-program  rm-return  ;
+
+-1 value rm-entry-adr
+: rm-run  ( eip -- )  to rm-entry-adr  smi  ;
+
+: soft-smi  ( -- )
+   rm-entry-adr -1 <>  if
+      rm-entry-adr  rm-setup
+      -1 to rm-entry-adr
+      exit
+   then
+
+   sbpadr @  if
+      sbpadr @ smm>physical  smm-pc smm>physical <>  if
+         ." Not at SMI breakpoint!" cr
+         .smipc
+         .smiregs
+      else
+         fixsbp
+      then
+      sbp-hook
+   then
+
+smm-pc 'bioscall =  if  " set-mode12" eval  sgo  else
+   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)
+\  8022 (Mem Write) - port 92 write
+
+\ : msr@!  ( msr# -- d.value )  >r r@ msr@  2dup r> msr!  ;
+: smi-dispatch  ( -- )
+   smm-flags h#  8 and       if   soft-smi  then
+
+\ CPU chip SMIs
+   h# 5000.2003 msr-sense16  if    pci-smi  then
+
+\  Commented-out lines are for devices we don't enable for SMIs
+   h# 8000.2003 msr-sense32  if     dc-smi  then
+\  h# a000.2003 msr-sense32  if     gp-smi  then
+\  h# 5400.2003 msr-sense16  if    vip-smi  then
+\  h# 5800.2003 msr-sense32  if    aes-smi  then
+\  h# 4c00.2003 msr-sense16  if   glcp-smi  then  \ Companion SMI isn't clearable
+
+   h# 1000.2003 msr-sense32  if  gliu0-smi  then  \ Virtual register
+\  h# 4000.2003 msr-sense32  if  gliu1-smi  then  \ Incoming cycles
+
+\ Companion chip (5536) SMIs
+
+   h# 5140.0003 msr-sense32p if  divil-smi  then
+   h# 5100.0003 msr-sense16p if     sb-smi  then
+   h# 5101.0003 msr-sense32  if  cgliu-smi  then
+\  h# 5170.0003 msr-sense16  if  cglcp-smi  then
+
+\   smm-flags h# 80 and  if  virtualize-io  then
+;
+' smi-dispatch is handle-smi
+
+: .dt  ( adr limit -- )
+   1+  8 max  8  ?do                     ( gdt-adr )
+      dup i + d@  dup  if                ( gdt-adr descr )
+         i 3 u.r space .descriptor cr    ( gdt-adr )
+      else                               ( gdt-adr descr )
+         2drop                           ( gdt-adr )
+      then                               ( gdt-adr )
+   8 +loop                               ( gdt-adr )
+   drop
+;
+
+: .smm-gdt  ( -- )
+   smm-save-gdt +smm  dup 2+ l@ smm>physical  ( 'gdt gdt-adr )
+   swap w@                               ( gdt-adr gdt-limit )
+   .dt                                   ( )
+;
+
+
 : 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
@@ -230,57 +868,131 @@
    smm-rp0 smm-save-rp0 !
 
    enable-virtual-pci
+   enable-io-smis
 ;
 
-: smi-interact  ( -- )  ." In SMI" cr  quit  ;
-' smi-interact is handle-smi
+0 [if]
+SMI sources:
+LX:
 
-\ : 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-regs la1+ @ h# 7fff.fffc and
-   smm-io-port 3 and  or
-;
-: smm-eax       ( -- adr )  smm-regs 9 la+  ;
++ 5000.2002   Virtual PCI header is 8.0000,  MPCI_ERROR is 17.0000  \ PCI bridge
+    clear errors 5000.2003
++ 8000.2002   Display Controller  - many bits, for SoftVGA
+    clear errors 8000.2003
+* 1000.2002   statistics is 1e.0000, VR is 1.0000
+    clear errors 1000.2003
+* 4000.2002   statistics is 1e.0000, VR is 1.0000
+    clear errors 1000.2003
 
-: vr-spoof?  ( -- handled? )  false  ;
-: config-spoof?  ( -- handled? )
-   smm-io-port 3 invert and  h# cfc <>  if  false exit  then
+5536:
++ 5140.0002  16 bits for HLT, SHTDWN, KEL, PIC, PM, KEL_INIT, PORTA_A20, PORTA_INIT, UART1/2, LPC, DMA, KEL_A20, PM2/1_CNT
+     clear errors 5140.0003
 
-   \ The existing Forth config spoofer does the hard work
-   smm-flags 2 and  if  \ Write
-      smm-io-data  smm-config-adr   ( data config-adr )
-      smm-io-size case
-         1 of  config-b!  endof
-         3 of  config-w!  endof
-         f of  config-l!  endof
-      endcase
-   else
-      smm-config-adr                 ( config-adr )
-      smm-io-size case
-         1 of  config-b@ smm-eax c!  endof
-         3 of  config-w@ smm-eax w!  endof
-         f of  config-l@ smm-eax l!  endof
-      endcase
-   then
-   true
+  5100.0002 (PCI SouthBridge) - VSA just clears the SMIs in this register and uses the next register for dispatch
+     clear errors 5100.0003
+   
+* 5101.0002 (5536 GLIU) - virtual register is 1.0000.0000, statistics is 1e.0000.0000
+     clear errors 5101.0003
+   
+VSA collects events from + and * registers
+
+For the * registers, it uses a common subroutine that ORs together all the
+1.0000.0000 bits to make a combined "virtual I/O" event, and saves the
+statistics bits for each register separately.
+
+It is important to clear (ack) all the SMI and error bits to prevent re-entering the SMI handler
+due to unhandled conditions.
+
+PCI BARs:
+  810 0000ac1d  northbridge
+
+  910 fd000000  FB  914 fe000000  GP   918 fe004000 VG   91c  fe008000 DF  920 fe00c000 VIP
+      be000000          bc000000  PW       bfff8000 9         bfff0000         bffec000
+
+ a10 fe010000  aes
+
+80007810 000018b1  ISA
+80007b10 00001481  AC97
+80007c10 fe01a000  ohci
+80007d10 fe01b000  ehci
+
+  bar 910
+  msr: 0000.1810 fdfff000.fd000111.  \ Video (write through), fbsize
+\ msr: 1000.0029 20a7e0fd.ffffd000.  \ fd00.0000 - fdff.ffff mapped to f00.0000 Memsize dependent, fbsize dependent
+  msr: 4000.002a 200000fd.ffffd000.  \ frame buffer - fd00.0000 .. fdff.ffff, route to GLIU0, fbsize
+
+  msr: a000.2001 00000000.0fde0000.  \ CBASE field is FB addr + 14M, fbsize
+
+  bar 914
+  msr: 0000.1811 fe003000.fe000101.  \ GP registers non-cacheable
+  msr: 1000.0022 a00000fe.000ffffc.  \ fe00.0000 - fe00.3fff GP
+  msr: 4000.0022 200000fe.000ffffc.  \ fe00.0000 - fe00.03ff GP, route to GLIU0
+
+  bar 918
+  msr: 0000.1812 fe007000.fe004101.  \ DC registers non-cacheable
+  msr: 1000.002a 801ffcfe.007fe004.  \ fe00.4000 - fe00.7fff mapped to 0 in DC space
+  msr: 4000.0024 200000fe.004ffffc.  \ fe00.4000 - fe00.7fff DC, route to GLIU0
+
+  bar 91c
+  msr: 0000.1813 fe00b000.fe008101.  \ VP registers non-cacheable
+  msr: 1000.0023 400000fe.008ffffc.  \ fe00.8000 - fe00.bfff VP in GLIU1
+  msr: 4000.0025 400000fe.008ffffc.  \ fe00.8000 - fe00.bfff VP, route to VP in GLIU1
+
+  bar 920
+  msr: 0000.1814 fe00f000.fe00c101.  \ VIP registers non-cacheable
+  msr: 1000.0024 400000fe.00cffffc.  \ fe00.8000 - fe00.bfff VIP in GLIU1
+  msr: 4000.0026 a00000fe.00cffffc.  \ fe00.c000 - fe00.ffff VIP, route to VIP in GLIU1
+
+
+
+  a10
+  msr: 0000.1815 fe013000.fe010101.  \ AES registers non-cacheable
+  msr: 1000.0025 400000fe.010ffffc.  \ fe01.0000 - fe01.3fff security block in GLIU1
+  msr: 4000.002b c00000fe.013fe010.  \ Security Block - fe01.0000 .. fe01.3fff
+
+  bar 7c10
+  msr: 5100.0027 fe01a000.fe01a001.  \ OHCI             Rconf
+  msr: 5140.0009 fffff001.fe01a000.  \ LBAR_KEL (USB)
+  msr: 5120.0008 0000000e.fe01a000.  \ USB OHC Base Address - 5536 page 266  P2D-Range
+  msr: 5101.0023 500000fe.01afffff.  \ P2D_BMK Descriptor 0 OHCI
+
+  bar 7d10
+  msr: 5100.0028 fe01b000.fe01b001.  \ EHCI
+  msr: 5101.0024 400000fe.01bfffff.  \ P2D_BMK Descriptor 1 EHCI
+  msr: 5120.0009 0000200e.fe01b000.  \ USB EHC Base Address - 5536 page 266 FLADJ set
+
+  msr: 5100.0029 efc00000.efc00001.  \ UOC
+  msr: 5101.0020 400000ef.c00fffff.  \ P2D_BM0 UOC
+  msr: 5120.000b 00000002.efc00000.  \ USB UOC Base Address - 5536 page 266
+
+
+[then]
+
+\  setup-rm-gateway  ( -- ) Init this module
+\  caller-regs  ( -- adr )  Base address of incoming registers
+\  rm-int@      ( -- n )    Incoming interrupt number
+\  rm-buf       ( -- adr )  Base address of a real-mode accessible buffer
+\  rm-init-program  ( eip -- )  Setup to enter real mode program on next rm-return
+\  rm-return    ( -- )      Resume execution of real-mode caller.  Returns when program does a BIOS INT.
+\ Sequence:
+\  setup-rm-gateway  ( eip ) rm-enter  begin  handle-bios-call rm-return  again
+
+
+: setup-rm-gateway  ( -- )
+   int-entry  'int10-dispatch  /int-entry move   
+
+   \ Prime with unused interrupt 1f
+   h# 100  0  do
+      'int10-dispatch h# f la+  i /l*  seg:off!
+   loop
+
+   h# 10  0  do
+      'int10-dispatch i la+  h# 10 i + /l*  seg:off!
+   loop
 ;
-: virtualize-io  ( -- )
-   smm-flags h# 80 and  0=  if  exit  then
-   config-spoof?  if  exit  then
-   vr-spoof?  if  exit  then
-;
-: soft-smi  smi-interact  ;
-: smi-dispatch  ( -- )
-   smm-flags h# 80 and  if  virtualize-io  then
-   smm-flags h#  8 and  if  soft-smi       then
-;
-' smi-dispatch is handle-smi
 
-code smi  smint  c;
+
+\ : caller-regs  ( -- adr )  smm-sregs  ;
+\ : rm-buf  ( -- adr )  smm-rmbuf  ;
+
+\ : doit  setup-smi disk-name open-dev is disk-ih get-mbr usb-quiet  ff 21 pc! h# 380f  h# 7c18 w!  smi ;

Modified: dev/geode/usb.fth
===================================================================
--- dev/geode/usb.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/geode/usb.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -104,29 +104,29 @@
    : close ;
 end-package
 
+: ohci-phys-l!  ( l offset -- )  ohci-pci-base + l!  ;
 stand-init: USB setup
    \ Set up an address routing to the USB Option Controller
-   h# efc00000.efc00001. h# 5100.0029 wrmsr
-   h# 400000ef.c00fffff. h# 5101.0020 wrmsr
-   h# 00000002.efc00000. h# 5120.000b wrmsr
+   uoc-pci-base  h# 1000 1  h# 5100.0029  set-rconf
+   uoc-pci-base  h# 1000 4  h# 5101.0020  set-p2d-bm
+   uoc-pci-base  2          h# 5120.000b  msr!
 [ifdef] virtual-mode
-   h# efc00000 h# 1000 0 mmu-claim drop  \ UOC
-   h# efc00000 dup h# 1000 -1 mmu-map    \ UOC
-   h# fe01a000 h# 1000 0 mmu-claim drop  \ OHCI
-   h# fe01a000 dup h# 1000 -1 mmu-map    \ OHCI
+   uoc-pci-base  h# 1000 map-v=p   \ UOC
+   ohci-pci-base h# 1000 map-v=p   \ OHCI
 [then]
    \ Configure the assignment of 2 USB Power Enable pins to USB ports
    \ to correspond to the way they are wired on the board.
    \ USB port 1 is PWR_EN2, USB ports 2-4 are PWR_EN1
-   usb-port-power-map h# efc00000 l!
-   2 h# efc00004 l!
-   h#       1 h# fe01a008 l!   \ Reset OHCI host controller
-   h# 1e.0000 h# fe01a04c l!   \ Configure ports for individual power
-   h#     100 h# fe01a058 l!   \ Power-on ports 2 and 3
+   usb-port-power-map  uoc-pci-base      l!
+   2                   uoc-pci-base 4 +  l!
+
+   h#       1 h# 08 ohci-phys-l!   \ Reset OHCI host controller
+   h# 1e.0000 h# 4c ohci-phys-l!   \ Configure ports for individual power
+   h#     100 h# 58 ohci-phys-l!   \ Power-on ports 2 and 3
    d# 10 ms                    \ Stagger for glitch-prevention
-   h#     100 h# fe01a054 l!   \ Power-on port 1
-   h#     100 h# fe01a05c l!   \ Power-on port 3
-   h#     100 h# fe01a060 l!   \ Power-on port 4
+   h#     100 h# 54 ohci-phys-l!   \ Power-on port 1
+   h#     100 h# 5c ohci-phys-l!   \ Power-on port 3
+   h#     100 h# 60 ohci-phys-l!   \ Power-on port 4
    get-msecs d# 1000 +  to usb-power-done-time
 ;
 

Modified: dev/mmc/sdhci/sdhci.fth
===================================================================
--- dev/mmc/sdhci/sdhci.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/mmc/sdhci/sdhci.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -165,18 +165,23 @@
 
 : data-timeout!  ( n -- )  h# 2e cb!  ;
 
+: intstat-on  ( -- )
+   h# 000b h# 34 cw!  \ normal interrupt status en reg
+            \ Enable: DMA Interrupt, Transfer Complete, CMD Complete
+            \ Disable: Card Interrupt, Remove, Insert, Read Ready,
+            \ Write Ready, Block Gap
+   h# f1ff h# 36 cw!  \ error interrupt status en reg
+;
+: intstat-off  ( -- )  h# 0 h# 34 cl!  ;  \ All interrupts off
+
 : setup-host  ( -- )
    reset-host
    internal-clock-on
 
    h#   00 h# 28 cb!  \ Not high speed, 1-bit data width, LED off
-   h# 000b h# 34 cw!  \ normal interrupt status en reg
-            \ Enable: DMA Interrupt, Transfer Complete, CMD Complete
-            \ Disable: Card Interrupt, Remove, Insert, Read Ready,
-            \ Write Ready, Block Gap
-   h# f1ff h# 36 cw!  \ error interrupt status en reg
    h# 0000 h# 38 cw!  \ Normal interrupt status interrupt enable reg
    h# 0000 h# 3a cw!  \ error interrupt status interrupt enable reg
+   intstat-on
 
    clear-interrupts
 ;
@@ -297,12 +302,13 @@
 
 \ Store in the buffer in little-endian form
 : get-response136  ( buf -- )  \ 128 bits (16 bytes) of data.
+    h# 1f  h# 10  do  i cb@ over c! 1+  loop  drop
 \   h# 20  h# 10  do  i cl@ buf+!  4 +loop  drop
-    >r
-    h# 1c cl@  8 lshift  h# 1b cb@ or  r@ 0 la+ l!
-    h# 18 cl@  8 lshift  h# 17 cb@ or  r@ 1 la+ l!
-    h# 14 cl@  8 lshift  h# 13 cb@ or  r@ 2 la+ l!
-    h# 10 cl@  8 lshift                r> 3 la+ l!
+\     >r
+\     h# 1c cl@  8 lshift  h# 1b cb@ or  r@ 0 la+ l!
+\     h# 18 cl@  8 lshift  h# 17 cb@ or  r@ 1 la+ l!
+\     h# 14 cl@  8 lshift  h# 13 cb@ or  r@ 2 la+ l!
+\     h# 10 cl@  8 lshift                r> 3 la+ l!
 ;
 
 d# 64 instance buffer: scratch-buf
@@ -449,7 +455,7 @@
    false to mmc?
    true to allow-timeout?
 
-   \ SD version 2 adds CMD3.  Pre-v2 cards will time out.
+   \ SD version 2 adds CMD8.  Pre-v2 cards will time out.
    false to timeout?  send-if-cond      (  )
    timeout?   if  h# 0030.0000  else  h# 4030.0000  then  to oc-mode
 
@@ -496,6 +502,7 @@
    then
 ;
 
+[ifdef] notdef
 \ Extract bit fields from CSD or CID  (adr is either csd or cid)
 : @bits   ( bit# #bits adr -- bits )
    rot 8 -                     ( #bits adr bit# )  \ -8 accounts for elided CRC
@@ -517,6 +524,7 @@
       1 swap lshift 1-  and    ( bits )
    then                        ( bits )
 ;
+[then]
 
 0 instance value writing?
 
@@ -539,17 +547,18 @@
 external
 
 : attach-card  ( -- okay? )
+   intstat-on
    card-power-off d# 20 ms
 
    card-power-on  d# 20 ms  \ This delay is just a guess
 
-   card-inserted?  0=  if  card-power-off  false exit  then   
+   card-inserted?  0=  if  card-power-off  false intstat-off  exit  then   
 
    card-clock-slow  d# 10 ms  \ This delay is just a guess
 
    reset-card     \ Cmd 0
 
-   set-operating-conditions  if  false exit  then
+   set-operating-conditions  if  false intstat-off  exit  then
 
    get-all-cids   \ Cmd 2
    mmc?  if
@@ -568,6 +577,7 @@
 
    set-timeout
 
+   intstat-off
    true
 ;
 
@@ -575,6 +585,7 @@
 : dma-free    ( vadr size -- )  " dma-free"   $call-parent  ;
 
 : r/w-blocks  ( addr block# #blocks in? -- actual )
+   intstat-on
    >r               ( addr block# #blocks r: in? )
    rot dma-setup    ( block# r: in? )
    wait-write-done
@@ -586,6 +597,7 @@
    2 wait
    dma-release
    dma-len /block /
+   intstat-off
 ;
 
 0 value open-count
@@ -600,6 +612,7 @@
 
 : close  ( -- )
    open-count  1 =  if
+      intstat-on
       wait-write-done
       card-clock-off
       card-power-off
@@ -617,6 +630,41 @@
    unmap-regs
 ;
 
+\ The bit numbering follows the table on page 78 of the
+\ SD Physical Layer Simplified Specification Version 2.00.
+
+\ The "8 -" accounts for the fact that the chip's response
+\ registers omit the CRC and tag in bits [7:0]
+: csdbit  ( bit# -- b )
+   8 -
+   dup 3 rshift csd +  c@   ( bit# byte )
+   swap 7 and rshift 1 and
+;
+: csdbits  ( high low -- bits )
+   swap 0 -rot  do  2*  i csdbit  or  -1 +loop
+;
+
+\ The calculation below is shown on page 81 of the
+\ SD Physical Layer Simplified Specification Version 2.00.
+: size  ( -- d.bytes )
+   d# 128 d# 126 csdbits  case
+      0 of
+         d# 49 d# 47 csdbits      ( c_size_mult )
+         2 +  1 swap  lshift      ( mult )
+
+         d# 73 d# 62 csdbits  1+  ( mult c_size+1 )
+         *                        ( blocknr )
+
+         d# 83 d# 80 csdbits  1 swap lshift  ( blocknr block_len )
+         um*
+      endof
+      1 of
+         d# 70 d# 48 csdbits  d# 10 lshift  h# 200  um*
+      endof
+      ( default )
+      h# ffffffff 0  rot
+   endcase
+;
 external
 
 \ LICENSE_BEGIN

Modified: dev/mmc/sdhci/sdmmc.fth
===================================================================
--- dev/mmc/sdhci/sdmmc.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/mmc/sdhci/sdmmc.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -62,9 +62,8 @@
 
 : block-size  ( -- n )  h# 200  ;
 
-: #blocks  ( -- true | n false )   \ XXX Decode CSD
-   \ " csd" $call-parent  csd>#blocks  false
-   true   
+: #blocks  ( -- n )
+   " size" $call-parent  block-size um/mod  nip
 ;
 : seek  ( offset.low offset.high -- okay? )
    offset-low offset-high d+  " seek"   deblocker $call-method

Modified: dev/olpc/keyboard/selftest.fth
===================================================================
--- dev/olpc/keyboard/selftest.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/olpc/keyboard/selftest.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -165,6 +165,7 @@
 ( 68 ) 152 c, 154 c,   0 c,   0 c,   0 c,   0 c, 135 c,   0 c,  \ 69 is rotate
 ( 70 )   0 c,   0 c,   0 c,  56 c,   0 c,   0 c,   0 c,   0 c,
 ( 78 )   0 c, 130 c,   0 c,   0 c,   0 c,   0 c,   0 c,   0 c,
+hex
 
 \ This should be a lookup table.  It would be smaller that way
 : e0-scan1>ibm#  ( scancode -- ibm# )
@@ -274,6 +275,7 @@
    154 c,                             \ Rotate
    156 c, 157 c, 158 c, 159 c,        \ Game O, square, check, X
 here ibm#s - constant /ibm#s
+hex
 
 : ibm#>key#  ( ibm# -- true | key# false )
    /ibm#s 0  ?do   ( ibm# )

Added: dev/pci/intmap.fth
===================================================================
--- dev/pci/intmap.fth	                        (rev 0)
+++ dev/pci/intmap.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,90 @@
+purpose: Interrupt mapping support functions
+\ See license at end of file
+
+headerless
+: pin,dev>isa-irq  ( pin# dev# -- true | irq-irq# false )
+   " slot-map" $call-self                  ( pin# dev# adr )
+   begin  dup c@  ff <>  while             ( pin# dev# adr )
+      2dup c@ =  if                        ( pin# dev# adr )
+         nip 1+ + c@ false exit
+      then                                 ( pin# dev# adr )
+      5 +                                  ( pin# dev# adr' )
+   repeat                                  ( pin# dev# adr' )
+   3drop true
+;
+
+0 value interrupt-parent
+
+headers
+1  " #interrupt-cells" integer-property
+0 0 encode-bytes  0000.f800 +i  0+i  0+i  7 +i  " interrupt-map-mask" property
+
+headerless
+: +map  ( adr len dev# int-pin# int-level -- adr' len' )
+   >r >r                           ( $ dev# R: level pin )
+   h# 800 *  +i                    ( $' R: level pin )
+   0+i 0+i  r> +i                  ( $' R: level )
+   interrupt-parent +i             ( $' R: level )
+   r> +i  1 +i                     ( $' )
+;
+
+headers
+external
+
+: make-isapic-interrupt-map  ( -- )
+   " /isa/interrupt-controller" find-package  0=  if  exit  then  to interrupt-parent
+
+   0 0 encode-bytes
+
+   " slot-map" $call-self                    ( adr )
+   begin  dup c@  h# ff <>  while            ( adr )
+      \ Each table entry contains dev#,pin1,pin2,pin3,pin4
+      \ We loop over the pin numbers and create map entries for each
+      \ valid pin entry.
+      5 1  do                                ( adr ) 
+         dup i + c@  h# ff <>  if            ( adr )
+            i swap >r                        ( pin# R: adr )
+            r@ c@  swap  dup r@ + c@  +map   ( R: adr )
+            r>                               ( adr )
+         then                                ( adr )
+      loop                                   ( adr )
+      5 +                                    ( adr' )
+   repeat                                    ( adr )
+   drop
+
+   " interrupt-map" property
+;
+
+: assign-int-line  ( phys.hi.func int-pin -- false | int-line true )
+   dup 0=  if  2drop false  exit  then               ( phys.hi.func int-pin# )
+   1-  swap d# 11 rshift  h# 1f and                  ( int-pin0 dev# )
+
+   \ Bail out for non-existent device IDs
+   pin,dev>pic-irq  if  false exit  then             ( opic-int# )
+
+   true
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END

Modified: dev/video/common/textmode.fth
===================================================================
--- dev/video/common/textmode.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/video/common/textmode.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -100,6 +100,26 @@
    " "(5f 4f 50 82 55 81 bf 1f 00 4f 0d 0e 00 00 00 00 9c 8e 8f 28 1f 96 b9 a3 ff)"
    place-string				\ CRT registers
 
+create mode12-table
+\  h# 67 c,
+\   h# e7 c,  \ Maybe c7
+   h# e3 c,
+
+   " "(00 01 0f 00 06)"   \ use 0e instead of 06 for mode 13
+   place-string				\ Sequencer registers
+
+   " "(00 01 02 03 04 05 14 07 38 39 3a 3b 3c 3d 3e 3f 01 00 0f 00 00)"
+   place-string				\ Attribute registers
+
+\   " "(00 00 00 00 00 40 05 0f ff)"
+   " "(00 00 00 00 00 00 05 0f ff)"
+   place-string				\ Graphics registers
+
+   " "(5f 4f 50 82 54 80 bf 3e 00 40 00 00 00 00 00 59 ea 0c df 28 00 e7 04 e3 ff)"
+\  " "(5f 4f 50 82 54 80 0b 3e 00 40 00 00 00 00 07 80 ea 0c df 50 00 e7 04 e3 ff)"
+   place-string				\ CRT registers
+
+
 : plane-mode     ( -- )  6 4 seq!  c 6 grf!  ;
 : odd/even-mode  ( -- )  2 4 seq!  e 6 grf!  ;
 [ifdef] testing
@@ -178,7 +198,14 @@
    ega-colors  0  d# 64  (set-colors)
 [then]
 ;
+0 value vga
+: graphics-mode12  ( -- )
+   io-base -1 =  if  map-io-regs  then
+   mode12-table set-vga-mode
+   h# 000a.0000 0  h# 8200.0000  h# 10000  " map-in" $call-parent  to vga
+;
 
+
 \ LICENSE_BEGIN
 \ Copyright (c) 2006 FirmWorks
 \ 

Modified: dev/video/controlr/vga.fth
===================================================================
--- dev/video/controlr/vga.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ dev/video/controlr/vga.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -116,12 +116,59 @@
    2 4 seq!				\ Enable video memory past 256K
 ;
 
+h# 20 buffer: crtcbuf
+: crtc@  ( index -- value )  crtcbuf + c@  ;
+
+: .vga-mode  ( -- )
+   push-decimal
+   ." HTotal:      "  0 crtc@  4 u.r  cr
+   ." HDispEnd:    "  1 crtc@  4 u.r  cr
+   ." HBlankStart: "  2 crtc@  4 u.r  cr
+   ." HBlankEnd:   "  3 crtc@ h# 1f and  5 crtc@ h# 80 and 2 rshift or  4 u.r  cr
+   ." HSyncStart:  "  4 crtc@  4 u.r  cr
+   ." HSyncEnd:    "  5 crtc@ h# 1f and  4 u.r  cr
+   ." VTotal:      "  6 crtc@  7 crtc@ 1 and 7 lshift or  7 crtc@ h# 20 and 4 lshift or  4 u.r  cr
+   ." BytePan:     "  8 crtc@  5 rshift  4 u.r  cr
+   ." PresetRowScn:"  8 crtc@  h# 1f and  4 u.r  cr
+   ." DoubleScan:  "  9 crtc@  7 rshift  4 u.r  cr
+   ." MaxScan:     "  9 crtc@  5 rshift  4 u.r  cr
+   ." CursorOff:   "  h# a crtc@  5 rshift  1 and  4 u.r  cr
+   ." CursorStart: "  h# a crtc@  h# 1f and  4 u.r  cr
+   ." CursorSkew:  "  h# b crtc@  5 rshift  7 and  4 u.r  cr
+   ." CursorEnd:   "  h# b crtc@  h# 1f and  4 u.r  cr
+   ." StartAddress:"  h# d crtc@  h# c crtc@ bwjoin 4 u.r cr
+   ." CursorLoc:   "  h# f crtc@  h# e crtc@ bwjoin 4 u.r cr
+   ." VSyncStart:  "  h# 10 crtc@  7 crtc@ 4 and 6 lshift or  7 crtc@ h# 80 and 2 lshift or  4 u.r  cr
+   ." VSyncEnd:    "  h# 11 crtc@ h# f and  4 u.r cr
+   ." WriteProtect:"  h# 11 crtc@ 7 rshift  4 u.r cr
+   ." VDispEnd:    "  h# 12 crtc@  7 crtc@ 2 and 7 lshift or  7 crtc@ h# 40 and 3 lshift or  4 u.r  cr
+   ." Offset:      "  h# 13 crtc@  4 u.r  cr
+   ." DoubleWord:  "  h# 14 crtc@  6 rshift 1 and  4 u.r  cr
+   ." UnderlineLoc:"  h# 14 crtc@  h# 1f and  4 u.r  cr
+   ." VBlankStart: "  h# 15 crtc@  7 crtc@ 8 and 5 lshift or  9 crtc@ h# 20 and 4 lshift or  4 u.r  cr
+   ." VBlankEnd:   "  h# 16 crtc@  4 u.r  cr
+   ." EnableSyncs: "  h# 17 crtc@  7 rshift 4 u.r  cr
+   ." ByteMode:    "  h# 17 crtc@  6 rshift 1 and 4 u.r  cr
+   ." AddressWrap: "  h# 17 crtc@  5 rshift 1 and 4 u.r  cr
+   ." VCLKSelect:  "  h# 17 crtc@  2 rshift 1 and 4 u.r  cr
+   ." SelectRowScn:"  h# 17 crtc@  1 rshift 1 and 4 u.r  cr
+   ." SelectA13:   "  h# 17 crtc@  1 and 4 u.r  cr
+   ." LineCompare: "  h# 18 crtc@  4 u.r  cr
+   pop-base
+;
+: showmode  ( adr len -- )   crtcbuf swap move  .vga-mode  ;
+
 instance defer crt-table
-: (vga-crt-table)
+: (mode12-crt-table)
+   \ AMD recommended values for mode 12
+   " "(5f 4f 50 82 51 9e 0b 3e 00 40 00 00 00 00 00 00 e9 8b df 28 00 e7 04 e3 ff)"
+;
+: (vga-crt-table)  \ 640x480, byte mode
    " "(5f 4f 50 82 54 80 0b 3e 00 40 00 00 00 00 07 80 ea 0c df 50 00 e7 04 e3 ff)"
-
+;
+\ : vga-400-crt-table
 \  " "(5f 4f 50 82 54 80 bf 1f 00 41 00 00 00 00 00 31 9c 0e 8f 28 40 96 b9 a3 ff)"
-;
+\ ;
 ' (vga-crt-table) to crt-table
 
 : crt  ( adr len -- )

Modified: ofw/fs/fatfs/partition.fth
===================================================================
--- ofw/fs/fatfs/partition.fth	2008-07-01 08:18:34 UTC (rev 842)
+++ ofw/fs/fatfs/partition.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -37,17 +37,17 @@
    \ Look for at least one recognizable partition type code
    ptable-bounds  do
       i 4 + c@                                        ( type )
-      dup 1 =
-      over 4 6 between or
+      dup 1 =                   \ FAT12
+      over 4 7 between or       \ 4: FAT16<32M  5: Extended 6: FAT16>32M 7: NTFS
       over h#  b =     or	\ FAT-32
       over h#  c =     or	\ FAT-32
       over h#  e =     or	\ FAT-16 LBA
       over h#  f =     or	\ Extended LBA
-      over h# 41 =     or
-      over iso-type =  or
-      over minix-type =  or
-      over ufs-type =  or
-      swap ext2fs-type =  or                             ( recognized? )
+      over h# 41 =     or       \ PowerPC PreP
+      over iso-type =  or       \ ISO9660
+      over minix-type =  or     \ Minix
+      over ufs-type =  or       \ Unix file system
+      swap ext2fs-type =  or    \ Linux ext2/3, reiser, etc  ( recognized? )
       if  i 4 + c@ to partition-type true unloop exit  then
    h# 10 +loop
    false

Added: ofw/fs/romfs.fth
===================================================================
--- ofw/fs/romfs.fth	                        (rev 0)
+++ ofw/fs/romfs.fth	2008-07-03 20:25:27 UTC (rev 843)
@@ -0,0 +1,357 @@
+\ See license at end of file
+purpose: romfs reader
+
+0 instance value block-buf    \ Start address of working buffer
+
+0 instance value inode-offset   \ Offset of current inode
+
+0 instance value /page          \ Efficient size for reading
+0 instance value pages/chip     \ total number of pages
+
+0 instance value the-page#
+
+\ Access a field within a romfs data structure
+: i@  ( adr offset -- value )  la+ be-l@  ;
+
+\ Data structures:
+\ Super-block:
+\  0: "-rom1fs-"
+\  8: total-size
+\  c: checksum of first 512 bytes
+\ 10: volume name, zero-padded to multiple of 16 
+\ 10+n: start of file headers
+\
+\ file header:
+\  0: next_filehdr_offset|4B_file_type 
+\  4: spec.info (hard_link:destination hdr, dir:first_file_hdr, block_or_char_dev:maj16/min16)
+\  8: size of data
+\  c: checksum of metadata
+\ 10: filename, zero-padded to multiple of 16
+\ 10+n: file data
+
+\ File types:
+\ 0*	hard link	link destination [file header]
+\ 1*	directory	first file's header
+\ 2*	regular file	unused, must be zero [MBZ]
+\ 3*	symbolic link	unused, MBZ (file data is the link content)
+\ 4	block device	16/16 bits major/minor number
+\ 5	char device		    - " -
+\ 6	socket		unused, MBZ
+\ 7	fifo		unused, MBZ
+
+: get-page  ( page# -- )
+   dup  the-page#  =  if       ( page# )
+      drop                     ( )
+   else                        ( page# )
+      block-buf over 1 " read-blocks" $call-parent    ( page# #read )
+      1 <>  abort" romfs: Bad read"                   ( page# )
+      to the-page#
+   then                        ( )
+;
+
+: be-checksum  ( adr len -- sum )
+   0 -rot  bounds ?do  i be-l@ +  /l +loop
+;
+
+0 instance value fs-max
+
+\ Information that we need about the working file/directory
+\ The working file changes at each level of a path search
+
+\ 0 instance value wd-inum  \ Inumber of directory
+\ 0 instance value wf-inum  \ Inumber of file or directory
+0 instance value wf-type  \ File type - see list above
+
+0 instance value root-header    \ Offset of first file header in root directory
+0 instance value wd-header      \ Offset of first file header in working directory
+0 instance value current-header \ Offset of current file header
+
+: find-root-header  ( -- error? )
+   d# 256  d# 31  do
+      i block-buf + c@  0=  if
+         i 1+ to root-header
+         false unloop exit
+      then
+   d# 16 +loop
+   true
+;
+
+: bad-super-block?  ( -- bad? )
+   0 get-page                                         ( )
+   block-buf  " -rom1fs-"  comp  if  true exit  then  ( )
+   block-buf d# 512 be-checksum  0<>  if  true exit  then       ( )
+   block-buf 4 + be-l@  to fs-max                     ( )
+   find-root-header                                   ( bad? )
+;
+
+: get-bytes  ( byte# -- adr len )
+   /page /mod                  ( offset page# )
+   get-page                    ( offset )
+   /page over -                ( offset remain )
+   swap block-buf + swap       ( adr len )
+;
+
+: copy-data  ( dst-adr dst-len byte# -- )
+   over bounds  ?do     ( dst-adr dst-len )
+      i get-bytes       ( dst-adr dst-len src-adr src-len )
+      2 pick min  >r    ( dst-adr dst-len src-adr r: copy-len )
+      2 pick  r@ move   ( dst-adr dst-len r: copy-len )
+      r@ /string        ( dst-adr' dst-len' r: copy-len )
+   r> +loop             ( dst-adr dst-len )
+   2drop
+;
+
+h# 10 constant /hdr-align
+h# 80 constant /name-max
+/name-max h# 10 + constant /hdr-max
+
+create root-template  
+
+/hdr-max instance buffer: hdr-buf
+: next-header   ( -- byte# )    hdr-buf be-l@ h# f invert and  ;
+: file-type     ( -- n )        hdr-buf be-l@ h# f and  ;
+: file-info     ( -- n )        hdr-buf 4 + be-l@  ;
+: file-size     ( -- n )        hdr-buf 8 + be-l@  ;
+: hdr-checksum  ( -- n )        hdr-buf d# 12 + be-l@   ;
+: file-name     ( -- adr len )  hdr-buf d# 16 + cscount  ;
+base @ octal
+\              hardlnk   dir   regular  symlink  blkdev   chardev  socket   fifo
+create modes   00444 , 40444 , 100444 , 120444 , 060444 , 020444 , 140444 , 010444 ,
+base !
+: file-mode  ( -- n )
+   modes file-type 7 and na+ @
+   file-type 8 and  if  o# 111 or  then
+;
+
+0 instance value file-data
+
+: get-file-header  ( byte# -- error? )
+   dup d# -16 =  if   \ Synthesize a root header
+      to current-header
+      1 hdr-buf be-l!
+      root-header hdr-buf 4 + be-l!
+      false exit
+   then
+
+   dup 0=  if  drop true exit  then            ( byte# )
+   dup fs-max >=  if  drop true exit  then     ( byte# )
+
+   hdr-buf h# 20  2 pick  copy-data   ( byte# )
+   h# 20                              ( byte# len )
+
+   hdr-buf be-l@ h# ffffffff =  if  2drop true exit  then
+
+   begin  dup hdr-buf + 1- c@  while               ( byte# len )
+      dup  /hdr-max >=  abort" Bad file header"    ( byte# len )
+      2dup + >r  dup hdr-buf +                     ( byte# len hdr-adr+len r: byte#+len)
+      /hdr-align  r>  copy-data                    ( byte# len )
+      /hdr-align +                                 ( byte# len' )
+   repeat                                          ( byte# len )
+   hdr-buf  over  be-checksum                      ( byte# len sum )
+   0<> abort" Bad header checksum"                 ( byte# len )
+
+   over to current-header
+   +  to file-data
+   false
+;
+
+: dma-alloc  ( len -- adr )  " dma-alloc" $call-parent  ;
+: dma-free   ( len -- adr )  " dma-free" $call-parent  ;
+
+: allocate-buffers  ( -- )
+   " block-size" $call-parent to /page
+   /page  dma-alloc     to block-buf
+   -1 to the-page#
+;
+
+: release-buffers  ( -- )
+   block-buf  /page  dma-free
+;
+
+char \ instance value delimiter
+
+: set-root  ( -- )
+   d# -16 to wd-header
+   wd-header  get-file-header  drop
+;
+
+defer $resolve-path
+
+: strip\  ( name$ -- name$' )
+   dup  0<>  if                      ( name$ )
+      over c@  delimiter  =  if      ( name$ )
+         1 /string                   ( name$ )
+         set-root                    ( name$ )
+      then                           ( name$ )
+   then                              ( name$ )
+;
+
+: $find-name  ( name$ -- error? )
+   wd-header                          ( name# byte# )
+   begin  get-file-header 0=  while   ( name$ )
+      2dup file-name $=  if           ( name$ )
+         2drop false exit
+      then                            ( name$ )
+      next-header                     ( name$ byte# )
+   repeat                             ( name$ byte# )
+   3drop   true
+;
+
+\ The work file is a symlink.  Resolve it to a new dirent
+: dir-link  ( -- error? )
+   file-size  /name-max >  if  true exit  then
+
+   delimiter >r  [char] / to delimiter
+
+   \ Allocate temporary space for the symlink value (new name)
+   /name-max alloc-mem >r
+
+   r@ file-size  file-data  copy-data  ( )
+   r@ file-size  $resolve-path         ( error? )
+
+   r> /name-max free-mem
+   r> to delimiter
+;
+: hard-link  ( -- error? )  file-info get-file-header  ;
+
+: ($resolve-path)  ( path$ -- error? )
+   begin  strip\  dup  while                       ( path$  )
+      file-type 7 and  case                        ( path$  c: type )
+         1  of   \ Directory                       ( path$ )
+            delimiter left-parse-string            ( rem$' head$ )
+            file-info to wd-header                 ( rem$' head$ )
+            $find-name  if  2drop true exit  then  ( rem$ )
+         endof                                     ( rem$ )
+
+         0  of   \ Hard link                       ( path$ )
+            hard-link  if  2drop true exit  then   ( path$ )
+         endof
+
+         3  of   \ symlink                         ( rem$ )
+            dir-link  if  2drop true exit  then    ( rem$ )
+         endof                                     ( rem$ )
+         ( default )                               ( rem$  c: type )
+
+         \ The parent is an ordinary file or something else that
+         \ can't be treated as a directory
+         3drop true exit
+      endcase                           ( rem$ )
+   repeat                               ( rem$ )
+   2drop false                          ( false )
+;
+
+' ($resolve-path) to $resolve-path
+
+decimal
+
+headerless
+0 value open-count
+0 instance value seek-ptr
+
+: clip-size  ( adr len -- len' adr len' )
+   seek-ptr +   file-size min  seek-ptr -     ( adr len' )
+   tuck
+;
+: update-ptr  ( len' -- len' )  dup seek-ptr +  to seek-ptr  ;
+
+headers
+external
+: seek  ( d.offset -- status )
+   0<>  over file-size u>  or  if  drop true  exit  then \ Seek offset too big
+   to seek-ptr
+   false
+;
+
+: ?release  ( flag -- flag )  dup 0=  if  release-buffers  then  ;
+
+\ Starting at the current directory (wd-inum), process all the path components,
+\ resolving symlinks until either a directory or an ordinary file is found.
+\ If the resulting final component is a directory, leave wd-inum set to it.
+\ If the resulting final component is a file, collect its data nodes so that
+\ "seek", "read", and "load" will access its data.
+
+: $find-file  ( name$ -- found? )
+   $resolve-path  if  false exit  then  ( )
+
+   begin
+      \ We now have the dirent for the file at the end of the string
+      file-type 7 and  case
+         1      of  current-header to wd-header  true exit  endof  \ Directory
+         2      of                               true exit  endof  \ Regular file
+         3      of  dir-link  if  false exit  then          endof  \ SymLink
+         0      of  hard-link if  false exit  then          endof  \ Hard link
+         ( default )   \ Anything else (special file) is error
+            drop false exit
+      endcase
+   again
+;
+
+: open  ( -- flag )
+   \ This lets us open the node during compilation
+   standalone?  0=  if  true exit  then
+
+   0 to seek-ptr                                ( )
+   allocate-buffers                             ( )
+
+   bad-super-block?  if  release-buffers false exit  then
+
+   my-args " <NoFile>"  $=  if  true exit  then
+
+   set-root
+   my-args  $find-file  ( okay? )
+   ?release
+;
+
+: close  ( -- )  release-buffers  ;
+
+: size  ( -- d.size )  file-size 0  ;
+
+: read  ( adr len -- actual )
+   clip-size 			     ( len' adr len' )
+   file-data seek-ptr +  copy-data   ( len' )
+   update-ptr
+;
+
+: load  ( adr -- len )
+   file-size  file-data  copy-data
+   file-size
+;
+
+hex
+\ End of common code
+
+: next-file-info  ( id -- false | id' s m h d m y len attributes name$ true )
+   if  next-header  else  ( wd-header get-file-header ) file-info  then  ( byte# )
+   get-file-header  if  false exit  then    ( )
+   current-header
+   0 0 0 0 0 0                 ( id' s m h  d m y  )
+   file-size                   ( id' s m h  d m y  len  )
+   file-mode                   ( id' s m h  d m y  len  mode )
+   file-name true
+;
+
+: free-bytes  ( -- d.#bytes )  0 0  ;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2006 FirmWorks
+\ 
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\ 
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\ 
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END




More information about the openfirmware mailing list