qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 08/15] Openrisc: add programmable interrupt cont


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 08/15] Openrisc: add programmable interrupt controller support
Date: Sat, 19 May 2012 08:33:39 +0000

On Thu, May 17, 2012 at 8:35 AM, Jia Liu <address@hidden> wrote:
> add the openrisc programmable interrupt controller support.
>
> Signed-off-by: Jia Liu <address@hidden>
> ---
>  cpu-exec.c        |   17 +++++++++++++++++
>  hw/openrisc_pic.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 65 insertions(+)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index ba10db1..845b2ae 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -375,6 +375,23 @@ int cpu_exec(CPUArchState *env)
>                         do_interrupt(env);
>                         next_tb = 0;
>                     }
> +#elif defined(TARGET_OPENRISC)
> +                    {
> +                        int idx = -1;
> +                        if ((interrupt_request & CPU_INTERRUPT_HARD)
> +                            && (env->sr & SR_IEE)) {
> +                            idx = EXCP_INT;
> +                        }
> +                        if ((interrupt_request & CPU_INTERRUPT_TIMER)
> +                            && (env->sr & SR_TEE)) {
> +                            idx = EXCP_TICK;
> +                        }
> +                        if (idx >= 0) {
> +                            env->exception_index = idx;
> +                            do_interrupt(env);
> +                            next_tb = 0;
> +                        }
> +                    }
>  #elif defined(TARGET_SPARC)
>                     if (interrupt_request & CPU_INTERRUPT_HARD) {
>                         if (cpu_interrupts_enabled(env) &&
> diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c
> index 0abdd50..52e48ec 100644
> --- a/hw/openrisc_pic.c
> +++ b/hw/openrisc_pic.c
> @@ -29,3 +29,51 @@ void cpu_openrisc_pic_reset(CPUOPENRISCState *env)
>     env->picmr = 0x00000000;
>     env->picsr = 0x00000000;
>  }
> +
> +/* openrisc pic handler */
> +static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
> +{
> +    CPUOPENRISCState *env = (CPUOPENRISCState *)opaque;
> +    int i;
> +    uint32_t irq_bit = 1 << irq;
> +
> +    if (irq > 31 || irq < 0) {
> +        return;
> +    }
> +
> +    if (level) {
> +        env->picsr |= irq_bit;
> +    } else {
> +        env->picsr &= ~irq_bit;
> +    }
> +
> +    for (i = 0; i < 32; i++) {
> +        if ((env->picsr && (1 << i)) && (env->picmr && (1 << i))) {
> +            cpu_interrupt(env, CPU_INTERRUPT_HARD);

The CPU could have one IRQ line input (set up at board or CPU level),
which the device toggles. That way the PIC does not need to be coupled
so tightly with the CPU (no need to access CPUState).

> +        } else {
> +            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
> +            env->picsr &= ~(1 << i);
> +        }
> +    }
> +}
> +
> +void cpu_openrisc_pic_init(CPUOPENRISCState *env)
> +{
> +    int i;
> +    qemu_irq *qi;
> +    qi = qemu_allocate_irqs(openrisc_pic_cpu_handler, env, NR_IRQS);
> +
> +    for (i = 0; i < NR_IRQS; i++) {
> +        env->irq[i] = qi[i];
> +    }
> +}
> +
> +void cpu_openrisc_store_picmr(CPUOPENRISCState *env, uint32_t value)
> +{
> +    env->picmr |= value;
> +}
> +
> +void cpu_openrisc_store_picsr(CPUOPENRISCState *env, uint32_t value)
> +{
> +    env->picsr &= ~value;
> +}
> --
> 1.7.9.5
>
>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]