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@0" ; [then] +[ifdef] preof-loaded : disk-name ( -- $ ) " /pci/ide@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@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@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@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@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@+ i gp! 4 +loop l@+ 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@+ 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
openfirmware@openfirmware.info