Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ 2c0d18dd

History | View | Annotate | Download (49.3 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
#include <signal.h>
25 ee5bbe38 bellard
26 ee5bbe38 bellard
#include "cpu.h"
27 ee5bbe38 bellard
#include "exec-all.h"
28 ca10f867 aurel32
#include "qemu-common.h"
29 e8af50a3 bellard
30 e80cfcfc bellard
//#define DEBUG_MMU
31 64a88d5d blueswir1
//#define DEBUG_FEATURES
32 e8af50a3 bellard
33 b8e9fc06 Igor V. Kovalenko
#ifdef DEBUG_MMU
34 b8e9fc06 Igor V. Kovalenko
#define DPRINTF_MMU(fmt, ...) \
35 b8e9fc06 Igor V. Kovalenko
    do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
36 b8e9fc06 Igor V. Kovalenko
#else
37 b8e9fc06 Igor V. Kovalenko
#define DPRINTF_MMU(fmt, ...) do {} while (0)
38 b8e9fc06 Igor V. Kovalenko
#endif
39 b8e9fc06 Igor V. Kovalenko
40 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
41 c48fcb47 blueswir1
42 e8af50a3 bellard
/* Sparc MMU emulation */
43 e8af50a3 bellard
44 5fafdf24 ths
#if defined(CONFIG_USER_ONLY)
45 9d893301 bellard
46 22548760 blueswir1
int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
47 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
48 9d893301 bellard
{
49 878d3096 bellard
    if (rw & 2)
50 22548760 blueswir1
        env1->exception_index = TT_TFAULT;
51 878d3096 bellard
    else
52 22548760 blueswir1
        env1->exception_index = TT_DFAULT;
53 9d893301 bellard
    return 1;
54 9d893301 bellard
}
55 9d893301 bellard
56 9d893301 bellard
#else
57 e8af50a3 bellard
58 3475187d bellard
#ifndef TARGET_SPARC64
59 83469015 bellard
/*
60 83469015 bellard
 * Sparc V8 Reference MMU (SRMMU)
61 83469015 bellard
 */
62 e8af50a3 bellard
static const int access_table[8][8] = {
63 a764a566 blueswir1
    { 0, 0, 0, 0, 8, 0, 12, 12 },
64 a764a566 blueswir1
    { 0, 0, 0, 0, 8, 0, 0, 0 },
65 a764a566 blueswir1
    { 8, 8, 0, 0, 0, 8, 12, 12 },
66 a764a566 blueswir1
    { 8, 8, 0, 0, 0, 8, 0, 0 },
67 a764a566 blueswir1
    { 8, 0, 8, 0, 8, 8, 12, 12 },
68 a764a566 blueswir1
    { 8, 0, 8, 0, 8, 0, 8, 0 },
69 a764a566 blueswir1
    { 8, 8, 8, 0, 8, 8, 12, 12 },
70 a764a566 blueswir1
    { 8, 8, 8, 0, 8, 8, 8, 0 }
71 e8af50a3 bellard
};
72 e8af50a3 bellard
73 227671c9 bellard
static const int perm_table[2][8] = {
74 227671c9 bellard
    {
75 227671c9 bellard
        PAGE_READ,
76 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
77 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
78 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
79 227671c9 bellard
        PAGE_EXEC,
80 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
81 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
82 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC
83 227671c9 bellard
    },
84 227671c9 bellard
    {
85 227671c9 bellard
        PAGE_READ,
86 227671c9 bellard
        PAGE_READ | PAGE_WRITE,
87 227671c9 bellard
        PAGE_READ | PAGE_EXEC,
88 227671c9 bellard
        PAGE_READ | PAGE_WRITE | PAGE_EXEC,
89 227671c9 bellard
        PAGE_EXEC,
90 227671c9 bellard
        PAGE_READ,
91 227671c9 bellard
        0,
92 227671c9 bellard
        0,
93 227671c9 bellard
    }
94 e8af50a3 bellard
};
95 e8af50a3 bellard
96 c227f099 Anthony Liguori
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
97 c48fcb47 blueswir1
                                int *prot, int *access_index,
98 d4c430a8 Paul Brook
                                target_ulong address, int rw, int mmu_idx,
99 d4c430a8 Paul Brook
                                target_ulong *page_size)
100 e8af50a3 bellard
{
101 e80cfcfc bellard
    int access_perms = 0;
102 c227f099 Anthony Liguori
    target_phys_addr_t pde_ptr;
103 af7bf89b bellard
    uint32_t pde;
104 6ebbf390 j_mayer
    int error_code = 0, is_dirty, is_user;
105 e80cfcfc bellard
    unsigned long page_offset;
106 e8af50a3 bellard
107 6ebbf390 j_mayer
    is_user = mmu_idx == MMU_USER_IDX;
108 40ce0a9a blueswir1
109 e8af50a3 bellard
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
110 d4c430a8 Paul Brook
        *page_size = TARGET_PAGE_SIZE;
111 40ce0a9a blueswir1
        // Boot mode: instruction fetches are taken from PROM
112 5578ceab blueswir1
        if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
113 58a770f3 blueswir1
            *physical = env->prom_addr | (address & 0x7ffffULL);
114 40ce0a9a blueswir1
            *prot = PAGE_READ | PAGE_EXEC;
115 40ce0a9a blueswir1
            return 0;
116 40ce0a9a blueswir1
        }
117 0f8a249a blueswir1
        *physical = address;
118 227671c9 bellard
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
119 e80cfcfc bellard
        return 0;
120 e8af50a3 bellard
    }
121 e8af50a3 bellard
122 7483750d bellard
    *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
123 5dcb6b91 blueswir1
    *physical = 0xffffffffffff0000ULL;
124 7483750d bellard
125 e8af50a3 bellard
    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
126 e8af50a3 bellard
    /* Context base + context number */
127 3deaeab7 blueswir1
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
128 49be8030 bellard
    pde = ldl_phys(pde_ptr);
129 e8af50a3 bellard
130 e8af50a3 bellard
    /* Ctx pde */
131 e8af50a3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
132 e80cfcfc bellard
    default:
133 e8af50a3 bellard
    case 0: /* Invalid */
134 0f8a249a blueswir1
        return 1 << 2;
135 e80cfcfc bellard
    case 2: /* L0 PTE, maybe should not happen? */
136 e8af50a3 bellard
    case 3: /* Reserved */
137 7483750d bellard
        return 4 << 2;
138 e80cfcfc bellard
    case 1: /* L0 PDE */
139 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
140 49be8030 bellard
        pde = ldl_phys(pde_ptr);
141 e8af50a3 bellard
142 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
143 0f8a249a blueswir1
        default:
144 0f8a249a blueswir1
        case 0: /* Invalid */
145 0f8a249a blueswir1
            return (1 << 8) | (1 << 2);
146 0f8a249a blueswir1
        case 3: /* Reserved */
147 0f8a249a blueswir1
            return (1 << 8) | (4 << 2);
148 0f8a249a blueswir1
        case 1: /* L1 PDE */
149 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
150 49be8030 bellard
            pde = ldl_phys(pde_ptr);
151 e8af50a3 bellard
152 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
153 0f8a249a blueswir1
            default:
154 0f8a249a blueswir1
            case 0: /* Invalid */
155 0f8a249a blueswir1
                return (2 << 8) | (1 << 2);
156 0f8a249a blueswir1
            case 3: /* Reserved */
157 0f8a249a blueswir1
                return (2 << 8) | (4 << 2);
158 0f8a249a blueswir1
            case 1: /* L2 PDE */
159 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
160 49be8030 bellard
                pde = ldl_phys(pde_ptr);
161 e8af50a3 bellard
162 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
163 0f8a249a blueswir1
                default:
164 0f8a249a blueswir1
                case 0: /* Invalid */
165 0f8a249a blueswir1
                    return (3 << 8) | (1 << 2);
166 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
167 0f8a249a blueswir1
                case 3: /* Reserved */
168 0f8a249a blueswir1
                    return (3 << 8) | (4 << 2);
169 0f8a249a blueswir1
                case 2: /* L3 PTE */
170 77f193da blueswir1
                    page_offset = (address & TARGET_PAGE_MASK) &
171 77f193da blueswir1
                        (TARGET_PAGE_SIZE - 1);
172 0f8a249a blueswir1
                }
173 d4c430a8 Paul Brook
                *page_size = TARGET_PAGE_SIZE;
174 0f8a249a blueswir1
                break;
175 0f8a249a blueswir1
            case 2: /* L2 PTE */
176 0f8a249a blueswir1
                page_offset = address & 0x3ffff;
177 d4c430a8 Paul Brook
                *page_size = 0x40000;
178 0f8a249a blueswir1
            }
179 0f8a249a blueswir1
            break;
180 0f8a249a blueswir1
        case 2: /* L1 PTE */
181 0f8a249a blueswir1
            page_offset = address & 0xffffff;
182 d4c430a8 Paul Brook
            *page_size = 0x1000000;
183 0f8a249a blueswir1
        }
184 e8af50a3 bellard
    }
185 e8af50a3 bellard
186 698235aa Artyom Tarasenko
    /* check access */
187 698235aa Artyom Tarasenko
    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
188 698235aa Artyom Tarasenko
    error_code = access_table[*access_index][access_perms];
189 698235aa Artyom Tarasenko
    if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
190 698235aa Artyom Tarasenko
        return error_code;
191 698235aa Artyom Tarasenko
192 e8af50a3 bellard
    /* update page modified and dirty bits */
193 b769d8fe bellard
    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
194 e8af50a3 bellard
    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
195 0f8a249a blueswir1
        pde |= PG_ACCESSED_MASK;
196 0f8a249a blueswir1
        if (is_dirty)
197 0f8a249a blueswir1
            pde |= PG_MODIFIED_MASK;
198 49be8030 bellard
        stl_phys_notdirty(pde_ptr, pde);
199 e8af50a3 bellard
    }
200 e8af50a3 bellard
201 e8af50a3 bellard
    /* the page can be put in the TLB */
202 227671c9 bellard
    *prot = perm_table[is_user][access_perms];
203 227671c9 bellard
    if (!(pde & PG_MODIFIED_MASK)) {
204 e8af50a3 bellard
        /* only set write access if already dirty... otherwise wait
205 e8af50a3 bellard
           for dirty access */
206 227671c9 bellard
        *prot &= ~PAGE_WRITE;
207 e8af50a3 bellard
    }
208 e8af50a3 bellard
209 e8af50a3 bellard
    /* Even if large ptes, we map only one 4KB page in the cache to
210 e8af50a3 bellard
       avoid filling it too fast */
