e449400c10b0695cb23d722fd8ed2886940978e0
[qemu] / target-sparc / helper.c
1 /*
2  *  sparc helpers
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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <signal.h>
26 #include <assert.h>
27
28 #include "cpu.h"
29 #include "exec-all.h"
30 #include "qemu-common.h"
31 #include "helper.h"
32
33 //#define DEBUG_MMU
34 //#define DEBUG_FEATURES
35 //#define DEBUG_PCALL
36
37 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
38
39 /* Sparc MMU emulation */
40
41 /* thread support */
42
43 spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
44
45 void cpu_lock(void)
46 {
47     spin_lock(&global_cpu_lock);
48 }
49
50 void cpu_unlock(void)
51 {
52     spin_unlock(&global_cpu_lock);
53 }
54
55 #if defined(CONFIG_USER_ONLY)
56
57 int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
58                                int mmu_idx, int is_softmmu)
59 {
60     if (rw & 2)
61         env1->exception_index = TT_TFAULT;
62     else
63         env1->exception_index = TT_DFAULT;
64     return 1;
65 }
66
67 #else
68
69 #ifndef TARGET_SPARC64
70 /*
71  * Sparc V8 Reference MMU (SRMMU)
72  */
73 static const int access_table[8][8] = {
74     { 0, 0, 0, 0, 8, 0, 12, 12 },
75     { 0, 0, 0, 0, 8, 0, 0, 0 },
76     { 8, 8, 0, 0, 0, 8, 12, 12 },
77     { 8, 8, 0, 0, 0, 8, 0, 0 },
78     { 8, 0, 8, 0, 8, 8, 12, 12 },
79     { 8, 0, 8, 0, 8, 0, 8, 0 },
80     { 8, 8, 8, 0, 8, 8, 12, 12 },
81     { 8, 8, 8, 0, 8, 8, 8, 0 }
82 };
83
84 static const int perm_table[2][8] = {
85     {
86         PAGE_READ,
87         PAGE_READ | PAGE_WRITE,
88         PAGE_READ | PAGE_EXEC,
89         PAGE_READ | PAGE_WRITE | PAGE_EXEC,
90         PAGE_EXEC,
91         PAGE_READ | PAGE_WRITE,
92         PAGE_READ | PAGE_EXEC,
93         PAGE_READ | PAGE_WRITE | PAGE_EXEC
94     },
95     {
96         PAGE_READ,
97         PAGE_READ | PAGE_WRITE,
98         PAGE_READ | PAGE_EXEC,
99         PAGE_READ | PAGE_WRITE | PAGE_EXEC,
100         PAGE_EXEC,
101         PAGE_READ,
102         0,
103         0,
104     }
105 };
106
107 static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
108                                 int *prot, int *access_index,
109                                 target_ulong address, int rw, int mmu_idx)
110 {
111     int access_perms = 0;
112     target_phys_addr_t pde_ptr;
113     uint32_t pde;
114     target_ulong virt_addr;
115     int error_code = 0, is_dirty, is_user;
116     unsigned long page_offset;
117
118     is_user = mmu_idx == MMU_USER_IDX;
119     virt_addr = address & TARGET_PAGE_MASK;
120
121     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
122         // Boot mode: instruction fetches are taken from PROM
123         if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
124             *physical = env->prom_addr | (address & 0x7ffffULL);
125             *prot = PAGE_READ | PAGE_EXEC;
126             return 0;
127         }
128         *physical = address;
129         *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
130         return 0;
131     }
132
133     *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
134     *physical = 0xffffffffffff0000ULL;
135
136     /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
137     /* Context base + context number */
138     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
139     pde = ldl_phys(pde_ptr);
140
141     /* Ctx pde */
142     switch (pde & PTE_ENTRYTYPE_MASK) {
143     default:
144     case 0: /* Invalid */
145         return 1 << 2;
146     case 2: /* L0 PTE, maybe should not happen? */
147     case 3: /* Reserved */
148         return 4 << 2;
149     case 1: /* L0 PDE */
150         pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
151         pde = ldl_phys(pde_ptr);
152
153         switch (pde & PTE_ENTRYTYPE_MASK) {
154         default:
155         case 0: /* Invalid */
156             return (1 << 8) | (1 << 2);
157         case 3: /* Reserved */
158             return (1 << 8) | (4 << 2);
159         case 1: /* L1 PDE */
160             pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
161             pde = ldl_phys(pde_ptr);
162
163             switch (pde & PTE_ENTRYTYPE_MASK) {
164             default:
165             case 0: /* Invalid */
166                 return (2 << 8) | (1 << 2);
167             case 3: /* Reserved */
168                 return (2 << 8) | (4 << 2);
169             case 1: /* L2 PDE */
170                 pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
171                 pde = ldl_phys(pde_ptr);
172
173                 switch (pde & PTE_ENTRYTYPE_MASK) {
174                 default:
175                 case 0: /* Invalid */
176                     return (3 << 8) | (1 << 2);
177                 case 1: /* PDE, should not happen */
178                 case 3: /* Reserved */
179                     return (3 << 8) | (4 << 2);
180                 case 2: /* L3 PTE */
181                     virt_addr = address & TARGET_PAGE_MASK;
182                     page_offset = (address & TARGET_PAGE_MASK) &
183                         (TARGET_PAGE_SIZE - 1);
184                 }
185                 break;
186             case 2: /* L2 PTE */
187                 virt_addr = address & ~0x3ffff;
188                 page_offset = address & 0x3ffff;
189             }
190             break;
191         case 2: /* L1 PTE */
192             virt_addr = address & ~0xffffff;
193             page_offset = address & 0xffffff;
194         }
195     }
196
197     /* update page modified and dirty bits */
198     is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
199     if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
200         pde |= PG_ACCESSED_MASK;
201         if (is_dirty)
202             pde |= PG_MODIFIED_MASK;
203         stl_phys_notdirty(pde_ptr, pde);
204     }
205     /* check access */
206     access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
207     error_code = access_table[*access_index][access_perms];
208     if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
209         return error_code;
210
211     /* the page can be put in the TLB */
212     *prot = perm_table[is_user][access_perms];
213     if (!(pde & PG_MODIFIED_MASK)) {
214         /* only set write access if already dirty... otherwise wait
215            for dirty access */
216         *prot &= ~PAGE_WRITE;
217     }
218
219     /* Even if large ptes, we map only one 4KB page in the cache to
220        avoid filling it too fast */
221     *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
222     return error_code;
223 }
224
225 /* Perform address translation */
226 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
227                               int mmu_idx, int is_softmmu)
228 {
229     target_phys_addr_t paddr;
230     target_ulong vaddr;
231     int error_code = 0, prot, ret = 0, access_index;
232
233     error_code = get_physical_address(env, &paddr, &prot, &access_index,
234                                       address, rw, mmu_idx);
235     if (error_code == 0) {
236         vaddr = address & TARGET_PAGE_MASK;
237         paddr &= TARGET_PAGE_MASK;
238 #ifdef DEBUG_MMU
239         printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
240                TARGET_FMT_lx "\n", address, paddr, vaddr);
241 #endif
242         ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
243         return ret;
244     }
245
246     if (env->mmuregs[3]) /* Fault status register */
247         env->mmuregs[3] = 1; /* overflow (not read before another fault) */
248     env->mmuregs[3] |= (access_index << 5) | error_code | 2;
249     env->mmuregs[4] = address; /* Fault address register */
250
251     if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
252         // No fault mode: if a mapping is available, just override
253         // permissions. If no mapping is available, redirect accesses to
254         // neverland. Fake/overridden mappings will be flushed when
255         // switching to normal mode.
256         vaddr = address & TARGET_PAGE_MASK;
257         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
258         ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
259         return ret;
260     } else {
261         if (rw & 2)
262             env->exception_index = TT_TFAULT;
263         else
264             env->exception_index = TT_DFAULT;
265         return 1;
266     }
267 }
268
269 target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
270 {
271     target_phys_addr_t pde_ptr;
272     uint32_t pde;
273
274     /* Context base + context number */
275     pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
276         (env->mmuregs[2] << 2);
277     pde = ldl_phys(pde_ptr);
278
279     switch (pde & PTE_ENTRYTYPE_MASK) {
280     default:
281     case 0: /* Invalid */
282     case 2: /* PTE, maybe should not happen? */
283     case 3: /* Reserved */
284         return 0;
285     case 1: /* L1 PDE */
286         if (mmulev == 3)
287             return pde;
288         pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
289         pde = ldl_phys(pde_ptr);
290
291         switch (pde & PTE_ENTRYTYPE_MASK) {
292         default:
293         case 0: /* Invalid */
294         case 3: /* Reserved */
295             return 0;
296         case 2: /* L1 PTE */
297             return pde;
298         case 1: /* L2 PDE */
299             if (mmulev == 2)
300                 return pde;
301             pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
302             pde = ldl_phys(pde_ptr);
303
304             switch (pde & PTE_ENTRYTYPE_MASK) {
305             default:
306             case 0: /* Invalid */
307             case 3: /* Reserved */
308                 return 0;
309             case 2: /* L2 PTE */
310                 return pde;
311             case 1: /* L3 PDE */
312                 if (mmulev == 1)
313                     return pde;
314                 pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
315                 pde = ldl_phys(pde_ptr);
316
317                 switch (pde & PTE_ENTRYTYPE_MASK) {
318                 default:
319                 case 0: /* Invalid */
320                 case 1: /* PDE, should not happen */
321                 case 3: /* Reserved */
322                     return 0;
323                 case 2: /* L3 PTE */
324                     return pde;
325                 }
326             }
327         }
328     }
329     return 0;
330 }
331
332 #ifdef DEBUG_MMU
333 void dump_mmu(CPUState *env)
334 {
335     target_ulong va, va1, va2;
336     unsigned int n, m, o;
337     target_phys_addr_t pde_ptr, pa;
338     uint32_t pde;
339
340     printf("MMU dump:\n");
341     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
342     pde = ldl_phys(pde_ptr);
343     printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
344            (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
345     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
346         pde = mmu_probe(env, va, 2);
347         if (pde) {
348             pa = cpu_get_phys_page_debug(env, va);
349             printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
350                    " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
351             for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
352                 pde = mmu_probe(env, va1, 1);
353                 if (pde) {
354                     pa = cpu_get_phys_page_debug(env, va1);
355                     printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
356                            " PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
357                     for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
358                         pde = mmu_probe(env, va2, 0);
359                         if (pde) {
360                             pa = cpu_get_phys_page_debug(env, va2);
361                             printf("  VA: " TARGET_FMT_lx ", PA: "
362                                    TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
363                                    va2, pa, pde);
364                         }
365                     }
366                 }
367             }
368         }
369     }
370     printf("MMU dump ends\n");
371 }
372 #endif /* DEBUG_MMU */
373
374 #else /* !TARGET_SPARC64 */
375 /*
376  * UltraSparc IIi I/DMMUs
377  */
378 static int get_physical_address_data(CPUState *env,
379                                      target_phys_addr_t *physical, int *prot,
380                                      target_ulong address, int rw, int is_user)
381 {
382     target_ulong mask;
383     unsigned int i;
384
385     if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
386         *physical = address;
387         *prot = PAGE_READ | PAGE_WRITE;
388         return 0;
389     }
390
391     for (i = 0; i < 64; i++) {
392         switch ((env->dtlb_tte[i] >> 61) & 3) {
393         default:
394         case 0x0: // 8k
395             mask = 0xffffffffffffe000ULL;
396             break;
397         case 0x1: // 64k
398             mask = 0xffffffffffff0000ULL;
399             break;
400         case 0x2: // 512k
401             mask = 0xfffffffffff80000ULL;
402             break;
403         case 0x3: // 4M
404             mask = 0xffffffffffc00000ULL;
405             break;
406         }
407         // ctx match, vaddr match?
408         if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
409             (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
410             // valid, access ok?
411             if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
412                 ((env->dtlb_tte[i] & 0x4) && is_user) ||
413                 (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
414                 if (env->dmmuregs[3]) /* Fault status register */
415                     env->dmmuregs[3] = 2; /* overflow (not read before
416                                              another fault) */
417                 env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
418                 env->dmmuregs[4] = address; /* Fault address register */
419                 env->exception_index = TT_DFAULT;
420 #ifdef DEBUG_MMU
421                 printf("DFAULT at 0x%" PRIx64 "\n", address);
422 #endif
423                 return 1;
424             }
425             *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) +
426                 (address & ~mask & 0x1fffffff000ULL);
427             *prot = PAGE_READ;
428             if (env->dtlb_tte[i] & 0x2)
429                 *prot |= PAGE_WRITE;
430             return 0;
431         }
432     }
433 #ifdef DEBUG_MMU
434     printf("DMISS at 0x%" PRIx64 "\n", address);
435 #endif
436     env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
437     env->exception_index = TT_DMISS;
438     return 1;
439 }
440
441 static int get_physical_address_code(CPUState *env,
442                                      target_phys_addr_t *physical, int *prot,
443                                      target_ulong address, int is_user)
444 {
445     target_ulong mask;
446     unsigned int i;
447
448     if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
449         *physical = address;
450         *prot = PAGE_EXEC;
451         return 0;
452     }
453
454     for (i = 0; i < 64; i++) {
455         switch ((env->itlb_tte[i] >> 61) & 3) {
456         default:
457         case 0x0: // 8k
458             mask = 0xffffffffffffe000ULL;
459             break;
460         case 0x1: // 64k
461             mask = 0xffffffffffff0000ULL;
462             break;
463         case 0x2: // 512k
464             mask = 0xfffffffffff80000ULL;
465             break;
466         case 0x3: // 4M
467             mask = 0xffffffffffc00000ULL;
468                 break;
469         }
470         // ctx match, vaddr match?
471         if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
472             (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
473             // valid, access ok?
474             if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
475                 ((env->itlb_tte[i] & 0x4) && is_user)) {
476                 if (env->immuregs[3]) /* Fault status register */
477                     env->immuregs[3] = 2; /* overflow (not read before
478                                              another fault) */
479                 env->immuregs[3] |= (is_user << 3) | 1;
480                 env->exception_index = TT_TFAULT;
481 #ifdef DEBUG_MMU
482                 printf("TFAULT at 0x%" PRIx64 "\n", address);
483 #endif
484                 return 1;
485             }
486             *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +
487                 (address & ~mask & 0x1fffffff000ULL);
488             *prot = PAGE_EXEC;
489             return 0;
490         }
491     }
492 #ifdef DEBUG_MMU
493     printf("TMISS at 0x%" PRIx64 "\n", address);
494 #endif
495     env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
496     env->exception_index = TT_TMISS;
497     return 1;
498 }
499
500 static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
501                                 int *prot, int *access_index,
502                                 target_ulong address, int rw, int mmu_idx)
503 {
504     int is_user = mmu_idx == MMU_USER_IDX;
505
506     if (rw == 2)
507         return get_physical_address_code(env, physical, prot, address,
508                                          is_user);
509     else
510         return get_physical_address_data(env, physical, prot, address, rw,
511                                          is_user);
512 }
513
514 /* Perform address translation */
515 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
516                               int mmu_idx, int is_softmmu)
517 {
518     target_ulong virt_addr, vaddr;
519     target_phys_addr_t paddr;
520     int error_code = 0, prot, ret = 0, access_index;
521
522     error_code = get_physical_address(env, &paddr, &prot, &access_index,
523                                       address, rw, mmu_idx);
524     if (error_code == 0) {
525         virt_addr = address & TARGET_PAGE_MASK;
526         vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
527                              (TARGET_PAGE_SIZE - 1));
528 #ifdef DEBUG_MMU
529         printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
530                "\n", address, paddr, vaddr);
531 #endif
532         ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
533         return ret;
534     }
535     // XXX
536     return 1;
537 }
538
539 #ifdef DEBUG_MMU
540 void dump_mmu(CPUState *env)
541 {
542     unsigned int i;
543     const char *mask;
544
545     printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n",
546            env->dmmuregs[1], env->dmmuregs[2]);
547     if ((env->lsu & DMMU_E) == 0) {
548         printf("DMMU disabled\n");
549     } else {
550         printf("DMMU dump:\n");
551         for (i = 0; i < 64; i++) {
552             switch ((env->dtlb_tte[i] >> 61) & 3) {
553             default:
554             case 0x0:
555                 mask = "  8k";
556                 break;
557             case 0x1:
558                 mask = " 64k";
559                 break;
560             case 0x2:
561                 mask = "512k";
562                 break;
563             case 0x3:
564                 mask = "  4M";
565                 break;
566             }
567             if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
568                 printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
569                        ", %s, %s, %s, %s, ctx %" PRId64 "\n",
570                        env->dtlb_tag[i] & ~0x1fffULL,
571                        env->dtlb_tte[i] & 0x1ffffffe000ULL,
572                        mask,
573                        env->dtlb_tte[i] & 0x4? "priv": "user",
574                        env->dtlb_tte[i] & 0x2? "RW": "RO",
575                        env->dtlb_tte[i] & 0x40? "locked": "unlocked",
576                        env->dtlb_tag[i] & 0x1fffULL);
577             }
578         }
579     }
580     if ((env->lsu & IMMU_E) == 0) {
581         printf("IMMU disabled\n");
582     } else {
583         printf("IMMU dump:\n");
584         for (i = 0; i < 64; i++) {
585             switch ((env->itlb_tte[i] >> 61) & 3) {
586             default:
587             case 0x0:
588                 mask = "  8k";
589                 break;
590             case 0x1:
591                 mask = " 64k";
592                 break;
593             case 0x2:
594                 mask = "512k";
595                 break;
596             case 0x3:
597                 mask = "  4M";
598                 break;
599             }
600             if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
601                 printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
602                        ", %s, %s, %s, ctx %" PRId64 "\n",
603                        env->itlb_tag[i] & ~0x1fffULL,
604                        env->itlb_tte[i] & 0x1ffffffe000ULL,
605                        mask,
606                        env->itlb_tte[i] & 0x4? "priv": "user",
607                        env->itlb_tte[i] & 0x40? "locked": "unlocked",
608                        env->itlb_tag[i] & 0x1fffULL);
609             }
610         }
611     }
612 }
613 #endif /* DEBUG_MMU */
614
615 #endif /* TARGET_SPARC64 */
616 #endif /* !CONFIG_USER_ONLY */
617
618
619 #if defined(CONFIG_USER_ONLY)
620 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
621 {
622     return addr;
623 }
624
625 #else
626 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
627 {
628     target_phys_addr_t phys_addr;
629     int prot, access_index;
630
631     if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
632                              MMU_KERNEL_IDX) != 0)
633         if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
634                                  0, MMU_KERNEL_IDX) != 0)
635             return -1;
636     if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
637         return -1;
638     return phys_addr;
639 }
640 #endif
641
642 #ifdef TARGET_SPARC64
643 #ifdef DEBUG_PCALL
644 static const char * const excp_names[0x80] = {
645     [TT_TFAULT] = "Instruction Access Fault",
646     [TT_TMISS] = "Instruction Access MMU Miss",
647     [TT_CODE_ACCESS] = "Instruction Access Error",
648     [TT_ILL_INSN] = "Illegal Instruction",
649     [TT_PRIV_INSN] = "Privileged Instruction",
650     [TT_NFPU_INSN] = "FPU Disabled",
651     [TT_FP_EXCP] = "FPU Exception",
652     [TT_TOVF] = "Tag Overflow",
653     [TT_CLRWIN] = "Clean Windows",
654     [TT_DIV_ZERO] = "Division By Zero",
655     [TT_DFAULT] = "Data Access Fault",
656     [TT_DMISS] = "Data Access MMU Miss",
657     [TT_DATA_ACCESS] = "Data Access Error",
658     [TT_DPROT] = "Data Protection Error",
659     [TT_UNALIGNED] = "Unaligned Memory Access",
660     [TT_PRIV_ACT] = "Privileged Action",
661     [TT_EXTINT | 0x1] = "External Interrupt 1",
662     [TT_EXTINT | 0x2] = "External Interrupt 2",
663     [TT_EXTINT | 0x3] = "External Interrupt 3",
664     [TT_EXTINT | 0x4] = "External Interrupt 4",
665     [TT_EXTINT | 0x5] = "External Interrupt 5",
666     [TT_EXTINT | 0x6] = "External Interrupt 6",
667     [TT_EXTINT | 0x7] = "External Interrupt 7",
668     [TT_EXTINT | 0x8] = "External Interrupt 8",
669     [TT_EXTINT | 0x9] = "External Interrupt 9",
670     [TT_EXTINT | 0xa] = "External Interrupt 10",
671     [TT_EXTINT | 0xb] = "External Interrupt 11",
672     [TT_EXTINT | 0xc] = "External Interrupt 12",
673     [TT_EXTINT | 0xd] = "External Interrupt 13",
674     [TT_EXTINT | 0xe] = "External Interrupt 14",
675     [TT_EXTINT | 0xf] = "External Interrupt 15",
676 };
677 #endif
678
679 void do_interrupt(CPUState *env)
680 {
681     int intno = env->exception_index;
682
683 #ifdef DEBUG_PCALL
684     if (loglevel & CPU_LOG_INT) {
685         static int count;
686         const char *name;
687
688         if (intno < 0 || intno >= 0x180)
689             name = "Unknown";
690         else if (intno >= 0x100)
691             name = "Trap Instruction";
692         else if (intno >= 0xc0)
693             name = "Window Fill";
694         else if (intno >= 0x80)
695             name = "Window Spill";
696         else {
697             name = excp_names[intno];
698             if (!name)
699                 name = "Unknown";
700         }
701
702         fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
703                 " SP=%016" PRIx64 "\n",
704                 count, name, intno,
705                 env->pc,
706                 env->npc, env->regwptr[6]);
707         cpu_dump_state(env, logfile, fprintf, 0);
708 #if 0
709         {
710             int i;
711             uint8_t *ptr;
712
713             fprintf(logfile, "       code=");
714             ptr = (uint8_t *)env->pc;
715             for(i = 0; i < 16; i++) {
716                 fprintf(logfile, " %02x", ldub(ptr + i));
717             }
718             fprintf(logfile, "\n");
719         }
720 #endif
721         count++;
722     }
723 #endif
724 #if !defined(CONFIG_USER_ONLY)
725     if (env->tl >= env->maxtl) {
726         cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
727                   " Error state", env->exception_index, env->tl, env->maxtl);
728         return;
729     }
730 #endif
731     if (env->tl < env->maxtl - 1) {
732         env->tl++;
733     } else {
734         env->pstate |= PS_RED;
735         if (env->tl < env->maxtl)
736             env->tl++;
737     }
738     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
739     env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
740         ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
741         GET_CWP64(env);
742     env->tsptr->tpc = env->pc;
743     env->tsptr->tnpc = env->npc;
744     env->tsptr->tt = intno;
745     if (!(env->def->features & CPU_FEATURE_GL)) {
746         switch (intno) {
747         case TT_IVEC:
748             change_pstate(PS_PEF | PS_PRIV | PS_IG);
749             break;
750         case TT_TFAULT:
751         case TT_TMISS:
752         case TT_DFAULT:
753         case TT_DMISS:
754         case TT_DPROT:
755             change_pstate(PS_PEF | PS_PRIV | PS_MG);
756             break;
757         default:
758             change_pstate(PS_PEF | PS_PRIV | PS_AG);
759             break;
760         }
761     }
762     if (intno == TT_CLRWIN)
763         cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
764     else if ((intno & 0x1c0) == TT_SPILL)
765         cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
766     else if ((intno & 0x1c0) == TT_FILL)
767         cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
768     env->tbr &= ~0x7fffULL;
769     env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
770     env->pc = env->tbr;
771     env->npc = env->pc + 4;
772     env->exception_index = 0;
773 }
774 #else
775 #ifdef DEBUG_PCALL
776 static const char * const excp_names[0x80] = {
777     [TT_TFAULT] = "Instruction Access Fault",
778     [TT_ILL_INSN] = "Illegal Instruction",
779     [TT_PRIV_INSN] = "Privileged Instruction",
780     [TT_NFPU_INSN] = "FPU Disabled",
781     [TT_WIN_OVF] = "Window Overflow",
782     [TT_WIN_UNF] = "Window Underflow",
783     [TT_UNALIGNED] = "Unaligned Memory Access",
784     [TT_FP_EXCP] = "FPU Exception",
785     [TT_DFAULT] = "Data Access Fault",
786     [TT_TOVF] = "Tag Overflow",
787     [TT_EXTINT | 0x1] = "External Interrupt 1",
788     [TT_EXTINT | 0x2] = "External Interrupt 2",
789     [TT_EXTINT | 0x3] = "External Interrupt 3",
790     [TT_EXTINT | 0x4] = "External Interrupt 4",
791     [TT_EXTINT | 0x5] = "External Interrupt 5",
792     [TT_EXTINT | 0x6] = "External Interrupt 6",
793     [TT_EXTINT | 0x7] = "External Interrupt 7",
794     [TT_EXTINT | 0x8] = "External Interrupt 8",
795     [TT_EXTINT | 0x9] = "External Interrupt 9",
796     [TT_EXTINT | 0xa] = "External Interrupt 10",
797     [TT_EXTINT | 0xb] = "External Interrupt 11",
798     [TT_EXTINT | 0xc] = "External Interrupt 12",
799     [TT_EXTINT | 0xd] = "External Interrupt 13",
800     [TT_EXTINT | 0xe] = "External Interrupt 14",
801     [TT_EXTINT | 0xf] = "External Interrupt 15",
802     [TT_TOVF] = "Tag Overflow",
803     [TT_CODE_ACCESS] = "Instruction Access Error",
804     [TT_DATA_ACCESS] = "Data Access Error",
805     [TT_DIV_ZERO] = "Division By Zero",
806     [TT_NCP_INSN] = "Coprocessor Disabled",
807 };
808 #endif
809
810 void do_interrupt(CPUState *env)
811 {
812     int cwp, intno = env->exception_index;
813
814 #ifdef DEBUG_PCALL
815     if (loglevel & CPU_LOG_INT) {
816         static int count;
817         const char *name;
818
819         if (intno < 0 || intno >= 0x100)
820             name = "Unknown";
821         else if (intno >= 0x80)
822             name = "Trap Instruction";
823         else {
824             name = excp_names[intno];
825             if (!name)
826                 name = "Unknown";
827         }
828
829         fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
830                 count, name, intno,
831                 env->pc,
832                 env->npc, env->regwptr[6]);
833         cpu_dump_state(env, logfile, fprintf, 0);
834 #if 0
835         {
836             int i;
837             uint8_t *ptr;
838
839             fprintf(logfile, "       code=");
840             ptr = (uint8_t *)env->pc;
841             for(i = 0; i < 16; i++) {
842                 fprintf(logfile, " %02x", ldub(ptr + i));
843             }
844             fprintf(logfile, "\n");
845         }
846 #endif
847         count++;
848     }
849 #endif
850 #if !defined(CONFIG_USER_ONLY)
851     if (env->psret == 0) {
852         cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
853                   env->exception_index);
854         return;
855     }
856 #endif
857     env->psret = 0;
858     cwp = cpu_cwp_dec(env, env->cwp - 1);
859     cpu_set_cwp(env, cwp);
860     env->regwptr[9] = env->pc;
861     env->regwptr[10] = env->npc;
862     env->psrps = env->psrs;
863     env->psrs = 1;
864     env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
865     env->pc = env->tbr;
866     env->npc = env->pc + 4;
867     env->exception_index = 0;
868 }
869 #endif
870
871 void memcpy32(target_ulong *dst, const target_ulong *src)
872 {
873     dst[0] = src[0];
874     dst[1] = src[1];
875     dst[2] = src[2];
876     dst[3] = src[3];
877     dst[4] = src[4];
878     dst[5] = src[5];
879     dst[6] = src[6];
880     dst[7] = src[7];
881 }
882
883 void cpu_reset(CPUSPARCState *env)
884 {
885     tlb_flush(env, 1);
886     env->cwp = 0;
887     env->wim = 1;
888     env->regwptr = env->regbase + (env->cwp * 16);
889 #if defined(CONFIG_USER_ONLY)
890     env->user_mode_only = 1;
891 #ifdef TARGET_SPARC64
892     env->cleanwin = env->nwindows - 2;
893     env->cansave = env->nwindows - 2;
894     env->pstate = PS_RMO | PS_PEF | PS_IE;
895     env->asi = 0x82; // Primary no-fault
896 #endif
897 #else
898     env->psret = 0;
899     env->psrs = 1;
900     env->psrps = 1;
901 #ifdef TARGET_SPARC64
902     env->pstate = PS_PRIV;
903     env->hpstate = HS_PRIV;
904     env->pc = 0x1fff0000020ULL; // XXX should be different for system_reset
905     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
906 #else
907     env->pc = 0;
908     env->mmuregs[0] &= ~(MMU_E | MMU_NF);
909     env->mmuregs[0] |= env->def->mmu_bm;
910 #endif
911     env->npc = env->pc + 4;
912 #endif
913 }
914
915 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
916 {
917     sparc_def_t def1, *def = &def1;
918
919     if (cpu_sparc_find_by_name(def, cpu_model) < 0)
920         return -1;
921
922     env->def = qemu_mallocz(sizeof(*def));
923     memcpy(env->def, def, sizeof(*def));
924 #if defined(CONFIG_USER_ONLY)
925     if ((env->def->features & CPU_FEATURE_FLOAT))
926         env->def->features |= CPU_FEATURE_FLOAT128;
927 #endif
928     env->cpu_model_str = cpu_model;
929     env->version = def->iu_version;
930     env->fsr = def->fpu_version;
931     env->nwindows = def->nwindows;
932 #if !defined(TARGET_SPARC64)
933     env->mmuregs[0] |= def->mmu_version;
934     cpu_sparc_set_id(env, 0);
935 #else
936     env->mmu_version = def->mmu_version;
937     env->maxtl = def->maxtl;
938     env->version |= def->maxtl << 8;
939     env->version |= def->nwindows - 1;
940 #endif
941     return 0;
942 }
943
944 static void cpu_sparc_close(CPUSPARCState *env)
945 {
946     free(env->def);
947     free(env);
948 }
949
950 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
951 {
952     CPUSPARCState *env;
953
954     env = qemu_mallocz(sizeof(CPUSPARCState));
955     if (!env)
956         return NULL;
957     cpu_exec_init(env);
958
959     gen_intermediate_code_init(env);
960
961     if (cpu_sparc_register(env, cpu_model) < 0) {
962         cpu_sparc_close(env);
963         return NULL;
964     }
965     cpu_reset(env);
966
967     return env;
968 }
969
970 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
971 {
972 #if !defined(TARGET_SPARC64)
973     env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
974 #endif
975 }
976
977 static const sparc_def_t sparc_defs[] = {
978 #ifdef TARGET_SPARC64
979     {
980         .name = "Fujitsu Sparc64",
981         .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
982         .fpu_version = 0x00000000,
983         .mmu_version = mmu_us_12,
984         .nwindows = 4,
985         .maxtl = 4,
986         .features = CPU_DEFAULT_FEATURES,
987     },
988     {
989         .name = "Fujitsu Sparc64 III",
990         .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
991         .fpu_version = 0x00000000,
992         .mmu_version = mmu_us_12,
993         .nwindows = 5,
994         .maxtl = 4,
995         .features = CPU_DEFAULT_FEATURES,
996     },
997     {
998         .name = "Fujitsu Sparc64 IV",
999         .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
1000         .fpu_version = 0x00000000,
1001         .mmu_version = mmu_us_12,
1002         .nwindows = 8,
1003         .maxtl = 5,
1004         .features = CPU_DEFAULT_FEATURES,
1005     },
1006     {
1007         .name = "Fujitsu Sparc64 V",
1008         .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
1009         .fpu_version = 0x00000000,
1010         .mmu_version = mmu_us_12,
1011         .nwindows = 8,
1012         .maxtl = 5,
1013         .features = CPU_DEFAULT_FEATURES,
1014     },
1015     {
1016         .name = "TI UltraSparc I",
1017         .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
1018         .fpu_version = 0x00000000,
1019         .mmu_version = mmu_us_12,
1020         .nwindows = 8,
1021         .maxtl = 5,
1022         .features = CPU_DEFAULT_FEATURES,
1023     },
1024     {
1025         .name = "TI UltraSparc II",
1026         .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
1027         .fpu_version = 0x00000000,
1028         .mmu_version = mmu_us_12,
1029         .nwindows = 8,
1030         .maxtl = 5,
1031         .features = CPU_DEFAULT_FEATURES,
1032     },
1033     {
1034         .name = "TI UltraSparc IIi",
1035         .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
1036         .fpu_version = 0x00000000,
1037         .mmu_version = mmu_us_12,
1038         .nwindows = 8,
1039         .maxtl = 5,
1040         .features = CPU_DEFAULT_FEATURES,
1041     },
1042     {
1043         .name = "TI UltraSparc IIe",
1044         .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
1045         .fpu_version = 0x00000000,
1046         .mmu_version = mmu_us_12,
1047         .nwindows = 8,
1048         .maxtl = 5,
1049         .features = CPU_DEFAULT_FEATURES,
1050     },
1051     {
1052         .name = "Sun UltraSparc III",
1053         .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
1054         .fpu_version = 0x00000000,
1055         .mmu_version = mmu_us_12,
1056         .nwindows = 8,
1057         .maxtl = 5,
1058         .features = CPU_DEFAULT_FEATURES,
1059     },
1060     {
1061         .name = "Sun UltraSparc III Cu",
1062         .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
1063         .fpu_version = 0x00000000,
1064         .mmu_version = mmu_us_3,
1065         .nwindows = 8,
1066         .maxtl = 5,
1067         .features = CPU_DEFAULT_FEATURES,
1068     },
1069     {
1070         .name = "Sun UltraSparc IIIi",
1071         .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
1072         .fpu_version = 0x00000000,
1073         .mmu_version = mmu_us_12,
1074         .nwindows = 8,
1075         .maxtl = 5,
1076         .features = CPU_DEFAULT_FEATURES,
1077     },
1078     {
1079         .name = "Sun UltraSparc IV",
1080         .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
1081         .fpu_version = 0x00000000,
1082         .mmu_version = mmu_us_4,
1083         .nwindows = 8,
1084         .maxtl = 5,
1085         .features = CPU_DEFAULT_FEATURES,
1086     },
1087     {
1088         .name = "Sun UltraSparc IV+",
1089         .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
1090         .fpu_version = 0x00000000,
1091         .mmu_version = mmu_us_12,
1092         .nwindows = 8,
1093         .maxtl = 5,
1094         .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
1095     },
1096     {
1097         .name = "Sun UltraSparc IIIi+",
1098         .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
1099         .fpu_version = 0x00000000,
1100         .mmu_version = mmu_us_3,
1101         .nwindows = 8,
1102         .maxtl = 5,
1103         .features = CPU_DEFAULT_FEATURES,
1104     },
1105     {
1106         .name = "Sun UltraSparc T1",
1107         // defined in sparc_ifu_fdp.v and ctu.h
1108         .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
1109         .fpu_version = 0x00000000,
1110         .mmu_version = mmu_sun4v,
1111         .nwindows = 8,
1112         .maxtl = 6,
1113         .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
1114         | CPU_FEATURE_GL,
1115     },
1116     {
1117         .name = "Sun UltraSparc T2",
1118         // defined in tlu_asi_ctl.v and n2_revid_cust.v
1119         .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
1120         .fpu_version = 0x00000000,
1121         .mmu_version = mmu_sun4v,
1122         .nwindows = 8,
1123         .maxtl = 6,
1124         .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
1125         | CPU_FEATURE_GL,
1126     },
1127     {
1128         .name = "NEC UltraSparc I",
1129         .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
1130         .fpu_version = 0x00000000,
1131         .mmu_version = mmu_us_12,
1132         .nwindows = 8,
1133         .maxtl = 5,
1134         .features = CPU_DEFAULT_FEATURES,
1135     },
1136 #else
1137     {
1138         .name = "Fujitsu MB86900",
1139         .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
1140         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1141         .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
1142         .mmu_bm = 0x00004000,
1143         .mmu_ctpr_mask = 0x007ffff0,
1144         .mmu_cxr_mask = 0x0000003f,
1145         .mmu_sfsr_mask = 0xffffffff,
1146         .mmu_trcr_mask = 0xffffffff,
1147         .nwindows = 7,
1148         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
1149     },
1150     {
1151         .name = "Fujitsu MB86904",
1152         .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
1153         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1154         .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
1155         .mmu_bm = 0x00004000,
1156         .mmu_ctpr_mask = 0x00ffffc0,
1157         .mmu_cxr_mask = 0x000000ff,
1158         .mmu_sfsr_mask = 0x00016fff,
1159         .mmu_trcr_mask = 0x00ffffff,
1160         .nwindows = 8,
1161         .features = CPU_DEFAULT_FEATURES,
1162     },
1163     {
1164         .name = "Fujitsu MB86907",
1165         .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
1166         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1167         .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
1168         .mmu_bm = 0x00004000,
1169         .mmu_ctpr_mask = 0xffffffc0,
1170         .mmu_cxr_mask = 0x000000ff,
1171         .mmu_sfsr_mask = 0x00016fff,
1172         .mmu_trcr_mask = 0xffffffff,
1173         .nwindows = 8,
1174         .features = CPU_DEFAULT_FEATURES,
1175     },
1176     {
1177         .name = "LSI L64811",
1178         .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
1179         .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
1180         .mmu_version = 0x10 << 24,
1181         .mmu_bm = 0x00004000,
1182         .mmu_ctpr_mask = 0x007ffff0,
1183         .mmu_cxr_mask = 0x0000003f,
1184         .mmu_sfsr_mask = 0xffffffff,
1185         .mmu_trcr_mask = 0xffffffff,
1186         .nwindows = 8,
1187         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1188         CPU_FEATURE_FSMULD,
1189     },
1190     {
1191         .name = "Cypress CY7C601",
1192         .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
1193         .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1194         .mmu_version = 0x10 << 24,
1195         .mmu_bm = 0x00004000,
1196         .mmu_ctpr_mask = 0x007ffff0,
1197         .mmu_cxr_mask = 0x0000003f,
1198         .mmu_sfsr_mask = 0xffffffff,
1199         .mmu_trcr_mask = 0xffffffff,
1200         .nwindows = 8,
1201         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1202         CPU_FEATURE_FSMULD,
1203     },
1204     {
1205         .name = "Cypress CY7C611",
1206         .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
1207         .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1208         .mmu_version = 0x10 << 24,
1209         .mmu_bm = 0x00004000,
1210         .mmu_ctpr_mask = 0x007ffff0,
1211         .mmu_cxr_mask = 0x0000003f,
1212         .mmu_sfsr_mask = 0xffffffff,
1213         .mmu_trcr_mask = 0xffffffff,
1214         .nwindows = 8,
1215         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1216         CPU_FEATURE_FSMULD,
1217     },
1218     {
1219         .name = "TI SuperSparc II",
1220         .iu_version = 0x40000000,
1221         .fpu_version = 0 << 17,
1222         .mmu_version = 0x04000000,
1223         .mmu_bm = 0x00002000,
1224         .mmu_ctpr_mask = 0xffffffc0,
1225         .mmu_cxr_mask = 0x0000ffff,
1226         .mmu_sfsr_mask = 0xffffffff,
1227         .mmu_trcr_mask = 0xffffffff,
1228         .nwindows = 8,
1229         .features = CPU_DEFAULT_FEATURES,
1230     },
1231     {
1232         .name = "TI MicroSparc I",
1233         .iu_version = 0x41000000,
1234         .fpu_version = 4 << 17,
1235         .mmu_version = 0x41000000,
1236         .mmu_bm = 0x00004000,
1237         .mmu_ctpr_mask = 0x007ffff0,
1238         .mmu_cxr_mask = 0x0000003f,
1239         .mmu_sfsr_mask = 0x00016fff,
1240         .mmu_trcr_mask = 0x0000003f,
1241         .nwindows = 7,
1242         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
1243         CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
1244         CPU_FEATURE_FMUL,
1245     },
1246     {
1247         .name = "TI MicroSparc II",
1248         .iu_version = 0x42000000,
1249         .fpu_version = 4 << 17,
1250         .mmu_version = 0x02000000,
1251         .mmu_bm = 0x00004000,
1252         .mmu_ctpr_mask = 0x00ffffc0,
1253         .mmu_cxr_mask = 0x000000ff,
1254         .mmu_sfsr_mask = 0x00016fff,
1255         .mmu_trcr_mask = 0x00ffffff,
1256         .nwindows = 8,
1257         .features = CPU_DEFAULT_FEATURES,
1258     },
1259     {
1260         .name = "TI MicroSparc IIep",
1261         .iu_version = 0x42000000,
1262         .fpu_version = 4 << 17,
1263         .mmu_version = 0x04000000,
1264         .mmu_bm = 0x00004000,
1265         .mmu_ctpr_mask = 0x00ffffc0,
1266         .mmu_cxr_mask = 0x000000ff,
1267         .mmu_sfsr_mask = 0x00016bff,
1268         .mmu_trcr_mask = 0x00ffffff,
1269         .nwindows = 8,
1270         .features = CPU_DEFAULT_FEATURES,
1271     },
1272     {
1273         .name = "TI SuperSparc 40", // STP1020NPGA
1274         .iu_version = 0x41000000,
1275         .fpu_version = 0 << 17,
1276         .mmu_version = 0x00000000,
1277         .mmu_bm = 0x00002000,
1278         .mmu_ctpr_mask = 0xffffffc0,
1279         .mmu_cxr_mask = 0x0000ffff,
1280         .mmu_sfsr_mask = 0xffffffff,
1281         .mmu_trcr_mask = 0xffffffff,
1282         .nwindows = 8,
1283         .features = CPU_DEFAULT_FEATURES,
1284     },
1285     {
1286         .name = "TI SuperSparc 50", // STP1020PGA
1287         .iu_version = 0x40000000,
1288         .fpu_version = 0 << 17,
1289         .mmu_version = 0x04000000,
1290         .mmu_bm = 0x00002000,
1291         .mmu_ctpr_mask = 0xffffffc0,
1292         .mmu_cxr_mask = 0x0000ffff,
1293         .mmu_sfsr_mask = 0xffffffff,
1294         .mmu_trcr_mask = 0xffffffff,
1295         .nwindows = 8,
1296         .features = CPU_DEFAULT_FEATURES,
1297     },
1298     {
1299         .name = "TI SuperSparc 51",
1300         .iu_version = 0x43000000,
1301         .fpu_version = 0 << 17,
1302         .mmu_version = 0x04000000,
1303         .mmu_bm = 0x00002000,
1304         .mmu_ctpr_mask = 0xffffffc0,
1305         .mmu_cxr_mask = 0x0000ffff,
1306         .mmu_sfsr_mask = 0xffffffff,
1307         .mmu_trcr_mask = 0xffffffff,
1308         .nwindows = 8,
1309         .features = CPU_DEFAULT_FEATURES,
1310     },
1311     {
1312         .name = "TI SuperSparc 60", // STP1020APGA
1313         .iu_version = 0x40000000,
1314         .fpu_version = 0 << 17,
1315         .mmu_version = 0x03000000,
1316         .mmu_bm = 0x00002000,
1317         .mmu_ctpr_mask = 0xffffffc0,
1318         .mmu_cxr_mask = 0x0000ffff,
1319         .mmu_sfsr_mask = 0xffffffff,
1320         .mmu_trcr_mask = 0xffffffff,
1321         .nwindows = 8,
1322         .features = CPU_DEFAULT_FEATURES,
1323     },
1324     {
1325         .name = "TI SuperSparc 61",
1326         .iu_version = 0x44000000,
1327         .fpu_version = 0 << 17,
1328         .mmu_version = 0x04000000,
1329         .mmu_bm = 0x00002000,
1330         .mmu_ctpr_mask = 0xffffffc0,
1331         .mmu_cxr_mask = 0x0000ffff,
1332         .mmu_sfsr_mask = 0xffffffff,
1333         .mmu_trcr_mask = 0xffffffff,
1334         .nwindows = 8,
1335         .features = CPU_DEFAULT_FEATURES,
1336     },
1337     {
1338         .name = "Ross RT625",
1339         .iu_version = 0x1e000000,
1340         .fpu_version = 1 << 17,
1341         .mmu_version = 0x1e000000,
1342         .mmu_bm = 0x00004000,
1343         .mmu_ctpr_mask = 0x007ffff0,
1344         .mmu_cxr_mask = 0x0000003f,
1345         .mmu_sfsr_mask = 0xffffffff,
1346         .mmu_trcr_mask = 0xffffffff,
1347         .nwindows = 8,
1348         .features = CPU_DEFAULT_FEATURES,
1349     },
1350     {
1351         .name = "Ross RT620",
1352         .iu_version = 0x1f000000,
1353         .fpu_version = 1 << 17,
1354         .mmu_version = 0x1f000000,
1355         .mmu_bm = 0x00004000,
1356         .mmu_ctpr_mask = 0x007ffff0,
1357         .mmu_cxr_mask = 0x0000003f,
1358         .mmu_sfsr_mask = 0xffffffff,
1359         .mmu_trcr_mask = 0xffffffff,
1360         .nwindows = 8,
1361         .features = CPU_DEFAULT_FEATURES,
1362     },
1363     {
1364         .name = "BIT B5010",
1365         .iu_version = 0x20000000,
1366         .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
1367         .mmu_version = 0x20000000,
1368         .mmu_bm = 0x00004000,
1369         .mmu_ctpr_mask = 0x007ffff0,
1370         .mmu_cxr_mask = 0x0000003f,
1371         .mmu_sfsr_mask = 0xffffffff,
1372         .mmu_trcr_mask = 0xffffffff,
1373         .nwindows = 8,
1374         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1375         CPU_FEATURE_FSMULD,
1376     },
1377     {
1378         .name = "Matsushita MN10501",
1379         .iu_version = 0x50000000,
1380         .fpu_version = 0 << 17,
1381         .mmu_version = 0x50000000,
1382         .mmu_bm = 0x00004000,
1383         .mmu_ctpr_mask = 0x007ffff0,
1384         .mmu_cxr_mask = 0x0000003f,
1385         .mmu_sfsr_mask = 0xffffffff,
1386         .mmu_trcr_mask = 0xffffffff,
1387         .nwindows = 8,
1388         .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
1389         CPU_FEATURE_FSMULD,
1390     },
1391     {
1392         .name = "Weitek W8601",
1393         .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
1394         .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
1395         .mmu_version = 0x10 << 24,
1396         .mmu_bm = 0x00004000,
1397         .mmu_ctpr_mask = 0x007ffff0,
1398         .mmu_cxr_mask = 0x0000003f,
1399         .mmu_sfsr_mask = 0xffffffff,
1400         .mmu_trcr_mask = 0xffffffff,
1401         .nwindows = 8,
1402         .features = CPU_DEFAULT_FEATURES,
1403     },
1404     {
1405         .name = "LEON2",
1406         .iu_version = 0xf2000000,
1407         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1408         .mmu_version = 0xf2000000,
1409         .mmu_bm = 0x00004000,
1410         .mmu_ctpr_mask = 0x007ffff0,
1411         .mmu_cxr_mask = 0x0000003f,
1412         .mmu_sfsr_mask = 0xffffffff,
1413         .mmu_trcr_mask = 0xffffffff,
1414         .nwindows = 8,
1415         .features = CPU_DEFAULT_FEATURES,
1416     },
1417     {
1418         .name = "LEON3",
1419         .iu_version = 0xf3000000,
1420         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1421         .mmu_version = 0xf3000000,
1422         .mmu_bm = 0x00004000,
1423         .mmu_ctpr_mask = 0x007ffff0,
1424         .mmu_cxr_mask = 0x0000003f,
1425         .mmu_sfsr_mask = 0xffffffff,
1426         .mmu_trcr_mask = 0xffffffff,
1427         .nwindows = 8,
1428         .features = CPU_DEFAULT_FEATURES,
1429     },
1430 #endif
1431 };
1432
1433 static const char * const feature_name[] = {
1434     "float",
1435     "float128",
1436     "swap",
1437     "mul",
1438     "div",
1439     "flush",
1440     "fsqrt",
1441     "fmul",
1442     "vis1",
1443     "vis2",
1444     "fsmuld",
1445     "hypv",
1446     "cmt",
1447     "gl",
1448 };
1449
1450 static void print_features(FILE *f,
1451                            int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1452                            uint32_t features, const char *prefix)
1453 {
1454     unsigned int i;
1455
1456     for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1457         if (feature_name[i] && (features & (1 << i))) {
1458             if (prefix)
1459                 (*cpu_fprintf)(f, "%s", prefix);
1460             (*cpu_fprintf)(f, "%s ", feature_name[i]);
1461         }
1462 }
1463
1464 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
1465 {
1466     unsigned int i;
1467
1468     for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1469         if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
1470             *features |= 1 << i;
1471             return;
1472         }
1473     fprintf(stderr, "CPU feature %s not found\n", flagname);
1474 }
1475
1476 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
1477 {
1478     unsigned int i;
1479     const sparc_def_t *def = NULL;
1480     char *s = strdup(cpu_model);
1481     char *featurestr, *name = strtok(s, ",");
1482     uint32_t plus_features = 0;
1483     uint32_t minus_features = 0;
1484     long long iu_version;
1485     uint32_t fpu_version, mmu_version, nwindows;
1486
1487     for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1488         if (strcasecmp(name, sparc_defs[i].name) == 0) {
1489             def = &sparc_defs[i];
1490         }
1491     }
1492     if (!def)
1493         goto error;
1494     memcpy(cpu_def, def, sizeof(*def));
1495
1496     featurestr = strtok(NULL, ",");
1497     while (featurestr) {
1498         char *val;
1499
1500         if (featurestr[0] == '+') {
1501             add_flagname_to_bitmaps(featurestr + 1, &plus_features);
1502         } else if (featurestr[0] == '-') {
1503             add_flagname_to_bitmaps(featurestr + 1, &minus_features);
1504         } else if ((val = strchr(featurestr, '='))) {
1505             *val = 0; val++;
1506             if (!strcmp(featurestr, "iu_version")) {
1507                 char *err;
1508
1509                 iu_version = strtoll(val, &err, 0);
1510                 if (!*val || *err) {
1511                     fprintf(stderr, "bad numerical value %s\n", val);
1512                     goto error;
1513                 }
1514                 cpu_def->iu_version = iu_version;
1515 #ifdef DEBUG_FEATURES
1516                 fprintf(stderr, "iu_version %llx\n", iu_version);
1517 #endif
1518             } else if (!strcmp(featurestr, "fpu_version")) {
1519                 char *err;
1520
1521                 fpu_version = strtol(val, &err, 0);
1522                 if (!*val || *err) {
1523                     fprintf(stderr, "bad numerical value %s\n", val);
1524                     goto error;
1525                 }
1526                 cpu_def->fpu_version = fpu_version;
1527 #ifdef DEBUG_FEATURES
1528                 fprintf(stderr, "fpu_version %llx\n", fpu_version);
1529 #endif
1530             } else if (!strcmp(featurestr, "mmu_version")) {
1531                 char *err;
1532
1533                 mmu_version = strtol(val, &err, 0);
1534                 if (!*val || *err) {
1535                     fprintf(stderr, "bad numerical value %s\n", val);
1536                     goto error;
1537                 }
1538                 cpu_def->mmu_version = mmu_version;
1539 #ifdef DEBUG_FEATURES
1540                 fprintf(stderr, "mmu_version %llx\n", mmu_version);
1541 #endif
1542             } else if (!strcmp(featurestr, "nwindows")) {
1543                 char *err;
1544
1545                 nwindows = strtol(val, &err, 0);
1546                 if (!*val || *err || nwindows > MAX_NWINDOWS ||
1547                     nwindows < MIN_NWINDOWS) {
1548                     fprintf(stderr, "bad numerical value %s\n", val);
1549                     goto error;
1550                 }
1551                 cpu_def->nwindows = nwindows;
1552 #ifdef DEBUG_FEATURES
1553                 fprintf(stderr, "nwindows %d\n", nwindows);
1554 #endif
1555             } else {
1556                 fprintf(stderr, "unrecognized feature %s\n", featurestr);
1557                 goto error;
1558             }
1559         } else {
1560             fprintf(stderr, "feature string `%s' not in format "
1561                     "(+feature|-feature|feature=xyz)\n", featurestr);
1562             goto error;
1563         }
1564         featurestr = strtok(NULL, ",");
1565     }
1566     cpu_def->features |= plus_features;
1567     cpu_def->features &= ~minus_features;
1568 #ifdef DEBUG_FEATURES
1569     print_features(stderr, fprintf, cpu_def->features, NULL);
1570 #endif
1571     free(s);
1572     return 0;
1573
1574  error:
1575     free(s);
1576     return -1;
1577 }
1578
1579 void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
1580 {
1581     unsigned int i;
1582
1583     for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1584         (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
1585                        sparc_defs[i].name,
1586                        sparc_defs[i].iu_version,
1587                        sparc_defs[i].fpu_version,
1588                        sparc_defs[i].mmu_version,
1589                        sparc_defs[i].nwindows);
1590         print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
1591                        ~sparc_defs[i].features, "-");
1592         print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
1593                        sparc_defs[i].features, "+");
1594         (*cpu_fprintf)(f, "\n");
1595     }
1596     (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
1597     print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
1598     (*cpu_fprintf)(f, "\n");
1599     (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
1600     print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
1601     (*cpu_fprintf)(f, "\n");
1602     (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
1603                    "fpu_version mmu_version nwindows\n");
1604 }
1605
1606 #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
1607
1608 void cpu_dump_state(CPUState *env, FILE *f,
1609                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1610                     int flags)
1611 {
1612     int i, x;
1613
1614     cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
1615                 env->npc);
1616     cpu_fprintf(f, "General Registers:\n");
1617     for (i = 0; i < 4; i++)
1618         cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1619     cpu_fprintf(f, "\n");
1620     for (; i < 8; i++)
1621         cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1622     cpu_fprintf(f, "\nCurrent Register Window:\n");
1623     for (x = 0; x < 3; x++) {
1624         for (i = 0; i < 4; i++)
1625             cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1626                     (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1627                     env->regwptr[i + x * 8]);
1628         cpu_fprintf(f, "\n");
1629         for (; i < 8; i++)
1630             cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1631                     (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1632                     env->regwptr[i + x * 8]);
1633         cpu_fprintf(f, "\n");
1634     }
1635     cpu_fprintf(f, "\nFloating Point Registers:\n");
1636     for (i = 0; i < 32; i++) {
1637         if ((i & 3) == 0)
1638             cpu_fprintf(f, "%%f%02d:", i);
1639         cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]);
1640         if ((i & 3) == 3)
1641             cpu_fprintf(f, "\n");
1642     }
1643 #ifdef TARGET_SPARC64
1644     cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
1645                 env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
1646     cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d "
1647                 "cleanwin %d cwp %d\n",
1648                 env->cansave, env->canrestore, env->otherwin, env->wstate,
1649                 env->cleanwin, env->nwindows - 1 - env->cwp);
1650 #else
1651     cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
1652                 GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
1653                 GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1654                 env->psrs?'S':'-', env->psrps?'P':'-',
1655                 env->psret?'E':'-', env->wim);
1656 #endif
1657     cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
1658 }
1659
1660 #ifdef TARGET_SPARC64
1661 #if !defined(CONFIG_USER_ONLY)
1662 #include "qemu-common.h"
1663 #include "hw/irq.h"
1664 #include "qemu-timer.h"
1665 #endif
1666
1667 void helper_tick_set_count(void *opaque, uint64_t count)
1668 {
1669 #if !defined(CONFIG_USER_ONLY)
1670     ptimer_set_count(opaque, -count);
1671 #endif
1672 }
1673
1674 uint64_t helper_tick_get_count(void *opaque)
1675 {
1676 #if !defined(CONFIG_USER_ONLY)
1677     return -ptimer_get_count(opaque);
1678 #else
1679     return 0;
1680 #endif
1681 }
1682
1683 void helper_tick_set_limit(void *opaque, uint64_t limit)
1684 {
1685 #if !defined(CONFIG_USER_ONLY)
1686     ptimer_set_limit(opaque, -limit, 0);
1687 #endif
1688 }
1689 #endif