1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47#ifndef CPU_LDST_H
48#define CPU_LDST_H
49
50#if defined(CONFIG_USER_ONLY)
51
52
53
54#if TARGET_VIRT_ADDR_SPACE_BITS <= 32
55typedef uint32_t abi_ptr;
56#define TARGET_ABI_FMT_ptr "%x"
57#else
58typedef uint64_t abi_ptr;
59#define TARGET_ABI_FMT_ptr "%"PRIx64
60#endif
61
62
63#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
64
65#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
66#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
67
68static inline int guest_range_valid(unsigned long start, unsigned long len)
69{
70 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
71}
72
73#define h2g_nocheck(x) ({ \
74 unsigned long __ret = (unsigned long)(x) - guest_base; \
75 (abi_ptr)__ret; \
76})
77
78#define h2g(x) ({ \
79 \
80 assert(h2g_valid(x)); \
81 h2g_nocheck(x); \
82})
83#else
84typedef target_ulong abi_ptr;
85#define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
86#endif
87
88#if defined(CONFIG_USER_ONLY)
89
90extern __thread uintptr_t helper_retaddr;
91
92
93
94#define MEMSUFFIX _data
95#define DATA_SIZE 1
96#include "exec/cpu_ldst_useronly_template.h"
97
98#define DATA_SIZE 2
99#include "exec/cpu_ldst_useronly_template.h"
100
101#define DATA_SIZE 4
102#include "exec/cpu_ldst_useronly_template.h"
103
104#define DATA_SIZE 8
105#include "exec/cpu_ldst_useronly_template.h"
106#undef MEMSUFFIX
107
108#define MEMSUFFIX _code
109#define CODE_ACCESS
110#define DATA_SIZE 1
111#include "exec/cpu_ldst_useronly_template.h"
112
113#define DATA_SIZE 2
114#include "exec/cpu_ldst_useronly_template.h"
115
116#define DATA_SIZE 4
117#include "exec/cpu_ldst_useronly_template.h"
118
119#define DATA_SIZE 8
120#include "exec/cpu_ldst_useronly_template.h"
121#undef MEMSUFFIX
122#undef CODE_ACCESS
123
124#else
125
126
127#include "tcg.h"
128
129static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry)
130{
131#if TCG_OVERSIZED_GUEST
132 return entry->addr_write;
133#else
134 return atomic_read(&entry->addr_write);
135#endif
136}
137
138
139static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
140 target_ulong addr)
141{
142 uintptr_t size_mask = env->tlb_mask[mmu_idx] >> CPU_TLB_ENTRY_BITS;
143
144 return (addr >> TARGET_PAGE_BITS) & size_mask;
145}
146
147static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx)
148{
149 return (env->tlb_mask[mmu_idx] >> CPU_TLB_ENTRY_BITS) + 1;
150}
151
152
153static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
154 target_ulong addr)
155{
156 return &env->tlb_table[mmu_idx][tlb_index(env, mmu_idx, addr)];
157}
158
159#ifdef MMU_MODE0_SUFFIX
160#define CPU_MMU_INDEX 0
161#define MEMSUFFIX MMU_MODE0_SUFFIX
162#define DATA_SIZE 1
163#include "exec/cpu_ldst_template.h"
164
165#define DATA_SIZE 2
166#include "exec/cpu_ldst_template.h"
167
168#define DATA_SIZE 4
169#include "exec/cpu_ldst_template.h"
170
171#define DATA_SIZE 8
172#include "exec/cpu_ldst_template.h"
173#undef CPU_MMU_INDEX
174#undef MEMSUFFIX
175#endif
176
177#if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
178#define CPU_MMU_INDEX 1
179#define MEMSUFFIX MMU_MODE1_SUFFIX
180#define DATA_SIZE 1
181#include "exec/cpu_ldst_template.h"
182
183#define DATA_SIZE 2
184#include "exec/cpu_ldst_template.h"
185
186#define DATA_SIZE 4
187#include "exec/cpu_ldst_template.h"
188
189#define DATA_SIZE 8
190#include "exec/cpu_ldst_template.h"
191#undef CPU_MMU_INDEX
192#undef MEMSUFFIX
193#endif
194
195#if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX)
196
197#define CPU_MMU_INDEX 2
198#define MEMSUFFIX MMU_MODE2_SUFFIX
199#define DATA_SIZE 1
200#include "exec/cpu_ldst_template.h"
201
202#define DATA_SIZE 2
203#include "exec/cpu_ldst_template.h"
204
205#define DATA_SIZE 4
206#include "exec/cpu_ldst_template.h"
207
208#define DATA_SIZE 8
209#include "exec/cpu_ldst_template.h"
210#undef CPU_MMU_INDEX
211#undef MEMSUFFIX
212#endif
213
214#if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
215
216#define CPU_MMU_INDEX 3
217#define MEMSUFFIX MMU_MODE3_SUFFIX
218#define DATA_SIZE 1
219#include "exec/cpu_ldst_template.h"
220
221#define DATA_SIZE 2
222#include "exec/cpu_ldst_template.h"
223
224#define DATA_SIZE 4
225#include "exec/cpu_ldst_template.h"
226
227#define DATA_SIZE 8
228#include "exec/cpu_ldst_template.h"
229#undef CPU_MMU_INDEX
230#undef MEMSUFFIX
231#endif
232
233#if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
234
235#define CPU_MMU_INDEX 4
236#define MEMSUFFIX MMU_MODE4_SUFFIX
237#define DATA_SIZE 1
238#include "exec/cpu_ldst_template.h"
239
240#define DATA_SIZE 2
241#include "exec/cpu_ldst_template.h"
242
243#define DATA_SIZE 4
244#include "exec/cpu_ldst_template.h"
245
246#define DATA_SIZE 8
247#include "exec/cpu_ldst_template.h"
248#undef CPU_MMU_INDEX
249#undef MEMSUFFIX
250#endif
251
252#if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
253
254#define CPU_MMU_INDEX 5
255#define MEMSUFFIX MMU_MODE5_SUFFIX
256#define DATA_SIZE 1
257#include "exec/cpu_ldst_template.h"
258
259#define DATA_SIZE 2
260#include "exec/cpu_ldst_template.h"
261
262#define DATA_SIZE 4
263#include "exec/cpu_ldst_template.h"
264
265#define DATA_SIZE 8
266#include "exec/cpu_ldst_template.h"
267#undef CPU_MMU_INDEX
268#undef MEMSUFFIX
269#endif
270
271#if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX)
272
273#define CPU_MMU_INDEX 6
274#define MEMSUFFIX MMU_MODE6_SUFFIX
275#define DATA_SIZE 1
276#include "exec/cpu_ldst_template.h"
277
278#define DATA_SIZE 2
279#include "exec/cpu_ldst_template.h"
280
281#define DATA_SIZE 4
282#include "exec/cpu_ldst_template.h"
283
284#define DATA_SIZE 8
285#include "exec/cpu_ldst_template.h"
286#undef CPU_MMU_INDEX
287#undef MEMSUFFIX
288#endif
289
290#if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX)
291
292#define CPU_MMU_INDEX 7
293#define MEMSUFFIX MMU_MODE7_SUFFIX
294#define DATA_SIZE 1
295#include "exec/cpu_ldst_template.h"
296
297#define DATA_SIZE 2
298#include "exec/cpu_ldst_template.h"
299
300#define DATA_SIZE 4
301#include "exec/cpu_ldst_template.h"
302
303#define DATA_SIZE 8
304#include "exec/cpu_ldst_template.h"
305#undef CPU_MMU_INDEX
306#undef MEMSUFFIX
307#endif
308
309#if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX)
310
311#define CPU_MMU_INDEX 8
312#define MEMSUFFIX MMU_MODE8_SUFFIX
313#define DATA_SIZE 1
314#include "exec/cpu_ldst_template.h"
315
316#define DATA_SIZE 2
317#include "exec/cpu_ldst_template.h"
318
319#define DATA_SIZE 4
320#include "exec/cpu_ldst_template.h"
321
322#define DATA_SIZE 8
323#include "exec/cpu_ldst_template.h"
324#undef CPU_MMU_INDEX
325#undef MEMSUFFIX
326#endif
327
328#if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX)
329
330#define CPU_MMU_INDEX 9
331#define MEMSUFFIX MMU_MODE9_SUFFIX
332#define DATA_SIZE 1
333#include "exec/cpu_ldst_template.h"
334
335#define DATA_SIZE 2
336#include "exec/cpu_ldst_template.h"
337
338#define DATA_SIZE 4
339#include "exec/cpu_ldst_template.h"
340
341#define DATA_SIZE 8
342#include "exec/cpu_ldst_template.h"
343#undef CPU_MMU_INDEX
344#undef MEMSUFFIX
345#endif
346
347#if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX)
348
349#define CPU_MMU_INDEX 10
350#define MEMSUFFIX MMU_MODE10_SUFFIX
351#define DATA_SIZE 1
352#include "exec/cpu_ldst_template.h"
353
354#define DATA_SIZE 2
355#include "exec/cpu_ldst_template.h"
356
357#define DATA_SIZE 4
358#include "exec/cpu_ldst_template.h"
359
360#define DATA_SIZE 8
361#include "exec/cpu_ldst_template.h"
362#undef CPU_MMU_INDEX
363#undef MEMSUFFIX
364#endif
365
366#if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX)
367
368#define CPU_MMU_INDEX 11
369#define MEMSUFFIX MMU_MODE11_SUFFIX
370#define DATA_SIZE 1
371#include "exec/cpu_ldst_template.h"
372
373#define DATA_SIZE 2
374#include "exec/cpu_ldst_template.h"
375
376#define DATA_SIZE 4
377#include "exec/cpu_ldst_template.h"
378
379#define DATA_SIZE 8
380#include "exec/cpu_ldst_template.h"
381#undef CPU_MMU_INDEX
382#undef MEMSUFFIX
383#endif
384
385#if (NB_MMU_MODES > 12)
386#error "NB_MMU_MODES > 12 is not supported for now"
387#endif
388
389
390#define CPU_MMU_INDEX (cpu_mmu_index(env, false))
391#define MEMSUFFIX _data
392#define DATA_SIZE 1
393#include "exec/cpu_ldst_template.h"
394
395#define DATA_SIZE 2
396#include "exec/cpu_ldst_template.h"
397
398#define DATA_SIZE 4
399#include "exec/cpu_ldst_template.h"
400
401#define DATA_SIZE 8
402#include "exec/cpu_ldst_template.h"
403#undef CPU_MMU_INDEX
404#undef MEMSUFFIX
405
406#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
407#define MEMSUFFIX _code
408#define SOFTMMU_CODE_ACCESS
409
410#define DATA_SIZE 1
411#include "exec/cpu_ldst_template.h"
412
413#define DATA_SIZE 2
414#include "exec/cpu_ldst_template.h"
415
416#define DATA_SIZE 4
417#include "exec/cpu_ldst_template.h"
418
419#define DATA_SIZE 8
420#include "exec/cpu_ldst_template.h"
421
422#undef CPU_MMU_INDEX
423#undef MEMSUFFIX
424#undef SOFTMMU_CODE_ACCESS
425
426#endif
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
444 int access_type, int mmu_idx)
445{
446#if defined(CONFIG_USER_ONLY)
447 return g2h(addr);
448#else
449 CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
450 abi_ptr tlb_addr;
451 uintptr_t haddr;
452
453 switch (access_type) {
454 case 0:
455 tlb_addr = tlbentry->addr_read;
456 break;
457 case 1:
458 tlb_addr = tlb_addr_write(tlbentry);
459 break;
460 case 2:
461 tlb_addr = tlbentry->addr_code;
462 break;
463 default:
464 g_assert_not_reached();
465 }
466
467 if (!tlb_hit(tlb_addr, addr)) {
468
469 return NULL;
470 }
471
472 if (tlb_addr & ~TARGET_PAGE_MASK) {
473
474 return NULL;
475 }
476
477 haddr = addr + tlbentry->addend;
478 return (void *)haddr;
479#endif
480}
481
482#endif
483