Annotation of qemu/roms/SLOF/llfw/romfs.S, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.