qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: "Laurent Desnogues" <laurent.desnogues@gmail.com>,
	"Patch Tracking" <patches@linaro.org>,
	"Michael Matz" <matz@suse.de>,
	"qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org>,
	"Claudio Fontana" <claudio.fontana@linaro.org>,
	"Dirk Mueller" <dmueller@suse.de>,
	"Will Newton" <will.newton@linaro.org>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"kvmarm@lists.cs.columbia.edu" <kvmarm@lists.cs.columbia.edu>,
	"Christoffer Dall" <christoffer.dall@linaro.org>,
	"Richard Henderson" <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH 11/21] target-arm: Update generic cpreg code for AArch64
Date: Fri, 20 Dec 2013 14:25:23 +1000	[thread overview]
Message-ID: <CAEgOgz4zADAeFDLvHRACRAJ9n1Us6hKVftyLzLACGF9eF0aiLQ@mail.gmail.com> (raw)
In-Reply-To: <1387293144-11554-12-git-send-email-peter.maydell@linaro.org>

On Wed, Dec 18, 2013 at 1:12 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> Update the generic cpreg support code to also handle AArch64:
> AArch64-visible registers coexist in the same hash table with
> AArch32-visible ones, with a bit in the hash key distinguishing
> them.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.h        | 59 ++++++++++++++++++++++++++++++++++++++-----
>  target-arm/helper.c     | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  target-arm/kvm-consts.h | 37 +++++++++++++++++++++++++++
>  3 files changed, 155 insertions(+), 7 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 56ed591..901f882 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -572,18 +572,43 @@ void armv7m_nvic_complete_irq(void *opaque, int irq);
>   *    or via MRRC/MCRR?)
>   * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
>   * (In this case crn and opc2 should be zero.)
> + * For AArch64, there is no 32/64 bit size distinction;
> + * instead all registers have a 2 bit op0, 3 bit op1 and op2,
> + * and 4 bit CRn and CRm. The encoding patterns are chosen
> + * to be easy to convert to and from the KVM encodings, and also
> + * so that the hashtable can contain both AArch32 and AArch64
> + * registers (to allow for interprocessing where we might run
> + * 32 bit code on a 64 bit core).
>   */
> +/* This bit is private to our hashtable cpreg; in KVM register
> + * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
> + * in the upper bits of the 64 bit ID.
> + */
> +#define CP_REG_AA64_SHIFT 28
> +#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
> +
>  #define ENCODE_CP_REG(cp, is64, crn, crm, opc1, opc2)   \
>      (((cp) << 16) | ((is64) << 15) | ((crn) << 11) |    \
>       ((crm) << 7) | ((opc1) << 3) | (opc2))
>
> +#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
> +    (CP_REG_AA64_MASK |                                 \
> +     ((cp) << CP_REG_ARM_COPROC_SHIFT) |                \
> +     ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) |         \
> +     ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) |         \
> +     ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) |         \
> +     ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) |         \
> +     ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
> +
>  /* Convert a full 64 bit KVM register ID to the truncated 32 bit
>   * version used as a key for the coprocessor register hashtable
>   */
>  static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
>  {
>      uint32_t cpregid = kvmid;
> -    if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
> +    if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
> +        cpregid |= CP_REG_AA64_MASK;
> +    } else if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
>          cpregid |= (1 << 15);
>      }
>      return cpregid;
> @@ -594,11 +619,18 @@ static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
>   */
>  static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
>  {
> -    uint64_t kvmid = cpregid & ~(1 << 15);
> -    if (cpregid & (1 << 15)) {
> -        kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
> +    uint64_t kvmid;
> +
> +    if (cpregid & CP_REG_AA64_MASK) {
> +        kvmid = cpregid & ~CP_REG_AA64_MASK;
> +        kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
>      } else {
> -        kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
> +        kvmid = cpregid & ~(1 << 15);
> +        if (cpregid & (1 << 15)) {
> +            kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
> +        } else {
> +            kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
> +        }
>      }
>      return kvmid;
>  }
> @@ -626,13 +658,14 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
>  #define ARM_CP_OVERRIDE 16
>  #define ARM_CP_NO_MIGRATE 32
>  #define ARM_CP_IO 64
> +#define ARM_CP_AA64 128
>  #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
>  #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
>  #define ARM_LAST_SPECIAL ARM_CP_WFI
>  /* Used only as a terminator for ARMCPRegInfo lists */
>  #define ARM_CP_SENTINEL 0xffff
>  /* Mask of only the flag bits in a type field */
> -#define ARM_CP_FLAG_MASK 0x7f
> +#define ARM_CP_FLAG_MASK 0xff
>
>  /* Return true if cptype is a valid type field. This is used to try to
>   * catch errors where the sentinel has been accidentally left off the end
> @@ -655,6 +688,8 @@ static inline bool cptype_valid(int cptype)
>   * (ie anything visible in PL2 is visible in S-PL1, some things are only
>   * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
>   * terminology a little and call this PL3.
> + * In AArch64 things are somewhat simpler as the PLx bits line up exactly
> + * with the ELx exception levels.
>   *
>   * If access permissions for a register are more complex than can be
>   * described with these bits, then use a laxer set of restrictions, and
> @@ -676,6 +711,10 @@ static inline bool cptype_valid(int cptype)
>
>  static inline int arm_current_pl(CPUARMState *env)
>  {
> +    if (env->aarch64) {
> +        return extract32(env->pstate, 2, 2);
> +    }
> +
>      if ((env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR) {
>          return 0;
>      }
> @@ -713,10 +752,18 @@ struct ARMCPRegInfo {
>       * then behave differently on read/write if necessary.
>       * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
>       * must both be zero.
> +     * For AArch64-visible registers, opc0 is also used.
> +     * Since there are no "coprocessors" in AArch64, cp is purely used as a
> +     * way to distinguish (for KVM's benefit) guest-visible system registers
> +     * from demuxed ones provided to preserve the "no side effects on
> +     * KVM register read/write from QEMU" semantics. cp==0x13 is guest
> +     * visible (to match KVM's encoding); cp==0 will be converted to
> +     * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
>       */
>      uint8_t cp;
>      uint8_t crn;
>      uint8_t crm;
> +    uint8_t opc0;
>      uint8_t opc1;
>      uint8_t opc2;
>      /* Register type: ARM_CP_* bits/values */
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 6ebd7dc..975a762 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -1951,6 +1951,11 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
>       * At least one of the original and the second definition should
>       * include ARM_CP_OVERRIDE in its type bits -- this is just a guard
>       * against accidental use.
> +     *
> +     * ARM_CP_AA64 is set in the type field to define a register to
> +     * be visible when in AArch64 state. In this case r->opc0 may also
> +     * be set, and the ARM_CP_64BIT flag must not be set. opc0 can't
> +     * be wildcarded.
>       */
>      int crm, opc1, opc2;
>      int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
> @@ -1961,6 +1966,53 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
>      int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
>      /* 64 bit registers have only CRm and Opc1 fields */
>      assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
> +    /* AArch64 regs are all 64 bit so the ARM_CP_64BIT flag is meaningless */
> +    assert((r->type & (ARM_CP_64BIT|ARM_CP_AA64))
> +           != (ARM_CP_64BIT|ARM_CP_AA64));
> +    /* op0 only exists in the AArch64 encodings */
> +    assert((r->type & ARM_CP_AA64) || (r->opc0 == 0));
> +    /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
> +     * encodes a minimum access level for the register. We roll this
> +     * runtime check into our general permission check code, so check
> +     * here that the reginfo's specified permissions are strict enough
> +     * to encompass the generic architectural permission check.
> +     */
> +    if (r->type & ARM_CP_AA64) {
> +        int mask = 0;
> +        switch (r->opc1) {
> +        case 0: case 1: case 2:
> +            /* min_EL EL1 */
> +            mask = PL1_RW;
> +            break;
> +        case 3:
> +            /* min_EL EL0 */
> +            mask = PL0_RW;
> +            break;
> +        case 4:
> +            /* min_EL EL2 */
> +            mask = PL2_RW;
> +            break;
> +        case 5:
> +            /* unallocated encoding, so not possible */
> +            assert(false);
> +            break;
> +        case 6:
> +            /* min_EL EL3 */
> +            mask = PL3_RW;
> +            break;
> +        case 7:
> +            /* min_EL EL1, secure mode only (we don't check the latter) */
> +            mask = PL1_RW;
> +            break;
> +        default:
> +            /* broken reginfo with out of range opc1 */

"op1".

Regards,
Peter

  parent reply	other threads:[~2013-12-20  4:25 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-17 15:12 [Qemu-devel] [PATCH 00/21] target-arm: A64 decoder sets 3 and 4: everything but fp & simd Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 01/21] target-arm: A64: add support for ld/st pair Peter Maydell
2013-12-19 16:58   ` Richard Henderson
2013-12-19 17:25     ` Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 02/21] target-arm: A64: add support for ld/st unsigned imm Peter Maydell
2013-12-19 17:46   ` Richard Henderson
2013-12-20 16:08     ` Peter Maydell
2013-12-20 16:26       ` Richard Henderson
2013-12-20 16:29         ` Peter Maydell
2013-12-20 16:44           ` Richard Henderson
2013-12-20 16:52             ` Peter Maydell
2013-12-20 16:57               ` Richard Henderson
2013-12-20 17:16                 ` Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 03/21] target-arm: A64: add support for ld/st with reg offset Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 04/21] target-arm: A64: add support for ld/st with index Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 05/21] target-arm: A64: add support for add, addi, sub, subi Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 06/21] target-arm: A64: add support for move wide instructions Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 07/21] target-arm: A64: add support for 3 src data proc insns Peter Maydell
2013-12-19 19:29   ` Richard Henderson
2013-12-20 13:18     ` Peter Maydell
2013-12-20 14:10       ` Richard Henderson
2013-12-20 14:19         ` Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 08/21] target-arm: A64: implement SVC, BRK Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 09/21] target-arm: A64: Add decoder skeleton for FP instructions Peter Maydell
2013-12-19 20:00   ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 10/21] target-arm: A64: implement FMOV Peter Maydell
2013-12-19 20:18   ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 11/21] target-arm: Update generic cpreg code for AArch64 Peter Maydell
2013-12-19  6:01   ` Peter Crosthwaite
2013-12-19  9:11     ` Peter Maydell
2013-12-20  4:24       ` Peter Crosthwaite
2013-12-20 10:00         ` Peter Maydell
2013-12-20 18:16           ` Peter Maydell
2013-12-20 21:41             ` Peter Crosthwaite
2013-12-20 22:07               ` Peter Maydell
2013-12-20 22:16                 ` Peter Maydell
2013-12-22 19:50                   ` Peter Maydell
2013-12-20 22:29                 ` Peter Crosthwaite
2013-12-20 23:04                   ` Peter Maydell
2013-12-20 17:41         ` Peter Maydell
2013-12-20  4:25   ` Peter Crosthwaite [this message]
2013-12-20 16:43   ` Peter Maydell
2013-12-20 18:53     ` Christoffer Dall
2013-12-17 15:12 ` [Qemu-devel] [PATCH 12/21] target-arm: Remove ARMCPU/CPUARMState from cpregs APIs used by decoder Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 13/21] target-arm: A64: Implement MRS/MSR/SYS/SYSL Peter Maydell
2013-12-19 20:30   ` Richard Henderson
2013-12-20 13:27     ` Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 14/21] target-arm: A64: Implement minimal set of EL0-visible sysregs Peter Maydell
2013-12-19 20:35   ` Richard Henderson
2013-12-21 22:56   ` Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 15/21] target-arm: Widen thread-local register state fields to 64 bits Peter Maydell
2013-12-19 20:53   ` Richard Henderson
2013-12-19 21:04     ` Peter Maydell
2013-12-19 21:09       ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 16/21] target-arm: A64: add support for add/sub with carry Peter Maydell
2013-12-19 20:57   ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 17/21] target-arm: A64: add support for conditional compare insns Peter Maydell
2013-12-19 21:04   ` Richard Henderson
2013-12-19 21:23     ` Peter Maydell
2013-12-19 21:26       ` Richard Henderson
2013-12-19 21:31         ` Peter Maydell
2013-12-20 16:19     ` Peter Maydell
2013-12-20 16:22       ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 18/21] target-arm: aarch64: add support for ld lit Peter Maydell
2013-12-19 21:07   ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 19/21] target-arm: Widen exclusive-access support struct fields to 64 bits Peter Maydell
2013-12-17 15:12 ` [Qemu-devel] [PATCH 20/21] target-arm: A64: support for ld/st/cl exclusive Peter Maydell
2013-12-19 21:15   ` Richard Henderson
2013-12-17 15:12 ` [Qemu-devel] [PATCH 21/21] default-configs: Add config for aarch64-linux-user Peter Maydell
2013-12-19 21:15   ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAEgOgz4zADAeFDLvHRACRAJ9n1Us6hKVftyLzLACGF9eF0aiLQ@mail.gmail.com \
    --to=peter.crosthwaite@xilinx.com \
    --cc=alex.bennee@linaro.org \
    --cc=christoffer.dall@linaro.org \
    --cc=claudio.fontana@linaro.org \
    --cc=dmueller@suse.de \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=laurent.desnogues@gmail.com \
    --cc=matz@suse.de \
    --cc=patches@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=will.newton@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).