Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ 14015304

History | View | Annotate | Download (58.4 kB)

1 e8af50a3 bellard
/*
2 e8af50a3 bellard
 *  sparc helpers
3 5fafdf24 ths
 *
4 83469015 bellard
 *  Copyright (c) 2003-2005 Fabrice Bellard
5 e8af50a3 bellard
 *
6 e8af50a3 bellard
 * This library is free software; you can redistribute it and/or
7 e8af50a3 bellard
 * modify it under the terms of the GNU Lesser General Public
8 e8af50a3 bellard
 * License as published by the Free Software Foundation; either
9 e8af50a3 bellard
 * version 2 of the License, or (at your option) any later version.
10 e8af50a3 bellard
 *
11 e8af50a3 bellard
 * This library is distributed in the hope that it will be useful,
12 e8af50a3 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 e8af50a3 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 e8af50a3 bellard
 * Lesser General Public License for more details.
15 e8af50a3 bellard
 *
16 e8af50a3 bellard
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 e8af50a3 bellard
 */
19 ee5bbe38 bellard
#include <stdarg.h>
20 ee5bbe38 bellard
#include <stdlib.h>
21 ee5bbe38 bellard
#include <stdio.h>
22 ee5bbe38 bellard
#include <string.h>
23 ee5bbe38 bellard
#include <inttypes.h>
24 ee5bbe38 bellard
25 ee5bbe38 bellard
#include "cpu.h"
26 ca10f867 aurel32
#include "qemu-common.h"
27 e8af50a3 bellard
28 e80cfcfc bellard
//#define DEBUG_MMU
29 64a88d5d blueswir1
//#define DEBUG_FEATURES
30 e8af50a3 bellard
31 b8e9fc06 Igor V. Kovalenko
#ifdef DEBUG_MMU
32 b8e9fc06 Igor V. Kovalenko
#define DPRINTF_MMU(fmt, ...) \
33 b8e9fc06 Igor V. Kovalenko
    do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
34 b8e9fc06 Igor V. Kovalenko
#else
35 b8e9fc06 Igor V. Kovalenko
#define DPRINTF_MMU(fmt, ...) do {} while (0)
36 b8e9fc06 Igor V. Kovalenko
#endif
37 b8e9fc06 Igor V. Kovalenko
38 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
39 c48fcb47 blueswir1
40 e8af50a3 bellard
/* Sparc MMU emulation */
41 e8af50a3 bellard
42 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
43 9d893301 bellard
44 22548760 blueswir1
int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
45 97b348e7 Blue Swirl
                               int mmu_idx)
46 9d893301 bellard
{
47 878d3096 bellard
    if (rw & 2)
48 22548760 blueswir1
        env1->exception_index = TT_TFAULT;
49 878d3096 bellard
    else
50 22548760 blueswir1
        env1->exception_index = TT_DFAULT;
51 9d893301 bellard
    return 1;
52 9d893301 bellard
}
53 9d893301 bellard
54 9d893301 bellard
#else
55 e8af50a3 bellard
56 3475187d bellard
#ifndef TARGET_SPARC64
57 83469015 bellard
/*
58 83469015 bellard
 * Sparc V8 Reference MMU (SRMMU)
59 83469015 bellard
 */
60 e8af50a3 bellard
static const int access_table[8][8] = {
61 a764a566 blueswir1
    { 0, 0, 0, 0, 8, 0, 12, 12 },
62 a764a566 blueswir1
    { 0, 0, 0, 0, 8, 0, 0, 0 },
63 a764a566 blueswir1
    { 8, 8, 0, 0, 0, 8, 12, 12 },
64 a764a566 blueswir1
    { 8, 8, 0, 0, 0, 8, 0, 0 },
65 a764a566 blueswir1
    { 8, 0, 8, 0, 8, 8, 12, 12 },
66 a764a566 blueswir1
    { 8, 0, 8, 0, 8, 0, 8, 0 },
67 a764a566 blueswir1
    { 8, 8, 8, 0, 8, 8, 12, 12 },
68 a764a566 blueswir1
    { 8, 8, 8, 0, 8, 8, 8, 0 }
69 e8af50a3 bellard
};
70 e8af50a3 bellard
71 227671c9 bellard
static const int perm_table[2][8] = {
72 227671c9 bellard
    {
73 227671c9 bellard
        PAGE_READ,
74 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
75 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
76 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
77 227671c9 bellard
        PAGE_EXEC,
78 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
79 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
80 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC
81 227671c9 bellard
    },
82 227671c9 bellard
    {
83 227671c9 bellard
        PAGE_READ,
84 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
85 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
86 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
87 227671c9 bellard
        PAGE_EXEC,
88 227671c9 bellard
        PAGE_READ,
89 227671c9 bellard
        0,
90 227671c9 bellard
        0,
91 227671c9 bellard
    }
92 e8af50a3 bellard
};
93 e8af50a3 bellard
94 c227f099 Anthony Liguori
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
95 c48fcb47 blueswir1
                                int *prot, int *access_index,
96 d4c430a8 Paul Brook
                                target_ulong address, int rw, int mmu_idx,
97 d4c430a8 Paul Brook
                                target_ulong *page_size)
98 e8af50a3 bellard
{
99 e80cfcfc bellard
    int access_perms = 0;
100 c227f099 Anthony Liguori
    target_phys_addr_t pde_ptr;
101 af7bf89b bellard
    uint32_t pde;
102 6ebbf390 j_mayer
    int error_code = 0, is_dirty, is_user;
103 e80cfcfc bellard
    unsigned long page_offset;
104 e8af50a3 bellard
105 6ebbf390 j_mayer
    is_user = mmu_idx == MMU_USER_IDX;
106 40ce0a9a blueswir1
107 e8af50a3 bellard
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
108 d4c430a8 Paul Brook
        *page_size = TARGET_PAGE_SIZE;
109 40ce0a9a blueswir1
        // Boot mode: instruction fetches are taken from PROM
110 5578ceab blueswir1
        if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
111 58a770f3 blueswir1
            *physical = env->prom_addr | (address & 0x7ffffULL);
112 40ce0a9a blueswir1
            *prot = PAGE_READ | PAGE_EXEC;
113 40ce0a9a blueswir1
            return 0;
114 40ce0a9a blueswir1
        }
115 0f8a249a blueswir1
        *physical = address;
116 227671c9 bellard
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
117 e80cfcfc bellard
        return 0;
118 e8af50a3 bellard
    }
119 e8af50a3 bellard
120 7483750d bellard
    *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
121 5dcb6b91 blueswir1
    *physical = 0xffffffffffff0000ULL;
122 7483750d bellard
123 e8af50a3 bellard
    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
124 e8af50a3 bellard
    /* Context base + context number */
125 3deaeab7 blueswir1
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
126 49be8030 bellard
    pde = ldl_phys(pde_ptr);
127 e8af50a3 bellard
128 e8af50a3 bellard
    /* Ctx pde */
129 e8af50a3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
130 e80cfcfc bellard
    default:
131 e8af50a3 bellard
    case 0: /* Invalid */
132 0f8a249a blueswir1
        return 1 << 2;
133 e80cfcfc bellard
    case 2: /* L0 PTE, maybe should not happen? */
134 e8af50a3 bellard
    case 3: /* Reserved */
135 7483750d bellard
        return 4 << 2;
136 e80cfcfc bellard
    case 1: /* L0 PDE */
137 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
138 49be8030 bellard
        pde = ldl_phys(pde_ptr);
139 e8af50a3 bellard
140 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
141 0f8a249a blueswir1
        default:
142 0f8a249a blueswir1
        case 0: /* Invalid */
143 0f8a249a blueswir1
            return (1 << 8) | (1 << 2);
144 0f8a249a blueswir1
        case 3: /* Reserved */
145 0f8a249a blueswir1
            return (1 << 8) | (4 << 2);
146 0f8a249a blueswir1
        case 1: /* L1 PDE */
147 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
148 49be8030 bellard
            pde = ldl_phys(pde_ptr);
149 e8af50a3 bellard
150 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
151 0f8a249a blueswir1
            default:
152 0f8a249a blueswir1
            case 0: /* Invalid */
153 0f8a249a blueswir1
                return (2 << 8) | (1 << 2);
154 0f8a249a blueswir1
            case 3: /* Reserved */
155 0f8a249a blueswir1
                return (2 << 8) | (4 << 2);
156 0f8a249a blueswir1
            case 1: /* L2 PDE */
157 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
158 49be8030 bellard
                pde = ldl_phys(pde_ptr);
159 e8af50a3 bellard
160 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
161 0f8a249a blueswir1
                default:
162 0f8a249a blueswir1
                case 0: /* Invalid */
163 0f8a249a blueswir1
                    return (3 << 8) | (1 << 2);
164 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
165 0f8a249a blueswir1
                case 3: /* Reserved */
166 0f8a249a blueswir1
                    return (3 << 8) | (4 << 2);
167 0f8a249a blueswir1
                case 2: /* L3 PTE */
168 77f193da blueswir1
                    page_offset = (address & TARGET_PAGE_MASK) &
169 77f193da blueswir1
                        (TARGET_PAGE_SIZE - 1);
170 0f8a249a blueswir1
                }
171 d4c430a8 Paul Brook
                *page_size = TARGET_PAGE_SIZE;
172 0f8a249a blueswir1
                break;
173 0f8a249a blueswir1
            case 2: /* L2 PTE */
174 0f8a249a blueswir1
                page_offset = address & 0x3ffff;
175 d4c430a8 Paul Brook
                *page_size = 0x40000;
176 0f8a249a blueswir1
            }
177 0f8a249a blueswir1
            break;
178 0f8a249a blueswir1
        case 2: /* L1 PTE */
179 0f8a249a blueswir1
            page_offset = address & 0xffffff;
180 d4c430a8 Paul Brook
            *page_size = 0x1000000;
181 0f8a249a blueswir1
        }
182 e8af50a3 bellard
    }
183 e8af50a3 bellard
184 698235aa Artyom Tarasenko
    /* check access */
185 698235aa Artyom Tarasenko
    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
186 698235aa Artyom Tarasenko
    error_code = access_table[*access_index][access_perms];
187 698235aa Artyom Tarasenko
    if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
188 698235aa Artyom Tarasenko
        return error_code;
189 698235aa Artyom Tarasenko
190 e8af50a3 bellard
    /* update page modified and dirty bits */
191 b769d8fe bellard
    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
192 e8af50a3 bellard
    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
193 0f8a249a blueswir1
        pde |= PG_ACCESSED_MASK;
194 0f8a249a blueswir1
        if (is_dirty)
195 0f8a249a blueswir1
            pde |= PG_MODIFIED_MASK;
196 49be8030 bellard
        stl_phys_notdirty(pde_ptr, pde);
197 e8af50a3 bellard
    }
198 e8af50a3 bellard
199 e8af50a3 bellard
    /* the page can be put in the TLB */
200 227671c9 bellard
    *prot = perm_table[is_user][access_perms];
201 227671c9 bellard
    if (!(pde & PG_MODIFIED_MASK)) {
202 e8af50a3 bellard
        /* only set write access if already dirty... otherwise wait
203 e8af50a3 bellard
           for dirty access */
204 227671c9 bellard
        *prot &= ~PAGE_WRITE;
205 e8af50a3 bellard
    }
206 e8af50a3 bellard
207 e8af50a3 bellard
    /* Even if large ptes, we map only one 4KB page in the cache to
208 e8af50a3 bellard
       avoid filling it too fast */
209 c227f099 Anthony Liguori
    *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
210 6f7e9aec bellard
    return error_code;
211 e80cfcfc bellard
}
212 e80cfcfc bellard
213 e80cfcfc bellard
/* Perform address translation */
214 af7bf89b bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
215 97b348e7 Blue Swirl
                              int mmu_idx)
216 e80cfcfc bellard
{
217 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
218 5dcb6b91 blueswir1
    target_ulong vaddr;
219 d4c430a8 Paul Brook
    target_ulong page_size;
220 d4c430a8 Paul Brook
    int error_code = 0, prot, access_index;
221 e8af50a3 bellard
222 77f193da blueswir1
    error_code = get_physical_address(env, &paddr, &prot, &access_index,
223 d4c430a8 Paul Brook
                                      address, rw, mmu_idx, &page_size);
224 e80cfcfc bellard
    if (error_code == 0) {
225 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
226 0f8a249a blueswir1
        paddr &= TARGET_PAGE_MASK;
227 9e61bde5 bellard
#ifdef DEBUG_MMU
228 0f8a249a blueswir1
        printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
229 5dcb6b91 blueswir1
               TARGET_FMT_lx "\n", address, paddr, vaddr);
230 9e61bde5 bellard
#endif
231 d4c430a8 Paul Brook
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
232 d4c430a8 Paul Brook
        return 0;
233 e80cfcfc bellard
    }
234 e8af50a3 bellard
235 e8af50a3 bellard
    if (env->mmuregs[3]) /* Fault status register */
236 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
237 7483750d bellard
    env->mmuregs[3] |= (access_index << 5) | error_code | 2;
238 e8af50a3 bellard
    env->mmuregs[4] = address; /* Fault address register */
