Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ 1a14026e

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

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

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