AArch64 EL2 hypervisor for QEMU virt that boots at EL2
1

Configure Feed

Select the types of activity you want to include in your feed.

ariel / core / sysreg.c
3.1 kB 90 lines
1#include "hv/sysreg.h" 2 3uint64_t sysreg_key_make(uint32_t op0, uint32_t op1, uint32_t crn, uint32_t crm, uint32_t op2) 4{ 5 return ((uint64_t)(op0 & 0x3u) << 14u) | 6 ((uint64_t)(op1 & 0x7u) << 11u) | 7 ((uint64_t)(crn & 0xfu) << 7u) | 8 ((uint64_t)(crm & 0xfu) << 3u) | 9 (uint64_t)(op2 & 0x7u); 10} 11 12bool sysreg_decode_from_esr_iss(uint64_t iss, struct sysreg_access *out) 13{ 14 if (out == (struct sysreg_access *)0) { 15 return false; 16 } 17 out->op0 = (uint32_t)((iss >> 20u) & 0x3u); 18 out->op2 = (uint32_t)((iss >> 17u) & 0x7u); 19 out->op1 = (uint32_t)((iss >> 14u) & 0x7u); 20 out->crn = (uint32_t)((iss >> 10u) & 0xfu); 21 out->rt = (uint32_t)((iss >> 5u) & 0x1fu); 22 out->crm = (uint32_t)((iss >> 1u) & 0xfu); 23 out->is_read = ((iss & 1u) == ESR_SYSREG_DIR_READ); 24 out->key = sysreg_key_make(out->op0, out->op1, out->crn, out->crm, out->op2); 25 return true; 26} 27 28struct sysreg_name { 29 uint64_t key; 30 const char *name; 31}; 32 33#define KEY(op0, op1, crn, crm, op2) SYSREG_KEY_CONST((op0), (op1), (crn), (crm), (op2)) 34 35static const struct sysreg_name g_names[] = { 36 { KEY(3, 0, 0, 0, 0), "midr_el1" }, 37 { KEY(3, 0, 0, 0, 5), "mpidr_el1" }, 38 { KEY(3, 0, 0, 4, 0), "id_aa64pfr0_el1" }, 39 { KEY(3, 0, 0, 4, 1), "id_aa64pfr1_el1" }, 40 { KEY(3, 0, 0, 6, 0), "id_aa64isar0_el1" }, 41 { KEY(3, 0, 0, 6, 1), "id_aa64isar1_el1" }, 42 { KEY(3, 0, 0, 7, 0), "id_aa64mmfr0_el1" }, 43 { KEY(3, 0, 0, 7, 1), "id_aa64mmfr1_el1" }, 44 { KEY(3, 1, 0, 0, 1), "clidr_el1" }, 45 { KEY(3, 2, 0, 0, 0), "csselr_el1" }, 46 { KEY(3, 3, 0, 0, 1), "ctr_el0" }, 47 { KEY(3, 3, 0, 0, 7), "dczid_el0" }, 48 { KEY(3, 0, 1, 0, 0), "sctlr_el1" }, 49 { KEY(3, 0, 1, 0, 1), "actlr_el1" }, 50 { KEY(3, 0, 1, 0, 2), "cpacr_el1" }, 51 { KEY(3, 4, 1, 1, 0), "hcr_el2" }, 52 { KEY(3, 6, 1, 1, 0), "scr_el3" }, 53 { KEY(3, 0, 2, 0, 0), "ttbr0_el1" }, 54 { KEY(3, 0, 2, 0, 1), "ttbr1_el1" }, 55 { KEY(3, 0, 2, 0, 2), "tcr_el1" }, 56 { KEY(3, 4, 2, 1, 0), "vttbr_el2" }, 57 { KEY(3, 3, 9, 12, 0), "pmcr_el0" }, 58 { KEY(3, 0, 10, 2, 0), "mair_el1" }, 59 { KEY(3, 0, 12, 0, 0), "vbar_el1" }, 60 { KEY(3, 0, 12, 0, 1), "rvbar_el1" }, 61 { KEY(3, 0, 13, 0, 1), "contextidr_el1" }, 62 { KEY(3, 0, 13, 0, 4), "tpidr_el1" }, 63 { KEY(3, 3, 13, 0, 3), "tpidrro_el0" }, 64 { KEY(3, 0, 14, 1, 0), "cntkctl_el1" }, 65 { KEY(3, 3, 14, 3, 0), "cntv_tval_el0" }, 66 { KEY(3, 3, 14, 3, 1), "cntv_ctl_el0" }, 67 { KEY(3, 3, 14, 3, 2), "cntv_cval_el0" }, 68 { KEY(2, 0, 0, 2, 2), "mdscr_el1" }, 69}; 70 71const char *sysreg_key_name(uint64_t key) 72{ 73 for (uint32_t i = 0; i < HV_ARRAY_SIZE(g_names); i++) { 74 if (g_names[i].key == key) { 75 return g_names[i].name; 76 } 77 } 78 return "unknown"; 79} 80 81bool sysreg_selftest(void) 82{ 83 struct sysreg_access a; 84 uint64_t iss = (3ull << 20u) | (0ull << 17u) | (0ull << 14u) | 85 (0ull << 10u) | (0ull << 5u) | (0ull << 1u) | 1ull; 86 if (!sysreg_decode_from_esr_iss(iss, &a)) { 87 return false; 88 } 89 return a.is_read && a.rt == 0u && a.key == KEY(3, 0, 0, 0, 0); 90}