linux/arch/arm/kernel/head-nommu.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 *  linux/arch/arm/kernel/head-nommu.S
   4 *
   5 *  Copyright (C) 1994-2002 Russell King
   6 *  Copyright (C) 2003-2006 Hyok S. Choi
   7 *
   8 *  Common kernel startup code (non-paged MM)
   9 */
  10#include <linux/linkage.h>
  11#include <linux/init.h>
  12#include <linux/errno.h>
  13
  14#include <asm/assembler.h>
  15#include <asm/ptrace.h>
  16#include <asm/asm-offsets.h>
  17#include <asm/memory.h>
  18#include <asm/cp15.h>
  19#include <asm/thread_info.h>
  20#include <asm/v7m.h>
  21#include <asm/mpu.h>
  22#include <asm/page.h>
  23
  24/*
  25 * Kernel startup entry point.
  26 * ---------------------------
  27 *
  28 * This is normally called from the decompressor code.  The requirements
  29 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
  30 * r1 = machine nr.
  31 *
  32 * See linux/arch/arm/tools/mach-types for the complete list of machine
  33 * numbers for r1.
  34 *
  35 */
  36
  37        __HEAD
  38
  39#ifdef CONFIG_CPU_THUMBONLY
  40        .thumb
  41ENTRY(stext)
  42#else
  43        .arm
  44ENTRY(stext)
  45
  46 THUMB( badr    r9, 1f          )       @ Kernel is always entered in ARM.
  47 THUMB( bx      r9              )       @ If this is a Thumb-2 kernel,
  48 THUMB( .thumb                  )       @ switch to Thumb now.
  49 THUMB(1:                       )
  50#endif
  51
  52#ifdef CONFIG_ARM_VIRT_EXT
  53        bl      __hyp_stub_install
  54#endif
  55        @ ensure svc mode and all interrupts masked
  56        safe_svcmode_maskall r9
  57                                                @ and irqs disabled
  58#if defined(CONFIG_CPU_CP15)
  59        mrc     p15, 0, r9, c0, c0              @ get processor id
  60#elif defined(CONFIG_CPU_V7M)
  61        ldr     r9, =BASEADDR_V7M_SCB
  62        ldr     r9, [r9, V7M_SCB_CPUID]
  63#else
  64        ldr     r9, =CONFIG_PROCESSOR_ID
  65#endif
  66        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
  67        movs    r10, r5                         @ invalid processor (r5=0)?
  68        beq     __error_p                               @ yes, error 'p'
  69
  70#ifdef CONFIG_ARM_MPU
  71        bl      __setup_mpu
  72#endif
  73
  74        badr    lr, 1f                          @ return (PIC) address
  75        ldr     r12, [r10, #PROCINFO_INITFUNC]
  76        add     r12, r12, r10
  77        ret     r12
  781:      ldr     lr, =__mmap_switched
  79        b       __after_proc_init
  80ENDPROC(stext)
  81
  82#ifdef CONFIG_SMP
  83        .text
  84ENTRY(secondary_startup)
  85        /*
  86         * Common entry point for secondary CPUs.
  87         *
  88         * Ensure that we're in SVC mode, and IRQs are disabled.  Lookup
  89         * the processor type - there is no need to check the machine type
  90         * as it has already been validated by the primary processor.
  91         */
  92#ifdef CONFIG_ARM_VIRT_EXT
  93        bl      __hyp_stub_install_secondary
  94#endif
  95        safe_svcmode_maskall r9
  96
  97#ifndef CONFIG_CPU_CP15
  98        ldr     r9, =CONFIG_PROCESSOR_ID
  99#else
 100        mrc     p15, 0, r9, c0, c0              @ get processor id
 101#endif
 102        bl      __lookup_processor_type         @ r5=procinfo r9=cpuid
 103        movs    r10, r5                         @ invalid processor?
 104        beq     __error_p                       @ yes, error 'p'
 105
 106        ldr     r7, __secondary_data
 107
 108#ifdef CONFIG_ARM_MPU
 109        bl      __secondary_setup_mpu           @ Initialize the MPU
 110#endif
 111
 112        badr    lr, 1f                          @ return (PIC) address
 113        ldr     r12, [r10, #PROCINFO_INITFUNC]
 114        add     r12, r12, r10
 115        ret     r12
 1161:      bl      __after_proc_init
 117        ldr     sp, [r7, #12]                   @ set up the stack pointer
 118        mov     fp, #0
 119        b       secondary_start_kernel
 120ENDPROC(secondary_startup)
 121
 122        .type   __secondary_data, %object
 123__secondary_data:
 124        .long   secondary_data
 125#endif /* CONFIG_SMP */
 126
 127/*
 128 * Set the Control Register and Read the process ID.
 129 */
 130        .text
 131__after_proc_init:
 132M_CLASS(movw    r12, #:lower16:BASEADDR_V7M_SCB)
 133M_CLASS(movt    r12, #:upper16:BASEADDR_V7M_SCB)
 134#ifdef CONFIG_ARM_MPU
 135M_CLASS(ldr     r3, [r12, 0x50])
 136AR_CLASS(mrc    p15, 0, r3, c0, c1, 4)          @ Read ID_MMFR0
 137        and     r3, r3, #(MMFR0_PMSA)           @ PMSA field
 138        teq     r3, #(MMFR0_PMSAv7)             @ PMSA v7
 139        beq     1f
 140        teq     r3, #(MMFR0_PMSAv8)             @ PMSA v8
 141        /*
 142         * Memory region attributes for PMSAv8:
 143         *
 144         *   n = AttrIndx[2:0]
 145         *                      n       MAIR
 146         *   DEVICE_nGnRnE      000     00000000
 147         *   NORMAL             001     11111111
 148         */
 149        ldreq   r3, =PMSAv8_MAIR(0x00, PMSAv8_RGN_DEVICE_nGnRnE) | \
 150                     PMSAv8_MAIR(0xff, PMSAv8_RGN_NORMAL)
 151AR_CLASS(mcreq  p15, 0, r3, c10, c2, 0)         @ MAIR 0
 152M_CLASS(streq   r3, [r12, #PMSAv8_MAIR0])
 153        moveq   r3, #0
 154AR_CLASS(mcreq  p15, 0, r3, c10, c2, 1)         @ MAIR 1
 155M_CLASS(streq   r3, [r12, #PMSAv8_MAIR1])
 156
 1571:
 158#endif
 159#ifdef CONFIG_CPU_CP15
 160        /*
 161         * CP15 system control register value returned in r0 from
 162         * the CPU init function.
 163         */
 164
 165#ifdef CONFIG_ARM_MPU
 166        biceq   r0, r0, #CR_BR                  @ Disable the 'default mem-map'
 167        orreq   r0, r0, #CR_M                   @ Set SCTRL.M (MPU on)
 168#endif
 169#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
 170        orr     r0, r0, #CR_A
 171#else
 172        bic     r0, r0, #CR_A
 173#endif
 174#ifdef CONFIG_CPU_DCACHE_DISABLE
 175        bic     r0, r0, #CR_C
 176#endif
 177#ifdef CONFIG_CPU_BPREDICT_DISABLE
 178        bic     r0, r0, #CR_Z
 179#endif
 180#ifdef CONFIG_CPU_ICACHE_DISABLE
 181        bic     r0, r0, #CR_I
 182#endif
 183        mcr     p15, 0, r0, c1, c0, 0           @ write control reg
 184        instr_sync
 185#elif defined (CONFIG_CPU_V7M)
 186#ifdef CONFIG_ARM_MPU
 187        ldreq   r3, [r12, MPU_CTRL]
 188        biceq   r3, #MPU_CTRL_PRIVDEFENA
 189        orreq   r3, #MPU_CTRL_ENABLE
 190        streq   r3, [r12, MPU_CTRL]
 191        isb
 192#endif
 193        /* For V7M systems we want to modify the CCR similarly to the SCTLR */
 194#ifdef CONFIG_CPU_DCACHE_DISABLE
 195        bic     r0, r0, #V7M_SCB_CCR_DC
 196#endif
 197#ifdef CONFIG_CPU_BPREDICT_DISABLE
 198        bic     r0, r0, #V7M_SCB_CCR_BP
 199#endif
 200#ifdef CONFIG_CPU_ICACHE_DISABLE
 201        bic     r0, r0, #V7M_SCB_CCR_IC
 202#endif
 203        str     r0, [r12, V7M_SCB_CCR]
 204        /* Pass exc_ret to __mmap_switched */
 205        mov     r0, r10
 206#endif /* CONFIG_CPU_CP15 elif CONFIG_CPU_V7M */
 207        ret     lr
 208ENDPROC(__after_proc_init)
 209        .ltorg
 210
 211#ifdef CONFIG_ARM_MPU
 212
 213
 214#ifndef CONFIG_CPU_V7M
 215/* Set which MPU region should be programmed */
 216.macro set_region_nr tmp, rgnr, unused
 217        mov     \tmp, \rgnr                     @ Use static region numbers
 218        mcr     p15, 0, \tmp, c6, c2, 0         @ Write RGNR
 219.endm
 220
 221/* Setup a single MPU region, either D or I side (D-side for unified) */
 222.macro setup_region bar, acr, sr, side = PMSAv7_DATA_SIDE, unused
 223        mcr     p15, 0, \bar, c6, c1, (0 + \side)       @ I/DRBAR
 224        mcr     p15, 0, \acr, c6, c1, (4 + \side)       @ I/DRACR
 225        mcr     p15, 0, \sr, c6, c1, (2 + \side)                @ I/DRSR
 226.endm
 227#else
 228.macro set_region_nr tmp, rgnr, base
 229        mov     \tmp, \rgnr
 230        str     \tmp, [\base, #PMSAv7_RNR]
 231.endm
 232
 233.macro setup_region bar, acr, sr, unused, base
 234        lsl     \acr, \acr, #16
 235        orr     \acr, \acr, \sr
 236        str     \bar, [\base, #PMSAv7_RBAR]
 237        str     \acr, [\base, #PMSAv7_RASR]
 238.endm
 239
 240#endif
 241/*
 242 * Setup the MPU and initial MPU Regions. We create the following regions:
 243 * Region 0: Use this for probing the MPU details, so leave disabled.
 244 * Region 1: Background region - covers the whole of RAM as strongly ordered
 245 * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6
 246 * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page
 247 *
 248 * r6: Value to be written to DRSR (and IRSR if required) for PMSAv7_RAM_REGION
 249*/
 250        __HEAD
 251
 252ENTRY(__setup_mpu)
 253
 254        /* Probe for v7 PMSA compliance */
 255M_CLASS(movw    r12, #:lower16:BASEADDR_V7M_SCB)
 256M_CLASS(movt    r12, #:upper16:BASEADDR_V7M_SCB)
 257
 258AR_CLASS(mrc    p15, 0, r0, c0, c1, 4)          @ Read ID_MMFR0
 259M_CLASS(ldr     r0, [r12, 0x50])
 260        and     r0, r0, #(MMFR0_PMSA)           @ PMSA field
 261        teq     r0, #(MMFR0_PMSAv7)             @ PMSA v7
 262        beq     __setup_pmsa_v7
 263        teq     r0, #(MMFR0_PMSAv8)             @ PMSA v8
 264        beq     __setup_pmsa_v8
 265
 266        ret     lr
 267ENDPROC(__setup_mpu)
 268
 269ENTRY(__setup_pmsa_v7)
 270        /* Calculate the size of a region covering just the kernel */
 271        ldr     r5, =PLAT_PHYS_OFFSET           @ Region start: PHYS_OFFSET
 272        ldr     r6, =(_end)                     @ Cover whole kernel
 273        sub     r6, r6, r5                      @ Minimum size of region to map
 274        clz     r6, r6                          @ Region size must be 2^N...
 275        rsb     r6, r6, #31                     @ ...so round up region size
 276        lsl     r6, r6, #PMSAv7_RSR_SZ          @ Put size in right field
 277        orr     r6, r6, #(1 << PMSAv7_RSR_EN)   @ Set region enabled bit
 278
 279        /* Determine whether the D/I-side memory map is unified. We set the
 280         * flags here and continue to use them for the rest of this function */
 281AR_CLASS(mrc    p15, 0, r0, c0, c0, 4)          @ MPUIR
 282M_CLASS(ldr    r0, [r12, #MPU_TYPE])
 283        ands    r5, r0, #MPUIR_DREGION_SZMASK   @ 0 size d region => No MPU
 284        bxeq    lr
 285        tst     r0, #MPUIR_nU                   @ MPUIR_nU = 0 for unified
 286
 287        /* Setup second region first to free up r6 */
 288        set_region_nr r0, #PMSAv7_RAM_REGION, r12
 289        isb
 290        /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */
 291        ldr     r0, =PLAT_PHYS_OFFSET           @ RAM starts at PHYS_OFFSET
 292        ldr     r5,=(PMSAv7_AP_PL1RW_PL0RW | PMSAv7_RGN_NORMAL)
 293
 294        setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12  @ PHYS_OFFSET, shared, enabled
 295        beq     1f                                      @ Memory-map not unified
 296        setup_region r0, r5, r6, PMSAv7_INSTR_SIDE, r12 @ PHYS_OFFSET, shared, enabled
 2971:      isb
 298
 299        /* First/background region */
 300        set_region_nr r0, #PMSAv7_BG_REGION, r12
 301        isb
 302        /* Execute Never,  strongly ordered, inaccessible to PL0, rw PL1  */
 303        mov     r0, #0                          @ BG region starts at 0x0
 304        ldr     r5,=(PMSAv7_ACR_XN | PMSAv7_RGN_STRONGLY_ORDERED | PMSAv7_AP_PL1RW_PL0NA)
 305        mov     r6, #PMSAv7_RSR_ALL_MEM         @ 4GB region, enabled
 306
 307        setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12  @ 0x0, BG region, enabled
 308        beq     2f                                      @ Memory-map not unified
 309        setup_region r0, r5, r6, PMSAv7_INSTR_SIDE r12  @ 0x0, BG region, enabled
 3102:      isb
 311
 312#ifdef CONFIG_XIP_KERNEL
 313        set_region_nr r0, #PMSAv7_ROM_REGION, r12
 314        isb
 315
 316        ldr     r5,=(PMSAv7_AP_PL1RO_PL0NA | PMSAv7_RGN_NORMAL)
 317
 318        ldr     r0, =CONFIG_XIP_PHYS_ADDR               @ ROM start
 319        ldr     r6, =(_exiprom)                         @ ROM end
 320        sub     r6, r6, r0                              @ Minimum size of region to map
 321        clz     r6, r6                                  @ Region size must be 2^N...
 322        rsb     r6, r6, #31                             @ ...so round up region size
 323        lsl     r6, r6, #PMSAv7_RSR_SZ                  @ Put size in right field
 324        orr     r6, r6, #(1 << PMSAv7_RSR_EN)           @ Set region enabled bit
 325
 326        setup_region r0, r5, r6, PMSAv7_DATA_SIDE, r12  @ XIP_PHYS_ADDR, shared, enabled
 327        beq     3f                                      @ Memory-map not unified
 328        setup_region r0, r5, r6, PMSAv7_INSTR_SIDE, r12 @ XIP_PHYS_ADDR, shared, enabled
 3293:      isb
 330#endif
 331        ret     lr
 332ENDPROC(__setup_pmsa_v7)
 333
 334ENTRY(__setup_pmsa_v8)
 335        mov     r0, #0
 336AR_CLASS(mcr    p15, 0, r0, c6, c2, 1)          @ PRSEL
 337M_CLASS(str     r0, [r12, #PMSAv8_RNR])
 338        isb
 339
 340#ifdef CONFIG_XIP_KERNEL
 341        ldr     r5, =CONFIG_XIP_PHYS_ADDR               @ ROM start
 342        ldr     r6, =(_exiprom)                         @ ROM end
 343        sub     r6, r6, #1
 344        bic     r6, r6, #(PMSAv8_MINALIGN - 1)
 345
 346        orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED)
 347        orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN)
 348
 349AR_CLASS(mcr    p15, 0, r5, c6, c8, 0)                  @ PRBAR0
 350AR_CLASS(mcr    p15, 0, r6, c6, c8, 1)                  @ PRLAR0
 351M_CLASS(str     r5, [r12, #PMSAv8_RBAR_A(0)])
 352M_CLASS(str     r6, [r12, #PMSAv8_RLAR_A(0)])
 353#endif
 354
 355        ldr     r5, =KERNEL_START
 356        ldr     r6, =KERNEL_END
 357        sub     r6, r6, #1
 358        bic     r6, r6, #(PMSAv8_MINALIGN - 1)
 359
 360        orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED)
 361        orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_NORMAL) | PMSAv8_LAR_EN)
 362
 363AR_CLASS(mcr    p15, 0, r5, c6, c8, 4)                  @ PRBAR1
 364AR_CLASS(mcr    p15, 0, r6, c6, c8, 5)                  @ PRLAR1
 365M_CLASS(str     r5, [r12, #PMSAv8_RBAR_A(1)])
 366M_CLASS(str     r6, [r12, #PMSAv8_RLAR_A(1)])
 367
 368        /* Setup Background: 0x0 - min(KERNEL_START, XIP_PHYS_ADDR) */
 369#ifdef CONFIG_XIP_KERNEL
 370        ldr     r6, =KERNEL_START
 371        ldr     r5, =CONFIG_XIP_PHYS_ADDR
 372        cmp     r6, r5
 373        movcs   r6, r5
 374#else
 375        ldr     r6, =KERNEL_START
 376#endif
 377        cmp     r6, #0
 378        beq     1f
 379
 380        mov     r5, #0
 381        sub     r6, r6, #1
 382        bic     r6, r6, #(PMSAv8_MINALIGN - 1)
 383
 384        orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN)
 385        orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN)
 386
 387AR_CLASS(mcr    p15, 0, r5, c6, c9, 0)                  @ PRBAR2
 388AR_CLASS(mcr    p15, 0, r6, c6, c9, 1)                  @ PRLAR2
 389M_CLASS(str     r5, [r12, #PMSAv8_RBAR_A(2)])
 390M_CLASS(str     r6, [r12, #PMSAv8_RLAR_A(2)])
 391
 3921:
 393        /* Setup Background: max(KERNEL_END, _exiprom) - 0xffffffff */
 394#ifdef CONFIG_XIP_KERNEL
 395        ldr     r5, =KERNEL_END
 396        ldr     r6, =(_exiprom)
 397        cmp     r5, r6
 398        movcc   r5, r6
 399#else
 400        ldr     r5, =KERNEL_END
 401#endif
 402        mov     r6, #0xffffffff
 403        bic     r6, r6, #(PMSAv8_MINALIGN - 1)
 404
 405        orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN)
 406        orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN)
 407
 408AR_CLASS(mcr    p15, 0, r5, c6, c9, 4)                  @ PRBAR3
 409AR_CLASS(mcr    p15, 0, r6, c6, c9, 5)                  @ PRLAR3
 410M_CLASS(str     r5, [r12, #PMSAv8_RBAR_A(3)])
 411M_CLASS(str     r6, [r12, #PMSAv8_RLAR_A(3)])
 412
 413#ifdef CONFIG_XIP_KERNEL
 414        /* Setup Background: min(_exiprom, KERNEL_END) - max(KERNEL_START, XIP_PHYS_ADDR) */
 415        ldr     r5, =(_exiprom)
 416        ldr     r6, =KERNEL_END
 417        cmp     r5, r6
 418        movcs   r5, r6
 419
 420        ldr     r6, =KERNEL_START
 421        ldr     r0, =CONFIG_XIP_PHYS_ADDR
 422        cmp     r6, r0
 423        movcc   r6, r0
 424
 425        sub     r6, r6, #1
 426        bic     r6, r6, #(PMSAv8_MINALIGN - 1)
 427
 428        orr     r5, r5, #(PMSAv8_AP_PL1RW_PL0NA | PMSAv8_RGN_SHARED | PMSAv8_BAR_XN)
 429        orr     r6, r6, #(PMSAv8_LAR_IDX(PMSAv8_RGN_DEVICE_nGnRnE) | PMSAv8_LAR_EN)
 430
 431#ifdef CONFIG_CPU_V7M
 432        /* There is no alias for n == 4 */
 433        mov     r0, #4
 434        str     r0, [r12, #PMSAv8_RNR]                  @ PRSEL
 435        isb
 436
 437        str     r5, [r12, #PMSAv8_RBAR_A(0)]
 438        str     r6, [r12, #PMSAv8_RLAR_A(0)]
 439#else
 440        mcr     p15, 0, r5, c6, c10, 0                  @ PRBAR4
 441        mcr     p15, 0, r6, c6, c10, 1                  @ PRLAR4
 442#endif
 443#endif
 444        ret     lr
 445ENDPROC(__setup_pmsa_v8)
 446
 447#ifdef CONFIG_SMP
 448/*
 449 * r6: pointer at mpu_rgn_info
 450 */
 451
 452        .text
 453ENTRY(__secondary_setup_mpu)
 454        /* Use MPU region info supplied by __cpu_up */
 455        ldr     r6, [r7]                        @ get secondary_data.mpu_rgn_info
 456
 457        /* Probe for v7 PMSA compliance */
 458        mrc     p15, 0, r0, c0, c1, 4           @ Read ID_MMFR0
 459        and     r0, r0, #(MMFR0_PMSA)           @ PMSA field
 460        teq     r0, #(MMFR0_PMSAv7)             @ PMSA v7
 461        beq     __secondary_setup_pmsa_v7
 462        teq     r0, #(MMFR0_PMSAv8)             @ PMSA v8
 463        beq     __secondary_setup_pmsa_v8
 464        b       __error_p
 465ENDPROC(__secondary_setup_mpu)
 466
 467/*
 468 * r6: pointer at mpu_rgn_info
 469 */
 470ENTRY(__secondary_setup_pmsa_v7)
 471        /* Determine whether the D/I-side memory map is unified. We set the
 472         * flags here and continue to use them for the rest of this function */
 473        mrc     p15, 0, r0, c0, c0, 4           @ MPUIR
 474        ands    r5, r0, #MPUIR_DREGION_SZMASK   @ 0 size d region => No MPU
 475        beq     __error_p
 476
 477        ldr     r4, [r6, #MPU_RNG_INFO_USED]
 478        mov     r5, #MPU_RNG_SIZE
 479        add     r3, r6, #MPU_RNG_INFO_RNGS
 480        mla     r3, r4, r5, r3
 481
 4821:
 483        tst     r0, #MPUIR_nU                   @ MPUIR_nU = 0 for unified
 484        sub     r3, r3, #MPU_RNG_SIZE
 485        sub     r4, r4, #1
 486
 487        set_region_nr r0, r4
 488        isb
 489
 490        ldr     r0, [r3, #MPU_RGN_DRBAR]
 491        ldr     r6, [r3, #MPU_RGN_DRSR]
 492        ldr     r5, [r3, #MPU_RGN_DRACR]
 493
 494        setup_region r0, r5, r6, PMSAv7_DATA_SIDE
 495        beq     2f
 496        setup_region r0, r5, r6, PMSAv7_INSTR_SIDE
 4972:      isb
 498
 499        mrc     p15, 0, r0, c0, c0, 4           @ Reevaluate the MPUIR
 500        cmp     r4, #0
 501        bgt     1b
 502
 503        ret     lr
 504ENDPROC(__secondary_setup_pmsa_v7)
 505
 506ENTRY(__secondary_setup_pmsa_v8)
 507        ldr     r4, [r6, #MPU_RNG_INFO_USED]
 508#ifndef CONFIG_XIP_KERNEL
 509        add     r4, r4, #1
 510#endif
 511        mov     r5, #MPU_RNG_SIZE
 512        add     r3, r6, #MPU_RNG_INFO_RNGS
 513        mla     r3, r4, r5, r3
 514
 5151:
 516        sub     r3, r3, #MPU_RNG_SIZE
 517        sub     r4, r4, #1
 518
 519        mcr     p15, 0, r4, c6, c2, 1           @ PRSEL
 520        isb
 521
 522        ldr     r5, [r3, #MPU_RGN_PRBAR]
 523        ldr     r6, [r3, #MPU_RGN_PRLAR]
 524
 525        mcr     p15, 0, r5, c6, c3, 0           @ PRBAR
 526        mcr     p15, 0, r6, c6, c3, 1           @ PRLAR
 527
 528        cmp     r4, #0
 529        bgt     1b
 530
 531        ret     lr
 532ENDPROC(__secondary_setup_pmsa_v8)
 533#endif /* CONFIG_SMP */
 534#endif /* CONFIG_ARM_MPU */
 535#include "head-common.S"
 536