|
|
1.1 ! root 1: /****************************************************************************** ! 2: * Copyright (c) 2004, 2008 IBM Corporation ! 3: * All rights reserved. ! 4: * This program and the accompanying materials ! 5: * are made available under the terms of the BSD License ! 6: * which accompanies this distribution, and is available at ! 7: * http://www.opensource.org/licenses/bsd-license.php ! 8: * ! 9: * Contributors: ! 10: * IBM Corporation - initial implementation ! 11: *****************************************************************************/ ! 12: #include "macros.h" ! 13: #include "romfs.h" ! 14: ! 15: /******************************************************************* ! 16: * Wrapper for romfs_lookup. ! 17: * ! 18: * Input: ! 19: * R3 = address of filename string ! 20: * R4 = address of struct romfs_t ! 21: * 0: file size (return) ! 22: * 8: flags (return) ! 23: * 10: fileaddr (return and input: tells if first search) ! 24: * 18: nextfile (return) ! 25: * 20: namep (return) ! 26: * ! 27: * Find File Procedure ! 28: * - set filename and rombase, on return 0 file properties are stored ! 29: * in romfs_t else struct not valid ! 30: * ! 31: * Listing procedure ! 32: * - clear romfs_t (important!) ! 33: * - set filename = NULL and rombase and call returns first file ! 34: * with properties in romfs_t including next-file pointer ! 35: * - if nextpointer is non-zero then just the next file is returned ! 36: * ! 37: * Returns: ! 38: * <Success>: ! 39: * R3 = 0 ! 40: * romfs_t is updated ! 41: * <FileNotFound>: ! 42: * R3 = 1 ! 43: * romfs_t not touched ! 44: * ! 45: * Potentially modifies the following registers: ! 46: * ! 47: ! 48: Example usage from C: ! 49: ! 50: int list_bootrom() ! 51: { ! 52: struct romfs_t rfs; ! 53: int i; ! 54: ! 55: printf("Build: "__TIME__" "__DATE__" \n"); ! 56: ! 57: i = 0; ! 58: memset((void*) &rfs, 0, sizeof(struct romfs_t)); ! 59: printf(" No. File Data Size Name\n"); ! 60: ! 61: while (romfs_stat(NULL, &rfs) == 0) { ! 62: i++; ! 63: printf(" %02d: %08X %08X %7d %s\n", ! 64: i, rfs.fileaddr, rfs.datap, ! 65: rfs.size, rfs.namep); ! 66: } ! 67: if (0 == i) { ! 68: printf("Error in reading ROMFS\n"); ! 69: return 1; ! 70: } ! 71: return 0; ! 72: } ! 73: *******************************************************************/ ! 74: #define RFS_T_SIZE 0x00 ! 75: #define RFS_T_FLAGS 0x08 ! 76: #define RFS_T_FILEADDR 0x10 ! 77: #define RFS_T_NEXT 0x18 ! 78: #define RFS_T_NAME 0x20 ! 79: #define RFS_T_DATA 0x28 ! 80: ! 81: #define RFS_H_NEXT 0x00 ! 82: #define RFS_H_SIZE 0x08 ! 83: #define RFS_H_FLAGS 0x10 ! 84: #define RFS_H_DATA 0x18 ! 85: #define RFS_H_NAME 0x20 ! 86: ! 87: ENTRY(romfs_stat_file) ! 88: /* save link register and romfs_t pointer */ ! 89: mflr r15 ! 90: mr r16, r4 ! 91: ! 92: /* if filename R3 is 0 then its a listing request */ ! 93: /* if not then just continue to lookup name */ ! 94: /* save R4 to R8 which is the address of header */ ! 95: li r7, 0 ! 96: cmpd r3, r7 ! 97: beq romfs_list ! 98: bl romfs_lookup ! 99: mfsprg r8, 1 ! 100: ! 101: /* if file found then go to romfs_fill_properties */ ! 102: /* else return 1 to caller */ ! 103: cmpwi r3, 0 ! 104: beq romfs_fill_properties ! 105: b romfs_stat_end ! 106: ! 107: romfs_list: ! 108: /* check if fileaddr == 0, in this case its */ ! 109: /* the first search on this handle, so return all */ ! 110: /* info for file at rombase (R8=R4) */ ! 111: ld r6, RFS_T_FILEADDR(r4) ! 112: mfsprg r8, 1 ! 113: li r7, 0 ! 114: cmpd r7, r6 ! 115: beq romfs_fill_properties ! 116: ! 117: /* check if next file != 0 by looking into */ ! 118: /* romfs_t, if not then return (next = 0) 1 */ ! 119: li r7, 0 ! 120: ld r4, RFS_T_NEXT(r4) ! 121: cmpd r7, r4 ! 122: li r3, 1 ! 123: beq romfs_stat_end ! 124: ! 125: /* now next file is available so move R8 to next */ ! 126: /* file address */ ! 127: mr r8, r4 ! 128: ! 129: romfs_fill_properties: ! 130: /* set properties in romfs_t takes R8 as address */ ! 131: /* to file header and R16 as address of romfs_t */ ! 132: mfsprg r3, 1 ! 133: std r8, RFS_T_FILEADDR(r16) ! 134: ! 135: ld r4, RFS_H_NEXT(r8) ! 136: li r7, 0 ! 137: cmpd r7, r4 ! 138: beq $ + (2 * 4) /* =0 so add no rombase */ ! 139: add r4, r4, r3 ! 140: std r4, RFS_T_NEXT(r16) ! 141: ! 142: ld r4, RFS_H_SIZE(r8) ! 143: std r4, RFS_T_SIZE(r16) ! 144: ld r4, RFS_H_FLAGS(r8) ! 145: std r4, RFS_T_FLAGS(r16) ! 146: ! 147: ld r4, RFS_H_DATA(r8) ! 148: add r4, r4, r3 ! 149: std r4, RFS_T_DATA(r16) ! 150: ! 151: addi r4, r8, RFS_H_NAME ! 152: std r4, RFS_T_NAME(r16) ! 153: ! 154: li r3, 0 ! 155: ! 156: /* restore romfs_t pointer and link register */ ! 157: romfs_stat_end: ! 158: mr r5, r16 ! 159: mtlr r15 ! 160: blr ! 161: ! 162: /******************************************************************* ! 163: * Copies the data of file referenced by name string to address ! 164: * requires root address of filesystem. ! 165: * FIXME: ignores flags ! 166: * ! 167: * Input: ! 168: * R3 = address of filename string ! 169: * R4 = ROMBASE ! 170: * R5 = destination address ! 171: * ! 172: * Returns: ! 173: * <Success>: R3 = 0, R6 = size, <FileNotFound>: R3 = 1 ! 174: * R5 is kept ! 175: * ! 176: * Potentially modifies the following registers: ! 177: * ctr, r15, r16, r17, r18 ! 178: * ! 179: * Uses the following calls with subsequent register modification: ! 180: * - romfs_lookup ! 181: *******************************************************************/ ! 182: ASM_ENTRY(romfs_load) ! 183: mflr r15 ! 184: ! 185: /* save R5 twice */ ! 186: /* lookup file, input regs */ ! 187: /* are already set */ ! 188: /* if not found, just return */ ! 189: mr r16, r5 ! 190: mr r17, r5 ! 191: bl romfs_lookup ! 192: cmpwi r3, 1 ! 193: bne 0f ! 194: mtlr r15 ! 195: blr /* abort, not found */ ! 196: ! 197: /* save data size for return */ ! 198: /* found, copy data */ ! 199: /* data size is in R6 */ ! 200: 0: ! 201: //mr r3, r6 ! 202: mtctr r6 ! 203: addi r16, r16, -1 /* dest */ ! 204: addi r5, r5, -1 /* source*/ ! 205: ! 206: /* data is expected to be */ ! 207: /* 8 byte aligned */ ! 208: /* copy loop */ ! 209: 0: lbzu r18, 1(r5) ! 210: stbu r18, 1(r16) ! 211: bdnz 0b ! 212: ! 213: /* restore size, keep padding */ ! 214: /* restore target address */ ! 215: /* return */ ! 216: mr r5, r17 ! 217: mtlr r15 ! 218: blr ! 219: ! 220: /******************************************************************* ! 221: * looks up a file based on filename ! 222: * ! 223: * Input: ! 224: * R3 = address of filename string ! 225: * R4 = ROMBASE ! 226: * ! 227: * Returns: ! 228: * <Success>: ! 229: * R3 = 0 ! 230: * R4 = address of file header ! 231: * R5 = address of data (real address) ! 232: * R6 = size of data ! 233: * R7 = flags for file ! 234: * <FileNotFound>: ! 235: * R3 = 1 ! 236: * ! 237: * Potentially modifies the following registers: ! 238: * R3, R4, R5, R6, R7, R8, R9 ! 239: * ! 240: * Uses the following calls with subsequent register modification: ! 241: * - romfs_namematch ! 242: *******************************************************************/ ! 243: ASM_ENTRY(romfs_lookup) ! 244: mflr r9 ! 245: ! 246: romfs_lookup_next: ! 247: /* save current file base */ ! 248: mr r8, r4 ! 249: /* name to look for */ ! 250: mr r10, r3 ! 251: /* name of file */ ! 252: mr r5, r4 ! 253: addi r5, r5, (4 /* elems */ * 8 /* elem-size */) ! 254: mr r11, r5 /* for namematch */ ! 255: /* compare */ ! 256: bl romfs_namematch ! 257: cmpwi r12, 1 ! 258: bne romfs_lookup_match ! 259: ! 260: /* load next pointer */ ! 261: /* check if next is 0 */ ! 262: /* apply root-offset */ ! 263: ld r5, 0(r4) ! 264: cmpwi r5, 0 ! 265: add r4, r4, r5 ! 266: bne romfs_lookup_next ! 267: /* last file reached, abort */ ! 268: li r3, 1 ! 269: mtlr r9 ! 270: blr ! 271: ! 272: /* here the name did match */ ! 273: /* r4 is still usable here and */ ! 274: /* pointing to the initial file */ ! 275: /* load r5 with data ptr */ ! 276: /* load r6 with data size */ ! 277: /* load r7 with flags */ ! 278: /* get abs addr of data */ ! 279: romfs_lookup_match: ! 280: li r3, 0 ! 281: ld r5, (3 * 8)(r4) /* data */ ! 282: ld r6, (1 * 8)(r4) /* len */ ! 283: ld r7, (2 * 8)(r4) /* flags */ ! 284: add r5, r5, r8 ! 285: mtlr r9 ! 286: blr ! 287: ! 288: /******************************************************************* ! 289: * compares two strings in memory, ! 290: * both must be null-terminated and 8-byte aligned ! 291: * ! 292: * Input: ! 293: * R10 = string 1 ! 294: * R11 = string 2 ! 295: * ! 296: * Returns: ! 297: * <Match>: R12 = 0 <NoMatch>: R12 = 1 ! 298: * ! 299: * Potentially modifies the following registers: ! 300: * R10, R11, r12, r13, r14 ! 301: *******************************************************************/ ! 302: romfs_namematch: ! 303: subi r10, r10, 8 ! 304: subi r11, r11, 8 ! 305: ! 306: /* ! 307: * load chars as 8byte chunk from current pos, name is ! 308: * always 8 byte aligned :) ! 309: */ ! 310: romfs_cmp_loop: ! 311: ldu r13, 8(r10) /* A */ ! 312: ldu r14, 8(r11) /* B */ ! 313: ! 314: cmpd r13, r14 ! 315: li r12, 1 ! 316: beq 1f ! 317: blr ! 318: ! 319: 1: andi. r14, r14, 0xff ! 320: bne romfs_cmp_loop ! 321: ! 322: li r12, 0 ! 323: blr ! 324: ! 325: /******************************************************************* ! 326: * wrapper for romfs_lookup ! 327: * this function saves the registers from r13 - r15 on the stack ! 328: * calls romfs_lookup ! 329: * restores the saved registers ! 330: * ! 331: * the return parameters are copied to (r5) and (r5) has to ! 332: * be 0x20 big ! 333: *******************************************************************/ ! 334: ENTRY(c_romfs_lookup) ! 335: stdu r1,-0x50(r1) # allocate space on stack ! 336: ! 337: mflr r0 # save link register ! 338: std r0,0x30(r1) ! 339: ! 340: std r15,0x38(r1) # save r15 ! 341: std r14,0x40(r1) # save r14 ! 342: std r13,0x48(r1) # and r13 ! 343: ! 344: mr r15,r5 # save the pointer for the return value ! 345: ! 346: bl romfs_lookup # do the thing ! 347: ! 348: ld r0,0x30(r1) # restore link register ! 349: mtlr r0 ! 350: ! 351: std r4,0x00(r15) # copy return values ! 352: std r5,0x08(r15) # to the return pointer ! 353: std r6,0x10(r15) ! 354: std r7,0x18(r15) ! 355: ! 356: ld r13,0x48(r1) # restore registers from stack ! 357: ld r14,0x40(r1) ! 358: ld r15,0x38(r1) ! 359: ! 360: addi r1,r1,0x50 # cleanup stack ! 361: ! 362: blr
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.