xref: /aosp_15_r20/external/coreboot/src/arch/x86/walkcbfs.S (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <fmap_config.h>
4
5#if CONFIG(CBFS_VERIFICATION)
6#error "walkcbfs_asm is not safe to use with CBFS verification!"
7#endif
8
9/* we use this instead of CBFS_HEADER_ALIGN because the latter is retired. */
10#define CBFS_ALIGNMENT 64
11
12#define CBFS_FILE_MAGIC 0
13#define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8)
14#define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4)
15#define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4)
16#define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4)
17
18#define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
19
20#if FMAP_SECTION_COREBOOT_START < (0xffffffff - CONFIG_ROM_SIZE + 1)
21#define COREBOOT_CBFS_START (0xffffffff - CONFIG_ROM_SIZE + 1 + FMAP_SECTION_COREBOOT_START)
22#else
23#define COREBOOT_CBFS_START FMAP_SECTION_COREBOOT_START
24#endif
25
26.code32
27.section .init
28.global walkcbfs_asm
29
30/*
31 * input %esi: filename
32 * input %esp: return address (not pointer to return address!)
33 * output %eax: pointer to CBFS header
34 * clobbers %ebx, %ecx, %edi
35 */
36walkcbfs_asm:
37	cld
38
39	movl $COREBOOT_CBFS_START, %ebx
40
41	/* determine filename length */
42	mov $0, %eax
431:
44	cmpb $0, (%eax,%esi)
45	jz 2f
46	add $1, %eax
47	jmp 1b
482:
49	add $1, %eax
50walker:
51	mov 0(%ebx), %edi /* Check for LARCHIVE header */
52	cmp %edi, filemagic
53	jne searchfile
54	mov 4(%ebx), %edi
55	cmp %edi, filemagic+4
56	jne searchfile
57
58	/* LARCHIVE header found */
59	mov %ebx, %edi
60	add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after
61					 * struct cbfs_file
62					 */
63	mov %eax, %ecx
64	repe cmpsb
65	/* zero flag set if strings are equal */
66	jnz tryharder
67
68	/* we found it! */
69	mov %ebx, %eax
70	jmp *%esp
71
72tryharder:
73	sub %ebx, %edi
74	sub $CBFS_FILE_STRUCTSIZE, %edi /* edi = # of walked bytes */
75	sub %edi, %esi /* esi = start of filename */
76
77	/* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */
78	mov CBFS_FILE_OFFSET(%ebx), %ecx
79	bswap %ecx
80	add %ebx, %ecx
81	mov CBFS_FILE_LEN(%ebx), %edi
82	bswap %edi
83	add %edi, %ecx
84	/* round by 64 bytes */
85	add $(CBFS_ALIGNMENT - 1), %ecx
86	and $~(CBFS_ALIGNMENT - 1), %ecx
87
88	/* if oldaddr >= addr, leave */
89	cmp %ebx, %ecx
90	jbe out
91
92	mov %ecx, %ebx
93
94check_for_exit:
95	/* if addr <= COREBOOT_END - 1, continue */
96#define FMAP_SECTION_COREBOOT_END (FMAP_SECTION_COREBOOT_START - 1 + FMAP_SECTION_COREBOOT_SIZE)
97
98	movl $FMAP_SECTION_COREBOOT_END, %ecx
99	cmp %ecx, %ebx
100	jbe walker
101
102out:
103	mov $0, %eax
104	jmp *%esp
105
106
107searchfile:
108	/* if filemagic isn't found, move forward 64 bytes */
109	add $CBFS_ALIGNMENT, %ebx
110	jmp check_for_exit
111
112filemagic:
113	.ascii "LARCHIVE"
114