210 lines
5.2 KiB
C++
210 lines
5.2 KiB
C++
// proc.c
|
|
// Author: Josh Holtrop
|
|
// Date; 08/18/05
|
|
// Modified: 08/18/05
|
|
|
|
#define __HOS_CPP__
|
|
|
|
extern "C" {
|
|
|
|
#include "hos_defines.h"
|
|
#include "mm/mm.h"
|
|
#include "mm/vmm.h"
|
|
#include "lang/lang.h"
|
|
#include "kernel.h"
|
|
#include "functions.h" //halt()
|
|
|
|
#include "display/kout.h"
|
|
|
|
extern u32_t mm_freepages;
|
|
|
|
}
|
|
|
|
#include "proc.h"
|
|
#include "proc/hash.h"
|
|
|
|
extern "C" {
|
|
u32_t cur_task = 0;
|
|
u32_t n_processes = 0;
|
|
tss_t tss0;
|
|
}
|
|
|
|
hash *processes;
|
|
|
|
int proc_init()
|
|
{
|
|
/* initialize tss0 */
|
|
memset(&tss0, 0, sizeof(tss_t));
|
|
tss0.ss0 = SEG_KERNEL_DATA;
|
|
tss0.esp0 = VIRT_STACK_TOP;
|
|
kprintf("make new hash\n");
|
|
processes = new hash();
|
|
vector< vector<int> > test;
|
|
for (u32_t i = 0; i < 5; i++)
|
|
test.add(vector<int>());
|
|
for (u32_t i = 0; i < 5; i++)
|
|
for (u32_t j = 0; j < 3; j++)
|
|
test[i].add(i*10+j);
|
|
for (u32_t i = 0; i < 5; i++)
|
|
for (u32_t j = 0; j < 3; j++)
|
|
kprintf("<%d>", test[i][j]);
|
|
for (u32_t i = 0; i < 11; i++)
|
|
{
|
|
kprintf("add %d to hash\n", i);
|
|
processes->add(i, (void *) i);
|
|
}
|
|
kprintf("\n\n");
|
|
processes->dump();
|
|
kprintf("\n\n");
|
|
for (u32_t i = 0; i < 11; i++)
|
|
{
|
|
kprintf("get %d from hash\n", i);
|
|
if (i != (u32_t)processes->get(i))
|
|
kprintf(" !=: %d -> %d\n", i, processes->get(i));
|
|
processes->remove(i);
|
|
}
|
|
kprintf("size: %d\n", processes->size());
|
|
|
|
return 0;
|
|
}
|
|
|
|
void proc_sched(int_stack_t *int_stack)
|
|
{
|
|
|
|
}
|
|
|
|
void switch_task(int_stack_t *int_stack, u32_t new_task)
|
|
{
|
|
// memcpy((*processes)[cur_task]->int_stack, int_stack, sizeof(int_stack_t));
|
|
cur_task = new_task;
|
|
// memcpy(int_stack, (*processes)[cur_task]->int_stack, sizeof(int_stack_t));
|
|
// write_cr3((*processes)[cur_task]->p_page_dir);
|
|
}
|
|
|
|
u32_t create_task(void *base, u32_t image_size, u32_t bss_size, void *entry)
|
|
{
|
|
u32_t pid;
|
|
// processes[++n_processes] = create_process(base, image_size, bss_size, entry);
|
|
return pid;
|
|
}
|
|
|
|
/* Create process_t struct for a new process
|
|
* image_size should be a multiple of 4096
|
|
*/
|
|
process_t *create_process(void *base, u32_t image_size, u32_t bss_size, void *entry)
|
|
{
|
|
if (mm_freepages < ((image_size + bss_size) >> 12) + 25)
|
|
return 0;
|
|
process_t *process = (process_t *) New(process_t); /* Allocate process_t struct */
|
|
create_address_space(process);
|
|
create_process_stack(process, entry);
|
|
int i;
|
|
u32_t *ptr32 = process->v_page_dir = (u32_t *) vmm_palloc();
|
|
for (i = 0; i < 1024; i++)
|
|
*ptr32++ = 0;
|
|
u32_t code_data_pages = (image_size + 4095) >> 12;
|
|
u32_t bss_pages = (bss_size + 4095) >> 12;
|
|
/* Load program at address 0 */
|
|
copy_into_address_space(0, (char *) base, code_data_pages, process);
|
|
zero_address_space(code_data_pages << 12, bss_pages, process);
|
|
ptr32 = process->v_page_dir;
|
|
for (i = 0; i < 1024; i++)
|
|
if (*ptr32)
|
|
vmm_unmapp((void *)*ptr32);
|
|
vmm_unmapp(process->v_page_dir);
|
|
process->v_page_dir = 0;
|
|
process->size = image_size + bss_size;
|
|
return process;
|
|
}
|
|
|
|
void create_address_space(process_t *p)
|
|
{
|
|
/* Allocate a new page directory */
|
|
p->page_dir = (u32_t *) vmm_palloc_addr(&p->p_page_dir);
|
|
int i;
|
|
u32_t *ptr32 = p->page_dir;
|
|
for (i = 0; i < 768; i++) /* zero 3 gigs */
|
|
*ptr32++ = 0;
|
|
memcpyd(ptr32, (void *)0xFFFFFC00, 256); /* 1 gig kernel mem */
|
|
}
|
|
|
|
void create_process_stack(process_t *p, void *entry)
|
|
{
|
|
u32_t p_stack_table, p_stack;
|
|
u32_t *v_stack_table = (u32_t *) vmm_palloc_addr(&p_stack_table);
|
|
u32_t *v_stack = (u32_t *) vmm_palloc_addr(&p_stack);
|
|
int i;
|
|
u32_t *ptr32 = v_stack_table;
|
|
for (i = 0; i < 1023; i++)
|
|
*ptr32++ = 0;
|
|
v_stack_table[1023] = p_stack | 0x7; /* user permissions */
|
|
p->page_dir[511] = p_stack_table | 0x7; /* stack at 2GB */
|
|
vmm_unmapp(v_stack_table);
|
|
vmm_unmapp(v_stack);
|
|
p->int_stack.ds = SEG_USER_DATA | 0x3;
|
|
p->int_stack.es = SEG_USER_DATA | 0x3;
|
|
p->int_stack.fs = SEG_USER_DATA | 0x3;
|
|
p->int_stack.gs = SEG_USER_DATA | 0x3;
|
|
p->int_stack.ss = SEG_USER_DATA | 0x3;
|
|
p->int_stack.esp = 0x20000000;
|
|
p->int_stack.eflags = 0x0202;
|
|
p->int_stack.cs = SEG_USER_CODE | 0x3;
|
|
p->int_stack.eip = (u32_t)entry;
|
|
}
|
|
|
|
/* Copy pages into new address space (v_page_dir must be set up) */
|
|
void copy_into_address_space(u32_t dest_addr,
|
|
char *src_addr,
|
|
u32_t pages,
|
|
process_t *p)
|
|
{
|
|
u32_t pde, pte;
|
|
void *page;
|
|
while (pages)
|
|
{
|
|
pde = dest_addr >> 22;
|
|
pte = (dest_addr >> 12) & 0x3FF;
|
|
u32_t p_page_addr;
|
|
if (!p->v_page_dir[pde])
|
|
{
|
|
/* Time for a new page table & page directory entry! */
|
|
p->v_page_dir[pde] = (u32_t)vmm_palloc_addr(&p_page_addr);
|
|
p->page_dir[pde] = p_page_addr | 0x7;
|
|
}
|
|
page = vmm_palloc_addr(&p_page_addr);
|
|
((u32_t *)(p->v_page_dir[pde]))[pte] = p_page_addr | 0x7;
|
|
memcpyd(page, src_addr, 1024);
|
|
vmm_unmapp(page);
|
|
dest_addr += 4096;
|
|
src_addr += 4096;
|
|
pages--;
|
|
}
|
|
}
|
|
|
|
/* Zeros pages into new address space (v_page_dir must be set up) */
|
|
void zero_address_space(u32_t dest_addr, u32_t pages, process_t *p)
|
|
{
|
|
u32_t pde, pte;
|
|
void *page;
|
|
while (pages)
|
|
{
|
|
pde = dest_addr >> 22;
|
|
pte = (dest_addr >> 12) & 0x3FF;
|
|
u32_t p_page_addr;
|
|
if (!p->v_page_dir[pde])
|
|
{
|
|
/* Time for a new page table & page directory entry! */
|
|
p->v_page_dir[pde] = (u32_t)vmm_palloc_addr(&p_page_addr);
|
|
p->page_dir[pde] = p_page_addr | 0x7;
|
|
vmm_unmapp((void *)p->v_page_dir[pde]);
|
|
}
|
|
page = vmm_palloc_addr(&p_page_addr);
|
|
((u32_t *)(p->v_page_dir[pde]))[pte] = p_page_addr | 0x7;
|
|
memsetd(page, 0, 1024);
|
|
vmm_unmapp(page);
|
|
dest_addr += 4096;
|
|
pages--;
|
|
}
|
|
}
|
|
|