thermosphere: implement reading and writing guest memory

This commit is contained in:
TuxSH 2020-01-20 02:24:02 +00:00
parent 0f0228e240
commit 217c1ad054
22 changed files with 467 additions and 118 deletions

View file

@ -62,6 +62,11 @@ typedef enum ReadWriteDirection {
DIRECTION_READWRITE = DIRECTION_READ | DIRECTION_WRITE,
} ReadWriteDirection;
static inline void __compiler_barrier(void)
{
__asm__ __volatile__ ("" ::: "memory");
}
static inline void __wfi(void)
{
__asm__ __volatile__ ("wfi" ::: "memory");
@ -100,6 +105,11 @@ static inline void __dsb(void)
__asm__ __volatile__ ("dsb ish" ::: "memory");
}
static inline void __dsb_local(void)
{
__asm__ __volatile__ ("dsb nsh" ::: "memory");
}
static inline void __dmb_sy(void)
{
__asm__ __volatile__ ("dmb sy" ::: "memory");
@ -125,11 +135,27 @@ static inline void __tlb_invalidate_el2_local(void)
__asm__ __volatile__ ("tlbi alle2" ::: "memory");
}
static inline void __tlb_invalidate_el2_page(uintptr_t addr)
{
__asm__ __volatile__ ("tlbi vae2is, %0" :: "r"(addr) : "memory");
}
static inline void __tlb_invalidate_el2_page_local(uintptr_t addr)
{
__asm__ __volatile__ ("tlbi vae2is, %0" :: "r"(addr) : "memory");
}
static inline void __tlb_invalidate_el1_stage12_local(void)
{
__asm__ __volatile__ ("tlbi alle1" ::: "memory");
}
static inline void __tlb_invalidate_el1(void)
{
__asm__ __volatile__ ("tlbi vmalle1is" ::: "memory");
}
bool overlaps(u64 as, u64 ae, u64 bs, u64 be);
// Assumes addr is valid, must be called with interrupts masked
@ -138,23 +164,11 @@ static inline uintptr_t va2pa(const void *el2_vaddr) {
// For debug purposes only
uintptr_t PAR;
uintptr_t va = (uintptr_t)el2_vaddr;
__asm__ __volatile__ ("at s1e2r, %0" :: "r"(va));
__asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR));
__asm__ __volatile__ ("at s1e2r, %0" :: "r"(va) : "memory");
__asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR) :: "memory");
return (PAR & MASK2L(47, 12)) | (va & MASKL(12));
}
static inline uintptr_t get_physical_address_el1_stage12(bool *valid, uintptr_t el1_vaddr) {
// NOTE: interrupt must be disabled when calling this func
uintptr_t PAR;
__asm__ __volatile__ ("at s12e1r, %0" :: "r"(el1_vaddr)); // note: we don't care whether it's writable in EL1&0 translation regime
__asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR));
*valid = (PAR & 1) == 0ull;
return (PAR & 1) ? 0ull : (PAR & MASK2L(47, 12)) | ((uintptr_t)el1_vaddr & MASKL(12));
}
bool readEl1Memory(void *dst, uintptr_t addr, size_t size);
bool writeEl1Memory(uintptr_t addr, const void *src, size_t size);
static inline void panic(void) {
#ifndef PLATFORM_QEMU
__builtin_trap();