linux/arch/arm/mm/proc-v7-3level.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * arch/arm/mm/proc-v7-3level.S
   4 *
   5 * Copyright (C) 2001 Deep Blue Solutions Ltd.
   6 * Copyright (C) 2011 ARM Ltd.
   7 * Author: Catalin Marinas <catalin.marinas@arm.com>
   8 *   based on arch/arm/mm/proc-v7-2level.S
   9 */
  10#include <asm/assembler.h>
  11
  12#define TTB_IRGN_NC     (0 << 8)
  13#define TTB_IRGN_WBWA   (1 << 8)
  14#define TTB_IRGN_WT     (2 << 8)
  15#define TTB_IRGN_WB     (3 << 8)
  16#define TTB_RGN_NC      (0 << 10)
  17#define TTB_RGN_OC_WBWA (1 << 10)
  18#define TTB_RGN_OC_WT   (2 << 10)
  19#define TTB_RGN_OC_WB   (3 << 10)
  20#define TTB_S           (3 << 12)
  21#define TTB_EAE         (1 << 31)
  22
  23/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
  24#define TTB_FLAGS_UP    (TTB_IRGN_WB|TTB_RGN_OC_WB)
  25#define PMD_FLAGS_UP    (PMD_SECT_WB)
  26
  27/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
  28#define TTB_FLAGS_SMP   (TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA)
  29#define PMD_FLAGS_SMP   (PMD_SECT_WBWA|PMD_SECT_S)
  30
  31#ifndef __ARMEB__
  32#  define rpgdl r0
  33#  define rpgdh r1
  34#else
  35#  define rpgdl r1
  36#  define rpgdh r0
  37#endif
  38
  39/*
  40 * cpu_v7_switch_mm(pgd_phys, tsk)
  41 *
  42 * Set the translation table base pointer to be pgd_phys (physical address of
  43 * the new TTB).
  44 */
  45ENTRY(cpu_v7_switch_mm)
  46#ifdef CONFIG_MMU
  47        mmid    r2, r2
  48        asid    r2, r2
  49        orr     rpgdh, rpgdh, r2, lsl #(48 - 32)        @ upper 32-bits of pgd
  50        mcrr    p15, 0, rpgdl, rpgdh, c2                @ set TTB 0
  51        isb
  52#endif
  53        ret     lr
  54ENDPROC(cpu_v7_switch_mm)
  55
  56#ifdef __ARMEB__
  57#define rl r3
  58#define rh r2
  59#else
  60#define rl r2
  61#define rh r3
  62#endif
  63
  64/*
  65 * cpu_v7_set_pte_ext(ptep, pte)
  66 *
  67 * Set a level 2 translation table entry.
  68 * - ptep - pointer to level 3 translation table entry
  69 * - pte - PTE value to store (64-bit in r2 and r3)
  70 */
  71ENTRY(cpu_v7_set_pte_ext)
  72#ifdef CONFIG_MMU
  73        tst     rl, #L_PTE_VALID
  74        beq     1f
  75        tst     rh, #1 << (57 - 32)             @ L_PTE_NONE
  76        bicne   rl, #L_PTE_VALID
  77        bne     1f
  78
  79        eor     ip, rh, #1 << (55 - 32) @ toggle L_PTE_DIRTY in temp reg to
  80                                        @ test for !L_PTE_DIRTY || L_PTE_RDONLY
  81        tst     ip, #1 << (55 - 32) | 1 << (58 - 32)
  82        orrne   rl, #PTE_AP2
  83        biceq   rl, #PTE_AP2
  84
  851:      strd    r2, r3, [r0]
  86        ALT_SMP(W(nop))
  87        ALT_UP (mcr     p15, 0, r0, c7, c10, 1)         @ flush_pte
  88#endif
  89        ret     lr
  90ENDPROC(cpu_v7_set_pte_ext)
  91
  92        /*
  93         * Memory region attributes for LPAE (defined in pgtable-3level.h):
  94         *
  95         *   n = AttrIndx[2:0]
  96         *
  97         *                      n       MAIR
  98         *   UNCACHED           000     00000000
  99         *   BUFFERABLE         001     01000100
 100         *   DEV_WC             001     01000100
 101         *   WRITETHROUGH       010     10101010
 102         *   WRITEBACK          011     11101110
 103         *   DEV_CACHED         011     11101110
 104         *   DEV_SHARED         100     00000100
 105         *   DEV_NONSHARED      100     00000100
 106         *   unused             101
 107         *   unused             110
 108         *   WRITEALLOC         111     11111111
 109         */
 110.equ    PRRR,   0xeeaa4400                      @ MAIR0
 111.equ    NMRR,   0xff000004                      @ MAIR1
 112
 113        /*
 114         * Macro for setting up the TTBRx and TTBCR registers.
 115         * - \ttbr1 updated.
 116         */
 117        .macro  v7_ttb_setup, zero, ttbr0l, ttbr0h, ttbr1, tmp
 118        ldr     \tmp, =swapper_pg_dir           @ swapper_pg_dir virtual address
 119        cmp     \ttbr1, \tmp, lsr #12           @ PHYS_OFFSET > PAGE_OFFSET?
 120        mov     \tmp, #TTB_EAE                  @ for TTB control egister
 121        ALT_SMP(orr     \tmp, \tmp, #TTB_FLAGS_SMP)
 122        ALT_UP(orr      \tmp, \tmp, #TTB_FLAGS_UP)
 123        ALT_SMP(orr     \tmp, \tmp, #TTB_FLAGS_SMP << 16)
 124        ALT_UP(orr      \tmp, \tmp, #TTB_FLAGS_UP << 16)
 125        /*
 126         * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above),
 127         * otherwise booting secondary CPUs would end up using TTBR1 for the
 128         * identity mapping set up in TTBR0.
 129         */
 130        orrls   \tmp, \tmp, #TTBR1_SIZE                         @ TTBCR.T1SZ
 131        mcr     p15, 0, \tmp, c2, c0, 2                         @ TTBCR
 132        mov     \tmp, \ttbr1, lsr #20
 133        mov     \ttbr1, \ttbr1, lsl #12
 134        addls   \ttbr1, \ttbr1, #TTBR1_OFFSET
 135        mcrr    p15, 1, \ttbr1, \tmp, c2                        @ load TTBR1
 136        .endm
 137
 138        /*
 139         *   AT
 140         *  TFR   EV X F   IHD LR    S
 141         * .EEE ..EE PUI. .TAT 4RVI ZWRS BLDP WCAM
 142         * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
 143         *   11    0 110    0  0011 1100 .111 1101 < we want
 144         */
 145        .align  2
 146        .type   v7_crval, #object
 147v7_crval:
 148        crval   clear=0x0122c302, mmuset=0x30c03c7d, ucset=0x00c01c7c
 149