📄 em86xxapi.c
字号:
if (icache > 0) reg |= 0x1000; else if (icache == 0) { reg &= ~0x1000; em86xx_flush_cache_data(); } if (dcache > 0) reg |= 0x0004; else if (dcache == 0) { reg &= ~0x0004; em86xx_flush_cache_data(); } if (writeback > 0) reg |= 0x0002; else if (writeback == 0) { reg &= ~0x0002; em86xx_clean_cache_data(); } __asm__ __volatile__ ( "mcr p15, 0, %0, c1, c0, 0\n" : : "r" (reg) );}void em86xx_clean_cache_data(void){ __asm__( "mcr p15, 0, %0, c7, c10, 0\n" // clean data : : "r" (0) );}void em86xx_clean_cache_data_region(unsigned int from, unsigned int to){ unsigned int flag; from &= ~0x0f; to &= ~0x0f; flag = em86xx_saveflag_cli(); for (; from <= to; from += 0x10) { __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 1\n" // clean data : : "r" (from) ); } em86xx_restoreflag(flag);}void em86xx_invalidate_cache_instruction(void){ unsigned int flag; flag = em86xx_saveflag_cli(); __asm__( "mcr p15, 0, %0, c7, c10, 0\n" // clean data "mcr p15, 0, %0, c7, c5, 0\n" // invalidate instruction : : "r" (0) ); em86xx_restoreflag(flag);}void em86xx_invalidate_cache_instruction_region(unsigned int from, unsigned int to){ unsigned int flag; from &= ~0x0f; to &= ~0x0f; flag = em86xx_saveflag_cli(); for (; from <= to; from += 0x10) { __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 1\n" // clean data "mcr p15, 0, %0, c7, c5, 1\n" // invalidate instruction : : "r" (from) ); } em86xx_restoreflag(flag);}void em86xx_invalidate_cache_data(void){ __asm__( "mcr p15, 0, %0, c7, c6, 0\n" // invalidate data : : "r" (0) );}void em86xx_invalidate_cache_data_region(unsigned int from, unsigned int to){ unsigned int flag; from &= ~0x0f; to &= ~0x0f; if (from < MEMORY_BASE_DRAMCTRL0) return; flag = em86xx_saveflag_cli(); for (; from <= to; from += 0x10) { __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c6, 1\n" // invalidate data : : "r" (from) ); } em86xx_restoreflag(flag);}void em86xx_flush_cache_all(void){ unsigned int flag; flag = em86xx_saveflag_cli(); __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 0\n" // clean data cache "mcr p15, 0, %0, c7, c5, 0\n" // invalidate instruction cache "mcr p15, 0, %0, c7, c6, 0\n" // invalidate data cache : : "r" (0) ); em86xx_restoreflag(flag);}void em86xx_flush_cache_data(void){ unsigned int flag; flag = em86xx_saveflag_cli(); __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 0\n" // clean data cache "mcr p15, 0, %0, c7, c6, 0\n" // invalidate data cache : : "r" (0) ); em86xx_restoreflag(flag);}void em86xx_flush_cache_data_region(unsigned int from, unsigned int to){ unsigned int flag; from &= ~0x0f; to &= ~0x0f; if (from < MEMORY_BASE_DRAMCTRL0) return; flag = em86xx_saveflag_cli(); for (; from <= to; from += 0x10) { __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 1\n" // clean data cache "mcr p15, 0, %0, c7, c6, 1\n" // invalidate data cache : : "r" (from) ); } em86xx_restoreflag(flag);}// // interrupt / fast interrupt control//void em86xx_irq_init(void){#if defined(CONFIG_ARCH_TANGO15) && (CONFIG_ARCH_TANGO15_REV > 1) /* Tango15 Rev B or above */ /* Disable all interrupts initially. */ __raw_writel(0xffffffff, REG_BASE_CPU + CPU_irq_enableclr); __raw_writel(0xffffffff, REG_BASE_CPU + CPU_fiq_enableclr); __raw_writel(0xffffffff, REG_BASE_CPU + CPU_irq_enableclr_hi); __raw_writel(0xffffffff, REG_BASE_CPU + CPU_fiq_enableclr_hi); /* Disable edge detector */ __raw_writel(IRQMASK_RISINGEDGE & 0xffffffff, REG_BASE_CPU + CPU_edge_config_rise); __raw_writel(IRQMASK_FALLINGEDGE & 0xffffffff, REG_BASE_CPU + CPU_edge_config_fall); __raw_writel((IRQMASK_RISINGEDGE>>32) & 0xffffffff, REG_BASE_CPU + CPU_edge_config_rise_hi); __raw_writel((IRQMASK_FALLINGEDGE>>32) & 0xffffffff, REG_BASE_CPU + CPU_edge_config_fall_hi); __raw_writel(__raw_readl(REG_BASE_CPU + CPU_edge_rawstat), REG_BASE_CPU + CPU_edge_rawstat); __raw_writel(__raw_readl(REG_BASE_CPU + CPU_edge_rawstat_hi), REG_BASE_CPU + CPU_edge_rawstat_hi);#else /* Disable all interrupts initially. */ __raw_writel(0xffffffff, REG_BASE_CPU + CPU_irq_enableclr); __raw_writel(0xffffffff, REG_BASE_CPU + CPU_fiq_enableclr); /* Disable edge detector */ __raw_writel(IRQMASK_RISINGEDGE, REG_BASE_CPU + CPU_edge_config_rise); __raw_writel(IRQMASK_FALLINGEDGE, REG_BASE_CPU + CPU_edge_config_fall); __raw_writel(__raw_readl(REG_BASE_CPU + CPU_edge_rawstat), REG_BASE_CPU + CPU_edge_rawstat);#endif}#if defined(CONFIG_ARCH_TANGO15) && (CONFIG_ARCH_TANGO15_REV > 1) /* Tango15 Rev B or above */#define EM86XX_X_MASK(x) \ void em86xx_mask_##x(unsigned int irq) \ { \ unsigned int reg, mask; \ unsigned int flag = em86xx_saveflag_clif(); \ \ if (irq >= 32) { \ reg = (1 << (irq - 32)); \ mask = (unsigned int)(((IRQMASK_RISINGEDGE | IRQMASK_FALLINGEDGE)>>32) & 0xffffffff); \ __raw_writel(reg, REG_BASE_CPU + CPU_##x##_enableclr_hi); \ /* if the interrupt is detected by edge detector not level detector */ \ /* clear edge status */ \ if ((reg & mask) != 0) \ __raw_writel(reg, REG_BASE_CPU + CPU_edge_rawstat_hi); \ } else { \ reg = (1 << irq); \ mask = (unsigned int)((IRQMASK_RISINGEDGE | IRQMASK_FALLINGEDGE) & 0xffffffff); \ __raw_writel(reg, REG_BASE_CPU + CPU_##x##_enableclr); \ /* if the interrupt is detected by edge detector not level detector */ \ /* clear edge status */ \ if ((reg & mask) != 0) \ __raw_writel(reg, REG_BASE_CPU + CPU_edge_rawstat); \ } \ em86xx_restoreflag(flag); \ } #define EM86XX_X_UNMASK(x) \ void em86xx_unmask_##x(unsigned int irq) \ { \ unsigned int flag = em86xx_saveflag_clif(); \ \ /* IRQ / FIQ enable */ \ if (irq >= 32) \ __raw_writel(1 << (irq - 32), REG_BASE_CPU + CPU_##x##_enableset_hi); \ else \ __raw_writel(1 << irq, REG_BASE_CPU + CPU_##x##_enableset); \ em86xx_restoreflag(flag); \ }#define EM86XX_X_STATUS(x) \ int em86xx_##x##_status(unsigned int irq) \ { \ unsigned int status, mask; \ \ if (irq >= 32) { \ mask = (1 << (irq - 32)); \ status = __raw_readl(REG_BASE_CPU + CPU_##x##_rawstat_hi); \ } else { \ mask = (1 << irq); \ status = __raw_readl(REG_BASE_CPU + CPU_##x##_rawstat); \ } \ \ return((status & mask) ? 1 : 0); \ }#define EM86XX_X_WAIT(x) \ void em86xx_##x##_wait(unsigned int irq) \ { \ unsigned int mask; \ \ if (irq >= 32) { \ mask = (1 << (irq - 32)); \ while((__raw_readl(REG_BASE_CPU + CPU_##x##_rawstat_hi) & mask) == 0) \ ; \ } else { \ mask = (1 << irq); \ while((__raw_readl(REG_BASE_CPU + CPU_##x##_rawstat) & mask) == 0) \ ; \ } \ }#else#define EM86XX_X_MASK(x) \ void em86xx_mask_##x(unsigned int irq) \ { \ unsigned int reg = IRQMASKOF(irq); \ unsigned int flag = em86xx_saveflag_clif(); \ \ /* IRQ / FIQ disable */ \ __raw_writel(reg, REG_BASE_CPU + CPU_##x##_enableclr); \ \ /* if the interrupt is detected by edge detector not level detector */ \ /* clear edge status */ \ if ((reg & (IRQMASK_RISINGEDGE | IRQMASK_FALLINGEDGE)) != 0) \ __raw_writel(reg, REG_BASE_CPU + CPU_edge_rawstat); \ em86xx_restoreflag(flag); \ } #define EM86XX_X_UNMASK(x) \ void em86xx_unmask_##x(unsigned int irq) \ { \ unsigned int reg = IRQMASKOF(irq); \ unsigned int flag = em86xx_saveflag_clif(); \ \ /* IRQ / FIQ enable */ \ __raw_writel(reg, REG_BASE_CPU + CPU_##x##_enableset); \ em86xx_restoreflag(flag); \ }#define EM86XX_X_STATUS(x) \ int em86xx_##x##_status(unsigned int irq) \ { \ unsigned int status = __raw_readl(REG_BASE_CPU + CPU_##x##_rawstat); \ \ return (status & IRQMASKOF(irq)) ? 1 : 0; \ }#define EM86XX_X_WAIT(x) \ void em86xx_##x##_wait(unsigned int irq) \ { \ unsigned int mask = IRQMASKOF(irq); \ \ while ((__raw_readl(REG_BASE_CPU + CPU_##x##_rawstat) & mask) == 0) \ ; \ }#endifEM86XX_X_MASK(irq)EM86XX_X_UNMASK(irq)EM86XX_X_STATUS(irq)EM86XX_X_WAIT(irq)EM86XX_X_MASK(fiq)EM86XX_X_UNMASK(fiq)EM86XX_X_STATUS(fiq)EM86XX_X_WAIT(fiq)// // interrupt handler//static struct { irq_handler_t handler; void *pdata;} s_irq_info[NR_IRQS];void em86xx_sti(void){ unsigned int cpsr_reg; __asm__ __volatile__( "mrs %0, cpsr\n" // get CPSR "bic %0, %0, #0x80\n" // enable IRQ "msr cpsr_c, %0\n" // set CPSR : "=r" (cpsr_reg) : : "memory");}void em86xx_cli(void){ unsigned int cpsr_reg; __asm__ __volatile__( "mrs %0, cpsr\n" // get CPSR "orr %0, %0, #0x80\n" // disable IRQ "msr cpsr_c, %0\n" // set CPSR : "=r" (cpsr_reg) : : "memory");}int em86xx_irqenabled(void){ unsigned int cpsr_reg; __asm__ __volatile__( "mrs %0, cpsr\n" // get CPSR : "=r" (cpsr_reg)); return (cpsr_reg & 0x80) ? 0 : 1;}void em86xx_request_irq(int irq, irq_handler_t handler, void *pdata){ s_irq_info[irq].handler = handler; s_irq_info[irq].pdata = pdata; em86xx_unmask_irq(irq);}void em86xx_free_irq(int irq){ em86xx_mask_irq(irq); s_irq_info[irq].handler = NULL; s_irq_info[irq].pdata = NULL;}void em86xx_irq_handler(void){ int i; unsigned int mask; unsigned int status = __raw_readl(REG_BASE_CPU + CPU_irq_status); for (i = 0, mask = 1; status != 0; ++i, mask <<= 1) { if (status & mask) { status &= ~mask; em86xx_mask_irq(i); /* If no handler, left it masked */ if (s_irq_info[i].handler) { s_irq_info[i].handler(i, s_irq_info[i].pdata); em86xx_unmask_irq(i); } } }}// // fast interrupt handler//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -