[Armadillo:05595] Re: Armadillo-9 の割り込みのフリップフロップ
Tomohiro NAMITSUKA
email@hidden
2010年 8月 6日 (金) 18:55:40 JST
波塚です。
Armadillo-9のハードウェアマニュアルに記載しているFFは、
ご指摘の通りエッジ検出と保持を行っております。
この概略図や割り込みコントローラの説明が不足しておりました。
実際には、
IMRが"1"の場合に、割り込み入力のマスクと同時にISRの値をクリアする処理も含まれています。
次回のマニュアルアップデートで、
概略図の修正や説明追記を行いたいと思います。
(2010/08/06 3:15), Yasuhisa Nakamura wrote:
> MLの皆様、お世話になってます。
> 中村です。
>
> Armadillo-9の割り込みについての質問(疑問)です。
> ちょっと長いメールです。
>
> ハードウェアマニュアルの最後に「PC/104の割り込みコントローラの仕組み」
> という図解があります。
>
> ・ここに記載されているFFは、どのようなFFでしょうか?
> ・このFFは説明のとおりに動いているのでしょうか?
>
> arch/arm/mach-ep93xx/irq.cにprintk()をいくつか挿入して挙動を
> 調べてみたのですが、どうも、説明通りには動いていないような
> 気がしてなりません。
>
>
> 調査は次のような方法で行いました。
>
>
> ■ハードウェア:
> ・Armadillo-9 単体
> ・PC/104バスのIRQ3(B25)とGND(B32)からリード線を引き出す。
> ・このリード線を短絡してIRQ3をLowに落とす。
>
>
> ■arch/arm/mach-ep93xx/irq.c に次のパッチ
>
> --- irq.c-orig 2008-06-17 17:33:48.000000000 +0900
> +++ irq.c 2010-08-06 02:02:44.000000000 +0900
> @@ -134,25 +134,35 @@
>
> static void mask_irq_intisa3 (unsigned int irq)
> {
> + printk("mask_irq_intisa3: irq=%d\n", irq);
> + printk("mask_irq_intisa3: now: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3& 0xf);
> miscreg_intmr3 |= 1<< (irq - IRQ_ISA_BASE);
> MISCREG_INTMR3 = miscreg_intmr3;
> + printk("mask_irq_intisa3: masked: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3& 0xf);
> }
>
> static void mask_ack_irq_intisa3 (unsigned int irq)
> {
> u8 mask;
>
> + printk("mask_ack_irq_intisa3: irq=%d\n", irq);
> + printk("mask_ack_irq_intisa3: now: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3&
> 0xf);
> mask = 1<< (irq - IRQ_ISA_BASE);
> miscreg_intmr3 |= mask;
> MISCREG_INTMR3 = miscreg_intmr3;
> + printk("mask_ack_irq_intisa3: masked: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3&
> 0xf);
>
> MISCREG_INTCR3 = mask;
> + printk("mask_ack_irq_intisa3: cleared: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3&
> 0xf);
> }
>
> static void unmask_irq_intisa3 (unsigned int irq)
> {
> + printk("unmask_irq_intisa3: irq=%d\n", irq);
> + printk("unmask_irq_intisa3: now: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3&
> 0xf);
> miscreg_intmr3&= ~(1<< (irq - IRQ_ISA_BASE));
> MISCREG_INTMR3 = miscreg_intmr3;
> + printk("unmask_irq_intisa3: unmasked: MISCREG_INTSR3=0x%x\n", MISCREG_INTSR3&
> 0xf);
> }
>
> static struct irqaction irq_isa = {
>
>
> ■テスト用のドライバ
> [Armadillo:00993] のものを流用させていただきました。
> 主要部分は次の通りです。
>
> static irqreturn_t ep93xx_isa3_isr(int irq, void *dev_id, struct pt_regs *regs)
> {
> printk("isa3_isr: irq=%d, dev_id=%s\n", irq, (char *)dev_id);
> printk("isa3_isr: end\n");
> return IRQ_HANDLED;
> }
>
> int __init pc104port_init(void)
> {
> int ret;
>
> printk("pc104port init:\n");
> ret = request_irq(IRQ_ISA3, ep93xx_isa3_isr, 0 /*SA_INTERRUPT*/, "isa3_isr", 0);
> printk("pc104port request_irq ret = %d\n", ret);
> printk("pc104port init: end\n");
> return 0;
> }
>
> void __exit pc104port_exit(void)
> {
> free_irq(IRQ_ISA3,0);
> }
>
> module_init(pc104port_init);
> module_exit(pc104port_exit);
>
>
> ■実行結果
>
> insmodしたときのメッセージ
>
> pc104port init:
> unmask_irq_intisa3: irq=64
> unmask_irq_intisa3: now: MISCREG_INTSR3=0x0
> unmask_irq_intisa3: unmasked: MISCREG_INTSR3=0x0
> pc104port request_irq ret = 0
> pc104port init: end
>
>
> 次にPC/104バスのIRQ3から引き出して、IRQ3をGNDに落としている
> リード線を解放する(IRQ3=Highになる)と、割り込みが連続的に発生。
>
> 大量にメッセージがでますが、そのうちの一部(チャタリングが
> なさそうなところ)は次のようになります。
>
> ....
> ....
> mask_ack_irq_intisa3: irq=64
> mask_ack_irq_intisa3: now: MISCREG_INTSR3=0x1
> mask_ack_irq_intisa3: masked: MISCREG_INTSR3=0x0
> mask_ack_irq_intisa3: cleared: MISCREG_INTSR3=0x0
> isa3_isr: irq=64, dev_id=<NULL>
> isa3_isr: end
> unmask_irq_intisa3: irq=64
> unmask_irq_intisa3: now: MISCREG_INTSR3=0x0
> unmask_irq_intisa3: unmasked: MISCREG_INTSR3=0x1
> mask_ack_irq_intisa3: irq=64
> mask_ack_irq_intisa3: now: MISCREG_INTSR3=0x1
> mask_ack_irq_intisa3: masked: MISCREG_INTSR3=0x0
> mask_ack_irq_intisa3: cleared: MISCREG_INTSR3=0x0
> isa3_isr: irq=64, dev_id=<NULL>
> isa3_isr: end
> unmask_irq_intisa3: irq=64
> unmask_irq_intisa3: now: MISCREG_INTSR3=0x0
> unmask_irq_intisa3: unmasked: MISCREG_INTSR3=0x1
> mask_ack_irq_intisa3: irq=64
> mask_ack_irq_intisa3: now: MISCREG_INTSR3=0x1
> mask_ack_irq_intisa3: masked: MISCREG_INTSR3=0x0
> mask_ack_irq_intisa3: cleared: MISCREG_INTSR3=0x0
> isa3_isr: irq=64, dev_id=<NULL>
> isa3_isr: end
> unmask_irq_intisa3: irq=64
> unmask_irq_intisa3: now: MISCREG_INTSR3=0x0
> unmask_irq_intisa3: unmasked: MISCREG_INTSR3=0x1
> ....
> ....
>
> 何がおかしいか(気になっているか)というと、まず
> 割り込み要因が発生した直後の
> mask_ack_irq_intisa3: now: MISCREG_INTSR3=0x1
> mask_ack_irq_intisa3: masked: MISCREG_INTSR3=0x0
> が「あれ?」なのです。
>
> 図では、ISRはFFそのもの(FFの出力?)で、IMRはISRの前にあります。
> そうするとFFが値をラッチしているならば、IMRでFFの入力を
> マスクしてもFFをクリアしていないのですから、ISRの値は変化
> しないはずです。
>
> ところが、上のようにマスクをかけただけでISRがクリアされてます。
>
> mask_ack_irq_intisa3 の出口でFFをクリアしたときは
> mask_ack_irq_intisa3: cleared: MISCREG_INTSR3=0x0
> まぁ、そのとおりでしょう。(これだけでは、FFのクリア機能が
> 正しく動いているかどうかは判断できませんが・・・)
>
> で、その次のマスクの解除です。
> unmask_irq_intisa3: now: MISCREG_INTSR3=0x0
> unmask_irq_intisa3: unmasked: MISCREG_INTSR3=0x1
>
> PC/104バスの割り込み入力IRQ3(B25端子)はオープンのまま、つまり
> HIGHレベルのままですが、マスクを解除するとISRが1になります。
>
> ここでこのメール冒頭の質問になります。
> このフリップフロップはどのようなフリップフロップなのでしょう?
>
> 割り込み入力のエッジを記憶して、割り込みをレベルトリガで
> ハンドリングできるようにするためのものなのではないでしょうか?
> そして割り込みが処理されたところでICRでFFをクリア、つまり
> 割り込み要因の解除です。
> (エッジの検出と保持でないならば、ここにFFを入れる必要は
> ないよう思います。マスクレジスタだけで十分。)
>
>
> こちらの都合でちょっと古いカーネルソースを使っています。
> linux-2.6.12.3-a9-14 です。
> 念のためこの arch/arm/mach-ep93xx/irq.c を 2.6.12.3-a9-17 の
> ものと比較をしてみましたが、この部分の違いはないようです。
>
>
> 以上、よろしくお願いいたします。
>
armadillo メーリングリストの案内