#include "target/ppc/cpu.h"
#include "qapi/error.h"
#include "qemu/log.h"
+#include "hw/isa/isa.h"
#include "hw/ppc/pnv.h"
#include "hw/ppc/pnv_lpc.h"
/* XXX Check for magic bits at the top, addr size etc... */
unsigned int sz = (cmd & ECCB_CTL_SZ_MASK) >> ECCB_CTL_SZ_LSH;
uint32_t opb_addr = cmd & ECCB_CTL_ADDR_MASK;
- uint8_t data[4];
+ uint8_t data[8];
bool success;
+ if (sz > sizeof(data)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ECCB: invalid operation at @0x%08x size %d\n", opb_addr, sz);
+ return;
+ }
+
if (cmd & ECCB_CTL_READ) {
success = opb_read(lpc, opb_addr, data, sz);
if (success) {
}
}
-qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type,
- int nirqs)
+ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
{
+ Error *local_err = NULL;
+ ISABus *isa_bus;
+ qemu_irq *irqs;
+ qemu_irq_handler handler;
+
+ /* let isa_bus_new() create its own bridge on SysBus otherwise
+ * devices speficied on the command line won't find the bus and
+ * will fail to create.
+ */
+ isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return NULL;
+ }
+
/* Not all variants have a working serial irq decoder. If not,
* handling of LPC interrupts becomes a platform issue (some
* platforms have a CPLD to do it).
*/
- if (chip_type == PNV_CHIP_POWER8NVL) {
- return qemu_allocate_irqs(pnv_lpc_isa_irq_handler, lpc, nirqs);
+ if (use_cpld) {
+ handler = pnv_lpc_isa_irq_handler_cpld;
} else {
- return qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, lpc, nirqs);
+ handler = pnv_lpc_isa_irq_handler;
}
+
+ irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS);
+
+ isa_bus_irqs(isa_bus, irqs);
+ return isa_bus;
}