[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