Annotation of qemu/target-sparc/helper.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *  sparc helpers
                      3:  * 
                      4:  *  Copyright (c) 2003-2005 Fabrice Bellard
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     19:  */
                     20: #include <stdarg.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24: #include <inttypes.h>
                     25: #include <signal.h>
                     26: #include <assert.h>
                     27: 
                     28: #include "cpu.h"
                     29: #include "exec-all.h"
                     30: 
                     31: //#define DEBUG_MMU
                     32: 
                     33: /* Sparc MMU emulation */
                     34: 
                     35: /* thread support */
                     36: 
                     37: spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
                     38: 
                     39: void cpu_lock(void)
                     40: {
                     41:     spin_lock(&global_cpu_lock);
                     42: }
                     43: 
                     44: void cpu_unlock(void)
                     45: {
                     46:     spin_unlock(&global_cpu_lock);
                     47: }
                     48: 
                     49: #if defined(CONFIG_USER_ONLY) 
                     50: 
                     51: int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
                     52:                                int is_user, int is_softmmu)
                     53: {
                     54:     if (rw & 2)
                     55:         env->exception_index = TT_TFAULT;
                     56:     else
                     57:         env->exception_index = TT_DFAULT;
                     58:     return 1;
                     59: }
                     60: 
                     61: #else
                     62: 
                     63: #ifndef TARGET_SPARC64
                     64: /*
                     65:  * Sparc V8 Reference MMU (SRMMU)
                     66:  */
                     67: static const int access_table[8][8] = {
                     68:     { 0, 0, 0, 0, 2, 0, 3, 3 },
                     69:     { 0, 0, 0, 0, 2, 0, 0, 0 },
                     70:     { 2, 2, 0, 0, 0, 2, 3, 3 },
                     71:     { 2, 2, 0, 0, 0, 2, 0, 0 },
                     72:     { 2, 0, 2, 0, 2, 2, 3, 3 },
                     73:     { 2, 0, 2, 0, 2, 0, 2, 0 },
                     74:     { 2, 2, 2, 0, 2, 2, 3, 3 },
                     75:     { 2, 2, 2, 0, 2, 2, 2, 0 }
                     76: };
                     77: 
