📄 interrupts.c
字号:
(unsigned long)cia, (unsigned long)DAR, (unsigned long)DSISR)); cia = perform_oea_interrupt(processor, cia, 0x00600, 0, 0, 0, 0); cpu_restart(processor, cia); default: error("internal error - alignment_interrupt - bad switch"); }}INLINE_INTERRUPTS\(void)program_interrupt(cpu *processor, unsigned_word cia, program_interrupt_reasons reason){ switch (CURRENT_ENVIRONMENT) { case USER_ENVIRONMENT: case VIRTUAL_ENVIRONMENT: switch (reason) { case floating_point_enabled_program_interrupt: cpu_error(processor, cia, "program interrupt - %s", "floating point enabled"); break; case illegal_instruction_program_interrupt: cpu_error(processor, cia, "program interrupt - %s", "illegal instruction"); break; case privileged_instruction_program_interrupt: cpu_error(processor, cia, "program interrupt - %s", "privileged instruction"); break; case trap_program_interrupt: cpu_error(processor, cia, "program interrupt - %s", "trap"); break; case optional_instruction_program_interrupt: cpu_error(processor, cia, "program interrupt - %s", "illegal instruction (optional instruction not supported)"); break; case mpc860c0_instruction_program_interrupt: cpu_error(processor, cia, "program interrupt - %s", "problematic branch detected, see MPC860 C0 errata"); break; default: error("internal error - program_interrupt - reason %d not implemented", reason); } case OPERATING_ENVIRONMENT: { msreg srr1_set; switch (reason) { case floating_point_enabled_program_interrupt: srr1_set = srr1_floating_point_enabled; break; case optional_instruction_program_interrupt: case illegal_instruction_program_interrupt: srr1_set = srr1_illegal_instruction; break; case privileged_instruction_program_interrupt: srr1_set = srr1_priviliged_instruction; break; case trap_program_interrupt: srr1_set = srr1_trap; break; case mpc860c0_instruction_program_interrupt: srr1_set = 0; cpu_error(processor, cia, "program interrupt - %s", "problematic branch detected, see MPC860 C0 errata"); break; default: srr1_set = 0; error("internal error - program_interrupt - reason %d not implemented", reason); break; } TRACE(trace_interrupts, ("program interrupt - cia=0x%lx SRR1|=0x%lx\n", (unsigned long)cia, (unsigned long)srr1_set)); cia = perform_oea_interrupt(processor, cia, 0x00700, 0, 0, 0, srr1_set); cpu_restart(processor, cia); } default: error("internal error - program_interrupt - bad switch"); }}INLINE_INTERRUPTS\(void)floating_point_unavailable_interrupt(cpu *processor, unsigned_word cia){ switch (CURRENT_ENVIRONMENT) { case USER_ENVIRONMENT: case VIRTUAL_ENVIRONMENT: cpu_error(processor, cia, "floating-point unavailable interrupt"); case OPERATING_ENVIRONMENT: TRACE(trace_interrupts, ("floating-point unavailable interrupt - cia=0x%lx\n", (unsigned long)cia)); cia = perform_oea_interrupt(processor, cia, 0x00800, 0, 0, 0, 0); cpu_restart(processor, cia); default: error("internal error - floating_point_unavailable_interrupt - bad switch"); }}INLINE_INTERRUPTS\(void)system_call_interrupt(cpu *processor, unsigned_word cia){ TRACE(trace_interrupts, ("system-call interrupt - cia=0x%lx\n", (unsigned long)cia)); switch (CURRENT_ENVIRONMENT) { case USER_ENVIRONMENT: case VIRTUAL_ENVIRONMENT: os_emul_system_call(processor, cia); cpu_restart(processor, cia+4); case OPERATING_ENVIRONMENT: cia = perform_oea_interrupt(processor, cia+4, 0x00c00, 0, 0, 0, 0); cpu_restart(processor, cia); default: error("internal error - system_call_interrupt - bad switch"); }}INLINE_INTERRUPTS\(void)floating_point_assist_interrupt(cpu *processor, unsigned_word cia){ switch (CURRENT_ENVIRONMENT) { case USER_ENVIRONMENT: case VIRTUAL_ENVIRONMENT: cpu_error(processor, cia, "floating-point assist interrupt"); case OPERATING_ENVIRONMENT: TRACE(trace_interrupts, ("floating-point assist interrupt - cia=0x%lx\n", (unsigned long)cia)); cia = perform_oea_interrupt(processor, cia, 0x00e00, 0, 0, 0, 0); cpu_restart(processor, cia); default: error("internal error - floating_point_assist_interrupt - bad switch"); }}/* handle an externally generated event or an interrupt that has just been enabled through changes to the MSR. */STATIC_INLINE_INTERRUPTS\(void)deliver_hardware_interrupt(void *data){ cpu *processor = (cpu*)data; interrupts *ints = cpu_interrupts(processor); ints->delivery_scheduled = NULL; if ((cpu_registers(processor)->msr & (msr_floating_point_exception_mode_0 | msr_floating_point_exception_mode_1)) && cpu_registers(processor)->fpscr & fpscr_fex) { msreg srr1_set = srr1_floating_point_enabled | srr1_subsequent_instruction; unsigned_word cia = cpu_get_program_counter(processor); unsigned_word nia = perform_oea_interrupt(processor, cia, 0x00700, 0, 0, 0, srr1_set); cpu_set_program_counter(processor, nia); } else if (cpu_registers(processor)->msr & msr_external_interrupt_enable) { /* external interrupts have a high priority and remain pending */ if (ints->pending_interrupts & external_interrupt_pending) { unsigned_word cia = cpu_get_program_counter(processor); unsigned_word nia = perform_oea_interrupt(processor, cia, 0x00500, 0, 0, 0, 0); TRACE(trace_interrupts, ("external interrupt - cia=0x%lx\n", (unsigned long)cia)); cpu_set_program_counter(processor, nia); } /* decrementer interrupts have a lower priority and are once only */ else if (ints->pending_interrupts & decrementer_interrupt_pending) { unsigned_word cia = cpu_get_program_counter(processor); unsigned_word nia = perform_oea_interrupt(processor, cia, 0x00900, 0, 0, 0, 0); TRACE(trace_interrupts, ("decrementer interrupt - cia 0x%lx, time %ld\n", (unsigned long)cia, (unsigned long)event_queue_time(psim_event_queue(cpu_system(processor))) )); cpu_set_program_counter(processor, nia); ints->pending_interrupts &= ~decrementer_interrupt_pending; } }}STATIC_INLINE_INTERRUPTS\(void)schedule_hardware_interrupt_delivery(cpu *processor) { interrupts *ints = cpu_interrupts(processor); if (ints->delivery_scheduled == NULL) { ints->delivery_scheduled = event_queue_schedule(psim_event_queue(cpu_system(processor)), 0, deliver_hardware_interrupt, processor); }}INLINE_INTERRUPTS\(void)check_masked_interrupts(cpu *processor){ if (((cpu_registers(processor)->msr & (msr_floating_point_exception_mode_0 | msr_floating_point_exception_mode_1)) && cpu_registers(processor)->fpscr & fpscr_fex) || ((cpu_registers(processor)->msr & msr_external_interrupt_enable) && (cpu_interrupts(processor)->pending_interrupts))) schedule_hardware_interrupt_delivery(processor);}INLINE_INTERRUPTS\(void)decrementer_interrupt(cpu *processor){ interrupts *ints = cpu_interrupts(processor); ints->pending_interrupts |= decrementer_interrupt_pending; if (cpu_registers(processor)->msr & msr_external_interrupt_enable) { schedule_hardware_interrupt_delivery(processor); }}INLINE_INTERRUPTS\(void)external_interrupt(cpu *processor, int is_asserted){ interrupts *ints = cpu_interrupts(processor); if (is_asserted) { if (!(ints->pending_interrupts & external_interrupt_pending)) { ints->pending_interrupts |= external_interrupt_pending; if (cpu_registers(processor)->msr & msr_external_interrupt_enable) schedule_hardware_interrupt_delivery(processor); } else { /* check that we haven't missed out on a chance to deliver an interrupt */ ASSERT(!(cpu_registers(processor)->msr & msr_external_interrupt_enable)); } } else { ints->pending_interrupts &= ~external_interrupt_pending; }}#endif /* _INTERRUPTS_C_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -