1/* 2 * Copyright 2018, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13/* 14 * 15 * Copyright 2016, 2017 Hesham Almatary, Data61/CSIRO <hesham.almatary@data61.csiro.au> 16 * Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com> 17 */ 18 19#ifndef __ARCH_MACHINE_H 20#define __ARCH_MACHINE_H 21 22#ifndef __ASSEMBLER__ 23#include <arch/types.h> 24#include <arch/object/structures.h> 25#include <arch/machine/hardware.h> 26#include <arch/encoding.h> 27#include <arch/model/statedata.h> 28#include <arch/sbi.h> 29 30static inline void sfence(void) 31{ 32 asm volatile ("sfence.vma" ::: "memory"); 33} 34 35static inline void hwASIDFlush(asid_t asid) 36{ 37 asm volatile ("sfence.vma x0, %0" :: "r" (asid): "memory"); 38} 39 40word_t PURE getRestartPC(tcb_t *thread); 41void setNextPC(tcb_t *thread, word_t v); 42 43/* Cleaning memory before user-level access */ 44static inline void clearMemory(void* ptr, unsigned int bits) 45{ 46 memzero(ptr, BIT(bits)); 47} 48 49static inline void write_sptbr(word_t value) 50{ 51 asm volatile("csrw sptbr, %0" :: "rK"(value)); 52} 53 54static inline void write_stvec(word_t value) 55{ 56 asm volatile("csrw stvec, %0" :: "rK"(value)); 57} 58 59static inline word_t read_sbadaddr(void) 60{ 61 word_t temp; 62 asm volatile("csrr %0, sbadaddr" : "=r"(temp)); 63 return temp; 64} 65 66static inline word_t read_scause(void) 67{ 68 word_t temp; 69 asm volatile("csrr %0, scause" : "=r"(temp)); 70 return temp; 71} 72 73static inline word_t read_sepc(void) 74{ 75 word_t temp; 76 asm volatile("csrr %0, sepc" : "=r"(temp)); 77 return temp; 78} 79 80static inline word_t read_sstatus(void) 81{ 82 word_t temp; 83 asm volatile("csrr %0, sstatus" : "=r"(temp)); 84 return temp; 85} 86 87static inline void set_sie_mask(word_t mask_high) 88{ 89 word_t temp; 90 asm volatile("csrrs %0, sie, %1" : "=r"(temp) : "rK"(mask_high)); 91} 92 93static inline void clear_sie_mask(word_t mask_low) 94{ 95 word_t temp; 96 asm volatile("csrrc %0, sie, %1" : "=r"(temp) : "rK"(mask_low)); 97} 98 99static inline void clear_sip_mask(word_t mask_low) 100{ 101 word_t temp; 102 asm volatile("csrrc %0, sip, %1" : "=r"(temp) : "rK"(mask_low)); 103} 104 105#if CONFIG_PT_LEVELS == 2 106#define SATP_MODE SPTBR_MODE_SV32 107#elif CONFIG_PT_LEVELS == 3 108#define SATP_MODE SPTBR_MODE_SV39 109#elif CONFIG_PT_LEVELS == 4 110#define SATP_MODE SPTBR_MODE_SV48 111#else 112#error "Unsupported PT levels" 113#endif 114static inline void setVSpaceRoot(paddr_t addr, asid_t asid) 115{ 116 satp_t satp = satp_new(SATP_MODE, /* mode */ 117 asid, /* asid */ 118 addr >> seL4_PageBits); /* PPN */ 119 120 /* Current toolchain still uses sptbr register name although it got renamed in priv-1.10. 121 * This will most likely need to change with newer toolchains 122 */ 123 write_sptbr(satp.words[0]); 124 125 /* Order read/write operations */ 126 sfence(); 127} 128 129static inline void Arch_finaliseInterrupt(void) 130{ 131} 132 133#endif // __ASSEMBLER__ 134#endif 135 136