[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.
*/
#include "libc/dce.h"
#include "libc/intrin/kmalloc.h"
#include "libc/inttypes.h"
#include "libc/irq/acpi.internal.h"
@ -60,8 +59,9 @@ textstartup void _AcpiMadtInit(void) {
p += h->Length;
}
ACPI_INFO("MADT: %zu I/O APIC(s)", num_io_apics);
_AcpiIoApics = kmalloc(num_io_apics * sizeof(const AcpiMadtIoApic *));
icp = _AcpiIoApics;
icp = _AcpiOsAllocate(num_io_apics * sizeof(const AcpiMadtIoApic *));
if (icp) {
_AcpiIoApics = icp;
p = madt->Subtable;
while (p != madt_end) {
h = (const AcpiSubtableHeader *)p;
@ -73,6 +73,7 @@ textstartup void _AcpiMadtInit(void) {
}
_AcpiNumIoApics = num_io_apics;
}
}
}
#endif /* __x86_64__ */

View file

@ -25,8 +25,9 @@
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/kmalloc.h"
#include "libc/intrin/directmap.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/irq/acpi.internal.h"
#include "libc/log/color.internal.h"
@ -34,6 +35,8 @@
#include "libc/nt/efi.h"
#include "libc/runtime/pc.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#ifdef __x86_64__
@ -55,6 +58,34 @@ textstartup void *_AcpiOsMapUncachedMemory(uintptr_t phy, size_t n) {
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) {
uint8_t c = 0;
while (n-- != 0) c += *p++;
@ -169,7 +200,7 @@ textstartup void _AcpiXsdtInit(void) {
const AcpiTableRsdt *rsdt = _AcpiMapTable(rsdp->RsdtPhysicalAddress);
nents = (rsdt->Header.Length - sizeof(rsdt->Header)) / sizeof(uint32_t);
ACPI_INFO("RSDT @ %p, %#zx entries", rsdt, nents);
ents = kmalloc(nents * sizeof(AcpiTableHeader *));
ents = _AcpiOsAllocate(nents * sizeof(AcpiTableHeader *));
if (ents) {
for (i = 0; i < nents; ++i) {
ents[i] = _AcpiMapTable(rsdt->TableOffsetEntry[i]);
@ -179,7 +210,7 @@ textstartup void _AcpiXsdtInit(void) {
const AcpiTableXsdt *xsdt = _AcpiMapTable(rsdp->XsdtPhysicalAddress);
nents = (xsdt->Header.Length - sizeof(xsdt->Header)) / sizeof(uint64_t);
ACPI_INFO("XSDT @ %p, %#zx entries", xsdt, nents);
ents = kmalloc(nents * sizeof(AcpiTableHeader *));
ents = _AcpiOsAllocate(nents * sizeof(AcpiTableHeader *));
if (ents) {
for (i = 0; i < nents; ++i) {
ents[i] = _AcpiMapTable(xsdt->TableOffsetEntry[i]);

View file

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