1、* set sigreturn to be a pointer to these.memcpy(void *)KERN_SIGRETURN_CODE, sigreturn_codes,sizeof(sigreturn_codes);flush_icache_range(vectors, vectors + PAGE_SIZE);modify_domain(DOMAIN_USER, DOMAIN_CLIENT);init_IRQ对irq进行初始化时,又调用了init_arch_irq对于具体平台体系的中断进行初始化。而init_arch_irq是在start_kernel里调用setup_arc
2、h函数设定的/* arch/arm/kernel/irq.c n */void _init init_IRQ(void)int irq;for (irq = 0; irq init_irq;machine_desc是用于描述平台体系(处理器芯片)的结构体,其定义如下: /* include/asm/mach/arch.h */struct machine_desc * Note! The first four elements are used* by assembler code in head-armv.Sunsigned int nr; /* architecture number */
3、unsigned int phys_io; /* start of physical io */unsigned int io_pg_offst; /* byte offset for io * page tabe entry */const char *name; /* architecture name */unsigned long boot_params; /* tagged list */unsigned int video_start; /* start of video RAM */unsigned int video_end; /* end of video RAM */uns
4、igned int reserve_lp0 :1; /* never has lp0 */unsigned int reserve_lp1 : /* never has lp1 */unsigned int reserve_lp2 : /* never has lp2 */unsigned int soft_reboot : /* soft reboot */void (*fixup)(struct machine_desc *,struct tag *, char *,struct meminfo *);void (*map_io)(void); /* IO mapping function
5、 */void (*init_irq)(void);struct sys_timer *timer; /* system tick timer */void (*init_machine)(void);* Set of macros to define architecture features. This is built into* a table by the linker.#define MACHINE_START(_type,_name) static const struct machine_desc _mach_desc_#_type _used _attribute_(_sec
6、tion_(.arch.info.init) = .nr = MACH_TYPE_#_type, .name = _name,#define MACHINE_END 对于s3c2410处理器芯片,其machine_desc变量的定义如下:/* arch/arm/mach-s3c2410/mach-smdk2410.c */MACHINE_START(SMDK2410, SMDK2410) /* TODO: request a new identifier and switch* to SMDK2410 */* Maintainer: Jonas Dietsche */.phys_io = S3
7、C2410_PA_UART,.io_pg_offst = (u32)S3C24XX_VA_UART) 18) & 0xfffc,.boot_params = S3C2410_SDRAM_PA + 0x100,.map_io = smdk2410_map_io,.init_irq = s3c24xx_init_irq,.init_machine = smdk2410_init,.timer = &s3c24xx_timer,MACHINE_END接下来,我们看看s3c2410处理器芯片的irq初始化函数/* arch/arm/plat-s3c24xx/irq.c */* s3c24xx_init
8、_irq* Initialise S3C2410 IRQ system/* s3c24xx系列芯片中断初始化函数 */void _init s3c24xx_init_irq(void)unsigned long pend;unsigned long last;int irqno;int i;irqdbf(s3c2410_init_irq: clearing interrupt status flagsn);/* first, clear all interrupts pending. */* 清空各个中断请求信号 */last = 0;for (i = 0; i 4; i+) pend = _
9、raw_readl(S3C24XX_EINTPEND);if (pend = 0 | pend = last)break;_raw_writel(pend, S3C24XX_EINTPEND);printk(irq: clearing pending ext status %08xn, (int)pend);last = pend;pend = _raw_readl(S3C2410_INTPND);_raw_writel(pend, S3C2410_SRCPND);_raw_writel(pend, S3C2410_INTPND); clearing pending status %08xnp
10、end = _raw_readl(S3C2410_SUBSRCPND); clearing subpending status %08xn_raw_writel(pend, S3C2410_SUBSRCPND);/* register the main interrupts */* 注册主要中断 */ registering s3c2410 interrupt handlersnfor (irqno = IRQ_EINT4t7; irqno = NR_IRQS)desc = &bad_irq_desc;irq_enter();desc_handle_irq(irq, desc); /* 调用已
11、安装的中断高层流处理函数 */* AT91 specific workaround */irq_finish(irq);irq_exit();set_irq_regs(old_regs);接下来,我们以IRQ_UART2(s3c2410串口2中断)为例,看看中断是如何分流到我们通过request_irq注册的中断处理函数在s3c24xx_init_irq里IRQ_S3CUART_TX2中断的中断高层流处理函数被设置为s3c_irq_demux_uart2。s3c_irq_demux_uart2主要工作是调用s3c_irq_demux_uart对串口中断进行分流处理,因为串口中断包含Rx(接收)
12、中断、Tx(发送)中断和Rx error(接收错误)中断/* arch/arm/plat-s3c2410/irq.c */static void s3c_irq_demux_uart2(unsigned int irq, struct irq_desc *desc)irq = irq;s3c_irq_demux_uart(IRQ_S3CUART_RX2);s3c_irq_demux_uart通过副中断源引脚寄存器的值,判断中断源并执行相应的中断处理函数/* start: 标示发出该中断信号的是哪个uart,即其值应为* IRQ_S3CUART_RX0、IRQ_S3CUART_RX1或IRQ_S
13、3CUART_RX2static void s3c_irq_demux_uart(unsigned int start)unsigned int subsrc, submsk;unsigned int offset = start - IRQ_S3CUART_RX0; /* 获取该UART中断源在副中断屏蔽寄存器中的偏移量 */struct irq_desc *desc;/* read the current pending interrupts, and the mask* for what it is available */subsrc = _raw_readl(S3C2410_SUBS
14、RCPND); /* 读取副中断源引脚寄存器 */submsk = _raw_readl(S3C2410_INTSUBMSK); /* 读取副中断屏蔽寄存器 */irqdbf2(s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08xn,start, offset, subsrc, submsk);subsrc &= submsk; /* 只留下已使能(未屏蔽)的中断源 */subsrc = offset; /* 截取发送中断的uart源到subsrc低3位 */= 7;if (subsrc != 0)desc = irq_desc + start;if (subsrc & 1) /* Rx中断 */desc_handle_irq(start, desc);desc+; 2) /* Tx中断 */desc_handle_irq(start+1, desc); 4) /* Rx error中断 */desc_handle_irq(start+2, desc);desc_handle_irq实际上只是调用了de
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1