239 e8af50a3 bellard
240 878d3096 bellard
    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
241 6f7e9aec bellard
        // No fault mode: if a mapping is available, just override
242 6f7e9aec bellard
        // permissions. If no mapping is available, redirect accesses to
243 6f7e9aec bellard
        // neverland. Fake/overridden mappings will be flushed when
244 6f7e9aec bellard
        // switching to normal mode.
245 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
246 227671c9 bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
247 d4c430a8 Paul Brook
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE);
248 d4c430a8 Paul Brook
        return 0;
249 7483750d bellard
    } else {
250 7483750d bellard
        if (rw & 2)
251 7483750d bellard
            env->exception_index = TT_TFAULT;
252 7483750d bellard
        else
253 7483750d bellard
            env->exception_index = TT_DFAULT;
254 7483750d bellard
        return 1;
255 878d3096 bellard
    }
256 e8af50a3 bellard
}
257 24741ef3 bellard
258 24741ef3 bellard
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
259 24741ef3 bellard
{
260 c227f099 Anthony Liguori
    target_phys_addr_t pde_ptr;
261 24741ef3 bellard
    uint32_t pde;
262 24741ef3 bellard
263 24741ef3 bellard
    /* Context base + context number */
264 c227f099 Anthony Liguori
    pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
265 5dcb6b91 blueswir1
        (env->mmuregs[2] << 2);
266 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
267 24741ef3 bellard
268 24741ef3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
269 24741ef3 bellard
    default:
270 24741ef3 bellard
    case 0: /* Invalid */
271 24741ef3 bellard
    case 2: /* PTE, maybe should not happen? */
272 24741ef3 bellard
    case 3: /* Reserved */
273 0f8a249a blueswir1
        return 0;
274 24741ef3 bellard
    case 1: /* L1 PDE */
275 0f8a249a blueswir1
        if (mmulev == 3)
276 0f8a249a blueswir1
            return pde;
277 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
278 24741ef3 bellard
        pde = ldl_phys(pde_ptr);
279 24741ef3 bellard
280 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
281 0f8a249a blueswir1
        default:
282 0f8a249a blueswir1
        case 0: /* Invalid */
283 0f8a249a blueswir1
        case 3: /* Reserved */
284 0f8a249a blueswir1
            return 0;
285 0f8a249a blueswir1
        case 2: /* L1 PTE */
286 0f8a249a blueswir1
            return pde;
287 0f8a249a blueswir1
        case 1: /* L2 PDE */
288 0f8a249a blueswir1
            if (mmulev == 2)
289 0f8a249a blueswir1
                return pde;
290 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
291 24741ef3 bellard
            pde = ldl_phys(pde_ptr);
292 24741ef3 bellard
293 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
294 0f8a249a blueswir1
            default:
295 0f8a249a blueswir1
            case 0: /* Invalid */
296 0f8a249a blueswir1
            case 3: /* Reserved */
297 0f8a249a blueswir1
                return 0;
298 0f8a249a blueswir1
            case 2: /* L2 PTE */
299 0f8a249a blueswir1
                return pde;
300 0f8a249a blueswir1
            case 1: /* L3 PDE */
301 0f8a249a blueswir1
                if (mmulev == 1)
302 0f8a249a blueswir1
                    return pde;
303 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((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 1: /* PDE, should not happen */
310 0f8a249a blueswir1
                case 3: /* Reserved */
311 0f8a249a blueswir1
                    return 0;
312 0f8a249a blueswir1
                case 2: /* L3 PTE */
313 0f8a249a blueswir1
                    return pde;
314 0f8a249a blueswir1
                }
315 0f8a249a blueswir1
            }
316 0f8a249a blueswir1
        }
317 24741ef3 bellard
    }
318 24741ef3 bellard
    return 0;
319 24741ef3 bellard
}
320 24741ef3 bellard
321 d41160a3 Blue Swirl
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
322 24741ef3 bellard
{
323 5dcb6b91 blueswir1
    target_ulong va, va1, va2;
324 5dcb6b91 blueswir1
    unsigned int n, m, o;
325 c227f099 Anthony Liguori
    target_phys_addr_t pde_ptr, pa;
326 24741ef3 bellard
    uint32_t pde;
327 24741ef3 bellard
328 24741ef3 bellard
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
329 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
330 d41160a3 Blue Swirl
    (*cpu_fprintf)(f, "Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
331 d41160a3 Blue Swirl
                   (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
332 24741ef3 bellard
    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
333 0f8a249a blueswir1
        pde = mmu_probe(env, va, 2);
334 0f8a249a blueswir1
        if (pde) {
335 0f8a249a blueswir1
            pa = cpu_get_phys_page_debug(env, va);
336 d41160a3 Blue Swirl
            (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
337 d41160a3 Blue Swirl
                           " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
338 0f8a249a blueswir1
            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
339 0f8a249a blueswir1
                pde = mmu_probe(env, va1, 1);
340 0f8a249a blueswir1
                if (pde) {
341 0f8a249a blueswir1
                    pa = cpu_get_phys_page_debug(env, va1);
342 d41160a3 Blue Swirl
                    (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
343 d41160a3 Blue Swirl
                                   TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
344 d41160a3 Blue Swirl
                                   va1, pa, pde);
345 0f8a249a blueswir1
                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
346 0f8a249a blueswir1
                        pde = mmu_probe(env, va2, 0);
347 0f8a249a blueswir1
                        if (pde) {
348 0f8a249a blueswir1
                            pa = cpu_get_phys_page_debug(env, va2);
349 d41160a3 Blue Swirl
                            (*cpu_fprintf)(f, "  VA: " TARGET_FMT_lx ", PA: "
350 d41160a3 Blue Swirl
                                           TARGET_FMT_plx " PTE: "
351 d41160a3 Blue Swirl
                                           TARGET_FMT_lx "\n",
352 d41160a3 Blue Swirl
                                           va2, pa, pde);
353 0f8a249a blueswir1
                        }
354 0f8a249a blueswir1
                    }
355 0f8a249a blueswir1
                }
356 0f8a249a blueswir1
            }
357 0f8a249a blueswir1
        }
358 24741ef3 bellard
    }
359 24741ef3 bellard
}
360 24741ef3 bellard
361 24741ef3 bellard
#else /* !TARGET_SPARC64 */
362 e8807b14 Igor Kovalenko
363 e8807b14 Igor Kovalenko
// 41 bit physical address space
364 c227f099 Anthony Liguori
static inline target_phys_addr_t ultrasparc_truncate_physical(uint64_t x)
365 e8807b14 Igor Kovalenko
{
366 e8807b14 Igor Kovalenko
    return x & 0x1ffffffffffULL;
367 e8807b14 Igor Kovalenko
}
368 e8807b14 Igor Kovalenko
369 83469015 bellard
/*
370 83469015 bellard
 * UltraSparc IIi I/DMMUs
371 83469015 bellard
 */
372 536ba015 Igor Kovalenko
373 536ba015 Igor Kovalenko
// Returns true if TTE tag is valid and matches virtual address value in context
374 536ba015 Igor Kovalenko
// requires virtual address mask value calculated from TTE entry size
375 6e8e7d4c Igor Kovalenko
static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
376 536ba015 Igor Kovalenko
                                       uint64_t address, uint64_t context,
377 299b520c Igor V. Kovalenko
                                       target_phys_addr_t *physical)
378 536ba015 Igor Kovalenko
{
379 536ba015 Igor Kovalenko
    uint64_t mask;
380 536ba015 Igor Kovalenko
381 06e12b65 Tsuneo Saito
    switch (TTE_PGSIZE(tlb->tte)) {
382 536ba015 Igor Kovalenko
    default:
383 536ba015 Igor Kovalenko
    case 0x0: // 8k
384 536ba015 Igor Kovalenko
        mask = 0xffffffffffffe000ULL;
385 536ba015 Igor Kovalenko
        break;
386 536ba015 Igor Kovalenko
    case 0x1: // 64k
387 536ba015 Igor Kovalenko
        mask = 0xffffffffffff0000ULL;
388 536ba015 Igor Kovalenko
        break;
389 536ba015 Igor Kovalenko
    case 0x2: // 512k
390 536ba015 Igor Kovalenko
        mask = 0xfffffffffff80000ULL;
391 536ba015 Igor Kovalenko
        break;
392 536ba015 Igor Kovalenko
    case 0x3: // 4M
393 536ba015 Igor Kovalenko
        mask = 0xffffffffffc00000ULL;
394 536ba015 Igor Kovalenko
        break;
395 536ba015 Igor Kovalenko
    }
396 536ba015 Igor Kovalenko
397 536ba015 Igor Kovalenko
    // valid, context match, virtual address match?
398 f707726e Igor Kovalenko
    if (TTE_IS_VALID(tlb->tte) &&
399 299b520c Igor V. Kovalenko
        (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context))
400 2a90358f Blue Swirl
        && compare_masked(address, tlb->tag, mask))
401 536ba015 Igor Kovalenko
    {
402 536ba015 Igor Kovalenko
        // decode physical address
403 6e8e7d4c Igor Kovalenko
        *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
404 536ba015 Igor Kovalenko
        return 1;
405 536ba015 Igor Kovalenko
    }
406 536ba015 Igor Kovalenko
407 536ba015 Igor Kovalenko
    return 0;
408 536ba015 Igor Kovalenko
}
409 536ba015 Igor Kovalenko
410 77f193da blueswir1
static int get_physical_address_data(CPUState *env,
411 c227f099 Anthony Liguori
                                     target_phys_addr_t *physical, int *prot,
412 2065061e Igor V. Kovalenko
                                     target_ulong address, int rw, int mmu_idx)
413 3475187d bellard
{
414 3475187d bellard
    unsigned int i;
415 536ba015 Igor Kovalenko
    uint64_t context;
416 ccc76c24 Tsuneo Saito
    uint64_t sfsr = 0;
417 3475187d bellard
418 2065061e Igor V. Kovalenko
    int is_user = (mmu_idx == MMU_USER_IDX ||
419 2065061e Igor V. Kovalenko
                   mmu_idx == MMU_USER_SECONDARY_IDX);
420 2065061e Igor V. Kovalenko
421 3475187d bellard
    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
422 e8807b14 Igor Kovalenko
        *physical = ultrasparc_truncate_physical(address);
423 0f8a249a blueswir1
        *prot = PAGE_READ | PAGE_WRITE;
424 3475187d bellard
        return 0;
425 3475187d bellard
    }
426 3475187d bellard
427 2065061e Igor V. Kovalenko
    switch(mmu_idx) {
428 2065061e Igor V. Kovalenko
    case MMU_USER_IDX:
429 2065061e Igor V. Kovalenko
    case MMU_KERNEL_IDX:
430 299b520c Igor V. Kovalenko
        context = env->dmmu.mmu_primary_context & 0x1fff;
431 ccc76c24 Tsuneo Saito
        sfsr |= SFSR_CT_PRIMARY;
432 2065061e Igor V. Kovalenko
        break;
433 2065061e Igor V. Kovalenko
    case MMU_USER_SECONDARY_IDX:
434 2065061e Igor V. Kovalenko
    case MMU_KERNEL_SECONDARY_IDX:
435 2065061e Igor V. Kovalenko
        context = env->dmmu.mmu_secondary_context & 0x1fff;
436 ccc76c24 Tsuneo Saito
        sfsr |= SFSR_CT_SECONDARY;
437 2065061e Igor V. Kovalenko
        break;
438 2065061e Igor V. Kovalenko
    case MMU_NUCLEUS_IDX:
439 ccc76c24 Tsuneo Saito
        sfsr |= SFSR_CT_NUCLEUS;
440 ccc76c24 Tsuneo Saito
        /* FALLTHRU */
441 44505216 Blue Swirl
    default:
442 299b520c Igor V. Kovalenko
        context = 0;
443 2065061e Igor V. Kovalenko
        break;
444 299b520c Igor V. Kovalenko
    }
445 536ba015 Igor Kovalenko
446 ccc76c24 Tsuneo Saito
    if (rw == 1) {
447 ccc76c24 Tsuneo Saito
        sfsr |= SFSR_WRITE_BIT;
448 d1afc48b Tsuneo Saito
    } else if (rw == 4) {
449 d1afc48b Tsuneo Saito
        sfsr |= SFSR_NF_BIT;
450 ccc76c24 Tsuneo Saito
    }
451 ccc76c24 Tsuneo Saito
452 3475187d bellard
    for (i = 0; i < 64; i++) {
453 afdf8109 blueswir1
        // ctx match, vaddr match, valid?
454 b8e9fc06 Igor V. Kovalenko
        if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
455 d1afc48b Tsuneo Saito
            int do_fault = 0;
456 b8e9fc06 Igor V. Kovalenko
457 afdf8109 blueswir1
            // access ok?
458 d1afc48b Tsuneo Saito
            /* multiple bits in SFSR.FT may be set on TT_DFAULT */
459 06e12b65 Tsuneo Saito
            if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
460 d1afc48b Tsuneo Saito
                do_fault = 1;
461 ccc76c24 Tsuneo Saito
                sfsr |= SFSR_FT_PRIV_BIT; /* privilege violation */
462 6e8e7d4c Igor Kovalenko
463 b8e9fc06 Igor V. Kovalenko
                DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64
464 b8e9fc06 Igor V. Kovalenko
                            " mmu_idx=%d tl=%d\n",
465 b8e9fc06 Igor V. Kovalenko
                            address, context, mmu_idx, env->tl);