211 c227f099 Anthony Liguori
    *physical = ((target_phys_addr_t)(pde & PTE_ADDR_MASK) << 4) + page_offset;
212 6f7e9aec bellard
    return error_code;
213 e80cfcfc bellard
}
214 e80cfcfc bellard
215 e80cfcfc bellard
/* Perform address translation */
216 af7bf89b bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
217 6ebbf390 j_mayer
                              int mmu_idx, int is_softmmu)
218 e80cfcfc bellard
{
219 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
220 5dcb6b91 blueswir1
    target_ulong vaddr;
221 d4c430a8 Paul Brook
    target_ulong page_size;
222 d4c430a8 Paul Brook
    int error_code = 0, prot, access_index;
223 e8af50a3 bellard
224 77f193da blueswir1
    error_code = get_physical_address(env, &paddr, &prot, &access_index,
225 d4c430a8 Paul Brook
                                      address, rw, mmu_idx, &page_size);
226 e80cfcfc bellard
    if (error_code == 0) {
227 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
228 0f8a249a blueswir1
        paddr &= TARGET_PAGE_MASK;
229 9e61bde5 bellard
#ifdef DEBUG_MMU
230 0f8a249a blueswir1
        printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
231 5dcb6b91 blueswir1
               TARGET_FMT_lx "\n", address, paddr, vaddr);
232 9e61bde5 bellard
#endif
233 d4c430a8 Paul Brook
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
234 d4c430a8 Paul Brook
        return 0;
235 e80cfcfc bellard
    }
236 e8af50a3 bellard
237 e8af50a3 bellard
    if (env->mmuregs[3]) /* Fault status register */
238 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
239 7483750d bellard
    env->mmuregs[3] |= (access_index << 5) | error_code | 2;
240 e8af50a3 bellard
    env->mmuregs[4] = address; /* Fault address register */
241 e8af50a3 bellard
242 878d3096 bellard
    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
243 6f7e9aec bellard
        // No fault mode: if a mapping is available, just override
244 6f7e9aec bellard
        // permissions. If no mapping is available, redirect accesses to
245 6f7e9aec bellard
        // neverland. Fake/overridden mappings will be flushed when
246 6f7e9aec bellard
        // switching to normal mode.
247 0f8a249a blueswir1
        vaddr = address & TARGET_PAGE_MASK;
248 227671c9 bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
249 d4c430a8 Paul Brook
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE);
250 d4c430a8 Paul Brook
        return 0;
251 7483750d bellard
    } else {
252 7483750d bellard
        if (rw & 2)
253 7483750d bellard
            env->exception_index = TT_TFAULT;
254 7483750d bellard
        else
255 7483750d bellard
            env->exception_index = TT_DFAULT;
256 7483750d bellard
        return 1;
257 878d3096 bellard
    }
258 e8af50a3 bellard
}
259 24741ef3 bellard
260 24741ef3 bellard
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
261 24741ef3 bellard
{
262 c227f099 Anthony Liguori
    target_phys_addr_t pde_ptr;
263 24741ef3 bellard
    uint32_t pde;
264 24741ef3 bellard
265 24741ef3 bellard
    /* Context base + context number */
266 c227f099 Anthony Liguori
    pde_ptr = (target_phys_addr_t)(env->mmuregs[1] << 4) +
267 5dcb6b91 blueswir1
        (env->mmuregs[2] << 2);
268 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
269 24741ef3 bellard
270 24741ef3 bellard
    switch (pde & PTE_ENTRYTYPE_MASK) {
271 24741ef3 bellard
    default:
272 24741ef3 bellard
    case 0: /* Invalid */
273 24741ef3 bellard
    case 2: /* PTE, maybe should not happen? */
274 24741ef3 bellard
    case 3: /* Reserved */
275 0f8a249a blueswir1
        return 0;
276 24741ef3 bellard
    case 1: /* L1 PDE */
277 0f8a249a blueswir1
        if (mmulev == 3)
278 0f8a249a blueswir1
            return pde;
279 0f8a249a blueswir1
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
280 24741ef3 bellard
        pde = ldl_phys(pde_ptr);
281 24741ef3 bellard
282 0f8a249a blueswir1
        switch (pde & PTE_ENTRYTYPE_MASK) {
283 0f8a249a blueswir1
        default:
284 0f8a249a blueswir1
        case 0: /* Invalid */
285 0f8a249a blueswir1
        case 3: /* Reserved */
286 0f8a249a blueswir1
            return 0;
287 0f8a249a blueswir1
        case 2: /* L1 PTE */
288 0f8a249a blueswir1
            return pde;
289 0f8a249a blueswir1
        case 1: /* L2 PDE */
290 0f8a249a blueswir1
            if (mmulev == 2)
291 0f8a249a blueswir1
                return pde;
292 0f8a249a blueswir1
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
293 24741ef3 bellard
            pde = ldl_phys(pde_ptr);
294 24741ef3 bellard
295 0f8a249a blueswir1
            switch (pde & PTE_ENTRYTYPE_MASK) {
296 0f8a249a blueswir1
            default:
297 0f8a249a blueswir1
            case 0: /* Invalid */
298 0f8a249a blueswir1
            case 3: /* Reserved */
299 0f8a249a blueswir1
                return 0;
300 0f8a249a blueswir1
            case 2: /* L2 PTE */
301 0f8a249a blueswir1
                return pde;
302 0f8a249a blueswir1
            case 1: /* L3 PDE */
303 0f8a249a blueswir1
                if (mmulev == 1)
304 0f8a249a blueswir1
                    return pde;
305 0f8a249a blueswir1
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
306 24741ef3 bellard
                pde = ldl_phys(pde_ptr);
307 24741ef3 bellard
308 0f8a249a blueswir1
                switch (pde & PTE_ENTRYTYPE_MASK) {
309 0f8a249a blueswir1
                default:
310 0f8a249a blueswir1
                case 0: /* Invalid */
311 0f8a249a blueswir1
                case 1: /* PDE, should not happen */
312 0f8a249a blueswir1
                case 3: /* Reserved */
313 0f8a249a blueswir1
                    return 0;
314 0f8a249a blueswir1
                case 2: /* L3 PTE */
315 0f8a249a blueswir1
                    return pde;
316 0f8a249a blueswir1
                }
317 0f8a249a blueswir1
            }
318 0f8a249a blueswir1
        }
319 24741ef3 bellard
    }
320 24741ef3 bellard
    return 0;
321 24741ef3 bellard
}
322 24741ef3 bellard
323 d41160a3 Blue Swirl
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
324 24741ef3 bellard
{
325 5dcb6b91 blueswir1
    target_ulong va, va1, va2;
326 5dcb6b91 blueswir1
    unsigned int n, m, o;
327 c227f099 Anthony Liguori
    target_phys_addr_t pde_ptr, pa;
328 24741ef3 bellard
    uint32_t pde;
329 24741ef3 bellard
330 24741ef3 bellard
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
331 24741ef3 bellard
    pde = ldl_phys(pde_ptr);
332 d41160a3 Blue Swirl
    (*cpu_fprintf)(f, "Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
333 d41160a3 Blue Swirl
                   (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
334 24741ef3 bellard
    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
335 0f8a249a blueswir1
        pde = mmu_probe(env, va, 2);
336 0f8a249a blueswir1
        if (pde) {
337 0f8a249a blueswir1
            pa = cpu_get_phys_page_debug(env, va);
338 d41160a3 Blue Swirl
            (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
339 d41160a3 Blue Swirl
                           " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
340 0f8a249a blueswir1
            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
341 0f8a249a blueswir1
                pde = mmu_probe(env, va1, 1);
342 0f8a249a blueswir1
                if (pde) {
343 0f8a249a blueswir1
                    pa = cpu_get_phys_page_debug(env, va1);
344 d41160a3 Blue Swirl
                    (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
345 d41160a3 Blue Swirl
                                   TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
346 d41160a3 Blue Swirl
                                   va1, pa, pde);
347 0f8a249a blueswir1
                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
348 0f8a249a blueswir1
                        pde = mmu_probe(env, va2, 0);
349 0f8a249a blueswir1
                        if (pde) {
350 0f8a249a blueswir1
                            pa = cpu_get_phys_page_debug(env, va2);
351 d41160a3 Blue Swirl
                            (*cpu_fprintf)(f, "  VA: " TARGET_FMT_lx ", PA: "
352 d41160a3 Blue Swirl
                                           TARGET_FMT_plx " PTE: "
353 d41160a3 Blue Swirl
                                           TARGET_FMT_lx "\n",
354 d41160a3 Blue Swirl
                                           va2, pa, pde);
355 0f8a249a blueswir1
                        }
356 0f8a249a blueswir1
                    }
357 0f8a249a blueswir1
                }
358 0f8a249a blueswir1
            }
359 0f8a249a blueswir1
        }
360 24741ef3 bellard
    }
361 24741ef3 bellard
}
362 24741ef3 bellard
363 24741ef3 bellard
#else /* !TARGET_SPARC64 */
364 e8807b14 Igor Kovalenko
365 e8807b14 Igor Kovalenko
// 41 bit physical address space
366 c227f099 Anthony Liguori
static inline target_phys_addr_t ultrasparc_truncate_physical(uint64_t x)
367 e8807b14 Igor Kovalenko
{
368 e8807b14 Igor Kovalenko
    return x & 0x1ffffffffffULL;
369 e8807b14 Igor Kovalenko
}
370 e8807b14 Igor Kovalenko
371 83469015 bellard
/*
372 83469015 bellard
 * UltraSparc IIi I/DMMUs
373 83469015 bellard
 */
374 536ba015 Igor Kovalenko
375 536ba015 Igor Kovalenko
// Returns true if TTE tag is valid and matches virtual address value in context
376 536ba015 Igor Kovalenko
// requires virtual address mask value calculated from TTE entry size
377 6e8e7d4c Igor Kovalenko
static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
378 536ba015 Igor Kovalenko
                                       uint64_t address, uint64_t context,
379 299b520c Igor V. Kovalenko
                                       target_phys_addr_t *physical)
