blob: 60eb8b53b061ace2acd45fd5d7f7028b70575e88 [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
Patrick Georgi9341acd2009-12-23 12:52:56 +000018/*
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000019 * input %esi: filename
20 * input %esp: return address (not pointer to return address!)
Alexandru Gagniuc299c2652013-12-08 01:13:43 -060021 * output %eax: pointer to CBFS header
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000022 * clobbers %ebx, %ecx, %edi
23 */
Patrick Georgifab35e32011-03-08 07:50:43 +000024walkcbfs_asm:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000025 cld
26
Patrick Georgi9341acd2009-12-23 12:52:56 +000027 mov CBFS_HEADER_PTR, %eax
28 mov CBFS_HEADER_ROMSIZE(%eax), %ecx
29 bswap %ecx
30 mov $0, %ebx
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000031 sub %ecx, %ebx /* rom base address in ebx */
Patrick Georgi9341acd2009-12-23 12:52:56 +000032 mov CBFS_HEADER_OFFSET(%eax), %ecx
33 bswap %ecx
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000034 add %ecx, %ebx /* address where we start looking for LARCHIVEs */
Patrick Georgi9341acd2009-12-23 12:52:56 +000035
Patrick Georgi1bb68282009-12-31 12:56:53 +000036 /* determine filename length */
37 mov $0, %eax
381:
39 cmpb $0, (%eax,%esi)
40 jz 2f
41 add $1, %eax
42 jmp 1b
432:
44 add $1, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000045walker:
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000046 mov 0(%ebx), %edi /* Check for LARCHIVE header */
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000047 cmp %edi, filemagic
48 jne searchfile
49 mov 4(%ebx), %edi
50 cmp %edi, filemagic+4
51 jne searchfile
52
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000053 /* LARCHIVE header found */
Patrick Georgi9341acd2009-12-23 12:52:56 +000054 mov %ebx, %edi
55 add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after struct cbfs_file */
Patrick Georgi1bb68282009-12-31 12:56:53 +000056 mov %eax, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000057 repe cmpsb
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000058 /* zero flag set if strings are equal */
Patrick Georgi9341acd2009-12-23 12:52:56 +000059 jnz tryharder
60
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000061 /* we found it! */
Alexandru Gagniuc299c2652013-12-08 01:13:43 -060062 mov %ebx, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000063 jmp *%esp
64
65tryharder:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000066 sub %ebx, %edi
67 sub $CBFS_FILE_STRUCTSIZE, %edi /* edi = # of walked bytes */
Patrick Georgi1bb68282009-12-31 12:56:53 +000068 sub %edi, %esi /* esi = start of filename */
69
70 /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */
Patrick Georgi9341acd2009-12-23 12:52:56 +000071 mov CBFS_FILE_OFFSET(%ebx), %ecx
72 bswap %ecx
73 add %ebx, %ecx
74 mov CBFS_FILE_LEN(%ebx), %edi
75 bswap %edi
76 add %edi, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000077 mov CBFS_HEADER_PTR, %edi
78 mov CBFS_HEADER_ALIGN(%edi), %edi
79 bswap %edi
80 sub $1, %edi
81 add %edi, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000082 not %edi
83 and %edi, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000084
85 /* if oldaddr >= addr, leave */
86 cmp %ebx, %ecx
87 jbe out
88
Patrick Georgi9341acd2009-12-23 12:52:56 +000089 mov %ecx, %ebx
90
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000091check_for_exit:
92 /* look if we should exit: did we pass into the bootblock already? */
Patrick Georgi1bb68282009-12-31 12:56:53 +000093 mov CBFS_HEADER_PTR, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000094 mov CBFS_HEADER_BOOTBLOCKSIZE(%ecx), %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000095 bswap %ecx
96 not %ecx
97 add $1, %ecx
98
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000099 cmp %ecx, %ebx
100 /* if bootblockstart >= addr (==we're still in the data area) , jump back */
Patrick Georgi9341acd2009-12-23 12:52:56 +0000101 jbe walker
102
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000103out:
Patrick Georgi9341acd2009-12-23 12:52:56 +0000104 mov $0, %eax
105 jmp *%esp
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000106
107
108searchfile:
109 /* if filemagic isn't found, move forward cbfs_header->align bytes */
110 mov CBFS_HEADER_PTR, %edi
111 mov CBFS_HEADER_ALIGN(%edi), %edi
112 bswap %edi
113 add %edi, %ebx
114 jmp check_for_exit
115
116filemagic:
117 .ascii "LARCHIVE"