void InterruptHandler::dispatch_interrupt(REGS * _r) { /* -- INTERRUPT NUMBER */ unsigned int int_no = _r->int_no - IRQ_BASE; //Console::puts("INTERRUPT DISPATCHER: int_no = "); ////Console::putui(int_no); ////Console::puts("\n"); assert((int_no >= 0) && (int_no < IRQ_TABLE_SIZE)); /* -- HAS A HANDLER BEEN REGISTERED FOR THIS INTERRUPT NO? */ InterruptHandler * handler = handler_table[int_no]; /* This is an interrupt that was raised by the interrupt controller. We need to send and end-of-interrupt (EOI) signal to the controller after the interrupt has been handled. */ // When the timer ticks 20ms, an interrupt happens. // Then the interrupt handler will take care of this interrupt and do the following. // In dispatch_interrupt function, it looks at the handler table, finds the right handler, and // then calls the corresponding handler function. // However, this function will not be returned in a short time. // If the new thread does not pend from here, it will return from somewhere else and therefore the // EOI signal will not be sent to PIC soon. Also, if this is the case, when this thread regains // CPU later, it will return from here, causing an unreansonable EOI signal sent. // To avoid this case, we must send EOI signal before the handler function (context switch) is called. /* Check if the interrupt was generated by the slave interrupt controller. If so, send an End-of-Interrupt (EOI) message to the slave controller. */ if (generated_by_slave_PIC(int_no)) { outportb(0xA0, 0x20); } /* Send an EOI message to the master interrupt controller. */ outportb(0x20, 0x20); //Then we call the corresponding handler function if (!handler) { /* --- NO DEFAULT HANDLER HAS BEEN REGISTERED. SIMPLY RETURN AN ERROR. */ Console::puts("INTERRUPT NO: "); Console::puti(int_no); Console::puts("\n"); Console::puts("NO DEFAULT INTERRUPT HANDLER REGISTERED\n"); //abort(); } else { /* -- HANDLE THE INTERRUPT */ handler->handle_interrupt(_r); } }
void InterruptHandler::dispatch_interrupt(REGS * _r) { /* -- INTERRUPT NUMBER */ unsigned int int_no = _r->int_no - IRQ_BASE; //Console::puts("INTERRUPT DISPATCHER: int_no = "); //Console::putui(int_no); //Console::puts("\n"); assert((int_no >= 0) && (int_no < IRQ_TABLE_SIZE)); /* -- HAS A HANDLER BEEN REGISTERED FOR THIS INTERRUPT NO? */ InterruptHandler * handler = handler_table[int_no]; if (!handler) { /* --- NO DEFAULT HANDLER HAS BEEN REGISTERED. SIMPLY RETURN AN ERROR. */ Console::puts("INTERRUPT NO: "); Console::puti(int_no); Console::puts("\n"); Console::puts("NO DEFAULT INTERRUPT HANDLER REGISTERED\n"); // abort(); } else { /* -- HANDLE THE INTERRUPT */ /* This is an interrupt that was raised by the interrupt controller. We need to send and end-of-interrupt (EOI) signal to the controller after the interrupt has been handled. */ /* Check if the interrupt was generated by the slave interrupt controller. If so, send an End-of-Interrupt (EOI) message to the slave controller. */ if (generated_by_slave_PIC(int_no)) {//modified to inform the control the interupt is being handled before the call to the handler outportb(0xA0, 0x20);//this will allow context switch during handler } /* Send an EOI message to the master interrupt controller. */ outportb(0x20, 0x20); // we send interupt has been handled before calling handle interupt to prevent the interupt from not being acknoledged //when a context switch occurs inside of the handler // and when the calling thread finally returns from the context switch to not send the interupt handled message //because at this point it has already been handled and if the PIC is waiting for a handled message it is a different interupt handler->handle_interrupt(_r); //dont do anything after handler to prevent interupts not being handled } }
void InterruptHandler::dispatch_interrupt(REGS * _r) { /* -- INTERRUPT NUMBER */ unsigned int int_no = _r->int_no - IRQ_BASE; //Console::puts("INTERRUPT DISPATCHER: int_no = "); //Console::putui(int_no); //Console::puts("\n"); assert((int_no >= 0) && (int_no < IRQ_TABLE_SIZE)); /* -- HAS A HANDLER BEEN REGISTERED FOR THIS INTERRUPT NO? */ InterruptHandler * handler = handler_table[int_no]; if (!handler) { /* --- NO DEFAULT HANDLER HAS BEEN REGISTERED. SIMPLY RETURN AN ERROR. */ Console::puts("INTERRUPT NO: "); Console::puti(int_no); Console::puts("\n"); Console::puts("NO DEFAULT INTERRUPT HANDLER REGISTERED\n"); // abort(); } else { /* -- HANDLE THE INTERRUPT */ /* Signal PIC that the interrupt has been handled and then make the call to handle interrupt */ if(int_no == 0) outportb(0x20, 0x20); handler->handle_interrupt(_r); } /* This is an interrupt that was raised by the interrupt controller. We need to send and end-of-interrupt (EOI) signal to the controller after the interrupt has been handled. */ /* Check if the interrupt was generated by the slave interrupt controller. If so, send an End-of-Interrupt (EOI) message to the slave controller. */ if (generated_by_slave_PIC(int_no)) { outportb(0xA0, 0x20); } /* Add additional check to see that we don't send EOI for interrupt 0, since its already done*/ /* Send an EOI message to the master interrupt controller. */ outportb(0x20, 0x20); }