summaryrefslogtreecommitdiff
path: root/riscv/riscv-probe/examples/enclave/enclave.c
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:18:39 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:18:39 +0200
commit8c6fc0c15415b32080a848bbde640e104098cf13 (patch)
tree04a21bd28f9dc82c8e216390d6208ed93b9bcd11 /riscv/riscv-probe/examples/enclave/enclave.c
Initial drop
Add some riscv code Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'riscv/riscv-probe/examples/enclave/enclave.c')
-rw-r--r--riscv/riscv-probe/examples/enclave/enclave.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/riscv/riscv-probe/examples/enclave/enclave.c b/riscv/riscv-probe/examples/enclave/enclave.c
new file mode 100644
index 0000000..93015cc
--- /dev/null
+++ b/riscv/riscv-probe/examples/enclave/enclave.c
@@ -0,0 +1,79 @@
+#include "femto.h"
+
+/*
+ * Simple enclave example using RISC-V PMP (Physical Memory Protection)
+ *
+ * NOTE: Physical memory protection is enabled for the program text (RX)
+ * program data (RW), UART, and the hart is switch to U mode, however,
+ * there is only one program and the default trap vector points into
+ * the executable text, so traps are handled in M mode, in the same
+ * executable text segment. A more complete example needs to load a
+ * second process and provide ecall APIs to the protected enclave.
+ * This is not yet a true secure enclave until two disjunctive worlds
+ * are have been implemented with measured boot and signed code.
+ */
+
+extern char _text_start;
+extern char _rodata_end;
+extern char _data_start;
+extern char _bss_end;
+
+static uintptr_t uart_keys[] = {
+ SIFIVE_UART0_CTRL_ADDR,
+ NS16550A_UART0_CTRL_ADDR,
+ RISCV_HTIF_BASE_ADDR,
+ 0
+};
+
+#ifdef __riscv
+#include "arch/riscv/encoding.h"
+#include "arch/riscv/machine.h"
+#include "arch/riscv/csr.h"
+#endif
+
+int main()
+{
+ uintptr_t uart = 0;
+ uintptr_t *uart_k = uart_keys;
+ const uintptr_t uartlen = 32;
+
+ /* locate UART address using known configuration keys */
+ while (*uart_k && !(uart = getauxval(*uart_k++)));
+
+ /* locate ROM/Flash (text+rodata) and RAM (data+bss) */
+ uintptr_t rx_s = (uintptr_t)&_text_start;
+ uintptr_t rx_l = roundpow2((uintptr_t)(&_rodata_end - &_text_start));
+ uintptr_t rw_s = (uintptr_t)&_data_start;
+ uintptr_t rw_l = roundpow2((uintptr_t)(&_bss_end - &_data_start));
+
+ /* print our findings */
+ printf("text: 0x%x - 0x%x\n", rx_s, rx_s + rx_l - 1);
+ printf("data: 0x%x - 0x%x\n", rw_s, rw_s + rw_l - 1);
+ if (uart) {
+ printf("uart: 0x%x - 0x%x\n", uart, uart + uartlen - 1);
+ }
+
+#ifdef __riscv
+ pmp_info_t info = pmp_probe();
+ if (info.count == 0) {
+ puts("pmp-not-supported");
+ return 0;
+ } else {
+ printf("pmp.count: %d\n", info.count);
+ printf("pmp.width: %d\n", info.width);
+ printf("pmp.granularity: %d\n", info.granularity);
+ }
+ /* set up physical memory protection */
+ pmp_entry_set(0, PMP_R | PMP_X, rx_s, rx_l);
+ pmp_entry_set(1, PMP_R | PMP_W, rw_s, rw_l);
+ if (uart) {
+ pmp_entry_set(2, PMP_R | PMP_W, uart, uartlen);
+ }
+
+ /* switch to user mode enclave */
+ mode_set_and_continue(PRV_U);
+ puts("riscv-enclave");
+#else
+ puts("architecture-not-supported");
+#endif
+}