(toppers-users 1940) Re: H8S、非タスクコンテキストでの割込みについて質問

二村誠示 snimura @ icrl.mew.co.jp
2005年 2月 16日 (水) 21:01:27 JST


松下電工の二村です。
お世話になっております。

H8SへのToppers移植において、割込み制御モード1への対応のために
修正を行った点について、ご連絡いたします。

修正点を簡単にまとめますと以下の通りです。詳細については、最後に載せます。
なにかお気づきの点などありましたら、ご指摘いただきたいと思います。

○cpu_config.h
・MAX_IPMを7から3へ変更(ccrのI,UIビット操作をMAX_IPMのビットシフトで行えるようにするため)
・chg_ipm/get_ipmのサポート解除
・割込みハンドラ入り口処理(_INTHDR_ENTRY)のexr操作をccr操作に変更
・割込みレベル設定用マクロ(icu_set_ilv)を修正
○cpu_config.c
・割込みレベル初期化処理修正(icu_set_ilvの修正に合わせて)
○cpu_support.S
・タスクディスパッチャ内のexrによる割込み禁止/許可をccrによる割込み禁止/許可に変更
・割込みハンドラ出入り口処理内のexrによる割込み禁止/許可をccrによる割込み禁止/許可に変更
・タスク起動処理内のexrによる割込み許可をccrによる割込み許可に変更
○cpu_insn.h
・割込みマスク制御用マクロ処理をexr操作からccr操作に変更

といったところです。

現在、岩沢様にご指摘いただいたようにH8のソースを参考にしようと思い、まずは
H8/3048Fのハードウェアマニュアルにて割込み制御の方法を確認中です。
ざっと見たところ、H8Sの割込み制御モード1と同様の方法のようなので、参考に
できそうかな、と感じています。

以下、修正点の詳細になります。ソースコードを載せてしまっているため、非常に
見にくくなっていますが、ご容赦下さい。


-------------------------------------------------------------------------------------------
-------------------- ◆割込み制御モード1対応のための変更点 -------------------------------
-------------------------------------------------------------------------------------------

【cpu_config.h】
・MAX_IPMの値を7から3に変更(ccrのIビットとUIビットへのマスク処理をビットシフトで対応するため)
#define	MAX_IPM	3

・chg_ipm/get_ipmをサポートしないように変更
/*#define	SUPPORT_CHG_IPM*/

・割込みハンドラ入口処理において、exr操作部分をccr操作に変更
#define	_INTHDR_ENTRY(entry, inthdr)		    \
asm("	.text					\n" \
"	.align 2				\n" \
"	.global _"#entry"			\n" \
"						\n" \
"_"#entry":					\n" \
"	push.l	er0				\n" \
			/* CPUロックに必要なレジスタをタスクスタックに待避 */ \
/*"	stc.b	exr, r0l			\n" */ \
			/* exr を r0l (er0) にコピー \
"			  (_kernel_ret_main 内で、割込み禁止許可制御に使う) */ \
/*"						\n" */ \
/*"	ldc.b	#"str_MAX_IPM", exr		\n" */ \
			/* lock_cpu 相当 (割込み禁止) */ \
/*"						\n" */ \
"	stc.b	ccr, r0l			\n" \
			/* ccr を r0l (er0) にコピー \
"			  (_kernel_ret_main 内で、割込み禁止許可制御に使う) */ \
"						\n" \
"	orc.b	#0xc0, ccr		\n" \
			/* lock_cpu 相当 (割込み禁止) */ \
"						\n" \
"	push.l	er1				\n" \
			/* er1 をタスクスタックに待避 */ \
"	mov.l	#_"#inthdr", er1		\n" \
			/* er1 = 割込みハンドラのアドレス */ \
"	jmp	_kernel_ret_main		\n" \
			/* 割込み入口処理へジャンプ */ \
)

・割込みレベル設定用マクロをレベル0/1の指定のみに変更
/*
 *  割込みレベル設定用マクロ(もしくは、インライン関数)
 *  ・x : インタラプトコントロールレジスタ	(ICRA - ICRC)
 *  ・y : ICR設定用マスク(設定ビット)		(BIT7 - BIT1)
 *  ・z : 割込みレベル						(0 - 1)
 *  2005/01/15 h8s2145用  二村修正
 */
Inline void icu_set_ilv( VP icr, UB mask, INT level ) {
	if( level == 1 ) {
		h8s_orb( icr, mask );
	} else if( level == 0 ) {
		h8s_andb( icr, ~mask );
	}
}


【cpu_config.c】
・割込みレベル初期化処理を、割込みレベル設定用マクロの変更に合わせて修正
	/* 割込みレベルの初期化 */
	icu_set_ilv( (VP) ICRA, ICR7, 0 );
      (以下、割込みコントロールレジスタの全ビットをセット)


【cpu_support.S】
・タスクディスパッチャ内の処理(dispatcher_2_enable_interrupt)にてexrによる
 割込み禁止/許可をccrによる割込み禁止/許可に変更

