Lions' 本ぼっち読み (22)
前回、call を読んでて力尽きている模様。とりあえず 0783 以降について確認してみます。
前モードがカーネルモードの場合
PS と $30000 と論理積を取ったら 0 になります。OS の前モードは 00 がカーネルで 11 がユーザとなっているためで、
0783 bit $30000,PS 0784 beq 2f
なナニ的にはカーネルモードだった場合、0873 の結果はゼロであり、PS の Z フラグが立ち、次の beq 命令で Z フラグが立ってるので 1f に jmp する、という事になります。
ので、前モードがカーネルモードだった場合には
0797 1: 0798 bis $30000,PS 0799 jsr pc,*(r0)+ 0800 cmp (sp)+,(sp)+
が実行されて共通の後始末な 0801 以降を実行していく模様。上記については
- 0798 で前モードがユーザモードであるように PS を修正
- 0799 で r0 に格納されている割り込みハンドラ (ここでは clock) に jmp
- 0800 で 戻ってきたら 0780 および 0781 でスタックに積まれたものを取り除く
という事になってるようです。
前モードがユーザモードだった場合
0783 な命令が 0 以外になる場合、0785 以降の命令が実行されていく模様。とりあえず 0784 で r0 に格納されている割り込みハンドラ (ここでは clock) を実行します。
0785 jsr pc,*(r0)+
で、それ以降は runrun の値を見て swtch を呼び出すループになってます。
0786 2: 0787 bis $340,PS 0788 tstb _runrun 0789 beq 2f 0790 bic $340,PS 0791 jsr pc,_swtch 0792 br 2b 0793 2:
runrun の値がゼロなら 0793 に jmp してます。あ、その前に 0787 で PS な優先度を最高にして割り込みが入らないようにしてます。なので runrun がゼロだったら割り込み優先度が最高のまま割り込み元に戻るんかな。
あ、Lions' 本に以下な記述がありますね。
その結果カレントプロセスが実行を続けてよいのならば、割り込みからのリターン命令の前にレジスタを元に戻すので、そのプロセスが割り込みを受けないことが重要である。
Lions' Commentary on UNIX より引用
おそらくは rtt で PC と PS が復帰されるのでそれまでは割り込みが入らない形、ということは理解できたんですが、swtch 手続き呼び出し中は割り込み OK ってことなのかな。そりゃそうか。swtch から戻ってきて runrun が 0 なら割り込み禁止で rtt になることは分かります。
とは言え、0780 および 0781 でスタックに積まれるソレは前モードがユーザモードの場合に有効とありますが、現時点でその詳細は不明です。
0793 以降ですが、以下 (一部略)。
0793 2: 0794 tst (sp)+ 0795 mtpi sp 0796 br 2f (ry 0801 2: 0802 mov (sp)+,r1 0803 tst (sp)+ 0804 mov (sp)+,r0 0805 rtt
0794 および 0795 は 0780 および 0781 の後始末なのだろうなと。また、0801 以降は前モードがカーネルモードの場合もここを実行します。
最後の 0804 は割り込みハンドラな jsr 呼び出し時に push される r0 になるはず。
とは言え、0780 および 0781 の命令の意図は別途確認したい。あとはなんとなくベースで理解できているのかどうか。
このままトラップも見てみます
0756 以降の命令を手繰った後に call と同じことをしているようです。
あと、call の 0781 でも云々してたナニですが、なるべく素早く PS を保存するのは割り込みやトラップの種別を特定する必要がある上に、PS レジスタの下らへんは命令のステイタスで随時変わるので、ということなのですね。
とりあえず 344p のカーネルスタックの項は今の状態では難解に過ぎるので別途、ということにてエントリ投入。