From: kettenis Date: Mon, 7 Mar 2022 11:08:13 +0000 (+0000) Subject: Since AIC2 uses 4 interrupt cells we need to adjust the code that handles X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=96995178995b64d725e67ef6d11c4e420254a45a;p=openbsd Since AIC2 uses 4 interrupt cells we need to adjust the code that handles the "msi-ranges" property and converts it into a proper interrupt descriptor for MSIs. ok jsg@ --- diff --git a/sys/arch/arm64/dev/aplpcie.c b/sys/arch/arm64/dev/aplpcie.c index e64ba3ccb9a..e2d6cc773b7 100644 --- a/sys/arch/arm64/dev/aplpcie.c +++ b/sys/arch/arm64/dev/aplpcie.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aplpcie.c,v 1.11 2022/02/13 12:02:21 kettenis Exp $ */ +/* $OpenBSD: aplpcie.c,v 1.12 2022/03/07 11:08:13 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis * @@ -127,7 +127,8 @@ struct aplpcie_softc { int sc_msi; bus_addr_t sc_msi_doorbell; - uint32_t sc_msi_range[5]; + uint32_t sc_msi_range[6]; + int sc_msi_rangelen; struct interrupt_controller sc_msi_ic; }; @@ -229,8 +230,12 @@ aplpcie_attach(struct device *parent, struct device *self, void *aux) sc->sc_msi_doorbell = OF_getpropint64(sc->sc_node, "msi-doorbell", 0xffff000ULL); - if (OF_getpropintarray(sc->sc_node, "msi-ranges", sc->sc_msi_range, - sizeof(sc->sc_msi_range)) != sizeof(sc->sc_msi_range)) { + sc->sc_msi_rangelen = OF_getpropintarray(sc->sc_node, "msi-ranges", + sc->sc_msi_range, sizeof(sc->sc_msi_range)); + if (sc->sc_msi_rangelen <= 0 || + (sc->sc_msi_rangelen % sizeof(uint32_t)) || + (sc->sc_msi_rangelen / sizeof(uint32_t)) < 5 || + (sc->sc_msi_rangelen / sizeof(uint32_t) > 6)) { printf(": invalid msi-ranges property\n"); return; } @@ -665,17 +670,18 @@ aplpcie_intr_establish_msi(void *cookie, uint64_t *addr, uint64_t *data, int level, struct cpu_info *ci, int (*func)(void *), void *arg, char *name) { struct aplpcie_softc *sc = cookie; - uint32_t cells[3]; + uint32_t cells[4]; + int ncells; - if (sc->sc_msi >= sc->sc_msi_range[4]) + ncells = sc->sc_msi_rangelen / sizeof(uint32_t); + if (sc->sc_msi >= sc->sc_msi_range[ncells - 1]) return NULL; *addr = sc->sc_msi_doorbell; *data = sc->sc_msi++; - cells[0] = sc->sc_msi_range[1]; - cells[1] = sc->sc_msi_range[2] + *data; - cells[2] = sc->sc_msi_range[3]; + memcpy(cells, &sc->sc_msi_range[1], sizeof(cells)); + cells[ncells - 4] += *data; return fdt_intr_parent_establish(&sc->sc_msi_ic, cells, level, ci, func, arg, name);