blob: d043af5690e73e0b40445bc38c2248e0c85e69b2 [file] [log] [blame]
Patrick Georgi9341acd2009-12-23 12:52:56 +00001#define CBFS_HEADER_PTR 0xfffffffc
2
3#define CBFS_HEADER_MAGIC 0
4#define CBFS_HEADER_VERSION (CBFS_HEADER_MAGIC + 4)
5#define CBFS_HEADER_ROMSIZE (CBFS_HEADER_VERSION + 4)
6#define CBFS_HEADER_BOOTBLOCKSIZE (CBFS_HEADER_ROMSIZE + 4)
7#define CBFS_HEADER_ALIGN (CBFS_HEADER_BOOTBLOCKSIZE + 4)
8#define CBFS_HEADER_OFFSET (CBFS_HEADER_ALIGN + 4)
9
10#define CBFS_FILE_MAGIC 0
11#define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8)
12#define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4)
13#define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4)
14#define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4)
15
16#define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
17
18#define CBFS_STAGE_COMPRESSION 0
19#define CBFS_STAGE_ENTRY (CBFS_STAGE_COMPRESSION + 4)
20#define CBFS_STAGE_LOAD (CBFS_STAGE_ENTRY + 8)
21#define CBFS_STAGE_LEN (CBFS_STAGE_LOAD + 8)
22#define CBFS_STAGE_MEMLEN (CBFS_STAGE_LEN + 4)
23
24/*
25 input %esi: filename
26 input %esp: return address (not pointer to return address!)
27 output %eax: entry point
Patrick Georgi1bb68282009-12-31 12:56:53 +000028 clobbers %ebx, %ecx, %edi
Patrick Georgi9341acd2009-12-23 12:52:56 +000029*/
30walkcbfs:
Patrick Georgi9341acd2009-12-23 12:52:56 +000031 mov CBFS_HEADER_PTR, %eax
32 mov CBFS_HEADER_ROMSIZE(%eax), %ecx
33 bswap %ecx
34 mov $0, %ebx
35 sub %ecx, %ebx
36 mov CBFS_HEADER_OFFSET(%eax), %ecx
37 bswap %ecx
38 add %ecx, %ebx
Patrick Georgi9341acd2009-12-23 12:52:56 +000039
Patrick Georgi1bb68282009-12-31 12:56:53 +000040 /* determine filename length */
41 mov $0, %eax
421:
43 cmpb $0, (%eax,%esi)
44 jz 2f
45 add $1, %eax
46 jmp 1b
472:
48 add $1, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000049walker:
Patrick Georgi9341acd2009-12-23 12:52:56 +000050 mov %ebx, %edi
51 add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after struct cbfs_file */
Patrick Georgi1bb68282009-12-31 12:56:53 +000052 mov %eax, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000053 repe cmpsb
54 # zero flag set if strings are equal
55 jnz tryharder
56
57 # we found it!
58 mov CBFS_FILE_OFFSET(%ebx), %eax
59 bswap %eax
60 add %ebx, %eax
61 add $CBFS_STAGE_ENTRY, %eax /* eax = ((cbfs_stage* (cbfs_file* ebx)->offset)->entry) */
62 mov 0(%eax), %eax
63 jmp *%esp
64
65tryharder:
Patrick Georgi1bb68282009-12-31 12:56:53 +000066 sub %ebx, %edi /* edi = # of walked bytes */
67 sub %edi, %esi /* esi = start of filename */
68
69 /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */
Patrick Georgi9341acd2009-12-23 12:52:56 +000070 mov CBFS_FILE_OFFSET(%ebx), %ecx
71 bswap %ecx
72 add %ebx, %ecx
73 mov CBFS_FILE_LEN(%ebx), %edi
74 bswap %edi
75 add %edi, %ecx
Patrick Georgi1bb68282009-12-31 12:56:53 +000076 mov CBFS_HEADER_PTR, %ebx
77 mov CBFS_HEADER_ALIGN(%ebx), %ebx
78 bswap %ebx
79 sub $1, %ebx
80 add %ebx, %ecx
81 mov %ebx, %edi
Patrick Georgi9341acd2009-12-23 12:52:56 +000082 not %edi
83 and %edi, %ecx
84 mov %ecx, %ebx
85
86 /* look if we should exit */
Patrick Georgi1bb68282009-12-31 12:56:53 +000087 mov CBFS_HEADER_PTR, %ecx
88 mov CBFS_HEADER_ROMSIZE(%ecx), %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000089 bswap %ecx
90 not %ecx
91 add $1, %ecx
92
93 cmp %ebx, %ecx
94 /* if we're still inside the ROM area, jump back */
95 jbe walker
96
97 mov $0, %eax
98 jmp *%esp