void frv_sim_engine_halt_hook (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia) { int i; if (current_cpu != NULL) CIA_SET (current_cpu, cia); /* Invalidate the insn and data caches of all cpus. */ for (i = 0; i < MAX_NR_PROCESSORS; ++i) { current_cpu = STATE_CPU (sd, i); frv_cache_invalidate_all (CPU_INSN_CACHE (current_cpu), 0); frv_cache_invalidate_all (CPU_DATA_CACHE (current_cpu), 1); } frv_term (sd); }
void sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus, /* ignore */ int siggnal) /* ignore */ { sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr); address_word cia = CIA_GET (cpu); while (1) { address_word nia; #if defined (ENGINE_ISSUE_PREFIX_HOOK) ENGINE_ISSUE_PREFIX_HOOK (); #endif if ((cia & 1)) { m16_instruction_word instruction_0 = IMEM16 (cia); nia = m16_idecode_issue (sd, instruction_0, cia); } else { m32_instruction_word instruction_0 = IMEM32 (cia); nia = m32_idecode_issue (sd, instruction_0, cia); } #if defined (ENGINE_ISSUE_POSTFIX_HOOK) ENGINE_ISSUE_POSTFIX_HOOK (); #endif /* Update the instruction address */ cia = nia; /* process any events */ if (sim_events_tick (sd)) { CIA_SET (CPU, cia); sim_events_process (sd); cia = CIA_GET (CPU); } } }
void sim_engine_run (SIM_DESC sd, int next_cpu_nr, /* ignore */ int nr_cpus, /* ignore */ int siggnal) /* ignore */ { sim_cia cia; sim_cpu *cpu; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); cpu = STATE_CPU (sd, 0); cia = CIA_GET (cpu); while (1) { instruction_word insn = IMEM32 (cia); cia = idecode_issue (sd, insn, cia); /* process any events */ if (sim_events_tick (sd)) { CIA_SET (cpu, cia); sim_events_process (sd); } } }
static void deliver_mn103cpu_interrupt (struct hw *me, void *data) { struct mn103cpu *controller = hw_data (me); SIM_DESC simulator = hw_system (me); sim_cpu *cpu = STATE_CPU (simulator, 0); if (controller->pending_reset) { controller->pending_reset = 0; /* need to clear all registers et.al! */ HW_TRACE ((me, "Reset!")); hw_abort (me, "Reset!"); } else if (controller->pending_nmi) { controller->pending_nmi = 0; store_word (SP - 4, CIA_GET (cpu)); store_half (SP - 8, PSW); PSW &= ~PSW_IE; SP = SP - 8; CIA_SET (cpu, 0x40000008); HW_TRACE ((me, "nmi pc=0x%08lx psw=0x%04x sp=0x%08lx", (long) CIA_GET (cpu), (unsigned) PSW, (long) SP)); } else if ((controller->pending_level < EXTRACT_PSW_LM) && (PSW & PSW_IE)) { /* Don't clear pending level. Request continues to be pending until the interrupt controller clears/changes it */ store_word (SP - 4, CIA_GET (cpu)); store_half (SP - 8, PSW); PSW &= ~PSW_IE; PSW &= ~PSW_LM; PSW |= INSERT_PSW_LM (controller->pending_level); SP = SP - 8; CIA_SET (cpu, 0x40000000 + controller->interrupt_vector[controller->pending_level]); HW_TRACE ((me, "port-out ack %d", controller->pending_level)); hw_port_event (me, ACK_PORT, controller->pending_level); HW_TRACE ((me, "int level=%d pc=0x%08lx psw=0x%04x sp=0x%08lx", controller->pending_level, (long) CIA_GET (cpu), (unsigned) PSW, (long) SP)); } if (controller->pending_level < 7) /* FIXME */ { /* As long as there is the potential need to deliver an interrupt we keep rescheduling this routine. */ if (controller->pending_handler != NULL) controller->pending_handler = hw_event_queue_schedule (me, 1, deliver_mn103cpu_interrupt, NULL); } else { /* Don't bother re-scheduling the interrupt handler as there is nothing to deliver */ controller->pending_handler = NULL; } }