• Mark Rutland's avatar
    arm64: Add sysreg header generation scripting · 66847e06
    Mark Rutland authored
    The arm64 kernel requires some metadata for each system register it may
    need to access. Currently we have:
    
    * A SYS_<regname> definition which sorresponds to a sys_reg() macro.
      This is used both to look up a sysreg by encoding (e.g. in KVM), and
      also to generate code to access a sysreg where the assembler is
      unaware of the specific sysreg encoding.
    
      Where assemblers support the S3_<op1>_C<crn>_C<crm>_<op2> syntax for
      system registers, we could use this rather than manually assembling
      the instructions. However, we don't have consistent definitions for
      these and we currently still need to handle toolchains that lack this
      feature.
    
    * A set of <regname>_<fieldname>_SHIFT and <regname>_<fieldname>_MASK
      definitions, which can be used to extract fields from the register, or
      to construct a register from a set of fields.
    
      These do not follow the convention used by <linux/bitfield.h>, and the
      masks are not shifted into place, preventing their use in FIELD_PREP()
      and FIELD_GET(). We require the SHIFT definitions for inline assembly
      (and WIDTH definitions would be helpful for UBFX/SBFX), so we cannot
      only define a shifted MASK. Defining a SHIFT, WIDTH, shifted MASK and
      unshifted MASK is tedious and error-prone and life is much easier when
      they can be relied up to exist when writing code.
    
    * A set of <regname>_<fieldname>_<valname> definitions for each
      enumerated value a field may hold. These are used when identifying the
      presence of features.
    
    Atop of this, other code has to build up metadata at runtime (e.g. the
    sets of RES0/RES1 bits in a register).
    
    This patch adds scripting so that we can have an easier-to-manage
    canonical representation of this metadata, from which we can generate
    all the definitions necessary for various use-cases, e.g.
    
    | #define REG_ID_AA64ISAR0_EL1                    S3_0_C0_C6_0
    | #define SYS_ID_AA64ISAR0_EL1                    sys_reg(3, 0, 0, 6, 0)
    | #define SYS_ID_AA64ISAR0_EL1_Op0                3
    | #define SYS_ID_AA64ISAR0_EL1_Op1                0
    | #define SYS_ID_AA64ISAR0_EL1_CRn                0
    | #define SYS_ID_AA64ISAR0_EL1_CRm                6
    | #define SYS_ID_AA64ISAR0_EL1_Op2                0
    
    | #define ID_AA64ISAR0_EL1_RNDR                   GENMASK(63, 60)
    | #define ID_AA64ISAR0_EL1_RNDR_MASK              GENMASK(63, 60)
    | #define ID_AA64ISAR0_EL1_RNDR_SHIFT             60
    | #define ID_AA64ISAR0_EL1_RNDR_WIDTH             4
    | #define ID_AA64ISAR0_EL1_RNDR_NI                UL(0b0000)
    | #define ID_AA64ISAR0_EL1_RNDR_IMP               UL(0b0001)
    
    The script requires that all bits in the register be specified and that
    there be no overlapping fields. This helps the script spot errors in the
    input but means that the few registers which change layout at runtime
    depending on things like virtualisation settings will need some manual
    handling. No actual register conversions are done here but a header for
    the register data with some documention of the format is provided.
    
    For cases where multiple registers share a layout (eg, when identical
    controls are provided at multiple ELs) the register fields can be
    defined once and referenced from the actual registers, currently we do
    not generate actual defines for the individual registers.
    
    At the moment this is only intended to express metadata from the
    architecture, and does not handle policy imposed by the kernel, such as
    values exposed to userspace or VMs. In future this could be extended to
    express such information.
    
    This script was mostly written by Mark Rutland but has been extended by
    Mark Brown to improve validation of input and better integrate with the
    kernel.
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Co-Developed-by: default avatarMark Brown <broonie@kernel.org>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    Link: https://lore.kernel.org/r/20220503170233.507788-9-broonie@kernel.orgSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    66847e06
sysreg 1.07 KB