Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ 77f193da

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