Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2634043
  • 博文数量: 333
  • 博客积分: 4817
  • 博客等级: 上校
  • 技术积分: 4413
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-28 10:51
文章分类

全部博文(333)

文章存档

2017年(20)

2016年(57)

2015年(27)

2014年(20)

2013年(21)

2012年(164)

2011年(24)

分类: LINUX

2012-02-20 14:51:20

S3C2410中断的定义的中断向量是从16~47.然后外部中断从48~69.70~80.一共有66(80-16)个中断其中70~78 UART是用来与PC进行通信的。

0125 #define S3C2410_CPUIRQ_OFFSET    (16)
0226
0327 #define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET)
0428
0529 /* main cpu interrupts */
0630 #define IRQ_EINT0      S3C2410_IRQ(0)       /* 16 */
0731 #define IRQ_EINT1      S3C2410_IRQ(1)
0832 #define IRQ_EINT2      S3C2410_IRQ(2)
0933 #define IRQ_EINT3      S3C2410_IRQ(3)
1034 #define IRQ_EINT4t7    S3C2410_IRQ(4)       /* 20 */
1135 #define IRQ_EINT8t23   S3C2410_IRQ(5)
1236 #define IRQ_RESERVED6  S3C2410_IRQ(6)       /* for s3c2410 */
1337 #define IRQ_CAM        S3C2410_IRQ(6)       /* for s3c2440,s3c2443 */
1438 #define IRQ_BATT_FLT   S3C2410_IRQ(7)
1539 #define IRQ_TICK       S3C2410_IRQ(8)       /* 24 */
1640 #define IRQ_WDT        S3C2410_IRQ(9)       /* WDT/AC97 for s3c2443 */
1741 #define IRQ_TIMER0     S3C2410_IRQ(10)
1842 #define IRQ_TIMER1     S3C2410_IRQ(11)
1943 #define IRQ_TIMER2     S3C2410_IRQ(12)
2044 #define IRQ_TIMER3     S3C2410_IRQ(13)
2145 #define IRQ_TIMER4     S3C2410_IRQ(14)
2246 #define IRQ_UART2      S3C2410_IRQ(15)
2347 #define IRQ_LCD        S3C2410_IRQ(16)      /* 32 */
2448 #define IRQ_DMA0       S3C2410_IRQ(17)      /* IRQ_DMA for s3c2443 */
2549 #define IRQ_DMA1       S3C2410_IRQ(18)
2650 #define IRQ_DMA2       S3C2410_IRQ(19)
2751 #define IRQ_DMA3       S3C2410_IRQ(20)
2852 #define IRQ_SDI        S3C2410_IRQ(21)
2953 #define IRQ_SPI0       S3C2410_IRQ(22)
3054 #define IRQ_UART1      S3C2410_IRQ(23)
3155 #define IRQ_RESERVED24 S3C2410_IRQ(24)      /* 40 */
3256 #define IRQ_NFCON      S3C2410_IRQ(24)      /* for s3c2440 */
3357 #define IRQ_USBD       S3C2410_IRQ(25)
3458 #define IRQ_USBH       S3C2410_IRQ(26)
3559 #define IRQ_IIC        S3C2410_IRQ(27)
3660 #define IRQ_UART0      S3C2410_IRQ(28)      /* 44 */
3761 #define IRQ_SPI1       S3C2410_IRQ(29)
3862 #define IRQ_RTC        S3C2410_IRQ(30)
3963 #define IRQ_ADCPARENT  S3C2410_IRQ(31)
0165 /* interrupts generated from the external interrupts sources */
02 66 #define IRQ_EINT4      S3C2410_IRQ(32)     /* 48 */
03 67 #define IRQ_EINT5      S3C2410_IRQ(33)
04 68 #define IRQ_EINT6      S3C2410_IRQ(34)
05 69 #define IRQ_EINT7      S3C2410_IRQ(35)
06 70 #define IRQ_EINT8      S3C2410_IRQ(36)
07 71 #define IRQ_EINT9      S3C2410_IRQ(37)
08 72 #define IRQ_EINT10     S3C2410_IRQ(38)
09 73 #define IRQ_EINT11     S3C2410_IRQ(39)
10 74 #define IRQ_EINT12     S3C2410_IRQ(40)
11 75 #define IRQ_EINT13     S3C2410_IRQ(41)
12 76 #define IRQ_EINT14     S3C2410_IRQ(42)
13 77 #define IRQ_EINT15     S3C2410_IRQ(43)
14 78 #define IRQ_EINT16     S3C2410_IRQ(44)
15 79 #define IRQ_EINT17     S3C2410_IRQ(45)
16 80 #define IRQ_EINT18     S3C2410_IRQ(46)
17 81 #define IRQ_EINT19     S3C2410_IRQ(47)
18 82 #define IRQ_EINT20     S3C2410_IRQ(48)     /* 64 */
19 83 #define IRQ_EINT21     S3C2410_IRQ(49)
20 84 #define IRQ_EINT22     S3C2410_IRQ(50)
21 85 #define IRQ_EINT23     S3C2410_IRQ(51)
22 86
23 87
24 88 #define IRQ_EINT(x)    S3C2410_IRQ((x >= 4) ? (IRQ_EINT4 + (x) - 4) : (S3C2410_IRQ(0) + (x)))
25 89
26 90 #define IRQ_LCD_FIFO   S3C2410_IRQ(52)
27 91 #define IRQ_LCD_FRAME  S3C2410_IRQ(53)
28 98 #define S3C2410_IRQSUB(x)   S3C2410_IRQ((x)+54)
29 99
30100 #define IRQ_S3CUART_RX0     S3C2410_IRQSUB(0)   /* 70 */
31101 #define IRQ_S3CUART_TX0     S3C2410_IRQSUB(1)
32102 #define IRQ_S3CUART_ERR0    S3C2410_IRQSUB(2)
33103
34104 #define IRQ_S3CUART_RX1     S3C2410_IRQSUB(3)   /* 73 */
35105 #define IRQ_S3CUART_TX1     S3C2410_IRQSUB(4)
36106 #define IRQ_S3CUART_ERR1    S3C2410_IRQSUB(5)
37107
38108 #define IRQ_S3CUART_RX2     S3C2410_IRQSUB(6)   /* 76 */
39109 #define IRQ_S3CUART_TX2     S3C2410_IRQSUB(7)
40110 #define IRQ_S3CUART_ERR2    S3C2410_IRQSUB(8)
41111
42112 #define IRQ_TC          S3C2410_IRQSUB(9)
43113 #define IRQ_ADC         S3C2410_IRQSUB(10)
44114
45115 /* extra irqs for s3c2440 */
46...

