25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_mips.c,v 1.42 2005/06/11 20:59:11 debug Exp $ |
* $Id: cpu_mips.c,v 1.46 2005/06/26 22:23:42 debug Exp $ |
29 |
* |
* |
30 |
* MIPS core CPU emulation. |
* MIPS core CPU emulation. |
31 |
*/ |
*/ |
113 |
ch[3] = ch[2] = '\0'; |
ch[3] = ch[2] = '\0'; |
114 |
|
|
115 |
if (r<0 || r>=32) |
if (r<0 || r>=32) |
116 |
strcpy(ch, "xx"); |
strlcpy(ch, "xx", sizeof(ch)); |
117 |
else if (machine->show_symbolic_register_names) |
else if (machine->show_symbolic_register_names) |
118 |
strcpy(ch, regnames[r]); |
strlcpy(ch, regnames[r], sizeof(ch)); |
119 |
else |
else |
120 |
sprintf(ch, "r%i", r); |
snprintf(ch, sizeof(ch), "r%i", r); |
121 |
|
|
122 |
return ch; |
return ch; |
123 |
} |
} |
127 |
* mips_cpu_new(): |
* mips_cpu_new(): |
128 |
* |
* |
129 |
* Create a new MIPS cpu object. |
* Create a new MIPS cpu object. |
130 |
|
* |
131 |
|
* Returns 1 on success, 0 if there was no valid MIPS processor with |
132 |
|
* a matching name. |
133 |
*/ |
*/ |
134 |
struct cpu *mips_cpu_new(struct memory *mem, struct machine *machine, |
int mips_cpu_new(struct cpu *cpu, struct memory *mem, struct machine *machine, |
135 |
int cpu_id, char *cpu_type_name) |
int cpu_id, char *cpu_type_name) |
136 |
{ |
{ |
|
struct cpu *cpu; |
|
137 |
int i, found, j, tags_size, n_cache_lines, size_per_cache_line; |
int i, found, j, tags_size, n_cache_lines, size_per_cache_line; |
138 |
struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS; |
struct mips_cpu_type_def cpu_type_defs[] = MIPS_CPU_TYPE_DEFS; |
139 |
int64_t secondary_cache_size; |
int64_t secondary_cache_size; |
151 |
} |
} |
152 |
|
|
153 |
if (found == -1) |
if (found == -1) |
154 |
return NULL; |
return 0; |
|
|
|
|
cpu = malloc(sizeof(struct cpu)); |
|
|
if (cpu == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
155 |
|
|
|
memset(cpu, 0, sizeof(struct cpu)); |
|
156 |
cpu->memory_rw = mips_memory_rw; |
cpu->memory_rw = mips_memory_rw; |
157 |
cpu->cd.mips.cpu_type = cpu_type_defs[found]; |
cpu->cd.mips.cpu_type = cpu_type_defs[found]; |
158 |
cpu->name = cpu->cd.mips.cpu_type.name; |
cpu->name = cpu->cd.mips.cpu_type.name; |
|
cpu->mem = mem; |
|
|
cpu->machine = machine; |
|
|
cpu->cpu_id = cpu_id; |
|
159 |
cpu->byte_order = EMUL_LITTLE_ENDIAN; |
cpu->byte_order = EMUL_LITTLE_ENDIAN; |
|
cpu->bootstrap_cpu_flag = 0; |
|
|
cpu->running = 0; |
|
160 |
cpu->cd.mips.gpr[MIPS_GPR_SP] = INITIAL_STACK_POINTER; |
cpu->cd.mips.gpr[MIPS_GPR_SP] = INITIAL_STACK_POINTER; |
161 |
|
|
162 |
if (cpu_id == 0) |
if (cpu_id == 0) |
329 |
cpu->translate_address = translate_address_generic; |
cpu->translate_address = translate_address_generic; |
330 |
} |
} |
331 |
|
|
332 |
return cpu; |
return 1; |
333 |
} |
} |
334 |
|
|
335 |
|
|
653 |
if (writeflag) { |
if (writeflag) { |
654 |
coproc_register_write(m->cpus[cpunr], |
coproc_register_write(m->cpus[cpunr], |
655 |
m->cpus[cpunr]->cd.mips.coproc[0], nr, |
m->cpus[cpunr]->cd.mips.coproc[0], nr, |
656 |
valuep, 1); |
valuep, 1, 0); |
657 |
} else { |
} else { |
658 |
/* TODO: Use coproc_register_read instead? */ |
/* TODO: Use coproc_register_read instead? */ |
659 |
*valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr]; |
*valuep = m->cpus[cpunr]->cd.mips.coproc[0]->reg[nr]; |
1978 |
|
|
1979 |
|
|
1980 |
/* |
/* |
1981 |
* ROM emulation: |
* ROM emulation: (0xbfcXXXXX or 0x9fcXXXXX) |
1982 |
* |
* |
1983 |
* This assumes that a jal was made to a ROM address, |
* This assumes that a jal was made to a ROM address, |
1984 |
* and we should return via gpr ra. |
* and we should return via gpr ra. |
1985 |
*/ |
*/ |
1986 |
if ((cached_pc & 0xfff00000) == 0xbfc00000 && |
if ((cached_pc & 0xdff00000) == 0x9fc00000 && |
1987 |
cpu->machine->prom_emulation) { |
cpu->machine->prom_emulation) { |
1988 |
int rom_jal, res = 1; |
int rom_jal = 1, res = 1; |
1989 |
switch (cpu->machine->machine_type) { |
switch (cpu->machine->machine_type) { |
1990 |
case MACHINE_DEC: |
case MACHINE_DEC: |
1991 |
res = decstation_prom_emul(cpu); |
res = decstation_prom_emul(cpu); |
|
rom_jal = 1; |
|
1992 |
break; |
break; |
1993 |
case MACHINE_PS2: |
case MACHINE_PS2: |
1994 |
res = playstation2_sifbios_emul(cpu); |
res = playstation2_sifbios_emul(cpu); |
|
rom_jal = 1; |
|
1995 |
break; |
break; |
1996 |
case MACHINE_ARC: |
case MACHINE_ARC: |
1997 |
case MACHINE_SGI: |
case MACHINE_SGI: |
1998 |
res = arcbios_emul(cpu); |
res = arcbios_emul(cpu); |
1999 |
rom_jal = 1; |
break; |
2000 |
|
case MACHINE_EVBMIPS: |
2001 |
|
res = yamon_emul(cpu); |
2002 |
break; |
break; |
2003 |
default: |
default: |
2004 |
rom_jal = 0; |
rom_jal = 0; |
3369 |
!(cp0->reg[COP0_STATUS] & STATUS_FR))) { |
!(cp0->reg[COP0_STATUS] & STATUS_FR))) { |
3370 |
uint64_t a, b; |
uint64_t a, b; |
3371 |
coproc_register_read(cpu, |
coproc_register_read(cpu, |
3372 |
cpu->cd.mips.coproc[cpnr], rt, &a); |
cpu->cd.mips.coproc[cpnr], rt, &a, 0); |
3373 |
coproc_register_read(cpu, |
coproc_register_read(cpu, |
3374 |
cpu->cd.mips.coproc[cpnr], rt^1, &b); |
cpu->cd.mips.coproc[cpnr], rt^1, &b, 0); |
3375 |
if (rt & 1) |
if (rt & 1) |
3376 |
fatal("WARNING: SDCx in 32-bit mode from odd register!\n"); |
fatal("WARNING: SDCx in 32-bit mode from odd register!\n"); |
3377 |
value = (a & 0xffffffffULL) |
value = (a & 0xffffffffULL) |
3378 |
| (b << 32); |
| (b << 32); |
3379 |
} else |
} else |
3380 |
coproc_register_read(cpu, cpu->cd.mips.coproc[cpnr], rt, &value); |
coproc_register_read(cpu, cpu->cd.mips.coproc[cpnr], rt, &value, 0); |
3381 |
} |
} |
3382 |
break; |
break; |
3383 |
default: |
default: |
3514 |
b = (int64_t)(int32_t) (value >> 32); |
b = (int64_t)(int32_t) (value >> 32); |
3515 |
coproc_register_write(cpu, |
coproc_register_write(cpu, |
3516 |
cpu->cd.mips.coproc[cpnr], rt, &a, |
cpu->cd.mips.coproc[cpnr], rt, &a, |
3517 |
hi6==HI6_LDC1 || hi6==HI6_LDC2); |
hi6==HI6_LDC1 || hi6==HI6_LDC2, 0); |
3518 |
coproc_register_write(cpu, |
coproc_register_write(cpu, |
3519 |
cpu->cd.mips.coproc[cpnr], rt ^ 1, &b, |
cpu->cd.mips.coproc[cpnr], rt ^ 1, &b, |
3520 |
hi6==HI6_LDC1 || hi6==HI6_LDC2); |
hi6==HI6_LDC1 || hi6==HI6_LDC2, 0); |
3521 |
if (rt & 1) |
if (rt & 1) |
3522 |
fatal("WARNING: LDCx in 32-bit mode to odd register!\n"); |
fatal("WARNING: LDCx in 32-bit mode to odd register!\n"); |
3523 |
} else { |
} else { |
3524 |
coproc_register_write(cpu, |
coproc_register_write(cpu, |
3525 |
cpu->cd.mips.coproc[cpnr], rt, &value, |
cpu->cd.mips.coproc[cpnr], rt, &value, |
3526 |
hi6==HI6_LDC1 || hi6==HI6_LDC2); |
hi6==HI6_LDC1 || hi6==HI6_LDC2, 0); |
3527 |
} |
} |
3528 |
} |
} |
3529 |
break; |
break; |