⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interrupt-8259_5.htm

📁 编写自己的操作系统
💻 HTM
📖 第 1 页 / 共 4 页
字号:
      <CENTER><FONT face="Courier New" size=2>5</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ13</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ5</FONT></CENTER></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>4</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ12</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ4</FONT></CENTER></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>3</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ11</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ3</FONT></CENTER></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>2</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ10</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ2</FONT></CENTER></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>1</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ9</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ1</FONT></CENTER></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>0</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask IRQ8</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>Mask 
  IRQ0</FONT></CENTER></TD></TR></TBODY></TABLE><FONT face="Courier New" 
size=2>Operation Control Word 1 (OCW1) </FONT></CENTER>
<P><FONT face="Courier New" size=2></FONT></P>
<P><FONT face="Courier New" 
size=2>OCW1是用来做中断请求屏蔽用的操作控制字。如果你想屏蔽那个IRQ,只需要对照上表将相应的Bit置为1,然后发送给相应的8259A就可以了。比如我想屏蔽IRQ10,我只需要将0x0A写到端口0xA1。对应代码如下:</FONT></P>
<P><FONT face="Courier New" size=2>outb(0x0A, 0xA1);</FONT></P>
<P><FONT face="Times New Roman TUR" size=4><STRONG>OCW2</STRONG></FONT></P>
<P>
<CENTER>
<TABLE width="80%" border=1>
  <TBODY>
  <TR>
    <TD><B>
      <CENTER><FONT face="Courier New" size=2>Bit(s)</FONT></B></CENTER></TD>
    <TD colSpan=2><B><FONT face="Courier New" size=2>Function</FONT></B></TD></TR>
  <TR>
    <TD vAlign=top rowSpan=8>
      <CENTER><FONT face="Courier New" size=2>7:5</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>000</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Rotate in Auto EOI Mode 
    (Clear)</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>001</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Non Specific EOI</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>010</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Reserved </FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>011</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Specific EOI</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>100</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Rotate in Auto EOI Mode 
  (Set)</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>101</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Rotate on Non-Specific 
EOI</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>110</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Set Priority Command (Use Bits 2:0) 
      </FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>111</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Rotate on Specific EOI (Use Bits 
      2:0)</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>4</FONT></CENTER></TD>
    <TD colSpan=2><FONT face="Courier New" size=2>Must be set to 
0</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>3</FONT></CENTER></TD>
    <TD colSpan=2><FONT face="Courier New" size=2>Must be set to 
0</FONT></TD></TR>
  <TR>
    <TD vAlign=top rowSpan=8>
      <CENTER><FONT face="Courier New" size=2>2:0</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>000</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 0 or 8</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>001</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 1 or 9</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>010</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 2 or 10</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>011</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 3 or 11</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>100</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 4 or 12</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>101</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 5 or 13</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>110</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 6 or 14</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>111</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Act on IRQ 7 or 
15</FONT></TD></TR></TBODY></TABLE><FONT face="Courier New" size=2>Operation 
Control Word 2 (OCW2) </FONT></CENTER>
<P><FONT face="Courier New" size=2></FONT></P>
<P><FONT face="Courier New" 
size=2>通过将bit3:4设置为0,以说明这是一个OCW2。如果bit-6被设为1,则bit0:2有效,其操作则是面向某个IRQ的;否则将bit0:2设为0,其操作是面向整个8259A的所有IRQ的。我们一般只会用到No 
Specific EOI——因为我们在初始化8259A时,制定的EOI 
Mode为手动模式,所以当每次对应某个8259A芯片的IRQ的中断服务程序ISR执行结束后,都需要向8259A发送一个EOI,其对应的OCW2的值为0x20。需要注意的是,由于IBM 
PC有2个级连的8259A,所以我们每次必须分别给两个都发一个。</FONT></P>
<P><FONT face="Courier New" 
size=2>比如下面示例代码用来向两个8259A芯片发送EOI,它需要在针对来自于两个8259A芯片的中断的服务程序ISR末尾处被调用:</FONT></P>
<P><FONT face="Courier New" size=2>inline void 
send_eoi(void)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp; /* Send EOI to both master and 
slave */ <BR>&nbsp;&nbsp;&nbsp; outb( 0x20, 0x20 ); /* master PIC 
*/<BR>&nbsp;&nbsp;&nbsp; outb( 0x20, 0xA0 ); /* slave PIC */<BR>}</FONT></P>
<P><FONT face="Times New Roman TUR" size=4><STRONG>OCW3</STRONG></FONT></P>
<P>
<CENTER>
<TABLE width="80%" border=1>
  <TBODY>
  <TR>
    <TD><B>
      <CENTER><FONT face="Courier New" size=2>Bit(s)</FONT></B></CENTER></TD>
    <TD colSpan=2><B><FONT face="Courier New" size=2>Function</FONT></B></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>7</FONT></CENTER></TD>
    <TD colSpan=2><FONT face="Courier New" size=2>Must be set to 
0</FONT></TD></TR>
  <TR>
    <TD vAlign=top rowSpan=4>
      <CENTER><FONT face="Courier New" size=2>6:5</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>00</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Reserved</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>01</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Reserved</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>10</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Reset Special Mask </FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>11</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Set Special Mask</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>4</FONT></CENTER></TD>
    <TD colSpan=2><FONT face="Courier New" size=2>Must be set to 
0</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>3</FONT></CENTER></TD>
    <TD colSpan=2><FONT face="Courier New" size=2>Must be set to 
