mmu.h #define SETGATE(gate, istrap, sel, off, d)
トップページ
jupiteroak.hatenablog.com
mmu.h
https://github.com/mit-pdos/xv6-public/blob/master/mmu.h#L168
#define SETGATE(gate, istrap, sel, off, d) \ { \ (gate).off_15_0 = (uint)(off) & 0xffff; \ (gate).cs = (sel); \ (gate).args = 0; \ (gate).rsv1 = 0; \ (gate).type = (istrap) ? STS_TG32 : STS_IG32; \ (gate).s = 0; \ (gate).dpl = (d); \ (gate).p = 1; \ (gate).off_31_16 = (uint)(off) >> 16; \ }
SETGATEマクロは、引数gateで指定された割り込みディスクリプタ(ゲートディスクリプタ)に値を設定して、割り込みベクタ番号とハンドラ(例外ハンドラ、または、割り込みハンドラ)の対応関係をつくります。
引数 gate
設定対象となる割り込みディスクリプタ(struct gatedesc構造体)です。
引数 istrap
設定対象となる割り込みディスクリプタ(gatedesc構造体)を、トラップゲートとして利用する場合は1を、割り込みゲートとして利用する場合は0を指定します。
引数 sel
ハンドラ(例外ハンドラ、または、割り込みハンドラ)が格納されているコードセグメントのセレクタ値です。
セレクタ値は割り込みディスクリプタのbit31-16(gatedesc構造体のcs)に格納されます。
引数 off
コードセグメント内にあるハンドラ(例外ハンドラ、または、割り込みハンドラ)のオフセットアドレスです。
オフセットアドレスの上位16bitは割り込みディスクリプタのbit63-48(gatedesc構造体のoff_31_16)に格納され、オフセットアドレスの下位16bitは割り込みディスクリプタのbit15-0(gatedesc構造体のoff_15_0 )に格納されます。
引数 d
ハンドラ(例外ハンドラ、または、割り込みハンドラ)の実行に必要なCPUの特権レベルです。
dの値は割り込みディスクリプタのbit46-45(gatedesc構造体のdpl)に格納されます。
処理の内容
- 前提
- 割り込みディスクリプタのbit15-0(gatedesc構造体のoff_15_0 )にオフセットアドレスを設定する
- 割り込みディスクリプタのbit39-16(gatedesc構造体のrsv1、args、cs)に値を設定する
- 割り込みディスクリプタのbit47-40(gatedesc構造体のp、dpl、s、type)に値を設定する
- 割り込みディスクリプタのbit63-48(gatedesc構造体のoff_31_16)にオフセットアドレスを設定する
前提
割り込みディスクリプタを表現したデータ構造であるgatedesc構造体(8バイト)です
struct gatedesc { uint off_15_0 : 16; // low 16 bits of offset in segment uint cs : 16; // code segment selector uint args : 5; // # args, 0 for interrupt/trap gates uint rsv1 : 3; // reserved(should be zero I guess) uint type : 4; // type(STS_{IG32,TG32}) uint s : 1; // must be 0 (system) uint dpl : 2; // descriptor(meaning new) privilege level uint p : 1; // Present uint off_31_16 : 16; // high bits of offset in segment };
割り込みディスクリプタのbit15-0(gatedesc構造体のoff_15_0 )にオフセットアドレスを設定する
(gate).off_15_0 = (uint)(off) & 0xffff;
割り込みディスクリプタのbit15-0(gatedesc構造体のoff_15_0 )に、オフセットアドレスの下位16bitを設定します。
off(32bit)を0xffffでマスク処理することにより、オフセットアドレスの下位16bitを取得しています。
割り込みディスクリプタのbit39-16(gatedesc構造体のrsv1、args、cs)に値を設定する
(gate).cs = (sel); (gate).args = 0; (gate).rsv1 = 0;
割り込みディスクリプタのbit31-16、bit36-32、bit39-37(gatedesc構造体のcs、args、rsv1)に、sel、0、0をそれぞれ設定します。
bit36-32
予約済みのフィールドで、常に 00000 です。
bit39-37
常に 000 です。
割り込みディスクリプタのbit47-40(gatedesc構造体のp、dpl、s、type)に値を設定する
(gate).type = (istrap) ? STS_TG32 : STS_IG32; (gate).s = 0; (gate).dpl = (d); (gate).p = 1;
割り込みディスクリプタのbit43-40、bit44、bit46-45、bit47(gatedesc構造体のtype、p、dpl、s)に、(istrap) ? STS_TG32 : STS_IG32、0、d、1をそれぞれ設定します。
bit43-40(type)
割り込みディスクリプタがトラップゲート(例外で使用する割り込みディスクリプタ)か割り込みゲート(ハードウェア割り込みで使用する割り込みディスクリプタ)かを指定するフィールドです。
トラップゲートとして利用する場合は(istrap = 1)、1111(#define STS_TG32 0xF)が格納されます。
割り込みゲートとして利用する場合(istrap = 0)は、1110(#define STS_IG32 0xE)が格納されます。
bit44(Sフラグ)
割り込みディスクリプタでは、常に0です。
bit46-45(DPL)
ハンドラ(例外ハンドラor割り込みハンドラ)の実行に必要なCPUの特権レベルを指定するフィールドです。
00...ハンドラの実行に必要なCPUの特権レベルがカーネルモードであることを示しています。
11...ハンドラの実行に必要なCPUの特権レベルがユーザーモードであることを示しています。
bit47(Pフラグ)
セグメントがメモリ上に存在するかしないかを示すフィールドです。
この値が1の時は、セグメントがメモリ上に常に存在することを示しています。