[metal] Rewrite ACPI code to avoid using kmalloc()

This commit is contained in:
tkchia 2023-09-13 15:47:43 +00:00
parent be1e41af33
commit 97b8dd5d0a
3 changed files with 47 additions and 14 deletions

View file

@ -25,7 +25,6 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/kmalloc.h"
#include "libc/inttypes.h" #include "libc/inttypes.h"
#include "libc/irq/acpi.internal.h" #include "libc/irq/acpi.internal.h"
@ -60,18 +59,20 @@ textstartup void _AcpiMadtInit(void) {
p += h->Length; p += h->Length;
} }
ACPI_INFO("MADT: %zu I/O APIC(s)", num_io_apics); ACPI_INFO("MADT: %zu I/O APIC(s)", num_io_apics);
_AcpiIoApics = kmalloc(num_io_apics * sizeof(const AcpiMadtIoApic *)); icp = _AcpiOsAllocate(num_io_apics * sizeof(const AcpiMadtIoApic *));
icp = _AcpiIoApics; if (icp) {
p = madt->Subtable; _AcpiIoApics = icp;
while (p != madt_end) { p = madt->Subtable;
h = (const AcpiSubtableHeader *)p; while (p != madt_end) {
switch (h->Type) { h = (const AcpiSubtableHeader *)p;
case kAcpiMadtIoApic: switch (h->Type) {
*icp++ = (const AcpiMadtIoApic *)p; case kAcpiMadtIoApic:
*icp++ = (const AcpiMadtIoApic *)p;
}
p += h->Length;
} }
p += h->Length; _AcpiNumIoApics = num_io_apics;
} }
_AcpiNumIoApics = num_io_apics;
} }
} }

View file

@ -25,8 +25,9 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/bits.h" #include "libc/intrin/bits.h"
#include "libc/intrin/kmalloc.h" #include "libc/intrin/directmap.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/irq/acpi.internal.h" #include "libc/irq/acpi.internal.h"
#include "libc/log/color.internal.h" #include "libc/log/color.internal.h"
@ -34,6 +35,8 @@
#include "libc/nt/efi.h" #include "libc/nt/efi.h"
#include "libc/runtime/pc.internal.h" #include "libc/runtime/pc.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#ifdef __x86_64__ #ifdef __x86_64__
@ -55,6 +58,34 @@ textstartup void *_AcpiOsMapUncachedMemory(uintptr_t phy, size_t n) {
return (void *)(BANE + phy); return (void *)(BANE + phy);
} }
textstartup static void *_AcpiOsAllocatePages(size_t n) {
struct DirectMap dm = sys_mmap_metal(NULL, n, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
void *addr = dm.addr;
if (addr == (void *)-1) addr = NULL;
return addr;
}
textstartup void *_AcpiOsAllocate(size_t n) {
static _Atomic(char *) slack = NULL;
char *addr = NULL;
size_t align = __BIGGEST_ALIGNMENT__, use;
if (n >= 4096) return _AcpiOsAllocatePages(n);
n = ROUNDUP(n, align);
for (;;) {
addr = atomic_exchange(&slack, NULL);
if (!addr) {
addr = _AcpiOsAllocatePages(4096);
if (!addr) return NULL;
}
use = (uintptr_t)addr % 4096 + n;
if (use <= 4096) {
if (use < 4096) atomic_store(&slack, addr + n);
return addr;
}
}
}
textstartup static uint8_t _AcpiTbChecksum(const uint8_t *p, size_t n) { textstartup static uint8_t _AcpiTbChecksum(const uint8_t *p, size_t n) {
uint8_t c = 0; uint8_t c = 0;
while (n-- != 0) c += *p++; while (n-- != 0) c += *p++;
@ -169,7 +200,7 @@ textstartup void _AcpiXsdtInit(void) {
const AcpiTableRsdt *rsdt = _AcpiMapTable(rsdp->RsdtPhysicalAddress); const AcpiTableRsdt *rsdt = _AcpiMapTable(rsdp->RsdtPhysicalAddress);
nents = (rsdt->Header.Length - sizeof(rsdt->Header)) / sizeof(uint32_t); nents = (rsdt->Header.Length - sizeof(rsdt->Header)) / sizeof(uint32_t);
ACPI_INFO("RSDT @ %p, %#zx entries", rsdt, nents); ACPI_INFO("RSDT @ %p, %#zx entries", rsdt, nents);
ents = kmalloc(nents * sizeof(AcpiTableHeader *)); ents = _AcpiOsAllocate(nents * sizeof(AcpiTableHeader *));
if (ents) { if (ents) {
for (i = 0; i < nents; ++i) { for (i = 0; i < nents; ++i) {
ents[i] = _AcpiMapTable(rsdt->TableOffsetEntry[i]); ents[i] = _AcpiMapTable(rsdt->TableOffsetEntry[i]);
@ -179,7 +210,7 @@ textstartup void _AcpiXsdtInit(void) {
const AcpiTableXsdt *xsdt = _AcpiMapTable(rsdp->XsdtPhysicalAddress); const AcpiTableXsdt *xsdt = _AcpiMapTable(rsdp->XsdtPhysicalAddress);
nents = (xsdt->Header.Length - sizeof(xsdt->Header)) / sizeof(uint64_t); nents = (xsdt->Header.Length - sizeof(xsdt->Header)) / sizeof(uint64_t);
ACPI_INFO("XSDT @ %p, %#zx entries", xsdt, nents); ACPI_INFO("XSDT @ %p, %#zx entries", xsdt, nents);
ents = kmalloc(nents * sizeof(AcpiTableHeader *)); ents = _AcpiOsAllocate(nents * sizeof(AcpiTableHeader *));
if (ents) { if (ents) {
for (i = 0; i < nents; ++i) { for (i = 0; i < nents; ++i) {
ents[i] = _AcpiMapTable(xsdt->TableOffsetEntry[i]); ents[i] = _AcpiMapTable(xsdt->TableOffsetEntry[i]);

View file

@ -212,6 +212,7 @@ extern uint32_t _AcpiMadtFlags;
extern const AcpiMadtIoApic **_AcpiIoApics; extern const AcpiMadtIoApic **_AcpiIoApics;
extern void *_AcpiOsMapUncachedMemory(uintptr_t, size_t); extern void *_AcpiOsMapUncachedMemory(uintptr_t, size_t);
extern void *_AcpiOsAllocate(size_t);
extern void *_AcpiMapTable(uintptr_t); extern void *_AcpiMapTable(uintptr_t);
extern AcpiStatus _AcpiGetTableImpl(uint32_t, uint32_t, void **); extern AcpiStatus _AcpiGetTableImpl(uint32_t, uint32_t, void **);