|
1 /* |
|
2 * m68k virtual CPU header |
|
3 * |
|
4 * Copyright (c) 2005-2007 CodeSourcery |
|
5 * Written by Paul Brook |
|
6 * |
|
7 * This library is free software; you can redistribute it and/or |
|
8 * modify it under the terms of the GNU Lesser General Public |
|
9 * License as published by the Free Software Foundation; either |
|
10 * version 2 of the License, or (at your option) any later version. |
|
11 * |
|
12 * This library is distributed in the hope that it will be useful, |
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
15 * General Public License for more details. |
|
16 * |
|
17 * You should have received a copy of the GNU Lesser General Public |
|
18 * License along with this library; if not, write to the Free Software |
|
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
20 */ |
|
21 #ifndef CPU_M68K_H |
|
22 #define CPU_M68K_H |
|
23 |
|
24 #define TARGET_LONG_BITS 32 |
|
25 |
|
26 #include "cpu-defs.h" |
|
27 |
|
28 #include "softfloat.h" |
|
29 |
|
30 #define MAX_QREGS 32 |
|
31 |
|
32 #define TARGET_HAS_ICE 1 |
|
33 |
|
34 #define ELF_MACHINE EM_68K |
|
35 |
|
36 #define EXCP_ACCESS 2 /* Access (MMU) error. */ |
|
37 #define EXCP_ADDRESS 3 /* Address error. */ |
|
38 #define EXCP_ILLEGAL 4 /* Illegal instruction. */ |
|
39 #define EXCP_DIV0 5 /* Divide by zero */ |
|
40 #define EXCP_PRIVILEGE 8 /* Privilege violation. */ |
|
41 #define EXCP_TRACE 9 |
|
42 #define EXCP_LINEA 10 /* Unimplemented line-A (MAC) opcode. */ |
|
43 #define EXCP_LINEF 11 /* Unimplemented line-F (FPU) opcode. */ |
|
44 #define EXCP_DEBUGNBP 12 /* Non-breakpoint debug interrupt. */ |
|
45 #define EXCP_DEBEGBP 13 /* Breakpoint debug interrupt. */ |
|
46 #define EXCP_FORMAT 14 /* RTE format error. */ |
|
47 #define EXCP_UNINITIALIZED 15 |
|
48 #define EXCP_TRAP0 32 /* User trap #0. */ |
|
49 #define EXCP_TRAP15 47 /* User trap #15. */ |
|
50 #define EXCP_UNSUPPORTED 61 |
|
51 #define EXCP_ICE 13 |
|
52 |
|
53 #define EXCP_RTE 0x100 |
|
54 #define EXCP_HALT_INSN 0x101 |
|
55 |
|
56 #define NB_MMU_MODES 2 |
|
57 |
|
58 typedef struct CPUM68KState { |
|
59 uint32_t dregs[8]; |
|
60 uint32_t aregs[8]; |
|
61 uint32_t pc; |
|
62 uint32_t sr; |
|
63 |
|
64 /* SSP and USP. The current_sp is stored in aregs[7], the other here. */ |
|
65 int current_sp; |
|
66 uint32_t sp[2]; |
|
67 |
|
68 /* Condition flags. */ |
|
69 uint32_t cc_op; |
|
70 uint32_t cc_dest; |
|
71 uint32_t cc_src; |
|
72 uint32_t cc_x; |
|
73 |
|
74 float64 fregs[8]; |
|
75 float64 fp_result; |
|
76 uint32_t fpcr; |
|
77 uint32_t fpsr; |
|
78 float_status fp_status; |
|
79 |
|
80 uint64_t mactmp; |
|
81 /* EMAC Hardware deals with 48-bit values composed of one 32-bit and |
|
82 two 8-bit parts. We store a single 64-bit value and |
|
83 rearrange/extend this when changing modes. */ |
|
84 uint64_t macc[4]; |
|
85 uint32_t macsr; |
|
86 uint32_t mac_mask; |
|
87 |
|
88 /* Temporary storage for DIV helpers. */ |
|
89 uint32_t div1; |
|
90 uint32_t div2; |
|
91 |
|
92 /* MMU status. */ |
|
93 struct { |
|
94 uint32_t ar; |
|
95 } mmu; |
|
96 |
|
97 /* Control registers. */ |
|
98 uint32_t vbr; |
|
99 uint32_t mbar; |
|
100 uint32_t rambar0; |
|
101 uint32_t cacr; |
|
102 |
|
103 /* ??? remove this. */ |
|
104 uint32_t t1; |
|
105 |
|
106 int pending_vector; |
|
107 int pending_level; |
|
108 |
|
109 uint32_t qregs[MAX_QREGS]; |
|
110 |
|
111 CPU_COMMON |
|
112 |
|
113 uint32_t features; |
|
114 } CPUM68KState; |
|
115 |
|
116 void m68k_tcg_init(void); |
|
117 CPUM68KState *cpu_m68k_init(const char *cpu_model); |
|
118 int cpu_m68k_exec(CPUM68KState *s); |
|
119 void cpu_m68k_close(CPUM68KState *s); |
|
120 void do_interrupt(int is_hw); |
|
121 /* you can call this signal handler from your SIGBUS and SIGSEGV |
|
122 signal handlers to inform the virtual CPU of exceptions. non zero |
|
123 is returned if the signal was handled by the virtual CPU. */ |
|
124 int cpu_m68k_signal_handler(int host_signum, void *pinfo, |
|
125 void *puc); |
|
126 void cpu_m68k_flush_flags(CPUM68KState *, int); |
|
127 |
|
128 enum { |
|
129 CC_OP_DYNAMIC, /* Use env->cc_op */ |
|
130 CC_OP_FLAGS, /* CC_DEST = CVZN, CC_SRC = unused */ |
|
131 CC_OP_LOGIC, /* CC_DEST = result, CC_SRC = unused */ |
|
132 CC_OP_ADD, /* CC_DEST = result, CC_SRC = source */ |
|
133 CC_OP_SUB, /* CC_DEST = result, CC_SRC = source */ |
|
134 CC_OP_CMPB, /* CC_DEST = result, CC_SRC = source */ |
|
135 CC_OP_CMPW, /* CC_DEST = result, CC_SRC = source */ |
|
136 CC_OP_ADDX, /* CC_DEST = result, CC_SRC = source */ |
|
137 CC_OP_SUBX, /* CC_DEST = result, CC_SRC = source */ |
|
138 CC_OP_SHIFT, /* CC_DEST = result, CC_SRC = carry */ |
|
139 }; |
|
140 |
|
141 #define CCF_C 0x01 |
|
142 #define CCF_V 0x02 |
|
143 #define CCF_Z 0x04 |
|
144 #define CCF_N 0x08 |
|
145 #define CCF_X 0x10 |
|
146 |
|
147 #define SR_I_SHIFT 8 |
|
148 #define SR_I 0x0700 |
|
149 #define SR_M 0x1000 |
|
150 #define SR_S 0x2000 |
|
151 #define SR_T 0x8000 |
|
152 |
|
153 #define M68K_SSP 0 |
|
154 #define M68K_USP 1 |
|
155 |
|
156 /* CACR fields are implementation defined, but some bits are common. */ |
|
157 #define M68K_CACR_EUSP 0x10 |
|
158 |
|
159 #define MACSR_PAV0 0x100 |
|
160 #define MACSR_OMC 0x080 |
|
161 #define MACSR_SU 0x040 |
|
162 #define MACSR_FI 0x020 |
|
163 #define MACSR_RT 0x010 |
|
164 #define MACSR_N 0x008 |
|
165 #define MACSR_Z 0x004 |
|
166 #define MACSR_V 0x002 |
|
167 #define MACSR_EV 0x001 |
|
168 |
|
169 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector); |
|
170 void m68k_set_macsr(CPUM68KState *env, uint32_t val); |
|
171 void m68k_switch_sp(CPUM68KState *env); |
|
172 |
|
173 #define M68K_FPCR_PREC (1 << 6) |
|
174 |
|
175 void do_m68k_semihosting(CPUM68KState *env, int nr); |
|
176 |
|
177 /* There are 4 ColdFire core ISA revisions: A, A+, B and C. |
|
178 Each feature covers the subset of instructions common to the |
|
179 ISA revisions mentioned. */ |
|
180 |
|
181 enum m68k_features { |
|
182 M68K_FEATURE_CF_ISA_A, |
|
183 M68K_FEATURE_CF_ISA_B, /* (ISA B or C). */ |
|
184 M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C). */ |
|
185 M68K_FEATURE_BRAL, /* Long unconditional branch. (ISA A+ or B). */ |
|
186 M68K_FEATURE_CF_FPU, |
|
187 M68K_FEATURE_CF_MAC, |
|
188 M68K_FEATURE_CF_EMAC, |
|
189 M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate). */ |
|
190 M68K_FEATURE_USP, /* User Stack Pointer. (ISA A+, B or C). */ |
|
191 M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */ |
|
192 M68K_FEATURE_WORD_INDEX /* word sized address index registers. */ |
|
193 }; |
|
194 |
|
195 static inline int m68k_feature(CPUM68KState *env, int feature) |
|
196 { |
|
197 return (env->features & (1u << feature)) != 0; |
|
198 } |
|
199 |
|
200 void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
|
201 |
|
202 void register_m68k_insns (CPUM68KState *env); |
|
203 |
|
204 #ifdef CONFIG_USER_ONLY |
|
205 /* Linux uses 8k pages. */ |
|
206 #define TARGET_PAGE_BITS 13 |
|
207 #else |
|
208 /* Smallest TLB entry size is 1k. */ |
|
209 #define TARGET_PAGE_BITS 10 |
|
210 #endif |
|
211 |
|
212 #define CPUState CPUM68KState |
|
213 #define cpu_init cpu_m68k_init |
|
214 #define cpu_exec cpu_m68k_exec |
|
215 #define cpu_gen_code cpu_m68k_gen_code |
|
216 #define cpu_signal_handler cpu_m68k_signal_handler |
|
217 #define cpu_list m68k_cpu_list |
|
218 |
|
219 /* MMU modes definitions */ |
|
220 #define MMU_MODE0_SUFFIX _kernel |
|
221 #define MMU_MODE1_SUFFIX _user |
|
222 #define MMU_USER_IDX 1 |
|
223 static inline int cpu_mmu_index (CPUState *env) |
|
224 { |
|
225 return (env->sr & SR_S) == 0 ? 1 : 0; |
|
226 } |
|
227 |
|
228 #if defined(CONFIG_USER_ONLY) |
|
229 static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) |
|
230 { |
|
231 if (newsp) |
|
232 env->aregs[7] = newsp; |
|
233 env->dregs[0] = 0; |
|
234 } |
|
235 #endif |
|
236 |
|
237 #include "cpu-all.h" |
|
238 #include "exec-all.h" |
|
239 |
|
240 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
|
241 { |
|
242 env->pc = tb->pc; |
|
243 } |
|
244 |
|
245 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, |
|
246 target_ulong *cs_base, int *flags) |
|
247 { |
|
248 *pc = env->pc; |
|
249 *cs_base = 0; |
|
250 *flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */ |
|
251 | (env->sr & SR_S) /* Bit 13 */ |
|
252 | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ |
|
253 } |
|
254 |
|
255 #endif |