6b13f685e
김민수
BSP 최초 추가
|
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
135
136
137
138
139
140
141
|
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/addrspace.h>
#include <asm/irq_regs.h>
#include <asm/ptrace.h>
#include <asm/traps.h>
#include <asm/dec/kn02ca.h>
#include <asm/dec/kn02xa.h>
#include <asm/dec/kn05.h>
static inline void dec_kn02xa_be_ack(void)
{
volatile u32 *mer = (void *)CKSEG1ADDR(KN02XA_MER);
volatile u32 *mem_intr = (void *)CKSEG1ADDR(KN02XA_MEM_INTR);
*mer = KN02CA_MER_INTR;
*mem_intr = 0;
iob();
}
static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
int invoker)
{
volatile u32 *kn02xa_mer = (void *)CKSEG1ADDR(KN02XA_MER);
volatile u32 *kn02xa_ear = (void *)CKSEG1ADDR(KN02XA_EAR);
static const char excstr[] = "exception";
static const char intstr[] = "interrupt";
static const char cpustr[] = "CPU";
static const char mreadstr[] = "memory read";
static const char readstr[] = "read";
static const char writestr[] = "write";
static const char timestr[] = "timeout";
static const char paritystr[] = "parity error";
static const char lanestat[][4] = { " OK", "BAD" };
const char *kind, *agent, *cycle, *event;
unsigned long address;
u32 mer = *kn02xa_mer;
u32 ear = *kn02xa_ear;
int action = MIPS_BE_FATAL;
dec_kn02xa_be_ack();
kind = invoker ? intstr : excstr;
agent = cpustr;
address = ear & KN02XA_EAR_ADDRESS;
if (address < 0x10000000) {
cycle = mreadstr;
event = paritystr;
} else {
cycle = invoker ? writestr : readstr;
event = timestr;
}
if (is_fixup)
action = MIPS_BE_FIXUP;
if (action != MIPS_BE_FIXUP)
printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx
",
kind, agent, cycle, event, address);
if (action != MIPS_BE_FIXUP && address < 0x10000000)
printk(KERN_ALERT " Byte lane status %#3x -- "
"#3: %s, #2: %s, #1: %s, #0: %s
",
(mer & KN02XA_MER_BYTERR) >> 8,
lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
return action;
}
int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
{
return dec_kn02xa_be_backend(regs, is_fixup, 0);
}
irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id)
{
struct pt_regs *regs = get_irq_regs();
int action = dec_kn02xa_be_backend(regs, 0, 1);
if (action == MIPS_BE_DISCARD)
return IRQ_HANDLED;
printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx
",
regs->cp0_epc, regs->regs[31]);
die("Unrecoverable bus error", regs);
}
void __init dec_kn02xa_be_init(void)
{
volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
if (current_cpu_type() == CPU_R4000SC)
*mbcs |= KN4K_MB_CSR_EE;
fast_iob();
dec_kn02xa_be_ack();
}
|