_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,
#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)
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
* 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. */
* 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) {
/* 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;
}
/*===========================================================================*
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) {
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 {
/* 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;
int r;
phys_bytes newmem, newmem_cl, clicks;
struct phys_block *newpb;
+ u32_t af = 0;
SANITYCHECK(SCL_FUNCTIONS);
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;
}
/* 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 */
/* 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)