Author: wmb Date: 2007-07-05 19:19:17 +0200 (Thu, 05 Jul 2007) New Revision: 461
Added: cpu/ppc/ cpu/ppc/Linux/ cpu/ppc/Linux/Makefile cpu/ppc/aiport.fth cpu/ppc/asmmacro.fth cpu/ppc/asmtools.fth cpu/ppc/assem.fth cpu/ppc/banner.fth cpu/ppc/basefw.bth cpu/ppc/bat.fth cpu/ppc/bat601.fth cpu/ppc/batf601.fth cpu/ppc/batfault.fth cpu/ppc/batmap.fth cpu/ppc/boot.fth cpu/ppc/build/ cpu/ppc/builder.bth cpu/ppc/cache601.fth cpu/ppc/cache603.fth cpu/ppc/cache823.fth cpu/ppc/call.fth cpu/ppc/catchexc.fth cpu/ppc/centry.fth cpu/ppc/code.fth cpu/ppc/cpubpsup.fth cpu/ppc/cpuclass.fth cpu/ppc/cpunode.fth cpu/ppc/cpustate.fth cpu/ppc/ctrace.fth cpu/ppc/debugm.fth cpu/ppc/decompm.fth cpu/ppc/dectrap.fth cpu/ppc/disinflt.fth cpu/ppc/epic.fth cpu/ppc/fb8-ops.fth cpu/ppc/field.fth cpu/ppc/filecode.fth cpu/ppc/filefld.fth cpu/ppc/finish.fth cpu/ppc/fixvoc.fth cpu/ppc/flipdic.fth cpu/ppc/flips.fth cpu/ppc/forthint.fth cpu/ppc/ftrace.fth cpu/ppc/gdb.fth cpu/ppc/getms.fth cpu/ppc/hacks.fth cpu/ppc/htabmmu.fth cpu/ppc/inflate.fth cpu/ppc/initpgm.fth cpu/ppc/kerncode.fth cpu/ppc/kernel.bth cpu/ppc/kernrel.fth cpu/ppc/loadmach.fth cpu/ppc/loadvmem.fth cpu/ppc/metainit.fth cpu/ppc/metarel.fth cpu/ppc/minifth.fth cpu/ppc/msr.fth cpu/ppc/ntctrace.fth cpu/ppc/objects.fth cpu/ppc/objsup.fth cpu/ppc/occhksum.fth cpu/ppc/olpc/ cpu/ppc/olpc/build/ cpu/ppc/olpc/devalias.fth cpu/ppc/olpc/elf.fth cpu/ppc/olpc/flash.fth cpu/ppc/olpc/fw.bth cpu/ppc/olpc/fwuboot.bth cpu/ppc/olpc/mappci.fth cpu/ppc/olpc/pciconfig.fth cpu/ppc/olpc/pcinode.fth cpu/ppc/olpc/probemem.fth cpu/ppc/olpc/reports.fth cpu/ppc/olpc/reset.fth cpu/ppc/olpc/rootnode.fth cpu/ppc/pause.fth cpu/ppc/ppcboot.fth cpu/ppc/ppcsim/ cpu/ppc/ppcsim/ppcsim.c cpu/ppc/ppcsim/simrom.c cpu/ppc/realcif.fth cpu/ppc/reboot.fth cpu/ppc/reenter.fth cpu/ppc/regacc.fth cpu/ppc/register.fth cpu/ppc/resetvec.fth cpu/ppc/rombp.fth cpu/ppc/rootnode.fth cpu/ppc/savefort.fth cpu/ppc/savemeta.fth cpu/ppc/scrub.fth cpu/ppc/scrub601.fth cpu/ppc/scrub823.fth cpu/ppc/segreg.fth cpu/ppc/spr.fth cpu/ppc/swapdic.fth cpu/ppc/syscall.fth cpu/ppc/tagwords.fth cpu/ppc/target.fth cpu/ppc/testmmu.fth cpu/ppc/tlb.fth cpu/ppc/tlb601.fth cpu/ppc/tlbmiss.fth cpu/ppc/tlbms823.fth cpu/ppc/tmmu823.fth cpu/ppc/tools.bth cpu/ppc/touchall.fth cpu/ppc/unalign.fth cpu/ppc/xadd.fth Log: PowerPC - initial checkin of PowerPC Open Firmware files.
Added: cpu/ppc/Linux/Makefile =================================================================== --- cpu/ppc/Linux/Makefile (rev 0) +++ cpu/ppc/Linux/Makefile 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,51 @@ +# Flags for the simulator version +WRAPPER = pforth +OPT = -O +# OPT = +CFLAGS = -DUNIX -DSYS5 -DSIM -DPOWERPC -DARGREGS -DSIMNEXT + +CC = gcc + +WRDIR = ${BP}/forth/wrapper +ZIPDIR = ${WRDIR}/zip +SIMDIR = ../ppcsim + +ZIPOBJS = zipmem.o deflate.o trees.o bits.o util.o inflate.o + +OBJS = wrapper.o ppcsim.o logger.o ${ZIPOBJS} +TRACEOBJS = wrapper.o ppcsim.trace.o logger.o ${ZIPOBJS} +SIMROMOBJS = simrom.o ppcsim.simrom.o + +all: ppcforth ppcforth.trace + +ppcforth: $(OBJS) + $(CC) $(LFLAGS) $(OBJS) -o $@ + +ppcforth.trace: $(TRACEOBJS) + $(CC) $(LFLAGS) $(TRACEOBJS) -o $@ + +simrom: $(SIMROMOBJS) + $(CC) $(LFLAGS) $(SIMROMOBJS) -o $@ + +%.o: ${WRDIR}/%.c + ${CC} -c ${CFLAGS} $< -o $@ + +%.o: ${ZIPDIR}/%.c + ${CC} -c ${CFLAGS} -I${ZIPDIR} $< -o $@ + +ppcsim.o: $(SIMDIR)/ppcsim.c + $(CC) $(OPT) $(CFLAGS) -c $< -o $@ + +ppcsim.trace.o: $(SIMDIR)/ppcsim.c + $(CC) $(OPT) $(CFLAGS) -DTRACE -c $< -o $@ + +ppcsim.simrom.o: $(SIMDIR)/ppcsim.c + $(CC) $(CFLAGS) -DTRACE -DSIMROM -c $< -o $@ + +simrom.o: $(SIMDIR)/simrom.c + $(CC) $(CFLAGS) -DTRACE -DSIMROM -c $< -o $@ + +clean: + @rm -f *.o ppcforth ppcforth.trace + +FRC:
Added: cpu/ppc/aiport.fth =================================================================== --- cpu/ppc/aiport.fth (rev 0) +++ cpu/ppc/aiport.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,76 @@ +purpose: Assembly-language driver for Promice Analysis Interface "serial port" +\ See copyright at end of file + +\ Requires the following external definitions: +\ ai-serial ( -- n ) \ Returns the base address of the AI port registers + +label init-serial ( -- ) \ Destroys: r3 + begin + ai-serial set r3,* + lbz r3,3(r3) \ Read status register + cmpi 0,0,r3,h#cc \ 0xcc is status_invalid + <> until \ Wait for port to become active + + ai-serial set r3,* + lbz r3,2(r3) \ Read data port (because the docs say to) + bclr 20,0 +end-code + +label putchar ( r3 -- ) \ Destroys: r1, r2 + ai-serial set r1,* + begin + lbz r2,3(r1) \ Read status register + andi. r0,r2,1 \ Transmitter ready bit + 0= until \ Wait for ready + + \ send char + lbz r2,1(r1) \ start bit + + andi. r3,r3,h#ff \ Clear high bits just in case + + ori r3,r3,h#100 \ merge in stop bit + begin + \ use the fact that ONE = 1 and ZERO = 0 + andi. r2,r3,1 + lbzx r2,r1,r2 \ send bit + rlwinm. r3,r3,31,1,31 \ last bit will be stop bit + 0= until + + bclr 20,0 +end-code + +label getchar ( -- r3 ) + begin \ wait for byte + ai-serial set r3,* + lbz r3,3(r3) \ Read status register + andi. r0,r3,2 \ Test received byte available bit + 0<> until + + ai-serial set r3,* + lbz r3,2(r3) \ Read received byte + bclr 20,0 +end-code + +\ 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/ppc/asmmacro.fth =================================================================== --- cpu/ppc/asmmacro.fth (rev 0) +++ cpu/ppc/asmmacro.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,42 @@ +purpose: Handy assembler macros +\ See copyright at end of file + +also forth definitions +: c$, ( adr len -- ) + 1+ here swap note-string dup allot move 4 (align) +; +previous definitions + +also ppc-assembler definitions +: $-to-r3 ( adr len -- ) + dup 5 + 4 round-up here + " bl *" evaluate \ Assemble code to skip string + c$, \ Place string + " mfspr r3,lr" evaluate \ Assemble code to get str adr +; +: pop-to-t0 " lwz t0,0(sp) addi sp,sp,1cell" evaluate ; +previous definitions + +\ 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/ppc/asmtools.fth =================================================================== --- cpu/ppc/asmtools.fth (rev 0) +++ cpu/ppc/asmtools.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,111 @@ +purpose: Tools for creating disembodied assembly code sequences +\ See license at end of file + +[ifndef] set-transize +fload ${BP}/forth/lib/transien.fth +true is suppress-transient? \ Disable transient definitions for now +[then] + +\needs suppress-headerless? fload ${BP}/forth/lib/headless.fth + +[ifndef] ppc-assembler +fload ${BP}/cpu/ppc/assem.fth +fload ${BP}/cpu/ppc/code.fth +fload ${BP}/forth/lib/loclabel.fth +[then] + +also ppc-assembler definitions +\needs $-to-r3 fload ${BP}/cpu/ppc/asmmacro.fth + +: $find-dropin, ( adr len -- ) + $-to-r3 \ Assemble string and skip it + " find-dropin bl *" evaluate \ and call find routine +; +previous definitions + +false value transient-labels? +0 value asm-origin +0 value asm-base +: pad-to ( n -- ) + begin dup here asm-base - asm-origin + u> while 0 , repeat drop +; +: align-to ( boundary -- ) + here asm-base - swap round-up pad-to +; + +: put-call ( target-adr branch-adr -- ) + tuck [ also assembler ] offset-26 [ previous ] + h# 4800.0001 + swap + [ also assembler ] asm! [ previous ] \ bl offset +; + +[ifndef] enable-transient? +: enable-transient ( -- ) + suppress-transient? if + unused 4 / d# 1000 set-transize + false is suppress-transient? + false is suppress-headerless? + then +; +[then] +enable-transient + +: tconstant ( value "name" -- ) + transient? 0= dup >r if transient then + constant + r> if resident then +; +: label ( "name" -- ) + transient-labels? if + here tconstant + [ also assembler ] init-labels [ previous ] !csp entercode + else + label + then +; + +: set-asm-origin ( -- ) + here to asm-base + 0 to asm-origin +; + +0 0 2value old-asms +: start-assembling ( -- ) + \ Use "is" instead of "to" in the next line because "to" is a PowerPC + \ assembly mnemonic (trap on overflow). + [ also assembler ] + ['] asm@ behavior ['] asm! behavior to old-asms + ['] be-l@ is asm@ ['] be-l! is asm! + [ previous ] + set-asm-origin + true to transient-labels? +; +: end-assembling ( -- ) + [ also assembler ] old-asms is asm! is asm@ [ previous ] + false to transient-labels? +; + + +\ 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/ppc/assem.fth =================================================================== --- cpu/ppc/assem.fth (rev 0) +++ cpu/ppc/assem.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,1324 @@ +purpose: PowerPC assembler +\ See license at end of file + +decimal + +\needs $vfind fload ${BP}/forthlang/lib/strings.fth +\needs left-parse-string fload ${BP}/forthlang/lib/parses1.fth + +vocabulary ppc-assembler + +also ppc-assembler definitions + +headerless +false value disassembling? +variable instruction +variable end-found +headers +variable pc +variable display-offset 0 display-offset ! +: +offset ( adr -- adr' ) display-offset @ + ; +' ul. is showaddr + +headerless +h# 40 /token * constant /op-map create op-map /op-map allot +h# 10 /token /n + * constant /19-map create 19-map /19-map allot +h# 400 /token * constant /31-map create 31-map /31-map allot +h# 20 /token * constant /59-map create 59-map /59-map allot +h# 20 /token /n + * constant /63-map create 63-map /63-map allot + +: unimp ( -- ) + end-found on + ." Not an instruction: " instruction @ + base @ >r hex 9 u.r r> base ! space + false is disassembling? +; + +: (.name) ( acf -- ) + dup ['] unimp = if execute else >name name>string type then +; + +: find-sparse-entry ( entry map -- acf ) + begin dup @ -1 <> while ( entry mapp ) + 2dup @ = if ( entry mapp ) + nip na1+ token@ exit ( acf ) + then ( entry mapp ) + na1+ ta1+ + repeat + 2drop ['] unimp +; +: find-indexed-entry ( entry map -- acf ) swap ta+ token@ ; + +: init-map ( adr len -- ) bounds ?do ['] unimp i token! /token +loop ; +: init-sparse-map ( adr len -- ) + bounds ?do -1 i ! ['] unimp i na1+ token! /token na1+ +loop +; + +variable start-column +variable need-comma +: ?, ( -- ) need-comma @ if ." ," else need-comma on then ; +: to-operand-column ( -- ) d# 8 start-column @ + to-column need-comma off ; +: ibits ( right-bit# width -- bits ) + tuck - 1+ instruction l@ swap << 32 rot - >> +; + +: init-maps ( -- ) + op-map /op-map init-map + 31-map /31-map init-map + 59-map /59-map init-map + 19-map /19-map init-sparse-map + 63-map /63-map init-sparse-map +; +init-maps + +headers +defer here +defer asm-allot +defer asm@ +defer asm! + +\ Install as a resident assembler +\ : xx see ; immediate +: resident-assembler ( -- ) + [ forth ] ['] here [ ppc-assembler ] is here + [ forth ] ['] allot [ ppc-assembler ] is asm-allot + [ forth ] ['] @ [ ppc-assembler ] is asm@ + [ forth ] ['] instruction! [ ppc-assembler ] is asm! +; +resident-assembler + +headerless +2variable operands + +: get-field ( -- adr len ) + operands 2@ ascii , left-parse-string 2swap operands 2! ( adr len ) +; +: field-or-number ( ? -- n true | adr len false ) + disassembling? if false exit then + get-field + 2dup " *" $= dup if nip nip then +; +\ If adr2,len2 is an initial substring of adr1,len1, return the remainder +\ of the adr1,len1 string following that initial substring. +\ Otherwise, return adr1,len1 +: ?remove ( adr1 len1 adr2 len2 -- adr3 len3 removed? ) + 2 pick over u< if 2drop false exit then \ len2 too long? + 3 pick rot 2 pick ( adr len1 len2 adr1 adr2 len2 ) + caps-comp 0= if /string true else drop false then +; +: set-base ( adr len -- adr' len' ) + " h#" ?remove if hex exit then + " 0x" ?remove if hex exit then + " d#" ?remove if decimal exit then + " o#" ?remove if octal exit then + " b#" ?remove if binary exit then +; + +headers +\ Define symbolic names for constants in this vocabulary +vocabulary constant-names + +headerless +: get-based-number ( adr len -- true | n false ) + ['] constant-names $vfind if execute false exit then + base @ >r decimal + set-base + $number + r> base ! +; +: number ( -- n ) + disassembling? if ?, exit then + field-or-number if exit then + get-based-number abort" Bad number" +; + +: reg-name ( adr1 len1 adr2 len2 -- n ) \ adr2 len2 is the register prefix + disassembling? if ?, type exit then + ?remove drop + base @ >r decimal + $number + r> base ! + abort" Bad register number" +; + +\ The two 5-bit halves of the special register field are interchanged +: flip5 ( n -- n' ) dup h# 1f and 5 << swap 5 >> or ; + +headers +: sp-reg: ( n -- ) flip5 constant ; + +vocabulary sp-registers +also sp-registers definitions +1011 sp-reg: tbar \ This is not really a PowerPC register; + \ I invented it as a way of communicating + \ the trap base address to the simulator + \ to avoid slowing the simulator down with + \ absolute addressing + + 0 sp-reg: mq + 1 sp-reg: xer + 4 sp-reg: rtcu \ mfspr version + 5 sp-reg: rtcl \ mfspr version + 8 sp-reg: lr + 9 sp-reg: ctr + 18 sp-reg: dsisr + 19 sp-reg: dar + 20 sp-reg: rtcu \ mtspr version + 21 sp-reg: rtcl \ mtspr version + 22 sp-reg: dec + 25 sp-reg: sdr1 + 26 sp-reg: srr0 + 27 sp-reg: srr1 + 268 sp-reg: tb \ For reading + 269 sp-reg: tbu \ For reading + 272 sp-reg: sprg0 + 273 sp-reg: sprg1 + 274 sp-reg: sprg2 + 275 sp-reg: sprg3 + 280 sp-reg: asr \ 620-specific + 282 sp-reg: ear + 284 sp-reg: tb.w \ For writing + 285 sp-reg: tbu.w \ For writing + 287 sp-reg: pvr + 528 sp-reg: ibat0u + 529 sp-reg: ibat0l + 530 sp-reg: ibat1u + 531 sp-reg: ibat1l + 532 sp-reg: ibat2u + 533 sp-reg: ibat2l + 534 sp-reg: ibat3u + 535 sp-reg: ibat3l + 536 sp-reg: dbat0u + 537 sp-reg: dbat0l + 538 sp-reg: dbat1u + 539 sp-reg: dbat1l + 540 sp-reg: dbat2u + 541 sp-reg: dbat2l + 542 sp-reg: dbat3u + 543 sp-reg: dbat3l + +1008 sp-reg: check \ Exponential 704-specific +1008 sp-reg: checkstop 1008 sp-reg: hid0 +1009 sp-reg: debug-mode 1009 sp-reg: hid1 +1010 sp-reg: iabr 1010 sp-reg: hid2 +1013 sp-reg: dabr 1013 sp-reg: hid5 +1016 sp-reg: buscsr \ 620-specific +1017 sp-reg: l2cr \ 620-specific +1018 sp-reg: l2sr \ 620-specific +1023 sp-reg: pir 1023 sp-reg: hid15 + + \ 603-specific + 976 sp-reg: dmiss + 977 sp-reg: dcmp + 978 sp-reg: hash1 + 979 sp-reg: hash2 + 980 sp-reg: imiss + 981 sp-reg: icmp + 982 sp-reg: rpa + +\ 604-specific + 952 sp-reg: mmcr0 \ 604-specific reg + 953 sp-reg: pmc1 \ 604-specific reg + 954 sp-reg: pmc2 \ 604-specific reg + 955 sp-reg: sia \ 604-specific reg + 959 sp-reg: sda \ 604-specific reg + +\ Exponential 704-specific: also uses some 603-specific registers + 276 sp-reg: sprg4 \ Exponential 704-specific + 277 sp-reg: sprg5 \ Exponential 704-specific + 278 sp-reg: sprg6 \ Exponential 704-specific + 279 sp-reg: sprg7 \ Exponential 704-specific + 953 sp-reg: event \ Exponential 704-specific + 954 sp-reg: modes \ Exponential 704-specific + 977 sp-reg: cmp \ Similar to 603 dcmp + 982 sp-reg: tlblru0 \ Similar to 603 rpa + 983 sp-reg: tlbmrf \ Exponential 704-specific + 985 sp-reg: bpctl \ Exponential 704-specific + 987 sp-reg: tlblru1 \ Exponential 704-specific + 988 sp-reg: misr \ Exponential 704-specific + 989 sp-reg: mar \ Exponential 704-specific +1012 sp-reg: l2cdr \ Exponential 704-specific +1014 sp-reg: xdabr \ Exponential 704-specific +1019 sp-reg: l2ctl \ Exponential 704-specific + +\ 823-specific + 80 sp-reg: eie + 81 sp-reg: eid + 82 sp-reg: nri + 144 sp-reg: cmpa + 145 sp-reg: cmpb + 146 sp-reg: cmpc + 147 sp-reg: cmpd + 148 sp-reg: icr + 149 sp-reg: der + 150 sp-reg: counta + 151 sp-reg: countb + 152 sp-reg: cmpe + 153 sp-reg: cmpf + 154 sp-reg: cmpg + 155 sp-reg: cmph + 156 sp-reg: lctrl1 + 157 sp-reg: lctrl2 + 158 sp-reg: ictrl + 159 sp-reg: bar + 560 sp-reg: ic-csr + 561 sp-reg: ic-adr + 562 sp-reg: ic-dat + 568 sp-reg: dc-csr + 569 sp-reg: dc-adr + 570 sp-reg: dc-dat + 630 sp-reg: dpdr + 631 sp-reg: dpir + 638 sp-reg: immr + 784 sp-reg: mi-ctr + 786 sp-reg: mi-ap + 787 sp-reg: mi-epn + 789 sp-reg: mi-twc + 790 sp-reg: mi-rpn + 816 sp-reg: mi-cam + 817 sp-reg: mi-ram0 + 818 sp-reg: mi-ram1 + 792 sp-reg: md-ctr + 793 sp-reg: m-casid + 794 sp-reg: md-ap + 795 sp-reg: md-epn + 796 sp-reg: m-twb + 797 sp-reg: md-twc + 798 sp-reg: md-rpn + 799 sp-reg: m-tw + 824 sp-reg: md-cam + 825 sp-reg: md-ram0 + 826 sp-reg: md-ram1 + + +previous definitions + +\ Define symbolic names for registers in this vocabulary +vocabulary register-names + +headerless +: r-reg-name ( adr len -- n ) + disassembling? 0= if + ['] register-names $vfind if execute exit then + then + " r" reg-name +; +: r-register ( -- n ) + field-or-number if exit then + r-reg-name +; +: crf-register ( -- n ) field-or-number if exit then " crf" reg-name ; +: crb-bit ( -- n ) field-or-number if exit then " crb" reg-name ; +: fr-register ( -- n ) field-or-number if exit then " fr" reg-name ; +: u.d ( n -- ) base @ >r decimal (u.) type r> base ! ; + +\ Nasty hack to handle the RTCU/RTCL SPR encoding difference +\ between mfspr and mtspr +: ?fix-rtc ( sp-reg# -- sp-reg#' ) + dup h# 280 = over h# 2a0 = or if \ rtcu or rtcl? + here /l - asm@ h# 100 and 0= if \ mfspr? + h# 200 - + then + then +; + +: sp-register ( -- n ) + disassembling? if + ?, + 20 10 ibits ( n ) + ['] sp-registers follow + begin another? while + name> dup execute ( n acf constant ) + 2 pick = if (.name) drop exit then ( n acf ) + drop + repeat + ." spr" flip5 u.d + else + field-or-number if exit then + ['] sp-registers $vfind 0= if + ." Bad special register name: " type cr abort + then + execute + ?fix-rtc + then +; +: relative? ( -- flag ) here 4 - asm@ 2 and 0= ; +: ?aligned ( adr -- adr ) + dup 3 and abort" Misaligned branch target" +; +: convert-target ( adr -- n ) + ?aligned + relative? if here 4 - - then +; +: safe-get-number ( adr len -- n ) + get-based-number abort" Bad branch target address" +; +: branch-target ( -- adr ) + field-or-number 0= if ( adr len ) + dup 2 >= if ( adr len ) + over " .+" comp 0= if ( adr len ) + 2 /string safe-get-number here /l - + exit + then ( adr len ) + over " .-" comp 0= if ( adr len ) + 2 /string safe-get-number negate here /l - + exit + then + then + safe-get-number + then +; + +: add-bits ( n -- ) + here /l - dup asm@ rot or swap asm! +; + +: >16-bits? ( n -- u flag ) + dup h# ffff and swap h# -8000 h# 8000 within 0= +; +: ?simm ( n -- n ) + >16-bits? abort" Signed immediate value out of range" +; + +: high-mask ( #low-zeroes -- mask ) 1 swap << 1- invert ; +: bit-field ( n shift width -- ) + disassembling? if ibits u.d exit then + high-mask 2 pick and abort" Value too large for bit field" + 31 swap - << add-bits +; +: 5bit-field ( -- ) 5 bit-field ; +: rd-field ( n -- ) 10 5bit-field ; +: ra-field ( n -- ) 15 5bit-field ; +: rb-field ( n -- ) 20 5bit-field ; +: rc-bit ( n -- ) 31 1 bit-field ; +: oe-bit ( n -- ) 21 1 bit-field ; + +: imm-field ( n -- ) 31 16 bit-field ; +: sign-extend-16 ( n1 -- n2 ) 16 << 16 >>a ; +: h#.x ( n -- ) + dup -9 9 between 0= if ." h#" then + base @ >r hex (.) type r> base ! +; +: simm ( n -- ) + disassembling? if + ?, 31 16 ibits sign-extend-16 h#.x + else + number ?simm imm-field + then +; +: ?uimm ( u -- u ) + dup h# ffff u> abort" Unsigned immediate value too large" +; +: uimm ( u -- ) + disassembling? if + ?, 31 16 ibits h#.x + else + number ?uimm + imm-field + then +; +\ In principle, this is a signed field, but it makes the code +\ incredibly hard to read if we display it as such. +: simms ( n -- ) + disassembling? if + ?, 31 16 ibits ( sign-extend-16 ) h#.x ." ...." + else + simm + then +; +: uimms ( n -- ) + disassembling? if + \ 64-bit: we will need to handle this differently for the 64-bit version + simms + else + uimm + then +; +: imm ( -- ) number 19 4 bit-field ; +: rd ( -- ) r-register rd-field ; +: ra ( -- ) r-register ra-field ; +: rb ( -- ) r-register rb-field ; +: rs ( -- ) rd ; +: crfd ( -- ) crf-register 8 3 bit-field ; +: crfs ( -- ) crf-register 13 3 bit-field ; +: crbd ( -- ) crb-bit rd-field ; +: crba ( -- ) crb-bit ra-field ; +: crbb ( -- ) crb-bit rb-field ; +: fm ( -- ) number 14 8 bit-field ; +: l ( -- ) number 10 1 bit-field ; +false value numeric-conditionals? +variable suppress-cond +: bo ( -- ) + disassembling? if + 10 5 ibits + numeric-conditionals? if ?, u.d exit then + dup h# 14 and h# 14 = if + ?, ." always" suppress-cond on + else + dup h# 4 and 0= if \ Decrement and test counter register + ?, ." ctr" + dup 2 and if ." =0" then + then + dup h# 10 and if + suppress-cond on + else + suppress-cond off + dup h# 8 and 0= if ?, ." not" then + then + then + 1 and if ?, ." Y" then + else + number rd-field + then +; + +headers +: set-y ( -- ) h# 0020.0000 add-bits ; + +headerless +string-array condnames ," lt" ," gt" ," eq" ," so" end-string-array +: bi ( -- ) + disassembling? if + 15 5 ibits + numeric-conditionals? if ?, u.d exit then + suppress-cond @ if + drop + else + ?, + 4 /mod ?dup if ." cr" u.d ." +" then + condnames ". + then + else + number ra-field + then +; +: frd ( -- ) fr-register rd-field ; +: frs ( -- ) fr-register rd-field ; +: fra ( -- ) fr-register ra-field ; +: frb ( -- ) fr-register rb-field ; +: frc ( -- ) fr-register 25 5bit-field ; +: spr ( -- ) sp-register disassembling? 0= if 20 10 bit-field then ; +: tbr ( -- ) sp-register disassembling? 0= if 20 10 bit-field then ; +: sr ( -- ) number 15 4 bit-field ; +: crm ( -- ) number 19 8 bit-field ; +\ Don't overload the Forth word "to" +: tox ( -- ) number rd-field ; +: mb ( -- ) number 25 5bit-field ; +: me ( -- ) number 30 5bit-field ; +: md ( -- ) number dup h# 1f and 25 5bit-field 5 >> 26 1 bit-field ; +: sh ( -- ) number rb-field ; +: shd ( -- ) number dup h# 1f and rb-field 5 >> 30 1 bit-field ; +: nb ( -- ) number rb-field ; +: set-bd-field ( adr -- ) convert-target ?simm 2 >> 29 14 bit-field ; +: bd ( -- ) + disassembling? if + ?, 29 14 ibits 2 << + 30 1 ibits 0= if sign-extend-16 pc @ + then showaddr + else + branch-target set-bd-field + then +; +: ?offset-26 ( target -- target-masked ) + dup h# fe00.0000 h# 200.0000 within 0= + abort" Branch target out of 26-bit range" + h# 3ff.ffff and +; +: lif ( -- ) + disassembling? if + ?, 29 24 ibits 8 << 6 >>a \ Sign extend + 30 1 ibits 0= if pc @ + then showaddr + else + branch-target + convert-target + ?offset-26 2 >> 29 24 bit-field + then + +; +: parse-d(ra) ( -- disp ra ) + field-or-number if exit then ( adr len ) + ascii ( left-parse-string ( rem-str disp-str ) + dup 0= if ( rem-str disp-str ) + 2drop 0 ( rem-str 0 ) + else ( rem-str disp-str ) + get-based-number abort" Bad displacement" ( rem-str disp ) + then ( rem-str disp ) + -rot ascii ) left-parse-string ( disp rem-str reg-str ) + 2swap 2drop r-reg-name ( disp ra ) +; +: d(ra) ( -- ) + disassembling? if + ?, + 31 16 ibits sign-extend-16 h#.x + need-comma off + 15 5 ibits if ." (" ra ." )" then + else + parse-d(ra) ra-field ?simm imm-field + then +; +: ds(ra) ( -- ) + disassembling? if + ?, + 29 14 ibits 2 lshift sign-extend-16 h#.x + need-comma off + 15 5 ibits if ." (" ra ." )" then + else + parse-d(ra) ra-field ?simm + dup 3 and abort" offset must be 4-byte aligned" + imm-field + then +; + +\ Operand formats +: rd,ra rd ra ; +: rd,ra,rb rd,ra rb ; +: rd,ra,simm rd,ra simm ; +: rd,ra,simms rd,ra simms ; +: crbd,crba,crbb crbd crba crbb ; +: ra,rs ra rs ; +: ra,rb ra rb ; +: rs,ra,rb rs ra rb ; +: rs,rb rs rb ; +: ra,rs,rb ra,rs rb ; +: ra,rs,uimm ra,rs uimm ; +: ra,rs,uimms ra,rs uimms ; +: bo,bi bo bi end-found on ; +: bo,bi,bd bo bi bd ; +: crfd,l,ra crfd l ra ; +: crfd,crfs crfd crfs ; +: crfd,l,ra,rb crfd,l,ra rb ; +: frd,frb frd frb ; +: frd,fra,frb frd fra frb ; +: frd,fra,frc frd fra frc ; +: crfd,fra,frb crfd fra frb ; +: frd,fra,frc,frb frd fra frc frb ; +: crfd,imm crfd imm ; +: crfd,l,ra,uimm crfd,l,ra uimm ; +: crfd,l,ra,simm crfd,l,ra simm ; +: frs,ra,rb frs ra rb ; +: frd,ra,rb frd ra rb ; +: rd,spr rd spr ; +: rd,tbr rd tbr ; +: rd,sr rd sr ; +: crm,rs crm rs ; +: spr,rs spr rs ; +: sr,rs sr rs ; +: to,ra,rb tox ra rb ; +: to,ra,simm tox ra simm ; +: rd,d(ra) rd d(ra) ; +: rs,d(ra) rs d(ra) ; +: rd,ds(ra) rd ds(ra) ; +: rs,ds(ra) rs ds(ra) ; +: frd,d(ra) frd d(ra) ; +: frs,d(ra) frs d(ra) ; +: ra,rs,rb,mb,me ra rs rb mb me ; +: ra,rs,sh,mb,me ra rs sh mb me ; +: ra,rs,shd,md ra rs shd md ; +: ra,rs,rb,md ra rs rb md ; +: ra,rs,sh ra rs sh ; +: ra,rs,shd ra rs shd ; +: fm,frb fm frb ; +: rd,ra,nb rd ra nb ; +: rs,ra,nb rs ra nb ; +: rd,rb rd rb ; +: no-args ; + +: no-. ; + +alias power noop +\ alias power \ + +\ alias 64bit \ +alias 64bit noop + +: >op2-field ( template -- op2 ) 1 >> h# 3fff and ; +: find-free ( map -- entry-adr ) + begin dup @ -1 <> while na1+ ta1+ repeat +; +headers + +transient +: set-indexed-map ( op2 map -- ) swap ta+ lastacf swap token! ; +: set-sparse-map ( op2 map -- ) + find-free tuck ! lastacf swap na1+ token! +; +: set-map ( opcode-template -- ) + dup >op2-field swap 26 >> ( op2 opcd ) + case + 19 of 19-map set-sparse-map endof + 31 of 31-map set-indexed-map endof + 59 of 59-map set-indexed-map endof + 63 of 63-map set-sparse-map endof + ( default ) op-map set-indexed-map + endcase +; +resident + +: asm, ( n -- ) here /l asm-allot asm! ; + +headerless +: ?. ( -- ) 31 1 ibits if ." ." then ; +: dis-operands ( acf -- ) + dup ['] unimp = if drop exit then + to-operand-column >body na1+ token@ execute +; +variable op-class \ Used for handling the "." forms of the rlw... opcodes +: dis-name&operands ( acf -- ) + dup (.name) + op-class @ d# 20 d# 23 between if ?. then + dis-operands +; + +: bust ( n -- ) + base @ >r decimal + dup 26 >> 2 u.r + dup 21 >> h# 1f and 3 u.r + dup 16 >> h# 1f and 3 u.r + dup 11 >> h# 1f and 3 u.r + dup 1 >> h# 3ff and 5 u.r + 1 and 2 u.r ( cr ) + r> base ! +; + +headers +: ppc-disasm ( 32b -- ) + dup instruction l! + true is disassembling? + 26 >> dup op-class ! op-map find-indexed-entry execute +; +also forth definitions +alias disasm ppc-disasm +: dis1 ( -- ) + ??cr + pc @ showaddr 4 spaces + #out @ start-column ! + pc @ +offset l@ disasm cr + /l pc +! +; +: +dis ( -- ) + base @ >r hex + end-found off + begin dis1 end-found @ exit? or until + r> base ! +; +: dis ( adr -- ) pc l! +dis ; +alias (dis dis +previous definitions + +headerless +\ Try to interpret the word with the "." removed, and then with the "o" +\ removed. +: interpreted? ( adr len -- adr len false | true ) + $find dup if swap execute then +; +: ?peel ( adr1 len1 char -- adr2 len2 flag ) + >r 2dup 1- + c@ r> = if 1- true else false then +; +: $ppc-assem-do-undefined ( adr len -- ) + ascii . ?peel if ( adr len ) + interpreted? if 1 rc-bit exit then ( adr len ) + ascii o ?peel if ( adr len ) + interpreted? if 1 oe-bit 1 rc-bit exit then + then ( adr len ) + else + ascii o ?peel if + interpreted? if 1 oe-bit exit then + then + then ( adr len ) + .not-found abort +; +: get-operands ( -- ) parse-word operands 2! ; + +: op: ( opcode-template -- ) + create dup set-map , \ Remember opcode template + + \ Remember argument parsing word + parse-word $find 0= abort" Missing argument specification" token, + + does> + disassembling? if + body> dis-name&operands + false is disassembling? + else + dup @ asm, \ Place opcode + na1+ token@ dup ['] no-args <> if get-operands then + execute \ Handle arguments + then +; + +[ifdef] notdef +: .binary ( n -- ) + base @ >r 2 base ! + <# 32 0 do # loop #> type space + r> base ! +; +[then] + +headers +transient +: can-. ( -- ) ; \ "." form is available +: can-o ( -- ) ; \ "o" form is available + +\ Opcode formats +resident +: >op ( op0 -- ) 26 << ; + +transient +: d: ( op0 -- ) >op op: ; +: b: ( op0 aa lk -- ) swap 1 << + swap >op + op: ; +: o: ( op1 op0 -- ) swap 1 << swap >op + op: ; + +: dl: ( op0 low -- ) swap >op + op: ; +: rd: ( low -- ) 2 << 30 >op + op: ; + +: r: ( op0 -- ) d: can-. ; + +: xl: ( op1 -- ) 19 o: ; +: x: ( op1 -- ) 31 o: ; +: s: ( op1 -- ) 59 o: can-. ; +: f: ( op1 -- ) 63 o: can-. ; + +\ : x: 31 swap 1 << swap >op + .binary newline word ". cr ; + +: xc: ( op1 -- ) x: can-. ; +: xo: ( op1 oe -- ) xc: can-o ; +resident + +\ Put a branch instruction from high-level Forth code + +: offset-26 ( target-address branch-address -- masked-displacement ) + swap ?aligned swap ?aligned + - ?offset-26 +; + +also forth definitions +: put-branch ( target-adr branch-adr -- ) + tuck offset-26 h# 4800.0000 + swap asm! \ b offset +; +previous definitions + +: cond ( bo bi -- ) + swap 5 << or 16 << create , does> @ +; +: -cond ( condition -- not-condition ) + dup h# 0080.0000 and 0= if h# 0040.0000 xor then \ CTR condition + dup h# 0200.0000 and 0= if h# 0100.0000 xor then \ CR condition +; + +headerless +: offset-16 ( target-address branch-address -- masked-displacement ) + dup 3 and abort" Unaligned branch displacement" + - + >16-bits? abort" branch displacement out of 16-bit range" +; + +headers +: brif ( address condition -- ) + h# 4000.0000 or swap here offset-16 or asm, +; + +: mr ( -- ) \ rdest,rsrc + 444 1 << 31 >op + asm, \ "or rdest,rsrc,rsrc" + get-operands + ra r-register dup rd-field rb-field +; +: li ( -- ) \ rdest,value + get-operands + 14 >op asm, \ "addi rdest,r0,value" + r-register rd-field 0 ra-field number ?simm imm-field +; +: lis ( -- ) + 15 >op asm, \ "addis rdest,r0,high(value)" + get-operands + r-register rd-field 0 ra-field number 16 >>a imm-field +; +: set ( -- ) \ rdest,value + \ We can't keep rd on the stack because a number might be there, + \ waiting for a "*" in the number field to pick it up + get-operands r-register >r number ( value ) ( r: register ) + dup >16-bits? if ( value val.low ) + swap ( val.low value ) + 15 >op asm, \ "addis rdest,r0,high(value)" ( val.low value ) + r@ rd-field 0 ra-field 16 >> imm-field ( val.low ) + ?dup if + 24 >op asm, \ "ori rdest,rdest,low(value) ( ) + imm-field r@ rd-field r@ ra-field + then ( ) + else ( value val.low ) + nip + 14 >op asm, \ "addi rdest,r0,value" ( val.low reg ) + r@ rd-field 0 ra-field imm-field ( ) + then + r> drop +; +: countdown ( adr -- ) 16 >op asm, 16 rd-field 0 ra-field set-bd-field ; +: nop ( -- ) 24 >op asm, ; \ ori r0,r0,0 + + \ 0,1 are unassigned + +64bit 2 d: tdi to,ra,simm + 3 d: twi to,ra,simm + + \ 4,5,6 are unassigned + + 7 d: mulli rd,ra,simm + 8 d: subfic rd,ra,simm +power 9 d: dozi rd,ra,simm + 10 d: cmpli crfd,l,ra,uimm + 11 d: cmpi crfd,l,ra,simm + 12 d: addic rd,ra,simm + 13 d: addic. rd,ra,simm + 14 d: addi rd,ra,simm + 15 d: addis rd,ra,simms + + \ 16 is bcX + \ 17 is sc + \ 18 is bX + \ 19 is xl: and bclr,bctr + + 20 r: rlwimi ra,rs,sh,mb,me + 21 r: rlwinm ra,rs,sh,mb,me +power 22 r: rlmi ra,rs,rb,mb,me + 23 r: rlwnm ra,rs,rb,mb,me + + 24 d: ori ra,rs,uimm + 25 d: oris ra,rs,uimms + 26 d: xori ra,rs,uimm + 27 d: xoris ra,rs,uimms + 28 d: andi. ra,rs,uimm + 29 d: andis. ra,rs,uimms + +64bit 0 rd: rldicl ra,rs,shd,md +64bit 1 rd: rldicr ra,rs,shd,md +64bit 2 rd: rldic ra,rs,shd,md +64bit 3 rd: rldimi ra,rs,shd,md +64bit 8 rd: rldcl ra,rs,rb,md +64bit 9 rd: rldcr ra,rs,rb,md + + \ 31 is x: xc: xo: + + 32 d: lwz rd,d(ra) + 33 d: lwzu rd,d(ra) + 34 d: lbz rd,d(ra) + 35 d: lbzu rd,d(ra) + 36 d: stw rs,d(ra) + 37 d: stwu rs,d(ra) + 38 d: stb rs,d(ra) + 39 d: stbu rs,d(ra) + 40 d: lhz rd,d(ra) + 41 d: lhzu rd,d(ra) + 42 d: lha rd,d(ra) + 43 d: lhau rd,d(ra) + 44 d: sth rs,d(ra) + 45 d: sthu rs,d(ra) + 46 d: lmw rd,d(ra) + 47 d: stmw rs,d(ra) + 48 d: lfs frd,d(ra) + 49 d: lfsu frd,d(ra) + 50 d: lfd frd,d(ra) + 51 d: lfdu frd,d(ra) + 52 d: stfs frs,d(ra) + 53 d: stfsu frs,d(ra) + 54 d: stfd frs,d(ra) + 55 d: stfdu frs,d(ra) + +\ 56,57 are unassigned + +64bit 58 0 dl: ld rd,ds(ra) +64bit 58 1 dl: ldu rd,ds(ra) +64bit 58 2 dl: lwa rd,ds(ra) + +\ 59 is s: words +\ 60,61 are unassigned + +64bit 62 0 dl: std rs,ds(ra) +64bit 62 1 dl: stdu rs,ds(ra) + +\ 63 is f: + + + 16 0 0 b: bc bo,bi,bd + 16 0 1 b: bca bo,bi,bd + 16 1 0 b: bcl bo,bi,bd + 16 1 1 b: bcla bo,bi,bd + + 17 1 0 b: sc no-args + + 18 0 0 b: b lif + 18 0 1 b: bl lif + 18 1 0 b: ba lif + 18 1 1 b: bla lif + +\ Opcode 19 + + 19 16 0 b: bclr bo,bi + 19 16 1 b: bclrl bo,bi + + 19 528 0 b: bcctr bo,bi + 19 528 1 b: bcctrl bo,bi + + 0 xl: mcrf crfd,crfs + + 50 xl: rfi no-args + 150 xl: isync no-args + + 33 xl: crnor crbd,crba,crbb + 129 xl: crandc crbd,crba,crbb + 193 xl: crxor crbd,crba,crbb + 225 xl: crnand crbd,crba,crbb + 257 xl: crand crbd,crba,crbb + 289 xl: creqv crbd,crba,crbb + 417 xl: crorc crbd,crba,crbb + 449 xl: cror crbd,crba,crbb + +\ Opcode 31 + + 8 xo: subfc rd,ra,rb + 10 xo: addc rd,ra,rb + 40 xo: subf rd,ra,rb + 104 xo: neg rd,ra +power 107 xo: mul rd,ra,rb + 136 xo: subfe rd,ra,rb + 138 xo: adde rd,ra,rb + 200 xo: subfze rd,ra + 202 xo: addze rd,ra + 232 xo: subfme rd,ra + 234 xo: addme rd,ra + 235 xo: mullw rd,ra,rb +power 264 xo: doz rd,ra,rb + 266 xo: add rd,ra,rb + 331 xo: div rd,ra,rb +power 360 xo: abs rd,ra + 363 xo: divs rd,ra,rb +64bit 457 xo: divdu rd,ra,rb + 459 xo: divwu rd,ra,rb + 491 xo: divw rd,ra,rb +power 488 xo: nabs rd,ra +64bit 233 xo: mulld rd,ra,rb +64bit 489 xo: divd rd,ra,rb + + 28 xc: and ra,rs,rb + 60 xc: andc ra,rs,rb + 124 xc: nor ra,rs,rb + 284 xc: eqv ra,rs,rb + 316 xc: xor ra,rs,rb + 412 xc: orc ra,rs,rb + 444 xc: or ra,rs,rb + 476 xc: nand ra,rs,rb + + 11 xc: mulhwu rd,ra,rb + 75 xc: mulhw rd,ra,rb +64bit 9 xc: mulhdu rd,ra,rb +64bit 73 xc: mulhd rd,ra,rb + 922 xc: extsh ra,rs + 954 xc: extsb ra,rs +64bit 986 xc: extsw ra,rs + + 24 xc: slw ra,rs,rb + 536 xc: srw ra,rs,rb + 792 xc: sraw ra,rs,rb + 824 xc: srawi ra,rs,sh +64bit 27 xc: sld ra,rs,rb +64bit 539 xc: srd ra,rs,rb +64bit 413 xc: sradi ra,rs,shd +64bit 794 xc: srad ra,rs,rb + + 26 xc: cntlzw ra,rs +64bit 58 xc: cntlzd ra,rs + + 150 xc: stwcx rs,ra,rb \ XXX the non-dotted form doesn't exist! +64bit 214 xc: stdcx rs,ra,rb \ XXX the non-dotted form doesn't exist! + +power 277 xc: lscbx rd,ra,rb + +power 29 xc: maskg ra,rs,rb +power 541 xc: maskir ra,rs,rb +power 537 xc: rrib ra,rs,rb +power 153 xc: sle ra,rs,rb +power 217 xc: sleq ra,rs,rb +power 216 xc: sllq ra,rs,rb +power 152 xc: slq ra,rs,rb +power 184 xc: sliq ra,rs,sh +power 248 xc: slliq ra,rs,sh +power 952 xc: sraiq ra,rs,sh +power 920 xc: sraq ra,rs,rb +power 665 xc: sre ra,rs,rb +power 921 xc: srea ra,rs,rb +power 729 xc: sreq ra,rs,rb +power 696 xc: sriq ra,rs,sh +power 760 xc: srliq ra,rs,sh +power 728 xc: srlq ra,rs,rb +power 664 xc: srq ra,rs,rb + + 531 x: clcs rd,ra + + 0 x: cmp crfd,l,ra,rb + 32 x: cmpl crfd,l,ra,rb + + 86 x: dcbf ra,rb + 470 x: dcbi ra,rb + 54 x: dcbst ra,rb + 278 x: dcbt ra,rb + 246 x: dcbtst ra,rb + 1014 x: dcbz ra,rb + + 310 x: eciwx rd,ra,rb + 438 x: ecowx rs,ra,rb + 854 x: eieio no-args + + 982 x: icbi ra,rb + + 87 x: lbzx rd,ra,rb + 119 x: lbzux rd,ra,rb + 343 x: lhax rd,ra,rb + 375 x: lhaux rd,ra,rb + 790 x: lhbrx rd,ra,rb + 279 x: lhzx rd,ra,rb + 311 x: lhzux rd,ra,rb + 23 x: lwzx rd,ra,rb + 55 x: lwzux rd,ra,rb + 20 x: lwarx rd,ra,rb + 534 x: lwbrx rd,ra,rb + 533 x: lswx rd,ra,rb + 597 x: lswi rd,ra,nb + +64bit 21 x: ldx rd,ra,rb +64bit 53 x: ldux rd,ra,rb +64bit 84 x: ldarx rd,ra,rb +64bit 341 x: lwax rd,ra,rb +64bit 373 x: lwaux rd,ra,rb + + 542 x: lwdx rd,ra,rb \ exponential + 670 x: stwdx rd,ra,rb \ exponential + + 215 x: stbx rs,ra,rb + 247 x: stbux rs,ra,rb + 407 x: sthx rs,ra,rb + 439 x: sthux rs,ra,rb + 918 x: sthbrx rs,ra,rb + 662 x: stwbrx rs,ra,rb + 151 x: stwx rs,ra,rb + 183 x: stwux rs,ra,rb + +64bit 149 x: stdx rs,ra,rb +64bit 181 x: stdux rs,ra,rb + + 725 x: stswi rs,ra,nb + 661 x: stswx rs,ra,rb + + 727 x: stfdx frs,ra,rb + 759 x: stfdux frs,ra,rb + 663 x: stfsx frs,ra,rb + 695 x: stfsux frs,ra,rb + +64bit 983 x: stfiwx frs,ra,rb + + 631 x: lfdux frd,ra,rb + 599 x: lfdx frd,ra,rb + 567 x: lfsux frd,ra,rb + 535 x: lfsx frd,ra,rb + + 512 x: mcrxr crfd + 19 x: mfcr rd + + 83 x: mfmsr rd + 339 x: mfspr rd,spr + 595 x: mfsr rd,sr + 659 x: mfsrin rd,rb + 144 x: mtcrf crm,rs + 146 x: mtmsr rs + 467 x: mtspr spr,rs + 210 x: mtsr sr,rs + 242 x: mtsrin rs,rb + 371 x: mftb rd,tbr \ tbr register is tb or tbu + +64bit 434 x: slbie no-args +64bit 498 x: slbia no-args + 566 x: tlbsync no-args +64bit 370 x: tlbia no-args + 598 x: sync no-args + 306 x: tlbie rb + 978 x: tlbld rb \ 603-specific + 1010 x: tlbli rb \ 603-specific + 4 x: tw to,ra,rb +64bit 68 x: td to,ra,rb + +\ Opcode 59 + + 18 s: fdivw frd,fra,frb + 20 s: fsubs frd,fra,frb + 21 s: fadds frd,fra,frb + 25 s: fmuls frd,fra,frc + 28 s: fmsubs frd,fra,frc,frb + 29 s: fmadds frd,fra,frc,frb + 30 s: fnmsubs frd,fra,frc,frb + 31 s: fnmadds frd,fra,frc,frb + +\ Opcode 63 + + 18 f: fdiv frd,fra,frb + 20 f: fsub frd,fra,frb + 21 f: fadd frd,fra,frb + 25 f: fmul frd,fra,frc + 28 f: fmsub frd,fra,frc,frb + 29 f: fmadd frd,fra,frc,frb + 30 f: fnmsub frd,fra,frc,frb + 31 f: fnmadd frd,fra,frc,frb + + 12 f: frsp frd,frb + 14 f: fctiw frd,frb + 15 f: fctiwz frd,frb +64bit 22 f: fsqrt frd,frb +64bit 23 f: fsel frd,frb +64bit 24 f: fres frd,frb +64bit 26 f: fsqrte frd,frb + 40 f: fneg frd,frb + 72 f: fmr frd,frb + 136 f: fnabs frd,frb + 264 f: fabs frd,frb + +64bit 814 f: fctid frd,frb +64bit 815 f: fctidz frd,frb +64bit 846 f: fcfid frd,frb + + 0 f: fcmpu crfd,fra,frb + 32 f: fcmpo crfd,fra,frb + + 38 f: mtfsb1 crbd + 64 f: mcrfs crfd,crfs ( no-. ) + 70 f: mtfsxl crbd + 134 f: mtfsfi crfd,imm + 583 f: mffs frd + 711 f: mtfsf fm,frb + +\ This definition prevents "add." from being parsed as a number. +: add. ( -- ) add 1 rc-bit ; + +headerless +: dis-16 ( -- ) + 31 2 ibits case + 0 of ['] bc endof + 1 of ['] bcl endof + 2 of ['] bca endof + 3 of ['] bcla endof + endcase + dis-name&operands +; + +16 op-map set-indexed-map +: dis-18 ( -- ) + 31 2 ibits case + 0 of ['] b endof + 1 of ['] bl endof + 2 of ['] ba endof + 3 of ['] bla endof + endcase + dis-name&operands +; +18 op-map set-indexed-map + +: dis-19 ( -- ) + 30 10 ibits 19-map find-sparse-entry + dup (.name) ( acf ) + 31 1 ibits if ." l" then + dis-operands +; +19 op-map set-indexed-map + +: dis-31 ( -- ) + 28 3 ibits 2 = if \ xo form, with o and . modifiers + 30 9 ibits 31-map find-indexed-entry dup (.name) ( acf ) + 21 1 ibits if ." o" then + else + 30 10 ibits 31-map find-indexed-entry dup (.name) ( acf ) + then ( acf ) + ?. dis-operands +; +31 op-map set-indexed-map + +: dis-59 ( -- ) + 30 5 ibits 59-map find-indexed-entry dup (.name) ?. dis-operands +; +59 op-map set-indexed-map + +: dis-63 ( -- ) + 30 10 ibits 63-map find-sparse-entry dup (.name) ?. dis-operands +; +63 op-map set-indexed-map + + +headers +\ Structured conditionals + +\ Condition names. There are more of these near the end of the file. +\ BO bits: 16 no-cond 8 cc bit true 4 no-ctr 2 ctr=0 +\ B1 values: 0 lt 1 gt 2 eq + +20 0 cond always +12 00 cond lt 04 00 cond ge +12 01 cond gt 04 01 cond le +12 02 cond eq 04 02 cond ne +12 03 cond vs 04 03 cond vc + +: ctr<>0 ( cond -- cond' ) + h# 0080.0000 invert [ also forth ] and [ previous ] +; +: ctr=0 ( cond -- cond' ) + ctr<>0 h# 0040.0000 [ also forth ] or [ previous ] +; + +headerless +: <mark ( -- <mark ) here ; +: >mark ( -- >mark ) here ; +: >resolve ( >mark -- ) here over offset-16 over asm@ + swap asm! ; +: <resolve ( -- ) ; + +headers +: but ( mark1 mark2 -- mark2 mark1 ) swap ; +: yet ( mark -- mark mark ) dup ; + +: ahead ( -- >mark ) >mark here always brif ; +: if ( cond -- >mark ) >mark here rot -cond brif ; +: then ( >mark -- ) >resolve ; +: else ( >mark -- >mark1 ) ahead but then ; +: begin ( -- <mark ) <mark ; +: until ( <mark cond -- ) -cond brif ; +: again ( <mark -- ) always brif ; +: repeat ( >mark <mark -- ) again then ; +: while ( <mark cond -- >mark <mark ) if but ; + +\ Define these last to delay overloading of the forth versions + +\ There are no explicit condition codes for unsigned comparison; +\ there is a "cmpl" instruction that performs an unsigned ("logical") +\ comparison, setting the regular less-than and greater-than bits. + +12 00 cond 0< 04 00 cond 0>= +12 00 cond < 04 00 cond >= +12 01 cond 0> 04 01 cond 0<= +12 01 cond > 04 01 cond <= +12 02 cond 0= 04 02 cond 0<> +12 02 cond = 04 02 cond <> + +previous definitions + +\ 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/ppc/banner.fth =================================================================== --- cpu/ppc/banner.fth (rev 0) +++ cpu/ppc/banner.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,35 @@ +purpose: Displays banner describing system configuration +\ See license at end of file + +\ Display the startup message. + +: fw-title ( -- ) + ." Power Firmware(TM) by FirmWorks" + " build-date" $find if ." , Built " execute type else 2drop then cr + ?spaces ." Copyright (c) 1995-2000, FirmWorks. All Rights Reserved." cr +; +' fw-title to .firmware + +\ 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/ppc/basefw.bth =================================================================== --- cpu/ppc/basefw.bth (rev 0) +++ cpu/ppc/basefw.bth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,113 @@ +purpose: Load file for base firmware - no platform specifics +\ See license at end of file + +dictionary: ${BP}/cpu/ppc/build/tools.dic +command: &ppcforth &dictionary &this +build-now + +hex + +\ ' $report-name is include-hook + +\ create use-prep-nvram + +create include-help \ Include help facility + +fload ${BP}/cpu/ppc/occhksum.fth \ IP checksum primitive + +alias cfill fill +fload ${BP}/ofw/core/ofwcore.fth \ Device tree and other OBP routines +fload ${BP}/ofw/core/ofwfw.fth \ FirmWorks enhancements + +fload ${BP}/ofw/core/memops.fth \ Call memory node methods +fload ${BP}/ofw/core/mmuops.fth \ Call MMU node methods +\ : cfill fill ; + +fload ${BP}/cpu/ppc/cpuclass.fth \ CPU characterization + +\ Load millisecond timer +fload ${BP}/cpu/ppc/getms.fth \ Timer access + +fload ${BP}/cpu/ppc/call.fth \ Primitive subroutine calls +fload ${BP}/cpu/ppc/centry.fth \ Low-level client entry and exit +fload ${BP}/cpu/ppc/fb8-ops.fth \ S Machine code for fb8 + +fload ${BP}/ofw/confvar/loadcv.fth \ Configuration variables +fload ${BP}/ofw/core/silentmd.fth \ NVRAM variable silent-mode? + +fload ${BP}/ofw/termemu/loadfb.fth \ Frame buffer support +fload ${BP}/ofw/termemu/difont.fth \ Get font from a dropin module + +fload ${BP}/ofw/gui/alert.fth \ Basic dialogs and alerts +fload ${BP}/dev/stringio.fth \ Output diversion + +fload ${BP}/ofw/core/loadmore.fth \ Load additional core stuff + +fload ${BP}/ofw/inet/loadtftp.fth \ Trivial File Transfer Protocol pkg. + +fload ${BP}/cpu/ppc/forthint.fth \ Alarm handler + +fload ${BP}/cpu/ppc/regacc.fth \ Register access words + +fload ${BP}/ofw/fcode/loadfcod.fth \ S Fcode interpreter + +fload ${BP}/ofw/fcode/regcodes.fth \ Register access words +fload ${BP}/ofw/fcode/extcodes.fth \ Firmworks extension FCodes + +\ File system readers +fload ${BP}/ofw/core/initprog.fth \ FCode and Forth source load formats + +fload ${BP}/ofw/core/infltdi.fth \ Support for compressed dropin drivers +' in-little-endian? to flip-code? \ Flip inflated code when in LE mode + +[ifdef] resident-packages +support-package: fat-file-system + fload ${BP}/ofw/fs/fatfs/loadpkg.fth \ FAT file system reader +end-support-package + +support-package: iso9660-file-system + fload ${BP}/ofw/fs/cdfs/loadpkg.fth \ ISO 9660 CD-ROM file system reader +end-support-package + +support-package: disk-label + fload ${BP}/ofw/disklabel/loadpkg.fth \ Disk label package +end-support-package +[then] + +[ifdef] resident-packages +fload ${BP}/ofw/fs/fatfs/fdisk2.fth \ Partition map administration +[else] +autoload: fdisk2.fth +defines: $.partitions +defines: .partitions +\ defines: init-nt-disk +defines: $partition +[then] + +[ifndef] no-heads +.( --- Saving basefw.dic --- ) cr "" basefw.dic save-forth +[then] + +\ 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/ppc/bat.fth =================================================================== --- cpu/ppc/bat.fth (rev 0) +++ cpu/ppc/bat.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,236 @@ +purpose: Block Address Translation register access +\ See license at end of file + +hex + +headerless +code ibat! ( bat-lo bat-hi ibat# -- ) + lwz t0,0(sp) + lwz t1,1cell(sp) + + cmpi 0,0,tos,0 + = if + sync isync + mtspr ibat0u,t0 + mtspr ibat0l,t1 + sync isync + else + + cmpi 0,0,tos,1 + = if + sync isync + mtspr ibat1u,t0 + mtspr ibat1l,t1 + sync isync + else + + cmpi 0,0,tos,2 + = if + sync isync + mtspr ibat2u,t0 + mtspr ibat2l,t1 + sync isync + else + + cmpi 0,0,tos,3 + = if + sync isync + mtspr ibat3u,t0 + mtspr ibat3l,t1 + sync isync + then then then then + + lwz tos,2cells(sp) + addi sp,sp,3cells +c; + +code dbat! ( bat-lo bat-hi dbat# -- ) + lwz t0,0(sp) + lwz t1,1cell(sp) + + cmpi 0,0,tos,0 + = if + sync isync + mtspr dbat0u,t0 + mtspr dbat0l,t1 + sync isync + else + + cmpi 0,0,tos,1 + = if + sync isync + mtspr dbat1u,t0 + mtspr dbat1l,t1 + sync isync + else + + cmpi 0,0,tos,2 + = if + sync isync + mtspr dbat2u,t0 + mtspr dbat2l,t1 + sync isync + else + + cmpi 0,0,tos,3 + = if + sync isync + mtspr dbat3u,t0 + mtspr dbat3l,t1 + sync isync + then then then then + + lwz tos,2cells(sp) + addi sp,sp,3cells +c; + +code ibat@ ( ibat# -- bat-lo bat-hi ) + cmpi 0,0,tos,0 + = if + mfspr tos,ibat0u + mfspr t1,ibat0l + else + + cmpi 0,0,tos,1 + = if + mfspr tos,ibat1u + mfspr t1,ibat1l + else + + cmpi 0,0,tos,2 + = if + mfspr tos,ibat2u + mfspr t1,ibat2l + else + + cmpi 0,0,tos,3 + = if + mfspr tos,ibat3u + mfspr t1,ibat3l + then then then then + + stwu t1,-1cell(sp) +c; + +code dbat@ ( dbat# -- bat-lo bat-hi ) + cmpi 0,0,tos,0 + = if + mfspr tos,dbat0u + mfspr t1,dbat0l + else + + cmpi 0,0,tos,1 + = if + mfspr tos,dbat1u + mfspr t1,dbat1l + else + + cmpi 0,0,tos,2 + = if + mfspr tos,dbat2u + mfspr t1,dbat2l + else + + cmpi 0,0,tos,3 + = if + mfspr tos,dbat3u + mfspr t1,dbat3l + then then then then + + stwu t1,-1cell(sp) +c; + +headers +0 constant ibat +1 constant dbat +2 constant i&dbats + +headerless +false value l1-writethru? + +: cache-mode ( io? -- mode ) + if 38 else 10 l1-writethru? if 40 or then then +; +: mask-bat-adr ( adr -- hi-bits ) 1.ffff invert and ; + +headers +: bat! ( pa va len io? bat# which -- ) + >r >r >r >r ( pa va ) ( R: which bat# io? len ) + mask-bat-adr r> ( pa BEPI len ) ( R: which bat# io) + 1- h# 11 >> 2 << or 2 or ( supervisor ) ( pa bat-hi ) + swap mask-bat-adr ( bat-hi BRPN ) + \ Coherent in both cases, no cache for I/O + r> cache-mode or ( bat-hi BRPN|WIMG ) ( R: wh bat# ) + 2 or ( r/w ) swap ( bat-lo bat-hi ) ( R: which bat# ) + r> r> case + dbat of dbat! endof + ibat of ibat! endof + i&dbats of 3dup dbat! ibat! endof + endcase +; + +: bat@ ( bat# which -- false | pa va len flags true ) + dbat = if dbat@ else ibat@ then ( bat-lo bat-hi ) + dup 3 and 0= if 2drop false exit then ( bat-lo bat-hi ) + over h# 7f and >r ( bat-lo bat-hi r: flags ) + swap mask-bat-adr swap ( pa bat-hi ) + dup mask-bat-adr swap ( pa va bat-hi ) + 2 >> 7ff and 1+ h# 11 << ( pa va len ) + r> true +; +headerless + +\ Motorola says that the BAT registers can become corrupted if +\ two of them happen to map overlapping ranges, even if address +\ translation is turned off, and that said corruption can be prevented +\ by invalidating all the BAT registers before programming any of them. + +: clear-bats ( -- ) 4 0 do 0 0 i ibat! 0 0 i dbat! loop ; +: clear-srs ( -- ) 10 0 do 0 i sr! loop ; + +: .xbats ( ibat|dbat -- ) + 4 0 do + dup ibat = if ." I" else ." D" then + i . + i over bat@ if ( pa va len flags ) + rot 9 u.r rot d# 10 u.r swap 9 u.r ( flags ) + binary 2 spaces <# u# u# 2/ ascii . hold u# u# u# u# u#> type hex + else + ." --invalid--" + then + cr + loop + drop +; +headers +: .bats ( -- ) + base @ >r hex + ." # Virtual Physical Length WIMG.PP" cr + ibat .xbats + dbat .xbats + r> 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/ppc/bat601.fth =================================================================== --- cpu/ppc/bat601.fth (rev 0) +++ cpu/ppc/bat601.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,100 @@ +purpose: Block Address Translation register access for PowerPC 601 +\ See license at end of file + +hex + +\ PPC 601 has a unified cache and a single set of BAT registers, accessed +\ with the SPR numbers used for IBATs + +\ The layout of the 601 BAT bits is different from the standard PPC layout + +: bat!-601 ( pa va len io? bat# which -- ) + drop >r >r >r ( pa va ) ( R: bat# io? len ) + + swap mask-bat-adr \ phys block # ( va PBN ) + r> 1- h# 11 >> or \ block length ( va PBN|BL) ( R: bat# io? ) + h# 40 or \ valid bit ( va bat-lo ) + + swap mask-bat-adr \ log. page index ( bat-lo BLPI ) + \ no cache for I/O, coherent and no protection in both cases + r> if h# 32 else h# 12 then or ( bat-lo bat-hi ) ( R: bat# ) + + r> ibat! +; + +: bat@-601 ( bat# which -- false | pa va len flags true ) + drop ibat@ ( bat-lo bat-hi ) + over h# 40 and 0= if 2drop false exit then ( bat-lo bat-hi ) + over mask-bat-adr ( bat-lo bat-hi pa ) + over mask-bat-adr ( bat-lo bat-hi pa va ) + 2swap swap h# 3f and 1+ h# 11 << ( pa va bat-hi len ) + swap h# 7f and true ( pa va len flags t ) +; + +\ On some processors, the BAT registers can become corrupted if +\ two of them happen to map overlapping ranges, even if address +\ translation is turned off, and that said corruption can be prevented +\ by invalidating all the BAT registers before programming any of them. + +: clear-bats-601 ( -- ) + 4 0 do 0 0 i ibat! loop +; + +: .bats-601 ( -- ) + base @ >r hex + ." # Virtual Physical Length WIMsuPP" cr + 4 0 do + i . + i ibat bat@-601 if ( pa va len flags ) + rot 9 u.r rot d# 10 u.r swap 8 u.r ( flags ) + binary 2 spaces <# u# u# u# u# u# u# u# u#> type hex + else + ." --invalid--" + then + cr + loop + r> base ! +; + +warning @ warning off +\ Overlay standard PowerPC versions with switchable versions +: bat@ ( pa va len io? bat# which -- ) + 601? if bat@-601 exit then + bat@ +; +: bat! ( pa va len io? bat# which -- ) + 601? if bat!-601 exit then + bat! +; +: clear-bats ( -- ) + 601? if clear-bats-601 exit then + clear-bats +; +: .bats ( -- ) + 601? if .bats-601 exit then .bats +; +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: cpu/ppc/batf601.fth =================================================================== --- cpu/ppc/batf601.fth (rev 0) +++ cpu/ppc/batf601.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,184 @@ +purpose: Block address translation (BAT) fault handler +\ See license at end of file + +\ This handler for the DSI interrupt treats the BAT registers +\ as a 4-entry software-filled TLB. 4 BAT registers are not +\ enough to hold all of the translations that the firmware and +\ the client program might need, so we use the BATs as a translation +\ cache. When a translation fault occurs, we pick a BAT register +\ and change its value to translate the address at which the fault +\ occurred. + +\ The 601 BAT registers are not compliant with the PowerPC architecture. +\ The locations of some fields are different, and each 601 BAT can only +\ map 8 MBytes, as opposed to 256 MBytes for PPC BATs. In order to +\ minimize memory usage, and to keep the same mapping granularity +\ between the 601 and PPC, we allow mapping only at 256 MByte granularity, +\ simulating that granularity in software in this implementation by +\ copying logical address bits 4-8 to the physical address. + +\ This allows us to make the mapping table quite small, so it will +\ fit nicely in otherwise-unused space in the trap vector. + +\ Each table entry uses 8 bits - 4 for the physical block number +\ and 4 for the WIMG bits - so we use 8-bit table entries. +\ The other BAT register bits are either fixed values or can be +\ derived from the logical address. + +\ For 601, the BAT registers do not support the "G" bit, so we mask it out. + +\ We use a round-robin replacement policy. + +\ Low memory usage: +\ Firmware private area: +\ e0: save r3 and t1 +\ e4: save lr and t2 +\ e8: save t0 +\ DSI vector: +\ 300.. jump to dsi-handler +\ 37f: next-bat (1 byte) +\ 380: bat-table (16 bytes) + +headerless + +label bat-fault-handler-601 + \ We assume that t0 has been saved at location f8 and now contains + \ the fault address. + + lwz r3,h#e4(r0) \ Restore lr + mtspr lr,r3 + lwz r3,h#e0(r0) \ Restore r3 + + stw t1,h#e0(r0) + stw t2,h#e4(r0) + mfcr t2 + stw t2,h#ec(r0) \ Save CR + +\ [ifdef] notyet +\ \ Determine the fault type +\ mfspr t1,dsisr \ SPR18 +\ add. t1,t1,t1 \ Test bit 1 by shifting it to the sign bit +\ 0>= if \ Not a translation fault +\ \ Restore registers and jump to unexpected exception handler +\ then +\ [then] + + \ Fault address is in t0 + + \ Index into translation table and get translation info + rlwinm t2,t0,4,28,31 \ Convert high 4 bits to a table index + lbz t2,h#380(t2) \ Translation entry in t2 + + \ Format lower BAT entry + rlwinm t1,t2,24,0,3 \ Shift up physical block number + rlwimi t1,t0,0,4,8 \ Merge in bits 4-8 of virtual address + ori t1,t1,h#7f \ valid (40 bit) and 8 MByte size (3f bits) + + \ Format upper BAT entry + + rlwinm t0,t0,0,0,8 \ Mask out lower bits, leaving page index + rlwimi t0,t2,3,25,27 \ Shift WIMG bits into place, masking out G + ori t0,t0,2 \ Allow all accesses + + lbz t2,h#37f(r0) \ Select a BAT + + \ Replace BAT value + \ On average, it takes more instructions to do an indexed jump + \ than to do explicit compares for this number of cases. + + cmpi 0,0,t2,0 + = if + sync isync + mtspr ibat0u,t0 + mtspr ibat0l,t1 + sync isync + set t2,1 + else + + cmpi 0,0,t2,1 + = if + sync isync + mtspr ibat1u,t0 + mtspr ibat1l,t1 + sync isync + set t2,2 + else + + cmpi 0,0,t2,2 + = if + sync isync + mtspr ibat2u,t0 + mtspr ibat2l,t1 + sync isync + set t2,3 + else + + sync isync + mtspr ibat3u,t0 + mtspr ibat3l,t1 + sync isync + set t2,0 + then then then + + stb t2,h#37f(r0) \ Update BAT replacement pointer + + + \ Restore registers + lwz t0,h#ec(r0) + mtcrf h#ff,t0 \ Restore CR + lwz t0,h#e8(r0) \ Restore t0 + lwz t1,h#e0(r0) \ Restore t1 + lwz t2,h#e4(r0 \ Restore t2 + + \ Return from interrupt + rfi +end-code + +label bat-dsi-handler-601 + stw t0,h#e8(r0) \ Save t0 in the exception table area + mfspr t0,dar \ Get fault address + bat-fault-handler-601 again \ Jump to common code +end-code + +label bat-isi-handler-601 + stw t0,h#e8(r0) \ Save t0 in the exception table area + mfspr t0,srr0 \ Get fault address + bat-fault-handler-601 again \ Jump to common code +end-code + +: install-bat-handler-601 ( -- ) + init-paged-mmu + + bat-dsi-handler-601 h# 300 put-exception + bat-isi-handler-601 h# 400 put-exception +; +warning @ warning off +: install-bat-handler ( -- ) + 601? if install-bat-handler-601 exit then + install-bat-handler +; +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: cpu/ppc/batfault.fth =================================================================== --- cpu/ppc/batfault.fth (rev 0) +++ cpu/ppc/batfault.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,321 @@ +purpose: Block address translation (BAT) fault handler +\ See license at end of file + +\ This handler for the DSI interrupt treats the BAT registers +\ as a 4-entry software-filled TLB. 4 BAT registers are not +\ enough to hold all of the translations that the firmware and +\ the client program might need, so we use the BATs as a translation +\ cache. When a translation fault occurs, we pick a BAT register +\ and change its value to translate the address at which the fault +\ occurred. + +\ For simplicity, we use a fixed block size. For memory economy, +\ we use the largest possible block size (256 MBytes), thus requiring +\ a 16-entry in-memory translation table indexed by the high 4 bits +\ of the logical address. + +\ Each table entry uses 8 bits - 4 for the physical block number +\ and 4 for the WIMG bits - so we use 8-bit table entries. +\ The other BAT register bits are either fixed values or can be +\ derived from the logical address. + +\ We use a round-robin replacement policy. + +\ We store the translation table in the DSI handler vector area so +\ it is easy to access from the fault handlers. + +h# 300 /exc + constant bat-table +bat-table h# 10 + constant 'next-bat +\ /exc h# 18 + constant /dsi-footprint + +\ On entry: +\ r2, r3, and lr have been saved. r2 points to this cpu's exception-area, + +\ Low memory usage: +\ Firmware private area: +\ 0: save r3 and t1 +\ 4: save r2 +\ 8: save lr and t2 +\ c: save t0 +\ 10: save cr +\ DSI vector: +\ 300.. jump to dsi-handler +\ 3x0: bat-table (16 bytes) +\ 3y0: next-bat (1 byte) + +\ Note: next-bat should be cpu specific: 3yc ? + +label bat-dsi-handler + mfcr r3 + stw r3,h#10(r2) \ Save CR + + \ Determine the fault type + mfspr r3,dsisr \ SPR18 + rlwinm. r3,r3,0,1,1 \ Test bit 1 + 0= if \ Not a translation fault +( Label ) begin but + \ Restore registers and jump to unexpected exception handler + lwz r3,h#10(r2) + mtcrf h#ff,r3 \ Restore CR + addi r3,r0,h#300 \ Exception address +\ XXX we need to jump to the physical address of save-state + save-state b * \ branch to exception handler + then + + mfspr r3,dar \ Get fault address + rlwinm r3,r3,4,28,31 \ Convert high 4 bits to a table index + lbz r3,h#380(r3) \ Translation entry in t2 + cmpi 0,0,r3,0 + <> until \ Jump back to Label if no translation + + lwz r3,h#08(r2) \ Restore lr + mtspr lr,r3 + + stw t0,h#0c(r2) \ Save t0 in the exception table area + stw t2,h#08(r2) \ Save t2 + + mfspr t0,dar \ Get fault address + + \ Index into translation table and get translation info + rlwinm t2,t0,4,28,31 \ Convert high 4 bits to a table index + lbz t2,h#380(t2) \ Translation entry in t2 + + \ Format Upper BAT entry + rlwinm t0,t0,0,0,3 \ Mask out lower bits, leaving page index + ori t0,t0,h#1ffe \ 256M block size, supervisor mode + + \ Format Lower BAT entry + rlwinm r3,t2,24,0,3 \ Shift up physical block number + rlwimi r3,t2,3,25,28 \ Shift WIMG bits into place + ori r3,r3,2 \ Allow all accesses + + lbz t2,h#37f(r0) \ Select a BAT + + \ Replace BAT value + \ On average, it takes more instructions to do an indexed jump + \ than to do explicit compares for this number of cases. + + cmpi 0,0,t2,0 = if + sync isync mtspr dbat0u,t0 mtspr dbat0l,r3 sync isync + set t2,1 + else + + cmpi 0,0,t2,1 = if + sync isync mtspr dbat1u,t0 mtspr dbat1l,r3 sync isync + set t2,2 + else + +[ifdef] NTkludge + \ Some earlier NT HALs have a bug that causes them to hang + \ if the KSEG0 (virt 8000.0000 -> phys 0) mapping resides in + \ IBAT3, so to be safe, we avoid using either IBAT3 or DBAT3. + sync isync mtspr dbat2u,t0 mtspr dbat2l,r3 sync isync + set t2,0 + then then +[else] + cmpi 0,0,t2,2 = if + sync isync mtspr dbat2u,t0 mtspr dbat2l,r3 sync isync + set t2,3 + else + sync isync mtspr dbat3u,t0 mtspr dbat3l,r3 sync isync + set t2,0 + then then then +[then] + + stb t2,h#37f(r0) \ Update BAT replacement pointer + + \ Restore registers + lwz t0,h#10(r2) + mtcrf h#ff,t0 \ Restore CR + lwz t0,h#0c(r2) \ Restore t0 + lwz r3,h#00(r2) \ Restore r3 + lwz t2,h#08(r2) \ Restore t2 + lwz r2,h#04(r2) \ Restore r2 + + \ Return from interrupt + rfi +end-code + +label bat-isi-handler + mfcr r3 + stw r3,h#10(r2) \ Save CR + + \ In violation of the PowerPC architecture definition, the 603 does + \ not implement the translation fault bit for instruction accesses, + \ so we assume that any 603 instruction fault is a translation fault. + \ This is tolerable because instruction accesses to non-existent devices + \ do not occur on purpose - probing to determine the presence of devices + \ is done with data accesses. + +\ However, the 603 ISI exception is front-ended by the ITLB miss handler, +\ in which we set the translation fault bit. + +\ mfspr r3,pvr +\ rlwinm r3,r3,16,16,31 +\ cmpi 0,0,r3,3 +\ 0<> if + + \ Determine the fault type + mfspr r3,srr1 \ Fault type is in SRR1 for I faults + rlwinm. r3,r3,0,1,1 \ Test bit 1 + 0= if \ Not a translation fault +( Label ) begin but + \ Restore registers and jump to unexpected exception handler + lwz r3,h#10(r2) + mtcrf h#ff,r3 \ Restore CR + addi r3,r0,h#400 \ Exception address + save-state b * \ branch to exception handler + then +\ then + + mfspr r3,srr0 \ Get fault address + rlwinm r3,r3,4,28,31 \ Convert high 4 bits to a table index + lbz r3,h#380(r3) \ Translation entry in t2 + cmpi 0,0,r3,0 + <> until \ Jump back to Label if no translation + + lwz r3,h#08(r2) \ Restore lr + mtspr lr,r3 + + stw t0,h#0c(r2) \ Save t0 in the exception table area + stw t2,h#08(r2) \ Save t2 + + mfspr t0,srr0 \ Get fault address + + \ Index into translation table and get translation info + rlwinm t2,t0,4,28,31 \ Convert high 4 bits to a table index + lbz t2,h#380(t2) \ Translation entry in t2 + + \ Format Upper BAT entry + rlwinm t0,t0,0,0,3 \ Mask out lower bits, leaving page index + ori t0,t0,h#1ffe \ 256M block size, supervisor mode + + \ Format Lower BAT entry + rlwinm r3,t2,24,0,3 \ Shift up physical block number + rlwimi r3,t2,3,25,27 \ Shift WIM bits into place, masking off G + ori r3,r3,2 \ Allow all accesses + + lbz t2,h#37f(r0) \ Select a BAT + + \ Replace BAT value + \ On average, it takes more instructions to do an indexed jump + \ than to do explicit compares for this number of cases. + + cmpi 0,0,t2,0 = if + sync isync mtspr ibat0u,t0 mtspr ibat0l,r3 sync isync + set t2,1 + else + + cmpi 0,0,t2,1 = if + sync isync mtspr ibat1u,t0 mtspr ibat1l,r3 sync isync + set t2,2 + else + + cmpi 0,0,t2,2 = if + sync isync mtspr ibat2u,t0 mtspr ibat2l,r3 sync isync + set t2,3 + else + sync isync mtspr ibat3u,t0 mtspr ibat3l,r3 sync isync + set t2,0 + then then then + + stb t2,h#37f(r0) \ Update BAT replacement pointer + + \ Restore registers + lwz t0,h#10(r2) + mtcrf h#ff,t0 \ Restore CR + lwz t0,h#0c(r2) \ Restore t0 + lwz r3,h#00(r2) \ Restore r3 + lwz t2,h#08(r2) \ Restore t2 + lwz r2,h#04(r2) \ Restore r2 + + \ Return from interrupt + rfi +end-code + +label tlb-miss-template \ 603-specific + mfspr r3,srr1 + set r2,h#40000000 \ Translation fault bit + rlwinm. r1,r3,0,13,13 + 0<> if \ Itlb + mtcrf h#80,r3 \ Restore Condition Register + or r3,r3,r2 \ Set instruction translation fault bit + mtspr srr1,r3 \ .. in SRR1 + else + mtcrf h#80,r3 \ Restore Condition Register + mtspr dsisr,r2 \ Set data translation fault bit + mfspr r2,dmiss \ Put the miss address + mtspr dar,r2 \ in the data address register + then + + mfmsr r3 + rlwinm r3,r3,0,15,13 \ Clear TGPR bit to reveal real registers + mtmsr r3 +end-code +here tlb-miss-template - constant /miss + +/miss la1+ to /rm-tlbmiss + +: put-tlb-miss-entry ( entry-vector target-vector -- ) + swap + tlb-miss-template /miss bounds ?do ( target-vector entry-vector ) + i l@ over instruction! la1+ + /l +loop ( target-vector entry-vector' ) + put-branch +; + +code invalidate-tlbs ( #entries -- ) + sync isync + + rlwinm tos,tos,12,0,19 + + begin + addic. tos,tos,h#-1000 + tlbie tos + 0= until + + tlbsync + + lwz tos,0(sp) + addi sp,sp,1cell +c; + +: install-bat-handler ( -- ) + init-paged-mmu + + bat-dsi-handler h# 300 put-exception + bat-isi-handler h# 400 put-exception + + software-tlb-miss? if + h# 1000 h# 400 put-tlb-miss-entry \ Instruction fetch TLB miss + h# 1100 h# 300 put-tlb-miss-entry \ Data load TLB + h# 1200 h# 300 put-tlb-miss-entry \ Data store TLB + else + then + + configure-tlb #tlb-lines invalidate-tlbs +; + +\ 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/ppc/batmap.fth =================================================================== --- cpu/ppc/batmap.fth (rev 0) +++ cpu/ppc/batmap.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,57 @@ +purpose: Block address translation (BAT) mapping setup +\ See license at end of file + +\ This code's data structures are shared with the low-level code +\ in batfault.fth and batf601.fth . See those files for a description. + +: >bat-map ( va -- adr ) h# 380 swap d# 28 rshift ca+ ; +: bat-invalid ( va -- ) 0 swap >bat-map c! ; +: bat-mapping ( va -- false | pa wim true ) + >bat-map c@ dup if dup 4 >> d# 28 << swap h# f and true then +; +: bat-set ( pa wimg va -- ) + -rot swap d# 28 rshift d# 4 lshift or ( va bte ) + swap >bat-map c! +; +: bat-map ( pa io? va -- ) + \ WIM bits - don't cache,coherent,guarded for I/O, coherent for memory + -rot if 7 else 2 then rot ( pa WIMG va ) + bat-set +; +h# 1000.0000 constant /bat-region +: clear-bat-table ( -- ) + 0 h# 37f c! \ bat entry 0 is next in line for replacement + + \ Invalidate all entries in the bat translation table + 0 0 do i bat-invalid /bat-region +loop +; +: setup-real-bat-table ( -- ) + 0 h# 37f c! \ bat entry 0 is next in line for replacement + + \ map first half of address space cacheable, rest non-cacheable. + 0 0 do i i 0< i bat-map /bat-region +loop +; + +\ 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/ppc/boot.fth =================================================================== --- cpu/ppc/boot.fth (rev 0) +++ cpu/ppc/boot.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,183 @@ +purpose: Boot code (cold and warm start) for PowerPC +\ See license at end of file + +\ Version for running Forth underneath a "wrapper" program + +\ The cold start code is executed when Forth is initially started. +\ Its job is to initialize the Forth virtual machine registers. +\ The warm start code is executed when Forth is re-entered, +\ perhaps as a result of an exception. + +hex + +only forth also labels also meta also definitions + +0 constant main-task +: init-user (s -- ) +; + +\ Stuff initialized at cold start time + +nuser memtop \ The top of the memory used by Forth +0 value #args \ The process's argument count +0 value args \ The process's argument list + +\ Defining these two in code is a significant performance optimization +\ for Open Firmware +code package( ( ihandle -- ) + 'user my-self lwz t0,* + stwu t0,-1cell(rp) + 'user my-self stw tos,* + pop-tos +c; +code )package ( -- ) + lwz t0,0(rp) + rdrop + 'user my-self stw t0,* +c; + +headerless + +label cold-code ( -- ) + +\ called with forth_startup(header-adr, functions, mem_end, &gargc, &gargv) +\ r3 r4 r5 r6 r7 + +\ Get some registers + \ XXX should save registers + +\ here origin - . cr + + nop + +\ Find the base address + here-t 4 + bl * \ Absolute address of next instruction + here-t set base,* \ Relative address of this instruction + mfspr t0,lr + subfc base,base,t0 \ Base address of Forth kernel + \ ( Use subfc for POWER compatibility) + \ Synchronize caches + addi t1,r5,31 \ round end address up ... + rlwinm t1,t1,0,0,26 \ ... to next cache line boundary + + sync isync + + begin + addi t1,t1,-32 cmpl 0,0,t1,r3 \ Down one cache line + dcbst r0,t1 sync isync icbi r0,t1 \ Synchronize it + <= until + + sync isync + +\ Find the user area size from the header + lwz t1,4(r3) \ Text size = offset to start of data + lwz t0,8(r3) \ Data size = user area size in t4 + + mr t5,r5 \ We'll need this later for memtop + +\ Allocate high memory for the stacks and stuff, starting at memtop and +\ allocating downwards. r5 is the allocation pointer. + +\ Allocate the RAM copy of the User Area + subfc r5,t0,r5 \ ( Use subfc for POWER compatibility) + rlwinm r5,r5,0,0,26 \ cache-line-align by clearing 5 low bits + mr up,r5 \ Set user pointer + + 'body main-task set t2,* \ Allow the exception handler to find the + \ user area by storing the address of the + stwx up,base,t2 \ main user area in the "constant" main-task + + \ Copy the initial User Area image to the RAM copy + add t3,t1,base \ Init-up pointer in t3 + mr t2,up \ Destination pointer + + srawi t0,t0,2 + mtspr ctr,t0 + addi t3,t3,-4 \ Account for pre-incrementing + addi t2,t2,-4 \ Account for pre-incrementing + begin + lwzu t0,4(t3) + stwu t0,4(t2) + countdown + +\ Synchronize the caches in the "next" region + sync isync dcbst r0,up sync isync icbi r0,up sync isync + + 'user powerpc? stw r8,* \ Set the PowerPC flag + +\ Now the user area has been copied to the proper place, so we can set +\ some important user variables whose initial values are determined at +\ run time. + +\ Top of memory and dictionary limit + 'user memtop stw t5,* + +\ Set the up0 user variable + 'user up0 stw up,* + +\ Establish the return stack and set the rp0 user variable + mr rp,r5 \ Set rp + 'user rp0 stw rp,* + rs-size-t negate addi r5,r5,* \ allocate space for the return stack + +\ Establish the Parameter Stack + 'user sp0 stw r5,* + addi sp,r5,4 \ account for the top of stack register + + ps-size-t negate addi r5,r5,* \ Allocate the stuff on the stack + + 'user limit stw r5,* \ Top of dictionary growth area + +\ Set the dictionary pointer + add t1,t1,base \ Base + text size + 'user dp stw t1,* \ Set dp + +\ Save the address of the system call table in the user variable syscall-vec + 'user syscall-vec stw r4,* + +\ Set the value of #args and args + 'user #args stw r6,* + 'user args stw r7,* + +\ Set the next pointer + mtspr ctr,up + +\ Enter Forth + 'body cold 4 - set ip,* + add ip,ip,base +c; + +headers + +[ifdef] little-endian-under-simulator +: sys-init-io + sys-init-io + ['] default-type is (type + ['] dumb-expect is expect + ['] lf-pstr is newline-pstring +; +[then] + +\ 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/ppc/builder.bth =================================================================== --- cpu/ppc/builder.bth (rev 0) +++ cpu/ppc/builder.bth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,35 @@ +purpose: Build file for PowerPC builder +\ See license at end of file + +dictionary: ${BP}/cpu/ppc/build/tools.dic +command: &ppcforth &dictionary &this +build-now + +fload ${BP}/ofw/tokenizer/tokenize.fth +fload ${BP}/forth/lib/builder.fth + +.( --- Saving builder.dic --- ) cr "" builder.dic save-forth + +\ 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/ppc/cache601.fth =================================================================== --- cpu/ppc/cache601.fth (rev 0) +++ cpu/ppc/cache601.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,53 @@ +purpose: Cache driver for PowerPC 601 chip +\ See license at end of file + +code stand-sync-cache-601 ( adr len -- ) + lwz t0,0(sp) + + cmpi 0,0,t0,0 + <> if + addi tos,tos,-1 \ Prevents touching the line past the end + begin + dcbst t0,tos + sync + icbi t0,tos + isync + addic. tos,tos,-32 + 0< until + sync + then + + lwz tos,1cell(sp) + addi sp,sp,2cells +c; + +warning @ warning off +: stand-init ( -- ) + stand-init + 601? if ['] stand-sync-cache-601 to sync-cache then +; +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: cpu/ppc/cache603.fth =================================================================== --- cpu/ppc/cache603.fth (rev 0) +++ cpu/ppc/cache603.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,233 @@ +purpose: Cache driver for 603 PowerPC chip +\ See license at end of file + +\ XXX - Dcache size is 1MB for Pegakid, because L2 cache is always on. +\ Fix this! Maybe parameterize /dcache? + +headerless +d# 32 constant /dcache-block +d# 32 constant /icache-block + +code (603-dcache-off) ( -- ) + \ Don't do anything if the data cache is already off + mfspr t1,hid0 + andi. t1,t1,h#4000 + 0= if + next + then + + \ Disable data translations before the flush loop: we'll run + \ in real mode to make sure there are no mapping problems. + mfmsr t2 + rlwinm t1,t2,0,28,26 \ Disable translation by clearing h#10 bit + sync isync + mtmsr t1 + sync isync + + \ Flush Dcache before turning it off + set t1,h#10.0000 \ Fill Dcache with known addresses + begin + addic. t1,t1,-32 + lwz r0,0(t1) + = until + + set t1,h#10.0000 \ Size of dcache + begin + addic. t1,t1,-32 \ Size of cache line + dcbf r0,t1 \ Flush Dcache line + = until + sync + + isync + mtmsr t2 \ Restore original MSR + sync isync + mfspr t0,hid0 \ Old HID0 value + rlwinm t0,t0,0,18,16 \ Disable cache by clearing h#4000 bit + isync + mtspr hid0,t0 + isync +c; +headers +: 603-dcache-off ( -- ) lock[ (603-dcache-off) ]unlock ; +defer dcache-off ' 603-dcache-off to dcache-off +headerless + +\ Warning: it is tempting to subtract one from the length, so that it refers +\ to the last byte in the range, and then decrement the index inside the loop. +\ However, that doesn't work because some PowerPC processors (e.g 604), when +\ in little-endian mode, do not appear to perform the following cache +\ operations properly when the effective address is unaligned. This was +\ determined empirically. + +code invalidate-603-i$-range ( adr len -- ) + mr t2,tos + lwz t0,0(sp) + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,hid0 + andi. t1,t1,h#8000 + 0<> if + add t0,t0,t2 \ Bias the base so we can increment the index + neg. t2,t2 \ Bias the index + ahead begin + icbi t0,t2 + addic. t2,t2,32 + but then 0>= until + sync + then +c; +defer invalidate-i$-range ' invalidate-603-i$-range to invalidate-i$-range + +code flush-603-d$-range ( adr len -- ) + mr t2,tos + lwz t0,0(sp) + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,hid0 + andi. t1,t1,h#4000 + 0<> if + add t0,t0,t2 \ Bias the base so we can increment the index + neg. t2,t2 \ Bias the index + ahead begin + dcbf t0,t2 + addic. t2,t2,32 + but then 0>= until + sync + then +c; +headers +defer flush-d$-range ' flush-603-d$-range to flush-d$-range +headerless + +code invalidate-603-d$-range ( adr len -- ) + mr t2,tos + lwz t0,0(sp) + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,hid0 + andi. t1,t1,h#4000 + 0<> if + add t0,t0,t2 \ Bias the base so we can increment the index + neg. t2,t2 \ Bias the index + ahead begin + dcbi t0,t2 + addic. t2,t2,32 + but then 0>= until + sync + then +c; +defer invalidate-d$-range ' invalidate-603-d$-range to invalidate-d$-range + +code store-603-d$-range ( adr len -- ) + mr t2,tos + lwz t0,0(sp) + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,hid0 + andi. t1,t1,h#4000 + 0<> if + add t0,t0,t2 \ Bias the base so we can increment the index + neg. t2,t2 \ Bias the index + ahead begin + dcbst t0,t2 + addic. t2,t2,32 + but then 0>= until + sync + then +c; +defer store-d$-range ' store-603-d$-range to store-d$-range + +: stand-sync-cache ( adr len -- adr ) + 2dup store-d$-range invalidate-i$-range +; + +defer invalidate-icache ' noop to invalidate-icache + +: invalidate-603-icache ( -- ) hid0@ dup h# 800 or hid0! hid0! ; +: invalidate-604-icache ( -- ) hid0@ h# 800 or hid0! ; + +headers +: 603-icache-on ( -- ) + \ Bail out if it's already on, to avoid causing inconsistencies + \ with L2 caches during invalidation. + hid0@ h# 8000 and if exit then + + hid0@ + sticky-cache-invalidate? if + h# 800 or dup hid0! \ Flush + h# 8000 or dup hid0! \ Turn on + h# 800 invert and hid0! \ Release flush bit + ['] invalidate-603-icache + else \ 604 + h# 8800 or hid0! \ turn on and invalidate + ['] invalidate-604-icache + then + to invalidate-icache +; +defer icache-on ' 603-icache-on to icache-on + +: 603-icache-off ( -- ) + hid0@ h# 800 or h# 8000 invert and hid0! + ['] noop to invalidate-icache +; +defer icache-off ' 603-icache-off to icache-off + +headerless +: 603-dcache-on? ( -- flag ) hid0@ h# 4000 and 0<> ; +: 603-icache-on? ( -- flag ) hid0@ h# 8000 and 0<> ; +defer dcache-on? ' 603-dcache-on? to dcache-on? +defer icache-on? ' 603-icache-on? to icache-on? + +headers +: 603-dcache-on ( -- ) + \ Bail out if it's already on, to avoid causing inconsistencies + \ with L2 caches during invalidation. + dcache-on? if exit then + + hid0@ + sticky-cache-invalidate? if + h# 400 or dup hid0! \ Invalidate + h# 4000 or dup hid0! \ Turn on + h# 400 invert and hid0! \ Release flush bit + else + h# 4400 or hid0! \ Invalidate and turn on + then +; +defer dcache-on ' 603-dcache-on to dcache-on + +\ Do this early so that the debugger will work as early as possible +: stand-init-io ( -- ) stand-init-io + ['] stand-sync-cache to sync-cache +; + +\ 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/ppc/cache823.fth =================================================================== --- cpu/ppc/cache823.fth (rev 0) +++ cpu/ppc/cache823.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,241 @@ +purpose: Cache driver for 823 PowerPC chip +\ See license at end of file + +headerless +d# 16 constant /dcache-block +d# 16 constant /icache-block + +code (823-dcache-off) ( -- ) + \ Don't do anything if the data cache is already off + mfspr t1,dc-csr + andis. t1,t1,h#8000 + 0= if + next + then + + \ Disable data translations before the flush loop: we'll run + \ in real mode to make sure there are no mapping problems. + mfmsr t2 + rlwinm t1,t2,0,28,26 \ Disable translation by clearing h#10 bit + sync isync + mtmsr t1 + sync isync + + \ Unlock Dcache + set t1,h#0a00.0000 + sync + mtspr dc-csr,t1 + + \ Flush Dcache before turning it off + set t1,h#400 \ Fill Dcache with known addresses + begin + addic. t1,t1,-16 + lwz r0,0(t1) + = until + + set t1,h#400 \ Size of dcache + begin + addic. t1,t1,-16 \ Size of cache line + dcbf r0,t1 \ Flush Dcache line + = until + sync + + isync + mtmsr t2 \ Restore original MSR + set t1,h#0400.0000 + sync + mtspr dc-csr,t1 \ Disable Dcache + isync +c; +headers +: 823-dcache-off ( -- ) lock[ (823-dcache-off) ]unlock ; +defer dcache-off ' 823-dcache-off to dcache-off +headerless + +\ Warning: it is tempting to subtract one from the length, so that it refers +\ to the last byte in the range, and then decrement the index inside the loop. +\ However, that doesn't work because some PowerPC processors (e.g 604), when +\ in little-endian mode, do not appear to perform the following cache +\ operations properly when the effective address is unaligned. This was +\ determined empirically. + +code invalidate-823-i$-range ( adr len -- ) + mr t2,tos \ len in t2 + lwz t3,0(sp) \ adr in t3 + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,ic-csr + andis. t1,t1,h#8000 + 0<> if + \ Expand the range to include all affected cache lines + add t0,t3,t2 \ End of range + addi t0,t0,15 \ Round end address up .. + rlwinm t0,t0,0,0,27 \ .. to cache line boundary + rlwinm t3,t3,0,0,27 \ Round start address down + subf. t2,t0,t3 \ Negative of length of expanded range + + ahead begin + icbi t0,t2 + addic. t2,t2,16 + but then 0>= until + sync + then +c; +defer invalidate-i$-range ' invalidate-823-i$-range to invalidate-i$-range + +code flush-823-d$-range ( adr len -- ) + mr t2,tos \ len in t2 + lwz t3,0(sp) \ adr in t3 + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,dc-csr + andis. t1,t1,h#8000 + 0<> if + \ Expand the range to include all affected cache lines + add t0,t3,t2 \ End of range + addi t0,t0,15 \ Round end address up .. + rlwinm t0,t0,0,0,27 \ .. to cache line boundary + rlwinm t3,t3,0,0,27 \ Round start address down + subf. t2,t0,t3 \ Negative of length of expanded range + + ahead begin + dcbf t0,t2 + addic. t2,t2,16 + but then 0>= until + sync + then +c; +headers +defer flush-d$-range ' flush-823-d$-range to flush-d$-range +headerless + +code invalidate-823-d$-range ( adr len -- ) + mr t2,tos \ len in t2 + lwz t3,0(sp) \ adr in t3 + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,dc-csr + andis. t1,t1,h#8000 + 0<> if + \ Expand the range to include all affected cache lines + add t0,t3,t2 \ End of range + addi t0,t0,15 \ Round end address up .. + rlwinm t0,t0,0,0,27 \ .. to cache line boundary + rlwinm t3,t3,0,0,27 \ Round start address down + subf. t2,t0,t3 \ Negative of length of expanded range + + ahead begin + dcbi t0,t2 + addic. t2,t2,16 + but then 0>= until + sync + then +c; +defer invalidate-d$-range ' invalidate-823-d$-range to invalidate-d$-range + +code store-823-d$-range ( adr len -- ) + mr t2,tos \ len in t2 + lwz t3,0(sp) \ adr in t3 + lwz tos,1cell(sp) + addi sp,sp,2cells + + \ Don't touch the cache if it's off + mfspr t1,dc-csr + andis. t1,t1,h#8000 + 0<> if + \ Expand the range to include all affected cache lines + add t0,t3,t2 \ End of range + addi t0,t0,15 \ Round end address up .. + rlwinm t0,t0,0,0,27 \ .. to cache line boundary + rlwinm t3,t3,0,0,27 \ Round start address down + subf. t2,t0,t3 \ Negative of length of expanded range + + ahead begin + dcbst t0,t2 + addic. t2,t2,16 + but then 0>= until + sync + then +c; +defer store-d$-range ' store-823-d$-range to store-d$-range + +: stand-sync-cache ( adr len -- adr ) + 2dup store-d$-range invalidate-i$-range +; + +: invalidate-823-icache ( -- ) + h# 0a00.0000 ic-csr! \ Unlock all + h# 0e00.0000 ic-csr! \ Invalidate all +; +defer invalidate-icache ' noop to invalidate-icache + +headerless +: 823-dcache-on? ( -- flag ) dc-csr@ h# 8000.0000 and ; +: 823-icache-on? ( -- flag ) ic-csr@ h# 8000.0000 and ; +defer dcache-on? ' 823-dcache-on? to dcache-on? +defer icache-on? ' 823-icache-on? to icache-on? + +headers +: 823-icache-on ( -- ) + \ Bail out if it's already on, to avoid causing inconsistencies + \ with L2 caches during invalidation. + 823-icache-on? if exit then + + invalidate-823-icache \ Unlock and invalidate Icache + h# 0200.0000 ic-csr! \ Enable Icache + ['] invalidate-823-icache to invalidate-icache +; +defer icache-on ' 823-icache-on to icache-on + +: 823-icache-off ( -- ) + h# 0400.0000 ic-csr! \ Disable Icache + ['] noop to invalidate-icache +; +defer icache-off ' 823-icache-off to icache-off + +headers +: 823-dcache-on ( -- ) + \ Bail out if it's already on, to avoid causing inconsistencies + \ with L2 caches during invalidation. + dcache-on? if exit then + + h# 0a00.0000 dc-csr! \ Unlock all + h# 0c00.0000 dc-csr! \ Invalidate all + h# 0200.0000 dc-csr! \ Enable Dcache +; +defer dcache-on ' 823-dcache-on to dcache-on + +\ Do this early so that the debugger will work as early as possible +: stand-init-io ( -- ) stand-init-io + ['] stand-sync-cache to sync-cache +; + +\ 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/ppc/call.fth =================================================================== --- cpu/ppc/call.fth (rev 0) +++ cpu/ppc/call.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,55 @@ +purpose: Call C subroutines from Forth +\ See license at end of file + +\ From Forth, call the C subroutine whose address is on the stack + +code call ( [ arg5 .. arg0 ] adr -- [ arg5 .. arg0 ] result ) + 'user saved-sp stw sp,* \ Save for callbacks + 'user saved-rp stw rp,* \ Save for callbacks + + \ Pass up to 6 arguments + lwz r3,h#00(sp) + lwz r4,h#04(sp) + lwz r5,h#08(sp) + lwz r6,h#0c(sp) + lwz r7,h#10(sp) + lwz r8,h#14(sp) + + mtspr lr,tos + bclrl 20,0 + + mr tos,r3 \ Return subroutine result + mtspr ctr,up \ Restore "next" pointer +c; + +headerless +code r1! ( adr -- ) mr r1,tos lwz tos,0(sp) addi sp,sp,1cell c; + +headers +: sp-call ( [ arg5 .. arg0 ] adr sp -- [ arg5 .. arg0 ] result ) + h# 10 - r1! call +; + +\ 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/ppc/catchexc.fth =================================================================== --- cpu/ppc/catchexc.fth (rev 0) +++ cpu/ppc/catchexc.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,433 @@ +purpose: Save the processor state after a signal. +\ See license at end of file + +\ This code is entered as a result of a Unix signal. +\ It saves the processor state, then enters Forth so that the +\ state may be examined, and possibly re-established later. + +\ needs signal signal.f + +\ exception-area is a place to store registers during exception handling. +\ Each cpu gets its own area and uses SPRG0 to point to it. +h# 40 /l* constant /exception-area +0 value exception-area + +decimal + +only forth also hidden also forth definitions + +headers +0 value virt-phys + +headerless +0 value cpu-state-phys + +: enterforth ( -- ) + state-valid on + my-self to %saved-my-self + handle-breakpoint +; + +code (restart ( -- ) + \ Restore the Forth stacks. + + \ Establish the Data and Return stacks + 'user rp0 lwz rp,* + 'user sp0 lwz sp,* + + \ Restore the Forth Data and Return stacks from the save area. + + \ Data Stack + 'user sp0 lwz t3,* + 'user pssave lwz t0,* \ Address of data stack save area + ps-size addi t1,r0,* \ Size of data stack area + add t0,t0,t1 \ End of save area + + srawi t1,t1,2 \ Number of longwords + mtspr ctr,t1 + + begin + lwzu t2,-4(t0) + stwu t2,-4(t3) + bc 16,0,* \ Decrement and branch if nonzero + + \ Return Stack + 'user rp0 lwz t3,* + 'user rssave lwz t0,* \ Address of return stack save area + rs-size addi t1,r0,* \ Size of return stack area + add t0,t0,t1 \ End of save area + + srawi t1,t1,2 \ Number of longwords + mtspr ctr,t1 + + begin + lwzu t2,-4(t0) + stwu t2,-4(t3) + bc 16,0,* \ Decrement and branch if nonzero + + or r0,r0,r0 + + \ The following code communicates with the first part of "save-state". + \ See the description there. + here 4 + bl * \ Get current address + mfspr t0,lr + addi t0,t0,16 + mfspr t2,sprg0 \ Get this cpu's exception-area address + stw t0,h#10(t2) \ Store the address of the next instruction + \ so save-state can recognize it + + \ Take another trap, so we can fix up the PC's in the signal handler + 0 asm, \ Illegal instruction + +end-code + +\ This is the second half of the state saving procedure. It is executed +\ in normal state (not exception state). + +label finish-save + \ The base register is already set + + \ Find the user area + 'body main-task set up,* \ Find the save area + lwzx up,up,base \ Get user pointer + + \ Establish the Data and Return stacks + + \ Copy the entire Forth Data and Return stacks areas to a save area. + + \ Data Stack + 'user sp0 lwz t3,* + 'user pssave lwz t0,* \ Address of data stack save area + ps-size addi t1,r0,* \ Size of data stack area + add t0,t0,t1 \ End of save area + + srawi t1,t1,2 \ Number of longwords + mtspr ctr,t1 + + begin + lwzu t2,-4(t3) + stwu t2,-4(t0) + bc 16,0,* \ Decrement and branch if nonzero + + 'user sp0 lwz sp,* + + \ Return Stack + 'user rp0 lwz t3,* + 'user rssave lwz t0,* \ Address of return stack save area + rs-size addi t1,r0,* \ Size of return stack area + add t0,t0,t1 \ End of save area + + srawi t1,t1,2 \ Number of longwords + mtspr ctr,t1 + + begin + lwzu t2,-4(t3) + stwu t2,-4(t0) + bc 16,0,* \ Decrement and branch if nonzero + + 'user rp0 lwz rp,* + + \ Adjust the stack pointer to account for the top of stack register + addi sp,sp,4 + + \ Restart the Forth interpreter. + + \ Set the next pointer + mtspr ctr,up + + \ Execute enterforth + 'body enterforth 4 - set ip,* + add ip,ip,base +c; + +\ This is the first part of the exception handling sequence. It is +\ executed in exception state. +\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area, +\ r3 points to the address where the exception occured. +label save-state + stw r3,h#0c(r2) \ Save exception address + lwz r3,h#08(r2) \ Restore lr + mtspr lr,r3 + \ R3 is available + stw base,h#14(r2) \ A register for us to play with + stw up,h#18(r2) \ A register for us to play with + + mfcr base \ CR is saved in base + + \ WARNING: This code is tricky. The goal is to determine whether or not + \ the instruction that caused the exception was the illegal instruction at + \ the end of (restart, just above. It's not safe to access the instruction + \ at the saved PC location, because this handler runs with translations + \ disabled, but the saved PC is virtual address, so accessing it could + \ result in a machine check (which would cause the system to hang) if the + \ PC value is not a valid real-mode address. + \ Instead, we compare the saved PC with the contents of the cell at + \ sprg0+10, depending on the fact that (restart stored the + \ address of its illegal instruction there just before executing that + \ illegal instruction. + + mfspr up,srr0 \ Saved PC + lwz r3,h#10(r2) \ Get magic address + cmp 0,0,up,r3 \ Is it the magic address? + + lwz r3,h#00(r2) \ Restore r3 + + = if + \ This is the second half of (restart, so we restore all the registers + \ from the save area. + + lwz up,h#18(r2) \ Get UP back + +\ 'user cpu-state-phys lwz r31,* \ Get cpu-state buffer address + lwz r31,h#38(r2) + + \ Restore floating point registers if they were saved + 36 /l* 31 lwz r0,* \ saved msr + andi. r0,r0,h#2000 + 0<> if + mfmsr t0 \ Turn on FP unit + ori t0,t0,h#2000 + mtmsr t0 + isync + + 106 /l* 31 lfd 0,* \ Get back fpscr double word into fr0 + mtfsf h#ff,0 \ Move fr0 to fpscr + + \ Assemble 32 "lfd fN,42*4+N*8(r31)" instructions + 32 0 do + i 8 * 42 la+ ( offset ) 31 ( r31 ) i ( reg# ) " lfd *,*" evaluate + loop + then + + 32 /l* 31 lwz r0,* mtspr xer,r0 \ xer + 33 /l* 31 lwz r0,* mtspr lr,r0 \ lr + 34 /l* 31 lwz r0,* mtspr ctr,r0 \ ctr + 35 /l* 31 lwz r0,* mtspr srr0,r0 \ saved pc + 36 /l* 31 lwz r0,* mtspr srr1,r0 \ saved msr + 37 /l* 31 lwz r0,* mtcrf h#ff,r0 \ cr + +\ 108 /l* 31 lwz r0,* mtspr sprg0,r0 \ sprg0 +\ 109 /l* 31 lwz r0,* mtspr sprg1,r0 \ sprg1 +\ 110 /l* 31 lwz r0,* mtspr sprg2,r0 \ sprg2 +\ 111 /l* 31 lwz r0,* mtspr sprg3,r0 \ sprg3 + + \ Assemble 32 "lwz rN,N*4(r31)" instructions + 32 0 do + i 4 * ( offset ) 31 ( r31 ) i ( reg# ) " lwz *,*" evaluate + loop +\ lmw r0,0(up) \ Restore all general registers + + rfi + then + + \ This is not the second half of (restart, so we save all the registers + \ to the save area. + mtcrf h#ff,base \ Restore CR + +\ \ Set the base register +\ here 4 + bl * \ Absolute address of next instruction +\ here origin - set base,* \ Relative address of this instruction +\ mfspr up,lr +\ subf base,base,up \ Base address of Forth kernel + +\ 'body main-task set up,* \ Find the save area +\ lwzx up,up,base \ Get user pointer +\ +\ 'user cpu-state-phys lwz up,* \ Get cpu-state buffer address + + lwz up,h#38(r2) \ Get address from save area + lwz base,h#3c(r2) \ Get address from save area + +\ stmw r0,0(up) \ Save all general registers + \ Assemble 32 "stw rN,N*4(up)" instructions + 32 0 do + i 4 * ( offset ) 27 ( up ) i ( reg# ) " stw *,*" evaluate + loop + + lwz r0,h#14(r2) 26 /l* 27 stw r0,* \ base + lwz r0,h#18(r2) 27 /l* 27 stw r0,* \ up + mfspr r0,xer 32 /l* 27 stw r0,* \ xer + lwz r0,h#08(r2) 33 /l* 27 stw r0,* \ lr + mfspr r0,ctr 34 /l* 27 stw r0,* \ ctr + mfspr r0,srr0 35 /l* 27 stw r0,* \ saved pc + mfspr r0,srr1 36 /l* 27 stw r0,* \ saved msr + mfcr r0 37 /l* 27 stw r0,* \ cr + + lwz r0,h#0c(r2) rlwinm r0,r0,24,24,31 + 38 /l* 27 stw r0,* \ exception# + lwz r2,h#04(r2) 2 /l* 27 stw r2,* \ original r2 + +\ mfspr r0,sprg0 108 /l* 27 stw r0,* \ sprg0 +\ mfspr r0,sprg1 109 /l* 27 stw r0,* \ sprg1 +\ mfspr r0,sprg2 110 /l* 27 stw r0,* \ sprg2 +\ mfspr r0,sprg3 111 /l* 27 stw r0,* \ sprg3 + + \ Save floating point registers if floating point is enabled + mfmsr t0 + andi. t0,t0,h#2000 + 0<> if + \ Assemble 32 "stfd fN,42*4+N*8(up)" instructions + 32 0 do + i 8 * 42 la+ ( offset ) 27 ( up ) i ( reg# ) " stfd *,*" evaluate + loop + \ Now that fp regs are saved, we can trounce on them to get the + \ fpscr register + mffs 0 \ Move fpscr to fp0[63:32] + 106 /l* 27 stfd 0,* \ Move fp0[63:0] to memory + then + + \ Now we set the saved PC to point to the rest of the state save + \ routine, then return from interrupt. + + 'body finish-save set up,* + add up,up,base + mtspr srr0,up + + rfi +end-code + +hidden definitions + +' (restart is restart +' (restart is restart-step + +string-array exception-name +( 00 ) ," Reserved exception 0" +( 01 ) ," System reset" +( 02 ) ," Machine check" +( 03 ) ," Data access exception" +( 04 ) ," Instruction access exception" +( 05 ) ," External interrupt" +( 06 ) ," Alignment exception" +( 07 ) ," Illegal instruction" +( 08 ) ," Floating point unavailable" +( 09 ) ," Decrementer interrupt" +( 0a ) ," I/O controller interface error" +( 0b ) ," Reserved exception 0b" +( 0c ) ," System call" +( 0d ) ," Trace exception" +( 0e ) ," Floating point assist exception" +( 0f ) ," Reserved exception 0f" +( 10 ) ," Instruction translation miss" +( 11 ) ," Data load translation miss" +( 12 ) ," Data store translation miss" +( 13 ) ," Instruction address breakpoint" +( 14 ) ," System management interrupt" +end-string-array + +: (.exception) ( -- ) + exception# dup h# 20 = if + ." Run mode/trace exception" + else + dup h# 15 < if + exception-name count type + else + ." Reserved exception # " .h + then + then + cr +; +' (.exception) is .exception + +: print-breakpoint + .exception \ norm + interactive? 0= if bye then \ Restart only if a human is at the controls + ??cr quit +; +\ ' print-breakpoint is handle-breakpoint + +code hwbp ( adr -- ) + mtspr iabr,tos + lwz tos,0(sp) + addi sp,sp,4 +c; + +code tbar! ( adr -- okay? ) + \ As a side effect of the mfspr *,pvr instruction, the simulator + \ sets its internal trap base address register (which isn't a real + \ part of the PowerPC architecture) to the address contained in the + \ destination register. That instruction was chosen because it + \ is not likely to be used in general code, but it is valid on all + \ PPC implementations. + mfspr tos,pvr +c; + +forth definitions +0 value exc-adr +: exc, ( instruction -- ) exc-adr instruction! exc-adr la1+ to exc-adr ; +: put-exception ( exception-handler-addr exception-addr -- ) + to exc-adr virt-phys - lwsplit + h# 7c51.43a6 exc, \ mtspr sprg1,r2 protect r2 + h# 7c50.42a6 exc, \ mfspr r2,sprg0 set r2 to save area + h# 9062.0000 exc, \ stw r3,0(r2) save r3 + h# 7c71.42a6 exc, \ mfspr r3,sprg1 + h# 9062.0004 exc, \ stw r3,4(r2) save r2 + h# 7c68.02a6 exc, \ mfspr r3,lr + h# 9062.0008 exc, \ stw r3,8(r2) save lr + \ h# 80620020 exc, h# 38630001 exc, h# 90620020 exc, + h# 3c60.0000 or exc, \ set r3,high address half-word + h# 6063.0000 or exc, \ set r3,low address half-word + h# 7c68.03a6 exc, \ mtspr lr,r3 point lr to handler + h# 3860.0000 exc-adr h# ff00 and or exc, \ addi r3,r0,exception-addr + h# 4e80.0020 exc, \ bclr 20,0 jump to handler +; +d# 12 /l* constant /exc \ size of entry made by put-exception +: catch-exception ( exception# -- ) 8 << save-state swap put-exception ; + +headers +: catch-exceptions ( -- ) + /save-area alloc-mem is cpu-state ( ) + clear-save-area ( ) + pssave drop rssave drop \ Force allocation of these buffers + /exception-area alloc-mem ( virt ) + cpu-state virt-phys - over h# 38 + l! ( virt ) + origin over h# 3c + l! ( virt ) + virt-phys - dup is exception-area ( virt' ) + sprg0! \ Save this cpu's exception-area address to SPRG0 + + + 2 catch-exception \ Machine check + 3 catch-exception \ Data access + 4 catch-exception \ Instruction access + 6 catch-exception \ Alignment + 7 catch-exception \ Illegal instruction + 8 catch-exception \ Floating point unavailable +; +: stand-init ( -- ) + msr@ h# 40 invert and msr! + catch-exceptions +; +: sys-init ( -- ) + sys-init + syscall-vec @ 0= if + h# 4000 alloc-mem tbar! if + catch-exceptions + then + then +; + +only forth also definitions + +\ 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/ppc/centry.fth =================================================================== --- cpu/ppc/centry.fth (rev 0) +++ cpu/ppc/centry.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,124 @@ +purpose: Client interface handler code +\ See license at end of file + +d# 108 buffer: cif-reg-save + +headerless +code cif-return !csp + mr r3,tos + + 'user cif-reg-save lwz r7,* \ Address of register save area in r7 + + lwz r13,00(r7) lwz r14,04(r7) lwz r15,08(r7) lwz r16,12(r7) + lwz r17,16(r7) lwz r18,20(r7) lwz r19,24(r7) lwz r20,28(r7) + lwz r21,32(r7) lwz r22,36(r7) lwz r23,40(r7) lwz r24,44(r7) + lwz r25,48(r7) lwz r26,52(r7) lwz r27,56(r7) lwz r28,60(r7) + lwz r29,64(r7) lwz r30,68(r7) lwz r31,72(r7) lwz r1,76(r7) + lwz r2,80(r7) lwz r4,88(r7) mtspr hid0,r4 + lwz r4,92(r7) mtspr sprg0,r4 lwz r4,96(r7) mtspr sprg1,r4 + lwz r4,100(r7) mtspr sprg2,r4 lwz r4,104(r7) mtspr sprg3,r4 + lwz r4,84(r7) + + mtspr lr,r4 + bclr 20,0 +end-code + +defer rm-cif-entry ' noop to rm-cif-entry +defer rm-cif-exit ' noop to rm-cif-exit + +: cif-exec ( args ... -- ) + rm-cif-entry do-cif rm-cif-exit cif-return +; + +headers +: cif-caller ( -- adr ) cif-reg-save d# 84 + @ ; + +headerless +label cif-handler + \ Registers: + \ r3 argument array pointer + \ r1,r2,r13-r31 must be preserved + \ r0,r4-r12 scratch + + mfspr r4,lr \ Save link register for later + mr r5,base \ Save base register (r26) + mr r6,up \ Save user area pointer register (r27) + + \ Set the base register + here 4 + bl * \ Absolute address of next instruction + here origin - set base,* \ Relative address of this instruction + mfspr up,lr + subf base,base,up \ Base address of Forth kernel in base + + \ Find the user area + 'body main-task set up,* \ Find the save area + lwzx up,up,base \ Get user pointer + + 'user cif-reg-save lwz r7,* \ Address of register save area in r7 + + stw r13,00(r7) stw r14,04(r7) stw r15,08(r7) stw r16,12(r7) + stw r17,16(r7) stw r18,20(r7) stw r19,24(r7) stw r20,28(r7) + stw r21,32(r7) stw r22,36(r7) stw r23,40(r7) stw r24,44(r7) + stw r25,48(r7) stw r5,52(r7) stw r6,56(r7) stw r28,60(r7) + stw r29,64(r7) stw r30,68(r7) stw r31,72(r7) stw r1,76(r7) + stw r2,80(r7) stw r4,84(r7) mfspr r4,hid0 stw r4,88(r7) + mfspr r4,sprg0 stw r4,92(r7) mfspr r4,sprg1 stw r4,96(r7) + mfspr r4,sprg2 stw r4,100(r7) mfspr r4,sprg3 stw r4,104(r7) + + mr tos,r3 + + 'user rp0 lwz rp,* + 'user sp0 lwz sp,* + \ We don't add 4 to account for the top of stack register because + \ there is one item - the argument array address - on the stack + \ (actually it is in the TOS register; logically it's on the stack) + + 'user exception-area lwz r2,* mtspr sprg0,r2 + + mtspr ctr,up \ Set "next" pointer + 'body cif-exec 4 - set ip,* + add ip,ip,base +c; + +0 value callback-stack + +headers +code callback-call ( args vector -- ) + mtspr lr,tos + lwz r3,0(sp) + 'user callback-stack lwz r1,* + lwz tos,1cell(sp) + addi sp,sp,2cells + bclrl 20,0 + mtspr ctr,up +c; + +\ Force allocation of buffer +stand-init: CIF buffers + cif-reg-save drop + h# 1000 dup alloc-mem + to callback-stack +; + +\ 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/ppc/code.fth =================================================================== --- cpu/ppc/code.fth (rev 0) +++ cpu/ppc/code.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,104 @@ +purpose: Assembler extensions to create Forth words +\ See license at end of file + +\ These words are specific to the virtual machine implementation +: assembler ( -- ) ppc-assembler ; + +only forth also assembler also definitions + +\ Forth Virtual Machine registers + +also register-names definitions +decimal +: t0 20 ; : t1 21 ; : t2 22 ; : t3 23 ; : t4 24 ; : t5 25 ; +: t6 19 ; : t7 18 ; : t8 17 ; : t9 16 ; +: base 26 ; : up 27 ; : tos 28 ; : ip 29 ; : rp 30 ; : sp 31 ; +: w t5 ; +previous definitions + +also constant-names definitions + +/n constant 1cell \ Offsets into the stack +1cell -1 * constant -1cell +1cell 2 * constant 2cells +1cell 3 * constant 3cells +1cell 4 * constant 4cells + +1cell constant /cf \ Size of a code field (except for "create") +/cf -1 * constant -/cf + +1cell constant /token \ Size of a compiled word reference +/token -1 * constant -/token + +1cell constant /branch \ Size of a branch offset + +/token 2 * constant /ccf \ Size of a "create" code field + +/cf 1cell + constant /cf+1cell \ Location of second half of +previous definitions + +\ The next few words are already in the forth vocabulary; +\ we want them in the assembler vocabulary too +alias next next +headerless +: exitcode ( -- ) + ['] $interpret-do-undefined is $do-undefined + previous +; +' exitcode is do-exitcode +headers +alias c; c; + +: 'user# \ name ( -- user# ) + ' ( acf-of-user-variable ) >body @ +; +: 'user \ name ( -- user-addressing-mode ) + [ also ppc-assembler also register-names ] + 'user# up + [ previous previous ] +; +: 'body \ name ( -- variable-apf-offset ) + ' ( acf-of-user-variable ) >body origin - +; +: 'acf \ name ( -- variable-acf-offset ) + ' ( acf-of-user-variable ) origin - +; + +also forth definitions +: entercode ( -- ) + also assembler + false is disassembling? + ['] $ppc-assem-do-undefined is $do-undefined +; +' entercode is do-entercode + +\ "code" is defined in the kernel + +: label \ name ( -- ) + create !csp entercode +; +only forth also definitions + +\ 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/ppc/cpubpsup.fth =================================================================== --- cpu/ppc/cpubpsup.fth (rev 0) +++ cpu/ppc/cpubpsup.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,91 @@ +purpose: Machine-dependent definitions for breakpoints +\ See license at end of file + +headerless +0 value breakpoint-opcode +defer breakpoint-trap? +' true is breakpoint-trap? \ XXX until arcbpsup is installed... + +: op@ ( adr -- op ) l@ ; +: op! ( op adr -- ) instruction! ; +: bp-address-valid? ( adr -- flag ) 3 and 0= ; +: at-breakpoint? ( adr -- flag ) op@ breakpoint-opcode = ; +: put-breakpoint ( adr -- ) breakpoint-opcode swap op! ; + +headers +: .instruction ( -- ) + %pc [ also assembler ] pc ! dis1 [ previous ] +; + +headerless +\ Find the places to set the next breakpoint for single stepping. + +\ Flag is true if the branch should be followed - we don't follow branches +\ if stepping? is false and the instruction modifies the link register. +: -hop? ( stepping? pc -- stepping? pc flag ) 2dup 1 and 0= or ; +: next-instruction ( stepping? -- next-adr branch-target|0 ) + %pc la1+ swap ( next-adr stepping? ) + + \ If we are hopping (not stepping), then we don't follow subroutine + \ calls (branches that have the link bit set). We needn't bother + \ checking whether or not the instruction is a branch, because if + \ it isn't, we want to do the same thing as for a branch with link. + 0= %pc l@ 1 and and if 0 exit then ( next-adr ) + + %pc ( next-adr pc ) + bclr? if drop %lr exit then ( next-adr pc ) + bcctr? if drop %ctr exit then ( next-adr pc ) + bc? if >bc-target exit then ( next-adr pc ) + b? if >b-target exit then ( next-adr pc ) + drop 0 +; + +: bumppc ( -- ) %pc la1+ to %pc ; + +alias rpc %pc + +code goto ( adr -- ) + mtspr lr,tos + lwz tos,0(sp) + addi sp,sp,4 + bclr 20,0 +end-code + +: return-adr ( -- adr ) %r1 @ 8 + @ ; +: leaf-return-adr ( -- adr ) %lr ; + +: backward-branch? ( adr -- flag ) \ True if adr points to a backward branch + b? if dup >b-target u> exit then ( adr ) + bc? if dup >bc-target u> exit then ( adr ) + drop false +; +: loop-exit-adr ( -- adr ) + %pc begin dup backward-branch? 0= while la1+ repeat la1+ +; + +headers +: set-pc ( adr -- ) to %pc ; + +\ 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/ppc/cpuclass.fth =================================================================== --- cpu/ppc/cpuclass.fth (rev 0) +++ cpu/ppc/cpuclass.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,97 @@ +purpose: Classify PowerPC CPUs into various general families +\ See license at end of file + +headerless +\ At present, PowerPC CPUs can be grouped into several classes. +\ There are several characteristics that are the same across all +\ members of a class. New classes and new class members appear +\ from time to time. The 601 is handled elsewhere. + +: 603-class? ( -- flag ) + \ CPU-version 81 is for the 8240 + cpu-version dup 3 = over 6 = or over 7 = or over 8 = or swap h# 81 = or +; +: 604-class? ( -- flag ) + cpu-version dup 4 = over 9 = or swap h# a = or +; +: 620-class? ( -- flag ) + cpu-version d# 20 = +; +: 704-class? ( -- flag ) \ remove 54 to drop proto support. + cpu-version dup h# 54 = swap h# 60 = or +; + +: mach-5/pass1? ( -- flag ) + pvr@ lwsplit h# a = swap h# 100 = and +; +: 823-class? ( -- flag ) + cpu-version h# 50 = +; + +\ According to IBM, MACH-5 (PVR = A) revision 100 has a bug that requires +\ the BTAC bit be set to 1 in order to disable cacheing of branch addresses. +\ We set the BTAC disable bit in resetvec, here we turn it off if we are +\ running on anything other than a mach-5, version 100. +\ The BTAC bit is bit 30 of HID0. (Well actually, its the 0x00000002 bit +\ the way we look at it) + +: fastest-mode ( -- ) + 604-class? if + \ Turn on 604 superscalar and dynamic branch prediction modes + \ machine checks, and cache parity checking + \ Turn off cache locks and bus parity checking + hid0@ h# 84 or ( hid0' ) + mach-5/pass1? 0= if ( hid0' ) + h# 02 invert and ( hid0'' ) + then ( hid0 ) + h# f008.3000 invert and hid0! ( ) + then +[ifdef] exponential + \ 704-class? if + cpu-version h# 60 = if \ non-proto x704 + \ Turn on 704 superscalar and set POE + modes@ h# 3.0000 or modes! + then +[then] +; + +\ Some characteristics of various classes + +: software-tlb-miss? ( -- flag ) 603-class? 823-class? or ; +: sticky-cache-invalidate? ( -- flag ) 603-class? ; + +d# 64 value #tlb-lines +: configure-tlb ( -- ) + cpu-version case + 3 of d# 32 endof + 6 of d# 32 endof + h# 50 of d# 8 endof + ( default ) #tlb-lines swap + endcase + to #tlb-lines +; +headers + +\ 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/ppc/cpunode.fth =================================================================== --- cpu/ppc/cpunode.fth (rev 0) +++ cpu/ppc/cpunode.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,223 @@ +purpose: CPU node +\ See license at end of file + +0 value l2-cache-node +defer probe-l2-cache +' false to probe-l2-cache ( -- false | #sets #bytes write-back? true ) + +\ A hook that can be used on a per-platform basis to amend any +\ information that needs to be changed. +defer get-cpu-info ( -- ) +' noop to get-cpu-info + +headerless +\ Interfaces to platform-dependent code to determine the status of +\ CPUs in an MP system. +1 value max#cpus + +\ keep track of cpu#; may be used by get-cpu-info and probe-l2-cache +0 value cpu + +defer firmware-cpu# ( -- cpu# ) +' 0 to firmware-cpu# + +defer cpu-started? ( cpu# -- flag ) +' 0= to cpu-started? + +headers +d# 100,000,000 value cpu-clock-frequency + +' cpu-node " cpu" chosen-variable + +headerless +0 value cpu-package + +headers +: make-l2-cache-node ( #sets size write-back? -- ) + new-device + " l2-cache" device-name + " cache" device-type + 0 0 encode-bytes " cache-unified" property \ Assumes a unified cache + + drop ( #sets size ) + 2dup " i-cache-size" integer-property " i-cache-sets" integer-property + " d-cache-size" integer-property " d-cache-sets" integer-property + + d# 32 " d-cache-block-size" integer-property + d# 32 " i-cache-block-size" integer-property + + current-device ( phandle ) + finish-device + dup to l2-cache-node + " l2-cache" integer-property +; +headerless + +: make-cache-props ( ts tsz d$s d$b d$sz i$s i$b i$sz -- ) + " i-cache-size" integer-property + dup to /icache-block + " i-cache-block-size" integer-property + " i-cache-sets" integer-property + " d-cache-size" integer-property + dup to /dcache-block + " d-cache-block-size" integer-property + " d-cache-sets" integer-property + " tlb-size" integer-property + " tlb-sets" integer-property +; +: start-cpu-node ( ts tsz d$s d$b d$sz i$s i$b i$sz adr len -- ) + new-device + ( tlb-params cache-params adr len ) device-name + " cpu" device-type +; +: make-603-node ( -- ) + " PowerPC,603" start-cpu-node + d# 64 d# 128 d# 128 d# 32 d# 8192 3dup make-cache-props +; +: make-604-node ( -- ) + " PowerPC,604" start-cpu-node + d# 128 d# 256 d# 128 d# 32 d# 16384 3dup make-cache-props +; +: make-603e-node ( -- ) + " PowerPC,603e" start-cpu-node + d# 64 d# 128 d# 128 d# 32 d# 16384 3dup make-cache-props +; +: make-603ev-node ( -- ) + " PowerPC,603ev" start-cpu-node + d# 64 d# 128 d# 128 d# 32 d# 16384 3dup make-cache-props +; +: make-603eva-node ( -- ) + " PowerPC,603evARTHUR" start-cpu-node + d# 128 d# 256 d# 128 d# 32 d# 32768 3dup make-cache-props +; +: make-604ev-node ( -- ) + " PowerPC,604ev" start-cpu-node + d# 128 d# 256 d# 256 d# 32 d# 32768 3dup make-cache-props +; +: make-604ev5-node ( -- ) + " PowerPC,604ev5" start-cpu-node + d# 128 d# 256 d# 256 d# 32 d# 32768 3dup make-cache-props +; +: make-620-node ( -- ) + " PowerPC,620" start-cpu-node + d# 128 d# 128 d# 64 d# 64 d# 32768 3dup make-cache-props +; +: make-704-node ( -- ) + " PowerPC,X704" start-cpu-node + d# 32 d# 128 d# 64 d# 32 d# 2048 3dup make-cache-props +; +: make-8240-node ( -- ) + " PowerPC,603ev" start-cpu-node + d# 64 d# 128 d# 128 d# 32 d# 16384 3dup make-cache-props +; +: make-823-node ( -- ) + " PowerPC,MPC823" start-cpu-node + d# 32 d# 256 d# 32 d# 16 d# 1024 d# 64 d# 16 d# 2048 make-cache-props +; + +headers +0 0 " " " /" begin-package +" cpus" device-name +1 " #address-cells" integer-property +0 " #size-cells" integer-property + +: decode-unit ( adr len -- phys ) $number if 0 then ; +: encode-unit ( phys -- adr len ) (u.) ; + +: open ( -- true ) true ; +: close ( -- ) ; +end-package + +headerless + +defer make-cpu-extras ' noop to make-cpu-extras + +: make-cpu-node ( cpu# -- ) + to cpu + " /cpus" find-device + + cpu-version case + 3 of make-603-node endof + 4 of make-604-node endof + 6 of make-603e-node endof + 7 of make-603ev-node endof + 8 of make-603eva-node endof + 9 of make-604ev-node endof + h# a of make-604ev5-node endof + d# 20 of make-620-node endof + h# 50 of make-823-node endof + h# 54 of make-704-node endof \ proto... remove! + h# 60 of make-704-node endof + h# 81 of make-8240-node endof + ( default ) ." make-cpu-node: Unknown CPU Version " dup . cr + endcase + + get-cpu-info + + \ ??? cpu-version " arc-key" integer-property + + counts/ms d# 1000 * " timebase-frequency" integer-property + + cpu firmware-cpu# = if current-device to cpu-package then + + cpu " reg" integer-property + + " clock-frequency" " /" find-package drop get-package-property 0= if + " bus-frequency" property + then + + cpu-clock-frequency " clock-frequency" integer-property + " : open true ; : close ;" evaluate + + \ check for in-line (or unshared) cache + probe-l2-cache if + make-l2-cache-node + else + l2-cache-node ?dup if " l2-cache" integer-property then + then + + make-cpu-extras + + finish-device + device-end +; + +: make-cpu-nodes ( -- ) + \ check for look-aside cache + " /cpus" find-device -1 to cpu + probe-l2-cache if make-l2-cache-node then + device-end + max#cpus 0 do + i cpu-started? if i make-cpu-node then + loop +; +headers + +stand-init: CPU nodes + make-cpu-nodes + cpu-package open-phandle cpu-node ! +; + +\ 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/ppc/cpustate.fth =================================================================== --- cpu/ppc/cpustate.fth (rev 0) +++ cpu/ppc/cpustate.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,40 @@ +purpose: Buffers for saving program state +\ See license at end of file + +headers +\ A place to save the CPU registers when we take a trap +0 value cpu-state \ Pointer to CPU state save area + +headerless +: >state ( offset -- adr ) cpu-state + ; + +ps-size buffer: pssave \ Forth data stack save area +rs-size buffer: rssave \ Forth return stack save area + +headers +defer .exception \ Display the exception type +defer handle-breakpoint \ What to do after saving the state + +\ 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/ppc/ctrace.fth =================================================================== --- cpu/ppc/ctrace.fth (rev 0) +++ cpu/ppc/ctrace.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,81 @@ +purpose: After a crash, displays a backtrace of C stack frames. +\ See license at end of file + +only forth also hidden also forth definitions +needs (rstrace rstrace.fth +needs >saved savedstk.fth +only forth also hidden also forth definitions + +headerless +: imatch? ( adr match mask -- adr flag ) 2 pick l@ and = ; + +: b? ( adr -- adr flag ) h# 4800.0000 h# fc00.0000 imatch? ; +: bc? ( adr -- adr flag ) h# 4000.0000 h# fc00.0000 imatch? ; +: bclr? ( adr -- adr flag ) h# 4c00.0020 h# fc00.07fe imatch? ; +: bcctr? ( adr -- adr flag ) h# 4c00.0420 h# fc00.07fe imatch? ; + +: >b-target ( adr -- target-adr ) + dup l@ dup d# 6 << d# 6 >>a 3 invert and ( adr instr bd ) + swap 2 and if nip else + then +; +: >bc-target ( adr -- target-adr ) + dup l@ dup d# 16 << d# 16 >>a 3 invert and ( adr instr bd ) + swap 2 and if nip else + then +; +: .subroutine ( call-adr -- ) \ Show subroutine address + b? if >b-target 9 u.r exit then + bc? if >bc-target 9 u.r exit then + bclr? if drop %lr 9 u.r exit then \ only works in leaf context + bcctr? if drop %ctr 9 u.r exit then \ only works in leaf context + drop ." ??????" +; +: .args ( -- ) \ Show C subroutine arguments + ." (" %r3 9 u.r %r4 9 u.r %r5 9 u.r %r6 9 u.r ." ... )" +; +: .leaf ( return-adr -- ) + 4 - + base @ >r hex + dup .subroutine .args ." called from " 9 u.r cr + r> base ! +; +: .subr ( return-adr -- ) + 4 - + base @ >r hex + dup .subroutine ." ( ???? )" ." called from " 9 u.r cr + r> base ! +; +headers +: ctrace ( -- ) \ C stack backtrace + ?saved-state + ." Last Leaf:" cr %lr .leaf + %r1 if + ." On stack:" cr + %r1 ( leaf-frame-adr ) + begin @ dup while ( frame-adr ) dup 8 + @ .subr repeat + drop + then +; + +\ 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/ppc/debugm.fth =================================================================== --- cpu/ppc/debugm.fth (rev 0) +++ cpu/ppc/debugm.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,110 @@ +purpose: CPU-dependent definitions for the source-level debugger +\ See license at end of file + +headerless +\ \needs at : at ( row column -- ) 2drop ; +\needs kill-line : kill-line ( -- ) ; + +hex + +: low-dictionary-adr ( -- adr ) origin init-user-area + ; + +nuser debug-next \ Pointer to "next" +vocabulary bug bug also definitions +nuser 'debug \ code field for high level trace +nuser <ip \ lower limit of ip +nuser ip> \ upper limit of ip +nuser cnt \ how many times thru debug next + +\ Since we use a shared "next" routine, slow-next and fast-next are no-op's +alias slow-next 2drop ( high low -- ) +alias fast-next 2drop ( high low -- ) + +: copy-next ( -- ) + \ Copy the normal next routine from the user area + here 5 /n* dup allot ( adr size ) + up@ -rot cmove +; + +label normal-next + copy-next +end-code + +label debnext + 'user <ip lwz t0,* + addi t2,ip,4 + cmpl 0,0,t2,t0 + >= if + 'user ip> lwz t0,* + cmpl 0,0,t2,t0 + < if + 'user cnt lwz t0,* + set t1,2 + addi t0,t0,1 + 'user cnt stw t0,* + cmp 0,0,t0,t1 + = if + set t0,0 + 'user cnt stw t0,* + + set t0,h#873d0004 \ lwzu w,4(ip) + stw t0,0(up) + + dcbf r0,up \ flush cache + icbi r0,up \ flush cache + isync + + \ Machine code for 'debug token@ execute + 'user 'debug lwz w,* + + \ Tail of "NEXT" + lwzux t1,w,base \ Read the contents of the code field + add t1,t1,base \ Relocate + mtspr lr,t1 + bclr 20,0 \ Execute the code + then + then + then + copy-next +end-code + +\ Fix the next routine to use the debug version +\ XXX This assumes that the user area and the dictionary are within +\ 16 MBytes of one another. +: pnext ( -- ) + debnext up@ - h# 3ffffff and h# 48000000 or up@ instruction! +; + +\ Turn off debugging +\ h# 873d0004 is "lwzu w,4(ip)", the first instruction of "next" +: unbug ( -- ) h# 873d0004 up@ instruction! ; + +forth definitions +syscall-vec @ 0= if +unbug +then +headers + +\ 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/ppc/decompm.fth =================================================================== --- cpu/ppc/decompm.fth (rev 0) +++ cpu/ppc/decompm.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,48 @@ +purpose: Machine/implementation-dependent decompiler support +\ See license at end of file + +headerless + +only forth also hidden also definitions +: dictionary-base ( -- adr ) origin ; + +\ True if adr is a reasonable value for the interpreter pointer +: reasonable-ip? ( adr -- flag ) + dup in-dictionary? if ( ip ) + #talign 1- and 0= \ must be token-aligned + else + drop false + then +; + +\ Decompiler extension for 32-bit literals +: .llit ( ip -- ip' ) ta1+ dup l@ n. la1+ ; +: skip-llit ( ip -- ip' ) ta1+ la1+ ; +' (llit) ' .llit ' skip-llit install-decomp + +only forth also definitions +headers + +\ 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/ppc/dectrap.fth =================================================================== --- cpu/ppc/dectrap.fth (rev 0) +++ cpu/ppc/dectrap.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,36 @@ +purpose: Ignore decrementer interrupt +\ See license at end of file + +headerless +label dec-handler +rfi +end-code + +headers +stand-init: Decrementer + dec-handler l@ h# 900 instruction! +; + +\ 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/ppc/disinflt.fth =================================================================== --- cpu/ppc/disinflt.fth (rev 0) +++ cpu/ppc/disinflt.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,85 @@ +purpose: Disassemble inflate.bix so it can be re-assembled from Forth +\ See license at end of file + +\ Example use: +\ ppcforth tools.dic ${BP}/cpu/powerpc/disinflt.fth >inflate.dis +\ +\ The output may require some amount of manual editing... +\ To make inflate.bix: xcftobin <inflate.out >inflate.bix + +hex + +4000 buffer: buf +0 value /buf +reading inflate.bix +buf 4000 ifd @ fgets to /buf +ifd @ fclose + +: show-relative ( target -- ) + [ also assembler ] pc [ previous ] @ - + push-hex + ?dup if dup 0< if ." .-" negate else ." .+" then ." h#" ul. then + pop-base +; +: +u. ( adr -- adr' ) dup be-l@ 9 u.r la1+ ; +: dis0 ( 32b -- ) + ?dup if disasm else + [ also assembler ] pc [ previous ] @ + + dup h# 14 + buf /buf + u> if + buf /buf + over do + ." h# " i be-l@ u. ." be-l, " + /l +loop cr + bye + then + + \ Typically produces: + \ Debug: 2041 800b0300 0 49c inflate + \ ^ ^^^ ^^^^^^^ + \ 0 for leaf code name + \ routines length + + cr ." Debug: " la1+ +u. +u. +u. +u. + dup wa1+ swap be-w@ 2dup ." " type cr + + aligned 4 - + [ also assembler ] pc [ previous ] ! + then +; +: keep-going ( adr -- false ) drop false ; +also assembler +true to numeric-conditionals? +patch dis0 disasm dis1 +patch keep-going @ +dis +patch keep-going @ +dis +patch @ keep-going +dis +' show-relative is showaddr +previous + +no-page + +\ buf 20 + dis +buf dis + +\ 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/ppc/epic.fth =================================================================== --- cpu/ppc/epic.fth (rev 0) +++ cpu/ppc/epic.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,73 @@ +purpose: Driver for Motorola Embedded Programmable Interrupt Controller +\ See license at end of file + +h# fdf0.0000 constant eu-pa +0 value eu-va +: map-eu ( -- ) + eu-pa h# 78 config-l! + eu-pa h# 10.0000 root-map-in to eu-va +; +: +eu ( offset -- adr ) eu-va + ; +: eu! ( l offset -- ) +eu rl! ; +: eu@ ( offset -- l ) +eu rl@ ; + +: priority! ( pri -- ) h# 60080 eu! ; +: vector@ ( -- vector ) h# 600a0 eu@ ; +: eoi ( -- ) 0 h# 600b0 eu! ; +: gcr! ( l -- ) h# 41020 eu! ; +: gcr@ ( -- l ) h# 41020 eu@ ; + +: pi! ( l -- ) h# 41090 eu! ; +: pi@ ( -- l ) h# 41090 eu@ ; + +: spurious! ( n -- ) h# 410e0 eu! ; +: eicr! ( l -- ) h# 41030 eu! ; +: eicr@ ( -- l ) h# 41030 eu@ ; + +: >irq ( channel -- adr ) h# 20 * h# 50200 + ; +: vec/pri! ( l channel -- ) >irq eu! ; +: vec/pri@ ( channel -- l ) >irq eu@ ; +: dest! ( l channel -- ) >irq h# 10 + eu! ; +: dest@ ( channel -- l ) >irq h# 10 + eu@ ; + +\ Other channels: I2C - 0x71, DMA0 - 0x72, DMA1 - 0x73, Message unit - 0x76 + +: reset-epic ( -- ) + gcr@ h# a000.0000 or gcr! + h# 2000.0000 gcr! + \ XXX should configure it for the correct mode - direct, pass-thru, etc. + + \ Eat any pending interrupts + h# 20 0 do + vector@ h# ff = if unloop exit then + eoi + loop + ." The EPIC won't stop interrupting" cr +; +stand-init: Initializing EPIC + map-eu + reset-epic +; +\ 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/ppc/fb8-ops.fth =================================================================== --- cpu/ppc/fb8-ops.fth (rev 0) +++ cpu/ppc/fb8-ops.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,205 @@ +purpose: Optimized fb8 package support routines +\ See license at end of file + +headerless +decimal + +\ Invert foreground and background colors within a rectangular region +code fb8-invert ( adr width height bytes/line fg-color bg-color -- ) + \ bg-color in tos + lwz t4,0(sp) \ fg-color in t4 + lwzu t0,1cell(sp) \ bytes/line in scr + lwzu t2,1cell(sp) \ height in t1 (outer loop index, >0) + lwzu t1,1cell(sp) \ width in t2 (inner loop index, >0) + lwzu t3,1cell(sp) \ adr in sc3 (starting address) + + mfspr t6,ctr \ Save counter + + subf t0,t1,t0 \ Account for inner loop incrementing + addi t3,t3,-1 \ Account for inner loop incrementing + + begin \ Outer loop + mtspr ctr,t1 \ Starting width value + begin \ Inner loop + lbzu t5,1(t3) \ read byte + cmp 0,0,t5,tos \ Background? + = if + mr t5,t4 \ Set to foreground + else + cmp 0,0,t5,t4 \ Foreground? + = if + mr t5,tos \ Set to background + then + then + stb t5,0(t3) \ store byte + countdown \ End inner loop when width=0 + + addic. t2,t2,-1 \ decrement height until =0 + add t3,t3,t0 \ increment adr to next line + = until \ End outer loop when height=0 + + mtspr ctr,t6 \ Restore counter + lwzu tos,1cell(sp) \ Clean up stack + addi sp,sp,1cell +c; + +\ Draws a character from a 1-bit-deep font into an 8-bit-deep frame buffer +\ Assumptions: Fontbytes is 2; 0 < width <= 16 +\ Fontadr is divisible by 2 +code fb8-paint +( fontadr fontbytes width height screenadr bytes/line fg-color bg-color -- ) + \ tos already there \ bg-color in tos + lwz t9,0(sp) \ fg-color in t9 + lwzu t2,1cell(sp) \ Bytes/line - bytes per scan line + lwzu t3,1cell(sp) \ Screenadr - start address in frame buffer + lwzu t4,1cell(sp) \ Height - character height in pixels + lwzu t5,1cell(sp) \ Width - character width in pixels (bytes) + lwzu t6,1cell(sp) \ Fontbytes - bytes per font line + lwzu t7,1cell(sp) \ Fontadr - start adr of this char in font table + + addi t3,t3,-1 \ Account for pre-incrementing + subf t2,t5,t2 \ Account for inner loop incrementing + mfspr t8,ctr \ Save counter + + addi r0,r0,8 \ Constant 8 (pixels/font-byte), needed below + + + begin \ Outer loop - for all scan lines in char + lbz t0,0(t7) \ Up to 8 font bits into scr + rlwinm t0,t0,23,1,8 \ Align almost to high part of word so that + \ one more shift will affect the sign bit + + mr t1,t5 \ Reset width counter for the new scan line + + ahead \ Branch down to end of loop + begin + + cmpi 0,0,t1,8 + < if + mtspr ctr,t1 \ Set count + subf t1,t1,t1 \ Width is exhausted + else + mtspr ctr,r0 \ Max inner loop count is 8 + addi t1,t1,-8 \ Reduce width by 8 + then + + begin \ Inner loop - for each pixel in a font byte + add. t0,t0,t0 \ Shift next pixel bit to top position + 0< if + stbu t9,1(t3) \ Write foreground color to framebuffer + else + stbu tos,1(t3) \ Write background color to framebuffer + then + countdown \ Repeat until width count = 0 + + but then + cmpi 0,0,t1,0 + = until + + add t7,t7,t6 \ Next scan line in font table + addic. t4,t4,-1 \ Decrement height counter + add t3,t3,t2 \ Increment frame buffer addr to next line + = until \ Repeat until height count = 0 + + mtspr ctr,t8 \ Restore counter + lwzu tos,4(sp) \ Clean up stack + addi sp,sp,4 +c; + +\ Very fast window move, for scrolling +\ Similar to 'move', but only moves #move/line out of every 'bytes/line' bytes +\ Assumes bytes/line is divisible by 8 (for double-long load/stores) +\ Assumes src and dst separated by n*bytes/line +\ Called with: +\ src-start dst-start size bytes/line #move/line fb8-move +\ (break-lo)(cursor-y) (winbot-breaklo) (") (emu-bytes/line) +\ src > dst, so move from start towards end + +\ Note that the 601 is a 32-bit implementation. +\ It would be cool to test here, but the PVR is supervisor-only! +[ifdef] sixtyfour-bit + 8 constant fbalign +[else] + 4 constant fbalign +[then] + +code fb8-window-move ( src-start dst-start size bytes/line #move/line -- ) + \ tos=#move/line + lwz t0,0(sp) \ t0=bytes/line + lwzu t1,1cell(sp) \ t1=size + lwzu t2,1cell(sp) \ t2=dst-start + lwzu t3,1cell(sp) \ t3=src-start + + fbalign 1- addi t5,r0,* \ Get fbalign-1 into a register + + \ First, force src and dst to alignment boundary, adjust #move/line + and t4,t3,t5 \ Any extra bytes at start? + add tos,tos,t4 \ Adjust #move/line by that amount + andc t3,t3,t5 \ Lock src to alignment boundary + andc t2,t2,t5 \ Lock dst to alignment boundary + add tos,tos,t5 \ Round #move/line up to next unit + andc tos,tos,t5 + + subf t4,tos,t0 \ Account for inner loop incrementing + + fbalign negate addi t3,t3,* \ Account for pre-incrementing + fbalign negate addi t2,t2,* \ Account for pre-incrementing +[ifdef] sixtyfour-bit + rlwinm tos,tos,29,3,31 +[else] + rlwinm tos,tos,30,2,31 +[then] + mfspr t7,ctr \ Save counter + + cmpi 0,0,t1,0 + ahead \ Branch to loop end for initial comparison + begin \ Outer loop + mtspr ctr,tos \ Setup inner loop index + + begin \ Inner loop +[ifdef] sixtyfour-bit + ldzu t6,8(t3) + stdu t6,8(t2) +[else] + lwzu t6,4(t3) + stwu t6,4(t2) +[then] + countdown + + subf. t1,t0,t1 \ Decrement size until =0 + add t2,t4,t2 \ Increment src + add t3,t4,t3 \ Increment dst + but then \ Target of "ahead" branch + <= until \ End outer loop when size=0 + + mtspr ctr,t7 \ Restore counter + + lwzu tos,1cell(sp) \ Clean up stack + addi sp,sp,1cell +c; + +headers + +\ 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/ppc/field.fth =================================================================== --- cpu/ppc/field.fth (rev 0) +++ cpu/ppc/field.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,45 @@ +purpose: Structures and fields for PowerPC +\ See license at end of file + +\ field creates words which add their offset within the structure +\ to the base address of the structure + +: struct ( -- 0 ) 0 ; + +: field \ name ( offset size -- offset+size ) + create over , + + + \ The high level equivalen of what the following machine code is: + \ does> @ file @ + ; + \ We write it in code because the metacompiler facilities for + \ resolving DOES> clauses are clumsy + + ;code ( struct-adr -- field-adr ) + pop-to-t0 \ Get the struct address + lwz tos,0(tos) \ Get the structure member offset + add tos,tos,t0 \ Return the structure member address +c; + +\ 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/ppc/filecode.fth =================================================================== --- cpu/ppc/filecode.fth (rev 0) +++ cpu/ppc/filecode.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,165 @@ +purpose: File system support code for PowerPC +\ See license at end of file + +headerless +\ signed mixed mode addition +code ln+ (s n1 n2 -- n3 ) pop-to-t0 add tos,tos,t0 c; + +\ &ptr is the address of a pointer. fetch the pointed-to +\ character and post-increment the pointer + +code @c@++ ( &ptr -- char ) + lwz t0,0(tos) \ Fetch the pointer + mr t1,tos \ Copy of the address + lbz tos,0(t0) \ Get the byte + addi t0,t0,1 \ Increment the pointer + stw t0,0(t1) \ Replace the pointer +c; + +\ &ptr is the address of a pointer. store the character into +\ the pointed-to location and post-increment the pointer + +code @c!++ ( char &ptr -- ) + lwz t0,0(tos) \ Fetch the pointer + lwz t1,0(sp) \ char in t1 + stb t1,0(t0) \ Put the byte + addi t0,t0,1 \ Increment the pointer + stw t0,0(tos) \ Replace the pointer + lwz tos,1cell(sp) \ Fixup top of stack + addi sp,sp,2cells \ Adjust stack pointer +c; + +headers +\ "adr1 len2" is the longest initial substring of the string "adr1 len1" +\ that does not contain the character "char". "adr2 len1-len2" is the +\ trailing substring of "adr1 len1" that is not included in "adr1 len2". +\ Accordingly, if there are no occurrences of that character in "adr1 len1", +\ "len2" equals "len1", so the return values are "adr1 len1 adr1+len1 0" + +code split-string ( adr1 len1 char -- adr1 len2 adr1+len2 len1-len2 ) + \ char in tos + lwz t1,0(sp) \ len1 + lwz t0,1cell(sp) \ adr1 + + cmpi 0,0,t1,0 \ Test length + 0<> if + mfspr t5,ctr + mtspr ctr,t1 + + addi t0,t0,-1 \ Account for pre-increment + + begin + lbzu t3,1(t0) \ get the next character + cmp 0,0,t3,tos \ Look for the terminator character + bc 0,2,* + + = if \ Found terminator? + mfspr tos,ctr \ len1-len2-1 + addi tos,tos,1 \ len1-len2 + subfc t1,tos,t1 \ len2 ( Use subfc for POWER compatibility) + stw t1,0(sp) \ store len2 on stack + + stwu t0,-1cell(sp) \ Store adr1+len2 on stack + mtspr ctr,t5 + next + then + mtspr ctr,t5 + then + + \ The test character is not present in the input string + + stwu t0,-1cell(sp) \ Store adr1+len2 on stack + addi tos,r0,0 \ Return rem-len=0 +c; + +headerless +\ Splits a buffer into two parts around the first line delimiter +\ sequence. A line delimiter sequence is either CR, LF, CR followed by LF, +\ or LF followed by CR. +\ adr1 len2 is the initial substring before, but not including, +\ the first line delimiter sequence. +\ adr2 len3 is the trailing substring after, but not including, +\ the first line delimiter sequence. + +code parse-line ( adr1 len1 -- adr1 len2 adr2 len3 ) + mr t1,tos \ len1 + lwz t0,0(sp) \ adr1 + + set tos,10 \ Delimiter 1 (linefeed) + set t4,13 \ Delimiter 2 (carriage return) + + cmpi 0,0,t1,0 \ Test length + 0<> if + mfspr t5,ctr + mtspr ctr,t1 + + addi t0,t0,-1 \ Account for pre-increment + + begin + lbzu t2,1(t0) \ get the next character + cmp 0,0,t2,tos <> if cmp 0,0,t2,t4 then \ Compare to delimiters + bc 0,2,* + + = if \ Found delimiter? + mfspr t3,ctr \ len1-len2 + addi t3,t3,1 + addi t0,t0,1 \ Consume first delimiter + + subfc t1,t3,t1 \ len2 ( Use subfc for POWER compatibility) + stwu t1,-1cell(sp) \ store len2 on stack + + addic. t3,t3,-1 + 0<> if \ Is there another delimiter? + lbz t6,0(t0) \ Get the next character + + \ Compare next character to other delimiter + cmp 0,0,t2,tos = if cmp 0,0,t6,t4 else cmp 0,0,t6,tos then + + = if \ If next character is the other delimiter + addi t0,t0,1 \ ... consume it + addi t3,t3,-1 + then + then + stwu t0,-1cell(sp) \ Store adr1+len2 on stack + + mr tos,t3 \ Return len1-len2 + mtspr ctr,t5 + next + then + mtspr ctr,t5 + then + + \ There is no line delimiter in the input string + + stwu t1,-1cell(sp) \ Store len2 (=len1) on stack + stwu t0,-1cell(sp) \ Store adr1+len2 on stack + addi tos,r0,0 \ Return rem-len=0 +c; + +headers + +nuser delimiter + +\ 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/ppc/filefld.fth =================================================================== --- cpu/ppc/filefld.fth (rev 0) +++ cpu/ppc/filefld.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,50 @@ +purpose: Code words to support the file system interface +\ See license at end of file + +nuser file + +:-h struct ( -- 0 ) 00 ;-h + +\ Run-time action for fields +code dofield + lwz tos,0(tos) \ Get the structure member offset + 'user file lwz t0,* \ Get the structure base address + add tos,tos,t0 \ Return the structure member address +c; + +\ Assembles the code field when metacompiling a field +:-h file-field-cf ( -- ) + dodoes token,-t + " dofield" $sfind drop resolution@ token,-t \ code field +;-h + +\ Metacompiler defining word for creating fields +:-h file-field \ name ( offset size -- offset' ) + " file-field-cf" header-t \ name field and code field + over ,-t + ?debug \ parameter field +;-h + + +\ 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/ppc/finish.fth =================================================================== --- cpu/ppc/finish.fth (rev 0) +++ cpu/ppc/finish.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,41 @@ +purpose: Final cleanup for kernel metacompilation +\ See license at end of file + +' init is do-init +' sys-init-io is init-io + +also assembler +'body cold-code 4 + cld 8 + put-branch +previous +variable dodoesaddr + +assembler dodoes meta is dodoesaddr +forth-h +metaoff +only forth also definitions +fix-vocabularies +' symbols fixall + +\ 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/ppc/fixvoc.fth =================================================================== --- cpu/ppc/fixvoc.fth (rev 0) +++ cpu/ppc/fixvoc.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,52 @@ +purpose: Fixup vocabularies at the end of kernel metacompilation +\ See license at end of file + +only forth meta also forth also definitions +\ Nasty kludge to resolve the to pointer to the does> clause of vocabulary +\ within "forth". The problem is that the code field of "forth" contains +\ a call instruction to the does> clause of vocabulary. This call is a +\ forward reference which cannot be resolved in the same way as compiled +\ addresses. + +: used-t ( definer-acf child-acf -- ) + [ also meta ] token!-t [ previous ] +; + +: fix-vocabularies ( -- ) + [""] <vocabulary> also symbols find previous ( acf true | str false ) + 0= abort" Can't find <vocabulary> in symbols" + dup resolution@ >r ( acf ) ( Return stack: <vocabulary>-adr ) + dup first-occurrence@ ( acf occurrence ) + \ Don't let fixall muck with this entry later + 0 rot >first-occurrence ! ( occurrence ) + begin another-occurrence? while ( occurrence ) + dup [ meta ] token@-t [ forth ] swap ( next-occurrence occurrence ) + \ Calculate the longword offset to the vocabulary does> clause + r@ swap used-t + repeat + r> drop +; + +\ 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/ppc/flipdic.fth =================================================================== --- cpu/ppc/flipdic.fth (rev 0) +++ cpu/ppc/flipdic.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,71 @@ +purpose: Endian-swap the Forth dictionary for PowerPC +\ See license at end of file + +\needs bittest fload ${BP}/forth/lib/bitops.fth +\needs lbflip \needs lbsplit fload ${BP}/forth/lib/split.fth +\needs lbflip : lbflip ( l1 -- l2 ) lbsplit swap 2swap swap bljoin ; +\needs lbflips : lbflips ( a l -- ) bounds ?do i l@ lbflip i l! /l +loop ; + +0 value header +h# 20 constant /header +0 value dict +0 value /dict +0 value ua +0 value /ua +0 value relmap +0 value total-size + +: ?lbflips ( adr len -- ) + 3 + 4 / 0 ?do ( adr ) + i relmap bittest 0= if ( adr ) + dup i la+ dup l@ lbflip swap l! ( adr ) + then ( adr ) + loop ( adr ) + drop +; + +reading fw.dil +ifd @ fsize to total-size +total-size alloc-mem to header +header total-size ifd @ fgets drop +ifd @ fclose + +header /header + to dict +header 1 la+ l@ to /dict + +dict /dict + to ua +header 2 la+ l@ to /ua + +ua /ua + to relmap + +header /header lbflips +dict /dict ?lbflips +ua /ua lbflips + +writing fw.dic +header total-size ofd @ fputs +ofd @ fclose + +\ 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/ppc/flips.fth =================================================================== --- cpu/ppc/flips.fth (rev 0) +++ cpu/ppc/flips.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,63 @@ +purpose: Switch to little-endian after the firmware is already running +\ See license at end of file + +code lbflips ( adr len -- ) + mfspr r10,ctr + + mr r6,tos + rlwinm r6,r6,30,2,31 \ Divide by /l + mtspr ctr,r6 + + lwz r5,0(sp) + addi sp,sp,1cell + + begin + lwz r4,0(r5) + stwbrx r4,r0,r5 + addi r5,r5,4 + countdown + mtspr ctr,r10 +c; + +code wbflips ( adr len -- ) + mfspr r10,ctr + + mr r6,tos + rlwinm r6,r6,31,1,31 \ Divide by /w + mtspr ctr,r6 + + lwz r5,0(sp) + addi sp,sp,1cell + + begin + lhz r4,0(r5) + sthbrx r4,r0,r5 + addi r5,r5,2 + countdown + mtspr ctr,r10 +c; + + +\ 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/ppc/forthint.fth =================================================================== --- cpu/ppc/forthint.fth (rev 0) +++ cpu/ppc/forthint.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,258 @@ +purpose: Low-level handler for alarm interrupt +\ See license at end of file + +headerless +\ Interfaces to system-dependent routines +defer init-dispatcher ( -- ) ' noop to init-dispatcher +defer dispatch-interrupt ' noop to dispatch-interrupt + +h# 400 constant /intstack +hex + +0 value tick-limit +0 value 'rm-intret + +decimal + +label rm-interrupt-return ( -- ) + mfspr r2,sprg0 \ physical address of this cpu's exception-area + + stw t3,h#0c(r2) \ Put derived flag in a safe place + + lwz r31,h#9fc(r0) \ Address of interrupt save area + + \ Now we have to get these guys back into the per-prpcessor + \ save area. They were squirreld away here by interrupt-preamble + 38 /l* 31 lwz r0,* stw r0,0(r2) \ r3 + 39 /l* 31 lwz r0,* stw r0,4(r2) \ r2 + 40 /l* 31 lwz r0,* stw r0,8(r2) \ lr + + 32 /l* 31 lwz r0,* mtspr xer,r0 \ xer + 34 /l* 31 lwz r0,* mtspr ctr,r0 \ ctr + 35 /l* 31 lwz r0,* mtspr srr0,r0 \ saved pc + 36 /l* 31 lwz r0,* mtspr srr1,r0 \ saved msr + +\ XXX the next line is probably unnecessary, because RFI doesn't change the +\ ILE bit, and we are careful to preserve it when we enter the high-level +\ handler. + mfmsr r1 rlwimi r1,r0,0,15,15 mtmsr r1 \ Restore MSR ILE bit - RFI won't + + 37 /l* 31 lwz r0,* stw r0,h#10(r2) \ Put CR in low memory area + + \ Assemble 32 "lwz rN,N*4(r31)" instructions + 32 0 do + i 4 * ( offset ) 31 ( r31 ) i ( reg# ) " lwz *,*" evaluate + loop + + mfspr r2,sprg0 + + \ Now the registers and low-memory values are back to the state that + \ existed upon entry to the interrupt handler. We can use only r3 and lr + \ in the following code. + + lwz r3,h#0c(r2) \ Abort flag + cmpi 0,0,r3,0 + <> if \ Abort if non-zero + lwz r3,h#10(r2) \ Restore CR + mtcrf h#ff,r3 + + lwz r3,h#9f0(r0) \ Save-state address + mtspr lr,r3 + addi r3,r0,-1 \ Indicate an abort + stw r3,h#0c(r2) \ Exception # + bclr 20,0 \ Jump to save-state + then + + lwz r3,h#10(r2) \ Restore CR + mtcrf h#ff,r3 + + lwz r3,h#08(r2) \ Restore LR + mtspr lr,r3 + + lwz r3,h#0(r2) \ Restore r3 + lwz r2,h#04(r2) \ Restore r2 + + rfi +end-code + +code interrupt-return ( -- ) + + \ At the first indication of a keyboard abort, we branch to the + \ Forth entry trap handler. We do the actual branch after we have + \ restored all the state, so it appears as if Forth were entered + \ directly from the program that was running, rather than through + \ the interrupt handler. + + addi t3,r0,0 \ Clear derived abort flag + 'user aborted? lwz t5,* \ Abort flag + + cmpi 0,0,t5,1 + = if + \ Don't abort in the middle of the terminal emulator, because + \ it's not reentrant. + + 'user terminal-locked? lwz t4,* + cmpi 0,0,t4,0 + = if + + \ Increment the abort flag past 1 so that we won't see it again + \ until the interpreter has seen and cleared it. + addi t5,t5,1 + 'user aborted? stw t5,* + + addi t3,r0,-1 \ Set derived abort flag + then + then + + mfmsr t4 + rlwinm t4,t4,0,28,25 \ Get back into real mode so we won't have + mtspr srr1,t4 \ translation faults in the following code. + + 'user 'rm-intret lwz t4,* + mtspr srr0,t4 + + rfi +end-code + +: interrupt-handler ( exc-adr -- ) + h# 900 = if check-alarm else dispatch-interrupt then + interrupt-return +; + +\ This routine is entered in real mode. +\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area, +\ r3 points to the address where the exception occured. +label interrupt-preamble + stw r3,h#9e8(r0) \ Save exception address + lwz r3,h#9fc(r0) \ Physical address of register save area + + \ Save the registers + + \ Assemble 32 "stw rN,N*4(r3)" instructions + 32 0 do + i 4 * ( offset ) 3 ( r3 ) i ( reg# ) " stw *,*" evaluate + loop + + \ We can't leave these in the sprg save area because they will + \ get trounced if we get a DSI in the hi level part of the handler + lwz r0,0(r2) 38 /l* 3 stw r0,* \ r3 + lwz r0,4(r2) 39 /l* 3 stw r0,* \ r2 + lwz r0,8(r2) 40 /l* 3 stw r0,* \ lr + + mfspr r0,xer 32 /l* 3 stw r0,* \ xer + mfspr r0,ctr 34 /l* 3 stw r0,* \ ctr + mfspr r0,srr0 35 /l* 3 stw r0,* \ saved pc + mfspr r0,srr1 + + \ Save the ILE bit too; it doesn't show up in SRR1, so we get it + \ from the LE bit in in the current MSR value, putting it in its + \ normal position in the saved value. + mfmsr r1 rlwimi r0,r1,16,15,15 + + \ Keep a copy for later use in establishing the MSR value for the + \ high-level interrupt handler, but turn off the EE bit so that the + \ handler can't be re-entered + rlwinm t1,r0,0,17,15 + + 36 /l* 3 stw r0,* \ saved msr + mfcr r0 37 /l* 3 stw r0,* \ cr + + lwz t0,h#9ec(r0) \ Virtual address of interrupt stack area + + \ Set up Forth stacks + addi sp,t0,h#200 \ Data stack pointer + addi rp,sp,h#200 \ Return stack pointer + + lwz t0,h#9f4(r0) \ Get decrementer initial value + mtspr dec,t0 \ Restart ticker + + here 4 + bl * \ Get address of next instruction into LR + here origin - set t0,* \ Relative address of this instruction + mfspr base,lr + subf base,t0,base \ Base register is now set (physical address) + + 'body main-task set up,* \ Relative address of main-task + lwzx up,up,base \ User pointer is now set + + lwz base,h#9f8(r0) \ Virtual address of origin + lwz tos,h#9e8(r0) \ Stack exception address + + 'body interrupt-handler 4 - set ip,* + add ip,ip,base + + mtspr ctr,up \ Pointer to NEXT routine + + \ Restore old MSR value so normal address translation can occur, but + \ don't allow other external interrupts + mtspr srr1,t1 \ Old MSR value + mtspr srr0,up \ Address of NEXT routine + rfi +end-code + +\ code dec! ( #ticks -- ) +\ mtspr dec,tos +\ lwz tos,0(sp) +\ addi sp,sp,1cell +\ c; +\ code dec@ ( -- #ticks ) +\ stwu tos,-1cell(sp) +\ mfspr tos,dec +\ c; + +\ The implementations are defined in msr.fth +' (enable-interrupts) to enable-interrupts +' (disable-interrupts) to disable-interrupts +' (lock) to lock[ +' (unlock) to ]unlock + +: set-tick-limit ( #msecs -- ) + to ms/tick + ms/tick counts/ms * to tick-limit + tick-limit dec! + tick-limit h# 9f4 ! +; +: install-alarm ( -- ) + \ Put various important parameters in real memory where the + \ real-mode part of the interrupt handler can find them. + + /intstack alloc-mem dup h# 9ec ! >physical h# 9fc ! \ Interrupt stack + origin h# 9f8 ! + tick-limit h# 9f4 ! + save-state >physical h# 9f0 ! + + rm-interrupt-return >physical to 'rm-intret + + disable-interrupts + interrupt-preamble h# 500 put-exception \ External interrupt + interrupt-preamble h# 900 put-exception \ Decrementer interrupt + init-dispatcher + d# 10 set-tick-limit + enable-interrupts \ Turn interrupts on +; + +headers +hex + +\ 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/ppc/ftrace.fth =================================================================== --- cpu/ppc/ftrace.fth (rev 0) +++ cpu/ppc/ftrace.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,33 @@ +purpose: Display a Forth stack backtrace +\ See license at end of file + +only forth also hidden also forth definitions +: ftrace ( -- ) \ Forth stack + ip >saved .traceline + rp >saved rssave-end swap (rstrace +; +only forth also definitions + +\ 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/ppc/gdb.fth =================================================================== --- cpu/ppc/gdb.fth (rev 0) +++ cpu/ppc/gdb.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,67 @@ +purpose: PowerPC-specific words for remote GDB interface +\ See license at end of file + +only forth also hidden also definitions +headerless + +: ppc-read-registers ( -- ) + xbuf + %r0 gr %r1 gr %r2 gr %r3 gr %r4 gr %r5 gr %r6 gr %r7 gr + %r8 gr %r9 gr %r10 gr %r11 gr %r12 gr %r13 gr %r14 gr %r15 gr + %r16 gr %r17 gr %r18 gr %r19 gr %r20 gr %r21 gr %r22 gr %r23 gr + %r24 gr %r25 gr %r26 gr %r27 gr %r28 gr %r29 gr %r30 gr %r31 gr + + %f0 dr %f1 dr %f2 dr %f3 dr %f4 dr %f5 dr %f6 dr %f7 dr + %f8 dr %f9 dr %f10 dr %f11 dr %f12 dr %f13 dr %f14 dr %f15 dr + %f16 dr %f17 dr %f18 dr %f19 dr %f20 dr %f21 dr %f22 dr %f23 dr + %f24 dr %f25 dr %f26 dr %f27 dr %f28 dr %f29 dr %f30 dr %f31 dr + +\ %y gr %psr gr %wim gr %tbr gr %pc gr %npc gr %fpsr gr %cpsr gr + xbuf tuck - putpkt +; +: ppc-write-registers ( -- ) + rbuf 1+ + v to %r0 v to %r1 v to %r2 v to %r3 v to %r4 v to %r5 v to %r6 v to %r7 + v to %r8 v to %r9 v to %r10 v to %r11 v to %r12 v to %r13 v to %r14 v to %r15 + v to %r16 v to %r17 v to %r18 v to %r19 v to %r20 v to %r21 v to %r22 v to %r23 + v to %r24 v to %r25 v to %r26 v to %r27 v to %r28 v to %r29 v to %r30 v to %r31 + + w to %f0 w to %f1 w to %f2 w to %f3 w to %f4 w to %f5 w to %f6 w to %f7 + w to %f8 w to %f9 w to %f10 w to %f11 w to %f12 w to %f13 w to %f14 w to %f15 + w to %f16 w to %f17 w to %f18 w to %f19 w to %f20 w to %f21 w to %f22 w to %f23 + w to %f24 w to %f25 w to %f26 w to %f27 w to %f28 w to %f29 w to %f30 w to %f31 + +\ v to %y v to %psr v to %wim v to %tbr v to %pc v to %npc +\ v to %fpsr v to %cpsr gr + drop + okay-reply +; +' ppc-read-registers to read-registers +' ppc-write-registers to write-registers + +headers +only forth also definitions + +\ 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/ppc/getms.fth =================================================================== --- cpu/ppc/getms.fth (rev 0) +++ cpu/ppc/getms.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,261 @@ +purpose: Interval timing functions +\ See license at end of file + +headerless +code 601? ( -- flag ) + stwu tos,-1cell(sp) + mfspr tos,pvr + rlwinm tos,tos,16,16,31 + cmpi 0,0,tos,1 + = if + set tos,-1 + else + set tos,0 + then +c; + +\ 604 TB is incremented at 1/4 the speed of the system bus. +\ at 40Mhz sysclk, there are 10000 counts/ms. +\ at 50Mhz sysclk, there are 12500 counts/ms. +\ default: 50Mhz +\ d# 8250 value counts/ms \ For a 603 with a 33 MHz bus clock +\ d# 10000 value counts/ms \ For a 604 with a 40 MHz bus clock +\ d# 12500 value counts/ms \ For a 604 with a 50 MHz bus clock +\ d# 16500 value counts/ms \ For a 604 with a 66 MHz bus clock + +headers +d# 8250 value counts/ms \ For a 603 with a 33 MHz bus clock + +headerless +\ XXX Put in the actual ratios when IBM gets around to documenting +\ the encoding of the bus ratio field +\ create 620-ratios ? c, ? c, ? c, ? c, +: bus-ratio ( -- n ) + 620-class? if +\ buscsr@ d# 22 2 bits 620-ratios + c@ + 1 \ Temporary value + else + 4 + then +; +headers +\ We want "microseconds" to have a range of at least 1 second +\ (1,000,000 microseconds) and as good a precision as possible +\ given that constraint. We do this by choosing multiplier and +\ divisor values accordingly. +0 value us-multiplier +0 value us-divisor +: calibrate-microseconds ( -- ) + \ The starting multiplier is counts/ms and the starting divisor is + \ 1000 (microseconds/millisecond). We can eliminate common factors + \ without introducing inaccuracy, so we go ahead and do that. The + \ factors of 1000 are 2x2x2x5x5x5. + + d# 1000 counts/ms ( denominator numerator ) + + \ Remove powers of two + begin 2dup or 1 and 0= while swap 2/ swap 2/ repeat ( den' num' ) + + \ Remove powers of 5 + begin ( den num ) + over 5 mod 0= over 5 mod 0= and ( den num flag ) + while ( den num ) + swap 5 / swap 5 / ( den' num' ) + repeat ( den num ) + + \ At this point, if the numerator is still too large (unlikely), + \ we divide the numerator by the denominator and accept the loss + \ in precision. + dup d# 4294 > if ( den num ) + swap / 1 swap ( 1 num' ) + then + + \ If the numerator is *still* too large, we just live with the + \ loss in range. We could do something like use 64-bit arithmetic + \ or loop over several calls to the low-level primitive, but we will + \ cross that bridge when we get to it (it won't happen until we see + \ a processor with a timebase tick rate of > 4K ticks/microsecond; + \ the timebase rate is typically scaled down considerably from the + \ instruction rate). + to us-multiplier to us-divisor +; + +\ The 601 increments the RTC register pair and decrements the +\ decrementer register by 128 counts every 128 nsec, thus their +\ count values represent nanoseconds. Other PowerPC processors +\ count bus clocks, with no absolute calibration. +: calibrate-ticker ( -- ) + 601? if + d# 1000000 + else + d# 8250 + + \ Current PowerPC processors run the timebase at 1/4 the bus clock + " /" find-package if + " clock-frequency" rot get-package-property 0= if ( n adr len ) + rot drop get-encoded-int d# 1000 / ( n' ) + bus-ratio / + then + then + + then + to counts/ms + calibrate-microseconds +; +headerless + +code get-rtclu ( -- nsec sec ) + stwu tos,-4(sp) + begin \ Loop until we get a consistent sample + mfspr t1,rtcu + mfspr t0,rtcl + mfspr tos,rtcu + cmp 0,0,t1,tos + = until + stwu t0,-4(sp) +c; +code get-tb ( -- ticks.lo ticks.hi ) + stwu tos,-4(sp) + begin \ Loop until we get a consistent sample + isync + mftb t1,tbu + mftb t0,tb + mftb tos,tbu + cmp 0,0,t1,tos + = until + stwu t0,-4(sp) +c; +: get-msecs-601 ( -- ms ) + get-rtclu d# 40000000 mod d# 1000 * swap counts/ms / + +; +: get-msecs-ppc ( -- ms ) get-tb counts/ms um/mod nip ; +: (get-msecs) ( -- ms ) 601? if get-msecs-601 else get-msecs-ppc then ; +' (get-msecs) to get-msecs + +: ms-601 ( n -- ) + d# 1000 /mod ( msec sec ) + swap counts/ms * swap ( nsec sec ) + get-rtclu ( nsec sec nsec sec ) + rot + -rot + dup d# 1000000000 >= if + d# 1000000000 - swap 1+ + else + swap + then ( target-nsec target-sec ) + + begin + get-rtclu ( target-nsec target-sec nsec sec ) + 2 pick 2dup u> if 5drop exit then ( t-n t-s n s t-s ) + = if + 2 pick ( t-n t-s n t-n ) u>= if 2drop exit then + else + drop + then + again +; +: ms-ppc ( n -- ) + counts/ms um* ( d.nsec ) + get-tb d+ ( d.target-ticks ) + + begin + get-tb ( d.target-ticks d.ticks ) + 2over d- ( d.target-ticks d.diff ) + nip 0>= + until + 2drop +; +: (ms) ( n -- ) 601? if ms-601 else ms-ppc then ; +' (ms) to ms + +code dec! ( #ticks -- ) \ Store the decrementer register + sync + mtspr dec,tos + sync + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code dec@ ( -- #ticks ) \ Read the decrementer rgister + stwu tos,-1cell(sp) + sync + mfspr tos,dec +c; +code tb@ ( -- ticks.lo ) + stwu tos,-4(sp) + isync + mftb tos,tb +c; + + +\ On a 60 MHz 8xx, the fixed overhead of this word is about .5 microseconds, +\ so the actual time delay is about half a count longer. On faster processors, +\ the overhead might be somewhat smaller, although the multiply time, the +\ time to enable and disable interrupts, and the time to read the time base +\ register might not quite scale with the clock rate. + +\ Delay at least n microseconds. Interrupts remain enabled. +code unlocked-microseconds ( #microseconds -- ) + 'user us-multiplier lwz t0,* \ Multiplier + mullw tos,t0,tos \ Counts*125 + 'user us-divisor lwz t0,* \ Divisor + divwu tos,tos,t0 \ Counts + mftb t0,tb \ Current time + add tos,tos,t0 \ Target time + begin + mftb t0,tb \ Get time + subf. t0,tos,t0 \ Compare to target using circular arithmetic + 0>= until \ Spin until target time reached + lwz tos,0(sp) \ Clean up stack + addi sp,sp,4 +c; + +\ Delay n microseconds with interrupts disabled. This gives more precise +\ timing but keeps the processor from doing other things. +code microseconds ( #microseconds -- ) + mfmsr t1 + rlwinm t2,t1,0,17,15 \ Clear interrupt enable bit + mtmsr t2 \ Disable interrupts + + 'user us-multiplier lwz t0,* \ Multiplier + mullw tos,t0,tos \ Counts*125 + 'user us-divisor lwz t0,* \ Divisor + divwu tos,tos,t0 \ Counts + mftb t0,tb \ Current time + add tos,tos,t0 \ Target time + begin + mftb t0,tb \ Get time + subf. t0,tos,t0 \ Compare to target using circular arithmetic + 0>= until \ Spin until target time reached + lwz tos,0(sp) \ Clean up stack + addi sp,sp,4 + + mtmsr t1 \ Restore interrupts +c; + +headers +stand-init: Calibrate + calibrate-ticker +; + +\ 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/ppc/hacks.fth =================================================================== --- cpu/ppc/hacks.fth (rev 0) +++ cpu/ppc/hacks.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,43 @@ +purpose: Little code fragments to clip out and paste in real programs as needed +\ See license at end of file + +\ For startup code - displays I and D if caches on, i and d if caches off +mfspr t0,hid0 +andi. t0,t0,h#4000 +0<> if + ascii D ?report +else + ascii d ?report +then + +mfspr t0,hid0 +andi. t0,t0,h#8000 +0<> if + ascii I ?report +else + ascii i ?report +then + +\ 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/ppc/htabmmu.fth =================================================================== --- cpu/ppc/htabmmu.fth (rev 0) +++ cpu/ppc/htabmmu.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,753 @@ +purpose: HTAB paged MMU driver +\ See license at end of file + +also forth definitions + +headers + +h# 1.0000 value /htab +/htab value htab +/htab value htab-phys + +headerless + +false value mmu64? +h# 40 value tag-h +h# 8000.0000 value tag-v + 8 value /htab-entry +/htab-entry 8 * value /htab-group +previous definitions + +also +: invalidate-pte ( pte-adr -- ) 0 swap l! ; + +\ Data in exception vector area: +\ 4f0: save-state address +\ 4f4: PTEG roving replacement offset +\ 4f8: physical base address of "translations" list +\ 4fc: virtual base address of "translations" list + +\ Data in this cpu's exception area (exception-area) +\ 00: save r3 +\ 04: save r2 +\ 08: save lr +\ 0c: save exception number +\ 10: save cr +\ 14: save base +\ 18: save ip +\ 1c: save lr +\ 20-3c: save registers + +\ fault - r4 node - r5 offset - r6 adr - r7 end - r8 +\ Physical address +also assembler also register-names definitions +warning @ warning off +4 constant fault +5 constant node +6 constant offset +7 constant adr +8 constant end +9 constant temp +warning ! +previous previous definitions + +\ get-phys searches the "translations" list, which is the master copy of +\ the information describing the current set of virtual to physical +\ address translations. The input (in r3) is the virtual address. The +\ output (in r3) is -1 if there was no mapping for that virtual address, +\ or the physical word of the PTE, containing the physical page number and +\ the mode bits, otherwise. + +\ Input: r4 - virtual address of fault +\ Output: r3 - physical_PTE_word or -1 +\ Destroys: r4-r8 +label get-phys + lwz node,h#4f8(r0) \ Physical base address of translation list + lwz offset,h#4fc(r0) \ Virtual base address of translation list + ahead begin + subf node,offset,node \ Convert node virtual address to physical + lwz adr,1cell(node) \ Beginning virtual address of range + cmpl 0,0,adr,fault \ Test beginning of range + <= if + lwz end,2cells(node) \ Length of mapped range + add end,adr,end \ Ending virtual address of range + cmpl 0,0,end,fault \ Test end of range + > if +1 L: + \ We found it + rlwinm temp,fault,0,0,19 \ Zero fault address page offset bits + subf adr,adr,temp \ Compute page offset within range + lwz r3,3cells(node) \ Physical page# + rlwinm r3,r3,12,0,19 \ Shift page# into place + add r3,r3,adr \ physical address portion is complete + lwz adr,4cells(node) \ WIMG.PP + or r3,r3,adr \ PTE physical word is complete +2 L: + bclr 20,0 + then + + \ If the ending address is 0, it really means 2^32, which is + \ larger than any possible fault address. + cmpi 0,0,end,0 + 1 B: = brif + + then + + but then + lwz node,0(node) \ Next node + cmpi 0,0,node,0 + = until + + \ No translation found + set r3,-1 + + 2 B: again +end-code + +\ r3:phys r4:fault r5:vsid r6:pteg r7:htab/ctr_save r8:mask r9:temp + +also assembler also register-names definitions +warning @ warning off +5 constant vsid +6 constant pteg +7 constant htab +8 constant mask +warning ! +previous previous definitions + +label find-pte ( r4: virtual -- r5: vsid r6: 'pte ) + mfsrin vsid,fault \ Get virtual segment ID + rlwinm vsid,vsid,0,13,31 \ Keep the low 19 bits (omit protection bits) + rlwinm pteg,fault,20,16,31 \ Move page index bits into place + xor pteg,vsid,pteg \ Compute hash value + + mfspr htab,sdr1 \ Get hash table base address and size mask + +mfspr mask,pvr +rlwinm mask,mask,16,16,31 +cmpi 0,0,mask,20 +<> if \ 32-bit code + addi mask,r0,h#3ff \ Set low 10 bits of mask + rlwimi mask,htab,10,13,21 \ merge in upper 9 bits + rlwinm mask,mask,6,7,25 \ Move up 6 bits to align with PTEG address + + rlwinm pteg,pteg,6,7,25 \ Move into place + and pteg,pteg,mask \ Compute low bits of pte + + rlwinm htab,htab,0,0,15 \ Eliminate mask bits + or pteg,htab,pteg \ Insert hash table base into the high bits + + \ Now we have the address of the primary page table entry group in "pteg". + \ We also need to preserve "mask" in case we need to find the secondary + \ PTEG, and "fault" and "vsid" to generate the first word of the new PTE. + + mfspr htab,ctr \ htab is no longer needed so we re-use it + + \ Generate the tag for the first word of the new PTE + rlwinm vsid,vsid,7,1,24 + rlwimi vsid,fault,10,26,31 \ Move bits 4-9 to 26-31 + \ vsid is now the new PTE tag + + \ In little-endian mode, addresses within a PTE are swizzled from the + \ viewpoint of code executing on the CPU, which does 32-bit or smaller + \ accesses, but not from the viewpoint of the table-search hardware, + \ which appears to do 64-bit accesses. Consequently, in little-endian + \ mode, the tag word appears at offset 4 and the physical word at offset 0. + mfmsr temp + andi. temp,temp,1 + <> if \ Little-endian + addi pteg,pteg,4 \ Tag is in second longword when in LE mode + then + + addi pteg,pteg,-8 + set temp,8 + mtspr ctr,temp + begin + lwzu temp,8(pteg) + cmpi 0,0,temp,0 + 1 F: >= brif + countdown + + \ Didn't find room in the primary PTEG - search the secondary PTEG + addi pteg,pteg,h#-38 \ Reset the lower bits + xor pteg,pteg,mask \ Invert the hash bits - to secondary PTEG + + ori vsid,vsid,h#40 \ Set the "H" bit in the tag + + addi pteg,pteg,-8 + set temp,8 + mtspr ctr,temp + begin + lwzu temp,8(pteg) + cmpi 0,0,temp,0 + 1 F: >= brif + countdown + + \ Didn't find room in the secondary PTEG - replace a primary entry. + addi pteg,pteg,h#-38 \ Reset the lower bits + xor pteg,pteg,mask \ Invert the hash bits - back to primary PTEG + rlwinm vsid,vsid,0,26,24 \ Clear the "H" bit in the tag + + \ It might be nice to use the statistics bits to implement a pseudo-LRU + \ replacement policy, but that is too complicated for now (especially + \ since I don't want to bother with the complexity of a periodic process + \ to test the bits), so I'm using a roving replacement pointer instead. + \ The performance difference is probably entirely negligeable in this + \ environment, and might favor the roving pointer anyway. + lwz temp,h#4f4(r0) \ Get replacement index + add pteg,temp,pteg \ Address of PTE to replace + + addi temp,temp,8 \ Update replacement pointer + cmpi 0,0,temp,h#40 + = if + set temp,0 + then + stw temp,h#4f4(r0) + + set temp,0 + stw temp,0(pteg) \ Invalidate tag word +else + set mask,h#4.0000 \ Smallest hash table size +\ TRYME rldcr mask,mask,htab,45 \ Shift to actual size + rlwnm mask,mask,htab,0,13 \ Shift to actual size + addi mask,mask,-1 \ Convert to mask + rlwinm mask,mask,0,0,24 \ Clear low 7 bits to align to PTEG base + +\ TRYME rldic pteg,pteg,7,0 \ Move hash value into place + rlwinm pteg,pteg,7,0,24 \ Move hash value into place + and pteg,pteg,mask \ Compute low bits of PTE + +\ TRYME rldicr htab,htab,0,45 \ Eliminate mask bits + rlwinm htab,htab,0,0,13 \ Eliminate mask bits + or pteg,htab,pteg \ Insert hash table base into the high bits + + \ Now we have the address of the primary page table entry group in "pteg". + \ We also need to preserve "mask" in case we need to find the secondary + \ PTEG, and "fault" and "vsid" to generate the first word of the new PTE. + + mfspr htab,ctr \ htab is no longer needed so we re-use it + + \ Generate the tag for the first word of the new PTE +\ TRYME rldicr vsid,vsid,12,51 + rlwinm vsid,vsid,12,0,19 + rlwimi vsid,fault,16,20,24 \ Move bits 4-8 to 20-24 (64-bit: okay as-is) + \ vsid is now the new PTE tag + +\ ZZZ 23/5/96 was 16 + addi pteg,pteg,-16 \ Account for pre-increment + set temp,8 + mtspr ctr,temp + begin + ldu temp,16(pteg) + andi. temp,temp,1 \ Test valid bit + 1 F: >= brif + countdown + + \ Didn't find room in the primary PTEG - search the secondary PTEG + addi pteg,pteg,h#-70 \ Reset the lower bits + xor pteg,pteg,mask \ Invert the hash bits - to secondary PTEG + + ori vsid,vsid,2 \ Set the "H" bit in the tag + + addi pteg,pteg,-16 + set temp,8 + mtspr ctr,temp + begin + ldu temp,16(pteg) + andi. temp,temp,1 \ Test valid bit + 1 F: >= brif + countdown + + \ Didn't find room in the secondary PTEG - replace a primary entry. + addi pteg,pteg,h#-70 \ Reset the lower bits + xor pteg,pteg,mask \ Invert the hash bits - back to primary PTEG + rlwinm vsid,vsid,0,31,29 \ Clear the "H" bit in the tag + + \ It might be nice to use the statistics bits to implement a pseudo-LRU + \ replacement policy, but that is too complicated for now (especially + \ since I don't want to bother with the complexity of a periodic process + \ to test the bits), so I'm using a roving replacement pointer instead. + \ The performance difference is probably entirely negligeable in this + \ environment, and might favor the roving pointer anyway. + lwz temp,h#4f4(r0) \ Get replacement index + add pteg,temp,pteg \ Address of PTE to replace + + addi temp,temp,16 \ Update replacement pointer + cmpi 0,0,temp,h#80 + = if + set temp,0 + then + stw temp,h#4f4(r0) + + set temp,0 + std temp,0(pteg) \ Invalidate tag word + +\ ZZZ AEC 23/5/1996 added ; 620 errata: tlbia does not work +\ tlbia + sync +then + + sync + tlbie pteg + sync + tlbsync + sync + +1 L: + mtspr ctr,htab + bclr 20,0 +end-code + +\ Common code for HTAB ISI and DSI miss handlers. +\ Input: r3: virtual address +\ r2: exception-area +\ Output: none (returns from interrupt) +\ Side effects: +\ If the input virtual address is mapped, adds or replaces an HTAB entry, +\ clearing the TLB as needed, to reflect that mapping. +\ If the input virtual address is not mapped, transfers control to the +\ unexpected exception handler. +\ Destroys: nothing +\ Requirements: +\ The pre-trap value of R3 must be in memory location 0(sprg0) +\ The pre-trap value of CR must be in memory location h#10(sprg0) +\ Those register values are restored before returning. +\ Uses: +\ Memory location h#0c(sprg0) to store the exception address. +\ Memory locations h#20-h#34(sprg0) for saving registers. + +label htab-miss-handler + + stw r4,h#20(r2) stw r5,h#24(r2) stw r6,h#28(r2) \ Save GPRs + stw r7,h#2c(r2) stw r8,h#30(r2) stw r9,h#34(r2) + + mr fault,r3 + + \ Determine the physical address, if any, to which the virtual address + \ that caused the fault is mapped. + + get-phys bl * \ ( virtual -- pte-phys|-1 ) + + \ If there is no valid mapping for that virtual address, invoke the + \ unexpected exception handler. + cmpi 0,0,r3,-1 \ If no + = if + lwz r4,h#20(r2) lwz r5,h#24(r2) lwz r6,h#28(r2) \ Restore GPRs + lwz r7,h#2c(r2) lwz r8,h#30(r2) lwz r9,h#34(r2) + + \ Restore registers and jump to unexpected exception handler + lwz r3,h#10(r2) mtcrf h#80,r3 \ Restore CR + lwz r3,h#4f0(r0) \ save-state address + mtspr lr,r3 + lwz r3,h#0c(r2) \ Exception address + bclr 20,0 \ branch to exception handler + then + + find-pte bl * ( r4: fault-address -- r6: 'pte ) + + mfspr temp,pvr + rlwinm temp,temp,16,16,31 + cmpi 0,0,temp,20 + <> if \ 32-bit processor + \ pteg now points to the tag word of an invalid PTE; replace its value + \ See clause 4.12.1 of the PPC architecture spec (hard-back book) + \ for an explanation of this sequence. + mfmsr temp + andi. temp,temp,1 + <> if \ Little-endian + stw r3,-4(pteg) \ Replace physical address portion + else + stw r3,4(pteg) \ Replace physical address portion + then + + stw vsid,0(pteg) \ Replace the tag word with valid bit clear + sync + oris vsid,vsid,h#8000 \ Set the valid bit + stw vsid,0(pteg) \ Replace the tag word with valid bit set + else \ 64-bit processor + \ pteg now points to the tag word of an invalid PTE; replace its value + \ See clause 4.12.1 of the PPC architecture spec (hard-back book) + \ for an explanation of this sequence. + std r3,8(pteg) \ Replace physical address portion + std vsid,0(pteg) \ Replace the tag word with valid bit clear + sync + ori vsid,vsid,1 \ Set the valid bit + std vsid,0(pteg) \ Replace the tag word with valid bit set + then + + \ Restore registers used herein + + lwz r4,h#20(r2) lwz r5,h#24(r2) lwz r6,h#28(r2) \ Restore GPRs + lwz r7,h#2c(r2) lwz r8,h#30(r2) lwz r9,h#34(r2) + + \ Restore registers used by the generic trap preamble + lwz r3,h#10(r2) mtcrf h#80,r3 \ Restore CR + lwz r3,h#08(r2) mtspr lr,r3 \ Restore LR + lwz r3,h#00(r2) \ Restore r3 + lwz r2,h#04(r2) \ Restore r2 + + \ Return from interrupt + rfi +end-code + +\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area, +\ r3 points to the address where the exception occured. +label htab-isi-handler + stw r3,h#0c(r2) \ Save exception number + mfcr r3 + stw r3,h#10(r2) \ Save CR + + \ Determine the fault type + mfspr r3,srr1 \ Fault type is in SRR1 for I faults + rlwinm. r3,r3,0,1,1 \ Test bit 1 + 0= if \ Not a translation fault + \ Restore registers and jump to unexpected exception handler + lwz r3,h#10(r2) mtcrf h#80,r3 \ Restore CR + lwz r3,h#4f0(r0) \ save-state address + mtspr lr,r3 + lwz r3,h#0c(r2) \ Exception address + bclr 20,0 \ branch to exception handler + then + + mfspr r3,srr0 \ Get fault address + + htab-miss-handler b * \ Jump to common code +end-code + +\ r2, r3, and lr have been saved. r2 points to the this cpu's exception-area, +\ r3 points to the address where the exception occured. +label htab-dsi-handler + stw r3,h#0c(r2) \ Save exception number + mfcr r3 + stw r3,h#10(r2) \ Save CR + + \ Determine the fault type + mfspr r3,dsisr \ SPR18 + rlwinm. r3,r3,0,1,1 \ Test bit 1 + 0= if \ Not a translation fault + \ Restore registers and jump to unexpected exception handler + lwz r3,h#10(r2) mtcrf h#80,r3 \ Restore CR + lwz r3,h#4f0(r0) \ save-state address + mtspr lr,r3 + lwz r3,h#0c(r2) \ Exception address + bclr 20,0 \ branch to exception handler + then + + mfspr r3,dar \ Get fault address + + htab-miss-handler b * \ Jump to common code +end-code + +previous + +headers +\ sdr1@ and sdr1! are okay for 64-bit implementations if the physical +\ address of the page table is in the lower 4GB of memory, which is a +\ fairly safe assumption. +code sdr1! ( n -- ) + mtspr sdr1,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code sdr1@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,sdr1 +c; + +headerless +\ We could use "fill" for this, but it is slightly faster to do it this way, +\ because we only have to touch every other word. +code invalidate-htab-64 ( -- ) + mfspr t3,sdr1 + rlwinm t3,t3,0,27,31 \ Compute hash table size from shift count + set t4,h#4.0000 \ Shift count 0 means 256K + rlwnm t3,t4,t3,0,31 + + 'user htab lwz t0,* \ Virtual address of hash table + + \ Hardware accesses PTEs as doublewords, so address swizzling doesn't occur. + addi t0,t0,-16 \ Account for pre-increment + + rlwinm t3,t3,28,4,31 \ Divide by 16; we'll touch each PTE once + set t2,0 + mtspr ctr,t3 \ Set loop count + begin + stdu t2,16(t0) \ Clear the tag word of each PTE + countdown + mtspr ctr,up \ Restore CTR register +c; + +\ We could use "fill" for this, but it is slightly faster to do it this way, +\ because we only have to touch every other word. +code invalidate-htab-32 ( -- ) + mfspr t3,sdr1 + rlwinm t3,t3,16,7,15 \ Compute hash table size from mask bits + ori t3,t3,h#ffff \ MAX(hashbits,64k-1) + addi t3,t3,1 + + 'user htab lwz t0,* \ Virtual address of hash table + + \ Hardware accesses PTEs as doublewords, so address swizzling doesn't occur. + \ Consequently, when accessing a PTE from the processor, we must undo + \ its swizzling. + mfmsr t4 + andi. t4,t4,1 \ Test little-endian bit + <> if \ Little endian + addi t0,t0,-4 \ Account for pre-increment and endianness + else + addi t0,t0,-8 \ Account for pre-increment + then + + rlwinm t3,t3,29,3,31 \ Divide by 8; we'll touch each PTE once + set t2,0 + mtspr ctr,t3 \ Set loop count + begin + stwu t2,8(t0) \ Clear the tag word of each PTE + countdown + mtspr ctr,up \ Restore CTR register +c; + +: set-mmu ( -- ) + cpu-version d# 20 = if + true to mmu64? + h# 4.0000 to /htab + 2 to tag-h + 1 to tag-v + d# 16 to /htab-entry + h# 80 to /htab-group + then +; + +: get-htab ( -- phys size ) + sdr1@ dup + mmu64? if + h# 3.ffff invert and h# 4.0000 rot h# 1f and lshift + else + h# ffff invert and swap h# 1ff and 1+ d# 16 lshift + then +; +: set-htab ( phys size -- ) + mmu64? if + log2 d# 18 - ( phys size-code ) + else + 1- d# 16 rshift ( phys size-mask ) + then + or sdr1! +; +: init-paged-mmu ( -- ) + htab /htab 0 mem-claim drop + + \ We don't use invalidate-htab here because we want the HTAB to start + \ out completely clean, and invalidate-htab clears only the tag words. + htab /htab erase + + htab-phys /htab set-htab +[ifdef] invalidate-tlb + invalidate-tlb +[then] +; + +[ifdef] shootdown-range +\ RFE: map? should report BAT mappings and VSID too +\ RFE: MMU driver should account for BAT mappings too + +: >htab-adr ( padr -- vadr ) + htab-phys - htab + + mmu64? if la1+ then + in-little-endian? 4 and xor +; +: htab-@ ( padr -- l ) >htab-adr l@ ; +: htab-! ( l padr -- ) >htab-adr l! ; + +\ HTAB display tools + +: break-pte ( phys-stuff tag -- false | rc.wimg.pp phys api vsid h true ) + \ Check valid bit + dup tag-v and 0= if 2drop false exit then ( phys-stuff tag ) + + \ Extract physical address and type field + over 9 lowbits rot h# fff invert and ( tags rc.wimg.pp phys ) + rot ( rc.wimg.pp phys tags ) + + \ Extract tag information + mmu64? if + d# 7 5 bits d# 23 lshift swap ( rc.wimg.pp phys api tags ) + \ XXX we should extract more vsid bits from the 64-bit tag + dup d# 12 d# 25 bits swap ( rc.wimg.pp phys api vsid tags ) + 1 1 bits ( rc.wimg.pp phys api vsid h ) + else + dup h# 7f and d# 22 lshift swap ( rc.wimg.pp phys api tags ) + dup 7 d# 19 bits swap ( rc.wimg.pp phys api vsid tags ) + 6 1 bits ( rc.wimg.pp phys api vsid h ) + then + true +; +headers +: pte@ ( adr -- phys-stuff tag ) + dup /htab-entry 2/ + htab-@ swap htab-@ +; +headerless +: hold. ( -- ) ascii . hold ; +: .mode ( mode -- ) + push-binary + ." RC.WIMG.PP: " <# u# u# hold. 2/ u# u# u# u# hold. u# u# u#> type + pop-base +; +: .phys ( phys -- ) push-hex ." Physical: " u. pop-base ; +: .pte ( tags phys-stuff -- ) + break-pte if + push-hex + ." H: " . + ." Virtual: " <# u# ascii , hold u#s u#> type ( rc.wimg.pp phys api ) + d# 20 >> (.2) type ." X.Xxxx" ( rc.wimg.pp phys ) + pop-base + ." " .phys .mode + else + ." Invalid" + then + cr +; + +\ See, for example, figure 7-24 in the 603 manual +\ >vsid is valid on 64-bit implementations only if the implementation +\ also supports mtsr and mfsr, as does the 620. +: >vsid ( virtual -- sr ) + d# 28 4 bits sr@ mmu64? if d# 24 lowbits then +; +: virtual>hash ( virtual -- tag hash ) + dup + mmu64? if + d# 23 5 ( virtual bit# #bits ) + else + d# 22 6 ( virtual bit# #bits ) + then + bits ( virtual api ) + mmu64? if 7 lshift then ( virtual api' ) + over >vsid tuck ( virtual vsid api vsid ) + mmu64? if d# 12 else 7 then ( virtual vsid api vsid bit# ) + lshift or tag-v or ( virtual vsid tag ) + rot d# 12 d# 16 bits ( vsid tag page-index ) + rot ( tag page-index vsid ) + \ 39 or 19 bit hash codes + mmu64? 0= if h# 7ffff and then ( tag page-index vsid' ) + xor ( tag hash ) +; +: hash>ptegs ( hash -- 'pteg1 'pteg2 ) + /htab-group * ( hash<< ) + get-htab 1- ( hash<< base size-mask ) + /htab-group 1- invert and ( hash<< base size-mask' ) + + rot over and ( base size-mask masked-hash ) + rot or tuck xor ( 'pteg1 'pteg2 ) +; +: virtual>pteg ( virtual -- tag 'pteg1 'pteg2 ) virtual>hash hash>ptegs ; + +: virtual>pte ( virtual -- false | pte-adr true ) + virtual>pteg -rot ( 'pteg2 tag 'pteg1 ) + /htab-group bounds do ( 'pteg2 tag ) + dup i htab-@ = if ( 'pteg2 tag ) + 2drop i true unloop exit + then ( 'pteg2 tag ) + /htab-entry +loop ( 'pteg2 tag ) + tag-h or swap ( tag' pteg2 ) + /htab-group bounds do ( tag ) + dup i htab-@ = if ( tag ) + drop i true unloop exit + then ( tag ) + /htab-entry +loop ( tag ) + drop false +; +: .pteg ( 'pteg -- ) d# 64 bounds ?do i pte@ .pte 8 +loop ; +headers +: pteg? ( virtual -- ) + virtual>pteg ( tag 'pteg1 'pteg2 ) + swap ." Primary PTEG" cr .pteg ( tag 'pgeg2 ) + ." Secondary PTEG" cr .pteg ( tag ) + drop +; +: pte? ( virtual -- ) + virtual>pte if pte@ .pte else ." Not in HTAB" cr then +; + +headerless +: (shootdown-range) ( virtual len -- ) + \ If we have to shootdown more than about 8 pages, + \ it's faster to blow away the whole thing; searching + \ for matching PTEs is pretty time-consuming. + dup h# 8000 u> if ( virtual len ) + 2drop + mmu64? if invalidate-htab-64 else invalidate-htab-32 then + invalidate-tlb ( ) + exit + then ( virtual len ) + bounds ?do ( ) + i virtual>pte if 0 swap htab-! i invalidate-tlb-entry then + pagesize +loop +; +' (shootdown-range) to shootdown-range + +: (map-mode) ( phys.. mode -- mode' ) + >r memory? r> ( memory? mode ) + dup -2 -1 between if ( memory? -1 ) + drop if ( ) + h# 12 \ For memory, WIMG.x.PP is 0010.0.10, i.e. M=1, PP=10 + else ( ) + h# 3a \ For I/O, WIMG.x.PP is 0111.0.10, i.e. I=1,M=1,G=1, PP=10 + then ( mode' ) + else ( memory? mode ) + nip ( mode ) + then ( mode' ) +; +' (map-mode) to map-mode + +headers +[ifdef] NOTYET +\ : init ( -- ) ; + +\ finish-device + +warning @ warning off +only forth also definitions +: stand-init ( -- ) + stand-init + " /mmu" open-dev mmu-node ! +; +warning ! +[then] + +: map? ( virtual -- ) +[ifdef] NOTYET + " translate" mmu-node @ $call-method if +[else] + translate if +[then] + >r .phys r> .mode + else + ." Not mapped" cr + then +; +[then] + +\ 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/ppc/inflate.fth =================================================================== --- cpu/ppc/inflate.fth (rev 0) +++ cpu/ppc/inflate.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,1396 @@ +purpose: Inflater - source code in Forth-assembler format +\ See license at end of file + +\ The following code uses only non-privileged instructions, and knows +\ nothing about the "operating environment" portion of the PowerPC +\ architecture. Please keep it that way! +\ For use in the firmware environment, this code is typically called +\ from a routine that handles operating-environment details, such as +\ setting up memory mappings, turning on caches, etc. + +\ The body of the code below was created by disassembling the stripped +\ output of GCC. The script that runs the disassembler is in +\ cpu/ppc/disinflt.fth + +fload ${BP}/cpu/ppc/asmtools.fth + +: number, ( -- ) + safe-parse-word ( adr len ) + push-hex $number abort" Invalid argument to debug:" pop-base ( n ) + be-l, +; +: debug: + 0 be-l, number, number, number, number, + safe-parse-word dup wbsplit c, c, ( adr len ) + here over allot ( adr len here ) + swap move align + postpone \ +; + +start-assembling + +\ The following routines use Power/Open C calling conventions: +\ e.g. arguments in r3, r4, ... +\ r1 must point to a stack area. r2 is ostensibly the TOC pointer, +\ but the C code and compilation flags were carefully set up so that +\ the generated code does not use a data segment or external linkage, +\ so there are no references to r2 in the code below. + +label inflate ( r3: &compressed-image r4: &destination r5: &scratch -- ... ) + ( ... -- r3: length-of-uncompressed-image ) + mfspr r0,lr + stw r21,h#-2c(r1) + stw r22,h#-28(r1) + stw r23,h#-24(r1) + stw r24,h#-20(r1) + stw r25,h#-1c(r1) + stw r26,h#-18(r1) + stw r27,h#-14(r1) + stw r28,h#-10(r1) + stw r29,h#-c(r1) + stw r30,-8(r1) + stw r31,-4(r1) + stw r0,8(r1) + stwu r1,h#-568(r1) + or r21,r4,r4 + or r27,r21,r21 + or r30,r5,r5 + addi r0,r30,h#80 + stw r0,h#7c(r30) + or r4,r30,r30 + bl .+h#46c + addi r0,r0,0 + addic r0,r0,1 + lwz r11,8(r30) + cmpi crf1,0,r0,2 + addi r9,r11,1 + stw r9,8(r30) + bc 4,5,.-h#14 + addi r0,r9,1 + stw r0,8(r30) + addi r0,r0,0 + lbz r10,1(r11) + addic r0,r0,1 + lwz r11,8(r30) + cmpi crf1,0,r0,5 + addi r9,r11,1 + stw r9,8(r30) + bc 4,5,.-h#14 + andi. r0,r10,8 + bc 12,2,.+h#30 + addi r0,r9,1 + stw r0,8(r30) + lbz r0,1(r11) + cmpi crf1,0,r0,0 + bc 12,6,.+h#1c + lwz r9,8(r30) + addi r0,r9,1 + stw r0,8(r30) + lbz r0,0(r9) + cmpi crf1,0,r0,0 + bc 4,6,.-h#14 + addi r26,r0,1 + addi r3,r0,1 + lwz r4,0(r30) + or r5,r30,r30 + bl .+h#7a0 + or r4,r3,r3 + rlwinm r25,r4,0,31,31 + addi r3,r0,2 + rlwinm r4,r4,31,1,31 + lwz r0,4(r30) + or r5,r30,r30 + addic r0,r0,-1 + stw r0,4(r30) + bl .+h#77c + or r4,r3,r3 + rlwinm r9,r4,0,30,31 + rlwinm r4,r4,30,2,31 + cmpi crf1,0,r9,0 + lwz r0,4(r30) + stw r4,0(r30) + addic r0,r0,-2 + stw r0,4(r30) + bc 4,6,.+h#b8 + addi r3,r0,h#10 + lwz r0,4(r30) + or r5,r30,r30 + rlwinm r31,r0,0,29,31 + subf r0,r31,r0 + stw r0,4(r30) + srw r4,r4,r31 + bl .+h#738 + or r4,r3,r3 + rlwinm r31,r4,0,16,31 + addi r3,r0,h#10 + rlwinm r4,r4,16,16,31 + lwz r0,4(r30) + or r5,r30,r30 + addic r0,r0,h#-10 + stw r0,4(r30) + bl .+h#714 + or r4,r3,r3 + nor r0,r4,r4 + rlwinm r9,r0,0,16,31 + cmp crf1,0,r31,r9 + bc 4,6,.+h#bc + rlwinm r4,r4,16,16,31 + lwz r0,4(r30) + cmpi crf1,0,r9,0 + addi r31,r31,-1 + addic r0,r0,h#-10 + stw r0,4(r30) + bc 12,6,.+h#3c + addi r3,r0,8 + or r5,r30,r30 + bl .+h#6d8 + or r4,r3,r3 + stb r4,0(r27) + addi r27,r27,1 + rlwinm r4,r4,24,8,31 + or r9,r31,r31 + lwz r0,4(r30) + cmpi crf1,0,r9,0 + addi r31,r31,-1 + addic r0,r0,-8 + stw r0,4(r30) + bc 4,6,.-h#34 + stw r4,0(r30) + b .+h#27c + cmpi crf1,0,r9,1 + bc 4,6,.+h#30 + or r3,r22,r22 + addi r4,r1,h#528 + addi r5,r1,h#52c + addi r6,r1,h#530 + addi r7,r1,h#534 + addi r8,r1,h#38 + or r9,r30,r30 + bl .+h#d20 + cmpi crf1,0,r3,0 + bc 4,6,.+h#30 + b .+h#34 + or r3,r22,r22 + addi r4,r1,h#528 + addi r5,r1,h#52c + addi r6,r1,h#530 + addi r7,r1,h#534 + addi r8,r1,h#38 + or r9,r30,r30 + bl .+h#e54 + cmpi crf1,0,r3,0 + bc 12,6,.+h#c + addi r25,r0,1 + b .+h#218 + lwz r9,h#530(r1) + lwz r10,0(r30) + lwz r0,h#534(r1) + slw r9,r26,r9 + addi r23,r9,-1 + slw r0,r26,r0 + addic r24,r0,-1 + or r4,r10,r10 + lwz r3,h#530(r1) + or r5,r30,r30 + bl .+h#614 + or r10,r3,r3 + and r9,r10,r23 + lwz r11,h#528(r1) + rlwinm r9,r9,3,0,28 + lbzx r31,r9,r11 + cmpli crf1,0,r31,h#10 + add r29,r9,r11 + bc 4,5,.+h#58 + cmpi crf1,0,r31,h#63 + bc 12,6,.+h#1c4 + addi r31,r31,h#-10 + or r3,r31,r31 + lbz r4,1(r29) + lwz r0,4(r30) + or r5,r30,r30 + subf r0,r4,r0 + stw r0,4(r30) + srw r4,r10,r4 + bl .+h#5c8 + or r10,r3,r3 + slw r9,r26,r31 + addi r9,r9,-1 + and r9,r10,r9 + lwz r11,4(r29) + rlwinm r9,r9,3,0,28 + lbzx r31,r9,r11 + cmpli crf1,0,r31,h#10 + add r29,r9,r11 + bc 12,5,.-h#50 + cmpi crf1,0,r31,h#10 + lbz r9,1(r29) + lwz r0,4(r30) + srw r10,r10,r9 + subf r0,r9,r0 + stw r0,4(r30) + bc 4,6,.+h#14 + lhz r0,2(r29) + stb r0,0(r27) + addi r27,r27,1 + b .-h#ac + cmpi crf1,0,r31,h#f + bc 12,6,.+h#138 + or r3,r31,r31 + or r4,r10,r10 + or r5,r30,r30 + bl .+h#55c + or r10,r3,r3 + srw r4,r10,r31 + or r5,r30,r30 + slw r0,r26,r31 + addic r0,r0,-1 + and r0,r10,r0 + lwz r3,h#534(r1) + lhz r11,2(r29) + lwz r9,4(r30) + add r28,r11,r0 + subf r9,r31,r9 + stw r9,4(r30) + bl .+h#528 + or r10,r3,r3 + and r9,r10,r24 + lwz r11,h#52c(r1) + rlwinm r9,r9,3,0,28 + lbzx r31,r9,r11 + cmpli crf1,0,r31,h#10 + add r29,r9,r11 + bc 4,5,.+h#58 + cmpi crf1,0,r31,h#63 + bc 12,6,.+h#d8 + addi r31,r31,h#-10 + or r3,r31,r31 + lbz r4,1(r29) + lwz r0,4(r30) + or r5,r30,r30 + subf r0,r4,r0 + stw r0,4(r30) + srw r4,r10,r4 + bl .+h#4dc + or r10,r3,r3 + slw r9,r26,r31 + addi r9,r9,-1 + and r9,r10,r9 + lwz r11,4(r29) + rlwinm r9,r9,3,0,28 + lbzx r31,r9,r11 + cmpli crf1,0,r31,h#10 + add r29,r9,r11 + bc 12,5,.-h#50 + or r3,r31,r31 + lbz r4,1(r29) + lwz r0,4(r30) + or r5,r30,r30 + subf r0,r4,r0 + stw r0,4(r30) + srw r4,r10,r4 + bl .+h#494 + or r10,r3,r3 + slw r9,r26,r31 + addi r9,r9,-1 + and r9,r10,r9 + srw r10,r10,r31 + or r11,r28,r28 + addi r28,r28,-1 + cmpi crf1,0,r11,0 + lwz r0,4(r30) + lhz r11,2(r29) + subf r0,r31,r0 + stw r0,4(r30) + add r11,r11,r9 + bc 12,6,.-h#1c4 + subf r9,r11,r27 + or r0,r28,r28 + lbz r9,0(r9) + cmpi crf1,0,r0,0 + addi r28,r28,-1 + stb r9,0(r27) + addi r27,r27,1 + bc 4,6,.-h#1c + b .-h#1e8 + lwz r0,h#20(r30) + stw r10,0(r30) + stw r0,h#7c(r30) + cmpi crf1,0,r25,0 + bc 12,6,.-h#388 + subf r3,r21,r27 + addi r1,r1,h#568 + lwz r0,8(r1) + mtspr lr,r0 + lwz r21,h#-2c(r1) + lwz r22,h#-28(r1) + lwz r23,h#-24(r1) + lwz r24,h#-20(r1) + lwz r25,h#-1c(r1) + lwz r26,h#-18(r1) + lwz r27,h#-14(r1) + lwz r28,h#-10(r1) + lwz r29,h#-c(r1) + lwz r30,-8(r1) + lwz r31,-4(r1) + bclr 20,0 + + Debug: 2041 800b0300 0 49c inflate + + addi r11,r0,0 + stw r11,0(r4) + stw r11,4(r4) + stw r3,8(r4) + addi r8,r0,0 + addi r10,r0,3 + lwz r9,h#7c(r4) + lwz r0,h#7c(r4) + stw r9,h#c(r4) + addic r0,r0,h#4c + stw r0,h#7c(r4) + lwz r9,h#c(r4) + addi r0,r0,h#10 + stw r0,0(r9) + addi r0,r0,h#11 + stwu r0,4(r9) + addi r0,r0,h#12 + stwu r0,4(r9) + stwu r11,4(r9) + addi r0,r0,8 + stwu r0,4(r9) + addi r0,r0,7 + stwu r0,4(r9) + addi r0,r0,9 + stwu r0,4(r9) + addi r0,r0,6 + stwu r0,4(r9) + addi r0,r0,h#a + stwu r0,4(r9) + addi r0,r0,5 + stwu r0,4(r9) + addi r0,r0,h#b + stwu r0,4(r9) + addi r0,r0,4 + stwu r0,4(r9) + addi r0,r0,h#c + stwu r0,4(r9) + addi r0,r0,3 + stwu r0,4(r9) + addi r0,r0,h#d + stwu r0,4(r9) + addi r0,r0,2 + stwu r0,4(r9) + addi r0,r0,h#e + stwu r0,4(r9) + addi r0,r0,1 + stwu r0,4(r9) + addi r0,r0,h#f + stw r0,4(r9) + lwz r9,h#7c(r4) + lwz r0,h#7c(r4) + stw r9,h#10(r4) + addic r0,r0,h#40 + stw r0,h#7c(r4) + lwz r9,h#10(r4) + addi r0,r0,3 + sth r0,0(r9) + addi r0,r0,4 + sthu r0,2(r9) + addi r0,r0,5 + sthu r0,2(r9) + addi r0,r0,6 + sthu r0,2(r9) + addi r0,r0,7 + sthu r0,2(r9) + addi r0,r0,8 + sthu r0,2(r9) + addi r0,r0,9 + sthu r0,2(r9) + addi r0,r0,h#a + sthu r0,2(r9) + addi r0,r0,h#b + sthu r0,2(r9) + addi r0,r0,h#d + sthu r0,2(r9) + addi r0,r0,h#f + sthu r0,2(r9) + addi r0,r0,h#11 + sthu r0,2(r9) + addi r0,r0,h#13 + sthu r0,2(r9) + addi r0,r0,h#17 + sthu r0,2(r9) + addi r0,r0,h#1b + sthu r0,2(r9) + addi r0,r0,h#1f + sthu r0,2(r9) + addi r0,r0,h#23 + sthu r0,2(r9) + addi r0,r0,h#2b + sthu r0,2(r9) + addi r0,r0,h#33 + sthu r0,2(r9) + addi r0,r0,h#3b + sthu r0,2(r9) + addi r0,r0,h#43 + sthu r0,2(r9) + addi r0,r0,h#53 + sthu r0,2(r9) + addi r0,r0,h#63 + sthu r0,2(r9) + addi r0,r0,h#73 + sthu r0,2(r9) + addi r0,r0,h#83 + sthu r0,2(r9) + addi r0,r0,h#a3 + sthu r0,2(r9) + addi r0,r0,h#c3 + sthu r0,2(r9) + addi r0,r0,h#e3 + sthu r0,2(r9) + addi r0,r0,h#102 + sthu r0,2(r9) + addi r0,r0,0 + sthu r0,2(r9) + addi r9,r9,2 + sth r0,0(r9) + lwz r9,h#7c(r4) + lwz r0,h#7c(r4) + stw r9,h#14(r4) + addic r0,r0,h#40 + stw r0,h#7c(r4) + lwz r9,h#14(r4) + addic. r10,r10,-1 + sth r8,0(r9) + addi r9,r9,2 + bc 4,0,.-h#c + addi r10,r0,4 + addi r0,r10,-1 + srawi r0,r0,2 + addze r0,r0 + sth r0,0(r9) + sthu r0,2(r9) + addi r10,r10,4 + cmpi crf1,0,r10,h#1b + sthu r0,2(r9) + sthu r0,2(r9) + addi r9,r9,2 + bc 4,5,.-h#28 + addi r11,r0,0 + sth r11,0(r9) + addi r0,r0,h#63 + sthu r0,2(r9) + sth r0,2(r9) + lwz r9,h#7c(r4) + lwz r0,h#7c(r4) + stw r9,h#18(r4) + addic r0,r0,h#40 + stw r0,h#7c(r4) + lwz r9,h#18(r4) + addi r0,r0,1 + sth r0,0(r9) + addi r0,r0,2 + sthu r0,2(r9) + addi r0,r0,3 + sthu r0,2(r9) + addi r0,r0,4 + sthu r0,2(r9) + addi r0,r0,5 + sthu r0,2(r9) + addi r0,r0,7 + sthu r0,2(r9) + addi r0,r0,9 + sthu r0,2(r9) + addi r0,r0,h#d + sthu r0,2(r9) + addi r0,r0,h#11 + sthu r0,2(r9) + addi r0,r0,h#19 + sthu r0,2(r9) + addi r0,r0,h#21 + sthu r0,2(r9) + addi r0,r0,h#31 + sthu r0,2(r9) + addi r0,r0,h#41 + sthu r0,2(r9) + addi r0,r0,h#61 + sthu r0,2(r9) + addi r0,r0,h#81 + sthu r0,2(r9) + addi r0,r0,h#c1 + sthu r0,2(r9) + addi r0,r0,h#101 + sthu r0,2(r9) + addi r0,r0,h#181 + sthu r0,2(r9) + addi r0,r0,h#201 + sthu r0,2(r9) + addi r0,r0,h#301 + sthu r0,2(r9) + addi r0,r0,h#401 + sthu r0,2(r9) + addi r0,r0,h#601 + sthu r0,2(r9) + addi r0,r0,h#801 + sthu r0,2(r9) + addi r0,r0,h#c01 + sthu r0,2(r9) + addi r0,r0,h#1001 + sthu r0,2(r9) + addi r0,r0,h#1801 + sthu r0,2(r9) + addi r0,r0,h#2001 + sthu r0,2(r9) + addi r0,r0,h#3001 + sthu r0,2(r9) + addi r0,r0,h#4001 + sthu r0,2(r9) + addi r0,r0,h#6001 + sth r0,2(r9) + lwz r0,h#7c(r4) + addi r10,r0,2 + stw r0,h#1c(r4) + lwz r0,h#7c(r4) + lwz r9,h#1c(r4) + addic r0,r0,h#40 + stw r0,h#7c(r4) + sth r11,0(r9) + sthu r11,2(r9) + addi r9,r9,2 + addi r0,r10,-1 + srawi r0,r0,1 + addze r0,r0 + addi r10,r10,2 + cmpi crf1,0,r10,h#1d + sth r0,0(r9) + sthu r0,2(r9) + addi r9,r9,2 + bc 4,5,.-h#20 + lwz r0,h#7c(r4) + stw r0,h#20(r4) + bclr 20,0 + + Debug: 2040 200 0 3a0 init_var + + lwz r0,4(r5) + or r8,r3,r3 + cmpl crf1,0,r0,r8 + or r3,r4,r4 + bclr 4,4 + lwz r11,8(r5) + lwz r10,4(r5) + addi r0,r11,1 + stw r0,8(r5) + addi r9,r10,8 + cmpl crf1,0,r9,r8 + lbz r0,0(r11) + stw r9,4(r5) + slw r0,r0,r10 + or r3,r3,r0 + bc 12,4,.-h#28 + bclr 20,0 + + Debug: 2040 300 0 44 NEEDBITS + + cmpi crf1,0,r5,0 + addi r5,r5,-1 + bclr 12,6 + lbz r0,0(r4) + addi r4,r4,1 + cmpi crf1,0,r5,0 + addi r5,r5,-1 + stb r0,0(r3) + addi r3,r3,1 + bc 4,6,.-h#18 + bclr 20,0 + + Debug: 2040 300 0 2c memcpy + + mfspr r0,lr + stw r13,h#-4c(r1) + stw r14,h#-48(r1) + stw r15,h#-44(r1) + stw r16,h#-40(r1) + stw r17,h#-3c(r1) + stw r18,h#-38(r1) + stw r19,h#-34(r1) + stw r20,h#-30(r1) + stw r21,h#-2c(r1) + stw r22,h#-28(r1) + stw r23,h#-24(r1) + stw r24,h#-20(r1) + stw r25,h#-1c(r1) + stw r26,h#-18(r1) + stw r27,h#-14(r1) + stw r28,h#-10(r1) + stw r29,h#-c(r1) + stw r30,-8(r1) + stw r31,-4(r1) + stw r0,8(r1) + stwu r1,h#-5f8(r1) + stw r4,h#588(r1) + or r13,r5,r5 + stw r6,h#58c(r1) + stw r7,h#590(r1) + or r7,r8,r8 + or r8,r9,r9 + or r6,r10,r10 + addi r9,r1,h#38 + addi r11,r0,0 + addi r0,r0,0 + stwx r11,r9,r0 + addic r0,r0,4 + cmpli crf1,0,r0,h#40 + bc 4,5,.-h#c + or r24,r3,r3 + addi r11,r1,h#38 + lwz r28,h#588(r1) + lwz r9,0(r24) + rlwinm r9,r9,2,0,29 + lwzx r0,r9,r11 + addi r24,r24,4 + addic r0,r0,1 + stwx r0,r9,r11 + addic. r28,r28,-1 + bc 12,2,.+h#8 + b .-h#20 + lwz r0,h#38(r1) + lwz r12,h#588(r1) + cmp crf1,0,r0,r12 + bc 4,6,.+h#14 + stw r28,0(r7) + stw r28,0(r8) + addi r3,r0,0 + b .+h#4a0 + addi r30,r0,1 + addi r11,r1,h#38 + addi r9,r0,4 + lwz r22,0(r8) + lwzx r0,r9,r11 + cmpi crf1,0,r0,0 + bc 4,6,.+h#14 + addi r30,r30,1 + cmpli crf1,0,r30,h#10 + addi r9,r9,4 + bc 4,5,.-h#18 + or r19,r30,r30 + subfc r9,r19,r22 + subfe r9,r9,r9 + nand r9,r9,r9 + nor r0,r9,r9 + and r0,r0,r19 + and r9,r22,r9 + or r22,r9,r0 + addi r28,r0,h#10 + addi r11,r1,h#38 + addi r9,r0,h#40 + lwzx r0,r9,r11 + cmpi crf1,0,r0,0 + bc 4,6,.+h#14 + addi r9,r9,-4 + addic. r28,r28,-1 + bc 12,2,.+h#8 + b .-h#18 + or r14,r28,r28 + subfc r9,r22,r14 + subfe r9,r9,r9 + nand r9,r9,r9 + nor r0,r9,r9 + and r0,r0,r14 + and r9,r22,r9 + or r22,r9,r0 + cmpl crf1,0,r30,r14 + stw r22,0(r8) + addi r0,r0,1 + slw r18,r0,r30 + bc 4,4,.+h#2c + addi r11,r1,h#38 + rlwinm r9,r30,2,0,29 + lwzx r0,r9,r11 + subf. r18,r0,r18 + bc 12,0,.+h#2c + addi r30,r30,1 + cmpl crf1,0,r30,r28 + addi r9,r9,4 + rlwinm r18,r18,1,0,30 + bc 12,4,.-h#1c + rlwinm r11,r28,2,0,29 + addi r9,r1,h#38 + lwzx r0,r11,r9 + subf. r18,r0,r18 + bc 4,0,.+h#c + addi r3,r0,2 + b .+h#3b4 + add r0,r18,r0 + stwx r0,r11,r9 + addi r30,r0,0 + stw r30,h#548(r1) + addi r24,r1,h#3c + addi r9,r1,h#54c + addic. r28,r28,-1 + bc 4,2,.+h#8 + b .+h#24 + lwz r0,0(r24) + addi r24,r24,4 + add r30,r30,r0 + stw r30,0(r9) + addi r9,r9,4 + addic. r28,r28,-1 + bc 12,2,.+h#8 + b .-h#1c + or r24,r3,r3 + addi r28,r0,0 + addi r10,r1,h#38 + lwz r30,0(r24) + cmpi crf1,0,r30,0 + addi r24,r24,4 + bc 12,6,.+h#24 + rlwinm r9,r30,2,0,29 + add r9,r9,r10 + lwz r11,h#50c(r9) + addi r0,r11,1 + stw r0,h#50c(r9) + rlwinm r11,r11,2,0,29 + add r11,r11,r10 + stw r28,h#8c(r11) + lwz r12,h#588(r1) + addi r28,r28,1 + cmpl crf1,0,r28,r12 + bc 12,4,.-h#3c + addi r28,r0,0 + stw r28,h#544(r1) + addi r24,r1,h#c4 + addi r20,r0,-1 + neg r27,r22 + cmp crf1,0,r19,r14 + stw r28,h#84(r1) + addi r26,r0,0 + addi r25,r0,0 + bc 12,5,.+h#2c0 + addi r17,r1,h#38 + addi r16,r0,1 + addi r12,r1,h#80 + stw r12,h#598(r1) + rlwinm r15,r19,2,0,29 + lwzx r21,r15,r17 + or r0,r21,r21 + cmpi crf1,0,r0,0 + addi r21,r21,-1 + bc 12,6,.+h#288 + stw r15,h#594(r1) + add r9,r27,r22 + cmp crf1,0,r19,r9 + bc 4,5,.+h#120 + rlwinm r0,r20,2,0,29 + add r29,r0,r17 + or r23,r0,r0 + addi r29,r29,4 + addi r23,r23,4 + addi r20,r20,1 + or r27,r9,r9 + subf r25,r27,r14 + subfc r9,r25,r22 + subfe r9,r9,r9 + nand r9,r9,r9 + nor r11,r9,r9 + subf r30,r27,r19 + slw r31,r16,r30 + addi r0,r21,1 + cmpl crf1,0,r31,r0 + and r11,r11,r22 + and r9,r25,r9 + or r25,r9,r11 + bc 4,5,.+h#40 + addi r30,r30,1 + addi r0,r31,-1 + cmpl crf1,0,r30,r25 + lwz r12,h#594(r1) + subf r31,r21,r0 + add r9,r17,r12 + bc 4,4,.+h#24 + lwzu r0,4(r9) + rlwinm r31,r31,1,0,30 + cmpl crf1,0,r31,r0 + bc 4,5,.+h#14 + addi r30,r30,1 + cmpl crf1,0,r30,r25 + subf r31,r0,r31 + bc 12,4,.-h#1c + slw r25,r16,r30 + addi r0,r25,1 + rlwinm r0,r0,3,0,28 + lwz r26,h#7c(r6) + cmpi crf1,0,r20,0 + add r0,r0,r26 + stw r0,h#7c(r6) + addi r9,r26,8 + stw r9,0(r7) + addi r7,r26,4 + addi r0,r0,0 + stw r0,4(r26) + or r26,r9,r9 + stw r26,h#4c(r29) + bc 12,6,.+h#4c + stw r28,h#50c(r29) + stb r22,h#7d(r1) + addi r0,r30,h#10 + stb r0,h#7c(r1) + stw r26,h#80(r1) + subf r0,r22,r27 + srw r30,r28,r0 + addi r4,r1,h#7c + addi r5,r0,8 + lwz r12,h#598(r1) + rlwinm r3,r30,3,0,28 + lwzx r0,r23,r12 + stw r6,h#59c(r1) + stw r7,h#5a0(r1) + add r3,r3,r0 + bl .-h#408 + lwz r6,h#59c(r1) + lwz r7,h#5a0(r1) + add r9,r27,r22 + cmp crf1,0,r19,r9 + bc 12,5,.-h#10c + lwz r12,h#588(r1) + addi r0,r1,h#c4 + rlwinm r9,r12,2,0,29 + add r0,r0,r9 + cmpl crf1,0,r24,r0 + subf r0,r27,r19 + stb r0,h#7d(r1) + bc 12,4,.+h#10 + addi r0,r0,h#63 + stb r0,h#7c(r1) + b .+h#64 + lwz r0,0(r24) + cmpl crf1,0,r0,r13 + bc 4,4,.+h#28 + subfic r0,r0,h#ff + subfe r0,r0,r0 + rlwinm r9,r0,0,28,31 + nor r0,r0,r0 + rlwinm r0,r0,0,27,27 + or r9,r9,r0 + stb r9,h#7c(r1) + lwz r0,0(r24) + b .+h#2c + subf r0,r13,r0 + lwz r12,h#590(r1) + rlwinm r0,r0,1,0,30 + lhzx r0,r12,r0 + stb r0,h#7c(r1) + lwz r0,0(r24) + lwz r12,h#58c(r1) + subf r0,r13,r0 + rlwinm r0,r0,1,0,30 + lhzx r0,r12,r0 + addi r24,r24,4 + sth r0,h#7e(r1) + srw r30,r28,r27 + cmpl crf1,0,r30,r25 + subf r0,r27,r19 + slw r31,r16,r0 + bc 4,4,.+h#40 + rlwinm r0,r30,3,0,28 + add r29,r0,r26 + or r3,r29,r29 + addi r4,r1,h#7c + addi r5,r0,8 + stw r6,h#59c(r1) + stw r7,h#5a0(r1) + bl .-h#4dc + add r30,r30,r31 + cmpl crf1,0,r30,r25 + rlwinm r0,r31,3,0,28 + add r29,r29,r0 + lwz r6,h#59c(r1) + lwz r7,h#5a0(r1) + bc 12,4,.-h#30 + addi r0,r19,-1 + slw r30,r16,r0 + and. r0,r28,r30 + bc 12,2,.+h#14 + xor r28,r28,r30 + rlwinm r30,r30,31,1,31 + and. r0,r28,r30 + bc 4,2,.-h#c + xor r28,r28,r30 + slw r0,r16,r27 + addic r0,r0,-1 + rlwinm r9,r20,2,0,29 + add r11,r9,r17 + lwz r9,h#50c(r11) + and r0,r28,r0 + cmp crf1,0,r0,r9 + bc 12,6,.+h#2c + addi r10,r0,1 + addi r11,r11,-4 + subf r27,r22,r27 + slw r0,r10,r27 + addic r0,r0,-1 + lwz r9,h#50c(r11) + and r0,r28,r0 + cmp crf1,0,r0,r9 + addi r20,r20,-1 + bc 4,6,.-h#20 + or r0,r21,r21 + cmpi crf1,0,r0,0 + addi r21,r21,-1 + bc 4,6,.-h#27c + addi r19,r19,1 + cmp crf1,0,r19,r14 + addi r15,r15,4 + bc 4,5,.-h#2a4 + neg r0,r18 + and r0,r0,r18 + cntlzw r0,r0 + subfic r0,r0,h#20 + neg r0,r0 + rlwinm r0,r0,1,31,31 + xori r3,r14,1 + neg r12,r3 + and r12,r12,r3 + cntlzw r12,r12 + subfic r12,r12,h#20 + or r3,r12,r12 + neg r3,r3 + rlwinm r3,r3,1,31,31 + and r3,r0,r3 + addi r1,r1,h#5f8 + lwz r0,8(r1) + mtspr lr,r0 + lwz r13,h#-4c(r1) + lwz r14,h#-48(r1) + lwz r15,h#-44(r1) + lwz r16,h#-40(r1) + lwz r17,h#-3c(r1) + lwz r18,h#-38(r1) + lwz r19,h#-34(r1) + lwz r20,h#-30(r1) + lwz r21,h#-2c(r1) + lwz r22,h#-28(r1) + lwz r23,h#-24(r1) + lwz r24,h#-20(r1) + lwz r25,h#-1c(r1) + lwz r26,h#-18(r1) + lwz r27,h#-14(r1) + lwz r28,h#-10(r1) + lwz r29,h#-c(r1) + lwz r30,-8(r1) + lwz r31,-4(r1) + bclr 20,0 + + Debug: 2041 80130800 0 5d8 huft_build + + mfspr r0,lr + stw r28,h#-10(r1) + stw r29,h#-c(r1) + stw r30,-8(r1) + stw r31,-4(r1) + stw r0,8(r1) + stwu r1,h#-48(r1) + or r11,r4,r4 + or r28,r5,r5 + or r29,r7,r7 + or r31,r8,r8 + or r30,r9,r9 + addi r9,r0,8 + addi r0,r0,h#23c + stwx r9,r31,r0 + addic. r0,r0,-4 + bc 4,0,.-h#8 + addi r3,r0,h#90 + addi r9,r0,9 + addi r0,r0,h#240 + addi r3,r3,1 + cmpi crf1,0,r3,h#ff + stwx r9,r31,r0 + addic r0,r0,4 + bc 4,5,.-h#10 + cmpi crf1,0,r3,h#117 + bc 12,5,.+h#20 + addi r9,r0,7 + rlwinm r0,r3,2,0,29 + addi r3,r3,1 + cmpi crf1,0,r3,h#117 + stwx r9,r31,r0 + addic r0,r0,4 + bc 4,5,.-h#10 + cmpi crf1,0,r3,h#11f + bc 12,5,.+h#1c + addi r0,r0,8 + rlwinm r3,r3,2,0,29 + stwx r0,r3,r31 + addi r3,r3,4 + cmpi crf1,0,r3,h#47c + bc 4,5,.-h#c + addi r0,r0,7 + stw r0,0(r6) + or r3,r31,r31 + addi r4,r0,h#120 + addi r5,r0,h#101 + or r8,r11,r11 + or r9,r6,r6 + lwz r6,h#10(r30) + lwz r7,h#14(r30) + or r10,r30,r30 + bl .-h#6c8 + or. r3,r3,r3 + bc 4,2,.+h#48 + addi r9,r0,5 + addi r0,r0,0 + stwx r9,r31,r0 + addic r0,r0,4 + cmpi crf1,0,r0,h#74 + bc 4,5,.-h#c + addi r0,r0,5 + stw r0,0(r29) + or r3,r31,r31 + addi r4,r0,h#1e + addi r5,r0,0 + or r8,r28,r28 + or r9,r29,r29 + lwz r6,h#18(r30) + lwz r7,h#1c(r30) + or r10,r30,r30 + bl .-h#714 + addi r1,r1,h#48 + lwz r0,8(r1) + mtspr lr,r0 + lwz r28,h#-10(r1) + lwz r29,h#-c(r1) + lwz r30,-8(r1) + lwz r31,-4(r1) + bclr 20,0 + + Debug: 2041 80040700 0 140 huft_fixed + + mfspr r0,lr + stw r16,h#-40(r1) + stw r17,h#-3c(r1) + stw r18,h#-38(r1) + stw r19,h#-34(r1) + stw r20,h#-30(r1) + stw r21,h#-2c(r1) + stw r22,h#-28(r1) + stw r23,h#-24(r1) + stw r24,h#-20(r1) + stw r25,h#-1c(r1) + stw r26,h#-18(r1) + stw r27,h#-14(r1) + stw r28,h#-10(r1) + stw r29,h#-c(r1) + stw r30,-8(r1) + stw r31,-4(r1) + stw r0,8(r1) + stwu r1,h#-78(r1) + or r20,r4,r4 + or r21,r5,r5 + or r23,r6,r6 + or r16,r7,r7 + or r25,r8,r8 + or r28,r9,r9 + addi r3,r0,5 + lwz r4,0(r28) + or r5,r28,r28 + bl .-h#874 + or r30,r3,r3 + addi r3,r0,5 + rlwinm r4,r30,27,5,31 + lwz r0,4(r28) + or r5,r28,r28 + addic r0,r0,-5 + stw r0,4(r28) + rlwinm r0,r30,0,27,31 + addic r19,r0,h#101 + bl .-h#89c + or r30,r3,r3 + addi r3,r0,4 + rlwinm r4,r30,27,5,31 + lwz r0,4(r28) + or r5,r28,r28 + addic r0,r0,-5 + stw r0,4(r28) + rlwinm r0,r30,0,27,31 + addic r18,r0,1 + bl .-h#8c4 + or r30,r3,r3 + rlwinm r10,r30,0,28,31 + rlwinm r30,r30,28,4,31 + subfic r11,r19,h#11e + subfe r11,r11,r11 + neg r11,r11 + subfic r9,r18,h#1e + subfe r9,r9,r9 + neg r9,r9 + or. r8,r11,r9 + lwz r0,4(r28) + addi r29,r10,4 + addic r0,r0,-4 + stw r0,4(r28) + bc 4,2,.+h#2fc + addi r31,r0,0 + cmpl crf1,0,r31,r29 + bc 4,4,.+h#4c + addi r3,r0,3 + or r4,r30,r30 + or r5,r28,r28 + bl .-h#91c + or r30,r3,r3 + rlwinm r9,r31,2,0,29 + addi r31,r31,1 + lwz r11,h#c(r28) + rlwinm r0,r30,0,29,31 + lwzx r9,r9,r11 + cmpl crf1,0,r31,r29 + rlwinm r9,r9,2,0,29 + stwx r0,r9,r25 + lwz r0,4(r28) + rlwinm r30,r30,29,3,31 + addic r0,r0,-3 + stw r0,4(r28) + bc 12,4,.-h#44 + cmpli crf1,0,r31,h#12 + bc 12,5,.+h#28 + addi r10,r0,0 + rlwinm r11,r31,2,0,29 + addi r31,r31,1 + lwz r9,h#c(r28) + cmpli crf1,0,r31,h#12 + lwzx r0,r11,r9 + rlwinm r0,r0,2,0,29 + stwx r10,r25,r0 + bc 4,5,.-h#1c + addi r0,r0,7 + stw r0,0(r23) + or r3,r25,r25 + addi r4,r0,h#13 + addi r5,r0,h#13 + addi r6,r0,0 + addi r7,r0,0 + or r8,r20,r20 + or r9,r23,r23 + or r10,r28,r28 + bl .-h#900 + or. r29,r3,r3 + bc 12,2,.+h#c + cmpi crf1,0,r29,1 + bc 12,6,.+h#240 + addi r26,r0,0 + addi r29,r0,0 + add r24,r19,r18 + lwz r0,0(r23) + cmpl crf1,0,r29,r24 + addi r9,r0,1 + slw r9,r9,r0 + addi r17,r9,-1 + bc 4,4,.+h#1d4 + addi r22,r0,0 + addi r27,r0,0 + or r4,r30,r30 + lwz r3,0(r23) + or r5,r28,r28 + bl .-h#9f8 + or r30,r3,r3 + and r9,r30,r17 + lwz r0,0(r20) + rlwinm r9,r9,3,0,28 + add r9,r9,r0 + stw r9,0(r21) + lbz r31,1(r9) + lwz r0,4(r28) + subf r0,r31,r0 + stw r0,4(r28) + lwz r9,0(r21) + srw r30,r30,r31 + lhz r31,2(r9) + cmpli crf1,0,r31,h#f + bc 12,5,.+h#18 + or r26,r31,r31 + stwx r26,r27,r25 + addi r27,r27,4 + addi r29,r29,1 + b .+h#164 + cmpi crf1,0,r31,h#10 + bc 4,6,.+h#74 + addi r3,r0,2 + or r4,r30,r30 + or r5,r28,r28 + bl .-h#a60 + or r30,r3,r3 + rlwinm r11,r30,0,30,31 + addi r31,r11,3 + add r9,r29,r31 + lwz r0,4(r28) + cmpl crf1,0,r9,r24 + rlwinm r30,r30,30,2,31 + addic r0,r0,-2 + stw r0,4(r28) + bc 12,5,.+h#174 + or r0,r31,r31 + cmpi crf1,0,r0,0 + addi r31,r11,2 + bc 12,6,.+h#114 + rlwinm r9,r29,2,0,29 + stwx r26,r9,r25 + addi r9,r9,4 + or r0,r31,r31 + cmpi crf1,0,r0,0 + addi r27,r27,4 + addi r29,r29,1 + addi r31,r31,-1 + bc 4,6,.-h#1c + b .+h#ec + cmpi crf1,0,r31,h#11 + bc 4,6,.+h#74 + addi r3,r0,3 + or r4,r30,r30 + or r5,r28,r28 + bl .-h#ad8 + or r30,r3,r3 + rlwinm r11,r30,0,29,31 + addi r31,r11,3 + add r9,r29,r31 + lwz r0,4(r28) + cmpl crf1,0,r9,r24 + rlwinm r30,r30,29,3,31 + addic r0,r0,-3 + stw r0,4(r28) + bc 12,5,.+h#fc + or r0,r31,r31 + cmpi crf1,0,r0,0 + addi r31,r11,2 + bc 12,6,.+h#98 + rlwinm r9,r29,2,0,29 + stwx r22,r9,r25 + addi r9,r9,4 + or r0,r31,r31 + cmpi crf1,0,r0,0 + addi r27,r27,4 + addi r29,r29,1 + addi r31,r31,-1 + bc 4,6,.-h#1c + b .+h#70 + addi r3,r0,7 + or r4,r30,r30 + or r5,r28,r28 + bl .-h#b48 + or r30,r3,r3 + rlwinm r11,r30,0,25,31 + addi r31,r11,h#b + add r9,r29,r31 + lwz r0,4(r28) + cmpl crf1,0,r9,r24 + rlwinm r30,r30,25,7,31 + addic r0,r0,-7 + stw r0,4(r28) + bc 12,5,.+h#8c + or r0,r31,r31 + cmpi crf1,0,r0,0 + addi r31,r11,h#a + bc 12,6,.+h#28 + rlwinm r9,r29,2,0,29 + stwx r22,r9,r25 + addi r9,r9,4 + or r0,r31,r31 + cmpi crf1,0,r0,0 + addi r27,r27,4 + addi r29,r29,1 + addi r31,r31,-1 + bc 4,6,.-h#1c + addi r26,r0,0 + cmpl crf1,0,r29,r24 + bc 12,4,.-h#1c4 + stw r30,0(r28) + or r3,r25,r25 + or r4,r19,r19 + addi r5,r0,h#101 + or r8,r20,r20 + lwz r0,h#20(r28) + or r9,r23,r23 + stw r0,h#7c(r28) + addi r0,r0,9 + stw r0,0(r9) + lwz r6,h#10(r28) + lwz r7,h#14(r28) + or r10,r28,r28 + bl .-h#b3c + or. r29,r3,r3 + bc 12,2,.+h#14 + or r3,r29,r29 + b .+h#48 + addi r3,r0,1 + b .+h#40 + addi r0,r0,6 + stw r0,0(r16) + rlwinm r3,r19,2,0,29 + add r3,r25,r3 + or r4,r18,r18 + addi r5,r0,0 + or r8,r21,r21 + or r9,r16,r16 + lwz r6,h#18(r28) + lwz r7,h#1c(r28) + or r10,r28,r28 + bl .-h#b84 + or. r29,r3,r3 + bc 12,2,.+h#8 + or r3,r29,r29 + addi r1,r1,h#78 + lwz r0,8(r1) + mtspr lr,r0 + lwz r16,h#-40(r1) + lwz r17,h#-3c(r1) + lwz r18,h#-38(r1) + lwz r19,h#-34(r1) + lwz r20,h#-30(r1) + lwz r21,h#-2c(r1) + lwz r22,h#-28(r1) + lwz r23,h#-24(r1) + lwz r24,h#-20(r1) + lwz r25,h#-1c(r1) + lwz r26,h#-18(r1) + lwz r27,h#-14(r1) + lwz r28,h#-10(r1) + lwz r29,h#-c(r1) + lwz r30,-8(r1) + lwz r31,-4(r1) + bclr 20,0 + + Debug: 2041 80100700 0 48c huft_dynamic + +\ I'm not sure what this is; perhaps part of the TOC, or something like that +\ The code above doesn't appear to depend on it. + h# 0 be-l, h# 153c be-l, h# 0 be-l, + +end-code + +end-assembling + +writing inflate.bin +asm-base here over - ofd @ fputs +ofd @ fclose + +\ 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/ppc/initpgm.fth =================================================================== --- cpu/ppc/initpgm.fth (rev 0) +++ cpu/ppc/initpgm.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,50 @@ +purpose: Generic tools for load image handlers +\ See license at end of file + +: +base ( n -- adr ) load-base + ; + +: (init-program) ( pc sp -- ) + clear-save-area state-valid on + \ PowerPC calling conventions store the link register at SP+8, + \ so we start with r1 a little below the top of the allocated region + h# 20 - to %r1 to %pc + cif-handler to %r5 + + msr@ interrupt-enable-bit invert and to %msr + + restartable? on + true to already-go? +; + +dev /client-services +: chain ( len args entry size virt -- ) + release ( len args entry ) + h# 8000 alloc-mem h# 8000 + (init-program) ( len args ) + to %r6 to %r7 + go +; +device-end + +\ 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/ppc/kerncode.fth =================================================================== --- cpu/ppc/kerncode.fth (rev 0) +++ cpu/ppc/kerncode.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,1479 @@ +purpose: Kernel code words +\ See license at end of file + +\ In the portions of the code than are used while incrementally compiling on +\ the host system, we use "subfc" instead of "subf" instructions, because the +\ POWER, as opposed to PowerPC, instruction set architecture does not have +\ "subf". This allows us to compile on POWER-based RS6000 systems. +\ In code that is only used in a target firmware environment, we can use "subf" +\ "subf" may execute somewhat faster than "subfc", because the carry bit +\ represents an interaction between the integer unit and the branch unit, +\ but the difference is likely to be insignificant in the Forth environment. +\ However, there are cases in interrupt handlers where "subfc" modification +\ of the carry bit represents an undesireable change to the value of the +\ XER register, complicating the process of restoring the state of the +\ interrupted code. + +meta +hex + +\ Allocate and clear the initial user area image +mlabel init-user-area +setup-user-area + +extend-meta-assembler + +\ ---- Assembler macros that reside in the host environment +\ and assemble code for the target environment + +\ Forth Virtual Machine registers + +\ Note that the Forth Stack Pointer (r31) is NOT the same register that +\ C uses for the stack frame pointer (r1). + +register-names definitions + +decimal +:-h t0 20 ;-h :-h t1 21 ;-h :-h t2 22 ;-h :-h t3 23 ;-h +:-h t4 24 ;-h :-h t5 25 ;-h +:-h base 26 ;-h :-h up 27 ;-h :-h tos 28 ;-h :-h ip 29 ;-h +:-h rp 30 ;-h :-h sp 31 ;-h +:-h w t5 ;-h +:-h t6 19 ;-h +hex + + +\ Constants defining virtual machine implementation parameters + +constant-names definitions + +also meta /n-t previous ( /n-t ) + constant-h 1cell \ Offsets into the stack +1cell -1 * constant-h -1cell +1cell 2 * constant-h 2cells +1cell 3 * constant-h 3cells +1cell 4 * constant-h 4cells +1cell 5 * constant-h 5cells + +1cell constant-h /cf \ Size of a code field (except for "create") +/cf -1 * constant-h -/cf + +1cell constant-h /token \ Size of a compiled word reference +/token -1 * constant-h -/token + +1cell constant-h /branch \ Size of a branch offset + +/token 2 * constant-h /ccf \ Size of a "create" code field + +/cf 1cell + constant-h /cf+1cell \ Location of second half of + +previous previous definitions + +\ assembler macros for common sequences +extend-meta-assembler + +:-h next-tail1 " add t1,t1,base mtspr lr,t1 bclr 20,0" evaluate ;-h +:-h next-tail " lwzux t1,w,base next-tail1" evaluate ;-h +:-h push-tos " stwu tos,-1cell(sp)" evaluate ;-h +:-h push-t0 " stwu t0,-1cell(sp)" evaluate ;-h +:-h pop-tos " lwz tos,0(sp) addi sp,sp,1cell" evaluate ;-h +:-h pop1 " lwz tos,1cell(sp) addi sp,sp,2cells" evaluate ;-h +:-h pop2 " lwz tos,2cells(sp) addi sp,sp,3cells" evaluate ;-h +:-h second-to-t0 " lwz t0,0(sp)" evaluate ;-h +:-h pop-to-t0 " second-to-t0 addi sp,sp,1cell" evaluate ;-h +:-h double-tos " add tos,tos,tos" evaluate ;-h +:-h third-to-t1 " lwz t1,1cell(sp)" evaluate ;-h +:-h user#-to-t0 " lwz t0,/cf(w)" evaluate ;-h +:-h take-branch " lwz t0,/branch(ip) add ip,ip,t0" evaluate ;-h +:-h skip-branch " addi ip,ip,/branch" evaluate ;-h +:-h literal-to-tos " lwzu tos,/token(ip)" evaluate ;-h +:-h literal-to-t0 " lwzu t0,/token(ip)" evaluate ;-h +:-h rdrop " addi rp,rp,1cell" evaluate ;-h +:-h rdrop3 " addi rp,rp,3cells" evaluate ;-h + +\ We create the shared code for the "next" routine so that: +\ a) It will be in RAM for speed (ROM is often slow) +\ b) We can use the user pointer as its base address, for quick jumping + +also forth +compilation-base here-t \ Save meta dictionary pointer +0 dp-t ! userarea-t is compilation-base \ Point it to user area +previous + +mlabel (next) \ Shared code for next; will be copied into user area + lwzu w,/token(ip) + next-tail +end-code + +also forth +dp-t ! is compilation-base previous \ Restore meta dict. pointer + +d# 32 equ #user-init \ Leaves space for the shared "next" + +only forth also labels also meta also assembler definitions + +\ assembler macro to assemble next +:-h next " bcctr 20,0" evaluate ;-h + +:-h c; next end-code ;-h + +previous definitions + +code-field: docolon + stwu ip,-1cell(rp) \ Push the ip register on the return stack + mr ip,w \ Set ip to apf of the colon definition +c; + +code-field: dovariable + push-tos + addi tos,w,/cf \ Put pfa in top-of-stack register +c; + +code-field: dolabel + + push-tos + addi tos,w,/cf \ Put pfa in top-of-stack register +c; + +code-field: douser + push-tos + user#-to-t0 + add tos,t0,up \ Add the base address of the user area +c; + +code-field: dovalue + push-tos + user#-to-t0 + lwzx tos,t0,up \ Get the contents of the user area location +c; + +code-field: dodefer + user#-to-t0 + lwzx w,t0,up \ Get the acf stored in that user location + next-tail +end-code + +code-field: doconstant + push-tos + lwz tos,/cf(w) \ Get the constant's value +c; + +code-field: do2constant + push-tos + lwzu tos,/cf(w) \ Get the constant's value + push-tos \ Put it on the memory stack + lwz tos,1cell(w) \ Get the top constant's value +c; + +code-field: dodoes + \ The child word's code field contains the token of dodoes, followed + \ by the token of the does clause. + + push-tos + addi tos,w,/ccf \ Put pfa in top-of-stack register + lwz w,/cf(w) \ Set w to acf of the definition + next-tail +end-code + +:-h code-cf ( -- ) here /token + aligned token,-t align-t ;-h +:-h label-cf ( -- ) dolabel token,-t align-t ;-h +:-h colon-cf ( -- ) docolon token,-t ;-h +:-h constant-cf ( -- ) doconstant token,-t ;-h +:-h variable-cf ( -- ) dovariable token,-t ;-h +:-h user-cf ( -- ) douser token,-t ;-h +:-h value-cf ( -- ) dovalue token,-t ;-h +:-h defer-cf ( -- ) dodefer token,-t ;-h +:-h startdoes ( -- ) colon-cf ;-h +:-h start;code ( -- ) code-cf ;-h +:-h create-cf ( -- ) dodoes token,-t compile-t noop ;-h +:-h vocabulary-cf ( -- ) dodoes token,-t compile-t <vocabulary> ;-h + +meta definitions + +\ dovariable constant dovariable +\ dodoes constant dodoes + +code (lit) (s -- n ) + push-tos + literal-to-tos +c; +code (wlit) (s -- n ) + push-tos + literal-to-tos +c; + +\ Execute a Forth word given a code field address +code execute (s acf -- ) + mr w,tos + pop-tos + lwz t1,0(w) \ Read the contents of the code field + next-tail1 +end-code + +\ High level branch. The branch offset is compiled in-line. +code branch (s -- ) +mlabel bran1 + take-branch +c; + +\ High level conditional branch. +code ?branch (s f -- ) \ Takes the branch if the flag is false + cmpi 0,0,tos,0 + pop-tos + + bran1 0= brif + + skip-branch +c; + +\ Run time word for loop +code (loop) (s -- ) + lwz t0,0(rp) + addic. t1,t0,1 \ Increment index + stw t1,0(rp) \ Write back the loop index + bran1 0>= brif \ Result still positive; continue looping + cmpi 0,0,t0,0 \ Result negative, so check operand + bran1 0< brif \ If operand is negative too, continue looping + + \ The internal "i" value went from positive to negative, so the loop ends + rdrop3 \ remove loop params from stack + skip-branch +c; + +\ Run time word for +loop +code (+loop) (s increment -- ) + lwz t0,0(rp) + add t1,t0,tos \ increment loop index + stw t1,0(rp) \ Write back the loop index + xor. t3,t0,tos \ Compare operand signs + pop-tos + bran1 0< brif \ Operand signs different + + xor. t2,t1,t0 \ Compare result with an operand + bran1 0>= brif \ Result has same sign as operand; continue looping + + \ The result sign differs from the operand signs; so the loop ends + rdrop3 \ remove loop params from stack + skip-branch +c; + +\ Run time word for do +code (do) (s l i -- ) + mr t1,tos \ i in t1 + second-to-t0 \ l in t0 + pop1 \ Finish popping stack +mlabel pd0 ( -- r: loop-end-offset l+0x8000 i-l-0x8000 ) + stwu ip,-1cell(rp) \ remember the do offset address + addi ip,ip,/branch \ Skip the do offset + addis t0,t0,h#-8000 \ Bias by h#8000.0000 + stwu t0,-1cell(rp) \ Push biased limit on return stack + subfc t1,t0,t1 \ ( Use subfc for POWER compatibility) + stwu t1,-1cell(rp) \ Push biased index on return stack +c; +meta + +\ Run time word for ?do +code (?do) (s l i -- ) + second-to-t0 \ l in t0 + mr t1,tos \ i in t1 + pop1 \ Finish popping stack + cmp 0,0,t0,t1 + pd0 <> brif + + take-branch +c; + +\ Loop index for current do loop +code i (s -- n ) + push-tos + lwz tos,0(rp) + lwz t0,1cell(rp) + add tos,tos,t0 +c; + +\ Loop index for next enclosing do loop +code j (s -- n ) + push-tos + lwz tos,12(rp) + lwz t0,16(rp) + add tos,tos,t0 +c; + +code (leave) (s -- ) +mlabel pleave + lwz ip,2cells(rp) \ Get the address of the ending offset + rdrop3 \ get rid of the loop indices + + take-branch +c; + +code (?leave) (s f -- ) + cmpi 0,0,tos,0 + pop-tos + pleave 0<> brif +c; + +code unloop ( -- ) rdrop3 c; \ Discard the loop indices + +code (of) ( selector test -- [ selector ] ) + pop-to-t0 \ Test in tos, Selector in t0 + cmp 0,0,t0,tos + mr tos,t0 \ Copy selector to tos + = if + pop-tos \ Overwrite tos if selector matches + skip-branch + next + then + + take-branch +c; + +\ (endof) is the same as branch, and (endcase) is the same as drop, +\ but redefining them this way makes the decompiler much easier. +code (endof) (s -- ) + take-branch +c; +code (endcase) (s n -- ) + pop-tos +c; + +assembler +mlabel dofalse + addi tos,r0,0 + next +meta + +\ Convert a character to a digit according to the current base +code digit (s char base -- digit true | char false ) + mr t0,tos \ base in t0 + lwz tos,0(sp) \ char in tos + addic. tos,tos,h#-30 \ convert to number \ 30 is ascii 0 + dofalse 0< brif \ Anything less than ascii 0 isn't a digit + cmpi 0,0,tos,10 \ Test for >= 10 + 0>= if \ Try for a letter representing a digit + ascii A ascii 0 - cmpi 0,0,tos,* + dofalse < brif \ bad if > '9' and < 'A' + ascii a ascii 0 - cmpi 0,0,tos,* \ >= 'a' + >= if + ascii a ascii 0 - d# 10 - negate addi tos,tos,* + else + ascii A ascii 0 - d# 10 - negate addi tos,tos,* + then + then + cmp 0,0,tos,t0 \ Compare digit to base + dofalse 0>= brif \ Error if digit is bigger than base + stw tos,0(sp) \ Replace the char on the stack with the digit + addi tos,r0,-1 \ True to indicate success +c; + +\ Copy cnt characters starting at from-addr to to-addr. Copying is done +\ strictly from low to high addresses, so be careful of overlap between the +\ two buffers. + +code cmove ( src dst cnt -- ) \ Copy from bottom to top + second-to-t0 \ Dst into t0 + third-to-t1 \ Src into t1 + + cmpi 0,0,tos,0 + 0<> if + addi t0,t0,-1 \ Account for pre-incrementing + addi t1,t1,-1 \ Account for pre-incrementing + mfspr t2,ctr \ Save count register + mtspr ctr,tos \ Count in count register + begin + lbzu t3,1(t1) \ Load byte + stbu t3,1(t0) \ Store byte + countdown \ Decrement & Branch if nonzero + mtspr ctr,t2 \ Restore count register + then + + pop2 +c; + +code cmove> ( src dst cnt -- ) \ Copy from top to bottom + second-to-t0 \ Dst into t0 + third-to-t1 \ Src into t1 + + cmpi 0,0,tos,0 + 0<> if + add t0,t0,tos \ Top of dst range + add t1,t1,tos \ Top of src range + mfspr t2,ctr \ Save count register + mtspr ctr,tos \ Count in count register + begin + lbzu t3,-1(t1) \ Load byte + stbu t3,-1(t0) \ Store byte + countdown \ Decrement & Branch if nonzero + mtspr ctr,t2 \ Restore count register + then + + pop2 +c; + +code lshift (s n1 cnt -- n2 ) pop-to-t0 slw tos,t0,tos c; +code rshift (s n1 cnt -- n2 ) pop-to-t0 srw tos,t0,tos c; +code << (s n1 cnt -- n2 ) pop-to-t0 slw tos,t0,tos c; +code >> (s n1 cnt -- n2 ) pop-to-t0 srw tos,t0,tos c; +code >>a (s n1 cnt -- n2 ) pop-to-t0 sraw tos,t0,tos c; + +code and (s n1 n2 -- n3 ) pop-to-t0 and tos,tos,t0 c; +code or (s n1 n2 -- n3 ) pop-to-t0 or tos,tos,t0 c; +code xor (s n1 n2 -- n3 ) pop-to-t0 xor tos,tos,t0 c; + +code + (s n1 n2 -- n3 ) pop-to-t0 add tos,tos,t0 c; + +\ ( Use subfc for POWER compatibility) +code - (s n1 n2 -- n3 ) pop-to-t0 subfc tos,tos,t0 c; + +code min (s n1 n2 -- n3 ) + pop-to-t0 cmp 0,0,t0,tos < if mr tos,t0 then +c; +code max (s n1 n2 -- n3 ) + pop-to-t0 cmp 0,0,t0,tos > if mr tos,t0 then +c; +code umin (s n1 n2 -- n3 ) + pop-to-t0 cmpl 0,0,t0,tos < if mr tos,t0 then +c; +code umax (s n1 n2 -- n3 ) + pop-to-t0 cmpl 0,0,t0,tos > if mr tos,t0 then +c; + +code invert (s n1 -- n2 ) nor tos,tos,tos c; +code negate (s n1 -- n2 ) neg tos,tos c; +code abs (s n1 -- n2 ) cmpi 0,0,tos,0 0< if neg tos,tos then c; + +code up@ (s -- addr ) push-tos mr tos,up c; +code sp@ (s -- addr ) push-tos mr tos,sp c; +code rp@ (s -- addr ) push-tos mr tos,rp c; +code up! (s addr -- ) mr up,tos pop-tos c; +code sp! (s addr -- ) mr sp,tos pop-tos c; +code rp! (s addr -- ) mr rp,tos pop-tos c; + +code >r (s n -- ) stwu tos,-1cell(rp) pop-tos c; +code r> (s -- n ) push-tos lwz tos,0(rp) rdrop c; +code r@ (s -- n ) push-tos lwz tos,0(rp) c; + +code 2>r (s n1 n2 -- ) + second-to-t0 stwu t0,-1cell(rp) stwu tos,-1cell(rp) pop1 +c; +code 2r> (s -- n1 n2 ) + push-tos lwz tos,1cell(rp) push-tos lwz tos,0(rp) addi rp,rp,2cells +c; +code 2r@ (s -- n1 n2 ) + push-tos lwz tos,1cell(rp) push-tos lwz tos,0(rp) +c; + +code ip> (s -- n ) push-tos lwz tos,0(rp) rdrop addi tos,tos,/token c; +code ip@ (s -- n ) push-tos lwz tos,0(rp) addi tos,tos,/token c; +code >ip (s n -- ) addi tos,tos,-/token stwu tos,-1cell(rp) pop-tos c; +code ip>token ( ip -- token-adr ) c; + +code exit (s -- ) lwz ip,0(rp) rdrop c; +code unnest (s -- ) lwz ip,0(rp) rdrop c; + +code tuck (s n1 n2 -- n2 n1 n2 ) second-to-t0 push-t0 stw tos,1cell(sp) c; +code nip (s n1 n2 -- n2 ) addi sp,sp,1cell c; +code flip (s w1 -- w2 ) \ byte swap + rlwinm t0,tos,24,24,31 \ high half to low half + rlwimi t0,tos,8,16,23 \ low to high and insert + mr tos,t0 +c; + +assembler definitions + +\ macro to assemble code to leave a flag on the stack +:-h leaveflag (s condition -- ) + " if addi tos,r0,-1 else addi tos,r0,0 then" evaluate +;-h + +:-h compare " pop-to-t0 cmp 0,0,t0,tos" evaluate ;-h +:-h compareu " pop-to-t0 cmpl 0,0,t0,tos" evaluate ;-h +:-h compare0 " cmpi 0,0,tos,0" evaluate ;-h + +meta definitions +code 0< (s n -- f ) compare0 0< leaveflag c; +code 0> (s n -- f ) compare0 0> leaveflag c; +code 0<= (s n -- f ) compare0 0<= leaveflag c; +code 0>= (s n -- f ) compare0 0>= leaveflag c; +code 0= (s n -- f ) compare0 0= leaveflag c; +code 0<> (s n -- f ) compare0 0<> leaveflag c; + +code = (s n1 n2 -- f ) compare = leaveflag c; +code <> (s n1 n2 -- f ) compare <> leaveflag c; + +code < (s n1 n2 -- f ) compare < leaveflag c; +code >= (s n1 n2 -- f ) compare >= leaveflag c; +code > (s n1 n2 -- f ) compare > leaveflag c; +code <= (s n1 n2 -- f ) compare <= leaveflag c; +code u< (s n1 n2 -- f ) compareu < leaveflag c; +code u>= (s n1 n2 -- f ) compareu >= leaveflag c; +code u> (s n1 n2 -- f ) compareu > leaveflag c; +code u<= (s n1 n2 -- f ) compareu <= leaveflag c; + +code drop (s n -- ) pop-tos c; +code dup (s n -- n n ) push-tos c; +code over (s n1 n2 -- n1 n2 n1 ) push-tos lwz tos,1cell(sp) c; +code swap (s n1 n2 -- n2 n1 ) second-to-t0 stw tos,0(sp) mr tos,t0 c; +code rot (s n1 n2 n3 -- n2 n3 n1 ) + second-to-t0 + third-to-t1 + stw t0,1cell(sp) + stw tos,0(sp) + mr tos,t1 +c; +code -rot (s n1 n2 n3 -- n3 n1 n2 ) + second-to-t0 + third-to-t1 + stw tos,1cell(sp) + stw t1,0(sp) + mr tos,t0 +c; +code 2drop (s d -- ) pop1 c; +code 2dup (s d -- d d ) second-to-t0 push-tos push-t0 c; +code 2over (s d1 d2 -- d1 d2 d1 ) + push-tos + lwz tos,12(sp) + push-tos + lwz tos,12(sp) +c; +code 2swap (s d1 d2 -- d2 d1 ) + lwz t2,2cells(sp) + third-to-t1 + second-to-t0 + stw t0,2cells(sp) + stw tos,1cell(sp) + stw t2,0(sp) + mr tos,t1 +c; +code 3drop (s n1 n2 n3 -- ) pop2 c; +code 3dup (s n1 n2 n3 -- n1 n2 n3 n1 n2 n3 ) + third-to-t1 + second-to-t0 + push-tos + stwu t1,-1cell(sp) + push-t0 +c; +code 4drop (s n1 n2 n3 n4 -- ) + lwz tos,3cells(sp) addi sp,sp,4cells +c; +code 5drop (s n1 n2 n3 n4 n5 -- ) + lwz tos,4cells(sp) addi sp,sp,5cells +c; + +code pick (s nm ... n1 n0 k -- nm ... n2 n0 nk ) + add tos,tos,tos + add tos,tos,tos \ Multiply by /n + lwzx tos,tos,sp +c; + +code 1+ (s n1 -- n2 ) addi tos,tos,1 c; +code 2+ (s n1 -- n2 ) addi tos,tos,2 c; +code 1- (s n1 -- n2 ) addi tos,tos,-1 c; +code 2- (s n1 -- n2 ) addi tos,tos,-2 c; + +code 2/ (s n1 -- n2 ) srawi tos,tos,1 c; +code u2/ (s n1 -- n2 ) rlwinm tos,tos,31,1,31 c; +code 4/ (s n1 -- n2 ) srawi tos,tos,2 c; +code 2* (s n1 -- n2 ) rlwinm tos,tos,1,0,30 c; +code 4* (s n1 -- n2 ) rlwinm tos,tos,2,0,29 c; +code 8* (s n1 -- n2 ) rlwinm tos,tos,3,0,28 c; + +code on (s addr -- ) addi t0,r0,-1 stw t0,0(tos) pop-tos c; +code off (s addr -- ) addi t0,r0,0 stw t0,0(tos) pop-tos c; + +code +! (s n addr -- ) + second-to-t0 + lwz t1,0(tos) + add t1,t1,t0 + stw t1,0(tos) + pop1 +c; + +code @ (s adr -- n ) lwz tos,0(tos) c; \ longword aligned +code l@ (s adr -- l ) lwz tos,0(tos) c; \ longword aligned +code w@ (s adr -- w ) lhz tos,0(tos) c; \ 16-bit word aligned +code <w@ (s adr -- w ) lha tos,0(tos) c; \ with sign extension +code c@ (s adr -- c ) lbz tos,0(tos) c; +code be-w@ ( a -- w ) + lbz t0,0(tos) + lbz tos,1(tos) + rlwimi tos,t0,8,16,23 +c; +code le-w@ ( a -- w ) + lbz t0,1(tos) + lbz tos,0(tos) + rlwimi tos,t0,8,16,23 +c; + +code ! (s n adr -- ) second-to-t0 stw t0,0(tos) pop1 c; +code l! (s n adr -- ) second-to-t0 stw t0,0(tos) pop1 c; +code w! (s w adr -- ) second-to-t0 sth t0,0(tos) pop1 c; +code c! (s c adr -- ) second-to-t0 stb t0,0(tos) pop1 c; +code be-w! ( w a -- ) + second-to-t0 + rlwinm t1,t0,24,24,31 \ high byte + stb t1,0(tos) + stb t0,1(tos) + pop1 +c; +code le-w! ( w a -- ) + second-to-t0 + rlwinm t1,t0,24,24,31 \ high byte + stb t1,1(tos) + stb t0,0(tos) + pop1 +c; + +[ifdef] 64bit-hardware +[else] +\ XXX Use 64-bit oper +: d@ (s adr -- low high ) dup na1+ @ swap @ ; +: d! (s low high adr -- ) tuck ! na1+ ! ; +[then] + +: instruction! (s n adr -- ) tuck ! /l sync-cache ; + +code 2@ (s adr -- d ) lwz t0,1cell(tos) push-t0 lwz tos,0(tos) c; +code 2! (s d adr -- ) + second-to-t0 + stw t0,0(tos) + lwz t0,1cell(sp) + stw t0,1cell(tos) + pop2 +c; + +code fill (s start-adr count char -- ) + \ char in tos + second-to-t0 \ count in t0 + third-to-t1 \ dst in t1 + + cmpli 0,0,t0,h#1000 \ Optimize only if the count is large + >= if + or r0,t1,t0 \ Collect low bits of count and address + andi. r0,r0,3 \ Optimize only if the address and count are aligned + 0= if + addi t1,t1,-1cell \ Account for pre-increment + rlwinm t0,t0,30,2,31 \ Divide count by 4 + rlwimi tos,tos,8,16,23 \ Replicate low byte into low halfword + rlwimi tos,tos,16,0,15 \ Replicate low halfword into word + mfspr t2,ctr \ Save CTR + mtspr ctr,t0 + begin + stwu tos,1cell(t1) + countdown + mtspr ctr,t2 + + pop2 next + then + + then + + cmpi 0,0,t0,0 + 0<> if + addi t1,t1,-1 \ Account for pre-increment + mfspr t2,ctr \ Save CTR + mtspr ctr,t0 + begin + stbu tos,1(t1) \ Store byte + countdown \ Decrement and Branch if nonzero + mtspr ctr,t2 + then + + pop2 +c; + +code noop (s -- ) c; + +code lowbyte (s n -- low ) andi. tos,tos,h#ff c; + +code wbsplit (s w -- b.low b.high ) \ split a word into two bytes + andi. t0,tos,h#ff + push-t0 + rlwinm tos,tos,24,24,31 +c; +code bwjoin (s b.low b.high -- w ) + pop-to-t0 + andi. t0,t0,h#ff + rlwimi t0,tos,8,16,23 + mr tos,t0 +c; +code lwsplit (s l -- w.low w.high ) \ split a long into two words + andi. t0,tos,h#ffff + push-t0 + rlwinm tos,tos,16,16,31 +c; +code wljoin (s w.low w.high -- l ) + pop-to-t0 + rlwimi t0,tos,16,0,15 + mr tos,t0 +c; + +1 constant /c +2 constant /w +4 constant /l +/l constant /n + +code ca+ (s addr index -- addr+index*/c ) + pop-to-t0 + add tos,tos,t0 +c; +code wa+ (s addr index -- addr+index*/w ) + pop-to-t0 + add tos,tos,tos + add tos,tos,t0 +c; +code la+ (s addr index -- addr+index*/l ) + pop-to-t0 + add tos,tos,tos + add tos,tos,tos + add tos,tos,t0 +c; +code na+ (s addr index -- addr+index*/n ) + pop-to-t0 + add tos,tos,tos + add tos,tos,tos + add tos,tos,t0 +c; +code ta+ (s addr index -- addr+index*/t ) + pop-to-t0 + add tos,tos,tos + add tos,tos,tos + add tos,tos,t0 +c; + +code ca1+ (s addr -- addr+/w ) addi tos,tos,1 c; +code char+ (s addr -- addr+/w ) addi tos,tos,1 c; +code wa1+ (s addr -- addr+/w ) addi tos,tos,2 c; +code la1+ (s addr -- addr+/l ) addi tos,tos,4 c; +code na1+ (s addr -- addr+/n ) addi tos,tos,1cell c; +code cell+ (s addr -- addr+/n ) addi tos,tos,1cell c; +code ta1+ (s addr -- addr+/token ) addi tos,tos,/token c; + +code /c* (s n -- n*/c ) c; +code chars (s n -- n*/c ) c; +code /w* (s n -- n*/w ) add tos,tos,tos c; +code /l* (s n -- n*/l ) add tos,tos,tos add tos,tos,tos c; +code /n* (s n -- n*/n ) add tos,tos,tos add tos,tos,tos c; +code cells (s n -- n*/n ) add tos,tos,tos add tos,tos,tos c; + +code upc (s char -- upper-case-char ) + ascii a cmpi 0,0,tos,* >= if + ascii z cmpi 0,0,tos,* <= if + addi tos,tos,h#-20 + then + then +c; +code lcc (s char -- upper-case-char ) + ascii A cmpi 0,0,tos,* >= if + ascii Z cmpi 0,0,tos,* <= if + addi tos,tos,h#20 + then + then +c; + +code c@+ (s adr -- adr' char ) addi t0,tos,1 push-t0 lbz tos,0(tos) c; + +code comp ( addr1 addr2 len -- -1 | 0 | 1 ) + second-to-t0 \ addr2 + third-to-t1 \ addr1 + addi sp,sp,2cells + mr t2,tos \ len + set tos,0 \ default result + + addi t0,t0,-1 \ Account for pre-incrementing + addi t1,t1,-1 \ Account for pre-incrementing + begin + cmpi 0,0,t2,0 0<> while + addi t2,t2,-1 + lbzu t3,1(t0) \ Load byte + lbzu t4,1(t1) \ Load byte + cmp 0,0,t3,t4 <> if \ mismatch + < if addi tos,tos,1 else addi tos,tos,-1 then + next + then + repeat +c; + +: caps-comp (s addr1 addr2 len -- -1 | 0 | 1 ) +\ XXX optimize me + rot 0 swap 2swap ( 0 addr1 addr2 len ) + bounds ?do ( 0 addr1' ) + c@+ lcc i c@ lcc <> if ( 0 addr1' ) + nip dup 1- c@ lcc i c@ lcc < + if -1 else 1 then ( addr1' flag ) + swap leave ( flag addr1' ) + then ( 0 addr1' ) + loop + drop +; + +code pack ( str-adr len dest -- dest ) + second-to-t0 \ len + third-to-t1 \ str-adr + addi sp,sp,2cells + mr t2,tos \ dest + stb t0,0(tos) \ requires length < 256 + + cmpi 0,0,t0,0 + 0<> if + addi t1,t1,-1 \ Account for pre-incrementing + mfspr t4,ctr \ Save count register + mtspr ctr,t0 \ Count in count register + begin + lbzu t3,1(t1) \ Load byte + stbu t3,1(t2) \ Store byte + countdown \ Decrement & Branch if nonzero + set t3,0 + stbu t3,1(t2) \ Store a null byte at the end + mtspr ctr,t4 \ Restore count register + then +c; + +code (') (s -- acf ) push-tos literal-to-tos add tos,tos,base c; + +\ Modifies caller's ip to skip over an in-line string +code skipstr (s -- adr len) + push-tos + lwz t0,0(rp) \ Get string address in t0 + lbzu tos,/token(t0) \ Get length byte in tos + addi t0,t0,1 \ Address of data bytes + push-t0 \ Push adr + + \ Now we have to skip the string + add t0,t0,tos \ Scr now points past the last data byte + +\ ! We don't want to add 4 because IP is pre-incremented inside NEXT +\ addi t0,t0,4 \ Round up to token boundary + null byte (4= #align) + + rlwinm t0,t0,0,0,29 \ Round down to token boundary + stw t0,0(rp) \ Put the modified ip back +c; + +code (") (s -- adr len) + push-tos + lbzu tos,/token(ip) \ Get length byte in tos + addi ip,ip,1 \ Address of data bytes + stwu ip,-1cell(sp) \ Push adr + + \ Now we have to skip the string + add ip,ip,tos \ ip now points past the last data byte + +\ ! We don't want to add 4 because IP is pre-incremented inside NEXT +\ addi ip,ip,4 \ Round up to a token boundary, plus null byte (#talign + + rlwinm ip,ip,0,0,29 +c; + +code count (s adr -- adr+1 len ) + addi tos,tos,1 + lbz t0,-1(tos) + push-tos + mr tos,t0 +c; + +code origin (s -- addr ) push-tos mr tos,base c; + +code origin+ (s n -- adr ) add tos,base,tos c; +code origin- (s n -- adr ) subf tos,base,tos c; + +: acf-align (s -- ) + begin here #acf-align 1- and while 0 c, repeat + here 'lastacf token! +; + +headerless + +\ Place the "standard" code field + +: set-cf (s action-adr -- ) acf-align origin+ token, ; + +headers +\ : place-cf (s action-adr -- ) acf-align token, ; +\ This is only used in action: . We define it as a no-op so that +\ "doaction" can do all the work. +: place-cf (s -- ) ; + +\ Create code field for code word +: code-cf (s -- ) acf-align here ta1+ aligned token, align ; + +: >code ( acf-of-code-word -- address-of-start-of-machine-code ) token@ ; +: code? ( acf -- f ) \ True if the acf is for a code word + dup token@ swap >body = +; + +\ Assemble "next" routine at the end of a code definition. +\ This is not needed for the kernel to run; it is used later +\ after the resident assembler has been loaded + +: next (s -- ) + here /l allot h# 4e800420 swap instruction! ( "bcctr 20,0" ) +; + +: create-cf (s -- ) [ dodoes ] literal set-cf ['] noop token, ; +: variable-cf (s -- ) [ dovariable ] literal set-cf ; + +: place-;code (s -- ) code-cf ; +: place-does (s -- ) [ docolon ] literal set-cf ; + +\ Ip is assumed to point to (;code . flag is true if +\ the code at ip is a does> clause as opposed to a ;code clause. +: does-ip? ( ip -- ip' flag ) + dup token@ ['] (does>) = ( ip flag ) swap ta1+ ta1+ swap +; + +: put-cf (s action-clause-adr where -- ) token! ; + +\ uses sets the code field of the indicated word so that +\ it will execute the code at action-clause-adr +: uses (s action-clause-adr xt -- ) + tuck /token + put-cf + [ dodoes ] literal origin+ swap put-cf +; + +\ used sets the code field of the most-recently-defined word so that +\ it executes the word at action-clause-adr +: used (s action-clause-adr -- ) lastacf uses ; + +: colon-cf? ( possible-acf -- flag ) + dup token@ [ docolon ] literal origin+ = if + /token - token@ + dup ['] branch <> + over ['] ?branch <> and + over ['] (of) <> and + over ['] (leave) <> and + over ['] (?leave) <> and + over ['] (do) <> and + over ['] (?do) <> and + swap ['] (lit) <> and + else + drop false + then +; +: colon-cf (s -- ) [ docolon ] literal set-cf ; +: user-cf (s -- ) [ douser ] literal set-cf ; +: value-cf (s -- ) [ dovalue ] literal set-cf ; +: constant-cf (s -- ) [ doconstant ] literal set-cf ; +: defer-cf (s -- ) [ dodefer ] literal set-cf ; +: 2constant-cf (s -- ) [ do2constant ] literal set-cf ; + +4 constant /branch +: branch, ( offset -- ) , ; +: branch! ( offset where -- ) ! ; + +: branch@ ( where -- offset ) @ ; +\ >target depends on the way that branches are compiled +: >target ( ip-of-branch-instruction -- target ) ta1+ dup branch@ + ; +headerless + +/a constant /a + +headers + +code a@ ( adr -- adr' ) + lwz tos,0(tos) + add tos,tos,base +c; + +\ R : a! ( adr1 adr2 -- ) set-relocation-bit l! ; +code a! ( adr1 adr2 -- ) + pop-to-t0 + subfc t0,base,t0 \ ( Use subfc for POWER compatibility) + stw t0,0(tos) + pop-tos +c; +: a, ( adr -- ) here /a allot a! ; + +/token constant /token +code token@ (s adr -- cfa ) lwz tos,0(tos) add tos,tos,base c; +\ R : token! (s cfa adr -- ) set-relocation-bit l! ; +code token! (s cfa addr -- ) + second-to-t0 + subfc t0,base,t0 \ ( Use subfc for POWER compatibility) + stw t0,0(tos) + pop1 +c; + + +: token, (s cfa -- ) here /token allot token! ; + +: null ( -- token ) origin ; +: !null-link ( adr -- ) null swap link! ; +: !null-token ( adr -- ) null swap token! ; +: non-null? ( link -- false | link true ) + dup origin = if drop false else true then +; +\ code non-null? ( link -- false | link true ) +\ tos base cmp +\ <> if +\ false t0 mr \ Delay slot +\ +\ push-tos +\ true t0 mr +\ then +\ t0 tos mr +\ c; +: get-token? ( adr -- false | acf true ) token@ non-null? ; +: another-link? ( adr -- false | link true ) link@ non-null? ; + +\ The "word type" is a number which distinguishes one type of word +\ from another. This is highly implementation-dependent. + +\ For the PowerPC implementation, the magic number returned by word-type +\ is the absolute address of the action code. + +: long-cf? (s acf -- flag ) token@ origin- [ dodoes ] literal = ; + +: word-type (s acf -- word-type ) dup long-cf? if ta1+ then token@ ; + +: body> (s apfa -- acf ) + /token - dup /token - long-cf? if /token - then +; +: >body (s acf -- apf ) dup long-cf? if ta1+ then ta1+ ; + +4 constant /user# + +\ Move to a machine alignment boundary. + +: aligned (s adr -- adr' ) /n round-up ; + +code acf-aligned (s adr -- adr' ) + addi tos,tos,3 +\ addi t0,r0,-4 +\ and tos,tos,t0 + rlwinm tos,tos,0,0,29 +c; + +\ Floored division is prescribed by the Forth 83 standard. +\ The quotient is rounded toward negative infinity, and the +\ remainder has the same sign as the divisor. + +: /mod (s dividend divisor -- remainder quotient ) + \ Check if either factor is negative + 2dup ( n1 n2 n1 n2) + or 0< if ( n1 n2) + + \ Both factors not non-negative; do division by: + \ Take absolute value and do unsigned division + \ Convert to truncated signed divide by: + \ if dividend is negative then negate the remainder + \ if dividend and divisor have opposite signs then negate the quotient + \ Then convert to floored signed divide by: + \ if quotient is negative and remainder is non-zero + \ add divisor to remainder and decrement quotient + + 2dup swap abs swap abs ( n1 n2 u1 u2) \ Absolute values + + u/mod ( n1 n2 urem uqout) \ Unsigned divide + >r >r ( n1 n2) ( uquot urem) + + over 0< if ( n1 n2) ( uquot urem) + r> negate >r \ Negative dividend; negate remainder + then ( n1 n2) ( uquot trem) + + swap over ( n2 n1 n2) ( uquot trem) + xor 0< if ( n2) ( uquot trem) + r> r> + negate ( n2 trem tquot) \ Opposite signs; negate quotient + -rot ( tquot n2 trem) + dup 0<> if + + ( tquot rem) \ Negative quotient & non-zero remainder + swap 1- ( rem quot) \ add divisor to rem. & decrement quot. + else + nip swap ( rem quot) + then + else + drop r> r> ( rem quot) + then + + else \ Both factors non-negative + + u/mod ( rem quot) + then +; + +\ 64-bit addition and subtraction +: dabs ( d# -- d# ) dup 0< if dnegate then ; +: dmax ( d1 d2 -- d3 ) 2over 2over d- nip 0< if 2swap then 2drop ; + +code d+ ( d1 d2 -- d3 ) + lwz t1,0(sp) \ d2.low + lwz t3,2cells(sp) \ d1.low + lwz t2,1cell(sp) \ d1.high + addi sp,sp,2cells \ Pop args + addc t1,t1,t3 \ d3.low + adde tos,tos,t2 \ d3.high + stw t1,0(sp) \ Push result (d3.high already in tos) +c; +code d- ( d1 d2 -- d3 ) + lwz t1,0(sp) \ x2.low + lwz t2,1cell(sp) \ x1.high + lwz t3,2cells(sp) \ x1.low + addi sp,sp,2cells \ Pop args + subfc t1,t1,t3 \ x3.low + subfe tos,tos,t2 \ x3.high + stw t1,0(sp) \ Push result (x3.high already in tos) +c; +code s>d ( n -- d ) push-tos srawi tos,tos,31 c; +code dnegate ( d -- -d ) + second-to-t0 + subfic t0,t0,0 + stw t0,0(sp) + subfze tos,tos +c; + +only forth also labels also meta also assembler definitions + +:-h 'user# \ name ( -- user# ) + [ meta ]-h ' ( acf-of-user-variable ) >body-t + @-t +;-h +:-h 'user \ name ( -- user-addressing-mode ) + [ also assembler also register-names ]-h 'user# up + [ previous previous ]-h +;-h +:-h 'body \ name ( -- variable-apf ) + [ meta ]-h ' ( acf-of-user-variable ) >body-t +;-h +:-h 'acf \ name ( -- variable-apf ) + [ meta ]-h ' ( acf-of-user-variable ) >body-t +;-h + +only forth also labels also meta also definitions + +: m+ ( d1|ud1 n -- ) s>d d+ ; + +fload ${BP}/forth/kernel/dmuldiv.fth + +: m/mod (s l.dividend n.divisor -- n.remainder n.quotient ) fm/mod ; + +code * ( n1 n2 -- n3 ) pop-to-t0 mullw tos,t0,tos c; + +: ul* (s un1 un2 -- lproduct ) * ; +: u* (s un1 un2 -- uproduct ) * ; + + +\ PowerPC version is dynamically relocated, so we don't need a bitmap +: clear-relocation-bits ( adr len -- ) 2drop ; + +: move ( src dst cnt -- ) + >r 2dup u< if r> cmove> else r> cmove then +; + +init-user-area constant init-user-area + +code (llit) (s -- l ) push-tos literal-to-tos c; +code (dlit) (s -- d ) push-tos literal-to-tos literal-to-t0 push-t0 c; + +\ Select a vocabulary thread by hashing the lookup name. +\ Hashing function: Use the lower bits of the first character in the +\ name to select one of #threads threads in the array pointed-to by +\ the user number in the parameter field of voc-acf. +code hash (s str-addr voc-acf -- thread ) + \ The next 2 lines are equivalent to ">threads", which in this + \ implementation happens to be the same as ">body >user" + lwz tos,/ccf(tos) \ Get the user number + add tos,tos,up \ Find the address of the threads + + pop-to-t0 \ str-adr in t0 + lbz t0,1(t0) \ First byte of string + #threads-t 1- andi. t0,t0,* \ Extract low bits + add t0,t0,t0 + add t0,t0,t0 \ Convert index to longword offset + add tos,tos,t0 +c; + +\ Search a vocabulary thread (link) for a name matching string. +\ If found, return its code field address and -1 if immediate, 1 if not +\ immediate. If not found, return the string and 0. + +\ Name field: +\ name: forth-style packed string, no tag bits +\ flag: 40 bit is immediate bit +\ Padding is optionally inserted between the name and the flags +\ so that the byte after the flag byte is on an even boundary. + +[ifdef] notdef +code (find) (s string link origin -- acf -1 | acf 1 | string 0 ) + pop-tos \ link in tos + +\ Registers: +\ tos alf of word being tested +\ t0 string +\ t1 name being tested +\ t2 # of characters left to test +\ string is kept on the top of the external stack + +\ 1 F: always brif \ Branch to test at end of list +\ begin + begin cmp 0,0,tos,base <> while + addi t1,tos,/token \ Get name address of word to test + second-to-t0 \ Get string address + lbz t2,0(t0) \ get the name field length + addi t0,t0,-1 \ Account for pre-increment + addi t1,t1,-1 \ Account for pre-increment + begin + lbzu t3,1(t0) \ Compare 2 characters + lbzu t4,1(t1) + cmp 0,0,t3,t4 = while \ Keep looking as long as characters match + addic. t2,t2,-1 \ Decrement byte counter + 0< if \ If we've tested all chars, the names match. + lbzu tos,1(t1) \ Get flags byte into tos register + + addi t1,t1,/cf \ Now find the code field by +\ addi t2,r0,-/cf +\ and t1,t1,t2 \ aligning to the next 4 byte boundary + rlwinm t1,t1,0,0,29 + + andi. t2,tos,h#20 \ Test the alias flag + 0<> if + lwz t1,0(t1) \ Get acf + add t1,t1,base \ Relocate + then + + stw t1,0(sp) \ Replace string on stack with acf + andi. t2,tos,h#40 \ Test the immediate flag + 0<> if + addi tos,r0,1 \ Immediate + else + addi tos,r0,-1 \ Not immediate + then + next + then + repeat + + \ The names did not match, so check the next name in the list + lwz tos,0(tos) \ Fetch next link ( next acf ) + add tos,tos,base \ Relocate +1 L: +\ cmp 0,0,tos,base +\ = until +repeat + + \ If we get here, we've checked all the names with no luck + addi tos,r0,0 +c; +[then] + +code ($find-next) (s adr len link -- adr len alf true | adr len false ) +\ Registers: +\ tos alf of word being tested +\ t0 string +\ t1 anf of word being tested +\ t2 saves ctr register value +\ t3 character from string +\ t4 character from name +\ t5 string length +\ string is kept on the top of the external stack + + lwz t0,1cell(sp) \ Get string address + lwz t5,0(sp) \ get the name field length + addi t0,t0,-1 \ Account for pre-increment + + mfspr t2,ctr \ Save CTR register + + ahead + begin + addi tos,tos,-/token \ >link + addi t1,tos,-2 \ t1 points before count byte at string *end* + subfc t1,t5,t1 \ t1 points to beginning of string + \ ( Use subfc for POWER compatibility) + mr t6,t0 + + mtspr ctr,t5 \ Set starting loop index + begin + lbzu t4,1(t1) \ Get character from name field + lbzu t3,1(t6) \ Get character from search string + cmp 0,0,t3,t4 \ Compare 2 characters + bc 8,2,* \ Branch while characters match and count non0 + + = if \ If we've tested all name chars, we + lbzu t4,1(t1) \ may have a match; check the count byte + andi. t4,t4,h#1f + cmp 0,0,t4,t5 \ Compare count bytes + = if + push-tos \ Push alf above pstr + addi tos,r0,-1 \ True on top of stack means "found" + mtspr ctr,t2 \ Restore CTR register + next + then + then + + but then + \ The names did not match, so check the next name in the list + lwz tos,0(tos) \ Fetch next link ( next acf ) + add tos,tos,base \ Relocate + cmp 0,0,tos,base + = until + + \ If we get here, we've checked all the names with no luck + addi tos,r0,0 + mtspr ctr,t2 \ Restore CTR register +c; + +: ?negate (s n1 n2 -- n3 ) if negate then ; + +code wflip (s l1 -- l2 ) \ word swap + rlwinm t0,tos,16,16,31 \ high half to low half + rlwimi t0,tos,16,0,15 \ low to high and insert + mr tos,t0 +c; + +code lwflip ( l -- l' ) + rlwinm t0,tos,16,0,15 + rlwimi t0,tos,16,16,31 + mr tos,t0 +c; + +code lbflip ( l -- l' ) + rlwinm t0,tos,24,0,7 + rlwimi t0,tos,8,8,15 + rlwimi t0,tos,24,16,23 + rlwimi t0,tos,8,24,31 + mr tos,t0 +c; + +code wbflip ( w -- w' ) + rlwinm t0,tos,8,16,23 + rlwimi t0,tos,24,24,31 + mr tos,t0 +c; + +code lwflips ( adr len -- ) + lwz t0,0(sp) \ adr in t0, len in tos + + addi tos,tos,3 \ Round up to longword boundary + rlwinm. tos,tos,30,2,31 \ Divide by 4 + + 0<> if + addi t0,t0,-4 \ Account for pre-increment + addi r0,r0,0 + + mtspr ctr,tos + + begin + lwzu t1,4(t0) \ Load one way + rlwinm t2,t1,16,0,15 + rlwimi t2,t1,16,16,31 + stw t2,0(t0) \ Store the other + countdown + + mtspr ctr,up + then + + lwz tos,1cell(sp) + addi sp,sp,2cells +c; + +code lbflips ( adr len -- ) + lwz t0,0(sp) \ adr in t0, len in tos + + addi tos,tos,3 \ Round up to longword boundary + rlwinm. tos,tos,30,2,31 \ Divide by 4 + + 0<> if + addi t0,t0,-4 \ Account for pre-increment + addi r0,r0,0 + + mtspr ctr,tos + + begin + lwzu t1,4(t0) \ Load one way + stwbrx t1,r0,t0 \ Store the other + countdown + + mtspr ctr,up + then + + lwz tos,1cell(sp) + addi sp,sp,2cells +c; + +code wbflips ( adr len -- ) + lwz t0,0(sp) \ adr in t0, len in tos + + addi tos,tos,1 \ Round up to longword boundary + rlwinm. tos,tos,31,1,31 \ Divide by 4 + + 0<> if + addi t0,t0,-2 \ Account for pre-increment + addi r0,r0,0 + + mtspr ctr,tos + + begin + lhzu t1,2(t0) \ Load one way + sthbrx t1,r0,t0 \ Store the other + countdown + + mtspr ctr,up + then + + lwz tos,1cell(sp) + addi sp,sp,2cells +c; + +\ these are not used. remove? +: cset (s byte-mask adr -- ) tuck c@ or swap c! ; +: creset (s byte-mask adr -- ) swap invert over c@ and swap c! ; +: ctoggle (s byte-mask adr -- ) tuck c@ xor swap c! ; +: toggle (s adr byte-mask -- ) swap ctoggle ; + + +code s->l (s n.signed -- l ) c; +code n->l (s n.unsigned -- l ) c; +code n->a (s n -- a ) c; +code l->n (s l -- n ) c; +code l->w (s l -- w ) andi. tos,tos,h#ffff c; +code n->w (s n -- w ) andi. tos,tos,h#ffff c; +code w->l (s w -- l ) + andi. t0,tos,h#8000 0<> if + set t1,h#ffff.0000 + or tos,tos,t1 + then +c; + + +code l>r (s l -- ) stwu tos,-1cell(rp) pop-tos c; +code lr> (s -- l ) push-tos lwz tos,0(rp) rdrop c; +code lr@ (s -- l ) push-tos lwz tos,0(rp) c; + +code /t* (s n -- n*/t ) add tos,tos,tos add tos,tos,tos c; + +[ifdef] oldmeta +: >name ( acf -- anf ) + 1- begin 1- dup c@ bl > until \ Find the end of the name + /token 1- invert and \ Move to token boundary + begin dup c@ bl >= while /token - repeat +; +[then] +#align-t constant #align +#acf-align-t constant #acf-align +#talign-t constant #talign + +: align (s -- ) #align (align) ; +: taligned (s adr -- adr' ) #talign round-up ; +: talign (s -- ) #talign (align) ; + +\ 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/ppc/kernel.bth =================================================================== --- cpu/ppc/kernel.bth (rev 0) +++ cpu/ppc/kernel.bth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,107 @@ +purpose: Load file for PowerPC Forth kernel +\ See license at end of file + +command: &builder &this +build-now + +\ ' $report-name is include-hook ' noop is include-exit-hook + ' noop is include-hook ' noop is include-exit-hook + + +\ Don't accept ',' as numeric punctuation because doing so makes +\ the forward referencing mechanism think that "c," is a number! +ascii . ascii , npatch numdelim? + +warning off \ Turn OFF the warning messages + +alias constant-h constant + +fload ${BP}/forth/kernel/conft32.fth +fload ${BP}/forth/kernel/meta1.fth + +only forth also meta also definitions +: sx .s cr ; +\needs ppc-assembler fload ${BP}/cpu/ppc/assem.fth + +only forth also meta definitions +: assembler ( -- ) ppc-assembler ; + +only forth also meta also assembler definitions +\needs L: fload ${BP}/forth/lib/loclabel.fth +init-labels + +only forth also definitions + +fload ${BP}/forth/kernel/swapmap.fth +\ : : : lastacf .name cr ; +fload ${BP}/cpu/ppc/target.fth +fload ${BP}/forth/kernel/forward.fth +fload ${BP}/cpu/ppc/fixvoc.fth +fload ${BP}/forth/kernel/metacompile.fth + +only forth meta also forth also definitions +sometimes-headers +only forth also definitions + +fload ${BP}/cpu/ppc/metainit.fth + +\ Comment out the following line(s) when debugging +-1 threshold ! \ Turn OFF ALL debugging messages +warning-t off \ Turn OFF target warning messages + +\ Uncomment the following line(s) for more debug output +\ show? on 1 granularity ! 1 threshold ! +\ warning-t on + +fload ${BP}/cpu/ppc/kerncode.fth + +fload ${BP}/forth/kernel/uservars.fth +fload ${BP}/forth/kernel/double.fth + +fload ${BP}/forth/lib/bitops.fth +fload ${BP}/cpu/ppc/kernrel.fth + +fload ${BP}/forth/lib/struct.fth + +fload ${BP}/cpu/ppc/unalign.fth + +fload ${BP}/forth/kernel/kernel.fth + +fload ${BP}/forth/kernel/sysio.fth +fload ${BP}/forth/lib/dumballo.fth +fload ${BP}/cpu/ppc/syscall.fth + +fload ${BP}/cpu/ppc/filecode.fth + +fload ${BP}/cpu/ppc/boot.fth +fload ${BP}/forth/kernel/init.fth +fload ${BP}/cpu/ppc/finish.fth + +fload ${BP}/cpu/ppc/savemeta.fth + +.( --- Saving kernel.dic ---) "" kernel.dic save-meta +cr + +\ 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/ppc/kernrel.fth =================================================================== --- cpu/ppc/kernrel.fth (rev 0) +++ cpu/ppc/kernrel.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,69 @@ +purpose: Maintain a byte swap table for the Forth dictionary +\ See license at end of file + +decimal + +0 value swap-map + +\ The swap map has one bit for every 32-bit word, since we assume +\ that relocated longwords must start on a 32-bit boundary +d# 32 constant bits/swapbit + +\ Number of bytes in bitmap +: >swap-map-size ( end-adr -- ) + origin - bits/swapbit /mod swap if 1+ then +; +: /swap-map ( -- n ) memtop @ >swap-map-size ; + +defer set-swap-bit +: (set-swap-bit) ( addr -- ) + origin - 2 >> ( lword-index ) + dup 3 >> /swap-map u< if swap-map bitset else drop then +; + +\ The upper endpoint must be aligned in case the lower endpoint +\ is unaligned and the lower endpoint straddles an alignment boundary. +\ In that case, if we didn't align the upper endpoint, the last +\ word of the range would not be marked. +: note-string ( adr len -- adr len ) + 2dup over + aligned swap ?do i set-swap-bit /n +loop +; + +defer init-swap-map +: (init-swap-map) ( -- ) + /swap-map alloc-mem is swap-map + swap-map /swap-map erase + \ Copy in old swap map + here user-size + swap-map here >swap-map-size move + ['] (set-swap-bit) is set-swap-bit +; +' (init-swap-map) is init-swap-map + +\ Plug this into init-swap-map to turn off swap-map management +: no-swap-map ( -- ) ['] drop is set-swap-bit ; + +: init ( -- ) init init-swap-map ; + +\ 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/ppc/loadmach.fth =================================================================== --- cpu/ppc/loadmach.fth (rev 0) +++ cpu/ppc/loadmach.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,73 @@ +purpose: Load file for machine-dependent Forth tools +\ See license at end of file + +assembler? [if] +fload ${BP}/cpu/ppc/assem.fth +fload ${BP}/cpu/ppc/code.fth +fload ${BP}/forth/lib/loclabel.fth +[else] +transient fload ${BP}/cpu/ppc/assem.fth resident +fload ${BP}/cpu/ppc/code.fth +transient fload ${BP}/forth/lib/loclabel.fth resident +[then] + +fload ${BP}/cpu/ppc/decompm.fth + +: be-l, ( l -- ) here 4 note-string allot be-l! ; + +[ifndef] partial-no-heads transient [then] +fload ${BP}/forth/lib/binhdr.fth +fload ${BP}/cpu/ppc/savefort.fth +\ alias save-forth save-forth +[ifndef] partial-no-heads resident [then] + +fload ${BP}/forth/lib/instdis.fth + +fload ${BP}/cpu/ppc/objsup.fth +fload ${BP}/forth/lib/objects.fth + +fload ${BP}/cpu/ppc/call.fth \ C subroutine calls + +fload ${BP}/cpu/ppc/cpustate.fth +fload ${BP}/cpu/ppc/register.fth + +fload ${BP}/forth/lib/savedstk.fth +fload ${BP}/forth/lib/rstrace.fth +fload ${BP}/cpu/ppc/ftrace.fth +fload ${BP}/cpu/ppc/ctrace.fth + +fload ${BP}/cpu/ppc/debugm.fth \ Forth debugger support +fload ${BP}/forth/lib/debug.fth \ Forth debugger + +start-module \ Breakpointing +fload ${BP}/cpu/ppc/cpubpsup.fth \ Breakpoint support +fload ${BP}/forth/lib/breakpt.fth +end-module + +fload ${BP}/cpu/ppc/msr.fth \ Stuff in the Machine State Register +fload ${BP}/cpu/ppc/spr.fth \ Various special registers +fload ${BP}/cpu/ppc/catchexc.fth + +\ 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/ppc/loadvmem.fth =================================================================== --- cpu/ppc/loadvmem.fth (rev 0) +++ cpu/ppc/loadvmem.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,63 @@ +purpose: Load file for virtual memory node +\ See license at end of file + +headers +false value use-real-mode? +true value in-real-mode? +0 value /rm-tlbmiss + +fload ${BP}/ofw/core/allocmor.fth \ S Allow alloc-mem to use more memory + +dev / +new-device +" mmu" device-name +fload ${BP}/ofw/core/virtlist.fth \ Virtual memory allocator +fload ${BP}/ofw/core/maplist.fth \ Manage translation list +fload ${BP}/ofw/core/clntmap.fth \ OS callbacks for address translation +\ fload ${BP}/arch/prep/memcb.fth \ Memory allocation callback + +fload ${BP}/cpu/ppc/tlb.fth +fload ${BP}/cpu/ppc/tlbmiss.fth +fload ${BP}/cpu/ppc/htabmmu.fth +fload ${BP}/cpu/ppc/batfault.fth +fload ${BP}/cpu/ppc/batmap.fth +[ifdef] exponential +fload ${BP}/cpu/ppc/exptlb.fth +[then] + +: .t translations translation-node .list ; + +fload ${BP}/cpu/ppc/testmmu.fth + +' 2drop is ?splice + +finish-device +device-end + +: map? ( virtual -- ) " map?" mmu-node @ $call-method ; +: .t ( -- ) " .t" mmu-node @ $call-method ; + + +\ 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/ppc/metainit.fth =================================================================== --- cpu/ppc/metainit.fth (rev 0) +++ cpu/ppc/metainit.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,70 @@ +purpose: Metacompiler initialization +\ See license at end of file + +\ Debugging aids + +0 #words ! h# 480 threshold ! 10 granularity ! + +warning off + +metaon +meta definitions + +\ We want the kernel to be romable, so we put variables in the user area +:-h variable ( -- ) nuser ;-h +alias \m \ + +initmeta + +th 11000 alloc-mem target-image \ Allocate space for the target image + +\ org sets the lowest address that is used by Forth kernel. +hex + +0.0000 org 0.0000 + voc-link-t token-t! + +200 equ ps-size + +assembler + +\ This is at the first location in the Forth image. + +\ init-forth is the initialization entry point. It should be called +\ exactly once, with arguments (dictionary_start, dictionary_size). +\ init-forth sets up some global variables which allow Forth to locate +\ its RAM areas, including the data stack, return stack, user area, +\ cpu-state save area, and dictionary. + +hex +mlabel cld + b 0 \ The address will be fixed later. + nop \ Delay slot + nop + nop + +meta + +\ 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/ppc/metarel.fth =================================================================== --- cpu/ppc/metarel.fth (rev 0) +++ cpu/ppc/metarel.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,50 @@ +purpose: Maintain a byte swap table for the Forth kernel during metacompilation +\ See license at end of file + +decimal + +only forth also meta also definitions +h# 10000 constant max-kernel-t + +\ The swap map has one bit for every 32-bit word, since we assume +\ that relocated longwords must start on a 32-bit boundary +d# 32 constant bits/swapbit-t + +\ Number of bytes in bitmap +: >swap-map-size-t ( end-adr -- ) + origin-t - bits/swapbit-t /mod swap if 1+ then +; + +max-kernel-t >swap-map-size-t constant /swap-map-t \ Number of bytes in bitmap +/swap-map-t buffer: swap-map-t + +: set-swap-bit-t ( addr -- ) origin-t - 2 >> swap-map-t bitset ; +: note-string-t ( adr len -- adr len ) + 2dup bounds ?do i set-swap-bit-t /n +loop +; + +: init-swap-t ( -- ) swap-map-t /swap-map-t erase ; + +\ 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/ppc/minifth.fth =================================================================== --- cpu/ppc/minifth.fth (rev 0) +++ cpu/ppc/minifth.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,986 @@ +purpose: Forth-like peek/poke/memory-test monitor using only registers +\ See license at end of file + +\ Requires the following external definitions: +\ isa-io-pa ( -- n ) \ Returns the base address of IO space +\ init-serial ( -- ) \ May destroy r3-r7 +\ getchar ( -- r3: char ) \ May destroy r3-r7 +\ putchar ( r3: char -- ) \ May destroy r3-r7 + +\ The following code must run entirely from registers. The following +\ register allocation conventions are used: +\ r3-r7 Argument passing and return, scratch registers for subroutines +\ r8 Return address for level 1 routines, scratch use for level 2+ +\ r9 Return address for level 2 routines, scratch use for level 3+ +\ r10-r11 Used as needed within higher-level subroutines +\ r12 Global state flags +\ r13 As-yet unassigned +\ r14-r17 4-element stack +\ r18 script pointer + +\ Send a space character to the output device. +label putspace ( -- ) \ Level 0, destroys: r3-r7 (because it calls putchar) + set r3,h#20 + putchar b * +end-code + +\ Send a newline sequence (CR-LF) to the output device. +label putcr ( -- ) \ Level 1, destroys: r3-r8 (because it calls putchar) + mfspr r8,lr + set r3,h#0d putchar bl * + set r3,h#0a putchar bl * + mtspr lr,r8 + bclr 20,0 +end-code + +\ Send ": " to the output device. +label putcolon ( -- ) \ Level 1, destroys: r3-r8 + mfspr r8,lr + char : set r3,* putchar bl * + putspace bl * + mtspr lr,r8 + bclr 20,0 +end-code + +\ Accept input characters, packing up to 8 of them into the register pair +\ r3,r4. The first character is placed in the least-significant byte of +\ r4, and for each subsequent character, the contents of r3,r4 are shifted +\ left by 8 bits to make room for the new character (shifting the most- +\ significant byte of r4 into the least-significant byte of r3). +\ A backspace character causes r3,r4 to be shifted right, discarding the +\ previous character. +\ The process terminates when a space or carriage return is seen. The +\ terminating character is not stored in r3,r4. Any unused character +\ positions in r3,r4 contain binary 0 bytes. +label getword ( -- r3,r4 ) \ Level 4, destroys r3-r11 + mfspr r9,lr + set r10,0 \ Clear high temporary holding register + set r11,0 \ Clear low temporary holding register + + begin + andi. r3,r12,4 0<> if + lbz r3,0(r18) + addi r18,r18,1 + \ Translate linefeed to carriage return in script mode + cmpi 0,0,r3,h#0a = if set r3,h#0d then + else + getchar bl * ( char in r3 ) + then + + cmpi 0,0,r3,h#0d = if \ carriage return + andi. r0,r12,8 0= if \ Check no-echo flag + putcr bl * \ Echo CR-LF + then + mr r3,r10 mr r4,r11 \ Return packed word in r3,r4 + mtspr lr,r9 + bclr 20,0 \ Return + then + + control h cmpi 0,0,r3,* <> if \ backspace + cmpi 0,0,r3,h#20 = if \ white space + andi. r0,r12,8 0= if \ Check no-echo flag + \ In quiet mode, echo the input character; otherwise echo CR-LF + andi. r0,r12,2 0<> if putchar bl * else putcr bl * then + then + mr r3,r10 mr r4,r11 \ Return packed word in r3,r4 + mtspr lr,r9 + bclr 20,0 \ Return + then + then + + mr r8,r3 \ Save character + andi. r0,r12,8 0= if \ Check no-echo flag + putchar bl * \ Echo the character + then + + control h cmpi 0,0,r8,* = if + \ Double-shift right one byte + rlwinm r11,r11,24,8,31 + rlwimi r11,r10,24,0,7 + rlwinm r10,r10,24,0,23 + else + \ Double-shift left one byte and merge in the new character + rlwinm r10,r10,8,0,23 + rlwimi r10,r11,8,24,31 + rlwinm r11,r11,8,0,23 + or r11,r11,r8 + then + again +end-code + +\ Convert the ASCII hexadecimal characters packed into r3,r4 into a +\ 32-bit binary number, returning the result in r3 and non-zero in r4 +\ if the operation succeeded. +\ If the operation failed (because of the presence of non-hex characters), +\ return 0 in r4, and an undefined value in r3. + +\ Level 1, destroys: r3-r8 +label convert-number ( r3,r4: ascii -- r3: binary r4: okay? ) + mr r8,r3 \ Move high 4 ASCII characters away from r3 + set r3,0 \ Accumulator for output + + set r6,8 \ Loop counter - convert 8 nibbles + mtspr ctr,r6 + begin + \ Shift r8,r4 left one byte, putting result in r6 + rlwinm r6,r8,8,24,31 \ High byte in r6 + rlwinm r8,r8,8,0,23 \ Shift high word + rlwimi r8,r4,8,24,31 \ Merge from low word to high word + rlwinm r4,r4,8,0,23 \ Shift low word + + cmpi 0,0,r6,0 <> if + + char 0 cmpi 0,0,r6,* + < if + set r4,0 + bclr 20,0 \ Exit if < '0' + then + + char 9 cmpi 0,0,r6,* <= if \ Good digit from 0-9 + char 0 negate addi r6,r6,* + else + char A cmpi 0,0,r6,* + < if + set r4,0 + bclr 20,0 \ Exit if < 'A' + then + + char F cmpi 0,0,r6,* <= if + char A d# 10 - negate addi r6,r6,* + else + char a cmpi 0,0,r6,* \ possibly lower case hex digit + < if + set r4,0 + bclr 20,0 \ Exit if < 'a' + then + + char f cmpi 0,0,r6,* + > if + set r4,0 + bclr 20,0 \ Exit if > 'f' + then + + char a d# 10 - negate addi r6,r6,* + then + then + rlwinm r3,r3,4,0,27 + or r3,r3,r6 + then + countdown + + set r4,-1 + + bclr 20,0 +end-code + +\ Display the number in r3 as an 8-digit unsigned hexadecimal number +label dot ( r3 -- ) \ Level 3, destroys: r3-r10 + mfspr r8,lr + set r9,8 + mtspr ctr,r9 + mr r9,r3 + begin + rlwinm r9,r9,4,0,31 + andi. r3,r9,h#f + cmpi 0,0,r3,10 + >= if + char a d# 10 - addi r3,r3,* + else + char 0 addi r3,r3,* + then + putchar bl * + countdown + + set r3,h#20 putchar bl * + + mtspr lr,r8 + bclr 20,0 +end-code + +transient +\ Macros for managing the mini-stack +: pop1 ( -- ) + " mr r14,r15 mr r15,r16 mr r16,r17" evaluate +; +: pop2 ( -- ) + " mr r14,r16 mr r15,r17 mr r16,r17" evaluate +; +: pop3 ( -- ) + " mr r14,r17 mr r15,r17 mr r16,r17" evaluate +; +: push1 ( -- ) + " mr r17,r16 mr r16,r15 mr r15,r15" evaluate +; +: spush ( -- ) + " mr r17,r16 mr r16,r15 mr r15,r14 mr r14,r3" evaluate +; + +\ Macros to assemble code to begin and end command definitions +8 buffer: name-buf + +\ Start a command definition +: t: ( "name" -- cond ) + \ Get a name from the input stream at compile time and pack it + \ into a buffer in the same form it will appear in the register + \ pair when the mini-interpreter is executed at run-time + name-buf 8 erase ( ) + parse-word ( adr len ) + dup 8 - 0 max /string ( adr' len' ) \ Keep last 8 + 8 min 8 over - name-buf + swap move ( ) + + \ Assemble code to compare the register-pair contents against the name. + name-buf be-l@ " set r6,* cmp 0,0,r3,r6 = if" evaluate + name-buf 4 + be-l@ " set r6,* cmp 0,0,r4,r6 then = if" evaluate +; + +\ End a command definition by: +\ a) Assembling code to jump back to the beginning of the loop after the +\ current definition has executed ("over again") +\ b) Resolve the "if" (conditional branch) that skips the current definition +\ if the name the user has entered does not match this definition. + +: t; ( loop-begin-adr if-adr --- loop-begin-adr ) + " over again then" evaluate +; +resident + +label minifth ( -- <does not return> ) \ Level 5 + init-serial bl * + +[ifdef] notdef +set r10,0 +begin + mr r3,r10 + dot bl * + putcr bl * + addi r10,r10,1 +again +[then] + + set r14,0 set r15,0 set r16,0 set r17,0 \ Init stack + set r12,0 \ Init loop flag + + begin ( loop-begin-adr ) + andi. r0,r12,6 0= if \ Display stack if neither silent nor scripting + \ mr r3,r17 dot bl * + mr r3,r16 dot bl * + mr r3,r15 dot bl * + mr r3,r14 dot bl * + char o set r3,* putchar bl * + char k set r3,* putchar bl * + putspace bl * + then + + getword bl * \ Result in r3 and r4 + + \ If the word is null (i.e. a bare space or return), do nothing + cmpi 0,0,r3,0 = if cmpi 0,0,r4,0 then + yet <> until \ Branch back to the "begin" if r3,r4 = 0 + + t: showstack ( -- ) + rlwinm r12,r12,0,31,29 \ Clear the 2 bit + t; + + t: quiet ( -- ) + or r12,r12,2 + t; + + t: clear ( ?? -- ) + set r14,0 set r15,0 set r16,0 set r17,0 \ Init stack + t; + + t: @ ( adr -- n ) + andi. r0,r12,1 <> if + begin lwz r3,0(r14) again + then + lwz r14,0(r14) + t; + + t: ! ( n adr -- ) + andi. r0,r12,1 <> if + begin stw r15,0(r14) again + then + stw r15,0(r14) + pop2 + t; + + t: l@ ( adr -- l ) + andi. r0,r12,1 <> if + begin lwz r3,0(r14) again + then + lwz r14,0(r14) + t; + + t: l! ( l adr -- ) + andi. r0,r12,1 <> if + begin stw r15,0(r14) again + then + stw r15,0(r14) + pop2 + t; + + t: c@ ( adr -- b ) + andi. r0,r12,1 <> if + begin lbz r3,0(r14) again + then + lbz r14,0(r14) + t; + + t: c! ( b adr -- ) + andi. r0,r12,1 <> if + begin stb r15,0(r14) again + then + stb r15,0(r14) + pop2 + t; + + t: w@ ( adr -- w ) + andi. r0,r12,1 <> if + begin lhz r3,0(r14) again + then + lhz r14,0(r14) + t; + + t: w! ( w adr -- ) + andi. r0,r12,1 <> if + begin sth r15,0(r14) again + then + sth r15,0(r14) + pop2 + t; + + t: pc@ ( port# -- b ) + isa-io-pa set r3,* + andi. r0,r12,1 <> if + begin lbzx r4,r14,r3 again + then + + lbzx r14,r14,r3 + t; + + t: pc! ( b port# -- ) + isa-io-pa set r3,* + andi. r0,r12,1 <> if + begin stbx r15,r14,r3 again + then + stbx r15,r14,r3 + pop2 + t; + + t: pw@ ( port# -- w ) + isa-io-pa set r3,* + andi. r0,r12,1 <> if + begin lhzx r4,r14,r3 again + then + lhzx r14,r14,r3 + t; + + t: pw! ( w port# -- ) + isa-io-pa set r3,* + andi. r0,r12,1 <> if + begin sthx r15,r14,r3 again + then + sthx r15,r14,r3 + pop2 + t; + + t: pl@ ( port# -- l ) + isa-io-pa set r3,* + andi. r0,r12,1 <> if + begin lwzx r4,r14,r3 again + then + lwzx r14,r14,r3 + t; + + t: pl! ( l port# -- ) + isa-io-pa set r3,* + andi. r0,r12,1 <> if + begin stwx r15,r14,r3 again + then + stwx r15,r14,r3 + pop2 + t; + + t: config-l! ( l config-adr -- ) + set r3,h#8000.0000 + or r14,r14,r3 \ Set access enable bit + config-addr set r3,* + stwbrx r14,0,r3 \ Set address + sync + config-data set r3,* + andi. r0,r12,1 <> if + begin stwbrx r15,0,r3 sync again + then + stwbrx r15,0,r3 sync + pop2 + t; + + t: cl! ( l config-adr -- ) \ Shorter name + set r3,h#8000.0000 + or r14,r14,r3 \ Set access enable bit + config-addr set r3,* + stwbrx r14,0,r3 \ Set address + sync + config-data set r3,* + andi. r0,r12,1 <> if + begin stwbrx r15,0,r3 sync again + then + stwbrx r15,0,r3 sync + pop2 + t; + + t: config-l@ ( config-adr -- l ) + set r3,h#8000.0000 + or r14,r14,r3 \ Set access enable bit + config-addr set r3,* + stwbrx r14,0,r3 \ Set address + sync + config-data set r3,* + andi. r0,r12,1 <> if + begin lwbrx r14,0,r3 sync again + then + lwbrx r14,0,r3 sync + t; + + t: cl@ ( config-adr -- l ) \ Shorter name + set r3,h#8000.0000 + or r14,r14,r3 \ Set access enable bit + config-addr set r3,* + stwbrx r14,0,r3 \ Set address + sync + config-data set r3,* + andi. r0,r12,1 <> if + begin lwbrx r14,0,r3 sync again + then + lwbrx r14,0,r3 sync + t; + + t: + ( n1 n2 -- n1+n2 ) + add r14,r15,r14 mr r15,r16 mr r16,r17 + t; + + t: - ( n1 n2 -- n1-n2 ) + subf r14,r14,r15 mr r15,r16 mr r16,r17 + t; + + t: and ( n1 n2 -- n1&n2 ) + and r14,r15,r14 mr r15,r16 mr r16,r17 + t; + + t: or ( n1 n2 -- n1|n2 ) + or r14,r15,r14 mr r15,r16 mr r16,r17 + t; + + t: xor ( n1 n2 -- n1^n2 ) + xor r14,r15,r14 mr r15,r16 mr r16,r17 + t; + + t: lshift ( n1 n2 -- n1<<n2 ) + slw r14,r14,r15 mr r15,r16 mr r16,r17 + t; + + t: rshift ( n1 n2 -- n1>>n2 ) + srw r14,r14,r15 mr r15,r16 mr r16,r17 + t; + + t: invert ( n -- ~n ) + nor r14,r14,r14 + t; + + t: negate ( n -- -n ) + neg r14,r14 + t; + + t: spin ( -- ) \ Modifies next @/!-class command to loop forever + set r12,1 + t; + + t: * ( n1 n2 -- n1*n2 ) + mullw r14,r15,r14 + t; + + t: . ( n -- ) + mr r3,r14 + dot bl * + putcr bl * + pop1 + t; + + t: move ( src dst len -- ) + cmpi 0,0,r14,0 + <> if + cmpl 0,0,r15,r16 + < if + begin + lbz r3,0(r16) + addi r16,r16,1 + stb r3,0(r15) + addi r15,r15,1 + addic. r14,r14,-1 + 0= until + else + begin + addic. r14,r14,-1 + lbzx r3,r16,r14 + stbx r3,r15,r14 + 0= until + then + then + pop3 + t; + + t: compare ( adr1 adr2 len -- -1 | offset ) + mr r4,r14 \ Save len for later + set r3,-1 \ -1 - provisional return value + addi r14,r14,1 + begin + addic. r14,r14,-1 + 0> while + lbz r5,0(r15) + lbz r6,0(r16) + cmp 0,0,r5,r6 + <> if subf. r3,r14,r4 then + <> until + then + pop3 + push1 + mr r14,r3 + t; + + t: fill ( adr len b -- ) + cmpi 0,0,r15,0 <> if + addi r16,r16,-1 + mtspr ctr,r15 + begin + stbu r14,1(r16) + countdown + then + pop3 + t; + + t: lfill ( adr len l -- ) + cmpi 0,0,r15,0 <> if + addi r16,r16,-4 +\ rlwinm r15,r15,2,0,29 + rlwinm r15,r15,30,2,31 + mtspr ctr,r15 + begin + stwu r14,4(r16) + countdown + then + pop3 + t; + + t: afill ( adr len -- ) + cmpi 0,0,r14,0 <> if +\ rlwinm r14,r14,2,0,29 + rlwinm r14,r14,30,2,31 + mtspr ctr,r14 + begin + stw r15,(r15) + addi r15,r15,4 + countdown + then + pop2 + t; + + t: check ( adr len b -- ) + addi r16,r16,-1 + begin + addic. r15,r15,-1 + >= while + lbzu r11,1(r16) + cmp 0,0,r11,r14 + <> if + mr r3,r16 dot bl * + putcolon bl * + mr r3,r11 dot bl * + putcr bl * + then + repeat + + pop3 + t; + + t: lcheck ( adr len l -- ) + addi r16,r16,-4 + begin + addic. r15,r15,-4 + >= while + lwzu r11,4(r16) + cmp 0,0,r11,r14 + <> if + mr r3,r16 dot bl * + putcolon bl * + mr r3,r11 dot bl * + putcr bl * + then + repeat + pop3 + t; + + t: acheck ( adr len -- ) + addi r15,r15,-4 + begin + addic. r14,r14,-4 + >= while + lwzu r11,4(r15) + cmp 0,0,r11,r15 + <> if + mr r3,r15 dot bl * + putcolon bl * + mr r3,r11 dot bl * + putcr bl * + then + repeat + pop2 + t; + + t: erase ( adr len -- ) + set r3,0 + cmpi 0,0,r14,0 <> if + addi r15,r15,-1 + begin + stbu r3,1(r15) + countdown + then + pop2 + t; + + t: dump ( adr len -- ) + begin + addic. r14,r14,-1 + >= while + mr r3,r15 dot bl * + putcolon bl * + lbz r3,0(r15) dot bl * + putcr bl * + addi r15,r15,1 + repeat + pop2 + t; + + t: ldump ( adr len -- ) + begin + addic. r14,r14,-4 + >= while + mr r3,r15 dot bl * + putcolon bl * + lwz r3,0(r15) dot bl * + putcr bl * + addi r15,r15,4 + repeat + pop2 + t; + + t: dup ( n -- n n ) + mr r17,r16 mr r16,r15 mr r15,r14 + t; + + t: drop ( n -- ) + mr r14,r15 mr r15,r16 mr r16,r17 + t; + + t: swap ( n1 n2 -- n2 n1 ) + mr r3,r15 mr r15,r14 mr r14,r3 + t; + + t: over ( n1 n2 -- n1 n2 n1 ) + mr r17,r16 mr r16,r15 mr r15,r14 mr r14,r16 + t; + + t: rot ( n1 n2 n3 -- n2 n3 n1 ) + mr r3,r16 mr r16,r15 mr r15,r14 mr r14,r3 + t; + + t: -rot ( n1 n2 n3 -- n3 n1 n2 ) + mr r3,r16 mr r16,r14 mr r14,r15 mr r15,r3 + t; + + t: script ( address -- ) + mr r18,r14 + ori r12,r12,h#c \ Set script and no-echo flags + pop1 + t; + + t: rom-script ( offset -- ) + rom-pa set r10,* + add r18,r14,r10 + ori r12,r12,h#c \ Set script and no-echo flags + pop1 + t; + + t: fexit ( -- ) + rlwinm r12,r12,0,30,27 \ Clear script and no-echo flags (h#0c) + t; + + t: scripts ( -- ) + set r10,0 + rom-pa h# 10000 + 1- set r11,* + begin + lbzu r0,1(r11) + ascii \ cmpi 0,0,r0,* \ If the script aread begings + = if \ with a comment character + \ display "s#: " + ascii s set r3,* putchar bl * + ascii 0 addi r3,r10,* putchar bl * + ascii : set r3,* putchar bl * + putspace bl * + begin \ display the first comment line + lbzu r3,1(r11) \ Get comment byte + cmpi 0,0,r3,h#0d \ Carriage return? + <> if cmpi 0,0,r3,h#0a then \ Line feed? + <> while + putchar bl * + repeat + putcr bl * + then + rlwinm r11,r11,0,0,19 \ Clear 12 low bits + addi r11,r11,h#fff \ Advance to next script + addi r10,r10,1 + cmpi 0,0,r10,10 + = until + t; + + t: s0 ( -- ) + rom-pa h# 10000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s1 ( -- ) + rom-pa h# 11000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s2 ( -- ) + rom-pa h# 12000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s3 ( -- ) + rom-pa h# 13000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s4 ( -- ) + rom-pa h# 14000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s5 ( -- ) + rom-pa h# 15000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s6 ( -- ) + rom-pa h# 16000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s7 ( -- ) + rom-pa h# 17000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s8 ( -- ) + rom-pa h# 18000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + t: s9 ( -- ) + rom-pa h# 19000 + 1- set r18,* + ori r12,r12,h#c \ Set script and no-echo flags + t; + + \ The original intention of "no-echo" and its inverse "echo" was + \ to create a capability like "dl" whereby one could download a + \ script over the serial line, but without requiring the use of + \ memory. However, this has the serious problem that there is + \ no flow control, so commands that can take a long time (like + \ memory tests) potentially cause input overrun. Consequently, + \ it's better to use quiet mode. However, quiet mode has its own + \ problem: few if any terminal programs support its character-echo + \ flow control technique. Character-echo flow control is not + \ particularly great anyway - it can be fooled by generated output + \ that happens to contain the next input character. + t: no-echo ( -- ) + ori r12,r12,h#8 \ Set no-echo flag + t; + + t: echo ( -- ) + rlwinm r12,r12,0,29,27 \ Clear no-echo flag + t; + + t: cr ( -- ) + putcr bl * + t; + + t: key ( -- char ) + getchar bl * + push1 mr r14,r3 + t; + + t: emit ( char -- ) + mr r3,r14 + putchar bl * + pop1 + t; + + \ This is useful for diagnostics in script mode, but essentially + \ useless otherwise. + t: .( ( "string" -- ) + begin + andi. r3,r12,4 0<> if \ Script mode + lbz r3,0(r18) + addi r18,r18,1 + else \ Normal mode + getchar bl * ( char in r3 ) + then + char ) cmpi 0,0,r3,* + <> while + putchar bl * + repeat + t; + + \ This is useful for commentary in script mode, but essentially + \ useless otherwise. + t: \ ( "rest-of-line" -- ) + begin + andi. r3,r12,4 0<> if \ Script mode + lbz r3,0(r18) + else \ Normal mode + getchar bl * ( char in r3 ) + then + cmpi 0,0,r3,h#0a + <> if cmpi 0,0,r3,h#0d then + = until + t; + + t: goto ( address -- ) + mr r3,r11 mr r4,r12 mr r5,r13 + mtspr lr,r15 + bclr 20,0 + t; + + t: gettext ( address -- length ) + addi r8,r14,-1 + begin + getchar bl * + cmpi 0,0,r3,4 \ Control-D (ASCII EOT) + <> while + stbu r0,1(r8) + repeat + + addi r8,r8,1 + subf r14,r14,r8 + t; + + t: getbytes ( address length -- ) + begin + addic. r14,r14,-1 + 0>= while + getchar bl * + stb r3,0(r15) + addi r15,r15,1 + repeat + pop2 + t; + +[ifdef] rom-pa + t: rom ( -- adr ) + push1 rom-pa set r14,* + t; +[then] + +[ifdef] isa-io-pa + t: io ( -- adr ) + push1 isa-io-pa set r14,* + t; +[then] + +[ifdef] mem0-pa + t: mem0 ( -- adr ) + push1 mem0-pa set r14,* + t; +[then] + +[ifdef] mem1-pa + t: mem1 ( -- adr ) + push1 mem1-pa set r14,* + t; +[then] + +[ifdef] mem2-pa + t: mem2 ( -- adr ) + push1 mem2-pa set r14,* + t; +[then] + +[ifdef] mem3-pa + t: mem3 ( -- adr ) + push1 mem3-pa set r14,* + t; +[then] + + t: 1m ( -- n ) + push1 set r14,h#100000 + t; + + t: 2m ( -- n ) + push1 set r14,h#200000 + t; + + t: 4m ( -- n ) + push1 set r14,h#400000 + t; + + t: 8m ( -- n ) + push1 set r14,h#800000 + t; + + t: 16m ( -- n ) + push1 set r14,h#1000000 + t; + + t: 32m ( -- n ) + push1 set r14,h#2000000 + t; + +[ifdef] load-nano-extras load-nano-extras [then] + + \ The word was not recognized; parse it as a number or complain + convert-number bl * cmpi 0,0,r4,0 <> if \ Number in r3 + \ Push the number + spush ( -- n ) + else + \ The word was neither recognized nor numeric; complain + char ? set r3,* putchar bl * putcr bl * + then + + again + +end-code + +\ 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/ppc/msr.fth =================================================================== --- cpu/ppc/msr.fth (rev 0) +++ cpu/ppc/msr.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,65 @@ +purpose: Machine Status Register access +\ See license at end of file + +code msr@ ( -- n ) + stwu tos,-4(sp) + mfmsr tos +c; +code msr! ( n -- ) + sync isync + mtmsr tos + sync isync + lwz tos,0(sp) + addi sp,sp,4 +c; + +h# 8000 constant interrupt-enable-bit +: interrupt-enable@ ( -- n ) msr@ interrupt-enable-bit and ; +: interrupt-enable! ( n -- ) + msr@ interrupt-enable-bit invert and or msr! +; + +headerless +: (enable-interrupts) ( -- ) msr@ interrupt-enable-bit or msr! ; +: (disable-interrupts) ( -- ) msr@ interrupt-enable-bit invert and msr! ; +: interrupts-enabled? ( -- yes? ) interrupt-enable@ ; + +code (lock) ( -- ) ( R: -- oldMSR ) + mfmsr t0 + stwu t0,-1cell(rp) + rlwinm t0,t0,0,17,15 \ Clear EE bit + mtmsr t0 +c; +code (unlock) ( -- ) ( R: oldMSR -- ) + lwz t0,0(rp) + mtmsr t0 + addi rp,rp,1cell +c; + +: mapping-on ( -- ) msr@ h# 30 or msr! ; +: mapping-off ( -- ) msr@ h# 30 invert and msr! ; +headers + +\ 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/ppc/ntctrace.fth =================================================================== --- cpu/ppc/ntctrace.fth (rev 0) +++ cpu/ppc/ntctrace.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,85 @@ +purpose: Stack backtrace for Microsoft/Motorola compiler +\ See license at end of file + +headerless +\ Search forward for a "bclr" instruction, then search backward for +\ "lwz r0,XXX(r1), then get the contents of that effective address. +: pc>caller ( fp pc -- call-point-adr ) + \ XXX we need to determine where we are in the function - if we are + \ before the place where the frame pointer is updated, or after the + \ place where it is restored, we must treat the function as a leaf + \ routine and get the caller address directly from LR. It is probably + \ a good idea to first check to see if the function is a pure leaf + \ routine, by searching for a "stwu r1,XX(r1)" instruction between + \ the beginning and the bclr. Hmmm... I wonder if the beginning + \ address of a leaf routine can be determined? It might not begin + \ with a "mfspr r0,lr". + + begin dup l@ h# 4e800020 <> while la1+ repeat ( fp end-adr ) + begin -1 la+ dup l@ d# 16 >> h# 8001 = until ( fp lwz-adr ) + l@ h# ffff and + l@ -1 la+ +; +\ Search forward for an "mfspr r0,lr" instruction +: pc>function ( pc -- entry-adr ) + begin dup l@ h# 7c0802a6 <> while -1 la+ repeat ( mfspr-r0,lr-adr ) +; + +\ Determine the stack frame size of the function containing the given PC +\ by finding the first "stwu r1,XXX(r1)" instruction in the function. +: pc>framesize ( pc -- /frame ) + pc>function + begin dup l@ d# 16 >> h# 9421 <> while la1+ repeat ( stwu-adr ) + + \ The offset is negative, so merge in the sign bits and negate it + l@ h# ffff invert or negate +; + +: .adr base @ >r hex 9 u.r r> base ! ; + +: .call ( fp caller function -- ) + .adr ." () called from" .adr ." FP: " .x cr +; + +\ This must agree with the stack initialization jointly established by +\ init-pe-program and (init-program). +: pe-stack-top ( -- adr ) pe-image-base h# 20 - ; + +headers +\ XXX show TOC too +: ms-ctrace ( -- ) + ?saved-state + %r1 %pc ( frame-ptr pc ) + begin ( frame-ptr pc ) + over pe-stack-top <> ( frame-ptr pc ) + while ( frame-ptr pc ) + dup pc>function >r ( frame-ptr pc ) + 2dup pc>caller >r over r> r> .call ( frame-ptr pc ) + 2dup pc>caller -rot pc>framesize + swap ( frame-ptr' pc' ) + exit? if 2drop exit then ( frame-ptr' pc' ) + repeat ( frame-ptr' pc' ) + 2drop 0 pe-image-base .call ( ) +; + +\ 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/ppc/objects.fth =================================================================== --- cpu/ppc/objects.fth (rev 0) +++ cpu/ppc/objects.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,214 @@ +purpose: Action definition for multiple-code-field words. +\ See license at end of file + +\ Data structures: +\ nth-action-does-clause acfs unnest +\ n-1th-action-does-clause acfs unnest +\ ... +\ 1th-action-does-clause acfs unnest +\ nth-adr +\ n-1th-adr +\ ... +\ 1th-adr +\ n +\ 0th-action-does-clause acfs unnest +\ object-header build-acfs +\ (') 0th-adr uses + +needs doaction objsup.fth \ Machine-dependent support routines + +decimal +headerless + +0 value action# +0 value #actions +0 value action-adr +headers +: actions ( #actions -- ) + is #actions + #actions 1- /token * na1+ allot ( #actions ) \ Make the jump table + \ The default action is a code field, which must be aligned + align acf-align here is action-adr + 0 is action# + #actions action-adr /n - n! +; +headerless +\ Sets the address entry in the action table +: set-action ( -- ) + action# #actions > abort" Too many actions defined" + lastacf action-adr action# /token * - /n - token! +; +headers +: action: ( -- ) + action# if \ Not the default action + doaction set-action + else \ The default action, like does> + place-does + then + + action# 1+ is action# + !csp + ] +; +: action-code ( -- ) + action# if \ Not the default action + acf-align start-code set-action + else \ The default action, like ;code + start-;code + then + + \ For the default action, the apf of the child word is found in + \ the same way as with ;code words. + + action# 1+ is action# + do-entercode +; +: use-actions ( -- ) + state @ if + compile (') action-adr token, compile used + else + action-adr used + then +; immediate + +headerless +: .object-error + ( object-acf action-adr false | acf action# #actions true -- ... ) + ( ... -- object-acf action-adr ) + if + ." Unimplemented action # " swap .d ." on object " swap .name + ." , whose maximum action # is " 1- .d cr + abort + then +; + +headers + +\ Run-time code for "to". This is important enough to deserve special +\ optimization. +code to ( -- ) + lwzu t0,4(ip) \ Object acf in t0 + add t0,t0,base \ Relocate + + stwu tos,-4(sp) \ Save the top-of-stack register on memory stack + addi tos,t0,8 \ Put pfa in top-of-stack register + + lwz t1,4(t0) \ Token of default action + add t1,t1,base \ Relocate + lwz w,-8(t1) \ Token of "to" action clause + + \ Tail of "NEXT" + lwzux t1,w,base \ Read the contents of the code field + add t1,t1,base \ Relocate + mtspr lr,t1 + bclr 20,0 \ Execute the code +end-code + +code dispatch-action ( acf action-adr -- ) + \ action-adr in tos + lwz t0,0(sp) \ Object acf in t0 + addi sp,sp,4 + + move w,tos \ Token of action clause + + addi tos,t0,8 \ Put pfa in top-of-stack register + + lwz t1,0(w) \ Read the contents of the code field + \ next-tail1 + add t1,t1,base \ Relocate + mtspr lr,t1 + bclr 20,0 \ Execute the code +end-code + +\ Executes the numbered action of the indicated object +\ It might be worthwhile to implement perform-action entirely in code. +: perform-action ( object-acf action# -- ) + dup if + >action-adr .object-error ( object-acf action-adr ) + dispatch-action + else + drop execute + then +; + +: action-name \ name ( action-offset-adr -- ) + create 1+ /token * negate , + ;code + + lwzu t0,4(ip) \ Object acf in t0 + add t0,t0,base \ Relocate + + lwz t1,4(t0) \ Token of default action + add t1,t1,base \ Relocate + lwz tos,0(tos) \ Get action offset + lwzx w,tos,t1 \ Token of indicated action clause + + addi tos,t0,8 \ Put pfa in top-of-stack register + + \ Tail of "NEXT" + lwzux t1,w,base \ Read the contents of the code field + add t1,t1,base \ Relocate + mtspr lr,t1 + bclr 20,0 \ Execute the code +end-code + +\ 1 action-name to +2 action-name addr + +: action-compiler: \ name ( -- ) + bl word dup find 0= ?missing \ pstr acf + swap "create token, immediate + does> ( apf ) + +level ( apf ) \ Enter temporary compile state if necessary + token@ (compile) \ Compile run-time action-name word + ' (compile) \ Compile object acf + -level \ Exit temporary compile state, perhaps run word +; +\ action-compiler: to +action-compiler: addr + + +\ Makes "is" and "to" synonymous. "is" first checks to see if the +\ object is of one of the kernel object types (which don't have multiple +\ code fields), and if so, compiles or executes the "(is) <token>" form. +\ If the object is not of one of the kernel object types, "is" calls +\ "to-hook" to handle the object as a multiple-code field type object. + +: (to) ( [data] acf -- ) +level compile to (compile) -level ; +' (to) is to-hook +alias to is + +\ 3 actions +\ action: @ ; +\ action: ! ; ( is ) +\ action: ; ( addr ) +\ : value \ name ( initial-value -- ) +\ create , +\ use-actions +\ ; + +\ Need inheritance + +\ 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/ppc/objsup.fth =================================================================== --- cpu/ppc/objsup.fth (rev 0) +++ cpu/ppc/objsup.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,102 @@ +purpose: Machine dependent support routines for multiple-code-field "objects" +\ See license at end of file + +\ These words know intimate details about the Forth virtual machine +\ implementation. + +\ Assembles the common code executed by actions. That code +\ extracts the next token (which is the acf of the object) from the +\ code stream and leaves the corresponding apf on the stack. + +headerless + +: start-code ( -- ) code-cf !csp ; + +\ Assembles code to begin a ;code clause +: start-;code ( -- ) start-code ; + +\ Code field for an object action. +: doaction ( -- ) acf-align colon-cf ; + +\ Returns the address of the code executed by the word whose code field +\ address is acf +: >code-adr ( acf -- code-adr ) token@ ; + +code >action-adr ( object-acf action# -- ) + ( ... -- object-acf action# #actions true | object-apf action-adr false ) + \ action# in tos + lwz t0,0(sp) \ object-acf in t0 + lwz t1,1cell(t0) \ code offset in t1 + add t1,t1,base \ Relocate; code address in t1 + lwz t2,-1cell(t1) \ #actions in t2 + cmp 0,0,t2,tos \ Test action number + <= if \ "true" branch is error + stwu tos,-1cell(sp) \ Push action# + stwu t2,-1cell(sp) \ Push #actions + addi tos,r0,-1 \ Return true for error + else + addi t0,t0,/cf+1cell \ Compute object-apf from object-acf + stw t0,0(sp) \ Put action-apf on stack + + rlwinm tos,tos,2,0,29 \ Convert index to byte offset + subfc t1,tos,t1 \ Skip back #actions tokens + \ ( Use subfc for POWER compatibility) + lwz t1,-1cell(t1) \ Get token, accounting for action# field + add t1,t1,base \ Relocate + stwu t1,-1cell(sp) \ Push action-adr + addi tos,r0,0 \ Return false for no error + then +c; + +headers +: action-name \ name ( action# -- ) + create , \ Store action number in data field + ;code ( -- object-pfa ) + lwz t0,0(tos) \ Action# in t0 + + lwzu t1,/token(ip) \ Object acf in t1 + add t1,t1,base \ Relocate + + addi tos,t1,/cf+1cell \ Compute and push object-apf + + lwz t1,1cell(t1) \ relative version of .. + add t1,t1,base \ default action code address + + rlwinm t0,t0,2,0,29 \ Convert index to byte offset + subfc t1,t0,t1 \ Skip back action# tokens + \ ( Use subfc for POWER compatibility) + + lwz w,-1cell(t1) \ Get token, accounting for action# field + + lwzux t1,w,base \ next-tail ... + add t1,t1,base + mtspr lr,t1 + bclr 20,0 +end-code + +: >action# ( apf -- action# ) @ ; +headers + +\ 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/ppc/occhksum.fth =================================================================== --- cpu/ppc/occhksum.fth (rev 0) +++ cpu/ppc/occhksum.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,102 @@ +purpose: Internet checksum (one's complement of 16-bit words) primitive +\ See license at end of file + +\ The complete checksum calculation consists of: +\ a) add together all the 16-bit big-endian words in the buffer, with +\ wrap-around carry (i.e. a carry out of the high bit is added back +\ in at the low bit). +\ b) Take the one's complement of the result, preserving only the +\ least-significant 16 bits. +\ c) If the result is 0, change it to ffff. + +\ The process of computing a checksum for UDP packets involves the +\ creation of a "pseudo header" containing selected information +\ from the IP header, and checksumming the combination of that pseudo +\ header and the UDP packet. To do so, it is convenient to perform +\ step (a) of the calculation separately on the two pieces (pseudo header +\ and UDP packet). Thus we factor the checksum calculation code with +\ a separate primitive "(oc-checksum)" that performs step (a). That +\ primitive is worth optimizing; steps (b) and (c) are typically not. + +headerless +\ This algorithm depends on the assumption that the buffer is +\ short enough so that we never have a carry out of the high +\ 16 bit word. Assuming worst case data (all bytes ff), the +\ buffer would have to be 128K + 3 bytes long for this to happen. +\ The maximum length of an IP packet is 64K bytes, so we are safe. +\ This allows us to accumulate the end-around carries in the high +\ 16-bit word and add them in one operation at the end. + +code (oc-checksum) ( accum adr len -- checksum ) + mr t1,tos \ t1: len + lwz t0,0(sp) \ t0: adr + lwz tos,4(sp) \ tos: accum + addi sp,sp,8 \ clean up stack + + mr t2,t1 \ t2: copy of len + cmpi 0,0,t1,2 \ Are there any complete words to do? + >= if + + mfspr t5,ctr \ Save counter + + rlwinm t1,t1,31,1,31 \ Convert to word count + mtspr ctr,t1 + + 'user in-little-endian? lwz t3,* \ Which endian + 0= if \ If BE, use word accesses + addi t0,t0,-2 \ Account for pre-increment + + begin + lhzu t3,2(t0) \ Read word and increment pointer + add tos,tos,t3 \ Update checksum + countdown + + addi t0,t0,2 \ Point to next byte + else \ If LE, use byte accesses + addi t0,t0,-1 \ Account for pre-increment + + begin + lbzu t4,1(t0) \ Read high byte and increment pointer + lbzu t3,1(t0) \ Read low byte and increment pointer + rlwimi t3,t4,8,16,23 \ Merge high and low bytes into t3 + add tos,tos,t3 \ Update checksum + countdown + + addi t0,t0,1 \ Point to next byte + then + + mtspr ctr,t5 \ Restore counter + then + + andi. r0,t2,1 \ Is there a leftover byte? + 0<> if + lbz t3,0(t0) \ Get the byte + rlwinm t3,t3,8,16,23 \ Move it to the correct position in the word + add tos,tos,t3 \ Update checksum + then + +c; + +\ 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/ppc/olpc/devalias.fth =================================================================== --- cpu/ppc/olpc/devalias.fth (rev 0) +++ cpu/ppc/olpc/devalias.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,40 @@ +purpose: Platform-specific device aliases +\ See license at end of file + +devalias net /pci/ethernet@e + +.( XXX olpc/devalias.fth) cr +devalias disk0 /pci/disk@0,0:1 +devalias disk1 /pci/scsi@c/disk@1,0:1 +devalias disk2 /pci/scsi@c/disk@2,0:1 +devalias cdrom /pci/scsi@c/disk@5,0 + +devalias c /pci/scsi@c/disk@0,0 + +devalias disk /pci/scsi@c/disk@0,0:1 + +devalias com1 /serial@f1012000 + +\ 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/ppc/olpc/elf.fth =================================================================== --- cpu/ppc/olpc/elf.fth (rev 0) +++ cpu/ppc/olpc/elf.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,126 @@ +purpose: Load image handler for ELF (Extended Linker Format) +\ See license at end of file + +hex + +headerless +: elf? ( -- flag ) 0 +base 4 " "(7f)ELF" $= ; +: elf-le? ( -- flag ) 5 +base c@ 1 = ; +: elfl@ ( adr -- n ) elf-le? if le-l@ else be-l@ then ; +: elfw@ ( adr -- w ) elf-le? if le-w@ else be-w@ then ; + +: eh-l@ ( offset -- l ) +base elfl@ ; +: eh-w@ ( offset -- w ) +base elfw@ ; + +: +elfl@ ( adr offset -- n ) + elfl@ ; + +\ XXX the following code assumes that the value of load-base is such that +\ the copying of program sections to their correct locations does not +\ overwrite portions of other sections that have not yet been copied. + +\ One sufficient condition is that the program sections are stored in the +\ ELF file in ascending order of their execution addresses (vaddr fields) +\ and that load-base is large enough that the sections must be moved to +\ lower addresses. + +0 value high-water +0 value low-water +: record-extent ( adr len -- ) + bounds low-water umin to low-water high-water umax to high-water +; + +: prepare-elf-program ( -- entry-point ) + 0 to high-water + -1 to low-water + + \ Copy all pheaders to allocated memory to protect them from being + \ overwritten when we copy the programs to their final destinations. + + \ e_entry e_phentsize e_phnum + h# 18 eh-l@ h# 2a eh-w@ dup h# 2c eh-w@ * ( entry phentsize phsize) + dup alloc-mem swap ( entry phentsize pbbuf phsize ) + + \ e_phoff + 2dup 1c eh-l@ +base -rot move ( entry phentsize phbuf phsize ) + + \ Scan the program sections and determine how much memory is needed + 2dup bounds ?do ( entry phentsize phbuf phsize ) \ throughout loop + \ p_type PT_LOAD + i 0 +elfl@ 1 = if + \ p_vaddr p_memsz + i 8 +elfl@ i h# 14 +elfl@ record-extent + then + 2 pick +loop ( entry phentsize phbuf phsize ) + + \ XXX Ultimatelty we need to allocate physical memory and map + \ it appropriately, but for now we just claim the virtual address + \ space, assuming that it is already mapped. + + low-water 0 high-water low-water - 0 mem-claim drop ( adr ) + low-water <> abort" Couldn't claim the program's memory" + + 2dup bounds ?do ( entry phentsize phbuf phsize ) \ throughout loop + \ p_type PT_LOAD + i 0 +elfl@ 1 = if + + \ XXX we need to acquire and map the memory first! + + \ Move it into the correct vaddr. + \ p_offset p_vaddr p_filesz + i 4 +elfl@ +base i 8 +elfl@ i h# 10 +elfl@ ( src dst len ) + 2dup 2>r move 2r> sync-cache + + \ Zero any bytes that are not stored in the file + \ p_vaddr p_memsz p_filesz + i 8 +elfl@ i h# 14 +elfl@ i h# 10 +elfl@ /string erase + then + 2 pick +loop ( entry phentsize phbuf phsize ) + free-mem drop ( entry ) +; + +defer verify-machine-type +: (verify-machine-type) ( -- ) + h# 10 eh-w@ 2 <> abort" The loaded file is not executable" + h# 12 eh-w@ dup d# 17 <> swap d# 20 <> and + abort" The loaded file is not a PowerPC program" +; +' (verify-machine-type) to verify-machine-type + +: init-elf-program ( -- ) + verify-machine-type + + prepare-elf-program ( pc ) + + h# 8000 alloc-mem h# 8000 + ( pc sp ) + + (init-program) +; + +headers +warning @ warning off +: init-program ( -- ) elf? if init-elf-program else init-program then ; +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: cpu/ppc/olpc/flash.fth =================================================================== --- cpu/ppc/olpc/flash.fth (rev 0) +++ cpu/ppc/olpc/flash.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,65 @@ +purpose: Setup for Flash ROM access +\ See license at end of file + +h# 8.0000 to /flash +h# fff0.0000 constant rom0-pa +h# fff8.0000 constant rom1-pa +rom0-pa value rom-pa +0 value rom0 + +0 value flashbase + +: ?swizzle ( adr -- adr' ) in-little-endian? if 7 xor then ; +: (fctl!) ( n a -- ) flashbase + ?swizzle c! ; ' (fctl!) to fctl! +: (fdata!) ( n a -- ) flashbase + ?swizzle c! ; ' (fdata!) to fdata! +: (fc@) ( a -- n ) flashbase + ?swizzle c@ ; ' (fc@) to fc@ + + +: open-flash ( -- ) + flashbase 0= if + rom-pa /flash root-map-in to flashbase + then + h# a8 config-l@ h# 00001000 or h# a8 config-l! +; +: close-flash ( -- ) + flashbase /flash root-map-out 0 to flashbase + h# a8 config-l@ h# 00001000 invert and h# a8 config-l! +; +' open-flash to enable-flash-writes + +: (use-rom) ( adr -- ) flashbase if close-flash then to rom-pa ; +: use-rom1 ( -- ) rom1-pa (use-rom) ; +: use-rom0 ( -- ) rom0-pa (use-rom) ; + +\ Copy ROM0 to ROM1 + +\ (flash) is a forward reference. +: copy-rom ( -- ) + rom-pa >r + " rom0" $read-file use-rom1 " (flash)" evaluate + r> (use-rom) +; + +\ 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/ppc/olpc/fw.bth =================================================================== --- cpu/ppc/olpc/fw.bth (rev 0) +++ cpu/ppc/olpc/fw.bth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,300 @@ +purpose: Load file for fw.dic for OLPC School Server +\ See license at end of file + +dictionary: ${BP}/cpu/ppc/build/basefw.dic +command: &ppcforth &dictionary &this +build-now + +\ Configuration defines +create bailout-early +true to stand-init-debug? +true constant real-mode? + +\ ' $report-name is include-hook + +headerless +h# 1000 to pagesize +d# 12 to pageshift + +headers +true value chrp? \ Change as needed + +dev / +1 encode-int " #address-cells" property +device-end + +\ Memory management services +fload ${BP}/ofw/core/clntmem1.fth \ client services for memory +fload ${BP}/ofw/core/memlist.fth \ Resource list common routines +fload ${BP}/ofw/core/showlist.fth \ Linked list display tool +fload ${BP}/ofw/core/allocph1.fth \ S Physical memory allocator +fload ${BP}/ofw/core/availpm.fth \ Available memory list + +headerless +: (memory?) ( phys -- flag ) h# 8000.0000 u< ; \ The CHRP boundary is 0x4000.0000 +' (memory?) to memory? + +headers +\ Handy tools to mark device nodes with the "built-in" property +: mark-builtin ( -- false ) + 0 package( 0 0 encode-bytes " built-in" property )package + false +; +: mark-builtin-all ( -- ) + ['] mark-builtin ['] search-preorder catch 2drop +; + +\ Load file format handlers + +fload ${BP}/cpu/ppc/initpgm.fth \ Basic boot handler +fload ${BP}/cpu/ppc/olpc/elf.fth \ handler for ELF booting +fload ${BP}/ofw/inet/loadtcp.fth \ TCP extensions + +\ Reboot and re-entry code +fload ${BP}/cpu/ppc/reboot.fth \ Restart the client program +fload ${BP}/cpu/ppc/reenter.fth \ Various entries into Forth + +\ Miscellaneous hardware interface words +fload ${BP}/cpu/ppc/cache603.fth \ Cache synchronization +fload ${BP}/cpu/ppc/segreg.fth \ Segment register access +fload ${BP}/cpu/ppc/bat.fth \ BAT mapping register access +fload ${BP}/cpu/ppc/scrub.fth \ Fast memory scrubbing using "dcbz" + +hex +warning on + +h# 40.0000 ' load-base set-config-int-default + +headerless +: (initial-heap) ( -- adr len ) sp0 @ ps-size - limit tuck - ; +' (initial-heap) is initial-heap +headers + +" /openprom" find-device + " FirmWorks,3.0" encode-string " model" property +device-end + +\ XXX this may need to change for L2 cache support +warning @ warning off +\ We can't turn on the dcache until we have set up BAT mapping +stand-init: Instruction cache on + icache-on? 0= if icache-on then +; +warning ! + +fload ${BP}/cpu/ppc/dectrap.fth \ Null decrementer handler +stand-init: Enable machine check exceptions + msr@ h# 1000 or msr! +; + +headerless +defer set-memory-map ' noop to set-memory-map + +headers +stand-init: Set Memory Map + set-memory-map +; + +headerless +h# 6000.0000 value fw-virt-base \ 32 megs of mapping space +h# 0200.0000 value fw-virt-size + +headers +0 value memsize + +fload ${BP}/cpu/ppc/loadvmem.fth \ /mmu node +stand-init: MMU + " /mmu" open-dev mmu-node ! +; + +fload ${BP}/cpu/ppc/realcif.fth \ Real-mode client interface fixups + +fload ${BP}/cpu/ppc/rootnode.fth \ Methods for root node +stand-init: Root node + " /" " init" execute-device-method drop +; +stand-init: Data cache on + msr@ h# 10 and dcache-on? 0= and if dcache-on then +; +stand-init: Fast CPU mode + fastest-mode +; + +0 0 " " " /" begin-package +fload ${BP}/cpu/ppc/olpc/mappci.fth \ PCI-to-root-node address translation +fload ${BP}/dev/pcibus.fth \ Generic PCI bus package +end-package +stand-init: PCI host bridge + " /pci" " init" execute-device-method drop +; + +fload ${BP}/dev/pciprobe.fth +defer probe-all ' probe-pci to probe-all + +fload ${BP}/cpu/ppc/cpunode.fth + +fload ${BP}/ofw/core/bailout.fth + +fload ${BP}/cpu/ppc/olpc/reset.fth \ Reset via "92" register + +fload ${BP}/ofw/core/countdwn.fth \ Startup countdown +fload ${BP}/cpu/ppc/banner.fth \ Startup banner + +fload ${BP}/forth/lib/pattern.fth \ Text string pattern matching +fload ${BP}/ofw/core/filecmds.fth \ File commands: dir, del, ren, etc. + +\ fload ${BP}/pkg/flash/flash.fth +\ fload ${BP}/dev/amd29fxx.fth + +\ fload ${BP}/cpu/ppc/ntctrace.fth + +fload ${BP}/ofw/core/startup.fth + +warning on + +h# 4.0000 constant initial-heap-size + +\ fload builton.fth \ Automatic version stamp +\ dev /openprom +\ built-date-int encode-int " built-on" property +\ 0 0 encode-bytes " arc-interrupt-level=vector" property +\ device-end + +\ fload ${BP}/arch/prep/loadcvar.fth \ PREP NVRAM layout + +\ fload ${BP}/arch/prep/ultra/fixednv.fth \ Offsets of fixed regions of NVRAM + +h# f100.0000 constant mv64660-base \ Needs to be mapped to a VA + +: mv-b@ ( offset -- byte ) mv64660-base + rb@ ; +: mv-b! ( byte offset -- ) mv64660-base + rb! ; +: mv-w@ ( offset -- byte ) mv64660-base + rw@ ; +: mv-w! ( byte offset -- ) mv64660-base + rw! ; +: mv-l@ ( offset -- byte ) mv64660-base + rl@ ; +: mv-l! ( byte offset -- ) mv64660-base + rl! ; +: uart@ ( reg# -- byte ) /l* h# 1.2000 + mv-b@ ; +: uart! ( byte reg# -- ) /l* h# 1.2000 + mv-b! ; +fload ${BP}/dev/diaguart.fth \ Diagnostic driver for PC-compatible serial port + +fload ${BP}/forth/lib/sysuart.fth \ Plug UART routines into key and emit +' ukey is diag-key \ Feed UART input to "dl" + +fload ${BP}/cpu/ppc/olpc/reports.fth \ Low-level character output routines + +fload ${BP}/cpu/ppc/olpc/pciconfig.fth \ Configuration space access +\ fload ${BP}/arch/prep/eagle.fth \ Eagle configuration registers +fload ${BP}/cpu/ppc/ppcboot.fth \ Forth startup code + +[ifdef] bailout-early +: startup quit ; + +install-rom-cold + +.( --- Saving fw.dic ---) cr p" fw.dic" save-forth +bye +[then] + +fload ${BP}/cpu/ppc/olpc/rootnode.fth \ Methods for root node + +fload ${BP}/cpu/ppc/olpc/pcinode.fth \ System-specific words for PCI + +" " dup config-string pci-probe-list + +6 buffer: 'system-mac-address +: get-mac-address ( -- ) + " /ethernet" find-package if + " local-mac-address" rot get-package-property 0= if ( a 6 ) + 'system-mac-address swap move exit + then + then + " 123456" 'system-mac-address swap move \ better than nothing? +; +: (system-mac-address) ( -- addr len ) 'system-mac-address 6 ; +' (system-mac-address) is system-mac-address + +: (probe-all) ( -- ) + " probe-" do-drop-in + probe-pci ( probe-pci-e probe-pci-x ) get-mac-address + " probe+" do-drop-in +; +' (probe-all) to probe-all + +[ifdef] notyet +0 0 " ????????" " /" begin-package \ Real-time clock node +fload ${BP}/dev/ds1385r.fth +end-package +stand-init: RTC + " /rtc" open-dev clock-node ! +; + +0 0 " i74" " /pci/isa" begin-package \ NVRAM node +fload ${BP}/dev/ds1385n.fth + +" ds1385-nvram" encode-string +" pnpPNP,8" encode-string encode+ +" compatible" property + +env-end-offset to /nvram +end-package +stand-init: NVRAM + " /nvram" open-dev to nvram-node + init-config-vars +; +[endif] + +\ fload ${BP}/dev/isa/irq.fth + +stand-init: Keyboard overrides + ?bailout +; + +\ fload ${BP}/cpu/ppc/olpc/cpunode.fth \ CPU node additions + +fload ${BP}/cpu/ppc/olpc/probemem.fth \ Memory probing + +fload ${BP}/cpu/ppc/olpc/devalias.fth \ Device aliases + +0 0 " fff00000" " /" begin-package + " flash" device-name + h# 8.0000 constant /device + my-address my-space /device reg + fload ${BP}/cpu/x86/pc/flashpkg.fth +end-package + +devalias rom /flash@fff00000 + +fload ${BP}/cpu/ppc/olpc/flash.fth \ Low-level FLASH access + +fload ${BP}/pkg/flash/saveflsh.fth \ FLASH to disk and back + +\ ' false to interrupt-auto-boot? \ Don't do countdown + +patch noop fw-title rom-cold \ Superseded by banner + +install-rom-cold + +.( --- Saving subset.dic ---) cr p" subset.dic" save-forth + +\ 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/ppc/olpc/fwuboot.bth =================================================================== --- cpu/ppc/olpc/fwuboot.bth (rev 0) +++ cpu/ppc/olpc/fwuboot.bth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,71 @@ +purpose: Create a Uboot-format image +\ See license at end of file + +command: &builder &this +in: ${BP}/cpu/ppc/olpc/build/fw.dic +build-now + +create uboot-header + h# 27051956 be-l, + 0 be-l, \ Header CRC, set later + 0 be-l, \ Timestamp + 0 be-l, \ Data size + h# 0f000000 be-l, \ Load address + h# 0f000000 be-l, \ Entry address + 0 be-l, \ Data CRC, set later + 5 c, \ OS type - Linux + 7 c, \ CPU type - PowerPC + 1 c, \ Image type - standalone (kernel is 2) + 0 c, \ Compression type - none + + here h# 20 blank + " Open Firmware" here swap move + h# 20 allot + +here uboot-header - constant /uboot-header + +fload ${BP}/forth/lib/crc32.fth + +reading fw.dic +ifd @ fsize constant /image +/image buffer: filebuf +filebuf /image ifd @ fgets /image <> abort" Can't read image" +ifd @ fclose + +/image uboot-header 3 la+ be-l! + +\ Compute the image CRC and store it in the uboot header +-1 crctab filebuf /image ($crc) invert uboot-header 6 la+ be-l! + +\ Compute the header CRC and store it in the uboot header +-1 crctab uboot-header /uboot-header ($crc) invert uboot-header 1 la+ be-l! + +.( --- Saving as fwuboot.rom) cr +writing fwuboot.rom +uboot-header /uboot-header ofd @ fputs +filebuf /image ofd @ fputs +ofd @ fclose + +\ 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/ppc/olpc/mappci.fth =================================================================== --- cpu/ppc/olpc/mappci.fth (rev 0) +++ cpu/ppc/olpc/mappci.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,38 @@ +purpose: PCI physical address mapping to root node +\ See license at end of file + +headerless +: map-pci-phys ( paddr io? phys.hi size -- vaddr ) + >r drop ( paddr io? R: size ) + if h# c800.0000 else h# a000.0000 then ( paddr R: size ) + or r> " map-in" $call-parent +; +: >pci-devaddr ( root-devaddr -- pci-devaddr ) + chrp? 0= if h# 8000.0000 + then +; +: pci-devaddr> ( pci-devaddr -- root-devaddr ) ; +headers + +\ 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/ppc/olpc/pciconfig.fth =================================================================== --- cpu/ppc/olpc/pciconfig.fth (rev 0) +++ cpu/ppc/olpc/pciconfig.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,47 @@ +purpose: PCI configuration space access for Marvell MV64660 +\ See license at end of file + +\ Ostensibly this applies to the PCI bus and thus should be in the PCI node. +\ However, many of the host bridge registers are accessed via this mechanism, +\ so it is convenient to make the configuration access words globally-visible. +\ This mechanism works for several different PCI host bridges. + +headerless + +: config-map ( config-adr -- port ) + dup 3 invert and h# 8000.0000 or h# 3.0c78 mv-l! ( config-adr ) + 3 and h# 3.0c7c or +; + +headers + +: config-l@ ( config-addr -- l ) config-map mv-l@ ; +: config-l! ( l config-addr -- ) config-map mv-l! ; +: config-w@ ( config-addr -- w ) config-map mv-w@ ; +: config-w! ( w config-addr -- ) config-map mv-w! ; +: config-b@ ( config-addr -- c ) config-map mv-b@ ; +: config-b! ( c config-addr -- ) config-map mv-b! ; + +\ 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/ppc/olpc/pcinode.fth =================================================================== --- cpu/ppc/olpc/pcinode.fth (rev 0) +++ cpu/ppc/olpc/pcinode.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,109 @@ +purpose: System-specific portions of PCI bus package +\ See license at end of file + +dev /pci + +d# 66,666,666 encode-int " clock-frequency" property + +headers + +\ These package methods use the global versions of the configuration +\ access words. This is appropriate only for single-PCI-bus systems. + +: config-l@ ( config-addr -- l ) config-l@ ; +: config-l! ( l config-addr -- ) config-l! ; +: config-w@ ( config-addr -- w ) config-w@ ; +: config-w! ( w config-addr -- ) config-w! ; +: config-b@ ( config-addr -- c ) config-b@ ; +: config-b! ( c config-addr -- ) config-b! ; + +\ ------PCI Address------- ---Host Address-- -- size -- +\ phys.hi .mid .low phys.hi .lo .hi .lo + +.( XXX - ranges properties for PCI node) cr +0 0 encode-bytes +0100.0000 +i 0+i 0+i c800.0000 +i 0+i 0800.0000 +i \ PCI I/O +0200.0000 +i 0+i 0+i a000.0000 +i 0+i 2000.0000 +i \ PCI Mem + " ranges" property + +headers + +: init ( -- ) + \ Could do interrupt routing here +; + +[ifdef] notyet +headerless + +\ Determine the parent interrupt information (the "interrupt line" in PCI +\ parlance) from the child's "interrupt pin" and the child's address, +\ returning "int-line true" if the child's interrupt line register should +\ be set or "false" otherwise. + +\ This table describes the wiring of PCI interrupt pins at the PCI slots +\ to PIRQ inputs on the 82378zb chip. The wiring varies from slot to slot. + +create slot-map + +\ Pin A Pin B Pin C Pin D Dev# + + 2 c, ff c, ff c, ff c, \ c SCSI + ff c, ff c, ff c, ff c, \ d nothing + 0 c, ff c, ff c, ff c, \ e Ethernet + 3 c, ff c, ff c, ff c, \ f Display + 0 c, 1 c, 2 c, 2 c, \ 10 Slot 1 (the riser connects INTC and INTD) + 1 c, 2 c, 2 c, 0 c, \ 11 Slot 2 (the riser connects INTC and INTD) + 2 c, 2 c, 0 c, 1 c, \ 12 Slot 3 (the riser connects INTC and INTD) + +: pin,dev>pirq ( pin# dev# -- true | pirq# false ) + dup c 12 between 0= if 2drop true exit then ( int-pin dev# ) + + c - 4 * + slot-map + c@ ( pirq#|ff ) + dup h# ff = if drop true else false then +; + +headers + +: 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>pirq if false exit then ( pirq# ) + + pirq>irq ( irq# ) + + true +; + +h# 700 encode-int \ Mask of implemented slots +" PCI 1" encode-string encode+ +" PCI 2" encode-string encode+ +" PCI 3" encode-string encode+ " slot-names" property +[then] + +device-end + +\ 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/ppc/olpc/probemem.fth =================================================================== --- cpu/ppc/olpc/probemem.fth (rev 0) +++ cpu/ppc/olpc/probemem.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,52 @@ +purpose: Memory probing +\ See license at end of file + +" /memory" find-device + +\ This assumes, without checking, that bottom and top are each aligned on +\ a cache block boundary +: scrub&release ( bottom top -- ) + 2dup = if 2drop exit then + over - 2dup berase + release +; + +: probe ( -- ) + 0 memsize reg \ Put all memory in the "reg" property value + + h# 4000 origin pagesize round-down scrub&release + + memtop @ memsize scrub&release +; + +device-end + +also forth definitions +stand-init: Probing memory + " probe" memory-node @ $call-method +; +previous definitions + +\ 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/ppc/olpc/reports.fth =================================================================== --- cpu/ppc/olpc/reports.fth (rev 0) +++ cpu/ppc/olpc/reports.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,132 @@ +purpose: Simple serial output routines for debugging startup code +\ See license at end of file + +transient +\ Assembler macro to assemble code to set the location "isa-adr" in +\ ISA I/O space to the value "data". Assumes that r1 is already set +\ to the base addess of ISA I/O space. +: isa-c! ( data isa-adr -- ) + swap " set r3,*" evaluate 1 " eieio stb r3,*" evaluate +; + +resident + +h# f101.2000 constant uart-base + +label putbyte ( r3: byte -- ) \ Destroys r0-r1 + uart-base set r1,* + begin lbz r0,h#14(r1) andi. r0,r0,h#20 0<> until + eieio stb r3,h#0(r1) + begin lbz r0,h#14(r1) andi. r0,r0,h#20 0<> until + bclr 20,0 +end-code + +\ destroys: r0-r4 +label putdigit ( r3: nibble -- ) \ print 4-bit value in r3 + mfspr r4,lr + andi. r3,r3,h#0f cmpi 0,0,r3,9 > if addi r3,r3,h#27 then + addi r3,r3,h#30 + putbyte bl * + mtspr lr,r4 + bclr 20,0 +end-code + +transient +: be-report ( char -- ) " set r3,* be-putbyte bl *" evaluate ; +resident + +\ destroys: r0-r6 +label dot ( r3: n -- ) \ print 32-bit value in r3 + mfspr r5,lr + mr r6,r3 + + set r3,h#20 putbyte bl * + + rlwinm r3,r6,04,28,31 putdigit bl * + rlwinm r3,r6,08,28,31 putdigit bl * + rlwinm r3,r6,12,28,31 putdigit bl * + rlwinm r3,r6,16,28,31 putdigit bl * + rlwinm r3,r6,20,28,31 putdigit bl * + rlwinm r3,r6,24,28,31 putdigit bl * + rlwinm r3,r6,28,28,31 putdigit bl * + rlwinm r3,r6,00,28,31 putdigit bl * + + set r3,h#20 putbyte bl * + mtspr lr,r5 + bclr 20,0 +end-code + +\ destroys: r0-r4 +label dcr ( -- ) + mfspr r4,lr + carret set r3,* putbyte bl * + linefeed set r3,* putbyte bl * + mtspr lr,r4 + bclr 20,0 +end-code + +[ifdef] pc@ +stand-init-debug? [if] +: putc ( char -- ) + begin 5 uart@ h# 20 and until + 0 uart! + begin 5 uart@ h# 20 and until +; +: ?putc ( "char" -- ) postpone [char] postpone putc ; immediate +[else] +transient +: ?putc ( "char" -- ) safe-parse-word 2drop ; immediate +resident +[then] +[then] + +[ifdef] notdef +: digits " 0123456789abcdef" drop ; +: xx. 0 d# 28 do dup i >> h# f and digits + c@ emit -4 +loop space drop ; +[then] + +headers +transient +: .r3 ( -- ) " dot bl *" evaluate ; + +[ifdef] stand-init-debug? +: ?report ( char -- ) + stand-init-debug? if + " set r3,* putbyte bl *" evaluate + else + drop + then +; +[else] +: ?report ( char -- ) " set r3,* putbyte bl *" evaluate ; +[then] + +resident + +transient +: spins ( n -- ) " set r0,* mtspr ctr,r0 begin countdown" evaluate ; +resident + +\ 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/ppc/olpc/reset.fth =================================================================== --- cpu/ppc/olpc/reset.fth (rev 0) +++ cpu/ppc/olpc/reset.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,35 @@ +purpose: Reset system - this version works on many PR*P systems +\ See license at end of file + +headerless +.( XXX: cpu/ppc/olpc/reset.fth - Implement reset-all ) cr +: (reset-all) ( -- ) + icache-off dcache-off + +; +' (reset-all) to reset-all +headers + +\ 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/ppc/olpc/rootnode.fth =================================================================== --- cpu/ppc/olpc/rootnode.fth (rev 0) +++ cpu/ppc/olpc/rootnode.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,35 @@ +purpose: Properties and Methods for root node +\ See license at end of file + +dev / + +" olpc,School Server 1" " model" string-property + +.( XXX - clock-frequency of root node) cr +d# 666,666,666 " clock-frequency" integer-property \ For root bus + +device-end + +\ 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/ppc/pause.fth =================================================================== --- cpu/ppc/pause.fth (rev 0) +++ cpu/ppc/pause.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,60 @@ +purpose: Code words for multitasking +\ See license at end of file + +code (pause (s -- ) \ go see if anybody else wants service + stwu tos,-4(sp) + + 'user saved-ip stw ip,* + 'user saved-rp stw rp,* + 'user saved-sp stw sp,* + + 'user link lwz up,* \ get up for new task + add up,up,base \ Relocate it + 'user entry lwz t0,* \ get pc for new task + add t0,t0,base + mtspr lr,t0 + bclr 20,0 +end-code + +label to-next-task (s -- address-of-"next-task"-code ) + 'user link lwz up,* \ get up for new task + add up,up,base \ Relocate it + 'user entry lwz t0,* \ get pc for new task + add t0,t0,base + mtspr lr,t0 + bclr 20,0 +end-code + +\ Called with up set to the user area address of the task to run +label task-resume (s -- ) \ start a task + stwu tos,-4(sp) + 'user saved-ip lwz ip,* + 'user saved-rp lwz rp,* + 'user saved-sp lwz sp,* + lwz tos,0(sp) + addi sp,sp,4 +c; + +\ 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/ppc/ppcboot.fth =================================================================== --- cpu/ppc/ppcboot.fth (rev 0) +++ cpu/ppc/ppcboot.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,377 @@ +purpose: PowerPC Forth startup code +\ See license at end of file + +hex + +\ Boot code (cold and warm start). The cold start code is executed +\ when Forth is initially started. Its job is to initialize the Forth +\ virtual machine registers. The warm start code is executed when Forth +\ is re-entered, perhaps as a result of an exception. + +hex + +warning @ warning off +: stand-init-io ( -- ) + stand-init-io + +\ inituarts \ Already done in startup code + install-uart-io + + ['] noop to mark-error + ['] noop to show-error + ['] reset-all to bye + ['] crlf-pstr to newline-pstring + ['] no-swap-map to init-swap-map + + real-mode? to use-real-mode? +; +warning ! + +headerless +defer rom-init-io +headers \ Debugging is difficult if rom-init-environment is headerless +defer rom-init-environment +headerless +defer rom-cold-hook + +: rom-cold (s -- ) + hex +\ ?putc $ + rom-init-io \ Memory allocator and character I/O +\ ?putc # + do-init \ Kernel +\ ?putc % + stand-init-debug? if + cr ." Type 'i' to interrupt stand-init sequence" cr + d# 200 ms + key? if key drop ." Interacting" cr interact then + then + ['] rom-init-environment guarded \ Environmental dependencies + ['] rom-cold-hook guarded \ Open Firmware final startup + + fw-title + quit +; + +[ifndef] ,64bit? +: ,64bit? ( -- ) + " mfspr r0,pvr rlwinm r0,r0,16,16,31 cmpi 0,0,r0,20 =" evaluate +; +[then] + +label synchronize-caches ( scratch: r0 r3 r4 ) + + \ Flush Dcache if it's on + + mfspr r3,hid0 + andi. r3,r3,h#4000 + 0<> if + ,64bit? if + h# 10000 64 / set r4,* \ #cache-lines + mtspr ctr,r4 + set r4,64 \ /cache-line + else + h# 10000 32 / set r4,* \ #cache-lines + mtspr ctr,r4 + set r4,32 \ /cache-line + then + + neg r3,r4 \ Begin at 0 - /cache-line + + begin + lbzux r0,r3,r4 \ Touch each cache block + countdown \ from [0 to 64K) (0x800 * 0x20) + + neg r4,r4 \ Prepare to count down + begin + dcbf r0,r3 \ Flush each block + add. r3,r3,r4 \ on the way back down to 0 + 0<> until + then + + \ Invalidate Icache if it's on + + mfspr r3,hid0 + andi. r3,r3,h#8000 + 0<> if + mfspr r3,hid0 + ori r0,r3,h#800 + sync isync + mtspr hid0,r0 \ Set the invalidate bit + sync isync + mtspr hid0,r3 \ Clear the invalidate bit for 603 + sync isync + then + + bclr 20,0 +end-code + +[ifndef] nv-adr-low +h# 74 constant nv-adr-low +h# 75 constant nv-adr-high +h# 77 constant nv-data +[then] + +create force-big-endian +\ \needs read-le-flag fload ${BP}/arch/prep/leflag.fth + +label memcpy ( r3: dst r4: src r5: n -- r3: dst ) + mtspr ctr,r5 + mr r6,r3 + + addi r3,r3,-1 \ Account for pre-decrement + addi r4,r4,-1 \ Account for pre-decrement + begin + lbzu r5,1(r4) + stbu r5,1(r3) + countdown + + mr r3,r6 \ Return dst + bclr 20,0 +end-code + +[ifdef] switcheroo +label ?switch-endian + mfspr r30,lr + + switcheroo origin - set r4,* + add r4,r4,base \ Absolute address of switcheroo code + set r3,h#1000 \ Temporary RAM location for switcheroo code + /switcheroo set r5,* + memcpy bl * + + bla h#1000 \ Execute the RAM copy of switcheroo + + nop nop nop nop \ Endian-independent landing pad + + mtspr lr,r30 + bclr 20,0 +end-code +[else] + +label move-user-area +\ move-user-area copies the initial user area image to its final RAM location + +\ In: r13: header-adr r14: little-endian? r15: allocation pointer +\ Destroys: r20-r24 +\ Out: up: final user area address r15: updated allocation pointer + +\ Find the user area size from the header + lwz r21,4(r13) \ Text size = offset to start of data + lwz r20,8(r13) \ Data size = user area size in r20 + +\ Allocate high memory for the stacks and stuff, starting at memtop and +\ allocating downwards. r15 is the allocation pointer. + +\ Allocate the RAM copy of the User Area + subf r15,r20,r15 + rlwinm r15,r15,0,0,28 \ doubleword-align by clearing 3 low bits + mr up,r15 \ Set user pointer + + \ Copy the initial User Area image to the RAM copy + add r23,r21,base \ Init-up pointer in r23 + mr r22,up \ Destination pointer + + srawi r20,r20,2 + mtspr ctr,r20 + addi r23,r23,-4 \ Account for pre-incrementing + addi r22,r22,-4 \ Account for pre-incrementing + begin \ Copy without byte swapping + lwzu r20,4(r23) + stwu r20,4(r22) + countdown + + bclr 20,0 + nop + +end-code +[then] + +create uboot-entry +label rom-cold-code ( r3:fw-RAM-base r4:fw-RAM-size -- ) + +[ifdef] uboot-entry + set r13,h#0f000000 \ Firmware memory base address in r13 + set r11,h#00200000 \ Firmware memory size in r11 +[else] + mr r13,r3 \ Firmware memory base address in r13 + mr r11,r4 \ Firmware memory size in r11 +[then] + + lwz r12,0(r0) \ Get memsize from low memory + + add r15,r13,r11 \ r15 is the allocation pointer + +carret ?report +linefeed ?report +ascii A ?report + +[ifdef] force-big-endian + set r14,0 +[else] + read-le-flag bl * + mr r14,r3 +[then] + + \ Allocate HTAB + ,64bit? if \ 64-bit CPUs + set r22,h#40000 \ /htab-64 + else \ 32-bit CPUs + set r22,h#10000 \ /htab-32 + then + rlwinm r2,base,0,0,19 \ Round base down to page boundary + + subf r15,r22,r15 + mr r6,r15 + +ascii B ?report +\ Find the base address + here 4 + bl * \ Absolute address of next instruction + here origin - set base,* \ Relative address of this instruction + mfspr r0,lr + subf base,base,r0 \ Base address of Forth kernel + +[ifdef] ?switch-endian + ?switch-endian bl * + +" ppcboot.fth: Do we need to sync caches after endian switch?" ?reminder +\ set r3,h#1f0.0000 set r4,h#10.0000 sync-cache bl * +\ mr r3,up user-size set r4,* sync-cache bl * +[else] +\ mr r3,r13 .r3 +\ lwz r3,4(r13) .r3 + lwz r3,8(r13) .r3 + + move-user-area bl * +[then] + +ascii Q ?report +[ifdef] ?enter-virtual-mode + mr r3,r13 \ Firmware memory base address + mr r4,r11 \ Firmware memory size + + ?enter-virtual-mode bl * \ Returns virt minus phys offset + mr r16,r3 +[else] + set r16,0 \ Set virtual-physical offset to 0 +[then] + +ascii R ?report + add r15,r15,r16 \ Convert allocation pointer to virtual + add up,up,r16 \ Convert user pointer to virtual + + \ This must be done after we switch modes because longwords may be + \ exchanged in the RAM copy of the user area prior to the mode switch. + 'user in-little-endian? stw r14,* \ Assert mode for Forth code + 'user virt-phys stw r16,* \ Assert mode for Forth code + + 'user htab-phys stw r6,* \ Allocated address of hash table + add r2,r2,r16 \ Convert htab address to virtual + 'user htab stw r6,* \ Allocated address of hash table + +ascii J ?report + +\ Find the base address + here 4 + bl * \ Absolute address of next instruction + here origin - set base,* \ Relative address of this instruction + mfspr r22,lr + subf base,base,r22 \ Base address of Forth kernel + +\ Now the user area has been copied to the proper place, so we can set +\ some important user variables whose inital values are determined at +\ run time. + + 'body main-task set r22,* \ Allow the exception handler to find the + \ user area by storing the address of the + stwx up,base,r22 \ main user area in the "constant" main-task + + set r0,-1 + 'user powerpc? stw r0,* + +\ Top of memory and dictionary limit + add r0,r11,r13 \ Compute memtop + 'user memtop stw r0,* + 'user memsize stw r12,* + +\ Set the up0 user variable + 'user up0 stw up,* + +\ Establish the return stack and set the rp0 user variable + mr rp,r15 \ Set rp + 'user rp0 stw rp,* + rs-size negate addi r15,r15,* \ allocate space for the return stack + +ascii K ?report +\ Establish the Parameter Stack + 'user sp0 stw r15,* + addi sp,r15,4 \ account for the top of stack register + + ps-size negate addi r15,r15,* \ Allocate the stuff on the stack + + initial-heap-size set r22,* \ Reserve some space for the heap + subf r15,r22,r15 + 'user limit stw r15,* \ Top of dictionary growth area + +\ Set the dictionary pointer + add r21,r21,base \ Base + text size + 'user dp stw r21,* \ Set dp + +ascii L ?report +\ Save the address of the system call table in the user variable syscall-vec + set r0,0 + 'user syscall-vec stw r0,* + +\ Set the value of #args and args + 'user #args stw r0,* + 'user args stw r0,* + + synchronize-caches bl * + +ascii M ?report +\ Set the next pointer + mtspr ctr,up + +ascii N ?report +\ Enter Forth + 'body rom-cold 4 - set ip,* + add ip,ip,base +\ ctr:np w:r25, base:r26, up:r27, tos:r28, ip:r29, rp:r30, sp: r31 +h# 20 ?report +mfspr r3,ctr .r3 mr r3,base .r3 mr r3,up .r3 mr r3,ip .r3 mr r3,rp .r3 mr r3,sp .r3 +lwz r3,0(ip) .r3 +carret ?report +c; + +: install-rom-cold ( -- ) + " stand-init-io" $find-name is rom-init-io + " stand-init" $find-name is rom-init-environment + " startup" $find-name is rom-cold-hook + + rom-cold-code origin put-branch +; + +headers + +\ 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/ppc/ppcsim/ppcsim.c =================================================================== --- cpu/ppc/ppcsim/ppcsim.c (rev 0) +++ cpu/ppc/ppcsim/ppcsim.c 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,2092 @@ +// See license at end of file +/* + * PowerPC instruction set simulator for Forth + */ + +#include <stdio.h> + +#define BI_ENDIAN + +extern long s_bye(); +extern long c_key(); + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +#define MAXMEM 0x80000 + +union { + u_long all; + struct { + u_long SO :1; + u_long OV :1; + u_long CA :1; + u_long res:13; + } bits; +} XER; + +union { + u_long all; + struct { + u_long LTGTEQ :3; + u_long SO :1; + u_long res:12; + } bits; +} CR; + + +#define ILLEGAL goto illegal + +#ifdef TRACE +#define INSTR(a) trace(a, instruction, pc) +#else +#define INSTR(a) +#endif + +#define CMP(a,b) ((a < b) ? 4 : ((a > b) ? 2 : 1 )) + +#define DO_UPDATE_SO CR.bits.SO = XER.bits.SO +#define DO_UPDATE_SO_CRFD(crfd) { \ + CR.all &= ~(1 << ((7-crfd)<<2)); \ + CR.all |= (XER.bits.SO << ((7-crfd)<<2));\ + } + +#define DO_UPDATE_OV(dest,src1,src2) \ + if (OE) { \ + XER.bits.SO |= \ + (XER.bits.OV = \ + ((((long)(dest))^((long)(src1))) < 0) && \ + ((((long)(src1))^((long)(src2))) >= 0)); \ + } + +#ifdef OVERFLOWS +#define UPDATE_SO DO_UPDATE_SO +#define UPDATE_SO_CRFD(crfd) DO_UPDATE_SO_CRFD(crfd) +#define UPDATE_OV(a,b,c) DO_UPDATE_OV(a,b,c) +#else +#define UPDATE_SO +#define UPDATE_SO_CRFD(a) +#define UPDATE_OV(a,b,c) +#endif + +#define UPDATE_CA(res,op) XER.bits.CA = ((u_long)res < (u_long)op) + +#define DO_UPDATE_CRFD(dest,src,crfd) \ + { \ + CR.all &= ~(0xe << ((7-crfd)<<2)); \ + CR.all |= (CMP(dest, src) << (((7-crfd)<<2)+1)); \ + UPDATE_SO_CRFD(crfd); \ + } + +#ifdef notdef +#define DO_UPDATE_CR(dest,src) \ + { \ + CR.bits.LTGTEQ = CMP(dest, src); \ + UPDATE_SO; \ + } +#else +#define DO_UPDATE_CR(dest,src) DO_UPDATE_CRFD(dest,src,0) +#endif + +#define UPDATE_CR(dest) \ + if (RC) { \ + DO_UPDATE_CR((long)dest, 0); \ + } + +/* Add/subtract with carry */ +#define ADDC(b,a) \ + temp = (b)+(a); \ + UPDATE_OV(temp,(b),(a)); \ + UPDATE_CA((temp),(a)); \ + UPDATE_CR(temp); \ + RD = temp; + +#define SUBC(b,a) \ + temp = (b)-(a); \ + UPDATE_OV(temp,(b),(a)); \ + XER.bits.CA = (b) >= (a); \ + UPDATE_CR(temp); \ + RD = temp; + +/* Add/subtract without carry */ +#define ADD(b,a) \ + temp = (b)+(a); \ + UPDATE_OV(temp,(b), (a)); \ + UPDATE_CR(temp); \ + RD = temp; \ + break; + +/* logical operations - and, or, shifts, etc */ +#define LOGIC(expr) \ + RA = expr; \ + UPDATE_CR(RA); \ + break; + +/* Condition/counter evaluation for bcXXX */ +#define CONDITION \ + /* \ + * If (BO&0x10), don't test condition. \ + * Otherwise the CR[BI] and the 0x8 bit of BO must be the same. \ + */ \ + cond_ok = ((BO & 0x10) \ + || ((long)((CR.all << BI) ^ (BO << 28)) >= 0)); \ + if ((BO & 4) == 0) { /* Update and test counter */ \ + CTR -= 1; \ + cond_ok &= ((CTR != 0) ^ ((BO >> 1) & 1)); \ + } \ + if (LK) \ + LR = CIA+4; + + +#define UFIELD(lbit,nbits) ((instruction << lbit) >> (32 - nbits)) +#define SFIELD(lbit,nbits) ((long)(instruction << lbit) >> (32 - nbits)) + +#define OPCD (instruction >> 26) +#define OP2 UFIELD(21,10) + +/* These bits are never used as indices; only as flags */ +#define LK (instruction & 1) +#define RC (instruction & 1) +#define AA (instruction & 2) +#define SHD (instruction & 2) + +#define LI SFIELD( 6,24) + +#define RD reg[UFIELD( 6, 5)] +#define RS reg[UFIELD( 6, 5)] +#define FRD reg[UFIELD( 6, 5)] +#define FRS reg[UFIELD( 6, 5)] +#define BO UFIELD( 6, 5) +#define CRBD UFIELD( 6, 5) + +#define RA reg[UFIELD(11, 5)] +#define FRA reg[UFIELD(11, 5)] +#define BI UFIELD(11, 5) +#define CRBA UFIELD(11, 5) +#define TO UFIELD(11, 5) +#define RA0 (UFIELD(11, 5) ? RA : 0) + +#define RB reg[UFIELD(16, 5)] +#define FRB reg[UFIELD(16, 5)] +#define CRBB UFIELD(16, 5) +#define NB UFIELD(16, 5) +#define SH UFIELD(16, 5) + +#define FRC reg[UFIELD(21, 5)] +#define MB UFIELD(21, 5) + +#define ME UFIELD(26, 5) + +#define BD SFIELD(16,14) +#define DS SFIELD(16,14) + +#define D SFIELD(16,16) +#define SIMM SFIELD(16,16) +#define UIMM UFIELD(16,16) + +#define CRFD UFIELD( 6, 3) +#define FM UFIELD( 7, 8) +#define L UFIELD(10, 1) +#define CRFS UFIELD(11, 3) +#define SPR (UFIELD(11,5) | (UFIELD(16,5) << 5)) +#define TBR UFIELD(11,10) +#define CRM UFIELD(12, 8) +#define SR seg[UFIELD(12, 4)] +#define IMM UFIELD(16, 4) +#define XO UFIELD(21,10) +#define OE UFIELD(21, 1) + +#define MASK ((MB <= ME) ? (u_long)(-1L << (31-ME+MB)) >> MB \ + : (u_long)(-1L << (31-ME)) | ((u_long)-1L >> MB)) + +#define ROTATE(val, cnt) (((val) >> (32-(cnt))) | ((val) << (cnt))) + +u_long TBAR; + +#ifdef MMU + +/* + * This is not an accurate simulation of the PowerPC MMU behavior + * a) BATs aren't implemented. + * b) the simulated TLB is much much larger than a real one + * c) segment register values are limited to the range 0..f + */ +u_long mmutab[0x100000]; +void +init_tlb() +{ + int i; + for (i = 0; i < 0x100000; i++) + mmutab[i] = 0xffffffff; +} +u_long +tlb_miss(vaddr) + register u_long vaddr; +{ + /* References: 603 manual, sections 7.6.1.4 and 7.6.3.1 */ + register u_long temp, vsid, mask; + vsid = seg[vaddr >> 28]; + temp = ((vaddr >> 12) & 0xffff) | vsid; + mask = ((((SDR1 & 0x1ff) << 10) | 0x3ff) << 6; + DMISS = IMISS = vaddr; + HASH1 = (SDR1 & 0xffff0000) | ((temp << 6) & mask); + HASH2 = HASH1 ^ mask; + DCMP = ICMP = 0x80000000 | (vsid << 7) | ((vaddr >> 22) & 0x3f); +} +tlbie(vaddr) + register u_long vaddr; +{ + mmutab[vaddr >> 12] = 0xffffffff; +} +u_long +MAP(vaddr) + register u_long vaddr; +{ + register u_long phys; + register u_long pageno; + pageno = (seg[vaddr >> 28] << 16) | ((vaddr >> 12) & 0xffff); + + if ((phys = mmutab[pageno]) == 0xffffffff) + mmutab[pageno] = phys = tlb_miss(vaddr); + return (phys | (vaddr & 0xfff)); +} +#else +#ifdef SIMNT +/* + * Most PPC kernel stuff wants to run in what used to be kseg0 (long + * long ago in a galaxy far far away). This little deal maps virtual + * to physical. + */ +u_long +MAP(vaddr) + u_long vaddr; +{ + if (vaddr > 0x80000000 && vaddr < 0xf0000000) + vaddr &= ~0x80000000; + return(vaddr < 0x10000 ? vaddr + 0x50000 : vaddr); +} +#else +#ifdef TRACE +#ifndef SIMROM +/* This can't be a macro because of side effects of operand evaluation */ +u_long +MAP(vaddr) + register u_long vaddr; +{ + return ((vaddr < 0x1000) ? (vaddr + TBAR) : vaddr); +} +#else +#define MAP(vaddr) (vaddr) +#endif +#else +#define MAP(vaddr) (vaddr) +#endif +#endif +#endif + +#ifdef NOTDEF +#define CIA ((u_char *)MAP(pc) - mem) +#else +#define CIA ((u_long)MAP(pc)) +#endif +#define UNIMP(str) { opname = str; goto unimplemented; } +#define POWER(str) { opname = str; goto power; } + +#ifdef BI_ENDIAN +#define MEM(type, size, adr) *(type *)(&mem[MAP((adr) ^ size)]) +#else +#define MEM(type, size, adr) *(type *)(&mem[MAP(adr)]) +#endif + +u_long greg[32]; +u_long seg[16]; + +#ifdef TRACE +u_long instruction; +u_long pc; +u_long CTR; +u_long LR; +#endif + +u_long IABR; +u_long HID0; +u_long DEC, SRR0, SRR1, SPRG0, SPRG1, SPRG2, SPRG3, MSR; + +u_char *xmem; + +void +simulate(mem, start, arg0, arg1, arg2, arg3, arg4, arg5) + register u_char *mem; + u_long start; + u_long arg0, arg1, arg2, arg3, arg4, arg5; +{ + register u_long *reg = &greg[0]; +#ifndef TRACE + register u_long instruction; + register u_long pc; + register u_long CTR; + register u_long LR; +#endif +#ifdef BI_ENDIAN + register u_long BYTE = 0; /* 7 for little-endian */ + register u_long WORD = 0; /* 6 for little-endian */ + register u_long LONG = 0; /* 4 for little-endian */ +#endif + + + register int cond_ok; + register u_long temp; + u_long scratch; + char *msg; + char *opname; + + xmem = mem; + + reg[3] = arg0; + + /* + * Pass 0 as the system call vector to let the kernel know it's + * running on the simulator. + */ + reg[4] = 0; /* Was reg[4] = arg1; */ + reg[5] = arg2; + reg[6] = arg3; + reg[7] = arg4; + reg[8] = arg5; + +#ifdef TRACE + catch_signals(); +#endif + + for (pc = start; ; pc += 4) { + +#ifdef TRACE + if (DEC-- == 0 && (MSR & 0x8000) && TBAR) { + SRR0 = CIA; + SRR1 = MSR; + pc = TBAR + 0x900 - 4; + continue; + } +#endif + + instruction = MEM(u_long , LONG, pc); + +switch(OPCD) { + +case 0: ILLEGAL; +case 1: ILLEGAL; +case 2: ILLEGAL; +case 3: /* UNIMP("twi"); */ +/* Hack to speed-up Forth dictionary searches */ + RA = (u_long) xfindnext((u_char *)reg[3], (long)reg[4], (long)reg[5], + (u_long)reg[6], (u_long *)reg[7]); + break; +case 4: ILLEGAL; +case 5: ILLEGAL; +case 6: ILLEGAL; +case 7: INSTR("mulli"); RD = RA * SIMM; break; + +case 8: INSTR("subfic"); + RD = SIMM - RA; + UPDATE_CA(RD,SIMM); + break; + +case 9: POWER("dozi"); + +case 10: INSTR("cmpli"); +/*DEBUG*/ if (L) UNIMP("cmpli - 64-bit"); + if (CRFD) + DO_UPDATE_CRFD(RA, UIMM, CRFD) + else + DO_UPDATE_CR(RA, UIMM) + break; + +case 11: INSTR("cmpi"); +/*DEBUG*/ if (L) UNIMP("cmpi - 64-bit"); + if (CRFD) + DO_UPDATE_CRFD((long)RA, SIMM, CRFD) + else + DO_UPDATE_CR((long)RA, SIMM) + break; + +case 12: INSTR("addic"); + RD = RA + SIMM; + UPDATE_CA(RD,SIMM); + break; + +case 13: INSTR("addic."); + RD = RA + SIMM; + UPDATE_CA(RD,SIMM); + DO_UPDATE_CR((long)RD, 0); + break; + +case 14: INSTR("addi"); RD = RA0 + SIMM; break; +case 15: INSTR("addis"); RD = RA0 + (SIMM << 16); break; + +case 16: INSTR("bcX"); + CONDITION + if ( cond_ok ) + pc = (BD << 2) + (AA ? 0 : CIA) - 4; + break; + +case 17: UNIMP("sc"); + +case 18: INSTR("bX"); + if (LK) + LR = CIA+4; + pc = (LI << 2) + (AA ? 0 : CIA) - 4; + break; + +case 19: + switch(OP2) { + case 16: INSTR("bclr"); + CONDITION +/* XXX Possible problem with updating the link register before using it */ + if ( cond_ok ) + pc = LR - 4; + break; + case 50: INSTR("rfi"); + MSR = SRR1; + pc = SRR0 - 4; + break; + case 150: INSTR("isync"); break; + case 528: INSTR("bcctr"); +#ifdef SIMNEXT +#define W reg[25] +#define BASE reg[26] +#define UP reg[27] +#define IP reg[29] +#define RP reg[30] +#define DOCOLON 0x10 +#define UNNEST 0x848 + if (instruction == 0x4e800420 && CTR == UP +/* + * If the first instruction of next is a branch, the Forth source + * debugger is active, in which case we don't want to do the fast + * next simulation. + */ + && (MEM(u_long, LONG, CTR) >> 26) != 18) { + + next: + + /* Recognize unnest from the unrelocated token value */ + IP += sizeof(u_long); + while ((temp = *(u_long *)IP) == UNNEST) { + IP += sizeof(u_long); + IP = *(u_long *)RP; + RP += sizeof(u_long); + } + + /* Recognize docolon from the unrelocated code field */ + if ((temp = *(u_long *)(W = temp + BASE)) == DOCOLON) { + RP -= sizeof(u_long); + *(u_long *)RP = IP; + IP = W; + goto next; + } + + /* -4 is an artifact of the simulator implementation */ + pc = temp + BASE - 4; + break; + } +#endif + CONDITION + if ( cond_ok ) + pc = CTR - 4; + break; + default: UNIMP("CR logical ops"); + } + break; +case 20: INSTR("rlwimi"); RA = (RA & ~MASK) | (ROTATE(RS,SH) & MASK); + UPDATE_CR(RA); break; +case 21: INSTR("rlwinm"); RA = ROTATE(RS,SH) & MASK; UPDATE_CR(RA); break; +case 22: POWER("rlmi"); +case 23: INSTR("rlwnm"); RA = ROTATE(RS,RB) & MASK; UPDATE_CR(RA); break; +case 24: INSTR("ori"); RA = RS | UIMM; break; +case 25: INSTR("oris"); RA = RS | (UIMM << 16); break; +case 26: INSTR("xori"); RA = RS ^ UIMM; break; +case 27: INSTR("xoris"); RA = RS ^ (UIMM << 16); break; +case 28: INSTR("andi."); RA = RS & UIMM; + DO_UPDATE_CR((long)RA, 0); break; +case 29: INSTR("andis."); RA = RS & (UIMM << 16); + DO_UPDATE_CR((long)RA, 0); break; +case 30: ILLEGAL; +/* case 31 is at the end */ +case 32: INSTR("lwz"); RD = MEM(u_long , LONG, RA0+ D ); break; +case 33: INSTR("lwzu"); RD = MEM(u_long , LONG, RA = (RA + D)); break; +case 34: INSTR("lbz"); RD = MEM(u_char , BYTE, RA0+ D ); break; +case 35: INSTR("lbzu"); RD = MEM(u_char , BYTE, RA = (RA + D)); break; +case 36: INSTR("stw"); MEM(u_long , LONG, RA0+ D ) = RS; break; +case 37: INSTR("stwu"); MEM(u_long , LONG, RA = (RA + D)) = RS; break; +case 38: INSTR("stb"); MEM(u_char , BYTE, RA0+ D ) = RS; break; +case 39: INSTR("stbu"); MEM(u_char , BYTE, RA = (RA + D)) = RS; break; +case 40: INSTR("lhz"); RD = MEM(u_short, WORD, RA0+ D ); break; +case 41: INSTR("lhzu"); RD = MEM(u_short, WORD, RA = (RA + D)); break; +case 42: INSTR("lha"); RD = MEM( short, WORD, RA0+ D ); break; +case 43: INSTR("lhau"); RD = MEM( short, WORD, RA = (RA + D)); break; +case 44: INSTR("sth"); MEM(u_short, WORD, RA0+ D ) = RS; break; +case 45: INSTR("sthu"); MEM(u_short, WORD, RA = (RA + D)) = RS; break; +case 46: INSTR("lmw"); { + u_long *src, *dst; +#ifdef BI_ENDIAN + if (LONG) + goto illegal; + /* Should be an alignment exception */ +#endif + dst = &(RD); + src = (u_long *)(&mem[MAP(RA0+D)]); + while (dst < ®[32]) + *dst++ = *src++; + } + break; +case 47: INSTR("stmw"); { + u_long *src, *dst; +#ifdef BI_ENDIAN + if (LONG) + goto illegal; + /* Should be an alignment exception */ +#endif + dst = (u_long *)(&mem[MAP(RA0+D)]); + src = &(RS); + while (src < ®[32]) + *dst++ = *src++; + } + break; +case 48: UNIMP("lfs"); +case 49: UNIMP("lfsu"); +case 50: UNIMP("lfd"); +case 51: UNIMP("lfdu"); +case 52: UNIMP("stfs"); +case 53: UNIMP("stfsu"); +case 54: UNIMP("stfd"); +case 55: UNIMP("stfdu"); +case 56: ILLEGAL; +case 57: ILLEGAL; +case 58: ILLEGAL; +case 59: UNIMP("Single Floating Point"); +case 60: ILLEGAL; +case 61: ILLEGAL; +case 62: ILLEGAL; +case 63: UNIMP("Double Floating Point"); +case 31: + +switch(OP2) { +case 0: INSTR("cmp"); +/*DEBUG*/ if (L) UNIMP("cmp - 64-bit"); + if (CRFD) + DO_UPDATE_CRFD((long)RA, (long)RB, CRFD) + else + DO_UPDATE_CR((long)RA, (long)RB) + + break; +case 1: ILLEGAL; +case 2: ILLEGAL; +case 3: ILLEGAL; +case 4: +#ifdef notdef + UNIMP("tw"); +#else + /* tw */ + /* Handle Forth wrapper calls - the call# is in RA */ + reg[3] = (*(long (*) ())(*(long *)(arg1 + RA))) + (reg[3],reg[4],reg[5],reg[6],reg[7], reg[8]); + break; +#endif +case 5: ILLEGAL; +case 6: ILLEGAL; +case 7: ILLEGAL; +case 8: INSTR("subfc"); SUBC(RB,RA); break; +case 9: ILLEGAL; +case 10: INSTR("addc"); ADDC(RB,RA); break; +case 11: INSTR("mulhwu"); + umtimes((u_long *)&RD, (u_long *)&scratch, RA, RB); UPDATE_CR(RD); break; +case 12: ILLEGAL; +case 13: ILLEGAL; +case 14: ILLEGAL; +case 15: ILLEGAL; +case 16: ILLEGAL; +case 17: ILLEGAL; +case 18: ILLEGAL; +case 19: INSTR("mfcr"); RD = CR.all; break; +case 20: UNIMP("lwarx"); +case 21: ILLEGAL; +case 22: ILLEGAL; +case 23: INSTR("lwzx"); RD = MEM(u_long , LONG, RA0 + RB); break; +case 24: INSTR("slw"); LOGIC( (RB & 0x20 ? 0 : RS << (RB & 0x1f)) ); break; +case 25: ILLEGAL; +case 26: INSTR("cntlzw"); + temp = RS; + for(scratch = 0; + scratch < 32 && ((temp & 0x80000000) == 0); + scratch++) { + temp <<= 1; + } + UPDATE_CR(scratch); + RA = scratch; + break; +case 27: ILLEGAL; +case 28: INSTR("and"); LOGIC( RS & RB ); +case 29: POWER("maskg"); +case 30: ILLEGAL; +case 31: ILLEGAL; +case 32: INSTR("cmpl"); +/*DEBUG*/ if (L) UNIMP("cmpl - 64-bit"); + if (CRFD) + DO_UPDATE_CRFD(RA, RB, CRFD) + else + DO_UPDATE_CR(RA, RB) + break; +case 33: ILLEGAL; +case 34: ILLEGAL; +case 35: ILLEGAL; +case 36: ILLEGAL; +case 37: ILLEGAL; +case 38: ILLEGAL; +case 39: ILLEGAL; +case 40: INSTR("subf"); ADD(RB,-RA); +case 41: ILLEGAL; +case 42: ILLEGAL; +case 43: ILLEGAL; +case 44: ILLEGAL; +case 45: ILLEGAL; +case 46: ILLEGAL; +case 47: ILLEGAL; +case 48: ILLEGAL; +case 49: ILLEGAL; +case 50: ILLEGAL; +case 51: ILLEGAL; +case 52: ILLEGAL; +case 53: ILLEGAL; +case 54: INSTR("dcbst"); break; +case 55: INSTR("lwzux"); RD = MEM(u_long , LONG, RA = (RA + RB)); break; +case 56: ILLEGAL; +case 57: ILLEGAL; +case 58: ILLEGAL; +case 59: ILLEGAL; +case 60: INSTR("andc"); LOGIC( RS & ~RB ); +case 61: ILLEGAL; +case 62: ILLEGAL; +case 63: ILLEGAL; +case 64: ILLEGAL; +case 65: ILLEGAL; +case 66: ILLEGAL; +case 67: ILLEGAL; +case 68: ILLEGAL; +case 69: ILLEGAL; +case 70: ILLEGAL; +case 71: ILLEGAL; +case 72: ILLEGAL; +case 73: ILLEGAL; +case 74: ILLEGAL; +case 75: INSTR("mulhw"); + { + int negative = ((long)(RA ^ RB)) < 0; + long highres; + long op1 = ((long)RA < 0) ? -(long)RA : RA; + long op2 = ((long)RB < 0) ? -(long)RB : RB; + umtimes((u_long *)&highres, (u_long *)&scratch, op1, op2); + RD = negative ? (~highres) + (scratch==0) : highres; + UPDATE_CR(RD); + break; + } + +case 76: ILLEGAL; +case 77: ILLEGAL; +case 78: ILLEGAL; +case 79: ILLEGAL; +case 80: ILLEGAL; +case 81: ILLEGAL; +case 82: ILLEGAL; +case 83: INSTR("mfmsr"); RD = MSR; break; +case 84: ILLEGAL; +case 85: ILLEGAL; +case 86: INSTR("dcbf"); break; +case 87: INSTR("lbzx"); RD = MEM(u_char , BYTE, RA0 + RB); break; +case 88: ILLEGAL; +case 89: ILLEGAL; +case 90: ILLEGAL; +case 91: ILLEGAL; +case 92: ILLEGAL; +case 93: ILLEGAL; +case 94: ILLEGAL; +case 95: ILLEGAL; +case 96: ILLEGAL; +case 97: ILLEGAL; +case 98: ILLEGAL; +case 99: ILLEGAL; +case 100: ILLEGAL; +case 101: ILLEGAL; +case 102: ILLEGAL; +case 103: ILLEGAL; +case 104: INSTR("neg"); ADD(0,-RA); +case 105: ILLEGAL; +case 106: ILLEGAL; +case 107: POWER("mul"); +case 108: ILLEGAL; +case 109: ILLEGAL; +case 110: ILLEGAL; +case 111: ILLEGAL; +case 112: ILLEGAL; +case 113: ILLEGAL; +case 114: ILLEGAL; +case 115: ILLEGAL; +case 116: ILLEGAL; +case 117: ILLEGAL; +case 118: ILLEGAL; +case 119: INSTR("lbzux"); RD = MEM(u_char , BYTE, RA = (RA + RB)); break; +case 120: ILLEGAL; +case 121: ILLEGAL; +case 122: ILLEGAL; +case 123: ILLEGAL; +case 124: INSTR("nor"); LOGIC( ~(RS | RB) ); +case 125: ILLEGAL; +case 126: ILLEGAL; +case 127: ILLEGAL; +case 128: ILLEGAL; +case 129: ILLEGAL; +case 130: ILLEGAL; +case 131: ILLEGAL; +case 132: ILLEGAL; +case 133: ILLEGAL; +case 134: ILLEGAL; +case 135: ILLEGAL; +case 136: INSTR("subfe"); + if (XER.bits.CA) { + SUBC(RB,RA); + } else { + ADDC(RB,~RA); + } + break; +case 137: ILLEGAL; +case 138: INSTR("adde"); +/* printf("adde: XER.bits.CA=%d RB %x -~RA %x\n", XER.bits.CA, RB, -(~RA)); */ + if (XER.bits.CA) { + ADDC(RB,-(~RA)); + } else { + ADDC(RB,RA); + } + break; +case 139: ILLEGAL; +case 140: ILLEGAL; +case 141: ILLEGAL; +case 142: ILLEGAL; +case 143: ILLEGAL; +case 144: INSTR("mtcrf"); CR.all = RS; break; /* XXX Ignores field mask */ +case 145: ILLEGAL; +case 146: INSTR("mtmsr"); MSR = RD; break; +case 147: ILLEGAL; +case 148: ILLEGAL; +case 149: ILLEGAL; +case 150: UNIMP("stwcx"); +case 151: INSTR("stwx"); MEM(u_long , LONG, RA0 + RB) = RS; break; +case 152: POWER("slq"); +case 153: POWER("sle"); +case 154: ILLEGAL; +case 155: ILLEGAL; +case 156: ILLEGAL; +case 157: ILLEGAL; +case 158: ILLEGAL; +case 159: ILLEGAL; +case 160: ILLEGAL; +case 161: ILLEGAL; +case 162: ILLEGAL; +case 163: ILLEGAL; +case 164: ILLEGAL; +case 165: ILLEGAL; +case 166: ILLEGAL; +case 167: ILLEGAL; +case 168: ILLEGAL; +case 169: ILLEGAL; +case 170: ILLEGAL; +case 171: ILLEGAL; +case 172: ILLEGAL; +case 173: ILLEGAL; +case 174: ILLEGAL; +case 175: ILLEGAL; +case 176: ILLEGAL; +case 177: ILLEGAL; +case 178: ILLEGAL; +case 179: ILLEGAL; +case 180: ILLEGAL; +case 181: ILLEGAL; +case 182: ILLEGAL; +case 183: INSTR("stwux"); MEM(u_long , LONG, RA = (RA + RB)) = RS; break; +case 184: POWER("sliq"); +case 185: ILLEGAL; +case 186: ILLEGAL; +case 187: ILLEGAL; +case 188: ILLEGAL; +case 189: ILLEGAL; +case 190: ILLEGAL; +case 191: ILLEGAL; +case 192: ILLEGAL; +case 193: ILLEGAL; +case 194: ILLEGAL; +case 195: ILLEGAL; +case 196: ILLEGAL; +case 197: ILLEGAL; +case 198: ILLEGAL; +case 199: ILLEGAL; +case 200: INSTR("subfze"); ADDC(~RA,XER.bits.CA); break; +case 201: ILLEGAL; +case 202: INSTR("addze"); ADDC(RA,XER.bits.CA); break; +case 203: ILLEGAL; +case 204: ILLEGAL; +case 205: ILLEGAL; +case 206: ILLEGAL; +case 207: ILLEGAL; +case 208: ILLEGAL; +case 209: ILLEGAL; +case 210: +#ifdef MMU + INSTR("mtsr"); SR = RS; break; +#else + UNIMP("mtsr"); +#endif +case 211: ILLEGAL; +case 212: ILLEGAL; +case 213: ILLEGAL; +case 214: ILLEGAL; +case 215: INSTR("stbx"); MEM(u_char , BYTE, RA0 + RB) = RS; break; +case 216: POWER("sllq"); +case 217: POWER("sleq"); +case 218: ILLEGAL; +case 219: ILLEGAL; +case 220: ILLEGAL; +case 221: ILLEGAL; +case 222: ILLEGAL; +case 223: ILLEGAL; +case 224: ILLEGAL; +case 225: ILLEGAL; +case 226: ILLEGAL; +case 227: ILLEGAL; +case 228: ILLEGAL; +case 229: ILLEGAL; +case 230: ILLEGAL; +case 231: ILLEGAL; +case 232: UNIMP("subfme"); +case 233: ILLEGAL; +case 234: UNIMP("addme"); +case 235: INSTR("mullw"); + umtimes((u_long *)&scratch, (u_long *)&RD, RA, RB); +#ifdef OVERFLOWS + if (OE) { + XER.bits.SO |= (XER.bits.OV = (scratch != 0)); + } +#endif + UPDATE_CR(RD); + break; +case 236: ILLEGAL; +case 237: ILLEGAL; +case 238: ILLEGAL; +case 239: ILLEGAL; +case 240: ILLEGAL; +case 241: ILLEGAL; +case 242: +#ifdef MMU + INSTR("mtsrin"); seg[RB] = RS; break; +#else + UNIMP("mtsrin"); +#endif +case 243: ILLEGAL; +case 244: ILLEGAL; +case 245: ILLEGAL; +case 246: INSTR("dcbtst"); break; +case 247: INSTR("stbux"); MEM(u_char , BYTE, RA = (RA + RB)) = RS; break; +case 248: POWER("slliq"); +case 249: ILLEGAL; +case 250: ILLEGAL; +case 251: ILLEGAL; +case 252: ILLEGAL; +case 253: ILLEGAL; +case 254: ILLEGAL; +case 255: ILLEGAL; +case 256: ILLEGAL; +case 257: ILLEGAL; +case 258: ILLEGAL; +case 259: ILLEGAL; +case 260: ILLEGAL; +case 261: ILLEGAL; +case 262: ILLEGAL; +case 263: ILLEGAL; +case 264: POWER("doz"); +case 265: ILLEGAL; +case 266: INSTR("add"); + temp = RB + RA; + UPDATE_OV(temp,RB,RA); + UPDATE_CR(temp); + RD = temp; + break; +case 267: ILLEGAL; +case 268: ILLEGAL; +case 269: ILLEGAL; +case 270: ILLEGAL; +case 271: ILLEGAL; +case 272: ILLEGAL; +case 273: ILLEGAL; +case 274: ILLEGAL; +case 275: ILLEGAL; +case 276: ILLEGAL; +case 277: POWER("lscbx"); +case 278: INSTR("dcbt"); break; +case 279: INSTR("lhzx"); RD = MEM(u_short, WORD, RA0 + RB); break; +case 280: ILLEGAL; +case 281: ILLEGAL; +case 282: ILLEGAL; +case 283: ILLEGAL; +case 284: INSTR("eqv"); LOGIC( ~(RS ^ RB) ); +case 285: ILLEGAL; +case 286: ILLEGAL; +case 287: ILLEGAL; +case 288: ILLEGAL; +case 289: ILLEGAL; +case 290: ILLEGAL; +case 291: ILLEGAL; +case 292: ILLEGAL; +case 293: ILLEGAL; +case 294: ILLEGAL; +case 295: ILLEGAL; +case 296: ILLEGAL; +case 297: ILLEGAL; +case 298: ILLEGAL; +case 299: ILLEGAL; +case 300: ILLEGAL; +case 301: ILLEGAL; +case 302: ILLEGAL; +case 303: ILLEGAL; +case 304: ILLEGAL; +case 305: ILLEGAL; +case 306: +#ifdef MMU + INSTR("tlbie"); tlbie(RB); break; +#else + UNIMP("tlbie"); +#endif +case 307: ILLEGAL; +case 308: ILLEGAL; +case 309: ILLEGAL; +case 310: UNIMP("eciwx"); /* uses RA0 */ +case 311: INSTR("lhzux"); RD = MEM(u_short, WORD, RA = (RA + RB)); break; +case 312: ILLEGAL; +case 313: ILLEGAL; +case 314: ILLEGAL; +case 315: ILLEGAL; +case 316: INSTR("xor"); LOGIC( RS ^ RB ); +case 317: ILLEGAL; +case 318: ILLEGAL; +case 319: ILLEGAL; +case 320: ILLEGAL; +case 321: ILLEGAL; +case 322: ILLEGAL; +case 323: ILLEGAL; +case 324: ILLEGAL; +case 325: ILLEGAL; +case 326: ILLEGAL; +case 327: ILLEGAL; +case 328: ILLEGAL; +case 329: ILLEGAL; +case 330: ILLEGAL; +case 331: POWER("div"); +case 332: ILLEGAL; +case 333: ILLEGAL; +case 334: ILLEGAL; +case 335: ILLEGAL; +case 336: ILLEGAL; +case 337: ILLEGAL; +case 338: ILLEGAL; +case 339: INSTR("mfspr"); + switch(SPR) { + case 1: RD = XER.all; break; + case 8: RD = LR; break; + case 9: RD = CTR; break; + case 22: RD = DEC; break; +#ifdef MMU + case 25: SDR1 = RD; break; +#endif + case 26: RD = SRR0; break; + case 27: RD = SRR1; break; + case 272: RD = SPRG0; break; + case 273: RD = SPRG1; break; + case 274: RD = SPRG2; break; + case 275: RD = SPRG3; break; + /* + * Special simulator reg. The return value indicates + * whether or not page-zero addressing is supported. + */ +#ifdef TRACE + case 287: TBAR = RD; RD = 1; break; +#else + case 287: TBAR = RD; RD = 0; break; +#endif + case 1008: RD = HID0; break; + case 1010: RD = IABR; break; + case 1023: RD = 0; break; + default: UNIMP("mfspr - bad SPR"); + } + break; +case 340: ILLEGAL; +case 341: ILLEGAL; +case 342: ILLEGAL; +case 343: INSTR("lhax"); RD = MEM(short , WORD, RA0 + RB); break; +case 344: ILLEGAL; +case 345: ILLEGAL; +case 346: ILLEGAL; +case 347: ILLEGAL; +case 348: ILLEGAL; +case 349: ILLEGAL; +case 350: ILLEGAL; +case 351: ILLEGAL; +case 352: ILLEGAL; +case 353: ILLEGAL; +case 354: ILLEGAL; +case 355: ILLEGAL; +case 356: ILLEGAL; +case 357: ILLEGAL; +case 358: ILLEGAL; +case 359: ILLEGAL; +case 360: POWER("abs"); +case 361: ILLEGAL; +case 362: ILLEGAL; +case 363: POWER("divs"); +case 364: ILLEGAL; +case 365: ILLEGAL; +case 366: ILLEGAL; +case 367: ILLEGAL; +case 368: ILLEGAL; +case 369: ILLEGAL; +case 370: ILLEGAL; +case 371: INSTR("mftb"); + { + extern void gettime(); + + switch(SPR) { + case 268: gettime((long *)0, (long *)&RD); break; + case 269: gettime((long *)&RD, (long *)0); break; + default: UNIMP("mftbf - bad TBR"); + } + } + break; + +case 372: ILLEGAL; +case 373: ILLEGAL; +case 374: ILLEGAL; +case 375: INSTR("lhaux"); RD = MEM(short , WORD, RA = (RA + RB)); break; +case 376: ILLEGAL; +case 377: ILLEGAL; +case 378: ILLEGAL; +case 379: ILLEGAL; +case 380: ILLEGAL; +case 381: ILLEGAL; +case 382: ILLEGAL; +case 383: ILLEGAL; +case 384: ILLEGAL; +case 385: ILLEGAL; +case 386: ILLEGAL; +case 387: ILLEGAL; +case 388: ILLEGAL; +case 389: ILLEGAL; +case 390: ILLEGAL; +case 391: ILLEGAL; +case 392: ILLEGAL; +case 393: ILLEGAL; +case 394: ILLEGAL; +case 395: ILLEGAL; +case 396: ILLEGAL; +case 397: ILLEGAL; +case 398: ILLEGAL; +case 399: ILLEGAL; +case 400: ILLEGAL; +case 401: ILLEGAL; +case 402: ILLEGAL; +case 403: ILLEGAL; +case 404: ILLEGAL; +case 405: ILLEGAL; +case 406: ILLEGAL; +case 407: INSTR("sthx"); MEM(u_short, WORD, RA0 + RB) = RS; break; +case 408: ILLEGAL; +case 409: ILLEGAL; +case 410: ILLEGAL; +case 411: ILLEGAL; +case 412: INSTR("orc"); LOGIC( RS | ~RB); +case 413: ILLEGAL; +case 414: ILLEGAL; +case 415: ILLEGAL; +case 416: ILLEGAL; +case 417: ILLEGAL; +case 418: ILLEGAL; +case 419: ILLEGAL; +case 420: ILLEGAL; +case 421: ILLEGAL; +case 422: ILLEGAL; +case 423: ILLEGAL; +case 424: ILLEGAL; +case 425: ILLEGAL; +case 426: ILLEGAL; +case 427: ILLEGAL; +case 428: ILLEGAL; +case 429: ILLEGAL; +case 430: ILLEGAL; +case 431: ILLEGAL; +case 432: ILLEGAL; +case 433: ILLEGAL; +case 434: ILLEGAL; +case 435: ILLEGAL; +case 436: ILLEGAL; +case 437: ILLEGAL; +case 438: UNIMP("ecowx"); /* uses RA0 */ +case 439: INSTR("sthux"); MEM(u_short, WORD, RA = (RA + RB)) = RS; break; +case 440: ILLEGAL; +case 441: ILLEGAL; +case 442: ILLEGAL; +case 443: ILLEGAL; +case 444: INSTR("or"); LOGIC( RS | RB ); +case 445: ILLEGAL; +case 446: ILLEGAL; +case 447: ILLEGAL; +case 448: ILLEGAL; +case 449: ILLEGAL; +case 450: ILLEGAL; +case 451: ILLEGAL; +case 452: ILLEGAL; +case 453: ILLEGAL; +case 454: ILLEGAL; +case 455: ILLEGAL; +case 456: ILLEGAL; +case 457: ILLEGAL; +case 458: ILLEGAL; +case 459: INSTR("divwu"); RD = (u_long)RA / (u_long)RB; UPDATE_CR(RD); break; + /* XXX Overflow is not handled */ +case 460: ILLEGAL; +case 461: ILLEGAL; +case 462: ILLEGAL; +case 463: ILLEGAL; +case 464: ILLEGAL; +case 465: ILLEGAL; +case 466: ILLEGAL; +case 467: INSTR("mtspr"); + switch (SPR) { + case 1: XER.all = RD; break; + case 8: LR = RD; break; + case 9: CTR = RD; break; + case 22: DEC = RD; break; +#ifdef MMU + case 25: SDR1 = RD; break; +#endif + case 26: SRR0 = RD; break; + case 27: SRR1 = RD; break; + case 272: SPRG0 = RD; break; + case 273: SPRG1 = RD; break; + case 274: SPRG2 = RD; break; + case 275: SPRG3 = RD; break; + case 1008: HID0 = RD; +#ifdef BI_ENDIAN + if (HID0 & 8) { + LONG = 4; WORD = 6; BYTE = 7; + } else { + LONG = 0; WORD = 0; BYTE = 0; + } +#endif + break; + case 1010: IABR = RD; break; + default: UNIMP("mtspr - bad SPR"); + } + break; +case 468: ILLEGAL; +case 469: ILLEGAL; +case 470: INSTR("dcbi"); break; +case 471: ILLEGAL; +case 472: ILLEGAL; +case 473: ILLEGAL; +case 474: ILLEGAL; +case 475: ILLEGAL; +case 476: INSTR("nand"); LOGIC( ~(RS & RB) ); +case 477: ILLEGAL; +case 478: ILLEGAL; +case 479: ILLEGAL; +case 480: ILLEGAL; +case 481: ILLEGAL; +case 482: ILLEGAL; +case 483: ILLEGAL; +case 484: ILLEGAL; +case 485: ILLEGAL; +case 486: ILLEGAL; +case 487: ILLEGAL; +case 488: POWER("nabs"); +case 489: ILLEGAL; +case 490: ILLEGAL; +case 491: INSTR("divw"); RD = RA / RB; UPDATE_CR(RD); break; + /* XXX Overflow is not handled */ +case 492: ILLEGAL; +case 493: ILLEGAL; +case 494: ILLEGAL; +case 495: ILLEGAL; +case 496: ILLEGAL; +case 497: ILLEGAL; +case 498: ILLEGAL; +case 499: ILLEGAL; +case 500: ILLEGAL; +case 501: ILLEGAL; +case 502: ILLEGAL; +case 503: ILLEGAL; +case 504: ILLEGAL; +case 505: ILLEGAL; +case 506: ILLEGAL; +case 507: ILLEGAL; +case 508: ILLEGAL; +case 509: ILLEGAL; +case 510: ILLEGAL; +case 511: ILLEGAL; +case 512: UNIMP("mcrxr"); +case 513: ILLEGAL; +case 514: ILLEGAL; +case 515: ILLEGAL; +case 516: ILLEGAL; +case 517: ILLEGAL; +case 518: ILLEGAL; +case 519: ILLEGAL; +case 520: ILLEGAL; +case 521: ILLEGAL; +case 522: ILLEGAL; +case 523: ILLEGAL; +case 524: ILLEGAL; +case 525: ILLEGAL; +case 526: ILLEGAL; +case 527: ILLEGAL; +case 528: ILLEGAL; +case 529: ILLEGAL; +case 530: ILLEGAL; +case 531: POWER("clcs"); +case 532: ILLEGAL; +case 533: UNIMP("lswx"); +case 534: INSTR("lwbrx"); + temp = MEM(u_long , LONG, RA0 + RB); + RD = ((temp << 24) & 0xff000000) | + ((temp << 8) & 0x00ff0000) | + ((temp >> 8) & 0x0000ff00) | + ((temp >> 24) & 0x000000ff); + break; +case 535: UNIMP("lfsx"); +/* XXX is it bit 16 or bit 26? */ +case 536: INSTR("srw"); LOGIC( (RB & 0x10020 ? 0 : RS >> (RB & 0x1f)) ); break; +case 537: POWER("rrib"); +case 538: ILLEGAL; +case 539: ILLEGAL; +case 540: ILLEGAL; +case 541: POWER("maskir"); +case 542: ILLEGAL; +case 543: ILLEGAL; +case 544: ILLEGAL; +case 545: ILLEGAL; +case 546: ILLEGAL; +case 547: ILLEGAL; +case 548: ILLEGAL; +case 549: ILLEGAL; +case 550: ILLEGAL; +case 551: ILLEGAL; +case 552: ILLEGAL; +case 553: ILLEGAL; +case 554: ILLEGAL; +case 555: ILLEGAL; +case 556: ILLEGAL; +case 557: ILLEGAL; +case 558: ILLEGAL; +case 559: ILLEGAL; +case 560: ILLEGAL; +case 561: ILLEGAL; +case 562: ILLEGAL; +case 563: ILLEGAL; +case 564: ILLEGAL; +case 565: ILLEGAL; +case 566: +#ifdef MMU + INSTR("tlbsync"); break; +#else + UNIMP("tlbsync"); +#endif +case 567: UNIMP("lfsux"); +case 568: ILLEGAL; +case 569: ILLEGAL; +case 570: ILLEGAL; +case 571: ILLEGAL; +case 572: ILLEGAL; +case 573: ILLEGAL; +case 574: ILLEGAL; +case 575: ILLEGAL; +case 576: ILLEGAL; +case 577: ILLEGAL; +case 578: ILLEGAL; +case 579: ILLEGAL; +case 580: ILLEGAL; +case 581: ILLEGAL; +case 582: ILLEGAL; +case 583: ILLEGAL; +case 584: ILLEGAL; +case 585: ILLEGAL; +case 586: ILLEGAL; +case 587: ILLEGAL; +case 588: ILLEGAL; +case 589: ILLEGAL; +case 590: ILLEGAL; +case 591: ILLEGAL; +case 592: ILLEGAL; +case 593: ILLEGAL; +case 594: ILLEGAL; +case 595: +#ifdef MMU + INSTR("mfsr"); RD = SR; break; +#else + UNIMP("mfsr"); +#endif +case 596: ILLEGAL; +case 597: UNIMP("lswi"); +case 598: INSTR("sync"); break; +case 599: UNIMP("lfdx"); +case 600: ILLEGAL; +case 601: ILLEGAL; +case 602: ILLEGAL; +case 603: ILLEGAL; +case 604: ILLEGAL; +case 605: ILLEGAL; +case 606: ILLEGAL; +case 607: ILLEGAL; +case 608: ILLEGAL; +case 609: ILLEGAL; +case 610: ILLEGAL; +case 611: ILLEGAL; +case 612: ILLEGAL; +case 613: ILLEGAL; +case 614: ILLEGAL; +case 615: ILLEGAL; +case 616: ILLEGAL; +case 617: ILLEGAL; +case 618: ILLEGAL; +case 619: ILLEGAL; +case 620: ILLEGAL; +case 621: ILLEGAL; +case 622: ILLEGAL; +case 623: ILLEGAL; +case 624: ILLEGAL; +case 625: ILLEGAL; +case 626: ILLEGAL; +case 627: ILLEGAL; +case 628: ILLEGAL; +case 629: ILLEGAL; +case 630: ILLEGAL; +case 631: UNIMP("lfdux"); +case 632: ILLEGAL; +case 633: ILLEGAL; +case 634: ILLEGAL; +case 635: ILLEGAL; +case 636: ILLEGAL; +case 637: ILLEGAL; +case 638: ILLEGAL; +case 639: ILLEGAL; +case 640: ILLEGAL; +case 641: ILLEGAL; +case 642: ILLEGAL; +case 643: ILLEGAL; +case 644: ILLEGAL; +case 645: ILLEGAL; +case 646: ILLEGAL; +case 647: ILLEGAL; +case 648: ILLEGAL; +case 649: ILLEGAL; +case 650: ILLEGAL; +case 651: ILLEGAL; +case 652: ILLEGAL; +case 653: ILLEGAL; +case 654: ILLEGAL; +case 655: ILLEGAL; +case 656: ILLEGAL; +case 657: ILLEGAL; +case 658: ILLEGAL; +case 659: +#ifdef MMU + INSTR("mfsrin"); RD = seg[RB]; break; +#else + UNIMP("mfsrin"); +#endif +case 660: ILLEGAL; +case 661: UNIMP("stswx"); +case 662: INSTR("stwbrx"); + temp = RS; + MEM(u_long , LONG, RA0 + RB) = + ((temp << 24) & 0xff000000) | + ((temp << 8) & 0x00ff0000) | + ((temp >> 8) & 0x0000ff00) | + ((temp >> 24) & 0x000000ff); + break; +case 663: UNIMP("stfsx"); +case 664: POWER("srq"); +case 665: POWER("sre"); +case 666: ILLEGAL; +case 667: ILLEGAL; +case 668: ILLEGAL; +case 669: ILLEGAL; +case 670: ILLEGAL; +case 671: ILLEGAL; +case 672: ILLEGAL; +case 673: ILLEGAL; +case 674: ILLEGAL; +case 675: ILLEGAL; +case 676: ILLEGAL; +case 677: ILLEGAL; +case 678: ILLEGAL; +case 679: ILLEGAL; +case 680: ILLEGAL; +case 681: ILLEGAL; +case 682: ILLEGAL; +case 683: ILLEGAL; +case 684: ILLEGAL; +case 685: ILLEGAL; +case 686: ILLEGAL; +case 687: ILLEGAL; +case 688: ILLEGAL; +case 689: ILLEGAL; +case 690: ILLEGAL; +case 691: ILLEGAL; +case 692: ILLEGAL; +case 693: ILLEGAL; +case 694: ILLEGAL; +case 695: UNIMP("stfsux"); +case 696: POWER("sriq"); +case 697: ILLEGAL; +case 698: ILLEGAL; +case 699: ILLEGAL; +case 700: ILLEGAL; +case 701: ILLEGAL; +case 702: ILLEGAL; +case 703: ILLEGAL; +case 704: ILLEGAL; +case 705: ILLEGAL; +case 706: ILLEGAL; +case 707: ILLEGAL; +case 708: ILLEGAL; +case 709: ILLEGAL; +case 710: ILLEGAL; +case 711: ILLEGAL; +case 712: ILLEGAL; +case 713: ILLEGAL; +case 714: ILLEGAL; +case 715: ILLEGAL; +case 716: ILLEGAL; +case 717: ILLEGAL; +case 718: ILLEGAL; +case 719: ILLEGAL; +case 720: ILLEGAL; +case 721: ILLEGAL; +case 722: ILLEGAL; +case 723: ILLEGAL; +case 724: ILLEGAL; +case 725: UNIMP("stswi"); +case 726: ILLEGAL; +case 727: UNIMP("stfdx"); +case 728: POWER("srlq"); +case 729: POWER("sreq"); +case 730: ILLEGAL; +case 731: ILLEGAL; +case 732: ILLEGAL; +case 733: ILLEGAL; +case 734: ILLEGAL; +case 735: ILLEGAL; +case 736: ILLEGAL; +case 737: ILLEGAL; +case 738: ILLEGAL; +case 739: ILLEGAL; +case 740: ILLEGAL; +case 741: ILLEGAL; +case 742: ILLEGAL; +case 743: ILLEGAL; +case 744: ILLEGAL; +case 745: ILLEGAL; +case 746: ILLEGAL; +case 747: ILLEGAL; +case 748: ILLEGAL; +case 749: ILLEGAL; +case 750: ILLEGAL; +case 751: ILLEGAL; +case 752: ILLEGAL; +case 753: ILLEGAL; +case 754: ILLEGAL; +case 755: ILLEGAL; +case 756: ILLEGAL; +case 757: ILLEGAL; +case 758: ILLEGAL; +case 759: UNIMP("stfdux"); +case 760: POWER("srliq"); +case 761: ILLEGAL; +case 762: ILLEGAL; +case 763: ILLEGAL; +case 764: ILLEGAL; +case 765: ILLEGAL; +case 766: ILLEGAL; +case 767: ILLEGAL; +case 768: ILLEGAL; +case 769: ILLEGAL; +case 770: ILLEGAL; +case 771: ILLEGAL; +case 772: ILLEGAL; +case 773: ILLEGAL; +case 774: ILLEGAL; +case 775: ILLEGAL; +case 776: ILLEGAL; +case 777: ILLEGAL; +case 778: ILLEGAL; +case 779: ILLEGAL; +case 780: ILLEGAL; +case 781: ILLEGAL; +case 782: ILLEGAL; +case 783: ILLEGAL; +case 784: ILLEGAL; +case 785: ILLEGAL; +case 786: ILLEGAL; +case 787: ILLEGAL; +case 788: ILLEGAL; +case 789: ILLEGAL; +case 790: INSTR("lhbrx"); + temp = MEM(u_short, WORD, RA0 + RB); + RD = ((temp & 0xff) << 8 ) | (temp >> 8); + break; +case 791: ILLEGAL; +case 792: INSTR("sraw"); + LOGIC( (RB & 0x20 ? (long)RS >> 31 : (long)RS >> (RB & 0x1f)) ); + break; + /* XXX handle XER.bits.CA */ +case 793: ILLEGAL; +case 794: ILLEGAL; +case 795: ILLEGAL; +case 796: ILLEGAL; +case 797: ILLEGAL; +case 798: ILLEGAL; +case 799: ILLEGAL; +case 800: ILLEGAL; +case 801: ILLEGAL; +case 802: ILLEGAL; +case 803: ILLEGAL; +case 804: ILLEGAL; +case 805: ILLEGAL; +case 806: ILLEGAL; +case 807: ILLEGAL; +case 808: ILLEGAL; +case 809: ILLEGAL; +case 810: ILLEGAL; +case 811: ILLEGAL; +case 812: ILLEGAL; +case 813: ILLEGAL; +case 814: ILLEGAL; +case 815: ILLEGAL; +case 816: ILLEGAL; +case 817: ILLEGAL; +case 818: ILLEGAL; +case 819: ILLEGAL; +case 820: ILLEGAL; +case 821: ILLEGAL; +case 822: ILLEGAL; +case 823: ILLEGAL; +case 824: INSTR("srawi"); LOGIC( (long)RS >> SH );/* XXX handle XER.bits.CA */ +case 825: ILLEGAL; +case 826: ILLEGAL; +case 827: ILLEGAL; +case 828: ILLEGAL; +case 829: ILLEGAL; +case 830: ILLEGAL; +case 831: ILLEGAL; +case 832: ILLEGAL; +case 833: ILLEGAL; +case 834: ILLEGAL; +case 835: ILLEGAL; +case 836: ILLEGAL; +case 837: ILLEGAL; +case 838: ILLEGAL; +case 839: ILLEGAL; +case 840: ILLEGAL; +case 841: ILLEGAL; +case 842: ILLEGAL; +case 843: ILLEGAL; +case 844: ILLEGAL; +case 845: ILLEGAL; +case 846: ILLEGAL; +case 847: ILLEGAL; +case 848: ILLEGAL; +case 849: ILLEGAL; +case 850: ILLEGAL; +case 851: ILLEGAL; +case 852: ILLEGAL; +case 853: ILLEGAL; +case 854: UNIMP("Old MacDonald had a farm - eieio"); +case 855: ILLEGAL; +case 856: ILLEGAL; +case 857: ILLEGAL; +case 858: ILLEGAL; +case 859: ILLEGAL; +case 860: ILLEGAL; +case 861: ILLEGAL; +case 862: ILLEGAL; +case 863: ILLEGAL; +case 864: ILLEGAL; +case 865: ILLEGAL; +case 866: ILLEGAL; +case 867: ILLEGAL; +case 868: ILLEGAL; +case 869: ILLEGAL; +case 870: ILLEGAL; +case 871: ILLEGAL; +case 872: ILLEGAL; +case 873: ILLEGAL; +case 874: ILLEGAL; +case 875: ILLEGAL; +case 876: ILLEGAL; +case 877: ILLEGAL; +case 878: ILLEGAL; +case 879: ILLEGAL; +case 880: ILLEGAL; +case 881: ILLEGAL; +case 882: ILLEGAL; +case 883: ILLEGAL; +case 884: ILLEGAL; +case 885: ILLEGAL; +case 886: ILLEGAL; +case 887: ILLEGAL; +case 888: ILLEGAL; +case 889: ILLEGAL; +case 890: ILLEGAL; +case 891: ILLEGAL; +case 892: ILLEGAL; +case 893: ILLEGAL; +case 894: ILLEGAL; +case 895: ILLEGAL; +case 896: ILLEGAL; +case 897: ILLEGAL; +case 898: ILLEGAL; +case 899: ILLEGAL; +case 900: ILLEGAL; +case 901: ILLEGAL; +case 902: ILLEGAL; +case 903: ILLEGAL; +case 904: ILLEGAL; +case 905: ILLEGAL; +case 906: ILLEGAL; +case 907: ILLEGAL; +case 908: ILLEGAL; +case 909: ILLEGAL; +case 910: ILLEGAL; +case 911: ILLEGAL; +case 912: ILLEGAL; +case 913: ILLEGAL; +case 914: ILLEGAL; +case 915: ILLEGAL; +case 916: ILLEGAL; +case 917: ILLEGAL; +case 918: INSTR("sthbrx"); + temp = RS & 0xffff; + MEM(u_short, WORD, RA0 + RB) = ((temp & 0xff) << 8 ) | (temp >> 8); + break; +case 919: ILLEGAL; +case 920: POWER("sraq"); +case 921: POWER("srea"); +case 922: INSTR("extsh"); LOGIC( (long)(RS << 16) >> 16 ); +case 923: ILLEGAL; +case 924: ILLEGAL; +case 925: ILLEGAL; +case 926: ILLEGAL; +case 927: ILLEGAL; +case 928: ILLEGAL; +case 929: ILLEGAL; +case 930: ILLEGAL; +case 931: ILLEGAL; +case 932: ILLEGAL; +case 933: ILLEGAL; +case 934: ILLEGAL; +case 935: ILLEGAL; +case 936: ILLEGAL; +case 937: ILLEGAL; +case 938: ILLEGAL; +case 939: ILLEGAL; +case 940: ILLEGAL; +case 941: ILLEGAL; +case 942: ILLEGAL; +case 943: ILLEGAL; +case 944: ILLEGAL; +case 945: ILLEGAL; +case 946: ILLEGAL; +case 947: ILLEGAL; +case 948: ILLEGAL; +case 949: ILLEGAL; +case 950: ILLEGAL; +case 951: ILLEGAL; +case 952: POWER("sraiq"); +case 953: ILLEGAL; +case 954: INSTR("extsb"); LOGIC( (long)(RS << 24) >> 24 ); +case 955: ILLEGAL; +case 956: ILLEGAL; +case 957: ILLEGAL; +case 958: ILLEGAL; +case 959: ILLEGAL; +case 960: ILLEGAL; +case 961: ILLEGAL; +case 962: ILLEGAL; +case 963: ILLEGAL; +case 964: ILLEGAL; +case 965: ILLEGAL; +case 966: ILLEGAL; +case 967: ILLEGAL; +case 968: ILLEGAL; +case 969: ILLEGAL; +case 970: ILLEGAL; +case 971: ILLEGAL; +case 972: ILLEGAL; +case 973: ILLEGAL; +case 974: ILLEGAL; +case 975: ILLEGAL; +case 976: ILLEGAL; +case 977: ILLEGAL; +case 978: +#ifdef MMU + INSTR("tlbld"); ONLY603 mmutab[RB >> 12] = RPA & 0xfffff00; break; +#else + UNIMP("tlbld"); +#endif +case 979: ILLEGAL; +case 980: ILLEGAL; +case 981: ILLEGAL; +case 982: INSTR("icbi"); break; +case 983: ILLEGAL; +case 984: ILLEGAL; +case 985: ILLEGAL; +case 986: ILLEGAL; +case 987: ILLEGAL; +case 988: ILLEGAL; +case 989: ILLEGAL; +case 990: ILLEGAL; +case 991: ILLEGAL; +case 992: ILLEGAL; +case 993: ILLEGAL; +case 994: ILLEGAL; +case 995: ILLEGAL; +case 996: ILLEGAL; +case 997: ILLEGAL; +case 998: ILLEGAL; +case 999: ILLEGAL; +case 1000: ILLEGAL; +case 1001: ILLEGAL; +case 1002: ILLEGAL; +case 1003: ILLEGAL; +case 1004: ILLEGAL; +case 1005: ILLEGAL; +case 1006: ILLEGAL; +case 1007: ILLEGAL; +case 1008: ILLEGAL; +case 1009: ILLEGAL; +case 1010: +#ifdef MMU + INSTR("tlbli"); ONLY603 mmutab[RB >> 12] = RPA & 0xfffff00; break; +#else + UNIMP("tlbli"); +#endif +case 1011: ILLEGAL; +case 1012: ILLEGAL; +case 1013: ILLEGAL; +case 1014: UNIMP("dcbz"); +case 1015: ILLEGAL; +case 1016: ILLEGAL; +case 1017: ILLEGAL; +case 1018: ILLEGAL; +case 1019: ILLEGAL; +case 1020: ILLEGAL; +case 1021: ILLEGAL; +case 1022: ILLEGAL; +case 1023: ILLEGAL; + } /* End of big 31-class switch */ + } /* End of main opcode switch */ + + continue; +power: + if (!TBAR) + printf("Unimplemented POWER instruction %08lx (%s) at %lx\n", + (long)instruction, (long)opname, (long)CIA); + goto trapout; + +unimplemented: + if (!TBAR) + printf("Unimplemented instruction %08lx (%s)at %lx\n", + (long)instruction, (long)opname, (long)CIA); + goto trapout; + +illegal: + if (!TBAR) + printf("Illegal instruction %08lx at %lx\n", + (long)instruction, (long)CIA, (long)0); + +trapout: + if (TBAR) { + SRR0 = CIA; + SRR1 = MSR; + pc = TBAR + 0x700 - 4; + continue; + } else + return; + + } /* End of main loop */ +} + + +umtimes(dhighp, dlowp, u1, u2) + u_long *dhighp, *dlowp; + u_long u1, u2; +{ + register u_long ah, al, bh, bl, tmp; + extern void dplus(); + + ah = u1>>16; al = u1 & 0xffff; + bh = u2>>16; bl = u2 & 0xffff; + + *dhighp = ah*bh; *dlowp = al*bl; + + tmp = ah*bl; + dplus((long *)dhighp, (long *)dlowp, (long)(tmp>>16), (long)(tmp<<16)); + + tmp = al*bh; + dplus((long *)dhighp, (long *)dlowp, (long)(tmp>>16), (long)(tmp<<16)); +} + +/* Carry calculation assumes 2's complement arithmetic. */ +#define CARRY(res,b) ((u_long)res < (u_long)b) + +void +dplus(dhighp, dlowp, shigh, slow) + register long *dhighp, *dlowp, shigh, slow; +{ + register long lowres; + + lowres = *dlowp + slow; + *dhighp += shigh + CARRY(lowres, slow); + *dlowp = lowres; +} + + +#ifdef TRACE +#include <sys/signal.h> +dumpregs() +{ +#ifdef ARGREGS + printf( + " r0 r1 r2 r3 r4 r5\n" + ); + printf( + "%8x %8x %8x %8x %8x %8x\n\n", + greg[ 0], greg[ 1], greg[ 2], greg[ 3], greg[ 4], greg[ 5] + ); + + printf( + " r6 r7 r8 r9 r10 r11\n" + ); + printf( + "%8x %8x %8x %8x %8x %8x\n\n", + greg[ 6], greg[ 7], greg[ 8], greg[ 9], greg[10], greg[11] + ); +#endif + printf( + " r20 t0 r21 t1 r22 t2 r23 t3 r24 t4 r25 t5\n" + ); + printf( + "%8x %8x %8x %8x %8x %8x\n\n", + greg[20], greg[21], greg[22], greg[23], greg[24], greg[25] + ); + printf( + " r26 base r27 up r28 tos r29 ip r30 rp r31 sp\n" + ); + printf( + "%8x %8x %8x %8x %8x %8x\n\n", + greg[26], greg[27], greg[28], greg[29], greg[30], greg[31] + ); + printf("pc %x LR %x CTR %x CR %x", + pc, LR, CTR, CR.all + ); +#ifndef SIMROM + printf(" CALLS: %x", greg[29] /* IP */); + + if (greg[30]) + printf(" %x %x %x", + ((u_long *)greg[30])[0], /* Return stack */ + ((u_long *)greg[30])[1], + ((u_long *)greg[30])[2] + ); + printf("\n"); +#endif +} +dumpallregs() +{ + int i; + for (i=0; i<8 ; i++) printf("%9x", greg[i]); putchar('\n'); + for ( ; i<16; i++) printf("%9x", greg[i]); putchar('\n'); + for ( ; i<24; i++) printf("%9x", greg[i]); putchar('\n'); + for ( ; i<32; i++) printf("%9x", greg[i]); putchar('\n'); + + printf("pc %x LR %x CTR %x CR %x ", + pc, LR, CTR, CR.all + ); + printf("\n"); +} + +void +handle_signal(foo) + int foo; +{ + dumpregs(); + s_bye(1); +} +catch_signals() +{ + signal(SIGINT,handle_signal); + signal(SIGILL,handle_signal); + signal(SIGFPE,handle_signal); + signal(SIGSEGV,handle_signal); +#ifdef UNIX + signal(SIGTRAP,handle_signal); +// signal(SIGEMT,handle_signal); + signal(SIGBUS,handle_signal); +#endif +} + +dumpmem(adr) + long adr; +{ + u_long *reladr; + + reladr = (u_long *) &xmem[ (int)adr ]; + printf("%x: %8x %8x %8x %8x %8x %8x %8x %8x\n", + adr, + reladr[0], reladr[1], reladr[2], reladr[3], + reladr[4], reladr[5], reladr[6], reladr[7] + ); +} + +#ifdef SIMROM +#define GETLINE (void)c_key(); +#else +#define GETLINE +#endif +trace(name, instruction) + char *name; + u_long instruction; +{ + int done; + int arg; + int c; + static int stepping = 1; + + if (!stepping & (!IABR || pc != IABR)) + return; + + IABR = 0; + stepping = 1; + + printf("%x %x %s ", pc, greg[29], name); + for (done=0; !done; ) { + printf(" : "); +#ifndef SIMROM + putchar(c = c_key()); + putchar('\n'); +#else + c = c_key(); +#endif + switch(c) + { + case 'b': scanf("%x", &IABR); stepping = 0; break; + case 'n': IABR = greg[27]; stepping = 0; break; + case 'u': scanf("%x", &arg); + dumpmem((long)(greg[27]+arg)); + GETLINE; + break; + case 'm': scanf("%x", &arg); + dumpmem((long)arg); + GETLINE; + break; + case 'q': s_bye(0); break; + case 'r': dumpregs(); + GETLINE; + break; + case 'a': dumpallregs(); + GETLINE; + break; + case 'c': stepping = 0; done=1; GETLINE; break; + default: done=1; break; + } + } +} +#endif + +#ifdef UNIX +#include <sys/time.h> +#else +/* ARGSUSED */ +#endif +void +gettime(secp, nsecp) + long *secp, *nsecp; +{ +#ifdef UNIX + struct timeval t; + extern int gettimeofday(); + + (void) gettimeofday(&t, (struct timezone *)0); + if (secp) + *secp = t.tv_sec; + if (nsecp) + *nsecp = t.tv_usec * 1000; +#endif +} +#define TOKEN 4 +int +xfindnext(adr, strlen, base, link, alf) + register u_char *adr; + register long strlen; + register long base; + register u_long link; + u_long *alf; +{ + register u_char *s, *p; + register int namelen, len; + + while((link = *(u_long *)link + base) != base) { + link -= TOKEN; /* link is now the absolute alf */ + s = (u_char *)(link-1-strlen); + p = adr; + len = strlen; + while (len-- && *s == *p) { + s++; + p++; + } + if ((len < 0) && ((*s & 0x1f) == strlen)) { + *alf = link; + return(-1); + } + } + return(0); +} + +// 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/ppc/ppcsim/simrom.c =================================================================== --- cpu/ppc/ppcsim/simrom.c (rev 0) +++ cpu/ppc/ppcsim/simrom.c 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,62 @@ +// See license at end of file +/* + * Main routine for calling the PowerPC simulator to simulate ROM images + */ + +extern void simulate(); +extern char *malloc(); + +char *loadaddr; + +#define MEMSIZE 0x800000 + +main() +{ + int f; + if((f = open("fw.img", 0)) < 0) { + perror("can't open fw.img"); + exit(1); + } + loadaddr = malloc(MEMSIZE); + (void) read(f, loadaddr, MEMSIZE); + close(f); + simulate(loadaddr, 0x100, 0, 0, 0, 0, 0, 1 /* 0=POWER, 1=PowerPC */); + exit(0); +} +int +c_key() +{ + int i; + if ((i = getchar()) == -1) + exit (0); + return (i); +} +void +s_bye() +{ + exit(0); +} + +// 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/ppc/realcif.fth =================================================================== --- cpu/ppc/realcif.fth (rev 0) +++ cpu/ppc/realcif.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,237 @@ +purpose: Real-mode client interface fixups +\ See license at end of file + +headerless +hex + +\ The client program is required to disable i&d translation and +\ disable interrupts before making a real-mode client interface call. +\ The firmware must save and restore + + +\ XXX finish the space optimization --- after exp fixups? +\ /exc h# 18 + ( dsi ) 20 + ( dbats ) 54 + ( sprs ) +100 ( dsi ) 20 + ( dbats ) 54 + ( sprs ) +\ /rm-tlbmiss 2* + ( dtlbs ) \ add this in stand-init +200 + ( dtlbs ) +value /env + +0 value fw-env +0 value client-env + +code save-sprs ( addr1 -- addr2 ) \ 54 + addi tos,tos,-4 + mfspr t0,sdr1 stwu t0,4(tos) + mfspr t0,sprg0 stwu t0,4(tos) + mfspr t0,sprg1 stwu t0,4(tos) + mfspr t0,sprg2 stwu t0,4(tos) + mfspr t0,sprg3 stwu t0,4(tos) + set t1,h#10 + begin + addi t1,t1,-1 + rlwinm t0,t1,28,0,3 + mfsrin t0,t0 stwu t0,4(tos) + cmpi 0,0,t1,0 <= + until + addi tos,tos,4 +c; +code restore-sprs ( addr1 -- addr2 ) + addi tos,tos,-4 + lwzu t0,4(tos) mtspr sdr1,t0 + lwzu t0,4(tos) mtspr sprg0,t0 + lwzu t0,4(tos) mtspr sprg1,t0 + lwzu t0,4(tos) mtspr sprg2,t0 + lwzu t0,4(tos) mtspr sprg3,t0 + set t1,h#10 + sync \ XXX move syncs inside the loop? + isync \ XXX do we *really* need both syncs both times? + begin + addi t1,t1,-1 + rlwinm t2,t1,28,0,3 + lwzu t0,4(tos) mtsrin t0,t2 + cmpi 0,0,t1,0 <= + until + sync + isync + addi tos,tos,4 +c; + +code save-dbats ( addr1 -- addr2 ) \ 20 + mfspr t0,dbat0u stw t0,0(tos) + mfspr t1,dbat0l stw t1,4(tos) + mfspr t2,dbat1u stw t2,8(tos) + mfspr t3,dbat1l stw t3,12(tos) + mfspr t4,dbat2u stw t4,16(tos) + mfspr t5,dbat2l stw t5,20(tos) + mfspr t6,dbat3u stw t6,24(tos) + mfspr t7,dbat3l stw t7,28(tos) + addi tos,tos,32 +c; +code restore-dbats ( addr1 -- addr2 ) + sync \ XXX move syncs inside the loop? + isync \ XXX do we *really* need both syncs both times? + lwz t0,0(tos) mtspr dbat0u,t0 + lwz t1,4(tos) mtspr dbat0l,t1 + lwz t2,8(tos) mtspr dbat1u,t2 + lwz t3,12(tos) mtspr dbat1l,t3 + lwz t4,16(tos) mtspr dbat2u,t4 + lwz t5,20(tos) mtspr dbat2l,t5 + lwz t6,24(tos) mtspr dbat3u,t6 + lwz t7,28(tos) mtspr dbat3l,t7 + sync + isync + addi tos,tos,32 +c; + +code save-lomem ( addr1 -- addr2 ) \ 120 + addi t0,tos,-4 \ Dst into t0 + + \ save 300-3ff + 300 4 - set t1,* \ Src + 100 4 / set t2,* \ set length + mtspr ctr,t2 \ Count in count register + begin + lbzu t2,4(t1) \ Load byte + stbu t2,4(t0) \ Store byte + countdown \ Decrement & Branch if nonzero + + \ check for 603-class processor + mfspr t3,pvr + rlwinm t3,t3,16,24,31 + cmpi 0,0,t3,6 = if set t3,3 then + cmpi 0,0,t3,7 = if set t3,3 then + cmpi 0,0,t3,3 = if \ this is a 603-class processor + \ save 1100-12ff + 1100 4 - set t1,* \ Src + 200 4 / set t2,* \ set length + mtspr ctr,t2 \ Count in count register + begin + lbzu t2,4(t1) \ Load byte + stbu t2,4(t0) \ Store byte + countdown \ Decrement & Branch if nonzero + then + addi tos,t0,4 \ addr2 + mtspr ctr,up \ Restore "next" pointer +c; +code restore-lomem ( addr1 -- addr2 ) + addi t1,tos,-4 \ Src into t1 + + \ restore 300-3ff + 300 4 - set t0,* \ Dst + 100 4 / set t2,* \ set length + mtspr ctr,t2 \ Count in count register + begin + lbzu t2,4(t1) \ Load byte + stbu t2,4(t0) \ Store byte + countdown \ Decrement & Branch if nonzero + + \ check for 603-class processor + mfspr t3,pvr + rlwinm t3,t3,16,24,31 + cmpi 0,0,t3,6 = if set t3,3 then + cmpi 0,0,t3,7 = if set t3,3 then + cmpi 0,0,t3,3 = if \ this is a 603-class processor + \ restore 1100-12ff + 1100 4 - set t0,* \ Dst + 200 4 / set t2,* \ set length + mtspr ctr,t2 \ Count in count register + begin + lbzu t2,4(t1) \ Load byte + stbu t2,4(t0) \ Store byte + countdown \ Decrement & Branch if nonzero + then + addi tos,t1,4 \ addr2 + mtspr ctr,up \ Restore "next" pointer +c; + +: save-environment ( addr -- ) \ data handlers only??? + save-lomem + save-dbats + save-sprs + drop +; +: restore-environment ( addr -- ) \ data handlers only??? + restore-lomem +\ #tlb-lines invalidate-tlbs + restore-dbats + restore-sprs + drop +; + +: ?real-mode-entry ( -- ) + client-env save-environment + fw-env restore-environment + \ msr@ h# 10 or msr! + msr@ h# 10 and 0= dcache-on? and if dcache-off then +; +: ?real-mode-exit ( -- ) + \ msr@ h# 10 invert and msr! + msr@ h# 10 and 0= if + \ If the cache was on when we entered, turn it back on + cif-reg-save 88 + @ h# 4000 or if dcache-on then + then + client-env restore-environment +; + +headers +stand-init: Real mode CIF +\ : rm-cif ( XXX for testing ) + use-real-mode? if + \ XXX optimize later: + \ 603-class? if /rm-tlbmiss 2* /env + to /env then + \ exp? if /exp-tlbmiss 2* /env + to /env then + /env alloc-mem to fw-env + /env alloc-mem to client-env + ['] ?real-mode-entry to rm-cif-entry + ['] ?real-mode-exit to rm-cif-exit + fw-env save-environment + then +; + +warning off +dev /client-services +: claim ( align size virt -- base ) + in-real-mode? if ( align size virt ) + swap rot dup if ( virt size align ) + rot drop ( size align ) + ['] mem-claim catch if 2drop 0 then + else ( virt size 0 ) + ['] mem-claim catch if 3drop 0 then + then + else + claim + then +; +: release ( size virt -- ) + in-real-mode? if ( virt=phys size ) + swap ?release-mem ( ) + else ( virt size ) + release + then +; +device-end +warning on + +\ 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/ppc/reboot.fth =================================================================== --- cpu/ppc/reboot.fth (rev 0) +++ cpu/ppc/reboot.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,62 @@ +purpose: Reboot system: save reboot info in nvram configuration variables +\ See license at end of file + +headerless +: put-env-number ( n name$ -- ) hex rot (.) 2swap (put-ge-var) drop ; +: get-env-number ( name$ -- n ) + hex $getenv if 0 else $number if 0 then then +; + +0 value reboot-info +: +rb ( offset -- adr ) reboot-info + ; +: copy-reboot-info ( -- ) + " reboot-command" $getenv if false to reboot? exit then + + d# 140 alloc-mem to reboot-info + " reboot-command" $getenv if " " then d# 0 +rb place + " reboot-line#" get-env-number d# 132 +rb ! + " reboot-column#" get-env-number d# 136 +rb ! + + " reboot-command" $unsetenv + " reboot-line#" $unsetenv + " reboot-column#" $unsetenv + + true to reboot? +; + +: (save-reboot-info) ( cmd$ line# column# -- ) + " reboot-column#" put-env-number + " reboot-line#" put-env-number + " reboot-command" (put-ge-var) drop +; +' (save-reboot-info) to save-reboot-info + +: (get-reboot-info) ( -- cmd$ line# column# ) + 0 +rb count d# 132 +rb @ d# 136 +rb @ +; +' (get-reboot-info) to get-reboot-info +headers + +\ 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/ppc/reenter.fth =================================================================== --- cpu/ppc/reenter.fth (rev 0) +++ cpu/ppc/reenter.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,78 @@ +purpose: Handle various kinds of entries into Forth from traps, etc. +\ See license at end of file + +headerless +: .go-message ( -- ) + \ Restarting is only possible if the state that was first saved + \ is from a restartable exception. + state-valid @ -1 = already-go? and if + restartable? on + ." Type 'go' to resume" cr + then +; + +: .entry ( -- ) + talign \ ... in case dp is misaligned + + aborted? @ if + aborted? off hex cr ." Keyboard interrupt" cr .go-message exit + then + +[ifdef] notyet + exittomon exittomon-end inside? if + ." Program terminated" cr exit + then + reenter reenter-end inside? if + .go-message %o0 to %tbr + %o2 to %itmr exit + then +[then] + [ also hidden ] (.exception) [ previous ] +; + +headers +stand-init: + ['] .entry is .exception +; + +\ Temporary hacks until we implement these functions correctly + +defer user-interface ' quit to user-interface +also client-services definitions +" reenter.fth: Implement 'exit' client service correctly" ?reminder +: exit ( -- ) + [ also hidden ] breakpoints-installed off [ previous ] + [ifdef] vector vector off [then] + + " restore" stdout @ ['] $call-method catch if 3drop then + " restore" stdin @ ['] $call-method catch if 3drop then + + user-interface +; +: enter ( -- ) interact ; +previous definitions + + +\ 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/ppc/regacc.fth =================================================================== --- cpu/ppc/regacc.fth (rev 0) +++ cpu/ppc/regacc.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,81 @@ +purpose: Register access words for PowerPC +\ See license at end of file + +code rl! ( l addr -- ) + lwz t0,0(sp) \ value + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + 0<> if + stw t0,0(tos) + else + stwbrx t0,r0,tos + then + eieio sync + lwz tos,1cell(sp) + addi sp,sp,2cells +c; +code rl@ ( addr -- l ) + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + 0<> if + lwz tos,0(tos) + else + lwbrx tos,r0,tos + then +c; +code rw! ( w addr -- ) + lwz t0,0(sp) \ value + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + 0<> if + sth t0,0(tos) + else + sthbrx t0,r0,tos + then + eieio sync + lwz tos,1cell(sp) + addi sp,sp,2cells +c; +code rw@ ( addr -- w ) + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + 0<> if + lhz tos,0(tos) + else + lhbrx tos,r0,tos + then +c; +code rb@ ( addr -- b ) + lbz tos,0(tos) +c; +code rb! ( b addr -- ) + lwz t0,0(sp) + stb t0,0(tos) + eieio sync + lwz tos,1cell(sp) + addi sp,sp,2cells +c; + +\ 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/ppc/register.fth =================================================================== --- cpu/ppc/register.fth (rev 0) +++ cpu/ppc/register.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,162 @@ +purpose: Display and modify the saved program state +\ See license at end of file + +\ This code is highly machine-dependent. +\ +\ Requires: +\ +\ >state ( offset -- addr ) +\ Returns an address within the processor state array given the +\ offset into that array +\ +\ Defines: +\ +\ register names +\ .registers + +needs action: objects.fth + +decimal +headerless + +only forth hidden also forth also definitions + +d# 112 /l* constant /save-area + +: state-valid ( -- addr ) d# 40 /l* >state ; +: ?saved-state ( -- ) + state-valid @ 0= abort" No program state has been saved in this session." +; + +: clear-save-area ( -- ) 0 >state /save-area erase ; + +: >vmem ; + +3 actions +action: @ ?saved-state >state @ ; +action: @ >state ! ; ( is ) +action: @ >state ; ( addr ) +: reg \ name ( offset -- ) + create /l* , + use-actions +; +: regs \ name name ... ( start #regs -- ) + bounds ?do i reg loop +; +3 actions +action: @ ?saved-state >state 2@ ; +action: @ >state 2! ; ( is ) +action: @ >state ; ( addr ) +: freg \ name ( offset -- ) + create /l* , + use-actions +; +: fregs \ name name ... ( start #regs -- ) + 2* bounds ?do i freg 2 +loop +; + + +headers + 0 8 regs %r0 %r1 %r2 %r3 %r4 %r5 %r6 %r7 + 8 8 regs %r8 %r9 %r10 %r11 %r12 %r13 %r14 %r15 + +16 8 regs %r16 %r17 %r18 %r19 %r20 %r21 %r22 %r23 +24 8 regs %r24 %r25 %r26 %r27 %r28 %r29 %r30 %r31 +20 12 regs t0 t1 t2 t3 t4 t5 rbase up tos ip rp sp + +32 6 regs %xer %lr %ctr %pc %msr %cr +35 2 regs %srr0 %srr1 + +38 1 regs exception# +39 3 regs %saved-my-self %state-valid %restartable? + +42 8 fregs %f0 %f1 %f2 %f3 %f4 %f5 %f6 %f7 +58 8 fregs %f8 %f9 %f10 %f11 %f12 %f13 %f14 %f15 +74 8 fregs %f16 %f17 %f18 %f19 %f20 %f21 %f22 %f23 +90 8 fregs %f24 %f25 %f26 %f27 %f28 %f29 %f30 %f31 + +106 reg %fpscr +106 freg f-tmp + +108 4 regs %sprg0 %sprg1 %sprg2 %sprg3 + +\ Following words defined here to satisfy the +\ references to these "variables" anywhere else +: saved-my-self ( -- addr ) addr %saved-my-self ; +: restartable? ( -- addr ) addr %restartable? ; + +headerless +: .lx ( l -- ) base @ >r hex 9 u.r r> base ! ; + +headers +: .registers ( -- ) + ?saved-state + ??cr +." pc msr ctr lr xer cr" cr + %pc .lx %msr .lx %ctr .lx %lr .lx %xer .lx %cr .lx +cr cr +." r0 r1 r2 r3 r4 r5 r6 r7" cr + %r0 .lx %r1 .lx %r2 .lx %r3 .lx %r4 .lx %r5 .lx %r6 .lx %r7 .lx +cr cr +." r8 r9 r10 r11 r12 r13 r14 r15" cr + %r8 .lx %r9 .lx %r10 .lx %r11 .lx %r12 .lx %r13 .lx %r14 .lx %r15 .lx +cr cr +." r16 r17 r18 r19 r20 r21 r22 r23" cr + %r16 .lx %r17 .lx %r18 .lx %r19 .lx %r20 .lx %r21 .lx %r22 .lx %r23 .lx +cr cr +." r24 r25 r26 r27 r28 r29 r30 r31" cr + %r24 .lx %r25 .lx %r26 .lx %r27 .lx %r28 .lx %r29 .lx %r30 .lx %r31 .lx +cr cr +." sprg0 sprg1 sprg2 sprg3 srr0 srr1" cr + %sprg0 .lx %sprg1 .lx %sprg2 .lx %sprg3 .lx %srr0 .lx %srr1 .lx +cr cr +; + +headerless +: ud.r ( d #columns -- ) >r <# #s #> r> over - spaces type ; +: .fx ( d -- ) base @ >r hex d# 17 ud.r r> base ! ; + +headers +: .fregisters ( -- ) + ??cr + %msr h# 2000 and 0= if + ." Floating point registers were not saved because the floating point" cr + ." unit was not enabled at the time the registers were saved." cr + exit + then + ." fpcsr " %fpscr .lx cr + ." f0-3 :" %f0 .fx %f1 .fx %f2 .fx %f3 .fx cr + ." f4-7 :" %f4 .fx %f5 .fx %f6 .fx %f7 .fx cr + ." f8-11 :" %f8 .fx %f9 .fx %f10 .fx %f11 .fx cr + ." f12-15 :" %f12 .fx %f13 .fx %f14 .fx %f15 .fx cr + ." f16-19 :" %f16 .fx %f17 .fx %f18 .fx %f19 .fx cr + ." f20-23 :" %f20 .fx %f21 .fx %f22 .fx %f23 .fx cr + ." f24-27 :" %f24 .fx %f25 .fx %f26 .fx %f27 .fx cr + ." f28-31 :" %f28 .fx %f29 .fx %f30 .fx %f31 .fx cr +; + +only forth also definitions + +\ 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/ppc/resetvec.fth =================================================================== --- cpu/ppc/resetvec.fth (rev 0) +++ cpu/ppc/resetvec.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,234 @@ +purpose: Reset vector handler for dropin-driver format +\ See license at end of file + +\ create debug-reset + +[ifdef] debug-reset +h# 8000.0000 constant io-base \ Wrong for GoldenGate +[then] + +\needs start-assembling fload ${BP}/cpu/ppc/asmtools.fth +\needs write-dropin fload ${BP}/tools/mkdropin.fth + +h# e.0000 d# 16 rshift constant inflate-offset \ Shifted for addis +h# f.0000 d# 16 rshift constant workspace-offset \ Shifted for addis + +\ This code is intended to execute from ROM, in big-endian byte order + +start-assembling +h# 20 to asm-origin \ Skip dropin header + +" Copyright 1995 FirmWorks" c$, + +\ Destroys: r5, r6 +label strcmp ( r3: str1 r4: str2 -- r3: 0 if match, nonzero if mismatch ) + addi r3,r3,-1 \ Account for pre-increment + addi r4,r4,-1 \ Account for pre-increment + begin + lbzu r5,1(r3) + lbzu r6,1(r4) + cmp 0,0,r5,r6 + = while + cmpi 0,0,r5,0 + = if + set r3,0 + bclr 20,0 + then + repeat + + subf r3,r5,r6 + bclr 20,0 +end-code + +label find-dropin ( r3: module-name-ptr -- r3: address|-1 ) + mfspr r31,lr + + mr r30,r3 + + \ Compute ROMbase + here 4 + bl * + mfspr r29,lr + here 4 - asm-base - asm-origin + negate addi r29,r29,* + + begin + lwz r4,0(r29) + set r5,h#4f424d44 \ 'OBMD' + cmp 0,0,r4,r5 + = while + mr r3,r30 + addi r4,r29,16 + strcmp bl * + cmpi 0,0,r3,0 + = if \ It the strings match, we found the dropin + mr r3,r29 + mtspr lr,r31 + bclr 20,0 + then + lwz r3,4(r29) \ Length of dropin image + add r3,r3,r29 \ Added to base address of previous dropin + addi r3,r3,35 \ Plus length of header (32) + roundup (3) + rlwinm r29,r3,0,0,29 \ Aligned to 4-byte boundary = new dropin addr + repeat + + set r3,-1 \ No more dropins; return -1 to indicate failure + + mtspr lr,r31 + bclr 20,0 +end-code + +label memcpy ( r3: dst r4: src r5: n -- r3: dst ) + mtspr ctr,r5 + mr r6,r3 + + addi r3,r3,-1 \ Account for pre-decrement + addi r4,r4,-1 \ Account for pre-decrement + begin + lbzu r5,1(r4) + stbu r5,1(r3) + countdown + + mr r3,r6 \ Return dst + bclr 20,0 +end-code + +\ Firmware startup sequence: +\ 1) Execute a dropin named "start", to initialize the host bridge and memory +\ 2) Locate a dropin named "firmware", either copy it or inflate it into RAM, +\ and execute it from RAM + +\ Add padding so "startup" begins at address h# 100 + +h# 100 pad-to + +[ifdef] debug-reset +label my-entry + 0 , \ To be patched later +end-code + +fload ${BP}/arch/prep/reports.fth +[then] + +label startup ( -- ) + + mfspr r3,hid0 + ori r3,r3,2 + mtspr hid0,r3 + + " start" $find-dropin, \ Assemble call to find-dropin with literal arg + + \ What should we do it this fails? Perhaps call a default routine + \ to try to initialize com1 and display a message? + \ For now, we assume success + + addi r3,r3,32 \ Skip dropin header + mtspr ctr,r3 + bcctrl 20,0 + + mr r26,r3 \ Save firmware load address + mr r27,r4 \ Save firmware RAM size + +[ifdef] debug-reset + ascii 0 ?report +[then] + + " firmware" $find-dropin, \ Assemble call to find-dropin with literal arg + + lwz r4,12(r3) + cmpi 0,0,r4,0 + <> if + \ The firmware dropin is compressed, so we load the inflater into RAM + \ and use it to inflate the firmware into RAM + mr r28,r3 \ Save address of firmware dropin + + " inflate" $find-dropin, \ Assemble call to find-dropin with literal arg + + lwz r5,4(r3) \ Length of inflater + addi r4,r3,32 \ src: Base address of inflater code in ROM + inflate-offset addis r3,r26,* \ Dst: Base address of inflater + + memcpy bl * \ Returns dst + +\ XXX we might want to turn on the cache, or perhaps flush it +\ We should decide whether or not the cache is on when 'start' returns + + mtspr ctr,r3 + +[ifdef] debug-reset + dot bl * + mr r3,r28 dot bl * + mr r3,r26 dot bl * + mr r3,r27 dot bl * + ascii 1 ?report +[then] + + addi r3,r28,32 \ Address of compressed bits of firmware dropin + mr r4,r26 \ Firmware RAM address + workspace-offset addis r5,r26,* \ Scratch RAM for inflater + mr r6,r27 \ Firmware RAM size + add r1,r26,r27 \ Stack for inflater + addi r1,r1,h#-10 \ Because LR is saved at FP+8 + + bcctrl 20,0 \ Inflate the firmware + + else + \ The firmware dropin isn't compressed, so we just copy it to RAM + + addi r4,r3,32 \ Skip dropin header + lwz r5,4(r3) \ Length of image + mr r3,r26 \ Firmware RAM address + memcpy bl * \ Copy the firmware + then + +[ifdef] debug-reset + ascii 2 ?report +[then] + + mr r3,r26 \ Firmware RAM address + mr r4,r27 \ Firmware RAM size + + mtspr ctr,r26 + bcctrl 20,0 \ Execute the firmware + + \ Notreached, in theory + begin again +end-code + +[ifdef] debug-reset +startup my-entry put-branch +[then] + +\ Add padding so this entire module ends at address h# 1e0. Doing so makes +\ it easy to concatenate a dropin driver (with its 32-byte header) to handle +\ other exception vectors, the first of which begins at ROM offset h# 200 + +h# 1e0 pad-to + +end-assembling + +writing resetvec.di +asm-base here over - 0 " reset-vector" write-dropin +ofd @ fclose + +\ 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/ppc/rombp.fth =================================================================== --- cpu/ppc/rombp.fth (rev 0) +++ cpu/ppc/rombp.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,69 @@ +purpose: Patches to allow limited breakpointing of ROM code +\ See license at end of file + +[ifndef] iabr! +code iabr! ( adr -- ) + mtspr iabr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +[then] +headerless +: rom-op! ( op adr -- ) + 2dup instruction! ( op adr ) + 2dup op@ = if ( op adr ) + 2drop ( ) + else ( op adr ) + swap breakpoint-opcode = if ( adr ) + 2 or %msr 5 >> 1 and or ( iabr-val ) + else ( adr ) + drop 0 ( iabr-val=0 ) + then ( iabr-val ) + iabr! ( ) + then +; +: rom-at-bp? ( adr -- flag ) + iabr@ 2 and if + %msr 5 >> 1 and iabr@ 1 and = if + dup iabr@ 3 invert and = if drop breakpoint-opcode exit then + then + then + op@ +; +patch rom-op! instruction! op! +patch rom-at-bp? op@ at-breakpoint? + +headers + +stand-init: + h# 13 catch-exception +; +\ Hacros +: --bp --bp 0 iabr! ; : ++ ff30.0000 + ; +: t --bp ++ till ; \ till +: s ++ to %pc ; \ skip + + +\ 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/ppc/rootnode.fth =================================================================== --- cpu/ppc/rootnode.fth (rev 0) +++ cpu/ppc/rootnode.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,117 @@ +purpose: Methods for root node +\ See license at end of file + +: root-map-in ( phys len -- virt ) + " /" " map-in" execute-device-method drop +; +: root-map-out ( virt len -- ) + " /" " map-out" execute-device-method drop +; + +dev / +extend-package + +hex + +\ Static methods +: decode-unit ( adr len -- phys ) push-hex $number if 0 then pop-base ; +: encode-unit ( phys -- adr len ) push-hex (u.) pop-base ; + +\ Not-necessarily-static methods +: open ( -- true ) true ; +: close ( -- ) ; + +: map-in ( phys size -- virt ) + in-real-mode? if drop exit then + over mmu-lowbits + pagesize round-up >r ( phys r: size' ) + chrp? if ( phys r: size' ) + dup fw-virt-base dup fw-virt-size + within if + r@ pagesize mmu-claim ( phys virt r: size' ) + else + \ Return virt=phys + dup mmu-highbits ( phys virt r: size' ) + then + else ( phys r: size' ) + r@ pagesize mmu-claim ( phys virt r: size' ) + then ( phys virt r: size' ) + >r dup mmu-highbits ( phys phys' r: size' virt ) + r> r> over >r ( phys phys' virt size r: virt ) + -1 mmu-map ( phys r: virt ) + mmu-lowbits r> + ( virtual ) +; +: map-out ( virtual size -- ) + in-real-mode? if 2drop exit then + chrp? if 2drop exit then + 2dup mmu-unmap mmu-release +; + +: dma-alloc ( size -- virt ) alloc-mem ; +: dma-free ( virt size -- ) free-mem ; + +: dma-map-in ( virt size cacheable -- devaddr ) + drop 2dup flush-d$-range drop ( virt ) + in-real-mode? 0= if + mmu-translate 0= abort" Invalid DMA address" drop ( phys ) + then +; +: dma-map-out ( virt devaddr size -- ) nip flush-d$-range ; + +: dma-sync ( virt devaddr size -- ) nip flush-d$-range ; +: dma-push ( virt devaddr size -- ) nip flush-d$-range ; +: dma-pull ( virt devaddr size -- ) nip flush-d$-range ; + +finish-device + +device-end + +\ Call this after the system-mac-address is determined, which is typically +\ done near the end of the probing process. +: set-system-id ( -- ) + system-mac-address dup if ( adr 6 ) + " /" find-device ( adr 6 ) + + \ Convert the six bytes of the MAC address into a string of the + \ form 0NNNNNNNNNN, where N is an uppercase hex digit. + push-hex ( adr 6 ) + + <# bounds swap 1- ?do ( ) + i c@ u# u# drop ( ) + -1 +loop ( ) + 0 u# u#> ( adr len ) + + 2dup upper ( adr len ) \ Force upper case + + pop-base ( adr len ) + + encode-string " system-id" property ( ) + + device-end + else + 2drop + then +; +headers + +\ 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/ppc/savefort.fth =================================================================== --- cpu/ppc/savefort.fth (rev 0) +++ cpu/ppc/savefort.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,101 @@ +purpose: Save the Forth dictionary to a file +\ See license at end of file + +\ save-forth ( filename -- ) +\ Saves the Forth dictionary to a file so it may be later used under Unix +\ +\ save-image ( header-adr header-len filename -- ) +\ Primitive save routine. Saves the dictionary image to a file. +\ The header is placed at the start of the file. The latest definition +\ whose name is the same as the "init-routine-name" argument is +\ installed as the init-io routine. + +only forth also hidden also forth definitions + + +headerless +: swap-size ( -- n ) here >swap-map-size ; +: be-lput ( adr -- ) + l@ lbsplit ofd @ fputc ofd @ fputc ofd @ fputc ofd @ fputc +; +: be-fputs ( adr len -- ) bounds ?do i be-lput 4 +loop ; +: ?be-fputs ( adr len -- ) + 3 + 2 >> 0 ?do ( adr ) + dup i la+ ( adr adr' ) + i swap-map bittest if ( adr adr' ) + 4 ofd @ fputs ( adr ) + else ( adr adr' ) + be-lput ( adr ) + then ( adr ) + loop ( adr ) + drop +; +: save-image ( header header-len filename -- ) + ['] ($find-next) is $find-next + + new-file ( header header-len ) + in-little-endian? if + ( header header-len ) be-fputs \ Write header + origin text-size ?be-fputs \ Write dictionary + up@ user-size be-fputs \ Write user area + else + ( header header-len ) ofd @ fputs \ Write header + origin text-size ofd @ fputs \ Write dictionary + up@ user-size ofd @ fputs \ Write user area + then + swap-map swap-size ofd @ fputs \ Write swap map + ofd @ fclose +; +headers + +0 value growth-size + +: make-bin-header ( -- ) + h# 48000020 h_magic l! \ This is a b .+0x20 instruction + text-size h_tlen l! \ Set the text size in program header + user-size h_dlen l! \ Set the data size in program header + growth-size h_blen l! \ Set the bss size in program header + 0 h_slen l! \ Set the symbol size in program header + origin h_entry l! \ Set the current starting address + swap-size h_trlen l! \ Set the relocation size + 0 h_drlen l! \ Set the data relocation size +; + +\ Save an image of the target system in a file. +: save-forth ( str -- ) + 8 (align) \ Make sure image is 8 byte aligned + + >r + + make-bin-header + + " sys-init-io" $find-name is init-io + " sys-init" init-save + bin-header /bin-header r> save-image +; + +only forth also definitions + +\ 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/ppc/savemeta.fth =================================================================== --- cpu/ppc/savemeta.fth (rev 0) +++ cpu/ppc/savemeta.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,81 @@ +purpose: Save the metacompiled kernel image into a file +\ See license at end of file + +hex +only forth labels also forth also definitions + +\ Program header +create header forth +h# 4800.0020 l, \ Branch past the header + 0 l, \ Text size, actual value will be set later + 0 l, \ Data size, actual value will be set later + 0 l, \ Bss size + 0 l, \ Symbol Table size + 0 l, \ Entry + 0 l, \ Text Relocation Size + 0 l, \ Data Relocation Size +\ End of header. +here header - constant /header + +only forth also meta also forth-h also definitions + +\ Save an image of the target system in the file whose name +\ is the argument on the stack. + +: doubleword-align ( n -- n' ) 7 + 7 invert and ; +: text-base ( -- adr ) origin-t >hostaddr ; +: text-size ( -- n ) here-t origin-t - doubleword-align ; +: swap-size ( -- n ) here-t >swap-map-size-t ; +: user-base ( -- adr ) userarea-t ; +: user-size ( -- n ) user-size-t doubleword-align ; +: save-meta ( str -- ) + + \ Doubleword alignment is required so that the user area image will + \ not be in the same doubleword as the end of the dictionary, thus + \ causing the copy loop to get the wrong value the first time. + begin here-t 7 and while 0 c,-t repeat + + new-file + + \ Set the text and data sizes in the program header + h# 4800.0020 header h# 0 + l-t! \ Branch past the header + text-size header h# 4 + l-t! \ Text size + user-size header h# 8 + l-t! \ Data size + 0 header h# 10 + l-t! \ Symbol table size + + 0 header h# 14 + l-t! \ Entry point + swap-size header h# 18 + l-t! \ Swap map size + + header /header ofd @ fputs + text-base text-size ofd @ fputs + user-base user-size ofd @ fputs + swap-map-t swap-size ofd @ fputs \ Swap map + + ofd @ fclose +; + +only forth also meta also definitions + +\ 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/ppc/scrub.fth =================================================================== --- cpu/ppc/scrub.fth (rev 0) +++ cpu/ppc/scrub.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,70 @@ +purpose: Fast memory scrubbing +\ See license at end of file + +headerless +code (berase) ( adr #cache-blocks /dcache-block -- ) + \ /dcache-block is already in tos + lwz t1,0(sp) \ #cache-blocks in t1 + lwz t0,1cell(sp) \ Address in t0 + + mfspr t2,ctr + mtspr ctr,t1 + begin + dcbz r0,t0 + dcbf r0,t0 + add t0,t0,tos + countdown + mtspr ctr,t2 + + lwz tos,2cells(sp) + addi sp,sp,3cells +c; + +headers +\ Usage requirements: +\ adr must aligned on a cache line boundary +\ len must a multiple of the cache line size +\ the range must not overlap a 256 MB (h# 1000.0000) boundary +\ the data cache must be turned on +: berase ( adr len -- ) + dcache-on? 0= dup >r if dcache-on then + real-mode? 0= if + over h# f000.0000 and ( adr len adr' ) + dup h# 1000.0000 false 2 dbat ( adr len pa va len io? bat# dbat ) + bat! ( adr len ) + then + \ XXX dcbz does not work on some versions of 620 + 620-class? if + 0 fill + else + /dcache-block / /dcache-block (berase) ( ) + then + real-mode? 0= if + 0 0 2 dbat! + then + r> if dcache-off then +; + +\ 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/ppc/scrub601.fth =================================================================== --- cpu/ppc/scrub601.fth (rev 0) +++ cpu/ppc/scrub601.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,53 @@ +purpose: Fast memory scrubbing - 601 version +\ See license at end of file + +\ Usage requirements: +\ adr must aligned on a cache line boundary +\ len must a multiple of the cache line size +\ the range must not overlap an 8 MB (h# 80.0000) boundary +\ the data cache must be turned on +: berase-range ( adr len -- ) + over h# ff80.0000 and dup h# 80.0000 false 2 i&dbats bat! + /dcache-block / /dcache-block (berase) + 0 0 2 ibat! +; +: berase-601 ( adr len -- ) + begin dup while ( adr len ) + \ Find the length of a piece that doesn't overlap a BAT boundary + over dup h# 7f.ffff or 1+ swap - ( adr len len-to-boundary ) + over umin ( adr len piece-len ) + >r over r@ berase-range ( adr len ) ( r: piece-len ) + r> /string ( adr' len' ) + repeat ( adr' 0 ) + 2drop +; +warning @ warning off +: berase ( adr len -- ) + 601? if berase-601 exit then + berase +; +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: cpu/ppc/scrub823.fth =================================================================== --- cpu/ppc/scrub823.fth (rev 0) +++ cpu/ppc/scrub823.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,57 @@ +purpose: Fast memory scrubbing +\ See license at end of file + +headerless +code (berase) ( adr #cache-blocks /dcache-block -- ) + \ /dcache-block is already in tos + lwz t1,0(sp) \ #cache-blocks in t1 + lwz t0,1cell(sp) \ Address in t0 + + mfspr t2,ctr + mtspr ctr,t1 + begin + dcbz r0,t0 + dcbf r0,t0 + add t0,t0,tos + countdown + mtspr ctr,t2 + + lwz tos,2cells(sp) + addi sp,sp,3cells +c; + +headers +\ Usage requirements: +\ adr must aligned on a cache line boundary +\ len must a multiple of the cache line size +\ the range must not overlap a 256 MB (h# 1000.0000) boundary +\ the data cache must be turned on +: berase ( adr len -- ) + dcache-on? 0= dup >r if dcache-on then + /dcache-block / /dcache-block (berase) ( ) + r> if dcache-off then +; + +\ 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/ppc/segreg.fth =================================================================== --- cpu/ppc/segreg.fth (rev 0) +++ cpu/ppc/segreg.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,40 @@ +purpose: Segment register access words +\ See license at end of file + +code sr@ ( sr# -- n ) + rlwinm tos,tos,28,0,3 \ Convert to x000.0000 + mfsrin tos,tos +c; +code sr! ( n sr# -- ) + lwz t1,0(sp) + rlwinm tos,tos,28,0,3 \ Convert to x000.0000 + sync isync + mtsrin t1,tos + sync isync + lwz tos,1cell(sp) + addi sp,sp,2cells +c; + +\ 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/ppc/spr.fth =================================================================== --- cpu/ppc/spr.fth (rev 0) +++ cpu/ppc/spr.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,456 @@ +purpose: Special Purpose Register access for 604 +\ See license at end of file + +\ XER register: spr 1. +\ contains overflow and carry bits and byte count for string instructions. +code xer@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,xer +c; +code xer! ( n -- ) + mtspr xer,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ link register: spr 8 +code lr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,lr +c; +code lr! ( n -- ) + mtspr lr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ count register: spr 9 +code ctr@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,ctr +c; +code ctr! ( n -- ) + mtspr ctr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ DSISR: spr 18 +\ contains the status and cause of the DSI or alignment exception. +\ updated along with DAR. + +code dsisr! ( n -- ) + mtspr dsisr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code dsisr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,dsisr +c; + +\ Data Address Register (DAR): spr 19 +\ contains the faulted address after a DSI or alignment exception. +code dar@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,dar +c; +\ is this register writable? (ry) +code dar! ( n -- ) + mtspr dar,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ ------------------------------------------------------------- +\ These are defined in forthint.fth . They should be here. +\ +\ \ Decrementer: spr 22 +\ \ code dec! ( n -- ) +\ mtspr dec,tos +\ lwz tos,0(sp) +\ addi sp,sp,1cell +\ c; +\ code dec@ ( -- n ) +\ stwu tos,-1cell(sp) +\ mfspr tos,dec +\ c; + +\ SDR1 register: spr 25 +code sdr1@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,sdr1 +c; +code sdr1! ( n -- ) + mtspr sdr1,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ machine status Save and Restore Registers (SRR0 - SRR1): spr 26 - 27 +code srr0@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,srr0 +c; +code srr0! ( n -- ) + mtspr srr0,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code srr1@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,srr1 +c; +code srr1! ( n -- ) + mtspr srr1,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ SPRG0 to SPRG3: spr 272 - 275 +\ misc. spr for OS usage +code sprg0@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,sprg0 +c; +code sprg0! ( n -- ) + mtspr sprg0,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code sprg1@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,sprg1 +c; +code sprg1! ( n -- ) + mtspr sprg1,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code sprg2@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,sprg2 +c; +code sprg2! ( n -- ) + mtspr sprg2,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code sprg3@ ( -- n) + stwu tos,-1cell(sp) + mfspr tos,sprg3 +c; +code sprg3! ( n -- ) + mtspr sprg3,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ external address register: spr 282. +\ used with eciwx and ecowx instructions only. +code ear@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,ear +c; +\ is this register writable? (ry) +code ear! ( n -- ) + mtspr ear,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ timebase register (for writing): spr 284 - 285. +\ use get-tb for reading. see getms.fth. +: put-tb ( tbu tbl -- ) + ." writing to Time Base Register pair not implemented. " cr +; + +\ processor version register: spr 287 (read only). +code pvr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,pvr +c; +: cpu-version ( -- n ) pvr@ lwsplit nip ; + +\ instruction Block Address Translation (BAT) registers: spr 528 - 535. +\ data Block Address Translation (BAR) registers: spr 536-543 +\ see bat.fth. + +\ Monitor Mode Control Register 0 (MMCR0): spr 952 +\ Performance Monitor Counters (PMC1-2): spr 953 - 954 +code mmcr0@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,mmcr0 +c; +code mmcr0! ( n -- ) + mtspr mmcr0,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code pmc1@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,pmc1 +c; +code pmc1! ( n -- ) + mtspr pmc1,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code pmc2@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,pmc2 +c; +code pmc2! ( n -- ) + mtspr pmc2,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ Sampled Instruction/Data Address (SIA, SDA): spr 955, 959 +code sia@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,sia +c; +code sia! ( n -- ) + mtspr sia,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code sda@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,sda +c; +code sda! ( n -- ) + mtspr sda,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ Hardware Implementation Dependent Register (HID0): spr 1008. +code hid0@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,hid0 +c; +code hid0! ( n -- ) + mtspr hid0,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ Instr/Data Address Breakpoint Register (IABR, DABR): spr 1010, 1013. +code iabr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,iabr +c; +code iabr! ( n -- ) + mtspr iabr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code dabr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,dabr +c; +code dabr! ( n -- ) + mtspr dabr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ Process Identification Register (PIR): spr 1023 +code pir@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,pir +c; +code pir! ( n -- ) + mtspr pir,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code buscsr@ ( -- n ) \ 620-specific + stwu tos,-1cell(sp) + mfspr tos,buscsr +c; + +\ 603-Arthur L2 Cache Control Register (L2CR): spr 1017. +code l2cr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,l2cr +c; +code l2cr! ( n -- ) + mtspr l2cr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ 823-specific +code ic-csr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,ic-csr +c; +code ic-csr! ( n -- ) + sync + mtspr ic-csr,tos + isync + lwz tos,0(sp) + addi sp,sp,1cell +c; +code dc-csr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,dc-csr +c; +code dc-csr! ( n -- ) + sync + mtspr dc-csr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code md-ctr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-ctr +c; +code md-ctr! ( n -- ) + mtspr md-ctr,tos + sync isync + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-epn@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-epn +c; +code md-epn! ( n -- ) + mtspr md-epn,tos + sync isync + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-rpn@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-rpn +c; +code md-rpn! ( n -- ) + mtspr md-rpn,tos + sync isync + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-twc@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-twc +c; +code md-twc! ( n -- ) + mtspr md-twc,tos + sync isync + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-ap@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-ap +c; +code md-ap! ( n -- ) + mtspr md-ap,tos + sync isync + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-cam@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-cam +c; +code md-cam! ( n -- ) + eieio + mtspr md-cam,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-ram0@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-ram0 +c; +code md-ram0! ( n -- ) + mtspr md-ram0,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code md-ram1@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,md-ram1 +c; +code md-ram1! ( n -- ) + mtspr md-ram1,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code m-twb@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,m-twb +c; +code m-twb! ( n -- ) + mtspr m-twb,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code m-casid@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,m-casid +c; +code m-casid! ( n -- ) + mtspr m-casid,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +code immr@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,immr +c; +code immr! ( n -- ) + mtspr immr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; +code der@ ( -- n ) + stwu tos,-1cell(sp) + mfspr tos,der +c; +code der! ( n -- ) + mtspr immr,tos + lwz tos,0(sp) + addi sp,sp,1cell +c; + +\ 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/ppc/swapdic.fth =================================================================== --- cpu/ppc/swapdic.fth (rev 0) +++ cpu/ppc/swapdic.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,74 @@ +purpose: Byte-swap the Forth dictionary +\ See license at end of file + +\needs bittest fload ${BP}/forth/lib/bitops.fth + +: lbflip ( n -- n' ) + lbsplit swap 2swap swap bljoin +; +: xlflips ( adr len -- ) + bounds ?do i l@ i la1+ l@ i l! i la1+ l! 2 /l* +loop +; + +h# 20 constant /iheader +0 value /image +0 value /itext +0 value /iuser +0 value /iswap +0 value text-base +0 value user-base +0 value swap-map +0 value buf + +: ?lbflips ( -- ) + /itext 4 / 0 do + i swap-map bittest 0= if text-base i la+ dup l@ lbflip swap l! loop + loop +; + +: +buf ( offset -- adr ) buf + ; +: little-endian-ify ( "infile" "outfile" -- ) + reading writing + + ifd @ fsize to /image + /image 8 round-up alloc-mem to buf + buf /image ifd @ fgets drop ifd @ fclose + + 4 +buf be-l@ to /itext + 8 +buf be-l@ to /iuser + h# 18 +buf be-l@ to /iswap + /iheader +buf to text-base + text-base /itext + to user-base + user-base /iuser + to swap-map + + buf /iheader lbflips + ?lbflips + user-base /iuser lbflips + buf /image xlflips + + buf /image ofd @ fputs ofd @ fclose +; + +\ 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/ppc/syscall.fth =================================================================== --- cpu/ppc/syscall.fth (rev 0) +++ cpu/ppc/syscall.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,195 @@ +purpose: Low-level I/O interface for use with the C "wrapper" program +\ See license at end of file + +\ The C program provides the Forth kernel with an array of entry-points +\ into C subroutines for performing the actual system calls. +\ This scheme should be reasonably compatible with nearly any Unix +\ implementation. The only difference would be in the implementation of +\ "syscall", which has to look up the address of the actual system call +\ C routine in the system call table provided to it by the C program loader. +\ It then has to convert the stack arguments into the same form as is +\ expected by the C system call routines. This obviously depends on the +\ details of the C calling sequence, but should not be too hard because +\ C compilers usually pass arguments on the stack. +\ Syscall is defined in the kernel, because it is needed for basics like +\ key and emit. + +decimal + +/l ualloc-t dup equ syscall-user# +user syscall-vec \ long address of system call vector +nuser sysretval + +\ I/O for running under an OS with a C program providing actual I/O routines + +meta +code syscall ( call# -- ) + lwz r3,0(sp) \ Get some arguments + lwz r4,4(sp) + lwz r5,8(sp) + lwz r6,12(sp) + lwz r7,16(sp) + lwz r8,20(sp) + + 'user syscall-vec lwz t0,* \ Get address of system call table + cmpi 0,0,t0,0 + 0<> if + andi. r0,t0,1 \ If low bit is set, this is not a TOC-based system + 0<> if + rlwinm t0,t0,0,0,30 \ Clear low bit + lwzx t2,t0,tos \ Code address in t2 + else + lwzx t1,t0,tos \ ptr-glue address in t1 + lwz t2,0(t1) \ Code address + lwz r2,4(t1) \ New TOC + then + mtspr lr,t2 + bclrl 20,0 + mtspr ctr,up \ Restore CTR + else + tw 0,tos,tos \ XXX Hack for use with simulator + then + + 'user sysretval stw r3,* \ Save the result + + lwz tos,0(sp) \ Fix stack + addi sp,sp,4 +c; +: retval ( -- return_value ) sysretval l@ ; +: lretval ( -- l.return_value ) sysretval l@ ; + +nuser errno \ The last system error code +: error? ( return-value -- return-value error? ) + dup 0< dup if 60 syscall retval errno ! then ( return-value flag ) +; + +true value powerpc? \ As opposed to POWER. Set by startup code + +code u/mod (s u.dividend u.divisor -- u.remainder u.quotient ) + second-to-t0 \ dividend + 'user powerpc? lwz t3,* + cmpi 0,0,t3,0 + 0= if \ Use POWER division (RS/6000) + mtspr mq,t0 + addi t0,r0,0 + div t1,t0,tos \ quotient in t1 + mfspr t2,mq + else + divwu t1,t0,tos \ quotient in t1 + mullw t2,t1,tos \ quot*divisor in t2 + subfc t2,t2,t0 \ remainder in t2 \ Use subfc for POWER compatibility + then + stw t2,0(sp) \ Put remainder on stack + mr tos,t1 \ Put quotient on stack +c; + +: / (s n1 n2 -- quot ) /mod nip ; +: mod (s n1 n2 -- rem ) /mod drop ; + +\ 32*32->64 bit unsigned multiply +\ y rs2 y rd + +code um* ( n1 n2 -- x[lo hi] ) + second-to-t0 + 'user powerpc? lwz t3,* + cmpi 0,0,t3,0 + 0= if \ Use POWER, not PowerPC, division + mul tos,t0,tos + mfspr t1,mq + else + mullw t1,t0,tos + mulhwu tos,t0,tos + then + stw t1,0(sp) +c; + +code m* ( n1 n2 -- low high ) + second-to-t0 + 'user powerpc? lwz t3,* \ "patch" div instr for simulator + cmpi 0,0,t3,0 + 0= if \ Use POWER, not PowerPC multiplication + mul tos,t0,tos + mfspr t1,mq + else + mullw t1,t0,tos + mulhw tos,t0,tos + then + stw t1,0(sp) +c; + +\ Rounds down to a block boundary. This causes all file accesses to the +\ underlying operating system to occur on disk block boundaries. Some +\ systems (e.g. CP/M) require this; others which don't require it +\ usually run faster with alignment than without. + +\ Aligns to a 512-byte boundary +hex +: _falign ( l.byte# fd -- l.aligned ) drop 1ff invert and ; +: _dfalign ( d.byte# fd -- d.aligned ) drop swap 1ff invert and swap ; + +code $sim-find-next (s adr len link -- adr len alf true | adr len false ) + mr r6,tos + mr r5,base + lwz r4,0(sp) + lwz r3,1cell(sp) + addi sp,sp,-4 + mr r7,sp + twi 0,tos,0 + or. tos,tos,tos + 0= if + addi sp,sp,4 + then +c; + +: set-endian ( -- ) + here off 1 here c! here @ 1 = is in-little-endian? +; + +\ : aix-flush-cache ( adr -- adr ) 4 swap sys-flush-cache nip ; +: sys-init-io ( -- ) +\ ['] drop origin - ['] set-swap-bit >body >user ! + install-wrapper-io +\ ['] aix-flush-cache is flush-cache + install-disk-io + \ Don't poll the keyboard under Unix; block waiting for a key + ['] (key ['] key (is + syscall-vec @ 0= if ['] $sim-find-next is $find-next then + + set-endian + +\ allocate-buffers + +\ init-keyboard +\ init-disk-files + +\ decimal +; +' sys-init-io is init-io + +: sys-init ; \ Environment initialization chain +' sys-init is init-environment +decimal + +\ 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/ppc/tagwords.fth =================================================================== --- cpu/ppc/tagwords.fth (rev 0) +++ cpu/ppc/tagwords.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,132 @@ +purpose: Tag all words that are executed; show all tagged words. +\ See license at end of file + +hex + +\ Generic tools for acting on all words + +defer each ( nfa -- ) ' drop to each +: every ( voc -- ) + follow begin another? while each repeat +; +: everywhere ( xt -- ) + to each + voc-link begin another-link? while ( v-link ) + voc> dup every ( voc ) + >voc-link ( v-link' ) + repeat +; + +\ verbose version +hidden also +: .vname ( voc -- ) + ??cr cr .in ['] vocabulary .name space .name cr +; +: show-every ( xt -- ) + to each + voc-link begin another-link? while ( v-link ) + voc> + dup .vname + dup follow + begin another? while + each + exit? if drop exit then + repeat + >voc-link ( v-link' ) + repeat +; +previous forth + +\ \ For reference... +\ label next +\ lwzu w,/token(ip) \ w has token of next word to execute +\ lwzux t1,w,base \ t1 has offset of its code field +\ add t1,t1,base \ t1 has acf +\ mtspr lr,t1 \ go there +\ bclr 20,0 +\ end-code + +\ Special version of "next" tags any word that is executed +label tagnext + lwzu w,/token(ip) \ w has token of next word to execute + + add t1,w,base \ t2 has acf + set t2,h#-10.0000 \ offset to tags + add t1,t1,t2 \ t1 has address of tag byte + \ lbz t2,0(t1) + set t2,h#a5 \ set magic# to tag the word + stb t2,0(t1) + + \ back to "next", which is already in progress... + lwzux t1,w,base \ t1 has offset of its code + add t1,t1,base \ t1 has code address + mtspr lr,t1 \ go there + bclr 20,0 +end-code + +\ Turn on tagnext +: tnext ( -- ) + tagnext up@ - h# 3ffffff and h# 48000000 or up@ instruction! +; +\ Revert to normal next +: nnext ( -- ) [ bug ] unbug [ forth ] ; + +\ \ an example +\ : tryit ( -- ) tnext bl word drop nnext ; + +: clear-tags ( -- ) + origin h# 10.0000 - here origin - erase +; + +\ variable tagged +\ : count-tagged ( nfa -- ) name> 10.0000 - c@ a5 = if 1 tagged +! then ; +\ : tagged? ( -- ) +\ 0 tagged ! +\ ['] count-tagged everywhere +\ tagged ? +\ ; + +: show-tagged? ( nfa -- ) + dup name> 10.0000 - c@ a5 = if + dup name>string nip .tab .id exit? if + exit + then + else + drop + then +; +decimal +: show-tagged ( -- ) + nnext + 0 lmargin ! 64 rmargin ! 14 tabstops ! ??cr + ['] show-tagged? show-every +; + +: stand-init-io ( -- ) + clear-tags tnext + stand-init-io +; + +\ 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/ppc/target.fth =================================================================== --- cpu/ppc/target.fth (rev 0) +++ cpu/ppc/target.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,291 @@ +purpose: Metacompiler target configuration for PowerPC +\ See license at end of file + +only forth also meta definitions +defer init-relocation-t +defer set-relocation-bit-t + +decimal + +h# c000 constant max-kernel \ Maximum size of the kernel + +only forth also meta assembler definitions +: normal ( -- ) \ Perform target-dependent assembler initialization +; + +only forth also meta definitions + +: lobyte th 0ff and ; +: hibyte 8 >> lobyte ; + +2 constant /w-t +4 constant /l-t +/l-t constant /n-t +/l-t constant /a-t +/a-t constant /thread-t +/l-t constant /token-t +/l-t constant /link-t +/token-t constant /defer-t +/n-t th 800 * constant user-size-t +/n-t th 100 * constant ps-size-t +/n-t th 200 * constant rs-size-t +/l-t constant /user#-t + +\ 32 bit host Forth compiling 32-bit target Forth +: l->n-t ; immediate +: n->l-t ; immediate +: n->n-t ; immediate +: s->l-t ; immediate + +[ifdef] little-endian +\ little-endian versions +\ The address munging (7 xor) with c@/!-t is due to the fact that +\ the system loads the target image in big-endian mode, and then +\ switches to little-endian mode after executing a few instructions. +: c!-t ( n add -- ) >hostaddr 7 xor c! ; +: w!-t ( n add -- ) over lobyte over c!-t ca1+ swap hibyte swap c!-t ; +: l!-t ( l add -- ) >r lwsplit swap r@ w!-t r> /w-t + w!-t ; +: c@-t ( target-address -- n ) >hostaddr 7 xor c@ ; +: w@-t ( target-address -- n ) dup c@-t swap 1+ c@-t 8 << or ; +: l@-t ( target-address -- n ) dup >r /w-t + w@-t r> w@-t swap wljoin ; +[else] +\ big-endian versions +: c!-t ( n add -- ) >hostaddr c! ; +: w!-t ( n add -- ) over hibyte over c!-t ca1+ swap lobyte swap c!-t ; +: l!-t ( l add -- ) ( set-swap-bit-t ) >r lwsplit r@ w!-t r> /w-t + w!-t ; +: c@-t ( target-address -- n ) >hostaddr c@ ; +: w@-t ( target-address -- n ) dup c@-t 8 << swap 1+ c@-t or ; +: l@-t ( target-address -- n ) dup >r /w-t + w@-t r> w@-t wljoin ; +[then] + +: le-l!-t ( l add -- ) >r lwsplit swap r@ w!-t r> /w-t + w!-t ; +: be-l!-t ( l add -- ) >r lwsplit r@ w!-t r> /w-t + w!-t ; + +: !-t ( n add -- ) l!-t ; +: @-t ( target-address -- n ) l@-t ; + +\ Store target data types into the host address space. +: c-t! ( c host-address -- ) c! ; +: w-t! ( w host-address -- ) + over hibyte over c-t! ca1+ swap lobyte swap c-t! +; +: l-t! ( l host-address -- ) >r lwsplit r@ w-t! r> /w-t + w-t! ; +: n-t! ( n host-address -- ) l-t! ; + +: c,-t ( byte -- ) here-t dup set-swap-bit-t 1 allot-t c!-t ; +: w,-t ( word -- ) here-t /w-t allot-t w!-t ; +: l,-t ( long -- ) here-t /l-t allot-t l!-t ; + +: ,-t ( n -- ) l,-t ; \ for 32 bit stacks +: ,user#-t ( user# -- ) l,-t ; + +: a@-t ( target-address -- target-address ) l@-t ; +: a!-t ( token target-address -- ) ( set-relocation-bit-t ) l!-t ; +: token@-t ( target-address -- target-acf ) a@-t ; +: token!-t ( acf target-address -- ) a!-t ; + +: rlink@-t ( occurrence -- next-occurrence ) a@-t ; +: rlink!-t ( next-occurrence occurrence -- ) token!-t ; + + +\ Machine independent +: a,-t ( adr -- ) here-t /a-t allot-t a!-t ; +: token,-t ( token -- ) here-t /token-t allot-t token!-t ; + +\ These versions of linkx-t are for absolute links +: link@-t ( target-address -- target-address' ) a@-t ; +: link!-t ( target-address target-address -- ) a!-t ; +: link,-t ( target-address -- ) a,-t ; + +: a-t@ ( host-address -- target-address ) +[ also forth ] + dup origin here within over up@ dup user-size + within or if +[ previous ] + l@ + else + hostaddr> a@-t + then +; +: a-t! ( target-address host-address -- ) +[ also forth ] + dup origin here within over up@ dup user-size + within or if +[ previous ] + l! + else + hostaddr> a!-t + then +; +: rlink-t@ ( host-adr -- target-adr ) a-t@ ; +: rlink-t! ( target-adr host-adr -- ) a-t! ; + +: token-t@ ( host-address -- target-acf ) a-t@ ; +: token-t! ( target-acf host-address -- ) a-t! ; +: link-t@ ( host-address -- target-address ) a-t@ ; +: link-t! ( target-address host-address -- ) a-t! ; + +\ Machine independent +: a-t, ( target-address -- ) here /a-t allot a-t! ; +: token-t, ( target-address -- ) here /token-t allot token-t! ; +: >body-t ( cfa-t -- pfa-t ) + \ The code fields of DOES> and ;CODE words contain an extra token + " dodoes" ['] labels $vfind if + execute + over token@-t = if /token-t + then + else + drop + then + /token-t + +; + + +\ 32 constant #threads-t +1 constant #threads-t +create (threads-t) #threads-t 1+ /link-t * allot +: threads-t ( -- adr ) (threads-t) 7 + 7 invert and ; + +: $hash-t ( adr len voc-ptr -- thread ) + -rot nip #threads-t 1- and /thread-t * + +; + +\ Should allocate these dynamically. +\ The dictionary space should be dynamically allocated too. + +\ The user area image lives in the host address space. +\ We wish to store into the user area with -t commands so as not +\ to need separate words to store target items into host addresses. +\ That is why user+ returns a target address. + +\ Machine Independent + +0 constant userarea-t +: setup-user-area ( -- ) + user-size-t alloc-mem is userarea-t + userarea-t user-size-t erase +; + +: >user-t ( cfa-t -- user-address-t ) + >body-t + @-t + userarea-t + +; + +: n>link-t ( anf-t -- alf-t ) /link-t - ; +: l>name-t ( alf-t -- anf-t ) /link-t + ; + +decimal +/l constant #align-t +/l constant #talign-t +/l constant #linkalign-t +/l constant #acf-align-t +: aligned-t ( n1 -- n2 ) #align-t 1- + #align-t negate and ; +: acf-aligned-t ( n1 -- n2 ) #acf-align-t 1- + #acf-align-t negate and ; + +\ NullFix bl -> 0 +: align-t ( -- ) + begin here-t #align-t 1- and while 0 c,-t repeat +; +: talign-t ( -- ) + begin here-t #talign-t 1- and while 0 c,-t repeat +; +: linkalign-t ( -- ) + begin here-t #linkalign-t 1- and while 0 c,-t repeat +; +: acf-align-t ( -- ) talign-t ; + +: entercode ( -- ) + only forth also labels also meta also ppc-assembler + [ also ppc-assembler ] + ['] $ppc-assem-do-undefined is $do-undefined + [ previous ] +\ assembler +; + +\ Next 5 are Machine Independent +: cmove-t ( from to-t n -- ) + 0 do over c@ over c!-t 1+ swap 1+ swap loop 2drop +; +: place-cstr-t ( adr len cstr-adr-t -- cstr-adr-t ) + >r tuck r@ swap cmove-t ( len ) r@ + 0 swap c!-t r> +; +: "copy-t ( from to-t -- ) + over c@ 2+ cmove-t +; +: toggle-t ( addr-t n -- ) swap >r r@ c@-t xor r> c!-t ; + +: clear-threads-t ( hostaddr -- ) + #threads-t /link-t * bounds do + origin-t i link-t! + /link +loop +; +: initmeta ( -- ) + init-swap-t + threads-t #threads-t /link-t * bounds do + origin-t i link-t! + /link +loop + threads-t current-t ! +; + +\ For compiling branch offsets used by control constructs. +\ These compile relative branches. + +/l-t constant /branch +: branch! ( offset addr-t -- ) + over - ( from offset ) swap + l!-t +; +: branch, ( offset -- ) + here-t - + l,-t +; + +\ Store actions for some data structures. This has to be in this +\ file because it depends on the location of the user area (in some +\ versions, the user area has to be in the dictionary for +\ relocation to work right, but in other versions, the user area +\ is elsewhere. Ultimately, separate relocation for the user area is +\ needed. + +: isuser ( n acf -- ) >user-t n-t! ; +: istuser ( acf1 acf -- ) >user-t token-t! ; +: isvalue ( n acf -- ) >user-t n-t! ; +: isdefer ( acf acf -- ) >user-t token-t! ; + +: thread-t! ( thread adr -- ) link-t! ; + +only forth also meta also definitions +: install-target-assembler ( -- ) + [ assembler ] +\ ['] dp-t is asmdp + ['] here-t is here + ['] allot-t is asm-allot + ['] l@-t is asm@ + ['] l!-t is asm! + [ meta ] +; +: install-host-assembler ( -- ) + [ assembler ] resident-assembler [ meta ] +; + +\ 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/ppc/testmmu.fth =================================================================== --- cpu/ppc/testmmu.fth (rev 0) +++ cpu/ppc/testmmu.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,175 @@ +purpose: Initialization code for PowerPC MMU +\ See license at end of file + +headerless +code v>p ( virt -- phys&mode ) + mr r3,tos + get-phys bl * + mr tos,r3 +c; +code vtopte ( virt -- vsid pteg ) + mr fault,tos + find-pte bl * + stwu vsid,-4(sp) + mr tos,pteg +c; +headers +: .htab htab /htab bounds do i @ if i . then 8 +loop ; + +headerless +list: translations-list + +: init-srs ( -- ) h# 10 0 do i i sr! loop ; + +[ifndef] initial-map +also forth definitions +: fw-base ( -- adr ) origin pagesize round-down ; + +headers +defer initial-map +: (initial-map) ( -- ) +[ '#adr-cells @ 2 = ] [if] +\ 0 0 0 2000.0000 -1 map \ Memory + + 0 0 over 2.0000 -1 map \ Hash table and trap vectors + 2.0000 0 over fw-base over - -1 map \ program load area + e0.0000 0 over 10.0000 -1 map \ Displacement flush area + f0.0000 0 over 10.0000 -1 map \ Firmware + + f100.0000 0 over 100.0000 -1 map \ Firmware I/O +\ 2000.0000 0 over e000.0000 -1 map \ I/O +[else] + 0 0 memsize -1 map \ Trap vects, pgm load area + fw-base virt-phys - fw-base htab /htab + over - -1 map \ Firmware +[then] + +[ifdef] io-base + io-base io-base h# 10000 -1 map +[then] +; +' (initial-map) to initial-map + +headerless +defer unmap-temp-io +: (unmap-temp-io) ( virt -- ) \ Remove temporary I/O mapping +[ifdef] io-base + dup io-base = if drop else h# 1000 unmap then +[else] + drop +[then] +; +' (unmap-temp-io) to unmap-temp-io +[then] +previous definitions +[then] + +: init-virtual-list ( -- ) + 0 memrange ! \ Clear free list + d# 500 memrange more-nodes \ Get enough nodes "forever" + + \ Create the available memory list from which the firmware is allowed + \ to dynamically allocate virtual memory. + + fw-virt-base fw-virt-size set-node fwvirt insert-after + + \ Setup the virtual list from which the firmware isn't permitted to allocate + 0 fw-virt-base add-os-piece + fw-virt-base fw-virt-size + ?dup if 0 add-os-piece then + +[ '#adr-cells @ 2 = ] [if] + \ XXX Claim the firmware and displacement flush areas for now + e0.0000 20.0000 claim-virtual drop +[else] + fw-base htab /htab + over - claim-virtual drop +[then] +; + +headers +warning off +: open ( -- ) + init-srs + + use-real-mode? if + install-bat-handler + setup-real-bat-table + clear-bats mapping-on + true exit + then + + set-mmu + + init-virtual-list + + translations-list to translations + + d# 50 translation-node more-nodes + + translations virt-phys - 4f8 ! \ physical + virt-phys 4fc ! \ virtual minus physical + 0 4f4 ! \ Replacement offset + save-state virt-phys - 4f0 ! \ fallback handler address + + init-paged-mmu + + initial-map + + configure-tlb + +[ifdef] install-tlb-miss +[ifdef] exponential + 704-class? if + install-exp-tlb-miss + else + install-tlb-miss + then +[else] + install-tlb-miss +[then] +[then] + + htab-dsi-handler h# 300 put-exception + htab-isi-handler h# 400 put-exception + + virt-phys if mapping-on clear-bats else clear-bats mapping-on then + + false to in-real-mode? + + true +; +warning on + +[ifdef] NOTYET +Allocate contiguous physical memory and add nodes to the translations +list. The memory should have one extra cell at the beginning, which is +the list head. Set "translations" to the virtual base address of the +beginning of that memory. +Store the difference between the physical and virtual base address of +that memory somewhere that the trap handler can find. +This is necessary because the fault handler runs in real mode, and needs +a convenient way to chase the list links without having to apply different +translations to different list nodes. +[then] + +\ 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/ppc/tlb.fth =================================================================== --- cpu/ppc/tlb.fth (rev 0) +++ cpu/ppc/tlb.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,61 @@ +purpose: TLB invalidation +\ See license at end of file + +headerless +code invalidate-tlb-entry ( virtual -- ) + sync isync + tlbie tos + + mfspr tos,pvr + rlwinm tos,tos,16,16,31 + cmpi 0,0,tos,1 + <> if + tlbsync + then + + lwz tos,0(sp) + addi sp,sp,1cell +c; +code invalidate-tlb ( -- ) + 'user #tlb-lines lwz t0,* + + sync isync + rlwinm t0,t0,12,4,19 + + begin + addic. t0,t0,h#-1000 + tlbie t0 + 0= until + + mfspr t0,pvr + rlwinm t0,t0,16,16,31 + cmpi 0,0,t0,1 + <> if + tlbsync + then +c; +headers + +\ 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/ppc/tlb601.fth =================================================================== --- cpu/ppc/tlb601.fth (rev 0) +++ cpu/ppc/tlb601.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,59 @@ +purpose: TLB invalidation for 601 +\ See license at end of file + +code invalidate-tlb-entry ( virtual -- ) + sync isync + tlbie tos + + mfspr tos,pvr + rlwinm tos,tos,16,16,31 + cmpi 0,0,tos,1 + <> if + tlbsync + then + + lwz tos,0(sp) + addi sp,sp,1cell +c; +code invalidate-tlb ( -- ) + 'user #tlb-lines lwz t0,* + + sync isync + rlwinm t0,t0,12,4,19 + + begin + addic. t0,t0,h#-1000 + tlbie t0 + 0= until + + mfspr tos,pvr + rlwinm tos,tos,16,16,31 + cmpi 0,0,tos,1 + <> if + tlbsync + then +c; + +\ 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/ppc/tlbmiss.fth =================================================================== --- cpu/ppc/tlbmiss.fth (rev 0) +++ cpu/ppc/tlbmiss.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,318 @@ +purpose: TLB miss handlers for 603-style (software PTE search) MMU +\ See license at end of file + +also assembler definitions +\needs set-y : set-y ( -- ) h# 0020.0000 add-bits ; +previous definitions + +headerless +label itlb-miss + \ Adapted from the code in section 7.6.3.2.2 of the 603 manual + mfspr r2,hash1 \ PTEG address + mfspr r0,ctr \ Save CTR + mfspr r3,icmp \ Comparison value + begin + mfmsr r1 + andi. r1,r1,1 + <> if \ Little-endian + addi r2,r2,-4 \ Account for pre-increment and endianness + else + addi r2,r2,-8 \ Account for pre-increment + then + addi r1,0,8 \ PTEs per PTEG + mtspr ctr,r1 \ Load CTR + begin + lwzu r1,8(r2) \ Get first word of PTE + cmp 0,0,r1,r3 \ Found PTE? + = ctr=0 until + = if \ Found? + \ Found a matching TLB entry + mfmsr r1 + andi. r1,r1,1 + <> if \ Little-endian + addi r2,r2,-8 \ Bias address to account for endianness + then + lwz r1,4(r2) \ Get physical word of matching TLB entry + andi. r3,r1,8 \ Check G bit + 1 F: <> brif \ ISI because of ifetch of guarded page + + mtspr ctr,r0 \ Restore CTR + mfspr r0,imiss \ Miss address + mfspr r3,srr1 \ saved cr0 bits + mtcrf h#80,r3 \ Restore CR0 + mtspr rpa,r1 \ Set PTE + ori r1,r1,h#100 \ Set the reference bit + tlbli r0 \ Load the TLB entry + tlbsync \ wait for tlbli to complete + stw r1,4(r2) \ update page table with R bit set + sync \ wait for page table store to complete + rfi + then + + \ Not found; try secondary hash or signal exception + andi. r1,r3,h#40 \ See if we have done second hash + 0= while + mfspr r2,hash2 \ Try secondary hash + ori r3,r3,h#40 \ Set H bit in compare value + repeat + + \ No HTAB entry; let the normal IAE handler take care of it + mfspr r3,srr1 \ Get SRR1 + rlwinm r2,r3,0,16,31 \ Clear high bits + addis r2,r2,h#4000 \ Or in srr1<1> = 1 to flag PTE not found + 2 F: always brif \ Branch to common IAE code + +1 L: \ Protection violation (guarded page) + mfspr r3,srr1 \ Get SRR1 + rlwinm r2,r3,0,16,31 \ Clear high bits + addis r2,r2,h#0800 \ Or in srr1<4> = 1 to flag prot. violation + +2 L: \ Common code for instruction access exception + mtspr ctr,r0 \ Restore CTR + mtspr srr1,r2 \ Put back fixed SRR1 + mfmsr r0 \ Get MSR + xoris r0,r0,h#0002 \ Flip the MSR<tgpr> bit + mtcrf h#80,r3 \ Restore CR0 + mtmsr r0 \ Go back to the normal GPRs + h# 400 ba * \ Go to the normal ISI handler +end-code +here itlb-miss - constant /itlb-miss + +\ This handler is used for both load and store exceptions because, since +\ we don't do demand paging, we need not maintain the "C" (changed) bit. + +label dtlb-r-miss + \ Adapted from the code in section 7.6.3.2.2 of the 603 manual + mfspr r2,hash1 \ PTEG address + mfspr r0,ctr \ Save CTR + mfspr r3,dcmp \ Comparison value + begin + mfmsr r1 + andi. r1,r1,1 + <> if \ Little-endian + addi r2,r2,-4 \ Account for pre-increment and endianness + else + addi r2,r2,-8 \ Account for pre-increment + then + addi r1,0,8 \ PTEs per PTEG + mtspr ctr,r1 \ Load CTR + begin + lwzu r1,8(r2) \ Get first word of PTE + cmp 0,0,r1,r3 \ Found PTE? + = ctr=0 until + = if + \ Found a matching TLB entry + mfmsr r1 + andi. r1,r1,1 + <> if \ Little-endian + addi r2,r2,-8 \ Bias address to account for endianness + then + lwz r1,4(r2) \ Get physical word of matching TLB entry + mtspr ctr,r0 \ Restore CTR + mfspr r0,dmiss \ Miss address + mfspr r3,srr1 \ saved cr0 bits + mtcrf h#80,r3 \ Restore CR0 + mtspr rpa,r1 \ Set PTE + ori r1,r1,h#100 \ Set the referenced bit + tlbld r0 \ Load the TLB entry + tlbsync \ Wait for tlbld to complete + stw r1,4(r2) \ Update TLB entry + sync \ Wait for page table store to complete + rfi + then + + \ Not found; try secondary hash or signal exception + andi. r1,r3,h#40 \ See if we have done second hash + 0= while + mfspr r2,hash2 \ Try secondary hash + ori r3,r3,h#40 \ Set H bit in compare value + repeat + + set r1,h#4000.0000 \ Set dsisr1<1> = 1 to flag PTE not found + + mfspr r3,srr1 \ Get SRR1 + mtspr ctr,r0 \ Restore CTR + rlwinm r2,r3,0,16,31 \ Clear upper bits of SRR1 + mtspr srr1,r2 \ Put back fixed SRR1 + mtspr dsisr,r1 \ Set DSISR + mfspr r1,dmiss \ Get miss address + + rlwinm. r2,r2,0,31,31 \ Test LE bit + <> if \ Little-endian + \ Note: this is naive; the processor's address + \ swizzling is size-dependent. However, this + \ is what the example code in the 603 data + \ book does. + xori r1,r1,7 \ convert to little-endian data address + then + + mtspr dar,r1 \ Set DAR + mfmsr r0 \ Get MSR + xoris r0,r0,h#0002 \ Flip the MSR<tgpr> bit + mtcrf h#80,r3 \ Restore CR0 + mtmsr r0 \ Go back to the normal GPRs + h# 300 ba * \ Go to the normal DSI handler +end-code +here dtlb-r-miss - constant /dtlb-r-miss + +label dtlb-w-miss + \ Adapted from the code in section 7.6.3.2.2 of the 603 manual + mfspr r2,hash1 \ PTEG address + mfspr r0,ctr \ Save CTR + mfspr r3,dcmp \ Comparison value + begin + mfmsr r1 + andi. r1,r1,1 + <> if \ Little-endian + addi r2,r2,-4 \ Account for pre-increment and endianness + else + addi r2,r2,-8 \ Account for pre-increment + then + addi r1,0,8 \ PTEs per PTEG + mtspr ctr,r1 \ Load CTR + begin + lwzu r1,8(r2) \ Get first word of PTE + cmp 0,0,r1,r3 \ Found PTE? + = ctr=0 until + = if + \ Found a matching TLB entry + + mfmsr r1 + andi. r1,r1,1 + <> if \ Little-endian + addi r2,r2,-8 \ Bias address to account for endianness + then + + lwz r1,4(r2) \ Get physical word of matching TLB entry + andi. r3,r1,h#80 \ Check the C bit + 0 F: = brif \ If (C==0) goto cEq0ChkProt (check prot modes) + +1 L: \ (ceq2:) + mtspr ctr,r0 \ Restore CTR + mfspr r0,dmiss \ Miss address + mfspr r3,srr1 \ saved cr0 bits + mtcrf h#80,r3 \ Restore CR0 + mtspr rpa,r1 \ Set PTE + tlbld r0 \ Load the TLB entry + tlbsync \ Wait for tlbld to complete + sync + rfi + then + + \ Not found; try secondary hash or signal exception + andi. r1,r3,h#40 \ See if we have done second hash + 0= while + mfspr r2,hash2 \ Try secondary hash + ori r3,r3,h#40 \ Set H bit in compare value + repeat + + set r1,h#4200.0000 \ Set dsisr1<1> = 1 to flag PTE not found, + \ <6>=1 to denote "store" operation) + 3 F: always brif + +2 L: + set r1,h#0a00.0000 \ Set dsisr1<4> = 1 to flag prot. violation + \ <6> = 1 to denote "store" operation +3 L: + mfspr r3,srr1 \ Get SRR1 + mtspr ctr,r0 \ Restore CTR + rlwinm r2,r3,0,16,31 \ Clear upper bits of SRR1 + mtspr srr1,r2 \ Put back fixed SRR1 + mtspr dsisr,r1 \ Set DSISR + mfspr r1,dmiss \ Get miss address + + rlwinm. r2,r2,0,31,31 \ Test LE bit + <> if \ Little-endian + \ Note: this is naive; the processor's address + \ swizzling is size-dependent. However, this + \ is what the example code in the 603 data + \ book does. + xori r1,r1,7 \ convert to little-endian data address + then + + mtspr dar,r1 \ Set DAR + mfmsr r0 \ Get MSR + xoris r0,r0,h#0002 \ Flip the MSR<tgpr> bit + mtcrf h#80,r3 \ Restore CR0 + mtmsr r0 \ Go back to the normal GPRs + h# 300 ba * \ Go to the normal DSI handler + +0 L: \ (cEq0ChkProt:) +\ We found the PTE in the page table and it has the +\ C (changed) bit set to zero. Check the protection bits. +\ PP: 00 SRSW +\ 01 SRWUR +\ 10 SRWURW +\ 11 SRUR + rlwinm. r3,r1,30,0,1 \ test PP + + < if \ if (PP==10 or PP==11) + andi. r3,r1,1 \ test PP[0] + 4 F: = brif set-y \ return if PP==10 + 2 B: always brif \ else Data Access Exception Protection (PP=11) + + then + + \ (chk0:) + \ PP==00 or PP==01 + \ Test MSR[PR] to determine protection violation. + + mfspr r3,srr1 \ get old msr + andi. r3,r3,0x4000 \ test PR bit + + <> if set-y \ if (PR!=0) + mfspr r3,dmiss \ get miss address + mfsrin r3,r3 \ get associated segment register + andis. r3,r3,0x2000 \ test Kp bit + 4 F: = brif set-y \ if (Kp==0) goto chk2 + 2 B: always brif \ else Data Access Exception Protection + then + + mfspr r3,dmiss \ get miss address (chk1:) + mfsrin r3,r3 \ get associated segment register + andis. r3,r3,0x4000 \ test Ks bit + 4 F: = brif set-y \ if (Ks==0) goto chk2 + 2 B: always brif \ else Data Access Exception Protection + +4 L: \ (chk2:) No protection violation + ori r1,r1,0x180 \ set reference and change bit + stw r1,4(r2) \ update page table + 1 B: always brif \ go back to main-line handler code + +end-code +here dtlb-w-miss - constant /dtlb-w-miss + +: put-handler ( adr exc-adr len -- ) 2dup 2>r move 2r> sync-cache ; + +: install-tlb-miss ( -- ) + software-tlb-miss? if + itlb-miss h# 1000 /itlb-miss put-handler \ Ifetch TLB miss + dtlb-r-miss h# 1100 /dtlb-r-miss put-handler \ Data load TLB miss + dtlb-w-miss h# 1200 /dtlb-w-miss put-handler \ Data store TLB miss + then +; +headers + +\ 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/ppc/tlbms823.fth =================================================================== --- cpu/ppc/tlbms823.fth (rev 0) +++ cpu/ppc/tlbms823.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,127 @@ +purpose: TLB miss handlers for 823-style MMU +\ See license at end of file + +also assembler definitions +\needs set-y : set-y ( -- ) h# 0020.0000 add-bits ; +previous definitions + +headerless + +h# 00d constant twc-mem \ Unguarded, 8MB, writeback +h# 01f constant twc-io \ Guarded, 8MB, writethrough +h# 9fd constant rpn-mem \ Cacheable +h# 9ff constant rpn-io \ Cache inhibit + +\ On entry: +\ sprg0 = &exception-save-area (don't clobber it!) + +\ Save registers in: +\ sprg1 = cr +\ sprg2 = r2 +\ sprg3 = r3 + +label dtlb-miss + + mtspr sprg3,r3 \ Save R3 + mtspr sprg2,r2 \ Save R2 + + mfcr r3 + mtspr sprg1,r3 \ Save cr + + mfmsr r3 + rlwinm r3,r3,0,15,28,26 \ Disable DR + mtmsr r3 + + \ Generate new TLB + set r3,h#2000.0000 + mfspr r2,md-epn \ Get effective address + rlwinm r2,r2,0,0,19 + cmpl 0,0,r2,r3 + < if + twc-mem set r3,* + mtspr md-twc,r3 \ Table Walk Control Reg + rpn-mem set r3,* + else + twc-io set r3,* + mtspr md-twc,r3 \ Table Walk Control Reg + rpn-io set r3,* + then + + or r3,r3,r2 + mtspr md-rpn,r3 \ Real Page Number Reg + sync isync + + \ Restore registers + mfmsr r3 + ori r3,r3,h#10 \ Enable DR + mtmsr r3 + + mfspr r3,sprg1 + mtcrf h#ff,r3 \ Restore CR + mfspr r2,sprg2 \ Restore R2 + mfspr r3,sprg3 \ Restore R3 + + \ Return from interrupt + rfi +end-code +here dtlb-miss - constant /dtlb-miss + +: init-dtlb ( -- ) + 0 m-casid! \ Current address space + 0 md-ap! \ Access protection groups + h# 0400.0000 md-ctr! \ PowerPC mode, Page res protection, TWAN=1 + \ DTLB_INDX dec mod 8, ignore problem/privilege + \ DTLB_INDX=0 +; +: init-tlb-entries ( -- ) + h# 0000.0200 md-epn! \ EPN=0 + twc-mem md-twc! + h# 0000.0000 rpn-mem or md-rpn! \ RPN=EPN + + h# 0080.0200 md-epn! \ EPN=80.0000 + twc-mem md-twc! + h# 0080.0000 rpn-mem or md-rpn! \ RPN=EPN + + h# fa20.0200 md-epn! \ EPN=FA20.0000 + twc-io md-twc! + h# fa20.0000 rpn-io or md-rpn! \ RPN=EPN +; +defer init-tlb ' init-dtlb to init-tlb + +: put-handler ( adr exc-adr len -- ) 2dup 2>r move 2r> sync-cache ; + +: install-tlb-miss ( -- ) + software-tlb-miss? if + dtlb-miss h# 1200 /dtlb-miss put-handler \ Data TLB miss + then + \ Redirect the implementation-dependent emulation trap, which + \ is what the 8xx PPC core generates instead of the usual program + \ interrupt, to the program interrupt vector. + h# 700 h# 1000 put-branch +; +headers + + +\ 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/ppc/tmmu823.fth =================================================================== --- cpu/ppc/tmmu823.fth (rev 0) +++ cpu/ppc/tmmu823.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,114 @@ +purpose: Initialization code for PowerPC 823 MMU +\ See license at end of file + +headerless +: dmapping-on ( -- ) msr@ h# 10 or msr! ; +: dmapping-off ( -- ) msr@ h# 10 invert and msr! ; + +headerless +list: translations-list + +[ifndef] initial-map +also forth definitions +: fw-base ( -- adr ) origin pagesize round-down ; + +headers +defer initial-map +: (initial-map) ( -- ) +[ '#adr-cells @ 2 = ] [if] +\ 0 0 0 2000.0000 -1 map \ Memory + + 0 0 over 2.0000 -1 map \ Hash table and trap vectors + 2.0000 0 over fw-base over - -1 map \ program load area + e0.0000 0 over 10.0000 -1 map \ Displacement flush area + f0.0000 0 over 10.0000 -1 map \ Firmware + + f100.0000 0 over 100.0000 -1 map \ Firmware I/O +\ 2000.0000 0 over e000.0000 -1 map \ I/O +[else] + 0 0 memsize -1 map \ Trap vects, pgm load area + fw-base virt-phys - fw-base 20.0000 -1 map \ Firmware +[then] +; +' (initial-map) to initial-map + +headerless +defer unmap-temp-io ' noop to unmap-temp-io +[then] +previous definitions +[then] + +: init-virtual-list ( -- ) + 0 memrange ! \ Clear free list + d# 500 memrange more-nodes \ Get enough nodes "forever" + + \ Create the available memory list from which the firmware is allowed + \ to dynamically allocate virtual memory. + + fw-virt-base fw-virt-size set-node fwvirt insert-after + + \ Setup the virtual list from which the firmware isn't permitted to allocate + 0 fw-virt-base add-os-piece + fw-virt-base fw-virt-size + ?dup if 0 add-os-piece then + + fw-base 20.0000 claim-virtual drop +; + +headers +warning off +: open ( -- ) + init-virtual-list + + translations-list to translations + + d# 50 translation-node more-nodes + + translations virt-phys - 4f8 ! \ physical + virt-phys 4fc ! \ virtual minus physical + 0 4f4 ! \ Replacement offset + save-state virt-phys - 4f0 ! \ fallback handler address + + configure-tlb + init-tlb + invalidate-tlb + init-tlb-entries + initial-map + install-tlb-miss + dmapping-on + + true to in-real-mode? + true +; + +: tlb0! ( rpn -- ) + 200 md-epn! d md-twc! md-rpn! + md-ctr@ 700 invert and md-ctr! + 0 md-cam! + md-cam@ u. md-ram0@ u. md-ram1@ u. cr +; +warning on + + +\ 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/ppc/tools.bth =================================================================== --- cpu/ppc/tools.bth (rev 0) +++ cpu/ppc/tools.bth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,49 @@ +purpose: Load file for Forth toolkit, without firmware +\ See license at end of file + +dictionary: ${BP}/cpu/ppc/build/kernel.dic +command: &ppcforth &dictionary &this +build-now + +\ ' $report-name is include-hook +\ ' noop is include-hook +\ : rn (cr 2dup type 15 spaces ; ' rn is include-hook + +create resident-packages + +fload ${BP}/forth/lib/fwsetup.fth + +transient +true value assembler? \ False to discard assembler after compilation +resident + +fload ${BP}/forth/lib/loadcomm.fth \ CPU-independent Forth tools +fload ${BP}/cpu/ppc/loadmach.fth \ CPU and OS-specific extensions + +[ifndef] no-heads +.( --- Saving tools.dic --- ) "" tools.dic save-forth cr +[then] + +\ 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/ppc/touchall.fth =================================================================== --- cpu/ppc/touchall.fth (rev 0) +++ cpu/ppc/touchall.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,43 @@ +purpose: Forces all translations into the HTAB +\ See license at end of file + +: touch ( -- ) + " /mmu" find-device + " translations" get-property abort" No translations property" ( adr len ) + begin dup while + decode-int >r ( r: virt ) + decode-int >r ( r: virt size ) + decode-int drop ( r: virt size ) \ Discard phys.hi + decode-int drop ( r: virt size ) \ Discard phys.lo + decode-int h# 20 and if ( r: virt size ) \ I/O + 2r> 2drop + else + r> r> swap bounds ?do i c@ drop pagesize +loop + then + repeat + 2drop +; + +\ 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/ppc/unalign.fth =================================================================== --- cpu/ppc/unalign.fth (rev 0) +++ cpu/ppc/unalign.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,115 @@ +purpose: Unaligned memory access primitives +\ See license at end of file + +0 value in-little-endian? + +code unaligned-l@ (s adr -- l ) + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + <> if \ Little endian + lbz t0,0(tos) \ low byte + lbz t1,1(tos) \ next byte + rlwimi t0,t1,8,16,23 + lbz t1,2(tos) \ next byte + rlwimi t0,t1,16,8,15 + lbz t1,3(tos) \ High byte + rlwimi t0,t1,24,0,7 + else \ Big endian + lbz t0,3(tos) \ low byte + lbz t1,2(tos) \ next byte + rlwimi t0,t1,8,16,23 + lbz t1,1(tos) \ next byte + rlwimi t0,t1,16,8,15 + lbz t1,0(tos) \ High byte + rlwimi t0,t1,24,0,7 + then + mr tos,t0 +c; +: unaligned-@ (s adr -- l ) unaligned-l@ ; +code unaligned-w@ (s adr -- w ) + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + <> if \ Little endian + lbz t0,1(tos) \ High byte + lbz t1,0(tos) \ low byte + else \ Big endian + lbz t0,0(tos) \ High byte + lbz t1,1(tos) \ low byte + then + rlwimi t1,t0,8,16,23 + mr tos,t1 +c; +code unaligned-l! (s n adr -- ) + second-to-t0 \ n in t0 + + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + <> if \ Little endian + stb t0,0(tos) + rlwinm t0,t0,24,0,31 + stb t0,1(tos) + rlwinm t0,t0,24,0,31 + stb t0,2(tos) + rlwinm t0,t0,24,0,31 + stb t0,3(tos) + else \ Big endian + \ XXX I think the hardware will do this for you + stb t0,3(tos) + rlwinm t0,t0,24,0,31 + stb t0,2(tos) + rlwinm t0,t0,24,0,31 + stb t0,1(tos) + rlwinm t0,t0,24,0,31 + stb t0,0(tos) + then + + pop1 +c; + +: unaligned-d! ( d adr -- ) + >r in-little-endian? if swap then + r@ unaligned-! r> na1+ unaligned-! +; + +: unaligned-! (s n adr -- ) unaligned-l! ; +code unaligned-w! (s w adr -- ) + second-to-t0 \ n in t0 + + 'user in-little-endian? lwz t1,* + cmpi 0,0,t1,0 + <> if \ Little endian + stb t0,0(tos) + rlwinm t0,t0,24,24,31 + stb t0,1(tos) + else \ Big endian + \ XXX I think the hardware will do this for you + stb t0,1(tos) + rlwinm t0,t0,24,24,31 + stb t0,0(tos) + then + pop1 +c; + +\ 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/ppc/xadd.fth =================================================================== --- cpu/ppc/xadd.fth (rev 0) +++ cpu/ppc/xadd.fth 2007-07-05 17:19:17 UTC (rev 461) @@ -0,0 +1,45 @@ +purpose: 64-bit addition and subtraction +\ See license at end of file + +code x+ ( x1 x2 -- x3 ) + lwz t1,0(sp) \ x2.low + lwz t3,8(sp) \ x1.low + lwz t2,4(sp) \ x1.high + addi sp,sp,8 \ Pop args + addc t1,t1,t3 \ x3.low + adde tos,tos,t2 \ x3.high + stw t1,0(sp) \ Push result (x3.high already in tos) +c; +code x- ( x1 x2 -- x3 ) + lwz t1,0(sp) \ x2.low + lwz t2,4(sp) \ x1.high + lwz t3,8(sp) \ x1.low + addi sp,sp,8 \ Pop args + subfc t1,t1,t3 \ x3.low + subfe tos,tos,t2 \ x3.high + stw t1,0(sp) \ Push result (x3.high already in tos) +c; + +\ 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