2961
|
1 /* Copyright (C) 2006 yopyop
|
|
2 yopyop156@ifrance.com
|
|
3 yopyop156.ifrance.com
|
|
4
|
|
5 This file is part of DeSmuME
|
|
6
|
|
7 DeSmuME is free software; you can redistribute it and/or modify
|
|
8 it under the terms of the GNU General Public License as published by
|
|
9 the Free Software Foundation; either version 2 of the License, or
|
|
10 (at your option) any later version.
|
|
11
|
|
12 DeSmuME 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
|
|
15 GNU General Public License for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with DeSmuME; if not, write to the Free Software
|
|
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
20 */
|
|
21
|
|
22 #ifndef ARM_CPU
|
|
23 #define ARM_CPU
|
|
24
|
|
25 #include "types.h"
|
|
26 #include "bits.h"
|
|
27 #include "MMU.h"
|
|
28
|
|
29 #ifdef __cplusplus
|
|
30 extern "C" {
|
|
31 #endif
|
|
32
|
|
33 #define ARMCPU_ARM7 1
|
|
34 #define ARMCPU_ARM9 0
|
|
35
|
|
36 #define CODE(i) (((i)>>25)&0X7)
|
|
37 #define OPCODE(i) (((i)>>21)&0xF)
|
|
38 #define SIGNEBIT(i) BIT_N(i,20)
|
|
39
|
|
40 #define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF))
|
|
41
|
|
42 #define ROR(i, j) ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j))))
|
|
43
|
|
44 #define UNSIGNED_OVERFLOW(a,b,c) ((BIT31(a)&BIT31(b)) | \
|
|
45 ((BIT31(a)|BIT31(b))&BIT31(~c)))
|
|
46
|
|
47 #define UNSIGNED_UNDERFLOW(a,b,c) ((BIT31(~a)&BIT31(b)) | \
|
|
48 ((BIT31(~a)|BIT31(b))&BIT31(c)))
|
|
49
|
|
50 #define SIGNED_OVERFLOW(a,b,c) ((BIT31(a)&BIT31(b)&BIT31(~c))|\
|
|
51 (BIT31(~a)&BIT31(~(b))&BIT31(c)))
|
|
52
|
|
53 #define SIGNED_UNDERFLOW(a,b,c) ((BIT31(a)&BIT31(~(b))&BIT31(~c))|\
|
|
54 (BIT31(~a)&BIT31(b)&BIT31(c)))
|
|
55
|
|
56 #define EQ 0x0
|
|
57 #define NE 0x1
|
|
58 #define CS 0x2
|
|
59 #define CC 0x3
|
|
60 #define MI 0x4
|
|
61 #define PL 0x5
|
|
62 #define VS 0x6
|
|
63 #define VC 0x7
|
|
64 #define HI 0x8
|
|
65 #define LS 0x9
|
|
66 #define GE 0xA
|
|
67 #define LT 0xB
|
|
68 #define GT 0xC
|
|
69 #define LE 0xD
|
|
70 #define AL 0xE
|
|
71
|
|
72 /*
|
|
73 #define TEST_COND(cond, CPSR) (((cond)==AL) ||\
|
|
74 (((cond)==EQ) && ( CPSR.bits.Z))||\
|
|
75 (((cond)==NE) && (!CPSR.bits.Z))||\
|
|
76 (((cond)==CS) && ( CPSR.bits.C))||\
|
|
77 (((cond)==CC) && (!CPSR.bits.C))||\
|
|
78 (((cond)==MI) && ( CPSR.bits.N))||\
|
|
79 (((cond)==PL) && (!CPSR.bits.N))||\
|
|
80 (((cond)==VS) && ( CPSR.bits.V))||\
|
|
81 (((cond)==VC) && (!CPSR.bits.V))||\
|
|
82 (((cond)==HI) && (CPSR.bits.C) && (!CPSR.bits.Z))||\
|
|
83 (((cond)==LS) && ((CPSR.bits.Z) || (!CPSR.bits.C)))||\
|
|
84 (((cond)==GE) && (CPSR.bits.N==CPSR.bits.V))||\
|
|
85 (((cond)==LT) && (CPSR.bits.N!=CPSR.bits.V))||\
|
|
86 (((cond)==GT) && (CPSR.bits.Z==0) && (CPSR.bits.N==CPSR.bits.V))||\
|
|
87 (((cond)==LE) && ((CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V))))
|
|
88 */
|
|
89
|
|
90 extern const unsigned char arm_cond_table[16*16];
|
|
91
|
|
92 #define TEST_COND(cond, inst, CPSR) ((arm_cond_table[((CPSR.val >> 24) & 0xf0)+(cond)] >> (inst)) & 1)
|
|
93
|
|
94
|
|
95 enum Mode
|
|
96 {
|
|
97 USR = 0x10,
|
|
98 FIQ = 0x11,
|
|
99 IRQ = 0x12,
|
|
100 SVC = 0x13,
|
|
101 ABT = 0x17,
|
|
102 UND = 0x1B,
|
|
103 SYS = 0x1F
|
|
104 };
|
|
105
|
|
106 #ifdef WORDS_BIGENDIAN
|
|
107 typedef union
|
|
108 {
|
|
109 struct
|
|
110 {
|
|
111 u32 N : 1,
|
|
112 Z : 1,
|
|
113 C : 1,
|
|
114 V : 1,
|
|
115 Q : 1,
|
|
116 RAZ : 19,
|
|
117 I : 1,
|
|
118 F : 1,
|
|
119 T : 1,
|
|
120 mode : 5;
|
|
121 } bits;
|
|
122 u32 val;
|
|
123 } Status_Reg;
|
|
124 #else
|
|
125 typedef union
|
|
126 {
|
|
127 struct
|
|
128 {
|
|
129 u32 mode : 5,
|
|
130 T : 1,
|
|
131 F : 1,
|
|
132 I : 1,
|
|
133 RAZ : 19,
|
|
134 Q : 1,
|
|
135 V : 1,
|
|
136 C : 1,
|
|
137 Z : 1,
|
|
138 N : 1;
|
|
139 } bits;
|
|
140 u32 val;
|
|
141 } Status_Reg;
|
|
142 #endif
|
|
143
|
|
144 /**
|
|
145 * The control interface to a CPU
|
|
146 */
|
|
147 struct armcpu_ctrl_iface {
|
|
148 /** stall the processor */
|
|
149 void (*stall)( void *instance);
|
|
150
|
|
151 /** unstall the processor */
|
|
152 void (*unstall)( void *instance);
|
|
153
|
|
154 /** read a register value */
|
|
155 u32 (*read_reg)( void *instance, u32 reg_num);
|
|
156
|
|
157 /** set a register value */
|
|
158 void (*set_reg)( void *instance, u32 reg_num, u32 value);
|
|
159
|
|
160 /** install the post execute function */
|
|
161 void (*install_post_ex_fn)( void *instance,
|
|
162 void (*fn)( void *, u32 adr, int thumb),
|
|
163 void *fn_data);
|
|
164
|
|
165 /** remove the post execute function */
|
|
166 void (*remove_post_ex_fn)( void *instance);
|
|
167
|
|
168 /** the private data passed to all interface functions */
|
|
169 void *data;
|
|
170 };
|
|
171
|
|
172
|
|
173 typedef void* armcp_t;
|
|
174
|
|
175 typedef struct armcpu_t
|
|
176 {
|
|
177 u32 proc_ID;
|
|
178 u32 instruction; //4
|
|
179 u32 instruct_adr; //8
|
|
180 u32 next_instruction; //12
|
|
181
|
|
182 u32 R[16]; //16
|
|
183 Status_Reg CPSR; //80
|
|
184 Status_Reg SPSR;
|
|
185
|
|
186 u32 R13_usr, R14_usr;
|
|
187 u32 R13_svc, R14_svc;
|
|
188 u32 R13_abt, R14_abt;
|
|
189 u32 R13_und, R14_und;
|
|
190 u32 R13_irq, R14_irq;
|
|
191 u32 R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq;
|
|
192 Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq;
|
|
193
|
|
194 armcp_t *coproc[16];
|
|
195
|
|
196 u32 intVector;
|
|
197 u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5
|
|
198 BOOL waitIRQ;
|
|
199 BOOL wIRQ;
|
|
200 BOOL wirq;
|
|
201
|
|
202 u32 (* *swi_tab)(struct armcpu_t * cpu);
|
|
203
|
|
204 #ifdef GDB_STUB
|
|
205 /** there is a pending irq for the cpu */
|
|
206 int irq_flag;
|
|
207
|
|
208 /** the post executed function (if installed) */
|
|
209 void (*post_ex_fn)( void *, u32 adr, int thumb);
|
|
210
|
|
211 /** data for the post executed function */
|
|
212 void *post_ex_fn_data;
|
|
213
|
|
214
|
|
215 /** flag indicating if the processor is stalled */
|
|
216 int stalled;
|
|
217
|
|
218 /** the memory interface */
|
|
219 struct armcpu_memory_iface *mem_if;
|
|
220
|
|
221 /** the ctrl interface */
|
|
222 struct armcpu_ctrl_iface ctrl_iface;
|
|
223 #endif
|
|
224 } armcpu_t;
|
|
225
|
|
226 #ifdef GDB_STUB
|
|
227 int armcpu_new( armcpu_t *armcpu, u32 id, struct armcpu_memory_iface *mem_if,
|
|
228 struct armcpu_ctrl_iface **ctrl_iface_ret);
|
|
229 #else
|
|
230 int armcpu_new( armcpu_t *armcpu, u32 id);
|
|
231 #endif
|
|
232 void armcpu_init(armcpu_t *armcpu, u32 adr);
|
|
233 u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode);
|
|
234 static u32 armcpu_prefetch(armcpu_t *armcpu);
|
|
235 u32 armcpu_exec(armcpu_t *armcpu);
|
|
236 BOOL armcpu_irqExeption(armcpu_t *armcpu);
|
|
237 //BOOL armcpu_prefetchExeption(armcpu_t *armcpu);
|
|
238 BOOL
|
|
239 armcpu_flagIrq( armcpu_t *armcpu);
|
|
240
|
|
241 extern armcpu_t NDS_ARM7;
|
|
242 extern armcpu_t NDS_ARM9;
|
|
243
|
|
244 static INLINE void NDS_makeARM9Int(u32 num)
|
|
245 {
|
|
246 /* flag the interrupt request source */
|
|
247 MMU.reg_IF[0] |= (1<<num);
|
|
248
|
|
249 /* generate the interrupt if enabled */
|
|
250 if ((MMU.reg_IE[0] & (1 << num)) && MMU.reg_IME[0])
|
|
251 {
|
|
252 NDS_ARM9.wIRQ = TRUE;
|
|
253 NDS_ARM9.waitIRQ = FALSE;
|
|
254 }
|
|
255 }
|
|
256
|
|
257 static INLINE void NDS_makeARM7Int(u32 num)
|
|
258 {
|
|
259 /* flag the interrupt request source */
|
|
260 MMU.reg_IF[1] |= (1<<num);
|
|
261
|
|
262 /* generate the interrupt if enabled */
|
|
263 if ((MMU.reg_IE[1] & (1 << num)) && MMU.reg_IME[1])
|
|
264 {
|
|
265 NDS_ARM7.wIRQ = TRUE;
|
|
266 NDS_ARM7.waitIRQ = FALSE;
|
|
267 }
|
|
268 }
|
|
269
|
|
270 static INLINE void NDS_makeInt(u8 proc_ID,u32 num)
|
|
271 {
|
|
272 switch (proc_ID)
|
|
273 {
|
|
274 case 0:
|
|
275 NDS_makeARM9Int(num) ;
|
|
276 break ;
|
|
277 case 1:
|
|
278 NDS_makeARM7Int(num) ;
|
|
279 break ;
|
|
280 }
|
|
281 }
|
|
282
|
|
283
|
|
284 #ifdef __cplusplus
|
|
285 }
|
|
286 #endif
|
|
287
|
|
288 #endif
|