mirror of
https://github.com/drasko/codezero.git
synced 2026-04-18 01:39:05 +02:00
Adding address space structure to ktcbs. Still booting until virtual memory is enabled.
This commit is contained in:
@@ -123,6 +123,7 @@ typedef struct pmd_table {
|
|||||||
#define DABT_EXT_NON_LFETCH_SECT 0x8
|
#define DABT_EXT_NON_LFETCH_SECT 0x8
|
||||||
#define DABT_EXT_NON_LFETCH_PAGE 0xA
|
#define DABT_EXT_NON_LFETCH_PAGE 0xA
|
||||||
|
|
||||||
|
#define TASK_PGD(x) (x)->space->pgd
|
||||||
|
|
||||||
/* Kernel's data about the fault */
|
/* Kernel's data about the fault */
|
||||||
typedef struct fault_kdata {
|
typedef struct fault_kdata {
|
||||||
|
|||||||
@@ -19,6 +19,17 @@
|
|||||||
#define MAP_IO_DEFAULT_FLAGS MAP_SVC_IO_FLAGS
|
#define MAP_IO_DEFAULT_FLAGS MAP_SVC_IO_FLAGS
|
||||||
|
|
||||||
#if defined (__KERNEL__)
|
#if defined (__KERNEL__)
|
||||||
|
|
||||||
|
#include <l4/lib/list.h>
|
||||||
|
#include INC_SUBARCH(mm.h)
|
||||||
|
|
||||||
|
/* A simple page table with a reference count */
|
||||||
|
struct address_space {
|
||||||
|
struct list_head list;
|
||||||
|
pgd_table_t *pgd;
|
||||||
|
int ktcb_refs;
|
||||||
|
};
|
||||||
|
|
||||||
int check_access(unsigned long vaddr, unsigned long size, unsigned int flags);
|
int check_access(unsigned long vaddr, unsigned long size, unsigned int flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <l4/lib/mutex.h>
|
#include <l4/lib/mutex.h>
|
||||||
#include <l4/generic/scheduler.h>
|
#include <l4/generic/scheduler.h>
|
||||||
#include <l4/generic/pgalloc.h>
|
#include <l4/generic/pgalloc.h>
|
||||||
|
#include <l4/generic/space.h>
|
||||||
#include INC_GLUE(memory.h)
|
#include INC_GLUE(memory.h)
|
||||||
#include INC_GLUE(syscall.h)
|
#include INC_GLUE(syscall.h)
|
||||||
#include INC_GLUE(message.h)
|
#include INC_GLUE(message.h)
|
||||||
@@ -39,12 +40,6 @@ struct task_ids {
|
|||||||
l4id_t tgid;
|
l4id_t tgid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A simple page table with a reference count */
|
|
||||||
struct address_space {
|
|
||||||
struct pgd_table_t *pgd;
|
|
||||||
int ktcb_refs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ktcb {
|
struct ktcb {
|
||||||
/* User context */
|
/* User context */
|
||||||
task_context_t context;
|
task_context_t context;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ int sys_map(syscall_context_t *regs)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
found:
|
found:
|
||||||
add_mapping_pgd(phys, virt, npages << PAGE_BITS, flags, target->pgd);
|
add_mapping_pgd(phys, virt, npages << PAGE_BITS, flags, TASK_PGD(target));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ int sys_unmap(syscall_context_t *regs)
|
|||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
for (int i = 0; i < npages; i++) {
|
for (int i = 0; i < npages; i++) {
|
||||||
ret = remove_mapping_pgd(virtual + i * PAGE_SIZE, target->pgd);
|
ret = remove_mapping_pgd(virtual + i * PAGE_SIZE, TASK_PGD(target));
|
||||||
if (ret)
|
if (ret)
|
||||||
retval = ret;
|
retval = ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ int arch_clear_thread(struct ktcb *task)
|
|||||||
task->context.spsr = ARM_MODE_USR;
|
task->context.spsr = ARM_MODE_USR;
|
||||||
|
|
||||||
/* Clear the page tables */
|
/* Clear the page tables */
|
||||||
remove_mapping_pgd_all_user(task->pgd);
|
remove_mapping_pgd_all_user(TASK_PGD(task));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -256,12 +256,6 @@ int thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KTCB_CREATE_PAGE_TABLES (1 << 0)
|
|
||||||
/* Allocates a ktcb and page tables depending on flags */
|
|
||||||
struct ktcb *ktcb_create(unsigned int flags)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Creates a thread, with a new thread id, and depending on the flags,
|
* Creates a thread, with a new thread id, and depending on the flags,
|
||||||
* either creates a new space, uses the same space as another thread,
|
* either creates a new space, uses the same space as another thread,
|
||||||
@@ -282,23 +276,23 @@ int thread_create(struct task_ids *ids, unsigned int flags)
|
|||||||
/* Determine space allocation */
|
/* Determine space allocation */
|
||||||
if (create_flags == THREAD_NEW_SPACE) {
|
if (create_flags == THREAD_NEW_SPACE) {
|
||||||
/* Allocate new pgd and copy all kernel areas */
|
/* Allocate new pgd and copy all kernel areas */
|
||||||
if (!(new->pgd = alloc_pgd())) {
|
if (!(TASK_PGD(new) = alloc_pgd())) {
|
||||||
free_page(new);
|
free_page(new);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_pgd_kern_all(new->pgd);
|
copy_pgd_kern_all(TASK_PGD(new));
|
||||||
} else {
|
} else {
|
||||||
/* Existing space will be used, find it from all tasks */
|
/* Existing space will be used, find it from all tasks */
|
||||||
list_for_each_entry(task, &global_task_list, task_list) {
|
list_for_each_entry(task, &global_task_list, task_list) {
|
||||||
/* Space ids match, can use existing space */
|
/* Space ids match, can use existing space */
|
||||||
if (task->spid == ids->spid) {
|
if (task->spid == ids->spid) {
|
||||||
if (flags == THREAD_SAME_SPACE) {
|
if (flags == THREAD_SAME_SPACE) {
|
||||||
new->pgd = task->pgd;
|
TASK_PGD(new) = TASK_PGD(task);
|
||||||
} else {
|
} else {
|
||||||
new->pgd = copy_page_tables(task->pgd);
|
TASK_PGD(new) = copy_page_tables(TASK_PGD(task));
|
||||||
if (IS_ERR(new->pgd)) {
|
if (IS_ERR(TASK_PGD(new))) {
|
||||||
err = (int)new->pgd;
|
err = (int)TASK_PGD(new);
|
||||||
free_page(new);
|
free_page(new);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
void remove_section_mapping(unsigned long vaddr)
|
void remove_section_mapping(unsigned long vaddr)
|
||||||
{
|
{
|
||||||
pgd_table_t *pgd = current->pgd;
|
pgd_table_t *pgd = TASK_PGD(current);
|
||||||
pgd_t pgd_i = PGD_INDEX(vaddr);
|
pgd_t pgd_i = PGD_INDEX(vaddr);
|
||||||
if (!((pgd->entry[pgd_i] & PGD_TYPE_MASK)
|
if (!((pgd->entry[pgd_i] & PGD_TYPE_MASK)
|
||||||
& PGD_TYPE_SECTION))
|
& PGD_TYPE_SECTION))
|
||||||
@@ -174,7 +174,7 @@ pte_t virt_to_pte_from_pgd(unsigned long virtual, pgd_table_t *pgd)
|
|||||||
/* Convert a virtual address to a pte if it exists in the page tables. */
|
/* Convert a virtual address to a pte if it exists in the page tables. */
|
||||||
pte_t virt_to_pte(unsigned long virtual)
|
pte_t virt_to_pte(unsigned long virtual)
|
||||||
{
|
{
|
||||||
return virt_to_pte_from_pgd(virtual, current->pgd);
|
return virt_to_pte_from_pgd(virtual, TASK_PGD(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach_pmd(pgd_table_t *pgd, pmd_table_t *pmd, unsigned int vaddr)
|
void attach_pmd(pgd_table_t *pgd, pmd_table_t *pmd, unsigned int vaddr)
|
||||||
@@ -238,7 +238,7 @@ void add_mapping_pgd(unsigned int paddr, unsigned int vaddr,
|
|||||||
void add_mapping(unsigned int paddr, unsigned int vaddr,
|
void add_mapping(unsigned int paddr, unsigned int vaddr,
|
||||||
unsigned int size, unsigned int flags)
|
unsigned int size, unsigned int flags)
|
||||||
{
|
{
|
||||||
add_mapping_pgd(paddr, vaddr, size, flags, current->pgd);
|
add_mapping_pgd(paddr, vaddr, size, flags, TASK_PGD(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -271,7 +271,7 @@ int check_mapping_pgd(unsigned long vaddr, unsigned long size,
|
|||||||
int check_mapping(unsigned long vaddr, unsigned long size,
|
int check_mapping(unsigned long vaddr, unsigned long size,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
return check_mapping_pgd(vaddr, size, flags, current->pgd);
|
return check_mapping_pgd(vaddr, size, flags, TASK_PGD(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Empty PMDs should be returned here !!! */
|
/* FIXME: Empty PMDs should be returned here !!! */
|
||||||
@@ -416,7 +416,7 @@ int remove_mapping_pgd(unsigned long vaddr, pgd_table_t *pgd)
|
|||||||
|
|
||||||
int remove_mapping(unsigned long vaddr)
|
int remove_mapping(unsigned long vaddr)
|
||||||
{
|
{
|
||||||
return remove_mapping_pgd(vaddr, current->pgd);
|
return remove_mapping_pgd(vaddr, TASK_PGD(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -503,7 +503,7 @@ void relocate_page_tables(void)
|
|||||||
memcpy((void *)pt_new, _start_kspace, pt_area_size);
|
memcpy((void *)pt_new, _start_kspace, pt_area_size);
|
||||||
|
|
||||||
/* Update the only reference to current pgd table */
|
/* Update the only reference to current pgd table */
|
||||||
current->pgd = (pgd_table_t *)pt_new;
|
TASK_PGD(current) = (pgd_table_t *)pt_new;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since pmd's are also moved, update the pmd references in pgd by
|
* Since pmd's are also moved, update the pmd references in pgd by
|
||||||
@@ -512,9 +512,9 @@ void relocate_page_tables(void)
|
|||||||
*/
|
*/
|
||||||
for (int i = 0; i < PGD_ENTRY_TOTAL; i++)
|
for (int i = 0; i < PGD_ENTRY_TOTAL; i++)
|
||||||
/* If there's a coarse 2nd level entry */
|
/* If there's a coarse 2nd level entry */
|
||||||
if ((current->pgd->entry[i] & PGD_TYPE_MASK)
|
if ((TASK_PGD(current)->entry[i] & PGD_TYPE_MASK)
|
||||||
== PGD_TYPE_COARSE)
|
== PGD_TYPE_COARSE)
|
||||||
current->pgd->entry[i] -= reloc_offset;
|
TASK_PGD(current)->entry[i] -= reloc_offset;
|
||||||
|
|
||||||
/* Update the pmd array pointer. */
|
/* Update the pmd array pointer. */
|
||||||
pmd_array = (pmd_table_t *)((unsigned long)_start_pmd - reloc_offset);
|
pmd_array = (pmd_table_t *)((unsigned long)_start_pmd - reloc_offset);
|
||||||
@@ -523,7 +523,7 @@ void relocate_page_tables(void)
|
|||||||
arm_clean_invalidate_cache();
|
arm_clean_invalidate_cache();
|
||||||
arm_drain_writebuffer();
|
arm_drain_writebuffer();
|
||||||
arm_invalidate_tlb();
|
arm_invalidate_tlb();
|
||||||
arm_set_ttb(virt_to_phys(current->pgd));
|
arm_set_ttb(virt_to_phys(TASK_PGD(current)));
|
||||||
arm_invalidate_tlb();
|
arm_invalidate_tlb();
|
||||||
|
|
||||||
/* Unmap the old page table area */
|
/* Unmap the old page table area */
|
||||||
@@ -535,7 +535,7 @@ void relocate_page_tables(void)
|
|||||||
__pt_end = pt_new + pt_area_size;
|
__pt_end = pt_new + pt_area_size;
|
||||||
|
|
||||||
printk("Initial page table area relocated from phys 0x%x to 0x%x\n",
|
printk("Initial page table area relocated from phys 0x%x to 0x%x\n",
|
||||||
virt_to_phys(&kspace), virt_to_phys(current->pgd));
|
virt_to_phys(&kspace), virt_to_phys(TASK_PGD(current)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -552,7 +552,7 @@ void remap_as_pages(void *vstart, void *vend)
|
|||||||
unsigned long paddr = pstart;
|
unsigned long paddr = pstart;
|
||||||
pgd_t pgd_i = PGD_INDEX(vstart);
|
pgd_t pgd_i = PGD_INDEX(vstart);
|
||||||
pmd_t pmd_i = PMD_INDEX(vstart);
|
pmd_t pmd_i = PMD_INDEX(vstart);
|
||||||
pgd_table_t *pgd = (pgd_table_t *)current->pgd;
|
pgd_table_t *pgd = (pgd_table_t *)TASK_PGD(current);
|
||||||
pmd_table_t *pmd = alloc_pmd();
|
pmd_table_t *pmd = alloc_pmd();
|
||||||
u32 pmd_phys = virt_to_phys(pmd);
|
u32 pmd_phys = virt_to_phys(pmd);
|
||||||
int numpages = __pfn(page_align_up(pend) - pstart);
|
int numpages = __pfn(page_align_up(pend) - pstart);
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ void physmem_init()
|
|||||||
/* Map initial pgd area as used */
|
/* Map initial pgd area as used */
|
||||||
start = (unsigned long)__pt_start;
|
start = (unsigned long)__pt_start;
|
||||||
end = (unsigned long)__pt_end;
|
end = (unsigned long)__pt_end;
|
||||||
set_page_map(virt_to_phys(current->pgd), __pfn(end - start), 1);
|
set_page_map(virt_to_phys(TASK_PGD(current)), __pfn(end - start), 1);
|
||||||
|
|
||||||
physmem.start = PHYS_MEM_START;
|
physmem.start = PHYS_MEM_START;
|
||||||
physmem.end = PHYS_MEM_END;
|
physmem.end = PHYS_MEM_END;
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ static inline void context_switch(struct ktcb *next)
|
|||||||
// printk("(%d) to (%d)\n", cur->tid, next->tid);
|
// printk("(%d) to (%d)\n", cur->tid, next->tid);
|
||||||
|
|
||||||
/* Flush caches and everything */
|
/* Flush caches and everything */
|
||||||
arch_hardware_flush(next->pgd);
|
arch_hardware_flush(TASK_PGD(next));
|
||||||
|
|
||||||
/* Update utcb region for next task */
|
/* Update utcb region for next task */
|
||||||
task_update_utcb(cur, next);
|
task_update_utcb(cur, next);
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ void init_locks(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct address_space pager_space;
|
||||||
|
|
||||||
/* Maps the early memory regions needed to bootstrap the system */
|
/* Maps the early memory regions needed to bootstrap the system */
|
||||||
void init_kernel_mappings(void)
|
void init_kernel_mappings(void)
|
||||||
{
|
{
|
||||||
@@ -60,7 +62,8 @@ void init_kernel_mappings(void)
|
|||||||
* Setup a dummy current ktcb over the bootstack, so that generic
|
* Setup a dummy current ktcb over the bootstack, so that generic
|
||||||
* mapping functions can use this as the pgd source.
|
* mapping functions can use this as the pgd source.
|
||||||
*/
|
*/
|
||||||
current->pgd = &kspace;
|
current->space = &pager_space;
|
||||||
|
TASK_PGD(current) = &kspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_sections(void)
|
void print_sections(void)
|
||||||
@@ -245,7 +248,7 @@ void switch_to_user(struct ktcb *task)
|
|||||||
{
|
{
|
||||||
arm_clean_invalidate_cache();
|
arm_clean_invalidate_cache();
|
||||||
arm_invalidate_tlb();
|
arm_invalidate_tlb();
|
||||||
arm_set_ttb(virt_to_phys(task->pgd));
|
arm_set_ttb(virt_to_phys(TASK_PGD(task)));
|
||||||
arm_invalidate_tlb();
|
arm_invalidate_tlb();
|
||||||
jump(task);
|
jump(task);
|
||||||
}
|
}
|
||||||
@@ -297,12 +300,7 @@ void init_pager(char *name, struct task_ids *ids)
|
|||||||
/* Pager gets first UTCB area available by default */
|
/* Pager gets first UTCB area available by default */
|
||||||
task->utcb_address = UTCB_AREA_START;
|
task->utcb_address = UTCB_AREA_START;
|
||||||
|
|
||||||
if (!task->pgd) {
|
BUG_ON(!TASK_PGD(task));
|
||||||
BUG(); /* Inittask won't come here */
|
|
||||||
task->pgd = alloc_pgd();
|
|
||||||
/* Tasks with no pgd copy from the inittask's pgd. */
|
|
||||||
memcpy(task->pgd, current->pgd, sizeof(pgd_table_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This task's userspace mapping. This should allocate a new pmd, if not
|
* This task's userspace mapping. This should allocate a new pmd, if not
|
||||||
@@ -310,7 +308,7 @@ void init_pager(char *name, struct task_ids *ids)
|
|||||||
*/
|
*/
|
||||||
add_mapping_pgd(taskimg->phys_start, INITTASK_AREA_START,
|
add_mapping_pgd(taskimg->phys_start, INITTASK_AREA_START,
|
||||||
task_pages * PAGE_SIZE, MAP_USR_DEFAULT_FLAGS,
|
task_pages * PAGE_SIZE, MAP_USR_DEFAULT_FLAGS,
|
||||||
task->pgd);
|
TASK_PGD(task));
|
||||||
printk("Mapping %d pages from 0x%x to 0x%x for %s\n", task_pages,
|
printk("Mapping %d pages from 0x%x to 0x%x for %s\n", task_pages,
|
||||||
taskimg->phys_start, INITTASK_AREA_START, name);
|
taskimg->phys_start, INITTASK_AREA_START, name);
|
||||||
|
|
||||||
@@ -359,9 +357,11 @@ void start_kernel(void)
|
|||||||
/* Initialise section mappings for the kernel area */
|
/* Initialise section mappings for the kernel area */
|
||||||
init_kernel_mappings();
|
init_kernel_mappings();
|
||||||
|
|
||||||
|
printascii("\nStarting virtual memory...\n");
|
||||||
/* Enable virtual memory and jump to virtual addresses */
|
/* Enable virtual memory and jump to virtual addresses */
|
||||||
start_vm();
|
start_vm();
|
||||||
|
|
||||||
|
printascii("\nStarted virtual memory...\n");
|
||||||
/* PMD tables initialised */
|
/* PMD tables initialised */
|
||||||
init_pmd_tables();
|
init_pmd_tables();
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ void copy_pgd_kern_by_vrange(pgd_table_t *to, pgd_table_t *from,
|
|||||||
/* Copies all standard bits that a user process should have in its pgd */
|
/* Copies all standard bits that a user process should have in its pgd */
|
||||||
void copy_pgd_kern_all(pgd_table_t *to)
|
void copy_pgd_kern_all(pgd_table_t *to)
|
||||||
{
|
{
|
||||||
pgd_table_t *from = current->pgd;
|
pgd_table_t *from = TASK_PGD(current);
|
||||||
|
|
||||||
copy_pgd_kern_by_vrange(to, from, KERNEL_AREA_START, KERNEL_AREA_END);
|
copy_pgd_kern_by_vrange(to, from, KERNEL_AREA_START, KERNEL_AREA_END);
|
||||||
copy_pgd_kern_by_vrange(to, from, IO_AREA_START, IO_AREA_END);
|
copy_pgd_kern_by_vrange(to, from, IO_AREA_START, IO_AREA_END);
|
||||||
|
|||||||
Reference in New Issue
Block a user