Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/booke/pmap_32.c
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | ||||
* | * | ||||
* Copyright (C) 2020 Justin Hibbits | |||||
* Copyright (C) 2007-2009 Semihalf, Rafal Jaworowski <raj@semihalf.com> | * Copyright (C) 2007-2009 Semihalf, Rafal Jaworowski <raj@semihalf.com> | ||||
* Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com> | * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com> | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
static vm_offset_t zero_page_va; | static vm_offset_t zero_page_va; | ||||
static struct mtx zero_page_mutex; | static struct mtx zero_page_mutex; | ||||
/* Reserved KVA space and mutex for mmu_booke_copy_page. */ | /* Reserved KVA space and mutex for mmu_booke_copy_page. */ | ||||
static vm_offset_t copy_page_src_va; | static vm_offset_t copy_page_src_va; | ||||
static vm_offset_t copy_page_dst_va; | static vm_offset_t copy_page_dst_va; | ||||
static struct mtx copy_page_mutex; | static struct mtx copy_page_mutex; | ||||
static vm_offset_t kernel_ptbl_root; | |||||
static unsigned int kernel_ptbls; /* Number of KVA ptbls. */ | |||||
/**************************************************************************/ | /**************************************************************************/ | ||||
/* PMAP */ | /* PMAP */ | ||||
/**************************************************************************/ | /**************************************************************************/ | ||||
#define VM_MAPDEV_BASE ((vm_offset_t)VM_MAXUSER_ADDRESS + PAGE_SIZE) | #define VM_MAPDEV_BASE ((vm_offset_t)VM_MAXUSER_ADDRESS + PAGE_SIZE) | ||||
static void tid_flush(tlbtid_t tid); | static void tid_flush(tlbtid_t tid); | ||||
static unsigned long ilog2(unsigned long); | static unsigned long ilog2(unsigned long); | ||||
Show All 12 Lines | |||||
static void ptbl_free(mmu_t, pmap_t, unsigned int); | static void ptbl_free(mmu_t, pmap_t, unsigned int); | ||||
static void ptbl_hold(mmu_t, pmap_t, unsigned int); | static void ptbl_hold(mmu_t, pmap_t, unsigned int); | ||||
static int ptbl_unhold(mmu_t, pmap_t, unsigned int); | static int ptbl_unhold(mmu_t, pmap_t, unsigned int); | ||||
static vm_paddr_t pte_vatopa(mmu_t, pmap_t, vm_offset_t); | static vm_paddr_t pte_vatopa(mmu_t, pmap_t, vm_offset_t); | ||||
static int pte_enter(mmu_t, pmap_t, vm_page_t, vm_offset_t, uint32_t, boolean_t); | static int pte_enter(mmu_t, pmap_t, vm_page_t, vm_offset_t, uint32_t, boolean_t); | ||||
static int pte_remove(mmu_t, pmap_t, vm_offset_t, uint8_t); | static int pte_remove(mmu_t, pmap_t, vm_offset_t, uint8_t); | ||||
static pte_t *pte_find(mmu_t, pmap_t, vm_offset_t); | static pte_t *pte_find(mmu_t, pmap_t, vm_offset_t); | ||||
static void kernel_pte_alloc(vm_offset_t, vm_offset_t, vm_offset_t); | |||||
struct ptbl_buf { | struct ptbl_buf { | ||||
TAILQ_ENTRY(ptbl_buf) link; /* list link */ | TAILQ_ENTRY(ptbl_buf) link; /* list link */ | ||||
vm_offset_t kva; /* va of mapping */ | vm_offset_t kva; /* va of mapping */ | ||||
}; | }; | ||||
/* Number of kva ptbl buffers, each covering one ptbl (PTBL_PAGES). */ | /* Number of kva ptbl buffers, each covering one ptbl (PTBL_PAGES). */ | ||||
#define PTBL_BUFS (128 * 16) | #define PTBL_BUFS (128 * 16) | ||||
▲ Show 20 Lines • Show All 443 Lines • ▼ Show 20 Lines | pte_find(mmu_t mmu, pmap_t pmap, vm_offset_t va) | ||||
if (pmap->pm_pdir[pdir_idx]) | if (pmap->pm_pdir[pdir_idx]) | ||||
return (&(pmap->pm_pdir[pdir_idx][ptbl_idx])); | return (&(pmap->pm_pdir[pdir_idx][ptbl_idx])); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* Set up kernel page tables. */ | /* Set up kernel page tables. */ | ||||
static void | static void | ||||
kernel_pte_alloc(vm_offset_t data_end, vm_offset_t addr, vm_offset_t pdir) | kernel_pte_alloc(vm_offset_t data_end, vm_offset_t addr) | ||||
{ | { | ||||
int i; | |||||
vm_offset_t va; | |||||
pte_t *pte; | pte_t *pte; | ||||
vm_offset_t va; | |||||
vm_offset_t pdir_start; | |||||
int i; | |||||
kptbl_min = VM_MIN_KERNEL_ADDRESS / PDIR_SIZE; | |||||
kernel_pmap->pm_pdir = (pte_t **)kernel_ptbl_root; | |||||
pdir_start = kernel_ptbl_root + PDIR_NENTRIES * sizeof(pte_t); | |||||
/* Initialize kernel pdir */ | /* Initialize kernel pdir */ | ||||
for (i = 0; i < kernel_ptbls; i++) | for (i = 0; i < kernel_ptbls; i++) { | ||||
kernel_pmap->pm_pdir[kptbl_min + i] = | kernel_pmap->pm_pdir[kptbl_min + i] = | ||||
(pte_t *)(pdir + (i * PAGE_SIZE * PTBL_PAGES)); | (pte_t *)(pdir_start + (i * PAGE_SIZE * PTBL_PAGES)); | ||||
} | |||||
/* | /* | ||||
* Fill in PTEs covering kernel code and data. They are not required | * Fill in PTEs covering kernel code and data. They are not required | ||||
* for address translation, as this area is covered by static TLB1 | * for address translation, as this area is covered by static TLB1 | ||||
* entries, but for pte_vatopa() to work correctly with kernel area | * entries, but for pte_vatopa() to work correctly with kernel area | ||||
* addresses. | * addresses. | ||||
*/ | */ | ||||
for (va = addr; va < data_end; va += PAGE_SIZE) { | for (va = addr; va < data_end; va += PAGE_SIZE) { | ||||
pte = &(kernel_pmap->pm_pdir[PDIR_IDX(va)][PTBL_IDX(va)]); | pte = &(kernel_pmap->pm_pdir[PDIR_IDX(va)][PTBL_IDX(va)]); | ||||
powerpc_sync(); | |||||
*pte = PTE_RPN_FROM_PA(kernload + (va - kernstart)); | *pte = PTE_RPN_FROM_PA(kernload + (va - kernstart)); | ||||
*pte |= PTE_M | PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | | *pte |= PTE_M | PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | | ||||
PTE_VALID | PTE_PS_4KB; | PTE_VALID | PTE_PS_4KB; | ||||
} | } | ||||
} | |||||
static vm_offset_t | |||||
mmu_booke_alloc_kernel_pgtables(vm_offset_t data_end) | |||||
{ | |||||
/* Allocate space for ptbl_bufs. */ | |||||
ptbl_bufs = (struct ptbl_buf *)data_end; | |||||
data_end += sizeof(struct ptbl_buf) * PTBL_BUFS; | |||||
debugf(" ptbl_bufs at 0x%"PRI0ptrX" end = 0x%"PRI0ptrX"\n", | |||||
(uintptr_t)ptbl_bufs, data_end); | |||||
data_end = round_page(data_end); | |||||
kernel_ptbl_root = data_end; | |||||
data_end += PDIR_NENTRIES * sizeof(pte_t*); | |||||
/* Allocate PTE tables for kernel KVA. */ | |||||
kernel_ptbls = howmany(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS, | |||||
PDIR_SIZE); | |||||
data_end += kernel_ptbls * PTBL_PAGES * PAGE_SIZE; | |||||
debugf(" kernel ptbls: %d\n", kernel_ptbls); | |||||
debugf(" kernel pdir at %#jx end = %#jx\n", | |||||
(uintmax_t)kernel_ptbl_root, (uintmax_t)data_end); | |||||
return (data_end); | |||||
} | } | ||||
/* | /* | ||||
* Initialize a preallocated and zeroed pmap structure, | * Initialize a preallocated and zeroed pmap structure, | ||||
* such as one in a vmspace structure. | * such as one in a vmspace structure. | ||||
*/ | */ | ||||
static void | static void | ||||
mmu_booke_pinit(mmu_t mmu, pmap_t pmap) | mmu_booke_pinit(mmu_t mmu, pmap_t pmap) | ||||
▲ Show 20 Lines • Show All 303 Lines • Show Last 20 Lines |