替换为fastipc
This commit is contained in:
@@ -44,7 +44,7 @@ void thread_knl_pf_set(thread_t *cur_th, void *pc)
|
||||
cur_th->sp.user_sp = 0;
|
||||
cur_th->sp.sp_type = 0xfffffff9;
|
||||
}
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack)
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram)
|
||||
{
|
||||
// assert((((umword_t)user_sp) & 0x7UL) == 0);
|
||||
umword_t usp = ((umword_t)(user_sp) & ~0x7UL);
|
||||
@@ -59,8 +59,12 @@ void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, um
|
||||
cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8);
|
||||
cur_th->sp.user_sp = cur_pf;
|
||||
cur_th->sp.sp_type = 0xfffffffd;
|
||||
|
||||
// printk("exc_regs:%x %x %x\n", cur_pf->pf_s.pc, cur_th->sp.user_sp, ram);
|
||||
}
|
||||
void thread_user_pf_restore(thread_t *cur_th, void *user_sp)
|
||||
{
|
||||
cur_th->sp.knl_sp = ((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE - 8);
|
||||
cur_th->sp.user_sp = user_sp;
|
||||
cur_th->sp.sp_type = 0xfffffffd;
|
||||
}
|
||||
void task_knl_init(task_t *knl_tk)
|
||||
{
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
#include "mm_space.h"
|
||||
#include "ram_limit.h"
|
||||
#include "types.h"
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size);
|
||||
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size, int mem_block);
|
||||
|
||||
@@ -7,11 +7,15 @@
|
||||
void mm_init(boot_info_t *info);
|
||||
void *mm_limit_alloc(ram_limit_t *limit, size_t size);
|
||||
void mm_limit_free(ram_limit_t *limit, void *mem);
|
||||
struct mem_heap *mm_get_free_raw(int mem_inx, struct mem_heap *next,
|
||||
umword_t hope_size, umword_t *ret_addr);
|
||||
struct mem_heap *mm_get_free(struct mem_heap *next,
|
||||
umword_t hope_size, umword_t *ret_addr);
|
||||
void mm_trace(void);
|
||||
void *mm_limit_alloc_align(ram_limit_t *limit, size_t size, size_t align);
|
||||
void *mm_limit_alloc_align_raw(int mem_inx, ram_limit_t *limit, size_t size, size_t align);
|
||||
void mm_limit_free_align(ram_limit_t *limit, void *mem, size_t size);
|
||||
void mm_limit_free_align_raw(int mem_inx, ram_limit_t *limit, void *mem, size_t size);
|
||||
void mm_info(size_t *total, size_t *free);
|
||||
|
||||
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
|
||||
|
||||
@@ -32,7 +32,8 @@ typedef struct task
|
||||
void *nofity_point; //!< commint point func.
|
||||
addr_t nofity_stack; //!< nofity_point_stack.
|
||||
mutex_t nofity_lock;
|
||||
addr_t nofity_msg_buf; //!<
|
||||
addr_t nofity_msg_buf; //!<
|
||||
umword_t *nofity_map_buf;
|
||||
umword_t *nofity_bitmap; //!<
|
||||
int nofity_bitmap_len; //!< max is WORD_BITS
|
||||
slist_head_t nofity_theads_head;
|
||||
@@ -46,6 +47,6 @@ static inline pid_t task_pid_get(task_t *task)
|
||||
}
|
||||
void task_init(task_t *task, ram_limit_t *ram, int is_knl);
|
||||
task_t *task_create(ram_limit_t *lim, int is_knl);
|
||||
int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size);
|
||||
int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size, int mem_block);
|
||||
void task_kill(task_t *tk);
|
||||
int task_set_pid(task_t *task, pid_t pid);
|
||||
|
||||
@@ -115,7 +115,7 @@ typedef struct thread_fast_ipc_item
|
||||
void *usp_backup; //!< 备份用户栈,用于快速通信
|
||||
void *msg_buf;
|
||||
} thread_fast_ipc_item_t;
|
||||
#define THREAD_FAST_IPC_ITEM_NUM 8
|
||||
#define THREAD_FAST_IPC_ITEM_NUM 4
|
||||
|
||||
#define THREAD_MAGIC 0xdeadead //!< 用于栈溢出检测
|
||||
typedef struct thread
|
||||
|
||||
@@ -10,13 +10,16 @@
|
||||
|
||||
#include "mm_wrap.h"
|
||||
#include "printk.h"
|
||||
#define assert(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
#define assert(cond) \
|
||||
do \
|
||||
{ \
|
||||
if (!(cond)) \
|
||||
{ \
|
||||
printk("\n%s:%d %s\n", __FILE__, __LINE__, #cond); \
|
||||
dumpstack(); \
|
||||
mm_trace(); \
|
||||
while (1) \
|
||||
; \
|
||||
} \
|
||||
dumpstack(); \
|
||||
mm_trace(); \
|
||||
sys_reset(); \
|
||||
while (1) \
|
||||
; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -191,7 +191,9 @@ int task_vma_alloc(task_vma_t *task_vma, vma_addr_t vaddr, size_t size,
|
||||
if (alloc_cn == 0)
|
||||
{
|
||||
task_vma->mem_pages_alloc_size[i] = size;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
task_vma->mem_pages_alloc_size[i] = 0;
|
||||
}
|
||||
alloc_cn++;
|
||||
@@ -592,14 +594,14 @@ static bool_t mpu_calc(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size)
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size, int mem_block)
|
||||
{
|
||||
#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);
|
||||
heap = mm_get_free_raw(mem_block, heap, ram_size, &pre_alloc_addr);
|
||||
if (!heap)
|
||||
{
|
||||
cpulock_set(status);
|
||||
@@ -619,7 +621,7 @@ again_alloc:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *ram = mm_limit_alloc_align(r_limit, ram_size, need_align);
|
||||
void *ram = mm_limit_alloc_align_raw(mem_block, r_limit, ram_size, need_align);
|
||||
if (!ram)
|
||||
{
|
||||
cpulock_set(status);
|
||||
@@ -632,7 +634,7 @@ again_alloc:
|
||||
{
|
||||
cpulock_set(status);
|
||||
printk("Again.\n");
|
||||
mm_limit_free_align(r_limit, ram, need_align);
|
||||
mm_limit_free_align_raw(mem_block, r_limit, ram, need_align);
|
||||
heap = heap->next;
|
||||
goto again_alloc;
|
||||
}
|
||||
@@ -641,7 +643,7 @@ again_alloc:
|
||||
#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);
|
||||
void *ram = mm_limit_alloc_align_raw(mem_block, r_limit, ram_size + MPU_ALIGN_SIZE, MPU_ALIGN_SIZE);
|
||||
if (!ram)
|
||||
{
|
||||
printk("The system is low on memory.\n");
|
||||
@@ -650,7 +652,7 @@ again_alloc:
|
||||
region = mm_space_alloc_pt_region(ms);
|
||||
if (!region)
|
||||
{
|
||||
mm_limit_free_align(r_limit, ram, ram_size);
|
||||
mm_limit_free_align_raw(mem_block, r_limit, ram, ram_size);
|
||||
return NULL;
|
||||
}
|
||||
region->block_start_addr = (umword_t)ram;
|
||||
@@ -662,9 +664,9 @@ again_alloc:
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size)
|
||||
void *mpu_ram_alloc(mm_space_t *ms, ram_limit_t *r_limit, size_t ram_size, int mem_block)
|
||||
{
|
||||
void *ram = mm_limit_alloc(r_limit, ram_size);
|
||||
void *ram = mm_limit_alloc_raw(mem_block, r_limit, ram_size);
|
||||
|
||||
return ram;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,11 @@ void mm_limit_free(ram_limit_t *limit, void *mem)
|
||||
mem_free(&mem_manage[0], (char *)mem - sizeof(size_t));
|
||||
ram_limit_free(limit, size);
|
||||
}
|
||||
struct mem_heap *mm_get_free_raw(int mem_inx, struct mem_heap *next,
|
||||
umword_t hope_size, umword_t *ret_addr)
|
||||
{
|
||||
return mem_get_free(&mem_manage[mem_inx], next, hope_size, (uint32_t *)ret_addr);
|
||||
}
|
||||
struct mem_heap *mm_get_free(struct mem_heap *next,
|
||||
umword_t hope_size, umword_t *ret_addr)
|
||||
{
|
||||
@@ -112,13 +117,13 @@ void mm_info(size_t *total, size_t *free)
|
||||
{
|
||||
mem_info(&mem_manage[0], total, free);
|
||||
}
|
||||
void *mm_limit_alloc_align(ram_limit_t *limit, size_t size, size_t align)
|
||||
void *mm_limit_alloc_align_raw(int mem_inx, ram_limit_t *limit, size_t size, size_t align)
|
||||
{
|
||||
if (ram_limit_alloc(limit, size) == FALSE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void *new_mem = mem_alloc_align(&mem_manage[0], size, align);
|
||||
void *new_mem = mem_alloc_align(&mem_manage[mem_inx], size, align);
|
||||
|
||||
if (!new_mem)
|
||||
{
|
||||
@@ -128,15 +133,23 @@ void *mm_limit_alloc_align(ram_limit_t *limit, size_t size, size_t align)
|
||||
|
||||
return (char *)new_mem;
|
||||
}
|
||||
void mm_limit_free_align(ram_limit_t *limit, void *mem, size_t size)
|
||||
void *mm_limit_alloc_align(ram_limit_t *limit, size_t size, size_t align)
|
||||
{
|
||||
return mm_limit_alloc_align_raw(0, limit, size, align);
|
||||
}
|
||||
void mm_limit_free_align_raw(int mem_inx, ram_limit_t *limit, void *mem, size_t size)
|
||||
{
|
||||
if (!mem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mem_free_align(&mem_manage[0], (char *)mem);
|
||||
mem_free_align(&mem_manage[mem_inx], (char *)mem);
|
||||
ram_limit_free(limit, size);
|
||||
}
|
||||
void mm_limit_free_align(ram_limit_t *limit, void *mem, size_t size)
|
||||
{
|
||||
mm_limit_free_align_raw(0, limit, mem, size);
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_BUDDY_SLAB)
|
||||
#include <buddy.h>
|
||||
#include <slab.h>
|
||||
|
||||
@@ -75,6 +75,7 @@ void sema_up(sema_t *obj)
|
||||
// printk("up1 sema cnt:%d max:%d.\n", obj->cnt, obj->max_cnt);
|
||||
}
|
||||
spinlock_set(&obj->lock, status);
|
||||
preemption();
|
||||
}
|
||||
void sema_down(sema_t *obj)
|
||||
{
|
||||
@@ -91,6 +92,7 @@ again:
|
||||
slist_add_append(&obj->suspend_head, &wait_item.node);
|
||||
thread_suspend_sw(th, FALSE);
|
||||
spinlock_set(&obj->lock, status);
|
||||
preemption();
|
||||
goto again;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -73,16 +73,17 @@ INIT_KOBJ_MEM(task_mem_init);
|
||||
* @param tk
|
||||
* @param lim
|
||||
* @param size
|
||||
* @param mem_block 使用的内存块
|
||||
* @return int
|
||||
*/
|
||||
int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size)
|
||||
int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size, int mem_block)
|
||||
{
|
||||
if (tk->mm_space.mm_block)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
// 申请init的ram内存
|
||||
void *ram = mpu_ram_alloc(&tk->mm_space, lim, size + THREAD_MSG_BUG_LEN);
|
||||
void *ram = mpu_ram_alloc(&tk->mm_space, lim, size + THREAD_MSG_BUG_LEN, mem_block);
|
||||
if (!ram)
|
||||
{
|
||||
printk("Failed to request process memory.\n");
|
||||
@@ -306,7 +307,7 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
|
||||
tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
||||
break;
|
||||
}
|
||||
int ret = task_alloc_base_ram(tag_task, tag_task->lim, f->regs[1]);
|
||||
int ret = task_alloc_base_ram(tag_task, tag_task->lim, f->regs[1], f->regs[2]);
|
||||
tag = msg_tag_init4(0, 0, 0, ret);
|
||||
f->regs[1] = (umword_t)(tag_task->mm_space.mm_block);
|
||||
spinlock_set(&tag_task->kobj.lock, status);
|
||||
@@ -411,12 +412,14 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
|
||||
tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
||||
break;
|
||||
}
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[3]), ROUND_UP(f->regs[4], 8), FALSE))
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[3]),
|
||||
ROUND_UP(f->regs[4], 8), FALSE))
|
||||
{
|
||||
tag = msg_tag_init4(0, 0, 0, -EPERM);
|
||||
break;
|
||||
}
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[5]), THREAD_MSG_BUG_LEN, FALSE))
|
||||
if (!is_rw_access(tag_task, (void *)(f->regs[5]),
|
||||
THREAD_MSG_BUG_LEN + CONFIG_THREAD_MAP_BUF_LEN * WORD_BYTES, FALSE))
|
||||
{
|
||||
tag = msg_tag_init4(0, 0, 0, -EPERM);
|
||||
break;
|
||||
@@ -428,6 +431,7 @@ static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t i
|
||||
tag_task->nofity_bitmap = (void *)(f->regs[3]);
|
||||
tag_task->nofity_bitmap_len = (f->regs[4]);
|
||||
tag_task->nofity_msg_buf = (addr_t)f->regs[5];
|
||||
tag_task->nofity_map_buf = (umword_t *)((addr_t)f->regs[5] + THREAD_MSG_BUG_LEN);
|
||||
tag = msg_tag_init4(0, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -718,6 +718,7 @@ void thread_timeout_del_recv_remote(thread_t *th, bool_t is_sche)
|
||||
static int ipc_dat_copy_raw(obj_space_t *dst_obj, obj_space_t *src_obj, ram_limit_t *lim,
|
||||
ipc_msg_t *dst_ipc, ipc_msg_t *src_ipc, msg_tag_t tag, int is_reply)
|
||||
{
|
||||
int i = 0;
|
||||
if (tag.map_buf_len > 0)
|
||||
{
|
||||
kobj_del_list_t del;
|
||||
@@ -725,13 +726,14 @@ static int ipc_dat_copy_raw(obj_space_t *dst_obj, obj_space_t *src_obj, ram_limi
|
||||
|
||||
kobj_del_list_init(&del);
|
||||
|
||||
for (int i = 0; i < map_len; i++)
|
||||
for (i = 0; i < map_len; i++)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
vpage_t dst_page = vpage_create_raw(dst_ipc->map_buf[i]);
|
||||
vpage_t src_page = vpage_create_raw(src_ipc->map_buf[i]);
|
||||
|
||||
// printk("map-> src:%d dst:%d\n", src_page.addr, dst_page.addr);
|
||||
if ((src_page.flags & VPAGE_FLAGS_MAP) || is_reply)
|
||||
{
|
||||
ret = obj_map_src_dst(dst_obj, src_obj,
|
||||
@@ -749,6 +751,7 @@ static int ipc_dat_copy_raw(obj_space_t *dst_obj, obj_space_t *src_obj, ram_limi
|
||||
}
|
||||
memcpy(dst_ipc->msg_buf, src_ipc->msg_buf,
|
||||
MIN(tag.msg_buf_len * WORD_BYTES, IPC_MSG_SIZE));
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
* @brief ipc传输时的数据拷贝
|
||||
@@ -1249,15 +1252,27 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
mutex_unlock(&old_task->nofity_lock);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
umword_t cpu_status = cpulock_lock();
|
||||
|
||||
task_t *cur_task = thread_get_current_task();
|
||||
ipc_msg_t *dst_ipc = (void *)cur_th->msg.msg;
|
||||
ipc_msg_t *src_ipc = (void *)old_task->nofity_msg_buf;
|
||||
ret = ipc_dat_copy_raw(&cur_task->obj_space, &old_task->obj_space, cur_task->lim,
|
||||
dst_ipc, src_ipc, in_tag, FALSE);
|
||||
if (ret < 0)
|
||||
dst_ipc, src_ipc, in_tag, TRUE);
|
||||
// if (ret > 0)
|
||||
// {
|
||||
// }
|
||||
for (int i = 0; i < CONFIG_THREAD_MAP_BUF_LEN; i++)
|
||||
{
|
||||
mutex_unlock(&old_task->nofity_lock);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
if (i < ret)
|
||||
{
|
||||
src_ipc->map_buf[i] = old_task->nofity_map_buf[i];
|
||||
old_task->nofity_map_buf[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_ipc->map_buf[i] = old_task->nofity_map_buf[i];
|
||||
}
|
||||
}
|
||||
mutex_unlock(&old_task->nofity_lock);
|
||||
pf_t *cur_pf = ((pf_t *)((char *)cur_th + CONFIG_THREAD_BLOCK_SIZE + 8)) - 1;
|
||||
@@ -1266,7 +1281,12 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
extern void mpu_switch_to_task(struct task * tk);
|
||||
mpu_switch_to_task(cur_task);
|
||||
ref_counter_dec_and_release(&old_task->ref_cn, &old_task->kobj);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
if (ret < 0)
|
||||
{
|
||||
in_tag = msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
cpulock_set(cpu_status);
|
||||
return in_tag;
|
||||
}
|
||||
break;
|
||||
case IPC_FAST_CALL:
|
||||
@@ -1280,6 +1300,7 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
|
||||
if (to_task->nofity_point == NULL)
|
||||
{
|
||||
printk("task:0x%x, notify point is not set.\n", to_task);
|
||||
return msg_tag_init4(0, 0, 0, -EIO);
|
||||
}
|
||||
_to_unlock:
|
||||
@@ -1297,6 +1318,7 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
preemption();
|
||||
goto _to_unlock;
|
||||
}
|
||||
umword_t cpu_status = cpulock_lock();
|
||||
ref_counter_inc((&to_task->ref_cn));
|
||||
//!< 执行目标线程时用的是当前线程的资源,这里还需要备份当前线程的上下文。
|
||||
ret = thread_fast_ipc_save(cur_th, to_task, (void *)(to_task->nofity_stack - 4 * 8)); //!< 备份栈和usp
|
||||
@@ -1324,9 +1346,9 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
|
||||
//! 寄存器传参数
|
||||
f->regs[0] = in_tag.raw;
|
||||
f->regs[1] = f->regs[2];
|
||||
f->regs[2] = f->regs[3];
|
||||
f->regs[3] = f->regs[4];
|
||||
f->regs[1] = user_id;
|
||||
f->regs[2] = f->regs[2];
|
||||
f->regs[3] = f->regs[3];
|
||||
|
||||
extern void mpu_switch_to_task(struct task * tk);
|
||||
mpu_switch_to_task(to_task);
|
||||
@@ -1343,6 +1365,7 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id)
|
||||
ref_counter_dec_and_release(&to_task->ref_cn, &to_task->kobj);
|
||||
mutex_unlock(&to_task->nofity_lock);
|
||||
}
|
||||
cpulock_set(cpu_status);
|
||||
return msg_tag_init4(0, 0, 0, ret);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -169,7 +169,7 @@ static void knl_init_2(void)
|
||||
assert(app);
|
||||
printk("init task text is 0x%x.\n", app);
|
||||
// 申请init的ram内存
|
||||
assert(task_alloc_base_ram(init_task, &root_factory_get()->limit, app->i.ram_size + THREAD_MSG_BUG_LEN) >= 0);
|
||||
assert(task_alloc_base_ram(init_task, &root_factory_get()->limit, app->i.ram_size + THREAD_MSG_BUG_LEN, 0) >= 0);
|
||||
void *sp_addr = (char *)init_task->mm_space.mm_block + app->i.stack_offset - app->i.data_offset;
|
||||
void *sp_addr_top = (char *)sp_addr + app->i.stack_size;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user