mmap: add xip mmap type support
Signed-off-by: wanggang26 <wanggang26@xiaomi.com>
This commit is contained in:
parent
545774eb88
commit
484600bd75
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
@ -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);
|
||||
}
|
||||
|
@ -47,6 +47,15 @@
|
||||
#include <sys/types.h>
|
||||
#include <nuttx/mm/map.h>
|
||||
|
||||
/* 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user