blob: b24b620c81db7991f74092a4ef4e3a695e731ca2 [file] [log] [blame]
Dimitris Papastamos446f7f12017-11-30 14:53:53 +00001/*
Dimitris Papastamos28803632018-01-08 13:57:39 +00002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Dimitris Papastamos446f7f12017-11-30 14:53:53 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
Dimitris Papastamos28803632018-01-08 13:57:39 +00008#include <arm_arch_svc.h>
Dimitris Papastamos446f7f12017-11-30 14:53:53 +00009#include <asm_macros.S>
10#include <context.h>
11
12 .globl workaround_mmu_runtime_exceptions
13
Dimitris Papastamos28803632018-01-08 13:57:39 +000014#define ESR_EL3_A64_SMC0 0x5e000000
15
Dimitris Papastamos446f7f12017-11-30 14:53:53 +000016vector_base workaround_mmu_runtime_exceptions
17
Dimitris Papastamos28803632018-01-08 13:57:39 +000018 .macro apply_workaround _is_sync_exception
Dimitris Papastamos446f7f12017-11-30 14:53:53 +000019 stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
Dimitris Papastamos28803632018-01-08 13:57:39 +000020 mrs x1, sctlr_el3
Dimitris Papastamos446f7f12017-11-30 14:53:53 +000021 /* Disable MMU */
Dimitris Papastamos28803632018-01-08 13:57:39 +000022 bic x1, x1, #SCTLR_M_BIT
Dimitris Papastamos446f7f12017-11-30 14:53:53 +000023 msr sctlr_el3, x1
24 isb
Dimitris Papastamos28803632018-01-08 13:57:39 +000025 /* Enable MMU */
26 orr x1, x1, #SCTLR_M_BIT
27 msr sctlr_el3, x1
28 /*
29 * Defer ISB to avoid synchronizing twice in case we hit
30 * the workaround SMC call which will implicitly synchronize
31 * because of the ERET instruction.
32 */
33
34 /*
35 * Ensure SMC is coming from A64 state on #0
36 * with W0 = SMCCC_ARCH_WORKAROUND_1
37 *
38 * This sequence evaluates as:
39 * (W0==SMCCC_ARCH_WORKAROUND_1) ? (ESR_EL3==SMC#0) : (NE)
40 * allowing use of a single branch operation
41 */
42 .if \_is_sync_exception
43 orr w1, wzr, #SMCCC_ARCH_WORKAROUND_1
44 cmp w0, w1
45 mrs x0, esr_el3
46 mov_imm w1, ESR_EL3_A64_SMC0
47 ccmp w0, w1, #0, eq
48 /* Static predictor will predict a fall through */
49 bne 1f
50 eret
511:
52 .endif
53
54 /*
55 * Synchronize now to enable the MMU. This is required
56 * to ensure the load pair below reads the data stored earlier.
57 */
Dimitris Papastamos446f7f12017-11-30 14:53:53 +000058 isb
59 ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
60 .endm
61
62 /* ---------------------------------------------------------------------
63 * Current EL with SP_EL0 : 0x0 - 0x200
64 * ---------------------------------------------------------------------
65 */
66vector_entry workaround_mmu_sync_exception_sp_el0
67 b sync_exception_sp_el0
68 check_vector_size workaround_mmu_sync_exception_sp_el0
69
70vector_entry workaround_mmu_irq_sp_el0
71 b irq_sp_el0
72 check_vector_size workaround_mmu_irq_sp_el0
73
74vector_entry workaround_mmu_fiq_sp_el0
75 b fiq_sp_el0
76 check_vector_size workaround_mmu_fiq_sp_el0
77
78vector_entry workaround_mmu_serror_sp_el0
79 b serror_sp_el0
80 check_vector_size workaround_mmu_serror_sp_el0
81
82 /* ---------------------------------------------------------------------
83 * Current EL with SP_ELx: 0x200 - 0x400
84 * ---------------------------------------------------------------------
85 */
86vector_entry workaround_mmu_sync_exception_sp_elx
87 b sync_exception_sp_elx
88 check_vector_size workaround_mmu_sync_exception_sp_elx
89
90vector_entry workaround_mmu_irq_sp_elx
91 b irq_sp_elx
92 check_vector_size workaround_mmu_irq_sp_elx
93
94vector_entry workaround_mmu_fiq_sp_elx
95 b fiq_sp_elx
96 check_vector_size workaround_mmu_fiq_sp_elx
97
98vector_entry workaround_mmu_serror_sp_elx
99 b serror_sp_elx
100 check_vector_size workaround_mmu_serror_sp_elx
101
102 /* ---------------------------------------------------------------------
103 * Lower EL using AArch64 : 0x400 - 0x600
104 * ---------------------------------------------------------------------
105 */
106vector_entry workaround_mmu_sync_exception_aarch64
Dimitris Papastamos28803632018-01-08 13:57:39 +0000107 apply_workaround _is_sync_exception=1
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000108 b sync_exception_aarch64
109 check_vector_size workaround_mmu_sync_exception_aarch64
110
111vector_entry workaround_mmu_irq_aarch64
Dimitris Papastamos28803632018-01-08 13:57:39 +0000112 apply_workaround _is_sync_exception=0
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000113 b irq_aarch64
114 check_vector_size workaround_mmu_irq_aarch64
115
116vector_entry workaround_mmu_fiq_aarch64
Dimitris Papastamos28803632018-01-08 13:57:39 +0000117 apply_workaround _is_sync_exception=0
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000118 b fiq_aarch64
119 check_vector_size workaround_mmu_fiq_aarch64
120
121vector_entry workaround_mmu_serror_aarch64
Dimitris Papastamos28803632018-01-08 13:57:39 +0000122 apply_workaround _is_sync_exception=0
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000123 b serror_aarch64
124 check_vector_size workaround_mmu_serror_aarch64
125
126 /* ---------------------------------------------------------------------
127 * Lower EL using AArch32 : 0x600 - 0x800
128 * ---------------------------------------------------------------------
129 */
130vector_entry workaround_mmu_sync_exception_aarch32
Dimitris Papastamos28803632018-01-08 13:57:39 +0000131 apply_workaround _is_sync_exception=1
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000132 b sync_exception_aarch32
133 check_vector_size workaround_mmu_sync_exception_aarch32
134
135vector_entry workaround_mmu_irq_aarch32
Dimitris Papastamos28803632018-01-08 13:57:39 +0000136 apply_workaround _is_sync_exception=0
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000137 b irq_aarch32
138 check_vector_size workaround_mmu_irq_aarch32
139
140vector_entry workaround_mmu_fiq_aarch32
Dimitris Papastamos28803632018-01-08 13:57:39 +0000141 apply_workaround _is_sync_exception=0
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000142 b fiq_aarch32
143 check_vector_size workaround_mmu_fiq_aarch32
144
145vector_entry workaround_mmu_serror_aarch32
Dimitris Papastamos28803632018-01-08 13:57:39 +0000146 apply_workaround _is_sync_exception=0
Dimitris Papastamos446f7f12017-11-30 14:53:53 +0000147 b serror_aarch32
148 check_vector_size workaround_mmu_serror_aarch32