1</FONT></TD></TR>
  <TR>
    <TD rowSpan=2>
      <CENTER><FONT face="Courier New" size=2>2</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>1</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Poll Command</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>0</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>No Poll Command</FONT></TD></TR>
  <TR>
    <TD vAlign=top rowSpan=4>
      <CENTER><FONT face="Courier New" size=2>1:0</FONT></CENTER></TD>
    <TD>
      <CENTER><FONT face="Courier New" size=2>00</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Reserved</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>01</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Reserved</FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>10</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Next Read Returns Interrupt Request 
      Register </FONT></TD></TR>
  <TR>
    <TD>
      <CENTER><FONT face="Courier New" size=2>11</FONT></CENTER></TD>
    <TD><FONT face="Courier New" size=2>Next Read Returns In-Service 
      Register</FONT></TD></TR></TBODY></TABLE><FONT face="Courier New" 
size=2>Operation Control Word 3 (OCW3) </FONT></CENTER>
<P><FONT face="Courier New" 
size=2>通过将Bit-3设为1,Bit-4设为0,以让8259A知道这是一个OCW3。OCW3中对我们最有意义的位是bit0:1,我们可以通过将bit-1设为1来通知8259A,下一个读端口的动作将要读取IRR或ISR寄存器的内容。</FONT></P>
<P><FONT face="Courier New" size=2>比如下面示例C++代码用来读取Master 
8259A的IRR寄存器内容到__irr变量中:</FONT></P>
<P><FONT face="Courier New" size=2>void read_irr(unsigned char&amp; 
__irr)<BR>{<BR>&nbsp;&nbsp;&nbsp; outb(0x02, 0x20);<BR>&nbsp;&nbsp;&nbsp; 
inb(&amp;__irr, 0x20);<BR>}</FONT></P>
<DIV align=left>
<HR width="100%" SIZE=2>
</DIV>
<DIV align=left></DIV>
<P align=left><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN 
style="mso-tab-count: 1"><FONT face="Times New Roman TUR" size=5><STRONG>2.5.7 
Full Nested Mode</STRONG></FONT></SPAN></FONT></SPAN></P>
<P align=left><FONT face="Courier New"><FONT size=2><SPAN lang=EN-US><SPAN 
style="mso-tab-count: 1">为了让我们更加理解8259A的中断控制机理,我们需要说明一下Full Nested 
Mode。</SPAN></SPAN><SPAN lang=EN-US><SPAN 
style="mso-tab-count: 1">在我们初始化时,只需要将ICW4的bit-4设为0,我们就选择了Full Nested 
Mode。</SPAN></SPAN></FONT></FONT></P>
<P align=left><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT 
face="Courier New" size=2>Full Nested 
Mode其实就是实现按照中断请求的优先级别进行抢断处理的机制——如果当前一个IRQ正在被CPU处理,也就是说,当前CPU正在调用其中断服务程序ISR;这时8259A又接到了新的IRQ,如果此IRQ的优先级大于正在处理的IRQ,那么,此IRQ就会被提交给CPU以优先处理;否则此IRQ则被放置在IRR中,直到所有的高优先级中断被处理结束为止。</FONT></SPAN></SPAN></P>
<P align=left><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT 
face="Courier New" size=2>其处理过程大致如下:</FONT></SPAN></SPAN></P>
<P align=left><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT 
face="Courier New" 
size=2>在ISR寄存器中有一个8-bit的字节,范围为bit[0,7];每一个bit对应一个IRQ(IRQ0-IRQ7对应bit[0,7])。当一个IRQ被提交给CPU之后(收到来自于CPU的第一个INTA信号之后),其对应的bit会被设置为1。比如IRQ6被提交给CPU之后,IS 
Register的bit-6会被设置为1。当此8259A收到一个EOI之后(对于手动模式,这意味着一个优先级别最高的中断请求被处理结束),会将IS 
Register中被设置的最高优先级IRQ的对应的bit清为0。比如在收到一个EOI时,发现IS Register的bit-3, bit-5, 
bit-6被设置,那么被清除的则是bit-3(越小优先级别越高)。在清除优先级最高的bit之后,8259A会到IRR中察看是否有优先级别高于当前正在处理的IRQ中优先级别最高的IRQ,如果有,则将此IRQ提交给CPU处理,同时设置相应的bit。还以上面的例子为例,当bit-3被清除之后,如果发现在IRR中有一个IRQ4等待被处理,则将其提交给CPU,在收到来自于CPU的第一个INTA信号之后,则将IS 
Register的bit-4置为1。</FONT></SPAN></SPAN></P>
<P align=left><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT 
face="Courier New" 
size=2>在此过程中,如果8259A接到更高优先级别的IRQ,则将其立即提交给CPU。比如,当前正在处理的IRQ为IRQ3,IRQ5,那么IS 
Register中被设置的bit为bit-3,bit-5;如果此时接到一个IRQ1,则立即将其提交给CPU,在收到来自于CPU的第一个INTA信号之后,则将IS 
Register的bit-1置为1。</FONT></SPAN></SPAN></P>
<P align=left><SPAN lang=EN-US><SPAN style="mso-tab-count: 1"><FONT 
face="Courier New" 
size=2>由此过程我们也可以看出,为了实现这种优先级机制,必须将EOI设为手动模式,也就是说必须将ICW4的bit-1设为0。因为,对于自动EOI模式,8259A会在收到来自于CPU的第2个INTA信号之后,就自动将IS 
Register中此IRQ对应的bit清0,而事实上,这个时候此IRQ对应的中断服务程序还没有被CPU调用,也就是说此IRQ还没有被处理结束,而由于此IRQ对应的bit已经被清除,如果此IRQ是一个优先级很高的话,那么此IRQ的处理完全可以被一个优先级别更低的IRQ所中断。这不是我们所需要的。</FONT></SPAN></SPAN></P></FONT></FONT></FONT></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN></FONT></DIV></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -