Index: trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp
===================================================================
--- trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp	(revision 260)
+++ trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp	(revision 262)
@@ -1978,12 +1978,12 @@
     {
     case DCACHE_IDLE:	// There is 8 conditions to exit the IDLE state :
-						// 1) Dirty bit update (processor)	=> DCACHE_DIRTY_GET_PTE
-						// 2) Coherence request (TGT FSM) 	=> DCACHE_CC_CHECK 
-						// 3) ITLB miss request (ICACHE FSM) 	=> DCACHE_TLB_MISS
-						// 4) XTN request (processor)		=> DCACHE_XTN_*
-						// 5) DTLB miss (processor) 		=> DCACHE_TLB_MISS
-						// 6) Cacheable read miss (processor)  	=> DCACHE_MISS_VICTIM
-						// 7) Uncacheable read (processor) 	=> DCACHE_UNC_WAIT 
-						// 8) SC access (processor)		=> DCACHE_SC_WAIT
+						// 1) Dirty bit update (processor)    => DCACHE_DIRTY_GET_PTE
+						// 2) Coherence request (TGT FSM)     => DCACHE_CC_CHECK 
+						// 3) ITLB miss request (ICACHE FSM)  => DCACHE_TLB_MISS
+						// 4) XTN request (processor)         => DCACHE_XTN_*
+						// 5) DTLB miss (processor)           => DCACHE_TLB_MISS
+						// 6) Cacheable read miss (processor) => DCACHE_MISS_VICTIM
+						// 7) Uncacheable read (processor)    => DCACHE_UNC_WAIT 
+						// 8) SC access (processor)           => DCACHE_SC_WAIT
                         //
                         // The dtlb is unconditionally accessed to translate the
@@ -2962,11 +2962,13 @@
     //////////////////////////
     case DCACHE_TLB_PTE1_UPDT:	// write a new PTE1 in tlb after testing the L/R bit
-				// if L/R bit already set, exit the sub-fsm
-                                // if not, the page table must be updated
-    {
-        paddr_t	  nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
-        uint32_t  pte   = r_dcache_tlb_pte_flags.read();
-        bool	  updt  = false;
-        bool	  local = true;
+                                // - if L/R bit already set, exit the sub-fsm.
+                                // - if not, we update the page table but we dont write
+                                //   neither in DCACHE, nor in TLB, as this will be done by
+                                //   the coherence mechanism.
+    {
+        paddr_t	  nline    = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
+        uint32_t  pte      = r_dcache_tlb_pte_flags.read();
+        bool	  pt_updt  = false;
+        bool	  local    = true;
 
         // We should compute the access locality: 
@@ -2981,9 +2983,9 @@
             if ( not ((pte & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
             {
-                updt                = true;
-                r_dcache_vci_sc_old = pte;
-                r_dcache_vci_sc_new = pte | PTE_L_MASK;
-                pte                 = pte | PTE_L_MASK;
-		r_dcache_tlb_pte_flags = pte;
+                pt_updt                = true;
+                r_dcache_vci_sc_old    = pte;
+                r_dcache_vci_sc_new    = pte | PTE_L_MASK;
+                pte                    = pte | PTE_L_MASK;
+                r_dcache_tlb_pte_flags = pte;
             }
         }
@@ -2992,63 +2994,74 @@
             if ( not ((pte & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
             {
-                updt                = true;
-                r_dcache_vci_sc_old = pte;
-                r_dcache_vci_sc_new = pte | PTE_R_MASK;
-                pte                 = pte | PTE_R_MASK;
-		r_dcache_tlb_pte_flags = pte;
-            }
-        }
-
-        // update TLB
-        if ( r_dcache_tlb_ins.read() )  
-        {
-            r_itlb.write( true,		// 2M page
-                          pte,
-                          0,		// argument unused for a PTE1
-                          r_dcache_tlb_vaddr.read(),    
-                          r_dcache_tlb_way.read(), 
-                          r_dcache_tlb_set.read(),
-                          nline );
+                pt_updt                = true;
+                r_dcache_vci_sc_old    = pte;
+                r_dcache_vci_sc_new    = pte | PTE_R_MASK;
+                pte                    = pte | PTE_R_MASK;
+                r_dcache_tlb_pte_flags = pte;
+            }
+        }
+
+        if ( not pt_updt )					// update TLB and return
+        {
+            if ( r_dcache_tlb_ins.read() )  
+            {
+                r_itlb.write( true,		// 2M page
+                              pte,
+                              0,		// argument unused for a PTE1
+                              r_dcache_tlb_vaddr.read(),    
+                              r_dcache_tlb_way.read(), 
+                              r_dcache_tlb_set.read(),
+                              nline );
 #ifdef INSTRUMENTATION
 m_cpt_itlb_write++;
 #endif
-        }
-        else
-        {
-            r_dtlb.write( true,		// 2M page
-                          pte,
-                          0,		// argument unused for a PTE1
-                          r_dcache_tlb_vaddr.read(),    
-                          r_dcache_tlb_way.read(), 
-                          r_dcache_tlb_set.read(),
-                          nline );
-#ifdef INSTRUMENTATION
-m_cpt_dtlb_write++;
-#endif
-        }
-        // next state
-        if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT; 	// dcache and page table update
-        else        r_dcache_fsm = DCACHE_TLB_RETURN;	// exit sub-fsm
 
 #if DEBUG_DCACHE
 if ( m_debug_dcache_fsm )
 {
-    if ( r_dcache_tlb_ins.read() ) 
-    {
-        std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB";
-        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
-                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
-        r_itlb.printTrace();
-    }
-    else                           
-    {
-        std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB";
-        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
-                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
-        r_dtlb.printTrace();
-    }
-    
+    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB";
+    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+              << " / way = " << r_dcache_tlb_way.read() << std::endl;
+    r_itlb.printTrace();
 }
 #endif
+            }
+            else
+            {
+                r_dtlb.write( true,		// 2M page
+                              pte,
+                              0,		// argument unused for a PTE1
+                              r_dcache_tlb_vaddr.read(),    
+                              r_dcache_tlb_way.read(), 
+                              r_dcache_tlb_set.read(),
+                              nline );
+#ifdef INSTRUMENTATION
+m_cpt_dtlb_write++;
+#endif
+
+#if DEBUG_DCACHE
+if ( m_debug_dcache_fsm )
+{
+    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB";
+    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+              << " / way = " << r_dcache_tlb_way.read() << std::endl;
+    r_dtlb.printTrace();
+}
+#endif
+            }
+            r_dcache_fsm = DCACHE_TLB_RETURN;
+        }
+        else                            // update page table but not TLB
+        {
+            r_dcache_fsm = DCACHE_TLB_LR_UPDT; 
+
+#if DEBUG_DCACHE
+if ( m_debug_dcache_fsm )
+{
+    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> L/R bit update required"
+              << std::endl;
+}
+#endif
+        }
         break;
     }
@@ -3182,12 +3195,14 @@
     }
     //////////////////////////
-    case DCACHE_TLB_PTE2_UPDT:      	// write a new PTE2 in tlb after testing the L/R bit
-				    	// if L/R bit already set, exit the sub-fsm
-                                    	// if not, the page table must be updated by an atomic access
+    case DCACHE_TLB_PTE2_UPDT:	// write a new PTE2 in tlb after testing the L/R bit
+                                // - if L/R bit already set, exit the sub-fsm.
+                                // - if not, we update the page table but we dont write
+                                //   neither in DCACHE, nor in TLB, as this will be done by
+                                //   the coherence mechanism.
     {
         paddr_t	        nline     = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
         uint32_t        pte_flags = r_dcache_tlb_pte_flags.read();
         uint32_t        pte_ppn   = r_dcache_tlb_pte_ppn.read();
-        bool            updt      = false;
+        bool            pt_updt   = false;
         bool            local     = true;
 
@@ -3203,9 +3218,9 @@
             if ( not ((pte_flags & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
             {
-                updt                = true;
-                r_dcache_vci_sc_old = pte_flags;
-                r_dcache_vci_sc_new = pte_flags | PTE_L_MASK;
-                pte_flags           = pte_flags | PTE_L_MASK;
-		r_dcache_tlb_pte_flags = pte_flags;
+                pt_updt                = true;
+                r_dcache_vci_sc_old    = pte_flags;
+                r_dcache_vci_sc_new    = pte_flags | PTE_L_MASK;
+                pte_flags              = pte_flags | PTE_L_MASK;
+		        r_dcache_tlb_pte_flags = pte_flags;
             }
         }
@@ -3214,67 +3229,79 @@
             if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
             {
-                updt                   = true;
-                r_dcache_vci_sc_old = pte_flags;
-                r_dcache_vci_sc_new = pte_flags | PTE_R_MASK;
-                pte_flags           = pte_flags | PTE_R_MASK;
-		r_dcache_tlb_pte_flags = pte_flags;
+                pt_updt                = true;
+                r_dcache_vci_sc_old    = pte_flags;
+                r_dcache_vci_sc_new    = pte_flags | PTE_R_MASK;
+                pte_flags              = pte_flags | PTE_R_MASK;
+		        r_dcache_tlb_pte_flags = pte_flags;
             }
         }
         
-        // update TLB for a PTE2
-        if ( r_dcache_tlb_ins.read() )  
-        {
-            r_itlb.write( false,	// 4K page
-                          pte_flags,
-                          pte_ppn,
-                          r_dcache_tlb_vaddr.read(),    
-                          r_dcache_tlb_way.read(), 
-                          r_dcache_tlb_set.read(),
-                          nline );
+        if ( not pt_updt )                       // update TLB 
+        {
+            if ( r_dcache_tlb_ins.read() )  
+            {
+                r_itlb.write( false,	// 4K page
+                              pte_flags,
+                              pte_ppn,
+                              r_dcache_tlb_vaddr.read(),    
+                              r_dcache_tlb_way.read(), 
+                              r_dcache_tlb_set.read(),
+                              nline );
 #ifdef INSTRUMENTATION
 m_cpt_itlb_write++;
 #endif
-        }
-        else
-        {
-            r_dtlb.write( false,	// 4K page
-                          pte_flags,
-                          pte_ppn,
-                          r_dcache_tlb_vaddr.read(),    
-                          r_dcache_tlb_way.read(), 
-                          r_dcache_tlb_set.read(),
-                          nline );
-#ifdef INSTRUMENTATION
-m_cpt_dtlb_write++;
-#endif
-        }
 
 #if DEBUG_DCACHE
 if ( m_debug_dcache_fsm )
 {
-    if ( r_dcache_tlb_ins.read() ) 
-    {
-        std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB";
-        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
-                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
-        r_itlb.printTrace();
-    }
-    else                           
-    {
-        std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB";
-        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
-                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
-        r_dtlb.printTrace();
-    }
+    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB";
+    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+              << " / way = " << r_dcache_tlb_way.read() << std::endl;
+    r_itlb.printTrace();
 }
 #endif
-        // next state
-        if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT; 	// dcache and page table update
-        else        r_dcache_fsm = DCACHE_TLB_RETURN;	// exit sub-fsm
+            }
+            else
+            {
+                r_dtlb.write( false,	// 4K page
+                              pte_flags,
+                              pte_ppn,
+                              r_dcache_tlb_vaddr.read(),    
+                              r_dcache_tlb_way.read(), 
+                              r_dcache_tlb_set.read(),
+                              nline );
+#ifdef INSTRUMENTATION
+m_cpt_dtlb_write++;
+#endif
+
+#if DEBUG_DCACHE
+if ( m_debug_dcache_fsm )
+{
+    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB";
+    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+              << " / way = " << r_dcache_tlb_way.read() << std::endl;
+    r_dtlb.printTrace();
+}
+#endif
+
+            }
+            r_dcache_fsm = DCACHE_TLB_RETURN;
+        }
+        else                                   // update page table but not TLB
+        {
+            r_dcache_fsm = DCACHE_TLB_LR_UPDT; 	// dcache and page table update
+
+#if DEBUG_DCACHE
+if ( m_debug_dcache_fsm )
+{
+    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> L/R bit update required"
+              << std::endl;
+}
+#endif
+        }
         break;
     }
     ////////////////////////
-    case DCACHE_TLB_LR_UPDT:		// update the dcache after a tlb miss (L/R bit),
-                                        // request a SC transaction to CMD FSM 
+    case DCACHE_TLB_LR_UPDT:        // request a SC transaction to update L/R bit
     {
 #if DEBUG_DCACHE
@@ -3284,11 +3311,4 @@
 }
 #endif
-        r_dcache.write(r_dcache_tlb_cache_way.read(),
-                       r_dcache_tlb_cache_set.read(),
-                       r_dcache_tlb_cache_word.read(),
-                       r_dcache_tlb_pte_flags.read());
-#ifdef INSTRUMENTATION
-m_cpt_dcache_data_write++;
-#endif
         // r_dcache_vci_sc_old & r_dcache_vci_sc_new registers are already set
         r_dcache_vci_paddr   = r_dcache_tlb_paddr.read();
@@ -3298,5 +3318,5 @@
     }
     ////////////////////////
-    case DCACHE_TLB_LR_WAIT:		// Waiting the response to SC transaction.
+    case DCACHE_TLB_LR_WAIT:		// Waiting the response to SC transaction for DIRTY bit.
                                     // We consume the response in rsp FIFO, 
                                     // and exit the sub-fsm, but we don't
@@ -3990,8 +4010,10 @@
     }
     //////////////////////////
-    case DCACHE_DIRTY_SC_WAIT:		// wait completion of SC for PTE Dirty bit
-                                        // If PTE update is a success, return to IDLE state.
-                                        // If PTE update is a failure, invalidate cache line
-                                        // in DCACHE and invalidate the matching TLB entries.
+    case DCACHE_DIRTY_SC_WAIT:		// wait completion of SC for PTE Dirty bit,
+                                    // and return to IDLE state when response is received.
+                                    // we don't care if the SC is a failure:
+                                    // - if the SC is a success, the coherence mechanism
+                                    //   updates the local copy.
+                                    // - if the SC is a failure, we just retry the write.
     {
         // external coherence request
