summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/subr_rman.c24
-rw-r--r--sys/sys/rman.h7
2 files changed, 30 insertions, 1 deletions
diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c
index 2746acfad72f..91a7bcdafcff 100644
--- a/sys/kern/subr_rman.c
+++ b/sys/kern/subr_rman.c
@@ -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));
+ }
diff --git a/sys/sys/rman.h b/sys/sys/rman.h
index 0e59f75fced4..6561554fcfbd 100644
--- a/sys/sys/rman.h
+++ b/sys/sys/rman.h
@@ -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)