aboutsummaryrefslogtreecommitdiff
path: root/sys/powerpc/booke/pmap.c
diff options
context:
space:
mode:
authorJustin Hibbits <jhibbits@FreeBSD.org>2019-11-04 00:35:40 +0000
committerJustin Hibbits <jhibbits@FreeBSD.org>2019-11-04 00:35:40 +0000
commit730de0f746cca1a5c79edb74587bc67e689e1523 (patch)
treeec9646ce414013f9eeb9249c2cd23c5cc2da89e1 /sys/powerpc/booke/pmap.c
parentd7a3eada0a0ab11cfd2c2f61a05dbf8a285bc2b8 (diff)
downloadsrc-730de0f746cca1a5c79edb74587bc67e689e1523.tar.gz
src-730de0f746cca1a5c79edb74587bc67e689e1523.zip
Notes
Diffstat (limited to 'sys/powerpc/booke/pmap.c')
-rw-r--r--sys/powerpc/booke/pmap.c124
1 files changed, 44 insertions, 80 deletions
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 9eac669e0f7c..e6ce3e729cc6 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -237,11 +237,11 @@ static void tlb_print_entry(int, uint32_t, uint32_t, uint32_t, uint32_t);
static void tlb1_read_entry(tlb_entry_t *, unsigned int);
static void tlb1_write_entry(tlb_entry_t *, unsigned int);
static int tlb1_iomapped(int, vm_paddr_t, vm_size_t, vm_offset_t *);
-static vm_size_t tlb1_mapin_region(vm_offset_t, vm_paddr_t, vm_size_t);
+static vm_size_t tlb1_mapin_region(vm_offset_t, vm_paddr_t, vm_size_t, int);
static vm_size_t tsize2size(unsigned int);
static unsigned int size2tsize(vm_size_t);
-static unsigned int ilog2(unsigned long);
+static unsigned long ilog2(unsigned long);
static void set_mas4_defaults(void);
@@ -1619,10 +1619,16 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
debugf(" kernel pdir at 0x%"PRI0ptrX" end = 0x%"PRI0ptrX"\n",
kernel_pdir, data_end);
+ /* Pre-round up to 1MB. This wastes some space, but saves TLB entries */
+ data_end = roundup2(data_end, 1 << 20);
debugf(" data_end: 0x%"PRI0ptrX"\n", data_end);
+ debugf(" kernstart: %p\n", kernstart);
+ debugf(" kernsize: %lx\n", kernsize);
+
if (data_end - kernstart > kernsize) {
kernsize += tlb1_mapin_region(kernstart + kernsize,
- kernload + kernsize, (data_end - kernstart) - kernsize);
+ kernload + kernsize, (data_end - kernstart) - kernsize,
+ _TLB_ENTRY_MEM);
}
data_end = kernstart + kernsize;
debugf(" updated data_end: 0x%"PRI0ptrX"\n", data_end);
@@ -1819,7 +1825,7 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
* Round so it fits into a single mapping.
*/
tlb1_mapin_region(DMAP_BASE_ADDRESS, 0,
- phys_avail[i + 1]);
+ phys_avail[i + 1], _TLB_ENTRY_MEM);
#endif
/*******************************************************/
@@ -3500,30 +3506,8 @@ mmu_booke_mapdev_attr(mmu_t mmu, vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
#endif
res = (void *)va;
- do {
- sz = 1 << (ilog2(size) & ~1);
- /* Align size to PA */
- if (pa % sz != 0) {
- do {
- sz >>= 2;
- } while (pa % sz != 0);
- }
- /* Now align from there to VA */
- if (va % sz != 0) {
- do {
- sz >>= 2;
- } while (va % sz != 0);
- }
- if (bootverbose)
- printf("Wiring VA=%p to PA=%jx (size=%lx)\n",
- (void *)va, (uintmax_t)pa, (long)sz);
- if (tlb1_set_entry(va, pa, sz,
- _TLB_ENTRY_SHARED | tlb_calc_wimg(pa, ma)) < 0)
- return (NULL);
- size -= sz;
- pa += sz;
- va += sz;
- } while (size > 0);
+ if (tlb1_mapin_region(va, pa, size, tlb_calc_wimg(pa, ma)) != size)
+ return (NULL);
return (res);
}
@@ -3864,7 +3848,7 @@ tlb1_write_entry(tlb_entry_t *e, unsigned int idx)
/*
* Return the largest uint value log such that 2^log <= num.
*/
-static unsigned int
+static unsigned long
ilog2(unsigned long num)
{
long lz;
@@ -3952,69 +3936,49 @@ tlb1_set_entry(vm_offset_t va, vm_paddr_t pa, vm_size_t size,
}
/*
- * Map in contiguous RAM region into the TLB1 using maximum of
- * KERNEL_REGION_MAX_TLB_ENTRIES entries.
- *
- * If necessary round up last entry size and return total size
- * used by all allocated entries.
+ * Map in contiguous RAM region into the TLB1.
*/
-vm_size_t
-tlb1_mapin_region(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
+static vm_size_t
+tlb1_mapin_region(vm_offset_t va, vm_paddr_t pa, vm_size_t size, int wimge)
{
- vm_size_t pgs[KERNEL_REGION_MAX_TLB_ENTRIES];
- vm_size_t mapped, pgsz, base, mask;
- int idx, nents;
-
- /* Round up to the next 1M */
- size = roundup2(size, 1 << 20);
+ vm_offset_t base;
+ vm_size_t mapped, sz, ssize;
mapped = 0;
- idx = 0;
base = va;
- pgsz = 64*1024*1024;
- while (mapped < size) {
- while (mapped < size && idx < KERNEL_REGION_MAX_TLB_ENTRIES) {
- while (pgsz > (size - mapped))
- pgsz >>= 2;
- pgs[idx++] = pgsz;
- mapped += pgsz;
- }
+ ssize = size;
- /* We under-map. Correct for this. */
- if (mapped < size) {
- while (pgs[idx - 1] == pgsz) {
- idx--;
- mapped -= pgsz;
- }
- /* XXX We may increase beyond out starting point. */
- pgsz <<= 2;
- pgs[idx++] = pgsz;
- mapped += pgsz;
+ while (size > 0) {
+ sz = 1UL << (ilog2(size) & ~1);
+ /* Align size to PA */
+ if (pa % sz != 0) {
+ do {
+ sz >>= 2;
+ } while (pa % sz != 0);
}
- }
-
- nents = idx;
- mask = pgs[0] - 1;
- /* Align address to the boundary */
- if (va & mask) {
- va = (va + mask) & ~mask;
- pa = (pa + mask) & ~mask;
- }
-
- for (idx = 0; idx < nents; idx++) {
- pgsz = pgs[idx];
- debugf("%u: %jx -> %jx, size=%jx\n", idx, (uintmax_t)pa,
- (uintmax_t)va, (uintmax_t)pgsz);
- tlb1_set_entry(va, pa, pgsz,
- _TLB_ENTRY_SHARED | _TLB_ENTRY_MEM);
- pa += pgsz;
- va += pgsz;
+ /* Now align from there to VA */
+ if (va % sz != 0) {
+ do {
+ sz >>= 2;
+ } while (va % sz != 0);
+ }
+ /* Now align from there to VA */
+ if (bootverbose)
+ printf("Wiring VA=%p to PA=%jx (size=%lx)\n",
+ (void *)va, (uintmax_t)pa, (long)sz);
+ if (tlb1_set_entry(va, pa, sz,
+ _TLB_ENTRY_SHARED | wimge) < 0)
+ return (mapped);
+ size -= sz;
+ pa += sz;
+ va += sz;
}
mapped = (va - base);
if (bootverbose)
printf("mapped size 0x%"PRIxPTR" (wasted space 0x%"PRIxPTR")\n",
- mapped, mapped - size);
+ mapped, mapped - ssize);
+
return (mapped);
}