1/*
2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3 * Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 */
7
8#pragma once
9
10#include <util.h>
11
12#include <mode/hardware.h>
13
14/* Privileged CSR definitions */
15#define SSTATUS_SPIE  0x00000020
16#define SSTATUS_SPP   0x00000100
17#define SSTATUS_FS    0x00006000
18
19#define SSTATUS_FS_CLEAN    0x00004000
20#define SSTATUS_FS_INITIAL  0x00002000
21#define SSTATUS_FS_DIRTY    0x00006000
22
23#define SATP_MODE_OFF  0
24#define SATP_MODE_SV32 1
25#define SATP_MODE_SV39 8
26#define SATP_MODE_SV48 9
27
28#ifndef __ASSEMBLER__
29
30#include <config.h>
31#include <linker.h>
32
33#include <arch/types.h>
34#include <sel4/sel4_arch/constants.h>
35
36/* The size is for HiFive Unleashed */
37#define L1_CACHE_LINE_SIZE_BITS     6
38#define L1_CACHE_LINE_SIZE          BIT(L1_CACHE_LINE_SIZE_BITS)
39
40#define PAGE_BITS seL4_PageBits
41
42#define MODE_RESERVED 0
43
44/* MMU RISC-V related definitions. See RISC-V manual priv-1.10 */
45
46/* Extract the n-level PT index from a virtual address. This works for any
47 * configured RISC-V system with CONFIG_PT_LEVEL (which can be 2 on Sv32,
48 * 3 on Sv38, or 4 on Sv48)
49 */
50#define RISCV_GET_PT_INDEX(addr, n)  (((addr) >> (((PT_INDEX_BITS) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits)) & MASK(PT_INDEX_BITS))
51#define RISCV_GET_LVL_PGSIZE_BITS(n) (((PT_INDEX_BITS) * (((CONFIG_PT_LEVELS) - 1) - (n))) + seL4_PageBits)
52#define RISCV_GET_LVL_PGSIZE(n)      BIT(RISCV_GET_LVL_PGSIZE_BITS((n)))
53/*
54 * These values are defined in RISC-V priv-1.10 manual, they represent the
55 * exception codes saved in scause register (by the hardware) on traps.
56 */
57enum vm_fault_type {
58    RISCVInstructionMisaligned = 0,
59    RISCVInstructionAccessFault = 1,
60    RISCVInstructionIllegal = 2,
61    RISCVBreakpoint = 3,
62    /* reserved */
63    RISCVLoadAccessFault = 5,
64    RISCVAddressMisaligned = 6,
65    RISCVStoreAccessFault = 7,
66    RISCVEnvCall = 8,
67    /* 9-11 reserved */
68    RISCVInstructionPageFault = 12,
69    RISCVLoadPageFault = 13,
70    /* 14 - reserved */
71    RISCVStorePageFault = 15
72                          /* >= 16 reserved */
73};
74typedef word_t vm_fault_type_t;
75
76enum frameSizeConstants {
77    RISCVPageBits        = seL4_PageBits,
78    RISCVMegaPageBits    = seL4_LargePageBits,
79#if CONFIG_PT_LEVELS > 2
80    RISCVGigaPageBits    = seL4_HugePageBits,
81#endif
82#if CONFIG_PT_LEVELS > 3
83    RISCVTeraPageBits    = seL4_TeraPageBits
84#endif
85};
86
87enum vm_page_size {
88    RISCV_4K_Page,
89    RISCV_Mega_Page,
90    RISCV_Giga_Page,
91    RISCV_Tera_Page
92};
93typedef word_t vm_page_size_t;
94
95static inline word_t CONST pageBitsForSize(vm_page_size_t pagesize)
96{
97    switch (pagesize) {
98    case RISCV_4K_Page:
99        return RISCVPageBits;
100
101    case RISCV_Mega_Page:
102        return RISCVMegaPageBits;
103
104#if CONFIG_PT_LEVELS > 2
105    case RISCV_Giga_Page:
106        return RISCVGigaPageBits;
107#endif
108
109#if CONFIG_PT_LEVELS > 3
110    case RISCV_Tera_Page:
111        return RISCVTeraPageBits;
112#endif
113
114    default:
115        fail("Invalid page size");
116    }
117}
118
119static inline void arch_clean_invalidate_caches(void)
120{
121    /* RISC-V doesn't have an architecture defined way of flushing caches */
122}
123#endif /* __ASSEMBLER__ */
124
125#define LOAD_S STRINGIFY(LOAD)
126#define STORE_S STRINGIFY(STORE)
127
128#define IPI_MEM_BARRIER \
129    do { \
130        asm volatile("fence rw,rw" ::: "memory"); \
131    } while (0)
132
133