static void bfin_mmr_invalid (struct hw *me, address_word addr, unsigned nr_bytes, bool write, bool missing) { SIM_CPU *cpu = hw_system_cpu (me); const char *rw = write ? "write" : "read"; const char *reason = missing ? "no such register" : (addr & 3) ? "must be 32-bit aligned" : "invalid length"; /* Only throw a fit if the cpu is doing the access. DMA/GDB simply go unnoticed. Not exactly hardware behavior, but close enough. */ if (!cpu) { sim_io_eprintf (hw_system (me), "%s: invalid MMR %s at %#x length %u: %s\n", hw_path (me), rw, addr, nr_bytes, reason); return; } HW_TRACE ((me, "invalid MMR %s at %#x length %u: %s", rw, addr, nr_bytes, reason)); /* XXX: is this what hardware does ? What about priority of unaligned vs wrong length vs missing register ? What about system-vs-core ? */ /* XXX: We should move this addr check to a model property so we get the same behavior regardless of where we map the model. */ if (addr >= BFIN_CORE_MMR_BASE) /* XXX: This should be setting up CPLB fault addrs ? */ mmu_process_fault (cpu, addr, write, false, false, true); else /* XXX: Newer parts set up an interrupt from EBIU and program EBIU_ERRADDR with the address. */ cec_hwerr (cpu, HWERR_SYSTEM_MMR); }
static void bfin_mmr_invalid (struct hw *me, SIM_CPU *cpu, address_word addr, unsigned nr_bytes, bool write) { if (!cpu) cpu = hw_system_cpu (me); /* Only throw a fit if the cpu is doing the access. DMA/GDB simply go unnoticed. Not exactly hardware behavior, but close enough. */ if (!cpu) { sim_io_eprintf (hw_system (me), "%s: invalid MMR access @ %#x\n", hw_path (me), addr); return; } HW_TRACE ((me, "invalid MMR %s to 0x%08lx length %u", write ? "write" : "read", (unsigned long) addr, nr_bytes)); /* XXX: is this what hardware does ? */ if (addr >= BFIN_CORE_MMR_BASE) /* XXX: This should be setting up CPLB fault addrs ? */ mmu_process_fault (cpu, addr, write, false, false, true); else /* XXX: Newer parts set up an interrupt from EBIU and program EBIU_ERRADDR with the address. */ cec_hwerr (cpu, HWERR_SYSTEM_MMR); }