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