/**
 * Any interrupt request except the spurious or timer should be
 * routed to the default interrupt handler.
 */
void interrupt_handler (tf_t *tf)
{
    unsigned int cur_pid;
    unsigned int trapno;

    cur_pid = get_curid ();

    trapno = tf -> trapno;

    switch (trapno)
    {
      case T_IRQ0 + IRQ_SPURIOUS:
          spurious_intr_handler ();
          break;
      case T_IRQ0 + IRQ_TIMER:
          timer_intr_handler ();
          break;
      case T_IRQ0 + IRQ_IDE1: {
		  ide_intr();
		  intr_eoi();
		  }
		  break;
	  case T_IRQ0 + IRQ_IDE2:
	      spurious_intr_handler();
		  break;
	  default:
          default_intr_handler ();
    }
}
Beispiel #2
0
irqreturn_t at91_irq_handler(int irq, void *dev_id)
{
	int ntries = 8;
	int pin_val1, pin_val2;

	/* additional deglitch, line can be noisy in badly designed PCB */
	do {
		pin_val1 = at91_get_gpio_value(irq);
		pin_val2 = at91_get_gpio_value(irq);
	} while (pin_val1 != pin_val2 && --ntries > 0);

	if (pin_val1 == 0 || ntries <= 0)
		return IRQ_HANDLED;

	return ide_intr(irq, dev_id);
}
Beispiel #3
0
/*
 * do_pdc4030_io() is called from do_rw_disk, having had the block number
 * already set up. It issues a READ or WRITE command to the Promise
 * controller, assuming LBA has been used to set up the block number.
 */
ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq)
{
	unsigned long timeout;
	byte stat;

	if (rq->cmd == READ) {
	    ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
	    OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
/* The card's behaviour is odd at this point. If the data is
   available, DRQ will be true, and no interrupt will be
   generated by the card. If this is the case, we need to simulate
   an interrupt. Ugh! Otherwise, if an interrupt will occur, bit0
   of the SELECT register will be high, so we can just return and
   be interrupted.*/
	    timeout = jiffies + HZ/20; /* 50ms wait */
	    do {
		stat=GET_STAT();
		if(stat & DRQ_STAT) {
                    disable_irq(HWIF(drive)->irq);
		    ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL);
                    enable_irq(HWIF(drive)->irq);
		    return ide_stopped;
		}
		if(IN_BYTE(IDE_SELECT_REG) & 0x01)
		    return ide_started;
		udelay(1);
	    } while (time_before(jiffies, timeout));
	    printk("%s: reading: No DRQ and not waiting - Odd!\n",
		   drive->name);
	    return ide_started;
	}
	if (rq->cmd == WRITE) {
	    ide_startstop_t startstop;
	    OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
	    if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
		printk("%s: no DRQ after issuing PROMISE_WRITE\n", drive->name);
		return startstop;
	    }
	    if (!drive->unmask)
		__cli();	/* local CPU only */
	    HWGROUP(drive)->wrq = *rq; /* scratchpad */
	    return promise_write(drive);
	}
	printk("%s: bad command: %d\n", drive->name, rq->cmd);
	ide_end_request(0, HWGROUP(drive));
	return ide_stopped;
}
Beispiel #4
0
/*
 *  interrupt handler function
 */
