summaryrefslogtreecommitdiff
path: root/riscv/riscv-probe/examples/enclave/enclave.c
blob: 93015ccefa2d7886981b345b3cc93408b2b35210 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
}