Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1382 → Rev 1383

/kernel/trunk/generic/src/mm/as.c
97,8 → 97,9
{
as_arch_init();
AS_KERNEL = as_create(FLAG_AS_KERNEL);
if (!AS_KERNEL)
panic("can't create kernel address space\n");
if (!AS_KERNEL)
panic("can't create kernel address space\n");
}
 
/** Create address space.
/kernel/trunk/arch/ppc32/src/mm/page.c
36,6 → 36,7
#include <arch.h>
#include <arch/types.h>
#include <arch/exception.h>
#include <align.h>
#include <config.h>
#include <print.h>
#include <symtab.h>
46,8 → 47,11
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The AS->lock must be held on entry to this function.
* The as->lock must be held on entry to this function
* if lock is true.
*
* @param as Address space.
* @param lock Lock/unlock the address space.
* @param badvaddr Faulting virtual address.
* @param istate Pointer to interrupted state.
* @param pfrc Pointer to variable where as_page_fault() return code will be stored.
54,12 → 58,12
* @return PTE on success, NULL otherwise.
*
*/
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, istate_t *istate, int *pfcr)
{
/*
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(AS, badvaddr);
pte_t *pte = page_mapping_find(as, badvaddr);
if ((pte) && (pte->p)) {
/*
* Mapping found in page tables.
73,7 → 77,7
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(AS, true);
page_table_unlock(as, lock);
switch (rc = as_page_fault(badvaddr, istate)) {
case AS_PF_OK:
/*
80,16 → 84,16
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
*/
page_table_lock(AS, true);
pte = page_mapping_find(AS, badvaddr);
page_table_lock(as, lock);
pte = page_mapping_find(as, badvaddr);
ASSERT((pte) && (pte->p));
return pte;
case AS_PF_DEFER:
page_table_lock(AS, true);
page_table_lock(as, lock);
*pfcr = rc;
return NULL;
case AS_PF_FAULT:
page_table_lock(AS, true);
page_table_lock(as, lock);
printf("Page fault.\n");
*pfcr = rc;
return NULL;
180,9 → 184,18
asid_t asid;
__address badvaddr;
pte_t *pte;
int pfcr;
as_t *as;
bool lock;
if (AS == NULL) {
as = AS_KERNEL;
lock = false;
} else {
as = AS;
lock = true;
}
if (data) {
asm volatile (
"mfdar %0\n"
191,13 → 204,13
} else
badvaddr = istate->pc;
spinlock_lock(&AS->lock);
asid = AS->asid;
spinlock_unlock(&AS->lock);
spinlock_lock(&as->lock);
asid = as->asid;
spinlock_unlock(&as->lock);
page_table_lock(AS, true);
page_table_lock(as, lock);
pte = find_mapping_and_check(badvaddr, istate, &pfcr);
pte = find_mapping_and_check(as, lock, badvaddr, istate, &pfcr);
if (!pte) {
switch (pfcr) {
case AS_PF_FAULT:
208,7 → 221,7
* The page fault came during copy_from_uspace()
* or copy_to_uspace().
*/
page_table_unlock(AS, true);
page_table_unlock(as, lock);
return;
default:
panic("Unexpected pfrc (%d)\n", pfcr);
218,11 → 231,11
pte->a = 1; /* Record access to PTE */
pht_insert(badvaddr, pte->pfn);
page_table_unlock(AS, true);
page_table_unlock(as, lock);
return;
fail:
page_table_unlock(AS, true);
page_table_unlock(as, lock);
pht_refill_fail(badvaddr, istate);
}
 
238,19 → 251,6
if (config.cpu_active == 1) {
page_mapping_operations = &pt_mapping_operations;
/*
* PA2KA(identity) mapping for all frames until last_frame.
*/
__address cur;
int flags;
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
flags = PAGE_CACHEABLE;
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
flags |= PAGE_GLOBAL;
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
/* Allocate page hash table */
phte_t *physical_phte = (phte_t *) PFN2ADDR(frame_alloc(PHT_ORDER, FRAME_KA | FRAME_PANIC));
phte = (phte_t *) PA2KA((__address) physical_phte);
265,3 → 265,19
);
}
}
 
 
__address hw_map(__address physaddr, size_t size)
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
__address virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}