70
65
#define QT1 (env->qt1)
72
67
#if !defined(CONFIG_USER_ONLY)
73
static void do_unassigned_access(target_phys_addr_t addr, int is_write,
74
int is_exec, int is_asi, int size);
77
static void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
78
int is_asi, int size);
68
#include "softmmu_exec.h"
69
#define MMUSUFFIX _mmu
73
#include "softmmu_template.h"
76
#include "softmmu_template.h"
79
#include "softmmu_template.h"
82
#include "softmmu_template.h"
82
85
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
451
457
case 0x08: /* Leon3 Instruction Cache config */
452
458
case 0x0C: /* Leon3 Date Cache config */
453
459
if (env->def->features & CPU_FEATURE_CACHE_CTRL) {
454
ret = leon3_cache_control_ld(addr, size);
460
ret = leon3_cache_control_ld(env, addr, size);
457
463
case 0x01c00a00: /* MXCC control register */
459
465
ret = env->mxccregs[3];
461
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
467
qemu_log_mask(LOG_UNIMP,
468
"%08x: unimplemented access size: %d\n", addr,
465
472
case 0x01c00a04: /* MXCC control register */
467
474
ret = env->mxccregs[3];
469
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
476
qemu_log_mask(LOG_UNIMP,
477
"%08x: unimplemented access size: %d\n", addr,
473
481
case 0x01c00c00: /* Module reset register */
475
483
ret = env->mxccregs[5];
476
484
/* should we do something here? */
478
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
486
qemu_log_mask(LOG_UNIMP,
487
"%08x: unimplemented access size: %d\n", addr,
482
491
case 0x01c00f00: /* MBus port address register */
484
493
ret = env->mxccregs[7];
486
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
495
qemu_log_mask(LOG_UNIMP,
496
"%08x: unimplemented access size: %d\n", addr,
491
DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
501
qemu_log_mask(LOG_UNIMP,
502
"%08x: unimplemented address, size: %d\n", addr,
495
506
DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
535
546
case 9: /* Supervisor code access */
538
ret = ldub_code(addr);
549
ret = cpu_ldub_code(env, addr);
541
ret = lduw_code(addr);
552
ret = cpu_lduw_code(env, addr);
545
ret = ldl_code(addr);
556
ret = cpu_ldl_code(env, addr);
548
ret = ldq_code(addr);
559
ret = cpu_ldq_code(env, addr);
552
563
case 0xa: /* User data access */
555
ret = ldub_user(addr);
566
ret = cpu_ldub_user(env, addr);
558
ret = lduw_user(addr);
569
ret = cpu_lduw_user(env, addr);
562
ret = ldl_user(addr);
573
ret = cpu_ldl_user(env, addr);
565
ret = ldq_user(addr);
576
ret = cpu_ldq_user(env, addr);
569
580
case 0xb: /* Supervisor data access */
572
ret = ldub_kernel(addr);
583
ret = cpu_ldub_kernel(env, addr);
575
ret = lduw_kernel(addr);
586
ret = cpu_lduw_kernel(env, addr);
579
ret = ldl_kernel(addr);
590
ret = cpu_ldl_kernel(env, addr);
582
ret = ldq_kernel(addr);
593
ret = cpu_ldq_kernel(env, addr);
713
725
env->mxccdata[0] = val;
715
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
727
qemu_log_mask(LOG_UNIMP,
728
"%08x: unimplemented access size: %d\n", addr,
719
732
case 0x01c00008: /* MXCC stream data register 1 */
721
734
env->mxccdata[1] = val;
723
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
736
qemu_log_mask(LOG_UNIMP,
737
"%08x: unimplemented access size: %d\n", addr,
727
741
case 0x01c00010: /* MXCC stream data register 2 */
729
743
env->mxccdata[2] = val;
731
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
745
qemu_log_mask(LOG_UNIMP,
746
"%08x: unimplemented access size: %d\n", addr,
735
750
case 0x01c00018: /* MXCC stream data register 3 */
737
752
env->mxccdata[3] = val;
739
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
754
qemu_log_mask(LOG_UNIMP,
755
"%08x: unimplemented access size: %d\n", addr,
743
759
case 0x01c00100: /* MXCC stream source */
745
761
env->mxccregs[0] = val;
747
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
763
qemu_log_mask(LOG_UNIMP,
764
"%08x: unimplemented access size: %d\n", addr,
750
767
env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
795
815
env->mxccregs[6] &= ~val;
797
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
817
qemu_log_mask(LOG_UNIMP,
818
"%08x: unimplemented access size: %d\n", addr,
801
822
case 0x01c00f00: /* MBus port address register */
803
824
env->mxccregs[7] = val;
805
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
826
qemu_log_mask(LOG_UNIMP,
827
"%08x: unimplemented access size: %d\n", addr,
810
DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
832
qemu_log_mask(LOG_UNIMP,
833
"%08x: unimplemented address, size: %d\n", addr,
814
837
DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
902
925
case 0xa: /* User data access */
928
cpu_stb_user(env, addr, val);
931
cpu_stw_user(env, addr, val);
935
cpu_stl_user(env, addr, val);
938
cpu_stq_user(env, addr, val);
919
942
case 0xb: /* Supervisor data access */
922
stb_kernel(addr, val);
945
cpu_stb_kernel(env, addr, val);
925
stw_kernel(addr, val);
948
cpu_stw_kernel(env, addr, val);
929
stl_kernel(addr, val);
952
cpu_stl_kernel(env, addr, val);
932
stq_kernel(addr, val);
955
cpu_stq_kernel(env, addr, val);
1238
1263
case 0x8a: /* Primary no-fault LE, RO */
1239
1264
case 0x8b: /* Secondary no-fault LE, RO */
1241
do_unassigned_access(addr, 1, 0, 1, size);
1266
helper_raise_exception(env, TT_DATA_ACCESS);
1246
1271
#else /* CONFIG_USER_ONLY */
1248
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1273
uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1250
1276
uint64_t ret = 0;
1251
1277
#if defined(DEBUG_ASI)
1321
1347
switch (size) {
1323
ret = ldub_kernel_secondary(addr);
1349
ret = cpu_ldub_kernel_secondary(env, addr);
1326
ret = lduw_kernel_secondary(addr);
1352
ret = cpu_lduw_kernel_secondary(env, addr);
1329
ret = ldl_kernel_secondary(addr);
1355
ret = cpu_ldl_kernel_secondary(env, addr);
1333
ret = ldq_kernel_secondary(addr);
1359
ret = cpu_ldq_kernel_secondary(env, addr);
1337
1363
switch (size) {
1339
ret = ldub_kernel(addr);
1365
ret = cpu_ldub_kernel(env, addr);
1342
ret = lduw_kernel(addr);
1368
ret = cpu_lduw_kernel(env, addr);
1345
ret = ldl_kernel(addr);
1371
ret = cpu_ldl_kernel(env, addr);
1349
ret = ldq_kernel(addr);
1375
ret = cpu_ldq_kernel(env, addr);
1357
1383
switch (size) {
1359
ret = ldub_user_secondary(addr);
1385
ret = cpu_ldub_user_secondary(env, addr);
1362
ret = lduw_user_secondary(addr);
1388
ret = cpu_lduw_user_secondary(env, addr);
1365
ret = ldl_user_secondary(addr);
1391
ret = cpu_ldl_user_secondary(env, addr);
1369
ret = ldq_user_secondary(addr);
1395
ret = cpu_ldq_user_secondary(env, addr);
1373
1399
switch (size) {
1375
ret = ldub_user(addr);
1401
ret = cpu_ldub_user(env, addr);
1378
ret = lduw_user(addr);
1404
ret = cpu_lduw_user(env, addr);
1381
ret = ldl_user(addr);
1407
ret = cpu_ldl_user(env, addr);
1385
ret = ldq_user(addr);
1411
ret = cpu_ldq_user(env, addr);
1540
1579
case 0x7e: /* E-cache tag */
1542
1581
case 0x5b: /* D-MMU data pointer */
1543
case 0x48: /* Interrupt dispatch, RO */
1544
case 0x49: /* Interrupt data receive */
1545
case 0x7f: /* Incoming interrupt vector, RO */
1548
1582
case 0x54: /* I-MMU data in, WO */
1549
1583
case 0x57: /* I-MMU demap, WO */
1550
1584
case 0x5c: /* D-MMU data in, WO */
1551
1585
case 0x5f: /* D-MMU demap, WO */
1552
1586
case 0x77: /* Interrupt vector, WO */
1554
do_unassigned_access(addr, 0, 0, 1, size);
1588
cpu_unassigned_access(env, addr, 0, 0, 1, size);
1682
1717
switch (size) {
1684
stb_kernel_secondary(addr, val);
1719
cpu_stb_kernel_secondary(env, addr, val);
1687
stw_kernel_secondary(addr, val);
1722
cpu_stw_kernel_secondary(env, addr, val);
1690
stl_kernel_secondary(addr, val);
1725
cpu_stl_kernel_secondary(env, addr, val);
1694
stq_kernel_secondary(addr, val);
1729
cpu_stq_kernel_secondary(env, addr, val);
1698
1733
switch (size) {
1700
stb_kernel(addr, val);
1735
cpu_stb_kernel(env, addr, val);
1703
stw_kernel(addr, val);
1738
cpu_stw_kernel(env, addr, val);
1706
stl_kernel(addr, val);
1741
cpu_stl_kernel(env, addr, val);
1710
stq_kernel(addr, val);
1745
cpu_stq_kernel(env, addr, val);
1718
1753
switch (size) {
1720
stb_user_secondary(addr, val);
1755
cpu_stb_user_secondary(env, addr, val);
1723
stw_user_secondary(addr, val);
1758
cpu_stw_user_secondary(env, addr, val);
1726
stl_user_secondary(addr, val);
1761
cpu_stl_user_secondary(env, addr, val);
1730
stq_user_secondary(addr, val);
1765
cpu_stq_user_secondary(env, addr, val);
1734
1769
switch (size) {
1736
stb_user(addr, val);
1771
cpu_stb_user(env, addr, val);
1739
stw_user(addr, val);
1774
cpu_stw_user(env, addr, val);
1742
stl_user(addr, val);
1777
cpu_stl_user(env, addr, val);
1746
stq_user(addr, val);
1781
cpu_stq_user(env, addr, val);
1983
2018
case 0x8a: /* Primary no-fault LE, RO */
1984
2019
case 0x8b: /* Secondary no-fault LE, RO */
1986
do_unassigned_access(addr, 1, 0, 1, size);
2021
cpu_unassigned_access(env, addr, 1, 0, 1, size);
1990
2025
#endif /* CONFIG_USER_ONLY */
1992
void helper_ldda_asi(target_ulong addr, int asi, int rd)
2027
void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
1994
2029
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1995
2030
|| (cpu_has_hypervisor(env)
2004
2039
#if !defined(CONFIG_USER_ONLY)
2005
2040
case 0x24: /* Nucleus quad LDD 128 bit atomic */
2006
2041
case 0x2c: /* Nucleus quad LDD 128 bit atomic LE */
2007
helper_check_align(addr, 0xf);
2042
helper_check_align(env, addr, 0xf);
2009
env->gregs[1] = ldq_nucleus(addr + 8);
2044
env->gregs[1] = cpu_ldq_nucleus(env, addr + 8);
2010
2045
if (asi == 0x2c) {
2011
2046
bswap64s(&env->gregs[1]);
2013
2048
} else if (rd < 8) {
2014
env->gregs[rd] = ldq_nucleus(addr);
2015
env->gregs[rd + 1] = ldq_nucleus(addr + 8);
2049
env->gregs[rd] = cpu_ldq_nucleus(env, addr);
2050
env->gregs[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2016
2051
if (asi == 0x2c) {
2017
2052
bswap64s(&env->gregs[rd]);
2018
2053
bswap64s(&env->gregs[rd + 1]);
2021
env->regwptr[rd] = ldq_nucleus(addr);
2022
env->regwptr[rd + 1] = ldq_nucleus(addr + 8);
2056
env->regwptr[rd] = cpu_ldq_nucleus(env, addr);
2057
env->regwptr[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2023
2058
if (asi == 0x2c) {
2024
2059
bswap64s(&env->regwptr[rd]);
2025
2060
bswap64s(&env->regwptr[rd + 1]);
2031
helper_check_align(addr, 0x3);
2066
helper_check_align(env, addr, 0x3);
2033
env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0);
2068
env->gregs[1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2034
2069
} else if (rd < 8) {
2035
env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0);
2036
env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2070
env->gregs[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2071
env->gregs[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2038
env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0);
2039
env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2073
env->regwptr[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2074
env->regwptr[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2045
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2080
void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2047
2083
unsigned int i;
2048
2084
target_ulong val;
2050
helper_check_align(addr, 3);
2086
helper_check_align(env, addr, 3);
2051
2087
addr = asi_address_mask(env, asi, addr);
2077
2113
helper_raise_exception(env, TT_ILL_INSN);
2080
helper_check_align(addr, 0x3f);
2081
for (i = 0; i < 8; i++, rd += 2, addr += 4) {
2082
env->fpr[rd/2].ll = helper_ld_asi(addr, asi & 0x19, 8, 0);
2116
helper_check_align(env, addr, 0x3f);
2117
for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2118
env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0);
2090
2126
switch (size) {
2093
val = helper_ld_asi(addr, asi, size, 0);
2129
val = helper_ld_asi(env, addr, asi, size, 0);
2095
env->fpr[rd/2].l.lower = val;
2131
env->fpr[rd / 2].l.lower = val;
2097
env->fpr[rd/2].l.upper = val;
2133
env->fpr[rd / 2].l.upper = val;
2101
env->fpr[rd/2].ll = helper_ld_asi(addr, asi, size, 0);
2137
env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, size, 0);
2104
env->fpr[rd/2].ll = helper_ld_asi(addr, asi, 8, 0);
2105
env->fpr[rd/2 + 1].ll = helper_ld_asi(addr + 8, asi, 8, 0);
2140
env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, 8, 0);
2141
env->fpr[rd / 2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0);
2110
void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2146
void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2112
2149
unsigned int i;
2113
2150
target_ulong val;
2115
helper_check_align(addr, 3);
2152
helper_check_align(env, addr, 3);
2116
2153
addr = asi_address_mask(env, asi, addr);
2161
val = env->fpr[rd/2].l.lower;
2198
val = env->fpr[rd / 2].l.lower;
2163
val = env->fpr[rd/2].l.upper;
2200
val = env->fpr[rd / 2].l.upper;
2165
helper_st_asi(addr, val, asi, size);
2202
helper_st_asi(env, addr, val, asi, size);
2168
helper_st_asi(addr, env->fpr[rd/2].ll, asi, size);
2205
helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, size);
2171
helper_st_asi(addr, env->fpr[rd/2].ll, asi, 8);
2172
helper_st_asi(addr + 8, env->fpr[rd/2 + 1].ll, asi, 8);
2208
helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, 8);
2209
helper_st_asi(env, addr + 8, env->fpr[rd / 2 + 1].ll, asi, 8);
2177
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
2178
target_ulong val2, uint32_t asi)
2214
target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
2215
target_ulong val1, target_ulong val2, uint32_t asi)
2180
2217
target_ulong ret;
2182
2219
val2 &= 0xffffffffUL;
2183
ret = helper_ld_asi(addr, asi, 4, 0);
2220
ret = helper_ld_asi(env, addr, asi, 4, 0);
2184
2221
ret &= 0xffffffffUL;
2185
2222
if (val2 == ret) {
2186
helper_st_asi(addr, val1 & 0xffffffffUL, asi, 4);
2223
helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
2191
target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
2192
target_ulong val2, uint32_t asi)
2228
target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
2229
target_ulong val1, target_ulong val2,
2194
2232
target_ulong ret;
2196
ret = helper_ld_asi(addr, asi, 8, 0);
2234
ret = helper_ld_asi(env, addr, asi, 8, 0);
2197
2235
if (val2 == ret) {
2198
helper_st_asi(addr, val1, asi, 8);
2236
helper_st_asi(env, addr, val1, asi, 8);
2202
2240
#endif /* TARGET_SPARC64 */
2204
void helper_ldqf(target_ulong addr, int mem_idx)
2242
void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2206
2244
/* XXX add 128 bit load */
2209
helper_check_align(addr, 7);
2247
helper_check_align(env, addr, 7);
2210
2248
#if !defined(CONFIG_USER_ONLY)
2211
2249
switch (mem_idx) {
2212
2250
case MMU_USER_IDX:
2213
u.ll.upper = ldq_user(addr);
2214
u.ll.lower = ldq_user(addr + 8);
2251
u.ll.upper = cpu_ldq_user(env, addr);
2252
u.ll.lower = cpu_ldq_user(env, addr + 8);
2217
2255
case MMU_KERNEL_IDX:
2218
u.ll.upper = ldq_kernel(addr);
2219
u.ll.lower = ldq_kernel(addr + 8);
2256
u.ll.upper = cpu_ldq_kernel(env, addr);
2257
u.ll.lower = cpu_ldq_kernel(env, addr + 8);
2222
2260
#ifdef TARGET_SPARC64
2223
2261
case MMU_HYPV_IDX:
2224
u.ll.upper = ldq_hypv(addr);
2225
u.ll.lower = ldq_hypv(addr + 8);
2262
u.ll.upper = cpu_ldq_hypv(env, addr);
2263
u.ll.lower = cpu_ldq_hypv(env, addr + 8);
2240
void helper_stqf(target_ulong addr, int mem_idx)
2278
void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2242
2280
/* XXX add 128 bit store */
2245
helper_check_align(addr, 7);
2283
helper_check_align(env, addr, 7);
2246
2284
#if !defined(CONFIG_USER_ONLY)
2247
2285
switch (mem_idx) {
2248
2286
case MMU_USER_IDX:
2250
stq_user(addr, u.ll.upper);
2251
stq_user(addr + 8, u.ll.lower);
2288
cpu_stq_user(env, addr, u.ll.upper);
2289
cpu_stq_user(env, addr + 8, u.ll.lower);
2253
2291
case MMU_KERNEL_IDX:
2255
stq_kernel(addr, u.ll.upper);
2256
stq_kernel(addr + 8, u.ll.lower);
2293
cpu_stq_kernel(env, addr, u.ll.upper);
2294
cpu_stq_kernel(env, addr + 8, u.ll.lower);
2258
2296
#ifdef TARGET_SPARC64
2259
2297
case MMU_HYPV_IDX:
2261
stq_hypv(addr, u.ll.upper);
2262
stq_hypv(addr + 8, u.ll.lower);
2299
cpu_stq_hypv(env, addr, u.ll.upper);
2300
cpu_stq_hypv(env, addr + 8, u.ll.lower);
2360
2393
#if !defined(CONFIG_USER_ONLY)
2361
void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr,
2362
int is_write, int is_exec, int is_asi, int size)
2364
CPUState *saved_env;
2368
do_unassigned_access(addr, is_write, is_exec, is_asi, size);
2394
/* XXX: make it generic ? */
2395
static void cpu_restore_state2(CPUSPARCState *env, uintptr_t retaddr)
2397
TranslationBlock *tb;
2400
/* now we have a real cpu fault */
2401
tb = tb_find_pc(retaddr);
2403
/* the PC is inside the translated code. It means that we have
2404
a virtual CPU fault */
2405
cpu_restore_state(tb, env, retaddr);
2410
void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write,
2411
int is_user, uintptr_t retaddr)
2413
#ifdef DEBUG_UNALIGNED
2414
printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2415
"\n", addr, env->pc);
2417
cpu_restore_state2(env, retaddr);
2418
helper_raise_exception(env, TT_UNALIGNED);
2421
/* try to fill the TLB and return an exception if error. If retaddr is
2422
NULL, it means that the function was called in C code (i.e. not
2423
from generated code or from helper.c) */
2424
/* XXX: fix it to restore all registers */
2425
void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx,
2430
ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
2432
cpu_restore_state2(env, retaddr);