OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [alpha/] [kernel/] [sys_rawhide.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *      linux/arch/alpha/kernel/sys_rawhide.c
3
 *
4
 *      Copyright (C) 1995 David A Rusling
5
 *      Copyright (C) 1996 Jay A Estabrook
6
 *      Copyright (C) 1998, 1999 Richard Henderson
7
 *
8
 * Code supporting the RAWHIDE.
9
 */
10
 
11
#include <linux/kernel.h>
12
#include <linux/types.h>
13
#include <linux/mm.h>
14
#include <linux/sched.h>
15
#include <linux/pci.h>
16
#include <linux/init.h>
17
 
18
#include <asm/ptrace.h>
19
#include <asm/system.h>
20
#include <asm/dma.h>
21
#include <asm/irq.h>
22
#include <asm/mmu_context.h>
23
#include <asm/io.h>
24
#include <asm/pgtable.h>
25
#include <asm/core_mcpcia.h>
26
#include <asm/tlbflush.h>
27
 
28
#include "proto.h"
29
#include "irq_impl.h"
30
#include "pci_impl.h"
31
#include "machvec_impl.h"
32
 
33
 
34
/*
35
 * HACK ALERT! only the boot cpu is used for interrupts.
36
 */
37
 
38
 
39
/* Note mask bit is true for ENABLED irqs.  */
40
 
41
static unsigned int hose_irq_masks[4] = {
42
        0xff0000, 0xfe0000, 0xff0000, 0xff0000
43
};
44
static unsigned int cached_irq_masks[4];
45
DEFINE_SPINLOCK(rawhide_irq_lock);
46
 
47
static inline void
48
rawhide_update_irq_hw(int hose, int mask)
49
{
50
        *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)) = mask;
51
        mb();
52
        *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose));
53
}
54
 
55
#define hose_exists(h) \
56
  (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))
57
 
58
static inline void
59
rawhide_enable_irq(unsigned int irq)
60
{
61
        unsigned int mask, hose;
62
 
63
        irq -= 16;
64
        hose = irq / 24;
65
        if (!hose_exists(hose)) /* if hose non-existent, exit */
66
                return;
67
 
68
        irq -= hose * 24;
69
        mask = 1 << irq;
70
 
71
        spin_lock(&rawhide_irq_lock);
72
        mask |= cached_irq_masks[hose];
73
        cached_irq_masks[hose] = mask;
74
        rawhide_update_irq_hw(hose, mask);
75
        spin_unlock(&rawhide_irq_lock);
76
}
77
 
78
static void
79
rawhide_disable_irq(unsigned int irq)
80
{
81
        unsigned int mask, hose;
82
 
83
        irq -= 16;
84
        hose = irq / 24;
85
        if (!hose_exists(hose)) /* if hose non-existent, exit */
86
                return;
87
 
88
        irq -= hose * 24;
89
        mask = ~(1 << irq) | hose_irq_masks[hose];
90
 
91
        spin_lock(&rawhide_irq_lock);
92
        mask &= cached_irq_masks[hose];
93
        cached_irq_masks[hose] = mask;
94
        rawhide_update_irq_hw(hose, mask);
95
        spin_unlock(&rawhide_irq_lock);
96
}
97
 
