diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-07-14 11:57:16 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:31:53 -0400 |
commit | e01402b115cccb6357f956649487aca2c6f7fbba (patch) | |
tree | 256e14f8d2762de98b992219b1a47e8f56b4b0da /arch/mips/mips-boards | |
parent | 86071b637db7baf599df26fdf820dce2fc55ca9f (diff) |
More AP / SP bits for the 34K, the Malta bits and things. Still wants
a little polishing.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mips-boards')
-rw-r--r-- | arch/mips/mips-boards/generic/init.c | 29 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/memory.c | 29 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/mipsIRQ.S | 110 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/time.c | 49 | ||||
-rw-r--r-- | arch/mips/mips-boards/malta/malta_int.c | 136 |
5 files changed, 243 insertions, 110 deletions
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index d821b13d24a0..58256ea33102 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <asm/gt64120.h> | 28 | #include <asm/gt64120.h> |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/cacheflush.h> | ||
32 | #include <asm/traps.h> | ||
31 | 33 | ||
32 | #include <asm/mips-boards/prom.h> | 34 | #include <asm/mips-boards/prom.h> |
33 | #include <asm/mips-boards/generic.h> | 35 | #include <asm/mips-boards/generic.h> |
@@ -224,6 +226,30 @@ void __init kgdb_config (void) | |||
224 | } | 226 | } |
225 | #endif | 227 | #endif |
226 | 228 | ||
229 | void __init mips_nmi_setup (void) | ||
230 | { | ||
231 | void *base; | ||
232 | extern char except_vec_nmi; | ||
233 | |||
234 | base = cpu_has_veic ? | ||
235 | (void *)(CAC_BASE + 0xa80) : | ||
236 | (void *)(CAC_BASE + 0x380); | ||
237 | memcpy(base, &except_vec_nmi, 0x80); | ||
238 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | ||
239 | } | ||
240 | |||
241 | void __init mips_ejtag_setup (void) | ||
242 | { | ||
243 | void *base; | ||
244 | extern char except_vec_ejtag_debug; | ||
245 | |||
246 | base = cpu_has_veic ? | ||
247 | (void *)(CAC_BASE + 0xa00) : | ||
248 | (void *)(CAC_BASE + 0x300); | ||
249 | memcpy(base, &except_vec_ejtag_debug, 0x80); | ||
250 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | ||
251 | } | ||
252 | |||
227 | void __init prom_init(void) | 253 | void __init prom_init(void) |
228 | { | 254 | { |
229 | u32 start, map, mask, data; | 255 | u32 start, map, mask, data; |
@@ -353,6 +379,9 @@ void __init prom_init(void) | |||
353 | while(1); /* We die here... */ | 379 | while(1); /* We die here... */ |
354 | } | 380 | } |
355 | #endif | 381 | #endif |
382 | board_nmi_handler_setup = mips_nmi_setup; | ||
383 | board_ejtag_handler_setup = mips_ejtag_setup; | ||
384 | |||
356 | prom_printf("\nLINUX started...\n"); | 385 | prom_printf("\nLINUX started...\n"); |
357 | prom_init_cmdline(); | 386 | prom_init_cmdline(); |
358 | prom_meminit(); | 387 | prom_meminit(); |
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index 5ae2b43e4c2e..2c8afd77a20b 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
25 | #include <linux/string.h> | ||
25 | 26 | ||
26 | #include <asm/bootinfo.h> | 27 | #include <asm/bootinfo.h> |
27 | #include <asm/page.h> | 28 | #include <asm/page.h> |
@@ -55,18 +56,30 @@ struct prom_pmemblock * __init prom_getmdesc(void) | |||
55 | { | 56 | { |
56 | char *memsize_str; | 57 | char *memsize_str; |
57 | unsigned int memsize; | 58 | unsigned int memsize; |
59 | char cmdline[CL_SIZE], *ptr; | ||
58 | 60 | ||
59 | memsize_str = prom_getenv("memsize"); | 61 | /* Check the command line first for a memsize directive */ |
60 | if (!memsize_str) { | 62 | strcpy(cmdline, arcs_cmdline); |
61 | prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); | 63 | ptr = strstr(cmdline, "memsize="); |
62 | memsize = 0x02000000; | 64 | if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) |
63 | } else { | 65 | ptr = strstr(ptr, " memsize="); |
66 | |||
67 | if (ptr) { | ||
68 | memsize = memparse(ptr + 8, &ptr); | ||
69 | } | ||
70 | else { | ||
71 | /* otherwise look in the environment */ | ||
72 | memsize_str = prom_getenv("memsize"); | ||
73 | if (!memsize_str) { | ||
74 | prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); | ||
75 | memsize = 0x02000000; | ||
76 | } else { | ||
64 | #ifdef DEBUG | 77 | #ifdef DEBUG |
65 | prom_printf("prom_memsize = %s\n", memsize_str); | 78 | prom_printf("prom_memsize = %s\n", memsize_str); |
66 | #endif | 79 | #endif |
67 | memsize = simple_strtol(memsize_str, NULL, 0); | 80 | memsize = simple_strtol(memsize_str, NULL, 0); |
81 | } | ||
68 | } | 82 | } |
69 | |||
70 | memset(mdesc, 0, sizeof(mdesc)); | 83 | memset(mdesc, 0, sizeof(mdesc)); |
71 | 84 | ||
72 | mdesc[0].type = yamon_dontuse; | 85 | mdesc[0].type = yamon_dontuse; |
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S index 131f49bccb20..a397ecb872d6 100644 --- a/arch/mips/mips-boards/generic/mipsIRQ.S +++ b/arch/mips/mips-boards/generic/mipsIRQ.S | |||
@@ -29,6 +29,20 @@ | |||
29 | #include <asm/regdef.h> | 29 | #include <asm/regdef.h> |
30 | #include <asm/stackframe.h> | 30 | #include <asm/stackframe.h> |
31 | 31 | ||
32 | #ifdef CONFIG_MIPS_ATLAS | ||
33 | #include <asm/mips-boards/atlasint.h> | ||
34 | #define CASCADE_IRQ MIPSCPU_INT_ATLAS | ||
35 | #define CASCADE_DISPATCH atlas_hw0_irqdispatch | ||
36 | #endif | ||
37 | #ifdef CONFIG_MIPS_MALTA | ||
38 | #include <asm/mips-boards/maltaint.h> | ||
39 | #define CASCADE_IRQ MIPSCPU_INT_I8259A | ||
40 | #define CASCADE_DISPATCH malta_hw0_irqdispatch | ||
41 | #endif | ||
42 | #ifdef CONFIG_MIPS_SEAD | ||
43 | #include <asm/mips-boards/seadint.h> | ||
44 | #endif | ||
45 | |||
32 | /* A lot of complication here is taken away because: | 46 | /* A lot of complication here is taken away because: |
33 | * | 47 | * |
34 | * 1) We handle one interrupt and return, sitting in a loop and moving across | 48 | * 1) We handle one interrupt and return, sitting in a loop and moving across |
@@ -80,74 +94,62 @@ | |||
80 | 94 | ||
81 | mfc0 s0, CP0_CAUSE # get irq bits | 95 | mfc0 s0, CP0_CAUSE # get irq bits |
82 | mfc0 s1, CP0_STATUS # get irq mask | 96 | mfc0 s1, CP0_STATUS # get irq mask |
97 | andi s0, ST0_IM # CAUSE.CE may be non-zero! | ||
83 | and s0, s1 | 98 | and s0, s1 |
84 | 99 | ||
85 | /* First we check for r4k counter/timer IRQ. */ | 100 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) |
86 | andi a0, s0, CAUSEF_IP7 | 101 | .set mips32 |
87 | beq a0, zero, 1f | 102 | clz a0, s0 |
88 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | 103 | .set mips0 |
104 | negu a0 | ||
105 | addu a0, 31-CAUSEB_IP | ||
106 | bltz a0, spurious | ||
107 | #else | ||
108 | beqz s0, spurious | ||
109 | li a0, 7 | ||
89 | 110 | ||
90 | /* Wheee, a timer interrupt. */ | 111 | and t0, s0, 0xf000 |
91 | move a0, sp | 112 | sltiu t0, t0, 1 |
92 | jal mips_timer_interrupt | 113 | sll t0, 2 |
93 | nop | 114 | subu a0, t0 |
115 | sll s0, t0 | ||
94 | 116 | ||
95 | j ret_from_irq | 117 | and t0, s0, 0xc000 |
96 | nop | 118 | sltiu t0, t0, 1 |
119 | sll t0, 1 | ||
120 | subu a0, t0 | ||
121 | sll s0, t0 | ||
97 | 122 | ||
98 | 1: | 123 | and t0, s0, 0x8000 |
99 | #if defined(CONFIG_MIPS_SEAD) | 124 | sltiu t0, t0, 1 |
100 | beq a0, zero, 1f | 125 | # sll t0, 0 |
101 | andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt | 126 | subu a0, t0 |
102 | #else | 127 | # sll s0, t0 |
103 | beq a0, zero, 1f # delay slot, check hw3 interrupt | ||
104 | andi a0, s0, CAUSEF_IP5 | ||
105 | #endif | 128 | #endif |
106 | 129 | ||
107 | /* Wheee, combined hardware level zero interrupt. */ | 130 | #ifdef CASCADE_IRQ |
108 | #if defined(CONFIG_MIPS_ATLAS) | 131 | li a1, CASCADE_IRQ |
109 | jal atlas_hw0_irqdispatch | 132 | bne a0, a1, 1f |
110 | #elif defined(CONFIG_MIPS_MALTA) | 133 | addu a0, MIPSCPU_INT_BASE |
111 | jal malta_hw0_irqdispatch | ||
112 | #elif defined(CONFIG_MIPS_SEAD) | ||
113 | jal sead_hw0_irqdispatch | ||
114 | #else | ||
115 | #error "MIPS board not supported\n" | ||
116 | #endif | ||
117 | move a0, sp # delay slot | ||
118 | 134 | ||
119 | j ret_from_irq | 135 | jal CASCADE_DISPATCH |
120 | nop # delay slot | 136 | move a0, sp |
121 | 137 | ||
122 | 1: | ||
123 | #if defined(CONFIG_MIPS_SEAD) | ||
124 | beq a0, zero, 1f | ||
125 | andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt | ||
126 | jal sead_hw1_irqdispatch | ||
127 | move a0, sp # delay slot | ||
128 | j ret_from_irq | ||
129 | nop # delay slot | ||
130 | 1: | ||
131 | #endif | ||
132 | #if defined(CONFIG_MIPS_MALTA) | ||
133 | beq a0, zero, 1f # check hw3 (coreHI) interrupt | ||
134 | nop | ||
135 | jal corehi_irqdispatch | ||
136 | move a0, sp | ||
137 | j ret_from_irq | 138 | j ret_from_irq |
138 | nop | 139 | nop |
139 | 1: | 140 | 1: |
141 | #else | ||
142 | addu a0, MIPSCPU_INT_BASE | ||
140 | #endif | 143 | #endif |
141 | /* | 144 | |
142 | * Here by mistake? This is possible, what can happen is that by the | 145 | jal do_IRQ |
143 | * time we take the exception the IRQ pin goes low, so just leave if | 146 | move a1, sp |
144 | * this is the case. | ||
145 | */ | ||
146 | move a1,s0 | ||
147 | PRINT("Got interrupt: c0_cause = %08x\n") | ||
148 | mfc0 a1, CP0_EPC | ||
149 | PRINT("c0_epc = %08x\n") | ||
150 | 147 | ||
151 | j ret_from_irq | 148 | j ret_from_irq |
152 | nop | 149 | nop |
150 | |||
151 | |||
152 | spurious: | ||
153 | j spurious_interrupt | ||
154 | nop | ||
153 | END(mipsIRQ) | 155 | END(mipsIRQ) |
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 16315444dd5a..3a6f1428b2cb 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -31,22 +31,21 @@ | |||
31 | 31 | ||
32 | #include <asm/mipsregs.h> | 32 | #include <asm/mipsregs.h> |
33 | #include <asm/ptrace.h> | 33 | #include <asm/ptrace.h> |
34 | #include <asm/hardirq.h> | ||
35 | #include <asm/irq.h> | ||
34 | #include <asm/div64.h> | 36 | #include <asm/div64.h> |
35 | #include <asm/cpu.h> | 37 | #include <asm/cpu.h> |
36 | #include <asm/time.h> | 38 | #include <asm/time.h> |
37 | #include <asm/mc146818-time.h> | 39 | #include <asm/mc146818-time.h> |
40 | #include <asm/msc01_ic.h> | ||
38 | 41 | ||
39 | #include <asm/mips-boards/generic.h> | 42 | #include <asm/mips-boards/generic.h> |
40 | #include <asm/mips-boards/prom.h> | 43 | #include <asm/mips-boards/prom.h> |
44 | #include <asm/mips-boards/maltaint.h> | ||
45 | #include <asm/mc146818-time.h> | ||
41 | 46 | ||
42 | unsigned long cpu_khz; | 47 | unsigned long cpu_khz; |
43 | 48 | ||
44 | #if defined(CONFIG_MIPS_SEAD) | ||
45 | #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5) | ||
46 | #else | ||
47 | #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) | ||
48 | #endif | ||
49 | |||
50 | #if defined(CONFIG_MIPS_ATLAS) | 49 | #if defined(CONFIG_MIPS_ATLAS) |
51 | static char display_string[] = " LINUX ON ATLAS "; | 50 | static char display_string[] = " LINUX ON ATLAS "; |
52 | #endif | 51 | #endif |
@@ -59,20 +58,27 @@ static char display_string[] = " LINUX ON SEAD "; | |||
59 | static unsigned int display_count = 0; | 58 | static unsigned int display_count = 0; |
60 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | 59 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) |
61 | 60 | ||
62 | #define MIPS_CPU_TIMER_IRQ (NR_IRQS-1) | ||
63 | |||
64 | static unsigned int timer_tick_count=0; | 61 | static unsigned int timer_tick_count=0; |
62 | static int mips_cpu_timer_irq; | ||
65 | 63 | ||
66 | void mips_timer_interrupt(struct pt_regs *regs) | 64 | static void mips_timer_dispatch (struct pt_regs *regs) |
67 | { | 65 | { |
66 | do_IRQ (mips_cpu_timer_irq, regs); | ||
67 | } | ||
68 | |||
69 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
70 | { | ||
71 | irqreturn_t r; | ||
72 | |||
73 | r = timer_interrupt(irq, dev_id, regs); | ||
74 | |||
68 | if ((timer_tick_count++ % HZ) == 0) { | 75 | if ((timer_tick_count++ % HZ) == 0) { |
69 | mips_display_message(&display_string[display_count++]); | 76 | mips_display_message(&display_string[display_count++]); |
70 | if (display_count == MAX_DISPLAY_COUNT) | 77 | if (display_count == MAX_DISPLAY_COUNT) |
71 | display_count = 0; | 78 | display_count = 0; |
72 | |||
73 | } | 79 | } |
74 | 80 | ||
75 | ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); | 81 | return r; |
76 | } | 82 | } |
77 | 83 | ||
78 | /* | 84 | /* |
@@ -140,10 +146,8 @@ void __init mips_time_init(void) | |||
140 | 146 | ||
141 | local_irq_save(flags); | 147 | local_irq_save(flags); |
142 | 148 | ||
143 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | ||
144 | /* Set Data mode - binary. */ | 149 | /* Set Data mode - binary. */ |
145 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | 150 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); |
146 | #endif | ||
147 | 151 | ||
148 | est_freq = estimate_cpu_frequency (); | 152 | est_freq = estimate_cpu_frequency (); |
149 | 153 | ||
@@ -157,11 +161,22 @@ void __init mips_time_init(void) | |||
157 | 161 | ||
158 | void __init mips_timer_setup(struct irqaction *irq) | 162 | void __init mips_timer_setup(struct irqaction *irq) |
159 | { | 163 | { |
164 | if (cpu_has_veic) { | ||
165 | set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch); | ||
166 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | ||
167 | } | ||
168 | else { | ||
169 | if (cpu_has_vint) | ||
170 | set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch); | ||
171 | mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR; | ||
172 | } | ||
173 | |||
174 | |||
160 | /* we are using the cpu counter for timer interrupts */ | 175 | /* we are using the cpu counter for timer interrupts */ |
161 | irq->handler = no_action; /* we use our own handler */ | 176 | irq->handler = mips_timer_interrupt; /* we use our own handler */ |
162 | setup_irq(MIPS_CPU_TIMER_IRQ, irq); | 177 | setup_irq(mips_cpu_timer_irq, irq); |
178 | |||
163 | 179 | ||
164 | /* to generate the first timer interrupt */ | 180 | /* to generate the first timer interrupt */ |
165 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); | 181 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); |
166 | set_c0_status(ALLINTS); | ||
167 | } | 182 | } |
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index dd2db35966bc..6f99a4492015 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/random.h> | 30 | #include <linux/random.h> |
31 | 31 | ||
32 | #include <asm/i8259.h> | 32 | #include <asm/i8259.h> |
33 | #include <asm/irq_cpu.h> | ||
33 | #include <asm/io.h> | 34 | #include <asm/io.h> |
34 | #include <asm/mips-boards/malta.h> | 35 | #include <asm/mips-boards/malta.h> |
35 | #include <asm/mips-boards/maltaint.h> | 36 | #include <asm/mips-boards/maltaint.h> |
@@ -37,8 +38,10 @@ | |||
37 | #include <asm/gt64120.h> | 38 | #include <asm/gt64120.h> |
38 | #include <asm/mips-boards/generic.h> | 39 | #include <asm/mips-boards/generic.h> |
39 | #include <asm/mips-boards/msc01_pci.h> | 40 | #include <asm/mips-boards/msc01_pci.h> |
41 | #include <asm/msc01_ic.h> | ||
40 | 42 | ||
41 | extern asmlinkage void mipsIRQ(void); | 43 | extern asmlinkage void mipsIRQ(void); |
44 | extern void mips_timer_interrupt(void); | ||
42 | 45 | ||
43 | static DEFINE_SPINLOCK(mips_irq_lock); | 46 | static DEFINE_SPINLOCK(mips_irq_lock); |
44 | 47 | ||
@@ -91,13 +94,13 @@ static inline int mips_pcibios_iack(void) | |||
91 | return irq; | 94 | return irq; |
92 | } | 95 | } |
93 | 96 | ||
94 | static inline int get_int(int *irq) | 97 | static inline int get_int(void) |
95 | { | 98 | { |
96 | unsigned long flags; | 99 | unsigned long flags; |
97 | 100 | int irq; | |
98 | spin_lock_irqsave(&mips_irq_lock, flags); | 101 | spin_lock_irqsave(&mips_irq_lock, flags); |
99 | 102 | ||
100 | *irq = mips_pcibios_iack(); | 103 | irq = mips_pcibios_iack(); |
101 | 104 | ||
102 | /* | 105 | /* |
103 | * IRQ7 is used to detect spurious interrupts. | 106 | * IRQ7 is used to detect spurious interrupts. |
@@ -106,73 +109,82 @@ static inline int get_int(int *irq) | |||
106 | * We can differentiate between this situation and a | 109 | * We can differentiate between this situation and a |
107 | * "Normal" IRQ7 by reading the ISR. | 110 | * "Normal" IRQ7 by reading the ISR. |
108 | */ | 111 | */ |
109 | if (*irq == 7) | 112 | if (irq == 7) |
110 | { | 113 | { |
111 | outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, | 114 | outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, |
112 | PIIX4_ICTLR1_OCW3); | 115 | PIIX4_ICTLR1_OCW3); |
113 | if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) { | 116 | if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) { |
114 | spin_unlock_irqrestore(&mips_irq_lock, flags); | 117 | irq = -1; /* Spurious interrupt */ |
115 | printk("We got a spurious interrupt from PIIX4.\n"); | 118 | printk("We got a spurious interrupt from PIIX4.\n"); |
116 | atomic_inc(&irq_err_count); | 119 | atomic_inc(&irq_err_count); |
117 | return -1; /* Spurious interrupt. */ | ||
118 | } | 120 | } |
119 | } | 121 | } |
120 | 122 | ||
121 | spin_unlock_irqrestore(&mips_irq_lock, flags); | 123 | spin_unlock_irqrestore(&mips_irq_lock, flags); |
122 | 124 | ||
123 | return 0; | 125 | return irq; |
124 | } | 126 | } |
125 | 127 | ||
126 | void malta_hw0_irqdispatch(struct pt_regs *regs) | 128 | void malta_hw0_irqdispatch(struct pt_regs *regs) |
127 | { | 129 | { |
128 | int irq; | 130 | int irq; |
129 | 131 | ||
130 | if (get_int(&irq)) | 132 | irq = get_int(); |
131 | return; /* interrupt has already been cleared */ | 133 | if (irq < 0) |
134 | return; /* interrupt has already been cleared */ | ||
132 | 135 | ||
133 | do_IRQ(irq, regs); | 136 | do_IRQ(MALTA_INT_BASE+irq, regs); |
134 | } | 137 | } |
135 | 138 | ||
136 | void corehi_irqdispatch(struct pt_regs *regs) | 139 | void corehi_irqdispatch(struct pt_regs *regs) |
137 | { | 140 | { |
138 | unsigned int data,datahi; | 141 | unsigned int intrcause,datalo,datahi; |
139 | 142 | unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr; | |
140 | /* Mask out corehi interrupt. */ | ||
141 | clear_c0_status(IE_IRQ3); | ||
142 | 143 | ||
143 | printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); | 144 | printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); |
144 | printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" | 145 | printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" |
145 | , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); | 146 | , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); |
147 | |||
148 | /* Read all the registers and then print them as there is a | ||
149 | problem with interspersed printk's upsetting the Bonito controller. | ||
150 | Do it for the others too. | ||
151 | */ | ||
152 | |||
146 | switch(mips_revision_corid) { | 153 | switch(mips_revision_corid) { |
147 | case MIPS_REVISION_CORID_CORE_MSC: | 154 | case MIPS_REVISION_CORID_CORE_MSC: |
148 | case MIPS_REVISION_CORID_CORE_FPGA2: | 155 | case MIPS_REVISION_CORID_CORE_FPGA2: |
149 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | 156 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: |
157 | ll_msc_irq(regs); | ||
150 | break; | 158 | break; |
151 | case MIPS_REVISION_CORID_QED_RM5261: | 159 | case MIPS_REVISION_CORID_QED_RM5261: |
152 | case MIPS_REVISION_CORID_CORE_LV: | 160 | case MIPS_REVISION_CORID_CORE_LV: |
153 | case MIPS_REVISION_CORID_CORE_FPGA: | 161 | case MIPS_REVISION_CORID_CORE_FPGA: |
154 | case MIPS_REVISION_CORID_CORE_FPGAR2: | 162 | case MIPS_REVISION_CORID_CORE_FPGAR2: |
155 | data = GT_READ(GT_INTRCAUSE_OFS); | 163 | intrcause = GT_READ(GT_INTRCAUSE_OFS); |
156 | printk("GT_INTRCAUSE = %08x\n", data); | 164 | datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); |
157 | data = GT_READ(GT_CPUERR_ADDRLO_OFS); | ||
158 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); | 165 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); |
159 | printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data); | 166 | printk("GT_INTRCAUSE = %08x\n", intrcause); |
167 | printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); | ||
160 | break; | 168 | break; |
161 | case MIPS_REVISION_CORID_BONITO64: | 169 | case MIPS_REVISION_CORID_BONITO64: |
162 | case MIPS_REVISION_CORID_CORE_20K: | 170 | case MIPS_REVISION_CORID_CORE_20K: |
163 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | 171 | case MIPS_REVISION_CORID_CORE_EMUL_BON: |
164 | data = BONITO_INTISR; | 172 | pcibadaddr = BONITO_PCIBADADDR; |
165 | printk("BONITO_INTISR = %08x\n", data); | 173 | pcimstat = BONITO_PCIMSTAT; |
166 | data = BONITO_INTEN; | 174 | intisr = BONITO_INTISR; |
167 | printk("BONITO_INTEN = %08x\n", data); | 175 | inten = BONITO_INTEN; |
168 | data = BONITO_INTPOL; | 176 | intpol = BONITO_INTPOL; |
169 | printk("BONITO_INTPOL = %08x\n", data); | 177 | intedge = BONITO_INTEDGE; |
170 | data = BONITO_INTEDGE; | 178 | intsteer = BONITO_INTSTEER; |
171 | printk("BONITO_INTEDGE = %08x\n", data); | 179 | pcicmd = BONITO_PCICMD; |
172 | data = BONITO_INTSTEER; | 180 | printk("BONITO_INTISR = %08x\n", intisr); |
173 | printk("BONITO_INTSTEER = %08x\n", data); | 181 | printk("BONITO_INTEN = %08x\n", inten); |
174 | data = BONITO_PCICMD; | 182 | printk("BONITO_INTPOL = %08x\n", intpol); |
175 | printk("BONITO_PCICMD = %08x\n", data); | 183 | printk("BONITO_INTEDGE = %08x\n", intedge); |
184 | printk("BONITO_INTSTEER = %08x\n", intsteer); | ||
185 | printk("BONITO_PCICMD = %08x\n", pcicmd); | ||
186 | printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr); | ||
187 | printk("BONITO_PCIMSTAT = %08x\n", pcimstat); | ||
176 | break; | 188 | break; |
177 | } | 189 | } |
178 | 190 | ||
@@ -180,8 +192,70 @@ void corehi_irqdispatch(struct pt_regs *regs) | |||
180 | die("CoreHi interrupt", regs); | 192 | die("CoreHi interrupt", regs); |
181 | } | 193 | } |
182 | 194 | ||
195 | static struct irqaction i8259irq = { | ||
196 | .handler = no_action, | ||
197 | .name = "XT-PIC cascade" | ||
198 | }; | ||
199 | |||
200 | static struct irqaction corehi_irqaction = { | ||
201 | .handler = no_action, | ||
202 | .name = "CoreHi" | ||
203 | }; | ||
204 | |||
205 | msc_irqmap_t __initdata msc_irqmap[] = { | ||
206 | {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, | ||
207 | {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, | ||
208 | }; | ||
209 | int __initdata msc_nr_irqs = sizeof(msc_irqmap)/sizeof(msc_irqmap_t); | ||
210 | |||
211 | msc_irqmap_t __initdata msc_eicirqmap[] = { | ||
212 | {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, | ||
213 | {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, | ||
214 | {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0}, | ||
215 | {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0}, | ||
216 | {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0}, | ||
217 | {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0}, | ||
218 | {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, | ||
219 | {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, | ||
220 | {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, | ||
221 | {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} | ||
222 | }; | ||
223 | int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t); | ||
224 | |||
183 | void __init arch_init_irq(void) | 225 | void __init arch_init_irq(void) |
184 | { | 226 | { |
185 | set_except_vector(0, mipsIRQ); | 227 | set_except_vector(0, mipsIRQ); |
186 | init_i8259_irqs(); | 228 | init_i8259_irqs(); |
229 | |||
230 | if (!cpu_has_veic) | ||
231 | mips_cpu_irq_init (MIPSCPU_INT_BASE); | ||
232 | |||
233 | switch(mips_revision_corid) { | ||
234 | case MIPS_REVISION_CORID_CORE_MSC: | ||
235 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
236 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
237 | if (cpu_has_veic) | ||
238 | init_msc_irqs (MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); | ||
239 | else | ||
240 | init_msc_irqs (MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); | ||
241 | } | ||
242 | |||
243 | if (cpu_has_veic) { | ||
244 | set_vi_handler (MSC01E_INT_I8259A, malta_hw0_irqdispatch); | ||
245 | set_vi_handler (MSC01E_INT_COREHI, corehi_irqdispatch); | ||
246 | setup_irq (MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); | ||
247 | setup_irq (MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); | ||
248 | } | ||
249 | else if (cpu_has_vint) { | ||
250 | set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); | ||
251 | set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch); | ||
252 | |||
253 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); | ||
254 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); | ||
255 | } | ||
256 | else { | ||
257 | set_except_vector(0, mipsIRQ); | ||
258 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); | ||
259 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); | ||
260 | } | ||
187 | } | 261 | } |