mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01: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_PAGE 0xA
|
||||
|
||||
#define TASK_PGD(x) (x)->space->pgd
|
||||
|
||||
/* Kernel's data about the fault */
|
||||
typedef struct fault_kdata {
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
#define MAP_IO_DEFAULT_FLAGS MAP_SVC_IO_FLAGS
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <l4/lib/mutex.h>
|
||||
#include <l4/generic/scheduler.h>
|
||||
#include <l4/generic/pgalloc.h>
|
||||
#include <l4/generic/space.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_GLUE(syscall.h)
|
||||
#include INC_GLUE(message.h)
|
||||
@@ -39,12 +40,6 @@ struct task_ids {
|
||||
l4id_t tgid;
|
||||
};
|
||||
|
||||
/* A simple page table with a reference count */
|
||||
struct address_space {
|
||||
struct pgd_table_t *pgd;
|
||||
int ktcb_refs;
|
||||
};
|
||||
|
||||
struct ktcb {
|
||||
/* User context */
|
||||
task_context_t context;
|
||||
|
||||
@@ -36,7 +36,7 @@ int sys_map(syscall_context_t *regs)
|
||||
return -EINVAL;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ int sys_unmap(syscall_context_t *regs)
|
||||
return -ESRCH;
|
||||
|
||||
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)
|
||||
retval = ret;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ int arch_clear_thread(struct ktcb *task)
|
||||
task->context.spsr = ARM_MODE_USR;
|
||||
|
||||
/* Clear the page tables */
|
||||
remove_mapping_pgd_all_user(task->pgd);
|
||||
remove_mapping_pgd_all_user(TASK_PGD(task));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -256,12 +256,6 @@ int thread_setup_new_ids(struct task_ids *ids, unsigned int flags,
|
||||
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,
|
||||
* 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 */
|
||||
if (create_flags == THREAD_NEW_SPACE) {
|
||||
/* Allocate new pgd and copy all kernel areas */
|
||||
if (!(new->pgd = alloc_pgd())) {
|
||||
if (!(TASK_PGD(new) = alloc_pgd())) {
|
||||
free_page(new);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
copy_pgd_kern_all(new->pgd);
|
||||
copy_pgd_kern_all(TASK_PGD(new));
|
||||
} else {
|
||||
/* Existing space will be used, find it from all tasks */
|
||||
list_for_each_entry(task, &global_task_list, task_list) {
|
||||
/* Space ids match, can use existing space */
|
||||
if (task->spid == ids->spid) {
|
||||
if (flags == THREAD_SAME_SPACE) {
|
||||
new->pgd = task->pgd;
|
||||
TASK_PGD(new) = TASK_PGD(task);
|
||||
} else {
|
||||
new->pgd = copy_page_tables(task->pgd);
|
||||
if (IS_ERR(new->pgd)) {
|
||||
err = (int)new->pgd;
|
||||
TASK_PGD(new) = copy_page_tables(TASK_PGD(task));
|
||||
if (IS_ERR(TASK_PGD(new))) {
|
||||
err = (int)TASK_PGD(new);
|
||||
free_page(new);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
*/
|
||||
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);
|
||||
if (!((pgd->entry[pgd_i] & PGD_TYPE_MASK)
|
||||
& 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. */
|
||||
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)
|
||||
@@ -238,7 +238,7 @@ void add_mapping_pgd(unsigned int paddr, unsigned int vaddr,
|
||||
void add_mapping(unsigned int paddr, unsigned int vaddr,
|
||||
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,
|
||||
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 !!! */
|
||||
@@ -416,7 +416,7 @@ int remove_mapping_pgd(unsigned long vaddr, pgd_table_t *pgd)
|
||||
|
||||
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);
|
||||
|
||||
/* 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
|
||||
@@ -512,9 +512,9 @@ void relocate_page_tables(void)
|
||||
*/
|
||||
for (int i = 0; i < PGD_ENTRY_TOTAL; i++)
|
||||
/* 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)
|
||||
current->pgd->entry[i] -= reloc_offset;
|
||||
TASK_PGD(current)->entry[i] -= reloc_offset;
|
||||
|
||||
/* Update the pmd array pointer. */
|
||||
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_drain_writebuffer();
|
||||
arm_invalidate_tlb();
|
||||
arm_set_ttb(virt_to_phys(current->pgd));
|
||||
arm_set_ttb(virt_to_phys(TASK_PGD(current)));
|
||||
arm_invalidate_tlb();
|
||||
|
||||
/* Unmap the old page table area */
|
||||
@@ -535,7 +535,7 @@ void relocate_page_tables(void)
|
||||
__pt_end = pt_new + pt_area_size;
|
||||
|
||||
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;
|
||||
pgd_t pgd_i = PGD_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();
|
||||
u32 pmd_phys = virt_to_phys(pmd);
|
||||
int numpages = __pfn(page_align_up(pend) - pstart);
|
||||
|
||||
@@ -76,7 +76,7 @@ void physmem_init()
|
||||
/* Map initial pgd area as used */
|
||||
start = (unsigned long)__pt_start;
|
||||
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.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);
|
||||
|
||||
/* Flush caches and everything */
|
||||
arch_hardware_flush(next->pgd);
|
||||
arch_hardware_flush(TASK_PGD(next));
|
||||
|
||||
/* Update utcb region for next task */
|
||||
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 */
|
||||
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
|
||||
* mapping functions can use this as the pgd source.
|
||||
*/
|
||||
current->pgd = &kspace;
|
||||
current->space = &pager_space;
|
||||
TASK_PGD(current) = &kspace;
|
||||
}
|
||||
|
||||
void print_sections(void)
|
||||
@@ -245,7 +248,7 @@ void switch_to_user(struct ktcb *task)
|
||||
{
|
||||
arm_clean_invalidate_cache();
|
||||
arm_invalidate_tlb();
|
||||
arm_set_ttb(virt_to_phys(task->pgd));
|
||||
arm_set_ttb(virt_to_phys(TASK_PGD(task)));
|
||||
arm_invalidate_tlb();
|
||||
jump(task);
|
||||
}
|
||||
@@ -297,12 +300,7 @@ void init_pager(char *name, struct task_ids *ids)
|
||||
/* Pager gets first UTCB area available by default */
|
||||
task->utcb_address = UTCB_AREA_START;
|
||||
|
||||
if (!task->pgd) {
|
||||
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));
|
||||
}
|
||||
BUG_ON(!TASK_PGD(task));
|
||||
|
||||
/*
|
||||
* 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,
|
||||
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,
|
||||
taskimg->phys_start, INITTASK_AREA_START, name);
|
||||
|
||||
@@ -359,9 +357,11 @@ void start_kernel(void)
|
||||
/* Initialise section mappings for the kernel area */
|
||||
init_kernel_mappings();
|
||||
|
||||
printascii("\nStarting virtual memory...\n");
|
||||
/* Enable virtual memory and jump to virtual addresses */
|
||||
start_vm();
|
||||
|
||||
printascii("\nStarted virtual memory...\n");
|
||||
/* PMD tables initialised */
|
||||
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 */
|
||||
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, IO_AREA_START, IO_AREA_END);
|
||||
|
||||
Reference in New Issue
Block a user