1b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier/*
2b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Copyright (C) 2012,2013 - ARM Ltd
3b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Author: Marc Zyngier <marc.zyngier@arm.com>
4b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier *
5b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Based on arch/arm/kvm/coproc_a15.c:
6b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Copyright (C) 2012 - Virtual Open Systems and Columbia University
7b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Authors: Rusty Russell <rusty@rustcorp.au>
8b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier *          Christoffer Dall <c.dall@virtualopensystems.com>
9b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier *
10b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * This program is free software; you can redistribute it and/or modify
11b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * it under the terms of the GNU General Public License, version 2, as
12b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * published by the Free Software Foundation.
13b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier *
14b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * This program is distributed in the hope that it will be useful,
15b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * but WITHOUT ANY WARRANTY; without even the implied warranty of
16b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * GNU General Public License for more details.
18b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier *
19b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * You should have received a copy of the GNU General Public License
20b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier */
22b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <linux/kvm_host.h>
23b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <asm/cputype.h>
24b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <asm/kvm_arm.h>
25b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <asm/kvm_asm.h>
26b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <asm/kvm_host.h>
27b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <asm/kvm_emulate.h>
28b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <asm/kvm_coproc.h>
29b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include <linux/init.h>
30b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
31b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier#include "sys_regs.h"
32b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
33b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngierstatic bool access_actlr(struct kvm_vcpu *vcpu,
34b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier			 const struct sys_reg_params *p,
35b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier			 const struct sys_reg_desc *r)
36b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier{
37b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	if (p->is_write)
38b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier		return ignore_write(vcpu, p);
39b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
40b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	*vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, ACTLR_EL1);
41b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	return true;
42b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier}
43b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
44b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngierstatic void reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
45b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier{
46b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	u64 actlr;
47b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
48b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	asm volatile("mrs %0, actlr_el1\n" : "=r" (actlr));
49b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	vcpu_sys_reg(vcpu, ACTLR_EL1) = actlr;
50b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier}
51b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
52b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier/*
53b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Implementation specific sys-reg registers.
54b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
55b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier */
56b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngierstatic const struct sys_reg_desc genericv8_sys_regs[] = {
57b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	/* ACTLR_EL1 */
58b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	{ Op0(0b11), Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
59b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	  access_actlr, reset_actlr, ACTLR_EL1 },
60b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier};
61b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
6206c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngierstatic const struct sys_reg_desc genericv8_cp15_regs[] = {
6306c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier	/* ACTLR */
6406c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier	{ Op1(0b000), CRn(0b0001), CRm(0b0000), Op2(0b001),
6506c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier	  access_actlr },
6606c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier};
6706c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier
68b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngierstatic struct kvm_sys_reg_target_table genericv8_target_table = {
69b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	.table64 = {
70b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier		.table = genericv8_sys_regs,
71b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier		.num = ARRAY_SIZE(genericv8_sys_regs),
72b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	},
7306c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier	.table32 = {
7406c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier		.table = genericv8_cp15_regs,
7506c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier		.num = ARRAY_SIZE(genericv8_cp15_regs),
7606c7654d2fb8bac7b1af4340ad59434a5d89b86aMarc Zyngier	},
77b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier};
78b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
79b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngierstatic int __init sys_reg_genericv8_init(void)
80b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier{
81b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	unsigned int i;
82b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
83b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	for (i = 1; i < ARRAY_SIZE(genericv8_sys_regs); i++)
84b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier		BUG_ON(cmp_sys_reg(&genericv8_sys_regs[i-1],
85b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier			       &genericv8_sys_regs[i]) >= 0);
86b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier
87b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_AEM_V8,
88b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier					  &genericv8_target_table);
89b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_FOUNDATION_V8,
90b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier					  &genericv8_target_table);
911252b3313642c3d0dff5b951b625468bf0dcd059Marc Zyngier	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A53,
921252b3313642c3d0dff5b951b625468bf0dcd059Marc Zyngier					  &genericv8_target_table);
93b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_CORTEX_A57,
94b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier					  &genericv8_target_table);
95e28100bd8ed9e37b7cd4578140a1e7f95bd40835Anup Patel	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_XGENE_POTENZA,
96e28100bd8ed9e37b7cd4578140a1e7f95bd40835Anup Patel					  &genericv8_target_table);
97e28100bd8ed9e37b7cd4578140a1e7f95bd40835Anup Patel
98b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier	return 0;
99b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngier}
100b990a9d3152bddca62cc1f8bf80518430b98737bMarc Zyngierlate_initcall(sys_reg_genericv8_init);
101