feat: handover + populate with dtb
This commit is contained in:
parent
2f9560d866
commit
5d8ecae526
17 changed files with 486 additions and 51 deletions
|
@ -11,3 +11,5 @@ Writer hal_writer(void);
|
||||||
void hal_brkpoint(void);
|
void hal_brkpoint(void);
|
||||||
|
|
||||||
DTBNode* hal_dtb_root(void);
|
DTBNode* hal_dtb_root(void);
|
||||||
|
|
||||||
|
size_t page_size(void);
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
#include <dtb>
|
#include <dtb>
|
||||||
|
#include <hal>
|
||||||
|
#include <handover-dtb>
|
||||||
#include <heap/bump.h>
|
#include <heap/bump.h>
|
||||||
#include <helpers/mem.h>
|
#include <helpers/mem.h>
|
||||||
#include <logger>
|
#include <logger>
|
||||||
#include <stddef.h>
|
#include <pmm>
|
||||||
#include <string.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "mem.h"
|
|
||||||
|
|
||||||
extern char __bss[], __bss_end[];
|
extern char __bss[], __bss_end[];
|
||||||
extern void kmain(void);
|
extern void kmain(void);
|
||||||
|
|
||||||
static uint8_t early_heap[kib$(20)];
|
static uint8_t early_heap[kib$(32)];
|
||||||
static DTBNode* dtb_root = NULL;
|
static DTBNode* dtb_root = NULL;
|
||||||
|
|
||||||
void rv32_start(__attribute__((unused)) size_t hartid, uintptr_t dtb) {
|
void rv32_start(__attribute__((unused)) size_t hartid, uintptr_t dtb) {
|
||||||
|
@ -20,7 +21,17 @@ void rv32_start(__attribute__((unused)) size_t hartid, uintptr_t dtb) {
|
||||||
BumpAllocator alloc = bump_allocator_create((void*)early_heap, sizeof(early_heap));
|
BumpAllocator alloc = bump_allocator_create((void*)early_heap, sizeof(early_heap));
|
||||||
dtb_root = dtb_init(dtb, &alloc.base);
|
dtb_root = dtb_init(dtb, &alloc.base);
|
||||||
|
|
||||||
mem_init();
|
handover_init(dtb_root, &alloc.base);
|
||||||
|
handover_append(handover(), (HandoverRecord){
|
||||||
|
.tag = HANDOVER_LOADER,
|
||||||
|
.start = (uintptr_t)early_heap,
|
||||||
|
.size = sizeof(early_heap),
|
||||||
|
});
|
||||||
|
|
||||||
|
for (size_t i = 0; i < handover()->count; i++) {
|
||||||
|
debug$("%s (start: %x, len: %x)", handover_tag_name(handover()->records[i].tag), handover()->records[i].start, handover()->records[i].size);
|
||||||
|
}
|
||||||
|
|
||||||
kmain();
|
kmain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,3 +9,7 @@ void hal_putc(int ch) {
|
||||||
void hal_brkpoint(void) {
|
void hal_brkpoint(void) {
|
||||||
__asm__ volatile("ebreak");
|
__asm__ volatile("ebreak");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t page_size(void) {
|
||||||
|
return 4096;
|
||||||
|
}
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
"sys": ["kernel"]
|
"sys": ["kernel"]
|
||||||
},
|
},
|
||||||
"provides": ["hal-impl"],
|
"provides": ["hal-impl"],
|
||||||
"requires": ["dtb"]
|
"requires": ["dtb", "pmm", "handover-dtb"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
#include <hal>
|
|
||||||
#include <helpers/mem.h>
|
|
||||||
#include <logger>
|
|
||||||
|
|
||||||
#include "mem.h"
|
|
||||||
|
|
||||||
void mem_init(void) {
|
|
||||||
DTBNode* root = hal_dtb_root();
|
|
||||||
if (root == NULL) {
|
|
||||||
error$("No DTB found");
|
|
||||||
hal_brkpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
DTBNode* mem = dtb_lookup(root, "memory");
|
|
||||||
if (mem == NULL) {
|
|
||||||
error$("No memory node found in DTB");
|
|
||||||
hal_brkpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
RegValue reg_val = dtb_lookup_reg(mem);
|
|
||||||
if (reg_val.len == 0) {
|
|
||||||
warn$("Memory node size is larger than 4GB. Defaulting to 4GB");
|
|
||||||
reg_val.len = align_down$(gib$(4) - 1, 4096);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug$("Memory node found at %x with size %x", reg_val.addr, reg_val.len);
|
|
||||||
|
|
||||||
DTBNode* reserved = dtb_lookup(root, "reserved-memory");
|
|
||||||
if (reserved == NULL) {
|
|
||||||
error$("No reserved memory node found in DTB");
|
|
||||||
hal_brkpoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
DTBNode* child = reserved->children;
|
|
||||||
|
|
||||||
while (child != NULL) {
|
|
||||||
RegValue reg = dtb_lookup_reg(child);
|
|
||||||
debug$("Reserved memory node with name %s found at %x with size %x", child->name, reg.addr, reg.len);
|
|
||||||
|
|
||||||
child = child->next;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
void mem_init(void);
|
|
|
@ -3,3 +3,8 @@
|
||||||
#include <logger>
|
#include <logger>
|
||||||
|
|
||||||
#define printf(...) _log(LOG_INFO, loc$(), __VA_ARGS__)
|
#define printf(...) _log(LOG_INFO, loc$(), __VA_ARGS__)
|
||||||
|
|
||||||
|
#define fprintf(TYPE, ...) _log(TYPE, loc$(), __VA_ARGS__)
|
||||||
|
|
||||||
|
#define stdio LOG_INFO
|
||||||
|
#define stderr LOG_ERROR
|
||||||
|
|
5
src/kernel/pmm/manifest.json
Normal file
5
src/kernel/pmm/manifest.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"type": "lib",
|
||||||
|
"id": "pmm"
|
||||||
|
}
|
14
src/kernel/pmm/mod.c
Normal file
14
src/kernel/pmm/mod.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "mod.h"
|
||||||
|
#include <hal>
|
||||||
|
#include <logger>
|
||||||
|
|
||||||
|
Pmm* pmm = NULL;
|
||||||
|
|
||||||
|
void pmm_init(size_t start, size_t len) {
|
||||||
|
(void)start;
|
||||||
|
(void)len;
|
||||||
|
if (pmm != NULL) {
|
||||||
|
error$("PMM already initialized");
|
||||||
|
hal_brkpoint();
|
||||||
|
}
|
||||||
|
}
|
17
src/kernel/pmm/mod.h
Normal file
17
src/kernel/pmm/mod.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct _Page {
|
||||||
|
struct _Page* next;
|
||||||
|
uintptr_t addr;
|
||||||
|
} Page;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t total_pages;
|
||||||
|
size_t free_pages;
|
||||||
|
Page* freelist;
|
||||||
|
} Pmm;
|
||||||
|
|
||||||
|
void pmm_init(size_t start, size_t len);
|
5
src/libs/handover/base/manifest.json
Normal file
5
src/libs/handover/base/manifest.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"type": "lib",
|
||||||
|
"id": "handover"
|
||||||
|
}
|
158
src/libs/handover/base/mod.c
Normal file
158
src/libs/handover/base/mod.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mod.h"
|
||||||
|
|
||||||
|
char const* handover_tag_name(HandoverTag tag) {
|
||||||
|
switch (tag) {
|
||||||
|
#define TAG(NAME, VALUE) \
|
||||||
|
case HANDOVER_##NAME: \
|
||||||
|
return #NAME;
|
||||||
|
HANDOVER_TAGS(TAG)
|
||||||
|
#undef TAG
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handover_mergeable(uint32_t tag) {
|
||||||
|
switch (tag) {
|
||||||
|
case HANDOVER_FREE:
|
||||||
|
case HANDOVER_LOADER:
|
||||||
|
case HANDOVER_KERNEL:
|
||||||
|
case HANDOVER_RESERVED:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handover_overlap(HandoverRecord lhs, HandoverRecord rhs) {
|
||||||
|
return lhs.start < rhs.start + rhs.size && rhs.start < lhs.start + lhs.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handover_just_before(HandoverRecord lhs, HandoverRecord rhs) {
|
||||||
|
return lhs.start + lhs.size == rhs.start;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handover_just_after(HandoverRecord lhs, HandoverRecord rhs) {
|
||||||
|
return lhs.start == rhs.start + rhs.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandoverRecord handover_half_under(HandoverRecord self, HandoverRecord other) {
|
||||||
|
if (handover_overlap(self, other) &&
|
||||||
|
self.start < other.start) {
|
||||||
|
return (HandoverRecord){
|
||||||
|
.tag = self.tag,
|
||||||
|
.flags = 0,
|
||||||
|
.start = self.start,
|
||||||
|
.size = other.start - self.start,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return (HandoverRecord){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
HandoverRecord handover_half_over(HandoverRecord self, HandoverRecord other) {
|
||||||
|
if (handover_overlap(self, other) &&
|
||||||
|
self.start + self.size > other.start + other.size) {
|
||||||
|
return (HandoverRecord){
|
||||||
|
.tag = self.tag,
|
||||||
|
.flags = 0,
|
||||||
|
.start = other.start + other.size,
|
||||||
|
.size = self.start + self.size - other.start - other.size,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return (HandoverRecord){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void handover_insert(HandoverPayload* payload, size_t index, HandoverRecord record) {
|
||||||
|
for (size_t i = payload->count; i > index; i--) {
|
||||||
|
payload->records[i] = payload->records[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
payload->records[index] = record;
|
||||||
|
payload->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handover_remove(HandoverPayload* payload, size_t index) {
|
||||||
|
for (size_t i = index; i < payload->count - 1; i++) {
|
||||||
|
payload->records[i] = payload->records[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
payload->count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handover_append(HandoverPayload* payload, HandoverRecord record) {
|
||||||
|
if (record.size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < payload->count; i++) {
|
||||||
|
HandoverRecord other = payload->records[i];
|
||||||
|
|
||||||
|
if (record.tag == other.tag && handover_just_after(record, other) && handover_mergeable(record.tag)) {
|
||||||
|
handover_remove(payload, i);
|
||||||
|
other.size += record.size;
|
||||||
|
handover_append(payload, other);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.tag == other.tag && handover_just_before(record, other) && handover_mergeable(record.tag)) {
|
||||||
|
handover_remove(payload, i);
|
||||||
|
other.start -= record.size;
|
||||||
|
other.size += record.size;
|
||||||
|
handover_append(payload, other);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handover_overlap(record, other)) {
|
||||||
|
if ((handover_mergeable(record.tag) && !handover_mergeable(other.tag)) || other.tag == HANDOVER_FREE) {
|
||||||
|
handover_remove(payload, i);
|
||||||
|
|
||||||
|
HandoverRecord lower = handover_half_under(other, record);
|
||||||
|
HandoverRecord upper = handover_half_over(other, record);
|
||||||
|
|
||||||
|
handover_append(payload, record);
|
||||||
|
handover_append(payload, lower);
|
||||||
|
handover_append(payload, upper);
|
||||||
|
return;
|
||||||
|
} else if (!handover_mergeable(record.tag) && handover_mergeable(other.tag)) {
|
||||||
|
handover_remove(payload, i);
|
||||||
|
|
||||||
|
HandoverRecord lower = handover_half_under(record, other);
|
||||||
|
HandoverRecord upper = handover_half_over(record, other);
|
||||||
|
|
||||||
|
handover_append(payload, other);
|
||||||
|
handover_append(payload, lower);
|
||||||
|
handover_append(payload, upper);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "handover: record %s (start: %x, len: %x) collides with %s (start: %x, len: %x)\n", handover_tag_name(record.tag), record.start, record.size, handover_tag_name(other.tag), other.start, other.size);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.start < other.start) {
|
||||||
|
handover_insert(payload, i, record);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
payload->records[payload->count++] = record;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* handover_str(HandoverPayload const* payload, uint32_t offset) {
|
||||||
|
return (char const*)payload + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t handover_add_string(HandoverPayload* handover, char const* str) {
|
||||||
|
size_t len = strlen(str) + 1;
|
||||||
|
size_t offset = handover->size - len;
|
||||||
|
memset((void*)((uintptr_t)handover + offset), 0, len);
|
||||||
|
memcpy((void*)((uintptr_t)handover + offset), str, len);
|
||||||
|
handover->size -= len;
|
||||||
|
return offset;
|
||||||
|
}
|
159
src/libs/handover/base/mod.h
Normal file
159
src/libs/handover/base/mod.h
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||||
|
|
||||||
|
#ifdef __ck_bits_64__
|
||||||
|
# define KERNEL_BASE 0xffffffff80000000;
|
||||||
|
# define UPPER_HALF 0xffff800000000000;
|
||||||
|
#else
|
||||||
|
# define KERNEL_BASE 0xc0000000;
|
||||||
|
# define UPPER_HALF 0xc0000000;
|
||||||
|
#endif //!__ck_bits_64__
|
||||||
|
|
||||||
|
#define HANDOVER_COOLBOOT 0xc001b001
|
||||||
|
#define HANDOVER_SECTION ".handover"
|
||||||
|
|
||||||
|
#define HANDOVER_TAGS(TAG) \
|
||||||
|
TAG(FREE, 0x00000000) \
|
||||||
|
TAG(MAGIC, HANDOVER_COOLBOOT) \
|
||||||
|
TAG(SELF, 0xa24f988d) \
|
||||||
|
TAG(STACK, 0xf65b391b) \
|
||||||
|
TAG(KERNEL, 0xbfc71b20) \
|
||||||
|
TAG(LOADER, 0xf1f80c26) \
|
||||||
|
TAG(FILE, 0xcbc36d3b) \
|
||||||
|
TAG(RSDP, 0x8ef29c18) \
|
||||||
|
TAG(FDT, 0xb628bbc1) \
|
||||||
|
TAG(FB, 0xe2d55685) \
|
||||||
|
TAG(CMDLINE, 0x435140c4) \
|
||||||
|
TAG(RESERVED, 0xb8841d2d) \
|
||||||
|
TAG(END, 0xffffffff)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
|
||||||
|
#define TAG(NAME, VALUE) HANDOVER_##NAME = VALUE,
|
||||||
|
HANDOVER_TAGS(TAG)
|
||||||
|
#undef TAG
|
||||||
|
} HandoverTag;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t tag;
|
||||||
|
uint32_t flags;
|
||||||
|
uintptr_t start;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
uint16_t pitch;
|
||||||
|
|
||||||
|
#define HANDOVER_RGBX8888 0x7451
|
||||||
|
#define HANDOVER_BGRX8888 0xd040
|
||||||
|
uint16_t format;
|
||||||
|
} fb;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t name;
|
||||||
|
uint32_t meta;
|
||||||
|
} file;
|
||||||
|
|
||||||
|
uint64_t more;
|
||||||
|
};
|
||||||
|
} HandoverRecord;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t magic, agent, size, count;
|
||||||
|
HandoverRecord records[];
|
||||||
|
} HandoverPayload;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t tag;
|
||||||
|
uint32_t flags;
|
||||||
|
uint64_t more;
|
||||||
|
} HandoverRequest;
|
||||||
|
|
||||||
|
typedef void HandoverEntry(
|
||||||
|
uint64_t magic,
|
||||||
|
HandoverPayload const* payload
|
||||||
|
);
|
||||||
|
|
||||||
|
/* --- Header Utilities ----------------------------------------------------- */
|
||||||
|
|
||||||
|
#define HANDOVER_REQ_START \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_MAGIC \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HANDOVER_REQ_END \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_END \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WITH_FB \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_FB \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WITH_ACPI \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_RSDP \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WITH_FDT \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_FDT \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WITH_FILES \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_FILE \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WITH_CMDLINE \
|
||||||
|
{ \
|
||||||
|
.tag = HANDOVER_CMDLINE \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HANDOVER(...) \
|
||||||
|
__attribute__((section(HANDOVER_SECTION), used)) static HandoverRequest handover_header[] = { \
|
||||||
|
{.tag = HANDOVER_MAGIC}, \
|
||||||
|
__VA_ARGS__ __VA_OPT__(, ){.tag = HANDOVER_END}, \
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --- Utilities ------------------------------------------------------------ */
|
||||||
|
|
||||||
|
char const* handover_tag_name(HandoverTag tag);
|
||||||
|
|
||||||
|
bool handover_mergeable(uint32_t tag);
|
||||||
|
|
||||||
|
bool handover_overlap(HandoverRecord lhs, HandoverRecord rhs);
|
||||||
|
|
||||||
|
bool handover_just_before(HandoverRecord lhs, HandoverRecord rhs);
|
||||||
|
|
||||||
|
bool handover_just_after(HandoverRecord lhs, HandoverRecord rhs);
|
||||||
|
|
||||||
|
HandoverRecord handover_half_under(HandoverRecord self, HandoverRecord other);
|
||||||
|
|
||||||
|
HandoverRecord handover_half_over(HandoverRecord self, HandoverRecord other);
|
||||||
|
|
||||||
|
void handover_insert(HandoverPayload* payload, size_t index, HandoverRecord record);
|
||||||
|
|
||||||
|
void handover_remove(HandoverPayload* payload, size_t index);
|
||||||
|
|
||||||
|
void handover_append(HandoverPayload* payload, HandoverRecord record);
|
||||||
|
|
||||||
|
char const* handover_str(HandoverPayload const* payload, uint32_t offset);
|
||||||
|
|
||||||
|
size_t handover_add_string(HandoverPayload* handover, char const* str);
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
9
src/libs/handover/dtb/manifest.json
Normal file
9
src/libs/handover/dtb/manifest.json
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.cute.engineering/stable/cutekit.manifest.component.v1",
|
||||||
|
"type": "lib",
|
||||||
|
"id": "handover-dtb",
|
||||||
|
"requires": [
|
||||||
|
"dtb",
|
||||||
|
"handover"
|
||||||
|
]
|
||||||
|
}
|
78
src/libs/handover/dtb/mod.c
Normal file
78
src/libs/handover/dtb/mod.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#include <helpers/mem.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "handover/base/mod.h"
|
||||||
|
#include "logger/mod.h"
|
||||||
|
#include "mod.h"
|
||||||
|
|
||||||
|
static DTBNode* dtb_root = NULL;
|
||||||
|
static HandoverPayload* payload = NULL;
|
||||||
|
|
||||||
|
static void handover_mmap(void) {
|
||||||
|
if (dtb_root == NULL) {
|
||||||
|
fprintf(stderr, "No DTB found");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
DTBNode* mem = dtb_lookup(dtb_root, "memory");
|
||||||
|
if (mem == NULL) {
|
||||||
|
fprintf(stderr, "No memory node found in DTB");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
RegValue reg_val = dtb_lookup_reg(mem);
|
||||||
|
|
||||||
|
if (reg_val.len == 0) {
|
||||||
|
printf("WARNING: Memory node size is larger than 4GB. Defaulting to 4GB");
|
||||||
|
reg_val.len = align_down$(gib$(4) - 1, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
handover_append(payload, (HandoverRecord){
|
||||||
|
.tag = HANDOVER_FREE,
|
||||||
|
.start = reg_val.addr,
|
||||||
|
.size = reg_val.len,
|
||||||
|
});
|
||||||
|
|
||||||
|
DTBNode* reserved = dtb_lookup(dtb_root, "reserved-memory");
|
||||||
|
if (reserved == NULL) {
|
||||||
|
fprintf(stderr, "No reserved memory node found in DTB");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
DTBNode* child = reserved->children;
|
||||||
|
while (child != NULL) {
|
||||||
|
RegValue reg = dtb_lookup_reg(child);
|
||||||
|
handover_append(payload, (HandoverRecord){
|
||||||
|
.tag = HANDOVER_RESERVED,
|
||||||
|
.start = reg.addr,
|
||||||
|
.size = reg.len,
|
||||||
|
});
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handover_init(DTBNode* dtb, Allocator* alloc) {
|
||||||
|
if (dtb_root != NULL) {
|
||||||
|
fprintf(stderr, "Handover is already initialized");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
dtb_root = dtb;
|
||||||
|
|
||||||
|
payload = alloc->alloc(alloc, kib$(16));
|
||||||
|
if (payload == NULL) {
|
||||||
|
fprintf(stderr, "Failed to allocate memory for handover payload");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
payload->count = 0;
|
||||||
|
payload->magic = HANDOVER_MAGIC;
|
||||||
|
|
||||||
|
handover_mmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
HandoverPayload* handover(void) {
|
||||||
|
return payload;
|
||||||
|
}
|
9
src/libs/handover/dtb/mod.h
Normal file
9
src/libs/handover/dtb/mod.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <dtb>
|
||||||
|
#include <handover>
|
||||||
|
#include <traits/allocator.h>
|
||||||
|
|
||||||
|
void handover_init(DTBNode* dtb, Allocator* alloc);
|
||||||
|
|
||||||
|
HandoverPayload* handover(void);
|
4
src/libs/helpers/misc.h
Normal file
4
src/libs/helpers/misc.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define GENERATE_ENUM(ENUM) ENUM,
|
||||||
|
#define GENERATE_STRING(STRING) #STRING,
|
Loading…
Add table
Reference in a new issue