From: patrick Date: Sun, 23 Jun 2024 21:58:34 +0000 (+0000) Subject: While Qualcomm Snapdragon X Elite (X1E80100) claims to support 32 device-id X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=2679ff7fc59fbe0363d63a59398ec0a48376e068;p=openbsd While Qualcomm Snapdragon X Elite (X1E80100) claims to support 32 device-id bits, it only seems to allow a 4k pagesize with 8 bytes per entry. This is not enough to handle all 32 device-id bits, but we also don't necessarily need to handle all of them. Hence clamp down the number of maximum device IDs to as much as we can possibly configure in hardware. ok kettenis@ --- diff --git a/sys/arch/arm64/dev/agintc.c b/sys/arch/arm64/dev/agintc.c index e0fe1de31fb..79da7f4da7e 100644 --- a/sys/arch/arm64/dev/agintc.c +++ b/sys/arch/arm64/dev/agintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agintc.c,v 1.57 2024/06/19 22:10:45 patrick Exp $ */ +/* $OpenBSD: agintc.c,v 1.58 2024/06/23 21:58:34 patrick Exp $ */ /* * Copyright (c) 2007, 2009, 2011, 2017 Dale Rahn * Copyright (c) 2018 Mark Kettenis @@ -1516,6 +1516,7 @@ agintc_send_ipi(struct cpu_info *ci, int id) #define GITS_BASER_PGSZ_4K (0ULL << 8) #define GITS_BASER_PGSZ_16K (1ULL << 8) #define GITS_BASER_PGSZ_64K (2ULL << 8) +#define GITS_BASER_SZ_MASK (0xffULL) #define GITS_BASER_PA_MASK 0x7ffffffff000ULL #define GITS_TRANSLATER 0x10040 @@ -1572,6 +1573,7 @@ struct agintc_msi_softc { uint16_t sc_cmdidx; int sc_devbits; + uint32_t sc_deviceid_max; struct agintc_dmamem *sc_dtt; size_t sc_dtt_pgsz; uint8_t sc_dte_sz; @@ -1703,6 +1705,13 @@ agintc_msi_attach(struct device *parent, struct device *self, void *aux) size = (1ULL << sc->sc_devbits) * sc->sc_dte_sz; size = roundup(size, sc->sc_dtt_pgsz); + /* Clamp down to maximum configurable num pages */ + if (size / sc->sc_dtt_pgsz > GITS_BASER_SZ_MASK + 1) + size = (GITS_BASER_SZ_MASK + 1) * sc->sc_dtt_pgsz; + + /* Calculate max deviceid based off configured size */ + sc->sc_deviceid_max = (size / sc->sc_dte_sz) - 1; + /* Allocate table. */ sc->sc_dtt = agintc_dmamem_alloc(sc->sc_dmat, size, sc->sc_dtt_pgsz); @@ -1858,6 +1867,9 @@ agintc_msi_create_device(struct agintc_msi_softc *sc, uint32_t deviceid) struct agintc_msi_device *md; struct gits_cmd cmd; + if (deviceid > sc->sc_deviceid_max) + return NULL; + md = malloc(sizeof(*md), M_DEVBUF, M_ZERO | M_WAITOK); md->md_deviceid = deviceid; md->md_itt = agintc_dmamem_alloc(sc->sc_dmat,