提交 952a328f 编写于 作者: B blueswir1

SuperSparc MXCC support (Robert Reif)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3397 c046a42c-6fe2-441c-8c8c-71466251a162
上级 992f48a0
...@@ -327,7 +327,7 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size, ...@@ -327,7 +327,7 @@ static void *sun4m_hw_init(const struct hwdef *hwdef, int RAM_size,
for(i = 0; i < smp_cpus; i++) { for(i = 0; i < smp_cpus; i++) {
env = cpu_init(); env = cpu_init();
cpu_sparc_register(env, def); cpu_sparc_register(env, def, i);
envs[i] = env; envs[i] = env;
if (i == 0) { if (i == 0) {
qemu_register_reset(main_cpu_reset, env); qemu_register_reset(main_cpu_reset, env);
......
...@@ -358,7 +358,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, ...@@ -358,7 +358,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
exit(1); exit(1);
} }
env = cpu_init(); env = cpu_init();
cpu_sparc_register(env, def); cpu_sparc_register(env, def, 0);
bh = qemu_bh_new(tick_irq, env); bh = qemu_bh_new(tick_irq, env);
env->tick = ptimer_init(bh); env->tick = ptimer_init(bh);
ptimer_set_period(env->tick, 1ULL); ptimer_set_period(env->tick, 1ULL);
......
...@@ -2142,7 +2142,7 @@ int main(int argc, char **argv) ...@@ -2142,7 +2142,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Unable to find Sparc CPU definition\n"); fprintf(stderr, "Unable to find Sparc CPU definition\n");
exit(1); exit(1);
} }
cpu_sparc_register(env, def); cpu_sparc_register(env, def, 0);
env->pc = regs->pc; env->pc = regs->pc;
env->npc = regs->npc; env->npc = regs->npc;
env->y = regs->y; env->y = regs->y;
......
...@@ -212,6 +212,8 @@ typedef struct CPUSPARCState { ...@@ -212,6 +212,8 @@ typedef struct CPUSPARCState {
uint64_t dtlb_tte[64]; uint64_t dtlb_tte[64];
#else #else
uint32_t mmuregs[16]; uint32_t mmuregs[16];
uint64_t mxccdata[4];
uint64_t mxccregs[8];
#endif #endif
/* temporary float registers */ /* temporary float registers */
float32 ft0, ft1; float32 ft0, ft1;
...@@ -268,7 +270,8 @@ int cpu_sparc_close(CPUSPARCState *s); ...@@ -268,7 +270,8 @@ int cpu_sparc_close(CPUSPARCState *s);
int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def); int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, 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); int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def,
unsigned int cpu);
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
(env->psref? PSR_EF : 0) | \ (env->psref? PSR_EF : 0) | \
......
...@@ -2,9 +2,24 @@ ...@@ -2,9 +2,24 @@
//#define DEBUG_PCALL //#define DEBUG_PCALL
//#define DEBUG_MMU //#define DEBUG_MMU
//#define DEBUG_MXCC
//#define DEBUG_UNALIGNED //#define DEBUG_UNALIGNED
//#define DEBUG_UNASSIGNED //#define DEBUG_UNASSIGNED
#ifdef DEBUG_MMU
#define DPRINTF_MMU(fmt, args...) \
do { printf("MMU: " fmt , ##args); } while (0)
#else
#define DPRINTF_MMU(fmt, args...)
#endif
#ifdef DEBUG_MXCC
#define DPRINTF_MXCC(fmt, args...) \
do { printf("MXCC: " fmt , ##args); } while (0)
#else
#define DPRINTF_MXCC(fmt, args...)
#endif
void raise_exception(int tt) void raise_exception(int tt)
{ {
env->exception_index = tt; env->exception_index = tt;
...@@ -139,12 +154,58 @@ GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); ...@@ -139,12 +154,58 @@ GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
#ifndef TARGET_SPARC64 #ifndef TARGET_SPARC64
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
#ifdef DEBUG_MXCC
static void dump_mxcc(CPUState *env)
{
printf("mxccdata: %016llx %016llx %016llx %016llx\n",
env->mxccdata[0], env->mxccdata[1], env->mxccdata[2], env->mxccdata[3]);
printf("mxccregs: %016llx %016llx %016llx %016llx\n"
" %016llx %016llx %016llx %016llx\n",
env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3],
env->mxccregs[4], env->mxccregs[5], env->mxccregs[6], env->mxccregs[7]);
}
#endif
void helper_ld_asi(int asi, int size, int sign) void helper_ld_asi(int asi, int size, int sign)
{ {
uint32_t ret = 0; uint32_t ret = 0;
#ifdef DEBUG_MXCC
uint32_t last_T0 = T0;
#endif
switch (asi) { switch (asi) {
case 2: /* SuperSparc MXCC registers */ case 2: /* SuperSparc MXCC registers */
switch (T0) {
case 0x01c00a00: /* MXCC control register */
if (size == 8) {
ret = env->mxccregs[3];
T0 = env->mxccregs[3] >> 32;
} else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00a04: /* MXCC control register */
if (size == 4)
ret = env->mxccregs[3];
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00f00: /* MBus port address register */
if (size == 8) {
ret = env->mxccregs[7];
T0 = env->mxccregs[7] >> 32;
} else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
default:
DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
break;
}
DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x,"
"T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
#ifdef DEBUG_MXCC
dump_mxcc(env);
#endif
break; break;
case 3: /* MMU probe */ case 3: /* MMU probe */
{ {
...@@ -157,9 +218,7 @@ void helper_ld_asi(int asi, int size, int sign) ...@@ -157,9 +218,7 @@ void helper_ld_asi(int asi, int size, int sign)
ret = mmu_probe(env, T0, mmulev); ret = mmu_probe(env, T0, mmulev);
//bswap32s(&ret); //bswap32s(&ret);
} }
#ifdef DEBUG_MMU DPRINTF_MMU("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 */ case 4: /* read MMU regs */
...@@ -169,9 +228,7 @@ void helper_ld_asi(int asi, int size, int sign) ...@@ -169,9 +228,7 @@ void helper_ld_asi(int asi, int size, int sign)
ret = env->mmuregs[reg]; ret = env->mmuregs[reg];
if (reg == 3) /* Fault status cleared on read */ if (reg == 3) /* Fault status cleared on read */
env->mmuregs[reg] = 0; env->mmuregs[reg] = 0;
#ifdef DEBUG_MMU DPRINTF_MMU("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 */ case 9: /* Supervisor code access */
...@@ -302,15 +359,93 @@ void helper_st_asi(int asi, int size) ...@@ -302,15 +359,93 @@ void helper_st_asi(int asi, int size)
{ {
switch(asi) { switch(asi) {
case 2: /* SuperSparc MXCC registers */ case 2: /* SuperSparc MXCC registers */
switch (T0) {
case 0x01c00000: /* MXCC stream data register 0 */
if (size == 8)
env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00008: /* MXCC stream data register 1 */
if (size == 8)
env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00010: /* MXCC stream data register 2 */
if (size == 8)
env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00018: /* MXCC stream data register 3 */
if (size == 8)
env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00100: /* MXCC stream source */
if (size == 8)
env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 0);
env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 8);
env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 16);
env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 24);
break;
case 0x01c00200: /* MXCC stream destination */
if (size == 8)
env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 0, env->mxccdata[0]);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 8, env->mxccdata[1]);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, env->mxccdata[2]);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, env->mxccdata[3]);
break;
case 0x01c00a00: /* MXCC control register */
if (size == 8)
env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00a04: /* MXCC control register */
if (size == 4)
env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000) | T1;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
case 0x01c00e00: /* MXCC error register */
if (size == 8)
env->mxccregs[6] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
if (env->mxccregs[6] == 0xffffffffffffffffULL) {
// this is probably a reset
}
break;
case 0x01c00f00: /* MBus port address register */
if (size == 8)
env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
else
DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
break;
default:
DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
break;
}
DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, T0, T1);
#ifdef DEBUG_MXCC
dump_mxcc(env);
#endif
break; break;
case 3: /* MMU flush */ case 3: /* MMU flush */
{ {
int mmulev; int mmulev;
mmulev = (T0 >> 8) & 15; mmulev = (T0 >> 8) & 15;
#ifdef DEBUG_MMU DPRINTF_MMU("mmu flush level %d\n", mmulev);
printf("mmu flush level %d\n", mmulev);
#endif
switch (mmulev) { switch (mmulev) {
case 0: // flush page case 0: // flush page
tlb_flush_page(env, T0 & 0xfffff000); tlb_flush_page(env, T0 & 0xfffff000);
...@@ -359,10 +494,10 @@ void helper_st_asi(int asi, int size) ...@@ -359,10 +494,10 @@ void helper_st_asi(int asi, int size)
env->mmuregs[reg] = T1; env->mmuregs[reg] = T1;
break; break;
} }
#ifdef DEBUG_MMU
if (oldreg != env->mmuregs[reg]) { if (oldreg != env->mmuregs[reg]) {
printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]); DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
} }
#ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(env);
#endif #endif
return; return;
...@@ -962,8 +1097,8 @@ void helper_st_asi(int asi, int size) ...@@ -962,8 +1097,8 @@ void helper_st_asi(int asi, int size)
// Mappings generated during D/I MMU disabled mode are // Mappings generated during D/I MMU disabled mode are
// invalid in normal mode // invalid in normal mode
if (oldreg != env->lsu) { if (oldreg != env->lsu) {
DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
dump_mmu(env); dump_mmu(env);
#endif #endif
tlb_flush(env, 1); tlb_flush(env, 1);
...@@ -995,10 +1130,10 @@ void helper_st_asi(int asi, int size) ...@@ -995,10 +1130,10 @@ void helper_st_asi(int asi, int size)
break; break;
} }
env->immuregs[reg] = T1; env->immuregs[reg] = T1;
#ifdef DEBUG_MMU
if (oldreg != env->immuregs[reg]) { if (oldreg != env->immuregs[reg]) {
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]); DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
} }
#ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(env);
#endif #endif
return; return;
...@@ -1064,10 +1199,10 @@ void helper_st_asi(int asi, int size) ...@@ -1064,10 +1199,10 @@ void helper_st_asi(int asi, int size)
break; break;
} }
env->dmmuregs[reg] = T1; env->dmmuregs[reg] = T1;
#ifdef DEBUG_MMU
if (oldreg != env->dmmuregs[reg]) { if (oldreg != env->dmmuregs[reg]) {
printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]); DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
} }
#ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(env);
#endif #endif
return; return;
......
...@@ -3618,12 +3618,13 @@ void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) ...@@ -3618,12 +3618,13 @@ 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) int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, unsigned int cpu)
{ {
env->version = def->iu_version; env->version = def->iu_version;
env->fsr = def->fpu_version; env->fsr = def->fpu_version;
#if !defined(TARGET_SPARC64) #if !defined(TARGET_SPARC64)
env->mmuregs[0] |= def->mmu_version; env->mmuregs[0] |= def->mmu_version;
env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
#endif #endif
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册