title: what is the right way to update MMU translation table
body: <p>I enabled MMU on my s3c2440 board (3G - 4G memory :: the fault attribute),everything was just fine when I didn't read/write 3G - 4G memory .So to test the page fault vector ,I wrote to a 0xFF to the 3G address,as I expected ,I got the right value from FSR ,So I did this in _do_page_fault (), the step was like this :</p>
  
  <pre><code>.....                 // set new page to translation table 
  .....
  invlidate_icache ();  // clear icache 
  clr_dcache ();        // wb is used ,clear dcache 
  invalidate_ttb ();    // invalidate translation table 
  </code></pre>
  
  <p>and then ISR_dataabort returned ,I read the 3G address to get the 0xFF which I wote before .
  Unfortunately I got a data abort again .(I am sure the translation table value I set is ok)</p>
  
  <p>So what is the correct way to update the MMU translation table .Any help is appreciate ! thanks </p>
  
  <p>here is the Main code I used (just for some test),
  <strong>(I am a littlte strange to ARM ARCH,so this code might be urgly )</strong></p>
  
  <pre><code>/* MMU TTB 0 BASE ATTR */
  #define TTB0_FAULT          (0|(1&lt;&lt;4))          /* TTB FAULT */
  #define TTB0_COARSE         (1|(1&lt;&lt;4))          /* COARSE PAGE BASE ADDR */
  #define TTB0_SEG            (2|(1&lt;&lt;4))          /* SEG BASE ADDR */
  #define TTB0_FINE           (3|(1&lt;&lt;4))          /* FINE PAGE BASE ADDR */
  
  /* MMU TTB 1 BASE ATTR */ 
  #define TTB1_FAULT          (0)
  #define TTB1_LPG            (1)                 /* Large page */
  #define TTB1_SPG            (2)                 /* small page */
  #define TTB1_TPG            (3)                 /* tiny page */
  
  /* domain access priority level */
  #define FAULT_PL            (0x0)               /* domain fault */
  #define USR_PL              (0x1)               /* usr mode */
  #define RSV_PL              (0x2)               /* reserved */
  #define SYS_PL              (0x3)               /* sys mode */
  
  #define DOMAIN_FAULT        (0x0&lt;&lt;5)            /* fault 0*/
  #define DOMAIN_SYS          (0x1&lt;&lt;5)            /* sys 1*/
  #define DOMAIN_USR          (0x2&lt;&lt;5)            /* usr 2*/
  
  /* C,B bit */
  #define CB                  (3&lt;&lt;2)              /* cache_on, write_back */
  #define CNB                 (2&lt;&lt;2)              /* cache_on, write_through */ 
  #define NCB                 (1&lt;&lt;2)              /* cache_off,WR_BUF on */
  #define NCNB                (0&lt;&lt;2)              /* cache_off,WR_BUF off */
  
  /* ap 2 bits */
  #define AP_FAULT            (0&lt;&lt;10)             /* access deny */
  #define AP_SU_ONLY          (1&lt;&lt;10)             /* rw su only */
  #define AP_USR_RO           (2&lt;&lt;10)             /* sup=RW, user=RO */
  #define AP_RW               (3&lt;&lt;10)             /* su=RW, user=RW */
  
  /* page dir 1 ap0 */
  #define AP0_SU_ONLY         (1&lt;&lt;4)             /* rw su only */
  #define AP0_USR_RO          (2&lt;&lt;4)             /* sup=RW, user=RO */
  #define AP0_RW              (3&lt;&lt;4)             /* su=RW, user=RW */
  
  /* page dir 1 ap1 */
  #define AP1_SU_ONLY         (1&lt;&lt;6)             /* rw su only */
  #define AP1_USR_RO          (2&lt;&lt;6)             /* sup=RW, user=RO */
  #define AP1_RW              (3&lt;&lt;6)             /* su=RW, user=RW */
  
  
  /* page dir 1 ap2 */
  #define AP2_SU_ONLY         (1&lt;&lt;8)             /* rw su only */
  #define AP2_USR_RO          (2&lt;&lt;8)             /* sup=RW, user=RO */
  #define AP2_RW              (3&lt;&lt;8)             /* su=RW, user=RW */
  
  /* page dir 1 ap3 */
  #define AP3_SU_ONLY         (1&lt;&lt;10)             /* rw su only */
  #define AP3_USR_RO          (2&lt;&lt;10)             /* sup=RW, user=RO */
  #define AP3_RW              (3&lt;&lt;10)             /* su=RW, user=RW */
  
  
  #define RAM_START           (0x30000000)
  #define KERNEL_ENTRY        (0x30300000)        /* BANK 6 (3M) */
  #define KERNEL_STACK        (0x3001A000)        /* BANK 6 (16K + 64K + 16K + 8K) (8k kernel stack) */
  #define IRQ_STACK           (0x3001B000)        /* 4K IRQ STACK */
  #define KERNEL_IMG_SIZE     (0x20000)            
  
  #define IRQ_STACK           (0x3001B000)
  
  /* 16K aignment */
  #define TTB_BASE            (0x30000000)        
  #define PAGE_DIR0           (TTB_BASE)
  #define TTB_FULL_SIZE       (0x4000)        
  #define PAGE_DIR1           (TTB_BASE+TTB_FULL_SIZE)                 
  
  #define PAGE_DIR0_SIZE      (0x4000)            /* 16k */
  
  
      void _do_page_fault (void)
      {
          //
          ...........
          // 
          // read the FSR &amp;&amp; get the vaddr &amp;&amp; type here 
      volatile unsigned *page_dir = (volatile unsigned*)(TTB_BASE);  
      unsigned index = vaddr &gt;&gt; 20,i = 0, j = 0;
      unsigned page = 0;
  
          if (!(page_dir[index] &amp; ~(0x3FF) &amp;&amp; (type == 0x0B))) {          /* page_dir empty */
              i = index &amp; ~0x03;                                          
              if ( (page_dir[i+0] &amp; ~(0x3FF)) || (page_dir [i+1] &amp; ~(0x3FF))         
                || (page_dir[i+2] &amp; ~(0x3FF)) || (page_dir [i+3] &amp; ~(0x3FF)) )
              {
                  panic ( "page dir is bad !\n" );                        /* 4 continuous page_dir must be 0 */
              }
  
              if (!(page = find_free_page ())) 
                  panic ( "no more free page !\n" );                      /* alloc a page page dir*/
  
              page_dir[i+0] = (page + 0x000) | DOMAIN_USR | TTB0_COARSE ; /* small page 1st 1KB */
              page_dir[i+1] = (page + 0x400) | DOMAIN_USR | TTB0_COARSE ; /* small page 2nd 1KB */
              page_dir[i+2] = (page + 0x800) | DOMAIN_USR | TTB0_COARSE ; /* small page 3rd 1KB */
              page_dir[i+3] = (page + 0xC00) | DOMAIN_USR | TTB0_COARSE ; /* small page 4th 1KB */
  
              if (!(page = find_free_page ())) 
                  panic ( "no more free page !\n" );                      /* alloc a page page table*/
  
              volatile unsigned *page_tbl = (volatile unsigned*) (page_dir[index] &amp; ~(0x3FF));
  
              *page_tbl = page|AP0_RW|AP1_RW|AP2_RW|AP3_RW| NCNB|TTB1_SPG;/* small page is used */
  
  
              invalidate_icache ();
  
              for (i = 0; i &lt; 64; i++)
              {
                  for (j = 0;j &lt; 8;j ++)
                      clr_invalidate_dcache ( (i&lt;&lt;26)|(j&lt;&lt;5) );
              }
  
  
              invalidate_tlb ();
          }
          ........
          //
  
      }
  
      /* here is the macros */
  
      #define invalidate_tlb()    \
      {\
           __asm__  __volatile__ (\
              "mov    r0,#0\n"\
              "mcr    p15,0,r0,c8,c7,0\n"\
              :::"r0" \
          );\
      }
  
      #define clr_invalidate_dcache(index)    \
      {\
          __asm__  __volatile__ (\
              "mcr    p15,0,%[i],c7,c14,2\n"\
              :: [i]"r"(index)\
          );\
      }
  
  
      #define invalidate_icache() \
      {\
          __asm__  __volatile__ (\
              "mov    r0,#0\n"\
              "mcr    p15,0,r0,c7,c5,0\n"\
              ::: "r0"\
          );\
      }
  
      #define invalidate_dcache() \
      {\
          __asm__  __volatile__ (\
              "mov    r0,#0\n"\
              "mcr    p15,0,r0,c7,c6,0\n"\
              ::: "r0"\
          );\
      }
  
  
  
      #define invalidate_idcache()    \
      {\
          __asm__  __volatile__ (\
              "mov    r0,#0\n"\
              "mcr    p15,0,r0,c7,c7,0\n"\
              :::"r0"\
          );\
      }\
  </code></pre>