예제 #1
0
파일: fault.c 프로젝트: LastRitter/GridOS
static void refill_tbl_to(struct km_walk_ctx * ctx, unsigned int asid, int write, int pos)
{	
	unsigned long entry, oldl1, oldl2;
	unsigned long G_FLAG;
	int idx;
	int oldpid;

	/* Just test ASID consistency: Current ASID must equal to Given ASID, kernel process do not obay this rule. */
	oldpid = read_c0_entryhi();

	/* Entry HI */	
	asid = asid & CPU_PAGE_FALG_ASID_MASK;
	entry = get_vpn2(ctx->current_virtual_address);
	entry |= asid;
	write_c0_entryhi(entry);
	mtc0_tlbw_hazard();
	tlb_probe();
	tlb_probe_hazard();
	idx = read_c0_index();

	oldl1 = read_c0_entrylo0();
	oldl2 = read_c0_entrylo1();
	/* Add the G_FLAG if ASID == 0, because the entry is from kernel and shared by all process */
	G_FLAG = (ctx->mem == &kp_get_system()->mem_ctx)? 1 : 0;

	/* Entry Low0 and Low1 */
	WRITE_LO;

	/* Write by type, the write is random if the TLB entry is flushed for R/W flags changing */
	mtc0_tlbw_hazard();
	if (unlikely(idx < 0))
		tlb_write_random();
	else
	{
		if (write == 2)
		{
			printk("Write is forced index for %x, pos %d, idx %d,asid %d, %x %x.\n", ctx->current_virtual_address, pos, idx, asid, oldl1, oldl2);
		}
		
		tlb_write_indexed();
	}
	tlbw_use_hazard();

	/* Sanity: Just test ASID consistency: Current ASID must equal to Given ASID, kernel process do not obey this rule. */
	if ((oldpid & 0xff) != (asid & 0xff) && asid != 0/*kernel asid*/)
 		printk("Why old = %x, asid = %x. ", oldpid, asid);
}
asmlinkage void xtlb_refill_debug(struct pt_regs *regs)
{
	unsigned long addr;
	pgd_t *pgd;
	pmd_t *pmd;
	pte_t *pte;

	addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1);
	pgd = pgd_offset(current->active_mm, addr);
	pmd = pmd_offset(pgd, addr);
	pte = pte_offset(pmd, addr);

	write_c0_entrylo0(pte_val(pte[0]) >> 6);
	write_c0_entrylo1(pte_val(pte[1]) >> 6);
	__asm__ __volatile__("nop;nop;nop");

	tlb_write_random();
}
예제 #3
0
파일: fault.c 프로젝트: LastRitter/GridOS
/**
	@brief Refill the TLB entry

	@note
		Have to in interrupt disabled
*/
static void refill_tbl(struct km_walk_ctx * ctx)
{
	unsigned char asid;
	unsigned long entry;
	unsigned long G_FLAG;

	/* Entry HI */
	asid = ctx->mem->asid & CPU_PAGE_FALG_ASID_MASK;
	entry = get_vpn2(ctx->current_virtual_address);
	entry |= asid;
	write_c0_entryhi(entry);

	/* Add the G_FLAG if ASID == 0, because the entry is from kernel and shared by all process */
	G_FLAG = (ctx->mem == &kp_get_system()->mem_ctx)? 1 : 0;

	/* Entry Low0 and Low1 */
	WRITE_LO;
	
	/* Write by type */
	mtc0_tlbw_hazard();
	tlb_write_random();
	tlbw_use_hazard();
}