Guest User

Untitled

a guest
Aug 1st, 2011
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.81 KB | None | 0 0
  1. ;;;;;;;;ISR for PIC:
  2.  
  3. extern timerTick
  4.  
  5. irq0:
  6.     cli
  7.     mov al, 0x20
  8.     out 0x20, al
  9.     mov eax, timerTick
  10.     mov ecx, [esp]          ;grab eip off stack
  11.     mov edx, [esp+8]        ;and grab eflags
  12.     mov ebx, esp
  13.     add ebx, 12   ;eip, cs, eflags were pushed on when this ISR was called, so the old esp is currentESP+12
  14.     push ecx
  15.     push ebx
  16.     push edx
  17.     call eax
  18.     pop ecx
  19.     pop ecx
  20.     pop ecx
  21.     sti
  22.     iret
  23.  
  24. ////////////////timerTick, called by ISR:
  25. int tick=0;
  26. void timerTick (unsigned int eflags, unsigned int esp, unsigned int eip) {
  27.     tick++;
  28.     if (tick == 20) {
  29.         tick = 0;
  30.         switchTasks (eflags, esp, eip);
  31.     }
  32. }
  33.  
  34. //////////////switchTasks, does the actual task-switching
  35. typedef struct task {
  36.     unsigned int esp, ebp, eip, eax, ebx, ecx, edx, edi, esi, eflags, id, *pageDir;
  37.     struct task *nextTask;
  38. } task_t;
  39.  
  40. task_t *firstTask, *currentTask;
  41.  
  42. unsigned int switchTasks (unsigned int eflags, unsigned int esp, unsigned int eip) {
  43.     if (firstTask->nextTask == firstTask)   {           //if we only have one task, just return
  44.         return 0;
  45.     }
  46.  
  47.     currentTask->eip = eip;                     //eip is taken from the stack when the ISR is called, and passed into this function
  48.     currentTask->esp = esp;                     //(through the previous function, tick, in timer.c), esp is passed in from ISR too
  49.     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
  50.     asm volatile ("mov %0, ebp" : "=r" (currentTask->ebp));     //store all the general registers and base pointer in the task struct
  51.     asm volatile ("mov %0, eax" : "=r" (currentTask->eax));
  52.     asm volatile ("mov %0, ebx" : "=r" (currentTask->ebx));
  53.     asm volatile ("mov %0, ecx" : "=r" (currentTask->ecx));
  54.     asm volatile ("mov %0, edx" : "=r" (currentTask->edx));
  55.     asm volatile ("mov %0, esi" : "=r" (currentTask->esi));
  56.     asm volatile ("mov %0, edi" : "=r" (currentTask->edi));
  57.  
  58.     currentTask = currentTask->nextTask;                //load next task struct
  59.  
  60.     asm volatile ("mov cr3, %0" :: "r" (currentTask->pageDir)); //switch to new page directory
  61.     asm volatile ("mov esp, %0" :: "r" (currentTask->esp));     //and update all the registers with the new task's values
  62.     asm volatile ("mov ebp, %0" :: "r" (currentTask->ebp));
  63.     asm volatile ("mov eax, %0" :: "r" (currentTask->eax));
  64.     asm volatile ("mov ebx, %0" :: "r" (currentTask->ebx));
  65.     asm volatile ("mov ecx, %0" :: "r" (currentTask->ecx));
  66.     asm volatile ("mov edi, %0" :: "r" (currentTask->edi));
  67.     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
  68.     asm volatile ("mov esi, %0; push esi; popfd; mov esi, %1" :: "r" (currentTask->eflags), "r" (currentTask->esi));
  69.     asm volatile ("sti; jmp %0" :: "r" (currentTask->eip));     //jmp to next task's eip
  70.  
  71.     return 0;
  72. }
Advertisement
Add Comment
Please, Sign In to add comment