2023-09-29 01:03:19 +08:00
|
|
|
/**
|
|
|
|
|
* @file task.c
|
|
|
|
|
* @author zhangzheng (1358745329@qq.com)
|
|
|
|
|
* @brief
|
|
|
|
|
* @version 0.1
|
|
|
|
|
* @date 2023-09-29
|
|
|
|
|
*
|
|
|
|
|
* @copyright Copyright (c) 2023
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2023-08-20 20:52:23 +08:00
|
|
|
#include "task.h"
|
|
|
|
|
#include "kobject.h"
|
|
|
|
|
#include "factory.h"
|
|
|
|
|
#include "init.h"
|
2023-08-28 22:11:49 +08:00
|
|
|
#include "map.h"
|
|
|
|
|
#include "thread.h"
|
2023-08-28 23:54:33 +08:00
|
|
|
#include "misc.h"
|
2023-09-02 00:18:54 +08:00
|
|
|
#include "spinlock.h"
|
2023-08-20 20:52:23 +08:00
|
|
|
enum task_op_code
|
|
|
|
|
{
|
|
|
|
|
TASK_OBJ_MAP,
|
2023-08-27 21:25:09 +08:00
|
|
|
TASK_OBJ_UNMAP,
|
2023-08-28 23:54:33 +08:00
|
|
|
TASK_ALLOC_RAM_BASE,
|
2023-09-07 23:47:34 +08:00
|
|
|
TASK_OBJ_VALID,
|
2023-08-20 20:52:23 +08:00
|
|
|
};
|
2023-08-28 22:11:49 +08:00
|
|
|
static bool_t task_put(kobject_t *kobj);
|
|
|
|
|
static void task_release_stage1(kobject_t *kobj);
|
|
|
|
|
static void task_release_stage2(kobject_t *kobj);
|
2023-08-28 23:54:33 +08:00
|
|
|
|
|
|
|
|
int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size)
|
|
|
|
|
{
|
|
|
|
|
if (tk->mm_space.mm_block)
|
|
|
|
|
{
|
|
|
|
|
return -EACCES;
|
|
|
|
|
}
|
|
|
|
|
// 申请init的ram内存
|
2023-09-03 15:55:06 +08:00
|
|
|
void *ram = mpu_ram_alloc(&tk->mm_space, lim, size + THREAD_MSG_BUG_LEN);
|
2023-08-28 23:54:33 +08:00
|
|
|
if (!ram)
|
|
|
|
|
{
|
|
|
|
|
printk("申请进程内存失败.\n");
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
2023-09-03 15:55:06 +08:00
|
|
|
mm_space_set_ram_block(&tk->mm_space, ram, size + THREAD_MSG_BUG_LEN);
|
|
|
|
|
printk("task alloc size is %d, base is 0x%x\n", size + THREAD_MSG_BUG_LEN, ram);
|
2023-08-28 23:54:33 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-03 15:55:06 +08:00
|
|
|
task_t *thread_get_bind_task(thread_t *th)
|
|
|
|
|
{
|
|
|
|
|
return container_of(th->task, task_t, kobj);
|
|
|
|
|
}
|
|
|
|
|
static void task_syscall_func(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f)
|
2023-08-20 20:52:23 +08:00
|
|
|
{
|
2023-08-28 22:11:49 +08:00
|
|
|
task_t *cur_task = thread_get_current_task();
|
|
|
|
|
task_t *tag_task = container_of(kobj, task_t, kobj);
|
2023-09-07 23:47:34 +08:00
|
|
|
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
2023-08-20 20:52:23 +08:00
|
|
|
|
2023-09-03 15:55:06 +08:00
|
|
|
if (sys_p.prot != TASK_PROT)
|
2023-08-20 20:52:23 +08:00
|
|
|
{
|
2023-09-07 23:47:34 +08:00
|
|
|
f->r[0] = msg_tag_init4(0, 0, 0, -EINVAL).raw;
|
2023-09-03 15:55:06 +08:00
|
|
|
return;
|
2023-08-20 20:52:23 +08:00
|
|
|
}
|
|
|
|
|
|
2023-09-03 15:55:06 +08:00
|
|
|
switch (sys_p.op)
|
2023-08-20 20:52:23 +08:00
|
|
|
{
|
2023-09-07 23:47:34 +08:00
|
|
|
case TASK_OBJ_VALID:
|
|
|
|
|
{
|
|
|
|
|
kobject_t *source_kobj = obj_space_lookup_kobj(&cur_task->obj_space, f->r[1]);
|
|
|
|
|
|
|
|
|
|
if (!source_kobj)
|
|
|
|
|
{
|
|
|
|
|
tag = msg_tag_init4(0, 0, 0, -ENOENT);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tag = msg_tag_init4(0, 0, 0, 1);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-08-20 20:52:23 +08:00
|
|
|
case TASK_OBJ_MAP:
|
2023-08-28 23:54:33 +08:00
|
|
|
{
|
2023-09-21 21:44:17 +08:00
|
|
|
kobj_del_list_t del;
|
|
|
|
|
|
|
|
|
|
kobj_del_list_init(&del);
|
2023-09-09 14:39:48 +08:00
|
|
|
int ret = obj_map_src_dst(&tag_task->obj_space, &cur_task->obj_space,
|
|
|
|
|
f->r[2], f->r[1],
|
2023-09-21 21:44:17 +08:00
|
|
|
tag_task->lim, f->r[3], &del);
|
2023-08-28 23:54:33 +08:00
|
|
|
|
2023-09-21 21:44:17 +08:00
|
|
|
kobj_del_list_to_do(&del);
|
2023-09-07 23:47:34 +08:00
|
|
|
tag = msg_tag_init4(0, 0, 0, ret);
|
2023-08-28 23:54:33 +08:00
|
|
|
}
|
|
|
|
|
break;
|
2023-08-27 21:25:09 +08:00
|
|
|
case TASK_OBJ_UNMAP:
|
2023-08-28 22:11:49 +08:00
|
|
|
{
|
|
|
|
|
kobject_t *del_kobj;
|
|
|
|
|
kobj_del_list_t kobj_list;
|
|
|
|
|
|
2023-09-02 00:18:54 +08:00
|
|
|
mword_t status = spinlock_lock(&tag_task->kobj.lock);
|
|
|
|
|
if (status < 0)
|
|
|
|
|
{
|
2023-09-07 23:47:34 +08:00
|
|
|
tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
2023-09-02 00:18:54 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2023-08-28 22:11:49 +08:00
|
|
|
kobj_del_list_init(&kobj_list);
|
2023-09-09 14:39:48 +08:00
|
|
|
obj_unmap(&tag_task->obj_space, vpage_create_raw(f->r[1]), &kobj_list);
|
2023-08-28 22:11:49 +08:00
|
|
|
kobj_del_list_to_do(&kobj_list);
|
2023-09-02 00:18:54 +08:00
|
|
|
spinlock_set(&tag_task->kobj.lock, status);
|
2023-08-28 22:11:49 +08:00
|
|
|
}
|
|
|
|
|
break;
|
2023-08-28 23:54:33 +08:00
|
|
|
case TASK_ALLOC_RAM_BASE:
|
|
|
|
|
{
|
2023-09-02 00:18:54 +08:00
|
|
|
mword_t status = spinlock_lock(&tag_task->kobj.lock);
|
|
|
|
|
if (status < 0)
|
|
|
|
|
{
|
2023-09-07 23:47:34 +08:00
|
|
|
tag = msg_tag_init4(0, 0, 0, -EINVAL);
|
2023-09-02 00:18:54 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
int ret = task_alloc_base_ram(tag_task, tag_task->lim, f->r[1]);
|
2023-09-07 23:47:34 +08:00
|
|
|
tag = msg_tag_init4(0, 0, 0, ret);
|
2023-09-03 15:55:06 +08:00
|
|
|
f->r[1] = (umword_t)(tag_task->mm_space.mm_block);
|
2023-09-02 00:18:54 +08:00
|
|
|
spinlock_set(&tag_task->kobj.lock, status);
|
2023-08-28 23:54:33 +08:00
|
|
|
}
|
|
|
|
|
break;
|
2023-08-20 20:52:23 +08:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-03 15:55:06 +08:00
|
|
|
f->r[0] = tag.raw;
|
2023-08-20 20:52:23 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-27 21:25:09 +08:00
|
|
|
void task_init(task_t *task, ram_limit_t *ram, int is_knl)
|
2023-08-20 20:52:23 +08:00
|
|
|
{
|
|
|
|
|
assert(task);
|
|
|
|
|
assert(ram);
|
|
|
|
|
|
|
|
|
|
kobject_init(&task->kobj);
|
|
|
|
|
obj_space_init(&task->obj_space, ram);
|
2023-08-27 21:25:09 +08:00
|
|
|
mm_space_init(&task->mm_space, is_knl);
|
2023-08-28 22:11:49 +08:00
|
|
|
ref_counter_init(&task->ref_cn);
|
|
|
|
|
ref_counter_inc(&task->ref_cn);
|
2023-08-27 16:52:53 +08:00
|
|
|
task->lim = ram;
|
2023-08-28 22:11:49 +08:00
|
|
|
task->kobj.invoke_func = task_syscall_func;
|
|
|
|
|
task->kobj.put_func = task_put;
|
|
|
|
|
task->kobj.stage_1_func = task_release_stage1;
|
|
|
|
|
task->kobj.stage_2_func = task_release_stage2;
|
2023-08-28 23:54:33 +08:00
|
|
|
|
|
|
|
|
mm_space_add(&task->mm_space, KNL_TEXT, 64 * 1024 * 1024, REGION_RO); // TODO:
|
2023-08-28 22:11:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool_t task_put(kobject_t *kobj)
|
|
|
|
|
{
|
|
|
|
|
task_t *tk = container_of(kobj, task_t, kobj);
|
|
|
|
|
return ref_counter_dec(&tk->ref_cn) == 1;
|
|
|
|
|
}
|
|
|
|
|
static void task_release_stage1(kobject_t *kobj)
|
|
|
|
|
{
|
|
|
|
|
task_t *tk = container_of(kobj, task_t, kobj);
|
|
|
|
|
kobj_del_list_t kobj_list;
|
2023-09-02 00:18:54 +08:00
|
|
|
kobject_invalidate(kobj);
|
2023-08-28 22:11:49 +08:00
|
|
|
kobj_del_list_init(&kobj_list);
|
|
|
|
|
obj_unmap_all(&tk->obj_space, &kobj_list);
|
|
|
|
|
kobj_del_list_to_do(&kobj_list);
|
|
|
|
|
}
|
|
|
|
|
static void task_release_stage2(kobject_t *kobj)
|
|
|
|
|
{
|
|
|
|
|
task_t *tk = container_of(kobj, task_t, kobj);
|
|
|
|
|
kobj_del_list_t kobj_list;
|
|
|
|
|
task_t *cur_tk = thread_get_current_task();
|
|
|
|
|
|
2023-08-28 23:54:33 +08:00
|
|
|
mm_limit_free_align(tk->lim, tk->mm_space.mm_block, tk->mm_space.mm_block_size);
|
2023-08-28 22:11:49 +08:00
|
|
|
mm_limit_free(tk->lim, tk);
|
|
|
|
|
if (cur_tk == tk)
|
|
|
|
|
{
|
|
|
|
|
thread_sched();
|
|
|
|
|
}
|
|
|
|
|
printk("release tk %x\n", tk);
|
2023-08-20 20:52:23 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-27 21:25:09 +08:00
|
|
|
task_t *task_create(ram_limit_t *lim, int is_knl)
|
2023-08-20 20:52:23 +08:00
|
|
|
{
|
|
|
|
|
task_t *tk = mm_limit_alloc(lim, sizeof(task_t));
|
|
|
|
|
|
|
|
|
|
if (!tk)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2023-08-27 21:25:09 +08:00
|
|
|
task_init(tk, lim, is_knl);
|
2023-08-20 20:52:23 +08:00
|
|
|
|
|
|
|
|
return tk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 该函数创建一个工厂对象
|
|
|
|
|
*
|
|
|
|
|
* @param lim
|
|
|
|
|
* @param arg0
|
|
|
|
|
* @param arg1
|
|
|
|
|
* @param arg2
|
|
|
|
|
* @param arg3
|
|
|
|
|
* @return kobject_t*
|
|
|
|
|
*/
|
|
|
|
|
static kobject_t *task_create_func(ram_limit_t *lim, umword_t arg0, umword_t arg1,
|
|
|
|
|
umword_t arg2, umword_t arg3)
|
|
|
|
|
{
|
2023-08-27 21:25:09 +08:00
|
|
|
task_t *tk = task_create(lim, FALSE);
|
2023-08-20 20:52:23 +08:00
|
|
|
|
|
|
|
|
return &tk->kobj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 工厂注册函数 TODO:
|
|
|
|
|
*
|
|
|
|
|
*/
|
2023-08-22 00:26:34 +08:00
|
|
|
void task_factory_register(void)
|
2023-08-20 20:52:23 +08:00
|
|
|
{
|
|
|
|
|
factory_register(task_create_func, TASK_PROT);
|
|
|
|
|
}
|
2023-08-22 00:26:34 +08:00
|
|
|
INIT_KOBJ(task_factory_register);
|