* [PATCH v4 3/4] ppc440_pcix: Fix up pci config access
2021-01-04 23:14 [PATCH v4 0/4] Misc sam460ex fixes (was: Clean up sam460ex irq mapping) BALATON Zoltan via
@ 2021-01-04 23:14 ` BALATON Zoltan via
2021-01-04 23:14 ` [PATCH v4 1/4] ppc440_pcix: Improve comment for IRQ mapping BALATON Zoltan via
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: BALATON Zoltan via @ 2021-01-04 23:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Peter Maydell, f4bug, Guenter Roeck, David Gibson
This fixes a long standing issue with MorphOS booting on sam460ex
which turns out to be because of suspicious values written to PCI
config address that apparently works on real machine but caused wrong
access on this device model. This replaces a previous work around for
this with a better fix that makes it work.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/ppc440_pcix.c | 37 ++++++++++++++++++++++---------------
1 file changed, 22 insertions(+), 15 deletions(-)
diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
index 7829d3e556..91cbcd0504 100644
--- a/hw/ppc/ppc440_pcix.c
+++ b/hw/ppc/ppc440_pcix.c
@@ -449,28 +449,35 @@ static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn)
return &s->bm_as;
}
-/* The default pci_host_data_{read,write} functions in pci/pci_host.c
- * deny access to registers without bit 31 set but our clients want
- * this to work so we have to override these here */
-static void pci_host_data_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned len)
+/*
+ * Some guests on sam460ex write all kinds of garbage here such as
+ * missing enable bit and low bits set and still expect this to work
+ * (apparently it does on real hardware because these boot there) so
+ * we have to override these ops here and fix it up
+ */
+static void pci_host_config_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned len)
{
PCIHostState *s = opaque;
- pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
+
+ if (addr != 0 || len != 4) {
+ return;
+ }
+ s->config_reg = (val & 0xfffffffcULL) | (1UL << 31);
}
-static uint64_t pci_host_data_read(void *opaque,
- hwaddr addr, unsigned len)
+static uint64_t pci_host_config_read(void *opaque, hwaddr addr,
+ unsigned len)
{
PCIHostState *s = opaque;
- uint32_t val;
- val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
+ uint32_t val = s->config_reg;
+
return val;
}
-const MemoryRegionOps ppc440_pcix_host_data_ops = {
- .read = pci_host_data_read,
- .write = pci_host_data_write,
+const MemoryRegionOps ppc440_pcix_host_conf_ops = {
+ .read = pci_host_config_read,
+ .write = pci_host_config_write,
.endianness = DEVICE_LITTLE_ENDIAN,
};
@@ -497,9 +504,9 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp)
pci_setup_iommu(h->bus, ppc440_pcix_set_iommu, s);
memory_region_init(&s->container, OBJECT(s), "pci-container", PCI_ALL_SIZE);
- memory_region_init_io(&h->conf_mem, OBJECT(s), &pci_host_conf_le_ops,
+ memory_region_init_io(&h->conf_mem, OBJECT(s), &ppc440_pcix_host_conf_ops,
h, "pci-conf-idx", 4);
- memory_region_init_io(&h->data_mem, OBJECT(s), &ppc440_pcix_host_data_ops,
+ memory_region_init_io(&h->data_mem, OBJECT(s), &pci_host_data_le_ops,
h, "pci-conf-data", 4);
memory_region_init_io(&s->iomem, OBJECT(s), &pci_reg_ops, s,
"pci.reg", PPC440_REG_SIZE);
--
2.21.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 1/4] ppc440_pcix: Improve comment for IRQ mapping
2021-01-04 23:14 [PATCH v4 0/4] Misc sam460ex fixes (was: Clean up sam460ex irq mapping) BALATON Zoltan via
2021-01-04 23:14 ` [PATCH v4 3/4] ppc440_pcix: Fix up pci config access BALATON Zoltan via
@ 2021-01-04 23:14 ` BALATON Zoltan via
2021-01-04 23:44 ` Peter Maydell
2021-01-04 23:14 ` [PATCH v4 2/4] ppc440_pcix: Fix register write trace event BALATON Zoltan via
2021-01-04 23:14 ` [PATCH v4 4/4] sam460ex: Use type cast macro instead of simple cast BALATON Zoltan via
3 siblings, 1 reply; 6+ messages in thread
From: BALATON Zoltan via @ 2021-01-04 23:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Peter Maydell, f4bug, Guenter Roeck, David Gibson
The code mapping all PCI interrupts to a single CPU IRQ works but is
not trivial so document it in a comment.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/ppc440_pcix.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
index ee952314c8..eb1290ffc8 100644
--- a/hw/ppc/ppc440_pcix.c
+++ b/hw/ppc/ppc440_pcix.c
@@ -415,8 +415,15 @@ static void ppc440_pcix_reset(DeviceState *dev)
s->sts = 0;
}
-/* All pins from each slot are tied to a single board IRQ.
- * This may need further refactoring for other boards. */
+/*
+ * All four IRQ[ABCD] pins from all slots are tied to a single board
+ * IRQ, so our mapping function here maps everything to IRQ 0.
+ * The code in pci_change_irq_level() tracks the number of times
+ * the mapped IRQ is asserted and deasserted, so if multiple devices
+ * assert an IRQ at the same time the behaviour is correct.
+ *
+ * This may need further refactoring for boards that use multiple IRQ lines.
+ */
static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num)
{
trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, 0);
--
2.21.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 2/4] ppc440_pcix: Fix register write trace event
2021-01-04 23:14 [PATCH v4 0/4] Misc sam460ex fixes (was: Clean up sam460ex irq mapping) BALATON Zoltan via
2021-01-04 23:14 ` [PATCH v4 3/4] ppc440_pcix: Fix up pci config access BALATON Zoltan via
2021-01-04 23:14 ` [PATCH v4 1/4] ppc440_pcix: Improve comment for IRQ mapping BALATON Zoltan via
@ 2021-01-04 23:14 ` BALATON Zoltan via
2021-01-04 23:14 ` [PATCH v4 4/4] sam460ex: Use type cast macro instead of simple cast BALATON Zoltan via
3 siblings, 0 replies; 6+ messages in thread
From: BALATON Zoltan via @ 2021-01-04 23:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Peter Maydell, f4bug, Guenter Roeck, David Gibson
The trace event for pci_host_config_write() was also using the trace
event for read. Add corresponding trace and correct this.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
hw/ppc/ppc440_pcix.c | 2 +-
hw/ppc/trace-events | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c
index eb1290ffc8..7829d3e556 100644
--- a/hw/ppc/ppc440_pcix.c
+++ b/hw/ppc/ppc440_pcix.c
@@ -169,7 +169,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr addr,
{
struct PPC440PCIXState *s = opaque;
- trace_ppc440_pcix_reg_read(addr, val);
+ trace_ppc440_pcix_reg_write(addr, val, size);
switch (addr) {
case PCI_VENDOR_ID ... PCI_MAX_LAT:
stl_le_p(s->dev->config + addr, val);
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index ed05f2fc9a..017c48624f 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -117,3 +117,4 @@ ppc440_pcix_set_irq(int irq_num) "PCI irq %d"
ppc440_pcix_update_pim(int idx, uint64_t size, uint64_t la) "Added window %d of size=0x%" PRIx64 " to CPU=0x%" PRIx64
ppc440_pcix_update_pom(int idx, uint32_t size, uint64_t la, uint64_t pcia) "Added window %d of size=0x%x from CPU=0x%" PRIx64 " to PCI=0x%" PRIx64
ppc440_pcix_reg_read(uint64_t addr, uint32_t val) "addr 0x%" PRIx64 " = 0x%" PRIx32
+ppc440_pcix_reg_write(uint64_t addr, uint32_t val, uint32_t size) "addr 0x%" PRIx64 " = 0x%" PRIx32 " size 0x%" PRIx32
--
2.21.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v4 4/4] sam460ex: Use type cast macro instead of simple cast
2021-01-04 23:14 [PATCH v4 0/4] Misc sam460ex fixes (was: Clean up sam460ex irq mapping) BALATON Zoltan via
` (2 preceding siblings ...)
2021-01-04 23:14 ` [PATCH v4 2/4] ppc440_pcix: Fix register write trace event BALATON Zoltan via
@ 2021-01-04 23:14 ` BALATON Zoltan via
3 siblings, 0 replies; 6+ messages in thread
From: BALATON Zoltan via @ 2021-01-04 23:14 UTC (permalink / raw)
To: qemu-devel, qemu-ppc; +Cc: Peter Maydell, f4bug, Guenter Roeck, David Gibson
Use the PCI_BUS type cast macro to convert result of
qdev_get_child_bus(). Also remove the check for NULL afterwards which
should not be needed because sysbus_create_simple() uses error_abort
and PCI_BUS macro also checks its argument by default so this
shouldn't fail here.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/sam460ex.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 14e6583eb0..cc67e9c39b 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -384,11 +384,8 @@ static void sam460ex_init(MachineState *machine)
ppc460ex_pcie_init(env);
/* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */
dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec00000, uic[1][0]);
- pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
- if (!pci_bus) {
- error_report("couldn't create PCI controller!");
- exit(1);
- }
+ pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0"));
+
memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(),
0, 0x10000);
memory_region_add_subregion(get_system_memory(), 0xc08000000, isa);
--
2.21.3
^ permalink raw reply related [flat|nested] 6+ messages in thread