466 d1afc48b Tsuneo Saito
            }
467 d1afc48b Tsuneo Saito
            if (rw == 4) {
468 d1afc48b Tsuneo Saito
                if (TTE_IS_SIDEEFFECT(env->dtlb[i].tte)) {
469 d1afc48b Tsuneo Saito
                    do_fault = 1;
470 d1afc48b Tsuneo Saito
                    sfsr |= SFSR_FT_NF_E_BIT;
471 d1afc48b Tsuneo Saito
                }
472 d1afc48b Tsuneo Saito
            } else {
473 d1afc48b Tsuneo Saito
                if (TTE_IS_NFO(env->dtlb[i].tte)) {
474 d1afc48b Tsuneo Saito
                    do_fault = 1;
475 d1afc48b Tsuneo Saito
                    sfsr |= SFSR_FT_NFO_BIT;
476 d1afc48b Tsuneo Saito
                }
477 d1afc48b Tsuneo Saito
            }
478 d1afc48b Tsuneo Saito
479 d1afc48b Tsuneo Saito
            if (do_fault) {
480 d1afc48b Tsuneo Saito
                /* faults above are reported with TT_DFAULT. */
481 d1afc48b Tsuneo Saito
                env->exception_index = TT_DFAULT;
482 06e12b65 Tsuneo Saito
            } else if (!TTE_IS_W_OK(env->dtlb[i].tte) && (rw == 1)) {
483 d1afc48b Tsuneo Saito
                do_fault = 1;
484 b8e9fc06 Igor V. Kovalenko
                env->exception_index = TT_DPROT;
485 6e8e7d4c Igor Kovalenko
486 b8e9fc06 Igor V. Kovalenko
                DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64
487 b8e9fc06 Igor V. Kovalenko
                            " mmu_idx=%d tl=%d\n",
488 b8e9fc06 Igor V. Kovalenko
                            address, context, mmu_idx, env->tl);
489 d1afc48b Tsuneo Saito
            }
490 d1afc48b Tsuneo Saito
491 d1afc48b Tsuneo Saito
            if (!do_fault) {
492 b8e9fc06 Igor V. Kovalenko
                *prot = PAGE_READ;
493 06e12b65 Tsuneo Saito
                if (TTE_IS_W_OK(env->dtlb[i].tte)) {
494 b8e9fc06 Igor V. Kovalenko
                    *prot |= PAGE_WRITE;
495 06e12b65 Tsuneo Saito
                }
496 b8e9fc06 Igor V. Kovalenko
497 b8e9fc06 Igor V. Kovalenko
                TTE_SET_USED(env->dtlb[i].tte);
498 b8e9fc06 Igor V. Kovalenko
499 b8e9fc06 Igor V. Kovalenko
                return 0;
500 b8e9fc06 Igor V. Kovalenko
            }
501 b8e9fc06 Igor V. Kovalenko
502 ccc76c24 Tsuneo Saito
            if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
503 ccc76c24 Tsuneo Saito
                sfsr |= SFSR_OW_BIT; /* overflow (not read before
504 ccc76c24 Tsuneo Saito
                                        another fault) */
505 ccc76c24 Tsuneo Saito
            }
506 6e8e7d4c Igor Kovalenko
507 ccc76c24 Tsuneo Saito
            if (env->pstate & PS_PRIV) {
508 ccc76c24 Tsuneo Saito
                sfsr |= SFSR_PR_BIT;
509 ccc76c24 Tsuneo Saito
            }
510 6e8e7d4c Igor Kovalenko
511 ccc76c24 Tsuneo Saito
            /* FIXME: ASI field in SFSR must be set */
512 ccc76c24 Tsuneo Saito
            env->dmmu.sfsr = sfsr | SFSR_VALID_BIT;
513 6e8e7d4c Igor Kovalenko
514 b8e9fc06 Igor V. Kovalenko
            env->dmmu.sfar = address; /* Fault address register */
515 9168b3a5 Igor V. Kovalenko
516 9168b3a5 Igor V. Kovalenko
            env->dmmu.tag_access = (address & ~0x1fffULL) | context;
517 9168b3a5 Igor V. Kovalenko
518 b8e9fc06 Igor V. Kovalenko
            return 1;
519 0f8a249a blueswir1
        }
520 3475187d bellard
    }
521 b8e9fc06 Igor V. Kovalenko
522 b8e9fc06 Igor V. Kovalenko
    DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n",
523 b8e9fc06 Igor V. Kovalenko
                address, context);
524 b8e9fc06 Igor V. Kovalenko
525 ccc76c24 Tsuneo Saito
    /*
526 ccc76c24 Tsuneo Saito
     * On MMU misses:
527 ccc76c24 Tsuneo Saito
     * - UltraSPARC IIi: SFSR and SFAR unmodified
528 ccc76c24 Tsuneo Saito
     * - JPS1: SFAR updated and some fields of SFSR updated
529 ccc76c24 Tsuneo Saito
     */
530 6e8e7d4c Igor Kovalenko
    env->dmmu.tag_access = (address & ~0x1fffULL) | context;
531 83469015 bellard
    env->exception_index = TT_DMISS;
532 3475187d bellard
    return 1;
533 3475187d bellard
}
534 3475187d bellard
535 77f193da blueswir1
static int get_physical_address_code(CPUState *env,
536 c227f099 Anthony Liguori
                                     target_phys_addr_t *physical, int *prot,
537 2065061e Igor V. Kovalenko
                                     target_ulong address, int mmu_idx)
538 3475187d bellard
{
539 3475187d bellard
    unsigned int i;
540 536ba015 Igor Kovalenko
    uint64_t context;
541 3475187d bellard
542 2065061e Igor V. Kovalenko
    int is_user = (mmu_idx == MMU_USER_IDX ||
543 2065061e Igor V. Kovalenko
                   mmu_idx == MMU_USER_SECONDARY_IDX);
544 2065061e Igor V. Kovalenko
545 e8807b14 Igor Kovalenko
    if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
546 e8807b14 Igor Kovalenko
        /* IMMU disabled */
547 e8807b14 Igor Kovalenko
        *physical = ultrasparc_truncate_physical(address);
548 0f8a249a blueswir1
        *prot = PAGE_EXEC;
549 3475187d bellard
        return 0;
550 3475187d bellard
    }
551 83469015 bellard
552 299b520c Igor V. Kovalenko
    if (env->tl == 0) {
553 2065061e Igor V. Kovalenko
        /* PRIMARY context */
554 299b520c Igor V. Kovalenko
        context = env->dmmu.mmu_primary_context & 0x1fff;
555 299b520c Igor V. Kovalenko
    } else {
556 2065061e Igor V. Kovalenko
        /* NUCLEUS context */
557 299b520c Igor V. Kovalenko
        context = 0;
558 299b520c Igor V. Kovalenko
    }
559 536ba015 Igor Kovalenko
560 3475187d bellard
    for (i = 0; i < 64; i++) {
561 afdf8109 blueswir1
        // ctx match, vaddr match, valid?
562 6e8e7d4c Igor Kovalenko
        if (ultrasparc_tag_match(&env->itlb[i],
563 299b520c Igor V. Kovalenko
                                 address, context, physical)) {
564 afdf8109 blueswir1
            // access ok?
565 06e12b65 Tsuneo Saito
            if (TTE_IS_PRIV(env->itlb[i].tte) && is_user) {
566 ccc76c24 Tsuneo Saito
                /* Fault status register */
567 ccc76c24 Tsuneo Saito
                if (env->immu.sfsr & SFSR_VALID_BIT) {
568 ccc76c24 Tsuneo Saito
                    env->immu.sfsr = SFSR_OW_BIT; /* overflow (not read before
569 ccc76c24 Tsuneo Saito
                                                     another fault) */
570 ccc76c24 Tsuneo Saito
                } else {
571 ccc76c24 Tsuneo Saito
                    env->immu.sfsr = 0;
572 ccc76c24 Tsuneo Saito
                }
573 ccc76c24 Tsuneo Saito
                if (env->pstate & PS_PRIV) {
574 ccc76c24 Tsuneo Saito
                    env->immu.sfsr |= SFSR_PR_BIT;
575 ccc76c24 Tsuneo Saito
                }
576 ccc76c24 Tsuneo Saito
                if (env->tl > 0) {
577 ccc76c24 Tsuneo Saito
                    env->immu.sfsr |= SFSR_CT_NUCLEUS;
578 ccc76c24 Tsuneo Saito
                }
579 ccc76c24 Tsuneo Saito
580 ccc76c24 Tsuneo Saito
                /* FIXME: ASI field in SFSR must be set */
581 ccc76c24 Tsuneo Saito
                env->immu.sfsr |= SFSR_FT_PRIV_BIT | SFSR_VALID_BIT;
582 0f8a249a blueswir1
                env->exception_index = TT_TFAULT;
583 b8e9fc06 Igor V. Kovalenko
584 9168b3a5 Igor V. Kovalenko
                env->immu.tag_access = (address & ~0x1fffULL) | context;
585 9168b3a5 Igor V. Kovalenko
586 b8e9fc06 Igor V. Kovalenko
                DPRINTF_MMU("TFAULT at %" PRIx64 " context %" PRIx64 "\n",
587 b8e9fc06 Igor V. Kovalenko
                            address, context);
588 b8e9fc06 Igor V. Kovalenko
589 0f8a249a blueswir1
                return 1;
590 0f8a249a blueswir1
            }
591 0f8a249a blueswir1
            *prot = PAGE_EXEC;
592 f707726e Igor Kovalenko
            TTE_SET_USED(env->itlb[i].tte);
593 0f8a249a blueswir1
            return 0;
594 0f8a249a blueswir1
        }
595 3475187d bellard
    }
596 b8e9fc06 Igor V. Kovalenko
597 b8e9fc06 Igor V. Kovalenko
    DPRINTF_MMU("TMISS at %" PRIx64 " context %" PRIx64 "\n",
598 b8e9fc06 Igor V. Kovalenko
                address, context);
599 b8e9fc06 Igor V. Kovalenko
600 7ab463cb Blue Swirl
    /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
601 6e8e7d4c Igor Kovalenko
    env->immu.tag_access = (address & ~0x1fffULL) | context;
602 83469015 bellard
    env->exception_index = TT_TMISS;
603 3475187d bellard
    return 1;
604 3475187d bellard
}
605 3475187d bellard
606 c227f099 Anthony Liguori
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
607 c48fcb47 blueswir1
                                int *prot, int *access_index,
608 d4c430a8 Paul Brook
                                target_ulong address, int rw, int mmu_idx,
609 d4c430a8 Paul Brook
                                target_ulong *page_size)
610 3475187d bellard
{
611 d4c430a8 Paul Brook
    /* ??? We treat everything as a small page, then explicitly flush
612 d4c430a8 Paul Brook
       everything when an entry is evicted.  */
613 d4c430a8 Paul Brook
    *page_size = TARGET_PAGE_SIZE;
614 9fd1ae3a Igor V. Kovalenko
615 9fd1ae3a Igor V. Kovalenko
#if defined (DEBUG_MMU)
616 9fd1ae3a Igor V. Kovalenko
    /* safety net to catch wrong softmmu index use from dynamic code */
617 9fd1ae3a Igor V. Kovalenko
    if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
618 9fd1ae3a Igor V. Kovalenko
        DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d"
619 9fd1ae3a Igor V. Kovalenko
                    " primary context=%" PRIx64
620 9fd1ae3a Igor V. Kovalenko
                    " secondary context=%" PRIx64
621 9fd1ae3a Igor V. Kovalenko
                " address=%" PRIx64
622 9fd1ae3a Igor V. Kovalenko
                "\n",
623 9fd1ae3a Igor V. Kovalenko
                (rw == 2 ? "CODE" : "DATA"),
624 9fd1ae3a Igor V. Kovalenko
                env->tl, mmu_idx,
625 9fd1ae3a Igor V. Kovalenko
                env->dmmu.mmu_primary_context,
626 9fd1ae3a Igor V. Kovalenko
                env->dmmu.mmu_secondary_context,
627 9fd1ae3a Igor V. Kovalenko
                address);
628 9fd1ae3a Igor V. Kovalenko
    }
629 9fd1ae3a Igor V. Kovalenko
#endif
630 9fd1ae3a Igor V. Kovalenko
631 3475187d bellard
    if (rw == 2)
632 22548760 blueswir1
        return get_physical_address_code(env, physical, prot, address,
633 2065061e Igor V. Kovalenko
                                         mmu_idx);
634 3475187d bellard
    else
635 22548760 blueswir1
        return get_physical_address_data(env, physical, prot, address, rw,
636 2065061e Igor V. Kovalenko
                                         mmu_idx);
637 3475187d bellard
}
638 3475187d bellard
639 3475187d bellard
/* Perform address translation */
640 3475187d bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
641 97b348e7 Blue Swirl
                              int mmu_idx)
