From 40628093932fc7ca7173651720436c93da6f181a Mon Sep 17 00:00:00 2001 From: Aditya Badole Date: Fri, 30 Jun 2023 10:48:14 +0800 Subject: [PATCH] Some more bunch of changes: - Add options to config script - Set request size for node and tag controllers - Modify ld/st insn behaviour to clear the tag on a scalar value Change-Id: I207b45eb6978707c05b3ea5ab8e0babf9df26d1a --- configs/capstone/fast-forward.py | 18 ++- src/arch/riscvcapstone/isa/decoder.isa | 125 +++++++++++--------- src/arch/riscvcapstone/node_controller.cc | 2 + src/arch/riscvcapstone/o3/node_commands.cc | 6 +- src/arch/riscvcapstone/o3/tag_controller.cc | 6 +- src/mem/request.hh | 7 ++ tests/capstone/o3/Makefile | 2 +- 7 files changed, 103 insertions(+), 63 deletions(-) diff --git a/configs/capstone/fast-forward.py b/configs/capstone/fast-forward.py index 2228119eef..6472a2fa68 100644 --- a/configs/capstone/fast-forward.py +++ b/configs/capstone/fast-forward.py @@ -19,6 +19,8 @@ parser.add_argument('--cpu', type=str, default='simple', help='CPU model (atomic, simple, o3)') parser.add_argument('--mocktag', action='store_true', help='use mock tag') parser.add_argument('--ckpt', type=str, default ='', help='restore checkpoint from here') +parser.add_argument('--tcache-memside', type=str, default ='l2', help='tcache mem side connection') +parser.add_argument('--ckpt-save', type=str, default ='m5out/ckp', help='checkpoint save directory') if '--' not in sys.argv: sys.stderr.write('Usage: fast-forward.py [flags] -- ') @@ -56,9 +58,11 @@ class L1Cache(Cache): class L1ICache(L1Cache): size = '16kB' + # prefetcher = TaggedPrefetcher(degree=1, prefetch_on_access=True) class L1DCache(L1Cache): size = '64kB' + # prefetcher = TaggedPrefetcher(degree=1, prefetch_on_access=True) class NCache(Cache): size = args.ncache_size @@ -68,6 +72,7 @@ class NCache(Cache): response_latency = 2 mshrs = 4 tgts_per_mshr = 20 + # prefetcher = TaggedPrefetcher(degree=1, prefetch_on_access=True) class TCache(Cache): size = args.tcache_size @@ -77,16 +82,19 @@ class TCache(Cache): response_latency = 2 mshrs = 4 tgts_per_mshr = 20 + prefetcher = TaggedPrefetcher(degree=1, prefetch_on_access=True) class L2Cache(Cache): size = '256kB' + # size = '1024kB' assoc = 8 tag_latency = 20 data_latency = 20 response_latency = 20 mshrs = 20 tgts_per_mshr = 12 + # prefetcher = TaggedPrefetcher(degree=1, prefetch_on_access=True) system = System() @@ -113,7 +121,10 @@ class L2Cache(Cache): if 'tcache_port' in system.cpu._ports and not args.mocktag: system.cpu.tcache = TCache() system.cpu.tcache_port = system.cpu.tcache.cpu_side - system.cpu.tcache.mem_side = system.l2bus.cpu_side_ports + if args.tcache_memside == 'l2': + system.cpu.tcache.mem_side = system.l2bus.cpu_side_ports + else: + system.cpu.tcache.mem_side = system.membus.cpu_side_ports system.l2bus.mem_side_ports = system.l2cache.cpu_side system.l2cache.mem_side = system.membus.cpu_side_ports @@ -203,9 +214,8 @@ class L2Cache(Cache): .format(m5.curTick(), exit_event.getCause())) if exit_event.getCause() == 'checkpoint': - m5.checkpoint('m5out/ckp') - -if exit_event.getCause() == 'm5_exit instruction encountered': + m5.checkpoint(args.ckpt_save) +while exit_event.getCause() == 'm5_exit instruction encountered': m5.stats.reset() #m5.stats.dump() exit_event = m5.simulate() diff --git a/src/arch/riscvcapstone/isa/decoder.isa b/src/arch/riscvcapstone/isa/decoder.isa index 0b5856f96b..e3e02f4fe6 100644 --- a/src/arch/riscvcapstone/isa/decoder.isa +++ b/src/arch/riscvcapstone/isa/decoder.isa @@ -631,7 +631,7 @@ decode QUADRANT default Unknown::unknown() { }}); } format RNodeMemOp { - 0xe: lwc ({{ + 0xe: ldc ({{ Rd_trv; Rs1_trv; assert(Rs1_trv.getTag()); @@ -698,7 +698,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; }}); - 0x13: lws ({{ + 0x13: lts ({{ Rd_trv; Rs1_trv; assert(Rs1_trv.getTag()); @@ -741,7 +741,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; }}); - 0x16: lbs ({{ + 0x16: ldb ({{ Rd_trv; Rs1_trv; assert(Rs1_trv.getTag()); @@ -751,12 +751,16 @@ decode QUADRANT default Unknown::unknown() { }}, {{ Addr EA = Rs1_trv.getRegVal().capVal().cursor(); + if(EA + sizeof(uint8_t) > Rs1_trv.getRegVal().capVal().end()) + return std::make_shared( + "Illegal read - out of capability bounds!", machInst); + + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + //TODO: retrieve tag bit to make sure it corresponds //with the called inst? - DPRINTFN("MemReads count = %d, tag query count = %d\n", - dyn_inst->memReadN, dyn_inst->tagQueryN); - //TODO: Maybe separate these statements //and introduce a new type(s) of fault if (static_cast(Rs1_trv.getRegVal().capVal().perm()) < 1 || @@ -767,9 +771,6 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Rs1 doesn't have the necessary perms", machInst); }}, {{ - //Addr alignment = EA & (sizeof(RegVal) - 1); - //dyn_inst->initiateSetTag((EA - alignment), false); - uint8_t& cap = Mem_ub; getMemLE(pkt, cap, traceData); @@ -780,7 +781,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; }}); - 0x17: lhs ({{ + 0x17: ldd ({{ Rd_trv; Rs1_trv; assert(Rs1_trv.getTag()); @@ -794,12 +795,12 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal read - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + //TODO: retrieve tag bit to make sure it corresponds //with the called inst? - DPRINTFN("MemReads count = %d, tag query count = %d\n", - dyn_inst->memReadN, dyn_inst->tagQueryN); - //TODO: Maybe separate these statements //and introduce a new type(s) of fault if (static_cast(Rs1_trv.getRegVal().capVal().perm()) < 1 || @@ -820,7 +821,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; }}); - 0x18: l16s ({{ + 0x18: ldh ({{ Rd_trv; Rs1_trv; assert(Rs1_trv.getTag()); @@ -834,12 +835,12 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal read - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + //TODO: retrieve tag bit to make sure it corresponds //with the called inst? - //DPRINTFN("MemReads count = %d, tag query count = %d\n", - // dyn_inst->memReadN, dyn_inst->tagQueryN); - //TODO: Maybe separate these statements //and introduce a new type(s) of fault if (static_cast(Rs1_trv.getRegVal().capVal().perm()) < 1 || @@ -860,7 +861,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; }}); - 0x19: l32s ({{ + 0x19: ldw ({{ Rd_trv; Rs1_trv; assert(Rs1_trv.getTag()); @@ -874,12 +875,12 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal read - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + //TODO: retrieve tag bit to make sure it corresponds //with the called inst? - DPRINTFN("MemReads count = %d, tag query count = %d\n", - dyn_inst->memReadN, dyn_inst->tagQueryN); - //TODO: Maybe separate these statements //and introduce a new type(s) of fault if (static_cast(Rs1_trv.getRegVal().capVal().perm()) < 1 || @@ -902,7 +903,7 @@ decode QUADRANT default Unknown::unknown() { }}); } format RNodeStoreMemOp { - 0xf: swc ({{ // check_code + 0xf: stc ({{ // check_code Rd_trv; Rs1_trv; assert(Rd_trv.getTag()); @@ -948,7 +949,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; Rs1_trv = Rs1_trv; }}, IsStore); - 0x1d: sbc ({{ // check_code + 0x1d: stb ({{ // check_code Rd_trv; Rs1_trv; assert(Rd_trv.getTag()); @@ -967,13 +968,16 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal write - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + Mem_ub = Rs1_trv.getRegVal().capVal().cursor(); - Fault fault = dyn_inst->initiateGetTag(EA); - if(fault != NoFault) - return fault; + //Fault fault = dyn_inst->initiateGetTag(EA); + //if(fault != NoFault) + // return fault; - fault = writeMemTimingLE(xc, traceData, Mem_ub, EA, + Fault fault = writeMemTimingLE(xc, traceData, Mem_ub, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; @@ -984,9 +988,9 @@ decode QUADRANT default Unknown::unknown() { Addr EA = rdv.capVal().cursor(); - dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); - if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) - Rs1_trv.setTag(false); + //dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); + //if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) + Rs1_trv.setTag(false); if(rdv.capVal().type() == CapType::UNINIT) rdv.capVal().setCursor(EA + sizeof(uint8_t)); @@ -994,7 +998,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; Rs1_trv = Rs1_trv; }}, IsStore); - 0x1c: shc ({{ // check_code + 0x1c: std ({{ // check_code Rd_trv; Rs1_trv; assert(Rd_trv.getTag()); @@ -1013,13 +1017,16 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal write - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + Mem_ud = Rs1_trv.getRegVal().capVal().cursor(); - Fault fault = dyn_inst->initiateGetTag(EA); - if(fault != NoFault) - return fault; + //Fault fault = dyn_inst->initiateGetTag(EA); + //if(fault != NoFault) + // return fault; - fault = writeMemTimingLE(xc, traceData, Mem_ud, EA, + Fault fault = writeMemTimingLE(xc, traceData, Mem_ud, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; @@ -1030,9 +1037,9 @@ decode QUADRANT default Unknown::unknown() { Addr EA = rdv.capVal().cursor(); - dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); - if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) - Rs1_trv.setTag(false); + //dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); + //if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) + Rs1_trv.setTag(false); if(rdv.capVal().type() == CapType::UNINIT) rdv.capVal().setCursor(EA + sizeof(uint64_t)); @@ -1040,7 +1047,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; Rs1_trv = Rs1_trv; }}, IsStore); - 0x1a: s16c ({{ // check_code + 0x1a: sth ({{ // check_code Rd_trv; Rs1_trv; assert(Rd_trv.getTag()); @@ -1059,13 +1066,16 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal write - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + Mem_uh = Rs1_trv.getRegVal().capVal().cursor(); - Fault fault = dyn_inst->initiateGetTag(EA); - if(fault != NoFault) - return fault; + //Fault fault = dyn_inst->initiateGetTag(EA); + //if(fault != NoFault) + // return fault; - fault = writeMemTimingLE(xc, traceData, Mem_uh, EA, + Fault fault = writeMemTimingLE(xc, traceData, Mem_uh, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; @@ -1076,9 +1086,9 @@ decode QUADRANT default Unknown::unknown() { Addr EA = rdv.capVal().cursor(); - dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); - if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) - Rs1_trv.setTag(false); + //dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); + //if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) + Rs1_trv.setTag(false); if(rdv.capVal().type() == CapType::UNINIT) rdv.capVal().setCursor(EA + sizeof(uint16_t)); @@ -1086,7 +1096,7 @@ decode QUADRANT default Unknown::unknown() { Rd_trv = Rd_trv; Rs1_trv = Rs1_trv; }}, IsStore); - 0x1b: s32c ({{ // check_code + 0x1b: stw ({{ // check_code Rd_trv; Rs1_trv; assert(Rd_trv.getTag()); @@ -1105,13 +1115,16 @@ decode QUADRANT default Unknown::unknown() { return std::make_shared( "Illegal write - out of capability bounds!", machInst); + Addr alignment = EA & (sizeof(RegVal) - 1); + dyn_inst->initiateSetTag((EA - alignment), false); + Mem_uw = Rs1_trv.getRegVal().capVal().cursor(); - Fault fault = dyn_inst->initiateGetTag(EA); - if(fault != NoFault) - return fault; + //Fault fault = dyn_inst->initiateGetTag(EA); + //if(fault != NoFault) + // return fault; - fault = writeMemTimingLE(xc, traceData, Mem_uw, EA, + Fault fault = writeMemTimingLE(xc, traceData, Mem_uw, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; @@ -1122,9 +1135,9 @@ decode QUADRANT default Unknown::unknown() { Addr EA = rdv.capVal().cursor(); - dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); - if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) - Rs1_trv.setTag(false); + //dyn_inst->initiateSetTag(EA, Rs1_trv.getTag()); + //if(Rs1_trv.getTag() && Rs1_trv.getRegVal().capVal().type() != CapType::NONLIN) + Rs1_trv.setTag(false); if(rdv.capVal().type() == CapType::UNINIT) rdv.capVal().setCursor(EA + sizeof(uint32_t)); @@ -1297,6 +1310,10 @@ decode QUADRANT default Unknown::unknown() { assert(dyn_inst); dyn_inst->printRegs(); }}, IsSerializing, IsNonSpeculative); + 0xe: getrand ({{ + srand(time(NULL)); + Rd = (rand() % (Rs2 - Rs1) + Rs1) & 0xFFFFFFFFFFFFFFF0; + }}); } format TagAccessStore { 0xb: tagset ({{ diff --git a/src/arch/riscvcapstone/node_controller.cc b/src/arch/riscvcapstone/node_controller.cc index 54dadc3a5a..a6d71e6f30 100644 --- a/src/arch/riscvcapstone/node_controller.cc +++ b/src/arch/riscvcapstone/node_controller.cc @@ -92,6 +92,7 @@ NodeController::sendLoad(NodeControllerCommandPtr cmd, NodeID node_id, bool atom RequestPtr req = std::make_shared(); req->requestorId(requestorId); req->setPaddr(addr); + req->setSize(sizeof(Node)); PacketPtr pkt = Packet::createRead(req); pkt->setSize(sizeof(Node)); // FIXME: do we need to specify the size here? pkt->allocate(); @@ -124,6 +125,7 @@ NodeController::sendStore(NodeControllerCommandPtr cmd, NodeID node_id, const No RequestPtr req = std::make_shared(); req->requestorId(requestorId); req->setPaddr(addr); + req->setSize(sizeof(Node)); PacketPtr pkt = Packet::createWrite(req); pkt->setSize(sizeof(Node)); pkt->allocate(); diff --git a/src/arch/riscvcapstone/o3/node_commands.cc b/src/arch/riscvcapstone/o3/node_commands.cc index f54b519fa0..3149a35fe1 100644 --- a/src/arch/riscvcapstone/o3/node_commands.cc +++ b/src/arch/riscvcapstone/o3/node_commands.cc @@ -25,8 +25,9 @@ create_load_node(RequestorID requestor_id, const NodeID& node_id) { RequestPtr req = std::make_shared(); req->requestorId(requestor_id); req->setPaddr(addr); + req->setSize(sizeof(Node)); PacketPtr pkt = Packet::createRead(req); - pkt->setSize(sizeof(Node)); // FIXME: do we need to specify the size here? + //pkt->setSize(sizeof(Node)); // FIXME: do we need to specify the size here? pkt->allocate(); return pkt; @@ -39,8 +40,9 @@ create_store_node(RequestorID requestor_id, const NodeID& node_id, RequestPtr req = std::make_shared(); req->requestorId(requestor_id); req->setPaddr(addr); + req->setSize(sizeof(Node)); PacketPtr pkt = Packet::createWrite(req); - pkt->setSize(sizeof(Node)); + //pkt->setSize(sizeof(Node)); pkt->allocate(); memcpy(pkt->getPtr(), &node, sizeof(Node)); diff --git a/src/arch/riscvcapstone/o3/tag_controller.cc b/src/arch/riscvcapstone/o3/tag_controller.cc index 99e382f59d..2fb1510ab0 100644 --- a/src/arch/riscvcapstone/o3/tag_controller.cc +++ b/src/arch/riscvcapstone/o3/tag_controller.cc @@ -174,9 +174,10 @@ MemoryTagController::getCommittedTag(const DynInstPtr& inst, RequestPtr req = std::make_shared(); req->requestorId(inst->requestorId()); req->setPaddr(tag_addr); + req->setSize(1); PacketPtr pkt = Packet::createRead(req); - pkt->setSize(1); + // pkt->setSize(1); pkt->allocate(); TagCacheRequest tcache_req = { @@ -219,9 +220,10 @@ MemoryTagController::writebackTagOp(DynInstPtr& inst, TagOp& tag_op) { RequestPtr req = std::make_shared(); req->requestorId(inst->requestorId()); req->setPaddr(addr); + req->setSize(1); PacketPtr pkt = Packet::createWrite(req); - pkt->setSize(1); + // pkt->setSize(1); pkt->allocate(); *(pkt->getPtr()) = tag_op.tagSet ? 1 : 0; diff --git a/src/mem/request.hh b/src/mem/request.hh index 39d9d7281c..aa905c04e9 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -599,6 +599,13 @@ class Request privateFlags.set(VALID_PADDR); } + void + setSize(unsigned size) + { + _size = size; + privateFlags.set(VALID_SIZE); + } + /** * Generate two requests as if this request had been split into two * pieces. The original request can't have been translated already. diff --git a/tests/capstone/o3/Makefile b/tests/capstone/o3/Makefile index 09dadb0fb3..f89c6aad7d 100644 --- a/tests/capstone/o3/Makefile +++ b/tests/capstone/o3/Makefile @@ -16,7 +16,7 @@ GEM5?=../../../build/RISCVCapstone/gem5.debug GEM5_FLAGS?= GEM5_CONFIG?=../../../configs/capstone/fast-forward.py GEM5_CONFIG_FLAGS?=--cpu=o3 -GEM5_TEST_TIMEOUT?=0 +GEM5_TEST_TIMEOUT?=20 CAPSTONE_TESTS_CFLAGS?= GCC=riscv64-unknown-linux-gnu-gcc