hw/intc/arm_gicv3: Update ID and feature registers for GICv4
Update the various GIC ID and feature registers for GICv4: * PIDR2 [7:4] is the GIC architecture revision * GICD_TYPER.DVIS is 1 to indicate direct vLPI injection support * GICR_TYPER.VLPIS is 1 to indicate redistributor support for vLPIs * GITS_TYPER.VIRTUAL is 1 to indicate vLPI support * GITS_TYPER.VMOVP is 1 to indicate that our VMOVP implementation handles cross-ITS synchronization for the guest * ICH_VTR_EL2.nV4 is 0 to indicate direct vLPI injection support Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220408141550.1271295-38-peter.maydell@linaro.org
This commit is contained in:
parent
1b19ccfa38
commit
e2d5e189aa
@ -406,8 +406,8 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
* Last == 1 if this is the last redistributor in a series of
|
||||
* contiguous redistributor pages
|
||||
* DirectLPI == 0 (direct injection of LPIs not supported)
|
||||
* VLPIS == 0 (virtual LPIs not supported)
|
||||
* PLPIS == 0 (physical LPIs not supported)
|
||||
* VLPIS == 1 if vLPIs supported (GICv4 and up)
|
||||
* PLPIS == 1 if LPIs supported
|
||||
*/
|
||||
cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
|
||||
|
||||
@ -422,6 +422,9 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
if (s->lpi_enable) {
|
||||
s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
|
||||
if (s->revision > 3) {
|
||||
s->cpu[i].gicr_typer |= GICR_TYPER_VLPIS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2578,11 +2578,15 @@ static uint64_t ich_vtr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
uint64_t value;
|
||||
|
||||
value = ((cs->num_list_regs - 1) << ICH_VTR_EL2_LISTREGS_SHIFT)
|
||||
| ICH_VTR_EL2_TDS | ICH_VTR_EL2_NV4 | ICH_VTR_EL2_A3V
|
||||
| ICH_VTR_EL2_TDS | ICH_VTR_EL2_A3V
|
||||
| (1 << ICH_VTR_EL2_IDBITS_SHIFT)
|
||||
| ((cs->vprebits - 1) << ICH_VTR_EL2_PREBITS_SHIFT)
|
||||
| ((cs->vpribits - 1) << ICH_VTR_EL2_PRIBITS_SHIFT);
|
||||
|
||||
if (cs->gic->revision < 4) {
|
||||
value |= ICH_VTR_EL2_NV4;
|
||||
}
|
||||
|
||||
trace_gicv3_ich_vtr_read(gicv3_redist_affid(cs), value);
|
||||
return value;
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
|
||||
* No1N == 1 (1-of-N SPI interrupts not supported)
|
||||
* A3V == 1 (non-zero values of Affinity level 3 supported)
|
||||
* IDbits == 0xf (we support 16-bit interrupt identifiers)
|
||||
* DVIS == 0 (Direct virtual LPI injection not supported)
|
||||
* DVIS == 1 (Direct virtual LPI injection supported) if GICv4
|
||||
* LPIS == 1 (LPIs are supported if affinity routing is enabled)
|
||||
* num_LPIs == 0b00000 (bits [15:11],Number of LPIs as indicated
|
||||
* by GICD_TYPER.IDbits)
|
||||
@ -399,8 +399,9 @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
|
||||
* so we only need to check the DS bit.
|
||||
*/
|
||||
bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
|
||||
bool dvis = s->revision >= 4;
|
||||
|
||||
*data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
|
||||
*data = (1 << 25) | (1 << 24) | (dvis << 18) | (sec_extn << 10) |
|
||||
(s->lpi_enable << GICD_TYPER_LPIS_SHIFT) |
|
||||
(0xf << 19) | itlinesnumber;
|
||||
return true;
|
||||
@ -557,7 +558,7 @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
|
||||
}
|
||||
case GICD_IDREGS ... GICD_IDREGS + 0x2f:
|
||||
/* ID registers */
|
||||
*data = gicv3_idreg(offset - GICD_IDREGS, GICV3_PIDR0_DIST);
|
||||
*data = gicv3_idreg(s, offset - GICD_IDREGS, GICV3_PIDR0_DIST);
|
||||
return true;
|
||||
case GICD_SGIR:
|
||||
/* WO registers, return unknown value */
|
||||
|
@ -1699,7 +1699,7 @@ static bool its_readl(GICv3ITSState *s, hwaddr offset,
|
||||
break;
|
||||
case GITS_IDREGS ... GITS_IDREGS + 0x2f:
|
||||
/* ID registers */
|
||||
*data = gicv3_idreg(offset - GITS_IDREGS, GICV3_PIDR0_ITS);
|
||||
*data = gicv3_idreg(s->gicv3, offset - GITS_IDREGS, GICV3_PIDR0_ITS);
|
||||
break;
|
||||
case GITS_TYPER:
|
||||
*data = extract64(s->typer, 0, 32);
|
||||
@ -1946,6 +1946,11 @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS);
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1);
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS);
|
||||
if (s->gicv3->revision >= 4) {
|
||||
/* Our VMOVP handles cross-ITS synchronization itself */
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, VMOVP, 1);
|
||||
s->typer = FIELD_DP64(s->typer, GITS_TYPER, VIRTUAL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void gicv3_its_reset(DeviceState *dev)
|
||||
|
@ -441,7 +441,7 @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
|
||||
*data = cs->gicr_nsacr;
|
||||
return MEMTX_OK;
|
||||
case GICR_IDREGS ... GICR_IDREGS + 0x2f:
|
||||
*data = gicv3_idreg(offset - GICR_IDREGS, GICV3_PIDR0_REDIST);
|
||||
*data = gicv3_idreg(cs->gic, offset - GICR_IDREGS, GICV3_PIDR0_REDIST);
|
||||
return MEMTX_OK;
|
||||
/*
|
||||
* VLPI frame registers. We don't need a version check for
|
||||
|
@ -309,6 +309,7 @@ FIELD(GITS_TYPER, SEIS, 18, 1)
|
||||
FIELD(GITS_TYPER, PTA, 19, 1)
|
||||
FIELD(GITS_TYPER, CIDBITS, 32, 4)
|
||||
FIELD(GITS_TYPER, CIL, 36, 1)
|
||||
FIELD(GITS_TYPER, VMOVP, 37, 1)
|
||||
|
||||
#define GITS_IDREGS 0xFFD0
|
||||
|
||||
@ -747,23 +748,29 @@ static inline uint32_t gicv3_iidr(void)
|
||||
#define GICV3_PIDR0_REDIST 0x93
|
||||
#define GICV3_PIDR0_ITS 0x94
|
||||
|
||||
static inline uint32_t gicv3_idreg(int regoffset, uint8_t pidr0)
|
||||
static inline uint32_t gicv3_idreg(GICv3State *s, int regoffset, uint8_t pidr0)
|
||||
{
|
||||
/* Return the value of the CoreSight ID register at the specified
|
||||
* offset from the first ID register (as found in the distributor
|
||||
* and redistributor register banks).
|
||||
* These values indicate an ARM implementation of a GICv3.
|
||||
* These values indicate an ARM implementation of a GICv3 or v4.
|
||||
*/
|
||||
static const uint8_t gicd_ids[] = {
|
||||
0x44, 0x00, 0x00, 0x00, 0x92, 0xB4, 0x3B, 0x00, 0x0D, 0xF0, 0x05, 0xB1
|
||||
0x44, 0x00, 0x00, 0x00, 0x92, 0xB4, 0x0B, 0x00, 0x0D, 0xF0, 0x05, 0xB1
|
||||
};
|
||||
uint32_t id;
|
||||
|
||||
regoffset /= 4;
|
||||
|
||||
if (regoffset == 4) {
|
||||
return pidr0;
|
||||
}
|
||||
return gicd_ids[regoffset];
|
||||
id = gicd_ids[regoffset];
|
||||
if (regoffset == 6) {
|
||||
/* PIDR2 bits [7:4] are the GIC architecture revision */
|
||||
id |= s->revision << 4;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user