2 Copyright � 2003-2007, The AROS Development Team. All rights reserved.
8 #include <exec/types.h>
9 #include <proto/exec.h>
10 #include <aros/debug.h>
11 #include <exec/memory.h>
12 #include <exec/memheaderext.h>
14 LONG
bfffo(ULONG val
, UBYTE bitoffset
)
16 val
&= (0xffffffff >> bitoffset
);
18 return __builtin_clz(val
);
23 LONG
bfflo(ULONG val
, UBYTE bitoffset
)
25 val
&= (0xffffffff << (31-bitoffset
));
27 return 31-__builtin_ctz(val
);
32 LONG
bfffz(ULONG val
, UBYTE bitoffset
)
34 return bfffo(~val
, bitoffset
);
37 LONG
bfflz(ULONG val
, UBYTE bitoffset
)
39 return bfflo(~val
, bitoffset
);
42 ULONG
bfset(ULONG data
, UBYTE bitoffset
, UBYTE bits
)
44 ULONG mask
= ~((1 << (32 - bits
)) - 1);
49 ULONG
bfclr(ULONG data
, UBYTE bitoffset
, UBYTE bits
)
51 ULONG mask
= ~((1 << (32 - bits
)) - 1);
58 ULONG
const w
= v
- ((v
>> 1) & 0x55555555); // temp
59 ULONG
const x
= (w
& 0x33333333) + ((w
>> 2) & 0x33333333); // temp
60 ULONG
const c
= ((x
+ ((x
>> 4) & 0xF0F0F0F)) * 0x1010101) >> 24; // count
70 LONG
bmffo(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
)
76 longoffset
= bitoffset
>> 5;
80 bitoffset
= bitoffset
& 0x1F;
83 if ((bit
= bfffo(*scan
, bitoffset
)) < 32) {
84 return (bit
+ ((scan
- bitmap
) << 5));
93 return (bfffo(*scan
,0) + ((scan
- bitmap
) << 5));
100 LONG
bmffz(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
)
102 ULONG
*scan
= bitmap
;
103 ULONG err
= 32*longs
;
106 longoffset
= bitoffset
>> 5;
110 bitoffset
= bitoffset
& 0x1F;
112 if (bitoffset
!= 0) {
113 if ((bit
= bfffz(*scan
, bitoffset
)) < 32) {
114 return (bit
+ ((scan
- bitmap
) << 5));
120 while (longs
-- > 0) {
121 if (*scan
++ != 0xFFFFFFFF) {
123 return (bfffz(*scan
,0) + ((scan
- bitmap
) << 5));
130 LONG
bmclr(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
, LONG bits
)
132 ULONG
*scan
= bitmap
;
136 longoffset
= bitoffset
>> 5;
140 bitoffset
= bitoffset
& 0x1F;
142 if (bitoffset
!= 0) {
144 *scan
= bfclr(*scan
, bitoffset
, bits
);
146 *scan
= bfclr(*scan
, bitoffset
, 32);
150 bits
-= 32 - bitoffset
;
153 while (bits
> 0 && longs
-- > 0) {
157 *scan
= bfclr(*scan
, 0, bits
);
165 return (orgbits
- bits
);
168 LONG
bmset(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
, LONG bits
)
170 ULONG
*scan
= bitmap
;
174 longoffset
= bitoffset
>> 5;
178 bitoffset
= bitoffset
& 0x1F;
180 if (bitoffset
!= 0) {
182 *scan
= (bfset((*scan
), bitoffset
, bits
));
184 *scan
= (bfset((*scan
), bitoffset
, 32));
188 bits
-= 32 - bitoffset
;
191 while (bits
> 0 && longs
-- > 0) {
193 *scan
++ = 0xFFFFFFFF;
195 *scan
= (bfset((*scan
), 0, bits
));
203 return (orgbits
- bits
);
206 int bmtstz(ULONG
*bitmap
, ULONG bitoffset
, LONG bits
)
208 LONG longoffset
= bitoffset
>> 5;
209 ULONG
*scan
= bitmap
;
217 if ((bits
+ bitoffset
) < 32)
219 mask
= (0xffffffff >> bitoffset
) & (0xffffffff << (32 - (bits
+bitoffset
)));
224 mask
= (0xffffffff >> bitoffset
);
225 bits
-= (32-bitoffset
);
227 if ((mask
& (*scan
++)) != 0)
240 mask
= 0xffffffff << (32-bits
);
243 if ((mask
& (*scan
++)) != 0)
250 ULONG
bmcnto(ULONG
*bitmap
, LONG bitoffset
, LONG bits
)
252 LONG longoffset
= bitoffset
>> 5;
253 ULONG
*scan
= bitmap
;
262 if ((bits
+ bitoffset
) < 32)
264 mask
= (0xffffffff >> bitoffset
) & (0xffffffff << (32 - (bits
+bitoffset
)));
269 mask
= (0xffffffff >> bitoffset
);
270 bits
-= (32-bitoffset
);
272 count
+= bfcnto(*scan
++ & mask
);
284 mask
= 0xffffffff << (32-bits
);
287 count
+= bfcnto(*scan
++ & mask
);
293 ULONG
bmcntz(ULONG
*bitmap
, LONG bitoffset
, LONG bits
)
295 LONG longoffset
= bitoffset
>> 5;
296 ULONG
*scan
= bitmap
;
305 if ((bits
+ bitoffset
) < 32)
307 mask
= ~((0xffffffff >> bitoffset
) & (0xffffffff << (32 - (bits
+bitoffset
))));
312 mask
= ~(0xffffffff >> bitoffset
);
313 bits
-= (32-bitoffset
);
316 count
+= bfcntz(*scan
++ | mask
);
328 mask
= ~(0xffffffff << (32-bits
));
332 count
+= bfcntz(*scan
++ | mask
);
338 void *mh_Alloc(struct MemHeaderExt
*mhe
, IPTR size
, ULONG
*flags
)
343 void mh_Free(struct MemHeaderExt
*mhe
, APTR mem
, IPTR size
)
347 void *mh_AllocAbs(struct MemHeaderExt
*mhe
, IPTR size
, APTR mem
)
352 void *mh_ReAlloc(struct MemHeaderExt
*mhe
, APTR old
, IPTR size
)
357 IPTR
mh_Avail(struct MemHeaderExt
*mhe
, ULONG flags
)
359 struct ati_staticdata
*sd
= (APTR
)mhe
->mhe_UserData
;
364 ObtainSemaphore(&sd
->CardMemLock
);
366 if (flags
& MEMF_TOTAL
)
367 size
= sd
->Card
.FbUsableSize
;
368 else if (flags
& MEMF_LARGEST
)
372 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, 0);
374 while (ptr
< (sd
->CardMemSize
<< 5))
376 ULONG tmpptr
= bmffo(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
);
378 if ((tmpptr
- ptr
) > size
)
381 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, tmpptr
);
387 size
= bmcntz(sd
->CardMemBmp
, 0, sd
->Card
.FbUsableSize
>> 10) << 10;
391 ReleaseSemaphore(&sd
->CardMemLock
);
396 void BitmapInit(struct ati_staticdata
*sd
)
399 * If Radeon chip has some video memory, create a bitmap representing all allocations.
400 * Divide whole memory into 1KB chunks
402 if (sd
->Card
.FbUsableSize
)
404 sd
->CardMemBmp
= AllocPooled(sd
->memPool
, sd
->Card
.FbUsableSize
>> 13);
406 sd
->managedMem
.mhe_MemHeader
.mh_Node
.ln_Type
= NT_MEMORY
;
407 sd
->managedMem
.mhe_MemHeader
.mh_Node
.ln_Name
= "Radeon VRAM";
408 sd
->managedMem
.mhe_MemHeader
.mh_Node
.ln_Pri
= -128;
409 sd
->managedMem
.mhe_MemHeader
.mh_Attributes
= MEMF_CHIP
| MEMF_MANAGED
| MEMF_PUBLIC
;
411 sd
->managedMem
.mhe_UserData
= sd
;
413 sd
->managedMem
.mhe_Alloc
= mh_Alloc
;
414 sd
->managedMem
.mhe_Free
= mh_Free
;
415 sd
->managedMem
.mhe_AllocAbs
= mh_AllocAbs
;
416 sd
->managedMem
.mhe_ReAlloc
= mh_ReAlloc
;
417 sd
->managedMem
.mhe_Avail
= mh_Avail
;
420 AddTail(&SysBase
->MemList
, (struct Node
*)&sd
->managedMem
);
424 /* Number of ULONG's in bitmap */
425 sd
->CardMemSize
= sd
->Card
.FbUsableSize
>> 15;
427 bug("[ATIBMP] Bitmap at %p, size %d bytes (%d bits)\n", sd
->CardMemBmp
, sd
->CardMemSize
<< 2, sd
->Card
.FbUsableSize
>> 10);
430 void BitmapFree(struct ati_staticdata
*sd
, ULONG ptr
, ULONG size
)
432 if (ptr
+ size
< sd
->Card
.FbUsableSize
)
434 bmclr(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
>> 10, (size
+ 1023) >> 10);
438 ULONG
BitmapAlloc(struct ati_staticdata
*sd
, ULONG size
)
441 size
= (size
+ 1023) >> 10;
443 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, 0);
445 D(bug("[ATIBMP] BitmapAlloc(%d)\n", size
));
447 while (ptr
<= (sd
->CardMemSize
<< 5) + size
)
449 D(bug("[ATIBMP] ptr=%08x\n", ptr
));
451 if (bmtstz(sd
->CardMemBmp
, ptr
, size
))
453 bmset(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
, size
);
457 ptr
= bmffo(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
);
458 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
);
461 if (ptr
> (sd
->CardMemSize
<< 5) - size
)