Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/riscv/vmm/vmm_vtimer.c
105420 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2024 Ruslan Bukin <[email protected]>
5
*
6
* This software was developed by the University of Cambridge Computer
7
* Laboratory (Department of Computer Science and Technology) under Innovate
8
* UK project 105694, "Digital Security by Design (DSbD) Technology Platform
9
* Prototype".
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
13
* are met:
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
*
20
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
24
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
* SUCH DAMAGE.
31
*/
32
33
#include <sys/param.h>
34
#include <sys/kernel.h>
35
#include <sys/lock.h>
36
#include <sys/mutex.h>
37
38
#include <dev/ofw/ofw_bus.h>
39
#include <dev/ofw/ofw_bus_subr.h>
40
#include <dev/ofw/openfirm.h>
41
42
#include <dev/vmm/vmm_vm.h>
43
44
#include "riscv.h"
45
46
#define VTIMER_DEFAULT_FREQ 1000000
47
48
static int
49
vtimer_get_timebase(uint32_t *freq)
50
{
51
phandle_t node;
52
int len;
53
54
node = OF_finddevice("/cpus");
55
if (node == -1)
56
return (ENXIO);
57
58
len = OF_getproplen(node, "timebase-frequency");
59
if (len != 4)
60
return (ENXIO);
61
62
OF_getencprop(node, "timebase-frequency", freq, len);
63
64
return (0);
65
}
66
67
void
68
vtimer_cpuinit(struct hypctx *hypctx)
69
{
70
struct vtimer *vtimer;
71
uint32_t freq;
72
int error;
73
74
vtimer = &hypctx->vtimer;
75
mtx_init(&vtimer->mtx, "vtimer callout mutex", NULL, MTX_DEF);
76
callout_init_mtx(&vtimer->callout, &vtimer->mtx, 0);
77
78
error = vtimer_get_timebase(&freq);
79
if (error)
80
freq = VTIMER_DEFAULT_FREQ;
81
82
vtimer->freq = freq;
83
}
84
85
static void
86
vtimer_inject_irq_callout(void *arg)
87
{
88
struct hypctx *hypctx;
89
struct hyp *hyp;
90
91
hypctx = arg;
92
hyp = hypctx->hyp;
93
94
atomic_set_32(&hypctx->interrupts_pending, HVIP_VSTIP);
95
vcpu_notify_event(vm_vcpu(hyp->vm, hypctx->cpu_id));
96
}
97
98
int
99
vtimer_set_timer(struct hypctx *hypctx, uint64_t next_val)
100
{
101
struct vtimer *vtimer;
102
sbintime_t time;
103
uint64_t curtime;
104
uint64_t delta;
105
106
vtimer = &hypctx->vtimer;
107
108
curtime = rdtime();
109
if (curtime < next_val) {
110
delta = next_val - curtime;
111
time = delta * SBT_1S / vtimer->freq;
112
atomic_clear_32(&hypctx->interrupts_pending, HVIP_VSTIP);
113
callout_reset_sbt(&vtimer->callout, time, 0,
114
vtimer_inject_irq_callout, hypctx, 0);
115
} else
116
atomic_set_32(&hypctx->interrupts_pending, HVIP_VSTIP);
117
118
return (0);
119
}
120
121