summaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/traps.c
blob: e9f5e8e5b2bed8d2a9812c81210742734516251c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 *  linux/arch/ppc/kernel/traps.c
 *
 *  Copyright (C) 1995  Gary Thomas
 *  Adapted for PowerPC by Gary Thomas
 */

/*
 * This file handles the architecture-dependent parts of hardware exceptions
 */

#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>

#include <asm/pgtable.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>

#include <asm/ppc_machine.h>

/*
 * Trap & Exception support
 */

void
trap_init(void)
{
}

void
_exception(int signr, struct pt_regs *regs)
{
/*	dump_regs(regs);*/
	force_sig(signr, current);
	if (!user_mode(regs))
	{
		printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
		while (1) ;
	}
}

MachineCheckException(struct pt_regs *regs)
{
/*	printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
	_exception(SIGSEGV, regs);	
}

ProgramCheckException(struct pt_regs *regs)
{
/*	printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
	if (current->flags & PF_PTRACED)
	{
		_exception(SIGTRAP, regs);
	} else
	{
		_exception(SIGILL, regs);
	}
}

SingleStepException(struct pt_regs *regs)
{
/*	printk("Single step at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
	_exception(SIGTRAP, regs);	
}

FloatingPointCheckException(struct pt_regs *regs)
{
/*	printk("Floating point check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
	_exception(SIGFPE, regs);	
}

AlignmentException(struct pt_regs *regs)
{
/*	printk("Alignment error at PC: %x, SR: %x\n", regs->nip, regs->msr);
	dump_regs(regs);
	printk("Alignment error at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
	_exception(SIGBUS, regs);	
}

bad_stack(struct pt_regs *regs)
{
/*	printk("Kernel stack overflow at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
	dump_regs(regs);*/
	while (1) ;
}

dump_regs(struct pt_regs *regs)
{
	int i;
	printk("NIP: %08X, MSR: %08X, XER: %08X, LR: %08X, FRAME: %08X\n", regs->nip, regs->msr, regs->xer, regs->link, regs);
#if 0	
	printk("HASH = %08X/%08X, MISS = %08X/%08X, CMP = %08X/%08X\n", regs->hash1, regs->hash2, regs->imiss, regs->dmiss, regs->icmp, regs->dcmp);
#endif	
	printk("TASK = %x[%d] '%s'\n", current, current->pid, current->comm);
	for (i = 0;  i < 32;  i++)
	{
		if ((i % 8) == 0)
		{
			printk("GPR%02d: ", i);
		}
		printk("%08X ", regs->gpr[i]);
		if ((i % 8) == 7)
		{
			printk("\n");
		}
	}
#if 0	
	if (regs->nip >= 0x1000)
		dump_buf(regs->nip-32, 64);
	dump_buf((regs->nip&0x0FFFFFFF)|KERNELBASE, 32);
#endif
}

trace_syscall(struct pt_regs *regs)
{
	static int count;
	printk("Task: %08X(%d), PC: %08X/%08X, Syscall: %3d, Result: %s%d\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3]);
	if (++count == 20)
	{
		count = 0;
	}
}