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