static irqreturn_t emxx_cfi_irq_handler(int irq, void *dev_id)
{
	int status, int_status;

	udelay(3);

	int_status = readl(EMXX_CFI_INTERRUPT);
	status = readl(EMXX_CFI_STATUS);

	pdbg("irq=0x%x status=0x%x\n", int_status, status);

	if (int_status) {
		writel(int_status, EMXX_CFI_INTERRUPT);
		if ((int_status & CFI_INT_RDYS))
			return ide_intr(irq, dev_id);
	}

	return IRQ_HANDLED;
}
Beispiel #5
0
void
trap(struct trapframe *tf)
{
  if(tf->trapno == T_SYSCALL){
    if(cp->killed)
      exit();
    cp->tf = tf;
    syscall();
    if(cp->killed)
      exit();
    return;
  }

  switch(tf->trapno){
  case IRQ_OFFSET + IRQ_TIMER:
    if(cpu() == 0){
      acquire(&tickslock);
      ticks++;
      wakeup(&ticks);
      release(&tickslock);
    }
    lapic_eoi();
    break;
  case IRQ_OFFSET + IRQ_IDE:
    ide_intr();
    lapic_eoi();
    break;
  case IRQ_OFFSET + IRQ_KBD:
    kbd_intr();
    lapic_eoi();
    break;
  case IRQ_OFFSET + IRQ_SPURIOUS:
    cprintf("cpu%d: spurious interrupt at %x:%x\n",
            cpu(), tf->cs, tf->eip);
    lapic_eoi();
    break;
    
  default:
    if(cp == 0 || (tf->cs&3) == 0){
      // In kernel, it must be our mistake.
      cprintf("unexpected trap %d from cpu %d eip %x\n",
              tf->trapno, cpu(), tf->eip);
      panic("trap");
    }
    // In user space, assume process misbehaved.
    cprintf("pid %d %s: trap %d err %d on cpu %d eip %x -- kill proc\n",
            cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip);
    cp->killed = 1;
  }

  // Force process exit if it has been killed and is in user space.
  // (If it is still executing in the kernel, let it keep running 
  // until it gets to the regular system call return.)
  if(cp && cp->killed && (tf->cs&3) == DPL_USER)
    exit();

  // Force process to give up CPU on clock tick.
  // If interrupts were on while locks held, would need to check nlock.
  if(cp && cp->state == RUNNING && tf->trapno == IRQ_OFFSET+IRQ_TIMER)
    yield();
}
Beispiel #6
0
void
trap(struct trapframe *tf)
{
  int v = tf->trapno;
  struct proc *cp = curproc[cpu()];

  if(v == T_SYSCALL){
    if(cp->killed)
      proc_exit();
    cp->tf = tf;
    syscall();
    if(cp->killed)
      proc_exit();
    return;
  }

  // Increment nlock to make sure interrupts stay off
  // during interrupt handler.  Decrement before returning.
  cpus[cpu()].nlock++;

  switch(v){
  case IRQ_OFFSET + IRQ_TIMER:
    lapic_timerintr();
    cpus[cpu()].nlock--;
    if(cp){
      // Force process exit if it has been killed and is in user space.
      // (If it is still executing in the kernel, let it keep running
      // until it gets to the regular system call return.)
      if((tf->cs&3) == 3 && cp->killed)
        proc_exit();

      // Force process to give up CPU and let others run.
      if(cp->state == RUNNING)
        yield();
    }
    return;

  case IRQ_OFFSET + IRQ_IDE:
    ide_intr();
    lapic_eoi();
    break;
  
  case IRQ_OFFSET + IRQ_KBD:
    kbd_intr();
    lapic_eoi();
    break;
  
  case IRQ_OFFSET + IRQ_SPURIOUS:
    cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip);
    break;
    
  default:
    if(curproc[cpu()]) {
      // Assume process divided by zero or dereferenced null, etc.
      cprintf("pid %d: unhandled trap %d on cpu %d eip %x -- kill proc\n",
              curproc[cpu()]->pid, v, cpu(), tf->eip);
      proc_exit();
    }
    
    // Otherwise it's our mistake.
    cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip);
    panic("trap");
  }
  
  cpus[cpu()].nlock--;
}
Beispiel #7
0
void
trap(struct trapframe *tf)
{

  uint cr2;
  //print_trapframe(tf); procdump(); //chy for debug
  if (cp!=NULL)
     dbmsg("trap frame from %x %x, cp name %s\n",tf->eip, tf->trapno,cp->name);
  if(tf->trapno == T_SYSCALL){
    if(cp->killed)
      exit();
    cp->tf = tf;
    syscall();
    if(cp->killed)
      exit();
    return;
  }

  switch(tf->trapno){
  cprintf("interrupt %x, trap frame : %x\n",tf->trapno, (uint)tf);
  case IRQ_OFFSET + IRQ_TIMER:
  //  if(cpu() == 0){
      acquire(&tickslock);
      ticks++;
      wakeup(&ticks);
      release(&tickslock);
  //  }
    lapic_eoi();
    break;
  case IRQ_OFFSET + IRQ_IDE:
    ide_intr();
    lapic_eoi();
    break;
  case IRQ_OFFSET + IRQ_KBD:
    kbd_intr();
    lapic_eoi();
    break;
  case IRQ_OFFSET + IRQ_SPURIOUS:
    cprintf("cpu%d: spurious interrupt at %x:%x\n",
            cpu(), tf->cs, tf->eip);
    lapic_eoi();
    break;
  case T_PGFLT:
    cprintf("page fault!\n");
    //cprintf("current process uses %d pages.\n", cp->sz/PAGE);
    cr2=rcr2();
    if(handle_pgfault(cr2)<0){
      cprintf("cannot handle page fault! Virtual addr: %x, eip: %x\n", cr2, tf->eip);
    }else{
      cprintf("page fault handled successfully! Virtual addr: %x, eip: %x\n", cr2, tf->eip);
    }
    //cprintf("current process uses %d pages.\n", cp->sz/PAGE);
    break;
  default:
    if(cp == 0 || (tf->cs&3) == 0){
      // In kernel, it must be our mistake.
      cprintf("unexpected trap %d from cpu %d eip %x esp %x cr2 %x, pid %d %s \n",
              tf->trapno, cpu(), tf->eip, tf->esp, rcr2(),cp->pid, cp->name);
      panic("trap");
    }
    // In user space, assume process misbehaved.
    cprintf("pid %d %s: trap %d err %d on cpu %d eip %x cr2 %x -- kill proc\n",
            cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip, rcr2());
    cp->killed = 1;
  }

  // Force process exit if it has been killed and is in user space.
  // (If it is still executing in the kernel, let it keep running 
  // until it gets to the regular system call return.)
  if(cp && cp->killed && (tf->cs&3) == DPL_USER)
    exit();

  // Force process to give up CPU on clock tick.
  // If interrupts were on while locks held, would need to check nlock.
  if(cp && cp->state == RUNNING && tf->trapno == IRQ_OFFSET+IRQ_TIMER){
#ifdef LOAD_BALANCE_ON
    if(cp == idleproc[cpu()]){
      struct rq* rq = theCpu.rq;
      rq->sched_class->load_balance(rq);
    }
#endif
    proc_tick(theCpu.rq, cp);
  }
}