Commit 93ac68bca5a3332ffacd7bf10e7b9c4cfdab6374
1 parent
1e43adfc
sparc emulation target (thanx to Thomas M. Ogrisegg)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@388 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
115 additions
and
12 deletions
cpu-all.h
... | ... | @@ -188,6 +188,56 @@ static inline void stfq(void *ptr, double v) |
188 | 188 | } |
189 | 189 | #endif |
190 | 190 | |
191 | +#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN) | |
192 | + | |
193 | +static inline int lduw(void *ptr) | |
194 | +{ | |
195 | + uint8_t *b = (uint8_t *) ptr; | |
196 | + return (b[0]<<8|b[1]); | |
197 | +} | |
198 | + | |
199 | +static inline int ldsw(void *ptr) | |
200 | +{ | |
201 | + int8_t *b = (int8_t *) ptr; | |
202 | + return (b[0]<<8|b[1]); | |
203 | +} | |
204 | + | |
205 | +static inline int ldl(void *ptr) | |
206 | +{ | |
207 | + uint8_t *b = (uint8_t *) ptr; | |
208 | + return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]); | |
209 | +} | |
210 | + | |
211 | +static inline uint64_t ldq(void *ptr) | |
212 | +{ | |
213 | + uint32_t a,b; | |
214 | + a = ldl (ptr); | |
215 | + b = ldl (ptr+4); | |
216 | + return (((uint64_t)a<<32)|b); | |
217 | +} | |
218 | + | |
219 | +static inline void stw(void *ptr, int v) | |
220 | +{ | |
221 | + uint8_t *d = (uint8_t *) ptr; | |
222 | + d[0] = v >> 8; | |
223 | + d[1] = v; | |
224 | +} | |
225 | + | |
226 | +static inline void stl(void *ptr, int v) | |
227 | +{ | |
228 | + uint8_t *d = (uint8_t *) ptr; | |
229 | + d[0] = v >> 24; | |
230 | + d[1] = v >> 16; | |
231 | + d[2] = v >> 8; | |
232 | + d[3] = v; | |
233 | +} | |
234 | + | |
235 | +static inline void stq(void *ptr, uint64_t v) | |
236 | +{ | |
237 | + stl (ptr, v); | |
238 | + stl (ptr+4, v >> 32); | |
239 | +} | |
240 | + | |
191 | 241 | #else |
192 | 242 | |
193 | 243 | static inline int lduw(void *ptr) |
... | ... | @@ -297,6 +347,15 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size); |
297 | 347 | #define cpu_interrupt cpu_arm_interrupt |
298 | 348 | #define cpu_signal_handler cpu_arm_signal_handler |
299 | 349 | |
350 | +#elif defined(TARGET_SPARC) | |
351 | + | |
352 | +#define CPUState CPUSPARCState | |
353 | +#define cpu_init cpu_sparc_init | |
354 | +#define cpu_exec cpu_sparc_exec | |
355 | +#define cpu_gen_code cpu_sparc_gen_code | |
356 | +#define cpu_interrupt cpu_sparc_interrupt | |
357 | +#define cpu_signal_handler cpu_sparc_signal_handler | |
358 | + | |
300 | 359 | #else |
301 | 360 | |
302 | 361 | #error unsupported target CPU | ... | ... |
cpu-exec.c
... | ... | @@ -18,19 +18,13 @@ |
18 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 | */ |
20 | 20 | #include "config.h" |
21 | -#ifdef TARGET_I386 | |
22 | -#include "exec-i386.h" | |
23 | -#endif | |
24 | -#ifdef TARGET_ARM | |
25 | -#include "exec-arm.h" | |
26 | -#endif | |
27 | - | |
21 | +#include "exec.h" | |
28 | 22 | #include "disas.h" |
29 | 23 | |
30 | 24 | //#define DEBUG_EXEC |
31 | 25 | //#define DEBUG_SIGNAL |
32 | 26 | |
33 | -#if defined(TARGET_ARM) | |
27 | +#if defined(TARGET_ARM) || defined(TARGET_SPARC) | |
34 | 28 | /* XXX: unify with i386 target */ |
35 | 29 | void cpu_loop_exit(void) |
36 | 30 | { |
... | ... | @@ -136,6 +130,7 @@ int cpu_exec(CPUState *env1) |
136 | 130 | env->VF = (psr << 3) & 0x80000000; |
137 | 131 | env->cpsr = psr & ~0xf0000000; |
138 | 132 | } |
133 | +#elif defined(TARGET_SPARC) | |
139 | 134 | #else |
140 | 135 | #error unsupported target CPU |
141 | 136 | #endif |
... | ... | @@ -229,6 +224,8 @@ int cpu_exec(CPUState *env1) |
229 | 224 | env->cpsr = compute_cpsr(); |
230 | 225 | cpu_arm_dump_state(env, logfile, 0); |
231 | 226 | env->cpsr &= ~0xf0000000; |
227 | +#elif defined(TARGET_SPARC) | |
228 | + cpu_sparc_dump_state (env, logfile, 0); | |
232 | 229 | #else |
233 | 230 | #error unsupported target CPU |
234 | 231 | #endif |
... | ... | @@ -246,6 +243,14 @@ int cpu_exec(CPUState *env1) |
246 | 243 | flags = 0; |
247 | 244 | cs_base = 0; |
248 | 245 | pc = (uint8_t *)env->regs[15]; |
246 | +#elif defined(TARGET_SPARC) | |
247 | + flags = 0; | |
248 | + cs_base = 0; | |
249 | + if (env->npc) { | |
250 | + env->pc = env->npc; | |
251 | + env->npc = 0; | |
252 | + } | |
253 | + pc = (uint8_t *) env->pc; | |
249 | 254 | #else |
250 | 255 | #error unsupported CPU |
251 | 256 | #endif |
... | ... | @@ -358,6 +363,7 @@ int cpu_exec(CPUState *env1) |
358 | 363 | #endif |
359 | 364 | #elif defined(TARGET_ARM) |
360 | 365 | env->cpsr = compute_cpsr(); |
366 | +#elif defined(TARGET_SPARC) | |
361 | 367 | #else |
362 | 368 | #error unsupported target CPU |
363 | 369 | #endif |
... | ... | @@ -488,6 +494,12 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
488 | 494 | /* XXX: do more */ |
489 | 495 | return 0; |
490 | 496 | } |
497 | +#elif defined(TARGET_SPARC) | |
498 | +static inline int handle_cpu_signal(unsigned long pc, unsigned long address, | |
499 | + int is_write, sigset_t *old_set) | |
500 | +{ | |
501 | + return 0; | |
502 | +} | |
491 | 503 | #else |
492 | 504 | #error unsupported target CPU |
493 | 505 | #endif | ... | ... |
disas.c
... | ... | @@ -142,6 +142,8 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags) |
142 | 142 | print_insn = print_insn_i386; |
143 | 143 | #elif defined(TARGET_ARM) |
144 | 144 | print_insn = print_insn_arm; |
145 | +#elif defined(TARGET_SPARC) | |
146 | + print_insn = print_insn_sparc; | |
145 | 147 | #else |
146 | 148 | fprintf(out, "Asm output not supported on this arch\n"); |
147 | 149 | return; | ... | ... |
linux-user/main.c
1 | 1 | /* |
2 | - * qemu main | |
2 | + * qemu user main | |
3 | 3 | * |
4 | 4 | * Copyright (c) 2003 Fabrice Bellard |
5 | 5 | * |
... | ... | @@ -38,7 +38,7 @@ static const char *interp_prefix = CONFIG_QEMU_PREFIX; |
38 | 38 | const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; |
39 | 39 | #endif |
40 | 40 | |
41 | -/* for recent libc, we add these dummies symbol which are not declared | |
41 | +/* for recent libc, we add these dummy symbols which are not declared | |
42 | 42 | when generating a linked object (bug in ld ?) */ |
43 | 43 | #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) |
44 | 44 | long __init_array_start[0]; |
... | ... | @@ -299,10 +299,37 @@ void cpu_loop(CPUARMState *env) |
299 | 299 | |
300 | 300 | #endif |
301 | 301 | |
302 | +#ifdef TARGET_SPARC | |
303 | + | |
304 | +void cpu_loop (CPUSPARCState *env) | |
305 | +{ | |
306 | + int trapnr; | |
307 | + | |
308 | + while (1) { | |
309 | + trapnr = cpu_sparc_exec (env); | |
310 | + | |
311 | + switch (trapnr) { | |
312 | + case 0x8: case 0x10: | |
313 | + env->regwptr[0] = do_syscall (env, env->gregs[1], | |
314 | + env->regwptr[0], env->regwptr[1], env->regwptr[2], | |
315 | + env->regwptr[3], env->regwptr[4], env->regwptr[13]); | |
316 | + if (env->regwptr[0] >= 0xffffffe0) | |
317 | + env->psr |= PSR_CARRY; | |
318 | + break; | |
319 | + default: | |
320 | + printf ("Invalid trap: %d\n", trapnr); | |
321 | + exit (1); | |
322 | + } | |
323 | + process_pending_signals (env); | |
324 | + } | |
325 | +} | |
326 | + | |
327 | +#endif | |
328 | + | |
302 | 329 | void usage(void) |
303 | 330 | { |
304 | - printf("qemu version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" | |
305 | - "usage: qemu [-h] [-d] [-L path] [-s size] program [arguments...]\n" | |
331 | + printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" | |
332 | + "usage: qemu-" TARGET_ARCH " [-h] [-d] [-L path] [-s size] program [arguments...]\n" | |
306 | 333 | "Linux CPU emulator (compiled for %s emulation)\n" |
307 | 334 | "\n" |
308 | 335 | "-h print this help\n" |
... | ... | @@ -497,6 +524,9 @@ int main(int argc, char **argv) |
497 | 524 | } |
498 | 525 | env->cpsr = regs->uregs[16]; |
499 | 526 | } |
527 | +#elif defined(TARGET_SPARC) | |
528 | + env->pc = regs->u_regs[0]; | |
529 | + env->regwptr[6] = regs->u_regs[1]-0x40; | |
500 | 530 | #else |
501 | 531 | #error unsupported target CPU |
502 | 532 | #endif | ... | ... |