blob: 9cb2fe17cf3af2ee170af0277e9ecd806ba2db07 [file] [log] [blame]
Christoffer Dall749cf76c2013-01-20 18:28:06 -05001/*
2 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
3 * Author: Christoffer Dall <c.dall@virtualopensystems.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#ifndef __ARM_KVM_EMULATE_H__
20#define __ARM_KVM_EMULATE_H__
21
22#include <linux/kvm_host.h>
23#include <asm/kvm_asm.h>
Christoffer Dall45e96ea2013-01-20 18:43:58 -050024#include <asm/kvm_mmio.h>
Marc Zyngier7393b592012-09-17 19:27:09 +010025#include <asm/kvm_arm.h>
Christoffer Dall749cf76c2013-01-20 18:28:06 -050026
Marc Zyngierdb730d82012-10-03 11:17:02 +010027unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
28unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
Christoffer Dall749cf76c2013-01-20 18:28:06 -050029
Christoffer Dall5b3e5e52013-01-20 18:28:09 -050030int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run);
Marc Zyngierc5997562012-12-08 18:13:18 +000031bool kvm_condition_valid(struct kvm_vcpu *vcpu);
Christoffer Dall5b3e5e52013-01-20 18:28:09 -050032void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr);
33void kvm_inject_undefined(struct kvm_vcpu *vcpu);
34void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
35void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
36
Marc Zyngieraa024c22013-01-20 18:28:13 -050037static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
38{
39 return 1;
40}
41
Marc Zyngierdb730d82012-10-03 11:17:02 +010042static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
Christoffer Dall749cf76c2013-01-20 18:28:06 -050043{
Marc Zyngierdb730d82012-10-03 11:17:02 +010044 return &vcpu->arch.regs.usr_regs.ARM_pc;
Christoffer Dall749cf76c2013-01-20 18:28:06 -050045}
46
Marc Zyngierdb730d82012-10-03 11:17:02 +010047static inline unsigned long *vcpu_cpsr(struct kvm_vcpu *vcpu)
Christoffer Dall749cf76c2013-01-20 18:28:06 -050048{
Marc Zyngierdb730d82012-10-03 11:17:02 +010049 return &vcpu->arch.regs.usr_regs.ARM_cpsr;
Christoffer Dall749cf76c2013-01-20 18:28:06 -050050}
51
Marc Zyngieraa024c22013-01-20 18:28:13 -050052static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
53{
54 *vcpu_cpsr(vcpu) |= PSR_T_BIT;
55}
56
Christoffer Dall749cf76c2013-01-20 18:28:06 -050057static inline bool mode_has_spsr(struct kvm_vcpu *vcpu)
58{
59 unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
60 return (cpsr_mode > USR_MODE && cpsr_mode < SYSTEM_MODE);
61}
62
63static inline bool vcpu_mode_priv(struct kvm_vcpu *vcpu)
64{
65 unsigned long cpsr_mode = vcpu->arch.regs.usr_regs.ARM_cpsr & MODE_MASK;
66 return cpsr_mode > USR_MODE;;
67}
68
Christoffer Dall45e96ea2013-01-20 18:43:58 -050069static inline bool kvm_vcpu_reg_is_pc(struct kvm_vcpu *vcpu, int reg)
70{
71 return reg == 15;
72}
73
Marc Zyngier7393b592012-09-17 19:27:09 +010074static inline u32 kvm_vcpu_get_hsr(struct kvm_vcpu *vcpu)
75{
76 return vcpu->arch.fault.hsr;
77}
78
79static inline unsigned long kvm_vcpu_get_hfar(struct kvm_vcpu *vcpu)
80{
81 return vcpu->arch.fault.hxfar;
82}
83
84static inline phys_addr_t kvm_vcpu_get_fault_ipa(struct kvm_vcpu *vcpu)
85{
86 return ((phys_addr_t)vcpu->arch.fault.hpfar & HPFAR_MASK) << 8;
87}
88
89static inline unsigned long kvm_vcpu_get_hyp_pc(struct kvm_vcpu *vcpu)
90{
91 return vcpu->arch.fault.hyp_pc;
92}
93
Marc Zyngier4a1df282012-09-18 11:06:23 +010094static inline bool kvm_vcpu_dabt_isvalid(struct kvm_vcpu *vcpu)
95{
96 return kvm_vcpu_get_hsr(vcpu) & HSR_ISV;
97}
98
Marc Zyngier023cc962012-09-18 11:12:26 +010099static inline bool kvm_vcpu_dabt_iswrite(struct kvm_vcpu *vcpu)
100{
101 return kvm_vcpu_get_hsr(vcpu) & HSR_WNR;
102}
103
Marc Zyngier7c511b82012-09-18 11:23:02 +0100104static inline bool kvm_vcpu_dabt_issext(struct kvm_vcpu *vcpu)
105{
106 return kvm_vcpu_get_hsr(vcpu) & HSR_SSE;
107}
108
Marc Zyngierd0adf742012-09-18 11:28:57 +0100109static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu)
110{
111 return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT;
112}
113
Marc Zyngier78abfcd2012-09-18 11:36:16 +0100114static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu)
115{
116 return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA;
117}
118
Marc Zyngierb37670b2012-09-18 11:37:28 +0100119static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu)
120{
121 return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW;
122}
123
Marc Zyngiera7123372012-09-18 11:43:30 +0100124/* Get Access Size from a data abort */
125static inline int kvm_vcpu_dabt_get_as(struct kvm_vcpu *vcpu)
126{
127 switch ((kvm_vcpu_get_hsr(vcpu) >> 22) & 0x3) {
128 case 0:
129 return 1;
130 case 1:
131 return 2;
132 case 2:
133 return 4;
134 default:
135 kvm_err("Hardware is weird: SAS 0b11 is reserved\n");
136 return -EFAULT;
137 }
138}
139
Marc Zyngier23b415d2012-09-18 12:07:06 +0100140/* This one is not specific to Data Abort */
141static inline bool kvm_vcpu_trap_il_is32bit(struct kvm_vcpu *vcpu)
142{
143 return kvm_vcpu_get_hsr(vcpu) & HSR_IL;
144}
145
Marc Zyngier4926d442012-09-18 14:09:58 +0100146static inline u8 kvm_vcpu_trap_get_class(struct kvm_vcpu *vcpu)
147{
148 return kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT;
149}
150
Marc Zyngier52d1dba2012-10-15 10:33:38 +0100151static inline bool kvm_vcpu_trap_is_iabt(struct kvm_vcpu *vcpu)
152{
153 return kvm_vcpu_trap_get_class(vcpu) == HSR_EC_IABT;
154}
155
Marc Zyngier1cc287d2012-09-18 14:14:35 +0100156static inline u8 kvm_vcpu_trap_get_fault(struct kvm_vcpu *vcpu)
157{
158 return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE;
159}
160
Christoffer Dallc088f8f2013-02-21 11:26:10 -0800161static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu)
162{
163 return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK;
164}
165
Christoffer Dall749cf76c2013-01-20 18:28:06 -0500166#endif /* __ARM_KVM_EMULATE_H__ */