Ignore:
Timestamp:
Sep 11, 2012, 12:43:28 PM (12 years ago)
Author:
alain
Message:

Bug fixing: The handling of L/R bit update has been modified in DCACHE FSM.
If the L/R bit must be updated after a TLB MISS, the DCACHE FSM request a SC
transaction to update the Page Table, but the PTE copies in the
dcache and in the tlb are not modified. They will be updated
by the coherence mechanism.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp

    r254 r262  
    19781978    {
    19791979    case DCACHE_IDLE:   // There is 8 conditions to exit the IDLE state :
    1980                                                 // 1) Dirty bit update (processor)      => DCACHE_DIRTY_GET_PTE
    1981                                                 // 2) Coherence request (TGT FSM)       => DCACHE_CC_CHECK
    1982                                                 // 3) ITLB miss request (ICACHE FSM)    => DCACHE_TLB_MISS
    1983                                                 // 4) XTN request (processor)           => DCACHE_XTN_*
    1984                                                 // 5) DTLB miss (processor)             => DCACHE_TLB_MISS
    1985                                                 // 6) Cacheable read miss (processor)   => DCACHE_MISS_VICTIM
    1986                                                 // 7) Uncacheable read (processor)      => DCACHE_UNC_WAIT
    1987                                                 // 8) SC access (processor)             => DCACHE_SC_WAIT
     1980                                                // 1) Dirty bit update (processor)    => DCACHE_DIRTY_GET_PTE
     1981                                                // 2) Coherence request (TGT FSM)     => DCACHE_CC_CHECK
     1982                                                // 3) ITLB miss request (ICACHE FSM)  => DCACHE_TLB_MISS
     1983                                                // 4) XTN request (processor)         => DCACHE_XTN_*
     1984                                                // 5) DTLB miss (processor)           => DCACHE_TLB_MISS
     1985                                                // 6) Cacheable read miss (processor) => DCACHE_MISS_VICTIM
     1986                                                // 7) Uncacheable read (processor)    => DCACHE_UNC_WAIT
     1987                                                // 8) SC access (processor)           => DCACHE_SC_WAIT
    19881988                        //
    19891989                        // The dtlb is unconditionally accessed to translate the
     
    29622962    //////////////////////////
    29632963    case DCACHE_TLB_PTE1_UPDT:  // write a new PTE1 in tlb after testing the L/R bit
    2964                                 // if L/R bit already set, exit the sub-fsm
    2965                                 // if not, the page table must be updated
    2966     {
    2967         paddr_t   nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
    2968         uint32_t  pte   = r_dcache_tlb_pte_flags.read();
    2969         bool      updt  = false;
    2970         bool      local = true;
     2964                                // - if L/R bit already set, exit the sub-fsm.
     2965                                // - if not, we update the page table but we dont write
     2966                                //   neither in DCACHE, nor in TLB, as this will be done by
     2967                                //   the coherence mechanism.
     2968    {
     2969        paddr_t   nline    = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
     2970        uint32_t  pte      = r_dcache_tlb_pte_flags.read();
     2971        bool      pt_updt  = false;
     2972        bool      local    = true;
    29712973
    29722974        // We should compute the access locality:
     
    29812983            if ( not ((pte & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
    29822984            {
    2983                 updt                = true;
    2984                 r_dcache_vci_sc_old = pte;
    2985                 r_dcache_vci_sc_new = pte | PTE_L_MASK;
    2986                 pte                 = pte | PTE_L_MASK;
    2987                 r_dcache_tlb_pte_flags = pte;
     2985                pt_updt                = true;
     2986                r_dcache_vci_sc_old    = pte;
     2987                r_dcache_vci_sc_new    = pte | PTE_L_MASK;
     2988                pte                    = pte | PTE_L_MASK;
     2989                r_dcache_tlb_pte_flags = pte;
    29882990            }
    29892991        }
     
    29922994            if ( not ((pte & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
    29932995            {
    2994                 updt                = true;
    2995                 r_dcache_vci_sc_old = pte;
    2996                 r_dcache_vci_sc_new = pte | PTE_R_MASK;
    2997                 pte                 = pte | PTE_R_MASK;
    2998                 r_dcache_tlb_pte_flags = pte;
    2999             }
    3000         }
    3001 
    3002         // update TLB
    3003         if ( r_dcache_tlb_ins.read() ) 
    3004         {
    3005             r_itlb.write( true,         // 2M page
    3006                           pte,
    3007                           0,            // argument unused for a PTE1
    3008                           r_dcache_tlb_vaddr.read(),   
    3009                           r_dcache_tlb_way.read(),
    3010                           r_dcache_tlb_set.read(),
    3011                           nline );
     2996                pt_updt                = true;
     2997                r_dcache_vci_sc_old    = pte;
     2998                r_dcache_vci_sc_new    = pte | PTE_R_MASK;
     2999                pte                    = pte | PTE_R_MASK;
     3000                r_dcache_tlb_pte_flags = pte;
     3001            }
     3002        }
     3003
     3004        if ( not pt_updt )                                      // update TLB and return
     3005        {
     3006            if ( r_dcache_tlb_ins.read() ) 
     3007            {
     3008                r_itlb.write( true,             // 2M page
     3009                              pte,
     3010                              0,                // argument unused for a PTE1
     3011                              r_dcache_tlb_vaddr.read(),   
     3012                              r_dcache_tlb_way.read(),
     3013                              r_dcache_tlb_set.read(),
     3014                              nline );
    30123015#ifdef INSTRUMENTATION
    30133016m_cpt_itlb_write++;
    30143017#endif
    3015         }
    3016         else
    3017         {
    3018             r_dtlb.write( true,         // 2M page
    3019                           pte,
    3020                           0,            // argument unused for a PTE1
    3021                           r_dcache_tlb_vaddr.read(),   
    3022                           r_dcache_tlb_way.read(),
    3023                           r_dcache_tlb_set.read(),
    3024                           nline );
    3025 #ifdef INSTRUMENTATION
    3026 m_cpt_dtlb_write++;
    3027 #endif
    3028         }
    3029         // next state
    3030         if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT;  // dcache and page table update
    3031         else        r_dcache_fsm = DCACHE_TLB_RETURN;   // exit sub-fsm
    30323018
    30333019#if DEBUG_DCACHE
    30343020if ( m_debug_dcache_fsm )
    30353021{
    3036     if ( r_dcache_tlb_ins.read() )
    3037     {
    3038         std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB";
    3039         std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
    3040                   << " / way = " << r_dcache_tlb_way.read() << std::endl;
    3041         r_itlb.printTrace();
    3042     }
    3043     else                           
    3044     {
    3045         std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB";
    3046         std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
    3047                   << " / way = " << r_dcache_tlb_way.read() << std::endl;
    3048         r_dtlb.printTrace();
    3049     }
    3050    
     3022    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB";
     3023    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     3024              << " / way = " << r_dcache_tlb_way.read() << std::endl;
     3025    r_itlb.printTrace();
    30513026}
    30523027#endif
     3028            }
     3029            else
     3030            {
     3031                r_dtlb.write( true,             // 2M page
     3032                              pte,
     3033                              0,                // argument unused for a PTE1
     3034                              r_dcache_tlb_vaddr.read(),   
     3035                              r_dcache_tlb_way.read(),
     3036                              r_dcache_tlb_set.read(),
     3037                              nline );
     3038#ifdef INSTRUMENTATION
     3039m_cpt_dtlb_write++;
     3040#endif
     3041
     3042#if DEBUG_DCACHE
     3043if ( m_debug_dcache_fsm )
     3044{
     3045    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB";
     3046    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     3047              << " / way = " << r_dcache_tlb_way.read() << std::endl;
     3048    r_dtlb.printTrace();
     3049}
     3050#endif
     3051            }
     3052            r_dcache_fsm = DCACHE_TLB_RETURN;
     3053        }
     3054        else                            // update page table but not TLB
     3055        {
     3056            r_dcache_fsm = DCACHE_TLB_LR_UPDT;
     3057
     3058#if DEBUG_DCACHE
     3059if ( m_debug_dcache_fsm )
     3060{
     3061    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE1_UPDT> L/R bit update required"
     3062              << std::endl;
     3063}
     3064#endif
     3065        }
    30533066        break;
    30543067    }
     
    31823195    }
    31833196    //////////////////////////
    3184     case DCACHE_TLB_PTE2_UPDT:          // write a new PTE2 in tlb after testing the L/R bit
    3185                                         // if L/R bit already set, exit the sub-fsm
    3186                                         // if not, the page table must be updated by an atomic access
     3197    case DCACHE_TLB_PTE2_UPDT:  // write a new PTE2 in tlb after testing the L/R bit
     3198                                // - if L/R bit already set, exit the sub-fsm.
     3199                                // - if not, we update the page table but we dont write
     3200                                //   neither in DCACHE, nor in TLB, as this will be done by
     3201                                //   the coherence mechanism.
    31873202    {
    31883203        paddr_t         nline     = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
    31893204        uint32_t        pte_flags = r_dcache_tlb_pte_flags.read();
    31903205        uint32_t        pte_ppn   = r_dcache_tlb_pte_ppn.read();
    3191         bool            updt      = false;
     3206        bool            pt_updt   = false;
    31923207        bool            local     = true;
    31933208
     
    32033218            if ( not ((pte_flags & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
    32043219            {
    3205                 updt                = true;
    3206                 r_dcache_vci_sc_old = pte_flags;
    3207                 r_dcache_vci_sc_new = pte_flags | PTE_L_MASK;
    3208                 pte_flags           = pte_flags | PTE_L_MASK;
    3209                 r_dcache_tlb_pte_flags = pte_flags;
     3220                pt_updt                = true;
     3221                r_dcache_vci_sc_old    = pte_flags;
     3222                r_dcache_vci_sc_new    = pte_flags | PTE_L_MASK;
     3223                pte_flags              = pte_flags | PTE_L_MASK;
     3224                        r_dcache_tlb_pte_flags = pte_flags;
    32103225            }
    32113226        }
     
    32143229            if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
    32153230            {
    3216                 updt                   = true;
    3217                 r_dcache_vci_sc_old = pte_flags;
    3218                 r_dcache_vci_sc_new = pte_flags | PTE_R_MASK;
    3219                 pte_flags           = pte_flags | PTE_R_MASK;
    3220                 r_dcache_tlb_pte_flags = pte_flags;
     3231                pt_updt                = true;
     3232                r_dcache_vci_sc_old    = pte_flags;
     3233                r_dcache_vci_sc_new    = pte_flags | PTE_R_MASK;
     3234                pte_flags              = pte_flags | PTE_R_MASK;
     3235                        r_dcache_tlb_pte_flags = pte_flags;
    32213236            }
    32223237        }
    32233238       
    3224         // update TLB for a PTE2
    3225         if ( r_dcache_tlb_ins.read() ) 
    3226         {
    3227             r_itlb.write( false,        // 4K page
    3228                           pte_flags,
    3229                           pte_ppn,
    3230                           r_dcache_tlb_vaddr.read(),   
    3231                           r_dcache_tlb_way.read(),
    3232                           r_dcache_tlb_set.read(),
    3233                           nline );
     3239        if ( not pt_updt )                       // update TLB
     3240        {
     3241            if ( r_dcache_tlb_ins.read() ) 
     3242            {
     3243                r_itlb.write( false,    // 4K page
     3244                              pte_flags,
     3245                              pte_ppn,
     3246                              r_dcache_tlb_vaddr.read(),   
     3247                              r_dcache_tlb_way.read(),
     3248                              r_dcache_tlb_set.read(),
     3249                              nline );
    32343250#ifdef INSTRUMENTATION
    32353251m_cpt_itlb_write++;
    32363252#endif
    3237         }
    3238         else
    3239         {
    3240             r_dtlb.write( false,        // 4K page
    3241                           pte_flags,
    3242                           pte_ppn,
    3243                           r_dcache_tlb_vaddr.read(),   
    3244                           r_dcache_tlb_way.read(),
    3245                           r_dcache_tlb_set.read(),
    3246                           nline );
    3247 #ifdef INSTRUMENTATION
    3248 m_cpt_dtlb_write++;
    3249 #endif
    3250         }
    32513253
    32523254#if DEBUG_DCACHE
    32533255if ( m_debug_dcache_fsm )
    32543256{
    3255     if ( r_dcache_tlb_ins.read() )
    3256     {
    3257         std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB";
    3258         std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
    3259                   << " / way = " << r_dcache_tlb_way.read() << std::endl;
    3260         r_itlb.printTrace();
    3261     }
    3262     else                           
    3263     {
    3264         std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB";
    3265         std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
    3266                   << " / way = " << r_dcache_tlb_way.read() << std::endl;
    3267         r_dtlb.printTrace();
    3268     }
     3257    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB";
     3258    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     3259              << " / way = " << r_dcache_tlb_way.read() << std::endl;
     3260    r_itlb.printTrace();
    32693261}
    32703262#endif
    3271         // next state
    3272         if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT;  // dcache and page table update
    3273         else        r_dcache_fsm = DCACHE_TLB_RETURN;   // exit sub-fsm
     3263            }
     3264            else
     3265            {
     3266                r_dtlb.write( false,    // 4K page
     3267                              pte_flags,
     3268                              pte_ppn,
     3269                              r_dcache_tlb_vaddr.read(),   
     3270                              r_dcache_tlb_way.read(),
     3271                              r_dcache_tlb_set.read(),
     3272                              nline );
     3273#ifdef INSTRUMENTATION
     3274m_cpt_dtlb_write++;
     3275#endif
     3276
     3277#if DEBUG_DCACHE
     3278if ( m_debug_dcache_fsm )
     3279{
     3280    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB";
     3281    std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
     3282              << " / way = " << r_dcache_tlb_way.read() << std::endl;
     3283    r_dtlb.printTrace();
     3284}
     3285#endif
     3286
     3287            }
     3288            r_dcache_fsm = DCACHE_TLB_RETURN;
     3289        }
     3290        else                                   // update page table but not TLB
     3291        {
     3292            r_dcache_fsm = DCACHE_TLB_LR_UPDT;  // dcache and page table update
     3293
     3294#if DEBUG_DCACHE
     3295if ( m_debug_dcache_fsm )
     3296{
     3297    std::cout << "  <PROC " << name() << ".DCACHE_TLB_PTE2_UPDT> L/R bit update required"
     3298              << std::endl;
     3299}
     3300#endif
     3301        }
    32743302        break;
    32753303    }
    32763304    ////////////////////////
    3277     case DCACHE_TLB_LR_UPDT:            // update the dcache after a tlb miss (L/R bit),
    3278                                         // request a SC transaction to CMD FSM
     3305    case DCACHE_TLB_LR_UPDT:        // request a SC transaction to update L/R bit
    32793306    {
    32803307#if DEBUG_DCACHE
     
    32843311}
    32853312#endif
    3286         r_dcache.write(r_dcache_tlb_cache_way.read(),
    3287                        r_dcache_tlb_cache_set.read(),
    3288                        r_dcache_tlb_cache_word.read(),
    3289                        r_dcache_tlb_pte_flags.read());
    3290 #ifdef INSTRUMENTATION
    3291 m_cpt_dcache_data_write++;
    3292 #endif
    32933313        // r_dcache_vci_sc_old & r_dcache_vci_sc_new registers are already set
    32943314        r_dcache_vci_paddr   = r_dcache_tlb_paddr.read();
     
    32983318    }
    32993319    ////////////////////////
    3300     case DCACHE_TLB_LR_WAIT:            // Waiting the response to SC transaction.
     3320    case DCACHE_TLB_LR_WAIT:            // Waiting the response to SC transaction for DIRTY bit.
    33013321                                    // We consume the response in rsp FIFO,
    33023322                                    // and exit the sub-fsm, but we don't
     
    39904010    }
    39914011    //////////////////////////
    3992     case DCACHE_DIRTY_SC_WAIT:          // wait completion of SC for PTE Dirty bit
    3993                                         // If PTE update is a success, return to IDLE state.
    3994                                         // If PTE update is a failure, invalidate cache line
    3995                                         // in DCACHE and invalidate the matching TLB entries.
     4012    case DCACHE_DIRTY_SC_WAIT:          // wait completion of SC for PTE Dirty bit,
     4013                                    // and return to IDLE state when response is received.
     4014                                    // we don't care if the SC is a failure:
     4015                                    // - if the SC is a success, the coherence mechanism
     4016                                    //   updates the local copy.
     4017                                    // - if the SC is a failure, we just retry the write.
    39964018    {
    39974019        // external coherence request
Note: See TracChangeset for help on using the changeset viewer.