blob: ac2d1341ebdc7a5fe1f35603847990c56001b177 [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
Patrick Georgi4d3e4c42015-07-14 22:28:27 +020010/* we use this instead of CBFS_HEADER_ALIGN because the latter is retired. */
11#define CBFS_ALIGNMENT 64
12
Patrick Georgi9341acd2009-12-23 12:52:56 +000013#define CBFS_FILE_MAGIC 0
14#define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8)
15#define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4)
16#define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4)
17#define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4)
18
19#define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
20
Alexandru Gagniucc46a3922015-10-02 16:17:41 -070021.section .text
22.global walkcbfs_asm
23
Patrick Georgi9341acd2009-12-23 12:52:56 +000024/*
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000025 * input %esi: filename
26 * input %esp: return address (not pointer to return address!)
Alexandru Gagniuc299c2652013-12-08 01:13:43 -060027 * output %eax: pointer to CBFS header
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000028 * clobbers %ebx, %ecx, %edi
29 */
Patrick Georgifab35e32011-03-08 07:50:43 +000030walkcbfs_asm:
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
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000037 sub %ecx, %ebx /* rom base address in ebx */
Patrick Georgi9341acd2009-12-23 12:52:56 +000038 mov CBFS_HEADER_OFFSET(%eax), %ecx
39 bswap %ecx
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000040 add %ecx, %ebx /* address where we start looking for LARCHIVEs */
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:
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000052 mov 0(%ebx), %edi /* Check for LARCHIVE header */
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000053 cmp %edi, filemagic
54 jne searchfile
55 mov 4(%ebx), %edi
56 cmp %edi, filemagic+4
57 jne searchfile
58
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000059 /* LARCHIVE header found */
Patrick Georgi9341acd2009-12-23 12:52:56 +000060 mov %ebx, %edi
61 add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after struct cbfs_file */
Patrick Georgi1bb68282009-12-31 12:56:53 +000062 mov %eax, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000063 repe cmpsb
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000064 /* zero flag set if strings are equal */
Patrick Georgi9341acd2009-12-23 12:52:56 +000065 jnz tryharder
66
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000067 /* we found it! */
Alexandru Gagniuc299c2652013-12-08 01:13:43 -060068 mov %ebx, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000069 jmp *%esp
70
71tryharder:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000072 sub %ebx, %edi
73 sub $CBFS_FILE_STRUCTSIZE, %edi /* edi = # of walked bytes */
Patrick Georgi1bb68282009-12-31 12:56:53 +000074 sub %edi, %esi /* esi = start of filename */
75
76 /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */
Patrick Georgi9341acd2009-12-23 12:52:56 +000077 mov CBFS_FILE_OFFSET(%ebx), %ecx
78 bswap %ecx
79 add %ebx, %ecx
80 mov CBFS_FILE_LEN(%ebx), %edi
81 bswap %edi
82 add %edi, %ecx
Patrick Georgi4d3e4c42015-07-14 22:28:27 +020083 /* round by 64 bytes */
84 add $(CBFS_ALIGNMENT - 1), %ecx
85 and $~(CBFS_ALIGNMENT - 1), %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000086
87 /* if oldaddr >= addr, leave */
88 cmp %ebx, %ecx
89 jbe out
90
Patrick Georgi9341acd2009-12-23 12:52:56 +000091 mov %ecx, %ebx
92
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000093check_for_exit:
94 /* look if we should exit: did we pass into the bootblock already? */
Patrick Georgi1bb68282009-12-31 12:56:53 +000095 mov CBFS_HEADER_PTR, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000096 mov CBFS_HEADER_BOOTBLOCKSIZE(%ecx), %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000097 bswap %ecx
98 not %ecx
99 add $1, %ecx
100
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000101 cmp %ecx, %ebx
102 /* if bootblockstart >= addr (==we're still in the data area) , jump back */
Patrick Georgi9341acd2009-12-23 12:52:56 +0000103 jbe walker
104
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000105out:
Patrick Georgi9341acd2009-12-23 12:52:56 +0000106 mov $0, %eax
107 jmp *%esp
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000108
109
110searchfile:
Patrick Georgi4d3e4c42015-07-14 22:28:27 +0200111 /* if filemagic isn't found, move forward 64 bytes */
112 add $CBFS_ALIGNMENT, %ebx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000113 jmp check_for_exit
114
115filemagic:
116 .ascii "LARCHIVE"