#endif /* CONFIG_SMP */
static void csum(void);
static void bootcmds(void);
-static void mem_translate(void);
-static void mem_check(void);
-static void mem_find_real(void);
-static void mem_find_vsid(void);
+void dump_segments(void);
static void debug_trace(void);
b show breakpoints\n\
bd set data breakpoint\n\
bi set instruction breakpoint\n\
- bc clear breakpoint\n\
+ bc clear breakpoint\n"
+#ifdef CONFIG_SMP
+ "\
+ c print cpus stopped in xmon\n\
+ ci send xmon interrupt to all other cpus\n\
+ c# try to switch to cpu number h (in hex)\n"
+#endif
+ "\
+ C checksum\n\
d dump bytes\n\
di dump instructions\n\
df dump float values\n\
md compare two blocks of memory\n\
ml locate a block of memory\n\
mz zero a block of memory\n\
- mx translation information for an effective address\n\
mi show information about memory allocation\n\
p show the task list\n\
r print registers\n\
t print backtrace\n\
T Enable/Disable PPCDBG flags\n\
x exit monitor\n\
-";
+ u dump segment table or SLB\n\
+ ? help\n"
+#ifndef CONFIG_PPC_ISERIES
+ "\
+ zr reboot\n\
+ zh halt\n"
+#endif
+;
static int xmon_trace[NR_CPUS];
#define SSTEP 1 /* stepping because of 's' command */
#endif /* CONFIG_SMP */
remove_bpts();
disable_surveillance();
+ printf("press ? for help ");
cmd = cmds(excp);
if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP;
set_msrd(msr); /* restore interrupt enable */
}
-void
-xmon_irq(int irq, void *d, struct pt_regs *regs)
-{
- unsigned long flags;
- local_save_flags(flags);
- local_irq_disable();
- printf("Keyboard interrupt\n");
- xmon(regs);
- local_irq_restore(flags);
-}
-
int
xmon_bpt(struct pt_regs *regs)
{
case 'z':
memzcan();
break;
- case 'x':
- mem_translate();
- break;
- case 'c':
- mem_check();
- break;
- case 'f':
- mem_find_real();
- break;
- case 'e':
- mem_find_vsid();
- break;
case 'i':
show_mem();
break;
cpu_cmd();
break;
#endif /* CONFIG_SMP */
+#ifndef CONFIG_PPC_ISERIES
case 'z':
bootcmds();
+#endif
case 'T':
debug_trace();
break;
+ case 'u':
+ dump_segments();
+ break;
default:
printf("Unrecognized command: ");
do {
termch = 0;
nflush = 1;
scanhex(&nflush);
- nflush = (nflush + 31) / 32;
- if (cmd != 'i') {
- for (; nflush > 0; --nflush, adrs += 0x20)
- cflush((void *) adrs);
- } else {
- for (; nflush > 0; --nflush, adrs += 0x20)
- cinval((void *) adrs);
+ nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
+ if( setjmp(bus_error_jmp) == 0 ) {
+ debugger_fault_handler = handle_fault;
+ sync();
+
+ if (cmd != 'i') {
+ for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
+ cflush((void *) adrs);
+ } else {
+ for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
+ cinval((void *) adrs);
+ }
+ sync();
+ /* wait a little while to see if we get a machine check */
+ __delay(200);
}
+ debugger_fault_handler = 0;
}
unsigned long
unsigned int instrs[2];
unsigned long (*code)(void);
unsigned long opd[3];
+ unsigned long ret = -1UL;
instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
instrs[1] = 0x4e800020;
store_inst(instrs+1);
code = (unsigned long (*)(void)) opd;
- return code();
+ if (setjmp(bus_error_jmp) == 0) {
+ debugger_fault_handler = handle_fault;
+ sync();
+
+ ret = code();
+
+ sync();
+ /* wait a little while to see if we get a machine check */
+ __delay(200);
+ } else {
+ printf("*** Error reading spr %x\n", n);
+ }
+
+ debugger_fault_handler = 0;
+
+ return ret;
}
void
store_inst(instrs+1);
code = (unsigned long (*)(unsigned long)) opd;
- code(val);
+ if (setjmp(bus_error_jmp) == 0) {
+ debugger_fault_handler = handle_fault;
+ sync();
+
+ code(val);
+
+ sync();
+ /* wait a little while to see if we get a machine check */
+ __delay(200);
+ } else {
+ printf("*** Error writing spr %x\n", n);
+ }
+
+ debugger_fault_handler = 0;
}
static unsigned long regno;
void
super_regs()
{
- int i, cmd;
+ int cmd;
unsigned long val;
- struct paca_struct* ptrPaca = NULL;
- struct ItLpPaca* ptrLpPaca = NULL;
- struct ItLpRegSave* ptrLpRegSave = NULL;
+#ifdef CONFIG_PPC_ISERIES
+ int i;
+ struct paca_struct *ptrPaca = NULL;
+ struct ItLpPaca *ptrLpPaca = NULL;
+ struct ItLpRegSave *ptrLpRegSave = NULL;
+#endif
cmd = skipbl();
if (cmd == '\n') {
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("asr = %.16lx\n", mfasr());
- for (i = 0; i < 8; ++i)
- printf("sr%.2ld = %.16lx sr%.2ld = %.16lx\n", i, get_sr(i), i+8, get_sr(i+8));
-
+#ifdef CONFIG_PPC_ISERIES
// Dump out relevant Paca data areas.
printf("Paca: \n");
ptrPaca = get_paca();
printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
-
+#endif
+
return;
}
case 'r':
printf("spr %lx = %lx\n", regno, read_spr(regno));
break;
- case 's':
- val = get_sr(regno);
- scanhex(&val);
- set_sr(regno, val);
- break;
case 'm':
val = get_msr();
scanhex(&val);
}
}
-void
-mem_translate()
-{
- int c;
- unsigned long ea, va, vsid, vpn, page, hpteg_slot_primary, hpteg_slot_secondary, primary_hash, i, *steg, esid, stabl;
- HPTE * hpte;
- struct mm_struct * mm;
- pte_t *ptep = NULL;
- void * pgdir;
-
- c = inchar();
- if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
- termch = c;
- scanhex((void *)&ea);
-
- if ((ea >= KRANGE_START) && (ea <= (KRANGE_START + (1UL<<60)))) {
- ptep = 0;
- vsid = get_kernel_vsid(ea);
- va = ( vsid << 28 ) | ( ea & 0x0fffffff );
- } else {
- // if in vmalloc range, use the vmalloc page directory
- if ( ( ea >= VMALLOC_START ) && ( ea <= VMALLOC_END ) ) {
- mm = &init_mm;
- vsid = get_kernel_vsid( ea );
- }
- // if in ioremap range, use the ioremap page directory
- else if ( ( ea >= IMALLOC_START ) && ( ea <= IMALLOC_END ) ) {
- mm = &ioremap_mm;
- vsid = get_kernel_vsid( ea );
- }
- // if in user range, use the current task's page directory
- else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) {
- mm = current->mm;
- vsid = get_vsid(mm->context, ea );
- }
- pgdir = mm->pgd;
- va = ( vsid << 28 ) | ( ea & 0x0fffffff );
- ptep = find_linux_pte( pgdir, ea );
- }
-
- vpn = ((vsid << 28) | (((ea) & 0xFFFF000))) >> 12;
- page = vpn & 0xffff;
- esid = (ea >> 28) & 0xFFFFFFFFF;
-
- // Search the primary group for an available slot
- primary_hash = ( vsid & 0x7fffffffff ) ^ page;
- hpteg_slot_primary = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
- hpteg_slot_secondary = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
-
- printf("ea : %.16lx\n", ea);
- printf("esid : %.16lx\n", esid);
- printf("vsid : %.16lx\n", vsid);
-
- printf("\nSoftware Page Table\n-------------------\n");
- printf("ptep : %.16lx\n", ((unsigned long *)ptep));
- if(ptep) {
- printf("*ptep : %.16lx\n", *((unsigned long *)ptep));
- }
-
- hpte = htab_data.htab + hpteg_slot_primary;
- printf("\nHardware Page Table\n-------------------\n");
- printf("htab base : %.16lx\n", htab_data.htab);
- printf("slot primary : %.16lx\n", hpteg_slot_primary);
- printf("slot secondary : %.16lx\n", hpteg_slot_secondary);
- printf("\nPrimary Group\n");
- for (i=0; i<8; ++i) {
- if ( hpte->dw0.dw0.v != 0 ) {
- printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
- printf(" vsid: %.13lx api: %.2lx hash: %.1lx\n",
- (hpte->dw0.dw0.avpn)>>5,
- (hpte->dw0.dw0.avpn) & 0x1f,
- (hpte->dw0.dw0.h));
- printf(" rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
- printf(" pp: %.1lx \n",
- ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
- printf(" wimgn: %.2lx reference: %.1lx change: %.1lx\n",
- ((hpte->dw1.dw1.w)<<4)|
- ((hpte->dw1.dw1.i)<<3)|
- ((hpte->dw1.dw1.m)<<2)|
- ((hpte->dw1.dw1.g)<<1)|
- ((hpte->dw1.dw1.n)<<0),
- hpte->dw1.dw1.r, hpte->dw1.dw1.c);
- }
- hpte++;
- }
-
- printf("\nSecondary Group\n");
- // Search the secondary group
- hpte = htab_data.htab + hpteg_slot_secondary;
- for (i=0; i<8; ++i) {
- if(hpte->dw0.dw0.v) {
- printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
- printf(" vsid: %.13lx api: %.2lx hash: %.1lx\n",
- (hpte->dw0.dw0.avpn)>>5,
- (hpte->dw0.dw0.avpn) & 0x1f,
- (hpte->dw0.dw0.h));
- printf(" rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
- printf(" pp: %.1lx \n",
- ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
- printf(" wimgn: %.2lx reference: %.1lx change: %.1lx\n",
- ((hpte->dw1.dw1.w)<<4)|
- ((hpte->dw1.dw1.i)<<3)|
- ((hpte->dw1.dw1.m)<<2)|
- ((hpte->dw1.dw1.g)<<1)|
- ((hpte->dw1.dw1.n)<<0),
- hpte->dw1.dw1.r, hpte->dw1.dw1.c);
- }
- hpte++;
- }
-
- printf("\nHardware Segment Table\n-----------------------\n");
- stabl = (unsigned long)(KERNELBASE+(_ASR&0xFFFFFFFFFFFFFFFE));
- steg = (unsigned long *)((stabl) | ((esid & 0x1f) << 7));
-
- printf("stab base : %.16lx\n", stabl);
- printf("slot : %.16lx\n", steg);
-
- for (i=0; i<8; ++i) {
- printf("%d: (ste) %.16lx %.16lx\n", i,
- *((unsigned long *)(steg+i*2)),*((unsigned long *)(steg+i*2+1)) );
- }
-}
-
-void mem_check()
-{
- unsigned long htab_size_bytes;
- unsigned long htab_end;
- unsigned long last_rpn;
- HPTE *hpte1, *hpte2;
-
- htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
- htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
- // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
- last_rpn = 0xfffff;
-
- printf("\nHardware Page Table Check\n-------------------\n");
- printf("htab base : %.16lx\n", htab_data.htab);
- printf("htab size : %.16lx\n", htab_size_bytes);
-
-#if 1
- for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
- if ( hpte1->dw0.dw0.v != 0 ) {
- if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
- for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
- if ( hpte2->dw0.dw0.v != 0 ) {
- if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
- printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
- printf(" hpte1: %16.16lx *hpte1: %16.16lx %16.16lx\n",
- hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
- printf(" hpte2: %16.16lx *hpte2: %16.16lx %16.16lx\n",
- hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
- }
- }
- }
- } else {
- printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
- printf(" hpte: %16.16lx *hpte: %16.16lx %16.16lx\n",
- hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
- }
- }
- }
-#endif
- printf("\nDone -------------------\n");
-}
-
-void mem_find_real()
+static void debug_trace(void)
{
- unsigned long htab_size_bytes;
- unsigned long htab_end;
- unsigned long last_rpn;
- HPTE *hpte1;
- unsigned long pa, rpn;
- int c;
-
- c = inchar();
- if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
- termch = c;
- scanhex((void *)&pa);
- rpn = pa >> 12;
-
- htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
- htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
- // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
- last_rpn = 0xfffff;
-
- printf("\nMem Find RPN\n-------------------\n");
- printf("htab base : %.16lx\n", htab_data.htab);
- printf("htab size : %.16lx\n", htab_size_bytes);
-
- for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
- if ( hpte1->dw0.dw0.v != 0 ) {
- if ( hpte1->dw1.dw1.rpn == rpn ) {
- printf(" Found rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
- printf(" hpte: %16.16lx *hpte1: %16.16lx %16.16lx\n",
- hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
- }
- }
- }
- printf("\nDone -------------------\n");
-}
-
-void mem_find_vsid()
-{
- unsigned long htab_size_bytes;
- unsigned long htab_end;
- HPTE *hpte1;
- unsigned long vsid;
- int c;
-
- c = inchar();
- if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
- termch = c;
- scanhex((void *)&vsid);
-
- htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
- htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
-
- printf("\nMem Find VSID\n-------------------\n");
- printf("htab base : %.16lx\n", htab_data.htab);
- printf("htab size : %.16lx\n", htab_size_bytes);
-
- for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
- if ( hpte1->dw0.dw0.v != 0 ) {
- if ( ((hpte1->dw0.dw0.avpn)>>5) == vsid ) {
- printf(" Found vsid: %.16lx \n", ((hpte1->dw0.dw0.avpn) >> 5));
- printf(" hpte: %16.16lx *hpte1: %16.16lx %16.16lx\n",
- hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
- }
- }
- }
- printf("\nDone -------------------\n");
-}
-
-static void debug_trace(void) {
unsigned long val, cmd, on;
cmd = skipbl();
cmd = skipbl();
}
}
+
+static void dump_slb(void)
+{
+ int i;
+ unsigned long tmp;
+
+ printf("SLB contents of cpu %d\n", smp_processor_id());
+
+ for (i = 0; i < naca->slb_size; i++) {
+ asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
+ printf("%02d %016lx ", i, tmp);
+
+ asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
+ printf("%016lx\n", tmp);
+ }
+}
+
+static void dump_stab(void)
+{
+ int i;
+ unsigned long *tmp = (unsigned long *)get_paca()->xStab_data.virt;
+
+ printf("Segment table contents of cpu %d\n", smp_processor_id());
+
+ for (i = 0; i < PAGE_SIZE/16; i++) {
+ unsigned long a, b;
+
+ a = *tmp++;
+ b = *tmp++;
+
+ if (a || b) {
+ printf("%03d %016lx ", i, a);
+ printf("%016lx\n", b);
+ }
+ }
+}
+
+void dump_segments(void)
+{
+ if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
+ dump_slb();
+ else
+ dump_stab();
+}