(toppers-users 2277) Re: ARM対応の割り込みとスタックの復帰について

Shinya Honda honda @ ertl.jp
2006年 2月 1日 (水) 09:45:53 JST


屋鋪様

名古屋大学の本田です。

Masafumi YASHIKI wrote:
> シャープの屋鋪と申します.
> 
> TOPPERS/JSP 1.4/1.4.1/1.4.2 の ARM 対応について質問がございます.
> 
> 割り込みからの復帰する際の割り込み許可のタイミングとスタックの復帰の手
> 順に関してです.
> 
> cpu_support.S では,
> ret_int_2:              
>         ldmfd sp!, {r0}       /* spsr を復帰 */
>         mrs   r2, cpsr        /* FIQを継承            */
>         and   r2, r2, #CPSR_FIQ_BIT
>         and   r0, r0, #~CPSR_FIQ_BIT
>         orr   r0, r0, r2                    
> (A)     msr   cpsr, r0      
> (B)     ldmfd sp!, {r0 - r3,ip,lr,pc} /* タスクへ戻る */
> 
> で割り込みから復帰しています.
> 
> 一方,sys_support.S では,
> return_to_task_irq:
>         ldmfd   sp!,{r1}           /* CPSRの復帰処理 */
>         mrs     r2, cpsr           /* FIQを継承            */
>         and     r2, r2, #CPSR_FIQ_BIT
>         and     r1, r1, #~CPSR_FIQ_BIT
>         orr     r1, r1, r2                 
> (C)     msr     spsr, r1           /* 割り込み許可   */
> (D)     ldmfd   sp!,{r0-r3,ip,lr,pc}^ /*タスク復帰 + 割込み許可 */
> 
> cpu_support.S では,(A)の命令を実行した時点で,割り込み許可状態になり
> ます.このため,スタックを復帰する前に割り込みが発生する可能性がありま
> す.sys_support.S では,(D)の命令を実行するでは,割り込み許可状態にな
> りません.このため,次の割り込みが発生するのはスタックを復帰した後にな
> ります.

おっしゃられるようにcpu_support.Sのコードもcpu_support.Sのコードと同様に
スタックの復帰とcpsrの更新による割込みの許可をアトミックに行う必要があり
ますね。sys_support.Sに関しても以前同様の問題を指摘していただいて、割込
みハンドラと例外ハンドラに関しては修正していましたが、この部分は見落とし
ていました。return_to_task_irqの方もコメントがおかしいので、以下のように
修正します。

ret_int_2:
   ldmfd sp!, {r0}       /* spsr を復帰 */
   mrs   r2, cpsr        /* FIQを継承            */
   and   r2, r2, #CPSR_FIQ_BIT
   and   r0, r0, #~CPSR_FIQ_BIT
   orr   r0, r0, r2
   msr   spsr, r0                 /* 戻り先のcpsrをspsrに設定 */
   ldmfd sp!, {r0 - r3,ip,lr,pc}^ /* タスクへ戻る ^付きなので、psr <- spsr*/

return_to_task_irq:
  ldmfd   sp!,{r1}           /* CPSRの復帰処理 */
  mrs     r2, cpsr           /* FIQを継承            */
  and     r2, r2, #CPSR_FIQ_BIT
  and     r1, r1, #~CPSR_FIQ_BIT
  orr     r1, r1, r2
  msr     spsr, r1              /* 戻り先のcpsrをspsrに設定 */
  ldmfd   sp!,{r0-r3,ip,lr,pc}^ /* タスクに復帰 ^付きなので、cpsr <- spsr */

これで問題がなければ次のリリースに反映させます。