smmu.c (182a69328da2aa081f61369540f5d674c23e277b) | smmu.c (41ce5498f8e69e6820962e813eb3b40c465079d0) |
---|---|
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 --- 1830 unchanged lines hidden (view full) --- 1839} 1840#endif 1841 1842static struct iommu_ctx * 1843smmu_ctx_alloc(device_t dev, struct iommu_domain *iodom, device_t child, 1844 bool disabled) 1845{ 1846 struct smmu_domain *domain; | 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 --- 1830 unchanged lines hidden (view full) --- 1839} 1840#endif 1841 1842static struct iommu_ctx * 1843smmu_ctx_alloc(device_t dev, struct iommu_domain *iodom, device_t child, 1844 bool disabled) 1845{ 1846 struct smmu_domain *domain; |
1847 struct smmu_ctx *ctx; 1848 1849 domain = (struct smmu_domain *)iodom; 1850 1851 ctx = malloc(sizeof(struct smmu_ctx), M_SMMU, M_WAITOK | M_ZERO); 1852 ctx->dev = child; 1853 ctx->domain = domain; 1854 if (disabled) 1855 ctx->bypass = true; 1856 1857 IOMMU_DOMAIN_LOCK(iodom); 1858 LIST_INSERT_HEAD(&domain->ctx_list, ctx, next); 1859 IOMMU_DOMAIN_UNLOCK(iodom); 1860 1861 return (&ctx->ioctx); 1862} 1863 1864static int 1865smmu_ctx_init(device_t dev, struct iommu_ctx *ioctx) 1866{ 1867 struct smmu_domain *domain; 1868 struct iommu_domain *iodom; |
|
1847 struct smmu_softc *sc; 1848 struct smmu_ctx *ctx; 1849 devclass_t pci_class; 1850 u_int sid; 1851 int err; 1852 | 1869 struct smmu_softc *sc; 1870 struct smmu_ctx *ctx; 1871 devclass_t pci_class; 1872 u_int sid; 1873 int err; 1874 |
1875 ctx = (struct smmu_ctx *)ioctx; 1876 |
|
1853 sc = device_get_softc(dev); | 1877 sc = device_get_softc(dev); |
1854 domain = (struct smmu_domain *)iodom; | |
1855 | 1878 |
1856 pci_class = devclass_find("pci"); 1857 if (device_get_devclass(device_get_parent(child)) != pci_class) 1858 return (NULL); | 1879 domain = ctx->domain; 1880 iodom = (struct iommu_domain *)domain; |
1859 | 1881 |
1882 pci_class = devclass_find("pci"); 1883 if (device_get_devclass(device_get_parent(ctx->dev)) == pci_class) { |
|
1860#ifdef DEV_ACPI | 1884#ifdef DEV_ACPI |
1861 err = smmu_pci_get_sid_acpi(child, NULL, &sid); | 1885 err = smmu_pci_get_sid_acpi(ctx->dev, NULL, &sid); |
1862#else | 1886#else |
1863 err = smmu_pci_get_sid_fdt(child, NULL, &sid); | 1887 err = smmu_pci_get_sid_fdt(ctx->dev, NULL, &sid); |
1864#endif | 1888#endif |
1865 if (err) 1866 return (NULL); | 1889 if (err) 1890 return (err); |
1867 | 1891 |
1892 ioctx->rid = pci_get_rid(dev); 1893 ctx->sid = sid; 1894 ctx->vendor = pci_get_vendor(ctx->dev); 1895 ctx->device = pci_get_device(ctx->dev); 1896 } 1897 |
|
1868 if (sc->features & SMMU_FEATURE_2_LVL_STREAM_TABLE) { | 1898 if (sc->features & SMMU_FEATURE_2_LVL_STREAM_TABLE) { |
1869 err = smmu_init_l1_entry(sc, sid); | 1899 err = smmu_init_l1_entry(sc, ctx->sid); |
1870 if (err) | 1900 if (err) |
1871 return (NULL); | 1901 return (err); |
1872 } 1873 | 1902 } 1903 |
1874 ctx = malloc(sizeof(struct smmu_ctx), M_SMMU, M_WAITOK | M_ZERO); 1875 ctx->vendor = pci_get_vendor(child); 1876 ctx->device = pci_get_device(child); 1877 ctx->dev = child; 1878 ctx->sid = sid; 1879 ctx->domain = domain; 1880 if (disabled) 1881 ctx->bypass = true; 1882 | |
1883 /* 1884 * Neoverse N1 SDP: 1885 * 0x800 xhci 1886 * 0x700 re 1887 * 0x600 sata 1888 */ 1889 1890 smmu_init_ste(sc, domain->cd, ctx->sid, ctx->bypass); 1891 | 1904 /* 1905 * Neoverse N1 SDP: 1906 * 0x800 xhci 1907 * 0x700 re 1908 * 0x600 sata 1909 */ 1910 1911 smmu_init_ste(sc, domain->cd, ctx->sid, ctx->bypass); 1912 |
1892 if (iommu_is_buswide_ctx(iodom->iommu, pci_get_bus(ctx->dev))) 1893 smmu_set_buswide(dev, domain, ctx); | 1913 if (device_get_devclass(device_get_parent(ctx->dev)) == pci_class) 1914 if (iommu_is_buswide_ctx(iodom->iommu, pci_get_bus(ctx->dev))) 1915 smmu_set_buswide(dev, domain, ctx); |
1894 | 1916 |
1895 IOMMU_DOMAIN_LOCK(iodom); 1896 LIST_INSERT_HEAD(&domain->ctx_list, ctx, next); 1897 IOMMU_DOMAIN_UNLOCK(iodom); 1898 1899 return (&ctx->ioctx); | 1917 return (0); |
1900} 1901 1902static void 1903smmu_ctx_free(device_t dev, struct iommu_ctx *ioctx) 1904{ 1905 struct smmu_softc *sc; 1906 struct smmu_ctx *ctx; 1907 --- 80 unchanged lines hidden (view full) --- 1988 1989 /* Check if xref is ours. */ 1990 if (xref != sc->xref) 1991 return (EFAULT); 1992 1993 return (0); 1994} 1995 | 1918} 1919 1920static void 1921smmu_ctx_free(device_t dev, struct iommu_ctx *ioctx) 1922{ 1923 struct smmu_softc *sc; 1924 struct smmu_ctx *ctx; 1925 --- 80 unchanged lines hidden (view full) --- 2006 2007 /* Check if xref is ours. */ 2008 if (xref != sc->xref) 2009 return (EFAULT); 2010 2011 return (0); 2012} 2013 |
2014#ifdef FDT 2015static int 2016smmu_ofw_md_data(device_t dev, struct iommu_ctx *ioctx, pcell_t *cells, 2017 int ncells) 2018{ 2019 struct smmu_ctx *ctx; 2020 2021 ctx = (struct smmu_ctx *)ioctx; 2022 2023 if (ncells != 1) 2024 return (-1); 2025 2026 ctx->sid = cells[0]; 2027 2028 return (0); 2029} 2030#endif 2031 |
|
1996static device_method_t smmu_methods[] = { 1997 /* Device interface */ 1998 DEVMETHOD(device_detach, smmu_detach), 1999 2000 /* SMMU interface */ 2001 DEVMETHOD(iommu_find, smmu_find), 2002 DEVMETHOD(iommu_map, smmu_map), 2003 DEVMETHOD(iommu_unmap, smmu_unmap), 2004 DEVMETHOD(iommu_domain_alloc, smmu_domain_alloc), 2005 DEVMETHOD(iommu_domain_free, smmu_domain_free), 2006 DEVMETHOD(iommu_ctx_alloc, smmu_ctx_alloc), | 2032static device_method_t smmu_methods[] = { 2033 /* Device interface */ 2034 DEVMETHOD(device_detach, smmu_detach), 2035 2036 /* SMMU interface */ 2037 DEVMETHOD(iommu_find, smmu_find), 2038 DEVMETHOD(iommu_map, smmu_map), 2039 DEVMETHOD(iommu_unmap, smmu_unmap), 2040 DEVMETHOD(iommu_domain_alloc, smmu_domain_alloc), 2041 DEVMETHOD(iommu_domain_free, smmu_domain_free), 2042 DEVMETHOD(iommu_ctx_alloc, smmu_ctx_alloc), |
2043 DEVMETHOD(iommu_ctx_init, smmu_ctx_init), |
|
2007 DEVMETHOD(iommu_ctx_free, smmu_ctx_free), 2008 DEVMETHOD(iommu_ctx_lookup, smmu_ctx_lookup), | 2044 DEVMETHOD(iommu_ctx_free, smmu_ctx_free), 2045 DEVMETHOD(iommu_ctx_lookup, smmu_ctx_lookup), |
2046#ifdef FDT 2047 DEVMETHOD(iommu_ofw_md_data, smmu_ofw_md_data), 2048#endif |
|
2009 2010 /* Bus interface */ 2011 DEVMETHOD(bus_read_ivar, smmu_read_ivar), 2012 2013 /* End */ 2014 DEVMETHOD_END 2015}; 2016 2017DEFINE_CLASS_0(smmu, smmu_driver, smmu_methods, sizeof(struct smmu_softc)); | 2049 2050 /* Bus interface */ 2051 DEVMETHOD(bus_read_ivar, smmu_read_ivar), 2052 2053 /* End */ 2054 DEVMETHOD_END 2055}; 2056 2057DEFINE_CLASS_0(smmu, smmu_driver, smmu_methods, sizeof(struct smmu_softc)); |