那么前16就是trap了。
这些中断向量的初始化是由

001661 void __init s3c24xx_init_irq(void)
002662 {
003663     unsigned long pend;
004664     unsigned long last;
005665     int irqno;
006666     int i;
007667
008668     irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
009669
010670     /* first, clear all interrupts pending... */
011671
012672     last = 0;
013673     for (i = 0; i < 4; i++) {
014674         pend = __raw_readl(S3C24XX_EINTPEND);
015675
016676         if (pend == 0 || pend == last)
017677             break;
018678
019679         __raw_writel(pend, S3C24XX_EINTPEND);
020680         printk("irq: clearing pending ext status %08x\n", (int)pend);
021681         last = pend;
022682     }
023683
024684     last = 0;
025685     for (i = 0; i < 4; i++) {
026686         pend = __raw_readl(S3C2410_INTPND);
027687
028688         if (pend == 0 || pend == last)
029689             break;
030690
031691         __raw_writel(pend, S3C2410_SRCPND);
032692         __raw_writel(pend, S3C2410_INTPND);
033693         printk("irq: clearing pending status %08x\n", (int)pend);
034694         last = pend;
035695     }
036696
037697     last = 0;
038698     for (i = 0; i < 4; i++) {
039699         pend = __raw_readl(S3C2410_SUBSRCPND);
040700
041701         if (pend == 0 || pend == last)
042702             break;
043703
044704         printk("irq: clearing subpending status %08x\n", (int)pend);
045705         __raw_writel(pend, S3C2410_SUBSRCPND);
046706         last = pend;
047707     }
048708
049709     /* register the main interrupts */
050710
051711     irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
052712
053713     for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
054714         /* set all the s3c2410 internal irqs */
055715
056716         switch (irqno) {
057717             /* deal with the special IRQs (cascaded) */
058718
059719         case IRQ_EINT4t7:
060720         case IRQ_EINT8t23:
061721         case IRQ_UART0:
062722         case IRQ_UART1:
063723         case IRQ_UART2:
064724         case IRQ_ADCPARENT:
065725             set_irq_chip(irqno, &s3c_irq_level_chip);
066726             set_irq_handler(irqno, handle_level_irq);
067727             break;
068728
069729         case IRQ_RESERVED6:
070730         case IRQ_RESERVED24:
071731             /* no IRQ here */
072732             break;
073733
074734         default:
075735             //irqdbf("registering irq %d (s3c irq)\n", irqno);
076736             set_irq_chip(irqno, &s3c_irq_chip);
077737             set_irq_handler(irqno, handle_edge_irq);
078738             set_irq_flags(irqno, IRQF_VALID);
079739         }
080740     }
081741
082742     /* setup the cascade irq handlers */
083743
084744     set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
085745     set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
086746
087747     set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
088748     set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
089749     set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
090750     set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
091751
092752     /* external interrupts */
093753
094754     for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
095755         irqdbf("registering irq %d (ext int)\n", irqno);
096756         set_irq_chip(irqno, &s3c_irq_eint0t4);
097757         set_irq_handler(irqno, handle_edge_irq);
098758         set_irq_flags(irqno, IRQF_VALID);
099759     }
100760
101761     for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
102762         irqdbf("registering irq %d (extended s3c irq)\n", irqno);
103763         set_irq_chip(irqno, &s3c_irqext_chip);
104764         set_irq_handler(irqno, handle_edge_irq);
105765         set_irq_flags(irqno, IRQF_VALID);
106766     }
107767
108768     /* register the uart interrupts */
109769
110770     irqdbf("s3c2410: registering external interrupts\n");
111771
112772     for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
113773         irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
114774         set_irq_chip(irqno, &s3c_irq_uart0);
115775         set_irq_handler(irqno, handle_level_irq);
116776         set_irq_flags(irqno, IRQF_VALID);
117777     }
118778
119779     for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
120780         irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
121781         set_irq_chip(irqno, &s3c_irq_uart1);
122782         set_irq_handler(irqno, handle_level_irq);
123783         set_irq_flags(irqno, IRQF_VALID);
124784     }
125785
126786     for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
127787         irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
128788         set_irq_chip(irqno, &s3c_irq_uart2);
129789         set_irq_handler(irqno, handle_level_irq);
130790         set_irq_flags(irqno, IRQF_VALID);
131791     }
132792
133793     for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
134794         irqdbf("registering irq %d (s3c adc irq)\n", irqno);
135795         set_irq_chip(irqno, &s3c_irq_adc);
136796         set_irq_handler(irqno, handle_edge_irq);
137797         set_irq_flags(irqno, IRQF_VALID);
138798     }
139799
140800     irqdbf("s3c2410: registered interrupt handlers\n");
141801 }

