Add ability to run all option roms in CBFS directory "genroms/".
diff --git a/src/coreboot.c b/src/coreboot.c
index 3782167..1ba8d12 100644
--- a/src/coreboot.c
+++ b/src/coreboot.c
@@ -280,6 +280,7 @@
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) {
@@ -401,13 +402,24 @@
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)
@@ -420,22 +432,10 @@
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;
}
@@ -477,7 +477,7 @@
}
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;
@@ -494,6 +494,32 @@
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;
diff --git a/src/optionroms.c b/src/optionroms.c
index ac26286..c42968a 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -187,8 +187,8 @@
&& ((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;
@@ -261,6 +261,22 @@
return NULL;
}
+// Adjust for the size of an option rom; allow it to resize.
+static struct rom_header *
+verifysize_optionrom(struct rom_header *rom, u16 bdf)
+{
+ if (! is_valid_rom(rom))
+ return NULL;
+
+ if (get_pnp_rom(rom))
+ // Init the PnP rom.
+ callrom(rom, OPTION_ROM_INITVECTOR, bdf);
+
+ next_rom += ALIGN(rom->size * 512, OPTION_ROM_ALIGN);
+
+ return rom;
+}
+
// Attempt to map and initialize the option rom on a given PCI device.
static struct rom_header *
init_optionrom(u16 bdf)
@@ -273,17 +289,7 @@
if (! rom)
// No ROM present.
return NULL;
-
- if (! is_valid_rom(rom))
- return NULL;
-
- if (get_pnp_rom(rom))
- // Init the PnP rom.
- callrom(rom, OPTION_ROM_INITVECTOR, bdf);
-
- next_rom += ALIGN(rom->size * 512, OPTION_ROM_ALIGN);
-
- return rom;
+ return verifysize_optionrom(rom, bdf);
}
@@ -325,6 +331,16 @@
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.
diff --git a/src/util.h b/src/util.h
index 0223f7f..5dbbca2 100644
--- a/src/util.h
+++ b/src/util.h
@@ -169,8 +169,11 @@
// coreboot.c
const char *cbfs_findNprefix(const char *prefix, int n);
-int cb_copy_optionrom(void *dst, u32 maxlen, u32 vendev);
+int cbfs_copy_optionrom(void *dst, u32 maxlen, u32 vendev);
void cbfs_run_payload(const char *filename);
+struct cbfs_file;
+struct cbfs_file *cbfs_copy_gen_optionrom(void *dst, u32 maxlen
+ , struct cbfs_file *file);
void coreboot_setup();
// vgahooks.c