From b7d678135f0294489e0458ef97088e848d08dfb5 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 22 Jun 2018 09:00:08 +0100 Subject: mac_dbdma: only dump commands for debug enabled channels This enables us to apply the same filter in DEBUG_DBDMA_CHANMASK to the DBDMA command execution debug output. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/mac_dbdma.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 1b2a69b..87ae246 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -71,18 +71,19 @@ static DBDMAState *dbdma_from_ch(DBDMA_channel *ch) } #if DEBUG_DBDMA -static void dump_dbdma_cmd(dbdma_cmd *cmd) +static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd) { - printf("dbdma_cmd %p\n", cmd); - printf(" req_count 0x%04x\n", le16_to_cpu(cmd->req_count)); - printf(" command 0x%04x\n", le16_to_cpu(cmd->command)); - printf(" phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr)); - printf(" cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep)); - printf(" res_count 0x%04x\n", le16_to_cpu(cmd->res_count)); - printf(" xfer_status 0x%04x\n", le16_to_cpu(cmd->xfer_status)); + DBDMA_DPRINTFCH(ch, "dbdma_cmd %p\n", cmd); + DBDMA_DPRINTFCH(ch, " req_count 0x%04x\n", le16_to_cpu(cmd->req_count)); + DBDMA_DPRINTFCH(ch, " command 0x%04x\n", le16_to_cpu(cmd->command)); + DBDMA_DPRINTFCH(ch, " phy_addr 0x%08x\n", le32_to_cpu(cmd->phy_addr)); + DBDMA_DPRINTFCH(ch, " cmd_dep 0x%08x\n", le32_to_cpu(cmd->cmd_dep)); + DBDMA_DPRINTFCH(ch, " res_count 0x%04x\n", le16_to_cpu(cmd->res_count)); + DBDMA_DPRINTFCH(ch, " xfer_status 0x%04x\n", + le16_to_cpu(cmd->xfer_status)); } #else -static void dump_dbdma_cmd(dbdma_cmd *cmd) +static void dump_dbdma_cmd(DBDMA_channel *ch, dbdma_cmd *cmd) { } #endif @@ -448,7 +449,7 @@ static void channel_run(DBDMA_channel *ch) uint32_t phy_addr; DBDMA_DPRINTFCH(ch, "channel_run\n"); - dump_dbdma_cmd(current); + dump_dbdma_cmd(ch, current); /* clear WAKE flag at command fetch */ -- cgit v1.1 From 5107a9cb431b816af6d7e450c22b044198bc6d18 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 22 Jun 2018 09:00:09 +0100 Subject: mac_newworld: always enable disable_direct_reg3_writes for ADB machines Commit 84051eb400 "adb: add property to disable direct reg 3 writes" added a workaround for MacOS 9 incorrectly setting the mouse address during boot of PMU machines. Further testing has shown that since fb6649f172 "adb: fix read reg 3 byte ordering" this can still sometimes happen with the CUDA mac99 machine, so let's enable this workaround for all New World machines using ADB for now. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index ff715ff..2b13fcd 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -407,11 +407,11 @@ static void ppc_core99_init(MachineState *machine) adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); - qdev_prop_set_bit(dev, "disable-direct-reg3-writes", has_pmu); + qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true); qdev_init_nofail(dev); dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); - qdev_prop_set_bit(dev, "disable-direct-reg3-writes", has_pmu); + qdev_prop_set_bit(dev, "disable-direct-reg3-writes", true); qdev_init_nofail(dev); } -- cgit v1.1 From 43f7868da3c84c1c7eef89631ab0bf6dc194eedb Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 23 Jun 2018 14:18:05 -0700 Subject: sam460ex: Fix sam460ex device tree when booting the Linux kernel sam460ex (or at least this emulation) does not support the "ibm,cpm" power management. As a result, Linux crashes when trying to access it. Remove its device tree node. Also, if/when we boot the Linux kernel directly, serial port clock frequencies in the device tree file will be unset, and serial port initialization will fail. Add valid frequency values to the serial ports to be able to use it. Also set valid values for the other clock nodes otherwise set by u-boot. Signed-off-by: Guenter Roeck Reviewed-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/ppc/sam460ex.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'hw') diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index bdc53d2..33ea518 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -37,6 +37,8 @@ #include "hw/i2c/smbus.h" #include "hw/usb/hcd-ehci.h" +#include + #define BINARY_DEVICE_TREE_FILE "canyonlands.dtb" #define UBOOT_FILENAME "u-boot-sam460-20100605.bin" /* to extract the official U-Boot bin from the updater: */ @@ -67,6 +69,10 @@ */ #define CPU_FREQ 1150000000 +#define PLB_FREQ 230000000 +#define OPB_FREQ 115000000 +#define EBC_FREQ 115000000 +#define UART_FREQ 11059200 #define SDRAM_NR_BANKS 4 /* FIXME: See u-boot.git 8ac41e, also fix in ppc440_uc.c */ @@ -255,6 +261,7 @@ static int sam460ex_load_device_tree(hwaddr addr, void *fdt; uint32_t tb_freq = CPU_FREQ; uint32_t clock_freq = CPU_FREQ; + int offset; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); if (!filename) { @@ -308,6 +315,27 @@ static int sam460ex_load_device_tree(hwaddr addr, qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency", tb_freq); + /* Remove cpm node if it exists (it is not emulated) */ + offset = fdt_path_offset(fdt, "/cpm"); + if (offset >= 0) { + fdt_nop_node(fdt, offset); + } + + /* set serial port clocks */ + offset = fdt_node_offset_by_compatible(fdt, -1, "ns16550"); + while (offset >= 0) { + fdt_setprop_cell(fdt, offset, "clock-frequency", UART_FREQ); + offset = fdt_node_offset_by_compatible(fdt, offset, "ns16550"); + } + + /* some more clocks */ + qemu_fdt_setprop_cell(fdt, "/plb", "clock-frequency", + PLB_FREQ); + qemu_fdt_setprop_cell(fdt, "/plb/opb", "clock-frequency", + OPB_FREQ); + qemu_fdt_setprop_cell(fdt, "/plb/opb/ebc", "clock-frequency", + EBC_FREQ); + rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr); g_free(fdt); ret = fdt_size; -- cgit v1.1 From a028dd423ee6dfd091a8c63028240832bf10f671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 20 Jun 2018 12:24:13 +0200 Subject: ppc/xics: introduce ICP DeviceRealize and DeviceReset handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes the ICP realize and reset handlers in DeviceRealize and DeviceReset handlers. parent handlers are now called from the inheriting classes which is a cleaner object pattern. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 10 ---------- hw/intc/xics_kvm.c | 34 +++++++++++++++++++++++++++------- hw/intc/xics_pnv.c | 15 +++++++++++++-- 3 files changed, 40 insertions(+), 19 deletions(-) (limited to 'hw') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index e73e623..063491f 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -294,7 +294,6 @@ static const VMStateDescription vmstate_icp_server = { static void icp_reset(void *dev) { ICPState *icp = ICP(dev); - ICPStateClass *icpc = ICP_GET_CLASS(icp); icp->xirr = 0; icp->pending_priority = 0xff; @@ -302,16 +301,11 @@ static void icp_reset(void *dev) /* Make all outputs are deasserted */ qemu_set_irq(icp->output, 0); - - if (icpc->reset) { - icpc->reset(icp); - } } static void icp_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); - ICPStateClass *icpc = ICP_GET_CLASS(dev); PowerPCCPU *cpu; CPUPPCState *env; Object *obj; @@ -351,10 +345,6 @@ static void icp_realize(DeviceState *dev, Error **errp) return; } - if (icpc->realize) { - icpc->realize(icp, errp); - } - qemu_register_reset(icp_reset, dev); vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp); } diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 8dba2f8..f511e50 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -114,22 +114,38 @@ static int icp_set_kvm_state(ICPState *icp, int version_id) return 0; } -static void icp_kvm_reset(ICPState *icp) +static void icp_kvm_reset(DeviceState *dev) { - icp_set_kvm_state(icp, 1); + ICPStateClass *icpc = ICP_GET_CLASS(dev); + + icpc->parent_reset(dev); + + icp_set_kvm_state(ICP(dev), 1); } -static void icp_kvm_realize(ICPState *icp, Error **errp) +static void icp_kvm_realize(DeviceState *dev, Error **errp) { - CPUState *cs = icp->cs; + ICPState *icp = ICP(dev); + ICPStateClass *icpc = ICP_GET_CLASS(icp); + Error *local_err = NULL; + CPUState *cs; KVMEnabledICP *enabled_icp; - unsigned long vcpu_id = kvm_arch_vcpu_id(cs); + unsigned long vcpu_id; int ret; if (kernel_xics_fd == -1) { abort(); } + icpc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + cs = icp->cs; + vcpu_id = kvm_arch_vcpu_id(cs); + /* * If we are reusing a parked vCPU fd corresponding to the CPU * which was hot-removed earlier we don't have to renable @@ -154,12 +170,16 @@ static void icp_kvm_realize(ICPState *icp, Error **errp) static void icp_kvm_class_init(ObjectClass *klass, void *data) { + DeviceClass *dc = DEVICE_CLASS(klass); ICPStateClass *icpc = ICP_CLASS(klass); + device_class_set_parent_realize(dc, icp_kvm_realize, + &icpc->parent_realize); + device_class_set_parent_reset(dc, icp_kvm_reset, + &icpc->parent_reset); + icpc->pre_save = icp_get_kvm_state; icpc->post_load = icp_set_kvm_state; - icpc->realize = icp_kvm_realize; - icpc->reset = icp_kvm_reset; icpc->synchronize_state = icp_synchronize_state; } diff --git a/hw/intc/xics_pnv.c b/hw/intc/xics_pnv.c index c87de21..fa48505 100644 --- a/hw/intc/xics_pnv.c +++ b/hw/intc/xics_pnv.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "qemu/log.h" #include "hw/ppc/xics.h" @@ -158,9 +159,18 @@ static const MemoryRegionOps pnv_icp_ops = { }, }; -static void pnv_icp_realize(ICPState *icp, Error **errp) +static void pnv_icp_realize(DeviceState *dev, Error **errp) { + ICPState *icp = ICP(dev); PnvICPState *pnv_icp = PNV_ICP(icp); + ICPStateClass *icpc = ICP_GET_CLASS(icp); + Error *local_err = NULL; + + icpc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } memory_region_init_io(&pnv_icp->mmio, OBJECT(icp), &pnv_icp_ops, icp, "icp-thread", 0x1000); @@ -171,7 +181,8 @@ static void pnv_icp_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); ICPStateClass *icpc = ICP_CLASS(klass); - icpc->realize = pnv_icp_realize; + device_class_set_parent_realize(dc, pnv_icp_realize, + &icpc->parent_realize); dc->desc = "PowerNV ICP"; } -- cgit v1.1 From 0a647b76dbf29e6a20c328cd8676a1ca49526f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Jun 2018 11:17:14 +0200 Subject: ppc/xics: introduce a parent_realize in ICSStateClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes possible to move the common ICSState code of the realize handlers in the ics-base class. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 37 ++++++++++++++++++++++--------------- hw/intc/xics_kvm.c | 20 +++++++++++++++----- 2 files changed, 37 insertions(+), 20 deletions(-) (limited to 'hw') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 063491f..d6066d5 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -618,30 +618,31 @@ static void ics_simple_initfn(Object *obj) ics->offset = XICS_IRQ_BASE; } -static void ics_simple_realize(ICSState *ics, Error **errp) +static void ics_simple_realize(DeviceState *dev, Error **errp) { - if (!ics->nr_irqs) { - error_setg(errp, "Number of interrupts needs to be greater 0"); + ICSState *ics = ICS_SIMPLE(dev); + ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics); + Error *local_err = NULL; + + icsc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } - ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); + ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); qemu_register_reset(ics_simple_reset, ics); } -static Property ics_simple_properties[] = { - DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0), - DEFINE_PROP_END_OF_LIST(), -}; - static void ics_simple_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ICSStateClass *isc = ICS_BASE_CLASS(klass); - isc->realize = ics_simple_realize; - dc->props = ics_simple_properties; + device_class_set_parent_realize(dc, ics_simple_realize, + &isc->parent_realize); + dc->vmsd = &vmstate_ics_simple; isc->reject = ics_simple_reject; isc->resend = ics_simple_resend; @@ -659,7 +660,6 @@ static const TypeInfo ics_simple_info = { static void ics_base_realize(DeviceState *dev, Error **errp) { - ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); ICSState *ics = ICS_BASE(dev); Object *obj; Error *err = NULL; @@ -672,17 +672,24 @@ static void ics_base_realize(DeviceState *dev, Error **errp) } ics->xics = XICS_FABRIC(obj); - - if (icsc->realize) { - icsc->realize(ics, errp); + if (!ics->nr_irqs) { + error_setg(errp, "Number of interrupts needs to be greater 0"); + return; } + ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); } +static Property ics_base_properties[] = { + DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0), + DEFINE_PROP_END_OF_LIST(), +}; + static void ics_base_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = ics_base_realize; + dc->props = ics_base_properties; } static const TypeInfo ics_base_info = { diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index f511e50..1f27eb4 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -345,13 +345,17 @@ static void ics_kvm_reset(void *dev) ics_set_kvm_state(ics, 1); } -static void ics_kvm_realize(ICSState *ics, Error **errp) +static void ics_kvm_realize(DeviceState *dev, Error **errp) { - if (!ics->nr_irqs) { - error_setg(errp, "Number of interrupts needs to be greater 0"); + ICSState *ics = ICS_KVM(dev); + ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics); + Error *local_err = NULL; + + icsc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } - ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs); qemu_register_reset(ics_kvm_reset, ics); @@ -360,8 +364,14 @@ static void ics_kvm_realize(ICSState *ics, Error **errp) static void ics_kvm_class_init(ObjectClass *klass, void *data) { ICSStateClass *icsc = ICS_BASE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + + /* + * Use device_class_set_parent_realize() when ics-kvm inherits + * directly from ics-base and not from ics-simple anymore. + */ + dc->realize = ics_kvm_realize; - icsc->realize = ics_kvm_realize; icsc->pre_save = ics_get_kvm_state; icsc->post_load = ics_set_kvm_state; icsc->synchronize_state = ics_synchronize_state; -- cgit v1.1 From 815049a01ba187d48166f0144356bc640d4e5803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Jun 2018 11:17:15 +0200 Subject: ppc/xics: move the instance_init handler under the ics-base class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'hw') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index d6066d5..8334077 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -611,13 +611,6 @@ static const VMStateDescription vmstate_ics_simple = { }, }; -static void ics_simple_initfn(Object *obj) -{ - ICSState *ics = ICS_SIMPLE(obj); - - ics->offset = XICS_IRQ_BASE; -} - static void ics_simple_realize(DeviceState *dev, Error **errp) { ICSState *ics = ICS_SIMPLE(dev); @@ -655,7 +648,6 @@ static const TypeInfo ics_simple_info = { .instance_size = sizeof(ICSState), .class_init = ics_simple_class_init, .class_size = sizeof(ICSStateClass), - .instance_init = ics_simple_initfn, }; static void ics_base_realize(DeviceState *dev, Error **errp) @@ -679,6 +671,13 @@ static void ics_base_realize(DeviceState *dev, Error **errp) ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState)); } +static void ics_base_instance_init(Object *obj) +{ + ICSState *ics = ICS_BASE(obj); + + ics->offset = XICS_IRQ_BASE; +} + static Property ics_base_properties[] = { DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0), DEFINE_PROP_END_OF_LIST(), @@ -697,6 +696,7 @@ static const TypeInfo ics_base_info = { .parent = TYPE_DEVICE, .abstract = true, .instance_size = sizeof(ICSState), + .instance_init = ics_base_instance_init, .class_init = ics_base_class_init, .class_size = sizeof(ICSStateClass), }; -- cgit v1.1 From eeefd43b3cf342d1696128462a16e092995ff1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Jun 2018 11:17:16 +0200 Subject: ppx/xics: introduce a parent_reset in ICSStateClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just like for the realize handlers, this makes possible to move the common ICSState code of the reset handlers in the ics-base class. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 45 ++++++++++++++++++++++++++++++--------------- hw/intc/xics_kvm.c | 26 ++++++++++---------------- 2 files changed, 40 insertions(+), 31 deletions(-) (limited to 'hw') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 8334077..8cfe223 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -537,23 +537,16 @@ static void ics_simple_eoi(ICSState *ics, uint32_t nr) } } -static void ics_simple_reset(void *dev) +static void ics_simple_reset(DeviceState *dev) { - ICSState *ics = ICS_SIMPLE(dev); - int i; - uint8_t flags[ics->nr_irqs]; + ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); - for (i = 0; i < ics->nr_irqs; i++) { - flags[i] = ics->irqs[i].flags; - } - - memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs); + icsc->parent_reset(dev); +} - for (i = 0; i < ics->nr_irqs; i++) { - ics->irqs[i].priority = 0xff; - ics->irqs[i].saved_priority = 0xff; - ics->irqs[i].flags = flags[i]; - } +static void ics_simple_reset_handler(void *dev) +{ + ics_simple_reset(dev); } static int ics_simple_dispatch_pre_save(void *opaque) @@ -625,7 +618,7 @@ static void ics_simple_realize(DeviceState *dev, Error **errp) ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs); - qemu_register_reset(ics_simple_reset, ics); + qemu_register_reset(ics_simple_reset_handler, ics); } static void ics_simple_class_init(ObjectClass *klass, void *data) @@ -635,6 +628,8 @@ static void ics_simple_class_init(ObjectClass *klass, void *data) device_class_set_parent_realize(dc, ics_simple_realize, &isc->parent_realize); + device_class_set_parent_reset(dc, ics_simple_reset, + &isc->parent_reset); dc->vmsd = &vmstate_ics_simple; isc->reject = ics_simple_reject; @@ -650,6 +645,25 @@ static const TypeInfo ics_simple_info = { .class_size = sizeof(ICSStateClass), }; +static void ics_base_reset(DeviceState *dev) +{ + ICSState *ics = ICS_BASE(dev); + int i; + uint8_t flags[ics->nr_irqs]; + + for (i = 0; i < ics->nr_irqs; i++) { + flags[i] = ics->irqs[i].flags; + } + + memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs); + + for (i = 0; i < ics->nr_irqs; i++) { + ics->irqs[i].priority = 0xff; + ics->irqs[i].saved_priority = 0xff; + ics->irqs[i].flags = flags[i]; + } +} + static void ics_base_realize(DeviceState *dev, Error **errp) { ICSState *ics = ICS_BASE(dev); @@ -689,6 +703,7 @@ static void ics_base_class_init(ObjectClass *klass, void *data) dc->realize = ics_base_realize; dc->props = ics_base_properties; + dc->reset = ics_base_reset; } static const TypeInfo ics_base_info = { diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 1f27eb4..b314eb7 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -324,25 +324,18 @@ static void ics_kvm_set_irq(void *opaque, int srcno, int val) } } -static void ics_kvm_reset(void *dev) +static void ics_kvm_reset(DeviceState *dev) { - ICSState *ics = ICS_SIMPLE(dev); - int i; - uint8_t flags[ics->nr_irqs]; - - for (i = 0; i < ics->nr_irqs; i++) { - flags[i] = ics->irqs[i].flags; - } + ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); - memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs); + icsc->parent_reset(dev); - for (i = 0; i < ics->nr_irqs; i++) { - ics->irqs[i].priority = 0xff; - ics->irqs[i].saved_priority = 0xff; - ics->irqs[i].flags = flags[i]; - } + ics_set_kvm_state(ICS_KVM(dev), 1); +} - ics_set_kvm_state(ics, 1); +static void ics_kvm_reset_handler(void *dev) +{ + ics_kvm_reset(dev); } static void ics_kvm_realize(DeviceState *dev, Error **errp) @@ -358,7 +351,7 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp) } ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs); - qemu_register_reset(ics_kvm_reset, ics); + qemu_register_reset(ics_kvm_reset_handler, ics); } static void ics_kvm_class_init(ObjectClass *klass, void *data) @@ -371,6 +364,7 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data) * directly from ics-base and not from ics-simple anymore. */ dc->realize = ics_kvm_realize; + dc->reset = ics_kvm_reset; icsc->pre_save = ics_get_kvm_state; icsc->post_load = ics_set_kvm_state; -- cgit v1.1 From c8b1846f238ea5702ccbc0c3e2760c8fee875808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Jun 2018 11:17:17 +0200 Subject: ppc/xics: move the vmstate structures under the ics-base class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 112 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) (limited to 'hw') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 8cfe223..b9f1a3c 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -549,61 +549,6 @@ static void ics_simple_reset_handler(void *dev) ics_simple_reset(dev); } -static int ics_simple_dispatch_pre_save(void *opaque) -{ - ICSState *ics = opaque; - ICSStateClass *info = ICS_BASE_GET_CLASS(ics); - - if (info->pre_save) { - info->pre_save(ics); - } - - return 0; -} - -static int ics_simple_dispatch_post_load(void *opaque, int version_id) -{ - ICSState *ics = opaque; - ICSStateClass *info = ICS_BASE_GET_CLASS(ics); - - if (info->post_load) { - return info->post_load(ics, version_id); - } - - return 0; -} - -static const VMStateDescription vmstate_ics_simple_irq = { - .name = "ics/irq", - .version_id = 2, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32(server, ICSIRQState), - VMSTATE_UINT8(priority, ICSIRQState), - VMSTATE_UINT8(saved_priority, ICSIRQState), - VMSTATE_UINT8(status, ICSIRQState), - VMSTATE_UINT8(flags, ICSIRQState), - VMSTATE_END_OF_LIST() - }, -}; - -static const VMStateDescription vmstate_ics_simple = { - .name = "ics", - .version_id = 1, - .minimum_version_id = 1, - .pre_save = ics_simple_dispatch_pre_save, - .post_load = ics_simple_dispatch_post_load, - .fields = (VMStateField[]) { - /* Sanity check */ - VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL), - - VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs, - vmstate_ics_simple_irq, - ICSIRQState), - VMSTATE_END_OF_LIST() - }, -}; - static void ics_simple_realize(DeviceState *dev, Error **errp) { ICSState *ics = ICS_SIMPLE(dev); @@ -631,7 +576,6 @@ static void ics_simple_class_init(ObjectClass *klass, void *data) device_class_set_parent_reset(dc, ics_simple_reset, &isc->parent_reset); - dc->vmsd = &vmstate_ics_simple; isc->reject = ics_simple_reject; isc->resend = ics_simple_resend; isc->eoi = ics_simple_eoi; @@ -692,6 +636,61 @@ static void ics_base_instance_init(Object *obj) ics->offset = XICS_IRQ_BASE; } +static int ics_base_dispatch_pre_save(void *opaque) +{ + ICSState *ics = opaque; + ICSStateClass *info = ICS_BASE_GET_CLASS(ics); + + if (info->pre_save) { + info->pre_save(ics); + } + + return 0; +} + +static int ics_base_dispatch_post_load(void *opaque, int version_id) +{ + ICSState *ics = opaque; + ICSStateClass *info = ICS_BASE_GET_CLASS(ics); + + if (info->post_load) { + return info->post_load(ics, version_id); + } + + return 0; +} + +static const VMStateDescription vmstate_ics_base_irq = { + .name = "ics/irq", + .version_id = 2, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(server, ICSIRQState), + VMSTATE_UINT8(priority, ICSIRQState), + VMSTATE_UINT8(saved_priority, ICSIRQState), + VMSTATE_UINT8(status, ICSIRQState), + VMSTATE_UINT8(flags, ICSIRQState), + VMSTATE_END_OF_LIST() + }, +}; + +static const VMStateDescription vmstate_ics_base = { + .name = "ics", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = ics_base_dispatch_pre_save, + .post_load = ics_base_dispatch_post_load, + .fields = (VMStateField[]) { + /* Sanity check */ + VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL), + + VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs, + vmstate_ics_base_irq, + ICSIRQState), + VMSTATE_END_OF_LIST() + }, +}; + static Property ics_base_properties[] = { DEFINE_PROP_UINT32("nr-irqs", ICSState, nr_irqs, 0), DEFINE_PROP_END_OF_LIST(), @@ -704,6 +703,7 @@ static void ics_base_class_init(ObjectClass *klass, void *data) dc->realize = ics_base_realize; dc->props = ics_base_properties; dc->reset = ics_base_reset; + dc->vmsd = &vmstate_ics_base; } static const TypeInfo ics_base_info = { -- cgit v1.1 From abe82ebb2005eef846fd62652b0107d268c8e06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 25 Jun 2018 11:17:18 +0200 Subject: ppc/xics: rework the ICS classes inheritance tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the previous changes, we can now let the ICS_KVM class inherit directly from ICS_BASE class and not from the intermediate ICS_SIMPLE. It makes the class hierarchy much cleaner. What is left in the top classes is the low level interface to access the KVM XICS device in ICS_KVM and the XICS emulating handlers in ICS_SIMPLE. This should not break migration compatibility. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics_kvm.c | 12 +++++------- hw/ppc/spapr.c | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'hw') diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index b314eb7..30c3769 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -359,12 +359,10 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data) ICSStateClass *icsc = ICS_BASE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - /* - * Use device_class_set_parent_realize() when ics-kvm inherits - * directly from ics-base and not from ics-simple anymore. - */ - dc->realize = ics_kvm_realize; - dc->reset = ics_kvm_reset; + device_class_set_parent_realize(dc, ics_kvm_realize, + &icsc->parent_realize); + device_class_set_parent_reset(dc, ics_kvm_reset, + &icsc->parent_reset); icsc->pre_save = ics_get_kvm_state; icsc->post_load = ics_set_kvm_state; @@ -373,7 +371,7 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data) static const TypeInfo ics_kvm_info = { .name = TYPE_ICS_KVM, - .parent = TYPE_ICS_SIMPLE, + .parent = TYPE_ICS_BASE, .instance_size = sizeof(ICSState), .class_init = ics_kvm_class_init, }; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b32b971..b2baec0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -137,7 +137,7 @@ static ICSState *spapr_ics_create(sPAPRMachineState *spapr, goto error; } - return ICS_SIMPLE(obj); + return ICS_BASE(obj); error: error_propagate(errp, local_err); -- cgit v1.1 From 56f68439213f4fc002c602cee6f4e6863609cb88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 26 Jun 2018 16:22:14 +0200 Subject: ppc/pnv: fix pnv_core_realize() error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d35aefa9ae15 ("ppc/pnv: introduce a new intc_create() operation to the chip model") changed the object link in the pnv_core_realize() routine but a return was forgotten in case of error, which can lead to more problems afterwards (segv) Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/pnv_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index a9f129f..9750464 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -150,6 +150,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) if (!chip) { error_propagate(errp, local_err); error_prepend(errp, "required link 'chip' not found: "); + return; } pc->threads = g_new(PowerPCCPU *, cc->nr_threads); -- cgit v1.1 From 3c47beb8defb8cab04ea2e19bc3fd8c65bf9af7d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 2 Jul 2018 11:59:35 +1000 Subject: hw/ppc: Give sam46ex its own config option At present the Sam460ex board is activated by the general CONFIG_PPC4XX option. However that includes the board for both ppc-softmmu and (deprecated) ppcemb-softmmu builds. As Sam460ex is developed, that would require adding more things into ppcemb-softmmu, which we don't want to do. Signed-off-by: David Gibson --- hw/ppc/Makefile.objs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index 86d82a6..bcab632 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -14,7 +14,8 @@ obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o # PowerPC 4xx boards obj-y += ppc4xx_devs.o ppc405_uc.o obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o -obj-$(CONFIG_PPC4XX) += ppc440_bamboo.o ppc440_pcix.o ppc440_uc.o sam460ex.o +obj-$(CONFIG_PPC4XX) += ppc440_bamboo.o ppc440_pcix.o ppc440_uc.o +obj-$(CONFIG_SAM460EX) += sam460ex.o # PReP obj-$(CONFIG_PREP) += prep.o obj-$(CONFIG_PREP) += prep_systemio.o -- cgit v1.1 From afb6e20429d5853e79e9a8af4a68b51d14b0c0c1 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 29 Jun 2018 00:38:33 +0200 Subject: ppc4xx_i2c: Rewrite to model hardware more closely MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite to make it closer to how real device works so that guest OS drivers can access I2C devices. Previously this was only a hack to allow U-Boot to get past accessing SPD EEPROMs but to support other I2C devices and allow guests to access them we need to model real device more properly. Signed-off-by: BALATON Zoltan Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/i2c/ppc4xx_i2c.c | 299 +++++++++++++++++++++++++++------------------------- 1 file changed, 157 insertions(+), 142 deletions(-) (limited to 'hw') diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index fca80d6..d6dfafa 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -34,16 +34,50 @@ #define PPC4xx_I2C_MEM_SIZE 18 +enum { + IIC_MDBUF = 0, + /* IIC_SDBUF = 2, */ + IIC_LMADR = 4, + IIC_HMADR, + IIC_CNTL, + IIC_MDCNTL, + IIC_STS, + IIC_EXTSTS, + IIC_LSADR, + IIC_HSADR, + IIC_CLKDIV, + IIC_INTRMSK, + IIC_XFRCNT, + IIC_XTCNTLSS, + IIC_DIRECTCNTL + /* IIC_INTR */ +}; + #define IIC_CNTL_PT (1 << 0) #define IIC_CNTL_READ (1 << 1) #define IIC_CNTL_CHT (1 << 2) #define IIC_CNTL_RPST (1 << 3) +#define IIC_CNTL_AMD (1 << 6) +#define IIC_CNTL_HMT (1 << 7) + +#define IIC_MDCNTL_EINT (1 << 2) +#define IIC_MDCNTL_ESM (1 << 3) +#define IIC_MDCNTL_FMDB (1 << 6) #define IIC_STS_PT (1 << 0) +#define IIC_STS_IRQA (1 << 1) #define IIC_STS_ERR (1 << 2) +#define IIC_STS_MDBF (1 << 4) #define IIC_STS_MDBS (1 << 5) #define IIC_EXTSTS_XFRA (1 << 0) +#define IIC_EXTSTS_BCS_FREE (4 << 4) +#define IIC_EXTSTS_BCS_BUSY (5 << 4) + +#define IIC_INTRMSK_EIMTC (1 << 0) +#define IIC_INTRMSK_EITA (1 << 1) +#define IIC_INTRMSK_EIIC (1 << 2) +#define IIC_INTRMSK_EIHE (1 << 3) #define IIC_XTCNTLSS_SRST (1 << 0) @@ -56,130 +90,83 @@ static void ppc4xx_i2c_reset(DeviceState *s) { PPC4xxI2CState *i2c = PPC4xx_I2C(s); - /* FIXME: Should also reset bus? - *if (s->address != ADDR_RESET) { - * i2c_end_transfer(s->bus); - *} - */ - - i2c->mdata = 0; - i2c->lmadr = 0; - i2c->hmadr = 0; + i2c->mdidx = -1; + memset(i2c->mdata, 0, ARRAY_SIZE(i2c->mdata)); + /* [hl][ms]addr are not affected by reset */ i2c->cntl = 0; i2c->mdcntl = 0; i2c->sts = 0; - i2c->extsts = 0x8f; - i2c->lsadr = 0; - i2c->hsadr = 0; + i2c->extsts = IIC_EXTSTS_BCS_FREE; i2c->clkdiv = 0; i2c->intrmsk = 0; i2c->xfrcnt = 0; i2c->xtcntlss = 0; - i2c->directcntl = 0xf; -} - -static inline bool ppc4xx_i2c_is_master(PPC4xxI2CState *i2c) -{ - return true; + i2c->directcntl = 0xf; /* all non-reserved bits set */ } static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) { PPC4xxI2CState *i2c = PPC4xx_I2C(opaque); uint64_t ret; + int i; switch (addr) { - case 0: - ret = i2c->mdata; - if (ppc4xx_i2c_is_master(i2c)) { + case IIC_MDBUF: + if (i2c->mdidx < 0) { ret = 0xff; - - if (!(i2c->sts & IIC_STS_MDBS)) { - qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read " - "without starting transfer\n", - TYPE_PPC4xx_I2C, __func__); - } else { - int pending = (i2c->cntl >> 4) & 3; - - /* get the next byte */ - int byte = i2c_recv(i2c->bus); - - if (byte < 0) { - qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed " - "for device 0x%02x\n", TYPE_PPC4xx_I2C, - __func__, i2c->lmadr); - ret = 0xff; - } else { - ret = byte; - /* Raise interrupt if enabled */ - /*ppc4xx_i2c_raise_interrupt(i2c)*/; - } - - if (!pending) { - i2c->sts &= ~IIC_STS_MDBS; - /*i2c_end_transfer(i2c->bus);*/ - /*} else if (i2c->cntl & (IIC_CNTL_RPST | IIC_CNTL_CHT)) {*/ - } else if (pending) { - /* current smbus implementation doesn't like - multibyte xfer repeated start */ - i2c_end_transfer(i2c->bus); - if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) { - /* if non zero is returned, the adress is not valid */ - i2c->sts &= ~IIC_STS_PT; - i2c->sts |= IIC_STS_ERR; - i2c->extsts |= IIC_EXTSTS_XFRA; - } else { - /*i2c->sts |= IIC_STS_PT;*/ - i2c->sts |= IIC_STS_MDBS; - i2c->sts &= ~IIC_STS_ERR; - i2c->extsts = 0; - } - } - pending--; - i2c->cntl = (i2c->cntl & 0xcf) | (pending << 4); - } - } else { - qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n", - TYPE_PPC4xx_I2C, __func__); + break; + } + ret = i2c->mdata[0]; + if (i2c->mdidx == 3) { + i2c->sts &= ~IIC_STS_MDBF; + } else if (i2c->mdidx == 0) { + i2c->sts &= ~IIC_STS_MDBS; + } + for (i = 0; i < i2c->mdidx; i++) { + i2c->mdata[i] = i2c->mdata[i + 1]; + } + if (i2c->mdidx >= 0) { + i2c->mdidx--; } break; - case 4: + case IIC_LMADR: ret = i2c->lmadr; break; - case 5: + case IIC_HMADR: ret = i2c->hmadr; break; - case 6: + case IIC_CNTL: ret = i2c->cntl; break; - case 7: + case IIC_MDCNTL: ret = i2c->mdcntl; break; - case 8: + case IIC_STS: ret = i2c->sts; break; - case 9: - ret = i2c->extsts; + case IIC_EXTSTS: + ret = i2c_bus_busy(i2c->bus) ? + IIC_EXTSTS_BCS_BUSY : IIC_EXTSTS_BCS_FREE; break; - case 10: + case IIC_LSADR: ret = i2c->lsadr; break; - case 11: + case IIC_HSADR: ret = i2c->hsadr; break; - case 12: + case IIC_CLKDIV: ret = i2c->clkdiv; break; - case 13: + case IIC_INTRMSK: ret = i2c->intrmsk; break; - case 14: + case IIC_XFRCNT: ret = i2c->xfrcnt; break; - case 15: + case IIC_XTCNTLSS: ret = i2c->xtcntlss; break; - case 16: + case IIC_DIRECTCNTL: ret = i2c->directcntl; break; default: @@ -202,99 +189,127 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, PPC4xxI2CState *i2c = opaque; switch (addr) { - case 0: - i2c->mdata = value; - if (!i2c_bus_busy(i2c->bus)) { - /* assume we start a write transfer */ - if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 0)) { - /* if non zero is returned, the adress is not valid */ - i2c->sts &= ~IIC_STS_PT; - i2c->sts |= IIC_STS_ERR; - i2c->extsts |= IIC_EXTSTS_XFRA; - } else { - i2c->sts |= IIC_STS_PT; - i2c->sts &= ~IIC_STS_ERR; - i2c->extsts = 0; - } + case IIC_MDBUF: + if (i2c->mdidx >= 3) { + break; } - if (i2c_bus_busy(i2c->bus)) { - if (i2c_send(i2c->bus, i2c->mdata)) { - /* if the target return non zero then end the transfer */ - i2c->sts &= ~IIC_STS_PT; - i2c->sts |= IIC_STS_ERR; - i2c->extsts |= IIC_EXTSTS_XFRA; - i2c_end_transfer(i2c->bus); - } + i2c->mdata[++i2c->mdidx] = value; + if (i2c->mdidx == 3) { + i2c->sts |= IIC_STS_MDBF; + } else if (i2c->mdidx == 0) { + i2c->sts |= IIC_STS_MDBS; } break; - case 4: + case IIC_LMADR: i2c->lmadr = value; - if (i2c_bus_busy(i2c->bus)) { - i2c_end_transfer(i2c->bus); - } break; - case 5: + case IIC_HMADR: i2c->hmadr = value; break; - case 6: - i2c->cntl = value; - if (i2c->cntl & IIC_CNTL_PT) { - if (i2c->cntl & IIC_CNTL_READ) { - if (i2c_bus_busy(i2c->bus)) { - /* end previous transfer */ - i2c->sts &= ~IIC_STS_PT; - i2c_end_transfer(i2c->bus); + case IIC_CNTL: + i2c->cntl = value & ~IIC_CNTL_PT; + if (value & IIC_CNTL_AMD) { + qemu_log_mask(LOG_UNIMP, "%s: only 7 bit addresses supported\n", + __func__); + } + if (value & IIC_CNTL_HMT && i2c_bus_busy(i2c->bus)) { + i2c_end_transfer(i2c->bus); + if (i2c->mdcntl & IIC_MDCNTL_EINT && + i2c->intrmsk & IIC_INTRMSK_EIHE) { + i2c->sts |= IIC_STS_IRQA; + qemu_irq_raise(i2c->irq); + } + } else if (value & IIC_CNTL_PT) { + int recv = (value & IIC_CNTL_READ) >> 1; + int tct = value >> 4 & 3; + int i; + + if (recv && (i2c->lmadr >> 1) >= 0x50 && (i2c->lmadr >> 1) < 0x58) { + /* smbus emulation does not like multi byte reads w/o restart */ + value |= IIC_CNTL_RPST; + } + + for (i = 0; i <= tct; i++) { + if (!i2c_bus_busy(i2c->bus)) { + i2c->extsts = IIC_EXTSTS_BCS_FREE; + if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, recv)) { + i2c->sts |= IIC_STS_ERR; + i2c->extsts |= IIC_EXTSTS_XFRA; + break; + } else { + i2c->sts &= ~IIC_STS_ERR; + } } - if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) { - /* if non zero is returned, the adress is not valid */ - i2c->sts &= ~IIC_STS_PT; + if (!(i2c->sts & IIC_STS_ERR) && + i2c_send_recv(i2c->bus, &i2c->mdata[i], !recv)) { i2c->sts |= IIC_STS_ERR; i2c->extsts |= IIC_EXTSTS_XFRA; - } else { - /*i2c->sts |= IIC_STS_PT;*/ - i2c->sts |= IIC_STS_MDBS; - i2c->sts &= ~IIC_STS_ERR; - i2c->extsts = 0; + break; + } + if (value & IIC_CNTL_RPST || !(value & IIC_CNTL_CHT)) { + i2c_end_transfer(i2c->bus); } - } else { - /* we actually already did the write transfer... */ - i2c->sts &= ~IIC_STS_PT; + } + i2c->xfrcnt = i; + i2c->mdidx = i - 1; + if (recv && i2c->mdidx >= 0) { + i2c->sts |= IIC_STS_MDBS; + } + if (recv && i2c->mdidx == 3) { + i2c->sts |= IIC_STS_MDBF; + } + if (i && i2c->mdcntl & IIC_MDCNTL_EINT && + i2c->intrmsk & IIC_INTRMSK_EIMTC) { + i2c->sts |= IIC_STS_IRQA; + qemu_irq_raise(i2c->irq); } } break; - case 7: - i2c->mdcntl = value & 0xdf; + case IIC_MDCNTL: + i2c->mdcntl = value & 0x3d; + if (value & IIC_MDCNTL_ESM) { + qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n", + __func__); + } + if (value & IIC_MDCNTL_FMDB) { + i2c->mdidx = -1; + memset(i2c->mdata, 0, ARRAY_SIZE(i2c->mdata)); + i2c->sts &= ~(IIC_STS_MDBF | IIC_STS_MDBS); + } break; - case 8: - i2c->sts &= ~(value & 0xa); + case IIC_STS: + i2c->sts &= ~(value & 0x0a); + if (value & IIC_STS_IRQA && i2c->mdcntl & IIC_MDCNTL_EINT) { + qemu_irq_lower(i2c->irq); + } break; - case 9: + case IIC_EXTSTS: i2c->extsts &= ~(value & 0x8f); break; - case 10: + case IIC_LSADR: i2c->lsadr = value; break; - case 11: + case IIC_HSADR: i2c->hsadr = value; break; - case 12: + case IIC_CLKDIV: i2c->clkdiv = value; break; - case 13: + case IIC_INTRMSK: i2c->intrmsk = value; break; - case 14: + case IIC_XFRCNT: i2c->xfrcnt = value & 0x77; break; - case 15: + case IIC_XTCNTLSS: + i2c->xtcntlss &= ~(value & 0xf0); if (value & IIC_XTCNTLSS_SRST) { /* Is it actually a full reset? U-Boot sets some regs before */ ppc4xx_i2c_reset(DEVICE(i2c)); break; } - i2c->xtcntlss = value; break; - case 16: + case IIC_DIRECTCNTL: i2c->directcntl = value & (IIC_DIRECTCNTL_SDAC & IIC_DIRECTCNTL_SCLC); i2c->directcntl |= (value & IIC_DIRECTCNTL_SCLC ? 1 : 0); bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SCL, -- cgit v1.1 From c6f2594c4b19db903cd76e89578cf501056b744d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 29 Jun 2018 00:38:33 +0200 Subject: hw/timer: Add basic M41T80 emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Basic emulation of the M41T80 serial (I2C) RTC chip. Only getting time of day is implemented. Setting time and RTC alarm are not supported. Signed-off-by: BALATON Zoltan Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/timer/Makefile.objs | 1 + hw/timer/m41t80.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 hw/timer/m41t80.c (limited to 'hw') diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 8b27a4b..e16b2b9 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -6,6 +6,7 @@ common-obj-$(CONFIG_CADENCE) += cadence_ttc.o common-obj-$(CONFIG_DS1338) += ds1338.o common-obj-$(CONFIG_HPET) += hpet.o common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o +common-obj-$(CONFIG_M41T80) += m41t80.o common-obj-$(CONFIG_M48T59) += m48t59.o ifeq ($(CONFIG_ISA_BUS),y) common-obj-$(CONFIG_M48T59) += m48t59-isa.o diff --git a/hw/timer/m41t80.c b/hw/timer/m41t80.c new file mode 100644 index 0000000..734d7d9 --- /dev/null +++ b/hw/timer/m41t80.c @@ -0,0 +1,117 @@ +/* + * M41T80 serial rtc emulation + * + * Copyright (c) 2018 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/timer.h" +#include "qemu/bcd.h" +#include "hw/i2c/i2c.h" + +#define TYPE_M41T80 "m41t80" +#define M41T80(obj) OBJECT_CHECK(M41t80State, (obj), TYPE_M41T80) + +typedef struct M41t80State { + I2CSlave parent_obj; + int8_t addr; +} M41t80State; + +static void m41t80_realize(DeviceState *dev, Error **errp) +{ + M41t80State *s = M41T80(dev); + + s->addr = -1; +} + +static int m41t80_send(I2CSlave *i2c, uint8_t data) +{ + M41t80State *s = M41T80(i2c); + + if (s->addr < 0) { + s->addr = data; + } else { + s->addr++; + } + return 0; +} + +static int m41t80_recv(I2CSlave *i2c) +{ + M41t80State *s = M41T80(i2c); + struct tm now; + qemu_timeval tv; + + if (s->addr < 0) { + s->addr = 0; + } + if (s->addr >= 1 && s->addr <= 7) { + qemu_get_timedate(&now, -1); + } + switch (s->addr++) { + case 0: + qemu_gettimeofday(&tv); + return to_bcd(tv.tv_usec / 10000); + case 1: + return to_bcd(now.tm_sec); + case 2: + return to_bcd(now.tm_min); + case 3: + return to_bcd(now.tm_hour); + case 4: + return to_bcd(now.tm_wday); + case 5: + return to_bcd(now.tm_mday); + case 6: + return to_bcd(now.tm_mon + 1); + case 7: + return to_bcd(now.tm_year % 100); + case 8 ... 19: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented register: %d\n", + __func__, s->addr - 1); + return 0; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid register: %d\n", + __func__, s->addr - 1); + return 0; + } +} + +static int m41t80_event(I2CSlave *i2c, enum i2c_event event) +{ + M41t80State *s = M41T80(i2c); + + if (event == I2C_START_SEND) { + s->addr = -1; + } + return 0; +} + +static void m41t80_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); + + dc->realize = m41t80_realize; + sc->send = m41t80_send; + sc->recv = m41t80_recv; + sc->event = m41t80_event; +} + +static const TypeInfo m41t80_info = { + .name = TYPE_M41T80, + .parent = TYPE_I2C_SLAVE, + .instance_size = sizeof(M41t80State), + .class_init = m41t80_class_init, +}; + +static void m41t80_register_types(void) +{ + type_register_static(&m41t80_info); +} + +type_init(m41t80_register_types) -- cgit v1.1 From d2179f70d396cf796151ebf56cc177d7c3e53749 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 29 Jun 2018 00:38:33 +0200 Subject: sam460ex: Add RTC device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Sam460ex has an M41T80 serial RTC chip on I2C bus 0 at address 0x68. Signed-off-by: BALATON Zoltan Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/sam460ex.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw') diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 33ea518..a03d12d1 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -485,6 +485,7 @@ static void sam460ex_init(MachineState *machine) object_property_set_bool(OBJECT(dev), true, "realized", NULL); smbus_eeprom_init(i2c[0]->bus, 8, smbus_eeprom_buf, smbus_eeprom_size); g_free(smbus_eeprom_buf); + i2c_create_slave(i2c[0]->bus, "m41t80", 0x68); dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600800, uic[0][3]); i2c[1] = PPC4xx_I2C(dev); -- cgit v1.1 From 3c409c1927efde2fc7ac5f6cd5d79d0784be3b5d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 29 Jun 2018 14:04:33 +0200 Subject: ppc440_uc: Basic emulation of PPC440 DMA controller PPC440 SoCs such as the AMCC 460EX have a DMA controller which is used by AmigaOS on the sam460ex. Implement the parts used by AmigaOS so it can get further booting on the sam460ex machine. Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/ppc/ppc440.h | 1 + hw/ppc/ppc440_uc.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/ppc/sam460ex.c | 3 + 3 files changed, 226 insertions(+) (limited to 'hw') diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h index ad27db1..7cef936 100644 --- a/hw/ppc/ppc440.h +++ b/hw/ppc/ppc440.h @@ -21,6 +21,7 @@ void ppc440_sdram_init(CPUPPCState *env, int nbanks, hwaddr *ram_bases, hwaddr *ram_sizes, int do_init); void ppc4xx_ahb_init(CPUPPCState *env); +void ppc4xx_dma_init(CPUPPCState *env, int dcr_base); void ppc460ex_pcie_init(CPUPPCState *env); #endif /* PPC440_H */ diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 123f4ac..32802d7 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -13,6 +13,7 @@ #include "qemu/cutils.h" #include "qemu/error-report.h" #include "qapi/error.h" +#include "qemu/log.h" #include "cpu.h" #include "hw/hw.h" #include "exec/address-spaces.h" @@ -803,6 +804,227 @@ void ppc4xx_ahb_init(CPUPPCState *env) } /*****************************************************************************/ +/* DMA controller */ + +#define DMA0_CR_CE (1 << 31) +#define DMA0_CR_PW (1 << 26 | 1 << 25) +#define DMA0_CR_DAI (1 << 24) +#define DMA0_CR_SAI (1 << 23) +#define DMA0_CR_DEC (1 << 2) + +enum { + DMA0_CR = 0x00, + DMA0_CT, + DMA0_SAH, + DMA0_SAL, + DMA0_DAH, + DMA0_DAL, + DMA0_SGH, + DMA0_SGL, + + DMA0_SR = 0x20, + DMA0_SGC = 0x23, + DMA0_SLP = 0x25, + DMA0_POL = 0x26, +}; + +typedef struct { + uint32_t cr; + uint32_t ct; + uint64_t sa; + uint64_t da; + uint64_t sg; +} PPC4xxDmaChnl; + +typedef struct { + int base; + PPC4xxDmaChnl ch[4]; + uint32_t sr; +} PPC4xxDmaState; + +static uint32_t dcr_read_dma(void *opaque, int dcrn) +{ + PPC4xxDmaState *dma = opaque; + uint32_t val = 0; + int addr = dcrn - dma->base; + int chnl = addr / 8; + + switch (addr) { + case 0x00 ... 0x1f: + switch (addr % 8) { + case DMA0_CR: + val = dma->ch[chnl].cr; + break; + case DMA0_CT: + val = dma->ch[chnl].ct; + break; + case DMA0_SAH: + val = dma->ch[chnl].sa >> 32; + break; + case DMA0_SAL: + val = dma->ch[chnl].sa; + break; + case DMA0_DAH: + val = dma->ch[chnl].da >> 32; + break; + case DMA0_DAL: + val = dma->ch[chnl].da; + break; + case DMA0_SGH: + val = dma->ch[chnl].sg >> 32; + break; + case DMA0_SGL: + val = dma->ch[chnl].sg; + break; + } + break; + case DMA0_SR: + val = dma->sr; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n", + __func__, dcrn, chnl, addr); + } + + return val; +} + +static void dcr_write_dma(void *opaque, int dcrn, uint32_t val) +{ + PPC4xxDmaState *dma = opaque; + int addr = dcrn - dma->base; + int chnl = addr / 8; + + switch (addr) { + case 0x00 ... 0x1f: + switch (addr % 8) { + case DMA0_CR: + dma->ch[chnl].cr = val; + if (val & DMA0_CR_CE) { + int count = dma->ch[chnl].ct & 0xffff; + + if (count) { + int width, i, sidx, didx; + uint8_t *rptr, *wptr; + hwaddr rlen, wlen; + + sidx = didx = 0; + width = 1 << ((val & DMA0_CR_PW) >> 25); + rptr = cpu_physical_memory_map(dma->ch[chnl].sa, &rlen, 0); + wptr = cpu_physical_memory_map(dma->ch[chnl].da, &wlen, 1); + if (rptr && wptr) { + if (!(val & DMA0_CR_DEC) && + val & DMA0_CR_SAI && val & DMA0_CR_DAI) { + /* optimise common case */ + memmove(wptr, rptr, count * width); + sidx = didx = count * width; + } else { + /* do it the slow way */ + for (sidx = didx = i = 0; i < count; i++) { + uint64_t v = ldn_le_p(rptr + sidx, width); + stn_le_p(wptr + didx, width, v); + if (val & DMA0_CR_SAI) { + sidx += width; + } + if (val & DMA0_CR_DAI) { + didx += width; + } + } + } + } + if (wptr) { + cpu_physical_memory_unmap(wptr, wlen, 1, didx); + } + if (wptr) { + cpu_physical_memory_unmap(rptr, rlen, 0, sidx); + } + } + } + break; + case DMA0_CT: + dma->ch[chnl].ct = val; + break; + case DMA0_SAH: + dma->ch[chnl].sa &= 0xffffffffULL; + dma->ch[chnl].sa |= (uint64_t)val << 32; + break; + case DMA0_SAL: + dma->ch[chnl].sa &= 0xffffffff00000000ULL; + dma->ch[chnl].sa |= val; + break; + case DMA0_DAH: + dma->ch[chnl].da &= 0xffffffffULL; + dma->ch[chnl].da |= (uint64_t)val << 32; + break; + case DMA0_DAL: + dma->ch[chnl].da &= 0xffffffff00000000ULL; + dma->ch[chnl].da |= val; + break; + case DMA0_SGH: + dma->ch[chnl].sg &= 0xffffffffULL; + dma->ch[chnl].sg |= (uint64_t)val << 32; + break; + case DMA0_SGL: + dma->ch[chnl].sg &= 0xffffffff00000000ULL; + dma->ch[chnl].sg |= val; + break; + } + break; + case DMA0_SR: + dma->sr &= ~val; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimplemented register %x (%d, %x)\n", + __func__, dcrn, chnl, addr); + } +} + +static void ppc4xx_dma_reset(void *opaque) +{ + PPC4xxDmaState *dma = opaque; + int dma_base = dma->base; + + memset(dma, 0, sizeof(*dma)); + dma->base = dma_base; +} + +void ppc4xx_dma_init(CPUPPCState *env, int dcr_base) +{ + PPC4xxDmaState *dma; + int i; + + dma = g_malloc0(sizeof(*dma)); + dma->base = dcr_base; + qemu_register_reset(&ppc4xx_dma_reset, dma); + for (i = 0; i < 4; i++) { + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CR, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_CT, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAH, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SAL, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAH, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_DAL, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGH, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + i * 8 + DMA0_SGL, + dma, &dcr_read_dma, &dcr_write_dma); + } + ppc_dcr_register(env, dcr_base + DMA0_SR, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + DMA0_SGC, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + DMA0_SLP, + dma, &dcr_read_dma, &dcr_write_dma); + ppc_dcr_register(env, dcr_base + DMA0_POL, + dma, &dcr_read_dma, &dcr_write_dma); +} + +/*****************************************************************************/ /* PCI Express controller */ /* FIXME: This is not complete and does not work, only implemented partially * to allow firmware and guests to find an empty bus. Cards should use PCI. diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index a03d12d1..80c888c 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -505,6 +505,9 @@ static void sam460ex_init(MachineState *machine) /* MAL */ ppc4xx_mal_init(env, 4, 16, &uic[2][3]); + /* DMA */ + ppc4xx_dma_init(env, 0x200); + /* 256K of L2 cache as memory */ ppc4xx_l2sram_init(env); /* FIXME: remove this after fixing l2sram mapping in ppc440_uc.c? */ -- cgit v1.1 From e89372951d328143ecdb3a524bf53454ad9309b0 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 2 Jul 2018 10:54:56 +0200 Subject: spapr: compute default value of "hpt-max-page-size" later It is currently not possible to run a pseries-2.12 or older machine with HV KVM. QEMU prints the following and exits right away. qemu-system-ppc64: KVM doesn't support for base page shift 34 The "hpt-max-page-size" capability was recently added to spapr to hide host configuration details from HPT mode guests. Its default value for newer machine types is 64k. For backwards compatibility, pseries-2.12 and older machine types need a different value. This is handled as usual in a class init function. The default value is 16G, ie, all page sizes supported by POWER7 and newer CPUs, but HV KVM requires guest pages to be hpa contiguous as well as gpa contiguous. The default value is the page size used to back the guest RAM in this case. Unfortunately kvmppc_hpt_needs_host_contiguous_pages()->kvm_enabled() is called way before KVM init and returns false, even if the user requested KVM. We thus end up selecting 16G, which isn't supported by HV KVM. The default value must be set during machine init, because we can safely assume that KVM is initialized at this point. We fix this by moving the logic to default_caps_with_cpu(). Since the user cannot pass cap-hpt-max-page-size=0, we set the default to 0 in the pseries-2.12 class init function and use that as a flag to do the real work. Signed-off-by: Greg Kurz Reviewed-by: Eduardo Habkost Signed-off-by: David Gibson --- hw/ppc/spapr.c | 13 ++++++------- hw/ppc/spapr_caps.c | 13 +++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b2baec0..062d9dc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4095,17 +4095,16 @@ static void spapr_machine_2_12_instance_options(MachineState *machine) static void spapr_machine_2_12_class_options(MachineClass *mc) { sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); - uint8_t mps; spapr_machine_3_0_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_12); - if (kvmppc_hpt_needs_host_contiguous_pages()) { - mps = ctz64(qemu_getrampagesize()); - } else { - mps = 34; /* allow everything up to 16GiB, i.e. everything */ - } - smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = mps; + /* We depend on kvm_enabled() to choose a default value for the + * hpt-max-page-size capability. Of course we can't do it here + * because this is too early and the HW accelerator isn't initialzed + * yet. Postpone this to machine init (see default_caps_with_cpu()). + */ + smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 0; } DEFINE_SPAPR_MACHINE(2_12, "2.12", false); diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 62663eb..aa605ce 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -465,6 +465,19 @@ static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr, caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; } + /* This is for pseries-2.12 and older */ + if (smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] == 0) { + uint8_t mps; + + if (kvmppc_hpt_needs_host_contiguous_pages()) { + mps = ctz64(qemu_getrampagesize()); + } else { + mps = 34; /* allow everything up to 16GiB, i.e. everything */ + } + + caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = mps; + } + return caps; } -- cgit v1.1 From 29f9cef39eb1ae55e82c6763eb22d7a1bdff7276 Mon Sep 17 00:00:00 2001 From: Sebastian Bauer Date: Mon, 2 Jul 2018 21:13:45 +0200 Subject: ppc: Include vga cirrus card into the compiling process Drivers for this card exists on PPC-based AmigaOS guests so it is useful to allow users to emulate the graphics card for PPC machines. As cirrus vga is currently preferred over std(vga) in absence of any user choice, this change also sets the default display of spapr machines to std as otherwise qemu refuses to start these machines. Not specifying an explicit graphics mode is for instance done by 'make check'. Signed-off-by: Sebastian Bauer Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 062d9dc..6e8723d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3962,6 +3962,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->no_parallel = 1; mc->default_boot_order = ""; mc->default_ram_size = 512 * M_BYTE; + mc->default_display = "std"; mc->kvm_type = spapr_kvm_type; machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SPAPR_PCI_HOST_BRIDGE); mc->pci_allow_0_address = true; -- cgit v1.1