aboutsummaryrefslogtreecommitdiff
path: root/riscv/zicfiss.h
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/zicfiss.h')
-rw-r--r--riscv/zicfiss.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/riscv/zicfiss.h b/riscv/zicfiss.h
new file mode 100644
index 0000000..83c166d
--- /dev/null
+++ b/riscv/zicfiss.h
@@ -0,0 +1,31 @@
+// See LICENSE for license details.
+
+#ifndef _RISCV_ZICFISS_H
+#define _RISCV_ZICFISS_H
+
+#define xSSE() \
+ ((STATE.prv != PRV_M) && get_field(STATE.menvcfg->read(), MENVCFG_SSE) && \
+ p->extension_enabled('S') && \
+ ((STATE.v && get_field(STATE.henvcfg->read(), HENVCFG_SSE)) || !STATE.v) && \
+ (((STATE.prv == PRV_U) && get_field(STATE.senvcfg->read(), SENVCFG_SSE)) || (STATE.prv != PRV_U)))
+
+#define PUSH_VALUE_TO_SS(value) ({ \
+ reg_t push_value = (value); \
+ reg_t push_ssp_addr = STATE.ssp->read() - xlen / 8; \
+ if (xlen == 32) \
+ MMU.ss_store<uint32_t>(push_ssp_addr, push_value); \
+ else \
+ MMU.ss_store<uint64_t>(push_ssp_addr, push_value); \
+ STATE.ssp->write(push_ssp_addr); \
+ })
+
+#define POP_VALUE_FROM_SS_AND_CHECK(value) \
+ reg_t shadow_return_addr; \
+ if (xlen == 32) \
+ shadow_return_addr = MMU.ss_load<uint32_t>(STATE.ssp->read()); \
+ else \
+ shadow_return_addr = MMU.ss_load<uint64_t>(STATE.ssp->read()); \
+ software_check(value == shadow_return_addr, SHADOW_STACK_FAULT); \
+ STATE.ssp->write(STATE.ssp->read() + xlen / 8);
+
+#endif