Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Merge xmon

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>

+1289 -283
+1 -1
arch/powerpc/Makefile
··· 131 131 arch/powerpc/sysdev/ \ 132 132 arch/powerpc/platforms/ 133 133 core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ 134 - #core-$(CONFIG_XMON) += arch/powerpc/xmon/ 134 + core-$(CONFIG_XMON) += arch/powerpc/xmon/ 135 135 core-$(CONFIG_APUS) += arch/ppc/amiga/ 136 136 drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ 137 137 drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
+3
arch/powerpc/kernel/head_32.S
··· 271 271 li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ 272 272 MTMSRD(r10); /* (except for mach check in rtas) */ \ 273 273 stw r0,GPR0(r11); \ 274 + lis r10,0x7265; /* put exception frame marker */ \ 275 + addi r10,r10,0x6773; \ 276 + stw r10,8(r11); \ 274 277 SAVE_4GPRS(3, r11); \ 275 278 SAVE_2GPRS(7, r11) 276 279
-5
arch/powerpc/kernel/ppc_ksyms.c
··· 44 44 #include <asm/cputable.h> 45 45 #include <asm/btext.h> 46 46 #include <asm/div64.h> 47 - #include <asm/xmon.h> 48 47 49 48 #ifdef CONFIG_8xx 50 49 #include <asm/commproc.h> ··· 237 238 EXPORT_SYMBOL(cacheable_memcpy); 238 239 #endif 239 240 240 - #ifdef CONFIG_XMON 241 - EXPORT_SYMBOL(xmon); 242 - EXPORT_SYMBOL(xmon_printf); 243 - #endif 244 241 EXPORT_SYMBOL(__up); 245 242 EXPORT_SYMBOL(__down); 246 243 EXPORT_SYMBOL(__down_interruptible);
+4 -2
arch/powerpc/kernel/setup_32.c
··· 302 302 303 303 #ifdef CONFIG_XMON 304 304 xmon_map_scc(); 305 - if (strstr(cmd_line, "xmon")) 306 - xmon(NULL); 305 + if (strstr(cmd_line, "xmon")) { 306 + xmon_init(1); 307 + debugger(NULL); 308 + } 307 309 #endif /* CONFIG_XMON */ 308 310 if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); 309 311
+1
arch/powerpc/kernel/setup_64.c
··· 59 59 #include <asm/iSeries/ItLpNaca.h> 60 60 #include <asm/firmware.h> 61 61 #include <asm/systemcfg.h> 62 + #include <asm/xmon.h> 62 63 63 64 #ifdef DEBUG 64 65 #define DBG(fmt...) udbg_printf(fmt)
+2
arch/powerpc/lib/Makefile
··· 11 11 obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ 12 12 memcpy_64.o usercopy_64.o mem_64.o 13 13 obj-$(CONFIG_PPC_ISERIES) += e2a.o 14 + obj-$(CONFIG_XMON) += sstep.o 15 + 14 16 ifeq ($(CONFIG_PPC64),y) 15 17 obj-$(CONFIG_SMP) += locks.o 16 18 obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
+11
arch/powerpc/xmon/Makefile
··· 1 + # Makefile for xmon 2 + 3 + ifdef CONFIG_PPC64 4 + EXTRA_CFLAGS += -mno-minimal-toc 5 + endif 6 + 7 + obj-$(CONFIG_8xx) += start_8xx.o 8 + obj-$(CONFIG_6xx) += start_32.o 9 + obj-$(CONFIG_4xx) += start_32.o 10 + obj-$(CONFIG_PPC64) += start_64.o 11 + obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
+135
arch/powerpc/xmon/setjmp.S
··· 1 + /* 2 + * Copyright (C) 1996 Paul Mackerras. 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License 6 + * as published by the Free Software Foundation; either version 7 + * 2 of the License, or (at your option) any later version. 8 + * 9 + * NOTE: assert(sizeof(buf) > 23 * sizeof(long)) 10 + */ 11 + #include <asm/processor.h> 12 + #include <asm/ppc_asm.h> 13 + #include <asm/asm-offsets.h> 14 + 15 + _GLOBAL(xmon_setjmp) 16 + mflr r0 17 + STL r0,0(r3) 18 + STL r1,SZL(r3) 19 + STL r2,2*SZL(r3) 20 + mfcr r0 21 + STL r0,3*SZL(r3) 22 + STL r13,4*SZL(r3) 23 + STL r14,5*SZL(r3) 24 + STL r15,6*SZL(r3) 25 + STL r16,7*SZL(r3) 26 + STL r17,8*SZL(r3) 27 + STL r18,9*SZL(r3) 28 + STL r19,10*SZL(r3) 29 + STL r20,11*SZL(r3) 30 + STL r21,12*SZL(r3) 31 + STL r22,13*SZL(r3) 32 + STL r23,14*SZL(r3) 33 + STL r24,15*SZL(r3) 34 + STL r25,16*SZL(r3) 35 + STL r26,17*SZL(r3) 36 + STL r27,18*SZL(r3) 37 + STL r28,19*SZL(r3) 38 + STL r29,20*SZL(r3) 39 + STL r30,21*SZL(r3) 40 + STL r31,22*SZL(r3) 41 + li r3,0 42 + blr 43 + 44 + _GLOBAL(xmon_longjmp) 45 + CMPI r4,0 46 + bne 1f 47 + li r4,1 48 + 1: LDL r13,4*SZL(r3) 49 + LDL r14,5*SZL(r3) 50 + LDL r15,6*SZL(r3) 51 + LDL r16,7*SZL(r3) 52 + LDL r17,8*SZL(r3) 53 + LDL r18,9*SZL(r3) 54 + LDL r19,10*SZL(r3) 55 + LDL r20,11*SZL(r3) 56 + LDL r21,12*SZL(r3) 57 + LDL r22,13*SZL(r3) 58 + LDL r23,14*SZL(r3) 59 + LDL r24,15*SZL(r3) 60 + LDL r25,16*SZL(r3) 61 + LDL r26,17*SZL(r3) 62 + LDL r27,18*SZL(r3) 63 + LDL r28,19*SZL(r3) 64 + LDL r29,20*SZL(r3) 65 + LDL r30,21*SZL(r3) 66 + LDL r31,22*SZL(r3) 67 + LDL r0,3*SZL(r3) 68 + mtcrf 0x38,r0 69 + LDL r0,0(r3) 70 + LDL r1,SZL(r3) 71 + LDL r2,2*SZL(r3) 72 + mtlr r0 73 + mr r3,r4 74 + blr 75 + 76 + /* 77 + * Grab the register values as they are now. 78 + * This won't do a particularily good job because we really 79 + * want our caller's caller's registers, and our caller has 80 + * already executed its prologue. 81 + * ToDo: We could reach back into the caller's save area to do 82 + * a better job of representing the caller's state (note that 83 + * that will be different for 32-bit and 64-bit, because of the 84 + * different ABIs, though). 85 + */ 86 + _GLOBAL(xmon_save_regs) 87 + STL r0,0*SZL(r3) 88 + STL r2,2*SZL(r3) 89 + STL r3,3*SZL(r3) 90 + STL r4,4*SZL(r3) 91 + STL r5,5*SZL(r3) 92 + STL r6,6*SZL(r3) 93 + STL r7,7*SZL(r3) 94 + STL r8,8*SZL(r3) 95 + STL r9,9*SZL(r3) 96 + STL r10,10*SZL(r3) 97 + STL r11,11*SZL(r3) 98 + STL r12,12*SZL(r3) 99 + STL r13,13*SZL(r3) 100 + STL r14,14*SZL(r3) 101 + STL r15,15*SZL(r3) 102 + STL r16,16*SZL(r3) 103 + STL r17,17*SZL(r3) 104 + STL r18,18*SZL(r3) 105 + STL r19,19*SZL(r3) 106 + STL r20,20*SZL(r3) 107 + STL r21,21*SZL(r3) 108 + STL r22,22*SZL(r3) 109 + STL r23,23*SZL(r3) 110 + STL r24,24*SZL(r3) 111 + STL r25,25*SZL(r3) 112 + STL r26,26*SZL(r3) 113 + STL r27,27*SZL(r3) 114 + STL r28,28*SZL(r3) 115 + STL r29,29*SZL(r3) 116 + STL r30,30*SZL(r3) 117 + STL r31,31*SZL(r3) 118 + /* go up one stack frame for SP */ 119 + LDL r4,0(r1) 120 + STL r4,1*SZL(r3) 121 + /* get caller's LR */ 122 + LDL r0,LRSAVE(r4) 123 + STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) 124 + STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) 125 + mfmsr r0 126 + STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) 127 + mfctr r0 128 + STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) 129 + mfxer r0 130 + STL r0,_XER-STACK_FRAME_OVERHEAD(r3) 131 + mfcr r0 132 + STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) 133 + li r0,0 134 + STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) 135 + blr
+624
arch/powerpc/xmon/start_32.c
··· 1 + /* 2 + * Copyright (C) 1996 Paul Mackerras. 3 + */ 4 + #include <linux/config.h> 5 + #include <linux/string.h> 6 + #include <asm/machdep.h> 7 + #include <asm/io.h> 8 + #include <asm/page.h> 9 + #include <linux/adb.h> 10 + #include <linux/pmu.h> 11 + #include <linux/cuda.h> 12 + #include <linux/kernel.h> 13 + #include <linux/errno.h> 14 + #include <linux/sysrq.h> 15 + #include <linux/bitops.h> 16 + #include <asm/xmon.h> 17 + #include <asm/prom.h> 18 + #include <asm/bootx.h> 19 + #include <asm/machdep.h> 20 + #include <asm/errno.h> 21 + #include <asm/pmac_feature.h> 22 + #include <asm/processor.h> 23 + #include <asm/delay.h> 24 + #include <asm/btext.h> 25 + 26 + static volatile unsigned char __iomem *sccc, *sccd; 27 + unsigned int TXRDY, RXRDY, DLAB; 28 + static int xmon_expect(const char *str, unsigned int timeout); 29 + 30 + static int use_serial; 31 + static int use_screen; 32 + static int via_modem; 33 + static int xmon_use_sccb; 34 + static struct device_node *channel_node; 35 + 36 + #define TB_SPEED 25000000 37 + 38 + static inline unsigned int readtb(void) 39 + { 40 + unsigned int ret; 41 + 42 + asm volatile("mftb %0" : "=r" (ret) :); 43 + return ret; 44 + } 45 + 46 + void buf_access(void) 47 + { 48 + if (DLAB) 49 + sccd[3] &= ~DLAB; /* reset DLAB */ 50 + } 51 + 52 + extern int adb_init(void); 53 + 54 + #ifdef CONFIG_PPC_CHRP 55 + /* 56 + * This looks in the "ranges" property for the primary PCI host bridge 57 + * to find the physical address of the start of PCI/ISA I/O space. 58 + * It is basically a cut-down version of pci_process_bridge_OF_ranges. 59 + */ 60 + static unsigned long chrp_find_phys_io_base(void) 61 + { 62 + struct device_node *node; 63 + unsigned int *ranges; 64 + unsigned long base = CHRP_ISA_IO_BASE; 65 + int rlen = 0; 66 + int np; 67 + 68 + node = find_devices("isa"); 69 + if (node != NULL) { 70 + node = node->parent; 71 + if (node == NULL || node->type == NULL 72 + || strcmp(node->type, "pci") != 0) 73 + node = NULL; 74 + } 75 + if (node == NULL) 76 + node = find_devices("pci"); 77 + if (node == NULL) 78 + return base; 79 + 80 + ranges = (unsigned int *) get_property(node, "ranges", &rlen); 81 + np = prom_n_addr_cells(node) + 5; 82 + while ((rlen -= np * sizeof(unsigned int)) >= 0) { 83 + if ((ranges[0] >> 24) == 1 && ranges[2] == 0) { 84 + /* I/O space starting at 0, grab the phys base */ 85 + base = ranges[np - 3]; 86 + break; 87 + } 88 + ranges += np; 89 + } 90 + return base; 91 + } 92 + #endif /* CONFIG_PPC_CHRP */ 93 + 94 + #ifdef CONFIG_MAGIC_SYSRQ 95 + static void sysrq_handle_xmon(int key, struct pt_regs *regs, 96 + struct tty_struct *tty) 97 + { 98 + xmon(regs); 99 + } 100 + 101 + static struct sysrq_key_op sysrq_xmon_op = 102 + { 103 + .handler = sysrq_handle_xmon, 104 + .help_msg = "Xmon", 105 + .action_msg = "Entering xmon", 106 + }; 107 + #endif 108 + 109 + void 110 + xmon_map_scc(void) 111 + { 112 + #ifdef CONFIG_PPC_MULTIPLATFORM 113 + volatile unsigned char __iomem *base; 114 + 115 + if (_machine == _MACH_Pmac) { 116 + struct device_node *np; 117 + unsigned long addr; 118 + #ifdef CONFIG_BOOTX_TEXT 119 + if (!use_screen && !use_serial 120 + && !machine_is_compatible("iMac")) { 121 + /* see if there is a keyboard in the device tree 122 + with a parent of type "adb" */ 123 + for (np = find_devices("keyboard"); np; np = np->next) 124 + if (np->parent && np->parent->type 125 + && strcmp(np->parent->type, "adb") == 0) 126 + break; 127 + 128 + /* needs to be hacked if xmon_printk is to be used 129 + from within find_via_pmu() */ 130 + #ifdef CONFIG_ADB_PMU 131 + if (np != NULL && boot_text_mapped && find_via_pmu()) 132 + use_screen = 1; 133 + #endif 134 + #ifdef CONFIG_ADB_CUDA 135 + if (np != NULL && boot_text_mapped && find_via_cuda()) 136 + use_screen = 1; 137 + #endif 138 + } 139 + if (!use_screen && (np = find_devices("escc")) != NULL) { 140 + /* 141 + * look for the device node for the serial port 142 + * we're using and see if it says it has a modem 143 + */ 144 + char *name = xmon_use_sccb? "ch-b": "ch-a"; 145 + char *slots; 146 + int l; 147 + 148 + np = np->child; 149 + while (np != NULL && strcmp(np->name, name) != 0) 150 + np = np->sibling; 151 + if (np != NULL) { 152 + /* XXX should parse this properly */ 153 + channel_node = np; 154 + slots = get_property(np, "slot-names", &l); 155 + if (slots != NULL && l >= 10 156 + && strcmp(slots+4, "Modem") == 0) 157 + via_modem = 1; 158 + } 159 + } 160 + btext_drawstring("xmon uses "); 161 + if (use_screen) 162 + btext_drawstring("screen and keyboard\n"); 163 + else { 164 + if (via_modem) 165 + btext_drawstring("modem on "); 166 + btext_drawstring(xmon_use_sccb? "printer": "modem"); 167 + btext_drawstring(" port\n"); 168 + } 169 + 170 + #endif /* CONFIG_BOOTX_TEXT */ 171 + 172 + #ifdef CHRP_ESCC 173 + addr = 0xc1013020; 174 + #else 175 + addr = 0xf3013020; 176 + #endif 177 + TXRDY = 4; 178 + RXRDY = 1; 179 + 180 + np = find_devices("mac-io"); 181 + if (np && np->n_addrs) 182 + addr = np->addrs[0].address + 0x13020; 183 + base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); 184 + sccc = base + (addr & ~PAGE_MASK); 185 + sccd = sccc + 0x10; 186 + 187 + } else { 188 + base = (volatile unsigned char *) isa_io_base; 189 + 190 + #ifdef CONFIG_PPC_CHRP 191 + if (_machine == _MACH_chrp) 192 + base = (volatile unsigned char __iomem *) 193 + ioremap(chrp_find_phys_io_base(), 0x1000); 194 + #endif 195 + 196 + sccc = base + 0x3fd; 197 + sccd = base + 0x3f8; 198 + if (xmon_use_sccb) { 199 + sccc -= 0x100; 200 + sccd -= 0x100; 201 + } 202 + TXRDY = 0x20; 203 + RXRDY = 1; 204 + DLAB = 0x80; 205 + } 206 + #elif defined(CONFIG_GEMINI) 207 + /* should already be mapped by the kernel boot */ 208 + sccc = (volatile unsigned char __iomem *) 0xffeffb0d; 209 + sccd = (volatile unsigned char __iomem *) 0xffeffb08; 210 + TXRDY = 0x20; 211 + RXRDY = 1; 212 + DLAB = 0x80; 213 + #elif defined(CONFIG_405GP) 214 + sccc = (volatile unsigned char __iomem *)0xef600305; 215 + sccd = (volatile unsigned char __iomem *)0xef600300; 216 + TXRDY = 0x20; 217 + RXRDY = 1; 218 + DLAB = 0x80; 219 + #endif /* platform */ 220 + 221 + register_sysrq_key('x', &sysrq_xmon_op); 222 + } 223 + 224 + static int scc_initialized = 0; 225 + 226 + void xmon_init_scc(void); 227 + extern void cuda_poll(void); 228 + 229 + static inline void do_poll_adb(void) 230 + { 231 + #ifdef CONFIG_ADB_PMU 232 + if (sys_ctrler == SYS_CTRLER_PMU) 233 + pmu_poll_adb(); 234 + #endif /* CONFIG_ADB_PMU */ 235 + #ifdef CONFIG_ADB_CUDA 236 + if (sys_ctrler == SYS_CTRLER_CUDA) 237 + cuda_poll(); 238 + #endif /* CONFIG_ADB_CUDA */ 239 + } 240 + 241 + int 242 + xmon_write(void *handle, void *ptr, int nb) 243 + { 244 + char *p = ptr; 245 + int i, c, ct; 246 + 247 + #ifdef CONFIG_SMP 248 + static unsigned long xmon_write_lock; 249 + int lock_wait = 1000000; 250 + int locked; 251 + 252 + while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) 253 + if (--lock_wait == 0) 254 + break; 255 + #endif 256 + 257 + #ifdef CONFIG_BOOTX_TEXT 258 + if (use_screen) { 259 + /* write it on the screen */ 260 + for (i = 0; i < nb; ++i) 261 + btext_drawchar(*p++); 262 + goto out; 263 + } 264 + #endif 265 + if (!scc_initialized) 266 + xmon_init_scc(); 267 + ct = 0; 268 + for (i = 0; i < nb; ++i) { 269 + while ((*sccc & TXRDY) == 0) 270 + do_poll_adb(); 271 + c = p[i]; 272 + if (c == '\n' && !ct) { 273 + c = '\r'; 274 + ct = 1; 275 + --i; 276 + } else { 277 + ct = 0; 278 + } 279 + buf_access(); 280 + *sccd = c; 281 + eieio(); 282 + } 283 + 284 + out: 285 + #ifdef CONFIG_SMP 286 + if (!locked) 287 + clear_bit(0, &xmon_write_lock); 288 + #endif 289 + return nb; 290 + } 291 + 292 + int xmon_wants_key; 293 + int xmon_adb_keycode; 294 + 295 + #ifdef CONFIG_BOOTX_TEXT 296 + static int xmon_adb_shiftstate; 297 + 298 + static unsigned char xmon_keytab[128] = 299 + "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */ 300 + "yt123465=97-80]o" /* 0x10 - 0x1f */ 301 + "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ 302 + "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ 303 + "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ 304 + "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ 305 + 306 + static unsigned char xmon_shift_keytab[128] = 307 + "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */ 308 + "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */ 309 + "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */ 310 + "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ 311 + "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ 312 + "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ 313 + 314 + static int 315 + xmon_get_adb_key(void) 316 + { 317 + int k, t, on; 318 + 319 + xmon_wants_key = 1; 320 + for (;;) { 321 + xmon_adb_keycode = -1; 322 + t = 0; 323 + on = 0; 324 + do { 325 + if (--t < 0) { 326 + on = 1 - on; 327 + btext_drawchar(on? 0xdb: 0x20); 328 + btext_drawchar('\b'); 329 + t = 200000; 330 + } 331 + do_poll_adb(); 332 + } while (xmon_adb_keycode == -1); 333 + k = xmon_adb_keycode; 334 + if (on) 335 + btext_drawstring(" \b"); 336 + 337 + /* test for shift keys */ 338 + if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) { 339 + xmon_adb_shiftstate = (k & 0x80) == 0; 340 + continue; 341 + } 342 + if (k >= 0x80) 343 + continue; /* ignore up transitions */ 344 + k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k]; 345 + if (k != 0) 346 + break; 347 + } 348 + xmon_wants_key = 0; 349 + return k; 350 + } 351 + #endif /* CONFIG_BOOTX_TEXT */ 352 + 353 + int 354 + xmon_read(void *handle, void *ptr, int nb) 355 + { 356 + char *p = ptr; 357 + int i; 358 + 359 + #ifdef CONFIG_BOOTX_TEXT 360 + if (use_screen) { 361 + for (i = 0; i < nb; ++i) 362 + *p++ = xmon_get_adb_key(); 363 + return i; 364 + } 365 + #endif 366 + if (!scc_initialized) 367 + xmon_init_scc(); 368 + for (i = 0; i < nb; ++i) { 369 + while ((*sccc & RXRDY) == 0) 370 + do_poll_adb(); 371 + buf_access(); 372 + *p++ = *sccd; 373 + } 374 + return i; 375 + } 376 + 377 + int 378 + xmon_read_poll(void) 379 + { 380 + if ((*sccc & RXRDY) == 0) { 381 + do_poll_adb(); 382 + return -1; 383 + } 384 + buf_access(); 385 + return *sccd; 386 + } 387 + 388 + static unsigned char scc_inittab[] = { 389 + 13, 0, /* set baud rate divisor */ 390 + 12, 1, 391 + 14, 1, /* baud rate gen enable, src=rtxc */ 392 + 11, 0x50, /* clocks = br gen */ 393 + 5, 0xea, /* tx 8 bits, assert DTR & RTS */ 394 + 4, 0x46, /* x16 clock, 1 stop */ 395 + 3, 0xc1, /* rx enable, 8 bits */ 396 + }; 397 + 398 + void 399 + xmon_init_scc(void) 400 + { 401 + if ( _machine == _MACH_chrp ) 402 + { 403 + sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */ 404 + sccd[0] = 12; eieio(); /* DLL = 9600 baud */ 405 + sccd[1] = 0; eieio(); 406 + sccd[2] = 0; eieio(); /* FCR = 0 */ 407 + sccd[3] = 3; eieio(); /* LCR = 8N1 */ 408 + sccd[1] = 0; eieio(); /* IER = 0 */ 409 + } 410 + else if ( _machine == _MACH_Pmac ) 411 + { 412 + int i, x; 413 + 414 + if (channel_node != 0) 415 + pmac_call_feature( 416 + PMAC_FTR_SCC_ENABLE, 417 + channel_node, 418 + PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); 419 + printk(KERN_INFO "Serial port locked ON by debugger !\n"); 420 + if (via_modem && channel_node != 0) { 421 + unsigned int t0; 422 + 423 + pmac_call_feature( 424 + PMAC_FTR_MODEM_ENABLE, 425 + channel_node, 0, 1); 426 + printk(KERN_INFO "Modem powered up by debugger !\n"); 427 + t0 = readtb(); 428 + while (readtb() - t0 < 3*TB_SPEED) 429 + eieio(); 430 + } 431 + /* use the B channel if requested */ 432 + if (xmon_use_sccb) { 433 + sccc = (volatile unsigned char *) 434 + ((unsigned long)sccc & ~0x20); 435 + sccd = sccc + 0x10; 436 + } 437 + for (i = 20000; i != 0; --i) { 438 + x = *sccc; eieio(); 439 + } 440 + *sccc = 9; eieio(); /* reset A or B side */ 441 + *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio(); 442 + for (i = 0; i < sizeof(scc_inittab); ++i) { 443 + *sccc = scc_inittab[i]; 444 + eieio(); 445 + } 446 + } 447 + scc_initialized = 1; 448 + if (via_modem) { 449 + for (;;) { 450 + xmon_write(NULL, "ATE1V1\r", 7); 451 + if (xmon_expect("OK", 5)) { 452 + xmon_write(NULL, "ATA\r", 4); 453 + if (xmon_expect("CONNECT", 40)) 454 + break; 455 + } 456 + xmon_write(NULL, "+++", 3); 457 + xmon_expect("OK", 3); 458 + } 459 + } 460 + } 461 + 462 + void *xmon_stdin; 463 + void *xmon_stdout; 464 + void *xmon_stderr; 465 + 466 + int xmon_putc(int c, void *f) 467 + { 468 + char ch = c; 469 + 470 + if (c == '\n') 471 + xmon_putc('\r', f); 472 + return xmon_write(f, &ch, 1) == 1? c: -1; 473 + } 474 + 475 + int xmon_putchar(int c) 476 + { 477 + return xmon_putc(c, xmon_stdout); 478 + } 479 + 480 + int xmon_fputs(char *str, void *f) 481 + { 482 + int n = strlen(str); 483 + 484 + return xmon_write(f, str, n) == n? 0: -1; 485 + } 486 + 487 + int 488 + xmon_readchar(void) 489 + { 490 + char ch; 491 + 492 + for (;;) { 493 + switch (xmon_read(xmon_stdin, &ch, 1)) { 494 + case 1: 495 + return ch; 496 + case -1: 497 + xmon_printf("read(stdin) returned -1\r\n", 0, 0); 498 + return -1; 499 + } 500 + } 501 + } 502 + 503 + static char line[256]; 504 + static char *lineptr; 505 + static int lineleft; 506 + 507 + int xmon_expect(const char *str, unsigned int timeout) 508 + { 509 + int c; 510 + unsigned int t0; 511 + 512 + timeout *= TB_SPEED; 513 + t0 = readtb(); 514 + do { 515 + lineptr = line; 516 + for (;;) { 517 + c = xmon_read_poll(); 518 + if (c == -1) { 519 + if (readtb() - t0 > timeout) 520 + return 0; 521 + continue; 522 + } 523 + if (c == '\n') 524 + break; 525 + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) 526 + *lineptr++ = c; 527 + } 528 + *lineptr = 0; 529 + } while (strstr(line, str) == NULL); 530 + return 1; 531 + } 532 + 533 + int 534 + xmon_getchar(void) 535 + { 536 + int c; 537 + 538 + if (lineleft == 0) { 539 + lineptr = line; 540 + for (;;) { 541 + c = xmon_readchar(); 542 + if (c == -1 || c == 4) 543 + break; 544 + if (c == '\r' || c == '\n') { 545 + *lineptr++ = '\n'; 546 + xmon_putchar('\n'); 547 + break; 548 + } 549 + switch (c) { 550 + case 0177: 551 + case '\b': 552 + if (lineptr > line) { 553 + xmon_putchar('\b'); 554 + xmon_putchar(' '); 555 + xmon_putchar('\b'); 556 + --lineptr; 557 + } 558 + break; 559 + case 'U' & 0x1F: 560 + while (lineptr > line) { 561 + xmon_putchar('\b'); 562 + xmon_putchar(' '); 563 + xmon_putchar('\b'); 564 + --lineptr; 565 + } 566 + break; 567 + default: 568 + if (lineptr >= &line[sizeof(line) - 1]) 569 + xmon_putchar('\a'); 570 + else { 571 + xmon_putchar(c); 572 + *lineptr++ = c; 573 + } 574 + } 575 + } 576 + lineleft = lineptr - line; 577 + lineptr = line; 578 + } 579 + if (lineleft == 0) 580 + return -1; 581 + --lineleft; 582 + return *lineptr++; 583 + } 584 + 585 + char * 586 + xmon_fgets(char *str, int nb, void *f) 587 + { 588 + char *p; 589 + int c; 590 + 591 + for (p = str; p < str + nb - 1; ) { 592 + c = xmon_getchar(); 593 + if (c == -1) { 594 + if (p == str) 595 + return NULL; 596 + break; 597 + } 598 + *p++ = c; 599 + if (c == '\n') 600 + break; 601 + } 602 + *p = 0; 603 + return str; 604 + } 605 + 606 + void 607 + xmon_enter(void) 608 + { 609 + #ifdef CONFIG_ADB_PMU 610 + if (_machine == _MACH_Pmac) { 611 + pmu_suspend(); 612 + } 613 + #endif 614 + } 615 + 616 + void 617 + xmon_leave(void) 618 + { 619 + #ifdef CONFIG_ADB_PMU 620 + if (_machine == _MACH_Pmac) { 621 + pmu_resume(); 622 + } 623 + #endif 624 + }
+287
arch/powerpc/xmon/start_8xx.c
··· 1 + /* 2 + * Copyright (C) 1996 Paul Mackerras. 3 + * Copyright (C) 2000 Dan Malek. 4 + * Quick hack of Paul's code to make XMON work on 8xx processors. Lots 5 + * of assumptions, like the SMC1 is used, it has been initialized by the 6 + * loader at some point, and we can just stuff and suck bytes. 7 + * We rely upon the 8xx uart driver to support us, as the interface 8 + * changes between boot up and operational phases of the kernel. 9 + */ 10 + #include <linux/string.h> 11 + #include <asm/machdep.h> 12 + #include <asm/io.h> 13 + #include <asm/page.h> 14 + #include <linux/kernel.h> 15 + #include <asm/8xx_immap.h> 16 + #include <asm/mpc8xx.h> 17 + #include <asm/commproc.h> 18 + 19 + extern void xmon_printf(const char *fmt, ...); 20 + extern int xmon_8xx_write(char *str, int nb); 21 + extern int xmon_8xx_read_poll(void); 22 + extern int xmon_8xx_read_char(void); 23 + void prom_drawhex(uint); 24 + void prom_drawstring(const char *str); 25 + 26 + static int use_screen = 1; /* default */ 27 + 28 + #define TB_SPEED 25000000 29 + 30 + static inline unsigned int readtb(void) 31 + { 32 + unsigned int ret; 33 + 34 + asm volatile("mftb %0" : "=r" (ret) :); 35 + return ret; 36 + } 37 + 38 + void buf_access(void) 39 + { 40 + } 41 + 42 + void 43 + xmon_map_scc(void) 44 + { 45 + 46 + cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); 47 + use_screen = 0; 48 + 49 + prom_drawstring("xmon uses serial port\n"); 50 + } 51 + 52 + static int scc_initialized = 0; 53 + 54 + void xmon_init_scc(void); 55 + 56 + int 57 + xmon_write(void *handle, void *ptr, int nb) 58 + { 59 + char *p = ptr; 60 + int i, c, ct; 61 + 62 + if (!scc_initialized) 63 + xmon_init_scc(); 64 + 65 + return(xmon_8xx_write(ptr, nb)); 66 + } 67 + 68 + int xmon_wants_key; 69 + 70 + int 71 + xmon_read(void *handle, void *ptr, int nb) 72 + { 73 + char *p = ptr; 74 + int i; 75 + 76 + if (!scc_initialized) 77 + xmon_init_scc(); 78 + 79 + for (i = 0; i < nb; ++i) { 80 + *p++ = xmon_8xx_read_char(); 81 + } 82 + return i; 83 + } 84 + 85 + int 86 + xmon_read_poll(void) 87 + { 88 + return(xmon_8xx_read_poll()); 89 + } 90 + 91 + void 92 + xmon_init_scc() 93 + { 94 + scc_initialized = 1; 95 + } 96 + 97 + #if 0 98 + extern int (*prom_entry)(void *); 99 + 100 + int 101 + xmon_exit(void) 102 + { 103 + struct prom_args { 104 + char *service; 105 + } args; 106 + 107 + for (;;) { 108 + args.service = "exit"; 109 + (*prom_entry)(&args); 110 + } 111 + } 112 + #endif 113 + 114 + void *xmon_stdin; 115 + void *xmon_stdout; 116 + void *xmon_stderr; 117 + 118 + void 119 + xmon_init(void) 120 + { 121 + } 122 + 123 + int 124 + xmon_putc(int c, void *f) 125 + { 126 + char ch = c; 127 + 128 + if (c == '\n') 129 + xmon_putc('\r', f); 130 + return xmon_write(f, &ch, 1) == 1? c: -1; 131 + } 132 + 133 + int 134 + xmon_putchar(int c) 135 + { 136 + return xmon_putc(c, xmon_stdout); 137 + } 138 + 139 + int 140 + xmon_fputs(char *str, void *f) 141 + { 142 + int n = strlen(str); 143 + 144 + return xmon_write(f, str, n) == n? 0: -1; 145 + } 146 + 147 + int 148 + xmon_readchar(void) 149 + { 150 + char ch; 151 + 152 + for (;;) { 153 + switch (xmon_read(xmon_stdin, &ch, 1)) { 154 + case 1: 155 + return ch; 156 + case -1: 157 + xmon_printf("read(stdin) returned -1\r\n", 0, 0); 158 + return -1; 159 + } 160 + } 161 + } 162 + 163 + static char line[256]; 164 + static char *lineptr; 165 + static int lineleft; 166 + 167 + #if 0 168 + int xmon_expect(const char *str, unsigned int timeout) 169 + { 170 + int c; 171 + unsigned int t0; 172 + 173 + timeout *= TB_SPEED; 174 + t0 = readtb(); 175 + do { 176 + lineptr = line; 177 + for (;;) { 178 + c = xmon_read_poll(); 179 + if (c == -1) { 180 + if (readtb() - t0 > timeout) 181 + return 0; 182 + continue; 183 + } 184 + if (c == '\n') 185 + break; 186 + if (c != '\r' && lineptr < &line[sizeof(line) - 1]) 187 + *lineptr++ = c; 188 + } 189 + *lineptr = 0; 190 + } while (strstr(line, str) == NULL); 191 + return 1; 192 + } 193 + #endif 194 + 195 + int 196 + xmon_getchar(void) 197 + { 198 + int c; 199 + 200 + if (lineleft == 0) { 201 + lineptr = line; 202 + for (;;) { 203 + c = xmon_readchar(); 204 + if (c == -1 || c == 4) 205 + break; 206 + if (c == '\r' || c == '\n') { 207 + *lineptr++ = '\n'; 208 + xmon_putchar('\n'); 209 + break; 210 + } 211 + switch (c) { 212 + case 0177: 213 + case '\b': 214 + if (lineptr > line) { 215 + xmon_putchar('\b'); 216 + xmon_putchar(' '); 217 + xmon_putchar('\b'); 218 + --lineptr; 219 + } 220 + break; 221 + case 'U' & 0x1F: 222 + while (lineptr > line) { 223 + xmon_putchar('\b'); 224 + xmon_putchar(' '); 225 + xmon_putchar('\b'); 226 + --lineptr; 227 + } 228 + break; 229 + default: 230 + if (lineptr >= &line[sizeof(line) - 1]) 231 + xmon_putchar('\a'); 232 + else { 233 + xmon_putchar(c); 234 + *lineptr++ = c; 235 + } 236 + } 237 + } 238 + lineleft = lineptr - line; 239 + lineptr = line; 240 + } 241 + if (lineleft == 0) 242 + return -1; 243 + --lineleft; 244 + return *lineptr++; 245 + } 246 + 247 + char * 248 + xmon_fgets(char *str, int nb, void *f) 249 + { 250 + char *p; 251 + int c; 252 + 253 + for (p = str; p < str + nb - 1; ) { 254 + c = xmon_getchar(); 255 + if (c == -1) { 256 + if (p == str) 257 + return 0; 258 + break; 259 + } 260 + *p++ = c; 261 + if (c == '\n') 262 + break; 263 + } 264 + *p = 0; 265 + return str; 266 + } 267 + 268 + void 269 + prom_drawhex(uint val) 270 + { 271 + unsigned char buf[10]; 272 + 273 + int i; 274 + for (i = 7; i >= 0; i--) 275 + { 276 + buf[i] = "0123456789abcdef"[val & 0x0f]; 277 + val >>= 4; 278 + } 279 + buf[8] = '\0'; 280 + xmon_fputs(buf, xmon_stdout); 281 + } 282 + 283 + void 284 + prom_drawstring(const char *str) 285 + { 286 + xmon_fputs(str, xmon_stdout); 287 + }
+1 -1
arch/ppc64/Makefile
··· 89 89 core-y += arch/powerpc/sysdev/ 90 90 core-y += arch/powerpc/platforms/ 91 91 core-y += arch/powerpc/lib/ 92 - core-$(CONFIG_XMON) += arch/ppc64/xmon/ 92 + core-$(CONFIG_XMON) += arch/powerpc/xmon/ 93 93 drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 94 94 95 95 boot := arch/ppc64/boot
-5
arch/ppc64/xmon/Makefile
··· 1 - # Makefile for xmon 2 - 3 - EXTRA_CFLAGS += -mno-minimal-toc 4 - 5 - obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
arch/ppc64/xmon/ansidecl.h arch/powerpc/xmon/ansidecl.h
arch/ppc64/xmon/nonstdio.h arch/powerpc/xmon/nonstdio.h
arch/ppc64/xmon/ppc-dis.c arch/powerpc/xmon/ppc-dis.c
arch/ppc64/xmon/ppc-opc.c arch/powerpc/xmon/ppc-opc.c
arch/ppc64/xmon/ppc.h arch/powerpc/xmon/ppc.h
-73
arch/ppc64/xmon/setjmp.S
··· 1 - /* 2 - * Copyright (C) 1996 Paul Mackerras. 3 - * 4 - * This program is free software; you can redistribute it and/or 5 - * modify it under the terms of the GNU General Public License 6 - * as published by the Free Software Foundation; either version 7 - * 2 of the License, or (at your option) any later version. 8 - * 9 - * NOTE: assert(sizeof(buf) > 184) 10 - */ 11 - #include <asm/processor.h> 12 - #include <asm/ppc_asm.h> 13 - 14 - _GLOBAL(xmon_setjmp) 15 - mflr r0 16 - std r0,0(r3) 17 - std r1,8(r3) 18 - std r2,16(r3) 19 - mfcr r0 20 - std r0,24(r3) 21 - std r13,32(r3) 22 - std r14,40(r3) 23 - std r15,48(r3) 24 - std r16,56(r3) 25 - std r17,64(r3) 26 - std r18,72(r3) 27 - std r19,80(r3) 28 - std r20,88(r3) 29 - std r21,96(r3) 30 - std r22,104(r3) 31 - std r23,112(r3) 32 - std r24,120(r3) 33 - std r25,128(r3) 34 - std r26,136(r3) 35 - std r27,144(r3) 36 - std r28,152(r3) 37 - std r29,160(r3) 38 - std r30,168(r3) 39 - std r31,176(r3) 40 - li r3,0 41 - blr 42 - 43 - _GLOBAL(xmon_longjmp) 44 - cmpdi r4,0 45 - bne 1f 46 - li r4,1 47 - 1: ld r13,32(r3) 48 - ld r14,40(r3) 49 - ld r15,48(r3) 50 - ld r16,56(r3) 51 - ld r17,64(r3) 52 - ld r18,72(r3) 53 - ld r19,80(r3) 54 - ld r20,88(r3) 55 - ld r21,96(r3) 56 - ld r22,104(r3) 57 - ld r23,112(r3) 58 - ld r24,120(r3) 59 - ld r25,128(r3) 60 - ld r26,136(r3) 61 - ld r27,144(r3) 62 - ld r28,152(r3) 63 - ld r29,160(r3) 64 - ld r30,168(r3) 65 - ld r31,176(r3) 66 - ld r0,24(r3) 67 - mtcrf 56,r0 68 - ld r0,0(r3) 69 - ld r1,8(r3) 70 - ld r2,16(r3) 71 - mtlr r0 72 - mr r3,r4 73 - blr
arch/ppc64/xmon/start.c arch/powerpc/xmon/start_64.c
+5 -6
arch/ppc64/xmon/subr_prf.c arch/powerpc/xmon/subr_prf.c
··· 18 18 19 19 #include <linux/kernel.h> 20 20 #include <linux/string.h> 21 + #include <linux/module.h> 21 22 #include <stdarg.h> 22 23 #include "nonstdio.h" 23 24 24 25 extern int xmon_write(void *, void *, int); 25 26 26 - void 27 - xmon_vfprintf(void *f, const char *fmt, va_list ap) 27 + void xmon_vfprintf(void *f, const char *fmt, va_list ap) 28 28 { 29 29 static char xmon_buf[2048]; 30 30 int n; ··· 33 33 xmon_write(f, xmon_buf, n); 34 34 } 35 35 36 - void 37 - xmon_printf(const char *fmt, ...) 36 + void xmon_printf(const char *fmt, ...) 38 37 { 39 38 va_list ap; 40 39 ··· 41 42 xmon_vfprintf(stdout, fmt, ap); 42 43 va_end(ap); 43 44 } 45 + EXPORT_SYMBOL(xmon_printf); 44 46 45 - void 46 - xmon_fprintf(void *f, const char *fmt, ...) 47 + void xmon_fprintf(void *f, const char *fmt, ...) 47 48 { 48 49 va_list ap; 49 50
+205 -189
arch/ppc64/xmon/xmon.c arch/powerpc/xmon/xmon.c
··· 17 17 #include <linux/delay.h> 18 18 #include <linux/kallsyms.h> 19 19 #include <linux/cpumask.h> 20 + #include <linux/module.h> 20 21 21 22 #include <asm/ptrace.h> 22 23 #include <asm/string.h> 23 24 #include <asm/prom.h> 24 25 #include <asm/machdep.h> 26 + #include <asm/xmon.h> 27 + #ifdef CONFIG_PMAC_BACKLIGHT 28 + #include <asm/backlight.h> 29 + #endif 25 30 #include <asm/processor.h> 26 31 #include <asm/pgtable.h> 27 32 #include <asm/mmu.h> 28 33 #include <asm/mmu_context.h> 29 - #include <asm/paca.h> 30 - #include <asm/ppcdebug.h> 31 34 #include <asm/cputable.h> 32 35 #include <asm/rtas.h> 33 36 #include <asm/sstep.h> 34 37 #include <asm/bug.h> 38 + 39 + #ifdef CONFIG_PPC64 35 40 #include <asm/hvcall.h> 41 + #include <asm/paca.h> 42 + #endif 36 43 37 44 #include "nonstdio.h" 38 - #include "privinst.h" 39 45 40 46 #define scanhex xmon_scanhex 41 47 #define skipbl xmon_skipbl ··· 64 58 static int termch; 65 59 static char tmpstr[128]; 66 60 67 - #define JMP_BUF_LEN (184/sizeof(long)) 61 + #define JMP_BUF_LEN 23 68 62 static long bus_error_jmp[JMP_BUF_LEN]; 69 63 static int catch_memory_errors; 70 64 static long *xmon_fault_jmp[NR_CPUS]; ··· 136 130 static int cpu_cmd(void); 137 131 static void csum(void); 138 132 static void bootcmds(void); 133 + static void proccall(void); 139 134 void dump_segments(void); 140 135 static void symbol_lookup(void); 141 136 static void xmon_print_symbol(unsigned long address, const char *mid, 142 137 const char *after); 143 138 static const char *getvecname(unsigned long vec); 144 139 145 - static void debug_trace(void); 146 - 147 140 extern int print_insn_powerpc(unsigned long, unsigned long, int); 148 141 extern void printf(const char *fmt, ...); 149 142 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); 150 143 extern int xmon_putc(int c, void *f); 151 144 extern int putchar(int ch); 145 + 146 + extern void xmon_enter(void); 147 + extern void xmon_leave(void); 148 + 152 149 extern int xmon_read_poll(void); 153 - extern int setjmp(long *); 154 - extern void longjmp(long *, int); 155 - extern unsigned long _ASR; 150 + extern long setjmp(long *); 151 + extern void longjmp(long *, long); 152 + extern void xmon_save_regs(struct pt_regs *); 153 + 154 + #ifdef CONFIG_PPC64 155 + #define REG "%.16lx" 156 + #define REGS_PER_LINE 4 157 + #define LAST_VOLATILE 13 158 + #else 159 + #define REG "%.8lx" 160 + #define REGS_PER_LINE 8 161 + #define LAST_VOLATILE 12 162 + #endif 156 163 157 164 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) 158 165 ··· 205 186 ml locate a block of memory\n\ 206 187 mz zero a block of memory\n\ 207 188 mi show information about memory allocation\n\ 208 - p show the task list\n\ 189 + p call a procedure\n\ 209 190 r print registers\n\ 210 191 s single step\n\ 211 192 S print special registers\n\ 212 193 t print backtrace\n\ 213 194 T Enable/Disable PPCDBG flags\n\ 214 195 x exit monitor and recover\n\ 215 - X exit monitor and dont recover\n\ 216 - u dump segment table or SLB\n\ 217 - ? help\n" 218 - "\ 219 - zr reboot\n\ 196 + X exit monitor and dont recover\n" 197 + #ifdef CONFIG_PPC64 198 + " u dump segment table or SLB\n" 199 + #endif 200 + #ifdef CONFIG_PPC_STD_MMU_32 201 + " u dump segment registers\n" 202 + #endif 203 + " ? help\n" 204 + " zr reboot\n\ 220 205 zh halt\n" 221 206 ; 222 207 223 208 static struct pt_regs *xmon_regs; 224 209 225 - extern inline void sync(void) 210 + static inline void sync(void) 226 211 { 227 212 asm volatile("sync; isync"); 228 213 } 229 214 230 - /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs). 231 - A PPC stack frame looks like this: 215 + static inline void store_inst(void *p) 216 + { 217 + asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); 218 + } 232 219 233 - High Address 234 - Back Chain 235 - FP reg save area 236 - GP reg save area 237 - Local var space 238 - Parameter save area (SP+48) 239 - TOC save area (SP+40) 240 - link editor doubleword (SP+32) 241 - compiler doubleword (SP+24) 242 - LR save (SP+16) 243 - CR save (SP+8) 244 - Back Chain (SP+0) 220 + static inline void cflush(void *p) 221 + { 222 + asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); 223 + } 245 224 246 - Note that the LR (ret addr) may not be saved in the current frame if 247 - no functions have been called from the current function. 248 - */ 225 + static inline void cinval(void *p) 226 + { 227 + asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); 228 + } 249 229 250 230 /* 251 231 * Disable surveillance (the service processor watchdog function) ··· 328 310 unsigned long timeout; 329 311 #endif 330 312 331 - msr = get_msr(); 332 - set_msrd(msr & ~MSR_EE); /* disable interrupts */ 313 + msr = mfmsr(); 314 + mtmsr(msr & ~MSR_EE); /* disable interrupts */ 333 315 334 316 bp = in_breakpoint_table(regs->nip, &offset); 335 317 if (bp != NULL) { ··· 505 487 506 488 insert_cpu_bpts(); 507 489 508 - set_msrd(msr); /* restore interrupt enable */ 490 + mtmsr(msr); /* restore interrupt enable */ 509 491 510 492 return cmd != 'X'; 511 493 } ··· 515 497 struct pt_regs regs; 516 498 517 499 if (excp == NULL) { 518 - /* Ok, grab regs as they are now. 519 - This won't do a particularily good job because the 520 - prologue has already been executed. 521 - ToDo: We could reach back into the callers save 522 - area to do a better job of representing the 523 - caller's state. 524 - */ 525 - asm volatile ("std 0,0(%0)\n\ 526 - std 1,8(%0)\n\ 527 - std 2,16(%0)\n\ 528 - std 3,24(%0)\n\ 529 - std 4,32(%0)\n\ 530 - std 5,40(%0)\n\ 531 - std 6,48(%0)\n\ 532 - std 7,56(%0)\n\ 533 - std 8,64(%0)\n\ 534 - std 9,72(%0)\n\ 535 - std 10,80(%0)\n\ 536 - std 11,88(%0)\n\ 537 - std 12,96(%0)\n\ 538 - std 13,104(%0)\n\ 539 - std 14,112(%0)\n\ 540 - std 15,120(%0)\n\ 541 - std 16,128(%0)\n\ 542 - std 17,136(%0)\n\ 543 - std 18,144(%0)\n\ 544 - std 19,152(%0)\n\ 545 - std 20,160(%0)\n\ 546 - std 21,168(%0)\n\ 547 - std 22,176(%0)\n\ 548 - std 23,184(%0)\n\ 549 - std 24,192(%0)\n\ 550 - std 25,200(%0)\n\ 551 - std 26,208(%0)\n\ 552 - std 27,216(%0)\n\ 553 - std 28,224(%0)\n\ 554 - std 29,232(%0)\n\ 555 - std 30,240(%0)\n\ 556 - std 31,248(%0)" : : "b" (&regs)); 557 - 558 - regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2]; 559 - regs.msr = get_msr(); 560 - regs.ctr = get_ctr(); 561 - regs.xer = get_xer(); 562 - regs.ccr = get_cr(); 563 - regs.trap = 0; 500 + xmon_save_regs(&regs); 564 501 excp = &regs; 565 502 } 566 503 return xmon_core(excp, 0); 504 + } 505 + EXPORT_SYMBOL(xmon); 506 + 507 + irqreturn_t 508 + xmon_irq(int irq, void *d, struct pt_regs *regs) 509 + { 510 + unsigned long flags; 511 + local_irq_save(flags); 512 + printf("Keyboard interrupt\n"); 513 + xmon(regs); 514 + local_irq_restore(flags); 515 + return IRQ_HANDLED; 567 516 } 568 517 569 518 int xmon_bpt(struct pt_regs *regs) ··· 703 718 if (dabr.enabled) 704 719 set_dabr(dabr.address | (dabr.enabled & 7)); 705 720 if (iabr && cpu_has_feature(CPU_FTR_IABR)) 706 - set_iabr(iabr->address 721 + mtspr(SPRN_IABR, iabr->address 707 722 | (iabr->enabled & (BP_IABR|BP_IABR_TE))); 708 723 } 709 724 ··· 731 746 { 732 747 set_dabr(0); 733 748 if (cpu_has_feature(CPU_FTR_IABR)) 734 - set_iabr(0); 749 + mtspr(SPRN_IABR, 0); 735 750 } 736 751 737 752 /* Command interpreting routine */ ··· 815 830 case '?': 816 831 printf(help_string); 817 832 break; 818 - case 'p': 819 - show_state(); 820 - break; 821 833 case 'b': 822 834 bpt_cmds(); 823 835 break; ··· 828 846 case 'z': 829 847 bootcmds(); 830 848 break; 831 - case 'T': 832 - debug_trace(); 849 + case 'p': 850 + proccall(); 833 851 break; 852 + #ifdef CONFIG_PPC_STD_MMU 834 853 case 'u': 835 854 dump_segments(); 836 855 break; 856 + #endif 837 857 default: 838 858 printf("Unrecognized command: "); 839 859 do { ··· 1054 1070 1055 1071 cmd = inchar(); 1056 1072 switch (cmd) { 1073 + #ifndef CONFIG_8xx 1057 1074 case 'd': /* bd - hardware data breakpoint */ 1058 1075 mode = 7; 1059 1076 cmd = inchar(); ··· 1096 1111 iabr = bp; 1097 1112 } 1098 1113 break; 1114 + #endif 1099 1115 1100 1116 case 'c': 1101 1117 if (!scanhex(&a)) { ··· 1138 1152 /* print all breakpoints */ 1139 1153 printf(" type address\n"); 1140 1154 if (dabr.enabled) { 1141 - printf(" data %.16lx [", dabr.address); 1155 + printf(" data "REG" [", dabr.address); 1142 1156 if (dabr.enabled & 1) 1143 1157 printf("r"); 1144 1158 if (dabr.enabled & 2) ··· 1217 1231 1218 1232 static int xmon_depth_to_print = 64; 1219 1233 1234 + #ifdef CONFIG_PPC64 1235 + #define LRSAVE_OFFSET 0x10 1236 + #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ 1237 + #define MARKER_OFFSET 0x60 1238 + #define REGS_OFFSET 0x70 1239 + #else 1240 + #define LRSAVE_OFFSET 4 1241 + #define REG_FRAME_MARKER 0x72656773 1242 + #define MARKER_OFFSET 8 1243 + #define REGS_OFFSET 16 1244 + #endif 1245 + 1220 1246 static void xmon_show_stack(unsigned long sp, unsigned long lr, 1221 1247 unsigned long pc) 1222 1248 { ··· 1245 1247 break; 1246 1248 } 1247 1249 1248 - if (!mread(sp + 16, &ip, sizeof(unsigned long)) 1250 + if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) 1249 1251 || !mread(sp, &newsp, sizeof(unsigned long))) { 1250 1252 printf("Couldn't read stack frame at %lx\n", sp); 1251 1253 break; ··· 1264 1266 get_function_bounds(pc, &fnstart, &fnend); 1265 1267 nextip = 0; 1266 1268 if (newsp > sp) 1267 - mread(newsp + 16, &nextip, 1269 + mread(newsp + LRSAVE_OFFSET, &nextip, 1268 1270 sizeof(unsigned long)); 1269 1271 if (lr == ip) { 1270 1272 if (lr < PAGE_OFFSET ··· 1278 1280 xmon_print_symbol(lr, " ", "\n"); 1279 1281 } 1280 1282 if (printip) { 1281 - printf("[%.16lx] ", sp); 1283 + printf("["REG"] ", sp); 1282 1284 xmon_print_symbol(ip, " ", " (unreliable)\n"); 1283 1285 } 1284 1286 pc = lr = 0; 1285 1287 1286 1288 } else { 1287 - printf("[%.16lx] ", sp); 1289 + printf("["REG"] ", sp); 1288 1290 xmon_print_symbol(ip, " ", "\n"); 1289 1291 } 1290 1292 1291 1293 /* Look for "regshere" marker to see if this is 1292 1294 an exception frame. */ 1293 - if (mread(sp + 0x60, &marker, sizeof(unsigned long)) 1294 - && marker == 0x7265677368657265ul) { 1295 - if (mread(sp + 0x70, &regs, sizeof(regs)) 1295 + if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) 1296 + && marker == REG_FRAME_MARKER) { 1297 + if (mread(sp + REGS_OFFSET, &regs, sizeof(regs)) 1296 1298 != sizeof(regs)) { 1297 1299 printf("Couldn't read registers at %lx\n", 1298 - sp + 0x70); 1300 + sp + REGS_OFFSET); 1299 1301 break; 1300 1302 } 1301 1303 printf("--- Exception: %lx %s at ", regs.trap, ··· 1369 1371 } 1370 1372 1371 1373 printf(" current = 0x%lx\n", current); 1374 + #ifdef CONFIG_PPC64 1372 1375 printf(" paca = 0x%lx\n", get_paca()); 1376 + #endif 1373 1377 if (current) { 1374 1378 printf(" pid = %ld, comm = %s\n", 1375 1379 current->pid, current->comm); ··· 1383 1383 1384 1384 void prregs(struct pt_regs *fp) 1385 1385 { 1386 - int n; 1386 + int n, trap; 1387 1387 unsigned long base; 1388 1388 struct pt_regs regs; 1389 1389 ··· 1396 1396 __delay(200); 1397 1397 } else { 1398 1398 catch_memory_errors = 0; 1399 - printf("*** Error reading registers from %.16lx\n", 1399 + printf("*** Error reading registers from "REG"\n", 1400 1400 base); 1401 1401 return; 1402 1402 } ··· 1404 1404 fp = &regs; 1405 1405 } 1406 1406 1407 + #ifdef CONFIG_PPC64 1407 1408 if (FULL_REGS(fp)) { 1408 1409 for (n = 0; n < 16; ++n) 1409 - printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", 1410 + printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1410 1411 n, fp->gpr[n], n+16, fp->gpr[n+16]); 1411 1412 } else { 1412 1413 for (n = 0; n < 7; ++n) 1413 - printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", 1414 + printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1414 1415 n, fp->gpr[n], n+7, fp->gpr[n+7]); 1415 1416 } 1417 + #else 1418 + for (n = 0; n < 32; ++n) { 1419 + printf("R%.2d = %.8x%s", n, fp->gpr[n], 1420 + (n & 3) == 3? "\n": " "); 1421 + if (n == 12 && !FULL_REGS(fp)) { 1422 + printf("\n"); 1423 + break; 1424 + } 1425 + } 1426 + #endif 1416 1427 printf("pc = "); 1417 1428 xmon_print_symbol(fp->nip, " ", "\n"); 1418 1429 printf("lr = "); 1419 1430 xmon_print_symbol(fp->link, " ", "\n"); 1420 - printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr); 1421 - printf("ctr = %.16lx xer = %.16lx trap = %8lx\n", 1431 + printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); 1432 + printf("ctr = "REG" xer = "REG" trap = %4lx\n", 1422 1433 fp->ctr, fp->xer, fp->trap); 1434 + trap = TRAP(fp); 1435 + if (trap == 0x300 || trap == 0x380 || trap == 0x600) 1436 + printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); 1423 1437 } 1424 1438 1425 1439 void cacheflush(void) ··· 1533 1519 extern char exc_prolog; 1534 1520 extern char dec_exc; 1535 1521 1536 - void 1537 - super_regs(void) 1522 + void super_regs(void) 1538 1523 { 1539 1524 int cmd; 1540 1525 unsigned long val; ··· 1549 1536 asm("mr %0,1" : "=r" (sp) :); 1550 1537 asm("mr %0,2" : "=r" (toc) :); 1551 1538 1552 - printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0()); 1553 - printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1()); 1554 - printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2()); 1555 - printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3()); 1556 - printf("toc = %.16lx dar = %.16lx\n", toc, get_dar()); 1557 - printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1()); 1539 + printf("msr = "REG" sprg0= "REG"\n", 1540 + mfmsr(), mfspr(SPRN_SPRG0)); 1541 + printf("pvr = "REG" sprg1= "REG"\n", 1542 + mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 1543 + printf("dec = "REG" sprg2= "REG"\n", 1544 + mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); 1545 + printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1546 + printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 1558 1547 #ifdef CONFIG_PPC_ISERIES 1559 1548 // Dump out relevant Paca data areas. 1560 1549 printf("Paca: \n"); ··· 1593 1578 case 'r': 1594 1579 printf("spr %lx = %lx\n", regno, read_spr(regno)); 1595 1580 break; 1596 - case 'm': 1597 - val = get_msr(); 1598 - scanhex(&val); 1599 - set_msrd(val); 1600 - break; 1601 1581 } 1602 1582 scannl(); 1603 1583 } ··· 1614 1604 q = (char *)buf; 1615 1605 switch (size) { 1616 1606 case 2: 1617 - *(short *)q = *(short *)p; 1607 + *(u16 *)q = *(u16 *)p; 1618 1608 break; 1619 1609 case 4: 1620 - *(int *)q = *(int *)p; 1610 + *(u32 *)q = *(u32 *)p; 1621 1611 break; 1622 1612 case 8: 1623 - *(long *)q = *(long *)p; 1613 + *(u64 *)q = *(u64 *)p; 1624 1614 break; 1625 1615 default: 1626 1616 for( ; n < size; ++n) { ··· 1651 1641 q = (char *) buf; 1652 1642 switch (size) { 1653 1643 case 2: 1654 - *(short *)p = *(short *)q; 1644 + *(u16 *)p = *(u16 *)q; 1655 1645 break; 1656 1646 case 4: 1657 - *(int *)p = *(int *)q; 1647 + *(u32 *)p = *(u32 *)q; 1658 1648 break; 1659 1649 case 8: 1660 - *(long *)p = *(long *)q; 1650 + *(u64 *)p = *(u64 *)q; 1661 1651 break; 1662 1652 default: 1663 1653 for ( ; n < size; ++n) { ··· 1677 1667 } 1678 1668 1679 1669 static int fault_type; 1670 + static int fault_except; 1680 1671 static char *fault_chars[] = { "--", "**", "##" }; 1681 1672 1682 - static int 1683 - handle_fault(struct pt_regs *regs) 1673 + static int handle_fault(struct pt_regs *regs) 1684 1674 { 1675 + fault_except = TRAP(regs); 1685 1676 switch (TRAP(regs)) { 1686 1677 case 0x200: 1687 1678 fault_type = 0; ··· 1971 1960 unsigned char temp[16]; 1972 1961 1973 1962 for (n = ndump; n > 0;) { 1974 - printf("%.16lx", adrs); 1963 + printf(REG, adrs); 1975 1964 putchar(' '); 1976 1965 r = n < 16? n: 16; 1977 1966 nr = mread(adrs, temp, r); ··· 2019 2008 if (nr == 0) { 2020 2009 if (praddr) { 2021 2010 const char *x = fault_chars[fault_type]; 2022 - printf("%.16lx %s%s%s%s\n", adr, x, x, x, x); 2011 + printf(REG" %s%s%s%s\n", adr, x, x, x, x); 2023 2012 } 2024 2013 break; 2025 2014 } ··· 2034 2023 dotted = 0; 2035 2024 last_inst = inst; 2036 2025 if (praddr) 2037 - printf("%.16lx %.8x", adr, inst); 2026 + printf(REG" %.8x", adr, inst); 2038 2027 printf("\t"); 2039 2028 print_insn_powerpc(inst, adr, 0); /* always returns 4 */ 2040 2029 printf("\n"); ··· 2163 2152 printf("%.8x\n", a - mskip); 2164 2153 } 2165 2154 2155 + void proccall(void) 2156 + { 2157 + unsigned long args[8]; 2158 + unsigned long ret; 2159 + int i; 2160 + typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, 2161 + unsigned long, unsigned long, unsigned long, 2162 + unsigned long, unsigned long, unsigned long); 2163 + callfunc_t func; 2164 + 2165 + if (!scanhex(&adrs)) 2166 + return; 2167 + if (termch != '\n') 2168 + termch = 0; 2169 + for (i = 0; i < 8; ++i) 2170 + args[i] = 0; 2171 + for (i = 0; i < 8; ++i) { 2172 + if (!scanhex(&args[i]) || termch == '\n') 2173 + break; 2174 + termch = 0; 2175 + } 2176 + func = (callfunc_t) adrs; 2177 + ret = 0; 2178 + if (setjmp(bus_error_jmp) == 0) { 2179 + catch_memory_errors = 1; 2180 + sync(); 2181 + ret = func(args[0], args[1], args[2], args[3], 2182 + args[4], args[5], args[6], args[7]); 2183 + sync(); 2184 + printf("return value is %x\n", ret); 2185 + } else { 2186 + printf("*** %x exception occurred\n", fault_except); 2187 + } 2188 + catch_memory_errors = 0; 2189 + } 2190 + 2166 2191 /* Input scanning routines */ 2167 2192 int 2168 2193 skipbl(void) ··· 2221 2174 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 2222 2175 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 2223 2176 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 2224 - "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe", 2177 + "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", 2178 + #ifdef CONFIG_PPC64 2179 + "softe", 2180 + #else 2181 + "mq", 2182 + #endif 2225 2183 "trap", "dar", "dsisr", "res" 2226 2184 }; 2227 2185 ··· 2332 2280 c = inchar(); 2333 2281 } 2334 2282 2335 - int 2336 - hexdigit(int c) 2283 + int hexdigit(int c) 2337 2284 { 2338 2285 if( '0' <= c && c <= '9' ) 2339 2286 return c - '0'; ··· 2429 2378 const char *name = NULL; 2430 2379 unsigned long offset, size; 2431 2380 2432 - printf("%.16lx", address); 2381 + printf(REG, address); 2433 2382 if (setjmp(bus_error_jmp) == 0) { 2434 2383 catch_memory_errors = 1; 2435 2384 sync(); ··· 2450 2399 printf("%s", after); 2451 2400 } 2452 2401 2453 - static void debug_trace(void) 2454 - { 2455 - unsigned long val, cmd, on; 2456 - 2457 - cmd = skipbl(); 2458 - if (cmd == '\n') { 2459 - /* show current state */ 2460 - unsigned long i; 2461 - printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch); 2462 - for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) { 2463 - on = PPCDBG_BITVAL(i) & ppc64_debug_switch; 2464 - printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : ""); 2465 - if (((i+1) % 3) == 0) 2466 - printf("\n"); 2467 - } 2468 - printf("\n"); 2469 - return; 2470 - } 2471 - while (cmd != '\n') { 2472 - on = 1; /* default if no sign given */ 2473 - while (cmd == '+' || cmd == '-') { 2474 - on = (cmd == '+'); 2475 - cmd = inchar(); 2476 - if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */ 2477 - ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE; 2478 - printf("Setting all values to %s...\n", on ? "on" : "off"); 2479 - if (cmd == '\n') return; 2480 - else cmd = skipbl(); 2481 - } 2482 - else 2483 - termch = cmd; 2484 - } 2485 - termch = cmd; /* not +/- ... let scanhex see it */ 2486 - scanhex((void *)&val); 2487 - if (val >= 64) { 2488 - printf("Value %x out of range:\n", val); 2489 - return; 2490 - } 2491 - if (on) { 2492 - ppc64_debug_switch |= PPCDBG_BITVAL(val); 2493 - printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : ""); 2494 - } else { 2495 - ppc64_debug_switch &= ~PPCDBG_BITVAL(val); 2496 - printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : ""); 2497 - } 2498 - cmd = skipbl(); 2499 - } 2500 - } 2501 - 2402 + #ifdef CONFIG_PPC64 2502 2403 static void dump_slb(void) 2503 2404 { 2504 2405 int i; ··· 2487 2484 } 2488 2485 } 2489 2486 2487 + void dump_segments(void) 2488 + { 2489 + if (cpu_has_feature(CPU_FTR_SLB)) 2490 + dump_slb(); 2491 + else 2492 + dump_stab(); 2493 + } 2494 + #endif 2495 + 2496 + #ifdef CONFIG_PPC_STD_MMU_32 2497 + void dump_segments(void) 2498 + { 2499 + int i; 2500 + 2501 + printf("sr0-15 ="); 2502 + for (i = 0; i < 16; ++i) 2503 + printf(" %x", mfsrin(i)); 2504 + printf("\n"); 2505 + } 2506 + #endif 2507 + 2490 2508 void xmon_init(int enable) 2491 2509 { 2492 2510 if (enable) { ··· 2527 2503 __debugger_dabr_match = NULL; 2528 2504 __debugger_fault_handler = NULL; 2529 2505 } 2530 - } 2531 - 2532 - void dump_segments(void) 2533 - { 2534 - if (cpu_has_feature(CPU_FTR_SLB)) 2535 - dump_slb(); 2536 - else 2537 - dump_stab(); 2538 2506 }
+8
include/asm-powerpc/ppc_asm.h
··· 188 188 #define LDL ld 189 189 #define STL std 190 190 #define CMPI cmpdi 191 + #define SZL 8 192 + 193 + /* offsets for stack frame layout */ 194 + #define LRSAVE 16 191 195 192 196 #else /* 32-bit */ 193 197 #define LOADADDR(rn,name) \ ··· 207 203 #define LDL lwz 208 204 #define STL stw 209 205 #define CMPI cmpwi 206 + #define SZL 4 207 + 208 + /* offsets for stack frame layout */ 209 + #define LRSAVE 4 210 210 211 211 #endif 212 212
+1
include/asm-powerpc/reg.h
··· 546 546 #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ 547 547 : : "r" (v)) 548 548 #define mtmsrd(v) __mtmsrd((v), 0) 549 + #define mtmsr(v) mtmsrd(v) 549 550 #else 550 551 #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) 551 552 #endif
+1 -1
include/asm-powerpc/xmon.h
··· 4 4 5 5 struct pt_regs; 6 6 7 - extern void xmon(struct pt_regs *excp); 7 + extern int xmon(struct pt_regs *excp); 8 8 extern void xmon_printf(const char *fmt, ...); 9 9 extern void xmon_init(int); 10 10