上面便是对中断向量进行赋值了。其中set_irq_chip是设置irq上的中断控制器。set_irq_handle便是设置该中断线上的处理函数了,比如ack mark之类的。set_irq_flags是设置该中断线的标志位,有哪些呢?

0149 #define IRQ_INPROGRESS      0x00000100  /* IRQ handler active - do not enter! */
0250 #define IRQ_DISABLED        0x00000200  /* IRQ disabled - do not enter! */
0351 #define IRQ_PENDING     0x00000400  /* IRQ pending - replay on enable */
0452 #define IRQ_REPLAY      0x00000800  /* IRQ has been replayed but not acked yet */
0553 #define IRQ_AUTODETECT      0x00001000  /* IRQ is being autodetected */
0654 #define IRQ_WAITING     0x00002000  /* IRQ not yet seen - for autodetection */
0755 #define IRQ_LEVEL       0x00004000  /* IRQ level triggered */
0856 #define IRQ_MASKED      0x00008000  /* IRQ masked - shouldn't be seen again */
0957 #define IRQ_PER_CPU     0x00010000  /* IRQ is per CPU */
1058 #define IRQ_NOPROBE     0x00020000  /* IRQ is not valid for probing */
1159 #define IRQ_NOREQUEST       0x00040000  /* IRQ cannot be requested */
1260 #define IRQ_NOAUTOEN        0x00080000  /* IRQ will not be enabled on request irq */
1361 #define IRQ_WAKEUP      0x00100000  /* IRQ triggers system wakeup */
1462 #define IRQ_MOVE_PENDING    0x00200000  /* need to re-target IRQ destination */
1563 #define IRQ_NO_BALANCING    0x00400000  /* IRQ is excluded from balancing */

