1 |
/* |
2 |
* PearPC |
3 |
* ppc_cpu.h |
4 |
* |
5 |
* Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net) |
6 |
* Copyright (C) 2004 Daniel Foesch (dfoesch@cs.nmsu.edu) |
7 |
* |
8 |
* This program is free software; you can redistribute it and/or modify |
9 |
* it under the terms of the GNU General Public License version 2 as |
10 |
* published by the Free Software Foundation. |
11 |
* |
12 |
* This program 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 this program; if not, write to the Free Software |
19 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 |
*/ |
21 |
|
22 |
#ifndef __PPC_CPU_H__ |
23 |
#define __PPC_CPU_H__ |
24 |
|
25 |
#include <stddef.h> |
26 |
#include "system/types.h" |
27 |
#include "cpu/common.h" |
28 |
|
29 |
#define PPC_MHz(v) ((v)*1000*1000) |
30 |
|
31 |
#define PPC_MODEL "ppc_model" |
32 |
#define PPC_CPU_MODEL "ppc_cpu" |
33 |
#define PPC_CLOCK_FREQUENCY PPC_MHz(200) |
34 |
#define PPC_BUS_FREQUENCY (PPC_CLOCK_FREQUENCY/5) |
35 |
#define PPC_TIMEBASE_FREQUENCY (PPC_BUS_FREQUENCY/4) |
36 |
|
37 |
struct PPC_CPU_State { |
38 |
// offsetof first entry of this structure must not be 0 |
39 |
uint32 dummy; |
40 |
|
41 |
// * uisa |
42 |
uint32 gpr[32]; |
43 |
uint64 fpr[32]; |
44 |
uint32 cr; |
45 |
uint32 fpscr; |
46 |
uint32 xer; // spr 1 |
47 |
uint32 xer_ca; // for jitc |
48 |
uint32 lr; // spr 8 |
49 |
uint32 ctr; // spr 9 |
50 |
// * oea |
51 |
uint32 msr; |
52 |
uint32 pvr; // spr 287 |
53 |
|
54 |
// * memory managment |
55 |
uint32 ibatu[4]; // spr 528, 530, 532, 534 |
56 |
uint32 ibatl[4]; // spr 529, 531, 533, 535 |
57 |
uint32 ibat_bl[4]; // internal |
58 |
uint32 ibat_nbl[4]; // internal |
59 |
uint32 ibat_bepi[4]; // internal |
60 |
uint32 ibat_brpn[4]; // internal |
61 |
|
62 |
uint32 dbatu[4]; // spr 536, 538, 540, 542 |
63 |
uint32 dbatl[4]; // spr 537, 539, 541, 543 |
64 |
uint32 dbat_bl[4]; // internal |
65 |
uint32 dbat_nbl[4]; // internal |
66 |
uint32 dbat_bepi[4]; // internal |
67 |
uint32 dbat_brpn[4]; // internal |
68 |
|
69 |
uint32 sdr1; // spr 25 (page table base address) |
70 |
|
71 |
uint32 sr[16]; |
72 |
|
73 |
// * exception handling |
74 |
uint32 dar; // spr 19 |
75 |
uint32 dsisr; // spr 18 |
76 |
uint32 sprg[4]; // spr 272-275 |
77 |
uint32 srr[2]; // spr 26-27 |
78 |
|
79 |
// * misc |
80 |
uint32 dec; // spr 22 |
81 |
uint32 ear; // spr 282 .101 |
82 |
uint32 pir; // spr 1032 |
83 |
uint64 tb; // .75 spr 284(l)/285(u) |
84 |
|
85 |
uint32 hid[16]; |
86 |
// * internal |
87 |
// this is used for speeding things up |
88 |
|
89 |
uint32 pc; |
90 |
uint32 npc; |
91 |
uint32 current_opc; |
92 |
bool exception_pending; |
93 |
bool dec_exception; |
94 |
bool ext_exception; |
95 |
bool stop_exception; |
96 |
bool singlestep_ignore; |
97 |
byte align[3]; |
98 |
|
99 |
uint32 pagetable_base; |
100 |
int pagetable_hashmask; |
101 |
uint32 reserve; |
102 |
bool have_reservation; |
103 |
byte align2[3]; |
104 |
|
105 |
uint32 tlb_last; |
106 |
uint32 tlb_pa[4]; |
107 |
uint32 tlb_va[4]; |
108 |
|
109 |
// for generic cpu core |
110 |
uint32 effective_code_page; |
111 |
byte *physical_code_page; |
112 |
uint64 pdec; // more precise version of dec |
113 |
uint64 ptb; // more precise version of tb |
114 |
|
115 |
// for jitc |
116 |
uint32 temp; |
117 |
uint32 temp2; |
118 |
uint32 x87cw; |
119 |
uint32 pc_ofs; |
120 |
uint32 current_code_base; |
121 |
|
122 |
// for altivec |
123 |
uint32 vscr; |
124 |
uint32 vrsave; // spr 256 |
125 |
uint32 vtemp; |
126 |
uint64 vtemp64; |
127 |
uint32 vfcw; // floating point control word store for vect unit |
128 |
uint32 vfcw_save; // floating point control word save |
129 |
Vector_t vr[36] ALIGN_STRUCT(16); // <-- this MUST be 16-byte aligned! |
130 |
} PACKED; |
131 |
|
132 |
enum PPC_Register { |
133 |
PPC_REG_NO = 0, |
134 |
PPC_GPR0 = offsetof(PPC_CPU_State, gpr), |
135 |
PPC_FPR1 = offsetof(PPC_CPU_State, fpr), |
136 |
PPC_VR = offsetof(PPC_CPU_State, vr), |
137 |
PPC_CR = offsetof(PPC_CPU_State, cr), |
138 |
PPC_FPSCR = offsetof(PPC_CPU_State, fpscr), |
139 |
PPC_VSCR = offsetof(PPC_CPU_State, vscr), |
140 |
PPC_VRSAVE = offsetof(PPC_CPU_State, vrsave), |
141 |
PPC_XER = offsetof(PPC_CPU_State, xer), |
142 |
PPC_LR = offsetof(PPC_CPU_State, lr), |
143 |
PPC_CTR = offsetof(PPC_CPU_State, ctr), |
144 |
PPC_MSR = offsetof(PPC_CPU_State, msr), |
145 |
PPC_SRR0 = offsetof(PPC_CPU_State, srr), |
146 |
PPC_SRR1 = offsetof(PPC_CPU_State, srr)+sizeof (uint32), |
147 |
PPC_DSISR = offsetof(PPC_CPU_State, dsisr), |
148 |
PPC_DAR = offsetof(PPC_CPU_State, dar), |
149 |
PPC_DEC = offsetof(PPC_CPU_State, dec), |
150 |
PPC_SDR1 = offsetof(PPC_CPU_State, sdr1), |
151 |
PPC_EAR = offsetof(PPC_CPU_State, ear), |
152 |
PPC_PVR = offsetof(PPC_CPU_State, pvr), |
153 |
PPC_HID0 = offsetof(PPC_CPU_State, hid), |
154 |
PPC_HID1 = offsetof(PPC_CPU_State, hid)+sizeof (uint32), |
155 |
}; |
156 |
|
157 |
enum PPC_CRx { |
158 |
PPC_CR0=0, |
159 |
PPC_CR1=1, |
160 |
PPC_CR2=2, |
161 |
PPC_CR3=3, |
162 |
PPC_CR4=4, |
163 |
PPC_CR5=5, |
164 |
PPC_CR6=6, |
165 |
PPC_CR7=7, |
166 |
|
167 |
PPC_NO_CRx=0xffffffff, |
168 |
}; |
169 |
|
170 |
#define PPC_GPR(n) ((PPC_Register)(offsetof(PPC_CPU_State, gpr)+(n)*sizeof (uint32))) |
171 |
#define PPC_FPR(n) ((PPC_Register)(offsetof(PPC_CPU_State, fpr)+(n)*sizeof (uint64))) |
172 |
#define PPC_FPR_U(n) ((PPC_Register)(offsetof(PPC_CPU_State, fpr)+4+(n)*sizeof (uint64))) |
173 |
#define PPC_FPR_L(n) ((PPC_Register)(offsetof(PPC_CPU_State, fpr)+(n)*sizeof (uint64))) |
174 |
#define PPC_VR(n) ((PPC_Register)((n)*sizeof (Vector_t))) |
175 |
#define PPC_VR_3(n) ((PPC_Register)(offsetof(PPC_CPU_State, vr)+12+(n)*sizeof (Vector_t))) |
176 |
#define PPC_VR_2(n) ((PPC_Register)(offsetof(PPC_CPU_State, vr)+8+(n)*sizeof (Vector_t))) |
177 |
#define PPC_VR_1(n) ((PPC_Register)(offsetof(PPC_CPU_State, vr)+4+(n)*sizeof (Vector_t))) |
178 |
#define PPC_VR_0(n) ((PPC_Register)(offsetof(PPC_CPU_State, vr)+(n)*sizeof (Vector_t))) |
179 |
#define PPC_SR(n) ((PPC_Register)(offsetof(PPC_CPU_State, sr)+(n)*sizeof (uint32))) |
180 |
#define PPC_SPRG(n) ((PPC_Register)(offsetof(PPC_CPU_State, sprg)+(n)*sizeof (uint32))) |
181 |
#define PPC_IBATU(n) ((PPC_Register)(offsetof(PPC_CPU_State, ibatu)+(n)*sizeof (uint32))) |
182 |
#define PPC_IBATL(n) ((PPC_Register)(offsetof(PPC_CPU_State, ibatl)+(n)*sizeof (uint32))) |
183 |
#define PPC_DBATU(n) ((PPC_Register)(offsetof(PPC_CPU_State, dbatu)+(n)*sizeof (uint32))) |
184 |
#define PPC_DBATL(n) ((PPC_Register)(offsetof(PPC_CPU_State, dbatl)+(n)*sizeof (uint32))) |
185 |
|
186 |
#include "system/systimer.h" |
187 |
|
188 |
extern PPC_CPU_State gCPU; |
189 |
extern uint64 gClientClockFrequency; |
190 |
extern uint64 gClientTimeBaseFrequency; |
191 |
extern sys_timer gDECtimer; |
192 |
|
193 |
uint64 ppc_get_cpu_timebase(); |
194 |
uint64 ppc_get_cpu_ideal_timebase(); |
195 |
|
196 |
void ppc_run(); |
197 |
void ppc_stop(); |
198 |
|
199 |
void ppc_set_singlestep_v(bool v, const char *file, int line, const char *infoformat, ...); |
200 |
void ppc_set_singlestep_nonverbose(bool v); |
201 |
|
202 |
extern "C" void ppc_cpu_atomic_raise_dec_exception(); |
203 |
extern "C" void ppc_cpu_atomic_raise_ext_exception(); |
204 |
extern "C" void ppc_cpu_atomic_cancel_ext_exception(); |
205 |
|
206 |
void cpu_wakeup(); |
207 |
|
208 |
bool cpu_init(); |
209 |
void cpu_init_config(); |
210 |
|
211 |
|
212 |
#define SINGLESTEP(info...) ppc_set_singlestep_v(true, __FILE__, __LINE__, info) |
213 |
extern uint32 gBreakpoint; |
214 |
extern uint32 gBreakpoint2; |
215 |
|
216 |
#endif |
217 |
|