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 return (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
143}
144
145
146static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
147 target_ulong addr)
148{
149 return &env->tlb_table[mmu_idx][tlb_index(env, mmu_idx, addr)];
150}
151
152#ifdef MMU_MODE0_SUFFIX
153#define CPU_MMU_INDEX 0
154#define MEMSUFFIX MMU_MODE0_SUFFIX
155#define DATA_SIZE 1
156#include "exec/cpu_ldst_template.h"
157
158#define DATA_SIZE 2
159#include "exec/cpu_ldst_template.h"
160
161#define DATA_SIZE 4
162#include "exec/cpu_ldst_template.h"
163
164#define DATA_SIZE 8
165#include "exec/cpu_ldst_template.h"
166#undef CPU_MMU_INDEX
167#undef MEMSUFFIX
168#endif
169
170#if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
171#define CPU_MMU_INDEX 1
172#define MEMSUFFIX MMU_MODE1_SUFFIX
173#define DATA_SIZE 1
174#include "exec/cpu_ldst_template.h"
175
176#define DATA_SIZE 2
177#include "exec/cpu_ldst_template.h"
178
179#define DATA_SIZE 4
180#include "exec/cpu_ldst_template.h"
181
182#define DATA_SIZE 8
183#include "exec/cpu_ldst_template.h"
184#undef CPU_MMU_INDEX
185#undef MEMSUFFIX
186#endif
187
188#if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX)
189
190#define CPU_MMU_INDEX 2
191#define MEMSUFFIX MMU_MODE2_SUFFIX
192#define DATA_SIZE 1
193#include "exec/cpu_ldst_template.h"
194
195#define DATA_SIZE 2
196#include "exec/cpu_ldst_template.h"
197
198#define DATA_SIZE 4
199#include "exec/cpu_ldst_template.h"
200
201#define DATA_SIZE 8
202#include "exec/cpu_ldst_template.h"
203#undef CPU_MMU_INDEX
204#undef MEMSUFFIX
205#endif
206
207#if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
208
209#define CPU_MMU_INDEX 3
210#define MEMSUFFIX MMU_MODE3_SUFFIX
211#define DATA_SIZE 1
212#include "exec/cpu_ldst_template.h"
213
214#define DATA_SIZE 2
215#include "exec/cpu_ldst_template.h"
216
217#define DATA_SIZE 4
218#include "exec/cpu_ldst_template.h"
219
220#define DATA_SIZE 8
221#include "exec/cpu_ldst_template.h"
222#undef CPU_MMU_INDEX
223#undef MEMSUFFIX
224#endif
225
226#if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
227
228#define CPU_MMU_INDEX 4
229#define MEMSUFFIX MMU_MODE4_SUFFIX
230#define DATA_SIZE 1
231#include "exec/cpu_ldst_template.h"
232
233#define DATA_SIZE 2
234#include "exec/cpu_ldst_template.h"
235
236#define DATA_SIZE 4
237#include "exec/cpu_ldst_template.h"
238
239#define DATA_SIZE 8
240#include "exec/cpu_ldst_template.h"
241#undef CPU_MMU_INDEX
242#undef MEMSUFFIX
243#endif
244
245#if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
246
247#define CPU_MMU_INDEX 5
248#define MEMSUFFIX MMU_MODE5_SUFFIX
249#define DATA_SIZE 1
250#include "exec/cpu_ldst_template.h"
251
252#define DATA_SIZE 2
253#include "exec/cpu_ldst_template.h"
254
255#define DATA_SIZE 4
256#include "exec/cpu_ldst_template.h"
257
258#define DATA_SIZE 8
259#include "exec/cpu_ldst_template.h"
260#undef CPU_MMU_INDEX
261#undef MEMSUFFIX
262#endif
263
264#if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX)
265
266#define CPU_MMU_INDEX 6
267#define MEMSUFFIX MMU_MODE6_SUFFIX
268#define DATA_SIZE 1
269#include "exec/cpu_ldst_template.h"
270
271#define DATA_SIZE 2
272#include "exec/cpu_ldst_template.h"
273
274#define DATA_SIZE 4
275#include "exec/cpu_ldst_template.h"
276
277#define DATA_SIZE 8
278#include "exec/cpu_ldst_template.h"
279#undef CPU_MMU_INDEX
280#undef MEMSUFFIX
281#endif
282
283#if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX)
284
285#define CPU_MMU_INDEX 7
286#define MEMSUFFIX MMU_MODE7_SUFFIX
287#define DATA_SIZE 1
288#include "exec/cpu_ldst_template.h"
289
290#define DATA_SIZE 2
291#include "exec/cpu_ldst_template.h"
292
293#define DATA_SIZE 4
294#include "exec/cpu_ldst_template.h"
295
296#define DATA_SIZE 8
297#include "exec/cpu_ldst_template.h"
298#undef CPU_MMU_INDEX
299#undef MEMSUFFIX
300#endif
301
302#if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX)
303
304#define CPU_MMU_INDEX 8
305#define MEMSUFFIX MMU_MODE8_SUFFIX
306#define DATA_SIZE 1
307#include "exec/cpu_ldst_template.h"
308
309#define DATA_SIZE 2
310#include "exec/cpu_ldst_template.h"
311
312#define DATA_SIZE 4
313#include "exec/cpu_ldst_template.h"
314
315#define DATA_SIZE 8
316#include "exec/cpu_ldst_template.h"
317#undef CPU_MMU_INDEX
318#undef MEMSUFFIX
319#endif
320
321#if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX)
322
323#define CPU_MMU_INDEX 9
324#define MEMSUFFIX MMU_MODE9_SUFFIX
325#define DATA_SIZE 1
326#include "exec/cpu_ldst_template.h"
327
328#define DATA_SIZE 2
329#include "exec/cpu_ldst_template.h"
330
331#define DATA_SIZE 4
332#include "exec/cpu_ldst_template.h"
333
334#define DATA_SIZE 8
335#include "exec/cpu_ldst_template.h"
336#undef CPU_MMU_INDEX
337#undef MEMSUFFIX
338#endif
339
340#if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX)
341
342#define CPU_MMU_INDEX 10
343#define MEMSUFFIX MMU_MODE10_SUFFIX
344#define DATA_SIZE 1
345#include "exec/cpu_ldst_template.h"
346
347#define DATA_SIZE 2
348#include "exec/cpu_ldst_template.h"
349
350#define DATA_SIZE 4
351#include "exec/cpu_ldst_template.h"
352
353#define DATA_SIZE 8
354#include "exec/cpu_ldst_template.h"
355#undef CPU_MMU_INDEX
356#undef MEMSUFFIX
357#endif
358
359#if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX)
360
361#define CPU_MMU_INDEX 11
362#define MEMSUFFIX MMU_MODE11_SUFFIX
363#define DATA_SIZE 1
364#include "exec/cpu_ldst_template.h"
365
366#define DATA_SIZE 2
367#include "exec/cpu_ldst_template.h"
368
369#define DATA_SIZE 4
370#include "exec/cpu_ldst_template.h"
371
372#define DATA_SIZE 8
373#include "exec/cpu_ldst_template.h"
374#undef CPU_MMU_INDEX
375#undef MEMSUFFIX
376#endif
377
378#if (NB_MMU_MODES > 12)
379#error "NB_MMU_MODES > 12 is not supported for now"
380#endif
381
382
383#define CPU_MMU_INDEX (cpu_mmu_index(env, false))
384#define MEMSUFFIX _data
385#define DATA_SIZE 1
386#include "exec/cpu_ldst_template.h"
387
388#define DATA_SIZE 2
389#include "exec/cpu_ldst_template.h"
390
391#define DATA_SIZE 4
392#include "exec/cpu_ldst_template.h"
393
394#define DATA_SIZE 8
395#include "exec/cpu_ldst_template.h"
396#undef CPU_MMU_INDEX
397#undef MEMSUFFIX
398
399#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
400#define MEMSUFFIX _code
401#define SOFTMMU_CODE_ACCESS
402
403#define DATA_SIZE 1
404#include "exec/cpu_ldst_template.h"
405
406#define DATA_SIZE 2
407#include "exec/cpu_ldst_template.h"
408
409#define DATA_SIZE 4
410#include "exec/cpu_ldst_template.h"
411
412#define DATA_SIZE 8
413#include "exec/cpu_ldst_template.h"
414
415#undef CPU_MMU_INDEX
416#undef MEMSUFFIX
417#undef SOFTMMU_CODE_ACCESS
418
419#endif
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
437 int access_type, int mmu_idx)
438{
439#if defined(CONFIG_USER_ONLY)
440 return g2h(addr);
441#else
442 CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
443 abi_ptr tlb_addr;
444 uintptr_t haddr;
445
446 switch (access_type) {
447 case 0:
448 tlb_addr = tlbentry->addr_read;
449 break;
450 case 1:
451 tlb_addr = tlb_addr_write(tlbentry);
452 break;
453 case 2:
454 tlb_addr = tlbentry->addr_code;
455 break;
456 default:
457 g_assert_not_reached();
458 }
459
460 if (!tlb_hit(tlb_addr, addr)) {
461
462 return NULL;
463 }
464
465 if (tlb_addr & ~TARGET_PAGE_MASK) {
466
467 return NULL;
468 }
469
470 haddr = addr + tlbentry->addend;
471 return (void *)haddr;
472#endif
473}
474
475#endif
476