blob: 41ed0526e204a36c34917a21395751beba2c5521 [file] [log] [blame]
Paolo Bonzinif08b6172014-03-28 19:42:10 +01001/*
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 *
Peter Maydelldb5fd8d2015-01-20 15:19:35 +000026 * The syntax for the accessors is:
27 *
28 * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr)
29 *
30 * store: cpu_st{sign}{size}_{mmusuffix}(env, ptr, val)
31 *
32 * sign is:
33 * (empty): for 32 and 64 bit sizes
34 * u : unsigned
35 * s : signed
36 *
37 * size is:
38 * b: 8 bits
39 * w: 16 bits
40 * l: 32 bits
41 * q: 64 bits
42 *
43 * mmusuffix is one of the generic suffixes "data" or "code", or
44 * (for softmmu configs) a target-specific MMU mode suffix as defined
45 * in target cpu.h.
Paolo Bonzinif08b6172014-03-28 19:42:10 +010046 */
47#ifndef CPU_LDST_H
48#define CPU_LDST_H
49
Paolo Bonzinic7738282014-03-28 19:11:26 +010050#if defined(CONFIG_USER_ONLY)
Laurent Vivier3e23de12018-08-14 19:12:17 +020051/* sparc32plus has 64bit long but 32bit space address
52 * this can make bad result with g2h() and h2g()
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
Paolo Bonzinic7738282014-03-28 19:11:26 +010062/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
Laurent Vivier3e23de12018-08-14 19:12:17 +020063#define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base))
Paolo Bonzinic7738282014-03-28 19:11:26 +010064
Max Filippovebf9a362018-03-07 13:50:10 -080065#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}
Paolo Bonzinif08b6172014-03-28 19:42:10 +010072
Paolo Bonzinic7738282014-03-28 19:11:26 +010073#define h2g_nocheck(x) ({ \
Laurent Vivierb76f21a2015-08-24 14:53:54 +020074 unsigned long __ret = (unsigned long)(x) - guest_base; \
Laurent Vivier3e23de12018-08-14 19:12:17 +020075 (abi_ptr)__ret; \
Paolo Bonzinic7738282014-03-28 19:11:26 +010076})
77
78#define h2g(x) ({ \
79 /* Check if given address fits target address space */ \
80 assert(h2g_valid(x)); \
81 h2g_nocheck(x); \
82})
Laurent Vivier3e23de12018-08-14 19:12:17 +020083#else
84typedef target_ulong abi_ptr;
85#define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
Paolo Bonzinic7738282014-03-28 19:11:26 +010086#endif
87
Paolo Bonzinic7738282014-03-28 19:11:26 +010088#if defined(CONFIG_USER_ONLY)
89
Richard Hendersonec603b52017-11-14 10:34:20 +010090extern __thread uintptr_t helper_retaddr;
91
Peter Maydell9220fe52015-01-20 15:19:34 +000092/* In user-only mode we provide only the _code and _data accessors. */
Paolo Bonzinic7738282014-03-28 19:11:26 +010093
Peter Maydell9220fe52015-01-20 15:19:34 +000094#define MEMSUFFIX _data
95#define DATA_SIZE 1
96#include "exec/cpu_ldst_useronly_template.h"
Paolo Bonzinic7738282014-03-28 19:11:26 +010097
Peter Maydell9220fe52015-01-20 15:19:34 +000098#define DATA_SIZE 2
99#include "exec/cpu_ldst_useronly_template.h"
Paolo Bonzinic7738282014-03-28 19:11:26 +0100100
Peter Maydell9220fe52015-01-20 15:19:34 +0000101#define DATA_SIZE 4
102#include "exec/cpu_ldst_useronly_template.h"
Paolo Bonzinic7738282014-03-28 19:11:26 +0100103
Peter Maydell9220fe52015-01-20 15:19:34 +0000104#define DATA_SIZE 8
105#include "exec/cpu_ldst_useronly_template.h"
106#undef MEMSUFFIX
Paolo Bonzinic7738282014-03-28 19:11:26 +0100107
Peter Maydell9220fe52015-01-20 15:19:34 +0000108#define MEMSUFFIX _code
109#define CODE_ACCESS
110#define DATA_SIZE 1
111#include "exec/cpu_ldst_useronly_template.h"
Paolo Bonzinic7738282014-03-28 19:11:26 +0100112
Peter Maydell9220fe52015-01-20 15:19:34 +0000113#define DATA_SIZE 2
114#include "exec/cpu_ldst_useronly_template.h"
Paolo Bonzinic7738282014-03-28 19:11:26 +0100115
Peter Maydell9220fe52015-01-20 15:19:34 +0000116#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
Paolo Bonzinic7738282014-03-28 19:11:26 +0100123
124#else
125
Paolo Bonzinic7738282014-03-28 19:11:26 +0100126/* The memory helpers for tcg-generated code need tcg_target_long etc. */
127#include "tcg.h"
128
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000129#ifdef MMU_MODE0_SUFFIX
Paolo Bonzinic7738282014-03-28 19:11:26 +0100130#define CPU_MMU_INDEX 0
131#define MEMSUFFIX MMU_MODE0_SUFFIX
132#define DATA_SIZE 1
133#include "exec/cpu_ldst_template.h"
134
135#define DATA_SIZE 2
136#include "exec/cpu_ldst_template.h"
137
138#define DATA_SIZE 4
139#include "exec/cpu_ldst_template.h"
140
141#define DATA_SIZE 8
142#include "exec/cpu_ldst_template.h"
143#undef CPU_MMU_INDEX
144#undef MEMSUFFIX
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000145#endif
Paolo Bonzinic7738282014-03-28 19:11:26 +0100146
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000147#if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
Paolo Bonzinic7738282014-03-28 19:11:26 +0100148#define CPU_MMU_INDEX 1
149#define MEMSUFFIX MMU_MODE1_SUFFIX
150#define DATA_SIZE 1
151#include "exec/cpu_ldst_template.h"
152
153#define DATA_SIZE 2
154#include "exec/cpu_ldst_template.h"
155
156#define DATA_SIZE 4
157#include "exec/cpu_ldst_template.h"
158
159#define DATA_SIZE 8
160#include "exec/cpu_ldst_template.h"
161#undef CPU_MMU_INDEX
162#undef MEMSUFFIX
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000163#endif
Paolo Bonzinic7738282014-03-28 19:11:26 +0100164
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000165#if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX)
Paolo Bonzinic7738282014-03-28 19:11:26 +0100166
167#define CPU_MMU_INDEX 2
168#define MEMSUFFIX MMU_MODE2_SUFFIX
169#define DATA_SIZE 1
170#include "exec/cpu_ldst_template.h"
171
172#define DATA_SIZE 2
173#include "exec/cpu_ldst_template.h"
174
175#define DATA_SIZE 4
176#include "exec/cpu_ldst_template.h"
177
178#define DATA_SIZE 8
179#include "exec/cpu_ldst_template.h"
180#undef CPU_MMU_INDEX
181#undef MEMSUFFIX
182#endif /* (NB_MMU_MODES >= 3) */
183
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000184#if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
Paolo Bonzinic7738282014-03-28 19:11:26 +0100185
186#define CPU_MMU_INDEX 3
187#define MEMSUFFIX MMU_MODE3_SUFFIX
188#define DATA_SIZE 1
189#include "exec/cpu_ldst_template.h"
190
191#define DATA_SIZE 2
192#include "exec/cpu_ldst_template.h"
193
194#define DATA_SIZE 4
195#include "exec/cpu_ldst_template.h"
196
197#define DATA_SIZE 8
198#include "exec/cpu_ldst_template.h"
199#undef CPU_MMU_INDEX
200#undef MEMSUFFIX
201#endif /* (NB_MMU_MODES >= 4) */
202
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000203#if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
Paolo Bonzinic7738282014-03-28 19:11:26 +0100204
205#define CPU_MMU_INDEX 4
206#define MEMSUFFIX MMU_MODE4_SUFFIX
207#define DATA_SIZE 1
208#include "exec/cpu_ldst_template.h"
209
210#define DATA_SIZE 2
211#include "exec/cpu_ldst_template.h"
212
213#define DATA_SIZE 4
214#include "exec/cpu_ldst_template.h"
215
216#define DATA_SIZE 8
217#include "exec/cpu_ldst_template.h"
218#undef CPU_MMU_INDEX
219#undef MEMSUFFIX
220#endif /* (NB_MMU_MODES >= 5) */
221
Peter Maydellde5ee4a2015-01-20 15:19:35 +0000222#if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
Paolo Bonzinic7738282014-03-28 19:11:26 +0100223
224#define CPU_MMU_INDEX 5
225#define MEMSUFFIX MMU_MODE5_SUFFIX
226#define DATA_SIZE 1
227#include "exec/cpu_ldst_template.h"
228
229#define DATA_SIZE 2
230#include "exec/cpu_ldst_template.h"
231
232#define DATA_SIZE 4
233#include "exec/cpu_ldst_template.h"
234
235#define DATA_SIZE 8
236#include "exec/cpu_ldst_template.h"
237#undef CPU_MMU_INDEX
238#undef MEMSUFFIX
239#endif /* (NB_MMU_MODES >= 6) */
240
Peter Maydell8f3ae2a2015-02-05 13:37:23 +0000241#if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX)
242
243#define CPU_MMU_INDEX 6
244#define MEMSUFFIX MMU_MODE6_SUFFIX
245#define DATA_SIZE 1
246#include "exec/cpu_ldst_template.h"
247
248#define DATA_SIZE 2
249#include "exec/cpu_ldst_template.h"
250
251#define DATA_SIZE 4
252#include "exec/cpu_ldst_template.h"
253
254#define DATA_SIZE 8
255#include "exec/cpu_ldst_template.h"
256#undef CPU_MMU_INDEX
257#undef MEMSUFFIX
258#endif /* (NB_MMU_MODES >= 7) */
259
Paolo Bonzini1de29ae2015-05-05 09:18:23 +0200260#if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX)
261
262#define CPU_MMU_INDEX 7
263#define MEMSUFFIX MMU_MODE7_SUFFIX
264#define DATA_SIZE 1
265#include "exec/cpu_ldst_template.h"
266
267#define DATA_SIZE 2
268#include "exec/cpu_ldst_template.h"
269
270#define DATA_SIZE 4
271#include "exec/cpu_ldst_template.h"
272
273#define DATA_SIZE 8
274#include "exec/cpu_ldst_template.h"
275#undef CPU_MMU_INDEX
276#undef MEMSUFFIX
277#endif /* (NB_MMU_MODES >= 8) */
278
279#if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX)
280
281#define CPU_MMU_INDEX 8
282#define MEMSUFFIX MMU_MODE8_SUFFIX
283#define DATA_SIZE 1
284#include "exec/cpu_ldst_template.h"
285
286#define DATA_SIZE 2
287#include "exec/cpu_ldst_template.h"
288
289#define DATA_SIZE 4
290#include "exec/cpu_ldst_template.h"
291
292#define DATA_SIZE 8
293#include "exec/cpu_ldst_template.h"
294#undef CPU_MMU_INDEX
295#undef MEMSUFFIX
296#endif /* (NB_MMU_MODES >= 9) */
297
298#if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX)
299
300#define CPU_MMU_INDEX 9
301#define MEMSUFFIX MMU_MODE9_SUFFIX
302#define DATA_SIZE 1
303#include "exec/cpu_ldst_template.h"
304
305#define DATA_SIZE 2
306#include "exec/cpu_ldst_template.h"
307
308#define DATA_SIZE 4
309#include "exec/cpu_ldst_template.h"
310
311#define DATA_SIZE 8
312#include "exec/cpu_ldst_template.h"
313#undef CPU_MMU_INDEX
314#undef MEMSUFFIX
315#endif /* (NB_MMU_MODES >= 10) */
316
317#if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX)
318
319#define CPU_MMU_INDEX 10
320#define MEMSUFFIX MMU_MODE10_SUFFIX
321#define DATA_SIZE 1
322#include "exec/cpu_ldst_template.h"
323
324#define DATA_SIZE 2
325#include "exec/cpu_ldst_template.h"
326
327#define DATA_SIZE 4
328#include "exec/cpu_ldst_template.h"
329
330#define DATA_SIZE 8
331#include "exec/cpu_ldst_template.h"
332#undef CPU_MMU_INDEX
333#undef MEMSUFFIX
334#endif /* (NB_MMU_MODES >= 11) */
335
336#if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX)
337
338#define CPU_MMU_INDEX 11
339#define MEMSUFFIX MMU_MODE11_SUFFIX
340#define DATA_SIZE 1
341#include "exec/cpu_ldst_template.h"
342
343#define DATA_SIZE 2
344#include "exec/cpu_ldst_template.h"
345
346#define DATA_SIZE 4
347#include "exec/cpu_ldst_template.h"
348
349#define DATA_SIZE 8
350#include "exec/cpu_ldst_template.h"
351#undef CPU_MMU_INDEX
352#undef MEMSUFFIX
353#endif /* (NB_MMU_MODES >= 12) */
354
355#if (NB_MMU_MODES > 12)
356#error "NB_MMU_MODES > 12 is not supported for now"
357#endif /* (NB_MMU_MODES > 12) */
Paolo Bonzinic7738282014-03-28 19:11:26 +0100358
359/* these access are slower, they must be as rare as possible */
Benjamin Herrenschmidt97ed5cc2015-08-17 17:34:10 +1000360#define CPU_MMU_INDEX (cpu_mmu_index(env, false))
Paolo Bonzinic7738282014-03-28 19:11:26 +0100361#define MEMSUFFIX _data
362#define DATA_SIZE 1
363#include "exec/cpu_ldst_template.h"
364
365#define DATA_SIZE 2
366#include "exec/cpu_ldst_template.h"
367
368#define DATA_SIZE 4
369#include "exec/cpu_ldst_template.h"
370
371#define DATA_SIZE 8
372#include "exec/cpu_ldst_template.h"
373#undef CPU_MMU_INDEX
374#undef MEMSUFFIX
375
Benjamin Herrenschmidt97ed5cc2015-08-17 17:34:10 +1000376#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
Paolo Bonzinic7738282014-03-28 19:11:26 +0100377#define MEMSUFFIX _code
378#define SOFTMMU_CODE_ACCESS
379
380#define DATA_SIZE 1
381#include "exec/cpu_ldst_template.h"
382
383#define DATA_SIZE 2
384#include "exec/cpu_ldst_template.h"
385
386#define DATA_SIZE 4
387#include "exec/cpu_ldst_template.h"
388
389#define DATA_SIZE 8
390#include "exec/cpu_ldst_template.h"
391
392#undef CPU_MMU_INDEX
393#undef MEMSUFFIX
394#undef SOFTMMU_CODE_ACCESS
395
Aurelien Jarno2e83c492015-06-13 00:45:49 +0200396#endif /* defined(CONFIG_USER_ONLY) */
397
Paolo Bonzinic7738282014-03-28 19:11:26 +0100398/**
399 * tlb_vaddr_to_host:
400 * @env: CPUArchState
401 * @addr: guest virtual address to look up
402 * @access_type: 0 for read, 1 for write, 2 for execute
403 * @mmu_idx: MMU index to use for lookup
404 *
405 * Look up the specified guest virtual index in the TCG softmmu TLB.
406 * If the TLB contains a host virtual address suitable for direct RAM
407 * access, then return it. Otherwise (TLB miss, TLB entry is for an
408 * I/O access, etc) return NULL.
409 *
410 * This is the equivalent of the initial fast-path code used by
411 * TCG backends for guest load and store accesses.
412 */
Laurent Vivier3e23de12018-08-14 19:12:17 +0200413static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
Paolo Bonzinic7738282014-03-28 19:11:26 +0100414 int access_type, int mmu_idx)
415{
Aurelien Jarno2e83c492015-06-13 00:45:49 +0200416#if defined(CONFIG_USER_ONLY)
Bobby Binghamc2a85312016-11-12 23:05:23 -0600417 return g2h(addr);
Aurelien Jarno2e83c492015-06-13 00:45:49 +0200418#else
Paolo Bonzinic7738282014-03-28 19:11:26 +0100419 int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
420 CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
Laurent Vivier3e23de12018-08-14 19:12:17 +0200421 abi_ptr tlb_addr;
Paolo Bonzinic7738282014-03-28 19:11:26 +0100422 uintptr_t haddr;
423
424 switch (access_type) {
425 case 0:
426 tlb_addr = tlbentry->addr_read;
427 break;
428 case 1:
429 tlb_addr = tlbentry->addr_write;
430 break;
431 case 2:
432 tlb_addr = tlbentry->addr_code;
433 break;
434 default:
435 g_assert_not_reached();
436 }
437
Peter Maydell334692b2018-06-29 17:21:21 +0100438 if (!tlb_hit(tlb_addr, addr)) {
Paolo Bonzinic7738282014-03-28 19:11:26 +0100439 /* TLB entry is for a different page */
440 return NULL;
441 }
442
443 if (tlb_addr & ~TARGET_PAGE_MASK) {
444 /* IO access */
445 return NULL;
446 }
447
448 haddr = addr + env->tlb_table[mmu_idx][index].addend;
449 return (void *)haddr;
Paolo Bonzinic7738282014-03-28 19:11:26 +0100450#endif /* defined(CONFIG_USER_ONLY) */
Aurelien Jarno2e83c492015-06-13 00:45:49 +0200451}
Paolo Bonzinic7738282014-03-28 19:11:26 +0100452
Paolo Bonzinif08b6172014-03-28 19:42:10 +0100453#endif /* CPU_LDST_H */