]> Zhao Yanbai Git Server - minix.git/commitdiff
let drivers allocate memory at 64k physical boundary.
authorBen Gras <ben@minix3.org>
Thu, 12 Feb 2009 12:26:08 +0000 (12:26 +0000)
committerBen Gras <ben@minix3.org>
Thu, 12 Feb 2009 12:26:08 +0000 (12:26 +0000)
include/minix/syslib.h
include/sys/mman.h
lib/syslib/alloc_util.c
servers/vm/alloc.c
servers/vm/mmap.c
servers/vm/region.c
servers/vm/region.h
servers/vm/vm.h

index 391837ea5b34172266e2a2fcd27c2c67b43f10a4..24f394b820fae3bc599653d6ce75fa711286bbf3 100755 (executable)
@@ -84,6 +84,7 @@ _PROTOTYPE( int sys_sdevio, (int req, long port, endpoint_t proc_nr,
 _PROTOTYPE(void *alloc_contig, (size_t len, int flags, phys_bytes *phys));
 #define AC_ALIGN4K     0x01
 #define AC_LOWER16M    0x02
+#define AC_ALIGN64K    0x04
 
 /* Clock functionality: get system times or (un)schedule an alarm call. */
 _PROTOTYPE( int sys_times, (endpoint_t proc_nr, clock_t *user_time,
index 1c3ef37a251f275d7024fd1de1876aaf283b115d..7209fc9be124451a570f80a60443833c0a02112e 100755 (executable)
@@ -19,6 +19,7 @@
 #define MAP_PREALLOC   0x0008          /* not on-demand */
 #define MAP_CONTIG     0x0010          /* contiguous in physical memory */
 #define MAP_LOWER16M   0x0020          /* physically below 16MB */
+#define MAP_ALIGN64K   0x0040          /* physically aligned at 64kB */
 
 /* mmap() error return */
 #define MAP_FAILED      ((void *)-1)
index 269b3b43af900f51ecf2266dcf33dfcadb3e7559..a2a5bd7619fff31aecb50b09869bb93aa3e95442 100644 (file)
@@ -29,6 +29,8 @@ void *alloc_contig(size_t len, int flags, phys_bytes *phys)
 
        if(flags & AC_LOWER16M)
                mmapflags |= MAP_LOWER16M;
+       if(flags & AC_ALIGN64K)
+               mmapflags |= MAP_ALIGN64K;
 
        /* First try to get memory with mmap. This is gauranteed
         * to be page-aligned, and we can tell VM it has to be
@@ -44,20 +46,22 @@ void *alloc_contig(size_t len, int flags, phys_bytes *phys)
         * so we can page align it ourselves.
         */
        if(buf == (vir_bytes) MAP_FAILED) {
+               u32_t align = 0;
                if(errno != (_SIGN ENXIO)) {
                        return NULL;
                }
-#define ALIGN 4096
-               if(flags & AC_ALIGN4K) {
-                       if(len + ALIGN < len)
-                               return NULL;
-                       len += ALIGN;
-               }
+               if(flags & AC_ALIGN4K)
+                       align = 4*1024;
+               if(flags & AC_ALIGN64K)
+                       align = 64*1024;
+               if(len + align < len)
+                       return NULL;
+               len += align;
                if(!(buf = (vir_bytes) malloc(len))) {
                        return NULL;
                }
-               if(flags & AC_ALIGN4K)
-                       buf += ALIGN - (buf % ALIGN);
+               if(align)
+                       buf += align - (buf % align);
        }
 
        /* Get physical address. */
index e28f4574d0f9996d60ef298b24bb05132d37ff3e..7ab0fd48861aac04f34270db30633d69efd47db9 100644 (file)
@@ -206,17 +206,19 @@ PUBLIC phys_clicks alloc_mem_f(phys_clicks clicks, u32_t memflags)
  * needed for FORK or EXEC.
  */
   register struct hole *hp, *prev_ptr;
-  phys_clicks old_base;
+  phys_clicks old_base, mem = NO_MEM, align_clicks = 0;
   int s;
 
-  if(vm_paged) {
-       vm_assert(CLICK_SIZE == VM_PAGE_SIZE);
-       return alloc_pages(clicks, memflags);
+  if(memflags & PAF_ALIGN64K) {
+       align_clicks = (64 * 1024) / CLICK_SIZE;
+       clicks += align_clicks;
   }
 
+  if(vm_paged) {
+       vm_assert(CLICK_SIZE == VM_PAGE_SIZE);
+       mem = alloc_pages(clicks, memflags);
+  } else {
 CHECKHOLES;
-
-  {
         prev_ptr = NIL_HOLE;
        hp = hole_head;
        while (hp != NIL_HOLE) {
@@ -239,15 +241,33 @@ CHECKHOLES;
 
                        /* Return the start address of the acquired block. */
 CHECKHOLES;
-                       return(old_base);
+                       mem = old_base;
+                       break;
                }
 
                prev_ptr = hp;
                hp = hp->h_next;
        }
   }
+
+  if(mem == NO_MEM)
+       return mem;
+
 CHECKHOLES;
-  return(NO_MEM);
+
+  if(align_clicks) {
+       phys_clicks o;
+       o = mem % align_clicks;
+       if(o > 0) {
+               phys_clicks e;
+               e = align_clicks - o;
+               FREE_MEM(mem, e);
+               mem += e;
+       }
+  }
+CHECKHOLES;
+
+  return mem;
 }
 
 /*===========================================================================*
index f519f9538d5a0ced32248e020a4f5f44d03c7bf1..1bbbf699e61ef2075ebc3cd28c6d85af78528ed7 100644 (file)
@@ -57,6 +57,7 @@ PUBLIC int do_mmap(message *m)
        if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
                int s;
                vir_bytes v;
+               u32_t vrflags = VR_ANON | VR_WRITABLE;
                size_t len = (vir_bytes) m->VMM_LEN;
 
                if(m->VMM_FD != -1) {
@@ -65,13 +66,14 @@ PUBLIC int do_mmap(message *m)
 
                if(m->VMM_FLAGS & MAP_CONTIG) mfflags |= MF_CONTIG;
                if(m->VMM_FLAGS & MAP_PREALLOC) mfflags |= MF_PREALLOC;
+               if(m->VMM_FLAGS & MAP_ALIGN64K) vrflags |= VR_PHYS64K;
 
                if(len % VM_PAGE_SIZE)
                        len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
 
                if(!(vr = map_page_region(vmp,
                        arch_vir2map(vmp, vmp->vm_stacktop), VM_DATATOP, len, MAP_NONE,
-                       VR_ANON | VR_WRITABLE, mfflags))) {
+                       vrflags, mfflags))) {
                        return ENOMEM;
                }
        } else {
index 358996db8a06c575e87cb9f8fc67bef10c26dda1..0784b9db857e84d9ad6da6e3208a0d71a9a76aae 100644 (file)
@@ -432,7 +432,10 @@ struct phys_region *physhint;
        /* Memory for new physical block. */
        clicks = CLICKSPERPAGE * length / VM_PAGE_SIZE;
        if(what_mem == MAP_NONE) {
-               if((mem_clicks = ALLOC_MEM(clicks, PAF_CLEAR)) == NO_MEM) {
+               u32_t af = PAF_CLEAR;
+               if(region->flags & VR_PHYS64K)
+                       af |= PAF_ALIGN64K;
+               if((mem_clicks = ALLOC_MEM(clicks, af)) == NO_MEM) {
                        SLABFREE(newpb);
                        SLABFREE(newphysr);
                        return ENOMEM;
@@ -499,6 +502,7 @@ struct phys_region *ph;
        int r;
        phys_bytes newmem, newmem_cl, clicks;
        struct phys_block *newpb;
+       u32_t af = 0;
 
        SANITYCHECK(SCL_FUNCTIONS);
 
@@ -514,7 +518,9 @@ struct phys_region *ph;
 
        clicks = CLICKSPERPAGE * ph->ph->length / VM_PAGE_SIZE;
        vm_assert(CLICK2ABS(clicks) == ph->ph->length);
-       if((newmem_cl = ALLOC_MEM(clicks, 0)) == NO_MEM) {
+       if(region->flags & VR_PHYS64K)
+               af |= PAF_ALIGN64K;
+       if((newmem_cl = ALLOC_MEM(clicks, af)) == NO_MEM) {
                SLABFREE(newpb);
                return ENOMEM;
        }
index a134ef73cbcd775b1d24368764f3d8064b8418bd..3b884a87c45c5f9a60f19ac6c0fb2a51531314d8 100644 (file)
@@ -29,6 +29,7 @@ struct vir_region {
 /* Mapping flags: */
 #define VR_WRITABLE    0x01    /* Process may write here. */
 #define VR_NOPF                0x02    /* May not generate page faults. */
+#define VR_PHYS64K     0x04    /* Physical memory must be 64k aligned. */
 
 /* Mapping type: */
 #define VR_ANON                0x10    /* Memory to be cleared and allocated */
index b305817b8f50f3806dfd247445a2299cd5c505c3..0f4040db7160e284826e6d58dde0f4ee3ee85106 100644 (file)
@@ -4,6 +4,7 @@
 /* Memory flags to pt_allocmap() and alloc_mem(). */
 #define PAF_CLEAR      0x01    /* Clear physical memory. */
 #define PAF_CONTIG     0x02    /* Physically contiguous. */
+#define PAF_ALIGN64K   0x04    /* Aligned to 64k boundary. */
 
 /* special value for v in pt_allocmap */
 #define AM_AUTO         ((u32_t) -1)