summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-09-29 19:11:09 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-09-29 19:11:09 +0000
commitb60b7cf9e3d07d9ff9f747df9992383468b6499c (patch)
tree719c9a96543b80ddbf52fe07fa0a09b442ceb1a5 /sys/arch/mips64
parent29c0098b834ddaa89ad7b55b50df47a30a055026 (diff)
Kill the mostly unused VMTLB_xxx and VMNUM_xxx defines. Move all tlb
knowledge to <machine/pte.h>. Add specific routines for tlb handling setup (at cpu initialization time) and tlb ASID wrap.
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r--sys/arch/mips64/include/cpu.h49
-rw-r--r--sys/arch/mips64/include/pte.h50
-rw-r--r--sys/arch/mips64/mips64/context.S5
-rw-r--r--sys/arch/mips64/mips64/mips64_machdep.c27
-rw-r--r--sys/arch/mips64/mips64/pmap.c41
5 files changed, 83 insertions, 89 deletions
diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h
index def32138a9b..54b982900db 100644
--- a/sys/arch/mips64/include/cpu.h
+++ b/sys/arch/mips64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.84 2012/09/29 18:54:38 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.85 2012/09/29 19:11:08 miod Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -299,38 +299,6 @@
#define FPC_ID $0
#define FPC_CSR $31
-/*
- * The low part of the TLB entry.
- */
-#define VMTLB_PF_NUM 0x3fffffc0
-#define VMTLB_ATTR_MASK 0x00000038
-#define VMTLB_MOD_BIT 0x00000004
-#define VMTLB_VALID_BIT 0x00000002
-#define VMTLB_GLOBAL_BIT 0x00000001
-
-#define VMTLB_PHYS_PAGE_SHIFT 6
-
-/*
- * The high part of the TLB entry.
- */
-#define VMTLB_VIRT_PAGE_NUM 0xffffe000
-#define VMTLB_PID 0x000000ff
-#define VMTLB_PID_SHIFT 0
-#define VMTLB_VIRT_PAGE_SHIFT 12
-
-/*
- * The number of process id entries.
- */
-#define VMNUM_PIDS 256
-
-/*
- * TLB probe return codes.
- */
-#define VMTLB_NOT_FOUND 0
-#define VMTLB_FOUND 1
-#define VMTLB_FOUND_WITH_PATCH 2
-#define VMTLB_PROBE_ERROR 3
-
#endif /* _KERNEL || _STANDALONE */
/*
@@ -573,7 +541,6 @@ void cp0_calibrate(struct cpu_info *);
#if defined(_KERNEL) && !defined(_LOCORE)
struct exec_package;
-struct tlb_entry;
struct user;
u_int cp0_get_count(void);
@@ -585,16 +552,14 @@ uint32_t cp0_get_prid(void);
void cp0_set_compare(u_int);
void cp0_set_config(uint32_t);
u_int cp1_get_prid(void);
-u_int tlb_get_pid(void);
-void tlb_set_page_mask(uint32_t);
-void tlb_set_pid(u_int);
-void tlb_set_wired(int);
-
+void tlb_asid_wrap(struct cpu_info *);
void tlb_flush(int);
void tlb_flush_addr(vaddr_t);
-void tlb_write_indexed(int, struct tlb_entry *);
-int tlb_update(vaddr_t, unsigned);
-void tlb_read(int, struct tlb_entry *);
+void tlb_init(unsigned int);
+void tlb_set_page_mask(uint32_t);
+void tlb_set_pid(u_int);
+void tlb_set_wired(uint32_t);
+int tlb_update(vaddr_t, register_t);
void build_trampoline(vaddr_t, vaddr_t);
void cpu_switchto_asm(struct proc *, struct proc *);
diff --git a/sys/arch/mips64/include/pte.h b/sys/arch/mips64/include/pte.h
index c778ca62c93..7f329e4983d 100644
--- a/sys/arch/mips64/include/pte.h
+++ b/sys/arch/mips64/include/pte.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pte.h,v 1.13 2012/04/24 20:01:59 miod Exp $ */
+/* $OpenBSD: pte.h,v 1.14 2012/09/29 19:11:08 miod Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -38,15 +38,14 @@
*/
/*
- * R4000 hardware page table entry
+ * R4000 hardware page table entries
*/
#ifndef _LOCORE
/*
- * Structure defining an tlb entry data set.
+ * Structure defining a TLB entry data set.
*/
-
struct tlb_entry {
u_int64_t tlb_mask;
u_int64_t tlb_hi;
@@ -54,40 +53,46 @@ struct tlb_entry {
u_int64_t tlb_lo1;
};
+u_int tlb_get_pid(void);
+void tlb_read(unsigned int, struct tlb_entry *);
+
typedef u_int32_t pt_entry_t; /* Mips page table entry */
#define NPTEPG (PMAP_L2SIZE / sizeof(pt_entry_t))
#endif /* _LOCORE */
/* entryhi values */
-#if PAGE_SHIFT == 12
-#define PG_SVPN 0xfffffffffffff000 /* Software page no mask */
-#define PG_HVPN 0xffffffffffffe000 /* Hardware page no mask */
-#define PG_ODDPG 0x0000000000001000 /* Odd even pte entry */
-#elif PAGE_SHIFT == 14
-#define PG_SVPN 0xffffffffffffc000 /* Software page no mask */
-#define PG_HVPN 0xffffffffffff8000 /* Hardware page no mask */
-#define PG_ODDPG 0x0000000000004000 /* Odd even pte entry */
-#endif
-#define PG_ASID 0x00000000000000ff /* Address space ID */
+#define PG_HVPN (-2 * PAGE_SIZE) /* Hardware page number mask */
+#define PG_ODDPG PAGE_SIZE
+
+/* Address space ID */
+#define PG_ASID_MASK 0x00000000000000ff
+#define PG_ASID_SHIFT 0
+#define MIN_USER_ASID 1
+#define PG_ASID_COUNT 256 /* Number of available ASID */
+
/* entrylo values */
#define PG_WIRED 0x80000000 /* SW */
#define PG_RO 0x40000000 /* SW */
#define PG_G 0x00000001 /* HW */
#define PG_V 0x00000002
-#define PG_NV 0x00000000
#define PG_M 0x00000004
-#define PG_UNCACHED (CCA_NC << 3)
-#define PG_CACHED_NC (CCA_NONCOHERENT << 3)
-#define PG_CACHED_CE (CCA_COHERENT_EXCL << 3)
-#define PG_CACHED_CEW (CCA_COHERENT_EXCLWRITE << 3)
-#define PG_CACHED (CCA_CACHED << 3)
-#define PG_CACHEMODE 0x00000038
-#define PG_ATTR 0x0000003f
+#define PG_CCA_SHIFT 3
+#define PG_NV 0x00000000
+
+#define PG_UNCACHED (CCA_NC << PG_CCA_SHIFT)
+#define PG_CACHED_NC (CCA_NONCOHERENT << PG_CCA_SHIFT)
+#define PG_CACHED_CE (CCA_COHERENT_EXCL << PG_CCA_SHIFT)
+#define PG_CACHED_CEW (CCA_COHERENT_EXCLWRITE << PG_CCA_SHIFT)
+#define PG_CACHED (CCA_CACHED << PG_CCA_SHIFT)
+#define PG_CACHEMODE (7 << PG_CCA_SHIFT)
+
+#define PG_ATTR (PG_CACHEMODE | PG_M | PG_V | PG_G)
#define PG_ROPAGE (PG_V | PG_RO | PG_CACHED) /* Write protected */
#define PG_RWPAGE (PG_V | PG_M | PG_CACHED) /* Not w-prot not clean */
#define PG_CWPAGE (PG_V | PG_CACHED) /* Not w-prot but clean */
#define PG_IOPAGE (PG_G | PG_V | PG_M | PG_UNCACHED)
+
#define PG_FRAME 0x3fffffc0
#define PG_FRAMEBITS 30
#define PG_SHIFT 6
@@ -102,7 +107,6 @@ typedef u_int32_t pt_entry_t; /* Mips page table entry */
#define PG_SIZE_1M 0x001fe000
#define PG_SIZE_4M 0x007fe000
#define PG_SIZE_16M 0x01ffe000
-
#if PAGE_SHIFT == 12
#define TLB_PAGE_MASK PG_SIZE_4K
#elif PAGE_SHIFT == 14
diff --git a/sys/arch/mips64/mips64/context.S b/sys/arch/mips64/mips64/context.S
index f2e74a8c224..01da9b764a4 100644
--- a/sys/arch/mips64/mips64/context.S
+++ b/sys/arch/mips64/mips64/context.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: context.S,v 1.48 2012/09/29 19:02:26 miod Exp $ */
+/* $OpenBSD: context.S,v 1.49 2012/09/29 19:11:08 miod Exp $ */
/*
* Copyright (c) 2002-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -238,6 +238,9 @@ ctx2:
TLB_HAZARD
#endif /* } UPAGES > 2 */
#else /* } UPAGES > 1 { */
+#if PG_ASID_SHIFT != 0
+ dsll v0, PG_ASID_SHIFT
+#endif
dmtc0 v0, COP_0_TLB_HI # init high entry (tlbid)
#endif /* } UPAGES > 1 */
diff --git a/sys/arch/mips64/mips64/mips64_machdep.c b/sys/arch/mips64/mips64/mips64_machdep.c
index 64adb643a9f..c3e5e8df524 100644
--- a/sys/arch/mips64/mips64/mips64_machdep.c
+++ b/sys/arch/mips64/mips64/mips64_machdep.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: mips64_machdep.c,v 1.4 2012/07/14 19:50:12 miod Exp $ */
+/* $OpenBSD: mips64_machdep.c,v 1.5 2012/09/29 19:11:08 miod Exp $ */
/*
- * Copyright (c) 2009, 2010 Miodrag Vallat.
+ * Copyright (c) 2009, 2010, 2012 Miodrag Vallat.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -190,6 +190,29 @@ exec_md_map(struct proc *p, struct exec_package *pack)
}
/*
+ * Initial TLB setup for the current processor.
+ */
+void
+tlb_init(unsigned int tlbsize)
+{
+ tlb_set_page_mask(TLB_PAGE_MASK);
+ tlb_set_wired(0);
+ tlb_flush(tlbsize);
+#if UPAGES > 1
+ tlb_set_wired(UPAGES / 2);
+#endif
+}
+
+/*
+ * Handle an ASID wrap.
+ */
+void
+tlb_asid_wrap(struct cpu_info *ci)
+{
+ tlb_flush(ci->ci_hw.tlbsize);
+}
+
+/*
* Mips machine independent clock routines.
*/
diff --git a/sys/arch/mips64/mips64/pmap.c b/sys/arch/mips64/mips64/pmap.c
index 48ecd80f6d3..c2b198ff87f 100644
--- a/sys/arch/mips64/mips64/pmap.c
+++ b/sys/arch/mips64/mips64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.63 2012/05/10 21:12:26 miod Exp $ */
+/* $OpenBSD: pmap.c,v 1.64 2012/09/29 19:11:08 miod Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -207,7 +207,7 @@ pmap_invalidate_user_page(pmap_t pmap, vaddr_t va)
if (cpumask == 1 << cpuid) {
u_long asid;
- asid = pmap->pm_asid[cpuid].pma_asid << VMTLB_PID_SHIFT;
+ asid = pmap->pm_asid[cpuid].pma_asid << PG_ASID_SHIFT;
tlb_flush_addr(va | asid);
} else if (cpumask) {
struct pmap_invalidate_page_arg arg;
@@ -227,7 +227,7 @@ pmap_invalidate_user_page_action(void *arg)
unsigned int cpuid = cpu_number();
u_long asid;
- asid = pmap->pm_asid[cpuid].pma_asid << VMTLB_PID_SHIFT;
+ asid = pmap->pm_asid[cpuid].pma_asid << PG_ASID_SHIFT;
tlb_flush_addr(va | asid);
}
@@ -289,7 +289,7 @@ pmap_update_user_page(pmap_t pmap, vaddr_t va, pt_entry_t entry)
if (cpumask == 1 << cpuid) {
u_long asid;
- asid = pmap->pm_asid[cpuid].pma_asid << VMTLB_PID_SHIFT;
+ asid = pmap->pm_asid[cpuid].pma_asid << PG_ASID_SHIFT;
tlb_update(va | asid, entry);
} else if (cpumask) {
struct pmap_update_page_arg arg;
@@ -310,7 +310,7 @@ pmap_update_user_page_action(void *arg)
unsigned int cpuid = cpu_number();
u_long asid;
- asid = pmap->pm_asid[cpuid].pma_asid << VMTLB_PID_SHIFT;
+ asid = pmap->pm_asid[cpuid].pma_asid << PG_ASID_SHIFT;
tlb_update(va | asid, entry);
}
#else
@@ -318,7 +318,7 @@ void
pmap_invalidate_user_page(pmap_t pmap, vaddr_t va)
{
u_long cpuid = cpu_number();
- u_long asid = pmap->pm_asid[cpuid].pma_asid << VMTLB_PID_SHIFT;
+ u_long asid = pmap->pm_asid[cpuid].pma_asid << PG_ASID_SHIFT;
if (pmap->pm_asid[cpuid].pma_asidgen ==
pmap_asid_info[cpuid].pma_asidgen)
@@ -329,7 +329,7 @@ void
pmap_update_user_page(pmap_t pmap, vaddr_t va, pt_entry_t entry)
{
u_long cpuid = cpu_number();
- u_long asid = pmap->pm_asid[cpuid].pma_asid << VMTLB_PID_SHIFT;
+ u_long asid = pmap->pm_asid[cpuid].pma_asid << PG_ASID_SHIFT;
if (pmap->pm_asid[cpuid].pma_asidgen ==
pmap_asid_info[cpuid].pma_asidgen)
@@ -384,7 +384,7 @@ pmap_bootstrap(void)
for (i = 0; i < MAXCPUS; i++) {
pmap_asid_info[i].pma_asidgen = 1;
- pmap_asid_info[i].pma_asid = 2;
+ pmap_asid_info[i].pma_asid = MIN_USER_ASID + 1;
}
}
@@ -504,10 +504,10 @@ extern struct user *proc0paddr;
if (pmap == vmspace0.vm_map.pmap) {
/*
* The initial process has already been allocated a TLBPID
- * in mach_init().
+ * in mips_init().
*/
for (i = 0; i < ncpusfound; i++) {
- pmap->pm_asid[i].pma_asid = 1;
+ pmap->pm_asid[i].pma_asid = MIN_USER_ASID;
pmap->pm_asid[i].pma_asidgen =
pmap_asid_info[i].pma_asidgen;
}
@@ -648,7 +648,7 @@ pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
panic("pmap_remove(%p, %p): not in range", sva, eva);
#endif
pte = kvtopte(sva);
- for(; sva < eva; sva += NBPG, pte++) {
+ for(; sva < eva; sva += PAGE_SIZE, pte++) {
entry = *pte;
if (!(entry & PG_V))
continue;
@@ -689,7 +689,7 @@ pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
* Invalidate every valid mapping within this segment.
*/
pte += uvtopte(sva);
- for (; sva < nssva; sva += NBPG, pte++) {
+ for (; sva < nssva; sva += PAGE_SIZE, pte++) {
entry = *pte;
if (!(entry & PG_V))
continue;
@@ -772,8 +772,7 @@ void
pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
{
vaddr_t nssva;
- pt_entry_t *pte, entry;
- u_int p;
+ pt_entry_t *pte, entry, p;
struct cpu_info *ci = curcpu();
DPRINTF(PDB_FOLLOW|PDB_PROTECT,
@@ -801,7 +800,7 @@ pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
panic("pmap_protect(%p, %p): not in range", sva, eva);
#endif
pte = kvtopte(sva);
- for (; sva < eva; sva += NBPG, pte++) {
+ for (; sva < eva; sva += PAGE_SIZE, pte++) {
entry = *pte;
if (!(entry & PG_V))
continue;
@@ -838,7 +837,7 @@ pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
* Change protection on every valid mapping within this segment.
*/
pte += uvtopte(sva);
- for (; sva < nssva; sva += NBPG, pte++) {
+ for (; sva < nssva; sva += PAGE_SIZE, pte++) {
entry = *pte;
if (!(entry & PG_V))
continue;
@@ -940,7 +939,7 @@ pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
pte = kvtopte(va);
if ((*pte & PG_V) && pa != pfn_to_pad(*pte)) {
- pmap_remove(pmap, va, va + NBPG);
+ pmap_remove(pmap, va, va + PAGE_SIZE);
stat_count(enter_stats.mchange);
}
if ((*pte & PG_V) == 0) {
@@ -998,7 +997,7 @@ pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
* MIPS pages in a OpenBSD page.
*/
if ((*pte & PG_V) && pa != pfn_to_pad(*pte)) {
- pmap_remove(pmap, va, va + NBPG);
+ pmap_remove(pmap, va, va + PAGE_SIZE);
stat_count(enter_stats.mchange);
}
if ((*pte & PG_V) == 0) {
@@ -1475,12 +1474,12 @@ pmap_alloc_tlbpid(struct proc *p)
if (pmap->pm_asid[cpuid].pma_asidgen !=
pmap_asid_info[cpuid].pma_asidgen) {
id = pmap_asid_info[cpuid].pma_asid;
- if (id >= VMNUM_PIDS) {
- tlb_flush(ci->ci_hw.tlbsize);
+ if (id >= PG_ASID_COUNT) {
+ tlb_asid_wrap(ci);
/* reserve tlbpid_gen == 0 to alway mean invalid */
if (++pmap_asid_info[cpuid].pma_asidgen == 0)
pmap_asid_info[cpuid].pma_asidgen = 1;
- id = 1;
+ id = MIN_USER_ASID;
}
pmap_asid_info[cpuid].pma_asid = id + 1;
pmap->pm_asid[cpuid].pma_asid = id;