summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2010-03-31 22:05:53 +0000
committerMarius Strobl <marius@FreeBSD.org>2010-03-31 22:05:53 +0000
commitd440faef02c3e2bffae8d5cc8558e786ee1faab7 (patch)
tree3cb07edc4252167cd180719197b6cd94b4a0ea53 /sys
parentf4c9392e623782c9201d0a586b6c8c3dd61e1978 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/sparc64/pmap.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c
index 1cf1be9f0a5c..6ad5f051513b 100644
--- a/sys/sparc64/sparc64/pmap.c
+++ b/sys/sparc64/sparc64/pmap.c
@@ -236,6 +236,8 @@ PMAP_STATS_VAR(pmap_ncopy_page_soc);
PMAP_STATS_VAR(pmap_nnew_thread);
PMAP_STATS_VAR(pmap_nnew_thread_oc);
+static inline u_long dtlb_get_data(u_int slot);
+
/*
* Quick sort callout for comparing memory regions
*/
@@ -274,6 +276,18 @@ om_cmp(const void *a, const void *b)
return (0);
}
+static inline u_long
+dtlb_get_data(u_int slot)
+{
+
+ /*
+ * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work
+ * around errata of USIII and beyond.
+ */
+ (void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG);
+ return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG));
+}
+
/*
* Bootstrap the system enough to run with virtual memory.
*/
@@ -287,11 +301,13 @@ pmap_bootstrap(u_int cpu_impl)
vm_paddr_t pa;
vm_size_t physsz;
vm_size_t virtsz;
+ u_long data;
phandle_t pmem;
phandle_t vmem;
- int sz;
+ u_int dtlb_slots_avail;
int i;
int j;
+ int sz;
/*
* Find out what physical memory is available from the PROM and
@@ -336,22 +352,30 @@ pmap_bootstrap(u_int cpu_impl)
/*
* Calculate the size of kernel virtual memory, and the size and mask
* for the kernel TSB based on the phsyical memory size but limited
- * by letting the kernel TSB take up no more than half of the dTLB
- * slots available for locked entries.
+ * by the amount of dTLB slots available for locked entries (given
+ * that for spitfire-class CPUs all of the dt64 slots can hold locked
+ * entries but there is no large dTLB for unlocked ones, we don't use
+ * more than half of it for locked entries).
*/
+ dtlb_slots_avail = 0;
+ for (i = 0; i < dtlb_slots; i++) {
+ data = dtlb_get_data(i);
+ if ((data & (TD_V | TD_L)) != (TD_V | TD_L))
+ dtlb_slots_avail++;
+ }
+#ifdef SMP
+ dtlb_slots_avail -= PCPU_PAGES;
+#endif
+ if (cpu_impl >= CPU_IMPL_ULTRASPARCI &&
+ cpu_impl < CPU_IMPL_ULTRASPARCIII)
+ dtlb_slots_avail /= 2;
virtsz = roundup(physsz, PAGE_SIZE_4M << (PAGE_SHIFT - TTE_SHIFT));
virtsz = MIN(virtsz,
- (dtlb_slots / 2 * PAGE_SIZE_4M) << (PAGE_SHIFT - TTE_SHIFT));
+ (dtlb_slots_avail * PAGE_SIZE_4M) << (PAGE_SHIFT - TTE_SHIFT));
vm_max_kernel_address = VM_MIN_KERNEL_ADDRESS + virtsz;
tsb_kernel_size = virtsz >> (PAGE_SHIFT - TTE_SHIFT);
tsb_kernel_mask = (tsb_kernel_size >> TTE_SHIFT) - 1;
- if (kernel_tlb_slots + PCPU_PAGES + tsb_kernel_size / PAGE_SIZE_4M +
- 1 /* PROM page */ + 1 /* spare */ > dtlb_slots)
- panic("pmap_bootstrap: insufficient dTLB entries");
- if (kernel_tlb_slots + 1 /* PROM page */ + 1 /* spare */ > itlb_slots)
- panic("pmap_bootstrap: insufficient iTLB entries");
-
/*
* Allocate the kernel TSB and lock it in the TLB.
*/