1.1.1.2 ! root       78: static const int perm_table[2][8] = {
        !            79:     {
        !            80:         PAGE_READ,
        !            81:         PAGE_READ | PAGE_WRITE,
        !            82:         PAGE_READ | PAGE_EXEC,
        !            83:         PAGE_READ | PAGE_WRITE | PAGE_EXEC,
        !            84:         PAGE_EXEC,
        !            85:         PAGE_READ | PAGE_WRITE,
        !            86:         PAGE_READ | PAGE_EXEC,
        !            87:         PAGE_READ | PAGE_WRITE | PAGE_EXEC
        !            88:     },
        !            89:     {
        !            90:         PAGE_READ,
        !            91:         PAGE_READ | PAGE_WRITE,
        !            92:         PAGE_READ | PAGE_EXEC,
        !            93:         PAGE_READ | PAGE_WRITE | PAGE_EXEC,
        !            94:         PAGE_EXEC,
        !            95:         PAGE_READ,
        !            96:         0,
        !            97:         0,
        !            98:     }
1.1       root       99: };
                    100: 
                    101: int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                    102:                          int *access_index, target_ulong address, int rw,
                    103:                          int is_user)
                    104: {
                    105:     int access_perms = 0;
                    106:     target_phys_addr_t pde_ptr;
                    107:     uint32_t pde;
                    108:     target_ulong virt_addr;
                    109:     int error_code = 0, is_dirty;
                    110:     unsigned long page_offset;
                    111: 
                    112:     virt_addr = address & TARGET_PAGE_MASK;
                    113:     if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
                    114:        *physical = address;
1.1.1.2 ! root      115:         *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1.1       root      116:         return 0;
                    117:     }
                    118: 
                    119:     *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
                    120:     *physical = 0xfffff000;
                    121: 
                    122:     /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
                    123:     /* Context base + context number */
                    124:     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
                    125:     pde = ldl_phys(pde_ptr);
                    126: 
                    127:     /* Ctx pde */
                    128:     switch (pde & PTE_ENTRYTYPE_MASK) {
                    129:     default:
                    130:     case 0: /* Invalid */
                    131:        return 1 << 2;
                    132:     case 2: /* L0 PTE, maybe should not happen? */
                    133:     case 3: /* Reserved */
                    134:         return 4 << 2;
                    135:     case 1: /* L0 PDE */
                    136:        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
                    137:         pde = ldl_phys(pde_ptr);
                    138: 
                    139:        switch (pde & PTE_ENTRYTYPE_MASK) {
                    140:        default:
                    141:        case 0: /* Invalid */
                    142:            return (1 << 8) | (1 << 2);
                    143:        case 3: /* Reserved */
                    144:            return (1 << 8) | (4 << 2);
                    145:        case 1: /* L1 PDE */
                    146:            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
                    147:             pde = ldl_phys(pde_ptr);
                    148: 
                    149:            switch (pde & PTE_ENTRYTYPE_MASK) {
                    150:            default:
                    151:            case 0: /* Invalid */
                    152:                return (2 << 8) | (1 << 2);
                    153:            case 3: /* Reserved */
                    154:                return (2 << 8) | (4 << 2);
                    155:            case 1: /* L2 PDE */
                    156:                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
                    157:                 pde = ldl_phys(pde_ptr);
                    158: 
                    159:                switch (pde & PTE_ENTRYTYPE_MASK) {
                    160:                default:
                    161:                case 0: /* Invalid */
                    162:                    return (3 << 8) | (1 << 2);
                    163:                case 1: /* PDE, should not happen */
                    164:                case 3: /* Reserved */
                    165:                    return (3 << 8) | (4 << 2);
                    166:                case 2: /* L3 PTE */
                    167:                    virt_addr = address & TARGET_PAGE_MASK;
                    168:                    page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
                    169:                }
                    170:                break;
                    171:            case 2: /* L2 PTE */
                    172:                virt_addr = address & ~0x3ffff;
                    173:                page_offset = address & 0x3ffff;
                    174:            }
                    175:            break;
                    176:        case 2: /* L1 PTE */
                    177:            virt_addr = address & ~0xffffff;
                    178:            page_offset = address & 0xffffff;
                    179:        }
                    180:     }
                    181: 
                    182:     /* update page modified and dirty bits */
                    183:     is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
                    184:     if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
                    185:        pde |= PG_ACCESSED_MASK;
                    186:        if (is_dirty)
                    187:            pde |= PG_MODIFIED_MASK;
                    188:         stl_phys_notdirty(pde_ptr, pde);
                    189:     }
                    190:     /* check access */
                    191:     access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
                    192:     error_code = access_table[*access_index][access_perms];
                    193:     if (error_code && !(env->mmuregs[0] & MMU_NF))
                    194:        return error_code;
                    195: 
                    196:     /* the page can be put in the TLB */
1.1.1.2 ! root      197:     *prot = perm_table[is_user][access_perms];
        !           198:     if (!(pde & PG_MODIFIED_MASK)) {
1.1       root      199:         /* only set write access if already dirty... otherwise wait
                    200:            for dirty access */
1.1.1.2 ! root      201:         *prot &= ~PAGE_WRITE;
1.1       root      202:     }
                    203: 
                    204:     /* Even if large ptes, we map only one 4KB page in the cache to
                    205:        avoid filling it too fast */
                    206:     *physical = ((pde & PTE_ADDR_MASK) << 4) + page_offset;
                    207:     return error_code;
                    208: }
                    209: 
                    210: /* Perform address translation */
                    211: int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                    212:                               int is_user, int is_softmmu)
                    213: {
                    214:     target_phys_addr_t paddr;
                    215:     unsigned long vaddr;
                    216:     int error_code = 0, prot, ret = 0, access_index;
                    217: 
                    218:     error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
                    219:     if (error_code == 0) {
1.1.1.2 ! root      220:        vaddr = address & TARGET_PAGE_MASK;
        !           221:        paddr &= TARGET_PAGE_MASK;
        !           222: #ifdef DEBUG_MMU
        !           223:        printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr);
        !           224: #endif
        !           225:        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
1.1       root      226:        return ret;
                    227:     }
                    228: 
                    229:     if (env->mmuregs[3]) /* Fault status register */
                    230:        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
                    231:     env->mmuregs[3] |= (access_index << 5) | error_code | 2;
                    232:     env->mmuregs[4] = address; /* Fault address register */
                    233: 
                    234:     if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
                    235:         // No fault mode: if a mapping is available, just override
                    236:         // permissions. If no mapping is available, redirect accesses to
                    237:         // neverland. Fake/overridden mappings will be flushed when
                    238:         // switching to normal mode.
                    239:        vaddr = address & TARGET_PAGE_MASK;
