Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Copyright (C) 2012 ARM Ltd.
  4 * Author: Marc Zyngier <marc.zyngier@arm.com>
  5 */
  6
  7#ifndef __ASM_ARM_KVM_ARCH_TIMER_H
  8#define __ASM_ARM_KVM_ARCH_TIMER_H
  9
 10#include <linux/clocksource.h>
 11#include <linux/hrtimer.h>
 12
 13enum kvm_arch_timers {
 14	TIMER_PTIMER,
 15	TIMER_VTIMER,
 16	NR_KVM_EL0_TIMERS,
 17	TIMER_HVTIMER = NR_KVM_EL0_TIMERS,
 18	TIMER_HPTIMER,
 19	NR_KVM_TIMERS
 20};
 21
 22enum kvm_arch_timer_regs {
 23	TIMER_REG_CNT,
 24	TIMER_REG_CVAL,
 25	TIMER_REG_TVAL,
 26	TIMER_REG_CTL,
 27	TIMER_REG_VOFF,
 28};
 29
 30struct arch_timer_offset {
 31	/*
 32	 * If set, pointer to one of the offsets in the kvm's offset
 33	 * structure. If NULL, assume a zero offset.
 34	 */
 35	u64	*vm_offset;
 36	/*
 37	 * If set, pointer to one of the offsets in the vcpu's sysreg
 38	 * array. If NULL, assume a zero offset.
 39	 */
 40	u64	*vcpu_offset;
 41};
 42
 43struct arch_timer_vm_data {
 44	/* Offset applied to the virtual timer/counter */
 45	u64	voffset;
 46	/* Offset applied to the physical timer/counter */
 47	u64	poffset;
 48
 49	/* The PPI for each timer, global to the VM */
 50	u8	ppi[NR_KVM_TIMERS];
 51};
 52
 53struct arch_timer_context {
 54	struct kvm_vcpu			*vcpu;
 55
 56	/* Emulated Timer (may be unused) */
 57	struct hrtimer			hrtimer;
 58	u64				ns_frac;
 59
 60	/* Offset for this counter/timer */
 61	struct arch_timer_offset	offset;
 62	/*
 63	 * We have multiple paths which can save/restore the timer state onto
 64	 * the hardware, so we need some way of keeping track of where the
 65	 * latest state is.
 66	 */
 67	bool				loaded;
 68
 69	/* Output level of the timer IRQ */
 70	struct {
 71		bool			level;
 72	} irq;
 73
 74	/* Duplicated state from arch_timer.c for convenience */
 75	u32				host_timer_irq;
 76};
 77
 78struct timer_map {
 79	struct arch_timer_context *direct_vtimer;
 80	struct arch_timer_context *direct_ptimer;
 81	struct arch_timer_context *emul_vtimer;
 82	struct arch_timer_context *emul_ptimer;
 83};
 84
 85void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map);
 86
 87struct arch_timer_cpu {
 88	struct arch_timer_context timers[NR_KVM_TIMERS];
 89
 90	/* Background timer used when the guest is not running */
 91	struct hrtimer			bg_timer;
 92
 93	/* Is the timer enabled */
 94	bool			enabled;
 95};
 96
 97int __init kvm_timer_hyp_init(bool has_gic);
 98int kvm_timer_enable(struct kvm_vcpu *vcpu);
 99void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
100void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
101void kvm_timer_sync_user(struct kvm_vcpu *vcpu);
102bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
103void kvm_timer_update_run(struct kvm_vcpu *vcpu);
104void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu);
105
106void kvm_timer_init_vm(struct kvm *kvm);
107
108u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid);
109int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value);
110
111int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
112int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
113int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
114
115u64 kvm_phys_timer_read(void);
116
117void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
118void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
119
120void kvm_timer_init_vhe(void);
121
122#define vcpu_timer(v)	(&(v)->arch.timer_cpu)
123#define vcpu_get_timer(v,t)	(&vcpu_timer(v)->timers[(t)])
124#define vcpu_vtimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_VTIMER])
125#define vcpu_ptimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_PTIMER])
126#define vcpu_hvtimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_HVTIMER])
127#define vcpu_hptimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_HPTIMER])
128
129#define arch_timer_ctx_index(ctx)	((ctx) - vcpu_timer((ctx)->vcpu)->timers)
130
131#define timer_vm_data(ctx)		(&(ctx)->vcpu->kvm->arch.timer_data)
132#define timer_irq(ctx)			(timer_vm_data(ctx)->ppi[arch_timer_ctx_index(ctx)])
133
134u64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu,
135			      enum kvm_arch_timers tmr,
136			      enum kvm_arch_timer_regs treg);
137void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu,
138				enum kvm_arch_timers tmr,
139				enum kvm_arch_timer_regs treg,
140				u64 val);
141
142/* Needed for tracing */
143u32 timer_get_ctl(struct arch_timer_context *ctxt);
144u64 timer_get_cval(struct arch_timer_context *ctxt);
145
146/* CPU HP callbacks */
147void kvm_timer_cpu_up(void);
148void kvm_timer_cpu_down(void);
149
150static inline bool has_cntpoff(void)
151{
152	return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
153}
154
155#endif