root / target-xtensa / helper.c @ a8170e5e
History | View | Annotate | Download (19.1 kB)
1 | 2328826b | Max Filippov | /*
|
---|---|---|---|
2 | 2328826b | Max Filippov | * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
3 | 2328826b | Max Filippov | * All rights reserved.
|
4 | 2328826b | Max Filippov | *
|
5 | 2328826b | Max Filippov | * Redistribution and use in source and binary forms, with or without
|
6 | 2328826b | Max Filippov | * modification, are permitted provided that the following conditions are met:
|
7 | 2328826b | Max Filippov | * * Redistributions of source code must retain the above copyright
|
8 | 2328826b | Max Filippov | * notice, this list of conditions and the following disclaimer.
|
9 | 2328826b | Max Filippov | * * Redistributions in binary form must reproduce the above copyright
|
10 | 2328826b | Max Filippov | * notice, this list of conditions and the following disclaimer in the
|
11 | 2328826b | Max Filippov | * documentation and/or other materials provided with the distribution.
|
12 | 2328826b | Max Filippov | * * Neither the name of the Open Source and Linux Lab nor the
|
13 | 2328826b | Max Filippov | * names of its contributors may be used to endorse or promote products
|
14 | 2328826b | Max Filippov | * derived from this software without specific prior written permission.
|
15 | 2328826b | Max Filippov | *
|
16 | 2328826b | Max Filippov | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17 | 2328826b | Max Filippov | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18 | 2328826b | Max Filippov | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
19 | 2328826b | Max Filippov | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
20 | 2328826b | Max Filippov | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
21 | 2328826b | Max Filippov | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
22 | 2328826b | Max Filippov | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
23 | 2328826b | Max Filippov | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24 | 2328826b | Max Filippov | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
25 | 2328826b | Max Filippov | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26 | 2328826b | Max Filippov | */
|
27 | 2328826b | Max Filippov | |
28 | 2328826b | Max Filippov | #include "cpu.h" |
29 | 2328826b | Max Filippov | #include "exec-all.h" |
30 | 2328826b | Max Filippov | #include "gdbstub.h" |
31 | 2328826b | Max Filippov | #include "host-utils.h" |
32 | 2328826b | Max Filippov | #if !defined(CONFIG_USER_ONLY)
|
33 | 2328826b | Max Filippov | #include "hw/loader.h" |
34 | 2328826b | Max Filippov | #endif
|
35 | 2328826b | Max Filippov | |
36 | ac8b7db4 | Max Filippov | static struct XtensaConfigList *xtensa_cores; |
37 | ac8b7db4 | Max Filippov | |
38 | ac8b7db4 | Max Filippov | void xtensa_register_core(XtensaConfigList *node)
|
39 | ac8b7db4 | Max Filippov | { |
40 | ac8b7db4 | Max Filippov | node->next = xtensa_cores; |
41 | ac8b7db4 | Max Filippov | xtensa_cores = node; |
42 | ac8b7db4 | Max Filippov | } |
43 | dedc5eae | Max Filippov | |
44 | 97129ac8 | Andreas Färber | static uint32_t check_hw_breakpoints(CPUXtensaState *env)
|
45 | f14c4b5f | Max Filippov | { |
46 | f14c4b5f | Max Filippov | unsigned i;
|
47 | f14c4b5f | Max Filippov | |
48 | f14c4b5f | Max Filippov | for (i = 0; i < env->config->ndbreak; ++i) { |
49 | f14c4b5f | Max Filippov | if (env->cpu_watchpoint[i] &&
|
50 | f14c4b5f | Max Filippov | env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) { |
51 | f14c4b5f | Max Filippov | return DEBUGCAUSE_DB | (i << DEBUGCAUSE_DBNUM_SHIFT);
|
52 | f14c4b5f | Max Filippov | } |
53 | f14c4b5f | Max Filippov | } |
54 | f14c4b5f | Max Filippov | return 0; |
55 | f14c4b5f | Max Filippov | } |
56 | f14c4b5f | Max Filippov | |
57 | 97129ac8 | Andreas Färber | static void breakpoint_handler(CPUXtensaState *env) |
58 | f14c4b5f | Max Filippov | { |
59 | f14c4b5f | Max Filippov | if (env->watchpoint_hit) {
|
60 | f14c4b5f | Max Filippov | if (env->watchpoint_hit->flags & BP_CPU) {
|
61 | f14c4b5f | Max Filippov | uint32_t cause; |
62 | f14c4b5f | Max Filippov | |
63 | f14c4b5f | Max Filippov | env->watchpoint_hit = NULL;
|
64 | f14c4b5f | Max Filippov | cause = check_hw_breakpoints(env); |
65 | f14c4b5f | Max Filippov | if (cause) {
|
66 | f14c4b5f | Max Filippov | debug_exception_env(env, cause); |
67 | f14c4b5f | Max Filippov | } |
68 | f14c4b5f | Max Filippov | cpu_resume_from_signal(env, NULL);
|
69 | f14c4b5f | Max Filippov | } |
70 | f14c4b5f | Max Filippov | } |
71 | f14c4b5f | Max Filippov | } |
72 | f14c4b5f | Max Filippov | |
73 | 15be3171 | Andreas Färber | XtensaCPU *cpu_xtensa_init(const char *cpu_model) |
74 | 2328826b | Max Filippov | { |
75 | 2328826b | Max Filippov | static int tcg_inited; |
76 | f14c4b5f | Max Filippov | static int debug_handler_inited; |
77 | a4633e16 | Andreas Färber | XtensaCPU *cpu; |
78 | 2328826b | Max Filippov | CPUXtensaState *env; |
79 | dedc5eae | Max Filippov | const XtensaConfig *config = NULL; |
80 | ac8b7db4 | Max Filippov | XtensaConfigList *core = xtensa_cores; |
81 | dedc5eae | Max Filippov | |
82 | ac8b7db4 | Max Filippov | for (; core; core = core->next)
|
83 | ac8b7db4 | Max Filippov | if (strcmp(core->config->name, cpu_model) == 0) { |
84 | ac8b7db4 | Max Filippov | config = core->config; |
85 | dedc5eae | Max Filippov | break;
|
86 | dedc5eae | Max Filippov | } |
87 | dedc5eae | Max Filippov | |
88 | dedc5eae | Max Filippov | if (config == NULL) { |
89 | dedc5eae | Max Filippov | return NULL; |
90 | dedc5eae | Max Filippov | } |
91 | 2328826b | Max Filippov | |
92 | a4633e16 | Andreas Färber | cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU)); |
93 | a4633e16 | Andreas Färber | env = &cpu->env; |
94 | dedc5eae | Max Filippov | env->config = config; |
95 | 2328826b | Max Filippov | |
96 | 2328826b | Max Filippov | if (!tcg_inited) {
|
97 | 2328826b | Max Filippov | tcg_inited = 1;
|
98 | 2328826b | Max Filippov | xtensa_translate_init(); |
99 | 2328826b | Max Filippov | } |
100 | 2328826b | Max Filippov | |
101 | f14c4b5f | Max Filippov | if (!debug_handler_inited && tcg_enabled()) {
|
102 | f14c4b5f | Max Filippov | debug_handler_inited = 1;
|
103 | eeec69dc | Igor Mammedov | cpu_set_debug_excp_handler(breakpoint_handler); |
104 | f14c4b5f | Max Filippov | } |
105 | f14c4b5f | Max Filippov | |
106 | b994e91b | Max Filippov | xtensa_irq_init(env); |
107 | 2328826b | Max Filippov | qemu_init_vcpu(env); |
108 | 15be3171 | Andreas Färber | return cpu;
|
109 | 2328826b | Max Filippov | } |
110 | 2328826b | Max Filippov | |
111 | 2328826b | Max Filippov | |
112 | 2328826b | Max Filippov | void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
113 | 2328826b | Max Filippov | { |
114 | ac8b7db4 | Max Filippov | XtensaConfigList *core = xtensa_cores; |
115 | dedc5eae | Max Filippov | cpu_fprintf(f, "Available CPUs:\n");
|
116 | ac8b7db4 | Max Filippov | for (; core; core = core->next) {
|
117 | ac8b7db4 | Max Filippov | cpu_fprintf(f, " %s\n", core->config->name);
|
118 | dedc5eae | Max Filippov | } |
119 | 2328826b | Max Filippov | } |
120 | 2328826b | Max Filippov | |
121 | a8170e5e | Avi Kivity | hwaddr cpu_get_phys_page_debug(CPUXtensaState *env, target_ulong addr) |
122 | 2328826b | Max Filippov | { |
123 | b67ea0cd | Max Filippov | uint32_t paddr; |
124 | b67ea0cd | Max Filippov | uint32_t page_size; |
125 | b67ea0cd | Max Filippov | unsigned access;
|
126 | b67ea0cd | Max Filippov | |
127 | ae4e7982 | Max Filippov | if (xtensa_get_physical_addr(env, false, addr, 0, 0, |
128 | b67ea0cd | Max Filippov | &paddr, &page_size, &access) == 0) {
|
129 | b67ea0cd | Max Filippov | return paddr;
|
130 | b67ea0cd | Max Filippov | } |
131 | ae4e7982 | Max Filippov | if (xtensa_get_physical_addr(env, false, addr, 2, 0, |
132 | b67ea0cd | Max Filippov | &paddr, &page_size, &access) == 0) {
|
133 | b67ea0cd | Max Filippov | return paddr;
|
134 | b67ea0cd | Max Filippov | } |
135 | b67ea0cd | Max Filippov | return ~0; |
136 | 2328826b | Max Filippov | } |
137 | 2328826b | Max Filippov | |
138 | 97129ac8 | Andreas Färber | static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
|
139 | 97836cee | Max Filippov | { |
140 | 97836cee | Max Filippov | if (xtensa_option_enabled(env->config,
|
141 | 97836cee | Max Filippov | XTENSA_OPTION_RELOCATABLE_VECTOR)) { |
142 | 97836cee | Max Filippov | return vector - env->config->vecbase + env->sregs[VECBASE];
|
143 | 97836cee | Max Filippov | } else {
|
144 | 97836cee | Max Filippov | return vector;
|
145 | 97836cee | Max Filippov | } |
146 | 97836cee | Max Filippov | } |
147 | 97836cee | Max Filippov | |
148 | b994e91b | Max Filippov | /*!
|
149 | b994e91b | Max Filippov | * Handle penging IRQ.
|
150 | b994e91b | Max Filippov | * For the high priority interrupt jump to the corresponding interrupt vector.
|
151 | b994e91b | Max Filippov | * For the level-1 interrupt convert it to either user, kernel or double
|
152 | b994e91b | Max Filippov | * exception with the 'level-1 interrupt' exception cause.
|
153 | b994e91b | Max Filippov | */
|
154 | 97129ac8 | Andreas Färber | static void handle_interrupt(CPUXtensaState *env) |
155 | b994e91b | Max Filippov | { |
156 | b994e91b | Max Filippov | int level = env->pending_irq_level;
|
157 | b994e91b | Max Filippov | |
158 | b994e91b | Max Filippov | if (level > xtensa_get_cintlevel(env) &&
|
159 | b994e91b | Max Filippov | level <= env->config->nlevel && |
160 | b994e91b | Max Filippov | (env->config->level_mask[level] & |
161 | b994e91b | Max Filippov | env->sregs[INTSET] & |
162 | b994e91b | Max Filippov | env->sregs[INTENABLE])) { |
163 | b994e91b | Max Filippov | if (level > 1) { |
164 | b994e91b | Max Filippov | env->sregs[EPC1 + level - 1] = env->pc;
|
165 | b994e91b | Max Filippov | env->sregs[EPS2 + level - 2] = env->sregs[PS];
|
166 | b994e91b | Max Filippov | env->sregs[PS] = |
167 | b994e91b | Max Filippov | (env->sregs[PS] & ~PS_INTLEVEL) | level | PS_EXCM; |
168 | 97836cee | Max Filippov | env->pc = relocated_vector(env, |
169 | 97836cee | Max Filippov | env->config->interrupt_vector[level]); |
170 | b994e91b | Max Filippov | } else {
|
171 | b994e91b | Max Filippov | env->sregs[EXCCAUSE] = LEVEL1_INTERRUPT_CAUSE; |
172 | b994e91b | Max Filippov | |
173 | b994e91b | Max Filippov | if (env->sregs[PS] & PS_EXCM) {
|
174 | b994e91b | Max Filippov | if (env->config->ndepc) {
|
175 | b994e91b | Max Filippov | env->sregs[DEPC] = env->pc; |
176 | b994e91b | Max Filippov | } else {
|
177 | b994e91b | Max Filippov | env->sregs[EPC1] = env->pc; |
178 | b994e91b | Max Filippov | } |
179 | b994e91b | Max Filippov | env->exception_index = EXC_DOUBLE; |
180 | b994e91b | Max Filippov | } else {
|
181 | b994e91b | Max Filippov | env->sregs[EPC1] = env->pc; |
182 | b994e91b | Max Filippov | env->exception_index = |
183 | b994e91b | Max Filippov | (env->sregs[PS] & PS_UM) ? EXC_USER : EXC_KERNEL; |
184 | b994e91b | Max Filippov | } |
185 | b994e91b | Max Filippov | env->sregs[PS] |= PS_EXCM; |
186 | b994e91b | Max Filippov | } |
187 | b994e91b | Max Filippov | env->exception_taken = 1;
|
188 | b994e91b | Max Filippov | } |
189 | b994e91b | Max Filippov | } |
190 | b994e91b | Max Filippov | |
191 | 97129ac8 | Andreas Färber | void do_interrupt(CPUXtensaState *env)
|
192 | 2328826b | Max Filippov | { |
193 | b994e91b | Max Filippov | if (env->exception_index == EXC_IRQ) {
|
194 | b994e91b | Max Filippov | qemu_log_mask(CPU_LOG_INT, |
195 | b994e91b | Max Filippov | "%s(EXC_IRQ) level = %d, cintlevel = %d, "
|
196 | b994e91b | Max Filippov | "pc = %08x, a0 = %08x, ps = %08x, "
|
197 | b994e91b | Max Filippov | "intset = %08x, intenable = %08x, "
|
198 | b994e91b | Max Filippov | "ccount = %08x\n",
|
199 | b994e91b | Max Filippov | __func__, env->pending_irq_level, xtensa_get_cintlevel(env), |
200 | b994e91b | Max Filippov | env->pc, env->regs[0], env->sregs[PS],
|
201 | b994e91b | Max Filippov | env->sregs[INTSET], env->sregs[INTENABLE], |
202 | b994e91b | Max Filippov | env->sregs[CCOUNT]); |
203 | b994e91b | Max Filippov | handle_interrupt(env); |
204 | b994e91b | Max Filippov | } |
205 | b994e91b | Max Filippov | |
206 | 40643d7c | Max Filippov | switch (env->exception_index) {
|
207 | 40643d7c | Max Filippov | case EXC_WINDOW_OVERFLOW4:
|
208 | 40643d7c | Max Filippov | case EXC_WINDOW_UNDERFLOW4:
|
209 | 40643d7c | Max Filippov | case EXC_WINDOW_OVERFLOW8:
|
210 | 40643d7c | Max Filippov | case EXC_WINDOW_UNDERFLOW8:
|
211 | 40643d7c | Max Filippov | case EXC_WINDOW_OVERFLOW12:
|
212 | 40643d7c | Max Filippov | case EXC_WINDOW_UNDERFLOW12:
|
213 | 40643d7c | Max Filippov | case EXC_KERNEL:
|
214 | 40643d7c | Max Filippov | case EXC_USER:
|
215 | 40643d7c | Max Filippov | case EXC_DOUBLE:
|
216 | e61dc8f7 | Max Filippov | case EXC_DEBUG:
|
217 | b994e91b | Max Filippov | qemu_log_mask(CPU_LOG_INT, "%s(%d) "
|
218 | b994e91b | Max Filippov | "pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n",
|
219 | b994e91b | Max Filippov | __func__, env->exception_index, |
220 | b994e91b | Max Filippov | env->pc, env->regs[0], env->sregs[PS], env->sregs[CCOUNT]);
|
221 | 40643d7c | Max Filippov | if (env->config->exception_vector[env->exception_index]) {
|
222 | 97836cee | Max Filippov | env->pc = relocated_vector(env, |
223 | 97836cee | Max Filippov | env->config->exception_vector[env->exception_index]); |
224 | 40643d7c | Max Filippov | env->exception_taken = 1;
|
225 | 40643d7c | Max Filippov | } else {
|
226 | 40643d7c | Max Filippov | qemu_log("%s(pc = %08x) bad exception_index: %d\n",
|
227 | 40643d7c | Max Filippov | __func__, env->pc, env->exception_index); |
228 | 40643d7c | Max Filippov | } |
229 | 40643d7c | Max Filippov | break;
|
230 | 40643d7c | Max Filippov | |
231 | b994e91b | Max Filippov | case EXC_IRQ:
|
232 | b994e91b | Max Filippov | break;
|
233 | b994e91b | Max Filippov | |
234 | b994e91b | Max Filippov | default:
|
235 | b994e91b | Max Filippov | qemu_log("%s(pc = %08x) unknown exception_index: %d\n",
|
236 | b994e91b | Max Filippov | __func__, env->pc, env->exception_index); |
237 | b994e91b | Max Filippov | break;
|
238 | 40643d7c | Max Filippov | } |
239 | b994e91b | Max Filippov | check_interrupts(env); |
240 | 2328826b | Max Filippov | } |
241 | b67ea0cd | Max Filippov | |
242 | 97129ac8 | Andreas Färber | static void reset_tlb_mmu_all_ways(CPUXtensaState *env, |
243 | b67ea0cd | Max Filippov | const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
|
244 | b67ea0cd | Max Filippov | { |
245 | b67ea0cd | Max Filippov | unsigned wi, ei;
|
246 | b67ea0cd | Max Filippov | |
247 | b67ea0cd | Max Filippov | for (wi = 0; wi < tlb->nways; ++wi) { |
248 | b67ea0cd | Max Filippov | for (ei = 0; ei < tlb->way_size[wi]; ++ei) { |
249 | b67ea0cd | Max Filippov | entry[wi][ei].asid = 0;
|
250 | b67ea0cd | Max Filippov | entry[wi][ei].variable = true;
|
251 | b67ea0cd | Max Filippov | } |
252 | b67ea0cd | Max Filippov | } |
253 | b67ea0cd | Max Filippov | } |
254 | b67ea0cd | Max Filippov | |
255 | 97129ac8 | Andreas Färber | static void reset_tlb_mmu_ways56(CPUXtensaState *env, |
256 | b67ea0cd | Max Filippov | const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
|
257 | b67ea0cd | Max Filippov | { |
258 | b67ea0cd | Max Filippov | if (!tlb->varway56) {
|
259 | b67ea0cd | Max Filippov | static const xtensa_tlb_entry way5[] = { |
260 | b67ea0cd | Max Filippov | { |
261 | b67ea0cd | Max Filippov | .vaddr = 0xd0000000,
|
262 | b67ea0cd | Max Filippov | .paddr = 0,
|
263 | b67ea0cd | Max Filippov | .asid = 1,
|
264 | b67ea0cd | Max Filippov | .attr = 7,
|
265 | b67ea0cd | Max Filippov | .variable = false,
|
266 | b67ea0cd | Max Filippov | }, { |
267 | b67ea0cd | Max Filippov | .vaddr = 0xd8000000,
|
268 | b67ea0cd | Max Filippov | .paddr = 0,
|
269 | b67ea0cd | Max Filippov | .asid = 1,
|
270 | b67ea0cd | Max Filippov | .attr = 3,
|
271 | b67ea0cd | Max Filippov | .variable = false,
|
272 | b67ea0cd | Max Filippov | } |
273 | b67ea0cd | Max Filippov | }; |
274 | b67ea0cd | Max Filippov | static const xtensa_tlb_entry way6[] = { |
275 | b67ea0cd | Max Filippov | { |
276 | b67ea0cd | Max Filippov | .vaddr = 0xe0000000,
|
277 | b67ea0cd | Max Filippov | .paddr = 0xf0000000,
|
278 | b67ea0cd | Max Filippov | .asid = 1,
|
279 | b67ea0cd | Max Filippov | .attr = 7,
|
280 | b67ea0cd | Max Filippov | .variable = false,
|
281 | b67ea0cd | Max Filippov | }, { |
282 | b67ea0cd | Max Filippov | .vaddr = 0xf0000000,
|
283 | b67ea0cd | Max Filippov | .paddr = 0xf0000000,
|
284 | b67ea0cd | Max Filippov | .asid = 1,
|
285 | b67ea0cd | Max Filippov | .attr = 3,
|
286 | b67ea0cd | Max Filippov | .variable = false,
|
287 | b67ea0cd | Max Filippov | } |
288 | b67ea0cd | Max Filippov | }; |
289 | b67ea0cd | Max Filippov | memcpy(entry[5], way5, sizeof(way5)); |
290 | b67ea0cd | Max Filippov | memcpy(entry[6], way6, sizeof(way6)); |
291 | b67ea0cd | Max Filippov | } else {
|
292 | b67ea0cd | Max Filippov | uint32_t ei; |
293 | b67ea0cd | Max Filippov | for (ei = 0; ei < 8; ++ei) { |
294 | b67ea0cd | Max Filippov | entry[6][ei].vaddr = ei << 29; |
295 | b67ea0cd | Max Filippov | entry[6][ei].paddr = ei << 29; |
296 | b67ea0cd | Max Filippov | entry[6][ei].asid = 1; |
297 | 0fdd2e1d | Max Filippov | entry[6][ei].attr = 3; |
298 | b67ea0cd | Max Filippov | } |
299 | b67ea0cd | Max Filippov | } |
300 | b67ea0cd | Max Filippov | } |
301 | b67ea0cd | Max Filippov | |
302 | 97129ac8 | Andreas Färber | static void reset_tlb_region_way0(CPUXtensaState *env, |
303 | b67ea0cd | Max Filippov | xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE]) |
304 | b67ea0cd | Max Filippov | { |
305 | b67ea0cd | Max Filippov | unsigned ei;
|
306 | b67ea0cd | Max Filippov | |
307 | b67ea0cd | Max Filippov | for (ei = 0; ei < 8; ++ei) { |
308 | b67ea0cd | Max Filippov | entry[0][ei].vaddr = ei << 29; |
309 | b67ea0cd | Max Filippov | entry[0][ei].paddr = ei << 29; |
310 | b67ea0cd | Max Filippov | entry[0][ei].asid = 1; |
311 | b67ea0cd | Max Filippov | entry[0][ei].attr = 2; |
312 | b67ea0cd | Max Filippov | entry[0][ei].variable = true; |
313 | b67ea0cd | Max Filippov | } |
314 | b67ea0cd | Max Filippov | } |
315 | b67ea0cd | Max Filippov | |
316 | 5087a72c | Andreas Färber | void reset_mmu(CPUXtensaState *env)
|
317 | b67ea0cd | Max Filippov | { |
318 | b67ea0cd | Max Filippov | if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
319 | b67ea0cd | Max Filippov | env->sregs[RASID] = 0x04030201;
|
320 | b67ea0cd | Max Filippov | env->sregs[ITLBCFG] = 0;
|
321 | b67ea0cd | Max Filippov | env->sregs[DTLBCFG] = 0;
|
322 | b67ea0cd | Max Filippov | env->autorefill_idx = 0;
|
323 | b67ea0cd | Max Filippov | reset_tlb_mmu_all_ways(env, &env->config->itlb, env->itlb); |
324 | b67ea0cd | Max Filippov | reset_tlb_mmu_all_ways(env, &env->config->dtlb, env->dtlb); |
325 | b67ea0cd | Max Filippov | reset_tlb_mmu_ways56(env, &env->config->itlb, env->itlb); |
326 | b67ea0cd | Max Filippov | reset_tlb_mmu_ways56(env, &env->config->dtlb, env->dtlb); |
327 | b67ea0cd | Max Filippov | } else {
|
328 | b67ea0cd | Max Filippov | reset_tlb_region_way0(env, env->itlb); |
329 | b67ea0cd | Max Filippov | reset_tlb_region_way0(env, env->dtlb); |
330 | b67ea0cd | Max Filippov | } |
331 | b67ea0cd | Max Filippov | } |
332 | b67ea0cd | Max Filippov | |
333 | 97129ac8 | Andreas Färber | static unsigned get_ring(const CPUXtensaState *env, uint8_t asid) |
334 | b67ea0cd | Max Filippov | { |
335 | b67ea0cd | Max Filippov | unsigned i;
|
336 | b67ea0cd | Max Filippov | for (i = 0; i < 4; ++i) { |
337 | b67ea0cd | Max Filippov | if (((env->sregs[RASID] >> i * 8) & 0xff) == asid) { |
338 | b67ea0cd | Max Filippov | return i;
|
339 | b67ea0cd | Max Filippov | } |
340 | b67ea0cd | Max Filippov | } |
341 | b67ea0cd | Max Filippov | return 0xff; |
342 | b67ea0cd | Max Filippov | } |
343 | b67ea0cd | Max Filippov | |
344 | b67ea0cd | Max Filippov | /*!
|
345 | b67ea0cd | Max Filippov | * Lookup xtensa TLB for the given virtual address.
|
346 | b67ea0cd | Max Filippov | * See ISA, 4.6.2.2
|
347 | b67ea0cd | Max Filippov | *
|
348 | b67ea0cd | Max Filippov | * \param pwi: [out] way index
|
349 | b67ea0cd | Max Filippov | * \param pei: [out] entry index
|
350 | b67ea0cd | Max Filippov | * \param pring: [out] access ring
|
351 | b67ea0cd | Max Filippov | * \return 0 if ok, exception cause code otherwise
|
352 | b67ea0cd | Max Filippov | */
|
353 | 97129ac8 | Andreas Färber | int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, |
354 | b67ea0cd | Max Filippov | uint32_t *pwi, uint32_t *pei, uint8_t *pring) |
355 | b67ea0cd | Max Filippov | { |
356 | b67ea0cd | Max Filippov | const xtensa_tlb *tlb = dtlb ?
|
357 | b67ea0cd | Max Filippov | &env->config->dtlb : &env->config->itlb; |
358 | b67ea0cd | Max Filippov | const xtensa_tlb_entry (*entry)[MAX_TLB_WAY_SIZE] = dtlb ?
|
359 | b67ea0cd | Max Filippov | env->dtlb : env->itlb; |
360 | b67ea0cd | Max Filippov | |
361 | b67ea0cd | Max Filippov | int nhits = 0; |
362 | b67ea0cd | Max Filippov | unsigned wi;
|
363 | b67ea0cd | Max Filippov | |
364 | b67ea0cd | Max Filippov | for (wi = 0; wi < tlb->nways; ++wi) { |
365 | b67ea0cd | Max Filippov | uint32_t vpn; |
366 | b67ea0cd | Max Filippov | uint32_t ei; |
367 | b67ea0cd | Max Filippov | split_tlb_entry_spec_way(env, addr, dtlb, &vpn, wi, &ei); |
368 | b67ea0cd | Max Filippov | if (entry[wi][ei].vaddr == vpn && entry[wi][ei].asid) {
|
369 | b67ea0cd | Max Filippov | unsigned ring = get_ring(env, entry[wi][ei].asid);
|
370 | b67ea0cd | Max Filippov | if (ring < 4) { |
371 | b67ea0cd | Max Filippov | if (++nhits > 1) { |
372 | b67ea0cd | Max Filippov | return dtlb ?
|
373 | b67ea0cd | Max Filippov | LOAD_STORE_TLB_MULTI_HIT_CAUSE : |
374 | b67ea0cd | Max Filippov | INST_TLB_MULTI_HIT_CAUSE; |
375 | b67ea0cd | Max Filippov | } |
376 | b67ea0cd | Max Filippov | *pwi = wi; |
377 | b67ea0cd | Max Filippov | *pei = ei; |
378 | b67ea0cd | Max Filippov | *pring = ring; |
379 | b67ea0cd | Max Filippov | } |
380 | b67ea0cd | Max Filippov | } |
381 | b67ea0cd | Max Filippov | } |
382 | b67ea0cd | Max Filippov | return nhits ? 0 : |
383 | b67ea0cd | Max Filippov | (dtlb ? LOAD_STORE_TLB_MISS_CAUSE : INST_TLB_MISS_CAUSE); |
384 | b67ea0cd | Max Filippov | } |
385 | b67ea0cd | Max Filippov | |
386 | b67ea0cd | Max Filippov | /*!
|
387 | b67ea0cd | Max Filippov | * Convert MMU ATTR to PAGE_{READ,WRITE,EXEC} mask.
|
388 | b67ea0cd | Max Filippov | * See ISA, 4.6.5.10
|
389 | b67ea0cd | Max Filippov | */
|
390 | b67ea0cd | Max Filippov | static unsigned mmu_attr_to_access(uint32_t attr) |
391 | b67ea0cd | Max Filippov | { |
392 | b67ea0cd | Max Filippov | unsigned access = 0; |
393 | b67ea0cd | Max Filippov | if (attr < 12) { |
394 | b67ea0cd | Max Filippov | access |= PAGE_READ; |
395 | b67ea0cd | Max Filippov | if (attr & 0x1) { |
396 | b67ea0cd | Max Filippov | access |= PAGE_EXEC; |
397 | b67ea0cd | Max Filippov | } |
398 | b67ea0cd | Max Filippov | if (attr & 0x2) { |
399 | b67ea0cd | Max Filippov | access |= PAGE_WRITE; |
400 | b67ea0cd | Max Filippov | } |
401 | b67ea0cd | Max Filippov | } else if (attr == 13) { |
402 | b67ea0cd | Max Filippov | access |= PAGE_READ | PAGE_WRITE; |
403 | b67ea0cd | Max Filippov | } |
404 | b67ea0cd | Max Filippov | return access;
|
405 | b67ea0cd | Max Filippov | } |
406 | b67ea0cd | Max Filippov | |
407 | b67ea0cd | Max Filippov | /*!
|
408 | b67ea0cd | Max Filippov | * Convert region protection ATTR to PAGE_{READ,WRITE,EXEC} mask.
|
409 | b67ea0cd | Max Filippov | * See ISA, 4.6.3.3
|
410 | b67ea0cd | Max Filippov | */
|
411 | b67ea0cd | Max Filippov | static unsigned region_attr_to_access(uint32_t attr) |
412 | b67ea0cd | Max Filippov | { |
413 | b67ea0cd | Max Filippov | unsigned access = 0; |
414 | b67ea0cd | Max Filippov | if ((attr < 6 && attr != 3) || attr == 14) { |
415 | b67ea0cd | Max Filippov | access |= PAGE_READ | PAGE_WRITE; |
416 | b67ea0cd | Max Filippov | } |
417 | b67ea0cd | Max Filippov | if (attr > 0 && attr < 6) { |
418 | b67ea0cd | Max Filippov | access |= PAGE_EXEC; |
419 | b67ea0cd | Max Filippov | } |
420 | b67ea0cd | Max Filippov | return access;
|
421 | b67ea0cd | Max Filippov | } |
422 | b67ea0cd | Max Filippov | |
423 | b67ea0cd | Max Filippov | static bool is_access_granted(unsigned access, int is_write) |
424 | b67ea0cd | Max Filippov | { |
425 | b67ea0cd | Max Filippov | switch (is_write) {
|
426 | b67ea0cd | Max Filippov | case 0: |
427 | b67ea0cd | Max Filippov | return access & PAGE_READ;
|
428 | b67ea0cd | Max Filippov | |
429 | b67ea0cd | Max Filippov | case 1: |
430 | b67ea0cd | Max Filippov | return access & PAGE_WRITE;
|
431 | b67ea0cd | Max Filippov | |
432 | b67ea0cd | Max Filippov | case 2: |
433 | b67ea0cd | Max Filippov | return access & PAGE_EXEC;
|
434 | b67ea0cd | Max Filippov | |
435 | b67ea0cd | Max Filippov | default:
|
436 | b67ea0cd | Max Filippov | return 0; |
437 | b67ea0cd | Max Filippov | } |
438 | b67ea0cd | Max Filippov | } |
439 | b67ea0cd | Max Filippov | |
440 | ae4e7982 | Max Filippov | static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte); |
441 | b67ea0cd | Max Filippov | |
442 | ae4e7982 | Max Filippov | static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb, |
443 | b67ea0cd | Max Filippov | uint32_t vaddr, int is_write, int mmu_idx, |
444 | 57705a67 | Max Filippov | uint32_t *paddr, uint32_t *page_size, unsigned *access,
|
445 | 57705a67 | Max Filippov | bool may_lookup_pt)
|
446 | b67ea0cd | Max Filippov | { |
447 | b67ea0cd | Max Filippov | bool dtlb = is_write != 2; |
448 | b67ea0cd | Max Filippov | uint32_t wi; |
449 | b67ea0cd | Max Filippov | uint32_t ei; |
450 | b67ea0cd | Max Filippov | uint8_t ring; |
451 | ae4e7982 | Max Filippov | uint32_t vpn; |
452 | ae4e7982 | Max Filippov | uint32_t pte; |
453 | ae4e7982 | Max Filippov | const xtensa_tlb_entry *entry = NULL; |
454 | ae4e7982 | Max Filippov | xtensa_tlb_entry tmp_entry; |
455 | b67ea0cd | Max Filippov | int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring);
|
456 | b67ea0cd | Max Filippov | |
457 | b67ea0cd | Max Filippov | if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) &&
|
458 | 57705a67 | Max Filippov | may_lookup_pt && get_pte(env, vaddr, &pte) == 0) {
|
459 | ae4e7982 | Max Filippov | ring = (pte >> 4) & 0x3; |
460 | ae4e7982 | Max Filippov | wi = 0;
|
461 | ae4e7982 | Max Filippov | split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei); |
462 | ae4e7982 | Max Filippov | |
463 | ae4e7982 | Max Filippov | if (update_tlb) {
|
464 | ae4e7982 | Max Filippov | wi = ++env->autorefill_idx & 0x3;
|
465 | ae4e7982 | Max Filippov | xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte); |
466 | ae4e7982 | Max Filippov | env->sregs[EXCVADDR] = vaddr; |
467 | ae4e7982 | Max Filippov | qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
|
468 | ae4e7982 | Max Filippov | __func__, vaddr, vpn, pte); |
469 | ae4e7982 | Max Filippov | } else {
|
470 | ae4e7982 | Max Filippov | xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte); |
471 | ae4e7982 | Max Filippov | entry = &tmp_entry; |
472 | ae4e7982 | Max Filippov | } |
473 | b67ea0cd | Max Filippov | ret = 0;
|
474 | b67ea0cd | Max Filippov | } |
475 | b67ea0cd | Max Filippov | if (ret != 0) { |
476 | b67ea0cd | Max Filippov | return ret;
|
477 | b67ea0cd | Max Filippov | } |
478 | b67ea0cd | Max Filippov | |
479 | ae4e7982 | Max Filippov | if (entry == NULL) { |
480 | ae4e7982 | Max Filippov | entry = xtensa_tlb_get_entry(env, dtlb, wi, ei); |
481 | ae4e7982 | Max Filippov | } |
482 | b67ea0cd | Max Filippov | |
483 | b67ea0cd | Max Filippov | if (ring < mmu_idx) {
|
484 | b67ea0cd | Max Filippov | return dtlb ?
|
485 | b67ea0cd | Max Filippov | LOAD_STORE_PRIVILEGE_CAUSE : |
486 | b67ea0cd | Max Filippov | INST_FETCH_PRIVILEGE_CAUSE; |
487 | b67ea0cd | Max Filippov | } |
488 | b67ea0cd | Max Filippov | |
489 | b67ea0cd | Max Filippov | *access = mmu_attr_to_access(entry->attr); |
490 | b67ea0cd | Max Filippov | if (!is_access_granted(*access, is_write)) {
|
491 | b67ea0cd | Max Filippov | return dtlb ?
|
492 | b67ea0cd | Max Filippov | (is_write ? |
493 | b67ea0cd | Max Filippov | STORE_PROHIBITED_CAUSE : |
494 | b67ea0cd | Max Filippov | LOAD_PROHIBITED_CAUSE) : |
495 | b67ea0cd | Max Filippov | INST_FETCH_PROHIBITED_CAUSE; |
496 | b67ea0cd | Max Filippov | } |
497 | b67ea0cd | Max Filippov | |
498 | b67ea0cd | Max Filippov | *paddr = entry->paddr | (vaddr & ~xtensa_tlb_get_addr_mask(env, dtlb, wi)); |
499 | b67ea0cd | Max Filippov | *page_size = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;
|
500 | b67ea0cd | Max Filippov | |
501 | b67ea0cd | Max Filippov | return 0; |
502 | b67ea0cd | Max Filippov | } |
503 | b67ea0cd | Max Filippov | |
504 | ae4e7982 | Max Filippov | static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte) |
505 | b67ea0cd | Max Filippov | { |
506 | b67ea0cd | Max Filippov | uint32_t paddr; |
507 | b67ea0cd | Max Filippov | uint32_t page_size; |
508 | b67ea0cd | Max Filippov | unsigned access;
|
509 | b67ea0cd | Max Filippov | uint32_t pt_vaddr = |
510 | b67ea0cd | Max Filippov | (env->sregs[PTEVADDR] | (vaddr >> 10)) & 0xfffffffc; |
511 | ae4e7982 | Max Filippov | int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0, |
512 | 57705a67 | Max Filippov | &paddr, &page_size, &access, false);
|
513 | b67ea0cd | Max Filippov | |
514 | b67ea0cd | Max Filippov | qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__,
|
515 | b67ea0cd | Max Filippov | vaddr, ret ? ~0 : paddr);
|
516 | b67ea0cd | Max Filippov | |
517 | b67ea0cd | Max Filippov | if (ret == 0) { |
518 | ae4e7982 | Max Filippov | *pte = ldl_phys(paddr); |
519 | b67ea0cd | Max Filippov | } |
520 | b67ea0cd | Max Filippov | return ret;
|
521 | b67ea0cd | Max Filippov | } |
522 | b67ea0cd | Max Filippov | |
523 | 97129ac8 | Andreas Färber | static int get_physical_addr_region(CPUXtensaState *env, |
524 | b67ea0cd | Max Filippov | uint32_t vaddr, int is_write, int mmu_idx, |
525 | b67ea0cd | Max Filippov | uint32_t *paddr, uint32_t *page_size, unsigned *access)
|
526 | b67ea0cd | Max Filippov | { |
527 | b67ea0cd | Max Filippov | bool dtlb = is_write != 2; |
528 | b67ea0cd | Max Filippov | uint32_t wi = 0;
|
529 | b67ea0cd | Max Filippov | uint32_t ei = (vaddr >> 29) & 0x7; |
530 | b67ea0cd | Max Filippov | const xtensa_tlb_entry *entry =
|
531 | b67ea0cd | Max Filippov | xtensa_tlb_get_entry(env, dtlb, wi, ei); |
532 | b67ea0cd | Max Filippov | |
533 | b67ea0cd | Max Filippov | *access = region_attr_to_access(entry->attr); |
534 | b67ea0cd | Max Filippov | if (!is_access_granted(*access, is_write)) {
|
535 | b67ea0cd | Max Filippov | return dtlb ?
|
536 | b67ea0cd | Max Filippov | (is_write ? |
537 | b67ea0cd | Max Filippov | STORE_PROHIBITED_CAUSE : |
538 | b67ea0cd | Max Filippov | LOAD_PROHIBITED_CAUSE) : |
539 | b67ea0cd | Max Filippov | INST_FETCH_PROHIBITED_CAUSE; |
540 | b67ea0cd | Max Filippov | } |
541 | b67ea0cd | Max Filippov | |
542 | b67ea0cd | Max Filippov | *paddr = entry->paddr | (vaddr & ~REGION_PAGE_MASK); |
543 | b67ea0cd | Max Filippov | *page_size = ~REGION_PAGE_MASK + 1;
|
544 | b67ea0cd | Max Filippov | |
545 | b67ea0cd | Max Filippov | return 0; |
546 | b67ea0cd | Max Filippov | } |
547 | b67ea0cd | Max Filippov | |
548 | b67ea0cd | Max Filippov | /*!
|
549 | b67ea0cd | Max Filippov | * Convert virtual address to physical addr.
|
550 | b67ea0cd | Max Filippov | * MMU may issue pagewalk and change xtensa autorefill TLB way entry.
|
551 | b67ea0cd | Max Filippov | *
|
552 | b67ea0cd | Max Filippov | * \return 0 if ok, exception cause code otherwise
|
553 | b67ea0cd | Max Filippov | */
|
554 | ae4e7982 | Max Filippov | int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, |
555 | b67ea0cd | Max Filippov | uint32_t vaddr, int is_write, int mmu_idx, |
556 | b67ea0cd | Max Filippov | uint32_t *paddr, uint32_t *page_size, unsigned *access)
|
557 | b67ea0cd | Max Filippov | { |
558 | b67ea0cd | Max Filippov | if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
559 | ae4e7982 | Max Filippov | return get_physical_addr_mmu(env, update_tlb,
|
560 | 57705a67 | Max Filippov | vaddr, is_write, mmu_idx, paddr, page_size, access, true);
|
561 | b67ea0cd | Max Filippov | } else if (xtensa_option_bits_enabled(env->config, |
562 | b67ea0cd | Max Filippov | XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) | |
563 | b67ea0cd | Max Filippov | XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) { |
564 | b67ea0cd | Max Filippov | return get_physical_addr_region(env, vaddr, is_write, mmu_idx,
|
565 | b67ea0cd | Max Filippov | paddr, page_size, access); |
566 | b67ea0cd | Max Filippov | } else {
|
567 | b67ea0cd | Max Filippov | *paddr = vaddr; |
568 | b67ea0cd | Max Filippov | *page_size = TARGET_PAGE_SIZE; |
569 | b67ea0cd | Max Filippov | *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC; |
570 | b67ea0cd | Max Filippov | return 0; |
571 | b67ea0cd | Max Filippov | } |
572 | b67ea0cd | Max Filippov | } |
573 | 692f737c | Max Filippov | |
574 | 692f737c | Max Filippov | static void dump_tlb(FILE *f, fprintf_function cpu_fprintf, |
575 | 97129ac8 | Andreas Färber | CPUXtensaState *env, bool dtlb)
|
576 | 692f737c | Max Filippov | { |
577 | 692f737c | Max Filippov | unsigned wi, ei;
|
578 | 692f737c | Max Filippov | const xtensa_tlb *conf =
|
579 | 692f737c | Max Filippov | dtlb ? &env->config->dtlb : &env->config->itlb; |
580 | 692f737c | Max Filippov | unsigned (*attr_to_access)(uint32_t) =
|
581 | 692f737c | Max Filippov | xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) ? |
582 | 692f737c | Max Filippov | mmu_attr_to_access : region_attr_to_access; |
583 | 692f737c | Max Filippov | |
584 | 692f737c | Max Filippov | for (wi = 0; wi < conf->nways; ++wi) { |
585 | 692f737c | Max Filippov | uint32_t sz = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;
|
586 | 692f737c | Max Filippov | const char *sz_text; |
587 | 692f737c | Max Filippov | bool print_header = true; |
588 | 692f737c | Max Filippov | |
589 | 692f737c | Max Filippov | if (sz >= 0x100000) { |
590 | 692f737c | Max Filippov | sz >>= 20;
|
591 | 692f737c | Max Filippov | sz_text = "MB";
|
592 | 692f737c | Max Filippov | } else {
|
593 | 692f737c | Max Filippov | sz >>= 10;
|
594 | 692f737c | Max Filippov | sz_text = "KB";
|
595 | 692f737c | Max Filippov | } |
596 | 692f737c | Max Filippov | |
597 | 692f737c | Max Filippov | for (ei = 0; ei < conf->way_size[wi]; ++ei) { |
598 | 692f737c | Max Filippov | const xtensa_tlb_entry *entry =
|
599 | 692f737c | Max Filippov | xtensa_tlb_get_entry(env, dtlb, wi, ei); |
600 | 692f737c | Max Filippov | |
601 | 692f737c | Max Filippov | if (entry->asid) {
|
602 | 692f737c | Max Filippov | unsigned access = attr_to_access(entry->attr);
|
603 | 692f737c | Max Filippov | |
604 | 692f737c | Max Filippov | if (print_header) {
|
605 | 692f737c | Max Filippov | print_header = false;
|
606 | 692f737c | Max Filippov | cpu_fprintf(f, "Way %u (%d %s)\n", wi, sz, sz_text);
|
607 | 692f737c | Max Filippov | cpu_fprintf(f, |
608 | 692f737c | Max Filippov | "\tVaddr Paddr ASID Attr RWX\n"
|
609 | 692f737c | Max Filippov | "\t---------- ---------- ---- ---- ---\n");
|
610 | 692f737c | Max Filippov | } |
611 | 692f737c | Max Filippov | cpu_fprintf(f, |
612 | 692f737c | Max Filippov | "\t0x%08x 0x%08x 0x%02x 0x%02x %c%c%c\n",
|
613 | 692f737c | Max Filippov | entry->vaddr, |
614 | 692f737c | Max Filippov | entry->paddr, |
615 | 692f737c | Max Filippov | entry->asid, |
616 | 692f737c | Max Filippov | entry->attr, |
617 | 692f737c | Max Filippov | (access & PAGE_READ) ? 'R' : '-', |
618 | 692f737c | Max Filippov | (access & PAGE_WRITE) ? 'W' : '-', |
619 | 692f737c | Max Filippov | (access & PAGE_EXEC) ? 'X' : '-'); |
620 | 692f737c | Max Filippov | } |
621 | 692f737c | Max Filippov | } |
622 | 692f737c | Max Filippov | } |
623 | 692f737c | Max Filippov | } |
624 | 692f737c | Max Filippov | |
625 | 97129ac8 | Andreas Färber | void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env)
|
626 | 692f737c | Max Filippov | { |
627 | 692f737c | Max Filippov | if (xtensa_option_bits_enabled(env->config,
|
628 | 692f737c | Max Filippov | XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) | |
629 | 692f737c | Max Filippov | XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION) | |
630 | 692f737c | Max Filippov | XTENSA_OPTION_BIT(XTENSA_OPTION_MMU))) { |
631 | 692f737c | Max Filippov | |
632 | 692f737c | Max Filippov | cpu_fprintf(f, "ITLB:\n");
|
633 | 692f737c | Max Filippov | dump_tlb(f, cpu_fprintf, env, false);
|
634 | 692f737c | Max Filippov | cpu_fprintf(f, "\nDTLB:\n");
|
635 | 692f737c | Max Filippov | dump_tlb(f, cpu_fprintf, env, true);
|
636 | 692f737c | Max Filippov | } else {
|
637 | 692f737c | Max Filippov | cpu_fprintf(f, "No TLB for this CPU core\n");
|
638 | 692f737c | Max Filippov | } |
639 | 692f737c | Max Filippov | } |