📄 iq80310_misc.c
字号:
case CYGNUM_HAL_INTERRUPT_AAIP: *ADCR_REG &= ~1; return; case CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY...CYGNUM_HAL_INTERRUPT_I2C_ADDRESS: *ICR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY)); return; case CYGNUM_HAL_INTERRUPT_MESSAGE_0...CYGNUM_HAL_INTERRUPT_INDEX_REGISTER: *IIMR_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0)); return; case CYGNUM_HAL_INTERRUPT_BIST: *ATUCR_REG &= ~(1<<3); return; case CYGNUM_HAL_INTERRUPT_P_SERR: // FIQ *ATUCR_REG &= ~(1<<9); return; case CYGNUM_HAL_INTERRUPT_S_SERR: // FIQ *ATUCR_REG &= ~(1<<10); return; case CYGNUM_HAL_INTERRUPT_TIMER...CYGNUM_HAL_INTERRUPT_PCI_S_INTD: *X3MASK_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_TIMER)); return; // The hardware doesn't (yet?) provide masking or status for these // even though they can trigger cpu interrupts. ISRs will need to // poll the device to see if the device actually triggered the // interrupt. case CYGNUM_HAL_INTERRUPT_PCI_S_INTC: case CYGNUM_HAL_INTERRUPT_PCI_S_INTB: case CYGNUM_HAL_INTERRUPT_PCI_S_INTA: default: /* do nothing */ return; } asm volatile ( "mrc p13,0,r1,c0,c0,0;" "bic r1, r1, %0;" "mcr p13,0,r1,c0,c0,0;" : : "r"(mask) : "r1" );}void hal_interrupt_unmask(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 + (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 "orr %0, r1, %0;" // preserve r1; better for debugging "mcr p14,0,%0,c0,c0,0;" "mrc p13,0,r2,c8,c0,0;" // steer PMU interrupt to IRQ "and r2, r2, #2;" // preserve the other bit (BCU steer) "mcr p13,0,r2,c8,c0,0;" : : "r"(submask) : "r1","r2" ); mask = 4; break; case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT: asm volatile ( "mrc p13,0,r2,c8,c0,0;" // steer BCU interrupt to IRQ "and r2, r2, #1;" // preserve the other bit (PMU steer) "mcr p13,0,r2,c8,c0,0;" : : : "r2" ); 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; case CYGNUM_HAL_INTERRUPT_AAIP: *ADCR_REG |= 1; return; case CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY...CYGNUM_HAL_INTERRUPT_I2C_ADDRESS: *ICR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_I2C_TX_EMPTY)); return; case CYGNUM_HAL_INTERRUPT_MESSAGE_0...CYGNUM_HAL_INTERRUPT_INDEX_REGISTER: *IIMR_REG |= (1<<(vector - CYGNUM_HAL_INTERRUPT_MESSAGE_0)); return; case CYGNUM_HAL_INTERRUPT_BIST: *ATUCR_REG |= (1<<3); return; case CYGNUM_HAL_INTERRUPT_P_SERR: // FIQ *ATUCR_REG |= (1<<9); return; case CYGNUM_HAL_INTERRUPT_S_SERR: // FIQ *ATUCR_REG |= (1<<10); return; case CYGNUM_HAL_INTERRUPT_TIMER...CYGNUM_HAL_INTERRUPT_PCI_S_INTD: *X3MASK_REG &= ~(1<<(vector - CYGNUM_HAL_INTERRUPT_TIMER)); return; // The hardware doesn't (yet?) provide masking or status for these // even though they can trigger cpu interrupts. ISRs will need to // poll the device to see if the device actually triggered the // interrupt. case CYGNUM_HAL_INTERRUPT_PCI_S_INTC: case CYGNUM_HAL_INTERRUPT_PCI_S_INTB: case CYGNUM_HAL_INTERRUPT_PCI_S_INTA: default: /* do nothing */ return; } asm volatile ( "mrc p13,0,r1,c0,c0,0;" "orr %0, r1, %0;" "mcr p13,0,%0,c0,c0,0;" : : "r"(mask) : "r1" );}void hal_interrupt_acknowledge(int vector){ 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 + 8)); // bits 8-10 are status; write 1 clr // Careful not to ack other interrupts or zero any counters: 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 "orr %0, r1, %0;" // preserve r1; better for debugging "mcr p14,0,%0,c0,c0,0;" : : "r"(submask) : "r1" ); break; case CYGNUM_HAL_INTERRUPT_BCU_INTERRUPT: case CYGNUM_HAL_INTERRUPT_NIRQ : case CYGNUM_HAL_INTERRUPT_NFIQ : default: /* do nothing */ return; }}void hal_interrupt_configure(int vector, int level, int up){}void hal_interrupt_set_level(int vector, int level){}#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS/*------------------------------------------------------------------------*/// HW Debug supportstatic inline void set_ibcr0(unsigned x){ asm volatile ("mcr p15,0,%0,c14,c8,0" : : "r"(x) );}static inline unsigned get_ibcr0(void){ unsigned x; asm volatile ("mrc p15,0,%0,c14,c8,0" : "=r"(x) : ); return x;}static inline void set_ibcr1(unsigned x){ asm volatile ("mcr p15,0,%0,c14,c9,0" : : "r"(x) );}static inline unsigned get_ibcr1(void){ unsigned x; asm volatile ("mrc p15,0,%0,c14,c9,0" : "=r"(x) : ); return x;}static inline void set_dbr0(unsigned x){ asm volatile ("mcr p15,0,%0,c14,c0,0" : : "r"(x) );}static inline unsigned get_dbr0(void){ unsigned x; asm volatile ("mrc p15,0,%0,c14,c0,0" : "=r"(x) : ); return x;}static inline void set_dbr1(unsigned x){ asm volatile ("mcr p15,0,%0,c14,c3,0" : : "r"(x) );}static inline unsigned get_dbr1(void){ unsigned x; asm volatile ("mrc p15,0,%0,c14,c3,0" : "=r"(x) : ); return x;}static inline void set_dbcon(unsigned x){ asm volatile ("mcr p15,0,%0,c14,c4,0" : : "r"(x) );}static inline unsigned get_dbcon(void){ unsigned x; asm volatile ("mrc p15,0,%0,c14,c4,0" : "=r"(x) : ); return x;}static inline void set_dcsr(unsigned x){ asm volatile ("mcr p14,0,%0,c10,c0,0" : : "r"(x) );}static inline unsigned get_dcsr(void){ unsigned x; asm volatile ("mrc p14,0,%0,c10,c0,0" : "=r"(x) : ); return x;}int cyg_hal_plf_hw_breakpoint(int setflag, void *vaddr, int len){ unsigned int addr = (unsigned)vaddr; if (setflag) { if (!(get_ibcr0() & 1)) set_ibcr0(addr | 1); else if (!(get_ibcr1() & 1)) set_ibcr1(addr | 1); else return -1; } else { unsigned x = (addr | 1); if (get_ibcr0() == x) set_ibcr0(0); else if (get_ibcr0() == x) set_ibcr1(0); else return -1; } return 0;}int cyg_hal_plf_hw_watchpoint(int setflag, void *vaddr, int len, int type){ unsigned int mask, bit_nr, mode, addr = (unsigned)vaddr; unsigned dbcon = get_dbcon(); mask = 0x80000000; bit_nr = 31; while (bit_nr) { if (len & mask) break; bit_nr--; mask >>= 1; } mask = ~(0xffffffff << bit_nr); if (setflag) { /* set a watchpoint */ if (type == 2) mode = 1; // break on write else if (type == 3) mode = 3; // break on read else if (type == 4) mode = 2; // break on any access else return 1; if (!(dbcon & 3)) { set_dbr0(addr); set_dbr1(mask); set_dbcon(dbcon | mode | 0x100); } else return 1; } else { /* clear a watchpoint */ if (dbcon & 3) set_dbcon(dbcon & ~3); else return 1; } return 0;}// Return indication of whether or not we stopped because of a// watchpoint or hardware breakpoint. If stopped by a watchpoint,// also set '*data_addr_p' to the data address which triggered the// watchpoint.int cyg_hal_plf_is_stopped_by_hardware(void **data_addr_p){ unsigned fsr, dcsr, dbcon, kind = 0; // Check for debug event asm volatile ("mrc p15,0,%0,c5,c0,0" : "=r"(fsr) : ); if ((fsr & 0x200) == 0) return HAL_STUB_HW_STOP_NONE; // There was a debug event. Check the MOE for details dcsr = get_dcsr(); switch ((dcsr >> 2) & 7) { case 1: // HW breakpoint case 3: // BKPT breakpoint return HAL_STUB_HW_STOP_BREAK; case 2: // Watchpoint dbcon = get_dbcon(); if (dbcon & 0x100) { // dbr1 is used as address mask kind = dbcon & 3; *data_addr_p = (void *)get_dbr0(); } if (kind == 1) return HAL_STUB_HW_STOP_WATCH; if (kind == 2) return HAL_STUB_HW_STOP_AWATCH; if (kind == 3) return HAL_STUB_HW_STOP_RWATCH; // should never get here break; } return HAL_STUB_HW_STOP_NONE;}#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS/*------------------------------------------------------------------------*/// EOF iq80310_misc.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -