From ee6488fc6f1a7ce9dd7a356a08b8a74a93a4ded6 Mon Sep 17 00:00:00 2001 From: Aditya Badole Date: Fri, 8 Sep 2023 14:12:08 +0800 Subject: [PATCH] #10 add checks for cwrld and emode; some code cleanup --- src/arch/riscvcapstone/isa/decoder.isa | 628 ++++--------------- src/arch/riscvcapstone/isa/formats/rnode.isa | 142 ++++- src/arch/riscvcapstone/o3/dyn_inst.hh | 8 + 3 files changed, 252 insertions(+), 526 deletions(-) diff --git a/src/arch/riscvcapstone/isa/decoder.isa b/src/arch/riscvcapstone/isa/decoder.isa index bad491a327..70acafbcc2 100644 --- a/src/arch/riscvcapstone/isa/decoder.isa +++ b/src/arch/riscvcapstone/isa/decoder.isa @@ -800,6 +800,10 @@ decode QUADRANT default Unknown::unknown() { } format Calls { 0x20: call ({{ //execute + if(dyn_inst->isSecureWorld()) { + return std::make_shared("Illegal instruction (2)", machInst); + } + if(!Rs1_trv.getTag()) return std::make_shared("Unexpected operand type (24)", machInst); @@ -870,6 +874,10 @@ decode QUADRANT default Unknown::unknown() { } format Return { 0x21: returni ({{ //execute + if(dyn_inst->isSecureWorld()) { + return std::make_shared("Illegal instruction (2)", machInst); + } + //rs1 != 0 check?? if(!Rs1_trv.getTag() || Rs2_trv.getTag()) { return std::make_shared("Unexpected operand type (24)", machInst); @@ -1142,47 +1150,10 @@ decode QUADRANT default Unknown::unknown() { }}); } format RNodeMemOp { - 0x3: ldc ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(RegVal))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(RegVal) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - //DPRINTFN("MemReads count = %d, tag query count = %d\n", - // dyn_inst->memReadN, dyn_inst->tagQueryN); - + 0x3: ldc ({{ //ea_code Fault fault = dyn_inst->initiateGetTag(EA); if(fault != NoFault) return fault; - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); }}, {{ //comp_code bool tag_res = dyn_inst->getTagQueryRes(0); if(!tag_res) { @@ -1190,6 +1161,13 @@ decode QUADRANT default Unknown::unknown() { "Load access fault (5)", machInst); } + Addr EA; + if(Rs1_trv.getTag()) { + EA = Rs1_trv.getRegVal().capVal().cursor() + IMM12; + } else { + EA = Rs1_trv.getRegVal().intVal() + IMM12; + } + ConstTaggedRegVal temp_regval; uint128_t& cap = Mem_rv.rawCapVal(); @@ -1200,8 +1178,6 @@ decode QUADRANT default Unknown::unknown() { using namespace gem5::RiscvcapstoneISA::o3; - Addr EA = Rs1_trv.getRegVal().capVal().cursor() + IMM12; - if(Mem_rv.capVal().type() != CapType::NONLIN) { dyn_inst->initiateSetTag(EA, false); } else { @@ -1221,6 +1197,13 @@ decode QUADRANT default Unknown::unknown() { using namespace gem5::RiscvcapstoneISA::o3; + DynInst* dyn_inst = dynamic_cast(xc); + assert(dyn_inst); + + if(dyn_inst->isSecureWorld()) { + return std::make_shared("Illegal instruction (2)", machInst); + } + if(!Rs1_trv.getTag()) { return std::make_shared("Unexpected operand type (24)", machInst); } @@ -1229,37 +1212,42 @@ decode QUADRANT default Unknown::unknown() { //signed imm12? NPC = rs1_cap.cursor() + IMM12; - DynInst* dyn_inst = dynamic_cast(xc); - assert(dyn_inst); - //write pc to rd + //todo: actually pc + 4 Rd_trv.getRegVal().rawCapVal() = (uint128_t)dyn_inst->cpu->getIEWObject().getPCCap(dyn_inst->threadNumber); dyn_inst->cpu->getIEWObject().setPCCap(rs1_cap, dyn_inst->threadNumber); //write cnull to rs1 - if(rs1_cap.type() != CapType::NONLIN) { - Rs1_trv.setTag(false); - } else { - NodeID node_id = Rs1_trv.getRegVal().capVal().nodeId(); - dyn_inst->initiateNodeCommand(new NodeRcUpdate(node_id, 1)); + if(RS1 != RD) { + if(rs1_cap.type() != CapType::NONLIN) { + Rs1_trv.setTag(false); + } else { + NodeID node_id = Rs1_trv.getRegVal().capVal().nodeId(); + dyn_inst->initiateNodeCommand(new NodeRcUpdate(node_id, 1)); + } } Rs1_trv = Rs1_trv; Rd_trv = Rd_trv; }}, IsUncondControl); 0x6: cbnz ({{ + using namespace gem5::RiscvcapstoneISA::o3; + + DynInst* dyn_inst = dynamic_cast(xc); + assert(dyn_inst); + + if(dyn_inst->isSecureWorld()) { + return std::make_shared("Illegal instruction (2)", machInst); + } + if(!(Rd_trv.getTag() && !Rs1_trv.getTag())) { return std::make_shared("Unexpected operand type (24)", machInst); } + //should I set PC or NPC hmmm if(Rs1_trv.getRegVal().intVal() != 0) { - using namespace gem5::RiscvcapstoneISA::o3; - - DynInst* dyn_inst = dynamic_cast(xc); - assert(dyn_inst); - Cap rd_cap = Rd_trv.getRegVal().capVal(); rd_cap.setCursor(rd_cap.cursor() + IMM12); @@ -1279,46 +1267,11 @@ decode QUADRANT default Unknown::unknown() { } format RNodeStoreMemOp { 0x4: stc ({{ //check_code - if(!Rs1_trv.getTag() || !Rs2_trv.getTag()) { - return std::make_shared( - "Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::SEALED || rs1_cap.type() == CapType::REV) { - return std::make_shared( - "Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasWritePerm()) { + if(!Rs2_trv.getTag()) { return std::make_shared( - "Insufficient capability permissions (27)", machInst); + "Unexpected operand type (24)", machInst); } - - //Rs1 == sealedret and Rs1.async != 0 - }}, {{ //ea_code - //@todo: load the value from aligned mem addr and update cap refcount if any - Addr offset = IMM7 << 5 | IMM5; - Addr EA = rs1_cap.cursor() + offset; - - if(rs1_cap.type() == CapType::UNINIT && - offset) { - return std::make_shared( - "Illegal operand value (29)", machInst); - } - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(RegVal))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if(EA & (sizeof(RegVal) - 1)) - return std::make_shared( - "Store address misaligned (6)", machInst); - - static_assert(sizeof(RegVal) == 16); + }}, {{ //memacc_code static_assert(sizeof(RegVal) == 16); Mem_rv = Rs2_trv.getRegVal(); @@ -1327,16 +1280,20 @@ decode QUADRANT default Unknown::unknown() { //if(fault != NoFault) // return fault; - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); - - Fault fault = writeMemTimingLE(xc, traceData, Mem_rv.rawCapVal(), EA, - memAccessFlags, nullptr); - if (fault != NoFault) - return fault; + Fault fault = writeMemTimingLE(xc, traceData, Mem.rawCapVal(), EA, + memAccessFlags, nullptr); + if (fault != NoFault) + return fault; }}, {{ //comp_code + if(Rs1_trv.getTag()) { Cap rs1_cap = Rs1_trv.getRegVal().capVal(); + if(rs1_cap.type() == CapType::UNINIT) + rs1_cap.setCursor(rs1_cap.cursor() + sizeof(RegVal)); + + Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + } + if(Rs2_trv.getRegVal().capVal().type() != CapType::NONLIN) Rs2_trv.setTag(false); else { @@ -1344,12 +1301,8 @@ decode QUADRANT default Unknown::unknown() { dyn_inst->initiateNodeCommand(new NodeRcUpdate(node_id, 1)); } - if(rs1_cap.type() == CapType::UNINIT) - rs1_cap.setCursor(rs1_cap.cursor() + sizeof(RegVal)); - Rs2_trv = Rs2_trv; Rs1_trv = Rs1_trv; - Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; }}, IsStore); } format CCSROp { @@ -1526,275 +1479,58 @@ decode QUADRANT default Unknown::unknown() { //End Capstone Ops 0x00: decode FUNCT3 { format RNodeMemOp { - 0x0: lb ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int8_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(int8_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x0: lb ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_sb, traceData); Rd_sb = Mem_sb; }}); - 0x1: lh ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int16_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(int16_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x1: lh ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_sh, traceData); Rd_sh = Mem_sh; }}); - 0x2: lw ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int32_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(int32_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x2: lw ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_sw, traceData); Rd_sw = Mem_sw; }}); - 0x3: ld ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int64_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(int64_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x3: ld ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_sd, traceData); Rd_sd = Mem_sd; }}); - 0x4: lbu ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(uint8_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(uint8_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x4: lbu ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_ub, traceData); Rd_ub = Mem_ub; }}); - 0x5: lhu ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(uint16_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(uint16_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x5: lhu ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_uh, traceData); Rd_uh = Mem_uh; }}); - 0x6: lwu ({{ //check_code - if(!Rs1_trv.getTag()) { - return std::make_shared("Unexpected operand type (24)", machInst); - } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::UNINIT || - rs1_cap.type() == CapType::SEALED || - rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 - return std::make_shared("Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasReadPerm()) { - return std::make_shared("Insufficient capability permissions (27)", machInst); - } - - //check if Rs1.type == SEALEDRET and Rs1.async == 0 - }}, {{ //ea_code - Addr EA = rs1_cap.cursor() + IMM12; - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(uint32_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if ((EA & (sizeof(uint32_t) - 1)) != 0) { - return std::make_shared( - "Load address misaligned (4)", machInst); - } - - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + 0x6: lwu ({{ //ea_code + }}, {{ //comp_code + Rs1_trv; getMemLE(pkt, Mem_uw, traceData); Rd_uw = Mem_uw; @@ -2004,46 +1740,11 @@ decode QUADRANT default Unknown::unknown() { 0x08: decode FUNCT3 { format RNodeStoreMemOp { 0x0: sb ({{ //check_code - if(!Rs1_trv.getTag() || Rs2_trv.getTag()) { + if(Rs2_trv.getTag()) { return std::make_shared( "Unexpected operand type (24)", machInst); } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::SEALED || rs1_cap.type() == CapType::REV) { - return std::make_shared( - "Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasWritePerm()) { - return std::make_shared( - "Insufficient capability permissions (27)", machInst); - } - - //Rs1 == sealedret and Rs1.async != 0 - }}, {{ //ea_code - //@todo: load the value from aligned mem addr and update cap refcount if any - Addr offset = IMM7 << 5 | IMM5; - Addr EA = rs1_cap.cursor() + offset; - - if(rs1_cap.type() == CapType::UNINIT && - offset) { - return std::make_shared( - "Illegal operand value (29)", machInst); - } - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int8_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if(EA & (sizeof(int8_t) - 1)) { - return std::make_shared( - "Store address misaligned (6)", machInst); - } - + }}, {{ //memacc_code Addr cap_aligned = EA & ~(sizeof(RegVal) - 1); dyn_inst->initiateSetTag(cap_aligned, false); @@ -2053,63 +1754,27 @@ decode QUADRANT default Unknown::unknown() { //if(fault != NoFault) // return fault; - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); - Fault fault = writeMemTimingLE(xc, traceData, Mem_sb, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; - }}, {{ //comp_code - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); + }}, {{ // comp_code + if(Rs1_trv.getTag()) { + Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - if(rs1_cap.type() == CapType::UNINIT) - rs1_cap.setCursor(rs1_cap.cursor() + sizeof(int8_t)); + if(rs1_cap.type() == CapType::UNINIT) + rs1_cap.setCursor(rs1_cap.cursor() + sizeof(Mem_sb)); - Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + } Rs1_trv = Rs1_trv; }}, IsStore); 0x1: sh ({{ //check_code - if(!Rs1_trv.getTag() || Rs2_trv.getTag()) { + if(Rs2_trv.getTag()) { return std::make_shared( "Unexpected operand type (24)", machInst); } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::SEALED || rs1_cap.type() == CapType::REV) { - return std::make_shared( - "Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasWritePerm()) { - return std::make_shared( - "Insufficient capability permissions (27)", machInst); - } - - //Rs1 == sealedret and Rs1.async != 0 - }}, {{ //ea_code - //@todo: load the value from aligned mem addr and update cap refcount if any - Addr offset = IMM7 << 5 | IMM5; - Addr EA = rs1_cap.cursor() + offset; - - if(rs1_cap.type() == CapType::UNINIT && - offset) { - return std::make_shared( - "Illegal operand value (29)", machInst); - } - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int16_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if(EA & (sizeof(int16_t) - 1)) { - return std::make_shared( - "Store address misaligned (6)", machInst); - } - + }}, {{ //memacc_code Addr cap_aligned = EA & ~(sizeof(RegVal) - 1); dyn_inst->initiateSetTag(cap_aligned, false); @@ -2119,63 +1784,27 @@ decode QUADRANT default Unknown::unknown() { //if(fault != NoFault) // return fault; - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); - Fault fault = writeMemTimingLE(xc, traceData, Mem_sh, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; - }}, {{ //comp_code - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); + }}, {{ // comp_code + if(Rs1_trv.getTag()) { + Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - if(rs1_cap.type() == CapType::UNINIT) - rs1_cap.setCursor(rs1_cap.cursor() + sizeof(int16_t)); + if(rs1_cap.type() == CapType::UNINIT) + rs1_cap.setCursor(rs1_cap.cursor() + sizeof(Mem_sh)); - Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + } Rs1_trv = Rs1_trv; }}, IsStore); 0x2: sw ({{ //check_code - if(!Rs1_trv.getTag() || Rs2_trv.getTag()) { + if(Rs2_trv.getTag()) { return std::make_shared( "Unexpected operand type (24)", machInst); } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::SEALED || rs1_cap.type() == CapType::REV) { - return std::make_shared( - "Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasWritePerm()) { - return std::make_shared( - "Insufficient capability permissions (27)", machInst); - } - - //Rs1 == sealedret and Rs1.async != 0 - }}, {{ //ea_code - //@todo: load the value from aligned mem addr and update cap refcount if any - Addr offset = IMM7 << 5 | IMM5; - Addr EA = rs1_cap.cursor() + offset; - - if(rs1_cap.type() == CapType::UNINIT && - offset) { - return std::make_shared( - "Illegal operand value (29)", machInst); - } - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int32_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if(EA & (sizeof(int32_t) - 1)) { - return std::make_shared( - "Store address misaligned (6)", machInst); - } - + }}, {{ //memacc_code Addr cap_aligned = EA & ~(sizeof(RegVal) - 1); dyn_inst->initiateSetTag(cap_aligned, false); @@ -2185,63 +1814,27 @@ decode QUADRANT default Unknown::unknown() { //if(fault != NoFault) // return fault; - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); - Fault fault = writeMemTimingLE(xc, traceData, Mem_sw, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; }}, {{ // comp_code - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); + if(Rs1_trv.getTag()) { + Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - if(rs1_cap.type() == CapType::UNINIT) - rs1_cap.setCursor(rs1_cap.cursor() + sizeof(int32_t)); + if(rs1_cap.type() == CapType::UNINIT) + rs1_cap.setCursor(rs1_cap.cursor() + sizeof(Mem_sw)); - Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + } Rs1_trv = Rs1_trv; }}, IsStore); 0x3: sd ({{ //check_code - if(!Rs1_trv.getTag() || Rs2_trv.getTag()) { + if(Rs2_trv.getTag()) { return std::make_shared( "Unexpected operand type (24)", machInst); } - - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - - if(rs1_cap.type() == CapType::SEALED || rs1_cap.type() == CapType::REV) { - return std::make_shared( - "Unexpected capability type (26)", machInst); - } - - if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && - !rs1_cap.hasWritePerm()) { - return std::make_shared( - "Insufficient capability permissions (27)", machInst); - } - - //Rs1 == sealedret and Rs1.async != 0 - }}, {{ //ea_code - //@todo: load the value from aligned mem addr and update cap refcount if any - Addr offset = IMM7 << 5 | IMM5; - Addr EA = rs1_cap.cursor() + offset; - - if(rs1_cap.type() == CapType::UNINIT && - offset) { - return std::make_shared( - "Illegal operand value (29)", machInst); - } - - if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(int64_t))) { - return std::make_shared( - "Capability out of bound (28)", machInst); - } - - if(EA & (sizeof(int64_t) - 1)) { - return std::make_shared( - "Store address misaligned (6)", machInst); - } - + }}, {{ //memacc_code Addr cap_aligned = EA & ~(sizeof(RegVal) - 1); dyn_inst->initiateSetTag(cap_aligned, false); @@ -2251,20 +1844,19 @@ decode QUADRANT default Unknown::unknown() { //if(fault != NoFault) // return fault; - NodeID node_id = rs1_cap.nodeId(); - dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); - Fault fault = writeMemTimingLE(xc, traceData, Mem_sd, EA, memAccessFlags, nullptr); if (fault != NoFault) return fault; }}, {{ // comp_code - Cap rs1_cap = Rs1_trv.getRegVal().capVal(); + if(Rs1_trv.getTag()) { + Cap rs1_cap = Rs1_trv.getRegVal().capVal(); - if(rs1_cap.type() == CapType::UNINIT) - rs1_cap.setCursor(rs1_cap.cursor() + sizeof(int64_t)); + if(rs1_cap.type() == CapType::UNINIT) + rs1_cap.setCursor(rs1_cap.cursor() + sizeof(Mem_sd)); - Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + Rs1_trv.getRegVal().rawCapVal() = (uint128_t)rs1_cap; + } Rs1_trv = Rs1_trv; }}, IsStore); } diff --git a/src/arch/riscvcapstone/isa/formats/rnode.isa b/src/arch/riscvcapstone/isa/formats/rnode.isa index 1fdcc8408c..8ff3b85b7a 100644 --- a/src/arch/riscvcapstone/isa/formats/rnode.isa +++ b/src/arch/riscvcapstone/isa/formats/rnode.isa @@ -108,11 +108,9 @@ def template RNodeExecute {{ } }}; -def format RNodeMemOp(check_code, - ea_code, memacc_code, *opt_flags) {{ +def format RNodeMemOp(ea_code, memacc_code, *opt_flags) {{ iop = InstObjParams(name, Name, 'RegNodeOp', - {'check_code': check_code, - 'ea_code': ea_code, + {'ea_code': ea_code, 'memacc_code': memacc_code}, opt_flags) header_output = RNodeMemDeclare.subst(iop) decoder_output = RNodeMemConstructor.subst(iop) @@ -135,12 +133,73 @@ def template RNodeMemExecute {{ %(op_decl)s; %(op_rd)s; - %(check_code)s; + CPU *o3cpu = dynamic_cast(dyn_inst->getCpuPtr()); + assert(o3cpu); + + bool cwrld = o3cpu->cwrld[dyn_inst->threadNumber]; + uint64_t emode = o3cpu->readMiscReg(CSR_EMODE, dyn_inst->threadNumber); + if(cwrld || (!cwrld && emode)) { + if(!Rs1.getTag()) { + return std::make_shared("Unexpected operand type (24)", machInst); + } + + Cap rs1_cap = Rs1.getRegVal().capVal(); + + if(rs1_cap.type() == CapType::UNINIT || + rs1_cap.type() == CapType::SEALED || + rs1_cap.type() == CapType::REV) { //todo: or sealedret and async != 0 + return std::make_shared("Unexpected capability type (26)", machInst); + } + + if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && + !rs1_cap.hasReadPerm()) { + return std::make_shared("Insufficient capability permissions (27)", machInst); + } + + //check if Rs1.type == SEALEDRET and Rs1.async == 0 + } else { //integer encoding mode + if(Rs1.getTag()) { + return std::make_shared("Unexpected operand type (24)", machInst); + } + } + + Addr EA; + + if(cwrld || (!cwrld && emode)) { + Cap rs1_cap = Rs1.getRegVal().capVal(); + EA = rs1_cap.cursor() + IMM12; + + if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(Mem))) { + return std::make_shared( + "Capability out of bound (28)", machInst); + } + + //DPRINTFN("MemReads count = %d, tag query count = %d\n", + //dyn_inst->memReadN, dyn_inst->tagQueryN); + + NodeID node_id = rs1_cap.nodeId(); + dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + } else { + EA = Rs1.getRegVal().intVal() + IMM12; + + if(dyn_inst->addrInSecRegion(EA, sizeof(Mem))) { + return std::make_shared( + "Load access fault (5)", machInst); + } + } + + if ((EA & (sizeof(Mem) - 1)) != 0) { + return std::make_shared( + "Load address misaligned (4)", machInst); + } %(ea_code)s; initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); + //for integer loads, if Rd already contains a cap + //clear it and update refcount + return NoFault; } }}; @@ -183,10 +242,10 @@ def template RNodeMemDeclare {{ }}; def format RNodeStoreMemOp(check_code, - ea_code, comp_code, *opt_flags) {{ + memacc_code, comp_code, *opt_flags) {{ iop = InstObjParams(name, Name, 'RegNodeOp', {'check_code': check_code, - 'ea_code': ea_code, + 'memacc_code': memacc_code, 'comp_code': comp_code}, opt_flags) header_output = RNodeStoreMemDeclare.subst(iop) @@ -209,8 +268,75 @@ def template RNodeStoreExecute {{ %(op_decl)s; %(op_rd)s; + CPU *o3cpu = dynamic_cast(dyn_inst->getCpuPtr()); + assert(o3cpu); + + bool cwrld = o3cpu->cwrld[dyn_inst->threadNumber]; + uint64_t emode = o3cpu->readMiscReg(CSR_EMODE, dyn_inst->threadNumber); + if(cwrld || (!cwrld && emode)) { + if(!Rs1.getTag()) { + return std::make_shared( + "Unexpected operand type (24)", machInst); + } + + Cap rs1_cap = Rs1.getRegVal().capVal(); + + if(rs1_cap.type() == CapType::SEALED || rs1_cap.type() == CapType::REV) { + return std::make_shared( + "Unexpected capability type (26)", machInst); + } + + if((rs1_cap.type() == CapType::LIN || rs1_cap.type() == CapType::NONLIN) && + !rs1_cap.hasWritePerm()) { + return std::make_shared( + "Insufficient capability permissions (27)", machInst); + } + + //Rs1 == sealedret and Rs1.async != 0 + } else { //integer encoding mode + if(Rs1.getTag()) { + return std::make_shared( + "Unexpected operand type (24)", machInst); + } + } + %(check_code)s; - %(ea_code)s; + + //@todo: load the value from aligned mem addr and update cap refcount if any + Addr EA; + Addr offset = IMM7 << 5 | IMM5; + if(cwrld || (!cwrld && emode)) { + Cap rs1_cap = Rs1.getRegVal().capVal(); + EA = rs1_cap.cursor() + offset; + + if(rs1_cap.type() == CapType::UNINIT && offset) { + return std::make_shared( + "Illegal operand value (29)", machInst); + } + + if(!capInBoundForMemAcc(rs1_cap, EA, sizeof(Mem))) { + return std::make_shared( + "Capability out of bound (28)", machInst); + } + } else { + EA = Rs1.getRegVal().intVal() + offset; + + if(dyn_inst->addrInSecRegion(EA, sizeof(Mem))) { + return std::make_shared( + "Store/AMO access fault (7)", machInst); + } + } + + if(EA & (sizeof(Mem) - 1)) + return std::make_shared( + "Store address misaligned (6)", machInst); + + if(cwrld || (!cwrld && emode)) { + NodeID node_id = rs1_cap.nodeId(); + dyn_inst->initiateNodeCommand(new NodeQuery(node_id)); + } + + %(memacc_code)s; return NoFault; } diff --git a/src/arch/riscvcapstone/o3/dyn_inst.hh b/src/arch/riscvcapstone/o3/dyn_inst.hh index 4373104b08..209fabfd2c 100644 --- a/src/arch/riscvcapstone/o3/dyn_inst.hh +++ b/src/arch/riscvcapstone/o3/dyn_inst.hh @@ -1403,6 +1403,14 @@ class DynInst : public ExecContext, public RefCounted void completeMemRead(int idx, PacketPtr pkt); void checkQueryCompleted(); + + bool addrInSecRegion(Addr addr, uint64_t size) { + return (addr >= cpu->secure_base - size && addr < cpu->secure_end); + } + + bool isSecureWorld() { + return cpu->cwrld[threadNumber]; + } }; } // namespace RiscvcapstoneISA::o3