Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ f97572e5

History | View | Annotate | Download (52.5 kB)

1 e8af50a3 bellard
/*
2 e8af50a3 bellard
 *  sparc helpers
3 5fafdf24 ths
 *
4 83469015 bellard
 *  Copyright (c) 2003-2005 Fabrice Bellard
5 e8af50a3 bellard
 *
6 e8af50a3 bellard
 * This library is free software; you can redistribute it and/or
7 e8af50a3 bellard
 * modify it under the terms of the GNU Lesser General Public
8 e8af50a3 bellard
 * License as published by the Free Software Foundation; either
9 e8af50a3 bellard
 * version 2 of the License, or (at your option) any later version.
10 e8af50a3 bellard
 *
11 e8af50a3 bellard
 * This library is distributed in the hope that it will be useful,
12 e8af50a3 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 e8af50a3 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 e8af50a3 bellard
 * Lesser General Public License for more details.
15 e8af50a3 bellard
 *
16 e8af50a3 bellard
 * You should have received a copy of the GNU Lesser General Public
17 e8af50a3 bellard
 * License along with this library; if not, write to the Free Software
18 e8af50a3 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 e8af50a3 bellard
 */
20 ee5bbe38 bellard
#include <stdarg.h>
21 ee5bbe38 bellard
#include <stdlib.h>
22 ee5bbe38 bellard
#include <stdio.h>
23 ee5bbe38 bellard
#include <string.h>
24 ee5bbe38 bellard
#include <inttypes.h>
25 ee5bbe38 bellard
#include <signal.h>
26 ee5bbe38 bellard
#include <assert.h>
27 ee5bbe38 bellard
28 ee5bbe38 bellard
#include "cpu.h"
29 ee5bbe38 bellard
#include "exec-all.h"
30 ca10f867 aurel32
#include "qemu-common.h"
31 22548760 blueswir1
#include "helper.h"
32 e8af50a3 bellard
33 e80cfcfc bellard
//#define DEBUG_MMU
34 64a88d5d blueswir1
//#define DEBUG_FEATURES
35 f2bc7e7f blueswir1
//#define DEBUG_PCALL
36 e8af50a3 bellard
37 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
38 c48fcb47 blueswir1
39 e8af50a3 bellard
/* Sparc MMU emulation */
40 e8af50a3 bellard
41 e8af50a3 bellard
/* thread support */
42 e8af50a3 bellard
43 e8af50a3 bellard
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
44 e8af50a3 bellard
45 e8af50a3 bellard
void cpu_lock(void)
46 e8af50a3 bellard
{
47 e8af50a3 bellard
    spin_lock(&global_cpu_lock);
48 e8af50a3 bellard
}
49 e8af50a3 bellard
50 e8af50a3 bellard
void cpu_unlock(void)
51 e8af50a3 bellard
{
52 e8af50a3 bellard
    spin_unlock(&global_cpu_lock);
53 e8af50a3 bellard
}
54 e8af50a3 bellard
55 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
56 9d893301 bellard
57 22548760 blueswir1
int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
58 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
59 9d893301 bellard
{
60 878d3096 bellard
    if (rw & 2)
61 22548760 blueswir1
        env1->exception_index = TT_TFAULT;
62 878d3096 bellard
    else
63 22548760 blueswir1
        env1->exception_index = TT_DFAULT;
64 9d893301 bellard
    return 1;
65 9d893301 bellard
}
66 9d893301 bellard
67 9d893301 bellard
#else
68 e8af50a3 bellard
69 3475187d bellard
#ifndef TARGET_SPARC64
70 83469015 bellard
/*
71 83469015 bellard
 * Sparc V8 Reference MMU (SRMMU)
72 83469015 bellard
 */
73 e8af50a3 bellard
static const int access_table[8][8] = {
74 a764a566 blueswir1
    { 0, 0, 0, 0, 8, 0, 12, 12 },
75 a764a566 blueswir1
    { 0, 0, 0, 0, 8, 0, 0, 0 },
76 a764a566 blueswir1
    { 8, 8, 0, 0, 0, 8, 12, 12 },
77 a764a566 blueswir1
    { 8, 8, 0, 0, 0, 8, 0, 0 },
78 a764a566 blueswir1
    { 8, 0, 8, 0, 8, 8, 12, 12 },
79 a764a566 blueswir1
    { 8, 0, 8, 0, 8, 0, 8, 0 },
80 a764a566 blueswir1
    { 8, 8, 8, 0, 8, 8, 12, 12 },
81 a764a566 blueswir1
    { 8, 8, 8, 0, 8, 8, 8, 0 }
82 e8af50a3 bellard
};
83 e8af50a3 bellard
84 227671c9 bellard
static const int perm_table[2][8] = {
85 227671c9 bellard
    {
86 227671c9 bellard
        PAGE_READ,
87 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
88 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
89 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
90 227671c9 bellard
        PAGE_EXEC,
91 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
92 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
93 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC
94 227671c9 bellard
    },
95 227671c9 bellard
    {
96 227671c9 bellard
        PAGE_READ,
97 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
98 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
99 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
100 227671c9 bellard
        PAGE_EXEC,
101 227671c9 bellard
        PAGE_READ,
102 227671c9 bellard
        0,
103 227671c9 bellard
        0,
104 227671c9 bellard
    }
105 e8af50a3 bellard
};
106 e8af50a3 bellard
107 c48fcb47 blueswir1
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
108 c48fcb47 blueswir1
                                int *prot, int *access_index,
109 c48fcb47 blueswir1
                                target_ulong address, int rw, int mmu_idx)
110 e8af50a3 bellard
{
111 e80cfcfc bellard
    int access_perms = 0;
112 e80cfcfc bellard
    target_phys_addr_t pde_ptr;
113 af7bf89b bellard
    uint32_t pde;
114 af7bf89b bellard
    target_ulong virt_addr;
115 6ebbf390 j_mayer
    int error_code = 0, is_dirty, is_user;
116 e80cfcfc bellard
    unsigned long page_offset;
117 e8af50a3 bellard
118 6ebbf390 j_mayer
    is_user = mmu_idx == MMU_USER_IDX;
119 e8af50a3 bellard
    virt_addr = address & TARGET_PAGE_MASK;
120 40ce0a9a blueswir1
121 e8af50a3 bellard
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
122 40ce0a9a blueswir1
        // Boot mode: instruction fetches are taken from PROM
123 5578ceab blueswir1
        if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
124 58a770f3 blueswir1
            *physical = env->prom_addr | (address & 0x7ffffULL);
125 40ce0a9a blueswir1
            *prot = PAGE_READ | PAGE_EXEC;
126 40ce0a9a blueswir1
            return 0;
127 40ce0a9a blueswir1
        }
128 0f8a249a blueswir1
        *physical = address;
129 227671c9 bellard
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
130 e80cfcfc bellard
        return 0;
131 e8af50a3 bellard
    }
132 e8af50a3 bellard
133 7483750d bellard
    *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
134 5dcb6b91 blueswir1
    *physical = 0xffffffffffff0000ULL;
135 7483750d bellard
136 e8af50a3 bellard
    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
137 e8af50a3 bellard
    /* Context base + context number */
138 3deaeab7 blueswir1
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
139 49be8030 bellard
    pde = ldl_phys(pde_ptr);
140 e8af50a3 bellard
141 e8af50a3 bellard
    /* Ctx pde */
142 e8af50a3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
143 e80cfcfc bellard
    default:
144 e8af50a3 bellard
    case 0: /* Invalid */
145 0f8a249a blueswir1
        return 1 << 2;
146 e80cfcfc bellard
    case 2: /* L0 PTE, maybe should not happen? */
147 e8af50a3 bellard
    case 3: /* Reserved */
148 7483750d bellard
        return 4 << 2;
149 e80cfcfc bellard
    case 1: /* L0 PDE */
150 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
151 49be8030 bellard
        pde = ldl_phys(pde_ptr);
152 e8af50a3 bellard
153 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
154 0f8a249a blueswir1
        default:
155 0f8a249a blueswir1
        case 0: /* Invalid */
156 0f8a249a blueswir1
            return (1 << 8) | (1 << 2);
157 0f8a249a blueswir1
        case 3: /* Reserved */
158 0f8a249a blueswir1
            return (1 << 8) | (4 << 2);
159 0f8a249a blueswir1
        case 1: /* L1 PDE */
160 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
161 49be8030 bellard
            pde = ldl_phys(pde_ptr);
162 e8af50a3 bellard
163 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
164 0f8a249a blueswir1
            default:
165 0f8a249a blueswir1
            case 0: /* Invalid */
166 0f8a249a blueswir1
                return (2 << 8) | (1 << 2);
167 0f8a249a blueswir1
            case 3: /* Reserved */
168 0f8a249a blueswir1
                return (2 << 8) | (4 << 2);
169 0f8a249a blueswir1
            case 1: /* L2 PDE */
170 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
171 49be8030 bellard
                pde = ldl_phys(pde_ptr);
172 e8af50a3 bellard
173 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
174 0f8a249a blueswir1
                default:
175 0f8a249a blueswir1
                case 0: /* Invalid */
176 0f8a249a blueswir1
                    return (3 << 8) | (1 << 2);
177 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
178 0f8a249a blueswir1
                case 3: /* Reserved */
179 0f8a249a blueswir1
                    return (3 << 8) | (4 << 2);
180 0f8a249a blueswir1
                case 2: /* L3 PTE */
181 0f8a249a blueswir1
                    virt_addr = address & TARGET_PAGE_MASK;
182 77f193da blueswir1
                    page_offset = (address & TARGET_PAGE_MASK) &
183 77f193da blueswir1
                        (TARGET_PAGE_SIZE - 1);
184 0f8a249a blueswir1
                }
185 0f8a249a blueswir1
                break;
186 0f8a249a blueswir1
            case 2: /* L2 PTE */
187 0f8a249a blueswir1
                virt_addr = address & ~0x3ffff;
188 0f8a249a blueswir1
                page_offset = address & 0x3ffff;
189 0f8a249a blueswir1
            }
190 0f8a249a blueswir1
            break;
191 0f8a249a blueswir1
        case 2: /* L1 PTE */
192 0f8a249a blueswir1
            virt_addr = address & ~0xffffff;
193 0f8a249a blueswir1
            page_offset = address & 0xffffff;
194 0f8a249a blueswir1
        }
195 e8af50a3 bellard
    }
196 e8af50a3 bellard
197 e8af50a3 bellard
    /* update page modified and dirty bits */
198 b769d8fe bellard
    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
199 e8af50a3 bellard
    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
200 0f8a249a blueswir1
        pde |= PG_ACCESSED_MASK;