642 3475187d bellard
{
643 83469015 bellard
    target_ulong virt_addr, vaddr;
644 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
645 d4c430a8 Paul Brook
    target_ulong page_size;
646 d4c430a8 Paul Brook
    int error_code = 0, prot, access_index;
647 3475187d bellard
648 77f193da blueswir1
    error_code = get_physical_address(env, &paddr, &prot, &access_index,
649 d4c430a8 Paul Brook
                                      address, rw, mmu_idx, &page_size);
650 3475187d bellard
    if (error_code == 0) {
651 0f8a249a blueswir1
        virt_addr = address & TARGET_PAGE_MASK;
652 77f193da blueswir1
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
653 77f193da blueswir1
                             (TARGET_PAGE_SIZE - 1));
654 b8e9fc06 Igor V. Kovalenko
655 b8e9fc06 Igor V. Kovalenko
        DPRINTF_MMU("Translate at %" PRIx64 " -> %" PRIx64 ","
656 b8e9fc06 Igor V. Kovalenko
                    " vaddr %" PRIx64
657 b8e9fc06 Igor V. Kovalenko
                    " mmu_idx=%d"
658 b8e9fc06 Igor V. Kovalenko
                    " tl=%d"
659 b8e9fc06 Igor V. Kovalenko
                    " primary context=%" PRIx64
660 b8e9fc06 Igor V. Kovalenko
                    " secondary context=%" PRIx64
661 b8e9fc06 Igor V. Kovalenko
                    "\n",
662 b8e9fc06 Igor V. Kovalenko
                    address, paddr, vaddr, mmu_idx, env->tl,
663 b8e9fc06 Igor V. Kovalenko
                    env->dmmu.mmu_primary_context,
664 b8e9fc06 Igor V. Kovalenko
                    env->dmmu.mmu_secondary_context);
665 b8e9fc06 Igor V. Kovalenko
666 d4c430a8 Paul Brook
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
667 d4c430a8 Paul Brook
        return 0;
668 3475187d bellard
    }
669 3475187d bellard
    // XXX
670 3475187d bellard
    return 1;
671 3475187d bellard
}
672 3475187d bellard
673 d41160a3 Blue Swirl
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
674 83469015 bellard
{
675 83469015 bellard
    unsigned int i;
676 83469015 bellard
    const char *mask;
677 83469015 bellard
678 d41160a3 Blue Swirl
    (*cpu_fprintf)(f, "MMU contexts: Primary: %" PRId64 ", Secondary: %"
679 d41160a3 Blue Swirl
                   PRId64 "\n",
680 d41160a3 Blue Swirl
                   env->dmmu.mmu_primary_context,
681 d41160a3 Blue Swirl
                   env->dmmu.mmu_secondary_context);
682 83469015 bellard
    if ((env->lsu & DMMU_E) == 0) {
683 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "DMMU disabled\n");
684 83469015 bellard
    } else {
685 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "DMMU dump\n");
686 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
687 06e12b65 Tsuneo Saito
            switch (TTE_PGSIZE(env->dtlb[i].tte)) {
688 0f8a249a blueswir1
            default:
689 0f8a249a blueswir1
            case 0x0:
690 0f8a249a blueswir1
                mask = "  8k";
691 0f8a249a blueswir1
                break;
692 0f8a249a blueswir1
            case 0x1:
693 0f8a249a blueswir1
                mask = " 64k";
694 0f8a249a blueswir1
                break;
695 0f8a249a blueswir1
            case 0x2:
696 0f8a249a blueswir1
                mask = "512k";
697 0f8a249a blueswir1
                break;
698 0f8a249a blueswir1
            case 0x3:
699 0f8a249a blueswir1
                mask = "  4M";
700 0f8a249a blueswir1
                break;
701 0f8a249a blueswir1
            }
702 06e12b65 Tsuneo Saito
            if (TTE_IS_VALID(env->dtlb[i].tte)) {
703 3b8b030a Stefan Weil
                (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %llx"
704 d41160a3 Blue Swirl
                               ", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
705 d41160a3 Blue Swirl
                               i,
706 d41160a3 Blue Swirl
                               env->dtlb[i].tag & (uint64_t)~0x1fffULL,
707 06e12b65 Tsuneo Saito
                               TTE_PA(env->dtlb[i].tte),
708 d41160a3 Blue Swirl
                               mask,
709 06e12b65 Tsuneo Saito
                               TTE_IS_PRIV(env->dtlb[i].tte) ? "priv" : "user",
710 06e12b65 Tsuneo Saito
                               TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
711 06e12b65 Tsuneo Saito
                               TTE_IS_LOCKED(env->dtlb[i].tte) ?
712 06e12b65 Tsuneo Saito
                               "locked" : "unlocked",
713 d41160a3 Blue Swirl
                               env->dtlb[i].tag & (uint64_t)0x1fffULL,
714 d41160a3 Blue Swirl
                               TTE_IS_GLOBAL(env->dtlb[i].tte)?
715 d41160a3 Blue Swirl
                               "global" : "local");
716 0f8a249a blueswir1
            }
717 0f8a249a blueswir1
        }
718 83469015 bellard
    }
719 83469015 bellard
    if ((env->lsu & IMMU_E) == 0) {
720 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "IMMU disabled\n");
721 83469015 bellard
    } else {
722 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "IMMU dump\n");
723 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
724 06e12b65 Tsuneo Saito
            switch (TTE_PGSIZE(env->itlb[i].tte)) {
725 0f8a249a blueswir1
            default:
726 0f8a249a blueswir1
            case 0x0:
727 0f8a249a blueswir1
                mask = "  8k";
728 0f8a249a blueswir1
                break;
729 0f8a249a blueswir1
            case 0x1:
730 0f8a249a blueswir1
                mask = " 64k";
731 0f8a249a blueswir1
                break;
732 0f8a249a blueswir1
            case 0x2:
733 0f8a249a blueswir1
                mask = "512k";
734 0f8a249a blueswir1
                break;
735 0f8a249a blueswir1
            case 0x3:
736 0f8a249a blueswir1
                mask = "  4M";
737 0f8a249a blueswir1
                break;
738 0f8a249a blueswir1
            }
739 06e12b65 Tsuneo Saito
            if (TTE_IS_VALID(env->itlb[i].tte)) {
740 3b8b030a Stefan Weil
                (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %llx"
741 d41160a3 Blue Swirl
                               ", %s, %s, %s, ctx %" PRId64 " %s\n",
742 d41160a3 Blue Swirl
                               i,
743 d41160a3 Blue Swirl
                               env->itlb[i].tag & (uint64_t)~0x1fffULL,
744 06e12b65 Tsuneo Saito
                               TTE_PA(env->itlb[i].tte),
745 d41160a3 Blue Swirl
                               mask,
746 06e12b65 Tsuneo Saito
                               TTE_IS_PRIV(env->itlb[i].tte) ? "priv" : "user",
747 06e12b65 Tsuneo Saito
                               TTE_IS_LOCKED(env->itlb[i].tte) ?
748 06e12b65 Tsuneo Saito
                               "locked" : "unlocked",
749 d41160a3 Blue Swirl
                               env->itlb[i].tag & (uint64_t)0x1fffULL,
750 d41160a3 Blue Swirl
                               TTE_IS_GLOBAL(env->itlb[i].tte)?
751 d41160a3 Blue Swirl
                               "global" : "local");
752 0f8a249a blueswir1
            }
753 0f8a249a blueswir1
        }
754 83469015 bellard
    }
755 83469015 bellard
}
756 24741ef3 bellard
757 24741ef3 bellard
#endif /* TARGET_SPARC64 */
758 24741ef3 bellard
#endif /* !CONFIG_USER_ONLY */
759 24741ef3 bellard
760 c48fcb47 blueswir1
761 4fcc562b Paul Brook
#if !defined(CONFIG_USER_ONLY)
762 321365ab Tsuneo Saito
static int cpu_sparc_get_phys_page(CPUState *env, target_phys_addr_t *phys,
763 321365ab Tsuneo Saito
                                   target_ulong addr, int rw, int mmu_idx)
764 321365ab Tsuneo Saito
{
765 321365ab Tsuneo Saito
    target_ulong page_size;
766 321365ab Tsuneo Saito
    int prot, access_index;
767 321365ab Tsuneo Saito
768 321365ab Tsuneo Saito
    return get_physical_address(env, phys, &prot, &access_index, addr, rw,
769 321365ab Tsuneo Saito
                                mmu_idx, &page_size);
770 321365ab Tsuneo Saito
}
771 321365ab Tsuneo Saito
772 b64b6436 Tsuneo Saito
#if defined(TARGET_SPARC64)
773 2065061e Igor V. Kovalenko
target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr,
774 2065061e Igor V. Kovalenko
                                           int mmu_idx)
775 c48fcb47 blueswir1
{
776 c227f099 Anthony Liguori
    target_phys_addr_t phys_addr;
777 c48fcb47 blueswir1
778 d1afc48b Tsuneo Saito
    if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 4, mmu_idx) != 0) {
779 c48fcb47 blueswir1
        return -1;
780 103dcbe5 Tsuneo Saito
    }
781 c48fcb47 blueswir1
    return phys_addr;
782 c48fcb47 blueswir1
}
783 b64b6436 Tsuneo Saito
#endif
784 2065061e Igor V. Kovalenko
785 2065061e Igor V. Kovalenko
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
786 2065061e Igor V. Kovalenko
{
787 b64b6436 Tsuneo Saito
    target_phys_addr_t phys_addr;
788 b64b6436 Tsuneo Saito
    int mmu_idx = cpu_mmu_index(env);
789 b64b6436 Tsuneo Saito
790 b64b6436 Tsuneo Saito
    if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) {
791 b64b6436 Tsuneo Saito
        if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) {
792 b64b6436 Tsuneo Saito
            return -1;
793 b64b6436 Tsuneo Saito
        }
794 b64b6436 Tsuneo Saito
    }
795 b64b6436 Tsuneo Saito
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) {
796 b64b6436 Tsuneo Saito
        return -1;
797 b64b6436 Tsuneo Saito
    }
798 b64b6436 Tsuneo Saito
    return phys_addr;
799 2065061e Igor V. Kovalenko
}
800 c48fcb47 blueswir1
#endif
801 c48fcb47 blueswir1
802 e67768d0 Blue Swirl
#ifdef TARGET_SPARC64
803 e67768d0 Blue Swirl
#ifdef DEBUG_PCALL
804 e67768d0 Blue Swirl
static const char * const excp_names[0x80] = {
805 e67768d0 Blue Swirl
    [TT_TFAULT] = "Instruction Access Fault",
806 e67768d0 Blue Swirl
    [TT_TMISS] = "Instruction Access MMU Miss",
807 e67768d0 Blue Swirl
    [TT_CODE_ACCESS] = "Instruction Access Error",
808 e67768d0 Blue Swirl
    [TT_ILL_INSN] = "Illegal Instruction",
809 e67768d0 Blue Swirl
    [TT_PRIV_INSN] = "Privileged Instruction",
810 e67768d0 Blue Swirl
    [TT_NFPU_INSN] = "FPU Disabled",
811 e67768d0 Blue Swirl
    [TT_FP_EXCP] = "FPU Exception",
812 e67768d0 Blue Swirl
    [TT_TOVF] = "Tag Overflow",
813 e67768d0 Blue Swirl
    [TT_CLRWIN] = "Clean Windows",
814 e67768d0 Blue Swirl
    [TT_DIV_ZERO] = "Division By Zero",
815 e67768d0 Blue Swirl
    [TT_DFAULT] = "Data Access Fault",
816 e67768d0 Blue Swirl
    [TT_DMISS] = "Data Access MMU Miss",
817 e67768d0 Blue Swirl
    [TT_DATA_ACCESS] = "Data Access Error",
818 e67768d0 Blue Swirl
    [TT_DPROT] = "Data Protection Error",
819 e67768d0 Blue Swirl
    [TT_UNALIGNED] = "Unaligned Memory Access",
820 e67768d0 Blue Swirl
    [TT_PRIV_ACT] = "Privileged Action",
821 e67768d0 Blue Swirl
    [TT_EXTINT | 0x1] = "External Interrupt 1",
822 e67768d0 Blue Swirl
    [TT_EXTINT | 0x2] = "External Interrupt 2",
823 e67768d0 Blue Swirl
    [TT_EXTINT | 0x3] = "External Interrupt 3",
824 e67768d0 Blue Swirl
    [TT_EXTINT | 0x4] = "External Interrupt 4",
825 e67768d0 Blue Swirl
    [TT_EXTINT | 0x5] = "External Interrupt 5",
826 e67768d0 Blue Swirl
    [TT_EXTINT | 0x6] = "External Interrupt 6",
827 e67768d0 Blue Swirl
    [TT_EXTINT | 0x7] = "External Interrupt 7",
828 e67768d0 Blue Swirl
    [TT_EXTINT | 0x8] = "External Interrupt 8",
829 e67768d0 Blue Swirl
    [TT_EXTINT | 0x9] = "External Interrupt 9",
830 e67768d0 Blue Swirl
    [TT_EXTINT | 0xa] = "External Interrupt 10",
831 e67768d0 Blue Swirl
    [TT_EXTINT | 0xb] = "External Interrupt 11",
832 e67768d0 Blue Swirl
    [TT_EXTINT | 0xc] = "External Interrupt 12",
833 e67768d0 Blue Swirl
    [TT_EXTINT | 0xd] = "External Interrupt 13",
834 e67768d0 Blue Swirl
    [TT_EXTINT | 0xe] = "External Interrupt 14",
835 e67768d0 Blue Swirl
    [TT_EXTINT | 0xf] = "External Interrupt 15",
836 e67768d0 Blue Swirl
};
837 e67768d0 Blue Swirl
#endif
838 e67768d0 Blue Swirl
839 e67768d0 Blue Swirl
void do_interrupt(CPUState *env)
840 e67768d0 Blue Swirl
{
841 e67768d0 Blue Swirl
    int intno = env->exception_index;
842 e67768d0 Blue Swirl
    trap_state *tsptr;
843 e67768d0 Blue Swirl
844 e67768d0 Blue Swirl
#ifdef DEBUG_PCALL
845 e67768d0 Blue Swirl
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
846 e67768d0 Blue Swirl
        static int count;
847 e67768d0 Blue Swirl
        const char *name;
848 e67768d0 Blue Swirl
849 e67768d0 Blue Swirl
        if (intno < 0 || intno >= 0x180) {
850 e67768d0 Blue Swirl
            name = "Unknown";
851 e67768d0 Blue Swirl
        } else if (intno >= 0x100) {
852 e67768d0 Blue Swirl
            name = "Trap Instruction";
853 e67768d0 Blue Swirl
        } else if (intno >= 0xc0) {
854 e67768d0 Blue Swirl
            name = "Window Fill";
855 e67768d0 Blue Swirl
        } else if (intno >= 0x80) {
856 e67768d0 Blue Swirl
            name = "Window Spill";
857 e67768d0 Blue Swirl
        } else {
858 e67768d0 Blue Swirl
            name = excp_names[intno];
859 e67768d0 Blue Swirl
            if (!name) {
860 e67768d0 Blue Swirl
                name = "Unknown";
861 e67768d0 Blue Swirl
            }
862 e67768d0 Blue Swirl
        }
863 e67768d0 Blue Swirl
864 e67768d0 Blue Swirl
        qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
865 e67768d0 Blue Swirl
                " SP=%016" PRIx64 "\n",
866 e67768d0 Blue Swirl
                count, name, intno,
867 e67768d0 Blue Swirl
                env->pc,
868 e67768d0 Blue Swirl
                env->npc, env->regwptr[6]);
