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:
Warner Losh 2000-10-17 22:08:03 +00:00
parent ef73bfb0f4
commit 85d693f9d8
2 changed files with 30 additions and 1 deletions

@ -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)