let drivers allocate memory at 64k physical boundary.

This commit is contained in:
Ben Gras 2009-02-12 12:26:08 +00:00
parent 6ac0338584
commit 59e972f074
8 changed files with 55 additions and 19 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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. */

View file

@ -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;
} }
/*===========================================================================* /*===========================================================================*

View file

@ -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 {

View file

@ -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;
} }

View file

@ -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 */

View file

@ -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)