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 size
= 8192ULL << 3 * TTE_PGSIZE(tlb
->tte
);
133 va
= tlb
->tag
& mask
;
135 for (offset
= 0; offset
< size
; offset
+= TARGET_PAGE_SIZE
) {
136 tlb_flush_page(cs
, va
+ offset
);
144 static void demap_tlb(SparcTLBEntry
*tlb
, target_ulong demap_addr
,
145 const char *strmmu
, CPUSPARCState
*env1
)
151 int is_demap_context
= (demap_addr
>> 6) & 1;
154 switch ((demap_addr
>> 4) & 3) {
155 case 0: /* primary */
156 context
= env1
->dmmu
.mmu_primary_context
;
158 case 1: /* secondary */
159 context
= env1
->dmmu
.mmu_secondary_context
;
161 case 2: /* nucleus */
164 case 3: /* reserved */
169 for (i
= 0; i
< 64; i
++) {
170 if (TTE_IS_VALID(tlb
[i
].tte
)) {
172 if (is_demap_context
) {
173 /* will remove non-global entries matching context value */
174 if (TTE_IS_GLOBAL(tlb
[i
].tte
) ||
175 !tlb_compare_context(&tlb
[i
], context
)) {
180 will remove any entry matching VA */
181 mask
= 0xffffffffffffe000ULL
;
182 mask
<<= 3 * ((tlb
[i
].tte
>> 61) & 3);
184 if (!compare_masked(demap_addr
, tlb
[i
].tag
, mask
)) {
188 /* entry should be global or matching context value */
189 if (!TTE_IS_GLOBAL(tlb
[i
].tte
) &&
190 !tlb_compare_context(&tlb
[i
], context
)) {
195 replace_tlb_entry(&tlb
[i
], 0, 0, env1
);
197 DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu
, i
);
198 dump_mmu(stdout
, fprintf
, env1
);
204 static void replace_tlb_1bit_lru(SparcTLBEntry
*tlb
,
205 uint64_t tlb_tag
, uint64_t tlb_tte
,
206 const char *strmmu
, CPUSPARCState
*env1
)
208 unsigned int i
, replace_used
;
210 /* Try replacing invalid entry */
211 for (i
= 0; i
< 64; i
++) {
212 if (!TTE_IS_VALID(tlb
[i
].tte
)) {
213 replace_tlb_entry(&tlb
[i
], tlb_tag
, tlb_tte
, env1
);
215 DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu
, i
);
216 dump_mmu(stdout
, fprintf
, env1
);
222 /* All entries are valid, try replacing unlocked entry */
224 for (replace_used
= 0; replace_used
< 2; ++replace_used
) {
226 /* Used entries are not replaced on first pass */
228 for (i
= 0; i
< 64; i
++) {
229 if (!TTE_IS_LOCKED(tlb
[i
].tte
) && !TTE_IS_USED(tlb
[i
].tte
)) {
231 replace_tlb_entry(&tlb
[i
], tlb_tag
, tlb_tte
, env1
);
233 DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
234 strmmu
, (replace_used
? "used" : "unused"), i
);
235 dump_mmu(stdout
, fprintf
, env1
);
241 /* Now reset used bit and search for unused entries again */
243 for (i
= 0; i
< 64; i
++) {
244 TTE_SET_UNUSED(tlb
[i
].tte
);
249 DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu
);
256 #ifdef TARGET_SPARC64
257 /* returns true if access using this ASI is to have address translated by MMU
258 otherwise access is to raw physical address */
259 /* TODO: check sparc32 bits */
260 static inline int is_translating_asi(int asi
)
262 /* Ultrasparc IIi translating asi
263 - note this list is defined by cpu implementation
280 static inline target_ulong
address_mask(CPUSPARCState
*env1
, target_ulong addr
)
282 if (AM_CHECK(env1
)) {
283 addr
&= 0xffffffffULL
;
288 static inline target_ulong
asi_address_mask(CPUSPARCState
*env
,
289 int asi
, target_ulong addr
)
291 if (is_translating_asi(asi
)) {
292 addr
= address_mask(env
, addr
);
298 static void do_check_align(CPUSPARCState
*env
, target_ulong addr
,
299 uint32_t align
, uintptr_t ra
)
302 #ifdef DEBUG_UNALIGNED
303 printf("Unaligned access to 0x" TARGET_FMT_lx
" from 0x" TARGET_FMT_lx
304 "\n", addr
, env
->pc
);
306 cpu_raise_exception_ra(env
, TT_UNALIGNED
, ra
);
310 void helper_check_align(CPUSPARCState
*env
, target_ulong addr
, uint32_t align
)
312 do_check_align(env
, addr
, align
, GETPC());
315 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
317 static void dump_mxcc(CPUSPARCState
*env
)
319 printf("mxccdata: %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016" PRIx64
321 env
->mxccdata
[0], env
->mxccdata
[1],
322 env
->mxccdata
[2], env
->mxccdata
[3]);
323 printf("mxccregs: %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016" PRIx64
325 " %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016" PRIx64
327 env
->mxccregs
[0], env
->mxccregs
[1],
328 env
->mxccregs
[2], env
->mxccregs
[3],
329 env
->mxccregs
[4], env
->mxccregs
[5],
330 env
->mxccregs
[6], env
->mxccregs
[7]);
334 #if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
335 && defined(DEBUG_ASI)
336 static void dump_asi(const char *txt
, target_ulong addr
, int asi
, int size
,
341 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %02" PRIx64
"\n", txt
,
342 addr
, asi
, r1
& 0xff);
345 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %04" PRIx64
"\n", txt
,
346 addr
, asi
, r1
& 0xffff);
349 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %08" PRIx64
"\n", txt
,
350 addr
, asi
, r1
& 0xffffffff);
353 DPRINTF_ASI("%s "TARGET_FMT_lx
" asi 0x%02x = %016" PRIx64
"\n", txt
,
360 #ifndef TARGET_SPARC64
361 #ifndef CONFIG_USER_ONLY
364 /* Leon3 cache control */
366 static void leon3_cache_control_st(CPUSPARCState
*env
, target_ulong addr
,
367 uint64_t val
, int size
)
369 DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64
", size:%d\n",
373 DPRINTF_CACHE_CONTROL("32bits only\n");
378 case 0x00: /* Cache control */
380 /* These values must always be read as zeros */
381 val
&= ~CACHE_CTRL_FD
;
382 val
&= ~CACHE_CTRL_FI
;
383 val
&= ~CACHE_CTRL_IB
;
384 val
&= ~CACHE_CTRL_IP
;
385 val
&= ~CACHE_CTRL_DP
;
387 env
->cache_control
= val
;
389 case 0x04: /* Instruction cache configuration */
390 case 0x08: /* Data cache configuration */
394 DPRINTF_CACHE_CONTROL("write unknown register %08x\n", addr
);
399 static uint64_t leon3_cache_control_ld(CPUSPARCState
*env
, target_ulong addr
,
405 DPRINTF_CACHE_CONTROL("32bits only\n");
410 case 0x00: /* Cache control */
411 ret
= env
->cache_control
;
414 /* Configuration registers are read and only always keep those
417 case 0x04: /* Instruction cache configuration */
420 case 0x08: /* Data cache configuration */
424 DPRINTF_CACHE_CONTROL("read unknown register %08x\n", addr
);
427 DPRINTF_CACHE_CONTROL("ld addr:%08x, ret:0x%" PRIx64
", size:%d\n",
432 uint64_t helper_ld_asi(CPUSPARCState
*env
, target_ulong addr
,
433 int asi
, uint32_t memop
)
435 int size
= 1 << (memop
& MO_SIZE
);
436 int sign
= memop
& MO_SIGN
;
437 CPUState
*cs
= CPU(sparc_env_get_cpu(env
));
439 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
440 uint32_t last_addr
= addr
;
443 do_check_align(env
, addr
, size
- 1, GETPC());
445 case ASI_M_MXCC
: /* SuperSparc MXCC registers, or... */
446 /* case ASI_LEON_CACHEREGS: Leon3 cache control */
448 case 0x00: /* Leon3 Cache Control */
449 case 0x08: /* Leon3 Instruction Cache config */
450 case 0x0C: /* Leon3 Date Cache config */
451 if (env
->def
->features
& CPU_FEATURE_CACHE_CTRL
) {
452 ret
= leon3_cache_control_ld(env
, addr
, size
);
455 case 0x01c00a00: /* MXCC control register */
457 ret
= env
->mxccregs
[3];
459 qemu_log_mask(LOG_UNIMP
,
460 "%08x: unimplemented access size: %d\n", addr
,
464 case 0x01c00a04: /* MXCC control register */
466 ret
= env
->mxccregs
[3];
468 qemu_log_mask(LOG_UNIMP
,
469 "%08x: unimplemented access size: %d\n", addr
,
473 case 0x01c00c00: /* Module reset register */
475 ret
= env
->mxccregs
[5];
476 /* should we do something here? */
478 qemu_log_mask(LOG_UNIMP
,
479 "%08x: unimplemented access size: %d\n", addr
,
483 case 0x01c00f00: /* MBus port address register */
485 ret
= env
->mxccregs
[7];
487 qemu_log_mask(LOG_UNIMP
,
488 "%08x: unimplemented access size: %d\n", addr
,
493 qemu_log_mask(LOG_UNIMP
,
494 "%08x: unimplemented address, size: %d\n", addr
,
498 DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
499 "addr = %08x -> ret = %" PRIx64
","
500 "addr = %08x\n", asi
, size
, sign
, last_addr
, ret
, addr
);
505 case ASI_M_FLUSH_PROBE
: /* SuperSparc MMU probe */
506 case ASI_LEON_MMUFLUSH
: /* LEON3 MMU probe */
510 mmulev
= (addr
>> 8) & 15;
514 ret
= mmu_probe(env
, addr
, mmulev
);
516 DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64
"\n",
520 case ASI_M_MMUREGS
: /* SuperSparc MMU regs */
521 case ASI_LEON_MMUREGS
: /* LEON3 MMU regs */
523 int reg
= (addr
>> 8) & 0x1f;
525 ret
= env
->mmuregs
[reg
];
526 if (reg
== 3) { /* Fault status cleared on read */
528 } else if (reg
== 0x13) { /* Fault status read */
529 ret
= env
->mmuregs
[3];
530 } else if (reg
== 0x14) { /* Fault address read */
531 ret
= env
->mmuregs
[4];
533 DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64
"\n", reg
, ret
);
536 case ASI_M_TLBDIAG
: /* Turbosparc ITLB Diagnostic */
537 case ASI_M_DIAGS
: /* Turbosparc DTLB Diagnostic */
538 case ASI_M_IODIAG
: /* Turbosparc IOTLB Diagnostic */
540 case ASI_KERNELTXT
: /* Supervisor code access */
543 ret
= cpu_ldub_code(env
, addr
);
546 ret
= cpu_lduw_code(env
, addr
);
550 ret
= cpu_ldl_code(env
, addr
);
553 ret
= cpu_ldq_code(env
, addr
);
557 case ASI_M_TXTC_TAG
: /* SparcStation 5 I-cache tag */
558 case ASI_M_TXTC_DATA
: /* SparcStation 5 I-cache data */
559 case ASI_M_DATAC_TAG
: /* SparcStation 5 D-cache tag */
560 case ASI_M_DATAC_DATA
: /* SparcStation 5 D-cache data */
562 case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
565 ret
= ldub_phys(cs
->as
, (hwaddr
)addr
566 | ((hwaddr
)(asi
& 0xf) << 32));
569 ret
= lduw_phys(cs
->as
, (hwaddr
)addr
570 | ((hwaddr
)(asi
& 0xf) << 32));
574 ret
= ldl_phys(cs
->as
, (hwaddr
)addr
575 | ((hwaddr
)(asi
& 0xf) << 32));
578 ret
= ldq_phys(cs
->as
, (hwaddr
)addr
579 | ((hwaddr
)(asi
& 0xf) << 32));
583 case 0x30: /* Turbosparc secondary cache diagnostic */
584 case 0x31: /* Turbosparc RAM snoop */
585 case 0x32: /* Turbosparc page table descriptor diagnostic */
586 case 0x39: /* data cache diagnostic register */
589 case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
591 int reg
= (addr
>> 8) & 3;
594 case 0: /* Breakpoint Value (Addr) */
595 ret
= env
->mmubpregs
[reg
];
597 case 1: /* Breakpoint Mask */
598 ret
= env
->mmubpregs
[reg
];
600 case 2: /* Breakpoint Control */
601 ret
= env
->mmubpregs
[reg
];
603 case 3: /* Breakpoint Status */
604 ret
= env
->mmubpregs
[reg
];
605 env
->mmubpregs
[reg
] = 0ULL;
608 DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64
"\n", reg
,
612 case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
613 ret
= env
->mmubpctrv
;
615 case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
616 ret
= env
->mmubpctrc
;
618 case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
619 ret
= env
->mmubpctrs
;
621 case 0x4c: /* SuperSPARC MMU Breakpoint Action */
622 ret
= env
->mmubpaction
;
624 case ASI_USERTXT
: /* User code access, XXX */
626 cpu_unassigned_access(cs
, addr
, false, false, asi
, size
);
630 case ASI_USERDATA
: /* User data access */
631 case ASI_KERNELDATA
: /* Supervisor data access */
632 case ASI_P
: /* Implicit primary context data access (v9 only?) */
633 case ASI_M_BYPASS
: /* MMU passthrough */
634 case ASI_LEON_BYPASS
: /* LEON MMU passthrough */
635 /* These are always handled inline. */
636 g_assert_not_reached();
654 dump_asi("read ", last_addr
, asi
, size
, ret
);
659 void helper_st_asi(CPUSPARCState
*env
, target_ulong addr
, uint64_t val
,
660 int asi
, uint32_t memop
)
662 int size
= 1 << (memop
& MO_SIZE
);
663 SPARCCPU
*cpu
= sparc_env_get_cpu(env
);
664 CPUState
*cs
= CPU(cpu
);
666 do_check_align(env
, addr
, size
- 1, GETPC());
668 case ASI_M_MXCC
: /* SuperSparc MXCC registers, or... */
669 /* case ASI_LEON_CACHEREGS: Leon3 cache control */
671 case 0x00: /* Leon3 Cache Control */
672 case 0x08: /* Leon3 Instruction Cache config */
673 case 0x0C: /* Leon3 Date Cache config */
674 if (env
->def
->features
& CPU_FEATURE_CACHE_CTRL
) {
675 leon3_cache_control_st(env
, addr
, val
, size
);
679 case 0x01c00000: /* MXCC stream data register 0 */
681 env
->mxccdata
[0] = val
;
683 qemu_log_mask(LOG_UNIMP
,
684 "%08x: unimplemented access size: %d\n", addr
,
688 case 0x01c00008: /* MXCC stream data register 1 */
690 env
->mxccdata
[1] = val
;
692 qemu_log_mask(LOG_UNIMP
,
693 "%08x: unimplemented access size: %d\n", addr
,
697 case 0x01c00010: /* MXCC stream data register 2 */
699 env
->mxccdata
[2] = val
;
701 qemu_log_mask(LOG_UNIMP
,
702 "%08x: unimplemented access size: %d\n", addr
,
706 case 0x01c00018: /* MXCC stream data register 3 */
708 env
->mxccdata
[3] = val
;
710 qemu_log_mask(LOG_UNIMP
,
711 "%08x: unimplemented access size: %d\n", addr
,
715 case 0x01c00100: /* MXCC stream source */
717 env
->mxccregs
[0] = val
;
719 qemu_log_mask(LOG_UNIMP
,
720 "%08x: unimplemented access size: %d\n", addr
,
723 env
->mxccdata
[0] = ldq_phys(cs
->as
,
724 (env
->mxccregs
[0] & 0xffffffffULL
) +
726 env
->mxccdata
[1] = ldq_phys(cs
->as
,
727 (env
->mxccregs
[0] & 0xffffffffULL
) +
729 env
->mxccdata
[2] = ldq_phys(cs
->as
,
730 (env
->mxccregs
[0] & 0xffffffffULL
) +
732 env
->mxccdata
[3] = ldq_phys(cs
->as
,
733 (env
->mxccregs
[0] & 0xffffffffULL
) +
736 case 0x01c00200: /* MXCC stream destination */
738 env
->mxccregs
[1] = val
;
740 qemu_log_mask(LOG_UNIMP
,
741 "%08x: unimplemented access size: %d\n", addr
,
744 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 0,
746 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 8,
748 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 16,
750 stq_phys(cs
->as
, (env
->mxccregs
[1] & 0xffffffffULL
) + 24,
753 case 0x01c00a00: /* MXCC control register */
755 env
->mxccregs
[3] = val
;
757 qemu_log_mask(LOG_UNIMP
,
758 "%08x: unimplemented access size: %d\n", addr
,
762 case 0x01c00a04: /* MXCC control register */
764 env
->mxccregs
[3] = (env
->mxccregs
[3] & 0xffffffff00000000ULL
)
767 qemu_log_mask(LOG_UNIMP
,
768 "%08x: unimplemented access size: %d\n", addr
,
772 case 0x01c00e00: /* MXCC error register */
773 /* writing a 1 bit clears the error */
775 env
->mxccregs
[6] &= ~val
;
777 qemu_log_mask(LOG_UNIMP
,
778 "%08x: unimplemented access size: %d\n", addr
,
782 case 0x01c00f00: /* MBus port address register */
784 env
->mxccregs
[7] = val
;
786 qemu_log_mask(LOG_UNIMP
,
787 "%08x: unimplemented access size: %d\n", addr
,
792 qemu_log_mask(LOG_UNIMP
,
793 "%08x: unimplemented address, size: %d\n", addr
,
797 DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64
"\n",
798 asi
, size
, addr
, val
);
803 case ASI_M_FLUSH_PROBE
: /* SuperSparc MMU flush */
804 case ASI_LEON_MMUFLUSH
: /* LEON3 MMU flush */
808 mmulev
= (addr
>> 8) & 15;
809 DPRINTF_MMU("mmu flush level %d\n", mmulev
);
811 case 0: /* flush page */
812 tlb_flush_page(CPU(cpu
), addr
& 0xfffff000);
814 case 1: /* flush segment (256k) */
815 case 2: /* flush region (16M) */
816 case 3: /* flush context (4G) */
817 case 4: /* flush entire */
824 dump_mmu(stdout
, fprintf
, env
);
828 case ASI_M_MMUREGS
: /* write MMU regs */
829 case ASI_LEON_MMUREGS
: /* LEON3 write MMU regs */
831 int reg
= (addr
>> 8) & 0x1f;
834 oldreg
= env
->mmuregs
[reg
];
836 case 0: /* Control Register */
837 env
->mmuregs
[reg
] = (env
->mmuregs
[reg
] & 0xff000000) |
839 /* Mappings generated during no-fault mode
840 are invalid in normal mode. */
841 if ((oldreg
^ env
->mmuregs
[reg
])
842 & (MMU_NF
| env
->def
->mmu_bm
)) {
846 case 1: /* Context Table Pointer Register */
847 env
->mmuregs
[reg
] = val
& env
->def
->mmu_ctpr_mask
;
849 case 2: /* Context Register */
850 env
->mmuregs
[reg
] = val
& env
->def
->mmu_cxr_mask
;
851 if (oldreg
!= env
->mmuregs
[reg
]) {
852 /* we flush when the MMU context changes because
853 QEMU has no MMU context support */
857 case 3: /* Synchronous Fault Status Register with Clear */
858 case 4: /* Synchronous Fault Address Register */
860 case 0x10: /* TLB Replacement Control Register */
861 env
->mmuregs
[reg
] = val
& env
->def
->mmu_trcr_mask
;
863 case 0x13: /* Synchronous Fault Status Register with Read
865 env
->mmuregs
[3] = val
& env
->def
->mmu_sfsr_mask
;
867 case 0x14: /* Synchronous Fault Address Register */
868 env
->mmuregs
[4] = val
;
871 env
->mmuregs
[reg
] = val
;
874 if (oldreg
!= env
->mmuregs
[reg
]) {
875 DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
876 reg
, oldreg
, env
->mmuregs
[reg
]);
879 dump_mmu(stdout
, fprintf
, env
);
883 case ASI_M_TLBDIAG
: /* Turbosparc ITLB Diagnostic */
884 case ASI_M_DIAGS
: /* Turbosparc DTLB Diagnostic */
885 case ASI_M_IODIAG
: /* Turbosparc IOTLB Diagnostic */
887 case ASI_M_TXTC_TAG
: /* I-cache tag */
888 case ASI_M_TXTC_DATA
: /* I-cache data */
889 case ASI_M_DATAC_TAG
: /* D-cache tag */
890 case ASI_M_DATAC_DATA
: /* D-cache data */
891 case ASI_M_FLUSH_PAGE
: /* I/D-cache flush page */
892 case ASI_M_FLUSH_SEG
: /* I/D-cache flush segment */
893 case ASI_M_FLUSH_REGION
: /* I/D-cache flush region */
894 case ASI_M_FLUSH_CTX
: /* I/D-cache flush context */
895 case ASI_M_FLUSH_USER
: /* I/D-cache flush user */
897 case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
901 stb_phys(cs
->as
, (hwaddr
)addr
902 | ((hwaddr
)(asi
& 0xf) << 32), val
);
905 stw_phys(cs
->as
, (hwaddr
)addr
906 | ((hwaddr
)(asi
& 0xf) << 32), val
);
910 stl_phys(cs
->as
, (hwaddr
)addr
911 | ((hwaddr
)(asi
& 0xf) << 32), val
);
914 stq_phys(cs
->as
, (hwaddr
)addr
915 | ((hwaddr
)(asi
& 0xf) << 32), val
);
920 case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
921 case 0x31: /* store buffer data, Ross RT620 I-cache flush or
922 Turbosparc snoop RAM */
923 case 0x32: /* store buffer control or Turbosparc page table
924 descriptor diagnostic */
925 case 0x36: /* I-cache flash clear */
926 case 0x37: /* D-cache flash clear */
928 case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
930 int reg
= (addr
>> 8) & 3;
933 case 0: /* Breakpoint Value (Addr) */
934 env
->mmubpregs
[reg
] = (val
& 0xfffffffffULL
);
936 case 1: /* Breakpoint Mask */
937 env
->mmubpregs
[reg
] = (val
& 0xfffffffffULL
);
939 case 2: /* Breakpoint Control */
940 env
->mmubpregs
[reg
] = (val
& 0x7fULL
);
942 case 3: /* Breakpoint Status */
943 env
->mmubpregs
[reg
] = (val
& 0xfULL
);
946 DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg
,
950 case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
951 env
->mmubpctrv
= val
& 0xffffffff;
953 case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
954 env
->mmubpctrc
= val
& 0x3;
956 case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
957 env
->mmubpctrs
= val
& 0x3;
959 case 0x4c: /* SuperSPARC MMU Breakpoint Action */
960 env
->mmubpaction
= val
& 0x1fff;
962 case ASI_USERTXT
: /* User code access, XXX */
963 case ASI_KERNELTXT
: /* Supervisor code access, XXX */
965 cpu_unassigned_access(CPU(sparc_env_get_cpu(env
)),
966 addr
, true, false, asi
, size
);
969 case ASI_USERDATA
: /* User data access */
970 case ASI_KERNELDATA
: /* Supervisor data access */
972 case ASI_M_BYPASS
: /* MMU passthrough */
973 case ASI_LEON_BYPASS
: /* LEON MMU passthrough */
974 case ASI_M_BCOPY
: /* Block copy, sta access */
975 case ASI_M_BFILL
: /* Block fill, stda access */
976 /* These are always handled inline. */
977 g_assert_not_reached();
980 dump_asi("write", addr
, asi
, size
, val
);
984 #endif /* CONFIG_USER_ONLY */
985 #else /* TARGET_SPARC64 */
987 #ifdef CONFIG_USER_ONLY
988 uint64_t helper_ld_asi(CPUSPARCState
*env
, target_ulong addr
,
989 int asi
, uint32_t memop
)
991 int size
= 1 << (memop
& MO_SIZE
);
992 int sign
= memop
& MO_SIGN
;
996 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
998 do_check_align(env
, addr
, size
- 1, GETPC());
999 addr
= asi_address_mask(env
, asi
, addr
);
1002 case ASI_PNF
: /* Primary no-fault */
1003 case ASI_PNFL
: /* Primary no-fault LE */
1004 case ASI_SNF
: /* Secondary no-fault */
1005 case ASI_SNFL
: /* Secondary no-fault LE */
1006 if (page_check_range(addr
, size
, PAGE_READ
) == -1) {
1012 ret
= cpu_ldub_data(env
, addr
);
1015 ret
= cpu_lduw_data(env
, addr
);
1018 ret
= cpu_ldl_data(env
, addr
);
1021 ret
= cpu_ldq_data(env
, addr
);
1024 g_assert_not_reached();
1029 case ASI_P
: /* Primary */
1030 case ASI_PL
: /* Primary LE */
1031 case ASI_S
: /* Secondary */
1032 case ASI_SL
: /* Secondary LE */
1033 /* These are always handled inline. */
1034 g_assert_not_reached();
1037 cpu_raise_exception_ra(env
, TT_DATA_ACCESS
, GETPC());
1040 /* Convert from little endian */
1042 case ASI_PNFL
: /* Primary no-fault LE */
1043 case ASI_SNFL
: /* Secondary no-fault LE */
1057 /* Convert to signed number */
1064 ret
= (int16_t) ret
;
1067 ret
= (int32_t) ret
;
1072 dump_asi("read", addr
, asi
, size
, ret
);
1077 void helper_st_asi(CPUSPARCState
*env
, target_ulong addr
, target_ulong val
,
1078 int asi
, uint32_t memop
)
1080 int size
= 1 << (memop
& MO_SIZE
);
1082 dump_asi("write", addr
, asi
, size
, val
);
1085 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
1087 do_check_align(env
, addr
, size
- 1, GETPC());
1090 case ASI_P
: /* Primary */
1091 case ASI_PL
: /* Primary LE */
1092 case ASI_S
: /* Secondary */
1093 case ASI_SL
: /* Secondary LE */
1094 /* These are always handled inline. */
1095 g_assert_not_reached();
1097 case ASI_PNF
: /* Primary no-fault, RO */
1098 case ASI_SNF
: /* Secondary no-fault, RO */
1099 case ASI_PNFL
: /* Primary no-fault LE, RO */
1100 case ASI_SNFL
: /* Secondary no-fault LE, RO */
1102 cpu_raise_exception_ra(env
, TT_DATA_ACCESS
, GETPC());
1106 #else /* CONFIG_USER_ONLY */
1108 uint64_t helper_ld_asi(CPUSPARCState
*env
, target_ulong addr
,
1109 int asi
, uint32_t memop
)
1111 int size
= 1 << (memop
& MO_SIZE
);
1112 int sign
= memop
& MO_SIGN
;
1113 CPUState
*cs
= CPU(sparc_env_get_cpu(env
));
1115 #if defined(DEBUG_ASI)
1116 target_ulong last_addr
= addr
;
1121 if ((asi
< 0x80 && (env
->pstate
& PS_PRIV
) == 0)
1122 || (cpu_has_hypervisor(env
)
1123 && asi
>= 0x30 && asi
< 0x80
1124 && !(env
->hpstate
& HS_PRIV
))) {
1125 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
1128 do_check_align(env
, addr
, size
- 1, GETPC());
1129 addr
= asi_address_mask(env
, asi
, addr
);
1138 int idx
= (env
->pstate
& PS_PRIV
1139 ? (asi
& 1 ? MMU_KERNEL_SECONDARY_IDX
: MMU_KERNEL_IDX
)
1140 : (asi
& 1 ? MMU_USER_SECONDARY_IDX
: MMU_USER_IDX
));
1142 if (cpu_get_phys_page_nofault(env
, addr
, idx
) == -1ULL) {
1144 dump_asi("read ", last_addr
, asi
, size
, ret
);
1146 /* exception_index is set in get_physical_address_data. */
1147 cpu_raise_exception_ra(env
, cs
->exception_index
, GETPC());
1149 oi
= make_memop_idx(memop
, idx
);
1152 ret
= helper_ret_ldub_mmu(env
, addr
, oi
, GETPC());
1156 ret
= helper_le_lduw_mmu(env
, addr
, oi
, GETPC());
1158 ret
= helper_be_lduw_mmu(env
, addr
, oi
, GETPC());
1163 ret
= helper_le_ldul_mmu(env
, addr
, oi
, GETPC());
1165 ret
= helper_be_ldul_mmu(env
, addr
, oi
, GETPC());
1170 ret
= helper_le_ldq_mmu(env
, addr
, oi
, GETPC());
1172 ret
= helper_be_ldq_mmu(env
, addr
, oi
, GETPC());
1176 g_assert_not_reached();
1181 case ASI_AIUP
: /* As if user primary */
1182 case ASI_AIUS
: /* As if user secondary */
1183 case ASI_AIUPL
: /* As if user primary LE */
1184 case ASI_AIUSL
: /* As if user secondary LE */
1185 case ASI_P
: /* Primary */
1186 case ASI_S
: /* Secondary */
1187 case ASI_PL
: /* Primary LE */
1188 case ASI_SL
: /* Secondary LE */
1189 case ASI_REAL
: /* Bypass */
1190 case ASI_REAL_IO
: /* Bypass, non-cacheable */
1191 case ASI_REAL_L
: /* Bypass LE */
1192 case ASI_REAL_IO_L
: /* Bypass, non-cacheable LE */
1193 case ASI_N
: /* Nucleus */
1194 case ASI_NL
: /* Nucleus Little Endian (LE) */
1195 case ASI_NUCLEUS_QUAD_LDD
: /* Nucleus quad LDD 128 bit atomic */
1196 case ASI_NUCLEUS_QUAD_LDD_L
: /* Nucleus quad LDD 128 bit atomic LE */
1197 case ASI_TWINX_AIUP
: /* As if user primary, twinx */
1198 case ASI_TWINX_AIUS
: /* As if user secondary, twinx */
1199 case ASI_TWINX_REAL
: /* Real address, twinx */
1200 case ASI_TWINX_AIUP_L
: /* As if user primary, twinx, LE */
1201 case ASI_TWINX_AIUS_L
: /* As if user secondary, twinx, LE */
1202 case ASI_TWINX_REAL_L
: /* Real address, twinx, LE */
1203 case ASI_TWINX_N
: /* Nucleus, twinx */
1204 case ASI_TWINX_NL
: /* Nucleus, twinx, LE */
1205 /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
1206 case ASI_TWINX_P
: /* Primary, twinx */
1207 case ASI_TWINX_PL
: /* Primary, twinx, LE */
1208 case ASI_TWINX_S
: /* Secondary, twinx */
1209 case ASI_TWINX_SL
: /* Secondary, twinx, LE */
1210 /* These are always handled inline. */
1211 g_assert_not_reached();
1213 case ASI_UPA_CONFIG
: /* UPA config */
1216 case ASI_LSU_CONTROL
: /* LSU */
1219 case ASI_IMMU
: /* I-MMU regs */
1221 int reg
= (addr
>> 3) & 0xf;
1224 /* 0x00 I-TSB Tag Target register */
1225 ret
= ultrasparc_tag_target(env
->immu
.tag_access
);
1228 ret
= env
->immu
.sfsr
;
1230 case 5: /* TSB access */
1231 ret
= env
->immu
.tsb
;
1234 /* 0x30 I-TSB Tag Access register */
1235 ret
= env
->immu
.tag_access
;
1238 cpu_unassigned_access(cs
, addr
, false, false, 1, size
);
1243 case ASI_IMMU_TSB_8KB_PTR
: /* I-MMU 8k TSB pointer */
1245 /* env->immuregs[5] holds I-MMU TSB register value
1246 env->immuregs[6] holds I-MMU Tag Access register value */
1247 ret
= ultrasparc_tsb_pointer(env
->immu
.tsb
, env
->immu
.tag_access
,
1251 case ASI_IMMU_TSB_64KB_PTR
: /* I-MMU 64k TSB pointer */
1253 /* env->immuregs[5] holds I-MMU TSB register value
1254 env->immuregs[6] holds I-MMU Tag Access register value */
1255 ret
= ultrasparc_tsb_pointer(env
->immu
.tsb
, env
->immu
.tag_access
,
1259 case ASI_ITLB_DATA_ACCESS
: /* I-MMU data access */
1261 int reg
= (addr
>> 3) & 0x3f;
1263 ret
= env
->itlb
[reg
].tte
;
1266 case ASI_ITLB_TAG_READ
: /* I-MMU tag read */
1268 int reg
= (addr
>> 3) & 0x3f;
1270 ret
= env
->itlb
[reg
].tag
;
1273 case ASI_DMMU
: /* D-MMU regs */
1275 int reg
= (addr
>> 3) & 0xf;
1278 /* 0x00 D-TSB Tag Target register */
1279 ret
= ultrasparc_tag_target(env
->dmmu
.tag_access
);
1281 case 1: /* 0x08 Primary Context */
1282 ret
= env
->dmmu
.mmu_primary_context
;
1284 case 2: /* 0x10 Secondary Context */
1285 ret
= env
->dmmu
.mmu_secondary_context
;
1288 ret
= env
->dmmu
.sfsr
;
1290 case 4: /* 0x20 SFAR */
1291 ret
= env
->dmmu
.sfar
;
1293 case 5: /* 0x28 TSB access */
1294 ret
= env
->dmmu
.tsb
;
1296 case 6: /* 0x30 D-TSB Tag Access register */
1297 ret
= env
->dmmu
.tag_access
;
1300 ret
= env
->dmmu
.virtual_watchpoint
;
1303 ret
= env
->dmmu
.physical_watchpoint
;
1306 cpu_unassigned_access(cs
, addr
, false, false, 1, size
);
1311 case ASI_DMMU_TSB_8KB_PTR
: /* D-MMU 8k TSB pointer */
1313 /* env->dmmuregs[5] holds D-MMU TSB register value
1314 env->dmmuregs[6] holds D-MMU Tag Access register value */
1315 ret
= ultrasparc_tsb_pointer(env
->dmmu
.tsb
, env
->dmmu
.tag_access
,
1319 case ASI_DMMU_TSB_64KB_PTR
: /* D-MMU 64k TSB pointer */
1321 /* env->dmmuregs[5] holds D-MMU TSB register value
1322 env->dmmuregs[6] holds D-MMU Tag Access register value */
1323 ret
= ultrasparc_tsb_pointer(env
->dmmu
.tsb
, env
->dmmu
.tag_access
,
1327 case ASI_DTLB_DATA_ACCESS
: /* D-MMU data access */
1329 int reg
= (addr
>> 3) & 0x3f;
1331 ret
= env
->dtlb
[reg
].tte
;
1334 case ASI_DTLB_TAG_READ
: /* D-MMU tag read */
1336 int reg
= (addr
>> 3) & 0x3f;
1338 ret
= env
->dtlb
[reg
].tag
;
1341 case ASI_INTR_DISPATCH_STAT
: /* Interrupt dispatch, RO */
1343 case ASI_INTR_RECEIVE
: /* Interrupt data receive */
1344 ret
= env
->ivec_status
;
1346 case ASI_INTR_R
: /* Incoming interrupt vector, RO */
1348 int reg
= (addr
>> 4) & 0x3;
1350 ret
= env
->ivec_data
[reg
];
1354 case ASI_SCRATCHPAD
: /* UA2005 privileged scratchpad */
1355 if (unlikely((addr
>= 0x20) && (addr
< 0x30))) {
1356 /* Hyperprivileged access only */
1357 cpu_unassigned_access(cs
, addr
, false, false, 1, size
);
1360 case ASI_HYP_SCRATCHPAD
: /* UA2005 hyperprivileged scratchpad */
1362 unsigned int i
= (addr
>> 3) & 0x7;
1363 ret
= env
->scratch
[i
];
1366 case ASI_DCACHE_DATA
: /* D-cache data */
1367 case ASI_DCACHE_TAG
: /* D-cache tag access */
1368 case ASI_ESTATE_ERROR_EN
: /* E-cache error enable */
1369 case ASI_AFSR
: /* E-cache asynchronous fault status */
1370 case ASI_AFAR
: /* E-cache asynchronous fault address */
1371 case ASI_EC_TAG_DATA
: /* E-cache tag data */
1372 case ASI_IC_INSTR
: /* I-cache instruction access */
1373 case ASI_IC_TAG
: /* I-cache tag access */
1374 case ASI_IC_PRE_DECODE
: /* I-cache predecode */
1375 case ASI_IC_NEXT_FIELD
: /* I-cache LRU etc. */
1376 case ASI_EC_W
: /* E-cache tag */
1377 case ASI_EC_R
: /* E-cache tag */
1379 case ASI_DMMU_TSB_DIRECT_PTR
: /* D-MMU data pointer */
1380 case ASI_ITLB_DATA_IN
: /* I-MMU data in, WO */
1381 case ASI_IMMU_DEMAP
: /* I-MMU demap, WO */
1382 case ASI_DTLB_DATA_IN
: /* D-MMU data in, WO */
1383 case ASI_DMMU_DEMAP
: /* D-MMU demap, WO */
1384 case ASI_INTR_W
: /* Interrupt vector, WO */
1386 cpu_unassigned_access(cs
, addr
, false, false, 1, size
);
1391 /* Convert to signed number */
1398 ret
= (int16_t) ret
;
1401 ret
= (int32_t) ret
;
1408 dump_asi("read ", last_addr
, asi
, size
, ret
);
1413 void helper_st_asi(CPUSPARCState
*env
, target_ulong addr
, target_ulong val
,
1414 int asi
, uint32_t memop
)
1416 int size
= 1 << (memop
& MO_SIZE
);
1417 SPARCCPU
*cpu
= sparc_env_get_cpu(env
);
1418 CPUState
*cs
= CPU(cpu
);
1421 dump_asi("write", addr
, asi
, size
, val
);
1426 if ((asi
< 0x80 && (env
->pstate
& PS_PRIV
) == 0)
1427 || (cpu_has_hypervisor(env
)
1428 && asi
>= 0x30 && asi
< 0x80
1429 && !(env
->hpstate
& HS_PRIV
))) {
1430 cpu_raise_exception_ra(env
, TT_PRIV_ACT
, GETPC());
1433 do_check_align(env
, addr
, size
- 1, GETPC());
1434 addr
= asi_address_mask(env
, asi
, addr
);
1437 case ASI_AIUP
: /* As if user primary */
1438 case ASI_AIUS
: /* As if user secondary */
1439 case ASI_AIUPL
: /* As if user primary LE */
1440 case ASI_AIUSL
: /* As if user secondary LE */
1441 case ASI_P
: /* Primary */
1442 case ASI_S
: /* Secondary */
1443 case ASI_PL
: /* Primary LE */
1444 case ASI_SL
: /* Secondary LE */
1445 case ASI_REAL
: /* Bypass */
1446 case ASI_REAL_IO
: /* Bypass, non-cacheable */
1447 case ASI_REAL_L
: /* Bypass LE */
1448 case ASI_REAL_IO_L
: /* Bypass, non-cacheable LE */
1449 case ASI_N
: /* Nucleus */
1450 case ASI_NL
: /* Nucleus Little Endian (LE) */
1451 case ASI_NUCLEUS_QUAD_LDD
: /* Nucleus quad LDD 128 bit atomic */
1452 case ASI_NUCLEUS_QUAD_LDD_L
: /* Nucleus quad LDD 128 bit atomic LE */
1453 case ASI_TWINX_AIUP
: /* As if user primary, twinx */
1454 case ASI_TWINX_AIUS
: /* As if user secondary, twinx */
1455 case ASI_TWINX_REAL
: /* Real address, twinx */
1456 case ASI_TWINX_AIUP_L
: /* As if user primary, twinx, LE */
1457 case ASI_TWINX_AIUS_L
: /* As if user secondary, twinx, LE */
1458 case ASI_TWINX_REAL_L
: /* Real address, twinx, LE */
1459 case ASI_TWINX_N
: /* Nucleus, twinx */
1460 case ASI_TWINX_NL
: /* Nucleus, twinx, LE */
1461 /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
1462 case ASI_TWINX_P
: /* Primary, twinx */
1463 case ASI_TWINX_PL
: /* Primary, twinx, LE */
1464 case ASI_TWINX_S
: /* Secondary, twinx */
1465 case ASI_TWINX_SL
: /* Secondary, twinx, LE */
1466 /* These are always handled inline. */
1467 g_assert_not_reached();
1469 case ASI_UPA_CONFIG
: /* UPA config */
1472 case ASI_LSU_CONTROL
: /* LSU */
1473 env
->lsu
= val
& (DMMU_E
| IMMU_E
);
1475 case ASI_IMMU
: /* I-MMU regs */
1477 int reg
= (addr
>> 3) & 0xf;
1480 oldreg
= env
->immuregs
[reg
];
1484 case 1: /* Not in I-MMU */
1488 if ((val
& 1) == 0) {
1489 val
= 0; /* Clear SFSR */
1491 env
->immu
.sfsr
= val
;
1495 case 5: /* TSB access */
1496 DPRINTF_MMU("immu TSB write: 0x%016" PRIx64
" -> 0x%016"
1497 PRIx64
"\n", env
->immu
.tsb
, val
);
1498 env
->immu
.tsb
= val
;
1500 case 6: /* Tag access */
1501 env
->immu
.tag_access
= val
;
1507 cpu_unassigned_access(cs
, addr
, true, false, 1, size
);
1511 if (oldreg
!= env
->immuregs
[reg
]) {
1512 DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64
" -> 0x%016"
1513 PRIx64
"\n", reg
, oldreg
, env
->immuregs
[reg
]);
1516 dump_mmu(stdout
, fprintf
, env
);
1520 case ASI_ITLB_DATA_IN
: /* I-MMU data in */
1521 replace_tlb_1bit_lru(env
->itlb
, env
->immu
.tag_access
, val
, "immu", env
);
1523 case ASI_ITLB_DATA_ACCESS
: /* I-MMU data access */
1525 /* TODO: auto demap */
1527 unsigned int i
= (addr
>> 3) & 0x3f;
1529 replace_tlb_entry(&env
->itlb
[i
], env
->immu
.tag_access
, val
, env
);
1532 DPRINTF_MMU("immu data access replaced entry [%i]\n", i
);
1533 dump_mmu(stdout
, fprintf
, env
);
1537 case ASI_IMMU_DEMAP
: /* I-MMU demap */
1538 demap_tlb(env
->itlb
, addr
, "immu", env
);
1540 case ASI_DMMU
: /* D-MMU regs */
1542 int reg
= (addr
>> 3) & 0xf;
1545 oldreg
= env
->dmmuregs
[reg
];
1551 if ((val
& 1) == 0) {
1552 val
= 0; /* Clear SFSR, Fault address */
1555 env
->dmmu
.sfsr
= val
;
1557 case 1: /* Primary context */
1558 env
->dmmu
.mmu_primary_context
= val
;
1559 /* can be optimized to only flush MMU_USER_IDX
1560 and MMU_KERNEL_IDX entries */
1561 tlb_flush(CPU(cpu
));
1563 case 2: /* Secondary context */
1564 env
->dmmu
.mmu_secondary_context
= val
;
1565 /* can be optimized to only flush MMU_USER_SECONDARY_IDX
1566 and MMU_KERNEL_SECONDARY_IDX entries */
1567 tlb_flush(CPU(cpu
));
1569 case 5: /* TSB access */
1570 DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64
" -> 0x%016"
1571 PRIx64
"\n", env
->dmmu
.tsb
, val
);
1572 env
->dmmu
.tsb
= val
;
1574 case 6: /* Tag access */
1575 env
->dmmu
.tag_access
= val
;
1577 case 7: /* Virtual Watchpoint */
1578 env
->dmmu
.virtual_watchpoint
= val
;
1580 case 8: /* Physical Watchpoint */
1581 env
->dmmu
.physical_watchpoint
= val
;
1584 cpu_unassigned_access(cs
, addr
, true, false, 1, size
);
1588 if (oldreg
!= env
->dmmuregs
[reg
]) {
1589 DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64
" -> 0x%016"
1590 PRIx64
"\n", reg
, oldreg
, env
->dmmuregs
[reg
]);
1593 dump_mmu(stdout
, fprintf
, env
);
1597 case ASI_DTLB_DATA_IN
: /* D-MMU data in */
1598 replace_tlb_1bit_lru(env
->dtlb
, env
->dmmu
.tag_access
, val
, "dmmu", env
);
1600 case ASI_DTLB_DATA_ACCESS
: /* D-MMU data access */
1602 unsigned int i
= (addr
>> 3) & 0x3f;
1604 replace_tlb_entry(&env
->dtlb
[i
], env
->dmmu
.tag_access
, val
, env
);
1607 DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i
);
1608 dump_mmu(stdout
, fprintf
, env
);
1612 case ASI_DMMU_DEMAP
: /* D-MMU demap */
1613 demap_tlb(env
->dtlb
, addr
, "dmmu", env
);
1615 case ASI_INTR_RECEIVE
: /* Interrupt data receive */
1616 env
->ivec_status
= val
& 0x20;
1618 case ASI_SCRATCHPAD
: /* UA2005 privileged scratchpad */
1619 if (unlikely((addr
>= 0x20) && (addr
< 0x30))) {
1620 /* Hyperprivileged access only */
1621 cpu_unassigned_access(cs
, addr
, true, false, 1, size
);
1624 case ASI_HYP_SCRATCHPAD
: /* UA2005 hyperprivileged scratchpad */
1626 unsigned int i
= (addr
>> 3) & 0x7;
1627 env
->scratch
[i
] = val
;
1630 case ASI_DCACHE_DATA
: /* D-cache data */
1631 case ASI_DCACHE_TAG
: /* D-cache tag access */
1632 case ASI_ESTATE_ERROR_EN
: /* E-cache error enable */
1633 case ASI_AFSR
: /* E-cache asynchronous fault status */
1634 case ASI_AFAR
: /* E-cache asynchronous fault address */
1635 case ASI_EC_TAG_DATA
: /* E-cache tag data */
1636 case ASI_IC_INSTR
: /* I-cache instruction access */
1637 case ASI_IC_TAG
: /* I-cache tag access */
1638 case ASI_IC_PRE_DECODE
: /* I-cache predecode */
1639 case ASI_IC_NEXT_FIELD
: /* I-cache LRU etc. */
1640 case ASI_EC_W
: /* E-cache tag */
1641 case ASI_EC_R
: /* E-cache tag */
1643 case ASI_IMMU_TSB_8KB_PTR
: /* I-MMU 8k TSB pointer, RO */
1644 case ASI_IMMU_TSB_64KB_PTR
: /* I-MMU 64k TSB pointer, RO */
1645 case ASI_ITLB_TAG_READ
: /* I-MMU tag read, RO */
1646 case ASI_DMMU_TSB_8KB_PTR
: /* D-MMU 8k TSB pointer, RO */
1647 case ASI_DMMU_TSB_64KB_PTR
: /* D-MMU 64k TSB pointer, RO */
1648 case ASI_DMMU_TSB_DIRECT_PTR
: /* D-MMU data pointer, RO */
1649 case ASI_DTLB_TAG_READ
: /* D-MMU tag read, RO */
1650 case ASI_INTR_DISPATCH_STAT
: /* Interrupt dispatch, RO */
1651 case ASI_INTR_R
: /* Incoming interrupt vector, RO */
1652 case ASI_PNF
: /* Primary no-fault, RO */
1653 case ASI_SNF
: /* Secondary no-fault, RO */
1654 case ASI_PNFL
: /* Primary no-fault LE, RO */
1655 case ASI_SNFL
: /* Secondary no-fault LE, RO */
1657 cpu_unassigned_access(cs
, addr
, true, false, 1, size
);
1661 #endif /* CONFIG_USER_ONLY */
1662 #endif /* TARGET_SPARC64 */
1664 #if !defined(CONFIG_USER_ONLY)
1665 #ifndef TARGET_SPARC64
1666 void sparc_cpu_unassigned_access(CPUState
*cs
, hwaddr addr
,
1667 bool is_write
, bool is_exec
, int is_asi
,
1670 SPARCCPU
*cpu
= SPARC_CPU(cs
);
1671 CPUSPARCState
*env
= &cpu
->env
;
1674 #ifdef DEBUG_UNASSIGNED
1676 printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
1677 " asi 0x%02x from " TARGET_FMT_lx
"\n",
1678 is_exec
? "exec" : is_write
? "write" : "read", size
,
1679 size
== 1 ? "" : "s", addr
, is_asi
, env
->pc
);
1681 printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
1682 " from " TARGET_FMT_lx
"\n",
1683 is_exec
? "exec" : is_write
? "write" : "read", size
,
1684 size
== 1 ? "" : "s", addr
, env
->pc
);
1687 /* Don't overwrite translation and access faults */
1688 fault_type
= (env
->mmuregs
[3] & 0x1c) >> 2;
1689 if ((fault_type
> 4) || (fault_type
== 0)) {
1690 env
->mmuregs
[3] = 0; /* Fault status register */
1692 env
->mmuregs
[3] |= 1 << 16;
1695 env
->mmuregs
[3] |= 1 << 5;
1698 env
->mmuregs
[3] |= 1 << 6;
1701 env
->mmuregs
[3] |= 1 << 7;
1703 env
->mmuregs
[3] |= (5 << 2) | 2;
1704 /* SuperSPARC will never place instruction fault addresses in the FAR */
1706 env
->mmuregs
[4] = addr
; /* Fault address register */
1709 /* overflow (same type fault was not read before another fault) */
1710 if (fault_type
== ((env
->mmuregs
[3] & 0x1c)) >> 2) {
1711 env
->mmuregs
[3] |= 1;
1714 if ((env
->mmuregs
[0] & MMU_E
) && !(env
->mmuregs
[0] & MMU_NF
)) {
1715 int tt
= is_exec
? TT_CODE_ACCESS
: TT_DATA_ACCESS
;
1716 cpu_raise_exception_ra(env
, tt
, GETPC());
1719 /* flush neverland mappings created during no-fault mode,
1720 so the sequential MMU faults report proper fault types */
1721 if (env
->mmuregs
[0] & MMU_NF
) {
1726 void sparc_cpu_unassigned_access(CPUState
*cs
, hwaddr addr
,
1727 bool is_write
, bool is_exec
, int is_asi
,
1730 SPARCCPU
*cpu
= SPARC_CPU(cs
);
1731 CPUSPARCState
*env
= &cpu
->env
;
1733 #ifdef DEBUG_UNASSIGNED
1734 printf("Unassigned mem access to " TARGET_FMT_plx
" from " TARGET_FMT_lx
1735 "\n", addr
, env
->pc
);
1738 if (is_exec
) { /* XXX has_hypervisor */
1739 if (env
->lsu
& (IMMU_E
)) {
1740 cpu_raise_exception_ra(env
, TT_CODE_ACCESS
, GETPC());
1741 } else if (cpu_has_hypervisor(env
) && !(env
->hpstate
& HS_PRIV
)) {
1742 cpu_raise_exception_ra(env
, TT_INSN_REAL_TRANSLATION_MISS
, GETPC());
1745 if (env
->lsu
& (DMMU_E
)) {
1746 cpu_raise_exception_ra(env
, TT_DATA_ACCESS
, GETPC());
1747 } else if (cpu_has_hypervisor(env
) && !(env
->hpstate
& HS_PRIV
)) {
1748 cpu_raise_exception_ra(env
, TT_DATA_REAL_TRANSLATION_MISS
, GETPC());
1755 #if !defined(CONFIG_USER_ONLY)
1756 void QEMU_NORETURN
sparc_cpu_do_unaligned_access(CPUState
*cs
, vaddr addr
,
1757 MMUAccessType access_type
,
1761 SPARCCPU
*cpu
= SPARC_CPU(cs
);
1762 CPUSPARCState
*env
= &cpu
->env
;
1764 #ifdef DEBUG_UNALIGNED
1765 printf("Unaligned access to 0x" TARGET_FMT_lx
" from 0x" TARGET_FMT_lx
1766 "\n", addr
, env
->pc
);
1768 cpu_raise_exception_ra(env
, TT_UNALIGNED
, retaddr
);
1771 /* try to fill the TLB and return an exception if error. If retaddr is
1772 NULL, it means that the function was called in C code (i.e. not
1773 from generated code or from helper.c) */
1774 /* XXX: fix it to restore all registers */
1775 void tlb_fill(CPUState
*cs
, target_ulong addr
, MMUAccessType access_type
,
1776 int mmu_idx
, uintptr_t retaddr
)
1780 ret
= sparc_cpu_handle_mmu_fault(cs
, addr
, access_type
, mmu_idx
);
1782 cpu_loop_exit_restore(cs
, retaddr
);