2020-07-25 16:54:37 -05:00
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
*/
|
|
|
|
|
2020-07-22 19:54:33 -05:00
|
|
|
#include "../../tasking.h"
|
|
|
|
#include "../paging.h"
|
|
|
|
#include "../tasking_helpers.h"
|
2020-07-23 06:41:18 -05:00
|
|
|
#include "../../pmem.h"
|
2020-07-23 11:50:23 -05:00
|
|
|
#include <stddef.h>
|
2020-07-22 19:54:33 -05:00
|
|
|
|
2020-07-25 16:54:37 -05:00
|
|
|
static void** kstacks=(void*)0xC8000000; //!< Pointer to all the thread kernel stacks
|
|
|
|
static char kstack_bmap[(218*1024)/8]={0}; //!< Bitmap of what kernel stacks have been allocated
|
2020-07-23 06:41:18 -05:00
|
|
|
|
2020-07-25 16:54:37 -05:00
|
|
|
/**
|
|
|
|
* Check whether a kernel stack is allocated
|
|
|
|
* \param index The kernel stack to check
|
|
|
|
* \return whether the kernel stack is allocated
|
|
|
|
*/
|
|
|
|
static char is_kstack_allocated(size_t index) {
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t byte=index/8;
|
|
|
|
size_t bit=index%8;
|
2020-07-23 06:41:18 -05:00
|
|
|
char entry=kstack_bmap[byte];
|
|
|
|
return (entry&(1<<bit))>0;
|
|
|
|
}
|
|
|
|
|
2020-07-25 16:54:37 -05:00
|
|
|
/**
|
|
|
|
* Mark that a kernel stack is allocated
|
|
|
|
* \param index The kernel stack to mark
|
|
|
|
*/
|
|
|
|
static void mark_kstack_allocated(size_t index) {
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t byte=index/8;
|
|
|
|
size_t bit=index%8;
|
2020-07-23 06:41:18 -05:00
|
|
|
kstack_bmap[byte]=kstack_bmap[byte]|(1<<bit);
|
|
|
|
}
|
|
|
|
|
2020-07-25 16:54:37 -05:00
|
|
|
/**
|
|
|
|
* Allocate a kernel stack for a thread
|
|
|
|
* \return The number of the new kernel stack, or -1 if none are unallocated.
|
|
|
|
*/
|
|
|
|
static int new_kstack() {
|
2020-07-23 06:41:18 -05:00
|
|
|
int num=-1;
|
|
|
|
for (int i=0;i<(218*1024);i++) {
|
2020-07-25 16:54:37 -05:00
|
|
|
if (is_kstack_allocated(i)==0) {
|
2020-07-23 06:41:18 -05:00
|
|
|
num=i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (num==-1) {
|
|
|
|
return -1;
|
|
|
|
}
|
2020-07-25 16:54:37 -05:00
|
|
|
mark_kstack_allocated(num);
|
2020-07-23 06:41:18 -05:00
|
|
|
map_pages(((char*)kstacks+num*0x1000),pmem_alloc(1),1,1,1);
|
|
|
|
return num;
|
|
|
|
}
|
2020-07-22 19:54:33 -05:00
|
|
|
|
2020-07-23 11:50:23 -05:00
|
|
|
void setup_kstack(Thread* thread,void* param1,void* param2,char kmode,void* eip) {
|
|
|
|
size_t kstack_num=new_kstack();
|
2020-07-22 19:54:33 -05:00
|
|
|
if (kmode) {
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t top_idx=(1024*(kstack_num+1));
|
|
|
|
thread->kernel_esp=((void*)(&kstacks[top_idx-5]));
|
2020-07-22 19:54:33 -05:00
|
|
|
thread->kernel_esp_top=thread->kernel_esp;
|
2020-07-23 11:50:23 -05:00
|
|
|
kstacks[top_idx-1]=(void*)eip;
|
2020-07-22 19:54:33 -05:00
|
|
|
} else {
|
2020-07-23 11:50:23 -05:00
|
|
|
size_t top_idx=(1024*(kstack_num+1));
|
|
|
|
thread->kernel_esp=((void*)(&kstacks[top_idx-7]));
|
2020-07-22 19:54:33 -05:00
|
|
|
thread->kernel_esp_top=thread->kernel_esp;
|
2020-07-29 08:58:45 -05:00
|
|
|
void** user_stack;
|
|
|
|
RUN_IN_ADDRESS_SPACE(thread->address_space,{
|
|
|
|
user_stack=(void**)(((char*)alloc_pages(2))+0x2000);
|
|
|
|
user_stack-=2;
|
|
|
|
user_stack[0]=param1;
|
|
|
|
user_stack[1]=param2;
|
|
|
|
});
|
2020-07-23 11:50:23 -05:00
|
|
|
kstacks[top_idx-3]=(void*)task_init;
|
|
|
|
kstacks[top_idx-2]=(void*)user_stack;
|
|
|
|
kstacks[top_idx-1]=(void*)eip;
|
2020-07-22 19:54:33 -05:00
|
|
|
}
|
|
|
|
}
|