Skip to content

Commit

Permalink
tlm_sbi: added translated attribute and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
janweinstock committed Nov 4, 2024
1 parent e74d795 commit f82c928
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 27 deletions.
87 changes: 78 additions & 9 deletions include/vcml/protocols/tlm_sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,71 @@

namespace vcml {

enum sbi_defaults : i64 {
SBI_CPUID_DEFAULT = 0,
SBI_PRIVILEGE_NONE = 0,
SBI_ASID_GLOBAL = 0,
};

//
// tlm_sbi
//
// Sideband information for TLM generic payloads, normally attached through the
// tlm optional extension mechanism using vcml::tlm_sbi_ext
//
// tlm_sbi.is_debug (bool, target-read-only, default off)
// request originates from a debugger and must not have any side effects,
// e.g. must not call wait() or notify()
//
// tlm_sbi.is_nodmi (bool, target-read-only, default off)
// set by the initiator to indicate that the target must not use DMI pointers
// to fullfull the request; the corresponding transaction should be forwarded
// to its next target using b_transport.
//
// tlm_sbi.is_sync (bool, target-read-only, default off)
// set by the initiator to request that the transaction should be executed
// synchronously and not ahead of simulation time (e.g. sc_time in
// b_transport should be SC_ZERO_TIME)
//
// tlm_sbi.is_insn (bool, target-read-only, default off)
// set by the initiatiro to indicate if a request is being used by for
// instruction execution execution, e.g. a instruction fetch or prefetch by a
// processor using a transaction read command
//
// tlm_sbi.is_excl (bool, target-read-write, default off)
// set by initiator to indicate exclusive load (if corresponding transaction
// is a read command) or an exclusive store (if it is a write command);
// cleared by the target if the exclusive store operation failed, e.g. due to
// a missing exclusive monitor lock.
//
// tlm_sbi.is_lock (bool, target-read-only, default off)
// set by the initiator to indicate a locked bus transaction; busses must
// block any requests from other initiators until they see another
// transaction from this initiator with is_lock set to false.
//
// tlm_sbi.is_secure (bool, target-read-only, default off)
// set by the initiator to indicate that this request originates from a
// secure context
//
// tlm_sbi.is_translated (bool, target-read-only, default off)
// set by the initiator to indicate that the address in the associated TLM
// generic payload is a physical address; IOMMUs should not attempt to
// perform a virtual-to-physical address translation on it.
//
// tlm_sbi.cpuid (bool, target-read-only, default 0)
// set by the initiator to its own unique identfication number.
//
// tlm_sbi.privilege (bool, target-read-only, default 0)
// set by the initiator to indicate the privilege level it is operating at; a
// default privilege level of 0 means "no privilege" (e.g. EL0 in ARM and
// U-Mode in RISCV)
//
// tlm_sbi.asid (bool, target-read-only, default 0)
// set by the initiator to indicate the application space ID of the address
// in the associated TLM generic payload, e.g. for SR-IOV:
// - for processors, the ASID may refer to the currently active process
// - for devices the ASID may refer to the currently active virtual function

struct tlm_sbi {
bool is_debug;
bool is_nodmi;
Expand All @@ -24,6 +89,7 @@ struct tlm_sbi {
bool is_excl;
bool is_lock;
bool is_secure;
bool is_translated;

u64 cpuid;
u64 privilege;
Expand All @@ -34,7 +100,8 @@ struct tlm_sbi {

tlm_sbi();
tlm_sbi(bool debug, bool nodmi, bool sync, bool insn, bool excl, bool lock,
bool secure, u64 cpu = 0, u64 privilege = 0, u64 asid = 0);
bool secure, bool translated, u64 cpu = 0,
u64 privilege = SBI_PRIVILEGE_NONE, u64 asid = SBI_ASID_GLOBAL);

void copy(const tlm_sbi& other);

Expand Down Expand Up @@ -65,7 +132,8 @@ inline bool tlm_sbi::operator==(const tlm_sbi& other) const {
return is_debug == other.is_debug && is_nodmi == other.is_nodmi &&
is_sync == other.is_sync && is_insn == other.is_insn &&
is_excl == other.is_excl && is_lock == other.is_lock &&
is_secure == other.is_secure && cpuid == other.cpuid &&
is_secure == other.is_secure &&
is_translated == other.is_translated && cpuid == other.cpuid &&
privilege == other.privilege && asid == other.asid;
}

Expand All @@ -81,21 +149,18 @@ extern const tlm_sbi SBI_INSN;
extern const tlm_sbi SBI_EXCL;
extern const tlm_sbi SBI_LOCK;
extern const tlm_sbi SBI_SECURE;
extern const tlm_sbi SBI_TRANSLATED;

inline tlm_sbi sbi_cpuid(u64 cpu) {
return tlm_sbi(false, false, false, false, false, false, false, cpu, 0, 0);
return tlm_sbi(0, 0, 0, 0, 0, 0, 0, 0, cpu, 0, 0);
}

inline tlm_sbi sbi_privilege(u64 lvl) {
return tlm_sbi(false, false, false, false, false, false, false, 0, lvl, 0);
return tlm_sbi(0, 0, 0, 0, 0, 0, 0, 0, 0, lvl, 0);
}

inline tlm_sbi sbi_asid(u64 id) {
return tlm_sbi(false, false, false, false, false, false, false, 0, 0, id);
}

inline tlm_sbi sbi_security(bool sec) {
return tlm_sbi(false, false, false, false, false, false, sec, 0, 0, 0);
return tlm_sbi(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, id);
}

class sbiext : public tlm_extension<sbiext>, public tlm_sbi
Expand Down Expand Up @@ -143,6 +208,10 @@ inline bool tx_is_secure(const tlm_generic_payload& tx) {
return tx_get_sbi(tx).is_secure;
}

inline bool tx_is_translated(const tlm_generic_payload& tx) {
return tx_get_sbi(tx).is_translated;
}

inline u64 tx_cpuid(const tlm_generic_payload& tx) {
return tx_get_sbi(tx).cpuid;
}
Expand Down
15 changes: 8 additions & 7 deletions src/vcml/models/riscv/iommu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ enum iommu_event : u32 {
IOMMU_EVENT_MAX,
};

constexpr u32 iommu_event_req(bool tx) {
return tx ? IOMMU_EVENT_TX_REQ : IOMMU_EVENT_UX_REQ;
}

using CAPS_VERSION = field<0, 8, u64>;
using CAPS_IGS = field<28, 2, u64>;
using CAPS_PAS = field<32, 6, u64>;
Expand Down Expand Up @@ -1135,6 +1139,7 @@ int iommu::translate_g(context& ctx, u64 virt, bool wnr, bool ind, bool dbg,
bool iommu::translate(const tlm_generic_payload& tx, const tlm_sbi& info,
bool dmi, iotlb& entry) {
bool dbg = info.is_debug;
bool txreq = info.is_translated;
bool super = info.privilege > 0;
u32 devid = info.cpuid;
u32 pasid = info.asid;
Expand All @@ -1160,6 +1165,9 @@ bool iommu::translate(const tlm_generic_payload& tx, const tlm_sbi& info,
return false;
}

if (!dbg && !dmi)
increment_counter(ctx, iommu_event_req(txreq));

err = fetch_iotlb(ctx, virt, tx.is_write(), super, dbg, dmi, entry);
if (err) {
if (!dbg && !dmi && !(ctx.tc & TC_DTF)) {
Expand All @@ -1178,13 +1186,6 @@ bool iommu::translate(const tlm_generic_payload& tx, const tlm_sbi& info,
return false;
}

if (!dbg && !dmi) {
if (ddtp.get_field<DDTP_MODE>() == DDTP_MODE_BARE)
increment_counter(ctx, IOMMU_EVENT_UX_REQ);
else
increment_counter(ctx, IOMMU_EVENT_TX_REQ);
}

return true;
}

Expand Down
26 changes: 17 additions & 9 deletions src/vcml/protocols/tlm_sbi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,24 @@ tlm_sbi::tlm_sbi():
is_excl(false),
is_lock(false),
is_secure(false),
is_translated(false),
cpuid(0),
privilege(0),
asid(0) {
// nothing to do
}

tlm_sbi::tlm_sbi(bool debug, bool nodmi, bool sync, bool insn, bool excl,
bool lock, bool secure, u64 cpu, u64 lvl, u64 id):
bool lock, bool secure, bool translated, u64 cpu, u64 lvl,
u64 id):
is_debug(debug),
is_nodmi(nodmi),
is_sync(sync),
is_insn(insn),
is_excl(excl),
is_lock(lock),
is_secure(secure),
is_translated(translated),
cpuid(cpu),
privilege(lvl),
asid(id) {
Expand All @@ -49,6 +52,7 @@ void tlm_sbi::copy(const tlm_sbi& other) {
is_excl = other.is_excl;
is_lock = other.is_lock;
is_secure = other.is_secure;
is_translated = other.is_translated;
cpuid = other.cpuid;
privilege = other.privilege;
asid = other.asid;
Expand All @@ -67,6 +71,7 @@ tlm_sbi& tlm_sbi::operator&=(const tlm_sbi& other) {
is_excl &= other.is_excl;
is_lock &= other.is_lock;
is_secure &= other.is_secure;
is_translated &= other.is_translated;
cpuid &= other.cpuid;
privilege &= other.privilege;
asid &= other.asid;
Expand All @@ -81,6 +86,7 @@ tlm_sbi& tlm_sbi::operator|=(const tlm_sbi& other) {
is_excl |= other.is_excl;
is_lock |= other.is_lock;
is_secure |= other.is_secure;
is_translated |= other.is_translated;
cpuid |= other.cpuid;
privilege |= other.privilege;
asid |= other.asid;
Expand All @@ -95,20 +101,22 @@ tlm_sbi& tlm_sbi::operator^=(const tlm_sbi& other) {
is_excl ^= other.is_excl;
is_lock ^= other.is_lock;
is_secure ^= other.is_secure;
is_translated ^= other.is_translated;
cpuid ^= other.cpuid;
privilege ^= other.privilege;
asid ^= other.asid;
return *this;
}

const tlm_sbi SBI_NONE = { false, false, false, false, false, false, false };
const tlm_sbi SBI_DEBUG = { true, false, false, false, false, false, false };
const tlm_sbi SBI_NODMI = { false, true, false, false, false, false, false };
const tlm_sbi SBI_SYNC = { false, false, true, false, false, false, false };
const tlm_sbi SBI_INSN = { false, false, false, true, false, false, false };
const tlm_sbi SBI_EXCL = { false, false, false, false, true, false, false };
const tlm_sbi SBI_LOCK = { false, false, false, false, false, true, false };
const tlm_sbi SBI_SECURE = { false, false, false, false, false, false, true };
const tlm_sbi SBI_NONE = { 0, 0, 0, 0, 0, 0, 0, 0 };
const tlm_sbi SBI_DEBUG = { true, 0, 0, 0, 0, 0, 0, 0 };
const tlm_sbi SBI_NODMI = { 0, true, 0, 0, 0, 0, 0, 0 };
const tlm_sbi SBI_SYNC = { 0, 0, true, 0, 0, 0, 0, 0 };
const tlm_sbi SBI_INSN = { 0, 0, 0, true, 0, 0, 0, 0 };
const tlm_sbi SBI_EXCL = { 0, 0, 0, 0, true, 0, 0, 0 };
const tlm_sbi SBI_LOCK = { 0, 0, 0, 0, 0, true, 0, 0 };
const tlm_sbi SBI_SECURE = { 0, 0, 0, 0, 0, 0, true, 0 };
const tlm_sbi SBI_TRANSLATED = { 0, 0, 0, 0, 0, 0, 0, true };

tlm_extension_base* sbiext::clone() const {
return new sbiext(*this);
Expand Down
4 changes: 2 additions & 2 deletions test/models/riscv_iommu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ class iommu_test : public test_base
ASSERT_OK(out.readw(iommu_iohpmctr(7), table_walks_s));
ASSERT_OK(out.readw(iommu_iohpmctr(8), table_walks_g));

EXPECT_EQ(ux_reqs, 0);
EXPECT_EQ(tx_reqs, 2);
EXPECT_EQ(ux_reqs, 2);
EXPECT_EQ(tx_reqs, 0);
EXPECT_EQ(tlb_misses, 1);
EXPECT_EQ(ddt_walks, 2);
EXPECT_EQ(pdt_walks, 0);
Expand Down

0 comments on commit f82c928

Please sign in to comment.