Skip to content

Commit

Permalink
target/arm: Implement M-profile "minimal RAS implementation"
Browse files Browse the repository at this point in the history
For v8.1M the architecture mandates that CPUs must provide at
least the "minimal RAS implementation" from the Reliability,
Availability and Serviceability extension. This consists of:
 * an ESB instruction which is a NOP
   -- since it is in the HINT space we need only add a comment
 * an RFSR register which will RAZ/WI
 * a RAZ/WI AIRCR.IESB bit
   -- the code which handles writes to AIRCR does not allow setting
      of RES0 bits, so we already treat this as RAZ/WI; add a comment
      noting that this is deliberate
 * minimal implementation of the RAS register block at 0xe0005000
   -- this will be in a subsequent commit
 * setting the ID_PFR0.RAS field to 0b0010
   -- we will do this when we add the Cortex-M55 CPU model

Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Message-id: [email protected]
  • Loading branch information
pm215 committed Dec 10, 2020
1 parent 194cde6 commit 46f4976
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
13 changes: 13 additions & 0 deletions hw/intc/armv7m_nvic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
return 0;
}
return cpu->env.v7m.sfar;
case 0xf04: /* RFSR */
if (!cpu_isar_feature(aa32_ras, cpu)) {
goto bad_offset;
}
/* We provide minimal-RAS only: RFSR is RAZ/WI */
return 0;
case 0xf34: /* FPCCR */
if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
return 0;
Expand Down Expand Up @@ -1611,6 +1617,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
R_V7M_AIRCR_PRIGROUP_SHIFT,
R_V7M_AIRCR_PRIGROUP_LENGTH);
}
/* AIRCR.IESB is RAZ/WI because we implement only minimal RAS */
if (attrs.secure) {
/* These bits are only writable by secure */
cpu->env.v7m.aircr = value &
Expand Down Expand Up @@ -2026,6 +2033,12 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
}
break;
}
case 0xf04: /* RFSR */
if (!cpu_isar_feature(aa32_ras, cpu)) {
goto bad_offset;
}
/* We provide minimal-RAS only: RFSR is RAZ/WI */
break;
case 0xf34: /* FPCCR */
if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
/* Not all bits here are banked. */
Expand Down
14 changes: 14 additions & 0 deletions target/arm/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,15 @@ FIELD(ID_MMFR4, LSM, 20, 4)
FIELD(ID_MMFR4, CCIDX, 24, 4)
FIELD(ID_MMFR4, EVT, 28, 4)

FIELD(ID_PFR0, STATE0, 0, 4)
FIELD(ID_PFR0, STATE1, 4, 4)
FIELD(ID_PFR0, STATE2, 8, 4)
FIELD(ID_PFR0, STATE3, 12, 4)
FIELD(ID_PFR0, CSV2, 16, 4)
FIELD(ID_PFR0, AMU, 20, 4)
FIELD(ID_PFR0, DIT, 24, 4)
FIELD(ID_PFR0, RAS, 28, 4)

FIELD(ID_PFR1, PROGMOD, 0, 4)
FIELD(ID_PFR1, SECURITY, 4, 4)
FIELD(ID_PFR1, MPROGMOD, 8, 4)
Expand Down Expand Up @@ -3573,6 +3582,11 @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
}

static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
}

static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
Expand Down
4 changes: 4 additions & 0 deletions target/arm/t32.decode
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
# SEV 1111 0011 1010 1111 1000 0000 0000 0100
# SEVL 1111 0011 1010 1111 1000 0000 0000 0101

# For M-profile minimal-RAS ESB can be a NOP, which is the
# default behaviour since it is in the hint space.
# ESB 1111 0011 1010 1111 1000 0000 0001 0000

# The canonical nop ends in 0000 0000, but the whole rest
# of the space is "reserved hint, behaves as nop".
NOP 1111 0011 1010 1111 1000 0000 ---- ----
Expand Down

0 comments on commit 46f4976

Please sign in to comment.