WIP
This commit is contained in:
@ -9,11 +9,11 @@
|
||||
#include "kprintf.h"
|
||||
#include "spinlock/spinlock.h"
|
||||
|
||||
PgTable *KERNEL_CR3 = NULL;
|
||||
uint64_t KERNEL_CR3 = 0;
|
||||
SpinLock spinlock;
|
||||
|
||||
PgTable *hal_vmm_current_cr3(void) {
|
||||
PgTable *cr3;
|
||||
uint64_t hal_vmm_current_cr3(void) {
|
||||
uint64_t cr3;
|
||||
asm volatile("mov %%cr3, %0" : "=r"(cr3));
|
||||
return cr3;
|
||||
}
|
||||
@ -30,92 +30,93 @@ PgIndex hal_vmm_pageindex(uint64_t vaddr) {
|
||||
}
|
||||
|
||||
uint64_t *hal_vmm_nexttable(uint64_t *table, uint64_t ent) {
|
||||
uint8_t *addr;
|
||||
|
||||
if (table[ent] & HAL_PG_PRESENT) {
|
||||
addr = (uint8_t *)(table[ent] & ~((uint64_t)0xfff));
|
||||
uint64_t entry = table[ent];
|
||||
uint64_t phys;
|
||||
if (entry & HAL_PG_PRESENT) {
|
||||
phys = entry & ~0xFFFULL;
|
||||
} else {
|
||||
addr = pmm_alloc(1);
|
||||
hal_memset(BOOT_INFO.hhdm_off + addr, 0, HAL_PAGE_SIZE);
|
||||
table[ent] = (uint64_t)addr | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT;
|
||||
uint8_t *newphys = pmm_alloc(1);
|
||||
phys = (uint64_t)newphys;
|
||||
hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE);
|
||||
table[ent] = phys | HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT;
|
||||
}
|
||||
|
||||
return (uint64_t *)(BOOT_INFO.hhdm_off + addr);
|
||||
return (uint64_t *)((uint8_t *)VIRT(phys));
|
||||
}
|
||||
|
||||
void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags) {
|
||||
void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, uint32_t flags) {
|
||||
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
|
||||
PgIndex pi = hal_vmm_pageindex(virtaddr);
|
||||
|
||||
uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4);
|
||||
uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3);
|
||||
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2);
|
||||
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
|
||||
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
|
||||
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
|
||||
uint64_t *pte = &pml1[pi.pml1];
|
||||
|
||||
*pte = (physaddr & ~0xFFF) | (flags & 0x7);
|
||||
*pte = (physaddr & ~0xFFFULL) | ((uint64_t)flags & 0x7ULL);
|
||||
}
|
||||
|
||||
void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr) {
|
||||
void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr) {
|
||||
uint64_t *pml4 = (uint64_t *)VIRT(cr3phys);
|
||||
PgIndex pi = hal_vmm_pageindex(virtaddr);
|
||||
|
||||
uint64_t *pml3 = hal_vmm_nexttable((uint64_t *)pml4, pi.pml4);
|
||||
uint64_t *pml2 = hal_vmm_nexttable((uint64_t *)pml3, pi.pml3);
|
||||
uint64_t *pml1 = hal_vmm_nexttable((uint64_t *)pml2, pi.pml2);
|
||||
|
||||
uint64_t *pml3 = hal_vmm_nexttable(pml4, pi.pml4);
|
||||
uint64_t *pml2 = hal_vmm_nexttable(pml3, pi.pml3);
|
||||
uint64_t *pml1 = hal_vmm_nexttable(pml2, pi.pml2);
|
||||
uint64_t *pte = &pml1[pi.pml1];
|
||||
|
||||
*pte &= ~HAL_PG_PRESENT;
|
||||
}
|
||||
|
||||
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags) {
|
||||
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PG_PRESENT != 0) {
|
||||
void hal_vmm_map_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size, uint32_t flags) {
|
||||
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PAGE_SIZE != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
spinlock_acquire(&spinlock);
|
||||
uint8_t *vaddr = virtstart, *paddr = physstart;
|
||||
|
||||
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
||||
hal_vmm_map_page(cr3, (uint64_t)vaddr, (uint64_t)paddr, flags);
|
||||
uint8_t *vaddr = (uint8_t *)virtstart;
|
||||
uint8_t *paddr = (uint8_t *)physstart;
|
||||
uint8_t *end = (uint8_t *)virtstart + size;
|
||||
for (; vaddr < end; vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
||||
hal_vmm_map_page(cr3phys, (uint64_t)vaddr, (uint64_t)paddr, flags);
|
||||
}
|
||||
spinlock_release(&spinlock);
|
||||
}
|
||||
|
||||
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size) {
|
||||
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PG_PRESENT != 0) {
|
||||
void hal_vmm_unmap_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size) {
|
||||
if (size % HAL_PAGE_SIZE != 0 || (uint64_t)virtstart % HAL_PAGE_SIZE != 0 || (uint64_t)physstart % HAL_PAGE_SIZE != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
spinlock_acquire(&spinlock);
|
||||
uint8_t *vaddr = virtstart, *paddr = physstart;
|
||||
uint8_t *vaddr = (uint8_t *)virtstart;
|
||||
uint8_t *paddr = (uint8_t *)physstart;
|
||||
uint8_t *end = vaddr + size;
|
||||
|
||||
for (; vaddr <= ((uint8_t *)virtstart + size); vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
||||
hal_vmm_unmap_page(cr3, (uint64_t)vaddr, (uint64_t)paddr);
|
||||
for (; vaddr < end; vaddr += HAL_PAGE_SIZE, paddr += HAL_PAGE_SIZE) {
|
||||
hal_vmm_unmap_page(cr3phys, (uint64_t)vaddr, (uint64_t)paddr);
|
||||
}
|
||||
spinlock_release(&spinlock);
|
||||
}
|
||||
|
||||
void hal_vmm_map_kern(PgTable *cr3) {
|
||||
PgTable *kcr3 = BOOT_INFO.hhdm_off + KERNEL_CR3;
|
||||
void hal_vmm_map_kern(uint64_t targetcr3) {
|
||||
uint64_t *kcr3 = (uint64_t *)VIRT(KERNEL_CR3);
|
||||
uint64_t *cr3 = (uint64_t *)VIRT(targetcr3);
|
||||
for (size_t i = 256; i < 512; i++) {
|
||||
cr3->ents[i] = kcr3->ents[i];
|
||||
cr3[i] = kcr3[i];
|
||||
}
|
||||
}
|
||||
|
||||
void hal_vmm_switch_pd(PgTable *cr3) {
|
||||
hal_loadpd(cr3);
|
||||
}
|
||||
|
||||
PgTable *hal_vmm_userproc_pml4(Proc *proc) {
|
||||
uint8_t *cr3 = pmm_alloc(1);
|
||||
PgTable *pml4 = (PgTable *)VIRT(cr3);
|
||||
hal_memset(pml4, 0, HAL_PAGE_SIZE);
|
||||
|
||||
PgTable *kcr3 = VIRT(KERNEL_CR3);
|
||||
uint64_t hal_vmm_userproc_pml4_phys(Proc *proc) {
|
||||
uint8_t *cr3phys = pmm_alloc(1);
|
||||
uint64_t phys = (uint64_t)cr3phys;
|
||||
hal_memset(VIRT(phys), 0, HAL_PAGE_SIZE);
|
||||
|
||||
uint64_t *kcr3 = (uint64_t *)VIRT(KERNEL_CR3);
|
||||
uint64_t *pml4 = (uint64_t *)VIRT(phys);
|
||||
for (size_t i = 256; i < 512; i++) {
|
||||
pml4->ents[i] = kcr3->ents[i];
|
||||
pml4[i] = kcr3[i];
|
||||
}
|
||||
|
||||
return (PgTable *)cr3;
|
||||
return phys;
|
||||
}
|
||||
|
||||
void hal_vmm_init(void) {
|
||||
|
@ -26,10 +26,14 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint64_t pml4;
|
||||
uint64_t pml3;
|
||||
uint64_t pml2;
|
||||
uint64_t pml1;
|
||||
uint16_t pml4;
|
||||
uint16_t pml3;
|
||||
uint16_t pml2;
|
||||
uint16_t pml1;
|
||||
/* uint64_t pml4; */
|
||||
/* uint64_t pml3; */
|
||||
/* uint64_t pml2; */
|
||||
/* uint64_t pml1; */
|
||||
} PACKED PgIndex;
|
||||
|
||||
typedef struct {
|
||||
@ -39,25 +43,32 @@ typedef struct {
|
||||
bool writethrough: 1;
|
||||
bool cachedisabled: 1;
|
||||
bool accessed: 1;
|
||||
bool zero0: 1;
|
||||
bool size: 1;
|
||||
bool zero1: 1;
|
||||
bool dirty: 1;
|
||||
bool hugepage: 1;
|
||||
bool global: 1;
|
||||
uint8_t avail: 3;
|
||||
uint64_t addr: 52;
|
||||
uint64_t addr: 40;
|
||||
uint16_t osdef: 11;
|
||||
bool nx: 1;
|
||||
/* bool zero0: 1; */
|
||||
/* bool size: 1; */
|
||||
/* bool zero1: 1; */
|
||||
/* uint8_t avail: 3; */
|
||||
/* uint64_t addr: 52; */
|
||||
} PACKED Pte;
|
||||
|
||||
typedef struct {
|
||||
Pte ents[512];
|
||||
} PACKED PgTable;
|
||||
|
||||
extern PgTable *KERNEL_CR3;
|
||||
extern uint64_t KERNEL_CR3;
|
||||
|
||||
void hal_vmm_init(void);
|
||||
void hal_vmm_unmap_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr);
|
||||
void hal_vmm_map_page(PgTable *pml4, uint64_t virtaddr, uint64_t physaddr, uint32_t flags);
|
||||
PgTable *hal_vmm_current_cr3(void);
|
||||
void hal_vmm_map_range(PgTable *cr3, void *virtstart, void *physstart, size_t size, uint32_t flags);
|
||||
void hal_vmm_unmap_range(PgTable *cr3, void *virtstart, void *physstart, size_t size);
|
||||
PgTable *hal_vmm_userproc_pml4(struct Proc *proc);
|
||||
void hal_vmm_unmap_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr);
|
||||
void hal_vmm_map_page(uint64_t cr3phys, uint64_t virtaddr, uint64_t physaddr, uint32_t flags);
|
||||
uint64_t hal_vmm_current_cr3(void);
|
||||
void hal_vmm_map_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size, uint32_t flags);
|
||||
void hal_vmm_unmap_range(uint64_t cr3phys, void *virtstart, void *physstart, size_t size);
|
||||
uint64_t hal_vmm_userproc_pml4_phys(struct Proc *proc);
|
||||
|
||||
#endif // HAL_VMM_H_
|
||||
|
@ -34,7 +34,6 @@ bool proc_checkelf(uint8_t *elf) {
|
||||
}
|
||||
|
||||
ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
|
||||
PgTable *vas = proc->platformdata.cr3;
|
||||
ElfAuxval aux = {0};
|
||||
|
||||
Elf64_Ehdr *elfhdr = (Elf64_Ehdr *)data;
|
||||
@ -51,16 +50,16 @@ ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
|
||||
} break;
|
||||
case PT_LOAD: {
|
||||
uint64_t off = phdr->p_vaddr & (HAL_PAGE_SIZE - 1);
|
||||
uint64_t blocks = (phdr->p_memsz / HAL_PAGE_SIZE) + 1;
|
||||
uint64_t blocks = (off + phdr->p_memsz + HAL_PAGE_SIZE - 1) / HAL_PAGE_SIZE;
|
||||
|
||||
uint8_t *physaddr = pmm_alloc(blocks);
|
||||
uint8_t *virtaddr = (uint8_t *)(phdr->p_vaddr - off);
|
||||
uint8_t *virtaddr = (uint8_t *)(phdr->p_vaddr & ~(HAL_PAGE_SIZE - 1));
|
||||
|
||||
hal_memset(VIRT(physaddr), 0, phdr->p_memsz);
|
||||
hal_memset(VIRT(physaddr), 0, blocks * HAL_PAGE_SIZE);
|
||||
hal_memcpy(VIRT(physaddr) + off, (data + phdr->p_offset), phdr->p_filesz);
|
||||
|
||||
uint32_t pgflags = HAL_PG_USER | HAL_PG_RW | HAL_PG_PRESENT;
|
||||
hal_vmm_map_range(VIRT(vas), virtaddr, physaddr, blocks * HAL_PAGE_SIZE, pgflags);
|
||||
hal_vmm_map_range(proc->platformdata.cr3, virtaddr, physaddr, blocks * HAL_PAGE_SIZE, pgflags);
|
||||
|
||||
VasRange *range = dlmalloc(sizeof(*range));
|
||||
range->virtstart = virtaddr;
|
||||
@ -89,15 +88,15 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) {
|
||||
|
||||
proc->kern = true;
|
||||
|
||||
uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
|
||||
uint8_t *pstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
|
||||
uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
|
||||
proc->platformdata.kstack = kstackp;
|
||||
proc->platformdata.pstack = sp;
|
||||
proc->platformdata.pstack = pstackp;
|
||||
|
||||
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
|
||||
|
||||
proc->platformdata.trapframe.ss = 0x10;
|
||||
proc->platformdata.trapframe.rsp = (uint64_t)VIRT(sp);
|
||||
proc->platformdata.trapframe.rsp = (uint64_t)VIRT(pstackp);
|
||||
proc->platformdata.trapframe.rflags = 0x202;
|
||||
proc->platformdata.trapframe.cs = 0x08;
|
||||
proc->platformdata.trapframe.rip = (uint64_t)ent;
|
||||
@ -144,31 +143,50 @@ Proc *proc_spawnuser(char *mountpoint, char *path) {
|
||||
Proc *proc = dlmalloc(sizeof(*proc));
|
||||
hal_memset(proc, 0, sizeof(*proc));
|
||||
ksprintf(proc->name, "%s:%s", mountpoint, path);
|
||||
|
||||
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
|
||||
proc->platformdata.cr3 = hal_vmm_userproc_pml4_phys(proc);
|
||||
|
||||
uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
|
||||
uint8_t *spbase = sp - PROC_STACKSIZE;
|
||||
uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE;
|
||||
proc->platformdata.kstack = kstackp;
|
||||
proc->platformdata.pstack = sp;
|
||||
uint8_t *pstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS);
|
||||
proc->platformdata.pstack = pstackp;
|
||||
|
||||
hal_memset(&proc->platformdata.trapframe, 0, sizeof(proc->platformdata.trapframe));
|
||||
|
||||
proc->platformdata.cr3 = hal_vmm_userproc_pml4(proc);
|
||||
uint64_t virttop = PROC_USER_STACK_TOP;
|
||||
uint64_t virtbase = virttop - PROC_STACKSIZE;
|
||||
|
||||
uint32_t flags = HAL_PG_RW | HAL_PG_USER | HAL_PG_PRESENT;
|
||||
uint32_t flags = HAL_PG_RW | HAL_PG_PRESENT | HAL_PG_USER;
|
||||
hal_vmm_map_range(proc->platformdata.cr3, (void *)virtbase, (void *)pstackp, PROC_STACKSIZE, flags);
|
||||
|
||||
hal_vmm_map_range(VIRT(proc->platformdata.cr3), spbase, spbase, PROC_STACKSIZE, flags);
|
||||
VasRange *range = dlmalloc(sizeof(*range));
|
||||
range->virtstart = spbase;
|
||||
range->physstart = spbase;
|
||||
range->virtstart = (uint8_t *)virtbase;
|
||||
range->physstart = (uint8_t *)pstackp;
|
||||
range->size = PROC_STACKSIZE;
|
||||
range->pgflags = flags;
|
||||
LL_APPEND(proc->vas, range);
|
||||
|
||||
/* uint8_t *sp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; */
|
||||
/* uint8_t *spbase = sp - PROC_STACKSIZE; */
|
||||
/* uint8_t *kstackp = (uint8_t *)pmm_alloc(PROC_STACKBLOCKS) + PROC_STACKSIZE; */
|
||||
/* proc->platformdata.kstack = kstackp; */
|
||||
/* proc->platformdata.pstack = sp; */
|
||||
|
||||
|
||||
|
||||
/* uint32_t flags = HAL_PG_RW | HAL_PG_USER | HAL_PG_PRESENT; */
|
||||
|
||||
/* hal_vmm_map_range(proc->platformdata.cr3, spbase, spbase, PROC_STACKSIZE, flags); */
|
||||
/* VasRange *range = dlmalloc(sizeof(*range)); */
|
||||
/* range->virtstart = spbase; */
|
||||
/* range->physstart = spbase; */
|
||||
/* range->size = PROC_STACKSIZE; */
|
||||
/* range->pgflags = flags; */
|
||||
/* LL_APPEND(proc->vas, range); */
|
||||
|
||||
ElfAuxval aux = proc_load_elf_segs(proc, data);
|
||||
|
||||
proc->platformdata.trapframe.ss = 0x20 | 0x3;
|
||||
proc->platformdata.trapframe.rsp = (uint64_t)sp;
|
||||
proc->platformdata.trapframe.rsp = (uint64_t)virttop;
|
||||
proc->platformdata.trapframe.rflags = 0x202;
|
||||
proc->platformdata.trapframe.cs = 0x18 | 0x3;
|
||||
proc->platformdata.trapframe.rip = aux.entry;
|
||||
@ -206,6 +224,7 @@ Proc *proc_nextready(void) {
|
||||
}
|
||||
|
||||
void proc_reaper(void) {
|
||||
spinlock_acquire(&PROCS.spinlock);
|
||||
Proc *head = PROCS.procs;
|
||||
while (head) {
|
||||
if (head->state == PROC_ZOMBIE) {
|
||||
@ -221,13 +240,13 @@ void proc_reaper(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) { */
|
||||
/* if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) { */
|
||||
/* dlfree(zombie->pipes[i]); */
|
||||
/* ipc_pipefree(zombie->pipes[i]); */
|
||||
/* zombie->pipes[i] = NULL; */
|
||||
/* } */
|
||||
/* } */
|
||||
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
|
||||
if (zombie->pipes[i] != NULL && zombie->pipes[i]->ownerpid == zombie->pid) {
|
||||
dlfree(zombie->pipes[i]);
|
||||
ipc_pipefree(zombie->pipes[i]);
|
||||
zombie->pipes[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pmm_free((uintptr_t)(zombie->platformdata.kstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
|
||||
pmm_free((uintptr_t)(zombie->platformdata.pstack - PROC_STACKSIZE), PROC_STACKBLOCKS);
|
||||
@ -238,11 +257,8 @@ void proc_reaper(void) {
|
||||
while (vashead) {
|
||||
VasRange *tmp = vashead;
|
||||
vashead = vashead->next;
|
||||
hal_vmm_unmap_range(VIRT(zombie->platformdata.cr3), tmp->virtstart, tmp->physstart, tmp->size);
|
||||
// first pmm mapping is for the elf itself
|
||||
if (i == 0) {
|
||||
pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE);
|
||||
}
|
||||
hal_vmm_unmap_range(zombie->platformdata.cr3, tmp->virtstart, tmp->physstart, tmp->size);
|
||||
pmm_free((uintptr_t)tmp->physstart, tmp->size / HAL_PAGE_SIZE);
|
||||
dlfree(tmp);
|
||||
i++;
|
||||
}
|
||||
@ -262,6 +278,7 @@ void proc_reaper(void) {
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
spinlock_release(&PROCS.spinlock);
|
||||
}
|
||||
|
||||
void proc_sched(void *cpustate) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#define PROC_NAME_MAX 0x100
|
||||
|
||||
#define PROC_STACKBLOCKS 32
|
||||
#define PROC_STACKBLOCKS 256
|
||||
#define PROC_STACKSIZE (PROC_STACKBLOCKS * BITMAP_BLOCK_SIZE)
|
||||
|
||||
#define PROC_MAX 0x100 // max amount of processes
|
||||
@ -19,13 +19,14 @@
|
||||
#define PROC_VFSHANDLES_MAX 0x80
|
||||
#define PROC_PIPEHANDLES_MAX 0x20
|
||||
|
||||
#define PROC_MMAN_MAP_BASE 0xC000000000
|
||||
#define PROC_MMAN_MAP_BASE 0x0000004000000000ULL
|
||||
#define PROC_USER_STACK_TOP 0x00007ffffffff000ULL
|
||||
|
||||
typedef struct {
|
||||
IntrStackFrame trapframe;
|
||||
uint8_t *kstack;
|
||||
uint8_t *pstack;
|
||||
PgTable *cr3;
|
||||
uint64_t cr3;
|
||||
} ProcPlatformData;
|
||||
|
||||
enum {
|
||||
@ -33,6 +34,7 @@ enum {
|
||||
PROC_READY = 1,
|
||||
PROC_ZOMBIE = 2,
|
||||
PROC_WAITING = 3,
|
||||
PROC_DIED = 4,
|
||||
};
|
||||
|
||||
typedef struct ProcArg {
|
||||
|
@ -18,7 +18,7 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
|
||||
uint64_t flags = flags1;
|
||||
uint8_t **out = (uint8_t **)out1;
|
||||
|
||||
if (size % HAL_PAGE_SIZE != 0) {
|
||||
if (size == 0 || (size % HAL_PAGE_SIZE != 0)) {
|
||||
if (out != NULL) {
|
||||
*out = NULL;
|
||||
}
|
||||
@ -37,11 +37,19 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
|
||||
spinlock_release(&PROCS.spinlock);
|
||||
|
||||
uint8_t *virt = NULL;
|
||||
if (flags & MMAN_MAP_F_FIXED && addr != NULL) {
|
||||
if ((flags & MMAN_MAP_F_FIXED) && addr != NULL) {
|
||||
if ((uintptr_t)addr % HAL_PAGE_SIZE != 0) {
|
||||
if (out != NULL) {
|
||||
*out = NULL;
|
||||
}
|
||||
pmm_free((uintptr_t)phys, pages);
|
||||
return E_INVALIDARGUMENT;
|
||||
}
|
||||
|
||||
virt = addr;
|
||||
} else {
|
||||
virt = (uint8_t *)proc->mman_map_base;
|
||||
proc->mman_map_base += size;
|
||||
proc->mman_map_base += pages * HAL_PAGE_SIZE;
|
||||
}
|
||||
|
||||
uint64_t pflags = HAL_PG_USER | HAL_PG_PRESENT;
|
||||
@ -49,11 +57,11 @@ int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) {
|
||||
pflags |= HAL_PG_RW;
|
||||
}
|
||||
|
||||
hal_vmm_map_range(VIRT(proc->platformdata.cr3), virt, phys, size, pflags);
|
||||
hal_vmm_map_range(proc->platformdata.cr3, virt, phys, pages * HAL_PAGE_SIZE, pflags);
|
||||
VasRange *range = dlmalloc(sizeof(*range));
|
||||
range->virtstart = virt;
|
||||
range->physstart = phys;
|
||||
range->size = size * HAL_PAGE_SIZE;
|
||||
range->size = pages * HAL_PAGE_SIZE;
|
||||
range->pgflags = pflags;
|
||||
LL_APPEND(proc->vas, range);
|
||||
|
||||
@ -91,7 +99,7 @@ int32_t SYSCALL1(sys_mman_unmap, addr1) {
|
||||
return E_INVALIDARGUMENT;
|
||||
}
|
||||
|
||||
hal_vmm_unmap_range(VIRT(proc->platformdata.cr3), tofree->virtstart, tofree->physstart, tofree->size);
|
||||
hal_vmm_unmap_range(proc->platformdata.cr3, tofree->virtstart, tofree->physstart, tofree->size);
|
||||
LL_REMOVE(proc->vas, tofree);
|
||||
pmm_free((uintptr_t)tofree->physstart, tofree->size / HAL_PAGE_SIZE);
|
||||
dlfree(tofree);
|
||||
|
@ -29,7 +29,7 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
|
||||
|
||||
if (proc == NULL) {
|
||||
if (cmd == PCTL_POLLSTATE) {
|
||||
ret = 2;
|
||||
ret = PROC_DIED;
|
||||
goto done;
|
||||
}
|
||||
ret = E_INVALIDARGUMENT;
|
||||
@ -104,6 +104,44 @@ int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
|
||||
}
|
||||
ret = E_OK;
|
||||
} break;
|
||||
case PCTL_PLS_SZ: {
|
||||
size_t i = 0;
|
||||
spinlock_acquire(&PROCS.spinlock);
|
||||
Proc *p = PROCS.procs;
|
||||
while (p) {
|
||||
i++;
|
||||
p = p->next;
|
||||
}
|
||||
spinlock_release(&PROCS.spinlock);
|
||||
ret = i;
|
||||
} break;
|
||||
case PCTL_PLS_STAT: {
|
||||
uint64_t pidx = arg1;
|
||||
ProcStat *stat = (ProcStat *)arg2;
|
||||
|
||||
if (stat == NULL) {
|
||||
ret = E_INVALIDARGUMENT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
spinlock_acquire(&PROCS.spinlock);
|
||||
Proc *p = PROCS.procs;
|
||||
while (p) {
|
||||
if (i == pidx) {
|
||||
stat->pid = p->pid;
|
||||
hal_strcpy(stat->name, p->name);
|
||||
stat->state = p->state;
|
||||
stat->kern = p->kern;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
p = p->next;
|
||||
}
|
||||
spinlock_release(&PROCS.spinlock);
|
||||
ret = E_OK;
|
||||
} break;
|
||||
default: {
|
||||
ret = E_INVALIDARGUMENT;
|
||||
} break;
|
||||
|
Reference in New Issue
Block a user