From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C80927FD64; Tue, 6 May 2025 12:24:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534245; cv=none; b=oJc/EcgBz5lf0RVISAT7cS/JT9mXJwvgI708BmmVmD2yss64SQmLd/tf/S8dHbOmVqM7hkSXsT0A6lMqNyAUJu7e/OU4P3vlMnBpauDFD1B9q+/9QjkZE2eTprA3z4+RQkPpKfif91ioVnYExRmAwSdXhWLeMA0i5njWninyTA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534245; c=relaxed/simple; bh=+ir0wgSpyLEltTxsgeyExf7czD5n9dwiKNdzfgzbSho=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OZVbXncE2n5invCihhPYww6COxPsysSD4bvrtVdvaMEuvaqP/ps+e/5EEQAVCNLK95Xv3xEEqmsMcKwyQQNnGkRNL0VV88nB52k1NzuSa3KWHg+PxEsbGsECcuhJcZcLCLHnZaXOCFVrCQdfc7G3edxGvSvkYsvbad39K18YffY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cKLZw+go; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cKLZw+go" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AF8ADC4CEED; Tue, 6 May 2025 12:24:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534244; bh=+ir0wgSpyLEltTxsgeyExf7czD5n9dwiKNdzfgzbSho=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cKLZw+gogY1SgXrmBE3tbNgqRvt55B+jasAmQ7bBAWP9e4vehmjWr3wfR6JBz86ro wasmzWNYPT4ybP9cp356+hLK6SGfzkmBse15vixgyUEIxoIRFN8H8o7lSsPcJeQ9u9 2A5d7jwuqwfQl1GyNlVqhfhwkHCAbXIl9UtmbgAJVmj9ZDzOermD8OqrYe9QMdbUhk Y7nERa34E2lbMRvmILmt1FDKyGLMg6B6SHgk6JcMhBofh7gHrtaxv00RRjrWuHFj2Q bZO44vnHP8P6HFsFcQypU/rHP9dEais+dL0ruMmim2u212Aln/GaXkRUMzu7Q2Wnfz 1ZZz7O8YjzsZA== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:30 +0200 Subject: [PATCH v3 01/25] dt-bindings: interrupt-controller: Add Arm GICv5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-1-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 The GICv5 interrupt controller architecture is composed of: - one or more Interrupt Routing Service (IRS) - zero or more Interrupt Translation Service (ITS) - zero or more Interrupt Wire Bridge (IWB) Describe a GICv5 implementation by specifying a top level node corresponding to the GICv5 system component. IRS nodes are added as GICv5 system component children. An ITS is associated with an IRS so ITS nodes are described as IRS children - use the hierarchy explicitly in the device tree to define the association. IWB nodes are described as a separate schema. An IWB is connected to a single ITS, the connection is made explicit through the msi-parent property and therefore is not required to be explicit through a parent-child relationship in the device tree. Signed-off-by: Lorenzo Pieralisi Cc: Conor Dooley Cc: Rob Herring Cc: Krzysztof Kozlowski Cc: Marc Zyngier --- .../interrupt-controller/arm,gic-v5-iwb.yaml | 76 ++++++++ .../bindings/interrupt-controller/arm,gic-v5.yaml | 196 +++++++++++++++++= ++++ MAINTAINERS | 7 + 3 files changed, 279 insertions(+) diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic= -v5-iwb.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,g= ic-v5-iwb.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b3eb89567b3457e91b93588d7db= 1cef69b6b9813 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5-iwb= .yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/arm,gic-v5-iwb.yam= l# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARM Generic Interrupt Controller, version 5 Interrupt Wire Bridge (= IWB) + +maintainers: + - Lorenzo Pieralisi + - Marc Zyngier + +description: | + The GICv5 architecture defines the guidelines to implement GICv5 + compliant interrupt controllers for AArch64 systems. + + The GICv5 specification can be found at + https://developer.arm.com/documentation/aes0070 + + GICv5 has zero or more Interrupt Wire Bridges (IWB) that are responsible + for translating wire signals into interrupt messages to the GICv5 ITS. + +allOf: + - $ref: /schemas/interrupt-controller.yaml# + +properties: + compatible: + const: arm,gic-v5-iwb + + interrupt-controller: true + + "#address-cells": + const: 0 + + "#interrupt-cells": + description: | + The 1st cell corresponds to the IWB wire. + + The 2nd cell is the flags, encoded as follows: + bits[3:0] trigger type and level flags. + + 1 =3D low-to-high edge triggered + 2 =3D high-to-low edge triggered + 4 =3D active high level-sensitive + 8 =3D active low level-sensitive + + const: 2 + + reg: + items: + - description: IWB control frame + + msi-parent: + maxItems: 1 + +required: + - compatible + - reg + - msi-parent + +additionalProperties: false + +examples: + - | + interrupt-controller@2f000000 { + compatible =3D "arm,gic-v5-iwb"; + #address-cells =3D <0>; + + interrupt-controller; + #interrupt-cells =3D <2>; + + reg =3D <0x2f000000 0x10000>; + + msi-parent =3D <&its0 64>; + }; +... diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic= -v5.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v= 5.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1ba0a2088e6d15bacae22c9fc9e= ebc4ce5c51b0b --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5.yaml @@ -0,0 +1,196 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/arm,gic-v5.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARM Generic Interrupt Controller, version 5 + +maintainers: + - Lorenzo Pieralisi + - Marc Zyngier + +description: | + The GICv5 architecture defines the guidelines to implement GICv5 + compliant interrupt controllers for AArch64 systems. + + The GICv5 specification can be found at + https://developer.arm.com/documentation/aes0070 + + The GICv5 architecture is composed of multiple components: + - one or more IRS (Interrupt Routing Service) + - zero or more ITS (Interrupt Translation Service) + + The architecture defines: + - PE-Private Peripheral Interrupts (PPI) + - Shared Peripheral Interrupts (SPI) + - Logical Peripheral Interrupts (LPI) + +allOf: + - $ref: /schemas/interrupt-controller.yaml# + +properties: + compatible: + const: arm,gic-v5 + + interrupt-controller: true + + "#address-cells": + enum: [ 1, 2 ] + + "#size-cells": + enum: [ 1, 2 ] + + ranges: true + + "#interrupt-cells": + description: | + The 1st cell corresponds to the INTID.Type field in the INTID; 1 for= PPI, + 3 for SPI. LPI interrupts must not be described in the bindings since + they are allocated dynamically by the software component managing th= em. + + The 2nd cell contains the interrupt INTID.ID field. + + The 3rd cell is the flags, encoded as follows: + bits[3:0] trigger type and level flags. + + 1 =3D low-to-high edge triggered + 2 =3D high-to-low edge triggered + 4 =3D active high level-sensitive + 8 =3D active low level-sensitive + + const: 3 + + interrupts: + description: + The VGIC maintenance interrupt. + maxItems: 1 + +required: + - compatible + +patternProperties: + "^irs@[0-9a-f]+$": + type: object + description: + GICv5 has one or more Interrupt Routing Services (IRS) that are + responsible for handling IRQ state and routing. + + additionalProperties: false + + properties: + compatible: + const: arm,gic-v5-irs + + "#address-cells": + enum: [ 1, 2 ] + + "#size-cells": + enum: [ 1, 2 ] + + ranges: true + + dma-noncoherent: + description: + Present if the GIC IRS permits programming shareability and + cacheability attributes but is connected to a non-coherent + downstream interconnect. + + reg: + minItems: 1 + items: + - description: IRS control frame + - description: IRS setlpi frame + + cpus: + description: + CPUs managed by the IRS. + + arm,iaffids: + $ref: /schemas/types.yaml#/definitions/uint16-array + description: + Interrupt AFFinity ID (IAFFID) associated with the CPU whose + CPU node phandle is at the same index in the cpus array. + + patternProperties: + "^msi-controller@[0-9a-f]+$": + type: object + description: + GICv5 has zero or more Interrupt Translation Services (ITS) that= are + used to route Message Signalled Interrupts (MSI) to the CPUs. Ea= ch + ITS is connected to an IRS. + additionalProperties: false + + properties: + compatible: + const: arm,gic-v5-its + + dma-noncoherent: + description: + Present if the GIC ITS permits programming shareability and + cacheability attributes but is connected to a non-coherent + downstream interconnect. + + msi-controller: true + + "#msi-cells": + description: + The single msi-cell is the DeviceID of the device which will + generate the MSI. + const: 1 + + reg: + items: + - description: ITS control frame + - description: ITS translate frame + + required: + - compatible + - msi-controller + - "#msi-cells" + - reg + + required: + - compatible + - reg + - cpus + - arm,iaffids + +additionalProperties: false + +examples: + - | + interrupt-controller { + compatible =3D "arm,gic-v5"; + #interrupt-cells =3D <3>; + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges; + + interrupt-controller; + + interrupts =3D <1 25 4>; + + irs@2f1a0000 { + compatible =3D "arm,gic-v5-irs"; + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges; + + reg =3D <0x2f1a0000 0x10000>; // IRS_CONFIG_FRAME for NS + + arm,iaffids =3D /bits/ 16 <0 1 2 3 4 5 6 7>; + cpus =3D <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>, <&cpu4>, <&cpu5>, <&c= pu6>, <&cpu7>; + + msi-controller@2f120000 { + compatible =3D "arm,gic-v5-its"; + + msi-controller; + #msi-cells =3D <1>; + + reg =3D <0x2f120000 0x10000 // ITS_CONFIG_FRAME for NS + 0x2f130000 0x10000>; // ITS_TRANSLATE_FRAME + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 96b82704950184bd71623ff41fc4df31e4c7fe87..1902291c3cccc06d27c5f79123e= 67774cf9a0e43 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1901,6 +1901,13 @@ F: drivers/irqchip/irq-gic*.[ch] F: include/linux/irqchip/arm-gic*.h F: include/linux/irqchip/arm-vgic-info.h =20 +ARM GENERIC INTERRUPT CONTROLLER V5 DRIVERS +M: Lorenzo Pieralisi +M: Marc Zyngier +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml + ARM HDLCD DRM DRIVER M: Liviu Dudau S: Supported --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D616280005; Tue, 6 May 2025 12:24:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534249; cv=none; b=S+q/8ul5SG4oi+KhpBup1uKC3/8nRZVu+Ufpab3mTOvkI1JhUjpe9h/4EMLEr/hC9RC5145kN2Aen2FOWiygOX/GVAJ7kRRL2t14vB2F9lQDVBOY7Y5CTmtgbOfSmO4D2yMsuuDnGcAvZRc+Sm5u2NG4SQ+5bHqOnVXr0qhjfa4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534249; c=relaxed/simple; bh=gXuthZuxBZQLsvBkFkEhlBn3G2hxd3VqLQiwIZeC8vM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M5bnshawnKN9OyJQfa2mjNXktqCCytH0wVpssFklQte9y3zQBnd4ar0KJcIrwdjNaZY2TUHuLL1RgmdazZ6VOuYDb3injQkz19eHFHwTu5/KcPt7aLDcYRiGaVq2twI5PMc67tSGrat77KlLJOLvC6lV6Y/EF8jGVsVp3SwhNt0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LIuiJrfZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LIuiJrfZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2053DC4CEE4; Tue, 6 May 2025 12:24:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534249; bh=gXuthZuxBZQLsvBkFkEhlBn3G2hxd3VqLQiwIZeC8vM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LIuiJrfZlpwYGShMeEz3c4uNe4TJvSX1MHc5TzTDqc4bIiSrdQwxwmPPkroUDklxi 8YTD/WpcL1LiD5yj993yR38P7Ngyj1lgpe1olPykvMs3wsnlr4i7F760V/fbUe3P7q YFdF89AHYk+CHDk1cQivQk5AgOncOvfHZzp69TxkeRDayDp/YtbUtMygGvEPFzXeYV irUhF++We6A9fVn2v+B8q5N/EPn5bvGTBfV/v+TpU6SXLocTfoO2xLjvn6mqgvo3AV rDu8y9oO76bJ5m3PRwO1ppEUZSr7pdGxCVz/R5nvZ9pBf3TH9Sqw3sby+mK1ivvAPm 6wnqlrQWpkKfQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:31 +0200 Subject: [PATCH v3 02/25] arm64/sysreg: Add GCIE field to ID_AA64PFR2_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-2-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add field reporting the GCIE feature to ID_AA64PFR2_EL1 sysreg. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index f9476848a2edfad53bb4af7f68bc05cb2a4af9ce..06e1fb5e126b41b7e41fffa0a00= 553d73197ac3c 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -1023,7 +1023,10 @@ UnsignedEnum 19:16 UINJ 0b0000 NI 0b0001 IMP EndEnum -Res0 15:12 +UnsignedEnum 15:12 GCIE + 0b0000 NI + 0b0001 IMP +EndEnum UnsignedEnum 11:8 MTEFAR 0b0000 NI 0b0001 IMP --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF7D528002B; Tue, 6 May 2025 12:24:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534254; cv=none; b=iu3KCTwnasI1qWo645Vjk6EdVpAQFxPY6v+NqtpwN92Sap/1tXpzx9PoyayuinXAFDaepUms7R6er7bvvfwtomcCWw6azjLahc9Z1ZJxRR5Bxzxkxjn7E/yULelDrqmXue9G5QYYSwSh6kEnymREiCW5B4JSRgSj0vZBPJqBoZo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534254; c=relaxed/simple; bh=TEy69hatB9WvAQZk1Qj5SRXNdR02N3m6osQeJAFrqRk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tLZC4ZoK+G7SmDycbuGW949BqdOso97r2p5cukuZPuStR00xOraoTD72nzF8x33GlXH9IfcU1U5zvElQjeUH9Ubhqkf1Up7yEQrDxOzE+SspCLfiDoxl/AdIcmdS9enYlKxQ3qK6UTdGSahO8YD7VxDrDzo50O8xtjIgVxreaTM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pP9mCQhJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pP9mCQhJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7B08BC4CEE4; Tue, 6 May 2025 12:24:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534253; bh=TEy69hatB9WvAQZk1Qj5SRXNdR02N3m6osQeJAFrqRk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pP9mCQhJlnmub9JIqm2vlrsuYyLARjeK5WZXkd0lACQUSKgl+l24d52bj3g6GExY4 uE+mGixk4ZDx3z0dD3m1BQuz1d+R/uoEhxyLLiMVxSz7UiQ7D722X9WajgtH2QUFkC aOfmY6Jgy0XMN1zX04T/wnsipioKHe91Djq4yawwcZmAqDCv98fyLAqJJcvemX5owy kXIqUwku0YWIr9kcNp0cgf/0i0/57m2UHr1xsEpHddrhr6vTDV/CIbmnAYqN7sitCS oB0CKkQM10JxVS+a/pB72D3tNZ4CmK24cPo8D2o0jJMJkd3RyReSP4bIwsvzPSQaX3 MikjQEyvuXumQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:32 +0200 Subject: [PATCH v3 03/25] arm64/sysreg: Add ICC_PPI_PRIORITY_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-3-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_PPI_PRIORITY_EL1 sysreg description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 83 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 06e1fb5e126b41b7e41fffa0a00553d73197ac3c..0cc1268c0bfad8266da47b441e8= 0c603e46c00ae 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2310,6 +2310,89 @@ Field 31 C Field 30:0 P EndSysreg =20 +SysregFields ICC_PPI_PRIORITYRx_EL1 +Res0 63:61 +Field 60:56 Priority7 +Res0 55:53 +Field 52:48 Priority6 +Res0 47:45 +Field 44:40 Priority5 +Res0 39:37 +Field 36:32 Priority4 +Res0 31:29 +Field 28:24 Priority3 +Res0 23:21 +Field 20:16 Priority2 +Res0 15:13 +Field 12:8 Priority1 +Res0 7:5 +Field 4:0 Priority0 +EndSysregFields + +Sysreg ICC_PPI_PRIORITYR0_EL1 3 0 12 14 0 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR1_EL1 3 0 12 14 1 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR2_EL1 3 0 12 14 2 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR3_EL1 3 0 12 14 3 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR4_EL1 3 0 12 14 4 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR5_EL1 3 0 12 14 5 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR6_EL1 3 0 12 14 6 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR7_EL1 3 0 12 14 7 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR8_EL1 3 0 12 15 0 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR9_EL1 3 0 12 15 1 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR10_EL1 3 0 12 15 2 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR11_EL1 3 0 12 15 3 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR12_EL1 3 0 12 15 4 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR13_EL1 3 0 12 15 5 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR14_EL1 3 0 12 15 6 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR15_EL1 3 0 12 15 7 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + Sysreg PMSELR_EL0 3 3 9 12 5 Res0 63:5 Field 4:0 SEL --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5057327F19F; Tue, 6 May 2025 12:24:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534259; cv=none; b=MpuD9rtzCajVV5KlZFfZL0qXrhnXr+eUlw/0pVFsxAFwaKWLFju46OsRkZpzxYBtphdN1S+SqTO8FTVvAqO7bMNY5OKJIiiDw9pKa17vYi4y936Tdmun/P9UpabpikJwm8+A+BReqjR1LQpP0Im4sPo5LibU3+hDN/aEYvkYK8U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534259; c=relaxed/simple; bh=Tv02OqEETUJL5RhGfHRLiUOkxm6hkdgtGZBz124yXQU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aY9UKC1fEayVIIC+xNt9RERLFwqD3grnS1kvbLLGoF7Waz+WVSy0XgbGCdNXbsZa9DJtpF/CDR1J4tZAZPHKUX4y5D45cVyi30E7s4BrI0osQwPMYyzUo8yarCT/1er0K+hyTzEpUALeNcB9U8Zym86yNDo5ugylrIWmqtDSVQI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SOQBh9sn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SOQBh9sn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D5583C4CEF1; Tue, 6 May 2025 12:24:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534257; bh=Tv02OqEETUJL5RhGfHRLiUOkxm6hkdgtGZBz124yXQU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SOQBh9snkrf3L/khzAK2xTex7xKK5U9wBZZAS+718Pk/0V5ruvIFHPS1jTTnWuPSg YW8WlWLCQs3i5Ja4yGWCDLvLKLl/lm1hZRMMsRAj3VxGe7pLjHwjkxNhFaARgkywX/ 7l9XytBILzWT4DSxXEUpP4ry9NxXoLHa6mzElGs6h8iWYQNfzZ5TgniBaTgXEUOpAz g7cG1/wpRWNPbeOkGn1iOWEj37AnH69RF/wWE/Iop2US5QfkjaGOp76pyrjM8nJ6XA xTWUR0soSIzXmy5aPJ2UDe2Nbl3fZW6RYFPTGx9OrKArmOIiC71tHrJ3NRA7GRTK54 xGUiZYHhBml7A== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:33 +0200 Subject: [PATCH v3 04/25] arm64/sysreg: Add ICC_ICSR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-4-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_ICSR_EL1 register sysreg description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 0cc1268c0bfad8266da47b441e80c603e46c00ae..985f2cdb67cfec6df335a3951ec= b63f128f6da55 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2310,6 +2310,20 @@ Field 31 C Field 30:0 P EndSysreg =20 +Sysreg ICC_ICSR_EL1 3 0 12 10 4 +Res0 63:48 +Field 47:32 IAFFID +Res0 31:16 +Field 15:11 Priority +Res0 10:6 +Field 5 HM +Field 4 Active +Field 3 IRM +Field 2 Pending +Field 1 Enabled +Field 0 F +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40656280A21; Tue, 6 May 2025 12:24:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534262; cv=none; b=cJ+MXykE6p+rrQktM6ZrVzK+2TN9NN18dZPBsHTB8qhJ02vlJ9UKXD+Yd+PdLHXTVd57BYVhjApbjX1nhvHLqdTd1u4BEM/V9UkRzEbA41uSaxkgHqRLl1IljaialpSlbjFyXpbzS6CVXg0RNuJHu/hWUxaeJIARza69EG3ABLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534262; c=relaxed/simple; bh=OznnXe4nZQZT5vM8HP2AP0cBLVxiMADjBCE9cYkRzRc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Y8DEf4RxluOAdnQOwC6E4eUIAec4ISXwzXwgEyqG2iPweRryryxuMcz6hbBRYAzzIanZRSOGnkxD8IPVLmKgSz20TJXCoDnr7DTuBDNynuZMo9G85EguLYA7NwfqaDrIaCwyAwxDQ/032jvGqQHw9b3dQC1/drh9jKNZw1BR+0Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZQIAGeZy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZQIAGeZy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 42D5FC4CEED; Tue, 6 May 2025 12:24:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534262; bh=OznnXe4nZQZT5vM8HP2AP0cBLVxiMADjBCE9cYkRzRc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZQIAGeZyl2KBOYusGJRbDZbKo8K2A8ai0vosbf3I5CqWA4BQFep6ReaUup7GjyvZV ud/Vc24TBWRl1Xr+t8a+VCHn38goxvH96MK0ULNekfbO4UKsUt4tibPJeamDIdL6zA 80S8Q6BHyXkHlZCEVhHI1B+9/gnVa/T2+8sbcxnJ+BKZfEjHisbCi36/ob5UdKcMvk EwJdXSOqBHIgRyzeF/Xp3qbTVUqeykqH+Vh9NtV/3g5iDlhS9d3cS5D2UOWub9Sgyh sQMPum8N7N1S+AINXUoGL0B54iuBROdiRvfbjsQ5TypBcv/KKdWvqM2dXvfWNjl776 x5QZy51SrBoNw== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:34 +0200 Subject: [PATCH v3 05/25] arm64/sysreg: Add ICC_PPI_HMR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-5-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_PPI_HMR_EL1 registers sysreg description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 75 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 75 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 985f2cdb67cfec6df335a3951ecb63f128f6da55..d046d719d4f69801aeef51b5b94= 37a0eaa04134e 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2324,6 +2324,81 @@ Field 1 Enabled Field 0 F EndSysreg =20 +SysregFields ICC_PPI_HMRx_EL1 +Field 63 HM63 +Field 62 HM62 +Field 61 HM61 +Field 60 HM60 +Field 59 HM59 +Field 58 HM58 +Field 57 HM57 +Field 56 HM56 +Field 55 HM55 +Field 54 HM54 +Field 53 HM53 +Field 52 HM52 +Field 51 HM51 +Field 50 HM50 +Field 49 HM49 +Field 48 HM48 +Field 47 HM47 +Field 46 HM46 +Field 45 HM45 +Field 44 HM44 +Field 43 HM43 +Field 42 HM42 +Field 41 HM41 +Field 40 HM40 +Field 39 HM39 +Field 38 HM38 +Field 37 HM37 +Field 36 HM36 +Field 35 HM35 +Field 34 HM34 +Field 33 HM33 +Field 32 HM32 +Field 31 HM31 +Field 30 HM30 +Field 29 HM29 +Field 28 HM28 +Field 27 HM27 +Field 26 HM26 +Field 25 HM25 +Field 24 HM24 +Field 23 HM23 +Field 22 HM22 +Field 21 HM21 +Field 20 HM20 +Field 19 HM19 +Field 18 HM18 +Field 17 HM17 +Field 16 HM16 +Field 15 HM15 +Field 14 HM14 +Field 13 HM13 +Field 12 HM12 +Field 11 HM11 +Field 10 HM10 +Field 9 HM9 +Field 8 HM8 +Field 7 HM7 +Field 6 HM6 +Field 5 HM5 +Field 4 HM4 +Field 3 HM3 +Field 2 HM2 +Field 1 HM1 +Field 0 HM0 +EndSysregFields + +Sysreg ICC_PPI_HMR0_EL1 3 0 12 10 0 +Fields ICC_PPI_HMRx_EL1 +EndSysreg + +Sysreg ICC_PPI_HMR1_EL1 3 0 12 10 1 +Fields ICC_PPI_HMRx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10B9027FB2A; Tue, 6 May 2025 12:24:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534267; cv=none; b=XvXmK/6rDTND/8hbSRpUotGEAEqMlUcyp4WyVE8DTVvAr4UapcVb4npLSRJHcEqc4gf6pKAcHKa6V5v3y6MWfceMA/H4mnYI9u81ZINgt9+vm192WmezKkYdceSTgjRnOLwA/0OW185seUBMh5xRSfWrwO94Bp9Msl3iQJhxWcM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534267; c=relaxed/simple; bh=eUBcCIH4szhTdWT4b2dVdh8O8kcTuP+XkEb7/cO8FcI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oHnclL0Awg06yRC6/Vua1EXn8YY0gWjb3KDzImfUTFOnre3evaqol6MpouA9e/qTtzRUdVF1QOykv4EcFr8zIb78Lt4P7JGHY+eWPmDkrPhnGKXQB93gxS9iazUslG8FCqp5BpAvf8hAR3S9+IiCwyCEz/zysXjV4coWffV64mU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qUn8W80Q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qUn8W80Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D243C4CEF0; Tue, 6 May 2025 12:24:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534266; bh=eUBcCIH4szhTdWT4b2dVdh8O8kcTuP+XkEb7/cO8FcI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qUn8W80QIJbi7c8P9ea7CAmhuBRLsED8u2RcnM8x1E2kiPSOZcpCV0QI8FO9josH2 DcHSAXUHMTXNmdk8v7K6/9S0BPFbqDfPU1GKyr+pzOnw9hrZWAcUYbC4WMLk+42S2R Eh+W5SChUDu1uTl4tYYPLgYK0YlZV7AG/bGCo1U0i7+VZYGTbFdPzFJDDTCYMyI/Er q9mQNSDdZN9iSZXLDq1acIJiUCbhYMF2RHsZbzIxG31pOOrkL129i0vphENL6v5Wqf GspM/QIU6ysEcRdXD6yVvec73KSxt3hf4cctDRd2crZDAQ1JT/OooypOIWD31UTBPH eP7/y3LEV7bBQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:35 +0200 Subject: [PATCH v3 06/25] arm64/sysreg: Add ICC_PPI_ENABLER_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-6-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_PPI_ENABLER_EL1 registers sysreg description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 75 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 75 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index d046d719d4f69801aeef51b5b9437a0eaa04134e..6c5552707ad88c145adc8b7ceb3= f63da401191ea 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2399,6 +2399,81 @@ Sysreg ICC_PPI_HMR1_EL1 3 0 12 10 1 Fields ICC_PPI_HMRx_EL1 EndSysreg =20 +SysregFields ICC_PPI_ENABLERx_EL1 +Field 63 EN63 +Field 62 EN62 +Field 61 EN61 +Field 60 EN60 +Field 59 EN59 +Field 58 EN58 +Field 57 EN57 +Field 56 EN56 +Field 55 EN55 +Field 54 EN54 +Field 53 EN53 +Field 52 EN52 +Field 51 EN51 +Field 50 EN50 +Field 49 EN49 +Field 48 EN48 +Field 47 EN47 +Field 46 EN46 +Field 45 EN45 +Field 44 EN44 +Field 43 EN43 +Field 42 EN42 +Field 41 EN41 +Field 40 EN40 +Field 39 EN39 +Field 38 EN38 +Field 37 EN37 +Field 36 EN36 +Field 35 EN35 +Field 34 EN34 +Field 33 EN33 +Field 32 EN32 +Field 31 EN31 +Field 30 EN30 +Field 29 EN29 +Field 28 EN28 +Field 27 EN27 +Field 26 EN26 +Field 25 EN25 +Field 24 EN24 +Field 23 EN23 +Field 22 EN22 +Field 21 EN21 +Field 20 EN20 +Field 19 EN19 +Field 18 EN18 +Field 17 EN17 +Field 16 EN16 +Field 15 EN15 +Field 14 EN14 +Field 13 EN13 +Field 12 EN12 +Field 11 EN11 +Field 10 EN10 +Field 9 EN9 +Field 8 EN8 +Field 7 EN7 +Field 6 EN6 +Field 5 EN5 +Field 4 EN4 +Field 3 EN3 +Field 2 EN2 +Field 1 EN1 +Field 0 EN0 +EndSysregFields + +Sysreg ICC_PPI_ENABLER0_EL1 3 0 12 10 6 +Fields ICC_PPI_ENABLERx_EL1 +EndSysreg + +Sysreg ICC_PPI_ENABLER1_EL1 3 0 12 10 7 +Fields ICC_PPI_ENABLERx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D9C227FB3E; Tue, 6 May 2025 12:24:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534271; cv=none; b=W15/2InKROkgtx3dq4GGxUKsvBt1IK9lD7KOAw82UHMEc/Nl5zQgwlapLq7IU5CqJFqNgAZvgaKdShOE2I9EpHHTarI/N7K4x14+izVx+HJDC4jovo2a0zeUuRMGpD4HAt3WR1QVIGAWiGIRcUM+vB1hVuC1MBmXIuBZarATt3g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534271; c=relaxed/simple; bh=kr4FIsYzSG8vhPEwCV+efvFDb0h/Nmo/+nvgPyW4hHA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BUs3Kp3Fk6uiiNkKcjJTHvjQ8pOe7sjuCGcVT+jDtmAj7/ysNAIvTUo3dv9nTBj89JYMXqtewrlhlsVdBdYnMhTT2lByQ+ABUH6aMqlBqohuYAVbjqINp6N0iFNzDoZeY1M23DfydO9X52+hs6GppD7v5vDp3e2oG4DFB7vmHmk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Zav5G45T; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Zav5G45T" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0ADBBC4CEEE; Tue, 6 May 2025 12:24:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534271; bh=kr4FIsYzSG8vhPEwCV+efvFDb0h/Nmo/+nvgPyW4hHA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Zav5G45TFKlLtijxj+eILVDB9zg3Vx/HrZ8PnSOCThanGPRSNwB8cfPZ580jxkBxi 9g3YCUrq7DNRe7DPuAC83nRZYAbhkij363xeZ4i3nE6JrmmUYiA3zFCLc60LzcEX4v 0+X7d8aFL6Scs/zWjC7Krp0JsO7142PubiWFN9aYIt5WcXcwawxSHtKysnUYRLj/WA dLideFmkLqX7MQ0F8inP7W3AlwY4E5uDd16YMaC9Em6u8N9kb+auG/lxtT4PDDUhri GoPtLMmyNkbv2+7JNzJVN/nw17XKPcoT3JRy+VzEhpxuvO876f/aQaHosu6cwLDV73 uUsyRFHqA90RQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:36 +0200 Subject: [PATCH v3 07/25] arm64/sysreg: Add ICC_PPI_{C/S}ACTIVER_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-7-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_PPI_{C/S}ACTIVER_EL1 registers description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 83 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 6c5552707ad88c145adc8b7ceb3f63da401191ea..0485721e1575c9ed158210c6f02= fb9af2828f2d5 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2474,6 +2474,89 @@ Sysreg ICC_PPI_ENABLER1_EL1 3 0 12 10 7 Fields ICC_PPI_ENABLERx_EL1 EndSysreg =20 +SysregFields ICC_PPI_ACTIVERx_EL1 +Field 63 Active63 +Field 62 Active62 +Field 61 Active61 +Field 60 Active60 +Field 59 Active59 +Field 58 Active58 +Field 57 Active57 +Field 56 Active56 +Field 55 Active55 +Field 54 Active54 +Field 53 Active53 +Field 52 Active52 +Field 51 Active51 +Field 50 Active50 +Field 49 Active49 +Field 48 Active48 +Field 47 Active47 +Field 46 Active46 +Field 45 Active45 +Field 44 Active44 +Field 43 Active43 +Field 42 Active42 +Field 41 Active41 +Field 40 Active40 +Field 39 Active39 +Field 38 Active38 +Field 37 Active37 +Field 36 Active36 +Field 35 Active35 +Field 34 Active34 +Field 33 Active33 +Field 32 Active32 +Field 31 Active31 +Field 30 Active30 +Field 29 Active29 +Field 28 Active28 +Field 27 Active27 +Field 26 Active26 +Field 25 Active25 +Field 24 Active24 +Field 23 Active23 +Field 22 Active22 +Field 21 Active21 +Field 20 Active20 +Field 19 Active19 +Field 18 Active18 +Field 17 Active17 +Field 16 Active16 +Field 15 Active15 +Field 14 Active14 +Field 13 Active13 +Field 12 Active12 +Field 11 Active11 +Field 10 Active10 +Field 9 Active9 +Field 8 Active8 +Field 7 Active7 +Field 6 Active6 +Field 5 Active5 +Field 4 Active4 +Field 3 Active3 +Field 2 Active2 +Field 1 Active1 +Field 0 Active0 +EndSysregFields + +Sysreg ICC_PPI_CACTIVER0_EL1 3 0 12 13 0 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + +Sysreg ICC_PPI_CACTIVER1_EL1 3 0 12 13 1 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + +Sysreg ICC_PPI_SACTIVER0_EL1 3 0 12 13 2 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + +Sysreg ICC_PPI_SACTIVER1_EL1 3 0 12 13 3 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2FD4281343; Tue, 6 May 2025 12:24:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534276; cv=none; b=o3NFwIgqg9t6SvdhLn9a/c0+S/hh4u5pyVIC5K/+Gi86FnKL/JW4fYlgF8FXxMR3mEeYXTIGdAVGalfIMLmeop5uo8IJCudK+IrZA29BOgPzsEsyD2oOvo4KOmoNIdV0awAw+MQhEmwVCW/fT19OHW8zcPPcZdl3F3OEkpkS5Mc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534276; c=relaxed/simple; bh=sQqjxedBfR/x/zpD52PYNFW1off5a3wsTQ0MTvz8038=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DptnIBbM3r7je8llaE3KHk4gzpuPufV/Z2kO+RKnsUpMhvqgYbcZE3ocECsrFgFU2On+Z7RUrIp9z2ADxdCNF+QRt4LXqJnFGG2zjvsvYkFycmjKQJ0N00fiiEErctZ5utVr3ieN3fsNQNzgrw4er6TSH//OKOV43+iDZphzZAw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JH2FSbRh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JH2FSbRh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7AF9FC4CEED; Tue, 6 May 2025 12:24:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534275; bh=sQqjxedBfR/x/zpD52PYNFW1off5a3wsTQ0MTvz8038=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JH2FSbRhY49r/xBD0KCVu1vulpBsgkXAcRvCQwJ9rOfS0je6ogfP30fm29/ylIz0I vixas9Q2kwz4vBjvDJlNdt/TLrgA07aeHBsBuSS/wnjxj/1fGDXN2Es3P0REntBId8 eNNxxFWWgrWVKxm67gsXNWDh8bxvycaTT7JUjrLmbHGFpTDc0ALp0fYTK6YRbvO9lR IIxe+PbWnhGm2s/Tqhza2uBriSYSLVcI8sEXxtun3fC/BpjPhEw43PDt9azthzQETS 8/gKgIoDRkaAa8+PpDRPRmisO9sofRd+bTl4rizi0MPwCGEH+6ERJTnC/NXNj8aDk9 FEGRnKpHHGz7g== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:37 +0200 Subject: [PATCH v3 08/25] arm64/sysreg: Add ICC_PPI_{C/S}PENDR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-8-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_PPI_{C/S}PENDR_EL1 registers description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 83 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 0485721e1575c9ed158210c6f02fb9af2828f2d5..7acad93718c56729ce2a333ed00= 7243ec554dbc9 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2557,6 +2557,89 @@ Sysreg ICC_PPI_SACTIVER1_EL1 3 0 12 13 3 Fields ICC_PPI_ACTIVERx_EL1 EndSysreg =20 +SysregFields ICC_PPI_PENDRx_EL1 +Field 63 Pend63 +Field 62 Pend62 +Field 61 Pend61 +Field 60 Pend60 +Field 59 Pend59 +Field 58 Pend58 +Field 57 Pend57 +Field 56 Pend56 +Field 55 Pend55 +Field 54 Pend54 +Field 53 Pend53 +Field 52 Pend52 +Field 51 Pend51 +Field 50 Pend50 +Field 49 Pend49 +Field 48 Pend48 +Field 47 Pend47 +Field 46 Pend46 +Field 45 Pend45 +Field 44 Pend44 +Field 43 Pend43 +Field 42 Pend42 +Field 41 Pend41 +Field 40 Pend40 +Field 39 Pend39 +Field 38 Pend38 +Field 37 Pend37 +Field 36 Pend36 +Field 35 Pend35 +Field 34 Pend34 +Field 33 Pend33 +Field 32 Pend32 +Field 31 Pend31 +Field 30 Pend30 +Field 29 Pend29 +Field 28 Pend28 +Field 27 Pend27 +Field 26 Pend26 +Field 25 Pend25 +Field 24 Pend24 +Field 23 Pend23 +Field 22 Pend22 +Field 21 Pend21 +Field 20 Pend20 +Field 19 Pend19 +Field 18 Pend18 +Field 17 Pend17 +Field 16 Pend16 +Field 15 Pend15 +Field 14 Pend14 +Field 13 Pend13 +Field 12 Pend12 +Field 11 Pend11 +Field 10 Pend10 +Field 9 Pend9 +Field 8 Pend8 +Field 7 Pend7 +Field 6 Pend6 +Field 5 Pend5 +Field 4 Pend4 +Field 3 Pend3 +Field 2 Pend2 +Field 1 Pend1 +Field 0 Pend0 +EndSysregFields + +Sysreg ICC_PPI_CPENDR0_EL1 3 0 12 13 4 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + +Sysreg ICC_PPI_CPENDR1_EL1 3 0 12 13 5 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + +Sysreg ICC_PPI_SPENDR0_EL1 3 0 12 13 6 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + +Sysreg ICC_PPI_SPENDR1_EL1 3 0 12 13 7 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55772281368; Tue, 6 May 2025 12:24:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534280; cv=none; b=ugzMpduDxGr3FDzH1dM6k1HnfJR2jzXz8wWQzrg4dbOB8WcALnzbKNCEZQkOX4KMqXilGtNv4VZteOu+bsaMknzktOLL8hg2vpBMppwqCLTMkRJvEy51uuPeBgjOrjmMypb9q5hujbXUS/qRJBTQyY+G0BrspVtTliiObXk/I/c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534280; c=relaxed/simple; bh=aABGEIrWEsGcFFHRxubhJftIId76X0k2qcZSdwnplek=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cZRzMBTjONujAi0gafj6oOoihBUl7o6kzkwEr4Mx1m81rASriA+rc0+DDMNKPVFjndWevwq+p/1cLNR27YRQ2hacOr46Aa4EnqaDkswvNjC+A4Ps4Zh1VC72w6agEZr1NzC2t8WpPO5lNQPCa4fbQmj3lFBEoo9fjgSnvlitEzM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FBXDAf60; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FBXDAf60" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E898EC4CEEE; Tue, 6 May 2025 12:24:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534279; bh=aABGEIrWEsGcFFHRxubhJftIId76X0k2qcZSdwnplek=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=FBXDAf60a8RKPxrbybL/t+7ybaq34zNLfJnqrxZH5G2+Ypuo8p6AFSVmkz4PB7MT7 NuJ4luoCgfaB/YrJTQJZuTawKzIFUoUXX4a5WJ3lu4F9EfApLF/o26nKAF+eo2NPD3 v0q2YbWV/z/TQrHHmEEeK8/pFqXhJlxjZortkcVsqnHsCCM1tdeL5Bwguq3l0sXjtO uiWgRmDhlUsPPkoKy++SWFnEezwtno5n/tZOXyaTrKHk43RCTKMveocdIYsYyYUYeC VSjvFxwLaZPcLEKnWzrSF+5b1xCuTueqtAkb6xrcwJmEt3J2UqDEIjOFgKRoiKsU4c qDNPfONWVRVxA== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:38 +0200 Subject: [PATCH v3 09/25] arm64/sysreg: Add ICC_CR0_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-9-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_CR0_EL1 register description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 7acad93718c56729ce2a333ed007243ec554dbc9..c96243505031ea680c04a693fee= 2c96ad19e30ea 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2798,6 +2798,14 @@ Res0 14:12 Field 11:0 AFFINITY EndSysreg =20 +Sysreg ICC_CR0_EL1 3 1 12 0 1 +Res0 63:39 +Field 38 PID +Field 37:32 IPPT +Res0 31:1 +Field 0 EN +EndSysreg + Sysreg CSSELR_EL1 3 2 0 0 0 Res0 63:5 Field 4 TnD --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59B3927FB0C; Tue, 6 May 2025 12:24:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534284; cv=none; b=BqSG76e+HoVZNP8qLaXjWZldL2yNJsM3cjScxhVP/sn7oeZXuVTxvjhMMuzxyU5xLi7jM2/E3KoFz79waLabZeuE/FLg4408fOHJsmGwdNcSPVjojKv+Le5K5h4helQsMlxNW8Ahdr2h+wTi6UIP5OsICT7toqcMADT1tvRlTrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534284; c=relaxed/simple; bh=IR60XZsATfdTuIxQzwSdrYf53KWRtcmnuEgRG5+wtmQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=j+dXP/qIxLwMm4H2bd2xn2XBp/FbU9JWSy7Q9EkN+bNYVzx4hKQMbStAfzKYEdw9vEjeBHEvvMHenR9TU4X5tYWQVLFkJe1E6ZbpXUHQ39y87uWJThrUDISnjwqaiAj+gs1d31AN/DyKTCwWs1HRZw/LmQz/Tb6BNG9G0053uFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IPq+lEj0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IPq+lEj0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 56887C4CEED; Tue, 6 May 2025 12:24:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534284; bh=IR60XZsATfdTuIxQzwSdrYf53KWRtcmnuEgRG5+wtmQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IPq+lEj0IohqZZ+lCvThNpzSlpPVBeaBJ/A5uHGRPgnr0rI8PahBUCST9vy9sz4ez 3cY8FFFsyev5Y0nYLdwlGAaOpUwUM+jsLXeRodgwPD5TCUQ+rseUzXggaLGl5Y1i7Y 43mJX2AS0HOsZyj+JKZ/XrHjK4OXardHCqWoymLKJS2zCu8s43czarXjDs0t3wXFXp FIEpwY9KCiuFmOvhgu7vAnYNxMZpTxRgZ63zA30ic/jpEhm9Z5oAe15LkR2FTQHhZK L0l2qqRWdb3J+UaYSXbaSC67TjQbySsQjIzOBluy1oFm3ryEQMw1IAbsclhojPCIoB Lr7PbuSvicrjg== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:39 +0200 Subject: [PATCH v3 10/25] arm64/sysreg: Add ICC_PCR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-10-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_PCR_EL1 register description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index c96243505031ea680c04a693fee2c96ad19e30ea..9a2ddab8661c85586b0e91f7eaa= bd5a6b3409c67 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2806,6 +2806,11 @@ Res0 31:1 Field 0 EN EndSysreg =20 +Sysreg ICC_PCR_EL1 3 1 12 0 2 +Res0 63:5 +Field 4:0 PRIORITY +EndSysreg + Sysreg CSSELR_EL1 3 2 0 0 0 Res0 63:5 Field 4 TnD --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14B1027FD5B; Tue, 6 May 2025 12:24:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534289; cv=none; b=lbTfKewKH4rqVzAk3lRSj9h3e7+dnixcRm9P4XaqDrMQjcNGanm5vDAfIbg0c0cUFtPNCfqcOFK/YfbXJ+EodaX6rlqoIpO/BChU7JmIQfnd7XbBgdWgBnxAY77zcVYOTqWKFH2N0v5qprclm3jx2VbDlbuFtXiA0upxaSMwRSc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534289; c=relaxed/simple; bh=Dk78WkgkowYSPPndroB+3TTj6jQAcxwQp1XS8EQ5gtg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aBJ/yixalIROgJHc/ZaxrFg/DXhMyXaoTqKCzib4tYgUSVD25ey7ET5aZQk+V5g2cV5dAKYXoK2JtQ4MWSK47QllmRl/bvl498S9K7YxPPNZXJ+NKKzVcxP+M9HdPcCr9eJI7l193pHKXHKQsSvS93tf22BSgYzQ7IFF/2+t5Oc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F4Lhskuf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="F4Lhskuf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B3355C4CEE4; Tue, 6 May 2025 12:24:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534288; bh=Dk78WkgkowYSPPndroB+3TTj6jQAcxwQp1XS8EQ5gtg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=F4LhskuftmnNJUUbeCs4it+1aQlhCbN2dPm5El8d3mxhYb9PXrGjib6Aq9ApVmiKg R6m/nx3PzMTC1/ITjIg6UURoT7zbm8IkGmfBFjhM/CxdBGpCjhQb7378aK3NfLNQhW OHXDrVLxWCJvQNq5rT/NeAhBaIljXm3KiNLzYOrj29nchHj98OMhJORig42Q6U5TD1 pNVNGefEwJQFF0Hed4XZYa4RytuG4nukAQxLb0hgYLVQcoTAfuVyXlpW0PdPnKnZL3 AVXwbZ9MY8kuQU03STnAIMfMEBlYPXWkeDFZZ7kOh5D0Il8Dkl9qppAynB6/1yTmYj BoWUcBLcEPmmA== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:40 +0200 Subject: [PATCH v3 11/25] arm64/sysreg: Add ICC_IDR0_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-11-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICC_IDR0_EL1 register description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 9a2ddab8661c85586b0e91f7eaabd5a6b3409c67..1ec8113df713dfea6d38e39c42e= ba1e3dca5eea5 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -2399,6 +2399,22 @@ Sysreg ICC_PPI_HMR1_EL1 3 0 12 10 1 Fields ICC_PPI_HMRx_EL1 EndSysreg =20 +Sysreg ICC_IDR0_EL1 3 0 12 10 2 +Res0 63:12 +UnsignedEnum 11:8 GCIE_LEGACY + 0b0000 NI + 0b0001 IMP +EndEnum +UnsignedEnum 7:4 PRI_BITS + 0b0011 4BITS + 0b0100 5BITS +EndEnum +UnsignedEnum 3:0 ID_BITS + 0b0000 16BITS + 0b0001 24BITS +EndEnum +EndSysreg + SysregFields ICC_PPI_ENABLERx_EL1 Field 63 EN63 Field 62 EN62 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81B3B27FD5B; Tue, 6 May 2025 12:24:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534293; cv=none; b=Yg++Ls1/4dHA72gcWf3/dvxF//8E0SDER5xspvOdXKM2K4/4jNv6cCAVTMVFGSQH8N0ZInU4xvQeIAxws+ti6ySvvVZmLZJPDzKSj3DZ/EaVdRXOMhU2zcMKE2n1jvoaXtuTgRsMiXZdSri3gck0vxXitTHUz61A2MgpMk/9dL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534293; c=relaxed/simple; bh=jtBNyXLItJhfIxTK4Pp6vzdTvnQztzIAhQqNSaBxo3Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GB9r715fThFQONQf60pDuCU0EzW9Cnt/Cxc4h9cuOFtxBjVw5RenI6hbiNdXGYwhruwYbRaqDkJe8fOaWbN8jEc3P9pYDGiCW/NVqQ1xVZ9wCRwyV3ruKd/uPufiE1NFSigGgZcBcSLGpG4Xs/fGJWPVJ76miOIJECcosuMP5pU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ss+UtzDG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ss+UtzDG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1BDCAC4CEED; Tue, 6 May 2025 12:24:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534293; bh=jtBNyXLItJhfIxTK4Pp6vzdTvnQztzIAhQqNSaBxo3Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ss+UtzDGK0GbH+rcWWinBurvS3uL0Qn9KEZxjT/oJEjDUn9tvTSl+V7iLc9u6MJPv tLTx7Dx3WB6uLxYsk+Q1cywdsFju1xM0zp/BknoFtFhSWevCwC4S8TX/cd6kLQh5bq oXZ28PWZbp8tVWSYn3Of3QRSo8BlRZWRMcD1p2eVjLZKDsWnVFobSJRF2G2NM41Yd8 RJldG9ObOD7kksut3g/1tAwDVqVYwVYVabkRAi+t+iFlSp4BckoA4WObWfD1MNKOmB jGJfSmsysRRCYoNFL68JXPRZtRM5vlGhcVWxVbKBnLbQQ62Kt+fFd/et+U44lCscvX 70zV1NW5ze7YA== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:41 +0200 Subject: [PATCH v3 12/25] arm64/sysreg: Add ICH_HFGRTR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-12-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICH_HFGRTR_EL2 register description. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 1ec8113df713dfea6d38e39c42eba1e3dca5eea5..0c0e805481c84a14ae62d199466= 171d97d54ef90 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3583,6 +3583,24 @@ Field 31:16 PhyPARTID29 Field 15:0 PhyPARTID28 EndSysreg =20 +Sysreg ICH_HFGRTR_EL2 3 4 12 9 4 +Res0 63:21 +Field 20 ICC_PPI_ACTIVERn_EL1 +Field 19 ICC_PPI_PRIORITYRn_EL1 +Field 18 ICC_PPI_PENDRn_EL1 +Field 17 ICC_PPI_ENABLERn_EL1 +Field 16 ICC_PPI_HMRn_EL1 +Res0 15:8 +Field 7 ICC_IAFFIDR_EL1 +Field 6 ICC_ICSR_EL1 +Field 5 ICC_PCR_EL1 +Field 4 ICC_HPPIR_EL1 +Field 3 ICC_HAPR_EL1 +Field 2 ICC_CR0_EL1 +Field 1 ICC_IDRn_EL1 +Field 0 ICC_APR_EL1 +EndSysreg + Sysreg ICH_HCR_EL2 3 4 12 11 0 Res0 63:32 Field 31:27 EOIcount --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6B662820AF; Tue, 6 May 2025 12:24:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534298; cv=none; b=rxshuyZOaqtFbGUxlaQ+eXOL4O7hnCYL+5Fdaw64R+zjbATZynm1HQCmIuCtDwRmiw1cSYE/Sg+KKTfiftINlnXnidZf2u0Wkjs5i4MeAgcYRlhvOFCCS56jN9BzDfyEfSPFDG3t1XkJFg3cDmgkgooT8sjy4S16/sezapck46c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534298; c=relaxed/simple; bh=3IG/dkyf3kNeiDq8iUpch8Bd+BjlFKQ3NbAf5IVjrxM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nMbFryg1VKJC8wy2WqWFS4BmRZeviPcPiI0dDBJmA8qvkwBR0dkeQpiUapNwu95nK3DFhnYus2kehl5sCYTI2Klx7jM9rm0vXhWRClqY6ekp/Uhb/p7LaX1KAMmOYeXwF1C9R5QM/eYGOhjS1sP6SY3mag9zRVFXGs96ItrLQMM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MO4XfklG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MO4XfklG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8062AC4CEE4; Tue, 6 May 2025 12:24:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534297; bh=3IG/dkyf3kNeiDq8iUpch8Bd+BjlFKQ3NbAf5IVjrxM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MO4XfklGtI92rBhKWuFGlfLpJH3w8PruZTzaBwhDPIEFf2c8JPXK0kXG2TPnLmD5F T9QGeX+TPuxhPm6uhrUveu7BOZyasXNWpXyhK121SR65DqSm//4Eig9khSiUpndWOt vwowav0QDpP6QOL6oaEMpJU3u9QI/XuIjEoHFJUzY9u2WU2LZmGJqv3hd1WI2J+LuE jIWER8I811pVF7OJXKwOF0Kgr+DmlnS1TuSReLYIUCuLffwq0xKZvaycXV7lZbmNQT 794SlyCd6+UagZZC7lpuBXNJn846F9RRFA45TNwG3AE94SqGJ0JnACgPK0t5+0Wgfd y8UDgz0AEZ2wQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:42 +0200 Subject: [PATCH v3 13/25] arm64/sysreg: Add ICH_HFGWTR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-13-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICH_HFGWTR_EL2 register description to sysreg. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 0c0e805481c84a14ae62d199466171d97d54ef90..1b519e35000be328acfe26d51e0= 98059f9cf9ef2 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3601,6 +3601,21 @@ Field 1 ICC_IDRn_EL1 Field 0 ICC_APR_EL1 EndSysreg =20 +Sysreg ICH_HFGWTR_EL2 3 4 12 9 6 +Res0 63:21 +Field 20 ICC_PPI_ACTIVERn_EL1 +Field 19 ICC_PPI_PRIORITYRn_EL1 +Field 18 ICC_PPI_PENDRn_EL1 +Field 17 ICC_PPI_ENABLERn_EL1 +Res0 16:7 +Field 6 ICC_ICSR_EL1 +Field 5 ICC_PCR_EL1 +Res0 4:3 +Field 2 ICC_CR0_EL1 +Res0 1 +Field 0 ICC_APR_EL1 +EndSysreg + Sysreg ICH_HCR_EL2 3 4 12 11 0 Res0 63:32 Field 31:27 EOIcount --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5391F28002E; Tue, 6 May 2025 12:25:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534302; cv=none; b=W9b6pUZeGjq7WYfwUDYHPZoFGhZajrR4FpeFLnvjGTKUxhzjd3UyYxj8OFOH9FFVAr4COVObvVg/xDk+ucnfqPeXAf7iX3tIpij4R8VdnSZxCSQmMO6C8RDP29CBG2ijCpWRxN4ZWHg6MGTlUiik2w9eXhTvvufHUO2grVeqNQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534302; c=relaxed/simple; bh=9zWp7WGj091+ZG2FSlP0T7J3sn+1tw+UEtNEfbmUjxQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GFS5G/5r6uZ4WVNI05ggpvE5lYd/pcrZizDZh64WMkxehd8EmtciEaxEovXZMF9Mnlq6qlvfocQWsIKR0pvl5mrwW9Fmww6WEQyefb31LD9SapGgBVGTkbN5RmX8ZzHTF0I1Ma/+vFZV0gjAxU0T9df1Jnpbabh/ibnNjpZzPfk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cfAMOE6r; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cfAMOE6r" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF52DC4CEED; Tue, 6 May 2025 12:24:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534301; bh=9zWp7WGj091+ZG2FSlP0T7J3sn+1tw+UEtNEfbmUjxQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cfAMOE6rM51h+vapY6Xn21DKVYkTo51ypb6iPcT9PE7cjAG/ALQZOkQ8xnP/Ricx0 HHg9ajhQSqsE9RBXKI9NlRbZVhOOYArRbq0BgTPiY/5iuc88RyTfwsFEk6LX0bTQ1n DO5OMlrkpH3XSvu7bXc21OaTarPGtiOBdytP4HQrvAHNm72gHHnWlsG+mv021FizXL LlIDg6OrnX5TF/cYUKqMN37T6V60yu/3mUa+/8m6BrNghl6DUqdU3TibKA1eJ6TwwQ FvunlvQkLzeaXMvKuS0QnGj/7wg78fG8lTpeDF8h+UQUC1SRuPW6blpE6HXly094oA otig4Ezlw6/nQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:43 +0200 Subject: [PATCH v3 14/25] arm64/sysreg: Add ICH_HFGITR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-14-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Add ICH_HFGITR_EL2 register description to sysreg. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/tools/sysreg | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 1b519e35000be328acfe26d51e098059f9cf9ef2..5af0dea6e775ea680686dbe4bc8= 36b5f5b69fbc7 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3616,6 +3616,21 @@ Res0 1 Field 0 ICC_APR_EL1 EndSysreg =20 +Sysreg ICH_HFGITR_EL2 3 4 12 9 7 +Res0 63:11 +Field 10 GICRCDNMIA +Field 9 GICRCDIA +Field 8 GICCDDI +Field 7 GICCDEOI +Field 6 GICCDHM +Field 5 GICCRDRCFG +Field 4 GICCDPEND +Field 3 GICCDAFF +Field 2 GICCDPRI +Field 1 GICCDDIS +Field 0 GICCDEN +EndSysreg + Sysreg ICH_HCR_EL2 3 4 12 11 0 Res0 63:32 Field 31:27 EOIcount --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DB4C27FD72; Tue, 6 May 2025 12:25:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534306; cv=none; b=gq5iKm6d6XX6SxrI4oTuSnKUpBoa/EfZxxaKU+LgrWSqK5+h6Ql+mT8pvCxHeilnRHqdjN1lBygtoxiI56kqq6Q3OPiDR/1k2a2Ywe/+DtUEkjdD1sU41bKnMKTPB1RT0f3OJpqseDSGDo5wxrAWykpBxRidRPATVlAt4HAraAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534306; c=relaxed/simple; bh=gRWN4/WxQNgzKjCuCmcZKjoQVmfMZVTNU54WEek8EP4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iOqEH/kyRfB/wdaoEWduUr6QeGoms+wWysZ/080u7ywqktrLe8Fk6dvXGT1jQoo3z6Q1x6hGnzkwBv67v63OKDPTRBVOQw5kt4cS37XlA3FAeN+MGzPzLKnnTCBXEjAA6BKNY0ac+eMwjimfN2Z++X+dZN0NRUPdlNwfuNochpo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EHZHs+9d; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EHZHs+9d" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F1B6C4CEEE; Tue, 6 May 2025 12:25:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534306; bh=gRWN4/WxQNgzKjCuCmcZKjoQVmfMZVTNU54WEek8EP4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EHZHs+9dVLolSMYcjh0g1FsSEzoa2/wxNl//whlVTNpE+Y5748T+TOuLOgvPqjjz0 NsBF+q6c6hGPU7MSOnUFMFq6b3uP70XSGLrMVTwtYrAO4/OI688eYCYGfuE0Aepb5U /j5y6ij1uRK0q5XjI3V0wVgJOmQRfBlUHe1iCG6Wh2b4yDNZyR9K53ou+IUcCIAsfY Z9pcZENwv5eU8WnivOgfKxjMI2BRHpEdPk7N2rPhVVXSMwPHxwqwdwcw4I+wolYqeI gv7c+WiY662+Jef9VX5EYIMPvIak53v9cAVdvR4PkW7Quz5m7I9DUvsD90q+gSsiOD RKC+L+hR90QVw== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:44 +0200 Subject: [PATCH v3 15/25] arm64: Disable GICv5 read/write/instruction traps Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-15-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 GICv5 trap configuration registers value is UNKNOWN at reset. Initialize GICv5 EL2 trap configuration registers to prevent trapping GICv5 instruction/register access upon entering the kernel. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/include/asm/el2_setup.h | 45 ++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el= 2_setup.h index ebceaae3c749b84395c9c5eccf0caf874697ad11..109b72b657d2fbb6d39e0446c10= d1b62e0a780b3 100644 --- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -165,6 +165,50 @@ .Lskip_gicv3_\@: .endm =20 +/* GICv5 system register access */ +.macro __init_el2_gicv5 + mrs_s x0, SYS_ID_AA64PFR2_EL1 + ubfx x0, x0, #ID_AA64PFR2_EL1_GCIE_SHIFT, #4 + cbz x0, .Lskip_gicv5_\@ + + mov x0, #(ICH_HFGITR_EL2_GICRCDNMIA | \ + ICH_HFGITR_EL2_GICRCDIA | \ + ICH_HFGITR_EL2_GICCDDI | \ + ICH_HFGITR_EL2_GICCDEOI | \ + ICH_HFGITR_EL2_GICCDHM | \ + ICH_HFGITR_EL2_GICCRDRCFG | \ + ICH_HFGITR_EL2_GICCDPEND | \ + ICH_HFGITR_EL2_GICCDAFF | \ + ICH_HFGITR_EL2_GICCDPRI | \ + ICH_HFGITR_EL2_GICCDDIS | \ + ICH_HFGITR_EL2_GICCDEN) + msr_s SYS_ICH_HFGITR_EL2, x0 // Disable instruction traps + mov_q x0, (ICH_HFGRTR_EL2_ICC_PPI_ACTIVERn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_PRIORITYRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_PENDRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_ENABLERn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_HMRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_IAFFIDR_EL1 | \ + ICH_HFGRTR_EL2_ICC_ICSR_EL1 | \ + ICH_HFGRTR_EL2_ICC_PCR_EL1 | \ + ICH_HFGRTR_EL2_ICC_HPPIR_EL1 | \ + ICH_HFGRTR_EL2_ICC_HAPR_EL1 | \ + ICH_HFGRTR_EL2_ICC_CR0_EL1 | \ + ICH_HFGRTR_EL2_ICC_IDRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_APR_EL1) + msr_s SYS_ICH_HFGRTR_EL2, x0 // Disable reg read traps + mov_q x0, (ICH_HFGWTR_EL2_ICC_PPI_ACTIVERn_EL1 | \ + ICH_HFGWTR_EL2_ICC_PPI_PRIORITYRn_EL1 | \ + ICH_HFGWTR_EL2_ICC_PPI_PENDRn_EL1 | \ + ICH_HFGWTR_EL2_ICC_PPI_ENABLERn_EL1 | \ + ICH_HFGWTR_EL2_ICC_ICSR_EL1 | \ + ICH_HFGWTR_EL2_ICC_PCR_EL1 | \ + ICH_HFGWTR_EL2_ICC_CR0_EL1 | \ + ICH_HFGWTR_EL2_ICC_APR_EL1) + msr_s SYS_ICH_HFGWTR_EL2, x0 // Disable reg write traps +.Lskip_gicv5_\@: +.endm + .macro __init_el2_hstr msr hstr_el2, xzr // Disable CP15 traps to EL2 .endm @@ -323,6 +367,7 @@ __init_el2_lor __init_el2_stage2 __init_el2_gicv3 + __init_el2_gicv5 __init_el2_hstr __init_el2_mpam __init_el2_nvhe_idregs --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BE9C283139; Tue, 6 May 2025 12:25:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534312; cv=none; b=eF+J8mn1LZbGAcDVQ3ybiTQh12cE2aKk/oeFh58u/UlEA4+3P8yxlnBppRE4pleRvXY0GO2keHxOOwqKvgHR4VUtCBLkbSZ5v3cjnvKWtmqybHfI654StD+Y3ebWAP+ljcE3cXEFq8GggYivUxsd2Y5TjKo9D8Wk38fK07WnN10= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534312; c=relaxed/simple; bh=J4d+23jK1xcMwImyyVNILtAarSzyfyzelW1CaxCFjwc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=m5ZtpVW3FAUdHduXrx1soFQ8qKJHipQXNm1aRKSGWEqCRWMH1GwuEX+VTGD2n8wiH98txWS5kmFFL76/N2DMLXX6zoVEKzRn13a4wufazhzbz/EpNqeQS0FBObFeT0SzXcTZqEX/0nicyBKy+T5kQjmDvu7jS3h6cF4j4g45ImQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oMgVqzfh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oMgVqzfh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AE7D8C4CEE4; Tue, 6 May 2025 12:25:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534310; bh=J4d+23jK1xcMwImyyVNILtAarSzyfyzelW1CaxCFjwc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oMgVqzfhMhks+7LgtwSz3BViAVXuV2TpcsegwgPYw8M8RiCiir6can3wbiOx9eowt 2FVIq5hS7eQM2Sh9S8UQ7Dupznk/PTJ+3MXjtwqRH9RbIsXeMsRG+n1Hx7rifEZgI3 4vZI3NRD3OrZG9XaHD9JUtuScYsaYvm6RtfrWf/KOZHmS8wUF1eSglhWxhytBYOEIR ekljig2gLlyrgBMMBRePou2aCT8yc89Ap3bW0SxYscaAA4+u38YWshQoMTd/KAR4bC rZnRbOVe05Nmb0eccUXEHG0jOBlM5z7q2jW6zaIgkbfJDNtK91v4McJ5gP/Zj+MYt7 kfSOptTJRvjLg== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:45 +0200 Subject: [PATCH v3 16/25] arm64: cpucaps: Rename GICv3 CPU interface capability Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-16-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 In preparation for adding a GICv5 CPU interface capability, rework the existing GICv3 CPUIF capability - change its name and description so that the subsequent GICv5 CPUIF capability can be added with a more consistent naming on top. Suggested-by: Mark Rutland Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/kernel/cpufeature.c | 10 +++++----- arch/arm64/tools/cpucaps | 2 +- drivers/irqchip/irq-gic.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9c4d6d552b25cb3a31d1fb267bd73d3f82513e69..cbb49de451f45fbee3100ea01e7= 7b06352bd55ac 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2283,11 +2283,11 @@ static bool can_use_gic_priorities(const struct arm= 64_cpu_capabilities *entry, int scope) { /* - * ARM64_HAS_GIC_CPUIF_SYSREGS has a lower index, and is a boot CPU + * ARM64_HAS_GICV3_CPUIF has a lower index, and is a boot CPU * feature, so will be detected earlier. */ - BUILD_BUG_ON(ARM64_HAS_GIC_PRIO_MASKING <=3D ARM64_HAS_GIC_CPUIF_SYSREGS); - if (!cpus_have_cap(ARM64_HAS_GIC_CPUIF_SYSREGS)) + BUILD_BUG_ON(ARM64_HAS_GIC_PRIO_MASKING <=3D ARM64_HAS_GICV3_CPUIF); + if (!cpus_have_cap(ARM64_HAS_GICV3_CPUIF)) return false; =20 return enable_pseudo_nmi; @@ -2483,8 +2483,8 @@ static const struct arm64_cpu_capabilities arm64_feat= ures[] =3D { .matches =3D has_always, }, { - .desc =3D "GIC system register CPU interface", - .capability =3D ARM64_HAS_GIC_CPUIF_SYSREGS, + .desc =3D "GICv3 CPU interface", + .capability =3D ARM64_HAS_GICV3_CPUIF, .type =3D ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, .matches =3D has_useable_gicv3_cpuif, ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, GIC, IMP) diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 772c1b008e437ed34cedb1c0f663c4dcea8f6759..860ec49cc0530885c138b7dc7f6= 7d58cd69b2593 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -34,7 +34,7 @@ HAS_GENERIC_AUTH HAS_GENERIC_AUTH_ARCH_QARMA3 HAS_GENERIC_AUTH_ARCH_QARMA5 HAS_GENERIC_AUTH_IMP_DEF -HAS_GIC_CPUIF_SYSREGS +HAS_GICV3_CPUIF HAS_GIC_PRIO_MASKING HAS_GIC_PRIO_RELAXED_SYNC HAS_HCR_NV1 diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 6503573557fdf295bc543b16b64e3e7dd6841321..1269ab8eb726afbb80849fd0626= 12861680cb4d1 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -54,7 +54,7 @@ =20 static void gic_check_cpu_features(void) { - WARN_TAINT_ONCE(this_cpu_has_cap(ARM64_HAS_GIC_CPUIF_SYSREGS), + WARN_TAINT_ONCE(this_cpu_has_cap(ARM64_HAS_GICV3_CPUIF), TAINT_CPU_OUT_OF_SPEC, "GICv3 system registers enabled, broken firmware!\n"); } --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 26DFF283151; Tue, 6 May 2025 12:25:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534315; cv=none; b=T58pBQ7QFS4iUOl6aiAJexuu9WlDb1Hm2F8V4gXuJDeuDRSYQ3jEzQLU9nBsnGOry3/uE5w+/MHIxYntHjDhbAVDpzzItXrmqz3eK9KeUOyUgc9HtNn8iJwITvpSM1JYhn7dDCtNVWKUJJfEsDhJrQ2GESTQ0D7GOFReEWaZFlk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534315; c=relaxed/simple; bh=dDrbPic70xFVMnGI2U6eslEy81yc+v4juJuGar89STY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GLZkslsu+o2SqS0BEvk7L16t5jBfU2jI74YVLsiyuICpwblbTDYEGgxx38LweVXtb6su7kxNxuht/onevTGMqy8230Em9QFXqVK+ZKEfEbVos/PJIq6KpCOMhGNvic6kq66EjqulGSIi2AAlKFgBE3mtG1MQzexJd0TTu03TwcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LbjSjXAV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LbjSjXAV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 20921C4CEED; Tue, 6 May 2025 12:25:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534315; bh=dDrbPic70xFVMnGI2U6eslEy81yc+v4juJuGar89STY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LbjSjXAVhVSlEHcrJzX7tgIA89wQSsrb4eBKyzvPN3BFVrT5I+VhjxmR93MK4f8xk vBsXVFaL9vnObqFl9NCj7nCsNX2+T4Hky5kCCk8pW5om9qUQmAuei/8mhic7+yXnAV YrEtF1Lnq5CCc6UinWafNu7i7SVBcAYrqZoVMJX7uZ4r61CMupczbQJrICKbzDItF1 YXg9mPeQhKV0CflYou/kMFz4Cq8p8v5QBAb3onCj2dK0mQ/cVwVBV8EPN1Ol0Klh5w 1g8cXa0DDA/RHiXHhIbG+18fx2CR+sCESRONWTtAJYWAeP88wbMq7/SMCpS0fSmGKV vRb5G+7I54q+A== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:46 +0200 Subject: [PATCH v3 17/25] arm64: cpucaps: Add GICv5 CPU interface (GCIE) capability Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-17-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Implement the GCIE capability as a strict boot cpu capability to detect whether architectural GICv5 support is available in HW. Plug it in with a naming consistent with the existing GICv3 CPU interface capability. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/kernel/cpufeature.c | 7 +++++++ arch/arm64/tools/cpucaps | 1 + 2 files changed, 8 insertions(+) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index cbb49de451f45fbee3100ea01e77b06352bd55ac..4d5163a20ee0fb09380ea5f1f2d= 37afb7257edfb 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -3041,6 +3041,13 @@ static const struct arm64_cpu_capabilities arm64_fea= tures[] =3D { .matches =3D has_pmuv3, }, #endif + { + .desc =3D "GICv5 CPU interface", + .type =3D ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, + .capability =3D ARM64_HAS_GICV5_CPUIF, + .matches =3D has_cpuid_feature, + ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, GCIE, IMP) + }, {}, }; =20 diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 860ec49cc0530885c138b7dc7f67d58cd69b2593..c36f4165e2bb460abde81baf453= 199f62dd265b0 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -35,6 +35,7 @@ HAS_GENERIC_AUTH_ARCH_QARMA3 HAS_GENERIC_AUTH_ARCH_QARMA5 HAS_GENERIC_AUTH_IMP_DEF HAS_GICV3_CPUIF +HAS_GICV5_CPUIF HAS_GIC_PRIO_MASKING HAS_GIC_PRIO_RELAXED_SYNC HAS_HCR_NV1 --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7DF2283151; Tue, 6 May 2025 12:25:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534320; cv=none; b=cAdJoh/CYYvN/zscem5YYCBE7zHCm2aTv50d+WEOhO4SR1prQQmUJrCFK9MUjlVpcI21DLW3ic/ezd/bT5PuqLvHVo7eB5kztUgMRdWm0GGc1CH/2xTXqasVG9537xsVhBhV+0BPDwV0yWW2OFRopB4QSIT5nQCsCcP90+lCFgU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534320; c=relaxed/simple; bh=WxlJpUqowBsQvYZOUMs8IGUAxzbj1n5Ter/RIBHuc/M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BckCMrtbWiLFT4Cb3GeknD9CChXE6BLG6o3MrD60Pvn7idTa8ubO1IzSKaPiCtqbrUW92D6PRxPgqns3NA/Axi3MW6vV4Su1PDE10fxF1FN5zBWLY/+QnngMEPLifC4M4U00CugfjWsllqYE9Ah9w+NZPksa1DwMi0YpL3nTn1M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hinV72AX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hinV72AX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85DC8C4CEE4; Tue, 6 May 2025 12:25:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534319; bh=WxlJpUqowBsQvYZOUMs8IGUAxzbj1n5Ter/RIBHuc/M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hinV72AXyN4gMzehiQPaIjiUrfqq8TQ33Xsdh9/JOsKS7V2TvmivTwe3fD+7p+07k wGHJJ3tELeWyHpP/CeU0D2oW6Iy5krz5jo1bnBVRgghbhvKxt/NseC3i1i0DnG5B5l IfzBVJJu/PGgWQ+rMSvAKVa7/RcapC/CWe6dCwCIlbI1lo4JN4pa8PJBkSgwZKed7P HhakYC36VbZMK0IpGDoVB9E8R+y1U0jqSWkyWRpeheoFsej+kheEiFczybDUGcE0co EOY9Dp/+qLOPKBq/4fr81rmq8hGGP6mZ/GEqB6FcUjbc+vq+JprpkDEAe9+4YTz7K1 cMBtQ8R/BwkcA== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:47 +0200 Subject: [PATCH v3 18/25] arm64: smp: Support non-SGIs for IPIs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-18-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 From: Marc Zyngier The arm64 arch has relied so far on GIC architectural software generated interrupt (SGIs) to handle IPIs. Those are per-cpu software generated interrupts. arm64 architecture code that allocates the IPIs virtual IRQs and IRQ descriptors was written accordingly. On GICv5 systems, IPIs are implemented using LPIs that are not per-cpu interrupts - they are just normal routable IRQs. Add arch code to set-up IPIs on systems where they are handled using normal routable IRQs. For those systems, force the IRQ affinity (and make it immutable) to the cpu a given IRQ was assigned to. Signed-off-by: Marc Zyngier [timothy.hayes@arm.com: fixed ipi/irq conversion, irq flags] Signed-off-by: Timothy Hayes [lpieralisi: changed affinity set-up, log] Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas --- arch/arm64/include/asm/smp.h | 7 ++- arch/arm64/kernel/smp.c | 139 ++++++++++++++++++++++++++++++++-------= ---- 2 files changed, 111 insertions(+), 35 deletions(-) diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 2510eec026f7e3d6f0ecf1197c3a81b183ddd216..d6fd6efb66a673ae33825971e4a= a07e791c02ee5 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -53,7 +53,12 @@ extern void smp_init_cpus(void); /* * Register IPI interrupts with the arch SMP code */ -extern void set_smp_ipi_range(int ipi_base, int nr_ipi); +extern void set_smp_ipi_range_percpu(int ipi_base, int nr_ipi, int ncpus); + +static inline void set_smp_ipi_range(int ipi_base, int n) +{ + set_smp_ipi_range_percpu(ipi_base, n, 0); +} =20 /* * Called from the secondary holding pen, this is the secondary CPU entry = point. diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 3b3f6b56e733039cad7ff5b8995db16a68f3c762..3f3712e47c94c62836fb89cd4bf= b3595fbb41557 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -83,7 +83,26 @@ enum ipi_msg_type { =20 static int ipi_irq_base __ro_after_init; static int nr_ipi __ro_after_init =3D NR_IPI; -static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init; + +struct ipi_descs { + struct irq_desc *descs[MAX_IPI]; +}; + +static DEFINE_PER_CPU(struct ipi_descs, pcpu_ipi_desc); + +#define get_ipi_desc(__cpu, __ipi) (per_cpu_ptr(&pcpu_ipi_desc, __cpu)->de= scs[__ipi]) + +static bool percpu_ipi_descs __ro_after_init; + +static int ipi_to_irq(int ipi, int cpu) +{ + return ipi_irq_base + (cpu * nr_ipi) + ipi; +} + +static int irq_to_ipi(int irq) +{ + return (irq - ipi_irq_base) % nr_ipi; +} =20 static bool crash_stop; =20 @@ -844,7 +863,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, prec >=3D 4 ? " " : ""); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu)); + seq_printf(p, "%10u ", irq_desc_kstat_cpu(get_ipi_desc(cpu, i), cpu)); seq_printf(p, " %s\n", ipi_types[i]); } =20 @@ -919,7 +938,13 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int= cpu, struct pt_regs *regs =20 static void arm64_backtrace_ipi(cpumask_t *mask) { - __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask); + unsigned int cpu; + + if (!percpu_ipi_descs) + __ipi_send_mask(get_ipi_desc(0, IPI_CPU_BACKTRACE), mask); + else + for_each_cpu(cpu, mask) + __ipi_send_single(get_ipi_desc(cpu, IPI_CPU_BACKTRACE), cpu); } =20 void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu) @@ -944,7 +969,7 @@ void kgdb_roundup_cpus(void) if (cpu =3D=3D this_cpu) continue; =20 - __ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu); + __ipi_send_single(get_ipi_desc(cpu, IPI_KGDB_ROUNDUP), cpu); } } #endif @@ -1013,14 +1038,21 @@ static void do_handle_IPI(int ipinr) =20 static irqreturn_t ipi_handler(int irq, void *data) { - do_handle_IPI(irq - ipi_irq_base); + do_handle_IPI(irq_to_ipi(irq)); return IRQ_HANDLED; } =20 static void smp_cross_call(const struct cpumask *target, unsigned int ipin= r) { + unsigned int cpu; + trace_ipi_raise(target, ipi_types[ipinr]); - __ipi_send_mask(ipi_desc[ipinr], target); + + if (!percpu_ipi_descs) + __ipi_send_mask(get_ipi_desc(0, ipinr), target); + else + for_each_cpu(cpu, target) + __ipi_send_single(get_ipi_desc(cpu, ipinr), cpu); } =20 static bool ipi_should_be_nmi(enum ipi_msg_type ipi) @@ -1046,11 +1078,15 @@ static void ipi_setup(int cpu) return; =20 for (i =3D 0; i < nr_ipi; i++) { - if (ipi_should_be_nmi(i)) { - prepare_percpu_nmi(ipi_irq_base + i); - enable_percpu_nmi(ipi_irq_base + i, 0); + if (!percpu_ipi_descs) { + if (ipi_should_be_nmi(i)) { + prepare_percpu_nmi(ipi_irq_base + i); + enable_percpu_nmi(ipi_irq_base + i, 0); + } else { + enable_percpu_irq(ipi_irq_base + i, 0); + } } else { - enable_percpu_irq(ipi_irq_base + i, 0); + enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, i))); } } } @@ -1064,44 +1100,79 @@ static void ipi_teardown(int cpu) return; =20 for (i =3D 0; i < nr_ipi; i++) { - if (ipi_should_be_nmi(i)) { - disable_percpu_nmi(ipi_irq_base + i); - teardown_percpu_nmi(ipi_irq_base + i); + if (!percpu_ipi_descs) { + if (ipi_should_be_nmi(i)) { + disable_percpu_nmi(ipi_irq_base + i); + teardown_percpu_nmi(ipi_irq_base + i); + } else { + disable_percpu_irq(ipi_irq_base + i); + } } else { - disable_percpu_irq(ipi_irq_base + i); + disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, i))); } } } #endif =20 -void __init set_smp_ipi_range(int ipi_base, int n) +static void ipi_setup_ppi(int ipi) +{ + int err, irq, cpu; + + irq =3D ipi_irq_base + ipi; + + if (ipi_should_be_nmi(irq)) { + err =3D request_percpu_nmi(irq, ipi_handler, "IPI", &irq_stat); + WARN(err, "Could not request IRQ %d as NMI, err=3D%d\n", irq, err); + } else { + err =3D request_percpu_irq(irq, ipi_handler, "IPI", &irq_stat); + WARN(err, "Could not request IRQ %d as IRQ, err=3D%d\n", irq, err); + } + + for_each_possible_cpu(cpu) + get_ipi_desc(cpu, ipi) =3D irq_to_desc(irq); + + irq_set_status_flags(irq, IRQ_HIDDEN); +} + +static void ipi_setup_lpi(int ipi, int ncpus) +{ + for (int cpu =3D 0; cpu < ncpus; cpu++) { + int err, irq; + + irq =3D ipi_to_irq(ipi, cpu); + + err =3D irq_force_affinity(irq, cpumask_of(cpu)); + + WARN(err, "Could not force affinity IRQ %d, err=3D%d\n", irq, err); + + err =3D request_irq(irq, ipi_handler, IRQF_NO_AUTOEN, "IPI", + &irq_stat); + + WARN(err, "Could not request IRQ %d, err=3D%d\n", irq, err); + + irq_set_status_flags(irq, (IRQ_HIDDEN | IRQ_NO_BALANCING_MASK)); + + get_ipi_desc(cpu, ipi) =3D irq_to_desc(irq); + } +} + +void __init set_smp_ipi_range_percpu(int ipi_base, int n, int ncpus) { int i; =20 WARN_ON(n < MAX_IPI); nr_ipi =3D min(n, MAX_IPI); =20 - for (i =3D 0; i < nr_ipi; i++) { - int err; - - if (ipi_should_be_nmi(i)) { - err =3D request_percpu_nmi(ipi_base + i, ipi_handler, - "IPI", &irq_stat); - WARN(err, "Could not request IPI %d as NMI, err=3D%d\n", - i, err); - } else { - err =3D request_percpu_irq(ipi_base + i, ipi_handler, - "IPI", &irq_stat); - WARN(err, "Could not request IPI %d as IRQ, err=3D%d\n", - i, err); - } - - ipi_desc[i] =3D irq_to_desc(ipi_base + i); - irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); - } - + percpu_ipi_descs =3D !!ncpus; ipi_irq_base =3D ipi_base; =20 + for (i =3D 0; i < nr_ipi; i++) { + if (!percpu_ipi_descs) + ipi_setup_ppi(i); + else + ipi_setup_lpi(i, ncpus); + } + /* Setup the boot CPU immediately */ ipi_setup(smp_processor_id()); } --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0EAA283151; Tue, 6 May 2025 12:25:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534324; cv=none; b=OaVlWwJeS5Q0DIZ8MhbCQ8XwdIh8aEUqncP2xCPw0P7sMWOdVzs1aDTsz5O+H8mTwnzWdHZu+uktYCxEjlfVfmnco0JMN7VjE0in87Eu3Gbua6sJ48eoRADBVlrhRFYmE07IzOQ3Whf7s3Kurc0LRXr4qeWIC1CUMICQ0Iqp1vg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534324; c=relaxed/simple; bh=LkJPqDgTcvITvCjal2jF9oi6QEuwQiB0J4qVejeTgGo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DBNgvfkiYLhrrIPZ4jTHcIST0j3WwnJ/rgy5is817hva+G0V/OtPT7AtodcWnJ0u+HL9x2WOo9Bk++AarEmzoIeZSYapbPYRdLDMSzOYFAGrT+Pm3GohS+Zx6cFOiprs3SC7XF1AjW30R8lMq92K5iV2G5oFdQ/czFqpIVuZS/8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=si/dNJrI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="si/dNJrI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E91D6C4CEED; Tue, 6 May 2025 12:25:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534323; bh=LkJPqDgTcvITvCjal2jF9oi6QEuwQiB0J4qVejeTgGo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=si/dNJrItQIGWeK2KZFfpSsZviqgsXgarUFlD4/UIoW4g1I6Gr0wl47GRXx5tTTO5 kIHzMQS3GNk3BTCoW/Wv/vPVHPuqIuVwb+QmQ4jA7kiTuIVvxPf8MfXL3V5vKTrYlV wqaK354RaMvOqz94y8q92UqdXvFuKez4Rtx17rqc9ts7pUQVLKXJX9Y8dtIa7FeHH6 TzblnceZwpLe0ws8vrXYL2pUy7ZezzU0M3n0a07F7mI1KIrl3z/BYJemAHR6iBGhiL cWKCiJiQZyxsjRjdH/YdlBiEC1lRHMmXdukvilgD2Jn9y8eBIeSxjj6z30YKLvZ42G f/zKEDtHlKJhw== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:48 +0200 Subject: [PATCH v3 19/25] arm64: Add support for GICv5 GSB barriers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-19-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 The GICv5 architecture introduces two barriers instructions (GSB SYS, GSB ACK) that are used to manage interrupt effects. Rework macro used to emit the SB barrier instruction and implement the GSB barriers on top of it. Suggested-by: Marc Zyngier Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/include/asm/barrier.h | 3 +++ arch/arm64/include/asm/sysreg.h | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barr= ier.h index 1ca947d5c93963d33fe8fb02d6037fc71bd9fd7a..f5801b0ba9e9e7e0433f16ffedf= 0ec7dfb3e358e 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -44,6 +44,9 @@ SB_BARRIER_INSN"nop\n", \ ARM64_HAS_SB)) =20 +#define gsb_ack() asm volatile(GSB_ACK_BARRIER_INSN : : : "memory") +#define gsb_sys() asm volatile(GSB_SYS_BARRIER_INSN : : : "memory") + #ifdef CONFIG_ARM64_PSEUDO_NMI #define pmr_sync() \ do { \ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index 2639d3633073de10f5040a7efff059021f847530..e7734f90bb723bfbd8be99f16dd= 6d6fdc7fa57e8 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -112,10 +112,14 @@ /* Register-based PAN access, for save/restore purposes */ #define SYS_PSTATE_PAN sys_reg(3, 0, 4, 2, 3) =20 -#define __SYS_BARRIER_INSN(CRm, op2, Rt) \ - __emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f)) +#define __SYS_BARRIER_INSN(op0, op1, CRn, CRm, op2, Rt) \ + __emit_inst(0xd5000000 | \ + sys_insn((op0), (op1), (CRn), (CRm), (op2)) | \ + ((Rt) & 0x1f)) =20 -#define SB_BARRIER_INSN __SYS_BARRIER_INSN(0, 7, 31) +#define SB_BARRIER_INSN __SYS_BARRIER_INSN(0, 3, 3, 0, 7, 31) +#define GSB_SYS_BARRIER_INSN __SYS_BARRIER_INSN(1, 0, 12, 0, 0, 31) +#define GSB_ACK_BARRIER_INSN __SYS_BARRIER_INSN(1, 0, 12, 0, 1, 31) =20 #define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) #define SYS_DC_IGSW sys_insn(1, 0, 7, 6, 4) --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94CD727FB29; Tue, 6 May 2025 12:25:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534328; cv=none; b=hyArGtCGPp9hucFHurt8RAQeWjgTrYJ/eZ9KbRwCqA3or1LkquXoz5DxGuah9zTYEniu/IjkNMuu0VC9HC4aKVqWByHDa0LRnS61qZ5g6ekT/GaU1zH7cLwpn8VKZPvh8etDC8Qs9/b5/KbxeQFCP8++3PTuki31oavl5IKxwyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534328; c=relaxed/simple; bh=pIOZvsE7m06vebtQtAxWdk9T0aeG70Xvc3Xwvn19H2g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gQ2s9nbRshAs9GFQjdOTsiMrBMnN3eeMTkpkMvDAb0CzGa2G8XGV1XbzL7Fj8PjpprwGybZMHJkOM5PYg0iXSPWmlEwAHnuS5aui88+EsT8x1WdLDK5m0uNrorya1SgXIH0DCAVQQsZypfIkom2qoMNlKEzGdhmHmHESFHdwZvs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f43g8l6p; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f43g8l6p" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5DDBBC4CEE4; Tue, 6 May 2025 12:25:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534328; bh=pIOZvsE7m06vebtQtAxWdk9T0aeG70Xvc3Xwvn19H2g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=f43g8l6piXDG9rpTD7ycL7wckvMcQ+sGyoXrvDx8tyZOWF8DtXg4j+pCdeF8h/N4+ ukkTraYk0cck0pFsEiYTDa6yqXcoYu6K/XJWOzdaWtlqEkbpjUoKfJ6KRTMF/3d5bk FTJ6KKUyEvvFLqZVet8Xyr6RHiVqsrfMgo3oXPbsIyPKst8GyelovxgLLbBLOc3Mc3 RtZ3ASQhKqMO7kxwLwyG/htf4ZRIJADBf15few0hWbw/DGoiFoPelNxy303Lq4tnRR ytwHOPG8He51w1FRND/RRMf7EQCcEjUpb4BTd5COjL/uk6uP3UksgylmgCj27/dv7k d8AjiUwA16eiQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:49 +0200 Subject: [PATCH v3 20/25] irqchip/gic-v5: Add GICv5 PPI support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-20-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 The GICv5 CPU interface implements support for PE-Private Peripheral Interrupts (PPI), that are handled (enabled/prioritized/delivered) entirely within the CPU interface hardware. To enable PPI interrupts, implement the baseline GICv5 host kernel driver infrastructure required to handle interrupts on a GICv5 system. Add the exception handling code path and definitions for GICv5 instructions. Add GICv5 PPI handling code as a specific IRQ domain to: - Set-up PPI priority - Manage PPI configuration and state - Manage IRQ flow handler - IRQs allocation/free - Hook-up a PPI specific IRQchip to provide the relevant methods PPI IRQ priority is chosen as the minimum allowed priority by the system design (after probing the number of priority bits implemented by the CPU interface). Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Thomas Gleixner Cc: Catalin Marinas Cc: Marc Zyngier --- MAINTAINERS | 2 + arch/arm64/include/asm/sysreg.h | 23 ++ drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-gic-v5.c | 454 +++++++++++++++++++++++++++++++++= ++++ include/linux/irqchip/arm-gic-v5.h | 19 ++ 6 files changed, 504 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 1902291c3cccc06d27c5f79123e67774cf9a0e43..49c377febad72e77dd6d480105c= 2b6bffa81f9a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1907,6 +1907,8 @@ M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml +F: drivers/irqchip/irq-gic-v5*.[ch] +F: include/linux/irqchip/arm-gic-v5.h =20 ARM HDLCD DRM DRIVER M: Liviu Dudau diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index e7734f90bb723bfbd8be99f16dd6d6fdc7fa57e8..4b48d00842c5750299f2983ecd7= 2f19f2865c0e3 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1079,6 +1079,29 @@ =20 #define GCS_CAP(x) ((((unsigned long)x) & GCS_CAP_ADDR_MASK) | \ GCS_CAP_VALID_TOKEN) +/* + * Definitions for GICv5 instructions + */ +#define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0) +#define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7) +#define GICV5_OP_GICR_CDIA sys_insn(1, 0, 12, 3, 0) + +/* Shift and mask definitions for GIC CDDI */ +#define GICV5_GIC_CDDI_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDDI_TYPE(r) FIELD_GET(GICV5_GIC_CDDI_TYPE_MASK, r) +#define GICV5_GIC_CDDI_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDDI_ID(r) FIELD_GET(GICV5_GIC_CDDI_ID_MASK, r) + +/* Shift and mask definitions for GICR CDIA */ +#define GICV5_GIC_CDIA_VALID_MASK BIT_ULL(32) +#define GICV5_GIC_CDIA_VALID(r) FIELD_GET(GICV5_GIC_CDIA_VALID_MASK, r) +#define GICV5_GIC_CDIA_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDIA_TYPE(r) FIELD_GET(GICV5_GIC_CDIA_TYPE_MASK, r) +#define GICV5_GIC_CDIA_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDIA_ID(r) FIELD_GET(GICV5_GIC_CDIA_ID_MASK, r) + +#define gicr_insn(insn) read_sysreg_s(GICV5_OP_GICR_##insn) +#define gic_insn(v, insn) write_sysreg_s(v, GICV5_OP_GIC_##insn) =20 #define ARM64_FEATURE_FIELD_BITS 4 =20 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index cec05e443083b8982b3e72f4212d808a22883914..6b3d70924186bd8ca0429483240= 9d1e379c9cbd4 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -54,6 +54,11 @@ config ARM_GIC_V3_ITS_FSL_MC depends on FSL_MC_BUS default ARM_GIC_V3_ITS =20 +config ARM_GIC_V5 + bool + select IRQ_DOMAIN_HIERARCHY + select GENERIC_IRQ_EFFECTIVE_AFF_MASK + config ARM_NVIC bool select IRQ_DOMAIN_HIERARCHY diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 365bcea9a61ff89e2cb41034125b3fc8cd494d81..3f8225bba5f0f9ce5dbb629b6d4= 782eacf85da44 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_ARM_GIC_V3) +=3D irq-gic-v3.o irq-gic-v3-mb= i.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o irq-gic-v= 3-its-msi-parent.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c new file mode 100644 index 0000000000000000000000000000000000000000..29915a82e798211b61b611ed3ad= 457047b299298 --- /dev/null +++ b/drivers/irqchip/irq-gic-v5.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ + +#define pr_fmt(fmt) "GICv5: " fmt + +#include +#include + +#include +#include + +#include +#include + +static u8 pri_bits =3D 5; +#define GICV5_IRQ_PRI_MASK 0x1f +#define GICV5_IRQ_PRI_MI \ + (GICV5_IRQ_PRI_MASK & GENMASK(4, 5 - pri_bits)) + +#define PPI_NR 128 + +static bool gicv5_cpuif_has_gcie(void) +{ + return this_cpu_has_cap(ARM64_HAS_GICV5_CPUIF); +} + +struct gicv5_chip_data { + struct fwnode_handle *fwnode; + struct irq_domain *ppi_domain; +}; + +static struct gicv5_chip_data gicv5_global_data __read_mostly; + +static void gicv5_ppi_priority_init(void) +{ + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR0_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR1_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR2_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR3_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR4_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR5_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR6_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR7_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR8_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR9_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR10_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR11_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR12_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR13_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR14_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR15_EL1= ); + + /* + * Context syncronization required to make sure system register writes + * effects are synchronised. + */ + isb(); +} + +static void gicv5_ppi_irq_mask(struct irq_data *d) +{ + u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + if (d->hwirq < 64) + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER0_EL1, hwirq_id_bit, 0); + else + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER1_EL1, hwirq_id_bit, 0); + + /* + * We must ensure that the disable takes effect immediately to + * guarantee that the lazy-disabled IRQ mechanism works. + * A context synchronization event is required to guarantee it. + * Reference: I_ZLTKB/R_YRGMH GICv5 specification - section 2.9.1. + */ + isb(); +} + +static void gicv5_ppi_irq_unmask(struct irq_data *d) +{ + u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + if (d->hwirq < 64) + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER0_EL1, 0, hwirq_id_bit); + else + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER1_EL1, 0, hwirq_id_bit); + /* + * We must ensure that the enable takes effect in finite time - a + * context synchronization event is required to guarantee it, we + * can not take for granted that would happen (eg a core going straight + * into idle after enabling a PPI). + * Reference: I_ZLTKB/R_YRGMH GICv5 specification - section 2.9.1. + */ + isb(); +} + +static void gicv5_hwirq_eoi(u32 hwirq_id, u8 hwirq_type) +{ + u64 cddi =3D hwirq_id | FIELD_PREP(GICV5_GIC_CDDI_TYPE_MASK, hwirq_type); + + gic_insn(cddi, CDDI); + + gic_insn(0, CDEOI); +} + +static void gicv5_ppi_irq_eoi(struct irq_data *d) +{ + gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_PPI); +} + +#define READ_PPI_REG(irq, reg) \ + ({ \ + u64 __ppi_val; \ + \ + if (irq < 64) \ + __ppi_val =3D read_sysreg_s(SYS_ICC_PPI_##reg##R0_EL1); \ + else \ + __ppi_val =3D read_sysreg_s(SYS_ICC_PPI_##reg##R1_EL1); \ + __ppi_val; \ + }) + +#define WRITE_PPI_REG(set, irq, bit, reg) \ + do { \ + if (set) { \ + if (irq < 64) \ + write_sysreg_s(bit, SYS_ICC_PPI_S##reg##R0_EL1);\ + else \ + write_sysreg_s(bit, SYS_ICC_PPI_S##reg##R1_EL1);\ + } else { \ + if (irq < 64) \ + write_sysreg_s(bit, SYS_ICC_PPI_C##reg##R0_EL1);\ + else \ + write_sysreg_s(bit, SYS_ICC_PPI_C##reg##R1_EL1);\ + } \ + } while (0) + +static int gicv5_ppi_set_type(struct irq_data *d, unsigned int type) +{ + /* + * The PPI trigger mode is not configurable at runtime, + * therefore this function simply confirms that the `type` + * parameter matches what is present. + */ + u64 hmr =3D READ_PPI_REG(d->hwirq, HM); + + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + case IRQ_TYPE_LEVEL_LOW: + if (((hmr >> (d->hwirq % 64)) & 0x1) !=3D GICV5_PPI_HM_LEVEL) + return -EINVAL; + break; + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + if (((hmr >> (d->hwirq % 64)) & 0x1) !=3D GICV5_PPI_HM_EDGE) + return -EINVAL; + break; + default: + pr_debug("Unexpected PPI trigger mode"); + return -EINVAL; + } + + return 0; +} + +static int gicv5_ppi_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *val) +{ + u64 pendr, activer, hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + switch (which) { + case IRQCHIP_STATE_PENDING: + pendr =3D READ_PPI_REG(d->hwirq, SPEND); + + *val =3D !!(pendr & hwirq_id_bit); + + return 0; + case IRQCHIP_STATE_ACTIVE: + activer =3D READ_PPI_REG(d->hwirq, SACTIVE); + + *val =3D !!(activer & hwirq_id_bit); + + return 0; + default: + pr_debug("Unexpected PPI irqchip state\n"); + } + + return -EINVAL; +} + +static int gicv5_ppi_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool val) +{ + u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + switch (which) { + case IRQCHIP_STATE_PENDING: + WRITE_PPI_REG(val, d->hwirq, hwirq_id_bit, PEND); + return 0; + case IRQCHIP_STATE_ACTIVE: + WRITE_PPI_REG(val, d->hwirq, hwirq_id_bit, ACTIVE); + return 0; + default: + pr_debug("Unexpected PPI irqchip state\n"); + } + + return -EINVAL; +} + +static const struct irq_chip gicv5_ppi_irq_chip =3D { + .name =3D "GICv5-PPI", + .irq_mask =3D gicv5_ppi_irq_mask, + .irq_unmask =3D gicv5_ppi_irq_unmask, + .irq_eoi =3D gicv5_ppi_irq_eoi, + .irq_set_type =3D gicv5_ppi_set_type, + .irq_get_irqchip_state =3D gicv5_ppi_irq_get_irqchip_state, + .irq_set_irqchip_state =3D gicv5_ppi_irq_set_irqchip_state, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND +}; + +static int gicv5_irq_ppi_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + if (!is_of_node(fwspec->fwnode)) + return -EINVAL; + + if (fwspec->param_count < 3) + return -EINVAL; + + if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_PPI) + return -EINVAL; + + *hwirq =3D fwspec->param[1]; + *type =3D fwspec->param[2] & IRQ_TYPE_SENSE_MASK; + + return 0; +} + +static int gicv5_irq_ppi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + unsigned int type =3D IRQ_TYPE_NONE; + struct irq_fwspec *fwspec =3D arg; + irq_hw_number_t hwirq; + int ret; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; + + ret =3D gicv5_irq_ppi_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + irq_set_percpu_devid(virq); + irq_domain_set_info(domain, virq, hwirq, &gicv5_ppi_irq_chip, NULL, + handle_percpu_devid_irq, NULL, NULL); + + return 0; +} + +static void gicv5_irq_domain_free(struct irq_domain *domain, unsigned int = virq, + unsigned int nr_irqs) +{ + struct irq_data *d; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return; + + d =3D irq_domain_get_irq_data(domain, virq); + + irq_set_handler(virq, NULL); + irq_domain_reset_irq_data(d); +} + +static int gicv5_irq_ppi_domain_select(struct irq_domain *d, struct irq_fw= spec *fwspec, + enum irq_domain_bus_token bus_token) +{ + if (fwspec->fwnode !=3D d->fwnode) + return 0; + + if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_PPI) + return 0; + + return (d =3D=3D gicv5_global_data.ppi_domain); +} + +static const struct irq_domain_ops gicv5_irq_ppi_domain_ops =3D { + .translate =3D gicv5_irq_ppi_domain_translate, + .alloc =3D gicv5_irq_ppi_domain_alloc, + .free =3D gicv5_irq_domain_free, + .select =3D gicv5_irq_ppi_domain_select +}; + +static void handle_irq_per_domain(u32 hwirq) +{ + u8 hwirq_type =3D FIELD_GET(GICV5_HWIRQ_TYPE, hwirq); + u32 hwirq_id =3D FIELD_GET(GICV5_HWIRQ_ID, hwirq); + struct irq_domain *domain; + + switch (hwirq_type) { + case GICV5_HWIRQ_TYPE_PPI: + domain =3D gicv5_global_data.ppi_domain; + break; + default: + pr_err_once("Unknown IRQ type, bail out\n"); + return; + } + + if (generic_handle_domain_irq(domain, hwirq_id)) { + pr_err_once("Could not handle, hwirq =3D 0x%x", hwirq_id); + gicv5_hwirq_eoi(hwirq_id, hwirq_type); + } +} + +static void __exception_irq_entry gicv5_handle_irq(struct pt_regs *regs) +{ + bool valid; + u32 hwirq; + u64 ia; + + ia =3D gicr_insn(CDIA); + valid =3D GICV5_GIC_CDIA_VALID(ia); + + if (!valid) + return; + + /* + * Ensure that the CDIA instruction effects (ie IRQ activation) are + * completed before handling the interrupt. + */ + gsb_ack(); + + /* + * Ensure instruction ordering between an acknowledgment and subsequent + * instructions in the IRQ handler using an ISB. + */ + isb(); + + hwirq =3D FIELD_GET(GICV5_HWIRQ_INTID, ia); + + handle_irq_per_domain(hwirq); +} + +static void gicv5_cpu_disable_interrupts(void) +{ + u64 cr0; + + cr0 =3D FIELD_PREP(ICC_CR0_EL1_EN, 0); + write_sysreg_s(cr0, SYS_ICC_CR0_EL1); +} + +static void gicv5_cpu_enable_interrupts(void) +{ + u64 cr0, pcr; + + write_sysreg_s(0, SYS_ICC_PPI_ENABLER0_EL1); + write_sysreg_s(0, SYS_ICC_PPI_ENABLER1_EL1); + + gicv5_ppi_priority_init(); + + pcr =3D FIELD_PREP(ICC_PCR_EL1_PRIORITY, GICV5_IRQ_PRI_MI); + write_sysreg_s(pcr, SYS_ICC_PCR_EL1); + + cr0 =3D FIELD_PREP(ICC_CR0_EL1_EN, 1); + write_sysreg_s(cr0, SYS_ICC_CR0_EL1); +} + +static int gicv5_starting_cpu(unsigned int cpu) +{ + if (WARN(!gicv5_cpuif_has_gcie(), + "GICv5 system components present but CPU does not have FEAT_GCIE")) + return -ENODEV; + + gicv5_cpu_enable_interrupts(); + + return 0; +} + +static void __init gicv5_free_domains(void) +{ + if (gicv5_global_data.ppi_domain) + irq_domain_remove(gicv5_global_data.ppi_domain); + + gicv5_global_data.ppi_domain =3D NULL; +} + +static int __init gicv5_init_domains(struct fwnode_handle *handle) +{ + struct irq_domain *d; + + d =3D irq_domain_create_linear(handle, PPI_NR, &gicv5_irq_ppi_domain_ops, + NULL); + if (!d) + return -ENOMEM; + + irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); + gicv5_global_data.ppi_domain =3D d; + + gicv5_global_data.fwnode =3D handle; + + return 0; +} + +static void gicv5_set_cpuif_pribits(void) +{ + u64 icc_idr0 =3D read_sysreg_s(SYS_ICC_IDR0_EL1); + + switch (FIELD_GET(ICC_IDR0_EL1_PRI_BITS, icc_idr0)) { + case ICC_IDR0_EL1_PRI_BITS_4BITS: + pri_bits =3D 4; + break; + case ICC_IDR0_EL1_PRI_BITS_5BITS: + pri_bits =3D 5; + break; + default: + pr_err("Unexpected ICC_IDR0_EL1_PRI_BITS value, default to 4"); + pri_bits =3D 4; + break; + } +} + +static int __init gicv5_of_init(struct device_node *node, struct device_no= de *parent) +{ + int ret; + + ret =3D gicv5_init_domains(&node->fwnode); + if (ret) + return ret; + + gicv5_set_cpuif_pribits(); + + ret =3D gicv5_starting_cpu(smp_processor_id()); + if (ret) + goto out_dom; + + ret =3D set_handle_irq(gicv5_handle_irq); + if (ret) + goto out_int; + + return 0; +out_int: + gicv5_cpu_disable_interrupts(); +out_dom: + gicv5_free_domains(); + + return ret; +} +IRQCHIP_DECLARE(gic_v5, "arm,gic-v5", gicv5_of_init); diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h new file mode 100644 index 0000000000000000000000000000000000000000..cc3da79e615b2b6ee27456e98c1= 7061e4508030f --- /dev/null +++ b/include/linux/irqchip/arm-gic-v5.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 ARM Limited, All Rights Reserved. + */ +#ifndef __LINUX_IRQCHIP_ARM_GIC_V5_H +#define __LINUX_IRQCHIP_ARM_GIC_V5_H + +#include + +#define GICV5_HWIRQ_ID GENMASK(23, 0) +#define GICV5_HWIRQ_TYPE GENMASK(31, 29) +#define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) + +#define GICV5_HWIRQ_TYPE_PPI UL(0x1) + +#define GICV5_PPI_HM_EDGE UL(0x0) +#define GICV5_PPI_HM_LEVEL UL(0x1) + +#endif --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C493283C9F; Tue, 6 May 2025 12:25:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534333; cv=none; b=ZmzxFI1PnD8nO/gG91Nrl02eK4BgWQa2qqYuDgqKm99eSPipdQvZ1DO1mt1U0j6xS+shaxxO6SFxM3mDPCux1ty3o2DS+fYRq0bQYppzBb60eoIisZanrkiRJy94GQqcTkf4FjFo4X3k/fbZB1sGWPPvRLVUXIIdHTmsXEddQjM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534333; c=relaxed/simple; bh=yMZ5B+dNx7E1RrbTLwxb+3GSun9A7kDBT/lx2ve/Vvc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mbcQukN/MYSz5TRl0B4VHFmHiC7oLUvwN87vjTEFqa+1L0BONaw138tjHWn1n3Voxhc6pbuPGVanzA8I99SGN1vq/zj39vGoaUkiOZPqxmXKtdFoe8vAeeaZZ18Qw3io2mkFZLhxINVIjh/U/i3M9prwBwNGXXVcq/VGl9BRvuI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cCV2enun; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cCV2enun" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 07086C4CEF0; Tue, 6 May 2025 12:25:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534333; bh=yMZ5B+dNx7E1RrbTLwxb+3GSun9A7kDBT/lx2ve/Vvc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cCV2enunJlGpSd5odTiC6puYc8VGCk4sjo25TsnmuI4OAvA+azCb4pI7vsSPkueTU t68R114wf368GkYLvH4cMHlwfONYGIEgg8rYTyk8XXQLh6IcjR9moRiBF0LsFOfziQ LYFTUiVmi3XoEqDr4WrsY5LN/nWWmI2Nx6X8oiZ4cydx9kBcBcBVXwcGhR4vXrw2z+ umiWowo6TJzHrKrLF9gsvxPvEJIGuYB0JTJ1v94JcPpREYD+r1a2sivY0GJKAl6jNy u9WXUnC0rowEcLXZcUzwT+mmNqu5es9Jili5mug0Bq3qXpuqSn4W7LKHg4TpHVx12B lMXVBeglUnlzg== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:50 +0200 Subject: [PATCH v3 21/25] irqchip/gic-v5: Add GICv5 IRS/SPI support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-21-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 The GICv5 Interrupt Routing Service (IRS) component implements interrupt management and routing in the GICv5 architecture. A GICv5 system comprises one or more IRSes, that together handle the interrupt routing and state for the system. An IRS supports Shared Peripheral Interrupts (SPIs), that are interrupt sources directly connected to the IRS; they do not rely on memory for storage. The number of supported SPIs is fixed for a given implementation and can be probed through IRS IDR registers. SPI interrupt state and routing are managed through GICv5 instructions. Each core (PE in GICv5 terms) in a GICv5 system is identified with an Interrupt AFFinity ID (IAFFID). An IRS manages a set of cores that are connected to it. Firmware provides a topology description that the driver uses to detect to which IRS a CPU (ie an IAFFID) is associated with. Use probeable information and firmware description to initialize the IRSes and implement GICv5 IRS SPIs support through an SPI-specific IRQ domain. The GICv5 IRS driver: - Probes IRSes in the system to detect SPI ranges - Associates an IRS with a set of cores connected to it - Adds an IRQchip structure for SPI handling SPIs priority is set to a value corresponding to the lowest permissible priority in the system (taking into account the implemented priority bits of the IRS and CPU interface). Since all IRQs are set to the same priority value, the value itself does not matter as long as it is a valid one. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Thomas Gleixner Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/include/asm/sysreg.h | 50 +++++ drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-gic-v5-irs.c | 433 +++++++++++++++++++++++++++++++++= ++++ drivers/irqchip/irq-gic-v5.c | 317 +++++++++++++++++++++++++-- include/linux/irqchip/arm-gic-v5.h | 130 +++++++++++ 5 files changed, 917 insertions(+), 15 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index 4b48d00842c5750299f2983ecd72f19f2865c0e3..c735721cf083e8b59e88bd5888f= a2519f40cc51e 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1082,16 +1082,66 @@ /* * Definitions for GICv5 instructions */ +#define GICV5_OP_GIC_CDAFF sys_insn(1, 0, 12, 1, 3) #define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0) +#define GICV5_OP_GIC_CDDIS sys_insn(1, 0, 12, 1, 0) +#define GICV5_OP_GIC_CDEN sys_insn(1, 0, 12, 1, 1) #define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7) +#define GICV5_OP_GIC_CDPEND sys_insn(1, 0, 12, 1, 4) +#define GICV5_OP_GIC_CDPRI sys_insn(1, 0, 12, 1, 2) +#define GICV5_OP_GIC_CDRCFG sys_insn(1, 0, 12, 1, 5) #define GICV5_OP_GICR_CDIA sys_insn(1, 0, 12, 3, 0) =20 +/* Shift and mask definitions for GIC CDAFF */ +#define GICV5_GIC_CDAFF_IAFFID_MASK GENMASK_ULL(47, 32) +#define GICV5_GIC_CDAFF_IAFFID(r) FIELD_GET(GICV5_GIC_CDAFF_IAFFID_MASK, r) +#define GICV5_GIC_CDAFF_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDAFF_TYPE(r) FIELD_GET(GICV5_GIC_CDAFF_TYPE_MASK, r) +#define GICV5_GIC_CDAFF_IRM_MASK BIT_ULL(28) +#define GICV5_GIC_CDAFF_IRM(r) FIELD_GET(GICV5_GIC_CDAFF_IRM_MASK, r) +#define GICV5_GIC_CDAFF_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDAFF_ID(r) FIELD_GET(GICV5_GIC_CDAFF_ID_MASK, r) + /* Shift and mask definitions for GIC CDDI */ #define GICV5_GIC_CDDI_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDDI_TYPE(r) FIELD_GET(GICV5_GIC_CDDI_TYPE_MASK, r) #define GICV5_GIC_CDDI_ID_MASK GENMASK_ULL(23, 0) #define GICV5_GIC_CDDI_ID(r) FIELD_GET(GICV5_GIC_CDDI_ID_MASK, r) =20 +/* Shift and mask definitions for GIC CDDIS */ +#define GICV5_GIC_CDDIS_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDDIS_TYPE(r) FIELD_GET(GICV5_GIC_CDDIS_TYPE_MASK, r) +#define GICV5_GIC_CDDIS_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDDIS_ID(r) FIELD_GET(GICV5_GIC_CDDIS_ID_MASK, r) + +/* Shift and mask definitions for GIC CDEN */ +#define GICV5_GIC_CDEN_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDEN_TYPE(r) FIELD_GET(GICV5_GIC_CDEN_TYPE_MASK, r) +#define GICV5_GIC_CDEN_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDEN_ID(r) FIELD_GET(GICV5_GIC_CDEN_ID_MASK, r) + +/* Shift and mask definitions for GIC CDPEND */ +#define GICV5_GIC_CDPEND_PENDING_MASK BIT_ULL(32) +#define GICV5_GIC_CDPEND_PENDING(r) FIELD_GET(GICV5_GIC_CDPEND_PENDING_MAS= K, r) +#define GICV5_GIC_CDPEND_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDPEND_TYPE(r) FIELD_GET(GICV5_GIC_CDPEND_TYPE_MASK, r) +#define GICV5_GIC_CDPEND_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDPEND_ID(r) FIELD_GET(GICV5_GIC_CDPEND_ID_MASK, r) + +/* Shift and mask definitions for GIC CDPRI */ +#define GICV5_GIC_CDPRI_PRIORITY_MASK GENMASK_ULL(39, 35) +#define GICV5_GIC_CDPRI_PRIORITY(r) FIELD_GET(GICV5_GIC_CDPRI_PRIORITY_MAS= K, r) +#define GICV5_GIC_CDPRI_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDPRI_TYPE(r) FIELD_GET(GICV5_GIC_CDPRI_TYPE_MASK, r) +#define GICV5_GIC_CDPRI_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDPRI_ID(r) FIELD_GET(GICV5_GIC_CDPRI_ID_MASK, r) + +/* Shift and mask definitions for GIC CDRCFG */ +#define GICV5_GIC_CDRCFG_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDRCFG_TYPE(r) FIELD_GET(GICV5_GIC_CDRCFG_TYPE_MASK, r) +#define GICV5_GIC_CDRCFG_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDRCFG_ID(r) FIELD_GET(GICV5_GIC_CDRCFG_ID_MASK, r) + /* Shift and mask definitions for GICR CDIA */ #define GICV5_GIC_CDIA_VALID_MASK BIT_ULL(32) #define GICV5_GIC_CDIA_VALID(r) FIELD_GET(GICV5_GIC_CDIA_VALID_MASK, r) diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 3f8225bba5f0f9ce5dbb629b6d4782eacf85da44..3d9c47fa3fdf40b7452c059d84f= e8ac24c91bc0f 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -35,7 +35,7 @@ obj-$(CONFIG_ARM_GIC_V3) +=3D irq-gic-v3.o irq-gic-v3-mb= i.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o irq-gic-v= 3-its-msi-parent.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o -obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-= irs.c new file mode 100644 index 0000000000000000000000000000000000000000..e4e0e90993f4b3e901b14d379e2= 19131e634aa75 --- /dev/null +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ + +#define pr_fmt(fmt) "GICv5 IRS: " fmt + +#include +#include + +#include +#include + +#define LPI_ID_BITS_LINEAR 12 + +#define IRS_FLAGS_NON_COHERENT BIT(0) + +static DEFINE_PER_CPU(struct gicv5_irs_chip_data *, per_cpu_irs_data); +static LIST_HEAD(irs_nodes); + +static u32 irs_readl_relaxed(struct gicv5_irs_chip_data *irs_data, + const u32 reg_offset) +{ + return readl_relaxed(irs_data->irs_base + reg_offset); +} + +static void irs_writel_relaxed(struct gicv5_irs_chip_data *irs_data, + const u32 val, const u32 reg_offset) +{ + writel_relaxed(val, irs_data->irs_base + reg_offset); +} + +struct iaffid_entry { + u16 iaffid; + bool valid; +}; + +static DEFINE_PER_CPU(struct iaffid_entry, cpu_iaffid); + +int gicv5_irs_cpu_to_iaffid(int cpuid, u16 *iaffid) +{ + if (!per_cpu(cpu_iaffid, cpuid).valid) { + pr_err("IAFFID for CPU %d has not been initialised\n", cpuid); + return -ENODEV; + } + + *iaffid =3D per_cpu(cpu_iaffid, cpuid).iaffid; + + return 0; +} + +struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id) +{ + struct gicv5_irs_chip_data *irs_data; + u32 min, max; + + list_for_each_entry(irs_data, &irs_nodes, entry) { + if (!irs_data->spi_range) + continue; + + min =3D irs_data->spi_min; + max =3D irs_data->spi_min + irs_data->spi_range - 1; + if (spi_id >=3D min && spi_id <=3D max) + return irs_data; + } + + return NULL; +} + +static int gicv5_irs_wait_for_spi_op(struct gicv5_irs_chip_data *irs_data) +{ + u32 statusr; + int ret; + + ret =3D gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_SPI_STATUS= R, + GICV5_IRS_SPI_STATUSR_IDLE, &statusr); + if (ret) + return ret; + + return !!FIELD_GET(GICV5_IRS_SPI_STATUSR_V, statusr) ? 0 : -EIO; +} + +static int gicv5_irs_wait_for_irs_pe(struct gicv5_irs_chip_data *irs_data, + bool selr) +{ + bool valid =3D true; + u32 statusr; + int ret; + + ret =3D gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_PE_STATUSR, + GICV5_IRS_PE_STATUSR_IDLE, &statusr); + if (ret) + return ret; + + if (selr) + valid =3D !!FIELD_GET(GICV5_IRS_PE_STATUSR_V, statusr); + + return valid ? 0 : -EIO; +} + +static int gicv5_irs_wait_for_pe_selr(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_irs_wait_for_irs_pe(irs_data, true); +} + +static int gicv5_irs_wait_for_pe_cr0(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_irs_wait_for_irs_pe(irs_data, false); +} + +int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gicv5_irs_chip_data *irs_data =3D d->chip_data; + u32 selr, cfgr; + bool level; + int ret; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + level =3D false; + break; + case IRQ_TYPE_LEVEL_HIGH: + case IRQ_TYPE_LEVEL_LOW: + level =3D true; + break; + default: + return -EINVAL; + } + + guard(raw_spinlock)(&irs_data->spi_config_lock); + + selr =3D FIELD_PREP(GICV5_IRS_SPI_SELR_ID, d->hwirq); + irs_writel_relaxed(irs_data, selr, GICV5_IRS_SPI_SELR); + ret =3D gicv5_irs_wait_for_spi_op(irs_data); + if (ret) + return ret; + + cfgr =3D FIELD_PREP(GICV5_IRS_SPI_CFGR_TM, level); + + irs_writel_relaxed(irs_data, cfgr, GICV5_IRS_SPI_CFGR); + ret =3D gicv5_irs_wait_for_spi_op(irs_data); + if (ret) + return ret; + + return 0; +} + +static int gicv5_irs_wait_for_idle(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_CR0, + GICV5_IRS_CR0_IDLE, NULL); +} + +int gicv5_irs_register_cpu(int cpuid) +{ + struct gicv5_irs_chip_data *irs_data; + u32 selr, cr0; + u16 iaffid; + int ret; + + ret =3D gicv5_irs_cpu_to_iaffid(cpuid, &iaffid); + if (ret) { + pr_err("IAFFID for CPU %d has not been initialised\n", cpuid); + return ret; + } + + irs_data =3D per_cpu(per_cpu_irs_data, cpuid); + if (!irs_data) { + pr_err("No IRS associated with CPU %u\n", cpuid); + return -ENXIO; + } + + selr =3D FIELD_PREP(GICV5_IRS_PE_SELR_IAFFID, iaffid); + irs_writel_relaxed(irs_data, selr, GICV5_IRS_PE_SELR); + + ret =3D gicv5_irs_wait_for_pe_selr(irs_data); + if (ret) { + pr_err("IAFFID 0x%x used in IRS_PE_SELR is invalid\n", iaffid); + return -ENXIO; + } + + cr0 =3D FIELD_PREP(GICV5_IRS_PE_CR0_DPS, 0x1); + irs_writel_relaxed(irs_data, cr0, GICV5_IRS_PE_CR0); + + ret =3D gicv5_irs_wait_for_pe_cr0(irs_data); + if (ret) + return ret; + + pr_debug("CPU %d enabled PE IAFFID 0x%x\n", cpuid, iaffid); + + return 0; +} + +static void __init gicv5_irs_init_bases(struct gicv5_irs_chip_data *irs_da= ta, + void __iomem *irs_base, + struct fwnode_handle *handle) +{ + struct device_node *np =3D to_of_node(handle); + u32 cr0, cr1; + + irs_data->fwnode =3D handle; + irs_data->irs_base =3D irs_base; + + if (of_property_read_bool(np, "dma-noncoherent")) { + /* + * A non-coherent IRS implies that some cache levels cannot be + * used coherently by the cores and GIC. Our only option is to mark + * memory attributes for the GIC as non-cacheable; by default, + * non-cacheable memory attributes imply outer-shareable + * shareability, the value written into IRS_CR1_SH is ignored. + */ + cr1 =3D FIELD_PREP(GICV5_IRS_CR1_VPED_WA, GICV5_NO_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPED_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_WA, GICV5_NO_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPET_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMT_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_WA, GICV5_NO_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IC, GICV5_NON_CACHE) | + FIELD_PREP(GICV5_IRS_CR1_OC, GICV5_NON_CACHE); + irs_data->flags |=3D IRS_FLAGS_NON_COHERENT; + } else { + cr1 =3D FIELD_PREP(GICV5_IRS_CR1_VPED_WA, GICV5_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPED_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_WA, GICV5_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPET_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMT_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_WA, GICV5_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_IRS_CR1_OC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_IRS_CR1_SH, GICV5_INNER_SHARE); + } + + irs_writel_relaxed(irs_data, cr1, GICV5_IRS_CR1); + + cr0 =3D FIELD_PREP(GICV5_IRS_CR0_IRSEN, 0x1); + irs_writel_relaxed(irs_data, cr0, GICV5_IRS_CR0); + gicv5_irs_wait_for_idle(irs_data); +} + +static int __init gicv5_irs_of_init_affinity(struct device_node *node, + struct gicv5_irs_chip_data *irs_data, + u8 iaffid_bits) +{ + /* + * Detect IAFFID<->CPU mappings from the device tree and + * record IRS<->CPU topology information. + */ + u16 iaffid_mask =3D GENMASK(iaffid_bits - 1, 0); + u16 *iaffids __free(kfree) =3D NULL; + int ret, i, ncpus, niaffids; + + ncpus =3D of_property_count_elems_of_size(node, "cpus", sizeof(u32)); + if (ncpus < 0) + return -EINVAL; + + niaffids =3D of_property_count_elems_of_size(node, "arm,iaffids", + sizeof(u16)); + if (niaffids !=3D ncpus) + return -EINVAL; + + iaffids =3D kcalloc(niaffids, sizeof(*iaffids), GFP_KERNEL); + if (!iaffids) + return -ENOMEM; + + ret =3D of_property_read_u16_array(node, "arm,iaffids", iaffids, niaffids= ); + if (ret) + return ret; + + for (i =3D 0; i < ncpus; i++) { + struct device_node *cpu_node; + u32 cpu_phandle; + int cpu; + + if (of_property_read_u32_index(node, "cpus", i, &cpu_phandle)) + continue; + + cpu_node =3D of_find_node_by_phandle(cpu_phandle); + if (WARN_ON(!cpu_node)) + continue; + + cpu =3D of_cpu_node_to_id(cpu_node); + of_node_put(cpu_node); + if (WARN_ON(cpu < 0)) + continue; + + if (iaffids[i] & ~iaffid_mask) { + pr_warn("CPU %d iaffid 0x%x exceeds IRS iaffid bits\n", + cpu, iaffids[i]); + continue; + } + + per_cpu(cpu_iaffid, cpu).iaffid =3D iaffids[i]; + per_cpu(cpu_iaffid, cpu).valid =3D true; + + // We also know that the CPU is connected to this IRS + per_cpu(per_cpu_irs_data, cpu) =3D irs_data; + } + + return ret; +} + +static void irs_setup_pri_bits(u32 idr1) +{ + switch (FIELD_GET(GICV5_IRS_IDR1_PRIORITY_BITS, idr1)) { + case GICV5_IRS_IDR1_PRIORITY_BITS_1BITS: + gicv5_global_data.irs_pri_bits =3D 1; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_2BITS: + gicv5_global_data.irs_pri_bits =3D 2; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_3BITS: + gicv5_global_data.irs_pri_bits =3D 3; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_4BITS: + gicv5_global_data.irs_pri_bits =3D 4; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_5BITS: + gicv5_global_data.irs_pri_bits =3D 5; + break; + default: + pr_warn("Detected wrong IDR priority bits value 0x%lx\n", + FIELD_GET(GICV5_IRS_IDR1_PRIORITY_BITS, idr1)); + gicv5_global_data.irs_pri_bits =3D 1; + break; + } +} + +static int __init gicv5_irs_init(struct device_node *node) +{ + struct gicv5_irs_chip_data *irs_data; + void __iomem *irs_base; + u32 idr, spi_count; + u8 iaffid_bits; + int ret; + + irs_data =3D kzalloc(sizeof(*irs_data), GFP_KERNEL); + if (!irs_data) + return -ENOMEM; + + raw_spin_lock_init(&irs_data->spi_config_lock); + + irs_base =3D of_io_request_and_map(node, 0, "IRS"); + if (IS_ERR(irs_base)) { + pr_err("%pOF: unable to map GICv5 IRS registers\n", node); + ret =3D PTR_ERR(irs_base); + goto out_err; + } + + gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode); + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); + iaffid_bits =3D FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1; + + ret =3D gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits); + if (ret) { + pr_err("Failed to parse CPU IAFFIDs from the device tree!\n"); + goto out_iomem; + } + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR7); + irs_data->spi_min =3D FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr); + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR6); + irs_data->spi_range =3D FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr); + + if (irs_data->spi_range) { + pr_info("%s detected SPI range [%u-%u]\n", + of_node_full_name(node), + irs_data->spi_min, + irs_data->spi_min + + irs_data->spi_range - 1); + } + + /* + * Do the global setting only on the first IRS. + * Global properties (iaffid_bits, global spi count) are guaranteed to + * be consistent across IRSes by the architecture. + */ + if (list_empty(&irs_nodes)) { + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); + irs_setup_pri_bits(idr); + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR5); + + spi_count =3D FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr); + gicv5_global_data.global_spi_count =3D spi_count; + + pr_debug("Detected %u SPIs globally\n", spi_count); + } + + list_add_tail(&irs_data->entry, &irs_nodes); + + return 0; +out_iomem: + iounmap(irs_base); +out_err: + kfree(irs_data); + return ret; +} + +void __init gicv5_irs_remove(void) +{ + struct gicv5_irs_chip_data *irs_data, *tmp_data; + + list_for_each_entry_safe(irs_data, tmp_data, &irs_nodes, entry) { + iounmap(irs_data->irs_base); + list_del(&irs_data->entry); + kfree(irs_data); + } +} + +int __init gicv5_irs_of_probe(struct device_node *parent) +{ + struct device_node *np; + int ret; + + for_each_available_child_of_node(parent, np) { + if (!of_device_is_compatible(np, "arm,gic-v5-irs")) + continue; + + ret =3D gicv5_irs_init(np); + if (ret) + pr_err("Failed to init IRS %s\n", np->full_name); + } + + return list_empty(&irs_nodes) ? -ENODEV : 0; +} diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index 29915a82e798211b61b611ed3ad457047b299298..e7ff82628ee67f368ea64e5e85e= 4474e6b82ef62 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -26,12 +26,7 @@ static bool gicv5_cpuif_has_gcie(void) return this_cpu_has_cap(ARM64_HAS_GICV5_CPUIF); } =20 -struct gicv5_chip_data { - struct fwnode_handle *fwnode; - struct irq_domain *ppi_domain; -}; - -static struct gicv5_chip_data gicv5_global_data __read_mostly; +struct gicv5_chip_data gicv5_global_data __read_mostly; =20 static void gicv5_ppi_priority_init(void) { @@ -59,6 +54,30 @@ static void gicv5_ppi_priority_init(void) isb(); } =20 +static void gicv5_hwirq_init(irq_hw_number_t hwirq, u8 priority, u8 hwirq_= type) +{ + u64 cdpri, cdaff; + u16 iaffid; + int ret; + + if (hwirq_type =3D=3D GICV5_HWIRQ_TYPE_SPI) { + cdpri =3D FIELD_PREP(GICV5_GIC_CDPRI_PRIORITY_MASK, priority) | + FIELD_PREP(GICV5_GIC_CDPRI_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDPRI_ID_MASK, hwirq); + gic_insn(cdpri, CDPRI); + + ret =3D gicv5_irs_cpu_to_iaffid(smp_processor_id(), &iaffid); + + if (WARN_ON_ONCE(ret)) + return; + + cdaff =3D FIELD_PREP(GICV5_GIC_CDAFF_IAFFID_MASK, iaffid) | + FIELD_PREP(GICV5_GIC_CDAFF_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDAFF_ID_MASK, hwirq); + gic_insn(cdaff, CDAFF); + } +} + static void gicv5_ppi_irq_mask(struct irq_data *d) { u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); @@ -77,6 +96,29 @@ static void gicv5_ppi_irq_mask(struct irq_data *d) isb(); } =20 +static void gicv5_iri_irq_mask(struct irq_data *d, u8 hwirq_type) +{ + u64 cddis =3D d->hwirq | FIELD_PREP(GICV5_GIC_CDDIS_TYPE_MASK, hwirq_type= ); + + gic_insn(cddis, CDDIS); + /* + * We must make sure that GIC CDDIS write effects are propagated + * immediately to make sure the disable takes effect to guarantee + * that the lazy-disabled IRQ mechanism works. + * Rule R_XCLJC states that the effects of a GIC system instruction + * complete in finite time. + * The GSB ensures completion of the GIC instruction and prevents + * loads, stores and GIC instructions from executing part of their + * functionality before the GSB SYS. + */ + gsb_sys(); +} + +static void gicv5_spi_irq_mask(struct irq_data *d) +{ + gicv5_iri_irq_mask(d, GICV5_HWIRQ_TYPE_SPI); +} + static void gicv5_ppi_irq_unmask(struct irq_data *d) { u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); @@ -95,6 +137,22 @@ static void gicv5_ppi_irq_unmask(struct irq_data *d) isb(); } =20 +static void gicv5_iri_irq_unmask(struct irq_data *d, u8 hwirq_type) +{ + u64 cden =3D d->hwirq | FIELD_PREP(GICV5_GIC_CDEN_TYPE_MASK, hwirq_type); + /* + * Rule R_XCLJC states that the effects of a GIC system instruction + * complete in finite time and that's the only requirement when + * unmasking an SPI IRQ. + */ + gic_insn(cden, CDEN); +} + +static void gicv5_spi_irq_unmask(struct irq_data *d) +{ + gicv5_iri_irq_unmask(d, GICV5_HWIRQ_TYPE_SPI); +} + static void gicv5_hwirq_eoi(u32 hwirq_id, u8 hwirq_type) { u64 cddi =3D hwirq_id | FIELD_PREP(GICV5_GIC_CDDI_TYPE_MASK, hwirq_type); @@ -109,6 +167,46 @@ static void gicv5_ppi_irq_eoi(struct irq_data *d) gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_PPI); } =20 +static void gicv5_spi_irq_eoi(struct irq_data *d) +{ + gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_SPI); +} + +static int gicv5_iri_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force, u8 hwirq_type) +{ + int ret, cpuid; + u16 iaffid; + u64 cdaff; + + if (force) + cpuid =3D cpumask_first(mask_val); + else + cpuid =3D cpumask_any_and(mask_val, cpu_online_mask); + + ret =3D gicv5_irs_cpu_to_iaffid(cpuid, &iaffid); + if (ret) + return ret; + + cdaff =3D FIELD_PREP(GICV5_GIC_CDAFF_IAFFID_MASK, iaffid) | + FIELD_PREP(GICV5_GIC_CDAFF_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDAFF_ID_MASK, d->hwirq); + gic_insn(cdaff, CDAFF); + + irq_data_update_effective_affinity(d, cpumask_of(cpuid)); + + return IRQ_SET_MASK_OK_DONE; +} + +static int gicv5_spi_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force) +{ + return gicv5_iri_irq_set_affinity(d, mask_val, force, + GICV5_HWIRQ_TYPE_SPI); +} + #define READ_PPI_REG(irq, reg) \ ({ \ u64 __ppi_val; \ @@ -189,6 +287,47 @@ static int gicv5_ppi_irq_get_irqchip_state(struct irq_= data *d, return -EINVAL; } =20 +static int gicv5_iri_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *val, u8 hwirq_type) +{ + u64 icsr, cdrcfg; + + cdrcfg =3D d->hwirq | FIELD_PREP(GICV5_GIC_CDRCFG_TYPE_MASK, hwirq_type); + + gic_insn(cdrcfg, CDRCFG); + isb(); + icsr =3D read_sysreg_s(SYS_ICC_ICSR_EL1); + + if (FIELD_GET(ICC_ICSR_EL1_F, icsr)) { + pr_err("ICSR_EL1 is invalid\n"); + return -EINVAL; + } + + switch (which) { + case IRQCHIP_STATE_PENDING: + *val =3D !!(FIELD_GET(ICC_ICSR_EL1_Pending, icsr)); + return 0; + + case IRQCHIP_STATE_ACTIVE: + *val =3D !!(FIELD_GET(ICC_ICSR_EL1_Active, icsr)); + return 0; + + default: + pr_debug("Unexpected irqchip_irq_state\n"); + } + + return -EINVAL; +} + +static int gicv5_spi_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *val) +{ + return gicv5_iri_irq_get_irqchip_state(d, which, val, + GICV5_HWIRQ_TYPE_SPI); +} + static int gicv5_ppi_irq_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool val) @@ -209,6 +348,45 @@ static int gicv5_ppi_irq_set_irqchip_state(struct irq_= data *d, return -EINVAL; } =20 +static void gicv5_iri_irq_write_pending_state(struct irq_data *d, bool val, + u8 hwirq_type) +{ + u64 cdpend; + + cdpend =3D FIELD_PREP(GICV5_GIC_CDPEND_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDPEND_ID_MASK, d->hwirq) | + FIELD_PREP(GICV5_GIC_CDPEND_PENDING_MASK, val); + + gic_insn(cdpend, CDPEND); +} + +static void gicv5_spi_irq_write_pending_state(struct irq_data *d, bool val) +{ + gicv5_iri_irq_write_pending_state(d, val, GICV5_HWIRQ_TYPE_SPI); +} + +static int gicv5_spi_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool val) +{ + switch (which) { + case IRQCHIP_STATE_PENDING: + gicv5_spi_irq_write_pending_state(d, val); + break; + default: + pr_debug("Unexpected irqchip_irq_state\n"); + return -EINVAL; + } + + return 0; +} + +static int gicv5_spi_irq_retrigger(struct irq_data *data) +{ + return !gicv5_spi_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, + true); +} + static const struct irq_chip gicv5_ppi_irq_chip =3D { .name =3D "GICv5-PPI", .irq_mask =3D gicv5_ppi_irq_mask, @@ -222,10 +400,26 @@ static const struct irq_chip gicv5_ppi_irq_chip =3D { IRQCHIP_MASK_ON_SUSPEND }; =20 -static int gicv5_irq_ppi_domain_translate(struct irq_domain *d, +static const struct irq_chip gicv5_spi_irq_chip =3D { + .name =3D "GICv5-SPI", + .irq_mask =3D gicv5_spi_irq_mask, + .irq_unmask =3D gicv5_spi_irq_unmask, + .irq_eoi =3D gicv5_spi_irq_eoi, + .irq_set_type =3D gicv5_spi_irq_set_type, + .irq_set_affinity =3D gicv5_spi_irq_set_affinity, + .irq_retrigger =3D gicv5_spi_irq_retrigger, + .irq_get_irqchip_state =3D gicv5_spi_irq_get_irqchip_state, + .irq_set_irqchip_state =3D gicv5_spi_irq_set_irqchip_state, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND +}; + +static int gicv5_irq_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec, irq_hw_number_t *hwirq, - unsigned int *type) + unsigned int *type, + u8 hwirq_type) { if (!is_of_node(fwspec->fwnode)) return -EINVAL; @@ -233,7 +427,7 @@ static int gicv5_irq_ppi_domain_translate(struct irq_do= main *d, if (fwspec->param_count < 3) return -EINVAL; =20 - if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_PPI) + if (fwspec->param[0] !=3D hwirq_type) return -EINVAL; =20 *hwirq =3D fwspec->param[1]; @@ -242,6 +436,15 @@ static int gicv5_irq_ppi_domain_translate(struct irq_d= omain *d, return 0; } =20 +static int gicv5_irq_ppi_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + return gicv5_irq_domain_translate(d, fwspec, hwirq, type, + GICV5_HWIRQ_TYPE_PPI); +} + static int gicv5_irq_ppi_domain_alloc(struct irq_domain *domain, unsigned = int virq, unsigned int nr_irqs, void *arg) { @@ -297,6 +500,63 @@ static const struct irq_domain_ops gicv5_irq_ppi_domai= n_ops =3D { .select =3D gicv5_irq_ppi_domain_select }; =20 +static int gicv5_irq_spi_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + return gicv5_irq_domain_translate(d, fwspec, hwirq, type, + GICV5_HWIRQ_TYPE_SPI); +} + +static int gicv5_irq_spi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + struct gicv5_irs_chip_data *chip_data; + unsigned int type =3D IRQ_TYPE_NONE; + struct irq_fwspec *fwspec =3D arg; + struct irq_data *irqd; + irq_hw_number_t hwirq; + int ret; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; + + ret =3D gicv5_irq_spi_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + irqd =3D irq_desc_get_irq_data(irq_to_desc(virq)); + chip_data =3D gicv5_irs_lookup_by_spi_id(hwirq); + + irq_domain_set_info(domain, virq, hwirq, &gicv5_spi_irq_chip, chip_data, + handle_fasteoi_irq, NULL, NULL); + irq_set_probe(virq); + irqd_set_single_target(irqd); + + gicv5_hwirq_init(hwirq, GICV5_IRQ_PRI_MI, GICV5_HWIRQ_TYPE_SPI); + + return 0; +} + +static int gicv5_irq_spi_domain_select(struct irq_domain *d, struct irq_fw= spec *fwspec, + enum irq_domain_bus_token bus_token) +{ + if (fwspec->fwnode !=3D d->fwnode) + return 0; + + if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_SPI) + return 0; + + return (d =3D=3D gicv5_global_data.spi_domain); +} + +static const struct irq_domain_ops gicv5_irq_spi_domain_ops =3D { + .translate =3D gicv5_irq_spi_domain_translate, + .alloc =3D gicv5_irq_spi_domain_alloc, + .free =3D gicv5_irq_domain_free, + .select =3D gicv5_irq_spi_domain_select +}; static void handle_irq_per_domain(u32 hwirq) { u8 hwirq_type =3D FIELD_GET(GICV5_HWIRQ_TYPE, hwirq); @@ -307,6 +567,9 @@ static void handle_irq_per_domain(u32 hwirq) case GICV5_HWIRQ_TYPE_PPI: domain =3D gicv5_global_data.ppi_domain; break; + case GICV5_HWIRQ_TYPE_SPI: + domain =3D gicv5_global_data.spi_domain; + break; default: pr_err_once("Unknown IRQ type, bail out\n"); return; @@ -379,19 +642,23 @@ static int gicv5_starting_cpu(unsigned int cpu) =20 gicv5_cpu_enable_interrupts(); =20 - return 0; + return gicv5_irs_register_cpu(cpu); } =20 static void __init gicv5_free_domains(void) { if (gicv5_global_data.ppi_domain) irq_domain_remove(gicv5_global_data.ppi_domain); + if (gicv5_global_data.spi_domain) + irq_domain_remove(gicv5_global_data.spi_domain); =20 gicv5_global_data.ppi_domain =3D NULL; + gicv5_global_data.spi_domain =3D NULL; } =20 static int __init gicv5_init_domains(struct fwnode_handle *handle) { + u32 spi_count =3D gicv5_global_data.global_spi_count; struct irq_domain *d; =20 d =3D irq_domain_create_linear(handle, PPI_NR, &gicv5_irq_ppi_domain_ops, @@ -402,6 +669,19 @@ static int __init gicv5_init_domains(struct fwnode_han= dle *handle) irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); gicv5_global_data.ppi_domain =3D d; =20 + if (spi_count) { + d =3D irq_domain_create_linear(handle, spi_count, + &gicv5_irq_spi_domain_ops, NULL); + + if (!d) { + gicv5_free_domains(); + return -ENOMEM; + } + + gicv5_global_data.spi_domain =3D d; + irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); + } + gicv5_global_data.fwnode =3D handle; =20 return 0; @@ -413,14 +693,14 @@ static void gicv5_set_cpuif_pribits(void) =20 switch (FIELD_GET(ICC_IDR0_EL1_PRI_BITS, icc_idr0)) { case ICC_IDR0_EL1_PRI_BITS_4BITS: - pri_bits =3D 4; + gicv5_global_data.cpuif_pri_bits =3D 4; break; case ICC_IDR0_EL1_PRI_BITS_5BITS: - pri_bits =3D 5; + gicv5_global_data.cpuif_pri_bits =3D 5; break; default: pr_err("Unexpected ICC_IDR0_EL1_PRI_BITS value, default to 4"); - pri_bits =3D 4; + gicv5_global_data.cpuif_pri_bits =3D 4; break; } } @@ -429,12 +709,19 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa { int ret; =20 - ret =3D gicv5_init_domains(&node->fwnode); + ret =3D gicv5_irs_of_probe(node); if (ret) return ret; =20 + ret =3D gicv5_init_domains(&node->fwnode); + if (ret) + goto out_irs; + gicv5_set_cpuif_pribits(); =20 + pri_bits =3D min_not_zero(gicv5_global_data.cpuif_pri_bits, + gicv5_global_data.irs_pri_bits); + ret =3D gicv5_starting_cpu(smp_processor_id()); if (ret) goto out_dom; @@ -448,6 +735,8 @@ static int __init gicv5_of_init(struct device_node *nod= e, struct device_node *pa gicv5_cpu_disable_interrupts(); out_dom: gicv5_free_domains(); +out_irs: + gicv5_irs_remove(); =20 return ret; } diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index cc3da79e615b2b6ee27456e98c17061e4508030f..65d5cecf39101f95d4c93ade609= 39fe481d1e466 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -5,6 +5,8 @@ #ifndef __LINUX_IRQCHIP_ARM_GIC_V5_H #define __LINUX_IRQCHIP_ARM_GIC_V5_H =20 +#include + #include =20 #define GICV5_HWIRQ_ID GENMASK(23, 0) @@ -12,8 +14,136 @@ #define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) =20 #define GICV5_HWIRQ_TYPE_PPI UL(0x1) +#define GICV5_HWIRQ_TYPE_SPI UL(0x3) =20 #define GICV5_PPI_HM_EDGE UL(0x0) #define GICV5_PPI_HM_LEVEL UL(0x1) =20 +#define GICV5_NO_READ_ALLOC 0b0 +#define GICV5_READ_ALLOC 0b1 +#define GICV5_NO_WRITE_ALLOC 0b0 +#define GICV5_WRITE_ALLOC 0b1 + +#define GICV5_NON_CACHE 0b00 +#define GICV5_WB_CACHE 0b01 +#define GICV5_WT_CACHE 0b10 + +#define GICV5_NON_SHARE 0b00 +#define GICV5_OUTER_SHARE 0b10 +#define GICV5_INNER_SHARE 0b11 + +#define GICV5_IRS_IDR1 0x0004 +#define GICV5_IRS_IDR2 0x0008 +#define GICV5_IRS_IDR5 0x0014 +#define GICV5_IRS_IDR6 0x0018 +#define GICV5_IRS_IDR7 0x001c +#define GICV5_IRS_CR0 0x0080 +#define GICV5_IRS_CR1 0x0084 +#define GICV5_IRS_SPI_SELR 0x0108 +#define GICV5_IRS_SPI_CFGR 0x0114 +#define GICV5_IRS_SPI_STATUSR 0x0118 +#define GICV5_IRS_PE_SELR 0x0140 +#define GICV5_IRS_PE_STATUSR 0x0144 +#define GICV5_IRS_PE_CR0 0x0148 +#define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) +#define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16) + +#define GICV5_IRS_IDR1_PRIORITY_BITS_1BITS 0b000 +#define GICV5_IRS_IDR1_PRIORITY_BITS_2BITS 0b001 +#define GICV5_IRS_IDR1_PRIORITY_BITS_3BITS 0b010 +#define GICV5_IRS_IDR1_PRIORITY_BITS_4BITS 0b011 +#define GICV5_IRS_IDR1_PRIORITY_BITS_5BITS 0b100 + +#define GICV5_IRS_IDR2_ISTMD_SZ GENMASK(19, 15) +#define GICV5_IRS_IDR2_ISTMD BIT(14) +#define GICV5_IRS_IDR2_IST_L2SZ GENMASK(13, 11) +#define GICV5_IRS_IDR2_IST_LEVELS BIT(10) +#define GICV5_IRS_IDR2_MIN_LPI_ID_BITS GENMASK(9, 6) +#define GICV5_IRS_IDR2_LPI BIT(5) +#define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0) + +#define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0) +#define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0) +#define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0) +#define GICV5_IRS_CR0_IDLE BIT(1) +#define GICV5_IRS_CR0_IRSEN BIT(0) + +#define GICV5_IRS_CR1_VPED_WA BIT(15) +#define GICV5_IRS_CR1_VPED_RA BIT(14) +#define GICV5_IRS_CR1_VMD_WA BIT(13) +#define GICV5_IRS_CR1_VMD_RA BIT(12) +#define GICV5_IRS_CR1_VPET_WA BIT(11) +#define GICV5_IRS_CR1_VPET_RA BIT(10) +#define GICV5_IRS_CR1_VMT_WA BIT(9) +#define GICV5_IRS_CR1_VMT_RA BIT(8) +#define GICV5_IRS_CR1_IST_WA BIT(7) +#define GICV5_IRS_CR1_IST_RA BIT(6) +#define GICV5_IRS_CR1_IC GENMASK(5, 4) +#define GICV5_IRS_CR1_OC GENMASK(3, 2) +#define GICV5_IRS_CR1_SH GENMASK(1, 0) + +#define GICV5_IRS_SPI_STATUSR_V BIT(1) +#define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) + +#define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0) + +#define GICV5_IRS_SPI_CFGR_TM BIT(0) + +#define GICV5_IRS_PE_SELR_IAFFID GENMASK(15, 0) + +#define GICV5_IRS_PE_STATUSR_V BIT(1) +#define GICV5_IRS_PE_STATUSR_IDLE BIT(0) + +#define GICV5_IRS_PE_CR0_DPS BIT(0) + +struct gicv5_chip_data { + struct fwnode_handle *fwnode; + struct irq_domain *ppi_domain; + struct irq_domain *spi_domain; + u32 global_spi_count; + u8 cpuif_pri_bits; + u8 irs_pri_bits; +}; + +extern struct gicv5_chip_data gicv5_global_data __read_mostly; + +struct gicv5_irs_chip_data { + struct list_head entry; + struct fwnode_handle *fwnode; + void __iomem *irs_base; + u32 flags; + u32 spi_min; + u32 spi_range; + raw_spinlock_t spi_config_lock; +}; + +static inline int gicv5_wait_for_op_s_atomic(void __iomem *addr, u32 offse= t, + const char *reg_s, u32 mask, + u32 *val) +{ + void __iomem *reg =3D addr + offset; + u32 tmp; + int ret; + + ret =3D readl_poll_timeout_atomic(reg, tmp, tmp & mask, 1, 10 * USEC_PER_= MSEC); + if (unlikely(ret =3D=3D -ETIMEDOUT)) { + pr_err_ratelimited("%s timeout...\n", reg_s); + return ret; + } + + if (val) + *val =3D tmp; + + return 0; +} + +#define gicv5_wait_for_op_atomic(base, reg, mask, val) \ + gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) + +int gicv5_irs_of_probe(struct device_node *parent); +void gicv5_irs_remove(void); +int gicv5_irs_register_cpu(int cpuid); +int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); +struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); +int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); #endif --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CDEC4280A29; Tue, 6 May 2025 12:25:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534337; cv=none; b=kOjs+GL7l/EeeACTFN64eyzJmSw0FgE15Qj8JsvRIPDBNl4kr9wIeMZkfJ0ip+r2Y7MqsezxdKX+rTzcvkBxNCH2moO1MFXb4Ob59P+IAo3jygOSJWopah4OU5hMqrKI+gWba8wwH1jKQ9E4S2Y6OhC0/TM9hJxrraMFcvZDMvk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534337; c=relaxed/simple; bh=9sXg1ECPH9LlzMy/jHIAp7sDOC1cOpycVlELHsQYxts=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bQB7HtqtIVHi5hJMo5s71ZyofR0TtLwxv2JzKqX75Bii/GsQfNh/Wqmys/e5i237k17N3EivnsvZbQ4Vurn4e+9srY0mkYzvfrHNhsvjWkBri6yFE7b61RFADlk2dpfH5OWa6dckMZKgxPev3zT3lLEc9rJ8DCY7EJTyzvLftBM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SBQ0fh8Z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SBQ0fh8Z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9E62BC4CEEE; Tue, 6 May 2025 12:25:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534337; bh=9sXg1ECPH9LlzMy/jHIAp7sDOC1cOpycVlELHsQYxts=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SBQ0fh8ZE6b1tVHlXzLB5FXIxklo88tynE2/WVUtFguGREO6310CGQJ5lxTQk65AI Wl8qLSb4HNy25c+wE6rYLiWshq691wZyOBvsujqnlvPV5e45HIueWvtNTt9LKXYGT2 SZevROQiuOAti6rBJaKMraWGIdqhlmgfZLTzLgJAHmDX1370uTvfOKNIUw/Zoyr3wY vHamZE0DEmfIi/MPRf/RB99UVq4byDkrZPDkK0SoDP2N6eDgEzyTAQAmiQF7Kfg1c+ ouk5oRjVShzwzNDIqHOqriUzEAVF9DwnoAhedk/NMNoH8oxELN07Cu1I14oQafxbIV slSk8DC6hJuFQ== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:51 +0200 Subject: [PATCH v3 22/25] irqchip/gic-v5: Add GICv5 LPI/IPI support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-22-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 An IRS supports Logical Peripheral Interrupts (LPIs) and implement Linux IPIs on top of it. LPIs are used for interrupt signals that are translated by a GICv5 ITS (Interrupt Translation Service) but also for software generated IRQs - namely interrupts that are not driven by a HW signal, ie IPIs. LPIs rely on memory storage for interrupt routing and state. LPIs state and routing information is kept in the Interrupt State Table (IST). IRSes provide support for 1- or 2-level IST tables configured to support a maximum number of interrupts that depend on the OS configuration and the HW capabilities. On systems that provide 2-level IST support, always allow the maximum number of LPIs; On systems with only 1-level support, limit the number of LPIs to 2^12 to prevent wasting memory (presumably a system that supports a 1-level only IST is not expecting a large number of interrupts). On a 2-level IST system, L2 entries are allocated on demand. The IST table memory is allocated using the kmalloc() interface; the allocation required may be smaller than a page and must be made up of contiguous physical pages if larger than a page. On systems where the IRS is not cache-coherent with the CPUs, cache mainteinance operations are executed to clean and invalidate the allocated memory to the point of coherency making it visible to the IRS components. On GICv5 systems, IPIs are implemented using LPIs. Add an LPI IRQ domain and implement an IPI-specific IRQ domain created as a child/subdomain of the LPI domain to allocate the required number of LPIs needed to implement the IPIs. IPIs are backed by LPIs, add LPIs allocation/de-allocation functions. The LPI INTID namespace is managed using an IDA to alloc/free LPI INTIDs. Associate an IPI irqchip with IPI IRQ descriptors to provide core code with the irqchip.ipi_send_single() method required to raise an IPI. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Thomas Gleixner Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/include/asm/smp.h | 17 ++ arch/arm64/kernel/smp.c | 17 -- drivers/irqchip/irq-gic-v5-irs.c | 361 +++++++++++++++++++++++++++++++++= ++++ drivers/irqchip/irq-gic-v5.c | 284 ++++++++++++++++++++++++++++- include/linux/irqchip/arm-gic-v5.h | 59 ++++++ 5 files changed, 719 insertions(+), 19 deletions(-) diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index d6fd6efb66a673ae33825971e4aa07e791c02ee5..d48ef6d5abcc77d1c06ad8e91e7= 2006acf662078 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -50,6 +50,23 @@ struct seq_file; */ extern void smp_init_cpus(void); =20 +enum ipi_msg_type { + IPI_RESCHEDULE, + IPI_CALL_FUNC, + IPI_CPU_STOP, + IPI_CPU_STOP_NMI, + IPI_TIMER, + IPI_IRQ_WORK, + NR_IPI, + /* + * Any enum >=3D NR_IPI and < MAX_IPI is special and not tracable + * with trace_ipi_* + */ + IPI_CPU_BACKTRACE =3D NR_IPI, + IPI_KGDB_ROUNDUP, + MAX_IPI +}; + /* * Register IPI interrupts with the arch SMP code */ diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 3f3712e47c94c62836fb89cd4bfb3595fbb41557..148145979d83f67469075df1c8b= 5e366ffe9d907 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -64,23 +64,6 @@ struct secondary_data secondary_data; /* Number of CPUs which aren't online, but looping in kernel text. */ static int cpus_stuck_in_kernel; =20 -enum ipi_msg_type { - IPI_RESCHEDULE, - IPI_CALL_FUNC, - IPI_CPU_STOP, - IPI_CPU_STOP_NMI, - IPI_TIMER, - IPI_IRQ_WORK, - NR_IPI, - /* - * Any enum >=3D NR_IPI and < MAX_IPI is special and not tracable - * with trace_ipi_* - */ - IPI_CPU_BACKTRACE =3D NR_IPI, - IPI_KGDB_ROUNDUP, - MAX_IPI -}; - static int ipi_irq_base __ro_after_init; static int nr_ipi __ro_after_init =3D NR_IPI; =20 diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-= irs.c index e4e0e90993f4b3e901b14d379e219131e634aa75..a3de1c1b918c0ae123ae204f0de= a6992db33ecd0 100644 --- a/drivers/irqchip/irq-gic-v5-irs.c +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -5,6 +5,7 @@ =20 #define pr_fmt(fmt) "GICv5 IRS: " fmt =20 +#include #include #include =20 @@ -30,6 +31,335 @@ static void irs_writel_relaxed(struct gicv5_irs_chip_da= ta *irs_data, writel_relaxed(val, irs_data->irs_base + reg_offset); } =20 +static u64 irs_readq_relaxed(struct gicv5_irs_chip_data *irs_data, + const u32 reg_offset) +{ + return readq_relaxed(irs_data->irs_base + reg_offset); +} + +static void irs_writeq_relaxed(struct gicv5_irs_chip_data *irs_data, + const u64 val, const u32 reg_offset) +{ + writeq_relaxed(val, irs_data->irs_base + reg_offset); +} + +/* + * The polling wait (in gicv5_wait_for_op_s_atomic()) on a GIC register + * provides the memory barriers (through MMIO accessors) + * required to synchronize CPU and GIC access to IST memory. + */ +static int gicv5_irs_ist_synchronise(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_IST_STATUSR, + GICV5_IRS_IST_STATUSR_IDLE, NULL); +} + +static int __init gicv5_irs_init_ist_linear(struct gicv5_irs_chip_data *ir= s_data, + unsigned int lpi_id_bits, + unsigned int istsz) +{ + size_t l2istsz; + u32 n, cfgr; + void *ist; + u64 baser; + int ret; + + /* Taken from GICv5 specifications 10.2.1.13 IRS_IST_BASER */ + n =3D max(5, lpi_id_bits + 1 + istsz); + + l2istsz =3D BIT(n + 1); + /* + * Check memory requirements. For a linear IST we cap the + * number of ID bits to a value that should never exceed + * kmalloc interface memory allocation limits, so this + * check is really belt and braces. + */ + if (l2istsz > KMALLOC_MAX_SIZE) { + u8 lpi_id_cap =3D ilog2(KMALLOC_MAX_SIZE) - 2 + istsz; + + pr_warn("Limiting LPI ID bits from %u to %u\n", + lpi_id_bits, lpi_id_cap); + lpi_id_bits =3D lpi_id_cap; + l2istsz =3D KMALLOC_MAX_SIZE; + } + + ist =3D kzalloc(l2istsz, GFP_KERNEL); + if (!ist) + return -ENOMEM; + + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) + dcache_clean_inval_poc((unsigned long)ist, + (unsigned long)ist + l2istsz); + else + dsb(ishst); + + cfgr =3D FIELD_PREP(GICV5_IRS_IST_CFGR_STRUCTURE, + GICV5_IRS_IST_CFGR_STRUCTURE_LINEAR) | + FIELD_PREP(GICV5_IRS_IST_CFGR_ISTSZ, istsz) | + FIELD_PREP(GICV5_IRS_IST_CFGR_L2SZ, + GICV5_IRS_IST_CFGR_L2SZ_4K) | + FIELD_PREP(GICV5_IRS_IST_CFGR_LPI_ID_BITS, lpi_id_bits); + irs_writel_relaxed(irs_data, cfgr, GICV5_IRS_IST_CFGR); + + gicv5_global_data.ist.l2 =3D false; + + baser =3D (virt_to_phys(ist) & GICV5_IRS_IST_BASER_ADDR_MASK) | + FIELD_PREP(GICV5_IRS_IST_BASER_VALID, 0x1); + irs_writeq_relaxed(irs_data, baser, GICV5_IRS_IST_BASER); + + ret =3D gicv5_irs_ist_synchronise(irs_data); + if (ret) { + kfree(ist); + return ret; + } + + return 0; +} + +static int __init gicv5_irs_init_ist_two_level(struct gicv5_irs_chip_data = *irs_data, + unsigned int lpi_id_bits, + unsigned int istsz, + unsigned int l2sz) +{ + __le64 *l1ist; + u32 cfgr, n; + size_t l1sz; + u64 baser; + int ret; + + /* Taken from GICv5 specifications 10.2.1.13 IRS_IST_BASER */ + n =3D max(5, lpi_id_bits - ((10 - istsz) + (2 * l2sz)) + 2); + + l1sz =3D BIT(n + 1); + + l1ist =3D kzalloc(l1sz, GFP_KERNEL); + if (!l1ist) + return -ENOMEM; + + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) + dcache_clean_inval_poc((unsigned long)l1ist, + (unsigned long)l1ist + l1sz); + else + dsb(ishst); + + cfgr =3D FIELD_PREP(GICV5_IRS_IST_CFGR_STRUCTURE, + GICV5_IRS_IST_CFGR_STRUCTURE_TWO_LEVEL) | + FIELD_PREP(GICV5_IRS_IST_CFGR_ISTSZ, istsz) | + FIELD_PREP(GICV5_IRS_IST_CFGR_L2SZ, l2sz) | + FIELD_PREP(GICV5_IRS_IST_CFGR_LPI_ID_BITS, lpi_id_bits); + irs_writel_relaxed(irs_data, cfgr, GICV5_IRS_IST_CFGR); + + /* + * The L2SZ determine bits required at L2 level. Number of bytes + * required by metadata is reported through istsz - the number of bits + * covered by L2 entries scales accordingly. + */ + gicv5_global_data.ist.l2_size =3D BIT(11 + (2 * l2sz) + 1); + gicv5_global_data.ist.l2_bits =3D (10 - istsz) + (2 * l2sz); + gicv5_global_data.ist.l1ist_addr =3D l1ist; + gicv5_global_data.ist.l2 =3D true; + + baser =3D (virt_to_phys(l1ist) & GICV5_IRS_IST_BASER_ADDR_MASK) | + FIELD_PREP(GICV5_IRS_IST_BASER_VALID, 0x1); + irs_writeq_relaxed(irs_data, baser, GICV5_IRS_IST_BASER); + + ret =3D gicv5_irs_ist_synchronise(irs_data); + if (ret) { + kfree(l1ist); + return ret; + } + + return 0; +} + +/* + * Alloc L2 IST entries on demand. + * + * Locking/serialization is guaranteed by irqdomain core code by + * taking the hierarchical domain struct irq_domain.root->mutex. + */ +int gicv5_irs_iste_alloc(const u32 lpi) +{ + struct gicv5_irs_chip_data *irs_data; + unsigned int index; + u32 l2istr, l2bits; + __le64 *l1ist; + size_t l2size; + void *l2ist; + int ret; + + if (!gicv5_global_data.ist.l2) + return 0; + + irs_data =3D per_cpu(per_cpu_irs_data, smp_processor_id()); + if (!irs_data) + return -ENOENT; + + l2size =3D gicv5_global_data.ist.l2_size; + l2bits =3D gicv5_global_data.ist.l2_bits; + + l1ist =3D gicv5_global_data.ist.l1ist_addr; + + index =3D lpi >> l2bits; + + if (FIELD_GET(GICV5_ISTL1E_VALID, le64_to_cpu(l1ist[index]))) + return 0; + + l2ist =3D kzalloc(l2size, GFP_KERNEL); + if (!l2ist) + return -ENOMEM; + + l1ist[index] =3D cpu_to_le64(virt_to_phys(l2ist) & GICV5_ISTL1E_L2_ADDR_M= ASK); + + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) { + dcache_clean_inval_poc((unsigned long)l2ist, + (unsigned long)l2ist + l2size); + dcache_clean_poc((unsigned long)(l1ist + index), + (unsigned long)(l1ist + index) + sizeof(*l1ist)); + } else { + dsb(ishst); + } + + l2istr =3D FIELD_PREP(GICV5_IRS_MAP_L2_ISTR_ID, lpi); + irs_writel_relaxed(irs_data, l2istr, GICV5_IRS_MAP_L2_ISTR); + + ret =3D gicv5_irs_ist_synchronise(irs_data); + if (ret) { + l1ist[index] =3D 0; + kfree(l2ist); + return ret; + } + + /* + * Make sure we invalidate the cache line pulled before the IRS + * had a chance to update the L1 entry and mark it valid. + */ + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) { + /* + * gicv5_irs_ist_synchronise() includes memory + * barriers (MMIO accessors) required to guarantee that the + * following dcache invalidation is not executed before the + * IST mapping operation has completed. + */ + dcache_inval_poc((unsigned long)(l1ist + index), + (unsigned long)(l1ist + index) + sizeof(*l1ist)); + } + + return 0; +} + +/* + * Try to match the L2 IST size to the pagesize, and if this is not possib= le + * pick the smallest supported L2 size in order to minimise the requiremen= t for + * physically contiguous blocks of memory as page-sized allocations are + * guaranteed to be physically contiguous, and are by definition the easie= st to + * find. + * + * Fall back to the smallest supported size (in the event that the pagesize + * itself is not supported) again serves to make it easier to find physica= lly + * contiguous blocks of memory. + */ +static unsigned int gicv5_irs_l2_sz(u32 idr2) +{ + switch (PAGE_SIZE) { + case SZ_64K: + if (GICV5_IRS_IST_L2SZ_SUPPORT_64KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_64K; + fallthrough; + case SZ_16K: + if (GICV5_IRS_IST_L2SZ_SUPPORT_16KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_16K; + fallthrough; + case SZ_4K: + if (GICV5_IRS_IST_L2SZ_SUPPORT_4KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_4K; + break; + } + + if (GICV5_IRS_IST_L2SZ_SUPPORT_16KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_16K; + + return GICV5_IRS_IST_CFGR_L2SZ_64K; +} + +static int __init gicv5_irs_init_ist(struct gicv5_irs_chip_data *irs_data) +{ + u32 lpi_id_bits, idr2_id_bits, idr2_min_lpi_id_bits, + l2_iste_sz, l2sz, l2_iste_sz_split, idr2; + bool two_levels, istmd; + u64 baser; + int ret; + + baser =3D irs_readq_relaxed(irs_data, GICV5_IRS_IST_BASER); + if (FIELD_GET(GICV5_IRS_IST_BASER_VALID, baser)) { + pr_err("IST is marked as valid already; cannot allocate\n"); + return -EPERM; + } + + idr2 =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); + + two_levels =3D !!FIELD_GET(GICV5_IRS_IDR2_IST_LEVELS, idr2); + + idr2_id_bits =3D FIELD_GET(GICV5_IRS_IDR2_ID_BITS, idr2); + idr2_min_lpi_id_bits =3D FIELD_GET(GICV5_IRS_IDR2_MIN_LPI_ID_BITS, idr2); + + /* + * For two level tables we are always supporting the maximum allowed + * number of IDs. + * + * For 1-level tables, we should support a number of bits that + * is >=3D min_lpi_id_bits but cap it to LPI_ID_BITS_LINEAR lest + * the level 1-table gets too large and its memory allocation + * may fail. + */ + if (two_levels) { + lpi_id_bits =3D idr2_id_bits; + } else { + lpi_id_bits =3D max(LPI_ID_BITS_LINEAR, idr2_min_lpi_id_bits); + lpi_id_bits =3D min(lpi_id_bits, idr2_id_bits); + } + + /* + * Cap the ID bits according to the CPUIF supported ID bits + */ + lpi_id_bits =3D min(lpi_id_bits, gicv5_global_data.cpuif_id_bits); + + if (two_levels) + l2sz =3D gicv5_irs_l2_sz(idr2); + + istmd =3D !!FIELD_GET(GICV5_IRS_IDR2_ISTMD, idr2); + + l2_iste_sz =3D GICV5_IRS_IST_CFGR_ISTSZ_4; + + // Only supported if IRS_IDR2.ISTMD is 1 + if (istmd) { + l2_iste_sz_split =3D FIELD_GET(GICV5_IRS_IDR2_ISTMD_SZ, idr2); + + if (lpi_id_bits < l2_iste_sz_split) + l2_iste_sz =3D GICV5_IRS_IST_CFGR_ISTSZ_8; + else + l2_iste_sz =3D GICV5_IRS_IST_CFGR_ISTSZ_16; + } + + /* + * Follow GICv5 specification recommendation to opt in for two + * level tables (ref: 10.2.1.14 IRS_IST_CFGR). + */ + if (two_levels && (lpi_id_bits > ((10 - l2_iste_sz) + (2 * l2sz)))) { + ret =3D gicv5_irs_init_ist_two_level(irs_data, lpi_id_bits, + l2_iste_sz, l2sz); + } else { + ret =3D gicv5_irs_init_ist_linear(irs_data, lpi_id_bits, + l2_iste_sz); + } + if (ret) + return ret; + + gicv5_init_lpis(BIT(lpi_id_bits)); + + return 0; +} + struct iaffid_entry { u16 iaffid; bool valid; @@ -362,6 +692,13 @@ static int __init gicv5_irs_init(struct device_node *n= ode) goto out_iomem; } =20 + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); + if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr), + "LPI support not available - no IPIs, can't proceed\n")) { + ret =3D -ENODEV; + goto out_iomem; + } + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR7); irs_data->spi_min =3D FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr); =20 @@ -391,6 +728,8 @@ static int __init gicv5_irs_init(struct device_node *no= de) spi_count =3D FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr); gicv5_global_data.global_spi_count =3D spi_count; =20 + gicv5_init_lpi_domain(); + pr_debug("Detected %u SPIs globally\n", spi_count); } =20 @@ -408,6 +747,9 @@ void __init gicv5_irs_remove(void) { struct gicv5_irs_chip_data *irs_data, *tmp_data; =20 + gicv5_free_lpi_domain(); + gicv5_deinit_lpis(); + list_for_each_entry_safe(irs_data, tmp_data, &irs_nodes, entry) { iounmap(irs_data->irs_base); list_del(&irs_data->entry); @@ -415,6 +757,25 @@ void __init gicv5_irs_remove(void) } } =20 +int __init gicv5_irs_enable(void) +{ + struct gicv5_irs_chip_data *irs_data; + int ret; + + irs_data =3D list_first_entry_or_null(&irs_nodes, + struct gicv5_irs_chip_data, entry); + if (!irs_data) + return -ENODEV; + + ret =3D gicv5_irs_init_ist(irs_data); + if (ret) { + pr_err("Failed to init IST\n"); + return ret; + } + + return 0; +} + int __init gicv5_irs_of_probe(struct device_node *parent) { struct device_node *np; diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index e7ff82628ee67f368ea64e5e85e4474e6b82ef62..c2c05f4411197365079c7d99766= 5c81e3a0f4b74 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -5,7 +5,9 @@ =20 #define pr_fmt(fmt) "GICv5: " fmt =20 +#include #include +#include #include =20 #include @@ -28,6 +30,42 @@ static bool gicv5_cpuif_has_gcie(void) =20 struct gicv5_chip_data gicv5_global_data __read_mostly; =20 +static DEFINE_IDA(lpi_ida); +static u32 num_lpis; + +void __init gicv5_init_lpis(u32 lpis) +{ + num_lpis =3D lpis; +} + +void __init gicv5_deinit_lpis(void) +{ + num_lpis =3D 0; +} + +static int alloc_lpi(void) +{ + if (!num_lpis) + return -ENOSPC; + + return ida_alloc_max(&lpi_ida, num_lpis - 1, GFP_KERNEL); +} + +static void release_lpi(u32 lpi) +{ + ida_free(&lpi_ida, lpi); +} + +static int gicv5_alloc_lpi(void) +{ + return alloc_lpi(); +} + +static void gicv5_free_lpi(u32 lpi) +{ + release_lpi(lpi); +} + static void gicv5_ppi_priority_init(void) { write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR0_EL1); @@ -60,7 +98,7 @@ static void gicv5_hwirq_init(irq_hw_number_t hwirq, u8 pr= iority, u8 hwirq_type) u16 iaffid; int ret; =20 - if (hwirq_type =3D=3D GICV5_HWIRQ_TYPE_SPI) { + if (hwirq_type =3D=3D GICV5_HWIRQ_TYPE_LPI || hwirq_type =3D=3D GICV5_HWI= RQ_TYPE_SPI) { cdpri =3D FIELD_PREP(GICV5_GIC_CDPRI_PRIORITY_MASK, priority) | FIELD_PREP(GICV5_GIC_CDPRI_TYPE_MASK, hwirq_type) | FIELD_PREP(GICV5_GIC_CDPRI_ID_MASK, hwirq); @@ -119,6 +157,11 @@ static void gicv5_spi_irq_mask(struct irq_data *d) gicv5_iri_irq_mask(d, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_mask(struct irq_data *d) +{ + gicv5_iri_irq_mask(d, GICV5_HWIRQ_TYPE_LPI); +} + static void gicv5_ppi_irq_unmask(struct irq_data *d) { u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); @@ -143,7 +186,7 @@ static void gicv5_iri_irq_unmask(struct irq_data *d, u8= hwirq_type) /* * Rule R_XCLJC states that the effects of a GIC system instruction * complete in finite time and that's the only requirement when - * unmasking an SPI IRQ. + * unmasking an SPI/LPI IRQ. */ gic_insn(cden, CDEN); } @@ -153,6 +196,11 @@ static void gicv5_spi_irq_unmask(struct irq_data *d) gicv5_iri_irq_unmask(d, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_unmask(struct irq_data *d) +{ + gicv5_iri_irq_unmask(d, GICV5_HWIRQ_TYPE_LPI); +} + static void gicv5_hwirq_eoi(u32 hwirq_id, u8 hwirq_type) { u64 cddi =3D hwirq_id | FIELD_PREP(GICV5_GIC_CDDI_TYPE_MASK, hwirq_type); @@ -172,6 +220,11 @@ static void gicv5_spi_irq_eoi(struct irq_data *d) gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_eoi(struct irq_data *d) +{ + gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_LPI); +} + static int gicv5_iri_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force, u8 hwirq_type) @@ -207,6 +260,14 @@ static int gicv5_spi_irq_set_affinity(struct irq_data = *d, GICV5_HWIRQ_TYPE_SPI); } =20 +static int gicv5_lpi_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force) +{ + return gicv5_iri_irq_set_affinity(d, mask_val, force, + GICV5_HWIRQ_TYPE_LPI); +} + #define READ_PPI_REG(irq, reg) \ ({ \ u64 __ppi_val; \ @@ -328,6 +389,14 @@ static int gicv5_spi_irq_get_irqchip_state(struct irq_= data *d, GICV5_HWIRQ_TYPE_SPI); } =20 +static int gicv5_lpi_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *val) +{ + return gicv5_iri_irq_get_irqchip_state(d, which, val, + GICV5_HWIRQ_TYPE_LPI); +} + static int gicv5_ppi_irq_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool val) @@ -365,6 +434,11 @@ static void gicv5_spi_irq_write_pending_state(struct i= rq_data *d, bool val) gicv5_iri_irq_write_pending_state(d, val, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_write_pending_state(struct irq_data *d, bool val) +{ + gicv5_iri_irq_write_pending_state(d, val, GICV5_HWIRQ_TYPE_LPI); +} + static int gicv5_spi_irq_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool val) @@ -381,12 +455,41 @@ static int gicv5_spi_irq_set_irqchip_state(struct irq= _data *d, return 0; } =20 +static int gicv5_lpi_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool val) +{ + switch (which) { + case IRQCHIP_STATE_PENDING: + gicv5_lpi_irq_write_pending_state(d, val); + break; + + default: + pr_debug("Unexpected irqchip_irq_state\n"); + return -EINVAL; + } + + return 0; +} + static int gicv5_spi_irq_retrigger(struct irq_data *data) { return !gicv5_spi_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true); } =20 +static int gicv5_lpi_irq_retrigger(struct irq_data *data) +{ + return !gicv5_lpi_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, + true); +} + +static void gicv5_ipi_send_single(struct irq_data *d, unsigned int cpu) +{ + /* Mark the LPI pending */ + irq_chip_retrigger_hierarchy(d); +} + static const struct irq_chip gicv5_ppi_irq_chip =3D { .name =3D "GICv5-PPI", .irq_mask =3D gicv5_ppi_irq_mask, @@ -557,6 +660,141 @@ static const struct irq_domain_ops gicv5_irq_spi_doma= in_ops =3D { .free =3D gicv5_irq_domain_free, .select =3D gicv5_irq_spi_domain_select }; + +static const struct irq_chip gicv5_lpi_irq_chip =3D { + .name =3D "GICv5-LPI", + .irq_mask =3D gicv5_lpi_irq_mask, + .irq_unmask =3D gicv5_lpi_irq_unmask, + .irq_eoi =3D gicv5_lpi_irq_eoi, + .irq_set_affinity =3D gicv5_lpi_irq_set_affinity, + .irq_retrigger =3D gicv5_lpi_irq_retrigger, + .irq_get_irqchip_state =3D gicv5_lpi_irq_get_irqchip_state, + .irq_set_irqchip_state =3D gicv5_lpi_irq_set_irqchip_state, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND +}; + +static const struct irq_chip gicv5_ipi_irq_chip =3D { + .name =3D "GICv5-IPI", + .irq_mask =3D irq_chip_mask_parent, + .irq_unmask =3D irq_chip_unmask_parent, + .irq_eoi =3D irq_chip_eoi_parent, + .irq_set_affinity =3D irq_chip_set_affinity_parent, + .irq_get_irqchip_state =3D irq_chip_get_parent_state, + .irq_set_irqchip_state =3D irq_chip_set_parent_state, + // We only handle this one in the IPI domain - the rest go to parent + .ipi_send_single =3D gicv5_ipi_send_single, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND +}; + +static int gicv5_irq_lpi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + irq_hw_number_t hwirq; + struct irq_data *irqd; + u32 *lpi =3D arg; + int ret; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; + + hwirq =3D *lpi; + + irqd =3D irq_domain_get_irq_data(domain, virq); + + irq_domain_set_info(domain, virq, hwirq, &gicv5_lpi_irq_chip, NULL, + handle_fasteoi_irq, NULL, NULL); + irqd_set_single_target(irqd); + + ret =3D gicv5_irs_iste_alloc(hwirq); + if (ret < 0) + return ret; + + gicv5_hwirq_init(hwirq, GICV5_IRQ_PRI_MI, GICV5_HWIRQ_TYPE_LPI); + + return 0; +} + +static const struct irq_domain_ops gicv5_irq_lpi_domain_ops =3D { + .alloc =3D gicv5_irq_lpi_domain_alloc, + .free =3D gicv5_irq_domain_free, +}; + +void __init gicv5_init_lpi_domain(void) +{ + struct irq_domain *d; + + d =3D irq_domain_create_tree(NULL, &gicv5_irq_lpi_domain_ops, NULL); + gicv5_global_data.lpi_domain =3D d; +} + +void __init gicv5_free_lpi_domain(void) +{ + irq_domain_remove(gicv5_global_data.lpi_domain); + gicv5_global_data.lpi_domain =3D NULL; +} + +static int gicv5_irq_ipi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + struct irq_data *irqd; + int ret, i; + u32 lpi; + + for (i =3D 0; i < nr_irqs; i++) { + ret =3D gicv5_alloc_lpi(); + if (ret < 0) + return ret; + + lpi =3D ret; + + ret =3D irq_domain_alloc_irqs_parent(domain, virq + i, 1, &lpi); + if (ret) { + gicv5_free_lpi(lpi); + return ret; + } + + irqd =3D irq_domain_get_irq_data(domain, virq + i); + + irq_domain_set_hwirq_and_chip(domain, virq + i, i, + &gicv5_ipi_irq_chip, NULL); + + irqd_set_single_target(irqd); + + irq_set_handler(virq + i, handle_percpu_irq); + } + + return 0; +} + +static void gicv5_irq_ipi_domain_free(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs) +{ + struct irq_data *d; + unsigned int i; + + for (i =3D 0; i < nr_irqs; i++) { + d =3D irq_domain_get_irq_data(domain, virq + i); + + if (!d) + return; + + gicv5_free_lpi(d->parent_data->hwirq); + + irq_set_handler(virq + i, NULL); + irq_domain_reset_irq_data(d); + irq_domain_free_irqs_parent(domain, virq + i, 1); + } +} + +static const struct irq_domain_ops gicv5_irq_ipi_domain_ops =3D { + .alloc =3D gicv5_irq_ipi_domain_alloc, + .free =3D gicv5_irq_ipi_domain_free, +}; + static void handle_irq_per_domain(u32 hwirq) { u8 hwirq_type =3D FIELD_GET(GICV5_HWIRQ_TYPE, hwirq); @@ -570,6 +808,9 @@ static void handle_irq_per_domain(u32 hwirq) case GICV5_HWIRQ_TYPE_SPI: domain =3D gicv5_global_data.spi_domain; break; + case GICV5_HWIRQ_TYPE_LPI: + domain =3D gicv5_global_data.lpi_domain; + break; default: pr_err_once("Unknown IRQ type, bail out\n"); return; @@ -651,9 +892,12 @@ static void __init gicv5_free_domains(void) irq_domain_remove(gicv5_global_data.ppi_domain); if (gicv5_global_data.spi_domain) irq_domain_remove(gicv5_global_data.spi_domain); + if (gicv5_global_data.ipi_domain) + irq_domain_remove(gicv5_global_data.ipi_domain); =20 gicv5_global_data.ppi_domain =3D NULL; gicv5_global_data.spi_domain =3D NULL; + gicv5_global_data.ipi_domain =3D NULL; } =20 static int __init gicv5_init_domains(struct fwnode_handle *handle) @@ -682,6 +926,19 @@ static int __init gicv5_init_domains(struct fwnode_han= dle *handle) irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); } =20 + if (!WARN(!gicv5_global_data.lpi_domain, + "LPI domain uninitialized, can't set up IPIs")) { + d =3D irq_domain_create_hierarchy(gicv5_global_data.lpi_domain, + 0, GICV5_IPIS_PER_CPU * nr_cpu_ids, + NULL, &gicv5_irq_ipi_domain_ops, + NULL); + + if (!d) { + gicv5_free_domains(); + return -ENOMEM; + } + gicv5_global_data.ipi_domain =3D d; + } gicv5_global_data.fwnode =3D handle; =20 return 0; @@ -705,6 +962,24 @@ static void gicv5_set_cpuif_pribits(void) } } =20 +static void gicv5_set_cpuif_idbits(void) +{ + u32 icc_idr0 =3D read_sysreg_s(SYS_ICC_IDR0_EL1); + + switch (FIELD_GET(ICC_IDR0_EL1_ID_BITS, icc_idr0)) { + case ICC_IDR0_EL1_ID_BITS_16BITS: + gicv5_global_data.cpuif_id_bits =3D 16; + break; + case ICC_IDR0_EL1_ID_BITS_24BITS: + gicv5_global_data.cpuif_id_bits =3D 24; + break; + default: + pr_err("Unexpected ICC_IDR0_EL1_ID_BITS value, default to 16"); + gicv5_global_data.cpuif_id_bits =3D 16; + break; + } +} + static int __init gicv5_of_init(struct device_node *node, struct device_no= de *parent) { int ret; @@ -718,6 +993,7 @@ static int __init gicv5_of_init(struct device_node *nod= e, struct device_node *pa goto out_irs; =20 gicv5_set_cpuif_pribits(); + gicv5_set_cpuif_idbits(); =20 pri_bits =3D min_not_zero(gicv5_global_data.cpuif_pri_bits, gicv5_global_data.irs_pri_bits); @@ -730,6 +1006,10 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa if (ret) goto out_int; =20 + ret =3D gicv5_irs_enable(); + if (ret) + goto out_int; + return 0; out_int: gicv5_cpu_disable_interrupts(); diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index 65d5cecf39101f95d4c93ade60939fe481d1e466..ff00c12cb9ec6758e135e6a7411= 873066d76763d 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -7,13 +7,18 @@ =20 #include =20 +#include +#include #include =20 +#define GICV5_IPIS_PER_CPU MAX_IPI + #define GICV5_HWIRQ_ID GENMASK(23, 0) #define GICV5_HWIRQ_TYPE GENMASK(31, 29) #define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) =20 #define GICV5_HWIRQ_TYPE_PPI UL(0x1) +#define GICV5_HWIRQ_TYPE_LPI UL(0x2) #define GICV5_HWIRQ_TYPE_SPI UL(0x3) =20 #define GICV5_PPI_HM_EDGE UL(0x0) @@ -45,6 +50,11 @@ #define GICV5_IRS_PE_SELR 0x0140 #define GICV5_IRS_PE_STATUSR 0x0144 #define GICV5_IRS_PE_CR0 0x0148 +#define GICV5_IRS_IST_BASER 0x0180 +#define GICV5_IRS_IST_CFGR 0x0190 +#define GICV5_IRS_IST_STATUSR 0x0194 +#define GICV5_IRS_MAP_L2_ISTR 0x01c0 + #define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) #define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16) =20 @@ -65,6 +75,11 @@ #define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0) #define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0) #define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0) + +#define GICV5_IRS_IST_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(11), (r)) +#define GICV5_IRS_IST_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(12), (r)) +#define GICV5_IRS_IST_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(13), (r)) + #define GICV5_IRS_CR0_IDLE BIT(1) #define GICV5_IRS_CR0_IRSEN BIT(0) =20 @@ -96,13 +111,49 @@ =20 #define GICV5_IRS_PE_CR0_DPS BIT(0) =20 +#define GICV5_IRS_IST_STATUSR_IDLE BIT(0) + +#define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16) +#define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7) +#define GICV5_IRS_IST_CFGR_L2SZ GENMASK(6, 5) +#define GICV5_IRS_IST_CFGR_LPI_ID_BITS GENMASK(4, 0) + +#define GICV5_IRS_IST_CFGR_STRUCTURE_LINEAR 0b0 +#define GICV5_IRS_IST_CFGR_STRUCTURE_TWO_LEVEL 0b1 + +#define GICV5_IRS_IST_CFGR_ISTSZ_4 0b00 +#define GICV5_IRS_IST_CFGR_ISTSZ_8 0b01 +#define GICV5_IRS_IST_CFGR_ISTSZ_16 0b10 + +#define GICV5_IRS_IST_CFGR_L2SZ_4K 0b00 +#define GICV5_IRS_IST_CFGR_L2SZ_16K 0b01 +#define GICV5_IRS_IST_CFGR_L2SZ_64K 0b10 + +#define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6) +#define GICV5_IRS_IST_BASER_VALID BIT_ULL(0) + +#define GICV5_IRS_MAP_L2_ISTR_ID GENMASK(23, 0) + +#define GICV5_ISTL1E_VALID BIT_ULL(0) + +#define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) + struct gicv5_chip_data { struct fwnode_handle *fwnode; struct irq_domain *ppi_domain; struct irq_domain *spi_domain; + struct irq_domain *lpi_domain; + struct irq_domain *ipi_domain; u32 global_spi_count; u8 cpuif_pri_bits; + u8 cpuif_id_bits; u8 irs_pri_bits; + struct { + __le64 *l1ist_addr; + u32 l2_size; + u8 l2_bits; + bool l2; + } ist; }; =20 extern struct gicv5_chip_data gicv5_global_data __read_mostly; @@ -140,10 +191,18 @@ static inline int gicv5_wait_for_op_s_atomic(void __i= omem *addr, u32 offset, #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) =20 +void __init gicv5_init_lpi_domain(void); +void __init gicv5_free_lpi_domain(void); + int gicv5_irs_of_probe(struct device_node *parent); void gicv5_irs_remove(void); +int gicv5_irs_enable(void); int gicv5_irs_register_cpu(int cpuid); int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); +int gicv5_irs_iste_alloc(u32 lpi); + +void gicv5_init_lpis(u32 max); +void gicv5_deinit_lpis(void); #endif --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D371280A4D; Tue, 6 May 2025 12:25:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534342; cv=none; b=bAb/Or26Hc/C0ee2Whjz48b/v7p5RJ6CQtzU0Tn05nLu/OrSQbSterNwsPXNdcyQsAmlEYdh0DBqPoCNlLNbPycqgzob98VIr3xpmMg2kZmn4gqyusXq2V/FuNhelL5OzVLr8/iT3YnFE1mALdyDCHsDD3NX+ixDbUTICP6Z3QQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534342; c=relaxed/simple; bh=b8y2q8GE/lpW2dmJu8iJNqqJM/E6ZKtJ8GNGL4ORKrs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SwY//pW370ASHtPZfXUlMhDzRV7pm6xeAPGdlDZ9rNrhh8Y+RyVmfQhXK+k04Oew+KoMe2ID7kLIMiwbT7rNPkZeeTADi+h0PCl/KwwprhFvg9jXcU3D9Qkpwxc0wkCNOXrBcg7Zmh8cX9b6BmEhCkTXCIpDllnc/WsaFAYPaQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GTotnHgz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GTotnHgz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3FB8DC4CEED; Tue, 6 May 2025 12:25:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534342; bh=b8y2q8GE/lpW2dmJu8iJNqqJM/E6ZKtJ8GNGL4ORKrs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GTotnHgz0xV0+fZFbBSLclZVcfl8kWyHkrVqMu97R65oT2ipe0dN3rHDZeffn0DMt 6wWpOEz+VoEQI5rWjcPkA+jJd1DJYOUSesDb13IYDEM7B9Pc99GNQLQjxITAk10nNO L6WbykgH1CpFAYO3on+umZjvLWRYKctheMP7NF/oX9gn4KgLDXEw76uA6pBJa319c8 UnRBy0ToAVgtwUE72y5ZqaJcsKVv/NgZ8aulLFHQH/pjmZttqDLVtt1mW+t4qZPR8Q pfUz/zplG4ADW4UxoqjBCFvW+imtpsezXnZHgkqWQbOFyqyu1wTfJhvREi0imJ/pdP iAl2SwnsrfB+Q== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:52 +0200 Subject: [PATCH v3 23/25] irqchip/gic-v5: Enable GICv5 SMP booting Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-23-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Set up IPIs by allocating IPI IRQs for all cpus and call into arm64 core code to initialise IPIs IRQ descriptors and request the related IRQ. Implement hotplug callback to enable interrupts on a cpu and register the cpu with an IRS. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Cc: Thomas Gleixner Cc: Marc Zyngier --- drivers/irqchip/irq-gic-v5.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index c2c05f4411197365079c7d997665c81e3a0f4b74..e4bb02a1988b01a23db61288ff1= b1fe3db02e0e4 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -5,6 +5,7 @@ =20 #define pr_fmt(fmt) "GICv5: " fmt =20 +#include #include #include #include @@ -875,6 +876,8 @@ static void gicv5_cpu_enable_interrupts(void) write_sysreg_s(cr0, SYS_ICC_CR0_EL1); } =20 +static int base_ipi_virq; + static int gicv5_starting_cpu(unsigned int cpu) { if (WARN(!gicv5_cpuif_has_gcie(), @@ -886,6 +889,22 @@ static int gicv5_starting_cpu(unsigned int cpu) return gicv5_irs_register_cpu(cpu); } =20 +static void __init gicv5_smp_init(void) +{ + unsigned int num_ipis =3D GICV5_IPIS_PER_CPU * nr_cpu_ids; + + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, + "irqchip/arm/gicv5:starting", + gicv5_starting_cpu, NULL); + + base_ipi_virq =3D irq_domain_alloc_irqs(gicv5_global_data.ipi_domain, + num_ipis, NUMA_NO_NODE, NULL); + if (WARN(base_ipi_virq <=3D 0, "IPI IRQ allocation was not successful")) + return; + + set_smp_ipi_range_percpu(base_ipi_virq, GICV5_IPIS_PER_CPU, nr_cpu_ids); +} + static void __init gicv5_free_domains(void) { if (gicv5_global_data.ppi_domain) @@ -1010,6 +1029,8 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa if (ret) goto out_int; =20 + gicv5_smp_init(); + return 0; out_int: gicv5_cpu_disable_interrupts(); --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F873280A52; Tue, 6 May 2025 12:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534347; cv=none; b=EPcU50r6JLatF0OAy9jvqLR/foCgTxROAJBSlTmXzPa0p3DM0xRmPug2TAxGMH4cacHCeCmO3SHGHiaF4rAOKqS6uiXIpXqWgcjbh94XU5OqLFuvnRqcQpJ378AT+KtU1PnNDIqJ0eOwa4GcXVOlSn9uruJ52AT0Sm2ZC2g65yQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534347; c=relaxed/simple; bh=5jKUQoSi7Ujpy71bqHTK9fmpxmJ8sre8fEsgLv3xmRo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qtTf42x4JKqkJFYAXO3ZU2dAKKbrh/LO8PjWZnirBWn87zJdCdcUyRfTz6JngVxLSGOc1aBZGH+m46UGG8LsgBqhoRfeiigpalHKMV4SIvr2/vYCLiW+3wiDw5337wEQoC1dbd1AyzwKo2NARspc6Np+WG/D3bvDtWAic7QmarI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pH0Gy+tj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pH0Gy+tj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B0BE9C4CEE4; Tue, 6 May 2025 12:25:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534346; bh=5jKUQoSi7Ujpy71bqHTK9fmpxmJ8sre8fEsgLv3xmRo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pH0Gy+tjCZOolp9wNGH7R4nPLeDrzQFitYzZQLXokUFa+7qUQf7rF8sx/bqDIPnxT CXZrhiv5G3OdvsQQOZFSFjB0keQRVG33ocPeJJwrqj/+6lVPKzoHKFhGaB5pV3smYm oRrgyCvGoxCk8qcFIOPwS2ylpT1dqsdJQe6d5Ji498OvXDOvzqzrgYcWhEiQn6N4O3 81RZ+I+SPxporDbgsDywLZ4AMpKK51oTE0wI5ynSuuCjVFAvBA+xnV4CsA3pwg1qQG t9CZsjL4oi1Z2ASVbBAHsUfbbvtnw7QerG5M98mFahnvexqmk69hUAzpnT+Tuvy1Dk Kyu/RNTkragOw== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:53 +0200 Subject: [PATCH v3 24/25] irqchip/gic-v5: Add GICv5 ITS support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-24-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 The GICv5 architecture implements Interrupt Translation Service (ITS) components in order to translate events coming from peripherals into interrupt events delivered to the connected IRSes. Events (ie MSI memory writes to ITS translate frame), are translated by the ITS using tables kept in memory. ITS translation tables for peripherals is kept in memory storage (device table [DT] and Interrupt Translation Table [ITT]) that is allocated by the driver on boot. Both tables can be 1- or 2-level; the structure is chosen by the driver after probing the ITS HW parameters and checking the allowed table splits and supported {device/event}_IDbits. DT table entries are allocated on demand (ie when a device is probed); the DT table is sized using the number of supported deviceID bits in that that's a system design decision (ie the number of deviceID bits implemented should reflect the number of devices expected in a system) therefore it makes sense to allocate a DT table that can cater for the maximum number of devices. DT and ITT tables are allocated using the kmalloc interface; the allocation size may be smaller than a page or larger, and must provide contiguous memory pages. LPIs INTIDs backing the device events are allocated one-by-one and only upon Linux IRQ allocation; this to avoid preallocating a large number of LPIs to cover the HW device MSI vector size whereas few MSI entries are actually enabled by a device. ITS cacheability/shareability attributes are programmed according to the provided firmware ITS description. The GICv5 ITS reuses the GICv3 MSI parent infrastructure, there is no need to duplicate it, make it common. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Cc: Thomas Gleixner Cc: Marc Zyngier --- MAINTAINERS | 1 + drivers/irqchip/Kconfig | 7 + drivers/irqchip/Makefile | 5 +- drivers/irqchip/irq-gic-common.h | 2 - ...3-its-msi-parent.c =3D> irq-gic-its-msi-parent.c} | 3 +- drivers/irqchip/irq-gic-its-msi-parent.h | 13 + drivers/irqchip/irq-gic-v3-its.c | 3 +- drivers/irqchip/irq-gic-v5-irs.c | 25 + drivers/irqchip/irq-gic-v5-its.c | 1176 ++++++++++++++++= ++++ drivers/irqchip/irq-gic-v5.c | 6 +- include/linux/irqchip/arm-gic-v5.h | 179 +++ 11 files changed, 1411 insertions(+), 9 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 49c377febad72e77dd6d480105c2b6bffa81f9a6..5159c517ca1968e6df1678b2695= 59257d2fcc86a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1907,6 +1907,7 @@ M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml +F: drivers/irqchip/irq-gic-its-msi-parent.[ch] F: drivers/irqchip/irq-gic-v5*.[ch] F: include/linux/irqchip/arm-gic-v5.h =20 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 6b3d70924186bd8ca04294832409d1e379c9cbd4..d73f9bcde8fd995b5b6c33108b9= d40b424437b3f 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -41,10 +41,14 @@ config ARM_GIC_V3 select HAVE_ARM_SMCCC_DISCOVERY select IRQ_MSI_IOMMU =20 +config ARM_GIC_ITS_PARENT + bool + config ARM_GIC_V3_ITS bool select GENERIC_MSI_IRQ select IRQ_MSI_LIB + select ARM_GIC_ITS_PARENT default ARM_GIC_V3 select IRQ_MSI_IOMMU =20 @@ -58,6 +62,9 @@ config ARM_GIC_V5 bool select IRQ_DOMAIN_HIERARCHY select GENERIC_IRQ_EFFECTIVE_AFF_MASK + select GENERIC_MSI_IRQ + select IRQ_MSI_LIB + select ARM_GIC_ITS_PARENT =20 config ARM_NVIC bool diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 3d9c47fa3fdf40b7452c059d84fe8ac24c91bc0f..18724910f2bdc20597d3d3e4852= d593a4bd163da 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -32,10 +32,11 @@ obj-$(CONFIG_ARCH_REALVIEW) +=3D irq-gic-realview.o obj-$(CONFIG_IRQ_MSI_LIB) +=3D irq-msi-lib.o obj-$(CONFIG_ARM_GIC_V2M) +=3D irq-gic-v2m.o obj-$(CONFIG_ARM_GIC_V3) +=3D irq-gic-v3.o irq-gic-v3-mbi.o irq-gic-commo= n.o -obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o irq-gic-v= 3-its-msi-parent.o +obj-$(CONFIG_ARM_GIC_ITS_PARENT) +=3D irq-gic-its-msi-parent.o +obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o -obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o irq-gic-v5-it= s.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-com= mon.h index 020ecdf16901c9720e5746aec4d0b5b39d3625ed..710cab61d9195a0bd64d57e03c6= 0852c4cd6ff8e 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -29,8 +29,6 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *= quirks, void gic_enable_of_quirks(const struct device_node *np, const struct gic_quirk *quirks, void *data); =20 -extern const struct msi_parent_ops gic_v3_its_msi_parent_ops; - #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) #define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2) diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/= irq-gic-its-msi-parent.c similarity index 98% rename from drivers/irqchip/irq-gic-v3-its-msi-parent.c rename to drivers/irqchip/irq-gic-its-msi-parent.c index bdb04c8081480de468fb217b68c6933a8e1e2bd7..71edcdb2defdfd5b892d8635403= 9d2e46b832ea5 100644 --- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c +++ b/drivers/irqchip/irq-gic-its-msi-parent.c @@ -7,7 +7,6 @@ #include #include =20 -#include "irq-gic-common.h" #include "irq-msi-lib.h" =20 #define ITS_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ @@ -200,7 +199,7 @@ static bool its_init_dev_msi_info(struct device *dev, s= truct irq_domain *domain, return true; } =20 -const struct msi_parent_ops gic_v3_its_msi_parent_ops =3D { +const struct msi_parent_ops gic_its_msi_parent_ops =3D { .supported_flags =3D ITS_MSI_FLAGS_SUPPORTED, .required_flags =3D ITS_MSI_FLAGS_REQUIRED, .chip_flags =3D MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK, diff --git a/drivers/irqchip/irq-gic-its-msi-parent.h b/drivers/irqchip/irq= -gic-its-msi-parent.h new file mode 100644 index 0000000000000000000000000000000000000000..e7bb7f3862eef379e5b85fe7bd5= eb72f3586d3b7 --- /dev/null +++ b/drivers/irqchip/irq-gic-its-msi-parent.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Limited, All Rights Reserved. + */ + +#ifndef _IRQ_GIC_ITS_MSI_PARENT_H +#define _IRQ_GIC_ITS_MSI_PARENT_H + +#include + +extern const struct msi_parent_ops gic_its_msi_parent_ops; + +#endif /* _IRQ_GIC_ITS_MSI_PARENT_H */ diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-= its.c index 0115ad6c82593de511c285d99437996919bfa308..6c51bf4e34a38103d612c74476d= 640cd4126e8b6 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -41,6 +41,7 @@ #include =20 #include "irq-gic-common.h" +#include "irq-gic-its-msi-parent.h" #include "irq-msi-lib.h" =20 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) @@ -5139,7 +5140,7 @@ static int its_init_domain(struct its_node *its) =20 irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS); =20 - inner_domain->msi_parent_ops =3D &gic_v3_its_msi_parent_ops; + inner_domain->msi_parent_ops =3D &gic_its_msi_parent_ops; inner_domain->flags |=3D IRQ_DOMAIN_FLAG_MSI_PARENT; =20 return 0; diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-= irs.c index a3de1c1b918c0ae123ae204f0dea6992db33ecd0..921472b958d84c6ded65c8f745b= ca90f7385e03f 100644 --- a/drivers/irqchip/irq-gic-v5-irs.c +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -482,6 +482,23 @@ static int gicv5_irs_wait_for_idle(struct gicv5_irs_ch= ip_data *irs_data) GICV5_IRS_CR0_IDLE, NULL); } =20 +void gicv5_irs_syncr(void) +{ + struct gicv5_irs_chip_data *irs_data; + u32 syncr; + + irs_data =3D list_first_entry_or_null(&irs_nodes, + struct gicv5_irs_chip_data, entry); + if (WARN_ON(!irs_data)) + return; + + syncr =3D FIELD_PREP(GICV5_IRS_SYNCR_SYNC, 1); + irs_writel_relaxed(irs_data, syncr, GICV5_IRS_SYNCR); + + gicv5_wait_for_op(irs_data->irs_base, GICV5_IRS_SYNC_STATUSR, + GICV5_IRS_SYNC_STATUSR_IDLE); +} + int gicv5_irs_register_cpu(int cpuid) { struct gicv5_irs_chip_data *irs_data; @@ -776,6 +793,14 @@ int __init gicv5_irs_enable(void) return 0; } =20 +void __init gicv5_irs_its_probe(void) +{ + struct gicv5_irs_chip_data *irs_data; + + list_for_each_entry(irs_data, &irs_nodes, entry) + gicv5_its_of_probe(to_of_node(irs_data->fwnode)); +} + int __init gicv5_irs_of_probe(struct device_node *parent) { struct device_node *np; diff --git a/drivers/irqchip/irq-gic-v5-its.c b/drivers/irqchip/irq-gic-v5-= its.c new file mode 100644 index 0000000000000000000000000000000000000000..e449be39a75c664ec34d616bc39= 474f599c11de5 --- /dev/null +++ b/drivers/irqchip/irq-gic-v5-its.c @@ -0,0 +1,1176 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ + +#define pr_fmt(fmt) "GICv5 ITS: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "irq-gic-its-msi-parent.h" +#include "irq-msi-lib.h" + +#define ITS_FLAGS_NON_COHERENT BIT(0) + +static LIST_HEAD(its_nodes); + +static u32 its_readl_relaxed(struct gicv5_its_chip_data *its_node, + const u32 reg_offset) +{ + return readl_relaxed(its_node->its_base + reg_offset); +} + +static void its_writel_relaxed(struct gicv5_its_chip_data *its_node, + const u32 val, const u32 reg_offset) +{ + writel_relaxed(val, its_node->its_base + reg_offset); +} + +static void its_writeq_relaxed(struct gicv5_its_chip_data *its_node, + const u64 val, const u32 reg_offset) +{ + writeq_relaxed(val, its_node->its_base + reg_offset); +} + +static void gicv5_its_dcache_clean(struct gicv5_its_chip_data *its, void *= start, + size_t sz) +{ + void *end =3D start + sz; + + if (its->flags & ITS_FLAGS_NON_COHERENT) + dcache_clean_inval_poc((unsigned long)start, (unsigned long)end); + else + dsb(ishst); +} + +static void its_write_table_entry(struct gicv5_its_chip_data *its, + __le64 *entry, u64 val) +{ + WRITE_ONCE(*entry, cpu_to_le64(val)); + gicv5_its_dcache_clean(its, entry, sizeof(*entry)); +} + +#define devtab_cfgr_field(its, f) \ + FIELD_GET(GICV5_ITS_DT_CFGR_##f, (its)->devtab_cfgr.cfgr) + +static int gicv5_its_cache_sync(struct gicv5_its_chip_data *its) +{ + return gicv5_wait_for_op_atomic(its->its_base, GICV5_ITS_STATUSR, + GICV5_ITS_STATUSR_IDLE, NULL); +} + +static void gicv5_its_syncr(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + u64 syncr; + + syncr =3D FIELD_PREP(GICV5_ITS_SYNCR_SYNC, 1) | + FIELD_PREP(GICV5_ITS_SYNCR_DEVICEID, its_dev->device_id); + + its_writeq_relaxed(its, syncr, GICV5_ITS_SYNCR); + + gicv5_wait_for_op(its->its_base, GICV5_ITS_SYNC_STATUSR, GICV5_ITS_SYNC_S= TATUSR_IDLE); +} + +static unsigned int gicv5_its_l2sz_to_l2_bits(unsigned int sz) +{ + switch (sz) { + case GICV5_ITS_DT_ITT_CFGR_L2SZ_64k: + return 13; + case GICV5_ITS_DT_ITT_CFGR_L2SZ_16k: + return 11; + case GICV5_ITS_DT_ITT_CFGR_L2SZ_4k: + default: + return 9; + } +} + +static int gicv5_its_itt_cache_inv(struct gicv5_its_chip_data *its, + u32 device_id, u16 event_id) +{ + u32 eventr, eidr; + u64 didr; + + didr =3D FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, device_id); + eidr =3D FIELD_PREP(GICV5_ITS_EIDR_EVENTID, event_id); + eventr =3D FIELD_PREP(GICV5_ITS_INV_EVENTR_I, 0x1); + + its_writeq_relaxed(its, didr, GICV5_ITS_DIDR); + its_writel_relaxed(its, eidr, GICV5_ITS_EIDR); + its_writel_relaxed(its, eventr, GICV5_ITS_INV_EVENTR); + + return gicv5_its_cache_sync(its); +} + +static void gicv5_its_free_itt_linear(struct gicv5_its_dev *its_dev) +{ + kfree(its_dev->itt_cfg.linear.itt); +} + +static void gicv5_its_free_itt_two_level(struct gicv5_its_dev *its_dev) +{ + unsigned int i, num_ents =3D its_dev->itt_cfg.l2.num_l1_ents; + + for (i =3D 0; i < num_ents; i++) + kfree(its_dev->itt_cfg.l2.l2ptrs[i]); + + kfree(its_dev->itt_cfg.l2.l2ptrs); + kfree(its_dev->itt_cfg.l2.l1itt); +} + +static void gicv5_its_free_itt(struct gicv5_its_dev *its_dev) +{ + if (!its_dev->itt_cfg.l2itt) + gicv5_its_free_itt_linear(its_dev); + else + gicv5_its_free_itt_two_level(its_dev); +} + +static int gicv5_its_create_itt_linear(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev, + unsigned int event_id_bits) +{ + unsigned int num_ents =3D BIT(event_id_bits); + __le64 *itt; + + itt =3D kcalloc(num_ents, sizeof(*itt), GFP_KERNEL); + if (!itt) + return -ENOMEM; + + its_dev->itt_cfg.linear.itt =3D itt; + its_dev->itt_cfg.linear.num_ents =3D num_ents; + its_dev->itt_cfg.l2itt =3D false; + its_dev->itt_cfg.event_id_bits =3D event_id_bits; + + gicv5_its_dcache_clean(its, itt, num_ents * sizeof(*itt)); + + return 0; +} + +/* + * Allocate a two-level ITT. All ITT entries are allocated in one go, unli= ke + * with the device table. Span may be used to limit the second level table + * size, where possible. + */ +static int gicv5_its_create_itt_two_level(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev, + unsigned int event_id_bits, + unsigned int itt_l2sz, + unsigned int num_events) +{ + unsigned int l1_bits, l2_bits, span, events_per_l2_table, + complete_tables, final_span, num_ents; + __le64 *itt_l1, *itt_l2, **l2ptrs; + unsigned int i; + int ret; + u64 val; + + ret =3D gicv5_its_l2sz_to_l2_bits(itt_l2sz); + if (ret >=3D event_id_bits) { + pr_debug("Incorrect l2sz (0x%x) for %u EventID bits. Cannot allocate ITT= \n", + itt_l2sz, event_id_bits); + return -EINVAL; + } + + l2_bits =3D ret; + + l1_bits =3D event_id_bits - l2_bits; + + num_ents =3D BIT(l1_bits); + + itt_l1 =3D kcalloc(num_ents, sizeof(*itt_l1), GFP_KERNEL); + if (!itt_l1) + return -ENOMEM; + + l2ptrs =3D kcalloc(num_ents, sizeof(*l2ptrs), GFP_KERNEL); + if (!l2ptrs) { + kfree(itt_l1); + return -ENOMEM; + } + + its_dev->itt_cfg.l2.l2ptrs =3D l2ptrs; + + its_dev->itt_cfg.l2.l2sz =3D itt_l2sz; + its_dev->itt_cfg.l2.l1itt =3D itt_l1; + its_dev->itt_cfg.l2.num_l1_ents =3D num_ents; + its_dev->itt_cfg.l2itt =3D true; + its_dev->itt_cfg.event_id_bits =3D event_id_bits; + + /* + * Need to determine how many entries there are per L2 - this is based + * on the number of bits in the table. + */ + events_per_l2_table =3D BIT(l2_bits); + complete_tables =3D num_events / events_per_l2_table; + final_span =3D order_base_2(num_events % events_per_l2_table); + + for (i =3D 0; i < num_ents; i++) { + size_t l2sz; + + span =3D i =3D=3D complete_tables ? final_span : l2_bits; + + itt_l2 =3D kcalloc(BIT(span), sizeof(*itt_l2), GFP_KERNEL); + if (!itt_l2) { + ret =3D -ENOMEM; + goto out_free; + } + + its_dev->itt_cfg.l2.l2ptrs[i] =3D itt_l2; + + l2sz =3D BIT(span) * sizeof(*itt_l2); + + gicv5_its_dcache_clean(its, itt_l2, l2sz); + + val =3D (virt_to_phys(itt_l2) & GICV5_ITTL1E_L2_ADDR_MASK) | + FIELD_PREP(GICV5_ITTL1E_SPAN, span) | + FIELD_PREP(GICV5_ITTL1E_VALID, 0x1); + + WRITE_ONCE(itt_l1[i], cpu_to_le64(val)); + } + + gicv5_its_dcache_clean(its, itt_l1, num_ents * sizeof(*itt_l1)); + + return 0; +out_free: + for (i =3D i - 1; i >=3D 0; i--) + kfree(its_dev->itt_cfg.l2.l2ptrs[i]); + + kfree(its_dev->itt_cfg.l2.l2ptrs); + kfree(itt_l1); + return ret; +} + +/* + * Function to check whether the device table or ITT table support + * a two-level table and if so depending on the number of id_bits + * requested, determine whether a two-level table is required. + * + * Return the 2-level size value if a two level table is deemed + * necessary. + */ +static bool gicv5_its_l2sz_two_level(bool devtab, u32 its_idr1, u8 id_bits, + u8 *sz) +{ + unsigned int l2_bits, l2_sz; + + if (devtab && !FIELD_GET(GICV5_ITS_IDR1_DT_LEVELS, its_idr1)) + return false; + + if (!devtab && !FIELD_GET(GICV5_ITS_IDR1_ITT_LEVELS, its_idr1)) + return false; + + /* + * Pick an L2 size that matches the pagesize; if a match + * is not found, go for the smallest supported l2 size granule. + * + * This ensures that we will always be able to allocate + * contiguous memory at L2. + */ + switch (PAGE_SIZE) { + case SZ_64K: + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_64k; + break; + } + fallthrough; + case SZ_16K: + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_16k; + break; + } + fallthrough; + case SZ_4K: + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; + break; + } + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_16k; + break; + } + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_64k; + break; + } + + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; + break; + } + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(l2_sz); + + if (l2_bits > id_bits) + return false; + + *sz =3D l2_sz; + + return true; +} + +static __le64 *gicv5_its_device_get_itte_ref(struct gicv5_its_dev *its_dev, + u16 event_id) +{ + unsigned int l1_idx, l2_idx, l2_bits; + __le64 *l2_itt, *l1_itt; + + if (!its_dev->itt_cfg.l2itt) { + __le64 *itt =3D its_dev->itt_cfg.linear.itt; + + return &itt[event_id]; + } + + l1_itt =3D its_dev->itt_cfg.l2.l1itt; + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(its_dev->itt_cfg.l2.l2sz); + + l1_idx =3D event_id >> l2_bits; + + BUG_ON(!FIELD_GET(GICV5_ITTL1E_VALID, le64_to_cpu(l1_itt[l1_idx]))); + + l2_idx =3D event_id & GENMASK(l2_bits - 1, 0); + + l2_itt =3D its_dev->itt_cfg.l2.l2ptrs[l1_idx]; + + return &l2_itt[l2_idx]; +} + +static int gicv5_its_device_cache_inv(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + u32 devicer; + u64 didr; + + didr =3D FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, its_dev->device_id); + devicer =3D FIELD_PREP(GICV5_ITS_INV_DEVICER_I, 0x1) | + FIELD_PREP(GICV5_ITS_INV_DEVICER_EVENTID_BITS, + its_dev->itt_cfg.event_id_bits) | + FIELD_PREP(GICV5_ITS_INV_DEVICER_L1, 0x0); + its_writeq_relaxed(its, didr, GICV5_ITS_DIDR); + its_writel_relaxed(its, devicer, GICV5_ITS_INV_DEVICER); + + return gicv5_its_cache_sync(its); +} + +/* + * Allocate a level 2 device table entry, update L1 parent to reference it. + * Only used for 2-level device tables, and it is called on demand. + */ +static int gicv5_its_alloc_l2_devtab(struct gicv5_its_chip_data *its, + unsigned int l1_index) +{ + __le64 *l2devtab, *l1devtab =3D its->devtab_cfgr.l2.l1devtab; + u8 span, l2sz, l2_bits; + u64 l1dte; + + if (FIELD_GET(GICV5_DTL1E_VALID, le64_to_cpu(l1devtab[l1_index]))) + return 0; + + span =3D FIELD_GET(GICV5_DTL1E_SPAN, le64_to_cpu(l1devtab[l1_index])); + l2sz =3D devtab_cfgr_field(its, L2SZ); + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(l2sz); + + /* + * Span allows us to create a smaller L2 device table. + * If it is too large, use the number of allowed L2 bits. + */ + if (span > l2_bits) + span =3D l2_bits; + + l2devtab =3D kcalloc(BIT(span), sizeof(*l2devtab), GFP_KERNEL); + if (!l2devtab) + return -ENOMEM; + + its->devtab_cfgr.l2.l2ptrs[l1_index] =3D l2devtab; + + l1dte =3D FIELD_PREP(GICV5_DTL1E_SPAN, span) | + (virt_to_phys(l2devtab) & GICV5_DTL1E_L2_ADDR_MASK) | + FIELD_PREP(GICV5_DTL1E_VALID, 0x1); + its_write_table_entry(its, &l1devtab[l1_index], l1dte); + + return 0; +} + +static __le64 *gicv5_its_devtab_get_dte_ref(struct gicv5_its_chip_data *it= s, + u32 device_id, bool alloc) +{ + u8 str =3D devtab_cfgr_field(its, STRUCTURE); + unsigned int l2sz, l2_bits, l1_idx, l2_idx; + __le64 *l1devtab, *l2devtab; + int ret; + + if (str =3D=3D GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) { + l2devtab =3D its->devtab_cfgr.linear.devtab; + return &l2devtab[device_id]; + } + + l2sz =3D devtab_cfgr_field(its, L2SZ); + l1devtab =3D its->devtab_cfgr.l2.l1devtab; + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(l2sz); + + l1_idx =3D device_id >> l2_bits; + l2_idx =3D device_id & GENMASK(l2_bits - 1, 0); + + if (alloc) { + /* + * Allocate a new L2 device table here before + * continuing. We make the assumption that the span in + * the L1 table has been set correctly, and blindly use + * that value. + */ + ret =3D gicv5_its_alloc_l2_devtab(its, l1_idx); + if (ret) + return NULL; + } + + BUG_ON(!FIELD_GET(GICV5_DTL1E_VALID, le64_to_cpu(l1devtab[l1_idx]))); + + l2devtab =3D its->devtab_cfgr.l2.l2ptrs[l1_idx]; + return &l2devtab[l2_idx]; +} + +/* + * Register a new device in the device table. Allocate an ITT and + * program the L2DTE entry according to the ITT structure that + * was chosen. + */ +static int gicv5_its_device_register(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + u8 event_id_bits, device_id_bits, itt_struct, itt_l2sz; + phys_addr_t itt_phys_base; + bool two_level_itt; + u32 idr1, idr2; + __le64 *dte; + u64 val; + int ret; + + device_id_bits =3D devtab_cfgr_field(its, DEVICEID_BITS); + + if (its_dev->device_id >=3D BIT(device_id_bits)) { + pr_err("Supplied DeviceID (%u) outside of Device Table range (%u)!", + its_dev->device_id, (u32)GENMASK(device_id_bits - 1, 0)); + return -EINVAL; + } + + dte =3D gicv5_its_devtab_get_dte_ref(its, its_dev->device_id, true); + if (!dte) + return -ENOMEM; + + if (FIELD_GET(GICV5_DTL2E_VALID, le64_to_cpu(*dte))) + return -EBUSY; + + /* + * Determine how many bits we need, validate those against the max. + * Based on these, determine if we should go for a 1- or 2-level ITT. + */ + event_id_bits =3D order_base_2(its_dev->num_events); + + idr2 =3D its_readl_relaxed(its, GICV5_ITS_IDR2); + + if (event_id_bits > FIELD_GET(GICV5_ITS_IDR2_EVENTID_BITS, idr2)) { + pr_err("Required EventID bits (%u) larger than supported bits (%u)!", + event_id_bits, + (u8)FIELD_GET(GICV5_ITS_IDR2_EVENTID_BITS, idr2)); + return -EINVAL; + } + + idr1 =3D its_readl_relaxed(its, GICV5_ITS_IDR1); + + /* + * L2 ITT size is programmed into the L2DTE regardless of + * whether a two-level or linear ITT is built, init it. + */ + itt_l2sz =3D 0; + + two_level_itt =3D gicv5_its_l2sz_two_level(false, idr1, event_id_bits, + &itt_l2sz); + if (two_level_itt) + ret =3D gicv5_its_create_itt_two_level(its, its_dev, event_id_bits, + itt_l2sz, + its_dev->num_events); + else + ret =3D gicv5_its_create_itt_linear(its, its_dev, event_id_bits); + if (ret) + return ret; + + itt_phys_base =3D two_level_itt ? virt_to_phys(its_dev->itt_cfg.l2.l1itt)= : + virt_to_phys(its_dev->itt_cfg.linear.itt); + + itt_struct =3D two_level_itt ? GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL : + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR; + + val =3D FIELD_PREP(GICV5_DTL2E_EVENT_ID_BITS, event_id_bits) | + FIELD_PREP(GICV5_DTL2E_ITT_STRUCTURE, itt_struct) | + (itt_phys_base & GICV5_DTL2E_ITT_ADDR_MASK) | + FIELD_PREP(GICV5_DTL2E_ITT_L2SZ, itt_l2sz) | + FIELD_PREP(GICV5_DTL2E_VALID, 0x1); + + its_write_table_entry(its, dte, val); + + ret =3D gicv5_its_device_cache_inv(its, its_dev); + if (ret) { + gicv5_its_free_itt(its_dev); + its_write_table_entry(its, dte, 0); + return ret; + } + + return 0; +} + +/* + * Unregister a device in the device table. Lookup the device by ID, free = the + * corresponding ITT, mark the device as invalid in the device table. + */ +static int gicv5_its_device_unregister(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + __le64 *dte; + + dte =3D gicv5_its_devtab_get_dte_ref(its, its_dev->device_id, false); + + if (!FIELD_GET(GICV5_DTL2E_VALID, le64_to_cpu(*dte))) { + pr_debug("Device table entry for DeviceID 0x%x is not valid. Nothing to = clean up!", + its_dev->device_id); + return -EINVAL; + } + + gicv5_its_free_itt(its_dev); + + /* Zero everything - make it clear that this is an invalid entry */ + its_write_table_entry(its, dte, 0); + + return gicv5_its_device_cache_inv(its, its_dev); +} + +/* + * Allocate a 1-level device table. All entries are allocated, but marked + * invalid. + */ +static int gicv5_its_alloc_devtab_linear(struct gicv5_its_chip_data *its, + u8 device_id_bits) +{ + __le64 *devtab; + size_t sz; + u64 baser; + u32 cfgr; + + /* + * We expect a GICv5 implementation requiring a large number of + * deviceID bits to support a 2-level device table. If that's not + * the case, cap the number of deviceIDs supported according to the + * kmalloc limits so that the system can chug along with a linear + * device table. + */ + sz =3D BIT_ULL(device_id_bits) * sizeof(*devtab); + if (sz > KMALLOC_MAX_SIZE) { + u8 device_id_cap =3D ilog2(KMALLOC_MAX_SIZE/sizeof(*devtab)); + + pr_warn("Limiting device ID bits from %u to %u\n", + device_id_bits, device_id_cap); + device_id_bits =3D device_id_cap; + } + + devtab =3D kcalloc(BIT(device_id_bits), sizeof(*devtab), GFP_KERNEL); + if (!devtab) + return -ENOMEM; + + gicv5_its_dcache_clean(its, devtab, sz); + + cfgr =3D FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) | + FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, 0) | + FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, device_id_bits); + its_writel_relaxed(its, cfgr, GICV5_ITS_DT_CFGR); + + baser =3D virt_to_phys(devtab) & GICV5_ITS_DT_BASER_ADDR_MASK; + its_writeq_relaxed(its, baser, GICV5_ITS_DT_BASER); + + its->devtab_cfgr.cfgr =3D cfgr; + its->devtab_cfgr.linear.devtab =3D devtab; + + return 0; +} + +/* + * Allocate a 2-level device table. L2 entries are not allocated, + * they are allocated on-demand. + */ +static int gicv5_its_alloc_devtab_two_level(struct gicv5_its_chip_data *it= s, + u8 device_id_bits, + u8 devtab_l2sz) +{ + unsigned int l1_bits, l2_bits, i; + __le64 *l1devtab, **l2ptrs; + size_t l1_sz; + u64 baser; + u32 cfgr; + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(devtab_l2sz); + + l1_bits =3D device_id_bits - l2_bits; + l1_sz =3D BIT(l1_bits) * sizeof(*l1devtab); + /* + * With 2-level device table support it is highly unlikely + * that we are not able to allocate the required amount of + * device table memory to cover deviceID space; cap the + * deviceID space if we encounter such set-up. + * If this ever becomes a problem we could revisit the policy + * behind level 2 size selection to reduce level-1 deviceID bits. + */ + if (l1_sz > KMALLOC_MAX_SIZE) { + l1_bits =3D ilog2(KMALLOC_MAX_SIZE/sizeof(*l1devtab)); + + pr_warn("Limiting device ID bits from %u to %u\n", + device_id_bits, l1_bits + l2_bits); + device_id_bits =3D l1_bits + l2_bits; + l1_sz =3D KMALLOC_MAX_SIZE; + } + + l1devtab =3D kcalloc(BIT(l1_bits), sizeof(*l1devtab), GFP_KERNEL); + if (!l1devtab) + return -ENOMEM; + + l2ptrs =3D kcalloc(BIT(l1_bits), sizeof(*l2ptrs), GFP_KERNEL); + if (!l2ptrs) { + kfree(l1devtab); + return -ENOMEM; + } + + for (i =3D 0; i < BIT(l1_bits); i++) + l1devtab[i] =3D cpu_to_le64(FIELD_PREP(GICV5_DTL1E_SPAN, l2_bits)); + + gicv5_its_dcache_clean(its, l1devtab, l1_sz); + + cfgr =3D FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL) | + FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, devtab_l2sz) | + FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, device_id_bits); + its_writel_relaxed(its, cfgr, GICV5_ITS_DT_CFGR); + + baser =3D virt_to_phys(l1devtab) & GICV5_ITS_DT_BASER_ADDR_MASK; + its_writeq_relaxed(its, baser, GICV5_ITS_DT_BASER); + + its->devtab_cfgr.cfgr =3D cfgr; + its->devtab_cfgr.l2.l1devtab =3D l1devtab; + its->devtab_cfgr.l2.l2ptrs =3D l2ptrs; + + return 0; +} + +/* + * Initialise the device table as either 1- or 2-level depending on what is + * supported by the hardware. + */ +static int gicv5_its_init_devtab(struct gicv5_its_chip_data *its) +{ + u8 device_id_bits, devtab_l2sz; + bool two_level_devtab; + u32 idr1; + + idr1 =3D its_readl_relaxed(its, GICV5_ITS_IDR1); + + device_id_bits =3D FIELD_GET(GICV5_ITS_IDR1_DEVICEID_BITS, idr1); + two_level_devtab =3D gicv5_its_l2sz_two_level(true, idr1, device_id_bits, + &devtab_l2sz); + if (two_level_devtab) + return gicv5_its_alloc_devtab_two_level(its, device_id_bits, + devtab_l2sz); + else + return gicv5_its_alloc_devtab_linear(its, device_id_bits); +} + +static void gicv5_its_compose_msi_msg(struct irq_data *d, struct msi_msg *= msg) +{ + struct gicv5_its_dev *its_dev =3D irq_data_get_irq_chip_data(d); + struct gicv5_its_chip_data *its =3D its_dev->its_node; + u64 addr; + + addr =3D its->its_trans_phys_base; + + msg->data =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + msi_msg_set_addr(irq_data_get_msi_desc(d), msg, addr); +} + +static const struct irq_chip gicv5_its_irq_chip =3D { + .name =3D "GICv5-ITS-MSI", + .irq_mask =3D irq_chip_mask_parent, + .irq_unmask =3D irq_chip_unmask_parent, + .irq_eoi =3D irq_chip_eoi_parent, + .irq_set_affinity =3D irq_chip_set_affinity_parent, + .irq_get_irqchip_state =3D irq_chip_get_parent_state, + .irq_set_irqchip_state =3D irq_chip_set_parent_state, + .irq_compose_msi_msg =3D gicv5_its_compose_msi_msg, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND +}; + +static struct gicv5_its_dev *gicv5_its_find_device(struct gicv5_its_chip_d= ata *its, + u32 device_id) +{ + struct gicv5_its_dev *dev =3D xa_load(&its->its_devices, device_id); + + return dev ? dev : ERR_PTR(-ENODEV); +} + +static struct gicv5_its_dev *gicv5_its_alloc_device(struct gicv5_its_chip_= data *its, int nvec, + u32 dev_id) +{ + struct gicv5_its_dev *its_dev; + void *entry; + int ret; + + its_dev =3D gicv5_its_find_device(its, dev_id); + if (!IS_ERR(its_dev)) { + pr_err("A device with this DeviceID (0x%x) has already been registered.\= n", + dev_id); + + return ERR_PTR(-EBUSY); + } + + its_dev =3D kzalloc(sizeof(*its_dev), GFP_KERNEL); + if (!its_dev) + return ERR_PTR(-ENOMEM); + + its_dev->device_id =3D dev_id; + its_dev->num_events =3D nvec; + + ret =3D gicv5_its_device_register(its, its_dev); + if (ret) { + pr_err("Failed to register the device\n"); + goto out_dev_free; + } + + gicv5_its_device_cache_inv(its, its_dev); + + its_dev->its_node =3D its; + + its_dev->event_map =3D (unsigned long *)bitmap_zalloc(its_dev->num_events= , GFP_KERNEL); + if (!its_dev->event_map) { + ret =3D -ENOMEM; + goto out_unregister; + } + + entry =3D xa_store(&its->its_devices, dev_id, its_dev, GFP_KERNEL); + if (xa_is_err(entry)) { + ret =3D xa_err(entry); + goto out_bitmap_free; + } + + return its_dev; +out_bitmap_free: + bitmap_free(its_dev->event_map); +out_unregister: + gicv5_its_device_unregister(its, its_dev); +out_dev_free: + kfree(its_dev); + return ERR_PTR(ret); +} + +static int gicv5_its_msi_prepare(struct irq_domain *domain, struct device = *dev, + int nvec, msi_alloc_info_t *info) +{ + u32 dev_id =3D info->scratchpad[0].ul; + struct msi_domain_info *msi_info; + struct gicv5_its_chip_data *its; + struct gicv5_its_dev *its_dev; + + msi_info =3D msi_get_domain_info(domain); + its =3D msi_info->data; + + guard(mutex)(&its->dev_alloc_lock); + + its_dev =3D gicv5_its_alloc_device(its, nvec, dev_id); + if (IS_ERR(its_dev)) + return PTR_ERR(its_dev); + + info->scratchpad[0].ptr =3D its_dev; + + return 0; +} + +static struct msi_domain_ops its_msi_domain_ops =3D { + .msi_prepare =3D gicv5_its_msi_prepare, +}; + +static int gicv5_its_map_event(struct gicv5_its_dev *its_dev, u16 event_id, + u32 lpi) +{ + struct gicv5_its_chip_data *its =3D its_dev->its_node; + u64 itt_entry; + __le64 *itte; + + itte =3D gicv5_its_device_get_itte_ref(its_dev, event_id); + + if (FIELD_GET(GICV5_ITTL2E_VALID, *itte)) + return -EEXIST; + + itt_entry =3D FIELD_PREP(GICV5_ITTL2E_LPI_ID, lpi) | + FIELD_PREP(GICV5_ITTL2E_VALID, 0x1); + + its_write_table_entry(its, itte, itt_entry); + + gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); + + return 0; +} + +static void gicv5_its_unmap_event(struct gicv5_its_dev *its_dev, u16 event= _id) +{ + struct gicv5_its_chip_data *its =3D its_dev->its_node; + u64 itte_val; + __le64 *itte; + + itte =3D gicv5_its_device_get_itte_ref(its_dev, event_id); + + itte_val =3D le64_to_cpu(*itte); + itte_val &=3D ~GICV5_ITTL2E_VALID; + + its_write_table_entry(its, itte, itte_val); + + gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); +} + +static int gicv5_its_alloc_eventid(struct gicv5_its_dev *its_dev, + unsigned int nr_irqs, u32 *eventid) +{ + int ret; + + ret =3D bitmap_find_free_region(its_dev->event_map, + its_dev->num_events, + get_count_order(nr_irqs)); + + if (ret < 0) + return ret; + + *eventid =3D ret; + + return 0; +} + +static void gicv5_its_free_eventid(struct gicv5_its_dev *its_dev, u32 even= t_id_base, + unsigned int nr_irqs) +{ + bitmap_release_region(its_dev->event_map, event_id_base, + get_count_order(nr_irqs)); +} + +static int gicv5_its_irq_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + u32 device_id, event_id_base, lpi; + struct msi_domain_info *msi_info; + struct gicv5_its_chip_data *its; + struct gicv5_its_dev *its_dev; + msi_alloc_info_t *info =3D arg; + irq_hw_number_t hwirq; + struct irq_data *irqd; + int ret, i; + + its_dev =3D info->scratchpad[0].ptr; + device_id =3D its_dev->device_id; + + msi_info =3D msi_get_domain_info(domain); + its =3D msi_info->data; + + ret =3D gicv5_its_alloc_eventid(its_dev, nr_irqs, &event_id_base); + if (ret) + return ret; + + ret =3D iommu_dma_prepare_msi(info->desc, its->its_trans_phys_base); + if (ret) + goto out_eventid; + + for (i =3D 0; i < nr_irqs; i++) { + lpi =3D gicv5_alloc_lpi(); + if (ret < 0) { + pr_debug("Failed to find free LPI!\n"); + goto out_eventid; + } + + ret =3D irq_domain_alloc_irqs_parent(domain, virq + i, 1, &lpi); + if (ret) + goto out_free_lpi; + + /* + * Store eventid and deviceid into the hwirq for later use. + * + * hwirq =3D event_id << 32 | device_id + */ + hwirq =3D FIELD_PREP(GICV5_ITS_HWIRQ_DEVICE_ID, device_id) | + FIELD_PREP(GICV5_ITS_HWIRQ_EVENT_ID, (u64)event_id_base + i); + irq_domain_set_info(domain, virq + i, hwirq, + &gicv5_its_irq_chip, its_dev, + handle_fasteoi_irq, NULL, NULL); + + irqd =3D irq_get_irq_data(virq + i); + irqd_set_single_target(irqd); + irqd_set_affinity_on_activate(irqd); + irqd_set_resend_when_in_progress(irqd); + } + + return 0; +out_free_lpi: + gicv5_free_lpi(lpi); +out_eventid: + gicv5_its_free_eventid(its_dev, event_id_base, nr_irqs); + + return ret; +} + +static void gicv5_its_irq_domain_free(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs) +{ + struct irq_data *d =3D irq_domain_get_irq_data(domain, virq); + struct gicv5_its_chip_data *its; + struct gicv5_its_dev *its_dev; + u16 event_id_base; + bool free_device; + unsigned int i; + + its_dev =3D irq_data_get_irq_chip_data(d); + its =3D its_dev->its_node; + + event_id_base =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + + guard(mutex)(&its->dev_alloc_lock); + + bitmap_release_region(its_dev->event_map, event_id_base, + get_count_order(nr_irqs)); + + free_device =3D bitmap_empty(its_dev->event_map, its_dev->num_events); + + /* Hierarchically free irq data */ + for (i =3D 0; i < nr_irqs; i++) { + d =3D irq_domain_get_irq_data(domain, virq + i); + + gicv5_free_lpi(d->parent_data->hwirq); + irq_domain_reset_irq_data(d); + irq_domain_free_irqs_parent(domain, virq + i, 1); + } + + gicv5_its_syncr(its, its_dev); + gicv5_irs_syncr(); + + if (free_device) { + gicv5_its_device_unregister(its, its_dev); + bitmap_free(its_dev->event_map); + xa_erase(&its->its_devices, its_dev->device_id); + kfree(its_dev); + } +} + +static int gicv5_its_irq_domain_activate(struct irq_domain *domain, + struct irq_data *d, bool reserve) +{ + struct gicv5_its_dev *its_dev =3D irq_data_get_irq_chip_data(d); + u16 event_id; + u32 lpi; + + event_id =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + lpi =3D d->parent_data->hwirq; + + return gicv5_its_map_event(its_dev, event_id, lpi); +} + +static void gicv5_its_irq_domain_deactivate(struct irq_domain *domain, + struct irq_data *d) +{ + struct gicv5_its_dev *its_dev =3D irq_data_get_irq_chip_data(d); + u16 event_id; + + event_id =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + + gicv5_its_unmap_event(its_dev, event_id); +} +static const struct irq_domain_ops gicv5_its_irq_domain_ops =3D { + .alloc =3D gicv5_its_irq_domain_alloc, + .free =3D gicv5_its_irq_domain_free, + .activate =3D gicv5_its_irq_domain_activate, + .deactivate =3D gicv5_its_irq_domain_deactivate, + .select =3D msi_lib_irq_domain_select, +}; + +static int gicv5_its_wait_for_cr0(struct gicv5_its_chip_data *its) +{ + return gicv5_wait_for_op_atomic(its->its_base, GICV5_ITS_CR0, + GICV5_ITS_CR0_IDLE, NULL); +} + +static void gicv5_its_print_info(struct gicv5_its_chip_data *its_node) +{ + bool devtab_linear; + u8 device_id_bits; + u8 str; + + device_id_bits =3D devtab_cfgr_field(its_node, DEVICEID_BITS); + + str =3D devtab_cfgr_field(its_node, STRUCTURE); + devtab_linear =3D (str =3D=3D GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR); + + pr_info("ITS %s enabled using %s device table device_id_bits %u\n", + fwnode_get_name(its_node->fwnode), + devtab_linear ? "linear" : "2-level", + device_id_bits); +} + +static int __init gicv5_its_init_bases(phys_addr_t its_trans_base, + void __iomem *its_base, + struct fwnode_handle *handle, + struct irq_domain *parent_domain) +{ + struct device_node *np =3D to_of_node(handle); + struct gicv5_its_chip_data *its_node; + struct msi_domain_info *info; + struct irq_domain *d; + u32 cr0, cr1; + bool enabled; + int ret; + + info =3D kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + its_node =3D kzalloc(sizeof(*its_node), GFP_KERNEL); + if (!its_node) { + ret =3D -ENOMEM; + goto out_free; + } + + info->ops =3D &its_msi_domain_ops; + info->data =3D its_node; + + mutex_init(&its_node->dev_alloc_lock); + xa_init(&its_node->its_devices); + its_node->fwnode =3D handle; + its_node->its_base =3D its_base; + its_node->its_trans_phys_base =3D its_trans_base; + + d =3D irq_domain_create_hierarchy(parent_domain, IRQ_DOMAIN_FLAG_ISOLATED= _MSI, + 0, handle, &gicv5_its_irq_domain_ops, info); + if (!d) { + ret =3D -ENOMEM; + goto out_free_node; + } + its_node->domain =3D d; + irq_domain_update_bus_token(its_node->domain, DOMAIN_BUS_NEXUS); + + its_node->domain->msi_parent_ops =3D &gic_its_msi_parent_ops; + its_node->domain->flags |=3D IRQ_DOMAIN_FLAG_MSI_PARENT; + + cr0 =3D its_readl_relaxed(its_node, GICV5_ITS_CR0); + enabled =3D FIELD_GET(GICV5_ITS_CR0_ITSEN, cr0); + if (WARN(enabled, "ITS %s enabled, disabling it before proceeding\n", np-= >full_name)) { + cr0 =3D FIELD_PREP(GICV5_ITS_CR0_ITSEN, 0x0); + its_writel_relaxed(its_node, cr0, GICV5_ITS_CR0); + ret =3D gicv5_its_wait_for_cr0(its_node); + if (ret) + goto out_dom_remove; + } + + if (of_property_read_bool(np, "dma-noncoherent")) { + /* + * A non-coherent ITS implies that some cache levels cannot be + * used coherently by the cores and GIC. Our only option is to mark + * memory attributes for the GIC as non-cacheable; by default, + * non-cacheable memory attributes imply outer-shareable + * shareability, the value written into ITS_CR1_SH is ignored. + */ + cr1 =3D FIELD_PREP(GICV5_ITS_CR1_ITT_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_DT_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_IC, GICV5_NON_CACHE) | + FIELD_PREP(GICV5_ITS_CR1_OC, GICV5_NON_CACHE); + its_node->flags |=3D ITS_FLAGS_NON_COHERENT; + } else { + cr1 =3D FIELD_PREP(GICV5_ITS_CR1_ITT_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_DT_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_IC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_ITS_CR1_OC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_ITS_CR1_SH, GICV5_INNER_SHARE); + } + + its_writel_relaxed(its_node, cr1, GICV5_ITS_CR1); + + ret =3D gicv5_its_init_devtab(its_node); + if (ret) + goto out_dom_remove; + + cr0 =3D FIELD_PREP(GICV5_ITS_CR0_ITSEN, 0x1); + its_writel_relaxed(its_node, cr0, GICV5_ITS_CR0); + + ret =3D gicv5_its_wait_for_cr0(its_node); + if (ret) + goto out_dom_remove; + + list_add(&its_node->entry, &its_nodes); + + gicv5_its_print_info(its_node); + + return 0; +out_dom_remove: + irq_domain_remove(its_node->domain); +out_free_node: + kfree(its_node); +out_free: + kfree(info); + return ret; +} + +static int __init gicv5_its_init(struct device_node *node) +{ + void __iomem *its_base; + struct resource res; + int ret; + + its_base =3D of_io_request_and_map(node, 0, "ITS"); + if (IS_ERR(its_base)) { + pr_err("%pOF: unable to map GICv5 ITS_CONFIG_FRAME\n", node); + return PTR_ERR(its_base); + } + + /* + * The ITS_TRANSLATE_FRAME is the second reg entry, (first is the + * ITS_CONFIG_FRAME) - extract it and use it to init ITS data + * structures. + */ + ret =3D of_address_to_resource(node, 1, &res); + if (ret) + goto out_unmap; + + ret =3D gicv5_its_init_bases(res.start, its_base, &node->fwnode, + gicv5_global_data.lpi_domain); + if (ret) + goto out_unmap; + + return 0; +out_unmap: + iounmap(its_base); + return ret; +} + +void __init gicv5_its_of_probe(struct device_node *parent) +{ + struct device_node *np; + + for_each_available_child_of_node(parent, np) { + if (!of_device_is_compatible(np, "arm,gic-v5-its")) + continue; + + if (gicv5_its_init(np)) + pr_err("Failed to init ITS %s\n", np->full_name); + } +} diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index e4bb02a1988b01a23db61288ff1b1fe3db02e0e4..910d7cdc7fa502b1a9ed37a05b1= 26a82c9dc2807 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -57,12 +57,12 @@ static void release_lpi(u32 lpi) ida_free(&lpi_ida, lpi); } =20 -static int gicv5_alloc_lpi(void) +int gicv5_alloc_lpi(void) { return alloc_lpi(); } =20 -static void gicv5_free_lpi(u32 lpi) +void gicv5_free_lpi(u32 lpi) { release_lpi(lpi); } @@ -1031,6 +1031,8 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa =20 gicv5_smp_init(); =20 + gicv5_irs_its_probe(); + return 0; out_int: gicv5_cpu_disable_interrupts(); diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index ff00c12cb9ec6758e135e6a7411873066d76763d..2d83ec87a4cf4d0ea7809d58f5a= 8bdadaa7c7135 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -8,6 +8,8 @@ #include =20 #include +#include + #include #include =20 @@ -44,6 +46,8 @@ #define GICV5_IRS_IDR7 0x001c #define GICV5_IRS_CR0 0x0080 #define GICV5_IRS_CR1 0x0084 +#define GICV5_IRS_SYNCR 0x00c0 +#define GICV5_IRS_SYNC_STATUSR 0x00c4 #define GICV5_IRS_SPI_SELR 0x0108 #define GICV5_IRS_SPI_CFGR 0x0114 #define GICV5_IRS_SPI_STATUSR 0x0118 @@ -97,6 +101,10 @@ #define GICV5_IRS_CR1_OC GENMASK(3, 2) #define GICV5_IRS_CR1_SH GENMASK(1, 0) =20 +#define GICV5_IRS_SYNCR_SYNC BIT(31) + +#define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0) + #define GICV5_IRS_SPI_STATUSR_V BIT(1) #define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) =20 @@ -138,6 +146,101 @@ =20 #define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) =20 +#define GICV5_ITS_IDR1 0x0004 +#define GICV5_ITS_IDR2 0x0008 +#define GICV5_ITS_CR0 0x0080 +#define GICV5_ITS_CR1 0x0084 +#define GICV5_ITS_DT_BASER 0x00c0 +#define GICV5_ITS_DT_CFGR 0x00d0 +#define GICV5_ITS_DIDR 0x0100 +#define GICV5_ITS_EIDR 0x0108 +#define GICV5_ITS_INV_EVENTR 0x010c +#define GICV5_ITS_INV_DEVICER 0x0110 +#define GICV5_ITS_STATUSR 0x0120 +#define GICV5_ITS_SYNCR 0x0140 +#define GICV5_ITS_SYNC_STATUSR 0x0148 + +#define GICV5_ITS_IDR1_L2SZ GENMASK(10, 8) +#define GICV5_ITS_IDR1_ITT_LEVELS BIT(7) +#define GICV5_ITS_IDR1_DT_LEVELS BIT(6) +#define GICV5_ITS_IDR1_DEVICEID_BITS GENMASK(5, 0) + +#define GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(8), (r)) +#define GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(9), (r)) +#define GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(10), (r)) + +#define GICV5_ITS_IDR2_XDMN_EVENTs GENMASK(6, 5) +#define GICV5_ITS_IDR2_EVENTID_BITS GENMASK(4, 0) + +#define GICV5_ITS_CR0_IDLE BIT(1) +#define GICV5_ITS_CR0_ITSEN BIT(0) + +#define GICV5_ITS_CR1_ITT_RA BIT(7) +#define GICV5_ITS_CR1_DT_RA BIT(6) +#define GICV5_ITS_CR1_IC GENMASK(5, 4) +#define GICV5_ITS_CR1_OC GENMASK(3, 2) +#define GICV5_ITS_CR1_SH GENMASK(1, 0) + +#define GICV5_ITS_DT_CFGR_STRUCTURE BIT(16) +#define GICV5_ITS_DT_CFGR_L2SZ GENMASK(7, 6) +#define GICV5_ITS_DT_CFGR_DEVICEID_BITS GENMASK(5, 0) + +#define GICV5_ITS_DT_BASER_ADDR_MASK GENMASK_ULL(55, 3) + +#define GICV5_ITS_INV_DEVICER_I BIT(31) +#define GICV5_ITS_INV_DEVICER_EVENTID_BITS GENMASK(5, 1) +#define GICV5_ITS_INV_DEVICER_L1 BIT(0) + +#define GICV5_ITS_DIDR_DEVICEID GENMASK_ULL(31, 0) + +#define GICV5_ITS_EIDR_EVENTID GENMASK(15, 0) + +#define GICV5_ITS_INV_EVENTR_I BIT(31) +#define GICV5_ITS_INV_EVENTR_ITT_L2SZ GENMASK(2, 1) +#define GICV5_ITS_INV_EVENTR_L1 BIT(0) + +#define GICV5_ITS_STATUSR_IDLE BIT(0) + +#define GICV5_ITS_SYNCR_SYNC BIT_ULL(63) +#define GICV5_ITS_SYNCR_SYNCALL BIT_ULL(32) +#define GICV5_ITS_SYNCR_DEVICEID GENMASK_ULL(31, 0) + +#define GICV5_ITS_SYNC_STATUSR_IDLE BIT(0) + +#define GICV5_DTL1E_VALID BIT_ULL(0) +// Note that there is no shift for the address by design +#define GICV5_DTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) +#define GICV5_DTL1E_SPAN GENMASK_ULL(63, 60) + +#define GICV5_DTL2E_VALID BIT_ULL(0) +#define GICV5_DTL2E_ITT_L2SZ GENMASK_ULL(2, 1) +// Note that there is no shift for the address by design +#define GICV5_DTL2E_ITT_ADDR_MASK GENMASK_ULL(55, 3) +#define GICV5_DTL2E_ITT_DSWE BIT_ULL(57) +#define GICV5_DTL2E_ITT_STRUCTURE BIT_ULL(58) +#define GICV5_DTL2E_EVENT_ID_BITS GENMASK_ULL(63, 59) + +#define GICV5_ITTL1E_VALID BIT_ULL(0) +// Note that there is no shift for the address by design +#define GICV5_ITTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) +#define GICV5_ITTL1E_SPAN GENMASK_ULL(63, 60) + +#define GICV5_ITTL2E_LPI_ID GENMASK_ULL(23, 0) +#define GICV5_ITTL2E_DAC GENMASK_ULL(29, 28) +#define GICV5_ITTL2E_VIRTUAL BIT_ULL(30) +#define GICV5_ITTL2E_VALID BIT_ULL(31) +#define GICV5_ITTL2E_VM_ID GENMASK_ULL(47, 32) + +#define GICV5_ITS_DT_ITT_CFGR_L2SZ_4k 0b00 +#define GICV5_ITS_DT_ITT_CFGR_L2SZ_16k 0b01 +#define GICV5_ITS_DT_ITT_CFGR_L2SZ_64k 0b10 + +#define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR 0 +#define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL 1 + +#define GICV5_ITS_HWIRQ_DEVICE_ID GENMASK_ULL(31, 0) +#define GICV5_ITS_HWIRQ_EVENT_ID GENMASK_ULL(63, 32) + struct gicv5_chip_data { struct fwnode_handle *fwnode; struct irq_domain *ppi_domain; @@ -188,21 +291,97 @@ static inline int gicv5_wait_for_op_s_atomic(void __i= omem *addr, u32 offset, return 0; } =20 +static inline int gicv5_wait_for_op_s(void __iomem *addr, u32 offset, + const char *reg_s, u32 mask) +{ + void __iomem *reg =3D addr + offset; + u32 val; + int ret; + + ret =3D readl_poll_timeout(reg, val, val & mask, 1, 10 * USEC_PER_MSEC); + if (unlikely(ret =3D=3D -ETIMEDOUT)) { + pr_err_ratelimited("%s timeout...\n", reg_s); + return ret; + } + + return 0; +} + #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) =20 +#define gicv5_wait_for_op(base, reg, mask) \ + gicv5_wait_for_op_s(base, reg, #reg, mask) + void __init gicv5_init_lpi_domain(void); void __init gicv5_free_lpi_domain(void); =20 int gicv5_irs_of_probe(struct device_node *parent); void gicv5_irs_remove(void); int gicv5_irs_enable(void); +void gicv5_irs_its_probe(void); int gicv5_irs_register_cpu(int cpuid); int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); int gicv5_irs_iste_alloc(u32 lpi); +void gicv5_irs_syncr(void); + +struct gicv5_its_devtab_cfg { + union { + struct { + __le64 *devtab; + } linear; + struct { + __le64 *l1devtab; + __le64 **l2ptrs; + } l2; + }; + u32 cfgr; +}; + +struct gicv5_its_itt_cfg { + union { + struct { + __le64 *itt; + unsigned int num_ents; + } linear; + struct { + __le64 *l1itt; + __le64 **l2ptrs; + unsigned int num_l1_ents; + u8 l2sz; + } l2; + }; + u8 event_id_bits; + bool l2itt; +}; + +struct gicv5_its_chip_data { + struct list_head entry; + struct xarray its_devices; + struct mutex dev_alloc_lock; + struct fwnode_handle *fwnode; + struct gicv5_its_devtab_cfg devtab_cfgr; + struct irq_domain *domain; + void __iomem *its_base; + phys_addr_t its_trans_phys_base; + u32 flags; +}; + +struct gicv5_its_dev { + struct gicv5_its_chip_data *its_node; + struct gicv5_its_itt_cfg itt_cfg; + unsigned long *event_map; + u32 device_id; + u32 num_events; +}; =20 void gicv5_init_lpis(u32 max); void gicv5_deinit_lpis(void); + +int gicv5_alloc_lpi(void); +void gicv5_free_lpi(u32 lpi); + +void __init gicv5_its_of_probe(struct device_node *parent); #endif --=20 2.48.0 From nobody Tue Dec 16 15:42:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60241284B27; Tue, 6 May 2025 12:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534351; cv=none; b=iWVnrDgKMKn6KS6DgCsxb9tQV6iKsHYnndMucoCEQ4e0Krzv1gNZqifAmbBAmmNGuaN+58x8H2z12gJZctLoMmxiM1pbMQA+g4KdNpm5chIVPNLkwVoxpt/5j2gUQKVBnpVsI9ehS3nLmxYS7QPrBwiL1YqFvUd3bBhvfZGaXag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746534351; c=relaxed/simple; bh=Dhr0rsx9WpeMa8aspdbgl7YO+d4d6KcEE2+waQCoYbI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DUIkXyAPVasPMzdab9bY7M2Lu/syAIFSmTOl/ssn8PbR+x1Db2uVinoDODUm30pyY7HA/zGis6kiiO5Bvdrr2y14W6MZBlSecJZCc7ADYXt+tzKEumEV9p2zB1ILz7ygTwWI4/SXjH92m4pWAXV58g4ZdHv6nXHuWBUnh+EBjZM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Dq5cTMty; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Dq5cTMty" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58A11C4CEF0; Tue, 6 May 2025 12:25:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746534351; bh=Dhr0rsx9WpeMa8aspdbgl7YO+d4d6KcEE2+waQCoYbI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Dq5cTMtyj0wHuo1T5aHKQkBcSlr+6GhC/2Qcc90isxK0fDRSfA0/Qo/GQnLnu53YZ 6S/53TJ5C1EXGWuq4Qd55nzieRvN0xzjjM3zme/3EvAv4Wj3tLhELaUTdAMAidfbFd kIbLU6kV4uSUVi8DAvFe09ZzCOdtMaL8hHvY51pQKaTND8dkWddz1nSt6/ZiBZ90+8 uK2I0XBLiZ7PxGSEZFtnHWlCj1BsFMF9AXFId2lfnYLepQi8xtoX+EyKVmoF7H2krc T24abHve5ye3qgA806xvLjWw+4bjpPF648cjcMWeaQ982/BBEa3ZbF+LAkI0/8E+ro 6WBwFb1pMheHA== From: Lorenzo Pieralisi Date: Tue, 06 May 2025 14:23:54 +0200 Subject: [PATCH v3 25/25] arm64: Kconfig: Enable GICv5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250506-gicv5-host-v3-25-6edd5a92fd09@kernel.org> References: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> In-Reply-To: <20250506-gicv5-host-v3-0-6edd5a92fd09@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Timothy Hayes , "Liam R. Howlett" , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.14.2 Enable GICv5 driver code for the ARM64 architecture. Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a182295e6f08bfa0f3e6f630dc4adfe797a4d273..f1b3c695b376717979ae8648652= 38ae12ad65ca2 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -128,6 +128,7 @@ config ARM64 select ARM_GIC_V2M if PCI select ARM_GIC_V3 select ARM_GIC_V3_ITS if PCI + select ARM_GIC_V5 select ARM_PSCI_FW select BUILDTIME_TABLE_SORT select CLONE_BACKWARDS --=20 2.48.0