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 | 72 | void do_interrupt(int intno); |
73 | 73 | void raise_exception(int tt); |
74 | 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 | 77 | void helper_debug(); |
78 | 78 | void do_wrpsr(); |
79 | 79 | void do_rdpsr(); | ... | ... |
target-sparc/helper.c
... | ... | @@ -17,7 +17,16 @@ |
17 | 17 | * License along with this library; if not, write to the Free Software |
18 | 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 | 31 | //#define DEBUG_PCALL |
23 | 32 | //#define DEBUG_MMU |
... | ... | @@ -52,55 +61,6 @@ int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, |
52 | 61 | |
53 | 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 | 64 | #ifndef TARGET_SPARC64 |
105 | 65 | static const int access_table[8][8] = { |
106 | 66 | { 0, 0, 0, 0, 2, 0, 3, 3 }, |
... | ... | @@ -412,131 +372,8 @@ void memcpy32(target_ulong *dst, const target_ulong *src) |
412 | 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 | 378 | target_phys_addr_t pde_ptr; |
542 | 379 | uint32_t pde; |
... | ... | @@ -599,7 +436,7 @@ target_ulong mmu_probe(target_ulong address, int mmulev) |
599 | 436 | } |
600 | 437 | |
601 | 438 | #ifdef DEBUG_MMU |
602 | -void dump_mmu(void) | |
439 | +void dump_mmu(CPUState *env) | |
603 | 440 | { |
604 | 441 | target_ulong va, va1, va2; |
605 | 442 | unsigned int n, m, o; |
... | ... | @@ -611,17 +448,17 @@ void dump_mmu(void) |
611 | 448 | pde = ldl_phys(pde_ptr); |
612 | 449 | printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); |
613 | 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 | 452 | if (pde_ptr) { |
616 | 453 | pa = cpu_get_phys_page_debug(env, va); |
617 | 454 | printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); |
618 | 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 | 457 | if (pde_ptr) { |
621 | 458 | pa = cpu_get_phys_page_debug(env, va1); |
622 | 459 | printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); |
623 | 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 | 462 | if (pde_ptr) { |
626 | 463 | pa = cpu_get_phys_page_debug(env, va2); |
627 | 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 | 234 | if (mmulev > 4) |
235 | 235 | ret = 0; |
236 | 236 | else { |
237 | - ret = mmu_probe(T0, mmulev); | |
237 | + ret = mmu_probe(env, T0, mmulev); | |
238 | 238 | //bswap32s(&ret); |
239 | 239 | } |
240 | 240 | #ifdef DEBUG_MMU |
... | ... | @@ -293,7 +293,7 @@ void helper_st_asi(int asi, int size, int sign) |
293 | 293 | break; |
294 | 294 | } |
295 | 295 | #ifdef DEBUG_MMU |
296 | - dump_mmu(); | |
296 | + dump_mmu(env); | |
297 | 297 | #endif |
298 | 298 | return; |
299 | 299 | } |
... | ... | @@ -330,7 +330,7 @@ void helper_st_asi(int asi, int size, int sign) |
330 | 330 | if (oldreg != env->mmuregs[reg]) { |
331 | 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 | 334 | #endif |
335 | 335 | return; |
336 | 336 | } |
... | ... | @@ -508,7 +508,7 @@ void helper_st_asi(int asi, int size, int sign) |
508 | 508 | if (oldreg != env->immuregs[reg]) { |
509 | 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 | 512 | #endif |
513 | 513 | return; |
514 | 514 | } |
... | ... | @@ -576,7 +576,7 @@ void helper_st_asi(int asi, int size, int sign) |
576 | 576 | if (oldreg != env->dmmuregs[reg]) { |
577 | 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 | 580 | #endif |
581 | 581 | return; |
582 | 582 | } |
... | ... | @@ -705,3 +705,181 @@ void do_popc() |
705 | 705 | T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL); |
706 | 706 | } |
707 | 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 | ... | ... |