201 0f8a249a blueswir1
        if (is_dirty)
202 0f8a249a blueswir1
            pde |= PG_MODIFIED_MASK;
203 49be8030 bellard
        stl_phys_notdirty(pde_ptr, pde);
204 e8af50a3 bellard
    }
205 e8af50a3 bellard
    /* check access */
206 e8af50a3 bellard
    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
207 e80cfcfc bellard
    error_code = access_table[*access_index][access_perms];
208 d8e3326c bellard
    if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
209 0f8a249a blueswir1
        return error_code;
210 e8af50a3 bellard
211 e8af50a3 bellard
    /* the page can be put in the TLB */
212 227671c9 bellard
    *prot = perm_table[is_user][access_perms];
213 227671c9 bellard
    if (!(pde & PG_MODIFIED_MASK)) {
214 e8af50a3 bellard
        /* only set write access if already dirty... otherwise wait
215 e8af50a3 bellard
           for dirty access */
216 227671c9 bellard
        *prot &= ~PAGE_WRITE;
217 e8af50a3 bellard
    }
218 e8af50a3 bellard
219 e8af50a3 bellard
    /* Even if large ptes, we map only one 4KB page in the cache to
220 e8af50a3 bellard
       avoid filling it too fast */
221 5dcb6b91 blueswir1
    *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
222 6f7e9aec bellard
    return error_code;
223 e80cfcfc bellard
}
224 e80cfcfc bellard
225 e80cfcfc bellard
/* Perform address translation */
226 af7bf89b bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
227 6ebbf390 j_mayer
                              int mmu_idx, int is_softmmu)
228 e80cfcfc bellard
{
229 af7bf89b bellard
    target_phys_addr_t paddr;
230 5dcb6b91 blueswir1
    target_ulong vaddr;
231 e80cfcfc bellard
    int error_code = 0, prot, ret = 0, access_index;
232 e8af50a3 bellard
233 77f193da blueswir1
    error_code = get_physical_address(env, &paddr, &prot, &access_index,
234 77f193da blueswir1
                                      address, rw, mmu_idx);
235 e80cfcfc bellard
    if (error_code == 0) {
236 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
237 0f8a249a blueswir1
        paddr &= TARGET_PAGE_MASK;
238 9e61bde5 bellard
#ifdef DEBUG_MMU
239 0f8a249a blueswir1
        printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
240 5dcb6b91 blueswir1
               TARGET_FMT_lx "\n", address, paddr, vaddr);
241 9e61bde5 bellard
#endif
242 6ebbf390 j_mayer
        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
243 0f8a249a blueswir1
        return ret;
244 e80cfcfc bellard
    }
245 e8af50a3 bellard
246 e8af50a3 bellard
    if (env->mmuregs[3]) /* Fault status register */
247 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
248 7483750d bellard
    env->mmuregs[3] |= (access_index << 5) | error_code | 2;
249 e8af50a3 bellard
    env->mmuregs[4] = address; /* Fault address register */
250 e8af50a3 bellard
251 878d3096 bellard
    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
252 6f7e9aec bellard
        // No fault mode: if a mapping is available, just override
253 6f7e9aec bellard
        // permissions. If no mapping is available, redirect accesses to
254 6f7e9aec bellard
        // neverland. Fake/overridden mappings will be flushed when
255 6f7e9aec bellard
        // switching to normal mode.
256 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
257 227671c9 bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
258 6ebbf390 j_mayer
        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
259 0f8a249a blueswir1
        return ret;
260 7483750d bellard
    } else {
261 7483750d bellard
        if (rw & 2)
262 7483750d bellard
            env->exception_index = TT_TFAULT;
263 7483750d bellard
        else
264 7483750d bellard
            env->exception_index = TT_DFAULT;
265 7483750d bellard
        return 1;
266 878d3096 bellard
    }
267 e8af50a3 bellard
}
268 24741ef3 bellard
269 24741ef3 bellard
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
270 24741ef3 bellard
{
271 24741ef3 bellard
    target_phys_addr_t pde_ptr;
272 24741ef3 bellard
    uint32_t pde;
273 24741ef3 bellard
274 24741ef3 bellard
    /* Context base + context number */
275 5dcb6b91 blueswir1
    pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
276 5dcb6b91 blueswir1
        (env->mmuregs[2] << 2);
277 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
278 24741ef3 bellard
279 24741ef3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
280 24741ef3 bellard
    default:
281 24741ef3 bellard
    case 0: /* Invalid */
282 24741ef3 bellard
    case 2: /* PTE, maybe should not happen? */
283 24741ef3 bellard
    case 3: /* Reserved */
284 0f8a249a blueswir1
        return 0;
285 24741ef3 bellard
    case 1: /* L1 PDE */
286 0f8a249a blueswir1
        if (mmulev == 3)
287 0f8a249a blueswir1
            return pde;
288 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
289 24741ef3 bellard
        pde = ldl_phys(pde_ptr);
290 24741ef3 bellard
291 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
292 0f8a249a blueswir1
        default:
293 0f8a249a blueswir1
        case 0: /* Invalid */
294 0f8a249a blueswir1
        case 3: /* Reserved */
295 0f8a249a blueswir1
            return 0;
296 0f8a249a blueswir1
        case 2: /* L1 PTE */
297 0f8a249a blueswir1
            return pde;
298 0f8a249a blueswir1
        case 1: /* L2 PDE */
299 0f8a249a blueswir1
            if (mmulev == 2)
300 0f8a249a blueswir1
                return pde;
301 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
302 24741ef3 bellard
            pde = ldl_phys(pde_ptr);
303 24741ef3 bellard
304 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
305 0f8a249a blueswir1
            default:
306 0f8a249a blueswir1
            case 0: /* Invalid */
307 0f8a249a blueswir1
            case 3: /* Reserved */
308 0f8a249a blueswir1
                return 0;
309 0f8a249a blueswir1
            case 2: /* L2 PTE */
310 0f8a249a blueswir1
                return pde;
311 0f8a249a blueswir1
            case 1: /* L3 PDE */
312 0f8a249a blueswir1
                if (mmulev == 1)
313 0f8a249a blueswir1
                    return pde;
314 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
315 24741ef3 bellard
                pde = ldl_phys(pde_ptr);
316 24741ef3 bellard
317 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
318 0f8a249a blueswir1
                default:
319 0f8a249a blueswir1
                case 0: /* Invalid */
320 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
321 0f8a249a blueswir1
                case 3: /* Reserved */
322 0f8a249a blueswir1
                    return 0;
323 0f8a249a blueswir1
                case 2: /* L3 PTE */
324 0f8a249a blueswir1
                    return pde;
325 0f8a249a blueswir1
                }
326 0f8a249a blueswir1
            }
327 0f8a249a blueswir1
        }
328 24741ef3 bellard
    }
329 24741ef3 bellard
    return 0;
330 24741ef3 bellard
}
331 24741ef3 bellard
332 24741ef3 bellard
#ifdef DEBUG_MMU
333 24741ef3 bellard
void dump_mmu(CPUState *env)
334 24741ef3 bellard
{
335 5dcb6b91 blueswir1
    target_ulong va, va1, va2;
336 5dcb6b91 blueswir1
    unsigned int n, m, o;
337 5dcb6b91 blueswir1
    target_phys_addr_t pde_ptr, pa;
338 24741ef3 bellard
    uint32_t pde;
339 24741ef3 bellard
340 24741ef3 bellard
    printf("MMU dump:\n");
341 24741ef3 bellard
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
342 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
343 5dcb6b91 blueswir1
    printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
344 5dcb6b91 blueswir1
           (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
345 24741ef3 bellard
    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
346 0f8a249a blueswir1
        pde = mmu_probe(env, va, 2);
347 0f8a249a blueswir1
        if (pde) {
348 0f8a249a blueswir1
            pa = cpu_get_phys_page_debug(env, va);
349 0f8a249a blueswir1
            printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
350 5dcb6b91 blueswir1
                   " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
351 0f8a249a blueswir1
            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
352 0f8a249a blueswir1
                pde = mmu_probe(env, va1, 1);
353 0f8a249a blueswir1
                if (pde) {
354 0f8a249a blueswir1
                    pa = cpu_get_phys_page_debug(env, va1);
355 0f8a249a blueswir1
                    printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
356 5dcb6b91 blueswir1
                           " PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
357 0f8a249a blueswir1
                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
358 0f8a249a blueswir1
                        pde = mmu_probe(env, va2, 0);
359 0f8a249a blueswir1
                        if (pde) {
360 0f8a249a blueswir1
                            pa = cpu_get_phys_page_debug(env, va2);
361 0f8a249a blueswir1
                            printf("  VA: " TARGET_FMT_lx ", PA: "
362 5dcb6b91 blueswir1
                                   TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
363 5dcb6b91 blueswir1
                                   va2, pa, pde);
364 0f8a249a blueswir1
                        }
365 0f8a249a blueswir1
                    }
366 0f8a249a blueswir1
                }
367 0f8a249a blueswir1
            }
368 0f8a249a blueswir1
        }
369 24741ef3 bellard
    }
370 24741ef3 bellard
    printf("MMU dump ends\n");
371 24741ef3 bellard
}
372 24741ef3 bellard
#endif /* DEBUG_MMU */
373 24741ef3 bellard
374 24741ef3 bellard
#else /* !TARGET_SPARC64 */
375 83469015 bellard
/*
376 83469015 bellard
 * UltraSparc IIi I/DMMUs
377 83469015 bellard
 */
378 77f193da blueswir1
static int get_physical_address_data(CPUState *env,
379 77f193da blueswir1
                                     target_phys_addr_t *physical, int *prot,
380 22548760 blueswir1
                                     target_ulong address, int rw, int is_user)
381 3475187d bellard
{
382 3475187d bellard
    target_ulong mask;
383 3475187d bellard
    unsigned int i;
384 3475187d bellard
385 3475187d bellard
    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
386 0f8a249a blueswir1
        *physical = address;
387 0f8a249a blueswir1
        *prot = PAGE_READ | PAGE_WRITE;
388 3475187d bellard
        return 0;
389 3475187d bellard
    }
