📄 iq80310_misc.c
字号:
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 + -