diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 6a2ed8b319f0..0689c0845777 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -216,7 +216,8 @@ Commands:\n\ | |||
216 | s single step\n" | 216 | s single step\n" |
217 | #ifdef CONFIG_PPC_CELL | 217 | #ifdef CONFIG_PPC_CELL |
218 | " ss stop execution on all spus\n\ | 218 | " ss stop execution on all spus\n\ |
219 | sr restore execution on stopped spus\n" | 219 | sr restore execution on stopped spus\n\ |
220 | sf # dump spu fields for spu # (in hex)\n" | ||
220 | #endif | 221 | #endif |
221 | " S print special registers\n\ | 222 | " S print special registers\n\ |
222 | t print backtrace\n\ | 223 | t print backtrace\n\ |
@@ -2744,8 +2745,66 @@ static void restart_spus(void) | |||
2744 | } | 2745 | } |
2745 | } | 2746 | } |
2746 | 2747 | ||
2748 | #define DUMP_WIDTH 23 | ||
2749 | #define DUMP_FIELD(obj, format, field) \ | ||
2750 | do { \ | ||
2751 | if (setjmp(bus_error_jmp) == 0) { \ | ||
2752 | catch_memory_errors = 1; \ | ||
2753 | sync(); \ | ||
2754 | printf(" %-*s = "format"\n", DUMP_WIDTH, \ | ||
2755 | #field, obj->field); \ | ||
2756 | sync(); \ | ||
2757 | __delay(200); \ | ||
2758 | } else { \ | ||
2759 | catch_memory_errors = 0; \ | ||
2760 | printf(" %-*s = *** Error reading field.\n", \ | ||
2761 | DUMP_WIDTH, #field); \ | ||
2762 | } \ | ||
2763 | catch_memory_errors = 0; \ | ||
2764 | } while (0) | ||
2765 | |||
2766 | static void dump_spu_fields(struct spu *spu) | ||
2767 | { | ||
2768 | printf("Dumping spu fields at address %p:\n", spu); | ||
2769 | |||
2770 | DUMP_FIELD(spu, "0x%x", number); | ||
2771 | DUMP_FIELD(spu, "%s", name); | ||
2772 | DUMP_FIELD(spu, "%s", devnode->full_name); | ||
2773 | DUMP_FIELD(spu, "0x%x", nid); | ||
2774 | DUMP_FIELD(spu, "0x%lx", local_store_phys); | ||
2775 | DUMP_FIELD(spu, "0x%p", local_store); | ||
2776 | DUMP_FIELD(spu, "0x%lx", ls_size); | ||
2777 | DUMP_FIELD(spu, "0x%x", node); | ||
2778 | DUMP_FIELD(spu, "0x%lx", flags); | ||
2779 | DUMP_FIELD(spu, "0x%lx", dar); | ||
2780 | DUMP_FIELD(spu, "0x%lx", dsisr); | ||
2781 | DUMP_FIELD(spu, "%d", class_0_pending); | ||
2782 | DUMP_FIELD(spu, "0x%lx", irqs[0]); | ||
2783 | DUMP_FIELD(spu, "0x%lx", irqs[1]); | ||
2784 | DUMP_FIELD(spu, "0x%lx", irqs[2]); | ||
2785 | DUMP_FIELD(spu, "0x%x", slb_replace); | ||
2786 | DUMP_FIELD(spu, "%d", pid); | ||
2787 | DUMP_FIELD(spu, "%d", prio); | ||
2788 | DUMP_FIELD(spu, "0x%p", mm); | ||
2789 | DUMP_FIELD(spu, "0x%p", ctx); | ||
2790 | DUMP_FIELD(spu, "0x%p", rq); | ||
2791 | DUMP_FIELD(spu, "0x%p", timestamp); | ||
2792 | DUMP_FIELD(spu, "0x%lx", problem_phys); | ||
2793 | DUMP_FIELD(spu, "0x%p", problem); | ||
2794 | DUMP_FIELD(spu, "0x%x", problem->spu_runcntl_RW); | ||
2795 | DUMP_FIELD(spu, "0x%x", problem->spu_status_R); | ||
2796 | DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW); | ||
2797 | DUMP_FIELD(spu, "0x%p", priv1); | ||
2798 | |||
2799 | if (spu->priv1) | ||
2800 | DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW); | ||
2801 | |||
2802 | DUMP_FIELD(spu, "0x%p", priv2); | ||
2803 | } | ||
2804 | |||
2747 | static int do_spu_cmd(void) | 2805 | static int do_spu_cmd(void) |
2748 | { | 2806 | { |
2807 | unsigned long num = 0; | ||
2749 | int cmd; | 2808 | int cmd; |
2750 | 2809 | ||
2751 | cmd = inchar(); | 2810 | cmd = inchar(); |
@@ -2756,6 +2815,12 @@ static int do_spu_cmd(void) | |||
2756 | case 'r': | 2815 | case 'r': |
2757 | restart_spus(); | 2816 | restart_spus(); |
2758 | break; | 2817 | break; |
2818 | case 'f': | ||
2819 | if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu) | ||
2820 | dump_spu_fields(spu_info[num].spu); | ||
2821 | else | ||
2822 | printf("*** Error: invalid spu number\n"); | ||
2823 | break; | ||
2759 | default: | 2824 | default: |
2760 | return -1; | 2825 | return -1; |
2761 | } | 2826 | } |