390 3475187d bellard
391 3475187d bellard
    for (i = 0; i < 64; i++) {
392 0f8a249a blueswir1
        switch ((env->dtlb_tte[i] >> 61) & 3) {
393 0f8a249a blueswir1
        default:
394 0f8a249a blueswir1
        case 0x0: // 8k
395 0f8a249a blueswir1
            mask = 0xffffffffffffe000ULL;
396 0f8a249a blueswir1
            break;
397 0f8a249a blueswir1
        case 0x1: // 64k
398 0f8a249a blueswir1
            mask = 0xffffffffffff0000ULL;
399 0f8a249a blueswir1
            break;
400 0f8a249a blueswir1
        case 0x2: // 512k
401 0f8a249a blueswir1
            mask = 0xfffffffffff80000ULL;
402 0f8a249a blueswir1
            break;
403 0f8a249a blueswir1
        case 0x3: // 4M
404 0f8a249a blueswir1
            mask = 0xffffffffffc00000ULL;
405 0f8a249a blueswir1
            break;
406 0f8a249a blueswir1
        }
407 0f8a249a blueswir1
        // ctx match, vaddr match?
408 0f8a249a blueswir1
        if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
409 0f8a249a blueswir1
            (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
410 0f8a249a blueswir1
            // valid, access ok?
411 0f8a249a blueswir1
            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
412 0f8a249a blueswir1
                ((env->dtlb_tte[i] & 0x4) && is_user) ||
413 0f8a249a blueswir1
                (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
414 0f8a249a blueswir1
                if (env->dmmuregs[3]) /* Fault status register */
415 77f193da blueswir1
                    env->dmmuregs[3] = 2; /* overflow (not read before
416 77f193da blueswir1
                                             another fault) */
417 0f8a249a blueswir1
                env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
418 0f8a249a blueswir1
                env->dmmuregs[4] = address; /* Fault address register */
419 0f8a249a blueswir1
                env->exception_index = TT_DFAULT;
420 83469015 bellard
#ifdef DEBUG_MMU
421 0f8a249a blueswir1
                printf("DFAULT at 0x%" PRIx64 "\n", address);
422 83469015 bellard
#endif
423 0f8a249a blueswir1
                return 1;
424 0f8a249a blueswir1
            }
425 77f193da blueswir1
            *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) +
426 77f193da blueswir1
                (address & ~mask & 0x1fffffff000ULL);
427 0f8a249a blueswir1
            *prot = PAGE_READ;
428 0f8a249a blueswir1
            if (env->dtlb_tte[i] & 0x2)
429 0f8a249a blueswir1
                *prot |= PAGE_WRITE;
430 0f8a249a blueswir1
            return 0;
431 0f8a249a blueswir1
        }
432 3475187d bellard
    }
433 83469015 bellard
#ifdef DEBUG_MMU
434 26a76461 bellard
    printf("DMISS at 0x%" PRIx64 "\n", address);
435 83469015 bellard
#endif
436 f617a9a6 blueswir1
    env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
437 83469015 bellard
    env->exception_index = TT_DMISS;
438 3475187d bellard
    return 1;
439 3475187d bellard
}
440 3475187d bellard
441 77f193da blueswir1
static int get_physical_address_code(CPUState *env,
442 77f193da blueswir1
                                     target_phys_addr_t *physical, int *prot,
443 22548760 blueswir1
                                     target_ulong address, int is_user)
444 3475187d bellard
{
445 3475187d bellard
    target_ulong mask;
446 3475187d bellard
    unsigned int i;
447 3475187d bellard
448 3475187d bellard
    if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
449 0f8a249a blueswir1
        *physical = address;
450 0f8a249a blueswir1
        *prot = PAGE_EXEC;
451 3475187d bellard
        return 0;
452 3475187d bellard
    }
453 83469015 bellard
454 3475187d bellard
    for (i = 0; i < 64; i++) {
455 0f8a249a blueswir1
        switch ((env->itlb_tte[i] >> 61) & 3) {
456 0f8a249a blueswir1
        default:
457 0f8a249a blueswir1
        case 0x0: // 8k
458 0f8a249a blueswir1
            mask = 0xffffffffffffe000ULL;
459 0f8a249a blueswir1
            break;
460 0f8a249a blueswir1
        case 0x1: // 64k
461 0f8a249a blueswir1
            mask = 0xffffffffffff0000ULL;
462 0f8a249a blueswir1
            break;
463 0f8a249a blueswir1
        case 0x2: // 512k
464 0f8a249a blueswir1
            mask = 0xfffffffffff80000ULL;
465 0f8a249a blueswir1
            break;
466 0f8a249a blueswir1
        case 0x3: // 4M
467 0f8a249a blueswir1
            mask = 0xffffffffffc00000ULL;
468 0f8a249a blueswir1
                break;
469 0f8a249a blueswir1
        }
470 0f8a249a blueswir1
        // ctx match, vaddr match?
471 0f8a249a blueswir1
        if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
472 0f8a249a blueswir1
            (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
473 0f8a249a blueswir1
            // valid, access ok?
474 0f8a249a blueswir1
            if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
475 0f8a249a blueswir1
                ((env->itlb_tte[i] & 0x4) && is_user)) {
476 0f8a249a blueswir1
                if (env->immuregs[3]) /* Fault status register */
477 77f193da blueswir1
                    env->immuregs[3] = 2; /* overflow (not read before
478 77f193da blueswir1
                                             another fault) */
479 0f8a249a blueswir1
                env->immuregs[3] |= (is_user << 3) | 1;
480 0f8a249a blueswir1
                env->exception_index = TT_TFAULT;
481 83469015 bellard
#ifdef DEBUG_MMU
482 0f8a249a blueswir1
                printf("TFAULT at 0x%" PRIx64 "\n", address);
483 83469015 bellard
#endif
484 0f8a249a blueswir1
                return 1;
485 0f8a249a blueswir1
            }
486 77f193da blueswir1
            *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) +
487 77f193da blueswir1
                (address & ~mask & 0x1fffffff000ULL);
488 0f8a249a blueswir1
            *prot = PAGE_EXEC;
489 0f8a249a blueswir1
            return 0;
490 0f8a249a blueswir1
        }
491 3475187d bellard
    }
492 83469015 bellard
#ifdef DEBUG_MMU
493 26a76461 bellard
    printf("TMISS at 0x%" PRIx64 "\n", address);
494 83469015 bellard
#endif
495 f617a9a6 blueswir1
    env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
496 83469015 bellard
    env->exception_index = TT_TMISS;
497 3475187d bellard
    return 1;
498 3475187d bellard
}
499 3475187d bellard
500 c48fcb47 blueswir1
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
501 c48fcb47 blueswir1
                                int *prot, int *access_index,
502 c48fcb47 blueswir1
                                target_ulong address, int rw, int mmu_idx)
503 3475187d bellard
{
504 6ebbf390 j_mayer
    int is_user = mmu_idx == MMU_USER_IDX;
505 6ebbf390 j_mayer
506 3475187d bellard
    if (rw == 2)
507 22548760 blueswir1
        return get_physical_address_code(env, physical, prot, address,
508 22548760 blueswir1
                                         is_user);
509 3475187d bellard
    else
510 22548760 blueswir1
        return get_physical_address_data(env, physical, prot, address, rw,
511 22548760 blueswir1
                                         is_user);
512 3475187d bellard
}
513 3475187d bellard
514 3475187d bellard
/* Perform address translation */
515 3475187d bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
516 6ebbf390 j_mayer
                              int mmu_idx, int is_softmmu)
517 3475187d bellard
{
518 83469015 bellard
    target_ulong virt_addr, vaddr;
519 3475187d bellard
    target_phys_addr_t paddr;
520 3475187d bellard
    int error_code = 0, prot, ret = 0, access_index;
521 3475187d bellard
522 77f193da blueswir1
    error_code = get_physical_address(env, &paddr, &prot, &access_index,
523 77f193da blueswir1
                                      address, rw, mmu_idx);
524 3475187d bellard
    if (error_code == 0) {
525 0f8a249a blueswir1
        virt_addr = address & TARGET_PAGE_MASK;
526 77f193da blueswir1
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
527 77f193da blueswir1
                             (TARGET_PAGE_SIZE - 1));
528 83469015 bellard
#ifdef DEBUG_MMU
529 77f193da blueswir1
        printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
530 77f193da blueswir1
               "\n", address, paddr, vaddr);
531 83469015 bellard
#endif
532 6ebbf390 j_mayer
        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
533 0f8a249a blueswir1
        return ret;
534 3475187d bellard
    }
535 3475187d bellard
    // XXX
536 3475187d bellard
    return 1;
537 3475187d bellard
}
538 3475187d bellard
539 83469015 bellard
#ifdef DEBUG_MMU
540 83469015 bellard
void dump_mmu(CPUState *env)
541 83469015 bellard
{
542 83469015 bellard
    unsigned int i;
543 83469015 bellard
    const char *mask;
544 83469015 bellard
545 77f193da blueswir1
    printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n",
546 77f193da blueswir1
           env->dmmuregs[1], env->dmmuregs[2]);
547 83469015 bellard
    if ((env->lsu & DMMU_E) == 0) {
548 0f8a249a blueswir1
        printf("DMMU disabled\n");
549 83469015 bellard
    } else {
550 0f8a249a blueswir1
        printf("DMMU dump:\n");
551 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
552 0f8a249a blueswir1
            switch ((env->dtlb_tte[i] >> 61) & 3) {
553 0f8a249a blueswir1
            default:
554 0f8a249a blueswir1
            case 0x0:
555 0f8a249a blueswir1
                mask = "  8k";
556 0f8a249a blueswir1
                break;
557 0f8a249a blueswir1
            case 0x1:
558 0f8a249a blueswir1
                mask = " 64k";
559 0f8a249a blueswir1
                break;
560 0f8a249a blueswir1
            case 0x2:
561 0f8a249a blueswir1
                mask = "512k";
562 0f8a249a blueswir1
                break;
563 0f8a249a blueswir1
            case 0x3:
564 0f8a249a blueswir1
                mask = "  4M";
565 0f8a249a blueswir1
                break;
566 0f8a249a blueswir1
            }
567 0f8a249a blueswir1
            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
568 77f193da blueswir1
                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
569 77f193da blueswir1
                       ", %s, %s, %s, %s, ctx %" PRId64 "\n",
570 0f8a249a blueswir1
                       env->dtlb_tag[i] & ~0x1fffULL,
571 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x1ffffffe000ULL,
572 0f8a249a blueswir1
                       mask,
573 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x4? "priv": "user",
574 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x2? "RW": "RO",
575 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x40? "locked": "unlocked",
576 0f8a249a blueswir1
                       env->dtlb_tag[i] & 0x1fffULL);
577 0f8a249a blueswir1
            }
578 0f8a249a blueswir1
        }
579 83469015 bellard
    }
