Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ 8686c490

History | View | Annotate | Download (41.4 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 e8af50a3 bellard
36 c48fcb47 blueswir1
typedef struct sparc_def_t sparc_def_t;
37 c48fcb47 blueswir1
38 c48fcb47 blueswir1
struct sparc_def_t {
39 22548760 blueswir1
    const char *name;
40 c48fcb47 blueswir1
    target_ulong iu_version;
41 c48fcb47 blueswir1
    uint32_t fpu_version;
42 c48fcb47 blueswir1
    uint32_t mmu_version;
43 c48fcb47 blueswir1
    uint32_t mmu_bm;
44 c48fcb47 blueswir1
    uint32_t mmu_ctpr_mask;
45 c48fcb47 blueswir1
    uint32_t mmu_cxr_mask;
46 c48fcb47 blueswir1
    uint32_t mmu_sfsr_mask;
47 c48fcb47 blueswir1
    uint32_t mmu_trcr_mask;
48 64a88d5d blueswir1
    uint32_t features;
49 c48fcb47 blueswir1
};
50 c48fcb47 blueswir1
51 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
52 c48fcb47 blueswir1
53 e8af50a3 bellard
/* Sparc MMU emulation */
54 e8af50a3 bellard
55 e8af50a3 bellard
/* thread support */
56 e8af50a3 bellard
57 e8af50a3 bellard
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
58 e8af50a3 bellard
59 e8af50a3 bellard
void cpu_lock(void)
60 e8af50a3 bellard
{
61 e8af50a3 bellard
    spin_lock(&global_cpu_lock);
62 e8af50a3 bellard
}
63 e8af50a3 bellard
64 e8af50a3 bellard
void cpu_unlock(void)
65 e8af50a3 bellard
{
66 e8af50a3 bellard
    spin_unlock(&global_cpu_lock);
67 e8af50a3 bellard
}
68 e8af50a3 bellard
69 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
70 9d893301 bellard
71 22548760 blueswir1
int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
72 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
73 9d893301 bellard
{
74 878d3096 bellard
    if (rw & 2)
75 22548760 blueswir1
        env1->exception_index = TT_TFAULT;
76 878d3096 bellard
    else
77 22548760 blueswir1
        env1->exception_index = TT_DFAULT;
78 9d893301 bellard
    return 1;
79 9d893301 bellard
}
80 9d893301 bellard
81 9d893301 bellard
#else
82 e8af50a3 bellard
83 3475187d bellard
#ifndef TARGET_SPARC64
84 83469015 bellard
/*
85 83469015 bellard
 * Sparc V8 Reference MMU (SRMMU)
86 83469015 bellard
 */
87 e8af50a3 bellard
static const int access_table[8][8] = {
88 e8af50a3 bellard
    { 0, 0, 0, 0, 2, 0, 3, 3 },
89 e8af50a3 bellard
    { 0, 0, 0, 0, 2, 0, 0, 0 },
90 e8af50a3 bellard
    { 2, 2, 0, 0, 0, 2, 3, 3 },
91 e8af50a3 bellard
    { 2, 2, 0, 0, 0, 2, 0, 0 },
92 e8af50a3 bellard
    { 2, 0, 2, 0, 2, 2, 3, 3 },
93 e8af50a3 bellard
    { 2, 0, 2, 0, 2, 0, 2, 0 },
94 e8af50a3 bellard
    { 2, 2, 2, 0, 2, 2, 3, 3 },
95 e8af50a3 bellard
    { 2, 2, 2, 0, 2, 2, 2, 0 }
96 e8af50a3 bellard
};
97 e8af50a3 bellard
98 227671c9 bellard
static const int perm_table[2][8] = {
99 227671c9 bellard
    {
100 227671c9 bellard
        PAGE_READ,
101 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
102 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
103 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
104 227671c9 bellard
        PAGE_EXEC,
105 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
106 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
107 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC
108 227671c9 bellard
    },
109 227671c9 bellard
    {
110 227671c9 bellard
        PAGE_READ,
111 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
112 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
113 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
114 227671c9 bellard
        PAGE_EXEC,
115 227671c9 bellard
        PAGE_READ,
116 227671c9 bellard
        0,
117 227671c9 bellard
        0,
118 227671c9 bellard
    }
119 e8af50a3 bellard
};
120 e8af50a3 bellard
121 c48fcb47 blueswir1
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
122 c48fcb47 blueswir1
                                int *prot, int *access_index,
123 c48fcb47 blueswir1
                                target_ulong address, int rw, int mmu_idx)
124 e8af50a3 bellard
{
125 e80cfcfc bellard
    int access_perms = 0;
126 e80cfcfc bellard
    target_phys_addr_t pde_ptr;
127 af7bf89b bellard
    uint32_t pde;
128 af7bf89b bellard
    target_ulong virt_addr;
129 6ebbf390 j_mayer
    int error_code = 0, is_dirty, is_user;
130 e80cfcfc bellard
    unsigned long page_offset;
131 e8af50a3 bellard
132 6ebbf390 j_mayer
    is_user = mmu_idx == MMU_USER_IDX;
133 e8af50a3 bellard
    virt_addr = address & TARGET_PAGE_MASK;
134 40ce0a9a blueswir1
135 e8af50a3 bellard
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
136 40ce0a9a blueswir1
        // Boot mode: instruction fetches are taken from PROM
137 6d5f237a blueswir1
        if (rw == 2 && (env->mmuregs[0] & env->mmu_bm)) {
138 58a770f3 blueswir1
            *physical = env->prom_addr | (address & 0x7ffffULL);
139 40ce0a9a blueswir1
            *prot = PAGE_READ | PAGE_EXEC;
140 40ce0a9a blueswir1
            return 0;
141 40ce0a9a blueswir1
        }
142 0f8a249a blueswir1
        *physical = address;
143 227671c9 bellard
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
144 e80cfcfc bellard
        return 0;
145 e8af50a3 bellard
    }
146 e8af50a3 bellard
147 7483750d bellard
    *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
148 5dcb6b91 blueswir1
    *physical = 0xffffffffffff0000ULL;
149 7483750d bellard
150 e8af50a3 bellard
    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
151 e8af50a3 bellard
    /* Context base + context number */
152 3deaeab7 blueswir1
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
153 49be8030 bellard
    pde = ldl_phys(pde_ptr);
154 e8af50a3 bellard
155 e8af50a3 bellard
    /* Ctx pde */
156 e8af50a3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
157 e80cfcfc bellard
    default:
158 e8af50a3 bellard
    case 0: /* Invalid */
159 0f8a249a blueswir1
        return 1 << 2;
160 e80cfcfc bellard
    case 2: /* L0 PTE, maybe should not happen? */
161 e8af50a3 bellard
    case 3: /* Reserved */
162 7483750d bellard
        return 4 << 2;
163 e80cfcfc bellard
    case 1: /* L0 PDE */
164 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
165 49be8030 bellard
        pde = ldl_phys(pde_ptr);
166 e8af50a3 bellard
167 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
168 0f8a249a blueswir1
        default:
169 0f8a249a blueswir1
        case 0: /* Invalid */
170 0f8a249a blueswir1
            return (1 << 8) | (1 << 2);
171 0f8a249a blueswir1
        case 3: /* Reserved */
172 0f8a249a blueswir1
            return (1 << 8) | (4 << 2);
173 0f8a249a blueswir1
        case 1: /* L1 PDE */
174 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
175 49be8030 bellard
            pde = ldl_phys(pde_ptr);
176 e8af50a3 bellard
177 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
178 0f8a249a blueswir1
            default:
179 0f8a249a blueswir1
            case 0: /* Invalid */
180 0f8a249a blueswir1
                return (2 << 8) | (1 << 2);
181 0f8a249a blueswir1
            case 3: /* Reserved */
182 0f8a249a blueswir1
                return (2 << 8) | (4 << 2);
