diff --git a/include/cpu.h b/include/cpu.h index 0b2c3c5..4229b91 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -43,4 +43,4 @@ bool cansetflag(u32 flag); void cpuid(u32 op, u32 * eax, u32 * ebx, u32 * ecx, u32 * edx); u8 getcpuinfos(cpuinfo * inf); void show_cpu(regs * stack); -void cpuerror(const u8 * src, const regs * stack, bool returnto); +void cpuerror(const u8 * src, const regs * dump, bool returnto); diff --git a/include/interrupts.h b/include/interrupts.h index 91561ae..2a74f5d 100644 --- a/include/interrupts.h +++ b/include/interrupts.h @@ -249,33 +249,62 @@ lors d'un iret en mode kernel: /* save pile */ typedef struct regs { - u64 efer; - u32 dr7; - u32 dr6; - u32 dr3; - u32 dr2; - u32 dr1; - u32 dr0; - u32 cr4; - u32 cr3; - u32 cr2; - u32 cr0; - u32 ebp; - u32 edi; - u32 esi; - u32 edx; - u32 ecx; - u32 ebx; - u32 eax; - u32 gs; - u32 fs; - u32 es; - u32 ds; - u32 eip; - u32 cs; - u32 eflags; - u32 esp; - u32 ss; + union { + struct { + u64 efer; + u32 dr7; + u32 dr6; + u32 dr3; + u32 dr2; + u32 dr1; + u32 dr0; + u32 cr4; + u32 cr3; + u32 cr2; + u32 cr0; + u32 ebp; + u32 edi; + u32 esi; + u32 edx; + u32 ecx; + u32 ebx; + u32 eax; + u32 gs; + u32 fs; + u32 es; + u32 ds; + u32 eip; + u32 cs; + u32 eflags; + u32 esp; + u32 ss; + }; + struct { + u32 efer_low, efer_high; + u32 dummy[13*sizeof(u32)]; + u16 dx,hdx; + u16 cx,hcx; + u16 bx,hbx; + u16 ax,hax; + u16 gsl,dummy_gs; + u16 fsl,dummy_fs; + u16 esl,dummy_es; + u16 dsl,dummy_ds; + u16 ip,hip; + u16 csl,dummy_cs; + u16 flags,hflags; + u16 sp,hsp; + u16 ssl,dummy_ss; + }; + struct { + u64 dummy2; + u32 dummy3[13*sizeof(u32)]; + u8 dl,dh,dx2,hdx2; + u8 cl,ch,cx2,hcx2; + u8 bl,bh,bx2,hbx2; + u8 al,ah,ax2,hax2; + }; + } } regs __attribute__ ((packed)); /* exception pile depuis code kernel*/ diff --git a/lib/cpu.c b/lib/cpu.c index 1df9d15..fa5ab47 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -7,6 +7,7 @@ #include "string.h" #include "asm.h" #include "gdt.h" +#include "process.h" /* Technologies supportées */ @@ -36,11 +37,18 @@ static u8 space[] = " "; /******************************************************************************/ /* Affiche une erreur CPU et fige l'ordinateur */ -void cpuerror(const u8 * src, const regs * stack, bool returnto) +void cpuerror(const u8 * src, const regs * dump, bool returnto) { - printf("\033[31m*** ERREUR CPU : %s *** \r\n", src); - if (stack != NULL) - show_cpu(stack); + process *aprocess=findcurrentprocess(); + if (!aprocess->iskernel && !returnto) + { + printf("\033[31m*** ERREUR CPU, KILLING PROCESS %u : %s *** \r\n", aprocess->pid, src); + deleteprocess(aprocess->pid); + } + else + printf("\033[31m*** ERREUR CPU : %s *** \r\n", src); + if (dump != NULL) + show_cpu(dump); print("\033[0m\r\n"); sti(); waitascii(); diff --git a/lib/handlers.c b/lib/handlers.c index c866a98..1768433 100644 --- a/lib/handlers.c +++ b/lib/handlers.c @@ -19,13 +19,13 @@ __attribute__ ((noreturn)) void interruption_handler(regs *dump) u32 interruption=dump->eip; exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1); bool noerror,user; - if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE) + if ((caller->cs & 0xFFF8)==SEL_KERNEL_CODE || (caller->cs & 0xFFF8)==SEL_USER_CODE) { noerror=true; dump->eip = caller->eip; dump->cs = caller->cs; dump->eflags = caller->eflags; - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { dump->esp = (u32) caller + sizeof(exception_stack_noerror); user=false; @@ -42,7 +42,7 @@ __attribute__ ((noreturn)) void interruption_handler(regs *dump) noerror=false; dump->eip = ((exception_stack*)caller)->eip; dump->cs = ((exception_stack*)caller)->cs; - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { dump->esp = (u32) caller + sizeof(exception_stack); user=false; @@ -62,7 +62,7 @@ __attribute__ ((noreturn)) void interruption_handler(regs *dump) default: print("Appel d'une interruption\r\n"); } - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { setESP(dump); restcpu_kernel(); @@ -104,13 +104,13 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump) u32 exception=dump->eip; exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1); bool noerror,user; - if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE) + if ((caller->cs & 0xFFF8)==SEL_KERNEL_CODE || (caller->cs & 0xFFF8)==SEL_USER_CODE) { noerror=true; dump->eip = caller->eip; dump->cs = caller->cs; dump->eflags = caller->eflags; - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { dump->esp = (u32) caller + sizeof(exception_stack_noerror); user=false; @@ -127,7 +127,7 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump) noerror=false; dump->eip = ((exception_stack*)caller)->eip; dump->cs = ((exception_stack*)caller)->cs; - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { dump->esp = (u32) caller + sizeof(exception_stack); user=false; @@ -217,7 +217,7 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump) cpuerror("#MC Machine check", dump, false); } endofexception: - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { setESP(dump); restcpu_kernel(); diff --git a/lib/process.c b/lib/process.c index ad30dbc..034c515 100644 --- a/lib/process.c +++ b/lib/process.c @@ -270,10 +270,12 @@ void switchtask(tid_t tid) { setTSS(0x0, 0x0); wrmsr(0x175, 0x0, 0x0); - } + } + if (((atask->dump.cs & 0xFFF8) !=SEL_KERNEL_CODE) && ((atask->dump.cs & 0xFFF8) !=SEL_USER_CODE)) + cpuerror("SWITCH ERROR", &atask->dump, false); atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF; createdump(atask->dump); - if (atask->dump.cs==SEL_KERNEL_CODE) + if ((atask->dump.cs & 0xFFF8)==SEL_KERNEL_CODE) restcpu_kernel(); else restcpu_user(); @@ -382,11 +384,12 @@ void deletetask(tid_t tid) stoptask(tid); process* aprocess=findprocess(tid.pid); if (aprocess==NULL) return; + if (current.pid=tid.pid && current.number==tid.number) + current=maketid(1,1); task *atask=findtask(tid); if (atask==NULL) return; TAILQ_REMOVE(&aprocess->task_head, atask, tailq); vfree(atask); - sti(); } /*******************************************************************************/ @@ -394,15 +397,10 @@ void deletetask(tid_t tid) void runtask(tid_t tid) { - cli(); task *atask=findtask(tid); if (atask==NULL) return; if (atask->status == TASK_STATUS_READY) - { atask->status = TASK_STATUS_RUN; - //switchtask(tid); - } - sti(); } /*******************************************************************************/ @@ -466,7 +464,6 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) new->dump.edi = 0; new->status = TASK_STATUS_READY; return new->tid; - sti(); } /*******************************************************************************/ @@ -474,11 +471,9 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) void stoptask(tid_t tid) { - cli(); task *atask=findtask(tid); if (atask==NULL) return; atask->status=TASK_STATUS_STOP; - sti(); } /*******************************************************************************/ @@ -495,9 +490,9 @@ pid_t createprocess(u8 *src, bool kerneltask) if (new==NULL) return NULL; new->parent=oldprocess->pid; new->pdd = virtual_pd_create(); + new->iskernel=kerneltask; TAILQ_INIT(&new->page_head); TAILQ_INIT(&new->task_head); - new->iskernel=kerneltask; setCR3(new->pdd->addr->paddr); new->entry = loadelf(src, new->pid); createtask(new->pid,new->entry, new->iskernel); @@ -509,8 +504,8 @@ pid_t createprocess(u8 *src, bool kerneltask) cr3=old->pdd->addr->paddr; setCR3(cr3); new->status=PROCESS_STATUS_READY; - sti(); return new->pid; + sti(); } /*******************************************************************************/ @@ -522,6 +517,8 @@ void deleteprocess(pid_t pid) stopprocess(pid); process* aprocess=findprocess(pid); if (aprocess==NULL) return; + if (current.pid==pid) + current=maketid(1,1); task *next; TAILQ_FOREACH(next, &aprocess->task_head, tailq) deletetask(next->tid); @@ -544,7 +541,6 @@ void runprocess(pid_t pid) task *atask=findtask(tid); if (atask==NULL) return; atask->status=TASK_STATUS_RUN; - //switchtask(tid); } sti(); } diff --git a/lib/scheduler.c b/lib/scheduler.c index e76ae3f..a55914c 100644 --- a/lib/scheduler.c +++ b/lib/scheduler.c @@ -42,13 +42,13 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump) { exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1); bool noerror,user; - if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE) + if ((caller->cs & 0xFFF8)==SEL_KERNEL_CODE || (caller->cs & 0xFFF8)==SEL_USER_CODE) { noerror=true; dump->eip = caller->eip; dump->cs = caller->cs; dump->eflags = caller->eflags; - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { dump->esp = (u32) caller + sizeof(exception_stack_noerror); user=false; @@ -65,7 +65,7 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump) noerror=false; dump->eip = ((exception_stack*)caller)->eip; dump->cs = ((exception_stack*)caller)->cs; - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { dump->esp = (u32) caller + sizeof(exception_stack); user=false; @@ -88,7 +88,7 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump) memcpy(dump, &old->dump, sizeof(regs), 0); switchtask(new->tid); } - if (dump->cs==SEL_KERNEL_CODE) + if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE) { setESP(dump); restcpu_kernel(); diff --git a/lib/shell.c b/lib/shell.c index 2a74090..6fdcc88 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -136,8 +136,8 @@ int testtask() pid_t pid; pid = createprocess(&programs_test2, false); runprocess(pid); - //pid = createprocess(&programs_test, false); - //runprocess(pid); + pid = createprocess(&programs_test, false); + runprocess(pid); } /*******************************************************************************/ diff --git a/programs/test2.c b/programs/test2.c index 28b39c6..876ff38 100644 --- a/programs/test2.c +++ b/programs/test2.c @@ -11,7 +11,7 @@ void main(void) print("demarrage...\r\n"); while (true) { - if (getticks()%100000==0) + if (getticks()%100==0) print("[TEST]\r\n"); } exit(1);