mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-08 02:40:28 +00:00
[metal] Rewrite ACPI code to avoid using kmalloc()
This commit is contained in:
parent
be1e41af33
commit
97b8dd5d0a
3 changed files with 47 additions and 14 deletions
|
@ -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,18 +59,20 @@ 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;
|
||||
p = madt->Subtable;
|
||||
while (p != madt_end) {
|
||||
h = (const AcpiSubtableHeader *)p;
|
||||
switch (h->Type) {
|
||||
case kAcpiMadtIoApic:
|
||||
*icp++ = (const AcpiMadtIoApic *)p;
|
||||
icp = _AcpiOsAllocate(num_io_apics * sizeof(const AcpiMadtIoApic *));
|
||||
if (icp) {
|
||||
_AcpiIoApics = icp;
|
||||
p = madt->Subtable;
|
||||
while (p != madt_end) {
|
||||
h = (const AcpiSubtableHeader *)p;
|
||||
switch (h->Type) {
|
||||
case kAcpiMadtIoApic:
|
||||
*icp++ = (const AcpiMadtIoApic *)p;
|
||||
}
|
||||
p += h->Length;
|
||||
}
|
||||
p += h->Length;
|
||||
_AcpiNumIoApics = num_io_apics;
|
||||
}
|
||||
_AcpiNumIoApics = num_io_apics;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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 **);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue