aarch64: some memory size management
This commit is contained in:
parent
bbd9bc7b5c
commit
bf40d8f289
@ -34,7 +34,6 @@ union PML * mmu_get_page(uintptr_t virtAddr, int flags);
|
||||
void mmu_set_directory(union PML * new_pml);
|
||||
void mmu_free(union PML * from);
|
||||
union PML * mmu_clone(union PML * from);
|
||||
void mmu_init(size_t memsize, uintptr_t firstFreePage);
|
||||
void mmu_invalidate(uintptr_t addr);
|
||||
uintptr_t mmu_allocate_a_frame(void);
|
||||
uintptr_t mmu_allocate_n_frames(int n);
|
||||
|
@ -671,12 +671,12 @@ static uintptr_t k2p(void * x) {
|
||||
return ((uintptr_t)x - MODULE_BASE_START) + QEMU_VIRT_KERNEL_BASE;
|
||||
}
|
||||
|
||||
void mmu_init(uintptr_t memsize, uintptr_t firstFreePage) {
|
||||
void mmu_init(uintptr_t memsize, size_t physsize, uintptr_t firstFreePage, uintptr_t endOfRamDisk) {
|
||||
this_core->current_pml = (union PML *)&init_page_region;
|
||||
|
||||
/* On this machine, there's 1GiB of unavailable memory. */
|
||||
unavailable_memory = 1048576;
|
||||
total_memory = 4194304;
|
||||
total_memory = memsize / 1024;
|
||||
|
||||
/* MAIR setup? */
|
||||
uint64_t mair;
|
||||
@ -727,9 +727,12 @@ void mmu_init(uintptr_t memsize, uintptr_t firstFreePage) {
|
||||
|
||||
/* Set up some space to map us */
|
||||
|
||||
/* How many 2MiB spans do we need to cover to endOfRamDisk? */
|
||||
size_t twoms = (endOfRamDisk + (LARGE_PAGE_SIZE - 1)) / LARGE_PAGE_SIZE;
|
||||
|
||||
/* init_page_region[511] -> high_base_pml[510] -> kbase_pmls[0] -> kbase_pmls[1+n] */
|
||||
high_base_pml[510].raw = k2p(&kbase_pmls[0]) | PTE_VALID | PTE_TABLE | PTE_AF;
|
||||
for (size_t j = 0; j < 64; ++j) {
|
||||
for (size_t j = 0; j < twoms; ++j) {
|
||||
kbase_pmls[0][j].raw = k2p(&kbase_pmls[1+j]) | PTE_VALID | PTE_TABLE | PTE_AF;
|
||||
for (int i = 0; i < 512; ++i) {
|
||||
kbase_pmls[1+j][i].raw = (uintptr_t)(QEMU_VIRT_KERNEL_BASE + LARGE_PAGE_SIZE * j + PAGE_SIZE * i) |
|
||||
@ -750,7 +753,7 @@ void mmu_init(uintptr_t memsize, uintptr_t firstFreePage) {
|
||||
|
||||
/* Physical frame allocator. We're gonna do this the same as the one we have x86-64, because
|
||||
* I can't be bothered to think of anything better right now... */
|
||||
nframes = (memsize) >> 12;
|
||||
nframes = (physsize) >> 12;
|
||||
size_t bytesOfFrames = INDEX_FROM_BIT(nframes * 8);
|
||||
bytesOfFrames = (bytesOfFrames + PAGE_LOW_MASK) & PAGE_SIZE_MASK;
|
||||
|
||||
@ -775,7 +778,7 @@ void mmu_init(uintptr_t memsize, uintptr_t firstFreePage) {
|
||||
}
|
||||
|
||||
/* Set kernel space as in use */
|
||||
for (uintptr_t i = 0; i < 64 * LARGE_PAGE_SIZE; i += PAGE_SIZE) {
|
||||
for (uintptr_t i = 0; i < twoms * LARGE_PAGE_SIZE; i += PAGE_SIZE) {
|
||||
mmu_frame_set(QEMU_VIRT_KERNEL_BASE + i);
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,13 @@
|
||||
#include <kernel/vfs.h>
|
||||
#include <kernel/mmu.h>
|
||||
#include <kernel/generic.h>
|
||||
#include <kernel/pipe.h>
|
||||
|
||||
#include <kernel/arch/aarch64/regs.h>
|
||||
|
||||
extern void framebuffer_initialize(void);
|
||||
extern void fbterm_initialize(void);
|
||||
extern void mmu_init(size_t memsize, size_t phys, uintptr_t firstFreePage, uintptr_t endOfInitrd);
|
||||
|
||||
static uint32_t swizzle(uint32_t from) {
|
||||
uint8_t a = from >> 24;
|
||||
@ -735,6 +737,7 @@ static void exception_handlers(void) {
|
||||
asm volatile("msr VBAR_EL1, %0" :: "r"(&_exception_vector));
|
||||
}
|
||||
|
||||
static void update_clock(void);
|
||||
void aarch64_sync_enter(struct regs * r) {
|
||||
uint64_t esr, far, elr, spsr;
|
||||
asm volatile ("mrs %0, ESR_EL1" : "=r"(esr));
|
||||
@ -742,6 +745,10 @@ void aarch64_sync_enter(struct regs * r) {
|
||||
asm volatile ("mrs %0, ELR_EL1" : "=r"(elr));
|
||||
asm volatile ("mrs %0, SPSR_EL1" : "=r"(spsr));
|
||||
|
||||
if (this_core->current_process) {
|
||||
this_core->current_process->time_switch = arch_perf_timer();
|
||||
}
|
||||
|
||||
if (elr == 0xFFFFB00F && far == 0xFFFFB00F) {
|
||||
task_exit(0);
|
||||
__builtin_unreachable();
|
||||
@ -760,6 +767,8 @@ void aarch64_sync_enter(struct regs * r) {
|
||||
printf(" x5: %#zx\n", r->x5);
|
||||
#endif
|
||||
|
||||
update_clock();
|
||||
|
||||
extern void syscall_handler(struct regs *);
|
||||
syscall_handler(r);
|
||||
|
||||
@ -777,6 +786,7 @@ void aarch64_sync_enter(struct regs * r) {
|
||||
|
||||
if (far == 0x1de7ec7edbadc0de) {
|
||||
/* KVM is mad at us */
|
||||
printf("kvm: blip (esr=%#zx, elr=%#zx; pid=%d [%s])\n", esr, elr, this_core->current_process->id, this_core->current_process->name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -820,12 +830,19 @@ static void fpu_enable(void) {
|
||||
}
|
||||
|
||||
static void timer_start(void) {
|
||||
volatile uint32_t * clock_addr = mmu_map_from_physical(0x09010000);
|
||||
|
||||
clock_addr[4] = 0;
|
||||
clock_addr[7] = 1;
|
||||
|
||||
#if 0
|
||||
asm volatile ("msr CNTKCTL_EL1, %0" ::
|
||||
"r"(
|
||||
(1 << 17) /* lower rate */
|
||||
| (23 << 4) /* uh lowest bit? */
|
||||
| (1 << 1) /* enable event stream */
|
||||
));
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint64_t time_slice_basis = 0; /**< When the last clock update happened */
|
||||
@ -862,6 +879,19 @@ void arch_pause(void) {
|
||||
switch_next();
|
||||
}
|
||||
|
||||
static fs_node_t * mouse_pipe;
|
||||
static fs_node_t * keyboard_pipe;
|
||||
|
||||
static void fake_input(void) {
|
||||
mouse_pipe = make_pipe(128);
|
||||
mouse_pipe->flags = FS_CHARDEVICE;
|
||||
vfs_mount("/dev/mouse", mouse_pipe);
|
||||
|
||||
keyboard_pipe = make_pipe(128);
|
||||
keyboard_pipe->flags = FS_CHARDEVICE;
|
||||
vfs_mount("/dev/kbd", keyboard_pipe);
|
||||
}
|
||||
|
||||
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;
|
||||
@ -873,6 +903,33 @@ void arch_clear_icache(uintptr_t start, uintptr_t end) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out 1) how much actual memory we have and 2) what the last
|
||||
* address of physical memory is.
|
||||
*/
|
||||
static void dtb_memory_size(size_t * memsize, size_t * physsize) {
|
||||
uint32_t * memory = find_node_prefix("memory");
|
||||
if (!memory) {
|
||||
printf("dtb: Could not find memory node.\n");
|
||||
arch_fatal();
|
||||
}
|
||||
|
||||
uint32_t * regs = node_find_property(memory, "reg");
|
||||
if (!regs) {
|
||||
printf("dtb: memory node has no regs\n");
|
||||
arch_fatal();
|
||||
}
|
||||
|
||||
/* Eventually, same with fw-cfg, we'll need to actually figure out
|
||||
* the size of the 'reg' cells, but at least right now it's been
|
||||
* 2 address, 2 size. */
|
||||
uint64_t mem_addr = (uint64_t)swizzle(regs[3]) | ((uint64_t)swizzle(regs[2]) << 32UL);
|
||||
uint64_t mem_size = (uint64_t)swizzle(regs[5]) | ((uint64_t)swizzle(regs[4]) << 32UL);
|
||||
|
||||
*memsize = mem_size;
|
||||
*physsize = mem_addr + mem_size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main kernel C entrypoint for qemu's -machine virt
|
||||
@ -912,7 +969,13 @@ int kmain(void) {
|
||||
|
||||
/* TODO get initial memory map data?
|
||||
* Eh, we can probably just probe the existing tables... maybe... */
|
||||
mmu_init(8UL * 1024 * 1024 * 1024 /* Should be maximum valid physical address */, 0x40100000 /* Should be end of DTB */);
|
||||
extern char end[];
|
||||
size_t memsize, physsize;
|
||||
dtb_memory_size(&memsize, &physsize);
|
||||
mmu_init(
|
||||
memsize, physsize,
|
||||
0x40100000 /* Should be end of DTB, but we're really just guessing */,
|
||||
(uintptr_t)&end + ramdisk_size - 0xffffffff80000000UL);
|
||||
|
||||
/* Find the cmdline */
|
||||
dtb_locate_cmdline();
|
||||
@ -935,6 +998,7 @@ int kmain(void) {
|
||||
timer_start();
|
||||
|
||||
/* TODO Install drivers that may need to sleep here */
|
||||
fake_input();
|
||||
|
||||
generic_main();
|
||||
|
||||
|
@ -45,6 +45,7 @@ extern void ps2hid_install(void);
|
||||
extern void serial_initialize(void);
|
||||
extern void fbterm_initialize(void);
|
||||
extern void pci_remap(void);
|
||||
extern void mmu_init(size_t memsize, uintptr_t firstFreePage);
|
||||
|
||||
struct multiboot * mboot_struct = NULL;
|
||||
int mboot_is_2 = 0;
|
||||
|
@ -872,7 +872,6 @@ long sys_fork(void) {
|
||||
}
|
||||
|
||||
long sys_clone(uintptr_t new_stack, uintptr_t thread_func, uintptr_t arg) {
|
||||
printf("sys_clone() from pid=%d\n", this_core->current_process->id);
|
||||
if (!new_stack || !PTR_INRANGE(new_stack)) return -EINVAL;
|
||||
if (!thread_func || !PTR_INRANGE(thread_func)) return -EINVAL;
|
||||
return (int)clone(new_stack, thread_func, arg);
|
||||
|
Loading…
Reference in New Issue
Block a user