qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 04/15] Openrisc: add interrupt support


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 04/15] Openrisc: add interrupt support
Date: Sat, 19 May 2012 07:30:27 +0000

On Thu, May 17, 2012 at 8:35 AM, Jia Liu <address@hidden> wrote:
> add the openrisc interrupt support.
>
> Signed-off-by: Jia Liu <address@hidden>
> ---
>  Makefile.target                |    2 +-
>  target-openrisc/helper.c       |   42 +++++++++++++++++++++++++++++++
>  target-openrisc/helper.h       |    3 +++
>  target-openrisc/intrp_helper.c |   53 
> ++++++++++++++++++++++++++++++++++++++++
>  target-openrisc/translate.c    |    2 +-
>  5 files changed, 100 insertions(+), 2 deletions(-)
>  create mode 100644 target-openrisc/intrp_helper.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 79c75f6..975c9a8 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -101,7 +101,7 @@ endif
>  libobj-$(TARGET_SPARC) += int32_helper.o
>  libobj-$(TARGET_SPARC64) += int64_helper.o
>  libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
> -libobj-$(TARGET_OPENRISC) += mem.o mem_helper.o
> +libobj-$(TARGET_OPENRISC) += intrp_helper.o mem.o mem_helper.o
>
>  libobj-y += disas.o
>  libobj-$(CONFIG_TCI_DIS) += tci-dis.o
> diff --git a/target-openrisc/helper.c b/target-openrisc/helper.c
> index dcb61c9..3aee996 100644
> --- a/target-openrisc/helper.c
> +++ b/target-openrisc/helper.c
> @@ -64,4 +64,46 @@ CPUOPENRISCState *cpu_openrisc_init(const char *cpu_model)
>
>  void do_interrupt(CPUOPENRISCState *env)

I'd put the function to intrp_helper.c too, or if you prefer, intrp.c
to match excp.c.

>  {
> +#if !defined(CONFIG_USER_ONLY)
> +    if (env->flags & D_FLAG) { /* Delay Slot insn */
> +        env->flags &= ~D_FLAG;
> +        env->sr |= SR_DSX;
> +        if (env->exception_index == EXCP_TICK    ||
> +            env->exception_index == EXCP_INT     ||
> +            env->exception_index == EXCP_SYSCALL ||
> +            env->exception_index == EXCP_FPE) {
> +            env->epcr = env->jmp_pc;
> +        } else {
> +            env->epcr = env->pc - 4;
> +        }
> +    } else {
> +        if (env->exception_index == EXCP_TICK    ||
> +            env->exception_index == EXCP_INT     ||
> +            env->exception_index == EXCP_SYSCALL ||
> +            env->exception_index == EXCP_FPE) {
> +            env->epcr = env->npc;
> +        } else {
> +            env->epcr = env->pc;
> +        }
> +    }
> +
> +    tlb_flush(env, 1);
> +
> +    env->esr = env->sr;
> +    env->sr &= ~SR_DME;
> +    env->sr &= ~SR_IME;
> +    env->sr |= SR_SM;
> +    env->sr &= ~SR_IEE;
> +    env->sr &= ~SR_TEE;
> +    env->map_address_data = &get_phys_nommu;
> +    env->map_address_code = &get_phys_nommu;
> +
> +    if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
> +        env->pc = env->exception_index * 0x100;

<< 8

> +    } else {
> +        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
> +    }
> +#endif
> +
> +    env->exception_index = -1;
>  }
> diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
> index 103d9b4..bb394ad 100644
> --- a/target-openrisc/helper.h
> +++ b/target-openrisc/helper.h
> @@ -20,4 +20,7 @@
>
>  #include "def-helper.h"
>
> +/* interrupt */
> +DEF_HELPER_FLAGS_1(rfe, 0, void, env)
> +
>  #include "def-helper.h"
> diff --git a/target-openrisc/intrp_helper.c b/target-openrisc/intrp_helper.c
> new file mode 100644
> index 0000000..c617068
> --- /dev/null
> +++ b/target-openrisc/intrp_helper.c
> @@ -0,0 +1,53 @@
> +/*
> + * OpenRISC interrupt helper routines
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *                          Feng Gao <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Library General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Library General Public License for more details.
> + *
> + * You should have received a copy of the GNU Library General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 
> USA
> + */
> +
> +#include "cpu.h"
> +#include "helper.h"
> +
> +void HELPER(rfe)(CPUOPENRISCState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    int need_flush_tlb = (env->sr & (SR_SM | SR_IME | SR_DME)) ^
> +                         (env->esr & (SR_SM | SR_IME | SR_DME));

If SR_SM is like supervisor mode flag, changes in it shouldn't cause
TLB flushes if you put it also to TB flags. The same is also true to
other flags but MMU enable/disable flags are commonly handled like
this.

> +#endif
> +    env->pc = env->epcr;
> +    env->npc = env->epcr;

+ 4?

> +    env->sr = env->esr;
> +
> +#if !defined(CONFIG_USER_ONLY)
> +    if (env->sr & SR_DME) {
> +        env->map_address_data = &get_phys_data;
> +    } else {
> +        env->map_address_data = &get_phys_nommu;
> +    }
> +
> +    if (env->sr & SR_IME) {
> +        env->map_address_code = &get_phys_code;
> +    } else {
> +        env->map_address_code = &get_phys_nommu;
> +    }
> +
> +    if (need_flush_tlb) {
> +        tlb_flush(env, 1);
> +    }
> +#endif
> +    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
> +}
> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
> index 4828ae6..dd0240c 100644
> --- a/target-openrisc/translate.c
> +++ b/target-openrisc/translate.c
> @@ -569,7 +569,7 @@ static void dec_misc(DisasContext *dc, CPUOPENRISCState 
> *env, uint32_t insn)
>     case 0x09:    /*l.rfe*/
>         LOG_DIS("l.rfe\n");
>         {
> -            /* rfe need a helper here */
> +            gen_helper_rfe(cpu_env);
>             dc->is_jmp = DISAS_UPDATE;
>         }
>         break;
> --
> 1.7.9.5
>
>



reply via email to

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