1// See LICENSE for license details.
2
3#ifndef _RISCV_MTRAP_H
4#define _RISCV_MTRAP_H
5
6#include "encoding.h"
7
8#ifdef __riscv_atomic
9# define MAX_HARTS 8 // arbitrary
10#else
11# define MAX_HARTS 1
12#endif
13
14#ifndef __ASSEMBLER__
15
16#include <stdint.h>
17#include <stddef.h>
18#include <stdarg.h>
19
20#define read_const_csr(reg) ({ unsigned long __tmp; \
21  asm ("csrr %0, " #reg : "=r"(__tmp)); \
22  __tmp; })
23
24static inline int supports_extension(char ext)
25{
26  return read_const_csr(misa) & (1 << (ext - 'A'));
27}
28
29static inline int xlen()
30{
31  return read_const_csr(misa) < 0 ? 64 : 32;
32}
33
34extern uintptr_t mem_size;
35extern volatile uint64_t* mtime;
36extern volatile uint32_t* plic_priorities;
37extern size_t plic_ndevs;
38
39typedef struct {
40  volatile uint32_t* ipi;
41  volatile int mipi_pending;
42
43  volatile uint64_t* timecmp;
44
45  volatile uint32_t* plic_m_thresh;
46  volatile uintptr_t* plic_m_ie;
47  volatile uint32_t* plic_s_thresh;
48  volatile uintptr_t* plic_s_ie;
49} hls_t;
50
51#define MACHINE_STACK_TOP() ({ \
52  register uintptr_t sp asm ("sp"); \
53  (void*)((sp + RISCV_PGSIZE) & -RISCV_PGSIZE); })
54
55// hart-local storage, at top of stack
56#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
57#define OTHER_HLS(id) ((hls_t*)((void*)HLS() + RISCV_PGSIZE * ((id) - read_const_csr(mhartid))))
58
59hls_t* hls_init(uintptr_t hart_id);
60void parse_config_string();
61void poweroff(uint16_t code) __attribute((noreturn));
62void printm(const char* s, ...);
63void vprintm(const char *s, va_list args);
64void putstring(const char* s);
65#define assert(x) ({ if (!(x)) die("assertion failed: %s", #x); })
66#define die(str, ...) ({ printm("%s:%d: " str "\n", __FILE__, __LINE__, ##__VA_ARGS__); poweroff(-1); })
67
68void setup_pmp();
69void enter_supervisor_mode(void (*fn)(uintptr_t), uintptr_t arg0, uintptr_t arg1)
70  __attribute__((noreturn));
71void enter_machine_mode(void (*fn)(uintptr_t, uintptr_t), uintptr_t arg0, uintptr_t arg1)
72  __attribute__((noreturn));
73void boot_loader(uintptr_t dtb);
74void boot_other_hart(uintptr_t dtb);
75
76static inline void wfi()
77{
78  asm volatile ("wfi" ::: "memory");
79}
80
81#endif // !__ASSEMBLER__
82
83#define IPI_SOFT       0x1
84#define IPI_FENCE_I    0x2
85#define IPI_SFENCE_VMA 0x4
86#define IPI_HALT       0x8
87
88#define MACHINE_STACK_SIZE RISCV_PGSIZE
89#define MENTRY_HLS_OFFSET (INTEGER_CONTEXT_SIZE + SOFT_FLOAT_CONTEXT_SIZE)
90#define MENTRY_FRAME_SIZE (MENTRY_HLS_OFFSET + HLS_SIZE)
91#define MENTRY_IPI_OFFSET (MENTRY_HLS_OFFSET)
92#define MENTRY_IPI_PENDING_OFFSET (MENTRY_HLS_OFFSET + REGBYTES)
93
94#ifdef __riscv_flen
95# define SOFT_FLOAT_CONTEXT_SIZE 0
96#else
97# define SOFT_FLOAT_CONTEXT_SIZE (8 * 32)
98#endif
99#define HLS_SIZE 64
100#define INTEGER_CONTEXT_SIZE (32 * REGBYTES)
101
102#endif
103