Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/include/asm/hvm/vpt.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * vpt.h: Virtual Platform Timer definitions
3
 *
4
 * Copyright (c) 2004, Intel Corporation.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms and conditions of the GNU General Public License,
8
 * version 2, as published by the Free Software Foundation.
9
 *
10
 * This program is distributed in the hope it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13
 * more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along with
16
 * this program; If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#ifndef __ASM_X86_HVM_VPT_H__
20
#define __ASM_X86_HVM_VPT_H__
21
22
#include <xen/init.h>
23
#include <xen/lib.h>
24
#include <xen/time.h>
25
#include <xen/errno.h>
26
#include <xen/time.h>
27
#include <xen/timer.h>
28
#include <xen/list.h>
29
#include <asm/hvm/vpic.h>
30
#include <asm/hvm/irq.h>
31
#include <public/hvm/save.h>
32
33
/*
34
 * Abstract layer of periodic time, one short time.
35
 */
36
typedef void time_cb(struct vcpu *v, void *opaque);
37
38
struct periodic_time {
39
    struct list_head list;
40
    bool_t on_list;
41
    bool_t one_shot;
42
    bool_t do_not_freeze;
43
    bool_t irq_issued;
44
    bool_t warned_timeout_too_short;
45
0
#define PTSRC_isa    1 /* ISA time source */
46
18.4E
#define PTSRC_lapic  2 /* LAPIC time source */
47
    u8 source;                  /* PTSRC_ */
48
    u8 irq;
49
    struct vcpu *vcpu;          /* vcpu timer interrupt delivers to */
50
    u32 pending_intr_nr;        /* pending timer interrupts */
51
    u64 period;                 /* frequency in ns */
52
    s_time_t scheduled;         /* scheduled timer interrupt */
53
    u64 last_plt_gtime;         /* platform time when last IRQ is injected */
54
    struct timer timer;         /* ac_timer */
55
    time_cb *cb;
56
    void *priv;                 /* point back to platform time source */
57
};
58
59
60
0
#define PIT_FREQ 1193182
61
0
#define PIT_BASE 0x40
62
63
typedef struct PITState {
64
    /* Hardware state */
65
    struct hvm_hw_pit hw;
66
    /* Last time the counters read zero, for calcuating counter reads */
67
    int64_t count_load_time[3];
68
    /* Channel 0 IRQ handling. */
69
    struct periodic_time pt0;
70
    spinlock_t lock;
71
} PITState;
72
73
struct hpet_registers {
74
    /* Memory-mapped, software visible registers */
75
    uint64_t capability;        /* capabilities */
76
    uint64_t config;            /* configuration */
77
    uint64_t isr;               /* interrupt status reg */
78
    uint64_t mc64;              /* main counter */
79
    struct {                    /* timers */
80
        uint64_t config;        /* configuration/cap */
81
        uint64_t cmp;           /* comparator */
82
        uint64_t fsb;           /* FSB route, not supported now */
83
    } timers[HPET_TIMER_NUM];
84
85
    /* Hidden register state */
86
    uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
87
    uint64_t comparator64[HPET_TIMER_NUM]; /* 64 bit running comparator */
88
};
89
90
typedef struct HPETState {
91
    struct hpet_registers hpet;
92
    uint64_t stime_freq;
93
    uint64_t hpet_to_ns_scale; /* hpet ticks to ns (multiplied by 2^10) */
94
    uint64_t hpet_to_ns_limit; /* max hpet ticks convertable to ns      */
95
    uint64_t mc_offset;
96
    struct periodic_time pt[HPET_TIMER_NUM];
97
    rwlock_t lock;
98
} HPETState;
99
100
typedef struct RTCState {
101
    /* Hardware state */
102
    struct hvm_hw_rtc hw;
103
    /* RTC's idea of the current time */
104
    struct tm current_tm;
105
    /* update-ended timer */
106
    struct timer update_timer;
107
    struct timer update_timer2;
108
    uint64_t next_update_time;
109
    /* alarm timer */
110
    struct timer alarm_timer;
111
    /* periodic timer */
112
    struct periodic_time pt;
113
    s_time_t start_time;
114
    s_time_t check_ticks_since;
115
    int period;
116
    uint8_t pt_dead_ticks;
117
    uint32_t use_timer;
118
    spinlock_t lock;
119
} RTCState;
120
121
0
#define FREQUENCE_PMTIMER  3579545  /* Timer should run at 3.579545 MHz */
122
typedef struct PMTState {
123
    struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
124
    uint64_t last_gtime;        /* Last (guest) time we updated the timer */
125
    uint32_t not_accounted;     /* time not accounted at last update */
126
    uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
127
    struct timer timer;         /* To make sure we send SCIs */
128
    spinlock_t lock;
129
} PMTState;
130
131
struct pl_time {    /* platform time */
132
    struct RTCState  vrtc;
133
    struct HPETState vhpet;
134
    struct PMTState  vpmt;
135
    /* guest_time = Xen sys time + stime_offset */
136
    int64_t stime_offset;
137
    /* Ensures monotonicity in appropriate timer modes. */
138
    uint64_t last_guest_time;
139
    spinlock_t pl_time_lock;
140
    struct domain *domain;
141
};
142
143
void pt_save_timer(struct vcpu *v);
144
void pt_restore_timer(struct vcpu *v);
145
int pt_update_irq(struct vcpu *v);
146
void pt_intr_post(struct vcpu *v, struct hvm_intack intack);
147
void pt_migrate(struct vcpu *v);
148
149
void pt_adjust_global_vcpu_target(struct vcpu *v);
150
#define pt_global_vcpu_target(d) \
151
0
    (is_hvm_domain(d) && (d)->arch.hvm_domain.i8259_target ? \
152
0
     (d)->arch.hvm_domain.i8259_target : \
153
0
     (d)->vcpu ? (d)->vcpu[0] : NULL)
