From 96165abec2da60c466659fa0e68e06d97587d51a Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Thu, 28 May 2009 18:27:08 +0000 Subject: FS#10253 : mkamsboot v1.0 - Bump version to 1.0 - Add Clipv2 target - Make mkamsboot work as a library (work by domonoky : FS#10185, with a few modifications by me) . Use a macro with variadic arguments for error cases in functions which might error. . Add detailed descriptions to functions exported by the library (in the header file) - modify bin2c.c to produce only one pair of .c/.h files with several files embedded in it - move files needing to be built by an ARM cross compiler into dualboot/ - commit produced .c/.h files (containing nrv2e_d8.S and dualboot.S built for Clip, Fuze, e200v2, c200v2, m200v4, Clipv2) - Write a real README file - cosmetics: indent dualboot.S properly, remove trailing spaces, limit lines to 80 characters - comments: add/correct comments in dualboot.S and mkamsboot.c - move back extract_fw.c to utils/AMS/hacking git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21118 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/mkamsboot/dualboot/nrv2e_d8.S | 193 +++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 rbutil/mkamsboot/dualboot/nrv2e_d8.S (limited to 'rbutil/mkamsboot/dualboot/nrv2e_d8.S') diff --git a/rbutil/mkamsboot/dualboot/nrv2e_d8.S b/rbutil/mkamsboot/dualboot/nrv2e_d8.S new file mode 100644 index 0000000000..b112ab2936 --- /dev/null +++ b/rbutil/mkamsboot/dualboot/nrv2e_d8.S @@ -0,0 +1,193 @@ +/* arm_nrv2e_d8.S -- ARM decompressor for NRV2E + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2008 Laszlo Molnar + Copyright (C) 2000-2008 John F. Reiser + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + + John F. Reiser + +*/ +#define SAFE 0 /* 1 for src+dst bounds checking: cost 40 bytes */ + +#define src r0 +#define len r1 /* overlaps 'cnt' */ +#define dst r2 +#define tmp r3 +#define bits r4 +#define off r5 +#define wrnk r6 /* 0x500 M2_MAX_OFFSET before "wrinkle" */ +#define srclim r7 +#if 1==SAFE /*{*/ +#define dstlim r12 +#endif /*}*/ + +#define cnt r1 /* overlaps 'len' while reading an offset */ + +#if 1==SAFE /*{*/ +#define CHECK_SRC cmp src,srclim; bhs bad_src_n2e +#define CHECK_DST cmp dst,dstlim; bhs bad_dst_n2e +#else /*}{*/ +#define CHECK_SRC /*empty*/ +#define CHECK_DST /*empty*/ +#endif /*}*/ + +#if 0 /*{ DEBUG only: check newly-decompressed against original dst */ +#define CHECK_BYTE \ + push {wrnk}; \ + ldrb wrnk,[dst]; \ + cmp wrnk,tmp; beq 0f; bkpt; \ +0: pop {wrnk} +#else /*}{*/ +#define CHECK_BYTE /*empty*/ +#endif /*}*/ + +/* "mov lr,pc; bxx ..." implements conditional subroutine call */ +#define GETBIT add bits,bits; mov lr,pc; beq get1_n2e + +#define getnextb(reg) GETBIT; adc reg,reg +#define jnextb0 GETBIT; bcc +#define jnextb1 GETBIT; bcs + +#ifndef PURE_THUMB +ucl_nrv2e_decompress_8: .globl ucl_nrv2e_decompress_8 @ ARM mode + .type ucl_nrv2e_decompress_8, %function +/* error = (*)(char const *src, int len_src, char *dst, int *plen_dst) + Actual decompressed length is stored through plen_dst. + For SAFE mode: at call, *plen_dst must be allowed length of output buffer. +*/ + adr r12,1+.thumb_nrv2e_d8; bx r12 @ enter THUMB mode +#endif + .code 16 @ THUMB mode + .thumb_func + +.thumb_nrv2e_d8: +#if 0 + push {r2,r3, r4,r5,r6,r7, lr} +#define sp_DST0 0 /* stack offset of original dst */ +#endif + add srclim,len,src @ srclim= eof_src; +#if 1==SAFE /*{*/ + ldr tmp,[r3] @ len_dst + add tmp,dst + mov dstlim,tmp +#endif /*}*/ + mov bits,#1; neg off,bits @ off= -1 initial condition + lsl bits,#31 @ 1<<31: refill next time + mov wrnk,#5 + lsl wrnk,#8 @ 0x500 @ nrv2e M2_MAX_OFFSET + b top_n2e + +#if 1==SAFE /*{*/ +bad_dst_n2e: # return value will be 2 + add src,srclim,#1 +bad_src_n2e: # return value will be 1 + add src,#1 +#endif /*}*/ +eof_n2e: +#if 0 + pop {r3,r4} @ r3= orig_dst; r4= plen_dst + sub src,srclim @ 0 if actual src length equals expected length + sub dst,r3 @ actual dst length + str dst,[r4] + pop {r4,r5,r6,r7 /*,pc*/} + pop {r1}; bx r1 @ "pop {,pc}" fails return to ARM mode on ARMv4T +#else + mov r0, #0 + bx r0 /* Branch to 0x0, switch to ARM mode */ +#endif + +get1_n2e: @ In: Carry set [from adding 0x80000000 (1<<31) to itself] + ldrb bits,[src] @ zero-extend next byte + adc bits,bits @ double and insert CarryIn as low bit + CHECK_SRC + add src,#1 + lsl bits,#24 @ move to top byte, and set CarryOut from old bit 8 + mov pc,lr @ return, stay in current (THUMB) mode + +lit_n2e: + CHECK_SRC; ldrb tmp,[src]; add src,#1 + CHECK_BYTE + CHECK_DST; strb tmp,[dst]; add dst,#1 +top_n2e: + jnextb1 lit_n2e + mov cnt,#1; b getoff_n2e + +off_n2e: + sub cnt,#1 + getnextb(cnt) +getoff_n2e: + getnextb(cnt) + jnextb0 off_n2e + + sub tmp,cnt,#3 @ set Carry + mov len,#0 @ Carry unaffected + blo offprev_n2e @ cnt was 2; tests Carry only + lsl tmp,#8 + CHECK_SRC; ldrb off,[src]; add src,#1 @ low 7+1 bits + orr off,tmp + mvn off,off; beq eof_n2e @ off= ~off + asr off,#1; bcs lenlast_n2e + b lenmore_n2e + +offprev_n2e: + jnextb1 lenlast_n2e +lenmore_n2e: + mov len,#1 + jnextb1 lenlast_n2e +len_n2e: + getnextb(len) + jnextb0 len_n2e + add len,#6-2 + b gotlen_n2e + +lenlast_n2e: + getnextb(len) @ 0,1,2,3 + add len,#2 +gotlen_n2e: @ 'cmn': add the inputs, set condition codes, discard the sum + cmn wrnk,off; bcs near_n2e @ within M2_MAX_OFFSET + add len,#1 @ too far away, so minimum match length is 3 +near_n2e: +#if 1==SAFE /*{*/ + ldr tmp,[sp,#sp_DST0] + sub tmp,dst + sub tmp,off; bhi bad_dst_n2e @ reaching back too far + + add tmp,dst,cnt + cmp tmp,dstlim; bhi bad_dst_n2e @ too much output +#endif /*}*/ + ldrb tmp,[dst] @ force cacheline allocate +copy_n2e: + ldrb tmp,[dst,off] + CHECK_BYTE + strb tmp,[dst]; add dst,#1 + sub len,#1; bne copy_n2e + b top_n2e + +#ifndef PURE_THUMB + .size ucl_nrv2e_decompress_8, .-ucl_nrv2e_decompress_8 +#endif + +/* +vi:ts=8:et:nowrap + */ -- cgit v1.2.3