869 e67768d0 Blue Swirl
        log_cpu_state(env, 0);
870 e67768d0 Blue Swirl
#if 0
871 e67768d0 Blue Swirl
        {
872 e67768d0 Blue Swirl
            int i;
873 e67768d0 Blue Swirl
            uint8_t *ptr;
874 e67768d0 Blue Swirl

875 e67768d0 Blue Swirl
            qemu_log("       code=");
876 e67768d0 Blue Swirl
            ptr = (uint8_t *)env->pc;
877 e67768d0 Blue Swirl
            for (i = 0; i < 16; i++) {
878 e67768d0 Blue Swirl
                qemu_log(" %02x", ldub(ptr + i));
879 e67768d0 Blue Swirl
            }
880 e67768d0 Blue Swirl
            qemu_log("\n");
881 e67768d0 Blue Swirl
        }
882 e67768d0 Blue Swirl
#endif
883 e67768d0 Blue Swirl
        count++;
884 e67768d0 Blue Swirl
    }
885 e67768d0 Blue Swirl
#endif
886 e67768d0 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
887 e67768d0 Blue Swirl
    if (env->tl >= env->maxtl) {
888 e67768d0 Blue Swirl
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
889 e67768d0 Blue Swirl
                  " Error state", env->exception_index, env->tl, env->maxtl);
890 e67768d0 Blue Swirl
        return;
891 e67768d0 Blue Swirl
    }
892 e67768d0 Blue Swirl
#endif
893 e67768d0 Blue Swirl
    if (env->tl < env->maxtl - 1) {
894 e67768d0 Blue Swirl
        env->tl++;
895 e67768d0 Blue Swirl
    } else {
896 e67768d0 Blue Swirl
        env->pstate |= PS_RED;
897 e67768d0 Blue Swirl
        if (env->tl < env->maxtl) {
898 e67768d0 Blue Swirl
            env->tl++;
899 e67768d0 Blue Swirl
        }
900 e67768d0 Blue Swirl
    }
901 e67768d0 Blue Swirl
    tsptr = cpu_tsptr(env);
902 e67768d0 Blue Swirl
903 e67768d0 Blue Swirl
    tsptr->tstate = (cpu_get_ccr(env) << 32) |
904 e67768d0 Blue Swirl
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
905 e67768d0 Blue Swirl
        cpu_get_cwp64(env);
906 e67768d0 Blue Swirl
    tsptr->tpc = env->pc;
907 e67768d0 Blue Swirl
    tsptr->tnpc = env->npc;
908 e67768d0 Blue Swirl
    tsptr->tt = intno;
909 e67768d0 Blue Swirl
910 e67768d0 Blue Swirl
    switch (intno) {
911 e67768d0 Blue Swirl
    case TT_IVEC:
912 e67768d0 Blue Swirl
        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
913 e67768d0 Blue Swirl
        break;
914 e67768d0 Blue Swirl
    case TT_TFAULT:
915 e67768d0 Blue Swirl
    case TT_DFAULT:
916 e67768d0 Blue Swirl
    case TT_TMISS ... TT_TMISS + 3:
917 e67768d0 Blue Swirl
    case TT_DMISS ... TT_DMISS + 3:
918 e67768d0 Blue Swirl
    case TT_DPROT ... TT_DPROT + 3:
919 e67768d0 Blue Swirl
        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
920 e67768d0 Blue Swirl
        break;
921 e67768d0 Blue Swirl
    default:
922 e67768d0 Blue Swirl
        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
923 e67768d0 Blue Swirl
        break;
924 e67768d0 Blue Swirl
    }
925 e67768d0 Blue Swirl
926 e67768d0 Blue Swirl
    if (intno == TT_CLRWIN) {
927 e67768d0 Blue Swirl
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
928 e67768d0 Blue Swirl
    } else if ((intno & 0x1c0) == TT_SPILL) {
929 e67768d0 Blue Swirl
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
930 e67768d0 Blue Swirl
    } else if ((intno & 0x1c0) == TT_FILL) {
931 e67768d0 Blue Swirl
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
932 e67768d0 Blue Swirl
    }
933 e67768d0 Blue Swirl
    env->tbr &= ~0x7fffULL;
934 e67768d0 Blue Swirl
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
935 e67768d0 Blue Swirl
    env->pc = env->tbr;
936 e67768d0 Blue Swirl
    env->npc = env->pc + 4;
937 e67768d0 Blue Swirl
    env->exception_index = -1;
938 e67768d0 Blue Swirl
}
939 e67768d0 Blue Swirl
#else
940 e67768d0 Blue Swirl
#ifdef DEBUG_PCALL
941 e67768d0 Blue Swirl
static const char * const excp_names[0x80] = {
942 e67768d0 Blue Swirl
    [TT_TFAULT] = "Instruction Access Fault",
943 e67768d0 Blue Swirl
    [TT_ILL_INSN] = "Illegal Instruction",
944 e67768d0 Blue Swirl
    [TT_PRIV_INSN] = "Privileged Instruction",
945 e67768d0 Blue Swirl
    [TT_NFPU_INSN] = "FPU Disabled",
946 e67768d0 Blue Swirl
    [TT_WIN_OVF] = "Window Overflow",
947 e67768d0 Blue Swirl
    [TT_WIN_UNF] = "Window Underflow",
948 e67768d0 Blue Swirl
    [TT_UNALIGNED] = "Unaligned Memory Access",
949 e67768d0 Blue Swirl
    [TT_FP_EXCP] = "FPU Exception",
950 e67768d0 Blue Swirl
    [TT_DFAULT] = "Data Access Fault",
951 e67768d0 Blue Swirl
    [TT_TOVF] = "Tag Overflow",
952 e67768d0 Blue Swirl
    [TT_EXTINT | 0x1] = "External Interrupt 1",
953 e67768d0 Blue Swirl
    [TT_EXTINT | 0x2] = "External Interrupt 2",
954 e67768d0 Blue Swirl
    [TT_EXTINT | 0x3] = "External Interrupt 3",
955 e67768d0 Blue Swirl
    [TT_EXTINT | 0x4] = "External Interrupt 4",
956 e67768d0 Blue Swirl
    [TT_EXTINT | 0x5] = "External Interrupt 5",
957 e67768d0 Blue Swirl
    [TT_EXTINT | 0x6] = "External Interrupt 6",
958 e67768d0 Blue Swirl
    [TT_EXTINT | 0x7] = "External Interrupt 7",
959 e67768d0 Blue Swirl
    [TT_EXTINT | 0x8] = "External Interrupt 8",
960 e67768d0 Blue Swirl
    [TT_EXTINT | 0x9] = "External Interrupt 9",
961 e67768d0 Blue Swirl
    [TT_EXTINT | 0xa] = "External Interrupt 10",
962 e67768d0 Blue Swirl
    [TT_EXTINT | 0xb] = "External Interrupt 11",
963 e67768d0 Blue Swirl
    [TT_EXTINT | 0xc] = "External Interrupt 12",
964 e67768d0 Blue Swirl
    [TT_EXTINT | 0xd] = "External Interrupt 13",
965 e67768d0 Blue Swirl
    [TT_EXTINT | 0xe] = "External Interrupt 14",
966 e67768d0 Blue Swirl
    [TT_EXTINT | 0xf] = "External Interrupt 15",
967 e67768d0 Blue Swirl
    [TT_TOVF] = "Tag Overflow",
968 e67768d0 Blue Swirl
    [TT_CODE_ACCESS] = "Instruction Access Error",
969 e67768d0 Blue Swirl
    [TT_DATA_ACCESS] = "Data Access Error",
970 e67768d0 Blue Swirl
    [TT_DIV_ZERO] = "Division By Zero",
971 e67768d0 Blue Swirl
    [TT_NCP_INSN] = "Coprocessor Disabled",
972 e67768d0 Blue Swirl
};
973 e67768d0 Blue Swirl
#endif
974 e67768d0 Blue Swirl
975 e67768d0 Blue Swirl
void do_interrupt(CPUState *env)
976 e67768d0 Blue Swirl
{
977 e67768d0 Blue Swirl
    int cwp, intno = env->exception_index;
978 e67768d0 Blue Swirl
979 e67768d0 Blue Swirl
#ifdef DEBUG_PCALL
980 e67768d0 Blue Swirl
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
981 e67768d0 Blue Swirl
        static int count;
982 e67768d0 Blue Swirl
        const char *name;
983 e67768d0 Blue Swirl
984 e67768d0 Blue Swirl
        if (intno < 0 || intno >= 0x100) {
985 e67768d0 Blue Swirl
            name = "Unknown";
986 e67768d0 Blue Swirl
        } else if (intno >= 0x80) {
987 e67768d0 Blue Swirl
            name = "Trap Instruction";
988 e67768d0 Blue Swirl
        } else {
989 e67768d0 Blue Swirl
            name = excp_names[intno];
990 e67768d0 Blue Swirl
            if (!name) {
991 e67768d0 Blue Swirl
                name = "Unknown";
992 e67768d0 Blue Swirl
            }
993 e67768d0 Blue Swirl
        }
994 e67768d0 Blue Swirl
995 e67768d0 Blue Swirl
        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
996 e67768d0 Blue Swirl
                count, name, intno,
997 e67768d0 Blue Swirl
                env->pc,
998 e67768d0 Blue Swirl
                env->npc, env->regwptr[6]);
999 e67768d0 Blue Swirl
        log_cpu_state(env, 0);
1000 e67768d0 Blue Swirl
#if 0
1001 e67768d0 Blue Swirl
        {
1002 e67768d0 Blue Swirl
            int i;
1003 e67768d0 Blue Swirl
            uint8_t *ptr;
1004 e67768d0 Blue Swirl

1005 e67768d0 Blue Swirl
            qemu_log("       code=");
1006 e67768d0 Blue Swirl
            ptr = (uint8_t *)env->pc;
1007 e67768d0 Blue Swirl
            for (i = 0; i < 16; i++) {
1008 e67768d0 Blue Swirl
                qemu_log(" %02x", ldub(ptr + i));
1009 e67768d0 Blue Swirl
            }
1010 e67768d0 Blue Swirl
            qemu_log("\n");
1011 e67768d0 Blue Swirl
        }
1012 e67768d0 Blue Swirl
#endif
1013 e67768d0 Blue Swirl
        count++;
1014 e67768d0 Blue Swirl
    }
1015 e67768d0 Blue Swirl
#endif
1016 e67768d0 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
1017 e67768d0 Blue Swirl
    if (env->psret == 0) {
1018 e67768d0 Blue Swirl
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
1019 e67768d0 Blue Swirl
                  env->exception_index);
1020 e67768d0 Blue Swirl
        return;
1021 e67768d0 Blue Swirl
    }
