/* SPDX-License-Identifier: GPL-2.0-only */ #include #if CONFIG(CBFS_VERIFICATION) #error "walkcbfs_asm is not safe to use with CBFS verification!" #endif /* we use this instead of CBFS_HEADER_ALIGN because the latter is retired. */ #define CBFS_ALIGNMENT 64 #define CBFS_FILE_MAGIC 0 #define CBFS_FILE_LEN (CBFS_FILE_MAGIC + 8) #define CBFS_FILE_TYPE (CBFS_FILE_LEN + 4) #define CBFS_FILE_CHECKSUM (CBFS_FILE_TYPE + 4) #define CBFS_FILE_OFFSET (CBFS_FILE_CHECKSUM + 4) #define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4) #if FMAP_SECTION_COREBOOT_START < (0xffffffff - CONFIG_ROM_SIZE + 1) #define COREBOOT_CBFS_START (0xffffffff - CONFIG_ROM_SIZE + 1 + FMAP_SECTION_COREBOOT_START) #else #define COREBOOT_CBFS_START FMAP_SECTION_COREBOOT_START #endif .code32 .section .init .global walkcbfs_asm /* * input %esi: filename * input %esp: return address (not pointer to return address!) * output %eax: pointer to CBFS header * clobbers %ebx, %ecx, %edi */ walkcbfs_asm: cld movl $COREBOOT_CBFS_START, %ebx /* determine filename length */ mov $0, %eax 1: cmpb $0, (%eax,%esi) jz 2f add $1, %eax jmp 1b 2: add $1, %eax walker: mov 0(%ebx), %edi /* Check for LARCHIVE header */ cmp %edi, filemagic jne searchfile mov 4(%ebx), %edi cmp %edi, filemagic+4 jne searchfile /* LARCHIVE header found */ mov %ebx, %edi add $CBFS_FILE_STRUCTSIZE, %edi /* edi = address of first byte after * struct cbfs_file */ mov %eax, %ecx repe cmpsb /* zero flag set if strings are equal */ jnz tryharder /* we found it! */ mov %ebx, %eax jmp *%esp tryharder: sub %ebx, %edi sub $CBFS_FILE_STRUCTSIZE, %edi /* edi = # of walked bytes */ sub %edi, %esi /* esi = start of filename */ /* ebx = ecx = (current+offset+len+ALIGN-1) & ~(ALIGN-1) */ mov CBFS_FILE_OFFSET(%ebx), %ecx bswap %ecx add %ebx, %ecx mov CBFS_FILE_LEN(%ebx), %edi bswap %edi add %edi, %ecx /* round by 64 bytes */ add $(CBFS_ALIGNMENT - 1), %ecx and $~(CBFS_ALIGNMENT - 1), %ecx /* if oldaddr >= addr, leave */ cmp %ebx, %ecx jbe out mov %ecx, %ebx check_for_exit: /* if addr <= COREBOOT_END - 1, continue */ #define FMAP_SECTION_COREBOOT_END (FMAP_SECTION_COREBOOT_START - 1 + FMAP_SECTION_COREBOOT_SIZE) movl $FMAP_SECTION_COREBOOT_END, %ecx cmp %ecx, %ebx jbe walker out: mov $0, %eax jmp *%esp searchfile: /* if filemagic isn't found, move forward 64 bytes */ add $CBFS_ALIGNMENT, %ebx jmp check_for_exit filemagic: .ascii "LARCHIVE"