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