Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm Add the generic arm32 bits of the new pmap, con...
details: https://anonhg.NetBSD.org/src/rev/6f1d8b5efc40
branches: trunk
changeset: 545964:6f1d8b5efc40
user: scw <scw%NetBSD.org@localhost>
date: Fri Apr 18 11:08:24 2003 +0000
description:
Add the generic arm32 bits of the new pmap, contributed by Wasabi Systems.
Some features of the new pmap are:
- It allows L1 descriptor tables to be shared efficiently between
multiple processes. A typical "maxusers 32" kernel, where NPROC is set
to 532, requires 35 L1s. A "maxusers 2" kernel runs quite happily
with just 4 L1s. This completely solves the problem of running out
of contiguous physical memory for allocating new L1s at runtime on a
busy system.
- Much improved cache/TLB management "smarts". This change ripples
out to encompass the low-level context switch code, which is also
much smarter about when to flush the cache/TLB, and when not to.
- Faster allocation of L2 page tables and associated metadata thanks,
in part, to the pool_cache enhancements recently contributed to
NetBSD by Wasabi Systems.
- Faster VM space teardown due to accurate referenced tracking of L2
page tables.
- Better/faster cache-alias tracking.
The new pmap is enabled by adding options ARM32_PMAP_NEW to the kernel
config file, and making the necessary changes to the port-specific
initarm() function. Several ports have already been converted and will
be committed shortly.
diffstat:
sys/arch/arm/arm32/arm32_machdep.c | 17 +-
sys/arch/arm/arm32/bus_dma.c | 13 +-
sys/arch/arm/arm32/cpuswitch.S | 321 ++-
sys/arch/arm/arm32/db_interface.c | 24 +-
sys/arch/arm/arm32/fault.c | 392 +-
sys/arch/arm/arm32/genassym.cf | 29 +-
sys/arch/arm/arm32/pmap_new.c | 4855 ++++++++++++++++++++++++++++++++++
sys/arch/arm/arm32/vm_machdep.c | 5 +-
sys/arch/arm/conf/files.arm | 10 +-
sys/arch/arm/include/arm32/pmap.h | 194 +-
sys/arch/arm/include/arm32/pte.h | 11 +-
sys/arch/arm/include/arm32/types.h | 9 +-
sys/arch/arm/include/arm32/vmparam.h | 40 +-
sys/arch/arm/include/pcb.h | 14 +-
14 files changed, 5731 insertions(+), 203 deletions(-)
diffs (truncated from 6584 to 300 lines):
diff -r f307c6bc5970 -r 6f1d8b5efc40 sys/arch/arm/arm32/arm32_machdep.c
--- a/sys/arch/arm/arm32/arm32_machdep.c Fri Apr 18 10:51:35 2003 +0000
+++ b/sys/arch/arm/arm32/arm32_machdep.c Fri Apr 18 11:08:24 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arm32_machdep.c,v 1.30 2003/04/18 10:51:35 scw Exp $ */
+/* $NetBSD: arm32_machdep.c,v 1.31 2003/04/18 11:08:24 scw Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
@@ -73,7 +73,7 @@
extern int physmem;
-#ifndef PMAP_STATIC_L1S
+#if !defined(PMAP_STATIC_L1S) && !defined(ARM32_PMAP_NEW)
extern int max_processes;
#endif /* !PMAP_STATIC_L1S */
#if NMD > 0 && defined(MEMORY_DISK_HOOKS) && !defined(MEMORY_DISK_ROOT_SIZE)
@@ -211,14 +211,19 @@
u_int loop, base, residual;
char pbuf[9];
+#ifndef ARM32_PMAP_NEW
+ /* This has moved to initarm() */
proc0paddr = (struct user *)kernelstack.pv_va;
lwp0.l_addr = proc0paddr;
+#endif
/* Set the cpu control register */
cpu_setup(boot_args);
+#ifndef ARM32_PMAP_NEW
/* All domains MUST be clients, permissions are VERY important */
cpu_domains(DOMAIN_CLIENT);
+#endif
/* Lock down zero page */
vector_page_setprot(VM_PROT_READ);
@@ -342,8 +347,12 @@
USPACE_UNDEF_STACK_TOP;
curpcb->pcb_un.un_32.pcb32_sp = (u_int)lwp0.l_addr +
USPACE_SVC_STACK_TOP;
+#ifndef ARM32_PMAP_NEW
(void) pmap_extract(pmap_kernel(), (vaddr_t)(pmap_kernel())->pm_pdir,
&curpcb->pcb_pagedir);
+#else
+ pmap_set_pcb_pagedir(pmap_kernel(), curpcb);
+#endif
curpcb->pcb_tf = (struct trapframe *)curpcb->pcb_un.un_32.pcb32_sp - 1;
}
@@ -446,7 +455,7 @@
/* if (get_bootconf_option(args, "nbuf", BOOTOPT_TYPE_INT, &integer))
bufpages = integer;*/
-#ifndef PMAP_STATIC_L1S
+#if !defined(PMAP_STATIC_L1S) && !defined(ARM32_PMAP_NEW)
if (get_bootconf_option(args, "maxproc", BOOTOPT_TYPE_INT, &integer)) {
max_processes = integer;
if (max_processes < 16)
@@ -455,7 +464,7 @@
if (max_processes > 255)
max_processes = 255;
}
-#endif /* !PMAP_STATUC_L1S */
+#endif /* !PMAP_STATUC_L1S && !ARM32_PMAP_NEW */
#if NMD > 0 && defined(MEMORY_DISK_HOOKS) && !defined(MEMORY_DISK_ROOT_SIZE)
if (get_bootconf_option(args, "memorydisc", BOOTOPT_TYPE_INT, &integer)
|| get_bootconf_option(args, "memorydisk", BOOTOPT_TYPE_INT, &integer)) {
diff -r f307c6bc5970 -r 6f1d8b5efc40 sys/arch/arm/arm32/bus_dma.c
--- a/sys/arch/arm/arm32/bus_dma.c Fri Apr 18 10:51:35 2003 +0000
+++ b/sys/arch/arm/arm32/bus_dma.c Fri Apr 18 11:08:24 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bus_dma.c,v 1.28 2003/04/09 18:51:35 thorpej Exp $ */
+/* $NetBSD: bus_dma.c,v 1.29 2003/04/18 11:08:25 scw Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -878,6 +878,9 @@
pt_entry_t pte;
int seg;
pmap_t pmap;
+#ifdef ARM32_PMAP_NEW
+ pt_entry_t *ptep;
+#endif
#ifdef DEBUG_DMA
printf("_bus_dmamem_load_buffer(buf=%p, len=%lx, flags=%d, 1st=%d)\n",
@@ -900,7 +903,11 @@
* XXX in user address space.
*/
if (__predict_true(pmap == pmap_kernel())) {
+#ifndef ARM32_PMAP_NEW
pde = pmap_pde(pmap, vaddr);
+#else
+ (void) pmap_get_pde_pte(pmap, vaddr, &pde, &ptep);
+#endif
if (__predict_false(pmap_pde_section(pde))) {
curaddr = (*pde & L1_S_FRAME) |
(vaddr & L1_S_OFFSET);
@@ -909,7 +916,11 @@
~ARM32_DMAMAP_COHERENT;
}
} else {
+#ifndef ARM32_PMAP_NEW
pte = *vtopte(vaddr);
+#else
+ pte = *ptep;
+#endif
KDASSERT((pte & L2_TYPE_MASK) != L2_TYPE_INV);
if (__predict_false((pte & L2_TYPE_MASK)
== L2_TYPE_L)) {
diff -r f307c6bc5970 -r 6f1d8b5efc40 sys/arch/arm/arm32/cpuswitch.S
--- a/sys/arch/arm/arm32/cpuswitch.S Fri Apr 18 10:51:35 2003 +0000
+++ b/sys/arch/arm/arm32/cpuswitch.S Fri Apr 18 11:08:24 2003 +0000
@@ -1,6 +1,40 @@
-/* $NetBSD: cpuswitch.S,v 1.29 2003/01/17 22:28:49 thorpej Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.30 2003/04/18 11:08:25 scw Exp $ */
/*
+ * Copyright 2003 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Steve C. Woodford for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
* Copyright (c) 1994-1998 Mark Brinicombe.
* Copyright (c) 1994 Brini.
* All rights reserved.
@@ -44,6 +78,7 @@
*/
#include "opt_armfpe.h"
+#include "opt_arm32_pmap.h"
#include "opt_multiprocessor.h"
#include "assym.h"
@@ -70,6 +105,25 @@
bic r14, r14, #(I32_bit) ; \
msr cpsr_c, r14 ; \
+#ifdef ARM32_PMAP_NEW
+/*
+ * These are used for switching the translation table/DACR.
+ * Since the vector page can be invalid for a short time, we must
+ * disable both regular IRQs *and* FIQs.
+ *
+ * XXX: This is not necessary if the vector table is relocated.
+ */
+#define IRQdisableALL \
+ mrs r14, cpsr ; \
+ orr r14, r14, #(I32_bit | F32_bit) ; \
+ msr cpsr_c, r14
+
+#define IRQenableALL \
+ mrs r14, cpsr ; \
+ bic r14, r14, #(I32_bit | F32_bit) ; \
+ msr cpsr_c, r14
+#endif
+
.text
.Lwhichqs:
@@ -122,6 +176,14 @@
.Lcpu_do_powersave:
.word _C_LABEL(cpu_do_powersave)
+#ifdef ARM32_PMAP_NEW
+.Lpmap_kernel_cstate:
+ .word (kernel_pmap_store + PMAP_CSTATE)
+
+.Llast_cache_state_ptr:
+ .word _C_LABEL(pmap_cache_state)
+#endif
+
/*
* Idle loop, exercised while waiting for a process to wake up.
*
@@ -463,10 +525,10 @@
ldr r10, [r8, #(PCB_PAGEDIR)] /* r10 = old L1 */
ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
+#ifndef ARM32_PMAP_NEW
ldr r3, .Lblock_userspace_access
mov r1, #0x00000001
mov r2, #0x00000000
-
teq r10, r11 /* r10 == r11? */
beq .Lcs_context_switched /* yes! */
@@ -509,6 +571,165 @@
ldr pc, [r3, #CF_CONTEXT_SWITCH]
.Lcs_context_switched:
+
+
+#else /* ARM32_PMAP_NEW */
+
+ ldr r0, [r8, #(PCB_DACR)] /* r0 = old DACR */
+ ldr r1, [r9, #(PCB_DACR)] /* r1 = new DACR */
+ ldr r8, [r9, #(PCB_CSTATE)] /* r8 = &new_pmap->pm_cstate */
+ ldr r5, .Llast_cache_state_ptr /* Previous thread's cstate */
+
+ teq r10, r11 /* Same L1? */
+ ldr r5, [r5]
+ cmpeq r0, r1 /* Same DACR? */
+ beq .Lcs_context_switched /* yes! */
+
+ ldr r3, .Lblock_userspace_access
+ mov r12, #0
+ cmp r5, #0 /* No last vm? (switch_exit) */
+ beq .Lcs_cache_purge_skipped /* No, we can skip cache flsh */
+
+ mov r2, #DOMAIN_CLIENT
+ cmp r1, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */
+ beq .Lcs_cache_purge_skipped /* Yup. Don't flush cache */
+
+ cmp r5, r8 /* Same userland VM space? */
+ ldrneb r12, [r5, #(CS_CACHE_ID)] /* Last VM space cache state */
+
+ /*
+ * We're definately switching to a new userland VM space,
+ * and the previous userland VM space has yet to be flushed
+ * from the cache/tlb.
+ *
+ * r12 holds the previous VM space's cs_cache_id state
+ */
+ tst r12, #0xff /* Test cs_cache_id */
+ beq .Lcs_cache_purge_skipped /* VM space is not in cache */
+
+ /*
+ * Definately need to flush the cache.
+ * Mark the old VM space as NOT being resident in the cache.
+ */
+ mov r2, #0x00000000
+ strh r2, [r5, #(CS_CACHE_ID)]
+
+ /*
+ * Don't allow user space access between the purge and the switch.
+ */
+ mov r2, #0x00000001
+ str r2, [r3]
+
+ stmfd sp!, {r0-r3}
+ ldr r1, .Lcpufuncs
+ mov lr, pc
+ ldr pc, [r1, #CF_IDCACHE_WBINV_ALL]
+ ldmfd sp!, {r0-r3}
+
+.Lcs_cache_purge_skipped:
+ /* rem: r1 = new DACR */
+ /* rem: r3 = &block_userspace_access */
+ /* rem: r4 = return value */
+ /* rem: r5 = &old_pmap->pm_cstate (or NULL) */
+ /* rem: r6 = new lwp */
+ /* rem: r8 = &new_pmap->pm_cstate */
+ /* rem: r9 = new PCB */
+ /* rem: r10 = old L1 */
+ /* rem: r11 = new L1 */
+
+ mov r2, #0x00000000
+ ldr r7, [r9, #(PCB_PL1VEC)]
+
+ /*
+ * At this point we need to kill IRQ's again.
+ *
+ * XXXSCW: Don't need to block FIQs if vectors have been relocated
+ */
+ IRQdisableALL
+
+ /*
+ * Interrupts are disabled so we can allow user space accesses again
Home |
Main Index |
Thread Index |
Old Index