33,14 → 33,16 |
/** @file |
*/ |
|
/* SUN4V-OK */ |
|
#include <arch/mm/as.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/tlb.h> |
#include <genarch/mm/page_ht.h> |
#include <genarch/mm/asid_fifo.h> |
#include <debug.h> |
#include <config.h> |
#include <arch/sun4v/hypercall.h> |
|
#ifdef CONFIG_TSB |
#include <arch/mm/tsb.h> |
63,12 → 65,8 |
int as_constructor_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
/* |
* The order must be calculated with respect to the emulated |
* 16K page size. |
*/ |
int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
int order = fnzb32( |
(TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
|
uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA); |
|
75,12 → 73,15 |
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)); |
as->arch.tsb_description.page_size = PAGESIZE_8K; |
as->arch.tsb_description.associativity = 1; |
as->arch.tsb_description.num_ttes = TSB_ENTRY_COUNT; |
as->arch.tsb_description.pgsize_mask = 1 << PAGESIZE_8K; |
as->arch.tsb_description.tsb_base = tsb; |
as->arch.tsb_description.reserved = 0; |
|
memsetb(as->arch.itsb, |
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); |
memsetb((void *) as->arch.tsb_description.tsb_base, |
TSB_ENTRY_COUNT * sizeof(tsb_entry_t), 0); |
#endif |
return 0; |
} |
88,13 → 89,8 |
int as_destructor_arch(as_t *as) |
{ |
#ifdef CONFIG_TSB |
/* |
* The count must be calculated with respect to the emualted 16K page |
* size. |
*/ |
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
frame_free(KA2PA((uintptr_t) as->arch.itsb)); |
count_t cnt = (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
frame_free(KA2PA((uintptr_t) as->arch.tsb_description.tsb_base)); |
return cnt; |
#else |
return 0; |
105,6 → 101,7 |
{ |
#ifdef CONFIG_TSB |
tsb_invalidate(as, 0, (count_t) -1); |
as->arch.tsb_description.context = as->asid; |
#endif |
return 0; |
} |
118,32 → 115,13 |
*/ |
void as_install_arch(as_t *as) |
{ |
#if 0 |
tlb_context_reg_t ctx; |
|
/* |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
|
/* |
* Write ASID to secondary context register. The primary context |
* register has to be set from TL>0 so it will be filled from the |
* secondary context register from the TL=1 code just before switch to |
* userspace. |
*/ |
ctx.v = 0; |
ctx.context = as->asid; |
mmu_secondary_context_write(ctx.v); |
mmu_secondary_context_write(as->asid); |
|
#ifdef CONFIG_TSB |
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
|
ASSERT(as->arch.itsb && as->arch.dtsb); |
|
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
ASSERT(as->arch.tsb_description.tsb_base); |
uintptr_t tsb = as->arch.tsb_description.tsb_base; |
|
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
151,43 → 129,15 |
* 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); |
mmu_demap_page(tsb, 0, MMU_FLAG_DTLB); |
mmu_map_perm_addr( |
tsb, KA2PA(tsb), true, true, false, true, |
PAGESIZE_64K, MMU_FLAG_DTLB); |
} |
|
/* |
* 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 = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH; |
itsb_base_write(tsb_base.value); |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; |
dtsb_base_write(tsb_base.value); |
__hypercall_fast2(MMU_TSB_CTX0, 1, as->arch.tsb_description.tsb_base); |
|
#if defined (US3) |
/* |
* Clear the extension registers. |
* In HelenOS, primary and secondary context registers contain |
* equal values and kernel misses (context 0, ie. the nucleus context) |
* are excluded from the TSB miss handler, so it makes no sense |
* to have separate TSBs for primary, secondary and nucleus contexts. |
* Clearing the extension registers will ensure that the value of the |
* TSB Base register will be used as an address of TSB, making the code |
* compatible with the US port. |
*/ |
itsb_primary_extension_write(0); |
itsb_nucleus_extension_write(0); |
dtsb_primary_extension_write(0); |
dtsb_secondary_extension_write(0); |
dtsb_nucleus_extension_write(0); |
#endif |
#endif |
#endif |
} |
|
/** Perform sparc64-specific tasks when an address space is removed from the |
199,7 → 149,6 |
*/ |
void as_deinstall_arch(as_t *as) |
{ |
|
/* |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
206,13 → 155,12 |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
|
#ifdef CONFIG_TSB |
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
|
ASSERT(as->arch.itsb && as->arch.dtsb); |
ASSERT(as->arch.tsb_description.tsb_base); |
|
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
uintptr_t tsb = as->arch.tsb_description.tsb_base; |
|
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
220,7 → 168,7 |
* 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); |
mmu_demap_page(tsb, 0, MMU_FLAG_DTLB); |
} |
#endif |
} |