98
static void
99
rawhide_mask_and_ack_irq(unsigned int irq)
100
{
101
        unsigned int mask, mask1, hose;
102
 
103
        irq -= 16;
104
        hose = irq / 24;
105
        if (!hose_exists(hose)) /* if hose non-existent, exit */
106
                return;
107
 
108
        irq -= hose * 24;
109
        mask1 = 1 << irq;
110
        mask = ~mask1 | hose_irq_masks[hose];
111
 
112
        spin_lock(&rawhide_irq_lock);
113
 
114
        mask &= cached_irq_masks[hose];
115
        cached_irq_masks[hose] = mask;
116
        rawhide_update_irq_hw(hose, mask);
117
 
118
        /* Clear the interrupt.  */
119
        *(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1;
120
 
121
        spin_unlock(&rawhide_irq_lock);
122
}
123
 
124
static unsigned int
125
rawhide_startup_irq(unsigned int irq)
126
{
127
        rawhide_enable_irq(irq);
128
        return 0;
129
}
130
 
131
static void
132
rawhide_end_irq(unsigned int irq)
133
{
134
        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
135
                rawhide_enable_irq(irq);
136
}
137
 
138
static struct hw_interrupt_type rawhide_irq_type = {
139
        .typename       = "RAWHIDE",
140
        .startup        = rawhide_startup_irq,
141
        .shutdown       = rawhide_disable_irq,
142
        .enable         = rawhide_enable_irq,
143
        .disable        = rawhide_disable_irq,
144
        .ack            = rawhide_mask_and_ack_irq,
145
        .end            = rawhide_end_irq,
146
};
147
 
148
static void
149
rawhide_srm_device_interrupt(unsigned long vector)
150
{
151
        int irq;
152
 
153
        irq = (vector - 0x800) >> 4;
154
 
155
        /*
156
         * The RAWHIDE SRM console reports PCI interrupts with a vector
157
         * 0x80 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
158
         * shows up as IRQ 24, etc, etc. We adjust it down by 8 to have
159
         * it line up with the actual bit numbers from the REQ registers,
160
         * which is how we manage the interrupts/mask. Sigh...
161
         *
162
         * Also, PCI #1 interrupts are offset some more... :-(
163
         */
164
 
165
        if (irq == 52) {
166
                /* SCSI on PCI1 is special.  */
167
                irq = 72;
168
        }
169
 
170
        /* Adjust by which hose it is from.  */
171
        irq -= ((irq + 16) >> 2) & 0x38;
172
 
173
        handle_irq(irq);
174
}
175
 
176
static void __init
177
rawhide_init_irq(void)
178
{
179
        struct pci_controller *hose;
180
        long i;
181
 
182
        mcpcia_init_hoses();
183
 
184
        /* Clear them all; only hoses that exist will be non-zero. */
185
        for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0;
186
 
187
        for (hose = hose_head; hose; hose = hose->next) {
188
                unsigned int h = hose->index;
189
                unsigned int mask = hose_irq_masks[h];
190
 
191
                cached_irq_masks[h] = mask;
192
                *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask;
193
                *(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0;
194
        }
195
 
196
        for (i = 16; i < 128; ++i) {
197
                irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
198
                irq_desc[i].chip = &rawhide_irq_type;
199
        }
200
 
201
        init_i8259a_irqs();
202
        common_init_isa_dma();
203
}
204
 
205
/*
206
 * PCI Fixup configuration.
207
 *
208
 * Summary @ MCPCIA_PCI0_INT_REQ:
209
 * Bit      Meaning
210
 * 0        Interrupt Line A from slot 2 PCI0
211
 * 1        Interrupt Line B from slot 2 PCI0
212
 * 2        Interrupt Line C from slot 2 PCI0
213
 * 3        Interrupt Line D from slot 2 PCI0
214
 * 4        Interrupt Line A from slot 3 PCI0
215
 * 5        Interrupt Line B from slot 3 PCI0
216
 * 6        Interrupt Line C from slot 3 PCI0
217
 * 7        Interrupt Line D from slot 3 PCI0
218
 * 8        Interrupt Line A from slot 4 PCI0
219
 * 9        Interrupt Line B from slot 4 PCI0
220
 * 10       Interrupt Line C from slot 4 PCI0
221
 * 11       Interrupt Line D from slot 4 PCI0
222
 * 12       Interrupt Line A from slot 5 PCI0
223
 * 13       Interrupt Line B from slot 5 PCI0
224
 * 14       Interrupt Line C from slot 5 PCI0
225
 * 15       Interrupt Line D from slot 5 PCI0
226
 * 16       EISA interrupt (PCI 0) or SCSI interrupt (PCI 1)
227
 * 17-23    NA
228
 *
229
 * IdSel
230
 *   1   EISA bridge (PCI bus 0 only)
231
 *   2   PCI option slot 2
232
 *   3   PCI option slot 3
233
 *   4   PCI option slot 4
234
 *   5   PCI option slot 5
235
 *
236
 */
237
 
238
static int __init
239
rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
240
{
241
        static char irq_tab[5][5] __initdata = {
242
                /*INT    INTA   INTB   INTC   INTD */
243
                { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
244
                { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
245
                { 16+ 4, 16+ 4, 16+ 5, 16+ 6, 16+ 7}, /* IdSel 3 slot 3 */
246
                { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 4 slot 4 */
247
                { 16+12, 16+12, 16+13, 16+14, 16+15}  /* IdSel 5 slot 5 */
248
        };
249
        const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5;
250
 
251
        struct pci_controller *hose = dev->sysdata;
252
        int irq = COMMON_TABLE_LOOKUP;
253
        if (irq >= 0)
254
                irq += 24 * hose->index;
255
        return irq;
256
}
257
 
258
 
259
/*
260
 * The System Vector
261
 */
262
 
263
struct alpha_machine_vector rawhide_mv __initmv = {
264
        .vector_name            = "Rawhide",
265
        DO_EV5_MMU,
266
        DO_DEFAULT_RTC,
267
        DO_MCPCIA_IO,
268
        .machine_check          = mcpcia_machine_check,
269
        .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
270
        .min_io_address         = DEFAULT_IO_BASE,
271
        .min_mem_address        = MCPCIA_DEFAULT_MEM_BASE,
272
        .pci_dac_offset         = MCPCIA_DAC_OFFSET,
273
 
274
        .nr_irqs                = 128,
275
        .device_interrupt       = rawhide_srm_device_interrupt,
276
 
277
        .init_arch              = mcpcia_init_arch,
278
        .init_irq               = rawhide_init_irq,
279
        .init_rtc               = common_init_rtc,
280
        .init_pci               = common_init_pci,
281
        .kill_arch              = NULL,
282
        .pci_map_irq            = rawhide_map_irq,
283
        .pci_swizzle            = common_swizzle,
284
};
285
ALIAS_MV(rawhide)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.