forked from xuos/xiuos
First commit XiUOS
This commit is contained in:
11
kernel/memory/Makefile
Normal file
11
kernel/memory/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
SRC_FILES := byte_manage.c
|
||||
|
||||
ifeq ($(CONFIG_KERNEL_MEMBLOCK),y)
|
||||
SRC_FILES += gatherblock.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_TASK_ISOLATION),y)
|
||||
SRC_FILES += isolation.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
1037
kernel/memory/byte_manage.c
Normal file
1037
kernel/memory/byte_manage.c
Normal file
File diff suppressed because it is too large
Load Diff
414
kernel/memory/gatherblock.c
Normal file
414
kernel/memory/gatherblock.c
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: gatherblock.c
|
||||
* @brief: block memory management file
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/8
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xiuos.h>
|
||||
#include <xs_hook.h>
|
||||
|
||||
#ifdef KERNEL_MEMBLOCK
|
||||
|
||||
/* a global list, which record all the gatherblocks*/
|
||||
DoubleLinklistType xiaoshan_memgather_head = {&xiaoshan_memgather_head, &xiaoshan_memgather_head};
|
||||
|
||||
/**
|
||||
* This function initializes a gather block memory structure.
|
||||
*
|
||||
* @param gm_handler the gatherblock structure
|
||||
* @param gm_name the name of gatherblock
|
||||
* @param begin_address the start address of gatherblock
|
||||
* @param gm_size the total size of gatherblock
|
||||
* @param one_block_size one block size in gatherblock
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *begin_address, x_size_t gm_size, x_size_t one_block_size)
|
||||
{
|
||||
x_base lock = 0;
|
||||
register x_size_t off_block = 0;
|
||||
register x_base critical_value = 0;
|
||||
uint8 *block_ptr = NONE;
|
||||
struct SysDoubleLinklistNode *list_entry = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
NULL_PARAM_CHECK(gm_name);
|
||||
NULL_PARAM_CHECK(begin_address);
|
||||
|
||||
CHECK(gm_size >= 1 && one_block_size >= 1);
|
||||
|
||||
lock = CriticalAreaLock();
|
||||
|
||||
/* try to find gatherblock object */
|
||||
for (list_entry = xiaoshan_memgather_head.node_next;
|
||||
list_entry != &(xiaoshan_memgather_head);
|
||||
list_entry = list_entry->node_next) {
|
||||
GatherMemType gm;
|
||||
|
||||
gm = SYS_DOUBLE_LINKLIST_ENTRY(list_entry, struct MemGather, m_link);
|
||||
if (gm) {
|
||||
CHECK(gm != gm_handler);
|
||||
}
|
||||
}
|
||||
CriticalAreaUnLock(lock);
|
||||
|
||||
/* set the type attribute of gatherblock object */
|
||||
gm_handler->m_kind = Cmpt_KindN_Static;
|
||||
/* set the name of gatherblock object */
|
||||
strncpy(gm_handler->m_name, gm_name, NAME_NUM_MAX);
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* insert gatherblock object into the global list */
|
||||
DoubleLinkListInsertNodeAfter(&xiaoshan_memgather_head, &(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* initialize the other attributes of gatherblock object */
|
||||
gm_handler->m_start_address = begin_address;
|
||||
gm_handler->m_size = ALIGN_MEN_DOWN(gm_size, MEM_ALIGN_SIZE);
|
||||
one_block_size = ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE);
|
||||
gm_handler->one_block_size = one_block_size;
|
||||
gm_handler->block_total_number = gm_handler->m_size / (gm_handler->one_block_size + sizeof(uint8 *));
|
||||
gm_handler->block_free_number = gm_handler->block_total_number;
|
||||
|
||||
InitDoubleLinkList(&(gm_handler->wait_task));
|
||||
|
||||
/* links all the blocks in gatherblock object */
|
||||
block_ptr = (uint8 *)gm_handler->m_start_address;
|
||||
for (off_block = 0; off_block < gm_handler->block_total_number; off_block ++) {
|
||||
*(uint8 **)(block_ptr + off_block * (one_block_size + sizeof(uint8 *))) =
|
||||
(uint8 *)(block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *)));
|
||||
}
|
||||
|
||||
*(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) =
|
||||
NONE;
|
||||
|
||||
gm_handler->m_block_link = block_ptr;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function will remove the gatherblock from the global list, which is created by MemGatherInit function
|
||||
*
|
||||
* @param gm_handler the gatherblock to be removed
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t RemoveMemGather(struct MemGather *gm_handler)
|
||||
{
|
||||
register x_ubase critical_value = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
|
||||
CHECK((gm_handler->m_kind & Cmpt_KindN_Static)!=0);
|
||||
|
||||
/* resume all the suspend tasks on gatherblock object */
|
||||
while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(gm_handler->wait_task.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = -ERROR;
|
||||
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
}
|
||||
|
||||
/* set the type attribute */
|
||||
gm_handler->m_kind = 0;
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* remove the gatherblock object from the global links */
|
||||
DoubleLinkListRmNode(&(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will create a gatherblock object.
|
||||
*
|
||||
* @param gm_name the name of gatherblock
|
||||
* @param block_number the number of blocks in gatherblock
|
||||
* @param one_block_size one block size
|
||||
*
|
||||
* @return EOK on success; NONE on failure
|
||||
*/
|
||||
GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size_t one_block_size)
|
||||
{
|
||||
|
||||
register x_size_t off_block = 0;
|
||||
register x_base critical_value = 0;
|
||||
uint8 *block_ptr = NONE;
|
||||
struct MemGather *gm_handler = NONE;
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_name);
|
||||
CHECK(block_number >= 1 && one_block_size >= 1);
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* allocate memory for gatherblock object */
|
||||
gm_handler = (struct MemGather *)KERNEL_MALLOC(sizeof(struct MemGather));
|
||||
|
||||
if (NONE == gm_handler)
|
||||
return NONE;
|
||||
/* clear the gatherblock object */
|
||||
memset(gm_handler, 0x0, sizeof(struct MemGather));
|
||||
/* set the name attribute */
|
||||
strncpy(gm_handler->m_name, gm_name, NAME_NUM_MAX);
|
||||
/* set the flag attribute */
|
||||
gm_handler->m_sign = 0;
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* insert gatherblock object into the global list */
|
||||
DoubleLinkListInsertNodeAfter(&xiaoshan_memgather_head, &(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* set the other attributes of gatherblock object */
|
||||
one_block_size = ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE);
|
||||
gm_handler->one_block_size = one_block_size;
|
||||
gm_handler->m_size = (one_block_size + sizeof(uint8 *)) * block_number;
|
||||
|
||||
/* allocate memory for gather blocks */
|
||||
gm_handler->m_start_address = x_malloc((one_block_size + sizeof(uint8 *)) * block_number);
|
||||
if (NONE == gm_handler->m_start_address) {
|
||||
gm_handler->m_kind = 0;
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* remove the gatherblock object from the global links */
|
||||
DoubleLinkListRmNode(&(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* release the memory for gather block structure */
|
||||
KERNEL_FREE(gm_handler);
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
gm_handler->block_total_number = block_number;
|
||||
gm_handler->block_free_number = gm_handler->block_total_number;
|
||||
|
||||
InitDoubleLinkList(&(gm_handler->wait_task));
|
||||
|
||||
/* links all the gather blocks */
|
||||
block_ptr = (uint8 *)gm_handler->m_start_address;
|
||||
for (off_block = 0; off_block < gm_handler->block_total_number; off_block ++) {
|
||||
*(uint8 **)(block_ptr + off_block * (one_block_size + sizeof(uint8 *)))
|
||||
= block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *));
|
||||
}
|
||||
|
||||
*(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *)))
|
||||
= NONE;
|
||||
|
||||
gm_handler->m_block_link = block_ptr;
|
||||
|
||||
return gm_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will delete a gatherblock object, which is created by MemGatherCreate function.
|
||||
*
|
||||
* @param gm_handler the gatherblock object to be deleted
|
||||
*
|
||||
* @return EOK
|
||||
*/
|
||||
x_err_t DeleteMemGather(GatherMemType gm_handler)
|
||||
{
|
||||
register x_ubase critical_value = 0;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
CHECK(((gm_handler->m_kind & Cmpt_KindN_Static)==0));
|
||||
|
||||
/* resume all the suspend tasks on gatherblock object */
|
||||
while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(gm_handler->wait_task.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = -ERROR;
|
||||
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
}
|
||||
|
||||
/* release the memory for gather blocks */
|
||||
x_free(gm_handler->m_start_address);
|
||||
|
||||
gm_handler->m_kind = 0;
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* remove the gatherblock object from the global links */
|
||||
DoubleLinkListRmNode(&(gm_handler->m_link));
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* release the memory for gather block structure */
|
||||
KERNEL_FREE(gm_handler);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will allocate a data block from gatherblock object
|
||||
*
|
||||
* @param gm_handler the gatherblock object to get data block
|
||||
* @param msec waiting time ,millisecond
|
||||
*
|
||||
* @return block pointer on success; NONE on failure
|
||||
*/
|
||||
void *AllocBlockMemGather(GatherMemType gm_handler, int32 msec)
|
||||
{
|
||||
int32 wait_time = 0;
|
||||
uint32 before_sleep = 0;
|
||||
register x_base critical_value = 0;
|
||||
uint8 *block_ptr = NONE;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(gm_handler);
|
||||
|
||||
/* get descriptor of task */
|
||||
task = GetKTaskDescriptor();
|
||||
wait_time = CalculteTickFromTimeMs(msec);
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
/* no free gatherblock*/
|
||||
while (0 == gm_handler->block_free_number) {
|
||||
if (wait_time == 0) {
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
KUpdateExstatus(ETIMEOUT);
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
KDEBUG_NOT_IN_INTERRUPT;
|
||||
|
||||
task->exstatus = EOK;
|
||||
|
||||
/* suspend current task */
|
||||
SuspendKTask(task->id.id);
|
||||
DoubleLinkListInsertNodeAfter(&(gm_handler->wait_task), &(task->task_dync_sched_member.sched_link));
|
||||
|
||||
if (wait_time > 0) {
|
||||
before_sleep = CurrentTicksGain();
|
||||
/* start the timer */
|
||||
KTaskSetDelay(task,wait_time);
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
/* schedule */
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
if (EOK != task->exstatus)
|
||||
return NONE;
|
||||
|
||||
if (wait_time > 0) {
|
||||
wait_time -= CurrentTicksGain() - before_sleep;
|
||||
if (wait_time < 0)
|
||||
wait_time = 0;
|
||||
}
|
||||
critical_value = CriticalAreaLock();
|
||||
}
|
||||
/* decrease the number of free gatherblocks */
|
||||
gm_handler->block_free_number--;
|
||||
|
||||
block_ptr = gm_handler->m_block_link;
|
||||
NULL_PARAM_CHECK(block_ptr);
|
||||
|
||||
/* set the block_list attribute of gather_block structure */
|
||||
gm_handler->m_block_link = *(uint8 **)block_ptr;
|
||||
|
||||
*(uint8 **)block_ptr = (uint8 *)gm_handler;
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
HOOK(hook.mem.hook_GmAlloc, (gm_handler, (uint8 *)(block_ptr + sizeof(uint8 *))));
|
||||
|
||||
return (uint8 *)(block_ptr + sizeof(uint8 *));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will release a data block to gatherblock object
|
||||
*
|
||||
* @param data_block the data block to be released
|
||||
*/
|
||||
void FreeBlockMemGather(void *data_block)
|
||||
{
|
||||
uint8 **block_ptr;
|
||||
register x_base critical_value = 0;
|
||||
struct MemGather *gm_handler = NONE;
|
||||
struct TaskDescriptor *task = NONE;
|
||||
|
||||
/* parameter detection */
|
||||
NULL_PARAM_CHECK(data_block);
|
||||
|
||||
/* get gatherblock structure */
|
||||
block_ptr = (uint8 **)((uint8 *)data_block - sizeof(uint8 *));
|
||||
gm_handler = (struct MemGather *)*block_ptr;
|
||||
|
||||
HOOK(hook.mem.hook_GmFree, (gm_handler, data_block));
|
||||
|
||||
critical_value = CriticalAreaLock();
|
||||
|
||||
/* increase the number of gatherblocks */
|
||||
gm_handler->block_free_number ++;
|
||||
|
||||
*block_ptr = gm_handler->m_block_link;
|
||||
/* set the block_list attribute of gather_block object */
|
||||
gm_handler->m_block_link = (uint8 *)block_ptr;
|
||||
|
||||
if (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) {
|
||||
task = SYS_DOUBLE_LINKLIST_ENTRY(gm_handler->wait_task.node_next, struct TaskDescriptor, task_dync_sched_member.sched_link);
|
||||
task->exstatus = EOK;
|
||||
|
||||
/* resume a suspend task */
|
||||
KTaskWakeup(task->id.id);
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
|
||||
DO_KTASK_ASSIGN;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(critical_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
59
kernel/memory/isolation.c
Normal file
59
kernel/memory/isolation.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: isolation.c
|
||||
* @brief: memory access structure definitions of ARM/RISCV
|
||||
* @version: 1.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2020/3/15
|
||||
*
|
||||
*/
|
||||
|
||||
#include <xs_isolation.h>
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
|
||||
#if defined(ARCH_ARM) && defined(SURPORT_MPU)
|
||||
|
||||
struct Mpu *isolation = NONE;
|
||||
struct MemoryAccessLimit mem_access = {
|
||||
.Enable = MpuEnable ,
|
||||
.Disable = MpuDisable ,
|
||||
.Init = MpuInit ,
|
||||
.InitIsolation = NONE,
|
||||
.AddRegion = NONE,
|
||||
.ClearRegion = NONE ,
|
||||
.Free = NONE,
|
||||
.Load = MpuLoad,
|
||||
.FaultHandle = NONE,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_RISCV) && defined(SURPORT_PMP)
|
||||
|
||||
struct Pmp *isolation = NONE;
|
||||
struct MemoryAccessLimit mem_access = {
|
||||
.Enable = NONE ,
|
||||
.Disable = NONE ,
|
||||
.Init = NONE ,
|
||||
.InitIsolation = PmpInitIsolation,
|
||||
.AddRegion = PmpAddTorRegion,
|
||||
.ClearRegion = PmpClearRegion ,
|
||||
.Free = PmpFree,
|
||||
.Load = PmpLoad,
|
||||
.FaultHandle = PmpAccessFaultHandle,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user