[parisc-linux-cvs] 2.4.16-pa15 patch
Helge Deller
deller@gmx.de
Wed, 5 Dec 2001 00:18:47 +0100
--------------Boundary-00=_B3EUU1BKUUK7QXEGT1RX
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 8bit
On Wednesday 05 December 2001 00:19, Helge Deller wrote:
> CVSROOT: /var/cvs
> Module name: linux
> Changes by: deller 01/12/04 16:19:47
>
> Modified files:
> . : Makefile
> arch/parisc/kernel: traps.c
> arch/parisc/mm : fault.c
> include/asm-parisc: traps.h unaligned.h
>
> Log message:
> - 2.4.16-pa15
> - nicer kernel dump output
> - reorganizing of code to avoid "extern XXX()'s"
--------------Boundary-00=_B3EUU1BKUUK7QXEGT1RX
Content-Type: text/plain;
charset="iso-8859-1";
name="di"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="di"
Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.218
diff -u -p -r1.218 Makefile
--- Makefile 2001/12/04 18:06:00 1.218
+++ Makefile 2001/12/04 22:53:46
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 16
-EXTRAVERSION = -pa14
+EXTRAVERSION = -pa15
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
Index: arch/parisc/kernel/traps.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/traps.c,v
retrieving revision 1.58
diff -u -p -r1.58 traps.c
--- arch/parisc/kernel/traps.c 2001/12/04 02:12:40 1.58
+++ arch/parisc/kernel/traps.c 2001/12/04 22:53:56
@@ -24,12 +24,14 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/console.h>
+
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/unaligned.h>
#include <asm/atomic.h>
-
#include <asm/smp.h>
#include <asm/pdc.h>
@@ -44,10 +46,7 @@
#endif /* CONFIG_KWDB */
#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
- /* dumped to the console via printk) */
-
-extern void handle_unaligned(struct pt_regs *regs);
-extern int check_unaligned(struct pt_regs *regs);
+ /* dumped to the console via printk) */
static int printbinary(char *buf, unsigned long x, int nbits)
{
@@ -86,9 +85,9 @@ void show_regs(struct pt_regs *regs)
for (i = 0; i < 32; i += 4) {
int j;
p = buf;
- p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3);
+ p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3);
for (j = 0; j < 4; j++) {
- p += sprintf(p, " " RFMT, i + j == 0 ? 0 : regs->gr[i + j]);
+ p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]);
}
printk("%s\n", buf);
}
@@ -96,7 +95,7 @@ void show_regs(struct pt_regs *regs)
for (i = 0; i < 8; i += 4) {
int j;
p = buf;
- p += sprintf(p, "%ssr%02d-%02d ", level, i, i + 3);
+ p += sprintf(p, "%ssr%d-%d ", level, i, i + 3);
for (j = 0; j < 4; j++) {
p += sprintf(p, " " RFMT, regs->sr[i + j]);
}
@@ -120,17 +119,90 @@ void show_regs(struct pt_regs *regs)
level, ((struct task_struct *)cr30)->processor, cr30, cr31);
printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
}
+
+
+static void dump_stack(unsigned long from, unsigned long to, int istackflag)
+{
+ unsigned int *fromptr;
+ unsigned int *toptr;
+
+ fromptr = (unsigned int *)from;
+ toptr = (unsigned int *)to;
+
+ if (istackflag)
+ printk("\nDumping Interrupt Stack from %p to %p:\n",fromptr,toptr);
+ else
+ printk("\nDumping Stack from %p to %p:\n",fromptr,toptr);
+ while (fromptr < toptr) {
+ printk("%04lx %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ ((unsigned long)fromptr) & 0xffff,
+ fromptr[0], fromptr[1], fromptr[2], fromptr[3],
+ fromptr[4], fromptr[5], fromptr[6], fromptr[7]);
+ fromptr += 8;
+ }
+ return;
+}
-void
-die_if_kernel (char *str, struct pt_regs *regs, long err)
+
+void show_stack(struct pt_regs *regs)
{
+#if 1
+ /* If regs->sr[7] == 0, we are on a kernel stack */
+ if (regs->sr[7] == 0) {
+
+ unsigned long sp = regs->gr[30];
+ unsigned long cr30;
+ unsigned long cr31;
+ unsigned long stack_start;
+ struct pt_regs *int_regs;
+
+ cr30 = mfctl(30);
+ cr31 = mfctl(31);
+ stack_start = sp & ~(ISTACK_SIZE - 1);
+ if (stack_start == cr31) {
+ /*
+ * We are on the interrupt stack, get the stack
+ * pointer from the first pt_regs structure on
+ * the interrupt stack, so we can dump the task
+ * stack first.
+ */
+
+ int_regs = (struct pt_regs *)cr31;
+ sp = int_regs->gr[30];
+ stack_start = sp & ~(INIT_TASK_SIZE - 1);
+ if (stack_start != cr30)
+ printk(KERN_CRIT "WARNING! Stack pointer and cr30 do not correspond!\n");
+ dump_stack(stack_start, sp, 0);
+
+ printk("\n\nRegisters at Interrupt:\n");
+ show_regs(int_regs);
+
+ /* Now dump the interrupt stack */
+
+ sp = regs->gr[30];
+ stack_start = sp & ~(ISTACK_SIZE - 1);
+ dump_stack(stack_start,sp,1);
+ }
+ else
+ {
+ /* Stack Dump! */
+ printk(KERN_CRIT "WARNING! Stack pointer and cr30 do not correspond!\n");
+ dump_stack(stack_start, sp, 0);
+ }
+ }
+#endif
+}
+
+
+void die_if_kernel(char *str, struct pt_regs *regs, long err)
+{
if (user_mode(regs)) {
#ifdef PRINT_USER_FAULTS
if (err == 0)
return; /* STFU */
/* XXX for debugging only */
- printk(KERN_DEBUG "!!die_if_kernel: %s(%d): %s %ld\n",
+ printk(KERN_DEBUG "%s (pid %d): %s (code %ld)\n",
current->comm, current->pid, str, err);
show_regs(regs);
#endif
@@ -144,16 +216,17 @@ die_if_kernel (char *str, struct pt_regs
if (!console_drivers)
pdc_console_restart();
- printk(KERN_CRIT "%s[%d]: %s %ld\n", current->comm, current->pid, str, err);
-
+ printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
+ current->comm, current->pid, str, err);
show_regs(regs);
/* Wot's wrong wif bein' racy? */
if (current->thread.flags & PARISC_KERNEL_DEATH) {
- printk(KERN_CRIT "die_if_kernel recursion detected.\n");
+ printk(KERN_CRIT "%s() recursion detected.\n", __FUNCTION__);
sti();
while (1);
}
+
current->thread.flags |= PARISC_KERNEL_DEATH;
do_exit(SIGSEGV);
}
@@ -245,7 +318,7 @@ int handle_toc(void)
return 0;
}
-void default_trap(int code, struct pt_regs *regs)
+static void default_trap(int code, struct pt_regs *regs)
{
printk(KERN_ERR "Trap %d on CPU %d\n", code, smp_processor_id());
show_regs(regs);
@@ -255,21 +328,128 @@ void (*cpu_lpmc) (int code, struct pt_re
#ifdef CONFIG_KWDB
-int
-debug_call (void) {
+int debug_call (void)
+{
printk ("Debug call.\n");
return 0;
}
-int
-debug_call_leaf (void) {
+int debug_call_leaf (void)
+{
return 0;
}
#endif /* CONFIG_KWDB */
+
+
+void transfer_pim_to_trap_frame(struct pt_regs *regs)
+{
+ register int i;
+ extern unsigned int hpmc_pim_data[];
+ struct pdc_hpmc_pim_11 *pim_narrow;
+ struct pdc_hpmc_pim_20 *pim_wide;
+
+ if (boot_cpu_data.cpu_type >= pcxu) {
+
+ pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;
-extern void do_page_fault(struct pt_regs *, int, unsigned long); /* in mm/fault.c */
-extern void parisc_terminate(char *, struct pt_regs *, int, unsigned long);
-extern void transfer_pim_to_trap_frame(struct pt_regs *);
+ /*
+ * Note: The following code will probably generate a
+ * bunch of truncation error warnings from the compiler.
+ * Could be handled with an ifdef, but perhaps there
+ * is a better way.
+ */
+
+ regs->gr[0] = pim_wide->cr[22];
+
+ for (i = 1; i < 32; i++)
+ regs->gr[i] = pim_wide->gr[i];
+
+ for (i = 0; i < 32; i++)
+ regs->fr[i] = pim_wide->fr[i];
+
+ for (i = 0; i < 8; i++)
+ regs->sr[i] = pim_wide->sr[i];
+
+ regs->iasq[0] = pim_wide->cr[17];
+ regs->iasq[1] = pim_wide->iasq_back;
+ regs->iaoq[0] = pim_wide->cr[18];
+ regs->iaoq[1] = pim_wide->iaoq_back;
+
+ regs->sar = pim_wide->cr[11];
+ regs->iir = pim_wide->cr[19];
+ regs->isr = pim_wide->cr[20];
+ regs->ior = pim_wide->cr[21];
+ }
+ else {
+ pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;
+
+ regs->gr[0] = pim_narrow->cr[22];
+
+ for (i = 1; i < 32; i++)
+ regs->gr[i] = pim_narrow->gr[i];
+
+ for (i = 0; i < 32; i++)
+ regs->fr[i] = pim_narrow->fr[i];
+
+ for (i = 0; i < 8; i++)
+ regs->sr[i] = pim_narrow->sr[i];
+
+ regs->iasq[0] = pim_narrow->cr[17];
+ regs->iasq[1] = pim_narrow->iasq_back;
+ regs->iaoq[0] = pim_narrow->cr[18];
+ regs->iaoq[1] = pim_narrow->iaoq_back;
+
+ regs->sar = pim_narrow->cr[11];
+ regs->iir = pim_narrow->cr[19];
+ regs->isr = pim_narrow->cr[20];
+ regs->ior = pim_narrow->cr[21];
+ }
+
+ /*
+ * The following fields only have meaning if we came through
+ * another path. So just zero them here.
+ */
+
+ regs->ksp = 0;
+ regs->kpc = 0;
+ regs->orig_r28 = 0;
+}
+
+
+/*
+ * This routine handles page faults. It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
+{
+ static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED;
+
+ set_eiem(0);
+ __cli();
+
+ spin_lock(&terminate_lock);
+
+ /* restart pdc console if necessary */
+ if (!console_drivers)
+ pdc_console_restart();
+
+ if (code == 1)
+ transfer_pim_to_trap_frame(regs);
+
+ show_stack(regs);
+
+ printk("\n%s: Code=%d regs=%p (Addr=" RFMT ")\n", msg,code,regs,offset);
+ show_regs(regs);
+
+ spin_unlock(&terminate_lock);
+
+ /* re-enable the power-off button */
+ pdc_soft_power_shutdown();
+
+ for(;;)
+ ;
+}
void handle_interruption(int code, struct pt_regs *regs)
{
@@ -378,7 +558,7 @@ void handle_interruption(int code, struc
goto give_sigill;
case 10:
- die_if_kernel("Privileged operation - shouldn't happen!", regs, code);
+ die_if_kernel("Privileged operation", regs, code);
si.si_code = ILL_PRVOPC;
goto give_sigill;
case 11:
@@ -399,7 +579,7 @@ void handle_interruption(int code, struc
return;
}
- die_if_kernel("Privileged register - shouldn't happen!", regs, code);
+ die_if_kernel("Privileged register usage", regs, code);
si.si_code = ILL_PRVREG;
give_sigill:
si.si_signo = SIGILL;
@@ -441,7 +621,7 @@ void handle_interruption(int code, struc
/* Fall Through */
case 27: /* D protection Id trap */
- die_if_kernel("Protection Id Trap", regs, code);
+ die_if_kernel("Protection id trap", regs, code);
si.si_code = SEGV_MAPERR;
si.si_signo = SIGSEGV;
si.si_errno = 0;
@@ -479,7 +659,7 @@ void handle_interruption(int code, struc
force_sig_info(SIGBUS, &si, current);
return;
}
- parisc_terminate("Unexpected Interruption!",regs,code,0);
+ parisc_terminate("Unexpected interruption", regs, code, 0);
/* NOT REACHED */
}
@@ -508,7 +688,7 @@ void handle_interruption(int code, struc
*/
if (fault_space == 0)
- parisc_terminate("Kernel Fault",regs,code,fault_address);
+ parisc_terminate("Kernel Fault", regs, code, fault_address);
}
#ifdef CONFIG_KWDB
@@ -520,189 +700,13 @@ void handle_interruption(int code, struc
return;
}
-void dump_stack(unsigned long from, unsigned long to,int istackflag)
-{
- unsigned int *fromptr;
- unsigned int *toptr;
-
- fromptr = (unsigned int *)from;
- toptr = (unsigned int *)to;
-
- if (istackflag)
- printk("\nDumping Interrupt Stack from %p to %p:\n",fromptr,toptr);
- else
- printk("\nDumping Stack from %p to %p:\n",fromptr,toptr);
- while (fromptr < toptr) {
- printk("%04lx %08x %08x %08x %08x %08x %08x %08x %08x\n",
- ((unsigned long)fromptr) & 0xffff,
- fromptr[0], fromptr[1], fromptr[2], fromptr[3],
- fromptr[4], fromptr[5], fromptr[6], fromptr[7]);
- fromptr += 8;
- }
- return;
-}
void show_trace_task(struct task_struct *tsk)
{
BUG();
}
-void show_stack(struct pt_regs *regs)
-{
-#if 1
- /* If regs->sr[7] == 0, we are on a kernel stack */
-
- if (regs->sr[7] == 0) {
-
- unsigned long sp = regs->gr[30];
- unsigned long cr30;
- unsigned long cr31;
- unsigned long stack_start;
- struct pt_regs *int_regs;
-
- cr30 = mfctl(30);
- cr31 = mfctl(31);
- stack_start = sp & ~(ISTACK_SIZE - 1);
- if (stack_start == cr31) {
-
- /*
- * We are on the interrupt stack, get the stack
- * pointer from the first pt_regs structure on
- * the interrupt stack, so we can dump the task
- * stack first.
- */
-
- int_regs = (struct pt_regs *)cr31;
- sp = int_regs->gr[30];
- stack_start = sp & ~(INIT_TASK_SIZE - 1);
- if (stack_start != cr30)
- printk("WARNING! Stack pointer and cr30 do not correspond!\n");
- dump_stack(stack_start,sp,0);
-
- printk("\n\nRegisters at Interrupt:\n");
- show_regs(int_regs);
-
- /* Now dump the interrupt stack */
-
- sp = regs->gr[30];
- stack_start = sp & ~(ISTACK_SIZE - 1);
- dump_stack(stack_start,sp,1);
- }
- else {
- /* Stack Dump! */
-
- stack_start = sp & ~(INIT_TASK_SIZE - 1);
- if (stack_start != cr30)
- printk("WARNING! Stack pointer and cr30 do not correspond!\n");
- dump_stack(stack_start,sp,0);
- }
- }
-#endif
-}
-
-static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED;
-
-void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset)
-{
- set_eiem(0);
- __cli();
-
- spin_lock(&terminate_lock);
-
- /* restart pdc console if necessary */
- if (!console_drivers)
- pdc_console_restart();
-
- if (code == 1)
- transfer_pim_to_trap_frame(regs);
- show_stack(regs);
-
- printk("\n%s: Code=%d regs=%p (Addr=" RFMT ")\n",msg,code,regs,offset);
- show_regs(regs);
-
- spin_unlock(&terminate_lock);
-
- /* re-enable the power-off button */
- pdc_soft_power_shutdown();
-
- for(;;)
- ;
-}
-
-void transfer_pim_to_trap_frame(struct pt_regs *regs)
-{
- register int i;
- extern unsigned int hpmc_pim_data[];
- struct pdc_hpmc_pim_11 *pim_narrow;
- struct pdc_hpmc_pim_20 *pim_wide;
-
- if (boot_cpu_data.cpu_type >= pcxu) {
-
- pim_wide = (struct pdc_hpmc_pim_20 *)hpmc_pim_data;
-
- /*
- * Note: The following code will probably generate a
- * bunch of truncation error warnings from the compiler.
- * Could be handled with an ifdef, but perhaps there
- * is a better way.
- */
-
- regs->gr[0] = pim_wide->cr[22];
-
- for (i = 1; i < 32; i++)
- regs->gr[i] = pim_wide->gr[i];
-
- for (i = 0; i < 32; i++)
- regs->fr[i] = pim_wide->fr[i];
-
- for (i = 0; i < 8; i++)
- regs->sr[i] = pim_wide->sr[i];
-
- regs->iasq[0] = pim_wide->cr[17];
- regs->iasq[1] = pim_wide->iasq_back;
- regs->iaoq[0] = pim_wide->cr[18];
- regs->iaoq[1] = pim_wide->iaoq_back;
-
- regs->sar = pim_wide->cr[11];
- regs->iir = pim_wide->cr[19];
- regs->isr = pim_wide->cr[20];
- regs->ior = pim_wide->cr[21];
- }
- else {
- pim_narrow = (struct pdc_hpmc_pim_11 *)hpmc_pim_data;
-
- regs->gr[0] = pim_narrow->cr[22];
-
- for (i = 1; i < 32; i++)
- regs->gr[i] = pim_narrow->gr[i];
-
- for (i = 0; i < 32; i++)
- regs->fr[i] = pim_narrow->fr[i];
-
- for (i = 0; i < 8; i++)
- regs->sr[i] = pim_narrow->sr[i];
-
- regs->iasq[0] = pim_narrow->cr[17];
- regs->iasq[1] = pim_narrow->iasq_back;
- regs->iaoq[0] = pim_narrow->cr[18];
- regs->iaoq[1] = pim_narrow->iaoq_back;
-
- regs->sar = pim_narrow->cr[11];
- regs->iir = pim_narrow->cr[19];
- regs->isr = pim_narrow->cr[20];
- regs->ior = pim_narrow->cr[21];
- }
-
- /*
- * The following fields only have meaning if we came through
- * another path. So just zero them here.
- */
-
- regs->ksp = 0;
- regs->kpc = 0;
- regs->orig_r28 = 0;
-}
int __init check_ivt(void *iva)
{
@@ -714,7 +718,7 @@ int __init check_ivt(void *iva)
extern void os_hpmc(void);
extern void os_hpmc_end(void);
- if(strcmp((char *)iva, "cows can fly"))
+ if (strcmp((char *)iva, "cows can fly"))
return -1;
ivap = (u32 *)iva;
@@ -729,10 +733,10 @@ int __init check_ivt(void *iva)
hpmcp = (u32 *)os_hpmc;
- for(i=0; i<length/4; i++)
+ for (i=0; i<length/4; i++)
check += *hpmcp++;
- for(i=0; i<8; i++)
+ for (i=0; i<8; i++)
check += ivap[i];
ivap[5] = -check;
@@ -758,6 +762,6 @@ void __init trap_init(void)
iva = (void *) &fault_vector_11;
#endif
- if(check_ivt(iva))
+ if (check_ivt(iva))
panic("IVT invalid");
}
Index: arch/parisc/mm/fault.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/mm/fault.c,v
retrieving revision 1.34
diff -u -p -r1.34 fault.c
--- arch/parisc/mm/fault.c 2001/08/28 12:09:57 1.34
+++ arch/parisc/mm/fault.c 2001/12/04 22:53:56
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <asm/uaccess.h>
+#include <asm/traps.h>
#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
/* dumped to the console via printk) */
@@ -117,12 +118,6 @@ parisc_acctyp(unsigned long code, unsign
#undef isGraphicsFlushRead
#undef BITSSET
-/*
- * This routine handles page faults. It determines the address,
- * and the problem, and then passes it off to one of the appropriate
- * routines.
- */
-extern void parisc_terminate(char *, struct pt_regs *, int, unsigned long);
#if 0
/* This is the treewalk to find a vma which is the highest that has
@@ -261,7 +256,7 @@ no_context:
}
}
- parisc_terminate("Bad Address (null pointer deref?)",regs,code,address);
+ parisc_terminate("Bad Address (null pointer deref?)", regs, code, address);
out_of_memory:
up_read(&mm->mmap_sem);
Index: include/asm-parisc/traps.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/traps.h,v
retrieving revision 1.2
diff -u -p -r1.2 traps.h
--- include/asm-parisc/traps.h 2000/02/26 18:50:00 1.2
+++ include/asm-parisc/traps.h 2001/12/04 22:54:09
@@ -1,4 +1,16 @@
#ifndef __ASM_TRAPS_H
#define __ASM_TRAPS_H
+#ifdef __KERNEL__
+struct pt_regs;
+
+/* traps.c */
+void parisc_terminate(char *msg, struct pt_regs *regs,
+ int code, unsigned long offset);
+
+/* mm/fault.c */
+void do_page_fault(struct pt_regs *regs, unsigned long code,
+ unsigned long address);
+#endif
+
#endif
Index: include/asm-parisc/unaligned.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/unaligned.h,v
retrieving revision 1.2
diff -u -p -r1.2 unaligned.h
--- include/asm-parisc/unaligned.h 2000/04/19 21:21:56 1.2
+++ include/asm-parisc/unaligned.h 2001/12/04 22:54:09
@@ -17,4 +17,11 @@
memmove((ptr), &__tmp, sizeof(*(ptr))); \
(void)0; })
-#endif /* _ASM_PARISC_UNALIGNED_H */
+
+#ifdef __KERNEL__
+struct pt_regs;
+void handle_unaligned(struct pt_regs *regs);
+int check_unaligned(struct pt_regs *regs);
+#endif
+
+#endif /* _ASM_PARISC_UNALIGNED_H_ */
--------------Boundary-00=_B3EUU1BKUUK7QXEGT1RX--