sis_ds.c revision 139749
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 * $FreeBSD: head/sys/dev/drm/sis_ds.c 139749 2005-01-06 01:43:34Z imp $ 30 */ 31 32#include "dev/drm/sis.h" 33#include "dev/drm/drmP.h" 34#include "dev/drm/drm.h" 35#include "dev/drm/sis_ds.h" 36 37/* Set Data Structure, not check repeated value 38 * temporarily used 39 */ 40 41set_t *setInit(void) 42{ 43 int i; 44 set_t *set; 45 46 set = (set_t *)DRM(alloc)(sizeof(set_t), DRM_MEM_DRIVER); 47 if (set != NULL) { 48 for (i = 0; i < SET_SIZE; i++) { 49 set->list[i].free_next = i + 1; 50 set->list[i].alloc_next = -1; 51 } 52 set->list[SET_SIZE-1].free_next = -1; 53 set->free = 0; 54 set->alloc = -1; 55 set->trace = -1; 56 } 57 return set; 58} 59 60int setAdd(set_t *set, ITEM_TYPE item) 61{ 62 int free = set->free; 63 64 if (free != -1) { 65 set->list[free].val = item; 66 set->free = set->list[free].free_next; 67 } else { 68 return 0; 69 } 70 71 set->list[free].alloc_next = set->alloc; 72 set->alloc = free; 73 set->list[free].free_next = -1; 74 75 return 1; 76} 77 78int setDel(set_t *set, ITEM_TYPE item) 79{ 80 int alloc = set->alloc; 81 int prev = -1; 82 83 while (alloc != -1) { 84 if (set->list[alloc].val == item) { 85 if (prev != -1) 86 set->list[prev].alloc_next = 87 set->list[alloc].alloc_next; 88 else 89 set->alloc = set->list[alloc].alloc_next; 90 break; 91 } 92 prev = alloc; 93 alloc = set->list[alloc].alloc_next; 94 } 95 96 if (alloc == -1) 97 return 0; 98 99 set->list[alloc].free_next = set->free; 100 set->free = alloc; 101 set->list[alloc].alloc_next = -1; 102 103 return 1; 104} 105 106/* setFirst -> setAdd -> setNext is wrong */ 107 108int setFirst(set_t *set, ITEM_TYPE *item) 109{ 110 if (set->alloc == -1) 111 return 0; 112 113 *item = set->list[set->alloc].val; 114 set->trace = set->list[set->alloc].alloc_next; 115 116 return 1; 117} 118 119int setNext(set_t *set, ITEM_TYPE *item) 120{ 121 if (set->trace == -1) 122 return 0; 123 124 *item = set->list[set->trace].val; 125 set->trace = set->list[set->trace].alloc_next; 126 127 return 1; 128} 129 130int setDestroy(set_t *set) 131{ 132 DRM(free)(set, sizeof(set_t), DRM_MEM_DRIVER); 133 134 return 1; 135} 136 137/* 138 * GLX Hardware Device Driver common code 139 * Copyright (C) 1999 Keith Whitwell 140 * 141 * Permission is hereby granted, free of charge, to any person obtaining a 142 * copy of this software and associated documentation files (the "Software"), 143 * to deal in the Software without restriction, including without limitation 144 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 145 * and/or sell copies of the Software, and to permit persons to whom the 146 * Software is furnished to do so, subject to the following conditions: 147 * 148 * The above copyright notice and this permission notice shall be included 149 * in all copies or substantial portions of the Software. 150 * 151 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 152 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 153 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 154 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 155 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 156 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 157 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 158 * 159 */ 160 161#define ISFREE(bptr) ((bptr)->free) 162 163memHeap_t *mmInit(int ofs, 164 int size) 165{ 166 PMemBlock blocks; 167 168 if (size <= 0) 169 return 0; 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 0; 179} 180 181/* Checks if a pointer 'b' is part of the heap 'heap' */ 182int 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 199/* Kludgey workaround for existing i810 server. Remove soon. 200 */ 201memHeap_t *mmAddRange( memHeap_t *heap, 202 int ofs, 203 int size ) 204{ 205 PMemBlock blocks; 206 blocks = (TMemBlock *)DRM(calloc)(2, sizeof(TMemBlock), DRM_MEM_DRIVER); 207 if (blocks != NULL) { 208 blocks[0].size = size; 209 blocks[0].free = 1; 210 blocks[0].ofs = ofs; 211 blocks[0].next = &blocks[1]; 212 213 /* Discontinuity - stops JoinBlock from trying to join 214 * non-adjacent ranges. 215 */ 216 blocks[1].size = 0; 217 blocks[1].free = 0; 218 blocks[1].ofs = ofs+size; 219 blocks[1].next = (PMemBlock)heap; 220 return (memHeap_t *)blocks; 221 } else 222 return heap; 223} 224 225static TMemBlock* SliceBlock(TMemBlock *p, 226 int startofs, int size, 227 int reserved, int alignment) 228{ 229 TMemBlock *newblock; 230 231 /* break left */ 232 if (startofs > p->ofs) { 233 newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock), 234 DRM_MEM_DRIVER); 235 newblock->ofs = startofs; 236 newblock->size = p->size - (startofs - p->ofs); 237 newblock->free = 1; 238 newblock->next = p->next; 239 p->size -= newblock->size; 240 p->next = newblock; 241 p = newblock; 242 } 243 244 /* break right */ 245 if (size < p->size) { 246 newblock = (TMemBlock*) DRM(calloc)(1, sizeof(TMemBlock), 247 DRM_MEM_DRIVER); 248 newblock->ofs = startofs + size; 249 newblock->size = p->size - size; 250 newblock->free = 1; 251 newblock->next = p->next; 252 p->size = size; 253 p->next = newblock; 254 } 255 256 /* p = middle block */ 257 p->align = alignment; 258 p->free = 0; 259 p->reserved = reserved; 260 return p; 261} 262 263PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch) 264{ 265 int mask,startofs, endofs; 266 TMemBlock *p; 267 268 if (heap == NULL || align2 < 0 || size <= 0) 269 return NULL; 270 271 mask = (1 << align2)-1; 272 startofs = 0; 273 p = (TMemBlock *)heap; 274 while (p != NULL) { 275 if (ISFREE(p)) { 276 startofs = (p->ofs + mask) & ~mask; 277 if ( startofs < startSearch ) { 278 startofs = startSearch; 279 } 280 endofs = startofs+size; 281 if (endofs <= (p->ofs+p->size)) 282 break; 283 } 284 p = p->next; 285 } 286 if (p == NULL) 287 return NULL; 288 p = SliceBlock(p,startofs,size,0,mask+1); 289 p->heap = heap; 290 return p; 291} 292 293static __inline__ int Join2Blocks(TMemBlock *p) 294{ 295 if (p->free && p->next && p->next->free) { 296 TMemBlock *q = p->next; 297 p->size += q->size; 298 p->next = q->next; 299 DRM(free)(q, sizeof(TMemBlock), DRM_MEM_DRIVER); 300 return 1; 301 } 302 return 0; 303} 304 305int mmFreeMem(PMemBlock b) 306{ 307 TMemBlock *p, *prev; 308 309 if (b == NULL) 310 return 0; 311 if (b->heap == NULL) 312 return -1; 313 314 p = b->heap; 315 prev = NULL; 316 while (p != NULL && p != b) { 317 prev = p; 318 p = p->next; 319 } 320 if (p == NULL || p->free || p->reserved) 321 return -1; 322 323 p->free = 1; 324 Join2Blocks(p); 325 if (prev) 326 Join2Blocks(prev); 327 return 0; 328} 329 330int mmReserveMem(memHeap_t *heap, int offset,int size) 331{ 332 int endofs; 333 TMemBlock *p; 334 335 if (heap == NULL || size <= 0) 336 return -1; 337 338 endofs = offset + size; 339 p = (TMemBlock *)heap; 340 while (p && p->ofs <= offset) { 341 if (ISFREE(p) && endofs <= (p->ofs+p->size)) { 342 SliceBlock(p,offset,size,1,1); 343 return 0; 344 } 345 p = p->next; 346 } 347 return -1; 348} 349 350int mmFreeReserved(memHeap_t *heap, int offset) 351{ 352 TMemBlock *p,*prev; 353 354 if (heap == NULL) 355 return -1; 356 357 p = (TMemBlock *)heap; 358 prev = NULL; 359 while (p != NULL && p->ofs != offset) { 360 prev = p; 361 p = p->next; 362 } 363 if (p == NULL || !p->reserved) 364 return -1; 365 366 p->free = 1; 367 p->reserved = 0; 368 Join2Blocks(p); 369 if (prev != NULL) 370 Join2Blocks(prev); 371 return 0; 372} 373 374void mmDestroy(memHeap_t *heap) 375{ 376 TMemBlock *p,*q; 377 378 if (heap == NULL) 379 return; 380 381 p = (TMemBlock *)heap; 382 while (p != NULL) { 383 q = p->next; 384 DRM(free)(p, sizeof(TMemBlock), DRM_MEM_DRIVER); 385 p = q; 386 } 387} 388