380 536ba015 Igor Kovalenko
{
381 536ba015 Igor Kovalenko
    uint64_t mask;
382 536ba015 Igor Kovalenko
383 6e8e7d4c Igor Kovalenko
    switch ((tlb->tte >> 61) & 3) {
384 536ba015 Igor Kovalenko
    default:
385 536ba015 Igor Kovalenko
    case 0x0: // 8k
386 536ba015 Igor Kovalenko
        mask = 0xffffffffffffe000ULL;
387 536ba015 Igor Kovalenko
        break;
388 536ba015 Igor Kovalenko
    case 0x1: // 64k
389 536ba015 Igor Kovalenko
        mask = 0xffffffffffff0000ULL;
390 536ba015 Igor Kovalenko
        break;
391 536ba015 Igor Kovalenko
    case 0x2: // 512k
392 536ba015 Igor Kovalenko
        mask = 0xfffffffffff80000ULL;
393 536ba015 Igor Kovalenko
        break;
394 536ba015 Igor Kovalenko
    case 0x3: // 4M
395 536ba015 Igor Kovalenko
        mask = 0xffffffffffc00000ULL;
396 536ba015 Igor Kovalenko
        break;
397 536ba015 Igor Kovalenko
    }
398 536ba015 Igor Kovalenko
399 536ba015 Igor Kovalenko
    // valid, context match, virtual address match?
400 f707726e Igor Kovalenko
    if (TTE_IS_VALID(tlb->tte) &&
401 299b520c Igor V. Kovalenko
        (TTE_IS_GLOBAL(tlb->tte) || tlb_compare_context(tlb, context))
402 2a90358f Blue Swirl
        && compare_masked(address, tlb->tag, mask))
403 536ba015 Igor Kovalenko
    {
404 536ba015 Igor Kovalenko
        // decode physical address
405 6e8e7d4c Igor Kovalenko
        *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
406 536ba015 Igor Kovalenko
        return 1;
407 536ba015 Igor Kovalenko
    }
408 536ba015 Igor Kovalenko
409 536ba015 Igor Kovalenko
    return 0;
410 536ba015 Igor Kovalenko
}
411 536ba015 Igor Kovalenko
412 77f193da blueswir1
static int get_physical_address_data(CPUState *env,
413 c227f099 Anthony Liguori
                                     target_phys_addr_t *physical, int *prot,
414 2065061e Igor V. Kovalenko
                                     target_ulong address, int rw, int mmu_idx)
415 3475187d bellard
{
416 3475187d bellard
    unsigned int i;
417 536ba015 Igor Kovalenko
    uint64_t context;
418 3475187d bellard
419 2065061e Igor V. Kovalenko
    int is_user = (mmu_idx == MMU_USER_IDX ||
420 2065061e Igor V. Kovalenko
                   mmu_idx == MMU_USER_SECONDARY_IDX);
421 2065061e Igor V. Kovalenko
422 3475187d bellard
    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
423 e8807b14 Igor Kovalenko
        *physical = ultrasparc_truncate_physical(address);
424 0f8a249a blueswir1
        *prot = PAGE_READ | PAGE_WRITE;
425 3475187d bellard
        return 0;
426 3475187d bellard
    }
427 3475187d bellard
428 2065061e Igor V. Kovalenko
    switch(mmu_idx) {
429 2065061e Igor V. Kovalenko
    case MMU_USER_IDX:
430 2065061e Igor V. Kovalenko
    case MMU_KERNEL_IDX:
431 299b520c Igor V. Kovalenko
        context = env->dmmu.mmu_primary_context & 0x1fff;
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 2065061e Igor V. Kovalenko
        break;
437 2065061e Igor V. Kovalenko
    case MMU_NUCLEUS_IDX:
438 44505216 Blue Swirl
    default:
439 299b520c Igor V. Kovalenko
        context = 0;
440 2065061e Igor V. Kovalenko
        break;
441 299b520c Igor V. Kovalenko
    }
442 536ba015 Igor Kovalenko
443 3475187d bellard
    for (i = 0; i < 64; i++) {
444 afdf8109 blueswir1
        // ctx match, vaddr match, valid?
445 b8e9fc06 Igor V. Kovalenko
        if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
446 b8e9fc06 Igor V. Kovalenko
447 b8e9fc06 Igor V. Kovalenko
            uint8_t fault_type = 0;
448 b8e9fc06 Igor V. Kovalenko
449 afdf8109 blueswir1
            // access ok?
450 b8e9fc06 Igor V. Kovalenko
            if ((env->dtlb[i].tte & 0x4) && is_user) {
451 b8e9fc06 Igor V. Kovalenko
                fault_type |= 1; /* privilege violation */
452 b8e9fc06 Igor V. Kovalenko
                env->exception_index = TT_DFAULT;
453 6e8e7d4c Igor Kovalenko
454 b8e9fc06 Igor V. Kovalenko
                DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64
455 b8e9fc06 Igor V. Kovalenko
                            " mmu_idx=%d tl=%d\n",
456 b8e9fc06 Igor V. Kovalenko
                            address, context, mmu_idx, env->tl);
457 b8e9fc06 Igor V. Kovalenko
            } else if (!(env->dtlb[i].tte & 0x2) && (rw == 1)) {
458 b8e9fc06 Igor V. Kovalenko
                env->exception_index = TT_DPROT;
459 6e8e7d4c Igor Kovalenko
460 b8e9fc06 Igor V. Kovalenko
                DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64
461 b8e9fc06 Igor V. Kovalenko
                            " mmu_idx=%d tl=%d\n",
462 b8e9fc06 Igor V. Kovalenko
                            address, context, mmu_idx, env->tl);
463 b8e9fc06 Igor V. Kovalenko
            } else {
464 b8e9fc06 Igor V. Kovalenko
                *prot = PAGE_READ;
465 b8e9fc06 Igor V. Kovalenko
                if (env->dtlb[i].tte & 0x2)
466 b8e9fc06 Igor V. Kovalenko
                    *prot |= PAGE_WRITE;
467 b8e9fc06 Igor V. Kovalenko
468 b8e9fc06 Igor V. Kovalenko
                TTE_SET_USED(env->dtlb[i].tte);
469 b8e9fc06 Igor V. Kovalenko
470 b8e9fc06 Igor V. Kovalenko
                return 0;
471 b8e9fc06 Igor V. Kovalenko
            }
472 b8e9fc06 Igor V. Kovalenko
473 b8e9fc06 Igor V. Kovalenko
            if (env->dmmu.sfsr & 1) /* Fault status register */
474 b8e9fc06 Igor V. Kovalenko
                env->dmmu.sfsr = 2; /* overflow (not read before
475 77f193da blueswir1
                                             another fault) */
476 6e8e7d4c Igor Kovalenko
477 b8e9fc06 Igor V. Kovalenko
            env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
478 6e8e7d4c Igor Kovalenko
479 b8e9fc06 Igor V. Kovalenko
            env->dmmu.sfsr |= (fault_type << 7);
480 6e8e7d4c Igor Kovalenko
481 b8e9fc06 Igor V. Kovalenko
            env->dmmu.sfar = address; /* Fault address register */
482 9168b3a5 Igor V. Kovalenko
483 9168b3a5 Igor V. Kovalenko
            env->dmmu.tag_access = (address & ~0x1fffULL) | context;
484 9168b3a5 Igor V. Kovalenko
485 b8e9fc06 Igor V. Kovalenko
            return 1;
486 0f8a249a blueswir1
        }
487 3475187d bellard
    }
488 b8e9fc06 Igor V. Kovalenko
489 b8e9fc06 Igor V. Kovalenko
    DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n",
490 b8e9fc06 Igor V. Kovalenko
                address, context);
491 b8e9fc06 Igor V. Kovalenko
492 6e8e7d4c Igor Kovalenko
    env->dmmu.tag_access = (address & ~0x1fffULL) | context;
493 83469015 bellard
    env->exception_index = TT_DMISS;
494 3475187d bellard
    return 1;
495 3475187d bellard
}
496 3475187d bellard
497 77f193da blueswir1
static int get_physical_address_code(CPUState *env,
498 c227f099 Anthony Liguori
                                     target_phys_addr_t *physical, int *prot,
499 2065061e Igor V. Kovalenko
                                     target_ulong address, int mmu_idx)
500 3475187d bellard
{
501 3475187d bellard
    unsigned int i;
502 536ba015 Igor Kovalenko
    uint64_t context;
503 3475187d bellard
504 2065061e Igor V. Kovalenko
    int is_user = (mmu_idx == MMU_USER_IDX ||
505 2065061e Igor V. Kovalenko
                   mmu_idx == MMU_USER_SECONDARY_IDX);
506 2065061e Igor V. Kovalenko
507 e8807b14 Igor Kovalenko
    if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
508 e8807b14 Igor Kovalenko
        /* IMMU disabled */
509 e8807b14 Igor Kovalenko
        *physical = ultrasparc_truncate_physical(address);
510 0f8a249a blueswir1
        *prot = PAGE_EXEC;
511 3475187d bellard
        return 0;
512 3475187d bellard
    }
513 83469015 bellard
514 299b520c Igor V. Kovalenko
    if (env->tl == 0) {
515 2065061e Igor V. Kovalenko
        /* PRIMARY context */
516 299b520c Igor V. Kovalenko
        context = env->dmmu.mmu_primary_context & 0x1fff;
517 299b520c Igor V. Kovalenko
    } else {
518 2065061e Igor V. Kovalenko
        /* NUCLEUS context */
519 299b520c Igor V. Kovalenko
        context = 0;
520 299b520c Igor V. Kovalenko
    }
521 536ba015 Igor Kovalenko
522 3475187d bellard
    for (i = 0; i < 64; i++) {
523 afdf8109 blueswir1
        // ctx match, vaddr match, valid?
524 6e8e7d4c Igor Kovalenko
        if (ultrasparc_tag_match(&env->itlb[i],
525 299b520c Igor V. Kovalenko
                                 address, context, physical)) {
526 afdf8109 blueswir1
            // access ok?
527 6e8e7d4c Igor Kovalenko
            if ((env->itlb[i].tte & 0x4) && is_user) {
528 6e8e7d4c Igor Kovalenko
                if (env->immu.sfsr) /* Fault status register */
529 6e8e7d4c Igor Kovalenko
                    env->immu.sfsr = 2; /* overflow (not read before
530 77f193da blueswir1
                                             another fault) */
531 6e8e7d4c Igor Kovalenko
                env->immu.sfsr |= (is_user << 3) | 1;
532 0f8a249a blueswir1
                env->exception_index = TT_TFAULT;
533 b8e9fc06 Igor V. Kovalenko
534 9168b3a5 Igor V. Kovalenko
                env->immu.tag_access = (address & ~0x1fffULL) | context;
535 9168b3a5 Igor V. Kovalenko
536 b8e9fc06 Igor V. Kovalenko
                DPRINTF_MMU("TFAULT at %" PRIx64 " context %" PRIx64 "\n",
537 b8e9fc06 Igor V. Kovalenko
                            address, context);
538 b8e9fc06 Igor V. Kovalenko
539 0f8a249a blueswir1
                return 1;
540 0f8a249a blueswir1
            }
541 0f8a249a blueswir1
            *prot = PAGE_EXEC;
542 f707726e Igor Kovalenko
            TTE_SET_USED(env->itlb[i].tte);
543 0f8a249a blueswir1
            return 0;
544 0f8a249a blueswir1
        }
545 3475187d bellard
    }