183 0f8a249a blueswir1
            case 1: /* L2 PDE */
184 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
185 49be8030 bellard
                pde = ldl_phys(pde_ptr);
186 e8af50a3 bellard
187 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
188 0f8a249a blueswir1
                default:
189 0f8a249a blueswir1
                case 0: /* Invalid */
190 0f8a249a blueswir1
                    return (3 << 8) | (1 << 2);
191 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
192 0f8a249a blueswir1
                case 3: /* Reserved */
193 0f8a249a blueswir1
                    return (3 << 8) | (4 << 2);
194 0f8a249a blueswir1
                case 2: /* L3 PTE */
195 0f8a249a blueswir1
                    virt_addr = address & TARGET_PAGE_MASK;
196 0f8a249a blueswir1
                    page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
197 0f8a249a blueswir1
                }
198 0f8a249a blueswir1
                break;
199 0f8a249a blueswir1
            case 2: /* L2 PTE */
200 0f8a249a blueswir1
                virt_addr = address & ~0x3ffff;
201 0f8a249a blueswir1
                page_offset = address & 0x3ffff;
202 0f8a249a blueswir1
            }
203 0f8a249a blueswir1
            break;
204 0f8a249a blueswir1
        case 2: /* L1 PTE */
205 0f8a249a blueswir1
            virt_addr = address & ~0xffffff;
206 0f8a249a blueswir1
            page_offset = address & 0xffffff;
207 0f8a249a blueswir1
        }
208 e8af50a3 bellard
    }
209 e8af50a3 bellard
210 e8af50a3 bellard
    /* update page modified and dirty bits */
211 b769d8fe bellard
    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
212 e8af50a3 bellard
    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
213 0f8a249a blueswir1
        pde |= PG_ACCESSED_MASK;
214 0f8a249a blueswir1
        if (is_dirty)
215 0f8a249a blueswir1
            pde |= PG_MODIFIED_MASK;
216 49be8030 bellard
        stl_phys_notdirty(pde_ptr, pde);
217 e8af50a3 bellard
    }
218 e8af50a3 bellard
    /* check access */
219 e8af50a3 bellard
    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
220 e80cfcfc bellard
    error_code = access_table[*access_index][access_perms];
221 d8e3326c bellard
    if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
222 0f8a249a blueswir1
        return error_code;
223 e8af50a3 bellard
224 e8af50a3 bellard
    /* the page can be put in the TLB */
225 227671c9 bellard
    *prot = perm_table[is_user][access_perms];
226 227671c9 bellard
    if (!(pde & PG_MODIFIED_MASK)) {
227 e8af50a3 bellard
        /* only set write access if already dirty... otherwise wait
228 e8af50a3 bellard
           for dirty access */
229 227671c9 bellard
        *prot &= ~PAGE_WRITE;
230 e8af50a3 bellard
    }
231 e8af50a3 bellard
232 e8af50a3 bellard
    /* Even if large ptes, we map only one 4KB page in the cache to
233 e8af50a3 bellard
       avoid filling it too fast */
234 5dcb6b91 blueswir1
    *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
235 6f7e9aec bellard
    return error_code;
236 e80cfcfc bellard
}
237 e80cfcfc bellard
238 e80cfcfc bellard
/* Perform address translation */
239 af7bf89b bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
240 6ebbf390 j_mayer
                              int mmu_idx, int is_softmmu)
241 e80cfcfc bellard
{
242 af7bf89b bellard
    target_phys_addr_t paddr;
243 5dcb6b91 blueswir1
    target_ulong vaddr;
244 e80cfcfc bellard
    int error_code = 0, prot, ret = 0, access_index;
245 e8af50a3 bellard
246 6ebbf390 j_mayer
    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
247 e80cfcfc bellard
    if (error_code == 0) {
248 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
249 0f8a249a blueswir1
        paddr &= TARGET_PAGE_MASK;
250 9e61bde5 bellard
#ifdef DEBUG_MMU
251 0f8a249a blueswir1
        printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
252 5dcb6b91 blueswir1
               TARGET_FMT_lx "\n", address, paddr, vaddr);
253 9e61bde5 bellard
#endif
254 6ebbf390 j_mayer
        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
255 0f8a249a blueswir1
        return ret;
256 e80cfcfc bellard
    }
257 e8af50a3 bellard
258 e8af50a3 bellard
    if (env->mmuregs[3]) /* Fault status register */
259 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
260 7483750d bellard
    env->mmuregs[3] |= (access_index << 5) | error_code | 2;
261 e8af50a3 bellard
    env->mmuregs[4] = address; /* Fault address register */
262 e8af50a3 bellard
263 878d3096 bellard
    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
264 6f7e9aec bellard
        // No fault mode: if a mapping is available, just override
265 6f7e9aec bellard
        // permissions. If no mapping is available, redirect accesses to
266 6f7e9aec bellard
        // neverland. Fake/overridden mappings will be flushed when
267 6f7e9aec bellard
        // switching to normal mode.
268 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
269 227671c9 bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
270 6ebbf390 j_mayer
        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
271 0f8a249a blueswir1
        return ret;
272 7483750d bellard
    } else {
273 7483750d bellard
        if (rw & 2)
274 7483750d bellard
            env->exception_index = TT_TFAULT;
275 7483750d bellard
        else
276 7483750d bellard
            env->exception_index = TT_DFAULT;
277 7483750d bellard
        return 1;
278 878d3096 bellard
    }
279 e8af50a3 bellard
}
280 24741ef3 bellard
281 24741ef3 bellard
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
282 24741ef3 bellard
{
283 24741ef3 bellard
    target_phys_addr_t pde_ptr;
284 24741ef3 bellard
    uint32_t pde;
285 24741ef3 bellard
286 24741ef3 bellard
    /* Context base + context number */
287 5dcb6b91 blueswir1
    pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
288 5dcb6b91 blueswir1
        (env->mmuregs[2] << 2);
289 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
290 24741ef3 bellard
291 24741ef3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
292 24741ef3 bellard
    default:
293 24741ef3 bellard
    case 0: /* Invalid */
294 24741ef3 bellard
    case 2: /* PTE, maybe should not happen? */
295 24741ef3 bellard
    case 3: /* Reserved */
296 0f8a249a blueswir1
        return 0;
297 24741ef3 bellard
    case 1: /* L1 PDE */
298 0f8a249a blueswir1
        if (mmulev == 3)
299 0f8a249a blueswir1
            return pde;
300 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
301 24741ef3 bellard
        pde = ldl_phys(pde_ptr);
302 24741ef3 bellard
303 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
304 0f8a249a blueswir1
        default:
305 0f8a249a blueswir1
        case 0: /* Invalid */
306 0f8a249a blueswir1
        case 3: /* Reserved */
307 0f8a249a blueswir1
            return 0;
308 0f8a249a blueswir1
        case 2: /* L1 PTE */
309 0f8a249a blueswir1
            return pde;
310 0f8a249a blueswir1
        case 1: /* L2 PDE */
311 0f8a249a blueswir1
            if (mmulev == 2)
312 0f8a249a blueswir1
                return pde;
313 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
314 24741ef3 bellard
            pde = ldl_phys(pde_ptr);
315 24741ef3 bellard
316 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
317 0f8a249a blueswir1
            default:
318 0f8a249a blueswir1
            case 0: /* Invalid */
319 0f8a249a blueswir1
            case 3: /* Reserved */
320 0f8a249a blueswir1
                return 0;
321 0f8a249a blueswir1
            case 2: /* L2 PTE */
322 0f8a249a blueswir1
                return pde;
323 0f8a249a blueswir1
            case 1: /* L3 PDE */
324 0f8a249a blueswir1
                if (mmulev == 1)
325 0f8a249a blueswir1
                    return pde;
326 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
327 24741ef3 bellard
                pde = ldl_phys(pde_ptr);
328 24741ef3 bellard
329 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
330 0f8a249a blueswir1
                default:
331 0f8a249a blueswir1
                case 0: /* Invalid */
332 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
333 0f8a249a blueswir1
                case 3: /* Reserved */
334 0f8a249a blueswir1
                    return 0;
335 0f8a249a blueswir1
                case 2: /* L3 PTE */
336 0f8a249a blueswir1
                    return pde;
337 0f8a249a blueswir1
                }
