3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * CDDL HEADER START
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * The contents of this file are subject to the terms of the
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Common Development and Distribution License (the "License").
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * You may not use this file except in compliance with the License.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * or http://www.opensolaris.org/os/licensing.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * See the License for the specific language governing permissions
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * and limitations under the License.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * When distributing Covered Code, include this CDDL HEADER in each
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * If applicable, add the following below this CDDL HEADER, with the
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * fields enclosed by brackets "[]" replaced with your own identifying
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * information: Portions Copyright [yyyy] [name of copyright owner]
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * CDDL HEADER END
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * Portions Copyright (c) 2010, Oracle and/or its affiliates.
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * All rights reserved.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Copyright (c) 2009, Intel Corporation.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * All rights reserved.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Intel IOMMU implementation
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * This file contains Intel IOMMU code exported
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * to the rest of the system and code that deals
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * with the Intel IOMMU as a whole.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/conf.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/modctl.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/pci.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/pci_impl.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/sysmacros.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/ddi.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/ddidmareq.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/ddi_impldefs.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/ddifm.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/sunndi.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/debug.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/fm/protocol.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/note.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/apic.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <vm/hat_i86.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/smp_impldefs.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/spl.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/archsystm.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/x86_archext.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/avl.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/bootconf.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/bootinfo.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/atomic.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde#include <sys/immu.h>
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ########################### Globals and tunables ######################## */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Global switches (boolean) that can be toggled either via boot options
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * or via /etc/system or kmdb
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* Various features */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegdeboolean_t immu_enable = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_dvma_enable = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* accessed in other files so not static */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_gfxdvma_enable = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_intrmap_enable = B_FALSE;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenboolean_t immu_qinv_enable = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* various quirks that need working around */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* XXX We always map page 0 read/write for now */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_quirk_usbpage0 = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_quirk_usbrmrr = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_quirk_usbfullpa;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_quirk_mobile4;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* debug messages */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_dmar_print;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde/* Tunables */
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegdeint64_t immu_flush_gran = 5;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenimmu_flags_t immu_global_dvma_flags;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ############ END OPTIONS section ################ */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Global used internally by Intel IOMMU code
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdedev_info_t *root_devinfo;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdekmutex_t immu_lock;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdelist_t immu_list;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_setup;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_running;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeboolean_t immu_quiesced;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ######################## END Globals and tunables ###################### */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* Globals used only in this file */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic char **black_array;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic uint_t nblacks;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic char **unity_driver_array;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic uint_t nunity;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic char **xlate_driver_array;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic uint_t nxlate;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenstatic char **premap_driver_array;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenstatic uint_t npremap;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenstatic char **nopremap_driver_array;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenstatic uint_t nnopremap;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ###################### Utility routines ############################# */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check if the device has mobile 4 chipset
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic int
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdecheck_mobile4(dev_info_t *dip, void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde _NOTE(ARGUNUSED(arg));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int vendor, device;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int *ip = (int *)arg;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde vendor = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "vendor-id", -1);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde device = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "device-id", -1);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (vendor == 0x8086 && device == 0x2a40) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *ip = B_TRUE;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden ddi_err(DER_NOTE, dip, "iommu: Mobile 4 chipset detected. "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "Force setting IOMMU write buffer");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (DDI_WALK_TERMINATE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde } else {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (DDI_WALK_CONTINUE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdemap_bios_rsvd_mem(dev_info_t *dip)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde struct memlist *mp;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden /*
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden * Make sure the domain for the device is set up before
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden * mapping anything.
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden */
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden (void) immu_dvma_device_setup(dip, 0);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde memlist_read_lock();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mp = bios_rsvd;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde while (mp != NULL) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde memrng_t mrng = {0};
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden ddi_err(DER_LOG, dip, "iommu: Mapping BIOS rsvd range "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "[0x%" PRIx64 " - 0x%"PRIx64 "]\n", mp->ml_address,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mp->ml_address + mp->ml_size);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde mrng.mrng_start = IMMU_ROUNDOWN(mp->ml_address);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde mrng.mrng_npages = IMMU_ROUNDUP(mp->ml_size) / IMMU_PAGESIZE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden (void) immu_map_memrange(dip, &mrng);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mp = mp->ml_next;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde memlist_read_unlock();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde/*
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * Check if the driver requests a specific type of mapping.
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde */
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde/*ARGSUSED*/
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegdestatic void
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindencheck_conf(dev_info_t *dip, void *arg)
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde{
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi_t *immu_devi;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden const char *dname;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden uint_t i;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden int hasmapprop = 0, haspreprop = 0;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden boolean_t old_premap;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde /*
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * Only PCI devices can use an IOMMU. Legacy ISA devices
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * are handled in check_lpc.
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde */
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (!DEVI_IS_PCI(dip))
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden dname = ddi_driver_name(dip);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (dname == NULL)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi = immu_devi_get(dip);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden for (i = 0; i < nunity; i++) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (strcmp(unity_driver_array[i], dname) == 0) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden hasmapprop = 1;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi->imd_dvma_flags |= IMMU_FLAGS_UNITY;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden for (i = 0; i < nxlate; i++) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (strcmp(xlate_driver_array[i], dname) == 0) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden hasmapprop = 1;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi->imd_dvma_flags &= ~IMMU_FLAGS_UNITY;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde }
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden old_premap = immu_devi->imd_use_premap;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden for (i = 0; i < nnopremap; i++) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (strcmp(nopremap_driver_array[i], dname) == 0) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden haspreprop = 1;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_devi->imd_use_premap = B_FALSE;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden for (i = 0; i < npremap; i++) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (strcmp(premap_driver_array[i], dname) == 0) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden haspreprop = 1;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_devi->imd_use_premap = B_TRUE;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden /*
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * Report if we changed the value from the default.
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden */
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (hasmapprop && (immu_devi->imd_dvma_flags ^ immu_global_dvma_flags))
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_err(DER_LOG, dip, "using %s DVMA mapping",
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi->imd_dvma_flags & IMMU_FLAGS_UNITY ?
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden DDI_DVMA_MAPTYPE_UNITY : DDI_DVMA_MAPTYPE_XLATE);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (haspreprop && (immu_devi->imd_use_premap != old_premap))
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden ddi_err(DER_LOG, dip, "%susing premapped DVMA space",
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_devi->imd_use_premap ? "" : "not ");
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde}
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check if the device is USB controller
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*ARGSUSED*/
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdecheck_usb(dev_info_t *dip, void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde const char *drv = ddi_driver_name(dip);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi_t *immu_devi;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (drv == NULL ||
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde (strcmp(drv, "uhci") != 0 && strcmp(drv, "ohci") != 0 &&
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde strcmp(drv, "ehci") != 0)) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi = immu_devi_get(dip);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden /*
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * If unit mappings are already specified, globally or
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * locally, we're done here, since that covers both
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * quirks below.
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden */
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (immu_devi->imd_dvma_flags & IMMU_FLAGS_UNITY)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* This must come first since it does unity mapping */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_quirk_usbfullpa == B_TRUE) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi->imd_dvma_flags |= IMMU_FLAGS_UNITY;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else if (immu_quirk_usbrmrr == B_TRUE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_LOG, dip, "Applying USB RMRR quirk");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde map_bios_rsvd_mem(dip);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check if the device is a LPC device
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*ARGSUSED*/
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdecheck_lpc(dev_info_t *dip, void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_devi_t *immu_devi;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_devi = immu_devi_get(dip);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_devi->imd_lpc == B_TRUE) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden ddi_err(DER_LOG, dip, "iommu: Found LPC device");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* This will put the immu_devi on the LPC "specials" list */
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden (void) immu_dvma_device_setup(dip, IMMU_FLAGS_SLEEP);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check if the device is a GFX device
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*ARGSUSED*/
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdecheck_gfx(dev_info_t *dip, void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_devi_t *immu_devi;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_devi = immu_devi_get(dip);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_devi->imd_display == B_TRUE) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_devi->imd_dvma_flags |= IMMU_FLAGS_UNITY;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden ddi_err(DER_LOG, dip, "iommu: Found GFX device");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* This will put the immu_devi on the GFX "specials" list */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde (void) immu_dvma_get_immu(dip, IMMU_FLAGS_SLEEP);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdewalk_tree(int (*f)(dev_info_t *, void *), void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int count;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ndi_devi_enter(root_devinfo, &count);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_walk_devs(ddi_get_child(root_devinfo), f, arg);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ndi_devi_exit(root_devinfo, count);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic int
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdecheck_pre_setup_quirks(dev_info_t *dip, void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* just 1 check right now */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (check_mobile4(dip, arg));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic int
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdecheck_pre_startup_quirks(dev_info_t *dip, void *arg)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_devi_set(dip, IMMU_FLAGS_SLEEP) != DDI_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_PANIC, dip, "Failed to get immu_devi");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde check_gfx(dip, arg);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde check_lpc(dip, arg);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden check_conf(dip, arg);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden check_usb(dip, arg);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (DDI_WALK_CONTINUE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdepre_setup_quirks(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde walk_tree(check_pre_setup_quirks, &immu_quirk_mobile4);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdepre_startup_quirks(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde walk_tree(check_pre_startup_quirks, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dmar_rmrr_map();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic int
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenget_conf_str(char *bopt, char **val)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden{
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden int ret;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden /*
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * Check the rootnex.conf property
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * Fake up a dev_t since searching the global
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden * property list needs it
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden */
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ret = ddi_prop_lookup_string(
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden makedevice(ddi_name_to_major("rootnex"), 0),
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden root_devinfo, DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL,
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden bopt, val);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return (ret);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden}
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde/*
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * get_conf_opt()
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * get a rootnex.conf setting (always a boolean)
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegdestatic void
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegdeget_conf_opt(char *bopt, boolean_t *kvar)
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde{
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde char *val = NULL;
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde /*
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * Check the rootnex.conf property
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * Fake up a dev_t since searching the global
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * property list needs it
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde */
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (get_conf_str(bopt, &val) != DDI_PROP_SUCCESS)
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde return;
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde if (strcmp(val, "true") == 0) {
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde *kvar = B_TRUE;
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde } else if (strcmp(val, "false") == 0) {
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde *kvar = B_FALSE;
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde } else {
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde ddi_err(DER_WARN, NULL, "rootnex.conf switch %s=\"%s\" ",
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde "is not set to true or false. Ignoring option.",
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde bopt, val);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde }
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde ddi_prop_free(val);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde}
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * get_bootopt()
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * check a boot option (always a boolean)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic int
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenget_boot_str(char *bopt, char **val)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden{
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden int ret;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ret = ddi_prop_lookup_string(DDI_DEV_T_ANY, root_devinfo,
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden DDI_PROP_DONTPASS, bopt, val);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return (ret);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden}
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeget_bootopt(char *bopt, boolean_t *kvar)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde char *val = NULL;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * All boot options set at the GRUB menu become
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * properties on the rootnex.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (get_boot_str(bopt, &val) != DDI_PROP_SUCCESS)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (strcmp(val, "true") == 0) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden *kvar = B_TRUE;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else if (strcmp(val, "false") == 0) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden *kvar = B_FALSE;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_err(DER_WARN, NULL, "boot option %s=\"%s\" ",
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden "is not set to true or false. Ignoring option.",
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden bopt, val);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_prop_free(val);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden}
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic void
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenget_boot_dvma_mode(void)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden{
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden char *val = NULL;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (get_boot_str(DDI_DVMA_MAPTYPE_ROOTNEX_PROP, &val)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden != DDI_PROP_SUCCESS)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (strcmp(val, DDI_DVMA_MAPTYPE_UNITY) == 0) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_global_dvma_flags |= IMMU_FLAGS_UNITY;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else if (strcmp(val, DDI_DVMA_MAPTYPE_XLATE) == 0) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_global_dvma_flags &= ~IMMU_FLAGS_UNITY;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_err(DER_WARN, NULL, "bad value \"%s\" for boot option %s",
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden val, DDI_DVMA_MAPTYPE_ROOTNEX_PROP);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_prop_free(val);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic void
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenget_conf_dvma_mode(void)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden{
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden char *val = NULL;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (get_conf_str(DDI_DVMA_MAPTYPE_ROOTNEX_PROP, &val)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden != DDI_PROP_SUCCESS)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden return;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (strcmp(val, DDI_DVMA_MAPTYPE_UNITY) == 0) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_global_dvma_flags |= IMMU_FLAGS_UNITY;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else if (strcmp(val, DDI_DVMA_MAPTYPE_XLATE) == 0) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden immu_global_dvma_flags &= ~IMMU_FLAGS_UNITY;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden } else {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_err(DER_WARN, NULL, "bad value \"%s\" for rootnex "
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden "option %s", val, DDI_DVMA_MAPTYPE_ROOTNEX_PROP);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden ddi_prop_free(val);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden}
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegdestatic void
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegdeget_conf_tunables(char *bopt, int64_t *ivar)
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde{
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde int64_t *iarray;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde uint_t n;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde /*
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde * Check the rootnex.conf property
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde * Fake up a dev_t since searching the global
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde * property list needs it
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde */
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde if (ddi_prop_lookup_int64_array(
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde makedevice(ddi_name_to_major("rootnex"), 0), root_devinfo,
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL, bopt,
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde &iarray, &n) != DDI_PROP_SUCCESS) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde return;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde }
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde if (n != 1) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde ddi_err(DER_WARN, NULL, "More than one value specified for "
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde "%s property. Ignoring and using default",
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde "immu-flush-gran");
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde ddi_prop_free(iarray);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde return;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde }
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde if (iarray[0] < 0) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde ddi_err(DER_WARN, NULL, "Negative value specified for "
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde "%s property. Inoring and Using default value",
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde "immu-flush-gran");
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde ddi_prop_free(iarray);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde return;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde }
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde *ivar = iarray[0];
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde ddi_prop_free(iarray);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde}
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegdestatic void
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegderead_conf_options(void)
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde{
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde /* enable/disable options */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-enable", &immu_enable);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-dvma-enable", &immu_dvma_enable);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-gfxdvma-enable", &immu_gfxdvma_enable);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-intrmap-enable", &immu_intrmap_enable);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-qinv-enable", &immu_qinv_enable);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde /* workaround switches */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-quirk-usbpage0", &immu_quirk_usbpage0);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-quirk-usbfullpa", &immu_quirk_usbfullpa);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-quirk-usbrmrr", &immu_quirk_usbrmrr);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde /* debug printing */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_opt("immu-dmar-print", &immu_dmar_print);
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde /* get tunables */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde get_conf_tunables("immu-flush-gran", &immu_flush_gran);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden get_conf_dvma_mode();
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde}
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegderead_boot_options(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* enable/disable options */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-enable", &immu_enable);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-dvma-enable", &immu_dvma_enable);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-gfxdvma-enable", &immu_gfxdvma_enable);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-intrmap-enable", &immu_intrmap_enable);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-qinv-enable", &immu_qinv_enable);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* workaround switches */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-quirk-usbpage0", &immu_quirk_usbpage0);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-quirk-usbfullpa", &immu_quirk_usbfullpa);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-quirk-usbrmrr", &immu_quirk_usbrmrr);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* debug printing */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde get_bootopt("immu-dmar-print", &immu_dmar_print);
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden get_boot_dvma_mode();
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden}
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenstatic void
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Lindenmapping_list_setup(void)
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden{
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden char **string_array;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden uint_t nstrings;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (ddi_prop_lookup_string_array(
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden makedevice(ddi_name_to_major("rootnex"), 0), root_devinfo,
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL,
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden "immu-dvma-unity-drivers",
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden &string_array, &nstrings) == DDI_PROP_SUCCESS) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden unity_driver_array = string_array;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden nunity = nstrings;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden }
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden if (ddi_prop_lookup_string_array(
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden makedevice(ddi_name_to_major("rootnex"), 0), root_devinfo,
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL,
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden "immu-dvma-xlate-drivers",
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden &string_array, &nstrings) == DDI_PROP_SUCCESS) {
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden xlate_driver_array = string_array;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden nxlate = nstrings;
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (ddi_prop_lookup_string_array(
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden makedevice(ddi_name_to_major("rootnex"), 0), root_devinfo,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden "immu-dvma-premap-drivers",
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden &string_array, &nstrings) == DDI_PROP_SUCCESS) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden premap_driver_array = string_array;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden npremap = nstrings;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (ddi_prop_lookup_string_array(
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden makedevice(ddi_name_to_major("rootnex"), 0), root_devinfo,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden "immu-dvma-nopremap-drivers",
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden &string_array, &nstrings) == DDI_PROP_SUCCESS) {
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden nopremap_driver_array = string_array;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden nnopremap = nstrings;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Note, this will not catch hardware not enumerated
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * in early boot
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic boolean_t
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeblacklisted_driver(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde char **strptr;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int i;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde major_t maj;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* need at least 2 strings */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (nblacks < 2) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_FALSE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (i = 0; nblacks - i > 1; i++) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde strptr = &black_array[i];
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (strcmp(*strptr++, "DRIVER") == 0) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if ((maj = ddi_name_to_major(*strptr++))
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde != DDI_MAJOR_T_NONE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* is there hardware bound to this drvr */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (devnamesp[maj].dn_head != NULL) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_TRUE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde i += 1; /* for loop adds 1, so add only 1 here */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_FALSE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic boolean_t
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeblacklisted_smbios(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde id_t smid;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde smbios_hdl_t *smhdl;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde smbios_info_t sminf;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde smbios_system_t smsys;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde char *mfg, *product, *version;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde char **strptr;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int i;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* need at least 4 strings for this setting */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (nblacks < 4) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_FALSE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde smhdl = smbios_open(NULL, SMB_VERSION, ksmbios_flags, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (smhdl == NULL ||
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde (smid = smbios_info_system(smhdl, &smsys)) == SMB_ERR ||
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde smbios_info_common(smhdl, smid, &sminf) == SMB_ERR) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_FALSE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mfg = (char *)sminf.smbi_manufacturer;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde product = (char *)sminf.smbi_product;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde version = (char *)sminf.smbi_version;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_CONT, NULL, "?System SMBIOS information:\n");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_CONT, NULL, "?Manufacturer = <%s>\n", mfg);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_CONT, NULL, "?Product = <%s>\n", product);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_CONT, NULL, "?Version = <%s>\n", version);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (i = 0; nblacks - i > 3; i++) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde strptr = &black_array[i];
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (strcmp(*strptr++, "SMBIOS") == 0) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (strcmp(*strptr++, mfg) == 0 &&
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ((char *)strptr == '\0' ||
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde strcmp(*strptr++, product) == 0) &&
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ((char *)strptr == '\0' ||
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde strcmp(*strptr++, version) == 0)) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_TRUE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde i += 3;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_FALSE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic boolean_t
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeblacklisted_acpi(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (nblacks == 0) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (B_FALSE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (immu_dmar_blacklisted(black_array, nblacks));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check if system is blacklisted by Intel IOMMU driver
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * i.e. should Intel IOMMU be disabled on this system
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Currently a system can be blacklistd based on the
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * following bases:
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * 1. DMAR ACPI table information.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * This information includes things like
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * manufacturer and revision number. If rootnex.conf
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * has matching info set in its blacklist property
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * then Intel IOMMu will be disabled
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * 2. SMBIOS information
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * 3. Driver installed - useful if a particular
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * driver or hardware is toxic if Intel IOMMU
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * is turned on.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeblacklist_setup(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde char **string_array;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde uint_t nstrings;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check the rootnex.conf blacklist property.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Fake up a dev_t since searching the global
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * property list needs it
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (ddi_prop_lookup_string_array(
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde makedevice(ddi_name_to_major("rootnex"), 0), root_devinfo,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde DDI_PROP_DONTPASS | DDI_PROP_ROOTNEX_GLOBAL, "immu-blacklist",
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde &string_array, &nstrings) != DDI_PROP_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* smallest blacklist criteria works with multiples of 2 */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (nstrings % 2 != 0) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_WARN, NULL, "Invalid IOMMU blacklist "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "rootnex.conf: number of strings must be a "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "multiple of 2");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_prop_free(string_array);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde black_array = string_array;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde nblacks = nstrings;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeblacklist_destroy(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (black_array) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_prop_free(black_array);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde black_array = NULL;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde nblacks = 0;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden}
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenstatic char *
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenimmu_alloc_name(const char *str, int instance)
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden{
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden size_t slen;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden char *s;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden slen = strlen(str) + IMMU_ISTRLEN + 1;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden s = kmem_zalloc(slen, VM_SLEEP);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (s != NULL)
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden (void) snprintf(s, slen, "%s%d", str, instance);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden return (s);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Now set all the fields in the order they are defined
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * We do this only as a defensive-coding practice, it is
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * not a correctness issue.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void *
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_state_alloc(int seg, void *dmar_unit)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_t *immu;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden char *nodename, *hcachename, *pcachename;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden int instance;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde dmar_unit = immu_dmar_walk_units(seg, dmar_unit);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (dmar_unit == NULL) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* No more IOMMUs in this segment */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu = kmem_zalloc(sizeof (immu_t), KM_SLEEP);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_init(&(immu->immu_lock), NULL, MUTEX_DRIVER, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu->immu_dmar_unit = dmar_unit;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu->immu_dip = immu_dmar_unit_dip(dmar_unit);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden nodename = ddi_node_name(immu->immu_dip);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden instance = ddi_get_instance(immu->immu_dip);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu->immu_name = immu_alloc_name(nodename, instance);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (immu->immu_name == NULL)
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden return (NULL);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * the immu_intr_lock mutex is grabbed by the IOMMU
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * unit's interrupt handler so we need to use an
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * interrupt cookie for the mutex
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_init(&(immu->immu_intr_lock), NULL, MUTEX_DRIVER,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde (void *)ipltospl(IMMU_INTR_IPL));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* IOMMU regs related */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_init(&(immu->immu_regs_lock), NULL, MUTEX_DEFAULT, NULL);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde cv_init(&(immu->immu_regs_cv), NULL, CV_DEFAULT, NULL);
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde immu->immu_regs_busy = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* DVMA related */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu->immu_dvma_coherent = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* DVMA context related */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde rw_init(&(immu->immu_ctx_rwlock), NULL, RW_DEFAULT, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* DVMA domain related */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde list_create(&(immu->immu_domain_list), sizeof (domain_t),
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde offsetof(domain_t, dom_immu_node));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* DVMA special device lists */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu->immu_dvma_gfx_only = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde list_create(&(immu->immu_dvma_lpc_list), sizeof (immu_devi_t),
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde offsetof(immu_devi_t, imd_spc_node));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde list_create(&(immu->immu_dvma_gfx_list), sizeof (immu_devi_t),
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde offsetof(immu_devi_t, imd_spc_node));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* interrupt remapping related */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_init(&(immu->immu_intrmap_lock), NULL, MUTEX_DEFAULT, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* qinv related */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_init(&(immu->immu_qinv_lock), NULL, MUTEX_DEFAULT, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * insert this immu unit into the system-wide list
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde list_insert_tail(&immu_list, immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden pcachename = immu_alloc_name("immu_pgtable_cache", instance);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (pcachename == NULL)
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden return (NULL);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden hcachename = immu_alloc_name("immu_hdl_cache", instance);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden if (hcachename == NULL)
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden return (NULL);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu->immu_pgtable_cache = kmem_cache_create(pcachename,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden sizeof (pgtable_t), 0, pgtable_ctor, pgtable_dtor, NULL, immu,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden NULL, 0);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu->immu_hdl_cache = kmem_cache_create(hcachename,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden sizeof (immu_hdl_priv_t), 64, immu_hdl_priv_ctor,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden NULL, NULL, immu, NULL, 0);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden ddi_err(DER_LOG, immu->immu_dip, "unit setup");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dmar_set_immu(dmar_unit, immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (dmar_unit);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_subsystems_setup(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int seg;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde void *unit_hdl;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_VERB, NULL,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden "Creating state structures for Intel IOMMU units");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_init(&immu_lock, NULL, MUTEX_DEFAULT, NULL);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde list_create(&immu_list, sizeof (immu_t), offsetof(immu_t, immu_node));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde unit_hdl = NULL;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (seg = 0; seg < IMMU_MAXSEG; seg++) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde while (unit_hdl = immu_state_alloc(seg, unit_hdl)) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_regs_setup(&immu_list); /* subsequent code needs this first */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dvma_setup(&immu_list);
d2256d265bf2bcad0d811b81411de3802a4b97c6Frank Van Der Linden if (immu_qinv_setup(&immu_list) == DDI_SUCCESS)
d2256d265bf2bcad0d811b81411de3802a4b97c6Frank Van Der Linden immu_intrmap_setup(&immu_list);
d2256d265bf2bcad0d811b81411de3802a4b97c6Frank Van Der Linden else
d2256d265bf2bcad0d811b81411de3802a4b97c6Frank Van Der Linden immu_intrmap_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * immu_subsystems_startup()
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * startup all units that were setup
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdestatic void
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_subsystems_startup(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_t *immu;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden iommulib_ops_t *iommulib_ops;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dmar_startup();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu = list_head(&immu_list);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (; immu; immu = list_next(&immu_list, immu)) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_intr_register(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dvma_startup(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_intrmap_startup(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_qinv_startup(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Set IOMMU unit's regs to do
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * the actual startup. This will
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * set immu->immu_running field
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * if the unit is successfully
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * started
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_regs_startup(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&(immu->immu_lock));
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden iommulib_ops = kmem_alloc(sizeof (iommulib_ops_t), KM_SLEEP);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden *iommulib_ops = immulib_ops;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden iommulib_ops->ilops_data = (void *)immu;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden (void) iommulib_iommu_register(immu->immu_dip, iommulib_ops,
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden &immu->immu_iommulib_handle);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ################## Intel IOMMU internal interfaces ###################### */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Internal interfaces for IOMMU code (i.e. not exported to rootnex
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * or rest of system)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * ddip can be NULL, in which case we walk up until we find the root dip
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * NOTE: We never visit the root dip since its not a hardware node
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeint
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_walk_ancestor(
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde dev_info_t *rdip,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde dev_info_t *ddip,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int (*func)(dev_info_t *, void *arg),
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde void *arg,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int *lvlp,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_flags_t immu_flags)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde dev_info_t *pdip;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int level;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int error = DDI_SUCCESS;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* ddip and immu can be NULL */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* Hold rdip so that branch is not detached */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ndi_hold_devi(rdip);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (pdip = rdip, level = 1; pdip && pdip != root_devinfo;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde pdip = ddi_get_parent(pdip), level++) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_devi_set(pdip, immu_flags) != DDI_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde error = DDI_FAILURE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde break;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (func(pdip, arg) == DDI_WALK_TERMINATE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde break;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_flags & IMMU_FLAGS_DONTPASS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde break;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (pdip == ddip) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde break;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ndi_rele_devi(rdip);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (lvlp)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde *lvlp = level;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (error);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ######################## Intel IOMMU entry points ####################### */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * immu_init()
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * called from rootnex_attach(). setup but don't startup the Intel IOMMU
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * This is the first function called in Intel IOMMU code
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdevoid
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_init(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde char *phony_reg = "A thing of beauty is a joy forever";
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* Set some global shorthands that are needed by all of IOMMU code */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde root_devinfo = ddi_root_node();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Intel IOMMU only supported only if MMU(CPU) page size is ==
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * IOMMU pages size.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*LINTED*/
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (MMU_PAGESIZE != IMMU_PAGESIZE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_WARN, NULL,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "MMU page size (%d) is not equal to\n"
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "IOMMU page size (%d). "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "Disabling Intel IOMMU. ",
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde MMU_PAGESIZE, IMMU_PAGESIZE);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde /*
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * Read rootnex.conf options. Do this before
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde * boot options so boot options can override .conf options.
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde */
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde read_conf_options();
3adb2334459b30a605b8d375be6c3f3a3ec9ef38Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * retrieve the Intel IOMMU boot options.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Do this before parsing immu ACPI table
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * as a boot option could potentially affect
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * ACPI parsing.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_CONT, NULL, "?Reading Intel IOMMU boot options\n");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde read_boot_options();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check the IOMMU enable boot-option first.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * This is so that we can skip parsing the ACPI table
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * if necessary because that may cause problems in
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * systems with buggy BIOS or ACPI tables
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_enable == B_FALSE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
c94adbf911e89a6f97faa6b966bc20f795e2f959Frank Van Der Linden if (immu_intrmap_enable == B_TRUE)
c94adbf911e89a6f97faa6b966bc20f795e2f959Frank Van Der Linden immu_qinv_enable = B_TRUE;
c94adbf911e89a6f97faa6b966bc20f795e2f959Frank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Next, check if the system even has an Intel IOMMU
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * We use the presence or absence of the IOMMU ACPI
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * table to detect Intel IOMMU.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_dmar_setup() != DDI_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden mapping_list_setup();
9e986f0e5fb5e5ac09af90cd3b63f7836d983f9dFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check blacklists
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde blacklist_setup();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (blacklisted_smbios() == B_TRUE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde blacklist_destroy();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (blacklisted_driver() == B_TRUE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde blacklist_destroy();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Read the "raw" DMAR ACPI table to get information
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * and convert into a form we can use.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_dmar_parse() != DDI_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde blacklist_destroy();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * now that we have processed the ACPI table
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * check if we need to blacklist this system
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * based on ACPI info
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (blacklisted_acpi() == B_TRUE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dmar_destroy();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde blacklist_destroy();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_enable = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde blacklist_destroy();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Check if system has HW quirks.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde pre_setup_quirks();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* Now do the rest of the setup */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_subsystems_setup();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Now that the IMMU is setup, create a phony
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * reg prop so that suspend/resume works
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (ddi_prop_update_byte_array(DDI_DEV_T_NONE, root_devinfo, "reg",
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde (uchar_t *)phony_reg, strlen(phony_reg) + 1) != DDI_PROP_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_PANIC, NULL, "Failed to create reg prop for "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "rootnex node");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*NOTREACHED*/
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_setup = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * immu_startup()
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * called directly by boot code to startup
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * all units of the IOMMU
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdevoid
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_startup(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * If IOMMU is disabled, do nothing
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_enable == B_FALSE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_setup == B_FALSE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_WARN, NULL, "Intel IOMMU not setup, "
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden "skipping IOMMU startup");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde pre_startup_quirks();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_CONT, NULL,
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "?Starting Intel IOMMU (dmar) units...\n");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_subsystems_startup();
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_running = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Hook to notify IOMMU code of device tree changes
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdevoid
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_device_tree_changed(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_setup == B_FALSE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ddi_err(DER_WARN, NULL, "Intel IOMMU currently "
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde "does not use device tree updates");
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Hook to notify IOMMU code of memory changes
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdevoid
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_physmem_update(uint64_t addr, uint64_t size)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_setup == B_FALSE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_dvma_physmem_update(addr, size);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * immu_quiesce()
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * quiesce all units that are running
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeint
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_quiesce(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_t *immu;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int ret = DDI_SUCCESS;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy if (immu_running == B_FALSE) {
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy mutex_exit(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (DDI_SUCCESS);
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu = list_head(&immu_list);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (; immu; immu = list_next(&immu_list, immu)) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* if immu is not running, we dont quiesce */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu->immu_regs_running == B_FALSE)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde continue;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* flush caches */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde rw_enter(&(immu->immu_ctx_rwlock), RW_WRITER);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_flush_context_gbl(immu, &immu->immu_ctx_inv_wait);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_flush_iotlb_gbl(immu, &immu->immu_ctx_inv_wait);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde rw_exit(&(immu->immu_ctx_rwlock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_regs_wbf_flush(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Set IOMMU unit's regs to do
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * the actual shutdown.
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_regs_shutdown(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_regs_suspend(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* if immu is still running, we failed */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu->immu_regs_running == B_TRUE)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ret = DDI_FAILURE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde else
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu->immu_regs_quiesced = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (ret == DDI_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_running = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_quiesced = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy mutex_exit(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (ret);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * immu_unquiesce()
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * unquiesce all units
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeint
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegdeimmu_unquiesce(void)
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde{
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_t *immu;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde int ret = DDI_SUCCESS;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy if (immu_quiesced == B_FALSE) {
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy mutex_exit(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (DDI_SUCCESS);
96992ee7c93bf61dc0579501855b17b4d249f22dEthindra Ramamurthy }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu = list_head(&immu_list);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde for (; immu; immu = list_next(&immu_list, immu)) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_enter(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* if immu was not quiesced, i.e was not running before */
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde if (immu->immu_regs_quiesced == B_FALSE) {
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde mutex_exit(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde continue;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu_regs_resume(immu) != DDI_SUCCESS) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ret = DDI_FAILURE;
e03dceed3deb85ad561202c77277e701f763fa13Vikram Hegde mutex_exit(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde continue;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /* flush caches before unquiesce */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde rw_enter(&(immu->immu_ctx_rwlock), RW_WRITER);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_flush_context_gbl(immu, &immu->immu_ctx_inv_wait);
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden immu_flush_iotlb_gbl(immu, &immu->immu_ctx_inv_wait);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde rw_exit(&(immu->immu_ctx_rwlock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde /*
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * Set IOMMU unit's regs to do
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * the actual startup. This will
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * set immu->immu_regs_running field
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * if the unit is successfully
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde * started
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde */
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_regs_startup(immu);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde if (immu->immu_regs_running == B_FALSE) {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde ret = DDI_FAILURE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde } else {
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_quiesced = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu_running = B_TRUE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde immu->immu_regs_quiesced = B_FALSE;
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&(immu->immu_lock));
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde }
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde mutex_exit(&immu_lock);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde return (ret);
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde}
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenvoid
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Lindenimmu_init_inv_wait(immu_inv_wait_t *iwp, const char *name, boolean_t sync)
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden{
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden caddr_t vaddr;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden uint64_t paddr;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden iwp->iwp_sync = sync;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden vaddr = (caddr_t)&iwp->iwp_vstatus;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden paddr = pfn_to_pa(hat_getpfnum(kas.a_hat, vaddr));
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden paddr += ((uintptr_t)vaddr) & MMU_PAGEOFFSET;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden iwp->iwp_pstatus = paddr;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden iwp->iwp_name = name;
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden}
50200e773f0242e336d032a7b43485e1bcfc9bfeFrank Van Der Linden
3a634bfc9a31448c742688c603d3e76b83b041a0Vikram Hegde/* ############## END Intel IOMMU entry points ################## */