546 b8e9fc06 Igor V. Kovalenko
547 b8e9fc06 Igor V. Kovalenko
    DPRINTF_MMU("TMISS at %" PRIx64 " context %" PRIx64 "\n",
548 b8e9fc06 Igor V. Kovalenko
                address, context);
549 b8e9fc06 Igor V. Kovalenko
550 7ab463cb Blue Swirl
    /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
551 6e8e7d4c Igor Kovalenko
    env->immu.tag_access = (address & ~0x1fffULL) | context;
552 83469015 bellard
    env->exception_index = TT_TMISS;
553 3475187d bellard
    return 1;
554 3475187d bellard
}
555 3475187d bellard
556 c227f099 Anthony Liguori
static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
557 c48fcb47 blueswir1
                                int *prot, int *access_index,
558 d4c430a8 Paul Brook
                                target_ulong address, int rw, int mmu_idx,
559 d4c430a8 Paul Brook
                                target_ulong *page_size)
560 3475187d bellard
{
561 d4c430a8 Paul Brook
    /* ??? We treat everything as a small page, then explicitly flush
562 d4c430a8 Paul Brook
       everything when an entry is evicted.  */
563 d4c430a8 Paul Brook
    *page_size = TARGET_PAGE_SIZE;
564 9fd1ae3a Igor V. Kovalenko
565 9fd1ae3a Igor V. Kovalenko
#if defined (DEBUG_MMU)
566 9fd1ae3a Igor V. Kovalenko
    /* safety net to catch wrong softmmu index use from dynamic code */
567 9fd1ae3a Igor V. Kovalenko
    if (env->tl > 0 && mmu_idx != MMU_NUCLEUS_IDX) {
568 9fd1ae3a Igor V. Kovalenko
        DPRINTF_MMU("get_physical_address %s tl=%d mmu_idx=%d"
569 9fd1ae3a Igor V. Kovalenko
                    " primary context=%" PRIx64
570 9fd1ae3a Igor V. Kovalenko
                    " secondary context=%" PRIx64
571 9fd1ae3a Igor V. Kovalenko
                " address=%" PRIx64
572 9fd1ae3a Igor V. Kovalenko
                "\n",
573 9fd1ae3a Igor V. Kovalenko
                (rw == 2 ? "CODE" : "DATA"),
574 9fd1ae3a Igor V. Kovalenko
                env->tl, mmu_idx,
575 9fd1ae3a Igor V. Kovalenko
                env->dmmu.mmu_primary_context,
576 9fd1ae3a Igor V. Kovalenko
                env->dmmu.mmu_secondary_context,
577 9fd1ae3a Igor V. Kovalenko
                address);
578 9fd1ae3a Igor V. Kovalenko
    }
579 9fd1ae3a Igor V. Kovalenko
#endif
580 9fd1ae3a Igor V. Kovalenko
581 3475187d bellard
    if (rw == 2)
582 22548760 blueswir1
        return get_physical_address_code(env, physical, prot, address,
583 2065061e Igor V. Kovalenko
                                         mmu_idx);
584 3475187d bellard
    else
585 22548760 blueswir1
        return get_physical_address_data(env, physical, prot, address, rw,
586 2065061e Igor V. Kovalenko
                                         mmu_idx);
587 3475187d bellard
}
588 3475187d bellard
589 3475187d bellard
/* Perform address translation */
590 3475187d bellard
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
591 6ebbf390 j_mayer
                              int mmu_idx, int is_softmmu)
592 3475187d bellard
{
593 83469015 bellard
    target_ulong virt_addr, vaddr;
594 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
595 d4c430a8 Paul Brook
    target_ulong page_size;
596 d4c430a8 Paul Brook
    int error_code = 0, prot, access_index;
597 3475187d bellard
598 77f193da blueswir1
    error_code = get_physical_address(env, &paddr, &prot, &access_index,
599 d4c430a8 Paul Brook
                                      address, rw, mmu_idx, &page_size);
600 3475187d bellard
    if (error_code == 0) {
601 0f8a249a blueswir1
        virt_addr = address & TARGET_PAGE_MASK;
602 77f193da blueswir1
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
603 77f193da blueswir1
                             (TARGET_PAGE_SIZE - 1));
604 b8e9fc06 Igor V. Kovalenko
605 b8e9fc06 Igor V. Kovalenko
        DPRINTF_MMU("Translate at %" PRIx64 " -> %" PRIx64 ","
606 b8e9fc06 Igor V. Kovalenko
                    " vaddr %" PRIx64
607 b8e9fc06 Igor V. Kovalenko
                    " mmu_idx=%d"
608 b8e9fc06 Igor V. Kovalenko
                    " tl=%d"
609 b8e9fc06 Igor V. Kovalenko
                    " primary context=%" PRIx64
610 b8e9fc06 Igor V. Kovalenko
                    " secondary context=%" PRIx64
611 b8e9fc06 Igor V. Kovalenko
                    "\n",
612 b8e9fc06 Igor V. Kovalenko
                    address, paddr, vaddr, mmu_idx, env->tl,
613 b8e9fc06 Igor V. Kovalenko
                    env->dmmu.mmu_primary_context,
614 b8e9fc06 Igor V. Kovalenko
                    env->dmmu.mmu_secondary_context);
615 b8e9fc06 Igor V. Kovalenko
616 d4c430a8 Paul Brook
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
617 d4c430a8 Paul Brook
        return 0;
618 3475187d bellard
    }
619 3475187d bellard
    // XXX
620 3475187d bellard
    return 1;
621 3475187d bellard
}
622 3475187d bellard
623 d41160a3 Blue Swirl
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
624 83469015 bellard
{
625 83469015 bellard
    unsigned int i;
626 83469015 bellard
    const char *mask;
627 83469015 bellard
628 d41160a3 Blue Swirl
    (*cpu_fprintf)(f, "MMU contexts: Primary: %" PRId64 ", Secondary: %"
629 d41160a3 Blue Swirl
                   PRId64 "\n",
630 d41160a3 Blue Swirl
                   env->dmmu.mmu_primary_context,
631 d41160a3 Blue Swirl
                   env->dmmu.mmu_secondary_context);
632 83469015 bellard
    if ((env->lsu & DMMU_E) == 0) {
633 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "DMMU disabled\n");
634 83469015 bellard
    } else {
635 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "DMMU dump\n");
636 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
637 31a68d57 Blue Swirl
            switch ((env->dtlb[i].tte >> 61) & 3) {
638 0f8a249a blueswir1
            default:
639 0f8a249a blueswir1
            case 0x0:
640 0f8a249a blueswir1
                mask = "  8k";
641 0f8a249a blueswir1
                break;
642 0f8a249a blueswir1
            case 0x1:
643 0f8a249a blueswir1
                mask = " 64k";
644 0f8a249a blueswir1
                break;
645 0f8a249a blueswir1
            case 0x2:
646 0f8a249a blueswir1
                mask = "512k";
647 0f8a249a blueswir1
                break;
648 0f8a249a blueswir1
            case 0x3:
649 0f8a249a blueswir1
                mask = "  4M";
650 0f8a249a blueswir1
                break;
651 0f8a249a blueswir1
            }
652 31a68d57 Blue Swirl
            if ((env->dtlb[i].tte & 0x8000000000000000ULL) != 0) {
653 d41160a3 Blue Swirl
                (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %" PRIx64
654 d41160a3 Blue Swirl
                               ", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
655 d41160a3 Blue Swirl
                               i,
656 d41160a3 Blue Swirl
                               env->dtlb[i].tag & (uint64_t)~0x1fffULL,
657 d41160a3 Blue Swirl
                               env->dtlb[i].tte & (uint64_t)0x1ffffffe000ULL,
658 d41160a3 Blue Swirl
                               mask,
659 d41160a3 Blue Swirl
                               env->dtlb[i].tte & 0x4? "priv": "user",
660 d41160a3 Blue Swirl
                               env->dtlb[i].tte & 0x2? "RW": "RO",
661 d41160a3 Blue Swirl
                               env->dtlb[i].tte & 0x40? "locked": "unlocked",
662 d41160a3 Blue Swirl
                               env->dtlb[i].tag & (uint64_t)0x1fffULL,
663 d41160a3 Blue Swirl
                               TTE_IS_GLOBAL(env->dtlb[i].tte)?
664 d41160a3 Blue Swirl
                               "global" : "local");
665 0f8a249a blueswir1
            }
666 0f8a249a blueswir1
        }
667 83469015 bellard
    }
668 83469015 bellard
    if ((env->lsu & IMMU_E) == 0) {
669 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "IMMU disabled\n");
670 83469015 bellard
    } else {
671 d41160a3 Blue Swirl
        (*cpu_fprintf)(f, "IMMU dump\n");
672 0f8a249a blueswir1
        for (i = 0; i < 64; i++) {
673 31a68d57 Blue Swirl
            switch ((env->itlb[i].tte >> 61) & 3) {
674 0f8a249a blueswir1
            default:
675 0f8a249a blueswir1
            case 0x0:
676 0f8a249a blueswir1
                mask = "  8k";
677 0f8a249a blueswir1
                break;
678 0f8a249a blueswir1
            case 0x1:
679 0f8a249a blueswir1
                mask = " 64k";
680 0f8a249a blueswir1
                break;
681 0f8a249a blueswir1
            case 0x2:
682 0f8a249a blueswir1
                mask = "512k";
683 0f8a249a blueswir1
                break;
684 0f8a249a blueswir1
            case 0x3:
685 0f8a249a blueswir1
                mask = "  4M";
686 0f8a249a blueswir1
                break;
687 0f8a249a blueswir1
            }
688 31a68d57 Blue Swirl
            if ((env->itlb[i].tte & 0x8000000000000000ULL) != 0) {
689 d41160a3 Blue Swirl
                (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %" PRIx64
690 d41160a3 Blue Swirl
                               ", %s, %s, %s, ctx %" PRId64 " %s\n",
691 d41160a3 Blue Swirl
                               i,
692 d41160a3 Blue Swirl
                               env->itlb[i].tag & (uint64_t)~0x1fffULL,
693 d41160a3 Blue Swirl
                               env->itlb[i].tte & (uint64_t)0x1ffffffe000ULL,
694 d41160a3 Blue Swirl
                               mask,
695 d41160a3 Blue Swirl
                               env->itlb[i].tte & 0x4? "priv": "user",
696 d41160a3 Blue Swirl
                               env->itlb[i].tte & 0x40? "locked": "unlocked",
697 d41160a3 Blue Swirl
                               env->itlb[i].tag & (uint64_t)0x1fffULL,
698 d41160a3 Blue Swirl
                               TTE_IS_GLOBAL(env->itlb[i].tte)?
699 d41160a3 Blue Swirl
                               "global" : "local");
700 0f8a249a blueswir1
            }
701 0f8a249a blueswir1
        }
702 83469015 bellard
    }