338 0f8a249a blueswir1
            }
339 0f8a249a blueswir1
        }
340 24741ef3 bellard
    }
341 24741ef3 bellard
    return 0;
342 24741ef3 bellard
}
343 24741ef3 bellard
344 24741ef3 bellard
#ifdef DEBUG_MMU
345 24741ef3 bellard
void dump_mmu(CPUState *env)
346 24741ef3 bellard
{
347 5dcb6b91 blueswir1
    target_ulong va, va1, va2;
348 5dcb6b91 blueswir1
    unsigned int n, m, o;
349 5dcb6b91 blueswir1
    target_phys_addr_t pde_ptr, pa;
350 24741ef3 bellard
    uint32_t pde;
351 24741ef3 bellard
352 24741ef3 bellard
    printf("MMU dump:\n");
353 24741ef3 bellard
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
354 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
355 5dcb6b91 blueswir1
    printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
356 5dcb6b91 blueswir1
           (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
357 24741ef3 bellard
    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
358 0f8a249a blueswir1
        pde = mmu_probe(env, va, 2);
359 0f8a249a blueswir1
        if (pde) {
360 0f8a249a blueswir1
            pa = cpu_get_phys_page_debug(env, va);
361 0f8a249a blueswir1
            printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
362 5dcb6b91 blueswir1
                   " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
363 0f8a249a blueswir1
            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
364 0f8a249a blueswir1
                pde = mmu_probe(env, va1, 1);
365 0f8a249a blueswir1
                if (pde) {
366 0f8a249a blueswir1
                    pa = cpu_get_phys_page_debug(env, va1);
367 0f8a249a blueswir1
                    printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
368 5dcb6b91 blueswir1
                           " PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
369 0f8a249a blueswir1
                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
370 0f8a249a blueswir1
                        pde = mmu_probe(env, va2, 0);
371 0f8a249a blueswir1
                        if (pde) {
372 0f8a249a blueswir1
                            pa = cpu_get_phys_page_debug(env, va2);
373 0f8a249a blueswir1
                            printf("  VA: " TARGET_FMT_lx ", PA: "
374 5dcb6b91 blueswir1
                                   TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
375 5dcb6b91 blueswir1
                                   va2, pa, pde);
376 0f8a249a blueswir1
                        }
377 0f8a249a blueswir1
                    }
378 0f8a249a blueswir1
                }
379 0f8a249a blueswir1
            }
380 0f8a249a blueswir1
        }
381 24741ef3 bellard
    }
382 24741ef3 bellard
    printf("MMU dump ends\n");
383 24741ef3 bellard
}
384 24741ef3 bellard
#endif /* DEBUG_MMU */
385 24741ef3 bellard
386 24741ef3 bellard
#else /* !TARGET_SPARC64 */
387 83469015 bellard
/*
388 83469015 bellard
 * UltraSparc IIi I/DMMUs
389 83469015 bellard
 */
390 3475187d bellard
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
391 22548760 blueswir1
                                     target_ulong address, int rw, int is_user)
392 3475187d bellard
{
393 3475187d bellard
    target_ulong mask;
394 3475187d bellard
    unsigned int i;
395 3475187d bellard
396 3475187d bellard
    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
397 0f8a249a blueswir1
        *physical = address;
398 0f8a249a blueswir1
        *prot = PAGE_READ | PAGE_WRITE;
399 3475187d bellard
        return 0;
400 3475187d bellard
    }
401 3475187d bellard
402 3475187d bellard
    for (i = 0; i < 64; i++) {
403 0f8a249a blueswir1
        switch ((env->dtlb_tte[i] >> 61) & 3) {
404 0f8a249a blueswir1
        default:
405 0f8a249a blueswir1
        case 0x0: // 8k
406 0f8a249a blueswir1
            mask = 0xffffffffffffe000ULL;
407 0f8a249a blueswir1
            break;
408 0f8a249a blueswir1
        case 0x1: // 64k
409 0f8a249a blueswir1
            mask = 0xffffffffffff0000ULL;
410 0f8a249a blueswir1
            break;
411 0f8a249a blueswir1
        case 0x2: // 512k
412 0f8a249a blueswir1
            mask = 0xfffffffffff80000ULL;
413 0f8a249a blueswir1
            break;
414 0f8a249a blueswir1
        case 0x3: // 4M
415 0f8a249a blueswir1
            mask = 0xffffffffffc00000ULL;
416 0f8a249a blueswir1
            break;
417 0f8a249a blueswir1
        }
418 0f8a249a blueswir1
        // ctx match, vaddr match?
419 0f8a249a blueswir1
        if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
420 0f8a249a blueswir1
            (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
421 0f8a249a blueswir1
            // valid, access ok?
422 0f8a249a blueswir1
            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
423 0f8a249a blueswir1
                ((env->dtlb_tte[i] & 0x4) && is_user) ||
424 0f8a249a blueswir1
                (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
425 0f8a249a blueswir1
                if (env->dmmuregs[3]) /* Fault status register */
426 0f8a249a blueswir1
                    env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
427 0f8a249a blueswir1
                env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
428 0f8a249a blueswir1
                env->dmmuregs[4] = address; /* Fault address register */
429 0f8a249a blueswir1
                env->exception_index = TT_DFAULT;
430 83469015 bellard
#ifdef DEBUG_MMU
431 0f8a249a blueswir1
                printf("DFAULT at 0x%" PRIx64 "\n", address);
432 83469015 bellard
#endif
433 0f8a249a blueswir1
                return 1;
434 0f8a249a blueswir1
            }
435 0f8a249a blueswir1
            *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
436 0f8a249a blueswir1
            *prot = PAGE_READ;
437 0f8a249a blueswir1
            if (env->dtlb_tte[i] & 0x2)
438 0f8a249a blueswir1
                *prot |= PAGE_WRITE;
439 0f8a249a blueswir1
            return 0;
440 0f8a249a blueswir1
        }
441 3475187d bellard
    }
442 83469015 bellard
#ifdef DEBUG_MMU
443 26a76461 bellard
    printf("DMISS at 0x%" PRIx64 "\n", address);
444 83469015 bellard
#endif
445 83469015 bellard
    env->exception_index = TT_DMISS;
446 3475187d bellard
    return 1;
447 3475187d bellard
}
448 3475187d bellard
449 3475187d bellard
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
450 22548760 blueswir1
                                     target_ulong address, int is_user)
451 3475187d bellard
{
452 3475187d bellard
    target_ulong mask;
453 3475187d bellard
    unsigned int i;
454 3475187d bellard
455 3475187d bellard
    if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
456 0f8a249a blueswir1
        *physical = address;
457 0f8a249a blueswir1
        *prot = PAGE_EXEC;
458 3475187d bellard
        return 0;
459 3475187d bellard
    }
