x86.h static inline void lidt(struct gatedesc *p, int size)
トップページ
jupiteroak.hatenablog.com
x86.h
https://github.com/mit-pdos/xv6-public/blob/master/x86.h#L76
static inline void lidt(struct gatedesc *p, int size) { volatile ushort pd[3]; pd[0] = size-1; pd[1] = (uint)p; pd[2] = (uint)p >> 16; asm volatile("lidt (%0)" : : "r" (pd)); }
lidt関数は、引数pで指定されたIDTの先頭アドレス(割り込みディスクリプタテーブルの先頭アドレス)と引数sizeで指定されたIDTのサイズ(割り込みディスクリプタテーブルのサイズ)を、IDTR(割り込みディスクリプタテーブルレジスタ)に設定します。
引数 struct gatedesc *p
IDTの先頭アドレスです。
引数 int size
IDTのサイズです。
処理の内容
前提
IDTRへの値の設定は、アセンブリ言語のlidt命令によって行われます。
アセンブリ言語のlidt命令はメインメモリ上のデータをIDTRにロードするので、あらかじめメインメモリ上にIDTRと同じデータ構造を用意する必要があります。
IDTRのbit47-16(先頭アドレス値)に設定する値を用意する
pd[1] = (uint)p;
IDTR様データ構造のbit31-16に、IDTの先頭アドレスの下位16bitを設定します。
pd[2] = (uint)p >> 16;
IDTR様データ構造のbit47-16に、IDTの先頭アドレスの上位16bitを設定します。
インラインアセンブラ
asm volatile("lidt (%0)" : : "r" (pd));
関数内のインラインアセンブラを解釈すると以下のようになります。
アセンブリ言語命令
lidt %レジスタ
インラインアセンブラの命令を実行する前の状態
・eax,ebx,ecx,edx,esi,ediレジスタのいずれか(入力レジスタのリストにrで表記されている)
引数pdの値が設定されています。