/*#ifdef SUPPORT_CHG_IPM*/
/*	ldc.b	@_task_intmask, exr	   unlock_cpu相当(割込み許可) */
/*#else  SUPPORT_CHG_IPM */
/*	ldc.b	#0, exr			   unlock_cpu相当(割込み許可) */
/*#endif SUPPORT_CHG_IPM */

	andc.b	#0x3f, ccr		/* unlock_cpu相当(割込み許可)B'00111111とCCRの& */
	sleep				/* 割込み待ち */
/*	ldc.b	#MAX_IPM, exr		   lock_cpu 相当 (割込み禁止) */
	orc	#0xc0:8, ccr		/* lock_cpu相当(割込み禁止)B'11000000とCCRのOR */

・割込みハンドラ出入り口処理内の多重割込みの処理(multipul_exception)にて
 exrによる割込み禁止/許可をccrによる割込み禁止/許可に変更

/*	ldc.b	r0l, exr		   (現在の割込みレベル以上)割込み許可 */
	ldc.b	r0l, ccr
	jsr	@er1			/* 割込みハンドラ呼出 */
/*	ldc.b	#MAX_IPM, exr		   lock_cpu 相当 (割込み禁止) */
	orc	#0xc0:8, ccr		/* lock_cpu相当(割込み禁止)B'11000000とCCRのOR */


・割込みハンドラ出入り口処理内の初段の割込みの場合(first_exception)にて
 exrによる割込み禁止/許可をccrによる割込み禁止/許可に変更

/*	ldc.b	r0l, exr		   (現在の割込みレベル以上)割込み許可 */
	ldc.b	r0l, ccr
	jsr	@er1			/* 割込みハンドラ呼出 */
/*	ldc.b	#MAX_IPM, exr		   lock_cpu 相当 (割込み禁止) */
	orc	#0xc0:8, ccr		/* lock_cpu相当(割込み禁止)B'11000000とCCRのOR */

・割込みハンドラ出入り口処理内の遅延ディスパッチ/タスク例外に関する処理
 (occur_dispatch_or_tsk_exception)にて、割込み発生箇所の判定処理変更
	mov.b	@(EXR_offset, sp), r0l	/* r01 = スタック上のEXR */
/*	and.b	#EXR_I_MASK, r0l	   r01 = スタック上の割り込みマスク */

	and.b	#CCR_I_UI, r0l
	shlr.b	#2, r0l			/* I,UIビットが7,6ビット目のため、 */
	shlr.b	#2, r0l			/* 1,0ビット目にビットシフト	   */
	shlr.b	#2, r0l	

・タスク起動処理内のexrによるCPUロックの解除をccrによるCPUロックの解除に変更
/*#ifdef SUPPORT_CHG_IPM */
/*	ldc.b	@_task_intmask, exr		  unlock_cpu相当(割込み許可) */
/*#else  SUPPORT_CHG_IPM */
/*	ldc.b	#0, exr				  unlock_cpu相当(割込み許可) */
/*#endif SUPPORT_CHG_IPM */
	andc.b	#0x3f, ccr		/* unlock_cpu相当(割込み許可)B'00111111とCCRの& */

【cpu_insn.h】
・割込みマスクの読出し関数をccrでのマスク読出しに変更
Inline IPM current_intmask(void)
{
//	return(  (IPM)  (current_exr() &  EXR_I_MASK) );
	/*
	 * I,UIは7,6ビット
	 * 6ビットシフトさせ、IPMを0〜3の範囲にする
	 */
	return(  (IPM)  ( (IPM) (current_ccr() & CCR_I_UI ) >> 6 ) );
}

・割込みマスクの設定関数をccrでのマスク設定に変更
Inline void set_intmask(IPM intmask)
{
//	set_exr( (IPM) ((current_exr() & ~EXR_I_MASK) | intmask ) );
	/*
	 * I,UIビットは7,6ビット
	 * intmaskが0〜3なので6ビットシフトさせて対応
	 */
	set_ccr( (IPM) ((current_ccr() & ~CCR_I_UI) | (intmask << 6)) );

}

・disint()関数をccrによる割込み禁止に変更
Inline void disint(void)
{
	/* set_intmask( (IPM) MAX_IPM ); */
//	set_exr( (IPM) ((current_exr() & ~EXR_I_MASK) | MAX_IPM ) );
	set_ccr( (IPM) (current_ccr() | CCR_I_UI ) );
}

・enaint()関数をccrによる割込み許可に変更
Inline void enaint()
{
	/* set_intmask( (IPM) 0 ); */
//	set_exr( (IPM)  (current_exr() & ~EXR_I_MASK) );
	set_ccr( (IPM) (current_ccr() & ~CCR_I_UI) );
}

・割込みロック状態の制御用関数をccrによる制御に変更
Inline void _disint_()
{
	/* set_intmask( (IPM) 7 ); */
//	set_exr( (IPM) (current_exr() | EXR_I_MASK) );
	set_ccr( (IPM) (current_ccr() | CCR_I_UI) );
}

------------------------------------------------------------------------------------------