[Gems-users] flushing L1D cache


Date: Mon, 05 May 2008 14:30:12 +0200
From: Mladen Nikitovic <mladen@xxxxxx>
Subject: [Gems-users] flushing L1D cache
Hi,

I'm encountering some problems when flushing the L1 data cache of a processor. I have already notified the target operating system that the processor is offline, so there is no problems regarding that. The processor does not execute any real instructions after that.

The approach is to simply walk the cache, detect the entries that are dirty and by issuing a write operation to that same entry (but with an address that would not conflict any other requests, using addresses beyond the physical memory size, yes I do lie to ruby about the size :) one would to force the entry out to the L2.

I did the following in Sequencer.C (where the flush is implemented).

First I addressed the mandatory queue explicitly of that processor that is being shut down. I enqueued requests of type CacheRequestType_ST with addresses that would force the cache to push out the dirty entries (the physical memory size is 256MB but I use address space 256 - 512 MB to request data addresses that will not be used in reality, they are only used for flushing).

However, using this approach i got the following assertion:

Sequencer: flushIL1caches: Dcache flush done
failed assertion 'm_writeRequestTable_ptr->exist(line_address(address))' at fn void Sequencer::writeCallback(const Address&, DataBlock&, Gener icMachineType, PrefetchBit) in system/Sequencer.C:403 failed assertion 'm_writeRequestTable_ptr->exist(line_address(address))' at fn void Sequencer::writeCallback(const Address&, DataBlock&, Gener icMachineType, PrefetchBit) in system/Sequencer.C:403
At this point you might want to attach a debug to the running and get to the
crash site; otherwise press enter to continue

This assertion led me to the conclusion that I probably need to make a call to makeRequest in order to force the request to exist in the writeRequestTable.

So, the "flush" is now done the follwing way:

 for(i=0; i<Dsets; i++) {
   for(j=0; j<Dassoc; j++) {
     if(m_chip_ptr->m_L1Cache_L1DcacheMemory_vec[cpu]->getDirty(i,j)) {
m_chip_ptr->getSequencer(cpu)->makeRequest(CacheMsg(Address(m_chip_ptr->m_L1Cache_L1DcacheMemory_vec[cpu]->getAddress(i,j) +
                                   (RubyConfig::memorySizeBytes()/2)),
                               CacheRequestType_ST,
                               Address(0),
                               AccessModeType_SupervisorMode,
                               4,
                               PrefetchBit_No,
                               0,
                               false));
     }
   }
 }

Using this approach I get the following assertion instead:

Sequencer: flushIL1caches: Dcache flush done
failed assertion 'm_lingering_request_address != Address(0-1)' at fn void SimicsProcessor::hitCallback(SubBlock&) in simics/SimicsProcessor.C:202 failed assertion 'm_lingering_request_address != Address(0-1)' at fn void SimicsProcessor::hitCallback(SubBlock&) in simics/SimicsProcessor.C:202
At this point you might want to attach a debug to the running and get to the
crash site; otherwise press enter to continue
PID: 19536

There is something about a "lingering_request" that is supposed to be equal to Address(0-1), but I don't understand what might be wrong with my request. Am I missing something regarding the parameters to my call to MakeRequest?

Hope you can help me.

/Mladen


[← Prev in Thread] Current Thread [Next in Thread→]