-
Notifications
You must be signed in to change notification settings - Fork 1
/
CPU.h
173 lines (118 loc) · 4.91 KB
/
CPU.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#ifndef _CPU_H_
#define _CPU_H_
//#define ARM_V6 //define to allow v6 instructions
//#define THUMB_2 //define to allow Thumb2
#include "types.h"
struct ArmCpu;
#define ARM_SR_N 0x80000000UL
#define ARM_SR_Z 0x40000000UL
#define ARM_SR_C 0x20000000UL
#define ARM_SR_V 0x10000000UL
#define ARM_SR_Q 0x08000000UL
#ifdef ARM_V6 //V6KT2, but without T2 to be exact (we implement things like MLS, but not Thumb2 or ThumbEE)
#define ARM_SR_J 0x01000000UL
#define ARM_SR_E 0x00000200UL
#define ARM_SR_A 0x00000100UL
#define ARM_SR_GE_0 0x00010000UL
#define ARM_SR_GE_1 0x00020000UL
#define ARM_SR_GE_2 0x00040000UL
#define ARM_SR_GE_3 0x00080000UL
#define ARM_SR_GE_MASK 0x000F0000UL
#define ARM_SR_GE_SHIFT 16
#endif
#define ARM_SR_I 0x00000080UL
#define ARM_SR_F 0x00000040UL
#define ARM_SR_T 0x00000020UL
#define ARM_SR_M 0x0000001FUL
#define ARM_SR_MODE_USR 0x00000010UL
#define ARM_SR_MODE_FIQ 0x00000011UL
#define ARM_SR_MODE_IRQ 0x00000012UL
#define ARM_SR_MODE_SVC 0x00000013UL
#define ARM_SR_MODE_ABT 0x00000017UL
#define ARM_SR_MODE_UND 0x0000001BUL
#define ARM_SR_MODE_SYS 0x0000001FUL
#define ARV_VECTOR_OFFT_RST 0x00000000UL
#define ARM_VECTOR_OFFT_UND 0x00000004UL
#define ARM_VECTOR_OFFT_SWI 0x00000008UL
#define ARM_VECTOR_OFFT_P_ABT 0x0000000CUL
#define ARM_VECTOR_OFFT_D_ABT 0x00000010UL
#define ARM_VECTOR_OFFT_UNUSED 0x00000014UL
#define ARM_VECTOR_OFFT_IRQ 0x00000018UL
#define ARM_VECTOR_OFFT_FIQ 0x0000001CUL
#define HYPERCALL_ARM 0xF7BBBBBBUL
#define HYPERCALL_THUMB 0xBBBBUL
//the following are for cpuGetRegExternal() and are generally used for debugging purposes
#define ARM_REG_NUM_CPSR 16
#define ARM_REG_NUM_SPSR 17
struct ArmCpu;
typedef Boolean (*ArmCoprocRegXferF) (struct ArmCpu* cpu, void* userData, Boolean two/* MCR2/MRC2 ? */, Boolean MRC, UInt8 op1, UInt8 Rx, UInt8 CRn, UInt8 CRm, UInt8 op2);
typedef Boolean (*ArmCoprocDatProcF) (struct ArmCpu* cpu, void* userData, Boolean two/* CDP2 ? */, UInt8 op1, UInt8 CRd, UInt8 CRn, UInt8 CRm, UInt8 op2);
typedef Boolean (*ArmCoprocMemAccsF) (struct ArmCpu* cpu, void* userData, Boolean two /* LDC2/STC2 ? */, Boolean N, Boolean store, UInt8 CRd, UInt32 addr, UInt8* option /* NULL if none */);
typedef Boolean (*ArmCoprocTwoRegF) (struct ArmCpu* cpu, void* userData, Boolean MRRC, UInt8 op, UInt8 Rd, UInt8 Rn, UInt8 CRm);
typedef Boolean (*ArmCpuMemF) (struct ArmCpu* cpu, void* buf, UInt32 vaddr, UInt8 size, Boolean write, Boolean priviledged, UInt8* fsr); //read/write
typedef Boolean (*ArmCpuHypercall) (struct ArmCpu* cpu); //return true if handled
typedef void (*ArmCpuEmulErr) (struct ArmCpu* cpu, const char* err_str);
typedef void (*ArmSetFaultAdrF) (struct ArmCpu* cpu, UInt32 adr, UInt8 faultStatus);
#include "icache.h"
/*
coprocessors:
0 - DSP (pxa only)
0, 1 - WMMX (pxa only)
11 - VFP (arm standard)
15 - system control (arm standard)
*/
typedef struct{
ArmCoprocRegXferF regXfer;
ArmCoprocDatProcF dataProcessing;
ArmCoprocMemAccsF memAccess;
ArmCoprocTwoRegF twoRegF;
void* userData;
}ArmCoprocessor;
typedef struct{
UInt32 R13, R14;
UInt32 SPSR; //usr mode doesn't have an SPSR
}ArmBankedRegs;
typedef struct ArmCpu{
UInt32 regs[16]; //current active regs as per current mode
UInt32 CPSR, SPSR;
ArmBankedRegs bank_usr; //usr regs when in another mode
ArmBankedRegs bank_svc; //svc regs when in another mode
ArmBankedRegs bank_abt; //abt regs when in another mode
ArmBankedRegs bank_und; //und regs when in another mode
ArmBankedRegs bank_irq; //irq regs when in another mode
ArmBankedRegs bank_fiq; //fiq regs when in another mode
UInt32 extra_regs[5]; //fiq regs when not in fiq mode, usr regs when in fiq mode. R8-12
UInt16 waitingIrqs;
UInt16 waitingFiqs;
UInt16 CPAR;
ArmCoprocessor coproc[16]; //coprocessors
// various other cpu config options
UInt32 vectorBase; //address of vector base
#ifdef ARM_V6
Boolean EEE; //endianness one exception entry
Boolean impreciseAbtWaiting;
#endif
ArmCpuMemF memF;
ArmCpuEmulErr emulErrF;
ArmCpuHypercall hypercallF;
ArmSetFaultAdrF setFaultAdrF;
icache ic;
void* userData; //shared by all callbacks
}ArmCpu;
Err cpuInit(ArmCpu* cpu, UInt32 pc, ArmCpuMemF memF, ArmCpuEmulErr emulErrF, ArmCpuHypercall hypercallF, ArmSetFaultAdrF setFaultAdrF);
Err cpuDeinit(ArmCpu* cp);
void cpuCycle(ArmCpu* cpu);
void cpuIrq(ArmCpu* cpu, Boolean fiq, Boolean raise); //unraise when acknowledged
#ifdef ARM_V6
void cpuSignalImpreciseAbt(ArmCpu* cpu, Boolean raise);
#endif
UInt32 cpuGetRegExternal(ArmCpu* cpu, UInt8 reg);
void cpuSetReg(ArmCpu* cpu, UInt8 reg, UInt32 val);
void cpuCoprocessorRegister(ArmCpu* cpu, UInt8 cpNum, ArmCoprocessor* coproc);
void cpuCoprocessorUnregister(ArmCpu* cpu, UInt8 cpNum);
void cpuSetVectorAddr(ArmCpu* cpu, UInt32 adr);
UInt16 cpuGetCPAR(ArmCpu* cpu);
void cpuSetCPAR(ArmCpu* cpu, UInt16 cpar);
void cpuIcacheInval(ArmCpu* cpu);
void cpuIcacheInvalAddr(ArmCpu* cpu, UInt32 addr);
#endif