Initial KVM support.
Add some of the enhancements KVM has to their bochs bios tree. This is only partial support for KVM - some features still do not work correctly.
This commit is contained in:
parent
0234cd90be
commit
7061eb6aa6
2
Makefile
2
Makefile
|
@ -13,7 +13,7 @@ SRCBOTH=output.c util.c floppy.c ata.c system.c mouse.c kbd.c pci.c \
|
|||
pnpbios.c pirtable.c
|
||||
SRC16=$(SRCBOTH) disk.c apm.c pcibios.c vgahooks.c
|
||||
SRC32=$(SRCBOTH) post.c shadow.c post_menu.c memmap.c coreboot.c boot.c \
|
||||
acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c
|
||||
acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c
|
||||
TABLESRC=font.c cbt.c floppy_dbt.c
|
||||
|
||||
cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
|
||||
|
|
77
src/acpi.c
77
src/acpi.c
|
@ -197,6 +197,21 @@ struct madt_io_apic
|
|||
* lines start */
|
||||
};
|
||||
|
||||
#if CONFIG_KVM
|
||||
/* IRQs 5,9,10,11 */
|
||||
#define PCI_ISA_IRQ_MASK 0x0e20
|
||||
#else
|
||||
#define PCI_ISA_IRQ_MASK 0x0000
|
||||
#endif
|
||||
|
||||
struct madt_intsrcovr {
|
||||
APIC_HEADER_DEF
|
||||
u8 bus;
|
||||
u8 source;
|
||||
u32 gsi;
|
||||
u16 flags;
|
||||
} PACKED;
|
||||
|
||||
#include "acpi-dsdt.hex"
|
||||
|
||||
static inline u16 cpu_to_le16(u16 x)
|
||||
|
@ -398,32 +413,44 @@ void acpi_bios_init(void)
|
|||
memcpy(dsdt, AmlCode, sizeof(AmlCode));
|
||||
|
||||
/* MADT */
|
||||
{
|
||||
struct madt_processor_apic *apic;
|
||||
struct madt_io_apic *io_apic;
|
||||
|
||||
memset(madt, 0, madt_size);
|
||||
madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
|
||||
madt->flags = cpu_to_le32(1);
|
||||
apic = (void *)(madt + 1);
|
||||
for(i=0;i<smp_cpus;i++) {
|
||||
apic->type = APIC_PROCESSOR;
|
||||
apic->length = sizeof(*apic);
|
||||
apic->processor_id = i;
|
||||
apic->local_apic_id = i;
|
||||
apic->flags = cpu_to_le32(1);
|
||||
apic++;
|
||||
}
|
||||
io_apic = (void *)apic;
|
||||
io_apic->type = APIC_IO;
|
||||
io_apic->length = sizeof(*io_apic);
|
||||
io_apic->io_apic_id = smp_cpus;
|
||||
io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
|
||||
io_apic->interrupt = cpu_to_le32(0);
|
||||
|
||||
acpi_build_table_header((struct acpi_table_header *)madt,
|
||||
APIC_SIGNATURE, madt_size, 1);
|
||||
memset(madt, 0, madt_size);
|
||||
madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
|
||||
madt->flags = cpu_to_le32(1);
|
||||
struct madt_processor_apic *apic = (void *)(madt + 1);
|
||||
for(i=0;i<smp_cpus;i++) {
|
||||
apic->type = APIC_PROCESSOR;
|
||||
apic->length = sizeof(*apic);
|
||||
apic->processor_id = i;
|
||||
apic->local_apic_id = i;
|
||||
apic->flags = cpu_to_le32(1);
|
||||
apic++;
|
||||
}
|
||||
struct madt_io_apic *io_apic = (void *)apic;
|
||||
io_apic->type = APIC_IO;
|
||||
io_apic->length = sizeof(*io_apic);
|
||||
io_apic->io_apic_id = smp_cpus;
|
||||
io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
|
||||
io_apic->interrupt = cpu_to_le32(0);
|
||||
|
||||
struct madt_intsrcovr *intsrcovr = (struct madt_intsrcovr*)(io_apic + 1);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (PCI_ISA_IRQ_MASK & (1 << i)) {
|
||||
memset(intsrcovr, 0, sizeof(*intsrcovr));
|
||||
intsrcovr->type = APIC_XRUPT_OVERRIDE;
|
||||
intsrcovr->length = sizeof(*intsrcovr);
|
||||
intsrcovr->source = i;
|
||||
intsrcovr->gsi = i;
|
||||
intsrcovr->flags = 0xd; /* active high, level triggered */
|
||||
} else {
|
||||
/* No need for a INT source override structure. */
|
||||
continue;
|
||||
}
|
||||
intsrcovr++;
|
||||
madt_size += sizeof(struct madt_intsrcovr);
|
||||
}
|
||||
|
||||
acpi_build_table_header((struct acpi_table_header *)madt,
|
||||
APIC_SIGNATURE, madt_size, 1);
|
||||
}
|
||||
|
||||
u32
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#define CONFIG_APPNAME6 "BOCHS "
|
||||
#define CONFIG_APPNAME4 "BXPC"
|
||||
|
||||
// Configure for use with KVM.
|
||||
#define CONFIG_KVM 0
|
||||
// Configure as a coreboot payload.
|
||||
#define CONFIG_COREBOOT 0
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// Initialize MTRRs - mostly useful on KVM.
|
||||
//
|
||||
// Copyright (C) 2006 Fabrice Bellard
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "util.h" // dprintf
|
||||
#include "biosvar.h" // GET_EBDA
|
||||
|
||||
#define MSR_MTRRcap 0x000000fe
|
||||
#define MSR_MTRRfix64K_00000 0x00000250
|
||||
#define MSR_MTRRfix16K_80000 0x00000258
|
||||
#define MSR_MTRRfix16K_A0000 0x00000259
|
||||
#define MSR_MTRRfix4K_C0000 0x00000268
|
||||
#define MSR_MTRRfix4K_C8000 0x00000269
|
||||
#define MSR_MTRRfix4K_D0000 0x0000026a
|
||||
#define MSR_MTRRfix4K_D8000 0x0000026b
|
||||
#define MSR_MTRRfix4K_E0000 0x0000026c
|
||||
#define MSR_MTRRfix4K_E8000 0x0000026d
|
||||
#define MSR_MTRRfix4K_F0000 0x0000026e
|
||||
#define MSR_MTRRfix4K_F8000 0x0000026f
|
||||
#define MSR_MTRRdefType 0x000002ff
|
||||
|
||||
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
static u64 rdmsr(unsigned index)
|
||||
{
|
||||
unsigned long long ret;
|
||||
|
||||
asm ("rdmsr" : "=A"(ret) : "c"(index));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wrmsr(unsigned index, u64 val)
|
||||
{
|
||||
asm volatile ("wrmsr" : : "c"(index), "A"(val));
|
||||
}
|
||||
|
||||
static void wrmsr_smp(u32 index, u64 val)
|
||||
{
|
||||
// XXX - should run this on other CPUs also.
|
||||
wrmsr(index, val);
|
||||
}
|
||||
|
||||
void mtrr_setup(void)
|
||||
{
|
||||
if (! CONFIG_KVM)
|
||||
return;
|
||||
dprintf(3, "init mtrr\n");
|
||||
|
||||
int i, vcnt, fix, wc;
|
||||
u32 ram_size = GET_GLOBAL(RamSize);
|
||||
u32 mtrr_cap;
|
||||
union {
|
||||
u8 valb[8];
|
||||
u64 val;
|
||||
} u;
|
||||
|
||||
mtrr_cap = rdmsr(MSR_MTRRcap);
|
||||
vcnt = mtrr_cap & 0xff;
|
||||
fix = mtrr_cap & 0x100;
|
||||
wc = mtrr_cap & 0x400;
|
||||
if (!vcnt || !fix)
|
||||
return;
|
||||
u.val = 0;
|
||||
for (i = 0; i < 8; ++i)
|
||||
if (ram_size >= 65536 * (i + 1))
|
||||
u.valb[i] = 6;
|
||||
wrmsr_smp(MSR_MTRRfix64K_00000, u.val);
|
||||
u.val = 0;
|
||||
for (i = 0; i < 8; ++i)
|
||||
if (ram_size >= 65536 * 8 + 16384 * (i + 1))
|
||||
u.valb[i] = 6;
|
||||
wrmsr_smp(MSR_MTRRfix16K_80000, u.val);
|
||||
wrmsr_smp(MSR_MTRRfix16K_A0000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_C0000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_C8000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_D0000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_D8000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_E0000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_E8000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_F0000, 0);
|
||||
wrmsr_smp(MSR_MTRRfix4K_F8000, 0);
|
||||
/* Mark 3.5-4GB as UC, anything not specified defaults to WB */
|
||||
wrmsr_smp(MTRRphysBase_MSR(0), 0xe0000000ull | 0);
|
||||
wrmsr_smp(MTRRphysMask_MSR(0), ~(0x20000000ull - 1) | 0x800);
|
||||
wrmsr_smp(MSR_MTRRdefType, 0xc06);
|
||||
}
|
|
@ -18,7 +18,13 @@ static u32 pci_bios_io_addr;
|
|||
static u32 pci_bios_mem_addr;
|
||||
static u32 pci_bios_bigmem_addr;
|
||||
/* host irqs corresponding to PCI irqs A-D */
|
||||
static u8 pci_irqs[4] = { 11, 9, 11, 9 };
|
||||
static u8 pci_irqs[4] = {
|
||||
#if CONFIG_KVM
|
||||
10, 10, 11, 11
|
||||
#else
|
||||
11, 9, 11, 9
|
||||
#endif
|
||||
};
|
||||
|
||||
static void pci_set_io_region_addr(u16 bdf, int region_num, u32 addr)
|
||||
{
|
||||
|
@ -176,6 +182,11 @@ static void pci_bios_init_device(u16 bdf)
|
|||
if (vendor_id == PCI_VENDOR_ID_INTEL
|
||||
&& device_id == PCI_DEVICE_ID_INTEL_82371AB_3) {
|
||||
/* PIIX4 Power Management device (for ACPI) */
|
||||
|
||||
if (CONFIG_KVM)
|
||||
// acpi sci is hardwired to 9
|
||||
pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
|
||||
|
||||
pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1);
|
||||
pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
|
||||
pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
|
||||
|
|
|
@ -126,6 +126,11 @@ ram_probe(void)
|
|||
, E820_RESERVED);
|
||||
add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED);
|
||||
|
||||
if (CONFIG_KVM)
|
||||
// 4 pages before the bios, 3 pages for vmx tss pages, the
|
||||
// other page for EPT real mode pagetable
|
||||
add_e820(0xfffbc000, 4*4096, E820_RESERVED);
|
||||
|
||||
dprintf(1, "Ram Size=0x%08x\n", RamSize);
|
||||
}
|
||||
|
||||
|
@ -197,6 +202,7 @@ post()
|
|||
|
||||
memmap_setup();
|
||||
ram_probe();
|
||||
mtrr_setup();
|
||||
|
||||
pnp_setup();
|
||||
vga_setup();
|
||||
|
|
|
@ -178,6 +178,9 @@ void init_dma();
|
|||
u16 get_pnp_offset();
|
||||
void pnp_setup();
|
||||
|
||||
// mtrr.c
|
||||
void mtrr_setup(void);
|
||||
|
||||
// romlayout.S
|
||||
void reset_vector() __attribute__ ((noreturn));
|
||||
|
||||
|
|
Loading…
Reference in New Issue