@@ -101,3 +101,4 @@ CONFIG_ALLWINNER_A10=y
CONFIG_XIO3130=y
CONFIG_IOH3420=y
CONFIG_I82801B11=y
+CONFIG_ACPI=y
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_IDE_ISA=y
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_PIIX4=y
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_PIIX4=y
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_PIIX4=y
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_PIIX4=y
@@ -15,6 +15,9 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_IDE_ISA=y
@@ -1,5 +1,6 @@
-common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
-common-obj-$(CONFIG_ACPI) += memory_hotplug.o
+common-obj-$(CONFIG_ACPI_CORE) += core.o piix4.o ich9.o pcihp.o
+common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
+common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
common-obj-$(CONFIG_ACPI) += aml-build.o
@@ -43,6 +43,7 @@
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "hw/pci-host/gpex.h"
+#include "hw/arm/virt-acpi-build.h"
#define NUM_VIRTIO_TRANSPORTS 32
@@ -60,6 +61,11 @@
#define GIC_FDT_IRQ_PPI_CPU_START 8
#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
+#define ARCH_TIMER_VIRT_IRQ 11
+#define ARCH_TIMER_S_EL1_IRQ 13
+#define ARCH_TIMER_NS_EL1_IRQ 14
+#define ARCH_TIMER_NS_EL2_IRQ 10
+
enum {
VIRT_FLASH,
VIRT_MEM,
@@ -149,6 +155,29 @@ static const int a15irqmap[] = {
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
};
+static acpi_madt_info madt_info = {
+ &a15memmap[VIRT_GIC_CPU].base,
+ &a15memmap[VIRT_GIC_DIST].base
+};
+
+static acpi_dsdt_info dsdt_info = {
+ .uart_addr = &a15memmap[VIRT_UART].base,
+ .uart_irq = &a15irqmap[VIRT_UART],
+ .virtio_mmio_addr = &a15memmap[VIRT_MMIO].base,
+ .virtio_mmio_irq = &a15irqmap[VIRT_MMIO],
+ .virtio_mmio_num = NUM_VIRTIO_TRANSPORTS,
+ .rtc_addr = &a15memmap[VIRT_RTC].base,
+ .rtc_irq = &a15irqmap[VIRT_RTC],
+ .flash_addr = &a15memmap[VIRT_FLASH].base,
+};
+
+static acpi_gtdt_info gtdt_info = {
+ ARCH_TIMER_VIRT_IRQ + 16,
+ ARCH_TIMER_S_EL1_IRQ + 16,
+ ARCH_TIMER_NS_EL1_IRQ + 16,
+ ARCH_TIMER_NS_EL2_IRQ + 16
+};
+
static VirtBoardInfo machines[] = {
{
.cpu_model = "cortex-a15",
@@ -289,10 +318,10 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
"arm,armv7-timer");
}
qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts",
- GIC_FDT_IRQ_TYPE_PPI, 13, irqflags,
- GIC_FDT_IRQ_TYPE_PPI, 14, irqflags,
- GIC_FDT_IRQ_TYPE_PPI, 11, irqflags,
- GIC_FDT_IRQ_TYPE_PPI, 10, irqflags);
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
+ GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
}
static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
@@ -633,8 +662,8 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
0x7 /* PCI irq */);
}
-static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
- uint32_t gic_phandle)
+static acpi_pcie_info *create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
+ uint32_t gic_phandle)
{
hwaddr base = vbi->memmap[VIRT_PCIE].base;
hwaddr size = vbi->memmap[VIRT_PCIE].size;
@@ -654,6 +683,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
DeviceState *dev;
char *nodename;
int i;
+ acpi_pcie_info *pcie_info;
base_ecam = QEMU_ALIGN_DOWN(end - size_ecam, size_ecam);
base_ioport = QEMU_ALIGN_DOWN(base_ecam - size_ioport, size_ioport);
@@ -709,6 +739,18 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
create_pcie_irq_map(vbi, gic_phandle, irq, nodename);
g_free(nodename);
+
+ pcie_info = g_malloc0(sizeof *pcie_info);
+ pcie_info->pcie_mmio_base = base_mmio;
+ pcie_info->pcie_mmio_size = size_mmio;
+ pcie_info->pcie_ioport_base = base_ioport;
+ pcie_info->pcie_ioport_size = size_ioport;
+ pcie_info->pcie_ecam_base = base_ecam;
+ pcie_info->pcie_ecam_size = size_ecam;
+ pcie_info->nr_pcie_buses = nr_pcie_buses;
+ pcie_info->pcie_irq = &a15irqmap[VIRT_PCIE];
+
+ return pcie_info;
}
static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
@@ -719,6 +761,15 @@ static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
return board->fdt;
}
+static
+void virt_guest_info_machine_done(Notifier *notifier, void *data)
+{
+ VirtGuestInfoState *guest_info_state = container_of(notifier,
+ VirtGuestInfoState,
+ machine_done);
+ virt_acpi_setup(&guest_info_state->info);
+}
+
static void machvirt_init(MachineState *machine)
{
VirtMachineState *vms = VIRT_MACHINE(machine);
@@ -728,6 +779,8 @@ static void machvirt_init(MachineState *machine)
MemoryRegion *ram = g_new(MemoryRegion, 1);
const char *cpu_model = machine->cpu_model;
VirtBoardInfo *vbi;
+ VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
+ VirtGuestInfo *guest_info = &guest_info_state->info;
uint32_t gic_phandle;
char **cpustr;
@@ -812,7 +865,7 @@ static void machvirt_init(MachineState *machine)
create_rtc(vbi, pic);
- create_pcie(vbi, pic, gic_phandle);
+ guest_info->pcie_info = create_pcie(vbi, pic, gic_phandle);
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
@@ -821,6 +874,7 @@ static void machvirt_init(MachineState *machine)
create_virtio_devices(vbi, pic);
create_fw_cfg(vbi);
+ rom_set_fw(fw_cfg_find());
vbi->bootinfo.ram_size = machine->ram_size;
vbi->bootinfo.kernel_filename = machine->kernel_filename;
@@ -831,6 +885,16 @@ static void machvirt_init(MachineState *machine)
vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;
vbi->bootinfo.get_dtb = machvirt_dtb;
vbi->bootinfo.firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
+
+ guest_info->smp_cpus = smp_cpus;
+ guest_info->max_cpus = max_cpus;
+ guest_info->fw_cfg = fw_cfg_find();
+ guest_info->madt_info = &madt_info;
+ guest_info->dsdt_info = &dsdt_info;
+ guest_info->gtdt_info = >dt_info;
+ guest_info_state->machine_done.notify = virt_guest_info_machine_done;
+ qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
+
arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
}
@@ -1,6 +1,6 @@
common-obj-y += core.o smbus.o smbus_eeprom.o
common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
-common-obj-$(CONFIG_ACPI) += smbus_ich9.o
+common-obj-$(CONFIG_ACPI_CORE) += smbus_ich9.o
common-obj-$(CONFIG_APM) += pm_smbus.o
common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o
common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o