mirror of
https://github.com/drasko/codezero.git
synced 2026-01-14 11:53:15 +01:00
Simplified/Cleaned up pager initialization in the kernel
This commit is contained in:
@@ -47,70 +47,6 @@ void kres_insert_container(struct container *c,
|
||||
kres->containers.ncont++;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Remove completely. Need to be done in userspace.
|
||||
* This searches pager capabilities and if it has a virtual memory area
|
||||
* defined as a UTCB, uses the first entry as its utcb. If not, it is
|
||||
* not an error, perhaps another pager will map its utcb.
|
||||
*/
|
||||
void pager_init_utcb(struct ktcb *task, struct pager *pager)
|
||||
{
|
||||
struct capability *cap;
|
||||
|
||||
/* Find a virtual memory capability with UTCB map permissions */
|
||||
list_foreach_struct(cap, &pager->cap_list.caps, list) {
|
||||
if (cap_rtype(cap) == CAP_RTYPE_VIRTMEM &&
|
||||
cap->access & CAP_MAP_UTCB) {
|
||||
/* Use first address slot as pager's utcb */
|
||||
task->utcb_address = __pfn_to_addr(cap->start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* NOTE: This is not useful because FP stores references to
|
||||
* old stack so even if stacks are copied, unwinding is not
|
||||
* possible, which makes copying pointless. If there was no
|
||||
* FP, it may make sense, but this is not tested.
|
||||
*
|
||||
* Copy current stack contents to new one,
|
||||
* and jump to that stack by modifying sp and frame pointer.
|
||||
*/
|
||||
int switch_stacks(struct ktcb *task)
|
||||
{
|
||||
volatile register unsigned int stack asm("sp");
|
||||
volatile register unsigned int frameptr asm("fp");
|
||||
volatile register unsigned int newstack;
|
||||
unsigned int stack_size = (unsigned int)_bootstack - stack;
|
||||
|
||||
newstack = align((unsigned long)task + PAGE_SIZE - 1,
|
||||
STACK_ALIGNMENT);
|
||||
|
||||
/* Copy stack contents to new stack */
|
||||
memcpy((void *)(newstack - stack_size),
|
||||
(void *)stack, stack_size);
|
||||
|
||||
/*
|
||||
* Switch to new stack, as new stack
|
||||
* minus currently used stack size
|
||||
*/
|
||||
stack = newstack - stack_size;
|
||||
|
||||
/*
|
||||
* Frame ptr is new stack minus the original
|
||||
* difference from start of boot stack to current fptr
|
||||
*/
|
||||
frameptr = newstack -
|
||||
((unsigned int)_bootstack - frameptr);
|
||||
|
||||
/* We should be able to return safely */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
@@ -120,48 +56,57 @@ int switch_stacks(struct ktcb *task)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inspects pager parameters defined in the container,
|
||||
* and sets up an execution environment for the pager.
|
||||
*
|
||||
* This involves setting up pager's ktcb, space, utcb,
|
||||
* all ids, registers, and mapping its (perhaps) first
|
||||
* few pages in order to make it runnable.
|
||||
*
|
||||
* The first pager initialization is a special-case
|
||||
* since it uses the current kernel pgd.
|
||||
*/
|
||||
int init_first_pager(struct pager *pager,
|
||||
int init_pager(struct pager *pager,
|
||||
struct container *cont,
|
||||
pgd_table_t *current_pgd)
|
||||
{
|
||||
struct ktcb *task;
|
||||
struct address_space *space;
|
||||
int first = !!current_pgd;
|
||||
|
||||
/*
|
||||
* Initialize dummy current capability list pointer
|
||||
* so that capability accounting can be done as normal
|
||||
*
|
||||
* FYI: We're still on bootstack instead of current's
|
||||
* real stack. Hence this is a dummy.
|
||||
*/
|
||||
current->cap_list_ptr = &pager->cap_list;
|
||||
|
||||
/*
|
||||
* Find capability from pager's list, since
|
||||
* there is no ktcb, no standard path to check
|
||||
* per-task capability list yet.
|
||||
*/
|
||||
/* Use it to allocate ktcb */
|
||||
/* New ktcb allocation is needed */
|
||||
task = tcb_alloc_init();
|
||||
|
||||
/* If first, manually allocate/initalize space */
|
||||
if (first) {
|
||||
if (!(space = alloc_space())) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Set up space id */
|
||||
space->spid = id_new(&kernel_resources.space_ids);
|
||||
|
||||
/* Initialize space structure */
|
||||
link_init(&space->list);
|
||||
mutex_init(&space->lock);
|
||||
space->pgd = current_pgd;
|
||||
address_space_attach(task, space);
|
||||
} else {
|
||||
/* Otherwise allocate conventionally */
|
||||
task->space = address_space_create(0);
|
||||
}
|
||||
|
||||
/* Initialize ktcb */
|
||||
task_init_registers(task, pager->start_vma);
|
||||
|
||||
pager_init_utcb(task, pager);
|
||||
|
||||
/* Allocate space structure */
|
||||
if (!(space = alloc_space()))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Set up space id */
|
||||
space->spid = id_new(&kernel_resources.space_ids);
|
||||
|
||||
/* Initialize space structure */
|
||||
link_init(&space->list);
|
||||
mutex_init(&space->lock);
|
||||
space->pgd = current_pgd;
|
||||
address_space_attach(task, space);
|
||||
|
||||
/* Initialize container/pager relationships */
|
||||
pager->tcb = task;
|
||||
task->pager = pager;
|
||||
@@ -192,64 +137,6 @@ int init_first_pager(struct pager *pager,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inspects pager parameters defined in the container,
|
||||
* and sets up an execution environment for the pager.
|
||||
*
|
||||
* This involves setting up pager's ktcb, space, utcb,
|
||||
* all ids, registers, and mapping its (perhaps) first
|
||||
* few pages in order to make it runnable.
|
||||
*/
|
||||
int init_pager(struct pager *pager, struct container *cont)
|
||||
{
|
||||
struct ktcb *task;
|
||||
|
||||
/*
|
||||
* Initialize dummy current capability list pointer
|
||||
* so that capability accounting can be done as normal
|
||||
* FYI: We're still on bootstack instead of current's
|
||||
* real stack. Hence this is a dummy.
|
||||
*/
|
||||
current->cap_list_ptr = &pager->cap_list;
|
||||
|
||||
/* Use it to allocate ktcb */
|
||||
task = tcb_alloc_init();
|
||||
|
||||
task_init_registers(task, pager->start_vma);
|
||||
|
||||
pager_init_utcb(task, pager);
|
||||
|
||||
task->space = address_space_create(0);
|
||||
|
||||
/* Initialize container/pager relationships */
|
||||
pager->tcb = task;
|
||||
task->pager = pager;
|
||||
task->container = cont;
|
||||
task->pagerid = task->tid;
|
||||
|
||||
task->cap_list_ptr = &pager->cap_list;
|
||||
|
||||
printk("%s: Mapping %lu pages from 0x%lx to 0x%lx for %s\n",
|
||||
__KERNELNAME__, __pfn(page_align_up(pager->memsize)),
|
||||
pager->start_lma, pager->start_vma, cont->name);
|
||||
|
||||
add_mapping_pgd(pager->start_lma, pager->start_vma,
|
||||
page_align_up(pager->memsize),
|
||||
MAP_USR_DEFAULT_FLAGS, TASK_PGD(task));
|
||||
|
||||
/* Initialize task scheduler parameters */
|
||||
sched_init_task(task, TASK_PRIO_PAGER);
|
||||
|
||||
/* Give it a kick-start tick and make runnable */
|
||||
task->ticks_left = 1;
|
||||
sched_resume_async(task);
|
||||
|
||||
/* Container list that keeps all tasks */
|
||||
tcb_add(task);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize all containers with their initial set of tasks,
|
||||
* spaces, scheduler parameters such that they can be started.
|
||||
@@ -259,19 +146,16 @@ int container_init_pagers(struct kernel_resources *kres,
|
||||
{
|
||||
struct container *cont;
|
||||
struct pager *pager;
|
||||
int pgidx = 0;
|
||||
|
||||
list_foreach_struct(cont, &kres->containers.list, list) {
|
||||
for (int i = 0; i < cont->npagers; i++) {
|
||||
pager = &cont->pager[i];
|
||||
|
||||
/* First pager initializes specially */
|
||||
if (pgidx == 0)
|
||||
init_first_pager(pager, cont,
|
||||
current_pgd);
|
||||
if (i == 0)
|
||||
init_pager(pager, cont, current_pgd);
|
||||
else
|
||||
init_pager(pager, cont);
|
||||
pgidx++;
|
||||
init_pager(pager, cont, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -477,17 +477,6 @@ int copy_container_info(struct container *c, struct container_info *cinfo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* Rearrange as follows:
|
||||
* 1.) Move realloc_page_tables to before container_init_pagers()
|
||||
* 2.) Set up dummy current cap_list_ptr right after real capability list
|
||||
* has been created. -> Think! since there are many containers!!!!!!!
|
||||
* 3.) At this point, no need to do alloc_boot_pmd(), and current->cap_list_ptr
|
||||
* is valid, so no custom alloc functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create real containers from compile-time created cinfo structures
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user