内核线程能够调度
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -343,7 +343,9 @@
|
||||
"slab.h": "c",
|
||||
"arm_local_reg.h": "c",
|
||||
"timer.h": "c",
|
||||
"arm_gicv2.h": "c"
|
||||
"arm_gicv2.h": "c",
|
||||
"sched_arch.h": "c",
|
||||
"thread_task_arch.h": "c"
|
||||
},
|
||||
"cortex-debug.showRTOS": false,
|
||||
"cortex-debug.variableUseNaturalFormat": false,
|
||||
|
||||
@@ -12,7 +12,7 @@ CONFIG_INIT_TASK_OFFSET=0x10000
|
||||
CONFIG_BOOTFS_OFFSET=0x02000000
|
||||
CONFIG_MK_MPU_CFG=n
|
||||
CONFIG_FT_ADDR_NR=16
|
||||
CONFIG_SYS_SCHE_HZ=1000
|
||||
CONFIG_SYS_SCHE_HZ=100
|
||||
CONFIG_USER_ISR_START_NO=16
|
||||
CONFIG_IRQ_REG_TAB_SIZE=80
|
||||
CONFIG_REGION_NUM=8
|
||||
@@ -116,3 +116,5 @@ CONFIG_SMP=y
|
||||
CONFIG_CPU=4
|
||||
CONFIG_THREAD_BLOCK_SIZE=0x1000
|
||||
CONFIG_PAGE_SHIFT=12
|
||||
CONFIG_MMU=y
|
||||
CONFIG_KNL_TEST=y
|
||||
|
||||
@@ -4,7 +4,14 @@ menu "Knl config"
|
||||
menuconfig KNL_INFO
|
||||
bool "knl info set"
|
||||
default y
|
||||
|
||||
config KNL_TEST
|
||||
bool "enable knl test."
|
||||
default n
|
||||
if KNL_INFO
|
||||
config MMU
|
||||
bool "support mmu"
|
||||
default n
|
||||
config PAGE_SHIFT
|
||||
int "page shift"
|
||||
default 9
|
||||
|
||||
@@ -30,5 +30,6 @@ target_include_directories(
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/lib
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/inc/knl
|
||||
|
||||
${CMAKE_SOURCE_DIR}/mkrtos_knl/arch/${ARCH}/${CONFIG_CPU_TYPE}
|
||||
|
||||
)
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
#include "config.h"
|
||||
#include "thread.h"
|
||||
#include "mk_sys.h"
|
||||
#include "mpu.h"
|
||||
#include <psci.h>
|
||||
#include <arm_gicv2.h>
|
||||
#include <timer/timer.h>
|
||||
#include <hyp.h>
|
||||
#include <sche_arch.h>
|
||||
__ALIGN__(THREAD_BLOCK_SIZE)
|
||||
static uint8_t thread_knl_stack[THREAD_BLOCK_SIZE] = {0};
|
||||
void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE;
|
||||
@@ -29,8 +29,7 @@ void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE;
|
||||
*/
|
||||
void to_sche(void)
|
||||
{
|
||||
// 开启pensv中断
|
||||
/*TODO:*/
|
||||
sche_arch_sw_context();
|
||||
}
|
||||
/**
|
||||
* 进行一些系统的初始化
|
||||
|
||||
@@ -16,6 +16,50 @@
|
||||
#include <aarch64_ptregs.h>
|
||||
#define LOG_INTR_NO 37 // USART1_IRQn
|
||||
|
||||
/// @brief 线程信息
|
||||
typedef struct
|
||||
{
|
||||
umword_t rg0[8]; //!< r0-r3
|
||||
umword_t r12;
|
||||
umword_t lr;
|
||||
umword_t pc;
|
||||
} pf_s_t;
|
||||
typedef struct pf
|
||||
{
|
||||
struct
|
||||
{
|
||||
mword_t regs[31]; //!< 基础寄存器
|
||||
mword_t sp; //!< sp
|
||||
mword_t pc; //!< pc
|
||||
mword_t pstate; //!< pstate
|
||||
};
|
||||
|
||||
mword_t orig_x0;
|
||||
uint32_t syscallno;
|
||||
uint32_t unused2;
|
||||
|
||||
mword_t orig_addr_limit;
|
||||
mword_t unused;
|
||||
mword_t stackframe[2];
|
||||
} pf_t;
|
||||
|
||||
typedef struct sp_info
|
||||
{
|
||||
mword_t x19;
|
||||
mword_t x20;
|
||||
mword_t x21;
|
||||
mword_t x22;
|
||||
mword_t x23;
|
||||
mword_t x24;
|
||||
mword_t x25;
|
||||
mword_t x26;
|
||||
mword_t x27;
|
||||
mword_t x28;
|
||||
mword_t fp; // x29
|
||||
mword_t sp;
|
||||
mword_t pc;
|
||||
} sp_info_t;
|
||||
|
||||
#define _barrier() __asm__ __volatile__("" : : : "memory")
|
||||
#define _dmb(ins) \
|
||||
asm volatile("dmb " #ins : : : "memory")
|
||||
@@ -23,6 +67,15 @@
|
||||
#define _dsb(ins) \
|
||||
asm volatile("dsb " #ins : : : "memory")
|
||||
|
||||
#define __arch_getl(a) (*(volatile unsigned int *)(a))
|
||||
#define __arch_putl(v, a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
#define __iormb() _barrier()
|
||||
#define __iowmb() _barrier()
|
||||
|
||||
#define readl(c) ({ unsigned int __v = __arch_getl(c); __iormb(); __v; })
|
||||
#define writel(v, c) ({ unsigned int __v = v; __iowmb(); __arch_putl(__v,c); })
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
do \
|
||||
@@ -155,7 +208,7 @@ static inline umword_t intr_status(void)
|
||||
umword_t ret;
|
||||
|
||||
asm volatile("mrs %0, daif" : "=r"(ret));
|
||||
return !(ret & 0xc0);
|
||||
return !!(ret & 0xc0);
|
||||
}
|
||||
|
||||
void sys_startup(void);
|
||||
|
||||
@@ -187,20 +187,9 @@ tsk .req x28 // current thread_info
|
||||
el1_irq:
|
||||
kernel_entry 2
|
||||
bl entry_handler
|
||||
get_thread_info tsk
|
||||
// bl 2f
|
||||
//1:
|
||||
// kernel_exit 2
|
||||
//2:
|
||||
// mov x24, lr
|
||||
//bl sched_printf
|
||||
bl SysTick_Handler
|
||||
kernel_exit 2
|
||||
// ret x24
|
||||
//
|
||||
|
||||
//string_test:
|
||||
// .string "t"
|
||||
|
||||
.global trigger_alignment
|
||||
trigger_alignment:
|
||||
@@ -230,9 +219,6 @@ ret_form_run:
|
||||
mov x0, x20
|
||||
blr x19
|
||||
1:
|
||||
//ldr x19, =test_user_stack
|
||||
//add x19, x19, #(4096 - 8)
|
||||
//msr sp_el1, x19
|
||||
b ret_to_user
|
||||
|
||||
/* 进程切换: 保存prev进程的上下文,并且恢复next进程
|
||||
|
||||
@@ -2,29 +2,6 @@
|
||||
#ifndef _P_IO_H
|
||||
#define _P_BASE_H
|
||||
|
||||
#if 1
|
||||
#define __arch_getl(a) (*(volatile unsigned int *)(a))
|
||||
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
#ifndef dmb
|
||||
#define dmb() __asm__ __volatile__ ("" : : : "memory")
|
||||
#endif
|
||||
#define __iormb() dmb()
|
||||
#define __iowmb() dmb()
|
||||
|
||||
#define readl(c) ({ unsigned int __v = __arch_getl(c); __iormb(); __v; })
|
||||
#define writel(v,c) ({ unsigned int __v = v; __iowmb(); __arch_putl(__v,c);})
|
||||
#else
|
||||
static inline void writel(unsigned int value, unsigned int addr)
|
||||
{
|
||||
*(volatile unsigned int *)addr = value;
|
||||
}
|
||||
|
||||
static inline unsigned int readl(unsigned int addr)
|
||||
{
|
||||
return *(volatile unsigned int *)addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void delay(unsigned int n)
|
||||
{
|
||||
|
||||
@@ -3,28 +3,11 @@
|
||||
/*
|
||||
* PSR bits
|
||||
*/
|
||||
#define PSR_MODE_EL0t 0x00000000
|
||||
#define PSR_MODE_EL1t 0x00000004
|
||||
#define PSR_MODE_EL1h 0x00000005
|
||||
#define PSR_MODE_EL2t 0x00000008
|
||||
#define PSR_MODE_EL2h 0x00000009
|
||||
#define PSR_MODE_EL3t 0x0000000c
|
||||
#define PSR_MODE_EL3h 0x0000000d
|
||||
#define PSR_MODE_MASK 0x0000000f
|
||||
|
||||
typedef struct entry_frame {
|
||||
struct {
|
||||
mword_t regs[31];
|
||||
mword_t sp;
|
||||
mword_t pc;
|
||||
mword_t pstate;
|
||||
};
|
||||
|
||||
mword_t orig_x0;
|
||||
uint32_t syscallno;
|
||||
uint32_t unused2;
|
||||
|
||||
mword_t orig_addr_limit;
|
||||
mword_t unused;
|
||||
mword_t stackframe[2];
|
||||
} entry_frame_t;
|
||||
#define PSR_MODE_EL0t 0x00000000
|
||||
#define PSR_MODE_EL1t 0x00000004
|
||||
#define PSR_MODE_EL1h 0x00000005
|
||||
#define PSR_MODE_EL2t 0x00000008
|
||||
#define PSR_MODE_EL2h 0x00000009
|
||||
#define PSR_MODE_EL3t 0x0000000c
|
||||
#define PSR_MODE_EL3h 0x0000000d
|
||||
#define PSR_MODE_MASK 0x0000000f
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
#include <arch.h>
|
||||
#include "early_boot.h"
|
||||
#include "asm/sysregs.h"
|
||||
#include "asm/base.h"
|
||||
#include "asm/mm.h"
|
||||
@@ -10,7 +9,8 @@
|
||||
#include <config.h>
|
||||
#include <spinlock.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <mm_page.h>
|
||||
#include <early_boot.h>
|
||||
#define DATA_BOOT_SECTION ".data.boot"
|
||||
#define TEXT_BOOT_SECTION ".text.boot"
|
||||
|
||||
|
||||
@@ -4,16 +4,7 @@
|
||||
#include "pager.h"
|
||||
#include "asm/mm.h"
|
||||
#include "asm_config.h"
|
||||
|
||||
#define PAGE_DEEP 4
|
||||
|
||||
typedef struct page_entry
|
||||
{
|
||||
pte_t *dir; //!< 存储页表地址
|
||||
uint8_t lv_shift_sizes[PAGE_DEEP]; //!< 页表翻译的大小,order
|
||||
uint8_t depth; //!< 页表深度
|
||||
} page_entry_t;
|
||||
|
||||
#include <mm_page.h>
|
||||
pte_t *pages_walk(page_entry_t *pdir, addr_t virt_addr, mword_t size, void *(*fn_alloc)(void));
|
||||
void map_mm(page_entry_t *pdir, addr_t virt_addr, addr_t phys_addr,
|
||||
mword_t page_order, mword_t pfn_cn, mword_t attr);
|
||||
|
||||
15
mkrtos_knl/arch/aarch64/mm_page.c
Normal file
15
mkrtos_knl/arch/aarch64/mm_page.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <buddy.h>
|
||||
#include <asm/mm.h>
|
||||
#include "mm_page.h"
|
||||
#include <early_boot.h>
|
||||
int page_entry_init(page_entry_t *entry)
|
||||
{
|
||||
entry->dir = buddy_alloc(buddy_get_alloter(), PAGE_SIZE);
|
||||
|
||||
if (entry->dir == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
knl_pdir_init(entry, entry->dir, 3);
|
||||
return 0;
|
||||
}
|
||||
15
mkrtos_knl/arch/aarch64/mm_page.h
Normal file
15
mkrtos_knl/arch/aarch64/mm_page.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include "pager.h"
|
||||
#include <err.h>
|
||||
#define PAGE_DEEP 4
|
||||
|
||||
typedef struct page_entry
|
||||
{
|
||||
pte_t *dir; //!< 存储页表地址
|
||||
uint8_t lv_shift_sizes[PAGE_DEEP]; //!< 页表翻译的大小,order
|
||||
uint8_t depth; //!< 页表深度
|
||||
} page_entry_t;
|
||||
|
||||
int page_entry_init(page_entry_t *entry);
|
||||
31
mkrtos_knl/arch/aarch64/mm_space.c
Normal file
31
mkrtos_knl/arch/aarch64/mm_space.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @file mm_space.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "mm_space.h"
|
||||
#include "assert.h"
|
||||
#include <early_boot.h>
|
||||
#include <mm_page.h>
|
||||
void mm_space_init(mm_space_t *mm_space, int is_knl)
|
||||
{
|
||||
page_entry_init(&mm_space->mem_dir);
|
||||
}
|
||||
bool_t mm_space_add(mm_space_t *m_space,
|
||||
umword_t addr,
|
||||
umword_t size,
|
||||
uint8_t attrs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void mm_space_del(mm_space_t *m_space, umword_t addr)
|
||||
{
|
||||
/*TODO:*/
|
||||
}
|
||||
@@ -254,4 +254,3 @@ typedef struct pte
|
||||
#define PTE_ADDR_LOW (((1UL << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
|
||||
#define PTE_ADDR_MASK PTE_ADDR_LOW
|
||||
|
||||
void paging_init(void);
|
||||
|
||||
35
mkrtos_knl/arch/aarch64/sche.s
Normal file
35
mkrtos_knl/arch/aarch64/sche.s
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <asm_config.h>
|
||||
#include <asm_offset.h>
|
||||
|
||||
|
||||
/* 进程切换: 保存prev进程的上下文,并且恢复next进程
|
||||
的上下文
|
||||
cpu_switch_to(struct cpu_context *prev,
|
||||
struct cpu_context *next);
|
||||
|
||||
需要保存的上下文: x19 ~ x29, sp, lr
|
||||
保存到进程的task_struct->cpu_context
|
||||
*/
|
||||
.align
|
||||
.global cpu_switch_to
|
||||
cpu_switch_to:
|
||||
mov x8, x0
|
||||
mov x9, sp
|
||||
stp x19, x20, [x8], #16
|
||||
stp x21, x22, [x8], #16
|
||||
stp x23, x24, [x8], #16
|
||||
stp x25, x26, [x8], #16
|
||||
stp x27, x28, [x8], #16
|
||||
stp x29, x9, [x8], #16
|
||||
str lr, [x8]
|
||||
|
||||
mov x8, x1
|
||||
ldp x19, x20, [x8], #16
|
||||
ldp x21, x22, [x8], #16
|
||||
ldp x23, x24, [x8], #16
|
||||
ldp x25, x26, [x8], #16
|
||||
ldp x27, x28, [x8], #16
|
||||
ldp x29, x9, [x8], #16
|
||||
ldr lr, [x8]
|
||||
mov sp, x9
|
||||
ret
|
||||
55
mkrtos_knl/arch/aarch64/sche_arch.c
Normal file
55
mkrtos_knl/arch/aarch64/sche_arch.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <types.h>
|
||||
#include <thread.h>
|
||||
#include <arch.h>
|
||||
#include <util.h>
|
||||
#include <sche_arch.h>
|
||||
#include <mm_space.h>
|
||||
#include <task.h>
|
||||
static void sw_mmu(thread_t *next_thread)
|
||||
{
|
||||
umword_t p_curr_dir = read_sysreg(vttbr_el2);
|
||||
task_t *next_task = (task_t *)(next_thread->task);
|
||||
umword_t p_next_dir = (umword_t)mm_space_get_pdir(&next_task->mm_space)->dir;
|
||||
|
||||
if (p_curr_dir != p_next_dir)
|
||||
{
|
||||
_dsb(sy);
|
||||
write_sysreg(p_next_dir | (1UL << 48) /*TODO:*/, vttbr_el2);
|
||||
_dsb(ish);
|
||||
_isb();
|
||||
asm volatile("ic iallu");
|
||||
|
||||
// mword_t vttbr;
|
||||
// // FIXME: could do a compare for the current VMID before loading
|
||||
// // the vttbr and the isb
|
||||
// asm volatile(
|
||||
// "mrs %[vttbr], vttbr_el2\n"
|
||||
// "msr vttbr_el2, %[asid] \n"
|
||||
// "isb \n"
|
||||
// "dsb ishst \n"
|
||||
// "tlbi ipas2e1, %[ipa] \n"
|
||||
// "dsb ish \n"
|
||||
// "tlbi vmalle1 \n"
|
||||
// "dsb ish \n"
|
||||
// "msr vttbr_el2, %[vttbr]\n"
|
||||
// :
|
||||
// [vttbr] "=&r" (vttbr)
|
||||
// :
|
||||
// [ipa] "r" ((unsigned long)va >> 12),
|
||||
// [asid] "r" (1 << 48)
|
||||
// :
|
||||
// "memory");
|
||||
}
|
||||
}
|
||||
void sche_arch_sw_context(void)
|
||||
{
|
||||
scheduler_t *sche = scheduler_get_current();
|
||||
thread_t *cur_th = thread_get_current();
|
||||
|
||||
sched_t *next = sche->cur_sche;
|
||||
thread_t *next_th = container_of(next, thread_t, sche);
|
||||
// 这里切换页表
|
||||
sw_mmu(next_th);
|
||||
// 变成了next的sp
|
||||
cpu_switch_to(&cur_th->sp, &next_th->sp);
|
||||
}
|
||||
6
mkrtos_knl/arch/aarch64/sche_arch.h
Normal file
6
mkrtos_knl/arch/aarch64/sche_arch.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <arch.h>
|
||||
|
||||
void cpu_switch_to(sp_info_t *prev,
|
||||
sp_info_t *next);
|
||||
void sche_arch_sw_context(void);
|
||||
46
mkrtos_knl/arch/aarch64/thread_aarch64.c
Normal file
46
mkrtos_knl/arch/aarch64/thread_aarch64.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file thread_armv7m.c
|
||||
* @author ATShining (135874329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "thread.h"
|
||||
#include "printk.h"
|
||||
#include "app.h"
|
||||
#include "mm_wrap.h"
|
||||
#include "arch.h"
|
||||
#include "string.h"
|
||||
#include <asm/system.h>
|
||||
#include <early_boot.h>
|
||||
#include <task.h>
|
||||
extern void ret_form_run(void);
|
||||
syscall_entry_func syscall_handler_get(void)
|
||||
{
|
||||
return syscall_entry;
|
||||
}
|
||||
void thread_knl_pf_set(thread_t *cur_th, void *pc)
|
||||
{
|
||||
pf_t *pt = ((pf_t *)((char *)cur_th + THREAD_BLOCK_SIZE)) - 1;
|
||||
|
||||
pt->pstate = PSR_MODE_EL2h;
|
||||
// pt->pc = (umword_t)pc;
|
||||
cur_th->sp.x19 = (umword_t)pc;
|
||||
cur_th->sp.x20 = 0 /*arg*/;
|
||||
cur_th->sp.pc = (mword_t)ret_form_run;
|
||||
cur_th->sp.sp = (umword_t)pt;
|
||||
}
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack)
|
||||
{
|
||||
/*TODO:*/
|
||||
assert(0);
|
||||
}
|
||||
void task_knl_init(task_t *knl_tk)
|
||||
{
|
||||
knl_tk->mm_space.mem_dir = *boot_get_pdir();
|
||||
}
|
||||
25
mkrtos_knl/arch/cortex-m3/sched_arch.c
Normal file
25
mkrtos_knl/arch/cortex-m3/sched_arch.c
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
|
||||
#include <scheduler.h>
|
||||
#include <types.h>
|
||||
#include <thread.h>
|
||||
#include <util.h>
|
||||
sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type)
|
||||
{
|
||||
scheduler_t *sche = scheduler_get_current();
|
||||
|
||||
sched_t *next = sche->cur_sche;
|
||||
thread_t *next_th = container_of(next, thread_t, sche);
|
||||
|
||||
assert(next_th->magic == THREAD_MAGIC);
|
||||
|
||||
if (sched_reset)
|
||||
{
|
||||
thread_t *cur_th = thread_get_current();
|
||||
cur_th->sp.knl_sp = ksp;
|
||||
cur_th->sp.user_sp = usp;
|
||||
cur_th->sp.sp_type = sp_type;
|
||||
}
|
||||
sched_reset = 1;
|
||||
return &next_th->sp;
|
||||
}
|
||||
@@ -14,6 +14,28 @@
|
||||
#include "arch.h"
|
||||
#define LOG_INTR_NO 38 // USART2_IRQn
|
||||
|
||||
/// @brief 线程信息
|
||||
typedef struct
|
||||
{
|
||||
umword_t rg0[4]; //!< r0-r3
|
||||
umword_t r12;
|
||||
umword_t lr;
|
||||
umword_t pc;
|
||||
umword_t xpsr;
|
||||
} pf_s_t;
|
||||
typedef struct pf
|
||||
{
|
||||
umword_t rg1[8]; //!< r4-r11
|
||||
pf_s_t pf_s;
|
||||
} pf_t;
|
||||
|
||||
typedef struct sp_info
|
||||
{
|
||||
void *user_sp; //!< 用户态的sp
|
||||
void *knl_sp; //!< 内核sp
|
||||
mword_t sp_type; //!< 使用的栈类型
|
||||
} sp_info_t;
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
do \
|
||||
@@ -88,17 +110,17 @@ void arch_disable_irq(int inx);
|
||||
void arch_enable_irq(int inx);
|
||||
void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio);
|
||||
|
||||
#define sti() \
|
||||
#define sti() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("CPSID I\n" :: \
|
||||
:); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
|
||||
static inline __attribute__((optimize(0))) void preemption(void)
|
||||
{
|
||||
@@ -118,4 +140,3 @@ void sys_reset(void);
|
||||
umword_t sys_tick_cnt_get(void);
|
||||
|
||||
uint32_t arch_get_sys_clk(void);
|
||||
|
||||
|
||||
@@ -12,7 +12,29 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "arch.h"
|
||||
#define LOG_INTR_NO 37//USART1_IRQn
|
||||
#define LOG_INTR_NO 37 // USART1_IRQn
|
||||
|
||||
/// @brief 线程信息
|
||||
typedef struct
|
||||
{
|
||||
umword_t rg0[4]; //!< r0-r3
|
||||
umword_t r12;
|
||||
umword_t lr;
|
||||
umword_t pc;
|
||||
umword_t xpsr;
|
||||
} pf_s_t;
|
||||
typedef struct pf
|
||||
{
|
||||
umword_t rg1[8]; //!< r4-r11
|
||||
pf_s_t pf_s;
|
||||
} pf_t;
|
||||
|
||||
typedef struct sp_info
|
||||
{
|
||||
void *user_sp; //!< 用户态的sp
|
||||
void *knl_sp; //!< 内核sp
|
||||
mword_t sp_type; //!< 使用的栈类型
|
||||
} sp_info_t;
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
@@ -43,7 +65,7 @@
|
||||
: "=r"(ret) \
|
||||
: \
|
||||
:); \
|
||||
((ret & 0x4) ? 0 : 1); \
|
||||
((ret & 0x4) ? 0 : 1); \
|
||||
})
|
||||
|
||||
void to_sche(void);
|
||||
@@ -88,17 +110,17 @@ void arch_disable_irq(int inx);
|
||||
void arch_enable_irq(int inx);
|
||||
void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio);
|
||||
|
||||
#define sti() \
|
||||
#define sti() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("CPSID I\n" :: \
|
||||
:); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
|
||||
static inline __attribute__((optimize(0))) void preemption(void)
|
||||
{
|
||||
|
||||
85
mkrtos_knl/arch/cortex-m33/mm_space.c
Normal file
85
mkrtos_knl/arch/cortex-m33/mm_space.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file mm_space.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "mm_space.h"
|
||||
#include "mpu.h"
|
||||
#include "assert.h"
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
void mm_space_init(mm_space_t *mm_space, int is_knl)
|
||||
{
|
||||
for (int i = 0; i < CONFIG_REGION_NUM; i++)
|
||||
{
|
||||
mm_space->pt_regions[i].region_inx = -1;
|
||||
}
|
||||
}
|
||||
region_info_t *mm_space_alloc_pt_region(mm_space_t *m_space)
|
||||
{
|
||||
for (int i = 0; i < CONFIG_REGION_NUM; i++)
|
||||
{
|
||||
/*TODO:原子操作*/
|
||||
if (m_space->pt_regions[i].region_inx < 0)
|
||||
{
|
||||
m_space->pt_regions[i].region_inx = (int16_t)i;
|
||||
return &m_space->pt_regions[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void mm_space_free_pt_region(mm_space_t *m_space, region_info_t *ri)
|
||||
{
|
||||
ri->region_inx = -1;
|
||||
}
|
||||
|
||||
bool_t mm_space_add(mm_space_t *m_space,
|
||||
umword_t addr,
|
||||
umword_t size,
|
||||
uint8_t attrs)
|
||||
{
|
||||
region_info_t *ri = mm_space_alloc_pt_region(m_space);
|
||||
|
||||
if (!ri)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
if (!is_power_of_2(size) || (addr & (!(size - 1))) != 0)
|
||||
{
|
||||
//!< 申请的大小必须是2的整数倍,而且地址也必须是2的整数倍
|
||||
mm_space_free_pt_region(m_space, ri);
|
||||
return FALSE;
|
||||
}
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
if ((size & (MPU_ALIGN_SIZE - 1)) == 0 && (addr & (MPU_ALIGN_SIZE - 1)) == 0)
|
||||
{
|
||||
mm_space_free_pt_region(m_space, ri);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
mpu_calc_regs(ri, addr, size, attrs, 0);
|
||||
ri->start_addr = addr;
|
||||
ri->size = size;
|
||||
return TRUE;
|
||||
}
|
||||
void mm_space_del(mm_space_t *m_space, umword_t addr)
|
||||
{
|
||||
for (int i = 0; i < CONFIG_REGION_NUM; i++)
|
||||
{
|
||||
if (m_space->pt_regions[i].region_inx >= 0 &&
|
||||
m_space->pt_regions[i].start_addr == addr)
|
||||
{
|
||||
m_space->pt_regions[i].region_inx = -1;
|
||||
m_space->pt_regions[i].start_addr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
25
mkrtos_knl/arch/cortex-m33/sched_arch.c
Normal file
25
mkrtos_knl/arch/cortex-m33/sched_arch.c
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
|
||||
#include <scheduler.h>
|
||||
#include <types.h>
|
||||
#include <thread.h>
|
||||
#include <util.h>
|
||||
sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type)
|
||||
{
|
||||
scheduler_t *sche = scheduler_get_current();
|
||||
|
||||
sched_t *next = sche->cur_sche;
|
||||
thread_t *next_th = container_of(next, thread_t, sche);
|
||||
|
||||
assert(next_th->magic == THREAD_MAGIC);
|
||||
|
||||
if (sched_reset)
|
||||
{
|
||||
thread_t *cur_th = thread_get_current();
|
||||
cur_th->sp.knl_sp = ksp;
|
||||
cur_th->sp.user_sp = usp;
|
||||
cur_th->sp.sp_type = sp_type;
|
||||
}
|
||||
sched_reset = 1;
|
||||
return &next_th->sp;
|
||||
}
|
||||
@@ -15,6 +15,28 @@
|
||||
|
||||
#define LOG_INTR_NO 0 // UART0_IRQn
|
||||
|
||||
/// @brief 线程信息
|
||||
typedef struct
|
||||
{
|
||||
umword_t rg0[4]; //!< r0-r3
|
||||
umword_t r12;
|
||||
umword_t lr;
|
||||
umword_t pc;
|
||||
umword_t xpsr;
|
||||
} pf_s_t;
|
||||
typedef struct pf
|
||||
{
|
||||
umword_t rg1[8]; //!< r4-r11
|
||||
pf_s_t pf_s;
|
||||
} pf_t;
|
||||
|
||||
typedef struct sp_info
|
||||
{
|
||||
void *user_sp; //!< 用户态的sp
|
||||
void *knl_sp; //!< 内核sp
|
||||
mword_t sp_type; //!< 使用的栈类型
|
||||
} sp_info_t;
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
do \
|
||||
@@ -92,12 +114,12 @@ void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio);
|
||||
#define sti() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(1, PRIMASK); \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
write_sysreg(1, PRIMASK); \
|
||||
} while (0)
|
||||
|
||||
static inline __attribute__((optimize(0))) void preemption(void)
|
||||
|
||||
55
mkrtos_knl/arch/cortex-m33/thread_armv8m.c
Normal file
55
mkrtos_knl/arch/cortex-m33/thread_armv8m.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file thread_armv7m.c
|
||||
* @author ATShining (135874329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "thread.h"
|
||||
#include "printk.h"
|
||||
#include "thread_armv7m.h"
|
||||
#include "app.h"
|
||||
#include "mm_wrap.h"
|
||||
#include "arch.h"
|
||||
#include "string.h"
|
||||
syscall_entry_func syscall_handler_get(void)
|
||||
{
|
||||
return syscall_entry;
|
||||
}
|
||||
void thread_knl_pf_set(thread_t *cur_th, void *pc)
|
||||
{
|
||||
pf_t *cur_pf = ((pf_t *)((char *)cur_th + THREAD_BLOCK_SIZE)) - 1;
|
||||
|
||||
cur_pf->pf_s.xpsr = 0x01000000L;
|
||||
cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数
|
||||
cur_pf->pf_s.pc = (umword_t)pc | 0x1;
|
||||
// cur_pf->rg1[5] = (umword_t)0;
|
||||
|
||||
cur_th->sp.knl_sp = (char *)cur_pf;
|
||||
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)
|
||||
{
|
||||
// assert((((umword_t)user_sp) & 0x7UL) == 0);
|
||||
umword_t usp = ((umword_t)(user_sp) & ~0x7UL);
|
||||
|
||||
|
||||
pf_t *cur_pf = (pf_t *)(usp)-1; // thread_get_pf(cur_th);
|
||||
|
||||
cur_pf->pf_s.xpsr = 0x01000000L;
|
||||
cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数
|
||||
cur_pf->pf_s.pc = (umword_t)pc | 0x1;
|
||||
cur_pf->rg1[5] = (umword_t)ram;
|
||||
|
||||
cur_th->sp.knl_sp = ((char *)cur_th + 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);
|
||||
}
|
||||
85
mkrtos_knl/arch/cortex-m4/mm_space.c
Normal file
85
mkrtos_knl/arch/cortex-m4/mm_space.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file mm_space.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "mm_space.h"
|
||||
#include "mpu.h"
|
||||
#include "assert.h"
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
void mm_space_init(mm_space_t *mm_space, int is_knl)
|
||||
{
|
||||
for (int i = 0; i < CONFIG_REGION_NUM; i++)
|
||||
{
|
||||
mm_space->pt_regions[i].region_inx = -1;
|
||||
}
|
||||
}
|
||||
region_info_t *mm_space_alloc_pt_region(mm_space_t *m_space)
|
||||
{
|
||||
for (int i = 0; i < CONFIG_REGION_NUM; i++)
|
||||
{
|
||||
/*TODO:原子操作*/
|
||||
if (m_space->pt_regions[i].region_inx < 0)
|
||||
{
|
||||
m_space->pt_regions[i].region_inx = (int16_t)i;
|
||||
return &m_space->pt_regions[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void mm_space_free_pt_region(mm_space_t *m_space, region_info_t *ri)
|
||||
{
|
||||
ri->region_inx = -1;
|
||||
}
|
||||
|
||||
bool_t mm_space_add(mm_space_t *m_space,
|
||||
umword_t addr,
|
||||
umword_t size,
|
||||
uint8_t attrs)
|
||||
{
|
||||
region_info_t *ri = mm_space_alloc_pt_region(m_space);
|
||||
|
||||
if (!ri)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#if CONFIG_MPU_VERSION == 1
|
||||
if (!is_power_of_2(size) || (addr & (!(size - 1))) != 0)
|
||||
{
|
||||
//!< 申请的大小必须是2的整数倍,而且地址也必须是2的整数倍
|
||||
mm_space_free_pt_region(m_space, ri);
|
||||
return FALSE;
|
||||
}
|
||||
#elif CONFIG_MPU_VERSION == 2
|
||||
if ((size & (MPU_ALIGN_SIZE - 1)) == 0 && (addr & (MPU_ALIGN_SIZE - 1)) == 0)
|
||||
{
|
||||
mm_space_free_pt_region(m_space, ri);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
mpu_calc_regs(ri, addr, size, attrs, 0);
|
||||
ri->start_addr = addr;
|
||||
ri->size = size;
|
||||
return TRUE;
|
||||
}
|
||||
void mm_space_del(mm_space_t *m_space, umword_t addr)
|
||||
{
|
||||
for (int i = 0; i < CONFIG_REGION_NUM; i++)
|
||||
{
|
||||
if (m_space->pt_regions[i].region_inx >= 0 &&
|
||||
m_space->pt_regions[i].start_addr == addr)
|
||||
{
|
||||
m_space->pt_regions[i].region_inx = -1;
|
||||
m_space->pt_regions[i].start_addr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
25
mkrtos_knl/arch/cortex-m4/sched_arch.c
Normal file
25
mkrtos_knl/arch/cortex-m4/sched_arch.c
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
|
||||
#include <scheduler.h>
|
||||
#include <types.h>
|
||||
#include <thread.h>
|
||||
#include <util.h>
|
||||
sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type)
|
||||
{
|
||||
scheduler_t *sche = scheduler_get_current();
|
||||
|
||||
sched_t *next = sche->cur_sche;
|
||||
thread_t *next_th = container_of(next, thread_t, sche);
|
||||
|
||||
assert(next_th->magic == THREAD_MAGIC);
|
||||
|
||||
if (sched_reset)
|
||||
{
|
||||
thread_t *cur_th = thread_get_current();
|
||||
cur_th->sp.knl_sp = ksp;
|
||||
cur_th->sp.user_sp = usp;
|
||||
cur_th->sp.sp_type = sp_type;
|
||||
}
|
||||
sched_reset = 1;
|
||||
return &next_th->sp;
|
||||
}
|
||||
@@ -12,7 +12,29 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "arch.h"
|
||||
#define LOG_INTR_NO 37//USART1_IRQn
|
||||
#define LOG_INTR_NO 37 // USART1_IRQn
|
||||
|
||||
/// @brief 线程信息
|
||||
typedef struct
|
||||
{
|
||||
umword_t rg0[4]; //!< r0-r3
|
||||
umword_t r12;
|
||||
umword_t lr;
|
||||
umword_t pc;
|
||||
umword_t xpsr;
|
||||
} pf_s_t;
|
||||
typedef struct pf
|
||||
{
|
||||
umword_t rg1[8]; //!< r4-r11
|
||||
pf_s_t pf_s;
|
||||
} pf_t;
|
||||
|
||||
typedef struct sp_info
|
||||
{
|
||||
void *user_sp; //!< 用户态的sp
|
||||
void *knl_sp; //!< 内核sp
|
||||
mword_t sp_type; //!< 使用的栈类型
|
||||
} sp_info_t;
|
||||
|
||||
#define read_reg(addr) (*((volatile umword_t *)(addr)))
|
||||
#define write_reg(addr, data) \
|
||||
@@ -43,7 +65,7 @@
|
||||
: "=r"(ret) \
|
||||
: \
|
||||
:); \
|
||||
((ret & 0x4) ? 0 : 1); \
|
||||
((ret & 0x4) ? 0 : 1); \
|
||||
})
|
||||
|
||||
void to_sche(void);
|
||||
@@ -88,17 +110,17 @@ void arch_disable_irq(int inx);
|
||||
void arch_enable_irq(int inx);
|
||||
void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio);
|
||||
|
||||
#define sti() \
|
||||
#define sti() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("CPSID I\n" :: \
|
||||
:); \
|
||||
} while (0)
|
||||
#define cli() \
|
||||
do \
|
||||
{ \
|
||||
write_sysreg(0, PRIMASK); \
|
||||
} while (0)
|
||||
|
||||
static inline void preemption(void)
|
||||
{
|
||||
|
||||
55
mkrtos_knl/arch/cortex-m4/thread_armv7m.c
Normal file
55
mkrtos_knl/arch/cortex-m4/thread_armv7m.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file thread_armv7m.c
|
||||
* @author ATShining (135874329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "thread.h"
|
||||
#include "printk.h"
|
||||
#include "thread_armv7m.h"
|
||||
#include "app.h"
|
||||
#include "mm_wrap.h"
|
||||
#include "arch.h"
|
||||
#include "string.h"
|
||||
syscall_entry_func syscall_handler_get(void)
|
||||
{
|
||||
return syscall_entry;
|
||||
}
|
||||
void thread_knl_pf_set(thread_t *cur_th, void *pc)
|
||||
{
|
||||
pf_t *cur_pf = ((pf_t *)((char *)cur_th + THREAD_BLOCK_SIZE)) - 1;
|
||||
|
||||
cur_pf->pf_s.xpsr = 0x01000000L;
|
||||
cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数
|
||||
cur_pf->pf_s.pc = (umword_t)pc | 0x1;
|
||||
// cur_pf->rg1[5] = (umword_t)0;
|
||||
|
||||
cur_th->sp.knl_sp = (char *)cur_pf;
|
||||
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)
|
||||
{
|
||||
// assert((((umword_t)user_sp) & 0x7UL) == 0);
|
||||
umword_t usp = ((umword_t)(user_sp) & ~0x7UL);
|
||||
|
||||
|
||||
pf_t *cur_pf = (pf_t *)(usp)-1; // thread_get_pf(cur_th);
|
||||
|
||||
cur_pf->pf_s.xpsr = 0x01000000L;
|
||||
cur_pf->pf_s.lr = (umword_t)NULL; //!< 线程退出时调用的函数
|
||||
cur_pf->pf_s.pc = (umword_t)pc | 0x1;
|
||||
cur_pf->rg1[5] = (umword_t)ram;
|
||||
|
||||
cur_th->sp.knl_sp = ((char *)cur_th + 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);
|
||||
}
|
||||
@@ -6,14 +6,17 @@ static umword_t sys_tick_cnt;
|
||||
|
||||
umword_t sys_tick_cnt_get(void)
|
||||
{
|
||||
return 0;
|
||||
return sys_tick_cnt;
|
||||
}
|
||||
#include <asm/arm_local_reg.h>
|
||||
|
||||
extern void handle_timer_irq(void);
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
handle_timer_irq(); // TODO:定时器的处理应该被分流,这里处理还有点问题,而且最好采用通用定时器
|
||||
// 进行上下文切换
|
||||
thread_sched();
|
||||
sys_tick_cnt++;
|
||||
thread_timeout_check(1);
|
||||
futex_timeout_times_tick();
|
||||
thread_sched();
|
||||
}
|
||||
|
||||
4
mkrtos_knl/inc/knl/knl_test.h
Normal file
4
mkrtos_knl/inc/knl/knl_test.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
void knl_test(void);
|
||||
@@ -1,4 +1,3 @@
|
||||
#pragma once
|
||||
#include "mm_page.h"
|
||||
void mm_man_dump(void);
|
||||
void *mm_page_alloc_fault(mm_pages_t *mm, addr_t addr);
|
||||
void mm_man_dump(void);
|
||||
@@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include "ram_limit.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef addr_t mm_addr_t;
|
||||
struct region_info;
|
||||
typedef struct region_info region_info_t;
|
||||
|
||||
// 使用一个mpu区域模拟页表
|
||||
// 该文件实现内存的管理
|
||||
typedef struct mm_entry
|
||||
{
|
||||
mm_addr_t addr; //!< 页表的地址
|
||||
uint16_t pfn_nr; //!< 多少页
|
||||
uint8_t attrs; //!< 属性
|
||||
} mm_entry_t;
|
||||
|
||||
static inline void mm_entry_set_first(mm_addr_t *addr)
|
||||
{
|
||||
*addr |= 1UL;
|
||||
}
|
||||
static inline bool_t mm_entry_get_first(mm_addr_t addr)
|
||||
{
|
||||
return addr & 0x1UL;
|
||||
}
|
||||
static inline addr_t mm_entry_get_addr(mm_addr_t addr)
|
||||
{
|
||||
return MASK_LSB(addr, 2);
|
||||
}
|
||||
static inline void mm_entry_set_addr(mm_addr_t *addr, addr_t new_addr)
|
||||
{
|
||||
*addr &= ~3UL;
|
||||
*addr |= new_addr & (~3UL);
|
||||
}
|
||||
|
||||
#define PAGE_NR 64
|
||||
#define PAGE_SIZE (1 << CONFIG_PAGE_SHIFT)
|
||||
|
||||
typedef struct mm_pages
|
||||
{
|
||||
mm_entry_t list[PAGE_NR]; // TODO: 使用hashmap
|
||||
region_info_t *region; //!< pages使用的mpu region
|
||||
} mm_pages_t;
|
||||
|
||||
void mm_pages_init(mm_pages_t *mm, region_info_t *regi);
|
||||
int mm_pages_alloc_page(mm_pages_t *mm, ram_limit_t *lim, size_t pnf_nr, addr_t *alloc_addr, uint8_t attrs);
|
||||
void mm_pages_free_page(mm_pages_t *mm, ram_limit_t *lim, addr_t addr, size_t pfn_nr);
|
||||
@@ -3,7 +3,11 @@
|
||||
#include "types.h"
|
||||
#include "mm_page.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <util.h>
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
#include <early_boot.h>
|
||||
#endif
|
||||
#if !IS_ENABLED(CONFIG_MMU)
|
||||
typedef struct region_info
|
||||
{
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
@@ -17,16 +21,24 @@ typedef struct region_info
|
||||
uint8_t region; //!< 区域禁止信息
|
||||
#endif
|
||||
} region_info_t;
|
||||
|
||||
#endif
|
||||
typedef struct mm_space
|
||||
{
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
region_info_t pt_regions[CONFIG_REGION_NUM]; //!< mpu内存保护块
|
||||
#endif
|
||||
// mm_pages_t mm_pages; //!< 模拟分页内存
|
||||
#if IS_ENABLED(CONFIG_MMU)
|
||||
page_entry_t mem_dir; //!< MMU根映射表,存放映射信息
|
||||
#endif
|
||||
void *mm_block; //!< task 的私有内存块
|
||||
size_t mm_block_size; //!< 私有内存块的大小
|
||||
} mm_space_t;
|
||||
|
||||
static inline page_entry_t *mm_space_get_pdir(mm_space_t *sp)
|
||||
{
|
||||
return &sp->mem_dir;
|
||||
}
|
||||
|
||||
enum region_rights
|
||||
{
|
||||
REGION_PRIV = 1,
|
||||
@@ -42,6 +54,7 @@ void mm_space_init(mm_space_t *mm_space, int is_knl);
|
||||
bool_t mm_space_add(mm_space_t *m_space, umword_t addr, umword_t size, uint8_t attrs);
|
||||
void mm_space_del(mm_space_t *m_space, umword_t addr);
|
||||
#else
|
||||
#if !IS_ENABLED(CONFIG_MMU)
|
||||
static inline void mm_space_init(mm_space_t *mm_space, int is_knl)
|
||||
{
|
||||
}
|
||||
@@ -52,8 +65,14 @@ static inline bool_t mm_space_add(mm_space_t *m_space, umword_t addr, umword_t s
|
||||
static inline void mm_space_del(mm_space_t *m_space, umword_t addr)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
void mm_space_init(mm_space_t *mm_space, int is_knl);
|
||||
bool_t mm_space_add(mm_space_t *m_space, umword_t addr, umword_t size, uint8_t attrs);
|
||||
void mm_space_del(mm_space_t *m_space, umword_t addr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !IS_ENABLED(CONFIG_MMU)
|
||||
static inline void mm_space_set_ram_block(mm_space_t *mm_space, void *mem, size_t size)
|
||||
{
|
||||
mm_space->mm_block = mem;
|
||||
@@ -66,3 +85,11 @@ static inline void mm_space_get_ram_block(mm_space_t *mm_space, void **mem, size
|
||||
*mem = mm_space->mm_block;
|
||||
*size = mm_space->mm_block_size;
|
||||
}
|
||||
#else
|
||||
static inline void mm_space_set_ram_block(mm_space_t *mm_space, void *mem, size_t size)
|
||||
{
|
||||
}
|
||||
static inline void mm_space_get_ram_block(mm_space_t *mm_space, void **mem, size_t *size)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@ void mpu_calc_regs(region_info_t *region, umword_t addr, umword_t ffs_val,
|
||||
void mpu_switch_to(void);
|
||||
void mpu_switch_to_task(struct task *tk);
|
||||
#else
|
||||
#if !IS_ENABLED(CONFIG_MMU)
|
||||
static inline void mpu_init(void)
|
||||
{
|
||||
}
|
||||
@@ -43,4 +44,9 @@ static inline void mpu_switch_to(void)
|
||||
static inline void mpu_switch_to_task(struct task *tk)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static inline void mpu_switch_to_task(struct task *tk)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "slist.h"
|
||||
|
||||
#define PRIO_MAX WORD_BITS
|
||||
|
||||
extern umword_t sched_reset;
|
||||
typedef struct sched
|
||||
{
|
||||
int prio;
|
||||
|
||||
@@ -89,26 +89,7 @@ enum thread_ipc_state
|
||||
THREAD_TIMEOUT,
|
||||
THREAD_IPC_ABORT,
|
||||
};
|
||||
typedef struct
|
||||
{
|
||||
umword_t rg0[4]; //!< r0-r3
|
||||
umword_t r12;
|
||||
umword_t lr;
|
||||
umword_t pc;
|
||||
umword_t xpsr;
|
||||
} pf_s_t;
|
||||
typedef struct pf
|
||||
{
|
||||
umword_t rg1[8]; //!< r4-r11
|
||||
pf_s_t pf_s;
|
||||
} pf_t;
|
||||
|
||||
typedef struct sp_info
|
||||
{
|
||||
void *user_sp; //!< 用户态的sp
|
||||
void *knl_sp; //!< 内核sp
|
||||
mword_t sp_type; //!< 使用的栈类型
|
||||
} sp_info_t;
|
||||
|
||||
typedef struct msg_buf
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void thread_exit(void);
|
||||
void thread_knl_pf_set(thread_t *cur_th, void *pc);
|
||||
void thread_user_pf_set(thread_t *cur_th, void *pc, void *user_sp, void *ram, umword_t stack);
|
||||
void task_knl_init(task_t *knl_tk);
|
||||
@@ -20,7 +20,7 @@ umword_t cpulock_lock(void)
|
||||
umword_t res;
|
||||
|
||||
res = intr_status();
|
||||
sti();
|
||||
cli();
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
@@ -44,10 +44,10 @@ void cpulock_set(umword_t s)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
sti();
|
||||
cli();
|
||||
}
|
||||
else
|
||||
{
|
||||
cli();
|
||||
sti();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,10 @@ void entry_handler(void)
|
||||
{
|
||||
umword_t isr_no = arch_get_isr_no();
|
||||
|
||||
if (isr_no <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
isr_no -= CONFIG_USER_ISR_START_NO; //!< 系统用的irq偏移
|
||||
|
||||
assert(isr_no < CONFIG_IRQ_REG_TAB_SIZE);
|
||||
@@ -93,7 +97,9 @@ void entry_handler(void)
|
||||
{
|
||||
irqs[isr_no].irq_tigger_func(&irqs[isr_no]);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
arch_disable_irq(isr_no);
|
||||
}
|
||||
}
|
||||
|
||||
56
mkrtos_knl/knl/knl_test.c
Normal file
56
mkrtos_knl/knl/knl_test.c
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
#include <task.h>
|
||||
#include <thread.h>
|
||||
#include <factory.h>
|
||||
#include <thread_task_arch.h>
|
||||
static void th_test(void *arg)
|
||||
{
|
||||
int a[20];
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
a[i] = i;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
printk("%d ", a[i]);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
}
|
||||
static void th_test2(void *arg)
|
||||
{
|
||||
int a[20];
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
a[i] = i;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
printk("%d,", a[i]);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
}
|
||||
void knl_test(void)
|
||||
{
|
||||
thread_t *thread2;
|
||||
task_t *cur_tk = thread_get_current_task();
|
||||
|
||||
thread2 = thread_create(&root_factory_get()->limit);
|
||||
assert(thread2);
|
||||
thread_bind(thread2, &cur_tk->kobj);
|
||||
thread_knl_pf_set(thread2, th_test);
|
||||
thread_ready(thread2, FALSE);
|
||||
|
||||
thread_t *thread3;
|
||||
|
||||
thread3 = thread_create(&root_factory_get()->limit);
|
||||
assert(thread3);
|
||||
thread_bind(thread3, &cur_tk->kobj);
|
||||
thread_knl_pf_set(thread3, th_test2);
|
||||
thread_ready(thread3, FALSE);
|
||||
}
|
||||
@@ -13,10 +13,10 @@
|
||||
#include "mm.h"
|
||||
#include "mm_space.h"
|
||||
#include "util.h"
|
||||
#include "mpu.h"
|
||||
#include "printk.h"
|
||||
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
#include "mpu.h"
|
||||
static bool_t mpu_calc(
|
||||
mm_space_t *ms,
|
||||
umword_t mem_start_addr,
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @file mm_page.c
|
||||
* @author ATShining (1358745329@qq.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2023-09-29
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "mm_space.h"
|
||||
#include "mm_wrap.h"
|
||||
#include "assert.h"
|
||||
#include "err.h"
|
||||
#include "mm_page.h"
|
||||
#include "mm_space.h"
|
||||
#include "mpu.h"
|
||||
#if CONFIG_MK_MPU_CFG
|
||||
static mm_entry_t *mm_pages_entry_alloc(mm_pages_t *mm, addr_t new_addr)
|
||||
{
|
||||
for (int i = 0; i < PAGE_NR; i++)
|
||||
{
|
||||
if (mm->list[i].addr == 0)
|
||||
{
|
||||
mm_entry_set_addr(&mm->list[i].addr, new_addr);
|
||||
return &mm->list[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void mm_pages_entry_free(mm_pages_t *mm, addr_t free_addr)
|
||||
{
|
||||
for (int i = 0; i < PAGE_NR; i++)
|
||||
{
|
||||
if (mm_entry_get_addr(mm->list[i].addr) == free_addr)
|
||||
{
|
||||
mm->list[i].addr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
static mm_entry_t *mm_pages_find_first(mm_pages_t *mm, addr_t free_addr)
|
||||
{
|
||||
for (int i = 0; i < PAGE_NR; i++)
|
||||
{
|
||||
if (mm_entry_get_addr(mm->list[i].addr) == free_addr && mm_entry_get_first(mm->list[i].addr))
|
||||
{
|
||||
return &mm->list[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void mm_pages_init(mm_pages_t *mm, region_info_t *regi)
|
||||
{
|
||||
for (int i = 0; i < PAGE_NR; i++)
|
||||
{
|
||||
mm->list[i].addr = 0;
|
||||
}
|
||||
mm->region = regi;
|
||||
}
|
||||
int mm_pages_alloc_page(mm_pages_t *mm, ram_limit_t *lim, size_t pnf_nr, addr_t *alloc_addr, uint8_t attrs)
|
||||
{
|
||||
assert(mm);
|
||||
assert(alloc_addr);
|
||||
|
||||
void *mem = mm_limit_alloc_align(lim, pnf_nr * PAGE_SIZE, PAGE_SIZE);
|
||||
if (!mem)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (int i = 0; i < pnf_nr; i++)
|
||||
{
|
||||
mm_entry_t *mm_entry = mm_pages_entry_alloc(mm, (addr_t)mem + i * PAGE_SIZE);
|
||||
if (mm_entry == NULL)
|
||||
{
|
||||
mm_limit_free_align(lim, mem, pnf_nr * PAGE_SIZE);
|
||||
/*TODO:清除申请的所有*/
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
mm_entry_set_first(&mm_entry->addr);
|
||||
mm_entry->attrs = attrs;
|
||||
mm_entry->pfn_nr = pnf_nr;
|
||||
}
|
||||
else
|
||||
{
|
||||
mm_entry->attrs = attrs;
|
||||
mm_entry->pfn_nr = 1;
|
||||
}
|
||||
}
|
||||
*alloc_addr = (addr_t)mem;
|
||||
return 0;
|
||||
}
|
||||
void mm_pages_free_page(mm_pages_t *mm, ram_limit_t *lim, addr_t addr, size_t pfn_nr)
|
||||
{
|
||||
addr = ALIGN_DOWN(addr, PAGE_SIZE);
|
||||
mm_entry_t *mm_entry = mm_pages_find_first(mm, addr);
|
||||
|
||||
if (!mm_entry)
|
||||
{
|
||||
return;
|
||||
}
|
||||
addr_t start_addr = mm_entry_get_addr(mm_entry->addr);
|
||||
|
||||
mm_limit_free_align(lim, (void *)start_addr, PAGE_SIZE * mm_entry->pfn_nr);
|
||||
for (int i = 0; i < pfn_nr; i++)
|
||||
{
|
||||
mm_pages_entry_free(mm, start_addr);
|
||||
start_addr += PAGE_SIZE;
|
||||
}
|
||||
mpu_region_clr(mm->region->region_inx);
|
||||
}
|
||||
|
||||
void *mm_page_alloc_fault(mm_pages_t *mm, addr_t addr)
|
||||
{
|
||||
addr = ALIGN_DOWN(addr, PAGE_SIZE);
|
||||
for (int i = 0; i < PAGE_NR; i++)
|
||||
{
|
||||
if (mm_entry_get_addr(mm->list[i].addr) == addr)
|
||||
{
|
||||
mpu_calc_regs(mm->region, addr, PAGE_SIZE,
|
||||
mm->list[i].attrs, 0x0);
|
||||
mpu_region_set(mm->region->region_inx, mm->region->rbar,
|
||||
mm->region->rasr);
|
||||
return (void *)(mm->list[i].addr);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "assert.h"
|
||||
#include "thread.h"
|
||||
#include "init.h"
|
||||
#include <arch.h>
|
||||
static scheduler_t scheduler;
|
||||
umword_t sched_reset = 0;
|
||||
|
||||
@@ -111,26 +112,7 @@ sched_t *scheduler_next(void)
|
||||
return next_sch;
|
||||
}
|
||||
|
||||
sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type)
|
||||
{
|
||||
scheduler_t *sche = scheduler_get_current();
|
||||
|
||||
sched_t *next = sche->cur_sche;
|
||||
thread_t *next_th = container_of(next, thread_t, sche);
|
||||
|
||||
assert(next_th->magic == THREAD_MAGIC);
|
||||
|
||||
if (sched_reset)
|
||||
{
|
||||
thread_t *cur_th = thread_get_current();
|
||||
cur_th->sp.knl_sp = ksp;
|
||||
cur_th->sp.user_sp = usp;
|
||||
cur_th->sp.sp_type = sp_type;
|
||||
}
|
||||
sched_reset = 1;
|
||||
return &next_th->sp;
|
||||
}
|
||||
void sched_tail(void)
|
||||
{
|
||||
/*TODO:*/
|
||||
sti();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
#include "assert.h"
|
||||
#include "access.h"
|
||||
#include "printk.h"
|
||||
#if IS_ENABLED(CONFIG_MMU)
|
||||
#include "early_boot.h"
|
||||
#endif
|
||||
/**
|
||||
* @brief 任务的操作码
|
||||
*
|
||||
@@ -334,7 +337,12 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl)
|
||||
task->kobj.put_func = task_put;
|
||||
task->kobj.stage_1_func = task_release_stage1;
|
||||
task->kobj.stage_2_func = task_release_stage2;
|
||||
|
||||
#if IS_ENABLED(CONFIG_MMU)
|
||||
knl_pdir_init(&task->mm_space.mem_dir, task->mm_space.mem_dir.dir, 3);
|
||||
#else
|
||||
mm_space_add(&task->mm_space, CONFIG_KNL_TEXT_ADDR, CONFIG_KNL_TEXT_SIZE, REGION_RO); // TODO:这里应该用config.配置
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool_t task_put(kobject_t *kobj)
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
#include "task.h"
|
||||
#include "thread.h"
|
||||
#include "slist.h"
|
||||
#include "thread_armv7m.h"
|
||||
#include "thread_task_arch.h"
|
||||
#include "assert.h"
|
||||
#include "err.h"
|
||||
#include "map.h"
|
||||
#include "access.h"
|
||||
#include "ipc.h"
|
||||
#include "asm/mm.h"
|
||||
enum thread_op
|
||||
{
|
||||
SET_EXEC_REGS,
|
||||
|
||||
@@ -20,9 +20,13 @@
|
||||
#include "map.h"
|
||||
#include "app.h"
|
||||
#include "mm_wrap.h"
|
||||
#include "thread_armv7m.h"
|
||||
#include "thread_task_arch.h"
|
||||
#include "knl_misc.h"
|
||||
|
||||
#if IS_ENABLED(CONFIG_KNL_TEST)
|
||||
#include <knl_test.h>
|
||||
#endif
|
||||
|
||||
static uint8_t knl_msg_buf[THREAD_MSG_BUG_LEN];
|
||||
static thread_t *knl_thread;
|
||||
static task_t knl_task;
|
||||
@@ -36,7 +40,7 @@ static void knl_main(void)
|
||||
{
|
||||
umword_t status;
|
||||
umword_t status2;
|
||||
// printk("knl main run..\n");
|
||||
printk("knl main run..\n");
|
||||
while (1)
|
||||
{
|
||||
task_t *pos;
|
||||
@@ -87,7 +91,7 @@ static void knl_init_1(void)
|
||||
|
||||
thread_init(knl_thread, &root_factory_get()->limit);
|
||||
task_init(&knl_task, &root_factory_get()->limit, TRUE);
|
||||
|
||||
task_knl_init(&knl_task);
|
||||
thread_knl_pf_set(knl_thread, knl_main);
|
||||
thread_bind(knl_thread, &knl_task.kobj);
|
||||
thread_set_msg_bug(knl_thread, knl_msg_buf);
|
||||
@@ -97,6 +101,7 @@ static void knl_init_1(void)
|
||||
}
|
||||
INIT_STAGE1(knl_init_1);
|
||||
|
||||
|
||||
/**
|
||||
* 初始化init线程
|
||||
* 初始化用户态任务
|
||||
@@ -107,12 +112,13 @@ static void knl_init_2(void)
|
||||
{
|
||||
mm_trace();
|
||||
|
||||
#if IS_ENABLED(CONFIG_KNL_TEST)
|
||||
knl_test();
|
||||
#else
|
||||
init_thread = thread_create(&root_factory_get()->limit);
|
||||
assert(init_thread);
|
||||
init_task = task_create(&root_factory_get()->limit, FALSE);
|
||||
assert(init_task);
|
||||
|
||||
#if 0
|
||||
app_info_t *app = app_info_get((void *)(CONFIG_KNL_TEXT_ADDR + CONFIG_INIT_TASK_OFFSET));
|
||||
// 申请init的ram内存
|
||||
assert(task_alloc_base_ram(init_task, &root_factory_get()->limit, app->i.ram_size + THREAD_MSG_BUG_LEN) >= 0);
|
||||
@@ -195,5 +201,4 @@ void start_kernel(void)
|
||||
|
||||
while (1)
|
||||
;
|
||||
// printk(".");
|
||||
}
|
||||
|
||||
10
mkrtos_script/run_aarch64_qemu.sh
Executable file
10
mkrtos_script/run_aarch64_qemu.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -machine virt,virtualization=on,gic-version=2,highmem=off,secure=off,dumpdtb=virt.dtb
|
||||
qemu-system-aarch64 \
|
||||
-machine virt,virtualization=on,gic-version=2,highmem=off,secure=off\
|
||||
-cpu cortex-a53 \
|
||||
-nographic \
|
||||
-m size=2048 \
|
||||
-smp 4\
|
||||
-kernel $PWD/build/output/bootstrap.elf
|
||||
Reference in New Issue
Block a user