Thanks for the comments, responses inline.

On 31 October 2014 06:56, Peter Maydell <peter.mayd...@linaro.org> wrote:

> On 30 October 2014 21:28, Greg Bellows <greg.bell...@linaro.org> wrote:
> > Adds a dedicated function and a lookup table for determining the target
> > exception level of IRQ and FIQ exceptions.  The lookup table is taken
> from the
> > ARMv7 and ARMv8 specification exception routing tables.
> >
> > Signed-off-by: Greg Bellows <greg.bell...@linaro.org>
> >
> > ---
> >
> > v7 -> v8
> > - Added target EL lookup table
> > - Rework arm_phys_excp_target_el to use an EL lookup table rather than
> >   conditionals.
> >
> > v5 -> v6
> > - Removed unneeded arm_phys_excp_target_el() function prototype.
> > - Removed unneeded arm_phys_excp_target_el() USER_ONLY function.
> > - Fixed up arm_phys_excp_target_el() function definition to be static.
> > - Globally replace Aarch# with AArch#
> >
> > v4 -> v5
> > - Simplify target EL function including removal of mode which was unused
> > - Merged with patch that plugs in the use of the function
> >
> > v3 -> v4
> > - Fixed arm_phys_excp_target_el() 0/0/0 case to return excp_mode when
> EL<2
> >   rather than ABORT.
> > ---
> >  target-arm/helper.c | 111
> ++++++++++++++++++++++++++++++++++++++++++----------
> >  1 file changed, 91 insertions(+), 20 deletions(-)
> >
> > diff --git a/target-arm/helper.c b/target-arm/helper.c
> > index c47487a..e610466 100644
> > --- a/target-arm/helper.c
> > +++ b/target-arm/helper.c
> > @@ -3761,6 +3761,94 @@ void switch_mode(CPUARMState *env, int mode)
> >      env->spsr = env->banked_spsr[i];
> >  }
> >
> > +/* Physical Interrupt Target EL Lookup Table
> > + *
> > + * [ From ARM ARM section G1.13.4 (Table G1-15) ]
> > + *
> > + * The below multi-dimensional table is used for looking up the target
> > + * exception level given numerous condition criteria.  Specifically, the
> > + * target EL is based on SCR and HCR routing controls as well as the
> > + * currently executing EL and secure state.
> > + *
> > + *    Dimensions:
> > + *    target_el_table[2][2][2][2][2][4]
> > + *                    |  |  |  |  |  +--- Current EL
> > + *                    |  |  |  |  +------ Non-secure(0)/Secure(1)
> > + *                    |  |  |  +--------- HCR mask override
> > + *                    |  |  +------------ SCR exec state control
> > + *                    |  +--------------- SCR mask override
> > + *                    +------------------ 32-bit(0)/64-bit(1) EL3
> > + *
> > + *    The table values are as such:
> > + *    0-3 = EL0-EL3
> > + *     -1 = Cannot occur
> > + *
> > + * In the case of exceptions not being taken, EL1 is returned.  These
> cases
> > + * will be caught by the checks for target being >= current.
>
> This could use rephrasing to make it clearer why returning 1 is ok:
>
> "The ARM ARM tables include some entries indicating 'exception not taken'.
> These are for the cases where we are currently at EL3 and the
> exception is not routed to EL3 by the SCR, or where we are currently
> at EL2 and the exception is not routed to EL3 or EL2. We can therefore
> put '1' in those entries in our array, and rely on the check for
> "target EL >= current EL" in the caller to ensure that the exception
> is not taken."
>
>
Added to v9.


> > + *
> > + *            SCR     HCR
> > + *         64  EA     AMO                 From
> > + *        BIT IRQ     IMO      Non-secure         Secure
> > + *        EL3 FIQ  RW FMO   EL0 EL1 EL2 EL3   EL0 EL1 EL2 EL3
> > + */
> > +const int8_t target_el_table[2][2][2][2][2][4] = {
> > +    {{{{/* 0   0   0   0 */{ 1,  1,  2, -1 },{ 3,  3, -1,  3 },},
> > +       {/* 0   0   0   1 */{ 2,  2,  2, -1 },{ 3,  3, -1,  3 },},},
> > +      {{/* 0   0   1   0 */{ 1,  1,  2, -1 },{ 3,  3, -1,  3 },},
> > +       {/* 0   0   1   1 */{ 2,  2,  2, -1 },{ 3,  3, -1,  3 },},},},
> > +     {{{/* 0   1   0   0 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},
> > +       {/* 0   1   0   1 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},},
> > +      {{/* 0   1   1   0 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},
> > +       {/* 0   1   1   1 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},},},},
>
> Your entries for 32-bit EL3, exception from Secure EL1 should all
> read "-1", not "3" -- it's not possible to have current_el be 1
> in this case (this is why table G1-15 has a "-" in those entries).
>
>
Hmmm... I copied directly from the table and remember having two columns of
-1, so I'm not sure where the 3s came from, but you are right.  Fixed in v9.


> > +    {{{{/* 1   0   0   0 */{ 1,  1,  2, -1 },{ 1,  1, -1,  1 },},
> > +       {/* 1   0   0   1 */{ 2,  2,  2, -1 },{ 1,  1, -1,  1 },},},
> > +      {{/* 1   0   1   0 */{ 1,  1,  1, -1 },{ 1,  1, -1,  1 },},
> > +       {/* 1   0   1   1 */{ 2,  2,  2, -1 },{ 1,  1, -1,  1 },},},},
> > +     {{{/* 1   1   0   0 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},
> > +       {/* 1   1   0   1 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},},
> > +      {{/* 1   1   1   0 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},
> > +       {/* 1   1   1   1 */{ 3,  3,  3, -1 },{ 3,  3, -1,  3 },},},},},
> > +};
> > +
> > +/*
> > + * Determine the target EL for physical exceptions
> > + */
> > +static inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t
> excp_idx,
> > +                                        uint32_t cur_el, bool secure)
> > +{
> > +    CPUARMState *env = cs->env_ptr;
> > +    uint32_t rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
> > +    uint32_t scr;
> > +    uint32_t hcr;
> > +    uint32_t target_el;
> > +    uint32_t is64 = arm_el_is_aa64(env, 3);
>
> You can just make these all "int".
>

Fixed in v9.


>
> > +
> > +    switch (excp_idx) {
> > +    case EXCP_IRQ:
> > +        scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
> > +        hcr = ((env->cp15.hcr_el2 & HCR_IMO) == HCR_IMO);
> > +        break;
> > +    case EXCP_FIQ:
> > +        scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
> > +        hcr = ((env->cp15.hcr_el2 & HCR_FMO) == HCR_FMO);
> > +        break;
> > +    default:
> > +        scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
> > +        hcr = ((env->cp15.hcr_el2 & HCR_AMO) == HCR_AMO);
> > +        break;
> > +    };
> > +
> > +    /* If HCR.TGE is set then HCR is treated as being 1 */
> > +    hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE);
> > +
> > +    /* Perform a table-lookup for the target EL given the current state
> */
> > +    target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
> > +
> > +    assert(target_el > 0);
> > +
> > +    return target_el;
> > +}
> > +
> >  /*
> >   * Determine the target EL for a given exception type.
> >   */
> > @@ -3769,14 +3857,8 @@ unsigned int arm_excp_target_el(CPUState *cs,
> unsigned int excp_idx)
> >      ARMCPU *cpu = ARM_CPU(cs);
> >      CPUARMState *env = &cpu->env;
> >      unsigned int cur_el = arm_current_el(env);
> > -    unsigned int target_el;
> > -    /* FIXME: Use actual secure state.  */
> > -    bool secure = false;
> > -
> > -    if (!env->aarch64) {
> > -        /* TODO: Add EL2 and 3 exception handling for AArch32.  */
> > -        return 1;
> > -    }
> > +    unsigned int target_el = 1;
>
> Do you actually need to initialize this?
>

