summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0002-feat-emulate-interrupt-controller-register-access.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0002-feat-emulate-interrupt-controller-register-access.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0002-feat-emulate-interrupt-controller-register-access.patch159
1 files changed, 159 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0002-feat-emulate-interrupt-controller-register-access.patch b/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0002-feat-emulate-interrupt-controller-register-access.patch
new file mode 100644
index 0000000000..95f1651a84
--- /dev/null
+++ b/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0002-feat-emulate-interrupt-controller-register-access.patch
@@ -0,0 +1,159 @@
+From 380f2cf944dd5db36c168a11d31a46ad14cdcb6d Mon Sep 17 00:00:00 2001
+From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
+Date: Tue, 26 Apr 2022 14:43:58 +0100
+Subject: [PATCH 4/5] feat: emulate interrupt controller register access
+
+This emulates ICC_SGI1R_EL1 and ICC_IGRPEN1_EL1 register
+
+Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
+Change-Id: I0c11f034f3676067597461a183a341c809adcaa4
+Upstream-Status: Inappropriate [Experimental feature]
+---
+ src/arch/aarch64/hypervisor/handler.c | 5 ++
+ src/arch/aarch64/hypervisor/perfmon.c | 84 +++++++++++++++++++++++++++
+ src/arch/aarch64/hypervisor/perfmon.h | 5 ++
+ src/arch/aarch64/msr.h | 3 +
+ 4 files changed, 97 insertions(+)
+
+diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
+index c9068c5..b9aa5d8 100644
+--- a/src/arch/aarch64/hypervisor/handler.c
++++ b/src/arch/aarch64/hypervisor/handler.c
+@@ -1282,6 +1282,11 @@ void handle_system_register_access(uintreg_t esr_el2)
+ inject_el1_unknown_exception(vcpu, esr_el2);
+ return;
+ }
++ } else if (intr_ctrl_is_register_access(esr_el2)) {
++ if (!intr_ctrl_el1_process_access(vcpu, vm_id, esr_el2)) {
++ inject_el1_unknown_exception(vcpu, esr_el2);
++ return;
++ }
+ } else {
+ inject_el1_unknown_exception(vcpu, esr_el2);
+ return;
+diff --git a/src/arch/aarch64/hypervisor/perfmon.c b/src/arch/aarch64/hypervisor/perfmon.c
+index f13b035..05e216c 100644
+--- a/src/arch/aarch64/hypervisor/perfmon.c
++++ b/src/arch/aarch64/hypervisor/perfmon.c
+@@ -116,6 +116,10 @@
+ X(PMEVTYPER30_EL0 , 3, 3, 14, 15, 6) \
+ X(PMCCFILTR_EL0 , 3, 3, 14, 15, 7)
+
++#define INTR_CTRL_REGISTERS \
++ X(ICC_IGRPEN1_EL1 , 3, 0, 12, 12, 7) \
++ X(ICC_SGI1R_EL1 , 3, 0, 12, 11, 5) \
++
+ /* clang-format on */
+
+ /**
+@@ -232,3 +236,83 @@ uintreg_t perfmon_get_pmccfiltr_el0_init_value(ffa_vm_id_t vm_id)
+
+ return 0;
+ }
++
++bool intr_ctrl_is_register_access(uintreg_t esr)
++{
++ uintreg_t op0 = GET_ISS_OP0(esr);
++ uintreg_t op1 = GET_ISS_OP1(esr);
++ uintreg_t crn = GET_ISS_CRN(esr);
++ uintreg_t crm = GET_ISS_CRM(esr);
++
++ if (op0 == 3 && op1 == 0 && crn == 12 && crm == 12) {
++ return true;
++ }
++
++ if (op0 == 3 && op1 == 0 && crn == 12 && crm == 11) {
++ return true;
++ }
++
++ return false;
++}
++
++bool intr_ctrl_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
++ uintreg_t esr)
++{
++ uintreg_t sys_register = GET_ISS_SYSREG(esr);
++ uintreg_t rt_register = GET_ISS_RT(esr);
++ uintreg_t value;
++
++ /* +1 because Rt can access register XZR */
++ CHECK(rt_register < NUM_GP_REGS + 1);
++
++ if (ISS_IS_READ(esr)) {
++ switch (sys_register) {
++#define X(reg_name, op0, op1, crn, crm, op2) \
++ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
++ value = read_msr(reg_name); \
++ break;
++ INTR_CTRL_REGISTERS
++#undef X
++ default:
++ value = vcpu->regs.r[rt_register];
++ dlog_notice(
++ "Unsupported interrupt control register "
++ "read: "
++ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
++ "rt=%d.\n",
++ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
++ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
++ GET_ISS_OP2(esr), GET_ISS_RT(esr));
++ break;
++ }
++ if (rt_register != RT_REG_XZR) {
++ vcpu->regs.r[rt_register] = value;
++ }
++ } else {
++ if (rt_register != RT_REG_XZR) {
++ value = vcpu->regs.r[rt_register];
++ } else {
++ value = 0;
++ }
++ switch (sys_register) {
++#define X(reg_name, op0, op1, crn, crm, op2) \
++ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
++ write_msr(reg_name, value); \
++ break;
++ INTR_CTRL_REGISTERS
++#undef X
++ default:
++ dlog_notice(
++ "Unsupported interrupt control register "
++ "write: "
++ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
++ "rt=%d.\n",
++ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
++ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
++ GET_ISS_OP2(esr), GET_ISS_RT(esr));
++ break;
++ }
++ }
++
++ return true;
++}
+diff --git a/src/arch/aarch64/hypervisor/perfmon.h b/src/arch/aarch64/hypervisor/perfmon.h
+index 81669ba..c90d45b 100644
+--- a/src/arch/aarch64/hypervisor/perfmon.h
++++ b/src/arch/aarch64/hypervisor/perfmon.h
+@@ -70,3 +70,8 @@ bool perfmon_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
+ uintreg_t esr_el2);
+
+ uintreg_t perfmon_get_pmccfiltr_el0_init_value(ffa_vm_id_t vm_id);
++
++bool intr_ctrl_is_register_access(uintreg_t esr);
++
++bool intr_ctrl_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
++ uintreg_t esr);
+diff --git a/src/arch/aarch64/msr.h b/src/arch/aarch64/msr.h
+index 55e7833..82aa884 100644
+--- a/src/arch/aarch64/msr.h
++++ b/src/arch/aarch64/msr.h
+@@ -134,3 +134,6 @@
+ #define MSR_CNTHPS_CTL_EL2 S3_4_C14_C5_1
+ #define MSR_CNTHPS_CVAL_EL2 S3_4_C14_C5_2
+ #define MSR_CNTHPS_TVAL_EL2 S3_4_C14_C5_0
++
++#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
++#define ICC_SGI1R_EL1 S3_0_C12_C11_5
+--
+2.17.1
+