diff options
Diffstat (limited to 'qemu/roms/SLOF/slof/fs/packages')
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/deblocker.fs | 70 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/disk-label.fs | 660 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/ext2-files.fs | 188 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/fat-files.fs | 188 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/filler.fs | 21 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/iso-9660.fs | 325 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/obp-tftp.fs | 71 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/rom-files.fs | 85 | ||||
-rw-r--r-- | qemu/roms/SLOF/slof/fs/packages/sms.fs | 29 |
9 files changed, 1637 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/slof/fs/packages/deblocker.fs b/qemu/roms/SLOF/slof/fs/packages/deblocker.fs new file mode 100644 index 000000000..83cd71278 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/deblocker.fs @@ -0,0 +1,70 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +\ ============================================================================= +\ ============================================================================= + + +\ The deblocker. Allows block devices to be used as a (seekable) byte device. + +s" deblocker" device-name + +INSTANCE VARIABLE offset +INSTANCE VARIABLE block-size +INSTANCE VARIABLE max-transfer +INSTANCE VARIABLE my-block +INSTANCE VARIABLE adr +INSTANCE VARIABLE len +INSTANCE VARIABLE fail-count + +: open + s" block-size" ['] $call-parent CATCH IF 2drop false EXIT THEN + block-size ! + s" max-transfer" ['] $call-parent CATCH IF 2drop false EXIT THEN + max-transfer ! + block-size @ alloc-mem my-block ! + 0 offset ! + true ; +: close my-block @ block-size @ free-mem ; + +: seek ( lo hi -- status ) \ XXX: perhaps we should fail if the underlying + \ device would fail at this offset + lxjoin offset ! 0 ; +: block+remainder ( -- block# remainder ) offset @ block-size @ u/mod swap ; +: read-blocks ( addr block# #blocks -- actual ) s" read-blocks" $call-parent ; +: read ( addr len -- actual ) + dup >r len ! adr ! + \ First, handle a partial block at the start. + block+remainder dup IF ( block# offset-in-block ) + >r my-block @ swap 1 read-blocks drop + my-block @ r@ + adr @ block-size @ r> - len @ min dup >r move + r> dup negate len +! dup adr +! offset +! ELSE 2drop THEN + + \ Now, in a loop read max. max-transfer sized runs of whole blocks. + 0 fail-count ! + BEGIN len @ block-size @ >= WHILE + adr @ block+remainder drop len @ max-transfer @ min block-size @ / read-blocks + dup 0= IF + 1 fail-count +! + fail-count @ 5 >= IF r> drop EXIT THEN + ELSE + 0 fail-count ! + THEN + block-size @ * dup negate len +! dup adr +! offset +! + REPEAT + + \ And lastly, handle a partial block at the end. + len @ IF my-block @ block+remainder drop 1 read-blocks drop + my-block @ adr @ len @ move THEN + + r> ; diff --git a/qemu/roms/SLOF/slof/fs/packages/disk-label.fs b/qemu/roms/SLOF/slof/fs/packages/disk-label.fs new file mode 100644 index 000000000..fe1c25e7a --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/disk-label.fs @@ -0,0 +1,660 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +\ Set debug-disk-label? to true to get debug messages for the disk-label code. +false VALUE debug-disk-label? + +\ This value defines the maximum number of blocks (512b) to load from a PREP +\ partition. This is required to keep the load time in reasonable limits if the +\ PREP partition becomes big. +\ If we ever want to put a large kernel with initramfs from a PREP partition +\ we might need to increase this value. The default value is 65536 blocks (32MB) +d# 65536 value max-prep-partition-blocks + +s" disk-label" device-name + +0 INSTANCE VALUE partition +0 INSTANCE VALUE part-offset +0 INSTANCE VALUE disk-chrp-boot + +0 INSTANCE VALUE part-start +0 INSTANCE VALUE lpart-start +0 INSTANCE VALUE part-size +0 INSTANCE VALUE dos-logical-partitions + +0 INSTANCE VALUE block-size +0 INSTANCE VALUE block + +0 INSTANCE VALUE args +0 INSTANCE VALUE args-len + +0 INSTANCE VALUE gpt-part-size +0 INSTANCE VALUE seek-pos + + +INSTANCE VARIABLE block# \ variable to store logical sector# +INSTANCE VARIABLE hit# \ partition counter +INSTANCE VARIABLE success-flag + +\ ISO9660 specific information +0ff constant END-OF-DESC +3 constant PARTITION-ID +48 constant VOL-PART-LOC + + +\ DOS partition label (MBR) specific structures + +STRUCT + 1b8 field mbr>boot-loader + /l field mbr>disk-signature + /w field mbr>null + 40 field mbr>partition-table + /w field mbr>magic + +CONSTANT /mbr + +STRUCT + /c field part-entry>active + /c field part-entry>start-head + /c field part-entry>start-sect + /c field part-entry>start-cyl + /c field part-entry>id + /c field part-entry>end-head + /c field part-entry>end-sect + /c field part-entry>end-cyl + /l field part-entry>sector-offset + /l field part-entry>sector-count + +CONSTANT /partition-entry + +STRUCT + 8 field gpt>signature + 4 field gpt>revision + 4 field gpt>header-size + 4 field gpt>header-crc32 + 4 field gpt>reserved + 8 field gpt>current-lba + 8 field gpt>backup-lba + 8 field gpt>first-lba + 8 field gpt>last-lba + 10 field gpt>disk-guid + 8 field gpt>part-entry-lba + 4 field gpt>num-part-entry + 4 field gpt>part-entry-size + 4 field gpt>part-array-crc32 + 1a4 field gpt>reserved + +CONSTANT /gpt-header + +STRUCT + 10 field gpt-part-entry>part-type-guid + 10 field gpt-part-entry>part-guid + 8 field gpt-part-entry>first-lba + 8 field gpt-part-entry>last-lba + 8 field gpt-part-entry>attribute + 48 field gpt-part-entry>part-name + +CONSTANT /gpt-part-entry + +\ Defined by IEEE 1275-1994 (3.8.1) + +: offset ( d.rel -- d.abs ) + part-offset xlsplit d+ +; + +: seek ( pos.lo pos.hi -- status ) + offset + debug-disk-label? IF 2dup ." seek-parent: pos.hi=0x" u. ." pos.lo=0x" u. THEN + s" seek" $call-parent + debug-disk-label? IF dup ." status=" . cr THEN +; + +: read ( addr len -- actual ) + debug-disk-label? IF 2dup swap ." read-parent: addr=0x" u. ." len=" .d THEN + s" read" $call-parent + debug-disk-label? IF dup ." actual=" .d cr THEN +; + + +\ read sector to array "block" +: read-sector ( sector-number -- ) + \ block-size is 0x200 on disks, 0x800 on cdrom drives + block-size * 0 seek drop \ seek to sector + block block-size read drop \ read sector +; + +: (.part-entry) ( part-entry ) + cr ." part-entry>active: " dup part-entry>active c@ .d + cr ." part-entry>start-head: " dup part-entry>start-head c@ .d + cr ." part-entry>start-sect: " dup part-entry>start-sect c@ .d + cr ." part-entry>start-cyl: " dup part-entry>start-cyl c@ .d + cr ." part-entry>id: " dup part-entry>id c@ .d + cr ." part-entry>end-head: " dup part-entry>end-head c@ .d + cr ." part-entry>end-sect: " dup part-entry>end-sect c@ .d + cr ." part-entry>end-cyl: " dup part-entry>end-cyl c@ .d + cr ." part-entry>sector-offset: " dup part-entry>sector-offset l@-le .d + cr ." part-entry>sector-count: " dup part-entry>sector-count l@-le .d + cr +; + +: (.name) r@ begin cell - dup @ <colon> = UNTIL xt>name cr type space ; + +: init-block ( -- ) + s" block-size" ['] $call-parent CATCH IF ABORT" parent has no block-size." THEN + to block-size + d# 4096 alloc-mem + dup d# 4096 erase + to block + debug-disk-label? IF + ." init-block: block-size=" block-size .d ." block=0x" block u. cr + THEN +; + +: partition>part-entry ( partition -- part-entry ) + 1- /partition-entry * block mbr>partition-table + +; + +: partition>start-sector ( partition -- sector-offset ) + partition>part-entry part-entry>sector-offset l@-le +; + +\ This word returns true if the currently loaded block has _NO_ MBR magic +: no-mbr? ( -- true|false ) + 0 read-sector + 1 partition>part-entry part-entry>id c@ ee = IF TRUE EXIT THEN \ GPT partition found + block mbr>magic w@-le aa55 <> +; + +\ This word returns true if the currently loaded block has _NO_ GPT partition id +: no-gpt? ( -- true|false ) + 0 read-sector + 1 partition>part-entry part-entry>id c@ ee <> +; + +: pc-extended-partition? ( part-entry-addr -- true|false ) + part-entry>id c@ ( id ) + dup 5 = swap ( true|false id ) + dup f = swap ( true|false true|false id ) + 85 = ( true|false true|false true|false ) + or or ( true|false ) +; + +: count-dos-logical-partitions ( -- #logical-partitions ) + no-mbr? IF 0 EXIT THEN + 0 5 1 DO ( current ) + i partition>part-entry ( current part-entry ) + dup pc-extended-partition? IF + part-entry>sector-offset l@-le ( current sector ) + dup to part-start to lpart-start ( current ) + BEGIN + part-start read-sector \ read EBR + 1 partition>start-sector IF + \ ." Logical Partition found at " part-start .d cr + 1+ + THEN \ another logical partition + 2 partition>start-sector + ( current relative-sector ) + ?dup IF lpart-start + to part-start false ELSE true THEN + UNTIL + ELSE + drop + THEN + LOOP +; + +: (get-dos-partition-params) ( ext-part-start part-entry -- offset count active? id ) + dup part-entry>sector-offset l@-le rot + swap ( offset part-entry ) + dup part-entry>sector-count l@-le swap ( offset count part-entry ) + dup part-entry>active c@ 80 = swap ( offset count active? part-entry ) + part-entry>id c@ ( offset count active? id ) +; + +: find-dos-partition ( partition# -- false | offset count active? id true ) + to partition 0 to part-start 0 to part-offset + + \ no negative partitions + partition 0<= IF 0 to partition false EXIT THEN + + \ load MBR and check it + no-mbr? IF 0 to partition false EXIT THEN + + partition 4 <= IF \ Is this a primary partition? + 0 partition partition>part-entry + (get-dos-partition-params) + \ FIXME sanity checks? + true EXIT + ELSE + partition 4 - 0 5 1 DO ( logical-partition current ) + i partition>part-entry ( log-part current part-entry ) + dup pc-extended-partition? IF + part-entry>sector-offset l@-le ( log-part current sector ) + dup to part-start to lpart-start ( log-part current ) + BEGIN + part-start read-sector \ read EBR + 1 partition>start-sector IF \ first partition entry + 1+ 2dup = IF ( log-part current ) + 2drop + part-start 1 partition>part-entry + (get-dos-partition-params) + true UNLOOP EXIT + THEN + 2 partition>start-sector + ( log-part current relative-sector ) + + ?dup IF lpart-start + to part-start false ELSE true THEN + ELSE + true + THEN + UNTIL + ELSE + drop + THEN + LOOP + 2drop false + THEN +; + +: try-dos-partition ( -- okay? ) + \ Read partition table and check magic. + no-mbr? IF cr ." No DOS disk-label found." cr false EXIT THEN + + count-dos-logical-partitions TO dos-logical-partitions + + debug-disk-label? IF + ." Found " dos-logical-partitions .d ." logical partitions" cr + ." Partition = " partition .d cr + THEN + + partition 1 5 dos-logical-partitions + + within 0= IF + cr ." Partition # not 1-" 4 dos-logical-partitions + . cr false EXIT + THEN + + \ Could/should check for valid partition here... the magic is not enough really. + + \ Get the partition offset. + + partition find-dos-partition IF + ( offset count active? id ) + 2drop + to part-size + block-size * to part-offset + true + ELSE + false + THEN +; + +\ Check for an ISO-9660 filesystem on the disk +\ : try-iso9660-partition ( -- true|false ) +\ implement me if you can ;-) +\ ; + + +\ Check for an ISO-9660 filesystem on the disk +\ (cf. CHRP IEEE 1275 spec., chapter 11.1.2.3) +: has-iso9660-filesystem ( -- TRUE|FALSE ) + \ Seek to the beginning of logical 2048-byte sector 16 + \ refer to Chapter C.11.1 in PAPR 2.0 Spec + \ was: 10 read-sector, but this might cause trouble if you + \ try booting an ISO image from a device with 512b sectors. + 10 800 * 0 seek drop \ seek to sector + block 800 read drop \ read sector + \ Check for CD-ROM volume magic: + block c@ 1 = + block 1+ 5 s" CD001" str= + and + dup IF 800 to block-size THEN +; + + +\ Load from first active DOS boot partition. + +\ NOTE: block-size is always 512 bytes for DOS partition tables. + +: load-from-dos-boot-partition ( addr -- size ) + no-mbr? IF drop FALSE EXIT THEN \ read MBR and check for DOS disk-label magic + + count-dos-logical-partitions TO dos-logical-partitions + + debug-disk-label? IF + ." Found " dos-logical-partitions .d ." logical partitions" cr + ." Partition = " partition .d cr + THEN + + \ Now walk through the partitions: + 5 dos-logical-partitions + 1 DO + \ ." checking partition " i . + i find-dos-partition IF ( addr offset count active? id ) + 41 = and ( addr offset count prep-boot-part? ) + IF ( addr offset count ) + max-prep-partition-blocks min \ reduce load size + swap ( addr count offset ) + block-size * to part-offset + 0 0 seek drop ( addr offset ) + block-size * read ( size ) + UNLOOP EXIT + ELSE + 2drop ( addr ) + THEN + THEN + LOOP + drop 0 +; + +\ Check for GPT PReP partition GUID +9E1A2D38 CONSTANT GPT-PREP-PARTITION-1 +C612 CONSTANT GPT-PREP-PARTITION-2 +4316 CONSTANT GPT-PREP-PARTITION-3 +AA26 CONSTANT GPT-PREP-PARTITION-4 +8B49521E5A8B CONSTANT GPT-PREP-PARTITION-5 + +: gpt-prep-partition? ( -- true|false ) + block gpt-part-entry>part-type-guid l@-le GPT-PREP-PARTITION-1 = IF + block gpt-part-entry>part-type-guid 4 + w@-le + GPT-PREP-PARTITION-2 = IF + block gpt-part-entry>part-type-guid 6 + w@-le + GPT-PREP-PARTITION-3 = IF + block gpt-part-entry>part-type-guid 8 + w@ + GPT-PREP-PARTITION-4 = IF + block gpt-part-entry>part-type-guid a + w@ + block gpt-part-entry>part-type-guid c + l@ swap lxjoin + GPT-PREP-PARTITION-5 = IF + TRUE EXIT + THEN + THEN + THEN + THEN + THEN + FALSE +; + +: load-from-gpt-prep-partition ( addr -- size ) + no-gpt? IF drop FALSE EXIT THEN + debug-disk-label? IF + cr ." GPT partition found " cr + THEN + 1 read-sector block gpt>part-entry-lba l@-le + block-size * to seek-pos + block gpt>part-entry-size l@-le to gpt-part-size + block gpt>num-part-entry l@-le dup 0= IF FALSE EXIT THEN + 1+ 1 ?DO + seek-pos 0 seek drop + block gpt-part-size read drop gpt-prep-partition? IF + debug-disk-label? IF + ." GPT PReP partition found " cr + THEN + block gpt-part-entry>first-lba x@ xbflip + block gpt-part-entry>last-lba x@ xbflip + over - 1+ ( addr offset len ) + swap ( addr len offset ) + block-size * to part-offset + 0 0 seek drop ( addr len ) + block-size * read ( size ) + UNLOOP EXIT + THEN + seek-pos gpt-part-size i * + to seek-pos + LOOP + FALSE +; + +\ Extract the boot loader path from a bootinfo.txt file +\ In: address and length of buffer where the bootinfo.txt has been loaded to. +\ Out: string address and length of the boot loader (within the input buffer) +\ or a string with length = 0 when parsing failed. + +\ Here is a sample bootinfo file: +\ <chrp-boot> +\ <description>Linux Distribution</description> +\ <os-name>Linux</os-name> +\ <boot-script>boot &device;:1,\boot\yaboot.ibm</boot-script> +\ <icon size=64,64 color-space=3,3,2> +\ <bitmap>[..]</bitmap> +\ </icon> +\ </chrp-boot> + +: parse-bootinfo-txt ( addr len -- str len ) + 2dup s" <boot-script>" find-substr ( addr len pos1 ) + 2dup = IF + \ String not found + 3drop 0 0 EXIT + THEN + dup >r - swap r> + swap ( addr1 len1 ) + + 2dup s" &device;:" find-substr ( addr1 len1 posdev ) + 2dup = IF + 3drop 0 0 EXIT + THEN + 9 + \ Skip the "&device;:" string + dup >r - swap r> + swap ( addr2 len2 ) + 2dup s" </boot-script>" find-substr nip ( addr2 len3 ) + + debug-disk-label? IF + ." Extracted boot loader from bootinfo.txt: '" + 2dup type ." '" cr + THEN +; + +\ Try to load \ppc\bootinfo.txt from the disk (used mainly on CD-ROMs), and if +\ available, get the boot loader path from this file and load it. +\ See the "CHRP system binding to IEEE 1275" specification for more information +\ about bootinfo.txt. An example file can be found in the comment of +\ parse-bootinfo-txt ( addr len -- str len ) + +: load-chrp-boot-file ( addr -- size ) + \ Create bootinfo.txt path name and load that file: + my-parent instance>path + disk-chrp-boot @ 1 = IF + s" :1,\ppc\bootinfo.txt" $cat strdup ( addr str len ) + ELSE + s" :\ppc\bootinfo.txt" $cat strdup ( addr str len ) + THEN + open-dev dup 0= IF 2drop 0 EXIT THEN + >r dup ( addr addr R:ihandle ) + dup s" load" r@ $call-method ( addr addr size R:ihandle ) + r> close-dev ( addr addr size ) + + \ Now parse the information from bootinfo.txt: + parse-bootinfo-txt ( addr fnstr fnlen ) + dup 0= IF 3drop 0 EXIT THEN + \ Does the string contain parameters (i.e. a white space)? + 2dup 20 findchar IF + ( addr fnstr fnlen offset ) + >r 2dup r@ - 1- swap r@ + 1+ swap ( addr fnstr fnlen pstr plen R: offset ) + encode-string s" bootargs" set-chosen + drop r> + THEN + + \ Create the full path to the boot loader: + my-parent instance>path ( addr fnstr fnlen nstr nlen ) + s" :" $cat 2swap $cat strdup ( addr str len ) + \ Update the bootpath: + 2dup encode-string s" bootpath" set-chosen + \ And finally load the boot loader itself: + open-dev dup 0= IF ." failed to load CHRP boot loader." 2drop 0 EXIT THEN + >r s" load" r@ $call-method ( size R:ihandle ) + r> close-dev ( size ) +; + +\ load from a bootable partition +: load-from-boot-partition ( addr -- size ) + debug-disk-label? IF ." Trying DOS boot " .s cr THEN + dup load-from-dos-boot-partition ?dup 0 <> IF nip EXIT THEN + + debug-disk-label? IF ." Trying CHRP boot " .s cr THEN + 1 disk-chrp-boot ! + dup load-chrp-boot-file ?dup 0 <> IF .s cr nip EXIT THEN + 0 disk-chrp-boot ! + + debug-disk-label? IF ." Trying GPT boot " .s cr THEN + load-from-gpt-prep-partition + \ More boot partition formats ... +; + +\ parse partition number from my-args + +\ my-args has the following format +\ [<partition>[,<path>]] + +\ | example my-args | example boot command | +\ +------------------+---------------------------+ +\ | 1,\boot\vmlinuz | boot disk:1,\boot\vmlinuz | +\ | 2 | boot disk:2 | + +\ 0 means the whole disk, this is the same behavior +\ as if no partition is specified (yaboot wants this). + +: parse-partition ( -- okay? ) + 0 to partition + 0 to part-offset + 0 to part-size + + my-args to args-len to args + + debug-disk-label? IF + cr ." disk-label parse-partition: my-args=" my-args type cr + THEN + + \ Called without arguments? + args-len 0 = IF true EXIT THEN + + \ Check for "full disk" arguments. + my-args [char] , findchar 0= IF \ no comma? + args c@ isdigit not IF \ ... and not a partition number? + true EXIT \ ... then it's not a partition we can parse + THEN + ELSE + drop + THEN + my-args [char] , split to args-len to args + dup 0= IF 2drop true EXIT THEN \ no first argument + + \ Check partition #. + base @ >r decimal $number r> base ! + IF cr ." Not a partition #" false EXIT THEN + + \ Store part #, done. + to partition + true +; + + +\ try-files and try-partitions + +: (interpose-filesystem) ( str len -- ) + find-package IF args args-len rot interpose THEN +; + +: try-dos-files ( -- found? ) + no-mbr? IF false EXIT THEN + + \ block 0 byte 0-2 is a jump instruction in all FAT + \ filesystems. + \ e9 and eb are jump instructions in x86 assembler. + block c@ e9 <> IF + block c@ eb <> + block 2+ c@ 90 <> or + IF false EXIT THEN + THEN + s" fat-files" (interpose-filesystem) + true +; + +: try-ext2-files ( -- found? ) + 2 read-sector \ read first superblock + block d# 56 + w@-le \ fetch s_magic + ef53 <> IF false EXIT THEN \ s_magic found? + s" ext2-files" (interpose-filesystem) + true +; + + +: try-iso9660-files + has-iso9660-filesystem 0= IF false exit THEN + s" iso-9660" (interpose-filesystem) + true +; + +: try-files ( -- found? ) + \ If no path, then full disk. + args-len 0= IF true EXIT THEN + + try-dos-files IF true EXIT THEN + try-ext2-files IF true EXIT THEN + try-iso9660-files IF true EXIT THEN + + \ ... more filesystem types here ... + + false +; + +: try-partitions ( -- found? ) + try-dos-partition IF try-files EXIT THEN + \ try-iso9660-partition IF try-files EXIT THEN + \ ... more partition types here... + false +; + +\ Interface functions for disk-label package +\ as defined by IEEE 1275-1994 3.8.1 + +: close ( -- ) + debug-disk-label? IF ." Closing disk-label: block=0x" block u. ." block-size=" block-size .d cr THEN + block d# 4096 free-mem +; + + +: open ( -- true|false ) + init-block + + parse-partition 0= IF + close + false EXIT + THEN + + partition IF + try-partitions + ELSE + try-files + THEN + dup 0= IF debug-disk-label? IF ." not found." cr THEN close THEN \ free memory again +; + + +\ Boot & Load w/o arguments is assumed to be boot from boot partition + +: load ( addr -- size ) + debug-disk-label? IF + ." load: " dup u. cr + THEN + + args-len IF + TRUE ABORT" Load done w/o filesystem" + ELSE + partition IF + 0 0 seek drop + part-size IF + part-size max-prep-partition-blocks min \ Load size + ELSE + max-prep-partition-blocks + THEN + 200 * read + ELSE + has-iso9660-filesystem IF + dup load-chrp-boot-file ?dup 0 > IF nip EXIT THEN + THEN + load-from-boot-partition + dup 0= ABORT" No boot partition found" + THEN + THEN +; diff --git a/qemu/roms/SLOF/slof/fs/packages/ext2-files.fs b/qemu/roms/SLOF/slof/fs/packages/ext2-files.fs new file mode 100644 index 000000000..262c64a34 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/ext2-files.fs @@ -0,0 +1,188 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ +s" ext2-files" device-name + +INSTANCE VARIABLE first-block +INSTANCE VARIABLE inode-size +INSTANCE VARIABLE block-size +INSTANCE VARIABLE inodes/group + +INSTANCE VARIABLE group-desc-size +INSTANCE VARIABLE group-descriptors + +: seek s" seek" $call-parent ; +: read s" read" $call-parent ; + +INSTANCE VARIABLE data +INSTANCE VARIABLE #data +INSTANCE VARIABLE indirect-block +INSTANCE VARIABLE dindirect-block + +: free-data + data @ ?dup IF #data @ free-mem 0 data ! THEN ; +: read-data ( offset size -- ) + free-data dup #data ! alloc-mem data ! + xlsplit seek -2 and ABORT" ext2-files read-data: seek failed" + data @ #data @ read #data @ <> ABORT" ext2-files read-data: read failed" ; + +: read-block ( block# -- ) + block-size @ * block-size @ read-data ; + +INSTANCE VARIABLE inode +INSTANCE VARIABLE file-len +INSTANCE VARIABLE blocks +INSTANCE VARIABLE #blocks +INSTANCE VARIABLE ^blocks +INSTANCE VARIABLE #blocks-left +: blocks-read ( n -- ) dup negate #blocks-left +! 4 * ^blocks +! ; +: read-indirect-blocks ( indirect-block# -- ) + read-block data @ data off + dup #blocks-left @ 4 * block-size @ min dup >r ^blocks @ swap move + r> 2 rshift blocks-read block-size @ free-mem ; + +: read-double-indirect-blocks ( double-indirect-block# -- ) + \ Resolve one level of indirection and call read-indirect-block + read-block data @ indirect-block ! data off + BEGIN + indirect-block @ l@-le dup 0 <> + WHILE + read-indirect-blocks + 4 indirect-block +! \ point to next indirect block + REPEAT + drop \ drop 0, the invalid block number +; + +: read-triple-indirect-blocks ( triple-indirect-block# -- ) + \ Resolve one level of indirection and call double-indirect-block + read-block data @ dindirect-block ! data off + BEGIN + dindirect-block @ l@-le dup 0 <> + WHILE + read-double-indirect-blocks + 4 dindirect-block +! \ point to next double indirect block + REPEAT + drop \ drop 0, the invalid block number +; + +: read-block#s ( -- ) + blocks @ ?dup IF #blocks @ 4 * free-mem THEN + inode @ 4 + l@-le file-len ! + file-len @ block-size @ // #blocks ! + #blocks @ 4 * alloc-mem blocks ! + blocks @ ^blocks ! #blocks @ #blocks-left ! + #blocks-left @ c min \ # direct blocks + inode @ 28 + over 4 * ^blocks @ swap move blocks-read + #blocks-left @ IF inode @ 58 + l@-le read-indirect-blocks THEN + #blocks-left @ IF inode @ 5c + l@-le read-double-indirect-blocks THEN + #blocks-left @ IF inode @ 60 + l@-le read-triple-indirect-blocks THEN ; +: read-inode ( inode# -- ) + 1- inodes/group @ u/mod \ # in group, group # + 20 * group-descriptors @ + 8 + l@-le block-size @ * \ # in group, inode table + swap inode-size @ * + xlsplit seek drop inode @ inode-size @ read drop +; + +: .rwx ( bits last-char-if-special special? -- ) + rot dup 4 and IF ." r" ELSE ." -" THEN + dup 2 and IF ." w" ELSE ." -" THEN + swap IF 1 and 0= IF upc THEN emit ELSE + 1 and IF ." x" ELSE ." -" THEN drop THEN ; +CREATE mode-chars 10 allot s" ?pc?d?b?-?l?s???" mode-chars swap move +: .mode ( mode -- ) + dup c rshift f and mode-chars + c@ emit + dup 6 rshift 7 and over 800 and 73 swap .rwx + dup 3 rshift 7 and over 400 and 73 swap .rwx + dup 7 and swap 200 and 74 swap .rwx ; +: .inode ( -- ) + base @ >r decimal + inode @ w@-le .mode \ file mode + inode @ 1a + w@-le 5 .r \ link count + inode @ 02 + w@-le 9 .r \ uid + inode @ 18 + w@-le 9 .r \ gid + inode @ 04 + l@-le 9 .r \ size + r> base ! ; + +: do-super ( -- ) + 400 400 read-data + data @ 14 + l@-le first-block ! + 400 data @ 18 + l@-le lshift block-size ! + data @ 28 + l@-le inodes/group ! + \ Check revision level... in revision 0, the inode size is always 128 + data @ 4c + l@-le 0= IF + 80 inode-size ! + ELSE + data @ 58 + w@-le inode-size ! + THEN + data @ 20 + l@-le group-desc-size ! + + \ Read the group descriptor table: + first-block @ 1+ block-size @ * + group-desc-size @ + read-data + data @ group-descriptors ! + + \ We keep the group-descriptor memory area, so clear data pointer: + data off +; + +INSTANCE VARIABLE current-pos + +: read ( adr len -- actual ) + file-len @ current-pos @ - min \ can't go past end of file + current-pos @ block-size @ u/mod 4 * blocks @ + l@-le read-block + block-size @ over - rot min >r ( adr off r: len ) + data @ + swap r@ move r> dup current-pos +! ; +: read ( adr len -- actual ) + ( check if a file is selected, first ) + dup >r BEGIN dup WHILE 2dup read dup 0= ABORT" ext2-files: read failed" + /string REPEAT 2drop r> ; +: seek ( lo hi -- status ) + lxjoin dup file-len @ > IF drop true EXIT THEN current-pos ! false ; +: load ( adr -- len ) + file-len @ read dup file-len @ <> ABORT" ext2-files: failed loading file" ; + +: .name ( adr -- ) dup 8 + swap 6 + c@ type ; +: read-dir ( inode# -- adr ) + read-inode read-block#s file-len @ alloc-mem + 0 0 seek ABORT" ext2-files read-dir: seek failed" + dup file-len @ read file-len @ <> ABORT" ext2-files read-dir: read failed" ; +: .dir ( inode# -- ) + read-dir dup BEGIN 2dup file-len @ - > over l@-le tuck and WHILE + cr dup 8 0.r space read-inode .inode space space dup .name + dup 4 + w@-le + REPEAT 2drop file-len @ free-mem ; +: (find-file) ( adr name len -- inode#|0 ) + 2>r dup BEGIN 2dup file-len @ - > over l@-le and WHILE + dup 8 + over 6 + c@ 2r@ str= IF 2r> 2drop nip l@-le EXIT THEN + dup 4 + w@-le + REPEAT 2drop 2r> 2drop 0 ; +: find-file ( inode# name len -- inode#|0 ) + 2>r read-dir dup 2r> (find-file) swap file-len @ free-mem ; +: find-path ( inode# name len -- inode#|0 ) + dup 0= IF 3drop 0 ." empty name " EXIT THEN + over c@ [char] \ = IF 1 /string ." slash " RECURSE EXIT THEN + [char] \ split 2>r find-file ?dup 0= IF + 2r> 2drop false ." not found " EXIT THEN + r@ 0<> IF 2r> ." more... " RECURSE EXIT THEN + 2r> 2drop ." got it " ; + +: close + inode @ inode-size @ free-mem + group-descriptors @ group-desc-size @ free-mem + free-data + blocks @ ?dup IF #blocks @ 4 * free-mem THEN +; + +: open + 0 data ! 0 blocks ! 0 #blocks ! + do-super + inode-size @ alloc-mem inode ! + my-args nip 0= IF 0 0 ELSE + 2 my-args find-path ?dup 0= IF close false EXIT THEN THEN + read-inode read-block#s 0 0 seek 0= ; diff --git a/qemu/roms/SLOF/slof/fs/packages/fat-files.fs b/qemu/roms/SLOF/slof/fs/packages/fat-files.fs new file mode 100644 index 000000000..0cec3664e --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/fat-files.fs @@ -0,0 +1,188 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +s" fat-files" device-name + +INSTANCE VARIABLE bytes/sector +INSTANCE VARIABLE sectors/cluster +INSTANCE VARIABLE #reserved-sectors +INSTANCE VARIABLE #fats +INSTANCE VARIABLE #root-entries +INSTANCE VARIABLE total-#sectors +INSTANCE VARIABLE media-descriptor +INSTANCE VARIABLE sectors/fat +INSTANCE VARIABLE sectors/track +INSTANCE VARIABLE #heads +INSTANCE VARIABLE #hidden-sectors + +INSTANCE VARIABLE fat-type +INSTANCE VARIABLE bytes/cluster +INSTANCE VARIABLE fat-offset +INSTANCE VARIABLE root-offset +INSTANCE VARIABLE cluster-offset +INSTANCE VARIABLE #clusters + +: seek s" seek" $call-parent ; +: read s" read" $call-parent ; + +INSTANCE VARIABLE data +INSTANCE VARIABLE #data + +: free-data + data @ ?dup IF #data @ free-mem 0 data ! THEN ; +: read-data ( offset size -- ) + free-data dup #data ! alloc-mem data ! + xlsplit seek -2 and ABORT" fat-files read-data: seek failed" + data @ #data @ read #data @ <> ABORT" fat-files read-data: read failed" ; + +CREATE fat-buf 8 allot +: read-fat ( cluster# -- data ) + fat-buf 8 erase + 1 #split fat-type @ * 2/ 2/ fat-offset @ + + xlsplit seek -2 and ABORT" fat-files read-fat: seek failed" + fat-buf 8 read 8 <> ABORT" fat-files read-fat: read failed" + fat-buf 8c@ bxjoin fat-type @ dup >r 2* #split drop r> #split + rot IF swap THEN drop ; + +INSTANCE VARIABLE next-cluster + +: read-cluster ( cluster# -- ) + dup bytes/cluster @ * cluster-offset @ + bytes/cluster @ read-data + read-fat dup #clusters @ >= IF drop 0 THEN next-cluster ! ; +: read-dir ( cluster# -- ) + ?dup 0= IF root-offset @ #root-entries @ 20 * read-data 0 next-cluster ! + ELSE read-cluster THEN ; + +: .time ( x -- ) + base @ >r decimal + b #split 2 0.r [char] : emit 5 #split 2 0.r [char] : emit 2* 2 0.r + r> base ! ; +: .date ( x -- ) + base @ >r decimal + 9 #split 7bc + 4 0.r [char] - emit 5 #split 2 0.r [char] - emit 2 0.r + r> base ! ; +: .attr ( attr -- ) + 6 0 DO dup 1 and IF s" RHSLDA" drop i + c@ ELSE bl THEN emit u2/ LOOP drop ; +: .dir-entry ( adr -- ) + dup 0b + c@ 8 and IF drop EXIT THEN \ volume label, not a file + dup c@ e5 = IF drop EXIT THEN \ deleted file + cr + dup 1a + 2c@ bwjoin [char] # emit 4 0.r space \ starting cluster + dup 18 + 2c@ bwjoin .date space + dup 16 + 2c@ bwjoin .time space + dup 1c + 4c@ bljoin base @ decimal swap a .r base ! space \ size in bytes + dup 0b + c@ .attr space + dup 8 BEGIN 2dup 1- + c@ 20 = over and WHILE 1- REPEAT type + dup 8 + 3 BEGIN 2dup 1- + c@ 20 = over and WHILE 1- REPEAT dup IF + [char] . emit type ELSE 2drop THEN + drop ; +: .dir-entries ( adr n -- ) + 0 ?DO dup i 20 * + dup c@ 0= IF drop LEAVE THEN .dir-entry LOOP drop ; +: .dir ( cluster# -- ) + read-dir BEGIN data @ #data @ 20 / .dir-entries next-cluster @ WHILE + next-cluster @ read-cluster REPEAT ; + +: str-upper ( str len adr -- ) \ Copy string to adr, uppercase + -rot bounds ?DO i c@ upc over c! char+ LOOP drop ; +CREATE dos-name b allot +: make-dos-name ( str len -- ) + dos-name b bl fill + 2dup [char] . findchar IF + 3dup 1+ /string 3 min dos-name 8 + str-upper nip THEN + 8 min dos-name str-upper ; + +: (find-file) ( -- cluster file-len is-dir? true | false ) + data @ BEGIN dup data @ #data @ + < WHILE + dup dos-name b comp WHILE 20 + REPEAT + dup 1a + 2c@ bwjoin swap dup 1c + 4c@ bljoin swap 0b + c@ 10 and 0<> true + ELSE drop false THEN ; +: find-file ( dir-cluster name len -- cluster file-len is-dir? true | false ) + make-dos-name read-dir BEGIN (find-file) 0= WHILE next-cluster @ WHILE + next-cluster @ read-cluster REPEAT false ELSE true THEN ; +: find-path ( dir-cluster name len -- cluster file-len true | false ) + dup 0= IF 3drop false ." empty name " EXIT THEN + over c@ [char] \ = IF 1 /string RECURSE EXIT THEN + [char] \ split 2>r find-file 0= IF 2r> 2drop false ." not found " EXIT THEN + r@ 0<> <> IF 2drop 2r> 2drop false ." no dir<->file match " EXIT THEN + r@ 0<> IF drop 2r> RECURSE EXIT THEN + 2r> 2drop true ; + +: do-super ( -- ) + 0 200 read-data + data @ 0b + 2c@ bwjoin bytes/sector ! + data @ 0d + c@ sectors/cluster ! + bytes/sector @ sectors/cluster @ * bytes/cluster ! + data @ 0e + 2c@ bwjoin #reserved-sectors ! + data @ 10 + c@ #fats ! + data @ 11 + 2c@ bwjoin #root-entries ! + data @ 13 + 2c@ bwjoin total-#sectors ! + data @ 15 + c@ media-descriptor ! + data @ 16 + 2c@ bwjoin sectors/fat ! + data @ 18 + 2c@ bwjoin sectors/track ! + data @ 1a + 2c@ bwjoin #heads ! + data @ 1c + 2c@ bwjoin #hidden-sectors ! + + \ For FAT16 and FAT32: + total-#sectors @ 0= IF data @ 20 + 4c@ bljoin total-#sectors ! THEN + + \ For FAT32: + sectors/fat @ 0= IF data @ 24 + 4c@ bljoin sectors/fat ! THEN + + \ XXX add other FAT32 stuff (offsets 28, 2c, 30) + + \ Compute the number of data clusters, decide what FAT type we are. + total-#sectors @ #reserved-sectors @ - sectors/fat @ #fats @ * - + #root-entries @ 20 * bytes/sector @ // - sectors/cluster @ / + dup #clusters ! + dup ff5 < IF drop c ELSE fff5 < IF 10 ELSE 20 THEN THEN fat-type ! + base @ decimal base ! + + \ Starting offset of first fat. + #reserved-sectors @ bytes/sector @ * fat-offset ! + + \ Starting offset of root dir. + #fats @ sectors/fat @ * bytes/sector @ * fat-offset @ + root-offset ! + + \ Starting offset of "cluster 0". + #root-entries @ 20 * bytes/sector @ tuck // * root-offset @ + + bytes/cluster @ 2* - cluster-offset ! ; + + +INSTANCE VARIABLE file-cluster +INSTANCE VARIABLE file-len +INSTANCE VARIABLE current-pos +INSTANCE VARIABLE pos-in-data + +: seek ( lo hi -- status ) + lxjoin dup current-pos ! file-cluster @ read-cluster + \ Read and skip blocks until we are where we want to be. + BEGIN dup #data @ >= WHILE #data @ - next-cluster @ dup 0= IF + 2drop true EXIT THEN read-cluster REPEAT pos-in-data ! false ; +: read ( adr len -- actual ) + file-len @ current-pos @ - min \ can't go past end of file + #data @ pos-in-data @ - min >r \ length for this transfer + data @ pos-in-data @ + swap r@ move \ move the data + r@ pos-in-data +! r@ current-pos +! pos-in-data @ #data @ = IF + next-cluster @ ?dup IF read-cluster 0 pos-in-data ! THEN THEN r> ; +: read ( adr len -- actual ) + file-len @ min \ len cannot be greater than file size + dup >r BEGIN dup WHILE 2dup read dup 0= ABORT" fat-files: read failed" + /string ( tuck - >r + r> ) REPEAT 2drop r> ; +: load ( adr -- len ) + file-len @ read dup file-len @ <> ABORT" fat-files: failed loading file" ; + +: close free-data ; +: open + do-super + 0 my-args find-path 0= IF close false EXIT THEN + file-len ! file-cluster ! 0 0 seek 0= ; diff --git a/qemu/roms/SLOF/slof/fs/packages/filler.fs b/qemu/roms/SLOF/slof/fs/packages/filler.fs new file mode 100644 index 000000000..bd5c17a39 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/filler.fs @@ -0,0 +1,21 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +s" filler" device-name + +: block-size s" block-size" $call-parent ; +: seek s" seek" $call-parent ; +: read s" read" $call-parent ; + +: open true ; +: close ; diff --git a/qemu/roms/SLOF/slof/fs/packages/iso-9660.fs b/qemu/roms/SLOF/slof/fs/packages/iso-9660.fs new file mode 100644 index 000000000..6eda8be70 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/iso-9660.fs @@ -0,0 +1,325 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +s" iso-9660" device-name + + +0 VALUE iso-debug-flag + +\ Method for code clean up - For release version of code iso-debug-flag is +\ cleared and for debugging it is set + +: iso-debug-print ( str len -- ) iso-debug-flag IF type cr ELSE 2drop THEN ; + + +\ -------------------------------------------------------- +\ GLOBAL VARIABLES +\ -------------------------------------------------------- + + +0 VALUE path-tbl-size +0 VALUE path-tbl-addr +0 VALUE root-dir-size +0 VALUE vol-size +0 VALUE logical-blk-size +0 VALUE path-table +0 VALUE count + + +\ INSTANCE VARIABLES + + +INSTANCE VARIABLE dir-addr +INSTANCE VARIABLE data-buff +INSTANCE VARIABLE #data +INSTANCE VARIABLE ptable +INSTANCE VARIABLE file-loc +INSTANCE VARIABLE file-size +INSTANCE VARIABLE cur-file-offset +INSTANCE VARIABLE self +INSTANCE VARIABLE index + + +\ -------------------------------------------------------- +\ COLON DEFINITIONS +\ -------------------------------------------------------- + + +\ This method is used to seek to the required position +\ Which calls seek of disk-label + +: seek ( pos.lo pos.hi -- status ) s" seek" $call-parent ; + + +\ This method is used to read the contents of disk +\ it calls read of disk-label + + + : read ( addr len -- actual ) s" read" $call-parent ; + + +\ This method releases the memory used as scratch pad buffer. + +: free-data ( -- ) + data-buff @ ( data-buff ) + ?DUP IF #data @ free-mem 0 data-buff ! 0 #data ! THEN +; + + +\ This method will release the previous allocated scratch pad buffer and +\ allocates a fresh buffer and copies the required number of bytes from the +\ media in to it. + +: read-data ( offset size -- ) + dup #data @ > IF + free-data dup dup ( offset size size size ) + #data ! alloc-mem data-buff ! ( offset size ) + THEN + swap xlsplit ( size pos.lo pos.hi ) + seek -2 and ABORT" seek failed." + data-buff @ over read ( size actual ) + <> ABORT" read failed." +; + + +\ This method extracts the information required from primary volume +\ descriptor and stores the required information in the global variables + +: extract-vol-info ( -- ) + 10 800 * 800 read-data + data-buff @ 88 + l@-be to path-tbl-size \ read path table size + data-buff @ 94 + l@-be to path-tbl-addr \ read big-endian path table + data-buff @ a2 + l@-be dir-addr ! \ gather of root directory info + data-buff @ 0aa + l@-be to root-dir-size \ get volume info + data-buff @ 54 + l@-be to vol-size \ size in blocks + data-buff @ 82 + l@-be to logical-blk-size + path-tbl-size alloc-mem dup TO path-table path-tbl-size erase + path-tbl-addr 800 * xlsplit seek drop + path-table path-tbl-size read drop \ pathtable in-system-memory copy +; + + +\ This method coverts the iso file name to user readble form + +: file-name ( str len -- str' len' ) + 2dup [char] ; findchar IF + ( str len offset ) + nip \ Omit the trailing ";1" revision of ISO9660 file name + 2dup + 1- ( str newlen endptr ) + c@ [CHAR] . = IF + 1- ( str len' ) \ Remove trailing dot + THEN + THEN +; + + +\ triplicates top stack element + +: dup3 ( num -- num num num ) dup dup dup ; + + +\ This method is used for traversing records of path table. If the +\ file identifier length is odd 1 byte padding is done else not. + +: get-next-record ( rec-addr -- next-rec-offset ) + dup3 ( rec-addr rec-addr rec-addr rec-addr ) + self @ 1 + self ! ( rec-addr rec-addr rec-addr rec-addr ) + c@ 1 AND IF ( rec-addr rec-addr rec-addr ) + c@ + 9 ( rec-addr rec-addr' rec-len ) + ELSE + c@ + 8 ( rec-addr rec-addr' rec-len ) + THEN + + swap - ( next-rec-offset ) +; + + +\ This method does search of given directory name in the path table +\ and returns true if finds a match else false. + +: path-table-search ( str len -- TRUE | FALSE ) + path-table path-tbl-size + path-table ptable @ + DO ( str len ) + 2dup I 6 + w@-be index @ = ( str len str len ) + -rot I 8 + I c@ + iso-debug-flag IF + ." ISO: comparing path name '" + 4dup type ." ' with '" type ." '" cr + THEN + string=ci and IF ( str len ) + s" Directory Matched!! " iso-debug-print ( str len ) + self @ index ! ( str len ) + I 2 + l@-be dir-addr ! I dup ( str len rec-addr ) + get-next-record + path-table - ptable ! ( str len ) + 2drop TRUE UNLOOP EXIT ( TRUE ) + THEN + I get-next-record ( str len next-rec-offset ) + +LOOP + 2drop + FALSE ( FALSE ) + s" Invalid path / directory " iso-debug-print +; + + +\ METHOD for searching for a file with in a direcotory + +: search-file-dir ( str len -- TRUE | FALSE ) + dir-addr @ 800 * dir-addr ! ( str len ) + dir-addr @ 100 read-data ( str len ) + data-buff @ 0e + l@-be dup >r ( str len rec-len ) + 100 > IF ( str len ) + s" size dir record" iso-debug-print ( str len ) + dir-addr @ r@ read-data ( str len ) + THEN + r> data-buff @ + data-buff @ DO ( str len ) + I 19 + c@ 2 and 0= I c@ 0<> and IF ( str len ) + 2dup ( str len str len ) + I 21 + I 20 + c@ ( str len str len str' len' ) + iso-debug-flag IF + ." ISO: comparing file name '" + 4dup type ." ' with '" type ." '" cr + THEN + file-name string=ci IF ( str len ) + s" File found!" iso-debug-print ( str len ) + I 6 + l@-be 800 * ( str len file-loc ) + file-loc ! ( str len ) + I 0e + l@-be file-size ! ( str len ) + 2drop + TRUE ( TRUE ) + UNLOOP + EXIT + THEN + THEN + ( str len ) + I c@ ?dup 0= IF + 800 I 7ff AND - + iso-debug-flag IF + ." skipping " dup . ." bytes at end of sector" cr + THEN + THEN + ( str len offset ) + +LOOP + 2drop + FALSE ( FALSE ) + s" file not found" iso-debug-print +; + + +\ This method splits the given absolute path in to directories from root and +\ calls search-path-table. when string reaches to state when it can not be +\ split i.e., end of the path, calls search-file-dir is made to search for +\ file . + +: search-path ( str len -- FALSE|TRUE ) + 0 ptable ! + 1 self ! + 1 index ! + dup ( str len len ) + 0= IF + 3drop FALSE ( FALSE ) + s" Empty path name " iso-debug-print EXIT ( FALSE ) + THEN + OVER c@ ( str len char ) + [char] \ = IF ( str len ) + swap 1 + swap 1 - BEGIN ( str len ) + [char] \ split ( str len str' len ' ) + dup 0 = IF ( str len str' len ' ) + 2drop search-file-dir EXIT ( TRUE | FALSE ) + ELSE + 2swap path-table-search invert IF ( str' len ' ) + 2drop FALSE EXIT ( FALSE ) + THEN + THEN + AGAIN + ELSE BEGIN + [char] \ split dup 0 = IF ( str len str' len' ) + 2drop search-file-dir EXIT ( TRUE | FALSE ) + ELSE + 2swap path-table-search invert IF ( str' len ' ) + 2drop FALSE EXIT ( FALSE ) + THEN + THEN + AGAIN + THEN +; + + +\ this method will seek and read the file in to the given memory location + +0 VALUE loc +: load ( addr -- len ) + dup to loc ( addr ) + file-loc @ xlsplit seek drop + file-size @ read ( file-size ) + iso-debug-flag IF s" Bytes returned from read:" type dup . cr THEN + dup file-size @ <> ABORT" read failed!" +; + + + +\ memory used by the file system will be freed + +: close ( -- ) + free-data count 1 - dup to count 0 = IF + path-table path-tbl-size free-mem + 0 TO path-table + THEN +; + + +\ open method of the file system + +: open ( -- TRUE | FALSE ) + 0 data-buff ! + 0 #data ! + 0 ptable ! + 0 file-loc ! + 0 file-size ! + 0 cur-file-offset ! + 1 self ! + 1 index ! + count 0 = IF + s" extract-vol-info called " iso-debug-print + extract-vol-info + THEN + count 1 + to count + my-args search-path IF + file-loc @ xlsplit seek drop + TRUE ( TRUE ) + ELSE + close + FALSE ( FALSE ) + THEN + 0 cur-file-offset ! + s" opened ISO9660 package" iso-debug-print +; + + +\ public seek method + +: seek ( pos.lo pos.hi -- status ) + lxjoin dup cur-file-offset ! ( offset ) + file-loc @ + xlsplit ( pos.lo pos.hi ) + s" seek" $call-parent ( status ) +; + + +\ public read method + + : read ( addr len -- actual ) + file-size @ cur-file-offset @ - ( addr len remainder-of-file ) + min ( addr len|remainder-of-file ) + s" read" $call-parent ( actual ) + dup cur-file-offset @ + cur-file-offset ! ( actual ) + cur-file-offset @ ( offset actual ) + xlsplit seek drop ( actual ) +; + diff --git a/qemu/roms/SLOF/slof/fs/packages/obp-tftp.fs b/qemu/roms/SLOF/slof/fs/packages/obp-tftp.fs new file mode 100644 index 000000000..89143a669 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/obp-tftp.fs @@ -0,0 +1,71 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +s" obp-tftp" device-name + +INSTANCE VARIABLE ciregs-buffer + +: open ( -- okay? ) + ciregs-size alloc-mem ciregs-buffer ! + true +; + +: load ( addr -- size ) + + \ Save old client interface register + ciregs ciregs-buffer @ ciregs-size move + + s" bootargs" get-chosen 0= IF 0 0 THEN >r >r + s" bootpath" get-chosen 0= IF 0 0 THEN >r >r + + \ Set bootpath to current device + my-parent ihandle>phandle node>path encode-string + s" bootpath" set-chosen + + \ Generate arg string for snk like + \ "netboot load-addr length filename" + (u.) s" netboot " 2swap $cat s" 60000000 " $cat + + \ Allocate 1720 bytes to store the BOOTP-REPLY packet + 6B8 alloc-mem dup >r (u.) $cat s" " $cat + huge-tftp-load @ IF s" 1 " ELSE s" 0 " THEN $cat + \ Add desired TFTP-Blocksize as additional argument + s" 1432 " $cat + \ Add OBP-TFTP Bootstring argument, e.g. "10.128.0.1,bootrom.bin,10.128.40.1" + my-args $cat + + \ Call SNK netboot loadr + (client-exec) dup 0< IF drop 0 THEN + + \ Restore to old client interface register + ciregs-buffer @ ciregs ciregs-size move + + \ Recover buffer address of BOOTP-REPLY packet + r> + + r> r> over IF s" bootpath" set-chosen ELSE 2drop THEN + r> r> over IF s" bootargs" set-chosen ELSE 2drop THEN + + \ Store BOOTP-REPLY packet as property + dup 6B8 encode-bytes s" bootp-response" s" /chosen" find-node set-property + + \ free buffer + 6B8 free-mem +; + +: close ( -- ) + ciregs-buffer @ ciregs-size free-mem +; + +: ping ( -- ) + s" ping " my-args $cat (client-exec) +; diff --git a/qemu/roms/SLOF/slof/fs/packages/rom-files.fs b/qemu/roms/SLOF/slof/fs/packages/rom-files.fs new file mode 100644 index 000000000..418cf4e05 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/rom-files.fs @@ -0,0 +1,85 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +\ package which adds support to read the romfs +\ this package is somehow limited as the maximum supported length +\ for a file name is hardcoded to 0x100 + +s" rom-files" device-name + +INSTANCE VARIABLE length +INSTANCE VARIABLE next-file +INSTANCE VARIABLE buffer +INSTANCE VARIABLE buffer-size +INSTANCE VARIABLE file +INSTANCE VARIABLE file-size +INSTANCE VARIABLE found + +: open true + 100 dup buffer-size ! alloc-mem buffer ! false found ! ; +: close buffer @ buffer-size @ free-mem ; + +: read ( addr len -- actual ) s" read" $call-parent ; + +: seek ( lo hi -- status ) s" seek" $call-parent ; + +: .read-file-name ( offset -- str len ) + \ move to the file name offset + 0 seek drop + \ read <buffer-size> bytes from that address + buffer @ buffer-size @ read drop + \ write a 0 to make sure it is a 0 terminated string + buffer-size @ 1 - buffer @ + 0 swap c! + buffer @ zcount ; + +: .print-info ( offset -- ) + dup 2 spaces 6 0.r 2 spaces dup + 8 + 0 seek drop length 8 read drop + 6 length @ swap 0.r 2 spaces + 20 + .read-file-name type cr ; + +: .list-header cr + s" --offset---size-----file-name----" type cr ; + +: list + .list-header + 0 0 BEGIN + dup + .print-info dup 0 seek drop + next-file 8 read drop next-file @ + dup 0= UNTIL 2drop ; + +: (find-file) ( name len -- offset | -1 ) + 0 0 seek drop false found ! + file-size ! file ! 0 0 BEGIN + dup + 20 + .read-file-name file @ file-size @ + str= IF true found ! THEN + dup 0 seek drop + next-file 8 read drop next-file @ + dup 0= found @ or UNTIL drop found @ 0= + IF drop -1 THEN ; + +: load ( addr -- size ) + my-parent instance>args 2@ [char] \ left-parse-string 2drop + (find-file) dup -1 = IF 2drop 0 ELSE + \ got to the beginning + 0 0 seek drop + \ read the file size + dup 8 + 0 seek drop + here 8 read drop here @ ( dest-addr offset file-size ) + \ read data start offset + over 18 + 0 seek drop + here 8 read drop here @ ( dest-addr offset file-size data-offset ) + rot + 0 seek drop ( dest-addr file-size ) + read + THEN +; diff --git a/qemu/roms/SLOF/slof/fs/packages/sms.fs b/qemu/roms/SLOF/slof/fs/packages/sms.fs new file mode 100644 index 000000000..d8c672f72 --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/packages/sms.fs @@ -0,0 +1,29 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2008 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + + +s" /packages" find-device + +new-device + s" sms" device-name + + : open true ; + + : close ; + + \ The rest of methods is loaded dynamically from the romfs + \ on a first call to sms-start + +finish-device + +device-end \ leave /packages + |