summaryrefslogtreecommitdiffstats
path: root/hw/pci-host
diff options
context:
space:
mode:
Diffstat (limited to 'hw/pci-host')
-rw-r--r--hw/pci-host/apb.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 96e5d0b60d..b709456b97 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -155,6 +155,18 @@ typedef struct APBState {
unsigned int nr_resets;
} APBState;
+#define TYPE_PBM_PCI_BRIDGE "pbm-bridge"
+#define PBM_PCI_BRIDGE(obj) \
+ OBJECT_CHECK(PBMPCIBridge, (obj), TYPE_PBM_PCI_BRIDGE)
+
+typedef struct PBMPCIBridge {
+ /*< private >*/
+ PCIBridge parent_obj;
+
+ /* Is this busA with in-built devices (ebus)? */
+ bool busA;
+} PBMPCIBridge;
+
static inline void pbm_set_request(APBState *s, unsigned int irq_num)
{
APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
@@ -559,7 +571,7 @@ static uint64_t apb_config_readl (void *opaque,
static const MemoryRegionOps apb_config_ops = {
.read = apb_config_readl,
.write = apb_config_writel,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_BIG_ENDIAN,
};
static void apb_pci_config_write(void *opaque, hwaddr addr,
@@ -568,7 +580,6 @@ static void apb_pci_config_write(void *opaque, hwaddr addr,
APBState *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
- val = qemu_bswap_len(val, size);
APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
pci_data_write(phb->bus, addr, val, size);
}
@@ -581,7 +592,6 @@ static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
PCIHostState *phb = PCI_HOST_BRIDGE(s);
ret = pci_data_read(phb->bus, addr, size);
- ret = qemu_bswap_len(ret, size);
APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
return ret;
}
@@ -634,8 +644,6 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level)
static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
{
- pci_bridge_initfn(dev, TYPE_PCI_BUS);
-
/*
* command register:
* According to PCI bridge spec, after reset
@@ -645,16 +653,28 @@ static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
* the reset value should be zero unless the boot pin is tied high
* (which is true) and thus it should be PCI_COMMAND_MEMORY.
*/
- pci_set_word(dev->config + PCI_COMMAND,
- PCI_COMMAND_MEMORY);
+ uint16_t cmd = PCI_COMMAND_MEMORY;
+ PBMPCIBridge *br = PBM_PCI_BRIDGE(dev);
+
+ pci_bridge_initfn(dev, TYPE_PCI_BUS);
+
+ /* If initialising busA, ensure that we allow IO transactions so that
+ we get the early serial console until OpenBIOS configures the bridge */
+ if (br->busA) {
+ cmd |= PCI_COMMAND_IO;
+ }
+
+ pci_set_word(dev->config + PCI_COMMAND, cmd);
pci_set_word(dev->config + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
PCI_STATUS_DEVSEL_MEDIUM);
+
+ pci_bridge_update_mappings(PCI_BRIDGE(br));
}
PCIBus *pci_apb_init(hwaddr special_base,
hwaddr mem_base,
- qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
+ qemu_irq *ivec_irqs, PCIBus **busA, PCIBus **busB,
qemu_irq **pbm_irqs)
{
DeviceState *dev;
@@ -703,20 +723,19 @@ PCIBus *pci_apb_init(hwaddr special_base,
/* APB secondary busses */
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
- "pbm-bridge");
+ TYPE_PBM_PCI_BRIDGE);
br = PCI_BRIDGE(pci_dev);
- pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
- pci_apb_map_irq);
+ pci_bridge_map_irq(br, "pciB", pci_apb_map_irq);
qdev_init_nofail(&pci_dev->qdev);
- *bus2 = pci_bridge_get_sec_bus(br);
+ *busB = pci_bridge_get_sec_bus(br);
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
- "pbm-bridge");
+ TYPE_PBM_PCI_BRIDGE);
br = PCI_BRIDGE(pci_dev);
- pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
- pci_apb_map_irq);
+ pci_bridge_map_irq(br, "pciA", pci_apb_map_irq);
+ qdev_prop_set_bit(DEVICE(pci_dev), "busA", true);
qdev_init_nofail(&pci_dev->qdev);
- *bus3 = pci_bridge_get_sec_bus(br);
+ *busA = pci_bridge_get_sec_bus(br);
return phb->bus;
}
@@ -745,7 +764,7 @@ static void pci_pbm_reset(DeviceState *d)
static const MemoryRegionOps pci_config_ops = {
.read = apb_pci_config_read,
.write = apb_pci_config_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static int pci_pbm_init_device(SysBusDevice *dev)
@@ -836,6 +855,11 @@ static const TypeInfo pbm_host_info = {
.class_init = pbm_host_class_init,
};
+static Property pbm_pci_properties[] = {
+ DEFINE_PROP_BOOL("busA", PBMPCIBridge, busA, false),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -851,12 +875,14 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->reset = pci_bridge_reset;
dc->vmsd = &vmstate_pci_device;
+ dc->props = pbm_pci_properties;
}
static const TypeInfo pbm_pci_bridge_info = {
- .name = "pbm-bridge",
+ .name = TYPE_PBM_PCI_BRIDGE,
.parent = TYPE_PCI_BRIDGE,
.class_init = pbm_pci_bridge_class_init,
+ .instance_size = sizeof(PBMPCIBridge),
};
static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)