blob: bd71f19158da69478e4812b6b4751c04a36b9153 [file] [log] [blame]
Martin Roth9df9e9392016-01-12 15:55:28 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Patrick Georgi9341acd2009-12-23 12:52:56 +000014#define CBFS_HEADER_PTR 0xfffffffc
15
16#define CBFS_HEADER_MAGIC 0
17#define CBFS_HEADER_VERSION (CBFS_HEADER_MAGIC + 4)
18#define CBFS_HEADER_ROMSIZE (CBFS_HEADER_VERSION + 4)
19#define CBFS_HEADER_BOOTBLOCKSIZE (CBFS_HEADER_ROMSIZE + 4)
20#define CBFS_HEADER_ALIGN (CBFS_HEADER_BOOTBLOCKSIZE + 4)
21#define CBFS_HEADER_OFFSET (CBFS_HEADER_ALIGN + 4)
22
Patrick Georgi4d3e4c42015-07-14 22:28:27 +020023/* we use this instead of CBFS_HEADER_ALIGN because the latter is retired. */
24#define CBFS_ALIGNMENT 64
25
Patrick Georgi9341acd2009-12-23 12:52:56 +000026#define CBFS_FILE_MAGIC 0
27#define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8)
28#define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4)
29#define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4)
30#define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4)
31
32#define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
33
Alexandru Gagniucc46a3922015-10-02 16:17:41 -070034.section .text
35.global walkcbfs_asm
36
Patrick Georgi9341acd2009-12-23 12:52:56 +000037/*
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000038 * input %esi: filename
39 * input %esp: return address (not pointer to return address!)
Alexandru Gagniuc299c2652013-12-08 01:13:43 -060040 * output %eax: pointer to CBFS header
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000041 * clobbers %ebx, %ecx, %edi
42 */
Patrick Georgifab35e32011-03-08 07:50:43 +000043walkcbfs_asm:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000044 cld
45
Patrick Georgi9341acd2009-12-23 12:52:56 +000046 mov CBFS_HEADER_PTR, %eax
47 mov CBFS_HEADER_ROMSIZE(%eax), %ecx
48 bswap %ecx
49 mov $0, %ebx
Elyes HAOUAS777ea892016-07-29 07:40:41 +020050 sub %ecx, %ebx /* ROM base address in ebx */
Patrick Georgi9341acd2009-12-23 12:52:56 +000051 mov CBFS_HEADER_OFFSET(%eax), %ecx
52 bswap %ecx
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000053 add %ecx, %ebx /* address where we start looking for LARCHIVEs */
Patrick Georgi9341acd2009-12-23 12:52:56 +000054
Patrick Georgi1bb68282009-12-31 12:56:53 +000055 /* determine filename length */
56 mov $0, %eax
571:
58 cmpb $0, (%eax,%esi)
59 jz 2f
60 add $1, %eax
61 jmp 1b
622:
63 add $1, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000064walker:
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000065 mov 0(%ebx), %edi /* Check for LARCHIVE header */
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000066 cmp %edi, filemagic
67 jne searchfile
68 mov 4(%ebx), %edi
69 cmp %edi, filemagic+4
70 jne searchfile
71
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000072 /* LARCHIVE header found */
Patrick Georgi9341acd2009-12-23 12:52:56 +000073 mov %ebx, %edi
74 add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after struct cbfs_file */
Patrick Georgi1bb68282009-12-31 12:56:53 +000075 mov %eax, %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +000076 repe cmpsb
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000077 /* zero flag set if strings are equal */
Patrick Georgi9341acd2009-12-23 12:52:56 +000078 jnz tryharder
79
Stefan Reinauer1fdfed12011-04-14 20:33:53 +000080 /* we found it! */
Alexandru Gagniuc299c2652013-12-08 01:13:43 -060081 mov %ebx, %eax
Patrick Georgi9341acd2009-12-23 12:52:56 +000082 jmp *%esp
83
84tryharder:
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000085 sub %ebx, %edi
86 sub $CBFS_FILE_STRUCTSIZE, %edi /* edi = # of walked bytes */
Patrick Georgi1bb68282009-12-31 12:56:53 +000087 sub %edi, %esi /* esi = start of filename */
88
89 /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */
Patrick Georgi9341acd2009-12-23 12:52:56 +000090 mov CBFS_FILE_OFFSET(%ebx), %ecx
91 bswap %ecx
92 add %ebx, %ecx
93 mov CBFS_FILE_LEN(%ebx), %edi
94 bswap %edi
95 add %edi, %ecx
Patrick Georgi4d3e4c42015-07-14 22:28:27 +020096 /* round by 64 bytes */
97 add $(CBFS_ALIGNMENT - 1), %ecx
98 and $~(CBFS_ALIGNMENT - 1), %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +000099
100 /* if oldaddr >= addr, leave */
101 cmp %ebx, %ecx
102 jbe out
103
Patrick Georgi9341acd2009-12-23 12:52:56 +0000104 mov %ecx, %ebx
105
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000106check_for_exit:
107 /* look if we should exit: did we pass into the bootblock already? */
Patrick Georgi1bb68282009-12-31 12:56:53 +0000108 mov CBFS_HEADER_PTR, %ecx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000109 mov CBFS_HEADER_BOOTBLOCKSIZE(%ecx), %ecx
Patrick Georgi9341acd2009-12-23 12:52:56 +0000110 bswap %ecx
111 not %ecx
112 add $1, %ecx
113
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000114 cmp %ecx, %ebx
115 /* if bootblockstart >= addr (==we're still in the data area) , jump back */
Patrick Georgi9341acd2009-12-23 12:52:56 +0000116 jbe walker
117
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000118out:
Patrick Georgi9341acd2009-12-23 12:52:56 +0000119 mov $0, %eax
120 jmp *%esp
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000121
122
123searchfile:
Patrick Georgi4d3e4c42015-07-14 22:28:27 +0200124 /* if filemagic isn't found, move forward 64 bytes */
125 add $CBFS_ALIGNMENT, %ebx
Patrick Georgif6fbfaf2010-02-22 12:58:01 +0000126 jmp check_for_exit
127
128filemagic:
129 .ascii "LARCHIVE"