From c50a818a88dd255298c1e4acb1f478e5c7da8441 Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 21 Oct 2021 18:30:57 +0000 Subject: [PATCH] Have ampintcmsi(4) go through the list of interrupt controllers to find the correct parent. So far we were directly calling some ampintc(4) code, which is fine for regular hardware. With Parallels on the Apple M1, ampintcmsi(4) is combined with agintc(4), which is quite a surprise. Luckily both types of interrupt controllers use the same API for passing interrupt information, so we can craft one structure and both ampintc(4) and agintc(4) will happily work with it. ok kettenis@ --- sys/arch/arm64/dev/ampintc.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sys/arch/arm64/dev/ampintc.c b/sys/arch/arm64/dev/ampintc.c index 98779c4da85..15f6ee276c2 100644 --- a/sys/arch/arm64/dev/ampintc.c +++ b/sys/arch/arm64/dev/ampintc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ampintc.c,v 1.23 2021/07/03 10:21:38 kettenis Exp $ */ +/* $OpenBSD: ampintc.c,v 1.24 2021/10/21 18:30:57 patrick Exp $ */ /* * Copyright (c) 2007,2009,2011 Dale Rahn * @@ -860,6 +860,7 @@ struct ampintc_msi_softc { struct device sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; + int sc_node; paddr_t sc_addr; int sc_bspi; int sc_nspi; @@ -890,6 +891,7 @@ ampintc_msi_attach(struct device *parent, struct device *self, void *aux) struct fdt_attach_args *faa = aux; uint32_t typer; + sc->sc_node = faa->fa_node; sc->sc_iot = faa->fa_iot; if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, faa->fa_reg[0].size, 0, &sc->sc_ioh)) @@ -928,21 +930,40 @@ ampintc_intr_establish_msi(void *self, uint64_t *addr, uint64_t *data, int level, struct cpu_info *ci, int (*func)(void *), void *arg, char *name) { struct ampintc_msi_softc *sc = (struct ampintc_msi_softc *)self; + extern LIST_HEAD(, interrupt_controller) interrupt_controllers; + struct interrupt_controller *ic; + struct machine_intr_handle *ih; void *cookie; + int cells[3]; int i; + LIST_FOREACH(ic, &interrupt_controllers, ic_list) { + if (ic->ic_node == OF_parent(sc->sc_node)) + break; + } + if (ic == NULL) + return NULL; + + cells[0] = 0; /* SPI */ + cells[2] = 1; /* Edge-Rising */ + for (i = 0; i < sc->sc_nspi; i++) { if (sc->sc_spi[i] != NULL) continue; - cookie = ampintc_intr_establish(sc->sc_bspi + i, - IST_EDGE_RISING, level, ci, func, arg, name); + cells[1] = sc->sc_bspi + i - 32; + cookie = ic->ic_establish(ic->ic_cookie, cells, + level, ci, func, arg, name); if (cookie == NULL) return NULL; + ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK); + ih->ih_ic = ic; + ih->ih_ih = cookie; + *addr = sc->sc_addr + GICV2M_SETSPI_NS; *data = sc->sc_bspi + i; - sc->sc_spi[i] = cookie; + sc->sc_spi[i] = ih; return &sc->sc_spi[i]; } @@ -952,7 +973,7 @@ ampintc_intr_establish_msi(void *self, uint64_t *addr, uint64_t *data, void ampintc_intr_disestablish_msi(void *cookie) { - ampintc_intr_disestablish(*(void **)cookie); + fdt_intr_disestablish(*(void **)cookie); *(void **)cookie = NULL; } -- 2.20.1