Changeset View
Changeset View
Standalone View
Standalone View
head/sys/powerpc/booke/pmap.c
Show First 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | |||||
uint32_t tlb1_entries; | uint32_t tlb1_entries; | ||||
#define TLB0_ENTRIES (tlb0_entries) | #define TLB0_ENTRIES (tlb0_entries) | ||||
#define TLB0_WAYS (tlb0_ways) | #define TLB0_WAYS (tlb0_ways) | ||||
#define TLB0_ENTRIES_PER_WAY (tlb0_entries_per_way) | #define TLB0_ENTRIES_PER_WAY (tlb0_entries_per_way) | ||||
#define TLB1_ENTRIES (tlb1_entries) | #define TLB1_ENTRIES (tlb1_entries) | ||||
static vm_offset_t tlb1_map_base = VM_MAXUSER_ADDRESS + PAGE_SIZE; | static vm_offset_t tlb1_map_base = (vm_offset_t)VM_MAXUSER_ADDRESS + PAGE_SIZE; | ||||
static tlbtid_t tid_alloc(struct pmap *); | static tlbtid_t tid_alloc(struct pmap *); | ||||
static void tid_flush(tlbtid_t tid); | static void tid_flush(tlbtid_t tid); | ||||
#ifdef DDB | #ifdef DDB | ||||
#ifdef __powerpc64__ | #ifdef __powerpc64__ | ||||
static void tlb_print_entry(int, uint32_t, uint64_t, uint32_t, uint32_t); | static void tlb_print_entry(int, uint32_t, uint64_t, uint32_t, uint32_t); | ||||
#else | #else | ||||
▲ Show 20 Lines • Show All 1,338 Lines • ▼ Show 20 Lines | #endif | ||||
/* Read TLB0 size and associativity. */ | /* Read TLB0 size and associativity. */ | ||||
tlb0_get_tlbconf(); | tlb0_get_tlbconf(); | ||||
/* | /* | ||||
* Align kernel start and end address (kernel image). | * Align kernel start and end address (kernel image). | ||||
* Note that kernel end does not necessarily relate to kernsize. | * Note that kernel end does not necessarily relate to kernsize. | ||||
* kernsize is the size of the kernel that is actually mapped. | * kernsize is the size of the kernel that is actually mapped. | ||||
*/ | */ | ||||
kernstart = trunc_page(start); | |||||
data_start = round_page(kernelend); | data_start = round_page(kernelend); | ||||
data_end = data_start; | data_end = data_start; | ||||
/* Allocate the dynamic per-cpu area. */ | /* Allocate the dynamic per-cpu area. */ | ||||
dpcpu = (void *)data_end; | dpcpu = (void *)data_end; | ||||
data_end += DPCPU_SIZE; | data_end += DPCPU_SIZE; | ||||
/* Allocate space for the message buffer. */ | /* Allocate space for the message buffer. */ | ||||
▲ Show 20 Lines • Show All 555 Lines • ▼ Show 20 Lines | |||||
* The returned pointer is valid until the next time this function is | * The returned pointer is valid until the next time this function is | ||||
* called in this thread. This is used internally in copyin/copyout. | * called in this thread. This is used internally in copyin/copyout. | ||||
*/ | */ | ||||
int | int | ||||
mmu_booke_map_user_ptr(mmu_t mmu, pmap_t pm, volatile const void *uaddr, | mmu_booke_map_user_ptr(mmu_t mmu, pmap_t pm, volatile const void *uaddr, | ||||
void **kaddr, size_t ulen, size_t *klen) | void **kaddr, size_t ulen, size_t *klen) | ||||
{ | { | ||||
if ((uintptr_t)uaddr + ulen > VM_MAXUSER_ADDRESS + PAGE_SIZE) | if (trunc_page((uintptr_t)uaddr + ulen) > VM_MAXUSER_ADDRESS) | ||||
return (EFAULT); | return (EFAULT); | ||||
*kaddr = (void *)(uintptr_t)uaddr; | *kaddr = (void *)(uintptr_t)uaddr; | ||||
if (klen) | if (klen) | ||||
*klen = ulen; | *klen = ulen; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Figure out where a given kernel pointer (usually in a fault) points | * Figure out where a given kernel pointer (usually in a fault) points | ||||
* to from the VM's perspective, potentially remapping into userland's | * to from the VM's perspective, potentially remapping into userland's | ||||
* address space. | * address space. | ||||
*/ | */ | ||||
static int | static int | ||||
mmu_booke_decode_kernel_ptr(mmu_t mmu, vm_offset_t addr, int *is_user, | mmu_booke_decode_kernel_ptr(mmu_t mmu, vm_offset_t addr, int *is_user, | ||||
vm_offset_t *decoded_addr) | vm_offset_t *decoded_addr) | ||||
{ | { | ||||
if (addr < VM_MAXUSER_ADDRESS) | if (trunc_page(addr) <= VM_MAXUSER_ADDRESS) | ||||
*is_user = 1; | *is_user = 1; | ||||
else | else | ||||
*is_user = 0; | *is_user = 0; | ||||
*decoded_addr = addr; | *decoded_addr = addr; | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,842 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* TLB1 initialization routine, to be called after the very first | * TLB1 initialization routine, to be called after the very first | ||||
* assembler level setup done in locore.S. | * assembler level setup done in locore.S. | ||||
*/ | */ | ||||
void | void | ||||
tlb1_init() | tlb1_init() | ||||
{ | { | ||||
uint32_t mas0, mas1, mas2, mas3, mas7; | vm_offset_t mas2; | ||||
uint32_t mas0, mas1, mas3, mas7; | |||||
uint32_t tsz; | uint32_t tsz; | ||||
tlb1_get_tlbconf(); | tlb1_get_tlbconf(); | ||||
mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(0); | mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(0); | ||||
mtspr(SPR_MAS0, mas0); | mtspr(SPR_MAS0, mas0); | ||||
__asm __volatile("isync; tlbre"); | __asm __volatile("isync; tlbre"); | ||||
mas1 = mfspr(SPR_MAS1); | mas1 = mfspr(SPR_MAS1); | ||||
mas2 = mfspr(SPR_MAS2); | mas2 = mfspr(SPR_MAS2); | ||||
mas3 = mfspr(SPR_MAS3); | mas3 = mfspr(SPR_MAS3); | ||||
mas7 = mfspr(SPR_MAS7); | mas7 = mfspr(SPR_MAS7); | ||||
kernload = ((vm_paddr_t)(mas7 & MAS7_RPN) << 32) | | kernload = ((vm_paddr_t)(mas7 & MAS7_RPN) << 32) | | ||||
(mas3 & MAS3_RPN); | (mas3 & MAS3_RPN); | ||||
tsz = (mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; | tsz = (mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT; | ||||
kernsize += (tsz > 0) ? tsize2size(tsz) : 0; | kernsize += (tsz > 0) ? tsize2size(tsz) : 0; | ||||
kernstart = trunc_page(mas2); | |||||
/* Setup TLB miss defaults */ | /* Setup TLB miss defaults */ | ||||
set_mas4_defaults(); | set_mas4_defaults(); | ||||
} | } | ||||
/* | /* | ||||
* pmap_early_io_unmap() should be used in short conjunction with | * pmap_early_io_unmap() should be used in short conjunction with | ||||
* pmap_early_io_map(), as in the following snippet: | * pmap_early_io_map(), as in the following snippet: | ||||
▲ Show 20 Lines • Show All 325 Lines • Show Last 20 Lines |