Commit 952a328ff50c323b28fb07658ccbc6604cf26a45

Authored by blueswir1
1 parent 992f48a0

SuperSparc MXCC support (Robert Reif)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3397 c046a42c-6fe2-441c-8c8c-71466251a162
hw/sun4m.c
@@ -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,
327 327
328 for(i = 0; i < smp_cpus; i++) { 328 for(i = 0; i < smp_cpus; i++) {
329 env = cpu_init(); 329 env = cpu_init();
330 - cpu_sparc_register(env, def); 330 + cpu_sparc_register(env, def, i);
331 envs[i] = env; 331 envs[i] = env;
332 if (i == 0) { 332 if (i == 0) {
333 qemu_register_reset(main_cpu_reset, env); 333 qemu_register_reset(main_cpu_reset, env);
hw/sun4u.c
@@ -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,
358 exit(1); 358 exit(1);
359 } 359 }
360 env = cpu_init(); 360 env = cpu_init();
361 - cpu_sparc_register(env, def); 361 + cpu_sparc_register(env, def, 0);
362 bh = qemu_bh_new(tick_irq, env); 362 bh = qemu_bh_new(tick_irq, env);
363 env->tick = ptimer_init(bh); 363 env->tick = ptimer_init(bh);
364 ptimer_set_period(env->tick, 1ULL); 364 ptimer_set_period(env->tick, 1ULL);
linux-user/main.c
@@ -2142,7 +2142,7 @@ int main(int argc, char **argv) @@ -2142,7 +2142,7 @@ int main(int argc, char **argv)
2142 fprintf(stderr, "Unable to find Sparc CPU definition\n"); 2142 fprintf(stderr, "Unable to find Sparc CPU definition\n");
2143 exit(1); 2143 exit(1);
2144 } 2144 }
2145 - cpu_sparc_register(env, def); 2145 + cpu_sparc_register(env, def, 0);
2146 env->pc = regs->pc; 2146 env->pc = regs->pc;
2147 env->npc = regs->npc; 2147 env->npc = regs->npc;
2148 env->y = regs->y; 2148 env->y = regs->y;
target-sparc/cpu.h
@@ -212,6 +212,8 @@ typedef struct CPUSPARCState { @@ -212,6 +212,8 @@ typedef struct CPUSPARCState {
212 uint64_t dtlb_tte[64]; 212 uint64_t dtlb_tte[64];
213 #else 213 #else
214 uint32_t mmuregs[16]; 214 uint32_t mmuregs[16];
  215 + uint64_t mxccdata[4];
  216 + uint64_t mxccregs[8];
215 #endif 217 #endif
216 /* temporary float registers */ 218 /* temporary float registers */
217 float32 ft0, ft1; 219 float32 ft0, ft1;
@@ -268,7 +270,8 @@ int cpu_sparc_close(CPUSPARCState *s); @@ -268,7 +270,8 @@ int cpu_sparc_close(CPUSPARCState *s);
268 int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def); 270 int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
269 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, 271 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
270 ...)); 272 ...));
271 -int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def); 273 +int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def,
  274 + unsigned int cpu);
272 275
273 #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ 276 #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
274 (env->psref? PSR_EF : 0) | \ 277 (env->psref? PSR_EF : 0) | \
target-sparc/op_helper.c
@@ -2,9 +2,24 @@ @@ -2,9 +2,24 @@
2 2
3 //#define DEBUG_PCALL 3 //#define DEBUG_PCALL
4 //#define DEBUG_MMU 4 //#define DEBUG_MMU
  5 +//#define DEBUG_MXCC
