vma interface fix.
This commit is contained in:
@@ -6,6 +6,11 @@
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <mpu.h>
|
||||
#include <mm.h>
|
||||
#include <mm_wrap.h>
|
||||
#include <task.h>
|
||||
#include <thread.h>
|
||||
#include <string.h>
|
||||
static region_info_t *vma_alloc_pt_region(task_vma_t *vma)
|
||||
{
|
||||
assert(vma != NULL);
|
||||
@@ -38,6 +43,7 @@ static region_info_t *vma_find_pt_region(task_vma_t *vma, addr_t addr, size_t si
|
||||
}
|
||||
static void vma_free_pt_region(task_vma_t *vma, region_info_t *ri)
|
||||
{
|
||||
memset(ri, 0, sizeof(*ri));
|
||||
ri->region_inx = -1;
|
||||
}
|
||||
|
||||
@@ -80,10 +86,6 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
mm_space);
|
||||
|
||||
assert(task_vma != NULL);
|
||||
if (!ret_vaddr)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
if (!is_power_of_2(size))
|
||||
{
|
||||
@@ -105,7 +107,16 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
}
|
||||
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
vma_addr = (addr_t)mm_limit_alloc_align(pt_task, size, size);
|
||||
if (paddr == 0)
|
||||
{
|
||||
// 未设置物理内存,则自动申请一个
|
||||
vma_addr = (addr_t)mm_limit_alloc_align(pt_task->lim, size, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 设置了物理内存,就用设置的物理内存
|
||||
vma_addr = paddr;
|
||||
}
|
||||
if (vma_addr == 0)
|
||||
{
|
||||
return -ENOMEM;
|
||||
@@ -152,14 +163,23 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
0 /*TODO:支持每一个region bit位*/);
|
||||
ri->start_addr = vma_addr;
|
||||
ri->size = size;
|
||||
mpu_switch_to_task(
|
||||
pt_task);
|
||||
if (pt_task == thread_get_current_task())
|
||||
{
|
||||
// 只有是当前线程的时候发生切换
|
||||
mpu_switch_to_task(pt_task);
|
||||
}
|
||||
if (ret_vaddr)
|
||||
{
|
||||
*ret_vaddr = vma_addr;
|
||||
}
|
||||
goto end;
|
||||
err_end:
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
mm_limit_free_align(pt_task, vma_addr, size);
|
||||
mm_limit_free_align(pt_task->lim, (void *)vma_addr, size);
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
mm_limit_free_align(pt_task, vma_addr, MPU_ALIGN_SIZE);
|
||||
mm_limit_free_align(pt_task->lim, (void *)vma_addr, MPU_ALIGN_SIZE);
|
||||
#endif
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
@@ -179,6 +199,37 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma,
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
static int task_vma_free_inner(task_vma_t *task_vma, vaddr_t vaddr, size_t size, bool_t is_free_mem)
|
||||
{
|
||||
region_info_t *ri = NULL;
|
||||
addr_t vma_addr;
|
||||
task_t *pt_task;
|
||||
|
||||
pt_task = container_of(
|
||||
container_of(task_vma, mm_space_t, mem_vma),
|
||||
task_t,
|
||||
mm_space);
|
||||
assert(task_vma);
|
||||
vma_addr = vaddr; // vma_addr_get_addr(vaddr);
|
||||
ri = vma_find_pt_region(task_vma, vma_addr, size);
|
||||
if (!ri)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
vma_free_pt_region(task_vma, ri);
|
||||
if (is_free_mem)
|
||||
{
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
mm_limit_free_align(pt_task->lim, (void *)vma_addr, size);
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
mm_limit_free_align(pt_task->lim, (void *)vma_addr, MPU_ALIGN_SIZE);
|
||||
#endif
|
||||
}
|
||||
if (pt_task==thread_get_current_task()){
|
||||
mpu_switch_to_task(pt_task);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @brief 释放申请的虚拟内存,并释放已经申请的物理内存
|
||||
* 1.从分配树中找到需要的节点
|
||||
@@ -191,34 +242,7 @@ int task_vma_grant(task_vma_t *src_task_vma, task_vma_t *dst_task_vma,
|
||||
*/
|
||||
int task_vma_free(task_vma_t *task_vma, vaddr_t vaddr, size_t size)
|
||||
{
|
||||
region_info_t *ri = NULL;
|
||||
addr_t vma_addr;
|
||||
task_t *pt_task;
|
||||
|
||||
pt_task = container_of(
|
||||
container_of(task_vma, mm_space_t, mem_vma),
|
||||
task_t,
|
||||
mm_space);
|
||||
assert(task_vma);
|
||||
vma_addr = vma_addr_get_addr(vaddr);
|
||||
ri = vma_find_pt_region(task_vma, vma_addr, size);
|
||||
if (!ri)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
vma_free_pt_region(task_vma, ri);
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
mm_limit_free_align(pt_task, vma_addr, size);
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
mm_limit_free_align(pt_task, vma_addr, MPU_ALIGN_SIZE);
|
||||
#endif
|
||||
mpu_switch_to_task(
|
||||
container_of(
|
||||
container_of(task_vma, mm_space_t, mem_vma),
|
||||
task_t,
|
||||
mm_space));
|
||||
|
||||
return 0;
|
||||
return task_vma_free_inner(task_vma, vaddr, size, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +256,7 @@ int task_vma_free(task_vma_t *task_vma, vaddr_t vaddr, size_t size)
|
||||
*/
|
||||
int task_vma_free_pmem(task_vma_t *task_vma, vaddr_t addr, size_t size, bool_t is_free_mem)
|
||||
{
|
||||
return -ENOSYS;
|
||||
return task_vma_free_inner(task_vma, addr, size, is_free_mem);
|
||||
}
|
||||
/**
|
||||
* @brief 缺页的处理流程
|
||||
@@ -268,11 +292,213 @@ int task_vma_clean(task_vma_t *task_vma)
|
||||
{
|
||||
task_vma->pt_regions[i].region_inx = -1;
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
mm_limit_free_align(pt_task, task_vma->pt_regions[i].start_addr, task_vma->pt_regions[i].size);
|
||||
mm_limit_free_align(pt_task->lim, (void *)(task_vma->pt_regions[i].start_addr),
|
||||
task_vma->pt_regions[i].size);
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
mm_limit_free_align(pt_task, task_vma->pt_regions[i].start_addr, MPU_ALIGN_SIZE);
|
||||
mm_limit_free_align(pt_task->lim, (void *)(task_vma->pt_regions[i].start_addr),
|
||||
MPU_ALIGN_SIZE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
#include "mpu.h"
|
||||
static bool_t mpu_calc(
|
||||
mm_space_t *ms,
|
||||
umword_t mem_start_addr,
|
||||
int size,
|
||||
umword_t *ret_align_size,
|
||||
umword_t *alloc_addr)
|
||||
{
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
int ffs_t_;
|
||||
int ffs_t;
|
||||
region_info_t *region[2];
|
||||
|
||||
region[0] = vma_alloc_pt_region(&ms->mem_vma);
|
||||
region[1] = vma_alloc_pt_region(&ms->mem_vma);
|
||||
|
||||
if (!region[0] || !region[1])
|
||||
{
|
||||
if (!region[0])
|
||||
{
|
||||
vma_free_pt_region(&ms->mem_vma, region[0]);
|
||||
}
|
||||
if (!region[1])
|
||||
{
|
||||
vma_free_pt_region(&ms->mem_vma, region[1]);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ffs_t_ = ffs(size);
|
||||
if (!is_power_of_2(size))
|
||||
{
|
||||
ffs_t_++;
|
||||
}
|
||||
ffs_t = 1 << ffs_t_;
|
||||
|
||||
int sub_region_t = ffs_t >> 3;
|
||||
int align_sub_size = ALIGN(size, sub_region_t);
|
||||
|
||||
umword_t mem_align_sub_mem_addr = ALIGN((umword_t)mem_start_addr, sub_region_t);
|
||||
umword_t mem_align_up_mem_addr = ALIGN((umword_t)mem_start_addr, ffs_t);
|
||||
umword_t mem_align_down_mem_addr = ALIGN_DOWN((umword_t)mem_start_addr, ffs_t);
|
||||
|
||||
region[0]->start_addr = mem_align_sub_mem_addr;
|
||||
region[0]->size = mem_align_up_mem_addr - mem_align_sub_mem_addr;
|
||||
region[0]->block_size = ffs_t;
|
||||
region[0]->block_start_addr = mem_align_down_mem_addr;
|
||||
|
||||
if (alloc_addr)
|
||||
{
|
||||
*alloc_addr = region[0]->start_addr;
|
||||
}
|
||||
|
||||
region[0]->region = 0xff;
|
||||
for (umword_t i = mem_align_down_mem_addr; i < mem_align_up_mem_addr; i += sub_region_t)
|
||||
{
|
||||
if (i < mem_align_sub_mem_addr)
|
||||
{
|
||||
region[0]->region |= 1 << ((i - mem_align_down_mem_addr) / sub_region_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
region[0]->region &= ~(1 << ((i - mem_align_down_mem_addr) / sub_region_t));
|
||||
}
|
||||
}
|
||||
|
||||
region[1]->region = 0x00;
|
||||
for (umword_t i = mem_align_up_mem_addr; i < mem_align_up_mem_addr + ffs_t; i += sub_region_t)
|
||||
{
|
||||
if (i < mem_align_sub_mem_addr + align_sub_size)
|
||||
{
|
||||
region[1]->region &= ~(1 << ((i - mem_align_up_mem_addr) / sub_region_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
region[1]->region |= (1 << ((i - mem_align_up_mem_addr) / sub_region_t));
|
||||
}
|
||||
}
|
||||
region[1]->start_addr = mem_align_up_mem_addr;
|
||||
region[1]->size = (mem_align_sub_mem_addr + align_sub_size) - mem_align_up_mem_addr;
|
||||
region[1]->block_size = ffs_t;
|
||||
region[1]->block_start_addr = mem_align_up_mem_addr;
|
||||
|
||||
*ret_align_size = sub_region_t;
|
||||
|
||||
#if 0
|
||||
printk("st:0x%x re:0x%x sub:0x%x\n region:[", region[0]->block_start_addr, region[0]->region, sub_region_t);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (region[0]->region & (1 << i))
|
||||
{
|
||||
printk("x");
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("o");
|
||||
}
|
||||
}
|
||||
printk("]\n");
|
||||
printk("st:0x%x re:0x%x sub:0x%x\n region:[", region[1]->block_start_addr, region[1]->region, sub_region_t);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (region[1]->region & (1 << i))
|
||||
{
|
||||
printk("x");
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("o");
|
||||
}
|
||||
}
|
||||
printk("]\n");
|
||||
#endif
|
||||
mpu_calc_regs(region[0], region[0]->block_start_addr, 1 << ffs_t_, REGION_RWX, region[0]->region);
|
||||
mpu_calc_regs(region[1], region[1]->block_start_addr, 1 << ffs_t_, REGION_RWX, region[1]->region);
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size)
|
||||
{
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
umword_t pre_alloc_addr;
|
||||
struct mem_heap *heap = NULL;
|
||||
umword_t status = cpulock_lock();
|
||||
again_alloc:
|
||||
heap = mm_get_free(heap, ram_size, &pre_alloc_addr);
|
||||
if (!heap)
|
||||
{
|
||||
cpulock_set(status);
|
||||
printk("The system is low on memory.\n");
|
||||
// mm_trace();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
umword_t need_align;
|
||||
umword_t alloc_addr;
|
||||
|
||||
if (mpu_calc(ms, pre_alloc_addr, ram_size,
|
||||
&need_align, &alloc_addr) == FALSE)
|
||||
{
|
||||
cpulock_set(status);
|
||||
printk("The MPU area is exhausted.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *ram = mm_limit_alloc_align(r_limit, ram_size, need_align);
|
||||
if (!ram)
|
||||
{
|
||||
cpulock_set(status);
|
||||
printk("The system is low on memory.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//!< 申请的地址与预分配的地址不同
|
||||
if (ram != (void *)alloc_addr)
|
||||
{
|
||||
cpulock_set(status);
|
||||
printk("Again.\n");
|
||||
mm_limit_free_align(r_limit, ram, need_align);
|
||||
heap = heap->next;
|
||||
goto again_alloc;
|
||||
}
|
||||
cpulock_set(status);
|
||||
return ram;
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
region_info_t *region;
|
||||
|
||||
void *ram = mm_limit_alloc_align(r_limit, ram_size + MPU_ALIGN_SIZE, MPU_ALIGN_SIZE);
|
||||
if (!ram)
|
||||
{
|
||||
printk("The system is low on memory.\n");
|
||||
return NULL;
|
||||
}
|
||||
region = mm_space_alloc_pt_region(ms);
|
||||
if (!region)
|
||||
{
|
||||
mm_limit_free_align(r_limit, ram, ram_size);
|
||||
return NULL;
|
||||
}
|
||||
region->block_start_addr = (umword_t)ram;
|
||||
region->start_addr = (umword_t)ram;
|
||||
region->block_size = 0;
|
||||
region->size = ram_size + MPU_ALIGN_SIZE;
|
||||
mpu_calc_regs(region, region->block_start_addr, ram_size & (~(MPU_ALIGN_SIZE - 1)), REGION_RWX, region->region);
|
||||
return ram;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size)
|
||||
{
|
||||
void *ram = mm_limit_alloc(r_limit, ram_size);
|
||||
|
||||
return ram;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user