]> err.no Git - linux-2.6/commitdiff
powerpc: Merge xmon
authorPaul Mackerras <paulus@samba.org>
Fri, 28 Oct 2005 12:53:37 +0000 (22:53 +1000)
committerPaul Mackerras <paulus@samba.org>
Fri, 28 Oct 2005 12:53:37 +0000 (22:53 +1000)
The merged version follows the ppc64 version pretty closely mostly,
and in fact ARCH=ppc64 now uses the arch/powerpc/xmon version.
The main difference for ppc64 is that the 'p' command to call
show_state (which was always pretty dodgy) has been replaced by
the ppc32 'p' command, which calls a given procedure (so in fact
the old 'p' command behaviour can be achieved with 'p $show_state').

Signed-off-by: Paul Mackerras <paulus@samba.org>
24 files changed:
arch/powerpc/Makefile
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/lib/Makefile
arch/powerpc/xmon/Makefile [new file with mode: 0644]
arch/powerpc/xmon/ansidecl.h [moved from arch/ppc64/xmon/ansidecl.h with 100% similarity]
arch/powerpc/xmon/nonstdio.h [moved from arch/ppc64/xmon/nonstdio.h with 100% similarity]
arch/powerpc/xmon/ppc-dis.c [moved from arch/ppc64/xmon/ppc-dis.c with 100% similarity]
arch/powerpc/xmon/ppc-opc.c [moved from arch/ppc64/xmon/ppc-opc.c with 100% similarity]
arch/powerpc/xmon/ppc.h [moved from arch/ppc64/xmon/ppc.h with 100% similarity]
arch/powerpc/xmon/setjmp.S [new file with mode: 0644]
arch/powerpc/xmon/start_32.c [new file with mode: 0644]
arch/powerpc/xmon/start_64.c [moved from arch/ppc64/xmon/start.c with 100% similarity]
arch/powerpc/xmon/start_8xx.c [new file with mode: 0644]
arch/powerpc/xmon/subr_prf.c [moved from arch/ppc64/xmon/subr_prf.c with 84% similarity]
arch/powerpc/xmon/xmon.c [moved from arch/ppc64/xmon/xmon.c with 90% similarity]
arch/ppc64/Makefile
arch/ppc64/xmon/Makefile [deleted file]
arch/ppc64/xmon/setjmp.S [deleted file]
include/asm-powerpc/ppc_asm.h
include/asm-powerpc/reg.h
include/asm-powerpc/xmon.h

index dedf1219761a195662ea15d2541764cb23077bae..29cda0732703ccf3327dc793570aeb39303f36ee 100644 (file)
@@ -131,7 +131,7 @@ core-y                              += arch/powerpc/kernel/ \
                                   arch/powerpc/sysdev/ \
                                   arch/powerpc/platforms/
 core-$(CONFIG_MATH_EMULATION)  += arch/ppc/math-emu/
-#core-$(CONFIG_XMON)           += arch/powerpc/xmon/
+core-$(CONFIG_XMON)            += arch/powerpc/xmon/
 core-$(CONFIG_APUS)            += arch/ppc/amiga/
 drivers-$(CONFIG_8xx)          += arch/ppc/8xx_io/
 drivers-$(CONFIG_4xx)          += arch/ppc/4xx_io/
index 600ea19d08b58134ca5f4b6045a4cfd045899416..b102e3a2415e1fe339324745e4c3a6df75530a8d 100644 (file)
@@ -271,6 +271,9 @@ __secondary_hold_acknowledge:
        li      r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
        MTMSRD(r10);                    /* (except for mach check in rtas) */ \
        stw     r0,GPR0(r11);   \
+       lis     r10,0x7265;             /* put exception frame marker */ \
+       addi    r10,r10,0x6773; \
+       stw     r10,8(r11);     \
        SAVE_4GPRS(3, r11);     \
        SAVE_2GPRS(7, r11)
 
index 5f3a12bb8961df872c35937fb72825024a9672fb..8bc540337ba086a4d4b81a65d4d3bf1ba0fd9d4a 100644 (file)
@@ -44,7 +44,6 @@
 #include <asm/cputable.h>
 #include <asm/btext.h>
 #include <asm/div64.h>
-#include <asm/xmon.h>
 
 #ifdef  CONFIG_8xx
 #include <asm/commproc.h>
@@ -238,10 +237,6 @@ EXPORT_SYMBOL(console_drivers);
 EXPORT_SYMBOL(cacheable_memcpy);
 #endif
 
-#ifdef CONFIG_XMON
-EXPORT_SYMBOL(xmon);
-EXPORT_SYMBOL(xmon_printf);
-#endif
 EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
index 7c99e6b8c76cd018b6cf4582ac212d045a992f2c..9680ae99b0845d5cd394e18400cdb68025b12474 100644 (file)
@@ -302,8 +302,10 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_XMON
        xmon_map_scc();
-       if (strstr(cmd_line, "xmon"))
-               xmon(NULL);
+       if (strstr(cmd_line, "xmon")) {
+               xmon_init(1);
+               debugger(NULL);
+       }
 #endif /* CONFIG_XMON */
        if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
 
index 950e6f0fea985b1d3659f9e2c492025f72947441..681537f8ea105afe35e3c3faaa837f03317633ca 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/iSeries/ItLpNaca.h>
 #include <asm/firmware.h>
 #include <asm/systemcfg.h>
+#include <asm/xmon.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
index 0115bf96751c1706c21009979ac0e59266ab1748..e6b2be3bcec1469816a8046b49cb572b04b09913 100644 (file)
@@ -11,6 +11,8 @@ obj-$(CONFIG_PPC32)   += div64.o copy_32.o checksum_32.o
 obj-$(CONFIG_PPC64)    += checksum_64.o copypage_64.o copyuser_64.o \
                           memcpy_64.o usercopy_64.o mem_64.o
 obj-$(CONFIG_PPC_ISERIES) += e2a.o
+obj-$(CONFIG_XMON)     += sstep.o
+
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)      += locks.o
 obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