5 //#define DEBUG_UNALIGNED 6 //#define DEBUG_UNALIGNED
6 //#define DEBUG_UNASSIGNED 7 //#define DEBUG_UNASSIGNED
7 8
  9 +#ifdef DEBUG_MMU
  10 +#define DPRINTF_MMU(fmt, args...) \
  11 +do { printf("MMU: " fmt , ##args); } while (0)
  12 +#else
  13 +#define DPRINTF_MMU(fmt, args...)
  14 +#endif
  15 +
  16 +#ifdef DEBUG_MXCC
  17 +#define DPRINTF_MXCC(fmt, args...) \
  18 +do { printf("MXCC: " fmt , ##args); } while (0)
  19 +#else
  20 +#define DPRINTF_MXCC(fmt, args...)
  21 +#endif
  22 +
8 void raise_exception(int tt) 23 void raise_exception(int tt)
9 { 24 {
10 env->exception_index = tt; 25 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);
139 154
140 #ifndef TARGET_SPARC64 155 #ifndef TARGET_SPARC64
141 #ifndef CONFIG_USER_ONLY 156 #ifndef CONFIG_USER_ONLY
  157 +
  158 +#ifdef DEBUG_MXCC
  159 +static void dump_mxcc(CPUState *env)
  160 +{
  161 + printf("mxccdata: %016llx %016llx %016llx %016llx\n",
  162 + env->mxccdata[0], env->mxccdata[1], env->mxccdata[2], env->mxccdata[3]);
  163 + printf("mxccregs: %016llx %016llx %016llx %016llx\n"
  164 + " %016llx %016llx %016llx %016llx\n",
  165 + env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3],
  166 + env->mxccregs[4], env->mxccregs[5], env->mxccregs[6], env->mxccregs[7]);
  167 +}
  168 +#endif
  169 +
142 void helper_ld_asi(int asi, int size, int sign) 170 void helper_ld_asi(int asi, int size, int sign)
143 { 171 {
144 uint32_t ret = 0; 172 uint32_t ret = 0;
  173 +#ifdef DEBUG_MXCC
  174 + uint32_t last_T0 = T0;
  175 +#endif
145 176
146 switch (asi) { 177 switch (asi) {
147 case 2: /* SuperSparc MXCC registers */ 178 case 2: /* SuperSparc MXCC registers */
  179 + switch (T0) {
  180 + case 0x01c00a00: /* MXCC control register */
  181 + if (size == 8) {
  182 + ret = env->mxccregs[3];
  183 + T0 = env->mxccregs[3] >> 32;
  184 + } else
  185 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  186 + break;
  187 + case 0x01c00a04: /* MXCC control register */
  188 + if (size == 4)
  189 + ret = env->mxccregs[3];
  190 + else
  191 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  192 + break;
  193 + case 0x01c00f00: /* MBus port address register */
  194 + if (size == 8) {
  195 + ret = env->mxccregs[7];
  196 + T0 = env->mxccregs[7] >> 32;
  197 + } else
  198 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  199 + break;
  200 + default:
  201 + DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
  202 + break;
  203 + }
  204 + DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x,"
  205 + "T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
  206 +#ifdef DEBUG_MXCC
  207 + dump_mxcc(env);
  208 +#endif
148 break; 209 break;
149 case 3: /* MMU probe */ 210 case 3: /* MMU probe */
150 { 211 {
@@ -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)
157 ret = mmu_probe(env, T0, mmulev); 218 ret = mmu_probe(env, T0, mmulev);
158 //bswap32s(&ret); 219 //bswap32s(&ret);
159 } 220 }
160 -#ifdef DEBUG_MMU  
161 - printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);  
162 -#endif 221 + DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
163 } 222 }
164 break; 223 break;
165 case 4: /* read MMU regs */ 224 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)
169 ret = env->mmuregs[reg]; 228 ret = env->mmuregs[reg];
170 if (reg == 3) /* Fault status cleared on read */ 229 if (reg == 3) /* Fault status cleared on read */
171 env->mmuregs[reg] = 0; 230 env->mmuregs[reg] = 0;
172 -#ifdef DEBUG_MMU  
173 - printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);  
174 -#endif 231 + DPRINTF_MMU("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
175 } 232 }
176 break; 233 break;
177 case 9: /* Supervisor code access */ 234 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)
302 { 359 {
303 switch(asi) { 360 switch(asi) {
304 case 2: /* SuperSparc MXCC registers */ 361 case 2: /* SuperSparc MXCC registers */
  362 + switch (T0) {
  363 + case 0x01c00000: /* MXCC stream data register 0 */
  364 + if (size == 8)
  365 + env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
  366 + else
  367 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  368 + break;
  369 + case 0x01c00008: /* MXCC stream data register 1 */
  370 + if (size == 8)
  371 + env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
  372 + else
  373 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  374 + break;
  375 + case 0x01c00010: /* MXCC stream data register 2 */
  376 + if (size == 8)
  377 + env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
  378 + else
  379 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  380 + break;
  381 + case 0x01c00018: /* MXCC stream data register 3 */
  382 + if (size == 8)
  383 + env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
  384 + else
  385 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  386 + break;
  387 + case 0x01c00100: /* MXCC stream source */
  388 + if (size == 8)
  389 + env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
  390 + else
  391 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  392 + env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 0);
  393 + env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 8);
  394 + env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 16);
  395 + env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 24);
  396 + break;
  397 + case 0x01c00200: /* MXCC stream destination */
  398 + if (size == 8)
  399 + env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
  400 + else
  401 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  402 + stq_phys((env->mxccregs[1] & 0xffffffffULL) + 0, env->mxccdata[0]);
  403 + stq_phys((env->mxccregs[1] & 0xffffffffULL) + 8, env->mxccdata[1]);
  404 + stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, env->mxccdata[2]);
  405 + stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, env->mxccdata[3]);
  406 + break;
  407 + case 0x01c00a00: /* MXCC control register */
  408 + if (size == 8)
  409 + env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
  410 + else
  411 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  412 + break;
  413 + case 0x01c00a04: /* MXCC control register */
  414 + if (size == 4)
  415 + env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000) | T1;
  416 + else
  417 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  418 + break;
  419 + case 0x01c00e00: /* MXCC error register */
  420 + if (size == 8)
  421 + env->mxccregs[6] = ((uint64_t)T1 << 32) | T2;
  422 + else
  423 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  424 + if (env->mxccregs[6] == 0xffffffffffffffffULL) {
  425 + // this is probably a reset
  426 + }
  427 + break;
  428 + case 0x01c00f00: /* MBus port address register */
  429 + if (size == 8)
  430 + env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
  431 + else
  432 + DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
  433 + break;
  434 + default:
  435 + DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
  436 + break;
  437 + }
  438 + DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, T0, T1);
  439 +#ifdef DEBUG_MXCC
  440 + dump_mxcc(env);
  441 +#endif
