28 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
29 |
* |
* |
30 |
* |
* |
31 |
* $Id: cpu_m88k.h,v 1.4 2007/04/28 00:12:03 debug Exp $ |
* $Id: cpu_m88k.h,v 1.21 2007/06/07 15:36:24 debug Exp $ |
32 |
*/ |
*/ |
33 |
|
|
34 |
#include "misc.h" |
#include "misc.h" |
35 |
#include "interrupt.h" |
#include "interrupt.h" |
36 |
|
|
37 |
|
#include "m88k_psl.h" |
38 |
|
|
39 |
struct cpu_family; |
struct cpu_family; |
40 |
|
struct timer; |
41 |
|
|
42 |
/* M88K CPU types: */ |
/* M88K CPU types: */ |
43 |
struct m88k_cpu_type_def { |
struct m88k_cpu_type_def { |
44 |
char *name; |
char *name; |
45 |
int type; |
int type; |
46 |
|
uint32_t pid; |
47 |
}; |
}; |
48 |
|
|
49 |
#define M88K_CPU_TYPE_DEFS { \ |
#define M88K_PID(arn,vn) ((arn << M88K_ARN_SHIFT) | (vn << M88K_VN_SHIFT)) |
50 |
{ "88100", 88100 }, \ |
|
51 |
{ "88110", 88110 }, \ |
#define M88K_CPU_TYPE_DEFS { \ |
52 |
{ NULL, 0 } \ |
{ "88100", 88100, M88K_PID(M88K_ARN_88100,3) }, \ |
53 |
|
{ "88110", 88110, M88K_PID(M88K_ARN_88110,0) }, \ |
54 |
|
{ NULL, 0, 0 } \ |
55 |
} |
} |
56 |
|
|
57 |
|
/* Control register names: */ |
58 |
|
#define N_M88K_CONTROL_REGS 64 |
59 |
|
#define M88K_CR_NAMES { \ |
60 |
|
"PID", "PSR", "EPSR", "SSBR", /* 0 .. 3 */ \ |
61 |
|
"SXIP", "SNIP", "SFIP", "VBR", /* 4 .. 7 */ \ |
62 |
|
"DMT0", "DMD0", "DMA0", "DMT1", /* 8 .. 11 */ \ |
63 |
|
"DMD1", "DMA1", "DMT2", "DMD2", /* 12 .. 15 */ \ |
64 |
|
"DMA2", "SR0", "SR1", "SR2", /* 16 .. 19 */ \ |
65 |
|
"SR3", "CR21", "CR22", "CR23", /* 20 .. 23 */ \ |
66 |
|
"CR24", "CR25", "CR26", "CR27", /* 24 .. 27 */ \ |
67 |
|
"CR28", "CR29", "CR30", "CR31", /* 28 .. 31 */ \ |
68 |
|
"CR32", "CR33", "CR34", "CR35", /* 32 .. 35 */ \ |
69 |
|
"CR36", "CR37", "CR38", "CR39", /* 36 .. 39 */ \ |
70 |
|
"CR40", "CR41", "CR42", "CR43", /* 40 .. 43 */ \ |
71 |
|
"CR44", "CR45", "CR46", "CR47", /* 44 .. 47 */ \ |
72 |
|
"CR48", "CR49", "CR50", "CR51", /* 48 .. 51 */ \ |
73 |
|
"CR52", "CR53", "CR54", "CR55", /* 52 .. 55 */ \ |
74 |
|
"CR56", "CR57", "CR58", "CR59", /* 56 .. 59 */ \ |
75 |
|
"CR60", "CR61", "CR62", "CR63" /* 60 .. 63 */ } |
76 |
|
|
77 |
|
#define M88K_CR_PID 0 |
78 |
|
#define M88K_CR_PSR 1 |
79 |
|
#define M88K_CR_EPSR 2 |
80 |
|
#define M88K_CR_SSBR 3 |
81 |
|
#define M88K_CR_SXIP 4 |
82 |
|
#define M88K_CR_SNIP 5 |
83 |
|
#define M88K_CR_SFIP 6 |
84 |
|
#define M88K_CR_VBR 7 |
85 |
|
#define M88K_CR_DMT0 8 |
86 |
|
#define M88K_CR_DMD0 9 |
87 |
|
#define M88K_CR_DMA0 10 |
88 |
|
#define M88K_CR_DMT1 11 |
89 |
|
#define M88K_CR_DMD1 12 |
90 |
|
#define M88K_CR_DMA1 13 |
91 |
|
#define M88K_CR_DMT2 14 |
92 |
|
#define M88K_CR_DMD2 15 |
93 |
|
#define M88K_CR_DMA2 16 |
94 |
|
#define M88K_CR_SR0 17 |
95 |
|
#define M88K_CR_SR1 18 |
96 |
|
#define M88K_CR_SR2 19 |
97 |
|
#define M88K_CR_SR3 20 |
98 |
|
|
99 |
|
/* MVME197 extended control registers: */ |
100 |
|
#define M88K_CR_NAMES_197 { \ |
101 |
|
"PID", "PSR", "EPSR", "SSBR", /* 0 .. 3 */ \ |
102 |
|
"EXIP", "ENIP", "SFIP", "VBR", /* 4 .. 7 */ \ |
103 |
|
"DMT0", "DMD0", "DMA0", "DMT1", /* 8 .. 11 */ \ |
104 |
|
"DMD1", "DMA1", "DMT2", "DMD2", /* 12 .. 15 */ \ |
105 |
|
"SRX", "SR0", "SR1", "SR2", /* 16 .. 19 */ \ |
106 |
|
"SR3", "CR21", "CR22", "CR23", /* 20 .. 23 */ \ |
107 |
|
"CR24", "ICMD", "ICTL", "ISAR", /* 24 .. 27 */ \ |
108 |
|
"ISAP", "IUAP", "IIR", "IBP", /* 28 .. 31 */ \ |
109 |
|
"IPPU", "IPPL", "ISR", "ILAR", /* 32 .. 35 */ \ |
110 |
|
"IPAR", "CR37", "CR38", "CR39", /* 36 .. 39 */ \ |
111 |
|
"DCMD", "DCTL", "DSAR", "DSAP", /* 40 .. 43 */ \ |
112 |
|
"DUAP", "DIR", "DBP", "DPPU", /* 44 .. 47 */ \ |
113 |
|
"DPPL", "DSR", "DLAR", "DPAR", /* 48 .. 51 */ \ |
114 |
|
"CR52", "CR53", "CR54", "CR55", /* 52 .. 55 */ \ |
115 |
|
"CR56", "CR57", "CR58", "CR59", /* 56 .. 59 */ \ |
116 |
|
"CR60", "CR61", "CR62", "CR63" /* 60 .. 63 */ } |
117 |
|
|
118 |
|
#define M88K_CR_EXIP 4 |
119 |
|
#define M88K_CR_ENIP 5 |
120 |
|
#define M88K_CR_SRX 16 |
121 |
|
#define M88K_CR_ICMD 25 |
122 |
|
#define M88K_CR_ICTL 26 |
123 |
|
#define M88K_CR_ISAR 27 |
124 |
|
#define M88K_CR_ISAP 28 |
125 |
|
#define M88K_CR_IUAP 29 |
126 |
|
#define M88K_CR_IIR 30 |
127 |
|
#define M88K_CR_IBP 31 |
128 |
|
#define M88K_CR_IPPU 32 |
129 |
|
#define M88K_CR_IPPL 33 |
130 |
|
#define M88K_CR_ISR 34 |
131 |
|
#define M88K_CR_ILAR 35 |
132 |
|
#define M88K_CR_IPAR 36 |
133 |
|
#define M88K_CR_DCMD 40 |
134 |
|
#define M88K_CR_DCTL 41 |
135 |
|
#define M88K_CR_DSAR 42 |
136 |
|
#define M88K_CR_DSAP 43 |
137 |
|
#define M88K_CR_DUAP 44 |
138 |
|
#define M88K_CR_DIR 45 |
139 |
|
#define M88K_CR_DBP 46 |
140 |
|
#define M88K_CR_DPPU 47 |
141 |
|
#define M88K_CR_DPPL 48 |
142 |
|
#define M88K_CR_DSR 49 |
143 |
|
#define M88K_CR_DLAR 50 |
144 |
|
#define M88K_CR_DPAR 51 |
145 |
|
|
146 |
|
#define N_M88K_FPU_CONTROL_REGS 64 |
147 |
|
|
148 |
|
|
149 |
#define M88K_N_IC_ARGS 3 |
#define M88K_N_IC_ARGS 3 |
150 |
#define M88K_INSTR_ALIGNMENT_SHIFT 2 |
#define M88K_INSTR_ALIGNMENT_SHIFT 2 |
162 |
|
|
163 |
#define N_M88K_REGS 32 |
#define N_M88K_REGS 32 |
164 |
|
|
165 |
/* Register r0 is always zero. */ |
/* Register r0 is always zero, r1 is the return address on function calls. */ |
166 |
#define M88K_ZERO_REG 0 |
#define M88K_ZERO_REG 0 |
167 |
|
#define M88K_RETURN_REG 1 |
168 |
|
|
169 |
|
#define M88K_CMP_HS 0x00000800 |
170 |
|
#define M88K_CMP_LO 0x00000400 |
171 |
|
#define M88K_CMP_LS 0x00000200 |
172 |
|
#define M88K_CMP_HI 0x00000100 |
173 |
|
#define M88K_CMP_GE 0x00000080 |
174 |
|
#define M88K_CMP_LT 0x00000040 |
175 |
|
#define M88K_CMP_LE 0x00000020 |
176 |
|
#define M88K_CMP_GT 0x00000010 |
177 |
|
#define M88K_CMP_NE 0x00000008 |
178 |
|
#define M88K_CMP_EQ 0x00000004 |
179 |
|
|
180 |
|
/* Exception numbers: */ |
181 |
|
#define M88K_EXCEPTION_RESET 0 |
182 |
|
#define M88K_EXCEPTION_INTERRUPT 1 |
183 |
|
#define M88K_EXCEPTION_INSTRUCTION_ACCESS 2 |
184 |
|
#define M88K_EXCEPTION_DATA_ACCESS 3 |
185 |
|
#define M88K_EXCEPTION_MISALIGNED_ACCESS 4 |
186 |
|
#define M88K_EXCEPTION_UNIMPLEMENTED_OPCODE 5 |
187 |
|
#define M88K_EXCEPTION_PRIVILEGE_VIOLATION 6 |
188 |
|
#define M88K_EXCEPTION_BOUNDS_CHECK_VIOLATION 7 |
189 |
|
#define M88K_EXCEPTION_ILLEGAL_INTEGER_DIVIDE 8 |
190 |
|
#define M88K_EXCEPTION_INTEGER_OVERFLOW 9 |
191 |
|
#define M88K_EXCEPTION_ERROR 10 |
192 |
|
#define M88K_EXCEPTION_SFU1_PRECISE 114 |
193 |
|
#define M88K_EXCEPTION_SFU1_IMPRECISE 115 |
194 |
|
#define M88K_EXCEPTION_USER_TRAPS_START 128 |
195 |
|
|
196 |
|
/* A reserved/unimplemented instruction, used for PROM calls: */ |
197 |
|
#define M88K_PROM_INSTR 0xf400fc92 |
198 |
|
|
199 |
|
|
200 |
|
/* |
201 |
|
* M88200/88204 CMMU: |
202 |
|
*/ |
203 |
|
|
204 |
|
#define MAX_M8820X_CMMUS 8 |
205 |
|
#define M8820X_LENGTH 0x1000 |
206 |
|
#define N_M88200_BATC_REGS 10 |
207 |
|
#define N_M88200_PATC_ENTRIES 56 |
208 |
|
#define M8820X_PATC_SUPERVISOR_BIT 0x00000001 |
209 |
|
|
210 |
|
struct m8820x_cmmu { |
211 |
|
uint32_t reg[M8820X_LENGTH / sizeof(uint32_t)]; |
212 |
|
uint32_t batc[N_M88200_BATC_REGS]; |
213 |
|
uint32_t patc_v_and_control[N_M88200_PATC_ENTRIES]; |
214 |
|
uint32_t patc_p_and_supervisorbit[N_M88200_PATC_ENTRIES]; |
215 |
|
int patc_update_index; |
216 |
|
}; |
217 |
|
|
218 |
|
|
219 |
struct m88k_cpu { |
struct m88k_cpu { |
220 |
struct m88k_cpu_type_def cpu_type; |
struct m88k_cpu_type_def cpu_type; |
221 |
|
|
222 |
/* General-Purpose Registers: */ |
/* |
223 |
uint32_t r[N_M88K_REGS]; |
* General-Purpose Registers: |
224 |
|
* |
225 |
|
* 32 (N_M88K_REGS) registers, plus one which is always zero. (This |
226 |
|
* is to support st.d with d = r31. ld.d with d=r31 is converted to |
227 |
|
* just ld. TODO) |
228 |
|
*/ |
229 |
|
uint32_t r[N_M88K_REGS+1]; |
230 |
|
|
231 |
|
/* Destination scratch register for non-nop instructions with d=r0: */ |
232 |
|
uint32_t zero_scratch; |
233 |
|
|
234 |
/* Destination for non-nop instructions with r0 as dest. reg.: */ |
/* Control Registers: */ |
235 |
uint32_t zero; |
uint32_t cr[N_M88K_CONTROL_REGS]; |
236 |
|
|
237 |
|
/* Floating Point registers: */ |
238 |
|
uint32_t fcr[N_M88K_FPU_CONTROL_REGS]; |
239 |
|
|
240 |
|
/* Current interrupt assertion: */ |
241 |
int irq_asserted; |
int irq_asserted; |
242 |
|
|
243 |
|
/* CMMUs (Cache/Memory Management Units): */ |
244 |
|
struct m8820x_cmmu *cmmu[MAX_M8820X_CMMUS]; |
245 |
|
|
246 |
|
/* Current memory transaction fault registers: */ |
247 |
|
uint32_t dmt[2]; |
248 |
|
uint32_t dmd[2]; |
249 |
|
uint32_t dma[2]; |
250 |
|
|
251 |
|
/* Delayed-branch target (for exception handling): */ |
252 |
|
uint32_t delay_target; |
253 |
|
|
254 |
|
|
255 |
/* |
/* |
256 |
* Instruction translation cache, and 32-bit virtual -> physical -> |
* Instruction translation cache, internal TLB structure, and 32-bit |
257 |
* host address translation: |
* virtual -> physical -> host address translation arrays for both |
258 |
|
* normal access and for the special .usr access mode (available in |
259 |
|
* supervisor mode). |
260 |
*/ |
*/ |
261 |
DYNTRANS_ITC(m88k) |
DYNTRANS_ITC(m88k) |
262 |
VPH_TLBS(m88k,M88K) |
VPH_TLBS(m88k,M88K) |
263 |
VPH32(m88k,M88K,uint32_t,uint8_t) |
VPH32(m88k,M88K) |
264 |
|
VPH32EXTENDED(m88k,M88K,usr) |
265 |
}; |
}; |
266 |
|
|
267 |
|
|
272 |
unsigned char *host_page, int writeflag, uint64_t paddr_page); |
unsigned char *host_page, int writeflag, uint64_t paddr_page); |
273 |
void m88k_invalidate_translation_caches(struct cpu *cpu, uint64_t, int); |
void m88k_invalidate_translation_caches(struct cpu *cpu, uint64_t, int); |
274 |
void m88k_invalidate_code_translation(struct cpu *cpu, uint64_t, int); |
void m88k_invalidate_code_translation(struct cpu *cpu, uint64_t, int); |
275 |
|
void m88k_timer_sample_tick(struct timer *, void *); |
276 |
int m88k_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, |
int m88k_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, |
277 |
unsigned char *data, size_t len, int writeflag, int cache_flags); |
unsigned char *data, size_t len, int writeflag, int cache_flags); |
278 |
int m88k_cpu_family_init(struct cpu_family *); |
int m88k_cpu_family_init(struct cpu_family *); |
279 |
|
void m88k_ldcr(struct cpu *cpu, uint32_t *r32ptr, int cr); |
280 |
|
void m88k_stcr(struct cpu *cpu, uint32_t value, int cr, int rte); |
281 |
|
void m88k_fstcr(struct cpu *cpu, uint32_t value, int fcr); |
282 |
|
void m88k_exception(struct cpu *cpu, int vector, int is_trap); |
283 |
|
|
284 |
|
/* memory_m88k.c: */ |
285 |
|
int m88k_translate_v2p(struct cpu *cpu, uint64_t vaddr, |
286 |
|
uint64_t *return_addr, int flags); |
287 |
|
|
288 |
|
|
289 |
#endif /* CPU_M88K_H */ |
#endif /* CPU_M88K_H */ |