* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / alpha / kernel / sys_sable.c
blob86b1d83718e17cb4408cc631aae52f503172ea6a
1 /*
2 * linux/arch/alpha/kernel/sys_sable.c
4 * Copyright (C) 1995 David A Rusling
5 * Copyright (C) 1996 Jay A Estabrook
6 * Copyright (C) 1998, 1999 Richard Henderson
8 * Code supporting the Sable and Sable-Gamma systems.
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/mmu_context.h>
24 #include <asm/io.h>
25 #include <asm/pgtable.h>
26 #include <asm/core_t2.h>
28 #include "proto.h"
29 #include "irq_impl.h"
30 #include "pci_impl.h"
31 #include "machvec_impl.h"
35 * For SABLE, which is really baroque, we manage 40 IRQ's, but the
36 * hardware really only supports 24, not via normal ISA PIC,
37 * but cascaded custom 8259's, etc.
38 * 0-7 (char at 536)
39 * 8-15 (char at 53a)
40 * 16-23 (char at 53c)
43 /* Note that the vector reported by the SRM PALcode corresponds to the
44 interrupt mask bits, but we have to manage via more normal IRQs. */
46 static struct
48 char irq_to_mask[40];
49 char mask_to_irq[40];
50 unsigned long shadow_mask;
51 } sable_irq_swizzle = {
53 -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */
54 -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */
55 -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7 */
56 -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */
57 2, 1, 0, 4, 5, -1, -1, -1, /* pseudo PCI */
60 34, 33, 32, 12, 35, 36, 1, 6, /* mask 0-7 */
61 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */
62 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */
68 static void
69 sable_update_irq_hw(unsigned long irq, unsigned long unused_mask, int unmask_p)
71 unsigned long bit, mask;
73 /* The "irq" argument is really the irq, but we need it to
74 be the mask bit number. Convert it now. */
76 irq = sable_irq_swizzle.irq_to_mask[irq];
77 bit = 1UL << irq;
78 mask = sable_irq_swizzle.shadow_mask | bit;
79 if (unmask_p)
80 mask &= ~bit;
81 sable_irq_swizzle.shadow_mask = mask;
83 /* The "irq" argument is now really the mask bit number. */
84 if (irq <= 7)
85 outb(mask, 0x537);
86 else if (irq <= 15)
87 outb(mask >> 8, 0x53b);
88 else
89 outb(mask >> 16, 0x53d);
92 static void
93 sable_ack_irq(unsigned long irq)
95 /* Note that the "irq" here is really the mask bit number */
96 switch (irq) {
97 case 0 ... 7:
98 outb(0xE0 | (irq - 0), 0x536);
99 outb(0xE0 | 1, 0x534); /* slave 0 */
100 break;
101 case 8 ... 15:
102 outb(0xE0 | (irq - 8), 0x53a);
103 outb(0xE0 | 3, 0x534); /* slave 1 */
104 break;
105 case 16 ... 24:
106 outb(0xE0 | (irq - 16), 0x53c);
107 outb(0xE0 | 4, 0x534); /* slave 2 */
108 break;
112 static void
113 sable_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
115 /* Note that the vector reported by the SRM PALcode corresponds
116 to the interrupt mask bits, but we have to manage via more
117 normal IRQs. */
119 int irq, ack;
121 ack = irq = (vector - 0x800) >> 4;
123 irq = sable_irq_swizzle.mask_to_irq[(ack)];
124 #if 0
125 if (irq == 5 || irq == 9 || irq == 10 || irq == 11 ||
126 irq == 14 || irq == 15)
127 printk("srm_device_interrupt: vector=0x%lx ack=0x%x"
128 " irq=0x%x\n", vector, ack, irq);
129 #endif
131 handle_irq(irq, ack, regs);
134 static void __init
135 sable_init_irq(void)
137 STANDARD_INIT_IRQ_PROLOG;
139 outb(alpha_irq_mask , 0x537); /* slave 0 */
140 outb(alpha_irq_mask >> 8, 0x53b); /* slave 1 */
141 outb(alpha_irq_mask >> 16, 0x53d); /* slave 2 */
142 outb(0x44, 0x535); /* enable cascades in master */
147 * PCI Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
149 * Summary Registers (536/53a/53c):
150 * Bit Meaning
151 *-----------------
152 * 0 PCI slot 0
153 * 1 NCR810 (builtin)
154 * 2 TULIP (builtin)
155 * 3 mouse
156 * 4 PCI slot 1
157 * 5 PCI slot 2
158 * 6 keyboard
159 * 7 floppy
160 * 8 COM2
161 * 9 parallel port
162 *10 EISA irq 3
163 *11 EISA irq 4
164 *12 EISA irq 5
165 *13 EISA irq 6
166 *14 EISA irq 7
167 *15 COM1
168 *16 EISA irq 9
169 *17 EISA irq 10
170 *18 EISA irq 11
171 *19 EISA irq 12
172 *20 EISA irq 13
173 *21 EISA irq 14
174 *22 NC
175 *23 IIC
177 * The device to slot mapping looks like:
179 * Slot Device
180 * 0 TULIP
181 * 1 SCSI
182 * 2 PCI-EISA bridge
183 * 3 none
184 * 4 none
185 * 5 none
186 * 6 PCI on board slot 0
187 * 7 PCI on board slot 1
188 * 8 PCI on board slot 2
191 * This two layered interrupt approach means that we allocate IRQ 16 and
192 * above for PCI interrupts. The IRQ relates to which bit the interrupt
193 * comes in on. This makes interrupt processing much easier.
196 * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
197 * with the values in the irq swizzling tables above.
200 static int __init
201 sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
203 static char irq_tab[9][5] __initlocaldata = {
204 /*INT INTA INTB INTC INTD */
205 { 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */
206 { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */
207 { -1, -1, -1, -1, -1}, /* IdSel 2, SIO */
208 { -1, -1, -1, -1, -1}, /* IdSel 3, none */
209 { -1, -1, -1, -1, -1}, /* IdSel 4, none */
210 { -1, -1, -1, -1, -1}, /* IdSel 5, none */
211 { 32+2, 32+2, 32+2, 32+2, 32+2}, /* IdSel 6, slot 0 */
212 { 32+3, 32+3, 32+3, 32+3, 32+3}, /* IdSel 7, slot 1 */
213 { 32+4, 32+4, 32+4, 32+4, 32+4}, /* IdSel 8, slot 2 */
215 const long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5;
216 return COMMON_TABLE_LOOKUP;
221 * The System Vectors
223 * In order that T2_HAE_ADDRESS should be a constant, we play
224 * these games with GAMMA_BIAS.
227 #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_GAMMA)
228 #undef GAMMA_BIAS
229 #define GAMMA_BIAS 0
230 struct alpha_machine_vector sable_mv __initmv = {
231 vector_name: "Sable",
232 DO_EV4_MMU,
233 DO_DEFAULT_RTC,
234 DO_T2_IO,
235 DO_T2_BUS,
236 machine_check: t2_machine_check,
237 max_dma_address: ALPHA_MAX_DMA_ADDRESS,
238 min_io_address: EISA_DEFAULT_IO_BASE,
239 min_mem_address: DEFAULT_MEM_BASE,
241 nr_irqs: 40,
242 irq_probe_mask: _PROBE_MASK(40),
243 update_irq_hw: sable_update_irq_hw,
244 ack_irq: sable_ack_irq,
245 device_interrupt: sable_srm_device_interrupt,
247 init_arch: t2_init_arch,
248 init_irq: sable_init_irq,
249 init_pit: common_init_pit,
250 init_pci: common_init_pci,
251 kill_arch: common_kill_arch,
252 pci_map_irq: sable_map_irq,
253 pci_swizzle: common_swizzle,
255 sys: { t2: {
256 gamma_bias: 0
259 ALIAS_MV(sable)
260 #endif
262 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_GAMMA)
263 #undef GAMMA_BIAS
264 #define GAMMA_BIAS _GAMMA_BIAS
265 struct alpha_machine_vector sable_gamma_mv __initmv = {
266 vector_name: "Sable-Gamma",
267 DO_EV5_MMU,
268 DO_DEFAULT_RTC,
269 DO_T2_IO,
270 DO_T2_BUS,
271 machine_check: t2_machine_check,
272 max_dma_address: ALPHA_MAX_DMA_ADDRESS,
273 min_io_address: EISA_DEFAULT_IO_BASE,
274 min_mem_address: DEFAULT_MEM_BASE,
276 nr_irqs: 40,
277 irq_probe_mask: _PROBE_MASK(40),
278 update_irq_hw: sable_update_irq_hw,
279 ack_irq: sable_ack_irq,
280 device_interrupt: sable_srm_device_interrupt,
282 init_arch: t2_init_arch,
283 init_irq: sable_init_irq,
284 init_pit: common_init_pit,
285 init_pci: common_init_pci,
286 kill_arch: common_kill_arch,
287 pci_map_irq: sable_map_irq,
288 pci_swizzle: common_swizzle,
290 sys: { t2: {
291 gamma_bias: _GAMMA_BIAS
294 ALIAS_MV(sable_gamma)
295 #endif