let drivers allocate memory at 64k physical boundary.
This commit is contained in:
parent
6ac0338584
commit
59e972f074
8 changed files with 55 additions and 19 deletions
|
@ -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));
|
_PROTOTYPE(void *alloc_contig, (size_t len, int flags, phys_bytes *phys));
|
||||||
#define AC_ALIGN4K 0x01
|
#define AC_ALIGN4K 0x01
|
||||||
#define AC_LOWER16M 0x02
|
#define AC_LOWER16M 0x02
|
||||||
|
#define AC_ALIGN64K 0x04
|
||||||
|
|
||||||
/* Clock functionality: get system times or (un)schedule an alarm call. */
|
/* Clock functionality: get system times or (un)schedule an alarm call. */
|
||||||
_PROTOTYPE( int sys_times, (endpoint_t proc_nr, clock_t *user_time,
|
_PROTOTYPE( int sys_times, (endpoint_t proc_nr, clock_t *user_time,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define MAP_PREALLOC 0x0008 /* not on-demand */
|
#define MAP_PREALLOC 0x0008 /* not on-demand */
|
||||||
#define MAP_CONTIG 0x0010 /* contiguous in physical memory */
|
#define MAP_CONTIG 0x0010 /* contiguous in physical memory */
|
||||||
#define MAP_LOWER16M 0x0020 /* physically below 16MB */
|
#define MAP_LOWER16M 0x0020 /* physically below 16MB */
|
||||||
|
#define MAP_ALIGN64K 0x0040 /* physically aligned at 64kB */
|
||||||
|
|
||||||
/* mmap() error return */
|
/* mmap() error return */
|
||||||
#define MAP_FAILED ((void *)-1)
|
#define MAP_FAILED ((void *)-1)
|
||||||
|
|
|
@ -29,6 +29,8 @@ void *alloc_contig(size_t len, int flags, phys_bytes *phys)
|
||||||
|
|
||||||
if(flags & AC_LOWER16M)
|
if(flags & AC_LOWER16M)
|
||||||
mmapflags |= MAP_LOWER16M;
|
mmapflags |= MAP_LOWER16M;
|
||||||
|
if(flags & AC_ALIGN64K)
|
||||||
|
mmapflags |= MAP_ALIGN64K;
|
||||||
|
|
||||||
/* First try to get memory with mmap. This is gauranteed
|
/* First try to get memory with mmap. This is gauranteed
|
||||||
* to be page-aligned, and we can tell VM it has to be
|
* 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.
|
* so we can page align it ourselves.
|
||||||
*/
|
*/
|
||||||
if(buf == (vir_bytes) MAP_FAILED) {
|
if(buf == (vir_bytes) MAP_FAILED) {
|
||||||
|
u32_t align = 0;
|
||||||
if(errno != (_SIGN ENXIO)) {
|
if(errno != (_SIGN ENXIO)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#define ALIGN 4096
|
if(flags & AC_ALIGN4K)
|
||||||
if(flags & AC_ALIGN4K) {
|
align = 4*1024;
|
||||||
if(len + ALIGN < len)
|
if(flags & AC_ALIGN64K)
|
||||||
return NULL;
|
align = 64*1024;
|
||||||
len += ALIGN;
|
if(len + align < len)
|
||||||
}
|
return NULL;
|
||||||
|
len += align;
|
||||||
if(!(buf = (vir_bytes) malloc(len))) {
|
if(!(buf = (vir_bytes) malloc(len))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(flags & AC_ALIGN4K)
|
if(align)
|
||||||
buf += ALIGN - (buf % ALIGN);
|
buf += align - (buf % align);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get physical address. */
|
/* Get physical address. */
|
||||||
|
|
|
@ -206,17 +206,19 @@ PUBLIC phys_clicks alloc_mem_f(phys_clicks clicks, u32_t memflags)
|
||||||
* needed for FORK or EXEC.
|
* needed for FORK or EXEC.
|
||||||
*/
|
*/
|
||||||
register struct hole *hp, *prev_ptr;
|
register struct hole *hp, *prev_ptr;
|
||||||
phys_clicks old_base;
|
phys_clicks old_base, mem = NO_MEM, align_clicks = 0;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
|
if(memflags & PAF_ALIGN64K) {
|
||||||
|
align_clicks = (64 * 1024) / CLICK_SIZE;
|
||||||
|
clicks += align_clicks;
|
||||||
|
}
|
||||||
|
|
||||||
if(vm_paged) {
|
if(vm_paged) {
|
||||||
vm_assert(CLICK_SIZE == VM_PAGE_SIZE);
|
vm_assert(CLICK_SIZE == VM_PAGE_SIZE);
|
||||||
return alloc_pages(clicks, memflags);
|
mem = alloc_pages(clicks, memflags);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
CHECKHOLES;
|
CHECKHOLES;
|
||||||
|
|
||||||
{
|
|
||||||
prev_ptr = NIL_HOLE;
|
prev_ptr = NIL_HOLE;
|
||||||
hp = hole_head;
|
hp = hole_head;
|
||||||
while (hp != NIL_HOLE) {
|
while (hp != NIL_HOLE) {
|
||||||
|
@ -239,15 +241,33 @@ CHECKHOLES;
|
||||||
|
|
||||||
/* Return the start address of the acquired block. */
|
/* Return the start address of the acquired block. */
|
||||||
CHECKHOLES;
|
CHECKHOLES;
|
||||||
return(old_base);
|
mem = old_base;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_ptr = hp;
|
prev_ptr = hp;
|
||||||
hp = hp->h_next;
|
hp = hp->h_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mem == NO_MEM)
|
||||||
|
return mem;
|
||||||
|
|
||||||
CHECKHOLES;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
|
|
@ -57,6 +57,7 @@ PUBLIC int do_mmap(message *m)
|
||||||
if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
|
if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
|
||||||
int s;
|
int s;
|
||||||
vir_bytes v;
|
vir_bytes v;
|
||||||
|
u32_t vrflags = VR_ANON | VR_WRITABLE;
|
||||||
size_t len = (vir_bytes) m->VMM_LEN;
|
size_t len = (vir_bytes) m->VMM_LEN;
|
||||||
|
|
||||||
if(m->VMM_FD != -1) {
|
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_CONTIG) mfflags |= MF_CONTIG;
|
||||||
if(m->VMM_FLAGS & MAP_PREALLOC) mfflags |= MF_PREALLOC;
|
if(m->VMM_FLAGS & MAP_PREALLOC) mfflags |= MF_PREALLOC;
|
||||||
|
if(m->VMM_FLAGS & MAP_ALIGN64K) vrflags |= VR_PHYS64K;
|
||||||
|
|
||||||
if(len % VM_PAGE_SIZE)
|
if(len % VM_PAGE_SIZE)
|
||||||
len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
|
len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
|
||||||
|
|
||||||
if(!(vr = map_page_region(vmp,
|
if(!(vr = map_page_region(vmp,
|
||||||
arch_vir2map(vmp, vmp->vm_stacktop), VM_DATATOP, len, MAP_NONE,
|
arch_vir2map(vmp, vmp->vm_stacktop), VM_DATATOP, len, MAP_NONE,
|
||||||
VR_ANON | VR_WRITABLE, mfflags))) {
|
vrflags, mfflags))) {
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -432,7 +432,10 @@ struct phys_region *physhint;
|
||||||
/* Memory for new physical block. */
|
/* Memory for new physical block. */
|
||||||
clicks = CLICKSPERPAGE * length / VM_PAGE_SIZE;
|
clicks = CLICKSPERPAGE * length / VM_PAGE_SIZE;
|
||||||
if(what_mem == MAP_NONE) {
|
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(newpb);
|
||||||
SLABFREE(newphysr);
|
SLABFREE(newphysr);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@ -499,6 +502,7 @@ struct phys_region *ph;
|
||||||
int r;
|
int r;
|
||||||
phys_bytes newmem, newmem_cl, clicks;
|
phys_bytes newmem, newmem_cl, clicks;
|
||||||
struct phys_block *newpb;
|
struct phys_block *newpb;
|
||||||
|
u32_t af = 0;
|
||||||
|
|
||||||
SANITYCHECK(SCL_FUNCTIONS);
|
SANITYCHECK(SCL_FUNCTIONS);
|
||||||
|
|
||||||
|
@ -514,7 +518,9 @@ struct phys_region *ph;
|
||||||
|
|
||||||
clicks = CLICKSPERPAGE * ph->ph->length / VM_PAGE_SIZE;
|
clicks = CLICKSPERPAGE * ph->ph->length / VM_PAGE_SIZE;
|
||||||
vm_assert(CLICK2ABS(clicks) == ph->ph->length);
|
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);
|
SLABFREE(newpb);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct vir_region {
|
||||||
/* Mapping flags: */
|
/* Mapping flags: */
|
||||||
#define VR_WRITABLE 0x01 /* Process may write here. */
|
#define VR_WRITABLE 0x01 /* Process may write here. */
|
||||||
#define VR_NOPF 0x02 /* May not generate page faults. */
|
#define VR_NOPF 0x02 /* May not generate page faults. */
|
||||||
|
#define VR_PHYS64K 0x04 /* Physical memory must be 64k aligned. */
|
||||||
|
|
||||||
/* Mapping type: */
|
/* Mapping type: */
|
||||||
#define VR_ANON 0x10 /* Memory to be cleared and allocated */
|
#define VR_ANON 0x10 /* Memory to be cleared and allocated */
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
/* Memory flags to pt_allocmap() and alloc_mem(). */
|
/* Memory flags to pt_allocmap() and alloc_mem(). */
|
||||||
#define PAF_CLEAR 0x01 /* Clear physical memory. */
|
#define PAF_CLEAR 0x01 /* Clear physical memory. */
|
||||||
#define PAF_CONTIG 0x02 /* Physically contiguous. */
|
#define PAF_CONTIG 0x02 /* Physically contiguous. */
|
||||||
|
#define PAF_ALIGN64K 0x04 /* Aligned to 64k boundary. */
|
||||||
|
|
||||||
/* special value for v in pt_allocmap */
|
/* special value for v in pt_allocmap */
|
||||||
#define AM_AUTO ((u32_t) -1)
|
#define AM_AUTO ((u32_t) -1)
|
||||||
|
|
Loading…
Reference in a new issue