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 |