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));
92 return (bfffo(*--scan
,0) + ((scan
- bitmap
) << 5));
99 LONG
bmffz(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
)
101 ULONG
*scan
= bitmap
;
102 ULONG err
= 32*longs
;
105 longoffset
= bitoffset
>> 5;
109 bitoffset
= bitoffset
& 0x1F;
111 if (bitoffset
!= 0) {
112 if ((bit
= bfffz(*scan
, bitoffset
)) < 32) {
113 return (bit
+ ((scan
- bitmap
) << 5));
119 while (longs
-- > 0) {
120 if (*scan
++ != 0xFFFFFFFF) {
121 return (bfffz(*--scan
,0) + ((scan
- bitmap
) << 5));
128 LONG
bmclr(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
, LONG bits
)
130 ULONG
*scan
= bitmap
;
134 longoffset
= bitoffset
>> 5;
138 bitoffset
= bitoffset
& 0x1F;
140 if (bitoffset
!= 0) {
142 *scan
= bfclr(*scan
, bitoffset
, bits
);
144 *scan
= bfclr(*scan
, bitoffset
, 32);
148 bits
-= 32 - bitoffset
;
151 while (bits
> 0 && longs
-- > 0) {
155 *scan
= bfclr(*scan
, 0, bits
);
163 return (orgbits
- bits
);
166 LONG
bmset(ULONG
*bitmap
, ULONG longs
, LONG bitoffset
, LONG bits
)
168 ULONG
*scan
= bitmap
;
172 longoffset
= bitoffset
>> 5;
176 bitoffset
= bitoffset
& 0x1F;
178 if (bitoffset
!= 0) {
180 *scan
= (bfset((*scan
), bitoffset
, bits
));
182 *scan
= (bfset((*scan
), bitoffset
, 32));
186 bits
-= 32 - bitoffset
;
189 while (bits
> 0 && longs
-- > 0) {
191 *scan
++ = 0xFFFFFFFF;
193 *scan
= (bfset((*scan
), 0, bits
));
201 return (orgbits
- bits
);
204 int bmtstz(ULONG
*bitmap
, ULONG bitoffset
, LONG bits
)
206 LONG longoffset
= bitoffset
>> 5;
207 ULONG
*scan
= bitmap
;
215 if ((bits
+ bitoffset
) < 32)
217 mask
= (0xffffffff >> bitoffset
) & (0xffffffff << (32 - (bits
+bitoffset
)));
222 mask
= (0xffffffff >> bitoffset
);
223 bits
-= (32-bitoffset
);
225 if ((mask
& (*scan
++)) != 0)
238 mask
= 0xffffffff << (32-bits
);
241 if ((mask
& (*scan
++)) != 0)
248 ULONG
bmcnto(ULONG
*bitmap
, LONG bitoffset
, LONG bits
)
250 LONG longoffset
= bitoffset
>> 5;
251 ULONG
*scan
= bitmap
;
260 if ((bits
+ bitoffset
) < 32)
262 mask
= (0xffffffff >> bitoffset
) & (0xffffffff << (32 - (bits
+bitoffset
)));
267 mask
= (0xffffffff >> bitoffset
);
268 bits
-= (32-bitoffset
);
270 count
+= bfcnto(*scan
++ & mask
);
282 mask
= 0xffffffff << (32-bits
);
285 count
+= bfcnto(*scan
++ & mask
);
291 ULONG
bmcntz(ULONG
*bitmap
, LONG bitoffset
, LONG bits
)
293 LONG longoffset
= bitoffset
>> 5;
294 ULONG
*scan
= bitmap
;
303 if ((bits
+ bitoffset
) < 32)
305 mask
= ~((0xffffffff >> bitoffset
) & (0xffffffff << (32 - (bits
+bitoffset
))));
310 mask
= ~(0xffffffff >> bitoffset
);
311 bits
-= (32-bitoffset
);
314 count
+= bfcntz(*scan
++ | mask
);
326 mask
= ~(0xffffffff << (32-bits
));
330 count
+= bfcntz(*scan
++ | mask
);
336 void *mh_Alloc(struct MemHeaderExt
*mhe
, ULONG size
, ULONG
*flags
)
341 void mh_Free(struct MemHeaderExt
*mhe
, APTR mem
, ULONG size
)
345 void *mh_AllocAbs(struct MemHeaderExt
*mhe
, APTR mem
, ULONG size
)
350 void *mh_ReAlloc(struct MemHeaderExt
*mhe
, APTR old
, ULONG size
)
355 ULONG
mh_Avail(struct MemHeaderExt
*mhe
, ULONG flags
)
357 struct ati_staticdata
*sd
= mhe
->mhe_UserData
;
362 if (flags
& MEMF_TOTAL
)
363 size
= sd
->Card
.FbUsableSize
;
364 else if (flags
& MEMF_LARGEST
)
368 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, 0);
370 while (ptr
< (sd
->CardMemSize
<< 5))
372 ULONG tmpptr
= bmffo(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
);
374 if ((tmpptr
- ptr
) > size
)
377 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, tmpptr
);
383 size
= bmcntz(sd
->CardMemBmp
, 0, sd
->Card
.FbUsableSize
>> 10) << 10;
390 void BitmapInit(struct ati_staticdata
*sd
)
393 * If Radeon chip has some video memory, create a bitmap representing all allocations.
394 * Divide whole memory into 1KB chunks
396 if (sd
->Card
.FbUsableSize
)
398 sd
->CardMemBmp
= AllocPooled(sd
->memPool
, sd
->Card
.FbUsableSize
>> 13);
400 sd
->managedMem
.mhe_MemHeader
.mh_Node
.ln_Type
= NT_MEMORY
;
401 sd
->managedMem
.mhe_MemHeader
.mh_Node
.ln_Name
= "Radeon VRAM";
402 sd
->managedMem
.mhe_MemHeader
.mh_Node
.ln_Pri
= -128;
403 sd
->managedMem
.mhe_MemHeader
.mh_Attributes
= MEMF_CHIP
| MEMF_MANAGED
| MEMF_PUBLIC
;
405 sd
->managedMem
.mhe_UserData
= sd
;
407 sd
->managedMem
.mhe_Alloc
= mh_Alloc
;
408 sd
->managedMem
.mhe_Free
= mh_Free
;
409 sd
->managedMem
.mhe_AllocAbs
= mh_AllocAbs
;
410 sd
->managedMem
.mhe_ReAlloc
= mh_ReAlloc
;
411 sd
->managedMem
.mhe_Avail
= mh_Avail
;
414 AddTail(&SysBase
->MemList
, &sd
->managedMem
);
418 /* Number of ULONG's in bitmap */
419 sd
->CardMemSize
= sd
->Card
.FbUsableSize
>> 15;
421 bug("[ATIBMP] Bitmap at %p, size %d bytes (%d bits)\n", sd
->CardMemBmp
, sd
->CardMemSize
<< 2, sd
->Card
.FbUsableSize
>> 10);
424 void BitmapFree(struct ati_staticdata
*sd
, ULONG ptr
, ULONG size
)
426 if (ptr
+ size
< sd
->Card
.FbUsableSize
)
428 bmclr(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
>> 10, (size
+ 1023) >> 10);
432 ULONG
BitmapAlloc(struct ati_staticdata
*sd
, ULONG size
)
435 size
= (size
+ 1023) >> 10;
437 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, 0);
439 D(bug("[ATIBMP] BitmapAlloc(%d)\n", size
));
441 while (ptr
<= (sd
->CardMemSize
<< 5) + size
)
443 D(bug("[ATIBMP] ptr=%08x\n", ptr
));
445 if (bmtstz(sd
->CardMemBmp
, ptr
, size
))
447 bmset(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
, size
);
451 ptr
= bmffo(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
);
452 ptr
= bmffz(sd
->CardMemBmp
, sd
->CardMemSize
, ptr
);
455 if (ptr
> (sd
->CardMemSize
<< 5) - size
)