static int
ulzma(u8 *dst, u32 maxlen, const u8 *src, u32 srclen)
{
+ dprintf(3, "Uncompressing data %d@%p to %d@%p\n", srclen, src, maxlen, dst);
CLzmaDecoderState state;
int ret = LzmaDecodeProperties(&state.Properties, src, LZMA_PROPERTIES_SIZE);
if (ret != LZMA_RESULT_OK) {
dprintf(3, "Searching CBFS for %s\n", fname);
struct cbfs_file *file;
for (file = cbfs_getfirst(); file; file = cbfs_getnext(file)) {
- dprintf(3, "Found CBFS file %s\n", file->filename);
if (strcmp(fname, file->filename) == 0)
return file;
}
return NULL;
}
+static int
+data_copy(u8 *dst, u32 maxlen, const u8 *src, u32 srclen)
+{
+ dprintf(3, "Copying data %d@%p to %d@%p\n", srclen, src, maxlen, dst);
+ if (srclen > maxlen) {
+ dprintf(1, "File too big to copy\n");
+ return -1;
+ }
+ memcpy(dst, src, srclen);
+ return srclen;
+}
+
// Copy a file to memory (uncompressing if necessary)
static int
cbfs_copyfile(void *dst, u32 maxlen, const char *fname)
continue;
u32 size = ntohl(file->len);
void *src = (void*)file + ntohl(file->offset);
- if (file->filename[fnlen] == '\0') {
- // No compression
- if (size > maxlen) {
- dprintf(1, "File too big to copy\n");
- return -1;
- }
- dprintf(3, "Copying data file %s\n", file->filename);
- memcpy(dst, src, size);
- return size;
- }
- if (strcmp(&file->filename[fnlen], ".lzma") == 0) {
- // lzma compressed file
- dprintf(3, "Uncompressing data file %s @ %p\n"
- , file->filename, src);
+ if (file->filename[fnlen] == '\0')
+ return data_copy(dst, maxlen, src, size);
+ if (strcmp(&file->filename[fnlen], ".lzma") == 0)
return ulzma(dst, maxlen, src, size);
- }
}
return -1;
}
}
int
-cb_copy_optionrom(void *dst, u32 maxlen, u32 vendev)
+cbfs_copy_optionrom(void *dst, u32 maxlen, u32 vendev)
{
if (! CONFIG_COREBOOT_FLASH)
return -1;
return cbfs_copyfile(dst, maxlen, fname);
}
+struct cbfs_file *
+cbfs_copy_gen_optionrom(void *dst, u32 maxlen, struct cbfs_file *file)
+{
+ if (! CONFIG_COREBOOT_FLASH)
+ return NULL;
+ if (! file)
+ file = cbfs_getfirst();
+ else
+ file = cbfs_getnext(file);
+ for (; file; file = cbfs_getnext(file)) {
+ if (memcmp("genroms/", file->filename, 8) != 0)
+ continue;
+ u32 size = ntohl(file->len);
+ void *src = (void*)file + ntohl(file->offset);
+ int fnamelen = strlen(file->filename);
+ int rv;
+ if (fnamelen > 5 && strcmp(&file->filename[fnamelen-5], ".lzma") == 0)
+ rv = ulzma(dst, maxlen, src, size);
+ else
+ rv = data_copy(dst, maxlen, src, size);
+ if (rv >= 0)
+ return file;
+ }
+ return NULL;
+}
+
struct cbfs_payload_segment {
u32 type;
u32 compression;
&& ((OPTIONROM_VENDEV_2 >> 16)
| ((OPTIONROM_VENDEV_2 & 0xffff)) << 16) == vendev)
return copy_rom((struct rom_header *)OPTIONROM_MEM_2);
- int ret = cb_copy_optionrom((void*)next_rom, BUILD_BIOS_ADDR - next_rom
- , vendev);
+ int ret = cbfs_copy_optionrom((void*)next_rom, BUILD_BIOS_ADDR - next_rom
+ , vendev);
if (ret < 0)
return NULL;
return (struct rom_header *)next_rom;
return NULL;
}
-// Attempt to map and initialize the option rom on a given PCI device.
+// Adjust for the size of an option rom; allow it to resize.
static struct rom_header *
-init_optionrom(u16 bdf)
+verifysize_optionrom(struct rom_header *rom, u16 bdf)
{
- u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
- dprintf(4, "Attempting to init PCI bdf %x (dev/ven %x)\n", bdf, vendev);
- struct rom_header *rom = lookup_hardcode(vendev);
- if (! rom)
- rom = map_optionrom(bdf, vendev);
- if (! rom)
- // No ROM present.
- return NULL;
-
if (! is_valid_rom(rom))
return NULL;
return rom;
}
+// Attempt to map and initialize the option rom on a given PCI device.
+static struct rom_header *
+init_optionrom(u16 bdf)
+{
+ u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
+ dprintf(4, "Attempting to init PCI bdf %x (dev/ven %x)\n", bdf, vendev);
+ struct rom_header *rom = lookup_hardcode(vendev);
+ if (! rom)
+ rom = map_optionrom(bdf, vendev);
+ if (! rom)
+ // No ROM present.
+ return NULL;
+ return verifysize_optionrom(rom, bdf);
+}
+
/****************************************************************
* Non-VGA option rom init
continue;
init_optionrom(bdf);
}
+
+ // Find and deploy CBFS roms not associated with a device.
+ struct cbfs_file *tmp = NULL;
+ for (;;) {
+ tmp = cbfs_copy_gen_optionrom(
+ (void*)next_rom, BUILD_BIOS_ADDR - next_rom, tmp);
+ if (!tmp)
+ break;
+ verifysize_optionrom((void*)next_rom, 0);
+ }
}
// All option roms found and deployed - now build BEV/BCV vectors.