interrupt.c

來源:互聯網
上載者:User
pintos中的中斷有256個即0-255.
void *frame_pointer; 是一個frame總會有個指標
void (*eip) (void); 下一個執行的指令的地址。
void *esp; stack pointer 棧指標
IDT(Interrupt Descriptor Table)是一個描述interrupt的數組,即idt[INTR_CNT];
PIC(可程式化插斷控制器):外設發出插斷要求需要PIC進行處理。
當發生中斷時先調用intrNN_stub();這是用彙編寫的。接著調用intr_entry();即把intr_frame放入棧中。最後調用intr_handler()執行特定註冊過的中斷。
intr_handler();返回後則恢複現場,即把棧中的CPU寄存器的值都恢複。
intr_frame裡面的都是CPU寄存器的值,我們在中斷時所要做的事就是儲存現場,而這就是一個現場,我們只要把這個放入棧中即可。
static intr_handler_func *intr_handlers[INTR_CNT];這個就是對應每個中斷處理函數。
static unsigned int unexpected_cnt[INTR_CNT];這個是記錄了每個中斷裡沒有註冊中斷處理函數的計數。
static bool yield_on_return;一般外部中斷是不能yield或sleep。
intr_init() 函數把中斷的一些基本配置都配好了。0-19都是有原因的中斷,20以上就是unknown。

//-------------------------------------------------------------------------------------------------------------------------------------------
static void
register_handler (uint8_t vec_no, int dpl, enum intr_level level,
intr_handler_func *handler, const char *name)
{
ASSERT (intr_handlers[vec_no] == NULL);
if (level == INTR_ON)
idt[vec_no] = make_trap_gate (intr_stubs[vec_no], dpl);
else
idt[vec_no] = make_intr_gate (intr_stubs[vec_no], dpl);
intr_handlers[vec_no] = handler;
intr_names[vec_no] = name;
}
這個函數的意思是vec_no的中斷調用了這個函數,調用handler這個函數的前提是vec_no的中斷執行程式還沒有被註冊。
這樣這個函數就可以把handler註冊為中斷處理常式,dpl(descriptor privilege level)只有兩種取值,第一種為3,意思是允許使用者模式中斷,第二種0,意思是禁止中斷。
如果level是開啟中斷,則把idt[vec_no]描述為make_trap_gate.並且把intr_handler[vec_no]賦值,name也賦值。
void
intr_register_ext (uint8_t vec_no, intr_handler_func *handler,
const char *name)
{
ASSERT (vec_no >= 0x20 && vec_no = 0x20 && vec_no vec_no >= 0x20 && frame->vec_no vec_no]; //內部中斷只需執行這個handler即可。
if (handler != NULL)
handler (frame);
else if (frame->vec_no == 0x27 || frame->vec_no == 0x2f)
{
/* There is no handler, but this interrupt can trigger
spuriously due to a hardware fault or hardware race
condition. Ignore it. */
}
else
unexpected_interrupt (frame); //沒有註冊handler

/* Complete the processing of an external interrupt. */
if (external)
{
ASSERT (intr_get_level () == INTR_OFF);
ASSERT (intr_context ());

in_external_intr = false; //退出外部中斷
pic_end_of_interrupt (frame->vec_no); //設定pic

if (yield_on_return) //外部中斷一定不會執行這句話
thread_yield ();
}
}
//-------------------------------------------------------------------
static void
unexpected_interrupt (const struct intr_frame *f)
{
/* Count the number so far. */
unsigned int n = ++unexpected_cnt[f->vec_no];

/* If the number is a power of 2, print a message. This rate
limiting means that we get information about an uncommon
unexpected interrupt the first time and fairly often after
that, but one that occurs many times will not overwhelm the
console. */
if ((n & (n - 1)) == 0)
printf ("Unexpected interrupt %#04x (%s)/n",
f->vec_no, intr_names[f->vec_no]);
}
這個函數只是把frame中對應的vec_no的unexpected_cnt數組加一。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.