25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_mips_coproc.c,v 1.64 2007/04/28 09:19:51 debug Exp $ |
* $Id: cpu_mips_coproc.c,v 1.69 2007/06/15 18:07:08 debug Exp $ |
29 |
* |
* |
30 |
* Emulation of MIPS coprocessors. |
* Emulation of MIPS coprocessors. |
31 |
*/ |
*/ |
48 |
#include "timer.h" |
#include "timer.h" |
49 |
|
|
50 |
|
|
|
#ifndef ENABLE_MIPS |
|
|
|
|
|
|
|
|
struct mips_coproc *mips_coproc_new(struct cpu *cpu, int coproc_nr) |
|
|
{ return NULL; } |
|
|
|
|
|
void mips_coproc_tlb_set_entry(struct cpu *cpu, int entrynr, int size, |
|
|
uint64_t vaddr, uint64_t paddr0, uint64_t paddr1, |
|
|
int valid0, int valid1, int dirty0, int dirty1, int global, int asid, |
|
|
int cachealgo0, int cachealgo1) { } |
|
|
|
|
|
|
|
|
#else /* ENABLE_MIPS */ |
|
|
|
|
|
|
|
51 |
extern volatile int single_step; |
extern volatile int single_step; |
52 |
|
|
53 |
static char *cop0_names[] = COP0_NAMES; |
static char *cop0_names[] = COP0_NAMES; |
84 |
; |
; |
85 |
/* Config select 1: caches etc. TODO: Don't use |
/* Config select 1: caches etc. TODO: Don't use |
86 |
cpu->machine for this stuff! */ |
cpu->machine for this stuff! */ |
87 |
IB = cpu->machine->cache_picache_linesize - 1; |
IB = cpu->cd.mips.cache_picache_linesize - 1; |
88 |
IB = IB < 0? 0 : (IB > 7? 7 : IB); |
IB = IB < 0? 0 : (IB > 7? 7 : IB); |
89 |
DB = cpu->machine->cache_pdcache_linesize - 1; |
DB = cpu->cd.mips.cache_pdcache_linesize - 1; |
90 |
DB = DB < 0? 0 : (DB > 7? 7 : DB); |
DB = DB < 0? 0 : (DB > 7? 7 : DB); |
91 |
IC = cpu->machine->cache_picache - |
IC = cpu->cd.mips.cache_picache - |
92 |
cpu->machine->cache_picache_linesize - 7; |
cpu->cd.mips.cache_picache_linesize - 7; |
93 |
DC = cpu->machine->cache_pdcache - |
DC = cpu->cd.mips.cache_pdcache - |
94 |
cpu->machine->cache_pdcache_linesize - 7; |
cpu->cd.mips.cache_pdcache_linesize - 7; |
95 |
IA = cpu->cd.mips.cpu_type.piways - 1; |
IA = cpu->cd.mips.cpu_type.piways - 1; |
96 |
DA = cpu->cd.mips.cpu_type.pdways - 1; |
DA = cpu->cd.mips.cpu_type.pdways - 1; |
97 |
cpu->cd.mips.cop0_config_select1 = |
cpu->cd.mips.cop0_config_select1 = |
119 |
break; |
break; |
120 |
case MIPS_R4000: /* according to the R4000 manual */ |
case MIPS_R4000: /* according to the R4000 manual */ |
121 |
case MIPS_R4600: |
case MIPS_R4600: |
122 |
IB = cpu->machine->cache_picache_linesize - 4; |
IB = cpu->cd.mips.cache_picache_linesize - 4; |
123 |
IB = IB < 0? 0 : (IB > 1? 1 : IB); |
IB = IB < 0? 0 : (IB > 1? 1 : IB); |
124 |
DB = cpu->machine->cache_pdcache_linesize - 4; |
DB = cpu->cd.mips.cache_pdcache_linesize - 4; |
125 |
DB = DB < 0? 0 : (DB > 1? 1 : DB); |
DB = DB < 0? 0 : (DB > 1? 1 : DB); |
126 |
SB = cpu->machine->cache_secondary_linesize - 4; |
SB = cpu->cd.mips.cache_secondary_linesize - 4; |
127 |
SB = SB < 0? 0 : (SB > 3? 3 : SB); |
SB = SB < 0? 0 : (SB > 3? 3 : SB); |
128 |
IC = cpu->machine->cache_picache - 12; |
IC = cpu->cd.mips.cache_picache - 12; |
129 |
IC = IC < 0? 0 : (IC > 7? 7 : IC); |
IC = IC < 0? 0 : (IC > 7? 7 : IC); |
130 |
DC = cpu->machine->cache_pdcache - 12; |
DC = cpu->cd.mips.cache_pdcache - 12; |
131 |
DC = DC < 0? 0 : (DC > 7? 7 : DC); |
DC = DC < 0? 0 : (DC > 7? 7 : DC); |
132 |
SC = cpu->machine->cache_secondary? 0 : 1; |
SC = cpu->cd.mips.cache_secondary? 0 : 1; |
133 |
c->reg[COP0_CONFIG] = |
c->reg[COP0_CONFIG] = |
134 |
( 0 << 31) /* Master/Checker present bit */ |
( 0 << 31) /* Master/Checker present bit */ |
135 |
| (0x00 << 28) /* EC: system clock divisor, |
| (0x00 << 28) /* EC: system clock divisor, |
161 |
; |
; |
162 |
break; |
break; |
163 |
case MIPS_R4100: /* According to the VR4131 manual: */ |
case MIPS_R4100: /* According to the VR4131 manual: */ |
164 |
IB = cpu->machine->cache_picache_linesize - 4; |
IB = cpu->cd.mips.cache_picache_linesize - 4; |
165 |
IB = IB < 0? 0 : (IB > 1? 1 : IB); |
IB = IB < 0? 0 : (IB > 1? 1 : IB); |
166 |
DB = cpu->machine->cache_pdcache_linesize - 4; |
DB = cpu->cd.mips.cache_pdcache_linesize - 4; |
167 |
DB = DB < 0? 0 : (DB > 1? 1 : DB); |
DB = DB < 0? 0 : (DB > 1? 1 : DB); |
168 |
IC = cpu->machine->cache_picache - 10; |
IC = cpu->cd.mips.cache_picache - 10; |
169 |
IC = IC < 0? 0 : (IC > 7? 7 : IC); |
IC = IC < 0? 0 : (IC > 7? 7 : IC); |
170 |
DC = cpu->machine->cache_pdcache - 10; |
DC = cpu->cd.mips.cache_pdcache - 10; |
171 |
DC = DC < 0? 0 : (DC > 7? 7 : DC); |
DC = DC < 0? 0 : (DC > 7? 7 : DC); |
172 |
c->reg[COP0_CONFIG] = |
c->reg[COP0_CONFIG] = |
173 |
( 0 << 31) /* IS: Instruction Streaming bit */ |
( 0 << 31) /* IS: Instruction Streaming bit */ |
232 |
case MIPS_R10000: |
case MIPS_R10000: |
233 |
case MIPS_R12000: |
case MIPS_R12000: |
234 |
case MIPS_R14000: |
case MIPS_R14000: |
235 |
IC = cpu->machine->cache_picache - 12; |
IC = cpu->cd.mips.cache_picache - 12; |
236 |
IC = IC < 0? 0 : (IC > 7? 7 : IC); |
IC = IC < 0? 0 : (IC > 7? 7 : IC); |
237 |
DC = cpu->machine->cache_pdcache - 12; |
DC = cpu->cd.mips.cache_pdcache - 12; |
238 |
DC = DC < 0? 0 : (DC > 7? 7 : DC); |
DC = DC < 0? 0 : (DC > 7? 7 : DC); |
239 |
SC = cpu->machine->cache_secondary - 19; |
SC = cpu->cd.mips.cache_secondary - 19; |
240 |
SC = SC < 0? 0 : (SC > 7? 7 : SC); |
SC = SC < 0? 0 : (SC > 7? 7 : SC); |
241 |
/* According to the R10000 User's Manual: */ |
/* According to the R10000 User's Manual: */ |
242 |
c->reg[COP0_CONFIG] = |
c->reg[COP0_CONFIG] = |
359 |
{ |
{ |
360 |
struct mips_coproc *c; |
struct mips_coproc *c; |
361 |
|
|
362 |
c = malloc(sizeof(struct mips_coproc)); |
CHECK_ALLOCATION(c = malloc(sizeof(struct mips_coproc))); |
|
if (c == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
|
|
|
363 |
memset(c, 0, sizeof(struct mips_coproc)); |
memset(c, 0, sizeof(struct mips_coproc)); |
364 |
|
|
365 |
c->coproc_nr = coproc_nr; |
c->coproc_nr = coproc_nr; |
366 |
|
|
367 |
if (coproc_nr == 0) { |
if (coproc_nr == 0) { |
960 |
cp->coproc_nr, reg_nr, cp->coproc_nr==0? |
cp->coproc_nr, reg_nr, cp->coproc_nr==0? |
961 |
cop0_names[reg_nr] : "?", (long long)tmp); |
cop0_names[reg_nr] : "?", (long long)tmp); |
962 |
|
|
963 |
mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, |
/* mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, |
964 |
cp->coproc_nr, 0, 0, 0); |
cp->coproc_nr, 0, 0, 0); |
965 |
return; |
return; */ |
966 |
} |
} |
967 |
|
|
968 |
if (readonly) { |
if (readonly) { |
2128 |
exit(1); |
exit(1); |
2129 |
} |
} |
2130 |
|
|
|
op = (function) & 0xff; |
|
2131 |
switch (co_bit) { |
switch (co_bit) { |
2132 |
|
case 0: |
2133 |
|
if ((function & 0x03e0ffdf) == 0x01606000) { |
2134 |
|
debug("%ci", function & 0x20? 'e' : 'd'); |
2135 |
|
if (rt != MIPS_GPR_ZERO) |
2136 |
|
debug("\t%s", regnames[rt]); |
2137 |
|
debug("\n"); |
2138 |
|
return; |
2139 |
|
} |
2140 |
|
break; |
2141 |
case 1: |
case 1: |
2142 |
|
op = (function) & 0xff; |
2143 |
switch (op) { |
switch (op) { |
2144 |
case COP0_TLBR: /* Read indexed TLB entry */ |
case COP0_TLBR: /* Read indexed TLB entry */ |
2145 |
debug("tlbr\n"); |
debug("tlbr\n"); |
2202 |
default: |
default: |
2203 |
; |
; |
2204 |
} |
} |
2205 |
default: |
break; |
|
; |
|
2206 |
} |
} |
2207 |
} |
} |
2208 |
|
|
2228 |
mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, cp->coproc_nr, 0, 0, 0); |
mips_cpu_exception(cpu, EXCEPTION_CPU, 0, 0, cp->coproc_nr, 0, 0, 0); |
2229 |
} |
} |
2230 |
|
|
|
#endif /* ENABLE_MIPS */ |
|