mirror of https://github.com/xemu-project/xemu.git
apb: add busA qdev property to PBM PCI bridge
As future sun4u PCI topologies place the ebus containing the in-built devices behind a PCI bridge, add a busA property to the PBM PCI bridge that is then used to allow IO accesses by default. This allows early fw_cfg/NVRAM/serial access to occur even before OpenBIOS has had a chance to configure the PCI bridges. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
parent
b2f9005a2b
commit
e5fd1eb05e
|
@ -155,6 +155,18 @@ typedef struct APBState {
|
||||||
unsigned int nr_resets;
|
unsigned int nr_resets;
|
||||||
} APBState;
|
} 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)
|
static inline void pbm_set_request(APBState *s, unsigned int irq_num)
|
||||||
{
|
{
|
||||||
APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
|
APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
|
||||||
|
@ -632,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)
|
static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
pci_bridge_initfn(dev, TYPE_PCI_BUS);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command register:
|
* command register:
|
||||||
* According to PCI bridge spec, after reset
|
* According to PCI bridge spec, after reset
|
||||||
|
@ -643,11 +653,23 @@ static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
|
||||||
* the reset value should be zero unless the boot pin is tied high
|
* the reset value should be zero unless the boot pin is tied high
|
||||||
* (which is true) and thus it should be PCI_COMMAND_MEMORY.
|
* (which is true) and thus it should be PCI_COMMAND_MEMORY.
|
||||||
*/
|
*/
|
||||||
pci_set_word(dev->config + PCI_COMMAND,
|
uint16_t cmd = PCI_COMMAND_MEMORY;
|
||||||
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_set_word(dev->config + PCI_STATUS,
|
||||||
PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
|
PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
|
||||||
PCI_STATUS_DEVSEL_MEDIUM);
|
PCI_STATUS_DEVSEL_MEDIUM);
|
||||||
|
|
||||||
|
pci_bridge_update_mappings(PCI_BRIDGE(br));
|
||||||
}
|
}
|
||||||
|
|
||||||
PCIBus *pci_apb_init(hwaddr special_base,
|
PCIBus *pci_apb_init(hwaddr special_base,
|
||||||
|
@ -701,16 +723,17 @@ PCIBus *pci_apb_init(hwaddr special_base,
|
||||||
|
|
||||||
/* APB secondary busses */
|
/* APB secondary busses */
|
||||||
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
|
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
|
||||||
"pbm-bridge");
|
TYPE_PBM_PCI_BRIDGE);
|
||||||
br = PCI_BRIDGE(pci_dev);
|
br = PCI_BRIDGE(pci_dev);
|
||||||
pci_bridge_map_irq(br, "pciB", pci_apb_map_irq);
|
pci_bridge_map_irq(br, "pciB", pci_apb_map_irq);
|
||||||
qdev_init_nofail(&pci_dev->qdev);
|
qdev_init_nofail(&pci_dev->qdev);
|
||||||
*busB = 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,
|
pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
|
||||||
"pbm-bridge");
|
TYPE_PBM_PCI_BRIDGE);
|
||||||
br = PCI_BRIDGE(pci_dev);
|
br = PCI_BRIDGE(pci_dev);
|
||||||
pci_bridge_map_irq(br, "pciA", 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);
|
qdev_init_nofail(&pci_dev->qdev);
|
||||||
*busA = pci_bridge_get_sec_bus(br);
|
*busA = pci_bridge_get_sec_bus(br);
|
||||||
|
|
||||||
|
@ -832,6 +855,11 @@ static const TypeInfo pbm_host_info = {
|
||||||
.class_init = pbm_host_class_init,
|
.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)
|
static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
@ -847,12 +875,14 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
|
||||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||||
dc->reset = pci_bridge_reset;
|
dc->reset = pci_bridge_reset;
|
||||||
dc->vmsd = &vmstate_pci_device;
|
dc->vmsd = &vmstate_pci_device;
|
||||||
|
dc->props = pbm_pci_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo pbm_pci_bridge_info = {
|
static const TypeInfo pbm_pci_bridge_info = {
|
||||||
.name = "pbm-bridge",
|
.name = TYPE_PBM_PCI_BRIDGE,
|
||||||
.parent = TYPE_PCI_BRIDGE,
|
.parent = TYPE_PCI_BRIDGE,
|
||||||
.class_init = pbm_pci_bridge_class_init,
|
.class_init = pbm_pci_bridge_class_init,
|
||||||
|
.instance_size = sizeof(PBMPCIBridge),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
|
static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
|
||||||
|
|
Loading…
Reference in New Issue