target-arm queue:
* i2c: Allow I2C devices to NAK start events * hw/char: QOM'ify exynos4210_uart.c * clean up and refactor virt-acpi-build.c * virt-acpi-build: Don't incorrectly claim architectural timer to be edge-triggered * m25p80: Don't let rogue SPI controllers cause buffer overruns * imx_spi: Remove broken MSGDATA register support -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJYc3mRAAoJEDwlJe0UNgzewfUP/jyufs23B8qI+61tTB0EzYn6 fKQipdUu1/EHRVoJ0Dh/FVmhGaOQ1HyGtvKqi1DXaQR8qiE32I9hcO7/ryYNigwo y9g8UVAi3a3maISNZ1AghtOXEWMFSWx97NS3VZLqTAKBYX7i9QulReq3yuR9ItlJ ojW/B4S2BOaaInNJAuZQDiPoy6FyzATpOlfesNeb8OJqlFo9dUsIrxa1qBcK0gQS KS9jk1woH4Bqw34BtDMtUXvE7ToD6+1OUsBBIGtmKjguc3J580ELb4xJjJGJNJQF HLpSxlN1ReTFna7iXBUKnfIGiDQhf7ozW8xbmRGxfI5dMIYDp1JnyLiJTWy57VNS QJfSeiRRDBzZBeTom7NLb1TfHUQ+oqJF1MonKYn3IgDXUiC1KHB43YPhgVjwf7zK 2l9qMAgUCfxf59o/1R2Izm7sVNCPSQj4NZfR+uCyUBYxD6HHJlkqrb7gsGoqAS3q 8BAR1p9XxryD94qPwfiQWR/X4GQi5CuwmQLScTGCnnoH9qZBIqsYv6AhdC88v3Z3 V8Oeh3ur2sQVcoOzdqDFkCjb6ge0JN8AsCBAPMmclbvvfCC3pYC9pN+2P6oq88ck d6b3XCBthQOWngYGmzdipcNvgb/WPgfMxESQ4+xesog7gpDLpQUZ22+1iHvnTuLg +bBe0XoulbP9afgXyQ8A =gmWH -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170109' into staging target-arm queue: * i2c: Allow I2C devices to NAK start events * hw/char: QOM'ify exynos4210_uart.c * clean up and refactor virt-acpi-build.c * virt-acpi-build: Don't incorrectly claim architectural timer to be edge-triggered * m25p80: Don't let rogue SPI controllers cause buffer overruns * imx_spi: Remove broken MSGDATA register support # gpg: Signature made Mon 09 Jan 2017 11:52:49 GMT # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20170109: (21 commits) hw/ssi/imx_spi.c: Remove MSGDATA register support m25p80: don't let rogue SPI controllers cause buffer overruns hw/arm/virt-acpi-build: Don't incorrectly claim architectural timer to be edge-triggered hw/arm/virt: remove VirtGuestInfo hw/arm/virt-acpi-build: don't save VirtGuestInfo on AcpiBuildState hw/arm/virt-acpi-build: remove redundant members from VirtGuestInfo hw/arm/virt: pass VirtMachineState instead of VirtGuestInfo hw/arm/virt: move VirtMachineState/Class to virt.h hw/arm/virt: remove include/hw/arm/virt-acpi-build.h hw/arm/virt: eliminate struct VirtGuestInfoState hw/arm/virt: use VirtMachineState.gic_version hw/arm/virt: parameter passing cleanups hw/arm/virt-acpi-build: fadt: improve flag naming hw/arm/virt-acpi-build: gtdt: improve flag naming hw/arm/virt-acpi-build: name GIC CPU Interface Structure appropriately hw/arm/virt-acpi-build: add all missing cpu_to_le's hw/arm/virt: Don't incorrectly claim architectural timer to be edge-triggered hw/arm/virt: Rename 'vbi' variables to 'vms' hw/arm/virt: Merge VirtBoardInfo and VirtMachineState hw/char: QOM'ify exynos4210_uart.c ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8305f9bdf7
@ -508,7 +508,6 @@ M: Shannon Zhao <shannon.zhao@linaro.org>
|
|||||||
L: qemu-arm@nongnu.org
|
L: qemu-arm@nongnu.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: hw/arm/virt-acpi-build.c
|
F: hw/arm/virt-acpi-build.c
|
||||||
F: include/hw/arm/virt-acpi-build.h
|
|
||||||
|
|
||||||
STM32F205
|
STM32F205
|
||||||
M: Alistair Francis <alistair@alistair23.me>
|
M: Alistair Francis <alistair@alistair23.me>
|
||||||
@ -885,7 +884,6 @@ F: hw/acpi/*
|
|||||||
F: hw/smbios/*
|
F: hw/smbios/*
|
||||||
F: hw/i386/acpi-build.[hc]
|
F: hw/i386/acpi-build.[hc]
|
||||||
F: hw/arm/virt-acpi-build.c
|
F: hw/arm/virt-acpi-build.c
|
||||||
F: include/hw/arm/virt-acpi-build.h
|
|
||||||
|
|
||||||
ppc4xx
|
ppc4xx
|
||||||
M: Alexander Graf <agraf@suse.de>
|
M: Alexander Graf <agraf@suse.de>
|
||||||
|
@ -1258,7 +1258,7 @@ static void pxa2xx_i2c_update(PXA2xxI2CState *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* These are only stubs now. */
|
/* These are only stubs now. */
|
||||||
static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
|
static int pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
|
PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
|
||||||
PXA2xxI2CState *s = slave->host;
|
PXA2xxI2CState *s = slave->host;
|
||||||
@ -1280,6 +1280,8 @@ static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pxa2xx_i2c_update(s);
|
pxa2xx_i2c_update(s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pxa2xx_i2c_rx(I2CSlave *i2c)
|
static int pxa2xx_i2c_rx(I2CSlave *i2c)
|
||||||
|
@ -172,7 +172,7 @@ static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
|
static int tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
TosaDACState *s = TOSA_DAC(i2c);
|
TosaDACState *s = TOSA_DAC(i2c);
|
||||||
|
|
||||||
@ -194,6 +194,8 @@ static void tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tosa_dac_recv(I2CSlave *s)
|
static int tosa_dac_recv(I2CSlave *s)
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "hw/arm/virt-acpi-build.h"
|
|
||||||
#include "qemu/bitmap.h"
|
#include "qemu/bitmap.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "qom/cpu.h"
|
#include "qom/cpu.h"
|
||||||
@ -43,6 +42,7 @@
|
|||||||
#include "hw/acpi/aml-build.h"
|
#include "hw/acpi/aml-build.h"
|
||||||
#include "hw/pci/pcie_host.h"
|
#include "hw/pci/pcie_host.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
|
#include "hw/arm/virt.h"
|
||||||
#include "sysemu/numa.h"
|
#include "sysemu/numa.h"
|
||||||
#include "kvm_arm.h"
|
#include "kvm_arm.h"
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
build_iort(GArray *table_data, BIOSLinker *linker)
|
||||||
{
|
{
|
||||||
int iort_start = table_data->len;
|
int iort_start = table_data->len;
|
||||||
AcpiIortIdMapping *idmap;
|
AcpiIortIdMapping *idmap;
|
||||||
@ -439,11 +439,11 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
AcpiSerialPortConsoleRedirection *spcr;
|
AcpiSerialPortConsoleRedirection *spcr;
|
||||||
const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
|
const MemMapEntry *uart_memmap = &vms->memmap[VIRT_UART];
|
||||||
int irq = guest_info->irqmap[VIRT_UART] + ARM_SPI_BASE;
|
int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
|
||||||
|
|
||||||
spcr = acpi_data_push(table_data, sizeof(*spcr));
|
spcr = acpi_data_push(table_data, sizeof(*spcr));
|
||||||
|
|
||||||
@ -472,16 +472,16 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
AcpiSystemResourceAffinityTable *srat;
|
AcpiSystemResourceAffinityTable *srat;
|
||||||
AcpiSratProcessorGiccAffinity *core;
|
AcpiSratProcessorGiccAffinity *core;
|
||||||
AcpiSratMemoryAffinity *numamem;
|
AcpiSratMemoryAffinity *numamem;
|
||||||
int i, j, srat_start;
|
int i, j, srat_start;
|
||||||
uint64_t mem_base;
|
uint64_t mem_base;
|
||||||
uint32_t *cpu_node = g_malloc0(guest_info->smp_cpus * sizeof(uint32_t));
|
uint32_t *cpu_node = g_malloc0(vms->smp_cpus * sizeof(uint32_t));
|
||||||
|
|
||||||
for (i = 0; i < guest_info->smp_cpus; i++) {
|
for (i = 0; i < vms->smp_cpus; i++) {
|
||||||
j = numa_get_node_for_cpu(i);
|
j = numa_get_node_for_cpu(i);
|
||||||
if (j < nb_numa_nodes) {
|
if (j < nb_numa_nodes) {
|
||||||
cpu_node[i] = j;
|
cpu_node[i] = j;
|
||||||
@ -492,7 +492,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
srat = acpi_data_push(table_data, sizeof(*srat));
|
srat = acpi_data_push(table_data, sizeof(*srat));
|
||||||
srat->reserved1 = cpu_to_le32(1);
|
srat->reserved1 = cpu_to_le32(1);
|
||||||
|
|
||||||
for (i = 0; i < guest_info->smp_cpus; ++i) {
|
for (i = 0; i < vms->smp_cpus; ++i) {
|
||||||
core = acpi_data_push(table_data, sizeof(*core));
|
core = acpi_data_push(table_data, sizeof(*core));
|
||||||
core->type = ACPI_SRAT_PROCESSOR_GICC;
|
core->type = ACPI_SRAT_PROCESSOR_GICC;
|
||||||
core->length = sizeof(*core);
|
core->length = sizeof(*core);
|
||||||
@ -502,7 +502,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
}
|
}
|
||||||
g_free(cpu_node);
|
g_free(cpu_node);
|
||||||
|
|
||||||
mem_base = guest_info->memmap[VIRT_MEM].base;
|
mem_base = vms->memmap[VIRT_MEM].base;
|
||||||
for (i = 0; i < nb_numa_nodes; ++i) {
|
for (i = 0; i < nb_numa_nodes; ++i) {
|
||||||
numamem = acpi_data_push(table_data, sizeof(*numamem));
|
numamem = acpi_data_push(table_data, sizeof(*numamem));
|
||||||
build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i,
|
build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i,
|
||||||
@ -515,10 +515,10 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
AcpiTableMcfg *mcfg;
|
AcpiTableMcfg *mcfg;
|
||||||
const MemMapEntry *memmap = guest_info->memmap;
|
const MemMapEntry *memmap = vms->memmap;
|
||||||
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
|
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
|
||||||
|
|
||||||
mcfg = acpi_data_push(table_data, len);
|
mcfg = acpi_data_push(table_data, len);
|
||||||
@ -535,24 +535,33 @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
|
|
||||||
/* GTDT */
|
/* GTDT */
|
||||||
static void
|
static void
|
||||||
build_gtdt(GArray *table_data, BIOSLinker *linker)
|
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
|
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||||
int gtdt_start = table_data->len;
|
int gtdt_start = table_data->len;
|
||||||
AcpiGenericTimerTable *gtdt;
|
AcpiGenericTimerTable *gtdt;
|
||||||
|
uint32_t irqflags;
|
||||||
|
|
||||||
|
if (vmc->claim_edge_triggered_timers) {
|
||||||
|
irqflags = ACPI_GTDT_INTERRUPT_MODE_EDGE;
|
||||||
|
} else {
|
||||||
|
irqflags = ACPI_GTDT_INTERRUPT_MODE_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
gtdt = acpi_data_push(table_data, sizeof *gtdt);
|
gtdt = acpi_data_push(table_data, sizeof *gtdt);
|
||||||
/* The interrupt values are the same with the device tree when adding 16 */
|
/* The interrupt values are the same with the device tree when adding 16 */
|
||||||
gtdt->secure_el1_interrupt = ARCH_TIMER_S_EL1_IRQ + 16;
|
gtdt->secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_S_EL1_IRQ + 16);
|
||||||
gtdt->secure_el1_flags = ACPI_EDGE_SENSITIVE;
|
gtdt->secure_el1_flags = cpu_to_le32(irqflags);
|
||||||
|
|
||||||
gtdt->non_secure_el1_interrupt = ARCH_TIMER_NS_EL1_IRQ + 16;
|
gtdt->non_secure_el1_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL1_IRQ + 16);
|
||||||
gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE | ACPI_GTDT_ALWAYS_ON;
|
gtdt->non_secure_el1_flags = cpu_to_le32(irqflags |
|
||||||
|
ACPI_GTDT_CAP_ALWAYS_ON);
|
||||||
|
|
||||||
gtdt->virtual_timer_interrupt = ARCH_TIMER_VIRT_IRQ + 16;
|
gtdt->virtual_timer_interrupt = cpu_to_le32(ARCH_TIMER_VIRT_IRQ + 16);
|
||||||
gtdt->virtual_timer_flags = ACPI_EDGE_SENSITIVE;
|
gtdt->virtual_timer_flags = cpu_to_le32(irqflags);
|
||||||
|
|
||||||
gtdt->non_secure_el2_interrupt = ARCH_TIMER_NS_EL2_IRQ + 16;
|
gtdt->non_secure_el2_interrupt = cpu_to_le32(ARCH_TIMER_NS_EL2_IRQ + 16);
|
||||||
gtdt->non_secure_el2_flags = ACPI_EDGE_SENSITIVE;
|
gtdt->non_secure_el2_flags = cpu_to_le32(irqflags);
|
||||||
|
|
||||||
build_header(linker, table_data,
|
build_header(linker, table_data,
|
||||||
(void *)(table_data->data + gtdt_start), "GTDT",
|
(void *)(table_data->data + gtdt_start), "GTDT",
|
||||||
@ -561,11 +570,12 @@ build_gtdt(GArray *table_data, BIOSLinker *linker)
|
|||||||
|
|
||||||
/* MADT */
|
/* MADT */
|
||||||
static void
|
static void
|
||||||
build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
|
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||||
int madt_start = table_data->len;
|
int madt_start = table_data->len;
|
||||||
const MemMapEntry *memmap = guest_info->memmap;
|
const MemMapEntry *memmap = vms->memmap;
|
||||||
const int *irqmap = guest_info->irqmap;
|
const int *irqmap = vms->irqmap;
|
||||||
AcpiMultipleApicTable *madt;
|
AcpiMultipleApicTable *madt;
|
||||||
AcpiMadtGenericDistributor *gicd;
|
AcpiMadtGenericDistributor *gicd;
|
||||||
AcpiMadtGenericMsiFrame *gic_msi;
|
AcpiMadtGenericMsiFrame *gic_msi;
|
||||||
@ -576,30 +586,30 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
gicd = acpi_data_push(table_data, sizeof *gicd);
|
gicd = acpi_data_push(table_data, sizeof *gicd);
|
||||||
gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
|
gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
|
||||||
gicd->length = sizeof(*gicd);
|
gicd->length = sizeof(*gicd);
|
||||||
gicd->base_address = memmap[VIRT_GIC_DIST].base;
|
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
|
||||||
gicd->version = guest_info->gic_version;
|
gicd->version = vms->gic_version;
|
||||||
|
|
||||||
for (i = 0; i < guest_info->smp_cpus; i++) {
|
for (i = 0; i < vms->smp_cpus; i++) {
|
||||||
AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
|
AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
|
||||||
sizeof *gicc);
|
sizeof(*gicc));
|
||||||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
|
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
|
||||||
|
|
||||||
gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
|
gicc->type = ACPI_APIC_GENERIC_CPU_INTERFACE;
|
||||||
gicc->length = sizeof(*gicc);
|
gicc->length = sizeof(*gicc);
|
||||||
if (guest_info->gic_version == 2) {
|
if (vms->gic_version == 2) {
|
||||||
gicc->base_address = memmap[VIRT_GIC_CPU].base;
|
gicc->base_address = cpu_to_le64(memmap[VIRT_GIC_CPU].base);
|
||||||
}
|
}
|
||||||
gicc->cpu_interface_number = i;
|
gicc->cpu_interface_number = cpu_to_le32(i);
|
||||||
gicc->arm_mpidr = armcpu->mp_affinity;
|
gicc->arm_mpidr = cpu_to_le64(armcpu->mp_affinity);
|
||||||
gicc->uid = i;
|
gicc->uid = cpu_to_le32(i);
|
||||||
gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
|
gicc->flags = cpu_to_le32(ACPI_MADT_GICC_ENABLED);
|
||||||
|
|
||||||
if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
|
if (arm_feature(&armcpu->env, ARM_FEATURE_PMU)) {
|
||||||
gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
|
gicc->performance_interrupt = cpu_to_le32(PPI(VIRTUAL_PMU_IRQ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guest_info->gic_version == 3) {
|
if (vms->gic_version == 3) {
|
||||||
AcpiMadtGenericTranslator *gic_its;
|
AcpiMadtGenericTranslator *gic_its;
|
||||||
AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
|
AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
|
||||||
sizeof *gicr);
|
sizeof *gicr);
|
||||||
@ -609,7 +619,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
|
gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
|
||||||
gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
|
gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
|
||||||
|
|
||||||
if (its_class_name() && !guest_info->no_its) {
|
if (its_class_name() && !vmc->no_its) {
|
||||||
gic_its = acpi_data_push(table_data, sizeof *gic_its);
|
gic_its = acpi_data_push(table_data, sizeof *gic_its);
|
||||||
gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
|
gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
|
||||||
gic_its->length = sizeof(*gic_its);
|
gic_its->length = sizeof(*gic_its);
|
||||||
@ -641,8 +651,8 @@ build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
|
|||||||
|
|
||||||
/* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
|
/* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
|
||||||
fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
|
fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
|
||||||
fadt->arm_boot_flags = cpu_to_le16((1 << ACPI_FADT_ARM_USE_PSCI_G_0_2) |
|
fadt->arm_boot_flags = cpu_to_le16(ACPI_FADT_ARM_PSCI_COMPLIANT |
|
||||||
(1 << ACPI_FADT_ARM_PSCI_USE_HVC));
|
ACPI_FADT_ARM_PSCI_USE_HVC);
|
||||||
|
|
||||||
/* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
|
/* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
|
||||||
fadt->minor_revision = 0x1;
|
fadt->minor_revision = 0x1;
|
||||||
@ -658,11 +668,11 @@ build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
|
|||||||
|
|
||||||
/* DSDT */
|
/* DSDT */
|
||||||
static void
|
static void
|
||||||
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
Aml *scope, *dsdt;
|
Aml *scope, *dsdt;
|
||||||
const MemMapEntry *memmap = guest_info->memmap;
|
const MemMapEntry *memmap = vms->memmap;
|
||||||
const int *irqmap = guest_info->irqmap;
|
const int *irqmap = vms->irqmap;
|
||||||
|
|
||||||
dsdt = init_aml_allocator();
|
dsdt = init_aml_allocator();
|
||||||
/* Reserve space for header */
|
/* Reserve space for header */
|
||||||
@ -674,7 +684,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
* the RTC ACPI device at all when using UEFI.
|
* the RTC ACPI device at all when using UEFI.
|
||||||
*/
|
*/
|
||||||
scope = aml_scope("\\_SB");
|
scope = aml_scope("\\_SB");
|
||||||
acpi_dsdt_add_cpus(scope, guest_info->smp_cpus);
|
acpi_dsdt_add_cpus(scope, vms->smp_cpus);
|
||||||
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
|
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
|
||||||
(irqmap[VIRT_UART] + ARM_SPI_BASE));
|
(irqmap[VIRT_UART] + ARM_SPI_BASE));
|
||||||
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
|
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
|
||||||
@ -682,7 +692,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
|
|||||||
acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
|
acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
|
||||||
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
|
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
|
||||||
acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
|
acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
|
||||||
guest_info->use_highmem);
|
vms->highmem);
|
||||||
acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
|
acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
|
||||||
(irqmap[VIRT_GPIO] + ARM_SPI_BASE));
|
(irqmap[VIRT_GPIO] + ARM_SPI_BASE));
|
||||||
acpi_dsdt_add_power_button(scope);
|
acpi_dsdt_add_power_button(scope);
|
||||||
@ -705,12 +715,12 @@ struct AcpiBuildState {
|
|||||||
MemoryRegion *linker_mr;
|
MemoryRegion *linker_mr;
|
||||||
/* Is table patched? */
|
/* Is table patched? */
|
||||||
bool patched;
|
bool patched;
|
||||||
VirtGuestInfo *guest_info;
|
|
||||||
} AcpiBuildState;
|
} AcpiBuildState;
|
||||||
|
|
||||||
static
|
static
|
||||||
void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
|
void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||||
{
|
{
|
||||||
|
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||||
GArray *table_offsets;
|
GArray *table_offsets;
|
||||||
unsigned dsdt, rsdt;
|
unsigned dsdt, rsdt;
|
||||||
GArray *tables_blob = tables->table_data;
|
GArray *tables_blob = tables->table_data;
|
||||||
@ -724,32 +734,32 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
|
|||||||
|
|
||||||
/* DSDT is pointed to by FADT */
|
/* DSDT is pointed to by FADT */
|
||||||
dsdt = tables_blob->len;
|
dsdt = tables_blob->len;
|
||||||
build_dsdt(tables_blob, tables->linker, guest_info);
|
build_dsdt(tables_blob, tables->linker, vms);
|
||||||
|
|
||||||
/* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
|
/* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_fadt(tables_blob, tables->linker, dsdt);
|
build_fadt(tables_blob, tables->linker, dsdt);
|
||||||
|
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_madt(tables_blob, tables->linker, guest_info);
|
build_madt(tables_blob, tables->linker, vms);
|
||||||
|
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_gtdt(tables_blob, tables->linker);
|
build_gtdt(tables_blob, tables->linker, vms);
|
||||||
|
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_mcfg(tables_blob, tables->linker, guest_info);
|
build_mcfg(tables_blob, tables->linker, vms);
|
||||||
|
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_spcr(tables_blob, tables->linker, guest_info);
|
build_spcr(tables_blob, tables->linker, vms);
|
||||||
|
|
||||||
if (nb_numa_nodes > 0) {
|
if (nb_numa_nodes > 0) {
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_srat(tables_blob, tables->linker, guest_info);
|
build_srat(tables_blob, tables->linker, vms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (its_class_name() && !guest_info->no_its) {
|
if (its_class_name() && !vmc->no_its) {
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_iort(tables_blob, tables->linker, guest_info);
|
build_iort(tables_blob, tables->linker);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RSDT is pointed to by RSDP */
|
/* RSDT is pointed to by RSDP */
|
||||||
@ -788,13 +798,12 @@ static void virt_acpi_build_update(void *build_opaque)
|
|||||||
|
|
||||||
acpi_build_tables_init(&tables);
|
acpi_build_tables_init(&tables);
|
||||||
|
|
||||||
virt_acpi_build(build_state->guest_info, &tables);
|
virt_acpi_build(VIRT_MACHINE(qdev_get_machine()), &tables);
|
||||||
|
|
||||||
acpi_ram_update(build_state->table_mr, tables.table_data);
|
acpi_ram_update(build_state->table_mr, tables.table_data);
|
||||||
acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
|
acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
|
||||||
acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
|
acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
|
||||||
|
|
||||||
|
|
||||||
acpi_build_tables_cleanup(&tables, true);
|
acpi_build_tables_cleanup(&tables, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,12 +831,12 @@ static const VMStateDescription vmstate_virt_acpi_build = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void virt_acpi_setup(VirtGuestInfo *guest_info)
|
void virt_acpi_setup(VirtMachineState *vms)
|
||||||
{
|
{
|
||||||
AcpiBuildTables tables;
|
AcpiBuildTables tables;
|
||||||
AcpiBuildState *build_state;
|
AcpiBuildState *build_state;
|
||||||
|
|
||||||
if (!guest_info->fw_cfg) {
|
if (!vms->fw_cfg) {
|
||||||
trace_virt_acpi_setup();
|
trace_virt_acpi_setup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -838,10 +847,9 @@ void virt_acpi_setup(VirtGuestInfo *guest_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_state = g_malloc0(sizeof *build_state);
|
build_state = g_malloc0(sizeof *build_state);
|
||||||
build_state->guest_info = guest_info;
|
|
||||||
|
|
||||||
acpi_build_tables_init(&tables);
|
acpi_build_tables_init(&tables);
|
||||||
virt_acpi_build(build_state->guest_info, &tables);
|
virt_acpi_build(vms, &tables);
|
||||||
|
|
||||||
/* Now expose it all to Guest */
|
/* Now expose it all to Guest */
|
||||||
build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
|
build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
|
||||||
@ -853,8 +861,8 @@ void virt_acpi_setup(VirtGuestInfo *guest_info)
|
|||||||
acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
|
acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
|
||||||
"etc/table-loader", 0);
|
"etc/table-loader", 0);
|
||||||
|
|
||||||
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
|
fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
|
||||||
tables.tcpalog->data, acpi_data_len(tables.tcpalog));
|
acpi_data_len(tables.tcpalog));
|
||||||
|
|
||||||
build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
|
build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
|
||||||
ACPI_BUILD_RSDP_FILE, 0);
|
ACPI_BUILD_RSDP_FILE, 0);
|
||||||
|
687
hw/arm/virt.c
687
hw/arm/virt.c
File diff suppressed because it is too large
Load Diff
@ -220,7 +220,7 @@ static int aer915_send(I2CSlave *i2c, uint8_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aer915_event(I2CSlave *i2c, enum i2c_event event)
|
static int aer915_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
AER915State *s = AER915(i2c);
|
AER915State *s = AER915(i2c);
|
||||||
|
|
||||||
@ -238,6 +238,8 @@ static void aer915_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aer915_recv(I2CSlave *slave)
|
static int aer915_recv(I2CSlave *slave)
|
||||||
|
@ -303,7 +303,7 @@ static void wm8750_reset(I2CSlave *i2c)
|
|||||||
s->i2c_len = 0;
|
s->i2c_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wm8750_event(I2CSlave *i2c, enum i2c_event event)
|
static int wm8750_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
WM8750State *s = WM8750(i2c);
|
WM8750State *s = WM8750(i2c);
|
||||||
|
|
||||||
@ -321,6 +321,8 @@ static void wm8750_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WM8750_LINVOL 0x00
|
#define WM8750_LINVOL 0x00
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "hw/ssi/ssi.h"
|
#include "hw/ssi/ssi.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#ifndef M25P80_ERR_DEBUG
|
#ifndef M25P80_ERR_DEBUG
|
||||||
@ -377,6 +378,8 @@ typedef enum {
|
|||||||
MAN_GENERIC,
|
MAN_GENERIC,
|
||||||
} Manufacturer;
|
} Manufacturer;
|
||||||
|
|
||||||
|
#define M25P80_INTERNAL_DATA_BUFFER_SZ 16
|
||||||
|
|
||||||
typedef struct Flash {
|
typedef struct Flash {
|
||||||
SSISlave parent_obj;
|
SSISlave parent_obj;
|
||||||
|
|
||||||
@ -387,7 +390,7 @@ typedef struct Flash {
|
|||||||
int page_size;
|
int page_size;
|
||||||
|
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
uint8_t data[16];
|
uint8_t data[M25P80_INTERNAL_DATA_BUFFER_SZ];
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t pos;
|
uint32_t pos;
|
||||||
uint8_t needed_bytes;
|
uint8_t needed_bytes;
|
||||||
@ -1115,6 +1118,17 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
|||||||
|
|
||||||
case STATE_COLLECTING_DATA:
|
case STATE_COLLECTING_DATA:
|
||||||
case STATE_COLLECTING_VAR_LEN_DATA:
|
case STATE_COLLECTING_VAR_LEN_DATA:
|
||||||
|
|
||||||
|
if (s->len >= M25P80_INTERNAL_DATA_BUFFER_SZ) {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"M25P80: Write overrun internal data buffer. "
|
||||||
|
"SPI controller (QEMU emulator or guest driver) "
|
||||||
|
"is misbehaving\n");
|
||||||
|
s->len = s->pos = 0;
|
||||||
|
s->state = STATE_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
s->data[s->len] = (uint8_t)tx;
|
s->data[s->len] = (uint8_t)tx;
|
||||||
s->len++;
|
s->len++;
|
||||||
|
|
||||||
@ -1124,6 +1138,17 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_READING_DATA:
|
case STATE_READING_DATA:
|
||||||
|
|
||||||
|
if (s->pos >= M25P80_INTERNAL_DATA_BUFFER_SZ) {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"M25P80: Read overrun internal data buffer. "
|
||||||
|
"SPI controller (QEMU emulator or guest driver) "
|
||||||
|
"is misbehaving\n");
|
||||||
|
s->len = s->pos = 0;
|
||||||
|
s->state = STATE_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
r = s->data[s->pos];
|
r = s->data[s->pos];
|
||||||
s->pos++;
|
s->pos++;
|
||||||
if (s->pos == s->len) {
|
if (s->pos == s->len) {
|
||||||
@ -1196,7 +1221,7 @@ static const VMStateDescription vmstate_m25p80 = {
|
|||||||
.pre_save = m25p80_pre_save,
|
.pre_save = m25p80_pre_save,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT8(state, Flash),
|
VMSTATE_UINT8(state, Flash),
|
||||||
VMSTATE_UINT8_ARRAY(data, Flash, 16),
|
VMSTATE_UINT8_ARRAY(data, Flash, M25P80_INTERNAL_DATA_BUFFER_SZ),
|
||||||
VMSTATE_UINT32(len, Flash),
|
VMSTATE_UINT32(len, Flash),
|
||||||
VMSTATE_UINT32(pos, Flash),
|
VMSTATE_UINT32(pos, Flash),
|
||||||
VMSTATE_UINT8(needed_bytes, Flash),
|
VMSTATE_UINT8(needed_bytes, Flash),
|
||||||
|
@ -629,22 +629,26 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exynos4210_uart_init(SysBusDevice *dev)
|
static void exynos4210_uart_init(Object *obj)
|
||||||
{
|
{
|
||||||
|
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
|
||||||
Exynos4210UartState *s = EXYNOS4210_UART(dev);
|
Exynos4210UartState *s = EXYNOS4210_UART(dev);
|
||||||
|
|
||||||
/* memory mapping */
|
/* memory mapping */
|
||||||
memory_region_init_io(&s->iomem, OBJECT(s), &exynos4210_uart_ops, s,
|
memory_region_init_io(&s->iomem, obj, &exynos4210_uart_ops, s,
|
||||||
"exynos4210.uart", EXYNOS4210_UART_REGS_MEM_SIZE);
|
"exynos4210.uart", EXYNOS4210_UART_REGS_MEM_SIZE);
|
||||||
sysbus_init_mmio(dev, &s->iomem);
|
sysbus_init_mmio(dev, &s->iomem);
|
||||||
|
|
||||||
sysbus_init_irq(dev, &s->irq);
|
sysbus_init_irq(dev, &s->irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void exynos4210_uart_realize(DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
Exynos4210UartState *s = EXYNOS4210_UART(dev);
|
||||||
|
|
||||||
qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive,
|
qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive,
|
||||||
exynos4210_uart_receive, exynos4210_uart_event,
|
exynos4210_uart_receive, exynos4210_uart_event,
|
||||||
s, NULL, true);
|
s, NULL, true);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property exynos4210_uart_properties[] = {
|
static Property exynos4210_uart_properties[] = {
|
||||||
@ -658,9 +662,8 @@ static Property exynos4210_uart_properties[] = {
|
|||||||
static void exynos4210_uart_class_init(ObjectClass *klass, void *data)
|
static void exynos4210_uart_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
|
|
||||||
|
|
||||||
k->init = exynos4210_uart_init;
|
dc->realize = exynos4210_uart_realize;
|
||||||
dc->reset = exynos4210_uart_reset;
|
dc->reset = exynos4210_uart_reset;
|
||||||
dc->props = exynos4210_uart_properties;
|
dc->props = exynos4210_uart_properties;
|
||||||
dc->vmsd = &vmstate_exynos4210_uart;
|
dc->vmsd = &vmstate_exynos4210_uart;
|
||||||
@ -670,6 +673,7 @@ static const TypeInfo exynos4210_uart_info = {
|
|||||||
.name = TYPE_EXYNOS4210_UART,
|
.name = TYPE_EXYNOS4210_UART,
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
.instance_size = sizeof(Exynos4210UartState),
|
.instance_size = sizeof(Exynos4210UartState),
|
||||||
|
.instance_init = exynos4210_uart_init,
|
||||||
.class_init = exynos4210_uart_class_init,
|
.class_init = exynos4210_uart_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ static int ssd0303_send(I2CSlave *i2c, uint8_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
|
static int ssd0303_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
ssd0303_state *s = SSD0303(i2c);
|
ssd0303_state *s = SSD0303(i2c);
|
||||||
|
|
||||||
@ -193,6 +193,8 @@ static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
/* Nothing to do. */
|
/* Nothing to do. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ssd0303_update_display(void *opaque)
|
static void ssd0303_update_display(void *opaque)
|
||||||
|
@ -129,7 +129,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void max7310_event(I2CSlave *i2c, enum i2c_event event)
|
static int max7310_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
MAX7310State *s = MAX7310(i2c);
|
MAX7310State *s = MAX7310(i2c);
|
||||||
s->len = 0;
|
s->len = 0;
|
||||||
@ -147,6 +147,8 @@ static void max7310_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_max7310 = {
|
static const VMStateDescription vmstate_max7310 = {
|
||||||
|
@ -88,18 +88,26 @@ int i2c_bus_busy(I2CBus *bus)
|
|||||||
return !QLIST_EMPTY(&bus->current_devs);
|
return !QLIST_EMPTY(&bus->current_devs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns non-zero if the address is not valid. If this is called
|
|
||||||
* again without an intervening i2c_end_transfer(), like in the SMBus
|
|
||||||
* case where the operation is switched from write to read, this
|
|
||||||
* function will not rescan the bus and thus cannot fail.
|
|
||||||
*/
|
|
||||||
/* TODO: Make this handle multiple masters. */
|
/* TODO: Make this handle multiple masters. */
|
||||||
|
/*
|
||||||
|
* Start or continue an i2c transaction. When this is called for the
|
||||||
|
* first time or after an i2c_end_transfer(), if it returns an error
|
||||||
|
* the bus transaction is terminated (or really never started). If
|
||||||
|
* this is called after another i2c_start_transfer() without an
|
||||||
|
* intervening i2c_end_transfer(), and it returns an error, the
|
||||||
|
* transaction will not be terminated. The caller must do it.
|
||||||
|
*
|
||||||
|
* This corresponds with the way real hardware works. The SMBus
|
||||||
|
* protocol uses a start transfer to switch from write to read mode
|
||||||
|
* without releasing the bus. If that fails, the bus is still
|
||||||
|
* in a transaction.
|
||||||
|
*/
|
||||||
int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
|
int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
|
||||||
{
|
{
|
||||||
BusChild *kid;
|
BusChild *kid;
|
||||||
I2CSlaveClass *sc;
|
I2CSlaveClass *sc;
|
||||||
I2CNode *node;
|
I2CNode *node;
|
||||||
|
bool bus_scanned = false;
|
||||||
|
|
||||||
if (address == I2C_BROADCAST) {
|
if (address == I2C_BROADCAST) {
|
||||||
/*
|
/*
|
||||||
@ -130,6 +138,7 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bus_scanned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QLIST_EMPTY(&bus->current_devs)) {
|
if (QLIST_EMPTY(&bus->current_devs)) {
|
||||||
@ -137,11 +146,21 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QLIST_FOREACH(node, &bus->current_devs, next) {
|
QLIST_FOREACH(node, &bus->current_devs, next) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
sc = I2C_SLAVE_GET_CLASS(node->elt);
|
sc = I2C_SLAVE_GET_CLASS(node->elt);
|
||||||
/* If the bus is already busy, assume this is a repeated
|
/* If the bus is already busy, assume this is a repeated
|
||||||
start condition. */
|
start condition. */
|
||||||
|
|
||||||
if (sc->event) {
|
if (sc->event) {
|
||||||
sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND);
|
rv = sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND);
|
||||||
|
if (rv && !bus->broadcast) {
|
||||||
|
if (bus_scanned) {
|
||||||
|
/* First call, terminate the transfer. */
|
||||||
|
i2c_end_transfer(bus);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -230,13 +230,15 @@ static void i2c_ddc_reset(DeviceState *ds)
|
|||||||
s->reg = 0;
|
s->reg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i2c_ddc_event(I2CSlave *i2c, enum i2c_event event)
|
static int i2c_ddc_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
I2CDDCState *s = I2CDDC(i2c);
|
I2CDDCState *s = I2CDDC(i2c);
|
||||||
|
|
||||||
if (event == I2C_START_SEND) {
|
if (event == I2C_START_SEND) {
|
||||||
s->firstbyte = true;
|
s->firstbyte = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int i2c_ddc_rx(I2CSlave *i2c)
|
static int i2c_ddc_rx(I2CSlave *i2c)
|
||||||
|
@ -67,7 +67,7 @@ static void smbus_do_write(SMBusDevice *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
|
static int smbus_i2c_event(I2CSlave *s, enum i2c_event event)
|
||||||
{
|
{
|
||||||
SMBusDevice *dev = SMBUS_DEVICE(s);
|
SMBusDevice *dev = SMBUS_DEVICE(s);
|
||||||
|
|
||||||
@ -148,6 +148,8 @@ static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbus_i2c_recv(I2CSlave *s)
|
static int smbus_i2c_recv(I2CSlave *s)
|
||||||
@ -249,7 +251,8 @@ int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
|
|||||||
}
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
if (i2c_start_transfer(bus, addr, 1)) {
|
if (i2c_start_transfer(bus, addr, 1)) {
|
||||||
assert(0);
|
i2c_end_transfer(bus);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
data = i2c_recv(bus);
|
data = i2c_recv(bus);
|
||||||
i2c_nack(bus);
|
i2c_nack(bus);
|
||||||
@ -276,7 +279,8 @@ int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
|
|||||||
}
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
if (i2c_start_transfer(bus, addr, 1)) {
|
if (i2c_start_transfer(bus, addr, 1)) {
|
||||||
assert(0);
|
i2c_end_transfer(bus);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
data = i2c_recv(bus);
|
data = i2c_recv(bus);
|
||||||
data |= i2c_recv(bus) << 8;
|
data |= i2c_recv(bus) << 8;
|
||||||
@ -307,7 +311,8 @@ int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
|
|||||||
}
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
if (i2c_start_transfer(bus, addr, 1)) {
|
if (i2c_start_transfer(bus, addr, 1)) {
|
||||||
assert(0);
|
i2c_end_transfer(bus);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
len = i2c_recv(bus);
|
len = i2c_recv(bus);
|
||||||
if (len > 32) {
|
if (len > 32) {
|
||||||
|
@ -383,7 +383,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
|
static int lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
LM823KbdState *s = LM8323(i2c);
|
LM823KbdState *s = LM8323(i2c);
|
||||||
|
|
||||||
@ -397,6 +397,8 @@ static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lm_i2c_rx(I2CSlave *i2c)
|
static int lm_i2c_rx(I2CSlave *i2c)
|
||||||
|
@ -176,7 +176,7 @@ static int tmp105_tx(I2CSlave *i2c, uint8_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tmp105_event(I2CSlave *i2c, enum i2c_event event)
|
static int tmp105_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
TMP105State *s = TMP105(i2c);
|
TMP105State *s = TMP105(i2c);
|
||||||
|
|
||||||
@ -185,6 +185,7 @@ static void tmp105_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->len = 0;
|
s->len = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tmp105_post_load(void *opaque, int version_id)
|
static int tmp105_post_load(void *opaque, int version_id)
|
||||||
|
@ -320,9 +320,6 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
|
|||||||
TYPE_IMX_SPI, __func__);
|
TYPE_IMX_SPI, __func__);
|
||||||
break;
|
break;
|
||||||
case ECSPI_TXDATA:
|
case ECSPI_TXDATA:
|
||||||
case ECSPI_MSGDATA:
|
|
||||||
/* Is there any difference between TXDATA and MSGDATA ? */
|
|
||||||
/* I'll have to look in the linux driver */
|
|
||||||
if (!imx_spi_is_enabled(s)) {
|
if (!imx_spi_is_enabled(s)) {
|
||||||
/* Ignore writes if device is disabled */
|
/* Ignore writes if device is disabled */
|
||||||
break;
|
break;
|
||||||
@ -380,6 +377,14 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case ECSPI_MSGDATA:
|
||||||
|
/* it is not clear from the spec what MSGDATA is for */
|
||||||
|
/* Anyway it is not used by Linux driver */
|
||||||
|
/* So for now we just ignore it */
|
||||||
|
qemu_log_mask(LOG_UNIMP,
|
||||||
|
"[%s]%s: Trying to write to MSGDATA, ignoring\n",
|
||||||
|
TYPE_IMX_SPI, __func__);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
s->regs[index] = value;
|
s->regs[index] = value;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ static void inc_regptr(DS1338State *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
|
static int ds1338_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
DS1338State *s = DS1338(i2c);
|
DS1338State *s = DS1338(i2c);
|
||||||
|
|
||||||
@ -113,6 +113,8 @@ static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ds1338_recv(I2CSlave *i2c)
|
static int ds1338_recv(I2CSlave *i2c)
|
||||||
|
@ -713,12 +713,14 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void menelaus_event(I2CSlave *i2c, enum i2c_event event)
|
static int menelaus_event(I2CSlave *i2c, enum i2c_event event)
|
||||||
{
|
{
|
||||||
MenelausState *s = TWL92230(i2c);
|
MenelausState *s = TWL92230(i2c);
|
||||||
|
|
||||||
if (event == I2C_START_SEND)
|
if (event == I2C_START_SEND)
|
||||||
s->firstbyte = 1;
|
s->firstbyte = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int menelaus_tx(I2CSlave *i2c, uint8_t data)
|
static int menelaus_tx(I2CSlave *i2c, uint8_t data)
|
||||||
|
@ -191,10 +191,8 @@ struct AcpiFadtDescriptorRev5_1 {
|
|||||||
|
|
||||||
typedef struct AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
|
typedef struct AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
|
||||||
|
|
||||||
enum {
|
#define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0)
|
||||||
ACPI_FADT_ARM_USE_PSCI_G_0_2 = 0,
|
#define ACPI_FADT_ARM_PSCI_USE_HVC (1 << 1)
|
||||||
ACPI_FADT_ARM_PSCI_USE_HVC = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Serial Port Console Redirection Table (SPCR), Rev. 1.02
|
* Serial Port Console Redirection Table (SPCR), Rev. 1.02
|
||||||
@ -290,7 +288,7 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
|
|||||||
#define ACPI_APIC_XRUPT_SOURCE 8
|
#define ACPI_APIC_XRUPT_SOURCE 8
|
||||||
#define ACPI_APIC_LOCAL_X2APIC 9
|
#define ACPI_APIC_LOCAL_X2APIC 9
|
||||||
#define ACPI_APIC_LOCAL_X2APIC_NMI 10
|
#define ACPI_APIC_LOCAL_X2APIC_NMI 10
|
||||||
#define ACPI_APIC_GENERIC_INTERRUPT 11
|
#define ACPI_APIC_GENERIC_CPU_INTERFACE 11
|
||||||
#define ACPI_APIC_GENERIC_DISTRIBUTOR 12
|
#define ACPI_APIC_GENERIC_DISTRIBUTOR 12
|
||||||
#define ACPI_APIC_GENERIC_MSI_FRAME 13
|
#define ACPI_APIC_GENERIC_MSI_FRAME 13
|
||||||
#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
|
#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
|
||||||
@ -361,7 +359,7 @@ struct AcpiMadtLocalX2ApicNmi {
|
|||||||
} QEMU_PACKED;
|
} QEMU_PACKED;
|
||||||
typedef struct AcpiMadtLocalX2ApicNmi AcpiMadtLocalX2ApicNmi;
|
typedef struct AcpiMadtLocalX2ApicNmi AcpiMadtLocalX2ApicNmi;
|
||||||
|
|
||||||
struct AcpiMadtGenericInterrupt {
|
struct AcpiMadtGenericCpuInterface {
|
||||||
ACPI_SUB_HEADER_DEF
|
ACPI_SUB_HEADER_DEF
|
||||||
uint16_t reserved;
|
uint16_t reserved;
|
||||||
uint32_t cpu_interface_number;
|
uint32_t cpu_interface_number;
|
||||||
@ -378,7 +376,10 @@ struct AcpiMadtGenericInterrupt {
|
|||||||
uint64_t arm_mpidr;
|
uint64_t arm_mpidr;
|
||||||
} QEMU_PACKED;
|
} QEMU_PACKED;
|
||||||
|
|
||||||
typedef struct AcpiMadtGenericInterrupt AcpiMadtGenericInterrupt;
|
typedef struct AcpiMadtGenericCpuInterface AcpiMadtGenericCpuInterface;
|
||||||
|
|
||||||
|
/* GICC CPU Interface Flags */
|
||||||
|
#define ACPI_MADT_GICC_ENABLED 1
|
||||||
|
|
||||||
struct AcpiMadtGenericDistributor {
|
struct AcpiMadtGenericDistributor {
|
||||||
ACPI_SUB_HEADER_DEF
|
ACPI_SUB_HEADER_DEF
|
||||||
@ -427,21 +428,9 @@ typedef struct AcpiMadtGenericTranslator AcpiMadtGenericTranslator;
|
|||||||
/*
|
/*
|
||||||
* Generic Timer Description Table (GTDT)
|
* Generic Timer Description Table (GTDT)
|
||||||
*/
|
*/
|
||||||
|
#define ACPI_GTDT_INTERRUPT_MODE_LEVEL (0 << 0)
|
||||||
#define ACPI_GTDT_INTERRUPT_MODE (1 << 0)
|
#define ACPI_GTDT_INTERRUPT_MODE_EDGE (1 << 0)
|
||||||
#define ACPI_GTDT_INTERRUPT_POLARITY (1 << 1)
|
#define ACPI_GTDT_CAP_ALWAYS_ON (1 << 2)
|
||||||
#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 {
|
struct AcpiGenericTimerTable {
|
||||||
ACPI_TABLE_HEADER_DEF
|
ACPI_TABLE_HEADER_DEF
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
#include "qemu/notify.h"
|
|
||||||
|
|
||||||
#define ACPI_GICC_ENABLED 1
|
|
||||||
|
|
||||||
typedef struct VirtGuestInfo {
|
|
||||||
int smp_cpus;
|
|
||||||
FWCfgState *fw_cfg;
|
|
||||||
const MemMapEntry *memmap;
|
|
||||||
const int *irqmap;
|
|
||||||
bool use_highmem;
|
|
||||||
int gic_version;
|
|
||||||
bool no_its;
|
|
||||||
} VirtGuestInfo;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct VirtGuestInfoState {
|
|
||||||
VirtGuestInfo info;
|
|
||||||
Notifier machine_done;
|
|
||||||
} VirtGuestInfoState;
|
|
||||||
|
|
||||||
void virt_acpi_setup(VirtGuestInfo *guest_info);
|
|
||||||
|
|
||||||
#endif
|
|
@ -32,6 +32,9 @@
|
|||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "exec/hwaddr.h"
|
#include "exec/hwaddr.h"
|
||||||
|
#include "qemu/notify.h"
|
||||||
|
#include "hw/boards.h"
|
||||||
|
#include "hw/arm/arm.h"
|
||||||
|
|
||||||
#define NUM_GICV2M_SPIS 64
|
#define NUM_GICV2M_SPIS 64
|
||||||
#define NUM_VIRTIO_TRANSPORTS 32
|
#define NUM_VIRTIO_TRANSPORTS 32
|
||||||
@ -74,5 +77,41 @@ typedef struct MemMapEntry {
|
|||||||
hwaddr size;
|
hwaddr size;
|
||||||
} MemMapEntry;
|
} MemMapEntry;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MachineClass parent;
|
||||||
|
bool disallow_affinity_adjustment;
|
||||||
|
bool no_its;
|
||||||
|
bool no_pmu;
|
||||||
|
bool claim_edge_triggered_timers;
|
||||||
|
} VirtMachineClass;
|
||||||
|
|
||||||
#endif
|
typedef struct {
|
||||||
|
MachineState parent;
|
||||||
|
Notifier machine_done;
|
||||||
|
FWCfgState *fw_cfg;
|
||||||
|
bool secure;
|
||||||
|
bool highmem;
|
||||||
|
int32_t gic_version;
|
||||||
|
struct arm_boot_info bootinfo;
|
||||||
|
const MemMapEntry *memmap;
|
||||||
|
const int *irqmap;
|
||||||
|
int smp_cpus;
|
||||||
|
void *fdt;
|
||||||
|
int fdt_size;
|
||||||
|
uint32_t clock_phandle;
|
||||||
|
uint32_t gic_phandle;
|
||||||
|
uint32_t msi_phandle;
|
||||||
|
bool using_psci;
|
||||||
|
} VirtMachineState;
|
||||||
|
|
||||||
|
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||||
|
#define VIRT_MACHINE(obj) \
|
||||||
|
OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
|
||||||
|
#define VIRT_MACHINE_GET_CLASS(obj) \
|
||||||
|
OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_VIRT_MACHINE)
|
||||||
|
#define VIRT_MACHINE_CLASS(klass) \
|
||||||
|
OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
|
||||||
|
|
||||||
|
void virt_acpi_setup(VirtMachineState *vms);
|
||||||
|
|
||||||
|
#endif /* QEMU_ARM_VIRT_H */
|
||||||
|
@ -32,14 +32,22 @@ typedef struct I2CSlaveClass
|
|||||||
/* Callbacks provided by the device. */
|
/* Callbacks provided by the device. */
|
||||||
int (*init)(I2CSlave *dev);
|
int (*init)(I2CSlave *dev);
|
||||||
|
|
||||||
/* Master to slave. */
|
/* Master to slave. Returns non-zero for a NAK, 0 for success. */
|
||||||
int (*send)(I2CSlave *s, uint8_t data);
|
int (*send)(I2CSlave *s, uint8_t data);
|
||||||
|
|
||||||
/* Slave to master. */
|
/*
|
||||||
|
* Slave to master. This cannot fail, the device should always
|
||||||
|
* return something here. Negative values probably result in 0xff
|
||||||
|
* and a possible log from the driver, and shouldn't be used.
|
||||||
|
*/
|
||||||
int (*recv)(I2CSlave *s);
|
int (*recv)(I2CSlave *s);
|
||||||
|
|
||||||
/* Notify the slave of a bus state change. */
|
/*
|
||||||
void (*event)(I2CSlave *s, enum i2c_event event);
|
* Notify the slave of a bus state change. For start event,
|
||||||
|
* returns non-zero to NAK an operation. For other events the
|
||||||
|
* return code is not used and should be zero.
|
||||||
|
*/
|
||||||
|
int (*event)(I2CSlave *s, enum i2c_event event);
|
||||||
} I2CSlaveClass;
|
} I2CSlaveClass;
|
||||||
|
|
||||||
struct I2CSlave
|
struct I2CSlave
|
||||||
|
Loading…
x
Reference in New Issue
Block a user