1221828Sgrehan/*- 2221828Sgrehan * Copyright (c) 2011 NetApp, Inc. 3221828Sgrehan * All rights reserved. 4221828Sgrehan * 5221828Sgrehan * Redistribution and use in source and binary forms, with or without 6221828Sgrehan * modification, are permitted provided that the following conditions 7221828Sgrehan * are met: 8221828Sgrehan * 1. Redistributions of source code must retain the above copyright 9221828Sgrehan * notice, this list of conditions and the following disclaimer. 10221828Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 11221828Sgrehan * notice, this list of conditions and the following disclaimer in the 12221828Sgrehan * documentation and/or other materials provided with the distribution. 13221828Sgrehan * 14221828Sgrehan * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15221828Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16221828Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17221828Sgrehan * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18221828Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19221828Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20221828Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21221828Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22221828Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23221828Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24221828Sgrehan * SUCH DAMAGE. 25221828Sgrehan * 26221828Sgrehan * $FreeBSD$ 27221828Sgrehan */ 28221828Sgrehan 29221828Sgrehan#include <sys/cdefs.h> 30221828Sgrehan__FBSDID("$FreeBSD$"); 31221828Sgrehan 32221828Sgrehan#include <sys/param.h> 33221828Sgrehan#include <sys/systm.h> 34221828Sgrehan#include <sys/malloc.h> 35256072Sneel#include <sys/sglist.h> 36256072Sneel#include <sys/lock.h> 37256072Sneel#include <sys/rwlock.h> 38221828Sgrehan 39221828Sgrehan#include <vm/vm.h> 40256072Sneel#include <vm/vm_param.h> 41221828Sgrehan#include <vm/pmap.h> 42256072Sneel#include <vm/vm_map.h> 43256072Sneel#include <vm/vm_object.h> 44241362Sneel#include <vm/vm_page.h> 45256072Sneel#include <vm/vm_pager.h> 46221828Sgrehan 47221828Sgrehan#include <machine/md_var.h> 48221828Sgrehan 49221828Sgrehan#include "vmm_mem.h" 50221828Sgrehan 51221828Sgrehanint 52221828Sgrehanvmm_mem_init(void) 53221828Sgrehan{ 54221828Sgrehan 55221828Sgrehan return (0); 56221828Sgrehan} 57221828Sgrehan 58256072Sneelvm_object_t 59256072Sneelvmm_mmio_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, 60256072Sneel vm_paddr_t hpa) 61221828Sgrehan{ 62256072Sneel int error; 63256072Sneel vm_object_t obj; 64256072Sneel struct sglist *sg; 65221828Sgrehan 66256072Sneel sg = sglist_alloc(1, M_WAITOK); 67256072Sneel error = sglist_append_phys(sg, hpa, len); 68256072Sneel KASSERT(error == 0, ("error %d appending physaddr to sglist", error)); 69221828Sgrehan 70256072Sneel obj = vm_pager_allocate(OBJT_SG, sg, len, VM_PROT_RW, 0, NULL); 71256072Sneel if (obj != NULL) { 72241362Sneel /* 73256072Sneel * VT-x ignores the MTRR settings when figuring out the 74256072Sneel * memory type for translations obtained through EPT. 75256072Sneel * 76256072Sneel * Therefore we explicitly force the pages provided by 77256072Sneel * this object to be mapped as uncacheable. 78241362Sneel */ 79256072Sneel VM_OBJECT_WLOCK(obj); 80256072Sneel error = vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); 81256072Sneel VM_OBJECT_WUNLOCK(obj); 82256072Sneel if (error != KERN_SUCCESS) { 83256072Sneel panic("vmm_mmio_alloc: vm_object_set_memattr error %d", 84256072Sneel error); 85256072Sneel } 86256072Sneel error = vm_map_find(&vmspace->vm_map, obj, 0, &gpa, len, 0, 87256072Sneel VMFS_NO_SPACE, VM_PROT_RW, VM_PROT_RW, 0); 88256072Sneel if (error != KERN_SUCCESS) { 89256072Sneel vm_object_deallocate(obj); 90256072Sneel obj = NULL; 91256072Sneel } 92221828Sgrehan } 93221828Sgrehan 94256072Sneel /* 95256072Sneel * Drop the reference on the sglist. 96256072Sneel * 97256072Sneel * If the scatter/gather object was successfully allocated then it 98256072Sneel * has incremented the reference count on the sglist. Dropping the 99256072Sneel * initial reference count ensures that the sglist will be freed 100256072Sneel * when the object is deallocated. 101256072Sneel * 102256072Sneel * If the object could not be allocated then we end up freeing the 103256072Sneel * sglist. 104256072Sneel */ 105256072Sneel sglist_free(sg); 106221828Sgrehan 107256072Sneel return (obj); 108239700Sgrehan} 109239700Sgrehan 110221828Sgrehanvoid 111256072Sneelvmm_mmio_free(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) 112221828Sgrehan{ 113221828Sgrehan 114256072Sneel vm_map_remove(&vmspace->vm_map, gpa, gpa + len); 115256072Sneel} 116256072Sneel 117221828Sgrehanvm_paddr_t 118221828Sgrehanvmm_mem_maxaddr(void) 119221828Sgrehan{ 120221828Sgrehan 121241362Sneel return (ptoa(Maxmem)); 122221828Sgrehan} 123