Though That WONT BE MULTITASKING either (I just did it for testing). For it I need to save the EIP also along with registers. I know that when an interrupt occurs, the last EIP and eflags, cs are pushed on the stack and I can pop them from there but I don't know EXACTLY HOW TO DO THAT.
I have registered my switch_task function in the interrupt handler of my PIT. I tried to pop the eax reg in the start of the function thinking EIP would be the last to be pushed. But that didn't worked. Also I tried to make my function as
void switch_task(irqregs_t regs) and do this inside: old_task->regs.eip=regs.eip; (the old_task-> regs is a separate struct, not related to irqregs_t)
the definition of irqregs_t is similar to :
typedef struct
{
uint32_t eflags,cs,eip;
}irqregs_t;
because I got to know from somewhere that its pushed in that fashion
but this didn't worked too.
I tried with this struct then:
typedef struct
{
uint32_t eip,cs,eflags;
}irqregs_t;
This too didn't worked after 1st cycle
In all the cases above, everything works fine for the 1st cycle that is, everything works fine until the "saved state of the task" is switched to rather then the "initial state of the task that I made while creating it"
my tasks are infinite while loops printing 1,2,3,4,5 depending on the task it is (1st task,2nd task...)
if everything works fine, I should print an infinite sequence like this :
1111111222222233333334444444555555511111112222222333333344444445555555.....
but its like this :
11111112222222333333344444445555555 that's it :/
Please give me a good way of handling the interrupt and getting the EIP from the stack (Please give me code with explanation and not only explanation because that's why I am in this situation :p)
here is my switch_task function:
Code: Select all
void switch_task(irqregs_t regs)
{
// If we haven't initialised tasking yet, just return.
//printf("\nSwitching Task\n");
asm volatile("cli");
old_task=current_task;
current_task=current_task->next;
//asm volatile("popl %%eax;": "=a"(old_task->regs.eip));
//printf("\nEIP: %x",old_task->regs.eip);
//asm volatile("add $0xc, %esp");
//switchTask(&old_task->regs, ¤t_task->regs);
asm volatile("movl %%ebx, %0;":"=r"(old_task->regs.ebx));
asm volatile("movl %%ecx, %0;":"=r"(old_task->regs.ecx));
asm volatile("movl %%edx, %0;":"=r"(old_task->regs.edx));
asm volatile("movl %%esi, %0;":"=r"(old_task->regs.esi));
asm volatile("movl %%edi, %0;":"=r"(old_task->regs.edi));
asm volatile("movl %%ebp, %0;":"=r"(old_task->regs.ebp));
asm volatile("pushl %eax");
asm volatile("pushl %ebx");
asm volatile("pushl %ecx");
asm volatile("pushl %edx");
asm volatile("pushl %esi");
asm volatile("pushl %edi");
asm volatile("pushl %ebp");
asm volatile("pushl %ds");
asm volatile("pushl %es");
asm volatile("pushl %fs");
asm volatile("pushl %gs");//*/
//asm volatile("mov %%esp, %0":"=r"(old_task->StackTop));
//old_task->regs.eip=regs.eip;
asm volatile(" movw $16, %ax "); /* KERNEL_DATA_SEG!!!! */
asm volatile(" movw %ax, %ds ");
asm volatile(" movw %ax, %es ");
asm volatile(" movw %ax, %fs ");
asm volatile(" movw %ax, %gs ");
asm volatile("movl %%ds, %0;":"=r"(old_task->ds));
asm volatile("movl %%es, %0;":"=r"(old_task->es));
asm volatile("movl %%fs, %0;":"=r"(old_task->fs));
asm volatile("movl %%gs, %0;":"=r"(old_task->gs));
asm volatile("movl %%ss, %0;":"=r"(old_task->ss));
stack=(uint32_t*)current_task->StackTop;
*--stack = current_task->regs.eflags; // eflags
*--stack = current_task->regs.cs; // cs
*--stack = current_task->regs.eip; // eip
*--stack = current_task->regs.eax; // eax
*--stack = current_task->regs.ebx; // ebx
*--stack = current_task->regs.ecx; // ecx
*--stack = current_task->regs.edx; //edx
*--stack = current_task->regs.esi; //esi
*--stack = current_task->regs.edi; //edi
*--stack = current_task->regs.ebp; //ebp
*--stack = current_task->ds; // ds
*--stack = current_task->fs; // fs
*--stack = current_task->es; // es
*--stack = current_task->gs; // gs
//old_task->regs.eip=regs.eip;
asm volatile("movl %%eax, %%esp;": :"a"(current_task->regs.esp));
asm volatile("movl %%eax, %%ss;": :"a"(current_task->ss));
asm volatile("popl %gs");
asm volatile("popl %fs");
asm volatile("pop %es");
asm volatile("popl %ds");
asm volatile("popl %ebp");
asm volatile("popl %edi");
asm volatile("popl %esi");
asm volatile("out %%al, %%dx": :"d"(0x20), "a"(0x20)); // send EoI to master PIC
asm volatile("popl %edx");
asm volatile("popl %ecx");
asm volatile("popl %ebx");
asm volatile("popl %eax");
//asm volatile("addl $8, %esp");
//asm volatile("push %0"::"r"(current_task->regs.eip));
/* asm volatile("\
sti; \
jmp *%0": :"r"(current_task->regs.eip));
//asm volatile("jmp *%0" :: "r"(current_task->regs.eip));
asm volatile("sti");
asm volatile("iret");/*
saveState();
asm volatile("mov %%esp, %%eax;":"=a"(old_task->regs.esp));
asm volatile("mov %%eax, %%esp;"::"a"(current_task->regs.esp));
loadState();*/
asm volatile("sti");
asm volatile("iret");
}