1022 e67768d0 Blue Swirl
#endif
1023 e67768d0 Blue Swirl
    env->psret = 0;
1024 e67768d0 Blue Swirl
    cwp = cpu_cwp_dec(env, env->cwp - 1);
1025 e67768d0 Blue Swirl
    cpu_set_cwp(env, cwp);
1026 e67768d0 Blue Swirl
    env->regwptr[9] = env->pc;
1027 e67768d0 Blue Swirl
    env->regwptr[10] = env->npc;
1028 e67768d0 Blue Swirl
    env->psrps = env->psrs;
1029 e67768d0 Blue Swirl
    env->psrs = 1;
1030 e67768d0 Blue Swirl
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
1031 e67768d0 Blue Swirl
    env->pc = env->tbr;
1032 e67768d0 Blue Swirl
    env->npc = env->pc + 4;
1033 e67768d0 Blue Swirl
    env->exception_index = -1;
1034 e67768d0 Blue Swirl
1035 e67768d0 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
1036 e67768d0 Blue Swirl
    /* IRQ acknowledgment */
1037 e67768d0 Blue Swirl
    if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
1038 e67768d0 Blue Swirl
        env->qemu_irq_ack(env->irq_manager, intno);
1039 e67768d0 Blue Swirl
    }
1040 e67768d0 Blue Swirl
#endif
1041 e67768d0 Blue Swirl
}
1042 e67768d0 Blue Swirl
#endif
1043 e67768d0 Blue Swirl
1044 c48fcb47 blueswir1
void cpu_reset(CPUSPARCState *env)
1045 c48fcb47 blueswir1
{
1046 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1047 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
1048 eca1bdf4 aliguori
        log_cpu_state(env, 0);
1049 eca1bdf4 aliguori
    }
1050 eca1bdf4 aliguori
1051 c48fcb47 blueswir1
    tlb_flush(env, 1);
1052 c48fcb47 blueswir1
    env->cwp = 0;
1053 5210977a Igor Kovalenko
#ifndef TARGET_SPARC64
1054 c48fcb47 blueswir1
    env->wim = 1;
1055 5210977a Igor Kovalenko
#endif
1056 c48fcb47 blueswir1
    env->regwptr = env->regbase + (env->cwp * 16);
1057 6b743278 Blue Swirl
    CC_OP = CC_OP_FLAGS;
1058 c48fcb47 blueswir1
#if defined(CONFIG_USER_ONLY)
1059 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1060 1a14026e blueswir1
    env->cleanwin = env->nwindows - 2;
1061 1a14026e blueswir1
    env->cansave = env->nwindows - 2;
1062 c48fcb47 blueswir1
    env->pstate = PS_RMO | PS_PEF | PS_IE;
1063 c48fcb47 blueswir1
    env->asi = 0x82; // Primary no-fault
1064 c48fcb47 blueswir1
#endif
1065 c48fcb47 blueswir1
#else
1066 5210977a Igor Kovalenko
#if !defined(TARGET_SPARC64)
1067 c48fcb47 blueswir1
    env->psret = 0;
1068 c48fcb47 blueswir1
    env->psrs = 1;
1069 c48fcb47 blueswir1
    env->psrps = 1;
1070 2aae2b8e Igor V. Kovalenko
#endif
1071 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1072 8194f35a Igor Kovalenko
    env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
1073 2aae2b8e Igor V. Kovalenko
    env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
1074 8194f35a Igor Kovalenko
    env->tl = env->maxtl;
1075 8194f35a Igor Kovalenko
    cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
1076 415fc906 blueswir1
    env->lsu = 0;
1077 c48fcb47 blueswir1
#else
1078 c48fcb47 blueswir1
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
1079 5578ceab blueswir1
    env->mmuregs[0] |= env->def->mmu_bm;
1080 c48fcb47 blueswir1
#endif
1081 e87231d4 blueswir1
    env->pc = 0;
1082 c48fcb47 blueswir1
    env->npc = env->pc + 4;
1083 c48fcb47 blueswir1
#endif
1084 b04d9890 Fabien Chouteau
    env->cache_control = 0;
