#include "mptable.h" // MPTABLE_SIGNATURE
#include "biosvar.h" // GET_EBDA
#include "lzmadecode.h" // LzmaDecode
+#include "smbios.h" // smbios_init
/****************************************************************
return NULL;
}
+// Find next file with the given filename prefix.
struct cbfs_file *
cbfs_findprefix(const char *prefix, struct cbfs_file *last)
{
// Find a file with the given filename (possibly with ".lzma" extension).
static struct cbfs_file *
-cbfs_finddatafile(const char *fname, int *iscomp)
+cbfs_finddatafile(const char *fname)
{
int fnlen = strlen(fname);
struct cbfs_file *file = NULL;
file = cbfs_findprefix(fname, file);
if (!file)
return NULL;
- if (file->filename[fnlen] == '\0') {
- *iscomp = 0;
+ if (file->filename[fnlen] == '\0'
+ || strcmp(&file->filename[fnlen], ".lzma") == 0)
return file;
- }
- if (strcmp(&file->filename[fnlen], ".lzma") == 0) {
- *iscomp = 1;
- return file;
- }
}
}
-// Locate a datafile with the given prefix.
-struct cbfs_file *
-cbfs_finddataprefix(const char *prefix, struct cbfs_file *last, int *iscomp)
+// Determine whether the file has a ".lzma" extension.
+static int
+cbfs_iscomp(struct cbfs_file *file)
{
- struct cbfs_file *file = cbfs_findprefix(prefix, last);
- if (!file)
- return NULL;
int fnamelen = strlen(file->filename);
- *iscomp = (fnamelen > 5
- && strcmp(&file->filename[fnamelen-5], ".lzma") == 0);
- return file;
+ return fnamelen > 5 && strcmp(&file->filename[fnamelen-5], ".lzma") == 0;
}
// Return the filename of a given file.
// Determine the uncompressed size of a datafile.
u32
-cbfs_datasize(struct cbfs_file *file, int iscomp)
+cbfs_datasize(struct cbfs_file *file)
{
void *src = (void*)file + ntohl(file->offset);
- if (iscomp)
+ if (cbfs_iscomp(file))
return *(u32*)(src + LZMA_PROPERTIES_SIZE);
return ntohl(file->len);
}
// Copy a file to memory (uncompressing if necessary)
int
-cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen, int iscomp)
+cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen)
{
if (! CONFIG_COREBOOT_FLASH || !file)
return -1;
u32 size = ntohl(file->len);
void *src = (void*)file + ntohl(file->offset);
- if (iscomp)
- // Compressed.
- return ulzma(dst, maxlen, src, size);
+ if (cbfs_iscomp(file)) {
+ // Compressed - copy to temp ram and uncompress it.
+ u32 asize = ALIGN(size, 4);
+ void *temp = malloc_tmphigh(asize);
+ if (!temp)
+ return -1;
+ iomemcpy(temp, src, asize);
+ int ret = ulzma(dst, maxlen, temp, size);
+ yield();
+ free(temp);
+ return ret;
+ }
// Not compressed.
dprintf(3, "Copying data %d@%p to %d@%p\n", size, src, maxlen, dst);
dprintf(1, "File too big to copy\n");
return -1;
}
- memcpy(dst, src, size);
+ iomemcpy(dst, src, size);
return size;
}
-static char
-getHex(u8 x)
-{
- if (x <= 9)
- return '0' + x;
- return 'a' + x - 10;
-}
-
-static u32
-hexify4(u16 x)
-{
- return ((getHex(x&0xf) << 24)
- | (getHex((x>>4)&0xf) << 16)
- | (getHex((x>>8)&0xf) << 8)
- | (getHex(x>>12)));
-}
-
// Find and copy the optionrom for the given vendor/device id.
int
cbfs_copy_optionrom(void *dst, u32 maxlen, u32 vendev)
return -1;
char fname[17];
- // Ughh - poor man's sprintf of "pci%04x,%04x.rom"
- *(u32*)fname = 0x20696370; // "pci "
- *(u32*)&fname[3] = hexify4(vendev);
- fname[7] = ',';
- *(u32*)&fname[8] = hexify4(vendev >> 16);
- *(u32*)&fname[12] = 0x6d6f722e; // ".rom"
- fname[16] = '\0';
-
- int iscomp;
- struct cbfs_file *file = cbfs_finddatafile(fname, &iscomp);
- return cbfs_copyfile(file, dst, maxlen, iscomp);
+ snprintf(fname, sizeof(fname), "pci%04x,%04x.rom"
+ , (u16)vendev, vendev >> 16);
+ return cbfs_copyfile(cbfs_finddatafile(fname), dst, maxlen);
}
struct cbfs_payload_segment {