-/* $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 <drahn@dalerahn.com>
* Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
#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
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;
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);
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,