Cores from the DTB /cpus or, on QEMU (ACPI, no DTB), the MADT GICC entries; the MADT lookup is now shared (hal/acpi.c) with amd64. PSCI CPU_ON through the discovered conduit into ap_entry.S, which copies the boot core's MMU/control state, sets TPIDR_EL1 and parks. Core 1 online at EL1 with its own block; its vCPU thread 0.0% on the host. QEMU aarch64 -smp 2 -name debug-threads=on. 3-ISA acceptance clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
1.7 KiB
C
62 lines
1.7 KiB
C
/*
|
||
StarForth — Steady-State Virtual Machine Runtime
|
||
|
||
Copyright (c) 2023–2025 Robert A. James
|
||
All rights reserved.
|
||
|
||
This file is part of the StarForth project.
|
||
|
||
Licensed under the StarForth License, Version 1.0 (the "License");
|
||
you may not use this file except in compliance with the License.
|
||
*/
|
||
|
||
/**
|
||
* acpi.c - Finding an ACPI table from the RSDP (FABRIC-3.10.8 MC-1b).
|
||
* See starkernel/acpi.h. Moved out of arch/amd64/smp.c (MC-1a) when
|
||
* aarch64 needed the same MADT lookup.
|
||
*/
|
||
|
||
#include "starkernel/acpi.h"
|
||
|
||
static int sig_eq(const uint8_t *p, const char *s, int n)
|
||
{
|
||
int i;
|
||
for (i = 0; i < n; i++) if (p[i] != (uint8_t)s[i]) return 0;
|
||
return 1;
|
||
}
|
||
|
||
static uint32_t le32(const uint8_t *p)
|
||
{
|
||
return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
|
||
}
|
||
|
||
static uint64_t le64(const uint8_t *p)
|
||
{
|
||
return (uint64_t)le32(p) | ((uint64_t)le32(p + 4) << 32);
|
||
}
|
||
|
||
uint32_t acpi_table_length(const uint8_t *table)
|
||
{
|
||
return table ? le32(table + 4) : 0;
|
||
}
|
||
|
||
const uint8_t *acpi_find_table(const void *rsdp, const char *sig)
|
||
{
|
||
const uint8_t *r = (const uint8_t *)rsdp;
|
||
const uint8_t *xsdt;
|
||
uint32_t len, n, i;
|
||
|
||
/* RSDP: "RSD PTR " at 0, revision at 15, XSDT address at 24 (ACPI 2.0+). */
|
||
if (!r || !sig_eq(r, "RSD PTR ", 8) || r[15] < 2) return (const uint8_t *)0;
|
||
xsdt = (const uint8_t *)(uintptr_t)le64(r + 24);
|
||
if (!xsdt || !sig_eq(xsdt, "XSDT", 4)) return (const uint8_t *)0;
|
||
len = le32(xsdt + 4);
|
||
if (len <= 36u) return (const uint8_t *)0;
|
||
n = (len - 36u) / 8u;
|
||
for (i = 0; i < n; i++) {
|
||
const uint8_t *t = (const uint8_t *)(uintptr_t)le64(xsdt + 36u + 8u * i);
|
||
if (t && sig_eq(t, sig, 4)) return t;
|
||
}
|
||
return (const uint8_t *)0;
|
||
}
|