580 83469015 bellard
    if ((env->lsu & IMMU_E) == 0) {
581 0f8a249a blueswir1
        printf("IMMU disabled\n");
582 83469015 bellard
    } else {
583 0f8a249a blueswir1
        printf("IMMU dump:\n");
584 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
585 0f8a249a blueswir1
            switch ((env->itlb_tte[i] >> 61) & 3) {
586 0f8a249a blueswir1
            default:
587 0f8a249a blueswir1
            case 0x0:
588 0f8a249a blueswir1
                mask = "  8k";
589 0f8a249a blueswir1
                break;
590 0f8a249a blueswir1
            case 0x1:
591 0f8a249a blueswir1
                mask = " 64k";
592 0f8a249a blueswir1
                break;
593 0f8a249a blueswir1
            case 0x2:
594 0f8a249a blueswir1
                mask = "512k";
595 0f8a249a blueswir1
                break;
596 0f8a249a blueswir1
            case 0x3:
597 0f8a249a blueswir1
                mask = "  4M";
598 0f8a249a blueswir1
                break;
599 0f8a249a blueswir1
            }
600 0f8a249a blueswir1
            if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
601 77f193da blueswir1
                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx
602 77f193da blueswir1
                       ", %s, %s, %s, ctx %" PRId64 "\n",
603 0f8a249a blueswir1
                       env->itlb_tag[i] & ~0x1fffULL,
604 0f8a249a blueswir1
                       env->itlb_tte[i] & 0x1ffffffe000ULL,
605 0f8a249a blueswir1
                       mask,
606 0f8a249a blueswir1
                       env->itlb_tte[i] & 0x4? "priv": "user",
607 0f8a249a blueswir1
                       env->itlb_tte[i] & 0x40? "locked": "unlocked",
608 0f8a249a blueswir1
                       env->itlb_tag[i] & 0x1fffULL);
609 0f8a249a blueswir1
            }
610 0f8a249a blueswir1
        }
611 83469015 bellard
    }
612 83469015 bellard
}
613 24741ef3 bellard
#endif /* DEBUG_MMU */
614 24741ef3 bellard
615 24741ef3 bellard
#endif /* TARGET_SPARC64 */
616 24741ef3 bellard
#endif /* !CONFIG_USER_ONLY */
617 24741ef3 bellard
618 c48fcb47 blueswir1
619 c48fcb47 blueswir1
#if defined(CONFIG_USER_ONLY)
620 c48fcb47 blueswir1
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
621 c48fcb47 blueswir1
{
622 c48fcb47 blueswir1
    return addr;
623 c48fcb47 blueswir1
}
624 c48fcb47 blueswir1
625 c48fcb47 blueswir1
#else
626 c48fcb47 blueswir1
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
627 c48fcb47 blueswir1
{
628 c48fcb47 blueswir1
    target_phys_addr_t phys_addr;
629 c48fcb47 blueswir1
    int prot, access_index;
630 c48fcb47 blueswir1
631 c48fcb47 blueswir1
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
632 c48fcb47 blueswir1
                             MMU_KERNEL_IDX) != 0)
633 c48fcb47 blueswir1
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
634 c48fcb47 blueswir1
                                 0, MMU_KERNEL_IDX) != 0)
635 c48fcb47 blueswir1
            return -1;
636 c48fcb47 blueswir1
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
637 c48fcb47 blueswir1
        return -1;
638 c48fcb47 blueswir1
    return phys_addr;
639 c48fcb47 blueswir1
}
640 c48fcb47 blueswir1
#endif
641 c48fcb47 blueswir1
642 f2bc7e7f blueswir1
#ifdef TARGET_SPARC64
643 f2bc7e7f blueswir1
#ifdef DEBUG_PCALL
644 e19e4efe blueswir1
static const char * const excp_names[0x80] = {
645 f2bc7e7f blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
646 f2bc7e7f blueswir1
    [TT_TMISS] = "Instruction Access MMU Miss",
647 f2bc7e7f blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
648 f2bc7e7f blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
649 f2bc7e7f blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
650 f2bc7e7f blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
651 f2bc7e7f blueswir1
    [TT_FP_EXCP] = "FPU Exception",
652 f2bc7e7f blueswir1
    [TT_TOVF] = "Tag Overflow",
653 f2bc7e7f blueswir1
    [TT_CLRWIN] = "Clean Windows",
654 f2bc7e7f blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
655 f2bc7e7f blueswir1
    [TT_DFAULT] = "Data Access Fault",
656 f2bc7e7f blueswir1
    [TT_DMISS] = "Data Access MMU Miss",
657 f2bc7e7f blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
658 f2bc7e7f blueswir1
    [TT_DPROT] = "Data Protection Error",
659 f2bc7e7f blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
660 f2bc7e7f blueswir1
    [TT_PRIV_ACT] = "Privileged Action",
661 f2bc7e7f blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
662 f2bc7e7f blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
663 f2bc7e7f blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
664 f2bc7e7f blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
665 f2bc7e7f blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
666 f2bc7e7f blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
667 f2bc7e7f blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
668 f2bc7e7f blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
669 f2bc7e7f blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
670 f2bc7e7f blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
671 f2bc7e7f blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
672 f2bc7e7f blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
673 f2bc7e7f blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
674 f2bc7e7f blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
675 f2bc7e7f blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
676 f2bc7e7f blueswir1
};
677 f2bc7e7f blueswir1
#endif
678 f2bc7e7f blueswir1
679 f2bc7e7f blueswir1
void do_interrupt(CPUState *env)
680 f2bc7e7f blueswir1
{
681 f2bc7e7f blueswir1
    int intno = env->exception_index;
682 f2bc7e7f blueswir1
683 f2bc7e7f blueswir1
#ifdef DEBUG_PCALL
684 f2bc7e7f blueswir1
    if (loglevel & CPU_LOG_INT) {
685 f2bc7e7f blueswir1
        static int count;
686 f2bc7e7f blueswir1
        const char *name;
687 f2bc7e7f blueswir1
688 e19e4efe blueswir1
        if (intno < 0 || intno >= 0x180)
689 f2bc7e7f blueswir1
            name = "Unknown";
690 f2bc7e7f blueswir1
        else if (intno >= 0x100)
691 f2bc7e7f blueswir1
            name = "Trap Instruction";
692 f2bc7e7f blueswir1
        else if (intno >= 0xc0)
693 f2bc7e7f blueswir1
            name = "Window Fill";
694 f2bc7e7f blueswir1
        else if (intno >= 0x80)
695 f2bc7e7f blueswir1
            name = "Window Spill";
696 f2bc7e7f blueswir1
        else {
697 f2bc7e7f blueswir1
            name = excp_names[intno];
698 f2bc7e7f blueswir1
            if (!name)
699 f2bc7e7f blueswir1
                name = "Unknown";
700 f2bc7e7f blueswir1
        }
701 f2bc7e7f blueswir1
702 f2bc7e7f blueswir1
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
703 f2bc7e7f blueswir1
                " SP=%016" PRIx64 "\n",
704 f2bc7e7f blueswir1
                count, name, intno,
705 f2bc7e7f blueswir1
                env->pc,
706 f2bc7e7f blueswir1
                env->npc, env->regwptr[6]);
707 f2bc7e7f blueswir1
        cpu_dump_state(env, logfile, fprintf, 0);
708 f2bc7e7f blueswir1
#if 0
709 f2bc7e7f blueswir1
        {
710 f2bc7e7f blueswir1
            int i;
711 f2bc7e7f blueswir1
            uint8_t *ptr;
712 f2bc7e7f blueswir1

713 f2bc7e7f blueswir1
            fprintf(logfile, "       code=");
714 f2bc7e7f blueswir1
            ptr = (uint8_t *)env->pc;
715 f2bc7e7f blueswir1
            for(i = 0; i < 16; i++) {
716 f2bc7e7f blueswir1
                fprintf(logfile, " %02x", ldub(ptr + i));
717 f2bc7e7f blueswir1
            }
718 f2bc7e7f blueswir1
            fprintf(logfile, "\n");
719 f2bc7e7f blueswir1
        }
720 f2bc7e7f blueswir1
#endif
721 f2bc7e7f blueswir1
        count++;
722 f2bc7e7f blueswir1
    }
723 f2bc7e7f blueswir1
#endif
724 f2bc7e7f blueswir1
#if !defined(CONFIG_USER_ONLY)
725 c19148bd blueswir1
    if (env->tl >= env->maxtl) {
726 c19148bd blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
727 c19148bd blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
728 f2bc7e7f blueswir1
        return;
729 f2bc7e7f blueswir1
    }
730 f2bc7e7f blueswir1
#endif
731 c19148bd blueswir1
    if (env->tl < env->maxtl - 1) {
732 e6bf7d70 blueswir1
        env->tl++;
733 e6bf7d70 blueswir1
    } else {
734 e6bf7d70 blueswir1
        env->pstate |= PS_RED;
735 c19148bd blueswir1
        if (env->tl < env->maxtl)
736 e6bf7d70 blueswir1
            env->tl++;
737 e6bf7d70 blueswir1
    }
738 c19148bd blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
739 f2bc7e7f blueswir1
    env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
740 f2bc7e7f blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
741 f2bc7e7f blueswir1
        GET_CWP64(env);
742 f2bc7e7f blueswir1
    env->tsptr->tpc = env->pc;
743 f2bc7e7f blueswir1
    env->tsptr->tnpc = env->npc;
744 f2bc7e7f blueswir1
    env->tsptr->tt = intno;
745 5578ceab blueswir1
    if (!(env->def->features & CPU_FEATURE_GL)) {
746 74b9decc blueswir1
        switch (intno) {
747 74b9decc blueswir1
        case TT_IVEC:
748 74b9decc blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_IG);
749 74b9decc blueswir1
            break;
750 74b9decc blueswir1
        case TT_TFAULT:
751 74b9decc blueswir1
        case TT_TMISS:
752 74b9decc blueswir1
        case TT_DFAULT:
753 74b9decc blueswir1
        case TT_DMISS:
754 74b9decc blueswir1
        case TT_DPROT:
755 74b9decc blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_MG);
756 74b9decc blueswir1
            break;
757 74b9decc blueswir1
        default:
758 74b9decc blueswir1
            change_pstate(PS_PEF | PS_PRIV | PS_AG);
759 74b9decc blueswir1
            break;
760 74b9decc blueswir1
        }
761 74b9decc blueswir1
    }
762 f2bc7e7f blueswir1
    if (intno == TT_CLRWIN)
763 1a14026e blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
764 f2bc7e7f blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
765 1a14026e blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
766 f2bc7e7f blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
767 1a14026e blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
768 f2bc7e7f blueswir1
    env->tbr &= ~0x7fffULL;
769 f2bc7e7f blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
770 f2bc7e7f blueswir1
    env->pc = env->tbr;
771 f2bc7e7f blueswir1
    env->npc = env->pc + 4;
