summaryrefslogtreecommitdiff
path: root/riscv/riscv-probe/examples
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/riscv-probe/examples')
-rw-r--r--riscv/riscv-probe/examples/abort/main.c6
-rw-r--r--riscv/riscv-probe/examples/abort/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/alloca/main.c17
-rw-r--r--riscv/riscv-probe/examples/alloca/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/argv0/main.c6
-rw-r--r--riscv/riscv-probe/examples/argv0/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/enclave/enclave.c79
-rw-r--r--riscv/riscv-probe/examples/enclave/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/hang/hang.c23
-rw-r--r--riscv/riscv-probe/examples/hang/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/hello/hello.c6
-rw-r--r--riscv/riscv-probe/examples/hello/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/malloc/main.c21
-rw-r--r--riscv/riscv-probe/examples/malloc/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/memory/main.c17
-rw-r--r--riscv/riscv-probe/examples/memory/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/probe/probe.c71
-rw-r--r--riscv/riscv-probe/examples/probe/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/symbols/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/symbols/symbols.c28
-rw-r--r--riscv/riscv-probe/examples/user/rules.mk1
-rw-r--r--riscv/riscv-probe/examples/user/user.c27
22 files changed, 312 insertions, 0 deletions
diff --git a/riscv/riscv-probe/examples/abort/main.c b/riscv/riscv-probe/examples/abort/main.c
new file mode 100644
index 0000000..cf5bcc0
--- /dev/null
+++ b/riscv/riscv-probe/examples/abort/main.c
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+
+int main(int argc, char **argv)
+{
+ abort();
+}
diff --git a/riscv/riscv-probe/examples/abort/rules.mk b/riscv/riscv-probe/examples/abort/rules.mk
new file mode 100644
index 0000000..d569b90
--- /dev/null
+++ b/riscv/riscv-probe/examples/abort/rules.mk
@@ -0,0 +1 @@
+abort_objs = main.o
diff --git a/riscv/riscv-probe/examples/alloca/main.c b/riscv/riscv-probe/examples/alloca/main.c
new file mode 100644
index 0000000..af9696a
--- /dev/null
+++ b/riscv/riscv-probe/examples/alloca/main.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <alloca.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ const size_t nelems = 4;
+ const size_t elemsize = 128;
+ char *alloc[nelems];
+
+ for (size_t i = 0; i < nelems; i++) {
+ if (alloc[i] = alloca(elemsize)) {
+ memset(alloc[i], 0, elemsize);
+ }
+ printf("alloca[%d]=0x%x\n", i, alloc[i]);
+ }
+}
diff --git a/riscv/riscv-probe/examples/alloca/rules.mk b/riscv/riscv-probe/examples/alloca/rules.mk
new file mode 100644
index 0000000..198ef24
--- /dev/null
+++ b/riscv/riscv-probe/examples/alloca/rules.mk
@@ -0,0 +1 @@
+alloca_objs = main.o
diff --git a/riscv/riscv-probe/examples/argv0/main.c b/riscv/riscv-probe/examples/argv0/main.c
new file mode 100644
index 0000000..7699fe2
--- /dev/null
+++ b/riscv/riscv-probe/examples/argv0/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("%s\n", argv[0]);
+}
diff --git a/riscv/riscv-probe/examples/argv0/rules.mk b/riscv/riscv-probe/examples/argv0/rules.mk
new file mode 100644
index 0000000..0ceeeaa
--- /dev/null
+++ b/riscv/riscv-probe/examples/argv0/rules.mk
@@ -0,0 +1 @@
+argv0_objs = main.o
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
+}
diff --git a/riscv/riscv-probe/examples/enclave/rules.mk b/riscv/riscv-probe/examples/enclave/rules.mk
new file mode 100644
index 0000000..046cbae
--- /dev/null
+++ b/riscv/riscv-probe/examples/enclave/rules.mk
@@ -0,0 +1 @@
+enclave_objs = enclave.o
diff --git a/riscv/riscv-probe/examples/hang/hang.c b/riscv/riscv-probe/examples/hang/hang.c
new file mode 100644
index 0000000..066ca9e
--- /dev/null
+++ b/riscv/riscv-probe/examples/hang/hang.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ volatile int a;
+ int b, c, d, e, f, g, h, i, j, k, l, m;
+ printf("hang\n");
+ for (;;) {
+ a = b;
+ b = c;
+ c = d;
+ d = e;
+ e = f;
+ f = g;
+ g = h;
+ h = i;
+ i = j;
+ j = k;
+ k = l;
+ l = m;
+ m = a;
+ }
+}
diff --git a/riscv/riscv-probe/examples/hang/rules.mk b/riscv/riscv-probe/examples/hang/rules.mk
new file mode 100644
index 0000000..8a04005
--- /dev/null
+++ b/riscv/riscv-probe/examples/hang/rules.mk
@@ -0,0 +1 @@
+hang_objs = hang.o
diff --git a/riscv/riscv-probe/examples/hello/hello.c b/riscv/riscv-probe/examples/hello/hello.c
new file mode 100644
index 0000000..d65ed6a
--- /dev/null
+++ b/riscv/riscv-probe/examples/hello/hello.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("hello\n");
+}
diff --git a/riscv/riscv-probe/examples/hello/rules.mk b/riscv/riscv-probe/examples/hello/rules.mk
new file mode 100644
index 0000000..4d43f63
--- /dev/null
+++ b/riscv/riscv-probe/examples/hello/rules.mk
@@ -0,0 +1 @@
+hello_objs = hello.o
diff --git a/riscv/riscv-probe/examples/malloc/main.c b/riscv/riscv-probe/examples/malloc/main.c
new file mode 100644
index 0000000..cde2038
--- /dev/null
+++ b/riscv/riscv-probe/examples/malloc/main.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ const size_t nelems = 8;
+ const size_t elemsize = 128;
+ char *alloc[nelems];
+
+ for (size_t i = 0; i < nelems; i++) {
+ if (alloc[i] = malloc(elemsize)) {
+ memset(alloc[i], 0, elemsize);
+ }
+ printf("malloc[%d]=0x%x\n", i, alloc[i]);
+ }
+
+ for (size_t i = 0; i < nelems; i++) {
+ free(alloc[i]);
+ }
+} \ No newline at end of file
diff --git a/riscv/riscv-probe/examples/malloc/rules.mk b/riscv/riscv-probe/examples/malloc/rules.mk
new file mode 100644
index 0000000..82b0bc6
--- /dev/null
+++ b/riscv/riscv-probe/examples/malloc/rules.mk
@@ -0,0 +1 @@
+malloc_objs = main.o
diff --git a/riscv/riscv-probe/examples/memory/main.c b/riscv/riscv-probe/examples/memory/main.c
new file mode 100644
index 0000000..01c5d0b
--- /dev/null
+++ b/riscv/riscv-probe/examples/memory/main.c
@@ -0,0 +1,17 @@
+#include "femto.h"
+#ifdef __riscv
+#include "arch/riscv/encoding.h"
+#include "arch/riscv/machine.h"
+#endif
+
+extern char _memory_start;
+
+int main(int argc, char **argv)
+{
+#ifdef __riscv
+ memory_info_t info = memory_probe();
+ printf("memory_start=0x%lx - 0x%lx\n", info.start, info.end);
+#else
+ puts("architecture-not-supported");
+#endif
+}
diff --git a/riscv/riscv-probe/examples/memory/rules.mk b/riscv/riscv-probe/examples/memory/rules.mk
new file mode 100644
index 0000000..1d0ad8c
--- /dev/null
+++ b/riscv/riscv-probe/examples/memory/rules.mk
@@ -0,0 +1 @@
+memory_objs = main.o
diff --git a/riscv/riscv-probe/examples/probe/probe.c b/riscv/riscv-probe/examples/probe/probe.c
new file mode 100644
index 0000000..4cc4384
--- /dev/null
+++ b/riscv/riscv-probe/examples/probe/probe.c
@@ -0,0 +1,71 @@
+#include "femto.h"
+
+#ifdef __riscv
+#include "arch/riscv/csr.h"
+#include "arch/riscv/trap.h"
+#include "arch/riscv/encoding.h"
+#include "arch/riscv/machine.h"
+
+#define MCAUSE_UNSET 0xabbaabba
+
+static volatile uintptr_t save_mcause;
+
+static void trap_save_cause(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
+{
+ save_mcause = mcause;
+ write_csr(mepc, mepc + 4);
+}
+
+static const char* isa_string(char *buf, size_t bufsz)
+{
+ static const char *ext = "iemafdqlcbjtpvnsu";
+
+ const char *p = ext;
+ char *q = buf + snprintf(buf, bufsz, "rv%d", xlen());
+ do {
+ if (has_ext(*p)) {
+ *q++ = *p;
+ }
+ } while (*++p);
+ *q = '\0';
+
+ return buf;
+}
+
+static void probe_all_csrs()
+{
+ int *csrenum = csr_enum_array();
+ const char **csrnames = csr_name_array();
+ const char* ws = " ";
+ set_trap_fn(trap_save_cause);
+ while (*csrenum != csr_none) {
+ save_mcause = MCAUSE_UNSET;
+ long value = read_csr_enum(*csrenum);
+ const char* csrname = csrnames[*csrenum];
+ if (save_mcause != MCAUSE_UNSET) {
+ int async = save_mcause < 0;
+ int cause = save_mcause & (((uintptr_t)-1) >> async);
+ printf("csr: %s%s %s cause=%ld mtval=0x%lx\n",
+ csrname, ws + strlen(csrname), cause < 16
+ ? (async ? riscv_intr_names : riscv_excp_names)[cause]
+ : "(unknown)", save_mcause, read_csr_enum(csr_mtval));
+ } else {
+ printf("csr: %s%s 0x%lx\n",
+ csrname, ws + strlen(csrname), value);
+ }
+ csrenum++;
+ }
+}
+#endif
+
+int main(int argc, char **argv)
+{
+#ifdef __riscv
+ char buf[32];
+ printf("isa: %s\n", isa_string(buf, sizeof(buf)));
+ probe_all_csrs();
+ printf("\n");
+#else
+ puts("architecture-not-supported");
+#endif
+}
diff --git a/riscv/riscv-probe/examples/probe/rules.mk b/riscv/riscv-probe/examples/probe/rules.mk
new file mode 100644
index 0000000..928f066
--- /dev/null
+++ b/riscv/riscv-probe/examples/probe/rules.mk
@@ -0,0 +1 @@
+probe_objs = probe.o
diff --git a/riscv/riscv-probe/examples/symbols/rules.mk b/riscv/riscv-probe/examples/symbols/rules.mk
new file mode 100644
index 0000000..ba4e934
--- /dev/null
+++ b/riscv/riscv-probe/examples/symbols/rules.mk
@@ -0,0 +1 @@
+symbols_objs = symbols.o
diff --git a/riscv/riscv-probe/examples/symbols/symbols.c b/riscv/riscv-probe/examples/symbols/symbols.c
new file mode 100644
index 0000000..d05807f
--- /dev/null
+++ b/riscv/riscv-probe/examples/symbols/symbols.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+/* program to print linker script provided symbols */
+
+extern char _text_start;
+extern char _text_end;
+extern char _rodata_start;
+extern char _rodata_end;
+extern char _data_start;
+extern char _data_end;
+extern char _bss_start;
+extern char _bss_end;
+extern char _memory_start;
+extern char _memory_end;
+
+int main(int argc, char **argv)
+{
+ printf("_text_start=0x%x\n", &_text_start);
+ printf("_text_end=0x%x\n", &_text_end);
+ printf("_rodata_start=0x%x\n", &_rodata_start);
+ printf("_rodata_end=0x%x\n", &_rodata_end);
+ printf("_data_start=0x%x\n", &_data_start);
+ printf("_data_end=0x%x\n", &_data_end);
+ printf("_bss_start=0x%x\n", &_bss_start);
+ printf("_bss_end=0x%x\n", &_bss_end);
+ printf("_memory_start=0x%x\n", &_memory_start);
+ printf("_memory_end=0x%x\n", &_memory_end);
+}
diff --git a/riscv/riscv-probe/examples/user/rules.mk b/riscv/riscv-probe/examples/user/rules.mk
new file mode 100644
index 0000000..63c6868
--- /dev/null
+++ b/riscv/riscv-probe/examples/user/rules.mk
@@ -0,0 +1 @@
+user_objs = user.o
diff --git a/riscv/riscv-probe/examples/user/user.c b/riscv/riscv-probe/examples/user/user.c
new file mode 100644
index 0000000..e37397f
--- /dev/null
+++ b/riscv/riscv-probe/examples/user/user.c
@@ -0,0 +1,27 @@
+#include "femto.h"
+
+#ifdef __riscv
+#include "arch/riscv/encoding.h"
+#include "arch/riscv/machine.h"
+#endif
+
+int main(int argc, char **argv)
+{
+ /*
+ * Set up PMP (Physical Memory Protection)
+ *
+ * PMP is optional; bit if implemented enforcement is mandatory
+ * and user-mode is prevented access to all memory by default.
+ * We should change this code to restrict user mode to its .text
+ * .rodata, .data, .bss and devices.
+ */
+#ifdef __riscv
+ if (pmp_entry_count() > 0) {
+ pmp_allow_all();
+ }
+ mode_set_and_continue(PRV_U);
+ puts("riscv-user-mode");
+#else
+ puts("architecture-not-supported");
+#endif
+}