void calypso_fiq(void) { uint8_t num, tmp; uint32_t *regs; /* XXX: What is this??? * Passed to but ignored in IRQ handlers * Only valid meaning is apparently non-NULL == IRQ context */ regs = (uint32_t *)current_regs; current_regs = (uint32_t *)# /* Detect & deliver like an IRQ but we are in FIQ context */ num = getreg8(IRQ_REG(FIQ_NUM)) & 0x1f; irq_dispatch(num, regs); /* Start new FIQ agreement */ tmp = getreg8(IRQ_REG(IRQ_CTRL)); tmp |= 0x02; putreg8(tmp, IRQ_REG(IRQ_CTRL)); current_regs = regs; }
static void set_default_priorities(void) { unsigned int i; for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++) { uint16_t val; uint8_t prio = default_irq_prio[i]; if (prio > 31) { prio = 31; } val = getreg16(IRQ_REG(ILR_IRQ(i))); val &= ~(0x1f << 2); val |= prio << 2; /* Make edge mode default. Hopefully causes less trouble */ val |= 0x02; putreg16(val, IRQ_REG(ILR_IRQ(i))); } }
void up_decodeirq(uint32_t *regs) { uint8_t num, tmp; uint32_t *saved_regs; /* XXX: What is this??? * Passed to but ignored in IRQ handlers * Only valid meaning is apparently non-NULL == IRQ context */ saved_regs = (uint32_t *)current_regs; current_regs = regs; /* Detect & deliver the IRQ */ num = getreg8(IRQ_REG(IRQ_NUM)) & 0x1f; irq_dispatch(num, regs); /* Start new IRQ agreement */ tmp = getreg8(IRQ_REG(IRQ_CTRL)); tmp |= 0x01; putreg8(tmp, IRQ_REG(IRQ_CTRL)); current_regs = saved_regs; }
void up_irqinitialize(void) { /* Prepare hardware */ calypso_exceptions_install(); current_regs = NULL; /* Switch to internal ROM */ calypso_bootrom(1); /* Set default priorities */ set_default_priorities(); /* Mask all interrupts off */ putreg16(0xffff, IRQ_REG(MASK_IT_REG1)); putreg16(0xffff, IRQ_REG(MASK_IT_REG2)); /* clear all pending interrupts */ putreg16(0, IRQ_REG(IT_REG1)); putreg16(0, IRQ_REG(IT_REG2)); /* Enable interrupts globally to the ARM core */ #ifndef CONFIG_SUPPRESS_INTERRUPTS irqrestore(SVC_MODE | PSR_F_BIT); #endif }
// void Oberon_hw0_irqdispatch(struct pt_regs *regs) void Oberon_hw0_irqdispatch(void) { unsigned short u16Reglow,u16Reghigh; u16Reglow = (unsigned short)IRQ_REG(REG_IRQ_PENDING_L); u16Reghigh = (unsigned short)IRQ_REG(REG_IRQ_PENDING_H); //u16Reglow += MSTAR_INT_BASE; if ( u16Reglow & IRQL_UHC ) { do_IRQ((unsigned int)E_IRQ_UHC); } if ( u16Reglow & IRQL_DEB ) { do_IRQ((unsigned int)E_IRQ_DEB); } if ( u16Reglow & IRQL_UART0 ) { do_IRQ((unsigned int)E_IRQ_UART0); } if ( u16Reglow & IRQL_UART1 ) { do_IRQ((unsigned int)E_IRQ_UART1); } if ( u16Reglow & IRQL_UART2 ) { do_IRQ((unsigned int)E_IRQ_UART2); } if(u16Reglow & IRQL_EMAC) { do_IRQ((unsigned int)E_IRQ_EMAC); } // if if ( u16Reghigh & IRQH_TSP ) { do_IRQ((unsigned int)E_IRQ_TSP); } if ( u16Reghigh & IRQH_HDMITX ) { do_IRQ((unsigned int)E_IRQ_HDMITX); } if ( u16Reghigh & IRQH_GOP ) { do_IRQ((unsigned int)E_IRQ_GOP); } if ( u16Reghigh & IRQH_PCM2MCU ) { do_IRQ((unsigned int)E_IRQ_PCM2MCU); } if ( u16Reghigh & IRQH_RTC ) { do_IRQ((unsigned int)E_IRQ_RTC); } }
//#define REG(addr) (*(volatile unsigned int *)(addr)) static int Oberon_EnableInterrupt (InterruptNum eIntNum) { int bRet = true; if (eIntNum == E_IRQ_FIQ_ALL) { IRQ_REG(REG_IRQ_MASK_L) &= ~IRQL_MASK; IRQ_REG(REG_IRQ_MASK_H) &= ~IRQH_MASK; IRQ_REG(REG_FIQ_MASK_L) &= ~FIQL_MASK; IRQ_REG(REG_FIQ_MASK_H) &= ~FIQH_MASK; } else if ( (eIntNum >= E_IRQL_START) && (eIntNum <= E_IRQL_END) ) { IRQ_REG(REG_IRQ_MASK_L) &= ~(0x1 << (eIntNum-E_IRQL_START) ); } else if ( (eIntNum >= E_IRQH_START) && (eIntNum <= E_IRQH_END) ) { IRQ_REG(REG_IRQ_MASK_H) &= ~(0x1 << (eIntNum-E_IRQH_START) ); } else if ( (eIntNum >= E_FIQL_START) && (eIntNum <= E_FIQL_END) ) { IRQ_REG(REG_FIQ_MASK_L) &= ~(0x1 << (eIntNum-E_FIQL_START) ); } else if ( (eIntNum >= E_FIQH_START) && (eIntNum <= E_FIQH_END) ) { IRQ_REG(REG_FIQ_MASK_H) &= ~(0x1 << (eIntNum-E_FIQH_START) ); } return bRet; }
static void set_default_priorities(void) { unsigned int i; for (i = 0; i < ARRAY_SIZE(default_irq_prio); i++) { uint16_t val; uint8_t prio = default_irq_prio[i]; if (prio > 31) prio = 31; val = readw(IRQ_REG(ILR_IRQ(i))); val &= ~(0x1f << 2); val |= prio << 2; writew(val, IRQ_REG(ILR_IRQ(i))); } }
static void _irq_enable(enum irq_nr nr, int enable) { uint16_t *reg = IRQ_REG(MASK_IT_REG1); uint16_t val; if (nr > 15) { reg = IRQ_REG(MASK_IT_REG2); nr -= 16; } val = readw(reg); if (enable) val &= ~(1 << nr); else val |= (1 << nr); writew(val, reg); }
/* Entry point for interrupts */ void irq(void) { uint8_t num, tmp; irq_handler *handler; #if 1 /* Hardware interrupt detection mode */ num = readb(IRQ_REG(IRQ_NUM)) & 0x1f; printd("i%02x\n", num); handler = irq_handlers[num]; if (handler) handler(num); #else /* Software interrupt detection mode */ { uint16_t it_reg, mask_reg; uint32_t irqs; it_reg = readw(IRQ_REG(IT_REG1)); mask_reg = readw(IRQ_REG(MASK_IT_REG1)); irqs = it_reg & ~mask_reg; it_reg = readw(IRQ_REG(IT_REG2)); mask_reg = readw(IRQ_REG(MASK_IT_REG2)); irqs |= (it_reg & ~mask_reg) << 16; for (num = 0; num < 32; num++) { if (irqs & (1 << num)) { printd("i%d\n", num); handler = irq_handlers[num]; if (handler) handler(num); /* clear this interrupt */ if (num < 16) writew(~(1 << num), IRQ_REG(IT_REG1)); else writew(~(1 << (num-16)), IRQ_REG(IT_REG2)); } } dputchar('\n'); } #endif /* Start new IRQ agreement */ tmp = readb(IRQ_REG(IRQ_CTRL)); tmp |= 0x01; writeb(tmp, IRQ_REG(IRQ_CTRL)); }
void interruptNotify(CPUState *st, Process *p) { InterruptMessage *msg = new InterruptMessage; msg->from = KERNEL_PID; msg->type = IRQType; msg->vector = IRQ_REG(st); p->getMessages()->prepend(msg); p->setState(Process::Ready); }
void interruptNotify(CPUState *st, Process *p) { #ifdef __i386__ ProcessManager *procs = Kernel::instance->getProcessManager(); p->getMessages()->prepend(new UserMessage(new InterruptMessage(IRQ_REG(st)), sizeof(InterruptMessage))); p->setState(Process::Ready); #endif }
/* Entry point for FIQs */ void fiq(void) { uint8_t num, tmp; irq_handler *handler; num = readb(IRQ_REG(FIQ_NUM)) & 0x1f; if (num) { printd("f%02x\n", num); } handler = irq_handlers[num]; if (handler) handler(num); /* Start new FIQ agreement */ tmp = readb(IRQ_REG(IRQ_CTRL)); tmp |= 0x02; writeb(tmp, IRQ_REG(IRQ_CTRL)); }
// void Oberon_hw0_fiqdispatch(struct pt_regs *regs) void Oberon_hw0_fiqdispatch(void) { unsigned short u16Reg; u16Reg = IRQ_REG(REG_FIQ_PENDING_H); //u16Reg += MSTAR_INT_BASE; if ( u16Reg & FIQH_DSP2UP ) { do_IRQ((unsigned int)E_FIQ_DSP2UP); } if ( u16Reg & FIQH_IR ) { do_IRQ((unsigned int)E_FIQ_IR); } u16Reg = IRQ_REG(REG_FIQ_PENDING_L); //u16Reg += MSTAR_INT_BASE; }
static void _irq_enable(enum irq_nr nr, int enable) { uintptr_t reg = IRQ_REG(MASK_IT_REG1); uint16_t val; if (nr > 15) { reg = IRQ_REG(MASK_IT_REG2); nr -= 16; } val = getreg16(reg); if (enable) { val &= ~(1 << nr); } else { val |= (1 << nr); } putreg16(val, reg); }
void irq_config(enum irq_nr nr, int fiq, int edge, int8_t prio) { uint16_t val; if (prio == -1) prio = default_irq_prio[nr]; if (prio > 31) prio = 31; val = prio << 2; if (edge) val |= 0x02; if (fiq) val |= 0x01; writew(val, IRQ_REG(ILR_IRQ(nr))); }
int up_prioritize_irq(int nr, int prio) { uint16_t val; if (prio == -1) { prio = default_irq_prio[nr]; } if (prio > 31) { prio = 31; } val = prio << 2; putreg16(val, IRQ_REG(ILR_IRQ(nr))); return 0; }
int up_prioritize_irq(int nr, int prio) { uint16_t val; if (prio == -1) prio = default_irq_prio[nr]; if (prio > 31) prio = 31; val = prio << 2; /* if (edge) val |= 0x02; if (fiq) val |= 0x01; */ writew(val, IRQ_REG(ILR_IRQ(nr))); return 0; // XXX: what's the return??? }
static int Oberon_DisableInterrupt (InterruptNum eIntNum) { if (eIntNum == E_IRQ_FIQ_ALL) { IRQ_REG(REG_IRQ_MASK_L) |= IRQL_MASK; IRQ_REG(REG_IRQ_MASK_H) |= IRQH_MASK; IRQ_REG(REG_FIQ_MASK_L) |= FIQL_MASK; IRQ_REG(REG_FIQ_MASK_H) |= FIQH_MASK; } else if ( (eIntNum >= E_IRQL_START) && (eIntNum <= E_IRQL_END) ) { IRQ_REG(REG_IRQ_MASK_L) |= (0x1 << (eIntNum-E_IRQL_START) ); } else if ( (eIntNum >= E_IRQH_START) && (eIntNum <= E_IRQH_END) ) { IRQ_REG(REG_IRQ_MASK_H) |= (0x1 << (eIntNum-E_IRQH_START) ); } else if ( (eIntNum >= E_FIQL_START) && (eIntNum <= E_FIQL_END) ) { IRQ_REG(REG_FIQ_MASK_L) |= (0x1 << (eIntNum-E_FIQL_START) ); IRQ_REG(REG_FIQ_CLEAR_L) = (0x1 << (eIntNum-E_FIQL_START) ); IRQ_REG(REG_FIQ_CLEAR_L) = 0; } else if ( (eIntNum >= E_FIQH_START) && (eIntNum <= E_FIQH_END) ) { IRQ_REG(REG_FIQ_MASK_H) |= (0x1 << (eIntNum-E_FIQH_START) ); IRQ_REG(REG_FIQ_CLEAR_H) = (0x1 << (eIntNum-E_FIQH_START) ); IRQ_REG(REG_FIQ_CLEAR_H) = 0; } return true; }
void interruptNotify(CPUState *st, ArchProcess *p) { p->getMessages()->insertHead(new UserMessage(new InterruptMessage(IRQ_REG(st)), sizeof(InterruptMessage))); p->wakeup(); }