diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c index a6e92bb7a89..09cf000df8d 100644 --- a/fs/mmap/fs_mmap.c +++ b/fs/mmap/fs_mmap.c @@ -47,8 +47,8 @@ ****************************************************************************/ static int file_mmap_(FAR struct file *filep, FAR void *start, - size_t length, int prot, int flags, - off_t offset, bool kernel, FAR void **mapped) + size_t length, int prot, int flags, off_t offset, + enum mm_map_type_e type, FAR void **mapped) { int ret = -ENOTTY; @@ -107,7 +107,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start, if ((flags & MAP_ANONYMOUS) != 0) { - ret = map_anonymous(&entry, kernel); + ret = map_anonymous(&entry, type); /* According to the mmap(2) specification, anonymous pages should be * initialized to zero unless the MAP_UNINITIALIZED is specified. @@ -161,7 +161,7 @@ static int file_mmap_(FAR struct file *filep, FAR void *start, * do much better in the KERNEL build using the MMU. */ - ret = rammap(filep, &entry, kernel); + ret = rammap(filep, &entry, type); } /* Return */ @@ -193,7 +193,7 @@ int file_mmap(FAR struct file *filep, FAR void *start, size_t length, int prot, int flags, off_t offset, FAR void **mapped) { return file_mmap_(filep, start, length, - prot, flags, offset, true, mapped); + prot, flags, offset, MAP_KERNEL, mapped); } /**************************************************************************** @@ -285,12 +285,8 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags, } ret = file_mmap_(filep, start, length, - prot, flags, offset, false, &mapped); - if (fd != -1) - { - fs_putfilep(filep); - } - + prot, flags, offset, MAP_USER, &mapped); + fs_putfilep(filep); if (ret < 0) { goto errout; diff --git a/fs/mmap/fs_munmap.c b/fs/mmap/fs_munmap.c index d9a9875e54f..4d8b68bcd3d 100644 --- a/fs/mmap/fs_munmap.c +++ b/fs/mmap/fs_munmap.c @@ -43,7 +43,8 @@ * Private Functions ****************************************************************************/ -static int file_munmap_(FAR void *start, size_t length, bool kernel) +static int file_munmap_(FAR void *start, size_t length, + enum mm_map_type_e type) { FAR struct tcb_s *tcb = this_task(); FAR struct task_group_s *group = tcb->group; @@ -100,7 +101,7 @@ unlock: int file_munmap(FAR void *start, size_t length) { - return file_munmap_(start, length, true); + return file_munmap_(start, length, MAP_KERNEL); } /**************************************************************************** @@ -157,7 +158,7 @@ int munmap(FAR void *start, size_t length) { int ret; - ret = file_munmap_(start, length, false); + ret = file_munmap_(start, length, MAP_USER); if (ret < 0) { set_errno(-ret); diff --git a/fs/mmap/fs_rammap.c b/fs/mmap/fs_rammap.c index 1286d90df8f..af7f41653e4 100644 --- a/fs/mmap/fs_rammap.c +++ b/fs/mmap/fs_rammap.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -55,7 +56,7 @@ static int unmap_rammap(FAR struct task_group_s *group, { FAR void *newaddr = NULL; off_t offset; - bool kernel = entry->priv.i; + enum mm_map_type_e type = entry->priv.i; int ret = OK; /* Get the offset from the beginning of the region and the actual number @@ -84,11 +85,11 @@ static int unmap_rammap(FAR struct task_group_s *group, { /* Free the region */ - if (kernel) + if (type == MAP_KERNEL) { kmm_free(entry->vaddr); } - else + else if (type == MAP_USER) { kumm_free(entry->vaddr); } @@ -104,11 +105,11 @@ static int unmap_rammap(FAR struct task_group_s *group, else { - if (kernel) + if (type == MAP_KERNEL) { newaddr = kmm_realloc(entry->vaddr, length); } - else + else if (type == MAP_USER) { newaddr = kumm_realloc(entry->vaddr, length); } @@ -135,7 +136,7 @@ static int unmap_rammap(FAR struct task_group_s *group, * filep file descriptor of the backing file -- required. * entry mmap entry information. * field offset and length must be initialized correctly. - * kernel kmm_zalloc or kumm_zalloc + * type kmm_zalloc or kumm_zalloc or xip_base * * Returned Value: * On success, rammap returns 0 and entry->vaddr points to memory mapped. @@ -151,7 +152,7 @@ static int unmap_rammap(FAR struct task_group_s *group, ****************************************************************************/ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry, - bool kernel) + enum mm_map_type_e type) { FAR uint8_t *rdbuffer; ssize_t nread; @@ -159,6 +160,13 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry, int ret; size_t length = entry->length; + ret = file_ioctl(filep, BIOC_XIPBASE, (unsigned long)&entry->vaddr); + if (ret == OK) + { + type = MAP_XIP; + goto out; + } + /* There is a major design flaw that I have not yet thought of fix for: * The goal is to have a single region of memory that represents a single * file and can be shared by many threads. That is, given a filename a @@ -174,7 +182,7 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry, /* Allocate a region of memory of the specified size */ - rdbuffer = kernel ? kmm_malloc(length) : kumm_malloc(length); + rdbuffer = type == MAP_KERNEL ? kmm_malloc(length) : kumm_malloc(length); if (!rdbuffer) { ferr("ERROR: Region allocation failed, length: %zu\n", length); @@ -239,7 +247,8 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry, /* Add the buffer to the list of regions */ - entry->priv.i = kernel; +out: + entry->priv.i = type; entry->munmap = unmap_rammap; ret = mm_map_add(get_current_mm(), entry); @@ -251,11 +260,11 @@ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry, return OK; errout_with_region: - if (kernel) + if (type == MAP_KERNEL) { kmm_free(entry->vaddr); } - else + else if (type == MAP_USER) { kumm_free(entry->vaddr); } diff --git a/fs/mmap/fs_rammap.h b/fs/mmap/fs_rammap.h index 32fc0c132b0..8b216c00895 100644 --- a/fs/mmap/fs_rammap.h +++ b/fs/mmap/fs_rammap.h @@ -47,6 +47,15 @@ #include #include +/* A memory mapping type definition */ + +enum mm_map_type_e +{ + MAP_USER = 0, + MAP_KERNEL, + MAP_XIP, +}; + #ifdef CONFIG_FS_RAMMAP /**************************************************************************** @@ -72,8 +81,7 @@ * length The length of the mapping. For exception #1 above, this length * ignored: The entire underlying media is always accessible. * offset The offset into the file to map - * kernel kmm_zalloc or kumm_zalloc - * mapped The pointer to the mapped area + * type kmm_zalloc or kumm_zalloc or xip_base * * Returned Value: * On success rammmap returns 0. Otherwise errno is returned appropriately. @@ -88,9 +96,9 @@ ****************************************************************************/ int rammap(FAR struct file *filep, FAR struct mm_map_entry_s *entry, - bool kernel); + enum mm_map_type_e type); #else -# define rammap(file, entry, kernel) (-ENOSYS) +# define rammap(file, entry, type) (-ENOSYS) #endif /* CONFIG_FS_RAMMAP */ #endif /* __FS_MMAP_FS_RAMMAP_H */