Files
mkrtos-real/mkrtos_knl/knl/map.c

163 lines
4.2 KiB
C
Executable File

/**
* @file map.c
* @author ATShining (1358745329@qq.com)
* @brief
* @version 0.1
* @date 2023-09-29
*
* @copyright Copyright (c) 2023
*
*/
#include "map.h"
#include "types.h"
#include "obj_space.h"
#include "kobject.h"
#include "assert.h"
#include "cpulock.h"
bool_t obj_map_root(kobject_t *kobj, obj_space_t *obj_space, ram_limit_t *ram, vpage_t page)
{
kobj_del_list_t kobj_list;
kobj_del_list_init(&kobj_list);
if (obj_space_lookup_kobj(obj_space, vpage_get_obj_handler(page)))
{ //!< 已经存在则删除
obj_unmap(obj_space, page, &kobj_list);
}
umword_t status = cpulock_lock();
kobj_del_list_to_do(&kobj_list);
cpulock_set(status);
obj_map_entry_t *map = obj_space_insert(obj_space, ram, kobj, vpage_get_obj_handler(page), vpage_get_attrs(page));
if (!map)
{
return FALSE;
}
kobj->mappable.map_cnt++;
slist_add(&kobj->mappable.node, &map->node);
return TRUE;
}
/**
* @brief 从源映射到目的,如果目的中已经存在,则先解除目的映射然后在影视
*
* @param dst_space
* @param src_space
* @param dst_inx
* @param src_inx
* @param ram
* @param del_attrs
* @return int
*/
int obj_map_src_dst(obj_space_t *dst_space, obj_space_t *src_space,
obj_handler_t dst_inx, obj_handler_t src_inx,
ram_limit_t *ram, uint8_t del_attrs, kobj_del_list_t *del_list)
{
obj_map_entry_t *entry_obj =
obj_space_lookup(src_space, src_inx);
if (!entry_obj)
{
return -ENOENT;
}
if (!entry_obj->obj)
{
return -ENOENT;
}
if (obj_space_lookup_kobj(dst_space, dst_inx))
{ //!< 已经存在则解除注释
obj_unmap(dst_space, vpage_create3(0, 0, dst_inx), del_list);
printk("unmap:%d \n", dst_inx);
}
return obj_map(dst_space, dst_inx, obj_map_entry_kobj_get(entry_obj),
ram, obj_map_entry_get_attr(entry_obj) & (~(del_attrs & 0x3UL)));
}
int obj_map(obj_space_t *obj_space, obj_handler_t inx, kobject_t *insert_kobj, ram_limit_t *ram, uint8_t attrs)
{
obj_map_entry_t *entry = NULL;
entry = obj_space_lookup(obj_space, inx);
if (entry)
{
if (obj_map_kobj_get(entry->obj))
{
return -EACCES;
}
}
obj_map_entry_t *map = obj_space_insert(obj_space, ram, insert_kobj, inx, attrs);
if (!map)
{
return -ENOMEM;
}
insert_kobj->mappable.map_cnt++;
slist_add(&insert_kobj->mappable.node, &map->node);
return 0;
}
void obj_unmap(obj_space_t *obj_space, vpage_t vpage, kobj_del_list_t *del_list)
{
obj_map_entry_t *entry = NULL;
entry = obj_space_lookup(obj_space, vpage_get_obj_handler(vpage));
if (!entry)
{
return;
}
kobject_t *kobj = obj_map_entry_kobj_get(entry);
if (!kobj)
{
return;
}
if (kobj->unmap_func)
{
kobj->unmap_func(obj_space, kobj);
}
if ((vpage.attrs & KOBJ_DELETE_RIGHT) &&
(obj_map_entry_get_attr(entry) & KOBJ_DELETE_RIGHT))
{
//!< 代表删除所有
obj_map_entry_t *pos;
slist_foreach_not_next(pos, &kobj->mappable.node, node)
{
obj_map_entry_t *next = slist_next_entry(pos, &kobj->mappable.node, node);
slist_del(&pos->node);
pos->obj = NULL;
// 删除一个
kobj->mappable.map_cnt--;
if (kobj->mappable.map_cnt <= 0)
{
if (del_list)
{
kobj_del_list_add(del_list, &kobj->del_node);
}
}
pos = next;
}
}
else
{
assert(!slist_is_empty(&entry->node));
slist_del(&entry->node);
entry->obj = NULL;
// 删除一个
kobj->mappable.map_cnt--;
if (kobj->mappable.map_cnt <= 0)
{
if (del_list)
{
kobj_del_list_add(del_list, &kobj->del_node);
}
}
}
}
void obj_unmap_all(obj_space_t *obj_space, kobj_del_list_t *del_list)
{
assert(obj_space);
for (umword_t i = 0; i < OBJ_MAP_MAX_ADDR; i++)
{
obj_unmap(obj_space, vpage_create3(KOBJ_DELETE_RIGHT /*执行删除操作*/, 0, i), del_list);
}
}