summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/boot/limine/memorymap.c2
-rw-r--r--arch/x86_64/elf.c27
-rw-r--r--arch/x86_64/init.c63
-rw-r--r--arch/x86_64/lib/object.c59
-rw-r--r--arch/x86_64/memory/koentry-ptr.c16
-rw-r--r--arch/x86_64/memory/message.c40
-rw-r--r--arch/x86_64/memory/page-mapping.c34
-rw-r--r--arch/x86_64/memory/pml4.c (renamed from arch/x86_64/memory/page_directory.c)86
-rw-r--r--arch/x86_64/memory/untyped_retype_page.c38
-rw-r--r--arch/x86_64/syscall/invoke-mapping.c8
-rw-r--r--arch/x86_64/syscall/wrappers.h2
-rw-r--r--arch/x86_64/usermode.c137
12 files changed, 239 insertions, 273 deletions
diff --git a/arch/x86_64/boot/limine/memorymap.c b/arch/x86_64/boot/limine/memorymap.c
index ec0f545..43aecf7 100644
--- a/arch/x86_64/boot/limine/memorymap.c
+++ b/arch/x86_64/boot/limine/memorymap.c
@@ -31,7 +31,7 @@ boot_populate_untyped(void)
if(entry->type != LIMINE_MEMMAP_USABLE) continue;
size_t table_index = s_untyped_dir.self.data++;
- uintmax_t *untyped_data = vmem_phys_tovirt(entry->base);
+ uintmax_t *untyped_data = pptr_tovirt_ident(entry->base);
objdir_entry_t *table_entry = &s_untyped_dir.entries[table_index];
table_entry->type = KO_MEMORY_UNTYPED;
diff --git a/arch/x86_64/elf.c b/arch/x86_64/elf.c
new file mode 100644
index 0000000..696b7a7
--- /dev/null
+++ b/arch/x86_64/elf.c
@@ -0,0 +1,27 @@
+#include "elf.h"
+#include <stddef.h>
+
+int
+elf64_ehdr_valid(Elf64_Ehdr *ehdr)
+{
+ if(ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
+ ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
+ ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
+ ehdr->e_ident[EI_MAG3] != ELFMAG3)
+ return 0;
+ if(ehdr->e_ident[EI_CLASS] != ELFCLASS64) return 0;
+ if(ehdr->e_ident[EI_DATA] != ELFDATA2LSB) return 0;
+ if(ehdr->e_type != ET_EXEC) return 0;
+ if(ehdr->e_machine != EM_X86_64) return 0;
+
+ return 1;
+}
+
+void*
+elf64_loadexec(Elf64_Ehdr *ehdr)
+{
+ if(!elf64_ehdr_valid(ehdr)) return NULL;
+
+ void *entry = (void*)ehdr->e_entry;
+ return entry;
+}
diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c
new file mode 100644
index 0000000..4ec7718
--- /dev/null
+++ b/arch/x86_64/init.c
@@ -0,0 +1,63 @@
+#include "init.h"
+#include "arch/x86_64/page.h"
+#include "device/processor.h"
+
+uintptr_t
+init_alloc_pageframe()
+{
+ objdir_entry_t *untyped_dir_entry = &_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR];
+ objdir_t *untyped_dir = ko_entry_data(untyped_dir_entry);
+
+ /*Seek to the last member of untyped directory.*/
+ uint8_t lastmembi = 1;
+ for(; untyped_dir->entries[lastmembi].type == KO_MEMORY_UNTYPED; lastmembi++);
+ objdir_entry_t *lastmemb = &untyped_dir->entries[lastmembi];
+
+ objdir_entry_t pageframe;
+ ko_untyped_split(lastmemb, &pageframe, 0x1000);
+ return pageframe.data;
+}
+
+void
+init_map_pageframe(uintptr_t pptr, uintptr_t vptr, uint8_t pflags)
+{
+ uint64_t pathval;
+ uint16_t *path = (uint16_t*)&pathval;
+ pml4_get_path(vptr, 4, path);
+
+ processor_t *proc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(proc->pdir);
+
+ pmle_t *pmld = pml4;
+ for(uint8_t d = 0; d < 3; d++) {
+ uint16_t pmli = path[d];
+ pmle_t *pmle = &pmld[pmli];
+ if(!pmle->p) {
+ pmle->value = init_alloc_pageframe() | PAGE_PRESENT | PAGE_RW | PAGE_US;
+ }
+ pmld = pptr_tovirt_ident(pmle->paddr << 12);
+ }
+ pmld[path[3]].value = pptr | pflags;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+}
+
+void
+init_ensure_page(uintptr_t vptr, uint8_t pflags)
+{
+ uint64_t pathval;
+ uint16_t *path = (uint16_t*)&pathval;
+ pml4_get_path(vptr, 4, path);
+
+ processor_t *proc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(proc->pdir);
+
+ pmle_t *pmld = pml4, *pmle;
+ for(uint8_t d = 0; d < 4; d++) {
+ uint16_t pmli = path[d];
+ pmle = &pmld[pmli];
+ if(!pmle->p) {
+ pmle->value = init_alloc_pageframe() | (d == 3 ? pflags : PAGE_PRESENT | PAGE_RW | PAGE_US);
+ }
+ pmld = pptr_tovirt_ident(pmle->paddr << 12);
+ }
+}
diff --git a/arch/x86_64/lib/object.c b/arch/x86_64/lib/object.c
new file mode 100644
index 0000000..4ab8f06
--- /dev/null
+++ b/arch/x86_64/lib/object.c
@@ -0,0 +1,59 @@
+#include "object.h"
+#include "error.h"
+#include "device/processor.h"
+#include "arch/x86_64/page.h"
+#include "arch/x86_64/page-mapping.h"
+
+void*
+ko_entry_data(objdir_entry_t *entry)
+{
+ if((intmax_t)entry->data < 0) return (void*)entry->data;
+ return pptr_tovirt_ident(entry->data);
+}
+
+uintptr_t
+ko_data_toentry(uintptr_t vptr)
+{
+ return vptr_tophys((void*)vptr);
+}
+
+int
+ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr)
+{
+ /* message data should point to the virtual address. */
+ /* If it doesn't, fail*/
+ if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL;
+ uintptr_t vptr = message->data;
+
+ processor_t *cproc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(cproc->pdir);
+
+ pmle_t *message_pmle = pml4_get_mapping(pml4, 4, vptr);
+ *saveptr = (uintptr_t)pptr_tovirt_ident(message_pmle->paddr << 12);
+
+ message_pmle->p = 0;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+
+ message->extra &= ~KODE_EX_MESSAGE_MAPPED;
+ return 0;
+}
+
+int
+ko_message_remap(objdir_entry_t *message)
+{
+ if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL;
+ uintptr_t vptr = message->data;
+
+ processor_t *cproc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(cproc->pdir);
+
+ pmle_t *message_pmle = pml4_get_mapping(pml4, 4, vptr);
+
+ message_pmle->p = 1;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+
+ message->extra |= KODE_EX_MESSAGE_MAPPED;
+ return 0;
+}
+
+void ko_message_move(objdir_entry_t *message, uintptr_t vptr);
diff --git a/arch/x86_64/memory/koentry-ptr.c b/arch/x86_64/memory/koentry-ptr.c
deleted file mode 100644
index b32d4e7..0000000
--- a/arch/x86_64/memory/koentry-ptr.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "memory.h"
-#include "arch/x86_64/page.h"
-#include <stdint.h>
-
-void*
-ko_entry_data(objdir_entry_t *entry)
-{
- if((intmax_t)entry->data < 0) return (void*)entry->data;
- return vmem_phys_tovirt(entry->data);
-}
-
-uintptr_t
-ko_data_toentry(uintptr_t vptr)
-{
- return vmem_ident_tophys((void*)vptr);
-}
diff --git a/arch/x86_64/memory/message.c b/arch/x86_64/memory/message.c
index 1fbdfc8..d5bedb7 100644
--- a/arch/x86_64/memory/message.c
+++ b/arch/x86_64/memory/message.c
@@ -6,43 +6,3 @@
#include "arch/x86_64/page-mapping.h"
#include "print.h"
-int
-ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr)
-{
- /* message data should point to the virtual address. */
- /* If it doesn't, fail*/
- if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL;
- uintptr_t vptr = message->data;
-
- processor_t *cproc = processor_current();
- pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir);
-
- pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr);
- *saveptr = (uintptr_t)vmem_phys_tovirt(message_pmle->paddr << 12);
-
- message_pmle->p = 0;
- __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
-
- message->extra &= ~KODE_EX_MESSAGE_MAPPED;
- return 0;
-}
-
-int
-ko_message_remap(objdir_entry_t *message)
-{
- if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL;
- uintptr_t vptr = message->data;
-
- processor_t *cproc = processor_current();
- pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir);
-
- pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr);
-
- message_pmle->p = 1;
- __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
-
- message->extra |= KODE_EX_MESSAGE_MAPPED;
- return 0;
-}
-
-void ko_message_move(objdir_entry_t *message, uintptr_t vptr);
diff --git a/arch/x86_64/memory/page-mapping.c b/arch/x86_64/memory/page-mapping.c
index d4b4e98..bbf210a 100644
--- a/arch/x86_64/memory/page-mapping.c
+++ b/arch/x86_64/memory/page-mapping.c
@@ -1,28 +1,28 @@
#include "arch/x86_64/page-mapping.h"
#include "arch/x86_64/page.h"
+#include "memory.h"
+#include "error.h"
#include <stddef.h>
#include "print.h"
-pmle_t*
-page_mapping_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path)
+void
+mapping_setup_init()
{
- uint16_t pathi = path[0];
-
- pmle_t *pmle = &pml4[pathi];
- pmle_t *pmle_table = vmem_phys_tovirt(pmle->paddr << 12);
- if(depth == 0) return pmle;
- if(!pmle->p) return NULL;
- return page_mapping_traverse(pmle_table, depth - 1, path + 1);
+ pml4_setup_init();
}
-pmle_t*
-mem_mapping_vptr_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr)
+void
+mapping_setup(objdir_entry_t *mapping)
{
- uint64_t pathval = 0;
- uint16_t *path = (uint16_t*)&pathval;
+ pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping);
+ pml4_setup(pml4);
+}
- for(uint8_t i = 0; i < depth; i++) {
- path[i] = PML_I_FOR_LAYER(vptr, 4 - i);
- }
- return page_mapping_traverse(pml4, depth - 1, path);
+int
+mapping_try_map_obj(objdir_entry_t *mapping, uintptr_t vptr, objdir_entry_t *obj)
+{
+ if(vptr & 0xFFFF800000000000) return KE_OOB;
+ pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping);
+ uintptr_t pptr = (uintptr_t)ko_entry_data(obj);
+ return pml4_try_map(pml4, pptr, vptr);
}
diff --git a/arch/x86_64/memory/page_directory.c b/arch/x86_64/memory/pml4.c
index 11e4861..fcfc897 100644
--- a/arch/x86_64/memory/page_directory.c
+++ b/arch/x86_64/memory/pml4.c
@@ -5,37 +5,78 @@
#include "object.h"
#include "string.h"
#include "jove.h"
+#include "error.h"
#include <stdint.h>
+#define IDENTITY_BASE 0xFFFF800000000000
+uintptr_t vptr_tophys(void *vptr)
+{
+ return ((uintptr_t)vptr) - IDENTITY_BASE;
+}
+
physptr_t
-vmem_tophys_koff(virtptr_t v)
+vptr_tophys_koff(virtptr_t v)
{
return v - (physptr_t)&_kernel_start + _boot_kernel_phys_base;
}
-#define IDENTITY_BASE 0xFFFF800000000000
void*
-vmem_phys_tovirt(physptr_t p)
+pptr_tovirt_ident(physptr_t p)
{
return (void*)(p + IDENTITY_BASE);
}
-uintptr_t vmem_ident_tophys(void *vptr)
-{
- return ((uintptr_t)vptr) - IDENTITY_BASE;
-}
-
void*
pmle_get_page(pmle_t entry)
{
uintptr_t pptr = entry.paddr << 12;
- return vmem_phys_tovirt(pptr);
+ return pptr_tovirt_ident(pptr);
+}
+
+void
+pml4_get_path(uintptr_t vptr, uint8_t depth, uint16_t *path)
+{
+ for(uint8_t i = 0; i < depth; i++) {
+ path[i] = PML_I_FOR_LAYER(vptr, 4 - i);
+ }
}
-uint8_t
-pmle_level(pmle_t entry)
+pmle_t*
+pml4_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path)
{
- return entry.osflg;
+ uint16_t pathi = path[0];
+
+ pmle_t *pmle = &pml4[pathi];
+ pmle_t *pmle_table = pptr_tovirt_ident(pmle->paddr << 12);
+ if(depth == 0) return pmle;
+ if(!pmle->p) return NULL;
+ return pml4_traverse(pmle_table, depth - 1, path + 1);
+}
+
+pmle_t*
+pml4_get_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr)
+{
+ uint64_t pathval = 0;
+ uint16_t *path = (uint16_t*)&pathval;
+
+ pml4_get_path(vptr, depth, path);
+ return pml4_traverse(pml4, depth - 1, path);
+}
+
+int
+pml4_try_map(pmle_t *pml4, uintptr_t pptr, uintptr_t vptr)
+{
+ uint64_t pathval = 0;
+ uint16_t *path = (uint16_t*)&pathval;
+
+ pml4_get_path(vptr, 4, path);
+ pmle_t *mapping = pml4_traverse(pml4, 3, path);
+
+ if(mapping == NULL) return KE_DNE;
+ if(mapping->p) return KE_FULL;
+
+ mapping->value = pptr | PAGE_PRESENT | PAGE_RW | PAGE_US;
+ return KE_OK;
}
__attribute__((aligned(0x1000))) pmle_t s_kernel_pml4[512]; // Page L4
@@ -47,7 +88,7 @@ __attribute__((aligned(0x1000))) pmle_t s_idmap_pml3[512];
__attribute__((aligned(0x1000))) pmle_t s_idmap_pml2[512];
void
-vmem_setup(void)
+pml4_setup_init(void)
{
memset(s_kernel_pml4, 0, 0x1000);
memset(s_kernel_pml3, 0, 0x1000);
@@ -63,13 +104,13 @@ vmem_setup(void)
size_t kernel_size = kernel_end - kernel_start;
size_t kernel_size_pages = (kernel_size / 0x1000) + 1;
- physptr_t kernel_pml4_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml4);
- physptr_t kernel_pml3_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml3);
- physptr_t kernel_pml2_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml2);
- physptr_t kernel_pml1_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml1);
+ physptr_t kernel_pml4_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml4);
+ physptr_t kernel_pml3_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml3);
+ physptr_t kernel_pml2_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml2);
+ physptr_t kernel_pml1_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml1);
- physptr_t idmap_pml3_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml3);
- physptr_t idmap_pml2_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml2);
+ physptr_t idmap_pml3_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml3);
+ physptr_t idmap_pml2_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml2);
processor_t *processor = processor_current();
processor->pdir = kernel_pml4_base;
@@ -103,3 +144,10 @@ vmem_setup(void)
.data = kernel_pml4_base
};
}
+
+void
+pml4_setup(pmle_t *pml4)
+{
+ memset(pml4, 0, 0x800);
+ memcpy(&pml4[256], &s_kernel_pml4[256], 0x800);
+}
diff --git a/arch/x86_64/memory/untyped_retype_page.c b/arch/x86_64/memory/untyped_retype_page.c
deleted file mode 100644
index 32afe2c..0000000
--- a/arch/x86_64/memory/untyped_retype_page.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "memory.h"
-#include "arch/x86_64/page.h"
-#include "print.h"
-#include <stddef.h>
-
-static int
-s_untyped_retype(
- objdir_entry_t *untyped_entry,
- size_t size,
- size_t align,
- void **dest)
-{
- if(untyped_entry->type != KO_MEMORY_UNTYPED) return -1;
- if((untyped_entry->data & (align - 1)) != 0) return -2; //EALIGN
-
- uintptr_t *untyped_data = vmem_phys_tovirt(untyped_entry->data);
- uintmax_t untyped_size = *untyped_data;
-
- if(untyped_size <= size) {
- return -3;
- }
-
- *untyped_data -= size;
- *dest = (void*)(untyped_entry->data + untyped_size - size);
-
- return 0;
-}
-
-int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest)
-{
- int r = s_untyped_retype(untyped_entry, 0x1000, 0x1000, dest);
- if(r != 0) return r;
-
- #ifdef DBG_MEM
- klogf("Untyped block %p retyped to page at %p\n", untyped_entry->data, *dest);
- #endif
- return r;
-}
diff --git a/arch/x86_64/syscall/invoke-mapping.c b/arch/x86_64/syscall/invoke-mapping.c
index be401d6..5fde8be 100644
--- a/arch/x86_64/syscall/invoke-mapping.c
+++ b/arch/x86_64/syscall/invoke-mapping.c
@@ -16,7 +16,7 @@ s_handle_invoke_mapping_exists(
size_t payload_at
)
{
- pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data);
pmle_t *target_pml;
uint8_t target_depth;
SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
@@ -36,7 +36,7 @@ s_handle_invoke_mapping_map(
size_t payload_at
)
{
- pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data);
pmle_t *target_pml;
uint8_t target_depth;
SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
@@ -85,7 +85,7 @@ s_handle_invoke_mapping_unmap(
size_t payload_at
)
{
- pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data);
pmle_t *target_pml;
uint8_t target_depth;
SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
@@ -105,7 +105,7 @@ s_handle_invoke_mapping_unmap(
if(dest_entry->type != KO_NONE) return KE_FULL;
uintptr_t pmle_addr = target_pml->paddr << 12;
- size_t *untyped = vmem_phys_tovirt(pmle_addr);
+ size_t *untyped = pptr_tovirt_ident(pmle_addr);
__asm__ volatile("invlpg (%0)":: "r"(untyped): "memory");
*untyped = 0x1000;
diff --git a/arch/x86_64/syscall/wrappers.h b/arch/x86_64/syscall/wrappers.h
index a6fdf88..0803262 100644
--- a/arch/x86_64/syscall/wrappers.h
+++ b/arch/x86_64/syscall/wrappers.h
@@ -8,7 +8,7 @@
SYSCALL_PAYLOAD_TAKEL(payload, at, depth, uint8_t); \
if(((depth + 1) * sizeof(uint16_t)) + at >= KO_MESSAGE_BYTES) return KE_BADMSG; \
if(depth == 0 && *(uint16_t*)&payload[at] > 255) return KE_OOB; \
- pml = page_mapping_traverse(pml4, depth, (uint16_t*)&payload[at]); \
+ pml = pml4_traverse(pml4, depth, (uint16_t*)&payload[at]); \
at += (depth + 1) * sizeof(uint16_t)
#endif
diff --git a/arch/x86_64/usermode.c b/arch/x86_64/usermode.c
index aa626a9..8975993 100644
--- a/arch/x86_64/usermode.c
+++ b/arch/x86_64/usermode.c
@@ -1,76 +1,4 @@
-#include "arch/x86_64/object.h"
-#include "object.h"
-#include "bootargs.h"
-#include "device/initrd.h"
-#include "object.h"
-#include "panic.h"
-#include "string.h"
-#include "device/processor.h"
-#include "arch/x86_64/page.h"
-#include "print.h"
-static tcb_t s_init_tcb;
-
-//Dynamic allocation hell!!!
-static uintptr_t
-s_new_mapping(objdir_t *untyped_dir)
-{
- objdir_entry_t *untyped_entry = NULL;
- for(int i = untyped_dir->self.data - 1; i != 0; i--) {
- untyped_entry = &untyped_dir->entries[i];
- if(untyped_entry->type != KO_MEMORY_UNTYPED) continue;
- uintptr_t mapping = 0;
- int err = untyped_retype_page(untyped_entry, (void**)&mapping);
- if(err != 0) continue;
- return mapping;
- }
- kpanic("Could not allocate page for init\n");
-}
-
-static pmle_t*
-s_ensure_mapping_layer(pmle_t *pml, objdir_t *untyped_dir, uintptr_t addr, uint8_t layer)
-{
- pmli_t pmli = PML_I_FOR_LAYER(addr, layer);
- if(pml[pmli].p)
- return pmle_get_page(pml[pmli]);
-
- uintptr_t table_phys = s_new_mapping(untyped_dir);
- pmle_t *table = vmem_phys_tovirt(table_phys);
- memset(table, 0, 0x1000);
-
- pml[pmli] = (pmle_t) {
- .p = 1,
- .rw = 1,
- .us = 1,
- .osflg = (layer - 1) & 3,
- .paddr = table_phys >> 12
- };
- __asm__ volatile("invlpg (%0)":: "r"(table_phys));
- return vmem_phys_tovirt(table_phys);
-}
-
-static uintptr_t
-s_map_page(pmle_t *pml4, objdir_t *untyped_dir, uintptr_t addr)
-{
- pmle_t *pml3 = s_ensure_mapping_layer(pml4, untyped_dir, addr, 4);
- pmle_t *pml2 = s_ensure_mapping_layer(pml3, untyped_dir, addr, 3);
- pmle_t *pml1 = s_ensure_mapping_layer(pml2, untyped_dir, addr, 2);
-
- pmli_t pml1i = PML_I_FOR_LAYER(addr, 1);
- pmle_t *pmle = &pml1[pml1i];
-
- uintptr_t pptr = s_new_mapping(untyped_dir);
-
- *pmle = (pmle_t) {
- .p = 1,
- .rw = 1,
- .us = 1,
- .osflg = 0,
- .paddr = pptr >> 12
- };
- __asm__ volatile("invlpg (%0)":: "r"(addr));
- return pptr;
-}
__attribute__((noreturn))
static void
@@ -85,68 +13,3 @@ s_enter_usermode(void *ip, void *sp)
"r"(sp), "r"(ip): "memory");
for(;;);
}
-
-void
-init_load(void)
-{
- const char *init_filename = bootargs_getarg("init");
- if(init_filename == NULL) {
- kpanic("Missing boot argument \"init\"");
- }
- tar_header_t *init_header = initrd_find_file(init_filename);
- if(init_header == NULL) {
- kpanic("Init file not found in initrd. (expected \"%s\")", init_filename);
- }
-
- _initDirectory.entries[INIT_OBJECT_TCB] = (objdir_entry_t) {
- .type = KO_TCB,
- .data = vmem_tophys_koff((uintptr_t)&s_init_tcb)
- };
-
- objdir_t *untyped_dir = (objdir_t*)_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR].data;
- pmle_t *pml4 = vmem_phys_tovirt(_initDirectory.entries[INIT_OBJECT_PAGEMAP].data & ~3ULL);
-
- //Reserve and map pages for init binary
- size_t init_size = initrd_file_size(init_header);
-
- size_t init_pages = (init_size >> 12);
- uintptr_t init_base = 0x1000;
-
- for(size_t i = 0; i < init_pages + 1; i++) {
- s_map_page(pml4, untyped_dir, init_base + (i * 0x1000));
- }
- //Copy over init data
- memcpy((void*)init_base, (&((tar_block_t*)init_header)[1])->data, init_size);
-
- //Create a user stack
- uintptr_t stack_base = 0x00007FFFFFFFF000;
- s_map_page(pml4, untyped_dir, stack_base);
- uintptr_t sp = stack_base + 0xFF0;
-
- //Create a kernel stack for the init TCB
- uintptr_t ksp_base = (uintptr_t)&s_init_tcb.kstack;
- s_init_tcb.ksp = ksp_base + 0xFF0;
-
- processor_t *proc = (processor_t*)processor_current();
- proc->tss.rsp0 = s_init_tcb.ksp;
- klogf("RSP0 %p\n", s_init_tcb.ksp);
-
- //Create a message object for init
- uintptr_t message_base = init_base + (init_pages << 12);
- message_base += ((~(message_base & 0xFFF)) & 0xFFF) + 1;
-
- uintptr_t message_phys = s_map_page(pml4, untyped_dir, message_base);
- _initDirectory.entries[INIT_OBJECT_MESSAGE] = (objdir_entry_t) {
- .type = KO_MESSAGE,
- .extra = KODE_EX_MESSAGE_MAPPED,
- .data = message_base
- };
-
- //Write message address to user stack.
- sp -= sizeof(uintptr_t);
- *((uintptr_t*)sp) = message_base;
-
- //Setup usermode and jump
- proc->tcb = &s_init_tcb;
- s_enter_usermode((void*)init_base, (void*)sp);
-}