static uval xh_handle_tlb_miss(uval ex, uval *regs) { uval vaddr = (uval)&_text_start; uval size = (uval)_end - vaddr; uval eaddr = 0; uval raddr = 0; uval offset; uval8 l = 1; uval8 ls = SELECT_LG; struct partition_info *pi = &pinfo[1]; uval lp = get_log_pgsize(pi, l, ls); uval pgsize = 1 << lp; if (ex == 0x400) { /* ISI */ eaddr = regs[XHR_SRR0]; } else { /* DSI */ eaddr = regs[XHR_DAR]; } #ifdef DEBUG hprintf("xh_handle_tlb_miss(): " "eaddr 0x%lx srr0 0x%lx srr1 0x%lx\n", eaddr, regs[XHR_SRR0], regs[XHR_SRR1]); #endif for (offset = 0; offset < size; offset += pgsize) { if ((eaddr >= (vaddr + offset)) && (eaddr < (vaddr + offset + pgsize))) { return tlb_enter(pi, vaddr + offset, raddr + offset, PAGE_WIMG_M, l, ls); } } return 1; }
void cpu_hatch(struct cpu_info *ci) { struct pmap_tlb_info * const ti = ci->ci_tlb_info; /* * Invalidate all the TLB enties (even wired ones) and then reserve * space for the wired TLB entries. */ mips3_cp0_wired_write(0); tlb_invalidate_all(); mips3_cp0_wired_write(ti->ti_wired); /* * Setup HWRENA and USERLOCAL COP0 registers (MIPSxxR2). */ cpu_hwrena_setup(); /* * If we are using register zero relative addressing to access cpu_info * in the exception vectors, enter that mapping into TLB now. */ if (ci->ci_tlb_slot >= 0) { const uint32_t tlb_lo = MIPS3_PG_G|MIPS3_PG_V | mips3_paddr_to_tlbpfn((vaddr_t)ci); tlb_enter(ci->ci_tlb_slot, -PAGE_SIZE, tlb_lo); } /* * Flush the icache just be sure. */ mips_icache_sync_all(); /* * Let this CPU do its own initialization (for things that have to be * done on the local CPU). */ (*mips_locoresw.lsw_cpu_init)(ci); /* * Announce we are hatched */ CPUSET_ADD(cpus_hatched, cpu_index(ci)); /* * Now wait to be set free! */ while (! CPUSET_HAS_P(cpus_running, cpu_index(ci))) { /* spin, spin, spin */ } /* * initialize the MIPS count/compare clock */ mips3_cp0_count_write(ci->ci_data.cpu_cc_skew); KASSERT(ci->ci_cycles_per_hz != 0); ci->ci_next_cp0_clk_intr = ci->ci_data.cpu_cc_skew + ci->ci_cycles_per_hz; mips3_cp0_compare_write(ci->ci_next_cp0_clk_intr); ci->ci_data.cpu_cc_skew = 0; /* * Let this CPU do its own post-running initialization * (for things that have to be done on the local CPU). */ (*mips_locoresw.lsw_cpu_run)(ci); /* * Now turn on interrupts. */ spl0(); /* * And do a tail call to idle_loop */ idle_loop(NULL); }