703 83469015 bellard
}
704 24741ef3 bellard
705 24741ef3 bellard
#endif /* TARGET_SPARC64 */
706 24741ef3 bellard
#endif /* !CONFIG_USER_ONLY */
707 24741ef3 bellard
708 c48fcb47 blueswir1
709 4fcc562b Paul Brook
#if !defined(CONFIG_USER_ONLY)
710 2065061e Igor V. Kovalenko
target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr,
711 2065061e Igor V. Kovalenko
                                           int mmu_idx)
712 c48fcb47 blueswir1
{
713 c227f099 Anthony Liguori
    target_phys_addr_t phys_addr;
714 d4c430a8 Paul Brook
    target_ulong page_size;
715 c48fcb47 blueswir1
    int prot, access_index;
716 c48fcb47 blueswir1
717 c48fcb47 blueswir1
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
718 2065061e Igor V. Kovalenko
                             mmu_idx, &page_size) != 0)
719 c48fcb47 blueswir1
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
720 2065061e Igor V. Kovalenko
                                 0, mmu_idx, &page_size) != 0)
721 c48fcb47 blueswir1
            return -1;
722 c48fcb47 blueswir1
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
723 c48fcb47 blueswir1
        return -1;
724 c48fcb47 blueswir1
    return phys_addr;
725 c48fcb47 blueswir1
}
726 2065061e Igor V. Kovalenko
727 2065061e Igor V. Kovalenko
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
728 2065061e Igor V. Kovalenko
{
729 9fd1ae3a Igor V. Kovalenko
    return cpu_get_phys_page_nofault(env, addr, cpu_mmu_index(env));
730 2065061e Igor V. Kovalenko
}
731 c48fcb47 blueswir1
#endif
732 c48fcb47 blueswir1
733 c48fcb47 blueswir1
void cpu_reset(CPUSPARCState *env)
734 c48fcb47 blueswir1
{
735 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
736 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
737 eca1bdf4 aliguori
        log_cpu_state(env, 0);
738 eca1bdf4 aliguori
    }
739 eca1bdf4 aliguori
740 c48fcb47 blueswir1
    tlb_flush(env, 1);
741 c48fcb47 blueswir1
    env->cwp = 0;
742 5210977a Igor Kovalenko
#ifndef TARGET_SPARC64
743 c48fcb47 blueswir1
    env->wim = 1;
744 5210977a Igor Kovalenko
#endif
745 c48fcb47 blueswir1
    env->regwptr = env->regbase + (env->cwp * 16);
746 6b743278 Blue Swirl
    CC_OP = CC_OP_FLAGS;
747 c48fcb47 blueswir1
#if defined(CONFIG_USER_ONLY)
748 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
749 1a14026e blueswir1
    env->cleanwin = env->nwindows - 2;
750 1a14026e blueswir1
    env->cansave = env->nwindows - 2;
751 c48fcb47 blueswir1
    env->pstate = PS_RMO | PS_PEF | PS_IE;
752 c48fcb47 blueswir1
    env->asi = 0x82; // Primary no-fault
753 c48fcb47 blueswir1
#endif
754 c48fcb47 blueswir1
#else
755 5210977a Igor Kovalenko
#if !defined(TARGET_SPARC64)
756 c48fcb47 blueswir1
    env->psret = 0;
757 c48fcb47 blueswir1
    env->psrs = 1;
758 c48fcb47 blueswir1
    env->psrps = 1;
759 2aae2b8e Igor V. Kovalenko
#endif
760 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
761 8194f35a Igor Kovalenko
    env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
762 2aae2b8e Igor V. Kovalenko
    env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
763 8194f35a Igor Kovalenko
    env->tl = env->maxtl;
764 8194f35a Igor Kovalenko
    cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
765 415fc906 blueswir1
    env->lsu = 0;
766 c48fcb47 blueswir1
#else
767 c48fcb47 blueswir1
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
768 5578ceab blueswir1
    env->mmuregs[0] |= env->def->mmu_bm;
769 c48fcb47 blueswir1
#endif
770 e87231d4 blueswir1
    env->pc = 0;
771 c48fcb47 blueswir1
    env->npc = env->pc + 4;
772 c48fcb47 blueswir1
#endif
773 b04d9890 Fabien Chouteau
    env->cache_control = 0;
