替换为fastipc

This commit is contained in:
zhangzheng
2024-12-29 21:50:20 +08:00
parent 49060a965b
commit 01cd44d7fd
570 changed files with 735 additions and 598 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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