>>>>> "Doug" == Doug Rabson <Doug> writes:
>> Well, with just 6 bits one could handle any alignment requirement up to
>> 2^(2^6).
>> 
>> We have 6 bits left.  If this were the alignment requirement, a value of
>> 0 would mean 2^0 or 1, which is the current behavior.  More restrictive
>> alignment requirements could be encoded easily.  No ABI or API change
>> needed.
>> 
>> #define RF_ALIGNMENT_MASK 0xfc00
>> #define RF_ALIGNMENT_SHIFT 10
>> #define RF_ALIGNMENT_LOG2(x) (x << RF_ALIGNMENT_SHIFT)
Doug> That seems reasonable. We should implement this right after 4.0 is
Doug> done.

I re-write a code using Warner's idea.

Thanks,
-------
YAMAMOTO Shigeru                        Internet Initiative Japan Inc.
<[EMAIL PROTECTED]>                     Network Engineering Div.
--- kern/subr_rman.c.org        Tue Nov 16 08:28:57 1999
+++ kern/subr_rman.c    Sat Jan 29 03:40:36 2000
@@ -227,7 +227,19 @@
                        continue;
                }
                rstart = max(s->r_start, start);
-               rend = min(s->r_end, max(start + count, end));
+               if (flags & RF_ALIGNMENT_MASK) {
+               /* need to align an address */
+                       u_long  aligned_rstart;
+                       u_long  alignment_size;
+
+                       alignment_size = (1u << ((flags & RF_ALIGNMENT_MASK) >> 
+RF_ALIGNMENT_SHIFT));
+                       aligned_rstart = (rstart & (~alignment_size + 1u));
+                       if ((rstart & (~(~alignment_size + 1u))) != 0) {
+                               aligned_rstart += alignment_size;
+                       }
+                       rstart = aligned_rstart;
+               }
+               rend = min(s->r_end, max(max(start + count, end), rstart + count));
 #ifdef RMAN_DEBUG
                printf("truncated region: [%#lx, %#lx]; size %#lx (requested %#lx)\n",
                       rstart, rend, (rend - rstart + 1), count);
@@ -608,4 +620,19 @@
        rv = int_rman_release_resource(rm, r);
        simple_unlock(rm->rm_slock);
        return (rv);
+}
+
+u_int32_t
+rman_make_alignment_flags(int size) {
+       int     i;
+
+       for (i = 0; i < 32 && size > 0x01; i ++) {
+               size = (size >> 1);
+       }
+
+       if (i > 31) {
+               i = 0;
+       }
+
+       return(RF_ALIGNMENT_LOG2(i));
 }
--- sys/rman.h.org      Mon Jan 10 08:48:52 2000
+++ sys/rman.h  Sat Jan 29 03:44:40 2000
@@ -64,7 +64,11 @@
 #define        RF_WANTED       0x0010  /* somebody is waiting for this resource */
 #define        RF_FIRSTSHARE   0x0020  /* first in sharing list */
 
-#define RF_PCCARD_ATTR 0x10000 /* PCCARD attribute memory */
+#define        RF_PCCARD_ATTR  0x10000 /* PCCARD attribute memory */
+
+#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)
 
 enum   rman_type { RMAN_UNINIT = 0, RMAN_GAUGE, RMAN_ARRAY };
 
@@ -91,6 +95,8 @@
 struct resource *rman_reserve_resource(struct rman *rm, u_long start,
                                        u_long end, u_long count,
                                        u_int flags, struct device *dev);
+
+extern u_int32_t       rman_make_alignment_flags       __P((int size));
 
 #define rman_get_start(r)      ((r)->r_start)
 #define rman_get_end(r)                ((r)->r_end)

Reply via email to