#include "memory.h" #include "process.h" #include "irq.h" #include "fileobj.h" // AMS linkage void lowlevel_yield(); unsigned short last_pid = 0; struct context *cur_cx; struct context kernel_cx; struct process_item *cur_proc; int num_yielding = 0; int num_processes = 0; void context_init(struct context *cx) { memset(cx, 0, sizeof(struct context)); cx->pd = create_pd(); cx->valloc_addr = (unsigned int)VIRTUAL_HEAP_START; cx->heap_top = (unsigned int)VIRTUAL_HEAP_START; // start at 1GB mark } void switch_context(struct context *cx) { cur_cx = cx; set_cr3(cur_cx->pd); } void switch_process(struct process_item *proc) { cur_proc = proc; to_process_context(); } void to_kernel_context() { switch_context(&kernel_cx); } void to_process_context() { switch_context(&cur_proc->cx); } void next_process() { cur_proc->timeleft = cur_proc->timeslice; // do { switch_process(cur_proc->next); // } while (cur_proc->timeleft == 0); // printf(" * "); } // Cooperative multitasking inside kernel // kernel_yield() should be called while waiting for IO etc void kernel_yield() { num_yielding++; // printf("%d %d\n", num_yielding, num_processes); lowlevel_yield(); num_yielding--; } // Timer interrupt void interrupt_32() { if (--cur_proc->timeleft <= 0) { next_process(); } ACK_MASTER_IRQ; } int food = 3; void sys_next_process() { switch_process(cur_proc->next); } void sys_exit() { } /*%macro push_regs 0 pusha ; EAX, ECX, EDX, EBX, ESP, EBP, ESI and EDI push gs push fs push es push ds %endmacro*/ void process_init(struct process_item *proc, unsigned int entry) { memset(proc, 0, sizeof(struct process_item)); proc->timeleft = proc->timeslice = 1; proc->entry = entry; proc->pid = ++last_pid; proc->owner = 0; } void internal_init_process(struct process_item *proc) { proc->timeleft = proc->timeslice = 10; // Process stack starts at right below PD proc->cx.esp = 0xFFFFFFFF - (1024 * 4096); // Switch to the process PD for a while to create and init the stack switch_context(&proc->cx); // Some stack space void *stack = alloc_page(); map_page(stack, (void *)(0xFFFFFFFF - (1024 * 4096) - 4096 + 1)); unsigned int *esp = (unsigned int *)proc->cx.esp; // Init stack (these are for iret) *--esp = 0x0202; // flags *--esp = 0x08; // code segment // *--esp = 0x18; // user code segment *--esp = proc->entry; // eip (entry point) // (mimic push_regs) *--esp = 0x00; // eax *--esp = 0x00; // ecx *--esp = 0x00; // edx *--esp = 0x00; // ebx *--esp = proc->cx.esp; // esp *--esp = 0x00; // ebp *--esp = 0x00; // esi *--esp = 0x00; // edi *--esp = 0x10; // gs *--esp = 0x10; // fd *--esp = 0x10; // es *--esp = 0x10; // ds proc->cx.esp = (unsigned int)esp; // Allocate some space on the heap for the process struct proc->proc = (struct process *)kmalloc(sizeof(struct process)); memset(&proc->proc->fd_table, 0, sizeof(struct file_object *) * 10); proc->proc->n_fds = 0; // Switch back to current PD switch_context(cur_cx); } /*void shoop(int da_woop) { int lazorz; printf("Imma firing my 0x%x\n", lazorz); }*/ void sys_start_process(struct process_item *proc) { printf("Hajimemashite, SUTAATO PUROSESSU desu~!\n"); // shoop(123); context_init(&proc->cx); // sti(); internal_init_process(proc); // cli(); // printf("Um...\n"); // if (food++ > 0) { panic("Halt!"); } proc->next = cur_proc->next; proc->prev = cur_proc; cur_proc->next->prev = proc; cur_proc->next = proc; num_processes++; } void sys_kill_process(struct process_item *proc) { printf("This would kill a process but... no."); }