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.
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/types.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>
23 #include <asm/mmu_context.h>
25 #include <asm/pgtable.h>
26 #include <asm/core_t2.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.
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. */
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 */
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
];
78 mask
= sable_irq_swizzle
.shadow_mask
| bit
;
81 sable_irq_swizzle
.shadow_mask
= mask
;
83 /* The "irq" argument is now really the mask bit number. */
87 outb(mask
>> 8, 0x53b);
89 outb(mask
>> 16, 0x53d);
93 sable_ack_irq(unsigned long irq
)
95 /* Note that the "irq" here is really the mask bit number */
98 outb(0xE0 | (irq
- 0), 0x536);
99 outb(0xE0 | 1, 0x534); /* slave 0 */
102 outb(0xE0 | (irq
- 8), 0x53a);
103 outb(0xE0 | 3, 0x534); /* slave 1 */
106 outb(0xE0 | (irq
- 16), 0x53c);
107 outb(0xE0 | 4, 0x534); /* slave 2 */
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
121 ack
= irq
= (vector
- 0x800) >> 4;
123 irq
= sable_irq_swizzle
.mask_to_irq
[(ack
)];
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
);
131 handle_irq(irq
, ack
, regs
);
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):
177 * The device to slot mapping looks like:
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.
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
;
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)
230 struct alpha_machine_vector sable_mv __initmv
= {
231 vector_name
: "Sable",
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
,
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
,
262 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_GAMMA)
264 #define GAMMA_BIAS _GAMMA_BIAS
265 struct alpha_machine_vector sable_gamma_mv __initmv
= {
266 vector_name
: "Sable-Gamma",
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
,
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
,
291 gamma_bias
: _GAMMA_BIAS
294 ALIAS_MV(sable_gamma
)