I think this was leftover from before, not needed now.  Fixed in v9.


>
> > +    bool secure = arm_is_secure(env);
> >
> >      switch (excp_idx) {
> >      case EXCP_HVC:
> > @@ -3788,19 +3870,8 @@ unsigned int arm_excp_target_el(CPUState *cs,
> unsigned int excp_idx)
> >          break;
> >      case EXCP_FIQ:
> >      case EXCP_IRQ:
> > -    {
> > -        const uint64_t hcr_mask = excp_idx == EXCP_FIQ ? HCR_FMO :
> HCR_IMO;
> > -        const uint32_t scr_mask = excp_idx == EXCP_FIQ ? SCR_FIQ :
> SCR_IRQ;
> > -
> > -        target_el = 1;
> > -        if (!secure && (env->cp15.hcr_el2 & hcr_mask)) {
> > -            target_el = 2;
> > -        }
> > -        if (env->cp15.scr_el3 & scr_mask) {
> > -            target_el = 3;
> > -        }
> > +        target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el,
> secure);
> >          break;
> > -    }
> >      case EXCP_VIRQ:
> >      case EXCP_VFIQ:
> >          target_el = 1;
> > --
> > 1.8.3.2
> >
>
> Thanks for adding the table-driven code: I found this much easier
> to review against the ARM ARM. If you make those minor changes I
> mention above then you can add my reviewed-by tag.
>
> -- PMM
>

Reply via email to