xref: /NextBSD/sys/dev/drm/sis_ds.c (revision eb1a5f8de9f7ea602c373a710f531abbf81141c4)
1 /* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*-
2  * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw
3  *
4  * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
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  * PRECISION INSIGHT 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 OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Authors:
27  *    Sung-Ching Lin <sclin@sis.com.tw>
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include "dev/drm/drmP.h"
35 #include "dev/drm/drm.h"
36 #include "dev/drm/sis_ds.h"
37 
38 /* Set Data Structure, not check repeated value
39  * temporarily used
40  */
41 
setInit(void)42 set_t *setInit(void)
43 {
44 	int i;
45 	set_t *set;
46 
47 	set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
48 	if (set != NULL) {
49 		for (i = 0; i < SET_SIZE; i++) {
50 			set->list[i].free_next = i + 1;
51 			set->list[i].alloc_next = -1;
52 		}
53 		set->list[SET_SIZE - 1].free_next = -1;
54 		set->free = 0;
55 		set->alloc = -1;
56 		set->trace = -1;
57 	}
58 	return set;
59 }
60 
setAdd(set_t * set,ITEM_TYPE item)61 int setAdd(set_t * set, ITEM_TYPE item)
62 {
63 	int free = set->free;
64 
65 	if (free != -1) {
66 		set->list[free].val = item;
67 		set->free = set->list[free].free_next;
68 	} else {
69 		return 0;
70 	}
71 
72 	set->list[free].alloc_next = set->alloc;
73 	set->alloc = free;
74 	set->list[free].free_next = -1;
75 
76 	return 1;
77 }
78 
setDel(set_t * set,ITEM_TYPE item)79 int setDel(set_t * set, ITEM_TYPE item)
80 {
81 	int alloc = set->alloc;
82 	int prev = -1;
83 
84 	while (alloc != -1) {
85 		if (set->list[alloc].val == item) {
86 			if (prev != -1)
87 				set->list[prev].alloc_next =
88 				    set->list[alloc].alloc_next;
89 			else
90 				set->alloc = set->list[alloc].alloc_next;
91 			break;
92 		}
93 		prev = alloc;
94 		alloc = set->list[alloc].alloc_next;
95 	}
96 
97 	if (alloc == -1)
98 		return 0;
99 
100 	set->list[alloc].free_next = set->free;
101 	set->free = alloc;
102 	set->list[alloc].alloc_next = -1;
103 
104 	return 1;
105 }
106 
107 /* setFirst -> setAdd -> setNext is wrong */
108 
setFirst(set_t * set,ITEM_TYPE * item)109 int setFirst(set_t * set, ITEM_TYPE * item)
110 {
111 	if (set->alloc == -1)
112 		return 0;
113 
114 	*item = set->list[set->alloc].val;
115 	set->trace = set->list[set->alloc].alloc_next;
116 
117 	return 1;
118 }
119 
setNext(set_t * set,ITEM_TYPE * item)120 int setNext(set_t * set, ITEM_TYPE * item)
121 {
122 	if (set->trace == -1)
123 		return 0;
124 
125 	*item = set->list[set->trace].val;
126 	set->trace = set->list[set->trace].alloc_next;
127 
128 	return 1;
129 }
130 
setDestroy(set_t * set)131 int setDestroy(set_t * set)
132 {
133 	drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
134 
135 	return 1;
136 }
137 
138 /*
139  * GLX Hardware Device Driver common code
140  * Copyright (C) 1999 Wittawat Yamwong
141  *
142  * Permission is hereby granted, free of charge, to any person obtaining a
143  * copy of this software and associated documentation files (the "Software"),
144  * to deal in the Software without restriction, including without limitation
145  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
146  * and/or sell copies of the Software, and to permit persons to whom the
147  * Software is furnished to do so, subject to the following conditions:
148  *
149  * The above copyright notice and this permission notice shall be included
150  * in all copies or substantial portions of the Software.
151  *
152  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
153  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
154  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
155  * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
156  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
157  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
158  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
159  *
160  */
161 
162 #define ISFREE(bptr) ((bptr)->free)
163 
mmInit(int ofs,int size)164 memHeap_t *mmInit(int ofs, int size)
165 {
166 	PMemBlock blocks;
167 
168 	if (size <= 0)
169 		return NULL;
170 
171 	blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
172 	if (blocks != NULL) {
173 		blocks->ofs = ofs;
174 		blocks->size = size;
175 		blocks->free = 1;
176 		return (memHeap_t *) blocks;
177 	} else
178 		return NULL;
179 }
180 
181 /* Checks if a pointer 'b' is part of the heap 'heap' */
mmBlockInHeap(memHeap_t * heap,PMemBlock b)182 int mmBlockInHeap(memHeap_t * heap, PMemBlock b)
183 {
184 	TMemBlock *p;
185 
186 	if (heap == NULL || b == NULL)
187 		return 0;
188 
189 	p = heap;
190 	while (p != NULL && p != b) {
191 		p = p->next;
192 	}
193 	if (p == b)
194 		return 1;
195 	else
196 		return 0;
197 }
198 
SliceBlock(TMemBlock * p,int startofs,int size,int reserved,int alignment)199 static TMemBlock *SliceBlock(TMemBlock * p,
200 			     int startofs, int size,
201 			     int reserved, int alignment)
202 {
203 	TMemBlock *newblock;
204 
205 	/* break left */
206 	if (startofs > p->ofs) {
207 		newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
208 						    DRM_MEM_DRIVER);
209 		newblock->ofs = startofs;
210 		newblock->size = p->size - (startofs - p->ofs);
211 		newblock->free = 1;
212 		newblock->next = p->next;
213 		p->size -= newblock->size;
214 		p->next = newblock;
215 		p = newblock;
216 	}
217 
218 	/* break right */
219 	if (size < p->size) {
220 		newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
221 						    DRM_MEM_DRIVER);
222 		newblock->ofs = startofs + size;
223 		newblock->size = p->size - size;
224 		newblock->free = 1;
225 		newblock->next = p->next;
226 		p->size = size;
227 		p->next = newblock;
228 	}
229 
230 	/* p = middle block */
231 	p->align = alignment;
232 	p->free = 0;
233 	p->reserved = reserved;
234 	return p;
235 }
236 
mmAllocMem(memHeap_t * heap,int size,int align2,int startSearch)237 PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
238 {
239 	int mask, startofs, endofs;
240 	TMemBlock *p;
241 
242 	if (heap == NULL || align2 < 0 || size <= 0)
243 		return NULL;
244 
245 	mask = (1 << align2) - 1;
246 	startofs = 0;
247 	p = (TMemBlock *) heap;
248 	while (p != NULL) {
249 		if (ISFREE(p)) {
250 			startofs = (p->ofs + mask) & ~mask;
251 			if (startofs < startSearch) {
252 				startofs = startSearch;
253 			}
254 			endofs = startofs + size;
255 			if (endofs <= (p->ofs + p->size))
256 				break;
257 		}
258 		p = p->next;
259 	}
260 	if (p == NULL)
261 		return NULL;
262 	p = SliceBlock(p, startofs, size, 0, mask + 1);
263 	p->heap = heap;
264 	return p;
265 }
266 
Join2Blocks(TMemBlock * p)267 static __inline__ int Join2Blocks(TMemBlock * p)
268 {
269 	if (p->free && p->next && p->next->free) {
270 		TMemBlock *q = p->next;
271 		p->size += q->size;
272 		p->next = q->next;
273 		drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
274 		return 1;
275 	}
276 	return 0;
277 }
278 
mmFreeMem(PMemBlock b)279 int mmFreeMem(PMemBlock b)
280 {
281 	TMemBlock *p, *prev;
282 
283 	if (b == NULL)
284 		return 0;
285 	if (b->heap == NULL)
286 		return -1;
287 
288 	p = b->heap;
289 	prev = NULL;
290 	while (p != NULL && p != b) {
291 		prev = p;
292 		p = p->next;
293 	}
294 	if (p == NULL || p->free || p->reserved)
295 		return -1;
296 
297 	p->free = 1;
298 	Join2Blocks(p);
299 	if (prev)
300 		Join2Blocks(prev);
301 	return 0;
302 }
303