#include #include void guest_main(void); uint64_t guest_hvc_call(uint64_t num, uint64_t a1, uint64_t a2); static size_t guest_strlen(const char *s) { size_t n = 0; while (s[n] != '\0') { n++; } return n; } static uint64_t hvc_call(uint64_t num, uint64_t a1, uint64_t a2) { return guest_hvc_call(num, a1, a2); } static void console(const char *s) { (void)hvc_call(4u, (uint64_t)(uintptr_t)s, guest_strlen(s)); } static uint64_t read_midr(void) { uint64_t v; __asm__ volatile("mrs %0, midr_el1" : "=r"(v)); return v; } static uint64_t read_pfr0(void) { uint64_t v; __asm__ volatile("mrs %0, id_aa64pfr0_el1" : "=r"(v)); return v; } static uint64_t read_cntv_ctl(void) { uint64_t v; __asm__ volatile("mrs %0, cntv_ctl_el0" : "=r"(v)); return v; } static void write_sctlr(uint64_t v) { __asm__ volatile("msr sctlr_el1, %0" :: "r"(v) : "memory"); } static void write_vbar(uint64_t v) { __asm__ volatile("msr vbar_el1, %0" :: "r"(v) : "memory"); } static void write_ttbr0(uint64_t v) { __asm__ volatile("msr ttbr0_el1, %0" :: "r"(v) : "memory"); } static void write_tcr(uint64_t v) { __asm__ volatile("msr tcr_el1, %0" :: "r"(v) : "memory"); } static void write_actlr(uint64_t v) { __asm__ volatile("msr actlr_el1, %0" :: "r"(v) : "memory"); } static uint64_t attempt_hcr_el2_read(void) { uint64_t v; __asm__ volatile("mrs %0, hcr_el2" : "=r"(v)); return v; } static uint64_t read_unknown_sysreg(void) { uint64_t v; __asm__ volatile("mrs %0, S3_7_C15_C15_7" : "=r"(v)); return v; } void guest_main(void) { console("diagnostic guest: start"); uint64_t midr = read_midr(); (void)midr; console("diagnostic guest: read midr_el1"); uint64_t pfr0 = read_pfr0(); (void)pfr0; console("diagnostic guest: read id_aa64pfr0_el1"); write_sctlr(0x30d00800u); console("diagnostic guest: wrote sctlr_el1 shadow"); write_vbar(0x40000800u); console("diagnostic guest: wrote vbar_el1 vector base"); write_ttbr0(0u); console("diagnostic guest: wrote ttbr0_el1 shadow"); write_tcr(0u); console("diagnostic guest: wrote tcr_el1 shadow"); uint64_t cntv = read_cntv_ctl(); (void)cntv; console("diagnostic guest: read cntv_ctl_el0"); (void)hvc_call(0u, 0u, 0u); console("diagnostic guest: requested hv id"); (void)hvc_call(1u, 0u, 0u); console("diagnostic guest: requested log dump"); console("diagnostic guest: attempting denied hcr_el2 read"); (void)attempt_hcr_el2_read(); console("diagnostic guest: returned through guest undefined vector"); __asm__ volatile("brk #0"); console("diagnostic guest: returned through guest brk vector"); console("diagnostic guest: attempting unknown sysreg read"); (void)read_unknown_sysreg(); console("diagnostic guest: returned from unknown sysreg read"); console("diagnostic guest: attempting denied actlr_el1 write"); write_actlr(1u); console("diagnostic guest: unexpected return from denied actlr_el1"); (void)hvc_call(3u, 0u, 0u); }