diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-08-17 09:44:26 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:32:09 -0400 |
commit | d03d0a57754cb820d318d2234c60b728eb38a94d (patch) | |
tree | c9feac8689e0081304382411592f3e074fe96502 | |
parent | 533330bf7fa19854f3b4accd2b84ff58e3ee160f (diff) |
MT bulletproofing.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/kernel/irq_cpu.c | 79 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 10 |
2 files changed, 75 insertions, 14 deletions
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 31c38c4971c0..5db67e31ec1a 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <asm/irq_cpu.h> | 34 | #include <asm/irq_cpu.h> |
35 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
36 | #include <asm/mipsmtregs.h> | ||
36 | #include <asm/system.h> | 37 | #include <asm/system.h> |
37 | 38 | ||
38 | static int mips_cpu_irq_base; | 39 | static int mips_cpu_irq_base; |
@@ -76,7 +77,7 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq) | |||
76 | return 0; | 77 | return 0; |
77 | } | 78 | } |
78 | 79 | ||
79 | #define mips_cpu_irq_shutdown mips_cpu_irq_disable | 80 | #define mips_cpu_irq_shutdown mips_cpu_irq_disable |
80 | 81 | ||
81 | /* | 82 | /* |
82 | * While we ack the interrupt interrupts are disabled and thus we don't need | 83 | * While we ack the interrupt interrupts are disabled and thus we don't need |
@@ -84,9 +85,6 @@ static unsigned int mips_cpu_irq_startup(unsigned int irq) | |||
84 | */ | 85 | */ |
85 | static void mips_cpu_irq_ack(unsigned int irq) | 86 | static void mips_cpu_irq_ack(unsigned int irq) |
86 | { | 87 | { |
87 | /* Only necessary for soft interrupts */ | ||
88 | clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); | ||
89 | |||
90 | mask_mips_irq(irq); | 88 | mask_mips_irq(irq); |
91 | } | 89 | } |
92 | 90 | ||
@@ -97,15 +95,60 @@ static void mips_cpu_irq_end(unsigned int irq) | |||
97 | } | 95 | } |
98 | 96 | ||
99 | static hw_irq_controller mips_cpu_irq_controller = { | 97 | static hw_irq_controller mips_cpu_irq_controller = { |
100 | .typename = "MIPS", | 98 | .typename = "MIPS", |
101 | .startup = mips_cpu_irq_startup, | 99 | .startup = mips_cpu_irq_startup, |
102 | .shutdown = mips_cpu_irq_shutdown, | 100 | .shutdown = mips_cpu_irq_shutdown, |
103 | .enable = mips_cpu_irq_enable, | 101 | .enable = mips_cpu_irq_enable, |
104 | .disable = mips_cpu_irq_disable, | 102 | .disable = mips_cpu_irq_disable, |
105 | .ack = mips_cpu_irq_ack, | 103 | .ack = mips_cpu_irq_ack, |
106 | .end = mips_cpu_irq_end, | 104 | .end = mips_cpu_irq_end, |
107 | }; | 105 | }; |
108 | 106 | ||
107 | /* | ||
108 | * Basically the same as above but taking care of all the MT stuff | ||
109 | */ | ||
110 | |||
111 | #define unmask_mips_mt_irq unmask_mips_irq | ||
112 | #define mask_mips_mt_irq mask_mips_irq | ||
113 | #define mips_mt_cpu_irq_enable mips_cpu_irq_enable | ||
114 | #define mips_mt_cpu_irq_disable mips_cpu_irq_disable | ||
115 | |||
116 | static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) | ||
117 | { | ||
118 | unsigned int vpflags = dvpe(); | ||
119 | |||
120 | clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); | ||
121 | evpe(vpflags); | ||
122 | mips_mt_cpu_irq_enable(irq); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | #define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable | ||
128 | |||
129 | /* | ||
130 | * While we ack the interrupt interrupts are disabled and thus we don't need | ||
131 | * to deal with concurrency issues. Same for mips_cpu_irq_end. | ||
132 | */ | ||
133 | static void mips_mt_cpu_irq_ack(unsigned int irq) | ||
134 | { | ||
135 | unsigned int vpflags = dvpe(); | ||
136 | clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); | ||
137 | evpe(vpflags); | ||
138 | mask_mips_mt_irq(irq); | ||
139 | } | ||
140 | |||
141 | #define mips_mt_cpu_irq_end mips_cpu_irq_end | ||
142 | |||
143 | static hw_irq_controller mips_mt_cpu_irq_controller = { | ||
144 | .typename = "MIPS", | ||
145 | .startup = mips_mt_cpu_irq_startup, | ||
146 | .shutdown = mips_mt_cpu_irq_shutdown, | ||
147 | .enable = mips_mt_cpu_irq_enable, | ||
148 | .disable = mips_mt_cpu_irq_disable, | ||
149 | .ack = mips_mt_cpu_irq_ack, | ||
150 | .end = mips_mt_cpu_irq_end, | ||
151 | }; | ||
109 | 152 | ||
110 | void __init mips_cpu_irq_init(int irq_base) | 153 | void __init mips_cpu_irq_init(int irq_base) |
111 | { | 154 | { |
@@ -115,7 +158,19 @@ void __init mips_cpu_irq_init(int irq_base) | |||
115 | clear_c0_status(ST0_IM); | 158 | clear_c0_status(ST0_IM); |
116 | clear_c0_cause(CAUSEF_IP); | 159 | clear_c0_cause(CAUSEF_IP); |
117 | 160 | ||
118 | for (i = irq_base; i < irq_base + 8; i++) { | 161 | /* |
162 | * Only MT is using the software interrupts currently, so we just | ||
163 | * leave them uninitialized for other processors. | ||
164 | */ | ||
165 | if (cpu_has_mipsmt) | ||
166 | for (i = irq_base; i < irq_base + 2; i++) { | ||
167 | irq_desc[i].status = IRQ_DISABLED; | ||
168 | irq_desc[i].action = NULL; | ||
169 | irq_desc[i].depth = 1; | ||
170 | irq_desc[i].handler = &mips_mt_cpu_irq_controller; | ||
171 | } | ||
172 | |||
173 | for (i = irq_base + 2; i < irq_base + 8; i++) { | ||
119 | irq_desc[i].status = IRQ_DISABLED; | 174 | irq_desc[i].status = IRQ_DISABLED; |
120 | irq_desc[i].action = NULL; | 175 | irq_desc[i].action = NULL; |
121 | irq_desc[i].depth = 1; | 176 | irq_desc[i].depth = 1; |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 519b8f18eedf..876aff71cd2e 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1186,8 +1186,14 @@ void __init per_cpu_trap_init(void) | |||
1186 | /* Setting vector spacing enables EI/VI mode */ | 1186 | /* Setting vector spacing enables EI/VI mode */ |
1187 | change_c0_intctl (0x3e0, VECTORSPACING); | 1187 | change_c0_intctl (0x3e0, VECTORSPACING); |
1188 | } | 1188 | } |
1189 | if (cpu_has_divec) | 1189 | if (cpu_has_divec) { |
1190 | set_c0_cause(CAUSEF_IV); | 1190 | if (cpu_has_mipsmt) { |
1191 | unsigned int vpflags = dvpe(); | ||
1192 | set_c0_cause(CAUSEF_IV); | ||
1193 | evpe(vpflags); | ||
1194 | } else | ||
1195 | set_c0_cause(CAUSEF_IV); | ||
1196 | } | ||
1191 | 1197 | ||
1192 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; | 1198 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; |
1193 | TLBMISS_HANDLER_SETUP(); | 1199 | TLBMISS_HANDLER_SETUP(); |