/[pearpc]/src/cpu/cpu_generic/ppc_cpu.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/cpu/cpu_generic/ppc_cpu.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (12 years, 3 months ago) by dpavlin
File size: 7378 byte(s)
import upstream CVS
1 /*
2 * PearPC
3 * ppc_cpu.cc
4 *
5 * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6 * Portions Copyright (C) 2004 Apple Computer, Inc.
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 #include <cstring>
23 #include <cstdio>
24
25 #include "system/systhread.h"
26 #include "system/arch/sysendian.h"
27 #include "tools/snprintf.h"
28 #include "debug/tracers.h"
29 #include "cpu/cpu.h"
30 #include "cpu/debug.h"
31 #include "info.h"
32 #include "io/pic/pic.h"
33 #include "debug/debugger.h"
34 #include "debug/tracers.h"
35 #include "ppc_cpu.h"
36 #include "ppc_dec.h"
37 #include "ppc_fpu.h"
38 #include "ppc_exc.h"
39 #include "ppc_mmu.h"
40 #include "ppc_tools.h"
41
42 //#include "io/graphic/gcard.h"
43
44 PPC_CPU_State gCPU;
45 Debugger *gDebugger;
46
47 static bool gSinglestep = false;
48
49 //uint32 gBreakpoint2 = 0x11b3acf4;
50 uint32 gBreakpoint3 = 0xc016ee74&0;
51 uint32 gBreakpoint = 0x11b3acf4&0;
52 uint32 gBreakpoint2 = 0xc017a4f4&0;
53
54 bool activate = false;
55 static inline void ppc_debug_hook()
56 {
57 if (gCPU.pc == gBreakpoint) {
58 gSinglestep = true;
59 // SINGLESTEP("breakpoint 1");
60 }
61 if (gCPU.pc == gBreakpoint2) {
62 SINGLESTEP("breakpoint 2");
63 }
64 // if (gCPU.pc == gBreakpoint3 && gCPU.gpr[5]==0x100004ec) {
65 /* if (gCPU.pc == gBreakpoint3) {
66 activate = true;
67 SINGLESTEP("breakpoint 3");
68 }*/
69 if (gSinglestep) {
70 gDebugger->enter();
71 }
72 }
73
74 sys_mutex exception_mutex;
75
76 void ppc_cpu_atomic_raise_ext_exception()
77 {
78 sys_lock_mutex(exception_mutex);
79 gCPU.ext_exception = true;
80 gCPU.exception_pending = true;
81 sys_unlock_mutex(exception_mutex);
82 }
83
84 void ppc_cpu_atomic_cancel_ext_exception()
85 {
86 sys_lock_mutex(exception_mutex);
87 gCPU.ext_exception = false;
88 if (!gCPU.dec_exception) gCPU.exception_pending = false;
89 sys_unlock_mutex(exception_mutex);
90 }
91
92 void ppc_cpu_atomic_raise_dec_exception()
93 {
94 sys_lock_mutex(exception_mutex);
95 gCPU.dec_exception = true;
96 gCPU.exception_pending = true;
97 sys_unlock_mutex(exception_mutex);
98 }
99
100 void ppc_cpu_wakeup()
101 {
102 }
103
104 void ppc_cpu_run()
105 {
106 gDebugger = new Debugger();
107 gDebugger->mAlwaysShowRegs = true;
108 PPC_CPU_TRACE("execution started at %08x\n", gCPU.pc);
109 uint ops=0;
110 gCPU.effective_code_page = 0xffffffff;
111 // ppc_fpu_test();
112 // return;
113 while (true) {
114 gCPU.npc = gCPU.pc+4;
115 if ((gCPU.pc & ~0xfff) == gCPU.effective_code_page) {
116 gCPU.current_opc = ppc_word_from_BE(*((uint32*)(&gCPU.physical_code_page[gCPU.pc & 0xfff])));
117 ppc_debug_hook();
118 } else {
119 int ret;
120 if ((ret = ppc_direct_effective_memory_handle_code(gCPU.pc & ~0xfff, gCPU.physical_code_page))) {
121 if (ret == PPC_MMU_EXC) {
122 gCPU.pc = gCPU.npc;
123 continue;
124 } else {
125 PPC_CPU_ERR("?\n");
126 }
127 }
128 gCPU.effective_code_page = gCPU.pc & ~0xfff;
129 continue;
130 }
131 ppc_exec_opc();
132 ops++;
133 gCPU.ptb++;
134 if (gCPU.pdec == 0) {
135 gCPU.exception_pending = true;
136 gCPU.dec_exception = true;
137 gCPU.pdec=0xffffffff*TB_TO_PTB_FACTOR;
138 } else {
139 gCPU.pdec--;
140 }
141 if ((ops & 0x3ffff)==0) {
142 /* if (pic_check_interrupt()) {
143 gCPU.exception_pending = true;
144 gCPU.ext_exception = true;
145 }*/
146 if ((ops & 0x0fffff)==0) {
147 // uint32 j=0;
148 // ppc_read_effective_word(0xc046b2f8, j);
149
150 ht_printf("@%08x (%u ops) pdec: %08x lr: %08x\r", gCPU.pc, ops, gCPU.pdec, gCPU.lr);
151 #if 0
152 extern uint32 PIC_enable_low;
153 extern uint32 PIC_enable_high;
154 ht_printf("enable ");
155 int x = 1;
156 for (int i=0; i<31; i++) {
157 if (PIC_enable_low & x) {
158 ht_printf("%d ", i);
159 }
160 x<<=1;
161 }
162 x=1;
163 for (int i=0; i<31; i++) {
164 if (PIC_enable_high & x) {
165 ht_printf("%d ", 32+i);
166 }
167 x<<=1;
168 }
169 ht_printf("\n");
170 #endif
171 }
172 }
173
174 gCPU.pc = gCPU.npc;
175
176 if (gCPU.exception_pending) {
177 if (gCPU.stop_exception) {
178 gCPU.stop_exception = false;
179 if (!gCPU.dec_exception && !gCPU.ext_exception) gCPU.exception_pending = false;
180 break;
181 }
182 if (gCPU.msr & MSR_EE) {
183 sys_lock_mutex(exception_mutex);
184 if (gCPU.ext_exception) {
185 ppc_exception(PPC_EXC_EXT_INT);
186 gCPU.ext_exception = false;
187 gCPU.pc = gCPU.npc;
188 if (!gCPU.dec_exception) gCPU.exception_pending = false;
189 sys_unlock_mutex(exception_mutex);
190 continue;
191 }
192 if (gCPU.dec_exception) {
193 ppc_exception(PPC_EXC_DEC);
194 gCPU.dec_exception = false;
195 gCPU.pc = gCPU.npc;
196 gCPU.exception_pending = false;
197 sys_unlock_mutex(exception_mutex);
198 continue;
199 }
200 sys_unlock_mutex(exception_mutex);
201 PPC_CPU_ERR("no interrupt, but signaled?!\n");
202 }
203 }
204 #ifdef PPC_CPU_ENABLE_SINGLESTEP
205 if (gCPU.msr & MSR_SE) {
206 if (gCPU.singlestep_ignore) {
207 gCPU.singlestep_ignore = false;
208 } else {
209 ppc_exception(PPC_EXC_TRACE2);
210 gCPU.pc = gCPU.npc;
211 continue;
212 }
213 }
214 #endif
215 }
216 }
217
218 void ppc_cpu_stop()
219 {
220 sys_lock_mutex(exception_mutex);
221 gCPU.stop_exception = true;
222 gCPU.exception_pending = true;
223 sys_unlock_mutex(exception_mutex);
224 }
225
226 uint64 ppc_get_clock_frequency(int cpu)
227 {
228 return PPC_CLOCK_FREQUENCY;
229 }
230
231 uint64 ppc_get_bus_frequency(int cpu)
232 {
233 return PPC_BUS_FREQUENCY;
234 }
235
236 uint64 ppc_get_timebase_frequency(int cpu)
237 {
238 return PPC_TIMEBASE_FREQUENCY;
239 }
240
241
242 void ppc_machine_check_exception()
243 {
244 PPC_CPU_ERR("machine check exception\n");
245 }
246
247 uint32 ppc_cpu_get_gpr(int cpu, int i)
248 {
249 return gCPU.gpr[i];
250 }
251
252 void ppc_cpu_set_gpr(int cpu, int i, uint32 newvalue)
253 {
254 gCPU.gpr[i] = newvalue;
255 }
256
257 void ppc_cpu_set_msr(int cpu, uint32 newvalue)
258 {
259 gCPU.msr = newvalue;
260 }
261
262 void ppc_cpu_set_pc(int cpu, uint32 newvalue)
263 {
264 gCPU.pc = newvalue;
265 }
266
267 uint32 ppc_cpu_get_pc(int cpu)
268 {
269 return gCPU.pc;
270 }
271
272 uint32 ppc_cpu_get_pvr(int cpu)
273 {
274 return gCPU.pvr;
275 }
276
277 void ppc_cpu_map_framebuffer(uint32 pa, uint32 ea)
278 {
279 // use BAT for framebuffer
280 gCPU.dbatu[0] = ea|(7<<2)|0x3;
281 gCPU.dbat_bl17[0] = ~(BATU_BL(gCPU.dbatu[0])<<17);
282 gCPU.dbatl[0] = pa;
283 }
284
285 void ppc_set_singlestep_v(bool v, const char *file, int line, const char *format, ...)
286 {
287 va_list arg;
288 va_start(arg, format);
289 ht_fprintf(stdout, "singlestep %s from %s:%d, info: ", v ? "set" : "cleared", file, line);
290 ht_vfprintf(stdout, format, arg);
291 ht_fprintf(stdout, "\n");
292 va_end(arg);
293 gSinglestep = v;
294 }
295
296 void ppc_set_singlestep_nonverbose(bool v)
297 {
298 gSinglestep = v;
299 }
300
301 #define CPU_KEY_PVR "cpu_pvr"
302
303 #include "configparser.h"
304
305 bool ppc_cpu_init()
306 {
307 memset(&gCPU, 0, sizeof gCPU);
308 gCPU.pvr = gConfig->getConfigInt(CPU_KEY_PVR);
309
310 ppc_dec_init();
311 // initialize srs (mostly for prom)
312 for (int i=0; i<16; i++) {
313 gCPU.sr[i] = 0x2aa*i;
314 }
315 sys_create_mutex(&exception_mutex);
316
317 PPC_CPU_WARN("You are using the generic CPU!\n");
318 PPC_CPU_WARN("This is much slower than the just-in-time compiler and\n");
319 PPC_CPU_WARN("should only be used for debugging purposes or if there's\n");
320 PPC_CPU_WARN("no just-in-time compiler for your platform.\n");
321
322 return true;
323 }
324
325 void ppc_cpu_init_config()
326 {
327 gConfig->acceptConfigEntryIntDef("cpu_pvr", 0x000c0201);
328 }

  ViewVC Help
Powered by ViewVC 1.1.26