9
#include <kernel/time/clock_source.h>
10
#include <kernel/irq.h>
11
#include <kernel/panic.h>
12
#include <xen/event_channel.h>
13
#include <xen_hypercall-x86_32.h>
15
#include <embox/unit.h>
21
extern shared_info_t xen_shared_info;
23
static int integratorcp_clock_setup(struct clock_source *cs) {
27
static struct time_event_device xen_event_device = {
28
.name = "xen event device",
29
.set_periodic = integratorcp_clock_setup,
33
static cycle_t xen_tcd_read(struct clock_source *cs) {
37
static struct time_counter_device xen_tcd = {
42
static uint64_t system_time;
44
static uint64_t xen_time(void) {
45
return xen_shared_info.vcpu_info[0].time.system_time;
48
static irq_return_t clock_handler(unsigned int irq_nr, void *dev_id) {
49
uint64_t time = xen_time();
51
const int n = (time - system_time) / NSEC_PER_MSEC;
52
for (int i = 0; i < n; i++) {
53
clock_tick_handler(dev_id);
59
static int xen_clock_init(struct clock_source *cs) {
61
evtchn_bind_virq_t op;
65
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op) != 0) {
66
panic("Error has happened during timer initialization.\n");
68
xen_event_device.irq_nr = op.port;
70
system_time = xen_time();
72
return irq_attach(op.port, clock_handler, 0, cs, "xen clock irq");
75
CLOCK_SOURCE_DEF(xen, xen_clock_init, NULL,
76
&xen_event_device, &xen_tcd);