/*
 * Copyright (C) 2012-2015 - ARM Ltd
 * Author: Marc Zyngier <marc.zyngier@arm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/compiler.h>
#include <linux/irqchip/arm-gic-v3.h>
#include <linux/kvm_host.h>

#include <asm/kvm_mmu.h>

#include "hyp.h"

#define vtr_to_max_lr_idx(v)		((v) & 0xf)
#define vtr_to_nr_pri_bits(v)		(((u32)(v) >> 29) + 1)

#define read_gicreg(r)							\
	({								\
		u64 reg;						\
		asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg));	\
		reg;							\
	})

#define write_gicreg(v,r)						\
	do {								\
		u64 __val = (v);					\
		asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
	} while (0)

/* vcpu is already in the HYP VA space */
void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
{
	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
	u64 val;
	u32 max_lr_idx, nr_pri_bits;

	/*
	 * Make sure stores to the GIC via the memory mapped interface
	 * are now visible to the system register interface.
	 */
	dsb(st);

	cpu_if->vgic_vmcr  = read_gicreg(ICH_VMCR_EL2);
	cpu_if->vgic_misr  = read_gicreg(ICH_MISR_EL2);
	cpu_if->vgic_eisr  = read_gicreg(ICH_EISR_EL2);
	cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2);

	write_gicreg(0, ICH_HCR_EL2);
	val = read_gicreg(ICH_VTR_EL2);
	max_lr_idx = vtr_to_max_lr_idx(val);
	nr_pri_bits = vtr_to_nr_pri_bits(val);

	switch (max_lr_idx) {
	case 15:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(15)] = read_gicreg(ICH_LR15_EL2);
	case 14:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(14)] = read_gicreg(ICH_LR14_EL2);
	case 13:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(13)] = read_gicreg(ICH_LR13_EL2);
	case 12:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(12)] = read_gicreg(ICH_LR12_EL2);
	case 11:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(11)] = read_gicreg(ICH_LR11_EL2);
	case 10:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(10)] = read_gicreg(ICH_LR10_EL2);
	case 9:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(9)] = read_gicreg(ICH_LR9_EL2);
	case 8:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(8)] = read_gicreg(ICH_LR8_EL2);
	case 7:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(7)] = read_gicreg(ICH_LR7_EL2);
	case 6:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(6)] = read_gicreg(ICH_LR6_EL2);
	case 5:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(5)] = read_gicreg(ICH_LR5_EL2);
	case 4:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(4)] = read_gicreg(ICH_LR4_EL2);
	case 3:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(3)] = read_gicreg(ICH_LR3_EL2);
	case 2:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(2)] = read_gicreg(ICH_LR2_EL2);
	case 1:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(1)] = read_gicreg(ICH_LR1_EL2);
	case 0:
		cpu_if->vgic_lr[VGIC_V3_LR_INDEX(0)] = read_gicreg(ICH_LR0_EL2);
	}

	switch (nr_pri_bits) {
	case 7:
		cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2);
		cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2);
	case 6:
		cpu_if->vgic_ap0r[1] = read_gicreg(ICH_AP0R1_EL2);
	default:
		cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2);
	}

	switch (nr_pri_bits) {
	case 7:
		cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2);
		cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2);
	case 6:
		cpu_if->vgic_ap1r[1] = read_gicreg(ICH_AP1R1_EL2);
	default:
		cpu_if->vgic_ap1r[0] = read_gicreg(ICH_AP1R0_EL2);
	}

	val = read_gicreg(ICC_SRE_EL2);
	write_gicreg(val | ICC_SRE_EL2_ENABLE, ICC_SRE_EL2);
	isb(); /* Make sure ENABLE is set at EL2 before setting SRE at EL1 */
	write_gicreg(1, ICC_SRE_EL1);
}

void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
{
	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
	u64 val;
	u32 max_lr_idx, nr_pri_bits;

	/*
	 * VFIQEn is RES1 if ICC_SRE_EL1.SRE is 1. This causes a
	 * Group0 interrupt (as generated in GICv2 mode) to be
	 * delivered as a FIQ to the guest, with potentially fatal
	 * consequences. So we must make sure that ICC_SRE_EL1 has
	 * been actually programmed with the value we want before
	 * starting to mess with the rest of the GIC.
	 */
	write_gicreg(cpu_if->vgic_sre, ICC_SRE_EL1);
	isb();

	write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2);
	write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2);

	val = read_gicreg(ICH_VTR_EL2);
	max_lr_idx = vtr_to_max_lr_idx(val);
	nr_pri_bits = vtr_to_nr_pri_bits(val);

	switch (nr_pri_bits) {
	case 7:
		 write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2);
		 write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2);
	case 6:
		 write_gicreg(cpu_if->vgic_ap0r[1], ICH_AP0R1_EL2);
	default:
		 write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2);
	}

	switch (nr_pri_bits) {
	case 7:
		 write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2);
		 write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2);
	case 6:
		 write_gicreg(cpu_if->vgic_ap1r[1], ICH_AP1R1_EL2);
	default:
		 write_gicreg(cpu_if->vgic_ap1r[0], ICH_AP1R0_EL2);
	}

	switch (max_lr_idx) {
	case 15:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(15)], ICH_LR15_EL2);
	case 14:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(14)], ICH_LR14_EL2);
	case 13:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(13)], ICH_LR13_EL2);
	case 12:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(12)], ICH_LR12_EL2);
	case 11:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(11)], ICH_LR11_EL2);
	case 10:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(10)], ICH_LR10_EL2);
	case 9:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(9)], ICH_LR9_EL2);
	case 8:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(8)], ICH_LR8_EL2);
	case 7:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(7)], ICH_LR7_EL2);
	case 6:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(6)], ICH_LR6_EL2);
	case 5:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(5)], ICH_LR5_EL2);
	case 4:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(4)], ICH_LR4_EL2);
	case 3:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(3)], ICH_LR3_EL2);
	case 2:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(2)], ICH_LR2_EL2);
	case 1:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(1)], ICH_LR1_EL2);
	case 0:
		write_gicreg(cpu_if->vgic_lr[VGIC_V3_LR_INDEX(0)], ICH_LR0_EL2);
	}

	/*
	 * Ensures that the above will have reached the
	 * (re)distributors. This ensure the guest will read the
	 * correct values from the memory-mapped interface.
	 */
	isb();
	dsb(sy);

	/*
	 * Prevent the guest from touching the GIC system registers if
	 * SRE isn't enabled for GICv3 emulation.
	 */
	if (!cpu_if->vgic_sre) {
		write_gicreg(read_gicreg(ICC_SRE_EL2) & ~ICC_SRE_EL2_ENABLE,
			     ICC_SRE_EL2);
	}
}

static u64 __hyp_text __vgic_v3_read_ich_vtr_el2(void)
{
	return read_gicreg(ICH_VTR_EL2);
}

__alias(__vgic_v3_read_ich_vtr_el2) u64 __vgic_v3_get_ich_vtr_el2(void);
