177943Sdfr/*- 277943Sdfr * Copyright (c) 2011 NetApp, Inc. 377943Sdfr * All rights reserved. 477943Sdfr * 577943Sdfr * Redistribution and use in source and binary forms, with or without 677943Sdfr * modification, are permitted provided that the following conditions 7163898Smarcel * are met: 8163898Smarcel * 1. Redistributions of source code must retain the above copyright 9163898Smarcel * notice, this list of conditions and the following disclaimer. 10163898Smarcel * 2. Redistributions in binary form must reproduce the above copyright 11163898Smarcel * notice, this list of conditions and the following disclaimer in the 12163898Smarcel * documentation and/or other materials provided with the distribution. 13163898Smarcel * 14163898Smarcel * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 1577943Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1677943Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1777943Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 1877943Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1977943Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2077943Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2177943Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2277943Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2377943Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2477943Sdfr * SUCH DAMAGE. 2577943Sdfr * 2677943Sdfr * $FreeBSD$ 2777943Sdfr */ 2877943Sdfr 2977943Sdfr#include <sys/cdefs.h> 30163898Smarcel__FBSDID("$FreeBSD$"); 31163898Smarcel 32163898Smarcel#include <sys/param.h> 3377943Sdfr#include <sys/systm.h> 3477943Sdfr#include <sys/malloc.h> 35294981Ssmh#include <sys/sglist.h> 3677943Sdfr#include <sys/lock.h> 3777943Sdfr#include <sys/rwlock.h> 3877943Sdfr 39163898Smarcel#include <vm/vm.h> 4077943Sdfr#include <vm/vm_param.h> 41163898Smarcel#include <vm/pmap.h> 42163898Smarcel#include <vm/vm_map.h> 43163898Smarcel#include <vm/vm_object.h> 4477943Sdfr#include <vm/vm_page.h> 4577943Sdfr#include <vm/vm_pager.h> 4677943Sdfr 4777943Sdfr#include <machine/md_var.h> 4877943Sdfr 4977943Sdfr#include "vmm_mem.h" 5077943Sdfr 5177943Sdfrint 5277943Sdfrvmm_mem_init(void) 53163898Smarcel{ 54163898Smarcel 55163898Smarcel return (0); 5677943Sdfr} 5777943Sdfr 5877943Sdfrvm_object_t 5977943Sdfrvmm_mmio_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, 6077943Sdfr vm_paddr_t hpa) 6177943Sdfr{ 6277943Sdfr int error; 6377943Sdfr vm_object_t obj; 6477943Sdfr struct sglist *sg; 6577943Sdfr 6677943Sdfr sg = sglist_alloc(1, M_WAITOK); 6777943Sdfr error = sglist_append_phys(sg, hpa, len); 6877943Sdfr KASSERT(error == 0, ("error %d appending physaddr to sglist", error)); 6977943Sdfr 7077943Sdfr obj = vm_pager_allocate(OBJT_SG, sg, len, VM_PROT_RW, 0, NULL); 7177943Sdfr if (obj != NULL) { 7277943Sdfr /* 7377943Sdfr * VT-x ignores the MTRR settings when figuring out the 7477943Sdfr * memory type for translations obtained through EPT. 7577943Sdfr * 76163898Smarcel * Therefore we explicitly force the pages provided by 77163898Smarcel * this object to be mapped as uncacheable. 78163898Smarcel */ 79163898Smarcel VM_OBJECT_WLOCK(obj); 80163898Smarcel error = vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); 8177943Sdfr VM_OBJECT_WUNLOCK(obj); 8277943Sdfr if (error != KERN_SUCCESS) { 8377943Sdfr panic("vmm_mmio_alloc: vm_object_set_memattr error %d", 84163898Smarcel error); 8577943Sdfr } 8677943Sdfr error = vm_map_find(&vmspace->vm_map, obj, 0, &gpa, len, 0, 8777943Sdfr VMFS_NO_SPACE, VM_PROT_RW, VM_PROT_RW, 0); 8877943Sdfr if (error != KERN_SUCCESS) { 8977943Sdfr vm_object_deallocate(obj); 9077943Sdfr obj = NULL; 9177943Sdfr } 9277943Sdfr } 9377943Sdfr 9477943Sdfr /* 9577943Sdfr * Drop the reference on the sglist. 9677943Sdfr * 9777943Sdfr * If the scatter/gather object was successfully allocated then it 9877943Sdfr * has incremented the reference count on the sglist. Dropping the 9977943Sdfr * initial reference count ensures that the sglist will be freed 10077943Sdfr * when the object is deallocated. 10177943Sdfr * 10277943Sdfr * If the object could not be allocated then we end up freeing the 10377943Sdfr * sglist. 10477943Sdfr */ 10577943Sdfr sglist_free(sg); 10677943Sdfr 10777943Sdfr return (obj); 108163898Smarcel} 109163898Smarcel 110163898Smarcelvoid 11177943Sdfrvmm_mmio_free(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) 11277943Sdfr{ 11377943Sdfr 11477943Sdfr vm_map_remove(&vmspace->vm_map, gpa, gpa + len); 11577943Sdfr} 11677943Sdfr 11777943Sdfrvm_paddr_t 11877943Sdfrvmm_mem_maxaddr(void) 11977943Sdfr{ 12077943Sdfr 12177943Sdfr return (ptoa(Maxmem)); 12277943Sdfr} 12377943Sdfr