include/mgba/internal/arm/arm.h (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef ARM_H
7#define ARM_H
8
9#include <mgba-util/common.h>
10
11CXX_GUARD_START
12
13#include <mgba/core/cpu.h>
14
15enum {
16 ARM_SP = 13,
17 ARM_LR = 14,
18 ARM_PC = 15
19};
20
21enum ExecutionMode {
22 MODE_ARM = 0,
23 MODE_THUMB = 1
24};
25
26enum PrivilegeMode {
27 MODE_USER = 0x10,
28 MODE_FIQ = 0x11,
29 MODE_IRQ = 0x12,
30 MODE_SUPERVISOR = 0x13,
31 MODE_ABORT = 0x17,
32 MODE_UNDEFINED = 0x1B,
33 MODE_SYSTEM = 0x1F
34};
35
36enum WordSize {
37 WORD_SIZE_ARM = 4,
38 WORD_SIZE_THUMB = 2
39};
40
41enum ExecutionVector {
42 BASE_RESET = 0x00000000,
43 BASE_UNDEF = 0x00000004,
44 BASE_SWI = 0x00000008,
45 BASE_PABT = 0x0000000C,
46 BASE_DABT = 0x00000010,
47 BASE_IRQ = 0x00000018,
48 BASE_FIQ = 0x0000001C
49};
50
51enum RegisterBank {
52 BANK_NONE = 0,
53 BANK_FIQ = 1,
54 BANK_IRQ = 2,
55 BANK_SUPERVISOR = 3,
56 BANK_ABORT = 4,
57 BANK_UNDEFINED = 5
58};
59
60enum LSMDirection {
61 LSM_B = 1,
62 LSM_D = 2,
63 LSM_IA = 0,
64 LSM_IB = 1,
65 LSM_DA = 2,
66 LSM_DB = 3
67};
68
69struct ARMCore;
70
71union PSR {
72 struct {
73#ifdef __BIG_ENDIAN__
74 unsigned n : 1;
75 unsigned z : 1;
76 unsigned c : 1;
77 unsigned v : 1;
78 unsigned q : 1;
79 unsigned unused : 19;
80 unsigned i : 1;
81 unsigned f : 1;
82 unsigned t : 1;
83 unsigned priv : 5;
84#else
85 unsigned priv : 5;
86 unsigned t : 1;
87 unsigned f : 1;
88 unsigned i : 1;
89 unsigned unused : 19;
90 unsigned q : 1;
91 unsigned v : 1;
92 unsigned c : 1;
93 unsigned z : 1;
94 unsigned n : 1;
95#endif
96 };
97
98 struct {
99#ifdef __BIG_ENDIAN__
100 uint8_t flags;
101 uint8_t status;
102 uint8_t extension;
103 uint8_t control;
104#else
105 uint8_t control;
106 uint8_t extension;
107 uint8_t status;
108 uint8_t flags;
109#endif
110 };
111
112 int32_t packed;
113};
114
115struct ARMMemory {
116 uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
117 uint32_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter);
118 uint32_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter);
119
120 void (*store32)(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
121 void (*store16)(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
122 void (*store8)(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
123
124 uint32_t (*loadMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
125 int* cycleCounter);
126 uint32_t (*storeMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
127 int* cycleCounter);
128
129 const uint32_t* activeRegion;
130 uint32_t activeMask;
131 uint32_t activeSeqCycles32;
132 uint32_t activeSeqCycles16;
133 uint32_t activeNonseqCycles32;
134 uint32_t activeNonseqCycles16;
135 int32_t (*stall)(struct ARMCore*, int32_t wait);
136 void (*setActiveRegion)(struct ARMCore*, uint32_t address);
137};
138
139struct ARMInterruptHandler {
140 void (*reset)(struct ARMCore* cpu);
141 void (*processEvents)(struct ARMCore* cpu);
142 void (*swi16)(struct ARMCore* cpu, int immediate);
143 void (*swi32)(struct ARMCore* cpu, int immediate);
144 void (*hitIllegal)(struct ARMCore* cpu, uint32_t opcode);
145 void (*bkpt16)(struct ARMCore* cpu, int immediate);
146 void (*bkpt32)(struct ARMCore* cpu, int immediate);
147 void (*readCPSR)(struct ARMCore* cpu);
148 void (*writeCP15)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2, uint32_t value);
149 uint32_t (*readCP15)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2);
150
151 void (*hitStub)(struct ARMCore* cpu, uint32_t opcode);
152};
153
154DECL_BITFIELD(ARMCPUID, uint32_t);
155DECL_BITFIELD(ARMCacheType, uint32_t);
156DECL_BITFIELD(ARMTCMType, uint32_t);
157DECL_BITFIELD(ARMTLBType, uint32_t);
158DECL_BITFIELD(ARMMPUType, uint32_t);
159
160DECL_BITFIELD(ARMControlReg, uint32_t);
161DECL_BIT(ARMControlReg, M, 0);
162DECL_BIT(ARMControlReg, A, 1);
163DECL_BIT(ARMControlReg, C, 2);
164DECL_BIT(ARMControlReg, W, 3);
165DECL_BIT(ARMControlReg, P, 4);
166DECL_BIT(ARMControlReg, D, 5);
167DECL_BIT(ARMControlReg, L, 6);
168DECL_BIT(ARMControlReg, B, 7);
169DECL_BIT(ARMControlReg, S, 8);
170DECL_BIT(ARMControlReg, R, 9);
171DECL_BIT(ARMControlReg, F, 10);
172DECL_BIT(ARMControlReg, Z, 11);
173DECL_BIT(ARMControlReg, I, 12);
174DECL_BIT(ARMControlReg, V, 13);
175DECL_BIT(ARMControlReg, RR, 14);
176DECL_BIT(ARMControlReg, L4, 15);
177DECL_BIT(ARMControlReg, FI, 21);
178DECL_BIT(ARMControlReg, U, 22);
179DECL_BIT(ARMControlReg, XP, 23);
180DECL_BIT(ARMControlReg, VE, 24);
181DECL_BIT(ARMControlReg, EE, 25);
182DECL_BIT(ARMControlReg, L2, 26);
183
184DECL_BITFIELD(ARMCoprocessorAccess, uint32_t);
185
186DECL_BITFIELD(ARMCacheability, uint32_t);
187DECL_BIT(ARMCacheability, 0, 0);
188DECL_BIT(ARMCacheability, 1, 1);
189DECL_BIT(ARMCacheability, 2, 2);
190DECL_BIT(ARMCacheability, 3, 3);
191DECL_BIT(ARMCacheability, 4, 4);
192DECL_BIT(ARMCacheability, 5, 5);
193DECL_BIT(ARMCacheability, 6, 6);
194DECL_BIT(ARMCacheability, 7, 7);
195
196DECL_BITFIELD(ARMProtection, uint32_t);
197DECL_BIT(ARMProtection, Enable, 0);
198DECL_BITS(ARMProtection, Size, 1, 5);
199DECL_BITS(ARMProtection, Base, 12, 20);
200
201DECL_BITFIELD(ARMTCMControl, uint32_t);
202DECL_BITS(ARMTCMControl, VirtualSize, 1, 5);
203DECL_BITS(ARMTCMControl, Base, 12, 20);
204
205struct ARMCP15 {
206 struct {
207 ARMCPUID cpuid;
208 ARMCacheType cachetype;
209 ARMTCMType tcmtype;
210 ARMTLBType tlbtype;
211 ARMMPUType mputype;
212 } r0;
213 struct {
214 ARMControlReg c0;
215 uint32_t c1;
216 ARMCoprocessorAccess cpAccess;
217 } r1;
218 struct {
219 ARMCacheability d;
220 ARMCacheability i;
221 } r2;
222 struct {
223 ARMCacheability d;
224 } r3;
225 struct {
226 ARMProtection region[8];
227 } r6;
228 struct {
229 ARMTCMControl d;
230 ARMTCMControl i;
231 } r9;
232};
233
234#define ARM_REGISTER_FILE struct { \
235 int32_t gprs[16]; \
236 union PSR cpsr; \
237 union PSR spsr; \
238}
239
240struct ARMRegisterFile {
241 ARM_REGISTER_FILE;
242};
243
244struct ARMCore {
245 union {
246 struct ARMRegisterFile regs;
247 ARM_REGISTER_FILE;
248 };
249
250 int32_t cycles;
251 int32_t nextEvent;
252 int halted;
253
254 int32_t bankedRegisters[6][7];
255 int32_t bankedSPSRs[6];
256
257 int32_t shifterOperand;
258 int32_t shifterCarryOut;
259
260 uint32_t prefetch[2];
261 enum ExecutionMode executionMode;
262 enum PrivilegeMode privilegeMode;
263
264 struct ARMMemory memory;
265 struct ARMInterruptHandler irqh;
266 struct ARMCP15 cp15;
267
268 struct mCPUComponent* master;
269
270 size_t numComponents;
271 struct mCPUComponent** components;
272};
273#undef ARM_REGISTER_FILE
274
275void ARMInit(struct ARMCore* cpu);
276void ARMDeinit(struct ARMCore* cpu);
277void ARMSetComponents(struct ARMCore* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
278void ARMHotplugAttach(struct ARMCore* cpu, size_t slot);
279void ARMHotplugDetach(struct ARMCore* cpu, size_t slot);
280
281void ARMReset(struct ARMCore* cpu);
282void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode);
283void ARMRaiseIRQ(struct ARMCore*);
284void ARMRaiseSWI(struct ARMCore*);
285void ARMRaiseUndefined(struct ARMCore*);
286void ARMHalt(struct ARMCore*);
287
288void ARMv4Run(struct ARMCore* cpu);
289void ARMv4RunLoop(struct ARMCore* cpu);
290void ARMv5Run(struct ARMCore* cpu);
291void ARMv5RunLoop(struct ARMCore* cpu);
292void ARMRunFake(struct ARMCore* cpu, uint32_t opcode);
293
294CXX_GUARD_END
295
296#endif