772 f2bc7e7f blueswir1
    env->exception_index = 0;
773 f2bc7e7f blueswir1
}
774 f2bc7e7f blueswir1
#else
775 f2bc7e7f blueswir1
#ifdef DEBUG_PCALL
776 f2bc7e7f blueswir1
static const char * const excp_names[0x80] = {
777 f2bc7e7f blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
778 f2bc7e7f blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
779 f2bc7e7f blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
780 f2bc7e7f blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
781 f2bc7e7f blueswir1
    [TT_WIN_OVF] = "Window Overflow",
782 f2bc7e7f blueswir1
    [TT_WIN_UNF] = "Window Underflow",
783 f2bc7e7f blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
784 f2bc7e7f blueswir1
    [TT_FP_EXCP] = "FPU Exception",
785 f2bc7e7f blueswir1
    [TT_DFAULT] = "Data Access Fault",
786 f2bc7e7f blueswir1
    [TT_TOVF] = "Tag Overflow",
787 f2bc7e7f blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
788 f2bc7e7f blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
789 f2bc7e7f blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
790 f2bc7e7f blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
791 f2bc7e7f blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
792 f2bc7e7f blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
793 f2bc7e7f blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
794 f2bc7e7f blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
795 f2bc7e7f blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
796 f2bc7e7f blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
797 f2bc7e7f blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
798 f2bc7e7f blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
799 f2bc7e7f blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
800 f2bc7e7f blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
801 f2bc7e7f blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
802 f2bc7e7f blueswir1
    [TT_TOVF] = "Tag Overflow",
803 f2bc7e7f blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
804 f2bc7e7f blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
805 f2bc7e7f blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
806 f2bc7e7f blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
807 f2bc7e7f blueswir1
};
808 f2bc7e7f blueswir1
#endif
809 f2bc7e7f blueswir1
810 f2bc7e7f blueswir1
void do_interrupt(CPUState *env)
811 f2bc7e7f blueswir1
{
812 f2bc7e7f blueswir1
    int cwp, intno = env->exception_index;
813 f2bc7e7f blueswir1
814 f2bc7e7f blueswir1
#ifdef DEBUG_PCALL
815 f2bc7e7f blueswir1
    if (loglevel & CPU_LOG_INT) {
816 f2bc7e7f blueswir1
        static int count;
817 f2bc7e7f blueswir1
        const char *name;
818 f2bc7e7f blueswir1
819 f2bc7e7f blueswir1
        if (intno < 0 || intno >= 0x100)
820 f2bc7e7f blueswir1
            name = "Unknown";
821 f2bc7e7f blueswir1
        else if (intno >= 0x80)
822 f2bc7e7f blueswir1
            name = "Trap Instruction";
823 f2bc7e7f blueswir1
        else {
824 f2bc7e7f blueswir1
            name = excp_names[intno];
825 f2bc7e7f blueswir1
            if (!name)
826 f2bc7e7f blueswir1
                name = "Unknown";
827 f2bc7e7f blueswir1
        }
828 f2bc7e7f blueswir1
829 f2bc7e7f blueswir1
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
830 f2bc7e7f blueswir1
                count, name, intno,
831 f2bc7e7f blueswir1
                env->pc,
832 f2bc7e7f blueswir1
                env->npc, env->regwptr[6]);
833 f2bc7e7f blueswir1
        cpu_dump_state(env, logfile, fprintf, 0);
834 f2bc7e7f blueswir1
#if 0
835 f2bc7e7f blueswir1
        {
836 f2bc7e7f blueswir1
            int i;
837 f2bc7e7f blueswir1
            uint8_t *ptr;
838 f2bc7e7f blueswir1

839 f2bc7e7f blueswir1
            fprintf(logfile, "       code=");
840 f2bc7e7f blueswir1
            ptr = (uint8_t *)env->pc;
841 f2bc7e7f blueswir1
            for(i = 0; i < 16; i++) {
842 f2bc7e7f blueswir1
                fprintf(logfile, " %02x", ldub(ptr + i));
843 f2bc7e7f blueswir1
            }
844 f2bc7e7f blueswir1
            fprintf(logfile, "\n");
845 f2bc7e7f blueswir1
        }
846 f2bc7e7f blueswir1
#endif
847 f2bc7e7f blueswir1
        count++;
848 f2bc7e7f blueswir1
    }
849 f2bc7e7f blueswir1
#endif
850 f2bc7e7f blueswir1
#if !defined(CONFIG_USER_ONLY)
851 f2bc7e7f blueswir1
    if (env->psret == 0) {
852 f2bc7e7f blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
853 f2bc7e7f blueswir1
                  env->exception_index);
854 f2bc7e7f blueswir1
        return;
855 f2bc7e7f blueswir1
    }
856 f2bc7e7f blueswir1
#endif
857 f2bc7e7f blueswir1
    env->psret = 0;
858 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
859 f2bc7e7f blueswir1
    cpu_set_cwp(env, cwp);
860 f2bc7e7f blueswir1
    env->regwptr[9] = env->pc;
861 f2bc7e7f blueswir1
    env->regwptr[10] = env->npc;
862 f2bc7e7f blueswir1
    env->psrps = env->psrs;
863 f2bc7e7f blueswir1
    env->psrs = 1;
864 f2bc7e7f blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
865 f2bc7e7f blueswir1
    env->pc = env->tbr;
866 f2bc7e7f blueswir1
    env->npc = env->pc + 4;
867 f2bc7e7f blueswir1
    env->exception_index = 0;
