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);
	}

}
Exemplo n.º 2
0
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
  }



}
Exemplo n.º 3
0
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);
    
}