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