psim_init(psim *system) { int cpu_nr; /* scrub the monitor */ mon_init(system->monitor, system->nr_cpus); /* trash any pending events */ event_queue_init(system->events); /* if needed, schedule a halt event. FIXME - In the future this will be replaced by a more generic change to psim_command(). A new command `schedule NNN halt' being added. */ if (tree_find_property(system->devices, "/openprom/options/max-iterations")) { event_queue_schedule(system->events, tree_find_integer_property(system->devices, "/openprom/options/max-iterations") - 2, psim_max_iterations_exceeded, system); } /* scrub all the cpus */ for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++) cpu_init(system->processors[cpu_nr]); /* init all the devices (which updates the cpus) */ tree_init(system->devices, system); /* and the emulation (which needs an initialized device tree) */ os_emul_init(system->os_emulation, system->nr_cpus); /* now sync each cpu against the initialized state of its registers */ for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++) { cpu *processor = system->processors[cpu_nr]; cpu_synchronize_context(processor, cpu_get_program_counter(processor)); cpu_page_tlb_invalidate_all(processor); } /* force loop to start with first cpu */ system->last_cpu = -1; }
perform_oea_interrupt(cpu *processor, unsigned_word cia, unsigned_word vector_offset, msreg msr_clear, msreg msr_set, msreg srr1_clear, msreg srr1_set) { msreg old_msr = MSR; msreg new_msr = interrupt_msr(old_msr, msr_clear, msr_set); unsigned_word nia; if (!(old_msr & msr_recoverable_interrupt)) error("perform_oea_interrupt() recoverable_interrupt bit clear, cia=0x%x, msr=0x%x\n", cia, old_msr); SRR0 = (spreg)(cia); SRR1 = interrupt_srr1(old_msr, srr1_clear, srr1_set); MSR = new_msr; nia = interrupt_base_ea(new_msr) + vector_offset; cpu_synchronize_context(processor); return nia; }