xref: /freebsd/sys/arm64/iommu/smmuvar.h (revision d1bdc2821fcd416ab9b238580386eb605a6128d0)
14cc87010SRuslan Bukin /*-
24cc87010SRuslan Bukin  * SPDX-License-Identifier: BSD-2-Clause
34cc87010SRuslan Bukin  *
44cc87010SRuslan Bukin  * Copyright (c) 2019-2020 Ruslan Bukin <br@bsdpad.com>
54cc87010SRuslan Bukin  *
64cc87010SRuslan Bukin  * This software was developed by SRI International and the University of
74cc87010SRuslan Bukin  * Cambridge Computer Laboratory (Department of Computer Science and
84cc87010SRuslan Bukin  * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
94cc87010SRuslan Bukin  * DARPA SSITH research programme.
104cc87010SRuslan Bukin  *
114cc87010SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
124cc87010SRuslan Bukin  * modification, are permitted provided that the following conditions
134cc87010SRuslan Bukin  * are met:
144cc87010SRuslan Bukin  * 1. Redistributions of source code must retain the above copyright
154cc87010SRuslan Bukin  *    notice, this list of conditions and the following disclaimer.
164cc87010SRuslan Bukin  * 2. Redistributions in binary form must reproduce the above copyright
174cc87010SRuslan Bukin  *    notice, this list of conditions and the following disclaimer in the
184cc87010SRuslan Bukin  *    documentation and/or other materials provided with the distribution.
194cc87010SRuslan Bukin  *
204cc87010SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
214cc87010SRuslan Bukin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224cc87010SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234cc87010SRuslan Bukin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
244cc87010SRuslan Bukin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254cc87010SRuslan Bukin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264cc87010SRuslan Bukin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274cc87010SRuslan Bukin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284cc87010SRuslan Bukin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294cc87010SRuslan Bukin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304cc87010SRuslan Bukin  * SUCH DAMAGE.
314cc87010SRuslan Bukin  */
324cc87010SRuslan Bukin 
334cc87010SRuslan Bukin #ifndef	_ARM64_IOMMU_SMMUVAR_H_
344cc87010SRuslan Bukin #define	_ARM64_IOMMU_SMMUVAR_H_
354cc87010SRuslan Bukin 
36*b97e94d9SAndrew Turner #include <arm64/iommu/iommu_pmap.h>
37*b97e94d9SAndrew Turner 
384cc87010SRuslan Bukin #define	SMMU_DEVSTR		"ARM System Memory Management Unit"
394cc87010SRuslan Bukin #define	SMMU_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
404cc87010SRuslan Bukin #define	SMMU_UNLOCK(_sc)	mtx_unlock(&(_sc)->sc_mtx)
414cc87010SRuslan Bukin 
424cc87010SRuslan Bukin DECLARE_CLASS(smmu_driver);
434cc87010SRuslan Bukin 
444cc87010SRuslan Bukin struct smmu_unit {
454cc87010SRuslan Bukin 	struct iommu_unit		iommu;
464cc87010SRuslan Bukin 	LIST_HEAD(, smmu_domain)	domain_list;
474cc87010SRuslan Bukin 	LIST_ENTRY(smmu_unit)		next;
484cc87010SRuslan Bukin 	device_t			dev;
494cc87010SRuslan Bukin 	intptr_t			xref;
504cc87010SRuslan Bukin };
514cc87010SRuslan Bukin 
524cc87010SRuslan Bukin struct smmu_domain {
534cc87010SRuslan Bukin 	struct iommu_domain		iodom;
544cc87010SRuslan Bukin 	LIST_HEAD(, smmu_ctx)		ctx_list;
554cc87010SRuslan Bukin 	LIST_ENTRY(smmu_domain)	next;
564cc87010SRuslan Bukin 	u_int entries_cnt;
574cc87010SRuslan Bukin 	struct smmu_cd			*cd;
58*b97e94d9SAndrew Turner 	struct smmu_pmap		p;
594cc87010SRuslan Bukin 	uint16_t			asid;
604cc87010SRuslan Bukin };
614cc87010SRuslan Bukin 
624cc87010SRuslan Bukin struct smmu_ctx {
634cc87010SRuslan Bukin 	struct iommu_ctx		ioctx;
644cc87010SRuslan Bukin 	struct smmu_domain		*domain;
654cc87010SRuslan Bukin 	LIST_ENTRY(smmu_ctx)		next;
664cc87010SRuslan Bukin 	device_t			dev;
674cc87010SRuslan Bukin 	bool				bypass;
684cc87010SRuslan Bukin 	int				sid;
694cc87010SRuslan Bukin 	uint16_t			vendor;
704cc87010SRuslan Bukin 	uint16_t			device;
714cc87010SRuslan Bukin };
724cc87010SRuslan Bukin 
734cc87010SRuslan Bukin struct smmu_queue_local_copy {
744cc87010SRuslan Bukin 	union {
754cc87010SRuslan Bukin 		uint64_t val;
764cc87010SRuslan Bukin 		struct {
774cc87010SRuslan Bukin 			uint32_t prod;
784cc87010SRuslan Bukin 			uint32_t cons;
794cc87010SRuslan Bukin 		};
804cc87010SRuslan Bukin 	};
814cc87010SRuslan Bukin };
824cc87010SRuslan Bukin 
834cc87010SRuslan Bukin struct smmu_cd {
844cc87010SRuslan Bukin 	vm_paddr_t paddr;
854cc87010SRuslan Bukin 	void *vaddr;
864cc87010SRuslan Bukin };
874cc87010SRuslan Bukin 
884cc87010SRuslan Bukin struct smmu_queue {
894cc87010SRuslan Bukin 	struct smmu_queue_local_copy lc;
904cc87010SRuslan Bukin 	vm_paddr_t paddr;
914cc87010SRuslan Bukin 	void *vaddr;
924cc87010SRuslan Bukin 	uint32_t prod_off;
934cc87010SRuslan Bukin 	uint32_t cons_off;
944cc87010SRuslan Bukin 	int size_log2;
954cc87010SRuslan Bukin 	uint64_t base;
964cc87010SRuslan Bukin };
974cc87010SRuslan Bukin 
984cc87010SRuslan Bukin struct smmu_cmdq_entry {
994cc87010SRuslan Bukin 	uint8_t opcode;
1004cc87010SRuslan Bukin 	union {
1014cc87010SRuslan Bukin 		struct {
1024cc87010SRuslan Bukin 			uint16_t asid;
1034cc87010SRuslan Bukin 			uint16_t vmid;
1044cc87010SRuslan Bukin 			vm_offset_t addr;
1054cc87010SRuslan Bukin 			bool leaf;
1064cc87010SRuslan Bukin 		} tlbi;
1074cc87010SRuslan Bukin 		struct {
1084cc87010SRuslan Bukin 			uint32_t sid;
1094cc87010SRuslan Bukin 			uint32_t ssid;
1104cc87010SRuslan Bukin 			bool leaf;
1114cc87010SRuslan Bukin 		} cfgi;
1124cc87010SRuslan Bukin 		struct {
1134cc87010SRuslan Bukin 			uint32_t sid;
1144cc87010SRuslan Bukin 		} prefetch;
1154cc87010SRuslan Bukin 		struct {
1164cc87010SRuslan Bukin 			uint64_t msiaddr;
1174cc87010SRuslan Bukin 		} sync;
1184cc87010SRuslan Bukin 	};
1194cc87010SRuslan Bukin };
1204cc87010SRuslan Bukin 
1214cc87010SRuslan Bukin struct l1_desc {
1224cc87010SRuslan Bukin 	uint8_t		span;
1234cc87010SRuslan Bukin 	void		*va;
1244cc87010SRuslan Bukin 	vm_paddr_t	pa;
1254cc87010SRuslan Bukin };
1264cc87010SRuslan Bukin 
1274cc87010SRuslan Bukin struct smmu_strtab {
1284cc87010SRuslan Bukin 	void		*vaddr;
1294cc87010SRuslan Bukin 	uint64_t	base;
1304cc87010SRuslan Bukin 	uint32_t	base_cfg;
1314cc87010SRuslan Bukin 	uint32_t	num_l1_entries;
1324cc87010SRuslan Bukin 	struct l1_desc	*l1;
1334cc87010SRuslan Bukin };
1344cc87010SRuslan Bukin 
1354cc87010SRuslan Bukin struct smmu_softc {
1364cc87010SRuslan Bukin 	device_t		dev;
137a5ec261aSRuslan Bukin 	struct resource		*res[5];
1384cc87010SRuslan Bukin 	void			*intr_cookie[3];
1394cc87010SRuslan Bukin 	uint32_t		ias; /* Intermediate Physical Address */
1404cc87010SRuslan Bukin 	uint32_t		oas; /* Physical Address */
1414cc87010SRuslan Bukin 	uint32_t		asid_bits;
1424cc87010SRuslan Bukin 	uint32_t		vmid_bits;
1434cc87010SRuslan Bukin 	uint32_t		sid_bits;
1444cc87010SRuslan Bukin 	uint32_t		ssid_bits;
1454cc87010SRuslan Bukin 	uint32_t		pgsizes;
1464cc87010SRuslan Bukin 	uint32_t		features;
1474cc87010SRuslan Bukin #define	SMMU_FEATURE_2_LVL_STREAM_TABLE		(1 << 0)
1484cc87010SRuslan Bukin #define	SMMU_FEATURE_2_LVL_CD			(1 << 1)
1494cc87010SRuslan Bukin #define	SMMU_FEATURE_TT_LE			(1 << 2)
1504cc87010SRuslan Bukin #define	SMMU_FEATURE_TT_BE			(1 << 3)
1514cc87010SRuslan Bukin #define	SMMU_FEATURE_SEV			(1 << 4)
1524cc87010SRuslan Bukin #define	SMMU_FEATURE_MSI			(1 << 5)
1534cc87010SRuslan Bukin #define	SMMU_FEATURE_HYP			(1 << 6)
1544cc87010SRuslan Bukin #define	SMMU_FEATURE_ATS			(1 << 7)
1554cc87010SRuslan Bukin #define	SMMU_FEATURE_PRI			(1 << 8)
1564cc87010SRuslan Bukin #define	SMMU_FEATURE_STALL_FORCE		(1 << 9)
1574cc87010SRuslan Bukin #define	SMMU_FEATURE_STALL			(1 << 10)
1584cc87010SRuslan Bukin #define	SMMU_FEATURE_S1P			(1 << 11)
1594cc87010SRuslan Bukin #define	SMMU_FEATURE_S2P			(1 << 12)
1604cc87010SRuslan Bukin #define	SMMU_FEATURE_VAX			(1 << 13)
1614cc87010SRuslan Bukin #define	SMMU_FEATURE_COHERENCY			(1 << 14)
1624cc87010SRuslan Bukin #define	SMMU_FEATURE_RANGE_INV			(1 << 15)
1634cc87010SRuslan Bukin 	struct smmu_queue cmdq;
1644cc87010SRuslan Bukin 	struct smmu_queue evtq;
1654cc87010SRuslan Bukin 	struct smmu_queue priq;
1664cc87010SRuslan Bukin 	struct smmu_strtab strtab;
1674cc87010SRuslan Bukin 	int				sync;
1684cc87010SRuslan Bukin 	struct mtx			sc_mtx;
1694cc87010SRuslan Bukin 	bitstr_t			*asid_set;
1704cc87010SRuslan Bukin 	int				asid_set_size;
1714cc87010SRuslan Bukin 	struct mtx			asid_set_mutex;
1724cc87010SRuslan Bukin 	struct smmu_unit		unit;
1734cc87010SRuslan Bukin 	uintptr_t			xref;
1744cc87010SRuslan Bukin };
1754cc87010SRuslan Bukin 
1764cc87010SRuslan Bukin MALLOC_DECLARE(M_SMMU);
1774cc87010SRuslan Bukin 
1784cc87010SRuslan Bukin /* Device methods */
1794cc87010SRuslan Bukin int smmu_attach(device_t dev);
1804cc87010SRuslan Bukin int smmu_detach(device_t dev);
1814cc87010SRuslan Bukin 
1824cc87010SRuslan Bukin struct smmu_ctx *smmu_ctx_lookup_by_sid(device_t dev, u_int sid);
1834cc87010SRuslan Bukin bool smmu_quirks_check(device_t dev, u_int sid, uint8_t event_id,
1844cc87010SRuslan Bukin     uintptr_t input_addr);
1854cc87010SRuslan Bukin 
1864cc87010SRuslan Bukin #endif /* _ARM64_IOMMU_SMMUVAR_H_ */
187