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));