Commit | Line | Data |
---|---|---|
22f579c6 DA |
1 | /* |
2 | * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. | |
3 | * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. | |
4 | * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. | |
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, sub license, | |
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 | |
14 | * next paragraph) shall be included in all copies or substantial portions | |
15 | * of the 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 NON-INFRINGEMENT. IN NO EVENT SHALL | |
20 | * VIA, S3 GRAPHICS, 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 OTHER | |
23 | * DEALINGS IN THE SOFTWARE. | |
24 | */ | |
7052cff9 | 25 | #include "drmP.h" |
22f579c6 DA |
26 | |
27 | #include "via_ds.h" | |
28 | extern unsigned int VIA_DEBUG; | |
29 | ||
30 | set_t *via_setInit(void) | |
31 | { | |
32 | int i; | |
33 | set_t *set; | |
34 | set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER); | |
35 | for (i = 0; i < SET_SIZE; i++) { | |
36 | set->list[i].free_next = i + 1; | |
37 | set->list[i].alloc_next = -1; | |
38 | } | |
39 | set->list[SET_SIZE - 1].free_next = -1; | |
40 | set->free = 0; | |
41 | set->alloc = -1; | |
42 | set->trace = -1; | |
43 | return set; | |
44 | } | |
45 | ||
46 | int via_setAdd(set_t * set, ITEM_TYPE item) | |
47 | { | |
48 | int free = set->free; | |
49 | if (free != -1) { | |
50 | set->list[free].val = item; | |
51 | set->free = set->list[free].free_next; | |
52 | } else { | |
53 | return 0; | |
54 | } | |
55 | set->list[free].alloc_next = set->alloc; | |
56 | set->alloc = free; | |
57 | set->list[free].free_next = -1; | |
58 | return 1; | |
59 | } | |
60 | ||
61 | int via_setDel(set_t * set, ITEM_TYPE item) | |
62 | { | |
63 | int alloc = set->alloc; | |
64 | int prev = -1; | |
65 | ||
66 | while (alloc != -1) { | |
67 | if (set->list[alloc].val == item) { | |
68 | if (prev != -1) | |
69 | set->list[prev].alloc_next = | |
70 | set->list[alloc].alloc_next; | |
71 | else | |
72 | set->alloc = set->list[alloc].alloc_next; | |
73 | break; | |
74 | } | |
75 | prev = alloc; | |
76 | alloc = set->list[alloc].alloc_next; | |
77 | } | |
78 | ||
79 | if (alloc == -1) | |
80 | return 0; | |
81 | ||
82 | set->list[alloc].free_next = set->free; | |
83 | set->free = alloc; | |
84 | set->list[alloc].alloc_next = -1; | |
85 | ||
86 | return 1; | |
87 | } | |
88 | ||
89 | /* setFirst -> setAdd -> setNext is wrong */ | |
90 | ||
91 | int via_setFirst(set_t * set, ITEM_TYPE * item) | |
92 | { | |
93 | if (set->alloc == -1) | |
94 | return 0; | |
95 | ||
96 | *item = set->list[set->alloc].val; | |
97 | set->trace = set->list[set->alloc].alloc_next; | |
98 | ||
99 | return 1; | |
100 | } | |
101 | ||
102 | int via_setNext(set_t * set, ITEM_TYPE * item) | |
103 | { | |
104 | if (set->trace == -1) | |
105 | return 0; | |
106 | ||
107 | *item = set->list[set->trace].val; | |
108 | set->trace = set->list[set->trace].alloc_next; | |
109 | ||
110 | return 1; | |
111 | } | |
112 | ||
113 | int via_setDestroy(set_t * set) | |
114 | { | |
115 | drm_free(set, sizeof(set_t), DRM_MEM_DRIVER); | |
116 | ||
117 | return 1; | |
118 | } | |
119 | ||
120 | #define ISFREE(bptr) ((bptr)->free) | |
121 | ||
122 | #define fprintf(fmt, arg...) do{}while(0) | |
123 | ||
124 | memHeap_t *via_mmInit(int ofs, int size) | |
125 | { | |
126 | PMemBlock blocks; | |
127 | ||
128 | if (size <= 0) | |
bbaf3641 | 129 | return NULL; |
22f579c6 DA |
130 | |
131 | blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER); | |
132 | ||
133 | if (blocks) { | |
134 | blocks->ofs = ofs; | |
135 | blocks->size = size; | |
136 | blocks->free = 1; | |
137 | return (memHeap_t *) blocks; | |
138 | } else | |
bbaf3641 | 139 | return NULL; |
22f579c6 DA |
140 | } |
141 | ||
142 | static TMemBlock *SliceBlock(TMemBlock * p, | |
143 | int startofs, int size, | |
144 | int reserved, int alignment) | |
145 | { | |
146 | TMemBlock *newblock; | |
147 | ||
148 | /* break left */ | |
149 | if (startofs > p->ofs) { | |
150 | newblock = | |
151 | (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), | |
152 | DRM_MEM_DRIVER); | |
153 | newblock->ofs = startofs; | |
154 | newblock->size = p->size - (startofs - p->ofs); | |
155 | newblock->free = 1; | |
156 | newblock->next = p->next; | |
157 | p->size -= newblock->size; | |
158 | p->next = newblock; | |
159 | p = newblock; | |
160 | } | |
161 | ||
162 | /* break right */ | |
163 | if (size < p->size) { | |
164 | newblock = | |
165 | (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), | |
166 | DRM_MEM_DRIVER); | |
167 | newblock->ofs = startofs + size; | |
168 | newblock->size = p->size - size; | |
169 | newblock->free = 1; | |
170 | newblock->next = p->next; | |
171 | p->size = size; | |
172 | p->next = newblock; | |
173 | } | |
174 | ||
175 | /* p = middle block */ | |
176 | p->align = alignment; | |
177 | p->free = 0; | |
178 | p->reserved = reserved; | |
179 | return p; | |
180 | } | |
181 | ||
182 | PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2, | |
183 | int startSearch) | |
184 | { | |
185 | int mask, startofs, endofs; | |
186 | TMemBlock *p; | |
187 | ||
188 | if (!heap || align2 < 0 || size <= 0) | |
189 | return NULL; | |
190 | ||
191 | mask = (1 << align2) - 1; | |
192 | startofs = 0; | |
193 | p = (TMemBlock *) heap; | |
194 | ||
195 | while (p) { | |
196 | if (ISFREE(p)) { | |
197 | startofs = (p->ofs + mask) & ~mask; | |
198 | ||
199 | if (startofs < startSearch) | |
200 | startofs = startSearch; | |
201 | ||
202 | endofs = startofs + size; | |
203 | ||
204 | if (endofs <= (p->ofs + p->size)) | |
205 | break; | |
206 | } | |
207 | ||
208 | p = p->next; | |
209 | } | |
210 | ||
211 | if (!p) | |
212 | return NULL; | |
213 | ||
214 | p = SliceBlock(p, startofs, size, 0, mask + 1); | |
215 | p->heap = heap; | |
216 | ||
217 | return p; | |
218 | } | |
219 | ||
220 | static __inline__ int Join2Blocks(TMemBlock * p) | |
221 | { | |
222 | if (p->free && p->next && p->next->free) { | |
223 | TMemBlock *q = p->next; | |
224 | p->size += q->size; | |
225 | p->next = q->next; | |
226 | drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER); | |
227 | ||
228 | return 1; | |
229 | } | |
230 | ||
231 | return 0; | |
232 | } | |
233 | ||
234 | int via_mmFreeMem(PMemBlock b) | |
235 | { | |
236 | TMemBlock *p, *prev; | |
237 | ||
238 | if (!b) | |
239 | return 0; | |
240 | ||
241 | if (!b->heap) { | |
242 | fprintf(stderr, "no heap\n"); | |
243 | ||
244 | return -1; | |
245 | } | |
246 | ||
247 | p = b->heap; | |
248 | prev = NULL; | |
249 | ||
250 | while (p && p != b) { | |
251 | prev = p; | |
252 | p = p->next; | |
253 | } | |
254 | ||
255 | if (!p || p->free || p->reserved) { | |
256 | if (!p) | |
257 | fprintf(stderr, "block not found in heap\n"); | |
258 | else if (p->free) | |
259 | fprintf(stderr, "block already free\n"); | |
260 | else | |
261 | fprintf(stderr, "block is reserved\n"); | |
262 | ||
263 | return -1; | |
264 | } | |
265 | ||
266 | p->free = 1; | |
267 | Join2Blocks(p); | |
268 | ||
269 | if (prev) | |
270 | Join2Blocks(prev); | |
271 | ||
272 | return 0; | |
273 | } |