305 break; 442 break;
306 case 3: /* MMU flush */ 443 case 3: /* MMU flush */
307 { 444 {
308 int mmulev; 445 int mmulev;
309 446
310 mmulev = (T0 >> 8) & 15; 447 mmulev = (T0 >> 8) & 15;
311 -#ifdef DEBUG_MMU  
312 - printf("mmu flush level %d\n", mmulev);  
313 -#endif 448 + DPRINTF_MMU("mmu flush level %d\n", mmulev);
314 switch (mmulev) { 449 switch (mmulev) {
315 case 0: // flush page 450 case 0: // flush page
316 tlb_flush_page(env, T0 & 0xfffff000); 451 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)
359 env->mmuregs[reg] = T1; 494 env->mmuregs[reg] = T1;
360 break; 495 break;
361 } 496 }
362 -#ifdef DEBUG_MMU  
363 if (oldreg != env->mmuregs[reg]) { 497 if (oldreg != env->mmuregs[reg]) {
364 - printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]); 498 + DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
365 } 499 }
  500 +#ifdef DEBUG_MMU
366 dump_mmu(env); 501 dump_mmu(env);
367 #endif 502 #endif
368 return; 503 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)
962 // Mappings generated during D/I MMU disabled mode are 1097 // Mappings generated during D/I MMU disabled mode are
963 // invalid in normal mode 1098 // invalid in normal mode
964 if (oldreg != env->lsu) { 1099 if (oldreg != env->lsu) {
  1100 + DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
965 #ifdef DEBUG_MMU 1101 #ifdef DEBUG_MMU
966 - printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);  
967 dump_mmu(env); 1102 dump_mmu(env);
968 #endif 1103 #endif
969 tlb_flush(env, 1); 1104 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)
995 break; 1130 break;
996 } 1131 }
997 env->immuregs[reg] = T1; 1132 env->immuregs[reg] = T1;
998 -#ifdef DEBUG_MMU  
999 if (oldreg != env->immuregs[reg]) { 1133 if (oldreg != env->immuregs[reg]) {
1000 - printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]); 1134 + DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1001 } 1135 }
  1136 +#ifdef DEBUG_MMU
1002 dump_mmu(env); 1137 dump_mmu(env);
1003 #endif 1138 #endif
1004 return; 1139 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)
1064 break; 1199 break;
1065 } 1200 }
1066 env->dmmuregs[reg] = T1; 1201 env->dmmuregs[reg] = T1;
1067 -#ifdef DEBUG_MMU  
1068 if (oldreg != env->dmmuregs[reg]) { 1202 if (oldreg != env->dmmuregs[reg]) {
1069 - printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]); 1203 + DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1070 } 1204 }
  1205 +#ifdef DEBUG_MMU
1071 dump_mmu(env); 1206 dump_mmu(env);
1072 #endif 1207 #endif
1073 return; 1208 return;
target-sparc/translate.c
@@ -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, ...))
3618 } 3618 }
3619 } 3619 }
3620 3620
3621 -int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def) 3621 +int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, unsigned int cpu)
3622 { 3622 {
3623 env->version = def->iu_version; 3623 env->version = def->iu_version;
3624 env->fsr = def->fpu_version; 3624 env->fsr = def->fpu_version;
3625 #if !defined(TARGET_SPARC64) 3625 #if !defined(TARGET_SPARC64)
3626 env->mmuregs[0] |= def->mmu_version; 3626 env->mmuregs[0] |= def->mmu_version;
  3627 + env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
3627 #endif 3628 #endif
3628 return 0; 3629 return 0;
3629 } 3630 }