2 * Helpers for loads and stores
4 * Copyright (c) 2003-2005 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
23 #include "exec/helper-proto.h"
24 #include "exec/exec-all.h"
25 #include "exec/cpu_ldst.h"
30 //#define DEBUG_UNALIGNED
31 //#define DEBUG_UNASSIGNED
33 //#define DEBUG_CACHE_CONTROL
36 #define DPRINTF_MMU(fmt, ...) \
37 do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
39 #define DPRINTF_MMU(fmt, ...) do {} while (0)
43 #define DPRINTF_MXCC(fmt, ...) \
44 do { printf("MXCC: " fmt , ## __VA_ARGS__); } while (0)
46 #define DPRINTF_MXCC(fmt, ...) do {} while (0)
50 #define DPRINTF_ASI(fmt, ...) \
51 do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0)
54 #ifdef DEBUG_CACHE_CONTROL
55 #define DPRINTF_CACHE_CONTROL(fmt, ...) \
56 do { printf("CACHE_CONTROL: " fmt , ## __VA_ARGS__); } while (0)
58 #define DPRINTF_CACHE_CONTROL(fmt, ...) do {} while (0)
63 #define AM_CHECK(env1) ((env1)->pstate & PS_AM)
65 #define AM_CHECK(env1) (1)
69 #define QT0 (env->qt0)
70 #define QT1 (env->qt1)
72 #if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
73 /* Calculates TSB pointer value for fault page size 8k or 64k */
74 static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register
,
75 uint64_t tag_access_register
,
78 uint64_t tsb_base
= tsb_register
& ~0x1fffULL
;
79 int tsb_split
= (tsb_register
& 0x1000ULL
) ? 1 : 0;
80 int tsb_size
= tsb_register
& 0xf;
82 /* discard lower 13 bits which hold tag access context */
83 uint64_t tag_access_va
= tag_access_register
& ~0x1fffULL
;
85 /* now reorder bits */
86 uint64_t tsb_base_mask
= ~0x1fffULL
;
87 uint64_t va
= tag_access_va
;
89 /* move va bits to correct position */
90 if (page_size
== 8*1024) {
92 } else if (page_size
== 64*1024) {
97 tsb_base_mask
<<= tsb_size
;
100 /* calculate tsb_base mask and adjust va if split is in use */
102 if (page_size
== 8*1024) {
103 va
&= ~(1ULL << (13 + tsb_size
));
104 } else if (page_size
== 64*1024) {
105 va
|= (1ULL << (13 + tsb_size
));
110 return ((tsb_base
& tsb_base_mask
) | (va
& ~tsb_base_mask
)) & ~0xfULL
;
113 /* Calculates tag target register value by reordering bits
114 in tag access register */
115 static uint64_t ultrasparc_tag_target(uint64_t tag_access_register
)
117 return ((tag_access_register
& 0x1fff) << 48) | (tag_access_register
>> 22);
120 static void replace_tlb_entry(SparcTLBEntry
*tlb
,
121 uint64_t tlb_tag
, uint64_t tlb_tte
,
124 target_ulong mask
, size
, va
, offset
;
126 /* flush page range if translation is valid */
127 if (TTE_IS_VALID(tlb
->tte
)) {
128 CPUState
*cs
= CPU(sparc_env_get_cpu(env1
));
130 mask
= 0xffffffffffffe000ULL
;
131 mask
<<= 3 * ((tlb
->tte
>> 61) & 3);
134 va
= tlb
->tag
& mask
;
136 for (offset
= 0; offset
< size
; offset
+= TARGET_PAGE_SIZE
) {
137 tlb_flush_page(cs
, va
+ offset
);
145 static void demap_tlb(SparcTLBEntry
*tlb
, target_ulong demap_addr
,
146 const char *strmmu
, CPUSPARCState
*env1
)
152 int is_demap_context
= (demap_addr
>> 6) & 1;
155 switch ((demap_addr
>> 4) & 3) {
156 case 0: /* primary */
157 context
= env1
->dmmu
.mmu_primary_context
;
159 case 1: /* secondary */
160 context
= env1
->dmmu
.mmu_secondary_context
;
162 case 2: /* nucleus */
165 case 3: /* reserved */
170 for (i
= 0; i
< 64; i
++) {
171 if (TTE_IS_VALID(tlb
[i
].tte
)) {
173 if (is_demap_context
) {
174 /* will remove non-global entries matching context value */
175 if (TTE_IS_GLOBAL(tlb
[i
].tte
) ||
176 !tlb_compare_context(&tlb
[i
], context
)) {
181 will remove any entry matching VA */
182 mask
= 0xffffffffffffe000ULL
;
183 mask
<<= 3 * ((tlb
[i
].tte
>> 61) & 3);
185 if (!compare_masked(demap_addr
, tlb
[i
].tag
, mask
)) {
189 /* entry should be global or matching context value */
190 if (!TTE_IS_GLOBAL(tlb
[i
].tte
) &&
191 !tlb_compare_context(&tlb
[i
], context
)) {
196 replace_tlb_entry(&tlb
[i
], 0, 0, env1
);
198 DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu
, i
);
199 dump_mmu(stdout
, fprintf
, env1
);
205 static void replace_tlb_1bit_lru(SparcTLBEntry
*tlb
,
206 uint64_t tlb_tag
, uint64_t tlb_tte
,
207 const char *strmmu
, CPUSPARCState
*env1
)
209 unsigned int i
, replace_used
;
211 /* Try replacing invalid entry */
212 for (i
= 0; i
< 64; i
++) {
213 if (!TTE_IS_VALID(tlb
[i
].tte
)) {
214 replace_tlb_entry(&tlb
[i
], tlb_tag
, tlb_tte
, env1
);
216 DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu
, i
);
217 dump_mmu(stdout
, fprintf
, env1
);
223 /* All entries are valid, try replacing unlocked entry */
225 for (replace_used
= 0; replace_used
< 2; ++replace_used
) {
227 /* Used entries are not replaced on first pass */
229 for (i
= 0; i
< 64; i
++) {
230 if (!TTE_IS_LOCKED(tlb
[i
].tte
) && !TTE_IS_USED(tlb
[i
].tte
)) {
232 replace_tlb_entry(&tlb
[i
], tlb_tag
, tlb_tte
, env1
);
234 DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
235 strmmu
, (replace_used
? "used" : "unused"), i
);
236 dump_mmu(stdout
, fprintf
, env1
);
242 /* Now reset used bit and search for unused entries again */
244 for (i
= 0; i
< 64; i
++) {
245 TTE_SET_UNUSED(tlb
[i
].tte
);
250 DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu
);
257 #ifdef TARGET_SPARC64
258 /* returns true if access using this ASI is to have address translated by MMU
259 otherwise access is to raw physical address */
260 /* TODO: check sparc32 bits */
261 static inline int is_translating_asi(int asi
)
263 /* Ultrasparc IIi translating asi
264 - note this list is defined by cpu implementation
281 static inline target_ulong
address_mask(CPUSPARCState
*env1
, target_ulong addr
)
283 if (AM_CHECK(env1
)) {
284 addr
&= 0xffffffffULL
;
289 static inline target_ulong
asi_address_mask(CPUSPARCState
*env
,
290 int asi
, target_ulong addr
)
292 if (is_translating_asi(asi
)) {
293 addr
= address_mask(env
, addr
);
299 static void do_check_align(CPUSPARCState
*env
, target_ulong addr
,
300 uint32_t align
, uintptr_t ra
)
303 #ifdef DEBUG_UNALIGNED
304 printf("Unaligned access to 0x" TARGET_FMT_lx
" from 0x" TARGET_FMT_lx
305 "\n", addr
, env
->pc
);
307 cpu_raise_exception_ra(env
, TT_UNALIGNED
, ra
);
311 void helper_check_align(CPUSPARCState
*env
, target_ulong addr
, uint32_t align
)
313 do_check_align(env
, addr
, align
, GETPC());
316 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
318 static void dump_mxcc(CPUSPARCState
*env
)
320 printf("mxccdata: %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016" PRIx64
322 env
->mxccdata
[0], env
->mxccdata
[1],
323 env
->mxccdata
[2], env
->mxccdata
[3]);
324 printf("mxccregs: %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016" PRIx64
326 " %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016" PRIx64
328 env
->mxccregs
[0], env
->mxccregs
[1],
329 env
->mxccregs
[2], env
->mxccregs
[3],
330 env
->mxccregs
[4], env
->mxccregs
[5],
331 env
->mxccregs
[6], env
->mxccregs
[7]);
335 #if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
336 && defined(DEBUG_ASI)
337 static void dump_asi(const char *txt
, target_ulong addr
, int asi
, int size
,
342 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %02" PRIx64
"\n", txt
,
343 addr
, asi
, r1
& 0xff);
346 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %04" PRIx64
"\n", txt
,
347 addr
, asi
, r1
& 0xffff);
350 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %08" PRIx64
"\n", txt
,
351 addr
, asi
, r1
& 0xffffffff);
354 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %016" PRIx64
"\n", txt
,
361 #ifndef TARGET_SPARC64
362 #ifndef CONFIG_USER_ONLY
365 /* Leon3 cache control */
367 static void leon3_cache_control_st(CPUSPARCState
*env
, target_ulong addr
,
368 uint64_t val
, int size
)
370 DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64
", size:%d\n",
374 DPRINTF_CACHE_CONTROL("32bits only\n");
379 case 0x00: /* Cache control */
381 /* These values must always be read as zeros */
382 val
&= ~CACHE_CTRL_FD
;
383 val
&= ~CACHE_CTRL_FI
;
384 val
&= ~CACHE_CTRL_IB
;
385 val
&= ~CACHE_CTRL_IP
;
386 val
&= ~CACHE_CTRL_DP
;
388 env
->cache_control
= val
;
390 case 0x04: /* Instruction cache configuration */
391 case 0x08: /* Data cache configuration */
395 DPRINTF_CACHE_CONTROL("write unknown register %08x\n", addr
);
400 static uint64_t leon3_cache_control_ld(CPUSPARCState
*env
, target_ulong addr
,
406 DPRINTF_CACHE_CONTROL("32bits only\n");
411 case 0x00: /* Cache control */
412 ret
= env
->cache_control
;
415 /* Configuration registers are read and only always keep those
418 case 0x04: /* Instruction cache configuration */
421 case 0x08: /* Data cache configuration */
425 DPRINTF_CACHE_CONTROL("read unknown register %08x\n", addr
);
428 DPRINTF_CACHE_CONTROL("ld addr:%08x, ret:0x%" PRIx64
", size:%d\n",
433 uint64_t helper_ld_asi(CPUSPARCState
*env
, target_ulong addr
,
434 int asi
, uint32_t memop
)
436 int size
= 1 << (memop
& MO_SIZE
);
437 int sign
= memop
& MO_SIGN
;
438 CPUState
*cs
= CPU(sparc_env_get_cpu(env
));
440 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
441 uint32_t last_addr
= addr
;
444 do_check_align(env
, addr
, size
- 1, GETPC());
446 case ASI_M_MXCC
: /* SuperSparc MXCC registers, or... */
447 /* case ASI_LEON_CACHEREGS: Leon3 cache control */
449 case 0x00: /* Leon3 Cache Control */
450 case 0x08: /* Leon3 Instruction Cache config */
451 case 0x0C: /* Leon3 Date Cache config */
452 if (env
->def
->features
& CPU_FEATURE_CACHE_CTRL
) {
453 ret
= leon3_cache_control_ld(env
, addr
, size
);
456 case 0x01c00a00: /* MXCC control register */
458 ret
= env
->mxccregs
[3];
460 qemu_log_mask(LOG_UNIMP
,
461 "%08x: unimplemented access size: %d\n", addr
,
465 case 0x01c00a04: /* MXCC control register */
467 ret
= env
->mxccregs
[3];
469 qemu_log_mask(LOG_UNIMP
,
470 "%08x: unimplemented access size: %d\n", addr
,
474 case 0x01c00c00: /* Module reset register */
476 ret
= env
->mxccregs
[5];
477 /* should we do something here? */
479 qemu_log_mask(LOG_UNIMP
,
480 "%08x: unimplemented access size: %d\n", addr
,
484 case 0x01c00f00: /* MBus port address register */
486 ret
= env
->mxccregs
[7];
488 qemu_log_mask(LOG_UNIMP
,
489 "%08x: unimplemented access size: %d\n", addr
,
494 qemu_log_mask(LOG_UNIMP
,
495 "%08x: unimplemented address, size: %d\n", addr
,
499 DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
500 "addr = %08x -> ret = %" PRIx64
","
501 "addr = %08x\n", asi
, size
, sign
, last_addr
, ret
, addr
);
506 case ASI_M_FLUSH_PROBE
: /* SuperSparc MMU probe */
507 case ASI_LEON_MMUFLUSH
: /* LEON3 MMU probe */
511 mmulev
= (addr
>> 8) & 15;
515 ret
= mmu_probe(env
, addr
, mmulev
);
517 DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64
"\n",
521 case ASI_M_MMUREGS
: /* SuperSparc MMU regs */
522 case ASI_LEON_MMUREGS
: /* LEON3 MMU regs */
524 int reg
= (addr
>> 8) & 0x1f;
526 ret
= env
->mmuregs
[reg
];
527 if (reg
== 3) { /* Fault status cleared on read */
529 } else if (reg
== 0x13) { /* Fault status read */
530 ret
= env
->mmuregs
[3];
531 } else if (reg
== 0x14) { /* Fault address read */
532 ret
= env
->mmuregs
[4];
534 DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64
"\n", reg
, ret
);
537 case ASI_M_TLBDIAG
: /* Turbosparc ITLB Diagnostic */
538 case ASI_M_DIAGS
: /* Turbosparc DTLB Diagnostic */
539 case ASI_M_IODIAG
: /* Turbosparc IOTLB Diagnostic */
541 case ASI_KERNELTXT
: /* Supervisor code access */
544 ret
= cpu_ldub_code(env
, addr
);
547 ret
= cpu_lduw_code(env
, addr
);
551 ret
= cpu_ldl_code(env
, addr
);
554 ret
= cpu_ldq_code(env
, addr
);
558 case ASI_M_TXTC_TAG
: /* SparcStation 5 I-cache tag */
559 case ASI_M_TXTC_DATA
: /* SparcStation 5 I-cache data */
560 case ASI_M_DATAC_TAG
: /* SparcStation 5 D-cache tag */
561 case ASI_M_DATAC_DATA
: /* SparcStation 5 D-cache data */
563 case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
566 ret
= ldub_phys(cs
->as
, (hwaddr
)addr
567 | ((hwaddr
)(asi
& 0xf) << 32));
570 ret
= lduw_phys(cs
->as
, (hwaddr
)addr
571 | ((hwaddr
)(asi
& 0xf) << 32));
575 ret
= ldl_phys(cs
->as
, (hwaddr
)addr
576 | ((hwaddr
)(asi
& 0xf) << 32));
579 ret
= ldq_phys(cs
->as
, (hwaddr
)addr
580 | ((hwaddr
)(asi
& 0xf) << 32));
584 case 0x30: /* Turbosparc secondary cache diagnostic */
585 case 0x31: /* Turbosparc RAM snoop */
586 case 0x32: /* Turbosparc page table descriptor diagnostic */
587 case 0x39: /* data cache diagnostic register */
590 case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
592 int reg
= (addr
>> 8) & 3;
595 case 0: /* Breakpoint Value (Addr) */
596 ret
= env
->mmubpregs
[reg
];
598 case 1: /* Breakpoint Mask */
599 ret
= env
->mmubpregs
[reg
];
601 case 2: /* Breakpoint Control */
602 ret
= env
->mmubpregs
[reg
];
604 case 3: /* Breakpoint Status */
605 ret
= env
->mmubpregs
[reg
];
606 env
->mmubpregs
[reg
] = 0ULL;
609 DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64
"\n", reg
,
613 case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
614 ret
= env
->mmubpctrv
;
616 case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
617 ret
= env
->mmubpctrc
;
619 case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
620 ret
= env
->mmubpctrs
;
622 case 0x4c: /* SuperSPARC MMU Breakpoint Action */
623 ret
= env
->mmubpaction
;
625 case ASI_USERTXT
: /* User code access, XXX */
627 cpu_unassigned_access(cs
, addr
, false, false, asi
, size
);
631 case ASI_USERDATA
: /* User data access */
632 case ASI_KERNELDATA
: /* Supervisor data access */
633 case ASI_P
: /* Implicit primary context data access (v9 only?) */
634 case ASI_M_BYPASS
: /* MMU passthrough */
635 case ASI_LEON_BYPASS
: /* LEON MMU passthrough */
636 /* These are always handled inline. */
637 g_assert_not_reached();
655 dump_asi("read ", last_addr
, asi
, size
, ret
);
660 void helper_st_asi(CPUSPARCState
*env
, target_ulong addr
, uint64_t val
,
661 int asi
, uint32_t memop
)
663 int size
= 1 << (memop
& MO_SIZE
);
664 SPARCCPU
*cpu
= sparc_env_get_cpu(env
);
665 CPUState
*cs
= CPU(cpu
);
667 do_check_align(env
, addr
, size
- 1, GETPC());
669 case ASI_M_MXCC
: /* SuperSparc MXCC registers, or... */
670 /* case ASI_LEON_CACHEREGS: Leon3 cache control */
672 case 0x00: /* Leon3 Cache Control */
673 case 0x08: /* Leon3 Instruction Cache config */
674 case 0x0C: /* Leon3 Date Cache config */
675 if (env
->def
->features
& CPU_FEATURE_CACHE_CTRL
) {
676 leon3_cache_control_st(env
, addr
, val
, size
);
680 case 0x01c00000: /* MXCC stream data register 0 */
682 env
->mxccdata
[0] = val
;
684 qemu_log_mask(LOG_UNIMP
,
685 "%08x: unimplemented access size: %d\n", addr
,
689 case 0x01c00008: /* MXCC stream data register 1 */
691 env
->mxccdata
[1] = val
;
693 qemu_log_mask(LOG_UNIMP
,
694 "%08x: unimplemented access size: %d\n", addr
,
698 case 0x01c00010: /* MXCC stream data register 2 */
700 env
->mxccdata
[2] = val
;
702 qemu_log_mask(LOG_UNIMP
,
703 "%08x: unimplemented access size: %d\n", addr
,
707 case 0x01c00018: /* MXCC stream data register 3 */
709 env
->mxccdata
[3] = val
;
711 qemu_log_mask(LOG_UNIMP
,
712 "%08x: unimplemented access size: %d\n", addr
,
716 case 0x01c00100: /* MXCC stream source */
718 env
->mxccregs
[0] = val
;
720 qemu_log_mask(LOG_UNIMP
,
721 "%08x: unimplemented access size: %d\n", addr
,
724 env
->mxccdata
[0] = ldq_phys(cs
->as
,
725 (env
->mxccregs
[0] & 0xffffffffULL
) +
727 env
->mxccdata
[1] = ldq_phys(cs
->as
,
728 (env
->mxccregs
[0] & 0xffffffffULL
) +
730 env
->mxccdata
[2] = ldq_phys(cs
->as
,
731 (env
->mxccregs
[0] & 0xffffffffULL
) +
733 env
->mxccdata
[3] = ldq_phys(cs
->as
,
734 (env
->mxccregs
[0] & 0xffffffffULL
) +
737 case 0x01c00200: /* MXCC stream destination */
739 env
->mxccregs
[1] = val
;
741 qemu_log_mask(LOG_UNIMP
,
742 "%08x: unimplemented access size: %d\n", addr
,
745 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 0,
747 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 8,
749 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 16,
751 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 24,
754 case 0x01c00a00: /* MXCC control register */
756 env
->mxccregs
[3] = val
;
758 qemu_log_mask(LOG_UNIMP
,
759 "%08x: unimplemented access size: %d\n", addr
,
763 case 0x01c00a04: /* MXCC control register */
765 env
->mxccregs
[3] = (env
->mxccregs
[3] & 0xffffffff00000000ULL
)
768 qemu_log_mask(LOG_UNIMP
,
769 "%08x: unimplemented access size: %d\n", addr
,
773 case 0x01c00e00: /* MXCC error register */
774 /* writing a 1 bit clears the error */
776 env
->mxccregs
[6] &= ~val
;
778 qemu_log_mask(LOG_UNIMP
,
779 "%08x: unimplemented access size: %d\n", addr
,
783 case 0x01c00f00: /* MBus port address register */
785 env
->mxccregs
[7] = val
;
787 qemu_log_mask(LOG_UNIMP
,
788 "%08x: unimplemented access size: %d\n", addr
,
793 qemu_log_mask(LOG_UNIMP
,
794 "%08x: unimplemented address, size: %d\n", addr
,
798 DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64
"\n",
799 asi
, size
, addr
, val
);
804 case ASI_M_FLUSH_PROBE
: /* SuperSparc MMU flush */
805 case ASI_LEON_MMUFLUSH
: /* LEON3 MMU flush */
809 mmulev
= (addr
>> 8) & 15;
810 DPRINTF_MMU("mmu flush level %d\n", mmulev
);
812 case 0: /* flush page */
813 tlb_flush_page(CPU(cpu
), addr
& 0xfffff000);
815 case 1: /* flush segment (256k) */
816 case 2: /* flush region (16M) */
817 case 3: /* flush context (4G) */
818 case 4: /* flush entire */
819 tlb_flush(CPU(cpu
), 1);
825 dump_mmu(stdout
, fprintf
, env
);
829 case ASI_M_MMUREGS
: /* write MMU regs */
830 case ASI_LEON_MMUREGS
: /* LEON3 write MMU regs */
832 int reg
= (addr
>> 8) & 0x1f;
835 oldreg
= env
->mmuregs
[reg
];
837 case 0: /* Control Register */
838 env
->mmuregs
[reg
] = (env
->mmuregs
[reg
] & 0xff000000) |
840 /* Mappings generated during no-fault mode
841 are invalid in normal mode. */
842 if ((oldreg
^ env
->mmuregs
[reg
])
843 & (MMU_NF
| env
->def
->mmu_bm
)) {
844 tlb_flush(CPU(cpu
), 1);
847 case 1: /* Context Table Pointer Register */
848 env
->mmuregs
[reg
] = val
& env
->def
->mmu_ctpr_mask
;
850 case 2: /* Context Register */
851 env
->mmuregs
[reg
] = val
& env
->def
->mmu_cxr_mask
;
852 if (oldreg
!= env
->mmuregs
[reg
]) {
853 /* we flush when the MMU context changes because
854 QEMU has no MMU context support */
855 tlb_flush(CPU(cpu
), 1);
858 case 3: /* Synchronous Fault Status Register with Clear */
859 case 4: /* Synchronous Fault Address Register */
861 case 0x10: /* TLB Replacement Control Register */
862 env
->mmuregs
[reg
] = val
& env
->def
->mmu_trcr_mask
;
864 case 0x13: /* Synchronous Fault Status Register with Read
866 env
->mmuregs
[3] = val
& env
->def
->mmu_sfsr_mask
;
868 case 0x14: /* Synchronous Fault Address Register */
869 env
->mmuregs
[4] = val
;
872 env
->mmuregs
[reg
] = val
;
875 if (oldreg
!= env
->mmuregs
[reg
]) {
876 DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
877 reg
, oldreg
, env
->mmuregs
[reg
]);
880 dump_mmu(stdout
, fprintf
, env
);
884 case ASI_M_TLBDIAG
: /* Turbosparc ITLB Diagnostic */
885 case ASI_M_DIAGS
: /* Turbosparc DTLB Diagnostic */
886 case ASI_M_IODIAG
: /* Turbosparc IOTLB Diagnostic */
888 case ASI_M_TXTC_TAG
: /* I-cache tag */
889 case ASI_M_TXTC_DATA
: /* I-cache data */
890 case ASI_M_DATAC_TAG
: /* D-cache tag */
891 case ASI_M_DATAC_DATA
: /* D-cache data */
892 case ASI_M_FLUSH_PAGE
: /* I/D-cache flush page */
893 case ASI_M_FLUSH_SEG
: /* I/D-cache flush segment */
894 case ASI_M_FLUSH_REGION
: /* I/D-cache flush region */
895 case ASI_M_FLUSH_CTX
: /* I/D-cache flush context */
896 case ASI_M_FLUSH_USER
: /* I/D-cache flush user */
898 case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
902 stb_phys(cs
->as
, (hwaddr
)addr
903 | ((hwaddr
)(asi
& 0xf) << 32), val
);
906 stw_phys(cs
->as
, (hwaddr
)addr
907 | ((hwaddr
)(asi
& 0xf) << 32), val
);
911 stl_phys(cs
->as
, (hwaddr
)addr
912 | ((hwaddr
)(asi
& 0xf) << 32), val
);
915 stq_phys(cs
->as
, (hwaddr
)addr
916 | ((hwaddr
)(asi
& 0xf) << 32), val
);
921 case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
922 case 0x31: /* store buffer data, Ross RT620 I-cache flush or
923 Turbosparc snoop RAM */
924 case 0x32: /* store buffer control or Turbosparc page table
925 descriptor diagnostic */
926 case 0x36: /* I-cache flash clear */
927 case 0x37: /* D-cache flash clear */
929 case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
931 int reg
= (addr
>> 8) & 3;
934 case 0: /* Breakpoint Value (Addr) */
935 env
->mmubpregs
[reg
] = (val
& 0xfffffffffULL
);
937 case 1: /* Breakpoint Mask */
938 env
->mmubpregs
[reg
] = (val
& 0xfffffffffULL
);
940 case 2: /* Breakpoint Control */
941 env
->mmubpregs
[reg
] = (val
& 0x7fULL
);
943 case 3: /* Breakpoint Status */
944 env
->mmubpregs
[reg
] = (val
& 0xfULL
);
947 DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg
,
951 case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
952 env
->mmubpctrv
= val
& 0xffffffff;
954 case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
955 env
->mmubpctrc
= val
& 0x3;
957 case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
958 env
->mmubpctrs
= val
& 0x3;
960 case 0x4c: /* SuperSPARC MMU Breakpoint Action */
961 env
->mmubpaction
= val
& 0x1fff;
963 case ASI_USERTXT
: /* User code access, XXX */
964 case ASI_KERNELTXT
: /* Supervisor code access, XXX */
966 cpu_unassigned_access(CPU(sparc_env_get_cpu(env
)),
967 addr
, true, false, asi
, size
);
970 case ASI_USERDATA
: /* User data access */
971 case ASI_KERNELDATA
: /* Supervisor data access */
973 case ASI_M_BYPASS
: /* MMU passthrough */
974 case ASI_LEON_BYPASS
: /* LEON MMU passthrough */
975 case ASI_M_BCOPY
: /* Block copy, sta access */
976 case ASI_M_BFILL
: /* Block fill, stda access */
977 /* These are always handled inline. */
978 g_assert_not_reached();
981 dump_asi("write", addr
, asi
, size
, val
);
985 #endif /* CONFIG_USER_ONLY */
986 #else /* TARGET_SPARC64 */
988 #ifdef CONFIG_USER_ONLY
989 uint64_t helper_ld_asi(CPUSPARCState
*env
, target_ulong addr
,
990 int asi
, uint32_t memop
)
992 int size
= 1 << (memop
& MO_SIZE
);
993 int sign
= memop
& MO_SIGN
;
997 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
999 do_check_align(env
, addr
, size
- 1, GETPC());
1000 addr
= asi_address_mask(env
, asi
, addr
);
1003 case ASI_PNF
: /* Primary no-fault */
1004 case ASI_PNFL
: /* Primary no-fault LE */
1005 case ASI_SNF
: /* Secondary no-fault */
1006 case ASI_SNFL
: /* Secondary no-fault LE */
1007 if (page_check_range(addr
, size
, PAGE_READ
) == -1) {
1013 ret
= cpu_ldub_data(env
, addr
);
1016 ret
= cpu_lduw_data(env
, addr
);
1019 ret
= cpu_ldl_data(env
, addr
);
1022 ret
= cpu_ldq_data(env
, addr
);
1025 g_assert_not_reached();
1030 case ASI_P
: /* Primary */
1031 case ASI_PL
: /* Primary LE */
1032 case ASI_S
: /* Secondary */
1033 case ASI_SL
: /* Secondary LE */
1034 /* These are always handled inline. */
1035 g_assert_not_reached();
1038 cpu_raise_exception_ra(env
, TT_DATA_ACCESS
, GETPC());
1041 /* Convert from little endian */
1043 case ASI_PNFL
: /* Primary no-fault LE */
1044 case ASI_SNFL
: /* Secondary no-fault LE */
1058 /* Convert to signed number */
1065 ret
= (int16_t) ret
;
1068 ret
= (int32_t) ret
;
1073 dump_asi("read", addr
, asi
, size
, ret
);
1078 void helper_st_asi(CPUSPARCState
*env
, target_ulong addr
, target_ulong val
,
1079 int asi
, uint32_t memop
)
1081 int size
= 1 << (memop
& MO_SIZE
);
1083 dump_asi("write", addr
, asi
, size
, val
);
1086 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
1088 do_check_align(env
, addr
, size
- 1, GETPC());
1091 case ASI_P
: /* Primary */
1092 case ASI_PL
: /* Primary LE */
1093 case ASI_S
: /* Secondary */
1094 case ASI_SL
: /* Secondary LE */
1095 /* These are always handled inline. */
1096 g_assert_not_reached();
1098 case ASI_PNF
: /* Primary no-fault, RO */
1099 case ASI_SNF
: /* Secondary no-fault, RO */
1100 case ASI_PNFL
: /* Primary no-fault LE, RO */
1101 case ASI_SNFL
: /* Secondary no-fault LE, RO */
1103 cpu_raise_exception_ra(env
, TT_DATA_ACCESS
, GETPC());
1107 #else /* CONFIG_USER_ONLY */
1109 uint64_t helper_ld_asi(CPUSPARCState
*env
, target_ulong addr
,
1110 int asi
, uint32_t memop
)
1112 int size
= 1 << (memop
& MO_SIZE
);
1113 int sign
= memop
& MO_SIGN
;
1114 CPUState
*cs
= CPU(sparc_env_get_cpu(env
));
1116 #if defined(DEBUG_ASI)
1117 target_ulong last_addr
= addr
;
1122 if ((asi
< 0x80 && (env
->pstate
& PS_PRIV
) == 0)
1123 || (cpu_has_hypervisor(env
)
1124 && asi
>= 0x30 && asi
< 0x80
1125 && !(env
->hpstate
& HS_PRIV
))) {
1126 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
1129 do_check_align(env
, addr
, size
- 1, GETPC());
1130 addr
= asi_address_mask(env
, asi
, addr
);
1139 int idx
= (env
->pstate
& PS_PRIV
1140 ? (asi
& 1 ? MMU_KERNEL_SECONDARY_IDX
: MMU_KERNEL_IDX
)
1141 : (asi
& 1 ? MMU_USER_SECONDARY_IDX
: MMU_USER_IDX
));
1143 if (cpu_get_phys_page_nofault(env
, addr
, idx
) == -1ULL) {
1145 dump_asi("read ", last_addr
, asi
, size
, ret
);
1147 /* exception_index is set in get_physical_address_data. */
1148 cpu_raise_exception_ra(env
, cs
->exception_index
, GETPC());
1150 oi
= make_memop_idx(memop
, idx
);
1153 ret
= helper_ret_ldub_mmu(env
, addr
, oi
, GETPC());
1157 ret
= helper_le_lduw_mmu(env
, addr
, oi
, GETPC());
1159 ret
= helper_be_lduw_mmu(env
, addr
, oi
, GETPC());
1164 ret
= helper_le_ldul_mmu(env
, addr
, oi
, GETPC());
1166 ret
= helper_be_ldul_mmu(env
, addr
, oi
, GETPC());
1171 ret
= helper_le_ldq_mmu(env
, addr
, oi
, GETPC());
1173 ret
= helper_be_ldq_mmu(env
, addr
, oi
, GETPC());
1177 g_assert_not_reached();
1182 case ASI_AIUP
: /* As if user primary */
1183 case ASI_AIUS
: /* As if user secondary */
1184 case ASI_AIUPL
: /* As if user primary LE */
1185 case ASI_AIUSL
: /* As if user secondary LE */
1186 case ASI_P
: /* Primary */
1187 case ASI_S
: /* Secondary */
1188 case ASI_PL
: /* Primary LE */
1189 case ASI_SL
: /* Secondary LE */
1190 case ASI_REAL
: /* Bypass */
1191 case ASI_REAL_IO
: /* Bypass, non-cacheable */
1192 case ASI_REAL_L
: /* Bypass LE */
1193 case ASI_REAL_IO_L
: /* Bypass, non-cacheable LE */
1194 case ASI_N
: /* Nucleus */
1195 case ASI_NL
: /* Nucleus Little Endian (LE) */
1196 case ASI_NUCLEUS_QUAD_LDD
: /* Nucleus quad LDD 128 bit atomic */
1197 case ASI_NUCLEUS_QUAD_LDD_L
: /* Nucleus quad LDD 128 bit atomic LE */
1198 case ASI_TWINX_AIUP
: /* As if user primary, twinx */
1199 case ASI_TWINX_AIUS
: /* As if user secondary, twinx */
1200 case ASI_TWINX_REAL
: /* Real address, twinx */
1201 case ASI_TWINX_AIUP_L
: /* As if user primary, twinx, LE */
1202 case ASI_TWINX_AIUS_L
: /* As if user secondary, twinx, LE */
1203 case ASI_TWINX_REAL_L
: /* Real address, twinx, LE */
1204 case ASI_TWINX_N
: /* Nucleus, twinx */
1205 case ASI_TWINX_NL
: /* Nucleus, twinx, LE */
1206 /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
1207 case ASI_TWINX_P
: /* Primary, twinx */
1208 case ASI_TWINX_PL
: /* Primary, twinx, LE */
1209 case ASI_TWINX_S
: /* Secondary, twinx */
1210 case ASI_TWINX_SL
: /* Secondary, twinx, LE */
1211 /* These are always handled inline. */
1212 g_assert_not_reached();
1214 case ASI_UPA_CONFIG
: /* UPA config */
1217 case ASI_LSU_CONTROL
: /* LSU */
1220 case ASI_IMMU
: /* I-MMU regs */
1222 int reg
= (addr
>> 3) & 0xf;
1225 /* I-TSB Tag Target register */
1226 ret
= ultrasparc_tag_target(env
->immu
.tag_access
);
1228 ret
= env
->immuregs
[reg
];
1233 case ASI_IMMU_TSB_8KB_PTR
: /* I-MMU 8k TSB pointer */
1235 /* env->immuregs[5] holds I-MMU TSB register value
1236 env->immuregs[6] holds I-MMU Tag Access register value */
1237 ret
= ultrasparc_tsb_pointer(env
->immu
.tsb
, env
->immu
.tag_access
,
1241 case ASI_IMMU_TSB_64KB_PTR
: /* I-MMU 64k TSB pointer */
1243 /* env->immuregs[5] holds I-MMU TSB register value
1244 env->immuregs[6] holds I-MMU Tag Access register value */
1245 ret
= ultrasparc_tsb_pointer(env
->immu
.tsb
, env
->immu
.tag_access
,
1249 case ASI_ITLB_DATA_ACCESS
: /* I-MMU data access */
1251 int reg
= (addr
>> 3) & 0x3f;
1253 ret
= env
->itlb
[reg
].tte
;
1256 case ASI_ITLB_TAG_READ
: /* I-MMU tag read */
1258 int reg
= (addr
>> 3) & 0x3f;
1260 ret
= env
->itlb
[reg
].tag
;
1263 case ASI_DMMU
: /* D-MMU regs */
1265 int reg
= (addr
>> 3) & 0xf;
1268 /* D-TSB Tag Target register */
1269 ret
= ultrasparc_tag_target(env
->dmmu
.tag_access
);
1271 ret
= env
->dmmuregs
[reg
];
1275 case ASI_DMMU_TSB_8KB_PTR
: /* D-MMU 8k TSB pointer */
1277 /* env->dmmuregs[5] holds D-MMU TSB register value
1278 env->dmmuregs[6] holds D-MMU Tag Access register value */
1279 ret
= ultrasparc_tsb_pointer(env
->dmmu
.tsb
, env
->dmmu
.tag_access
,
1283 case ASI_DMMU_TSB_64KB_PTR
: /* D-MMU 64k TSB pointer */
1285 /* env->dmmuregs[5] holds D-MMU TSB register value
1286 env->dmmuregs[6] holds D-MMU Tag Access register value */
1287 ret
= ultrasparc_tsb_pointer(env
->dmmu
.tsb
, env
->dmmu
.tag_access
,
1291 case ASI_DTLB_DATA_ACCESS
: /* D-MMU data access */
1293 int reg
= (addr
>> 3) & 0x3f;
1295 ret
= env
->dtlb
[reg
].tte
;
1298 case ASI_DTLB_TAG_READ
: /* D-MMU tag read */
1300 int reg
= (addr
>> 3) & 0x3f;
1302 ret
= env
->dtlb
[reg
].tag
;
1305 case ASI_INTR_DISPATCH_STAT
: /* Interrupt dispatch, RO */
1307 case ASI_INTR_RECEIVE
: /* Interrupt data receive */
1308 ret
= env
->ivec_status
;
1310 case ASI_INTR_R
: /* Incoming interrupt vector, RO */
1312 int reg
= (addr
>> 4) & 0x3;
1314 ret
= env
->ivec_data
[reg
];
1318 case ASI_DCACHE_DATA
: /* D-cache data */
1319 case ASI_DCACHE_TAG
: /* D-cache tag access */
1320 case ASI_ESTATE_ERROR_EN
: /* E-cache error enable */
1321 case ASI_AFSR
: /* E-cache asynchronous fault status */
1322 case ASI_AFAR
: /* E-cache asynchronous fault address */
1323 case ASI_EC_TAG_DATA
: /* E-cache tag data */
1324 case ASI_IC_INSTR
: /* I-cache instruction access */
1325 case ASI_IC_TAG
: /* I-cache tag access */
1326 case ASI_IC_PRE_DECODE
: /* I-cache predecode */
1327 case ASI_IC_NEXT_FIELD
: /* I-cache LRU etc. */
1328 case ASI_EC_W
: /* E-cache tag */
1329 case ASI_EC_R
: /* E-cache tag */
1331 case ASI_DMMU_TSB_DIRECT_PTR
: /* D-MMU data pointer */
1332 case ASI_ITLB_DATA_IN
: /* I-MMU data in, WO */
1333 case ASI_IMMU_DEMAP
: /* I-MMU demap, WO */
1334 case ASI_DTLB_DATA_IN
: /* D-MMU data in, WO */
1335 case ASI_DMMU_DEMAP
: /* D-MMU demap, WO */
1336 case ASI_INTR_W
: /* Interrupt vector, WO */
1338 cpu_unassigned_access(cs
, addr
, false, false, 1, size
);
1343 /* Convert to signed number */
1350 ret
= (int16_t) ret
;
1353 ret
= (int32_t) ret
;
1360 dump_asi("read ", last_addr
, asi
, size
, ret
);
1365 void helper_st_asi(CPUSPARCState
*env
, target_ulong addr
, target_ulong val
,
1366 int asi
, uint32_t memop
)
1368 int size
= 1 << (memop
& MO_SIZE
);
1369 SPARCCPU
*cpu
= sparc_env_get_cpu(env
);
1370 CPUState
*cs
= CPU(cpu
);
1373 dump_asi("write", addr
, asi
, size
, val
);
1378 if ((asi
< 0x80 && (env
->pstate
& PS_PRIV
) == 0)
1379 || (cpu_has_hypervisor(env
)
1380 && asi
>= 0x30 && asi
< 0x80
1381 && !(env
->hpstate
& HS_PRIV
))) {
1382 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
1385 do_check_align(env
, addr
, size
- 1, GETPC());
1386 addr
= asi_address_mask(env
, asi
, addr
);
1389 case ASI_AIUP
: /* As if user primary */
1390 case ASI_AIUS
: /* As if user secondary */
1391 case ASI_AIUPL
: /* As if user primary LE */
1392 case ASI_AIUSL
: /* As if user secondary LE */
1393 case ASI_P
: /* Primary */
1394 case ASI_S
: /* Secondary */
1395 case ASI_PL
: /* Primary LE */
1396 case ASI_SL
: /* Secondary LE */
1397 case ASI_REAL
: /* Bypass */
1398 case ASI_REAL_IO
: /* Bypass, non-cacheable */
1399 case ASI_REAL_L
: /* Bypass LE */
1400 case ASI_REAL_IO_L
: /* Bypass, non-cacheable LE */
1401 case ASI_N
: /* Nucleus */
1402 case ASI_NL
: /* Nucleus Little Endian (LE) */
1403 case ASI_NUCLEUS_QUAD_LDD
: /* Nucleus quad LDD 128 bit atomic */
1404 case ASI_NUCLEUS_QUAD_LDD_L
: /* Nucleus quad LDD 128 bit atomic LE */
1405 case ASI_TWINX_AIUP
: /* As if user primary, twinx */
1406 case ASI_TWINX_AIUS
: /* As if user secondary, twinx */
1407 case ASI_TWINX_REAL
: /* Real address, twinx */
1408 case ASI_TWINX_AIUP_L
: /* As if user primary, twinx, LE */
1409 case ASI_TWINX_AIUS_L
: /* As if user secondary, twinx, LE */
1410 case ASI_TWINX_REAL_L
: /* Real address, twinx, LE */
1411 case ASI_TWINX_N
: /* Nucleus, twinx */
1412 case ASI_TWINX_NL
: /* Nucleus, twinx, LE */
1413 /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
1414 case ASI_TWINX_P
: /* Primary, twinx */
1415 case ASI_TWINX_PL
: /* Primary, twinx, LE */
1416 case ASI_TWINX_S
: /* Secondary, twinx */
1417 case ASI_TWINX_SL
: /* Secondary, twinx, LE */
1418 /* These are always handled inline. */
1419 g_assert_not_reached();
1421 case ASI_UPA_CONFIG
: /* UPA config */
1424 case ASI_LSU_CONTROL
: /* LSU */
1425 env
->lsu
= val
& (DMMU_E
| IMMU_E
);
1427 case ASI_IMMU
: /* I-MMU regs */
1429 int reg
= (addr
>> 3) & 0xf;
1432 oldreg
= env
->immuregs
[reg
];
1436 case 1: /* Not in I-MMU */
1440 if ((val
& 1) == 0) {
1441 val
= 0; /* Clear SFSR */
1443 env
->immu
.sfsr
= val
;
1447 case 5: /* TSB access */
1448 DPRINTF_MMU("immu TSB write: 0x%016" PRIx64
" -> 0x%016"
1449 PRIx64
"\n", env
->immu
.tsb
, val
);
1450 env
->immu
.tsb
= val
;
1452 case 6: /* Tag access */
1453 env
->immu
.tag_access
= val
;
1462 if (oldreg
!= env
->immuregs
[reg
]) {
1463 DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64
" -> 0x%016"
1464 PRIx64
"\n", reg
, oldreg
, env
->immuregs
[reg
]);
1467 dump_mmu(stdout
, fprintf
, env
);
1471 case ASI_ITLB_DATA_IN
: /* I-MMU data in */
1472 replace_tlb_1bit_lru(env
->itlb
, env
->immu
.tag_access
, val
, "immu", env
);
1474 case ASI_ITLB_DATA_ACCESS
: /* I-MMU data access */
1476 /* TODO: auto demap */
1478 unsigned int i
= (addr
>> 3) & 0x3f;
1480 replace_tlb_entry(&env
->itlb
[i
], env
->immu
.tag_access
, val
, env
);
1483 DPRINTF_MMU("immu data access replaced entry [%i]\n", i
);
1484 dump_mmu(stdout
, fprintf
, env
);
1488 case ASI_IMMU_DEMAP
: /* I-MMU demap */
1489 demap_tlb(env
->itlb
, addr
, "immu", env
);
1491 case ASI_DMMU
: /* D-MMU regs */
1493 int reg
= (addr
>> 3) & 0xf;
1496 oldreg
= env
->dmmuregs
[reg
];
1502 if ((val
& 1) == 0) {
1503 val
= 0; /* Clear SFSR, Fault address */
1506 env
->dmmu
.sfsr
= val
;
1508 case 1: /* Primary context */
1509 env
->dmmu
.mmu_primary_context
= val
;
1510 /* can be optimized to only flush MMU_USER_IDX
1511 and MMU_KERNEL_IDX entries */
1512 tlb_flush(CPU(cpu
), 1);
1514 case 2: /* Secondary context */
1515 env
->dmmu
.mmu_secondary_context
= val
;
1516 /* can be optimized to only flush MMU_USER_SECONDARY_IDX
1517 and MMU_KERNEL_SECONDARY_IDX entries */
1518 tlb_flush(CPU(cpu
), 1);
1520 case 5: /* TSB access */
1521 DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64
" -> 0x%016"
1522 PRIx64
"\n", env
->dmmu
.tsb
, val
);
1523 env
->dmmu
.tsb
= val
;
1525 case 6: /* Tag access */
1526 env
->dmmu
.tag_access
= val
;
1528 case 7: /* Virtual Watchpoint */
1529 case 8: /* Physical Watchpoint */
1531 env
->dmmuregs
[reg
] = val
;
1535 if (oldreg
!= env
->dmmuregs
[reg
]) {
1536 DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64
" -> 0x%016"
1537 PRIx64
"\n", reg
, oldreg
, env
->dmmuregs
[reg
]);
1540 dump_mmu(stdout
, fprintf
, env
);
1544 case ASI_DTLB_DATA_IN
: /* D-MMU data in */
1545 replace_tlb_1bit_lru(env
->dtlb
, env
->dmmu
.tag_access
, val
, "dmmu", env
);
1547 case ASI_DTLB_DATA_ACCESS
: /* D-MMU data access */
1549 unsigned int i
= (addr
>> 3) & 0x3f;
1551 replace_tlb_entry(&env
->dtlb
[i
], env
->dmmu
.tag_access
, val
, env
);
1554 DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i
);
1555 dump_mmu(stdout
, fprintf
, env
);
1559 case ASI_DMMU_DEMAP
: /* D-MMU demap */
1560 demap_tlb(env
->dtlb
, addr
, "dmmu", env
);
1562 case ASI_INTR_RECEIVE
: /* Interrupt data receive */
1563 env
->ivec_status
= val
& 0x20;
1565 case ASI_DCACHE_DATA
: /* D-cache data */
1566 case ASI_DCACHE_TAG
: /* D-cache tag access */
1567 case ASI_ESTATE_ERROR_EN
: /* E-cache error enable */
1568 case ASI_AFSR
: /* E-cache asynchronous fault status */
1569 case ASI_AFAR
: /* E-cache asynchronous fault address */
1570 case ASI_EC_TAG_DATA
: /* E-cache tag data */
1571 case ASI_IC_INSTR
: /* I-cache instruction access */
1572 case ASI_IC_TAG
: /* I-cache tag access */
1573 case ASI_IC_PRE_DECODE
: /* I-cache predecode */
1574 case ASI_IC_NEXT_FIELD
: /* I-cache LRU etc. */
1575 case ASI_EC_W
: /* E-cache tag */
1576 case ASI_EC_R
: /* E-cache tag */
1578 case ASI_IMMU_TSB_8KB_PTR
: /* I-MMU 8k TSB pointer, RO */
1579 case ASI_IMMU_TSB_64KB_PTR
: /* I-MMU 64k TSB pointer, RO */
1580 case ASI_ITLB_TAG_READ
: /* I-MMU tag read, RO */
1581 case ASI_DMMU_TSB_8KB_PTR
: /* D-MMU 8k TSB pointer, RO */
1582 case ASI_DMMU_TSB_64KB_PTR
: /* D-MMU 64k TSB pointer, RO */
1583 case ASI_DMMU_TSB_DIRECT_PTR
: /* D-MMU data pointer, RO */
1584 case ASI_DTLB_TAG_READ
: /* D-MMU tag read, RO */
1585 case ASI_INTR_DISPATCH_STAT
: /* Interrupt dispatch, RO */
1586 case ASI_INTR_R
: /* Incoming interrupt vector, RO */
1587 case ASI_PNF
: /* Primary no-fault, RO */
1588 case ASI_SNF
: /* Secondary no-fault, RO */
1589 case ASI_PNFL
: /* Primary no-fault LE, RO */
1590 case ASI_SNFL
: /* Secondary no-fault LE, RO */
1592 cpu_unassigned_access(cs
, addr
, true, false, 1, size
);
1596 #endif /* CONFIG_USER_ONLY */
1597 #endif /* TARGET_SPARC64 */
1599 #if !defined(CONFIG_USER_ONLY)
1600 #ifndef TARGET_SPARC64
1601 void sparc_cpu_unassigned_access(CPUState
*cs
, hwaddr addr
,
1602 bool is_write
, bool is_exec
, int is_asi
,
1605 SPARCCPU
*cpu
= SPARC_CPU(cs
);
1606 CPUSPARCState
*env
= &cpu
->env
;
1609 #ifdef DEBUG_UNASSIGNED
1611 printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
1612 " asi 0x%02x from " TARGET_FMT_lx
"\n",
1613 is_exec
? "exec" : is_write
? "write" : "read", size
,
1614 size
== 1 ? "" : "s", addr
, is_asi
, env
->pc
);
1616 printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
1617 " from " TARGET_FMT_lx
"\n",
1618 is_exec
? "exec" : is_write
? "write" : "read", size
,
1619 size
== 1 ? "" : "s", addr
, env
->pc
);
1622 /* Don't overwrite translation and access faults */
1623 fault_type
= (env
->mmuregs
[3] & 0x1c) >> 2;
1624 if ((fault_type
> 4) || (fault_type
== 0)) {
1625 env
->mmuregs
[3] = 0; /* Fault status register */
1627 env
->mmuregs
[3] |= 1 << 16;
1630 env
->mmuregs
[3] |= 1 << 5;
1633 env
->mmuregs
[3] |= 1 << 6;
1636 env
->mmuregs
[3] |= 1 << 7;
1638 env
->mmuregs
[3] |= (5 << 2) | 2;
1639 /* SuperSPARC will never place instruction fault addresses in the FAR */
1641 env
->mmuregs
[4] = addr
; /* Fault address register */
1644 /* overflow (same type fault was not read before another fault) */
1645 if (fault_type
== ((env
->mmuregs
[3] & 0x1c)) >> 2) {
1646 env
->mmuregs
[3] |= 1;
1649 if ((env
->mmuregs
[0] & MMU_E
) && !(env
->mmuregs
[0] & MMU_NF
)) {
1650 int tt
= is_exec
? TT_CODE_ACCESS
: TT_DATA_ACCESS
;
1651 cpu_raise_exception_ra(env
, tt
, GETPC());
1654 /* flush neverland mappings created during no-fault mode,
1655 so the sequential MMU faults report proper fault types */
1656 if (env
->mmuregs
[0] & MMU_NF
) {
1661 void sparc_cpu_unassigned_access(CPUState
*cs
, hwaddr addr
,
1662 bool is_write
, bool is_exec
, int is_asi
,
1665 SPARCCPU
*cpu
= SPARC_CPU(cs
);
1666 CPUSPARCState
*env
= &cpu
->env
;
1667 int tt
= is_exec
? TT_CODE_ACCESS
: TT_DATA_ACCESS
;
1669 #ifdef DEBUG_UNASSIGNED
1670 printf("Unassigned mem access to " TARGET_FMT_plx
" from " TARGET_FMT_lx
1671 "\n", addr
, env
->pc
);
1674 cpu_raise_exception_ra(env
, tt
, GETPC());
1679 #if !defined(CONFIG_USER_ONLY)
1680 void QEMU_NORETURN
sparc_cpu_do_unaligned_access(CPUState
*cs
, vaddr addr
,
1681 MMUAccessType access_type
,
1685 SPARCCPU
*cpu
= SPARC_CPU(cs
);
1686 CPUSPARCState
*env
= &cpu
->env
;
1688 #ifdef DEBUG_UNALIGNED
1689 printf("Unaligned access to 0x" TARGET_FMT_lx
" from 0x" TARGET_FMT_lx
1690 "\n", addr
, env
->pc
);
1692 cpu_raise_exception_ra(env
, TT_UNALIGNED
, retaddr
);
1695 /* try to fill the TLB and return an exception if error. If retaddr is
1696 NULL, it means that the function was called in C code (i.e. not
1697 from generated code or from helper.c) */
1698 /* XXX: fix it to restore all registers */
1699 void tlb_fill(CPUState
*cs
, target_ulong addr
, MMUAccessType access_type
,
1700 int mmu_idx
, uintptr_t retaddr
)
1704 ret
= sparc_cpu_handle_mmu_fault(cs
, addr
, access_type
, mmu_idx
);
1706 cpu_loop_exit_restore(cs
, retaddr
);