Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/riscv/iommu/iommu_fdt.c
282995 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2026 Ruslan Bukin <[email protected]>
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/types.h>
29
#include <sys/systm.h>
30
#include <sys/bus.h>
31
#include <sys/bitstring.h>
32
#include <sys/kernel.h>
33
#include <sys/rman.h>
34
#include <sys/sysctl.h>
35
#include <sys/tree.h>
36
#include <sys/taskqueue.h>
37
#include <sys/malloc.h>
38
#include <sys/module.h>
39
#include <vm/vm.h>
40
#include <vm/pmap.h>
41
42
#include <sys/bus.h>
43
#include <sys/conf.h>
44
#include <sys/rman.h>
45
46
#include <machine/bus.h>
47
#include <machine/resource.h>
48
49
#include <dev/ofw/ofw_bus.h>
50
#include <dev/ofw/ofw_bus_subr.h>
51
52
#include <dev/iommu/iommu.h>
53
#include <riscv/iommu/iommu_pmap.h>
54
#include <riscv/iommu/iommu.h>
55
#include <riscv/iommu/iommu_frontend.h>
56
57
static struct ofw_compat_data compat_data[] = {
58
{ "riscv,iommu", 1 },
59
{ NULL, 0 }
60
};
61
62
static struct resource_spec riscv_iommu_spec[] = {
63
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
64
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* CQ */
65
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* FQ */
66
{ SYS_RES_IRQ, 2, RF_ACTIVE }, /* PM */
67
{ SYS_RES_IRQ, 3, RF_ACTIVE }, /* PQ */
68
RESOURCE_SPEC_END
69
};
70
71
static int
72
riscv_iommu_fdt_probe(device_t dev)
73
{
74
if (!ofw_bus_status_okay(dev))
75
return (ENXIO);
76
77
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
78
return (ENXIO);
79
80
device_set_desc(dev, "RISC-V IOMMU");
81
82
return (BUS_PROBE_DEFAULT);
83
}
84
85
static int
86
riscv_iommu_fdt_attach(device_t dev)
87
{
88
struct riscv_iommu_softc *sc;
89
struct riscv_iommu_unit *unit;
90
struct iommu_unit *iommu;
91
phandle_t node;
92
int error;
93
94
sc = device_get_softc(dev);
95
sc->dev = dev;
96
97
node = ofw_bus_get_node(dev);
98
99
error = bus_alloc_resources(dev, riscv_iommu_spec, sc->res);
100
if (error) {
101
device_printf(dev, "could not allocate resources\n");
102
goto error;
103
}
104
105
error = riscv_iommu_attach(dev);
106
if (error != 0) {
107
device_printf(dev, "Failed to attach. Error %d\n", error);
108
goto error;
109
}
110
111
unit = &sc->unit;
112
unit->dev = dev;
113
114
iommu = &unit->iommu;
115
iommu->dev = dev;
116
117
LIST_INIT(&unit->domain_list);
118
119
sc->xref = OF_xref_from_node(node);
120
121
error = iommu_register(iommu);
122
if (error) {
123
device_printf(dev, "Failed to register RISC-V IOMMU.\n");
124
goto error;
125
}
126
127
return (0);
128
129
error:
130
bus_release_resources(dev, riscv_iommu_spec, sc->res);
131
132
return (error);
133
}
134
135
static device_method_t riscv_iommu_fdt_methods[] = {
136
/* Device interface */
137
DEVMETHOD(device_probe, riscv_iommu_fdt_probe),
138
DEVMETHOD(device_attach, riscv_iommu_fdt_attach),
139
DEVMETHOD_END
140
};
141
142
DEFINE_CLASS_1(riscv_iommu, riscv_iommu_fdt_driver, riscv_iommu_fdt_methods,
143
sizeof(struct riscv_iommu_softc), riscv_iommu_driver);
144
EARLY_DRIVER_MODULE(riscv_iommu, simplebus, riscv_iommu_fdt_driver, 0, 0,
145
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
146
147