1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2019-2020 Ruslan Bukin <br@bsdpad.com>
5 *
6 * This software was developed by SRI International and the University of
7 * Cambridge Computer Laboratory (Department of Computer Science and
8 * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
9 * DARPA SSITH research programme.
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 THE 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 THE 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 * $FreeBSD$
33 */
34
35#ifndef	_ARM64_IOMMU_SMMUVAR_H_
36#define	_ARM64_IOMMU_SMMUVAR_H_
37
38#define	SMMU_DEVSTR		"ARM System Memory Management Unit"
39#define	SMMU_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
40#define	SMMU_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
41
42DECLARE_CLASS(smmu_driver);
43
44struct smmu_unit {
45	struct iommu_unit		iommu;
46	LIST_HEAD(, smmu_domain)	domain_list;
47	LIST_ENTRY(smmu_unit)		next;
48	device_t			dev;
49	intptr_t			xref;
50};
51
52struct smmu_domain {
53	struct iommu_domain		iodom;
54	LIST_HEAD(, smmu_ctx)		ctx_list;
55	LIST_ENTRY(smmu_domain)	next;
56	u_int entries_cnt;
57	struct smmu_cd			*cd;
58	struct pmap			p;
59	uint16_t			asid;
60};
61
62struct smmu_ctx {
63	struct iommu_ctx		ioctx;
64	struct smmu_domain		*domain;
65	LIST_ENTRY(smmu_ctx)		next;
66	device_t			dev;
67	bool				bypass;
68	int				sid;
69	uint16_t			vendor;
70	uint16_t			device;
71};
72
73struct smmu_queue_local_copy {
74	union {
75		uint64_t val;
76		struct {
77			uint32_t prod;
78			uint32_t cons;
79		};
80	};
81};
82
83struct smmu_cd {
84	vm_paddr_t paddr;
85	vm_size_t size;
86	void *vaddr;
87};
88
89struct smmu_queue {
90	struct smmu_queue_local_copy lc;
91	vm_paddr_t paddr;
92	void *vaddr;
93	uint32_t prod_off;
94	uint32_t cons_off;
95	int size_log2;
96	uint64_t base;
97};
98
99struct smmu_cmdq_entry {
100	uint8_t opcode;
101	union {
102		struct {
103			uint16_t asid;
104			uint16_t vmid;
105			vm_offset_t addr;
106			bool leaf;
107		} tlbi;
108		struct {
109			uint32_t sid;
110			uint32_t ssid;
111			bool leaf;
112		} cfgi;
113		struct {
114			uint32_t sid;
115		} prefetch;
116		struct {
117			uint64_t msiaddr;
118		} sync;
119	};
120};
121
122struct l1_desc {
123	uint8_t		span;
124	size_t		size;
125	void		*va;
126	vm_paddr_t	pa;
127};
128
129struct smmu_strtab {
130	void		*vaddr;
131	uint64_t	base;
132	uint32_t	base_cfg;
133	uint32_t	num_l1_entries;
134	struct l1_desc	*l1;
135};
136
137struct smmu_softc {
138	device_t		dev;
139	struct resource		*res[4];
140	void			*intr_cookie[3];
141	uint32_t		ias; /* Intermediate Physical Address */
142	uint32_t		oas; /* Physical Address */
143	uint32_t		asid_bits;
144	uint32_t		vmid_bits;
145	uint32_t		sid_bits;
146	uint32_t		ssid_bits;
147	uint32_t		pgsizes;
148	uint32_t		features;
149#define	SMMU_FEATURE_2_LVL_STREAM_TABLE		(1 << 0)
150#define	SMMU_FEATURE_2_LVL_CD			(1 << 1)
151#define	SMMU_FEATURE_TT_LE			(1 << 2)
152#define	SMMU_FEATURE_TT_BE			(1 << 3)
153#define	SMMU_FEATURE_SEV			(1 << 4)
154#define	SMMU_FEATURE_MSI			(1 << 5)
155#define	SMMU_FEATURE_HYP			(1 << 6)
156#define	SMMU_FEATURE_ATS			(1 << 7)
157#define	SMMU_FEATURE_PRI			(1 << 8)
158#define	SMMU_FEATURE_STALL_FORCE		(1 << 9)
159#define	SMMU_FEATURE_STALL			(1 << 10)
160#define	SMMU_FEATURE_S1P			(1 << 11)
161#define	SMMU_FEATURE_S2P			(1 << 12)
162#define	SMMU_FEATURE_VAX			(1 << 13)
163#define	SMMU_FEATURE_COHERENCY			(1 << 14)
164#define	SMMU_FEATURE_RANGE_INV			(1 << 15)
165	struct smmu_queue cmdq;
166	struct smmu_queue evtq;
167	struct smmu_queue priq;
168	struct smmu_strtab strtab;
169	int				sync;
170	struct mtx			sc_mtx;
171	bitstr_t			*asid_set;
172	int				asid_set_size;
173	struct mtx			asid_set_mutex;
174	struct smmu_unit		unit;
175	uintptr_t			xref;
176};
177
178MALLOC_DECLARE(M_SMMU);
179
180/* Device methods */
181int smmu_attach(device_t dev);
182int smmu_detach(device_t dev);
183
184struct smmu_ctx *smmu_ctx_lookup_by_sid(device_t dev, u_int sid);
185bool smmu_quirks_check(device_t dev, u_int sid, uint8_t event_id,
186    uintptr_t input_addr);
187
188#endif /* _ARM64_IOMMU_SMMUVAR_H_ */
189