/* * This file is part of the coreboot project. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #define CBFS_HEADER_PTR 0xfffffffc #define CBFS_HEADER_MAGIC 0 #define CBFS_HEADER_VERSION (CBFS_HEADER_MAGIC + 4) #define CBFS_HEADER_ROMSIZE (CBFS_HEADER_VERSION + 4) #define CBFS_HEADER_BOOTBLOCKSIZE (CBFS_HEADER_ROMSIZE + 4) #define CBFS_HEADER_ALIGN (CBFS_HEADER_BOOTBLOCKSIZE + 4) #define CBFS_HEADER_OFFSET (CBFS_HEADER_ALIGN + 4) /* 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) .section .text .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 mov CBFS_HEADER_PTR, %eax mov CBFS_HEADER_ROMSIZE(%eax), %ecx bswap %ecx mov $0, %ebx sub %ecx, %ebx /* ROM base address in ebx */ mov CBFS_HEADER_OFFSET(%eax), %ecx bswap %ecx add %ecx, %ebx /* address where we start looking for LARCHIVEs */ /* 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: /* look if we should exit: did we pass into the bootblock already? */ mov CBFS_HEADER_PTR, %ecx mov CBFS_HEADER_BOOTBLOCKSIZE(%ecx), %ecx bswap %ecx not %ecx add $1, %ecx cmp %ecx, %ebx /* if bootblockstart >= addr (==we're still in the data area), * jump back */ 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"