aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYenHaoChen <howard25336284@gmail.com>2023-01-11 18:44:02 +0800
committerYenHaoChen <howard25336284@gmail.com>2023-01-30 21:15:15 +0800
commitf8856e4d4f5a62bcc04234a2007910c20b0ca185 (patch)
tree0efd19de21f365b3dccb43f889530e6f7acb9711
parent4fb1389b17ee42452bb5d9dbf0118ec8f73518d2 (diff)
downloadspike-f8856e4d4f5a62bcc04234a2007910c20b0ca185.zip
spike-f8856e4d4f5a62bcc04234a2007910c20b0ca185.tar.gz
spike-f8856e4d4f5a62bcc04234a2007910c20b0ca185.tar.bz2
triggers: add icount_t and update tinfo
-rw-r--r--riscv/triggers.cc36
-rw-r--r--riscv/triggers.h16
2 files changed, 52 insertions, 0 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc
index 13c1a58..39e59bc 100644
--- a/riscv/triggers.cc
+++ b/riscv/triggers.cc
@@ -287,6 +287,40 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const
load = get_field(val, CSR_MCONTROL6_LOAD);
}
+reg_t icount_t::tdata1_read(const processor_t * const proc) const noexcept
+{
+ auto xlen = proc->get_xlen();
+ reg_t tdata1 = 0;
+ tdata1 = set_field(tdata1, CSR_ICOUNT_TYPE(xlen), CSR_TDATA1_TYPE_ICOUNT);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_DMODE(xlen), dmode);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_VS, proc->extension_enabled('H') ? vs : 0);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_VU, proc->extension_enabled('H') ? vu : 0);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_HIT, hit);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_COUNT, count);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_M, m);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_PENDING, pending);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_S, s);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_U, u);
+ tdata1 = set_field(tdata1, CSR_ICOUNT_ACTION, action);
+ return tdata1;
+}
+
+void icount_t::tdata1_write(processor_t * const proc, const reg_t val, const bool UNUSED allow_chain) noexcept
+{
+ auto xlen = proc->get_xlen();
+ assert(get_field(val, CSR_ICOUNT_TYPE(xlen)) == CSR_TDATA1_TYPE_ICOUNT);
+ dmode = proc->get_state()->debug_mode ? get_field(val, CSR_ICOUNT_DMODE(xlen)) : 0;
+ vs = get_field(val, CSR_ICOUNT_VS);
+ vu = get_field(val, CSR_ICOUNT_VU);
+ hit = get_field(val, CSR_ICOUNT_HIT);
+ count = get_field(val, CSR_ICOUNT_COUNT);
+ m = get_field(val, CSR_ICOUNT_M);
+ pending = get_field(val, CSR_ICOUNT_PENDING);
+ s = proc->extension_enabled_const('S') ? get_field(val, CSR_ICOUNT_S) : 0;
+ u = proc->extension_enabled_const('U') ? get_field(val, CSR_ICOUNT_U) : 0;
+ action = legalize_action(val, CSR_ICOUNT_ACTION, CSR_ICOUNT_DMODE(xlen));
+}
+
reg_t itrigger_t::tdata1_read(const processor_t * const proc) const noexcept
{
auto xlen = proc->get_xlen();
@@ -423,6 +457,7 @@ bool module_t::tdata1_write(unsigned index, const reg_t val) noexcept
delete triggers[index];
switch (type) {
case CSR_TDATA1_TYPE_MCONTROL: triggers[index] = new mcontrol_t(); break;
+ case CSR_TDATA1_TYPE_ICOUNT: triggers[index] = new icount_t(); break;
case CSR_TDATA1_TYPE_ITRIGGER: triggers[index] = new itrigger_t(); break;
case CSR_TDATA1_TYPE_ETRIGGER: triggers[index] = new etrigger_t(); break;
case CSR_TDATA1_TYPE_MCONTROL6: triggers[index] = new mcontrol6_t(); break;
@@ -515,6 +550,7 @@ reg_t module_t::tinfo_read(unsigned UNUSED index) const noexcept
{
/* In spike, every trigger supports the same types. */
return (1 << CSR_TDATA1_TYPE_MCONTROL) |
+ (1 << CSR_TDATA1_TYPE_ICOUNT) |
(1 << CSR_TDATA1_TYPE_ITRIGGER) |
(1 << CSR_TDATA1_TYPE_ETRIGGER) |
(1 << CSR_TDATA1_TYPE_MCONTROL6) |
diff --git a/riscv/triggers.h b/riscv/triggers.h
index bc64c4d..85842e3 100644
--- a/riscv/triggers.h
+++ b/riscv/triggers.h
@@ -233,6 +233,22 @@ public:
virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override;
};
+class icount_t : public trigger_t {
+public:
+ virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override;
+ virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override;
+
+ bool get_dmode() const override { return dmode; }
+ virtual action_t get_action() const override { return action; }
+
+private:
+ bool dmode;
+ bool hit;
+ unsigned count;
+ bool pending;
+ action_t action;
+};
+
class module_t {
public:
module_t(unsigned count);