Files
mkrtos-real/mkrtos_knl/knl/mm_man.c
2023-09-29 01:03:19 +08:00

115 lines
2.5 KiB
C

/**
* @file mm_man.c
* @author zhangzheng (1358745329@qq.com)
* @brief
* @version 0.1
* @date 2023-09-29
*
* @copyright Copyright (c) 2023
*
*/
#include "types.h"
#include "kobject.h"
#include "init.h"
#include "mm_page.h"
#include "thread.h"
#include "task.h"
#include "globals.h"
#include "mpu.h"
typedef struct mm_man
{
kobject_t kobj;
} mm_man_t;
static mm_man_t mm_man;
static void mm_man_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f);
static void mm_man_reg(void)
{
kobject_init(&mm_man.kobj);
mm_man.kobj.invoke_func = mm_man_syscall;
global_reg_kobj(&mm_man.kobj, MM_PROT);
}
INIT_KOBJ(mm_man_reg);
enum mm_op
{
MM_ALLOC,
MM_FREE,
MM_ALIGN_ALLOC, //!< 直接暂用一个region
MM_ALIGN_FREE,
MM_MOD_ATTRS,
};
static void mm_man_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f)
{
task_t *cur_task = thread_get_current_task();
msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL);
if (sys_p.prot != MM_PROT)
{
f->r[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw;
return;
}
switch (sys_p.op)
{
case MM_ALLOC:
{
addr_t ret_addr;
int ret = mm_pages_alloc_page(&cur_task->mm_space.mm_pages, cur_task->lim, f->r[1], &ret_addr, f->r[2]);
if (ret < 0)
{
tag = msg_tag_init4(0, 0, 0, ret);
}
else
{
tag = msg_tag_init4(0, 0, 0, 0);
f->r[1] = ret_addr;
}
}
break;
case MM_FREE:
{
mm_pages_free_page(&cur_task->mm_space.mm_pages, cur_task->lim, f->r[1], f->r[2]);
tag = msg_tag_init4(0, 0, 0, 0);
}
break;
case MM_ALIGN_ALLOC:
{
region_info_t *regi_info = mm_space_alloc_pt_region(&cur_task->mm_space);
if (regi_info)
{
umword_t size = f->r[2];
umword_t addr = f->r[1];
if ((!is_power_of_2(size)) && ((addr & (~(size - 1))) != 0))
{
tag = msg_tag_init4(0, 0, 0, -EINVAL);
break;
}
mpu_calc_regs(regi_info, addr, ffs(size), REGION_RWX, 0);
mpu_switch_to_task(cur_task);
tag = msg_tag_init4(0, 0, 0, 0);
}
else
{
tag = msg_tag_init4(0, 0, 0, -ENOMEM);
}
}
break;
case MM_MOD_ATTRS:
{
tag = msg_tag_init4(0, 0, 0, -ENOSYS); // TODO:
}
break;
default:
tag = msg_tag_init4(0, 0, 0, -ENOSYS);
break;
}
f->r[0] = tag.raw;
}
void mm_man_dump(void)
{
}