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