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
48
49
50
51
52
53
54
55
56
57#ifndef CPU_LDST_H
58#define CPU_LDST_H
59
60#if defined(CONFIG_USER_ONLY)
61
62
63
64#if TARGET_VIRT_ADDR_SPACE_BITS <= 32
65typedef uint32_t abi_ptr;
66#define TARGET_ABI_FMT_ptr "%x"
67#else
68typedef uint64_t abi_ptr;
69#define TARGET_ABI_FMT_ptr "%"PRIx64
70#endif
71
72
73#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
74
75#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
76#define guest_addr_valid(x) (1)
77#else
78#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
79#endif
80#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
81
82static inline int guest_range_valid(unsigned long start, unsigned long len)
83{
84 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
85}
86
87#define h2g_nocheck(x) ({ \
88 unsigned long __ret = (unsigned long)(x) - guest_base; \
89 (abi_ptr)__ret; \
90})
91
92#define h2g(x) ({ \
93 \
94 assert(h2g_valid(x)); \
95 h2g_nocheck(x); \
96})
97#else
98typedef target_ulong abi_ptr;
99#define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
100#endif
101
102uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr);
103int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr);
104
105uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr ptr);
106int cpu_ldsw_be_data(CPUArchState *env, abi_ptr ptr);
107uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr ptr);
108uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr ptr);
109
110uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr ptr);
111int cpu_ldsw_le_data(CPUArchState *env, abi_ptr ptr);
112uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr ptr);
113uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr ptr);
114
115uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
116int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
117
118uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
119int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
120uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
121uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
122
123uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
124int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
125uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
126uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
127
128void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
129
130void cpu_stw_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
131void cpu_stl_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
132void cpu_stq_be_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
133
134void cpu_stw_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
135void cpu_stl_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
136void cpu_stq_le_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
137
138void cpu_stb_data_ra(CPUArchState *env, abi_ptr ptr,
139 uint32_t val, uintptr_t ra);
140
141void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr ptr,
142 uint32_t val, uintptr_t ra);
143void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr ptr,
144 uint32_t val, uintptr_t ra);
145void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr ptr,
146 uint64_t val, uintptr_t ra);
147
148void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr ptr,
149 uint32_t val, uintptr_t ra);
150void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr ptr,
151 uint32_t val, uintptr_t ra);
152void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr ptr,
153 uint64_t val, uintptr_t ra);
154
155#if defined(CONFIG_USER_ONLY)
156
157extern __thread uintptr_t helper_retaddr;
158
159static inline void set_helper_retaddr(uintptr_t ra)
160{
161 helper_retaddr = ra;
162
163
164
165
166 signal_barrier();
167}
168
169static inline void clear_helper_retaddr(void)
170{
171
172
173
174
175 signal_barrier();
176 helper_retaddr = 0;
177}
178
179
180
181
182
183
184static inline uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
185 int mmu_idx, uintptr_t ra)
186{
187 return cpu_ldub_data_ra(env, addr, ra);
188}
189
190static inline int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
191 int mmu_idx, uintptr_t ra)
192{
193 return cpu_ldsb_data_ra(env, addr, ra);
194}
195
196static inline uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
197 int mmu_idx, uintptr_t ra)
198{
199 return cpu_lduw_be_data_ra(env, addr, ra);
200}
201
202static inline int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
203 int mmu_idx, uintptr_t ra)
204{
205 return cpu_ldsw_be_data_ra(env, addr, ra);
206}
207
208static inline uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
209 int mmu_idx, uintptr_t ra)
210{
211 return cpu_ldl_be_data_ra(env, addr, ra);
212}
213
214static inline uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
215 int mmu_idx, uintptr_t ra)
216{
217 return cpu_ldq_be_data_ra(env, addr, ra);
218}
219
220static inline uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
221 int mmu_idx, uintptr_t ra)
222{
223 return cpu_lduw_le_data_ra(env, addr, ra);
224}
225
226static inline int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
227 int mmu_idx, uintptr_t ra)
228{
229 return cpu_ldsw_le_data_ra(env, addr, ra);
230}
231
232static inline uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
233 int mmu_idx, uintptr_t ra)
234{
235 return cpu_ldl_le_data_ra(env, addr, ra);
236}
237
238static inline uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
239 int mmu_idx, uintptr_t ra)
240{
241 return cpu_ldq_le_data_ra(env, addr, ra);
242}
243
244static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
245 uint32_t val, int mmu_idx, uintptr_t ra)
246{
247 cpu_stb_data_ra(env, addr, val, ra);
248}
249
250static inline void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
251 uint32_t val, int mmu_idx,
252 uintptr_t ra)
253{
254 cpu_stw_be_data_ra(env, addr, val, ra);
255}
256
257static inline void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
258 uint32_t val, int mmu_idx,
259 uintptr_t ra)
260{
261 cpu_stl_be_data_ra(env, addr, val, ra);
262}
263
264static inline void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
265 uint64_t val, int mmu_idx,
266 uintptr_t ra)
267{
268 cpu_stq_be_data_ra(env, addr, val, ra);
269}
270
271static inline void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
272 uint32_t val, int mmu_idx,
273 uintptr_t ra)
274{
275 cpu_stw_le_data_ra(env, addr, val, ra);
276}
277
278static inline void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
279 uint32_t val, int mmu_idx,
280 uintptr_t ra)
281{
282 cpu_stl_le_data_ra(env, addr, val, ra);
283}
284
285static inline void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
286 uint64_t val, int mmu_idx,
287 uintptr_t ra)
288{
289 cpu_stq_le_data_ra(env, addr, val, ra);
290}
291
292#else
293
294
295#include "tcg/tcg.h"
296
297static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry)
298{
299#if TCG_OVERSIZED_GUEST
300 return entry->addr_write;
301#else
302 return atomic_read(&entry->addr_write);
303#endif
304}
305
306
307static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
308 target_ulong addr)
309{
310 uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS;
311
312 return (addr >> TARGET_PAGE_BITS) & size_mask;
313}
314
315
316static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
317 target_ulong addr)
318{
319 return &env_tlb(env)->f[mmu_idx].table[tlb_index(env, mmu_idx, addr)];
320}
321
322uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
323 int mmu_idx, uintptr_t ra);
324int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
325 int mmu_idx, uintptr_t ra);
326
327uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
328 int mmu_idx, uintptr_t ra);
329int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
330 int mmu_idx, uintptr_t ra);
331uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
332 int mmu_idx, uintptr_t ra);
333uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
334 int mmu_idx, uintptr_t ra);
335
336uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
337 int mmu_idx, uintptr_t ra);
338int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
339 int mmu_idx, uintptr_t ra);
340uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
341 int mmu_idx, uintptr_t ra);
342uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
343 int mmu_idx, uintptr_t ra);
344
345void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
346 int mmu_idx, uintptr_t retaddr);
347
348void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
349 int mmu_idx, uintptr_t retaddr);
350void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
351 int mmu_idx, uintptr_t retaddr);
352void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
353 int mmu_idx, uintptr_t retaddr);
354
355void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
356 int mmu_idx, uintptr_t retaddr);
357void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
358 int mmu_idx, uintptr_t retaddr);
359void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
360 int mmu_idx, uintptr_t retaddr);
361
362#endif
363
364#ifdef TARGET_WORDS_BIGENDIAN
365# define cpu_lduw_data cpu_lduw_be_data
366# define cpu_ldsw_data cpu_ldsw_be_data
367# define cpu_ldl_data cpu_ldl_be_data
368# define cpu_ldq_data cpu_ldq_be_data
369# define cpu_lduw_data_ra cpu_lduw_be_data_ra
370# define cpu_ldsw_data_ra cpu_ldsw_be_data_ra
371# define cpu_ldl_data_ra cpu_ldl_be_data_ra
372# define cpu_ldq_data_ra cpu_ldq_be_data_ra
373# define cpu_lduw_mmuidx_ra cpu_lduw_be_mmuidx_ra
374# define cpu_ldsw_mmuidx_ra cpu_ldsw_be_mmuidx_ra
375# define cpu_ldl_mmuidx_ra cpu_ldl_be_mmuidx_ra
376# define cpu_ldq_mmuidx_ra cpu_ldq_be_mmuidx_ra
377# define cpu_stw_data cpu_stw_be_data
378# define cpu_stl_data cpu_stl_be_data
379# define cpu_stq_data cpu_stq_be_data
380# define cpu_stw_data_ra cpu_stw_be_data_ra
381# define cpu_stl_data_ra cpu_stl_be_data_ra
382# define cpu_stq_data_ra cpu_stq_be_data_ra
383# define cpu_stw_mmuidx_ra cpu_stw_be_mmuidx_ra
384# define cpu_stl_mmuidx_ra cpu_stl_be_mmuidx_ra
385# define cpu_stq_mmuidx_ra cpu_stq_be_mmuidx_ra
386#else
387# define cpu_lduw_data cpu_lduw_le_data
388# define cpu_ldsw_data cpu_ldsw_le_data
389# define cpu_ldl_data cpu_ldl_le_data
390# define cpu_ldq_data cpu_ldq_le_data
391# define cpu_lduw_data_ra cpu_lduw_le_data_ra
392# define cpu_ldsw_data_ra cpu_ldsw_le_data_ra
393# define cpu_ldl_data_ra cpu_ldl_le_data_ra
394# define cpu_ldq_data_ra cpu_ldq_le_data_ra
395# define cpu_lduw_mmuidx_ra cpu_lduw_le_mmuidx_ra
396# define cpu_ldsw_mmuidx_ra cpu_ldsw_le_mmuidx_ra
397# define cpu_ldl_mmuidx_ra cpu_ldl_le_mmuidx_ra
398# define cpu_ldq_mmuidx_ra cpu_ldq_le_mmuidx_ra
399# define cpu_stw_data cpu_stw_le_data
400# define cpu_stl_data cpu_stl_le_data
401# define cpu_stq_data cpu_stq_le_data
402# define cpu_stw_data_ra cpu_stw_le_data_ra
403# define cpu_stl_data_ra cpu_stl_le_data_ra
404# define cpu_stq_data_ra cpu_stq_le_data_ra
405# define cpu_stw_mmuidx_ra cpu_stw_le_mmuidx_ra
406# define cpu_stl_mmuidx_ra cpu_stl_le_mmuidx_ra
407# define cpu_stq_mmuidx_ra cpu_stq_le_mmuidx_ra
408#endif
409
410uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr);
411uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr);
412uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr);
413uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr);
414
415static inline int cpu_ldsb_code(CPUArchState *env, abi_ptr addr)
416{
417 return (int8_t)cpu_ldub_code(env, addr);
418}
419
420static inline int cpu_ldsw_code(CPUArchState *env, abi_ptr addr)
421{
422 return (int16_t)cpu_lduw_code(env, addr);
423}
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438#ifdef CONFIG_USER_ONLY
439static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
440 MMUAccessType access_type, int mmu_idx)
441{
442 return g2h(addr);
443}
444#else
445void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
446 MMUAccessType access_type, int mmu_idx);
447#endif
448
449#endif
450