Commit 5ef54116ea1c576995f0074b71400bf7bda08cf1
1 parent
725cb90b
Sparc64 user emulator fixes (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2063 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
31 additions
and
3 deletions
linux-user/elfload.c
| @@ -135,11 +135,13 @@ enum | @@ -135,11 +135,13 @@ enum | ||
| 135 | 135 | ||
| 136 | #define ELF_START_MMAP 0x80000000 | 136 | #define ELF_START_MMAP 0x80000000 |
| 137 | 137 | ||
| 138 | -#define elf_check_arch(x) ( (x) == EM_SPARC ) | 138 | +#define elf_check_arch(x) ( (x) == EM_SPARCV9 ) |
| 139 | 139 | ||
| 140 | #define ELF_CLASS ELFCLASS64 | 140 | #define ELF_CLASS ELFCLASS64 |
| 141 | #define ELF_DATA ELFDATA2MSB | 141 | #define ELF_DATA ELFDATA2MSB |
| 142 | -#define ELF_ARCH EM_SPARC | 142 | +#define ELF_ARCH EM_SPARCV9 |
| 143 | + | ||
| 144 | +#define STACK_BIAS 2047 | ||
| 143 | 145 | ||
| 144 | static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) | 146 | static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) |
| 145 | { | 147 | { |
| @@ -147,7 +149,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i | @@ -147,7 +149,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i | ||
| 147 | regs->pc = infop->entry; | 149 | regs->pc = infop->entry; |
| 148 | regs->npc = regs->pc + 4; | 150 | regs->npc = regs->pc + 4; |
| 149 | regs->y = 0; | 151 | regs->y = 0; |
| 150 | - regs->u_regs[14] = infop->start_stack - 16 * 4; | 152 | + regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; |
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | #else | 155 | #else |
linux-user/main.c
| @@ -473,11 +473,17 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1) | @@ -473,11 +473,17 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1) | ||
| 473 | 473 | ||
| 474 | static void save_window(CPUSPARCState *env) | 474 | static void save_window(CPUSPARCState *env) |
| 475 | { | 475 | { |
| 476 | +#ifndef TARGET_SPARC64 | ||
| 476 | unsigned int new_wim; | 477 | unsigned int new_wim; |
| 477 | new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & | 478 | new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & |
| 478 | ((1LL << NWINDOWS) - 1); | 479 | ((1LL << NWINDOWS) - 1); |
| 479 | save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); | 480 | save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); |
| 480 | env->wim = new_wim; | 481 | env->wim = new_wim; |
| 482 | +#else | ||
| 483 | + save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); | ||
| 484 | + env->cansave++; | ||
| 485 | + env->canrestore--; | ||
| 486 | +#endif | ||
| 481 | } | 487 | } |
| 482 | 488 | ||
| 483 | static void restore_window(CPUSPARCState *env) | 489 | static void restore_window(CPUSPARCState *env) |
| @@ -500,6 +506,12 @@ static void restore_window(CPUSPARCState *env) | @@ -500,6 +506,12 @@ static void restore_window(CPUSPARCState *env) | ||
| 500 | sp_ptr += sizeof(target_ulong); | 506 | sp_ptr += sizeof(target_ulong); |
| 501 | } | 507 | } |
| 502 | env->wim = new_wim; | 508 | env->wim = new_wim; |
| 509 | +#ifdef TARGET_SPARC64 | ||
| 510 | + env->canrestore++; | ||
| 511 | + if (env->cleanwin < NWINDOWS - 1) | ||
| 512 | + env->cleanwin++; | ||
| 513 | + env->cansave--; | ||
| 514 | +#endif | ||
| 503 | } | 515 | } |
| 504 | 516 | ||
| 505 | static void flush_windows(CPUSPARCState *env) | 517 | static void flush_windows(CPUSPARCState *env) |
| @@ -532,8 +544,12 @@ void cpu_loop (CPUSPARCState *env) | @@ -532,8 +544,12 @@ void cpu_loop (CPUSPARCState *env) | ||
| 532 | trapnr = cpu_sparc_exec (env); | 544 | trapnr = cpu_sparc_exec (env); |
| 533 | 545 | ||
| 534 | switch (trapnr) { | 546 | switch (trapnr) { |
| 547 | +#ifndef TARGET_SPARC64 | ||
| 535 | case 0x88: | 548 | case 0x88: |
| 536 | case 0x90: | 549 | case 0x90: |
| 550 | +#else | ||
| 551 | + case 0x16d: | ||
| 552 | +#endif | ||
| 537 | ret = do_syscall (env, env->gregs[1], | 553 | ret = do_syscall (env, env->gregs[1], |
| 538 | env->regwptr[0], env->regwptr[1], | 554 | env->regwptr[0], env->regwptr[1], |
| 539 | env->regwptr[2], env->regwptr[3], | 555 | env->regwptr[2], env->regwptr[3], |
| @@ -574,6 +590,12 @@ void cpu_loop (CPUSPARCState *env) | @@ -574,6 +590,12 @@ void cpu_loop (CPUSPARCState *env) | ||
| 574 | } | 590 | } |
| 575 | break; | 591 | break; |
| 576 | #else | 592 | #else |
| 593 | + case TT_SPILL: /* window overflow */ | ||
| 594 | + save_window(env); | ||
| 595 | + break; | ||
| 596 | + case TT_FILL: /* window underflow */ | ||
| 597 | + restore_window(env); | ||
| 598 | + break; | ||
| 577 | // XXX | 599 | // XXX |
| 578 | #endif | 600 | #endif |
| 579 | case EXCP_INTERRUPT: | 601 | case EXCP_INTERRUPT: |
target-sparc/translate.c
| @@ -2731,6 +2731,10 @@ void cpu_reset(CPUSPARCState *env) | @@ -2731,6 +2731,10 @@ void cpu_reset(CPUSPARCState *env) | ||
| 2731 | env->regwptr = env->regbase + (env->cwp * 16); | 2731 | env->regwptr = env->regbase + (env->cwp * 16); |
| 2732 | #if defined(CONFIG_USER_ONLY) | 2732 | #if defined(CONFIG_USER_ONLY) |
| 2733 | env->user_mode_only = 1; | 2733 | env->user_mode_only = 1; |
| 2734 | +#ifdef TARGET_SPARC64 | ||
| 2735 | + env->cleanwin = NWINDOWS - 1; | ||
| 2736 | + env->cansave = NWINDOWS - 1; | ||
| 2737 | +#endif | ||
| 2734 | #else | 2738 | #else |
| 2735 | env->psrs = 1; | 2739 | env->psrs = 1; |
| 2736 | env->psrps = 1; | 2740 | env->psrps = 1; |