From nobody Mon Jul 21 12:31:23 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bm0BM6ntlz62ZrN; Mon, 21 Jul 2025 12:31:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bm0BM415xz3w8Z; Mon, 21 Jul 2025 12:31:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753101083; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5BOzwEotixHm/0KpBuG1k1cgxbB4BHuPd9THpxF/4Qo=; b=lCOzaXyjNjod39BtlblKJ2SQDgvtH7S6axaA8svQcHT2tQShAwWFIyOdH3SIgObOCap5db Iz5XHxkqJHOaIOTAhdEXa7QhQh6zl89rii4JS6V+IOTNtPmJ+1pzfA6EDdrF2sOd0JhJPF rfQPri4LUIFwyLlknRqc8kdyJjpR2sktQ7TeNbLGbA6EdEPoCkMuoVSZMxrE2MbJ0q3Mta 3idS8JQlCCTUT3nJZsJSF89MEM+FIxz94wYxjzQKRpmWw9oOQGgK8btBvVcouq+cmkLzbk c7XhmMnpIxViT/tyNhFleAowhFkSptP5+UJx29Rgm9WZZlfu1BfFz8yi75FBvQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753101083; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5BOzwEotixHm/0KpBuG1k1cgxbB4BHuPd9THpxF/4Qo=; b=C6KI82tJwdLgHPgPd8kAlVAn/JFe/zJqQFQvQ3qhPMW7m8Ie6X9ZJzOsFGqymbcZySqaXz c+/8f5NV9Yq/m0T57hevkhyAIhTJXdbDbBbxSNRw0mNgvP1ocHgdHhYI30yisavcaUqMoU kMqaTiZmA4bMT+CmMYpwPy1uGXykwC4j+tmD0igtUyu9xxEj+ymEA/+g2pr2uMVSL7RnuK J6EQTFPyWp1hDIGGfmCBIDW8EvfvErCO3DBGNG1wfGPrypSvZG00YMQDkn6vcc/yj7c3t7 zI3mnYjnt/uMWpIipBOPvl9PC6x4Rok3Uirj6lUXeWt0X/ZSrFSU9S8ayIzbIw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1753101083; a=rsa-sha256; cv=none; b=ZmS/UAXj2TWFMb4bUULPyhnBH7o4Wfy4gUYBT4kC9mbfMOR+7WawvkurIagl8U2KAJaIil 0I60Wc5djPZZ/LKBLxtHUDZZ+VhnDdLlCL7751B2sOYJvUfuO5wSSsi+z8HYHQ4kQHP5Co SuGRW610QCYOgfhYe5rHvL3XdYH6uO8/ELqSgZIvsLxwWp521RfDgJ559CW/VAX76FBSN4 6YPPeL6eS8+YP/odNFHKIiFBStROq1h3rkYTQr7cevEJ12ETlHbuNlGJODxgjknDlAId7l GknF1Udjra9w1E3HHRi2ddlt2EOlfLFAGqHOGk/bJrAycjoV/jM2DXGNIAATfg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bm0BM3RPxzy0x; Mon, 21 Jul 2025 12:31:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 56LCVNgW079839; Mon, 21 Jul 2025 12:31:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 56LCVN56079836; Mon, 21 Jul 2025 12:31:23 GMT (envelope-from git) Date: Mon, 21 Jul 2025 12:31:23 GMT Message-Id: <202507211231.56LCVN56079836@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: 7fcdbfc9baf5 - main - dev/ofw: Add interrupt-map support List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7fcdbfc9baf5c5b6ba920df2b0afc1ce1ee4e58f Auto-Submitted: auto-generated The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=7fcdbfc9baf5c5b6ba920df2b0afc1ce1ee4e58f commit 7fcdbfc9baf5c5b6ba920df2b0afc1ce1ee4e58f Author: Andrew Turner AuthorDate: 2025-07-21 11:46:12 +0000 Commit: Andrew Turner CommitDate: 2025-07-21 12:07:14 +0000 dev/ofw: Add interrupt-map support Follow interrupt-map properties until either an interrupt controller or invalid node is found. In the former case return the translated details for the interrupt controller driver to decode. In the latter case return 0 as an error. Tested on the Arm DTS files that use interrupt-maps and with a userspace test. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D51257 --- sys/dev/ofw/ofw_bus_subr.c | 101 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 6 deletions(-) diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c index 4d0479dfb957..b99d784929bc 100644 --- a/sys/dev/ofw/ofw_bus_subr.c +++ b/sys/dev/ofw/ofw_bus_subr.c @@ -634,11 +634,89 @@ ofw_bus_find_iparent(phandle_t node) return (iparent); } +static phandle_t +ofw_bus_search_iparent(phandle_t node) +{ + phandle_t iparent; + + do { + if (OF_getencprop(node, "interrupt-parent", &iparent, + sizeof(iparent)) > 0) { + node = OF_node_from_xref(iparent); + } else { + node = OF_parent(node); + } + if (node == 0) + return (0); + } while (!OF_hasprop(node, "#interrupt-cells")); + + return (OF_xref_from_node(node)); +} + +static int +ofw_bus_traverse_imap(phandle_t inode, phandle_t node, uint32_t *intr, + int intrsz, pcell_t *res, int ressz, phandle_t *iparentp) +{ + struct ofw_bus_iinfo ii; + void *reg; + uint32_t *intrp; + phandle_t iparent; + int rv = 0; + + /* We already have an interrupt controller */ + if (OF_hasprop(node, "interrupt-controller")) + return (0); + + intrp = malloc(intrsz, M_OFWPROP, M_WAITOK); + memcpy(intrp, intr, intrsz); + + while (true) { + /* There is no interrupt-map to follow */ + if (!OF_hasprop(inode, "interrupt-map")) { + free(intrp, M_OFWPROP); + return (0); + } + + memset(&ii, 0, sizeof(ii)); + ofw_bus_setup_iinfo(inode, &ii, sizeof(cell_t)); + + reg = NULL; + if (ii.opi_addrc > 0) + reg = malloc(ii.opi_addrc, M_OFWPROP, M_WAITOK); + + rv = ofw_bus_lookup_imap(node, &ii, reg, ii.opi_addrc, intrp, + intrsz, res, ressz, &iparent); + + free(reg, M_OFWPROP); + free(ii.opi_imap, M_OFWPROP); + free(ii.opi_imapmsk, M_OFWPROP); + free(intrp, M_OFWPROP); + + if (rv == 0) + return (0); + + node = inode; + inode = OF_node_from_xref(iparent); + + /* Stop when we have an interrupt controller */ + if (OF_hasprop(inode, "interrupt-controller")) { + *iparentp = iparent; + return (rv); + } + + intrsz = rv * sizeof(pcell_t); + intrp = malloc(intrsz, M_OFWPROP, M_WAITOK); + memcpy(intrp, res, intrsz); + } +} + int ofw_bus_intr_to_rl(device_t dev, phandle_t node, struct resource_list *rl, int *rlen) { - phandle_t iparent; + phandle_t iparent, iparent_node; + uint32_t result[16]; + uint32_t intrpcells, *intrp; uint32_t icells, *intr; int err, i, irqnum, nintr, rid; bool extended; @@ -646,15 +724,16 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node, nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr), (void **)&intr); if (nintr > 0) { - iparent = ofw_bus_find_iparent(node); + iparent = ofw_bus_search_iparent(node); if (iparent == 0) { device_printf(dev, "No interrupt-parent found, " "assuming direct parent\n"); iparent = OF_parent(node); iparent = OF_xref_from_node(iparent); } - if (OF_searchencprop(OF_node_from_xref(iparent), - "#interrupt-cells", &icells, sizeof(icells)) == -1) { + iparent_node = OF_node_from_xref(iparent); + if (OF_searchencprop(iparent_node, "#interrupt-cells", &icells, + sizeof(icells)) == -1) { device_printf(dev, "Missing #interrupt-cells " "property, assuming <1>\n"); icells = 1; @@ -677,7 +756,8 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node, for (i = 0; i < nintr; i += icells) { if (extended) { iparent = intr[i++]; - if (OF_searchencprop(OF_node_from_xref(iparent), + iparent_node = OF_node_from_xref(iparent); + if (OF_searchencprop(iparent_node, "#interrupt-cells", &icells, sizeof(icells)) == -1) { device_printf(dev, "Missing #interrupt-cells " "property\n"); @@ -691,7 +771,16 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node, break; } } - irqnum = ofw_bus_map_intr(dev, iparent, icells, &intr[i]); + + intrp = &intr[i]; + intrpcells = ofw_bus_traverse_imap(iparent_node, node, intrp, + icells * sizeof(intr[0]), result, sizeof(result), &iparent); + if (intrpcells > 0) + intrp = result; + else + intrpcells = icells; + + irqnum = ofw_bus_map_intr(dev, iparent, intrpcells, intrp); resource_list_add(rl, SYS_RES_IRQ, rid++, irqnum, irqnum, 1); } if (rlen != NULL)