summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2015-06-29 08:54:07 +0300
committerRichard Lowe <richlowe@richlowe.net>2015-07-14 11:59:27 -0400
commit8a9764c34ea643308eed074c3fef1579dabe8461 (patch)
tree4992aefcd649e57113ec0d51ca6285ac64385f07 /usr
parentc0dbe950192897247de6003f2dea1ca3c466fe01 (diff)
downloadillumos-joyent-8a9764c34ea643308eed074c3fef1579dabe8461.tar.gz
6041 SPARC boot should support LZ4
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr')
-rwxr-xr-xusr/src/psm/stand/bootblks/common/mkbb.sh8
-rw-r--r--usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth2
-rw-r--r--usr/src/psm/stand/bootblks/zfs/common/zfs.fth274
3 files changed, 273 insertions, 11 deletions
diff --git a/usr/src/psm/stand/bootblks/common/mkbb.sh b/usr/src/psm/stand/bootblks/common/mkbb.sh
index d5d395d1fd..115126ed1e 100755
--- a/usr/src/psm/stand/bootblks/common/mkbb.sh
+++ b/usr/src/psm/stand/bootblks/common/mkbb.sh
@@ -23,10 +23,6 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-
-#!/bin/sh
# defaults
bblen=7680
@@ -75,8 +71,8 @@ dd if=$2 of=$3 conv=notrunc bs=1 oseek=$rdoff
#
if [ $totlen -gt $bblen ]; then
extsize=$(ls -l $extra | awk -e '{ print $5 }')
- if [ $extsize -gt 8192 ]; then
- printf "$1 must be smaller than 8k\n"
+ if [ $extsize -gt 16384 ]; then
+ printf "$1 must be smaller than 16k\n"
exit -1
fi
dd if=$extra of=$3 conv=notrunc bs=1 oseek=$bblen
diff --git a/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth
index 2b3f5dd2d6..41a614432b 100644
--- a/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth
+++ b/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth
@@ -29,7 +29,7 @@ copyright: Copyright 2009 Sun Microsystems, Inc. All Rights Reserved
\ big bootblk
create bigbootblk
-d# 8192 constant /fs-fcode
+d# 16384 constant /fs-fcode
\ Set the offset to the correct zfs boot block area. This area is at offset 512K
d# 512 d# 1024 * constant fs-offset
diff --git a/usr/src/psm/stand/bootblks/zfs/common/zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/zfs.fth
index 2c6c80f6ca..569a845f08 100644
--- a/usr/src/psm/stand/bootblks/zfs/common/zfs.fth
+++ b/usr/src/psm/stand/bootblks/zfs/common/zfs.fth
@@ -22,6 +22,7 @@
\ Copyright 2010 Sun Microsystems, Inc. All rights reserved.
\ Use is subject to license terms.
\
+\ Copyright 2015 Toomas Soome <tsoome@me.com>
purpose: ZFS file system support package
@@ -159,6 +160,259 @@ new-device
2drop 2drop r> drop ( )
;
+ \ decode lz4 buffer header, returns src addr and len
+ : lz4_sbuf ( addr -- s_addr s_len )
+ dup C@ 8 lshift swap 1+ ( byte0 addr++ )
+ dup C@ ( byte0 addr byte1 )
+ rot ( addr byte1 byte0 )
+ or d# 16 lshift swap 1+ ( d addr++ )
+
+ dup C@ 8 lshift ( d addr byte2 )
+ swap 1+ ( d byte2 addr++ )
+ dup C@ swap 1+ ( d byte2 byte3 addr++ )
+ -rot ( d s_addr byte2 byte3 )
+ or ( d s_addr d' )
+ rot ( s_addr d' d )
+ or ( s_addr s_len )
+ ;
+
+ 4 constant STEPSIZE
+ 8 constant COPYLENGTH
+ 5 constant LASTLITERALS
+ 4 constant ML_BITS
+ d# 15 constant ML_MASK \ (1<<ML_BITS)-1
+ 4 constant RUN_BITS \ 8 - ML_BITS
+ d# 15 constant RUN_MASK \ (1<<RUN_BITS)-1
+
+ \ A32(d) = A32(s); d+=4; s+=4
+ : lz4_copystep ( dest source -- dest' source')
+ 2dup swap 4 move
+ swap 4 +
+ swap 4 + ( dest+4 source+4 )
+ ;
+
+ \ do { LZ4_COPYPACKET(s, d) } while (d < e);
+ : lz4_copy ( e d s -- e d' s' )
+ begin ( e d s )
+ lz4_copystep
+ lz4_copystep ( e d s )
+ over ( e d s d )
+ 3 pick < 0=
+ until
+ ;
+
+ \ lz4 decompress translation from C code
+ \ could use some factorisation
+ : lz4 ( src dest len -- )
+ swap dup >r swap \ save original dest to return stack.
+ rot ( dest len src )
+ lz4_sbuf ( dest len s_buf s_len )
+ over + ( dest len s_buf s_end )
+ 2swap ( s_buf s_end dest len )
+ over + ( s_buf s_end dest dest_end )
+ 2swap ( dest dest_end s_buf s_end )
+
+ \ main loop
+ begin 2dup < while
+ swap dup C@ ( dest dest_end s_end s_buf token )
+ swap CHAR+ swap ( dest dest_end s_end s_buf++ token )
+ dup ML_BITS rshift ( dest dest_end s_end s_buf token length )
+ >r rot rot r> ( dest dest_end token s_end s_buf length )
+ dup RUN_MASK = if
+ d# 255 begin ( dest dest_end token s_end s_buf length s )
+ swap ( dest dest_end token s_end s_buf s length )
+ >r >r ( ... R: length s )
+ 2dup > ( dest dest_end token s_end s_buf flag )
+ r@ d# 255 = and ( dest dest_end token s_end s_buf flag R: length s )
+ r> swap r> swap ( dest dest_end token s_end s_buf s length flag )
+ >r swap r> ( dest dest_end token s_end s_buf length s flag )
+ while
+ drop >r ( dest dest_end token s_end s_buf R: length )
+ dup c@ swap CHAR+ ( dest dest_end token s_end s s_buf++ )
+ swap ( dest dest_end token s_end s_buf s )
+ dup ( dest dest_end token s_end s_buf s s )
+ r> + swap ( dest dest_end token s_end s_buf length s )
+ repeat
+ drop ( dest dest_end token s_end s_buf length )
+ then
+
+ -rot ( dest dest_end token length s_end s_buf )
+ swap >r >r ( dest dest_end token length R: s_end s_buf )
+ swap >r ( dest dest_end length R: s_end s_buf token )
+ rot ( dest_end length dest )
+ 2dup + ( dest_end length dest cpy )
+
+ 2dup > if ( dest > cpy )
+ " lz4 overflow" die
+ then
+
+ 3 pick COPYLENGTH - over < ( dest_end length dest cpy flag )
+ 3 pick ( dest_end length dest cpy flag length )
+ r> ( dest_end length dest cpy flag length token )
+ r> ( dest_end length dest cpy flag length token s_buf R: s_end )
+ rot ( dest_end length dest cpy flag token s_buf length )
+ over + ( dest_end length dest cpy flag token s_buf length+s_buf )
+ r@ COPYLENGTH - > ( dest_end length dest cpy flag token s_buf flag )
+ swap >r ( dest_end length dest cpy flag token flag R: s_end s_buf )
+ swap >r ( dest_end length dest cpy flag flag R: s_end s_buf token )
+ or if ( dest_end length dest cpy R: s_end s_buf token )
+
+ 3 pick over swap > if
+ " lz4 write beyond buffer end" die ( write beyond the dest end )
+ then ( dest_end length dest cpy )
+
+ 2 pick ( dest_end length dest cpy length )
+ r> r> swap ( dest_end length dest cpy length s_buf token R: s_end )
+ r> ( dest_end length dest cpy length s_buf token s_end )
+ swap >r >r ( dest_end length dest cpy length s_buf R: token s_end )
+
+ swap over + ( dest_end length dest cpy s_buf s_buf+length )
+ r@ > if ( dest_end length dest cpy s_buf R: token s_end )
+ " lz4 read beyond source" die \ read beyond source buffer
+ then
+
+ nip ( dest_end length dest s_buf R: token s_end )
+ >r ( dest_end length dest R: token s_end s_buf )
+ over r@ ( dest_end length dest length s_buf )
+ -rot move ( dest_end length )
+
+ r> + r> r> drop < if
+ " lz4 format violation" die \ LZ4 format violation
+ then
+
+ r> drop \ drop original dest
+ drop
+ exit \ parsing done
+ then
+
+ swap ( dest_end length cpy dest R: s_end s_buf token )
+ r> r> swap >r ( dest_end length cpy dest s_buf R: s_end token )
+
+ lz4_copy ( dest_end length cpy dest s_buf)
+
+ -rot ( dest_end length s_buf cpy dest )
+ over - ( dest_end length s_buf cpy dest-cpy )
+ rot ( dest_end length cpy dest-cpy s_buf )
+ swap - ( dest_end length cpy s_buf )
+
+ dup C@ swap ( dest_end length cpy b s_buf )
+ dup 1+ C@ 8 lshift ( dest_end length cpy b s_buf w )
+ rot or ( dest_end length cpy s_buf w )
+ 2 pick swap - ( dest_end length cpy s_buf ref )
+ swap 2 + ( dest_end length cpy ref s_buf+2 )
+ \ note: cpy is also dest, remember to save it
+ -rot ( dest_end length s_buf cpy ref )
+ dup ( dest_end length s_buf cpy ref ref )
+
+ \ now we need original dest
+ r> r> swap r@ ( dest_end length s_buf cpy ref ref s_end token dest )
+ -rot swap >r >r
+ < if
+ " lz4 reference outside buffer" die \ reference outside dest buffer
+ then ( dest_end length s_buf op ref )
+
+ 2swap ( dest_end op ref length s_buf )
+ swap ( dest_end op ref s_buf length R: dest s_end token )
+
+ \ get matchlength
+ drop r> ML_MASK and ( dest_end op ref s_buf length R: dest s_end )
+ dup ML_MASK = if ( dest_end op ref s_buf length R: dest s_end )
+ -1 \ flag to top
+ begin
+ rot ( dest_end op ref length flag s_buf )
+ dup r@ < ( dest_end op ref length flag s_buf flag )
+ rot and ( dest_end op ref length s_buf flag )
+ while
+ dup c@ ( dest_end op ref length s_buf s )
+ swap 1+ ( dest_end op ref length s s_buf++ )
+ -rot ( dest_end op ref s_buf length s )
+ swap over + swap ( dest_end op ref s_buf length+s s )
+ d# 255 =
+ repeat
+ swap
+ then ( dest_end op ref s_buf length R: dest s_end )
+
+ 2swap ( dest_end s_buf length op ref )
+
+ \ copy repeated sequence
+ 2dup - STEPSIZE < if ( dest_end s_buf length op ref )
+ \ 4 times *op++ = *ref++;
+ dup c@ >r ( dest_end s_buf length op ref R: C )
+ CHAR+ swap ( dest_end s_buf length ref++ op )
+ dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref )
+ dup c@ >r ( dest_end s_buf length op ref R: C )
+ CHAR+ swap ( dest_end s_buf length ref++ op )
+ dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref )
+ dup c@ >r ( dest_end s_buf length op ref R: C )
+ CHAR+ swap ( dest_end s_buf length ref++ op )
+ dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref )
+ dup c@ >r ( dest_end s_buf length op ref R: C )
+ CHAR+ swap ( dest_end s_buf length ref++ op )
+ dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref )
+ 2dup - ( dest_end s_buf length op ref op-ref )
+ case
+ 1 of 3 endof
+ 2 of 2 endof
+ 3 of 3 endof
+ 0
+ endcase
+ - \ ref -= dec
+ 2dup swap 4 move ( dest_end s_buf length op ref )
+ swap STEPSIZE 4 - +
+ swap ( dest_end s_buf length op ref )
+ else
+ lz4_copystep ( dest_end s_buf length op ref )
+ then
+ -rot ( dest_end s_buf ref length op )
+ swap over ( dest_end s_buf ref op length op )
+ + STEPSIZE 4 - - ( dest_end s_buf ref op cpy R: dest s_end )
+
+ \ if cpy > oend - COPYLENGTH
+ 4 pick COPYLENGTH - ( dest_end s_buf ref op cpy oend-COPYLENGTH )
+ 2dup > if ( dest_end s_buf ref op cpy oend-COPYLENGTH )
+ swap ( dest_end s_buf ref op oend-COPYLENGTH cpy )
+
+ 5 pick over < if
+ " lz4 write outside buffer" die \ write outside of dest buffer
+ then ( dest_end s_buf ref op oend-COPYLENGTH cpy )
+
+ >r ( dest_end s_buf ref op oend-COPYLENGTH R: dest s_end cpy )
+ -rot swap ( dest_end s_buf oend-COPYLENGTH op ref )
+ lz4_copy ( dest_end s_buf oend-COPYLENGTH op ref )
+ rot drop swap r> ( dest_end s_buf ref op cpy )
+ begin
+ 2dup <
+ while
+ >r ( dest_end s_buf ref op R: cpy )
+ over ( dest_end s_buf ref op ref )
+ c@ ( dest_end s_buf ref op C )
+ over c! ( dest_end s_buf ref op )
+ >r 1+ r> 1+ r> ( dest_end s_buf ref++ op++ cpy )
+ repeat
+
+ nip ( dest_end s_buf ref op )
+ dup 4 pick = if
+ \ op == dest_end we are done, cleanup
+ r> r> 2drop 2drop 2drop
+ exit
+ then
+ ( dest_end s_buf ref op R: dest s_end )
+ nip ( dest_end s_buf op )
+ else
+ drop ( dest_end s_buf ref op cpy R: dest s_end)
+ -rot ( dest_end s_buf cpy ref op )
+ swap ( dest_end s_buf cpy op ref )
+ lz4_copy
+ 2drop ( dest_end s_buf op )
+ then
+
+ -rot r> ( op dest_end s_buf s_end R: dest )
+ repeat
+
+ r> drop
+ 2drop
+ 2drop
+ ;
\
\ ZFS block (SPA) routines
@@ -167,6 +421,7 @@ new-device
1 constant def-comp#
2 constant no-comp#
3 constant lzjb-comp#
+ d# 15 constant lz4-comp#
h# 2.0000 constant /max-bsize
d# 512 constant /disk-block
@@ -254,16 +509,27 @@ new-device
read-dva exit ( )
then
- \ only do lzjb
- dup blk_comp dup lzjb-comp# <> ( adr len bp comp lzjb? )
+ \ lzjb?
+ dup blk_comp lzjb-comp# = if
+ \ read into blk-space and de-compress
+ blk-space over bp-dsize ( adr len bp blk-adr rd-len )
+ rot read-dva ( adr len )
+ blk-space -rot lzjb ( )
+ exit
+ then
+
+ dup blk_comp dup lz4-comp# <> ( adr len bp comp lz4? )
swap def-comp# <> and if ( adr len bp )
- " only lzjb supported" die
+ dup hex . ." BP: "
+ blk_comp decimal .
+ ." : bug, unknown compression algorithm: "
+ " only lzjb and lz4 supported" die
then
\ read into blk-space and de-compress
blk-space over bp-dsize ( adr len bp blk-adr rd-len )
rot read-dva ( adr len )
- blk-space -rot lzjb ( )
+ blk-space -rot lz4 ( )
;
\