new file mode 100644 (file)
index 0000000..79a784f
--- /dev/null
@@ -0,0 +1,11 @@
+# Makefile for xmon
+
+ifdef CONFIG_PPC64
+EXTRA_CFLAGS += -mno-minimal-toc
+endif
+
+obj-$(CONFIG_8xx)      += start_8xx.o
+obj-$(CONFIG_6xx)      += start_32.o
+obj-$(CONFIG_4xx)      += start_32.o
+obj-$(CONFIG_PPC64)    += start_64.o
+obj-y                  += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S
new file mode 100644 (file)
index 0000000..f8e40df
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ * NOTE: assert(sizeof(buf) > 23 * sizeof(long))
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+_GLOBAL(xmon_setjmp)
+       mflr    r0
+       STL     r0,0(r3)
+       STL     r1,SZL(r3)
+       STL     r2,2*SZL(r3)
+       mfcr    r0
+       STL     r0,3*SZL(r3)
+       STL     r13,4*SZL(r3)
+       STL     r14,5*SZL(r3)
+       STL     r15,6*SZL(r3)
+       STL     r16,7*SZL(r3)
+       STL     r17,8*SZL(r3)
+       STL     r18,9*SZL(r3)
+       STL     r19,10*SZL(r3)
+       STL     r20,11*SZL(r3)
+       STL     r21,12*SZL(r3)
+       STL     r22,13*SZL(r3)
+       STL     r23,14*SZL(r3)
+       STL     r24,15*SZL(r3)
+       STL     r25,16*SZL(r3)
+       STL     r26,17*SZL(r3)
+       STL     r27,18*SZL(r3)
+       STL     r28,19*SZL(r3)
+       STL     r29,20*SZL(r3)
+       STL     r30,21*SZL(r3)
+       STL     r31,22*SZL(r3)
+       li      r3,0
+       blr
+
+_GLOBAL(xmon_longjmp)
+       CMPI    r4,0
+       bne     1f
+       li      r4,1
+1:     LDL     r13,4*SZL(r3)
+       LDL     r14,5*SZL(r3)
+       LDL     r15,6*SZL(r3)
+       LDL     r16,7*SZL(r3)
+       LDL     r17,8*SZL(r3)
+       LDL     r18,9*SZL(r3)
+       LDL     r19,10*SZL(r3)
+       LDL     r20,11*SZL(r3)
+       LDL     r21,12*SZL(r3)
+       LDL     r22,13*SZL(r3)
+       LDL     r23,14*SZL(r3)
+       LDL     r24,15*SZL(r3)
+       LDL     r25,16*SZL(r3)
+       LDL     r26,17*SZL(r3)
+       LDL     r27,18*SZL(r3)
+       LDL     r28,19*SZL(r3)
+       LDL     r29,20*SZL(r3)
+       LDL     r30,21*SZL(r3)
+       LDL     r31,22*SZL(r3)
+       LDL     r0,3*SZL(r3)
+       mtcrf   0x38,r0
+       LDL     r0,0(r3)
+       LDL     r1,SZL(r3)
+       LDL     r2,2*SZL(r3)
+       mtlr    r0
+       mr      r3,r4
+       blr
+
+/*
+ * Grab the register values as they are now.
+ * This won't do a particularily good job because we really
+ * want our caller's caller's registers, and our caller has
+ * already executed its prologue.
+ * ToDo: We could reach back into the caller's save area to do
+ * a better job of representing the caller's state (note that
+ * that will be different for 32-bit and 64-bit, because of the
+ * different ABIs, though).
+ */
+_GLOBAL(xmon_save_regs)
+       STL     r0,0*SZL(r3)
+       STL     r2,2*SZL(r3)
+       STL     r3,3*SZL(r3)
+       STL     r4,4*SZL(r3)
+       STL     r5,5*SZL(r3)
+       STL     r6,6*SZL(r3)
+       STL     r7,7*SZL(r3)
+       STL     r8,8*SZL(r3)
+       STL     r9,9*SZL(r3)
+       STL     r10,10*SZL(r3)
+       STL     r11,11*SZL(r3)
+       STL     r12,12*SZL(r3)
+       STL     r13,13*SZL(r3)
+       STL     r14,14*SZL(r3)
+       STL     r15,15*SZL(r3)
+       STL     r16,16*SZL(r3)
+       STL     r17,17*SZL(r3)
+       STL     r18,18*SZL(r3)
+       STL     r19,19*SZL(r3)
+       STL     r20,20*SZL(r3)
+       STL     r21,21*SZL(r3)
+       STL     r22,22*SZL(r3)
+       STL     r23,23*SZL(r3)
+       STL     r24,24*SZL(r3)
+       STL     r25,25*SZL(r3)
+       STL     r26,26*SZL(r3)
+       STL     r27,27*SZL(r3)
+       STL     r28,28*SZL(r3)
+       STL     r29,29*SZL(r3)
+       STL     r30,30*SZL(r3)
+       STL     r31,31*SZL(r3)
+       /* go up one stack frame for SP */
+       LDL     r4,0(r1)
+       STL     r4,1*SZL(r3)
+       /* get caller's LR */
+       LDL     r0,LRSAVE(r4)
+       STL     r0,_NIP-STACK_FRAME_OVERHEAD(r3)
+       STL     r0,_LINK-STACK_FRAME_OVERHEAD(r3)
+       mfmsr   r0
+       STL     r0,_MSR-STACK_FRAME_OVERHEAD(r3)
+       mfctr   r0
+       STL     r0,_CTR-STACK_FRAME_OVERHEAD(r3)
+       mfxer   r0
+       STL     r0,_XER-STACK_FRAME_OVERHEAD(r3)
+       mfcr    r0
+       STL     r0,_CCR-STACK_FRAME_OVERHEAD(r3)
+       li      r0,0
+       STL     r0,_TRAP-STACK_FRAME_OVERHEAD(r3)
+       blr
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
new file mode 100644 (file)
index 0000000..69b658c
--- /dev/null
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/cuda.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sysrq.h>
+#include <linux/bitops.h>
+#include <asm/xmon.h>
+#include <asm/prom.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/errno.h>
+#include <asm/pmac_feature.h>
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/btext.h>
+
+static volatile unsigned char __iomem *sccc, *sccd;
+unsigned int TXRDY, RXRDY, DLAB;
+static int xmon_expect(const char *str, unsigned int timeout);
+
+static int use_serial;
+static int use_screen;
+static int via_modem;
+static int xmon_use_sccb;
+static struct device_node *channel_node;
+
+#define TB_SPEED       25000000
+
+static inline unsigned int readtb(void)
+{
+       unsigned int ret;
+
+       asm volatile("mftb %0" : "=r" (ret) :);
+       return ret;
+}
+
+void buf_access(void)
+{
+       if (DLAB)
+               sccd[3] &= ~DLAB;       /* reset DLAB */
+}
+
+extern int adb_init(void);
+
+#ifdef CONFIG_PPC_CHRP
+/*
+ * This looks in the "ranges" property for the primary PCI host bridge
+ * to find the physical address of the start of PCI/ISA I/O space.
+ * It is basically a cut-down version of pci_process_bridge_OF_ranges.
+ */
+static unsigned long chrp_find_phys_io_base(void)
+{
+       struct device_node *node;
+       unsigned int *ranges;
+       unsigned long base = CHRP_ISA_IO_BASE;
+       int rlen = 0;
+       int np;
+
+       node = find_devices("isa");
+       if (node != NULL) {
+               node = node->parent;
+               if (node == NULL || node->type == NULL
+                   || strcmp(node->type, "pci") != 0)
+                       node = NULL;
+       }
+       if (node == NULL)
+               node = find_devices("pci");
+       if (node == NULL)
+               return base;
+
+       ranges = (unsigned int *) get_property(node, "ranges", &rlen);
+       np = prom_n_addr_cells(node) + 5;
+       while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+               if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
+                       /* I/O space starting at 0, grab the phys base */
+                       base = ranges[np - 3];
+                       break;
+               }
+               ranges += np;
+       }
+       return base;
+}
+#endif /* CONFIG_PPC_CHRP */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_handle_xmon(int key, struct pt_regs *regs,
+                             struct tty_struct *tty)
+{
+       xmon(regs);
+}
+
+static struct sysrq_key_op sysrq_xmon_op =
+{
+       .handler =      sysrq_handle_xmon,
+       .help_msg =     "Xmon",
+       .action_msg =   "Entering xmon",
+};
+#endif
+
+void
+xmon_map_scc(void)
+{
+#ifdef CONFIG_PPC_MULTIPLATFORM
+       volatile unsigned char __iomem *base;
+
+       if (_machine == _MACH_Pmac) {
+               struct device_node *np;
+               unsigned long addr;
+#ifdef CONFIG_BOOTX_TEXT
+               if (!use_screen && !use_serial
+                   && !machine_is_compatible("iMac")) {
+                       /* see if there is a keyboard in the device tree
+                          with a parent of type "adb" */
+                       for (np = find_devices("keyboard"); np; np = np->next)
+                               if (np->parent && np->parent->type
+                                   && strcmp(np->parent->type, "adb") == 0)
+                                       break;
+
+                       /* needs to be hacked if xmon_printk is to be used
+                          from within find_via_pmu() */
+#ifdef CONFIG_ADB_PMU
+                       if (np != NULL && boot_text_mapped && find_via_pmu())
+                               use_screen = 1;
+#endif
+#ifdef CONFIG_ADB_CUDA
+                       if (np != NULL && boot_text_mapped && find_via_cuda())
+                               use_screen = 1;
+#endif
+               }
+               if (!use_screen && (np = find_devices("escc")) != NULL) {
+                       /*
+                        * look for the device node for the serial port
+                        * we're using and see if it says it has a modem
+                        */
+                       char *name = xmon_use_sccb? "ch-b": "ch-a";
+                       char *slots;
+                       int l;
+
+                       np = np->child;
+                       while (np != NULL && strcmp(np->name, name) != 0)
+                               np = np->sibling;
+                       if (np != NULL) {
+                               /* XXX should parse this properly */
+                               channel_node = np;
+                               slots = get_property(np, "slot-names", &l);
+                               if (slots != NULL && l >= 10
+                                   && strcmp(slots+4, "Modem") == 0)
+                                       via_modem = 1;
+                       }
+               }
+               btext_drawstring("xmon uses ");
+               if (use_screen)
+                       btext_drawstring("screen and keyboard\n");
+               else {
+                       if (via_modem)
+                               btext_drawstring("modem on ");
+                       btext_drawstring(xmon_use_sccb? "printer": "modem");
+                       btext_drawstring(" port\n");
+               }
+
+#endif /* CONFIG_BOOTX_TEXT */
+
+#ifdef CHRP_ESCC
+               addr = 0xc1013020;
+#else
+               addr = 0xf3013020;
+#endif
+               TXRDY = 4;
+               RXRDY = 1;
+       
+               np = find_devices("mac-io");
+               if (np && np->n_addrs)
+                       addr = np->addrs[0].address + 0x13020;
+               base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
+               sccc = base + (addr & ~PAGE_MASK);
+               sccd = sccc + 0x10;
+
+       } else {
+               base = (volatile unsigned char *) isa_io_base;
+
+#ifdef CONFIG_PPC_CHRP
+               if (_machine == _MACH_chrp)
+                       base = (volatile unsigned char __iomem *)
+                               ioremap(chrp_find_phys_io_base(), 0x1000);
+#endif
+
+               sccc = base + 0x3fd;
+               sccd = base + 0x3f8;
+               if (xmon_use_sccb) {
+                       sccc -= 0x100;
+                       sccd -= 0x100;
+               }
+               TXRDY = 0x20;
+               RXRDY = 1;
+               DLAB = 0x80;
+       }
+#elif defined(CONFIG_GEMINI)
+       /* should already be mapped by the kernel boot */
+       sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
+       sccd = (volatile unsigned char __iomem *) 0xffeffb08;
+       TXRDY = 0x20;
+       RXRDY = 1;
+       DLAB = 0x80;
+#elif defined(CONFIG_405GP)
+       sccc = (volatile unsigned char __iomem *)0xef600305;
+       sccd = (volatile unsigned char __iomem *)0xef600300;
+       TXRDY = 0x20;
+       RXRDY = 1;
+       DLAB = 0x80;
+#endif /* platform */
+
+       register_sysrq_key('x', &sysrq_xmon_op);
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+extern void cuda_poll(void);
+
+static inline void do_poll_adb(void)
+{
+#ifdef CONFIG_ADB_PMU
+       if (sys_ctrler == SYS_CTRLER_PMU)
+               pmu_poll_adb();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+       if (sys_ctrler == SYS_CTRLER_CUDA)
+               cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+       char *p = ptr;
+       int i, c, ct;
+
+#ifdef CONFIG_SMP
+       static unsigned long xmon_write_lock;
+       int lock_wait = 1000000;
+       int locked;
+
+       while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
+               if (--lock_wait == 0)
+                       break;
+#endif
+
+#ifdef CONFIG_BOOTX_TEXT
+       if (use_screen) {
+               /* write it on the screen */
+               for (i = 0; i < nb; ++i)
+                       btext_drawchar(*p++);
+               goto out;
+       }
+#endif
+       if (!scc_initialized)
+               xmon_init_scc();
+       ct = 0;
+       for (i = 0; i < nb; ++i) {
+               while ((*sccc & TXRDY) == 0)
+                       do_poll_adb();
+               c = p[i];
+               if (c == '\n' && !ct) {
+                       c = '\r';
+                       ct = 1;
+                       --i;
+               } else {
+                       ct = 0;
+               }
+               buf_access();
+               *sccd = c;
+               eieio();
+       }
+
+ out:
+#ifdef CONFIG_SMP
+       if (!locked)
+               clear_bit(0, &xmon_write_lock);
+#endif
+       return nb;
+}
+
+int xmon_wants_key;
+int xmon_adb_keycode;
+
+#ifdef CONFIG_BOOTX_TEXT
+static int xmon_adb_shiftstate;
+
+static unsigned char xmon_keytab[128] =
+       "asdfhgzxcv\000bqwer"                           /* 0x00 - 0x0f */
+       "yt123465=97-80]o"                              /* 0x10 - 0x1f */
+       "u[ip\rlj'k;\\,/nm."                            /* 0x20 - 0x2f */
+       "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
+       "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
+       "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
+
+static unsigned char xmon_shift_keytab[128] =
+       "ASDFHGZXCV\000BQWER"                           /* 0x00 - 0x0f */
+       "YT!@#$^%+(&_*)}O"                              /* 0x10 - 0x1f */
+       "U{IP\rLJ\"K:|<?NM>"                            /* 0x20 - 0x2f */
+       "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
+       "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
+       "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
+
+static int
+xmon_get_adb_key(void)
+{
+       int k, t, on;
+
+       xmon_wants_key = 1;
+       for (;;) {
+               xmon_adb_keycode = -1;
+               t = 0;
+               on = 0;
+               do {
+                       if (--t < 0) {
+                               on = 1 - on;
+                               btext_drawchar(on? 0xdb: 0x20);
+                               btext_drawchar('\b');
+                               t = 200000;
+                       }
+                       do_poll_adb();
+               } while (xmon_adb_keycode == -1);
+               k = xmon_adb_keycode;
+               if (on)
+                       btext_drawstring(" \b");
+
+               /* test for shift keys */
+               if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
+                       xmon_adb_shiftstate = (k & 0x80) == 0;
+                       continue;
+               }
+               if (k >= 0x80)
+                       continue;       /* ignore up transitions */
+               k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
+               if (k != 0)
+                       break;
+       }
+       xmon_wants_key = 0;
+       return k;
+}
+#endif /* CONFIG_BOOTX_TEXT */
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+    char *p = ptr;
+    int i;
+
+#ifdef CONFIG_BOOTX_TEXT
+    if (use_screen) {
+       for (i = 0; i < nb; ++i)
+           *p++ = xmon_get_adb_key();
+       return i;
+    }
+#endif
+    if (!scc_initialized)
+       xmon_init_scc();
+    for (i = 0; i < nb; ++i) {
+       while ((*sccc & RXRDY) == 0)
+           do_poll_adb();
+       buf_access();
+       *p++ = *sccd;
+    }
+    return i;
+}
+
+int
+xmon_read_poll(void)
+{
+       if ((*sccc & RXRDY) == 0) {
+               do_poll_adb();
+               return -1;
+       }
+       buf_access();
+       return *sccd;
+}
+
+static unsigned char scc_inittab[] = {
+    13, 0,             /* set baud rate divisor */
+    12, 1,
+    14, 1,             /* baud rate gen enable, src=rtxc */
+    11, 0x50,          /* clocks = br gen */
+    5,  0xea,          /* tx 8 bits, assert DTR & RTS */
+    4,  0x46,          /* x16 clock, 1 stop */
+    3,  0xc1,          /* rx enable, 8 bits */
+};
+
+void
+xmon_init_scc(void)
+{
+       if ( _machine == _MACH_chrp )
+       {
+               sccd[3] = 0x83; eieio();        /* LCR = 8N1 + DLAB */
+               sccd[0] = 12; eieio();          /* DLL = 9600 baud */
+               sccd[1] = 0; eieio();
+               sccd[2] = 0; eieio();           /* FCR = 0 */
+               sccd[3] = 3; eieio();           /* LCR = 8N1 */
+               sccd[1] = 0; eieio();           /* IER = 0 */
+       }
+       else if ( _machine == _MACH_Pmac )
+       {
+               int i, x;
+
+               if (channel_node != 0)
+                       pmac_call_feature(
+                               PMAC_FTR_SCC_ENABLE,
+                               channel_node,
+                               PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
+                       printk(KERN_INFO "Serial port locked ON by debugger !\n");
+               if (via_modem && channel_node != 0) {
+                       unsigned int t0;
+
+                       pmac_call_feature(
+                               PMAC_FTR_MODEM_ENABLE,
+                               channel_node, 0, 1);
+                       printk(KERN_INFO "Modem powered up by debugger !\n");
+                       t0 = readtb();
+                       while (readtb() - t0 < 3*TB_SPEED)
+                               eieio();
+               }
+               /* use the B channel if requested */
+               if (xmon_use_sccb) {
+                       sccc = (volatile unsigned char *)
+                               ((unsigned long)sccc & ~0x20);
+                       sccd = sccc + 0x10;
+               }
+               for (i = 20000; i != 0; --i) {
+                       x = *sccc; eieio();
+               }
+               *sccc = 9; eieio();             /* reset A or B side */
+               *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
+               for (i = 0; i < sizeof(scc_inittab); ++i) {
+                       *sccc = scc_inittab[i];
+                       eieio();
+               }
+       }
+       scc_initialized = 1;
+       if (via_modem) {
+               for (;;) {
+                       xmon_write(NULL, "ATE1V1\r", 7);
+                       if (xmon_expect("OK", 5)) {
+                               xmon_write(NULL, "ATA\r", 4);
+                               if (xmon_expect("CONNECT", 40))
+                                       break;
+                       }
+                       xmon_write(NULL, "+++", 3);
+                       xmon_expect("OK", 3);
+               }
+       }
+}
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+int xmon_putc(int c, void *f)
+{
+    char ch = c;
+
+    if (c == '\n')
+       xmon_putc('\r', f);
+    return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int xmon_putchar(int c)
+{
+       return xmon_putc(c, xmon_stdout);
+}
+
+int xmon_fputs(char *str, void *f)
+{
+       int n = strlen(str);
+
+       return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+       char ch;
+
+       for (;;) {
+               switch (xmon_read(xmon_stdin, &ch, 1)) {
+               case 1:
+                       return ch;
+               case -1:
+                       xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+                       return -1;
+               }
+       }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int xmon_expect(const char *str, unsigned int timeout)
+{
+       int c;
+       unsigned int t0;
+
+       timeout *= TB_SPEED;
+       t0 = readtb();
+       do {
+               lineptr = line;
+               for (;;) {
+                       c = xmon_read_poll();
+                       if (c == -1) {
+                               if (readtb() - t0 > timeout)
+                                       return 0;
+                               continue;
+                       }
+                       if (c == '\n')
+                               break;
+                       if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+                               *lineptr++ = c;
+               }
+               *lineptr = 0;
+       } while (strstr(line, str) == NULL);
+       return 1;
+}
+
+int
+xmon_getchar(void)
+{
+    int c;
+
+    if (lineleft == 0) {
+       lineptr = line;
+       for (;;) {
+           c = xmon_readchar();
+           if (c == -1 || c == 4)
+               break;
+           if (c == '\r' || c == '\n') {
+               *lineptr++ = '\n';
+               xmon_putchar('\n');
+               break;
+           }
+           switch (c) {
+           case 0177:
+           case '\b':
+               if (lineptr > line) {
+                   xmon_putchar('\b');
+                   xmon_putchar(' ');
+                   xmon_putchar('\b');
+                   --lineptr;
+               }
+               break;
+           case 'U' & 0x1F:
+               while (lineptr > line) {
+                   xmon_putchar('\b');
+                   xmon_putchar(' ');
+                   xmon_putchar('\b');
+                   --lineptr;
+               }
+               break;
+           default:
+               if (lineptr >= &line[sizeof(line) - 1])
+                   xmon_putchar('\a');
+               else {
+                   xmon_putchar(c);
+                   *lineptr++ = c;
+               }
+           }
+       }
+       lineleft = lineptr - line;
+       lineptr = line;
+    }
+    if (lineleft == 0)
+       return -1;
+    --lineleft;
+    return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+    char *p;
+    int c;
+
+    for (p = str; p < str + nb - 1; ) {
+       c = xmon_getchar();
+       if (c == -1) {
+           if (p == str)
+               return NULL;
+           break;
+       }
+       *p++ = c;
+       if (c == '\n')
+           break;
+    }
+    *p = 0;
+    return str;
+}
+
+void
+xmon_enter(void)
+{
+#ifdef CONFIG_ADB_PMU
+       if (_machine == _MACH_Pmac) {
+               pmu_suspend();
+       }
+#endif
+}
+
+void
+xmon_leave(void)
+{
+#ifdef CONFIG_ADB_PMU
+       if (_machine == _MACH_Pmac) {
+               pmu_resume();
+       }
+#endif
+}
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
new file mode 100644 (file)
index 0000000..a48bd59
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ * Copyright (C) 2000 Dan Malek.
+ * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
+ * of assumptions, like the SMC1 is used, it has been initialized by the
+ * loader at some point, and we can just stuff and suck bytes.
+ * We rely upon the 8xx uart driver to support us, as the interface
+ * changes between boot up and operational phases of the kernel.
+ */
+#include <linux/string.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <linux/kernel.h>
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+extern void xmon_printf(const char *fmt, ...);
+extern int xmon_8xx_write(char *str, int nb);
+extern int xmon_8xx_read_poll(void);
+extern int xmon_8xx_read_char(void);
+void prom_drawhex(uint);
+void prom_drawstring(const char *str);
+
+static int use_screen = 1; /* default */
+
+#define TB_SPEED       25000000
+
+static inline unsigned int readtb(void)
+{
+       unsigned int ret;
+
+       asm volatile("mftb %0" : "=r" (ret) :);
+       return ret;
+}
+
+void buf_access(void)
+{
+}
+
+void
+xmon_map_scc(void)
+{
+
+       cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+       use_screen = 0;
+       
+       prom_drawstring("xmon uses serial port\n");
+}
+
+static int scc_initialized = 0;
+
+void xmon_init_scc(void);
+
+int
+xmon_write(void *handle, void *ptr, int nb)
+{
+       char *p = ptr;
+       int i, c, ct;
+
+       if (!scc_initialized)
+               xmon_init_scc();
+
+       return(xmon_8xx_write(ptr, nb));
+}
+
+int xmon_wants_key;
+
+int
+xmon_read(void *handle, void *ptr, int nb)
+{
+       char *p = ptr;
+       int i;
+
+       if (!scc_initialized)
+               xmon_init_scc();
+
+       for (i = 0; i < nb; ++i) {
+               *p++ = xmon_8xx_read_char();
+       }
+       return i;
+}
+
+int
+xmon_read_poll(void)
+{
+       return(xmon_8xx_read_poll());
+}
+
+void
+xmon_init_scc()
+{
+       scc_initialized = 1;
+}
+
+#if 0
+extern int (*prom_entry)(void *);
+
+int
+xmon_exit(void)
+{
+    struct prom_args {
+       char *service;
+    } args;
+
+    for (;;) {
+       args.service = "exit";
+       (*prom_entry)(&args);
+    }
+}
+#endif
+
+void *xmon_stdin;
+void *xmon_stdout;
+void *xmon_stderr;
+
+void
+xmon_init(void)
+{
+}
+
+int
+xmon_putc(int c, void *f)
+{
+    char ch = c;
+
+    if (c == '\n')
+       xmon_putc('\r', f);
+    return xmon_write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+xmon_putchar(int c)
+{
+    return xmon_putc(c, xmon_stdout);
+}
+
+int
+xmon_fputs(char *str, void *f)
+{
+    int n = strlen(str);
+
+    return xmon_write(f, str, n) == n? 0: -1;
+}
+
+int
+xmon_readchar(void)
+{
+    char ch;
+
+    for (;;) {
+       switch (xmon_read(xmon_stdin, &ch, 1)) {
+       case 1:
+           return ch;
+       case -1:
+           xmon_printf("read(stdin) returned -1\r\n", 0, 0);
+           return -1;
+       }
+    }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+#if 0
+int xmon_expect(const char *str, unsigned int timeout)
+{
+       int c;
+       unsigned int t0;
+
+       timeout *= TB_SPEED;
+       t0 = readtb();
+       do {
+               lineptr = line;
+               for (;;) {
+                       c = xmon_read_poll();
+                       if (c == -1) {
+                               if (readtb() - t0 > timeout)
+                                       return 0;
+                               continue;
+                       }
+                       if (c == '\n')
+                               break;
+                       if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+                               *lineptr++ = c;
+               }
+               *lineptr = 0;
+       } while (strstr(line, str) == NULL);
+       return 1;
+}
+#endif
+
+int
+xmon_getchar(void)
+{
+    int c;
+
+    if (lineleft == 0) {
+       lineptr = line;
+       for (;;) {
+           c = xmon_readchar();
+           if (c == -1 || c == 4)
+               break;
+           if (c == '\r' || c == '\n') {
+               *lineptr++ = '\n';
+               xmon_putchar('\n');
+               break;
+           }
+           switch (c) {
+           case 0177:
+           case '\b':
+               if (lineptr > line) {
+                   xmon_putchar('\b');
+                   xmon_putchar(' ');
+                   xmon_putchar('\b');
+                   --lineptr;
+               }
+               break;
+           case 'U' & 0x1F:
+               while (lineptr > line) {
+                   xmon_putchar('\b');
+                   xmon_putchar(' ');
+                   xmon_putchar('\b');
+                   --lineptr;
+               }
+               break;
+           default:
+               if (lineptr >= &line[sizeof(line) - 1])
+                   xmon_putchar('\a');
+               else {
+                   xmon_putchar(c);
+                   *lineptr++ = c;
+               }
+           }
+       }
+       lineleft = lineptr - line;
+       lineptr = line;
+    }
+    if (lineleft == 0)
+       return -1;
+    --lineleft;
+    return *lineptr++;
+}
+
+char *
+xmon_fgets(char *str, int nb, void *f)
+{
+    char *p;
+    int c;
+
+    for (p = str; p < str + nb - 1; ) {
+       c = xmon_getchar();
+       if (c == -1) {
+           if (p == str)
+               return 0;
+           break;
+       }
+       *p++ = c;
+       if (c == '\n')
+           break;
+    }
+    *p = 0;
+    return str;
+}
+
+void
+prom_drawhex(uint val)
+{
+       unsigned char buf[10];
+
+       int i;
+       for (i = 7;  i >= 0;  i--)
+       {
+               buf[i] = "0123456789abcdef"[val & 0x0f];
+               val >>= 4;
+       }
+       buf[8] = '\0';
+       xmon_fputs(buf, xmon_stdout);
+}
+
+void
+prom_drawstring(const char *str)
+{
+       xmon_fputs(str, xmon_stdout);
+}
similarity index 84%
rename from arch/ppc64/xmon/subr_prf.c
rename to arch/powerpc/xmon/subr_prf.c
index 5242bd7d09594d07b03af8c13e16d1ec42deec4c..b48738c6dd3366c49f298d45fdd17c292f3df1c0 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/module.h>
 #include <stdarg.h>
 #include "nonstdio.h"
 
 extern int xmon_write(void *, void *, int);
 
-void
-xmon_vfprintf(void *f, const char *fmt, va_list ap)
+void xmon_vfprintf(void *f, const char *fmt, va_list ap)
 {
        static char xmon_buf[2048];
        int n;
@@ -33,8 +33,7 @@ xmon_vfprintf(void *f, const char *fmt, va_list ap)
        xmon_write(f, xmon_buf, n);
 }
 
-void
-xmon_printf(const char *fmt, ...)
+void xmon_printf(const char *fmt, ...)
 {
        va_list ap;
 
@@ -42,9 +41,9 @@ xmon_printf(const char *fmt, ...)
        xmon_vfprintf(stdout, fmt, ap);
        va_end(ap);
 }
+EXPORT_SYMBOL(xmon_printf);
 
-void
-xmon_fprintf(void *f, const char *fmt, ...)
+void xmon_fprintf(void *f, const char *fmt, ...)
 {
        va_list ap;
 
similarity index 90%
rename from arch/ppc64/xmon/xmon.c
rename to arch/powerpc/xmon/xmon.c
index 74e63a886a69ae4b9769cacd3b6f2df44bcec48d..d0623e0fd8ee6e377c4fbd0c1b5e60d797b8434f 100644 (file)
 #include <linux/delay.h>
 #include <linux/kallsyms.h>
 #include <linux/cpumask.h>
+#include <linux/module.h>
 
 #include <asm/ptrace.h>
 #include <asm/string.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
+#include <asm/xmon.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
 #include <asm/processor.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
-#include <asm/paca.h>
-#include <asm/ppcdebug.h>
 #include <asm/cputable.h>
 #include <asm/rtas.h>
 #include <asm/sstep.h>
 #include <asm/bug.h>
+
+#ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
+#include <asm/paca.h>
+#endif
 
 #include "nonstdio.h"
-#include "privinst.h"
 
 #define scanhex        xmon_scanhex
 #define skipbl xmon_skipbl
@@ -58,7 +64,7 @@ static unsigned long ncsum = 4096;
 static int termch;
 static char tmpstr[128];
 
-#define JMP_BUF_LEN    (184/sizeof(long))
+#define JMP_BUF_LEN    23
 static long bus_error_jmp[JMP_BUF_LEN];
 static int catch_memory_errors;
 static long *xmon_fault_jmp[NR_CPUS];
@@ -130,23 +136,36 @@ static void cacheflush(void);
 static int  cpu_cmd(void);
 static void csum(void);
 static void bootcmds(void);
+static void proccall(void);
 void dump_segments(void);
 static void symbol_lookup(void);
 static void xmon_print_symbol(unsigned long address, const char *mid,
                              const char *after);
 static const char *getvecname(unsigned long vec);
 
-static void debug_trace(void);
-
 extern int print_insn_powerpc(unsigned long, unsigned long, int);
 extern void printf(const char *fmt, ...);
 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
 extern int xmon_putc(int c, void *f);
 extern int putchar(int ch);
+
+extern void xmon_enter(void);
+extern void xmon_leave(void);
+
 extern int xmon_read_poll(void);
-extern int setjmp(long *);
-extern void longjmp(long *, int);
-extern unsigned long _ASR;
+extern long setjmp(long *);
+extern void longjmp(long *, long);
+extern void xmon_save_regs(struct pt_regs *);
+
+#ifdef CONFIG_PPC64
+#define REG            "%.16lx"
+#define REGS_PER_LINE  4
+#define LAST_VOLATILE  13
+#else
+#define REG            "%.8lx"
+#define REGS_PER_LINE  8
+#define LAST_VOLATILE  12
+#endif
 
 #define GETWORD(v)     (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
 
@@ -186,47 +205,46 @@ Commands:\n\
   ml   locate a block of memory\n\
   mz   zero a block of memory\n\
   mi   show information about memory allocation\n\
-  p    show the task list\n\
+  p    call a procedure\n\
   r    print registers\n\
   s    single step\n\
   S    print special registers\n\
   t    print backtrace\n\
   T    Enable/Disable PPCDBG flags\n\
   x    exit monitor and recover\n\
-  X    exit monitor and dont recover\n\
-  u    dump segment table or SLB\n\
-  ?    help\n"
-  "\
-  zr   reboot\n\
+  X    exit monitor and dont recover\n"
+#ifdef CONFIG_PPC64
+"  u   dump segment table or SLB\n"
+#endif
+#ifdef CONFIG_PPC_STD_MMU_32
+"  u   dump segment registers\n"
+#endif
+"  ?   help\n"
+"  zr  reboot\n\
   zh   halt\n"
 ;
 
 static struct pt_regs *xmon_regs;
 
-extern inline void sync(void)
+static inline void sync(void)
 {
        asm volatile("sync; isync");
 }
 
-/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
- A PPC stack frame looks like this:
-
- High Address
-    Back Chain
-    FP reg save area
-    GP reg save area
-    Local var space
-    Parameter save area                (SP+48)
-    TOC save area              (SP+40)
-    link editor doubleword     (SP+32)
-    compiler doubleword                (SP+24)
-    LR save                    (SP+16)
-    CR save                    (SP+8)
-    Back Chain                 (SP+0)
-
- Note that the LR (ret addr) may not be saved in the current frame if
- no functions have been called from the current function.
- */
+static inline void store_inst(void *p)
+{
+       asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
+}
+
+static inline void cflush(void *p)
+{
+       asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+       asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
 
 /*
  * Disable surveillance (the service processor watchdog function)
@@ -310,8 +328,8 @@ int xmon_core(struct pt_regs *regs, int fromipi)
        unsigned long timeout;
 #endif
 
-       msr = get_msr();
-       set_msrd(msr & ~MSR_EE);        /* disable interrupts */
+       msr = mfmsr();
+       mtmsr(msr & ~MSR_EE);   /* disable interrupts */
 
        bp = in_breakpoint_table(regs->nip, &offset);
        if (bp != NULL) {
@@ -487,7 +505,7 @@ int xmon_core(struct pt_regs *regs, int fromipi)
 
        insert_cpu_bpts();
 
-       set_msrd(msr);          /* restore interrupt enable */
+       mtmsr(msr);             /* restore interrupt enable */
 
        return cmd != 'X';
 }
@@ -497,56 +515,23 @@ int xmon(struct pt_regs *excp)
        struct pt_regs regs;
 
        if (excp == NULL) {
-               /* Ok, grab regs as they are now.
-                This won't do a particularily good job because the
-                prologue has already been executed.
-                ToDo: We could reach back into the callers save
-                area to do a better job of representing the
-                caller's state.
-                */
-               asm volatile ("std      0,0(%0)\n\
-                       std     1,8(%0)\n\
-                       std     2,16(%0)\n\
-                       std     3,24(%0)\n\
-                       std     4,32(%0)\n\
-                       std     5,40(%0)\n\
-                       std     6,48(%0)\n\
-                       std     7,56(%0)\n\
-                       std     8,64(%0)\n\
-                       std     9,72(%0)\n\
-                       std     10,80(%0)\n\
-                       std     11,88(%0)\n\
-                       std     12,96(%0)\n\
-                       std     13,104(%0)\n\
-                       std     14,112(%0)\n\
-                       std     15,120(%0)\n\
-                       std     16,128(%0)\n\
-                       std     17,136(%0)\n\
-                       std     18,144(%0)\n\
-                       std     19,152(%0)\n\
-                       std     20,160(%0)\n\
-                       std     21,168(%0)\n\
-                       std     22,176(%0)\n\
-                       std     23,184(%0)\n\
-                       std     24,192(%0)\n\
-                       std     25,200(%0)\n\
-                       std     26,208(%0)\n\
-                       std     27,216(%0)\n\
-                       std     28,224(%0)\n\
-                       std     29,232(%0)\n\
-                       std     30,240(%0)\n\
-                       std     31,248(%0)" : : "b" (&regs));
-
-               regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
-               regs.msr = get_msr();
-               regs.ctr = get_ctr();
-               regs.xer = get_xer();
-               regs.ccr = get_cr();
-               regs.trap = 0;
+               xmon_save_regs(&regs);
                excp = &regs;
        }
        return xmon_core(excp, 0);
 }
+EXPORT_SYMBOL(xmon);
+
+irqreturn_t
+xmon_irq(int irq, void *d, struct pt_regs *regs)
+{
+       unsigned long flags;
+       local_irq_save(flags);
+       printf("Keyboard interrupt\n");
+       xmon(regs);
+       local_irq_restore(flags);
+       return IRQ_HANDLED;
+}
 
 int xmon_bpt(struct pt_regs *regs)
 {
@@ -718,7 +703,7 @@ static void insert_cpu_bpts(void)
        if (dabr.enabled)
                set_dabr(dabr.address | (dabr.enabled & 7));
        if (iabr && cpu_has_feature(CPU_FTR_IABR))
-               set_iabr(iabr->address
+               mtspr(SPRN_IABR, iabr->address
                         | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
 }
 
@@ -746,7 +731,7 @@ static void remove_cpu_bpts(void)
 {
        set_dabr(0);
        if (cpu_has_feature(CPU_FTR_IABR))
-               set_iabr(0);
+               mtspr(SPRN_IABR, 0);
 }
 
 /* Command interpreting routine */
@@ -830,9 +815,6 @@ cmds(struct pt_regs *excp)
                case '?':
                        printf(help_string);
                        break;
-               case 'p':
-                       show_state();
-                       break;
                case 'b':
                        bpt_cmds();
                        break;
@@ -846,12 +828,14 @@ cmds(struct pt_regs *excp)
                case 'z':
                        bootcmds();
                        break;
-               case 'T':
-                       debug_trace();
+               case 'p':
+                       proccall();
                        break;
+#ifdef CONFIG_PPC_STD_MMU
                case 'u':
                        dump_segments();
                        break;
+#endif
                default:
                        printf("Unrecognized command: ");
                        do {
@@ -1070,6 +1054,7 @@ bpt_cmds(void)
 
        cmd = inchar();
        switch (cmd) {
+#ifndef CONFIG_8xx
        case 'd':       /* bd - hardware data breakpoint */
                mode = 7;
                cmd = inchar();
@@ -1111,6 +1096,7 @@ bpt_cmds(void)
                        iabr = bp;
                }
                break;
+#endif
 
        case 'c':
                if (!scanhex(&a)) {
@@ -1152,7 +1138,7 @@ bpt_cmds(void)
                        /* print all breakpoints */
                        printf("   type            address\n");
                        if (dabr.enabled) {
-                               printf("   data   %.16lx  [", dabr.address);
+                               printf("   data   "REG"  [", dabr.address);
                                if (dabr.enabled & 1)
                                        printf("r");
                                if (dabr.enabled & 2)
@@ -1231,6 +1217,18 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
 
 static int xmon_depth_to_print = 64;
 
+#ifdef CONFIG_PPC64
+#define LRSAVE_OFFSET          0x10
+#define REG_FRAME_MARKER       0x7265677368657265ul    /* "regshere" */
+#define MARKER_OFFSET          0x60
+#define REGS_OFFSET            0x70
+#else
+#define LRSAVE_OFFSET          4
+#define REG_FRAME_MARKER       0x72656773
+#define MARKER_OFFSET          8
+#define REGS_OFFSET            16
+#endif
+
 static void xmon_show_stack(unsigned long sp, unsigned long lr,
                            unsigned long pc)
 {
@@ -1247,7 +1245,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
                        break;
                }
 
-               if (!mread(sp + 16, &ip, sizeof(unsigned long))
+               if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
                    || !mread(sp, &newsp, sizeof(unsigned long))) {
                        printf("Couldn't read stack frame at %lx\n", sp);
                        break;
@@ -1266,7 +1264,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
                        get_function_bounds(pc, &fnstart, &fnend);
                        nextip = 0;
                        if (newsp > sp)
-                               mread(newsp + 16, &nextip,
+                               mread(newsp + LRSAVE_OFFSET, &nextip,
                                      sizeof(unsigned long));
                        if (lr == ip) {
                                if (lr < PAGE_OFFSET
@@ -1280,24 +1278,24 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
                                xmon_print_symbol(lr, " ", "\n");
                        }
                        if (printip) {
-                               printf("[%.16lx] ", sp);
+                               printf("["REG"] ", sp);
                                xmon_print_symbol(ip, " ", " (unreliable)\n");
                        }
                        pc = lr = 0;
 
                } else {
-                       printf("[%.16lx] ", sp);
+                       printf("["REG"] ", sp);
                        xmon_print_symbol(ip, " ", "\n");
                }
 
                /* Look for "regshere" marker to see if this is
                   an exception frame. */
-               if (mread(sp + 0x60, &marker, sizeof(unsigned long))
-                   && marker == 0x7265677368657265ul) {
-                       if (mread(sp + 0x70, &regs, sizeof(regs))
+               if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
+                   && marker == REG_FRAME_MARKER) {
+                       if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
                            != sizeof(regs)) {
                                printf("Couldn't read registers at %lx\n",
-                                      sp + 0x70);
+                                      sp + REGS_OFFSET);
                                break;
                        }
                         printf("--- Exception: %lx %s at ", regs.trap,
@@ -1371,7 +1369,9 @@ void excprint(struct pt_regs *fp)
        }
 
        printf("  current = 0x%lx\n", current);
+#ifdef CONFIG_PPC64
        printf("  paca    = 0x%lx\n", get_paca());
+#endif
        if (current) {
                printf("    pid   = %ld, comm = %s\n",
                       current->pid, current->comm);
@@ -1383,7 +1383,7 @@ void excprint(struct pt_regs *fp)
 
 void prregs(struct pt_regs *fp)
 {
-       int n;
+       int n, trap;
        unsigned long base;
        struct pt_regs regs;
 
@@ -1396,7 +1396,7 @@ void prregs(struct pt_regs *fp)
                        __delay(200);
                } else {
                        catch_memory_errors = 0;
-                       printf("*** Error reading registers from %.16lx\n",
+                       printf("*** Error reading registers from "REG"\n",
                               base);
                        return;
                }
@@ -1404,22 +1404,36 @@ void prregs(struct pt_regs *fp)
                fp = &regs;
        }
 
+#ifdef CONFIG_PPC64
        if (FULL_REGS(fp)) {
                for (n = 0; n < 16; ++n)
-                       printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n",
+                       printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
                               n, fp->gpr[n], n+16, fp->gpr[n+16]);
        } else {
                for (n = 0; n < 7; ++n)
-                       printf("R%.2ld = %.16lx   R%.2ld = %.16lx\n",
+                       printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
                               n, fp->gpr[n], n+7, fp->gpr[n+7]);
        }
+#else
+       for (n = 0; n < 32; ++n) {
+               printf("R%.2d = %.8x%s", n, fp->gpr[n],
+                      (n & 3) == 3? "\n": "   ");
+               if (n == 12 && !FULL_REGS(fp)) {
+                       printf("\n");
+                       break;
+               }
+       }
+#endif
        printf("pc  = ");
        xmon_print_symbol(fp->nip, " ", "\n");
        printf("lr  = ");
        xmon_print_symbol(fp->link, " ", "\n");
-       printf("msr = %.16lx   cr  = %.8lx\n", fp->msr, fp->ccr);
-       printf("ctr = %.16lx   xer = %.16lx   trap = %8lx\n",
+       printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
+       printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
               fp->ctr, fp->xer, fp->trap);
+       trap = TRAP(fp);
+       if (trap == 0x300 || trap == 0x380 || trap == 0x600)
+               printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
 }
 
 void cacheflush(void)
@@ -1519,8 +1533,7 @@ static unsigned long regno;
 extern char exc_prolog;
 extern char dec_exc;
 
-void
-super_regs(void)
+void super_regs(void)
 {
        int cmd;
        unsigned long val;
@@ -1536,12 +1549,14 @@ super_regs(void)
                asm("mr %0,1" : "=r" (sp) :);
                asm("mr %0,2" : "=r" (toc) :);
 
-               printf("msr  = %.16lx  sprg0= %.16lx\n", get_msr(), get_sprg0());
-               printf("pvr  = %.16lx  sprg1= %.16lx\n", get_pvr(), get_sprg1()); 
-               printf("dec  = %.16lx  sprg2= %.16lx\n", get_dec(), get_sprg2());
-               printf("sp   = %.16lx  sprg3= %.16lx\n", sp, get_sprg3());
-               printf("toc  = %.16lx  dar  = %.16lx\n", toc, get_dar());
-               printf("srr0 = %.16lx  srr1 = %.16lx\n", get_srr0(), get_srr1());
+               printf("msr  = "REG"  sprg0= "REG"\n",
+                      mfmsr(), mfspr(SPRN_SPRG0));
+               printf("pvr  = "REG"  sprg1= "REG"\n",
+                      mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 
+               printf("dec  = "REG"  sprg2= "REG"\n",
+                      mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
+               printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
+               printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
 #ifdef CONFIG_PPC_ISERIES
                // Dump out relevant Paca data areas.
                printf("Paca: \n");
@@ -1578,11 +1593,6 @@ super_regs(void)
        case 'r':
                printf("spr %lx = %lx\n", regno, read_spr(regno));
                break;
-       case 'm':
-               val = get_msr();
-               scanhex(&val);
-               set_msrd(val);
-               break;
        }
        scannl();
 }
@@ -1604,13 +1614,13 @@ mread(unsigned long adrs, void *buf, int size)
                q = (char *)buf;
                switch (size) {
                case 2:
-                       *(short *)q = *(short *)p;
+                       *(u16 *)q = *(u16 *)p;
                        break;
                case 4:
-                       *(int *)q = *(int *)p;
+                       *(u32 *)q = *(u32 *)p;
                        break;
                case 8:
-                       *(long *)q = *(long *)p;
+                       *(u64 *)q = *(u64 *)p;
                        break;
                default:
                        for( ; n < size; ++n) {
@@ -1641,13 +1651,13 @@ mwrite(unsigned long adrs, void *buf, int size)
                q = (char *) buf;
                switch (size) {
                case 2:
-                       *(short *)p = *(short *)q;
+                       *(u16 *)p = *(u16 *)q;
                        break;
                case 4:
-                       *(int *)p = *(int *)q;
+                       *(u32 *)p = *(u32 *)q;
                        break;
                case 8:
-                       *(long *)p = *(long *)q;
+                       *(u64 *)p = *(u64 *)q;
                        break;
                default:
                        for ( ; n < size; ++n) {
@@ -1667,11 +1677,12 @@ mwrite(unsigned long adrs, void *buf, int size)
 }
 
 static int fault_type;
+static int fault_except;
 static char *fault_chars[] = { "--", "**", "##" };
 
-static int
-handle_fault(struct pt_regs *regs)
+static int handle_fault(struct pt_regs *regs)
 {
+       fault_except = TRAP(regs);
        switch (TRAP(regs)) {
        case 0x200:
                fault_type = 0;
@@ -1960,7 +1971,7 @@ prdump(unsigned long adrs, long ndump)
        unsigned char temp[16];
 
        for (n = ndump; n > 0;) {
-               printf("%.16lx", adrs);
+               printf(REG, adrs);
                putchar(' ');
                r = n < 16? n: 16;
                nr = mread(adrs, temp, r);
@@ -2008,7 +2019,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
                if (nr == 0) {
                        if (praddr) {
                                const char *x = fault_chars[fault_type];
-                               printf("%.16lx  %s%s%s%s\n", adr, x, x, x, x);
+                               printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
                        }
                        break;
                }
@@ -2023,7 +2034,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
                dotted = 0;
                last_inst = inst;
                if (praddr)
-                       printf("%.16lx  %.8x", adr, inst);
+                       printf(REG"  %.8x", adr, inst);
                printf("\t");
                print_insn_powerpc(inst, adr, 0);       /* always returns 4 */
                printf("\n");
@@ -2152,6 +2163,42 @@ memzcan(void)
                printf("%.8x\n", a - mskip);
 }
 
+void proccall(void)
+{
+       unsigned long args[8];
+       unsigned long ret;
+       int i;
+       typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
+                       unsigned long, unsigned long, unsigned long,
+                       unsigned long, unsigned long, unsigned long);
+       callfunc_t func;
+
+       if (!scanhex(&adrs))
+               return;
+       if (termch != '\n')
+               termch = 0;
+       for (i = 0; i < 8; ++i)
+               args[i] = 0;
+       for (i = 0; i < 8; ++i) {
+               if (!scanhex(&args[i]) || termch == '\n')
+                       break;
+               termch = 0;
+       }
+       func = (callfunc_t) adrs;
+       ret = 0;
+       if (setjmp(bus_error_jmp) == 0) {
+               catch_memory_errors = 1;
+               sync();
+               ret = func(args[0], args[1], args[2], args[3],
+                          args[4], args[5], args[6], args[7]);
+               sync();
+               printf("return value is %x\n", ret);
+       } else {
+               printf("*** %x exception occurred\n", fault_except);
+       }
+       catch_memory_errors = 0;
+}
+
 /* Input scanning routines */
 int
 skipbl(void)
@@ -2174,7 +2221,12 @@ static char *regnames[N_PTREGS] = {
        "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
-       "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
+       "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
+#ifdef CONFIG_PPC64
+       "softe",
+#else
+       "mq",
+#endif
        "trap", "dar", "dsisr", "res"
 };
 
@@ -2280,8 +2332,7 @@ scannl(void)
                c = inchar();
 }
 
-int
-hexdigit(int c)
+int hexdigit(int c)
 {
        if( '0' <= c && c <= '9' )
                return c - '0';
@@ -2378,7 +2429,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
        const char *name = NULL;
        unsigned long offset, size;
 
-       printf("%.16lx", address);
+       printf(REG, address);
        if (setjmp(bus_error_jmp) == 0) {
                catch_memory_errors = 1;
                sync();
@@ -2399,55 +2450,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
        printf("%s", after);
 }
 
-static void debug_trace(void)
-{
-        unsigned long val, cmd, on;
-
-       cmd = skipbl();
-       if (cmd == '\n') {
-               /* show current state */
-               unsigned long i;
-               printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
-               for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
-                       on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
-                       printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");
-                       if (((i+1) % 3) == 0)
-                               printf("\n");
-               }
-               printf("\n");
-               return;
-       }
-       while (cmd != '\n') {
-               on = 1; /* default if no sign given */
-               while (cmd == '+' || cmd == '-') {
-                       on = (cmd == '+');
-                       cmd = inchar();
-                       if (cmd == ' ' || cmd == '\n') {  /* Turn on or off based on + or - */
-                               ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
-                               printf("Setting all values to %s...\n", on ? "on" : "off");
-                               if (cmd == '\n') return;
-                               else cmd = skipbl(); 
-                       }
-                       else
-                               termch = cmd;
-               }
-               termch = cmd;   /* not +/- ... let scanhex see it */
-               scanhex((void *)&val);
-               if (val >= 64) {
-                       printf("Value %x out of range:\n", val);
-                       return;
-               }
-               if (on) {
-                       ppc64_debug_switch |= PPCDBG_BITVAL(val);
-                       printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
-               } else {
-                       ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
-                       printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
-               }
-               cmd = skipbl();
-       }
-}
-
+#ifdef CONFIG_PPC64
 static void dump_slb(void)
 {
        int i;
@@ -2484,6 +2487,27 @@ static void dump_stab(void)
        }
 }
 
+void dump_segments(void)
+{
+       if (cpu_has_feature(CPU_FTR_SLB))
+               dump_slb();
+       else
+               dump_stab();
+}
+#endif
+
+#ifdef CONFIG_PPC_STD_MMU_32
+void dump_segments(void)
+{
+       int i;
+
+       printf("sr0-15 =");
+       for (i = 0; i < 16; ++i)
+               printf(" %x", mfsrin(i));
+       printf("\n");
+}
+#endif
+
 void xmon_init(int enable)
 {
        if (enable) {
@@ -2504,11 +2528,3 @@ void xmon_init(int enable)
                __debugger_fault_handler = NULL;
        }
 }
-
-void dump_segments(void)
-{
-       if (cpu_has_feature(CPU_FTR_SLB))
-               dump_slb();
-       else
-               dump_stab();
-}
index 2a7af765bfb6d75b2ff18a734c48d0a6f5752512..743f0dbdebf346984a0342a583a6f7446d7ddc7e 100644 (file)
@@ -89,7 +89,7 @@ core-y                                += arch/powerpc/mm/
 core-y                         += arch/powerpc/sysdev/
 core-y                         += arch/powerpc/platforms/
 core-y                         += arch/powerpc/lib/
-core-$(CONFIG_XMON)            += arch/ppc64/xmon/
+core-$(CONFIG_XMON)            += arch/powerpc/xmon/
 drivers-$(CONFIG_OPROFILE)     += arch/powerpc/oprofile/
 
 boot := arch/ppc64/boot
diff --git a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile
deleted file mode 100644 (file)
index fb21a70..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile for xmon
-
-EXTRA_CFLAGS += -mno-minimal-toc
-
-obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S
deleted file mode 100644 (file)
index 30ee643..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- *
- * NOTE: assert(sizeof(buf) > 184)
- */
-#include <asm/processor.h>
-#include <asm/ppc_asm.h>
-
-_GLOBAL(xmon_setjmp)
-       mflr    r0
-       std     r0,0(r3)
-       std     r1,8(r3)
-       std     r2,16(r3)
-       mfcr    r0
-       std     r0,24(r3)
-       std     r13,32(r3)
-       std     r14,40(r3)
-       std     r15,48(r3)
-       std     r16,56(r3)
-       std     r17,64(r3)
-       std     r18,72(r3)
-       std     r19,80(r3)
-       std     r20,88(r3)
-       std     r21,96(r3)
-       std     r22,104(r3)
-       std     r23,112(r3)
-       std     r24,120(r3)
-       std     r25,128(r3)
-       std     r26,136(r3)
-       std     r27,144(r3)
-       std     r28,152(r3)
-       std     r29,160(r3)
-       std     r30,168(r3)
-       std     r31,176(r3)
-       li      r3,0
-       blr
-
-_GLOBAL(xmon_longjmp)
-       cmpdi   r4,0
-       bne     1f
-       li      r4,1
-1:     ld      r13,32(r3)
-       ld      r14,40(r3)
-       ld      r15,48(r3)
-       ld      r16,56(r3)
-       ld      r17,64(r3)
-       ld      r18,72(r3)
-       ld      r19,80(r3)
-       ld      r20,88(r3)
-       ld      r21,96(r3)
-       ld      r22,104(r3)
-       ld      r23,112(r3)
-       ld      r24,120(r3)
-       ld      r25,128(r3)
-       ld      r26,136(r3)
-       ld      r27,144(r3)
-       ld      r28,152(r3)
-       ld      r29,160(r3)
-       ld      r30,168(r3)
-       ld      r31,176(r3)
-       ld      r0,24(r3)
-       mtcrf   56,r0
-       ld      r0,0(r3)
-       ld      r1,8(r3)
-       ld      r2,16(r3)
-       mtlr    r0
-       mr      r3,r4
-       blr
index 470d7400ac59755c82179739caeb8d200bff03ec..f99f2af82ca564fb9377d5cd5cdb70be70d12887 100644 (file)
@@ -188,6 +188,10 @@ n:
 #define LDL    ld
 #define STL    std
 #define CMPI   cmpdi
+#define SZL    8
+
+/* offsets for stack frame layout */
+#define LRSAVE 16
 
 #else /* 32-bit */
 #define LOADADDR(rn,name) \
@@ -203,6 +207,10 @@ n:
 #define LDL    lwz
 #define STL    stw
 #define CMPI   cmpwi
+#define SZL    4
+
+/* offsets for stack frame layout */
+#define LRSAVE 4
 
 #endif
 
index bfb45a4523d3859ab18da2039975c9b6ee34fc85..da848412f11b1dd73d4d72ae672d3cb4a18bcba3 100644 (file)
 #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \
                                     : : "r" (v))
 #define mtmsrd(v)      __mtmsrd((v), 0)
+#define mtmsr(v)       mtmsrd(v)
 #else
 #define mtmsr(v)       asm volatile("mtmsr %0" : : "r" (v))
 #endif
index ca5f33277e0c320f9d884f78ef8d0d853d84b909..43f7129984c723312c3ca394ccf32fe53d52a4e8 100644 (file)
@@ -4,7 +4,7 @@
 
 struct pt_regs;
 
-extern void xmon(struct pt_regs *excp);
+extern int xmon(struct pt_regs *excp);
 extern void xmon_printf(const char *fmt, ...);
 extern void xmon_init(int);