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 #pragma ident "%Z%%M% %I% %E% SMI" 28fc1821feSrugrat 29fc1821feSrugrat #include <sys/debug.h> 30fc1821feSrugrat #include <sys/types.h> 31fc1821feSrugrat #include <sys/param.h> 32fc1821feSrugrat #include <sys/time.h> 33fc1821feSrugrat #include <sys/buf.h> 34fc1821feSrugrat #include <sys/errno.h> 35fc1821feSrugrat #include <sys/systm.h> 36fc1821feSrugrat #include <sys/conf.h> 37fc1821feSrugrat #include <sys/signal.h> 38fc1821feSrugrat #include <vm/page.h> 39fc1821feSrugrat #include <vm/as.h> 40fc1821feSrugrat #include <vm/hat.h> 41fc1821feSrugrat #include <vm/seg.h> 42fc1821feSrugrat #include <vm/seg_dev.h> 43fc1821feSrugrat #include <vm/hat_i86.h> 44fc1821feSrugrat #include <sys/ddi.h> 45fc1821feSrugrat #include <sys/devops.h> 46fc1821feSrugrat #include <sys/sunddi.h> 47fc1821feSrugrat #include <sys/ddi_impldefs.h> 48fc1821feSrugrat #include <sys/fs/snode.h> 49fc1821feSrugrat #include <sys/pci.h> 50fc1821feSrugrat #include <sys/vmsystm.h> 51*843e1988Sjohnlev #include <sys/int_fmtio.h> 52fc1821feSrugrat #include "gfx_private.h" 53fc1821feSrugrat 54*843e1988Sjohnlev #ifdef __xpv 55*843e1988Sjohnlev #include <sys/hypervisor.h> 56*843e1988Sjohnlev #endif 57*843e1988Sjohnlev 58fc1821feSrugrat /* 59fc1821feSrugrat * Create a dummy ddi_umem_cookie given to gfxp_devmap_umem_setup(). 60fc1821feSrugrat */ 61fc1821feSrugrat ddi_umem_cookie_t 62fc1821feSrugrat gfxp_umem_cookie_init(caddr_t kva, size_t size) 63fc1821feSrugrat { 64fc1821feSrugrat struct ddi_umem_cookie *umem_cookie; 65fc1821feSrugrat 66fc1821feSrugrat umem_cookie = kmem_zalloc(sizeof (struct ddi_umem_cookie), KM_SLEEP); 67fc1821feSrugrat 68fc1821feSrugrat if (umem_cookie == NULL) 69fc1821feSrugrat return (NULL); 70fc1821feSrugrat 71fc1821feSrugrat umem_cookie->cvaddr = kva; 72fc1821feSrugrat umem_cookie->type = KMEM_NON_PAGEABLE; 73fc1821feSrugrat umem_cookie->size = size; 74fc1821feSrugrat 75fc1821feSrugrat return ((ddi_umem_cookie_t *)umem_cookie); 76fc1821feSrugrat } 77fc1821feSrugrat 78fc1821feSrugrat void 79fc1821feSrugrat gfxp_umem_cookie_destroy(ddi_umem_cookie_t cookie) 80fc1821feSrugrat { 81fc1821feSrugrat kmem_free(cookie, sizeof (struct ddi_umem_cookie)); 82fc1821feSrugrat } 83fc1821feSrugrat 84fc1821feSrugrat /* 85fc1821feSrugrat * called by driver devmap routine to pass kernel virtual address mapping 867b93957cSeota * info to the framework. 87fc1821feSrugrat */ 88fc1821feSrugrat /*ARGSUSED*/ 89fc1821feSrugrat int 90fc1821feSrugrat gfxp_devmap_umem_setup(devmap_cookie_t dhc, dev_info_t *dip, 91fc1821feSrugrat struct devmap_callback_ctl *callbackops, ddi_umem_cookie_t cookie, 92fc1821feSrugrat offset_t off, size_t len, uint_t maxprot, uint_t flags, 93fc1821feSrugrat ddi_device_acc_attr_t *accattrp) 94fc1821feSrugrat { 957b93957cSeota uint_t l_flags = flags & ~IOMEM_DATA_MASK; /* clear cache attrs */ 967b93957cSeota int e; 97fc1821feSrugrat 98fc1821feSrugrat /* 997b93957cSeota * Set an appropriate attribute from devacc_attr_dataorder 1007b93957cSeota * to keep compatibility. The cache attributes are igonred 1017b93957cSeota * if specified. 102fc1821feSrugrat */ 1037b93957cSeota if (accattrp != NULL) { 1047b93957cSeota if (accattrp->devacc_attr_dataorder == DDI_STRICTORDER_ACC) { 1057b93957cSeota l_flags |= IOMEM_DATA_UNCACHED; 1067b93957cSeota } else if (accattrp->devacc_attr_dataorder == 1077b93957cSeota DDI_MERGING_OK_ACC) { 1087b93957cSeota l_flags |= IOMEM_DATA_UC_WR_COMBINE; 109fc1821feSrugrat } else { 1107b93957cSeota l_flags |= IOMEM_DATA_CACHED; 111fc1821feSrugrat } 112fc1821feSrugrat } 113fc1821feSrugrat 1147b93957cSeota e = devmap_umem_setup(dhc, dip, callbackops, cookie, off, len, maxprot, 1157b93957cSeota l_flags, accattrp); 1167b93957cSeota return (e); 117fc1821feSrugrat } 1180b8c1102Srugrat 1190b8c1102Srugrat /* 1200b8c1102Srugrat * Replacement for devmap_devmem_setup() which will map a machine address 1210b8c1102Srugrat * instead of a register set/offset. 1220b8c1102Srugrat */ 1230b8c1102Srugrat void 1240b8c1102Srugrat gfxp_map_devmem(devmap_cookie_t dhc, gfx_maddr_t maddr, size_t length, 1250b8c1102Srugrat ddi_device_acc_attr_t *attrp) 1260b8c1102Srugrat { 1270b8c1102Srugrat devmap_handle_t *dhp = (devmap_handle_t *)dhc; 1280b8c1102Srugrat pfn_t pfn; 1290b8c1102Srugrat 1300b8c1102Srugrat 131*843e1988Sjohnlev #ifdef __xpv 132*843e1988Sjohnlev ASSERT(DOMAIN_IS_INITDOMAIN(xen_info)); 133*843e1988Sjohnlev pfn = xen_assign_pfn(mmu_btop(maddr)); 134*843e1988Sjohnlev #else 1350b8c1102Srugrat pfn = mmu_btop(maddr); 136*843e1988Sjohnlev #endif 1370b8c1102Srugrat 1380b8c1102Srugrat dhp->dh_pfn = pfn; 1390b8c1102Srugrat dhp->dh_len = mmu_ptob(mmu_btopr(length)); 1400b8c1102Srugrat dhp->dh_roff = 0; 1410b8c1102Srugrat 1420b8c1102Srugrat #ifndef DEVMAP_DEVMEM_COOKIE 1430b8c1102Srugrat #define DEVMAP_DEVMEM_COOKIE ((ddi_umem_cookie_t)0x1) /* XXPV */ 1440b8c1102Srugrat #endif /* DEVMAP_DEVMEM_COOKIE */ 1450b8c1102Srugrat dhp->dh_cookie = DEVMAP_DEVMEM_COOKIE; 1460b8c1102Srugrat /*LINTED: E_EXPR_NULL_EFFECT*/ 1470b8c1102Srugrat dhp->dh_flags |= DEVMAP_DEFAULTS; 1480b8c1102Srugrat dhp->dh_maxprot = PROT_ALL & dhp->dh_orig_maxprot; 1490b8c1102Srugrat 1500b8c1102Srugrat /* no callbacks needed */ 1510b8c1102Srugrat bzero(&dhp->dh_callbackops, sizeof (struct devmap_callback_ctl)); 1520b8c1102Srugrat 1530b8c1102Srugrat switch (attrp->devacc_attr_dataorder) { 1540b8c1102Srugrat case DDI_UNORDERED_OK_ACC: 1550b8c1102Srugrat dhp->dh_hat_attr = HAT_UNORDERED_OK; 1560b8c1102Srugrat break; 1570b8c1102Srugrat case DDI_MERGING_OK_ACC: 1580b8c1102Srugrat dhp->dh_hat_attr = HAT_MERGING_OK; 1590b8c1102Srugrat break; 1600b8c1102Srugrat case DDI_LOADCACHING_OK_ACC: 1610b8c1102Srugrat dhp->dh_hat_attr = HAT_LOADCACHING_OK; 1620b8c1102Srugrat break; 1630b8c1102Srugrat case DDI_STORECACHING_OK_ACC: 1640b8c1102Srugrat dhp->dh_hat_attr = HAT_STORECACHING_OK; 1650b8c1102Srugrat break; 1660b8c1102Srugrat case DDI_STRICTORDER_ACC: 1670b8c1102Srugrat default: 1680b8c1102Srugrat dhp->dh_hat_attr = HAT_STRICTORDER; 1690b8c1102Srugrat } 1700b8c1102Srugrat 1710b8c1102Srugrat /* don't use large pages */ 1720b8c1102Srugrat dhp->dh_mmulevel = 0; 1730b8c1102Srugrat dhp->dh_flags &= ~DEVMAP_FLAG_LARGE; 1740b8c1102Srugrat 1750b8c1102Srugrat dhp->dh_flags |= DEVMAP_SETUP_DONE; 1760b8c1102Srugrat } 177