File: /usr/src/linux/arch/alpha/kernel/sys_nautilus.c

1     /*
2      *	linux/arch/alpha/kernel/sys_nautilus.c
3      *
4      *	Copyright (C) 1995 David A Rusling
5      *	Copyright (C) 1998 Richard Henderson
6      *	Copyright (C) 1999 Alpha Processor, Inc.,
7      *		(David Daniel, Stig Telfer, Soohoon Lee)
8      *
9      * Code supporting NAUTILUS systems.
10      *
11      *
12      * NAUTILUS has the following I/O features:
13      *
14      * a) Driven by AMD 751 aka IRONGATE (northbridge):
15      *     4 PCI slots
16      *     1 AGP slot
17      *
18      * b) Driven by ALI M1543C (southbridge)
19      *     2 ISA slots
20      *     2 IDE connectors
21      *     1 dual drive capable FDD controller
22      *     2 serial ports
23      *     1 ECP/EPP/SP parallel port
24      *     2 USB ports
25      */
26     
27     #include <linux/kernel.h>
28     #include <linux/types.h>
29     #include <linux/mm.h>
30     #include <linux/sched.h>
31     #include <linux/pci.h>
32     #include <linux/init.h>
33     #include <linux/reboot.h>
34     
35     #include <asm/ptrace.h>
36     #include <asm/system.h>
37     #include <asm/dma.h>
38     #include <asm/irq.h>
39     #include <asm/bitops.h>
40     #include <asm/mmu_context.h>
41     #include <asm/io.h>
42     #include <asm/pci.h>
43     #include <asm/pgtable.h>
44     #include <asm/core_irongate.h>
45     #include <asm/hwrpb.h>
46     
47     #include "proto.h"
48     #include "irq_impl.h"
49     #include "pci_impl.h"
50     #include "machvec_impl.h"
51     
52     
53     static void __init
54     nautilus_init_irq(void)
55     {
56     	if (alpha_using_srm) {
57     		alpha_mv.device_interrupt = srm_device_interrupt;
58     	}
59     
60     	init_i8259a_irqs();
61     	common_init_isa_dma();
62     }
63     
64     static int __init
65     nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
66     {
67     	/* Preserve the IRQ set up by the console.  */
68     
69     	u8 irq;
70     	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
71     	return irq;
72     }
73     
74     void
75     nautilus_kill_arch(int mode)
76     {
77     	switch (mode) {
78     	case LINUX_REBOOT_CMD_RESTART:
79     		if (! alpha_using_srm) {
80     			u8 t8;
81     			pcibios_read_config_byte(0, 0x38, 0x43, &t8);
82     			pcibios_write_config_byte(0, 0x38, 0x43, t8 | 0x80);
83     			outb(1, 0x92);
84     			outb(0, 0x92);
85     			/* NOTREACHED */
86     		}
87     		break;
88     
89     	case LINUX_REBOOT_CMD_POWER_OFF:
90     		{
91     			u32 pmuport;
92     			pcibios_read_config_dword(0, 0x88, 0x10, &pmuport);
93     			pmuport &= 0xfffe;
94     			outl(0xffff, pmuport); /* clear pending events */
95     			outw(0x2000, pmuport+4); /* power off */
96     			/* NOTREACHED */
97     		}
98     		break;
99     	}
100     }
101     
102     /* Machine check handler code
103      *
104      * Perform analysis of a machine check that was triggered by the EV6
105      * CPU's fault-detection mechanism.
106      */
107     
108     /* IPR structures for EV6, containing the necessary data for the
109      * machine check handler to unpick the logout frame
110      */
111     
112     /* I_STAT */
113     
114     #define EV6__I_STAT__PAR                ( 1 << 29 )
115     
116     /* MM_STAT */
117     
118     #define EV6__MM_STAT__DC_TAG_PERR       ( 1 << 10 )
119     
120     /* DC_STAT */
121     
122     #define EV6__DC_STAT__SEO               ( 1 << 4 )
123     #define EV6__DC_STAT__ECC_ERR_LD        ( 1 << 3 )
124     #define EV6__DC_STAT__ECC_ERR_ST        ( 1 << 2 )
125     #define EV6__DC_STAT__TPERR_P1          ( 1 << 1 )
126     #define EV6__DC_STAT__TPERR_P0          ( 1      )
127     
128     /* C_STAT */
129     
130     #define EV6__C_STAT__BC_PERR            ( 0x01 )
131     #define EV6__C_STAT__DC_PERR            ( 0x02 )
132     #define EV6__C_STAT__DSTREAM_MEM_ERR    ( 0x03 )
133     #define EV6__C_STAT__DSTREAM_BC_ERR     ( 0x04 )
134     #define EV6__C_STAT__DSTREAM_DC_ERR     ( 0x05 )
135     #define EV6__C_STAT__PROBE_BC_ERR0      ( 0x06 )
136     #define EV6__C_STAT__PROBE_BC_ERR1      ( 0x07 )
137     #define EV6__C_STAT__ISTREAM_MEM_ERR    ( 0x0B )
138     #define EV6__C_STAT__ISTREAM_BC_ERR     ( 0x0C )
139     #define EV6__C_STAT__DSTREAM_MEM_DBL    ( 0x13 )
140     #define EV6__C_STAT__DSTREAM_BC_DBL     ( 0x14 )
141     #define EV6__C_STAT__ISTREAM_MEM_DBL    ( 0x1B )
142     #define EV6__C_STAT__ISTREAM_BC_DBL     ( 0x1C )
143     
144     
145     /* Take the two syndromes from the CBOX error chain and convert them
146      * into a bit number.  */
147     
148     /* NOTE - since I don't know of any difference between C0 and C1 I
149        just ignore C1, since in all cases I've seen so far they are
150        identical.  */
151     
152     static const unsigned char ev6_bit_to_syndrome[72] =
153     {
154     	0xce, 0xcb, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc,     /* 0 */
155     	0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,     /* 8 */
156     	0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,     /* 16 */
157     	0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xf1, 0xf4,     /* 24 */
158     	0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,     /* 32 */
159     	0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xb0, 0xb5,     /* 40 */
160     	0x8f, 0x8a, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d,     /* 48 */
161     	0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,     /* 56 */
162     	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80      /* 64 */
163     };
164     
165     
166     static int ev6_syn2bit(unsigned long c0, unsigned long c1)
167     {
168     	int bit;
169     
170     	for (bit = 0; bit < 72; bit++)
171     		if (ev6_bit_to_syndrome[bit] == c0)	return bit;
172     	for (bit = 0; bit < 72; bit++)
173     		if (ev6_bit_to_syndrome[bit] == c1)	return bit + 64;
174     
175     	return -1;                  /* not found */
176     }
177     
178     
179     /* Single bit ECC errors are categorized here.  */
180     
181     #if 0
182     static const char *interr = "CPU internal error";
183     static const char *slotb= "Slot-B error";
184     static const char *membus= "Memory/EV6-bus error";
185     #else
186     static const char *interr = "";
187     static const char *slotb = "";
188     static const char *membus = "";
189     #endif
190     
191     static void
192     ev6_crd_interp(char *interp, struct el_common_EV6_mcheck * L)
193     {
194     	/* Icache data or tag parity error.  */
195     	if (L->I_STAT & EV6__I_STAT__PAR) {
196     		sprintf(interp, "%s: I_STAT[PAR]\n "
197     			"Icache data or tag parity error", interr);
198     		return;
199     	}
200     
201     	/* Dcache tag parity error (on issue) (DFAULT).  */
202     	if (L->MM_STAT & EV6__MM_STAT__DC_TAG_PERR) {
203     		sprintf(interp, "%s: MM_STAT[DC_TAG_PERR]\n "
204     			"Dcache tag parity error(on issue)", interr);
205     		return;
206     	}
207     
208     	/* Errors relating to D-stream set non-zero DC_STAT.
209     	   Mask CRD bits.  */
210     	switch (L->DC_STAT & (EV6__DC_STAT__ECC_ERR_ST
211     			      | EV6__DC_STAT__ECC_ERR_LD)) {
212     	case EV6__DC_STAT__ECC_ERR_ST:
213     		/* Dcache single-bit ECC error on small store */
214     		sprintf(interp, "%s: DC_STAT[ECC_ERR_ST]\n "
215     			"Dcache single-bit ECC error on small store", interr);
216     		return;
217     
218     	case EV6__DC_STAT__ECC_ERR_LD:
219     		switch (L->C_STAT) {
220     		case 0:
221     			/* Dcache single-bit error on speculative load */
222     			/* Bcache victim read on Dcache/Bcache miss */
223     			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT=0\n "
224     				"Dcache single-bit ECC error on speculative load",
225     				slotb);
226     			return;
227     
228     		case EV6__C_STAT__DSTREAM_DC_ERR:
229     			/* Dcache single bit error on load */
230     			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_DC_ERR]\n"
231     				" Dcache single-bit ECC error on speculative load, bit %d",
232     				interr, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
233     			return;
234     
235     		case EV6__C_STAT__DSTREAM_BC_ERR:
236     			/* Bcache single-bit error on Dcache fill */
237     			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_BC_ERR]\n"
238     				" Bcache single-bit error on Dcache fill, bit %d",
239     				slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
240     			return;
241     
242     		case EV6__C_STAT__DSTREAM_MEM_ERR:
243     			/* Memory single-bit error on Dcache fill */
244     			sprintf(interp, "%s (to Dcache): DC_STAT[ECC_ERR_LD] "
245     				"C_STAT[DSTREAM_MEM_ERR]\n "
246     				"Memory single-bit error on Dcache fill, "
247     				"Address 0x%lX, bit %d",
248     				membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
249     							       L->DC1_SYNDROME));
250     			return;
251     		}
252     	}
253     
254     	/* I-stream, other misc errors go on C_STAT alone */
255     	switch (L->C_STAT) {
256     	case EV6__C_STAT__ISTREAM_BC_ERR:
257     		/* Bcache single-bit error on Icache fill (also MCHK) */
258     		sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
259     			"Bcache single-bit error on Icache fill, bit %d",
260     			slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
261     		return;
262     
263     	case EV6__C_STAT__ISTREAM_MEM_ERR:
264     		/* Memory single-bit error on Icache fill (also MCHK) */
265     		sprintf(interp, "%s : C_STATISTREAM_MEM_ERR]\n "
266     			"Memory single-bit error on Icache fill "
267     			"addr 0x%lX, bit %d",
268     			membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
269     						       L->DC1_SYNDROME));
270     		return;
271     
272     	case EV6__C_STAT__PROBE_BC_ERR0:
273     	case EV6__C_STAT__PROBE_BC_ERR1:
274     		/* Bcache single-bit error on a probe hit */
275     		sprintf(interp, "%s: C_STAT[PROBE_BC_ERR]\n "
276     			"Bcache single-bit error on a probe hit, "
277     			"addr 0x%lx, bit %d",
278     			slotb, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
279     						      L->DC1_SYNDROME));
280     		return;
281     	}
282     }
283     
284     static void
285     ev6_mchk_interp(char *interp, struct el_common_EV6_mcheck * L)
286     {
287     	/* Machine check errors described by DC_STAT */
288     	switch (L->DC_STAT) {
289     	case EV6__DC_STAT__TPERR_P0:
290     	case EV6__DC_STAT__TPERR_P1:
291     		/* Dcache tag parity error (on retry) */
292     		sprintf(interp, "%s: DC_STAT[TPERR_P0|TPERR_P1]\n "
293     			"Dcache tag parity error(on retry)", interr);
294     		return;
295     
296     	case EV6__DC_STAT__SEO:
297     		/* Dcache second error on store */
298     		sprintf(interp, "%s: DC_STAT[SEO]\n "
299     			"Dcache second error during mcheck", interr);
300     		return;
301     	}
302     
303     	/* Machine check errors described by C_STAT */
304     	switch (L->C_STAT) {
305     	case EV6__C_STAT__DC_PERR:
306     		/* Dcache duplicate tag parity error */
307     		sprintf(interp, "%s: C_STAT[DC_PERR]\n "
308     			"Dcache duplicate tag parity error at 0x%lX",
309     			interr, L->C_ADDR);
310     		return;
311     
312     	case EV6__C_STAT__BC_PERR:
313     		/* Bcache tag parity error */
314     		sprintf(interp, "%s: C_STAT[BC_PERR]\n "
315     			"Bcache tag parity error at 0x%lX",
316     			slotb, L->C_ADDR);
317     		return;
318     
319     	case EV6__C_STAT__ISTREAM_BC_ERR:
320     		/* Bcache single-bit error on Icache fill (also CRD) */
321     		sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
322     			"Bcache single-bit error on Icache fill 0x%lX bit %d",
323     			slotb, L->C_ADDR,
324     			ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
325     		return;
326     
327     
328     	case EV6__C_STAT__ISTREAM_MEM_ERR:
329     		/* Memory single-bit error on Icache fill (also CRD) */
330     		sprintf(interp, "%s: C_STAT[ISTREAM_MEM_ERR]\n "
331     			"Memory single-bit error on Icache fill 0x%lX, bit %d",
332     			membus, L->C_ADDR,
333     			ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
334     		return;
335     
336     
337     	case EV6__C_STAT__ISTREAM_BC_DBL:
338     		/* Bcache double-bit error on Icache fill */
339     		sprintf(interp, "%s: C_STAT[ISTREAM_BC_DBL]\n "
340     			"Bcache double-bit error on Icache fill at 0x%lX",
341     			slotb, L->C_ADDR);
342     		return;
343     	case EV6__C_STAT__DSTREAM_BC_DBL:
344     		/* Bcache double-bit error on Dcache fill */
345     		sprintf(interp, "%s: C_STAT[DSTREAM_BC_DBL]\n "
346     			"Bcache double-bit error on Dcache fill at 0x%lX",
347     			slotb, L->C_ADDR);
348     		return;
349     
350     	case EV6__C_STAT__ISTREAM_MEM_DBL:
351     		/* Memory double-bit error on Icache fill */
352     		sprintf(interp, "%s: C_STAT[ISTREAM_MEM_DBL]\n "
353     			"Memory double-bit error on Icache fill at 0x%lX",
354     			membus, L->C_ADDR);
355     		return;
356     
357     	case EV6__C_STAT__DSTREAM_MEM_DBL:
358     		/* Memory double-bit error on Dcache fill */
359     		sprintf(interp, "%s: C_STAT[DSTREAM_MEM_DBL]\n "
360     			"Memory double-bit error on Dcache fill at 0x%lX",
361     			membus, L->C_ADDR);
362     		return;
363     	}
364     }
365     
366     static void
367     ev6_cpu_machine_check(unsigned long vector, struct el_common_EV6_mcheck *L,
368     		      struct pt_regs *regs)
369     {
370     	char interp[80];
371     
372     	/* This is verbose and looks intimidating.  Should it be printed for
373     	   corrected (CRD) machine checks? */
374     
375     	printk(KERN_CRIT "PALcode logout frame:  "
376     	       "MCHK_Code       %d  "
377     	       "MCHK_Frame_Rev  %d\n"
378     	       "I_STAT  %016lx  "
379     	       "DC_STAT %016lx  "
380     	       "C_ADDR  %016lx\n"
381     	       "SYND1   %016lx  "
382     	       "SYND0   %016lx  "
383     	       "C_STAT  %016lx\n"
384     	       "C_STS   %016lx  "
385     	       "RES     %016lx  "
386     	       "EXC_ADDR%016lx\n"
387     	       "IER_CM  %016lx  "
388     	       "ISUM    %016lx  "
389     	       "MM_STAT %016lx\n"
390     	       "PALBASE %016lx  "
391     	       "I_CTL   %016lx  "
392     	       "PCTX    %016lx\n"
393     	       "CPU registers: "
394     	       "PC      %016lx  "
395     	       "Return  %016lx\n",
396     	       L->MCHK_Code, L->MCHK_Frame_Rev, L->I_STAT, L->DC_STAT,
397     	       L->C_ADDR, L->DC1_SYNDROME, L->DC0_SYNDROME, L->C_STAT,
398     	       L->C_STS, L->RESERVED0, L->EXC_ADDR, L->IER_CM, L->ISUM,
399     	       L->MM_STAT, L->PAL_BASE, L->I_CTL, L->PCTX,
400     	       regs->pc, regs->r26);
401     
402     	/* Attempt an interpretation on the meanings of the fields above.  */
403     	sprintf(interp, "No interpretation available!" );
404     	if (vector == SCB_Q_PROCERR)
405     		ev6_crd_interp(interp, L);
406     	else if (vector == SCB_Q_PROCMCHK)
407     		ev6_mchk_interp(interp, L);
408     
409     	printk(KERN_CRIT "interpretation: %s\n\n", interp);
410     }
411     
412     
413     /* Perform analysis of a machine check that arrived from the system (NMI) */
414     
415     static void
416     naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
417     		       struct pt_regs *regs)
418     {
419     	printk("xtime %lx\n", CURRENT_TIME);
420     	printk("PC %lx RA %lx\n", regs->pc, regs->r26);
421     	irongate_pci_clr_err();
422     }
423     
424     /* Machine checks can come from two sources - those on the CPU and those
425        in the system.  They are analysed separately but all starts here.  */
426     
427     void
428     nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
429     		       struct pt_regs *regs)
430     {
431     	char *mchk_class;
432     	unsigned cpu_analysis=0, sys_analysis=0;
433     
434     	/* Now for some analysis.  Machine checks fall into two classes --
435     	   those picked up by the system, and those picked up by the CPU.
436     	   Add to that the two levels of severity - correctable or not.  */
437     
438     	if (vector == SCB_Q_SYSMCHK
439     	    && ((IRONGATE0->dramms & 0x300) == 0x300)) {
440     		unsigned long nmi_ctl;
441     
442     		/* Clear ALI NMI */
443     		nmi_ctl = inb(0x61);
444     		nmi_ctl |= 0x0c;
445     		outb(nmi_ctl, 0x61);
446     		nmi_ctl &= ~0x0c;
447     		outb(nmi_ctl, 0x61);
448     
449     		/* Write again clears error bits.  */
450     		IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
451     		mb();
452     		IRONGATE0->stat_cmd;
453     
454     		/* Write again clears error bits.  */
455     		IRONGATE0->dramms = IRONGATE0->dramms;
456     		mb();
457     		IRONGATE0->dramms;
458     
459     		draina();
460     		wrmces(0x7);
461     		mb();
462     		return;
463     	}
464     
465     	switch (vector) {
466     	case SCB_Q_SYSERR:
467     		mchk_class = "Correctable System Machine Check (NMI)";
468     		sys_analysis = 1;
469     		break;
470     	case SCB_Q_SYSMCHK:
471     		mchk_class = "Fatal System Machine Check (NMI)";
472     		sys_analysis = 1;
473     		break;
474     
475     	case SCB_Q_PROCERR:
476     		mchk_class = "Correctable Processor Machine Check";
477     		cpu_analysis = 1;
478     		break;
479     	case SCB_Q_PROCMCHK:
480     		mchk_class = "Fatal Processor Machine Check";
481     		cpu_analysis = 1;
482     		break;
483     
484     	default:
485     		mchk_class = "Unknown vector!";
486     		break;
487     	}
488     
489     	printk(KERN_CRIT "NAUTILUS Machine check 0x%lx [%s]\n",
490     	       vector, mchk_class);
491     
492     	if (cpu_analysis)
493     		ev6_cpu_machine_check(vector,
494     				      (struct el_common_EV6_mcheck *)la_ptr,
495     				      regs);
496     	if (sys_analysis)
497     		naut_sys_machine_check(vector, la_ptr, regs);
498     
499     	/* Tell the PALcode to clear the machine check */
500     	draina();
501     	wrmces(0x7);
502     	mb();
503     }
504     
505     
506     
507     /*
508      * The System Vectors
509      */
510     
511     struct alpha_machine_vector nautilus_mv __initmv = {
512     	vector_name:		"Nautilus",
513     	DO_EV6_MMU,
514     	DO_DEFAULT_RTC,
515     	DO_IRONGATE_IO,
516     	DO_IRONGATE_BUS,
517     	machine_check:		nautilus_machine_check,
518     	max_dma_address:	ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
519     	min_io_address:		DEFAULT_IO_BASE,
520     	min_mem_address:	IRONGATE_DEFAULT_MEM_BASE,
521     
522     	nr_irqs:		16,
523     	device_interrupt:	isa_device_interrupt,
524     
525     	init_arch:		irongate_init_arch,
526     	init_irq:		nautilus_init_irq,
527     	init_rtc:		common_init_rtc,
528     	init_pci:		common_init_pci,
529     	kill_arch:		nautilus_kill_arch,
530     	pci_map_irq:		nautilus_map_irq,
531     	pci_swizzle:		common_swizzle,
532     };
533     ALIAS_MV(nautilus)
534