title: computing physical addresses from virtual addresses in C
body: <p>I'm struggling to write a function that translates virtual memory address to physical ones. I want the function to return the physical memory address of a virtual 16-bit address. </p>
  
  <p>I'm just using 16-bit long virtual addresses that ignore permission bits (read,write, etc.). There are 256 pages in the page table so the base table register, which is BTR, just points to the table.</p>
  
  <p>I want the function to either return:
  </p>
  
  <pre class="lang-none prettyprint-override"><code>    Success: the physical address (a void*)
      Page Fault: the virtual page number (an integer)
      Protection Fault: a copy of the PTE
  </code></pre>
  
  <p>Here is the page table entry:</p>
  
  <pre class="lang-none prettyprint-override"><code>    31    30..28 27..............................................4 3 2 1 0
     +-----+------+-------------------------------------------------+-+-+-+-+
     |Valid|unused| 24-bit Physical Page Number                     |P|R|W|X|
     +-----+------+-------------------------------------------------+-+-+-+-+
  </code></pre>
  
  <p>I'm trying to learn how virtual memory works. I'm confused on how I would take a 16-bit virtual address and map it to a 32-bit page table entry, and then how to get the physical address from there. I've defined <code>result_t</code> and a union of the page table entry below, but I'm unsure how to use them. I've gotten a lot of help from looking online but everything is getting muddle together, I just want to learn how everything works straightforwardly.                                </p>
  
  <p>Here are some necessary definitions:
   </p>
  
  <pre class="lang-c prettyprint-override"><code>  extern void* BTR;
  
    typedef struct result_st {
       enum {SUCCESS, PAGEFAULT,
                  PROTFAULT, NOTIMPLEMENTED} status;
       union {
           void* pa;
           unsigned vpn;
           unsigned pte;
       } value;
  
      } result_t;
    static result_t success(void* pa) {
  
        result_t res;
        res.status=SUCCESS;
        res.value.pa = pa;
        return res;
      }
  
    typedef union {
        unsigned All;
        struct {
          unsigned Valid               :1;
          unsigned Unused              :3;
          unsigned PhysicalPageNumber  :24;
          unsigned SupervisoryMode     :1;
          unsigned Read                :1;
          unsigned Execute             :1;
          unsigned Write               :1;
  
        };
      } PageTableEntry;
  
    static int is_valid (unsigned pte) {
  
          return 1 &amp; (pte &gt;&gt; 31);
        }
  </code></pre>
  
  <p>Here is the function I am writing:</p>
  
  <pre class="lang-c prettyprint-override"><code>result_t legacy(unsigned short va)
  {
    result_t result;
    unsigned pte = va &lt;&lt; 8;
    result.value.pte = pte;
    // This is my attempt so far.
    // I want to use is_Valid() somewhere
  
    void* pa = pte &gt;&gt; 8 | (va &amp; 255);
      return success(pa);
  }
  </code></pre>
  
  <p>Thanks for any advice you can provide!</p>