Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1890 → Rev 1891

/trunk/kernel/arch/sparc64/src/mm/as.c
40,6 → 40,12
 
#ifdef CONFIG_TSB
#include <arch/mm/tsb.h>
#include <arch/memstr.h>
#include <synch/mutex.h>
#include <arch/asm.h>
#include <mm/frame.h>
#include <bitops.h>
#include <macros.h>
#endif
 
/** Architecture dependent address space init. */
49,6 → 55,47
asid_fifo_init();
}
 
int as_constructor_arch(as_t *as, int flags)
{
#ifdef CONFIG_TSB
int order = fnzb32(((ITSB_ENTRY_COUNT+DTSB_ENTRY_COUNT)*sizeof(tsb_entry_t))>>FRAME_WIDTH);
uintptr_t tsb = (uintptr_t) frame_alloc(order, flags);
 
if (!tsb)
return -1;
 
as->arch.itsb = (tsb_entry_t *) tsb;
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * sizeof(tsb_entry_t));
#endif
return 0;
}
 
int as_destructor_arch(as_t *as)
{
#ifdef CONFIG_TSB
count_t cnt = ((ITSB_ENTRY_COUNT+DTSB_ENTRY_COUNT)*sizeof(tsb_entry_t))>>FRAME_WIDTH;
frame_free((uintptr_t) as->arch.itsb);
return cnt;
#else
return 0;
#endif
}
 
int as_create_arch(as_t *as, int flags)
{
#ifdef CONFIG_TSB
ipl_t ipl;
 
memsetb((uintptr_t) as->arch.itsb, (ITSB_ENTRY_COUNT+DTSB_ENTRY_COUNT)*sizeof(tsb_entry_t), 0);
ipl = interrupts_disable();
mutex_lock_active(&as->lock); /* completely unnecessary, but polite */
tsb_invalidate(as, 0, (count_t) -1);
mutex_unlock(&as->lock);
interrupts_restore(ipl);
#endif
return 0;
}
 
/** Perform sparc64-specific tasks when an address space becomes active on the processor.
*
* Install ASID and map TSBs.
78,37 → 125,35
mmu_secondary_context_write(ctx.v);
 
#ifdef CONFIG_TSB
if (as != AS_KERNEL) {
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 
ASSERT(as->arch.itsb && as->arch.dtsb);
ASSERT(as->arch.itsb && as->arch.dtsb);
 
uintptr_t tsb = as->arch.itsb;
uintptr_t tsb = (uintptr_t) as->arch.itsb;
if (!overlaps(tsb, 8*PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
/*
* TSBs were allocated from memory not covered
* by the locked 4M kernel DTLB entry. We need
* to map both TSBs explicitly.
*/
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true);
}
if (!overlaps(tsb, 8*PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
/*
* Setup TSB Base registers.
* TSBs were allocated from memory not covered
* by the locked 4M kernel DTLB entry. We need
* to map both TSBs explicitly.
*/
tsb_base_reg_t tsb_base;
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true);
}
tsb_base.value = 0;
tsb_base.size = TSB_SIZE;
tsb_base.split = 0;
/*
* Setup TSB Base registers.
*/
tsb_base_reg_t tsb_base;
tsb_base.value = 0;
tsb_base.size = TSB_SIZE;
tsb_base.split = 0;
 
tsb_base.base = as->arch.itsb >> PAGE_WIDTH;
itsb_base_write(tsb_base.value);
tsb_base.base = as->arch.dtsb >> PAGE_WIDTH;
dtsb_base_write(tsb_base.value);
}
tsb_base.base = ((uintptr_t) as->arch.itsb) >> PAGE_WIDTH;
itsb_base_write(tsb_base.value);
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> PAGE_WIDTH;
dtsb_base_write(tsb_base.value);
#endif
}
 
129,22 → 174,19
*/
 
#ifdef CONFIG_TSB
if (as != AS_KERNEL) {
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 
ASSERT(as->arch.itsb && as->arch.dtsb);
ASSERT(as->arch.itsb && as->arch.dtsb);
 
uintptr_t tsb = as->arch.itsb;
uintptr_t tsb = (uintptr_t) as->arch.itsb;
if (!overlaps(tsb, 8*PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
/*
* TSBs were allocated from memory not covered
* by the locked 4M kernel DTLB entry. We need
* to demap the entry installed by as_install_arch().
*/
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
}
if (!overlaps(tsb, 8*PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
/*
* TSBs were allocated from memory not covered
* by the locked 4M kernel DTLB entry. We need
* to demap the entry installed by as_install_arch().
*/
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
}
#endif
}