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