1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/device.h>
6 __weak
void platform_fill_gicc(acpi_madt_gicc_t
*gicc
)
10 static int acpi_create_madt_one_gicc_v3(acpi_madt_gicc_t
*gicc
, u32 acpi_uid
, u32 pi_gsiv
,
11 uint32_t vgic_mi
, uint64_t mpidr
)
13 memset(gicc
, 0, sizeof(acpi_madt_gicc_t
));
15 gicc
->length
= sizeof(acpi_madt_gicc_t
);
17 gicc
->cpu_interface_number
= 0; /* V3, no compat mode */
18 gicc
->acpi_processor_uid
= acpi_uid
;
19 gicc
->flags
.enabled
= 1;
20 gicc
->parking_protocol_version
= 0; /* Assume PSCI exclusively */
21 gicc
->performance_interrupt_gsiv
= pi_gsiv
;
22 gicc
->parked_address
= 0;
23 gicc
->physical_base_address
= 0; /* V3, no compat mode */
24 gicc
->vgic_maintenance_interrupt
= vgic_mi
;
25 gicc
->gicr_base_address
= 0; /* ignored by OSPM if GICR is present */
26 gicc
->processor_power_efficiency_class
= 0; /* Ignore for now */
27 /* For platforms implementing GIC V3 the format must be:
28 * Bits [63:40] Must be zero
29 * Bits [39:32] Aff3 : Match Aff3 of target processor MPIDR
30 * Bits [31:24] Must be zero
31 * Bits [23:16] Aff2 : Match Aff2 of target processor MPIDR
32 * Bits [15:8] Aff1 : Match Aff1 of target processor MPIDR
33 * Bits [7:0] Aff0 : Match Aff0 of target processor MPIDR
35 gicc
->mpidr
= mpidr
& 0xff00fffffful
;
37 platform_fill_gicc(gicc
);
42 static unsigned long acpi_create_madt_giccs_v3(unsigned long current
)
46 for (struct device
*dev
= dev_find_path(NULL
, DEVICE_PATH_GICC_V3
); dev
;
47 dev
= dev_find_path(dev
, DEVICE_PATH_GICC_V3
)) {
48 acpi_madt_gicc_t
*gicc
= (acpi_madt_gicc_t
*)current
;
49 current
+= acpi_create_madt_one_gicc_v3(gicc
, acpi_id
++,
50 dev
->path
.gicc_v3
.pi_gsiv
,
51 dev
->path
.gicc_v3
.vgic_mi
,
52 dev
->path
.gicc_v3
.mpidr
);
58 static unsigned long acpi_create_madt_gicd_v3(unsigned long current
)
60 acpi_madt_gicd_t
*gicd
= (acpi_madt_gicd_t
*)current
;
61 memset(gicd
, 0, sizeof(acpi_madt_gicd_t
));
63 gicd
->length
= sizeof(acpi_madt_gicd_t
);
64 gicd
->physical_base_address
= platform_get_gicd_base();
65 gicd
->system_vector_base
= 0;
66 gicd
->gic_version
= 3;
68 return current
+ gicd
->length
;
72 * The redistributor in GICv3 has two 64KB frames per CPU; in
73 * GICv4 it has four 64KB frames per CPU.
75 #define GICV3_REDIST_SIZE 0x20000
76 #define GICV4_REDIST_SIZE 0x40000
77 static unsigned long acpi_create_madt_gicr_v3(unsigned long current
)
79 acpi_madt_gicr_t
*gicr
= (acpi_madt_gicr_t
*)current
;
80 memset(gicr
, 0, sizeof(acpi_madt_gicr_t
));
82 gicr
->length
= sizeof(acpi_madt_gicr_t
);
83 gicr
->discovery_range_base_address
= platform_get_gicr_base();
84 gicr
->discovery_range_length
= GICV3_REDIST_SIZE
* CONFIG_MAX_CPUS
;
86 return current
+ gicr
->length
;
89 __weak
int platform_get_gic_its(uintptr_t **base
)
94 static unsigned long acpi_create_madt_gic_its_v3(unsigned long current
)
99 its_count
= platform_get_gic_its(&its_base
);
101 for (i
= 0; i
< its_count
; i
++) {
102 acpi_madt_gic_its_t
*gic_its
= (acpi_madt_gic_its_t
*)current
;
103 memset(gic_its
, 0, sizeof(acpi_madt_gic_its_t
));
104 gic_its
->type
= GIC_ITS
;
105 gic_its
->gic_its_id
= i
;
106 gic_its
->physical_base_address
= its_base
[i
];
107 gic_its
->length
= sizeof(acpi_madt_gic_its_t
);
109 current
= current
+ gic_its
->length
;
114 unsigned long acpi_arch_fill_madt(acpi_madt_t
*madt
, unsigned long current
)
116 current
= acpi_create_madt_giccs_v3(current
);
117 current
= acpi_create_madt_gicd_v3(current
);
118 current
= acpi_create_madt_gicr_v3(current
);
119 current
= acpi_create_madt_gic_its_v3(current
);