xref: /openbmc/qemu/include/exec/cpu_ldst.h (revision ed4cfbcd)
1 /*
2  *  Software MMU support
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 /*
20  * Generate inline load/store functions for all MMU modes (typically
21  * at least _user and _kernel) as well as _data versions, for all data
22  * sizes.
23  *
24  * Used by target op helpers.
25  *
26  * The syntax for the accessors is:
27  *
28  * load:  cpu_ld{sign}{size}_{mmusuffix}(env, ptr)
29  *        cpu_ld{sign}{size}_{mmusuffix}_ra(env, ptr, retaddr)
30  *        cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmu_idx, retaddr)
31  *
32  * store: cpu_st{size}_{mmusuffix}(env, ptr, val)
33  *        cpu_st{size}_{mmusuffix}_ra(env, ptr, val, retaddr)
34  *        cpu_st{size}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)
35  *
36  * sign is:
37  * (empty): for 32 and 64 bit sizes
38  *   u    : unsigned
39  *   s    : signed
40  *
41  * size is:
42  *   b: 8 bits
43  *   w: 16 bits
44  *   l: 32 bits
45  *   q: 64 bits
46  *
47  * mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx".
48  * The "mmuidx" suffix carries an extra mmu_idx argument that specifies
49  * the index to use; the "data" and "code" suffixes take the index from
50  * cpu_mmu_index().
51  */
52 #ifndef CPU_LDST_H
53 #define CPU_LDST_H
54 
55 #if defined(CONFIG_USER_ONLY)
56 /* sparc32plus has 64bit long but 32bit space address
57  * this can make bad result with g2h() and h2g()
58  */
59 #if TARGET_VIRT_ADDR_SPACE_BITS <= 32
60 typedef uint32_t abi_ptr;
61 #define TARGET_ABI_FMT_ptr "%x"
62 #else
63 typedef uint64_t abi_ptr;
64 #define TARGET_ABI_FMT_ptr "%"PRIx64
65 #endif
66 
67 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
68 #define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
69 
70 #if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
71 #define guest_addr_valid(x) (1)
72 #else
73 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
74 #endif
75 #define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
76 
77 static inline int guest_range_valid(unsigned long start, unsigned long len)
78 {
79     return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
80 }
81 
82 #define h2g_nocheck(x) ({ \
83     unsigned long __ret = (unsigned long)(x) - guest_base; \
84     (abi_ptr)__ret; \
85 })
86 
87 #define h2g(x) ({ \
88     /* Check if given address fits target address space */ \
89     assert(h2g_valid(x)); \
90     h2g_nocheck(x); \
91 })
92 #else
93 typedef target_ulong abi_ptr;
94 #define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
95 #endif
96 
97 #if defined(CONFIG_USER_ONLY)
98 
99 extern __thread uintptr_t helper_retaddr;
100 
101 static inline void set_helper_retaddr(uintptr_t ra)
102 {
103     helper_retaddr = ra;
104     /*
105      * Ensure that this write is visible to the SIGSEGV handler that
106      * may be invoked due to a subsequent invalid memory operation.
107      */
108     signal_barrier();
109 }
110 
111 static inline void clear_helper_retaddr(void)
112 {
113     /*
114      * Ensure that previous memory operations have succeeded before
115      * removing the data visible to the signal handler.
116      */
117     signal_barrier();
118     helper_retaddr = 0;
119 }
120 
121 /* In user-only mode we provide only the _code and _data accessors. */
122 
123 uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr);
124 uint32_t cpu_lduw_data(CPUArchState *env, abi_ptr ptr);
125 uint32_t cpu_ldl_data(CPUArchState *env, abi_ptr ptr);
126 uint64_t cpu_ldq_data(CPUArchState *env, abi_ptr ptr);
127 int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr);
128 int cpu_ldsw_data(CPUArchState *env, abi_ptr ptr);
129 
130 uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
131 uint32_t cpu_lduw_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
132 uint32_t cpu_ldl_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
133 uint64_t cpu_ldq_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
134 int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
135 int cpu_ldsw_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
136 
137 void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
138 void cpu_stw_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
139 void cpu_stl_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
140 void cpu_stq_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
141 
142 void cpu_stb_data_ra(CPUArchState *env, abi_ptr ptr,
143                      uint32_t val, uintptr_t retaddr);
144 void cpu_stw_data_ra(CPUArchState *env, abi_ptr ptr,
145                      uint32_t val, uintptr_t retaddr);
146 void cpu_stl_data_ra(CPUArchState *env, abi_ptr ptr,
147                      uint32_t val, uintptr_t retaddr);
148 void cpu_stq_data_ra(CPUArchState *env, abi_ptr ptr,
149                      uint64_t val, uintptr_t retaddr);
150 
151 /*
152  * Provide the same *_mmuidx_ra interface as for softmmu.
153  * The mmu_idx argument is ignored.
154  */
155 
156 static inline uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
157                                           int mmu_idx, uintptr_t ra)
158 {
159     return cpu_ldub_data_ra(env, addr, ra);
160 }
161 
162 static inline uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
163                                           int mmu_idx, uintptr_t ra)
164 {
165     return cpu_lduw_data_ra(env, addr, ra);
166 }
167 
168 static inline uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
169                                          int mmu_idx, uintptr_t ra)
170 {
171     return cpu_ldl_data_ra(env, addr, ra);
172 }
173 
174 static inline uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
175                                          int mmu_idx, uintptr_t ra)
176 {
177     return cpu_ldq_data_ra(env, addr, ra);
178 }
179 
180 static inline int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
181                                      int mmu_idx, uintptr_t ra)
182 {
183     return cpu_ldsb_data_ra(env, addr, ra);
184 }
185 
186 static inline int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
187                                      int mmu_idx, uintptr_t ra)
188 {
189     return cpu_ldsw_data_ra(env, addr, ra);
190 }
191 
192 static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
193                                      uint32_t val, int mmu_idx, uintptr_t ra)
194 {
195     cpu_stb_data_ra(env, addr, val, ra);
196 }
197 
198 static inline void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
199                                      uint32_t val, int mmu_idx, uintptr_t ra)
200 {
201     cpu_stw_data_ra(env, addr, val, ra);
202 }
203 
204 static inline void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
205                                      uint32_t val, int mmu_idx, uintptr_t ra)
206 {
207     cpu_stl_data_ra(env, addr, val, ra);
208 }
209 
210 static inline void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
211                                      uint64_t val, int mmu_idx, uintptr_t ra)
212 {
213     cpu_stq_data_ra(env, addr, val, ra);
214 }
215 
216 #else
217 
218 /* Needed for TCG_OVERSIZED_GUEST */
219 #include "tcg.h"
220 
221 static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry)
222 {
223 #if TCG_OVERSIZED_GUEST
224     return entry->addr_write;
225 #else
226     return atomic_read(&entry->addr_write);
227 #endif
228 }
229 
230 /* Find the TLB index corresponding to the mmu_idx + address pair.  */
231 static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
232                                   target_ulong addr)
233 {
234     uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS;
235 
236     return (addr >> TARGET_PAGE_BITS) & size_mask;
237 }
238 
239 static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx)
240 {
241     return (env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS) + 1;
242 }
243 
244 /* Find the TLB entry corresponding to the mmu_idx + address pair.  */
245 static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
246                                      target_ulong addr)
247 {
248     return &env_tlb(env)->f[mmu_idx].table[tlb_index(env, mmu_idx, addr)];
249 }
250 
251 uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
252                             int mmu_idx, uintptr_t ra);
253 uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
254                             int mmu_idx, uintptr_t ra);
255 uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
256                            int mmu_idx, uintptr_t ra);
257 uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
258                            int mmu_idx, uintptr_t ra);
259 
260 int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
261                        int mmu_idx, uintptr_t ra);
262 int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
263                        int mmu_idx, uintptr_t ra);
264 
265 void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
266                        int mmu_idx, uintptr_t retaddr);
267 void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
268                        int mmu_idx, uintptr_t retaddr);
269 void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
270                        int mmu_idx, uintptr_t retaddr);
271 void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
272                        int mmu_idx, uintptr_t retaddr);
273 
274 #ifdef MMU_MODE0_SUFFIX
275 #define CPU_MMU_INDEX 0
276 #define MEMSUFFIX MMU_MODE0_SUFFIX
277 #define DATA_SIZE 1
278 #include "exec/cpu_ldst_template.h"
279 
280 #define DATA_SIZE 2
281 #include "exec/cpu_ldst_template.h"
282 
283 #define DATA_SIZE 4
284 #include "exec/cpu_ldst_template.h"
285 
286 #define DATA_SIZE 8
287 #include "exec/cpu_ldst_template.h"
288 #undef CPU_MMU_INDEX
289 #undef MEMSUFFIX
290 #endif
291 
292 #if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
293 #define CPU_MMU_INDEX 1
294 #define MEMSUFFIX MMU_MODE1_SUFFIX
295 #define DATA_SIZE 1
296 #include "exec/cpu_ldst_template.h"
297 
298 #define DATA_SIZE 2
299 #include "exec/cpu_ldst_template.h"
300 
301 #define DATA_SIZE 4
302 #include "exec/cpu_ldst_template.h"
303 
304 #define DATA_SIZE 8
305 #include "exec/cpu_ldst_template.h"
306 #undef CPU_MMU_INDEX
307 #undef MEMSUFFIX
308 #endif
309 
310 #if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX)
311 
312 #define CPU_MMU_INDEX 2
313 #define MEMSUFFIX MMU_MODE2_SUFFIX
314 #define DATA_SIZE 1
315 #include "exec/cpu_ldst_template.h"
316 
317 #define DATA_SIZE 2
318 #include "exec/cpu_ldst_template.h"
319 
320 #define DATA_SIZE 4
321 #include "exec/cpu_ldst_template.h"
322 
323 #define DATA_SIZE 8
324 #include "exec/cpu_ldst_template.h"
325 #undef CPU_MMU_INDEX
326 #undef MEMSUFFIX
327 #endif /* (NB_MMU_MODES >= 3) */
328 
329 #if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
330 
331 #define CPU_MMU_INDEX 3
332 #define MEMSUFFIX MMU_MODE3_SUFFIX
333 #define DATA_SIZE 1
334 #include "exec/cpu_ldst_template.h"
335 
336 #define DATA_SIZE 2
337 #include "exec/cpu_ldst_template.h"
338 
339 #define DATA_SIZE 4
340 #include "exec/cpu_ldst_template.h"
341 
342 #define DATA_SIZE 8
343 #include "exec/cpu_ldst_template.h"
344 #undef CPU_MMU_INDEX
345 #undef MEMSUFFIX
346 #endif /* (NB_MMU_MODES >= 4) */
347 
348 #if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
349 
350 #define CPU_MMU_INDEX 4
351 #define MEMSUFFIX MMU_MODE4_SUFFIX
352 #define DATA_SIZE 1
353 #include "exec/cpu_ldst_template.h"
354 
355 #define DATA_SIZE 2
356 #include "exec/cpu_ldst_template.h"
357 
358 #define DATA_SIZE 4
359 #include "exec/cpu_ldst_template.h"
360 
361 #define DATA_SIZE 8
362 #include "exec/cpu_ldst_template.h"
363 #undef CPU_MMU_INDEX
364 #undef MEMSUFFIX
365 #endif /* (NB_MMU_MODES >= 5) */
366 
367 #if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
368 
369 #define CPU_MMU_INDEX 5
370 #define MEMSUFFIX MMU_MODE5_SUFFIX
371 #define DATA_SIZE 1
372 #include "exec/cpu_ldst_template.h"
373 
374 #define DATA_SIZE 2
375 #include "exec/cpu_ldst_template.h"
376 
377 #define DATA_SIZE 4
378 #include "exec/cpu_ldst_template.h"
379 
380 #define DATA_SIZE 8
381 #include "exec/cpu_ldst_template.h"
382 #undef CPU_MMU_INDEX
383 #undef MEMSUFFIX
384 #endif /* (NB_MMU_MODES >= 6) */
385 
386 #if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX)
387 
388 #define CPU_MMU_INDEX 6
389 #define MEMSUFFIX MMU_MODE6_SUFFIX
390 #define DATA_SIZE 1
391 #include "exec/cpu_ldst_template.h"
392 
393 #define DATA_SIZE 2
394 #include "exec/cpu_ldst_template.h"
395 
396 #define DATA_SIZE 4
397 #include "exec/cpu_ldst_template.h"
398 
399 #define DATA_SIZE 8
400 #include "exec/cpu_ldst_template.h"
401 #undef CPU_MMU_INDEX
402 #undef MEMSUFFIX
403 #endif /* (NB_MMU_MODES >= 7) */
404 
405 #if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX)
406 
407 #define CPU_MMU_INDEX 7
408 #define MEMSUFFIX MMU_MODE7_SUFFIX
409 #define DATA_SIZE 1
410 #include "exec/cpu_ldst_template.h"
411 
412 #define DATA_SIZE 2
413 #include "exec/cpu_ldst_template.h"
414 
415 #define DATA_SIZE 4
416 #include "exec/cpu_ldst_template.h"
417 
418 #define DATA_SIZE 8
419 #include "exec/cpu_ldst_template.h"
420 #undef CPU_MMU_INDEX
421 #undef MEMSUFFIX
422 #endif /* (NB_MMU_MODES >= 8) */
423 
424 #if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX)
425 
426 #define CPU_MMU_INDEX 8
427 #define MEMSUFFIX MMU_MODE8_SUFFIX
428 #define DATA_SIZE 1
429 #include "exec/cpu_ldst_template.h"
430 
431 #define DATA_SIZE 2
432 #include "exec/cpu_ldst_template.h"
433 
434 #define DATA_SIZE 4
435 #include "exec/cpu_ldst_template.h"
436 
437 #define DATA_SIZE 8
438 #include "exec/cpu_ldst_template.h"
439 #undef CPU_MMU_INDEX
440 #undef MEMSUFFIX
441 #endif /* (NB_MMU_MODES >= 9) */
442 
443 #if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX)
444 
445 #define CPU_MMU_INDEX 9
446 #define MEMSUFFIX MMU_MODE9_SUFFIX
447 #define DATA_SIZE 1
448 #include "exec/cpu_ldst_template.h"
449 
450 #define DATA_SIZE 2
451 #include "exec/cpu_ldst_template.h"
452 
453 #define DATA_SIZE 4
454 #include "exec/cpu_ldst_template.h"
455 
456 #define DATA_SIZE 8
457 #include "exec/cpu_ldst_template.h"
458 #undef CPU_MMU_INDEX
459 #undef MEMSUFFIX
460 #endif /* (NB_MMU_MODES >= 10) */
461 
462 #if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX)
463 
464 #define CPU_MMU_INDEX 10
465 #define MEMSUFFIX MMU_MODE10_SUFFIX
466 #define DATA_SIZE 1
467 #include "exec/cpu_ldst_template.h"
468 
469 #define DATA_SIZE 2
470 #include "exec/cpu_ldst_template.h"
471 
472 #define DATA_SIZE 4
473 #include "exec/cpu_ldst_template.h"
474 
475 #define DATA_SIZE 8
476 #include "exec/cpu_ldst_template.h"
477 #undef CPU_MMU_INDEX
478 #undef MEMSUFFIX
479 #endif /* (NB_MMU_MODES >= 11) */
480 
481 #if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX)
482 
483 #define CPU_MMU_INDEX 11
484 #define MEMSUFFIX MMU_MODE11_SUFFIX
485 #define DATA_SIZE 1
486 #include "exec/cpu_ldst_template.h"
487 
488 #define DATA_SIZE 2
489 #include "exec/cpu_ldst_template.h"
490 
491 #define DATA_SIZE 4
492 #include "exec/cpu_ldst_template.h"
493 
494 #define DATA_SIZE 8
495 #include "exec/cpu_ldst_template.h"
496 #undef CPU_MMU_INDEX
497 #undef MEMSUFFIX
498 #endif /* (NB_MMU_MODES >= 12) */
499 
500 #if (NB_MMU_MODES > 12)
501 #error "NB_MMU_MODES > 12 is not supported for now"
502 #endif /* (NB_MMU_MODES > 12) */
503 
504 /* these access are slower, they must be as rare as possible */
505 #define CPU_MMU_INDEX (cpu_mmu_index(env, false))
506 #define MEMSUFFIX _data
507 #define DATA_SIZE 1
508 #include "exec/cpu_ldst_template.h"
509 
510 #define DATA_SIZE 2
511 #include "exec/cpu_ldst_template.h"
512 
513 #define DATA_SIZE 4
514 #include "exec/cpu_ldst_template.h"
515 
516 #define DATA_SIZE 8
517 #include "exec/cpu_ldst_template.h"
518 #undef CPU_MMU_INDEX
519 #undef MEMSUFFIX
520 
521 #endif /* defined(CONFIG_USER_ONLY) */
522 
523 uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr);
524 uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr);
525 uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr);
526 uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr);
527 
528 static inline int cpu_ldsb_code(CPUArchState *env, abi_ptr addr)
529 {
530     return (int8_t)cpu_ldub_code(env, addr);
531 }
532 
533 static inline int cpu_ldsw_code(CPUArchState *env, abi_ptr addr)
534 {
535     return (int16_t)cpu_lduw_code(env, addr);
536 }
537 
538 /**
539  * tlb_vaddr_to_host:
540  * @env: CPUArchState
541  * @addr: guest virtual address to look up
542  * @access_type: 0 for read, 1 for write, 2 for execute
543  * @mmu_idx: MMU index to use for lookup
544  *
545  * Look up the specified guest virtual index in the TCG softmmu TLB.
546  * If we can translate a host virtual address suitable for direct RAM
547  * access, without causing a guest exception, then return it.
548  * Otherwise (TLB entry is for an I/O access, guest software
549  * TLB fill required, etc) return NULL.
550  */
551 #ifdef CONFIG_USER_ONLY
552 static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
553                                       MMUAccessType access_type, int mmu_idx)
554 {
555     return g2h(addr);
556 }
557 #else
558 void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
559                         MMUAccessType access_type, int mmu_idx);
560 #endif
561 
562 #endif /* CPU_LDST_H */
563