868 f2bc7e7f blueswir1
}
869 f2bc7e7f blueswir1
#endif
870 f2bc7e7f blueswir1
871 24741ef3 bellard
void memcpy32(target_ulong *dst, const target_ulong *src)
872 24741ef3 bellard
{
873 24741ef3 bellard
    dst[0] = src[0];
874 24741ef3 bellard
    dst[1] = src[1];
875 24741ef3 bellard
    dst[2] = src[2];
876 24741ef3 bellard
    dst[3] = src[3];
877 24741ef3 bellard
    dst[4] = src[4];
878 24741ef3 bellard
    dst[5] = src[5];
879 24741ef3 bellard
    dst[6] = src[6];
880 24741ef3 bellard
    dst[7] = src[7];
881 24741ef3 bellard
}
882 87ecb68b pbrook
883 c48fcb47 blueswir1
void cpu_reset(CPUSPARCState *env)
884 c48fcb47 blueswir1
{
885 c48fcb47 blueswir1
    tlb_flush(env, 1);
886 c48fcb47 blueswir1
    env->cwp = 0;
887 c48fcb47 blueswir1
    env->wim = 1;
888 c48fcb47 blueswir1
    env->regwptr = env->regbase + (env->cwp * 16);
889 c48fcb47 blueswir1
#if defined(CONFIG_USER_ONLY)
890 c48fcb47 blueswir1
    env->user_mode_only = 1;
891 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
892 1a14026e blueswir1
    env->cleanwin = env->nwindows - 2;
893 1a14026e blueswir1
    env->cansave = env->nwindows - 2;
894 c48fcb47 blueswir1
    env->pstate = PS_RMO | PS_PEF | PS_IE;
895 c48fcb47 blueswir1
    env->asi = 0x82; // Primary no-fault
896 c48fcb47 blueswir1
#endif
897 c48fcb47 blueswir1
#else
898 c48fcb47 blueswir1
    env->psret = 0;
899 c48fcb47 blueswir1
    env->psrs = 1;
900 c48fcb47 blueswir1
    env->psrps = 1;
901 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
902 c48fcb47 blueswir1
    env->pstate = PS_PRIV;
903 c48fcb47 blueswir1
    env->hpstate = HS_PRIV;
904 8eba209e blueswir1
    env->pc = 0x1fff0000020ULL; // XXX should be different for system_reset
905 c19148bd blueswir1
    env->tsptr = &env->ts[env->tl & MAXTL_MASK];
906 c48fcb47 blueswir1
#else
907 c48fcb47 blueswir1
    env->pc = 0;
908 c48fcb47 blueswir1
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
909 5578ceab blueswir1
    env->mmuregs[0] |= env->def->mmu_bm;
910 c48fcb47 blueswir1
#endif
911 c48fcb47 blueswir1
    env->npc = env->pc + 4;
912 c48fcb47 blueswir1
#endif
913 c48fcb47 blueswir1
}
914 c48fcb47 blueswir1
915 64a88d5d blueswir1
static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
916 c48fcb47 blueswir1
{
917 64a88d5d blueswir1
    sparc_def_t def1, *def = &def1;
918 c48fcb47 blueswir1
919 64a88d5d blueswir1
    if (cpu_sparc_find_by_name(def, cpu_model) < 0)
920 64a88d5d blueswir1
        return -1;
921 c48fcb47 blueswir1
922 5578ceab blueswir1
    env->def = qemu_mallocz(sizeof(*def));
923 5578ceab blueswir1
    memcpy(env->def, def, sizeof(*def));
924 5578ceab blueswir1
#if defined(CONFIG_USER_ONLY)
925 5578ceab blueswir1
    if ((env->def->features & CPU_FEATURE_FLOAT))
926 5578ceab blueswir1
        env->def->features |= CPU_FEATURE_FLOAT128;
927 5578ceab blueswir1
#endif
928 c48fcb47 blueswir1
    env->cpu_model_str = cpu_model;
929 c48fcb47 blueswir1
    env->version = def->iu_version;
930 c48fcb47 blueswir1
    env->fsr = def->fpu_version;
931 1a14026e blueswir1
    env->nwindows = def->nwindows;
932 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
933 c48fcb47 blueswir1
    env->mmuregs[0] |= def->mmu_version;
934 c48fcb47 blueswir1
    cpu_sparc_set_id(env, 0);
935 1a14026e blueswir1
#else
936 fb79ceb9 blueswir1
    env->mmu_version = def->mmu_version;
937 c19148bd blueswir1
    env->maxtl = def->maxtl;
938 c19148bd blueswir1
    env->version |= def->maxtl << 8;
939 1a14026e blueswir1
    env->version |= def->nwindows - 1;
940 c48fcb47 blueswir1
#endif
941 64a88d5d blueswir1
    return 0;
942 64a88d5d blueswir1
}
943 64a88d5d blueswir1
944 64a88d5d blueswir1
static void cpu_sparc_close(CPUSPARCState *env)
945 64a88d5d blueswir1
{
946 5578ceab blueswir1
    free(env->def);
947 64a88d5d blueswir1
    free(env);
948 64a88d5d blueswir1
}
949 64a88d5d blueswir1
950 64a88d5d blueswir1
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
951 64a88d5d blueswir1
{
952 64a88d5d blueswir1
    CPUSPARCState *env;
953 64a88d5d blueswir1
954 64a88d5d blueswir1
    env = qemu_mallocz(sizeof(CPUSPARCState));
955 64a88d5d blueswir1
    if (!env)
956 64a88d5d blueswir1
        return NULL;
957 64a88d5d blueswir1
    cpu_exec_init(env);
958 c48fcb47 blueswir1
959 c48fcb47 blueswir1
    gen_intermediate_code_init(env);
960 c48fcb47 blueswir1
961 64a88d5d blueswir1
    if (cpu_sparc_register(env, cpu_model) < 0) {
962 64a88d5d blueswir1
        cpu_sparc_close(env);
963 64a88d5d blueswir1
        return NULL;
964 64a88d5d blueswir1
    }
965 c48fcb47 blueswir1
    cpu_reset(env);
966 c48fcb47 blueswir1
967 c48fcb47 blueswir1
    return env;
968 c48fcb47 blueswir1
}
969 c48fcb47 blueswir1
970 c48fcb47 blueswir1
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
971 c48fcb47 blueswir1
{
972 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
973 c48fcb47 blueswir1
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
974 c48fcb47 blueswir1
#endif
975 c48fcb47 blueswir1
}
976 c48fcb47 blueswir1
977 c48fcb47 blueswir1
static const sparc_def_t sparc_defs[] = {
978 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
979 c48fcb47 blueswir1
    {
980 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64",
981 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
982 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
983 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
984 1a14026e blueswir1
        .nwindows = 4,
985 c19148bd blueswir1
        .maxtl = 4,
986 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
987 c48fcb47 blueswir1
    },
988 c48fcb47 blueswir1
    {
989 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 III",
990 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
991 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
992 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
993 1a14026e blueswir1
        .nwindows = 5,
994 c19148bd blueswir1
        .maxtl = 4,
995 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
996 c48fcb47 blueswir1
    },
997 c48fcb47 blueswir1
    {
998 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 IV",
999 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
1000 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1001 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1002 1a14026e blueswir1
        .nwindows = 8,
1003 c19148bd blueswir1
        .maxtl = 5,
1004 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1005 c48fcb47 blueswir1
    },
1006 c48fcb47 blueswir1
    {
1007 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 V",
1008 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
1009 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1010 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1011 1a14026e blueswir1
        .nwindows = 8,
1012 c19148bd blueswir1
        .maxtl = 5,
1013 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1014 c48fcb47 blueswir1
    },
1015 c48fcb47 blueswir1
    {
1016 c48fcb47 blueswir1
        .name = "TI UltraSparc I",
1017 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
1018 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1019 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1020 1a14026e blueswir1
        .nwindows = 8,
1021 c19148bd blueswir1
        .maxtl = 5,
1022 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1023 c48fcb47 blueswir1
    },
1024 c48fcb47 blueswir1
    {
1025 c48fcb47 blueswir1
        .name = "TI UltraSparc II",
1026 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
1027 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1028 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1029 1a14026e blueswir1
        .nwindows = 8,
1030 c19148bd blueswir1
        .maxtl = 5,
1031 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1032 c48fcb47 blueswir1
    },
1033 c48fcb47 blueswir1
    {
1034 c48fcb47 blueswir1
        .name = "TI UltraSparc IIi",
1035 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
1036 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1037 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1038 1a14026e blueswir1
        .nwindows = 8,
1039 c19148bd blueswir1
        .maxtl = 5,
1040 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1041 c48fcb47 blueswir1
    },
1042 c48fcb47 blueswir1
    {
1043 c48fcb47 blueswir1
        .name = "TI UltraSparc IIe",
1044 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
1045 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1046 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1047 1a14026e blueswir1
        .nwindows = 8,
1048 c19148bd blueswir1
        .maxtl = 5,
1049 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1050 c48fcb47 blueswir1
    },
1051 c48fcb47 blueswir1
    {
1052 c48fcb47 blueswir1
        .name = "Sun UltraSparc III",
1053 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
1054 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1055 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1056 1a14026e blueswir1
        .nwindows = 8,
1057 c19148bd blueswir1
        .maxtl = 5,
1058 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1059 c48fcb47 blueswir1
    },
1060 c48fcb47 blueswir1
    {
1061 c48fcb47 blueswir1
        .name = "Sun UltraSparc III Cu",
1062 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
1063 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1064 fb79ceb9 blueswir1
        .mmu_version = mmu_us_3,
1065 1a14026e blueswir1
        .nwindows = 8,
1066 c19148bd blueswir1
        .maxtl = 5,
1067 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1068 c48fcb47 blueswir1
    },
1069 c48fcb47 blueswir1
    {
1070 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi",
1071 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
1072 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1073 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1074 1a14026e blueswir1
        .nwindows = 8,
1075 c19148bd blueswir1
        .maxtl = 5,
1076 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1077 c48fcb47 blueswir1
    },
1078 c48fcb47 blueswir1
    {
1079 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV",
1080 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
1081 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1082 fb79ceb9 blueswir1
        .mmu_version = mmu_us_4,
1083 1a14026e blueswir1
        .nwindows = 8,
1084 c19148bd blueswir1
        .maxtl = 5,
1085 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1086 c48fcb47 blueswir1
    },
1087 c48fcb47 blueswir1
    {
1088 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV+",
1089 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
1090 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1091 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1092 1a14026e blueswir1
        .nwindows = 8,
1093 c19148bd blueswir1
        .maxtl = 5,
1094 fb79ceb9 blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
1095 c48fcb47 blueswir1
    },
1096 c48fcb47 blueswir1
    {
1097 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi+",
1098 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
1099 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1100 fb79ceb9 blueswir1
        .mmu_version = mmu_us_3,
1101 1a14026e blueswir1
        .nwindows = 8,
1102 c19148bd blueswir1
        .maxtl = 5,
1103 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1104 c48fcb47 blueswir1
    },
1105 c48fcb47 blueswir1
    {
1106 c7ba218d blueswir1
        .name = "Sun UltraSparc T1",
1107 c7ba218d blueswir1
        // defined in sparc_ifu_fdp.v and ctu.h
1108 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
1109 c7ba218d blueswir1
        .fpu_version = 0x00000000,
1110 c7ba218d blueswir1
        .mmu_version = mmu_sun4v,
1111 c7ba218d blueswir1
        .nwindows = 8,
1112 c19148bd blueswir1
        .maxtl = 6,
1113 c7ba218d blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
1114 c7ba218d blueswir1
        | CPU_FEATURE_GL,
1115 c7ba218d blueswir1
    },
1116 c7ba218d blueswir1
    {
1117 c7ba218d blueswir1
        .name = "Sun UltraSparc T2",
1118 c7ba218d blueswir1
        // defined in tlu_asi_ctl.v and n2_revid_cust.v
1119 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
1120 c7ba218d blueswir1
        .fpu_version = 0x00000000,
1121 c7ba218d blueswir1
        .mmu_version = mmu_sun4v,
1122 c7ba218d blueswir1
        .nwindows = 8,
1123 c19148bd blueswir1
        .maxtl = 6,
1124 c7ba218d blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
1125 c7ba218d blueswir1
        | CPU_FEATURE_GL,
1126 c7ba218d blueswir1
    },
1127 c7ba218d blueswir1
    {
1128 c48fcb47 blueswir1
        .name = "NEC UltraSparc I",
1129 c19148bd blueswir1
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
1130 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1131 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1132 1a14026e blueswir1
        .nwindows = 8,
1133 c19148bd blueswir1
        .maxtl = 5,
1134 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1135 c48fcb47 blueswir1
    },
1136 c48fcb47 blueswir1
#else
1137 c48fcb47 blueswir1
    {
1138 c48fcb47 blueswir1
        .name = "Fujitsu MB86900",
1139 c48fcb47 blueswir1
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
1140 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1141 c48fcb47 blueswir1
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
1142 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1143 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1144 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1145 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1146 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1147 1a14026e blueswir1
        .nwindows = 7,
1148 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
1149 c48fcb47 blueswir1
    },
1150 c48fcb47 blueswir1
    {
1151 c48fcb47 blueswir1
        .name = "Fujitsu MB86904",
1152 c48fcb47 blueswir1
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
1153 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1154 c48fcb47 blueswir1
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
1155 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1156 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1157 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1158 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1159 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1160 1a14026e blueswir1
        .nwindows = 8,
1161 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1162 c48fcb47 blueswir1
    },
1163 c48fcb47 blueswir1
    {
1164 c48fcb47 blueswir1
        .name = "Fujitsu MB86907",
1165 c48fcb47 blueswir1
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
1166 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1167 c48fcb47 blueswir1
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
1168 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1169 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1170 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1171 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1172 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1173 1a14026e blueswir1
        .nwindows = 8,
1174 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1175 c48fcb47 blueswir1
    },
1176 c48fcb47 blueswir1
    {
1177 c48fcb47 blueswir1
        .name = "LSI L64811",
1178 c48fcb47 blueswir1
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
1179 c48fcb47 blueswir1
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
1180 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1181 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1182 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1183 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1184 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1185 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1186 1a14026e blueswir1
        .nwindows = 8,
1187 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1188 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1189 c48fcb47 blueswir1
    },
1190 c48fcb47 blueswir1
    {
1191 c48fcb47 blueswir1
        .name = "Cypress CY7C601",
1192 c48fcb47 blueswir1
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
1193 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1194 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1195 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1196 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1197 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1198 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1199 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1200 1a14026e blueswir1
        .nwindows = 8,
1201 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1202 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1203 c48fcb47 blueswir1
    },
1204 c48fcb47 blueswir1
    {
1205 c48fcb47 blueswir1
        .name = "Cypress CY7C611",
1206 c48fcb47 blueswir1
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
1207 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1208 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1209 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1210 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1211 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1212 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1213 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1214 1a14026e blueswir1
        .nwindows = 8,
1215 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1216 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1217 c48fcb47 blueswir1
    },
1218 c48fcb47 blueswir1
    {
1219 c48fcb47 blueswir1
        .name = "TI SuperSparc II",
1220 c48fcb47 blueswir1
        .iu_version = 0x40000000,
1221 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1222 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1223 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1224 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1225 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1226 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1227 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1228 1a14026e blueswir1
        .nwindows = 8,
1229 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1230 c48fcb47 blueswir1
    },
1231 c48fcb47 blueswir1
    {
1232 c48fcb47 blueswir1
        .name = "TI MicroSparc I",
1233 c48fcb47 blueswir1
        .iu_version = 0x41000000,
1234 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1235 c48fcb47 blueswir1
        .mmu_version = 0x41000000,
1236 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1237 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1238 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1239 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1240 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x0000003f,
1241 1a14026e blueswir1
        .nwindows = 7,
1242 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
1243 e30b4678 blueswir1
        CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
1244 e30b4678 blueswir1
        CPU_FEATURE_FMUL,
1245 c48fcb47 blueswir1
    },
1246 c48fcb47 blueswir1
    {
1247 c48fcb47 blueswir1
        .name = "TI MicroSparc II",
1248 c48fcb47 blueswir1
        .iu_version = 0x42000000,
1249 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1250 c48fcb47 blueswir1
        .mmu_version = 0x02000000,
1251 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1252 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1253 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1254 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1255 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1256 1a14026e blueswir1
        .nwindows = 8,
1257 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1258 c48fcb47 blueswir1
    },
1259 c48fcb47 blueswir1
    {
1260 c48fcb47 blueswir1
        .name = "TI MicroSparc IIep",
1261 c48fcb47 blueswir1
        .iu_version = 0x42000000,
1262 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1263 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1264 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1265 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1266 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1267 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016bff,
1268 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1269 1a14026e blueswir1
        .nwindows = 8,
1270 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1271 c48fcb47 blueswir1
    },
1272 c48fcb47 blueswir1
    {
1273 b5154bde blueswir1
        .name = "TI SuperSparc 40", // STP1020NPGA
1274 b5154bde blueswir1
        .iu_version = 0x41000000,
1275 b5154bde blueswir1
        .fpu_version = 0 << 17,
1276 b5154bde blueswir1
        .mmu_version = 0x00000000,
1277 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1278 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1279 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1280 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1281 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1282 1a14026e blueswir1
        .nwindows = 8,
1283 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1284 b5154bde blueswir1
    },
1285 b5154bde blueswir1
    {
1286 b5154bde blueswir1
        .name = "TI SuperSparc 50", // STP1020PGA
1287 b5154bde blueswir1
        .iu_version = 0x40000000,
1288 b5154bde blueswir1
        .fpu_version = 0 << 17,
1289 b5154bde blueswir1
        .mmu_version = 0x04000000,
1290 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1291 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1292 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1293 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1294 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1295 1a14026e blueswir1
        .nwindows = 8,
1296 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1297 b5154bde blueswir1
    },
1298 b5154bde blueswir1
    {
1299 c48fcb47 blueswir1
        .name = "TI SuperSparc 51",
1300 c48fcb47 blueswir1
        .iu_version = 0x43000000,
1301 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1302 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1303 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1304 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1305 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1306 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1307 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1308 1a14026e blueswir1
        .nwindows = 8,
1309 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1310 c48fcb47 blueswir1
    },
1311 c48fcb47 blueswir1
    {
1312 b5154bde blueswir1
        .name = "TI SuperSparc 60", // STP1020APGA
1313 b5154bde blueswir1
        .iu_version = 0x40000000,
1314 b5154bde blueswir1
        .fpu_version = 0 << 17,
1315 b5154bde blueswir1
        .mmu_version = 0x03000000,
1316 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1317 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1318 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1319 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1320 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1321 1a14026e blueswir1
        .nwindows = 8,
1322 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1323 b5154bde blueswir1
    },
1324 b5154bde blueswir1
    {
1325 c48fcb47 blueswir1
        .name = "TI SuperSparc 61",
1326 c48fcb47 blueswir1
        .iu_version = 0x44000000,
1327 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1328 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1329 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1330 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1331 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1332 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1333 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1334 1a14026e blueswir1
        .nwindows = 8,
1335 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1336 c48fcb47 blueswir1
    },
1337 c48fcb47 blueswir1
    {
1338 c48fcb47 blueswir1
        .name = "Ross RT625",
1339 c48fcb47 blueswir1
        .iu_version = 0x1e000000,
1340 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1341 c48fcb47 blueswir1
        .mmu_version = 0x1e000000,
1342 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1343 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1344 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1345 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1346 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1347 1a14026e blueswir1
        .nwindows = 8,
1348 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1349 c48fcb47 blueswir1
    },
1350 c48fcb47 blueswir1
    {
1351 c48fcb47 blueswir1
        .name = "Ross RT620",
1352 c48fcb47 blueswir1
        .iu_version = 0x1f000000,
1353 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1354 c48fcb47 blueswir1
        .mmu_version = 0x1f000000,
1355 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1356 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1357 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1358 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1359 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1360 1a14026e blueswir1
        .nwindows = 8,
1361 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1362 c48fcb47 blueswir1
    },
1363 c48fcb47 blueswir1
    {
1364 c48fcb47 blueswir1
        .name = "BIT B5010",
1365 c48fcb47 blueswir1
        .iu_version = 0x20000000,
1366 c48fcb47 blueswir1
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
1367 c48fcb47 blueswir1
        .mmu_version = 0x20000000,
1368 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1369 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1370 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1371 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1372 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1373 1a14026e blueswir1
        .nwindows = 8,
1374 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1375 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1376 c48fcb47 blueswir1
    },
1377 c48fcb47 blueswir1
    {
1378 c48fcb47 blueswir1
        .name = "Matsushita MN10501",
1379 c48fcb47 blueswir1
        .iu_version = 0x50000000,
1380 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1381 c48fcb47 blueswir1
        .mmu_version = 0x50000000,
1382 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1383 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1384 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1385 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1386 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1387 1a14026e blueswir1
        .nwindows = 8,
1388 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
1389 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1390 c48fcb47 blueswir1
    },
1391 c48fcb47 blueswir1
    {
1392 c48fcb47 blueswir1
        .name = "Weitek W8601",
1393 c48fcb47 blueswir1
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
1394 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
1395 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1396 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1397 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1398 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1399 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1400 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1401 1a14026e blueswir1
        .nwindows = 8,
1402 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1403 c48fcb47 blueswir1
    },
1404 c48fcb47 blueswir1
    {
1405 c48fcb47 blueswir1
        .name = "LEON2",
1406 c48fcb47 blueswir1
        .iu_version = 0xf2000000,
1407 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1408 c48fcb47 blueswir1
        .mmu_version = 0xf2000000,
1409 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1410 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1411 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1412 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1413 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1414 1a14026e blueswir1
        .nwindows = 8,
1415 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1416 c48fcb47 blueswir1
    },
1417 c48fcb47 blueswir1
    {
1418 c48fcb47 blueswir1
        .name = "LEON3",
1419 c48fcb47 blueswir1
        .iu_version = 0xf3000000,
1420 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1421 c48fcb47 blueswir1
        .mmu_version = 0xf3000000,
1422 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1423 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1424 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1425 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1426 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1427 1a14026e blueswir1
        .nwindows = 8,
1428 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1429 c48fcb47 blueswir1
    },
1430 c48fcb47 blueswir1
#endif
1431 c48fcb47 blueswir1
};
1432 c48fcb47 blueswir1
1433 64a88d5d blueswir1
static const char * const feature_name[] = {
1434 64a88d5d blueswir1
    "float",
1435 64a88d5d blueswir1
    "float128",
1436 64a88d5d blueswir1
    "swap",
1437 64a88d5d blueswir1
    "mul",
1438 64a88d5d blueswir1
    "div",
1439 64a88d5d blueswir1
    "flush",
1440 64a88d5d blueswir1
    "fsqrt",
1441 64a88d5d blueswir1
    "fmul",
1442 64a88d5d blueswir1
    "vis1",
1443 64a88d5d blueswir1
    "vis2",
1444 e30b4678 blueswir1
    "fsmuld",
1445 fb79ceb9 blueswir1
    "hypv",
1446 fb79ceb9 blueswir1
    "cmt",
1447 fb79ceb9 blueswir1
    "gl",
1448 64a88d5d blueswir1
};
1449 64a88d5d blueswir1
1450 64a88d5d blueswir1
static void print_features(FILE *f,
1451 64a88d5d blueswir1
                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1452 64a88d5d blueswir1
                           uint32_t features, const char *prefix)
