1fc1821feSrugrat /* 2fc1821feSrugrat * CDDL HEADER START 3fc1821feSrugrat * 4fc1821feSrugrat * The contents of this file are subject to the terms of the 57b93957cSeota * Common Development and Distribution License (the "License"). 67b93957cSeota * You may not use this file except in compliance with the License. 7fc1821feSrugrat * 8fc1821feSrugrat * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fc1821feSrugrat * or http://www.opensolaris.org/os/licensing. 10fc1821feSrugrat * See the License for the specific language governing permissions 11fc1821feSrugrat * and limitations under the License. 12fc1821feSrugrat * 13fc1821feSrugrat * When distributing Covered Code, include this CDDL HEADER in each 14fc1821feSrugrat * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fc1821feSrugrat * If applicable, add the following below this CDDL HEADER, with the 16fc1821feSrugrat * fields enclosed by brackets "[]" replaced with your own identifying 17fc1821feSrugrat * information: Portions Copyright [yyyy] [name of copyright owner] 18fc1821feSrugrat * 19fc1821feSrugrat * CDDL HEADER END 20fc1821feSrugrat */ 217b93957cSeota 22fc1821feSrugrat /* 230b8c1102Srugrat * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24fc1821feSrugrat * Use is subject to license terms. 25fc1821feSrugrat */ 26fc1821feSrugrat 27fc1821feSrugrat #include <sys/debug.h> 28fc1821feSrugrat #include <sys/types.h> 29fc1821feSrugrat #include <sys/param.h> 30fc1821feSrugrat #include <sys/time.h> 31fc1821feSrugrat #include <sys/buf.h> 32fc1821feSrugrat #include <sys/errno.h> 33fc1821feSrugrat #include <sys/systm.h> 34fc1821feSrugrat #include <sys/conf.h> 35fc1821feSrugrat #include <sys/signal.h> 36fc1821feSrugrat #include <vm/page.h> 37fc1821feSrugrat #include <vm/as.h> 38fc1821feSrugrat #include <vm/hat.h> 39fc1821feSrugrat #include <vm/seg.h> 40fc1821feSrugrat #include <vm/seg_dev.h> 41fc1821feSrugrat #include <vm/hat_i86.h> 42fc1821feSrugrat #include <sys/ddi.h> 43fc1821feSrugrat #include <sys/devops.h> 44fc1821feSrugrat #include <sys/sunddi.h> 45fc1821feSrugrat #include <sys/ddi_impldefs.h> 46fc1821feSrugrat #include <sys/fs/snode.h> 47fc1821feSrugrat #include <sys/pci.h> 48fc1821feSrugrat #include <sys/vmsystm.h> 49843e1988Sjohnlev #include <sys/int_fmtio.h> 50fc1821feSrugrat #include "gfx_private.h" 51fc1821feSrugrat 52843e1988Sjohnlev #ifdef __xpv 53843e1988Sjohnlev #include <sys/hypervisor.h> 54843e1988Sjohnlev #endif 55843e1988Sjohnlev 56fc1821feSrugrat /* 57fc1821feSrugrat * Create a dummy ddi_umem_cookie given to gfxp_devmap_umem_setup(). 58fc1821feSrugrat */ 59fc1821feSrugrat ddi_umem_cookie_t 60fc1821feSrugrat gfxp_umem_cookie_init(caddr_t kva, size_t size) 61fc1821feSrugrat { 62fc1821feSrugrat struct ddi_umem_cookie *umem_cookie; 63fc1821feSrugrat 64fc1821feSrugrat umem_cookie = kmem_zalloc(sizeof (struct ddi_umem_cookie), KM_SLEEP); 65fc1821feSrugrat 66fc1821feSrugrat if (umem_cookie == NULL) 67fc1821feSrugrat return (NULL); 68fc1821feSrugrat 69fc1821feSrugrat umem_cookie->cvaddr = kva; 70fc1821feSrugrat umem_cookie->type = KMEM_NON_PAGEABLE; 71fc1821feSrugrat umem_cookie->size = size; 72fc1821feSrugrat 73*058c4bb4SToomas Soome return ((ddi_umem_cookie_t)umem_cookie); 74fc1821feSrugrat } 75fc1821feSrugrat 76fc1821feSrugrat void 77fc1821feSrugrat gfxp_umem_cookie_destroy(ddi_umem_cookie_t cookie) 78fc1821feSrugrat { 79fc1821feSrugrat kmem_free(cookie, sizeof (struct ddi_umem_cookie)); 80fc1821feSrugrat } 81fc1821feSrugrat 82fc1821feSrugrat /* 83fc1821feSrugrat * called by driver devmap routine to pass kernel virtual address mapping 847b93957cSeota * info to the framework. 85fc1821feSrugrat */ 86fc1821feSrugrat /*ARGSUSED*/ 87fc1821feSrugrat int 88fc1821feSrugrat gfxp_devmap_umem_setup(devmap_cookie_t dhc, dev_info_t *dip, 89fc1821feSrugrat struct devmap_callback_ctl *callbackops, ddi_umem_cookie_t cookie, 90fc1821feSrugrat offset_t off, size_t len, uint_t maxprot, uint_t flags, 91fc1821feSrugrat ddi_device_acc_attr_t *accattrp) 92fc1821feSrugrat { 937b93957cSeota uint_t l_flags = flags & ~IOMEM_DATA_MASK; /* clear cache attrs */ 947b93957cSeota int e; 95fc1821feSrugrat 96fc1821feSrugrat /* 977b93957cSeota * Set an appropriate attribute from devacc_attr_dataorder 987b93957cSeota * to keep compatibility. The cache attributes are igonred 997b93957cSeota * if specified. 100fc1821feSrugrat */ 1017b93957cSeota if (accattrp != NULL) { 1027b93957cSeota if (accattrp->devacc_attr_dataorder == DDI_STRICTORDER_ACC) { 1037b93957cSeota l_flags |= IOMEM_DATA_UNCACHED; 1047b93957cSeota } else if (accattrp->devacc_attr_dataorder == 1057b93957cSeota DDI_MERGING_OK_ACC) { 1067b93957cSeota l_flags |= IOMEM_DATA_UC_WR_COMBINE; 107fc1821feSrugrat } else { 1087b93957cSeota l_flags |= IOMEM_DATA_CACHED; 109fc1821feSrugrat } 110fc1821feSrugrat } 111fc1821feSrugrat 1127b93957cSeota e = devmap_umem_setup(dhc, dip, callbackops, cookie, off, len, maxprot, 1137b93957cSeota l_flags, accattrp); 1147b93957cSeota return (e); 115fc1821feSrugrat } 1160b8c1102Srugrat 1170b8c1102Srugrat /* 1180b8c1102Srugrat * Replacement for devmap_devmem_setup() which will map a machine address 1190b8c1102Srugrat * instead of a register set/offset. 1200b8c1102Srugrat */ 1210b8c1102Srugrat void 1220b8c1102Srugrat gfxp_map_devmem(devmap_cookie_t dhc, gfx_maddr_t maddr, size_t length, 1230b8c1102Srugrat ddi_device_acc_attr_t *attrp) 1240b8c1102Srugrat { 1250b8c1102Srugrat devmap_handle_t *dhp = (devmap_handle_t *)dhc; 1260b8c1102Srugrat pfn_t pfn; 1270b8c1102Srugrat 1280b8c1102Srugrat 129843e1988Sjohnlev #ifdef __xpv 130843e1988Sjohnlev ASSERT(DOMAIN_IS_INITDOMAIN(xen_info)); 131843e1988Sjohnlev pfn = xen_assign_pfn(mmu_btop(maddr)); 132843e1988Sjohnlev #else 1330b8c1102Srugrat pfn = mmu_btop(maddr); 134843e1988Sjohnlev #endif 1350b8c1102Srugrat 1360b8c1102Srugrat dhp->dh_pfn = pfn; 1370b8c1102Srugrat dhp->dh_len = mmu_ptob(mmu_btopr(length)); 1380b8c1102Srugrat dhp->dh_roff = 0; 1390b8c1102Srugrat 1400b8c1102Srugrat #ifndef DEVMAP_DEVMEM_COOKIE 1410b8c1102Srugrat #define DEVMAP_DEVMEM_COOKIE ((ddi_umem_cookie_t)0x1) /* XXPV */ 1420b8c1102Srugrat #endif /* DEVMAP_DEVMEM_COOKIE */ 1430b8c1102Srugrat dhp->dh_cookie = DEVMAP_DEVMEM_COOKIE; 1440b8c1102Srugrat /*LINTED: E_EXPR_NULL_EFFECT*/ 1450b8c1102Srugrat dhp->dh_flags |= DEVMAP_DEFAULTS; 1460b8c1102Srugrat dhp->dh_maxprot = PROT_ALL & dhp->dh_orig_maxprot; 1470b8c1102Srugrat 1480b8c1102Srugrat /* no callbacks needed */ 1490b8c1102Srugrat bzero(&dhp->dh_callbackops, sizeof (struct devmap_callback_ctl)); 1500b8c1102Srugrat 1510b8c1102Srugrat switch (attrp->devacc_attr_dataorder) { 1520b8c1102Srugrat case DDI_UNORDERED_OK_ACC: 1530b8c1102Srugrat dhp->dh_hat_attr = HAT_UNORDERED_OK; 1540b8c1102Srugrat break; 1550b8c1102Srugrat case DDI_MERGING_OK_ACC: 1560b8c1102Srugrat dhp->dh_hat_attr = HAT_MERGING_OK; 1570b8c1102Srugrat break; 1580b8c1102Srugrat case DDI_LOADCACHING_OK_ACC: 1590b8c1102Srugrat dhp->dh_hat_attr = HAT_LOADCACHING_OK; 1600b8c1102Srugrat break; 1610b8c1102Srugrat case DDI_STORECACHING_OK_ACC: 1620b8c1102Srugrat dhp->dh_hat_attr = HAT_STORECACHING_OK; 1630b8c1102Srugrat break; 1640b8c1102Srugrat case DDI_STRICTORDER_ACC: 1650b8c1102Srugrat default: 1660b8c1102Srugrat dhp->dh_hat_attr = HAT_STRICTORDER; 1670b8c1102Srugrat } 1680b8c1102Srugrat 1690b8c1102Srugrat /* don't use large pages */ 1700b8c1102Srugrat dhp->dh_mmulevel = 0; 1710b8c1102Srugrat dhp->dh_flags &= ~DEVMAP_FLAG_LARGE; 1720b8c1102Srugrat 1730b8c1102Srugrat dhp->dh_flags |= DEVMAP_SETUP_DONE; 1740b8c1102Srugrat } 175