#include "farptr.h" // FLATPTR_TO_SEG
#include "config.h" // CONFIG_*
#include "util.h" // dprintf
-#include "pci.h" // pci_find_class
+#include "pci.h" // foreachpci
#include "pci_regs.h" // PCI_ROM_ADDRESS
#include "pci_ids.h" // PCI_CLASS_DISPLAY_VGA
#include "boot.h" // IPL
+#include "paravirt.h" // qemu_cfg_*
/****************************************************************
struct bregs br;
memset(&br, 0, sizeof(br));
+ br.flags = F_IF;
br.ax = bdf;
br.bx = 0xffff;
br.dx = 0xffff;
br.es = SEG_BIOS;
br.di = get_pnp_offset();
- br.cs = seg;
- br.ip = offset;
+ br.code = SEGOFF(seg, offset);
+ start_preempt();
call16big(&br);
+ finish_preempt();
debug_serial_setup();
}
return pci;
}
+// Return the memory position up to which roms may be located.
+static inline u32
+max_rom()
+{
+ extern u8 code32flat_start[];
+ if ((u32)code32flat_start > BUILD_BIOS_ADDR)
+ return BUILD_BIOS_ADDR;
+ return (u32)code32flat_start;
+}
+
// Copy a rom to its permanent location below 1MiB
static struct rom_header *
copy_rom(struct rom_header *rom)
{
u32 romsize = rom->size * 512;
- if (RomEnd + romsize > BUILD_BIOS_ADDR) {
+ if (RomEnd + romsize > max_rom()) {
// Option rom doesn't fit.
dprintf(1, "Option rom %p doesn't fit.\n", rom);
return NULL;
}
dprintf(4, "Copying option rom (size %d) from %p to %x\n"
, romsize, rom, RomEnd);
- memcpy((void*)RomEnd, rom, romsize);
+ iomemcpy((void*)RomEnd, rom, romsize);
return (void*)RomEnd;
}
&& ((OPTIONROM_VENDEV_2 >> 16)
| ((OPTIONROM_VENDEV_2 & 0xffff)) << 16) == vendev)
return copy_rom((void*)OPTIONROM_MEM_2);
- int ret = cbfs_copy_optionrom((void*)RomEnd, BUILD_BIOS_ADDR - RomEnd
- , vendev);
+ int ret = cbfs_copy_optionrom((void*)RomEnd, max_rom() - RomEnd, vendev);
if (ret < 0)
return NULL;
return (void*)RomEnd;
static void
run_cbfs_roms(const char *prefix, int isvga)
{
- struct cbfs_file *tmp = NULL;
+ struct cbfs_file *file = NULL;
for (;;) {
- tmp = cbfs_copyfile_prefix(
- (void*)RomEnd, BUILD_BIOS_ADDR - RomEnd, prefix, tmp);
- if (!tmp)
+ file = cbfs_findprefix(prefix, file);
+ if (!file)
break;
- init_optionrom((void*)RomEnd, 0, isvga);
+ int ret = cbfs_copyfile(file, (void*)RomEnd, max_rom() - RomEnd);
+ if (ret > 0)
+ init_optionrom((void*)RomEnd, 0, isvga);
+ }
+}
+
+static void
+run_qemu_roms(const char *prefix, int isvga)
+{
+ struct QemuCfgFile entry;
+ int plen = strlen(prefix);
+ int rc, dlen;
+
+ rc = qemu_cfg_first_file(&entry);
+ while (rc > 0) {
+ if (memcmp(prefix, entry.name, plen) == 0) {
+ dlen = qemu_cfg_read_file(&entry, (void*)RomEnd, max_rom() - RomEnd);
+ if (dlen > 0) {
+ dprintf(1, "init qemu rom: %s\n", entry.name);
+ init_optionrom((void*)RomEnd, 0, isvga);
+ }
+ }
+ rc = qemu_cfg_next_file(&entry);
}
}
struct rom_header *rom = (void*)orig;
for (;;) {
- dprintf(5, "Inspecting possible rom at %p (dv=%x bdf=%x)\n"
+ dprintf(5, "Inspecting possible rom at %p (dv=%08x bdf=%x)\n"
, rom, vendev, bdf);
if (rom->signature != OPTION_ROM_SIGNATURE) {
dprintf(6, "No option rom signature (got %x)\n", rom->signature);
if (vd == vendev && pci->type == PCIROM_CODETYPE_X86)
// A match
break;
- dprintf(6, "Didn't match dev/ven (got %x) or type (got %d)\n"
+ dprintf(6, "Didn't match dev/ven (got %08x) or type (got %d)\n"
, vd, pci->type);
if (pci->indicator & 0x80) {
dprintf(6, "No more images left\n");
init_pcirom(u16 bdf, int isvga)
{
u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
- dprintf(4, "Attempting to init PCI bdf %02x:%02x.%x (dev/ven %x)\n"
+ dprintf(4, "Attempting to init PCI bdf %02x:%02x.%x (dev/ven %08x)\n"
, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)
, vendev);
struct rom_header *rom = lookup_hardcode(vendev);
if (CONFIG_OPTIONROMS_DEPLOYED) {
// Option roms are already deployed on the system.
u32 pos = RomEnd;
- while (pos < BUILD_BIOS_ADDR) {
+ while (pos < max_rom()) {
int ret = init_optionrom((void*)pos, 0, 0);
if (ret)
pos += OPTION_ROM_ALIGN;
// Find and deploy CBFS roms not associated with a device.
run_cbfs_roms("genroms/", 0);
+ run_qemu_roms("genroms/", 0);
}
// All option roms found and deployed - now build BEV/BCV vectors.
// Find and deploy CBFS vga-style roms not associated with a device.
run_cbfs_roms("vgaroms/", 1);
+ run_qemu_roms("vgaroms/", 1);
}
if (RomEnd == BUILD_ROM_START) {
dprintf(1, "Turning on vga console\n");
struct bregs br;
memset(&br, 0, sizeof(br));
+ br.flags = F_IF;
br.ax = 0x0003;
call16_int(0x10, &br);
// Write to screen.
- printf("Starting SeaBIOS\n\n");
+ printf("Starting SeaBIOS (version %s)\n\n", VERSION);
}
void