1453 c48fcb47 blueswir1
{
1454 c48fcb47 blueswir1
    unsigned int i;
1455 c48fcb47 blueswir1
1456 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1457 64a88d5d blueswir1
        if (feature_name[i] && (features & (1 << i))) {
1458 64a88d5d blueswir1
            if (prefix)
1459 64a88d5d blueswir1
                (*cpu_fprintf)(f, "%s", prefix);
1460 64a88d5d blueswir1
            (*cpu_fprintf)(f, "%s ", feature_name[i]);
1461 64a88d5d blueswir1
        }
1462 64a88d5d blueswir1
}
1463 64a88d5d blueswir1
1464 64a88d5d blueswir1
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
1465 64a88d5d blueswir1
{
1466 64a88d5d blueswir1
    unsigned int i;
1467 64a88d5d blueswir1
1468 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1469 64a88d5d blueswir1
        if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
1470 64a88d5d blueswir1
            *features |= 1 << i;
1471 64a88d5d blueswir1
            return;
1472 64a88d5d blueswir1
        }
1473 64a88d5d blueswir1
    fprintf(stderr, "CPU feature %s not found\n", flagname);
1474 64a88d5d blueswir1
}
1475 64a88d5d blueswir1
1476 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
1477 64a88d5d blueswir1
{
1478 64a88d5d blueswir1
    unsigned int i;
1479 64a88d5d blueswir1
    const sparc_def_t *def = NULL;
1480 64a88d5d blueswir1
    char *s = strdup(cpu_model);
1481 64a88d5d blueswir1
    char *featurestr, *name = strtok(s, ",");
1482 64a88d5d blueswir1
    uint32_t plus_features = 0;
1483 64a88d5d blueswir1
    uint32_t minus_features = 0;
1484 64a88d5d blueswir1
    long long iu_version;
1485 1a14026e blueswir1
    uint32_t fpu_version, mmu_version, nwindows;
1486 64a88d5d blueswir1
1487 c48fcb47 blueswir1
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1488 c48fcb47 blueswir1
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
1489 64a88d5d blueswir1
            def = &sparc_defs[i];
1490 c48fcb47 blueswir1
        }
1491 c48fcb47 blueswir1
    }
1492 64a88d5d blueswir1
    if (!def)
1493 64a88d5d blueswir1
        goto error;
1494 64a88d5d blueswir1
    memcpy(cpu_def, def, sizeof(*def));
1495 64a88d5d blueswir1
1496 64a88d5d blueswir1
    featurestr = strtok(NULL, ",");
