drm_memory.c revision 1.23
1/* $OpenBSD: drm_memory.c,v 1.23 2012/09/08 16:53:01 mpi 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#if !defined(__amd64__) && !defined(__i386__) 43#define DRM_NO_MTRR 1 44#endif 45 46void* 47drm_alloc(size_t size) 48{ 49 return (malloc(size, M_DRM, M_NOWAIT)); 50} 51 52void * 53drm_calloc(size_t nmemb, size_t size) 54{ 55 if (nmemb == 0 || SIZE_MAX / nmemb < size) 56 return (NULL); 57 else 58 return malloc(size * nmemb, M_DRM, M_NOWAIT | M_ZERO); 59} 60 61void * 62drm_realloc(void *oldpt, size_t oldsize, size_t size) 63{ 64 void *pt; 65 66 pt = malloc(size, M_DRM, M_NOWAIT); 67 if (pt == NULL) 68 return NULL; 69 if (oldpt && oldsize) { 70 memcpy(pt, oldpt, min(oldsize, size)); 71 free(oldpt, M_DRM); 72 } 73 return pt; 74} 75 76void 77drm_free(void *pt) 78{ 79 if (pt != NULL) 80 free(pt, M_DRM); 81} 82 83/* Inline replacements for DRM_IOREMAP macros */ 84void 85drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) 86{ 87 DRM_DEBUG("offset: 0x%x size: 0x%x type: %d\n", map->offset, map->size, 88 map->type); 89 90 /* default to failure. */ 91 map->handle = 0; 92 93 if (map->type == _DRM_AGP || map->type == _DRM_FRAME_BUFFER) { 94 /* 95 * there can be multiple agp maps in the same BAR, agp also 96 * quite possibly isn't the same as the vga device, just try 97 * to map it. 98 */ 99 DRM_DEBUG("AGP map\n"); 100 map->bst = dev->bst; 101 if (bus_space_map(map->bst, map->offset, 102 map->size, BUS_SPACE_MAP_LINEAR | 103 BUS_SPACE_MAP_PREFETCHABLE, &map->bsh)) { 104 DRM_ERROR("ioremap fail\n"); 105 return; 106 } 107 /* handles are still supposed to be kernel virtual addresses */ 108 map->handle = bus_space_vaddr(map->bst, map->bsh); 109 } 110} 111 112void 113drm_core_ioremapfree(struct drm_local_map *map) 114{ 115 if (map->handle && map->size && (map->type == _DRM_AGP || 116 map->type == _DRM_FRAME_BUFFER)) { 117 bus_space_unmap(map->bst, map->bsh, map->size); 118 map->handle = 0; 119 } 120} 121 122int 123drm_mtrr_add(unsigned long offset, size_t size, int flags) 124{ 125#ifndef DRM_NO_MTRR 126 int act; 127 struct mem_range_desc mrdesc; 128 129 mrdesc.mr_base = offset; 130 mrdesc.mr_len = size; 131 mrdesc.mr_flags = flags; 132 act = MEMRANGE_SET_UPDATE; 133 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 134 return mem_range_attr_set(&mrdesc, &act); 135#else 136 return 0; 137#endif 138} 139 140int 141drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags) 142{ 143#ifndef DRM_NO_MTRR 144 int act; 145 struct mem_range_desc mrdesc; 146 147 mrdesc.mr_base = offset; 148 mrdesc.mr_len = size; 149 mrdesc.mr_flags = flags; 150 act = MEMRANGE_SET_REMOVE; 151 strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); 152 return mem_range_attr_set(&mrdesc, &act); 153#else 154 return 0; 155#endif 156} 157