Skip to content

Commit 9a236f8

Browse files
ZiadElhanafykartben
authored andcommitted
drivers: gic: Add multiple GIC redistributors regions support
For GIC multiple views feature support, all GIC Re-distributor's GICR_TYPER.last will be set. Because configuration view-0 can assign non-contiguous CPUs to views other than 0, in this case the GIC Redistributors' registers won't seem contiguous. So the GIC driver should cope with multiple sets of redistributors like multi-chip scenarios. In this patch we add multiple GIC redistributor regions support in GIC redistributor iteration. For more information, refer to the Multi view subsection in the GIC Technical Reference Manual. For example: https://developer.arm.com/documentation/101516/0400/Operation-of-GIC-700/Multi-view Signed-off-by: Ziad Elhanafy <ziad.elhanafy@arm.com>
1 parent 176676d commit 9a236f8

File tree

3 files changed

+101
-19
lines changed

3 files changed

+101
-19
lines changed

drivers/interrupt_controller/intc_gicv3.c

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright 2020 Broadcom
33
* Copyright 2024 NXP
4+
* Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
45
*
56
* SPDX-License-Identifier: Apache-2.0
67
*/
@@ -20,6 +21,33 @@
2021

2122
#define DT_DRV_COMPAT arm_gic_v3
2223

24+
#define GIC_V3_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(DT_DRV_COMPAT)
25+
26+
#define GIC_REDISTRIBUTOR_STRIDE DT_PROP_OR(GIC_V3_NODE, redistributor_stride, 0)
27+
#define GIC_NUM_REDISTRIBUTOR_REGIONS DT_PROP_OR(GIC_V3_NODE, redistributor_regions, 1)
28+
29+
#define GIC_REG_REGION(idx, node_id) \
30+
{ \
31+
.base = DT_REG_ADDR_BY_IDX(node_id, idx), \
32+
.size = DT_REG_SIZE_BY_IDX(node_id, idx), \
33+
}
34+
35+
/*
36+
* Structure to save GIC register region info
37+
*/
38+
struct gic_reg_region {
39+
mem_addr_t base;
40+
mem_addr_t size;
41+
};
42+
43+
/*
44+
* GIC register regions info table
45+
*/
46+
static struct gic_reg_region gic_reg_regions[] = {
47+
LISTIFY(DT_NUM_REGS(GIC_V3_NODE), GIC_REG_REGION, (,), GIC_V3_NODE)
48+
};
49+
50+
2351
/* Redistributor base addresses for each core */
2452
mem_addr_t gic_rdists[CONFIG_MP_MAX_NUM_CPUS];
2553

@@ -578,20 +606,34 @@ static inline uint64_t arm_gic_get_typer(mem_addr_t addr)
578606
static mem_addr_t arm_gic_iterate_rdists(void)
579607
{
580608
uint64_t aff = arm_gic_mpidr_to_affinity(GET_MPIDR());
609+
uint32_t idx;
581610

582-
for (mem_addr_t rdist_addr = GIC_RDIST_BASE;
583-
rdist_addr < GIC_RDIST_BASE + GIC_RDIST_SIZE;
584-
rdist_addr += 0x20000) {
585-
uint64_t val = arm_gic_get_typer(rdist_addr + GICR_TYPER);
586-
uint64_t gicr_aff = GICR_TYPER_AFFINITY_VALUE_GET(val);
611+
/* Skip the first array entry as it refers to the GIC distributor */
612+
for (idx = 1; idx < GIC_NUM_REDISTRIBUTOR_REGIONS + 1; idx++) {
613+
uint64_t val;
614+
mem_addr_t rdist_addr = gic_reg_regions[idx].base;
615+
mem_addr_t rdist_end = rdist_addr + gic_reg_regions[idx].size;
587616

588-
if (arm_gic_aff_matching(gicr_aff, aff)) {
589-
return rdist_addr;
590-
}
617+
do {
618+
val = arm_gic_get_typer(rdist_addr + GICR_TYPER);
619+
uint64_t gicr_aff = GICR_TYPER_AFFINITY_VALUE_GET(val);
591620

592-
if (GICR_TYPER_LAST_GET(val) == 1) {
593-
return (mem_addr_t)NULL;
594-
}
621+
if (arm_gic_aff_matching(gicr_aff, aff)) {
622+
return rdist_addr;
623+
}
624+
625+
if (GIC_REDISTRIBUTOR_STRIDE > 0) {
626+
rdist_addr += GIC_REDISTRIBUTOR_STRIDE;
627+
} else {
628+
/*
629+
* Skip RD_base and SGI_base
630+
* In GICv3, GICR_TYPER.VLPIS bit is RES0 and can can be ignored
631+
* as there are no VLPI and reserved pages.
632+
*/
633+
rdist_addr += KB(64) * 2;
634+
}
635+
636+
} while ((!GICR_TYPER_LAST_GET(val)) && (rdist_addr < rdist_end));
595637
}
596638

597639
return (mem_addr_t)NULL;

drivers/interrupt_controller/intc_gicv3_priv.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright 2020 Broadcom
3+
* Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -25,13 +26,6 @@
2526
#define GIC_BASER_SHARE_INNER 0x1UL /* Inner Shareable */
2627
#define GIC_BASER_SHARE_OUTER 0x2UL /* Outer Shareable */
2728

28-
/*
29-
* GIC Register Interface Base Addresses
30-
*/
31-
32-
#define GIC_RDIST_BASE DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1)
33-
#define GIC_RDIST_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1)
34-
3529
/* SGI base is at 64K offset from Redistributor */
3630
#define GICR_SGI_BASE_OFF 0x10000
3731

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
1+
#
2+
# Copyright 2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
3+
#
14
# SPDX-License-Identifier: Apache-2.0
5+
#
26

3-
description: ARM Generic Interrupt Controller v3
7+
description: |
8+
ARM Generic Interrupt Controller v3
9+
10+
Examples for GICv3 devicetree nodes:
11+
12+
gic: interrupt-controller@2cf00000 {
13+
compatible = "arm,gic-v3", "arm,gic";
14+
reg = <0x2f000000 0x10000>, /* GICD */
15+
<0x2f100000 0x200000>; /* GICR */
16+
interrupt-controller;
17+
#interrupt-cells = <3>;
18+
status = "okay";
19+
};
20+
21+
gic: interrupt-controller@2c010000 {
22+
compatible = "arm,gic-v3", "arm,gic";
23+
redistributor-stride = <0x40000>; /* 256kB stride */
24+
redistributor-regions = <2>;
25+
reg = <0x2c010000 0x10000>, /* GICD */
26+
<0x2d000000 0x800000>, /* GICR 1: CPUs 0-31 */
27+
<0x2e000000 0x800000>; /* GICR 2: CPUs 32-63 */
28+
interrupt-controller;
29+
#interrupt-cells = <4>;
30+
status = "okay";
31+
};
432
533
compatible: arm,gic-v3
634

735
include: arm,gic.yaml
36+
37+
properties:
38+
redistributor-stride:
39+
type: int
40+
description:
41+
If using padding pages, specifies the stride of consecutive
42+
redistributors which is the distance between consecutive redistributors in
43+
memory. Must be a multiple of 64kB. Required if the distance between
44+
redistributors is not the default 128kB.
45+
46+
redistributor-regions:
47+
type: int
48+
description:
49+
The number of independent contiguous regions occupied by the redistributors.
50+
The term "regions" refers to distinct memory segments or areas allocated
51+
for redistributors within the system memory. The number of redistributor
52+
regions and their sizes are hardware-specific. Required if more than one
53+
such region is present.

0 commit comments

Comments
 (0)