Implement resource alignment as discussed in arch@ a long time ago.
This was implemented by Shigeru YAMAMOTO-san and Jonathan Chen. I've cleaned them up somewhat and they seem to work well enough to boot current (but given current's state it can be hard to tell). Doug Rabson also reviewed the design and signed off on it.
This commit is contained in:
parent
ef73bfb0f4
commit
85d693f9d8
sys
@ -223,7 +223,9 @@ rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count,
|
||||
continue;
|
||||
}
|
||||
rstart = max(s->r_start, start);
|
||||
rend = min(s->r_end, max(start + count, end));
|
||||
rstart = (rstart + ((1ul << RF_ALIGNMENT(flags))) - 1) &
|
||||
~((1ul << RF_ALIGNMENT(flags)) - 1);
|
||||
rend = min(s->r_end, max(rstart + count, end));
|
||||
DPRINTF(("truncated region: [%#lx, %#lx]; size %#lx (requested %#lx)\n",
|
||||
rstart, rend, (rend - rstart + 1), count));
|
||||
|
||||
@ -591,3 +593,23 @@ rman_release_resource(struct resource *r)
|
||||
simple_unlock(rm->rm_slock);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rman_make_alignment_flags(uint32_t size)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
for (i = 0, count = 0; i < 32 && size > 0x01; i++) {
|
||||
count += size & 1;
|
||||
size >>= 1;
|
||||
}
|
||||
|
||||
if (count > 0)
|
||||
i ++;
|
||||
|
||||
if (i > 31)
|
||||
i = 0;
|
||||
|
||||
return(RF_ALIGNMENT_LOG2(i));
|
||||
}
|
||||
|
@ -64,6 +64,12 @@ struct resource {
|
||||
#define RF_WANTED 0x0010 /* somebody is waiting for this resource */
|
||||
#define RF_FIRSTSHARE 0x0020 /* first in sharing list */
|
||||
|
||||
#define RF_ALIGNMENT_SHIFT 10 /* alignment size bit starts bit 10 */
|
||||
#define RF_ALIGNMENT_MASK (0x003F << RF_ALIGNMENT_SHIFT)
|
||||
/* resource address alignemnt size bit mask */
|
||||
#define RF_ALIGNMENT_LOG2(x) ((x) << RF_ALIGNMENT_SHIFT)
|
||||
#define RF_ALIGNMENT(x) (((x) & RF_ALIGNMENT_MASK) >> RF_ALIGNMENT_SHIFT)
|
||||
|
||||
enum rman_type { RMAN_UNINIT = 0, RMAN_GAUGE, RMAN_ARRAY };
|
||||
|
||||
struct rman {
|
||||
@ -89,6 +95,7 @@ int rman_release_resource(struct resource *r);
|
||||
struct resource *rman_reserve_resource(struct rman *rm, u_long start,
|
||||
u_long end, u_long count,
|
||||
u_int flags, struct device *dev);
|
||||
uint32_t rman_make_alignment_flags(uint32_t size);
|
||||
|
||||
#define rman_get_start(r) ((r)->r_start)
|
||||
#define rman_get_end(r) ((r)->r_end)
|
||||
|
Loading…
x
Reference in New Issue
Block a user