feat: reprise des fonctions de sauvegarde des registres pour task_switch
This commit is contained in:
parent
12aacb33f1
commit
dd70f75ab8
|
@ -2,6 +2,7 @@
|
|||
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
||||
/* */
|
||||
#include "types.h"
|
||||
#include "asm.h"
|
||||
|
||||
#ifndef _INTERRUPTS
|
||||
#define _INTERRUPTS
|
||||
|
@ -54,16 +55,57 @@
|
|||
asm volatile ("movl %%ebp,%[tomem];":: [tomem] "m" (mem)); \
|
||||
})
|
||||
|
||||
#define dumpcpu() asm("\
|
||||
pushal \n \
|
||||
#define createdump(dump) ({ \
|
||||
push(dump.eflags);\
|
||||
push(dump.cs);\
|
||||
push(dump.eip);\
|
||||
push(dump.esp);\
|
||||
push(dump.ss);\
|
||||
push(dump.ds);\
|
||||
push(dump.es);\
|
||||
push(dump.fs);\
|
||||
push(dump.gs);\
|
||||
push(dump.eax);\
|
||||
push(dump.ebx);\
|
||||
push(dump.ecx);\
|
||||
push(dump.edx);\
|
||||
push(dump.esi);\
|
||||
push(dump.edi);\
|
||||
push(dump.ebp);\
|
||||
push(dump.cr0);\
|
||||
push(dump.cr2);\
|
||||
push(dump.cr3);\
|
||||
push(dump.cr4);\
|
||||
push(dump.dr0);\
|
||||
push(dump.dr1);\
|
||||
push(dump.dr2);\
|
||||
push(dump.dr3);\
|
||||
push(dump.dr6);\
|
||||
push(dump.dr7);\
|
||||
u32 eferlow=(u32) dump.efer & 0xFFFF;\
|
||||
u32 eferhigh=(u32) dump.efer >> 32;\
|
||||
push(eferlow);\
|
||||
push(eferhigh);\
|
||||
})
|
||||
|
||||
#define dumpcpu() ({ \
|
||||
asm("\
|
||||
pushf \n \
|
||||
pushl %%cs\n \
|
||||
pushl $0x0\n \
|
||||
pushl %%ds\n \
|
||||
pushl %%esp\n \
|
||||
pushl %%ss\n \
|
||||
pushl %%ds\n \
|
||||
pushl %%es\n \
|
||||
pushl %%fs\n \
|
||||
pushl %%gs\n \
|
||||
pushl %%ss\n \
|
||||
pushl %%eax\n \
|
||||
pushl %%ebx\n \
|
||||
pushl %%ecx\n \
|
||||
pushl %%edx\n \
|
||||
pushl %%esi\n \
|
||||
pushl %%edi\n \
|
||||
pushl %%ebp\n \
|
||||
mov %%cr0, %%eax \n \
|
||||
pushl %%eax\n \
|
||||
mov %%cr2, %%eax \n \
|
||||
|
@ -87,9 +129,11 @@
|
|||
mov $0xC0000080, %%ecx \n \
|
||||
rdmsr \n \
|
||||
pushl %%edx \n \
|
||||
pushl %%eax":::)
|
||||
pushl %%eax":::);\
|
||||
})
|
||||
|
||||
#define restcpu() asm("\
|
||||
#define restcpu(usermode) ({\
|
||||
asm("\
|
||||
popl %%eax \n \
|
||||
popl %%edx \n \
|
||||
mov $0xC0000080, %%ecx \n \
|
||||
|
@ -107,24 +151,27 @@
|
|||
popl %%eax \n \
|
||||
mov %%eax,%%dr0 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr4 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr3 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr2 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr0 \n \
|
||||
popl %%ss\n \
|
||||
popl %%ebp\n \
|
||||
popl %%edi\n \
|
||||
popl %%esi\n \
|
||||
popl %%edx\n \
|
||||
popl %%ecx\n \
|
||||
popl %%ebx\n \
|
||||
popl %%eax\n \
|
||||
popl %%gs\n \
|
||||
popl %%fs\n \
|
||||
popl %%es\n \
|
||||
popl %%ds\n \
|
||||
popl %%eax \n \
|
||||
popl %%eax \n \
|
||||
popf \n \
|
||||
popal":::)
|
||||
popl %%ds\n \"::);\
|
||||
if (usermode==true)\
|
||||
asm("add $0x8,%%esp"::);\
|
||||
})
|
||||
|
||||
#define restdebugcpu() asm("\
|
||||
#define restdebugcpu(usermode) ({\
|
||||
asm("\
|
||||
popl %%eax \n \
|
||||
popl %%edx \n \
|
||||
mov $0xC0000080, %%ecx \n \
|
||||
|
@ -136,22 +183,34 @@
|
|||
popl %%eax \n \
|
||||
popl %%eax \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr4 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr3 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr2 \n \
|
||||
popl %%eax \n \
|
||||
mov %%eax,%%cr0 \n \
|
||||
popl %%ss\n \
|
||||
popl %%ebp\n \
|
||||
popl %%edi\n \
|
||||
popl %%esi\n \
|
||||
popl %%edx\n \
|
||||
popl %%ecx\n \
|
||||
popl %%ebx\n \
|
||||
popl %%eax\n \
|
||||
popl %%gs\n \
|
||||
popl %%fs\n \
|
||||
popl %%es\n \
|
||||
popl %%ds\n \
|
||||
popl %%eax \n \
|
||||
popl %%eax \n \
|
||||
popf \n \
|
||||
popal":::)
|
||||
popl %%ds":::);\
|
||||
if (usermode==true)\
|
||||
asm("add $0x8,%%esp"::);\
|
||||
})
|
||||
|
||||
/*
|
||||
lors d'un iret en mode user:
|
||||
pushl %%ss\n \
|
||||
pushl %%esp\n \
|
||||
lors d'un iret en mode kernel:
|
||||
pushf \n \
|
||||
pushl $cs\n \
|
||||
pushl $0x0\
|
||||
*/
|
||||
|
||||
|
||||
/* save pile */
|
||||
|
@ -167,22 +226,22 @@ typedef struct regs {
|
|||
u32 cr3;
|
||||
u32 cr2;
|
||||
u32 cr0;
|
||||
u32 ss;
|
||||
u32 ebp;
|
||||
u32 edi;
|
||||
u32 esi;
|
||||
u32 edx;
|
||||
u32 ecx;
|
||||
u32 ebx;
|
||||
u32 eax;
|
||||
u32 gs;
|
||||
u32 fs;
|
||||
u32 es;
|
||||
u32 ds;
|
||||
u32 ss;
|
||||
u32 esp;
|
||||
u32 eip;
|
||||
u32 cs;
|
||||
u32 eflags;
|
||||
u32 edi;
|
||||
u32 esi;
|
||||
u32 ebp;
|
||||
u32 esp;
|
||||
u32 ebx;
|
||||
u32 edx;
|
||||
u32 ecx;
|
||||
u32 eax;
|
||||
} regs __attribute__ ((packed));
|
||||
/* exception pile */
|
||||
typedef struct exception_stack {
|
||||
|
@ -220,6 +279,5 @@ struct idtr {
|
|||
void enableirq(u8 irq);
|
||||
void disableirq(u8 irq);
|
||||
void cpuerror(const u8 * src, const regs *stack);
|
||||
void createdump(regs *dump);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -134,44 +134,6 @@ void putidt(u32 offset, u16 select, u16 type, u16 index)
|
|||
idt[index] = temp;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Créé un dump de la mémoire en empilant les registres */
|
||||
|
||||
void createdump(regs *dump)
|
||||
{
|
||||
|
||||
push(dump->eax);
|
||||
push(dump->ecx);
|
||||
push(dump->edx);
|
||||
push(dump->ebx);
|
||||
push(dump->esp);
|
||||
push(dump->ebp);
|
||||
push(dump->esi);
|
||||
push(dump->edi);
|
||||
push(dump->eflags);
|
||||
push(dump->cs);
|
||||
push(dump->eip);
|
||||
push(dump->ds);
|
||||
push(dump->es);
|
||||
push(dump->fs);
|
||||
push(dump->gs);
|
||||
push(dump->ss);
|
||||
push(dump->cr0);
|
||||
push(dump->cr2);
|
||||
push(dump->cr3);
|
||||
push(dump->cr4);
|
||||
push(dump->dr0);
|
||||
push(dump->dr1);
|
||||
push(dump->dr2);
|
||||
push(dump->dr3);
|
||||
push(dump->dr6);
|
||||
push(dump->dr7);
|
||||
u32 eferlow=dump->efer & 0xFFFF;
|
||||
u32 eferhigh=dump->efer >> 32;
|
||||
push(eferlow);
|
||||
push(eferhigh);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Affiche une erreur CPU et fige l'ordinateur */
|
||||
|
||||
|
@ -213,8 +175,8 @@ void exception0()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#DE Divide error",dump);
|
||||
}
|
||||
|
@ -229,8 +191,8 @@ void exception1()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
changevc(6);
|
||||
clearscreen();
|
||||
|
@ -252,10 +214,14 @@ void exception1()
|
|||
initselectors(retry_address);
|
||||
}
|
||||
changevc(0);
|
||||
dump->ebp=oldesp;
|
||||
restdebugcpu();
|
||||
leave();
|
||||
sti();
|
||||
if (dump->cs==SEL_KERNEL_CODE)
|
||||
{
|
||||
restdebugcpu(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
restdebugcpu(false);
|
||||
}
|
||||
iret();
|
||||
}
|
||||
|
||||
|
@ -268,8 +234,8 @@ void exception2()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("NMI Non-maskable hardware interrupt",dump);
|
||||
}
|
||||
|
@ -283,8 +249,8 @@ void exception3()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#BP INT3 instruction",dump);
|
||||
}
|
||||
|
@ -298,8 +264,8 @@ void exception4()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#OF INTO instruction detected overflow",dump);
|
||||
}
|
||||
|
@ -313,8 +279,8 @@ void exception5()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#BR BOUND instruction detected overrange",dump);
|
||||
}
|
||||
|
@ -328,8 +294,8 @@ void exception6()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#UD Invalid instruction opcode",dump);
|
||||
}
|
||||
|
@ -343,8 +309,8 @@ void exception7()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#NM No coprocessor",dump);
|
||||
}
|
||||
|
@ -358,8 +324,8 @@ void exception8()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#DF Double fault",dump);
|
||||
}
|
||||
|
@ -373,8 +339,8 @@ void exception9()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("Coprocessor segment overrun",dump);
|
||||
}
|
||||
|
@ -388,8 +354,8 @@ void exception10()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#TS Invalid task state segment (TSS)",dump);
|
||||
}
|
||||
|
@ -403,8 +369,8 @@ void exception11()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#NP Segment not present",dump);
|
||||
}
|
||||
|
@ -418,8 +384,8 @@ void exception12()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#SS Stack fault",dump);
|
||||
}
|
||||
|
@ -433,8 +399,8 @@ void exception13()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#GP General protection fault (GPF)",dump);
|
||||
}
|
||||
|
@ -458,8 +424,8 @@ void exception14()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
if (dump->cr2 >= USER_CODE && dump->cr2 < USER_STACK)
|
||||
{
|
||||
|
@ -469,12 +435,15 @@ void exception14()
|
|||
printf("Page fault - %s at adress %Y cs:eip - %Y:%Y\r\n",ex14_errors[current->error_code & 0xF],dump->cr2,dump->cs,dump->eip);
|
||||
cpuerror("#SS Page fault",dump);
|
||||
}
|
||||
dump->ebp=oldesp;
|
||||
restdebugcpu();
|
||||
leave();
|
||||
sti();
|
||||
asm("addl $0x04,%%esp"::);
|
||||
iret();
|
||||
if (dump->cs==SEL_KERNEL_CODE)
|
||||
{
|
||||
restdebugcpu(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
restdebugcpu(false);
|
||||
}
|
||||
iret();
|
||||
}
|
||||
|
||||
void exception15()
|
||||
|
@ -486,8 +455,8 @@ void exception15()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("(reserved)",dump);
|
||||
}
|
||||
|
@ -501,8 +470,8 @@ void exception16()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#MF Coprocessor error",dump);
|
||||
}
|
||||
|
@ -516,8 +485,8 @@ void exception17()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#AC Alignment check",dump);
|
||||
}
|
||||
|
@ -531,8 +500,8 @@ void exception18()
|
|||
dumpcpu();
|
||||
getESP(dump);
|
||||
current=(exception_stack *) (oldesp+1);
|
||||
dump->esp=*oldesp;
|
||||
dump->ebp=*((u32 *) dump->esp);
|
||||
dump->ebp=*oldesp;
|
||||
dump->esp=(u32) oldesp+sizeof(exception_stack);
|
||||
dump->eip=current->eip;
|
||||
cpuerror("#MC Machine check",dump);
|
||||
}
|
||||
|
|
|
@ -154,19 +154,19 @@ u32 task_usePID (u32 pid)
|
|||
|
||||
void task_switch(u32 pid, bool fromkernelmode)
|
||||
{
|
||||
u32 ss,esp,eflags;
|
||||
current = &processes[pid];
|
||||
setTSS(current->kstack.ss0,current->kstack.esp0);
|
||||
eflags = (current->dump.eflags | 0x200) & 0xFFFFBFFF;
|
||||
if (fromkernelmode) {
|
||||
ss = current->dump.ss;
|
||||
esp = current->dump.esp;
|
||||
} else {
|
||||
ss = current->kstack.ss0;
|
||||
esp = current->kstack.esp0;
|
||||
setTSS(current->kstack.ss0,current->kstack.esp0);
|
||||
current->dump.eflags = (current->dump.eflags | 0x200) & 0xFFFFBFFF;
|
||||
createdump(current->dump);
|
||||
if (fromkernelmode)
|
||||
{
|
||||
restdebugcpu(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
restdebugcpu(false);
|
||||
}
|
||||
createdump(¤t->dump);
|
||||
restdebugcpu();
|
||||
iret();
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
|
|
@ -42,7 +42,7 @@ void sysenter_handler(void)
|
|||
break;
|
||||
|
||||
}
|
||||
restdebugcpu();
|
||||
restdebugcpu(true);
|
||||
sysexit();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue