drm_memory.c revision 1.3
1/*- 2 *Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 3 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Rickard E. (Rik) Faith <faith@valinux.com> 27 * Gareth Hughes <gareth@valinux.com> 28 * 29 */ 30 31/** @file drm_memory.c 32 * Wrappers for kernel memory allocation routines, and MTRR management support. 33 * 34 * This file previously implemented a memory consumption tracking system using 35 * the "area" argument for various different types of allocations, but that 36 * has been stripped out for now. 37 */ 38 39#include "drmP.h" 40 41#ifndef __OpenBSD__ 42MALLOC_DEFINE(M_DRM, "drm", "DRM Data Structures"); 43#endif 44 45void 46drm_mem_init(void) 47{ 48#if defined(__NetBSD__) 49/* 50 malloc_type_attach(M_DRM); 51*/ 52#endif 53} 54 55void 56drm_mem_uninit(void) 57{ 58} 59 60void* 61drm_alloc(size_t size, int area) 62{ 63 return malloc(size, M_DRM, M_NOWAIT); 64} 65 66void * 67drm_calloc(size_t nmemb, size_t size, int area) 68{ 69 /* XXX overflow checking */ 70 return malloc(size * nmemb, M_DRM, M_NOWAIT | M_ZERO); 71} 72 73void * 74drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) 75{ 76 void *pt; 77 78 pt = malloc(size, M_DRM, M_NOWAIT); 79 if (pt == NULL) 80 return NULL; 81 if (oldpt && oldsize) { 82 memcpy(pt, oldpt, oldsize); 83 free(oldpt, M_DRM); 84 } 85 return pt; 86} 87 88void 89drm_free(void *pt, size_t size, int area) 90{ 91 free(pt, M_DRM); 92} 93 94void * 95drm_ioremap(drm_device_t *dev, drm_local_map_t *map) 96{ 97#ifdef __FreeBSD__ 98 return pmap_mapdev(map->offset, map->size); 99#elif defined(__NetBSD__) || defined(__OpenBSD__) 100 struct vga_pci_bar *bar = NULL; 101 int i; 102 103 DRM_DEBUG("offset: 0x%x size: 0x%x type: %d\n", map->offset, map->size, 104 map->type); 105 106 if (map->type == _DRM_AGP || map->type == _DRM_FRAME_BUFFER) { 107 /* 108 * there can be multiple agp maps in the same BAR, agp also 109 * quite possibly isn't the same as the vga device, just try 110 * to map it. 111 */ 112 DRM_DEBUG("AGP map\n"); 113 map->bst = dev->pa.pa_memt; 114 if (bus_space_map(map->bst, map->offset, 115 map->size, BUS_SPACE_MAP_LINEAR, &map->bsh)) { 116 DRM_ERROR("ioremap fail\n"); 117 return (NULL); 118 } 119 goto done; 120 } else { 121 for (i = 0 ; i < DRM_MAX_PCI_RESOURCE; ++i) { 122 bar = vga_pci_bar_info(dev->vga_softc, i); 123 if (bar == NULL) 124 continue; 125 126 if (bar->base == map->offset) { 127 DRM_DEBUG("REGISTERS map\n"); 128 map->bsr = vga_pci_bar_map(dev->vga_softc, 129 bar->addr, map->size, BUS_SPACE_MAP_LINEAR); 130 if (map->bsr == NULL) { 131 DRM_ERROR("ioremap fail\n"); 132 return (NULL); 133 } 134 map->bst = map->bsr->bst; 135 map->bsh = map->bsr->bsh; 136 goto done; 137 } 138 } 139 } 140done: 141 /* handles are still supposed to be kernel virtual addresses */ 142 return bus_space_vaddr(map->bst, map->bsh); 143#endif 144} 145 146void 147drm_ioremapfree(drm_local_map_t *map) 148{ 149#ifdef __FreeBSD__ 150 pmap_unmapdev((vm_offset_t) map->handle, map->size); 151#elif defined(__NetBSD__) || defined(__OpenBSD__) 152 if (map != NULL && map->bsr != NULL) 153 vga_pci_bar_unmap(map->bsr); 154 else 155 bus_space_unmap(map->bst, map->bsh, map->size); 156#endif 157} 158 159#if defined(__FreeBSD__) || defined(__OpenBSD__) 160int 161drm_mtrr_add(unsigned long offset, size_t size, int flags) 162{ 163#ifndef DRM_NO_MTRR 164 int act; 165 struct mem_range_desc mrdesc; 166 167 mrdesc.mr_base = offset; 168 mrdesc.mr_len = size; 169 mrdesc.mr_flags = flags; 170 act = MEMRANGE_SET_UPDATE; 171 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 172 return mem_range_attr_set(&mrdesc, &act); 173#else 174 return 0; 175#endif 176} 177 178int 179drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags) 180{ 181#ifndef DRM_NO_MTRR 182 int act; 183 struct mem_range_desc mrdesc; 184 185 mrdesc.mr_base = offset; 186 mrdesc.mr_len = size; 187 mrdesc.mr_flags = flags; 188 act = MEMRANGE_SET_REMOVE; 189 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 190 return mem_range_attr_set(&mrdesc, &act); 191#else 192 return 0; 193#endif 194} 195#elif defined(__NetBSD__) 196int 197drm_mtrr_add(unsigned long offset, size_t size, int flags) 198{ 199#ifndef DRM_NO_MTRR 200 struct mtrr mtrrmap; 201 int one = 1; 202 203 DRM_DEBUG("offset=%lx size=%ld\n", (long)offset, (long)size); 204 mtrrmap.base = offset; 205 mtrrmap.len = size; 206 mtrrmap.type = flags; 207 mtrrmap.flags = MTRR_VALID; 208 return mtrr_set(&mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); 209#else 210 return 0; 211#endif 212} 213 214int 215drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags) 216{ 217#ifndef DRM_NO_MTRR 218 struct mtrr mtrrmap; 219 int one = 1; 220 221 DRM_DEBUG("offset=%lx size=%ld\n", (long)offset, (long)size); 222 mtrrmap.base = offset; 223 mtrrmap.len = size; 224 mtrrmap.type = flags; 225 mtrrmap.flags = 0; 226 return mtrr_set(&mtrrmap, &one, NULL, MTRR_GETSET_KERNEL); 227#else 228 return 0; 229#endif 230} 231#endif 232