Commit 9fdc60bf55fc291d734735ddfb5629f8e8ced32b
1 parent
74c62ba8
kvm/powerpc: Add irq support for E500 core
Signed-off-by: Liu Yu <yu.liu@freescale.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6662 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
74 additions
and
2 deletions
hw/ppc.c
@@ -314,6 +314,66 @@ void ppc40x_irq_init (CPUState *env) | @@ -314,6 +314,66 @@ void ppc40x_irq_init (CPUState *env) | ||
314 | env, PPC40x_INPUT_NB); | 314 | env, PPC40x_INPUT_NB); |
315 | } | 315 | } |
316 | 316 | ||
317 | +/* PowerPC E500 internal IRQ controller */ | ||
318 | +static void ppce500_set_irq (void *opaque, int pin, int level) | ||
319 | +{ | ||
320 | + CPUState *env = opaque; | ||
321 | + int cur_level; | ||
322 | + | ||
323 | + LOG_IRQ("%s: env %p pin %d level %d\n", __func__, | ||
324 | + env, pin, level); | ||
325 | + cur_level = (env->irq_input_state >> pin) & 1; | ||
326 | + /* Don't generate spurious events */ | ||
327 | + if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { | ||
328 | + switch (pin) { | ||
329 | + case PPCE500_INPUT_MCK: | ||
330 | + if (level) { | ||
331 | + LOG_IRQ("%s: reset the PowerPC system\n", | ||
332 | + __func__); | ||
333 | + qemu_system_reset_request(); | ||
334 | + } | ||
335 | + break; | ||
336 | + case PPCE500_INPUT_RESET_CORE: | ||
337 | + if (level) { | ||
338 | + LOG_IRQ("%s: reset the PowerPC core\n", __func__); | ||
339 | + ppc_set_irq(env, PPC_INTERRUPT_MCK, level); | ||
340 | + } | ||
341 | + break; | ||
342 | + case PPCE500_INPUT_CINT: | ||
343 | + /* Level sensitive - active high */ | ||
344 | + LOG_IRQ("%s: set the critical IRQ state to %d\n", | ||
345 | + __func__, level); | ||
346 | + ppc_set_irq(env, PPC_INTERRUPT_CEXT, level); | ||
347 | + break; | ||
348 | + case PPCE500_INPUT_INT: | ||
349 | + /* Level sensitive - active high */ | ||
350 | + LOG_IRQ("%s: set the core IRQ state to %d\n", | ||
351 | + __func__, level); | ||
352 | + ppc_set_irq(env, PPC_INTERRUPT_EXT, level); | ||
353 | + break; | ||
354 | + case PPCE500_INPUT_DEBUG: | ||
355 | + /* Level sensitive - active high */ | ||
356 | + LOG_IRQ("%s: set the debug pin state to %d\n", | ||
357 | + __func__, level); | ||
358 | + ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level); | ||
359 | + break; | ||
360 | + default: | ||
361 | + /* Unknown pin - do nothing */ | ||
362 | + LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); | ||
363 | + return; | ||
364 | + } | ||
365 | + if (level) | ||
366 | + env->irq_input_state |= 1 << pin; | ||
367 | + else | ||
368 | + env->irq_input_state &= ~(1 << pin); | ||
369 | + } | ||
370 | +} | ||
371 | + | ||
372 | +void ppce500_irq_init (CPUState *env) | ||
373 | +{ | ||
374 | + env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq, | ||
375 | + env, PPCE500_INPUT_NB); | ||
376 | +} | ||
317 | /*****************************************************************************/ | 377 | /*****************************************************************************/ |
318 | /* PowerPC time base and decrementer emulation */ | 378 | /* PowerPC time base and decrementer emulation */ |
319 | struct ppc_tb_t { | 379 | struct ppc_tb_t { |
hw/ppc.h
@@ -31,6 +31,7 @@ extern CPUReadMemoryFunc *PPC_io_read[]; | @@ -31,6 +31,7 @@ extern CPUReadMemoryFunc *PPC_io_read[]; | ||
31 | void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val); | 31 | void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val); |
32 | 32 | ||
33 | void ppc40x_irq_init (CPUState *env); | 33 | void ppc40x_irq_init (CPUState *env); |
34 | +void ppce500_irq_init (CPUState *env); | ||
34 | void ppc6xx_irq_init (CPUState *env); | 35 | void ppc6xx_irq_init (CPUState *env); |
35 | void ppc970_irq_init (CPUState *env); | 36 | void ppc970_irq_init (CPUState *env); |
36 | 37 |
target-ppc/cpu.h
@@ -1356,6 +1356,16 @@ enum { | @@ -1356,6 +1356,16 @@ enum { | ||
1356 | }; | 1356 | }; |
1357 | 1357 | ||
1358 | enum { | 1358 | enum { |
1359 | + /* PowerPC E500 input pins */ | ||
1360 | + PPCE500_INPUT_RESET_CORE = 0, | ||
1361 | + PPCE500_INPUT_MCK = 1, | ||
1362 | + PPCE500_INPUT_CINT = 3, | ||
1363 | + PPCE500_INPUT_INT = 4, | ||
1364 | + PPCE500_INPUT_DEBUG = 6, | ||
1365 | + PPCE500_INPUT_NB, | ||
1366 | +}; | ||
1367 | + | ||
1368 | +enum { | ||
1359 | /* PowerPC 40x input pins */ | 1369 | /* PowerPC 40x input pins */ |
1360 | PPC40x_INPUT_RESET_CORE = 0, | 1370 | PPC40x_INPUT_RESET_CORE = 0, |
1361 | PPC40x_INPUT_RESET_CHIP = 1, | 1371 | PPC40x_INPUT_RESET_CHIP = 1, |
target-ppc/translate_init.c
@@ -63,6 +63,7 @@ void glue(glue(ppc, name),_irq_init) (CPUPPCState *env); | @@ -63,6 +63,7 @@ void glue(glue(ppc, name),_irq_init) (CPUPPCState *env); | ||
63 | PPC_IRQ_INIT_FN(40x); | 63 | PPC_IRQ_INIT_FN(40x); |
64 | PPC_IRQ_INIT_FN(6xx); | 64 | PPC_IRQ_INIT_FN(6xx); |
65 | PPC_IRQ_INIT_FN(970); | 65 | PPC_IRQ_INIT_FN(970); |
66 | +PPC_IRQ_INIT_FN(e500); | ||
66 | 67 | ||
67 | /* Generic callbacks: | 68 | /* Generic callbacks: |
68 | * do nothing but store/retrieve spr value | 69 | * do nothing but store/retrieve spr value |
@@ -4198,7 +4199,6 @@ static void init_proc_e300 (CPUPPCState *env) | @@ -4198,7 +4199,6 @@ static void init_proc_e300 (CPUPPCState *env) | ||
4198 | #define check_pow_e500v2 check_pow_hid0 | 4199 | #define check_pow_e500v2 check_pow_hid0 |
4199 | #define init_proc_e500v2 init_proc_e500 | 4200 | #define init_proc_e500v2 init_proc_e500 |
4200 | 4201 | ||
4201 | -__attribute__ (( unused )) | ||
4202 | static void init_proc_e500 (CPUPPCState *env) | 4202 | static void init_proc_e500 (CPUPPCState *env) |
4203 | { | 4203 | { |
4204 | /* Time base */ | 4204 | /* Time base */ |
@@ -4300,7 +4300,8 @@ static void init_proc_e500 (CPUPPCState *env) | @@ -4300,7 +4300,8 @@ static void init_proc_e500 (CPUPPCState *env) | ||
4300 | init_excp_e200(env); | 4300 | init_excp_e200(env); |
4301 | env->dcache_line_size = 32; | 4301 | env->dcache_line_size = 32; |
4302 | env->icache_line_size = 32; | 4302 | env->icache_line_size = 32; |
4303 | - /* XXX: TODO: allocate internal IRQ controller */ | 4303 | + /* Allocate hardware IRQ controller */ |
4304 | + ppce500_irq_init(env); | ||
4304 | } | 4305 | } |
4305 | 4306 | ||
4306 | /* Non-embedded PowerPC */ | 4307 | /* Non-embedded PowerPC */ |