mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
arm64/smmu: Only MSI poll when cache-coherent
Only use the MSI polling method when we support MSIs and the SMMU is cache-coherent. The SMMU writes to a memory location. If it is not cache-coherent then the CPU may read the existing value in its cache and miss the signal the sync operation has completed. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D59489
This commit is contained in:
1 parent
0689a5ea45
commit
50e01b6351
3 files changed
+14
-4
No files matched your search
@@ -623,20 +623,23 @@ smmu_sync(struct smmu_softc *sc)
|
||||
struct smmu_cmdq_entry cmd;
|
||||
struct smmu_queue *q;
|
||||
int prod;
|
||||
bool msipoll;
|
||||
|
||||
q = &sc->cmdq;
|
||||
prod = q->lc.prod;
|
||||
|
||||
msipoll = ((sc->options & SMMU_OPT_MSIPOLL) != 0);
|
||||
|
||||
/* Enqueue sync command. */
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.opcode = CMD_SYNC;
|
||||
if ((sc->features & SMMU_FEATURE_MSI) != 0) {
|
||||
if (msipoll) {
|
||||
cmd.sync.msiaddr = q->paddr +
|
||||
Q_IDX(q, prod) * CMDQ_ENTRY_DWORDS * 8;
|
||||
}
|
||||
smmu_cmdq_enqueue_cmd(sc, &cmd);
|
||||
|
||||
if ((sc->features & SMMU_FEATURE_MSI) != 0)
|
||||
if (msipoll)
|
||||
smmu_sync_wait_msi(sc, q);
|
||||
else
|
||||
smmu_sync_wait_poll(sc, q);
|
||||
@@ -1356,8 +1359,6 @@ smmu_check_features(struct smmu_softc *sc)
|
||||
uint32_t reg;
|
||||
uint32_t val;
|
||||
|
||||
sc->features = 0;
|
||||
|
||||
reg = bus_read_4(sc->res[0], SMMU_IDR0);
|
||||
|
||||
if (reg & IDR0_ST_LVL_2) {
|
||||
@@ -1404,6 +1405,9 @@ smmu_check_features(struct smmu_softc *sc)
|
||||
if (bootverbose)
|
||||
device_printf(sc->dev, "MSI feature present.\n");
|
||||
sc->features |= SMMU_FEATURE_MSI;
|
||||
/* Support polling if we support MSI & are cache-coherent */
|
||||
if ((sc->features & SMMU_FEATURE_COHERENCY) != 0)
|
||||
sc->options |= SMMU_OPT_MSIPOLL;
|
||||
}
|
||||
|
||||
if (reg & IDR0_HYP) {
|
||||
|
||||
@@ -87,6 +87,8 @@ smmu_fdt_attach(device_t dev)
|
||||
sc->dev = dev;
|
||||
|
||||
node = ofw_bus_get_node(dev);
|
||||
if (OF_hasprop(node, "dma-coherent"))
|
||||
sc->features |= SMMU_FEATURE_COHERENCY;
|
||||
|
||||
rid = 0;
|
||||
sc->res[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
||||
|
||||
@@ -160,6 +160,10 @@ struct smmu_softc {
|
||||
#define SMMU_FEATURE_VAX (1 << 13)
|
||||
#define SMMU_FEATURE_COHERENCY (1 << 14)
|
||||
#define SMMU_FEATURE_RANGE_INV (1 << 15)
|
||||
|
||||
uint32_t options;
|
||||
#define SMMU_OPT_MSIPOLL (1 << 0)
|
||||
|
||||
struct smmu_queue cmdq;
|
||||
struct smmu_queue evtq;
|
||||
struct smmu_queue priq;
|
||||
|
||||
Reference in new issue
Block a user