Ejemplo n.º 1
0
Archivo: xh.c Proyecto: machinaut/rhype
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;
}
Ejemplo n.º 2
0
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);
}