774 c48fcb47 blueswir1
}
775 c48fcb47 blueswir1
776 64a88d5d blueswir1
static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
777 c48fcb47 blueswir1
{
778 64a88d5d blueswir1
    sparc_def_t def1, *def = &def1;
779 c48fcb47 blueswir1
780 64a88d5d blueswir1
    if (cpu_sparc_find_by_name(def, cpu_model) < 0)
781 64a88d5d blueswir1
        return -1;
782 c48fcb47 blueswir1
783 5578ceab blueswir1
    env->def = qemu_mallocz(sizeof(*def));
784 5578ceab blueswir1
    memcpy(env->def, def, sizeof(*def));
785 5578ceab blueswir1
#if defined(CONFIG_USER_ONLY)
786 5578ceab blueswir1
    if ((env->def->features & CPU_FEATURE_FLOAT))
787 5578ceab blueswir1
        env->def->features |= CPU_FEATURE_FLOAT128;
788 5578ceab blueswir1
#endif
789 c48fcb47 blueswir1
    env->cpu_model_str = cpu_model;
790 c48fcb47 blueswir1
    env->version = def->iu_version;
791 c48fcb47 blueswir1
    env->fsr = def->fpu_version;
792 1a14026e blueswir1
    env->nwindows = def->nwindows;
793 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
794 c48fcb47 blueswir1
    env->mmuregs[0] |= def->mmu_version;
795 c48fcb47 blueswir1
    cpu_sparc_set_id(env, 0);
796 963262de blueswir1
    env->mxccregs[7] |= def->mxcc_version;
797 1a14026e blueswir1
#else
798 fb79ceb9 blueswir1
    env->mmu_version = def->mmu_version;
799 c19148bd blueswir1
    env->maxtl = def->maxtl;
800 c19148bd blueswir1
    env->version |= def->maxtl << 8;
801 1a14026e blueswir1
    env->version |= def->nwindows - 1;
802 c48fcb47 blueswir1
#endif
803 64a88d5d blueswir1
    return 0;
804 64a88d5d blueswir1
}
805 64a88d5d blueswir1
806 64a88d5d blueswir1
static void cpu_sparc_close(CPUSPARCState *env)
807 64a88d5d blueswir1
{
808 5578ceab blueswir1
    free(env->def);
809 64a88d5d blueswir1
    free(env);
810 64a88d5d blueswir1
}
811 64a88d5d blueswir1
812 64a88d5d blueswir1
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
813 64a88d5d blueswir1
{
814 64a88d5d blueswir1
    CPUSPARCState *env;
815 64a88d5d blueswir1
816 64a88d5d blueswir1
    env = qemu_mallocz(sizeof(CPUSPARCState));
817 64a88d5d blueswir1
    cpu_exec_init(env);
818 c48fcb47 blueswir1
819 c48fcb47 blueswir1
    gen_intermediate_code_init(env);
820 c48fcb47 blueswir1
821 64a88d5d blueswir1
    if (cpu_sparc_register(env, cpu_model) < 0) {
822 64a88d5d blueswir1
        cpu_sparc_close(env);
823 64a88d5d blueswir1
        return NULL;
824 64a88d5d blueswir1
    }
825 0bf46a40 aliguori
    qemu_init_vcpu(env);
826 c48fcb47 blueswir1
827 c48fcb47 blueswir1
    return env;
828 c48fcb47 blueswir1
}
829 c48fcb47 blueswir1
830 c48fcb47 blueswir1
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
831 c48fcb47 blueswir1
{
832 c48fcb47 blueswir1
#if !defined(TARGET_SPARC64)
833 c48fcb47 blueswir1
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
834 c48fcb47 blueswir1
#endif
835 c48fcb47 blueswir1
}
836 c48fcb47 blueswir1
837 c48fcb47 blueswir1
static const sparc_def_t sparc_defs[] = {
838 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
839 c48fcb47 blueswir1
    {
840 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64",
841 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
842 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
843 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
844 1a14026e blueswir1
        .nwindows = 4,
845 c19148bd blueswir1
        .maxtl = 4,
846 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
847 c48fcb47 blueswir1
    },
848 c48fcb47 blueswir1
    {
849 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 III",
850 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
851 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
852 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
853 1a14026e blueswir1
        .nwindows = 5,
854 c19148bd blueswir1
        .maxtl = 4,
855 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
856 c48fcb47 blueswir1
    },
857 c48fcb47 blueswir1
    {
858 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 IV",
859 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
860 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
861 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
862 1a14026e blueswir1
        .nwindows = 8,
863 c19148bd blueswir1
        .maxtl = 5,
864 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
865 c48fcb47 blueswir1
    },
866 c48fcb47 blueswir1
    {
867 c48fcb47 blueswir1
        .name = "Fujitsu Sparc64 V",
868 c19148bd blueswir1
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
869 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
870 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
871 1a14026e blueswir1
        .nwindows = 8,
872 c19148bd blueswir1
        .maxtl = 5,
873 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
874 c48fcb47 blueswir1
    },
875 c48fcb47 blueswir1
    {
876 c48fcb47 blueswir1
        .name = "TI UltraSparc I",
877 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
878 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
879 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
880 1a14026e blueswir1
        .nwindows = 8,
881 c19148bd blueswir1
        .maxtl = 5,
882 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
883 c48fcb47 blueswir1
    },
884 c48fcb47 blueswir1
    {
885 c48fcb47 blueswir1
        .name = "TI UltraSparc II",
886 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
887 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
888 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
889 1a14026e blueswir1
        .nwindows = 8,
890 c19148bd blueswir1
        .maxtl = 5,
891 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
892 c48fcb47 blueswir1
    },
893 c48fcb47 blueswir1
    {
894 c48fcb47 blueswir1
        .name = "TI UltraSparc IIi",
895 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
896 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
897 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
898 1a14026e blueswir1
        .nwindows = 8,
899 c19148bd blueswir1
        .maxtl = 5,
900 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
901 c48fcb47 blueswir1
    },
902 c48fcb47 blueswir1
    {
903 c48fcb47 blueswir1
        .name = "TI UltraSparc IIe",
904 c19148bd blueswir1
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
905 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
906 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
907 1a14026e blueswir1
        .nwindows = 8,
908 c19148bd blueswir1
        .maxtl = 5,
909 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
910 c48fcb47 blueswir1
    },
911 c48fcb47 blueswir1
    {
912 c48fcb47 blueswir1
        .name = "Sun UltraSparc III",
913 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
914 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
915 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
916 1a14026e blueswir1
        .nwindows = 8,
917 c19148bd blueswir1
        .maxtl = 5,
918 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
919 c48fcb47 blueswir1
    },
920 c48fcb47 blueswir1
    {
921 c48fcb47 blueswir1
        .name = "Sun UltraSparc III Cu",
922 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
923 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
924 fb79ceb9 blueswir1
        .mmu_version = mmu_us_3,
925 1a14026e blueswir1
        .nwindows = 8,
926 c19148bd blueswir1
        .maxtl = 5,
927 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
928 c48fcb47 blueswir1
    },
929 c48fcb47 blueswir1
    {
930 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi",
931 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
932 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
933 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
934 1a14026e blueswir1
        .nwindows = 8,
935 c19148bd blueswir1
        .maxtl = 5,
936 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
937 c48fcb47 blueswir1
    },
938 c48fcb47 blueswir1
    {
939 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV",
940 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
941 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
942 fb79ceb9 blueswir1
        .mmu_version = mmu_us_4,
943 1a14026e blueswir1
        .nwindows = 8,
944 c19148bd blueswir1
        .maxtl = 5,
945 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
946 c48fcb47 blueswir1
    },
947 c48fcb47 blueswir1
    {
948 c48fcb47 blueswir1
        .name = "Sun UltraSparc IV+",
949 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
950 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
951 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
952 1a14026e blueswir1
        .nwindows = 8,
953 c19148bd blueswir1
        .maxtl = 5,
954 fb79ceb9 blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
955 c48fcb47 blueswir1
    },
956 c48fcb47 blueswir1
    {
957 c48fcb47 blueswir1
        .name = "Sun UltraSparc IIIi+",
958 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
959 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
960 fb79ceb9 blueswir1
        .mmu_version = mmu_us_3,
961 1a14026e blueswir1
        .nwindows = 8,
962 c19148bd blueswir1
        .maxtl = 5,
963 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
964 c48fcb47 blueswir1
    },
965 c48fcb47 blueswir1
    {
966 c7ba218d blueswir1
        .name = "Sun UltraSparc T1",
967 c7ba218d blueswir1
        // defined in sparc_ifu_fdp.v and ctu.h
968 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
969 c7ba218d blueswir1
        .fpu_version = 0x00000000,
970 c7ba218d blueswir1
        .mmu_version = mmu_sun4v,
971 c7ba218d blueswir1
        .nwindows = 8,
972 c19148bd blueswir1
        .maxtl = 6,
973 c7ba218d blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
974 c7ba218d blueswir1
        | CPU_FEATURE_GL,
975 c7ba218d blueswir1
    },
976 c7ba218d blueswir1
    {
977 c7ba218d blueswir1
        .name = "Sun UltraSparc T2",
978 c7ba218d blueswir1
        // defined in tlu_asi_ctl.v and n2_revid_cust.v
979 c19148bd blueswir1
        .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
980 c7ba218d blueswir1
        .fpu_version = 0x00000000,
981 c7ba218d blueswir1
        .mmu_version = mmu_sun4v,
982 c7ba218d blueswir1
        .nwindows = 8,
983 c19148bd blueswir1
        .maxtl = 6,
984 c7ba218d blueswir1
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
985 c7ba218d blueswir1
        | CPU_FEATURE_GL,
986 c7ba218d blueswir1
    },
987 c7ba218d blueswir1
    {
988 c48fcb47 blueswir1
        .name = "NEC UltraSparc I",
989 c19148bd blueswir1
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
990 c48fcb47 blueswir1
        .fpu_version = 0x00000000,
991 fb79ceb9 blueswir1
        .mmu_version = mmu_us_12,
992 1a14026e blueswir1
        .nwindows = 8,
993 c19148bd blueswir1
        .maxtl = 5,
994 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
995 c48fcb47 blueswir1
    },
996 c48fcb47 blueswir1
#else
997 c48fcb47 blueswir1
    {
998 c48fcb47 blueswir1
        .name = "Fujitsu MB86900",
999 c48fcb47 blueswir1
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
1000 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1001 c48fcb47 blueswir1
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
1002 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1003 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1004 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1005 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1006 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1007 1a14026e blueswir1
        .nwindows = 7,
1008 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
1009 c48fcb47 blueswir1
    },
1010 c48fcb47 blueswir1
    {
1011 c48fcb47 blueswir1
        .name = "Fujitsu MB86904",
1012 c48fcb47 blueswir1
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
1013 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1014 c48fcb47 blueswir1
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
1015 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1016 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1017 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1018 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1019 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1020 1a14026e blueswir1
        .nwindows = 8,
1021 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1022 c48fcb47 blueswir1
    },
1023 c48fcb47 blueswir1
    {
1024 c48fcb47 blueswir1
        .name = "Fujitsu MB86907",
1025 c48fcb47 blueswir1
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
1026 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1027 c48fcb47 blueswir1
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
1028 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1029 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1030 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1031 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1032 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1033 1a14026e blueswir1
        .nwindows = 8,
1034 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1035 c48fcb47 blueswir1
    },
1036 c48fcb47 blueswir1
    {
1037 c48fcb47 blueswir1
        .name = "LSI L64811",
1038 c48fcb47 blueswir1
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
1039 c48fcb47 blueswir1
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
1040 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1041 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1042 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1043 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1044 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1045 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1046 1a14026e blueswir1
        .nwindows = 8,
1047 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1048 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1049 c48fcb47 blueswir1
    },
1050 c48fcb47 blueswir1
    {
1051 c48fcb47 blueswir1
        .name = "Cypress CY7C601",
1052 c48fcb47 blueswir1
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
1053 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1054 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1055 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1056 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1057 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1058 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1059 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1060 1a14026e blueswir1
        .nwindows = 8,
1061 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1062 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1063 c48fcb47 blueswir1
    },
1064 c48fcb47 blueswir1
    {
1065 c48fcb47 blueswir1
        .name = "Cypress CY7C611",
1066 c48fcb47 blueswir1
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
1067 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
1068 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1069 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1070 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1071 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1072 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1073 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1074 1a14026e blueswir1
        .nwindows = 8,
1075 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1076 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1077 c48fcb47 blueswir1
    },
1078 c48fcb47 blueswir1
    {
1079 c48fcb47 blueswir1
        .name = "TI MicroSparc I",
1080 c48fcb47 blueswir1
        .iu_version = 0x41000000,
1081 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1082 c48fcb47 blueswir1
        .mmu_version = 0x41000000,
1083 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1084 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1085 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1086 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1087 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x0000003f,
1088 1a14026e blueswir1
        .nwindows = 7,
1089 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
1090 e30b4678 blueswir1
        CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
1091 e30b4678 blueswir1
        CPU_FEATURE_FMUL,
1092 c48fcb47 blueswir1
    },
1093 c48fcb47 blueswir1
    {
1094 c48fcb47 blueswir1
        .name = "TI MicroSparc II",
1095 c48fcb47 blueswir1
        .iu_version = 0x42000000,
1096 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1097 c48fcb47 blueswir1
        .mmu_version = 0x02000000,
1098 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1099 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1100 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1101 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016fff,
1102 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1103 1a14026e blueswir1
        .nwindows = 8,
1104 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1105 c48fcb47 blueswir1
    },
1106 c48fcb47 blueswir1
    {
1107 c48fcb47 blueswir1
        .name = "TI MicroSparc IIep",
1108 c48fcb47 blueswir1
        .iu_version = 0x42000000,
1109 c48fcb47 blueswir1
        .fpu_version = 4 << 17,
1110 c48fcb47 blueswir1
        .mmu_version = 0x04000000,
1111 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1112 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x00ffffc0,
1113 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x000000ff,
1114 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0x00016bff,
1115 c48fcb47 blueswir1
        .mmu_trcr_mask = 0x00ffffff,
1116 1a14026e blueswir1
        .nwindows = 8,
1117 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1118 c48fcb47 blueswir1
    },
1119 c48fcb47 blueswir1
    {
1120 b5154bde blueswir1
        .name = "TI SuperSparc 40", // STP1020NPGA
1121 963262de blueswir1
        .iu_version = 0x41000000, // SuperSPARC 2.x
1122 b5154bde blueswir1
        .fpu_version = 0 << 17,
1123 963262de blueswir1
        .mmu_version = 0x00000800, // SuperSPARC 2.x, no MXCC
1124 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1125 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1126 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1127 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1128 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1129 1a14026e blueswir1
        .nwindows = 8,
1130 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1131 b5154bde blueswir1
    },
1132 b5154bde blueswir1
    {
1133 b5154bde blueswir1
        .name = "TI SuperSparc 50", // STP1020PGA
1134 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC 3.x
1135 b5154bde blueswir1
        .fpu_version = 0 << 17,
1136 963262de blueswir1
        .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC
1137 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1138 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1139 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1140 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1141 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1142 1a14026e blueswir1
        .nwindows = 8,
1143 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1144 b5154bde blueswir1
    },
1145 b5154bde blueswir1
    {
1146 c48fcb47 blueswir1
        .name = "TI SuperSparc 51",
1147 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC 3.x
1148 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1149 963262de blueswir1
        .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC
1150 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1151 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1152 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1153 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1154 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1155 963262de blueswir1
        .mxcc_version = 0x00000104,
1156 1a14026e blueswir1
        .nwindows = 8,
1157 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1158 c48fcb47 blueswir1
    },
1159 c48fcb47 blueswir1
    {
1160 b5154bde blueswir1
        .name = "TI SuperSparc 60", // STP1020APGA
1161 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC 3.x
1162 b5154bde blueswir1
        .fpu_version = 0 << 17,
1163 963262de blueswir1
        .mmu_version = 0x01000800, // SuperSPARC 3.x, no MXCC
1164 b5154bde blueswir1
        .mmu_bm = 0x00002000,
1165 b5154bde blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1166 b5154bde blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1167 b5154bde blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1168 b5154bde blueswir1
        .mmu_trcr_mask = 0xffffffff,
1169 1a14026e blueswir1
        .nwindows = 8,
1170 b5154bde blueswir1
        .features = CPU_DEFAULT_FEATURES,
1171 b5154bde blueswir1
    },
1172 b5154bde blueswir1
    {
1173 c48fcb47 blueswir1
        .name = "TI SuperSparc 61",
1174 963262de blueswir1
        .iu_version = 0x44000000, // SuperSPARC 3.x
1175 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1176 963262de blueswir1
        .mmu_version = 0x01000000, // SuperSPARC 3.x, MXCC
1177 963262de blueswir1
        .mmu_bm = 0x00002000,
1178 963262de blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1179 963262de blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1180 963262de blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1181 963262de blueswir1
        .mmu_trcr_mask = 0xffffffff,
1182 963262de blueswir1
        .mxcc_version = 0x00000104,
1183 963262de blueswir1
        .nwindows = 8,
1184 963262de blueswir1
        .features = CPU_DEFAULT_FEATURES,
1185 963262de blueswir1
    },
1186 963262de blueswir1
    {
1187 963262de blueswir1
        .name = "TI SuperSparc II",
1188 963262de blueswir1
        .iu_version = 0x40000000, // SuperSPARC II 1.x
1189 963262de blueswir1
        .fpu_version = 0 << 17,
1190 963262de blueswir1
        .mmu_version = 0x08000000, // SuperSPARC II 1.x, MXCC
1191 c48fcb47 blueswir1
        .mmu_bm = 0x00002000,
1192 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0xffffffc0,
1193 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000ffff,
1194 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1195 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1196 963262de blueswir1
        .mxcc_version = 0x00000104,
1197 1a14026e blueswir1
        .nwindows = 8,
1198 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1199 c48fcb47 blueswir1
    },
1200 c48fcb47 blueswir1
    {
1201 c48fcb47 blueswir1
        .name = "Ross RT625",
1202 c48fcb47 blueswir1
        .iu_version = 0x1e000000,
1203 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1204 c48fcb47 blueswir1
        .mmu_version = 0x1e000000,
1205 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1206 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1207 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1208 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1209 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1210 1a14026e blueswir1
        .nwindows = 8,
1211 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1212 c48fcb47 blueswir1
    },
1213 c48fcb47 blueswir1
    {
1214 c48fcb47 blueswir1
        .name = "Ross RT620",
1215 c48fcb47 blueswir1
        .iu_version = 0x1f000000,
1216 c48fcb47 blueswir1
        .fpu_version = 1 << 17,
1217 c48fcb47 blueswir1
        .mmu_version = 0x1f000000,
1218 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1219 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1220 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1221 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1222 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1223 1a14026e blueswir1
        .nwindows = 8,
1224 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1225 c48fcb47 blueswir1
    },
1226 c48fcb47 blueswir1
    {
1227 c48fcb47 blueswir1
        .name = "BIT B5010",
1228 c48fcb47 blueswir1
        .iu_version = 0x20000000,
1229 c48fcb47 blueswir1
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
1230 c48fcb47 blueswir1
        .mmu_version = 0x20000000,
1231 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1232 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1233 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1234 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1235 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1236 1a14026e blueswir1
        .nwindows = 8,
1237 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1238 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1239 c48fcb47 blueswir1
    },
1240 c48fcb47 blueswir1
    {
1241 c48fcb47 blueswir1
        .name = "Matsushita MN10501",
1242 c48fcb47 blueswir1
        .iu_version = 0x50000000,
1243 c48fcb47 blueswir1
        .fpu_version = 0 << 17,
1244 c48fcb47 blueswir1
        .mmu_version = 0x50000000,
1245 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1246 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1247 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1248 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1249 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1250 1a14026e blueswir1
        .nwindows = 8,
1251 e30b4678 blueswir1
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
1252 e30b4678 blueswir1
        CPU_FEATURE_FSMULD,
1253 c48fcb47 blueswir1
    },
1254 c48fcb47 blueswir1
    {
1255 c48fcb47 blueswir1
        .name = "Weitek W8601",
1256 c48fcb47 blueswir1
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
1257 c48fcb47 blueswir1
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
1258 c48fcb47 blueswir1
        .mmu_version = 0x10 << 24,
1259 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1260 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1261 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1262 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1263 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1264 1a14026e blueswir1
        .nwindows = 8,
1265 64a88d5d blueswir1
        .features = CPU_DEFAULT_FEATURES,
1266 c48fcb47 blueswir1
    },
1267 c48fcb47 blueswir1
    {
1268 c48fcb47 blueswir1
        .name = "LEON2",
1269 c48fcb47 blueswir1
        .iu_version = 0xf2000000,
1270 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1271 c48fcb47 blueswir1
        .mmu_version = 0xf2000000,
1272 c48fcb47 blueswir1
        .mmu_bm = 0x00004000,
1273 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1274 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1275 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1276 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1277 1a14026e blueswir1
        .nwindows = 8,
1278 b04d9890 Fabien Chouteau
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
1279 c48fcb47 blueswir1
    },
1280 c48fcb47 blueswir1
    {
1281 c48fcb47 blueswir1
        .name = "LEON3",
1282 c48fcb47 blueswir1
        .iu_version = 0xf3000000,
1283 c48fcb47 blueswir1
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
1284 c48fcb47 blueswir1
        .mmu_version = 0xf3000000,
1285 b04d9890 Fabien Chouteau
        .mmu_bm = 0x00000000,
1286 c48fcb47 blueswir1
        .mmu_ctpr_mask = 0x007ffff0,
1287 c48fcb47 blueswir1
        .mmu_cxr_mask = 0x0000003f,
1288 c48fcb47 blueswir1
        .mmu_sfsr_mask = 0xffffffff,
1289 c48fcb47 blueswir1
        .mmu_trcr_mask = 0xffffffff,
1290 1a14026e blueswir1
        .nwindows = 8,
1291 4a2ba232 Fabien Chouteau
        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
1292 60f356e8 Fabien Chouteau
        CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
1293 c48fcb47 blueswir1
    },
1294 c48fcb47 blueswir1
#endif
1295 c48fcb47 blueswir1
};
1296 c48fcb47 blueswir1
1297 64a88d5d blueswir1
static const char * const feature_name[] = {
1298 64a88d5d blueswir1
    "float",
1299 64a88d5d blueswir1
    "float128",
1300 64a88d5d blueswir1
    "swap",
1301 64a88d5d blueswir1
    "mul",
1302 64a88d5d blueswir1
    "div",
1303 64a88d5d blueswir1
    "flush",
1304 64a88d5d blueswir1
    "fsqrt",
1305 64a88d5d blueswir1
    "fmul",
1306 64a88d5d blueswir1
    "vis1",
1307 64a88d5d blueswir1
    "vis2",
1308 e30b4678 blueswir1
    "fsmuld",
1309 fb79ceb9 blueswir1
    "hypv",
1310 fb79ceb9 blueswir1
    "cmt",
1311 fb79ceb9 blueswir1
    "gl",
1312 64a88d5d blueswir1
};
1313 64a88d5d blueswir1
1314 9a78eead Stefan Weil
static void print_features(FILE *f, fprintf_function cpu_fprintf,
1315 64a88d5d blueswir1
                           uint32_t features, const char *prefix)
