1119895Sanholt/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*-
2152909Sanholt * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw
3152909Sanholt *
4119895Sanholt * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
5119895Sanholt * All rights reserved.
6119895Sanholt *
7119895Sanholt * Permission is hereby granted, free of charge, to any person obtaining a
8119895Sanholt * copy of this software and associated documentation files (the "Software"),
9119895Sanholt * to deal in the Software without restriction, including without limitation
10119895Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11119895Sanholt * and/or sell copies of the Software, and to permit persons to whom the
12119895Sanholt * Software is furnished to do so, subject to the following conditions:
13145132Sanholt *
14119895Sanholt * The above copyright notice and this permission notice (including the next
15119895Sanholt * paragraph) shall be included in all copies or substantial portions of the
16119895Sanholt * Software.
17145132Sanholt *
18119895Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19119895Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20119895Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21119895Sanholt * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22119895Sanholt * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23119895Sanholt * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24119895Sanholt * DEALINGS IN THE SOFTWARE.
25145132Sanholt *
26119895Sanholt * Authors:
27119895Sanholt *    Sung-Ching Lin <sclin@sis.com.tw>
28145132Sanholt *
29119895Sanholt */
30119895Sanholt
31152909Sanholt#include <sys/cdefs.h>
32152909Sanholt__FBSDID("$FreeBSD$");
33152909Sanholt
34119895Sanholt#include "dev/drm/drmP.h"
35119895Sanholt#include "dev/drm/drm.h"
36119895Sanholt#include "dev/drm/sis_ds.h"
37119895Sanholt
38119895Sanholt/* Set Data Structure, not check repeated value
39119895Sanholt * temporarily used
40119895Sanholt */
41119895Sanholt
42119895Sanholtset_t *setInit(void)
43119895Sanholt{
44119895Sanholt	int i;
45119895Sanholt	set_t *set;
46119895Sanholt
47145132Sanholt	set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
48119895Sanholt	if (set != NULL) {
49119895Sanholt		for (i = 0; i < SET_SIZE; i++) {
50145132Sanholt			set->list[i].free_next = i + 1;
51119895Sanholt			set->list[i].alloc_next = -1;
52119895Sanholt		}
53145132Sanholt		set->list[SET_SIZE - 1].free_next = -1;
54119895Sanholt		set->free = 0;
55119895Sanholt		set->alloc = -1;
56119895Sanholt		set->trace = -1;
57119895Sanholt	}
58119895Sanholt	return set;
59119895Sanholt}
60119895Sanholt
61145132Sanholtint setAdd(set_t * set, ITEM_TYPE item)
62119895Sanholt{
63119895Sanholt	int free = set->free;
64145132Sanholt
65119895Sanholt	if (free != -1) {
66119895Sanholt		set->list[free].val = item;
67119895Sanholt		set->free = set->list[free].free_next;
68119895Sanholt	} else {
69119895Sanholt		return 0;
70119895Sanholt	}
71119895Sanholt
72119895Sanholt	set->list[free].alloc_next = set->alloc;
73145132Sanholt	set->alloc = free;
74145132Sanholt	set->list[free].free_next = -1;
75119895Sanholt
76119895Sanholt	return 1;
77119895Sanholt}
78119895Sanholt
79145132Sanholtint setDel(set_t * set, ITEM_TYPE item)
80119895Sanholt{
81119895Sanholt	int alloc = set->alloc;
82145132Sanholt	int prev = -1;
83119895Sanholt
84119895Sanholt	while (alloc != -1) {
85119895Sanholt		if (set->list[alloc].val == item) {
86119895Sanholt			if (prev != -1)
87119895Sanholt				set->list[prev].alloc_next =
88119895Sanholt				    set->list[alloc].alloc_next;
89119895Sanholt			else
90119895Sanholt				set->alloc = set->list[alloc].alloc_next;
91119895Sanholt			break;
92119895Sanholt		}
93119895Sanholt		prev = alloc;
94119895Sanholt		alloc = set->list[alloc].alloc_next;
95119895Sanholt	}
96119895Sanholt
97119895Sanholt	if (alloc == -1)
98119895Sanholt		return 0;
99119895Sanholt
100119895Sanholt	set->list[alloc].free_next = set->free;
101119895Sanholt	set->free = alloc;
102119895Sanholt	set->list[alloc].alloc_next = -1;
103119895Sanholt
104119895Sanholt	return 1;
105119895Sanholt}
106119895Sanholt
107119895Sanholt/* setFirst -> setAdd -> setNext is wrong */
108119895Sanholt
109145132Sanholtint setFirst(set_t * set, ITEM_TYPE * item)
110119895Sanholt{
111119895Sanholt	if (set->alloc == -1)
112119895Sanholt		return 0;
113119895Sanholt
114119895Sanholt	*item = set->list[set->alloc].val;
115119895Sanholt	set->trace = set->list[set->alloc].alloc_next;
116119895Sanholt
117119895Sanholt	return 1;
118119895Sanholt}
119119895Sanholt
120145132Sanholtint setNext(set_t * set, ITEM_TYPE * item)
121119895Sanholt{
122119895Sanholt	if (set->trace == -1)
123119895Sanholt		return 0;
124119895Sanholt
125119895Sanholt	*item = set->list[set->trace].val;
126119895Sanholt	set->trace = set->list[set->trace].alloc_next;
127119895Sanholt
128119895Sanholt	return 1;
129119895Sanholt}
130119895Sanholt
131145132Sanholtint setDestroy(set_t * set)
132119895Sanholt{
133145132Sanholt	drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
134119895Sanholt
135119895Sanholt	return 1;
136119895Sanholt}
137119895Sanholt
138119895Sanholt/*
139119895Sanholt * GLX Hardware Device Driver common code
140145132Sanholt * Copyright (C) 1999 Wittawat Yamwong
141119895Sanholt *
142119895Sanholt * Permission is hereby granted, free of charge, to any person obtaining a
143119895Sanholt * copy of this software and associated documentation files (the "Software"),
144119895Sanholt * to deal in the Software without restriction, including without limitation
145119895Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
146119895Sanholt * and/or sell copies of the Software, and to permit persons to whom the
147119895Sanholt * Software is furnished to do so, subject to the following conditions:
148119895Sanholt *
149119895Sanholt * The above copyright notice and this permission notice shall be included
150119895Sanholt * in all copies or substantial portions of the Software.
151119895Sanholt *
152119895Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
153119895Sanholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
154119895Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
155157617Sanholt * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
156145132Sanholt * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
157145132Sanholt * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
158119895Sanholt * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
159119895Sanholt *
160119895Sanholt */
161119895Sanholt
162119895Sanholt#define ISFREE(bptr) ((bptr)->free)
163119895Sanholt
164145132SanholtmemHeap_t *mmInit(int ofs, int size)
165119895Sanholt{
166119895Sanholt	PMemBlock blocks;
167119895Sanholt
168119895Sanholt	if (size <= 0)
169145132Sanholt		return NULL;
170119895Sanholt
171145132Sanholt	blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
172119895Sanholt	if (blocks != NULL) {
173119895Sanholt		blocks->ofs = ofs;
174119895Sanholt		blocks->size = size;
175119895Sanholt		blocks->free = 1;
176145132Sanholt		return (memHeap_t *) blocks;
177119895Sanholt	} else
178145132Sanholt		return NULL;
179119895Sanholt}
180119895Sanholt
181119895Sanholt/* Checks if a pointer 'b' is part of the heap 'heap' */
182145132Sanholtint mmBlockInHeap(memHeap_t * heap, PMemBlock b)
183119895Sanholt{
184119895Sanholt	TMemBlock *p;
185119895Sanholt
186119895Sanholt	if (heap == NULL || b == NULL)
187119895Sanholt		return 0;
188119895Sanholt
189119895Sanholt	p = heap;
190119895Sanholt	while (p != NULL && p != b) {
191119895Sanholt		p = p->next;
192119895Sanholt	}
193119895Sanholt	if (p == b)
194119895Sanholt		return 1;
195119895Sanholt	else
196119895Sanholt		return 0;
197119895Sanholt}
198119895Sanholt
199145132Sanholtstatic TMemBlock *SliceBlock(TMemBlock * p,
200145132Sanholt			     int startofs, int size,
201119895Sanholt			     int reserved, int alignment)
202119895Sanholt{
203119895Sanholt	TMemBlock *newblock;
204119895Sanholt
205119895Sanholt	/* break left */
206119895Sanholt	if (startofs > p->ofs) {
207145132Sanholt		newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
208145132Sanholt						    DRM_MEM_DRIVER);
209119895Sanholt		newblock->ofs = startofs;
210119895Sanholt		newblock->size = p->size - (startofs - p->ofs);
211119895Sanholt		newblock->free = 1;
212119895Sanholt		newblock->next = p->next;
213119895Sanholt		p->size -= newblock->size;
214119895Sanholt		p->next = newblock;
215119895Sanholt		p = newblock;
216119895Sanholt	}
217119895Sanholt
218119895Sanholt	/* break right */
219119895Sanholt	if (size < p->size) {
220145132Sanholt		newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
221145132Sanholt						    DRM_MEM_DRIVER);
222119895Sanholt		newblock->ofs = startofs + size;
223119895Sanholt		newblock->size = p->size - size;
224119895Sanholt		newblock->free = 1;
225119895Sanholt		newblock->next = p->next;
226119895Sanholt		p->size = size;
227119895Sanholt		p->next = newblock;
228119895Sanholt	}
229119895Sanholt
230119895Sanholt	/* p = middle block */
231119895Sanholt	p->align = alignment;
232119895Sanholt	p->free = 0;
233119895Sanholt	p->reserved = reserved;
234119895Sanholt	return p;
235119895Sanholt}
236119895Sanholt
237145132SanholtPMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
238119895Sanholt{
239145132Sanholt	int mask, startofs, endofs;
240119895Sanholt	TMemBlock *p;
241145132Sanholt
242119895Sanholt	if (heap == NULL || align2 < 0 || size <= 0)
243119895Sanholt		return NULL;
244119895Sanholt
245145132Sanholt	mask = (1 << align2) - 1;
246119895Sanholt	startofs = 0;
247145132Sanholt	p = (TMemBlock *) heap;
248119895Sanholt	while (p != NULL) {
249119895Sanholt		if (ISFREE(p)) {
250119895Sanholt			startofs = (p->ofs + mask) & ~mask;
251145132Sanholt			if (startofs < startSearch) {
252119895Sanholt				startofs = startSearch;
253119895Sanholt			}
254145132Sanholt			endofs = startofs + size;
255145132Sanholt			if (endofs <= (p->ofs + p->size))
256119895Sanholt				break;
257119895Sanholt		}
258119895Sanholt		p = p->next;
259119895Sanholt	}
260119895Sanholt	if (p == NULL)
261119895Sanholt		return NULL;
262145132Sanholt	p = SliceBlock(p, startofs, size, 0, mask + 1);
263119895Sanholt	p->heap = heap;
264119895Sanholt	return p;
265119895Sanholt}
266119895Sanholt
267145132Sanholtstatic __inline__ int Join2Blocks(TMemBlock * p)
268119895Sanholt{
269119895Sanholt	if (p->free && p->next && p->next->free) {
270119895Sanholt		TMemBlock *q = p->next;
271119895Sanholt		p->size += q->size;
272119895Sanholt		p->next = q->next;
273145132Sanholt		drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
274119895Sanholt		return 1;
275119895Sanholt	}
276119895Sanholt	return 0;
277119895Sanholt}
278119895Sanholt
279119895Sanholtint mmFreeMem(PMemBlock b)
280119895Sanholt{
281119895Sanholt	TMemBlock *p, *prev;
282119895Sanholt
283119895Sanholt	if (b == NULL)
284119895Sanholt		return 0;
285119895Sanholt	if (b->heap == NULL)
286119895Sanholt		return -1;
287119895Sanholt
288119895Sanholt	p = b->heap;
289119895Sanholt	prev = NULL;
290119895Sanholt	while (p != NULL && p != b) {
291119895Sanholt		prev = p;
292119895Sanholt		p = p->next;
293119895Sanholt	}
294119895Sanholt	if (p == NULL || p->free || p->reserved)
295119895Sanholt		return -1;
296119895Sanholt
297119895Sanholt	p->free = 1;
298119895Sanholt	Join2Blocks(p);
299119895Sanholt	if (prev)
300119895Sanholt		Join2Blocks(prev);
301119895Sanholt	return 0;
302119895Sanholt}
303