Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/cortex Add Cortex-A9 support including the ARM ...



details:   https://anonhg.NetBSD.org/src/rev/0c31d55e0ac0
branches:  trunk
changeset: 781315:0c31d55e0ac0
user:      matt <matt%NetBSD.org@localhost>
date:      Sat Sep 01 00:03:14 2012 +0000

description:
Add Cortex-A9 support including the ARM Generic Interrupt Controller
and the A9 Global Timer / Watchdog.

diffstat:

 sys/arch/arm/cortex/a9_mpsubr.S  |  401 +++++++++++++++++++++++++++
 sys/arch/arm/cortex/a9tmr.c      |  324 +++++++++++++++++++++
 sys/arch/arm/cortex/a9tmr_intr.h |   42 ++
 sys/arch/arm/cortex/a9tmr_reg.h  |   93 ++++++
 sys/arch/arm/cortex/a9tmr_var.h  |   52 +++
 sys/arch/arm/cortex/a9wdt.c      |  249 ++++++++++++++++
 sys/arch/arm/cortex/armperiph.c  |  177 +++++++++++
 sys/arch/arm/cortex/files.cortex |   20 +
 sys/arch/arm/cortex/gic.c        |  576 +++++++++++++++++++++++++++++++++++++++
 sys/arch/arm/cortex/gic_intr.h   |   56 +++
 sys/arch/arm/cortex/gic_reg.h    |  202 +++++++++++++
 sys/arch/arm/cortex/mpcore_var.h |   40 ++
 sys/arch/arm/cortex/scu_reg.h    |   71 ++++
 13 files changed, 2303 insertions(+), 0 deletions(-)

diffs (truncated from 2355 to 300 lines):

