aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.objs1
-rw-r--r--default-configs/sparc64-softmmu.mak3
-rw-r--r--hw/display/vga.c3
-rw-r--r--hw/intc/grlib_irqmp.c17
-rw-r--r--hw/pci-bridge/Makefile.objs2
-rw-r--r--hw/pci-bridge/simba.c101
-rw-r--r--hw/pci-host/Makefile.objs2
-rw-r--r--hw/pci-host/sabre.c (renamed from hw/pci-host/apb.c)270
-rw-r--r--hw/pci-host/trace-events11
-rw-r--r--hw/sparc64/sparc64.c85
-rw-r--r--hw/sparc64/sun4u.c109
-rw-r--r--hw/sparc64/trace-events18
-rw-r--r--include/hw/pci-bridge/simba.h38
-rw-r--r--include/hw/pci-host/sabre.h (renamed from include/hw/pci-host/apb.h)26
14 files changed, 419 insertions, 267 deletions
diff --git a/Makefile.objs b/Makefile.objs
index 669d8d684d..323ef12384 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -150,6 +150,7 @@ trace-events-subdirs += hw/i386/xen
trace-events-subdirs += hw/9pfs
trace-events-subdirs += hw/ppc
trace-events-subdirs += hw/pci
+trace-events-subdirs += hw/pci-host
trace-events-subdirs += hw/s390x
trace-events-subdirs += hw/vfio
trace-events-subdirs += hw/acpi
diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak
index 3e177bbd7b..52edafe547 100644
--- a/default-configs/sparc64-softmmu.mak
+++ b/default-configs/sparc64-softmmu.mak
@@ -11,7 +11,8 @@ CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_IDE_ISA=y
CONFIG_IDE_CMD646=y
-CONFIG_PCI_APB=y
+CONFIG_PCI_SABRE=y
+CONFIG_SIMBA=y
CONFIG_SUNHME=y
CONFIG_MC146818RTC=y
CONFIG_ISA_TESTDEV=y
diff --git a/hw/display/vga.c b/hw/display/vga.c
index a0412000a5..6e78a4e156 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1279,6 +1279,9 @@ static void vga_draw_text(VGACommonState *s, int full_update)
cx_min = width;
cx_max = -1;
for(cx = 0; cx < width; cx++) {
+ if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
+ break;
+ }
ch_attr = *(uint16_t *)src;
if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
if (cx < cx_min)
diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index 94659ee256..d6f9cb3692 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -106,6 +106,15 @@ static void grlib_irqmp_check_irqs(IRQMPState *state)
}
}
+static void grlib_irqmp_ack_mask(IRQMPState *state, uint32_t mask)
+{
+ /* Clear registers */
+ state->pending &= ~mask;
+ state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
+
+ grlib_irqmp_check_irqs(state);
+}
+
void grlib_irqmp_ack(DeviceState *dev, int intno)
{
IRQMP *irqmp = GRLIB_IRQMP(dev);
@@ -120,11 +129,7 @@ void grlib_irqmp_ack(DeviceState *dev, int intno)
trace_grlib_irqmp_ack(intno);
- /* Clear registers */
- state->pending &= ~mask;
- state->force[0] &= ~mask; /* Only CPU 0 (No SMP support) */
-
- grlib_irqmp_check_irqs(state);
+ grlib_irqmp_ack_mask(state, mask);
}
void grlib_irqmp_set_irq(void *opaque, int irq, int level)
@@ -251,7 +256,7 @@ static void grlib_irqmp_write(void *opaque, hwaddr addr,
case CLEAR_OFFSET:
value &= ~1; /* clean up the value */
- state->pending &= ~value;
+ grlib_irqmp_ack_mask(state, value);
return;
case MP_STATUS_OFFSET:
diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index 1b05023662..47065f87d9 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -6,3 +6,5 @@ common-obj-$(CONFIG_IOH3420) += ioh3420.o
common-obj-$(CONFIG_I82801B11) += i82801b11.o
# NewWorld PowerMac
common-obj-$(CONFIG_DEC_PCI) += dec.o
+# Sun4u
+common-obj-$(CONFIG_SIMBA) += simba.o
diff --git a/hw/pci-bridge/simba.c b/hw/pci-bridge/simba.c
new file mode 100644
index 0000000000..dea4c8c5e7
--- /dev/null
+++ b/hw/pci-bridge/simba.c
@@ -0,0 +1,101 @@
+/*
+ * QEMU Simba PCI bridge
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2012,2013 Artyom Tarasenko
+ * Copyright (c) 2018 Mark Cave-Ayland
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci-bridge/simba.h"
+
+/*
+ * Chipset docs:
+ * APB: "Advanced PCI Bridge (APB) User's Manual",
+ * http://www.sun.com/processors/manuals/805-1251.pdf
+ */
+
+static void simba_pci_bridge_realize(PCIDevice *dev, Error **errp)
+{
+ /*
+ * command register:
+ * According to PCI bridge spec, after reset
+ * bus master bit is off
+ * memory space enable bit is off
+ * According to manual (805-1251.pdf).
+ * the reset value should be zero unless the boot pin is tied high
+ * (which is true) and thus it should be PCI_COMMAND_MEMORY.
+ */
+ SimbaPCIBridge *br = SIMBA_PCI_BRIDGE(dev);
+
+ pci_bridge_initfn(dev, TYPE_PCI_BUS);
+
+ pci_set_word(dev->config + PCI_COMMAND, PCI_COMMAND_MEMORY);
+ pci_set_word(dev->config + PCI_STATUS,
+ PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
+ PCI_STATUS_DEVSEL_MEDIUM);
+
+ /* Allow 32-bit IO addresses */
+ pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
+ pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
+ pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
+ pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
+
+ pci_bridge_update_mappings(PCI_BRIDGE(br));
+}
+
+static void simba_pci_bridge_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ k->realize = simba_pci_bridge_realize;
+ k->exit = pci_bridge_exitfn;
+ k->vendor_id = PCI_VENDOR_ID_SUN;
+ k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
+ k->revision = 0x11;
+ k->config_write = pci_bridge_write_config;
+ k->is_bridge = 1;
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+ dc->reset = pci_bridge_reset;
+ dc->vmsd = &vmstate_pci_device;
+}
+
+static const TypeInfo simba_pci_bridge_info = {
+ .name = TYPE_SIMBA_PCI_BRIDGE,
+ .parent = TYPE_PCI_BRIDGE,
+ .class_init = simba_pci_bridge_class_init,
+ .instance_size = sizeof(SimbaPCIBridge),
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
+};
+
+static void simba_register_types(void)
+{
+ type_register_static(&simba_pci_bridge_info);
+}
+
+type_init(simba_register_types)
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
index 9c7909cf44..4b69f737b5 100644
--- a/hw/pci-host/Makefile.objs
+++ b/hw/pci-host/Makefile.objs
@@ -11,7 +11,7 @@ common-obj-$(CONFIG_PPCE500_PCI) += ppce500.o
# ARM devices
common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o
-common-obj-$(CONFIG_PCI_APB) += apb.o
+common-obj-$(CONFIG_PCI_SABRE) += sabre.o
common-obj-$(CONFIG_FULONG) += bonito.o
common-obj-$(CONFIG_PCI_PIIX) += piix.o
common-obj-$(CONFIG_PCI_Q35) += q35.o
diff --git a/hw/pci-host/apb.c b/hw/pci-host/sabre.c
index ec676f94b6..2268a41dd9 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/sabre.c
@@ -1,8 +1,9 @@
/*
- * QEMU Ultrasparc APB PCI host
+ * QEMU Ultrasparc Sabre PCI host (PBM)
*
* Copyright (c) 2006 Fabrice Bellard
* Copyright (c) 2012,2013 Artyom Tarasenko
+ * Copyright (c) 2018 Mark Cave-Ayland
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,39 +24,24 @@
* THE SOFTWARE.
*/
-/* XXX This file and most of its contents are somewhat misnamed. The
- Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
- the secondary PCI bridge. */
-
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
-#include "hw/pci-host/apb.h"
+#include "hw/pci-bridge/simba.h"
+#include "hw/pci-host/sabre.h"
#include "sysemu/sysemu.h"
#include "exec/address-spaces.h"
#include "qapi/error.h"
#include "qemu/log.h"
-
-/* debug APB */
-//#define DEBUG_APB
-
-#ifdef DEBUG_APB
-#define APB_DPRINTF(fmt, ...) \
-do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define APB_DPRINTF(fmt, ...)
-#endif
+#include "trace.h"
/*
* Chipset docs:
* PBM: "UltraSPARC IIi User's Manual",
* http://www.sun.com/processors/manuals/805-0087.pdf
- *
- * APB: "Advanced PCI Bridge (APB) User's Manual",
- * http://www.sun.com/processors/manuals/805-1251.pdf
*/
#define PBM_PCI_IMR_MASK 0x7fffffff
@@ -72,22 +58,20 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
#define NO_IRQ_REQUEST (MAX_IVEC + 1)
-static inline void pbm_set_request(APBState *s, unsigned int irq_num)
+static inline void sabre_set_request(SabreState *s, unsigned int irq_num)
{
- APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
-
+ trace_sabre_set_request(irq_num);
s->irq_request = irq_num;
qemu_set_irq(s->ivec_irqs[irq_num], 1);
}
-static inline void pbm_check_irqs(APBState *s)
+static inline void sabre_check_irqs(SabreState *s)
{
-
unsigned int i;
/* Previous request is not acknowledged, resubmit */
if (s->irq_request != NO_IRQ_REQUEST) {
- pbm_set_request(s, s->irq_request);
+ sabre_set_request(s, s->irq_request);
return;
}
/* no request pending */
@@ -97,7 +81,7 @@ static inline void pbm_check_irqs(APBState *s)
for (i = 0; i < 32; i++) {
if (s->pci_irq_in & (1ULL << i)) {
if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
- pbm_set_request(s, i);
+ sabre_set_request(s, i);
return;
}
}
@@ -105,33 +89,33 @@ static inline void pbm_check_irqs(APBState *s)
for (i = 32; i < 64; i++) {
if (s->pci_irq_in & (1ULL << i)) {
if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
- pbm_set_request(s, i);
+ sabre_set_request(s, i);
break;
}
}
}
}
-static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
+static inline void sabre_clear_request(SabreState *s, unsigned int irq_num)
{
- APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
+ trace_sabre_clear_request(irq_num);
qemu_set_irq(s->ivec_irqs[irq_num], 0);
s->irq_request = NO_IRQ_REQUEST;
}
-static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+static AddressSpace *sabre_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
IOMMUState *is = opaque;
return &is->iommu_as;
}
-static void apb_config_writel (void *opaque, hwaddr addr,
+static void sabre_config_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- APBState *s = opaque;
+ SabreState *s = opaque;
- APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
+ trace_sabre_config_write(addr, val);
switch (addr & 0xffff) {
case 0x30 ... 0x4f: /* DMA error registers */
@@ -143,9 +127,9 @@ static void apb_config_writel (void *opaque, hwaddr addr,
s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
- pbm_clear_request(s, ino);
+ sabre_clear_request(s, ino);
}
- pbm_check_irqs(s);
+ sabre_check_irqs(s);
}
break;
case 0x1000 ... 0x107f: /* OBIO interrupt control */
@@ -155,17 +139,17 @@ static void apb_config_writel (void *opaque, hwaddr addr,
s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
if ((s->irq_request == (ino | 0x20))
&& !(val & ~PBM_PCI_IMR_MASK)) {
- pbm_clear_request(s, ino | 0x20);
+ sabre_clear_request(s, ino | 0x20);
}
- pbm_check_irqs(s);
+ sabre_check_irqs(s);
}
break;
case 0x1400 ... 0x14ff: /* PCI interrupt clear */
if (addr & 4) {
unsigned int ino = (addr & 0xff) >> 5;
if ((s->irq_request / 4) == ino) {
- pbm_clear_request(s, s->irq_request);
- pbm_check_irqs(s);
+ sabre_clear_request(s, s->irq_request);
+ sabre_check_irqs(s);
}
}
break;
@@ -173,8 +157,8 @@ static void apb_config_writel (void *opaque, hwaddr addr,
if (addr & 4) {
unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
if (s->irq_request == ino) {
- pbm_clear_request(s, ino);
- pbm_check_irqs(s);
+ sabre_clear_request(s, ino);
+ sabre_check_irqs(s);
}
}
break;
@@ -204,10 +188,10 @@ static void apb_config_writel (void *opaque, hwaddr addr,
}
}
-static uint64_t apb_config_readl (void *opaque,
+static uint64_t sabre_config_read(void *opaque,
hwaddr addr, unsigned size)
{
- APBState *s = opaque;
+ SabreState *s = opaque;
uint32_t val;
switch (addr & 0xffff) {
@@ -255,47 +239,47 @@ static uint64_t apb_config_readl (void *opaque,
val = 0;
break;
}
- APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
+ trace_sabre_config_read(addr, val);
return val;
}
-static const MemoryRegionOps apb_config_ops = {
- .read = apb_config_readl,
- .write = apb_config_writel,
+static const MemoryRegionOps sabre_config_ops = {
+ .read = sabre_config_read,
+ .write = sabre_config_write,
.endianness = DEVICE_BIG_ENDIAN,
};
-static void apb_pci_config_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
+static void sabre_pci_config_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
- APBState *s = opaque;
+ SabreState *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
- APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
+ trace_sabre_pci_config_write(addr, val);
pci_data_write(phb->bus, addr, val, size);
}
-static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
- unsigned size)
+static uint64_t sabre_pci_config_read(void *opaque, hwaddr addr,
+ unsigned size)
{
uint32_t ret;
- APBState *s = opaque;
+ SabreState *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
ret = pci_data_read(phb->bus, addr, size);
- APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
+ trace_sabre_pci_config_read(addr, ret);
return ret;
}
-/* The APB host has an IRQ line for each IRQ line of each slot. */
-static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
+/* The sabre host has an IRQ line for each IRQ line of each slot. */
+static int pci_sabre_map_irq(PCIDevice *pci_dev, int irq_num)
{
/* Return the irq as swizzled by the PBM */
return irq_num;
}
-static int pci_pbmA_map_irq(PCIDevice *pci_dev, int irq_num)
+static int pci_simbaA_map_irq(PCIDevice *pci_dev, int irq_num)
{
/* The on-board devices have fixed (legacy) OBIO intnos */
switch (PCI_SLOT(pci_dev->devfn)) {
@@ -313,22 +297,23 @@ static int pci_pbmA_map_irq(PCIDevice *pci_dev, int irq_num)
return ((PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
}
-static int pci_pbmB_map_irq(PCIDevice *pci_dev, int irq_num)
+static int pci_simbaB_map_irq(PCIDevice *pci_dev, int irq_num)
{
return (0x10 + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
}
-static void pci_apb_set_irq(void *opaque, int irq_num, int level)
+static void pci_sabre_set_irq(void *opaque, int irq_num, int level)
{
- APBState *s = opaque;
+ SabreState *s = opaque;
+
+ trace_sabre_pci_set_irq(irq_num, level);
- APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
/* PCI IRQ map onto the first 32 INO. */
if (irq_num < 32) {
if (level) {
s->pci_irq_in |= 1ULL << irq_num;
if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
- pbm_set_request(s, irq_num);
+ sabre_set_request(s, irq_num);
}
} else {
s->pci_irq_in &= ~(1ULL << irq_num);
@@ -336,11 +321,11 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
} else {
/* OBIO IRQ map onto the next 32 INO. */
if (level) {
- APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
+ trace_sabre_pci_set_obio_irq(irq_num, level);
s->pci_irq_in |= 1ULL << irq_num;
if ((s->irq_request == NO_IRQ_REQUEST)
&& (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
- pbm_set_request(s, irq_num);
+ sabre_set_request(s, irq_num);
}
} else {
s->pci_irq_in &= ~(1ULL << irq_num);
@@ -348,38 +333,9 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
}
}
-static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
+static void sabre_reset(DeviceState *d)
{
- /*
- * command register:
- * According to PCI bridge spec, after reset
- * bus master bit is off
- * memory space enable bit is off
- * According to manual (805-1251.pdf).
- * the reset value should be zero unless the boot pin is tied high
- * (which is true) and thus it should be PCI_COMMAND_MEMORY.
- */
- PBMPCIBridge *br = PBM_PCI_BRIDGE(dev);
-
- pci_bridge_initfn(dev, TYPE_PCI_BUS);
-
- pci_set_word(dev->config + PCI_COMMAND, PCI_COMMAND_MEMORY);
- pci_set_word(dev->config + PCI_STATUS,
- PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
- PCI_STATUS_DEVSEL_MEDIUM);
-
- /* Allow 32-bit IO addresses */
- pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
- pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
- pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
- pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
-
- pci_bridge_update_mappings(PCI_BRIDGE(br));
-}
-
-static void pci_pbm_reset(DeviceState *d)
-{
- APBState *s = APB_DEVICE(d);
+ SabreState *s = SABRE_DEVICE(d);
PCIDevice *pci_dev;
unsigned int i;
uint16_t cmd;
@@ -410,19 +366,19 @@ static void pci_pbm_reset(DeviceState *d)
}
static const MemoryRegionOps pci_config_ops = {
- .read = apb_pci_config_read,
- .write = apb_pci_config_write,
+ .read = sabre_pci_config_read,
+ .write = sabre_pci_config_write,
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static void pci_pbm_realize(DeviceState *dev, Error **errp)
+static void sabre_realize(DeviceState *dev, Error **errp)
{
- APBState *s = APB_DEVICE(dev);
+ SabreState *s = SABRE_DEVICE(dev);
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
PCIDevice *pci_dev;
- /* apb_config */
+ /* sabre_config */
sysbus_mmio_map(sbd, 0, s->special_base);
/* PCI configuration space */
sysbus_mmio_map(sbd, 1, s->special_base + 0x1000000ULL);
@@ -434,35 +390,35 @@ static void pci_pbm_realize(DeviceState *dev, Error **errp)
&s->pci_mmio);
phb->bus = pci_register_root_bus(dev, "pci",
- pci_apb_set_irq, pci_apb_map_irq, s,
+ pci_sabre_set_irq, pci_sabre_map_irq, s,
&s->pci_mmio,
&s->pci_ioport,
0, 32, TYPE_PCI_BUS);
- pci_create_simple(phb->bus, 0, "pbm-pci");
+ pci_create_simple(phb->bus, 0, TYPE_SABRE_PCI_DEVICE);
- /* APB IOMMU */
- memory_region_add_subregion_overlap(&s->apb_config, 0x200,
+ /* IOMMU */
+ memory_region_add_subregion_overlap(&s->sabre_config, 0x200,
sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
- pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, s->iommu);
+ pci_setup_iommu(phb->bus, sabre_pci_dma_iommu, s->iommu);
/* APB secondary busses */
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
- TYPE_PBM_PCI_BRIDGE);
+ TYPE_SIMBA_PCI_BRIDGE);
s->bridgeB = PCI_BRIDGE(pci_dev);
- pci_bridge_map_irq(s->bridgeB, "pciB", pci_pbmB_map_irq);
+ pci_bridge_map_irq(s->bridgeB, "pciB", pci_simbaB_map_irq);
qdev_init_nofail(&pci_dev->qdev);
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
- TYPE_PBM_PCI_BRIDGE);
+ TYPE_SIMBA_PCI_BRIDGE);
s->bridgeA = PCI_BRIDGE(pci_dev);
- pci_bridge_map_irq(s->bridgeA, "pciA", pci_pbmA_map_irq);
+ pci_bridge_map_irq(s->bridgeA, "pciA", pci_simbaA_map_irq);
qdev_init_nofail(&pci_dev->qdev);
}
-static void pci_pbm_init(Object *obj)
+static void sabre_init(Object *obj)
{
- APBState *s = APB_DEVICE(obj);
+ SabreState *s = SABRE_DEVICE(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
unsigned int i;
@@ -475,7 +431,7 @@ static void pci_pbm_init(Object *obj)
for (i = 0; i < 32; i++) {
s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
}
- qdev_init_gpio_in_named(DEVICE(s), pci_apb_set_irq, "pbm-irq", MAX_IVEC);
+ qdev_init_gpio_in_named(DEVICE(s), pci_sabre_set_irq, "pbm-irq", MAX_IVEC);
qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
s->irq_request = NO_IRQ_REQUEST;
s->pci_irq_in = 0ULL;
@@ -486,25 +442,26 @@ static void pci_pbm_init(Object *obj)
qdev_prop_allow_set_link_before_realize,
0, NULL);
- /* apb_config */
- memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
- "apb-config", 0x10000);
+ /* sabre_config */
+ memory_region_init_io(&s->sabre_config, OBJECT(s), &sabre_config_ops, s,
+ "sabre-config", 0x10000);
/* at region 0 */
- sysbus_init_mmio(sbd, &s->apb_config);
+ sysbus_init_mmio(sbd, &s->sabre_config);
memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
- "apb-pci-config", 0x1000000);
+ "sabre-pci-config", 0x1000000);
/* at region 1 */
sysbus_init_mmio(sbd, &s->pci_config);
/* pci_ioport */
- memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
+ memory_region_init(&s->pci_ioport, OBJECT(s), "sabre-pci-ioport",
+ 0x1000000);
/* at region 2 */
sysbus_init_mmio(sbd, &s->pci_ioport);
}
-static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
+static void sabre_pci_realize(PCIDevice *d, Error **errp)
{
pci_set_word(d->config + PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
@@ -513,12 +470,12 @@ static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
PCI_STATUS_DEVSEL_MEDIUM);
}
-static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
+static void sabre_pci_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->realize = pbm_pci_host_realize;
+ k->realize = sabre_pci_realize;
k->vendor_id = PCI_VENDOR_ID_SUN;
k->device_id = PCI_DEVICE_ID_SUN_SABRE;
k->class_id = PCI_CLASS_BRIDGE_HOST;
@@ -529,74 +486,45 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
dc->user_creatable = false;
}
-static const TypeInfo pbm_pci_host_info = {
- .name = "pbm-pci",
+static const TypeInfo sabre_pci_info = {
+ .name = TYPE_SABRE_PCI_DEVICE,
.parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCIDevice),
- .class_init = pbm_pci_host_class_init,
+ .instance_size = sizeof(SabrePCIState),
+ .class_init = sabre_pci_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
},
};
-static Property pbm_pci_host_properties[] = {
- DEFINE_PROP_UINT64("special-base", APBState, special_base, 0),
- DEFINE_PROP_UINT64("mem-base", APBState, mem_base, 0),
+static Property sabre_properties[] = {
+ DEFINE_PROP_UINT64("special-base", SabreState, special_base, 0),
+ DEFINE_PROP_UINT64("mem-base", SabreState, mem_base, 0),
DEFINE_PROP_END_OF_LIST(),
};
-static void pbm_host_class_init(ObjectClass *klass, void *data)
+static void sabre_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->realize = pci_pbm_realize;
- dc->reset = pci_pbm_reset;
- dc->props = pbm_pci_host_properties;
+ dc->realize = sabre_realize;
+ dc->reset = sabre_reset;
+ dc->props = sabre_properties;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
-static const TypeInfo pbm_host_info = {
- .name = TYPE_APB,
+static const TypeInfo sabre_info = {
+ .name = TYPE_SABRE,
.parent = TYPE_PCI_HOST_BRIDGE,
- .instance_size = sizeof(APBState),
- .instance_init = pci_pbm_init,
- .class_init = pbm_host_class_init,
-};
-
-static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = apb_pci_bridge_realize;
- k->exit = pci_bridge_exitfn;
- k->vendor_id = PCI_VENDOR_ID_SUN;
- k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
- k->revision = 0x11;
- k->config_write = pci_bridge_write_config;
- k->is_bridge = 1;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
- dc->reset = pci_bridge_reset;
- dc->vmsd = &vmstate_pci_device;
-}
-
-static const TypeInfo pbm_pci_bridge_info = {
- .name = TYPE_PBM_PCI_BRIDGE,
- .parent = TYPE_PCI_BRIDGE,
- .class_init = pbm_pci_bridge_class_init,
- .instance_size = sizeof(PBMPCIBridge),
- .interfaces = (InterfaceInfo[]) {
- { INTERFACE_CONVENTIONAL_PCI_DEVICE },
- { },
- },
+ .instance_size = sizeof(SabreState),
+ .instance_init = sabre_init,
+ .class_init = sabre_class_init,
};
-static void pbm_register_types(void)
+static void sabre_register_types(void)
{
- type_register_static(&pbm_host_info);
- type_register_static(&pbm_pci_host_info);
- type_register_static(&pbm_pci_bridge_info);
+ type_register_static(&sabre_info);
+ type_register_static(&sabre_pci_info);
}
-type_init(pbm_register_types)
+type_init(sabre_register_types)
diff --git a/hw/pci-host/trace-events b/hw/pci-host/trace-events
new file mode 100644
index 0000000000..32dfc84692
--- /dev/null
+++ b/hw/pci-host/trace-events
@@ -0,0 +1,11 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/pci-host/sabre.c
+sabre_set_request(int irq_num) "request irq %d"
+sabre_clear_request(int irq_num) "clear request irq %d"
+sabre_config_write(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" val 0x%"PRIx64
+sabre_config_read(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" val 0x%"PRIx64
+sabre_pci_config_write(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" val 0x%"PRIx64
+sabre_pci_config_read(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" val 0x%"PRIx64
+sabre_pci_set_irq(int irq_num, int level) "set irq_in %d level %d"
+sabre_pci_set_obio_irq(int irq_num, int level) "set irq %d level %d"
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
index 95a06f00b2..408388945e 100644
--- a/hw/sparc64/sparc64.c
+++ b/hw/sparc64/sparc64.c
@@ -28,25 +28,9 @@
#include "hw/char/serial.h"
#include "hw/sparc/sparc64.h"
#include "qemu/timer.h"
+#include "trace.h"
-//#define DEBUG_IRQ
-//#define DEBUG_TIMER
-
-#ifdef DEBUG_IRQ
-#define CPUIRQ_DPRINTF(fmt, ...) \
- do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define CPUIRQ_DPRINTF(fmt, ...)
-#endif
-
-#ifdef DEBUG_TIMER
-#define TIMER_DPRINTF(fmt, ...) \
- do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define TIMER_DPRINTF(fmt, ...)
-#endif
-
#define TICK_MAX 0x7fffffffffffffffULL
void cpu_check_irqs(CPUSPARCState *env)
@@ -73,8 +57,7 @@ void cpu_check_irqs(CPUSPARCState *env)
is (2 << psrpil). */
if (pil < (2 << env->psrpil)) {
if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
- CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
- env->interrupt_index);
+ trace_sparc64_cpu_check_irqs_reset_irq(env->interrupt_index);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
@@ -92,22 +75,21 @@ void cpu_check_irqs(CPUSPARCState *env)
if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
&& ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
- CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
- "current %x >= pending %x\n",
- env->tl, cpu_tsptr(env)->tt, new_interrupt);
+ trace_sparc64_cpu_check_irqs_noset_irq(env->tl,
+ cpu_tsptr(env)->tt,
+ new_interrupt);
} else if (old_interrupt != new_interrupt) {
env->interrupt_index = new_interrupt;
- CPUIRQ_DPRINTF("Set CPU IRQ %d old=%x new=%x\n", i,
- old_interrupt, new_interrupt);
+ trace_sparc64_cpu_check_irqs_set_irq(i, old_interrupt,
+ new_interrupt);
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
}
break;
}
}
} else if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
- CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
- "current interrupt %x\n",
- pil, env->pil_in, env->softint, env->interrupt_index);
+ trace_sparc64_cpu_check_irqs_disabled(pil, env->pil_in, env->softint,
+ env->interrupt_index);
env->interrupt_index = 0;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
@@ -131,7 +113,7 @@ void sparc64_cpu_set_ivec_irq(void *opaque, int irq, int level)
if (level) {
if (!(env->ivec_status & 0x20)) {
- CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
+ trace_sparc64_cpu_ivec_raise_irq(irq);
cs = CPU(cpu);
cs->halted = 0;
env->interrupt_index = TT_IVEC;
@@ -143,7 +125,7 @@ void sparc64_cpu_set_ivec_irq(void *opaque, int irq, int level)
}
} else {
if (env->ivec_status & 0x20) {
- CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
+ trace_sparc64_cpu_ivec_lower_irq(irq);
cs = CPU(cpu);
env->ivec_status &= ~0x20;
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
@@ -216,10 +198,10 @@ static void tick_irq(void *opaque)
CPUTimer *timer = env->tick;
if (timer->disabled) {
- CPUIRQ_DPRINTF("tick_irq: softint disabled\n");
+ trace_sparc64_cpu_tick_irq_disabled();
return;
} else {
- CPUIRQ_DPRINTF("tick: fire\n");
+ trace_sparc64_cpu_tick_irq_fire();
}
env->softint |= SOFTINT_TIMER;
@@ -234,10 +216,10 @@ static void stick_irq(void *opaque)
CPUTimer *timer = env->stick;
if (timer->disabled) {
- CPUIRQ_DPRINTF("stick_irq: softint disabled\n");
+ trace_sparc64_cpu_stick_irq_disabled();
return;
} else {
- CPUIRQ_DPRINTF("stick: fire\n");
+ trace_sparc64_cpu_stick_irq_fire();
}
env->softint |= SOFTINT_STIMER;
@@ -252,10 +234,10 @@ static void hstick_irq(void *opaque)
CPUTimer *timer = env->hstick;
if (timer->disabled) {
- CPUIRQ_DPRINTF("hstick_irq: softint disabled\n");
+ trace_sparc64_cpu_hstick_irq_disabled();
return;
} else {
- CPUIRQ_DPRINTF("hstick: fire\n");
+ trace_sparc64_cpu_hstick_irq_fire();
}
env->softint |= SOFTINT_STIMER;
@@ -280,9 +262,9 @@ void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
cpu_to_timer_ticks(real_count, timer->frequency);
- TIMER_DPRINTF("%s set_count count=0x%016lx (npt %s) p=%p\n",
- timer->name, real_count,
- timer->npt ? "disabled" : "enabled", timer);
+ trace_sparc64_cpu_tick_set_count(timer->name, real_count,
+ timer->npt ? "disabled" : "enabled",
+ timer);
timer->npt = npt_bit ? 1 : 0;
timer->clock_offset = vm_clock_offset;
@@ -294,9 +276,9 @@ uint64_t cpu_tick_get_count(CPUTimer *timer)
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
timer->frequency);
- TIMER_DPRINTF("%s get_count count=0x%016lx (npt %s) p=%p\n",
- timer->name, real_count,
- timer->npt ? "disabled" : "enabled", timer);
+ trace_sparc64_cpu_tick_get_count(timer->name, real_count,
+ timer->npt ? "disabled" : "enabled",
+ timer);
if (timer->npt) {
real_count |= timer->npt_mask;
@@ -319,18 +301,19 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
expires = now + 1;
}
- TIMER_DPRINTF("%s set_limit limit=0x%016lx (%s) p=%p "
- "called with limit=0x%016lx at 0x%016lx (delta=0x%016lx)\n",
- timer->name, real_limit,
- timer->disabled ? "disabled" : "enabled",
- timer, limit,
- timer_to_cpu_ticks(now - timer->clock_offset,
- timer->frequency),
- timer_to_cpu_ticks(expires - now, timer->frequency));
+ trace_sparc64_cpu_tick_set_limit(timer->name, real_limit,
+ timer->disabled ? "disabled" : "enabled",
+ timer, limit,
+ timer_to_cpu_ticks(
+ now - timer->clock_offset,
+ timer->frequency
+ ),
+ timer_to_cpu_ticks(
+ expires - now, timer->frequency
+ ));
if (!real_limit) {
- TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
- timer->name);
+ trace_sparc64_cpu_tick_set_limit_zero(timer->name);
timer_del(timer->qtimer);
} else if (timer->disabled) {
timer_del(timer->qtimer);
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index ec45ec2801..a23cb26b0d 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -30,7 +30,7 @@
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_host.h"
-#include "hw/pci-host/apb.h"
+#include "hw/pci-host/sabre.h"
#include "hw/i386/pc.h"
#include "hw/char/serial.h"
#include "hw/timer/m48t59.h"
@@ -55,9 +55,9 @@
#define CMDLINE_ADDR 0x003ff000
#define PROM_SIZE_MAX (4 * 1024 * 1024)
#define PROM_VADDR 0x000ffd00000ULL
-#define APB_SPECIAL_BASE 0x1fe00000000ULL
-#define APB_MEM_BASE 0x1ff00000000ULL
-#define APB_PCI_IO_BASE (APB_SPECIAL_BASE + 0x02000000ULL)
+#define PBM_SPECIAL_BASE 0x1fe00000000ULL
+#define PBM_MEM_BASE 0x1ff00000000ULL
+#define PBM_PCI_IO_BASE (PBM_SPECIAL_BASE + 0x02000000ULL)
#define PROM_FILENAME "openbios-sparc64"
#define NVRAM_SIZE 0x2000
#define MAX_IDE_BUS 2
@@ -205,6 +205,59 @@ typedef struct ResetData {
uint64_t prom_addr;
} ResetData;
+#define TYPE_SUN4U_POWER "power"
+#define SUN4U_POWER(obj) OBJECT_CHECK(PowerDevice, (obj), TYPE_SUN4U_POWER)
+
+typedef struct PowerDevice {
+ SysBusDevice parent_obj;
+
+ MemoryRegion power_mmio;
+} PowerDevice;
+
+/* Power */
+static void power_mem_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ /* According to a real Ultra 5, bit 24 controls the power */
+ if (val & 0x1000000) {
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+ }
+}
+
+static const MemoryRegionOps power_mem_ops = {
+ .write = power_mem_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static void power_realize(DeviceState *dev, Error **errp)
+{
+ PowerDevice *d = SUN4U_POWER(dev);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+ memory_region_init_io(&d->power_mmio, OBJECT(dev), &power_mem_ops, d,
+ "power", sizeof(uint32_t));
+
+ sysbus_init_mmio(sbd, &d->power_mmio);
+}
+
+static void power_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = power_realize;
+}
+
+static const TypeInfo power_info = {
+ .name = TYPE_SUN4U_POWER,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(PowerDevice),
+ .class_init = power_class_init,
+};
+
static void ebus_isa_irq_handler(void *opaque, int n, int level)
{
EbusState *s = EBUS(opaque);
@@ -221,6 +274,7 @@ static void ebus_isa_irq_handler(void *opaque, int n, int level)
static void ebus_realize(PCIDevice *pci_dev, Error **errp)
{
EbusState *s = EBUS(pci_dev);
+ SysBusDevice *sbd;
DeviceState *dev;
qemu_irq *isa_irq;
DriveInfo *fd[MAX_FD];
@@ -270,6 +324,13 @@ static void ebus_realize(PCIDevice *pci_dev, Error **errp)
qdev_prop_set_uint32(dev, "dma", -1);
qdev_init_nofail(dev);
+ /* Power */
+ dev = qdev_create(NULL, TYPE_SUN4U_POWER);
+ qdev_init_nofail(dev);
+ sbd = SYS_BUS_DEVICE(dev);
+ memory_region_add_subregion(pci_address_space_io(pci_dev), 0x7240,
+ sysbus_mmio_get_region(sbd, 0));
+
/* PCI */
pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
pci_dev->config[0x05] = 0x00;
@@ -282,7 +343,7 @@ static void ebus_realize(PCIDevice *pci_dev, Error **errp)
0, 0x1000000);
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
memory_region_init_alias(&s->bar1, OBJECT(s), "bar1", get_system_io(),
- 0, 0x4000);
+ 0, 0x8000);
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->bar1);
}
@@ -465,7 +526,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
Nvram *nvram;
unsigned int i;
uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
- APBState *apb;
+ SabreState *sabre;
PCIBus *pci_bus, *pci_busA, *pci_busB;
PCIDevice *ebus, *pci_dev;
SysBusDevice *s;
@@ -488,24 +549,25 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
prom_init(hwdef->prom_addr, bios_name);
- /* Init APB (PCI host bridge) */
- apb = APB_DEVICE(qdev_create(NULL, TYPE_APB));
- qdev_prop_set_uint64(DEVICE(apb), "special-base", APB_SPECIAL_BASE);
- qdev_prop_set_uint64(DEVICE(apb), "mem-base", APB_MEM_BASE);
- object_property_set_link(OBJECT(apb), OBJECT(iommu), "iommu", &error_abort);
- qdev_init_nofail(DEVICE(apb));
+ /* Init sabre (PCI host bridge) */
+ sabre = SABRE_DEVICE(qdev_create(NULL, TYPE_SABRE));
+ qdev_prop_set_uint64(DEVICE(sabre), "special-base", PBM_SPECIAL_BASE);
+ qdev_prop_set_uint64(DEVICE(sabre), "mem-base", PBM_MEM_BASE);
+ object_property_set_link(OBJECT(sabre), OBJECT(iommu), "iommu",
+ &error_abort);
+ qdev_init_nofail(DEVICE(sabre));
/* Wire up PCI interrupts to CPU */
for (i = 0; i < IVEC_MAX; i++) {
- qdev_connect_gpio_out_named(DEVICE(apb), "ivec-irq", i,
+ qdev_connect_gpio_out_named(DEVICE(sabre), "ivec-irq", i,
qdev_get_gpio_in_named(DEVICE(cpu), "ivec-irq", i));
}
- pci_bus = PCI_HOST_BRIDGE(apb)->bus;
- pci_busA = pci_bridge_get_sec_bus(apb->bridgeA);
- pci_busB = pci_bridge_get_sec_bus(apb->bridgeB);
+ pci_bus = PCI_HOST_BRIDGE(sabre)->bus;
+ pci_busA = pci_bridge_get_sec_bus(sabre->bridgeA);
+ pci_busB = pci_bridge_get_sec_bus(sabre->bridgeB);
- /* Only in-built Simba PBMs can exist on the root bus, slot 0 on busA is
+ /* Only in-built Simba APBs can exist on the root bus, slot 0 on busA is
reserved (leaving no slots free after on-board devices) however slots
0-3 are free on busB */
pci_bus->slot_reserved_mask = 0xfffffffc;
@@ -517,17 +579,17 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
hwdef->console_serial_base);
qdev_init_nofail(DEVICE(ebus));
- /* Wire up "well-known" ISA IRQs to APB legacy obio IRQs */
+ /* Wire up "well-known" ISA IRQs to PBM legacy obio IRQs */
qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 7,
- qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_LPT_IRQ));
+ qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_LPT_IRQ));
qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 6,
- qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_FDD_IRQ));
+ qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_FDD_IRQ));
qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 1,
- qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_KBD_IRQ));
+ qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_KBD_IRQ));
qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 12,
- qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_MSE_IRQ));
+ qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_MSE_IRQ));
qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 4,
- qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_SER_IRQ));
+ qdev_get_gpio_in_named(DEVICE(sabre), "pbm-irq", OBIO_SER_IRQ));
pci_dev = pci_create_simple(pci_busA, PCI_DEVFN(2, 0), "VGA");
@@ -693,6 +755,7 @@ static const TypeInfo sun4v_type = {
static void sun4u_register_types(void)
{
+ type_register_static(&power_info);
type_register_static(&ebus_info);
type_register_static(&prom_info);
type_register_static(&ram_info);
diff --git a/hw/sparc64/trace-events b/hw/sparc64/trace-events
index 2ee2d75f70..ce597a6e9d 100644
--- a/hw/sparc64/trace-events
+++ b/hw/sparc64/trace-events
@@ -7,3 +7,21 @@ ebus_isa_irq_handler(int n, int level) "Set ISA IRQ %d level %d"
sun4u_iommu_mem_read(uint64_t addr, uint64_t val, int size) "addr: 0x%"PRIx64" val: 0x%"PRIx64" size: %d"
sun4u_iommu_mem_write(uint64_t addr, uint64_t val, int size) "addr: 0x%"PRIx64" val: 0x%"PRIx64" size: %d"
sun4u_iommu_translate(uint64_t addr, uint64_t trans_addr, uint64_t tte) "xlate 0x%"PRIx64" => pa 0x%"PRIx64" tte: 0x%"PRIx64
+
+# hw/sparc64/sparc64.c
+sparc64_cpu_check_irqs_reset_irq(int intno) "Reset CPU IRQ (current interrupt 0x%x)"
+sparc64_cpu_check_irqs_noset_irq(uint32_t tl, uint32_t tt, int intno) "Not setting CPU IRQ: TL=%d current 0x%x >= pending 0x%x"
+sparc64_cpu_check_irqs_set_irq(unsigned int i, int old, int new) "Set CPU IRQ %d old=0x%x new=0x%x"
+sparc64_cpu_check_irqs_disabled(uint32_t pil, uint32_t pil_in, uint32_t softint, int intno) "Interrupts disabled, pil=0x%08x pil_in=0x%08x softint=0x%08x current interrupt 0x%x"
+sparc64_cpu_ivec_raise_irq(int irq) "Raise IVEC IRQ %d"
+sparc64_cpu_ivec_lower_irq(int irq) "Lower IVEC IRQ %d"
+sparc64_cpu_tick_irq_disabled(void) "tick_irq: softint disabled"
+sparc64_cpu_tick_irq_fire(void) "tick_irq: fire"
+sparc64_cpu_stick_irq_disabled(void) "stick_irq: softint disabled"
+sparc64_cpu_stick_irq_fire(void) "stick_irq: fire"
+sparc64_cpu_hstick_irq_disabled(void) "hstick_irq: softint disabled"
+sparc64_cpu_hstick_irq_fire(void) "hstick_irq: fire"
+sparc64_cpu_tick_set_count(const char *name, uint64_t real_count, const char *npt, void *p) "%s set_count count=0x%"PRIx64" (npt %s) p=%p"
+sparc64_cpu_tick_get_count(const char *name, uint64_t real_count, const char *npt, void *p) "%s get_count count=0x%"PRIx64" (npt %s) p=%p"
+sparc64_cpu_tick_set_limit(const char *name, uint64_t real_limit, const char *dis, void *p, uint64_t limit, uint64_t t, uint64_t dt) "%s set_limit limit=0x%"PRIx64 " (%s) p=%p called with limit=0x%"PRIx64" at 0x%"PRIx64" (delta=0x%"PRIx64")"
+sparc64_cpu_tick_set_limit_zero(const char *name) "%s set_limit limit=ZERO - not starting timer"
diff --git a/include/hw/pci-bridge/simba.h b/include/hw/pci-bridge/simba.h
new file mode 100644
index 0000000000..fac56ab1cf
--- /dev/null
+++ b/include/hw/pci-bridge/simba.h
@@ -0,0 +1,38 @@
+/*
+ * QEMU Simba PCI bridge
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2012,2013 Artyom Tarasenko
+ * Copyright (c) 2017 Mark Cave-Ayland
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci_bridge.h"
+
+
+typedef struct SimbaPCIBridge {
+ /*< private >*/
+ PCIBridge parent_obj;
+} SimbaPCIBridge;
+
+#define TYPE_SIMBA_PCI_BRIDGE "pbm-bridge"
+#define SIMBA_PCI_BRIDGE(obj) \
+ OBJECT_CHECK(SimbaPCIBridge, (obj), TYPE_SIMBA_PCI_BRIDGE)
diff --git a/include/hw/pci-host/apb.h b/include/hw/pci-host/sabre.h
index 604d899b1e..0f2ccc01c6 100644
--- a/include/hw/pci-host/apb.h
+++ b/include/hw/pci-host/sabre.h
@@ -14,17 +14,20 @@
#define OBIO_MSE_IRQ 0x2a
#define OBIO_SER_IRQ 0x2b
-#define TYPE_APB "pbm"
+typedef struct SabrePCIState {
+ PCIDevice parent_obj;
+} SabrePCIState;
-#define APB_DEVICE(obj) \
- OBJECT_CHECK(APBState, (obj), TYPE_APB)
+#define TYPE_SABRE_PCI_DEVICE "sabre-pci"
+#define SABRE_PCI_DEVICE(obj) \
+ OBJECT_CHECK(SabrePCIState, (obj), TYPE_SABRE_PCI_DEVICE)
-typedef struct APBState {
+typedef struct SabreState {
PCIHostState parent_obj;
hwaddr special_base;
hwaddr mem_base;
- MemoryRegion apb_config;
+ MemoryRegion sabre_config;
MemoryRegion pci_config;
MemoryRegion pci_mmio;
MemoryRegion pci_ioport;
@@ -40,15 +43,10 @@ typedef struct APBState {
unsigned int irq_request;
uint32_t reset_control;
unsigned int nr_resets;
-} APBState;
+} SabreState;
-typedef struct PBMPCIBridge {
- /*< private >*/
- PCIBridge parent_obj;
-} PBMPCIBridge;
-
-#define TYPE_PBM_PCI_BRIDGE "pbm-bridge"
-#define PBM_PCI_BRIDGE(obj) \
- OBJECT_CHECK(PBMPCIBridge, (obj), TYPE_PBM_PCI_BRIDGE)
+#define TYPE_SABRE "sabre"
+#define SABRE_DEVICE(obj) \
+ OBJECT_CHECK(SabreState, (obj), TYPE_SABRE)
#endif