/[gxemul]/upstream/0.3.3.1/src/cpu_hppa.c
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 /upstream/0.3.3.1/src/cpu_hppa.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Mon Oct 8 16:18:14 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 8271 byte(s)
0.3.3.1
1 dpavlin 2 /*
2     * Copyright (C) 2005 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 4 * $Id: cpu_hppa.c,v 1.4 2005/04/15 21:39:59 debug Exp $
29 dpavlin 2 *
30     * HPPA CPU emulation.
31     *
32     * TODO: This is just a dummy so far.
33     */
34    
35     #include <stdio.h>
36     #include <stdlib.h>
37     #include <string.h>
38     #include <ctype.h>
39    
40     #include "misc.h"
41    
42    
43     #ifndef ENABLE_HPPA
44    
45    
46     #include "cpu_hppa.h"
47    
48    
49     /*
50     * hppa_cpu_family_init():
51     *
52     * Bogus, when ENABLE_HPPA isn't defined.
53     */
54     int hppa_cpu_family_init(struct cpu_family *fp)
55     {
56     return 0;
57     }
58    
59    
60     #else /* ENABLE_HPPA */
61    
62    
63     #include "cpu.h"
64     #include "cpu_hppa.h"
65     #include "machine.h"
66     #include "memory.h"
67     #include "opcodes_hppa.h"
68     #include "symbol.h"
69    
70    
71     extern volatile int single_step;
72     extern int old_show_trace_tree;
73     extern int old_instruction_trace;
74     extern int old_quiet_mode;
75     extern int quiet_mode;
76    
77    
78     /*
79     * hppa_cpu_new():
80     *
81     * Create a new HPPA cpu object.
82     */
83     struct cpu *hppa_cpu_new(struct memory *mem, struct machine *machine,
84     int cpu_id, char *cpu_type_name)
85     {
86     struct cpu *cpu;
87    
88     if (cpu_type_name == NULL)
89     return NULL;
90    
91     if (strcasecmp(cpu_type_name, "HPPA1.0") != 0 &&
92     strcasecmp(cpu_type_name, "HPPA1.1") != 0 &&
93     strcasecmp(cpu_type_name, "HPPA2.0") != 0)
94     return NULL;
95    
96     cpu = malloc(sizeof(struct cpu));
97     if (cpu == NULL) {
98     fprintf(stderr, "out of memory\n");
99     exit(1);
100     }
101    
102     memset(cpu, 0, sizeof(struct cpu));
103     cpu->memory_rw = hppa_memory_rw;
104     cpu->name = cpu_type_name;
105     cpu->mem = mem;
106     cpu->machine = machine;
107     cpu->cpu_id = cpu_id;
108     cpu->byte_order = EMUL_BIG_ENDIAN;
109     cpu->bootstrap_cpu_flag = 0;
110     cpu->running = 0;
111    
112     cpu->cd.hppa.bits = 32;
113     if (strcasecmp(cpu_type_name, "HPPA2.0") == 0)
114     cpu->cd.hppa.bits = 64;
115    
116     /* Only show name and caches etc for CPU nr 0 (in SMP machines): */
117     if (cpu_id == 0) {
118     debug("%s", cpu->name);
119     }
120    
121     return cpu;
122     }
123    
124    
125     /*
126     * hppa_cpu_dumpinfo():
127     */
128     void hppa_cpu_dumpinfo(struct cpu *cpu)
129     {
130     debug(" (%i-bit)", cpu->cd.hppa.bits);
131    
132     debug("\n");
133     }
134    
135    
136     /*
137     * hppa_cpu_list_available_types():
138     *
139     * Print a list of available HPPA CPU types.
140     */
141     void hppa_cpu_list_available_types(void)
142     {
143     debug("HPPA1.0 HPPA1.1 HPPA2.0\n");
144     }
145    
146    
147     /*
148     * hppa_cpu_register_match():
149     */
150     void hppa_cpu_register_match(struct machine *m, char *name,
151     int writeflag, uint64_t *valuep, int *match_register)
152     {
153     int cpunr = 0;
154    
155     /* CPU number: */
156    
157     /* TODO */
158    
159     /* Register name: */
160     if (strcasecmp(name, "pc") == 0) {
161     if (writeflag) {
162     m->cpus[cpunr]->pc = *valuep;
163     } else
164     *valuep = m->cpus[cpunr]->pc;
165     *match_register = 1;
166     }
167    
168     /* TODO: _LOTS_ of stuff. */
169     }
170    
171    
172     /*
173     * hppa_cpu_disassemble_instr():
174     *
175     * Convert an instruction word into human readable format, for instruction
176     * tracing.
177     *
178     * If running is 1, cpu->pc should be the address of the instruction.
179     *
180     * If running is 0, things that depend on the runtime environment (eg.
181     * register contents) will not be shown, and addr will be used instead of
182     * cpu->pc for relative addresses.
183     */
184     int hppa_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
185     int running, uint64_t dumpaddr, int bintrans)
186     {
187 dpavlin 4 uint64_t offset;
188 dpavlin 2 uint32_t iword;
189 dpavlin 4 char *symbol;
190 dpavlin 2 int hi6, imm, rr, rb;
191    
192     if (running)
193     dumpaddr = cpu->pc;
194    
195     symbol = get_symbol_name(&cpu->machine->symbol_context,
196     dumpaddr, &offset);
197     if (symbol != NULL && offset==0)
198     debug("<%s>\n", symbol);
199    
200     if (cpu->machine->ncpus > 1 && running)
201     debug("cpu%i: ", cpu->cpu_id);
202    
203     if (cpu->cd.hppa.bits == 32)
204     debug("%08x", (int)dumpaddr);
205     else
206     debug("%016llx", (long long)dumpaddr);
207    
208     /* NOTE: Fixed to big-endian. */
209     iword = (instr[0] << 24) + (instr[1] << 16) + (instr[2] << 8)
210     + instr[3];
211    
212     debug(": %08x\t", iword);
213    
214     if (bintrans && !running) {
215     debug("(bintrans)");
216     goto disasm_ret;
217     }
218    
219     /*
220     * Decode the instruction:
221     */
222    
223     hi6 = iword >> 26;
224    
225     switch (hi6) {
226     case HPPA_LDIL:
227     rr = (iword >> 21) & 31;
228     imm = assemble_21(iword & 0x1fffff);
229     imm <<= 11;
230     debug("ldil\t0x%x,r%i", imm, rr);
231     break;
232     case HPPA_STW:
233     case HPPA_STW_1B:
234     rb = (iword >> 21) & 31;
235     rr = (iword >> 16) & 31;
236    
237     /* TODO: hahahahaha, assemble_16 is really weird */
238    
239     imm = (int16_t)(iword & 0xffff);
240     debug("stw\tr%i,%i(r%i)", rr, imm, rb);
241     break;
242     default:
243     debug("unimplemented hi6=%i", hi6);
244     }
245    
246     disasm_ret:
247     debug("\n");
248     return sizeof(iword);
249     }
250    
251    
252     /*
253     * hppa_cpu_run_instr():
254     *
255     * Execute one instruction on a specific CPU.
256     *
257     * Return value is the number of instructions executed during this call,
258     * 0 if no instruction was executed.
259     */
260     int hppa_cpu_run_instr(struct emul *emul, struct cpu *cpu)
261     {
262     uint32_t iword;
263     unsigned char buf[4];
264     uint64_t cached_pc;
265     int r, i, hi6, rt, imm;
266    
267     cached_pc = cpu->pc;
268    
269     /* Check PC against breakpoints: */
270     if (!single_step)
271     for (i=0; i<cpu->machine->n_breakpoints; i++)
272     if (cached_pc == cpu->machine->breakpoint_addr[i]) {
273     fatal("Breakpoint reached, pc=0x");
274     if (cpu->cd.hppa.bits == 32)
275     fatal("%08x", (int)cached_pc);
276     else
277     fatal("%016llx", (long long)cached_pc);
278     fatal("\n");
279     single_step = 1;
280     return 0;
281     }
282    
283     r = cpu->memory_rw(cpu, cpu->mem, cached_pc, &buf[0], sizeof(buf),
284     MEM_READ, CACHE_INSTRUCTION | PHYSICAL);
285     if (!r)
286     return 0;
287    
288     iword = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
289    
290     if (cpu->machine->instruction_trace)
291     hppa_cpu_disassemble_instr(cpu, buf, 1, 0, 0);
292    
293     cpu->cd.hppa.pc_last = cpu->pc;
294     cpu->pc += sizeof(iword);
295    
296     hi6 = iword >> 26;
297    
298     switch (hi6) {
299     case HPPA_LDIL:
300     rt = (iword >> 21) & 31;
301     imm = assemble_21(iword & 0x1fffff) << 1;
302     cpu->cd.hppa.gr[rt] = (int64_t)(int32_t) imm;
303     break;
304     default:
305     fatal("[ unimplemented HPPA hi6 = 0x%02x, pc = 0x%016llx ]\n",
306     hi6, (long long) (cpu->cd.hppa.pc_last));
307     cpu->running = 0;
308     return 0;
309     }
310    
311     return 1;
312     }
313    
314    
315     #define MEMORY_RW hppa_memory_rw
316     #define MEM_HPPA
317     #include "memory_rw.c"
318     #undef MEM_HPPA
319     #undef MEMORY_RW
320    
321    
322     #define CPU_RUN hppa_cpu_run
323     #define CPU_RINSTR hppa_cpu_run_instr
324     #define CPU_RUN_HPPA
325     #include "cpu_run.c"
326     #undef CCPU_RINSTR
327     #undef CPU_RUN_HPPA
328     #undef CPU_RUN
329    
330    
331     /*
332     * hppa_cpu_family_init():
333     *
334     * Fill in the cpu_family struct for HPPA.
335     */
336     int hppa_cpu_family_init(struct cpu_family *fp)
337     {
338     fp->name = "HPPA";
339     fp->cpu_new = hppa_cpu_new;
340     fp->list_available_types = hppa_cpu_list_available_types;
341     fp->register_match = hppa_cpu_register_match;
342     fp->disassemble_instr = hppa_cpu_disassemble_instr;
343     /* fp->register_dump = hppa_cpu_register_dump; */
344     fp->run = hppa_cpu_run;
345     fp->dumpinfo = hppa_cpu_dumpinfo;
346     /* fp->show_full_statistics = hppa_cpu_show_full_statistics; */
347     /* fp->tlbdump = hppa_cpu_tlbdump; */
348     /* fp->interrupt = hppa_cpu_interrupt; */
349     /* fp->interrupt_ack = hppa_cpu_interrupt_ack; */
350     return 1;
351     }
352    
353     #endif /* ENABLE_HPPA */

  ViewVC Help
Powered by ViewVC 1.1.26