First a picture:

page




New copy of every accessed data made by fork for a child task,



/************************************************************************
This fault handler serves the tlb data fault at 0x1000 (IVT).
It has purposes:
    -It implements an example of tlb fault handling
    -It implements an example of page table usage
    -It implements an example how to continue after a task crashing
         (the registers demonstrated: cr.ifa, cr.itir, the in instructions demonstrated: itr.d  dtr[] , srlz.d) 

PSEUDO CODE (shared memory as example but code and other data is using the same techique):

    if (the faulting address is not in the area of shared memory)
      if (the faulting address differs from the allowed area to the running task)
        call a fault handler which marks the task as crashed and continues the system
      else
       copy data from "disc" to a new physical block and update page table
    
   set up the correct tlb translation for a shared memory virtual access
   (phys page number finds out from PHYS_pages table)

"PHYS_pages" table for The 64kb shared memory segment:

Virtual page     Physical page

4000000000040000 04f000 (4kb)
4000000000041000 04e000 (4kb)
4000000000042000 04d000 (4kb)
......
400000000004f000 040000

The PHYS_pages created during the startup (k_start.c):

   pps = 0x4f000;//Poor man's page table
   for(_index=0;_index<0x10;_index++) {
     PHYS_pages[_index]=pps;
     pps=pps - 0x1000;
   }


Then: How to see paging to work?

One application task has the code lines:

    ................
         T4_ptr     =(long *)(SHM_PTR+0x2200);//SHM_PTR is 0x4000000000040000
    ...............
         *(T4)=*(T4)+1;
    ...............



    Run the ski. Set break. Make command: dj 42200

    You get:
    0000000000042200 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx

    Make command: dj 4d200 //IF TRANSLATION EXISTS (REGION =0)

    You get:
    000000000004d200 0000000000000190 0000000000000000 0000000000000000 0000000000000000
    (190 is incrementing message value)

    VIRTUAL/PHYSICAL!
     
************************************************************************/



void k_tlb_fault_sub(void) {
  __asm__("mov r16=pr;;mov ar.k1=r16;;mov r16=ar.lc;;mov ar.k2=r16;;mov r16=b0;;mov ar.k6=r16;");
          //Save task's pr, lc and b0 to kernel registers
  __asm__("mov r16=cr.ifa;"); //Faulting address
  __asm__("add r17=@gprel(ifa_v),gp;;st8 [r17]=r16;;");
 itir_v  = (TASK_KEY<<8)|(12<<2); 
 if((ifa_v & 0xffffffffffff0000) != SHM_PTR ) {//Two cases task's data nad shared memory
    if ((ifa_v & 0xffffffffffff0000) != IFA  )//Task tries access out of it's rights
              __asm__(" add r29=  @gprel(fault_handler),gp;;mov b6=r29;;br.sptk.few b6;"); 
                //Task is not crashing system but taken away
        Index=(ifa_v & 0xff000)>>12;
        X=((DS_M >>12) & 0xff);
        Index = Index -X;               
        PD=PHYS_data[found][Index];//Page table found is TASK NUMBER AND INDEX PAGE NUMBER
        if(PD==0) //We must create new from virtual to physical transaltion and copy data (FORK)
        {      
                 SRC            = PHYS_data[0][Index] ;
                next_block+=0x200;
                cpy_dest      =  next_block; //NEXT available physical block to use               
                PD               =(long) next_block;       
                cpy_src        = (long *)SRC;
                 
        for(ix=0;ix<0x200;ix++)//Copy backing storage 0x1000 chars is 0x200 long is 4kb
                     *cpy_dest++= *cpy_src++; 
                      PHYS_data[found][Index]=PD;                                     
         }
                     
         itrd_v=  0x0010000000000000| (3 << 7) | (3 << 9 )|(1 << 6) | ( 1 << 5 ) | (1 << 0) | PD;         
         index_v= 7;
 }
 else { //Now we set the correct tlb translation's physical page from the page table PYS_pages.
  itrd_v     =   0x0010000000000000| (3 << 7) | (3 << 9 )|(1 << 6) | ( 1 << 5 ) | (1 << 0) | PHYS_pages[ ((ifa_v & 0xf000) >> 12)  ];
  index_v  = SHM_INDEX;
 }
            __asm__("add r17=@gprel(index_v),gp;;ld8 r19=[r17];;");//Set up transltion registers cr.itir and dtr
            __asm__("add r17=@gprel(itir_v),gp;;ld8 r18=[r17];;");
            __asm__("mov cr.itir=r18");
            __asm__("add r17=@gprel(itrd_v),gp;;ld8 r18=[r17];;");
           __asm__("itr.d  dtr[r19]   = r18; srlz.d");

           __asm__("mov r16=ar.k1;;mov pr=r16;;mov r16=ar.k2;;mov ar.lc=r16;;mov r16=ar.k6;;mov b0=r16;");
          __asm__("movl r31=0x4000000000000000;"); __asm__("or r1=r1,r31;bsw.1;rfi");    // set up task gp
}

}