460 83469015 bellard
461 3475187d bellard
    for (i = 0; i < 64; i++) {
462 0f8a249a blueswir1
        switch ((env->itlb_tte[i] >> 61) & 3) {
463 0f8a249a blueswir1
        default:
464 0f8a249a blueswir1
        case 0x0: // 8k
465 0f8a249a blueswir1
            mask = 0xffffffffffffe000ULL;
466 0f8a249a blueswir1
            break;
467 0f8a249a blueswir1
        case 0x1: // 64k
468 0f8a249a blueswir1
            mask = 0xffffffffffff0000ULL;
469 0f8a249a blueswir1
            break;
470 0f8a249a blueswir1
        case 0x2: // 512k
471 0f8a249a blueswir1
            mask = 0xfffffffffff80000ULL;
472 0f8a249a blueswir1
            break;
473 0f8a249a blueswir1
        case 0x3: // 4M
474 0f8a249a blueswir1
            mask = 0xffffffffffc00000ULL;
475 0f8a249a blueswir1
                break;
476 0f8a249a blueswir1
        }
477 0f8a249a blueswir1
        // ctx match, vaddr match?
478 0f8a249a blueswir1
        if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
479 0f8a249a blueswir1
            (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
480 0f8a249a blueswir1
            // valid, access ok?
481 0f8a249a blueswir1
            if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
482 0f8a249a blueswir1
                ((env->itlb_tte[i] & 0x4) && is_user)) {
483 0f8a249a blueswir1
                if (env->immuregs[3]) /* Fault status register */
484 0f8a249a blueswir1
                    env->immuregs[3] = 2; /* overflow (not read before another fault) */
485 0f8a249a blueswir1
                env->immuregs[3] |= (is_user << 3) | 1;
486 0f8a249a blueswir1
                env->exception_index = TT_TFAULT;
487 83469015 bellard
#ifdef DEBUG_MMU
488 0f8a249a blueswir1
                printf("TFAULT at 0x%" PRIx64 "\n", address);
489 83469015 bellard
#endif
490 0f8a249a blueswir1
                return 1;
491 0f8a249a blueswir1
            }
492 0f8a249a blueswir1
            *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
493 0f8a249a blueswir1
            *prot = PAGE_EXEC;
494 0f8a249a blueswir1
            return 0;
495 0f8a249a blueswir1
        }
496 3475187d bellard
    }
497 83469015 bellard
#ifdef DEBUG_MMU
498 26a76461 bellard
    printf("TMISS at 0x%" PRIx64 "\n", address);
499 83469015 bellard
#endif
500 83469015 bellard
    env->exception_index = TT_TMISS;
501 3475187d bellard
    return 1;
502 3475187d bellard
}
503 3475187d bellard
504 c48fcb47 blueswir1
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
505 c48fcb47 blueswir1
                                int *prot, int *access_index,
506 c48fcb47 blueswir1
                                target_ulong address, int rw, int mmu_idx)
507 3475187d bellard
{
508 6ebbf390 j_mayer
    int is_user = mmu_idx == MMU_USER_IDX;
509 6ebbf390 j_mayer
510 3475187d bellard
    if (rw == 2)
511 22548760 blueswir1
        return get_physical_address_code(env, physical, prot, address,
512 22548760 blueswir1
                                         is_user);
513 3475187d bellard
    else
514 22548760 blueswir1
        return get_physical_address_data(env, physical, prot, address, rw,
515 22548760 blueswir1
                                         is_user);
516 3475187d bellard
}
517 3475187d bellard
518 3475187d bellard
/* Perform address translation */
519 3475187d bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
520 6ebbf390 j_mayer
                              int mmu_idx, int is_softmmu)
521 3475187d bellard
{
522 83469015 bellard
    target_ulong virt_addr, vaddr;
523 3475187d bellard
    target_phys_addr_t paddr;
524 3475187d bellard
    int error_code = 0, prot, ret = 0, access_index;
525 3475187d bellard
526 6ebbf390 j_mayer
    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
527 3475187d bellard
    if (error_code == 0) {
528 0f8a249a blueswir1
        virt_addr = address & TARGET_PAGE_MASK;
529 0f8a249a blueswir1
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
530 83469015 bellard
#ifdef DEBUG_MMU
531 0f8a249a blueswir1
        printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
532 83469015 bellard
#endif
533 6ebbf390 j_mayer
        ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
534 0f8a249a blueswir1
        return ret;
535 3475187d bellard
    }
536 3475187d bellard
    // XXX
537 3475187d bellard
    return 1;
538 3475187d bellard
}
539 3475187d bellard
540 83469015 bellard
#ifdef DEBUG_MMU
541 83469015 bellard
void dump_mmu(CPUState *env)
542 83469015 bellard
{
543 83469015 bellard
    unsigned int i;
544 83469015 bellard
    const char *mask;
545 83469015 bellard
546 26a76461 bellard
    printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n", 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 0f8a249a blueswir1
                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
569 0f8a249a blueswir1
                       env->dtlb_tag[i] & ~0x1fffULL,
570 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x1ffffffe000ULL,
571 0f8a249a blueswir1
                       mask,
572 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x4? "priv": "user",
573 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x2? "RW": "RO",
574 0f8a249a blueswir1
                       env->dtlb_tte[i] & 0x40? "locked": "unlocked",
575 0f8a249a blueswir1
                       env->dtlb_tag[i] & 0x1fffULL);
576 0f8a249a blueswir1
            }
577 0f8a249a blueswir1
        }
578 83469015 bellard
    }
579 83469015 bellard
    if ((env->lsu & IMMU_E) == 0) {
580 0f8a249a blueswir1
        printf("IMMU disabled\n");
581 83469015 bellard
    } else {
582 0f8a249a blueswir1
        printf("IMMU dump:\n");
583 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
584 0f8a249a blueswir1
            switch ((env->itlb_tte[i] >> 61) & 3) {
585 0f8a249a blueswir1
            default:
586 0f8a249a blueswir1
            case 0x0:
587 0f8a249a blueswir1
                mask = "  8k";
588 0f8a249a blueswir1
                break;
589 0f8a249a blueswir1
            case 0x1:
590 0f8a249a blueswir1
                mask = " 64k";
591 0f8a249a blueswir1
                break;
592 0f8a249a blueswir1
            case 0x2:
593 0f8a249a blueswir1
                mask = "512k";
594 0f8a249a blueswir1
                break;
595 0f8a249a blueswir1
            case 0x3:
596 0f8a249a blueswir1
                mask = "  4M";
597 0f8a249a blueswir1
                break;
598 0f8a249a blueswir1
            }
599 0f8a249a blueswir1
            if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
600 0f8a249a blueswir1
                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
601 0f8a249a blueswir1
                       env->itlb_tag[i] & ~0x1fffULL,
602 0f8a249a blueswir1
                       env->itlb_tte[i] & 0x1ffffffe000ULL,
603 0f8a249a blueswir1
                       mask,
604 0f8a249a blueswir1
                       env->itlb_tte[i] & 0x4? "priv": "user",
605 0f8a249a blueswir1
                       env->itlb_tte[i] & 0x40? "locked": "unlocked",
606 0f8a249a blueswir1
                       env->itlb_tag[i] & 0x1fffULL);
607 0f8a249a blueswir1
            }
608 0f8a249a blueswir1
        }
609 83469015 bellard
    }
610 83469015 bellard
}
611 24741ef3 bellard
#endif /* DEBUG_MMU */
612 24741ef3 bellard
613 24741ef3 bellard
#endif /* TARGET_SPARC64 */
614 24741ef3 bellard
#endif /* !CONFIG_USER_ONLY */
615 24741ef3 bellard
616 c48fcb47 blueswir1
617 c48fcb47 blueswir1
#if defined(CONFIG_USER_ONLY)
618 c48fcb47 blueswir1
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
619 c48fcb47 blueswir1
{
620 c48fcb47 blueswir1
    return addr;
621 c48fcb47 blueswir1
}
622 c48fcb47 blueswir1
623 c48fcb47 blueswir1
#else
624 c48fcb47 blueswir1
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
625 c48fcb47 blueswir1
{
626 c48fcb47 blueswir1
    target_phys_addr_t phys_addr;
627 c48fcb47 blueswir1
    int prot, access_index;
628 c48fcb47 blueswir1
629 c48fcb47 blueswir1
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
630 c48fcb47 blueswir1
                             MMU_KERNEL_IDX) != 0)
