/* 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; }