1.1.1.2 ! root      240:         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
        !           241:         ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
1.1       root      242:        return ret;
                    243:     } else {
                    244:         if (rw & 2)
                    245:             env->exception_index = TT_TFAULT;
                    246:         else
                    247:             env->exception_index = TT_DFAULT;
                    248:         return 1;
                    249:     }
                    250: }
1.1.1.2 ! root      251: 
        !           252: target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
        !           253: {
        !           254:     target_phys_addr_t pde_ptr;
        !           255:     uint32_t pde;
        !           256: 
        !           257:     /* Context base + context number */
        !           258:     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
        !           259:     pde = ldl_phys(pde_ptr);
        !           260: 
        !           261:     switch (pde & PTE_ENTRYTYPE_MASK) {
        !           262:     default:
        !           263:     case 0: /* Invalid */
        !           264:     case 2: /* PTE, maybe should not happen? */
        !           265:     case 3: /* Reserved */
        !           266:        return 0;
        !           267:     case 1: /* L1 PDE */
        !           268:        if (mmulev == 3)
        !           269:            return pde;
        !           270:        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
        !           271:         pde = ldl_phys(pde_ptr);
        !           272: 
        !           273:        switch (pde & PTE_ENTRYTYPE_MASK) {
        !           274:        default:
        !           275:        case 0: /* Invalid */
        !           276:        case 3: /* Reserved */
        !           277:            return 0;
        !           278:        case 2: /* L1 PTE */
        !           279:            return pde;
        !           280:        case 1: /* L2 PDE */
        !           281:            if (mmulev == 2)
        !           282:                return pde;
        !           283:            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
        !           284:             pde = ldl_phys(pde_ptr);
        !           285: 
        !           286:            switch (pde & PTE_ENTRYTYPE_MASK) {
        !           287:            default:
        !           288:            case 0: /* Invalid */
        !           289:            case 3: /* Reserved */
        !           290:                return 0;
        !           291:            case 2: /* L2 PTE */
        !           292:                return pde;
        !           293:            case 1: /* L3 PDE */
        !           294:                if (mmulev == 1)
        !           295:                    return pde;
        !           296:                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
        !           297:                 pde = ldl_phys(pde_ptr);
        !           298: 
        !           299:                switch (pde & PTE_ENTRYTYPE_MASK) {
        !           300:                default:
        !           301:                case 0: /* Invalid */
        !           302:                case 1: /* PDE, should not happen */
        !           303:                case 3: /* Reserved */
        !           304:                    return 0;
        !           305:                case 2: /* L3 PTE */
        !           306:                    return pde;
        !           307:                }
        !           308:            }
        !           309:        }
        !           310:     }
        !           311:     return 0;
        !           312: }
        !           313: 
        !           314: #ifdef DEBUG_MMU
        !           315: void dump_mmu(CPUState *env)
        !           316: {
        !           317:      target_ulong va, va1, va2;
        !           318:      unsigned int n, m, o;
        !           319:      target_phys_addr_t pde_ptr, pa;
        !           320:     uint32_t pde;
        !           321: 
        !           322:     printf("MMU dump:\n");
        !           323:     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
        !           324:     pde = ldl_phys(pde_ptr);
        !           325:     printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
        !           326:     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
        !           327:        pde_ptr = mmu_probe(env, va, 2);
        !           328:        if (pde_ptr) {
        !           329:            pa = cpu_get_phys_page_debug(env, va);
        !           330:            printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr);
        !           331:            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
        !           332:                pde_ptr = mmu_probe(env, va1, 1);
        !           333:                if (pde_ptr) {
        !           334:                    pa = cpu_get_phys_page_debug(env, va1);
        !           335:                    printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr);
        !           336:                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
        !           337:                        pde_ptr = mmu_probe(env, va2, 0);
        !           338:                        if (pde_ptr) {
        !           339:                            pa = cpu_get_phys_page_debug(env, va2);
        !           340:                            printf("  VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr);
        !           341:                        }
        !           342:                    }
        !           343:                }
        !           344:            }
        !           345:        }
        !           346:     }
        !           347:     printf("MMU dump ends\n");
        !           348: }
        !           349: #endif /* DEBUG_MMU */
        !           350: 
        !           351: #else /* !TARGET_SPARC64 */