1085 c48fcb47 blueswir1
}
1086 c48fcb47 blueswir1
1087 64a88d5d blueswir1
static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
1088 c48fcb47 blueswir1
{
1089 64a88d5d blueswir1
    sparc_def_t def1, *def = &def1;
1090 c48fcb47 blueswir1
1091 64a88d5d blueswir1
    if (cpu_sparc_find_by_name(def, cpu_model) < 0)
1092 64a88d5d blueswir1
        return -1;
1093 c48fcb47 blueswir1
1094 5578ceab blueswir1
    env->def = qemu_mallocz(sizeof(*def));
1095 5578ceab blueswir1
    memcpy(env->def, def, sizeof(*def));
1096 5578ceab blueswir1
#if defined(CONFIG_USER_ONLY)
1097 5578ceab blueswir1
    if ((env->def->features & CPU_FEATURE_FLOAT))
1098 5578ceab blueswir1
        env->def->features |= CPU_FEATURE_FLOAT128;
1099 5578ceab blueswir1
#endif
1100 c48fcb47 blueswir1
    env->cpu_model_str = cpu_model;
1101 c48fcb47 blueswir1
    env->version = def->iu_version;
1102 c48fcb47 blueswir1
    env->fsr = def->fpu_version;
1103 1a14026e blueswir1
    env->nwindows = def->nwindows;
1104 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
1105 c48fcb47 blueswir1
    env->mmuregs[0] |= def->mmu_version;
1106 c48fcb47 blueswir1
    cpu_sparc_set_id(env, 0);
1107 963262de blueswir1
    env->mxccregs[7] |= def->mxcc_version;
1108 1a14026e blueswir1
#else
1109 fb79ceb9 blueswir1
    env->mmu_version = def->mmu_version;
1110 c19148bd blueswir1
    env->maxtl = def->maxtl;
1111 c19148bd blueswir1
    env->version |= def->maxtl << 8;
1112 1a14026e blueswir1
    env->version |= def->nwindows - 1;
1113 c48fcb47 blueswir1
#endif
1114 64a88d5d blueswir1
    return 0;
1115 64a88d5d blueswir1
}
1116 64a88d5d blueswir1
1117 64a88d5d blueswir1
static void cpu_sparc_close(CPUSPARCState *env)
1118 64a88d5d blueswir1
{
1119 5578ceab blueswir1
    free(env->def);
1120 64a88d5d blueswir1
    free(env);
1121 64a88d5d blueswir1
}
1122 64a88d5d blueswir1
1123 64a88d5d blueswir1
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
1124 64a88d5d blueswir1
{
1125 64a88d5d blueswir1
    CPUSPARCState *env;
1126 64a88d5d blueswir1
1127 64a88d5d blueswir1
    env = qemu_mallocz(sizeof(CPUSPARCState));
1128 64a88d5d blueswir1
    cpu_exec_init(env);
1129 c48fcb47 blueswir1
1130 c48fcb47 blueswir1
    gen_intermediate_code_init(env);
1131 c48fcb47 blueswir1
1132 64a88d5d blueswir1
    if (cpu_sparc_register(env, cpu_model) < 0) {
1133 64a88d5d blueswir1
        cpu_sparc_close(env);
1134 64a88d5d blueswir1
        return NULL;
1135 64a88d5d blueswir1
    }
1136 0bf46a40 aliguori
    qemu_init_vcpu(env);
1137 c48fcb47 blueswir1
1138 c48fcb47 blueswir1
    return env;
1139 c48fcb47 blueswir1
}
1140 c48fcb47 blueswir1
1141 c48fcb47 blueswir1
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
1142 c48fcb47 blueswir1
{
1143 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
1144 c48fcb47 blueswir1
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
1145 c48fcb47 blueswir1
#endif
1146 c48fcb47 blueswir1
}
1147 c48fcb47 blueswir1
1148 c48fcb47 blueswir1
static const sparc_def_t sparc_defs[] = {
1149 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1150 c48fcb47 blueswir1
    {
1151 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64",
1152 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
1153 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1154 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1155 1a14026e blueswir1
        .nwindows = 4,
1156 c19148bd blueswir1
        .maxtl = 4,
1157 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1158 c48fcb47 blueswir1
    },
1159 c48fcb47 blueswir1
    {
1160 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 III",
1161 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
1162 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1163 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1164 1a14026e blueswir1
        .nwindows = 5,
1165 c19148bd blueswir1
        .maxtl = 4,
1166 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1167 c48fcb47 blueswir1
    },
1168 c48fcb47 blueswir1
    {
1169 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 IV",
1170 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
1171 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1172 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1173 1a14026e blueswir1
        .nwindows = 8,
1174 c19148bd blueswir1
        .maxtl = 5,
1175 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1176 c48fcb47 blueswir1
    },
1177 c48fcb47 blueswir1
    {
1178 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 V",
1179 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
1180 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1181 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1182 1a14026e blueswir1
        .nwindows = 8,
1183 c19148bd blueswir1
        .maxtl = 5,
1184 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1185 c48fcb47 blueswir1
    },
1186 c48fcb47 blueswir1
    {
1187 c48fcb47 blueswir1
        .name = "TI UltraSparc I",
1188 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
1189 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1190 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1191 1a14026e blueswir1
        .nwindows = 8,
1192 c19148bd blueswir1
        .maxtl = 5,
1193 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1194 c48fcb47 blueswir1
    },
1195 c48fcb47 blueswir1
    {
1196 c48fcb47 blueswir1
        .name = "TI UltraSparc II",
1197 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
1198 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1199 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1200 1a14026e blueswir1
        .nwindows = 8,
1201 c19148bd blueswir1
        .maxtl = 5,
1202 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1203 c48fcb47 blueswir1
    },
1204 c48fcb47 blueswir1
    {
1205 c48fcb47 blueswir1
        .name = "TI UltraSparc IIi",
1206 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
1207 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1208 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1209 1a14026e blueswir1
        .nwindows = 8,
1210 c19148bd blueswir1
        .maxtl = 5,
1211 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1212 c48fcb47 blueswir1
    },
1213 c48fcb47 blueswir1
    {
1214 c48fcb47 blueswir1
        .name = "TI UltraSparc IIe",
1215 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
1216 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1217 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1218 1a14026e blueswir1
        .nwindows = 8,
1219 c19148bd blueswir1
        .maxtl = 5,
1220 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1221 c48fcb47 blueswir1
    },
1222 c48fcb47 blueswir1
    {
1223 c48fcb47 blueswir1
        .name = "Sun UltraSparc III",
1224 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
1225 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1226 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1227 1a14026e blueswir1
        .nwindows = 8,
1228 c19148bd blueswir1
        .maxtl = 5,
1229 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1230 c48fcb47 blueswir1
    },
1231 c48fcb47 blueswir1
    {
1232 c48fcb47 blueswir1
        .name = "Sun UltraSparc III Cu",
1233 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
1234 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1235 fb79ceb9 blueswir1
        .mmu_version = mmu_us_3,
1236 1a14026e blueswir1
        .nwindows = 8,
1237 c19148bd blueswir1
        .maxtl = 5,
1238 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1239 c48fcb47 blueswir1
    },
1240 c48fcb47 blueswir1
    {
1241 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi",
1242 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
1243 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1244 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1245 1a14026e blueswir1
        .nwindows = 8,
1246 c19148bd blueswir1
        .maxtl = 5,
1247 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1248 c48fcb47 blueswir1
    },
1249 c48fcb47 blueswir1
    {
1250 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV",
1251 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
1252 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1253 fb79ceb9 blueswir1
        .mmu_version = mmu_us_4,
1254 1a14026e blueswir1
        .nwindows = 8,
1255 c19148bd blueswir1
        .maxtl = 5,
1256 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1257 c48fcb47 blueswir1
    },
1258 c48fcb47 blueswir1
    {
1259 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV+",
1260 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
1261 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1262 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1263 1a14026e blueswir1
        .nwindows = 8,
1264 c19148bd blueswir1
        .maxtl = 5,
1265 fb79ceb9 blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
1266 c48fcb47 blueswir1
    },
1267 c48fcb47 blueswir1
    {
1268 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi+",
1269 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
1270 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1271 fb79ceb9 blueswir1
        .mmu_version = mmu_us_3,
1272 1a14026e blueswir1
        .nwindows = 8,
1273 c19148bd blueswir1
        .maxtl = 5,
1274 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1275 c48fcb47 blueswir1
    },
1276 c48fcb47 blueswir1
    {
1277 c7ba218d blueswir1
        .name = "Sun UltraSparc T1",
1278 c7ba218d blueswir1
        // defined in sparc_ifu_fdp.v and ctu.h
1279 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
1280 c7ba218d blueswir1
        .fpu_version = 0x00000000,
1281 c7ba218d blueswir1
        .mmu_version = mmu_sun4v,
1282 c7ba218d blueswir1
        .nwindows = 8,
1283 c19148bd blueswir1
        .maxtl = 6,
1284 c7ba218d blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
1285 c7ba218d blueswir1
        | CPU_FEATURE_GL,
1286 c7ba218d blueswir1
    },
1287 c7ba218d blueswir1
    {
1288 c7ba218d blueswir1
        .name = "Sun UltraSparc T2",
1289 c7ba218d blueswir1
        // defined in tlu_asi_ctl.v and n2_revid_cust.v
1290 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
1291 c7ba218d blueswir1
        .fpu_version = 0x00000000,
1292 c7ba218d blueswir1
        .mmu_version = mmu_sun4v,
1293 c7ba218d blueswir1
        .nwindows = 8,
1294 c19148bd blueswir1
        .maxtl = 6,
1295 c7ba218d blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
1296 c7ba218d blueswir1
        | CPU_FEATURE_GL,
1297 c7ba218d blueswir1
    },
1298 c7ba218d blueswir1
    {
1299 c48fcb47 blueswir1
        .name = "NEC UltraSparc I",
1300 c19148bd blueswir1
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
1301 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
1302 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
1303 1a14026e blueswir1
        .nwindows = 8,
1304 c19148bd blueswir1
        .maxtl = 5,
1305 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1306 c48fcb47 blueswir1
    },
1307 c48fcb47 blueswir1
#else
1308 c48fcb47 blueswir1
    {
1309 c48fcb47 blueswir1
        .name = "Fujitsu MB86900",
1310 c48fcb47 blueswir1
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
1311 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1312 c48fcb47 blueswir1
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
1313 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1314 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1315 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1316 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1317 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1318 1a14026e blueswir1
        .nwindows = 7,
1319 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
1320 c48fcb47 blueswir1
    },
1321 c48fcb47 blueswir1
    {
1322 c48fcb47 blueswir1
        .name = "Fujitsu MB86904",
1323 c48fcb47 blueswir1
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
1324 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1325 c48fcb47 blueswir1
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
1326 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1327 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1328 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1329 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1330 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1331 1a14026e blueswir1
        .nwindows = 8,
1332 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1333 c48fcb47 blueswir1
    },
1334 c48fcb47 blueswir1
    {
1335 c48fcb47 blueswir1
        .name = "Fujitsu MB86907",
1336 c48fcb47 blueswir1
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
1337 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1338 c48fcb47 blueswir1
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
1339 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1340 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1341 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1342 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1343 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1344 1a14026e blueswir1
        .nwindows = 8,
1345 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1346 c48fcb47 blueswir1
    },
1347 c48fcb47 blueswir1
    {
1348 c48fcb47 blueswir1
        .name = "LSI L64811",
1349 c48fcb47 blueswir1
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
1350 c48fcb47 blueswir1
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
1351 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1352 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1353 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1354 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1355 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1356 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1357 1a14026e blueswir1
        .nwindows = 8,
1358 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1359 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1360 c48fcb47 blueswir1
    },
1361 c48fcb47 blueswir1
    {
1362 c48fcb47 blueswir1
        .name = "Cypress CY7C601",
1363 c48fcb47 blueswir1
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
1364 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1365 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1366 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1367 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1368 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1369 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1370 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1371 1a14026e blueswir1
        .nwindows = 8,
1372 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1373 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1374 c48fcb47 blueswir1
    },
1375 c48fcb47 blueswir1
    {
1376 c48fcb47 blueswir1
        .name = "Cypress CY7C611",
1377 c48fcb47 blueswir1
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
1378 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1379 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1380 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1381 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1382 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1383 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1384 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1385 1a14026e blueswir1
        .nwindows = 8,
1386 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1387 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1388 c48fcb47 blueswir1
    },
1389 c48fcb47 blueswir1
    {
1390 c48fcb47 blueswir1
        .name = "TI MicroSparc I",
1391 c48fcb47 blueswir1
        .iu_version = 0x41000000,
1392 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1393 c48fcb47 blueswir1
        .mmu_version = 0x41000000,
1394 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1395 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1396 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1397 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1398 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x0000003f,
1399 1a14026e blueswir1
        .nwindows = 7,
1400 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
1401 e30b4678 blueswir1
        CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
1402 e30b4678 blueswir1
        CPU_FEATURE_FMUL,
1403 c48fcb47 blueswir1
    },
1404 c48fcb47 blueswir1
    {
1405 c48fcb47 blueswir1
        .name = "TI MicroSparc II",
1406 c48fcb47 blueswir1
        .iu_version = 0x42000000,
1407 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1408 c48fcb47 blueswir1
        .mmu_version = 0x02000000,
1409 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1410 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1411 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1412 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1413 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1414 1a14026e blueswir1
        .nwindows = 8,
1415 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1416 c48fcb47 blueswir1
    },
1417 c48fcb47 blueswir1
    {
1418 c48fcb47 blueswir1
        .name = "TI MicroSparc IIep",
1419 c48fcb47 blueswir1
        .iu_version = 0x42000000,
1420 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1421 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1422 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1423 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1424 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1425 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016bff,
1426 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1427 1a14026e blueswir1
        .nwindows = 8,
1428 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1429 c48fcb47 blueswir1
    },
1430 c48fcb47 blueswir1
    {
1431 b5154bde blueswir1
        .name = "TI SuperSparc 40", // STP1020NPGA
1432 963262de blueswir1
        .iu_version = 0x41000000, // SuperSPARC 2.x
1433 b5154bde blueswir1
        .fpu_version = 0 << 17,
1434 963262de blueswir1
        .mmu_version = 0x00000800, // SuperSPARC 2.x, no MXCC
1435 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1436 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1437 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1438 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1439 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1440 1a14026e blueswir1
        .nwindows = 8,
1441 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1442 b5154bde blueswir1
    },
1443 b5154bde blueswir1
    {
1444 b5154bde blueswir1
        .name = "TI SuperSparc 50", // STP1020PGA
1445 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC 3.x
1446 b5154bde blueswir1
        .fpu_version = 0 << 17,
1447 963262de blueswir1
        .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC
1448 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1449 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1450 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1451 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1452 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1453 1a14026e blueswir1
        .nwindows = 8,
1454 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1455 b5154bde blueswir1
    },
1456 b5154bde blueswir1
    {
1457 c48fcb47 blueswir1
        .name = "TI SuperSparc 51",
1458 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC 3.x
1459 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1460 963262de blueswir1
        .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC
1461 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1462 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1463 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1464 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1465 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1466 963262de blueswir1
        .mxcc_version = 0x00000104,
1467 1a14026e blueswir1
        .nwindows = 8,
1468 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1469 c48fcb47 blueswir1
    },
1470 c48fcb47 blueswir1
    {
1471 b5154bde blueswir1
        .name = "TI SuperSparc 60", // STP1020APGA
1472 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC 3.x
1473 b5154bde blueswir1
        .fpu_version = 0 << 17,
1474 963262de blueswir1
        .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC
1475 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1476 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1477 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1478 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1479 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1480 1a14026e blueswir1
        .nwindows = 8,
1481 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1482 b5154bde blueswir1
    },
1483 b5154bde blueswir1
    {
1484 c48fcb47 blueswir1
        .name = "TI SuperSparc 61",
1485 963262de blueswir1
        .iu_version = 0x44000000, // SuperSPARC 3.x
1486 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1487 963262de blueswir1
        .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC
1488 963262de blueswir1
        .mmu_bm = 0x00002000,
1489 963262de blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1490 963262de blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1491 963262de blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1492 963262de blueswir1
        .mmu_trcr_mask = 0xffffffff,
1493 963262de blueswir1
        .mxcc_version = 0x00000104,
1494 963262de blueswir1
        .nwindows = 8,
1495 963262de blueswir1
        .features = CPU_DEFAULT_FEATURES,
1496 963262de blueswir1
    },
1497 963262de blueswir1
    {
1498 963262de blueswir1
        .name = "TI SuperSparc II",
1499 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC II 1.x
1500 963262de blueswir1
        .fpu_version = 0 << 17,
1501 963262de blueswir1
        .mmu_version = 0x08000000, // SuperSPARC II 1.x, MXCC
1502 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1503 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1504 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1505 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1506 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1507 963262de blueswir1
        .mxcc_version = 0x00000104,
1508 1a14026e blueswir1
        .nwindows = 8,
1509 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1510 c48fcb47 blueswir1
    },
1511 c48fcb47 blueswir1
    {
1512 c48fcb47 blueswir1
        .name = "Ross RT625",
1513 c48fcb47 blueswir1
        .iu_version = 0x1e000000,
1514 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1515 c48fcb47 blueswir1
        .mmu_version = 0x1e000000,
1516 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1517 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1518 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1519 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1520 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1521 1a14026e blueswir1
        .nwindows = 8,
1522 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1523 c48fcb47 blueswir1
    },
1524 c48fcb47 blueswir1
    {
1525 c48fcb47 blueswir1
        .name = "Ross RT620",
1526 c48fcb47 blueswir1
        .iu_version = 0x1f000000,
1527 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1528 c48fcb47 blueswir1
        .mmu_version = 0x1f000000,
1529 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1530 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1531 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1532 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1533 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1534 1a14026e blueswir1
        .nwindows = 8,
1535 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1536 c48fcb47 blueswir1
    },
1537 c48fcb47 blueswir1
    {
1538 c48fcb47 blueswir1
        .name = "BIT B5010",
1539 c48fcb47 blueswir1
        .iu_version = 0x20000000,
1540 c48fcb47 blueswir1
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
1541 c48fcb47 blueswir1
        .mmu_version = 0x20000000,
1542 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1543 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1544 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1545 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1546 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1547 1a14026e blueswir1
        .nwindows = 8,
1548 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1549 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1550 c48fcb47 blueswir1
    },
1551 c48fcb47 blueswir1
    {
1552 c48fcb47 blueswir1
        .name = "Matsushita MN10501",
1553 c48fcb47 blueswir1
        .iu_version = 0x50000000,
1554 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1555 c48fcb47 blueswir1
        .mmu_version = 0x50000000,
1556 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1557 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1558 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1559 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1560 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1561 1a14026e blueswir1
        .nwindows = 8,
1562 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
1563 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1564 c48fcb47 blueswir1
    },
1565 c48fcb47 blueswir1
    {
1566 c48fcb47 blueswir1
        .name = "Weitek W8601",
1567 c48fcb47 blueswir1
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
1568 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
1569 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1570 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1571 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1572 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1573 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1574 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1575 1a14026e blueswir1
        .nwindows = 8,
1576 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1577 c48fcb47 blueswir1
    },
1578 c48fcb47 blueswir1
    {
1579 c48fcb47 blueswir1
        .name = "LEON2",
1580 c48fcb47 blueswir1
        .iu_version = 0xf2000000,
1581 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1582 c48fcb47 blueswir1
        .mmu_version = 0xf2000000,
1583 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1584 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1585 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1586 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1587 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1588 1a14026e blueswir1
        .nwindows = 8,
1589 b04d9890 Fabien Chouteau
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
1590 c48fcb47 blueswir1
    },
1591 c48fcb47 blueswir1
    {
1592 c48fcb47 blueswir1
        .name = "LEON3",
1593 c48fcb47 blueswir1
        .iu_version = 0xf3000000,
1594 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1595 c48fcb47 blueswir1
        .mmu_version = 0xf3000000,
1596 b04d9890 Fabien Chouteau
        .mmu_bm = 0x00000000,
1597 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1598 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1599 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1600 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1601 1a14026e blueswir1
        .nwindows = 8,
1602 4a2ba232 Fabien Chouteau
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
1603 60f356e8 Fabien Chouteau
        CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
1604 c48fcb47 blueswir1
    },
1605 c48fcb47 blueswir1
#endif
1606 c48fcb47 blueswir1
};
1607 c48fcb47 blueswir1
1608 64a88d5d blueswir1
static const char * const feature_name[] = {
1609 64a88d5d blueswir1
    "float",
1610 64a88d5d blueswir1
    "float128",
1611 64a88d5d blueswir1
    "swap",
1612 64a88d5d blueswir1
    "mul",
1613 64a88d5d blueswir1
    "div",
1614 64a88d5d blueswir1
    "flush",
1615 64a88d5d blueswir1
    "fsqrt",
1616 64a88d5d blueswir1
    "fmul",
1617 64a88d5d blueswir1
    "vis1",
1618 64a88d5d blueswir1
    "vis2",
1619 e30b4678 blueswir1
    "fsmuld",
1620 fb79ceb9 blueswir1
    "hypv",
1621 fb79ceb9 blueswir1
    "cmt",
1622 fb79ceb9 blueswir1
    "gl",
1623 64a88d5d blueswir1
};
1624 64a88d5d blueswir1
1625 9a78eead Stefan Weil
static void print_features(FILE *f, fprintf_function cpu_fprintf,
1626 64a88d5d blueswir1
                           uint32_t features, const char *prefix)
1627 c48fcb47 blueswir1
{
1628 c48fcb47 blueswir1
    unsigned int i;
1629 c48fcb47 blueswir1
1630 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1631 64a88d5d blueswir1
        if (feature_name[i] && (features & (1 << i))) {
1632 64a88d5d blueswir1
            if (prefix)
1633 64a88d5d blueswir1
                (*cpu_fprintf)(f, "%s", prefix);
1634 64a88d5d blueswir1
            (*cpu_fprintf)(f, "%s ", feature_name[i]);
1635 64a88d5d blueswir1
        }
1636 64a88d5d blueswir1
}
1637 64a88d5d blueswir1
1638 64a88d5d blueswir1
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
1639 64a88d5d blueswir1
{
1640 64a88d5d blueswir1
    unsigned int i;
1641 64a88d5d blueswir1
1642 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1643 64a88d5d blueswir1
        if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
1644 64a88d5d blueswir1
            *features |= 1 << i;
1645 64a88d5d blueswir1
            return;
1646 64a88d5d blueswir1
        }
