diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index 5cf7b84c79..b9f0b0d06e 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -35,6 +35,7 @@ #include "sysemu/sysemu.h" #include "hw/devices.h" #include "hw/boards.h" +#include "hw/misc/unimp.h" #include "exec/address-spaces.h" #include "hw/char/xilinx_uartlite.h" @@ -47,6 +48,7 @@ #define MEMORY_BASEADDR 0x90000000 #define FLASH_BASEADDR 0xa0000000 +#define GPIO_BASEADDR 0x81400000 #define INTC_BASEADDR 0x81800000 #define TIMER_BASEADDR 0x83c00000 #define UARTLITE_BASEADDR 0x84000000 @@ -122,6 +124,8 @@ petalogix_s3adsp1800_init(MachineState *machine) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]); + create_unimplemented_device("gpio", GPIO_BASEADDR, 0x10000); + microblaze_load_kernel(cpu, ddr_base, ram_size, machine->initrd_filename, BINARY_DEVICE_TREE_FILE, diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index 9b546a2c18..5596cd5485 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -202,7 +202,11 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp) (cpu->cfg.use_barrel ? PVR2_USE_BARREL_MASK : 0) | (cpu->cfg.use_div ? PVR2_USE_DIV_MASK : 0) | (cpu->cfg.use_msr_instr ? PVR2_USE_MSR_INSTR : 0) | - (cpu->cfg.use_pcmp_instr ? PVR2_USE_PCMP_INSTR : 0); + (cpu->cfg.use_pcmp_instr ? PVR2_USE_PCMP_INSTR : 0) | + (cpu->cfg.dopb_bus_exception ? + PVR2_DOPB_BUS_EXC_MASK : 0) | + (cpu->cfg.iopb_bus_exception ? + PVR2_IOPB_BUS_EXC_MASK : 0); env->pvr.regs[5] |= cpu->cfg.dcache_writeback ? PVR5_DCACHE_WRITEBACK_MASK : 0; @@ -265,6 +269,12 @@ static Property mb_properties[] = { DEFINE_PROP_BOOL("dcache-writeback", MicroBlazeCPU, cfg.dcache_writeback, false), DEFINE_PROP_BOOL("endianness", MicroBlazeCPU, cfg.endi, false), + /* Enables bus exceptions on failed data accesses (load/stores). */ + DEFINE_PROP_BOOL("dopb-bus-exception", MicroBlazeCPU, + cfg.dopb_bus_exception, false), + /* Enables bus exceptions on failed instruction fetches. */ + DEFINE_PROP_BOOL("iopb-bus-exception", MicroBlazeCPU, + cfg.iopb_bus_exception, false), DEFINE_PROP_STRING("version", MicroBlazeCPU, cfg.version), DEFINE_PROP_UINT8("pvr", MicroBlazeCPU, cfg.pvr, C_PVR_FULL), DEFINE_PROP_END_OF_LIST(), @@ -297,7 +307,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data) #ifdef CONFIG_USER_ONLY cc->handle_mmu_fault = mb_cpu_handle_mmu_fault; #else - cc->do_unassigned_access = mb_cpu_unassigned_access; + cc->do_transaction_failed = mb_cpu_transaction_failed; cc->get_phys_page_debug = mb_cpu_get_phys_page_debug; #endif dc->vmsd = &vmstate_mb_cpu; diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 3c4e0ba80a..792bbc97c7 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -308,6 +308,8 @@ struct MicroBlazeCPU { bool use_mmu; bool dcache_writeback; bool endi; + bool dopb_bus_exception; + bool iopb_bus_exception; char *version; uint8_t pvr; } cfg; @@ -388,9 +390,10 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc, } #if !defined(CONFIG_USER_ONLY) -void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr, - bool is_write, bool is_exec, int is_asi, - unsigned size); +void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, + unsigned size, MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr); #endif #endif diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c index 7cdbbcccae..e23dcfdc20 100644 --- a/target/microblaze/op_helper.c +++ b/target/microblaze/op_helper.c @@ -486,26 +486,28 @@ void helper_mmu_write(CPUMBState *env, uint32_t ext, uint32_t rn, uint32_t v) mmu_write(env, ext, rn, v); } -void mb_cpu_unassigned_access(CPUState *cs, hwaddr addr, - bool is_write, bool is_exec, int is_asi, - unsigned size) +void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, + unsigned size, MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr) { MicroBlazeCPU *cpu; CPUMBState *env; - - qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", - addr, is_write ? 1 : 0, is_exec ? 1 : 0); - if (cs == NULL) { - return; - } + qemu_log_mask(CPU_LOG_INT, "Transaction failed: vaddr 0x%" VADDR_PRIx + " physaddr 0x" TARGET_FMT_plx " size %d access type %s\n", + addr, physaddr, size, + access_type == MMU_INST_FETCH ? "INST_FETCH" : + (access_type == MMU_DATA_LOAD ? "DATA_LOAD" : "DATA_STORE")); cpu = MICROBLAZE_CPU(cs); env = &cpu->env; + + cpu_restore_state(cs, retaddr, true); if (!(env->sregs[SR_MSR] & MSR_EE)) { return; } env->sregs[SR_EAR] = addr; - if (is_exec) { + if (access_type == MMU_INST_FETCH) { if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) { env->sregs[SR_ESR] = ESR_EC_INSN_BUS; helper_raise_exception(env, EXCP_HW_EXCP);