Commit 8543e2cfce168af5499f27f322a3433888a62a18
1 parent
80be36b8
Improved ASI debugging (Robert Reif)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3868 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
58 additions
and
14 deletions
target-sparc/op_helper.c
| @@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
| 6 | //#define DEBUG_MXCC | 6 | //#define DEBUG_MXCC |
| 7 | //#define DEBUG_UNALIGNED | 7 | //#define DEBUG_UNALIGNED |
| 8 | //#define DEBUG_UNASSIGNED | 8 | //#define DEBUG_UNASSIGNED |
| 9 | +//#define DEBUG_ASI | ||
| 9 | 10 | ||
| 10 | #ifdef DEBUG_MMU | 11 | #ifdef DEBUG_MMU |
| 11 | #define DPRINTF_MMU(fmt, args...) \ | 12 | #define DPRINTF_MMU(fmt, args...) \ |
| @@ -21,6 +22,13 @@ do { printf("MXCC: " fmt , ##args); } while (0) | @@ -21,6 +22,13 @@ do { printf("MXCC: " fmt , ##args); } while (0) | ||
| 21 | #define DPRINTF_MXCC(fmt, args...) | 22 | #define DPRINTF_MXCC(fmt, args...) |
| 22 | #endif | 23 | #endif |
| 23 | 24 | ||
| 25 | +#ifdef DEBUG_ASI | ||
| 26 | +#define DPRINTF_ASI(fmt, args...) \ | ||
| 27 | +do { printf("ASI: " fmt , ##args); } while (0) | ||
| 28 | +#else | ||
| 29 | +#define DPRINTF_ASI(fmt, args...) | ||
| 30 | +#endif | ||
| 31 | + | ||
| 24 | void raise_exception(int tt) | 32 | void raise_exception(int tt) |
| 25 | { | 33 | { |
| 26 | env->exception_index = tt; | 34 | env->exception_index = tt; |
| @@ -229,11 +237,34 @@ static void dump_mxcc(CPUState *env) | @@ -229,11 +237,34 @@ static void dump_mxcc(CPUState *env) | ||
| 229 | } | 237 | } |
| 230 | #endif | 238 | #endif |
| 231 | 239 | ||
| 240 | +#ifdef DEBUG_ASI | ||
| 241 | +static void dump_asi(const char * txt, uint32_t addr, int asi, int size, | ||
| 242 | + uint32_t r1, uint32_t r2) | ||
| 243 | +{ | ||
| 244 | + switch (size) | ||
| 245 | + { | ||
| 246 | + case 1: | ||
| 247 | + DPRINTF_ASI("%s %08x asi 0x%02x = %02x\n", txt, addr, asi, r1 & 0xff); | ||
| 248 | + break; | ||
| 249 | + case 2: | ||
| 250 | + DPRINTF_ASI("%s %08x asi 0x%02x = %04x\n", txt, addr, asi, r1 & 0xffff); | ||
| 251 | + break; | ||
| 252 | + case 4: | ||
| 253 | + DPRINTF_ASI("%s %08x asi 0x%02x = %08x\n", txt, addr, asi, r1); | ||
| 254 | + break; | ||
| 255 | + case 8: | ||
| 256 | + DPRINTF_ASI("%s %08x asi 0x%02x = %016llx\n", txt, addr, asi, | ||
| 257 | + r2 | ((uint64_t)r1 << 32)); | ||
| 258 | + break; | ||
| 259 | + } | ||
| 260 | +} | ||
| 261 | +#endif | ||
| 262 | + | ||
| 232 | void helper_ld_asi(int asi, int size, int sign) | 263 | void helper_ld_asi(int asi, int size, int sign) |
| 233 | { | 264 | { |
| 234 | uint32_t ret = 0; | 265 | uint32_t ret = 0; |
| 235 | uint64_t tmp; | 266 | uint64_t tmp; |
| 236 | -#ifdef DEBUG_MXCC | 267 | +#if defined(DEBUG_MXCC) || defined(DEBUG_ASI) |
| 237 | uint32_t last_T0 = T0; | 268 | uint32_t last_T0 = T0; |
| 238 | #endif | 269 | #endif |
| 239 | 270 | ||
| @@ -416,7 +447,7 @@ void helper_ld_asi(int asi, int size, int sign) | @@ -416,7 +447,7 @@ void helper_ld_asi(int asi, int size, int sign) | ||
| 416 | break; | 447 | break; |
| 417 | case 0x21 ... 0x2d: /* MMU passthrough, unassigned */ | 448 | case 0x21 ... 0x2d: /* MMU passthrough, unassigned */ |
| 418 | default: | 449 | default: |
| 419 | - do_unassigned_access(T0, 0, 0, 1); | 450 | + do_unassigned_access(T0, 0, 0, asi); |
| 420 | ret = 0; | 451 | ret = 0; |
| 421 | break; | 452 | break; |
| 422 | } | 453 | } |
| @@ -435,6 +466,9 @@ void helper_ld_asi(int asi, int size, int sign) | @@ -435,6 +466,9 @@ void helper_ld_asi(int asi, int size, int sign) | ||
| 435 | } | 466 | } |
| 436 | else | 467 | else |
| 437 | T1 = ret; | 468 | T1 = ret; |
| 469 | +#ifdef DEBUG_ASI | ||
| 470 | + dump_asi("read ", last_T0, asi, size, T1, T0); | ||
| 471 | +#endif | ||
| 438 | } | 472 | } |
| 439 | 473 | ||
| 440 | void helper_st_asi(int asi, int size) | 474 | void helper_st_asi(int asi, int size) |
| @@ -542,8 +576,8 @@ void helper_st_asi(int asi, int size) | @@ -542,8 +576,8 @@ void helper_st_asi(int asi, int size) | ||
| 542 | #ifdef DEBUG_MMU | 576 | #ifdef DEBUG_MMU |
| 543 | dump_mmu(env); | 577 | dump_mmu(env); |
| 544 | #endif | 578 | #endif |
| 545 | - return; | ||
| 546 | } | 579 | } |
| 580 | + break; | ||
| 547 | case 4: /* write MMU regs */ | 581 | case 4: /* write MMU regs */ |
| 548 | { | 582 | { |
| 549 | int reg = (T0 >> 8) & 0x1f; | 583 | int reg = (T0 >> 8) & 0x1f; |
| @@ -587,8 +621,8 @@ void helper_st_asi(int asi, int size) | @@ -587,8 +621,8 @@ void helper_st_asi(int asi, int size) | ||
| 587 | #ifdef DEBUG_MMU | 621 | #ifdef DEBUG_MMU |
| 588 | dump_mmu(env); | 622 | dump_mmu(env); |
| 589 | #endif | 623 | #endif |
| 590 | - return; | ||
| 591 | } | 624 | } |
| 625 | + break; | ||
| 592 | case 0xa: /* User data access */ | 626 | case 0xa: /* User data access */ |
| 593 | switch(size) { | 627 | switch(size) { |
| 594 | case 1: | 628 | case 1: |
| @@ -646,7 +680,7 @@ void helper_st_asi(int asi, int size) | @@ -646,7 +680,7 @@ void helper_st_asi(int asi, int size) | ||
| 646 | stl_kernel(dst, temp); | 680 | stl_kernel(dst, temp); |
| 647 | } | 681 | } |
| 648 | } | 682 | } |
| 649 | - return; | 683 | + break; |
| 650 | case 0x1f: /* Block fill, stda access */ | 684 | case 0x1f: /* Block fill, stda access */ |
| 651 | { | 685 | { |
| 652 | // value (T1, T2) | 686 | // value (T1, T2) |
| @@ -661,7 +695,7 @@ void helper_st_asi(int asi, int size) | @@ -661,7 +695,7 @@ void helper_st_asi(int asi, int size) | ||
| 661 | for (i = 0; i < 32; i += 8, dst += 8) | 695 | for (i = 0; i < 32; i += 8, dst += 8) |
| 662 | stq_kernel(dst, val); | 696 | stq_kernel(dst, val); |
| 663 | } | 697 | } |
| 664 | - return; | 698 | + break; |
| 665 | case 0x20: /* MMU passthrough */ | 699 | case 0x20: /* MMU passthrough */ |
| 666 | { | 700 | { |
| 667 | switch(size) { | 701 | switch(size) { |
| @@ -680,7 +714,7 @@ void helper_st_asi(int asi, int size) | @@ -680,7 +714,7 @@ void helper_st_asi(int asi, int size) | ||
| 680 | break; | 714 | break; |
| 681 | } | 715 | } |
| 682 | } | 716 | } |
| 683 | - return; | 717 | + break; |
| 684 | case 0x2e: /* MMU passthrough, 0xexxxxxxxx */ | 718 | case 0x2e: /* MMU passthrough, 0xexxxxxxxx */ |
| 685 | case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */ | 719 | case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */ |
| 686 | { | 720 | { |
| @@ -705,7 +739,7 @@ void helper_st_asi(int asi, int size) | @@ -705,7 +739,7 @@ void helper_st_asi(int asi, int size) | ||
| 705 | break; | 739 | break; |
| 706 | } | 740 | } |
| 707 | } | 741 | } |
| 708 | - return; | 742 | + break; |
| 709 | case 0x30: /* store buffer tags */ | 743 | case 0x30: /* store buffer tags */ |
| 710 | case 0x31: /* store buffer data or Ross RT620 I-cache flush */ | 744 | case 0x31: /* store buffer data or Ross RT620 I-cache flush */ |
| 711 | case 0x32: /* store buffer control */ | 745 | case 0x32: /* store buffer control */ |
| @@ -717,9 +751,12 @@ void helper_st_asi(int asi, int size) | @@ -717,9 +751,12 @@ void helper_st_asi(int asi, int size) | ||
| 717 | case 9: /* Supervisor code access, XXX */ | 751 | case 9: /* Supervisor code access, XXX */ |
| 718 | case 0x21 ... 0x2d: /* MMU passthrough, unassigned */ | 752 | case 0x21 ... 0x2d: /* MMU passthrough, unassigned */ |
| 719 | default: | 753 | default: |
| 720 | - do_unassigned_access(T0, 1, 0, 1); | ||
| 721 | - return; | 754 | + do_unassigned_access(T0, 1, 0, asi); |
| 755 | + break; | ||
| 722 | } | 756 | } |
| 757 | +#ifdef DEBUG_ASI | ||
| 758 | + dump_asi("write", T0, asi, size, T1, T2); | ||
| 759 | +#endif | ||
| 723 | } | 760 | } |
| 724 | 761 | ||
| 725 | #endif /* CONFIG_USER_ONLY */ | 762 | #endif /* CONFIG_USER_ONLY */ |
| @@ -1832,6 +1869,17 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | @@ -1832,6 +1869,17 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | ||
| 1832 | generated code */ | 1869 | generated code */ |
| 1833 | saved_env = env; | 1870 | saved_env = env; |
| 1834 | env = cpu_single_env; | 1871 | env = cpu_single_env; |
| 1872 | +#ifdef DEBUG_UNASSIGNED | ||
| 1873 | + if (is_asi) | ||
| 1874 | + printf("Unassigned mem %s access to " TARGET_FMT_plx " asi 0x%02x from " | ||
| 1875 | + TARGET_FMT_lx "\n", | ||
| 1876 | + is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi, | ||
| 1877 | + env->pc); | ||
| 1878 | + else | ||
| 1879 | + printf("Unassigned mem %s access to " TARGET_FMT_plx " from " | ||
| 1880 | + TARGET_FMT_lx "\n", | ||
| 1881 | + is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc); | ||
| 1882 | +#endif | ||
| 1835 | if (env->mmuregs[3]) /* Fault status register */ | 1883 | if (env->mmuregs[3]) /* Fault status register */ |
| 1836 | env->mmuregs[3] = 1; /* overflow (not read before another fault) */ | 1884 | env->mmuregs[3] = 1; /* overflow (not read before another fault) */ |
| 1837 | if (is_asi) | 1885 | if (is_asi) |
| @@ -1845,10 +1893,6 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | @@ -1845,10 +1893,6 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | ||
| 1845 | env->mmuregs[3] |= (5 << 2) | 2; | 1893 | env->mmuregs[3] |= (5 << 2) | 2; |
| 1846 | env->mmuregs[4] = addr; /* Fault address register */ | 1894 | env->mmuregs[4] = addr; /* Fault address register */ |
| 1847 | if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { | 1895 | if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) { |
| 1848 | -#ifdef DEBUG_UNASSIGNED | ||
| 1849 | - printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx | ||
| 1850 | - "\n", addr, env->pc); | ||
| 1851 | -#endif | ||
| 1852 | if (is_exec) | 1896 | if (is_exec) |
| 1853 | raise_exception(TT_CODE_ACCESS); | 1897 | raise_exception(TT_CODE_ACCESS); |
| 1854 | else | 1898 | else |