Import 2.3.13pre1
[davej-history.git] / arch / alpha / kernel / sys_mikasa.c
blob9952c311fd482e9b99719b8d2520efa7a5eafc93
1 /*
2 * linux/arch/alpha/kernel/sys_mikasa.c
4 * Copyright (C) 1995 David A Rusling
5 * Copyright (C) 1996 Jay A Estabrook
6 * Copyright (C) 1998 Richard Henderson
8 * Code supporting the MIKASA (AlphaServer 1000).
9 */
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/mm.h>
15 #include <linux/sched.h>
16 #include <linux/pci.h>
17 #include <linux/init.h>
19 #include <asm/ptrace.h>
20 #include <asm/system.h>
21 #include <asm/dma.h>
22 #include <asm/irq.h>
23 #include <asm/bitops.h>
24 #include <asm/mmu_context.h>
25 #include <asm/io.h>
26 #include <asm/pgtable.h>
27 #include <asm/core_apecs.h>
28 #include <asm/core_cia.h>
30 #include "proto.h"
31 #include "irq.h"
32 #include "bios32.h"
33 #include "machvec.h"
35 static void
36 mikasa_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
38 if (irq >= 16)
39 outw(~(mask >> 16), 0x536); /* note invert */
40 else if (irq >= 8)
41 outb(mask >> 8, 0xA1);
42 else
43 outb(mask, 0x21);
46 static void
47 mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs)
49 unsigned long pld;
50 unsigned int i;
52 /* Read the interrupt summary registers */
53 pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) |
54 (((unsigned long) inb(0xa0)) << 8) |
55 ((unsigned long) inb(0x20));
58 * Now for every possible bit set, work through them and call
59 * the appropriate interrupt handler.
61 while (pld) {
62 i = ffz(~pld);
63 pld &= pld - 1; /* clear least bit set */
64 if (i < 16) {
65 isa_device_interrupt(vector, regs);
66 } else {
67 handle_irq(i, i, regs);
72 static void __init
73 mikasa_init_irq(void)
75 STANDARD_INIT_IRQ_PROLOG;
77 if (alpha_using_srm)
78 alpha_mv.device_interrupt = srm_device_interrupt;
80 outw(~(alpha_irq_mask >> 16), 0x536); /* note invert */
81 enable_irq(2); /* enable cascade */
86 * PCI Fixup configuration.
88 * Summary @ 0x536:
89 * Bit Meaning
90 * 0 Interrupt Line A from slot 0
91 * 1 Interrupt Line B from slot 0
92 * 2 Interrupt Line C from slot 0
93 * 3 Interrupt Line D from slot 0
94 * 4 Interrupt Line A from slot 1
95 * 5 Interrupt line B from slot 1
96 * 6 Interrupt Line C from slot 1
97 * 7 Interrupt Line D from slot 1
98 * 8 Interrupt Line A from slot 2
99 * 9 Interrupt Line B from slot 2
100 *10 Interrupt Line C from slot 2
101 *11 Interrupt Line D from slot 2
102 *12 NCR 810 SCSI
103 *13 Power Supply Fail
104 *14 Temperature Warn
105 *15 Reserved
107 * The device to slot mapping looks like:
109 * Slot Device
110 * 6 NCR SCSI controller
111 * 7 Intel PCI-EISA bridge chip
112 * 11 PCI on board slot 0
113 * 12 PCI on board slot 1
114 * 13 PCI on board slot 2
117 * This two layered interrupt approach means that we allocate IRQ 16 and
118 * above for PCI interrupts. The IRQ relates to which bit the interrupt
119 * comes in on. This makes interrupt processing much easier.
122 static int __init
123 mikasa_map_irq(struct pci_dev *dev, int slot, int pin)
125 static char irq_tab[8][5] __initlocaldata = {
126 /*INT INTA INTB INTC INTD */
127 {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */
128 { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
129 { -1, -1, -1, -1, -1}, /* IdSel 19, ???? */
130 { -1, -1, -1, -1, -1}, /* IdSel 20, ???? */
131 { -1, -1, -1, -1, -1}, /* IdSel 21, ???? */
132 { 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 0 */
133 { 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
134 { 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 24, slot 2 */
136 const long min_idsel = 6, max_idsel = 13, irqs_per_slot = 5;
137 return COMMON_TABLE_LOOKUP;
140 static void __init
141 mikasa_pci_fixup(void)
143 layout_all_busses(EISA_DEFAULT_IO_BASE,APECS_AND_LCA_DEFAULT_MEM_BASE);
144 common_pci_fixup(mikasa_map_irq, common_swizzle);
147 static void __init
148 mikasa_primo_pci_fixup(void)
150 layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
151 common_pci_fixup(mikasa_map_irq, common_swizzle);
154 static void
155 mikasa_machine_check(unsigned long vector, unsigned long la_ptr,
156 struct pt_regs * regs)
158 #define MCHK_NO_DEVSEL 0x205L
159 #define MCHK_NO_TABT 0x204L
161 struct el_common *mchk_header;
162 struct el_apecs_procdata *mchk_procdata;
163 struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata;
164 unsigned long *ptr;
165 int i;
167 mchk_header = (struct el_common *)la_ptr;
169 mchk_procdata = (struct el_apecs_procdata *)
170 (la_ptr + mchk_header->proc_offset
171 - sizeof(mchk_procdata->paltemp));
173 mchk_sysdata = (struct el_apecs_mikasa_sysdata_mcheck *)
174 (la_ptr + mchk_header->sys_offset);
176 #ifdef DEBUG
177 printk("mikasa_machine_check: vector=0x%lx la_ptr=0x%lx\n",
178 vector, la_ptr);
179 printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
180 regs->pc, mchk_header->size, mchk_header->proc_offset,
181 mchk_header->sys_offset);
182 printk("mikasa_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
183 apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
184 mchk_sysdata->epic_pear);
185 ptr = (unsigned long *)la_ptr;
186 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
187 printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
189 #endif
192 * Check if machine check is due to a badaddr() and if so,
193 * ignore the machine check.
196 if (apecs_mcheck_expected
197 && ((unsigned int)mchk_header->code == MCHK_NO_DEVSEL
198 || (unsigned int)mchk_header->code == MCHK_NO_TABT)) {
199 apecs_mcheck_expected = 0;
200 apecs_mcheck_taken = 1;
201 mb();
202 mb(); /* magic */
203 apecs_pci_clr_err();
204 wrmces(0x7);
205 mb();
206 draina();
208 else if (vector == 0x620 || vector == 0x630) {
209 /* Disable correctable from now on. */
210 wrmces(0x1f);
211 mb();
212 draina();
213 printk("mikasa_machine_check: HW correctable (0x%lx)\n",
214 vector);
216 else {
217 printk(KERN_CRIT "APECS machine check:\n");
218 printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx\n",
219 vector, la_ptr);
220 printk(KERN_CRIT
221 " pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
222 regs->pc, mchk_header->size, mchk_header->proc_offset,
223 mchk_header->sys_offset);
224 printk(KERN_CRIT " expected %d DCSR 0x%lx PEAR 0x%lx\n",
225 apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
226 mchk_sysdata->epic_pear);
228 ptr = (unsigned long *)la_ptr;
229 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
230 printk(KERN_CRIT " +%lx %lx %lx\n",
231 i*sizeof(long), ptr[i], ptr[i+1]);
233 #if 0
234 /* doesn't work with MILO */
235 show_regs(regs);
236 #endif
242 * The System Vector
245 #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
246 struct alpha_machine_vector mikasa_mv __initmv = {
247 vector_name: "Mikasa",
248 DO_EV4_MMU,
249 DO_DEFAULT_RTC,
250 DO_APECS_IO,
251 DO_APECS_BUS,
252 machine_check: mikasa_machine_check,
253 max_dma_address: ALPHA_MAX_DMA_ADDRESS,
255 nr_irqs: 32,
256 irq_probe_mask: _PROBE_MASK(32),
257 update_irq_hw: mikasa_update_irq_hw,
258 ack_irq: generic_ack_irq,
259 device_interrupt: mikasa_device_interrupt,
261 init_arch: apecs_init_arch,
262 init_irq: mikasa_init_irq,
263 init_pit: generic_init_pit,
264 pci_fixup: mikasa_pci_fixup,
265 kill_arch: generic_kill_arch,
267 ALIAS_MV(mikasa)
268 #endif
270 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
271 struct alpha_machine_vector mikasa_primo_mv __initmv = {
272 vector_name: "Mikasa-Primo",
273 DO_EV5_MMU,
274 DO_DEFAULT_RTC,
275 DO_CIA_IO,
276 DO_CIA_BUS,
277 machine_check: mikasa_machine_check,
278 max_dma_address: ALPHA_MAX_DMA_ADDRESS,
280 nr_irqs: 32,
281 irq_probe_mask: _PROBE_MASK(32),
282 update_irq_hw: mikasa_update_irq_hw,
283 ack_irq: generic_ack_irq,
284 device_interrupt: mikasa_device_interrupt,
286 init_arch: cia_init_arch,
287 init_irq: mikasa_init_irq,
288 init_pit: generic_init_pit,
289 pci_fixup: mikasa_primo_pci_fixup,
290 kill_arch: generic_kill_arch,
292 ALIAS_MV(mikasa_primo)
293 #endif