/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Wed Sep 5 18:23:57 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 7431 byte(s)
various tweaks to make all tracers work again
1 dpavlin 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 dpavlin 7 uint32 ppc_cpu_get_lr(int cpu)
278     {
279     return gCPU.lr;
280     }
281    
282 dpavlin 1 void ppc_cpu_map_framebuffer(uint32 pa, uint32 ea)
283     {
284     // use BAT for framebuffer
285     gCPU.dbatu[0] = ea|(7<<2)|0x3;
286     gCPU.dbat_bl17[0] = ~(BATU_BL(gCPU.dbatu[0])<<17);
287     gCPU.dbatl[0] = pa;
288     }
289    
290     void ppc_set_singlestep_v(bool v, const char *file, int line, const char *format, ...)
291     {
292     va_list arg;
293     va_start(arg, format);
294     ht_fprintf(stdout, "singlestep %s from %s:%d, info: ", v ? "set" : "cleared", file, line);
295     ht_vfprintf(stdout, format, arg);
296     ht_fprintf(stdout, "\n");
297     va_end(arg);
298     gSinglestep = v;
299     }
300    
301     void ppc_set_singlestep_nonverbose(bool v)
302     {
303     gSinglestep = v;
304     }
305    
306     #define CPU_KEY_PVR "cpu_pvr"
307    
308     #include "configparser.h"
309    
310     bool ppc_cpu_init()
311     {
312     memset(&gCPU, 0, sizeof gCPU);
313     gCPU.pvr = gConfig->getConfigInt(CPU_KEY_PVR);
314    
315     ppc_dec_init();
316     // initialize srs (mostly for prom)
317     for (int i=0; i<16; i++) {
318     gCPU.sr[i] = 0x2aa*i;
319     }
320     sys_create_mutex(&exception_mutex);
321    
322     PPC_CPU_WARN("You are using the generic CPU!\n");
323     PPC_CPU_WARN("This is much slower than the just-in-time compiler and\n");
324     PPC_CPU_WARN("should only be used for debugging purposes or if there's\n");
325     PPC_CPU_WARN("no just-in-time compiler for your platform.\n");
326    
327     return true;
328     }
329    
330     void ppc_cpu_init_config()
331     {
332     gConfig->acceptConfigEntryIntDef("cpu_pvr", 0x000c0201);
333     }

  ViewVC Help
Powered by ViewVC 1.1.26