Commit ee5bbe38b1193bb2a8c2a450acb3d4679663fba1
1 parent
e37e863f
correct split between helper.c and op_helper.c
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1506 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
201 additions
and
186 deletions
target-sparc/exec.h
@@ -72,8 +72,8 @@ void do_ldd_raw(target_ulong addr); | @@ -72,8 +72,8 @@ void do_ldd_raw(target_ulong addr); | ||
72 | void do_interrupt(int intno); | 72 | void do_interrupt(int intno); |
73 | void raise_exception(int tt); | 73 | void raise_exception(int tt); |
74 | void memcpy32(target_ulong *dst, const target_ulong *src); | 74 | void memcpy32(target_ulong *dst, const target_ulong *src); |
75 | -target_ulong mmu_probe(target_ulong address, int mmulev); | ||
76 | -void dump_mmu(void); | 75 | +target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev); |
76 | +void dump_mmu(CPUState *env); | ||
77 | void helper_debug(); | 77 | void helper_debug(); |
78 | void do_wrpsr(); | 78 | void do_wrpsr(); |
79 | void do_rdpsr(); | 79 | void do_rdpsr(); |
target-sparc/helper.c
@@ -17,7 +17,16 @@ | @@ -17,7 +17,16 @@ | ||
17 | * License along with this library; if not, write to the Free Software | 17 | * License along with this library; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | -#include "exec.h" | 20 | +#include <stdarg.h> |
21 | +#include <stdlib.h> | ||
22 | +#include <stdio.h> | ||
23 | +#include <string.h> | ||
24 | +#include <inttypes.h> | ||
25 | +#include <signal.h> | ||
26 | +#include <assert.h> | ||
27 | + | ||
28 | +#include "cpu.h" | ||
29 | +#include "exec-all.h" | ||
21 | 30 | ||
22 | //#define DEBUG_PCALL | 31 | //#define DEBUG_PCALL |
23 | //#define DEBUG_MMU | 32 | //#define DEBUG_MMU |
@@ -52,55 +61,6 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, | @@ -52,55 +61,6 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, | ||
52 | 61 | ||
53 | #else | 62 | #else |
54 | 63 | ||
55 | -#define MMUSUFFIX _mmu | ||
56 | -#define GETPC() (__builtin_return_address(0)) | ||
57 | - | ||
58 | -#define SHIFT 0 | ||
59 | -#include "softmmu_template.h" | ||
60 | - | ||
61 | -#define SHIFT 1 | ||
62 | -#include "softmmu_template.h" | ||
63 | - | ||
64 | -#define SHIFT 2 | ||
65 | -#include "softmmu_template.h" | ||
66 | - | ||
67 | -#define SHIFT 3 | ||
68 | -#include "softmmu_template.h" | ||
69 | - | ||
70 | - | ||
71 | -/* try to fill the TLB and return an exception if error. If retaddr is | ||
72 | - NULL, it means that the function was called in C code (i.e. not | ||
73 | - from generated code or from helper.c) */ | ||
74 | -/* XXX: fix it to restore all registers */ | ||
75 | -void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) | ||
76 | -{ | ||
77 | - TranslationBlock *tb; | ||
78 | - int ret; | ||
79 | - unsigned long pc; | ||
80 | - CPUState *saved_env; | ||
81 | - | ||
82 | - /* XXX: hack to restore env in all cases, even if not called from | ||
83 | - generated code */ | ||
84 | - saved_env = env; | ||
85 | - env = cpu_single_env; | ||
86 | - | ||
87 | - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1); | ||
88 | - if (ret) { | ||
89 | - if (retaddr) { | ||
90 | - /* now we have a real cpu fault */ | ||
91 | - pc = (unsigned long)retaddr; | ||
92 | - tb = tb_find_pc(pc); | ||
93 | - if (tb) { | ||
94 | - /* the PC is inside the translated code. It means that we have | ||
95 | - a virtual CPU fault */ | ||
96 | - cpu_restore_state(tb, env, pc, (void *)T2); | ||
97 | - } | ||
98 | - } | ||
99 | - cpu_loop_exit(); | ||
100 | - } | ||
101 | - env = saved_env; | ||
102 | -} | ||
103 | - | ||
104 | #ifndef TARGET_SPARC64 | 64 | #ifndef TARGET_SPARC64 |
105 | static const int access_table[8][8] = { | 65 | static const int access_table[8][8] = { |
106 | { 0, 0, 0, 0, 2, 0, 3, 3 }, | 66 | { 0, 0, 0, 0, 2, 0, 3, 3 }, |
@@ -412,131 +372,8 @@ void memcpy32(target_ulong *dst, const target_ulong *src) | @@ -412,131 +372,8 @@ void memcpy32(target_ulong *dst, const target_ulong *src) | ||
412 | dst[7] = src[7]; | 372 | dst[7] = src[7]; |
413 | } | 373 | } |
414 | 374 | ||
415 | -void set_cwp(int new_cwp) | ||
416 | -{ | ||
417 | - /* put the modified wrap registers at their proper location */ | ||
418 | - if (env->cwp == (NWINDOWS - 1)) | ||
419 | - memcpy32(env->regbase, env->regbase + NWINDOWS * 16); | ||
420 | - env->cwp = new_cwp; | ||
421 | - /* put the wrap registers at their temporary location */ | ||
422 | - if (new_cwp == (NWINDOWS - 1)) | ||
423 | - memcpy32(env->regbase + NWINDOWS * 16, env->regbase); | ||
424 | - env->regwptr = env->regbase + (new_cwp * 16); | ||
425 | - REGWPTR = env->regwptr; | ||
426 | -} | ||
427 | - | ||
428 | -void cpu_set_cwp(CPUState *env1, int new_cwp) | ||
429 | -{ | ||
430 | - CPUState *saved_env; | ||
431 | -#ifdef reg_REGWPTR | ||
432 | - target_ulong *saved_regwptr; | ||
433 | -#endif | ||
434 | - | ||
435 | - saved_env = env; | ||
436 | -#ifdef reg_REGWPTR | ||
437 | - saved_regwptr = REGWPTR; | ||
438 | -#endif | ||
439 | - env = env1; | ||
440 | - set_cwp(new_cwp); | ||
441 | - env = saved_env; | ||
442 | -#ifdef reg_REGWPTR | ||
443 | - REGWPTR = saved_regwptr; | ||
444 | -#endif | ||
445 | -} | ||
446 | - | ||
447 | -#ifdef TARGET_SPARC64 | ||
448 | -void do_interrupt(int intno) | ||
449 | -{ | ||
450 | -#ifdef DEBUG_PCALL | ||
451 | - if (loglevel & CPU_LOG_INT) { | ||
452 | - static int count; | ||
453 | - fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n", | ||
454 | - count, intno, | ||
455 | - env->pc, | ||
456 | - env->npc, env->regwptr[6]); | ||
457 | - cpu_dump_state(env, logfile, fprintf, 0); | ||
458 | -#if 0 | ||
459 | - { | ||
460 | - int i; | ||
461 | - uint8_t *ptr; | ||
462 | - | ||
463 | - fprintf(logfile, " code="); | ||
464 | - ptr = (uint8_t *)env->pc; | ||
465 | - for(i = 0; i < 16; i++) { | ||
466 | - fprintf(logfile, " %02x", ldub(ptr + i)); | ||
467 | - } | ||
468 | - fprintf(logfile, "\n"); | ||
469 | - } | ||
470 | -#endif | ||
471 | - count++; | ||
472 | - } | ||
473 | -#endif | ||
474 | -#if !defined(CONFIG_USER_ONLY) | ||
475 | - if (env->pstate & PS_IE) { | ||
476 | - cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index); | ||
477 | - return; | ||
478 | - } | ||
479 | -#endif | ||
480 | - env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | | ||
481 | - ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff); | ||
482 | - env->tpc[env->tl] = env->pc; | ||
483 | - env->tnpc[env->tl] = env->npc; | ||
484 | - env->tt[env->tl] = intno; | ||
485 | - env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4); | ||
486 | - env->tl++; | ||
487 | - env->pc = env->tbr; | ||
488 | - env->npc = env->pc + 4; | ||
489 | - env->exception_index = 0; | ||
490 | -} | ||
491 | -#else | ||
492 | -void do_interrupt(int intno) | ||
493 | -{ | ||
494 | - int cwp; | ||
495 | - | ||
496 | -#ifdef DEBUG_PCALL | ||
497 | - if (loglevel & CPU_LOG_INT) { | ||
498 | - static int count; | ||
499 | - fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n", | ||
500 | - count, intno, | ||
501 | - env->pc, | ||
502 | - env->npc, env->regwptr[6]); | ||
503 | - cpu_dump_state(env, logfile, fprintf, 0); | ||
504 | -#if 0 | ||
505 | - { | ||
506 | - int i; | ||
507 | - uint8_t *ptr; | ||
508 | - | ||
509 | - fprintf(logfile, " code="); | ||
510 | - ptr = (uint8_t *)env->pc; | ||
511 | - for(i = 0; i < 16; i++) { | ||
512 | - fprintf(logfile, " %02x", ldub(ptr + i)); | ||
513 | - } | ||
514 | - fprintf(logfile, "\n"); | ||
515 | - } | ||
516 | -#endif | ||
517 | - count++; | ||
518 | - } | ||
519 | -#endif | ||
520 | -#if !defined(CONFIG_USER_ONLY) | ||
521 | - if (env->psret == 0) { | ||
522 | - cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index); | ||
523 | - return; | ||
524 | - } | ||
525 | -#endif | ||
526 | - env->psret = 0; | ||
527 | - cwp = (env->cwp - 1) & (NWINDOWS - 1); | ||
528 | - set_cwp(cwp); | ||
529 | - env->regwptr[9] = env->pc; | ||
530 | - env->regwptr[10] = env->npc; | ||
531 | - env->psrps = env->psrs; | ||
532 | - env->psrs = 1; | ||
533 | - env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); | ||
534 | - env->pc = env->tbr; | ||
535 | - env->npc = env->pc + 4; | ||
536 | - env->exception_index = 0; | ||
537 | -} | ||
538 | - | ||
539 | -target_ulong mmu_probe(target_ulong address, int mmulev) | 375 | +#if !defined(TARGET_SPARC64) |
376 | +target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev) | ||
540 | { | 377 | { |
541 | target_phys_addr_t pde_ptr; | 378 | target_phys_addr_t pde_ptr; |
542 | uint32_t pde; | 379 | uint32_t pde; |
@@ -599,7 +436,7 @@ target_ulong mmu_probe(target_ulong address, int mmulev) | @@ -599,7 +436,7 @@ target_ulong mmu_probe(target_ulong address, int mmulev) | ||
599 | } | 436 | } |
600 | 437 | ||
601 | #ifdef DEBUG_MMU | 438 | #ifdef DEBUG_MMU |
602 | -void dump_mmu(void) | 439 | +void dump_mmu(CPUState *env) |
603 | { | 440 | { |
604 | target_ulong va, va1, va2; | 441 | target_ulong va, va1, va2; |
605 | unsigned int n, m, o; | 442 | unsigned int n, m, o; |
@@ -611,17 +448,17 @@ void dump_mmu(void) | @@ -611,17 +448,17 @@ void dump_mmu(void) | ||
611 | pde = ldl_phys(pde_ptr); | 448 | pde = ldl_phys(pde_ptr); |
612 | printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); | 449 | printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); |
613 | for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { | 450 | for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { |
614 | - pde_ptr = mmu_probe(va, 2); | 451 | + pde_ptr = mmu_probe(env, va, 2); |
615 | if (pde_ptr) { | 452 | if (pde_ptr) { |
616 | pa = cpu_get_phys_page_debug(env, va); | 453 | pa = cpu_get_phys_page_debug(env, va); |
617 | printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); | 454 | printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); |
618 | for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { | 455 | for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { |
619 | - pde_ptr = mmu_probe(va1, 1); | 456 | + pde_ptr = mmu_probe(env, va1, 1); |
620 | if (pde_ptr) { | 457 | if (pde_ptr) { |
621 | pa = cpu_get_phys_page_debug(env, va1); | 458 | pa = cpu_get_phys_page_debug(env, va1); |
622 | printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); | 459 | printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); |
623 | for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { | 460 | for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { |
624 | - pde_ptr = mmu_probe(va2, 0); | 461 | + pde_ptr = mmu_probe(env, va2, 0); |
625 | if (pde_ptr) { | 462 | if (pde_ptr) { |
626 | pa = cpu_get_phys_page_debug(env, va2); | 463 | pa = cpu_get_phys_page_debug(env, va2); |
627 | printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr); | 464 | printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr); |
target-sparc/op_helper.c
@@ -234,7 +234,7 @@ void helper_ld_asi(int asi, int size, int sign) | @@ -234,7 +234,7 @@ void helper_ld_asi(int asi, int size, int sign) | ||
234 | if (mmulev > 4) | 234 | if (mmulev > 4) |
235 | ret = 0; | 235 | ret = 0; |
236 | else { | 236 | else { |
237 | - ret = mmu_probe(T0, mmulev); | 237 | + ret = mmu_probe(env, T0, mmulev); |
238 | //bswap32s(&ret); | 238 | //bswap32s(&ret); |
239 | } | 239 | } |
240 | #ifdef DEBUG_MMU | 240 | #ifdef DEBUG_MMU |
@@ -293,7 +293,7 @@ void helper_st_asi(int asi, int size, int sign) | @@ -293,7 +293,7 @@ void helper_st_asi(int asi, int size, int sign) | ||
293 | break; | 293 | break; |
294 | } | 294 | } |
295 | #ifdef DEBUG_MMU | 295 | #ifdef DEBUG_MMU |
296 | - dump_mmu(); | 296 | + dump_mmu(env); |
297 | #endif | 297 | #endif |
298 | return; | 298 | return; |
299 | } | 299 | } |
@@ -330,7 +330,7 @@ void helper_st_asi(int asi, int size, int sign) | @@ -330,7 +330,7 @@ void helper_st_asi(int asi, int size, int sign) | ||
330 | if (oldreg != env->mmuregs[reg]) { | 330 | if (oldreg != env->mmuregs[reg]) { |
331 | printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]); | 331 | printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]); |
332 | } | 332 | } |
333 | - dump_mmu(); | 333 | + dump_mmu(env); |
334 | #endif | 334 | #endif |
335 | return; | 335 | return; |
336 | } | 336 | } |
@@ -508,7 +508,7 @@ void helper_st_asi(int asi, int size, int sign) | @@ -508,7 +508,7 @@ void helper_st_asi(int asi, int size, int sign) | ||
508 | if (oldreg != env->immuregs[reg]) { | 508 | if (oldreg != env->immuregs[reg]) { |
509 | printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->immuregs[reg]); | 509 | printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->immuregs[reg]); |
510 | } | 510 | } |
511 | - dump_mmu(); | 511 | + dump_mmu(env); |
512 | #endif | 512 | #endif |
513 | return; | 513 | return; |
514 | } | 514 | } |
@@ -576,7 +576,7 @@ void helper_st_asi(int asi, int size, int sign) | @@ -576,7 +576,7 @@ void helper_st_asi(int asi, int size, int sign) | ||
576 | if (oldreg != env->dmmuregs[reg]) { | 576 | if (oldreg != env->dmmuregs[reg]) { |
577 | printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->dmmuregs[reg]); | 577 | printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->dmmuregs[reg]); |
578 | } | 578 | } |
579 | - dump_mmu(); | 579 | + dump_mmu(env); |
580 | #endif | 580 | #endif |
581 | return; | 581 | return; |
582 | } | 582 | } |
@@ -705,3 +705,181 @@ void do_popc() | @@ -705,3 +705,181 @@ void do_popc() | ||
705 | T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL); | 705 | T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL); |
706 | } | 706 | } |
707 | #endif | 707 | #endif |
708 | + | ||
709 | +void set_cwp(int new_cwp) | ||
710 | +{ | ||
711 | + /* put the modified wrap registers at their proper location */ | ||
712 | + if (env->cwp == (NWINDOWS - 1)) | ||
713 | + memcpy32(env->regbase, env->regbase + NWINDOWS * 16); | ||
714 | + env->cwp = new_cwp; | ||
715 | + /* put the wrap registers at their temporary location */ | ||
716 | + if (new_cwp == (NWINDOWS - 1)) | ||
717 | + memcpy32(env->regbase + NWINDOWS * 16, env->regbase); | ||
718 | + env->regwptr = env->regbase + (new_cwp * 16); | ||
719 | + REGWPTR = env->regwptr; | ||
720 | +} | ||
721 | + | ||
722 | +void cpu_set_cwp(CPUState *env1, int new_cwp) | ||
723 | +{ | ||
724 | + CPUState *saved_env; | ||
725 | +#ifdef reg_REGWPTR | ||
726 | + target_ulong *saved_regwptr; | ||
727 | +#endif | ||
728 | + | ||
729 | + saved_env = env; | ||
730 | +#ifdef reg_REGWPTR | ||
731 | + saved_regwptr = REGWPTR; | ||
732 | +#endif | ||
733 | + env = env1; | ||
734 | + set_cwp(new_cwp); | ||
735 | + env = saved_env; | ||
736 | +#ifdef reg_REGWPTR | ||
737 | + REGWPTR = saved_regwptr; | ||
738 | +#endif | ||
739 | +} | ||
740 | + | ||
741 | +#ifdef TARGET_SPARC64 | ||
742 | +void do_interrupt(int intno) | ||
743 | +{ | ||
744 | +#ifdef DEBUG_PCALL | ||
745 | + if (loglevel & CPU_LOG_INT) { | ||
746 | + static int count; | ||
747 | + fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n", | ||
748 | + count, intno, | ||
749 | + env->pc, | ||
750 | + env->npc, env->regwptr[6]); | ||
751 | + cpu_dump_state(env, logfile, fprintf, 0); | ||
752 | +#if 0 | ||
753 | + { | ||
754 | + int i; | ||
755 | + uint8_t *ptr; | ||
756 | + | ||
757 | + fprintf(logfile, " code="); | ||
758 | + ptr = (uint8_t *)env->pc; | ||
759 | + for(i = 0; i < 16; i++) { | ||
760 | + fprintf(logfile, " %02x", ldub(ptr + i)); | ||
761 | + } | ||
762 | + fprintf(logfile, "\n"); | ||
763 | + } | ||
764 | +#endif | ||
765 | + count++; | ||
766 | + } | ||
767 | +#endif | ||
768 | +#if !defined(CONFIG_USER_ONLY) | ||
769 | + if (env->pstate & PS_IE) { | ||
770 | + cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index); | ||
771 | + return; | ||
772 | + } | ||
773 | +#endif | ||
774 | + env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | | ||
775 | + ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff); | ||
776 | + env->tpc[env->tl] = env->pc; | ||
777 | + env->tnpc[env->tl] = env->npc; | ||
778 | + env->tt[env->tl] = intno; | ||
779 | + env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4); | ||
780 | + env->tl++; | ||
781 | + env->pc = env->tbr; | ||
782 | + env->npc = env->pc + 4; | ||
783 | + env->exception_index = 0; | ||
784 | +} | ||
785 | +#else | ||
786 | +void do_interrupt(int intno) | ||
787 | +{ | ||
788 | + int cwp; | ||
789 | + | ||
790 | +#ifdef DEBUG_PCALL | ||
791 | + if (loglevel & CPU_LOG_INT) { | ||
792 | + static int count; | ||
793 | + fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n", | ||
794 | + count, intno, | ||
795 | + env->pc, | ||
796 | + env->npc, env->regwptr[6]); | ||
797 | + cpu_dump_state(env, logfile, fprintf, 0); | ||
798 | +#if 0 | ||
799 | + { | ||
800 | + int i; | ||
801 | + uint8_t *ptr; | ||
802 | + | ||
803 | + fprintf(logfile, " code="); | ||
804 | + ptr = (uint8_t *)env->pc; | ||
805 | + for(i = 0; i < 16; i++) { | ||
806 | + fprintf(logfile, " %02x", ldub(ptr + i)); | ||
807 | + } | ||
808 | + fprintf(logfile, "\n"); | ||
809 | + } | ||
810 | +#endif | ||
811 | + count++; | ||
812 | + } | ||
813 | +#endif | ||
814 | +#if !defined(CONFIG_USER_ONLY) | ||
815 | + if (env->psret == 0) { | ||
816 | + cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index); | ||
817 | + return; | ||
818 | + } | ||
819 | +#endif | ||
820 | + env->psret = 0; | ||
821 | + cwp = (env->cwp - 1) & (NWINDOWS - 1); | ||
822 | + set_cwp(cwp); | ||
823 | + env->regwptr[9] = env->pc; | ||
824 | + env->regwptr[10] = env->npc; | ||
825 | + env->psrps = env->psrs; | ||
826 | + env->psrs = 1; | ||
827 | + env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); | ||
828 | + env->pc = env->tbr; | ||
829 | + env->npc = env->pc + 4; | ||
830 | + env->exception_index = 0; | ||
831 | +} | ||
832 | +#endif | ||
833 | + | ||
834 | +#if !defined(CONFIG_USER_ONLY) | ||
835 | + | ||
836 | +#define MMUSUFFIX _mmu | ||
837 | +#define GETPC() (__builtin_return_address(0)) | ||
838 | + | ||
839 | +#define SHIFT 0 | ||
840 | +#include "softmmu_template.h" | ||
841 | + | ||
842 | +#define SHIFT 1 | ||
843 | +#include "softmmu_template.h" | ||
844 | + | ||
845 | +#define SHIFT 2 | ||
846 | +#include "softmmu_template.h" | ||
847 | + | ||
848 | +#define SHIFT 3 | ||
849 | +#include "softmmu_template.h" | ||
850 | + | ||
851 | + | ||
852 | +/* try to fill the TLB and return an exception if error. If retaddr is | ||
853 | + NULL, it means that the function was called in C code (i.e. not | ||
854 | + from generated code or from helper.c) */ | ||
855 | +/* XXX: fix it to restore all registers */ | ||
856 | +void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) | ||
857 | +{ | ||
858 | + TranslationBlock *tb; | ||
859 | + int ret; | ||
860 | + unsigned long pc; | ||
861 | + CPUState *saved_env; | ||
862 | + | ||
863 | + /* XXX: hack to restore env in all cases, even if not called from | ||
864 | + generated code */ | ||
865 | + saved_env = env; | ||
866 | + env = cpu_single_env; | ||
867 | + | ||
868 | + ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1); | ||
869 | + if (ret) { | ||
870 | + if (retaddr) { | ||
871 | + /* now we have a real cpu fault */ | ||
872 | + pc = (unsigned long)retaddr; | ||
873 | + tb = tb_find_pc(pc); | ||
874 | + if (tb) { | ||
875 | + /* the PC is inside the translated code. It means that we have | ||
876 | + a virtual CPU fault */ | ||
877 | + cpu_restore_state(tb, env, pc, (void *)T2); | ||
878 | + } | ||
879 | + } | ||
880 | + cpu_loop_exit(); | ||
881 | + } | ||
882 | + env = saved_env; | ||
883 | +} | ||
884 | + | ||
885 | +#endif |