631 c48fcb47 blueswir1
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
632 c48fcb47 blueswir1
                                 0, MMU_KERNEL_IDX) != 0)
633 c48fcb47 blueswir1
            return -1;
634 c48fcb47 blueswir1
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
635 c48fcb47 blueswir1
        return -1;
636 c48fcb47 blueswir1
    return phys_addr;
637 c48fcb47 blueswir1
}
638 c48fcb47 blueswir1
#endif
639 c48fcb47 blueswir1
640 24741ef3 bellard
void memcpy32(target_ulong *dst, const target_ulong *src)
641 24741ef3 bellard
{
642 24741ef3 bellard
    dst[0] = src[0];
643 24741ef3 bellard
    dst[1] = src[1];
644 24741ef3 bellard
    dst[2] = src[2];
645 24741ef3 bellard
    dst[3] = src[3];
646 24741ef3 bellard
    dst[4] = src[4];
647 24741ef3 bellard
    dst[5] = src[5];
648 24741ef3 bellard
    dst[6] = src[6];
649 24741ef3 bellard
    dst[7] = src[7];
650 24741ef3 bellard
}
651 87ecb68b pbrook
652 c48fcb47 blueswir1
void helper_flush(target_ulong addr)
653 c48fcb47 blueswir1
{
654 c48fcb47 blueswir1
    addr &= ~7;
655 c48fcb47 blueswir1
    tb_invalidate_page_range(addr, addr + 8);
656 c48fcb47 blueswir1
}
657 c48fcb47 blueswir1
658 c48fcb47 blueswir1
void cpu_reset(CPUSPARCState *env)
659 c48fcb47 blueswir1
{
660 c48fcb47 blueswir1
    tlb_flush(env, 1);
661 c48fcb47 blueswir1
    env->cwp = 0;
662 c48fcb47 blueswir1
    env->wim = 1;
663 c48fcb47 blueswir1
    env->regwptr = env->regbase + (env->cwp * 16);
664 c48fcb47 blueswir1
#if defined(CONFIG_USER_ONLY)
665 c48fcb47 blueswir1
    env->user_mode_only = 1;
666 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
667 c48fcb47 blueswir1
    env->cleanwin = NWINDOWS - 2;
668 c48fcb47 blueswir1
    env->cansave = NWINDOWS - 2;
669 c48fcb47 blueswir1
    env->pstate = PS_RMO | PS_PEF | PS_IE;
670 c48fcb47 blueswir1
    env->asi = 0x82; // Primary no-fault
671 c48fcb47 blueswir1
#endif
672 c48fcb47 blueswir1
#else
673 c48fcb47 blueswir1
    env->psret = 0;
674 c48fcb47 blueswir1
    env->psrs = 1;
675 c48fcb47 blueswir1
    env->psrps = 1;
676 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
677 c48fcb47 blueswir1
    env->pstate = PS_PRIV;
678 c48fcb47 blueswir1
    env->hpstate = HS_PRIV;
679 c48fcb47 blueswir1
    env->pc = 0x1fff0000000ULL;
680 c48fcb47 blueswir1
    env->tsptr = &env->ts[env->tl];
681 c48fcb47 blueswir1
#else
682 c48fcb47 blueswir1
    env->pc = 0;
683 c48fcb47 blueswir1
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
684 c48fcb47 blueswir1
    env->mmuregs[0] |= env->mmu_bm;
685 c48fcb47 blueswir1
#endif
686 c48fcb47 blueswir1
    env->npc = env->pc + 4;
687 c48fcb47 blueswir1
#endif
688 c48fcb47 blueswir1
}
689 c48fcb47 blueswir1
690 64a88d5d blueswir1
static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
691 c48fcb47 blueswir1
{
692 64a88d5d blueswir1
    sparc_def_t def1, *def = &def1;
693 c48fcb47 blueswir1
694 64a88d5d blueswir1
    if (cpu_sparc_find_by_name(def, cpu_model) < 0)
695 64a88d5d blueswir1
        return -1;
696 c48fcb47 blueswir1
697 64a88d5d blueswir1
    env->features = def->features;
698 c48fcb47 blueswir1
    env->cpu_model_str = cpu_model;
699 c48fcb47 blueswir1
    env->version = def->iu_version;
700 c48fcb47 blueswir1
    env->fsr = def->fpu_version;
701 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
702 c48fcb47 blueswir1
    env->mmu_bm = def->mmu_bm;
703 c48fcb47 blueswir1
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
704 c48fcb47 blueswir1
    env->mmu_cxr_mask = def->mmu_cxr_mask;
705 c48fcb47 blueswir1
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
706 c48fcb47 blueswir1
    env->mmu_trcr_mask = def->mmu_trcr_mask;
707 c48fcb47 blueswir1
    env->mmuregs[0] |= def->mmu_version;
708 c48fcb47 blueswir1
    cpu_sparc_set_id(env, 0);
709 c48fcb47 blueswir1
#endif
710 64a88d5d blueswir1
    return 0;
711 64a88d5d blueswir1
}
712 64a88d5d blueswir1
713 64a88d5d blueswir1
static void cpu_sparc_close(CPUSPARCState *env)
714 64a88d5d blueswir1
{
715 64a88d5d blueswir1
    free(env);
716 64a88d5d blueswir1
}
717 64a88d5d blueswir1
718 64a88d5d blueswir1
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
719 64a88d5d blueswir1
{
720 64a88d5d blueswir1
    CPUSPARCState *env;
721 64a88d5d blueswir1
722 64a88d5d blueswir1
    env = qemu_mallocz(sizeof(CPUSPARCState));
723 64a88d5d blueswir1
    if (!env)
724 64a88d5d blueswir1
        return NULL;
725 64a88d5d blueswir1
    cpu_exec_init(env);
726 c48fcb47 blueswir1
727 c48fcb47 blueswir1
    gen_intermediate_code_init(env);
728 c48fcb47 blueswir1
729 64a88d5d blueswir1
    if (cpu_sparc_register(env, cpu_model) < 0) {
730 64a88d5d blueswir1
        cpu_sparc_close(env);
731 64a88d5d blueswir1
        return NULL;
732 64a88d5d blueswir1
    }
733 c48fcb47 blueswir1
    cpu_reset(env);
734 c48fcb47 blueswir1
735 c48fcb47 blueswir1
    return env;
736 c48fcb47 blueswir1
}
737 c48fcb47 blueswir1
738 c48fcb47 blueswir1
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
739 c48fcb47 blueswir1
{
740 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
741 c48fcb47 blueswir1
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
742 c48fcb47 blueswir1
#endif
743 c48fcb47 blueswir1
}
744 c48fcb47 blueswir1
745 c48fcb47 blueswir1
static const sparc_def_t sparc_defs[] = {
746 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
747 c48fcb47 blueswir1
    {
748 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64",
749 c48fcb47 blueswir1
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
750 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
751 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
752 c48fcb47 blueswir1
        .mmu_version = 0,
753 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
754 c48fcb47 blueswir1
    },
755 c48fcb47 blueswir1
    {
756 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 III",
757 c48fcb47 blueswir1
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
758 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
759 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
760 c48fcb47 blueswir1
        .mmu_version = 0,
761 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
762 c48fcb47 blueswir1
    },
763 c48fcb47 blueswir1
    {
764 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 IV",
765 c48fcb47 blueswir1
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
766 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
767 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
768 c48fcb47 blueswir1
        .mmu_version = 0,
769 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
770 c48fcb47 blueswir1
    },
771 c48fcb47 blueswir1
    {
772 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 V",
773 c48fcb47 blueswir1
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
774 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
775 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
776 c48fcb47 blueswir1
        .mmu_version = 0,
777 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
778 c48fcb47 blueswir1
    },
779 c48fcb47 blueswir1
    {
780 c48fcb47 blueswir1
        .name = "TI UltraSparc I",
781 c48fcb47 blueswir1
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
782 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
783 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
784 c48fcb47 blueswir1
        .mmu_version = 0,
785 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
786 c48fcb47 blueswir1
    },
787 c48fcb47 blueswir1
    {
788 c48fcb47 blueswir1
        .name = "TI UltraSparc II",
789 c48fcb47 blueswir1
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
790 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
791 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
792 c48fcb47 blueswir1
        .mmu_version = 0,
793 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
794 c48fcb47 blueswir1
    },
795 c48fcb47 blueswir1
    {
796 c48fcb47 blueswir1
        .name = "TI UltraSparc IIi",
797 c48fcb47 blueswir1
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
798 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
799 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
800 c48fcb47 blueswir1
        .mmu_version = 0,
801 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
802 c48fcb47 blueswir1
    },
803 c48fcb47 blueswir1
    {
804 c48fcb47 blueswir1
        .name = "TI UltraSparc IIe",
805 c48fcb47 blueswir1
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
806 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
807 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
808 c48fcb47 blueswir1
        .mmu_version = 0,
809 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
810 c48fcb47 blueswir1
    },
811 c48fcb47 blueswir1
    {
812 c48fcb47 blueswir1
        .name = "Sun UltraSparc III",
813 c48fcb47 blueswir1
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
814 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
815 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
816 c48fcb47 blueswir1
        .mmu_version = 0,
817 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
818 c48fcb47 blueswir1
    },
819 c48fcb47 blueswir1
    {
820 c48fcb47 blueswir1
        .name = "Sun UltraSparc III Cu",
821 c48fcb47 blueswir1
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
822 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
823 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
824 c48fcb47 blueswir1
        .mmu_version = 0,
825 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
826 c48fcb47 blueswir1
    },
827 c48fcb47 blueswir1
    {
828 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi",
829 c48fcb47 blueswir1
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
830 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
831 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
832 c48fcb47 blueswir1
        .mmu_version = 0,
833 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
834 c48fcb47 blueswir1
    },
835 c48fcb47 blueswir1
    {
836 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV",
837 c48fcb47 blueswir1
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
838 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
839 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
840 c48fcb47 blueswir1
        .mmu_version = 0,
841 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
842 c48fcb47 blueswir1
    },
843 c48fcb47 blueswir1
    {
844 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV+",
845 c48fcb47 blueswir1
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
846 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
847 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
848 c48fcb47 blueswir1
        .mmu_version = 0,
849 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
850 c48fcb47 blueswir1
    },
851 c48fcb47 blueswir1
    {
852 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi+",
853 c48fcb47 blueswir1
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
854 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
855 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
856 c48fcb47 blueswir1
        .mmu_version = 0,
857 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
858 c48fcb47 blueswir1
    },
859 c48fcb47 blueswir1
    {
860 c48fcb47 blueswir1
        .name = "NEC UltraSparc I",
861 c48fcb47 blueswir1
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
862 c48fcb47 blueswir1
                       | (MAXTL << 8) | (NWINDOWS - 1)),
863 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
864 c48fcb47 blueswir1
        .mmu_version = 0,
865 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
866 c48fcb47 blueswir1
    },
