Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;;;;;;;ISR for PIC:
- extern timerTick
- irq0:
- cli
- mov al, 0x20
- out 0x20, al
- mov eax, timerTick
- mov ecx, [esp] ;grab eip off stack
- mov edx, [esp+8] ;and grab eflags
- mov ebx, esp
- add ebx, 12 ;eip, cs, eflags were pushed on when this ISR was called, so the old esp is currentESP+12
- push ecx
- push ebx
- push edx
- call eax
- pop ecx
- pop ecx
- pop ecx
- sti
- iret
- ////////////////timerTick, called by ISR:
- int tick=0;
- void timerTick (unsigned int eflags, unsigned int esp, unsigned int eip) {
- tick++;
- if (tick == 20) {
- tick = 0;
- switchTasks (eflags, esp, eip);
- }
- }
- //////////////switchTasks, does the actual task-switching
- typedef struct task {
- unsigned int esp, ebp, eip, eax, ebx, ecx, edx, edi, esi, eflags, id, *pageDir;
- struct task *nextTask;
- } task_t;
- task_t *firstTask, *currentTask;
- unsigned int switchTasks (unsigned int eflags, unsigned int esp, unsigned int eip) {
- if (firstTask->nextTask == firstTask) { //if we only have one task, just return
- return 0;
- }
- currentTask->eip = eip; //eip is taken from the stack when the ISR is called, and passed into this function
- currentTask->esp = esp; //(through the previous function, tick, in timer.c), esp is passed in from ISR too
- currentTask->eflags = (eflags & 0xFFFFFDFF); //clear the IF bit, so we aren't interrupted between when we restore the flags register and jmp to next task
- asm volatile ("mov %0, ebp" : "=r" (currentTask->ebp)); //store all the general registers and base pointer in the task struct
- asm volatile ("mov %0, eax" : "=r" (currentTask->eax));
- asm volatile ("mov %0, ebx" : "=r" (currentTask->ebx));
- asm volatile ("mov %0, ecx" : "=r" (currentTask->ecx));
- asm volatile ("mov %0, edx" : "=r" (currentTask->edx));
- asm volatile ("mov %0, esi" : "=r" (currentTask->esi));
- asm volatile ("mov %0, edi" : "=r" (currentTask->edi));
- currentTask = currentTask->nextTask; //load next task struct
- asm volatile ("mov cr3, %0" :: "r" (currentTask->pageDir)); //switch to new page directory
- asm volatile ("mov esp, %0" :: "r" (currentTask->esp)); //and update all the registers with the new task's values
- asm volatile ("mov ebp, %0" :: "r" (currentTask->ebp));
- asm volatile ("mov eax, %0" :: "r" (currentTask->eax));
- asm volatile ("mov ebx, %0" :: "r" (currentTask->ebx));
- asm volatile ("mov ecx, %0" :: "r" (currentTask->ecx));
- asm volatile ("mov edi, %0" :: "r" (currentTask->edi));
- asm volatile ("mov edx, %0" :: "r" (currentTask->edx)); //below: put eflags into esi, push it, popfd pops the top value on the stack into the eflags register, then store esi's value in esi
- asm volatile ("mov esi, %0; push esi; popfd; mov esi, %1" :: "r" (currentTask->eflags), "r" (currentTask->esi));
- asm volatile ("sti; jmp %0" :: "r" (currentTask->eip)); //jmp to next task's eip
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment