Ok, I have an (almost) working scheduler. However after the first task is started, the timer interrupt is mysteriously never called again. That is however, unless I include an 'sti' statement in each task's code, in which case is works fine (ie tasks keep scheduling)! I'm setting eflags (on the stack to be popped off by the iret) to 0x206 (that is IF enabled), so I do not think that is the problem.
Can anyone offer some suggestions as to why this is not working, based on what I have said? I'll post the code later if need be, but no point making the post any bigger if it can be solved without it!
Thankyou very much in advance,
OScoder
Scheduler interupt problem
Re:Scheduler interupt problem
When you do an IRET, the EFLAGS register is restored, as well as CS and EIP.
Chances are the EFLAGS you are restoring does not have IF set. In the code that creates a stack frame, TSS or whatever you are using to describe each task, you want to ensure that the tasks EFLAGS register will have IF set as needed.
I hope that makes sense I can't really say any more without seeing the code.
Chances are the EFLAGS you are restoring does not have IF set. In the code that creates a stack frame, TSS or whatever you are using to describe each task, you want to ensure that the tasks EFLAGS register will have IF set as needed.
I hope that makes sense I can't really say any more without seeing the code.
Re:Scheduler interupt problem
Do you send an EOI (end of interrupt) to the master pic just before you iret? Otherwise the pic doesn't know that you finished your interrupt routine and won't start sending interrupts again!
look into the FAQ (click the banner above) for a more precise/correct explanation if needed.
Code: Select all
mov al,20h
out 20h,al
Re:Scheduler interupt problem
I've checked what's on the stack just before the iret, and eflags is set to 0x206 which, I think at least, contains the IF bit? Also, I do send an EOI. Any other things I could be doing wrong?
Asm code is here:
note - stack filler and scheduler to not restore or save registers apart from those used in the iret (for the the moment at least)...
Also the c code:
The tasks are stored in a linked list, if that makes any difference...
Thanks for your help so far,
OScoder
Asm code is here:
note - stack filler and scheduler to not restore or save registers apart from those used in the iret (for the the moment at least)...
Code: Select all
[BITS 32]
[GLOBAL _current_task_descriptor]
[GLOBAL _test_mockup]
[GLOBAL _fill_stack]
_current_task_descriptor dd 0x00
_test_mockup:
;save current stack pointer
mov ebx, [_current_task_descriptor]
mov [ebx + 4], esp
mov ecx, [ebx + 4]
;mov on to next task:
mov ebx, [_current_task_descriptor] ;make ebx point to task descriptor
mov eax, [ebx] ;make task descriptor point to first value in current task descriptor (which
mov DWORD [_current_task_descriptor], eax ;is the pointer to the next task on the list, if you get my drift...)
;get stack pointer of next task
mov ebx, [_current_task_descriptor]
mov eax, DWORD [ebx + 4] ;put second value in the now current task descriptor (stack pointer) into eax
mov esp, eax
;Tell the PIC that we have handled the interrupt
mov al, 0x20
out 0x20, al
iret
_fill_stack:
mov edx, esp
mov eax, [edx+4]
mov ebx, [edx+8]
mov ecx, esp
mov esp, eax
mov eax, 0x206
push eax
mov ax, 0x08
push ax
push ebx
mov esp, ecx ;EIP = 11a5
ret
Code: Select all
extern void fill_stack(ulong address, ulong eip);
struct task_descriptor tasknull;
struct task_descriptor task1;
struct task_descriptor task2;
ushort scheduler_init()
{
idt_add_gate( (unsigned long)&test_mockup, /*Address of our handler*/
_DPL_0 | _DESCRIPTOR_PRESENT | _DESCRIPTOR_INT_GATE,
0x08 & 0xFFF8, /*Decide selector from current code segment we are in*/
_IRQ_0); /*Interupt number - equal to irq0*/
return(0);
}
ushort scheduler_test()
{
/*Set up the stacks for our 'processes'*/
task1.esp0=0x100500;
task2.esp0=0x100400;
fill_stack(task1.esp0, (unsigned long)&task1_function);
fill_stack(task2.esp0, (unsigned long)&task2_function);
/*Update esp0's*/
task1.esp0=0x1004F6;
task2.esp0=0x1003F6;
/*Link tasks together so they can multitask*/
tasknull.next=(unsigned long) &task1;
task1.next=(unsigned long)&task2;
task2.next=(unsigned long)&task1;
/*Set current task descriptor as our first task*/
current_task_descriptor=(unsigned long)&tasknull;
/*Ok, now this is set up we just enable INTs, switch stacks and wait...*/
enable_irq(0);
asm("sti");
asm("hlt");
}
void task1_function()
{
_print("Task1",0xDF,1);
asm("hlt");
}
void task2_function()
{
_print("Task2",0xDF,2);
asm("hlt");
}
Thanks for your help so far,
OScoder
Re:Scheduler interupt problem
Hi,
Otherwise "task A" would recieve the IRQ and switch to "task B", and "task B" might not send the EOI at all. If "task A" gets the CPU back in 3 days time (for e.g.) then the EOI it sends will be 3 days late.
Cheers,
Brendan
You must send the EOI before you do the task switch.OScoder wrote: I've checked what's on the stack just before the iret, and eflags is set to 0x206 which, I think at least, contains the IF bit? Also, I do send an EOI. Any other things I could be doing wrong?
Otherwise "task A" would recieve the IRQ and switch to "task B", and "task B" might not send the EOI at all. If "task A" gets the CPU back in 3 days time (for e.g.) then the EOI it sends will be 3 days late.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:Scheduler interupt problem
How do you mean? I moved the EOI to the beggining of the handler (before I do anything else), and it seems to have made no difference....
Re:Scheduler interupt problem
Hi,
Have you tried single-stepping through everything with Bochs?
Cheers,
Brendan
That is what I meant, but unfortunately sometimes there's 2 bugs and fixing one of them might not make a difference..._OScoder wrote:How do you mean? I moved the EOI to the beggining of the handler (before I do anything else), and it seems to have made no difference....
Have you tried single-stepping through everything with Bochs?
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.