title: How to debug an aarch64 translation fault?
body: <p>I am writing a simple kernel in armv8 (aarch64).</p>
  
  <p>MMU config:</p>
  
  <ul>
  <li>48 VA bits (T1SZ=64-48=16)</li>
  <li>4K page size</li>
  <li>All physical RAM flat mapped into kernel virtual memory (on TTBR1_EL1)
  (MMU is active with TTBR0_EL1=0, so I'm only using addresses in 0xffff&lt; addr >, all flat-mapped into physical memory)</li>
  </ul>
  
  <p>I'm mapping a new address space (starting at 1&lt;&lt;40) to some free physical region. When I try to access address 1&lt;&lt;40, I get an exception (of type "EL1 using SP1, synchronous"):</p>
  
  <pre><code>ESR_EL1=0x96000044
  FAR_EL1=0xffff010000000000
  </code></pre>
  
  <p>Inspecting other registers, I have:</p>
  
  <pre><code>TTBR1_EL1=0x82000000
  TTBR1_EL1[2]=0x0000000082003003
  </code></pre>
  
  <p>So, based on ARM Architecture Reference Manual for ARMv8 (ARMv8-A profile):</p>
  
  <ul>
  <li>ESR (exception syndrome register) translates into: Exception Class=100101 (<strong>Data abort without a change in exception level</strong>) on pages D7-1933 sq. ; WnR=1 (faulting instruction is a write) ; DFSC=0b000100 (<strong>translation fault at level 0</strong>) on page D7-1958 ;</li>
  <li>FAR_EL1 is the faulting address ; it indicates TTBR1_EL1 is used (since high bits are all 1). The VA top 9 bits are 0b000000010, which indicate that entry 2 is used in the table ;</li>
  <li>Entry 2 in the table indicates a next-level table (low bits 0b11) at physical address 0x82003000.</li>
  </ul>
  
  <p>So, translation fails at level 0, where it should not.</p>
  
  <p>My question is: am I doing something wrong? Am I missing some info that could lead to the translation fault? And, more generally, how to debug a translation fault ?</p>
  
  <p><strong>Update:</strong><br>
  Everthing works when I write to tables before enabling the MMU.<br>
  Whenever I write to tables AFTER enabling the MMU (via flat-mapped table region), mapping never works. I wonder why this happens.  </p>
  
  <p>I also tried manually writing to the selected tables (to remove any side effect from my mmapping function): same result (when writes are done before MMU is on, it works; after, it fails). </p>
  
  <p>I tried doing <code>tlbi</code> and <code>dsb sy</code> instructions, followed by <code>isb</code>, without effect. Only one CPU is running at this time so caching should not be a problem - write instructions and MMU talk to the same caches (but I will test it next).</p>