123ba6841SJoseph Chen // SPDX-License-Identifier: GPL-2.0+ 223ba6841SJoseph Chen /* 323ba6841SJoseph Chen * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd 423ba6841SJoseph Chen */ 523ba6841SJoseph Chen 623ba6841SJoseph Chen #include <errno.h> 723ba6841SJoseph Chen #include <memory.h> 823ba6841SJoseph Chen #include <stdint.h> 923ba6841SJoseph Chen #include <stdio.h> 1023ba6841SJoseph Chen #include <stdlib.h> 1123ba6841SJoseph Chen #include <stdbool.h> 1223ba6841SJoseph Chen #include <sys/stat.h> 1323ba6841SJoseph Chen #include <time.h> 14*467d16dbSJoseph Chen 15*467d16dbSJoseph Chen /** 16*467d16dbSJoseph Chen * \brief SHA-1 context structure 17*467d16dbSJoseph Chen */ 18*467d16dbSJoseph Chen typedef struct 19*467d16dbSJoseph Chen { 20*467d16dbSJoseph Chen unsigned long total[2]; /*!< number of bytes processed */ 21*467d16dbSJoseph Chen unsigned long state[5]; /*!< intermediate digest state */ 22*467d16dbSJoseph Chen unsigned char buffer[64]; /*!< data block being processed */ 23*467d16dbSJoseph Chen } 24*467d16dbSJoseph Chen sha1_context; 25*467d16dbSJoseph Chen 26*467d16dbSJoseph Chen /* 27*467d16dbSJoseph Chen * 32-bit integer manipulation macros (big endian) 28*467d16dbSJoseph Chen */ 29*467d16dbSJoseph Chen #ifndef GET_UINT32_BE 30*467d16dbSJoseph Chen #define GET_UINT32_BE(n,b,i) { \ 31*467d16dbSJoseph Chen (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ 32*467d16dbSJoseph Chen | ( (unsigned long) (b)[(i) + 1] << 16 ) \ 33*467d16dbSJoseph Chen | ( (unsigned long) (b)[(i) + 2] << 8 ) \ 34*467d16dbSJoseph Chen | ( (unsigned long) (b)[(i) + 3] ); \ 35*467d16dbSJoseph Chen } 36*467d16dbSJoseph Chen #endif 37*467d16dbSJoseph Chen #ifndef PUT_UINT32_BE 38*467d16dbSJoseph Chen #define PUT_UINT32_BE(n,b,i) { \ 39*467d16dbSJoseph Chen (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 40*467d16dbSJoseph Chen (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 41*467d16dbSJoseph Chen (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 42*467d16dbSJoseph Chen (b)[(i) + 3] = (unsigned char) ( (n) ); \ 43*467d16dbSJoseph Chen } 44*467d16dbSJoseph Chen #endif 45*467d16dbSJoseph Chen 46*467d16dbSJoseph Chen /* 47*467d16dbSJoseph Chen * SHA-1 context setup 48*467d16dbSJoseph Chen */ 49*467d16dbSJoseph Chen static 50*467d16dbSJoseph Chen void sha1_starts (sha1_context * ctx) 51*467d16dbSJoseph Chen { 52*467d16dbSJoseph Chen ctx->total[0] = 0; 53*467d16dbSJoseph Chen ctx->total[1] = 0; 54*467d16dbSJoseph Chen 55*467d16dbSJoseph Chen ctx->state[0] = 0x67452301; 56*467d16dbSJoseph Chen ctx->state[1] = 0xEFCDAB89; 57*467d16dbSJoseph Chen ctx->state[2] = 0x98BADCFE; 58*467d16dbSJoseph Chen ctx->state[3] = 0x10325476; 59*467d16dbSJoseph Chen ctx->state[4] = 0xC3D2E1F0; 60*467d16dbSJoseph Chen } 61*467d16dbSJoseph Chen 62*467d16dbSJoseph Chen static void sha1_process(sha1_context *ctx, const unsigned char data[64]) 63*467d16dbSJoseph Chen { 64*467d16dbSJoseph Chen unsigned long temp, W[16], A, B, C, D, E; 65*467d16dbSJoseph Chen 66*467d16dbSJoseph Chen GET_UINT32_BE (W[0], data, 0); 67*467d16dbSJoseph Chen GET_UINT32_BE (W[1], data, 4); 68*467d16dbSJoseph Chen GET_UINT32_BE (W[2], data, 8); 69*467d16dbSJoseph Chen GET_UINT32_BE (W[3], data, 12); 70*467d16dbSJoseph Chen GET_UINT32_BE (W[4], data, 16); 71*467d16dbSJoseph Chen GET_UINT32_BE (W[5], data, 20); 72*467d16dbSJoseph Chen GET_UINT32_BE (W[6], data, 24); 73*467d16dbSJoseph Chen GET_UINT32_BE (W[7], data, 28); 74*467d16dbSJoseph Chen GET_UINT32_BE (W[8], data, 32); 75*467d16dbSJoseph Chen GET_UINT32_BE (W[9], data, 36); 76*467d16dbSJoseph Chen GET_UINT32_BE (W[10], data, 40); 77*467d16dbSJoseph Chen GET_UINT32_BE (W[11], data, 44); 78*467d16dbSJoseph Chen GET_UINT32_BE (W[12], data, 48); 79*467d16dbSJoseph Chen GET_UINT32_BE (W[13], data, 52); 80*467d16dbSJoseph Chen GET_UINT32_BE (W[14], data, 56); 81*467d16dbSJoseph Chen GET_UINT32_BE (W[15], data, 60); 82*467d16dbSJoseph Chen 83*467d16dbSJoseph Chen #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 84*467d16dbSJoseph Chen 85*467d16dbSJoseph Chen #define R(t) ( \ 86*467d16dbSJoseph Chen temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 87*467d16dbSJoseph Chen W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 88*467d16dbSJoseph Chen ( W[t & 0x0F] = S(temp,1) ) \ 89*467d16dbSJoseph Chen ) 90*467d16dbSJoseph Chen 91*467d16dbSJoseph Chen #define P(a,b,c,d,e,x) { \ 92*467d16dbSJoseph Chen e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 93*467d16dbSJoseph Chen } 94*467d16dbSJoseph Chen 95*467d16dbSJoseph Chen A = ctx->state[0]; 96*467d16dbSJoseph Chen B = ctx->state[1]; 97*467d16dbSJoseph Chen C = ctx->state[2]; 98*467d16dbSJoseph Chen D = ctx->state[3]; 99*467d16dbSJoseph Chen E = ctx->state[4]; 100*467d16dbSJoseph Chen 101*467d16dbSJoseph Chen #define F(x,y,z) (z ^ (x & (y ^ z))) 102*467d16dbSJoseph Chen #define K 0x5A827999 103*467d16dbSJoseph Chen 104*467d16dbSJoseph Chen P (A, B, C, D, E, W[0]); 105*467d16dbSJoseph Chen P (E, A, B, C, D, W[1]); 106*467d16dbSJoseph Chen P (D, E, A, B, C, W[2]); 107*467d16dbSJoseph Chen P (C, D, E, A, B, W[3]); 108*467d16dbSJoseph Chen P (B, C, D, E, A, W[4]); 109*467d16dbSJoseph Chen P (A, B, C, D, E, W[5]); 110*467d16dbSJoseph Chen P (E, A, B, C, D, W[6]); 111*467d16dbSJoseph Chen P (D, E, A, B, C, W[7]); 112*467d16dbSJoseph Chen P (C, D, E, A, B, W[8]); 113*467d16dbSJoseph Chen P (B, C, D, E, A, W[9]); 114*467d16dbSJoseph Chen P (A, B, C, D, E, W[10]); 115*467d16dbSJoseph Chen P (E, A, B, C, D, W[11]); 116*467d16dbSJoseph Chen P (D, E, A, B, C, W[12]); 117*467d16dbSJoseph Chen P (C, D, E, A, B, W[13]); 118*467d16dbSJoseph Chen P (B, C, D, E, A, W[14]); 119*467d16dbSJoseph Chen P (A, B, C, D, E, W[15]); 120*467d16dbSJoseph Chen P (E, A, B, C, D, R (16)); 121*467d16dbSJoseph Chen P (D, E, A, B, C, R (17)); 122*467d16dbSJoseph Chen P (C, D, E, A, B, R (18)); 123*467d16dbSJoseph Chen P (B, C, D, E, A, R (19)); 124*467d16dbSJoseph Chen 125*467d16dbSJoseph Chen #undef K 126*467d16dbSJoseph Chen #undef F 127*467d16dbSJoseph Chen 128*467d16dbSJoseph Chen #define F(x,y,z) (x ^ y ^ z) 129*467d16dbSJoseph Chen #define K 0x6ED9EBA1 130*467d16dbSJoseph Chen 131*467d16dbSJoseph Chen P (A, B, C, D, E, R (20)); 132*467d16dbSJoseph Chen P (E, A, B, C, D, R (21)); 133*467d16dbSJoseph Chen P (D, E, A, B, C, R (22)); 134*467d16dbSJoseph Chen P (C, D, E, A, B, R (23)); 135*467d16dbSJoseph Chen P (B, C, D, E, A, R (24)); 136*467d16dbSJoseph Chen P (A, B, C, D, E, R (25)); 137*467d16dbSJoseph Chen P (E, A, B, C, D, R (26)); 138*467d16dbSJoseph Chen P (D, E, A, B, C, R (27)); 139*467d16dbSJoseph Chen P (C, D, E, A, B, R (28)); 140*467d16dbSJoseph Chen P (B, C, D, E, A, R (29)); 141*467d16dbSJoseph Chen P (A, B, C, D, E, R (30)); 142*467d16dbSJoseph Chen P (E, A, B, C, D, R (31)); 143*467d16dbSJoseph Chen P (D, E, A, B, C, R (32)); 144*467d16dbSJoseph Chen P (C, D, E, A, B, R (33)); 145*467d16dbSJoseph Chen P (B, C, D, E, A, R (34)); 146*467d16dbSJoseph Chen P (A, B, C, D, E, R (35)); 147*467d16dbSJoseph Chen P (E, A, B, C, D, R (36)); 148*467d16dbSJoseph Chen P (D, E, A, B, C, R (37)); 149*467d16dbSJoseph Chen P (C, D, E, A, B, R (38)); 150*467d16dbSJoseph Chen P (B, C, D, E, A, R (39)); 151*467d16dbSJoseph Chen 152*467d16dbSJoseph Chen #undef K 153*467d16dbSJoseph Chen #undef F 154*467d16dbSJoseph Chen 155*467d16dbSJoseph Chen #define F(x,y,z) ((x & y) | (z & (x | y))) 156*467d16dbSJoseph Chen #define K 0x8F1BBCDC 157*467d16dbSJoseph Chen 158*467d16dbSJoseph Chen P (A, B, C, D, E, R (40)); 159*467d16dbSJoseph Chen P (E, A, B, C, D, R (41)); 160*467d16dbSJoseph Chen P (D, E, A, B, C, R (42)); 161*467d16dbSJoseph Chen P (C, D, E, A, B, R (43)); 162*467d16dbSJoseph Chen P (B, C, D, E, A, R (44)); 163*467d16dbSJoseph Chen P (A, B, C, D, E, R (45)); 164*467d16dbSJoseph Chen P (E, A, B, C, D, R (46)); 165*467d16dbSJoseph Chen P (D, E, A, B, C, R (47)); 166*467d16dbSJoseph Chen P (C, D, E, A, B, R (48)); 167*467d16dbSJoseph Chen P (B, C, D, E, A, R (49)); 168*467d16dbSJoseph Chen P (A, B, C, D, E, R (50)); 169*467d16dbSJoseph Chen P (E, A, B, C, D, R (51)); 170*467d16dbSJoseph Chen P (D, E, A, B, C, R (52)); 171*467d16dbSJoseph Chen P (C, D, E, A, B, R (53)); 172*467d16dbSJoseph Chen P (B, C, D, E, A, R (54)); 173*467d16dbSJoseph Chen P (A, B, C, D, E, R (55)); 174*467d16dbSJoseph Chen P (E, A, B, C, D, R (56)); 175*467d16dbSJoseph Chen P (D, E, A, B, C, R (57)); 176*467d16dbSJoseph Chen P (C, D, E, A, B, R (58)); 177*467d16dbSJoseph Chen P (B, C, D, E, A, R (59)); 178*467d16dbSJoseph Chen 179*467d16dbSJoseph Chen #undef K 180*467d16dbSJoseph Chen #undef F 181*467d16dbSJoseph Chen 182*467d16dbSJoseph Chen #define F(x,y,z) (x ^ y ^ z) 183*467d16dbSJoseph Chen #define K 0xCA62C1D6 184*467d16dbSJoseph Chen 185*467d16dbSJoseph Chen P (A, B, C, D, E, R (60)); 186*467d16dbSJoseph Chen P (E, A, B, C, D, R (61)); 187*467d16dbSJoseph Chen P (D, E, A, B, C, R (62)); 188*467d16dbSJoseph Chen P (C, D, E, A, B, R (63)); 189*467d16dbSJoseph Chen P (B, C, D, E, A, R (64)); 190*467d16dbSJoseph Chen P (A, B, C, D, E, R (65)); 191*467d16dbSJoseph Chen P (E, A, B, C, D, R (66)); 192*467d16dbSJoseph Chen P (D, E, A, B, C, R (67)); 193*467d16dbSJoseph Chen P (C, D, E, A, B, R (68)); 194*467d16dbSJoseph Chen P (B, C, D, E, A, R (69)); 195*467d16dbSJoseph Chen P (A, B, C, D, E, R (70)); 196*467d16dbSJoseph Chen P (E, A, B, C, D, R (71)); 197*467d16dbSJoseph Chen P (D, E, A, B, C, R (72)); 198*467d16dbSJoseph Chen P (C, D, E, A, B, R (73)); 199*467d16dbSJoseph Chen P (B, C, D, E, A, R (74)); 200*467d16dbSJoseph Chen P (A, B, C, D, E, R (75)); 201*467d16dbSJoseph Chen P (E, A, B, C, D, R (76)); 202*467d16dbSJoseph Chen P (D, E, A, B, C, R (77)); 203*467d16dbSJoseph Chen P (C, D, E, A, B, R (78)); 204*467d16dbSJoseph Chen P (B, C, D, E, A, R (79)); 205*467d16dbSJoseph Chen 206*467d16dbSJoseph Chen #undef K 207*467d16dbSJoseph Chen #undef F 208*467d16dbSJoseph Chen 209*467d16dbSJoseph Chen ctx->state[0] += A; 210*467d16dbSJoseph Chen ctx->state[1] += B; 211*467d16dbSJoseph Chen ctx->state[2] += C; 212*467d16dbSJoseph Chen ctx->state[3] += D; 213*467d16dbSJoseph Chen ctx->state[4] += E; 214*467d16dbSJoseph Chen } 215*467d16dbSJoseph Chen 216*467d16dbSJoseph Chen #undef P 217*467d16dbSJoseph Chen #undef R 218*467d16dbSJoseph Chen #undef S 219*467d16dbSJoseph Chen 220*467d16dbSJoseph Chen /* 221*467d16dbSJoseph Chen * SHA-1 process buffer 222*467d16dbSJoseph Chen */ 223*467d16dbSJoseph Chen static 224*467d16dbSJoseph Chen void sha1_update(sha1_context *ctx, const unsigned char *input, 225*467d16dbSJoseph Chen unsigned int ilen) 226*467d16dbSJoseph Chen { 227*467d16dbSJoseph Chen int fill; 228*467d16dbSJoseph Chen unsigned long left; 229*467d16dbSJoseph Chen 230*467d16dbSJoseph Chen if (ilen <= 0) 231*467d16dbSJoseph Chen return; 232*467d16dbSJoseph Chen 233*467d16dbSJoseph Chen left = ctx->total[0] & 0x3F; 234*467d16dbSJoseph Chen fill = 64 - left; 235*467d16dbSJoseph Chen 236*467d16dbSJoseph Chen ctx->total[0] += ilen; 237*467d16dbSJoseph Chen ctx->total[0] &= 0xFFFFFFFF; 238*467d16dbSJoseph Chen 239*467d16dbSJoseph Chen if (ctx->total[0] < (unsigned long) ilen) 240*467d16dbSJoseph Chen ctx->total[1]++; 241*467d16dbSJoseph Chen 242*467d16dbSJoseph Chen if (left && ilen >= fill) { 243*467d16dbSJoseph Chen memcpy ((void *) (ctx->buffer + left), (void *) input, fill); 244*467d16dbSJoseph Chen sha1_process (ctx, ctx->buffer); 245*467d16dbSJoseph Chen input += fill; 246*467d16dbSJoseph Chen ilen -= fill; 247*467d16dbSJoseph Chen left = 0; 248*467d16dbSJoseph Chen } 249*467d16dbSJoseph Chen 250*467d16dbSJoseph Chen while (ilen >= 64) { 251*467d16dbSJoseph Chen sha1_process (ctx, input); 252*467d16dbSJoseph Chen input += 64; 253*467d16dbSJoseph Chen ilen -= 64; 254*467d16dbSJoseph Chen } 255*467d16dbSJoseph Chen 256*467d16dbSJoseph Chen if (ilen > 0) { 257*467d16dbSJoseph Chen memcpy ((void *) (ctx->buffer + left), (void *) input, ilen); 258*467d16dbSJoseph Chen } 259*467d16dbSJoseph Chen } 260*467d16dbSJoseph Chen 261*467d16dbSJoseph Chen static const unsigned char sha1_padding[64] = { 262*467d16dbSJoseph Chen 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 265*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 266*467d16dbSJoseph Chen }; 267*467d16dbSJoseph Chen 268*467d16dbSJoseph Chen /* 269*467d16dbSJoseph Chen * SHA-1 final digest 270*467d16dbSJoseph Chen */ 271*467d16dbSJoseph Chen static 272*467d16dbSJoseph Chen void sha1_finish (sha1_context * ctx, unsigned char output[20]) 273*467d16dbSJoseph Chen { 274*467d16dbSJoseph Chen unsigned long last, padn; 275*467d16dbSJoseph Chen unsigned long high, low; 276*467d16dbSJoseph Chen unsigned char msglen[8]; 277*467d16dbSJoseph Chen 278*467d16dbSJoseph Chen high = (ctx->total[0] >> 29) 279*467d16dbSJoseph Chen | (ctx->total[1] << 3); 280*467d16dbSJoseph Chen low = (ctx->total[0] << 3); 281*467d16dbSJoseph Chen 282*467d16dbSJoseph Chen PUT_UINT32_BE (high, msglen, 0); 283*467d16dbSJoseph Chen PUT_UINT32_BE (low, msglen, 4); 284*467d16dbSJoseph Chen 285*467d16dbSJoseph Chen last = ctx->total[0] & 0x3F; 286*467d16dbSJoseph Chen padn = (last < 56) ? (56 - last) : (120 - last); 287*467d16dbSJoseph Chen 288*467d16dbSJoseph Chen sha1_update (ctx, (unsigned char *) sha1_padding, padn); 289*467d16dbSJoseph Chen sha1_update (ctx, msglen, 8); 290*467d16dbSJoseph Chen 291*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[0], output, 0); 292*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[1], output, 4); 293*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[2], output, 8); 294*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[3], output, 12); 295*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[4], output, 16); 296*467d16dbSJoseph Chen } 297*467d16dbSJoseph Chen 298*467d16dbSJoseph Chen /* 299*467d16dbSJoseph Chen * Output = SHA-1( input buffer ) 300*467d16dbSJoseph Chen */ 301*467d16dbSJoseph Chen static 302*467d16dbSJoseph Chen void sha1_csum(const unsigned char *input, unsigned int ilen, 303*467d16dbSJoseph Chen unsigned char *output) 304*467d16dbSJoseph Chen { 305*467d16dbSJoseph Chen sha1_context ctx; 306*467d16dbSJoseph Chen 307*467d16dbSJoseph Chen sha1_starts (&ctx); 308*467d16dbSJoseph Chen sha1_update (&ctx, input, ilen); 309*467d16dbSJoseph Chen sha1_finish (&ctx, output); 310*467d16dbSJoseph Chen } 311*467d16dbSJoseph Chen 312*467d16dbSJoseph Chen typedef struct { 313*467d16dbSJoseph Chen uint32_t total[2]; 314*467d16dbSJoseph Chen uint32_t state[8]; 315*467d16dbSJoseph Chen uint8_t buffer[64]; 316*467d16dbSJoseph Chen } sha256_context; 317*467d16dbSJoseph Chen 318*467d16dbSJoseph Chen static 319*467d16dbSJoseph Chen void sha256_starts(sha256_context * ctx) 320*467d16dbSJoseph Chen { 321*467d16dbSJoseph Chen ctx->total[0] = 0; 322*467d16dbSJoseph Chen ctx->total[1] = 0; 323*467d16dbSJoseph Chen 324*467d16dbSJoseph Chen ctx->state[0] = 0x6A09E667; 325*467d16dbSJoseph Chen ctx->state[1] = 0xBB67AE85; 326*467d16dbSJoseph Chen ctx->state[2] = 0x3C6EF372; 327*467d16dbSJoseph Chen ctx->state[3] = 0xA54FF53A; 328*467d16dbSJoseph Chen ctx->state[4] = 0x510E527F; 329*467d16dbSJoseph Chen ctx->state[5] = 0x9B05688C; 330*467d16dbSJoseph Chen ctx->state[6] = 0x1F83D9AB; 331*467d16dbSJoseph Chen ctx->state[7] = 0x5BE0CD19; 332*467d16dbSJoseph Chen } 333*467d16dbSJoseph Chen 334*467d16dbSJoseph Chen static void sha256_process(sha256_context *ctx, const uint8_t data[64]) 335*467d16dbSJoseph Chen { 336*467d16dbSJoseph Chen uint32_t temp1, temp2; 337*467d16dbSJoseph Chen uint32_t W[64]; 338*467d16dbSJoseph Chen uint32_t A, B, C, D, E, F, G, H; 339*467d16dbSJoseph Chen 340*467d16dbSJoseph Chen GET_UINT32_BE(W[0], data, 0); 341*467d16dbSJoseph Chen GET_UINT32_BE(W[1], data, 4); 342*467d16dbSJoseph Chen GET_UINT32_BE(W[2], data, 8); 343*467d16dbSJoseph Chen GET_UINT32_BE(W[3], data, 12); 344*467d16dbSJoseph Chen GET_UINT32_BE(W[4], data, 16); 345*467d16dbSJoseph Chen GET_UINT32_BE(W[5], data, 20); 346*467d16dbSJoseph Chen GET_UINT32_BE(W[6], data, 24); 347*467d16dbSJoseph Chen GET_UINT32_BE(W[7], data, 28); 348*467d16dbSJoseph Chen GET_UINT32_BE(W[8], data, 32); 349*467d16dbSJoseph Chen GET_UINT32_BE(W[9], data, 36); 350*467d16dbSJoseph Chen GET_UINT32_BE(W[10], data, 40); 351*467d16dbSJoseph Chen GET_UINT32_BE(W[11], data, 44); 352*467d16dbSJoseph Chen GET_UINT32_BE(W[12], data, 48); 353*467d16dbSJoseph Chen GET_UINT32_BE(W[13], data, 52); 354*467d16dbSJoseph Chen GET_UINT32_BE(W[14], data, 56); 355*467d16dbSJoseph Chen GET_UINT32_BE(W[15], data, 60); 356*467d16dbSJoseph Chen 357*467d16dbSJoseph Chen #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 358*467d16dbSJoseph Chen #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 359*467d16dbSJoseph Chen 360*467d16dbSJoseph Chen #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 361*467d16dbSJoseph Chen #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 362*467d16dbSJoseph Chen 363*467d16dbSJoseph Chen #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 364*467d16dbSJoseph Chen #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 365*467d16dbSJoseph Chen 366*467d16dbSJoseph Chen #define F0(x,y,z) ((x & y) | (z & (x | y))) 367*467d16dbSJoseph Chen #define F1(x,y,z) (z ^ (x & (y ^ z))) 368*467d16dbSJoseph Chen 369*467d16dbSJoseph Chen #define R(t) \ 370*467d16dbSJoseph Chen ( \ 371*467d16dbSJoseph Chen W[t] = S1(W[t - 2]) + W[t - 7] + \ 372*467d16dbSJoseph Chen S0(W[t - 15]) + W[t - 16] \ 373*467d16dbSJoseph Chen ) 374*467d16dbSJoseph Chen 375*467d16dbSJoseph Chen #define P(a,b,c,d,e,f,g,h,x,K) { \ 376*467d16dbSJoseph Chen temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 377*467d16dbSJoseph Chen temp2 = S2(a) + F0(a,b,c); \ 378*467d16dbSJoseph Chen d += temp1; h = temp1 + temp2; \ 379*467d16dbSJoseph Chen } 380*467d16dbSJoseph Chen 381*467d16dbSJoseph Chen A = ctx->state[0]; 382*467d16dbSJoseph Chen B = ctx->state[1]; 383*467d16dbSJoseph Chen C = ctx->state[2]; 384*467d16dbSJoseph Chen D = ctx->state[3]; 385*467d16dbSJoseph Chen E = ctx->state[4]; 386*467d16dbSJoseph Chen F = ctx->state[5]; 387*467d16dbSJoseph Chen G = ctx->state[6]; 388*467d16dbSJoseph Chen H = ctx->state[7]; 389*467d16dbSJoseph Chen 390*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98); 391*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, W[1], 0x71374491); 392*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF); 393*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5); 394*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B); 395*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1); 396*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4); 397*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5); 398*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98); 399*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, W[9], 0x12835B01); 400*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); 401*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); 402*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); 403*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); 404*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); 405*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); 406*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); 407*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); 408*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); 409*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); 410*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); 411*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); 412*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); 413*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); 414*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); 415*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); 416*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); 417*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); 418*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); 419*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); 420*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); 421*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(31), 0x14292967); 422*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); 423*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); 424*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); 425*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); 426*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); 427*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); 428*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); 429*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); 430*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); 431*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); 432*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); 433*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); 434*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); 435*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); 436*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); 437*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); 438*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); 439*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); 440*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); 441*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); 442*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); 443*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); 444*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); 445*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); 446*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); 447*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); 448*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); 449*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); 450*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); 451*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); 452*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); 453*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); 454*467d16dbSJoseph Chen 455*467d16dbSJoseph Chen ctx->state[0] += A; 456*467d16dbSJoseph Chen ctx->state[1] += B; 457*467d16dbSJoseph Chen ctx->state[2] += C; 458*467d16dbSJoseph Chen ctx->state[3] += D; 459*467d16dbSJoseph Chen ctx->state[4] += E; 460*467d16dbSJoseph Chen ctx->state[5] += F; 461*467d16dbSJoseph Chen ctx->state[6] += G; 462*467d16dbSJoseph Chen ctx->state[7] += H; 463*467d16dbSJoseph Chen } 464*467d16dbSJoseph Chen 465*467d16dbSJoseph Chen #undef P 466*467d16dbSJoseph Chen #undef R 467*467d16dbSJoseph Chen #undef F1 468*467d16dbSJoseph Chen #undef F0 469*467d16dbSJoseph Chen #undef S3 470*467d16dbSJoseph Chen #undef S2 471*467d16dbSJoseph Chen #undef S1 472*467d16dbSJoseph Chen #undef S0 473*467d16dbSJoseph Chen #undef ROTR 474*467d16dbSJoseph Chen #undef SHR 475*467d16dbSJoseph Chen 476*467d16dbSJoseph Chen static 477*467d16dbSJoseph Chen void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length) 478*467d16dbSJoseph Chen { 479*467d16dbSJoseph Chen uint32_t left, fill; 480*467d16dbSJoseph Chen 481*467d16dbSJoseph Chen if (!length) 482*467d16dbSJoseph Chen return; 483*467d16dbSJoseph Chen 484*467d16dbSJoseph Chen left = ctx->total[0] & 0x3F; 485*467d16dbSJoseph Chen fill = 64 - left; 486*467d16dbSJoseph Chen 487*467d16dbSJoseph Chen ctx->total[0] += length; 488*467d16dbSJoseph Chen ctx->total[0] &= 0xFFFFFFFF; 489*467d16dbSJoseph Chen 490*467d16dbSJoseph Chen if (ctx->total[0] < length) 491*467d16dbSJoseph Chen ctx->total[1]++; 492*467d16dbSJoseph Chen 493*467d16dbSJoseph Chen if (left && length >= fill) { 494*467d16dbSJoseph Chen memcpy((void *) (ctx->buffer + left), (void *) input, fill); 495*467d16dbSJoseph Chen sha256_process(ctx, ctx->buffer); 496*467d16dbSJoseph Chen length -= fill; 497*467d16dbSJoseph Chen input += fill; 498*467d16dbSJoseph Chen left = 0; 499*467d16dbSJoseph Chen } 500*467d16dbSJoseph Chen 501*467d16dbSJoseph Chen while (length >= 64) { 502*467d16dbSJoseph Chen sha256_process(ctx, input); 503*467d16dbSJoseph Chen length -= 64; 504*467d16dbSJoseph Chen input += 64; 505*467d16dbSJoseph Chen } 506*467d16dbSJoseph Chen 507*467d16dbSJoseph Chen if (length) 508*467d16dbSJoseph Chen memcpy((void *) (ctx->buffer + left), (void *) input, length); 509*467d16dbSJoseph Chen } 510*467d16dbSJoseph Chen 511*467d16dbSJoseph Chen static uint8_t sha256_padding[64] = { 512*467d16dbSJoseph Chen 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 513*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 515*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 516*467d16dbSJoseph Chen }; 517*467d16dbSJoseph Chen 518*467d16dbSJoseph Chen static 519*467d16dbSJoseph Chen void sha256_finish(sha256_context * ctx, uint8_t digest[32]) 520*467d16dbSJoseph Chen { 521*467d16dbSJoseph Chen uint32_t last, padn; 522*467d16dbSJoseph Chen uint32_t high, low; 523*467d16dbSJoseph Chen uint8_t msglen[8]; 524*467d16dbSJoseph Chen 525*467d16dbSJoseph Chen high = ((ctx->total[0] >> 29) 526*467d16dbSJoseph Chen | (ctx->total[1] << 3)); 527*467d16dbSJoseph Chen low = (ctx->total[0] << 3); 528*467d16dbSJoseph Chen 529*467d16dbSJoseph Chen PUT_UINT32_BE(high, msglen, 0); 530*467d16dbSJoseph Chen PUT_UINT32_BE(low, msglen, 4); 531*467d16dbSJoseph Chen 532*467d16dbSJoseph Chen last = ctx->total[0] & 0x3F; 533*467d16dbSJoseph Chen padn = (last < 56) ? (56 - last) : (120 - last); 534*467d16dbSJoseph Chen 535*467d16dbSJoseph Chen sha256_update(ctx, sha256_padding, padn); 536*467d16dbSJoseph Chen sha256_update(ctx, msglen, 8); 537*467d16dbSJoseph Chen 538*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[0], digest, 0); 539*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[1], digest, 4); 540*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[2], digest, 8); 541*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[3], digest, 12); 542*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[4], digest, 16); 543*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[5], digest, 20); 544*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[6], digest, 24); 545*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[7], digest, 28); 546*467d16dbSJoseph Chen } 547*467d16dbSJoseph Chen 548*467d16dbSJoseph Chen /* 549*467d16dbSJoseph Chen * Output = SHA-256( input buffer ). 550*467d16dbSJoseph Chen */ 551*467d16dbSJoseph Chen static 552*467d16dbSJoseph Chen void sha256_csum(const unsigned char *input, unsigned int ilen, 553*467d16dbSJoseph Chen unsigned char *output) 554*467d16dbSJoseph Chen { 555*467d16dbSJoseph Chen sha256_context ctx; 556*467d16dbSJoseph Chen 557*467d16dbSJoseph Chen sha256_starts(&ctx); 558*467d16dbSJoseph Chen sha256_update(&ctx, input, ilen); 559*467d16dbSJoseph Chen sha256_finish(&ctx, output); 560*467d16dbSJoseph Chen } 56123ba6841SJoseph Chen 56223ba6841SJoseph Chen /* #define DEBUG */ 56323ba6841SJoseph Chen 56423ba6841SJoseph Chen static bool g_debug = 56523ba6841SJoseph Chen #ifdef DEBUG 56623ba6841SJoseph Chen true; 56723ba6841SJoseph Chen #else 56823ba6841SJoseph Chen false; 56923ba6841SJoseph Chen #endif /* DEBUG */ 57023ba6841SJoseph Chen 57123ba6841SJoseph Chen #define LOGE(fmt, args...) \ 57223ba6841SJoseph Chen fprintf(stderr, "E/%s(%d): " fmt "\n", __func__, __LINE__, ##args) 57323ba6841SJoseph Chen #define LOGD(fmt, args...) \ 57423ba6841SJoseph Chen do { \ 57523ba6841SJoseph Chen if (g_debug) \ 57623ba6841SJoseph Chen fprintf(stderr, "D/%s(%d): " fmt "\n", __func__, __LINE__, ##args); \ 57723ba6841SJoseph Chen } while (0) 57823ba6841SJoseph Chen 57923ba6841SJoseph Chen /* sync with ./board/rockchip/rk30xx/rkloader.c #define FDT_PATH */ 58023ba6841SJoseph Chen #define FDT_PATH "rk-kernel.dtb" 58123ba6841SJoseph Chen #define DTD_SUBFIX ".dtb" 58223ba6841SJoseph Chen 58323ba6841SJoseph Chen #define DEFAULT_IMAGE_PATH "resource.img" 58423ba6841SJoseph Chen #define DEFAULT_UNPACK_DIR "out" 58523ba6841SJoseph Chen #define BLOCK_SIZE 512 58623ba6841SJoseph Chen 58723ba6841SJoseph Chen #define RESOURCE_PTN_HDR_SIZE 1 58823ba6841SJoseph Chen #define INDEX_TBL_ENTR_SIZE 1 58923ba6841SJoseph Chen 59023ba6841SJoseph Chen #define RESOURCE_PTN_VERSION 0 59123ba6841SJoseph Chen #define INDEX_TBL_VERSION 0 59223ba6841SJoseph Chen 59323ba6841SJoseph Chen #define RESOURCE_PTN_HDR_MAGIC "RSCE" 59423ba6841SJoseph Chen typedef struct { 59523ba6841SJoseph Chen char magic[4]; /* tag, "RSCE" */ 59623ba6841SJoseph Chen uint16_t resource_ptn_version; 59723ba6841SJoseph Chen uint16_t index_tbl_version; 59823ba6841SJoseph Chen uint8_t header_size; /* blocks, size of ptn header. */ 59923ba6841SJoseph Chen uint8_t tbl_offset; /* blocks, offset of index table. */ 60023ba6841SJoseph Chen uint8_t tbl_entry_size; /* blocks, size of index table's entry. */ 60123ba6841SJoseph Chen uint32_t tbl_entry_num; /* numbers of index table's entry. */ 60223ba6841SJoseph Chen } resource_ptn_header; 60323ba6841SJoseph Chen 60423ba6841SJoseph Chen #define INDEX_TBL_ENTR_TAG "ENTR" 6055e817a0eSJoseph Chen #define MAX_INDEX_ENTRY_PATH_LEN 220 6065e817a0eSJoseph Chen #define MAX_HASH_LEN 32 6075e817a0eSJoseph Chen 60823ba6841SJoseph Chen typedef struct { 60923ba6841SJoseph Chen char tag[4]; /* tag, "ENTR" */ 61023ba6841SJoseph Chen char path[MAX_INDEX_ENTRY_PATH_LEN]; 6115e817a0eSJoseph Chen char hash[MAX_HASH_LEN]; /* hash data */ 6125e817a0eSJoseph Chen uint32_t hash_size; /* 20 or 32 */ 61323ba6841SJoseph Chen uint32_t content_offset; /* blocks, offset of resource content. */ 61423ba6841SJoseph Chen uint32_t content_size; /* bytes, size of resource content. */ 61523ba6841SJoseph Chen } index_tbl_entry; 61623ba6841SJoseph Chen 61723ba6841SJoseph Chen #define OPT_VERBOSE "--verbose" 61823ba6841SJoseph Chen #define OPT_HELP "--help" 61923ba6841SJoseph Chen #define OPT_VERSION "--version" 62023ba6841SJoseph Chen #define OPT_PRINT "--print" 62123ba6841SJoseph Chen #define OPT_PACK "--pack" 62223ba6841SJoseph Chen #define OPT_UNPACK "--unpack" 62323ba6841SJoseph Chen #define OPT_TEST_LOAD "--test_load" 62423ba6841SJoseph Chen #define OPT_TEST_CHARGE "--test_charge" 62523ba6841SJoseph Chen #define OPT_IMAGE "--image=" 62623ba6841SJoseph Chen #define OPT_ROOT "--root=" 62723ba6841SJoseph Chen 62823ba6841SJoseph Chen #define VERSION "2014-5-31 14:43:42" 62923ba6841SJoseph Chen 63023ba6841SJoseph Chen typedef struct { 63123ba6841SJoseph Chen char path[MAX_INDEX_ENTRY_PATH_LEN]; 63223ba6841SJoseph Chen uint32_t content_offset; /* blocks, offset of resource content. */ 63323ba6841SJoseph Chen uint32_t content_size; /* bytes, size of resource content. */ 63423ba6841SJoseph Chen void *load_addr; 63523ba6841SJoseph Chen } resource_content; 63623ba6841SJoseph Chen 63723ba6841SJoseph Chen typedef struct { 63823ba6841SJoseph Chen int max_level; 63923ba6841SJoseph Chen int num; 64023ba6841SJoseph Chen int delay; 64123ba6841SJoseph Chen char prefix[MAX_INDEX_ENTRY_PATH_LEN]; 64223ba6841SJoseph Chen } anim_level_conf; 64323ba6841SJoseph Chen 64423ba6841SJoseph Chen #define DEF_CHARGE_DESC_PATH "charge_anim_desc.txt" 64523ba6841SJoseph Chen 64623ba6841SJoseph Chen #define OPT_CHARGE_ANIM_DELAY "delay=" 64723ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LOOP_CUR "only_current_level=" 64823ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVELS "levels=" 64923ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVEL_CONF "max_level=" 65023ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVEL_NUM "num=" 65123ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVEL_PFX "prefix=" 65223ba6841SJoseph Chen 65323ba6841SJoseph Chen static char image_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0"; 65423ba6841SJoseph Chen 65523ba6841SJoseph Chen static int fix_blocks(size_t size) 65623ba6841SJoseph Chen { 65723ba6841SJoseph Chen return (size + BLOCK_SIZE - 1) / BLOCK_SIZE; 65823ba6841SJoseph Chen } 65923ba6841SJoseph Chen 66023ba6841SJoseph Chen static const char *fix_path(const char *path) 66123ba6841SJoseph Chen { 66223ba6841SJoseph Chen if (!memcmp(path, "./", 2)) { 66323ba6841SJoseph Chen return path + 2; 66423ba6841SJoseph Chen } 66523ba6841SJoseph Chen return path; 66623ba6841SJoseph Chen } 66723ba6841SJoseph Chen 66823ba6841SJoseph Chen static uint16_t switch_short(uint16_t x) 66923ba6841SJoseph Chen { 67023ba6841SJoseph Chen uint16_t val; 67123ba6841SJoseph Chen uint8_t *p = (uint8_t *)(&x); 67223ba6841SJoseph Chen 67323ba6841SJoseph Chen val = (*p++ & 0xff) << 0; 67423ba6841SJoseph Chen val |= (*p & 0xff) << 8; 67523ba6841SJoseph Chen 67623ba6841SJoseph Chen return val; 67723ba6841SJoseph Chen } 67823ba6841SJoseph Chen 67923ba6841SJoseph Chen static uint32_t switch_int(uint32_t x) 68023ba6841SJoseph Chen { 68123ba6841SJoseph Chen uint32_t val; 68223ba6841SJoseph Chen uint8_t *p = (uint8_t *)(&x); 68323ba6841SJoseph Chen 68423ba6841SJoseph Chen val = (*p++ & 0xff) << 0; 68523ba6841SJoseph Chen val |= (*p++ & 0xff) << 8; 68623ba6841SJoseph Chen val |= (*p++ & 0xff) << 16; 68723ba6841SJoseph Chen val |= (*p & 0xff) << 24; 68823ba6841SJoseph Chen 68923ba6841SJoseph Chen return val; 69023ba6841SJoseph Chen } 69123ba6841SJoseph Chen 69223ba6841SJoseph Chen static void fix_header(resource_ptn_header *header) 69323ba6841SJoseph Chen { 69423ba6841SJoseph Chen /* switch for be. */ 69523ba6841SJoseph Chen header->resource_ptn_version = switch_short(header->resource_ptn_version); 69623ba6841SJoseph Chen header->index_tbl_version = switch_short(header->index_tbl_version); 69723ba6841SJoseph Chen header->tbl_entry_num = switch_int(header->tbl_entry_num); 69823ba6841SJoseph Chen } 69923ba6841SJoseph Chen 70023ba6841SJoseph Chen static void fix_entry(index_tbl_entry *entry) 70123ba6841SJoseph Chen { 70223ba6841SJoseph Chen /* switch for be. */ 70323ba6841SJoseph Chen entry->content_offset = switch_int(entry->content_offset); 70423ba6841SJoseph Chen entry->content_size = switch_int(entry->content_size); 70523ba6841SJoseph Chen } 70623ba6841SJoseph Chen 70723ba6841SJoseph Chen static int inline get_ptn_offset(void) 70823ba6841SJoseph Chen { 70923ba6841SJoseph Chen return 0; 71023ba6841SJoseph Chen } 71123ba6841SJoseph Chen 71223ba6841SJoseph Chen static bool StorageWriteLba(int offset_block, void *data, int blocks) 71323ba6841SJoseph Chen { 71423ba6841SJoseph Chen bool ret = false; 71523ba6841SJoseph Chen FILE *file = fopen(image_path, "rb+"); 71623ba6841SJoseph Chen if (!file) 71723ba6841SJoseph Chen goto end; 71823ba6841SJoseph Chen int offset = offset_block * BLOCK_SIZE; 71923ba6841SJoseph Chen fseek(file, offset, SEEK_SET); 72023ba6841SJoseph Chen if (offset != ftell(file)) { 72123ba6841SJoseph Chen LOGE("Failed to seek %s to %d!", image_path, offset); 72223ba6841SJoseph Chen goto end; 72323ba6841SJoseph Chen } 72423ba6841SJoseph Chen if (!fwrite(data, blocks * BLOCK_SIZE, 1, file)) { 72523ba6841SJoseph Chen LOGE("Failed to write %s!", image_path); 72623ba6841SJoseph Chen goto end; 72723ba6841SJoseph Chen } 72823ba6841SJoseph Chen ret = true; 72923ba6841SJoseph Chen end: 73023ba6841SJoseph Chen if (file) 73123ba6841SJoseph Chen fclose(file); 73223ba6841SJoseph Chen return ret; 73323ba6841SJoseph Chen } 73423ba6841SJoseph Chen 73523ba6841SJoseph Chen static bool StorageReadLba(int offset_block, void *data, int blocks) 73623ba6841SJoseph Chen { 73723ba6841SJoseph Chen bool ret = false; 73823ba6841SJoseph Chen FILE *file = fopen(image_path, "rb"); 73923ba6841SJoseph Chen if (!file) 74023ba6841SJoseph Chen goto end; 74123ba6841SJoseph Chen int offset = offset_block * BLOCK_SIZE; 74223ba6841SJoseph Chen fseek(file, offset, SEEK_SET); 74323ba6841SJoseph Chen if (offset != ftell(file)) { 74423ba6841SJoseph Chen goto end; 74523ba6841SJoseph Chen } 74623ba6841SJoseph Chen if (!fread(data, blocks * BLOCK_SIZE, 1, file)) { 74723ba6841SJoseph Chen goto end; 74823ba6841SJoseph Chen } 74923ba6841SJoseph Chen ret = true; 75023ba6841SJoseph Chen end: 75123ba6841SJoseph Chen if (file) 75223ba6841SJoseph Chen fclose(file); 75323ba6841SJoseph Chen return ret; 75423ba6841SJoseph Chen } 75523ba6841SJoseph Chen 75623ba6841SJoseph Chen static bool write_data(int offset_block, void *data, size_t len) 75723ba6841SJoseph Chen { 75823ba6841SJoseph Chen bool ret = false; 75923ba6841SJoseph Chen if (!data) 76023ba6841SJoseph Chen goto end; 76123ba6841SJoseph Chen int blocks = len / BLOCK_SIZE; 76223ba6841SJoseph Chen if (blocks && !StorageWriteLba(offset_block, data, blocks)) { 76323ba6841SJoseph Chen goto end; 76423ba6841SJoseph Chen } 76523ba6841SJoseph Chen int left = len % BLOCK_SIZE; 76623ba6841SJoseph Chen if (left) { 76723ba6841SJoseph Chen char buf[BLOCK_SIZE] = "\0"; 76823ba6841SJoseph Chen memcpy(buf, data + blocks * BLOCK_SIZE, left); 76923ba6841SJoseph Chen if (!StorageWriteLba(offset_block + blocks, buf, 1)) 77023ba6841SJoseph Chen goto end; 77123ba6841SJoseph Chen } 77223ba6841SJoseph Chen ret = true; 77323ba6841SJoseph Chen end: 77423ba6841SJoseph Chen return ret; 77523ba6841SJoseph Chen } 77623ba6841SJoseph Chen 77723ba6841SJoseph Chen /**********************load test************************/ 77823ba6841SJoseph Chen static int load_file(const char *file_path, int offset_block, int blocks); 77923ba6841SJoseph Chen 78023ba6841SJoseph Chen static int test_load(int argc, char **argv) 78123ba6841SJoseph Chen { 78223ba6841SJoseph Chen if (argc < 1) { 78323ba6841SJoseph Chen LOGE("Nothing to load!"); 78423ba6841SJoseph Chen return -1; 78523ba6841SJoseph Chen } 78623ba6841SJoseph Chen const char *file_path; 78723ba6841SJoseph Chen int offset_block = 0; 78823ba6841SJoseph Chen int blocks = 0; 78923ba6841SJoseph Chen if (argc > 0) { 79023ba6841SJoseph Chen file_path = (const char *)fix_path(argv[0]); 79123ba6841SJoseph Chen argc--, argv++; 79223ba6841SJoseph Chen } 79323ba6841SJoseph Chen if (argc > 0) { 79423ba6841SJoseph Chen offset_block = atoi(argv[0]); 79523ba6841SJoseph Chen argc--, argv++; 79623ba6841SJoseph Chen } 79723ba6841SJoseph Chen if (argc > 0) { 79823ba6841SJoseph Chen blocks = atoi(argv[0]); 79923ba6841SJoseph Chen } 80023ba6841SJoseph Chen return load_file(file_path, offset_block, blocks); 80123ba6841SJoseph Chen } 80223ba6841SJoseph Chen 80323ba6841SJoseph Chen static void free_content(resource_content *content) 80423ba6841SJoseph Chen { 80523ba6841SJoseph Chen if (content->load_addr) { 80623ba6841SJoseph Chen free(content->load_addr); 80723ba6841SJoseph Chen content->load_addr = 0; 80823ba6841SJoseph Chen } 80923ba6841SJoseph Chen } 81023ba6841SJoseph Chen 81123ba6841SJoseph Chen static void tests_dump_file(const char *path, void *data, int len) 81223ba6841SJoseph Chen { 81323ba6841SJoseph Chen FILE *file = fopen(path, "wb"); 81423ba6841SJoseph Chen if (!file) 81523ba6841SJoseph Chen return; 81623ba6841SJoseph Chen fwrite(data, len, 1, file); 81723ba6841SJoseph Chen fclose(file); 81823ba6841SJoseph Chen } 81923ba6841SJoseph Chen 82023ba6841SJoseph Chen static bool load_content(resource_content *content) 82123ba6841SJoseph Chen { 82223ba6841SJoseph Chen if (content->load_addr) 82323ba6841SJoseph Chen return true; 82423ba6841SJoseph Chen int blocks = fix_blocks(content->content_size); 82523ba6841SJoseph Chen content->load_addr = malloc(blocks * BLOCK_SIZE); 82623ba6841SJoseph Chen if (!content->load_addr) 82723ba6841SJoseph Chen return false; 82823ba6841SJoseph Chen if (!StorageReadLba(get_ptn_offset() + content->content_offset, 82923ba6841SJoseph Chen content->load_addr, blocks)) { 83023ba6841SJoseph Chen free_content(content); 83123ba6841SJoseph Chen return false; 83223ba6841SJoseph Chen } 83323ba6841SJoseph Chen 83423ba6841SJoseph Chen tests_dump_file(content->path, content->load_addr, content->content_size); 83523ba6841SJoseph Chen return true; 83623ba6841SJoseph Chen } 83723ba6841SJoseph Chen 83823ba6841SJoseph Chen static bool load_content_data(resource_content *content, int offset_block, 83923ba6841SJoseph Chen void *data, int blocks) 84023ba6841SJoseph Chen { 84123ba6841SJoseph Chen if (!StorageReadLba(get_ptn_offset() + content->content_offset + offset_block, 84223ba6841SJoseph Chen data, blocks)) { 84323ba6841SJoseph Chen return false; 84423ba6841SJoseph Chen } 84523ba6841SJoseph Chen tests_dump_file(content->path, data, blocks * BLOCK_SIZE); 84623ba6841SJoseph Chen return true; 84723ba6841SJoseph Chen } 84823ba6841SJoseph Chen 84923ba6841SJoseph Chen static bool get_entry(const char *file_path, index_tbl_entry *entry) 85023ba6841SJoseph Chen { 85123ba6841SJoseph Chen bool ret = false; 85223ba6841SJoseph Chen char buf[BLOCK_SIZE]; 85323ba6841SJoseph Chen resource_ptn_header header; 85423ba6841SJoseph Chen if (!StorageReadLba(get_ptn_offset(), buf, 1)) { 85523ba6841SJoseph Chen LOGE("Failed to read header!"); 85623ba6841SJoseph Chen goto end; 85723ba6841SJoseph Chen } 85823ba6841SJoseph Chen memcpy(&header, buf, sizeof(header)); 85923ba6841SJoseph Chen 86023ba6841SJoseph Chen if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) { 86123ba6841SJoseph Chen LOGE("Not a resource image(%s)!", image_path); 86223ba6841SJoseph Chen goto end; 86323ba6841SJoseph Chen } 86423ba6841SJoseph Chen /* test on pc, switch for be. */ 86523ba6841SJoseph Chen fix_header(&header); 86623ba6841SJoseph Chen 86723ba6841SJoseph Chen /* TODO: support header_size & tbl_entry_size */ 86823ba6841SJoseph Chen if (header.resource_ptn_version != RESOURCE_PTN_VERSION || 86923ba6841SJoseph Chen header.header_size != RESOURCE_PTN_HDR_SIZE || 87023ba6841SJoseph Chen header.index_tbl_version != INDEX_TBL_VERSION || 87123ba6841SJoseph Chen header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) { 87223ba6841SJoseph Chen LOGE("Not supported in this version!"); 87323ba6841SJoseph Chen goto end; 87423ba6841SJoseph Chen } 87523ba6841SJoseph Chen 87623ba6841SJoseph Chen int i; 87723ba6841SJoseph Chen for (i = 0; i < header.tbl_entry_num; i++) { 87823ba6841SJoseph Chen /* TODO: support tbl_entry_size */ 87923ba6841SJoseph Chen if (!StorageReadLba( 88023ba6841SJoseph Chen get_ptn_offset() + header.header_size + i * header.tbl_entry_size, 88123ba6841SJoseph Chen buf, 1)) { 88223ba6841SJoseph Chen LOGE("Failed to read index entry:%d!", i); 88323ba6841SJoseph Chen goto end; 88423ba6841SJoseph Chen } 88523ba6841SJoseph Chen memcpy(entry, buf, sizeof(*entry)); 88623ba6841SJoseph Chen 88723ba6841SJoseph Chen if (memcmp(entry->tag, INDEX_TBL_ENTR_TAG, sizeof(entry->tag))) { 88823ba6841SJoseph Chen LOGE("Something wrong with index entry:%d!", i); 88923ba6841SJoseph Chen goto end; 89023ba6841SJoseph Chen } 89123ba6841SJoseph Chen 89223ba6841SJoseph Chen if (!strncmp(entry->path, file_path, sizeof(entry->path))) 89323ba6841SJoseph Chen break; 89423ba6841SJoseph Chen } 89523ba6841SJoseph Chen if (i == header.tbl_entry_num) { 89623ba6841SJoseph Chen LOGE("Cannot find %s!", file_path); 89723ba6841SJoseph Chen goto end; 89823ba6841SJoseph Chen } 89923ba6841SJoseph Chen /* test on pc, switch for be. */ 90023ba6841SJoseph Chen fix_entry(entry); 90123ba6841SJoseph Chen 90223ba6841SJoseph Chen printf("Found entry:\n\tpath:%s\n\toffset:%d\tsize:%d\n", entry->path, 90323ba6841SJoseph Chen entry->content_offset, entry->content_size); 90423ba6841SJoseph Chen 90523ba6841SJoseph Chen ret = true; 90623ba6841SJoseph Chen end: 90723ba6841SJoseph Chen return ret; 90823ba6841SJoseph Chen } 90923ba6841SJoseph Chen 91023ba6841SJoseph Chen static bool get_content(resource_content *content) 91123ba6841SJoseph Chen { 91223ba6841SJoseph Chen bool ret = false; 91323ba6841SJoseph Chen index_tbl_entry entry; 91423ba6841SJoseph Chen if (!get_entry(content->path, &entry)) 91523ba6841SJoseph Chen goto end; 91623ba6841SJoseph Chen content->content_offset = entry.content_offset; 91723ba6841SJoseph Chen content->content_size = entry.content_size; 91823ba6841SJoseph Chen ret = true; 91923ba6841SJoseph Chen end: 92023ba6841SJoseph Chen return ret; 92123ba6841SJoseph Chen } 92223ba6841SJoseph Chen 92323ba6841SJoseph Chen static int load_file(const char *file_path, int offset_block, int blocks) 92423ba6841SJoseph Chen { 92523ba6841SJoseph Chen printf("Try to load:%s", file_path); 92623ba6841SJoseph Chen if (blocks) { 92723ba6841SJoseph Chen printf(", offset block:%d, blocks:%d\n", offset_block, blocks); 92823ba6841SJoseph Chen } else { 92923ba6841SJoseph Chen printf("\n"); 93023ba6841SJoseph Chen } 93123ba6841SJoseph Chen bool ret = false; 93223ba6841SJoseph Chen resource_content content; 93323ba6841SJoseph Chen snprintf(content.path, sizeof(content.path), "%s", file_path); 93423ba6841SJoseph Chen content.load_addr = 0; 93523ba6841SJoseph Chen if (!get_content(&content)) { 93623ba6841SJoseph Chen goto end; 93723ba6841SJoseph Chen } 93823ba6841SJoseph Chen if (!blocks) { 93923ba6841SJoseph Chen if (!load_content(&content)) { 94023ba6841SJoseph Chen goto end; 94123ba6841SJoseph Chen } 94223ba6841SJoseph Chen } else { 94323ba6841SJoseph Chen void *data = malloc(blocks * BLOCK_SIZE); 94423ba6841SJoseph Chen if (!data) 94523ba6841SJoseph Chen goto end; 94623ba6841SJoseph Chen if (!load_content_data(&content, offset_block, data, blocks)) { 94723ba6841SJoseph Chen goto end; 94823ba6841SJoseph Chen } 94923ba6841SJoseph Chen } 95023ba6841SJoseph Chen ret = true; 95123ba6841SJoseph Chen end: 95223ba6841SJoseph Chen free_content(&content); 95323ba6841SJoseph Chen return ret; 95423ba6841SJoseph Chen } 95523ba6841SJoseph Chen 95623ba6841SJoseph Chen /**********************load test end************************/ 95723ba6841SJoseph Chen /**********************anim test************************/ 95823ba6841SJoseph Chen 95923ba6841SJoseph Chen static bool parse_level_conf(const char *arg, anim_level_conf *level_conf) 96023ba6841SJoseph Chen { 96123ba6841SJoseph Chen memset(level_conf, 0, sizeof(anim_level_conf)); 96223ba6841SJoseph Chen char *buf = NULL; 96323ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_CONF); 96423ba6841SJoseph Chen if (buf) { 96523ba6841SJoseph Chen level_conf->max_level = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_CONF)); 96623ba6841SJoseph Chen } else { 96723ba6841SJoseph Chen LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_CONF); 96823ba6841SJoseph Chen return false; 96923ba6841SJoseph Chen } 97023ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_NUM); 97123ba6841SJoseph Chen if (buf) { 97223ba6841SJoseph Chen level_conf->num = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_NUM)); 97323ba6841SJoseph Chen if (level_conf->num <= 0) { 97423ba6841SJoseph Chen return false; 97523ba6841SJoseph Chen } 97623ba6841SJoseph Chen } else { 97723ba6841SJoseph Chen LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_NUM); 97823ba6841SJoseph Chen return false; 97923ba6841SJoseph Chen } 98023ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_DELAY); 98123ba6841SJoseph Chen if (buf) { 98223ba6841SJoseph Chen level_conf->delay = atoi(buf + strlen(OPT_CHARGE_ANIM_DELAY)); 98323ba6841SJoseph Chen } 98423ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_PFX); 98523ba6841SJoseph Chen if (buf) { 98623ba6841SJoseph Chen snprintf(level_conf->prefix, sizeof(level_conf->prefix), "%s", 98723ba6841SJoseph Chen buf + strlen(OPT_CHARGE_ANIM_LEVEL_PFX)); 98823ba6841SJoseph Chen } else { 98923ba6841SJoseph Chen LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_PFX); 99023ba6841SJoseph Chen return false; 99123ba6841SJoseph Chen } 99223ba6841SJoseph Chen 99323ba6841SJoseph Chen LOGD("Found conf:\nmax_level:%d, num:%d, delay:%d, prefix:%s", 99423ba6841SJoseph Chen level_conf->max_level, level_conf->num, level_conf->delay, 99523ba6841SJoseph Chen level_conf->prefix); 99623ba6841SJoseph Chen return true; 99723ba6841SJoseph Chen } 99823ba6841SJoseph Chen 99923ba6841SJoseph Chen static int test_charge(int argc, char **argv) 100023ba6841SJoseph Chen { 100123ba6841SJoseph Chen const char *desc; 100223ba6841SJoseph Chen if (argc > 0) { 100323ba6841SJoseph Chen desc = argv[0]; 100423ba6841SJoseph Chen } else { 100523ba6841SJoseph Chen desc = DEF_CHARGE_DESC_PATH; 100623ba6841SJoseph Chen } 100723ba6841SJoseph Chen 100823ba6841SJoseph Chen resource_content content; 100923ba6841SJoseph Chen snprintf(content.path, sizeof(content.path), "%s", desc); 101023ba6841SJoseph Chen content.load_addr = 0; 101123ba6841SJoseph Chen if (!get_content(&content)) { 101223ba6841SJoseph Chen goto end; 101323ba6841SJoseph Chen } 101423ba6841SJoseph Chen if (!load_content(&content)) { 101523ba6841SJoseph Chen goto end; 101623ba6841SJoseph Chen } 101723ba6841SJoseph Chen 101823ba6841SJoseph Chen char *buf = (char *)content.load_addr; 101923ba6841SJoseph Chen char *end = buf + content.content_size - 1; 102023ba6841SJoseph Chen *end = '\0'; 102123ba6841SJoseph Chen LOGD("desc:\n%s", buf); 102223ba6841SJoseph Chen 102323ba6841SJoseph Chen int pos = 0; 102423ba6841SJoseph Chen while (1) { 102523ba6841SJoseph Chen char *line = (char *)memchr(buf + pos, '\n', strlen(buf + pos)); 102623ba6841SJoseph Chen if (!line) 102723ba6841SJoseph Chen break; 102823ba6841SJoseph Chen *line = '\0'; 102923ba6841SJoseph Chen LOGD("splite:%s", buf + pos); 103023ba6841SJoseph Chen pos += (strlen(buf + pos) + 1); 103123ba6841SJoseph Chen } 103223ba6841SJoseph Chen 103323ba6841SJoseph Chen int delay = 900; 103423ba6841SJoseph Chen int only_current_level = false; 103523ba6841SJoseph Chen anim_level_conf *level_confs = NULL; 103623ba6841SJoseph Chen int level_conf_pos = 0; 103723ba6841SJoseph Chen int level_conf_num = 0; 103823ba6841SJoseph Chen 103923ba6841SJoseph Chen while (true) { 104023ba6841SJoseph Chen if (buf >= end) 104123ba6841SJoseph Chen break; 104223ba6841SJoseph Chen const char *arg = buf; 104323ba6841SJoseph Chen buf += (strlen(buf) + 1); 104423ba6841SJoseph Chen 104523ba6841SJoseph Chen LOGD("parse arg:%s", arg); 104623ba6841SJoseph Chen if (!memcmp(arg, OPT_CHARGE_ANIM_LEVEL_CONF, 104723ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_LEVEL_CONF))) { 104823ba6841SJoseph Chen if (!level_confs) { 104923ba6841SJoseph Chen LOGE("Found level conf before levels!"); 105023ba6841SJoseph Chen goto end; 105123ba6841SJoseph Chen } 105223ba6841SJoseph Chen if (level_conf_pos >= level_conf_num) { 105323ba6841SJoseph Chen LOGE("Too many level confs!(%d >= %d)", level_conf_pos, level_conf_num); 105423ba6841SJoseph Chen goto end; 105523ba6841SJoseph Chen } 105623ba6841SJoseph Chen if (!parse_level_conf(arg, level_confs + level_conf_pos)) { 105723ba6841SJoseph Chen LOGE("Failed to parse level conf:%s", arg); 105823ba6841SJoseph Chen goto end; 105923ba6841SJoseph Chen } 106023ba6841SJoseph Chen level_conf_pos++; 106123ba6841SJoseph Chen } else if (!memcmp(arg, OPT_CHARGE_ANIM_DELAY, 106223ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_DELAY))) { 106323ba6841SJoseph Chen delay = atoi(arg + strlen(OPT_CHARGE_ANIM_DELAY)); 106423ba6841SJoseph Chen LOGD("Found delay:%d", delay); 106523ba6841SJoseph Chen } else if (!memcmp(arg, OPT_CHARGE_ANIM_LOOP_CUR, 106623ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_LOOP_CUR))) { 106723ba6841SJoseph Chen only_current_level = 106823ba6841SJoseph Chen !memcmp(arg + strlen(OPT_CHARGE_ANIM_LOOP_CUR), "true", 4); 106923ba6841SJoseph Chen LOGD("Found only_current_level:%d", only_current_level); 107023ba6841SJoseph Chen } else if (!memcmp(arg, OPT_CHARGE_ANIM_LEVELS, 107123ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_LEVELS))) { 107223ba6841SJoseph Chen if (level_conf_num) { 107323ba6841SJoseph Chen goto end; 107423ba6841SJoseph Chen } 107523ba6841SJoseph Chen level_conf_num = atoi(arg + strlen(OPT_CHARGE_ANIM_LEVELS)); 107623ba6841SJoseph Chen if (!level_conf_num) { 107723ba6841SJoseph Chen goto end; 107823ba6841SJoseph Chen } 107923ba6841SJoseph Chen level_confs = 108023ba6841SJoseph Chen (anim_level_conf *)malloc(level_conf_num * sizeof(anim_level_conf)); 108123ba6841SJoseph Chen LOGD("Found levels:%d", level_conf_num); 108223ba6841SJoseph Chen } else { 108323ba6841SJoseph Chen LOGE("Unknown arg:%s", arg); 108423ba6841SJoseph Chen goto end; 108523ba6841SJoseph Chen } 108623ba6841SJoseph Chen } 108723ba6841SJoseph Chen 108823ba6841SJoseph Chen if (level_conf_pos != level_conf_num || !level_conf_num) { 108923ba6841SJoseph Chen LOGE("Something wrong with level confs!"); 109023ba6841SJoseph Chen goto end; 109123ba6841SJoseph Chen } 109223ba6841SJoseph Chen 109323ba6841SJoseph Chen int i = 0, j = 0; 109423ba6841SJoseph Chen for (i = 0; i < level_conf_num; i++) { 109523ba6841SJoseph Chen if (!level_confs[i].delay) { 109623ba6841SJoseph Chen level_confs[i].delay = delay; 109723ba6841SJoseph Chen } 109823ba6841SJoseph Chen if (!level_confs[i].delay) { 109923ba6841SJoseph Chen LOGE("Missing delay in level conf:%d", i); 110023ba6841SJoseph Chen goto end; 110123ba6841SJoseph Chen } 110223ba6841SJoseph Chen for (j = 0; j < i; j++) { 110323ba6841SJoseph Chen if (level_confs[j].max_level == level_confs[i].max_level) { 110423ba6841SJoseph Chen LOGE("Dup level conf:%d", i); 110523ba6841SJoseph Chen goto end; 110623ba6841SJoseph Chen } 110723ba6841SJoseph Chen if (level_confs[j].max_level > level_confs[i].max_level) { 110823ba6841SJoseph Chen anim_level_conf conf = level_confs[i]; 110923ba6841SJoseph Chen memmove(level_confs + j + 1, level_confs + j, 111023ba6841SJoseph Chen (i - j) * sizeof(anim_level_conf)); 111123ba6841SJoseph Chen level_confs[j] = conf; 111223ba6841SJoseph Chen } 111323ba6841SJoseph Chen } 111423ba6841SJoseph Chen } 111523ba6841SJoseph Chen 111623ba6841SJoseph Chen printf("Parse anim desc(%s):\n", desc); 111723ba6841SJoseph Chen printf("only_current_level=%d\n", only_current_level); 111823ba6841SJoseph Chen printf("level conf:\n"); 111923ba6841SJoseph Chen for (i = 0; i < level_conf_num; i++) { 112023ba6841SJoseph Chen printf("\tmax=%d, delay=%d, num=%d, prefix=%s\n", level_confs[i].max_level, 112123ba6841SJoseph Chen level_confs[i].delay, level_confs[i].num, level_confs[i].prefix); 112223ba6841SJoseph Chen } 112323ba6841SJoseph Chen 112423ba6841SJoseph Chen end: 112523ba6841SJoseph Chen free_content(&content); 112623ba6841SJoseph Chen return 0; 112723ba6841SJoseph Chen } 112823ba6841SJoseph Chen 112923ba6841SJoseph Chen /**********************anim test end************************/ 113023ba6841SJoseph Chen /**********************append file************************/ 113123ba6841SJoseph Chen 113223ba6841SJoseph Chen static const char *PROG = NULL; 113323ba6841SJoseph Chen static resource_ptn_header header; 113423ba6841SJoseph Chen static bool just_print = false; 113523ba6841SJoseph Chen static char root_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0"; 113623ba6841SJoseph Chen 113723ba6841SJoseph Chen static void version(void) 113823ba6841SJoseph Chen { 113923ba6841SJoseph Chen printf("%s (cjf@rock-chips.com)\t" VERSION "\n", PROG); 114023ba6841SJoseph Chen } 114123ba6841SJoseph Chen 114223ba6841SJoseph Chen static void usage(void) 114323ba6841SJoseph Chen { 114423ba6841SJoseph Chen printf("Usage: %s [options] [FILES]\n", PROG); 114523ba6841SJoseph Chen printf("Tools for Rockchip's resource image.\n"); 114623ba6841SJoseph Chen version(); 114723ba6841SJoseph Chen printf("Options:\n"); 114823ba6841SJoseph Chen printf("\t" OPT_PACK "\t\t\tPack image from given files.\n"); 114923ba6841SJoseph Chen printf("\t" OPT_UNPACK "\t\tUnpack given image to current dir.\n"); 115023ba6841SJoseph Chen printf("\t" OPT_IMAGE "path" 115123ba6841SJoseph Chen "\t\tSpecify input/output image path.\n"); 115223ba6841SJoseph Chen printf("\t" OPT_PRINT "\t\t\tJust print informations.\n"); 115323ba6841SJoseph Chen printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n"); 115423ba6841SJoseph Chen printf("\t" OPT_HELP "\t\t\tDisplay this information.\n"); 115523ba6841SJoseph Chen printf("\t" OPT_VERSION "\t\tDisplay version information.\n"); 115623ba6841SJoseph Chen printf("\t" OPT_ROOT "path" 115723ba6841SJoseph Chen "\t\tSpecify resources' root dir.\n"); 115823ba6841SJoseph Chen } 115923ba6841SJoseph Chen 116023ba6841SJoseph Chen static int pack_image(int file_num, const char **files); 116123ba6841SJoseph Chen static int unpack_image(const char *unpack_dir); 116223ba6841SJoseph Chen 116323ba6841SJoseph Chen enum ACTION { 116423ba6841SJoseph Chen ACTION_PACK, 116523ba6841SJoseph Chen ACTION_UNPACK, 116623ba6841SJoseph Chen ACTION_TEST_LOAD, 116723ba6841SJoseph Chen ACTION_TEST_CHARGE, 116823ba6841SJoseph Chen }; 116923ba6841SJoseph Chen 117023ba6841SJoseph Chen int main(int argc, char **argv) 117123ba6841SJoseph Chen { 117223ba6841SJoseph Chen PROG = fix_path(argv[0]); 117323ba6841SJoseph Chen 117423ba6841SJoseph Chen enum ACTION action = ACTION_PACK; 117523ba6841SJoseph Chen 117623ba6841SJoseph Chen argc--, argv++; 117723ba6841SJoseph Chen while (argc > 0 && argv[0][0] == '-') { 117823ba6841SJoseph Chen /* it's a opt arg. */ 117923ba6841SJoseph Chen const char *arg = argv[0]; 118023ba6841SJoseph Chen argc--, argv++; 118123ba6841SJoseph Chen if (!strcmp(OPT_VERBOSE, arg)) { 118223ba6841SJoseph Chen g_debug = true; 118323ba6841SJoseph Chen } else if (!strcmp(OPT_HELP, arg)) { 118423ba6841SJoseph Chen usage(); 118523ba6841SJoseph Chen return 0; 118623ba6841SJoseph Chen } else if (!strcmp(OPT_VERSION, arg)) { 118723ba6841SJoseph Chen version(); 118823ba6841SJoseph Chen return 0; 118923ba6841SJoseph Chen } else if (!strcmp(OPT_PRINT, arg)) { 119023ba6841SJoseph Chen just_print = true; 119123ba6841SJoseph Chen } else if (!strcmp(OPT_PACK, arg)) { 119223ba6841SJoseph Chen action = ACTION_PACK; 119323ba6841SJoseph Chen } else if (!strcmp(OPT_UNPACK, arg)) { 119423ba6841SJoseph Chen action = ACTION_UNPACK; 119523ba6841SJoseph Chen } else if (!strcmp(OPT_TEST_LOAD, arg)) { 119623ba6841SJoseph Chen action = ACTION_TEST_LOAD; 119723ba6841SJoseph Chen } else if (!strcmp(OPT_TEST_CHARGE, arg)) { 119823ba6841SJoseph Chen action = ACTION_TEST_CHARGE; 119923ba6841SJoseph Chen } else if (!memcmp(OPT_IMAGE, arg, strlen(OPT_IMAGE))) { 120023ba6841SJoseph Chen snprintf(image_path, sizeof(image_path), "%s", arg + strlen(OPT_IMAGE)); 120123ba6841SJoseph Chen } else if (!memcmp(OPT_ROOT, arg, strlen(OPT_ROOT))) { 120223ba6841SJoseph Chen snprintf(root_path, sizeof(root_path), "%s", arg + strlen(OPT_ROOT)); 120323ba6841SJoseph Chen } else { 120423ba6841SJoseph Chen LOGE("Unknown opt:%s", arg); 120523ba6841SJoseph Chen usage(); 120623ba6841SJoseph Chen return -1; 120723ba6841SJoseph Chen } 120823ba6841SJoseph Chen } 120923ba6841SJoseph Chen 121023ba6841SJoseph Chen if (!image_path[0]) { 121123ba6841SJoseph Chen snprintf(image_path, sizeof(image_path), "%s", DEFAULT_IMAGE_PATH); 121223ba6841SJoseph Chen } 121323ba6841SJoseph Chen 121423ba6841SJoseph Chen switch (action) { 121523ba6841SJoseph Chen case ACTION_PACK: { 121623ba6841SJoseph Chen int file_num = argc; 121723ba6841SJoseph Chen const char **files = (const char **)argv; 121823ba6841SJoseph Chen if (!file_num) { 121923ba6841SJoseph Chen LOGE("No file to pack!"); 122023ba6841SJoseph Chen return 0; 122123ba6841SJoseph Chen } 122223ba6841SJoseph Chen LOGD("try to pack %d files.", file_num); 122323ba6841SJoseph Chen return pack_image(file_num, files); 122423ba6841SJoseph Chen } 122523ba6841SJoseph Chen case ACTION_UNPACK: { 122623ba6841SJoseph Chen return unpack_image(argc > 0 ? argv[0] : DEFAULT_UNPACK_DIR); 122723ba6841SJoseph Chen } 122823ba6841SJoseph Chen case ACTION_TEST_LOAD: { 122923ba6841SJoseph Chen return test_load(argc, argv); 123023ba6841SJoseph Chen } 123123ba6841SJoseph Chen case ACTION_TEST_CHARGE: { 123223ba6841SJoseph Chen return test_charge(argc, argv); 123323ba6841SJoseph Chen } 123423ba6841SJoseph Chen } 123523ba6841SJoseph Chen /* not reach here. */ 123623ba6841SJoseph Chen return -1; 123723ba6841SJoseph Chen } 123823ba6841SJoseph Chen 123923ba6841SJoseph Chen /************unpack code****************/ 124023ba6841SJoseph Chen static bool mkdirs(char *path) 124123ba6841SJoseph Chen { 124223ba6841SJoseph Chen char *tmp = path; 124323ba6841SJoseph Chen char *pos = NULL; 124423ba6841SJoseph Chen char buf[MAX_INDEX_ENTRY_PATH_LEN]; 124523ba6841SJoseph Chen bool ret = true; 124623ba6841SJoseph Chen while ((pos = memchr(tmp, '/', strlen(tmp)))) { 124723ba6841SJoseph Chen strcpy(buf, path); 124823ba6841SJoseph Chen buf[pos - path] = '\0'; 124923ba6841SJoseph Chen tmp = pos + 1; 125023ba6841SJoseph Chen LOGD("mkdir:%s", buf); 125123ba6841SJoseph Chen if (!mkdir(buf, 0755)) { 125223ba6841SJoseph Chen ret = false; 125323ba6841SJoseph Chen } 125423ba6841SJoseph Chen } 125523ba6841SJoseph Chen if (!ret) 125623ba6841SJoseph Chen LOGD("Failed to mkdir(%s)!", path); 125723ba6841SJoseph Chen return ret; 125823ba6841SJoseph Chen } 125923ba6841SJoseph Chen 126023ba6841SJoseph Chen static bool dump_file(FILE *file, const char *unpack_dir, 126123ba6841SJoseph Chen index_tbl_entry entry) 126223ba6841SJoseph Chen { 126323ba6841SJoseph Chen LOGD("try to dump entry:%s", entry.path); 126423ba6841SJoseph Chen bool ret = false; 126523ba6841SJoseph Chen FILE *out_file = NULL; 126623ba6841SJoseph Chen long int pos = 0; 126723ba6841SJoseph Chen char path[MAX_INDEX_ENTRY_PATH_LEN * 2 + 1]; 126823ba6841SJoseph Chen if (just_print) { 126923ba6841SJoseph Chen ret = true; 127023ba6841SJoseph Chen goto done; 127123ba6841SJoseph Chen } 127223ba6841SJoseph Chen 127323ba6841SJoseph Chen pos = ftell(file); 127423ba6841SJoseph Chen snprintf(path, sizeof(path), "%s/%s", unpack_dir, entry.path); 127523ba6841SJoseph Chen mkdirs(path); 127623ba6841SJoseph Chen out_file = fopen(path, "wb"); 127723ba6841SJoseph Chen if (!out_file) { 127823ba6841SJoseph Chen LOGE("Failed to create:%s", path); 127923ba6841SJoseph Chen goto end; 128023ba6841SJoseph Chen } 128123ba6841SJoseph Chen long int offset = entry.content_offset * BLOCK_SIZE; 128223ba6841SJoseph Chen fseek(file, offset, SEEK_SET); 128323ba6841SJoseph Chen if (offset != ftell(file)) { 128423ba6841SJoseph Chen LOGE("Failed to read content:%s", entry.path); 128523ba6841SJoseph Chen goto end; 128623ba6841SJoseph Chen } 128723ba6841SJoseph Chen char buf[BLOCK_SIZE]; 128823ba6841SJoseph Chen int n; 128923ba6841SJoseph Chen int len = entry.content_size; 129023ba6841SJoseph Chen while (len > 0) { 129123ba6841SJoseph Chen n = len > BLOCK_SIZE ? BLOCK_SIZE : len; 129223ba6841SJoseph Chen if (!fread(buf, n, 1, file)) { 129323ba6841SJoseph Chen LOGE("Failed to read content:%s", entry.path); 129423ba6841SJoseph Chen goto end; 129523ba6841SJoseph Chen } 129623ba6841SJoseph Chen if (!fwrite(buf, n, 1, out_file)) { 129723ba6841SJoseph Chen LOGE("Failed to write:%s", entry.path); 129823ba6841SJoseph Chen goto end; 129923ba6841SJoseph Chen } 130023ba6841SJoseph Chen len -= n; 130123ba6841SJoseph Chen } 130223ba6841SJoseph Chen done: 130323ba6841SJoseph Chen ret = true; 130423ba6841SJoseph Chen end: 130523ba6841SJoseph Chen if (out_file) 130623ba6841SJoseph Chen fclose(out_file); 130723ba6841SJoseph Chen if (pos) 130823ba6841SJoseph Chen fseek(file, pos, SEEK_SET); 130923ba6841SJoseph Chen return ret; 131023ba6841SJoseph Chen } 131123ba6841SJoseph Chen 131223ba6841SJoseph Chen static int unpack_image(const char *dir) 131323ba6841SJoseph Chen { 131423ba6841SJoseph Chen FILE *image_file = NULL; 131523ba6841SJoseph Chen bool ret = false; 131623ba6841SJoseph Chen char unpack_dir[MAX_INDEX_ENTRY_PATH_LEN]; 131723ba6841SJoseph Chen if (just_print) 131823ba6841SJoseph Chen dir = "."; 131923ba6841SJoseph Chen snprintf(unpack_dir, sizeof(unpack_dir), "%s", dir); 132023ba6841SJoseph Chen if (!strlen(unpack_dir)) { 132123ba6841SJoseph Chen goto end; 132223ba6841SJoseph Chen } else if (unpack_dir[strlen(unpack_dir) - 1] == '/') { 132323ba6841SJoseph Chen unpack_dir[strlen(unpack_dir) - 1] = '\0'; 132423ba6841SJoseph Chen } 132523ba6841SJoseph Chen 132623ba6841SJoseph Chen mkdir(unpack_dir, 0755); 132723ba6841SJoseph Chen image_file = fopen(image_path, "rb"); 132823ba6841SJoseph Chen char buf[BLOCK_SIZE]; 132923ba6841SJoseph Chen if (!image_file) { 133023ba6841SJoseph Chen LOGE("Failed to open:%s", image_path); 133123ba6841SJoseph Chen goto end; 133223ba6841SJoseph Chen } 133323ba6841SJoseph Chen if (!fread(buf, BLOCK_SIZE, 1, image_file)) { 133423ba6841SJoseph Chen LOGE("Failed to read header!"); 133523ba6841SJoseph Chen goto end; 133623ba6841SJoseph Chen } 133723ba6841SJoseph Chen memcpy(&header, buf, sizeof(header)); 133823ba6841SJoseph Chen 133923ba6841SJoseph Chen if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) { 134023ba6841SJoseph Chen LOGE("Not a resource image(%s)!", image_path); 134123ba6841SJoseph Chen goto end; 134223ba6841SJoseph Chen } 134323ba6841SJoseph Chen /* switch for be. */ 134423ba6841SJoseph Chen fix_header(&header); 134523ba6841SJoseph Chen 134623ba6841SJoseph Chen printf("Dump header:\n"); 134723ba6841SJoseph Chen printf("partition version:%d.%d\n", header.resource_ptn_version, 134823ba6841SJoseph Chen header.index_tbl_version); 134923ba6841SJoseph Chen printf("header size:%d\n", header.header_size); 135023ba6841SJoseph Chen printf("index tbl:\n\toffset:%d\tentry size:%d\tentry num:%d\n", 135123ba6841SJoseph Chen header.tbl_offset, header.tbl_entry_size, header.tbl_entry_num); 135223ba6841SJoseph Chen 135323ba6841SJoseph Chen /* TODO: support header_size & tbl_entry_size */ 135423ba6841SJoseph Chen if (header.resource_ptn_version != RESOURCE_PTN_VERSION || 135523ba6841SJoseph Chen header.header_size != RESOURCE_PTN_HDR_SIZE || 135623ba6841SJoseph Chen header.index_tbl_version != INDEX_TBL_VERSION || 135723ba6841SJoseph Chen header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) { 135823ba6841SJoseph Chen LOGE("Not supported in this version!"); 135923ba6841SJoseph Chen goto end; 136023ba6841SJoseph Chen } 136123ba6841SJoseph Chen 136223ba6841SJoseph Chen printf("Dump Index table:\n"); 136323ba6841SJoseph Chen index_tbl_entry entry; 136423ba6841SJoseph Chen int i; 136523ba6841SJoseph Chen for (i = 0; i < header.tbl_entry_num; i++) { 136623ba6841SJoseph Chen /* TODO: support tbl_entry_size */ 136723ba6841SJoseph Chen if (!fread(buf, BLOCK_SIZE, 1, image_file)) { 136823ba6841SJoseph Chen LOGE("Failed to read index entry:%d!", i); 136923ba6841SJoseph Chen goto end; 137023ba6841SJoseph Chen } 137123ba6841SJoseph Chen memcpy(&entry, buf, sizeof(entry)); 137223ba6841SJoseph Chen 137323ba6841SJoseph Chen if (memcmp(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag))) { 137423ba6841SJoseph Chen LOGE("Something wrong with index entry:%d!", i); 137523ba6841SJoseph Chen goto end; 137623ba6841SJoseph Chen } 137723ba6841SJoseph Chen /* switch for be. */ 137823ba6841SJoseph Chen fix_entry(&entry); 137923ba6841SJoseph Chen 138023ba6841SJoseph Chen printf("entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n", i, entry.path, 138123ba6841SJoseph Chen entry.content_offset, entry.content_size); 138223ba6841SJoseph Chen if (!dump_file(image_file, unpack_dir, entry)) { 138323ba6841SJoseph Chen goto end; 138423ba6841SJoseph Chen } 138523ba6841SJoseph Chen } 138623ba6841SJoseph Chen printf("Unack %s to %s successed!\n", image_path, unpack_dir); 138723ba6841SJoseph Chen ret = true; 138823ba6841SJoseph Chen end: 138923ba6841SJoseph Chen if (image_file) 139023ba6841SJoseph Chen fclose(image_file); 139123ba6841SJoseph Chen return ret ? 0 : -1; 139223ba6841SJoseph Chen } 139323ba6841SJoseph Chen 139423ba6841SJoseph Chen /************unpack code end****************/ 139523ba6841SJoseph Chen /************pack code****************/ 139623ba6841SJoseph Chen 139723ba6841SJoseph Chen static inline size_t get_file_size(const char *path) 139823ba6841SJoseph Chen { 139923ba6841SJoseph Chen LOGD("try to get size(%s)...", path); 140023ba6841SJoseph Chen struct stat st; 140123ba6841SJoseph Chen if (stat(path, &st) < 0) { 140223ba6841SJoseph Chen LOGE("Failed to get size:%s", path); 140323ba6841SJoseph Chen return -1; 140423ba6841SJoseph Chen } 140523ba6841SJoseph Chen LOGD("path:%s, size:%ld", path, st.st_size); 140623ba6841SJoseph Chen return st.st_size; 140723ba6841SJoseph Chen } 140823ba6841SJoseph Chen 14095e817a0eSJoseph Chen static int write_file(int offset_block, const char *src_path, 14105e817a0eSJoseph Chen char hash[], int hash_size) 141123ba6841SJoseph Chen { 141223ba6841SJoseph Chen LOGD("try to write file(%s) to offset:%d...", src_path, offset_block); 14135e817a0eSJoseph Chen char *buf = NULL; 141423ba6841SJoseph Chen int ret = -1; 141523ba6841SJoseph Chen size_t file_size; 141623ba6841SJoseph Chen FILE *src_file = fopen(src_path, "rb"); 141723ba6841SJoseph Chen if (!src_file) { 141823ba6841SJoseph Chen LOGE("Failed to open:%s", src_path); 141923ba6841SJoseph Chen goto end; 142023ba6841SJoseph Chen } 142123ba6841SJoseph Chen 142223ba6841SJoseph Chen file_size = get_file_size(src_path); 142323ba6841SJoseph Chen if (file_size < 0) { 142423ba6841SJoseph Chen goto end; 142523ba6841SJoseph Chen } 142623ba6841SJoseph Chen 14275e817a0eSJoseph Chen buf = calloc(file_size, 1); 14285e817a0eSJoseph Chen if (!buf) 142923ba6841SJoseph Chen goto end; 14305e817a0eSJoseph Chen 14315e817a0eSJoseph Chen if (!fread(buf, file_size, 1, src_file)) 143223ba6841SJoseph Chen goto end; 14335e817a0eSJoseph Chen 14345e817a0eSJoseph Chen if (!write_data(offset_block, buf, file_size)) 14355e817a0eSJoseph Chen goto end; 14365e817a0eSJoseph Chen 14375e817a0eSJoseph Chen if (hash_size == 20) 14385e817a0eSJoseph Chen sha1_csum((const unsigned char *)buf, file_size, 14395e817a0eSJoseph Chen (unsigned char *)hash); 14405e817a0eSJoseph Chen else if (hash_size == 32) 14415e817a0eSJoseph Chen sha256_csum((const unsigned char *)buf, file_size, 14425e817a0eSJoseph Chen (unsigned char *)hash); 14435e817a0eSJoseph Chen else 14445e817a0eSJoseph Chen goto end; 14455e817a0eSJoseph Chen 14465e817a0eSJoseph Chen ret = file_size; 144723ba6841SJoseph Chen end: 144823ba6841SJoseph Chen if (src_file) 144923ba6841SJoseph Chen fclose(src_file); 14505e817a0eSJoseph Chen if (buf) 14515e817a0eSJoseph Chen free(buf); 14525e817a0eSJoseph Chen 145323ba6841SJoseph Chen return ret; 145423ba6841SJoseph Chen } 145523ba6841SJoseph Chen 145623ba6841SJoseph Chen static bool write_header(const int file_num) 145723ba6841SJoseph Chen { 145823ba6841SJoseph Chen LOGD("try to write header..."); 145923ba6841SJoseph Chen memcpy(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic)); 146023ba6841SJoseph Chen header.resource_ptn_version = RESOURCE_PTN_VERSION; 146123ba6841SJoseph Chen header.index_tbl_version = INDEX_TBL_VERSION; 146223ba6841SJoseph Chen header.header_size = RESOURCE_PTN_HDR_SIZE; 146323ba6841SJoseph Chen header.tbl_offset = header.header_size; 146423ba6841SJoseph Chen header.tbl_entry_size = INDEX_TBL_ENTR_SIZE; 146523ba6841SJoseph Chen header.tbl_entry_num = file_num; 146623ba6841SJoseph Chen 146723ba6841SJoseph Chen /* switch for le. */ 146823ba6841SJoseph Chen resource_ptn_header hdr = header; 146923ba6841SJoseph Chen fix_header(&hdr); 147023ba6841SJoseph Chen return write_data(0, &hdr, sizeof(hdr)); 147123ba6841SJoseph Chen } 147223ba6841SJoseph Chen 147323ba6841SJoseph Chen static bool write_index_tbl(const int file_num, const char **files) 147423ba6841SJoseph Chen { 147523ba6841SJoseph Chen LOGD("try to write index table..."); 147623ba6841SJoseph Chen bool ret = false; 147723ba6841SJoseph Chen bool foundFdt = false; 147823ba6841SJoseph Chen int offset = 147923ba6841SJoseph Chen header.header_size + header.tbl_entry_size * header.tbl_entry_num; 148023ba6841SJoseph Chen index_tbl_entry entry; 14815e817a0eSJoseph Chen char hash[20]; /* sha1 */ 148223ba6841SJoseph Chen int i; 14835e817a0eSJoseph Chen 14845e817a0eSJoseph Chen memcpy(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag)); 148523ba6841SJoseph Chen for (i = 0; i < file_num; i++) { 148623ba6841SJoseph Chen size_t file_size = get_file_size(files[i]); 148723ba6841SJoseph Chen if (file_size < 0) 148823ba6841SJoseph Chen goto end; 148923ba6841SJoseph Chen entry.content_size = file_size; 149023ba6841SJoseph Chen entry.content_offset = offset; 149123ba6841SJoseph Chen 14925e817a0eSJoseph Chen if (write_file(offset, files[i], hash, sizeof(hash)) < 0) 149323ba6841SJoseph Chen goto end; 149423ba6841SJoseph Chen 14955e817a0eSJoseph Chen memcpy(entry.hash, hash, sizeof(hash)); 14965e817a0eSJoseph Chen entry.hash_size = sizeof(hash); 14975e817a0eSJoseph Chen 149823ba6841SJoseph Chen LOGD("try to write index entry(%s)...", files[i]); 149923ba6841SJoseph Chen 150023ba6841SJoseph Chen /* switch for le. */ 150123ba6841SJoseph Chen fix_entry(&entry); 150223ba6841SJoseph Chen memset(entry.path, 0, sizeof(entry.path)); 150323ba6841SJoseph Chen const char *path = files[i]; 150423ba6841SJoseph Chen if (root_path[0]) { 150523ba6841SJoseph Chen if (!strncmp(path, root_path, strlen(root_path))) { 150623ba6841SJoseph Chen path += strlen(root_path); 150723ba6841SJoseph Chen if (path[0] == '/') 150823ba6841SJoseph Chen path++; 150923ba6841SJoseph Chen } 151023ba6841SJoseph Chen } 151123ba6841SJoseph Chen path = fix_path(path); 151223ba6841SJoseph Chen if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) { 151323ba6841SJoseph Chen if (!foundFdt) { 151423ba6841SJoseph Chen /* use default path. */ 151523ba6841SJoseph Chen LOGD("mod fdt path:%s -> %s...", files[i], FDT_PATH); 151623ba6841SJoseph Chen path = FDT_PATH; 151723ba6841SJoseph Chen foundFdt = true; 151823ba6841SJoseph Chen } 151923ba6841SJoseph Chen } 152023ba6841SJoseph Chen snprintf(entry.path, sizeof(entry.path), "%s", path); 152123ba6841SJoseph Chen offset += fix_blocks(file_size); 152223ba6841SJoseph Chen if (!write_data(header.header_size + i * header.tbl_entry_size, &entry, 152323ba6841SJoseph Chen sizeof(entry))) 152423ba6841SJoseph Chen goto end; 152523ba6841SJoseph Chen } 152623ba6841SJoseph Chen ret = true; 152723ba6841SJoseph Chen end: 152823ba6841SJoseph Chen return ret; 152923ba6841SJoseph Chen } 153023ba6841SJoseph Chen 153123ba6841SJoseph Chen static int pack_image(int file_num, const char **files) 153223ba6841SJoseph Chen { 153323ba6841SJoseph Chen bool ret = false; 153423ba6841SJoseph Chen FILE *image_file = fopen(image_path, "wb"); 153523ba6841SJoseph Chen if (!image_file) { 153623ba6841SJoseph Chen LOGE("Failed to create:%s", image_path); 153723ba6841SJoseph Chen goto end; 153823ba6841SJoseph Chen } 153923ba6841SJoseph Chen fclose(image_file); 154023ba6841SJoseph Chen 154123ba6841SJoseph Chen /* prepare files */ 154223ba6841SJoseph Chen int i = 0; 154323ba6841SJoseph Chen int pos = 0; 154423ba6841SJoseph Chen const char *tmp; 154523ba6841SJoseph Chen for (i = 0; i < file_num; i++) { 154623ba6841SJoseph Chen if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) { 154723ba6841SJoseph Chen /* dtb files for kernel. */ 154823ba6841SJoseph Chen tmp = files[pos]; 154923ba6841SJoseph Chen files[pos] = files[i]; 155023ba6841SJoseph Chen files[i] = tmp; 155123ba6841SJoseph Chen pos++; 155223ba6841SJoseph Chen } else if (!strcmp(fix_path(image_path), fix_path(files[i]))) { 155323ba6841SJoseph Chen /* not to pack image itself! */ 155423ba6841SJoseph Chen tmp = files[file_num - 1]; 155523ba6841SJoseph Chen files[file_num - 1] = files[i]; 155623ba6841SJoseph Chen files[i] = tmp; 155723ba6841SJoseph Chen file_num--; 155823ba6841SJoseph Chen } 155923ba6841SJoseph Chen } 156023ba6841SJoseph Chen 156123ba6841SJoseph Chen if (!write_header(file_num)) { 156223ba6841SJoseph Chen LOGE("Failed to write header!"); 156323ba6841SJoseph Chen goto end; 156423ba6841SJoseph Chen } 156523ba6841SJoseph Chen if (!write_index_tbl(file_num, files)) { 156623ba6841SJoseph Chen LOGE("Failed to write index table!"); 156723ba6841SJoseph Chen goto end; 156823ba6841SJoseph Chen } 156923ba6841SJoseph Chen printf("Pack to %s successed!\n", image_path); 157023ba6841SJoseph Chen ret = true; 157123ba6841SJoseph Chen end: 157223ba6841SJoseph Chen return ret ? 0 : -1; 157323ba6841SJoseph Chen } 157423ba6841SJoseph Chen 157523ba6841SJoseph Chen /************pack code end****************/ 1576