1945Srugrat /*
2945Srugrat * CDDL HEADER START
3945Srugrat *
4945Srugrat * The contents of this file are subject to the terms of the
51900Seota * Common Development and Distribution License (the "License").
61900Seota * You may not use this file except in compliance with the License.
7945Srugrat *
8945Srugrat * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9945Srugrat * or http://www.opensolaris.org/os/licensing.
10945Srugrat * See the License for the specific language governing permissions
11945Srugrat * and limitations under the License.
12945Srugrat *
13945Srugrat * When distributing Covered Code, include this CDDL HEADER in each
14945Srugrat * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15945Srugrat * If applicable, add the following below this CDDL HEADER, with the
16945Srugrat * fields enclosed by brackets "[]" replaced with your own identifying
17945Srugrat * information: Portions Copyright [yyyy] [name of copyright owner]
18945Srugrat *
19945Srugrat * CDDL HEADER END
20945Srugrat */
211900Seota
22945Srugrat /*
233987Srugrat * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24945Srugrat * Use is subject to license terms.
25945Srugrat */
26945Srugrat
27945Srugrat #pragma ident "%Z%%M% %I% %E% SMI"
28945Srugrat
29945Srugrat #include <sys/debug.h>
30945Srugrat #include <sys/types.h>
31945Srugrat #include <sys/param.h>
32945Srugrat #include <sys/time.h>
33945Srugrat #include <sys/buf.h>
34945Srugrat #include <sys/errno.h>
35945Srugrat #include <sys/systm.h>
36945Srugrat #include <sys/conf.h>
37945Srugrat #include <sys/signal.h>
38945Srugrat #include <vm/page.h>
39945Srugrat #include <vm/as.h>
40945Srugrat #include <vm/hat.h>
41945Srugrat #include <vm/seg.h>
42945Srugrat #include <vm/seg_dev.h>
43945Srugrat #include <vm/hat_i86.h>
44945Srugrat #include <sys/ddi.h>
45945Srugrat #include <sys/devops.h>
46945Srugrat #include <sys/sunddi.h>
47945Srugrat #include <sys/ddi_impldefs.h>
48945Srugrat #include <sys/fs/snode.h>
49945Srugrat #include <sys/pci.h>
50945Srugrat #include <sys/vmsystm.h>
51*5084Sjohnlev #include <sys/int_fmtio.h>
52945Srugrat #include "gfx_private.h"
53945Srugrat
54*5084Sjohnlev #ifdef __xpv
55*5084Sjohnlev #include <sys/hypervisor.h>
56*5084Sjohnlev #endif
57*5084Sjohnlev
58945Srugrat /*
59945Srugrat * Create a dummy ddi_umem_cookie given to gfxp_devmap_umem_setup().
60945Srugrat */
61945Srugrat ddi_umem_cookie_t
gfxp_umem_cookie_init(caddr_t kva,size_t size)62945Srugrat gfxp_umem_cookie_init(caddr_t kva, size_t size)
63945Srugrat {
64945Srugrat struct ddi_umem_cookie *umem_cookie;
65945Srugrat
66945Srugrat umem_cookie = kmem_zalloc(sizeof (struct ddi_umem_cookie), KM_SLEEP);
67945Srugrat
68945Srugrat if (umem_cookie == NULL)
69945Srugrat return (NULL);
70945Srugrat
71945Srugrat umem_cookie->cvaddr = kva;
72945Srugrat umem_cookie->type = KMEM_NON_PAGEABLE;
73945Srugrat umem_cookie->size = size;
74945Srugrat
75945Srugrat return ((ddi_umem_cookie_t *)umem_cookie);
76945Srugrat }
77945Srugrat
78945Srugrat void
gfxp_umem_cookie_destroy(ddi_umem_cookie_t cookie)79945Srugrat gfxp_umem_cookie_destroy(ddi_umem_cookie_t cookie)
80945Srugrat {
81945Srugrat kmem_free(cookie, sizeof (struct ddi_umem_cookie));
82945Srugrat }
83945Srugrat
84945Srugrat /*
851900Seota * called by driver devmap routine to pass kernel virtual address mapping
861900Seota * info to the framework.
87945Srugrat */
88945Srugrat /*ARGSUSED*/
89945Srugrat int
gfxp_devmap_umem_setup(devmap_cookie_t dhc,dev_info_t * dip,struct devmap_callback_ctl * callbackops,ddi_umem_cookie_t cookie,offset_t off,size_t len,uint_t maxprot,uint_t flags,ddi_device_acc_attr_t * accattrp)90945Srugrat gfxp_devmap_umem_setup(devmap_cookie_t dhc, dev_info_t *dip,
91945Srugrat struct devmap_callback_ctl *callbackops, ddi_umem_cookie_t cookie,
92945Srugrat offset_t off, size_t len, uint_t maxprot, uint_t flags,
93945Srugrat ddi_device_acc_attr_t *accattrp)
94945Srugrat {
951900Seota uint_t l_flags = flags & ~IOMEM_DATA_MASK; /* clear cache attrs */
961900Seota int e;
97945Srugrat
98945Srugrat /*
991900Seota * Set an appropriate attribute from devacc_attr_dataorder
1001900Seota * to keep compatibility. The cache attributes are igonred
1011900Seota * if specified.
102945Srugrat */
103945Srugrat if (accattrp != NULL) {
1041900Seota if (accattrp->devacc_attr_dataorder == DDI_STRICTORDER_ACC) {
1051900Seota l_flags |= IOMEM_DATA_UNCACHED;
1061900Seota } else if (accattrp->devacc_attr_dataorder ==
1071900Seota DDI_MERGING_OK_ACC) {
1081900Seota l_flags |= IOMEM_DATA_UC_WR_COMBINE;
1091900Seota } else {
1101900Seota l_flags |= IOMEM_DATA_CACHED;
111945Srugrat }
112945Srugrat }
113945Srugrat
1141900Seota e = devmap_umem_setup(dhc, dip, callbackops, cookie, off, len, maxprot,
1151900Seota l_flags, accattrp);
1161900Seota return (e);
117945Srugrat }
1183987Srugrat
1193987Srugrat /*
1203987Srugrat * Replacement for devmap_devmem_setup() which will map a machine address
1213987Srugrat * instead of a register set/offset.
1223987Srugrat */
1233987Srugrat void
gfxp_map_devmem(devmap_cookie_t dhc,gfx_maddr_t maddr,size_t length,ddi_device_acc_attr_t * attrp)1243987Srugrat gfxp_map_devmem(devmap_cookie_t dhc, gfx_maddr_t maddr, size_t length,
1253987Srugrat ddi_device_acc_attr_t *attrp)
1263987Srugrat {
1273987Srugrat devmap_handle_t *dhp = (devmap_handle_t *)dhc;
1283987Srugrat pfn_t pfn;
1293987Srugrat
1303987Srugrat
131*5084Sjohnlev #ifdef __xpv
132*5084Sjohnlev ASSERT(DOMAIN_IS_INITDOMAIN(xen_info));
133*5084Sjohnlev pfn = xen_assign_pfn(mmu_btop(maddr));
134*5084Sjohnlev #else
1353987Srugrat pfn = mmu_btop(maddr);
136*5084Sjohnlev #endif
1373987Srugrat
1383987Srugrat dhp->dh_pfn = pfn;
1393987Srugrat dhp->dh_len = mmu_ptob(mmu_btopr(length));
1403987Srugrat dhp->dh_roff = 0;
1413987Srugrat
1423987Srugrat #ifndef DEVMAP_DEVMEM_COOKIE
1433987Srugrat #define DEVMAP_DEVMEM_COOKIE ((ddi_umem_cookie_t)0x1) /* XXPV */
1443987Srugrat #endif /* DEVMAP_DEVMEM_COOKIE */
1453987Srugrat dhp->dh_cookie = DEVMAP_DEVMEM_COOKIE;
1463987Srugrat /*LINTED: E_EXPR_NULL_EFFECT*/
1473987Srugrat dhp->dh_flags |= DEVMAP_DEFAULTS;
1483987Srugrat dhp->dh_maxprot = PROT_ALL & dhp->dh_orig_maxprot;
1493987Srugrat
1503987Srugrat /* no callbacks needed */
1513987Srugrat bzero(&dhp->dh_callbackops, sizeof (struct devmap_callback_ctl));
1523987Srugrat
1533987Srugrat switch (attrp->devacc_attr_dataorder) {
1543987Srugrat case DDI_UNORDERED_OK_ACC:
1553987Srugrat dhp->dh_hat_attr = HAT_UNORDERED_OK;
1563987Srugrat break;
1573987Srugrat case DDI_MERGING_OK_ACC:
1583987Srugrat dhp->dh_hat_attr = HAT_MERGING_OK;
1593987Srugrat break;
1603987Srugrat case DDI_LOADCACHING_OK_ACC:
1613987Srugrat dhp->dh_hat_attr = HAT_LOADCACHING_OK;
1623987Srugrat break;
1633987Srugrat case DDI_STORECACHING_OK_ACC:
1643987Srugrat dhp->dh_hat_attr = HAT_STORECACHING_OK;
1653987Srugrat break;
1663987Srugrat case DDI_STRICTORDER_ACC:
1673987Srugrat default:
1683987Srugrat dhp->dh_hat_attr = HAT_STRICTORDER;
1693987Srugrat }
1703987Srugrat
1713987Srugrat /* don't use large pages */
1723987Srugrat dhp->dh_mmulevel = 0;
1733987Srugrat dhp->dh_flags &= ~DEVMAP_FLAG_LARGE;
1743987Srugrat
1753987Srugrat dhp->dh_flags |= DEVMAP_SETUP_DONE;
1763987Srugrat }
177