867 c48fcb47 blueswir1
#else
868 c48fcb47 blueswir1
    {
869 c48fcb47 blueswir1
        .name = "Fujitsu MB86900",
870 c48fcb47 blueswir1
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
871 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
872 c48fcb47 blueswir1
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
873 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
874 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
875 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
876 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
877 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
878 64a88d5d blueswir1
        .features = CPU_FEATURE_FLOAT,
879 c48fcb47 blueswir1
    },
880 c48fcb47 blueswir1
    {
881 c48fcb47 blueswir1
        .name = "Fujitsu MB86904",
882 c48fcb47 blueswir1
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
883 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
884 c48fcb47 blueswir1
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
885 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
886 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
887 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
888 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
889 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
890 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
891 c48fcb47 blueswir1
    },
892 c48fcb47 blueswir1
    {
893 c48fcb47 blueswir1
        .name = "Fujitsu MB86907",
894 c48fcb47 blueswir1
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
895 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
896 c48fcb47 blueswir1
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
897 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
898 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
899 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
900 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
901 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
902 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
903 c48fcb47 blueswir1
    },
904 c48fcb47 blueswir1
    {
905 c48fcb47 blueswir1
        .name = "LSI L64811",
906 c48fcb47 blueswir1
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
907 c48fcb47 blueswir1
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
908 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
909 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
910 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
911 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
912 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
913 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
914 64a88d5d blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
915 c48fcb47 blueswir1
    },
916 c48fcb47 blueswir1
    {
917 c48fcb47 blueswir1
        .name = "Cypress CY7C601",
918 c48fcb47 blueswir1
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
919 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
920 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
921 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
922 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
923 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
924 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
925 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
926 64a88d5d blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
927 c48fcb47 blueswir1
    },
928 c48fcb47 blueswir1
    {
929 c48fcb47 blueswir1
        .name = "Cypress CY7C611",
930 c48fcb47 blueswir1
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
931 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
932 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
933 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
934 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
935 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
936 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
937 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
938 64a88d5d blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
939 c48fcb47 blueswir1
    },
940 c48fcb47 blueswir1
    {
941 c48fcb47 blueswir1
        .name = "TI SuperSparc II",
942 c48fcb47 blueswir1
        .iu_version = 0x40000000,
943 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
944 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
945 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
946 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
947 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
948 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
949 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
950 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
951 c48fcb47 blueswir1
    },
952 c48fcb47 blueswir1
    {
953 c48fcb47 blueswir1
        .name = "TI MicroSparc I",
954 c48fcb47 blueswir1
        .iu_version = 0x41000000,
955 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
956 c48fcb47 blueswir1
        .mmu_version = 0x41000000,
957 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
958 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
959 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
960 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
961 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x0000003f,
962 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
963 c48fcb47 blueswir1
    },
964 c48fcb47 blueswir1
    {
965 c48fcb47 blueswir1
        .name = "TI MicroSparc II",
966 c48fcb47 blueswir1
        .iu_version = 0x42000000,
967 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
968 c48fcb47 blueswir1
        .mmu_version = 0x02000000,
969 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
970 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
971 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
972 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
973 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
974 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
975 c48fcb47 blueswir1
    },
976 c48fcb47 blueswir1
    {
977 c48fcb47 blueswir1
        .name = "TI MicroSparc IIep",
978 c48fcb47 blueswir1
        .iu_version = 0x42000000,
979 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
980 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
981 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
982 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
983 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
984 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016bff,
985 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
986 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
987 c48fcb47 blueswir1
    },
988 c48fcb47 blueswir1
    {
989 c48fcb47 blueswir1
        .name = "TI SuperSparc 51",
990 c48fcb47 blueswir1
        .iu_version = 0x43000000,
991 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
992 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
993 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
994 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
995 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
996 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
997 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
998 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
999 c48fcb47 blueswir1
    },
1000 c48fcb47 blueswir1
    {
1001 c48fcb47 blueswir1
        .name = "TI SuperSparc 61",
1002 c48fcb47 blueswir1
        .iu_version = 0x44000000,
1003 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1004 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1005 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1006 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1007 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1008 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1009 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1010 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1011 c48fcb47 blueswir1
    },
1012 c48fcb47 blueswir1
    {
1013 c48fcb47 blueswir1
        .name = "Ross RT625",
1014 c48fcb47 blueswir1
        .iu_version = 0x1e000000,
1015 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1016 c48fcb47 blueswir1
        .mmu_version = 0x1e000000,
1017 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1018 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1019 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1020 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1021 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1022 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1023 c48fcb47 blueswir1
    },
