/* Returns 16-bit values from mem array. Big endian version. * * STATISTICS OK (only used for cpu_access, that is architectural access) */ uint16_t eval_mem16 (oraddr_t memaddr, int *breakpoint) { uint16_t temp; oraddr_t phys_memaddr; if (config.sim.mprofile) mprofile (memaddr, MPROF_16 | MPROF_READ); if (memaddr & 1) { except_handle (EXCEPT_ALIGN, memaddr); return 0; } phys_memaddr = dmmu_translate (memaddr, 0); if (except_pending) return 0; if (config.pcu.enabled) pcu_count_event(SPR_PCMR_LA); if (config.debug.enabled) *breakpoint += check_debug_unit (DebugLoadAddress, memaddr); if (config.dc.enabled) temp = dc_simulate_read (phys_memaddr, memaddr, 2); else temp = evalsim_mem16 (phys_memaddr, memaddr); if (config.debug.enabled) *breakpoint += check_debug_unit (DebugLoadData, temp); return temp; }
/* WARNING: If this is called during a simulated instruction (ie. from a read/ * write mem callback), the interrupt will be delivered after the instruction * has finished executeing */ void report_interrupt (int line) { uint32_t lmask = 1 << line; /* Disable doze and sleep mode */ cpu_state.sprs[SPR_PMR] &= ~(SPR_PMR_DME | SPR_PMR_SME); /* If PIC is disabled, don't set any register, just raise EXCEPT_INT */ if (!config.pic.enabled) { if (cpu_state.sprs[SPR_SR] & SPR_SR_IEE) except_handle (EXCEPT_INT, cpu_state.sprs[SPR_EEAR_BASE]); return; } if (cpu_state.pic_lines & lmask) { /* No edge occured, warn about performance penalty and exit */ fprintf (stderr, "Warning: Int line %d did not change state\n", line); return; } cpu_state.pic_lines |= lmask; cpu_state.sprs[SPR_PICSR] |= lmask; if ((cpu_state.sprs[SPR_PICMR] & lmask) || line < 2) if (cpu_state.sprs[SPR_SR] & SPR_SR_IEE) SCHED_ADD (pic_rep_int, NULL, 0); }
/* Handles the reporting of an interrupt if it had to be delayed */ static void pic_rep_int (void *dat) { if (cpu_state.sprs[SPR_PICSR]) { except_handle (EXCEPT_INT, cpu_state.sprs[SPR_EEAR_BASE]); } }
/*! Raises a timer exception */ static void tick_raise_except (void *dat) { cpu_state.sprs[SPR_TTMR] |= SPR_TTMR_IP; /* Reschedule unconditionally, since we have to raise the exception until * TTMR_IP has been cleared */ sched_next_insn (tick_raise_except, NULL); /* be sure not to issue a timer exception if an exception occured before it */ if (cpu_state.sprs[SPR_SR] & SPR_SR_TEE) { except_handle (EXCEPT_TICK, cpu_state.sprs[SPR_EEAR_BASE]); } }
/* For cpu accesses * * NOTE: This function _is_ only called from set_mem8 below and * dc_simulate_write. _Don't_ call it from anywere else. */ void setsim_mem8 (oraddr_t memaddr, oraddr_t vaddr, uint8_t value) { struct dev_memarea *mem; if ((mem = verify_memoryarea (memaddr))) { cur_vadd = vaddr; runtime.sim.mem_cycles += mem->ops.delayw; mem->ops.writefunc8 (memaddr & mem->size_mask, value, mem->ops.write_dat8); } else { if (config.sim.report_mem_errs) { PRINTF ("EXCEPTION: write out of memory (8-bit access to %" PRIxADDR ")\n", memaddr); } except_handle (EXCEPT_BUSERR, vaddr); } }
void set_mem16 (oraddr_t memaddr, uint16_t value, int *breakpoint) { oraddr_t phys_memaddr; if (config.sim.mprofile) mprofile (memaddr, MPROF_16 | MPROF_WRITE); if (memaddr & 1) { except_handle (EXCEPT_ALIGN, memaddr); return; } phys_memaddr = dmmu_translate (memaddr, 1);; /* If we produced exception don't set anything */ if (except_pending) return; if (config.pcu.enabled) pcu_count_event(SPR_PCMR_SA); if (config.debug.enabled) { *breakpoint += check_debug_unit (DebugStoreAddress, memaddr); /* 28/05/01 CZ */ *breakpoint += check_debug_unit (DebugStoreData, value); } if (config.dc.enabled) dc_simulate_write (phys_memaddr, memaddr, value, 2); else setsim_mem16 (phys_memaddr, memaddr, value); if (cur_area && cur_area->log) fprintf (cur_area->log, "[%" PRIxADDR "] -> write %04" PRIx16 "\n", memaddr, value); }
/* For cpu accesses * * NOTE: This function _is_ only called from eval_mem8 below and * {i,d}c_simulate_read. _Don't_ call it from anywere else. */ uint8_t evalsim_mem8 (oraddr_t memaddr, oraddr_t vaddr) { struct dev_memarea *mem; if ((mem = verify_memoryarea (memaddr))) { runtime.sim.mem_cycles += mem->ops.delayr; return mem->ops.readfunc8 (memaddr & mem->size_mask, mem->ops.read_dat8); } else { if (config.sim.report_mem_errs) { PRINTF ("EXCEPTION: read out of memory (8-bit access to %" PRIxADDR ")\n", memaddr); } except_handle (EXCEPT_BUSERR, vaddr); } return 0; }
static void set_mem_32_inv (oraddr_t memaddr, uint32_t val, void *dat) { except_handle (EXCEPT_BUSERR, cur_vadd); }
static uint32_t eval_mem_32_inv (oraddr_t memaddr, void *dat) { except_handle (EXCEPT_BUSERR, cur_vadd); return 0; }