1316 c48fcb47 blueswir1
{
1317 c48fcb47 blueswir1
    unsigned int i;
1318 c48fcb47 blueswir1
1319 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1320 64a88d5d blueswir1
        if (feature_name[i] && (features & (1 << i))) {
1321 64a88d5d blueswir1
            if (prefix)
1322 64a88d5d blueswir1
                (*cpu_fprintf)(f, "%s", prefix);
1323 64a88d5d blueswir1
            (*cpu_fprintf)(f, "%s ", feature_name[i]);
1324 64a88d5d blueswir1
        }
1325 64a88d5d blueswir1
}
1326 64a88d5d blueswir1
1327 64a88d5d blueswir1
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
1328 64a88d5d blueswir1
{
1329 64a88d5d blueswir1
    unsigned int i;
1330 64a88d5d blueswir1
1331 64a88d5d blueswir1
    for (i = 0; i < ARRAY_SIZE(feature_name); i++)
1332 64a88d5d blueswir1
        if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
1333 64a88d5d blueswir1
            *features |= 1 << i;
1334 64a88d5d blueswir1
            return;
1335 64a88d5d blueswir1
        }
1336 64a88d5d blueswir1
    fprintf(stderr, "CPU feature %s not found\n", flagname);
1337 64a88d5d blueswir1
}
1338 64a88d5d blueswir1
1339 22548760 blueswir1
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
1340 64a88d5d blueswir1
{
1341 64a88d5d blueswir1
    unsigned int i;
1342 64a88d5d blueswir1
    const sparc_def_t *def = NULL;
1343 64a88d5d blueswir1
    char *s = strdup(cpu_model);
1344 64a88d5d blueswir1
    char *featurestr, *name = strtok(s, ",");
1345 64a88d5d blueswir1
    uint32_t plus_features = 0;
1346 64a88d5d blueswir1
    uint32_t minus_features = 0;
1347 0bfcd599 Blue Swirl
    uint64_t iu_version;
1348 1a14026e blueswir1
    uint32_t fpu_version, mmu_version, nwindows;
1349 64a88d5d blueswir1
1350 b1503cda malc
    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
1351 c48fcb47 blueswir1
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
1352 64a88d5d blueswir1
            def = &sparc_defs[i];
1353 c48fcb47 blueswir1
        }
1354 c48fcb47 blueswir1
    }
1355 64a88d5d blueswir1
    if (!def)
1356 64a88d5d blueswir1
        goto error;
1357 64a88d5d blueswir1
    memcpy(cpu_def, def, sizeof(*def));
1358 64a88d5d blueswir1
1359 64a88d5d blueswir1
    featurestr = strtok(NULL, ",");
