moved VMA initialization to vma_init()

This commit is contained in:
Steffen Vogel 2014-02-18 12:50:59 +01:00
parent aa6abef955
commit 7a08120fd2
3 changed files with 128 additions and 58 deletions

View file

@ -81,6 +81,26 @@ typedef struct vma {
struct vma* prev;
} vma_t;
/** @brief Initalize the kernelspace VMA list
*
* Reserves several system-relevant virtual memory regions:
* - SMP boot page (SMP_SETUP_ADDR)
* - VGA video memory (VIDEO_MEM_ADDR)
* - MP Table (apic_mp)
* - IOAPIC mapped registers (IOAPIC_ADDR)
* - LAPIC mapped registers (LAPIC_ADDR)
* - The kernel (kernel_start - kernel_end)
* - Multiboot structure (mb_info)
* - Multiboot mmap (mb_info->mmap_*)
* - Multiboot modules (mb_info->mods_*)
* - Init Ramdisk
*
* @return
* - 0 on success
* - <0 on failure
*/
int vma_init();
/** @brief Add a new virtual memory area to the list of VMAs
*
* @param start Start address of the new area

View file

@ -35,7 +35,6 @@
#include <asm/SCC_API.h>
#include <asm/icc.h>
#endif
#include <asm/apic.h>
/*
* Set whole address space as occupied:
@ -55,8 +54,6 @@ atomic_int32_t total_available_pages = ATOMIC_INIT(0);
extern const void kernel_start;
extern const void kernel_end;
extern apic_mp_t* apic_mp;
inline static int page_marked(size_t i)
{
size_t index = i >> 3;
@ -304,67 +301,24 @@ int mmu_init(void)
return ret;
}
// add kernel to VMA list
vma_add(PAGE_CEIL((size_t) &kernel_start),
PAGE_FLOOR((size_t) &kernel_end),
VMA_READ|VMA_WRITE|VMA_EXECUTE|VMA_CACHEABLE);
// TODO: should we move the following architecture specific VMA regions
// to arch_paging_init() ?
// add Multiprocessing Tables to VMA list
vma_add(PAGE_CEIL((size_t) apic_mp),
PAGE_FLOOR((size_t) apic_mp + sizeof(apic_mp_t)),
VMA_READ|VMA_WRITE|VMA_EXECUTE|VMA_CACHEABLE);
// add IOAPIC and LAPIC to VMA list
vma_add(LAPIC_ADDR, LAPIC_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE);
vma_add(IOAPIC_ADDR, IOAPIC_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE);
#ifdef CONFIG_VGA
// add VGA to VMA list
vma_add(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE);
#endif
#if MAX_CORES > 1
// reserve page for SMP boot code
vma_add(SMP_SETUP_ADDR, SMP_SETUP_ADDR + PAGE_SIZE,
VMA_READ|VMA_WRITE|VMA_EXECUTE|VMA_CACHEABLE);
#endif
ret = vma_init();
if (ret) {
kprintf("Failed to initialize VMA regions: %d\n", ret);
return ret;
}
#ifdef CONFIG_MULTIBOOT
/*
* Modules like the init ram disk are already loaded.
* Therefore, we set these pages as used.
*/
if (mb_info) {
vma_add(PAGE_CEIL((size_t) mb_info),
PAGE_FLOOR((size_t) mb_info + sizeof(multiboot_info_t)),
VMA_READ|VMA_CACHEABLE);
if (mb_info->flags & MULTIBOOT_INFO_MEM_MAP) {
vma_add(PAGE_CEIL((size_t) mb_info->mmap_addr),
PAGE_FLOOR((size_t) mb_info->mmap_addr + mb_info->mmap_length),
VMA_READ|VMA_CACHEABLE);
}
if (mb_info->flags & MULTIBOOT_INFO_MODS) {
multiboot_module_t* mmodule = (multiboot_module_t*) ((size_t) mb_info->mods_addr);
vma_add(PAGE_CEIL((size_t) mb_info->mods_addr),
PAGE_FLOOR((size_t) mb_info->mods_addr + mb_info->mods_count*sizeof(multiboot_module_t)),
VMA_READ|VMA_CACHEABLE);
for(i=0; i<mb_info->mods_count; i++) {
vma_add(PAGE_CEIL(mmodule[i].mod_start),
PAGE_FLOOR(mmodule[i].mod_end),
VMA_READ|VMA_WRITE|VMA_CACHEABLE);
for(addr=mmodule[i].mod_start; addr<mmodule[i].mod_end; addr+=PAGE_SIZE) {
page_set_mark(addr >> PAGE_BITS);
atomic_int32_inc(&total_allocated_pages);
atomic_int32_dec(&total_available_pages);
}
if (mb_info && (mb_info->flags & MULTIBOOT_INFO_MODS)) {
multiboot_module_t* mmodule = (multiboot_module_t*) ((size_t) mb_info->mods_addr);
for(i=0; i<mb_info->mods_count; i++) {
for(addr=mmodule[i].mod_start; addr<mmodule[i].mod_end; addr+=PAGE_SIZE) {
page_set_mark(addr >> PAGE_BITS);
atomic_int32_inc(&total_allocated_pages);
atomic_int32_dec(&total_available_pages);
}
}
}

View file

@ -24,6 +24,20 @@
#include <metalsvm/spinlock.h>
#include <metalsvm/errno.h>
#ifdef CONFIG_MULTIBOOT
#include <asm/multiboot.h>
#endif
#include <asm/apic.h>
extern apic_mp_t* apic_mp;
/*
* Note that linker symbols are not variables, they have no memory allocated for
* maintaining a value, rather their address is their value.
*/
extern const void kernel_start;
extern const void kernel_end;
/*
* Kernel space VMA list and lock
*
@ -34,6 +48,88 @@ static vma_t vma_boot = { VMA_KERN_MIN, VMA_KERN_MIN, VMA_HEAP };
static vma_t* vma_list = &vma_boot;
static spinlock_t vma_lock = SPINLOCK_INIT;
// TODO: we might move the architecture specific VMA regions to a
// seperate function arch_vma_init()
int vma_init()
{
int ret;
// add Kernel
ret = vma_add(PAGE_CEIL((size_t) &kernel_start),
PAGE_FLOOR((size_t) &kernel_end),
VMA_READ|VMA_WRITE|VMA_EXECUTE|VMA_CACHEABLE);
if (ret)
goto out;
// add MP Table
ret = vma_add(PAGE_CEIL((size_t) apic_mp),
PAGE_FLOOR((size_t) apic_mp + sizeof(apic_mp_t)),
VMA_READ|VMA_WRITE|VMA_EXECUTE|VMA_CACHEABLE);
if (ret)
goto out;
// add IOAPIC and LAPIC memory mapped registers
ret = vma_add(LAPIC_ADDR, LAPIC_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE);
if (ret)
goto out;
ret = vma_add(IOAPIC_ADDR, IOAPIC_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE);
if (ret)
goto out;
#ifdef CONFIG_VGA
// add VGA video memory
ret = vma_add(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE);
if (ret)
goto out;
#endif
#if MAX_CORES > 1
// add SMP boot page
ret = vma_add(SMP_SETUP_ADDR, SMP_SETUP_ADDR + PAGE_SIZE,
VMA_READ|VMA_WRITE|VMA_EXECUTE|VMA_CACHEABLE);
if (ret)
goto out;
#endif
#ifdef CONFIG_MULTIBOOT
// add Multiboot structures as modules
if (mb_info) {
ret = vma_add(PAGE_CEIL((size_t) mb_info),
PAGE_FLOOR((size_t) mb_info + sizeof(multiboot_info_t)),
VMA_READ|VMA_CACHEABLE);
if (ret)
goto out;
if (mb_info->flags & MULTIBOOT_INFO_MEM_MAP) {
ret = vma_add(PAGE_CEIL((size_t) mb_info->mmap_addr),
PAGE_FLOOR((size_t) mb_info->mmap_addr + mb_info->mmap_length),
VMA_READ|VMA_CACHEABLE);
}
if (mb_info->flags & MULTIBOOT_INFO_MODS) {
multiboot_module_t* mmodule = (multiboot_module_t*) ((size_t) mb_info->mods_addr);
ret = vma_add(PAGE_CEIL((size_t) mb_info->mods_addr),
PAGE_FLOOR((size_t) mb_info->mods_addr + mb_info->mods_count*sizeof(multiboot_module_t)),
VMA_READ|VMA_CACHEABLE);
int i;
for(i=0; i<mb_info->mods_count; i++) {
ret = vma_add(PAGE_CEIL(mmodule[i].mod_start),
PAGE_FLOOR(mmodule[i].mod_end),
VMA_READ|VMA_WRITE|VMA_CACHEABLE);
if (ret)
goto out;
}
}
}
#endif
out:
return ret;
}
size_t vma_alloc(size_t size, uint32_t flags)
{
task_t* task = per_core(current_task);