]> Git Repo - qemu.git/blob - target-sparc/ldst_helper.c
qmp: add ImageInfo in BlockDeviceInfo used by query-block
[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(env, addr, 0, 0, asi, size);
690         ret = 0;
691         break;
692     }
693     if (sign) {
694         switch (size) {
695         case 1:
696             ret = (int8_t) ret;
697             break;
698         case 2:
699             ret = (int16_t) ret;
700             break;
701         case 4:
702             ret = (int32_t) ret;
703             break;
704         default:
705             break;
706         }
707     }
708 #ifdef DEBUG_ASI
709     dump_asi("read ", last_addr, asi, size, ret);
710 #endif
711     return ret;
712 }
713
714 void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
715                    int size)
716 {
717     helper_check_align(env, addr, size - 1);
718     switch (asi) {
719     case 2: /* SuperSparc MXCC registers and Leon3 cache control */
720         switch (addr) {
721         case 0x00:          /* Leon3 Cache Control */
722         case 0x08:          /* Leon3 Instruction Cache config */
723         case 0x0C:          /* Leon3 Date Cache config */
724             if (env->def->features & CPU_FEATURE_CACHE_CTRL) {
725                 leon3_cache_control_st(env, addr, val, size);
726             }
727             break;
728
729         case 0x01c00000: /* MXCC stream data register 0 */
730             if (size == 8) {
731                 env->mxccdata[0] = val;
732             } else {
733                 qemu_log_mask(LOG_UNIMP,
734                               "%08x: unimplemented access size: %d\n", addr,
735                               size);
736             }
737             break;
738         case 0x01c00008: /* MXCC stream data register 1 */
739             if (size == 8) {
740                 env->mxccdata[1] = val;
741             } else {
742                 qemu_log_mask(LOG_UNIMP,
743                               "%08x: unimplemented access size: %d\n", addr,
744                               size);
745             }
746             break;
747         case 0x01c00010: /* MXCC stream data register 2 */
748             if (size == 8) {
749                 env->mxccdata[2] = val;
750             } else {
751                 qemu_log_mask(LOG_UNIMP,
752                               "%08x: unimplemented access size: %d\n", addr,
753                               size);
754             }
755             break;
756         case 0x01c00018: /* MXCC stream data register 3 */
757             if (size == 8) {
758                 env->mxccdata[3] = val;
759             } else {
760                 qemu_log_mask(LOG_UNIMP,
761                               "%08x: unimplemented access size: %d\n", addr,
762                               size);
763             }
764             break;
765         case 0x01c00100: /* MXCC stream source */
766             if (size == 8) {
767                 env->mxccregs[0] = val;
768             } else {
769                 qemu_log_mask(LOG_UNIMP,
770                               "%08x: unimplemented access size: %d\n", addr,
771                               size);
772             }
773             env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
774                                         0);
775             env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
776                                         8);
777             env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
778                                         16);
779             env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
780                                         24);
781             break;
782         case 0x01c00200: /* MXCC stream destination */
783             if (size == 8) {
784                 env->mxccregs[1] = val;
785             } else {
786                 qemu_log_mask(LOG_UNIMP,
787                               "%08x: unimplemented access size: %d\n", addr,
788                               size);
789             }
790             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0,
791                      env->mxccdata[0]);
792             stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8,
793                      env->mxccdata[1]);
794             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16,
795                      env->mxccdata[2]);
796             stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24,
797                      env->mxccdata[3]);
798             break;
799         case 0x01c00a00: /* MXCC control register */
800             if (size == 8) {
801                 env->mxccregs[3] = val;
802             } else {
803                 qemu_log_mask(LOG_UNIMP,
804                               "%08x: unimplemented access size: %d\n", addr,
805                               size);
806             }
807             break;
808         case 0x01c00a04: /* MXCC control register */
809             if (size == 4) {
810                 env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
811                     | val;
812             } else {
813                 qemu_log_mask(LOG_UNIMP,
814                               "%08x: unimplemented access size: %d\n", addr,
815                               size);
816             }
817             break;
818         case 0x01c00e00: /* MXCC error register  */
819             /* writing a 1 bit clears the error */
820             if (size == 8) {
821                 env->mxccregs[6] &= ~val;
822             } else {
823                 qemu_log_mask(LOG_UNIMP,
824                               "%08x: unimplemented access size: %d\n", addr,
825                               size);
826             }
827             break;
828         case 0x01c00f00: /* MBus port address register */
829             if (size == 8) {
830                 env->mxccregs[7] = val;
831             } else {
832                 qemu_log_mask(LOG_UNIMP,
833                               "%08x: unimplemented access size: %d\n", addr,
834                               size);
835             }
836             break;
837         default:
838             qemu_log_mask(LOG_UNIMP,
839                           "%08x: unimplemented address, size: %d\n", addr,
840                           size);
841             break;
842         }
843         DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
844                      asi, size, addr, val);
845 #ifdef DEBUG_MXCC
846         dump_mxcc(env);
847 #endif
848         break;
849     case 3: /* MMU flush */
850     case 0x18: /* LEON3 MMU flush */
851         {
852             int mmulev;
853
854             mmulev = (addr >> 8) & 15;
855             DPRINTF_MMU("mmu flush level %d\n", mmulev);
856             switch (mmulev) {
857             case 0: /* flush page */
858                 tlb_flush_page(env, addr & 0xfffff000);
859                 break;
860             case 1: /* flush segment (256k) */
861             case 2: /* flush region (16M) */
862             case 3: /* flush context (4G) */
863             case 4: /* flush entire */
864                 tlb_flush(env, 1);
865                 break;
866             default:
867                 break;
868             }
869 #ifdef DEBUG_MMU
870             dump_mmu(stdout, fprintf, env);
871 #endif
872         }
873         break;
874     case 4: /* write MMU regs */
875     case 0x19: /* LEON3 write MMU regs */
876         {
877             int reg = (addr >> 8) & 0x1f;
878             uint32_t oldreg;
879
880             oldreg = env->mmuregs[reg];
881             switch (reg) {
882             case 0: /* Control Register */
883                 env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
884                     (val & 0x00ffffff);
885                 /* Mappings generated during no-fault mode or MMU
886                    disabled mode are invalid in normal mode */
887                 if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
888                     (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm))) {
889                     tlb_flush(env, 1);
890                 }
891                 break;
892             case 1: /* Context Table Pointer Register */
893                 env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
894                 break;
895             case 2: /* Context Register */
896                 env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
897                 if (oldreg != env->mmuregs[reg]) {
898                     /* we flush when the MMU context changes because
899                        QEMU has no MMU context support */
900                     tlb_flush(env, 1);
901                 }
902                 break;
903             case 3: /* Synchronous Fault Status Register with Clear */
904             case 4: /* Synchronous Fault Address Register */
905                 break;
906             case 0x10: /* TLB Replacement Control Register */
907                 env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
908                 break;
909             case 0x13: /* Synchronous Fault Status Register with Read
910                           and Clear */
911                 env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
912                 break;
913             case 0x14: /* Synchronous Fault Address Register */
914                 env->mmuregs[4] = val;
915                 break;
916             default:
917                 env->mmuregs[reg] = val;
918                 break;
919             }
920             if (oldreg != env->mmuregs[reg]) {
921                 DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
922                             reg, oldreg, env->mmuregs[reg]);
923             }
924 #ifdef DEBUG_MMU
925             dump_mmu(stdout, fprintf, env);
926 #endif
927         }
928         break;
929     case 5: /* Turbosparc ITLB Diagnostic */
930     case 6: /* Turbosparc DTLB Diagnostic */
931     case 7: /* Turbosparc IOTLB Diagnostic */
932         break;
933     case 0xa: /* User data access */
934         switch (size) {
935         case 1:
936             cpu_stb_user(env, addr, val);
937             break;
938         case 2:
939             cpu_stw_user(env, addr, val);
940             break;
941         default:
942         case 4:
943             cpu_stl_user(env, addr, val);
944             break;
945         case 8:
946             cpu_stq_user(env, addr, val);
947             break;
948         }
949         break;
950     case 0xb: /* Supervisor data access */
951         switch (size) {
952         case 1:
953             cpu_stb_kernel(env, addr, val);
954             break;
955         case 2:
956             cpu_stw_kernel(env, addr, val);
957             break;
958         default:
959         case 4:
960             cpu_stl_kernel(env, addr, val);
961             break;
962         case 8:
963             cpu_stq_kernel(env, addr, val);
964             break;
965         }
966         break;
967     case 0xc: /* I-cache tag */
968     case 0xd: /* I-cache data */
969     case 0xe: /* D-cache tag */
970     case 0xf: /* D-cache data */
971     case 0x10: /* I/D-cache flush page */
972     case 0x11: /* I/D-cache flush segment */
973     case 0x12: /* I/D-cache flush region */
974     case 0x13: /* I/D-cache flush context */
975     case 0x14: /* I/D-cache flush user */
976         break;
977     case 0x17: /* Block copy, sta access */
978         {
979             /* val = src
980                addr = dst
981                copy 32 bytes */
982             unsigned int i;
983             uint32_t src = val & ~3, dst = addr & ~3, temp;
984
985             for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
986                 temp = cpu_ldl_kernel(env, src);
987                 cpu_stl_kernel(env, dst, temp);
988             }
989         }
990         break;
991     case 0x1f: /* Block fill, stda access */
992         {
993             /* addr = dst
994                fill 32 bytes with val */
995             unsigned int i;
996             uint32_t dst = addr & 7;
997
998             for (i = 0; i < 32; i += 8, dst += 8) {
999                 cpu_stq_kernel(env, dst, val);
1000             }
1001         }
1002         break;
1003     case 0x20: /* MMU passthrough */
1004     case 0x1c: /* LEON MMU passthrough */
1005         {
1006             switch (size) {
1007             case 1:
1008                 stb_phys(addr, val);
1009                 break;
1010             case 2:
1011                 stw_phys(addr, val);
1012                 break;
1013             case 4:
1014             default:
1015                 stl_phys(addr, val);
1016                 break;
1017             case 8:
1018                 stq_phys(addr, val);
1019                 break;
1020             }
1021         }
1022         break;
1023     case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1024         {
1025             switch (size) {
1026             case 1:
1027                 stb_phys((hwaddr)addr
1028                          | ((hwaddr)(asi & 0xf) << 32), val);
1029                 break;
1030             case 2:
1031                 stw_phys((hwaddr)addr
1032                          | ((hwaddr)(asi & 0xf) << 32), val);
1033                 break;
1034             case 4:
1035             default:
1036                 stl_phys((hwaddr)addr
1037                          | ((hwaddr)(asi & 0xf) << 32), val);
1038                 break;
1039             case 8:
1040                 stq_phys((hwaddr)addr
1041                          | ((hwaddr)(asi & 0xf) << 32), val);
1042                 break;
1043             }
1044         }
1045         break;
1046     case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
1047     case 0x31: /* store buffer data, Ross RT620 I-cache flush or
1048                   Turbosparc snoop RAM */
1049     case 0x32: /* store buffer control or Turbosparc page table
1050                   descriptor diagnostic */
1051     case 0x36: /* I-cache flash clear */
1052     case 0x37: /* D-cache flash clear */
1053         break;
1054     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
1055         {
1056             int reg = (addr >> 8) & 3;
1057
1058             switch (reg) {
1059             case 0: /* Breakpoint Value (Addr) */
1060                 env->mmubpregs[reg] = (val & 0xfffffffffULL);
1061                 break;
1062             case 1: /* Breakpoint Mask */
1063                 env->mmubpregs[reg] = (val & 0xfffffffffULL);
1064                 break;
1065             case 2: /* Breakpoint Control */
1066                 env->mmubpregs[reg] = (val & 0x7fULL);
1067                 break;
1068             case 3: /* Breakpoint Status */
1069                 env->mmubpregs[reg] = (val & 0xfULL);
1070                 break;
1071             }
1072             DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg,
1073                         env->mmuregs[reg]);
1074         }
1075         break;
1076     case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
1077         env->mmubpctrv = val & 0xffffffff;
1078         break;
1079     case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
1080         env->mmubpctrc = val & 0x3;
1081         break;
1082     case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
1083         env->mmubpctrs = val & 0x3;
1084         break;
1085     case 0x4c: /* SuperSPARC MMU Breakpoint Action */
1086         env->mmubpaction = val & 0x1fff;
1087         break;
1088     case 8: /* User code access, XXX */
1089     case 9: /* Supervisor code access, XXX */
1090     default:
1091         cpu_unassigned_access(env, addr, 1, 0, asi, size);
1092         break;
1093     }
1094 #ifdef DEBUG_ASI
1095     dump_asi("write", addr, asi, size, val);
1096 #endif
1097 }
1098
1099 #endif /* CONFIG_USER_ONLY */
1100 #else /* TARGET_SPARC64 */
1101
1102 #ifdef CONFIG_USER_ONLY
1103 uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1104                        int sign)
1105 {
1106     uint64_t ret = 0;
1107 #if defined(DEBUG_ASI)
1108     target_ulong last_addr = addr;
1109 #endif
1110
1111     if (asi < 0x80) {
1112         helper_raise_exception(env, TT_PRIV_ACT);
1113     }
1114
1115     helper_check_align(env, addr, size - 1);
1116     addr = asi_address_mask(env, asi, addr);
1117
1118     switch (asi) {
1119     case 0x82: /* Primary no-fault */
1120     case 0x8a: /* Primary no-fault LE */
1121         if (page_check_range(addr, size, PAGE_READ) == -1) {
1122 #ifdef DEBUG_ASI
1123             dump_asi("read ", last_addr, asi, size, ret);
1124 #endif
1125             return 0;
1126         }
1127         /* Fall through */
1128     case 0x80: /* Primary */
1129     case 0x88: /* Primary LE */
1130         {
1131             switch (size) {
1132             case 1:
1133                 ret = ldub_raw(addr);
1134                 break;
1135             case 2:
1136                 ret = lduw_raw(addr);
1137                 break;
1138             case 4:
1139                 ret = ldl_raw(addr);
1140                 break;
1141             default:
1142             case 8:
1143                 ret = ldq_raw(addr);
1144                 break;
1145             }
1146         }
1147         break;
1148     case 0x83: /* Secondary no-fault */
1149     case 0x8b: /* Secondary no-fault LE */
1150         if (page_check_range(addr, size, PAGE_READ) == -1) {
1151 #ifdef DEBUG_ASI
1152             dump_asi("read ", last_addr, asi, size, ret);
1153 #endif
1154             return 0;
1155         }
1156         /* Fall through */
1157     case 0x81: /* Secondary */
1158     case 0x89: /* Secondary LE */
1159         /* XXX */
1160         break;
1161     default:
1162         break;
1163     }
1164
1165     /* Convert from little endian */
1166     switch (asi) {
1167     case 0x88: /* Primary LE */
1168     case 0x89: /* Secondary LE */
1169     case 0x8a: /* Primary no-fault LE */
1170     case 0x8b: /* Secondary no-fault LE */
1171         switch (size) {
1172         case 2:
1173             ret = bswap16(ret);
1174             break;
1175         case 4:
1176             ret = bswap32(ret);
1177             break;
1178         case 8:
1179             ret = bswap64(ret);
1180             break;
1181         default:
1182             break;
1183         }
1184     default:
1185         break;
1186     }
1187
1188     /* Convert to signed number */
1189     if (sign) {
1190         switch (size) {
1191         case 1:
1192             ret = (int8_t) ret;
1193             break;
1194         case 2:
1195             ret = (int16_t) ret;
1196             break;
1197         case 4:
1198             ret = (int32_t) ret;
1199             break;
1200         default:
1201             break;
1202         }
1203     }
1204 #ifdef DEBUG_ASI
1205     dump_asi("read ", last_addr, asi, size, ret);
1206 #endif
1207     return ret;
1208 }
1209
1210 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
1211                    int asi, int size)
1212 {
1213 #ifdef DEBUG_ASI
1214     dump_asi("write", addr, asi, size, val);
1215 #endif
1216     if (asi < 0x80) {
1217         helper_raise_exception(env, TT_PRIV_ACT);
1218     }
1219
1220     helper_check_align(env, addr, size - 1);
1221     addr = asi_address_mask(env, asi, addr);
1222
1223     /* Convert to little endian */
1224     switch (asi) {
1225     case 0x88: /* Primary LE */
1226     case 0x89: /* Secondary LE */
1227         switch (size) {
1228         case 2:
1229             val = bswap16(val);
1230             break;
1231         case 4:
1232             val = bswap32(val);
1233             break;
1234         case 8:
1235             val = bswap64(val);
1236             break;
1237         default:
1238             break;
1239         }
1240     default:
1241         break;
1242     }
1243
1244     switch (asi) {
1245     case 0x80: /* Primary */
1246     case 0x88: /* Primary LE */
1247         {
1248             switch (size) {
1249             case 1:
1250                 stb_raw(addr, val);
1251                 break;
1252             case 2:
1253                 stw_raw(addr, val);
1254                 break;
1255             case 4:
1256                 stl_raw(addr, val);
1257                 break;
1258             case 8:
1259             default:
1260                 stq_raw(addr, val);
1261                 break;
1262             }
1263         }
1264         break;
1265     case 0x81: /* Secondary */
1266     case 0x89: /* Secondary LE */
1267         /* XXX */
1268         return;
1269
1270     case 0x82: /* Primary no-fault, RO */
1271     case 0x83: /* Secondary no-fault, RO */
1272     case 0x8a: /* Primary no-fault LE, RO */
1273     case 0x8b: /* Secondary no-fault LE, RO */
1274     default:
1275         helper_raise_exception(env, TT_DATA_ACCESS);
1276         return;
1277     }
1278 }
1279
1280 #else /* CONFIG_USER_ONLY */
1281
1282 uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1283                        int sign)
1284 {
1285     uint64_t ret = 0;
1286 #if defined(DEBUG_ASI)
1287     target_ulong last_addr = addr;
1288 #endif
1289
1290     asi &= 0xff;
1291
1292     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1293         || (cpu_has_hypervisor(env)
1294             && asi >= 0x30 && asi < 0x80
1295             && !(env->hpstate & HS_PRIV))) {
1296         helper_raise_exception(env, TT_PRIV_ACT);
1297     }
1298
1299     helper_check_align(env, addr, size - 1);
1300     addr = asi_address_mask(env, asi, addr);
1301
1302     /* process nonfaulting loads first */
1303     if ((asi & 0xf6) == 0x82) {
1304         int mmu_idx;
1305
1306         /* secondary space access has lowest asi bit equal to 1 */
1307         if (env->pstate & PS_PRIV) {
1308             mmu_idx = (asi & 1) ? MMU_KERNEL_SECONDARY_IDX : MMU_KERNEL_IDX;
1309         } else {
1310             mmu_idx = (asi & 1) ? MMU_USER_SECONDARY_IDX : MMU_USER_IDX;
1311         }
1312
1313         if (cpu_get_phys_page_nofault(env, addr, mmu_idx) == -1ULL) {
1314 #ifdef DEBUG_ASI
1315             dump_asi("read ", last_addr, asi, size, ret);
1316 #endif
1317             /* env->exception_index is set in get_physical_address_data(). */
1318             helper_raise_exception(env, env->exception_index);
1319         }
1320
1321         /* convert nonfaulting load ASIs to normal load ASIs */
1322         asi &= ~0x02;
1323     }
1324
1325     switch (asi) {
1326     case 0x10: /* As if user primary */
1327     case 0x11: /* As if user secondary */
1328     case 0x18: /* As if user primary LE */
1329     case 0x19: /* As if user secondary LE */
1330     case 0x80: /* Primary */
1331     case 0x81: /* Secondary */
1332     case 0x88: /* Primary LE */
1333     case 0x89: /* Secondary LE */
1334     case 0xe2: /* UA2007 Primary block init */
1335     case 0xe3: /* UA2007 Secondary block init */
1336         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1337             if (cpu_hypervisor_mode(env)) {
1338                 switch (size) {
1339                 case 1:
1340                     ret = cpu_ldub_hypv(env, addr);
1341                     break;
1342                 case 2:
1343                     ret = cpu_lduw_hypv(env, addr);
1344                     break;
1345                 case 4:
1346                     ret = cpu_ldl_hypv(env, addr);
1347                     break;
1348                 default:
1349                 case 8:
1350                     ret = cpu_ldq_hypv(env, addr);
1351                     break;
1352                 }
1353             } else {
1354                 /* secondary space access has lowest asi bit equal to 1 */
1355                 if (asi & 1) {
1356                     switch (size) {
1357                     case 1:
1358                         ret = cpu_ldub_kernel_secondary(env, addr);
1359                         break;
1360                     case 2:
1361                         ret = cpu_lduw_kernel_secondary(env, addr);
1362                         break;
1363                     case 4:
1364                         ret = cpu_ldl_kernel_secondary(env, addr);
1365                         break;
1366                     default:
1367                     case 8:
1368                         ret = cpu_ldq_kernel_secondary(env, addr);
1369                         break;
1370                     }
1371                 } else {
1372                     switch (size) {
1373                     case 1:
1374                         ret = cpu_ldub_kernel(env, addr);
1375                         break;
1376                     case 2:
1377                         ret = cpu_lduw_kernel(env, addr);
1378                         break;
1379                     case 4:
1380                         ret = cpu_ldl_kernel(env, addr);
1381                         break;
1382                     default:
1383                     case 8:
1384                         ret = cpu_ldq_kernel(env, addr);
1385                         break;
1386                     }
1387                 }
1388             }
1389         } else {
1390             /* secondary space access has lowest asi bit equal to 1 */
1391             if (asi & 1) {
1392                 switch (size) {
1393                 case 1:
1394                     ret = cpu_ldub_user_secondary(env, addr);
1395                     break;
1396                 case 2:
1397                     ret = cpu_lduw_user_secondary(env, addr);
1398                     break;
1399                 case 4:
1400                     ret = cpu_ldl_user_secondary(env, addr);
1401                     break;
1402                 default:
1403                 case 8:
1404                     ret = cpu_ldq_user_secondary(env, addr);
1405                     break;
1406                 }
1407             } else {
1408                 switch (size) {
1409                 case 1:
1410                     ret = cpu_ldub_user(env, addr);
1411                     break;
1412                 case 2:
1413                     ret = cpu_lduw_user(env, addr);
1414                     break;
1415                 case 4:
1416                     ret = cpu_ldl_user(env, addr);
1417                     break;
1418                 default:
1419                 case 8:
1420                     ret = cpu_ldq_user(env, addr);
1421                     break;
1422                 }
1423             }
1424         }
1425         break;
1426     case 0x14: /* Bypass */
1427     case 0x15: /* Bypass, non-cacheable */
1428     case 0x1c: /* Bypass LE */
1429     case 0x1d: /* Bypass, non-cacheable LE */
1430         {
1431             switch (size) {
1432             case 1:
1433                 ret = ldub_phys(addr);
1434                 break;
1435             case 2:
1436                 ret = lduw_phys(addr);
1437                 break;
1438             case 4:
1439                 ret = ldl_phys(addr);
1440                 break;
1441             default:
1442             case 8:
1443                 ret = ldq_phys(addr);
1444                 break;
1445             }
1446             break;
1447         }
1448     case 0x24: /* Nucleus quad LDD 128 bit atomic */
1449     case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
1450                   Only ldda allowed */
1451         helper_raise_exception(env, TT_ILL_INSN);
1452         return 0;
1453     case 0x04: /* Nucleus */
1454     case 0x0c: /* Nucleus Little Endian (LE) */
1455         {
1456             switch (size) {
1457             case 1:
1458                 ret = cpu_ldub_nucleus(env, addr);
1459                 break;
1460             case 2:
1461                 ret = cpu_lduw_nucleus(env, addr);
1462                 break;
1463             case 4:
1464                 ret = cpu_ldl_nucleus(env, addr);
1465                 break;
1466             default:
1467             case 8:
1468                 ret = cpu_ldq_nucleus(env, addr);
1469                 break;
1470             }
1471             break;
1472         }
1473     case 0x4a: /* UPA config */
1474         /* XXX */
1475         break;
1476     case 0x45: /* LSU */
1477         ret = env->lsu;
1478         break;
1479     case 0x50: /* I-MMU regs */
1480         {
1481             int reg = (addr >> 3) & 0xf;
1482
1483             if (reg == 0) {
1484                 /* I-TSB Tag Target register */
1485                 ret = ultrasparc_tag_target(env->immu.tag_access);
1486             } else {
1487                 ret = env->immuregs[reg];
1488             }
1489
1490             break;
1491         }
1492     case 0x51: /* I-MMU 8k TSB pointer */
1493         {
1494             /* env->immuregs[5] holds I-MMU TSB register value
1495                env->immuregs[6] holds I-MMU Tag Access register value */
1496             ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
1497                                          8*1024);
1498             break;
1499         }
1500     case 0x52: /* I-MMU 64k TSB pointer */
1501         {
1502             /* env->immuregs[5] holds I-MMU TSB register value
1503                env->immuregs[6] holds I-MMU Tag Access register value */
1504             ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
1505                                          64*1024);
1506             break;
1507         }
1508     case 0x55: /* I-MMU data access */
1509         {
1510             int reg = (addr >> 3) & 0x3f;
1511
1512             ret = env->itlb[reg].tte;
1513             break;
1514         }
1515     case 0x56: /* I-MMU tag read */
1516         {
1517             int reg = (addr >> 3) & 0x3f;
1518
1519             ret = env->itlb[reg].tag;
1520             break;
1521         }
1522     case 0x58: /* D-MMU regs */
1523         {
1524             int reg = (addr >> 3) & 0xf;
1525
1526             if (reg == 0) {
1527                 /* D-TSB Tag Target register */
1528                 ret = ultrasparc_tag_target(env->dmmu.tag_access);
1529             } else {
1530                 ret = env->dmmuregs[reg];
1531             }
1532             break;
1533         }
1534     case 0x59: /* D-MMU 8k TSB pointer */
1535         {
1536             /* env->dmmuregs[5] holds D-MMU TSB register value
1537                env->dmmuregs[6] holds D-MMU Tag Access register value */
1538             ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
1539                                          8*1024);
1540             break;
1541         }
1542     case 0x5a: /* D-MMU 64k TSB pointer */
1543         {
1544             /* env->dmmuregs[5] holds D-MMU TSB register value
1545                env->dmmuregs[6] holds D-MMU Tag Access register value */
1546             ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
1547                                          64*1024);
1548             break;
1549         }
1550     case 0x5d: /* D-MMU data access */
1551         {
1552             int reg = (addr >> 3) & 0x3f;
1553
1554             ret = env->dtlb[reg].tte;
1555             break;
1556         }
1557     case 0x5e: /* D-MMU tag read */
1558         {
1559             int reg = (addr >> 3) & 0x3f;
1560
1561             ret = env->dtlb[reg].tag;
1562             break;
1563         }
1564     case 0x48: /* Interrupt dispatch, RO */
1565         break;
1566     case 0x49: /* Interrupt data receive */
1567         ret = env->ivec_status;
1568         break;
1569     case 0x7f: /* Incoming interrupt vector, RO */
1570         {
1571             int reg = (addr >> 4) & 0x3;
1572             if (reg < 3) {
1573                 ret = env->ivec_data[reg];
1574             }
1575             break;
1576         }
1577     case 0x46: /* D-cache data */
1578     case 0x47: /* D-cache tag access */
1579     case 0x4b: /* E-cache error enable */
1580     case 0x4c: /* E-cache asynchronous fault status */
1581     case 0x4d: /* E-cache asynchronous fault address */
1582     case 0x4e: /* E-cache tag data */
1583     case 0x66: /* I-cache instruction access */
1584     case 0x67: /* I-cache tag access */
1585     case 0x6e: /* I-cache predecode */
1586     case 0x6f: /* I-cache LRU etc. */
1587     case 0x76: /* E-cache tag */
1588     case 0x7e: /* E-cache tag */
1589         break;
1590     case 0x5b: /* D-MMU data pointer */
1591     case 0x54: /* I-MMU data in, WO */
1592     case 0x57: /* I-MMU demap, WO */
1593     case 0x5c: /* D-MMU data in, WO */
1594     case 0x5f: /* D-MMU demap, WO */
1595     case 0x77: /* Interrupt vector, WO */
1596     default:
1597         cpu_unassigned_access(env, addr, 0, 0, 1, size);
1598         ret = 0;
1599         break;
1600     }
1601
1602     /* Convert from little endian */
1603     switch (asi) {
1604     case 0x0c: /* Nucleus Little Endian (LE) */
1605     case 0x18: /* As if user primary LE */
1606     case 0x19: /* As if user secondary LE */
1607     case 0x1c: /* Bypass LE */
1608     case 0x1d: /* Bypass, non-cacheable LE */
1609     case 0x88: /* Primary LE */
1610     case 0x89: /* Secondary LE */
1611         switch(size) {
1612         case 2:
1613             ret = bswap16(ret);
1614             break;
1615         case 4:
1616             ret = bswap32(ret);
1617             break;
1618         case 8:
1619             ret = bswap64(ret);
1620             break;
1621         default:
1622             break;
1623         }
1624     default:
1625         break;
1626     }
1627
1628     /* Convert to signed number */
1629     if (sign) {
1630         switch (size) {
1631         case 1:
1632             ret = (int8_t) ret;
1633             break;
1634         case 2:
1635             ret = (int16_t) ret;
1636             break;
1637         case 4:
1638             ret = (int32_t) ret;
1639             break;
1640         default:
1641             break;
1642         }
1643     }
1644 #ifdef DEBUG_ASI
1645     dump_asi("read ", last_addr, asi, size, ret);
1646 #endif
1647     return ret;
1648 }
1649
1650 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
1651                    int asi, int size)
1652 {
1653 #ifdef DEBUG_ASI
1654     dump_asi("write", addr, asi, size, val);
1655 #endif
1656
1657     asi &= 0xff;
1658
1659     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1660         || (cpu_has_hypervisor(env)
1661             && asi >= 0x30 && asi < 0x80
1662             && !(env->hpstate & HS_PRIV))) {
1663         helper_raise_exception(env, TT_PRIV_ACT);
1664     }
1665
1666     helper_check_align(env, addr, size - 1);
1667     addr = asi_address_mask(env, asi, addr);
1668
1669     /* Convert to little endian */
1670     switch (asi) {
1671     case 0x0c: /* Nucleus Little Endian (LE) */
1672     case 0x18: /* As if user primary LE */
1673     case 0x19: /* As if user secondary LE */
1674     case 0x1c: /* Bypass LE */
1675     case 0x1d: /* Bypass, non-cacheable LE */
1676     case 0x88: /* Primary LE */
1677     case 0x89: /* Secondary LE */
1678         switch (size) {
1679         case 2:
1680             val = bswap16(val);
1681             break;
1682         case 4:
1683             val = bswap32(val);
1684             break;
1685         case 8:
1686             val = bswap64(val);
1687             break;
1688         default:
1689             break;
1690         }
1691     default:
1692         break;
1693     }
1694
1695     switch (asi) {
1696     case 0x10: /* As if user primary */
1697     case 0x11: /* As if user secondary */
1698     case 0x18: /* As if user primary LE */
1699     case 0x19: /* As if user secondary LE */
1700     case 0x80: /* Primary */
1701     case 0x81: /* Secondary */
1702     case 0x88: /* Primary LE */
1703     case 0x89: /* Secondary LE */
1704     case 0xe2: /* UA2007 Primary block init */
1705     case 0xe3: /* UA2007 Secondary block init */
1706         if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1707             if (cpu_hypervisor_mode(env)) {
1708                 switch (size) {
1709                 case 1:
1710                     cpu_stb_hypv(env, addr, val);
1711                     break;
1712                 case 2:
1713                     cpu_stw_hypv(env, addr, val);
1714                     break;
1715                 case 4:
1716                     cpu_stl_hypv(env, addr, val);
1717                     break;
1718                 case 8:
1719                 default:
1720                     cpu_stq_hypv(env, addr, val);
1721                     break;
1722                 }
1723             } else {
1724                 /* secondary space access has lowest asi bit equal to 1 */
1725                 if (asi & 1) {
1726                     switch (size) {
1727                     case 1:
1728                         cpu_stb_kernel_secondary(env, addr, val);
1729                         break;
1730                     case 2:
1731                         cpu_stw_kernel_secondary(env, addr, val);
1732                         break;
1733                     case 4:
1734                         cpu_stl_kernel_secondary(env, addr, val);
1735                         break;
1736                     case 8:
1737                     default:
1738                         cpu_stq_kernel_secondary(env, addr, val);
1739                         break;
1740                     }
1741                 } else {
1742                     switch (size) {
1743                     case 1:
1744                         cpu_stb_kernel(env, addr, val);
1745                         break;
1746                     case 2:
1747                         cpu_stw_kernel(env, addr, val);
1748                         break;
1749                     case 4:
1750                         cpu_stl_kernel(env, addr, val);
1751                         break;
1752                     case 8:
1753                     default:
1754                         cpu_stq_kernel(env, addr, val);
1755                         break;
1756                     }
1757                 }
1758             }
1759         } else {
1760             /* secondary space access has lowest asi bit equal to 1 */
1761             if (asi & 1) {
1762                 switch (size) {
1763                 case 1:
1764                     cpu_stb_user_secondary(env, addr, val);
1765                     break;
1766                 case 2:
1767                     cpu_stw_user_secondary(env, addr, val);
1768                     break;
1769                 case 4:
1770                     cpu_stl_user_secondary(env, addr, val);
1771                     break;
1772                 case 8:
1773                 default:
1774                     cpu_stq_user_secondary(env, addr, val);
1775                     break;
1776                 }
1777             } else {
1778                 switch (size) {
1779                 case 1:
1780                     cpu_stb_user(env, addr, val);
1781                     break;
1782                 case 2:
1783                     cpu_stw_user(env, addr, val);
1784                     break;
1785                 case 4:
1786                     cpu_stl_user(env, addr, val);
1787                     break;
1788                 case 8:
1789                 default:
1790                     cpu_stq_user(env, addr, val);
1791                     break;
1792                 }
1793             }
1794         }
1795         break;
1796     case 0x14: /* Bypass */
1797     case 0x15: /* Bypass, non-cacheable */
1798     case 0x1c: /* Bypass LE */
1799     case 0x1d: /* Bypass, non-cacheable LE */
1800         {
1801             switch (size) {
1802             case 1:
1803                 stb_phys(addr, val);
1804                 break;
1805             case 2:
1806                 stw_phys(addr, val);
1807                 break;
1808             case 4:
1809                 stl_phys(addr, val);
1810                 break;
1811             case 8:
1812             default:
1813                 stq_phys(addr, val);
1814                 break;
1815             }
1816         }
1817         return;
1818     case 0x24: /* Nucleus quad LDD 128 bit atomic */
1819     case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
1820                   Only ldda allowed */
1821         helper_raise_exception(env, TT_ILL_INSN);
1822         return;
1823     case 0x04: /* Nucleus */
1824     case 0x0c: /* Nucleus Little Endian (LE) */
1825         {
1826             switch (size) {
1827             case 1:
1828                 cpu_stb_nucleus(env, addr, val);
1829                 break;
1830             case 2:
1831                 cpu_stw_nucleus(env, addr, val);
1832                 break;
1833             case 4:
1834                 cpu_stl_nucleus(env, addr, val);
1835                 break;
1836             default:
1837             case 8:
1838                 cpu_stq_nucleus(env, addr, val);
1839                 break;
1840             }
1841             break;
1842         }
1843
1844     case 0x4a: /* UPA config */
1845         /* XXX */
1846         return;
1847     case 0x45: /* LSU */
1848         {
1849             uint64_t oldreg;
1850
1851             oldreg = env->lsu;
1852             env->lsu = val & (DMMU_E | IMMU_E);
1853             /* Mappings generated during D/I MMU disabled mode are
1854                invalid in normal mode */
1855             if (oldreg != env->lsu) {
1856                 DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
1857                             oldreg, env->lsu);
1858 #ifdef DEBUG_MMU
1859                 dump_mmu(stdout, fprintf, env);
1860 #endif
1861                 tlb_flush(env, 1);
1862             }
1863             return;
1864         }
1865     case 0x50: /* I-MMU regs */
1866         {
1867             int reg = (addr >> 3) & 0xf;
1868             uint64_t oldreg;
1869
1870             oldreg = env->immuregs[reg];
1871             switch (reg) {
1872             case 0: /* RO */
1873                 return;
1874             case 1: /* Not in I-MMU */
1875             case 2:
1876                 return;
1877             case 3: /* SFSR */
1878                 if ((val & 1) == 0) {
1879                     val = 0; /* Clear SFSR */
1880                 }
1881                 env->immu.sfsr = val;
1882                 break;
1883             case 4: /* RO */
1884                 return;
1885             case 5: /* TSB access */
1886                 DPRINTF_MMU("immu TSB write: 0x%016" PRIx64 " -> 0x%016"
1887                             PRIx64 "\n", env->immu.tsb, val);
1888                 env->immu.tsb = val;
1889                 break;
1890             case 6: /* Tag access */
1891                 env->immu.tag_access = val;
1892                 break;
1893             case 7:
1894             case 8:
1895                 return;
1896             default:
1897                 break;
1898             }
1899
1900             if (oldreg != env->immuregs[reg]) {
1901                 DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
1902                             PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1903             }
1904 #ifdef DEBUG_MMU
1905             dump_mmu(stdout, fprintf, env);
1906 #endif
1907             return;
1908         }
1909     case 0x54: /* I-MMU data in */
1910         replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env);
1911         return;
1912     case 0x55: /* I-MMU data access */
1913         {
1914             /* TODO: auto demap */
1915
1916             unsigned int i = (addr >> 3) & 0x3f;
1917
1918             replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env);
1919
1920 #ifdef DEBUG_MMU
1921             DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
1922             dump_mmu(stdout, fprintf, env);
1923 #endif
1924             return;
1925         }
1926     case 0x57: /* I-MMU demap */
1927         demap_tlb(env->itlb, addr, "immu", env);
1928         return;
1929     case 0x58: /* D-MMU regs */
1930         {
1931             int reg = (addr >> 3) & 0xf;
1932             uint64_t oldreg;
1933
1934             oldreg = env->dmmuregs[reg];
1935             switch (reg) {
1936             case 0: /* RO */
1937             case 4:
1938                 return;
1939             case 3: /* SFSR */
1940                 if ((val & 1) == 0) {
1941                     val = 0; /* Clear SFSR, Fault address */
1942                     env->dmmu.sfar = 0;
1943                 }
1944                 env->dmmu.sfsr = val;
1945                 break;
1946             case 1: /* Primary context */
1947                 env->dmmu.mmu_primary_context = val;
1948                 /* can be optimized to only flush MMU_USER_IDX
1949                    and MMU_KERNEL_IDX entries */
1950                 tlb_flush(env, 1);
1951                 break;
1952             case 2: /* Secondary context */
1953                 env->dmmu.mmu_secondary_context = val;
1954                 /* can be optimized to only flush MMU_USER_SECONDARY_IDX
1955                    and MMU_KERNEL_SECONDARY_IDX entries */
1956                 tlb_flush(env, 1);
1957                 break;
1958             case 5: /* TSB access */
1959                 DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
1960                             PRIx64 "\n", env->dmmu.tsb, val);
1961                 env->dmmu.tsb = val;
1962                 break;
1963             case 6: /* Tag access */
1964                 env->dmmu.tag_access = val;
1965                 break;
1966             case 7: /* Virtual Watchpoint */
1967             case 8: /* Physical Watchpoint */
1968             default:
1969                 env->dmmuregs[reg] = val;
1970                 break;
1971             }
1972
1973             if (oldreg != env->dmmuregs[reg]) {
1974                 DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
1975                             PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1976             }
1977 #ifdef DEBUG_MMU
1978             dump_mmu(stdout, fprintf, env);
1979 #endif
1980             return;
1981         }
1982     case 0x5c: /* D-MMU data in */
1983         replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env);
1984         return;
1985     case 0x5d: /* D-MMU data access */
1986         {
1987             unsigned int i = (addr >> 3) & 0x3f;
1988
1989             replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env);
1990
1991 #ifdef DEBUG_MMU
1992             DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
1993             dump_mmu(stdout, fprintf, env);
1994 #endif
1995             return;
1996         }
1997     case 0x5f: /* D-MMU demap */
1998         demap_tlb(env->dtlb, addr, "dmmu", env);
1999         return;
2000     case 0x49: /* Interrupt data receive */
2001         env->ivec_status = val & 0x20;
2002         return;
2003     case 0x46: /* D-cache data */
2004     case 0x47: /* D-cache tag access */
2005     case 0x4b: /* E-cache error enable */
2006     case 0x4c: /* E-cache asynchronous fault status */
2007     case 0x4d: /* E-cache asynchronous fault address */
2008     case 0x4e: /* E-cache tag data */
2009     case 0x66: /* I-cache instruction access */
2010     case 0x67: /* I-cache tag access */
2011     case 0x6e: /* I-cache predecode */
2012     case 0x6f: /* I-cache LRU etc. */
2013     case 0x76: /* E-cache tag */
2014     case 0x7e: /* E-cache tag */
2015         return;
2016     case 0x51: /* I-MMU 8k TSB pointer, RO */
2017     case 0x52: /* I-MMU 64k TSB pointer, RO */
2018     case 0x56: /* I-MMU tag read, RO */
2019     case 0x59: /* D-MMU 8k TSB pointer, RO */
2020     case 0x5a: /* D-MMU 64k TSB pointer, RO */
2021     case 0x5b: /* D-MMU data pointer, RO */
2022     case 0x5e: /* D-MMU tag read, RO */
2023     case 0x48: /* Interrupt dispatch, RO */
2024     case 0x7f: /* Incoming interrupt vector, RO */
2025     case 0x82: /* Primary no-fault, RO */
2026     case 0x83: /* Secondary no-fault, RO */
2027     case 0x8a: /* Primary no-fault LE, RO */
2028     case 0x8b: /* Secondary no-fault LE, RO */
2029     default:
2030         cpu_unassigned_access(env, addr, 1, 0, 1, size);
2031         return;
2032     }
2033 }
2034 #endif /* CONFIG_USER_ONLY */
2035
2036 void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
2037 {
2038     if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2039         || (cpu_has_hypervisor(env)
2040             && asi >= 0x30 && asi < 0x80
2041             && !(env->hpstate & HS_PRIV))) {
2042         helper_raise_exception(env, TT_PRIV_ACT);
2043     }
2044
2045     addr = asi_address_mask(env, asi, addr);
2046
2047     switch (asi) {
2048 #if !defined(CONFIG_USER_ONLY)
2049     case 0x24: /* Nucleus quad LDD 128 bit atomic */
2050     case 0x2c: /* Nucleus quad LDD 128 bit atomic LE */
2051         helper_check_align(env, addr, 0xf);
2052         if (rd == 0) {
2053             env->gregs[1] = cpu_ldq_nucleus(env, addr + 8);
2054             if (asi == 0x2c) {
2055                 bswap64s(&env->gregs[1]);
2056             }
2057         } else if (rd < 8) {
2058             env->gregs[rd] = cpu_ldq_nucleus(env, addr);
2059             env->gregs[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2060             if (asi == 0x2c) {
2061                 bswap64s(&env->gregs[rd]);
2062                 bswap64s(&env->gregs[rd + 1]);
2063             }
2064         } else {
2065             env->regwptr[rd] = cpu_ldq_nucleus(env, addr);
2066             env->regwptr[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2067             if (asi == 0x2c) {
2068                 bswap64s(&env->regwptr[rd]);
2069                 bswap64s(&env->regwptr[rd + 1]);
2070             }
2071         }
2072         break;
2073 #endif
2074     default:
2075         helper_check_align(env, addr, 0x3);
2076         if (rd == 0) {
2077             env->gregs[1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2078         } else if (rd < 8) {
2079             env->gregs[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2080             env->gregs[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2081         } else {
2082             env->regwptr[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2083             env->regwptr[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2084         }
2085         break;
2086     }
2087 }
2088
2089 void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2090                     int rd)
2091 {
2092     unsigned int i;
2093     target_ulong val;
2094
2095     helper_check_align(env, addr, 3);
2096     addr = asi_address_mask(env, asi, addr);
2097
2098     switch (asi) {
2099     case 0xf0: /* UA2007/JPS1 Block load primary */
2100     case 0xf1: /* UA2007/JPS1 Block load secondary */
2101     case 0xf8: /* UA2007/JPS1 Block load primary LE */
2102     case 0xf9: /* UA2007/JPS1 Block load secondary LE */
2103         if (rd & 7) {
2104             helper_raise_exception(env, TT_ILL_INSN);
2105             return;
2106         }
2107         helper_check_align(env, addr, 0x3f);
2108         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2109             env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x8f, 8, 0);
2110         }
2111         return;
2112
2113     case 0x16: /* UA2007 Block load primary, user privilege */
2114     case 0x17: /* UA2007 Block load secondary, user privilege */
2115     case 0x1e: /* UA2007 Block load primary LE, user privilege */
2116     case 0x1f: /* UA2007 Block load secondary LE, user privilege */
2117     case 0x70: /* JPS1 Block load primary, user privilege */
2118     case 0x71: /* JPS1 Block load secondary, user privilege */
2119     case 0x78: /* JPS1 Block load primary LE, user privilege */
2120     case 0x79: /* JPS1 Block load secondary LE, user privilege */
2121         if (rd & 7) {
2122             helper_raise_exception(env, TT_ILL_INSN);
2123             return;
2124         }
2125         helper_check_align(env, addr, 0x3f);
2126         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2127             env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0);
2128         }
2129         return;
2130
2131     default:
2132         break;
2133     }
2134
2135     switch (size) {
2136     default:
2137     case 4:
2138         val = helper_ld_asi(env, addr, asi, size, 0);
2139         if (rd & 1) {
2140             env->fpr[rd / 2].l.lower = val;
2141         } else {
2142             env->fpr[rd / 2].l.upper = val;
2143         }
2144         break;
2145     case 8:
2146         env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, size, 0);
2147         break;
2148     case 16:
2149         env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, 8, 0);
2150         env->fpr[rd / 2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0);
2151         break;
2152     }
2153 }
2154
2155 void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2156                     int rd)
2157 {
2158     unsigned int i;
2159     target_ulong val;
2160
2161     helper_check_align(env, addr, 3);
2162     addr = asi_address_mask(env, asi, addr);
2163
2164     switch (asi) {
2165     case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
2166     case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
2167     case 0xf0: /* UA2007/JPS1 Block store primary */
2168     case 0xf1: /* UA2007/JPS1 Block store secondary */
2169     case 0xf8: /* UA2007/JPS1 Block store primary LE */
2170     case 0xf9: /* UA2007/JPS1 Block store secondary LE */
2171         if (rd & 7) {
2172             helper_raise_exception(env, TT_ILL_INSN);
2173             return;
2174         }
2175         helper_check_align(env, addr, 0x3f);
2176         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2177             helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x8f, 8);
2178         }
2179
2180         return;
2181     case 0x16: /* UA2007 Block load primary, user privilege */
2182     case 0x17: /* UA2007 Block load secondary, user privilege */
2183     case 0x1e: /* UA2007 Block load primary LE, user privilege */
2184     case 0x1f: /* UA2007 Block load secondary LE, user privilege */
2185     case 0x70: /* JPS1 Block store primary, user privilege */
2186     case 0x71: /* JPS1 Block store secondary, user privilege */
2187     case 0x78: /* JPS1 Block load primary LE, user privilege */
2188     case 0x79: /* JPS1 Block load secondary LE, user privilege */
2189         if (rd & 7) {
2190             helper_raise_exception(env, TT_ILL_INSN);
2191             return;
2192         }
2193         helper_check_align(env, addr, 0x3f);
2194         for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2195             helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x19, 8);
2196         }
2197
2198         return;
2199     default:
2200         break;
2201     }
2202
2203     switch (size) {
2204     default:
2205     case 4:
2206         if (rd & 1) {
2207             val = env->fpr[rd / 2].l.lower;
2208         } else {
2209             val = env->fpr[rd / 2].l.upper;
2210         }
2211         helper_st_asi(env, addr, val, asi, size);
2212         break;
2213     case 8:
2214         helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, size);
2215         break;
2216     case 16:
2217         helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, 8);
2218         helper_st_asi(env, addr + 8, env->fpr[rd / 2 + 1].ll, asi, 8);
2219         break;
2220     }
2221 }
2222
2223 target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
2224                             target_ulong val1, target_ulong val2, uint32_t asi)
2225 {
2226     target_ulong ret;
2227
2228     val2 &= 0xffffffffUL;
2229     ret = helper_ld_asi(env, addr, asi, 4, 0);
2230     ret &= 0xffffffffUL;
2231     if (val2 == ret) {
2232         helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
2233     }
2234     return ret;
2235 }
2236
2237 target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
2238                              target_ulong val1, target_ulong val2,
2239                              uint32_t asi)
2240 {
2241     target_ulong ret;
2242
2243     ret = helper_ld_asi(env, addr, asi, 8, 0);
2244     if (val2 == ret) {
2245         helper_st_asi(env, addr, val1, asi, 8);
2246     }
2247     return ret;
2248 }
2249 #endif /* TARGET_SPARC64 */
2250
2251 void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2252 {
2253     /* XXX add 128 bit load */
2254     CPU_QuadU u;
2255
2256     helper_check_align(env, addr, 7);
2257 #if !defined(CONFIG_USER_ONLY)
2258     switch (mem_idx) {
2259     case MMU_USER_IDX:
2260         u.ll.upper = cpu_ldq_user(env, addr);
2261         u.ll.lower = cpu_ldq_user(env, addr + 8);
2262         QT0 = u.q;
2263         break;
2264     case MMU_KERNEL_IDX:
2265         u.ll.upper = cpu_ldq_kernel(env, addr);
2266         u.ll.lower = cpu_ldq_kernel(env, addr + 8);
2267         QT0 = u.q;
2268         break;
2269 #ifdef TARGET_SPARC64
2270     case MMU_HYPV_IDX:
2271         u.ll.upper = cpu_ldq_hypv(env, addr);
2272         u.ll.lower = cpu_ldq_hypv(env, addr + 8);
2273         QT0 = u.q;
2274         break;
2275 #endif
2276     default:
2277         DPRINTF_MMU("helper_ldqf: need to check MMU idx %d\n", mem_idx);
2278         break;
2279     }
2280 #else
2281     u.ll.upper = ldq_raw(address_mask(env, addr));
2282     u.ll.lower = ldq_raw(address_mask(env, addr + 8));
2283     QT0 = u.q;
2284 #endif
2285 }
2286
2287 void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2288 {
2289     /* XXX add 128 bit store */
2290     CPU_QuadU u;
2291
2292     helper_check_align(env, addr, 7);
2293 #if !defined(CONFIG_USER_ONLY)
2294     switch (mem_idx) {
2295     case MMU_USER_IDX:
2296         u.q = QT0;
2297         cpu_stq_user(env, addr, u.ll.upper);
2298         cpu_stq_user(env, addr + 8, u.ll.lower);
2299         break;
2300     case MMU_KERNEL_IDX:
2301         u.q = QT0;
2302         cpu_stq_kernel(env, addr, u.ll.upper);
2303         cpu_stq_kernel(env, addr + 8, u.ll.lower);
2304         break;
2305 #ifdef TARGET_SPARC64
2306     case MMU_HYPV_IDX:
2307         u.q = QT0;
2308         cpu_stq_hypv(env, addr, u.ll.upper);
2309         cpu_stq_hypv(env, addr + 8, u.ll.lower);
2310         break;
2311 #endif
2312     default:
2313         DPRINTF_MMU("helper_stqf: need to check MMU idx %d\n", mem_idx);
2314         break;
2315     }
2316 #else
2317     u.q = QT0;
2318     stq_raw(address_mask(env, addr), u.ll.upper);
2319     stq_raw(address_mask(env, addr + 8), u.ll.lower);
2320 #endif
2321 }
2322
2323 #if !defined(CONFIG_USER_ONLY)
2324 #ifndef TARGET_SPARC64
2325 void cpu_unassigned_access(CPUSPARCState *env, hwaddr addr,
2326                            int is_write, int is_exec, int is_asi, int size)
2327 {
2328     int fault_type;
2329
2330 #ifdef DEBUG_UNASSIGNED
2331     if (is_asi) {
2332         printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
2333                " asi 0x%02x from " TARGET_FMT_lx "\n",
2334                is_exec ? "exec" : is_write ? "write" : "read", size,
2335                size == 1 ? "" : "s", addr, is_asi, env->pc);
2336     } else {
2337         printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
2338                " from " TARGET_FMT_lx "\n",
2339                is_exec ? "exec" : is_write ? "write" : "read", size,
2340                size == 1 ? "" : "s", addr, env->pc);
2341     }
2342 #endif
2343     /* Don't overwrite translation and access faults */
2344     fault_type = (env->mmuregs[3] & 0x1c) >> 2;
2345     if ((fault_type > 4) || (fault_type == 0)) {
2346         env->mmuregs[3] = 0; /* Fault status register */
2347         if (is_asi) {
2348             env->mmuregs[3] |= 1 << 16;
2349         }
2350         if (env->psrs) {
2351             env->mmuregs[3] |= 1 << 5;
2352         }
2353         if (is_exec) {
2354             env->mmuregs[3] |= 1 << 6;
2355         }
2356         if (is_write) {
2357             env->mmuregs[3] |= 1 << 7;
2358         }
2359         env->mmuregs[3] |= (5 << 2) | 2;
2360         /* SuperSPARC will never place instruction fault addresses in the FAR */
2361         if (!is_exec) {
2362             env->mmuregs[4] = addr; /* Fault address register */
2363         }
2364     }
2365     /* overflow (same type fault was not read before another fault) */
2366     if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) {
2367         env->mmuregs[3] |= 1;
2368     }
2369
2370     if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
2371         if (is_exec) {
2372             helper_raise_exception(env, TT_CODE_ACCESS);
2373         } else {
2374             helper_raise_exception(env, TT_DATA_ACCESS);
2375         }
2376     }
2377
2378     /* flush neverland mappings created during no-fault mode,
2379        so the sequential MMU faults report proper fault types */
2380     if (env->mmuregs[0] & MMU_NF) {
2381         tlb_flush(env, 1);
2382     }
2383 }
2384 #else
2385 void cpu_unassigned_access(CPUSPARCState *env, hwaddr addr,
2386                            int is_write, int is_exec, int is_asi, int size)
2387 {
2388 #ifdef DEBUG_UNASSIGNED
2389     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
2390            "\n", addr, env->pc);
2391 #endif
2392
2393     if (is_exec) {
2394         helper_raise_exception(env, TT_CODE_ACCESS);
2395     } else {
2396         helper_raise_exception(env, TT_DATA_ACCESS);
2397     }
2398 }
2399 #endif
2400 #endif
2401
2402 #if !defined(CONFIG_USER_ONLY)
2403 static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
2404                                               target_ulong addr, int is_write,
2405                                               int is_user, uintptr_t retaddr)
2406 {
2407 #ifdef DEBUG_UNALIGNED
2408     printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2409            "\n", addr, env->pc);
2410 #endif
2411     if (retaddr) {
2412         cpu_restore_state(env, retaddr);
2413     }
2414     helper_raise_exception(env, TT_UNALIGNED);
2415 }
2416
2417 /* try to fill the TLB and return an exception if error. If retaddr is
2418    NULL, it means that the function was called in C code (i.e. not
2419    from generated code or from helper.c) */
2420 /* XXX: fix it to restore all registers */
2421 void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx,
2422               uintptr_t retaddr)
2423 {
2424     int ret;
2425
2426     ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
2427     if (ret) {
2428         if (retaddr) {
2429             cpu_restore_state(env, retaddr);
2430         }
2431         cpu_loop_exit(env);
2432     }
2433 }
2434 #endif
This page took 0.171809 seconds and 4 git commands to generate.