1 |
dpavlin |
40 |
#ifndef CPU_M88K_H |
2 |
|
|
#define CPU_M88K_H |
3 |
|
|
|
4 |
|
|
/* |
5 |
|
|
* Copyright (C) 2007 Anders Gavare. All rights reserved. |
6 |
|
|
* |
7 |
|
|
* Redistribution and use in source and binary forms, with or without |
8 |
|
|
* modification, are permitted provided that the following conditions are met: |
9 |
|
|
* |
10 |
|
|
* 1. Redistributions of source code must retain the above copyright |
11 |
|
|
* notice, this list of conditions and the following disclaimer. |
12 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
13 |
|
|
* notice, this list of conditions and the following disclaimer in the |
14 |
|
|
* documentation and/or other materials provided with the distribution. |
15 |
|
|
* 3. The name of the author may not be used to endorse or promote products |
16 |
|
|
* derived from this software without specific prior written permission. |
17 |
|
|
* |
18 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
19 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
20 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
21 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
22 |
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
24 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
25 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
26 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
27 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
28 |
|
|
* SUCH DAMAGE. |
29 |
|
|
* |
30 |
|
|
* |
31 |
dpavlin |
42 |
* $Id: cpu_m88k.h,v 1.21 2007/06/07 15:36:24 debug Exp $ |
32 |
dpavlin |
40 |
*/ |
33 |
|
|
|
34 |
|
|
#include "misc.h" |
35 |
|
|
#include "interrupt.h" |
36 |
|
|
|
37 |
dpavlin |
42 |
#include "m88k_psl.h" |
38 |
|
|
|
39 |
dpavlin |
40 |
struct cpu_family; |
40 |
dpavlin |
42 |
struct timer; |
41 |
dpavlin |
40 |
|
42 |
|
|
/* M88K CPU types: */ |
43 |
|
|
struct m88k_cpu_type_def { |
44 |
|
|
char *name; |
45 |
|
|
int type; |
46 |
dpavlin |
42 |
uint32_t pid; |
47 |
dpavlin |
40 |
}; |
48 |
|
|
|
49 |
dpavlin |
42 |
#define M88K_PID(arn,vn) ((arn << M88K_ARN_SHIFT) | (vn << M88K_VN_SHIFT)) |
50 |
|
|
|
51 |
|
|
#define M88K_CPU_TYPE_DEFS { \ |
52 |
|
|
{ "88100", 88100, M88K_PID(M88K_ARN_88100,3) }, \ |
53 |
|
|
{ "88110", 88110, M88K_PID(M88K_ARN_88110,0) }, \ |
54 |
|
|
{ NULL, 0, 0 } \ |
55 |
dpavlin |
40 |
} |
56 |
|
|
|
57 |
dpavlin |
42 |
/* 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 |
dpavlin |
40 |
|
77 |
dpavlin |
42 |
#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 |
dpavlin |
40 |
#define M88K_N_IC_ARGS 3 |
150 |
|
|
#define M88K_INSTR_ALIGNMENT_SHIFT 2 |
151 |
|
|
#define M88K_IC_ENTRIES_SHIFT 10 |
152 |
|
|
#define M88K_IC_ENTRIES_PER_PAGE (1 << M88K_IC_ENTRIES_SHIFT) |
153 |
|
|
#define M88K_PC_TO_IC_ENTRY(a) (((a)>>M88K_INSTR_ALIGNMENT_SHIFT) \ |
154 |
|
|
& (M88K_IC_ENTRIES_PER_PAGE-1)) |
155 |
|
|
#define M88K_ADDR_TO_PAGENR(a) ((a) >> (M88K_IC_ENTRIES_SHIFT \ |
156 |
|
|
+ M88K_INSTR_ALIGNMENT_SHIFT)) |
157 |
|
|
|
158 |
|
|
DYNTRANS_MISC_DECLARATIONS(m88k,M88K,uint32_t) |
159 |
|
|
|
160 |
|
|
#define M88K_MAX_VPH_TLB_ENTRIES 128 |
161 |
|
|
|
162 |
|
|
|
163 |
|
|
#define N_M88K_REGS 32 |
164 |
|
|
|
165 |
dpavlin |
42 |
/* Register r0 is always zero, r1 is the return address on function calls. */ |
166 |
dpavlin |
40 |
#define M88K_ZERO_REG 0 |
167 |
dpavlin |
42 |
#define M88K_RETURN_REG 1 |
168 |
dpavlin |
40 |
|
169 |
dpavlin |
42 |
#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 |
dpavlin |
40 |
struct m88k_cpu { |
220 |
|
|
struct m88k_cpu_type_def cpu_type; |
221 |
|
|
|
222 |
dpavlin |
42 |
/* |
223 |
|
|
* 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 |
dpavlin |
40 |
|
231 |
dpavlin |
42 |
/* Destination scratch register for non-nop instructions with d=r0: */ |
232 |
|
|
uint32_t zero_scratch; |
233 |
dpavlin |
40 |
|
234 |
dpavlin |
42 |
/* Control Registers: */ |
235 |
|
|
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 |
dpavlin |
40 |
int irq_asserted; |
242 |
|
|
|
243 |
dpavlin |
42 |
/* CMMUs (Cache/Memory Management Units): */ |
244 |
|
|
struct m8820x_cmmu *cmmu[MAX_M8820X_CMMUS]; |
245 |
dpavlin |
40 |
|
246 |
dpavlin |
42 |
/* 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 |
dpavlin |
40 |
/* |
256 |
dpavlin |
42 |
* Instruction translation cache, internal TLB structure, and 32-bit |
257 |
|
|
* virtual -> physical -> host address translation arrays for both |
258 |
|
|
* normal access and for the special .usr access mode (available in |
259 |
|
|
* supervisor mode). |
260 |
dpavlin |
40 |
*/ |
261 |
|
|
DYNTRANS_ITC(m88k) |
262 |
|
|
VPH_TLBS(m88k,M88K) |
263 |
dpavlin |
42 |
VPH32(m88k,M88K) |
264 |
|
|
VPH32EXTENDED(m88k,M88K,usr) |
265 |
dpavlin |
40 |
}; |
266 |
|
|
|
267 |
|
|
|
268 |
|
|
/* cpu_m88k.c: */ |
269 |
|
|
int m88k_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib); |
270 |
|
|
int m88k_run_instr(struct cpu *cpu); |
271 |
|
|
void m88k_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, |
272 |
|
|
unsigned char *host_page, int writeflag, uint64_t paddr_page); |
273 |
|
|
void m88k_invalidate_translation_caches(struct cpu *cpu, uint64_t, int); |
274 |
|
|
void m88k_invalidate_code_translation(struct cpu *cpu, uint64_t, int); |
275 |
dpavlin |
42 |
void m88k_timer_sample_tick(struct timer *, void *); |
276 |
dpavlin |
40 |
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); |
278 |
|
|
int m88k_cpu_family_init(struct cpu_family *); |
279 |
dpavlin |
42 |
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 |
dpavlin |
40 |
|
284 |
dpavlin |
42 |
/* memory_m88k.c: */ |
285 |
|
|
int m88k_translate_v2p(struct cpu *cpu, uint64_t vaddr, |
286 |
|
|
uint64_t *return_addr, int flags); |
287 |
|
|
|
288 |
|
|
|
289 |
dpavlin |
40 |
#endif /* CPU_M88K_H */ |