示例#1
0
文件: pht.c 项目: narke/Einherjar.tmp
/** Try to find PTE for faulting address
 *
 * @param as       Address space.
 * @param badvaddr Faulting virtual address.
 * @param access   Access mode that caused the fault.
 * @param istate   Pointer to interrupted state.
 *
 * @return PTE on success, NULL otherwise.
 *
 */
static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    istate_t *istate)
{
	/*
	 * Check if the mapping exists in page tables.
	 */
	pte_t *pte = page_mapping_find(as, badvaddr, true);
	if ((pte) && (pte->present)) {
		/*
		 * Mapping found in page tables.
		 * Immediately succeed.
		 */
		return pte;
	}
	/*
	 * Mapping not found in page tables.
	 * Resort to higher-level page fault handler.
	 */
	if (as_page_fault(badvaddr, access, istate) == AS_PF_OK) {
		/*
		 * The higher-level page fault handler succeeded,
		 * The mapping ought to be in place.
		 */
		pte = page_mapping_find(as, badvaddr, true);
		ASSERT((pte) && (pte->present));
		return pte;
	}

	return NULL;
}
示例#2
0
/** Try to find PTE for faulting address.
 *
 * @param badvaddr Faulting virtual address.
 * @param access   Access mode that caused the fault.
 * @param istate   Pointer to interrupted state.
 * @param pfrc     Pointer to variable where as_page_fault()
 *                 return code will be stored.
 *
 * @return PTE on success, NULL otherwise.
 *
 */
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access,
    istate_t *istate, int *pfrc)
{
	entry_hi_t hi;
	hi.value = cp0_entry_hi_read();
	
	/*
	 * Handler cannot succeed if the ASIDs don't match.
	 */
	if (hi.asid != AS->asid) {
		printf("EntryHi.asid=%d, AS->asid=%d\n", hi.asid, AS->asid);
		return NULL;
	}
	
	/*
	 * Check if the mapping exists in page tables.
	 */
	pte_t *pte = page_mapping_find(AS, badvaddr, true);
	if ((pte) && (pte->p) && ((pte->w) || (access != PF_ACCESS_WRITE))) {
		/*
		 * Mapping found in page tables.
		 * Immediately succeed.
		 */
		return pte;
	} else {
		int rc;
		
		/*
		 * Mapping not found in page tables.
		 * Resort to higher-level page fault handler.
		 */
		switch (rc = as_page_fault(badvaddr, access, istate)) {
		case AS_PF_OK:
			/*
			 * The higher-level page fault handler succeeded,
			 * The mapping ought to be in place.
			 */
			pte = page_mapping_find(AS, badvaddr, true);
			ASSERT(pte);
			ASSERT(pte->p);
			ASSERT((pte->w) || (access != PF_ACCESS_WRITE));
			return pte;
		case AS_PF_DEFER:
			*pfrc = AS_PF_DEFER;
			return NULL;
		case AS_PF_FAULT:
			*pfrc = AS_PF_FAULT;
			return NULL;
		default:
			panic("Unexpected return code (%d).", rc);
		}
	}
}
示例#3
0
/** Try to find PTE for faulting address
 *
 * @param as       Address space.
 * @param badvaddr Faulting virtual address.
 * @param access   Access mode that caused the fault.
 * @param istate   Pointer to interrupted state.
 * @param pfrc     Pointer to variable where as_page_fault() return code
 *                 will be stored.
 *
 * @return PTE on success, NULL otherwise.
 *
 */
static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    istate_t *istate, int *pfrc)
{
	/*
	 * Check if the mapping exists in page tables.
	 */
	pte_t *pte = page_mapping_find(as, badvaddr, true);
	if ((pte) && (pte->present)) {
		/*
		 * Mapping found in page tables.
		 * Immediately succeed.
		 */
		return pte;
	} else {
		/*
		 * Mapping not found in page tables.
		 * Resort to higher-level page fault handler.
		 */
		int rc = as_page_fault(badvaddr, access, istate);
		switch (rc) {
		case AS_PF_OK:
			/*
			 * The higher-level page fault handler succeeded,
			 * The mapping ought to be in place.
			 */
			pte = page_mapping_find(as, badvaddr, true);
			ASSERT((pte) && (pte->present));
			*pfrc = 0;
			return pte;
		case AS_PF_DEFER:
			*pfrc = rc;
			return NULL;
		case AS_PF_FAULT:
			*pfrc = rc;
			return NULL;
		default:
			panic("Unexpected rc (%d).", rc);
		}
	}
}
示例#4
0
/** Try to find PTE for faulting address.
 *
 * @param badvaddr Faulting virtual address.
 * @param access   Access mode that caused the fault.
 * @param istate   Pointer to interrupted state.
 *
 * @return PTE on success, NULL otherwise.
 *
 */
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access,
    istate_t *istate)
{
	entry_hi_t hi;
	hi.value = cp0_entry_hi_read();
	
	ASSERT(hi.asid == AS->asid);
	
	/*
	 * Check if the mapping exists in page tables.
	 */
	pte_t *pte = page_mapping_find(AS, badvaddr, true);
	if ((pte) && (pte->p) && ((pte->w) || (access != PF_ACCESS_WRITE))) {
		/*
		 * Mapping found in page tables.
		 * Immediately succeed.
		 */
		return pte;
	}

	/*
	 * Mapping not found in page tables.
	 * Resort to higher-level page fault handler.
	 */
	if (as_page_fault(badvaddr, access, istate) == AS_PF_OK) {
		/*
		 * The higher-level page fault handler succeeded,
		 * The mapping ought to be in place.
		 */
		pte = page_mapping_find(AS, badvaddr, true);
		ASSERT(pte);
		ASSERT(pte->p);
		ASSERT((pte->w) || (access != PF_ACCESS_WRITE));
		return pte;
	}

	return NULL;
}