1024 c48fcb47 blueswir1
    {
1025 c48fcb47 blueswir1
        .name = "Ross RT620",
1026 c48fcb47 blueswir1
        .iu_version = 0x1f000000,
1027 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1028 c48fcb47 blueswir1
        .mmu_version = 0x1f000000,
1029 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1030 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1031 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1032 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1033 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1034 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1035 c48fcb47 blueswir1
    },
1036 c48fcb47 blueswir1
    {
1037 c48fcb47 blueswir1
        .name = "BIT B5010",
1038 c48fcb47 blueswir1
        .iu_version = 0x20000000,
1039 c48fcb47 blueswir1
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
1040 c48fcb47 blueswir1
        .mmu_version = 0x20000000,
1041 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1042 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1043 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1044 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1045 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1046 64a88d5d blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
1047 c48fcb47 blueswir1
    },
1048 c48fcb47 blueswir1
    {
1049 c48fcb47 blueswir1
        .name = "Matsushita MN10501",
1050 c48fcb47 blueswir1
        .iu_version = 0x50000000,
1051 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1052 c48fcb47 blueswir1
        .mmu_version = 0x50000000,
1053 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1054 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1055 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1056 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1057 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1058 64a88d5d blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT,
1059 c48fcb47 blueswir1
    },
1060 c48fcb47 blueswir1
    {
1061 c48fcb47 blueswir1
        .name = "Weitek W8601",
1062 c48fcb47 blueswir1
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
1063 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
1064 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1065 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1066 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1067 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1068 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1069 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1070 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1071 c48fcb47 blueswir1
    },
1072 c48fcb47 blueswir1
    {
1073 c48fcb47 blueswir1
        .name = "LEON2",
1074 c48fcb47 blueswir1
        .iu_version = 0xf2000000,
1075 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1076 c48fcb47 blueswir1
        .mmu_version = 0xf2000000,
1077 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1078 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1079 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1080 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1081 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1082 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1083 c48fcb47 blueswir1
    },
1084 c48fcb47 blueswir1
    {
1085 c48fcb47 blueswir1
        .name = "LEON3",
1086 c48fcb47 blueswir1
        .iu_version = 0xf3000000,
1087 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1088 c48fcb47 blueswir1
        .mmu_version = 0xf3000000,
1089 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1090 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1091 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1092 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1093 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1094 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1095 c48fcb47 blueswir1
    },
1096 c48fcb47 blueswir1
#endif
1097 c48fcb47 blueswir1
};
1098 c48fcb47 blueswir1
1099 64a88d5d blueswir1
static const char * const feature_name[] = {
1100 64a88d5d blueswir1
    "float",
1101 64a88d5d blueswir1
    "float128",
1102 64a88d5d blueswir1
    "swap",
1103 64a88d5d blueswir1
    "mul",
1104 64a88d5d blueswir1
    "div",
1105 64a88d5d blueswir1
    "flush",
1106 64a88d5d blueswir1
    "fsqrt",
1107 64a88d5d blueswir1
    "fmul",
1108 64a88d5d blueswir1
    "vis1",
1109 64a88d5d blueswir1
    "vis2",
1110 64a88d5d blueswir1
};
1111 64a88d5d blueswir1
1112 64a88d5d blueswir1
static void print_features(FILE *f,
1113 64a88d5d blueswir1
                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1114 64a88d5d blueswir1
                           uint32_t features, const char *prefix)
1115 c48fcb47 blueswir1
{
1116 c48fcb47 blueswir1
    unsigned int i;
1117 c48fcb47 blueswir1
1118 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1119 64a88d5d blueswir1
        if (feature_name[i] && (features & (1 << i))) {
1120 64a88d5d blueswir1
            if (prefix)
1121 64a88d5d blueswir1
                (*cpu_fprintf)(f, "%s", prefix);
1122 64a88d5d blueswir1
            (*cpu_fprintf)(f, "%s ", feature_name[i]);
1123 64a88d5d blueswir1
        }
1124 64a88d5d blueswir1
}
1125 64a88d5d blueswir1
1126 64a88d5d blueswir1
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
1127 64a88d5d blueswir1
{
1128 64a88d5d blueswir1
    unsigned int i;
1129 64a88d5d blueswir1
1130 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1131 64a88d5d blueswir1
        if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
1132 64a88d5d blueswir1
            *features |= 1 << i;
1133 64a88d5d blueswir1
            return;
1134 64a88d5d blueswir1
        }
1135 64a88d5d blueswir1
    fprintf(stderr, "CPU feature %s not found\n", flagname);
1136 64a88d5d blueswir1
}
1137 64a88d5d blueswir1
1138 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
1139 64a88d5d blueswir1
{
1140 64a88d5d blueswir1
    unsigned int i;
1141 64a88d5d blueswir1
    const sparc_def_t *def = NULL;
1142 64a88d5d blueswir1
    char *s = strdup(cpu_model);
1143 64a88d5d blueswir1
    char *featurestr, *name = strtok(s, ",");
1144 64a88d5d blueswir1
    uint32_t plus_features = 0;
1145 64a88d5d blueswir1
    uint32_t minus_features = 0;
1146 64a88d5d blueswir1
    long long iu_version;
1147 64a88d5d blueswir1
    uint32_t fpu_version, mmu_version;
1148 64a88d5d blueswir1
1149 c48fcb47 blueswir1
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1150 c48fcb47 blueswir1
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
1151 64a88d5d blueswir1
            def = &sparc_defs[i];
1152 c48fcb47 blueswir1
        }
1153 c48fcb47 blueswir1
    }
1154 64a88d5d blueswir1
    if (!def)
1155 64a88d5d blueswir1
        goto error;
1156 64a88d5d blueswir1
    memcpy(cpu_def, def, sizeof(*def));
1157 64a88d5d blueswir1
1158 64a88d5d blueswir1
    featurestr = strtok(NULL, ",");
1159 64a88d5d blueswir1
    while (featurestr) {
1160 64a88d5d blueswir1
        char *val;
1161 64a88d5d blueswir1
1162 64a88d5d blueswir1
        if (featurestr[0] == '+') {
1163 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &plus_features);
1164 64a88d5d blueswir1
        } else if (featurestr[0] == '-') {
1165 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &minus_features);
1166 64a88d5d blueswir1
        } else if ((val = strchr(featurestr, '='))) {
1167 64a88d5d blueswir1
            *val = 0; val++;
1168 64a88d5d blueswir1
            if (!strcmp(featurestr, "iu_version")) {
1169 64a88d5d blueswir1
                char *err;
1170 64a88d5d blueswir1
1171 64a88d5d blueswir1
                iu_version = strtoll(val, &err, 0);
1172 64a88d5d blueswir1
                if (!*val || *err) {
1173 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1174 64a88d5d blueswir1
                    goto error;
1175 64a88d5d blueswir1
                }
1176 64a88d5d blueswir1
                cpu_def->iu_version = iu_version;
1177 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1178 64a88d5d blueswir1
                fprintf(stderr, "iu_version %llx\n", iu_version);
1179 64a88d5d blueswir1
#endif
1180 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "fpu_version")) {
1181 64a88d5d blueswir1
                char *err;
1182 64a88d5d blueswir1
1183 64a88d5d blueswir1
                fpu_version = strtol(val, &err, 0);
1184 64a88d5d blueswir1
                if (!*val || *err) {
1185 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1186 64a88d5d blueswir1
                    goto error;
1187 64a88d5d blueswir1
                }
1188 64a88d5d blueswir1
                cpu_def->fpu_version = fpu_version;
1189 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1190 64a88d5d blueswir1
                fprintf(stderr, "fpu_version %llx\n", fpu_version);
1191 64a88d5d blueswir1
#endif
1192 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "mmu_version")) {
1193 64a88d5d blueswir1
                char *err;
1194 64a88d5d blueswir1
1195 64a88d5d blueswir1
                mmu_version = strtol(val, &err, 0);
1196 64a88d5d blueswir1
                if (!*val || *err) {
1197 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1198 64a88d5d blueswir1
                    goto error;
1199 64a88d5d blueswir1
                }
1200 64a88d5d blueswir1
                cpu_def->mmu_version = mmu_version;
1201 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1202 64a88d5d blueswir1
                fprintf(stderr, "mmu_version %llx\n", mmu_version);
1203 64a88d5d blueswir1
#endif
1204 64a88d5d blueswir1
            } else {
1205 64a88d5d blueswir1
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1206 64a88d5d blueswir1
                goto error;
1207 64a88d5d blueswir1
            }
