SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c \
- biostables.c xen.c bmp.c
+ biostables.c xen.c bmp.c romfile.c
SRC32SEG=util.c output.c pci.c pcibios.c apm.c stacks.c
# Default compiler flags
#include "bregs.h" // struct bregs
#include "boot.h" // func defs
#include "cmos.h" // inb_cmos
-#include "paravirt.h" // romfile_loadfile
-#include "pci.h" //pci_bdf_to_*
+#include "paravirt.h" // qemu_cfg_show_boot_menu
+#include "pci.h" // pci_bdf_to_*
#include "usb.h" // struct usbdevice_s
#include "config.h" // CONFIG_*
#include "util.h" // dprintf
#include "jpeg.h" // splash
-#include "paravirt.h" // romfile_find
#include "vbe.h" // struct vbe_info
#include "bmp.h"
const char *CBvendor = "", *CBpart = "";
// Populate max ram and e820 map info by scanning for a coreboot table.
-static void
-coreboot_fill_map(void)
+void
+coreboot_setup(void)
{
dprintf(3, "Attempting to find coreboot table\n");
u32 pad[2];
} PACKED;
-static struct cbfs_header *CBHDR;
-
-static void
-cbfs_setup(void)
-{
- if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
- return;
-
- CBHDR = *(void **)CBFS_HEADPTR_ADDR;
- if (CBHDR->magic != htonl(CBFS_HEADER_MAGIC)) {
- dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n"
- , CBHDR, CBHDR->magic, htonl(CBFS_HEADER_MAGIC));
- CBHDR = NULL;
- return;
- }
-
- dprintf(1, "Found CBFS header at %p\n", CBHDR);
-}
-
#define CBFS_FILE_MAGIC 0x455649484352414cLL // LARCHIVE
struct cbfs_file {
char filename[0];
} PACKED;
-// Verify a cbfs entry looks valid.
-static struct cbfs_file *
-cbfs_verify(struct cbfs_file *file)
-{
- if (file < (struct cbfs_file *)(0xFFFFFFFF - ntohl(CBHDR->romsize)))
- return NULL;
- u64 magic = file->magic;
- if (magic == CBFS_FILE_MAGIC) {
- dprintf(8, "Found CBFS file %s\n", file->filename);
- return file;
- }
- return NULL;
-}
-
-// Return the first file in the CBFS archive
-static struct cbfs_file *
-cbfs_getfirst(void)
-{
- if (! CBHDR)
- return NULL;
- return cbfs_verify((void *)(0 - ntohl(CBHDR->romsize) + ntohl(CBHDR->offset)));
-}
-
-// Return the file after the given file.
-static struct cbfs_file *
-cbfs_getnext(struct cbfs_file *file)
-{
- file = (void*)file + ALIGN(ntohl(file->len) + ntohl(file->offset), ntohl(CBHDR->align));
- return cbfs_verify(file);
-}
-
-// Find the file with the given filename.
-struct cbfs_file *
-cbfs_findfile(const char *fname)
-{
- dprintf(7, "Searching CBFS for %s\n", fname);
- struct cbfs_file *file;
- for (file = cbfs_getfirst(); file; file = cbfs_getnext(file))
- if (strcmp(fname, file->filename) == 0)
- return file;
- return NULL;
-}
-
-// Find next file with the given filename prefix.
-struct cbfs_file *
-cbfs_findprefix(const char *prefix, struct cbfs_file *last)
-{
- if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
- return NULL;
-
- dprintf(7, "Searching CBFS for prefix %s\n", prefix);
- int len = strlen(prefix);
- struct cbfs_file *file;
- if (! last)
- file = cbfs_getfirst();
- else
- file = cbfs_getnext(last);
- for (; file; file = cbfs_getnext(file))
- if (memcmp(prefix, file->filename, len) == 0)
- return file;
- return NULL;
-}
-
-// Find a file with the given filename (possibly with ".lzma" extension).
-struct cbfs_file *
-cbfs_finddatafile(const char *fname)
-{
- int fnlen = strlen(fname);
- struct cbfs_file *file = NULL;
- for (;;) {
- file = cbfs_findprefix(fname, file);
- if (!file)
- return NULL;
- if (file->filename[fnlen] == '\0'
- || strcmp(&file->filename[fnlen], ".lzma") == 0)
- return file;
- }
-}
-
-// Determine whether the file has a ".lzma" extension.
-static int
-cbfs_iscomp(struct cbfs_file *file)
-{
- int fnamelen = strlen(file->filename);
- return fnamelen > 5 && strcmp(&file->filename[fnamelen-5], ".lzma") == 0;
-}
-
-// Return the filename of a given file.
-const char *
-cbfs_filename(struct cbfs_file *file)
-{
- return file->filename;
-}
-
-// Determine the uncompressed size of a datafile.
-u32
-cbfs_datasize(struct cbfs_file *file)
-{
- void *src = (void*)file + ntohl(file->offset);
- 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)
+static int
+cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen)
{
- if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !file)
+ if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
return -1;
- u32 size = ntohl(file->len);
- void *src = (void*)file + ntohl(file->offset);
- if (cbfs_iscomp(file)) {
+ u32 size = file->rawsize;
+ void *src = file->data;
+ if (file->flags) {
// Compressed - copy to temp ram and uncompress it.
void *temp = malloc_tmphigh(size);
- if (!temp)
+ if (!temp) {
+ warn_noalloc();
return -1;
+ }
iomemcpy(temp, src, size);
int ret = ulzma(dst, maxlen, temp, size);
yield();
return size;
}
+void
+coreboot_cbfs_setup(void)
+{
+ if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
+ return;
+
+ struct cbfs_header *hdr = *(void **)CBFS_HEADPTR_ADDR;
+ if (hdr->magic != htonl(CBFS_HEADER_MAGIC)) {
+ dprintf(1, "Unable to find CBFS (ptr=%p; got %x not %x)\n"
+ , hdr, hdr->magic, htonl(CBFS_HEADER_MAGIC));
+ return;
+ }
+ dprintf(1, "Found CBFS header at %p\n", hdr);
+
+ struct cbfs_file *cfile = (void *)(0 - ntohl(hdr->romsize)
+ + ntohl(hdr->offset));
+ for (;;) {
+ if (cfile < (struct cbfs_file *)(0xFFFFFFFF - ntohl(hdr->romsize)))
+ break;
+ u64 magic = cfile->magic;
+ if (magic != CBFS_FILE_MAGIC)
+ break;
+ struct romfile_s *file = malloc_tmp(sizeof(*file));
+ if (!file) {
+ warn_noalloc();
+ break;
+ }
+ memset(file, 0, sizeof(*file));
+ strtcpy(file->name, cfile->filename, sizeof(file->name));
+ dprintf(3, "Found CBFS file: %s\n", file->name);
+ file->size = file->rawsize = ntohl(cfile->len);
+ file->id = (u32)cfile;
+ file->copy = cbfs_copyfile;
+ file->data = (void*)cfile + ntohl(cfile->offset);
+ int len = strlen(file->name);
+ if (len > 5 && strcmp(&file->name[len-5], ".lzma") == 0) {
+ // Using compression.
+ file->flags = 1;
+ file->name[len-5] = '\0';
+ file->size = *(u32*)(file->data + LZMA_PROPERTIES_SIZE);
+ }
+ romfile_add(file);
+
+ cfile = (void*)ALIGN((u32)file->data + file->size, ntohl(hdr->align));
+ }
+}
+
struct cbfs_payload_segment {
u32 type;
u32 compression;
void
cbfs_payload_setup(void)
{
- struct cbfs_file *file = NULL;
+ if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH)
+ return;
+ struct romfile_s *file = NULL;
for (;;) {
- file = cbfs_findprefix("img/", file);
+ file = romfile_findprefix("img/", file);
if (!file)
break;
- const char *filename = cbfs_filename(file);
+ const char *filename = file->name;
char *desc = znprintf(MAXDESCSIZE, "Payload [%s]", &filename[4]);
- boot_add_cbfs(file, desc, bootprio_find_named_rom(filename, 0));
+ boot_add_cbfs((void*)file->id, desc
+ , bootprio_find_named_rom(filename, 0));
}
}
-
-void
-coreboot_setup(void)
-{
- coreboot_fill_map();
- cbfs_setup();
-}
#include "pci_regs.h" // PCI_ROM_ADDRESS
#include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
#include "boot.h" // IPL
-#include "paravirt.h" // qemu_cfg_*
#include "optionroms.h" // struct rom_header
return -1;
if (source & RS_PCIROM)
return bootprio_find_pci_rom((void*)(u32)source, instance);
- return bootprio_find_named_rom(romfile_name(source), instance);
+ struct romfile_s *file = (void*)(u32)source;
+ return bootprio_find_named_rom(file->name, instance);
}
****************************************************************/
static struct rom_header *
-deploy_romfile(u32 file)
+deploy_romfile(struct romfile_s *file)
{
- u32 size = romfile_size(file);
+ u32 size = file->size;
struct rom_header *rom = rom_reserve(size);
if (!rom) {
warn_noalloc();
return NULL;
}
- int ret = romfile_copy(file, rom, size);
+ int ret = file->copy(file, rom, size);
if (ret <= 0)
return NULL;
return rom;
char fname[17];
snprintf(fname, sizeof(fname), "pci%04x,%04x.rom"
, pci->vendor, pci->device);
- u32 file = romfile_find(fname);
+ struct romfile_s *file = romfile_find(fname);
if (file)
return deploy_romfile(file);
return NULL;
static void
run_file_roms(const char *prefix, int isvga, u64 *sources)
{
- u32 file = 0;
+ struct romfile_s *file = NULL;
for (;;) {
file = romfile_findprefix(prefix, file);
if (!file)
break;
struct rom_header *rom = deploy_romfile(file);
if (rom) {
- setRomSource(sources, rom, file);
+ setRomSource(sources, rom, (u32)file);
init_optionrom(rom, 0, isvga);
}
}
return cnt;
}
-static QemuCfgFile LastFile;
-
-static u32
-__cfg_next_prefix_file(const char *prefix, int prefixlen, u32 prevselect)
-{
- if (!qemu_cfg_present)
- return 0;
-
- u32 count;
- qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
- count = ntohl(count);
- u32 e;
- for (e = 0; e < count; e++) {
- qemu_cfg_read((void*)&LastFile, sizeof(LastFile));
- u32 select = ntohs(LastFile.select);
- if (select <= prevselect)
- continue;
- if (memcmp(prefix, LastFile.name, prefixlen) == 0)
- return select;
- }
- return 0;
-}
-
-u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect)
+int qemu_cfg_read_file(struct romfile_s *file, void *dst, u32 maxlen)
{
- return __cfg_next_prefix_file(prefix, strlen(prefix), prevselect);
+ if (file->size > maxlen)
+ return -1;
+ qemu_cfg_read_entry(dst, file->id, file->size);
+ return file->size;
}
-u32 qemu_cfg_find_file(const char *name)
-{
- return __cfg_next_prefix_file(name, strlen(name) + 1, 0);
-}
+struct QemuCfgFile {
+ u32 size; /* file size */
+ u16 select; /* write this to 0x510 to read it */
+ u16 reserved;
+ char name[56];
+};
-static int
-__qemu_cfg_set_file(u32 select)
+void qemu_cfg_romfile_setup(void)
{
- if (!qemu_cfg_present || !select)
- return -1;
- if (select == ntohs(LastFile.select))
- return 0;
+ if (CONFIG_COREBOOT || !qemu_cfg_present)
+ return;
u32 count;
qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
count = ntohl(count);
u32 e;
for (e = 0; e < count; e++) {
- qemu_cfg_read((void*)&LastFile, sizeof(LastFile));
- if (select == ntohs(LastFile.select))
- return 0;
- }
- return -1;
-}
-
-int qemu_cfg_size_file(u32 select)
-{
- if (__qemu_cfg_set_file(select))
- return -1;
- return ntohl(LastFile.size);
-}
-
-const char* qemu_cfg_name_file(u32 select)
-{
- if (__qemu_cfg_set_file(select))
- return NULL;
- return LastFile.name;
-}
-
-int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen)
-{
- if (__qemu_cfg_set_file(select))
- return -1;
- int len = qemu_cfg_size_file(select);
- if (len < 0 || len > maxlen)
- return -1;
- qemu_cfg_read_entry(dst, select, len);
- return len;
-}
-
-// Helper function to find, malloc_tmphigh, and copy a romfile. This
-// function adds a trailing zero to the malloc'd copy.
-void *
-romfile_loadfile(const char *name, int *psize)
-{
- u32 file = romfile_find(name);
- if (!file)
- return NULL;
-
- int filesize = romfile_size(file);
- if (!filesize)
- return NULL;
-
- char *data = malloc_tmphigh(filesize+1);
- if (!data) {
- warn_noalloc();
- return NULL;
+ struct QemuCfgFile qfile;
+ qemu_cfg_read((void*)&qfile, sizeof(qfile));
+ struct romfile_s *file = malloc_tmp(sizeof(*file));
+ if (!file) {
+ warn_noalloc();
+ return;
+ }
+ memset(file, 0, sizeof(*file));
+ strtcpy(file->name, qfile.name, sizeof(file->name));
+ file->size = ntohl(qfile.size);
+ file->id = ntohs(qfile.select);
+ file->copy = qemu_cfg_read_file;
+ romfile_add(file);
+ dprintf(3, "Found fw_cfg file: %s (size=%d)\n", file->name, file->size);
}
-
- dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
- romfile_copy(file, data, filesize);
- if (psize)
- *psize = filesize;
- data[filesize] = '\0';
- return data;
-}
-
-// Attempt to load an integer from the given file - return 'defval'
-// if unsuccesful.
-u64
-romfile_loadint(const char *name, u64 defval)
-{
- u32 file = romfile_find(name);
- if (!file)
- return defval;
-
- int filesize = romfile_size(file);
- if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
- // Doesn't look like a valid integer.
- return defval;
-
- u64 val = 0;
- romfile_copy(file, &val, sizeof(val));
- return val;
}
int qemu_cfg_get_numa_nodes(void);
void qemu_cfg_get_numa_data(u64 *data, int n);
u16 qemu_cfg_get_max_cpus(void);
-
-typedef struct QemuCfgFile {
- u32 size; /* file size */
- u16 select; /* write this to 0x510 to read it */
- u16 reserved;
- char name[56];
-} QemuCfgFile;
-
struct e820_reservation {
u64 address;
u64 length;
u32 type;
};
-
-u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect);
-u32 qemu_cfg_find_file(const char *name);
-int qemu_cfg_size_file(u32 select);
-const char* qemu_cfg_name_file(u32 select);
-int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen);
-
-// Wrappers that select cbfs or qemu_cfg file interface.
-static inline u32 romfile_findprefix(const char *prefix, u32 previd) {
- if (CONFIG_COREBOOT)
- return (u32)cbfs_findprefix(prefix, (void*)previd);
- return qemu_cfg_next_prefix_file(prefix, previd);
-}
-static inline u32 romfile_find(const char *name) {
- if (CONFIG_COREBOOT)
- return (u32)cbfs_finddatafile(name);
- return qemu_cfg_find_file(name);
-}
-static inline u32 romfile_size(u32 fileid) {
- if (CONFIG_COREBOOT)
- return cbfs_datasize((void*)fileid);
- return qemu_cfg_size_file(fileid);
-}
-static inline int romfile_copy(u32 fileid, void *dst, u32 maxlen) {
- if (CONFIG_COREBOOT)
- return cbfs_copyfile((void*)fileid, dst, maxlen);
- return qemu_cfg_read_file(fileid, dst, maxlen);
-}
-static inline const char* romfile_name(u32 fileid) {
- if (CONFIG_COREBOOT)
- return cbfs_filename((void*)fileid);
- return qemu_cfg_name_file(fileid);
-}
-void *romfile_loadfile(const char *name, int *psize);
-u64 romfile_loadint(const char *name, u64 defval);
-
u32 qemu_cfg_e820_entries(void);
void* qemu_cfg_e820_load_next(void *addr);
+void qemu_cfg_romfile_setup(void);
#endif
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
+#include "config.h" // CONFIG_*
#include "pci.h" // pci_config_writel
#include "ioport.h" // outl
#include "util.h" // dprintf
-#include "paravirt.h" // romfile_loadint
#include "farptr.h" // MAKE_FLATPTR
#include "pci_regs.h" // PCI_VENDOR_ID
#include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
static void
maininit(void)
{
+ // Setup romfile items.
+ qemu_cfg_romfile_setup();
+ coreboot_cbfs_setup();
+
// Setup ivt/bda/ebda
init_ivt();
init_bda();
#include "ioport.h" // inb
#include "util.h" // dprintf
-#include "paravirt.h" // romfile_loadint
#include "biosvar.h" // GET_LOW
#include "ps2port.h" // ps2_kbd_command
#include "pic.h" // eoi_pic1
void
ramdisk_setup(void)
{
- if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY)
+ if (!CONFIG_FLASH_FLOPPY)
return;
// Find image.
- struct cbfs_file *file = cbfs_findprefix("floppyimg/", NULL);
+ struct romfile_s *file = romfile_findprefix("floppyimg/", NULL);
if (!file)
return;
- const char *filename = cbfs_filename(file);
- u32 size = cbfs_datasize(file);
+ const char *filename = file->name;
+ u32 size = file->size;
dprintf(3, "Found floppy file %s of size %d\n", filename, size);
int ftype = find_floppy_type(size);
if (ftype < 0) {
add_e820((u32)pos, size, E820_RESERVED);
// Copy image into ram.
- cbfs_copyfile(file, pos, size);
+ int ret = file->copy(file, pos, size);
+ if (ret < 0)
+ return;
// Setup driver.
struct drive_s *drive_g = init_floppy((u32)pos, ftype);
--- /dev/null
+// Access to pseudo "file" interface for configuration information.
+//
+// Copyright (C) 2012 Kevin O'Connor <kevin@koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_*
+#include "util.h" // dprintf
+
+static struct romfile_s *RomfileRoot;
+
+void
+romfile_add(struct romfile_s *file)
+{
+ file->next = RomfileRoot;
+ RomfileRoot = file;
+}
+
+// Search for the specified file.
+static struct romfile_s *
+__romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev)
+{
+ struct romfile_s *cur = RomfileRoot;
+ if (prev)
+ cur = prev->next;
+ while (cur) {
+ if (memcmp(prefix, cur->name, prefixlen) == 0)
+ return cur;
+ cur = cur->next;
+ }
+ return NULL;
+}
+
+struct romfile_s *
+romfile_findprefix(const char *prefix, struct romfile_s *prev)
+{
+ return __romfile_findprefix(prefix, strlen(prefix), prev);
+}
+
+struct romfile_s *
+romfile_find(const char *name)
+{
+ return __romfile_findprefix(name, strlen(name) + 1, NULL);
+}
+
+// Helper function to find, malloc_tmphigh, and copy a romfile. This
+// function adds a trailing zero to the malloc'd copy.
+void *
+romfile_loadfile(const char *name, int *psize)
+{
+ struct romfile_s *file = romfile_find(name);
+ if (!file)
+ return NULL;
+
+ int filesize = file->size;
+ if (!filesize)
+ return NULL;
+
+ char *data = malloc_tmphigh(filesize+1);
+ if (!data) {
+ warn_noalloc();
+ return NULL;
+ }
+
+ dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
+ int ret = file->copy(file, data, filesize);
+ if (ret < 0) {
+ free(data);
+ return NULL;
+ }
+ if (psize)
+ *psize = filesize;
+ data[filesize] = '\0';
+ return data;
+}
+
+// Attempt to load an integer from the given file - return 'defval'
+// if unsuccesful.
+u64
+romfile_loadint(const char *name, u64 defval)
+{
+ struct romfile_s *file = romfile_find(name);
+ if (!file)
+ return defval;
+
+ int filesize = file->size;
+ if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
+ // Doesn't look like a valid integer.
+ return defval;
+
+ u64 val = 0;
+ int ret = file->copy(file, &val, sizeof(val));
+ if (ret < 0)
+ return defval;
+ return val;
+}
// coreboot.c
extern const char *CBvendor, *CBpart;
struct cbfs_file;
-struct cbfs_file *cbfs_finddatafile(const char *fname);
-struct cbfs_file *cbfs_findprefix(const char *prefix, struct cbfs_file *last);
-u32 cbfs_datasize(struct cbfs_file *file);
-const char *cbfs_filename(struct cbfs_file *file);
-int cbfs_copyfile(struct cbfs_file *file, void *dst, u32 maxlen);
void cbfs_run_payload(struct cbfs_file *file);
void coreboot_copy_biostable(void);
void cbfs_payload_setup(void);
void coreboot_setup(void);
+void coreboot_cbfs_setup(void);
// biostable.c
void copy_pir(void *pos);
// mtrr.c
void mtrr_setup(void);
+// romfile.c
+struct romfile_s {
+ struct romfile_s *next;
+ char name[128];
+ u32 size;
+ int (*copy)(struct romfile_s *file, void *dest, u32 maxlen);
+
+ u32 id;
+ u32 rawsize;
+ u32 flags;
+ void *data;
+};
+void romfile_add(struct romfile_s *file);
+struct romfile_s *romfile_findprefix(const char *prefix, struct romfile_s *prev);
+struct romfile_s *romfile_find(const char *name);
+void *romfile_loadfile(const char *name, int *psize);
+u64 romfile_loadint(const char *name, u64 defval);
+
// romlayout.S
void reset_vector(void) __noreturn;