Commit 9fdc60bf55fc291d734735ddfb5629f8e8ced32b

Authored by aurel32
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
hw/ppc.c
... ... @@ -314,6 +314,66 @@ void ppc40x_irq_init (CPUState *env)
314 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 378 /* PowerPC time base and decrementer emulation */
319 379 struct ppc_tb_t {
... ...
hw/ppc.h
... ... @@ -31,6 +31,7 @@ extern CPUReadMemoryFunc *PPC_io_read[];
31 31 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
32 32  
33 33 void ppc40x_irq_init (CPUState *env);
  34 +void ppce500_irq_init (CPUState *env);
34 35 void ppc6xx_irq_init (CPUState *env);
35 36 void ppc970_irq_init (CPUState *env);
36 37  
... ...
target-ppc/cpu.h
... ... @@ -1356,6 +1356,16 @@ enum {
1356 1356 };
1357 1357  
1358 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 1369 /* PowerPC 40x input pins */
1360 1370 PPC40x_INPUT_RESET_CORE = 0,
1361 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 63 PPC_IRQ_INIT_FN(40x);
64 64 PPC_IRQ_INIT_FN(6xx);
65 65 PPC_IRQ_INIT_FN(970);
  66 +PPC_IRQ_INIT_FN(e500);
66 67  
67 68 /* Generic callbacks:
68 69 * do nothing but store/retrieve spr value
... ... @@ -4198,7 +4199,6 @@ static void init_proc_e300 (CPUPPCState *env)
4198 4199 #define check_pow_e500v2 check_pow_hid0
4199 4200 #define init_proc_e500v2 init_proc_e500
4200 4201  
4201   -__attribute__ (( unused ))
4202 4202 static void init_proc_e500 (CPUPPCState *env)
4203 4203 {
4204 4204 /* Time base */
... ... @@ -4300,7 +4300,8 @@ static void init_proc_e500 (CPUPPCState *env)
4300 4300 init_excp_e200(env);
4301 4301 env->dcache_line_size = 32;
4302 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 4307 /* Non-embedded PowerPC */
... ...