OSDN Git Service

add cortex-a9 base
[hos/hos-v4a.git] / kernel / source / arch / proc / arm / arm_v7a / gcc / kirq_hdr.S
diff --git a/kernel/source/arch/proc/arm/arm_v7a/gcc/kirq_hdr.S b/kernel/source/arch/proc/arm/arm_v7a/gcc/kirq_hdr.S
new file mode 100644 (file)
index 0000000..a1aed71
--- /dev/null
@@ -0,0 +1,116 @@
+/** 
+ *  Hyper Operating System V4 Advance
+ *
+ * Copyright (C) 1998-2014 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "arm_v7a.inc"
+
+
+                               .code   32
+                               .text
+                               .align  2
+
+                               .global _kernel_ictxcb
+                               .global _kernel_sta_inh
+                               .global _kernel_end_inh
+                               .global _kernel_exe_inh
+
+/************************************************
+  IRQ handler
+ ************************************************/
+                               .global _kernel_irq_hdr
+_kernel_irq_hdr:
+                       /* ---- レジスタ退避 */
+                               sub             lr, lr, #4                                                              /* リターンアドレス算出 */
+               /*              srsfd   #Mode_SYS!                      */                                      /* lr_irq, spsr_irqをSYSモードスタックに退避 */
+                               .long   0xf96d051f
+                               cps             #Mode_SYS                                                               /* SYSモードに移行 */
+                               stmfd   sp!, {r0-r3, r12, lr}                                   /* 汎用レジスタ退避 */
+                               mrs             r2, cpsr                                                                /* cpsrをr2に退避 */
+                               cpsid   fi                                                                              /* 割り込み禁止 */
+                               
+                       /* ---- 割込みマスク設定 */
+                               ldr             r0, =_kernel_ictxcb
+                               ldr             r3, [r0, #ICTXCB_IMSK]                                  /* 古いimsk値を取り出し */
+                               and             r2, r2, #(F_Bit | I_Bit)
+                               strb    r2, [r0, #ICTXCB_IMSK]                                  /* cpsr値をimsk値に設定 */
+                               
+                       /* ---- 多重割込み判定 */
+                               ldrb    r1, [r0, #ICTXCB_INTCNT]                                /* 割り込みネストカウンタ値取得 */
+                               add             r1, r1, #1                                                              /* 割り込みネストカウンタインクリメント */
+                               strb    r1, [r0, #ICTXCB_INTCNT]                                /* 割り込みネストカウンタ設定 */
+                               cmp             r1, #1
+                               bne             multiple_int                                                    /* 多重割り込みなら分岐 */
+                               
+                       /* ---- SPを割込みコンテキストのものに切替え */
+                               mov             r1, sp                                                                  /* タスクのSPを保存 */
+                               ldr             sp, [r0, #ICTXCB_ISP]                                   /* 割り込み用スタックに切り替え */
+                               stmfd   sp!, {r1, r3}                                                   /* タスクのSPと旧imask保存 */
+                               
+                       /* ---- 割込み開始処理 */
+                               bl              _kernel_sta_inh                                                 /* 割り込み開始 */
+                               
+                       /* ---- 割込みハンドラ実行 */
+                               mov             r0, #INHNO_IRQ
+                               bl              _kernel_exe_inh
+                               
+                       /* ---- 割込み処理の終了設定 */
+                               ldmfd   sp!, {r1, r3}                                                   /* 汎用レジスタ復帰 */
+                               mov             sp, r1                                                                  /* SPを元のコンテキストのものに戻す */
+                               ldr             r0, =_kernel_ictxcb                                             /* 割り込みネストカウンタのアドレス取得 */
+                               mov             r1, #0                                                                  /* 割り込みネストカウンタを0に戻す */
+                               strb    r1, [r0, #ICTXCB_INTCNT]                                /* 割り込みネストカウンタ値設定 */
+                       
+                       /* ---- 割込みマスク値復帰処理 */
+                               ldr             r1, [sp, #28]                                                   /* spsr_irq 値取り出し */
+                               and             r1, r1, #(F_Bit | I_Bit)
+                               cmp             r1, r3                                                                  /* 旧imsk値と比較 */
+                               bne             return_int                                                              /* 不一致なら終了処理スキップ */
+                               strb    r3, [r0, #ICTXCB_IMSK]                                  /* マスク値復帰 */
+                               
+                       /* ---- 割込み終了処理 */
+                               bl              _kernel_end_inh                                                 /* 割り込み終了処理 */
+
+                               ldr             r0, =_kernel_ictxcb
+                               ldr             r1, [sp, #28]                                                   /* spsr_irq 値取り出し */
+                               ldrb    r0, [r0, #ICTXCB_IMSK]                                  /* この時点でのimsk値取り出し */
+                               bic             r1, r1, #(F_Bit | I_Bit)
+                               and             r0, r0, #(F_Bit | I_Bit)
+                               orr             r1, r1, r0
+                               str             r1, [sp, #28]                                                   /* spsr_irq にimsk値反映 */
+
+return_int:
+                       /* ---- 復帰処理 */
+                               ldmfd   sp!, {r0-r3, r12, lr}                                   /* 汎用レジスタ復帰 */
+                               rfefd   sp!                                                                             /* リターン */
+
+
+                       /* ---- 多重割り込み処理 */
+multiple_int:
+                       /* ---- スタックを8バイトアライメントに移動 */
+                               mov             r1,  sp                                                                 /* 割り込み発生時のSYSモードのSPに8の倍数の保証されないので */
+                               bic             sp, sp, #0x7
+                               stmfd   sp!, {r0, r1}                                                   /* タスクのSPを割り込み用スタックに保存(8の倍数になるようにr1も) */
+                               
+                       /* ---- 割り込みハンドラ実行 */
+                               mov             r0, #INHNO_IRQ
+                               bl              _kernel_exe_inh
+
+                       /* ---- スタックアライメント復帰 */
+                               ldmfd   sp!, {r0, r1}                                                   /* 汎用レジスタ復帰 */
+                               mov             sp, r1
+                               
+                       /* ---- 割り込みカウンタ復帰 */
+                               ldrb    r1, [r0, #ICTXCB_INTCNT]
+                               add             r1, r1, #1
+                               strb    r1, [r0, #ICTXCB_INTCNT]
+                               b               return_int                                                              /* 復帰処理 */
+
+
+                               .end
+
+
+/* end of file */