1360 64a88d5d blueswir1
    while (featurestr) {
1361 64a88d5d blueswir1
        char *val;
1362 64a88d5d blueswir1
1363 64a88d5d blueswir1
        if (featurestr[0] == '+') {
1364 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &plus_features);
1365 64a88d5d blueswir1
        } else if (featurestr[0] == '-') {
1366 64a88d5d blueswir1
            add_flagname_to_bitmaps(featurestr + 1, &minus_features);
1367 64a88d5d blueswir1
        } else if ((val = strchr(featurestr, '='))) {
1368 64a88d5d blueswir1
            *val = 0; val++;
1369 64a88d5d blueswir1
            if (!strcmp(featurestr, "iu_version")) {
1370 64a88d5d blueswir1
                char *err;
1371 64a88d5d blueswir1
1372 64a88d5d blueswir1
                iu_version = strtoll(val, &err, 0);
1373 64a88d5d blueswir1
                if (!*val || *err) {
1374 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1375 64a88d5d blueswir1
                    goto error;
1376 64a88d5d blueswir1
                }
1377 64a88d5d blueswir1
                cpu_def->iu_version = iu_version;
1378 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1379 0bfcd599 Blue Swirl
                fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
1380 64a88d5d blueswir1
#endif
1381 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "fpu_version")) {
1382 64a88d5d blueswir1
                char *err;
1383 64a88d5d blueswir1
1384 64a88d5d blueswir1
                fpu_version = strtol(val, &err, 0);
1385 64a88d5d blueswir1
                if (!*val || *err) {
1386 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1387 64a88d5d blueswir1
                    goto error;
1388 64a88d5d blueswir1
                }
1389 64a88d5d blueswir1
                cpu_def->fpu_version = fpu_version;
1390 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1391 0bf9e31a Blue Swirl
                fprintf(stderr, "fpu_version %x\n", fpu_version);
1392 64a88d5d blueswir1
#endif
1393 64a88d5d blueswir1
            } else if (!strcmp(featurestr, "mmu_version")) {
1394 64a88d5d blueswir1
                char *err;
1395 64a88d5d blueswir1
1396 64a88d5d blueswir1
                mmu_version = strtol(val, &err, 0);
1397 64a88d5d blueswir1
                if (!*val || *err) {
1398 64a88d5d blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1399 64a88d5d blueswir1
                    goto error;
1400 64a88d5d blueswir1
                }
1401 64a88d5d blueswir1
                cpu_def->mmu_version = mmu_version;
1402 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1403 0bf9e31a Blue Swirl
                fprintf(stderr, "mmu_version %x\n", mmu_version);
1404 64a88d5d blueswir1
#endif
1405 1a14026e blueswir1
            } else if (!strcmp(featurestr, "nwindows")) {
1406 1a14026e blueswir1
                char *err;
1407 1a14026e blueswir1
1408 1a14026e blueswir1
                nwindows = strtol(val, &err, 0);
1409 1a14026e blueswir1
                if (!*val || *err || nwindows > MAX_NWINDOWS ||
1410 1a14026e blueswir1
                    nwindows < MIN_NWINDOWS) {
1411 1a14026e blueswir1
                    fprintf(stderr, "bad numerical value %s\n", val);
1412 1a14026e blueswir1
                    goto error;
1413 1a14026e blueswir1
                }
1414 1a14026e blueswir1
                cpu_def->nwindows = nwindows;
1415 1a14026e blueswir1
#ifdef DEBUG_FEATURES
1416 1a14026e blueswir1
                fprintf(stderr, "nwindows %d\n", nwindows);
1417 1a14026e blueswir1
#endif
1418 64a88d5d blueswir1
            } else {
1419 64a88d5d blueswir1
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1420 64a88d5d blueswir1
                goto error;
1421 64a88d5d blueswir1
            }
1422 64a88d5d blueswir1
        } else {
1423 77f193da blueswir1
            fprintf(stderr, "feature string `%s' not in format "
1424 77f193da blueswir1
                    "(+feature|-feature|feature=xyz)\n", featurestr);
1425 64a88d5d blueswir1
            goto error;
1426 64a88d5d blueswir1
        }
1427 64a88d5d blueswir1
        featurestr = strtok(NULL, ",");
1428 64a88d5d blueswir1
    }
1429 64a88d5d blueswir1
    cpu_def->features |= plus_features;
1430 64a88d5d blueswir1
    cpu_def->features &= ~minus_features;
1431 64a88d5d blueswir1
#ifdef DEBUG_FEATURES
1432 64a88d5d blueswir1
    print_features(stderr, fprintf, cpu_def->features, NULL);
1433 64a88d5d blueswir1
#endif
1434 64a88d5d blueswir1
    free(s);
1435 64a88d5d blueswir1
    return 0;
1436 64a88d5d blueswir1
1437 64a88d5d blueswir1
 error:
1438 64a88d5d blueswir1
    free(s);
1439 64a88d5d blueswir1
    return -1;
1440 c48fcb47 blueswir1
}
1441 c48fcb47 blueswir1
1442 9a78eead Stefan Weil
void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1443 c48fcb47 blueswir1
{
1444 c48fcb47 blueswir1
    unsigned int i;
1445 c48fcb47 blueswir1
1446 b1503cda malc
    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
1447 1a14026e blueswir1
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
1448 c48fcb47 blueswir1
                       sparc_defs[i].name,
1449 c48fcb47 blueswir1
                       sparc_defs[i].iu_version,
1450 c48fcb47 blueswir1
                       sparc_defs[i].fpu_version,
1451 1a14026e blueswir1
                       sparc_defs[i].mmu_version,
1452 1a14026e blueswir1
                       sparc_defs[i].nwindows);
1453 77f193da blueswir1
        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
1454 77f193da blueswir1
                       ~sparc_defs[i].features, "-");
1455 77f193da blueswir1
        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
1456 77f193da blueswir1
                       sparc_defs[i].features, "+");
1457 64a88d5d blueswir1
        (*cpu_fprintf)(f, "\n");
1458 c48fcb47 blueswir1
    }
1459 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
1460 f76981b1 blueswir1
    print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
1461 64a88d5d blueswir1
    (*cpu_fprintf)(f, "\n");
1462 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
1463 f76981b1 blueswir1
    print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
1464 f76981b1 blueswir1
    (*cpu_fprintf)(f, "\n");
1465 f76981b1 blueswir1
    (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
1466 f76981b1 blueswir1
                   "fpu_version mmu_version nwindows\n");
1467 c48fcb47 blueswir1
}
1468 c48fcb47 blueswir1
1469 9a78eead Stefan Weil
static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
1470 43bb98bf Blue Swirl
                         uint32_t cc)
1471 43bb98bf Blue Swirl
{
1472 43bb98bf Blue Swirl
    cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG? 'N' : '-',
1473 43bb98bf Blue Swirl
                cc & PSR_ZERO? 'Z' : '-', cc & PSR_OVF? 'V' : '-',
1474 43bb98bf Blue Swirl
                cc & PSR_CARRY? 'C' : '-');
1475 43bb98bf Blue Swirl
}
1476 43bb98bf Blue Swirl
1477 43bb98bf Blue Swirl
#ifdef TARGET_SPARC64
1478 43bb98bf Blue Swirl
#define REGS_PER_LINE 4
1479 43bb98bf Blue Swirl
#else
1480 43bb98bf Blue Swirl
#define REGS_PER_LINE 8
1481 43bb98bf Blue Swirl
#endif
1482 43bb98bf Blue Swirl
1483 9a78eead Stefan Weil
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1484 c48fcb47 blueswir1
                    int flags)
1485 c48fcb47 blueswir1
{
1486 c48fcb47 blueswir1
    int i, x;
1487 c48fcb47 blueswir1
1488 77f193da blueswir1
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
1489 77f193da blueswir1
                env->npc);
1490 c48fcb47 blueswir1
    cpu_fprintf(f, "General Registers:\n");
1491 43bb98bf Blue Swirl
1492 43bb98bf Blue Swirl
    for (i = 0; i < 8; i++) {
1493 43bb98bf Blue Swirl
        if (i % REGS_PER_LINE == 0) {
1494 43bb98bf Blue Swirl
            cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
1495 43bb98bf Blue Swirl
        }
1496 43bb98bf Blue Swirl
        cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
1497 43bb98bf Blue Swirl
        if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
1498 43bb98bf Blue Swirl
            cpu_fprintf(f, "\n");
1499 43bb98bf Blue Swirl
        }
1500 43bb98bf Blue Swirl
    }
1501 c48fcb47 blueswir1
    cpu_fprintf(f, "\nCurrent Register Window:\n");
1502 c48fcb47 blueswir1
    for (x = 0; x < 3; x++) {
1503 43bb98bf Blue Swirl
        for (i = 0; i < 8; i++) {
1504 43bb98bf Blue Swirl
            if (i % REGS_PER_LINE == 0) {
1505 43bb98bf Blue Swirl
                cpu_fprintf(f, "%%%c%d-%d: ",
1506 43bb98bf Blue Swirl
                            x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
1507 43bb98bf Blue Swirl
                            i, i + REGS_PER_LINE - 1);
1508 43bb98bf Blue Swirl
            }
1509 43bb98bf Blue Swirl
            cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
1510 43bb98bf Blue Swirl
            if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
1511 43bb98bf Blue Swirl
                cpu_fprintf(f, "\n");
1512 43bb98bf Blue Swirl
            }
1513 43bb98bf Blue Swirl
        }
1514 c48fcb47 blueswir1
    }
1515 c48fcb47 blueswir1
    cpu_fprintf(f, "\nFloating Point Registers:\n");
1516 43bb98bf Blue Swirl
    for (i = 0; i < TARGET_FPREGS; i++) {
1517 c48fcb47 blueswir1
        if ((i & 3) == 0)
1518 c48fcb47 blueswir1
            cpu_fprintf(f, "%%f%02d:", i);
1519 a37ee56c blueswir1
        cpu_fprintf(f, " %016f", *(float *)&env->fpr[i]);
1520 c48fcb47 blueswir1
        if ((i & 3) == 3)
1521 c48fcb47 blueswir1
            cpu_fprintf(f, "\n");
1522 c48fcb47 blueswir1
    }
1523 c48fcb47 blueswir1
#ifdef TARGET_SPARC64
1524 43bb98bf Blue Swirl
    cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
1525 113c6106 Stefan Weil
                (unsigned)cpu_get_ccr(env));
1526 5a834bb4 Blue Swirl
    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
1527 43bb98bf Blue Swirl
    cpu_fprintf(f, " xcc: ");
1528 5a834bb4 Blue Swirl
    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
1529 43bb98bf Blue Swirl
    cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
1530 43bb98bf Blue Swirl
                env->psrpil);
1531 43bb98bf Blue Swirl
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
1532 43bb98bf Blue Swirl
                "cleanwin: %d cwp: %d\n",
1533 c48fcb47 blueswir1
                env->cansave, env->canrestore, env->otherwin, env->wstate,
1534 1a14026e blueswir1
                env->cleanwin, env->nwindows - 1 - env->cwp);
1535 43bb98bf Blue Swirl
    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
1536 43bb98bf Blue Swirl
                TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
1537 c48fcb47 blueswir1
#else
1538 5a834bb4 Blue Swirl
    cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
1539 5a834bb4 Blue Swirl
    cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
1540 43bb98bf Blue Swirl
    cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs? 'S' : '-',
1541 43bb98bf Blue Swirl
                env->psrps? 'P' : '-', env->psret? 'E' : '-',
1542 43bb98bf Blue Swirl
                env->wim);
1543 43bb98bf Blue Swirl
    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
1544 43bb98bf Blue Swirl
                env->fsr, env->y);
1545 c48fcb47 blueswir1
#endif
1546 c48fcb47 blueswir1
}