From owner-svn-src-projects@FreeBSD.ORG Sat Jan 12 21:52:05 2013 Return-Path: <owner-svn-src-projects@FreeBSD.ORG> Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 7ACCD466; Sat, 12 Jan 2013 21:52:05 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 6D940A94; Sat, 12 Jan 2013 21:52:05 +0000 (UTC) Received: from svn.freebsd.org (svn.FreeBSD.org [8.8.178.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0CLq5vQ083269; Sat, 12 Jan 2013 21:52:05 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0CLq5MF083268; Sat, 12 Jan 2013 21:52:05 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201301122152.r0CLq5MF083268@svn.freebsd.org> From: Marcel Moolenaar <marcel@FreeBSD.org> Date: Sat, 12 Jan 2013 21:52:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r245342 - projects/altix2/sys/ia64/sgisn X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" <svn-src-projects.freebsd.org> List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-projects>, <mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe> List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects> List-Post: <mailto:svn-src-projects@freebsd.org> List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help> List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, <mailto:svn-src-projects-request@freebsd.org?subject=subscribe> X-List-Received-Date: Sat, 12 Jan 2013 21:52:05 -0000 Author: marcel Date: Sat Jan 12 21:52:04 2013 New Revision: 245342 URL: http://svnweb.freebsd.org/changeset/base/245342 Log: Make DMA work reliably for isp(4). As it turns out, consistent DMA only work for 64-bit direct-mapped addresses when the PCI bus is in PCI-X mode. As it turns out, we're not on my machine. With both 32-bit and 64-bit direct-mapped addresses out of the picture WRT to consistent DMA, we're left with programming the I/O MMU (aka ATEs). Hack it enough for use by isp(4) to see what's needed. With this commit, we can install FreeBSD on an Altix 350 (single node). with SMP of course. Next steps: 1. make the I/O MMU code generic. 2. port bge(4) so that we have networking. 3. make it all work with 2 nodes (mostly VM coherency) Modified: projects/altix2/sys/ia64/sgisn/sgisn_pcib.c Modified: projects/altix2/sys/ia64/sgisn/sgisn_pcib.c ============================================================================== --- projects/altix2/sys/ia64/sgisn/sgisn_pcib.c Sat Jan 12 21:51:49 2013 (r245341) +++ projects/altix2/sys/ia64/sgisn/sgisn_pcib.c Sat Jan 12 21:52:04 2013 (r245342) @@ -56,6 +56,10 @@ __FBSDID("$FreeBSD$"); #include <ia64/sgisn/sgisn_pcib.h> +#define SGISN_PCIB_PAGE_SHIFT 14 /* 16KB; Use 12 for 4KB */ +#define SGISN_PCIB_PAGE_SIZE (1UL << SGISN_PCIB_PAGE_SHIFT) +#define SGISN_PCIB_PAGE_MASK (SGISN_PCIB_PAGE_SIZE - 1UL) + static struct sgisn_fwdev sgisn_dev; static struct sgisn_fwirq sgisn_irq; @@ -427,6 +431,7 @@ sgisn_pcib_attach(device_t dev) device_t parent; size_t fwflushsz; uintptr_t addr, ivar; + uint64_t ctrl; int error; sc = device_get_softc(dev); @@ -461,6 +466,15 @@ sgisn_pcib_attach(device_t dev) sc->sc_fwbus->fw_common.bus_xid, sc->sc_fwbus->fw_type, sc->sc_fwbus->fw_mode); + /* Set the preferred I/O MMU page size -- 4KB or 16KB. */ + ctrl = bus_space_read_8(sc->sc_tag, sc->sc_hndl, PIC_REG_WGT_CTRL); +#if SGISN_PCIB_PAGE_SHIFT == 12 + ctrl &= ~(1UL << 21); +#else + ctrl |= 1UL << 21; +#endif + bus_space_write_8(sc->sc_tag, sc->sc_hndl, PIC_REG_WGT_CTRL, ctrl); + fwflushsz = (PCI_SLOTMAX + 1) * sizeof(struct sgisn_fwflush); fwflush = contigmalloc(fwflushsz, M_TEMP, M_ZERO, 0UL, ~0UL, 16, 0); BUS_READ_IVAR(parent, dev, SHUB_IVAR_NASID, &ivar); @@ -524,12 +538,25 @@ sgisn_pcib_iommu_xlate(device_t bus, dev vm_paddr_t bndry = 0x80000000UL; /* + * 64-bit consistent DMA is only guaranteed for PCI-X. So, if we + * need consistent DMA and we're not in PCI-X mode, force 32-bit + * mappings. + */ + if ((mtag->dmt_flags & BUSDMA_ALLOC_CONSISTENT) && + (sc->sc_fwbus->fw_mode & 1) == 0 && + mtag->dmt_maxaddr == BUS_SPACE_MAXADDR) + mtag->dmt_maxaddr >>= 4; + + /* * Use a 31-bit direct-mapped window for PCI devices that are not - * 64-bit capable and we're not in PCI-X mode. + * 64-bit capable and we're not in PCI-X mode and we don't need + * consistent DMA. * For 31-bit direct-mapped DMA we need to make sure allocations * do not cross the 2G boundary. */ - if (mtag->dmt_maxaddr < ~0UL && (sc->sc_fwbus->fw_mode & 1) == 0) + if (mtag->dmt_maxaddr < BUS_SPACE_MAXADDR && + (sc->sc_fwbus->fw_mode & 1) == 0 && + (mtag->dmt_flags & BUSDMA_ALLOC_CONSISTENT) == 0) mtag->dmt_flags |= BUSDMA_MD_IA64_DIRECT32; if (mtag->dmt_flags & BUSDMA_MD_IA64_DIRECT32) { @@ -560,14 +587,48 @@ sgisn_pcib_iommu_map(device_t bus, devic tag = busdma_md_get_tag(md); maxaddr = busdma_tag_get_maxaddr(tag); - if (maxaddr == ~0UL) { + if (maxaddr == BUS_SPACE_MAXADDR) { *ba_p = ba | ((u_long)sc->sc_fwbus->fw_hub_xid << 60) | - (1UL << 59); + (1UL << ((flags & BUSDMA_ALLOC_CONSISTENT) ? 56 : 59)); return (0); } - /* XXX 32-bit mapped DMA */ - return (ENXIO); + /* + * 32-bit mapped DMA. + * + * XXX HACK START XXX + */ + { + bus_addr_t size; + size_t count; + u_int entry; + + size = busdma_md_get_size(md, idx); + count = ((ba & SGISN_PCIB_PAGE_MASK) + size + + SGISN_PCIB_PAGE_MASK) >> SGISN_PCIB_PAGE_SHIFT; + + entry = 0; + + *ba_p = (1UL << 30) | (ba & SGISN_PCIB_PAGE_MASK) | + (SGISN_PCIB_PAGE_SIZE * entry); + + ba &= ~SGISN_PCIB_PAGE_MASK; + ba |= 1 << 0; /* valid */ + ba |= 1 << ((flags & BUSDMA_ALLOC_CONSISTENT) ? 4 : 3); + ba |= (u_long)sc->sc_fwbus->fw_hub_xid << 8; + + while (count > 0) { + bus_space_write_8(sc->sc_tag, sc->sc_hndl, + PIC_REG_ATE(entry), ba); + ba += SGISN_PCIB_PAGE_SIZE; + entry++; + count--; + } + } + /* + * XXX HACK END XXX + */ + return (0); } static int