1497 64a88d5d blueswir1
    while (featurestr) {
1498 64a88d5d blueswir1
        char *val;
1499 64a88d5d blueswir1
1500 64a88d5d blueswir1
        if (featurestr[0] == '+') {
1501 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &plus_features);
1502 64a88d5d blueswir1
        } else if (featurestr[0] == '-') {
1503 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &minus_features);
1504 64a88d5d blueswir1
        } else if ((val = strchr(featurestr, '='))) {
1505 64a88d5d blueswir1
            *val = 0; val++;
1506 64a88d5d blueswir1
            if (!strcmp(featurestr, "iu_version")) {
1507 64a88d5d blueswir1
                char *err;
1508 64a88d5d blueswir1
1509 64a88d5d blueswir1
                iu_version = strtoll(val, &err, 0);
1510 64a88d5d blueswir1
                if (!*val || *err) {
1511 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1512 64a88d5d blueswir1
                    goto error;
1513 64a88d5d blueswir1
                }
1514 64a88d5d blueswir1
                cpu_def->iu_version = iu_version;
1515 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1516 64a88d5d blueswir1
                fprintf(stderr, "iu_version %llx\n", iu_version);
1517 64a88d5d blueswir1
#endif
1518 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "fpu_version")) {
1519 64a88d5d blueswir1
                char *err;
1520 64a88d5d blueswir1
1521 64a88d5d blueswir1
                fpu_version = strtol(val, &err, 0);
1522 64a88d5d blueswir1
                if (!*val || *err) {
1523 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1524 64a88d5d blueswir1
                    goto error;
1525 64a88d5d blueswir1
                }
1526 64a88d5d blueswir1
                cpu_def->fpu_version = fpu_version;
1527 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1528 64a88d5d blueswir1
                fprintf(stderr, "fpu_version %llx\n", fpu_version);
1529 64a88d5d blueswir1
#endif
1530 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "mmu_version")) {
1531 64a88d5d blueswir1
                char *err;
1532 64a88d5d blueswir1
1533 64a88d5d blueswir1
                mmu_version = strtol(val, &err, 0);
1534 64a88d5d blueswir1
                if (!*val || *err) {
1535 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1536 64a88d5d blueswir1
                    goto error;
1537 64a88d5d blueswir1
                }
1538 64a88d5d blueswir1
                cpu_def->mmu_version = mmu_version;
1539 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1540 64a88d5d blueswir1
                fprintf(stderr, "mmu_version %llx\n", mmu_version);
1541 64a88d5d blueswir1
#endif
1542 1a14026e blueswir1
            } else if (!strcmp(featurestr, "nwindows")) {
1543 1a14026e blueswir1
                char *err;
1544 1a14026e blueswir1
1545 1a14026e blueswir1
                nwindows = strtol(val, &err, 0);
1546 1a14026e blueswir1
                if (!*val || *err || nwindows > MAX_NWINDOWS ||
1547 1a14026e blueswir1
                    nwindows < MIN_NWINDOWS) {
1548 1a14026e blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1549 1a14026e blueswir1
                    goto error;
1550 1a14026e blueswir1
                }
1551 1a14026e blueswir1
                cpu_def->nwindows = nwindows;
1552 1a14026e blueswir1
#ifdef DEBUG_FEATURES
1553 1a14026e blueswir1
                fprintf(stderr, "nwindows %d\n", nwindows);
1554 1a14026e blueswir1
#endif
1555 64a88d5d blueswir1
            } else {
1556 64a88d5d blueswir1
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1557 64a88d5d blueswir1
                goto error;
1558 64a88d5d blueswir1
            }
1559 64a88d5d blueswir1
        } else {
1560 77f193da blueswir1
            fprintf(stderr, "feature string `%s' not in format "
1561 77f193da blueswir1
                    "(+feature|-feature|feature=xyz)\n", featurestr);
1562 64a88d5d blueswir1
            goto error;
1563 64a88d5d blueswir1
        }
1564 64a88d5d blueswir1
        featurestr = strtok(NULL, ",");
1565 64a88d5d blueswir1
    }
1566 64a88d5d blueswir1
    cpu_def->features |= plus_features;
1567 64a88d5d blueswir1
    cpu_def->features &= ~minus_features;
1568 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1569 64a88d5d blueswir1
    print_features(stderr, fprintf, cpu_def->features, NULL);
1570 64a88d5d blueswir1
#endif
1571 64a88d5d blueswir1
    free(s);
1572 64a88d5d blueswir1
    return 0;
1573 64a88d5d blueswir1
1574 64a88d5d blueswir1
 error:
1575 64a88d5d blueswir1
    free(s);
1576 64a88d5d blueswir1
    return -1;
1577 c48fcb47 blueswir1
}
1578 c48fcb47 blueswir1
1579 77f193da blueswir1
void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
1580 c48fcb47 blueswir1
{
1581 c48fcb47 blueswir1
    unsigned int i;
1582 c48fcb47 blueswir1
1583 c48fcb47 blueswir1
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1584 1a14026e blueswir1
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
1585 c48fcb47 blueswir1
                       sparc_defs[i].name,
1586 c48fcb47 blueswir1
                       sparc_defs[i].iu_version,
1587 c48fcb47 blueswir1
                       sparc_defs[i].fpu_version,
1588 1a14026e blueswir1
                       sparc_defs[i].mmu_version,
1589 1a14026e blueswir1
                       sparc_defs[i].nwindows);
1590 77f193da blueswir1
        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
1591 77f193da blueswir1
                       ~sparc_defs[i].features, "-");
1592 77f193da blueswir1
        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
1593 77f193da blueswir1
                       sparc_defs[i].features, "+");
1594 64a88d5d blueswir1
        (*cpu_fprintf)(f, "\n");
1595 c48fcb47 blueswir1
    }
1596 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
1597 f76981b1 blueswir1
    print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
1598 64a88d5d blueswir1
    (*cpu_fprintf)(f, "\n");
1599 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
1600 f76981b1 blueswir1
    print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
1601 f76981b1 blueswir1
    (*cpu_fprintf)(f, "\n");
1602 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
1603 f76981b1 blueswir1
                   "fpu_version mmu_version nwindows\n");
1604 c48fcb47 blueswir1
}
1605 c48fcb47 blueswir1
1606 c48fcb47 blueswir1
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
1607 c48fcb47 blueswir1
1608 c48fcb47 blueswir1
void cpu_dump_state(CPUState *env, FILE *f,
1609 c48fcb47 blueswir1
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1610 c48fcb47 blueswir1
                    int flags)
1611 c48fcb47 blueswir1
{
1612 c48fcb47 blueswir1
    int i, x;
1613 c48fcb47 blueswir1
1614 77f193da blueswir1
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
1615 77f193da blueswir1
                env->npc);
1616 c48fcb47 blueswir1
    cpu_fprintf(f, "General Registers:\n");
1617 c48fcb47 blueswir1
    for (i = 0; i < 4; i++)
1618 c48fcb47 blueswir1
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1619 c48fcb47 blueswir1
    cpu_fprintf(f, "\n");
1620 c48fcb47 blueswir1
    for (; i < 8; i++)
1621 c48fcb47 blueswir1
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1622 c48fcb47 blueswir1
    cpu_fprintf(f, "\nCurrent Register Window:\n");
1623 c48fcb47 blueswir1
    for (x = 0; x < 3; x++) {
1624 c48fcb47 blueswir1
        for (i = 0; i < 4; i++)
1625 c48fcb47 blueswir1
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1626 c48fcb47 blueswir1
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1627 c48fcb47 blueswir1
                    env->regwptr[i + x * 8]);
1628 c48fcb47 blueswir1
        cpu_fprintf(f, "\n");
1629 c48fcb47 blueswir1
        for (; i < 8; i++)
1630 c48fcb47 blueswir1
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1631 c48fcb47 blueswir1
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1632 c48fcb47 blueswir1
                    env->regwptr[i + x * 8]);
1633 c48fcb47 blueswir1
        cpu_fprintf(f, "\n");
1634 c48fcb47 blueswir1
    }
1635 c48fcb47 blueswir1
    cpu_fprintf(f, "\nFloating Point Registers:\n");
1636 c48fcb47 blueswir1
    for (i = 0; i < 32; i++) {
1637 c48fcb47 blueswir1
        if ((i & 3) == 0)
1638 c48fcb47 blueswir1
            cpu_fprintf(f, "%%f%02d:", i);
1639 a37ee56c blueswir1
        cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]);
1640 c48fcb47 blueswir1
        if ((i & 3) == 3)
1641 c48fcb47 blueswir1
            cpu_fprintf(f, "\n");
1642 c48fcb47 blueswir1
    }
1643 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1644 c48fcb47 blueswir1
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
1645 c48fcb47 blueswir1
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
1646 77f193da blueswir1
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d "
1647 77f193da blueswir1
                "cleanwin %d cwp %d\n",
1648 c48fcb47 blueswir1
                env->cansave, env->canrestore, env->otherwin, env->wstate,
1649 1a14026e blueswir1
                env->cleanwin, env->nwindows - 1 - env->cwp);
1650 c48fcb47 blueswir1
#else
1651 77f193da blueswir1
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
1652 77f193da blueswir1
                GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
1653 77f193da blueswir1
                GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1654 77f193da blueswir1
                env->psrs?'S':'-', env->psrps?'P':'-',
1655 77f193da blueswir1
                env->psret?'E':'-', env->wim);
1656 c48fcb47 blueswir1
#endif
1657 c48fcb47 blueswir1
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
1658 c48fcb47 blueswir1
}
1659 c48fcb47 blueswir1
1660 87ecb68b pbrook
#ifdef TARGET_SPARC64
1661 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1662 87ecb68b pbrook
#include "qemu-common.h"
1663 87ecb68b pbrook
#include "hw/irq.h"
1664 87ecb68b pbrook
#include "qemu-timer.h"
1665 87ecb68b pbrook
#endif
1666 87ecb68b pbrook
1667 ccd4a219 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
1668 87ecb68b pbrook
{
1669 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1670 87ecb68b pbrook
    ptimer_set_count(opaque, -count);
1671 87ecb68b pbrook
#endif
1672 87ecb68b pbrook
}
1673 87ecb68b pbrook
1674 ccd4a219 blueswir1
uint64_t helper_tick_get_count(void *opaque)
1675 87ecb68b pbrook
{
1676 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1677 87ecb68b pbrook
    return -ptimer_get_count(opaque);
1678 87ecb68b pbrook
#else
1679 87ecb68b pbrook
    return 0;
1680 87ecb68b pbrook
#endif
1681 87ecb68b pbrook
}
1682 87ecb68b pbrook
1683 ccd4a219 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
1684 87ecb68b pbrook
{
1685 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1686 87ecb68b pbrook
    ptimer_set_limit(opaque, -limit, 0);
1687 87ecb68b pbrook
#endif
1688 87ecb68b pbrook
}
1689 87ecb68b pbrook
#endif