diff -r 6f1f9308cf53 -r 0c31d55e0ac0 sys/arch/arm/cortex/a9_mpsubr.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/cortex/a9_mpsubr.S   Sat Sep 01 00:03:14 2012 +0000
@@ -0,0 +1,401 @@
+/*     $NetBSD: a9_mpsubr.S,v 1.1 2012/09/01 00:03:14 matt Exp $       */
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 THE FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#include "opt_cpuoptions.h"
+#include "opt_cputypes.h"
+#include "opt_multiprocessor.h"
+
+#include <arm/asm.h>
+#include <arm/armreg.h>
+#include "assym.h"
+
+/*
+ * Set up a preliminary mapping in the MMU to allow us to run
+ * at KERNEL_BASE with caches on.
+ */
+arm_boot_l1pt_init:
+       mv      ip, r1                  @ save mmu table addr
+       /* Build page table from scratch */
+       mov     r1, r0                  /* Start address to clear memory. */
+       /* Zero the entire table so all virtual addresses are invalid. */
+       mov     r2, #L1_TABLE_SIZE      /* in bytes */
+       mov     r3, #0
+       mov     r4, r3
+       mov     r5, r3
+       mov     r6, r3
+       mov     r7, r3
+       mov     r8, r3
+       mov     r10, r3
+       mov     r11, r3
+1:     stmia   r1!, {r3-r8,r10-r11}
+       stmia   r1!, {r3-r8,r10-r11}
+       stmia   r1!, {r3-r8,r10-r11}
+       stmia   r1!, {r3-r8,r10-r11}
+       subs    r2, r2, #(4 * 4 * 8)    /* bytes per loop */
+       bne     1b
+
+       /* Now create our entries per the mmu_init_table. */
+       l1table .req r0
+       va      .req r1
+       pa      .req r2
+       n_sec   .req r3
+       attr    .req r4
+       itable  .req r5
+
+       mov     itable, ip              @ reclaim table address
+       b       3f
+
+2:     str     pa, [l1table, va]
+       add     va, va, #4
+       add     pa, pa, #(L1_S_SIZE)
+       subs    n_sec, n_sec, #1
+       bhi     2b
+
+3:     ldmia   itable!, {va,pa,n_sec,attr}
+       /* Convert va to l1 offset:     va = 4 * (va >> L1_S_SHIFT)     */
+       lsr     va, va, #L1_S_SHIFT
+       lsl     va, va, #2
+       /* Convert pa to l1 entry:      pa = (pa & L1_S_FRAME) | attr   */
+#ifdef _ARM_ARCH_7
+       bfc     pa, #0, #L1_S_SHIFT
+#else
+       lsr     pa, pa, #L1_S_SHIFT
+       lsl     pa, pa, #L1_S_SHIFT
+#ndif
+       orr     pa, pa, attr
+       cmp     n_sec, #0
+       bne     2b
+       bx      lr                      @ return
+
+       .unreq  va
+       .unreq  pa
+       .unreq  n_sec
+       .unreq  attr
+       .unreq  itable
+       .unreq  l1table
+
+.Lctl_ID:
+       .word   CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE
+
+a9_cpuinit:
+       /*
+        * In theory, because the MMU is off, we shouldn't need all of this,
+        * but let's not take any chances and do a typical sequence to set
+        * the Translation Table Base.
+        */
+       mov     ip, lr
+       mov     r10, r0
+
+       mrc     p15, 0, r2, c1, c0, 0   /*  "       "   "     */
+       bic     r2, r2, #CPU_CONTROL_DC_ENABLE  @ clear data cache enable
+       bic     r2, r2, #CPU_CONTROL_IC_ENABLE  @ clear instruction cache enable
+       mcr     p15, 0, r2, c1, c0, 0   /*  "       "   "     */
+
+       XPUTC(#70)
+       mov     r1, #0
+       mcr     p15, 0, r1, c7, c10, 4  /* Drain the write buffers. */
+
+       XPUTC(#71)
+       mcr     p15, 0, r10, c2, c0, 0  /* Set Translation Table Base */
+
+       XPUTC(#72)
+       mov     r1, #0
+       mcr     p15, 0, r1, c8, c7, 0   /* Invalidate TLBs */
+
+       /* Set the Domain Access register.  Very important! */
+       XPUTC(#74)
+       mov     r1, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
+       mcr     p15, 0, r1, c3, c0, 0
+
+       /*
+        * Enable the MMU, etc.
+        */
+       XPUTC(#75)
+       mrc     p15, 0, r0, c1, c0, 0
+
+       ldr     r2, .Lcontrol_clr
+       bic     r0, r0, r2
+       ldr     r3, .Lcontrol_set
+       orr     r0, r0, r3
+       
+       dsb
+       .align 5
+       @ turn mmu on!
+       mov     r0, r0
+       mcr     p15, 0, r0, c1, c0, 0
+
+       /*
+        * Ensure that the coprocessor has finished turning on the MMU.
+        */
+       mrc     p15, 0, r0, c0, c0, 0   /* Read an arbitrary value. */
+       mov     r0, r0                  /* Stall until read completes. */
+
+       bx      ip                      /* return */
+
+#if defined(VERBOSE_INIT_ARM) && XPUTC
+#define        TIMO    0x25000
+xputc:
+#ifdef MULTIPROCESSOR
+       mov     r2, #1
+       ldr     r3, .Lcomlock
+10:
+       ldrex   r1, [r3]
+       cmp     r1, #0
+       bne     10b
+       strex   r1, r2, [r3]
+       cmp     r1, #0
+       bne     10b
+#endif
+
+       mov     r2, #TIMO
+       ldr     r3, .Luart0
+1:     ldrb    r1, [r3, #COM_LSR]
+       tst     r1, #LSR_TXRDY
+       bne     2f
+       subs    r2, r2, #1
+       bne     1b
+2:
+       strb    r0, [r3, #COM_DATA]
+
+       mov     r2, #TIMO
+3:     ldrb    r1, [r3, #COM_LSR]
+       tst     r1, #LSR_TSRE
+       bne     4f
+       subs    r2, r2, #1
+       bne     3b
+4:
+#ifdef MULTIPROCESSOR
+       ldr     r3, .Lcomlock
+       mov     r0, #0
+       str     r0, [r3]
+       dsb
+#endif
+       bx      lr
+
+.Luart0:
+       .word   CONSADDR
+
+#ifdef MULTIPROCESSOR
+.Lcomlock:
+       .word   comlock
+
+       .pushsection .data
+comlock:
+       .p2align 2
+       .word   0               @ not in bss
+
+       .popsection
+#endif /* MULTIPROCESSOR */
+#endif /* VERBOSE_INIT_ARM */
+
+#ifdef CPU_CORTEXA9
+a9_start:
+       mov     r10, lr                         @ save lr
+
+       cpsid   if, #PSR_SVC32_MODE
+
+       XPUTC(#64)
+       bl      _C_LABEL(armv7_icache_inv_all)  @ invalidate i-cache
+
+       /*
+        * Step 1a, invalidate the all cache tags in all ways on the SCU.
+        */
+       XPUTC(#65)
+       mrc     p15, 4, r3, c15, c0, 0          @ read cbar
+       ldr     r0, [r3, #4]                    @ read scu config
+       and     r0, r0, #7                      @ get cpu max
+       add     r0, r0, #1                      @ adjust to cpu num
+       lsl     r0, r0, #4                      @ multiply by 16
+       sub     r0, r0, #1                      @ make it into a mask
+       str     r0, [r3, #12]                   @ write scu invalidate all
+       dsb
+       isb
+
+       /*
+        * Step 1b, invalidate the data cache
+        */
+       XPUTC(#66)
+       bl      _C_LABEL(armv7_dcache_wbinv_all)        @ writeback/invalidate d-cache
+
+       /*
+        * Step 2, disable the data cache
+        */
+       mrc     p15, 0, r2, c1, c0, 0           @ get system ctl register (save)
+       bic     r1, r2, #CPU_CONTROL_DC_ENABLE  @ clear data cache enable
+       mcr     p15, 0, r1, c1, c0, 0           @ set system ctl register
+       isb
+
+       /*
+        * Step 3, enable the SCU (and set SMP mode)
+        */
+       ldr     r1, [r3, #4]                    @ read scu config
+       orr     r1, r1, #0xf0                   @ set smp mode
+       str     r1, [r3, #4]                    @ write scu config
+       ldr     r1, [r3, #0]                    @ read scu control
+       orr     r1, r1, #1                      @ set scu enable flag
+       str     r1, [r3, #4]                    @ write scu control
+       dsb
+       isb
+
+       /*
+        * Step 4a, enable the data cache
+        */
+       mcr     p15, 0, r2, c1, c0, 0           @ reenable caches
+       isb
+
+       /*
+        * Step 4b, set ACTLR.SMP=1 (and ACTRL.FX=1)
+        */
+       mrc     p15, 0, r0, c1, c0, 1           @ read aux ctl
+       orr     r0, #0x41                       @ enable cache/tlb/coherency
+       mcr     p15, 0, r0, c1, c0, 1           @ write aux ctl
+       isb
+
+       bx      r10
+ASEND(a9_startup)
+
+/*
+ * Secondary processors come here after exiting the SKU ROM.
+ */
+a9_mpstart:
+#ifdef MULTIPROCESSOR
+       /*
+        * Step 1, invalidate the caches
+        */
+       bl      _C_LABEL(armv7_icache_inv_all)  @ toss i-cache
+       bl      _C_LABEL(armv7_dcache_inv_all)  @ toss d-cache
+
+       /*
+        * Step 2, wait for the SCU to be enabled



Home | Main Index | Thread Index | Old Index