]> Git Repo - qemu.git/blob - target-sparc/ldst_helper.c
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
[qemu.git] / target-sparc / ldst_helper.c
1 /*
2  * Helpers for loads and stores
3  *
4  *  Copyright (c) 2003-2005 Fabrice Bellard
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include "cpu.h"
21 #include "helper.h"
22
23 //#define DEBUG_MMU
24 //#define DEBUG_MXCC
25 //#define DEBUG_UNALIGNED
26 //#define DEBUG_UNASSIGNED
27 //#define DEBUG_ASI
28 //#define DEBUG_CACHE_CONTROL
29
30 #ifdef DEBUG_MMU
31 #define DPRINTF_MMU(fmt, ...)                                   \
32     do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
33 #else
34 #define DPRINTF_MMU(fmt, ...) do {} while (0)
35 #endif
36
37 #ifdef DEBUG_MXCC
38 #define DPRINTF_MXCC(fmt, ...)                                  \
39     do { printf("MXCC: " fmt , ## __VA_ARGS__); } while (0)
40 #else
41 #define DPRINTF_MXCC(fmt, ...) do {} while (0)
42 #endif
43
44 #ifdef DEBUG_ASI
45 #define DPRINTF_ASI(fmt, ...)                                   \
46     do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0)
47 #endif
48
49 #ifdef DEBUG_CACHE_CONTROL
50 #define DPRINTF_CACHE_CONTROL(fmt, ...)                                 \
51     do { printf("CACHE_CONTROL: " fmt , ## __VA_ARGS__); } while (0)
52 #else
53 #define DPRINTF_CACHE_CONTROL(fmt, ...) do {} while (0)
54 #endif
55
56 #ifdef TARGET_SPARC64
57 #ifndef TARGET_ABI32
58 #define AM_CHECK(env1) ((env1)->pstate & PS_AM)
59 #else
60 #define AM_CHECK(env1) (1)
61 #endif
62 #endif
63
64 #define QT0 (env->qt0)
65 #define QT1 (env->qt1)
66
67 #if !defined(CONFIG_USER_ONLY)
68 static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
69                                               target_ulong addr, int is_write,
70                                               int is_user, uintptr_t retaddr);
71 #include "exec/softmmu_exec.h"
72 #define MMUSUFFIX _mmu
73 #define ALIGNED_ONLY
74
75 #define SHIFT 0
76 #include "exec/softmmu_template.h"
77
78 #define SHIFT 1
79 #include "exec/softmmu_template.h"
80
81 #define SHIFT 2
82 #include "exec/softmmu_template.h"
83
84 #define SHIFT 3
85 #include "exec/softmmu_template.h"
86 #endif
87
88 #if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
89 /* Calculates TSB pointer value for fault page size 8k or 64k */
90 static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
91                                        uint64_t tag_access_register,
92                                        int page_size)
93 {
94     uint64_t tsb_base = tsb_register & ~0x1fffULL;
95     int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0;
96     int tsb_size  = tsb_register & 0xf;
97
98     /* discard lower 13 bits which hold tag access context */
99     uint64_t tag_access_va = tag_access_register & ~0x1fffULL;
100
101     /* now reorder bits */
102     uint64_t tsb_base_mask = ~0x1fffULL;
103     uint64_t va = tag_access_va;
104
105     /* move va bits to correct position */
106     if (page_size == 8*1024) {
107         va >>= 9;
108     } else if (page_size == 64*1024) {
109         va >>= 12;
110     }
111
112     if (tsb_size) {
113         tsb_base_mask <<= tsb_size;
114     }
115
116     /* calculate tsb_base mask and adjust va if split is in use */
117     if (tsb_split) {
118         if (page_size == 8*1024) {
119             va &= ~(1ULL << (13 + tsb_size));
120         } else if (page_size == 64*1024) {
121             va |= (1ULL << (13 + tsb_size));
122         }
123         tsb_base_mask <<= 1;
124     }
125
126     return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
127 }
128
129 /* Calculates tag target register value by reordering bits
130    in tag access register */
131 static uint64_t ultrasparc_tag_target(uint64_t tag_access_register)
132 {
133     return ((tag_access_register & 0x1fff) << 48) | (tag_access_register >> 22);
134 }
135
136 static void replace_tlb_entry(SparcTLBEntry *tlb,
137                               uint64_t tlb_tag, uint64_t tlb_tte,
138                               CPUSPARCState *env1)
139 {
140     target_ulong mask, size, va, offset;
141
142     /* flush page range if translation is valid */
143     if (TTE_IS_VALID(tlb->tte)) {
144
145         mask = 0xffffffffffffe000ULL;
146         mask <<= 3 * ((tlb->tte >> 61) & 3);
147         size = ~mask + 1;
148
149         va = tlb->tag & mask;
150
151         for (offset = 0; offset < size; offset += TARGET_PAGE_SIZE) {
152             tlb_flush_page(env1, va + offset);
153         }
154     }
155
156     tlb->tag = tlb_tag;
157     tlb->tte = tlb_tte;
158 }
159
160 static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
161                       const char *strmmu, CPUSPARCState *env1)
162 {
163     unsigned int i;
164     target_ulong mask;
165     uint64_t context;
166
167     int is_demap_context = (demap_addr >> 6) & 1;
168
169     /* demap context */
170     switch ((demap_addr >> 4) & 3) {
171     case 0: /* primary */
172         context = env1->dmmu.mmu_primary_context;
173         break;
174     case 1: /* secondary */
175         context = env1->dmmu.mmu_secondary_context;
176         break;
177     case 2: /* nucleus */
178         context = 0;
179         break;
180     case 3: /* reserved */
181     default:
182         return;
183     }
184
185     for (i = 0; i < 64; i++) {
186         if (TTE_IS_VALID(tlb[i].tte)) {
187
188             if (is_demap_context) {
189                 /* will remove non-global entries matching context value */
190                 if (TTE_IS_GLOBAL(tlb[i].tte) ||
191                     !tlb_compare_context(&tlb[i], context)) {
192                     continue;
193                 }
194             } else {
195                 /* demap page
196                    will remove any entry matching VA */
197                 mask = 0xffffffffffffe000ULL;
198                 mask <<= 3 * ((tlb[i].tte >> 61) & 3);
199
200                 if (!compare_masked(demap_addr, tlb[i].tag, mask)) {
201                     continue;
202                 }
203
204                 /* entry should be global or matching context value */
205                 if (!TTE_IS_GLOBAL(tlb[i].tte) &&
206                     !tlb_compare_context(&tlb[i], context)) {
207                     continue;
208                 }
209             }
210
211             replace_tlb_entry(&tlb[i], 0, 0, env1);
212 #ifdef DEBUG_MMU
213             DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
214             dump_mmu(stdout, fprintf, env1);
215 #endif
216         }
217     }
218 }
219
220 static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
221                                  uint64_t tlb_tag, uint64_t tlb_tte,
222                                  const char *strmmu, CPUSPARCState *env1)
223 {
224     unsigned int i, replace_used;
225
226     /* Try replacing invalid entry */
227     for (i = 0; i < 64; i++) {
228         if (!TTE_IS_VALID(tlb[i].tte)) {
229             replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
230 #ifdef DEBUG_MMU
231             DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i);
232             dump_mmu(stdout, fprintf, env1);
233 #endif
234             return;
235         }
236     }
237
238     /* All entries are valid, try replacing unlocked entry */
239
240     for (replace_used = 0; replace_used < 2; ++replace_used) {
241
242         /* Used entries are not replaced on first pass */
243
244         for (i = 0; i < 64; i++) {
245             if (!TTE_IS_LOCKED(tlb[i].tte) && !TTE_IS_USED(tlb[i].tte)) {
246
247                 replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
248 #ifdef DEBUG_MMU
249                 DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
250                             strmmu, (replace_used ? "used" : "unused"), i);
251                 dump_mmu(stdout, fprintf, env1);
252 #endif
253                 return;
254             }
255         }
256
257         /* Now reset used bit and search for unused entries again */
258
259         for (i = 0; i < 64; i++) {
260             TTE_SET_UNUSED(tlb[i].tte);
261         }
262     }
263
264 #ifdef DEBUG_MMU
265     DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu);
266 #endif
267     /* error state? */
268 }
269
270 #endif
271
272 static inline target_ulong address_mask(CPUSPARCState *env1, target_ulong addr)
273 {
274 #ifdef TARGET_SPARC64
275     if (AM_CHECK(env1)) {
276         addr &= 0xffffffffULL;
277     }
278 #endif
279     return addr;
280 }
281
282 /* returns true if access using this ASI is to have address translated by MMU
283    otherwise access is to raw physical address */
284 static inline int is_translating_asi(int asi)
285 {
286 #ifdef TARGET_SPARC64
287     /* Ultrasparc IIi translating asi
288        - note this list is defined by cpu implementation
289     */
290     switch (asi) {
291     case 0x04 ... 0x11:
292     case 0x16 ... 0x19:
293     case 0x1E ... 0x1F:
294     case 0x24 ... 0x2C:
295     case 0x70 ... 0x73:
296     case 0x78 ... 0x79:
297     case 0x80 ... 0xFF:
298         return 1;
299
300     default:
301         return 0;
302     }
303 #else
304     /* TODO: check sparc32 bits */
305     return 0;
306 #endif
307 }
308
309 static inline target_ulong asi_address_mask(CPUSPARCState *env,
310                                             int asi, target_ulong addr)
311 {
312     if (is_translating_asi(asi)) {
313         return address_mask(env, addr);
314     } else {
315         return addr;
316     }
317 }
318
319 void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align)
320 {
321     if (addr & align) {
322 #ifdef DEBUG_UNALIGNED
323         printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
324                "\n", addr, env->pc);
325 #endif
326         helper_raise_exception(env, TT_UNALIGNED);
327     }
328 }
329
330 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) &&   \
331     defined(DEBUG_MXCC)
332 static void dump_mxcc(CPUSPARCState *env)
333 {
334     printf("mxccdata: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
335            "\n",
336            env->mxccdata[0], env->mxccdata[1],
337            env->mxccdata[2], env->mxccdata[3]);
338     printf("mxccregs: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
339            "\n"
340            "          %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
341            "\n",
342            env->mxccregs[0], env->mxccregs[1],
343            env->mxccregs[2], env->mxccregs[3],
344            env->mxccregs[4], env->mxccregs[5],
345            env->mxccregs[6], env->mxccregs[7]);
346 }
347 #endif
348
349 #if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY))     \
350     && defined(DEBUG_ASI)
351 static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
352                      uint64_t r1)
353 {
354     switch (size) {
355     case 1:
356         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
357                     addr, asi, r1 & 0xff);
358         break;
359     case 2:
360         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
361                     addr, asi, r1 & 0xffff);
362         break;
363     case 4:
364         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
365                     addr, asi, r1 & 0xffffffff);
366         break;
367     case 8:
368         DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
369                     addr, asi, r1);
370         break;
371     }
372 }
373 #endif
374
375 #ifndef TARGET_SPARC64
376 #ifndef CONFIG_USER_ONLY
377
378
379 /* Leon3 cache control */
380
381 static void leon3_cache_control_st(CPUSPARCState *env, target_ulong addr,
382                                    uint64_t val, int size)
383 {
384     DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64 ", size:%d\n",
385                           addr, val, size);
386
387     if (size != 4) {
388         DPRINTF_CACHE_CONTROL("32bits only\n");
389         return;
390     }
391
392     switch (addr) {
393     case 0x00:              /* Cache control */
394
395         /* These values must always be read as zeros */
396         val &= ~CACHE_CTRL_FD;
397         val &= ~CACHE_CTRL_FI;
398         val &= ~CACHE_CTRL_IB;
399         val &= ~CACHE_CTRL_IP;
400         val &= ~CACHE_CTRL_DP;
401
402         env->cache_control = val;
403         break;
404     case 0x04:              /* Instruction cache configuration */
405     case 0x08:              /* Data cache configuration */
406         /* Read Only */
407         break;
408     default:
409         DPRINTF_CACHE_CONTROL("write unknown register %08x\n", addr);
410         break;
411     };
412 }
413
414 static uint64_t leon3_cache_control_ld(CPUSPARCState *env, target_ulong addr,
415                                        int size)
416 {
417     uint64_t ret = 0;
418
419     if (size != 4) {
420         DPRINTF_CACHE_CONTROL("32bits only\n");
421         return 0;
422     }
423
424     switch (addr) {
425     case 0x00:              /* Cache control */
426         ret = env->cache_control;
427         break;
428
429         /* Configuration registers are read and only always keep those
430            predefined values */
431
432     case 0x04:              /* Instruction cache configuration */
433         ret = 0x10220000;
434         break;
435     case 0x08:              /* Data cache configuration */
436         ret = 0x18220000;
437         break;
438     default:
439         DPRINTF_CACHE_CONTROL("read unknown register %08x\n", addr);
440         break;
441     };
442     DPRINTF_CACHE_CONTROL("ld addr:%08x, ret:0x%" PRIx64 ", size:%d\n",
443                           addr, ret, size);
444     return ret;
445 }
446
447 uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
448                        int sign)
449 {
450     uint64_t ret = 0;
451 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
452     uint32_t last_addr = addr;
453 #endif
454
455     helper_check_align(env, addr, size - 1);
456     switch (asi) {
457     case 2: /* SuperSparc MXCC registers and Leon3 cache control */
458         switch (addr) {
459         case 0x00:          /* Leon3 Cache Control */
460         case 0x08:          /* Leon3 Instruction Cache config */
461         case 0x0C:          /* Leon3 Date Cache config */
462             if (env->def->features & CPU_FEATURE_CACHE_CTRL) {
463                 ret = leon3_cache_control_ld(env, addr, size);
464             }
465             break;
466         case 0x01c00a00: /* MXCC control register */
467             if (size == 8) {
468                 ret = env->mxccregs[3];
469             } else {
470                 qemu_log_mask(LOG_UNIMP,
471                               "%08x: unimplemented access size: %d\n", addr,
472                               size);
473             }
474             break;
475         case 0x01c00a04: /* MXCC control register */
476             if (size == 4) {
477                 ret = env->mxccregs[3];
478             } else {
479                 qemu_log_mask(LOG_UNIMP,
480                               "%08x: unimplemented access size: %d\n", addr,
481                               size);
482             }
483             break;
484         case 0x01c00c00: /* Module reset register */
485             if (size == 8) {
486                 ret = env->mxccregs[5];
487                 /* should we do something here? */
488             } else {
489                 qemu_log_mask(LOG_UNIMP,
490                               "%08x: unimplemented access size: %d\n", addr,
491                               size);
492             }
493             break;
494         case 0x01c00f00: /* MBus port address register */
495             if (size == 8) {
496                 ret = env->mxccregs[7];
497             } else {
498                 qemu_log_mask(LOG_UNIMP,
499                               "%08x: unimplemented access size: %d\n", addr,
500                               size);
501             }
502             break;
503         default:
504             qemu_log_mask(LOG_UNIMP,
505                           "%08x: unimplemented address, size: %d\n", addr,
506                           size);
507             break;
508         }
509         DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
510                      "addr = %08x -> ret = %" PRIx64 ","
511                      "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
512 #ifdef DEBUG_MXCC
513         dump_mxcc(env);
514 #endif
515         break;
516     case 3: /* MMU probe */
517     case 0x18: /* LEON3 MMU probe */
518         {
519             int mmulev;
520
521             mmulev = (addr >> 8) & 15;
522             if (mmulev > 4) {
523                 ret = 0;
524             } else {
525                 ret = mmu_probe(env, addr, mmulev);
526             }
527             DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
528                         addr, mmulev, ret);
529         }
530         break;
531     case 4: /* read MMU regs */
532     case 0x19: /* LEON3 read MMU regs */
533         {
534             int reg = (addr >> 8) & 0x1f;
535
536             ret = env->mmuregs[reg];
537             if (reg == 3) { /* Fault status cleared on read */
538                 env->mmuregs[3] = 0;
539             } else if (reg == 0x13) { /* Fault status read */
540                 ret = env->mmuregs[3];
541             } else if (reg == 0x14) { /* Fault address read */
542                 ret = env->mmuregs[4];
543             }
544             DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
545         }
546         break;
547     case 5: /* Turbosparc ITLB Diagnostic */
548     case 6: /* Turbosparc DTLB Diagnostic */
549     case 7: /* Turbosparc IOTLB Diagnostic */
550         break;
551     case 9: /* Supervisor code access */
552         switch (size) {
553         case 1:
554             ret = cpu_ldub_code(env, addr);
555             break;
556         case 2:
557             ret = cpu_lduw_code(env, addr);
558             break;
559         default:
560         case 4:
561             ret = cpu_ldl_code(env, addr);
562             break;
563         case 8:
564             ret = cpu_ldq_code(env, addr);
565             break;
566         }
567         break;
568     case 0xa: /* User data access */
569         switch (size) {
570         case 1:
571             ret = cpu_ldub_user(env, addr);
572             break;
573         case 2:
574             ret = cpu_lduw_user(env, addr);
575             break;
576         default:
577         case 4:
578             ret = cpu_ldl_user(env, addr);
579             break;
580         case 8:
581             ret = cpu_ldq_user(env, addr);
582             break;
583         }
584         break;
585     case 0xb: /* Supervisor data access */
586         switch (size) {
587         case 1:
588             ret = cpu_ldub_kernel(env, addr);
589             break;
590         case 2:
591             ret = cpu_lduw_kernel(env, addr);
592             break;
593         default:
594         case 4:
595             ret = cpu_ldl_kernel(env, addr);
596             break;
597         case 8:
598             ret = cpu_ldq_kernel(env, addr);
599             break;
600         }
601         break;
602     case 0xc: /* I-cache tag */
603     case 0xd: /* I-cache data */
604     case 0xe: /* D-cache tag */
605     case 0xf: /* D-cache data */
606         break;
607     case 0x20: /* MMU passthrough */
608     case 0x1c: /* LEON MMU passthrough */
609         switch (size) {
610         case 1:
611             ret = ldub_phys(addr);
612             break;
613         case 2:
614             ret = lduw_phys(addr);
615             break;
616         default:
617         case 4:
618             ret = ldl_phys(addr);
619             break;
620         case 8:
621             ret = ldq_phys(addr);
622             break;
623         }
624         break;
625     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
626         switch (size) {
627         case 1:
628             ret = ldub_phys((hwaddr)addr
629                             | ((hwaddr)(asi & 0xf) << 32));
630             break;
631         case 2:
632             ret = lduw_phys((hwaddr)addr
633                             | ((hwaddr)(asi & 0xf) << 32));
634             break;
635         default:
636         case 4:
637             ret = ldl_phys((hwaddr)addr
638                            | ((hwaddr)(asi & 0xf) << 32));
639             break;
640         case 8:
641             ret = ldq_phys((hwaddr)addr
642                            | ((hwaddr)(asi & 0xf) << 32));
643             break;
644         }
645         break;
646     case 0x30: /* Turbosparc secondary cache diagnostic */
647     case 0x31: /* Turbosparc RAM snoop */
648     case 0x32: /* Turbosparc page table descriptor diagnostic */
649     case 0x39: /* data cache diagnostic register */
650         ret = 0;
651         break;
652     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
653         {
654             int reg = (addr >> 8) & 3;
655
656             switch (reg) {
657             case 0: /* Breakpoint Value (Addr) */
658                 ret = env->mmubpregs[reg];
659                 break;
660             case 1: /* Breakpoint Mask */
661                 ret = env->mmubpregs[reg];
662                 break;
663             case 2: /* Breakpoint Control */
664                 ret = env->mmubpregs[reg];
665                 break;
666             case 3: /* Breakpoint Status */
667                 ret = env->mmubpregs[reg];
668                 env->mmubpregs[reg] = 0ULL;
669                 break;
670             }
671             DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64 "\n", reg,
672                         ret);
673         }
674         break;
675     case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
676         ret = env->mmubpctrv;
677         break;
678     case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
679         ret = env->mmubpctrc;
680         break;
681     case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
682         ret = env->mmubpctrs;
683         break;
684     case 0x4c: /* SuperSPARC MMU Breakpoint Action */
685         ret = env->mmubpaction;
686         break;
687     case 8: /* User code access, XXX */
688     default:
689         cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
690                               addr, false, false, asi, size);
691         ret = 0;
692         break;
693     }
694     if (sign) {
695         switch (size) {
696         case 1:
697             ret = (int8_t) ret;
698             break;
699         case 2:
700             ret = (int16_t) ret;
701             break;
702         case 4:
703             ret = (int32_t) ret;
704             break;
705         default:
706             break;
707         }
708     }
709 #ifdef DEBUG_ASI
710     dump_asi("read ", last_addr, asi, size, ret);
711 #endif
712     return ret;
713 }
714
715 void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
716                    int size)
717 {
718     helper_check_align(env, addr, size - 1);
719     switch (asi) {
720     case 2: /* SuperSparc MXCC registers and Leon3 cache control */
721         switch (addr) {
722         case 0x00:          /* Leon3 Cache Control */
723         case 0x08:          /* Leon3 Instruction Cache config */
724         case 0x0C:          /* Leon3 Date Cache config */
725             if (env->def->features & CPU_FEATURE_CACHE_CTRL) {
726                 leon3_cache_control_st(env, addr, val, size);
727             }
728             break;
729
730         case 0x01c00000: /* MXCC stream data register 0 */
731             if (size == 8) {
732                 env->mxccdata[0] = val;
733             } else {
734                 qemu_log_mask(LOG_UNIMP,
735                               "%08x: unimplemented access size: %d\n", addr,
736                               size);
737             }
738             break;
739         case 0x01c00008: /* MXCC stream data register 1 */
740             if (size == 8) {
741                 env->mxccdata[1] = val;
742             } else {
743                 qemu_log_mask(LOG_UNIMP,
744                               "%08x: unimplemented access size: %d\n", addr,
745                               size);
746             }
747             break;
748         case 0x01c00010: /* MXCC stream data register 2 */
749             if (size == 8) {
750                 env->mxccdata[2] = val;
751             } else {
752                 qemu_log_mask(LOG_UNIMP,
753                               "%08x: unimplemented access size: %d\n", addr,
754                               size);
755             }
756             break;
757         case 0x01c00018: /* MXCC stream data register 3 */
758             if (size == 8) {
759                 env->mxccdata[3] = val;
760             } else {
761                 qemu_log_mask(LOG_UNIMP,
762                               "%08x: unimplemented access size: %d\n", addr,
763                               size);
764             }
765             break;
766         case 0x01c00100: /* MXCC stream source */
767             if (size == 8) {
768                 env->mxccregs[0] = val;
769             } else {
770                 qemu_log_mask(LOG_UNIMP,
771                               "%08x: unimplemented access size: %d\n", addr,
772                               size);
773             }
774             env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
775                                         0);
776             env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
777                                         8);
778             env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
779                                         16);
780             env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
781                                         24);
782             break;
783         case 0x01c00200: /* MXCC stream destination */
784             if (size == 8) {
785                 env->mxccregs[1] = val;
786             } else {
787                 qemu_log_mask(LOG_UNIMP,
788                               "%08x: unimplemented access size: %d\n", addr,
789                               size);
790             }
791             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0,
792                      env->mxccdata[0]);
793             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8,
794                      env->mxccdata[1]);
795             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16,
796                      env->mxccdata[2]);
797             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24,
798                      env->mxccdata[3]);
799             break;
800         case 0x01c00a00: /* MXCC control register */
801             if (size == 8) {
802                 env->mxccregs[3] = val;
803             } else {
804                 qemu_log_mask(LOG_UNIMP,
805                               "%08x: unimplemented access size: %d\n", addr,
806                               size);
807             }
808             break;
809         case 0x01c00a04: /* MXCC control register */
810             if (size == 4) {
811                 env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
812                     | val;
813             } else {
814                 qemu_log_mask(LOG_UNIMP,
815                               "%08x: unimplemented access size: %d\n", addr,
816                               size);
817             }
818             break;
819         case 0x01c00e00: /* MXCC error register  */
820             /* writing a 1 bit clears the error */
821             if (size == 8) {
822                 env->mxccregs[6] &= ~val;
823             } else {
824                 qemu_log_mask(LOG_UNIMP,
825                               "%08x: unimplemented access size: %d\n", addr,
826                               size);
827             }
828             break;
829         case 0x01c00f00: /* MBus port address register */
830             if (size == 8) {
831                 env->mxccregs[7] = val;
832             } else {
833                 qemu_log_mask(LOG_UNIMP,
834                               "%08x: unimplemented access size: %d\n", addr,
835                               size);
836             }
837             break;
838         default:
839             qemu_log_mask(LOG_UNIMP,
840                           "%08x: unimplemented address, size: %d\n", addr,
841                           size);
842             break;
843         }
844         DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
845                      asi, size, addr, val);
846 #ifdef DEBUG_MXCC
847         dump_mxcc(env);
848 #endif
849         break;
850     case 3: /* MMU flush */
851     case 0x18: /* LEON3 MMU flush */
852         {
853             int mmulev;
854
855             mmulev = (addr >> 8) & 15;
856             DPRINTF_MMU("mmu flush level %d\n", mmulev);
857             switch (mmulev) {
858             case 0: /* flush page */
859                 tlb_flush_page(env, addr & 0xfffff000);
860                 break;
861             case 1: /* flush segment (256k) */
862             case 2: /* flush region (16M) */
863             case 3: /* flush context (4G) */
864             case 4: /* flush entire */
865                 tlb_flush(env, 1);
866                 break;
867             default:
868                 break;
869             }
870 #ifdef DEBUG_MMU
871             dump_mmu(stdout, fprintf, env);
872 #endif
873         }
874         break;
875     case 4: /* write MMU regs */
876     case 0x19: /* LEON3 write MMU regs */
877         {
878             int reg = (addr >> 8) & 0x1f;
879             uint32_t oldreg;
880
881             oldreg = env->mmuregs[reg];
882             switch (reg) {
883             case 0: /* Control Register */
884                 env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
885                     (val & 0x00ffffff);
886                 /* Mappings generated during no-fault mode or MMU
887                    disabled mode are invalid in normal mode */
888                 if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
889                     (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm))) {
890                     tlb_flush(env, 1);
891                 }
892                 break;
893             case 1: /* Context Table Pointer Register */
894                 env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
895                 break;
896             case 2: /* Context Register */
897                 env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
898                 if (oldreg != env->mmuregs[reg]) {
899                     /* we flush when the MMU context changes because
900                        QEMU has no MMU context support */
901                     tlb_flush(env, 1);
902                 }
903                 break;
904             case 3: /* Synchronous Fault Status Register with Clear */
905             case 4: /* Synchronous Fault Address Register */
906                 break;
907             case 0x10: /* TLB Replacement Control Register */
908                 env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
909                 break;
910             case 0x13: /* Synchronous Fault Status Register with Read
911                           and Clear */
912                 env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
913                 break;
914             case 0x14: /* Synchronous Fault Address Register */
915                 env->mmuregs[4] = val;
916                 break;
917             default:
918                 env->mmuregs[reg] = val;
919                 break;
920             }
921             if (oldreg != env->mmuregs[reg]) {
922                 DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
923                             reg, oldreg, env->mmuregs[reg]);
924             }
925 #ifdef DEBUG_MMU
926             dump_mmu(stdout, fprintf, env);
927 #endif
928         }
929         break;
930     case 5: /* Turbosparc ITLB Diagnostic */
931     case 6: /* Turbosparc DTLB Diagnostic */
932     case 7: /* Turbosparc IOTLB Diagnostic */
933         break;
934     case 0xa: /* User data access */
935         switch (size) {
936         case 1:
937             cpu_stb_user(env, addr, val);
938             break;
939         case 2:
940             cpu_stw_user(env, addr, val);
941             break;
942         default:
943         case 4:
944             cpu_stl_user(env, addr, val);
945             break;
946         case 8:
947             cpu_stq_user(env, addr, val);
948             break;
949         }
950         break;
951     case 0xb: /* Supervisor data access */
952         switch (size) {
953         case 1:
954             cpu_stb_kernel(env, addr, val);
955             break;
956         case 2:
957             cpu_stw_kernel(env, addr, val);
958             break;
959         default:
960         case 4:
961             cpu_stl_kernel(env, addr, val);
962             break;
963         case 8:
964             cpu_stq_kernel(env, addr, val);
965             break;
966         }
967         break;
968     case 0xc: /* I-cache tag */
969     case 0xd: /* I-cache data */
970     case 0xe: /* D-cache tag */
971     case 0xf: /* D-cache data */
972     case 0x10: /* I/D-cache flush page */
973     case 0x11: /* I/D-cache flush segment */
974     case 0x12: /* I/D-cache flush region */
975     case 0x13: /* I/D-cache flush context */
976     case 0x14: /* I/D-cache flush user */
977         break;
978     case 0x17: /* Block copy, sta access */
979         {
980             /* val = src
981                addr = dst
982                copy 32 bytes */
983             unsigned int i;
984             uint32_t src = val & ~3, dst = addr & ~3, temp;
985
986             for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
987                 temp = cpu_ldl_kernel(env, src);
988                 cpu_stl_kernel(env, dst, temp);
989             }
990         }
991         break;
992     case 0x1f: /* Block fill, stda access */
993         {
994             /* addr = dst
995                fill 32 bytes with val */
996             unsigned int i;
997             uint32_t dst = addr & 7;
998
999             for (i = 0; i < 32; i += 8, dst += 8) {
1000                 cpu_stq_kernel(env, dst, val);
1001             }
1002         }
1003         break;
1004     case 0x20: /* MMU passthrough */
1005     case 0x1c: /* LEON MMU passthrough */
1006         {
1007             switch (size) {
1008             case 1:
1009                 stb_phys(addr, val);
1010                 break;
1011             case 2:
1012                 stw_phys(addr, val);
1013                 break;
1014             case 4:
1015             default:
1016                 stl_phys(addr, val);
1017                 break;
1018             case 8:
1019                 stq_phys(addr, val);
1020                 break;
1021             }
1022         }
1023         break;
1024     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1025         {
1026             switch (size) {
1027             case 1:
1028                 stb_phys((hwaddr)addr
1029                          | ((hwaddr)(asi & 0xf) << 32), val);
1030                 break;
1031             case 2:
1032                 stw_phys((hwaddr)addr
1033                          | ((hwaddr)(asi & 0xf) << 32), val);
1034                 break;
1035             case 4:
1036             default:
1037                 stl_phys((hwaddr)addr
1038                          | ((hwaddr)(asi & 0xf) << 32), val);
1039                 break;
1040             case 8:
1041                 stq_phys((hwaddr)addr
1042                          | ((hwaddr)(asi & 0xf) << 32), val);
1043                 break;
1044             }
1045         }
1046         break;
1047     case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
1048     case 0x31: /* store buffer data, Ross RT620 I-cache flush or
1049                   Turbosparc snoop RAM */
1050     case 0x32: /* store buffer control or Turbosparc page table
1051                   descriptor diagnostic */
1052     case 0x36: /* I-cache flash clear */
1053     case 0x37: /* D-cache flash clear */
1054         break;
1055     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
1056         {
1057             int reg = (addr >> 8) & 3;
1058
1059             switch (reg) {
1060             case 0: /* Breakpoint Value (Addr) */
1061                 env->mmubpregs[reg] = (val & 0xfffffffffULL);
1062                 break;
1063             case 1: /* Breakpoint Mask */
1064                 env->mmubpregs[reg] = (val & 0xfffffffffULL);
1065                 break;
1066             case 2: /* Breakpoint Control */
1067                 env->mmubpregs[reg] = (val & 0x7fULL);
1068                 break;
1069             case 3: /* Breakpoint Status */
1070                 env->mmubpregs[reg] = (val & 0xfULL);
1071                 break;
1072             }
1073             DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg,
1074                         env->mmuregs[reg]);
1075         }
1076         break;
1077     case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
1078         env->mmubpctrv = val & 0xffffffff;
1079         break;
1080     case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
1081         env->mmubpctrc = val & 0x3;
1082         break;
1083     case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
1084         env->mmubpctrs = val & 0x3;
1085         break;
1086     case 0x4c: /* SuperSPARC MMU Breakpoint Action */
1087         env->mmubpaction = val & 0x1fff;
1088         break;
1089     case 8: /* User code access, XXX */
1090     case 9: /* Supervisor code access, XXX */
1091     default:
1092         cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
1093                               addr, true, false, asi, size);
1094         break;
1095     }
1096 #ifdef DEBUG_ASI
1097     dump_asi("write", addr, asi, size, val);
1098 #endif
1099 }
1100
1101 #endif /* CONFIG_USER_ONLY */
1102 #else /* TARGET_SPARC64 */
1103
1104 #ifdef CONFIG_USER_ONLY
1105 uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1106                        int sign)
1107 {
1108     uint64_t ret = 0;
1109 #if defined(DEBUG_ASI)
1110     target_ulong last_addr = addr;
1111 #endif
1112
1113     if (asi < 0x80) {
1114         helper_raise_exception(env, TT_PRIV_ACT);
1115     }
1116
1117     helper_check_align(env, addr, size - 1);
1118     addr = asi_address_mask(env, asi, addr);
1119
1120     switch (asi) {
1121     case 0x82: /* Primary no-fault */
1122     case 0x8a: /* Primary no-fault LE */
1123         if (page_check_range(addr, size, PAGE_READ) == -1) {
1124 #ifdef DEBUG_ASI
1125             dump_asi("read ", last_addr, asi, size, ret);
1126 #endif
1127             return 0;
1128         }
1129         /* Fall through */
1130     case 0x80: /* Primary */
1131     case 0x88: /* Primary LE */
1132         {
1133             switch (size) {
1134             case 1:
1135                 ret = ldub_raw(addr);
1136                 break;
1137             case 2:
1138                 ret = lduw_raw(addr);
1139                 break;
1140             case 4:
1141                 ret = ldl_raw(addr);
1142                 break;
1143             default:
1144             case 8:
1145                 ret = ldq_raw(addr);
1146                 break;
1147             }
1148         }
1149         break;
1150     case 0x83: /* Secondary no-fault */
1151     case 0x8b: /* Secondary no-fault LE */
1152         if (page_check_range(addr, size, PAGE_READ) == -1) {
1153 #ifdef DEBUG_ASI
1154             dump_asi("read ", last_addr, asi, size, ret);
1155 #endif
1156             return 0;
1157         }
1158         /* Fall through */
1159     case 0x81: /* Secondary */
1160     case 0x89: /* Secondary LE */
1161         /* XXX */
1162         break;
1163     default:
1164         break;
1165     }
1166
1167     /* Convert from little endian */
1168     switch (asi) {
1169     case 0x88: /* Primary LE */
1170     case 0x89: /* Secondary LE */
1171     case 0x8a: /* Primary no-fault LE */
1172     case 0x8b: /* Secondary no-fault LE */
1173         switch (size) {
1174         case 2:
1175             ret = bswap16(ret);
1176             break;
1177         case 4:
1178             ret = bswap32(ret);
1179             break;
1180         case 8:
1181             ret = bswap64(ret);
1182             break;
1183         default:
1184             break;
1185         }
1186     default:
1187         break;
1188     }
1189
1190     /* Convert to signed number */
1191     if (sign) {
1192         switch (size) {
1193         case 1:
1194             ret = (int8_t) ret;
1195             break;
1196         case 2:
1197             ret = (int16_t) ret;
1198             break;
1199         case 4:
1200             ret = (int32_t) ret;
1201             break;
1202         default:
1203             break;
1204         }
1205     }
1206 #ifdef DEBUG_ASI
1207     dump_asi("read ", last_addr, asi, size, ret);
1208 #endif
1209     return ret;
1210 }
1211
1212 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
1213                    int asi, int size)
1214 {
1215 #ifdef DEBUG_ASI
1216     dump_asi("write", addr, asi, size, val);
1217 #endif
1218     if (asi < 0x80) {
1219         helper_raise_exception(env, TT_PRIV_ACT);
1220     }
1221
1222     helper_check_align(env, addr, size - 1);
1223     addr = asi_address_mask(env, asi, addr);
1224
1225     /* Convert to little endian */
1226     switch (asi) {
1227     case 0x88: /* Primary LE */
1228     case 0x89: /* Secondary LE */
1229         switch (size) {
1230         case 2:
1231             val = bswap16(val);
1232             break;
1233         case 4:
1234             val = bswap32(val);
1235             break;
1236         case 8:
1237             val = bswap64(val);
1238             break;
1239         default:
1240             break;
1241         }
1242     default:
1243         break;
1244     }
1245
1246     switch (asi) {
1247     case 0x80: /* Primary */
1248     case 0x88: /* Primary LE */
1249         {
1250             switch (size) {
1251             case 1:
1252                 stb_raw(addr, val);
1253                 break;
1254             case 2:
1255                 stw_raw(addr, val);
1256                 break;
1257             case 4:
1258                 stl_raw(addr, val);
1259                 break;
1260             case 8:
1261             default:
1262                 stq_raw(addr, val);
1263                 break;
1264             }
1265         }
1266         break;
1267     case 0x81: /* Secondary */
1268     case 0x89: /* Secondary LE */
1269         /* XXX */
1270         return;
1271
1272     case 0x82: /* Primary no-fault, RO */
1273     case 0x83: /* Secondary no-fault, RO */
1274     case 0x8a: /* Primary no-fault LE, RO */
1275     case 0x8b: /* Secondary no-fault LE, RO */
1276     default:
1277         helper_raise_exception(env, TT_DATA_ACCESS);
1278         return;
1279     }
1280 }
1281
1282 #else /* CONFIG_USER_ONLY */
1283
1284 uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1285                        int sign)
1286 {
1287     uint64_t ret = 0;
1288 #if defined(DEBUG_ASI)
1289     target_ulong last_addr = addr;
1290 #endif
1291
1292     asi &= 0xff;
1293
1294     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1295         || (cpu_has_hypervisor(env)
1296             && asi >= 0x30 && asi < 0x80
1297             && !(env->hpstate & HS_PRIV))) {
1298         helper_raise_exception(env, TT_PRIV_ACT);
1299     }
1300
1301     helper_check_align(env, addr, size - 1);
1302     addr = asi_address_mask(env, asi, addr);
1303
1304     /* process nonfaulting loads first */
1305     if ((asi & 0xf6) == 0x82) {
1306         int mmu_idx;
1307
1308         /* secondary space access has lowest asi bit equal to 1 */
1309         if (env->pstate & PS_PRIV) {
1310             mmu_idx = (asi & 1) ? MMU_KERNEL_SECONDARY_IDX : MMU_KERNEL_IDX;
1311         } else {
1312             mmu_idx = (asi & 1) ? MMU_USER_SECONDARY_IDX : MMU_USER_IDX;
1313         }
1314
1315         if (cpu_get_phys_page_nofault(env, addr, mmu_idx) == -1ULL) {
1316 #ifdef DEBUG_ASI
1317             dump_asi("read ", last_addr, asi, size, ret);
1318 #endif
1319             /* env->exception_index is set in get_physical_address_data(). */
1320             helper_raise_exception(env, env->exception_index);
1321         }
1322
1323         /* convert nonfaulting load ASIs to normal load ASIs */
1324         asi &= ~0x02;
1325     }
1326
1327     switch (asi) {
1328     case 0x10: /* As if user primary */
1329     case 0x11: /* As if user secondary */
1330     case 0x18: /* As if user primary LE */
1331     case 0x19: /* As if user secondary LE */
1332     case 0x80: /* Primary */
1333     case 0x81: /* Secondary */
1334     case 0x88: /* Primary LE */
1335     case 0x89: /* Secondary LE */
1336     case 0xe2: /* UA2007 Primary block init */
1337     case 0xe3: /* UA2007 Secondary block init */
1338         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1339             if (cpu_hypervisor_mode(env)) {
1340                 switch (size) {
1341                 case 1:
1342                     ret = cpu_ldub_hypv(env, addr);
1343                     break;
1344                 case 2:
1345                     ret = cpu_lduw_hypv(env, addr);
1346                     break;
1347                 case 4:
1348                     ret = cpu_ldl_hypv(env, addr);
1349                     break;
1350                 default:
1351                 case 8:
1352                     ret = cpu_ldq_hypv(env, addr);
1353                     break;
1354                 }
1355             } else {
1356                 /* secondary space access has lowest asi bit equal to 1 */
1357                 if (asi & 1) {
1358                     switch (size) {
1359                     case 1:
1360                         ret = cpu_ldub_kernel_secondary(env, addr);
1361                         break;
1362                     case 2:
1363                         ret = cpu_lduw_kernel_secondary(env, addr);
1364                         break;
1365                     case 4:
1366                         ret = cpu_ldl_kernel_secondary(env, addr);
1367                         break;
1368                     default:
1369                     case 8:
1370                         ret = cpu_ldq_kernel_secondary(env, addr);
1371                         break;
1372                     }
1373                 } else {
1374                     switch (size) {
1375                     case 1:
1376                         ret = cpu_ldub_kernel(env, addr);
1377                         break;
1378                     case 2:
1379                         ret = cpu_lduw_kernel(env, addr);
1380                         break;
1381                     case 4:
1382                         ret = cpu_ldl_kernel(env, addr);
1383                         break;
1384                     default:
1385                     case 8:
1386                         ret = cpu_ldq_kernel(env, addr);
1387                         break;
1388                     }
1389                 }
1390             }
1391         } else {
1392             /* secondary space access has lowest asi bit equal to 1 */
1393             if (asi & 1) {
1394                 switch (size) {
1395                 case 1:
1396                     ret = cpu_ldub_user_secondary(env, addr);
1397                     break;
1398                 case 2:
1399                     ret = cpu_lduw_user_secondary(env, addr);
1400                     break;
1401                 case 4:
1402                     ret = cpu_ldl_user_secondary(env, addr);
1403                     break;
1404                 default:
1405                 case 8:
1406                     ret = cpu_ldq_user_secondary(env, addr);
1407                     break;
1408                 }
1409             } else {
1410                 switch (size) {
1411                 case 1:
1412                     ret = cpu_ldub_user(env, addr);
1413                     break;
1414                 case 2:
1415                     ret = cpu_lduw_user(env, addr);
1416                     break;
1417                 case 4:
1418                     ret = cpu_ldl_user(env, addr);
1419                     break;
1420                 default:
1421                 case 8:
1422                     ret = cpu_ldq_user(env, addr);
1423                     break;
1424                 }
1425             }
1426         }
1427         break;
1428     case 0x14: /* Bypass */
1429     case 0x15: /* Bypass, non-cacheable */
1430     case 0x1c: /* Bypass LE */
1431     case 0x1d: /* Bypass, non-cacheable LE */
1432         {
1433             switch (size) {
1434             case 1:
1435                 ret = ldub_phys(addr);
1436                 break;
1437             case 2:
1438                 ret = lduw_phys(addr);
1439                 break;
1440             case 4:
1441                 ret = ldl_phys(addr);
1442                 break;
1443             default:
1444             case 8:
1445                 ret = ldq_phys(addr);
1446                 break;
1447             }
1448             break;
1449         }
1450     case 0x24: /* Nucleus quad LDD 128 bit atomic */
1451     case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
1452                   Only ldda allowed */
1453         helper_raise_exception(env, TT_ILL_INSN);
1454         return 0;
1455     case 0x04: /* Nucleus */
1456     case 0x0c: /* Nucleus Little Endian (LE) */
1457         {
1458             switch (size) {
1459             case 1:
1460                 ret = cpu_ldub_nucleus(env, addr);
1461                 break;
1462             case 2:
1463                 ret = cpu_lduw_nucleus(env, addr);
1464                 break;
1465             case 4:
1466                 ret = cpu_ldl_nucleus(env, addr);
1467                 break;
1468             default:
1469             case 8:
1470                 ret = cpu_ldq_nucleus(env, addr);
1471                 break;
1472             }
1473             break;
1474         }
1475     case 0x4a: /* UPA config */
1476         /* XXX */
1477         break;
1478     case 0x45: /* LSU */
1479         ret = env->lsu;
1480         break;
1481     case 0x50: /* I-MMU regs */
1482         {
1483             int reg = (addr >> 3) & 0xf;
1484
1485             if (reg == 0) {
1486                 /* I-TSB Tag Target register */
1487                 ret = ultrasparc_tag_target(env->immu.tag_access);
1488             } else {
1489                 ret = env->immuregs[reg];
1490             }
1491
1492             break;
1493         }
1494     case 0x51: /* I-MMU 8k TSB pointer */
1495         {
1496             /* env->immuregs[5] holds I-MMU TSB register value
1497                env->immuregs[6] holds I-MMU Tag Access register value */
1498             ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
1499                                          8*1024);
1500             break;
1501         }
1502     case 0x52: /* I-MMU 64k TSB pointer */
1503         {
1504             /* env->immuregs[5] holds I-MMU TSB register value
1505                env->immuregs[6] holds I-MMU Tag Access register value */
1506             ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
1507                                          64*1024);
1508             break;
1509         }
1510     case 0x55: /* I-MMU data access */
1511         {
1512             int reg = (addr >> 3) & 0x3f;
1513
1514             ret = env->itlb[reg].tte;
1515             break;
1516         }
1517     case 0x56: /* I-MMU tag read */
1518         {
1519             int reg = (addr >> 3) & 0x3f;
1520
1521             ret = env->itlb[reg].tag;
1522             break;
1523         }
1524     case 0x58: /* D-MMU regs */
1525         {
1526             int reg = (addr >> 3) & 0xf;
1527
1528             if (reg == 0) {
1529                 /* D-TSB Tag Target register */
1530                 ret = ultrasparc_tag_target(env->dmmu.tag_access);
1531             } else {
1532                 ret = env->dmmuregs[reg];
1533             }
1534             break;
1535         }
1536     case 0x59: /* D-MMU 8k TSB pointer */
1537         {
1538             /* env->dmmuregs[5] holds D-MMU TSB register value
1539                env->dmmuregs[6] holds D-MMU Tag Access register value */
1540             ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
1541                                          8*1024);
1542             break;
1543         }
1544     case 0x5a: /* D-MMU 64k TSB pointer */
1545         {
1546             /* env->dmmuregs[5] holds D-MMU TSB register value
1547                env->dmmuregs[6] holds D-MMU Tag Access register value */
1548             ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
1549                                          64*1024);
1550             break;
1551         }
1552     case 0x5d: /* D-MMU data access */
1553         {
1554             int reg = (addr >> 3) & 0x3f;
1555
1556             ret = env->dtlb[reg].tte;
1557             break;
1558         }
1559     case 0x5e: /* D-MMU tag read */
1560         {
1561             int reg = (addr >> 3) & 0x3f;
1562
1563             ret = env->dtlb[reg].tag;
1564             break;
1565         }
1566     case 0x48: /* Interrupt dispatch, RO */
1567         break;
1568     case 0x49: /* Interrupt data receive */
1569         ret = env->ivec_status;
1570         break;
1571     case 0x7f: /* Incoming interrupt vector, RO */
1572         {
1573             int reg = (addr >> 4) & 0x3;
1574             if (reg < 3) {
1575                 ret = env->ivec_data[reg];
1576             }
1577             break;
1578         }
1579     case 0x46: /* D-cache data */
1580     case 0x47: /* D-cache tag access */
1581     case 0x4b: /* E-cache error enable */
1582     case 0x4c: /* E-cache asynchronous fault status */
1583     case 0x4d: /* E-cache asynchronous fault address */
1584     case 0x4e: /* E-cache tag data */
1585     case 0x66: /* I-cache instruction access */
1586     case 0x67: /* I-cache tag access */
1587     case 0x6e: /* I-cache predecode */
1588     case 0x6f: /* I-cache LRU etc. */
1589     case 0x76: /* E-cache tag */
1590     case 0x7e: /* E-cache tag */
1591         break;
1592     case 0x5b: /* D-MMU data pointer */
1593     case 0x54: /* I-MMU data in, WO */
1594     case 0x57: /* I-MMU demap, WO */
1595     case 0x5c: /* D-MMU data in, WO */
1596     case 0x5f: /* D-MMU demap, WO */
1597     case 0x77: /* Interrupt vector, WO */
1598     default:
1599         cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
1600                               addr, false, false, 1, size);
1601         ret = 0;
1602         break;
1603     }
1604
1605     /* Convert from little endian */
1606     switch (asi) {
1607     case 0x0c: /* Nucleus Little Endian (LE) */
1608     case 0x18: /* As if user primary LE */
1609     case 0x19: /* As if user secondary LE */
1610     case 0x1c: /* Bypass LE */
1611     case 0x1d: /* Bypass, non-cacheable LE */
1612     case 0x88: /* Primary LE */
1613     case 0x89: /* Secondary LE */
1614         switch(size) {
1615         case 2:
1616             ret = bswap16(ret);
1617             break;
1618         case 4:
1619             ret = bswap32(ret);
1620             break;
1621         case 8:
1622             ret = bswap64(ret);
1623             break;
1624         default:
1625             break;
1626         }
1627     default:
1628         break;
1629     }
1630
1631     /* Convert to signed number */
1632     if (sign) {
1633         switch (size) {
1634         case 1:
1635             ret = (int8_t) ret;
1636             break;
1637         case 2:
1638             ret = (int16_t) ret;
1639             break;
1640         case 4:
1641             ret = (int32_t) ret;
1642             break;
1643         default:
1644             break;
1645         }
1646     }
1647 #ifdef DEBUG_ASI
1648     dump_asi("read ", last_addr, asi, size, ret);
1649 #endif
1650     return ret;
1651 }
1652
1653 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
1654                    int asi, int size)
1655 {
1656 #ifdef DEBUG_ASI
1657     dump_asi("write", addr, asi, size, val);
1658 #endif
1659
1660     asi &= 0xff;
1661
1662     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1663         || (cpu_has_hypervisor(env)
1664             && asi >= 0x30 && asi < 0x80
1665             && !(env->hpstate & HS_PRIV))) {
1666         helper_raise_exception(env, TT_PRIV_ACT);
1667     }
1668
1669     helper_check_align(env, addr, size - 1);
1670     addr = asi_address_mask(env, asi, addr);
1671
1672     /* Convert to little endian */
1673     switch (asi) {
1674     case 0x0c: /* Nucleus Little Endian (LE) */
1675     case 0x18: /* As if user primary LE */
1676     case 0x19: /* As if user secondary LE */
1677     case 0x1c: /* Bypass LE */
1678     case 0x1d: /* Bypass, non-cacheable LE */
1679     case 0x88: /* Primary LE */
1680     case 0x89: /* Secondary LE */
1681         switch (size) {
1682         case 2:
1683             val = bswap16(val);
1684             break;
1685         case 4:
1686             val = bswap32(val);
1687             break;
1688         case 8:
1689             val = bswap64(val);
1690             break;
1691         default:
1692             break;
1693         }
1694     default:
1695         break;
1696     }
1697
1698     switch (asi) {
1699     case 0x10: /* As if user primary */
1700     case 0x11: /* As if user secondary */
1701     case 0x18: /* As if user primary LE */
1702     case 0x19: /* As if user secondary LE */
1703     case 0x80: /* Primary */
1704     case 0x81: /* Secondary */
1705     case 0x88: /* Primary LE */
1706     case 0x89: /* Secondary LE */
1707     case 0xe2: /* UA2007 Primary block init */
1708     case 0xe3: /* UA2007 Secondary block init */
1709         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1710             if (cpu_hypervisor_mode(env)) {
1711                 switch (size) {
1712                 case 1:
1713                     cpu_stb_hypv(env, addr, val);
1714                     break;
1715                 case 2:
1716                     cpu_stw_hypv(env, addr, val);
1717                     break;
1718                 case 4:
1719                     cpu_stl_hypv(env, addr, val);
1720                     break;
1721                 case 8:
1722                 default:
1723                     cpu_stq_hypv(env, addr, val);
1724                     break;
1725                 }
1726             } else {
1727                 /* secondary space access has lowest asi bit equal to 1 */
1728                 if (asi & 1) {
1729                     switch (size) {
1730                     case 1:
1731                         cpu_stb_kernel_secondary(env, addr, val);
1732                         break;
1733                     case 2:
1734                         cpu_stw_kernel_secondary(env, addr, val);
1735                         break;
1736                     case 4:
1737                         cpu_stl_kernel_secondary(env, addr, val);
1738                         break;
1739                     case 8:
1740                     default:
1741                         cpu_stq_kernel_secondary(env, addr, val);
1742                         break;
1743                     }
1744                 } else {
1745                     switch (size) {
1746                     case 1:
1747                         cpu_stb_kernel(env, addr, val);
1748                         break;
1749                     case 2:
1750                         cpu_stw_kernel(env, addr, val);
1751                         break;
1752                     case 4:
1753                         cpu_stl_kernel(env, addr, val);
1754                         break;
1755                     case 8:
1756                     default:
1757                         cpu_stq_kernel(env, addr, val);
1758                         break;
1759                     }
1760                 }
1761             }
1762         } else {
1763             /* secondary space access has lowest asi bit equal to 1 */
1764             if (asi & 1) {
1765                 switch (size) {
1766                 case 1:
1767                     cpu_stb_user_secondary(env, addr, val);
1768                     break;
1769                 case 2:
1770                     cpu_stw_user_secondary(env, addr, val);
1771                     break;
1772                 case 4:
1773                     cpu_stl_user_secondary(env, addr, val);
1774                     break;
1775                 case 8:
1776                 default:
1777                     cpu_stq_user_secondary(env, addr, val);
1778                     break;
1779                 }
1780             } else {
1781                 switch (size) {
1782                 case 1:
1783                     cpu_stb_user(env, addr, val);
1784                     break;
1785                 case 2:
1786                     cpu_stw_user(env, addr, val);
1787                     break;
1788                 case 4:
1789                     cpu_stl_user(env, addr, val);
1790                     break;
1791                 case 8:
1792                 default:
1793                     cpu_stq_user(env, addr, val);
1794                     break;
1795                 }
1796             }
1797         }
1798         break;
1799     case 0x14: /* Bypass */
1800     case 0x15: /* Bypass, non-cacheable */
1801     case 0x1c: /* Bypass LE */
1802     case 0x1d: /* Bypass, non-cacheable LE */
1803         {
1804             switch (size) {
1805             case 1:
1806                 stb_phys(addr, val);
1807                 break;
1808             case 2:
1809                 stw_phys(addr, val);
1810                 break;
1811             case 4:
1812                 stl_phys(addr, val);
1813                 break;
1814             case 8:
1815             default:
1816                 stq_phys(addr, val);
1817                 break;
1818             }
1819         }
1820         return;
1821     case 0x24: /* Nucleus quad LDD 128 bit atomic */
1822     case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
1823                   Only ldda allowed */
1824         helper_raise_exception(env, TT_ILL_INSN);
1825         return;
1826     case 0x04: /* Nucleus */
1827     case 0x0c: /* Nucleus Little Endian (LE) */
1828         {
1829             switch (size) {
1830             case 1:
1831                 cpu_stb_nucleus(env, addr, val);
1832                 break;
1833             case 2:
1834                 cpu_stw_nucleus(env, addr, val);
1835                 break;
1836             case 4:
1837                 cpu_stl_nucleus(env, addr, val);
1838                 break;
1839             default:
1840             case 8:
1841                 cpu_stq_nucleus(env, addr, val);
1842                 break;
1843             }
1844             break;
1845         }
1846
1847     case 0x4a: /* UPA config */
1848         /* XXX */
1849         return;
1850     case 0x45: /* LSU */
1851         {
1852             uint64_t oldreg;
1853
1854             oldreg = env->lsu;
1855             env->lsu = val & (DMMU_E | IMMU_E);
1856             /* Mappings generated during D/I MMU disabled mode are
1857                invalid in normal mode */
1858             if (oldreg != env->lsu) {
1859                 DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
1860                             oldreg, env->lsu);
1861 #ifdef DEBUG_MMU
1862                 dump_mmu(stdout, fprintf, env);
1863 #endif
1864                 tlb_flush(env, 1);
1865             }
1866             return;
1867         }
1868     case 0x50: /* I-MMU regs */
1869         {
1870             int reg = (addr >> 3) & 0xf;
1871             uint64_t oldreg;
1872
1873             oldreg = env->immuregs[reg];
1874             switch (reg) {
1875             case 0: /* RO */
1876                 return;
1877             case 1: /* Not in I-MMU */
1878             case 2:
1879                 return;
1880             case 3: /* SFSR */
1881                 if ((val & 1) == 0) {
1882                     val = 0; /* Clear SFSR */
1883                 }
1884                 env->immu.sfsr = val;
1885                 break;
1886             case 4: /* RO */
1887                 return;
1888             case 5: /* TSB access */
1889                 DPRINTF_MMU("immu TSB write: 0x%016" PRIx64 " -> 0x%016"
1890                             PRIx64 "\n", env->immu.tsb, val);
1891                 env->immu.tsb = val;
1892                 break;
1893             case 6: /* Tag access */
1894                 env->immu.tag_access = val;
1895                 break;
1896             case 7:
1897             case 8:
1898                 return;
1899             default:
1900                 break;
1901             }
1902
1903             if (oldreg != env->immuregs[reg]) {
1904                 DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
1905                             PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1906             }
1907 #ifdef DEBUG_MMU
1908             dump_mmu(stdout, fprintf, env);
1909 #endif
1910             return;
1911         }
1912     case 0x54: /* I-MMU data in */
1913         replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env);
1914         return;
1915     case 0x55: /* I-MMU data access */
1916         {
1917             /* TODO: auto demap */
1918
1919             unsigned int i = (addr >> 3) & 0x3f;
1920
1921             replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env);
1922
1923 #ifdef DEBUG_MMU
1924             DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
1925             dump_mmu(stdout, fprintf, env);
1926 #endif
1927             return;
1928         }
1929     case 0x57: /* I-MMU demap */
1930         demap_tlb(env->itlb, addr, "immu", env);
1931         return;
1932     case 0x58: /* D-MMU regs */
1933         {
1934             int reg = (addr >> 3) & 0xf;
1935             uint64_t oldreg;
1936
1937             oldreg = env->dmmuregs[reg];
1938             switch (reg) {
1939             case 0: /* RO */
1940             case 4:
1941                 return;
1942             case 3: /* SFSR */
1943                 if ((val & 1) == 0) {
1944                     val = 0; /* Clear SFSR, Fault address */
1945                     env->dmmu.sfar = 0;
1946                 }
1947                 env->dmmu.sfsr = val;
1948                 break;
1949             case 1: /* Primary context */
1950                 env->dmmu.mmu_primary_context = val;
1951                 /* can be optimized to only flush MMU_USER_IDX
1952                    and MMU_KERNEL_IDX entries */
1953                 tlb_flush(env, 1);
1954                 break;
1955             case 2: /* Secondary context */
1956                 env->dmmu.mmu_secondary_context = val;
1957                 /* can be optimized to only flush MMU_USER_SECONDARY_IDX
1958                    and MMU_KERNEL_SECONDARY_IDX entries */
1959                 tlb_flush(env, 1);
1960                 break;
1961             case 5: /* TSB access */
1962                 DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
1963                             PRIx64 "\n", env->dmmu.tsb, val);
1964                 env->dmmu.tsb = val;
1965                 break;
1966             case 6: /* Tag access */
1967                 env->dmmu.tag_access = val;
1968                 break;
1969             case 7: /* Virtual Watchpoint */
1970             case 8: /* Physical Watchpoint */
1971             default:
1972                 env->dmmuregs[reg] = val;
1973                 break;
1974             }
1975
1976             if (oldreg != env->dmmuregs[reg]) {
1977                 DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
1978                             PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1979             }
1980 #ifdef DEBUG_MMU
1981             dump_mmu(stdout, fprintf, env);
1982 #endif
1983             return;
1984         }
1985     case 0x5c: /* D-MMU data in */
1986         replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env);
1987         return;
1988     case 0x5d: /* D-MMU data access */
1989         {
1990             unsigned int i = (addr >> 3) & 0x3f;
1991
1992             replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env);
1993
1994 #ifdef DEBUG_MMU
1995             DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
1996             dump_mmu(stdout, fprintf, env);
1997 #endif
1998             return;
1999         }
2000     case 0x5f: /* D-MMU demap */
2001         demap_tlb(env->dtlb, addr, "dmmu", env);
2002         return;
2003     case 0x49: /* Interrupt data receive */
2004         env->ivec_status = val & 0x20;
2005         return;
2006     case 0x46: /* D-cache data */
2007     case 0x47: /* D-cache tag access */
2008     case 0x4b: /* E-cache error enable */
2009     case 0x4c: /* E-cache asynchronous fault status */
2010     case 0x4d: /* E-cache asynchronous fault address */
2011     case 0x4e: /* E-cache tag data */
2012     case 0x66: /* I-cache instruction access */
2013     case 0x67: /* I-cache tag access */
2014     case 0x6e: /* I-cache predecode */
2015     case 0x6f: /* I-cache LRU etc. */
2016     case 0x76: /* E-cache tag */
2017     case 0x7e: /* E-cache tag */
2018         return;
2019     case 0x51: /* I-MMU 8k TSB pointer, RO */
2020     case 0x52: /* I-MMU 64k TSB pointer, RO */
2021     case 0x56: /* I-MMU tag read, RO */
2022     case 0x59: /* D-MMU 8k TSB pointer, RO */
2023     case 0x5a: /* D-MMU 64k TSB pointer, RO */
2024     case 0x5b: /* D-MMU data pointer, RO */
2025     case 0x5e: /* D-MMU tag read, RO */
2026     case 0x48: /* Interrupt dispatch, RO */
2027     case 0x7f: /* Incoming interrupt vector, RO */
2028     case 0x82: /* Primary no-fault, RO */
2029     case 0x83: /* Secondary no-fault, RO */
2030     case 0x8a: /* Primary no-fault LE, RO */
2031     case 0x8b: /* Secondary no-fault LE, RO */
2032     default:
2033         cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
2034                               addr, true, false, 1, size);
2035         return;
2036     }
2037 }
2038 #endif /* CONFIG_USER_ONLY */
2039
2040 void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
2041 {
2042     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2043         || (cpu_has_hypervisor(env)
2044             && asi >= 0x30 && asi < 0x80
2045             && !(env->hpstate & HS_PRIV))) {
2046         helper_raise_exception(env, TT_PRIV_ACT);
2047     }
2048
2049     addr = asi_address_mask(env, asi, addr);
2050
2051     switch (asi) {
2052 #if !defined(CONFIG_USER_ONLY)
2053     case 0x24: /* Nucleus quad LDD 128 bit atomic */
2054     case 0x2c: /* Nucleus quad LDD 128 bit atomic LE */
2055         helper_check_align(env, addr, 0xf);
2056         if (rd == 0) {
2057             env->gregs[1] = cpu_ldq_nucleus(env, addr + 8);
2058             if (asi == 0x2c) {
2059                 bswap64s(&env->gregs[1]);
2060             }
2061         } else if (rd < 8) {
2062             env->gregs[rd] = cpu_ldq_nucleus(env, addr);
2063             env->gregs[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2064             if (asi == 0x2c) {
2065                 bswap64s(&env->gregs[rd]);
2066                 bswap64s(&env->gregs[rd + 1]);
2067             }
2068         } else {
2069             env->regwptr[rd] = cpu_ldq_nucleus(env, addr);
2070             env->regwptr[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2071             if (asi == 0x2c) {
2072                 bswap64s(&env->regwptr[rd]);
2073                 bswap64s(&env->regwptr[rd + 1]);
2074             }
2075         }
2076         break;
2077 #endif
2078     default:
2079         helper_check_align(env, addr, 0x3);
2080         if (rd == 0) {
2081             env->gregs[1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2082         } else if (rd < 8) {
2083             env->gregs[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2084             env->gregs[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2085         } else {
2086             env->regwptr[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2087             env->regwptr[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2088         }
2089         break;
2090     }
2091 }
2092
2093 void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2094                     int rd)
2095 {
2096     unsigned int i;
2097     target_ulong val;
2098
2099     helper_check_align(env, addr, 3);
2100     addr = asi_address_mask(env, asi, addr);
2101
2102     switch (asi) {
2103     case 0xf0: /* UA2007/JPS1 Block load primary */
2104     case 0xf1: /* UA2007/JPS1 Block load secondary */
2105     case 0xf8: /* UA2007/JPS1 Block load primary LE */
2106     case 0xf9: /* UA2007/JPS1 Block load secondary LE */
2107         if (rd & 7) {
2108             helper_raise_exception(env, TT_ILL_INSN);
2109             return;
2110         }
2111         helper_check_align(env, addr, 0x3f);
2112         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2113             env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x8f, 8, 0);
2114         }
2115         return;
2116
2117     case 0x16: /* UA2007 Block load primary, user privilege */
2118     case 0x17: /* UA2007 Block load secondary, user privilege */
2119     case 0x1e: /* UA2007 Block load primary LE, user privilege */
2120     case 0x1f: /* UA2007 Block load secondary LE, user privilege */
2121     case 0x70: /* JPS1 Block load primary, user privilege */
2122     case 0x71: /* JPS1 Block load secondary, user privilege */
2123     case 0x78: /* JPS1 Block load primary LE, user privilege */
2124     case 0x79: /* JPS1 Block load secondary LE, user privilege */
2125         if (rd & 7) {
2126             helper_raise_exception(env, TT_ILL_INSN);
2127             return;
2128         }
2129         helper_check_align(env, addr, 0x3f);
2130         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2131             env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0);
2132         }
2133         return;
2134
2135     default:
2136         break;
2137     }
2138
2139     switch (size) {
2140     default:
2141     case 4:
2142         val = helper_ld_asi(env, addr, asi, size, 0);
2143         if (rd & 1) {
2144             env->fpr[rd / 2].l.lower = val;
2145         } else {
2146             env->fpr[rd / 2].l.upper = val;
2147         }
2148         break;
2149     case 8:
2150         env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, size, 0);
2151         break;
2152     case 16:
2153         env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, 8, 0);
2154         env->fpr[rd / 2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0);
2155         break;
2156     }
2157 }
2158
2159 void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2160                     int rd)
2161 {
2162     unsigned int i;
2163     target_ulong val;
2164
2165     helper_check_align(env, addr, 3);
2166     addr = asi_address_mask(env, asi, addr);
2167
2168     switch (asi) {
2169     case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
2170     case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
2171     case 0xf0: /* UA2007/JPS1 Block store primary */
2172     case 0xf1: /* UA2007/JPS1 Block store secondary */
2173     case 0xf8: /* UA2007/JPS1 Block store primary LE */
2174     case 0xf9: /* UA2007/JPS1 Block store secondary LE */
2175         if (rd & 7) {
2176             helper_raise_exception(env, TT_ILL_INSN);
2177             return;
2178         }
2179         helper_check_align(env, addr, 0x3f);
2180         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2181             helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x8f, 8);
2182         }
2183
2184         return;
2185     case 0x16: /* UA2007 Block load primary, user privilege */
2186     case 0x17: /* UA2007 Block load secondary, user privilege */
2187     case 0x1e: /* UA2007 Block load primary LE, user privilege */
2188     case 0x1f: /* UA2007 Block load secondary LE, user privilege */
2189     case 0x70: /* JPS1 Block store primary, user privilege */
2190     case 0x71: /* JPS1 Block store secondary, user privilege */
2191     case 0x78: /* JPS1 Block load primary LE, user privilege */
2192     case 0x79: /* JPS1 Block load secondary LE, user privilege */
2193         if (rd & 7) {
2194             helper_raise_exception(env, TT_ILL_INSN);
2195             return;
2196         }
2197         helper_check_align(env, addr, 0x3f);
2198         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2199             helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x19, 8);
2200         }
2201
2202         return;
2203     default:
2204         break;
2205     }
2206
2207     switch (size) {
2208     default:
2209     case 4:
2210         if (rd & 1) {
2211             val = env->fpr[rd / 2].l.lower;
2212         } else {
2213             val = env->fpr[rd / 2].l.upper;
2214         }
2215         helper_st_asi(env, addr, val, asi, size);
2216         break;
2217     case 8:
2218         helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, size);
2219         break;
2220     case 16:
2221         helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, 8);
2222         helper_st_asi(env, addr + 8, env->fpr[rd / 2 + 1].ll, asi, 8);
2223         break;
2224     }
2225 }
2226
2227 target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
2228                             target_ulong val1, target_ulong val2, uint32_t asi)
2229 {
2230     target_ulong ret;
2231
2232     val2 &= 0xffffffffUL;
2233     ret = helper_ld_asi(env, addr, asi, 4, 0);
2234     ret &= 0xffffffffUL;
2235     if (val2 == ret) {
2236         helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
2237     }
2238     return ret;
2239 }
2240
2241 target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
2242                              target_ulong val1, target_ulong val2,
2243                              uint32_t asi)
2244 {
2245     target_ulong ret;
2246
2247     ret = helper_ld_asi(env, addr, asi, 8, 0);
2248     if (val2 == ret) {
2249         helper_st_asi(env, addr, val1, asi, 8);
2250     }
2251     return ret;
2252 }
2253 #endif /* TARGET_SPARC64 */
2254
2255 void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2256 {
2257     /* XXX add 128 bit load */
2258     CPU_QuadU u;
2259
2260     helper_check_align(env, addr, 7);
2261 #if !defined(CONFIG_USER_ONLY)
2262     switch (mem_idx) {
2263     case MMU_USER_IDX:
2264         u.ll.upper = cpu_ldq_user(env, addr);
2265         u.ll.lower = cpu_ldq_user(env, addr + 8);
2266         QT0 = u.q;
2267         break;
2268     case MMU_KERNEL_IDX:
2269         u.ll.upper = cpu_ldq_kernel(env, addr);
2270         u.ll.lower = cpu_ldq_kernel(env, addr + 8);
2271         QT0 = u.q;
2272         break;
2273 #ifdef TARGET_SPARC64
2274     case MMU_HYPV_IDX:
2275         u.ll.upper = cpu_ldq_hypv(env, addr);
2276         u.ll.lower = cpu_ldq_hypv(env, addr + 8);
2277         QT0 = u.q;
2278         break;
2279 #endif
2280     default:
2281         DPRINTF_MMU("helper_ldqf: need to check MMU idx %d\n", mem_idx);
2282         break;
2283     }
2284 #else
2285     u.ll.upper = ldq_raw(address_mask(env, addr));
2286     u.ll.lower = ldq_raw(address_mask(env, addr + 8));
2287     QT0 = u.q;
2288 #endif
2289 }
2290
2291 void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2292 {
2293     /* XXX add 128 bit store */
2294     CPU_QuadU u;
2295
2296     helper_check_align(env, addr, 7);
2297 #if !defined(CONFIG_USER_ONLY)
2298     switch (mem_idx) {
2299     case MMU_USER_IDX:
2300         u.q = QT0;
2301         cpu_stq_user(env, addr, u.ll.upper);
2302         cpu_stq_user(env, addr + 8, u.ll.lower);
2303         break;
2304     case MMU_KERNEL_IDX:
2305         u.q = QT0;
2306         cpu_stq_kernel(env, addr, u.ll.upper);
2307         cpu_stq_kernel(env, addr + 8, u.ll.lower);
2308         break;
2309 #ifdef TARGET_SPARC64
2310     case MMU_HYPV_IDX:
2311         u.q = QT0;
2312         cpu_stq_hypv(env, addr, u.ll.upper);
2313         cpu_stq_hypv(env, addr + 8, u.ll.lower);
2314         break;
2315 #endif
2316     default:
2317         DPRINTF_MMU("helper_stqf: need to check MMU idx %d\n", mem_idx);
2318         break;
2319     }
2320 #else
2321     u.q = QT0;
2322     stq_raw(address_mask(env, addr), u.ll.upper);
2323     stq_raw(address_mask(env, addr + 8), u.ll.lower);
2324 #endif
2325 }
2326
2327 #if !defined(CONFIG_USER_ONLY)
2328 #ifndef TARGET_SPARC64
2329 void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
2330                                  bool is_write, bool is_exec, int is_asi,
2331                                  unsigned size)
2332 {
2333     SPARCCPU *cpu = SPARC_CPU(cs);
2334     CPUSPARCState *env = &cpu->env;
2335     int fault_type;
2336
2337 #ifdef DEBUG_UNASSIGNED
2338     if (is_asi) {
2339         printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
2340                " asi 0x%02x from " TARGET_FMT_lx "\n",
2341                is_exec ? "exec" : is_write ? "write" : "read", size,
2342                size == 1 ? "" : "s", addr, is_asi, env->pc);
2343     } else {
2344         printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
2345                " from " TARGET_FMT_lx "\n",
2346                is_exec ? "exec" : is_write ? "write" : "read", size,
2347                size == 1 ? "" : "s", addr, env->pc);
2348     }
2349 #endif
2350     /* Don't overwrite translation and access faults */
2351     fault_type = (env->mmuregs[3] & 0x1c) >> 2;
2352     if ((fault_type > 4) || (fault_type == 0)) {
2353         env->mmuregs[3] = 0; /* Fault status register */
2354         if (is_asi) {
2355             env->mmuregs[3] |= 1 << 16;
2356         }
2357         if (env->psrs) {
2358             env->mmuregs[3] |= 1 << 5;
2359         }
2360         if (is_exec) {
2361             env->mmuregs[3] |= 1 << 6;
2362         }
2363         if (is_write) {
2364             env->mmuregs[3] |= 1 << 7;
2365         }
2366         env->mmuregs[3] |= (5 << 2) | 2;
2367         /* SuperSPARC will never place instruction fault addresses in the FAR */
2368         if (!is_exec) {
2369             env->mmuregs[4] = addr; /* Fault address register */
2370         }
2371     }
2372     /* overflow (same type fault was not read before another fault) */
2373     if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) {
2374         env->mmuregs[3] |= 1;
2375     }
2376
2377     if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
2378         if (is_exec) {
2379             helper_raise_exception(env, TT_CODE_ACCESS);
2380         } else {
2381             helper_raise_exception(env, TT_DATA_ACCESS);
2382         }
2383     }
2384
2385     /* flush neverland mappings created during no-fault mode,
2386        so the sequential MMU faults report proper fault types */
2387     if (env->mmuregs[0] & MMU_NF) {
2388         tlb_flush(env, 1);
2389     }
2390 }
2391 #else
2392 void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
2393                                  bool is_write, bool is_exec, int is_asi,
2394                                  unsigned size)
2395 {
2396     SPARCCPU *cpu = SPARC_CPU(cs);
2397     CPUSPARCState *env = &cpu->env;
2398
2399 #ifdef DEBUG_UNASSIGNED
2400     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
2401            "\n", addr, env->pc);
2402 #endif
2403
2404     if (is_exec) {
2405         helper_raise_exception(env, TT_CODE_ACCESS);
2406     } else {
2407         helper_raise_exception(env, TT_DATA_ACCESS);
2408     }
2409 }
2410 #endif
2411 #endif
2412
2413 #if !defined(CONFIG_USER_ONLY)
2414 static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
2415                                               target_ulong addr, int is_write,
2416                                               int is_user, uintptr_t retaddr)
2417 {
2418 #ifdef DEBUG_UNALIGNED
2419     printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2420            "\n", addr, env->pc);
2421 #endif
2422     if (retaddr) {
2423         cpu_restore_state(env, retaddr);
2424     }
2425     helper_raise_exception(env, TT_UNALIGNED);
2426 }
2427
2428 /* try to fill the TLB and return an exception if error. If retaddr is
2429    NULL, it means that the function was called in C code (i.e. not
2430    from generated code or from helper.c) */
2431 /* XXX: fix it to restore all registers */
2432 void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx,
2433               uintptr_t retaddr)
2434 {
2435     int ret;
2436
2437     ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
2438     if (ret) {
2439         if (retaddr) {
2440             cpu_restore_state(env, retaddr);
2441         }
2442         cpu_loop_exit(env);
2443     }
2444 }
2445 #endif
This page took 0.159316 seconds and 4 git commands to generate.