Detabify
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3195 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2e03286b9a
commit
0f8a249a0b
@ -22,9 +22,9 @@
|
||||
#define TARGET_HAS_ICE 1
|
||||
|
||||
#if !defined(TARGET_SPARC64)
|
||||
#define ELF_MACHINE EM_SPARC
|
||||
#define ELF_MACHINE EM_SPARC
|
||||
#else
|
||||
#define ELF_MACHINE EM_SPARCV9
|
||||
#define ELF_MACHINE EM_SPARCV9
|
||||
#endif
|
||||
|
||||
/*#define EXCP_INTERRUPT 0x100*/
|
||||
@ -143,8 +143,8 @@
|
||||
#define FSR_FCC0 (1<<10)
|
||||
|
||||
/* MMU */
|
||||
#define MMU_E (1<<0)
|
||||
#define MMU_NF (1<<1)
|
||||
#define MMU_E (1<<0)
|
||||
#define MMU_NF (1<<1)
|
||||
|
||||
#define PTE_ENTRYTYPE_MASK 3
|
||||
#define PTE_ACCESS_MASK 0x1c
|
||||
@ -152,8 +152,8 @@
|
||||
#define PTE_PPN_SHIFT 7
|
||||
#define PTE_ADDR_MASK 0xffffff00
|
||||
|
||||
#define PG_ACCESSED_BIT 5
|
||||
#define PG_MODIFIED_BIT 6
|
||||
#define PG_ACCESSED_BIT 5
|
||||
#define PG_MODIFIED_BIT 6
|
||||
#define PG_CACHE_BIT 7
|
||||
|
||||
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
|
||||
@ -221,7 +221,7 @@ typedef struct CPUSPARCState {
|
||||
uint64_t tnpc[MAXTL];
|
||||
uint64_t tstate[MAXTL];
|
||||
uint32_t tt[MAXTL];
|
||||
uint32_t xcc; /* Extended integer condition codes */
|
||||
uint32_t xcc; /* Extended integer condition codes */
|
||||
uint32_t asi;
|
||||
uint32_t pstate;
|
||||
uint32_t tl;
|
||||
@ -245,12 +245,12 @@ typedef struct CPUSPARCState {
|
||||
} CPUSPARCState;
|
||||
#if defined(TARGET_SPARC64)
|
||||
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
|
||||
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
||||
env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
|
||||
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
||||
env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
|
||||
} while (0)
|
||||
#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL)
|
||||
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
|
||||
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
|
||||
#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
|
||||
env->fsr = _tmp & 0x3fcfc1c3ffULL; \
|
||||
} while (0)
|
||||
#else
|
||||
#define GET_FSR32(env) (env->fsr)
|
||||
@ -268,31 +268,31 @@ void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
|
||||
int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
|
||||
|
||||
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
|
||||
(env->psref? PSR_EF : 0) | \
|
||||
(env->psrpil << 8) | \
|
||||
(env->psrs? PSR_S : 0) | \
|
||||
(env->psrps? PSR_PS : 0) | \
|
||||
(env->psret? PSR_ET : 0) | env->cwp)
|
||||
(env->psref? PSR_EF : 0) | \
|
||||
(env->psrpil << 8) | \
|
||||
(env->psrs? PSR_S : 0) | \
|
||||
(env->psrps? PSR_PS : 0) | \
|
||||
(env->psret? PSR_ET : 0) | env->cwp)
|
||||
|
||||
#ifndef NO_CPU_IO_DEFS
|
||||
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
|
||||
#endif
|
||||
|
||||
#define PUT_PSR(env, val) do { int _tmp = val; \
|
||||
env->psr = _tmp & PSR_ICC; \
|
||||
env->psref = (_tmp & PSR_EF)? 1 : 0; \
|
||||
env->psrpil = (_tmp & PSR_PIL) >> 8; \
|
||||
env->psrs = (_tmp & PSR_S)? 1 : 0; \
|
||||
env->psrps = (_tmp & PSR_PS)? 1 : 0; \
|
||||
env->psret = (_tmp & PSR_ET)? 1 : 0; \
|
||||
#define PUT_PSR(env, val) do { int _tmp = val; \
|
||||
env->psr = _tmp & PSR_ICC; \
|
||||
env->psref = (_tmp & PSR_EF)? 1 : 0; \
|
||||
env->psrpil = (_tmp & PSR_PIL) >> 8; \
|
||||
env->psrs = (_tmp & PSR_S)? 1 : 0; \
|
||||
env->psrps = (_tmp & PSR_PS)? 1 : 0; \
|
||||
env->psret = (_tmp & PSR_ET)? 1 : 0; \
|
||||
cpu_set_cwp(env, _tmp & PSR_CWP); \
|
||||
} while (0)
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
#define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20))
|
||||
#define PUT_CCR(env, val) do { int _tmp = val; \
|
||||
env->xcc = (_tmp >> 4) << 20; \
|
||||
env->psr = (_tmp & 0xf) << 20; \
|
||||
#define PUT_CCR(env, val) do { int _tmp = val; \
|
||||
env->xcc = (_tmp >> 4) << 20; \
|
||||
env->psr = (_tmp & 0xf) << 20; \
|
||||
} while (0)
|
||||
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp)
|
||||
#define PUT_CWP64(env, val) \
|
||||
|
@ -99,8 +99,8 @@ static const int perm_table[2][8] = {
|
||||
};
|
||||
|
||||
int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
{
|
||||
int access_perms = 0;
|
||||
target_phys_addr_t pde_ptr;
|
||||
@ -111,7 +111,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
|
||||
|
||||
virt_addr = address & TARGET_PAGE_MASK;
|
||||
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
||||
*physical = address;
|
||||
*physical = address;
|
||||
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
return 0;
|
||||
}
|
||||
@ -128,70 +128,70 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return 1 << 2;
|
||||
return 1 << 2;
|
||||
case 2: /* L0 PTE, maybe should not happen? */
|
||||
case 3: /* Reserved */
|
||||
return 4 << 2;
|
||||
case 1: /* L0 PDE */
|
||||
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
||||
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
||||
pde = ldl_phys(pde_ptr);
|
||||
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return (1 << 8) | (1 << 2);
|
||||
case 3: /* Reserved */
|
||||
return (1 << 8) | (4 << 2);
|
||||
case 1: /* L1 PDE */
|
||||
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return (1 << 8) | (1 << 2);
|
||||
case 3: /* Reserved */
|
||||
return (1 << 8) | (4 << 2);
|
||||
case 1: /* L1 PDE */
|
||||
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
||||
pde = ldl_phys(pde_ptr);
|
||||
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return (2 << 8) | (1 << 2);
|
||||
case 3: /* Reserved */
|
||||
return (2 << 8) | (4 << 2);
|
||||
case 1: /* L2 PDE */
|
||||
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return (2 << 8) | (1 << 2);
|
||||
case 3: /* Reserved */
|
||||
return (2 << 8) | (4 << 2);
|
||||
case 1: /* L2 PDE */
|
||||
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
||||
pde = ldl_phys(pde_ptr);
|
||||
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return (3 << 8) | (1 << 2);
|
||||
case 1: /* PDE, should not happen */
|
||||
case 3: /* Reserved */
|
||||
return (3 << 8) | (4 << 2);
|
||||
case 2: /* L3 PTE */
|
||||
virt_addr = address & TARGET_PAGE_MASK;
|
||||
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
|
||||
}
|
||||
break;
|
||||
case 2: /* L2 PTE */
|
||||
virt_addr = address & ~0x3ffff;
|
||||
page_offset = address & 0x3ffff;
|
||||
}
|
||||
break;
|
||||
case 2: /* L1 PTE */
|
||||
virt_addr = address & ~0xffffff;
|
||||
page_offset = address & 0xffffff;
|
||||
}
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
return (3 << 8) | (1 << 2);
|
||||
case 1: /* PDE, should not happen */
|
||||
case 3: /* Reserved */
|
||||
return (3 << 8) | (4 << 2);
|
||||
case 2: /* L3 PTE */
|
||||
virt_addr = address & TARGET_PAGE_MASK;
|
||||
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
|
||||
}
|
||||
break;
|
||||
case 2: /* L2 PTE */
|
||||
virt_addr = address & ~0x3ffff;
|
||||
page_offset = address & 0x3ffff;
|
||||
}
|
||||
break;
|
||||
case 2: /* L1 PTE */
|
||||
virt_addr = address & ~0xffffff;
|
||||
page_offset = address & 0xffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* update page modified and dirty bits */
|
||||
is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
|
||||
if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
|
||||
pde |= PG_ACCESSED_MASK;
|
||||
if (is_dirty)
|
||||
pde |= PG_MODIFIED_MASK;
|
||||
pde |= PG_ACCESSED_MASK;
|
||||
if (is_dirty)
|
||||
pde |= PG_MODIFIED_MASK;
|
||||
stl_phys_notdirty(pde_ptr, pde);
|
||||
}
|
||||
/* check access */
|
||||
access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
|
||||
error_code = access_table[*access_index][access_perms];
|
||||
if (error_code && !((env->mmuregs[0] & MMU_NF) && is_user))
|
||||
return error_code;
|
||||
return error_code;
|
||||
|
||||
/* the page can be put in the TLB */
|
||||
*prot = perm_table[is_user][access_perms];
|
||||
@ -217,18 +217,18 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
|
||||
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
|
||||
if (error_code == 0) {
|
||||
vaddr = address & TARGET_PAGE_MASK;
|
||||
paddr &= TARGET_PAGE_MASK;
|
||||
vaddr = address & TARGET_PAGE_MASK;
|
||||
paddr &= TARGET_PAGE_MASK;
|
||||
#ifdef DEBUG_MMU
|
||||
printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
|
||||
printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
|
||||
TARGET_FMT_lx "\n", address, paddr, vaddr);
|
||||
#endif
|
||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||
return ret;
|
||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (env->mmuregs[3]) /* Fault status register */
|
||||
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
|
||||
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
|
||||
env->mmuregs[3] |= (access_index << 5) | error_code | 2;
|
||||
env->mmuregs[4] = address; /* Fault address register */
|
||||
|
||||
@ -237,10 +237,10 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
// permissions. If no mapping is available, redirect accesses to
|
||||
// neverland. Fake/overridden mappings will be flushed when
|
||||
// switching to normal mode.
|
||||
vaddr = address & TARGET_PAGE_MASK;
|
||||
vaddr = address & TARGET_PAGE_MASK;
|
||||
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||
return ret;
|
||||
return ret;
|
||||
} else {
|
||||
if (rw & 2)
|
||||
env->exception_index = TT_TFAULT;
|
||||
@ -265,50 +265,50 @@ target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
|
||||
case 0: /* Invalid */
|
||||
case 2: /* PTE, maybe should not happen? */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
return 0;
|
||||
case 1: /* L1 PDE */
|
||||
if (mmulev == 3)
|
||||
return pde;
|
||||
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
||||
if (mmulev == 3)
|
||||
return pde;
|
||||
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
||||
pde = ldl_phys(pde_ptr);
|
||||
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
case 2: /* L1 PTE */
|
||||
return pde;
|
||||
case 1: /* L2 PDE */
|
||||
if (mmulev == 2)
|
||||
return pde;
|
||||
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
case 2: /* L1 PTE */
|
||||
return pde;
|
||||
case 1: /* L2 PDE */
|
||||
if (mmulev == 2)
|
||||
return pde;
|
||||
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
||||
pde = ldl_phys(pde_ptr);
|
||||
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
case 2: /* L2 PTE */
|
||||
return pde;
|
||||
case 1: /* L3 PDE */
|
||||
if (mmulev == 1)
|
||||
return pde;
|
||||
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
case 2: /* L2 PTE */
|
||||
return pde;
|
||||
case 1: /* L3 PDE */
|
||||
if (mmulev == 1)
|
||||
return pde;
|
||||
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
||||
pde = ldl_phys(pde_ptr);
|
||||
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
case 1: /* PDE, should not happen */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
case 2: /* L3 PTE */
|
||||
return pde;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (pde & PTE_ENTRYTYPE_MASK) {
|
||||
default:
|
||||
case 0: /* Invalid */
|
||||
case 1: /* PDE, should not happen */
|
||||
case 3: /* Reserved */
|
||||
return 0;
|
||||
case 2: /* L3 PTE */
|
||||
return pde;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -327,29 +327,29 @@ void dump_mmu(CPUState *env)
|
||||
printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
|
||||
(target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
|
||||
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
|
||||
pde = mmu_probe(env, va, 2);
|
||||
if (pde) {
|
||||
pa = cpu_get_phys_page_debug(env, va);
|
||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||
pde = mmu_probe(env, va, 2);
|
||||
if (pde) {
|
||||
pa = cpu_get_phys_page_debug(env, va);
|
||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||
" PDE: " TARGET_FMT_lx "\n", va, pa, pde);
|
||||
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
|
||||
pde = mmu_probe(env, va1, 1);
|
||||
if (pde) {
|
||||
pa = cpu_get_phys_page_debug(env, va1);
|
||||
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
|
||||
pde = mmu_probe(env, va1, 1);
|
||||
if (pde) {
|
||||
pa = cpu_get_phys_page_debug(env, va1);
|
||||
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||
" PDE: " TARGET_FMT_lx "\n", va1, pa, pde);
|
||||
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
|
||||
pde = mmu_probe(env, va2, 0);
|
||||
if (pde) {
|
||||
pa = cpu_get_phys_page_debug(env, va2);
|
||||
printf(" VA: " TARGET_FMT_lx ", PA: "
|
||||
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
|
||||
pde = mmu_probe(env, va2, 0);
|
||||
if (pde) {
|
||||
pa = cpu_get_phys_page_debug(env, va2);
|
||||
printf(" VA: " TARGET_FMT_lx ", PA: "
|
||||
TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n",
|
||||
va2, pa, pde);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("MMU dump ends\n");
|
||||
}
|
||||
@ -360,57 +360,57 @@ void dump_mmu(CPUState *env)
|
||||
* UltraSparc IIi I/DMMUs
|
||||
*/
|
||||
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
{
|
||||
target_ulong mask;
|
||||
unsigned int i;
|
||||
|
||||
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
|
||||
*physical = address;
|
||||
*prot = PAGE_READ | PAGE_WRITE;
|
||||
*physical = address;
|
||||
*prot = PAGE_READ | PAGE_WRITE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0: // 8k
|
||||
mask = 0xffffffffffffe000ULL;
|
||||
break;
|
||||
case 0x1: // 64k
|
||||
mask = 0xffffffffffff0000ULL;
|
||||
break;
|
||||
case 0x2: // 512k
|
||||
mask = 0xfffffffffff80000ULL;
|
||||
break;
|
||||
case 0x3: // 4M
|
||||
mask = 0xffffffffffc00000ULL;
|
||||
break;
|
||||
}
|
||||
// ctx match, vaddr match?
|
||||
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
|
||||
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
|
||||
// valid, access ok?
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
||||
((env->dtlb_tte[i] & 0x4) && is_user) ||
|
||||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
|
||||
if (env->dmmuregs[3]) /* Fault status register */
|
||||
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
|
||||
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
|
||||
env->dmmuregs[4] = address; /* Fault address register */
|
||||
env->exception_index = TT_DFAULT;
|
||||
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0: // 8k
|
||||
mask = 0xffffffffffffe000ULL;
|
||||
break;
|
||||
case 0x1: // 64k
|
||||
mask = 0xffffffffffff0000ULL;
|
||||
break;
|
||||
case 0x2: // 512k
|
||||
mask = 0xfffffffffff80000ULL;
|
||||
break;
|
||||
case 0x3: // 4M
|
||||
mask = 0xffffffffffc00000ULL;
|
||||
break;
|
||||
}
|
||||
// ctx match, vaddr match?
|
||||
if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
|
||||
(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
|
||||
// valid, access ok?
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
||||
((env->dtlb_tte[i] & 0x4) && is_user) ||
|
||||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
|
||||
if (env->dmmuregs[3]) /* Fault status register */
|
||||
env->dmmuregs[3] = 2; /* overflow (not read before another fault) */
|
||||
env->dmmuregs[3] |= (is_user << 3) | ((rw == 1) << 2) | 1;
|
||||
env->dmmuregs[4] = address; /* Fault address register */
|
||||
env->exception_index = TT_DFAULT;
|
||||
#ifdef DEBUG_MMU
|
||||
printf("DFAULT at 0x%" PRIx64 "\n", address);
|
||||
printf("DFAULT at 0x%" PRIx64 "\n", address);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||
*prot = PAGE_READ;
|
||||
if (env->dtlb_tte[i] & 0x2)
|
||||
*prot |= PAGE_WRITE;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*physical = (env->dtlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||
*prot = PAGE_READ;
|
||||
if (env->dtlb_tte[i] & 0x2)
|
||||
*prot |= PAGE_WRITE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MMU
|
||||
printf("DMISS at 0x%" PRIx64 "\n", address);
|
||||
@ -420,53 +420,53 @@ static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical
|
||||
}
|
||||
|
||||
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
{
|
||||
target_ulong mask;
|
||||
unsigned int i;
|
||||
|
||||
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
|
||||
*physical = address;
|
||||
*prot = PAGE_EXEC;
|
||||
*physical = address;
|
||||
*prot = PAGE_EXEC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
switch ((env->itlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0: // 8k
|
||||
mask = 0xffffffffffffe000ULL;
|
||||
break;
|
||||
case 0x1: // 64k
|
||||
mask = 0xffffffffffff0000ULL;
|
||||
break;
|
||||
case 0x2: // 512k
|
||||
mask = 0xfffffffffff80000ULL;
|
||||
break;
|
||||
case 0x3: // 4M
|
||||
mask = 0xffffffffffc00000ULL;
|
||||
break;
|
||||
}
|
||||
// ctx match, vaddr match?
|
||||
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
|
||||
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
|
||||
// valid, access ok?
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
||||
((env->itlb_tte[i] & 0x4) && is_user)) {
|
||||
if (env->immuregs[3]) /* Fault status register */
|
||||
env->immuregs[3] = 2; /* overflow (not read before another fault) */
|
||||
env->immuregs[3] |= (is_user << 3) | 1;
|
||||
env->exception_index = TT_TFAULT;
|
||||
switch ((env->itlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0: // 8k
|
||||
mask = 0xffffffffffffe000ULL;
|
||||
break;
|
||||
case 0x1: // 64k
|
||||
mask = 0xffffffffffff0000ULL;
|
||||
break;
|
||||
case 0x2: // 512k
|
||||
mask = 0xfffffffffff80000ULL;
|
||||
break;
|
||||
case 0x3: // 4M
|
||||
mask = 0xffffffffffc00000ULL;
|
||||
break;
|
||||
}
|
||||
// ctx match, vaddr match?
|
||||
if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
|
||||
(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
|
||||
// valid, access ok?
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0 ||
|
||||
((env->itlb_tte[i] & 0x4) && is_user)) {
|
||||
if (env->immuregs[3]) /* Fault status register */
|
||||
env->immuregs[3] = 2; /* overflow (not read before another fault) */
|
||||
env->immuregs[3] |= (is_user << 3) | 1;
|
||||
env->exception_index = TT_TFAULT;
|
||||
#ifdef DEBUG_MMU
|
||||
printf("TFAULT at 0x%" PRIx64 "\n", address);
|
||||
printf("TFAULT at 0x%" PRIx64 "\n", address);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||
*prot = PAGE_EXEC;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||
*prot = PAGE_EXEC;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MMU
|
||||
printf("TMISS at 0x%" PRIx64 "\n", address);
|
||||
@ -476,13 +476,13 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
|
||||
}
|
||||
|
||||
int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
int *access_index, target_ulong address, int rw,
|
||||
int is_user)
|
||||
{
|
||||
if (rw == 2)
|
||||
return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
|
||||
return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
|
||||
else
|
||||
return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
|
||||
return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
|
||||
}
|
||||
|
||||
/* Perform address translation */
|
||||
@ -495,13 +495,13 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
|
||||
error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
|
||||
if (error_code == 0) {
|
||||
virt_addr = address & TARGET_PAGE_MASK;
|
||||
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
|
||||
virt_addr = address & TARGET_PAGE_MASK;
|
||||
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
|
||||
#ifdef DEBUG_MMU
|
||||
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
|
||||
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
|
||||
#endif
|
||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||
return ret;
|
||||
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||
return ret;
|
||||
}
|
||||
// XXX
|
||||
return 1;
|
||||
@ -515,67 +515,67 @@ void dump_mmu(CPUState *env)
|
||||
|
||||
printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n", env->dmmuregs[1], env->dmmuregs[2]);
|
||||
if ((env->lsu & DMMU_E) == 0) {
|
||||
printf("DMMU disabled\n");
|
||||
printf("DMMU disabled\n");
|
||||
} else {
|
||||
printf("DMMU dump:\n");
|
||||
for (i = 0; i < 64; i++) {
|
||||
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0:
|
||||
mask = " 8k";
|
||||
break;
|
||||
case 0x1:
|
||||
mask = " 64k";
|
||||
break;
|
||||
case 0x2:
|
||||
mask = "512k";
|
||||
break;
|
||||
case 0x3:
|
||||
mask = " 4M";
|
||||
break;
|
||||
}
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
|
||||
env->dtlb_tag[i] & ~0x1fffULL,
|
||||
env->dtlb_tte[i] & 0x1ffffffe000ULL,
|
||||
mask,
|
||||
env->dtlb_tte[i] & 0x4? "priv": "user",
|
||||
env->dtlb_tte[i] & 0x2? "RW": "RO",
|
||||
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
|
||||
env->dtlb_tag[i] & 0x1fffULL);
|
||||
}
|
||||
}
|
||||
printf("DMMU dump:\n");
|
||||
for (i = 0; i < 64; i++) {
|
||||
switch ((env->dtlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0:
|
||||
mask = " 8k";
|
||||
break;
|
||||
case 0x1:
|
||||
mask = " 64k";
|
||||
break;
|
||||
case 0x2:
|
||||
mask = "512k";
|
||||
break;
|
||||
case 0x3:
|
||||
mask = " 4M";
|
||||
break;
|
||||
}
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, %s, ctx %" PRId64 "\n",
|
||||
env->dtlb_tag[i] & ~0x1fffULL,
|
||||
env->dtlb_tte[i] & 0x1ffffffe000ULL,
|
||||
mask,
|
||||
env->dtlb_tte[i] & 0x4? "priv": "user",
|
||||
env->dtlb_tte[i] & 0x2? "RW": "RO",
|
||||
env->dtlb_tte[i] & 0x40? "locked": "unlocked",
|
||||
env->dtlb_tag[i] & 0x1fffULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((env->lsu & IMMU_E) == 0) {
|
||||
printf("IMMU disabled\n");
|
||||
printf("IMMU disabled\n");
|
||||
} else {
|
||||
printf("IMMU dump:\n");
|
||||
for (i = 0; i < 64; i++) {
|
||||
switch ((env->itlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0:
|
||||
mask = " 8k";
|
||||
break;
|
||||
case 0x1:
|
||||
mask = " 64k";
|
||||
break;
|
||||
case 0x2:
|
||||
mask = "512k";
|
||||
break;
|
||||
case 0x3:
|
||||
mask = " 4M";
|
||||
break;
|
||||
}
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
|
||||
env->itlb_tag[i] & ~0x1fffULL,
|
||||
env->itlb_tte[i] & 0x1ffffffe000ULL,
|
||||
mask,
|
||||
env->itlb_tte[i] & 0x4? "priv": "user",
|
||||
env->itlb_tte[i] & 0x40? "locked": "unlocked",
|
||||
env->itlb_tag[i] & 0x1fffULL);
|
||||
}
|
||||
}
|
||||
printf("IMMU dump:\n");
|
||||
for (i = 0; i < 64; i++) {
|
||||
switch ((env->itlb_tte[i] >> 61) & 3) {
|
||||
default:
|
||||
case 0x0:
|
||||
mask = " 8k";
|
||||
break;
|
||||
case 0x1:
|
||||
mask = " 64k";
|
||||
break;
|
||||
case 0x2:
|
||||
mask = "512k";
|
||||
break;
|
||||
case 0x3:
|
||||
mask = " 4M";
|
||||
break;
|
||||
}
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
|
||||
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx ", %s, %s, %s, ctx %" PRId64 "\n",
|
||||
env->itlb_tag[i] & ~0x1fffULL,
|
||||
env->itlb_tte[i] & 0x1ffffffe000ULL,
|
||||
mask,
|
||||
env->itlb_tte[i] & 0x4? "priv": "user",
|
||||
env->itlb_tte[i] & 0x40? "locked": "unlocked",
|
||||
env->itlb_tag[i] & 0x1fffULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_MMU */
|
||||
|
@ -376,33 +376,33 @@ void OPPROTO op_add_T1_T0_cc(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->xcc |= PSR_CARRY;
|
||||
env->xcc |= PSR_CARRY;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
||||
env->xcc |= PSR_OVF;
|
||||
env->xcc |= PSR_OVF;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -448,26 +448,26 @@ void OPPROTO op_addx_T1_T0_cc(void)
|
||||
}
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
||||
env->xcc |= PSR_OVF;
|
||||
env->xcc |= PSR_OVF;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -481,37 +481,37 @@ void OPPROTO op_tadd_T1_T0_cc(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
if ((src1 & 0x03) || (T1 & 0x03))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->xcc |= PSR_CARRY;
|
||||
env->xcc |= PSR_CARRY;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
|
||||
env->xcc |= PSR_OVF;
|
||||
env->xcc |= PSR_OVF;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
if ((src1 & 0x03) || (T1 & 0x03))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -528,7 +528,7 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
raise_exception(TT_TOVF);
|
||||
#else
|
||||
if ((src1 & 0x03) || (T1 & 0x03))
|
||||
@ -538,26 +538,26 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->xcc |= PSR_CARRY;
|
||||
env->xcc |= PSR_CARRY;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -576,33 +576,33 @@ void OPPROTO op_sub_T1_T0_cc(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (src1 < T1)
|
||||
env->xcc |= PSR_CARRY;
|
||||
env->xcc |= PSR_CARRY;
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
||||
env->xcc |= PSR_OVF;
|
||||
env->xcc |= PSR_OVF;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (src1 < T1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -648,26 +648,26 @@ void OPPROTO op_subx_T1_T0_cc(void)
|
||||
}
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
||||
env->xcc |= PSR_OVF;
|
||||
env->xcc |= PSR_OVF;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -681,37 +681,37 @@ void OPPROTO op_tsub_T1_T0_cc(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
if ((src1 & 0x03) || (T1 & 0x03))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (src1 < T1)
|
||||
env->xcc |= PSR_CARRY;
|
||||
env->xcc |= PSR_CARRY;
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
|
||||
env->xcc |= PSR_OVF;
|
||||
env->xcc |= PSR_OVF;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (src1 < T1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
if ((src1 & 0x03) || (T1 & 0x03))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -728,7 +728,7 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
|
||||
raise_exception(TT_TOVF);
|
||||
#else
|
||||
if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
|
||||
@ -738,26 +738,26 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
if (src1 < T1)
|
||||
env->xcc |= PSR_CARRY;
|
||||
env->xcc |= PSR_CARRY;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (src1 < T1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -833,13 +833,13 @@ void OPPROTO op_mulscc_T1_T0(void)
|
||||
T0 += T1;
|
||||
env->psr = 0;
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (T0 < src1)
|
||||
env->psr |= PSR_CARRY;
|
||||
env->psr |= PSR_CARRY;
|
||||
if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
env->y = (b2 << 31) | (env->y >> 1);
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -858,11 +858,11 @@ void OPPROTO op_udiv_T1_T0(void)
|
||||
|
||||
x0 = x0 / x1;
|
||||
if (x0 > 0xffffffff) {
|
||||
T0 = 0xffffffff;
|
||||
T1 = 1;
|
||||
T0 = 0xffffffff;
|
||||
T1 = 1;
|
||||
} else {
|
||||
T0 = x0;
|
||||
T1 = 0;
|
||||
T0 = x0;
|
||||
T1 = 0;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -881,11 +881,11 @@ void OPPROTO op_sdiv_T1_T0(void)
|
||||
|
||||
x0 = x0 / x1;
|
||||
if ((int32_t) x0 != x0) {
|
||||
T0 = x0 < 0? 0x80000000: 0x7fffffff;
|
||||
T1 = 1;
|
||||
T0 = x0 < 0? 0x80000000: 0x7fffffff;
|
||||
T1 = 1;
|
||||
} else {
|
||||
T0 = x0;
|
||||
T1 = 0;
|
||||
T0 = x0;
|
||||
T1 = 0;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -895,24 +895,24 @@ void OPPROTO op_div_cc(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (T1)
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
if (T1)
|
||||
env->psr |= PSR_OVF;
|
||||
env->psr |= PSR_OVF;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -939,9 +939,9 @@ void OPPROTO op_sdivx_T1_T0(void)
|
||||
raise_exception(TT_DIV_ZERO);
|
||||
}
|
||||
if (T0 == INT64_MIN && T1 == -1)
|
||||
T0 = INT64_MIN;
|
||||
T0 = INT64_MIN;
|
||||
else
|
||||
T0 /= (target_long) T1;
|
||||
T0 /= (target_long) T1;
|
||||
FORCE_RET();
|
||||
}
|
||||
#endif
|
||||
@ -951,20 +951,20 @@ void OPPROTO op_logic_T0_cc(void)
|
||||
env->psr = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
if (!(T0 & 0xffffffff))
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
|
||||
env->xcc = 0;
|
||||
if (!T0)
|
||||
env->xcc |= PSR_ZERO;
|
||||
env->xcc |= PSR_ZERO;
|
||||
if ((int64_t) T0 < 0)
|
||||
env->xcc |= PSR_NEG;
|
||||
env->xcc |= PSR_NEG;
|
||||
#else
|
||||
if (!T0)
|
||||
env->psr |= PSR_ZERO;
|
||||
env->psr |= PSR_ZERO;
|
||||
if ((int32_t) T0 < 0)
|
||||
env->psr |= PSR_NEG;
|
||||
env->psr |= PSR_NEG;
|
||||
#endif
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -1200,17 +1200,17 @@ void OPPROTO op_save(void)
|
||||
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
||||
if (env->cansave == 0) {
|
||||
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
} else {
|
||||
if (env->cleanwin - env->canrestore == 0) {
|
||||
// XXX Clean windows without trap
|
||||
raise_exception(TT_CLRWIN);
|
||||
} else {
|
||||
env->cansave--;
|
||||
env->canrestore++;
|
||||
set_cwp(cwp);
|
||||
}
|
||||
if (env->cleanwin - env->canrestore == 0) {
|
||||
// XXX Clean windows without trap
|
||||
raise_exception(TT_CLRWIN);
|
||||
} else {
|
||||
env->cansave--;
|
||||
env->canrestore++;
|
||||
set_cwp(cwp);
|
||||
}
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -1221,12 +1221,12 @@ void OPPROTO op_restore(void)
|
||||
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
||||
if (env->canrestore == 0) {
|
||||
raise_exception(TT_FILL | (env->otherwin != 0 ?
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
} else {
|
||||
env->cansave++;
|
||||
env->canrestore--;
|
||||
set_cwp(cwp);
|
||||
env->cansave++;
|
||||
env->canrestore--;
|
||||
set_cwp(cwp);
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
@ -1576,15 +1576,15 @@ void OPPROTO op_clear_ieee_excp_and_FTT(void)
|
||||
#define F_BINOP(name) \
|
||||
F_OP(name, s) \
|
||||
{ \
|
||||
set_float_exception_flags(0, &env->fp_status); \
|
||||
set_float_exception_flags(0, &env->fp_status); \
|
||||
FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
|
||||
check_ieee_exceptions(); \
|
||||
check_ieee_exceptions(); \
|
||||
} \
|
||||
F_OP(name, d) \
|
||||
{ \
|
||||
set_float_exception_flags(0, &env->fp_status); \
|
||||
set_float_exception_flags(0, &env->fp_status); \
|
||||
DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
|
||||
check_ieee_exceptions(); \
|
||||
check_ieee_exceptions(); \
|
||||
}
|
||||
|
||||
F_BINOP(add);
|
||||
@ -1784,27 +1784,27 @@ void OPPROTO op_fdtox(void)
|
||||
void OPPROTO op_fmovs_cc(void)
|
||||
{
|
||||
if (T2)
|
||||
FT0 = FT1;
|
||||
FT0 = FT1;
|
||||
}
|
||||
|
||||
void OPPROTO op_fmovd_cc(void)
|
||||
{
|
||||
if (T2)
|
||||
DT0 = DT1;
|
||||
DT0 = DT1;
|
||||
}
|
||||
|
||||
void OPPROTO op_mov_cc(void)
|
||||
{
|
||||
if (T2)
|
||||
T0 = T1;
|
||||
T0 = T1;
|
||||
}
|
||||
|
||||
void OPPROTO op_flushw(void)
|
||||
{
|
||||
if (env->cansave != NWINDOWS - 2) {
|
||||
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1812,9 +1812,9 @@ void OPPROTO op_saved(void)
|
||||
{
|
||||
env->cansave++;
|
||||
if (env->otherwin == 0)
|
||||
env->canrestore--;
|
||||
env->canrestore--;
|
||||
else
|
||||
env->otherwin--;
|
||||
env->otherwin--;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
@ -1822,11 +1822,11 @@ void OPPROTO op_restored(void)
|
||||
{
|
||||
env->canrestore++;
|
||||
if (env->cleanwin < NWINDOWS - 1)
|
||||
env->cleanwin++;
|
||||
env->cleanwin++;
|
||||
if (env->otherwin == 0)
|
||||
env->cansave--;
|
||||
env->cansave--;
|
||||
else
|
||||
env->otherwin--;
|
||||
env->otherwin--;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
|
@ -16,29 +16,29 @@ void check_ieee_exceptions()
|
||||
T0 = get_float_exception_flags(&env->fp_status);
|
||||
if (T0)
|
||||
{
|
||||
/* Copy IEEE 754 flags into FSR */
|
||||
if (T0 & float_flag_invalid)
|
||||
env->fsr |= FSR_NVC;
|
||||
if (T0 & float_flag_overflow)
|
||||
env->fsr |= FSR_OFC;
|
||||
if (T0 & float_flag_underflow)
|
||||
env->fsr |= FSR_UFC;
|
||||
if (T0 & float_flag_divbyzero)
|
||||
env->fsr |= FSR_DZC;
|
||||
if (T0 & float_flag_inexact)
|
||||
env->fsr |= FSR_NXC;
|
||||
/* Copy IEEE 754 flags into FSR */
|
||||
if (T0 & float_flag_invalid)
|
||||
env->fsr |= FSR_NVC;
|
||||
if (T0 & float_flag_overflow)
|
||||
env->fsr |= FSR_OFC;
|
||||
if (T0 & float_flag_underflow)
|
||||
env->fsr |= FSR_UFC;
|
||||
if (T0 & float_flag_divbyzero)
|
||||
env->fsr |= FSR_DZC;
|
||||
if (T0 & float_flag_inexact)
|
||||
env->fsr |= FSR_NXC;
|
||||
|
||||
if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
|
||||
{
|
||||
/* Unmasked exception, generate a trap */
|
||||
env->fsr |= FSR_FTT_IEEE_EXCP;
|
||||
raise_exception(TT_FP_EXCP);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Accumulate exceptions */
|
||||
env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
|
||||
}
|
||||
if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
|
||||
{
|
||||
/* Unmasked exception, generate a trap */
|
||||
env->fsr |= FSR_FTT_IEEE_EXCP;
|
||||
raise_exception(TT_FP_EXCP);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Accumulate exceptions */
|
||||
env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,33 +155,33 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
case 2: /* SuperSparc MXCC registers */
|
||||
break;
|
||||
case 3: /* MMU probe */
|
||||
{
|
||||
int mmulev;
|
||||
{
|
||||
int mmulev;
|
||||
|
||||
mmulev = (T0 >> 8) & 15;
|
||||
if (mmulev > 4)
|
||||
ret = 0;
|
||||
else {
|
||||
ret = mmu_probe(env, T0, mmulev);
|
||||
//bswap32s(&ret);
|
||||
}
|
||||
mmulev = (T0 >> 8) & 15;
|
||||
if (mmulev > 4)
|
||||
ret = 0;
|
||||
else {
|
||||
ret = mmu_probe(env, T0, mmulev);
|
||||
//bswap32s(&ret);
|
||||
}
|
||||
#ifdef DEBUG_MMU
|
||||
printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
|
||||
printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4: /* read MMU regs */
|
||||
{
|
||||
int reg = (T0 >> 8) & 0xf;
|
||||
{
|
||||
int reg = (T0 >> 8) & 0xf;
|
||||
|
||||
ret = env->mmuregs[reg];
|
||||
if (reg == 3) /* Fault status cleared on read */
|
||||
env->mmuregs[reg] = 0;
|
||||
ret = env->mmuregs[reg];
|
||||
if (reg == 3) /* Fault status cleared on read */
|
||||
env->mmuregs[reg] = 0;
|
||||
#ifdef DEBUG_MMU
|
||||
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
|
||||
printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 9: /* Supervisor code access */
|
||||
switch(size) {
|
||||
case 1:
|
||||
@ -218,11 +218,11 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
ret = ldl_phys(T0 & ~3);
|
||||
break;
|
||||
case 8:
|
||||
ret = ldl_phys(T0 & ~3);
|
||||
T0 = ldl_phys((T0 + 4) & ~3);
|
||||
break;
|
||||
ret = ldl_phys(T0 & ~3);
|
||||
T0 = ldl_phys((T0 + 4) & ~3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
|
||||
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
|
||||
switch(size) {
|
||||
@ -244,14 +244,14 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
| ((target_phys_addr_t)(asi & 0xf) << 32));
|
||||
T0 = ldl_phys((target_phys_addr_t)((T0 + 4) & ~3)
|
||||
| ((target_phys_addr_t)(asi & 0xf) << 32));
|
||||
break;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
|
||||
default:
|
||||
do_unassigned_access(T0, 0, 0, 1);
|
||||
ret = 0;
|
||||
break;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
T1 = ret;
|
||||
}
|
||||
@ -262,48 +262,48 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 2: /* SuperSparc MXCC registers */
|
||||
break;
|
||||
case 3: /* MMU flush */
|
||||
{
|
||||
int mmulev;
|
||||
{
|
||||
int mmulev;
|
||||
|
||||
mmulev = (T0 >> 8) & 15;
|
||||
mmulev = (T0 >> 8) & 15;
|
||||
#ifdef DEBUG_MMU
|
||||
printf("mmu flush level %d\n", mmulev);
|
||||
printf("mmu flush level %d\n", mmulev);
|
||||
#endif
|
||||
switch (mmulev) {
|
||||
case 0: // flush page
|
||||
tlb_flush_page(env, T0 & 0xfffff000);
|
||||
break;
|
||||
case 1: // flush segment (256k)
|
||||
case 2: // flush region (16M)
|
||||
case 3: // flush context (4G)
|
||||
case 4: // flush entire
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (mmulev) {
|
||||
case 0: // flush page
|
||||
tlb_flush_page(env, T0 & 0xfffff000);
|
||||
break;
|
||||
case 1: // flush segment (256k)
|
||||
case 2: // flush region (16M)
|
||||
case 3: // flush context (4G)
|
||||
case 4: // flush entire
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_MMU
|
||||
dump_mmu(env);
|
||||
dump_mmu(env);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 4: /* write MMU regs */
|
||||
{
|
||||
int reg = (T0 >> 8) & 0xf;
|
||||
uint32_t oldreg;
|
||||
{
|
||||
int reg = (T0 >> 8) & 0xf;
|
||||
uint32_t oldreg;
|
||||
|
||||
oldreg = env->mmuregs[reg];
|
||||
oldreg = env->mmuregs[reg];
|
||||
switch(reg) {
|
||||
case 0:
|
||||
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
|
||||
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
|
||||
// Mappings generated during no-fault mode or MMU
|
||||
// disabled mode are invalid in normal mode
|
||||
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
|
||||
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
|
||||
// Mappings generated during no-fault mode or MMU
|
||||
// disabled mode are invalid in normal mode
|
||||
if (oldreg != env->mmuregs[reg])
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
case 2:
|
||||
env->mmuregs[reg] = T1;
|
||||
env->mmuregs[reg] = T1;
|
||||
if (oldreg != env->mmuregs[reg]) {
|
||||
/* we flush when the MMU context changes because
|
||||
QEMU has no MMU context support */
|
||||
@ -314,17 +314,17 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
env->mmuregs[reg] = T1;
|
||||
env->mmuregs[reg] = T1;
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_MMU
|
||||
if (oldreg != env->mmuregs[reg]) {
|
||||
printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
|
||||
}
|
||||
dump_mmu(env);
|
||||
dump_mmu(env);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0xc: /* I-cache tag */
|
||||
case 0xd: /* I-cache data */
|
||||
case 0xe: /* D-cache tag */
|
||||
@ -336,10 +336,10 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 0x14: /* I/D-cache flush user */
|
||||
break;
|
||||
case 0x17: /* Block copy, sta access */
|
||||
{
|
||||
// value (T1) = src
|
||||
// address (T0) = dst
|
||||
// copy 32 bytes
|
||||
{
|
||||
// value (T1) = src
|
||||
// address (T0) = dst
|
||||
// copy 32 bytes
|
||||
unsigned int i;
|
||||
uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
|
||||
|
||||
@ -347,13 +347,13 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
temp = ldl_kernel(src);
|
||||
stl_kernel(dst, temp);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case 0x1f: /* Block fill, stda access */
|
||||
{
|
||||
// value (T1, T2)
|
||||
// address (T0) = dst
|
||||
// fill 32 bytes
|
||||
{
|
||||
// value (T1, T2)
|
||||
// address (T0) = dst
|
||||
// fill 32 bytes
|
||||
unsigned int i;
|
||||
uint32_t dst = T0 & 7;
|
||||
uint64_t val;
|
||||
@ -362,10 +362,10 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
|
||||
for (i = 0; i < 32; i += 8, dst += 8)
|
||||
stq_kernel(dst, val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case 0x20: /* MMU passthrough */
|
||||
{
|
||||
{
|
||||
switch(size) {
|
||||
case 1:
|
||||
stb_phys(T0, T1);
|
||||
@ -382,11 +382,11 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
stl_phys((T0 + 4) & ~3, T2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
|
||||
case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
|
||||
{
|
||||
{
|
||||
switch(size) {
|
||||
case 1:
|
||||
stb_phys((target_phys_addr_t)T0
|
||||
@ -408,8 +408,8 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
| ((target_phys_addr_t)(asi & 0xf) << 32), T1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case 0x31: /* Ross RT620 I-cache flush */
|
||||
case 0x36: /* I-cache flash clear */
|
||||
case 0x37: /* D-cache flash clear */
|
||||
@ -418,7 +418,7 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
|
||||
default:
|
||||
do_unassigned_access(T0, 1, 0, 1);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,12 +429,12 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
uint64_t ret = 0;
|
||||
|
||||
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
|
||||
switch (asi) {
|
||||
case 0x14: // Bypass
|
||||
case 0x15: // Bypass, non-cacheable
|
||||
{
|
||||
{
|
||||
switch(size) {
|
||||
case 1:
|
||||
ret = ldub_phys(T0);
|
||||
@ -450,8 +450,8 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
ret = ldq_phys(T0 & ~7);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x04: // Nucleus
|
||||
case 0x0c: // Nucleus Little Endian (LE)
|
||||
case 0x10: // As if user primary
|
||||
@ -469,58 +469,58 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
case 0x89: // Secondary LE
|
||||
case 0x8a: // Primary no-fault LE
|
||||
case 0x8b: // Secondary no-fault LE
|
||||
// XXX
|
||||
break;
|
||||
// XXX
|
||||
break;
|
||||
case 0x45: // LSU
|
||||
ret = env->lsu;
|
||||
break;
|
||||
ret = env->lsu;
|
||||
break;
|
||||
case 0x50: // I-MMU regs
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
|
||||
ret = env->immuregs[reg];
|
||||
break;
|
||||
}
|
||||
ret = env->immuregs[reg];
|
||||
break;
|
||||
}
|
||||
case 0x51: // I-MMU 8k TSB pointer
|
||||
case 0x52: // I-MMU 64k TSB pointer
|
||||
case 0x55: // I-MMU data access
|
||||
// XXX
|
||||
break;
|
||||
// XXX
|
||||
break;
|
||||
case 0x56: // I-MMU tag read
|
||||
{
|
||||
unsigned int i;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
// Valid, ctx match, vaddr match
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
||||
env->itlb_tag[i] == T0) {
|
||||
ret = env->itlb_tag[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 64; i++) {
|
||||
// Valid, ctx match, vaddr match
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
||||
env->itlb_tag[i] == T0) {
|
||||
ret = env->itlb_tag[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x58: // D-MMU regs
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
|
||||
ret = env->dmmuregs[reg];
|
||||
break;
|
||||
}
|
||||
ret = env->dmmuregs[reg];
|
||||
break;
|
||||
}
|
||||
case 0x5e: // D-MMU tag read
|
||||
{
|
||||
unsigned int i;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
// Valid, ctx match, vaddr match
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
||||
env->dtlb_tag[i] == T0) {
|
||||
ret = env->dtlb_tag[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 64; i++) {
|
||||
// Valid, ctx match, vaddr match
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
|
||||
env->dtlb_tag[i] == T0) {
|
||||
ret = env->dtlb_tag[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x59: // D-MMU 8k TSB pointer
|
||||
case 0x5a: // D-MMU 64k TSB pointer
|
||||
case 0x5b: // D-MMU data pointer
|
||||
@ -528,8 +528,8 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
case 0x48: // Interrupt dispatch, RO
|
||||
case 0x49: // Interrupt data receive
|
||||
case 0x7f: // Incoming interrupt vector, RO
|
||||
// XXX
|
||||
break;
|
||||
// XXX
|
||||
break;
|
||||
case 0x54: // I-MMU data in, WO
|
||||
case 0x57: // I-MMU demap, WO
|
||||
case 0x5c: // D-MMU data in, WO
|
||||
@ -537,8 +537,8 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
case 0x77: // Interrupt vector, WO
|
||||
default:
|
||||
do_unassigned_access(T0, 0, 0, 1);
|
||||
ret = 0;
|
||||
break;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
T1 = ret;
|
||||
}
|
||||
@ -546,12 +546,12 @@ void helper_ld_asi(int asi, int size, int sign)
|
||||
void helper_st_asi(int asi, int size, int sign)
|
||||
{
|
||||
if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
|
||||
switch(asi) {
|
||||
case 0x14: // Bypass
|
||||
case 0x15: // Bypass, non-cacheable
|
||||
{
|
||||
{
|
||||
switch(size) {
|
||||
case 1:
|
||||
stb_phys(T0, T1);
|
||||
@ -567,8 +567,8 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
stq_phys(T0 & ~7, T1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case 0x04: // Nucleus
|
||||
case 0x0c: // Nucleus Little Endian (LE)
|
||||
case 0x10: // As if user primary
|
||||
@ -582,31 +582,31 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 0x4a: // UPA config
|
||||
case 0x88: // Primary LE
|
||||
case 0x89: // Secondary LE
|
||||
// XXX
|
||||
return;
|
||||
// XXX
|
||||
return;
|
||||
case 0x45: // LSU
|
||||
{
|
||||
uint64_t oldreg;
|
||||
{
|
||||
uint64_t oldreg;
|
||||
|
||||
oldreg = env->lsu;
|
||||
env->lsu = T1 & (DMMU_E | IMMU_E);
|
||||
// Mappings generated during D/I MMU disabled mode are
|
||||
// invalid in normal mode
|
||||
if (oldreg != env->lsu) {
|
||||
oldreg = env->lsu;
|
||||
env->lsu = T1 & (DMMU_E | IMMU_E);
|
||||
// Mappings generated during D/I MMU disabled mode are
|
||||
// invalid in normal mode
|
||||
if (oldreg != env->lsu) {
|
||||
#ifdef DEBUG_MMU
|
||||
printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
|
||||
dump_mmu(env);
|
||||
dump_mmu(env);
|
||||
#endif
|
||||
tlb_flush(env, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
tlb_flush(env, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x50: // I-MMU regs
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
uint64_t oldreg;
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
uint64_t oldreg;
|
||||
|
||||
oldreg = env->immuregs[reg];
|
||||
oldreg = env->immuregs[reg];
|
||||
switch(reg) {
|
||||
case 0: // RO
|
||||
case 4:
|
||||
@ -617,73 +617,73 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 8:
|
||||
return;
|
||||
case 3: // SFSR
|
||||
if ((T1 & 1) == 0)
|
||||
T1 = 0; // Clear SFSR
|
||||
if ((T1 & 1) == 0)
|
||||
T1 = 0; // Clear SFSR
|
||||
break;
|
||||
case 5: // TSB access
|
||||
case 6: // Tag access
|
||||
default:
|
||||
break;
|
||||
}
|
||||
env->immuregs[reg] = T1;
|
||||
env->immuregs[reg] = T1;
|
||||
#ifdef DEBUG_MMU
|
||||
if (oldreg != env->immuregs[reg]) {
|
||||
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
|
||||
}
|
||||
dump_mmu(env);
|
||||
dump_mmu(env);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x54: // I-MMU data in
|
||||
{
|
||||
unsigned int i;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
// Try finding an invalid entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
||||
env->itlb_tag[i] = env->immuregs[6];
|
||||
env->itlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Try finding an unlocked entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->itlb_tte[i] & 0x40) == 0) {
|
||||
env->itlb_tag[i] = env->immuregs[6];
|
||||
env->itlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// error state?
|
||||
return;
|
||||
}
|
||||
// Try finding an invalid entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
||||
env->itlb_tag[i] = env->immuregs[6];
|
||||
env->itlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Try finding an unlocked entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->itlb_tte[i] & 0x40) == 0) {
|
||||
env->itlb_tag[i] = env->immuregs[6];
|
||||
env->itlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// error state?
|
||||
return;
|
||||
}
|
||||
case 0x55: // I-MMU data access
|
||||
{
|
||||
unsigned int i = (T0 >> 3) & 0x3f;
|
||||
{
|
||||
unsigned int i = (T0 >> 3) & 0x3f;
|
||||
|
||||
env->itlb_tag[i] = env->immuregs[6];
|
||||
env->itlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
env->itlb_tag[i] = env->immuregs[6];
|
||||
env->itlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
case 0x57: // I-MMU demap
|
||||
// XXX
|
||||
return;
|
||||
// XXX
|
||||
return;
|
||||
case 0x58: // D-MMU regs
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
uint64_t oldreg;
|
||||
{
|
||||
int reg = (T0 >> 3) & 0xf;
|
||||
uint64_t oldreg;
|
||||
|
||||
oldreg = env->dmmuregs[reg];
|
||||
oldreg = env->dmmuregs[reg];
|
||||
switch(reg) {
|
||||
case 0: // RO
|
||||
case 4:
|
||||
return;
|
||||
case 3: // SFSR
|
||||
if ((T1 & 1) == 0) {
|
||||
T1 = 0; // Clear SFSR, Fault address
|
||||
env->dmmuregs[4] = 0;
|
||||
}
|
||||
env->dmmuregs[reg] = T1;
|
||||
if ((T1 & 1) == 0) {
|
||||
T1 = 0; // Clear SFSR, Fault address
|
||||
env->dmmuregs[4] = 0;
|
||||
}
|
||||
env->dmmuregs[reg] = T1;
|
||||
break;
|
||||
case 1: // Primary context
|
||||
case 2: // Secondary context
|
||||
@ -694,50 +694,50 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
env->dmmuregs[reg] = T1;
|
||||
env->dmmuregs[reg] = T1;
|
||||
#ifdef DEBUG_MMU
|
||||
if (oldreg != env->dmmuregs[reg]) {
|
||||
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
|
||||
}
|
||||
dump_mmu(env);
|
||||
dump_mmu(env);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 0x5c: // D-MMU data in
|
||||
{
|
||||
unsigned int i;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
// Try finding an invalid entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||
env->dtlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Try finding an unlocked entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->dtlb_tte[i] & 0x40) == 0) {
|
||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||
env->dtlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// error state?
|
||||
return;
|
||||
}
|
||||
// Try finding an invalid entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
|
||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||
env->dtlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Try finding an unlocked entry
|
||||
for (i = 0; i < 64; i++) {
|
||||
if ((env->dtlb_tte[i] & 0x40) == 0) {
|
||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||
env->dtlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// error state?
|
||||
return;
|
||||
}
|
||||
case 0x5d: // D-MMU data access
|
||||
{
|
||||
unsigned int i = (T0 >> 3) & 0x3f;
|
||||
{
|
||||
unsigned int i = (T0 >> 3) & 0x3f;
|
||||
|
||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||
env->dtlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
env->dtlb_tag[i] = env->dmmuregs[6];
|
||||
env->dtlb_tte[i] = T1;
|
||||
return;
|
||||
}
|
||||
case 0x5f: // D-MMU demap
|
||||
case 0x49: // Interrupt data receive
|
||||
// XXX
|
||||
return;
|
||||
// XXX
|
||||
return;
|
||||
case 0x51: // I-MMU 8k TSB pointer, RO
|
||||
case 0x52: // I-MMU 64k TSB pointer, RO
|
||||
case 0x56: // I-MMU tag read, RO
|
||||
@ -753,7 +753,7 @@ void helper_st_asi(int asi, int size, int sign)
|
||||
case 0x8b: // Secondary no-fault LE, RO
|
||||
default:
|
||||
do_unassigned_access(T0, 1, 0, 1);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -783,17 +783,17 @@ void helper_ldfsr(void)
|
||||
switch (env->fsr & FSR_RD_MASK) {
|
||||
case FSR_RD_NEAREST:
|
||||
rnd_mode = float_round_nearest_even;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
case FSR_RD_ZERO:
|
||||
rnd_mode = float_round_to_zero;
|
||||
break;
|
||||
break;
|
||||
case FSR_RD_POS:
|
||||
rnd_mode = float_round_up;
|
||||
break;
|
||||
break;
|
||||
case FSR_RD_NEG:
|
||||
rnd_mode = float_round_down;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
set_float_rounding_mode(rnd_mode, &env->fp_status);
|
||||
}
|
||||
@ -835,13 +835,13 @@ static inline uint64_t *get_gregset(uint64_t pstate)
|
||||
switch (pstate) {
|
||||
default:
|
||||
case 0:
|
||||
return env->bgregs;
|
||||
return env->bgregs;
|
||||
case PS_AG:
|
||||
return env->agregs;
|
||||
return env->agregs;
|
||||
case PS_MG:
|
||||
return env->mgregs;
|
||||
return env->mgregs;
|
||||
case PS_IG:
|
||||
return env->igregs;
|
||||
return env->igregs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -853,11 +853,11 @@ static inline void change_pstate(uint64_t new_pstate)
|
||||
pstate_regs = env->pstate & 0xc01;
|
||||
new_pstate_regs = new_pstate & 0xc01;
|
||||
if (new_pstate_regs != pstate_regs) {
|
||||
// Switch global register bank
|
||||
src = get_gregset(new_pstate_regs);
|
||||
dst = get_gregset(pstate_regs);
|
||||
memcpy32(dst, env->gregs);
|
||||
memcpy32(env->gregs, src);
|
||||
// Switch global register bank
|
||||
src = get_gregset(new_pstate_regs);
|
||||
dst = get_gregset(pstate_regs);
|
||||
memcpy32(dst, env->gregs);
|
||||
memcpy32(env->gregs, src);
|
||||
}
|
||||
env->pstate = new_pstate;
|
||||
}
|
||||
@ -927,36 +927,36 @@ void do_interrupt(int intno)
|
||||
{
|
||||
#ifdef DEBUG_PCALL
|
||||
if (loglevel & CPU_LOG_INT) {
|
||||
static int count;
|
||||
fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
|
||||
static int count;
|
||||
fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
|
||||
count, intno,
|
||||
env->pc,
|
||||
env->npc, env->regwptr[6]);
|
||||
cpu_dump_state(env, logfile, fprintf, 0);
|
||||
cpu_dump_state(env, logfile, fprintf, 0);
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
uint8_t *ptr;
|
||||
{
|
||||
int i;
|
||||
uint8_t *ptr;
|
||||
|
||||
fprintf(logfile, " code=");
|
||||
ptr = (uint8_t *)env->pc;
|
||||
for(i = 0; i < 16; i++) {
|
||||
fprintf(logfile, " %02x", ldub(ptr + i));
|
||||
}
|
||||
fprintf(logfile, "\n");
|
||||
}
|
||||
fprintf(logfile, " code=");
|
||||
ptr = (uint8_t *)env->pc;
|
||||
for(i = 0; i < 16; i++) {
|
||||
fprintf(logfile, " %02x", ldub(ptr + i));
|
||||
}
|
||||
fprintf(logfile, "\n");
|
||||
}
|
||||
#endif
|
||||
count++;
|
||||
count++;
|
||||
}
|
||||
#endif
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (env->tl == MAXTL) {
|
||||
cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
|
||||
((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
|
||||
((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
|
||||
env->tpc[env->tl] = env->pc;
|
||||
env->tnpc[env->tl] = env->npc;
|
||||
env->tt[env->tl] = intno;
|
||||
@ -971,11 +971,11 @@ void do_interrupt(int intno)
|
||||
env->tbr &= ~0x7fffULL;
|
||||
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
|
||||
if (env->tl < MAXTL - 1) {
|
||||
env->tl++;
|
||||
env->tl++;
|
||||
} else {
|
||||
env->pstate |= PS_RED;
|
||||
if (env->tl != MAXTL)
|
||||
env->tl++;
|
||||
env->pstate |= PS_RED;
|
||||
if (env->tl != MAXTL)
|
||||
env->tl++;
|
||||
}
|
||||
env->pc = env->tbr;
|
||||
env->npc = env->pc + 4;
|
||||
@ -988,32 +988,32 @@ void do_interrupt(int intno)
|
||||
|
||||
#ifdef DEBUG_PCALL
|
||||
if (loglevel & CPU_LOG_INT) {
|
||||
static int count;
|
||||
fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
|
||||
static int count;
|
||||
fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
|
||||
count, intno,
|
||||
env->pc,
|
||||
env->npc, env->regwptr[6]);
|
||||
cpu_dump_state(env, logfile, fprintf, 0);
|
||||
cpu_dump_state(env, logfile, fprintf, 0);
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
uint8_t *ptr;
|
||||
{
|
||||
int i;
|
||||
uint8_t *ptr;
|
||||
|
||||
fprintf(logfile, " code=");
|
||||
ptr = (uint8_t *)env->pc;
|
||||
for(i = 0; i < 16; i++) {
|
||||
fprintf(logfile, " %02x", ldub(ptr + i));
|
||||
}
|
||||
fprintf(logfile, "\n");
|
||||
}
|
||||
fprintf(logfile, " code=");
|
||||
ptr = (uint8_t *)env->pc;
|
||||
for(i = 0; i < 16; i++) {
|
||||
fprintf(logfile, " %02x", ldub(ptr + i));
|
||||
}
|
||||
fprintf(logfile, "\n");
|
||||
}
|
||||
#endif
|
||||
count++;
|
||||
count++;
|
||||
}
|
||||
#endif
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
if (env->psret == 0) {
|
||||
cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
env->psret = 0;
|
||||
@ -1106,7 +1106,7 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
|
||||
saved_env = env;
|
||||
env = cpu_single_env;
|
||||
if (env->mmuregs[3]) /* Fault status register */
|
||||
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
|
||||
env->mmuregs[3] = 1; /* overflow (not read before another fault) */
|
||||
if (is_asi)
|
||||
env->mmuregs[3] |= 1 << 16;
|
||||
if (env->psrs)
|
||||
|
@ -2,13 +2,13 @@
|
||||
#define SPARC_LD_OP(name, qp) \
|
||||
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
|
||||
{ \
|
||||
T1 = (target_ulong)glue(qp, MEMSUFFIX)(T0); \
|
||||
T1 = (target_ulong)glue(qp, MEMSUFFIX)(T0); \
|
||||
}
|
||||
|
||||
#define SPARC_LD_OP_S(name, qp) \
|
||||
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
|
||||
{ \
|
||||
T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
|
||||
#define SPARC_LD_OP_S(name, qp) \
|
||||
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
|
||||
{ \
|
||||
T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
|
||||
}
|
||||
|
||||
#define SPARC_ST_OP(name, op) \
|
||||
@ -85,7 +85,7 @@ void OPPROTO glue(op_cas, MEMSUFFIX)(void)
|
||||
tmp = glue(ldl, MEMSUFFIX)(T0);
|
||||
T2 &= 0xffffffffULL;
|
||||
if (tmp == (T1 & 0xffffffffULL)) {
|
||||
glue(stl, MEMSUFFIX)(T0, T2);
|
||||
glue(stl, MEMSUFFIX)(T0, T2);
|
||||
}
|
||||
T2 = tmp;
|
||||
}
|
||||
@ -98,7 +98,7 @@ void OPPROTO glue(op_casx, MEMSUFFIX)(void)
|
||||
tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
|
||||
tmp |= glue(ldl, MEMSUFFIX)(T0);
|
||||
if (tmp == T1) {
|
||||
glue(stq, MEMSUFFIX)(T0, T2);
|
||||
glue(stq, MEMSUFFIX)(T0, T2);
|
||||
}
|
||||
T2 = tmp;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user