1208 64a88d5d blueswir1
        } else {
1209 64a88d5d blueswir1
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
1210 64a88d5d blueswir1
            goto error;
1211 64a88d5d blueswir1
        }
1212 64a88d5d blueswir1
        featurestr = strtok(NULL, ",");
1213 64a88d5d blueswir1
    }
1214 64a88d5d blueswir1
    cpu_def->features |= plus_features;
1215 64a88d5d blueswir1
    cpu_def->features &= ~minus_features;
1216 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1217 64a88d5d blueswir1
    print_features(stderr, fprintf, cpu_def->features, NULL);
1218 64a88d5d blueswir1
#endif
1219 64a88d5d blueswir1
    free(s);
1220 64a88d5d blueswir1
    return 0;
1221 64a88d5d blueswir1
1222 64a88d5d blueswir1
 error:
1223 64a88d5d blueswir1
    free(s);
1224 64a88d5d blueswir1
    return -1;
1225 c48fcb47 blueswir1
}
1226 c48fcb47 blueswir1
1227 c48fcb47 blueswir1
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
1228 c48fcb47 blueswir1
{
1229 c48fcb47 blueswir1
    unsigned int i;
1230 c48fcb47 blueswir1
1231 c48fcb47 blueswir1
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1232 64a88d5d blueswir1
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ",
1233 c48fcb47 blueswir1
                       sparc_defs[i].name,
1234 c48fcb47 blueswir1
                       sparc_defs[i].iu_version,
1235 c48fcb47 blueswir1
                       sparc_defs[i].fpu_version,
1236 c48fcb47 blueswir1
                       sparc_defs[i].mmu_version);
1237 64a88d5d blueswir1
        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & ~sparc_defs[i].features, "-");
1238 64a88d5d blueswir1
        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & sparc_defs[i].features, "+");
1239 64a88d5d blueswir1
        (*cpu_fprintf)(f, "\n");
1240 c48fcb47 blueswir1
    }
1241 64a88d5d blueswir1
    (*cpu_fprintf)(f, "CPU feature flags (+/-): ");
1242 64a88d5d blueswir1
    print_features(f, cpu_fprintf, -1, NULL);
1243 64a88d5d blueswir1
    (*cpu_fprintf)(f, "\n");
1244 64a88d5d blueswir1
    (*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version mmu_version\n");
1245 c48fcb47 blueswir1
}
1246 c48fcb47 blueswir1
1247 c48fcb47 blueswir1
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
1248 c48fcb47 blueswir1
1249 c48fcb47 blueswir1
void cpu_dump_state(CPUState *env, FILE *f,
1250 c48fcb47 blueswir1
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1251 c48fcb47 blueswir1
                    int flags)
1252 c48fcb47 blueswir1
{
1253 c48fcb47 blueswir1
    int i, x;
1254 c48fcb47 blueswir1
1255 c48fcb47 blueswir1
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
1256 c48fcb47 blueswir1
    cpu_fprintf(f, "General Registers:\n");
1257 c48fcb47 blueswir1
    for (i = 0; i < 4; i++)
1258 c48fcb47 blueswir1
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1259 c48fcb47 blueswir1
    cpu_fprintf(f, "\n");
1260 c48fcb47 blueswir1
    for (; i < 8; i++)
1261 c48fcb47 blueswir1
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1262 c48fcb47 blueswir1
    cpu_fprintf(f, "\nCurrent Register Window:\n");
1263 c48fcb47 blueswir1
    for (x = 0; x < 3; x++) {
1264 c48fcb47 blueswir1
        for (i = 0; i < 4; i++)
1265 c48fcb47 blueswir1
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1266 c48fcb47 blueswir1
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1267 c48fcb47 blueswir1
                    env->regwptr[i + x * 8]);
1268 c48fcb47 blueswir1
        cpu_fprintf(f, "\n");
1269 c48fcb47 blueswir1
        for (; i < 8; i++)
1270 c48fcb47 blueswir1
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1271 c48fcb47 blueswir1
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1272 c48fcb47 blueswir1
                    env->regwptr[i + x * 8]);
1273 c48fcb47 blueswir1
        cpu_fprintf(f, "\n");
1274 c48fcb47 blueswir1
    }
1275 c48fcb47 blueswir1
    cpu_fprintf(f, "\nFloating Point Registers:\n");
1276 c48fcb47 blueswir1
    for (i = 0; i < 32; i++) {
1277 c48fcb47 blueswir1
        if ((i & 3) == 0)
1278 c48fcb47 blueswir1
            cpu_fprintf(f, "%%f%02d:", i);
1279 c48fcb47 blueswir1
        cpu_fprintf(f, " %016lf", env->fpr[i]);
1280 c48fcb47 blueswir1
        if ((i & 3) == 3)
1281 c48fcb47 blueswir1
            cpu_fprintf(f, "\n");
1282 c48fcb47 blueswir1
    }
1283 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1284 c48fcb47 blueswir1
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
1285 c48fcb47 blueswir1
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
1286 c48fcb47 blueswir1
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
1287 c48fcb47 blueswir1
                env->cansave, env->canrestore, env->otherwin, env->wstate,
1288 c48fcb47 blueswir1
                env->cleanwin, NWINDOWS - 1 - env->cwp);
1289 c48fcb47 blueswir1
#else
1290 c48fcb47 blueswir1
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
1291 c48fcb47 blueswir1
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
1292 c48fcb47 blueswir1
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1293 c48fcb47 blueswir1
            env->psrs?'S':'-', env->psrps?'P':'-',
1294 c48fcb47 blueswir1
            env->psret?'E':'-', env->wim);
1295 c48fcb47 blueswir1
#endif
1296 c48fcb47 blueswir1
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
1297 c48fcb47 blueswir1
}
1298 c48fcb47 blueswir1
1299 87ecb68b pbrook
#ifdef TARGET_SPARC64
1300 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1301 87ecb68b pbrook
#include "qemu-common.h"
1302 87ecb68b pbrook
#include "hw/irq.h"
1303 87ecb68b pbrook
#include "qemu-timer.h"
1304 87ecb68b pbrook
#endif
1305 87ecb68b pbrook
1306 ccd4a219 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
1307 87ecb68b pbrook
{
1308 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1309 87ecb68b pbrook
    ptimer_set_count(opaque, -count);
1310 87ecb68b pbrook
#endif
1311 87ecb68b pbrook
}
1312 87ecb68b pbrook
1313 ccd4a219 blueswir1
uint64_t helper_tick_get_count(void *opaque)
1314 87ecb68b pbrook
{
1315 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1316 87ecb68b pbrook
    return -ptimer_get_count(opaque);
1317 87ecb68b pbrook
#else
1318 87ecb68b pbrook
    return 0;
1319 87ecb68b pbrook
#endif
1320 87ecb68b pbrook
}
1321 87ecb68b pbrook
1322 ccd4a219 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
1323 87ecb68b pbrook
{
1324 87ecb68b pbrook
#if !defined(CONFIG_USER_ONLY)
1325 87ecb68b pbrook
    ptimer_set_limit(opaque, -limit, 0);
1326 87ecb68b pbrook
#endif
1327 87ecb68b pbrook
}
1328 87ecb68b pbrook
#endif