1 /* $OpenBSD: drm_memory.c,v 1.22 2011/06/02 18:22:00 weerd Exp $ */ 2 /*- 3 *Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 * OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Authors: 27 * Rickard E. (Rik) Faith <faith@valinux.com> 28 * Gareth Hughes <gareth@valinux.com> 29 * 30 */ 31 32 /** @file drm_memory.c 33 * Wrappers for kernel memory allocation routines, and MTRR management support. 34 * 35 * This file previously implemented a memory consumption tracking system using 36 * the "area" argument for various different types of allocations, but that 37 * has been stripped out for now. 38 */ 39 40 #include "drmP.h" 41 42 void* 43 drm_alloc(size_t size) 44 { 45 return (malloc(size, M_DRM, M_NOWAIT)); 46 } 47 48 void * 49 drm_calloc(size_t nmemb, size_t size) 50 { 51 if (nmemb == 0 || SIZE_MAX / nmemb < size) 52 return (NULL); 53 else 54 return malloc(size * nmemb, M_DRM, M_NOWAIT | M_ZERO); 55 } 56 57 void * 58 drm_realloc(void *oldpt, size_t oldsize, size_t size) 59 { 60 void *pt; 61 62 pt = malloc(size, M_DRM, M_NOWAIT); 63 if (pt == NULL) 64 return NULL; 65 if (oldpt && oldsize) { 66 memcpy(pt, oldpt, min(oldsize, size)); 67 free(oldpt, M_DRM); 68 } 69 return pt; 70 } 71 72 void 73 drm_free(void *pt) 74 { 75 if (pt != NULL) 76 free(pt, M_DRM); 77 } 78 79 /* Inline replacements for DRM_IOREMAP macros */ 80 void 81 drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) 82 { 83 DRM_DEBUG("offset: 0x%x size: 0x%x type: %d\n", map->offset, map->size, 84 map->type); 85 86 /* default to failure. */ 87 map->handle = 0; 88 89 if (map->type == _DRM_AGP || map->type == _DRM_FRAME_BUFFER) { 90 /* 91 * there can be multiple agp maps in the same BAR, agp also 92 * quite possibly isn't the same as the vga device, just try 93 * to map it. 94 */ 95 DRM_DEBUG("AGP map\n"); 96 map->bst = dev->bst; 97 if (bus_space_map(map->bst, map->offset, 98 map->size, BUS_SPACE_MAP_LINEAR | 99 BUS_SPACE_MAP_PREFETCHABLE, &map->bsh)) { 100 DRM_ERROR("ioremap fail\n"); 101 return; 102 } 103 /* handles are still supposed to be kernel virtual addresses */ 104 map->handle = bus_space_vaddr(map->bst, map->bsh); 105 } 106 } 107 108 void 109 drm_core_ioremapfree(struct drm_local_map *map) 110 { 111 if (map->handle && map->size && (map->type == _DRM_AGP || 112 map->type == _DRM_FRAME_BUFFER)) { 113 bus_space_unmap(map->bst, map->bsh, map->size); 114 map->handle = 0; 115 } 116 } 117 118 int 119 drm_mtrr_add(unsigned long offset, size_t size, int flags) 120 { 121 #ifndef DRM_NO_MTRR 122 int act; 123 struct mem_range_desc mrdesc; 124 125 mrdesc.mr_base = offset; 126 mrdesc.mr_len = size; 127 mrdesc.mr_flags = flags; 128 act = MEMRANGE_SET_UPDATE; 129 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 130 return mem_range_attr_set(&mrdesc, &act); 131 #else 132 return 0; 133 #endif 134 } 135 136 int 137 drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags) 138 { 139 #ifndef DRM_NO_MTRR 140 int act; 141 struct mem_range_desc mrdesc; 142 143 mrdesc.mr_base = offset; 144 mrdesc.mr_len = size; 145 mrdesc.mr_flags = flags; 146 act = MEMRANGE_SET_REMOVE; 147 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 148 return mem_range_attr_set(&mrdesc, &act); 149 #else 150 return 0; 151 #endif 152 } 153