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