mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20150529' into staging
target-arm: * Support ACPI for ARMv8 systems using the 'virt' board (and a UEFI boot image, typically) * avoid buffer overrun in some UNPREDICTABLE ldrd/strd cases * further work preparing for 64-bit EL2/EL3 support # gpg: Signature made Fri May 29 12:14:06 2015 BST using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-target-arm-20150529: (39 commits) target-arm: Avoid buffer overrun on UNPREDICTABLE ldrd/strd hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables ACPI: split CONFIG_ACPI into 4 pieces hw/arm/virt-acpi-build: Add PCIe controller in ACPI DSDT table hw/acpi/aml-build: Add Unicode macro hw/acpi/aml-build: Add aml_dword_io() term hw/acpi/aml-build: Add aml_create_dword_field() term hw/acpi/aml-build: Add aml_else() term hw/acpi/aml-build: Add aml_lnot() term hw/acpi/aml-build: Add aml_or() term hw/acpi/aml-build: Add ToUUID macro hw/acpi/aml-build: Make aml_buffer() definition consistent with the spec hw/arm/virt-acpi-build: Generate MCFG table hw/arm/virt-acpi-build: Generate RSDP table hw/arm/virt-acpi-build: Generate RSDT table hw/arm/virt-acpi-build: Generate GTDT table hw/arm/virt-acpi-build: Generate MADT table hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers hw/arm/virt-acpi-build: Generation of DSDT table for virt devices hw/acpi/aml-build: Add aml_interrupt() term ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -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_X86=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_X86=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_X86=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_X86=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_X86=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_X86=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_X86) += 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
|
||||
|
||||
+223
-8
@@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
#include "hw/acpi/aml-build.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "hw/acpi/bios-linker-loader.h"
|
||||
|
||||
static GArray *build_alloc_array(void)
|
||||
@@ -454,6 +455,16 @@ Aml *aml_and(Aml *arg1, Aml *arg2)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
|
||||
Aml *aml_or(Aml *arg1, Aml *arg2)
|
||||
{
|
||||
Aml *var = aml_opcode(0x7D /* OrOp */);
|
||||
aml_append(var, arg1);
|
||||
aml_append(var, arg2);
|
||||
build_append_byte(var->buf, 0x00 /* NullNameOp */);
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
|
||||
Aml *aml_notify(Aml *arg1, Aml *arg2)
|
||||
{
|
||||
@@ -505,6 +516,60 @@ Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor
|
||||
* (Type 1, Large Item Name 0x6)
|
||||
*/
|
||||
Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
|
||||
AmlReadAndWrite read_and_write)
|
||||
{
|
||||
Aml *var = aml_alloc();
|
||||
build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
|
||||
build_append_byte(var->buf, 9); /* Length, bits[7:0] value = 9 */
|
||||
build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */
|
||||
build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
|
||||
|
||||
/* Range base address */
|
||||
build_append_byte(var->buf, extract32(addr, 0, 8)); /* bits[7:0] */
|
||||
build_append_byte(var->buf, extract32(addr, 8, 8)); /* bits[15:8] */
|
||||
build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
|
||||
build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
|
||||
|
||||
/* Range length */
|
||||
build_append_byte(var->buf, extract32(size, 0, 8)); /* bits[7:0] */
|
||||
build_append_byte(var->buf, extract32(size, 8, 8)); /* bits[15:8] */
|
||||
build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
|
||||
build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
|
||||
* Type 1, Large Item Name 0x9
|
||||
*/
|
||||
Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
|
||||
AmlLevelAndEdge level_and_edge,
|
||||
AmlActiveHighAndLow high_and_low, AmlShared shared,
|
||||
uint32_t irq)
|
||||
{
|
||||
Aml *var = aml_alloc();
|
||||
uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
|
||||
| (high_and_low << 2) | (shared << 3);
|
||||
|
||||
build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
|
||||
build_append_byte(var->buf, 6); /* Length, bits[7:0] minimum value = 6 */
|
||||
build_append_byte(var->buf, 0); /* Length, bits[15:8] minimum value = 0 */
|
||||
build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
|
||||
build_append_byte(var->buf, 0x01); /* Interrupt table length = 1 */
|
||||
|
||||
/* Interrupt Number */
|
||||
build_append_byte(var->buf, extract32(irq, 0, 8)); /* bits[7:0] */
|
||||
build_append_byte(var->buf, extract32(irq, 8, 8)); /* bits[15:8] */
|
||||
build_append_byte(var->buf, extract32(irq, 16, 8)); /* bits[23:16] */
|
||||
build_append_byte(var->buf, extract32(irq, 24, 8)); /* bits[31:24] */
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
|
||||
Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
|
||||
uint8_t aln, uint8_t len)
|
||||
@@ -542,6 +607,14 @@ Aml *aml_irq_no_flags(uint8_t irq)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
|
||||
Aml *aml_lnot(Aml *arg)
|
||||
{
|
||||
Aml *var = aml_opcode(0x92 /* LNotOp */);
|
||||
aml_append(var, arg);
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
|
||||
Aml *aml_equal(Aml *arg1, Aml *arg2)
|
||||
{
|
||||
@@ -559,6 +632,13 @@ Aml *aml_if(Aml *predicate)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
|
||||
Aml *aml_else(void)
|
||||
{
|
||||
Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
|
||||
Aml *aml_method(const char *name, int arg_count)
|
||||
{
|
||||
@@ -587,10 +667,22 @@ Aml *aml_resource_template(void)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
|
||||
Aml *aml_buffer(void)
|
||||
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
|
||||
* Pass byte_list as NULL to request uninitialized buffer to reserve space.
|
||||
*/
|
||||
Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
|
||||
{
|
||||
int i;
|
||||
Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
|
||||
|
||||
for (i = 0; i < buffer_size; i++) {
|
||||
if (byte_list == NULL) {
|
||||
build_append_byte(var->buf, 0x0);
|
||||
} else {
|
||||
build_append_byte(var->buf, byte_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -646,6 +738,17 @@ Aml *aml_field(const char *name, AmlAccessType type, AmlUpdateRule rule)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
|
||||
Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
|
||||
{
|
||||
Aml *var = aml_alloc();
|
||||
build_append_byte(var->buf, 0x8A); /* CreateDWordFieldOp */
|
||||
aml_append(var, srcbuf);
|
||||
aml_append(var, index);
|
||||
build_append_namestring(var->buf, "%s", name);
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
|
||||
Aml *aml_string(const char *name_format, ...)
|
||||
{
|
||||
@@ -833,7 +936,7 @@ Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
|
||||
uint16_t addr_trans, uint16_t len)
|
||||
|
||||
{
|
||||
return aml_word_as_desc(aml_bus_number_range, min_fixed, max_fixed, dec,
|
||||
return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec,
|
||||
addr_gran, addr_min, addr_max, addr_trans, len, 0);
|
||||
}
|
||||
|
||||
@@ -850,7 +953,25 @@ Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
|
||||
uint16_t len)
|
||||
|
||||
{
|
||||
return aml_word_as_desc(aml_io_range, min_fixed, max_fixed, dec,
|
||||
return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
|
||||
addr_gran, addr_min, addr_max, addr_trans, len,
|
||||
isa_ranges);
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
|
||||
*
|
||||
* More verbose description at:
|
||||
* ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
|
||||
*/
|
||||
Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
|
||||
AmlDecode dec, AmlISARanges isa_ranges,
|
||||
uint32_t addr_gran, uint32_t addr_min,
|
||||
uint32_t addr_max, uint32_t addr_trans,
|
||||
uint32_t len)
|
||||
|
||||
{
|
||||
return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
|
||||
addr_gran, addr_min, addr_max, addr_trans, len,
|
||||
isa_ranges);
|
||||
}
|
||||
@@ -862,7 +983,7 @@ Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
|
||||
* ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
|
||||
*/
|
||||
Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
AmlMaxFixed max_fixed, AmlCacheble cacheable,
|
||||
AmlMaxFixed max_fixed, AmlCacheable cacheable,
|
||||
AmlReadAndWrite read_and_write,
|
||||
uint32_t addr_gran, uint32_t addr_min,
|
||||
uint32_t addr_max, uint32_t addr_trans,
|
||||
@@ -870,7 +991,7 @@ Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
{
|
||||
uint8_t flags = read_and_write | (cacheable << 1);
|
||||
|
||||
return aml_dword_as_desc(aml_memory_range, min_fixed, max_fixed,
|
||||
return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
|
||||
dec, addr_gran, addr_min, addr_max,
|
||||
addr_trans, len, flags);
|
||||
}
|
||||
@@ -882,7 +1003,7 @@ Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
* ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
|
||||
*/
|
||||
Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
AmlMaxFixed max_fixed, AmlCacheble cacheable,
|
||||
AmlMaxFixed max_fixed, AmlCacheable cacheable,
|
||||
AmlReadAndWrite read_and_write,
|
||||
uint64_t addr_gran, uint64_t addr_min,
|
||||
uint64_t addr_max, uint64_t addr_trans,
|
||||
@@ -890,11 +1011,81 @@ Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
{
|
||||
uint8_t flags = read_and_write | (cacheable << 1);
|
||||
|
||||
return aml_qword_as_desc(aml_memory_range, min_fixed, max_fixed,
|
||||
return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
|
||||
dec, addr_gran, addr_min, addr_max,
|
||||
addr_trans, len, flags);
|
||||
}
|
||||
|
||||
static uint8_t Hex2Byte(const char *src)
|
||||
{
|
||||
int hi, lo;
|
||||
|
||||
hi = Hex2Digit(src[0]);
|
||||
assert(hi >= 0);
|
||||
assert(hi <= 15);
|
||||
|
||||
lo = Hex2Digit(src[1]);
|
||||
assert(lo >= 0);
|
||||
assert(lo <= 15);
|
||||
return (hi << 4) | lo;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
|
||||
* e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
|
||||
* call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
|
||||
*/
|
||||
Aml *aml_touuid(const char *uuid)
|
||||
{
|
||||
Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
|
||||
|
||||
assert(strlen(uuid) == 36);
|
||||
assert(uuid[8] == '-');
|
||||
assert(uuid[13] == '-');
|
||||
assert(uuid[18] == '-');
|
||||
assert(uuid[23] == '-');
|
||||
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 6)); /* dd - at offset 00 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 4)); /* cc - at offset 01 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 2)); /* bb - at offset 02 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 0)); /* aa - at offset 03 */
|
||||
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 9)); /* ee - at offset 05 */
|
||||
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
|
||||
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
|
||||
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
|
||||
build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI 2.0b: 16.2.3.6.4.3 Unicode Macro (Convert Ascii String To Unicode)
|
||||
*/
|
||||
Aml *aml_unicode(const char *str)
|
||||
{
|
||||
int i = 0;
|
||||
Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
|
||||
|
||||
do {
|
||||
build_append_byte(var->buf, str[i]);
|
||||
build_append_byte(var->buf, 0);
|
||||
i++;
|
||||
} while (i <= strlen(str));
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
void
|
||||
build_header(GArray *linker, GArray *table_data,
|
||||
AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
|
||||
@@ -951,3 +1142,27 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
|
||||
g_array_free(tables->table_data, true);
|
||||
g_array_free(tables->tcpalog, mfre);
|
||||
}
|
||||
|
||||
/* Build rsdt table */
|
||||
void
|
||||
build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
||||
{
|
||||
AcpiRsdtDescriptorRev1 *rsdt;
|
||||
size_t rsdt_len;
|
||||
int i;
|
||||
const int table_data_len = (sizeof(uint32_t) * table_offsets->len);
|
||||
|
||||
rsdt_len = sizeof(*rsdt) + table_data_len;
|
||||
rsdt = acpi_data_push(table_data, rsdt_len);
|
||||
memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len);
|
||||
for (i = 0; i < table_offsets->len; ++i) {
|
||||
/* rsdt->table_offset_entry to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE,
|
||||
ACPI_BUILD_TABLE_FILE,
|
||||
table_data, &rsdt->table_offset_entry[i],
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
build_header(linker, table_data,
|
||||
(void *)rsdt, "RSDT", rsdt_len, 1);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o
|
||||
obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
|
||||
obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
|
||||
obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
|
||||
obj-$(CONFIG_ACPI) += virt-acpi-build.o
|
||||
obj-y += netduino2.o
|
||||
|
||||
obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+37
-48
@@ -31,6 +31,7 @@
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/arm/arm.h"
|
||||
#include "hw/arm/primecell.h"
|
||||
#include "hw/arm/virt.h"
|
||||
#include "hw/devices.h"
|
||||
#include "net/net.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
@@ -43,8 +44,7 @@
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/pci-host/gpex.h"
|
||||
|
||||
#define NUM_VIRTIO_TRANSPORTS 32
|
||||
#include "hw/arm/virt-acpi-build.h"
|
||||
|
||||
/* Number of external interrupt lines to configure the GIC with */
|
||||
#define NUM_IRQS 128
|
||||
@@ -60,24 +60,6 @@
|
||||
#define GIC_FDT_IRQ_PPI_CPU_START 8
|
||||
#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
|
||||
|
||||
enum {
|
||||
VIRT_FLASH,
|
||||
VIRT_MEM,
|
||||
VIRT_CPUPERIPHS,
|
||||
VIRT_GIC_DIST,
|
||||
VIRT_GIC_CPU,
|
||||
VIRT_UART,
|
||||
VIRT_MMIO,
|
||||
VIRT_RTC,
|
||||
VIRT_FW_CFG,
|
||||
VIRT_PCIE,
|
||||
};
|
||||
|
||||
typedef struct MemMapEntry {
|
||||
hwaddr base;
|
||||
hwaddr size;
|
||||
} MemMapEntry;
|
||||
|
||||
typedef struct VirtBoardInfo {
|
||||
struct arm_boot_info bootinfo;
|
||||
const char *cpu_model;
|
||||
@@ -131,14 +113,9 @@ static const MemMapEntry a15memmap[] = {
|
||||
[VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
|
||||
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
|
||||
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
|
||||
/*
|
||||
* PCIE verbose map:
|
||||
*
|
||||
* MMIO window { 0x10000000, 0x2eff0000 },
|
||||
* PIO window { 0x3eff0000, 0x00010000 },
|
||||
* ECAM { 0x3f000000, 0x01000000 },
|
||||
*/
|
||||
[VIRT_PCIE] = { 0x10000000, 0x30000000 },
|
||||
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
|
||||
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
|
||||
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
|
||||
[VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
|
||||
};
|
||||
|
||||
@@ -289,10 +266,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)
|
||||
@@ -644,16 +621,14 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
|
||||
static void 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;
|
||||
hwaddr end = base + size;
|
||||
hwaddr size_mmio;
|
||||
hwaddr size_ioport = 64 * 1024;
|
||||
int nr_pcie_buses = 16;
|
||||
hwaddr size_ecam = PCIE_MMCFG_SIZE_MIN * nr_pcie_buses;
|
||||
hwaddr base_mmio = base;
|
||||
hwaddr base_ioport;
|
||||
hwaddr base_ecam;
|
||||
hwaddr base_mmio = vbi->memmap[VIRT_PCIE_MMIO].base;
|
||||
hwaddr size_mmio = vbi->memmap[VIRT_PCIE_MMIO].size;
|
||||
hwaddr base_pio = vbi->memmap[VIRT_PCIE_PIO].base;
|
||||
hwaddr size_pio = vbi->memmap[VIRT_PCIE_PIO].size;
|
||||
hwaddr base_ecam = vbi->memmap[VIRT_PCIE_ECAM].base;
|
||||
hwaddr size_ecam = vbi->memmap[VIRT_PCIE_ECAM].size;
|
||||
hwaddr base = base_mmio;
|
||||
int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
|
||||
int irq = vbi->irqmap[VIRT_PCIE];
|
||||
MemoryRegion *mmio_alias;
|
||||
MemoryRegion *mmio_reg;
|
||||
@@ -663,10 +638,6 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
|
||||
char *nodename;
|
||||
int i;
|
||||
|
||||
base_ecam = QEMU_ALIGN_DOWN(end - size_ecam, size_ecam);
|
||||
base_ioport = QEMU_ALIGN_DOWN(base_ecam - size_ioport, size_ioport);
|
||||
size_mmio = base_ioport - base;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_GPEX_HOST);
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
@@ -689,7 +660,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
|
||||
memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
|
||||
|
||||
/* Map IO port space */
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_ioport);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
|
||||
|
||||
for (i = 0; i < GPEX_NUM_IRQS; i++) {
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
|
||||
@@ -709,7 +680,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
|
||||
2, base_ecam, 2, size_ecam);
|
||||
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
|
||||
1, FDT_PCI_RANGE_IOPORT, 2, 0,
|
||||
2, base_ioport, 2, size_ioport,
|
||||
2, base_pio, 2, size_pio,
|
||||
1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
|
||||
2, base_mmio, 2, size_mmio);
|
||||
|
||||
@@ -727,6 +698,14 @@ 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);
|
||||
@@ -736,6 +715,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;
|
||||
|
||||
@@ -828,6 +809,14 @@ static void machvirt_init(MachineState *machine)
|
||||
create_virtio_devices(vbi, pic);
|
||||
|
||||
create_fw_cfg(vbi);
|
||||
rom_set_fw(fw_cfg_find());
|
||||
|
||||
guest_info->smp_cpus = smp_cpus;
|
||||
guest_info->fw_cfg = fw_cfg_find();
|
||||
guest_info->memmap = vbi->memmap;
|
||||
guest_info->irqmap = vbi->irqmap;
|
||||
guest_info_state->machine_done.notify = virt_guest_info_machine_done;
|
||||
qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
|
||||
|
||||
vbi->bootinfo.ram_size = machine->ram_size;
|
||||
vbi->bootinfo.kernel_filename = machine->kernel_filename;
|
||||
|
||||
@@ -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_X86) += 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
|
||||
|
||||
+29
-53
@@ -620,31 +620,31 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
/* build PCI0._CRS */
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_word_bus_number(aml_min_fixed, aml_max_fixed, aml_pos_decode,
|
||||
aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
|
||||
0x0000, 0x0000, 0x00FF, 0x0000, 0x0100));
|
||||
aml_append(crs, aml_io(aml_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
|
||||
aml_append(crs, aml_io(AML_DECODE16, 0x0CF8, 0x0CF8, 0x01, 0x08));
|
||||
|
||||
aml_append(crs,
|
||||
aml_word_io(aml_min_fixed, aml_max_fixed,
|
||||
aml_pos_decode, aml_entire_range,
|
||||
aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_POS_DECODE, AML_ENTIRE_RANGE,
|
||||
0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
|
||||
aml_append(crs,
|
||||
aml_word_io(aml_min_fixed, aml_max_fixed,
|
||||
aml_pos_decode, aml_entire_range,
|
||||
aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_POS_DECODE, AML_ENTIRE_RANGE,
|
||||
0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300));
|
||||
aml_append(crs,
|
||||
aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
|
||||
aml_cacheable, aml_ReadWrite,
|
||||
aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_CACHEABLE, AML_READ_WRITE,
|
||||
0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
|
||||
aml_append(crs,
|
||||
aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
|
||||
aml_non_cacheable, aml_ReadWrite,
|
||||
aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_NON_CACHEABLE, AML_READ_WRITE,
|
||||
0, pci->w32.begin, pci->w32.end - 1, 0,
|
||||
pci->w32.end - pci->w32.begin));
|
||||
if (pci->w64.begin) {
|
||||
aml_append(crs,
|
||||
aml_qword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
|
||||
aml_cacheable, aml_ReadWrite,
|
||||
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_CACHEABLE, AML_READ_WRITE,
|
||||
0, pci->w64.begin, pci->w64.end - 1, 0,
|
||||
pci->w64.end - pci->w64.begin));
|
||||
}
|
||||
@@ -658,7 +658,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, pm->gpe0_blk, pm->gpe0_blk, 1, pm->gpe0_blk_len)
|
||||
aml_io(AML_DECODE16, pm->gpe0_blk, pm->gpe0_blk, 1, pm->gpe0_blk_len)
|
||||
);
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
aml_append(scope, dev);
|
||||
@@ -673,7 +673,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, pm->pcihp_io_base, pm->pcihp_io_base, 1,
|
||||
aml_io(AML_DECODE16, pm->pcihp_io_base, pm->pcihp_io_base, 1,
|
||||
pm->pcihp_io_len)
|
||||
);
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
@@ -720,7 +720,7 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, misc->applesmc_io_base, misc->applesmc_io_base,
|
||||
aml_io(AML_DECODE16, misc->applesmc_io_base, misc->applesmc_io_base,
|
||||
0x01, APPLESMC_MAX_DATA_LENGTH)
|
||||
);
|
||||
aml_append(crs, aml_irq_no_flags(6));
|
||||
@@ -738,13 +738,13 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)
|
||||
aml_io(AML_DECODE16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)
|
||||
);
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
|
||||
aml_append(dev, aml_operation_region("PEOR", aml_system_io,
|
||||
aml_append(dev, aml_operation_region("PEOR", AML_SYSTEM_IO,
|
||||
misc->pvpanic_port, 1));
|
||||
field = aml_field("PEOR", aml_byte_acc, aml_preserve);
|
||||
field = aml_field("PEOR", AML_BYTE_ACC, AML_PRESERVE);
|
||||
aml_append(field, aml_named_field("PEPT", 8));
|
||||
aml_append(dev, field);
|
||||
|
||||
@@ -773,15 +773,15 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,
|
||||
aml_io(AML_DECODE16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,
|
||||
pm->cpu_hp_io_len)
|
||||
);
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
aml_append(sb_scope, dev);
|
||||
/* declare CPU hotplug MMIO region and PRS field to access it */
|
||||
aml_append(sb_scope, aml_operation_region(
|
||||
"PRST", aml_system_io, pm->cpu_hp_io_base, pm->cpu_hp_io_len));
|
||||
field = aml_field("PRST", aml_byte_acc, aml_preserve);
|
||||
"PRST", AML_SYSTEM_IO, pm->cpu_hp_io_base, pm->cpu_hp_io_len));
|
||||
field = aml_field("PRST", AML_BYTE_ACC, AML_PRESERVE);
|
||||
aml_append(field, aml_named_field("PRS", 256));
|
||||
aml_append(sb_scope, field);
|
||||
|
||||
@@ -845,18 +845,18 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_io(aml_decode16, pm->mem_hp_io_base, pm->mem_hp_io_base, 0,
|
||||
aml_io(AML_DECODE16, pm->mem_hp_io_base, pm->mem_hp_io_base, 0,
|
||||
pm->mem_hp_io_len)
|
||||
);
|
||||
aml_append(scope, aml_name_decl("_CRS", crs));
|
||||
|
||||
aml_append(scope, aml_operation_region(
|
||||
stringify(MEMORY_HOTPLUG_IO_REGION), aml_system_io,
|
||||
stringify(MEMORY_HOTPLUG_IO_REGION), AML_SYSTEM_IO,
|
||||
pm->mem_hp_io_base, pm->mem_hp_io_len)
|
||||
);
|
||||
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc,
|
||||
aml_preserve);
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), AML_DWORD_ACC,
|
||||
AML_PRESERVE);
|
||||
aml_append(field, /* read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));
|
||||
aml_append(field, /* read only */
|
||||
@@ -869,8 +869,8 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
aml_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));
|
||||
aml_append(scope, field);
|
||||
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_byte_acc,
|
||||
aml_write_as_zeros);
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), AML_BYTE_ACC,
|
||||
AML_WRITE_AS_ZEROS);
|
||||
aml_append(field, aml_reserved_field(160 /* bits, Offset(20) */));
|
||||
aml_append(field, /* 1 if enabled, read only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_ENABLED), 1));
|
||||
@@ -885,8 +885,8 @@ build_ssdt(GArray *table_data, GArray *linker,
|
||||
aml_named_field(stringify(MEMORY_SLOT_EJECT), 1));
|
||||
aml_append(scope, field);
|
||||
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc,
|
||||
aml_preserve);
|
||||
field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), AML_DWORD_ACC,
|
||||
AML_PRESERVE);
|
||||
aml_append(field, /* DIMM selector, write only */
|
||||
aml_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));
|
||||
aml_append(field, /* _OST event code, write only */
|
||||
@@ -1208,30 +1208,6 @@ build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
|
||||
misc->dsdt_size, 1);
|
||||
}
|
||||
|
||||
/* Build final rsdt table */
|
||||
static void
|
||||
build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
|
||||
{
|
||||
AcpiRsdtDescriptorRev1 *rsdt;
|
||||
size_t rsdt_len;
|
||||
int i;
|
||||
|
||||
rsdt_len = sizeof(*rsdt) + sizeof(uint32_t) * table_offsets->len;
|
||||
rsdt = acpi_data_push(table_data, rsdt_len);
|
||||
memcpy(rsdt->table_offset_entry, table_offsets->data,
|
||||
sizeof(uint32_t) * table_offsets->len);
|
||||
for (i = 0; i < table_offsets->len; ++i) {
|
||||
/* rsdt->table_offset_entry to be filled by Guest linker */
|
||||
bios_linker_loader_add_pointer(linker,
|
||||
ACPI_BUILD_TABLE_FILE,
|
||||
ACPI_BUILD_TABLE_FILE,
|
||||
table_data, &rsdt->table_offset_entry[i],
|
||||
sizeof(uint32_t));
|
||||
}
|
||||
build_header(linker, table_data,
|
||||
(void *)rsdt, "RSDT", rsdt_len, 1);
|
||||
}
|
||||
|
||||
static GArray *
|
||||
build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
|
||||
{
|
||||
|
||||
+172
-38
@@ -88,46 +88,54 @@ struct AcpiTableHeader /* ACPI common table header */
|
||||
typedef struct AcpiTableHeader AcpiTableHeader;
|
||||
|
||||
/*
|
||||
* ACPI 1.0 Fixed ACPI Description Table (FADT)
|
||||
* ACPI Fixed ACPI Description Table (FADT)
|
||||
*/
|
||||
#define ACPI_FADT_COMMON_DEF /* FADT common definition */ \
|
||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \
|
||||
uint32_t firmware_ctrl; /* Physical address of FACS */ \
|
||||
uint32_t dsdt; /* Physical address of DSDT */ \
|
||||
uint8_t model; /* System Interrupt Model */ \
|
||||
uint8_t reserved1; /* Reserved */ \
|
||||
uint16_t sci_int; /* System vector of SCI interrupt */ \
|
||||
uint32_t smi_cmd; /* Port address of SMI command port */ \
|
||||
uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \
|
||||
uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \
|
||||
/* Value to write to SMI CMD to enter S4BIOS state */ \
|
||||
uint8_t S4bios_req; \
|
||||
uint8_t reserved2; /* Reserved - must be zero */ \
|
||||
/* Port address of Power Mgt 1a acpi_event Reg Blk */ \
|
||||
uint32_t pm1a_evt_blk; \
|
||||
/* Port address of Power Mgt 1b acpi_event Reg Blk */ \
|
||||
uint32_t pm1b_evt_blk; \
|
||||
uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \
|
||||
uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \
|
||||
uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \
|
||||
uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \
|
||||
/* Port addr of General Purpose acpi_event 0 Reg Blk */ \
|
||||
uint32_t gpe0_blk; \
|
||||
/* Port addr of General Purpose acpi_event 1 Reg Blk */ \
|
||||
uint32_t gpe1_blk; \
|
||||
uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ \
|
||||
uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ \
|
||||
uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \
|
||||
uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ \
|
||||
uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \
|
||||
uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \
|
||||
uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */ \
|
||||
uint8_t reserved3; /* Reserved */ \
|
||||
uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \
|
||||
uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \
|
||||
uint16_t flush_size; /* Size of area read to flush caches */ \
|
||||
uint16_t flush_stride; /* Stride used in flushing caches */ \
|
||||
uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */ \
|
||||
uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */ \
|
||||
uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \
|
||||
uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \
|
||||
uint8_t century; /* Index to century in RTC CMOS RAM */
|
||||
|
||||
struct AcpiFadtDescriptorRev1
|
||||
{
|
||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||
uint32_t firmware_ctrl; /* Physical address of FACS */
|
||||
uint32_t dsdt; /* Physical address of DSDT */
|
||||
uint8_t model; /* System Interrupt Model */
|
||||
uint8_t reserved1; /* Reserved */
|
||||
uint16_t sci_int; /* System vector of SCI interrupt */
|
||||
uint32_t smi_cmd; /* Port address of SMI command port */
|
||||
uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */
|
||||
uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */
|
||||
uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
|
||||
uint8_t reserved2; /* Reserved - must be zero */
|
||||
uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
|
||||
uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
|
||||
uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
|
||||
uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
|
||||
uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
|
||||
uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
|
||||
uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
|
||||
uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
|
||||
uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
|
||||
uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
|
||||
uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
|
||||
uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */
|
||||
uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
|
||||
uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
|
||||
uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */
|
||||
uint8_t reserved3; /* Reserved */
|
||||
uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
|
||||
uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
|
||||
uint16_t flush_size; /* Size of area read to flush caches */
|
||||
uint16_t flush_stride; /* Stride used in flushing caches */
|
||||
uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */
|
||||
uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */
|
||||
uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
|
||||
uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
|
||||
uint8_t century; /* Index to century in RTC CMOS RAM */
|
||||
ACPI_FADT_COMMON_DEF
|
||||
uint8_t reserved4; /* Reserved */
|
||||
uint8_t reserved4a; /* Reserved */
|
||||
uint8_t reserved4b; /* Reserved */
|
||||
@@ -135,6 +143,59 @@ struct AcpiFadtDescriptorRev1
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
|
||||
|
||||
struct AcpiGenericAddress {
|
||||
uint8_t space_id; /* Address space where struct or register exists */
|
||||
uint8_t bit_width; /* Size in bits of given register */
|
||||
uint8_t bit_offset; /* Bit offset within the register */
|
||||
uint8_t access_width; /* Minimum Access size (ACPI 3.0) */
|
||||
uint64_t address; /* 64-bit address of struct or register */
|
||||
} QEMU_PACKED;
|
||||
|
||||
struct AcpiFadtDescriptorRev5_1 {
|
||||
ACPI_FADT_COMMON_DEF
|
||||
/* IA-PC Boot Architecture Flags (see below for individual flags) */
|
||||
uint16_t boot_flags;
|
||||
uint8_t reserved; /* Reserved, must be zero */
|
||||
/* Miscellaneous flag bits (see below for individual flags) */
|
||||
uint32_t flags;
|
||||
/* 64-bit address of the Reset register */
|
||||
struct AcpiGenericAddress reset_register;
|
||||
/* Value to write to the reset_register port to reset the system */
|
||||
uint8_t reset_value;
|
||||
/* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
|
||||
uint16_t arm_boot_flags;
|
||||
uint8_t minor_revision; /* FADT Minor Revision (ACPI 5.1) */
|
||||
uint64_t Xfacs; /* 64-bit physical address of FACS */
|
||||
uint64_t Xdsdt; /* 64-bit physical address of DSDT */
|
||||
/* 64-bit Extended Power Mgt 1a Event Reg Blk address */
|
||||
struct AcpiGenericAddress xpm1a_event_block;
|
||||
/* 64-bit Extended Power Mgt 1b Event Reg Blk address */
|
||||
struct AcpiGenericAddress xpm1b_event_block;
|
||||
/* 64-bit Extended Power Mgt 1a Control Reg Blk address */
|
||||
struct AcpiGenericAddress xpm1a_control_block;
|
||||
/* 64-bit Extended Power Mgt 1b Control Reg Blk address */
|
||||
struct AcpiGenericAddress xpm1b_control_block;
|
||||
/* 64-bit Extended Power Mgt 2 Control Reg Blk address */
|
||||
struct AcpiGenericAddress xpm2_control_block;
|
||||
/* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
|
||||
struct AcpiGenericAddress xpm_timer_block;
|
||||
/* 64-bit Extended General Purpose Event 0 Reg Blk address */
|
||||
struct AcpiGenericAddress xgpe0_block;
|
||||
/* 64-bit Extended General Purpose Event 1 Reg Blk address */
|
||||
struct AcpiGenericAddress xgpe1_block;
|
||||
/* 64-bit Sleep Control register (ACPI 5.0) */
|
||||
struct AcpiGenericAddress sleep_control;
|
||||
/* 64-bit Sleep Status register (ACPI 5.0) */
|
||||
struct AcpiGenericAddress sleep_status;
|
||||
} QEMU_PACKED;
|
||||
|
||||
typedef struct AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
|
||||
|
||||
enum {
|
||||
ACPI_FADT_ARM_USE_PSCI_G_0_2 = 0,
|
||||
ACPI_FADT_ARM_PSCI_USE_HVC = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* ACPI 1.0 Root System Description Table (RSDT)
|
||||
*/
|
||||
@@ -195,7 +256,13 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
|
||||
#define ACPI_APIC_IO_SAPIC 6
|
||||
#define ACPI_APIC_LOCAL_SAPIC 7
|
||||
#define ACPI_APIC_XRUPT_SOURCE 8
|
||||
#define ACPI_APIC_RESERVED 9 /* 9 and greater are reserved */
|
||||
#define ACPI_APIC_LOCAL_X2APIC 9
|
||||
#define ACPI_APIC_LOCAL_X2APIC_NMI 10
|
||||
#define ACPI_APIC_GENERIC_INTERRUPT 11
|
||||
#define ACPI_APIC_GENERIC_DISTRIBUTOR 12
|
||||
#define ACPI_APIC_GENERIC_MSI_FRAME 13
|
||||
#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
|
||||
#define ACPI_APIC_RESERVED 15 /* 15 and greater are reserved */
|
||||
|
||||
/*
|
||||
* MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
|
||||
@@ -243,6 +310,73 @@ struct AcpiMadtLocalNmi {
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiMadtLocalNmi AcpiMadtLocalNmi;
|
||||
|
||||
struct AcpiMadtGenericInterrupt {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint16_t reserved;
|
||||
uint32_t cpu_interface_number;
|
||||
uint32_t uid;
|
||||
uint32_t flags;
|
||||
uint32_t parking_version;
|
||||
uint32_t performance_interrupt;
|
||||
uint64_t parked_address;
|
||||
uint64_t base_address;
|
||||
uint64_t gicv_base_address;
|
||||
uint64_t gich_base_address;
|
||||
uint32_t vgic_interrupt;
|
||||
uint64_t gicr_base_address;
|
||||
uint64_t arm_mpidr;
|
||||
} QEMU_PACKED;
|
||||
|
||||
typedef struct AcpiMadtGenericInterrupt AcpiMadtGenericInterrupt;
|
||||
|
||||
struct AcpiMadtGenericDistributor {
|
||||
ACPI_SUB_HEADER_DEF
|
||||
uint16_t reserved;
|
||||
uint32_t gic_id;
|
||||
uint64_t base_address;
|
||||
uint32_t global_irq_base;
|
||||
uint32_t reserved2;
|
||||
} QEMU_PACKED;
|
||||
|
||||
typedef struct AcpiMadtGenericDistributor AcpiMadtGenericDistributor;
|
||||
|
||||
/*
|
||||
* Generic Timer Description Table (GTDT)
|
||||
*/
|
||||
|
||||
#define ACPI_GTDT_INTERRUPT_MODE (1 << 0)
|
||||
#define ACPI_GTDT_INTERRUPT_POLARITY (1 << 1)
|
||||
#define ACPI_GTDT_ALWAYS_ON (1 << 2)
|
||||
|
||||
/* Triggering */
|
||||
|
||||
#define ACPI_LEVEL_SENSITIVE ((uint8_t) 0x00)
|
||||
#define ACPI_EDGE_SENSITIVE ((uint8_t) 0x01)
|
||||
|
||||
/* Polarity */
|
||||
|
||||
#define ACPI_ACTIVE_HIGH ((uint8_t) 0x00)
|
||||
#define ACPI_ACTIVE_LOW ((uint8_t) 0x01)
|
||||
#define ACPI_ACTIVE_BOTH ((uint8_t) 0x02)
|
||||
|
||||
struct AcpiGenericTimerTable {
|
||||
ACPI_TABLE_HEADER_DEF
|
||||
uint64_t counter_block_addresss;
|
||||
uint32_t reserved;
|
||||
uint32_t secure_el1_interrupt;
|
||||
uint32_t secure_el1_flags;
|
||||
uint32_t non_secure_el1_interrupt;
|
||||
uint32_t non_secure_el1_flags;
|
||||
uint32_t virtual_timer_interrupt;
|
||||
uint32_t virtual_timer_flags;
|
||||
uint32_t non_secure_el2_interrupt;
|
||||
uint32_t non_secure_el2_flags;
|
||||
uint64_t counter_read_block_address;
|
||||
uint32_t platform_timer_count;
|
||||
uint32_t platform_timer_offset;
|
||||
} QEMU_PACKED;
|
||||
typedef struct AcpiGenericTimerTable AcpiGenericTimerTable;
|
||||
|
||||
/*
|
||||
* HPET Description Table
|
||||
*/
|
||||
|
||||
+92
-35
@@ -36,49 +36,49 @@ struct Aml {
|
||||
typedef struct Aml Aml;
|
||||
|
||||
typedef enum {
|
||||
aml_decode10 = 0,
|
||||
aml_decode16 = 1,
|
||||
AML_DECODE10 = 0,
|
||||
AML_DECODE16 = 1,
|
||||
} AmlIODecode;
|
||||
|
||||
typedef enum {
|
||||
aml_any_acc = 0,
|
||||
aml_byte_acc = 1,
|
||||
aml_word_acc = 2,
|
||||
aml_dword_acc = 3,
|
||||
aml_qword_acc = 4,
|
||||
aml_buffer_acc = 5,
|
||||
AML_ANY_ACC = 0,
|
||||
AML_BYTE_ACC = 1,
|
||||
AML_WORD_ACC = 2,
|
||||
AML_DWORD_ACC = 3,
|
||||
AML_QWORD_ACC = 4,
|
||||
AML_BUFFER_ACC = 5,
|
||||
} AmlAccessType;
|
||||
|
||||
typedef enum {
|
||||
aml_preserve = 0,
|
||||
aml_write_as_ones = 1,
|
||||
aml_write_as_zeros = 2,
|
||||
AML_PRESERVE = 0,
|
||||
AML_WRITE_AS_ONES = 1,
|
||||
AML_WRITE_AS_ZEROS = 2,
|
||||
} AmlUpdateRule;
|
||||
|
||||
typedef enum {
|
||||
aml_system_memory = 0x00,
|
||||
aml_system_io = 0x01,
|
||||
AML_SYSTEM_MEMORY = 0X00,
|
||||
AML_SYSTEM_IO = 0X01,
|
||||
} AmlRegionSpace;
|
||||
|
||||
typedef enum {
|
||||
aml_memory_range = 0,
|
||||
aml_io_range = 1,
|
||||
aml_bus_number_range = 2,
|
||||
AML_MEMORY_RANGE = 0,
|
||||
AML_IO_RANGE = 1,
|
||||
AML_BUS_NUMBER_RANGE = 2,
|
||||
} AmlResourceType;
|
||||
|
||||
typedef enum {
|
||||
aml_sub_decode = 1 << 1,
|
||||
aml_pos_decode = 0
|
||||
AML_SUB_DECODE = 1 << 1,
|
||||
AML_POS_DECODE = 0
|
||||
} AmlDecode;
|
||||
|
||||
typedef enum {
|
||||
aml_max_fixed = 1 << 3,
|
||||
aml_max_not_fixed = 0,
|
||||
AML_MAX_FIXED = 1 << 3,
|
||||
AML_MAX_NOT_FIXED = 0,
|
||||
} AmlMaxFixed;
|
||||
|
||||
typedef enum {
|
||||
aml_min_fixed = 1 << 2,
|
||||
aml_min_not_fixed = 0
|
||||
AML_MIN_FIXED = 1 << 2,
|
||||
AML_MIN_NOT_FIXED = 0
|
||||
} AmlMinFixed;
|
||||
|
||||
/*
|
||||
@@ -86,9 +86,9 @@ typedef enum {
|
||||
* _RNG field definition
|
||||
*/
|
||||
typedef enum {
|
||||
aml_isa_only = 1,
|
||||
aml_non_isa_only = 2,
|
||||
aml_entire_range = 3,
|
||||
AML_ISA_ONLY = 1,
|
||||
AML_NON_ISA_ONLY = 2,
|
||||
AML_ENTIRE_RANGE = 3,
|
||||
} AmlISARanges;
|
||||
|
||||
/*
|
||||
@@ -96,21 +96,59 @@ typedef enum {
|
||||
* _MEM field definition
|
||||
*/
|
||||
typedef enum {
|
||||
aml_non_cacheable = 0,
|
||||
aml_cacheable = 1,
|
||||
aml_write_combining = 2,
|
||||
aml_prefetchable = 3,
|
||||
} AmlCacheble;
|
||||
AML_NON_CACHEABLE = 0,
|
||||
AML_CACHEABLE = 1,
|
||||
AML_WRITE_COMBINING = 2,
|
||||
AML_PREFETCHABLE = 3,
|
||||
} AmlCacheable;
|
||||
|
||||
/*
|
||||
* ACPI 1.0b: Table 6-25 Memory Resource Flag (Resource Type = 0) Definitions
|
||||
* _RW field definition
|
||||
*/
|
||||
typedef enum {
|
||||
aml_ReadOnly = 0,
|
||||
aml_ReadWrite = 1,
|
||||
AML_READ_ONLY = 0,
|
||||
AML_READ_WRITE = 1,
|
||||
} AmlReadAndWrite;
|
||||
|
||||
/*
|
||||
* ACPI 5.0: Table 6-187 Extended Interrupt Descriptor Definition
|
||||
* Interrupt Vector Flags Bits[0] Consumer/Producer
|
||||
*/
|
||||
typedef enum {
|
||||
AML_CONSUMER_PRODUCER = 0,
|
||||
AML_CONSUMER = 1,
|
||||
} AmlConsumerAndProducer;
|
||||
|
||||
/*
|
||||
* ACPI 5.0: Table 6-187 Extended Interrupt Descriptor Definition
|
||||
* _HE field definition
|
||||
*/
|
||||
typedef enum {
|
||||
AML_LEVEL = 0,
|
||||
AML_EDGE = 1,
|
||||
} AmlLevelAndEdge;
|
||||
|
||||
/*
|
||||
* ACPI 5.0: Table 6-187 Extended Interrupt Descriptor Definition
|
||||
* _LL field definition
|
||||
*/
|
||||
typedef enum {
|
||||
AML_ACTIVE_HIGH = 0,
|
||||
AML_ACTIVE_LOW = 1,
|
||||
} AmlActiveHighAndLow;
|
||||
|
||||
/*
|
||||
* ACPI 5.0: Table 6-187 Extended Interrupt Descriptor Definition
|
||||
* _SHR field definition
|
||||
*/
|
||||
typedef enum {
|
||||
AML_EXCLUSIVE = 0,
|
||||
AML_SHARED = 1,
|
||||
AML_EXCLUSIVE_AND_WAKE = 2,
|
||||
AML_SHARED_AND_WAKE = 3,
|
||||
} AmlShared;
|
||||
|
||||
typedef
|
||||
struct AcpiBuildTables {
|
||||
GArray *table_data;
|
||||
@@ -163,11 +201,18 @@ Aml *aml_int(const uint64_t val);
|
||||
Aml *aml_arg(int pos);
|
||||
Aml *aml_store(Aml *val, Aml *target);
|
||||
Aml *aml_and(Aml *arg1, Aml *arg2);
|
||||
Aml *aml_or(Aml *arg1, Aml *arg2);
|
||||
Aml *aml_notify(Aml *arg1, Aml *arg2);
|
||||
Aml *aml_call1(const char *method, Aml *arg1);
|
||||
Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
|
||||
Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3);
|
||||
Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4);
|
||||
Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
|
||||
AmlReadAndWrite read_and_write);
|
||||
Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
|
||||
AmlLevelAndEdge level_and_edge,
|
||||
AmlActiveHighAndLow high_and_low, AmlShared shared,
|
||||
uint32_t irq);
|
||||
Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
|
||||
uint8_t aln, uint8_t len);
|
||||
Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
|
||||
@@ -177,6 +222,7 @@ Aml *aml_named_field(const char *name, unsigned length);
|
||||
Aml *aml_reserved_field(unsigned length);
|
||||
Aml *aml_local(int num);
|
||||
Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
|
||||
Aml *aml_lnot(Aml *arg);
|
||||
Aml *aml_equal(Aml *arg1, Aml *arg2);
|
||||
Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
|
||||
const char *name_format, ...) GCC_FMT_ATTR(4, 5);
|
||||
@@ -190,14 +236,19 @@ Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
|
||||
uint16_t addr_gran, uint16_t addr_min,
|
||||
uint16_t addr_max, uint16_t addr_trans,
|
||||
uint16_t len);
|
||||
Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
|
||||
AmlDecode dec, AmlISARanges isa_ranges,
|
||||
uint32_t addr_gran, uint32_t addr_min,
|
||||
uint32_t addr_max, uint32_t addr_trans,
|
||||
uint32_t len);
|
||||
Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
AmlMaxFixed max_fixed, AmlCacheble cacheable,
|
||||
AmlMaxFixed max_fixed, AmlCacheable cacheable,
|
||||
AmlReadAndWrite read_and_write,
|
||||
uint32_t addr_gran, uint32_t addr_min,
|
||||
uint32_t addr_max, uint32_t addr_trans,
|
||||
uint32_t len);
|
||||
Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
|
||||
AmlMaxFixed max_fixed, AmlCacheble cacheable,
|
||||
AmlMaxFixed max_fixed, AmlCacheable cacheable,
|
||||
AmlReadAndWrite read_and_write,
|
||||
uint64_t addr_gran, uint64_t addr_min,
|
||||
uint64_t addr_max, uint64_t addr_trans,
|
||||
@@ -208,11 +259,15 @@ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
|
||||
Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
|
||||
Aml *aml_method(const char *name, int arg_count);
|
||||
Aml *aml_if(Aml *predicate);
|
||||
Aml *aml_else(void);
|
||||
Aml *aml_package(uint8_t num_elements);
|
||||
Aml *aml_buffer(void);
|
||||
Aml *aml_buffer(int buffer_size, uint8_t *byte_list);
|
||||
Aml *aml_resource_template(void);
|
||||
Aml *aml_field(const char *name, AmlAccessType type, AmlUpdateRule rule);
|
||||
Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name);
|
||||
Aml *aml_varpackage(uint32_t num_elements);
|
||||
Aml *aml_touuid(const char *uuid);
|
||||
Aml *aml_unicode(const char *str);
|
||||
|
||||
void
|
||||
build_header(GArray *linker, GArray *table_data,
|
||||
@@ -222,5 +277,7 @@ unsigned acpi_data_len(GArray *table);
|
||||
void acpi_add_table(GArray *table_offsets, GArray *table_data);
|
||||
void acpi_build_tables_init(AcpiBuildTables *tables);
|
||||
void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre);
|
||||
void
|
||||
build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2015 HUAWEI TECHNOLOGIES CO.,LTD.
|
||||
*
|
||||
* Author: Shannon Zhao <zhaoshenglong@huawei.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_VIRT_ACPI_BUILD_H
|
||||
#define QEMU_VIRT_ACPI_BUILD_H
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "hw/arm/virt.h"
|
||||
|
||||
#define VIRT_ACPI_CPU_ID_LIMIT 8
|
||||
#define ACPI_GICC_ENABLED 1
|
||||
|
||||
typedef struct VirtGuestInfo {
|
||||
int smp_cpus;
|
||||
FWCfgState *fw_cfg;
|
||||
const MemMapEntry *memmap;
|
||||
const int *irqmap;
|
||||
} VirtGuestInfo;
|
||||
|
||||
|
||||
typedef struct VirtGuestInfoState {
|
||||
VirtGuestInfo info;
|
||||
Notifier machine_done;
|
||||
} VirtGuestInfoState;
|
||||
|
||||
void virt_acpi_setup(VirtGuestInfo *guest_info);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2015 Linaro Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Emulate a virtual board which works by passing Linux all the information
|
||||
* it needs about what devices are present via the device tree.
|
||||
* There are some restrictions about what we can do here:
|
||||
* + we can only present devices whose Linux drivers will work based
|
||||
* purely on the device tree with no platform data at all
|
||||
* + we want to present a very stripped-down minimalist platform,
|
||||
* both because this reduces the security attack surface from the guest
|
||||
* and also because it reduces our exposure to being broken when
|
||||
* the kernel updates its device tree bindings and requires further
|
||||
* information in a device binding that we aren't providing.
|
||||
* This is essentially the same approach kvmtool uses.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_ARM_VIRT_H
|
||||
#define QEMU_ARM_VIRT_H
|
||||
|
||||
#include "qemu-common.h"
|
||||
|
||||
#define NUM_VIRTIO_TRANSPORTS 32
|
||||
|
||||
#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,
|
||||
VIRT_CPUPERIPHS,
|
||||
VIRT_GIC_DIST,
|
||||
VIRT_GIC_CPU,
|
||||
VIRT_UART,
|
||||
VIRT_MMIO,
|
||||
VIRT_RTC,
|
||||
VIRT_FW_CFG,
|
||||
VIRT_PCIE,
|
||||
VIRT_PCIE_MMIO,
|
||||
VIRT_PCIE_PIO,
|
||||
VIRT_PCIE_ECAM,
|
||||
};
|
||||
|
||||
typedef struct MemMapEntry {
|
||||
hwaddr base;
|
||||
hwaddr size;
|
||||
} MemMapEntry;
|
||||
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -1352,7 +1352,7 @@ be needed to boot from old floppy disks.
|
||||
ETEXI
|
||||
|
||||
DEF("no-acpi", 0, QEMU_OPTION_no_acpi,
|
||||
"-no-acpi disable ACPI\n", QEMU_ARCH_I386)
|
||||
"-no-acpi disable ACPI\n", QEMU_ARCH_I386 | QEMU_ARCH_ARM)
|
||||
STEXI
|
||||
@item -no-acpi
|
||||
@findex -no-acpi
|
||||
|
||||
+58
-20
@@ -206,31 +206,52 @@ static void arm_cpu_reset(CPUState *s)
|
||||
bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cs);
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
uint32_t cur_el = arm_current_el(env);
|
||||
bool secure = arm_is_secure(env);
|
||||
uint32_t target_el;
|
||||
uint32_t excp_idx;
|
||||
bool ret = false;
|
||||
|
||||
if (interrupt_request & CPU_INTERRUPT_FIQ
|
||||
&& arm_excp_unmasked(cs, EXCP_FIQ)) {
|
||||
cs->exception_index = EXCP_FIQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_FIQ) {
|
||||
excp_idx = EXCP_FIQ;
|
||||
target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD
|
||||
&& arm_excp_unmasked(cs, EXCP_IRQ)) {
|
||||
cs->exception_index = EXCP_IRQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
excp_idx = EXCP_IRQ;
|
||||
target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_VIRQ
|
||||
&& arm_excp_unmasked(cs, EXCP_VIRQ)) {
|
||||
cs->exception_index = EXCP_VIRQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_VIRQ) {
|
||||
excp_idx = EXCP_VIRQ;
|
||||
target_el = 1;
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_VFIQ
|
||||
&& arm_excp_unmasked(cs, EXCP_VFIQ)) {
|
||||
cs->exception_index = EXCP_VFIQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_VFIQ) {
|
||||
excp_idx = EXCP_VFIQ;
|
||||
target_el = 1;
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1197,6 +1218,23 @@ static Property arm_cpu_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
|
||||
int mmu_idx)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
||||
env->exception.vaddress = address;
|
||||
if (rw == 2) {
|
||||
cs->exception_index = EXCP_PREFETCH_ABORT;
|
||||
} else {
|
||||
cs->exception_index = EXCP_DATA_ABORT;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user