📄 iq80310_misc.c
字号:
// Check for single-bit error if(!(*ELOG0_REG & 0x00000100)) { // call ECC restoration function _scrub_ecc(*ECAR0_REG); // Clear the MCISR *MCISR_REG = 0x1; } else {#ifdef DEBUG_NMI diag_printf("Multi-bit or nibble error\n");#endif } } // Check for ECC Error 1 if(*MCISR_REG & 0x2) {#ifdef DEBUG_NMI diag_printf("ELOG0 = 0x%X\n",*ELOG1_REG); diag_printf("ECC Error Detected at Address 0x%X\n",*ECAR1_REG); #endif // Check for single-bit error if(!(*ELOG1_REG & 0x00000100)) { // call ECC restoration function _scrub_ecc(*ECAR1_REG); // Clear the MCISR *MCISR_REG = 0x2; } else {#ifdef DEBUG_NMI diag_printf("Multi-bit or nibble error\n");#endif } } // Check for ECC Error N if(*MCISR_REG & 0x4) { // Clear the MCISR *MCISR_REG = 0x4; diag_printf("Uncorrectable error during RMW\n"); } // Restore ECCR register *ECCR_REG = eccr_reg; // clear the interrupt condition *MCISR_REG = *MCISR_REG & 7; return CYG_ISR_HANDLED;}static cyg_uint32 nmi_patu_ISR(cyg_vector_t vector, cyg_addrword_t data){ cyg_uint32 status; status = *PATUISR_REG;#ifdef DEBUG_NMI if (status & 0x001) diag_printf ("PPCI Master Parity Error\n"); if (status & 0x002) diag_printf ("PPCI Target Abort (target)\n"); if (status & 0x004) diag_printf ("PPCI Target Abort (master)\n"); if (status & 0x008) diag_printf ("PPCI Master Abort\n"); if (status & 0x010) diag_printf ("Primary P_SERR# Detected\n"); if (status & 0x080) diag_printf ("Internal Bus Master Abort\n"); if (status & 0x100) diag_printf ("PATU BIST Interrupt\n"); if (status & 0x200) diag_printf ("PPCI Parity Error Detected\n"); if (status & 0x400) diag_printf ("Primary P_SERR# Asserted\n");#endif *PATUISR_REG = status & 0x79f; *PATUSR_REG |= 0xf900; return CYG_ISR_HANDLED;}static cyg_uint32 nmi_satu_ISR(cyg_vector_t vector, cyg_addrword_t data){ cyg_uint32 status; status = *SATUISR_REG;#ifdef DEBUG_NMI if (status & 0x001) diag_printf ("SPCI Master Parity Error\n"); if (status & 0x002) diag_printf ("SPCI Target Abort (target)\n"); if (status & 0x004) diag_printf ("SPCI Target Abort (master)\n"); if (status & 0x008) diag_printf ("SPCI Master Abort\n"); if (status & 0x010) diag_printf ("Secondary P_SERR# Detected\n"); if (status & 0x080) diag_printf ("Internal Bus Master Abort\n"); if (status & 0x200) diag_printf ("SPCI Parity Error Detected\n"); if (status & 0x400) diag_printf ("Secondary P_SERR# Asserted\n");#endif *SATUISR_REG = status & 0x69f; *SATUSR_REG |= 0xf900; return CYG_ISR_HANDLED;}static cyg_uint32 nmi_pb_ISR(cyg_vector_t vector, cyg_addrword_t data){ cyg_uint32 status; status = *PBISR_REG;#ifdef DEBUG_NMI if (status & 0x001) diag_printf ("PPCI Master Parity Error\n"); if (status & 0x002) diag_printf ("PPCI Target Abort (target)\n"); if (status & 0x004) diag_printf ("PPCI Target Abort (master)\n"); if (status & 0x008) diag_printf ("PPCI Master Abort\n"); if (status & 0x010) diag_printf ("Primary P_SERR# Asserted\n"); if (status & 0x020) diag_printf ("PPCI Parity Error Detected\n");#endif *PBISR_REG = status & 0x3f; *PSR_REG |= 0xf900; return CYG_ISR_HANDLED;}static cyg_uint32 nmi_sb_ISR(cyg_vector_t vector, cyg_addrword_t data){ cyg_uint32 status; status = *SBISR_REG; *SBISR_REG = status & 0x7f; *SSR_REG |= 0xf900; return CYG_ISR_HANDLED;}static cyg_uint32 nfiq_ISR(cyg_vector_t vector, cyg_addrword_t data){ cyg_uint32 sources; int i, isr_ret; // Check NMI sources = *NISR_REG; for (i = 0; i < 12; i++) { if (sources & (1<<i)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_MCU_ERR + i); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); return isr_ret; } } return 0;}static cyg_uint32 nirq_ISR(cyg_vector_t vector, cyg_addrword_t data){ cyg_uint32 sources; int i, isr_ret; // Check XINT3 sources = *X3ISR_REG & ~(*X3MASK_REG); for (i = 0; i < 5; i++) { if (sources & (1 << i)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_TIMER + i); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); return isr_ret; } } // What to do about S_INTA-S_INTC? // Check XINT6 sources = *X6ISR_REG; for (i = 0; i < 3; i++) { // check DMA irqs if (sources & (1<<i)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_DMA_0 + i); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); return isr_ret; } } if (sources & 0x10) { // performance monitor _80312_EMISR = *EMISR_REG; if (_80312_EMISR & 1) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_GTSC); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (_80312_EMISR & 0x7ffe) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_PEC); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } return 0; } if (sources & 0x20) { // Application Accelerator Unit isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_AAIP); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); return isr_ret; } // Check XINT7 sources = *X7ISR_REG; if (sources & 2) { // I2C Unit cyg_uint32 i2c_sources = *ISR_REG; if (i2c_sources & (1<<7)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_RX_FULL); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (i2c_sources & (1<<6)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (i2c_sources & (1<<10)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_BUS_ERR); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (i2c_sources & (1<<4)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_STOP); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (i2c_sources & (1<<5)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_LOSS); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (i2c_sources & (1<<9)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_I2C_ADDRESS); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } return 0; } if (sources & 4) { // Messaging Unit cyg_uint32 inb_sources = *IISR_REG; if (inb_sources & (1<<0)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_MESSAGE_0); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (inb_sources & (1<<1)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_MESSAGE_1); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (inb_sources & (1<<2)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_DOORBELL); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (inb_sources & (1<<4)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_QUEUE_POST); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } if (inb_sources & (1<<6)) { isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_INDEX_REGISTER); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } return 0; } if (sources & 8) { // BIST isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_BIST); CYG_ASSERT (isr_ret & CYG_ISR_HANDLED, "Interrupt not handled"); } return 0;}// This routine is called to respond to a hardware interrupt (IRQ). It// should interrogate the hardware and return the IRQ vector number.int hal_IRQ_handler(void){ int sources, masks; asm volatile ( // read the interrupt source reg INTSRC "mrc p13,0,%0,c4,c0,0;" : "=r"(sources) : /*:*/ ); asm volatile ( // read the interrupt control reg INTCTL "mrc p13,0,%0,c0,c0,0;" : "=r"(masks) : /*:*/ ); // is a source both unmasked and active? if ( (0 != (1 & masks)) && (0 != ((8 << 28) & sources)) ) return CYGNUM_HAL_INTERRUPT_NFIQ; if ( (0 != (2 & masks)) && (0 != ((4 << 28) & sources)) ) return CYGNUM_HAL_INTERRUPT_NIRQ; if ( (0 != (8 & masks)) && (0 != ((2 << 28) & sources)) ) return CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT; if ( (0 != (4 & masks)) && (0 != ((1 << 28) & sources)) ) { // more complicated; it's the PMU. asm volatile ( // read the PMNC perfmon control reg "mrc p14,0,%0,c0,c0,0;" : "=r"(sources) : /*:*/ ); // sources is now the PMNC performance monitor control register // enable bits are 4..6, status bits are 8..10 sources = (sources >> 4) & (sources >> 8); if ( 1 & sources ) return CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL; if ( 2 & sources ) return CYGNUM_HAL_INTERRUPT_PMU_PMN1_OVFL; if ( 4 & sources ) return CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL; } return CYGNUM_HAL_INTERRUPT_reserved0; // This shouldn't happen!}//// Interrupt control//void hal_interrupt_mask(int vector){ int mask = 0; int submask = 0; switch ( vector ) { case CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL: case CYGNUM_HAL_INTERRUPT_PMU_PMN1_OVFL: case CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL: submask = vector - CYGNUM_HAL_INTERRUPT_PMU_PMN0_OVFL; // 0 to 2 // select interrupt enable bit and also enable the perfmon per se submask = (1 << (submask + 4)); // bits 4-6 are masks asm volatile ( "mrc p14,0,r1,c0,c0,0;" "bic r1, r1, #0x700;" // clear the overflow/interrupt flags "bic r1, r1, #0x006;" // clear the reset bits "bic %0, r1, %0;" // preserve r1; better for debugging "tsts %0, #0x070;" // are all 3 sources now off? "biceq %0, %0, #1;" // if so, disable entirely. "mcr p14,0,%0,c0,c0,0;" : : "r"(submask) : "r1" ); mask = 4; break; case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT: // Nothing specific to do here mask = 8; break; case CYGNUM_HAL_INTERRUPT_NIRQ : mask = 2; break; case CYGNUM_HAL_INTERRUPT_NFIQ : mask = 1; break; case CYGNUM_HAL_INTERRUPT_GTSC: *GTMR_REG &= ~1; return; case CYGNUM_HAL_INTERRUPT_PEC: *ESR_REG &= ~(1<<16); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -