px_mmu.c revision 15e1afcd5e908ae29b1e6018838638befdc225a2
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * CDDL HEADER START
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * The contents of this file are subject to the terms of the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Common Development and Distribution License (the "License").
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * You may not use this file except in compliance with the License.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * See the License for the specific language governing permissions
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * and limitations under the License.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * When distributing Covered Code, include this CDDL HEADER in each
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * If applicable, add the following below this CDDL HEADER, with the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * fields enclosed by brackets "[]" replaced with your own identifying
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * information: Portions Copyright [yyyy] [name of copyright owner]
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * CDDL HEADER END
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * PX mmu initialization and configuration
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Allocate mmu state structure and link it to the
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * px state structure.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Check for "virtual-dma" property that specifies
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the DVMA range.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States px_p->px_mmu_p = NULL;
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States mmu_p->mmu_dvma_base = dvma_prop->dvma_base;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Setup base and bounds for DVMA and bypass mappings.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Create a virtual memory map for dvma address space.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Reserve 'size' bytes of low dvma space for fast track cache.
1c29f7e382074ff2792b7f30c9be898ead487a30Qiyan Sun - Sun Microsystems - San Diego United States (void) snprintf(map_name, sizeof (map_name), "%s%d_dvma",
fd9489cef0e9b7d8a708339e560d453f230af2cfQiyan Sun - Sun Microsystems - San Diego United States mmu_p->mmu_dvma_fast_end = mmu_p->mmu_dvma_base +
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mutex_init(&mmu_p->dvma_debug_lock, NULL, MUTEX_DRIVER, NULL);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (px_lib_iommu_getmap(px_p->px_dip, PCI_TSBID(0, tsb_i),
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the va is within the *fast* dvma range; therefore,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * lock its fast dvma page cache cluster in order to
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * both preserve the TTE and prevent the use of this
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * fast dvma page cache cluster by px_dvma_map_fast().
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * the lock value 0xFF comes from ldstub().
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Free the dvma resource map.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Free the mmu state structure.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qspx_mmu_map_pages(px_mmu_t *mmu_p, ddi_dma_impl_t *mp, px_dvma_addr_t dvma_pg,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs px_dvma_addr_t pg_index = MMU_PAGE_INDEX(mmu_p, dvma_pg);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "npages=0x%x pfn_index=0x%x\n", (uint_t)mmu_p->dvma_base_pg,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs (uint_t)pg_index, dvma_pg, (uint_t)npages, (uint_t)pfn_index);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (px_lib_iommu_map(dip, PCI_TSBID(0, pg_index), npages,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs PX_ADD_ATTR_EXTNS(attr, mp->dmai_bdf), (void *)mp, pfn_index,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "px_lib_iommu_map failed\n");
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs DBG(DBG_MAP_WIN, dip, "px_mmu_map_pages: redzone pg=%x\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (px_lib_iommu_map(dip, PCI_TSBID(0, pg_index + npages), 1,
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "REDZONE page failed\n");
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs if (px_lib_iommu_demap(dip, PCI_TSBID(0, pg_index), npages)
fe930412c257f961ae67039de3b164b83717976aqspx_mmu_unmap_pages(px_mmu_t *mmu_p, ddi_dma_impl_t *mp, px_dvma_addr_t dvma_pg,
fe930412c257f961ae67039de3b164b83717976aqs px_dvma_addr_t pg_index = MMU_PAGE_INDEX(mmu_p, dvma_pg);
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "px_mmu_unmap_pages:%x+%x=%x npages=0x%x\n",
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "px_lib_iommu_demap: failed\n");
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs DBG(DBG_UNMAP_WIN, mmu_p->mmu_px_p->px_dip, "px_mmu_unmap_pages: "
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs "px_lib_iommu_demap: failed\n");
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * px_mmu_map_window - map a dvma window into the mmu
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * used by: px_dma_win(), px_dma_ctlops() - DDI_DMA_MOVWIN, DDI_DMA_NEXTWIN
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * return value: none
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qspx_mmu_map_window(px_mmu_t *mmu_p, ddi_dma_impl_t *mp, px_window_t win_no)
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs size_t obj_off = win_no ? pfn_index - obj_pg0_off : 0; /* xferred sz */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs size_t res_size = mp->dmai_object.dmao_size - obj_off + win_pg0_off;
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs mp->dmai_size = win_size - win_pg0_off; /* cur win xferrable size */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs pfn_index = MMU_BTOP(pfn_index); /* index into pfnlist */
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs ret = px_mmu_map_pages(mmu_p, mp, dvma_pg, MMU_BTOPR(win_size),
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * px_mmu_unmap_window
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * This routine is called to break down the mmu mappings to a dvma window.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * Non partial mappings are viewed as single window mapping.
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * used by: px_dma_unbindhdl(), px_dma_window(),
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * and px_dma_ctlops() - DDI_DMA_FREE, DDI_DMA_MOVWIN, DDI_DMA_NEXTWIN
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs * return value: none
3dec9fcdd56adf1b4a563137b4915c8f2d83b881qs/*ARGSUSED*/
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer px_dvma_addr_t dvma_pg = MMU_BTOP(mp->dmai_mapping);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer px_mmu_unmap_pages(mmu_p, mp, dvma_pg, npages);
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer px_dvma_free_debug(mmu_p, (char *)mp->dmai_mapping,
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * The following table is for reference only. It denotes the
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * the TSB table size measured in number of 8 byte entries.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * It is represented by bits 3:0 in the MMU TSB CTRL REG.
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speerstatic char *px_mmu_errsts[] = {
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer "Protection Error", "Invalid Error", "Timeout", "ECC Error(UE)"
1ed830817782694e7259ee818a2f8eee72233f1eMichael Speer * Place holder, the correct eror bits need tobe logged.