blob: 395c46e20c3790686d8a9475330893aa45948288 [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 Georgif6fbfaf2010-02-22 12:58:01 +000031 cld
32
Patrick Georgi9341acd2009-12-23 12:52:56 +000033 mov CBFS_HEADER_PTR, %eax
34 mov CBFS_HEADER_ROMSIZE(%eax), %ecx
35 bswap %ecx
36 mov $0, %ebx
37 sub %ecx, %ebx
38 mov CBFS_HEADER_OFFSET(%eax), %ecx
39 bswap %ecx
40 add %ecx, %ebx
Patrick Georgi9341acd2009-12-23 12:52:56 +000041
Patrick Georgi1bb68282009-12-31 12:56:53 +000042 /* determine filename length */
43 mov $0, %eax
441:
45 cmpb $0, (%eax,%esi)
46 jz 2f
47 add $1, %eax
48 jmp 1b
492:
50 add $1, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000051walker:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000052 mov 0(%ebx), %edi
53 cmp %edi, filemagic
54 jne searchfile
55 mov 4(%ebx), %edi
56 cmp %edi, filemagic+4
57 jne searchfile
58
Patrick Georgi9341acd2009-12-23 12:52:56 +000059 mov %ebx, %edi
60 add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after struct cbfs_file */
Patrick Georgi1bb68282009-12-31 12:56:53 +000061 mov %eax, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000062 repe cmpsb
63 # zero flag set if strings are equal
64 jnz tryharder
65
66 # we found it!
67 mov CBFS_FILE_OFFSET(%ebx), %eax
68 bswap %eax
69 add %ebx, %eax
70 add $CBFS_STAGE_ENTRY, %eax /* eax = ((cbfs_stage* (cbfs_file* ebx)->offset)->entry) */
71 mov 0(%eax), %eax
72 jmp *%esp
73
74tryharder:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000075 sub %ebx, %edi
76 sub $CBFS_FILE_STRUCTSIZE, %edi /* edi = # of walked bytes */
Patrick Georgi1bb68282009-12-31 12:56:53 +000077 sub %edi, %esi /* esi = start of filename */
78
79 /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */
Patrick Georgi9341acd2009-12-23 12:52:56 +000080 mov CBFS_FILE_OFFSET(%ebx), %ecx
81 bswap %ecx
82 add %ebx, %ecx
83 mov CBFS_FILE_LEN(%ebx), %edi
84 bswap %edi
85 add %edi, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000086 mov CBFS_HEADER_PTR, %edi
87 mov CBFS_HEADER_ALIGN(%edi), %edi
88 bswap %edi
89 sub $1, %edi
90 add %edi, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000091 not %edi
92 and %edi, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000093
94 /* if oldaddr >= addr, leave */
95 cmp %ebx, %ecx
96 jbe out
97
Patrick Georgi9341acd2009-12-23 12:52:56 +000098 mov %ecx, %ebx
99
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000100check_for_exit:
101 /* look if we should exit: did we pass into the bootblock already? */
Patrick Georgi1bb68282009-12-31 12:56:53 +0000102 mov CBFS_HEADER_PTR, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000103 mov CBFS_HEADER_BOOTBLOCKSIZE(%ecx), %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +0000104 bswap %ecx
105 not %ecx
106 add $1, %ecx
107
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000108 cmp %ecx, %ebx
109 /* if bootblockstart >= addr (==we're still in the data area) , jump back */
Patrick Georgi9341acd2009-12-23 12:52:56 +0000110 jbe walker
111
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000112out:
Patrick Georgi9341acd2009-12-23 12:52:56 +0000113 mov $0, %eax
114 jmp *%esp
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000115
116
117searchfile:
118 /* if filemagic isn't found, move forward cbfs_header->align bytes */
119 mov CBFS_HEADER_PTR, %edi
120 mov CBFS_HEADER_ALIGN(%edi), %edi
121 bswap %edi
122 add %edi, %ebx
123 jmp check_for_exit
124
125filemagic:
126 .ascii "LARCHIVE"