diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index bc0bce6..9be692d 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -101,6 +101,66 @@ void *valloc(vctx_t *ctx, size_t pages, uint64_t flags) return (void *)new->start; } +void *vallocat(vctx_t *ctx, size_t pages, uint64_t flags, uint64_t phys) +{ + if (ctx == NULL || ctx->root == NULL || ctx->pagemap == NULL) + return NULL; + + vregion_t *region = ctx->root; + vregion_t *new = NULL; + vregion_t *last = ctx->root; + + while (region) + { + if (region->next == NULL || region->start + region->pages < region->next->start) + { + new = (vregion_t *)palloc(1, true); + if (!new) + return NULL; + + memset(new, 0, sizeof(vregion_t)); + new->pages = pages; + new->flags = VFLAGS_TO_PFLAGS(flags); + new->start = region->start + (region->pages * PAGE_SIZE); + new->next = region->next; + new->prev = region; + region->next = new; + for (uint64_t i = 0; i < pages; i++) + { + uint64_t page = phys + i * PAGE_SIZE; + if (page == 0) + return NULL; + + vmap(ctx->pagemap, new->start + i * PAGE_SIZE, page, new->flags); + } + return (void *)new->start; + } + region = region->next; + } + + new = (vregion_t *)palloc(1, true); + if (!new) + return NULL; + + memset(new, 0, sizeof(vregion_t)); + last->next = new; + new->prev = last; + new->start = last->start + (last->pages * PAGE_SIZE); + new->pages = pages; + new->flags = VFLAGS_TO_PFLAGS(flags); + new->next = NULL; + + for (uint64_t i = 0; i < pages; i++) + { + uint64_t page = phys + i * PAGE_SIZE; + if (page == 0) + return NULL; + + vmap(ctx->pagemap, new->start + i * PAGE_SIZE, page, new->flags); + } + return (void *)new->start; +} + void vfree(vctx_t *ctx, void *ptr) { if (ctx == NULL) diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h index 0668393..7325233 100644 --- a/kernel/src/mm/vmm.h +++ b/kernel/src/mm/vmm.h @@ -38,6 +38,7 @@ typedef struct vctx vctx_t *vinit(uint64_t *pm, uint64_t start); void vdestroy(vctx_t *ctx); void *valloc(vctx_t *ctx, size_t pages, uint64_t flags); +void *vallocat(vctx_t *ctx, size_t pages, uint64_t flags, uint64_t phys); void vfree(vctx_t *ctx, void *ptr); #endif // VMM_H \ No newline at end of file diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c index ef482ef..c90754e 100644 --- a/kernel/src/sys/acpi.c +++ b/kernel/src/sys/acpi.c @@ -4,6 +4,7 @@ #include #include #include +#include static int acpi_uses_xsdt = 0; static void *acpi_rsdt_ptr = NULL; @@ -15,7 +16,9 @@ void acpi_init(void) kpanic(NULL, "No RSDP provided"); } - acpi_rsdp_t *rsdp = (acpi_rsdp_t *)HIGHER_HALF(rsdp_response->address); + acpi_rsdp_t *rsdp = (acpi_rsdp_t *)vallocat(kvm_ctx, 1, VALLOC_RW, rsdp_response->address); + log_early("Allocated RSDP at %p", rsdp); + if (memcmp(rsdp->signature, "RSD PTR", 7)) kpanic(NULL, "Invalid RSDP signature!");