1.1       root      352: /*
                    353:  * UltraSparc IIi I/DMMUs
                    354:  */
                    355: static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
                    356:                          int *access_index, target_ulong address, int rw,
                    357:                          int is_user)
                    358: {
                    359:     target_ulong mask;
                    360:     unsigned int i;
                    361: 
                    362:     if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
                    363:        *physical = address;
                    364:        *prot = PAGE_READ | PAGE_WRITE;
                    365:         return 0;
                    366:     }
                    367: 
                    368:     for (i = 0; i < 64; i++) {
                    369:        switch ((env->dtlb_tte[i] >> 61) & 3) {
                    370:        default:
                    371:        case 0x0: // 8k
                    372:            mask = 0xffffffffffffe000ULL;
                    373:            break;
                    374:        case 0x1: // 64k
                    375:            mask = 0xffffffffffff0000ULL;
                    376:            break;
                    377:        case 0x2: // 512k
                    378:            mask = 0xfffffffffff80000ULL;
                    379:            break;
                    380:        case 0x3: // 4M
                    381:            mask = 0xffffffffffc00000ULL;
                    382:            break;
                    383:        }
                    384:        // ctx match, vaddr match?
                    385:        if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
                    386:            (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
                    387:            // valid, access ok?
                    388:            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
                    389:                ((env->dtlb_tte[i] & 0x4) && is_user) ||
                    390:                (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
                    391:                if (env->dmmuregs[3]) /* Fault status register */
                    392:                    env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
                    393:                env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
                    394:                env->dmmuregs[4] = address; /* Fault address register */
                    395:                env->exception_index = TT_DFAULT;
                    396: #ifdef DEBUG_MMU
                    397:                printf("DFAULT at 0x%llx\n", address);
                    398: #endif
                    399:                return 1;
                    400:            }
                    401:            *physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
                    402:            *prot = PAGE_READ;
                    403:            if (env->dtlb_tte[i] & 0x2)
                    404:                *prot |= PAGE_WRITE;
                    405:            return 0;
                    406:        }
                    407:     }
                    408: #ifdef DEBUG_MMU
                    409:     printf("DMISS at 0x%llx\n", address);
                    410: #endif
                    411:     env->exception_index = TT_DMISS;
                    412:     return 1;
                    413: }
                    414: 
                    415: static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
                    416:                          int *access_index, target_ulong address, int rw,
                    417:                          int is_user)
                    418: {
                    419:     target_ulong mask;
                    420:     unsigned int i;
                    421: 
                    422:     if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
                    423:        *physical = address;
1.1.1.2 ! root      424:        *prot = PAGE_EXEC;
1.1       root      425:         return 0;
                    426:     }
                    427: 
                    428:     for (i = 0; i < 64; i++) {
                    429:        switch ((env->itlb_tte[i] >> 61) & 3) {
                    430:        default:
                    431:        case 0x0: // 8k
                    432:            mask = 0xffffffffffffe000ULL;
                    433:            break;
                    434:        case 0x1: // 64k
                    435:            mask = 0xffffffffffff0000ULL;
                    436:            break;
                    437:        case 0x2: // 512k
                    438:            mask = 0xfffffffffff80000ULL;
                    439:            break;
                    440:        case 0x3: // 4M
                    441:            mask = 0xffffffffffc00000ULL;
                    442:                break;
                    443:        }
                    444:        // ctx match, vaddr match?
                    445:        if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
                    446:            (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
                    447:            // valid, access ok?
                    448:            if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
                    449:                ((env->itlb_tte[i] & 0x4) && is_user)) {
                    450:                if (env->immuregs[3]) /* Fault status register */
                    451:                    env->immuregs[3] = 2; /* overflow (not read before another fault) */
                    452:                env->immuregs[3] |= (is_user << 3) | 1;
                    453:                env->exception_index = TT_TFAULT;
                    454: #ifdef DEBUG_MMU
                    455:                printf("TFAULT at 0x%llx\n", address);
                    456: #endif
                    457:                return 1;
                    458:            }
                    459:            *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
1.1.1.2 ! root      460:            *prot = PAGE_EXEC;
1.1       root      461:            return 0;
                    462:        }
                    463:     }
                    464: #ifdef DEBUG_MMU
                    465:     printf("TMISS at 0x%llx\n", address);
                    466: #endif
                    467:     env->exception_index = TT_TMISS;
                    468:     return 1;
                    469: }
                    470: 
                    471: int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
                    472:                          int *access_index, target_ulong address, int rw,
                    473:                          int is_user)
                    474: {
                    475:     if (rw == 2)
                    476:        return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
                    477:     else
                    478:        return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
                    479: }
                    480: 
                    481: /* Perform address translation */
                    482: int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                    483:                               int is_user, int is_softmmu)
                    484: {
                    485:     target_ulong virt_addr, vaddr;
                    486:     target_phys_addr_t paddr;
                    487:     int error_code = 0, prot, ret = 0, access_index;
                    488: 
                    489:     error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
                    490:     if (error_code == 0) {
                    491:        virt_addr = address & TARGET_PAGE_MASK;
                    492:        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
                    493: #ifdef DEBUG_MMU
                    494:        printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr);
                    495: #endif
1.1.1.2 ! root      496:        ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
1.1       root      497:        return ret;
                    498:     }
                    499:     // XXX
                    500:     return 1;
                    501: }
                    502: 
                    503: #ifdef DEBUG_MMU
                    504: void dump_mmu(CPUState *env)
                    505: {
                    506:     unsigned int i;
                    507:     const char *mask;
                    508: 
                    509:     printf("MMU contexts: Primary: %lld, Secondary: %lld\n", env->dmmuregs[1], env->dmmuregs[2]);
                    510:     if ((env->lsu & DMMU_E) == 0) {
                    511:        printf("DMMU disabled\n");
                    512:     } else {
                    513:        printf("DMMU dump:\n");
                    514:        for (i = 0; i < 64; i++) {
                    515:            switch ((env->dtlb_tte[i] >> 61) & 3) {
                    516:            default:
                    517:            case 0x0:
                    518:                mask = "  8k";
                    519:                break;
                    520:            case 0x1:
                    521:                mask = " 64k";
                    522:                break;
                    523:            case 0x2:
                    524:                mask = "512k";
                    525:                break;
                    526:            case 0x3:
                    527:                mask = "  4M";
                    528:                break;
                    529:            }
                    530:            if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
                    531:                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %lld\n",
                    532:                       env->dtlb_tag[i] & ~0x1fffULL,
                    533:                       env->dtlb_tte[i] & 0x1ffffffe000ULL,
                    534:                       mask,
                    535:                       env->dtlb_tte[i] & 0x4? "priv": "user",
                    536:                       env->dtlb_tte[i] & 0x2? "RW": "RO",
                    537:                       env->dtlb_tte[i] & 0x40? "locked": "unlocked",
                    538:                       env->dtlb_tag[i] & 0x1fffULL);
                    539:            }
                    540:        }
                    541:     }
                    542:     if ((env->lsu & IMMU_E) == 0) {
                    543:        printf("IMMU disabled\n");
                    544:     } else {
                    545:        printf("IMMU dump:\n");
                    546:        for (i = 0; i < 64; i++) {
                    547:            switch ((env->itlb_tte[i] >> 61) & 3) {
                    548:            default:
                    549:            case 0x0:
                    550:                mask = "  8k";
                    551:                break;
                    552:            case 0x1:
                    553:                mask = " 64k";
                    554:                break;
                    555:            case 0x2:
                    556:                mask = "512k";
                    557:                break;
                    558:            case 0x3:
                    559:                mask = "  4M";
                    560:                break;
                    561:            }
                    562:            if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
                    563:                printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %lld\n",
                    564:                       env->itlb_tag[i] & ~0x1fffULL,
                    565:                       env->itlb_tte[i] & 0x1ffffffe000ULL,
                    566:                       mask,
                    567:                       env->itlb_tte[i] & 0x4? "priv": "user",
                    568:                       env->itlb_tte[i] & 0x40? "locked": "unlocked",
                    569:                       env->itlb_tag[i] & 0x1fffULL);
                    570:            }
                    571:        }
                    572:     }
                    573: }
1.1.1.2 ! root      574: #endif /* DEBUG_MMU */
        !           575: 
        !           576: #endif /* TARGET_SPARC64 */
        !           577: #endif /* !CONFIG_USER_ONLY */
        !           578: 
        !           579: void memcpy32(target_ulong *dst, const target_ulong *src)
        !           580: {
        !           581:     dst[0] = src[0];
        !           582:     dst[1] = src[1];
        !           583:     dst[2] = src[2];
        !           584:     dst[3] = src[3];
        !           585:     dst[4] = src[4];
        !           586:     dst[5] = src[5];
        !           587:     dst[6] = src[6];
        !           588:     dst[7] = src[7];
        !           589: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.