1647 64a88d5d blueswir1
    fprintf(stderr, "CPU feature %s not found\n", flagname);
1648 64a88d5d blueswir1
}
1649 64a88d5d blueswir1
1650 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
1651 64a88d5d blueswir1
{
1652 64a88d5d blueswir1
    unsigned int i;
1653 64a88d5d blueswir1
    const sparc_def_t *def = NULL;
1654 64a88d5d blueswir1
    char *s = strdup(cpu_model);
1655 64a88d5d blueswir1
    char *featurestr, *name = strtok(s, ",");
1656 64a88d5d blueswir1
    uint32_t plus_features = 0;
1657 64a88d5d blueswir1
    uint32_t minus_features = 0;
1658 0bfcd599 Blue Swirl
    uint64_t iu_version;
1659 1a14026e blueswir1
    uint32_t fpu_version, mmu_version, nwindows;
1660 64a88d5d blueswir1
1661 b1503cda malc
    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
1662 c48fcb47 blueswir1
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
1663 64a88d5d blueswir1
            def = &sparc_defs[i];
1664 c48fcb47 blueswir1
        }
1665 c48fcb47 blueswir1
    }
1666 64a88d5d blueswir1
    if (!def)
1667 64a88d5d blueswir1
        goto error;
1668 64a88d5d blueswir1
    memcpy(cpu_def, def, sizeof(*def));
1669 64a88d5d blueswir1
1670 64a88d5d blueswir1
    featurestr = strtok(NULL, ",");
1671 64a88d5d blueswir1
    while (featurestr) {
1672 64a88d5d blueswir1
        char *val;
1673 64a88d5d blueswir1
1674 64a88d5d blueswir1
        if (featurestr[0] == '+') {
1675 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &plus_features);
1676 64a88d5d blueswir1
        } else if (featurestr[0] == '-') {
1677 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &minus_features);
1678 64a88d5d blueswir1
        } else if ((val = strchr(featurestr, '='))) {
1679 64a88d5d blueswir1
            *val = 0; val++;
1680 64a88d5d blueswir1
            if (!strcmp(featurestr, "iu_version")) {
1681 64a88d5d blueswir1
                char *err;
1682 64a88d5d blueswir1
1683 64a88d5d blueswir1
                iu_version = strtoll(val, &err, 0);
1684 64a88d5d blueswir1
                if (!*val || *err) {
1685 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1686 64a88d5d blueswir1
                    goto error;
1687 64a88d5d blueswir1
                }
1688 64a88d5d blueswir1
                cpu_def->iu_version = iu_version;
1689 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1690 0bfcd599 Blue Swirl
                fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
1691 64a88d5d blueswir1
#endif
1692 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "fpu_version")) {
1693 64a88d5d blueswir1
                char *err;
1694 64a88d5d blueswir1
1695 64a88d5d blueswir1
                fpu_version = strtol(val, &err, 0);
1696 64a88d5d blueswir1
                if (!*val || *err) {
1697 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1698 64a88d5d blueswir1
                    goto error;
1699 64a88d5d blueswir1
                }
1700 64a88d5d blueswir1
                cpu_def->fpu_version = fpu_version;
1701 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1702 0bf9e31a Blue Swirl
                fprintf(stderr, "fpu_version %x\n", fpu_version);
1703 64a88d5d blueswir1
#endif
1704 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "mmu_version")) {
1705 64a88d5d blueswir1
                char *err;
1706 64a88d5d blueswir1
1707 64a88d5d blueswir1
                mmu_version = strtol(val, &err, 0);
1708 64a88d5d blueswir1
                if (!*val || *err) {
1709 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1710 64a88d5d blueswir1
                    goto error;
1711 64a88d5d blueswir1
                }
1712 64a88d5d blueswir1
                cpu_def->mmu_version = mmu_version;
1713 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1714 0bf9e31a Blue Swirl
                fprintf(stderr, "mmu_version %x\n", mmu_version);
1715 64a88d5d blueswir1
#endif
1716 1a14026e blueswir1
            } else if (!strcmp(featurestr, "nwindows")) {
1717 1a14026e blueswir1
                char *err;
1718 1a14026e blueswir1
1719 1a14026e blueswir1
                nwindows = strtol(val, &err, 0);
1720 1a14026e blueswir1
                if (!*val || *err || nwindows > MAX_NWINDOWS ||
1721 1a14026e blueswir1
                    nwindows < MIN_NWINDOWS) {
1722 1a14026e blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1723 1a14026e blueswir1
                    goto error;
1724 1a14026e blueswir1
                }
1725 1a14026e blueswir1
                cpu_def->nwindows = nwindows;
1726 1a14026e blueswir1
#ifdef DEBUG_FEATURES
1727 1a14026e blueswir1
                fprintf(stderr, "nwindows %d\n", nwindows);
1728 1a14026e blueswir1
#endif
1729 64a88d5d blueswir1
            } else {
1730 64a88d5d blueswir1
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1731 64a88d5d blueswir1
                goto error;
1732 64a88d5d blueswir1
            }
1733 64a88d5d blueswir1
        } else {
1734 77f193da blueswir1
            fprintf(stderr, "feature string `%s' not in format "
1735 77f193da blueswir1
                    "(+feature|-feature|feature=xyz)\n", featurestr);
1736 64a88d5d blueswir1
            goto error;
1737 64a88d5d blueswir1
        }
1738 64a88d5d blueswir1
        featurestr = strtok(NULL, ",");
1739 64a88d5d blueswir1
    }
1740 64a88d5d blueswir1
    cpu_def->features |= plus_features;
1741 64a88d5d blueswir1
    cpu_def->features &= ~minus_features;
1742 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1743 64a88d5d blueswir1
    print_features(stderr, fprintf, cpu_def->features, NULL);
1744 64a88d5d blueswir1
#endif
1745 64a88d5d blueswir1
    free(s);
1746 64a88d5d blueswir1
    return 0;
1747 64a88d5d blueswir1
1748 64a88d5d blueswir1
 error:
1749 64a88d5d blueswir1
    free(s);
1750 64a88d5d blueswir1
    return -1;
1751 c48fcb47 blueswir1
}
1752 c48fcb47 blueswir1
1753 9a78eead Stefan Weil
void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1754 c48fcb47 blueswir1
{
1755 c48fcb47 blueswir1
    unsigned int i;
1756 c48fcb47 blueswir1
1757 b1503cda malc
    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
1758 1a14026e blueswir1
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
1759 c48fcb47 blueswir1
                       sparc_defs[i].name,
1760 c48fcb47 blueswir1
                       sparc_defs[i].iu_version,
1761 c48fcb47 blueswir1
                       sparc_defs[i].fpu_version,
1762 1a14026e blueswir1
                       sparc_defs[i].mmu_version,
1763 1a14026e blueswir1
                       sparc_defs[i].nwindows);
1764 77f193da blueswir1
        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
1765 77f193da blueswir1
                       ~sparc_defs[i].features, "-");
1766 77f193da blueswir1
        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
1767 77f193da blueswir1
                       sparc_defs[i].features, "+");
1768 64a88d5d blueswir1
        (*cpu_fprintf)(f, "\n");
1769 c48fcb47 blueswir1
    }
1770 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
1771 f76981b1 blueswir1
    print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
1772 64a88d5d blueswir1
    (*cpu_fprintf)(f, "\n");
1773 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
1774 f76981b1 blueswir1
    print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
1775 f76981b1 blueswir1
    (*cpu_fprintf)(f, "\n");
1776 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
1777 f76981b1 blueswir1
                   "fpu_version mmu_version nwindows\n");
1778 c48fcb47 blueswir1
}
1779 c48fcb47 blueswir1
1780 9a78eead Stefan Weil
static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
1781 43bb98bf Blue Swirl
                         uint32_t cc)
1782 43bb98bf Blue Swirl
{
1783 43bb98bf Blue Swirl
    cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG? 'N' : '-',
1784 43bb98bf Blue Swirl
                cc & PSR_ZERO? 'Z' : '-', cc & PSR_OVF? 'V' : '-',
1785 43bb98bf Blue Swirl
                cc & PSR_CARRY? 'C' : '-');
1786 43bb98bf Blue Swirl
}
1787 43bb98bf Blue Swirl
1788 43bb98bf Blue Swirl
#ifdef TARGET_SPARC64
1789 43bb98bf Blue Swirl
#define REGS_PER_LINE 4
1790 43bb98bf Blue Swirl
#else
1791 43bb98bf Blue Swirl
#define REGS_PER_LINE 8
1792 43bb98bf Blue Swirl
#endif
1793 43bb98bf Blue Swirl
1794 9a78eead Stefan Weil
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1795 c48fcb47 blueswir1
                    int flags)
1796 c48fcb47 blueswir1
{
1797 c48fcb47 blueswir1
    int i, x;
1798 c48fcb47 blueswir1
1799 77f193da blueswir1
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
1800 77f193da blueswir1
                env->npc);
1801 c48fcb47 blueswir1
    cpu_fprintf(f, "General Registers:\n");
1802 43bb98bf Blue Swirl
1803 43bb98bf Blue Swirl
    for (i = 0; i < 8; i++) {
1804 43bb98bf Blue Swirl
        if (i % REGS_PER_LINE == 0) {
1805 43bb98bf Blue Swirl
            cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
1806 43bb98bf Blue Swirl
        }
1807 43bb98bf Blue Swirl
        cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
1808 43bb98bf Blue Swirl
        if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
1809 43bb98bf Blue Swirl
            cpu_fprintf(f, "\n");
1810 43bb98bf Blue Swirl
        }
1811 43bb98bf Blue Swirl
    }
1812 c48fcb47 blueswir1
    cpu_fprintf(f, "\nCurrent Register Window:\n");
1813 c48fcb47 blueswir1
    for (x = 0; x < 3; x++) {
1814 43bb98bf Blue Swirl
        for (i = 0; i < 8; i++) {
1815 43bb98bf Blue Swirl
            if (i % REGS_PER_LINE == 0) {
1816 43bb98bf Blue Swirl
                cpu_fprintf(f, "%%%c%d-%d: ",
1817 43bb98bf Blue Swirl
                            x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
1818 43bb98bf Blue Swirl
                            i, i + REGS_PER_LINE - 1);
1819 43bb98bf Blue Swirl
            }
1820 43bb98bf Blue Swirl
            cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
1821 43bb98bf Blue Swirl
            if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
1822 43bb98bf Blue Swirl
                cpu_fprintf(f, "\n");
1823 43bb98bf Blue Swirl
            }
1824 43bb98bf Blue Swirl
        }
1825 c48fcb47 blueswir1
    }
1826 c48fcb47 blueswir1
    cpu_fprintf(f, "\nFloating Point Registers:\n");
1827 43bb98bf Blue Swirl
    for (i = 0; i < TARGET_FPREGS; i++) {
1828 c48fcb47 blueswir1
        if ((i & 3) == 0)
1829 c48fcb47 blueswir1
            cpu_fprintf(f, "%%f%02d:", i);
1830 a37ee56c blueswir1
        cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]);
1831 c48fcb47 blueswir1
        if ((i & 3) == 3)
1832 c48fcb47 blueswir1
            cpu_fprintf(f, "\n");
1833 c48fcb47 blueswir1
    }
1834 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1835 43bb98bf Blue Swirl
    cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
1836 113c6106 Stefan Weil
                (unsigned)cpu_get_ccr(env));
1837 5a834bb4 Blue Swirl
    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
1838 43bb98bf Blue Swirl
    cpu_fprintf(f, " xcc: ");
1839 5a834bb4 Blue Swirl
    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
1840 43bb98bf Blue Swirl
    cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
1841 43bb98bf Blue Swirl
                env->psrpil);
1842 43bb98bf Blue Swirl
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
1843 43bb98bf Blue Swirl
                "cleanwin: %d cwp: %d\n",
1844 c48fcb47 blueswir1
                env->cansave, env->canrestore, env->otherwin, env->wstate,
1845 1a14026e blueswir1
                env->cleanwin, env->nwindows - 1 - env->cwp);
1846 43bb98bf Blue Swirl
    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
1847 43bb98bf Blue Swirl
                TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
1848 c48fcb47 blueswir1
#else
1849 5a834bb4 Blue Swirl
    cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
1850 5a834bb4 Blue Swirl
    cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
1851 43bb98bf Blue Swirl
    cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs? 'S' : '-',
1852 43bb98bf Blue Swirl
                env->psrps? 'P' : '-', env->psret? 'E' : '-',
1853 43bb98bf Blue Swirl
                env->wim);
1854 43bb98bf Blue Swirl
    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
1855 43bb98bf Blue Swirl
                env->fsr, env->y);
1856 c48fcb47 blueswir1
#endif
1857 c48fcb47 blueswir1
}