154
155
void pt_may_unmask_irq(struct domain *d, struct periodic_time *vlapic_pt);
156
157
/* Is given periodic timer active? */
158
0
#define pt_active(pt) ((pt)->on_list || (pt)->pending_intr_nr)
159
160
/*
161
 * Create/destroy a periodic (or one-shot!) timer.
162
 * The given periodic timer structure must be initialised with zero bytes,
163
 * except for the 'source' field which must be initialised with the
164
 * correct PTSRC_ value. The initialised timer structure can then be passed
165
 * to {create,destroy}_periodic_time() any number of times and in any order.
166
 * Note that, for a given periodic timer, invocations of these functions MUST
167
 * be serialised.
168
 */
169
void create_periodic_time(
170
    struct vcpu *v, struct periodic_time *pt, uint64_t delta,
171
    uint64_t period, uint8_t irq, time_cb *cb, void *data);
172
void destroy_periodic_time(struct periodic_time *pt);
173
174
int pv_pit_handler(int port, int data, int write);
175
void pit_reset(struct domain *d);
176
177
void pit_init(struct domain *d, unsigned long cpu_khz);
178
void pit_stop_channel0_irq(PITState * pit);
179
void pit_deinit(struct domain *d);
180
void rtc_init(struct domain *d);
181
void rtc_migrate_timers(struct vcpu *v);
182
void rtc_deinit(struct domain *d);
183
void rtc_reset(struct domain *d);
184
void rtc_update_clock(struct domain *d);
185
186
void pmtimer_init(struct vcpu *v);
187
void pmtimer_deinit(struct domain *d);
188
void pmtimer_reset(struct domain *d);
189
int pmtimer_change_ioport(struct domain *d, unsigned int version);
190
191
void hpet_init(struct domain *d);
192
void hpet_deinit(struct domain *d);
193
void hpet_reset(struct domain *d);
194
195
#endif /* __ASM_X86_HVM_VPT_H__ */