另外set_irq_handler我们来看一下:

01534 void
02535 __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
03536           const char *name)
04537 {
05538     struct irq_desc *desc;
06539     unsigned long flags;
07540
08541     if (irq >= NR_IRQS) {
09542         printk(KERN_ERR
10543                "Trying to install type control for IRQ%d\n", irq);
11544         return;
12545     }
13546
14547     desc = irq_desc + irq;
15548
16549     if (!handle)              //如果形参handle没有被赋值,那么先将之赋值为handle_bad_irq.在后面567行我们会看到,实际上是会执行卸载操作
17550         handle = handle_bad_irq;
18551     else if (desc->chip == &no_irq_chip) {
19552         printk(KERN_WARNING "Trying to install %sinterrupt handler "
20553                "for IRQ%d\n", is_chained ? "chained " : "", irq);
21554         /*
22555          * Some ARM implementations install a handler for really dumb
23556          * interrupt hardware without setting an irq_chip. This worked
24557          * with the ARM no_irq_chip but the check in setup_irq would
25558          * prevent us to setup the interrupt at all. Switch it to
26559          * dummy_irq_chip for easy transition.
27560          */
28561         desc->chip = &dummy_irq_chip;
29562     }
30563
31564     spin_lock_irqsave(&desc->lock, flags);
32565
33566     /* Uninstall? */
34567     if (handle == handle_bad_irq) {
35568         if (desc->chip != &no_irq_chip)
36569             mask_ack_irq(desc, irq);
37570         desc->status |= IRQ_DISABLED;
38571         desc->depth = 1;
39572     }
40573     desc->handle_irq = handle;
41574     desc->name = name;

另外,现在已经设置好中断向量了,那么这些中断向量在哪里放着呢?因为如果要响应中断的话,必须找到入口啊。
看一下trap_init函数:

01678 void __init trap_init(void)
02679 {
03680     unsigned long vectors = CONFIG_VECTORS_BASE;
04681     extern char __stubs_start[], __stubs_end[];
05682     extern char __vectors_start[], __vectors_end[];
06683     extern char __kuser_helper_start[], __kuser_helper_end[];
07684     int kuser_sz = __kuser_helper_end - __kuser_helper_start;
08685
09686     /*
10687      * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
11688      * into the vector page, mapped at 0xffff0000, and ensure these
12689      * are visible to the instruction stream.
13690      */
14691     memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
15692     memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
16693     memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
17694
18695     /*
19696      * Copy signal return handlers into the vector page, and
20697      * set sigreturn to be a pointer to these.
21698      */
22699     memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
23700            sizeof(sigreturn_codes));
24701
25702     flush_icache_range(vectors, vectors + PAGE_SIZE);
26703     modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
27704 }

看到了吧,将__vectors_start~__vectors_end还有stub都移到了vector的位置,而vector的位置既是 CONFIG_VECTORS_BASE,

1147 #define CONFIG_VECTORS_BASE 0xffff0000

那么__vector_start在哪里捏?
~/linux-2.6.21.1/arch/arm/kernel/entry-armv.S

1062 __vectors_start: 1063 swi SYS_ERROR0 1064 b vector_und + stubs_offset 1065 ldr pc, .LCvswi + stubs_offset 1066 b vector_pabt + stubs_offset 1067 b vector_dabt + stubs_offset 1068 b vector_addrexcptn + stubs_offset 1069 b vector_irq + stubs_offset 1070 b vector_fiq + stubs_offset 1071 1072 .globl __vectors_end 1073 __vectors_end:

在该文件,我们也可以找到__stub_start的变量地址。

阅读(993) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~