|
|
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.