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