From: Sergiu Moga Date: Sun, 21 May 2023 13:17:50 +0000 (+0300) Subject: plat: Enable secondary cores allocation through `ACPI` on `ARM64` X-Git-Tag: RELEASE-0.14.0~47 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=0b02ff343b36203d17eb4461f588cadee07e286a;p=unikraft%2Funikraft.git plat: Enable secondary cores allocation through `ACPI` on `ARM64` Split secondary cores enumeration in two methods: - if CONFIG_UKPLAT_ACPI is enabled then get the information through the `MADT`'s `GICC` structures - else rely on the `Devicetree`'s `cpu@` nodes Signed-off-by: Sergiu Moga Reviewed-by: Razvan Virtan Reviewed-by: Michalis Pappas Approved-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Closes: #912 --- diff --git a/plat/common/arm/lcpu.c b/plat/common/arm/lcpu.c index 3a827c351..213b5f37e 100644 --- a/plat/common/arm/lcpu.c +++ b/plat/common/arm/lcpu.c @@ -30,6 +30,8 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include #include @@ -73,7 +75,6 @@ void __noreturn lcpu_arch_jump_to(void *sp, ukplat_lcpu_entry_t entry) #define FDT_SIZE_CELLS_DEFAULT 0 #define FDT_ADDR_CELLS_DEFAULT 2 -static void *dtb; void lcpu_start(struct lcpu *cpu); static __paddr_t lcpu_start_paddr; extern struct _gic_dev *gic; @@ -92,7 +93,59 @@ int lcpu_arch_init(struct lcpu *this_lcpu) return ret; } -int lcpu_arch_mp_init(void *arg) +#ifdef CONFIG_UKPLAT_ACPI +static int do_arch_mp_init(void *arg __unused) +{ + __lcpuid bsp_cpu_id = lcpu_get(0)->id; + int bsp_found __maybe_unused = 0; + union { + struct acpi_madt_gicc *gicc; + struct acpi_subsdt_hdr *h; + } m; + struct lcpu *lcpu; + struct acpi_madt *madt; + __lcpuid cpu_id; + __sz off, len; + + uk_pr_info("Bootstrapping processor has the ID %ld\n", bsp_cpu_id); + + /* Enumerate all other CPUs */ + madt = acpi_get_madt(); + UK_ASSERT(madt); + + len = madt->hdr.tab_len - sizeof(*madt); + for (off = 0; off < len; off += m.h->len) { + m.h = (struct acpi_subsdt_hdr *)(madt->entries + off); + + if (m.h->type != ACPI_MADT_GICC || + !(m.gicc->flags & ACPI_MADT_GICC_FLAGS_EN)) + continue; + + cpu_id = m.gicc->mpidr & CPU_ID_MASK; + + if (bsp_cpu_id == cpu_id) { + UK_ASSERT(!bsp_found); + + bsp_found = 1; + continue; + } + + lcpu = lcpu_alloc(cpu_id); + if (unlikely(!lcpu)) { + /* If we cannot allocate another LCPU, we probably have + * reached the maximum number of supported CPUs. So + * just stop here. + */ + uk_pr_warn("Maximum number of cores exceeded.\n"); + return 0; + } + } + UK_ASSERT(bsp_found); + + return 0; +} +#else +static int do_arch_mp_init(void *arg) { int fdt_cpu; const fdt32_t *naddr_prop, *nsize_prop, *id_reg; @@ -103,17 +156,12 @@ int lcpu_arch_mp_init(void *arg) __lcpuid bsp_cpu_id; char bsp_found __maybe_unused = 0; struct lcpu *lcpu; + void *dtb; /* MP support is dependent on an initialized GIC */ UK_ASSERT(gic); dtb = arg; - /** - * We have to provide the physical address of the start routine when - * starting secondary CPUs. We thus do the translation here once and - * cache the result. - */ - lcpu_start_paddr = ukplat_virt_to_phys(lcpu_start); bsp_cpu_id = lcpu_arch_id(); uk_pr_info("Bootstrapping processor has the ID %ld\n", @@ -216,6 +264,19 @@ int lcpu_arch_mp_init(void *arg) return 0; } +#endif + +int lcpu_arch_mp_init(void *arg) +{ + /** + * We have to provide the physical address of the start routine when + * starting secondary CPUs. We thus do the translation here once and + * cache the result. + */ + lcpu_start_paddr = ukplat_virt_to_phys(lcpu_start); + + return do_arch_mp_init(arg); +} int lcpu_arch_start(struct lcpu *lcpu, unsigned long flags __unused) { diff --git a/plat/common/include/uk/plat/common/madt.h b/plat/common/include/uk/plat/common/madt.h index cabb3d9ef..a3674c5d5 100644 --- a/plat/common/include/uk/plat/common/madt.h +++ b/plat/common/include/uk/plat/common/madt.h @@ -167,6 +167,9 @@ struct acpi_madt_x2apic_nmi { } __packed; /* GIC CPU Interface (GICC) Structure */ +#define ACPI_MADT_GICC_FLAGS_EN 0x01 +#define ACPI_MADT_GICC_FLAGS_PERF_IRQ_MODE 0x02 +#define ACPI_MADT_GICC_FLAGS_VGIC_IRQ_MODE 0x03 struct acpi_madt_gicc { struct acpi_subsdt_hdr hdr; __u16 reserved;