Revision d0dfae6e hw/ppc.c
b/hw/ppc.c | ||
---|---|---|
161 | 161 |
env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6); |
162 | 162 |
} |
163 | 163 |
|
164 |
/* PowerPC 970 internal IRQ controller */ |
|
165 |
static void ppc970_set_irq (void *opaque, int pin, int level) |
|
166 |
{ |
|
167 |
CPUState *env = opaque; |
|
168 |
int cur_level; |
|
169 |
|
|
170 |
#if defined(PPC_DEBUG_IRQ) |
|
171 |
if (loglevel & CPU_LOG_INT) { |
|
172 |
fprintf(logfile, "%s: env %p pin %d level %d\n", __func__, |
|
173 |
env, pin, level); |
|
174 |
} |
|
175 |
#endif |
|
176 |
cur_level = (env->irq_input_state >> pin) & 1; |
|
177 |
/* Don't generate spurious events */ |
|
178 |
if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { |
|
179 |
switch (pin) { |
|
180 |
case PPC970_INPUT_INT: |
|
181 |
/* Level sensitive - active high */ |
|
182 |
#if defined(PPC_DEBUG_IRQ) |
|
183 |
if (loglevel & CPU_LOG_INT) { |
|
184 |
fprintf(logfile, "%s: set the external IRQ state to %d\n", |
|
185 |
__func__, level); |
|
186 |
} |
|
187 |
#endif |
|
188 |
ppc_set_irq(env, PPC_INTERRUPT_EXT, level); |
|
189 |
break; |
|
190 |
case PPC970_INPUT_THINT: |
|
191 |
/* Level sensitive - active high */ |
|
192 |
#if defined(PPC_DEBUG_IRQ) |
|
193 |
if (loglevel & CPU_LOG_INT) { |
|
194 |
fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__, |
|
195 |
level); |
|
196 |
} |
|
197 |
#endif |
|
198 |
ppc_set_irq(env, PPC_INTERRUPT_THERM, level); |
|
199 |
break; |
|
200 |
case PPC970_INPUT_MCP: |
|
201 |
/* Negative edge sensitive */ |
|
202 |
/* XXX: TODO: actual reaction may depends on HID0 status |
|
203 |
* 603/604/740/750: check HID0[EMCP] |
|
204 |
*/ |
|
205 |
if (cur_level == 1 && level == 0) { |
|
206 |
#if defined(PPC_DEBUG_IRQ) |
|
207 |
if (loglevel & CPU_LOG_INT) { |
|
208 |
fprintf(logfile, "%s: raise machine check state\n", |
|
209 |
__func__); |
|
210 |
} |
|
211 |
#endif |
|
212 |
ppc_set_irq(env, PPC_INTERRUPT_MCK, 1); |
|
213 |
} |
|
214 |
break; |
|
215 |
case PPC970_INPUT_CKSTP: |
|
216 |
/* Level sensitive - active low */ |
|
217 |
/* XXX: TODO: relay the signal to CKSTP_OUT pin */ |
|
218 |
if (level) { |
|
219 |
#if defined(PPC_DEBUG_IRQ) |
|
220 |
if (loglevel & CPU_LOG_INT) { |
|
221 |
fprintf(logfile, "%s: stop the CPU\n", __func__); |
|
222 |
} |
|
223 |
#endif |
|
224 |
env->halted = 1; |
|
225 |
} else { |
|
226 |
#if defined(PPC_DEBUG_IRQ) |
|
227 |
if (loglevel & CPU_LOG_INT) { |
|
228 |
fprintf(logfile, "%s: restart the CPU\n", __func__); |
|
229 |
} |
|
230 |
#endif |
|
231 |
env->halted = 0; |
|
232 |
} |
|
233 |
break; |
|
234 |
case PPC970_INPUT_HRESET: |
|
235 |
/* Level sensitive - active low */ |
|
236 |
if (level) { |
|
237 |
#if 0 // XXX: TOFIX |
|
238 |
#if defined(PPC_DEBUG_IRQ) |
|
239 |
if (loglevel & CPU_LOG_INT) { |
|
240 |
fprintf(logfile, "%s: reset the CPU\n", __func__); |
|
241 |
} |
|
242 |
#endif |
|
243 |
cpu_reset(env); |
|
244 |
#endif |
|
245 |
} |
|
246 |
break; |
|
247 |
case PPC970_INPUT_SRESET: |
|
248 |
#if defined(PPC_DEBUG_IRQ) |
|
249 |
if (loglevel & CPU_LOG_INT) { |
|
250 |
fprintf(logfile, "%s: set the RESET IRQ state to %d\n", |
|
251 |
__func__, level); |
|
252 |
} |
|
253 |
#endif |
|
254 |
ppc_set_irq(env, PPC_INTERRUPT_RESET, level); |
|
255 |
break; |
|
256 |
case PPC970_INPUT_TBEN: |
|
257 |
#if defined(PPC_DEBUG_IRQ) |
|
258 |
if (loglevel & CPU_LOG_INT) { |
|
259 |
fprintf(logfile, "%s: set the TBEN state to %d\n", __func__, |
|
260 |
level); |
|
261 |
} |
|
262 |
#endif |
|
263 |
/* XXX: TODO */ |
|
264 |
break; |
|
265 |
default: |
|
266 |
/* Unknown pin - do nothing */ |
|
267 |
#if defined(PPC_DEBUG_IRQ) |
|
268 |
if (loglevel & CPU_LOG_INT) { |
|
269 |
fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin); |
|
270 |
} |
|
271 |
#endif |
|
272 |
return; |
|
273 |
} |
|
274 |
if (level) |
|
275 |
env->irq_input_state |= 1 << pin; |
|
276 |
else |
|
277 |
env->irq_input_state &= ~(1 << pin); |
|
278 |
} |
|
279 |
} |
|
280 |
|
|
281 |
void ppc970_irq_init (CPUState *env) |
|
282 |
{ |
|
283 |
env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env, 7); |
|
284 |
} |
|
285 |
|
|
164 | 286 |
/* PowerPC 405 internal IRQ controller */ |
165 | 287 |
static void ppc405_set_irq (void *opaque, int pin, int level) |
166 | 288 |
{ |
Also available in: Unified diff