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 
11 CXX_GUARD_START
12 
13 #include <mgba/core/cpu.h>
14 
15 enum {
16 	ARM_SP = 13,
17 	ARM_LR = 14,
18 	ARM_PC = 15
19 };
20 
21 enum ExecutionMode {
22 	MODE_ARM = 0,
23 	MODE_THUMB = 1
24 };
25 
26 enum 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 
36 enum WordSize {
37 	WORD_SIZE_ARM = 4,
38 	WORD_SIZE_THUMB = 2
39 };
40 
41 enum 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 
51 enum 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 
60 enum 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 
69 struct ARMCore;
70 
71 union PSR {
72 	struct {
73 #if defined(__BIG_ENDIAN__)
74 		unsigned n : 1;
75 		unsigned z : 1;
76 		unsigned c : 1;
77 		unsigned v : 1;
78 		unsigned unused : 20;
79 		unsigned i : 1;
80 		unsigned f : 1;
81 		unsigned t : 1;
82 		unsigned priv : 5;
83 #else
84 		unsigned priv : 5;
85 		unsigned t : 1;
86 		unsigned f : 1;
87 		unsigned i : 1;
88 		unsigned unused : 20;
89 		unsigned v : 1;
90 		unsigned c : 1;
91 		unsigned z : 1;
92 		unsigned n : 1;
93 #endif
94 	};
95 
96 	struct {
97 #if defined(__BIG_ENDIAN__)
98 		uint8_t flags;
99 		uint8_t status;
100 		uint8_t extension;
101 		uint8_t control;
102 #else
103 		uint8_t control;
104 		uint8_t extension;
105 		uint8_t status;
106 		uint8_t flags;
107 #endif
108 	};
109 
110 	int32_t packed;
111 };
112 
113 struct ARMMemory {
114 	uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
115 	uint32_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter);
116 	uint32_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter);
117 
118 	void (*store32)(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
119 	void (*store16)(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
120 	void (*store8)(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
121 
122 	uint32_t (*loadMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
123 	                         int* cycleCounter);
124 	uint32_t (*storeMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
125 	                          int* cycleCounter);
126 
127 	const uint32_t* activeRegion;
128 	uint32_t activeMask;
129 	uint32_t activeSeqCycles32;
130 	uint32_t activeSeqCycles16;
131 	uint32_t activeNonseqCycles32;
132 	uint32_t activeNonseqCycles16;
133 	int32_t (*stall)(struct ARMCore*, int32_t wait);
134 	void (*setActiveRegion)(struct ARMCore*, uint32_t address);
135 };
136 
137 struct ARMInterruptHandler {
138 	void (*reset)(struct ARMCore* cpu);
139 	void (*processEvents)(struct ARMCore* cpu);
140 	void (*swi16)(struct ARMCore* cpu, int immediate);
141 	void (*swi32)(struct ARMCore* cpu, int immediate);
142 	void (*hitIllegal)(struct ARMCore* cpu, uint32_t opcode);
143 	void (*bkpt16)(struct ARMCore* cpu, int immediate);
144 	void (*bkpt32)(struct ARMCore* cpu, int immediate);
145 	void (*readCPSR)(struct ARMCore* cpu);
146 
147 	void (*hitStub)(struct ARMCore* cpu, uint32_t opcode);
148 };
149 
150 struct ARMCore {
151 	int32_t gprs[16];
152 	union PSR cpsr;
153 	union PSR spsr;
154 
155 	int32_t cycles;
156 	int32_t nextEvent;
157 	int halted;
158 
159 	int32_t bankedRegisters[6][7];
160 	int32_t bankedSPSRs[6];
161 
162 	int32_t shifterOperand;
163 	int32_t shifterCarryOut;
164 
165 	uint32_t prefetch[2];
166 	enum ExecutionMode executionMode;
167 	enum PrivilegeMode privilegeMode;
168 
169 	struct ARMMemory memory;
170 	struct ARMInterruptHandler irqh;
171 
172 	struct mCPUComponent* master;
173 
174 	size_t numComponents;
175 	struct mCPUComponent** components;
176 };
177 
178 void ARMInit(struct ARMCore* cpu);
179 void ARMDeinit(struct ARMCore* cpu);
180 void ARMSetComponents(struct ARMCore* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
181 void ARMHotplugAttach(struct ARMCore* cpu, size_t slot);
182 void ARMHotplugDetach(struct ARMCore* cpu, size_t slot);
183 
184 void ARMReset(struct ARMCore* cpu);
185 void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode);
186 void ARMRaiseIRQ(struct ARMCore*);
187 void ARMRaiseSWI(struct ARMCore*);
188 void ARMRaiseUndefined(struct ARMCore*);
189 
190 void ARMRun(struct ARMCore* cpu);
191 void ARMRunLoop(struct ARMCore* cpu);
192 void ARMRunFake(struct ARMCore* cpu, uint32_t opcode);
193 
194 CXX_GUARD_END
195 
196 #endif
197