⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iq80310_misc.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 3 页
字号:
    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;"
        "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 support

static 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 + -