blob: 589832793d09490e63f21b2958f15173f903fe42 [file] [log] [blame]
Arthur Heymans3df6cc92023-06-27 16:44:59 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <acpi/acpi.h>
Felix Held4a9ed702023-12-05 22:09:14 +01004#include <device/device.h>
Arthur Heymans3df6cc92023-06-27 16:44:59 +02005
6static int acpi_create_madt_one_gicc_v3(acpi_madt_gicc_t *gicc, u32 acpi_uid, u32 pi_gsiv,
7 uint32_t vgic_mi, uint64_t mpidr)
8{
9 memset(gicc, 0, sizeof(acpi_madt_gicc_t));
10 gicc->type = GICC;
11 gicc->length = sizeof(acpi_madt_gicc_t);
12 gicc->reserved = 0;
13 gicc->cpu_interface_number = 0; /* V3, no compat mode */
14 gicc->acpi_processor_uid = acpi_uid;
15 gicc->flags.enabled = 1;
Naresh Solanki75f0b602023-09-25 13:59:25 +020016 gicc->parking_protocol_version = 0; /* Assume PSCI exclusively */
Arthur Heymans3df6cc92023-06-27 16:44:59 +020017 gicc->performance_interrupt_gsiv = pi_gsiv;
18 gicc->parked_address = 0;
19 gicc->physical_base_address = 0; /* V3, no compat mode */
20 gicc->vgic_maintenance_interrupt = vgic_mi;
21 gicc->gicr_base_address = 0; /* ignored by OSPM if GICR is present */
22 gicc->processor_power_efficiency_class = 0; /* Ignore for now */
23 /* For platforms implementing GIC V3 the format must be:
24 * Bits [63:40] Must be zero
25 * Bits [39:32] Aff3 : Match Aff3 of target processor MPIDR
26 * Bits [31:24] Must be zero
27 * Bits [23:16] Aff2 : Match Aff2 of target processor MPIDR
28 * Bits [15:8] Aff1 : Match Aff1 of target processor MPIDR
29 * Bits [7:0] Aff0 : Match Aff0 of target processor MPIDR
30 */
31 gicc->mpidr = mpidr & 0xff00fffffful;
32
33 return gicc->length;
34}
35
36static unsigned long acpi_create_madt_giccs_v3(unsigned long current)
37{
38 // Loop over CPUs GIC
39 uint32_t acpi_id = 0;
40 for (struct device *dev = dev_find_path(NULL, DEVICE_PATH_GICC_V3); dev;
41 dev = dev_find_path(dev, DEVICE_PATH_GICC_V3)) {
42 acpi_madt_gicc_t *gicc = (acpi_madt_gicc_t *)current;
43 current += acpi_create_madt_one_gicc_v3(gicc, acpi_id++,
44 dev->path.gicc_v3.pi_gsiv,
45 dev->path.gicc_v3.vgic_mi,
46 dev->path.gicc_v3.mpidr);
47 }
48
49 return current;
50}
51
52static unsigned long acpi_create_madt_gicd_v3(unsigned long current)
53{
54 acpi_madt_gicd_t *gicd = (acpi_madt_gicd_t *)current;
55 memset(gicd, 0, sizeof(acpi_madt_gicd_t));
56 gicd->type = GICD;
57 gicd->length = sizeof(acpi_madt_gicd_t);
58 gicd->physical_base_address = platform_get_gicd_base();
59 gicd->system_vector_base = 0;
60 gicd->gic_version = 3;
61
62 return current + gicd->length;
63}
64
65/*
66 * The redistributor in GICv3 has two 64KB frames per CPU; in
67 * GICv4 it has four 64KB frames per CPU.
68 */
69#define GICV3_REDIST_SIZE 0x20000
70#define GICV4_REDIST_SIZE 0x40000
71static unsigned long acpi_create_madt_gicr_v3(unsigned long current)
72{
73 acpi_madt_gicr_t *gicr = (acpi_madt_gicr_t *)current;
74 memset(gicr, 0, sizeof(acpi_madt_gicr_t));
75 gicr->type = GICR;
76 gicr->length = sizeof(acpi_madt_gicr_t);
77 gicr->discovery_range_base_address = platform_get_gicr_base();
78 gicr->discovery_range_length = GICV3_REDIST_SIZE * CONFIG_MAX_CPUS;
79
80 return current + gicr->length;
81}
82
Naresh Solanki1fe19042023-09-25 14:24:34 +020083__weak int platform_get_gic_its(uintptr_t **base)
84{
85 return 0;
86}
87
88static unsigned long acpi_create_madt_gic_its_v3(unsigned long current)
89{
90 int i, its_count;
91 uintptr_t *its_base;
92
93 its_count = platform_get_gic_its(&its_base);
94
95 for (i = 0; i < its_count; i++) {
96 acpi_madt_gic_its_t *gic_its = (acpi_madt_gic_its_t *)current;
97 memset(gic_its, 0, sizeof(acpi_madt_gic_its_t));
98 gic_its->type = GIC_ITS;
99 gic_its->gic_its_id = i;
100 gic_its->physical_base_address = its_base[i];
101 gic_its->length = sizeof(acpi_madt_gic_its_t);
102
103 current = current + gic_its->length;
104 }
105 return current;
106}
107
Arthur Heymans3df6cc92023-06-27 16:44:59 +0200108unsigned long acpi_arch_fill_madt(acpi_madt_t *madt, unsigned long current)
109{
110 current = acpi_create_madt_giccs_v3(current);
111 current = acpi_create_madt_gicd_v3(current);
112 current = acpi_create_madt_gicr_v3(current);
Naresh Solanki1fe19042023-09-25 14:24:34 +0200113 current = acpi_create_madt_gic_its_v3(current);
Arthur Heymans3df6cc92023-06-27 16:44:59 +0200114
115 return current;
116}