Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ e00c1e71

History | View | Annotate | Download (48.5 kB)

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

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

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