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 327  
328 328 for(i = 0; i < smp_cpus; i++) {
329 329 env = cpu_init();
330   - cpu_sparc_register(env, def);
  330 + cpu_sparc_register(env, def, i);
331 331 envs[i] = env;
332 332 if (i == 0) {
333 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 358 exit(1);
359 359 }
360 360 env = cpu_init();
361   - cpu_sparc_register(env, def);
  361 + cpu_sparc_register(env, def, 0);
362 362 bh = qemu_bh_new(tick_irq, env);
363 363 env->tick = ptimer_init(bh);
364 364 ptimer_set_period(env->tick, 1ULL);
... ...
linux-user/main.c
... ... @@ -2142,7 +2142,7 @@ int main(int argc, char **argv)
2142 2142 fprintf(stderr, "Unable to find Sparc CPU definition\n");
2143 2143 exit(1);
2144 2144 }
2145   - cpu_sparc_register(env, def);
  2145 + cpu_sparc_register(env, def, 0);
2146 2146 env->pc = regs->pc;
2147 2147 env->npc = regs->npc;
2148 2148 env->y = regs->y;
... ...
target-sparc/cpu.h
... ... @@ -212,6 +212,8 @@ typedef struct CPUSPARCState {
212 212 uint64_t dtlb_tte[64];
213 213 #else
214 214 uint32_t mmuregs[16];
  215 + uint64_t mxccdata[4];
  216 + uint64_t mxccregs[8];
215 217 #endif
216 218 /* temporary float registers */
217 219 float32 ft0, ft1;
... ... @@ -268,7 +270,8 @@ int cpu_sparc_close(CPUSPARCState *s);
268 270 int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
269 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 276 #define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
274 277 (env->psref? PSR_EF : 0) | \
... ...
target-sparc/op_helper.c
... ... @@ -2,9 +2,24 @@
2 2  
3 3 //#define DEBUG_PCALL
4 4 //#define DEBUG_MMU
  5 +//#define DEBUG_MXCC
5 6 //#define DEBUG_UNALIGNED
6 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 23 void raise_exception(int tt)
9 24 {
10 25 env->exception_index = tt;
... ... @@ -139,12 +154,58 @@ GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
139 154  
140 155 #ifndef TARGET_SPARC64
141 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 170 void helper_ld_asi(int asi, int size, int sign)
143 171 {
144 172 uint32_t ret = 0;
  173 +#ifdef DEBUG_MXCC
  174 + uint32_t last_T0 = T0;
  175 +#endif
145 176  
146 177 switch (asi) {
147 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 209 break;
149 210 case 3: /* MMU probe */
150 211 {
... ... @@ -157,9 +218,7 @@ void helper_ld_asi(int asi, int size, int sign)
157 218 ret = mmu_probe(env, T0, mmulev);
158 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 223 break;
165 224 case 4: /* read MMU regs */
... ... @@ -169,9 +228,7 @@ void helper_ld_asi(int asi, int size, int sign)
169 228 ret = env->mmuregs[reg];
170 229 if (reg == 3) /* Fault status cleared on read */
171 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 233 break;
177 234 case 9: /* Supervisor code access */
... ... @@ -302,15 +359,93 @@ void helper_st_asi(int asi, int size)
302 359 {
303 360 switch(asi) {
304 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 442 break;
306 443 case 3: /* MMU flush */
307 444 {
308 445 int mmulev;
309 446  
310 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 449 switch (mmulev) {
315 450 case 0: // flush page
316 451 tlb_flush_page(env, T0 & 0xfffff000);
... ... @@ -359,10 +494,10 @@ void helper_st_asi(int asi, int size)
359 494 env->mmuregs[reg] = T1;
360 495 break;
361 496 }
362   -#ifdef DEBUG_MMU
363 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 501 dump_mmu(env);
367 502 #endif
368 503 return;
... ... @@ -962,8 +1097,8 @@ void helper_st_asi(int asi, int size)
962 1097 // Mappings generated during D/I MMU disabled mode are
963 1098 // invalid in normal mode
964 1099 if (oldreg != env->lsu) {
  1100 + DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
965 1101 #ifdef DEBUG_MMU
966   - printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
967 1102 dump_mmu(env);
968 1103 #endif
969 1104 tlb_flush(env, 1);
... ... @@ -995,10 +1130,10 @@ void helper_st_asi(int asi, int size)
995 1130 break;
996 1131 }
997 1132 env->immuregs[reg] = T1;
998   -#ifdef DEBUG_MMU
999 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 1137 dump_mmu(env);
1003 1138 #endif
1004 1139 return;
... ... @@ -1064,10 +1199,10 @@ void helper_st_asi(int asi, int size)
1064 1199 break;
1065 1200 }
1066 1201 env->dmmuregs[reg] = T1;
1067   -#ifdef DEBUG_MMU
1068 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 1206 dump_mmu(env);
1072 1207 #endif
1073 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 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 3623 env->version = def->iu_version;
3624 3624 env->fsr = def->fpu_version;
3625 3625 #if !defined(TARGET_SPARC64)
3626 3626 env->mmuregs[0] |= def->mmu_version;
  3627 + env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
3627 3628 #endif
3628 3629 return 0;
3629 3630 }
... ...