From owner-svn-src-head@FreeBSD.ORG Tue Aug 20 06:20:05 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id D3C1AE6D; Tue, 20 Aug 2013 06:20:05 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id C12B6256A; Tue, 20 Aug 2013 06:20:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7K6K5Lh058716; Tue, 20 Aug 2013 06:20:05 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7K6K5wZ058715; Tue, 20 Aug 2013 06:20:05 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201308200620.r7K6K5wZ058715@svn.freebsd.org> From: Neel Natu Date: Tue, 20 Aug 2013 06:20:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254548 - head/sys/amd64/vmm/intel X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Aug 2013 06:20:05 -0000 Author: neel Date: Tue Aug 20 06:20:05 2013 New Revision: 254548 URL: http://svnweb.freebsd.org/changeset/base/254548 Log: Extract the location of the remapping hardware units from the ACPI DMAR table. Submitted by: Gopakumar T (gopakumar_thekkedath@yahoo.co.in) Modified: head/sys/amd64/vmm/intel/vtd.c Modified: head/sys/amd64/vmm/intel/vtd.c ============================================================================== --- head/sys/amd64/vmm/intel/vtd.c Tue Aug 20 02:09:26 2013 (r254547) +++ head/sys/amd64/vmm/intel/vtd.c Tue Aug 20 06:20:05 2013 (r254548) @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include "io/iommu.h" @@ -123,60 +123,6 @@ static uint64_t ctx_tables[256][PAGE_SIZ static MALLOC_DEFINE(M_VTD, "vtd", "vtd"); -/* - * Config space register definitions from the "Intel 5520 and 5500" datasheet. - */ -static int -tylersburg_vtd_ident(void) -{ - int units, nlbus; - uint16_t did, vid; - uint32_t miscsts, vtbar; - - const int bus = 0; - const int slot = 20; - const int func = 0; - - units = 0; - - vid = pci_cfgregread(bus, slot, func, PCIR_VENDOR, 2); - did = pci_cfgregread(bus, slot, func, PCIR_DEVICE, 2); - if (vid != 0x8086 || did != 0x342E) - goto done; - - /* - * Check if this is a dual IOH configuration. - */ - miscsts = pci_cfgregread(bus, slot, func, 0x9C, 4); - if (miscsts & (1 << 25)) - nlbus = pci_cfgregread(bus, slot, func, 0x160, 1); - else - nlbus = -1; - - vtbar = pci_cfgregread(bus, slot, func, 0x180, 4); - if (vtbar & 0x1) { - vtdmaps[units++] = (struct vtdmap *) - PHYS_TO_DMAP(vtbar & 0xffffe000); - } else if (bootverbose) - printf("VT-d unit in legacy IOH is disabled!\n"); - - if (nlbus != -1) { - vtbar = pci_cfgregread(nlbus, slot, func, 0x180, 4); - if (vtbar & 0x1) { - vtdmaps[units++] = (struct vtdmap *) - PHYS_TO_DMAP(vtbar & 0xffffe000); - } else if (bootverbose) - printf("VT-d unit in non-legacy IOH is disabled!\n"); - } -done: - return (units); -} - -static drhd_ident_func_t drhd_ident_funcs[] = { - tylersburg_vtd_ident, - NULL -}; - static int vtd_max_domains(struct vtdmap *vtdmap) { @@ -291,19 +237,67 @@ vtd_translation_disable(struct vtdmap *v static int vtd_init(void) { - int i, units; + int i, units, remaining; struct vtdmap *vtdmap; vm_paddr_t ctx_paddr; - - for (i = 0; drhd_ident_funcs[i] != NULL; i++) { - units = (*drhd_ident_funcs[i])(); - if (units > 0) + char *end, envname[32]; + unsigned long mapaddr; + ACPI_STATUS status; + ACPI_TABLE_DMAR *dmar; + ACPI_DMAR_HEADER *hdr; + ACPI_DMAR_HARDWARE_UNIT *drhd; + + /* + * Allow the user to override the ACPI DMAR table by specifying the + * physical address of each remapping unit. + * + * The following example specifies two remapping units at + * physical addresses 0xfed90000 and 0xfeda0000 respectively. + * set vtd.regmap.0.addr=0xfed90000 + * set vtd.regmap.1.addr=0xfeda0000 + */ + for (units = 0; units < DRHD_MAX_UNITS; units++) { + snprintf(envname, sizeof(envname), "vtd.regmap.%d.addr", units); + if (getenv_ulong(envname, &mapaddr) == 0) + break; + vtdmaps[units] = (struct vtdmap *)PHYS_TO_DMAP(mapaddr); + } + + if (units > 0) + goto skip_dmar; + + /* Search for DMAR table. */ + status = AcpiGetTable(ACPI_SIG_DMAR, 0, (ACPI_TABLE_HEADER **)&dmar); + if (ACPI_FAILURE(status)) + return (ENXIO); + + end = (char *)dmar + dmar->Header.Length; + remaining = dmar->Header.Length - sizeof(ACPI_TABLE_DMAR); + while (remaining > sizeof(ACPI_DMAR_HEADER)) { + hdr = (ACPI_DMAR_HEADER *)(end - remaining); + if (hdr->Length > remaining) + break; + /* + * From Intel VT-d arch spec, version 1.3: + * BIOS implementations must report mapping structures + * in numerical order, i.e. All remapping structures of + * type 0 (DRHD) enumerated before remapping structures of + * type 1 (RMRR) and so forth. + */ + if (hdr->Type != ACPI_DMAR_TYPE_HARDWARE_UNIT) + break; + + drhd = (ACPI_DMAR_HARDWARE_UNIT *)hdr; + vtdmaps[units++] = (struct vtdmap *)PHYS_TO_DMAP(drhd->Address); + if (units >= DRHD_MAX_UNITS) break; + remaining -= hdr->Length; } if (units <= 0) return (ENXIO); +skip_dmar: drhd_num = units; vtdmap = vtdmaps[0];