{"componentChunkName":"component---src-templates-post-template-js","path":"/unix-xv6-006-kernel-main-03-en","result":{"data":{"markdownRemark":{"id":"134084b1-1ed1-59b0-b513-144869123820","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/unix-xv6-006-kernel-main-03\">original page</a>.</p>\n</blockquote>\n<p>Inspired by <a href=\"https://amzn.to/3q8TU3K\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">An Introduction to OS Code Reading: Learning Kernel Internals with UNIX V6</a>, I’m reading <a href=\"https://github.com/mit-pdos/xv6-public\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">xv6 OS</a>.</p>\n<p>Because UNIX V6 itself does not run on x86 CPUs, I decided to read the source of <a href=\"https://github.com/kash1064/xv6-public\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">kash1064/xv6-public: xv6 OS</a>, a fork of the <a href=\"https://github.com/mit-pdos/xv6-public\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">xv6 OS</a> repository that makes UNIX V6 run on the x86 architecture.</p>\n<p>In the <a href=\"/unix-xv6-005-kernel-main-02-en\">previous article</a>, I looked at the behavior of the <code class=\"language-text\">kvmalloc</code> function and its page table allocation executed from <code class=\"language-text\">main</code>.</p>\n<p>This time, I will trace the behavior of the <code class=\"language-text\">mpinit</code> function.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li>\n<p><a href=\"#the-mpinit-function\">The <code class=\"language-text\">mpinit</code> function</a></p>\n<ul>\n<li><a href=\"#declaring-structure-variables\">Declaring structure variables</a></li>\n<li><a href=\"#about-the-mp-specification\">About the MP specification</a></li>\n<li><a href=\"#obtaining-the-mp-floating-pointer-structure\">Obtaining the MP Floating Pointer Structure</a></li>\n<li><a href=\"#obtaining-the-mp-configuration-table\">Obtaining the MP Configuration Table</a></li>\n<li><a href=\"#obtaining-the-ioapic-from-the-mp-configuration-table\">Obtaining the IOAPIC from the MP Configuration Table</a></li>\n<li><a href=\"#obtaining-processor-information\">Obtaining processor information</a></li>\n<li><a href=\"#reading-processor-entry-information\">Reading Processor Entry information</a></li>\n<li><a href=\"#reading-ioapic-information\">Reading IOAPIC information</a></li>\n<li><a href=\"#modifying-the-imcr\">Modifying the IMCR</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n<li><a href=\"#reference-books\">Reference Books</a></li>\n</ul>\n<h2 id=\"the-mpinit-function\" style=\"position:relative;\"><a href=\"#the-mpinit-function\" aria-label=\"the mpinit function permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <code class=\"language-text\">mpinit</code> function</h2>\n<p>The <code class=\"language-text\">mpinit</code> function is the following function defined in <code class=\"language-text\">mp.c</code>.</p>\n<p>“mp” probably stands for multiprocessor; the function whose role is to detect other processors is <code class=\"language-text\">mpinit</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">void</span> <span class=\"token function\">mpinit</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  uchar <span class=\"token operator\">*</span>p<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>e<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">int</span> ismp<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token operator\">*</span>mp<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span> <span class=\"token operator\">*</span>conf<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span> <span class=\"token operator\">*</span>proc<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span> <span class=\"token operator\">*</span>ioapic<span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>conf <span class=\"token operator\">=</span> <span class=\"token function\">mpconfig</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>mp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Expect to run on an SMP\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  ismp <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\n  lapic <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>uint<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token operator\">-></span>lapicaddr<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>p<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>conf<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> e<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token operator\">+</span>conf<span class=\"token operator\">-></span>length<span class=\"token punctuation\">;</span> p<span class=\"token operator\">&lt;</span>e<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">switch</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>p<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> MPPROC<span class=\"token operator\">:</span>\n      proc <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>ncpu <span class=\"token operator\">&lt;</span> NCPU<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        cpus<span class=\"token punctuation\">[</span>ncpu<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>apicid <span class=\"token operator\">=</span> proc<span class=\"token operator\">-></span>apicid<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// apicid may differ from ncpu</span>\n        ncpu<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> MPIOAPIC<span class=\"token operator\">:</span>\n      ioapic <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n      ioapicid <span class=\"token operator\">=</span> ioapic<span class=\"token operator\">-></span>apicno<span class=\"token punctuation\">;</span>\n      p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> MPBUS<span class=\"token operator\">:</span>\n    <span class=\"token keyword\">case</span> MPIOINTR<span class=\"token operator\">:</span>\n    <span class=\"token keyword\">case</span> MPLINTR<span class=\"token operator\">:</span>\n      p <span class=\"token operator\">+=</span> <span class=\"token number\">8</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n      ismp <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>ismp<span class=\"token punctuation\">)</span>\n    <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Didn't find a suitable machine\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>mp<span class=\"token operator\">-></span>imcrp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Bochs doesn't support IMCR, so this doesn't run on Bochs.</span>\n    <span class=\"token comment\">// But it would on real hardware.</span>\n    <span class=\"token function\">outb</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x22</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0x70</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>   <span class=\"token comment\">// Select IMCR</span>\n    <span class=\"token function\">outb</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x23</span><span class=\"token punctuation\">,</span> <span class=\"token function\">inb</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x23</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">|</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// Mask external interrupts.</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Let’s read through the source code step by step.</p>\n<h3 id=\"declaring-structure-variables\" style=\"position:relative;\"><a href=\"#declaring-structure-variables\" aria-label=\"declaring structure variables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Declaring structure variables</h3>\n<p>After the function call, several structure variables are declared.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">uchar <span class=\"token operator\">*</span>p<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>e<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">int</span> ismp<span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token operator\">*</span>mp<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span> <span class=\"token operator\">*</span>conf<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span> <span class=\"token operator\">*</span>proc<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span> <span class=\"token operator\">*</span>ioapic<span class=\"token punctuation\">;</span></code></pre></div>\n<p>All of these are defined in <code class=\"language-text\">mp.h</code>.</p>\n<p>The structure definitions are as follows. I will skip the details for now and cover them when the source code actually uses them.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// See MultiProcessor Specification Version 1.[14]</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token punctuation\">{</span>             <span class=\"token comment\">// floating pointer</span>\n  uchar signature<span class=\"token punctuation\">[</span><span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>           <span class=\"token comment\">// \"_MP_\"</span>\n  <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>physaddr<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// phys addr of MP config table</span>\n  uchar length<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// 1</span>\n  uchar specrev<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// [14]</span>\n  uchar checksum<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// all bytes must add up to 0</span>\n  uchar type<span class=\"token punctuation\">;</span>                   <span class=\"token comment\">// MP system config type</span>\n  uchar imcrp<span class=\"token punctuation\">;</span>\n  uchar reserved<span class=\"token punctuation\">[</span><span class=\"token number\">3</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span> <span class=\"token punctuation\">{</span>         <span class=\"token comment\">// configuration table header</span>\n  uchar signature<span class=\"token punctuation\">[</span><span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>           <span class=\"token comment\">// \"PCMP\"</span>\n  ushort length<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// total table length</span>\n  uchar version<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// [14]</span>\n  uchar checksum<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// all bytes must add up to 0</span>\n  uchar product<span class=\"token punctuation\">[</span><span class=\"token number\">20</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>            <span class=\"token comment\">// product id</span>\n  uint <span class=\"token operator\">*</span>oemtable<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// OEM table pointer</span>\n  ushort oemlength<span class=\"token punctuation\">;</span>             <span class=\"token comment\">// OEM table length</span>\n  ushort entry<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// entry count</span>\n  uint <span class=\"token operator\">*</span>lapicaddr<span class=\"token punctuation\">;</span>              <span class=\"token comment\">// address of local APIC</span>\n  ushort xlength<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// extended table length</span>\n  uchar xchecksum<span class=\"token punctuation\">;</span>              <span class=\"token comment\">// extended table checksum</span>\n  uchar reserved<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span> <span class=\"token punctuation\">{</span>         <span class=\"token comment\">// processor table entry</span>\n  uchar type<span class=\"token punctuation\">;</span>                   <span class=\"token comment\">// entry type (0)</span>\n  uchar apicid<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// local APIC id</span>\n  uchar version<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// local APIC verison</span>\n  uchar flags<span class=\"token punctuation\">;</span>                  <span class=\"token comment\">// CPU flags</span>\n    <span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MPBOOT</span> <span class=\"token expression\"><span class=\"token number\">0x02</span>           </span><span class=\"token comment\">// This proc is the bootstrap processor.</span></span>\n  uchar signature<span class=\"token punctuation\">[</span><span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>           <span class=\"token comment\">// CPU signature</span>\n  uint feature<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// feature flags from CPUID instruction</span>\n  uchar reserved<span class=\"token punctuation\">[</span><span class=\"token number\">8</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span> <span class=\"token punctuation\">{</span>       <span class=\"token comment\">// I/O APIC table entry</span>\n  uchar type<span class=\"token punctuation\">;</span>                   <span class=\"token comment\">// entry type (2)</span>\n  uchar apicno<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// I/O APIC id</span>\n  uchar version<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// I/O APIC version</span>\n  uchar flags<span class=\"token punctuation\">;</span>                  <span class=\"token comment\">// I/O APIC flags</span>\n  uint <span class=\"token operator\">*</span>addr<span class=\"token punctuation\">;</span>                  <span class=\"token comment\">// I/O APIC address</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"about-the-mp-specification\" style=\"position:relative;\"><a href=\"#about-the-mp-specification\" aria-label=\"about the mp specification permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About the MP specification</h3>\n<p>Before reading the source code, let me summarize the MP specification.</p>\n<p>The MP table is a mechanism that allows an OS on an x86 CPU to obtain multiprocessor information.</p>\n<p>The MP table contains information related to the MP specification of x86 CPUs.</p>\n<p>The following diagram, from Intel’s documentation, shows the data structure of the MP specification.</p>\n<p>It depicts the <code class=\"language-text\">FLOATING POINTER STRUCTURE</code> pointing to the <code class=\"language-text\">FIXED-LENGTH HEADER</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/39dd9bb88a7189f5967b9d92bba7b4ba/0b533/image-29.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 86.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAARlAAAEZQAGA43XUAAAB7ElEQVQ4y2WUiY6CQBBE+f9vW40bz0QNuq4niqIg4NU7r9fGESfpMGdNdXUNQZ7nkmVZFcfjUXa7nSRJIpvNRrbbraRpKvv9Xk6nkySHg84d3Jc59p3PZ91TFIUEUmv3+70+JePxWJrNprRa3+5w/rZ2vV7fxsHj8RAL2uVyUabcBnu+MOr3+/Izmykb5gn6rNMMIzAga2ww+naoLEu53W7KhnnG9LmcvQaoDG3AAZppuo0iWSyXslgsZD6fayzdOM8L1W3m2DJGxw9AdIuijWr11WhoYSytenBZ5C5br9f69QE1ZR+dNAAjrSQ5aLV3Tj8OomPsxsUzfYCtum8MrWNf9AEUi2ANghQBYA6W2CkMQ5WD1IuirDACn65pCIgVJHdsGU+nU03T9xx7SNmsVgH6DNlU9xash8OhkyD+8CjZ+Fl+AGIFUlSmz5cAmyxLn0VJFQSmZycD/mRcAfroxN0JzkFYWWX/AbOqb15kTIEAN9t9aMiCsTJgWPvhW8guMpkCHwj6vFdEt0NxHGsxVquVGpm+WYbAUr51Xhq6Sv06C4STSVVFgioa4OoJ6L9nLnz7OfjUoQ2YvQA2YxlEf0Wia7aO+c1KyBP44hMsDAYDGY1GGp1OR9rttnS7XQ36vV5Pjc1e++NwFn3/AEu3IidA9NVQAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/39dd9bb88a7189f5967b9d92bba7b4ba/8ac56/image-29.webp 240w,\n/static/39dd9bb88a7189f5967b9d92bba7b4ba/d3be9/image-29.webp 480w,\n/static/39dd9bb88a7189f5967b9d92bba7b4ba/b0a15/image-29.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/39dd9bb88a7189f5967b9d92bba7b4ba/8ff5a/image-29.png 240w,\n/static/39dd9bb88a7189f5967b9d92bba7b4ba/e85cb/image-29.png 480w,\n/static/39dd9bb88a7189f5967b9d92bba7b4ba/0b533/image-29.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/39dd9bb88a7189f5967b9d92bba7b4ba/0b533/image-29.png\"\n            alt=\"2022/01/image-29.png\"\n            title=\"2022/01/image-29.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Intel MultiProcessor Specification | ManualsLib</a></p>\n<p>This <code class=\"language-text\">FLOATING POINTER STRUCTURE</code> is the MP Floating Pointer Structure, defined in xv6OS as the <code class=\"language-text\">mp</code> structure.</p>\n<p>If a system has an MP Floating Pointer Structure, it means the system conforms to the MP specification.</p>\n<p>The MP Floating Pointer Structure contains the following information:</p>\n<ul>\n<li>A pointer to the MP Configuration Table</li>\n<li>Pointers to other MP information</li>\n</ul>\n<p>The MP Configuration Table is defined as the <code class=\"language-text\">mpconf</code> structure in xv6OS.</p>\n<p>The <code class=\"language-text\">mpconfig</code> function described later defines the processing that obtains the MP Configuration Table after retrieving the MP Floating Pointer Structure.</p>\n<p>Now, how does the OS find the MP Floating Pointer Structure? According to the Intel specification, the MP Floating Pointer Structure is defined to exist in one of the following locations, so the OS searches these locations to check whether one is present:</p>\n<ul>\n<li>Within the first 1 KiB of the Extended BIOS Data Area (EBDA)</li>\n<li>Within the last 1 KiB of the system base memory</li>\n<li>In the BIOS ROM address space between <code class=\"language-text\">0x0F0000</code> and <code class=\"language-text\">0x0FFFFFF</code></li>\n</ul>\n<p>In xv6OS, the <code class=\"language-text\">mpsearch</code> and <code class=\"language-text\">mpsearch1</code> functions perform the search in the above regions.</p>\n<p>These functions are described below.</p>\n<p>Next, regarding the MP Configuration Table — it appears to be an optional component in the default configuration.</p>\n<p>If the system uses the default configuration, defining the MP Configuration Table is unnecessary; however, it becomes required when the number of CPUs may vary. (In practice it is effectively required for any general-purpose OS.)</p>\n<p>The MP Configuration Table contains configuration information about the APIC, processors, buses, and interrupts.</p>\n<p>A new term has appeared: APIC. This is the interrupt control mechanism used in Intel’s multiprocessor CPUs.</p>\n<p>I plan to look at APIC in more detail when configuring the interrupt controller in xv6OS.</p>\n<p>Reference: <a href=\"https://wiki.osdev.org/APIC\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">APIC - OSDev Wiki</a></p>\n<p>Since I could not find much useful information about the MP specification from web pages or books, reading Intel’s specification document directly is probably the fastest way to learn more.</p>\n<p>Reference: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html?page=37#manual\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Chapter 4 MP Configuration Table; MP Configuration Data Structures - Intel MultiProcessor Specification [Page 37] | ManualsLib</a></p>\n<h3 id=\"obtaining-the-mp-floating-pointer-structure\" style=\"position:relative;\"><a href=\"#obtaining-the-mp-floating-pointer-structure\" aria-label=\"obtaining the mp floating pointer structure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Obtaining the MP Floating Pointer Structure</h3>\n<p>With that background, let’s look at the following code:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>conf <span class=\"token operator\">=</span> <span class=\"token function\">mpconfig</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>mp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Expect to run on an SMP\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">mp</code> structure is passed as an argument to <code class=\"language-text\">mpconfig</code>, and the return value is stored in <code class=\"language-text\">conf</code>, a variable of type <code class=\"language-text\">mpconf</code>.</p>\n<p>This line initializes the <code class=\"language-text\">mpconf</code> variable <code class=\"language-text\">conf</code> and also checks whether the system is running on an SMP.</p>\n<p>SMP stands for Symmetric Multiprocessing (or Shared-Memory Multiprocessing) — essentially a multiprocessor system in which multiple CPUs share memory resources.</p>\n<p>Reference: <a href=\"https://en.wikipedia.org/wiki/Symmetric_multiprocessing\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Symmetric multiprocessing - Wikipedia</a></p>\n<p>Reference: <a href=\"https://wiki.osdev.org/Symmetric_Multiprocessing\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Symmetric Multiprocessing - OSDev Wiki</a></p>\n<p>Let’s look at the source code of <code class=\"language-text\">mpconfig</code>.</p>\n<p><code class=\"language-text\">mpconfig</code> takes the address of the <code class=\"language-text\">mp</code> structure object declared in <code class=\"language-text\">mpinit</code> as its argument, and returns an <code class=\"language-text\">mpconf</code> structure.</p>\n<p>This function searches for the MP table and initializes both the <code class=\"language-text\">mp</code> structure object passed as the argument and the returned <code class=\"language-text\">mpconf</code> structure.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Search for an MP configuration table.  For now,</span>\n<span class=\"token comment\">// don't accept the default configurations (physaddr == 0).</span>\n<span class=\"token comment\">// Check for correct signature, calculate the checksum and,</span>\n<span class=\"token comment\">// if correct, check the version.</span>\n<span class=\"token comment\">// To do: check extended table checksum.</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span><span class=\"token operator\">*</span> <span class=\"token function\">mpconfig</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span>pmp<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span> <span class=\"token operator\">*</span>conf<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token operator\">*</span>mp<span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>mp <span class=\"token operator\">=</span> <span class=\"token function\">mpsearch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span> <span class=\"token operator\">||</span> mp<span class=\"token operator\">-></span>physaddr <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  conf <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span> mp<span class=\"token operator\">-></span>physaddr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">memcmp</span><span class=\"token punctuation\">(</span>conf<span class=\"token punctuation\">,</span> <span class=\"token string\">\"PCMP\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>conf<span class=\"token operator\">-></span>version <span class=\"token operator\">!=</span> <span class=\"token number\">1</span> <span class=\"token operator\">&amp;&amp;</span> conf<span class=\"token operator\">-></span>version <span class=\"token operator\">!=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">sum</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token punctuation\">,</span> conf<span class=\"token operator\">-></span>length<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n  <span class=\"token operator\">*</span>pmp <span class=\"token operator\">=</span> mp<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> conf<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The <code class=\"language-text\">mp</code> structure refers to the MP Floating Pointer Structure described above.</p>\n<p>At the point <code class=\"language-text\">mpconfig</code> is called, the system’s MP Floating Pointer Structure has not yet been obtained, so the search must be performed first.</p>\n<p>This is done by calling <code class=\"language-text\">mpsearch</code> and <code class=\"language-text\">mpsearch1</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Look for an MP structure in the len bytes at addr.</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span><span class=\"token operator\">*</span> <span class=\"token function\">mpsearch1</span><span class=\"token punctuation\">(</span>uint a<span class=\"token punctuation\">,</span> <span class=\"token keyword\">int</span> len<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  uchar <span class=\"token operator\">*</span>e<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>p<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>addr<span class=\"token punctuation\">;</span>\n  addr <span class=\"token operator\">=</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  e <span class=\"token operator\">=</span> addr<span class=\"token operator\">+</span>len<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>p <span class=\"token operator\">=</span> addr<span class=\"token punctuation\">;</span> p <span class=\"token operator\">&lt;</span> e<span class=\"token punctuation\">;</span> p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">memcmp</span><span class=\"token punctuation\">(</span>p<span class=\"token punctuation\">,</span> <span class=\"token string\">\"_MP_\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span> <span class=\"token operator\">&amp;&amp;</span> <span class=\"token function\">sum</span><span class=\"token punctuation\">(</span>p<span class=\"token punctuation\">,</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// Search for the MP Floating Pointer Structure, which according to the</span>\n<span class=\"token comment\">// spec is in one of the following three locations:</span>\n<span class=\"token comment\">// 1) in the first KB of the EBDA;</span>\n<span class=\"token comment\">// 2) in the last KB of system base memory;</span>\n<span class=\"token comment\">// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.</span>\n<span class=\"token keyword\">static</span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span><span class=\"token operator\">*</span> <span class=\"token function\">mpsearch</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">void</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n  uchar <span class=\"token operator\">*</span>bda<span class=\"token punctuation\">;</span>\n  uint p<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token operator\">*</span>mp<span class=\"token punctuation\">;</span>\n\n  bda <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>uchar <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x400</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>p <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>bda<span class=\"token punctuation\">[</span><span class=\"token number\">0x0F</span><span class=\"token punctuation\">]</span><span class=\"token operator\">&lt;&lt;</span><span class=\"token number\">8</span><span class=\"token punctuation\">)</span><span class=\"token operator\">|</span> bda<span class=\"token punctuation\">[</span><span class=\"token number\">0x0E</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>mp <span class=\"token operator\">=</span> <span class=\"token function\">mpsearch1</span><span class=\"token punctuation\">(</span>p<span class=\"token punctuation\">,</span> <span class=\"token number\">1024</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> mp<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    p <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>bda<span class=\"token punctuation\">[</span><span class=\"token number\">0x14</span><span class=\"token punctuation\">]</span><span class=\"token operator\">&lt;&lt;</span><span class=\"token number\">8</span><span class=\"token punctuation\">)</span><span class=\"token operator\">|</span>bda<span class=\"token punctuation\">[</span><span class=\"token number\">0x13</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token operator\">*</span><span class=\"token number\">1024</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>mp <span class=\"token operator\">=</span> <span class=\"token function\">mpsearch1</span><span class=\"token punctuation\">(</span>p<span class=\"token operator\">-</span><span class=\"token number\">1024</span><span class=\"token punctuation\">,</span> <span class=\"token number\">1024</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> mp<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> <span class=\"token function\">mpsearch1</span><span class=\"token punctuation\">(</span><span class=\"token number\">0xF0000</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0x10000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>As noted above, if the MP Floating Pointer Structure is present, it is located in one of the following:</p>\n<ul>\n<li>Within the first 1 KiB of the Extended BIOS Data Area (EBDA)</li>\n<li>Within the last 1 KiB of the system base memory</li>\n<li>In the BIOS ROM address space between <code class=\"language-text\">0x0F0000</code> and <code class=\"language-text\">0x0FFFFFF</code></li>\n</ul>\n<p>These areas are searched, and if the MP Floating Pointer Structure is found, it is stored in <code class=\"language-text\">mp</code>.</p>\n<p>If the MP Floating Pointer Structure is not found, or if the address of the MP Configuration Table held by the MP Floating Pointer Structure is empty, the kernel terminates.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>mp <span class=\"token operator\">=</span> <span class=\"token function\">mpsearch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span> <span class=\"token operator\">||</span> mp<span class=\"token operator\">-></span>physaddr <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The MP Floating Pointer Structure has the following layout:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mp</span> <span class=\"token punctuation\">{</span>             <span class=\"token comment\">// floating pointer</span>\n  uchar signature<span class=\"token punctuation\">[</span><span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>           <span class=\"token comment\">// \"_MP_\"</span>\n  <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>physaddr<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// phys addr of MP config table</span>\n  uchar length<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// 1</span>\n  uchar specrev<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// [14]</span>\n  uchar checksum<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// all bytes must add up to 0</span>\n  uchar type<span class=\"token punctuation\">;</span>                   <span class=\"token comment\">// MP system config type</span>\n  uchar imcrp<span class=\"token punctuation\">;</span>\n  uchar reserved<span class=\"token punctuation\">[</span><span class=\"token number\">3</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The definition of the <code class=\"language-text\">mp</code> structure is as above, but the diagram from the Intel specification is easier to visualize, so I am including it here.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/89053dbef9ccb06f6561234b34173eaa/0b533/image-30.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAARlAAAEZQAGA43XUAAABz0lEQVQoz01S2W7CQAzM/38TfQKJW4irhQINOYCEcARCQkiAqcewVVeyNvHaY4/HVhiG2O/3OBwOap7ngj5+n89nHI9HbLdbxHGsPsYGQYBot/vLiaJIYhMkSQLrdDrhdrupFUWhAJc0xf1+h23/oNPpoF5vwF+t1JfnOdIsQ/7OKcsSl8tFC/Hd4s//83g89IEnirZot9vo9XpI00x9z+dTC5sYnixLsfJ9uTNYpPU9naLRaGjyerPBUWjYtg3HcZQqi27E77mu0icr0nOWSx1PkrDDnRQqXx0SdDweYb1eazLnQjCCEpDUCLgS2juZHWNo8/lc/amMKJD7es1hsRLbJxXenAkLsJtAqvtCZTqZKJgrPt5F8Zq3OQRkp8xVQD7SjDCJADJRaXqedmr+WcTE/heFShflmzI7IzUOld9GzTAM0O/3MRwOhd5COyEAAQ0T5jOP47qJ3yJQnl8xm81U+r3MKJEg13WwWCw0mKtESiMB5jdFYUFPYry3upGIdZcNsagaRWAQK/q+p0qapeYSs7p5j+OXzyw+jUKxe5rF1inIQWSvVD7wOR7jS0Sg6tVqFYPBALVaDa1mU9eq1WqhLcve7XbUt3RczTfz/wUC5z2KzlmzsAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/89053dbef9ccb06f6561234b34173eaa/8ac56/image-30.webp 240w,\n/static/89053dbef9ccb06f6561234b34173eaa/d3be9/image-30.webp 480w,\n/static/89053dbef9ccb06f6561234b34173eaa/b0a15/image-30.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/89053dbef9ccb06f6561234b34173eaa/8ff5a/image-30.png 240w,\n/static/89053dbef9ccb06f6561234b34173eaa/e85cb/image-30.png 480w,\n/static/89053dbef9ccb06f6561234b34173eaa/0b533/image-30.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/89053dbef9ccb06f6561234b34173eaa/0b533/image-30.png\"\n            alt=\"2022/01/image-30.png\"\n            title=\"2022/01/image-30.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Intel MultiProcessor Specification | ManualsLib</a></p>\n<p>The first 4 bytes of <code class=\"language-text\">SIGNATURE</code> are expected to contain <code class=\"language-text\">_MP_</code>.</p>\n<p>When <code class=\"language-text\">mpsearch</code> and <code class=\"language-text\">mpsearch1</code> perform their search, they look for this <code class=\"language-text\">SIGNATURE</code>.</p>\n<p><code class=\"language-text\">physaddr</code> holds the address of the MP Configuration Table; from here we use that information to obtain the MP Configuration Table.</p>\n<h3 id=\"obtaining-the-mp-configuration-table\" style=\"position:relative;\"><a href=\"#obtaining-the-mp-configuration-table\" aria-label=\"obtaining the mp configuration table permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Obtaining the MP Configuration Table</h3>\n<p>After obtaining the MP Floating Pointer Structure, the virtual address of the MP Configuration Table is retrieved and stored as the pointer variable <code class=\"language-text\">conf</code> of type <code class=\"language-text\">mpconf</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span> <span class=\"token operator\">*</span>conf<span class=\"token punctuation\">;</span>\nconf <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> <span class=\"token function\">P2V</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uint<span class=\"token punctuation\">)</span> mp<span class=\"token operator\">-></span>physaddr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">memcmp</span><span class=\"token punctuation\">(</span>conf<span class=\"token punctuation\">,</span> <span class=\"token string\">\"PCMP\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>conf<span class=\"token operator\">-></span>version <span class=\"token operator\">!=</span> <span class=\"token number\">1</span> <span class=\"token operator\">&amp;&amp;</span> conf<span class=\"token operator\">-></span>version <span class=\"token operator\">!=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">sum</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token punctuation\">,</span> conf<span class=\"token operator\">-></span>length<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The MP Configuration Table has the following structure:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpconf</span> <span class=\"token punctuation\">{</span>         <span class=\"token comment\">// configuration table header</span>\n  uchar signature<span class=\"token punctuation\">[</span><span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>           <span class=\"token comment\">// \"PCMP\"</span>\n  ushort length<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// total table length</span>\n  uchar version<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// [14]</span>\n  uchar checksum<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// all bytes must add up to 0</span>\n  uchar product<span class=\"token punctuation\">[</span><span class=\"token number\">20</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>            <span class=\"token comment\">// product id</span>\n  uint <span class=\"token operator\">*</span>oemtable<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// OEM table pointer</span>\n  ushort oemlength<span class=\"token punctuation\">;</span>             <span class=\"token comment\">// OEM table length</span>\n  ushort entry<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// entry count</span>\n  uint <span class=\"token operator\">*</span>lapicaddr<span class=\"token punctuation\">;</span>              <span class=\"token comment\">// address of local APIC</span>\n  ushort xlength<span class=\"token punctuation\">;</span>               <span class=\"token comment\">// extended table length</span>\n  uchar xchecksum<span class=\"token punctuation\">;</span>              <span class=\"token comment\">// extended table checksum</span>\n  uchar reserved<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The following is a structural diagram quoted from the Intel specification.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 476px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/6dd866aa292a4e75103c8b5ea32eaf83/f2205/image-31.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 126.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAARlAAAEZQAGA43XUAAADeUlEQVQ4y2WV6XLaUAyF/f7Pkb5HM9P+SiYEwr4vjrENBAibAYOqTyCnae/MnbtpOTqS5WA2m8lisZD9fm/z/f1dBoOh3THTJNHzQD4+Puw9yzLdL2S9Xtv5cDjYebVaS57nEmy2W+l02vL09CSlUknG47Gslkv5/euXPDz8kFa7LbvdTjabjfS6XanX69Lv96Wr++FwKO1W297SJJY0nUmwWq0MQaPRkLYqp2kqW3VSLr/Kz8dH6fV6hiLTmShaIiAq9lEUyWQyEWx4lAHK5/NZfLRaLUOBdxyB2Jx1OmYsiqZmhL2Py+Vq1MznCwk+Pz+FSVhH5QfPTJCGYWgoMMo+jmO7Z87nc+MTPUCBkHMATEfohtI0MQUfhMzI87PxB8LRaGh7EmG6OFMqAgjFy+l0MjRhiPDIQjqrMM6QYT0ejwVCd344ZEWmDSFw2WDwer0WqPDcaNSleU8W2X57e5ODyjKQvVwupoezOJ5a2IZwqwj9EQfGp6Ihe2QU7qBgqeWEc2hC7qSGcMyZOkUn8GT0el0NI72jPZsBCpyBIwaZR5EzctNppHp9M4wdhiHc3wsXTzzAyW63ldLLizSbDSOfUnp+fi7ePRL0/GwGPSGDQd+yBB9M7kDJilKWHc1Afk8Uk8wSRZ5fviPk8IVsZ0jhw5OFDCt3TOfQI/JzgRCvXCDsWWOlATBQ0LzKWpN0PJ5M/mgOsgJZrHxG0+n3LwVFMsv5bxRk1873aHhHziMjAnduXwoeqXzqiD01tlotrTFw3llZ5bcC17OXGKvL36KQG0LPGBxuNl97ipVibt8bBmWFIUcFx8hhjPN/WZ79k2UQM5C5Xi8WqhczXMLh591QOBnr5xopQr2ADyY8ULiszgsr5UMU7DHKPZM9DZo39KEgyDSzE7VOaK/asaNpbKHUanWp6l2iDcC7EZzWqlWp6uxofyyXy9bWDKE2FZpLweFFifXyYbLP1VBXFSuVijUISoUWZh1cneIIVMgvlx92Dnik/vhfhOG7CZA16gokIKBN0SBAFcdJkd2p1l2z2bSOHd27eTC3/0Nqj/DHBz/SDk1/wxARhCrM6n9IX6nPJEmKTmQc+qfHCge3/0ZkCnynlM5Q/y0gIIszdUIDBrnLYoywcRp4QyV+SK7WakXHhjtaVqn0IuXXkr5X7I0EEiqUvGhHonZ9/AE7OWhVjDxa3AAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/6dd866aa292a4e75103c8b5ea32eaf83/8ac56/image-31.webp 240w,\n/static/6dd866aa292a4e75103c8b5ea32eaf83/cf53a/image-31.webp 476w\"\n              sizes=\"(max-width: 476px) 100vw, 476px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/6dd866aa292a4e75103c8b5ea32eaf83/8ff5a/image-31.png 240w,\n/static/6dd866aa292a4e75103c8b5ea32eaf83/f2205/image-31.png 476w\"\n            sizes=\"(max-width: 476px) 100vw, 476px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/6dd866aa292a4e75103c8b5ea32eaf83/f2205/image-31.png\"\n            alt=\"2022/01/image-31.png\"\n            title=\"2022/01/image-31.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Intel MultiProcessor Specification | ManualsLib</a></p>\n<p>The first 4 bytes hold the <code class=\"language-text\">SIGNATURE</code>, which is expected to be <code class=\"language-text\">PCMP</code>.</p>\n<p>In xv6OS, the <code class=\"language-text\">memcmp</code> function checks whether the first 4 bytes of the retrieved MP Configuration Table match <code class=\"language-text\">PCMP</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">memcmp</span><span class=\"token punctuation\">(</span>conf<span class=\"token punctuation\">,</span> <span class=\"token string\">\"PCMP\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>conf<span class=\"token operator\">-></span>version <span class=\"token operator\">!=</span> <span class=\"token number\">1</span> <span class=\"token operator\">&amp;&amp;</span> conf<span class=\"token operator\">-></span>version <span class=\"token operator\">!=</span> <span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">sum</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token punctuation\">,</span> conf<span class=\"token operator\">-></span>length<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>It also checks whether the version information is appropriate and whether the data size matches the actual size.</p>\n<p>With this, the following processing in <code class=\"language-text\">mpinit</code> is complete, and both the MP Floating Pointer Structure and the MP Configuration Table have been obtained.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>conf <span class=\"token operator\">=</span> <span class=\"token function\">mpconfig</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>mp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span> <span class=\"token function\">panic</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Expect to run on an SMP\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"obtaining-the-ioapic-from-the-mp-configuration-table\" style=\"position:relative;\"><a href=\"#obtaining-the-ioapic-from-the-mp-configuration-table\" aria-label=\"obtaining the ioapic from the mp configuration table permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Obtaining the IOAPIC from the MP Configuration Table</h3>\n<p>Next, the address obtained from <code class=\"language-text\">lapicaddr</code> in the MP Configuration Table is stored into <code class=\"language-text\">lapic</code>, and <code class=\"language-text\">ismp</code> is initialized.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">int</span> ismp<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span> <span class=\"token operator\">*</span>ioapic<span class=\"token punctuation\">;</span>\n\nismp <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\nlapic <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>uint<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token operator\">-></span>lapicaddr<span class=\"token punctuation\">;</span></code></pre></div>\n<p>The <code class=\"language-text\">mpioapic</code> structure is as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span> <span class=\"token punctuation\">{</span>       <span class=\"token comment\">// I/O APIC table entry</span>\n  uchar type<span class=\"token punctuation\">;</span>                   <span class=\"token comment\">// entry type (2)</span>\n  uchar apicno<span class=\"token punctuation\">;</span>                 <span class=\"token comment\">// I/O APIC id</span>\n  uchar version<span class=\"token punctuation\">;</span>                <span class=\"token comment\">// I/O APIC version</span>\n  uchar flags<span class=\"token punctuation\">;</span>                  <span class=\"token comment\">// I/O APIC flags</span>\n  uint <span class=\"token operator\">*</span>addr<span class=\"token punctuation\">;</span>                  <span class=\"token comment\">// I/O APIC address</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The Intel specification diagram is as follows.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/aa0f5df371a8d16482b51da6fec26f48/0b533/image-32.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 68.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAARlAAAEZQAGA43XUAAACBUlEQVQ4y3VT2ZKiQBD0//9n9tEXn8YxQiZmFA9uEcFVQUNBQcytLGSXNXaJqOimKju7juzedrtFEARYryPEmw08z8d+v8dyaSHLMmzEx/9NFAlmrft2ZeznbockSZDnOc7nM3qHw0EdOwnQ4jhGmqbq830f4/EY0+lU/SRhjLjuSiyJ+SkhnVzbPQ8ej0fYtg3DGOPr6xuJVNLGiGtX2lYII6ngfr+jx0CbXdfo930PpmlisVgglkP/wjalR2Dr6rpuCF+NQGboOA5GoxGMz0/x/cmsa/SRMAxDyVAIr9erNrQoCjXu6WN5HBaBifSP+y6ui+XwWHZdP9CrqgplWf5lVXXXiXmeB9d1EclUSfyKo7Fvp9MJq9WqKZmEt9vtt7VAglgKgb4fqFS6mO6e2CROGsI2SGJaUVx1/PnlotqzLEu1ySnyADNime2eKwnbuA6FZVnLJULJIpPeUS40X/p2EeIso6xS1SIzTZ8YXmbbjiqAg1RCCncwGGA4HKLf72u/Rh8feHv7oRPmFIPA14mzfEcuJyEHQeG3Gmbs8RBhU2fD93d8TyaYz2Z6a1nenlO9dA41EsllukkS4yiEfKp78TFzVqJPr+nDQ/tBWwmRYRgqZrbCdR29bCLGJziV1TRnSsxeFs+VEqKvh5fvID2dz+eq/Oap7VQyLCkM19oSTv1/3y9w/hzqn7A9GwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/aa0f5df371a8d16482b51da6fec26f48/8ac56/image-32.webp 240w,\n/static/aa0f5df371a8d16482b51da6fec26f48/d3be9/image-32.webp 480w,\n/static/aa0f5df371a8d16482b51da6fec26f48/b0a15/image-32.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/aa0f5df371a8d16482b51da6fec26f48/8ff5a/image-32.png 240w,\n/static/aa0f5df371a8d16482b51da6fec26f48/e85cb/image-32.png 480w,\n/static/aa0f5df371a8d16482b51da6fec26f48/0b533/image-32.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/aa0f5df371a8d16482b51da6fec26f48/0b533/image-32.png\"\n            alt=\"2022/01/image-32.png\"\n            title=\"2022/01/image-32.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Intel MultiProcessor Specification | ManualsLib</a></p>\n<p>The IOAPIC is a mechanism that distributes external interrupts among multiple CPUs.</p>\n<p>I mentioned earlier that APIC is an external interrupt mechanism; there appear to be two types of APIC: the Local APIC and the IOAPIC.</p>\n<p>In xv6OS, the Local APIC is implemented in <code class=\"language-text\">lapic.c</code>, and the IOAPIC is implemented in <code class=\"language-text\">ioapic.c</code>.</p>\n<p>The Local APIC handles interrupts built into the CPU, while the IOAPIC receives interrupts from I/O devices and notifies the CPU based on information in the Redirection Table.</p>\n<p>The IOAPIC has an IOAPIC table, and x86 CPUs can define entries in this table through memory-mapped I/O.</p>\n<p>In simple terms, memory-mapped I/O is one way to perform input and output between the CPU and I/O devices: a region of the physical address space is reserved for I/O device input and output, and data is exchanged using the CPU’s memory read/write capabilities.</p>\n<p>Reference: <a href=\"https://mmi.hatenablog.com/entry/2017/04/09/132708\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">About I/O APIC - 睡分不足</a></p>\n<p>Reference: <a href=\"https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%9E%E3%83%83%E3%83%97%E3%83%89I/O\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Memory-mapped I/O - Wikipedia</a></p>\n<p>In a typical system with PCI I/O devices, the IOAPIC detects changes in PCI interrupt signals and issues interrupt messages to the CPU based on the Redirection Table.</p>\n<p>The Local APIC inside the CPU receives this information, calls the interrupt handler to process the interrupt, and then sends an EOI (End of Interrupt) command back to the IOAPIC to notify it that the interrupt has been handled.</p>\n<p>I will cover this in more detail when I get to actually implementing interrupt handling. Probably.</p>\n<p>Reference: <a href=\"https://ja.wikipedia.org/wiki/APIC\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">APIC - Wikipedia</a></p>\n<p>Reference: <a href=\"https://wiki.osdev.org/APIC\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">APIC - OSDev Wiki</a></p>\n<p>Reference: <a href=\"https://wiki.osdev.org/IOAPIC\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">IOAPIC - OSDev Wiki</a></p>\n<p>Reference: <a href=\"https://pdos.csail.mit.edu/6.828/2008/readings/ia32/ioapic.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">82093AA I/O ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER (IOAPIC)</a></p>\n<p>The APIC mechanism was born from the need for an interrupt controller capable of handling interrupts in a multiprocessor environment such as x86 CPUs and their motherboards.</p>\n<p>It seems the earlier, simpler interrupt mechanism called the PIC could not handle interrupt processing in multiprocessor configurations.</p>\n<p>Because xv6OS assumes a multiprocessor configuration, it ignores interrupts from the PIC and implements interrupt processing using the Local APIC and IOAPIC.</p>\n<p>Reference: <a href=\"https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">P45</a></p>\n<p>In the xv6OS code, the address obtained from <code class=\"language-text\">lapicaddr</code> in the MP Configuration Table is stored into the global variable <code class=\"language-text\">lapic</code>.</p>\n<p>The value stored in <code class=\"language-text\">lapicaddr</code> is the address of the memory-mapped Local APIC.</p>\n<p>The variable <code class=\"language-text\">lapic</code> is defined as a global variable in <code class=\"language-text\">defs.h</code>.</p>\n<p>It is not used further within this function; it will be used in <code class=\"language-text\">lapic.c</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">extern</span> <span class=\"token keyword\">volatile</span> uint<span class=\"token operator\">*</span>    lapic<span class=\"token punctuation\">;</span></code></pre></div>\n<h3 id=\"obtaining-processor-information\" style=\"position:relative;\"><a href=\"#obtaining-processor-information\" aria-label=\"obtaining processor information permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Obtaining processor information</h3>\n<p>Let’s look at the loop that comes after obtaining <code class=\"language-text\">lapicaddr</code>.</p>\n<p><code class=\"language-text\">conf</code> holds the MP Configuration Table retrieved earlier.</p>\n<p>According to Intel’s specification, MP Configuration Table entries follow the MP Configuration Table header (the starting address of the MP Configuration Table) in variable numbers.</p>\n<p>In addition to the <code class=\"language-text\">Processor Entries</code> shown earlier, MP Configuration Table entries include <code class=\"language-text\">Bus Entry</code>, <code class=\"language-text\">I/O APIC Entry</code>, <code class=\"language-text\">I/O Interrupt Entry</code>, and <code class=\"language-text\">Local Interrupt Entry</code>. (There are also extended entries.)</p>\n<p>Each of these has a unique <code class=\"language-text\">Entry Type</code> defined in its first byte.</p>\n<ul>\n<li>Processor Entry</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/aa0f5df371a8d16482b51da6fec26f48/0b533/image-32-164559487926114.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 68.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAARlAAAEZQAGA43XUAAACBUlEQVQ4y3VT2ZKiQBD0//9n9tEXn8YxQiZmFA9uEcFVQUNBQcytLGSXNXaJqOimKju7juzedrtFEARYryPEmw08z8d+v8dyaSHLMmzEx/9NFAlmrft2ZeznbockSZDnOc7nM3qHw0EdOwnQ4jhGmqbq830f4/EY0+lU/SRhjLjuSiyJ+SkhnVzbPQ8ej0fYtg3DGOPr6xuJVNLGiGtX2lYII6ngfr+jx0CbXdfo930PpmlisVgglkP/wjalR2Dr6rpuCF+NQGboOA5GoxGMz0/x/cmsa/SRMAxDyVAIr9erNrQoCjXu6WN5HBaBifSP+y6ui+XwWHZdP9CrqgplWf5lVXXXiXmeB9d1EclUSfyKo7Fvp9MJq9WqKZmEt9vtt7VAglgKgb4fqFS6mO6e2CROGsI2SGJaUVx1/PnlotqzLEu1ySnyADNime2eKwnbuA6FZVnLJULJIpPeUS40X/p2EeIso6xS1SIzTZ8YXmbbjiqAg1RCCncwGGA4HKLf72u/Rh8feHv7oRPmFIPA14mzfEcuJyEHQeG3Gmbs8RBhU2fD93d8TyaYz2Z6a1nenlO9dA41EsllukkS4yiEfKp78TFzVqJPr+nDQ/tBWwmRYRgqZrbCdR29bCLGJziV1TRnSsxeFs+VEqKvh5fvID2dz+eq/Oap7VQyLCkM19oSTv1/3y9w/hzqn7A9GwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/aa0f5df371a8d16482b51da6fec26f48/8ac56/image-32-164559487926114.webp 240w,\n/static/aa0f5df371a8d16482b51da6fec26f48/d3be9/image-32-164559487926114.webp 480w,\n/static/aa0f5df371a8d16482b51da6fec26f48/b0a15/image-32-164559487926114.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/aa0f5df371a8d16482b51da6fec26f48/8ff5a/image-32-164559487926114.png 240w,\n/static/aa0f5df371a8d16482b51da6fec26f48/e85cb/image-32-164559487926114.png 480w,\n/static/aa0f5df371a8d16482b51da6fec26f48/0b533/image-32-164559487926114.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/aa0f5df371a8d16482b51da6fec26f48/0b533/image-32-164559487926114.png\"\n            alt=\"2022/01/image-32.png\"\n            title=\"2022/01/image-32.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<ul>\n<li>Bus Entry</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ebb106502198c09c82ee7c65884af857/0b533/image-33.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAARlAAAEZQAGA43XUAAABSElEQVQoz3VRXXOCQAzk//+t+mZrHwUH5U6BooBw+FE4lW026oydaTOTyc0lu0k2wW63A70sSyyXMYyxqKoKdV1jv6+xWq1QFAXattWa7baAtRavuDzLtN65FsHlcoEfBjCSwHUdrtervPdKbEyihAR779H3vZLzPQiO8Xw+K6EXjuB2uykZI4tZMMrbGIM4jrFYRAijCPP5HIPk2Px0OuHVOEAimzTtY8LhMeHxeNRu3t8b0PhHAGPbOiXjhFYaJkmC9XqNL9mA+XEcEbx24nQE05ikk4AxDEOdmmuxKbU0yV2Ow+GApWxTVjWCTjRzzumntQZZliuAHekkoT7cgpJ0nUMqR/iWN+v4R72fMgQc/+k8ApOZAAjK81xXStMUm81Gr8tcLTVN0/zpv1Z+Go/xNpkgkmPQKfj7xwyfsxmm0yn6weM/+wHnhWCKxxlD3wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ebb106502198c09c82ee7c65884af857/8ac56/image-33.webp 240w,\n/static/ebb106502198c09c82ee7c65884af857/d3be9/image-33.webp 480w,\n/static/ebb106502198c09c82ee7c65884af857/b0a15/image-33.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ebb106502198c09c82ee7c65884af857/8ff5a/image-33.png 240w,\n/static/ebb106502198c09c82ee7c65884af857/e85cb/image-33.png 480w,\n/static/ebb106502198c09c82ee7c65884af857/0b533/image-33.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ebb106502198c09c82ee7c65884af857/0b533/image-33.png\"\n            alt=\"2022/01/image-33.png\"\n            title=\"2022/01/image-33.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<ul>\n<li>I/O APIC Entry</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/7ad98ae9eace37cd674ae886ea48e121/0b533/image-34.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAARlAAAEZQAGA43XUAAABTElEQVQozz1R7a6CMBTj/V9LE8UoinKjV0QQjIOBRr4EFOxdZ64/mmXL2tP2GOfzGVmW4Xq94na7wfM8fS/LQqGETBJEUYSiKJDnuUai3tI0/XKEELjf76jrGkZVVej7Hq/XC8MwIAxD7Pd7hEqE4qfTCcfjEa7ramEa4J9S8Yah19ymaRDHMerHAwZdPJ9PdF2nRcXlAt/3IaXUZCF4D7QYXfH9X5D/CTpjKgobJG02a2y3WyyXS7iHg447Go1gmiZyFbVrW2RKzA8CSHWSGAY+FgtL85iA1ZRlBYP5LcvCdDpVwg5Wq5VyIvHjOPCUOB1xOt1xOHsjHioe09Eda0vVv6ZpP4IEOyCZcZNEfgmfiJEunQvhKUSsB3AhBJfEJHop7I898CTe7zfWaxuTyQS2beN3t9MLmc1MjMdjzOdzFXXx7ZDdk9eqWog/BA8JmOWgzGAAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/7ad98ae9eace37cd674ae886ea48e121/8ac56/image-34.webp 240w,\n/static/7ad98ae9eace37cd674ae886ea48e121/d3be9/image-34.webp 480w,\n/static/7ad98ae9eace37cd674ae886ea48e121/b0a15/image-34.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/7ad98ae9eace37cd674ae886ea48e121/8ff5a/image-34.png 240w,\n/static/7ad98ae9eace37cd674ae886ea48e121/e85cb/image-34.png 480w,\n/static/7ad98ae9eace37cd674ae886ea48e121/0b533/image-34.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/7ad98ae9eace37cd674ae886ea48e121/0b533/image-34.png\"\n            alt=\"2022/01/image-34.png\"\n            title=\"2022/01/image-34.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<ul>\n<li>I/O Interrupt Entry</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/8edea3877268c6c4dd0f14c0f9fc9f24/0b533/image-35.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 39.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAARlAAAEZQAGA43XUAAABhUlEQVQoz21Sa2+CQBD0//8sbX010SpaRB4CBUQBkXfig+nOmX5peskFbu92ZnZnB0maoixLVFWFMAxhWhaKolCbcfdwgO/76v56vSLLMniei1Tyft9FkpckCfI8x8DY7aBtNlitVtjv9wp0o85rbLdbBEGgYtp6jZ2uwxLCy+WCXPaaMcmvm0YBP59PDD7mc8xmM0wnYwXcyOVG0zCZTLFcfiIVRV3XwrEtaBKnyrqu0cgej9+FfIu+73FwHGRCMrjf74J+hWmaWAnjcrFQ/7qoITPVJOezOlP18Rirsm1RakhFjgC5nictKfGgwsfjgSgKMRqNMByOYBgGclERfPsIwgiu6+J2u8HY6fLm7aVOiDLpIdvBXpLYse2XwjiOcTrF0mhPVHzBlouqqlVpfMwzv6yk6zq0bQPmNG2rjCJBmiYSb9FTIZvJCwboqmWZCtwTZVEU4SAuszQC0122g1UQtChKZQbJ6bByGX8WARfSRyZlWfoaJXOvpoBO0wROAUfpv/UDy39OoWydYDYAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/8edea3877268c6c4dd0f14c0f9fc9f24/8ac56/image-35.webp 240w,\n/static/8edea3877268c6c4dd0f14c0f9fc9f24/d3be9/image-35.webp 480w,\n/static/8edea3877268c6c4dd0f14c0f9fc9f24/b0a15/image-35.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/8edea3877268c6c4dd0f14c0f9fc9f24/8ff5a/image-35.png 240w,\n/static/8edea3877268c6c4dd0f14c0f9fc9f24/e85cb/image-35.png 480w,\n/static/8edea3877268c6c4dd0f14c0f9fc9f24/0b533/image-35.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/8edea3877268c6c4dd0f14c0f9fc9f24/0b533/image-35.png\"\n            alt=\"2022/01/image-35.png\"\n            title=\"2022/01/image-35.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<ul>\n<li>Local Interrupt Entry</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/3b0896cae18d6fa27616529c9db55817/0b533/image-36.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 39.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAARlAAAEZQAGA43XUAAABhUlEQVQoz11SyZKCQAzl/3/Gmpsnaxy8aImjIloKLqDstBubwOFNEqvmIFVNd9JJXt5La1EUoSxLFEWBsipxPB5xvV7fNvlVlsHzPDyfT/Hl+ROck6ap2Lz4fL/fUdc1NP9yQb/fx8/wG4PBAL7vY7NeY7k0sVgssN3tEMcxttstDMPAfr8Xu64rrExT4nIqmmUpgeXQGGEyGeOr15OE16vBzJjKeTweY2VZgp6mifiUUlDEoG0pbmZgOjXo3BFIJHEat6lUhp1t40R0OWm93uBwOAhVBmAJ3ncz8ed5gSDwYVOO67q4EEumzbJot9tNKs/nc6I9hD4aIQxDWVyEC2SZElBd1+EHgWj7eDwkhgux/d8hd8EJMQnt+4Hop9RV9GDEgDT1zmfq9IWu69A0DZIkkXuW6y1HCm6MYzT+MW3e27aF49gwSWyLCjuOQ7RdWNaKxF/KkHgQvP8So4xeAANUVU2rkk41fHzc+ul0kknyABg5JJpML6D9TN3yS2BmJRX5/P4AbOBPKN6XDQsAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/3b0896cae18d6fa27616529c9db55817/8ac56/image-36.webp 240w,\n/static/3b0896cae18d6fa27616529c9db55817/d3be9/image-36.webp 480w,\n/static/3b0896cae18d6fa27616529c9db55817/b0a15/image-36.webp 500w\"\n              sizes=\"(max-width: 500px) 100vw, 500px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/3b0896cae18d6fa27616529c9db55817/8ff5a/image-36.png 240w,\n/static/3b0896cae18d6fa27616529c9db55817/e85cb/image-36.png 480w,\n/static/3b0896cae18d6fa27616529c9db55817/0b533/image-36.png 500w\"\n            sizes=\"(max-width: 500px) 100vw, 500px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/3b0896cae18d6fa27616529c9db55817/0b533/image-36.png\"\n            alt=\"2022/01/image-36.png\"\n            title=\"2022/01/image-36.png\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Reference image: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Intel MultiProcessor Specification | ManualsLib</a></p>\n<p>The following xv6OS code iterates through each entry from the start of the MP Configuration Header and branches processing according to the value of the first <code class=\"language-text\">Entry Type</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>p<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>conf<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> e<span class=\"token operator\">=</span><span class=\"token punctuation\">(</span>uchar<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>conf<span class=\"token operator\">+</span>conf<span class=\"token operator\">-></span>length<span class=\"token punctuation\">;</span> p<span class=\"token operator\">&lt;</span>e<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">switch</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>p<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\n  <span class=\"token keyword\">case</span> MPPROC<span class=\"token operator\">:</span>\n    proc <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>ncpu <span class=\"token operator\">&lt;</span> NCPU<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      cpus<span class=\"token punctuation\">[</span>ncpu<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>apicid <span class=\"token operator\">=</span> proc<span class=\"token operator\">-></span>apicid<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// apicid may differ from ncpu</span>\n      ncpu<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">case</span> MPIOAPIC<span class=\"token operator\">:</span>\n    ioapic <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n    ioapicid <span class=\"token operator\">=</span> ioapic<span class=\"token operator\">-></span>apicno<span class=\"token punctuation\">;</span>\n    p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">case</span> MPBUS<span class=\"token operator\">:</span>\n  <span class=\"token keyword\">case</span> MPIOINTR<span class=\"token operator\">:</span>\n  <span class=\"token keyword\">case</span> MPLINTR<span class=\"token operator\">:</span>\n    p <span class=\"token operator\">+=</span> <span class=\"token number\">8</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n    ismp <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The entries being checked are defined as follows:</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">// Table entry types</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MPPROC</span>    <span class=\"token expression\"><span class=\"token number\">0x00</span>  </span><span class=\"token comment\">// One per processor</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MPBUS</span>     <span class=\"token expression\"><span class=\"token number\">0x01</span>  </span><span class=\"token comment\">// One per bus</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MPIOAPIC</span>  <span class=\"token expression\"><span class=\"token number\">0x02</span>  </span><span class=\"token comment\">// One per I/O APIC</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MPIOINTR</span>  <span class=\"token expression\"><span class=\"token number\">0x03</span>  </span><span class=\"token comment\">// One per bus interrupt source</span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">MPLINTR</span>   <span class=\"token expression\"><span class=\"token number\">0x04</span>  </span><span class=\"token comment\">// One per system interrupt source</span></span></code></pre></div>\n<h3 id=\"reading-processor-entry-information\" style=\"position:relative;\"><a href=\"#reading-processor-entry-information\" aria-label=\"reading processor entry information permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reading Processor Entry information</h3>\n<p>First is the case for <code class=\"language-text\">Processor Entry</code>.</p>\n<p>Here, the <code class=\"language-text\">Processor Entry</code> is obtained as an <code class=\"language-text\">mpproc</code> structure object, and the <code class=\"language-text\">Local APIC ID</code> values are stored one by one in all elements of the <code class=\"language-text\">cpus</code> array.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">case</span> MPPROC<span class=\"token operator\">:</span>\n  proc <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>ncpu <span class=\"token operator\">&lt;</span> NCPU<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    cpus<span class=\"token punctuation\">[</span>ncpu<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>apicid <span class=\"token operator\">=</span> proc<span class=\"token operator\">-></span>apicid<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// apicid may differ from ncpu</span>\n    ncpu<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpproc</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Incidentally, <code class=\"language-text\">NCPU</code> used here is defined as a constant in <code class=\"language-text\">param.h</code> as follows.</p>\n<p>It appears xv6OS supports up to 8 CPUs.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">NCPU</span>      <span class=\"token expression\"><span class=\"token number\">8</span>  </span><span class=\"token comment\">// maximum number of CPUs</span></span></code></pre></div>\n<h3 id=\"reading-ioapic-information\" style=\"position:relative;\"><a href=\"#reading-ioapic-information\" aria-label=\"reading ioapic information permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reading IOAPIC information</h3>\n<p>Next, IOAPIC information is obtained.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">case</span> MPIOAPIC<span class=\"token operator\">:</span>\n  ioapic <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span><span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>p<span class=\"token punctuation\">;</span>\n  ioapicid <span class=\"token operator\">=</span> ioapic<span class=\"token operator\">-></span>apicno<span class=\"token punctuation\">;</span>\n  p <span class=\"token operator\">+=</span> <span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">mpioapic</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">continue</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>I will skip the details of each structure here since they were covered earlier.</p>\n<h3 id=\"modifying-the-imcr\" style=\"position:relative;\"><a href=\"#modifying-the-imcr\" aria-label=\"modifying the imcr permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Modifying the IMCR</h3>\n<p>With this, the processing in <code class=\"language-text\">mp.c</code> is nearly complete.</p>\n<p>Finally, the <code class=\"language-text\">IMCR</code> is disabled.</p>\n<p>The IMCR is known as the Interrupt Mode Configuration Register; changing the <code class=\"language-text\">IMCR</code> appears to be required in order to switch away from PIC mode.</p>\n<p>Reference: <a href=\"https://reverseengineering.stackexchange.com/questions/26308/where-is-the-imcr-defined-in-the-docs\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">x86 - Where is the IMCR defined in the docs? - Reverse Engineering Stack Exchange</a></p>\n<p>Reference: <a href=\"https://forum.osdev.org/viewtopic.php?f=1&#x26;t=29102\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">OSDev.org • View topic - Set IMCR to 0x1 to mask external interrupts?</a></p>\n<p>Reference: <a href=\"https://www.manualslib.com/manual/77733/Intel-Multiprocessor.html?page=31\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Default Configurations; Symmetric I/O Mode - Intel MultiProcessor Specification [Page 31] | ManualsLib</a></p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>Next time I will start with the <code class=\"language-text\">lapicinit</code> function.</p>\n<p>It seems the information obtained this time will be used to implement the interrupt controller.</p>\n<p>My head is starting to struggle to keep up, so I will try to buckle down.</p>\n<h2 id=\"reference-books\" style=\"position:relative;\"><a href=\"#reference-books\" aria-label=\"reference books permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reference Books</h2>\n<ul>\n<li><a href=\"https://amzn.to/3qZSCY7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Build an OS in 30 Days!</a></li>\n<li><a href=\"https://amzn.to/3qXYsZX\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Introduction to OS Development from Zero</a></li>\n<li><a href=\"https://amzn.to/3q8TU3K\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">An Introduction to OS Code Reading: Learning Kernel Internals with UNIX V6</a></li>\n<li><a href=\"https://amzn.to/3I6fkVt\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Detailed Linux Kernel</a></li>\n<li><a href=\"https://amzn.to/3JRUdI2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Build and Understand an OS: Theory and Implementation for Running x86 Computers</a></li>\n</ul>","fields":{"slug":"/unix-xv6-006-kernel-main-03-en","tagSlugs":["/tag/unix-en/","/tag/xv-6-en/","/tag/kernel-en/","/tag/os-en/","/tag/english/"]},"frontmatter":{"date":"2022-01-31","description":"I am learning about kernels by reading the source code of the educational OS xv6OS. In this article, I walk through the behavior of the xv6OS kernel's main function.","tags":["Unix (en)","xv6 (en)","Kernel (en)","OS (en)","English"],"title":"Reading xv6OS Thoroughly to Fully Understand the Kernel - Multiprocessor Edition -","socialImage":{"publicURL":"/static/12ee68105f5342558992dba6e3ab8add/unix-xv6-006-kernel-main-03.png"}}}},"pageContext":{"slug":"/unix-xv6-006-kernel-main-03-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}