aarch64: fixup clone(), add mmu_free(), cache stuff for ld.so
This commit is contained in:
parent
f0409ff120
commit
f0d7ed7743
@ -516,10 +516,54 @@ size_t mmu_used_memory(void) {
|
||||
|
||||
void mmu_free(union PML * from) {
|
||||
/* walk and free pages */
|
||||
if (!from) {
|
||||
printf("can't clear NULL directory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(frame_alloc_lock);
|
||||
for (size_t i = 0; i < 256; ++i) {
|
||||
if (from[i].bits.present) {
|
||||
union PML * pdp_in = mmu_map_from_physical((uintptr_t)from[i].bits.page << PAGE_SHIFT);
|
||||
for (size_t j = 0; j < 512; ++j) {
|
||||
if (pdp_in[j].bits.present) {
|
||||
union PML * pd_in = mmu_map_from_physical((uintptr_t)pdp_in[j].bits.page << PAGE_SHIFT);
|
||||
for (size_t k = 0; k < 512; ++k) {
|
||||
if (pd_in[k].bits.present) {
|
||||
union PML * pt_in = mmu_map_from_physical((uintptr_t)pd_in[k].bits.page << PAGE_SHIFT);
|
||||
for (size_t l = 0; l < 512; ++l) {
|
||||
uintptr_t address = ((i << (9 * 3 + 12)) | (j << (9*2 + 12)) | (k << (9 + 12)) | (l << PAGE_SHIFT));
|
||||
/* Do not free shared mappings; SHM subsystem does that for SHM, devices don't need it. */
|
||||
if (address >= USER_DEVICE_MAP && address <= USER_SHM_HIGH) continue;
|
||||
if (pt_in[l].bits.present) {
|
||||
/* Free only user pages */
|
||||
if (pt_in[l].bits.ap & 1) {
|
||||
mmu_frame_clear((uintptr_t)pt_in[l].bits.page << PAGE_SHIFT);
|
||||
pt_in[l].raw = 0;
|
||||
//free_page_maybe(pt_in,l,address);
|
||||
}
|
||||
}
|
||||
}
|
||||
mmu_frame_clear((uintptr_t)pd_in[k].bits.page << PAGE_SHIFT);
|
||||
pd_in[k].raw = 0;
|
||||
}
|
||||
}
|
||||
mmu_frame_clear((uintptr_t)pdp_in[j].bits.page << PAGE_SHIFT);
|
||||
pdp_in[j].raw = 0;
|
||||
}
|
||||
}
|
||||
mmu_frame_clear((uintptr_t)from[i].bits.page << PAGE_SHIFT);
|
||||
from[i].raw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mmu_frame_clear((((uintptr_t)from) & PHYS_MASK));
|
||||
asm volatile ("dsb ishst\ntlbi vmalle1is\ndsb ish\nisb" ::: "memory");
|
||||
spin_unlock(frame_alloc_lock);
|
||||
}
|
||||
|
||||
union PML * mmu_get_kernel_directory(void) {
|
||||
return (union PML*)&init_page_region;
|
||||
return mmu_map_from_physical((uintptr_t)&init_page_region);
|
||||
}
|
||||
|
||||
void mmu_set_directory(union PML * new_pml) {
|
||||
@ -586,6 +630,7 @@ void mmu_unmap_module(uintptr_t start_address, size_t size) {
|
||||
}
|
||||
|
||||
int mmu_copy_on_write(uintptr_t address) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -742,6 +742,11 @@ void aarch64_sync_enter(struct regs * r) {
|
||||
asm volatile ("mrs %0, ELR_EL1" : "=r"(elr));
|
||||
asm volatile ("mrs %0, SPSR_EL1" : "=r"(spsr));
|
||||
|
||||
if (elr == 0xFFFFB00F && far == 0xFFFFB00F) {
|
||||
task_exit(0);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
if ((esr >> 26) == 0x15) {
|
||||
#if 0
|
||||
printf("%s: syscall(%ld) puts sp at %#zx with base of %#zx\n", this_core->current_process->name, r->x0, (uintptr_t)r,
|
||||
@ -857,6 +862,16 @@ void arch_pause(void) {
|
||||
switch_next();
|
||||
}
|
||||
|
||||
void arch_clear_icache(uintptr_t start, uintptr_t end) {
|
||||
for (uintptr_t x = start; x < end; x += 64) {
|
||||
if (!mmu_validate_user_pointer((void*)x, 64, MMU_PTR_WRITE)) continue;
|
||||
asm volatile ("dc cvau, %0" :: "r"(x));
|
||||
}
|
||||
for (uintptr_t x = start; x < end; x += 64) {
|
||||
if (!mmu_validate_user_pointer((void*)x, 64, MMU_PTR_WRITE)) continue;
|
||||
asm volatile ("ic ivau, %0" :: "r"(x));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -282,6 +282,11 @@ int elf_exec(const char * path, fs_node_t * file, int argc, const char *const ar
|
||||
*(char*)(phdr.p_vaddr + i) = 0;
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
extern void arch_clear_icache(uintptr_t,uintptr_t);
|
||||
arch_clear_icache(phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz);
|
||||
#endif
|
||||
|
||||
if (phdr.p_vaddr + phdr.p_memsz > heapBase) {
|
||||
heapBase = phdr.p_vaddr + phdr.p_memsz;
|
||||
}
|
||||
|
@ -1378,10 +1378,11 @@ pid_t clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) {
|
||||
/* different calling convention */
|
||||
#if defined(__x86_64__)
|
||||
r.rdi = arg;
|
||||
PUSH(new_stack, uintptr_t, (uintptr_t)0xFFFFB00F);
|
||||
#elif defined(__aarch64__)
|
||||
r.x0 = arg;
|
||||
r.x30 = 0xFFFFB00F;
|
||||
#endif
|
||||
PUSH(new_stack, uintptr_t, (uintptr_t)0xFFFFB00F);
|
||||
PUSH(sp, struct regs, r);
|
||||
new_proc->syscall_registers = (void*)sp;
|
||||
#if defined(__x86_64__)
|
||||
@ -1391,8 +1392,7 @@ pid_t clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) {
|
||||
#elif defined(__aarch64__)
|
||||
new_proc->syscall_registers->user_sp = new_stack;
|
||||
new_proc->syscall_registers->x29 = new_stack;
|
||||
//new_proc->syscall_registers->x30 = thread_func;
|
||||
new_proc->thread.context.saved[14] = thread_func;
|
||||
new_proc->thread.context.saved[10] = thread_func;
|
||||
#endif
|
||||
new_proc->thread.context.sp = sp;
|
||||
new_proc->thread.context.bp = bp;
|
||||
|
@ -95,6 +95,15 @@ long sys_sysfunc(long fn, char ** args) {
|
||||
printf("kdebug: not implemented\n");
|
||||
return -EINVAL;
|
||||
|
||||
case 42:
|
||||
#ifdef __aarch64__
|
||||
PTR_VALIDATE(&args[0]);
|
||||
PTR_VALIDATE(&args[1]);
|
||||
extern void arch_clear_icache(uintptr_t,uintptr_t);
|
||||
arch_clear_icache((uintptr_t)args[0], (uintptr_t)args[1]);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
case TOARU_SYS_FUNC_INSMOD:
|
||||
/* Linux has init_module as a system call? */
|
||||
if (this_core->current_process->user != 0) return -EACCES;
|
||||
|
@ -115,6 +115,11 @@ typedef struct elf_object {
|
||||
|
||||
static elf_t * _main_obj = NULL;
|
||||
|
||||
static void clear_cache(uintptr_t start, uintptr_t end) {
|
||||
char * data[] = {(char*)start,(char*)end};
|
||||
sysfunc(42, data);
|
||||
}
|
||||
|
||||
/* Locate library for LD_LIBRARY PATH */
|
||||
static char * find_lib(const char * file) {
|
||||
|
||||
@ -298,6 +303,7 @@ static uintptr_t object_load(elf_t * object, uintptr_t base) {
|
||||
/* Copy the code into memory */
|
||||
fseek(object->file, phdr.p_offset, SEEK_SET);
|
||||
fread((void *)(base + phdr.p_vaddr), phdr.p_filesz, 1, object->file);
|
||||
clear_cache(base + phdr.p_vaddr, base + phdr.p_vaddr + phdr.p_filesz);
|
||||
|
||||
/* Zero the remaining area */
|
||||
size_t r = phdr.p_filesz;
|
||||
@ -431,7 +437,7 @@ static int object_relocate(elf_t * object) {
|
||||
hashmap_set(dumb_symbol_table, symname, (void*)(table->st_value + object->base));
|
||||
table->st_value = table->st_value + object->base;
|
||||
} else {
|
||||
table->st_value = hashmap_get(dumb_symbol_table, symname);
|
||||
table->st_value = (uintptr_t)hashmap_get(dumb_symbol_table, symname);
|
||||
}
|
||||
} else {
|
||||
table->st_value = table->st_value + object->base;
|
||||
|
Loading…
Reference in New Issue
Block a user