The simplest way to implement this (assuming that you want to invalidate
the whole cache and not a single block) is probably to break into Python
and execute something like this:
m5.memWriteback(root)
m5.memInvalidate(root)
These functions are called recursively on the object tree denoted by
root, which can be any object in the simulation hierarchy (e.g., a
single cache or the simulation root). Another option is to call
memWriteback() on the specific object you are interested in. For example:
root.cpu.l1cache.memWriteback()
There is no "clean" way of making callbacks into the simulation script.
(I've been planning on implementing this for a while.) The method I
currently use is to execute "m5 fail" pseudo instructions in the
simulated systems. I usually reserve one bit to denote non-failure exits
(e.g., 0x80) and handle the exit code in my simulation scripts. Doing a
call into gem5 from the kernel should be fairly easy since this is just
a read from a magic address (0xFFFF0000 + offset). I use the following
assembly code in some of my test cases (calls m5fail(delay=0, code=0x80)):
mov $0xFFFF0000, %r14 /* m5 interface base address */
xor %rdi, %rdi /* Set delay to 0 */
mov $0x80, %rsi /* Set error code */
mov 0x2200(%r14), %rax /* Call m5fail */
The read into rax becomes a "fake" function call that uses the Linux
x86-64 ABI. Have a look at m5op_x86.S for an example that generates
c-wrappers.
//Andreas
On 2014-01-21 23:53, Fangfei Liu wrote:
Thanks! I really appreciate your help! I just realized TLB flush is also
implemented without timing. Anyway, I will try the functional
implementation first.
*From:*gem5-users-boun...@gem5.org [mailto:gem5-users-boun...@gem5.org]
*On Behalf Of *Amin Farmahini
*Sent:* 2014年1月21日1:03
*To:* gem5 users mailing list
*Subject:* Re: [gem5-users] implement cache flush in classic memory model
Hi Fangfei,
If you want to implement it using *functional *accesses (*zero
*latency), you need to
1. Writeback every dirty lines in the cache.
2. Invalidate all lines in the cache.
For invalidation and writeback you can use visitor functions. Here is a
piece of code that might help you.
template<class TagStore>
void
Cache<TagStore>::memWriteback()
{
WrappedBlkVisitor visitor(*this, &Cache<TagStore>::writebackVisitor);
tags->forEachBlk(visitor);
}
template<class TagStore>
void
Cache<TagStore>::memInvalidate()
{
DPRINTF(Cache, "memInvalidate\n");
WrappedBlkVisitor visitor(*this, &Cache<TagStore>::invalidateVisitor);
tags->forEachBlk(visitor);
}
template<class TagStore>
bool
Cache<TagStore>::writebackVisitor(BlkType &blk)
{
if (blk.isDirty()) {
DPRINTF(Cache, "writebackVisitor set %d\n", blk.set);
assert(blk.isValid());
Request request(tags->regenerateBlkAddr(blk.tag, blk.set),
blkSize, 0, Request::funcMasterId);
Packet packet(&request, MemCmd::WriteReq);
packet.dataStatic(blk.data);
memSidePort->sendFunctional(&packet);
blk.status &= ~BlkDirty;
}
return true;
}
template<class TagStore>
bool
Cache<TagStore>::invalidateVisitor(BlkType &blk)
{
DPRINTF(Cache, "invalidateVisitor set %d\n", blk.set);
if (blk.isDirty())
warn_once("Invalidating dirty cache lines. Expect things to
break.\n");
if (blk.isValid()) {
assert(!blk.isDirty());
tags->invalidate(dynamic_cast< BlkType *>(&blk));
blk.invalidate();
}
return true;
}
Your pseudo instr can simply call memWriteback() and memInvaliate()
funcitons. You also need to have a pointer to the cache that you are
flushing. You can extend this code to take into account the latency for
flushing by using timing accesses.
If you end up implementing this, please post a patch to review board.
Thanks,
Amin
On Mon, Jan 20, 2014 at 9:08 PM, Fangfei Liu <fangf...@princeton.edu
<mailto:fangf...@princeton.edu>> wrote:
Hi everyone,
I would like to implement cache flush (invalidate all and write back
to main memory) in classic memory model for my project (x86 full
system). Right now I’m considering two choices. One is to implement
x86 wbinvd instruction and the other is to add a gem5 pseudo
instruction. This instruction will be used by Linux kernel. I was
wondering which method is easier to implement? Does anyone have any
idea on how to implement it? I find that it seems gem5 implemented
the TLB flush instruction, can I follow the similar way to implement
wbinvd instruction? Thanks!
Best regards
Fangfei
_______________________________________________
gem5-users mailing list
gem5-users@gem5.org <mailto:gem5-users@gem5.org>
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
_______________________________________________
gem5-users mailing list
gem5-users@gem5.org
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users
_______________________________________________
gem5-users mailing list
gem5-users@gem5.org
http://m5sim.org/cgi-bin/mailman/listinfo/gem5-users