Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * arch/arm/mm/proc-v7-3level.S
0004  *
0005  * Copyright (C) 2001 Deep Blue Solutions Ltd.
0006  * Copyright (C) 2011 ARM Ltd.
0007  * Author: Catalin Marinas <catalin.marinas@arm.com>
0008  *   based on arch/arm/mm/proc-v7-2level.S
0009  */
0010 #include <asm/assembler.h>
0011 
0012 #define TTB_IRGN_NC (0 << 8)
0013 #define TTB_IRGN_WBWA   (1 << 8)
0014 #define TTB_IRGN_WT (2 << 8)
0015 #define TTB_IRGN_WB (3 << 8)
0016 #define TTB_RGN_NC  (0 << 10)
0017 #define TTB_RGN_OC_WBWA (1 << 10)
0018 #define TTB_RGN_OC_WT   (2 << 10)
0019 #define TTB_RGN_OC_WB   (3 << 10)
0020 #define TTB_S       (3 << 12)
0021 #define TTB_EAE     (1 << 31)
0022 
0023 /* PTWs cacheable, inner WB not shareable, outer WB not shareable */
0024 #define TTB_FLAGS_UP    (TTB_IRGN_WB|TTB_RGN_OC_WB)
0025 #define PMD_FLAGS_UP    (PMD_SECT_WB)
0026 
0027 /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
0028 #define TTB_FLAGS_SMP   (TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA)
0029 #define PMD_FLAGS_SMP   (PMD_SECT_WBWA|PMD_SECT_S)
0030 
0031 #ifndef __ARMEB__
0032 #  define rpgdl r0
0033 #  define rpgdh r1
0034 #else
0035 #  define rpgdl r1
0036 #  define rpgdh r0
0037 #endif
0038 
0039 /*
0040  * cpu_v7_switch_mm(pgd_phys, tsk)
0041  *
0042  * Set the translation table base pointer to be pgd_phys (physical address of
0043  * the new TTB).
0044  */
0045 ENTRY(cpu_v7_switch_mm)
0046 #ifdef CONFIG_MMU
0047     mmid    r2, r2
0048     asid    r2, r2
0049     orr rpgdh, rpgdh, r2, lsl #(48 - 32)    @ upper 32-bits of pgd
0050     mcrr    p15, 0, rpgdl, rpgdh, c2        @ set TTB 0
0051     isb
0052 #endif
0053     ret lr
0054 ENDPROC(cpu_v7_switch_mm)
0055 
0056 #ifdef __ARMEB__
0057 #define rl r3
0058 #define rh r2
0059 #else
0060 #define rl r2
0061 #define rh r3
0062 #endif
0063 
0064 /*
0065  * cpu_v7_set_pte_ext(ptep, pte)
0066  *
0067  * Set a level 2 translation table entry.
0068  * - ptep - pointer to level 3 translation table entry
0069  * - pte - PTE value to store (64-bit in r2 and r3)
0070  */
0071 ENTRY(cpu_v7_set_pte_ext)
0072 #ifdef CONFIG_MMU
0073     tst rl, #L_PTE_VALID
0074     beq 1f
0075     tst rh, #1 << (57 - 32)     @ L_PTE_NONE
0076     bicne   rl, #L_PTE_VALID
0077     bne 1f
0078 
0079     eor ip, rh, #1 << (55 - 32) @ toggle L_PTE_DIRTY in temp reg to
0080                     @ test for !L_PTE_DIRTY || L_PTE_RDONLY
0081     tst ip, #1 << (55 - 32) | 1 << (58 - 32)
0082     orrne   rl, #PTE_AP2
0083     biceq   rl, #PTE_AP2
0084 
0085 1:  strd    r2, r3, [r0]
0086     ALT_SMP(W(nop))
0087     ALT_UP (mcr p15, 0, r0, c7, c10, 1)     @ flush_pte
0088 #endif
0089     ret lr
0090 ENDPROC(cpu_v7_set_pte_ext)
0091 
0092     /*
0093      * Memory region attributes for LPAE (defined in pgtable-3level.h):
0094      *
0095      *   n = AttrIndx[2:0]
0096      *
0097      *          n   MAIR
0098      *   UNCACHED       000 00000000
0099      *   BUFFERABLE     001 01000100
0100      *   DEV_WC     001 01000100
0101      *   WRITETHROUGH   010 10101010
0102      *   WRITEBACK      011 11101110
0103      *   DEV_CACHED     011 11101110
0104      *   DEV_SHARED     100 00000100
0105      *   DEV_NONSHARED  100 00000100
0106      *   unused     101
0107      *   unused     110
0108      *   WRITEALLOC     111 11111111
0109      */
0110 .equ    PRRR,   0xeeaa4400          @ MAIR0
0111 .equ    NMRR,   0xff000004          @ MAIR1
0112 
0113     /*
0114      * Macro for setting up the TTBRx and TTBCR registers.
0115      * - \ttbr1 updated.
0116      */
0117     .macro  v7_ttb_setup, zero, ttbr0l, ttbr0h, ttbr1, tmp
0118     ldr \tmp, =swapper_pg_dir       @ swapper_pg_dir virtual address
0119     cmp \ttbr1, \tmp, lsr #12       @ PHYS_OFFSET > PAGE_OFFSET?
0120     mov \tmp, #TTB_EAE          @ for TTB control egister
0121     ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP)
0122     ALT_UP(orr  \tmp, \tmp, #TTB_FLAGS_UP)
0123     ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16)
0124     ALT_UP(orr  \tmp, \tmp, #TTB_FLAGS_UP << 16)
0125     /*
0126      * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above),
0127      * otherwise booting secondary CPUs would end up using TTBR1 for the
0128      * identity mapping set up in TTBR0.
0129      */
0130     orrls   \tmp, \tmp, #TTBR1_SIZE             @ TTBCR.T1SZ
0131     mcr p15, 0, \tmp, c2, c0, 2             @ TTBCR
0132     mov \tmp, \ttbr1, lsr #20
0133     mov \ttbr1, \ttbr1, lsl #12
0134     addls   \ttbr1, \ttbr1, #TTBR1_OFFSET
0135     mcrr    p15, 1, \ttbr1, \tmp, c2            @ load TTBR1
0136     .endm
0137 
0138     /*
0139      *   AT
0140      *  TFR   EV X F   IHD LR    S
0141      * .EEE ..EE PUI. .TAT 4RVI ZWRS BLDP WCAM
0142      * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
0143      *   11    0 110    0  0011 1100 .111 1101 < we want
0144      */
0145     .align  2
0146     .type   v7_crval, #object
0147 v7_crval:
0148     crval   clear=0x0122c302, mmuset=0x30c03c7d, ucset=0x00c01c7c