From dc144a5cf44a90d5608142c8ff512fde638ecaf2 Mon Sep 17 00:00:00 2001 From: Chen Peng Date: Wed, 27 May 2026 23:30:31 +0800 Subject: [PATCH] =?UTF-8?q?PORT=E6=8C=89CPU=E5=9E=8B=E5=8F=B7=E6=9B=B4?= =?UTF-8?q?=E7=AE=80=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPU/CH32V10x/cpu.c | 1 + CPU/CH32V10x/cpu.h | 47 ++ CPU/{QingKeV3 => CH32V10x}/os_loopdelay.c | 0 CPU/{QingKeV3 => CH32V10x}/os_loopdelay.h | 0 CPU/CH32V10x/os_port.c | 226 +++++ CPU/CH32V10x/os_port_gnu.S | 321 +++++++ CPU/QingKeV3/os_port_gnu.S | 176 ---- CPU/QingKeV3/qkv3.c | 1 - CPU/QingKeV3/qkv3.h | 224 ----- CPU/QingKeV3/riscv.c | 287 ------- CPU/QingKeV3/riscv.h | 240 ------ CPU/QingKeV3FV5F/cpu.c | 1 + CPU/QingKeV3FV5F/cpu.h | 10 + CPU/QingKeV3FV5F/os_loopdelay.c | 10 + CPU/QingKeV3FV5F/os_loopdelay.h | 34 + CPU/{QingKeV3 => QingKeV3FV5F}/os_port.c | 32 +- CPU/QingKeV3FV5F/riscv.c | 816 ++++++++++++++++++ CPU/QingKeV3FV5F/riscv.h | 970 ++++++++++++++++++++++ CPU/QingKeV5/cpu.c | 1 + CPU/QingKeV5/cpu.h | 6 + Kernel/SingleCore/cpu_clz.c | 1 + Kernel/SingleCore/os_config.h.in | 16 +- Kernel/SingleCore/os_port.h | 37 +- Kernel/SingleCore/os_task.h | 15 + 24 files changed, 2519 insertions(+), 953 deletions(-) create mode 100644 CPU/CH32V10x/cpu.c create mode 100644 CPU/CH32V10x/cpu.h rename CPU/{QingKeV3 => CH32V10x}/os_loopdelay.c (100%) rename CPU/{QingKeV3 => CH32V10x}/os_loopdelay.h (100%) create mode 100644 CPU/CH32V10x/os_port.c create mode 100644 CPU/CH32V10x/os_port_gnu.S delete mode 100644 CPU/QingKeV3/os_port_gnu.S delete mode 100644 CPU/QingKeV3/qkv3.c delete mode 100644 CPU/QingKeV3/qkv3.h delete mode 100644 CPU/QingKeV3/riscv.c delete mode 100644 CPU/QingKeV3/riscv.h create mode 100644 CPU/QingKeV3FV5F/cpu.c create mode 100644 CPU/QingKeV3FV5F/cpu.h create mode 100644 CPU/QingKeV3FV5F/os_loopdelay.c create mode 100644 CPU/QingKeV3FV5F/os_loopdelay.h rename CPU/{QingKeV3 => QingKeV3FV5F}/os_port.c (87%) create mode 100644 CPU/QingKeV3FV5F/riscv.c create mode 100644 CPU/QingKeV3FV5F/riscv.h create mode 100644 CPU/QingKeV5/cpu.c create mode 100644 CPU/QingKeV5/cpu.h diff --git a/CPU/CH32V10x/cpu.c b/CPU/CH32V10x/cpu.c new file mode 100644 index 0000000..942f6ed --- /dev/null +++ b/CPU/CH32V10x/cpu.c @@ -0,0 +1 @@ +#include diff --git a/CPU/CH32V10x/cpu.h b/CPU/CH32V10x/cpu.h new file mode 100644 index 0000000..5038e2b --- /dev/null +++ b/CPU/CH32V10x/cpu.h @@ -0,0 +1,47 @@ +#ifndef INCLUDED_CPU_H +#define INCLUDED_CPU_H + +#ifndef INCLUDED_CH32V10X_H +#define INCLUDED_CH32V10X_H +#include +#endif /*INCLUDED_CH32V10X_H*/ + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#ifndef INCLUDED_OS_COMPILER_H +#include +#endif /*INCLUDED_OS_COMPILER_H*/ + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +#define CPU_KEY1 0xFA05 +#define CPU_KEY2 0xBCAF +#define CPU_KEY3 0xBEEF + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + + +OS_STATIC_FORCE_INLINE +os_uint_t cpu_save_disable_irq_in_isr(void){ + os_uint_t result; + __asm volatile ("csrrw %0, mstatus, %1":"=r"(result):"r"(0x1800):"memory"); + return result; +} + +OS_STATIC_FORCE_INLINE +void cpu_restore_irq_in_isr(os_uint_t value){ + __set_MSTATUS(value); +} + +#define os_port_disable_irq __disable_irq +#define os_port_enable_irq __enable_irq +#define os_port_save_disable_irq_in_isr cpu_save_disable_irq_in_isr +#define os_port_restore_irq_in_isr cpu_restore_irq_in_isr +#define os_port_save_disable_irq cpu_save_disable_irq_in_isr +#define os_port_restore_irq cpu_restore_irq_in_isr + +#endif /*INCLUDED_CPU_H*/ diff --git a/CPU/QingKeV3/os_loopdelay.c b/CPU/CH32V10x/os_loopdelay.c similarity index 100% rename from CPU/QingKeV3/os_loopdelay.c rename to CPU/CH32V10x/os_loopdelay.c diff --git a/CPU/QingKeV3/os_loopdelay.h b/CPU/CH32V10x/os_loopdelay.h similarity index 100% rename from CPU/QingKeV3/os_loopdelay.h rename to CPU/CH32V10x/os_loopdelay.h diff --git a/CPU/CH32V10x/os_port.c b/CPU/CH32V10x/os_port.c new file mode 100644 index 0000000..8933664 --- /dev/null +++ b/CPU/CH32V10x/os_port.c @@ -0,0 +1,226 @@ +#include "os_port.h" +#include "os_stack.h" +#include "os_macros.h" +#include "os_align.h" +#include "os_compiler.h" +#include "os_systick.h" +#include "os_sched.h" +#include "os_isr.h" +#include "cpu.h" + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +OS_STATIC_FORCE_INLINE +uint32_t _SysTick_Config(os_tick_t ticks) +{ + + + NVIC->CFGR = (CPU_KEY1<<16) | (1<<1/*NESTCTRL*/) | (1<<0/*HWSTKCTRL*/); /* 关闭硬件压栈和嵌套 */ + + NVIC_SetPriority(SysTick_IRQn,0xf0); + NVIC_SetPriority(Software_IRQn,0xf0); + + SysTick->CTLR=0; + SysTick->CNTL0=0;SysTick->CNTL1=0;SysTick->CNTL2=0;SysTick->CNTL3=0; + SysTick->CNTH0=0;SysTick->CNTH1=0;SysTick->CNTH2=0;SysTick->CNTH3=0; + SysTick->CMPLR0=(uint8_t)(ticks-1); + SysTick->CMPLR1=(uint8_t)((ticks-1)>>8); + SysTick->CMPLR2=(uint8_t)((ticks-1)>>16); + SysTick->CMPLR3=(uint8_t)((ticks-1)>>24); + SysTick->CMPHR0=0;SysTick->CMPHR1=0;SysTick->CMPHR2=0;SysTick->CMPHR3=0; + SysTick->CTLR=0x1; + + NVIC_EnableIRQ(SysTick_IRQn); + NVIC_EnableIRQ(Software_IRQn); + return 0; +} + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +typedef struct { +#if (OS_CFG_CPU_FPU_PRESENT) + os_uintptr_t f0; + os_uintptr_t f1; + os_uintptr_t f2; + os_uintptr_t f3; + os_uintptr_t f4; + os_uintptr_t f5; + os_uintptr_t f6; + os_uintptr_t f7; + os_uintptr_t f8; + os_uintptr_t f9; + os_uintptr_t f10; + os_uintptr_t f11; + os_uintptr_t f12; + os_uintptr_t f13; + os_uintptr_t f14; + os_uintptr_t f15; + os_uintptr_t f16; + os_uintptr_t f17; + os_uintptr_t f18; + os_uintptr_t f19; + os_uintptr_t f20; + os_uintptr_t f21; + os_uintptr_t f22; + os_uintptr_t f23; + os_uintptr_t f24; + os_uintptr_t f25; + os_uintptr_t f26; + os_uintptr_t f27; + os_uintptr_t f28; + os_uintptr_t f29; + os_uintptr_t f30; + os_uintptr_t f31; +#endif + os_uintptr_t mstatus; /* zero, 用于 mstatus 保存 */ + os_uintptr_t ra; /* 返回地址 */ + os_uintptr_t mepc; /* 栈指针, mepc */ + os_uintptr_t x3; /* 全局指针 */ + os_uintptr_t x4; /* 线程指针 */ + os_uintptr_t x5; /* 临时寄存器0 */ + os_uintptr_t x6; /* 临时寄存器1 */ + os_uintptr_t x7; /* 临时寄存器2 */ + os_uintptr_t x8; /* s0/fp */ + os_uintptr_t x9; /* 保存寄存器1 */ + os_uintptr_t a0; /* 函数参数/返回值 */ + os_uintptr_t x11; /* 函数参数 */ + os_uintptr_t x12; /* 函数参数 */ + os_uintptr_t x13; /* 函数参数 */ + os_uintptr_t x14; /* 函数参数 */ + os_uintptr_t x15; /* 函数参数 */ + os_uintptr_t x16; /* 函数参数 */ + os_uintptr_t x17; /* 函数参数 */ + os_uintptr_t x18; /* 保存寄存器 */ + os_uintptr_t x19; /* 保存寄存器 */ + os_uintptr_t x20; /* 保存寄存器 */ + os_uintptr_t x21; /* 保存寄存器 */ + os_uintptr_t x22; /* 保存寄存器 */ + os_uintptr_t x23; /* 保存寄存器 */ + os_uintptr_t x24; /* 保存寄存器 */ + os_uintptr_t x25; /* 保存寄存器 */ + os_uintptr_t x26; /* 保存寄存器 */ + os_uintptr_t x27; /* 保存寄存器 */ + os_uintptr_t x28; /* 临时寄存器 */ + os_uintptr_t x29; /* 临时寄存器 */ + os_uintptr_t x30; /* 临时寄存器 */ + os_uintptr_t x31; /* 临时寄存器 */ +}os_stack_frame_t; + +#define STACK_FRAME_SIZE sizeof(os_stack_frame_t) +#define MSTATUS_MPIE (1<<7) + +os_stack_t os_port_cpu_stack_init(os_task_entry_t entry, void* param + , void* stack_base, os_size_t stack_size, void(*exit_entry)(void)){ + os_uintptr_t stack_max = (os_uintptr_t)((uint8_t *) stack_base + stack_size); + os_uintptr_t real_max = OS_ALIGN_DOWN(stack_max, OS_ALIGN_SIZE); /* 实际栈顶的位置,对齐后的位置 */ + stack_size -= (stack_max - real_max); /* 实际栈大小 */ + + os_stack_frame_t* p_frame = (os_stack_frame_t*)(real_max - STACK_FRAME_SIZE); + for(os_size_t i=0; imstatus = MSTATUS_MPIE; + p_frame->mepc = (os_uintptr_t)entry; + p_frame->a0 = (os_uintptr_t)param; + p_frame->ra = (os_uintptr_t)exit_entry; + + os_stack_t stack; + stack.min = (os_uintptr_t)stack_base; + stack.max = (os_uintptr_t)real_max; + stack.type = kOsStackType_MaxToMin; + stack.sp = p_frame; + return stack; +} + +//void os_port_disable_irq(void){ +// RISCV_disable_irq(); +//} +// +//void os_port_enable_irq(void){ +// RISCV_enable_irq(); +//} +// +//os_uint_t os_port_save_disable_irq(void){ +// return os_port_save_disable_irq_in_isr(); +//} +// +//void os_port_restore_irq(os_uint_t level){ +// os_port_restore_irq_in_isr(level); +//} + +//os_uint_t os_port_save_disable_irq_in_isr(void){ +// return RISCV_get_set_MSTATUS(0x1800); +//} + +//void os_port_restore_irq_in_isr(os_uint_t level){ +// RISCV_set_MSTATUS(level); +//} + +void os_sched(void){ + os_sched_in_isr(); +} + + +OS_WEAK +void os_port_init(void){ + +} + +OS_WEAK +void os_port_startup(void){ + _SysTick_Config(SystemCoreClock/8/OS_CFG_TICKS_PER_SECOND); +} + +/* + * 发出上下文切换的请求 + */ +void os_port_send_context_switch_request(void){ + NVIC_SetPendingIRQ(Software_IRQn); +} + +/* + * 清除上下文切换的请求 + */ +void os_port_clear_context_switch_request(void){ + NVIC_ClearPendingIRQ(Software_IRQn); +} + +extern void os_port_context_switch_to(os_uintptr_t to); + +OS_USED +void os_port_context_switch(void* from_sp, void* to_sp){ + os_critical_enter_in_isr(); + if(g_os_port_context_switch_flag==OS_TRUE){ + os_critical_leave_in_isr(); + return; + } + g_os_port_switch_from_sp = from_sp; + g_os_port_switch_to_sp = to_sp; + g_os_port_context_switch_flag = OS_TRUE; + os_critical_leave_in_isr(); + if(from_sp==0){ + os_port_context_switch_to((os_uintptr_t)to_sp); + }else{ + os_port_send_context_switch_request(); + } +} + + +void SysTick_Handler(void) __attribute__((interrupt())); +void SysTick_Handler(void){ + SysTick->CTLR=0; + SysTick->CNTL0=0;SysTick->CNTL1=0;SysTick->CNTL2=0;SysTick->CNTL3=0; + SysTick->CNTH0=0;SysTick->CNTH1=0;SysTick->CNTH2=0;SysTick->CNTH3=0; + SysTick->CTLR=0x1; + + // 调用系统心跳处理 + os_systick_tick(); +} + diff --git a/CPU/CH32V10x/os_port_gnu.S b/CPU/CH32V10x/os_port_gnu.S new file mode 100644 index 0000000..ef9e141 --- /dev/null +++ b/CPU/CH32V10x/os_port_gnu.S @@ -0,0 +1,321 @@ +#include "os_config.h" + +#if __riscv_xlen == 64 + #define REG_BYTES 8 + #define STORE sd + #define LOAD ld + #define FSTORE fsd + #define FLOAD fld +#elif __riscv_xlen == 32 + #define REG_BYTES 4 + #define STORE sw + #define LOAD lw + #define FSTORE fsw + #define FLOAD flw +#else + #error Assembler did not define __riscv_xlen +#endif + +#define CONTEXT_SIZE (32 * REG_BYTES) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//// CODE + +#ifdef OS_CFG_CPU_CLZ_ASM_PRESENT +.section .text.cpu_clz,"ax",%progbits +.align 8 +.func +.global cpu_clz +cpu_clz: + clz a0, a0 + ret + .endfunc +#endif + +.section .text.os_port_context_switch_to,"ax",%progbits +.align 8 +.func +.global os_port_context_switch_to +.extern os_port_on_switch_success +os_port_context_switch_to: + /* machine mode, disable ISR */ + li t0, 0x1800 + csrw mstatus, t0 + + /* first save interrupt stack */ + la t0, _eusrstack + addi t0, t0, -512 + csrw mscratch,t0 + + /* restore sp */ + LOAD sp, (a0) + + csrrw sp, mscratch, sp + jal os_port_on_switch_success + csrrw sp, mscratch, sp + + /* restore mstatus.MPIE */ + LOAD a0, 0*REG_BYTES(sp) + csrs mstatus, a0 + + /* restore mepc */ + LOAD a0, 2 * REG_BYTES(sp) + csrw mepc, a0 + + /* return address */ + LOAD x1, 1 * REG_BYTES(sp) + LOAD x4, 4 * REG_BYTES(sp) + LOAD x5, 5 * REG_BYTES(sp) + LOAD x6, 6 * REG_BYTES(sp) + LOAD x7, 7 * REG_BYTES(sp) + LOAD x8, 8 * REG_BYTES(sp) + LOAD x9, 9 * REG_BYTES(sp) + LOAD x10, 10 * REG_BYTES(sp) + LOAD x11, 11 * REG_BYTES(sp) + LOAD x12, 12 * REG_BYTES(sp) + LOAD x13, 13 * REG_BYTES(sp) + LOAD x14, 14 * REG_BYTES(sp) + LOAD x15, 15 * REG_BYTES(sp) + LOAD x16, 16 * REG_BYTES(sp) + LOAD x17, 17 * REG_BYTES(sp) + LOAD x18, 18 * REG_BYTES(sp) + LOAD x19, 19 * REG_BYTES(sp) + LOAD x20, 20 * REG_BYTES(sp) + LOAD x21, 21 * REG_BYTES(sp) + LOAD x22, 22 * REG_BYTES(sp) + LOAD x23, 23 * REG_BYTES(sp) + LOAD x24, 24 * REG_BYTES(sp) + LOAD x25, 25 * REG_BYTES(sp) + LOAD x26, 26 * REG_BYTES(sp) + LOAD x27, 27 * REG_BYTES(sp) + LOAD x28, 28 * REG_BYTES(sp) + LOAD x29, 29 * REG_BYTES(sp) + LOAD x30, 30 * REG_BYTES(sp) + LOAD x31, 31 * REG_BYTES(sp) + addi sp, sp, CONTEXT_SIZE + + /* load float reg */ +#if (OS_CFG_CPU_MPU_PRESENT) + FLOAD f0, 0 * REG_BYTES(sp) + FLOAD f1, 1 * REG_BYTES(sp) + FLOAD f2, 2 * REG_BYTES(sp) + FLOAD f3, 3 * REG_BYTES(sp) + FLOAD f4, 4 * REG_BYTES(sp) + FLOAD f5, 5 * REG_BYTES(sp) + FLOAD f6, 6 * REG_BYTES(sp) + FLOAD f7, 7 * REG_BYTES(sp) + FLOAD f8, 8 * REG_BYTES(sp) + FLOAD f9, 9 * REG_BYTES(sp) + FLOAD f10, 10 * REG_BYTES(sp) + FLOAD f11, 11 * REG_BYTES(sp) + FLOAD f12, 12 * REG_BYTES(sp) + FLOAD f13, 13 * REG_BYTES(sp) + FLOAD f14, 14 * REG_BYTES(sp) + FLOAD f15, 15 * REG_BYTES(sp) + FLOAD f16, 16 * REG_BYTES(sp) + FLOAD f17, 17 * REG_BYTES(sp) + FLOAD f18, 18 * REG_BYTES(sp) + FLOAD f19, 19 * REG_BYTES(sp) + FLOAD f20, 20 * REG_BYTES(sp) + FLOAD f21, 21 * REG_BYTES(sp) + FLOAD f22, 22 * REG_BYTES(sp) + FLOAD f23, 23 * REG_BYTES(sp) + FLOAD f24, 24 * REG_BYTES(sp) + FLOAD f25, 25 * REG_BYTES(sp) + FLOAD f26, 26 * REG_BYTES(sp) + FLOAD f27, 27 * REG_BYTES(sp) + FLOAD f28, 28 * REG_BYTES(sp) + FLOAD f29, 29 * REG_BYTES(sp) + FLOAD f30, 30 * REG_BYTES(sp) + FLOAD f31, 31 * REG_BYTES(sp) + addi sp, sp, 32 * REG_BYTES +#endif + + mret + + .endfunc + + +.section .text.SW_Handler,"ax",%progbits +.align 8 +.func +.global SW_Handler +.extern g_os_port_switch_from_sp +.extern g_os_port_switch_to_sp +.extern os_isr_enter +.extern os_isr_leave +.extern os_port_on_switch_success +.extern g_t0 +SW_Handler: +#if (OS_CFG_CPU_FPU_PRESENT) + addi sp, sp, -32 * REG_BYTES + FSTORE f0, 0 * REG_BYTES(sp) + FSTORE f1, 1 * REG_BYTES(sp) + FSTORE f2, 2 * REG_BYTES(sp) + FSTORE f3, 3 * REG_BYTES(sp) + FSTORE f4, 4 * REG_BYTES(sp) + FSTORE f5, 5 * REG_BYTES(sp) + FSTORE f6, 6 * REG_BYTES(sp) + FSTORE f7, 7 * REG_BYTES(sp) + FSTORE f8, 8 * REG_BYTES(sp) + FSTORE f9, 9 * REG_BYTES(sp) + FSTORE f10, 10 * REG_BYTES(sp) + FSTORE f11, 11 * REG_BYTES(sp) + FSTORE f12, 12 * REG_BYTES(sp) + FSTORE f13, 13 * REG_BYTES(sp) + FSTORE f14, 14 * REG_BYTES(sp) + FSTORE f15, 15 * REG_BYTES(sp) + FSTORE f16, 16 * REG_BYTES(sp) + FSTORE f17, 17 * REG_BYTES(sp) + FSTORE f18, 18 * REG_BYTES(sp) + FSTORE f19, 19 * REG_BYTES(sp) + FSTORE f20, 20 * REG_BYTES(sp) + FSTORE f21, 21 * REG_BYTES(sp) + FSTORE f22, 22 * REG_BYTES(sp) + FSTORE f23, 23 * REG_BYTES(sp) + FSTORE f24, 24 * REG_BYTES(sp) + FSTORE f25, 25 * REG_BYTES(sp) + FSTORE f26, 26 * REG_BYTES(sp) + FSTORE f27, 27 * REG_BYTES(sp) + FSTORE f28, 28 * REG_BYTES(sp) + FSTORE f29, 29 * REG_BYTES(sp) + FSTORE f30, 30 * REG_BYTES(sp) + FSTORE f31, 31 * REG_BYTES(sp) +#endif + + addi sp, sp, -CONTEXT_SIZE // 留出栈空间 + STORE t0, 5*REG_BYTES(sp) // 保存 t0 + + li t0, 0x80 + STORE t0, 0 * REG_BYTES(sp) // 设置 MPIE + + csrr t0, mepc + STORE t0, 2*REG_BYTES(sp) // 保存正在运行任务的 pc 指针 + + STORE x1, 1 * REG_BYTES(sp) // return address + STORE x4, 4 * REG_BYTES(sp) + STORE x6, 6 * REG_BYTES(sp) + STORE x7, 7 * REG_BYTES(sp) + STORE x8, 8 * REG_BYTES(sp) + STORE x9, 9 * REG_BYTES(sp) + STORE x10, 10 * REG_BYTES(sp) + STORE x11, 11 * REG_BYTES(sp) + STORE x12, 12 * REG_BYTES(sp) + STORE x13, 13 * REG_BYTES(sp) + STORE x14, 14 * REG_BYTES(sp) + STORE x15, 15 * REG_BYTES(sp) + STORE x16, 16 * REG_BYTES(sp) + STORE x17, 17 * REG_BYTES(sp) + STORE x18, 18 * REG_BYTES(sp) + STORE x19, 19 * REG_BYTES(sp) + STORE x20, 20 * REG_BYTES(sp) + STORE x21, 21 * REG_BYTES(sp) + STORE x22, 22 * REG_BYTES(sp) + STORE x23, 23 * REG_BYTES(sp) + STORE x24, 24 * REG_BYTES(sp) + STORE x25, 25 * REG_BYTES(sp) + STORE x26, 26 * REG_BYTES(sp) + STORE x27, 27 * REG_BYTES(sp) + STORE x28, 28 * REG_BYTES(sp) + STORE x29, 29 * REG_BYTES(sp) + STORE x30, 30 * REG_BYTES(sp) + STORE x31, 31 * REG_BYTES(sp) + + la s0, g_os_port_switch_from_sp + LOAD s1, 0(s0) + STORE sp, 0(s1) // 将 sp 存入 g_os_port_switch_from_sp + + // 切换到 isr stack + csrrw sp,mscratch,sp + jal os_port_on_switch_success + csrrw sp,mscratch,sp + + la s0, g_os_port_switch_to_sp + LOAD s1, 0(s0) + LOAD sp, 0(s1) // 将 sp 指向 g_os_port_switch_to_sp 栈 + + LOAD a0, 2 * REG_BYTES(sp) // 加载/恢复 mepc + csrw mepc, a0 + + LOAD x1, 1*REG_BYTES(sp) + + li t0, 0x1800 + csrs mstatus, t0 // 确保 M 模式 + + LOAD t0, 0*REG_BYTES(sp) // 加载 mstatus + csrs mstatus, t0 // 恢复 mstatus + + LOAD x4, 4 * REG_BYTES(sp) + LOAD x5, 5 * REG_BYTES(sp) + LOAD x6, 6 * REG_BYTES(sp) + LOAD x7, 7 * REG_BYTES(sp) + LOAD x8, 8 * REG_BYTES(sp) + LOAD x9, 9 * REG_BYTES(sp) + LOAD x10, 10 * REG_BYTES(sp) + LOAD x11, 11 * REG_BYTES(sp) + LOAD x12, 12 * REG_BYTES(sp) + LOAD x13, 13 * REG_BYTES(sp) + LOAD x14, 14 * REG_BYTES(sp) + LOAD x15, 15 * REG_BYTES(sp) + LOAD x16, 16 * REG_BYTES(sp) + LOAD x17, 17 * REG_BYTES(sp) + LOAD x18, 18 * REG_BYTES(sp) + LOAD x19, 19 * REG_BYTES(sp) + LOAD x20, 20 * REG_BYTES(sp) + LOAD x21, 21 * REG_BYTES(sp) + LOAD x22, 22 * REG_BYTES(sp) + LOAD x23, 23 * REG_BYTES(sp) + LOAD x24, 24 * REG_BYTES(sp) + LOAD x25, 25 * REG_BYTES(sp) + LOAD x26, 26 * REG_BYTES(sp) + LOAD x27, 27 * REG_BYTES(sp) + LOAD x28, 28 * REG_BYTES(sp) + LOAD x29, 29 * REG_BYTES(sp) + LOAD x30, 30 * REG_BYTES(sp) + LOAD x31, 31 * REG_BYTES(sp) + addi sp, sp, CONTEXT_SIZE // 恢复栈指针 + +/* load float reg */ +#if (OS_CFG_CPU_FPU_PRESENT) + FLOAD f0, 0 * REG_BYTES(sp) + FLOAD f1, 1 * REG_BYTES(sp) + FLOAD f2, 2 * REG_BYTES(sp) + FLOAD f3, 3 * REG_BYTES(sp) + FLOAD f4, 4 * REG_BYTES(sp) + FLOAD f5, 5 * REG_BYTES(sp) + FLOAD f6, 6 * REG_BYTES(sp) + FLOAD f7, 7 * REG_BYTES(sp) + FLOAD f8, 8 * REG_BYTES(sp) + FLOAD f9, 9 * REG_BYTES(sp) + FLOAD f10, 10 * REG_BYTES(sp) + FLOAD f11, 11 * REG_BYTES(sp) + FLOAD f12, 12 * REG_BYTES(sp) + FLOAD f13, 13 * REG_BYTES(sp) + FLOAD f14, 14 * REG_BYTES(sp) + FLOAD f15, 15 * REG_BYTES(sp) + FLOAD f16, 16 * REG_BYTES(sp) + FLOAD f17, 17 * REG_BYTES(sp) + FLOAD f18, 18 * REG_BYTES(sp) + FLOAD f19, 19 * REG_BYTES(sp) + FLOAD f20, 20 * REG_BYTES(sp) + FLOAD f21, 21 * REG_BYTES(sp) + FLOAD f22, 22 * REG_BYTES(sp) + FLOAD f23, 23 * REG_BYTES(sp) + FLOAD f24, 24 * REG_BYTES(sp) + FLOAD f25, 25 * REG_BYTES(sp) + FLOAD f26, 26 * REG_BYTES(sp) + FLOAD f27, 27 * REG_BYTES(sp) + FLOAD f28, 28 * REG_BYTES(sp) + FLOAD f29, 29 * REG_BYTES(sp) + FLOAD f30, 30 * REG_BYTES(sp) + FLOAD f31, 31 * REG_BYTES(sp) + addi sp, sp, 32 * REG_BYTES +#endif + + mret // 从 M 模式退出 + .endfunc + + + + .align 4 + .end \ No newline at end of file diff --git a/CPU/QingKeV3/os_port_gnu.S b/CPU/QingKeV3/os_port_gnu.S deleted file mode 100644 index f8affa1..0000000 --- a/CPU/QingKeV3/os_port_gnu.S +++ /dev/null @@ -1,176 +0,0 @@ - .section .text.SW_Handler,"ax",@progbits - .global SW_Handler - .p2align 2 /* 4 bytes align */ - .func -SW_Handler: - /* save all from thread context */ - addi sp, sp, -32 * 4 - sw t0, 5 * 4(sp) /* 保存 t0, 后面要使用这个寄存器 */ - - li t0, 0x80 /* 读取 mstatus */ - sw t0, 2 * 4(sp) /* 保存到 x2 位置 */ - - li t0, 0x1800 /* 关闭中断,并进入 M-Mode 模式 */ - csrw mstatus, t0 - - sw x1, 1 * 4(sp) /* return address */ - sw x4, 4 * 4(sp) /* tp */ - sw x6, 6 * 4(sp) - sw x7, 7 * 4(sp) - sw x8, 8 * 4(sp) - sw x9, 9 * 4(sp) - sw x10, 10 * 4(sp) - sw x11, 11 * 4(sp) - sw x12, 12 * 4(sp) - sw x13, 13 * 4(sp) - sw x14, 14 * 4(sp) - sw x15, 15 * 4(sp) - sw x16, 16 * 4(sp) - sw x17, 17 * 4(sp) - sw x18, 18 * 4(sp) - sw x19, 19 * 4(sp) - sw x20, 20 * 4(sp) - sw x21, 21 * 4(sp) - sw x22, 22 * 4(sp) - sw x23, 23 * 4(sp) - sw x24, 24 * 4(sp) - sw x25, 25 * 4(sp) - sw x26, 26 * 4(sp) - sw x27, 27 * 4(sp) - sw x28, 28 * 4(sp) - sw x29, 29 * 4(sp) - sw x30, 30 * 4(sp) - sw x31, 31 * 4(sp) - - csrr t0, mepc /* 额外保存 mepc 到 x0 位置 */ - sw t0, 0 * 4(sp) - - la s0, g_os_port_switch_from_sp /* 更新旧任务栈指针 */ - lw s1, 0(s0) - sw sp, 0(s1) - - /* ---------- 收尾工作 ---------- */ - jal os_port_on_switch_success - - /* ---------- 切换到新任务 ---------- */ - - la s0, g_os_port_switch_to_sp /* 加载新任务栈指针 */ - lw s1, 0(s0) - lw sp, 0(s1) - - lw t0, 0 * 4(sp) /* 恢复 mepc 指针 */ - csrw mepc, t0 /* 将 t0 值写入 mepc */ - - lw x1, 1 * 4(sp) /* 加载 return address */ - - li t0, 0x1800 - csrs mstatus, t0 - lw t0, 2*4(sp) /* 将栈里面的 mstatus 恢复 */ - csrs mstatus, t0 /* 设置 MPIE = 1 */ - - lw x4, 4 * 4(sp) /* 恢复其它寄存器 */ - lw x5, 5 * 4(sp) - lw x6, 6 * 4(sp) - lw x7, 7 * 4(sp) - lw x8, 8 * 4(sp) - lw x9, 9 * 4(sp) - lw x10, 10 * 4(sp) - lw x11, 11 * 4(sp) - lw x12, 12 * 4(sp) - lw x13, 13 * 4(sp) - lw x14, 14 * 4(sp) - lw x15, 15 * 4(sp) - lw x16, 16 * 4(sp) - lw x17, 17 * 4(sp) - lw x18, 18 * 4(sp) - lw x19, 19 * 4(sp) - lw x20, 20 * 4(sp) - lw x21, 21 * 4(sp) - lw x22, 22 * 4(sp) - lw x23, 23 * 4(sp) - lw x24, 24 * 4(sp) - lw x25, 25 * 4(sp) - lw x26, 26 * 4(sp) - lw x27, 27 * 4(sp) - lw x28, 28 * 4(sp) - lw x29, 29 * 4(sp) - lw x30, 30 * 4(sp) - lw x31, 31 * 4(sp) - addi sp, sp, 32 * 4 /* 出栈 */ - - mret - .endfunc - - - /* - * void os_port_context_restore(os_uintptr_t to); - * a0 --> to - * a1 --> to_thread - */ - .section .text.os_port_context_restore,"ax",@progbits - .globl os_port_context_restore - .func - .p2align 2 /* 4 bytes align */ -os_port_context_restore: - /* first save interrupt stack */ - la t0, _eusrstack - addi t0, t0, -512 - csrw mscratch,t0 - - /* 关闭中断 */ - li t0, 0x1800 - csrw mstatus, t0 - - /* ---------- 收尾工作 ---------- */ - jal os_port_on_switch_success - - /* ---- Load target sp ---- */ - - lw sp, (a0) /* 将 to 的指针加载到 sp */ - - /* resw ra to mepc */ - lw a0, 0 * 4(sp) - csrw mepc, a0 - - li t0, 0x1800 - csrs mstatus, t0 - lw a0, 2*4(sp) - csrs mstatus, a0 - - lw x1, 1 * 4(sp) /* 返回地址 */ - lw x4, 4 * 4(sp) - lw x5, 5 * 4(sp) - lw x6, 6 * 4(sp) - lw x7, 7 * 4(sp) - lw x8, 8 * 4(sp) - lw x9, 9 * 4(sp) - lw x10, 10 * 4(sp) - lw x11, 11 * 4(sp) - lw x12, 12 * 4(sp) - lw x13, 13 * 4(sp) - lw x14, 14 * 4(sp) - lw x15, 15 * 4(sp) - lw x16, 16 * 4(sp) - lw x17, 17 * 4(sp) - lw x18, 18 * 4(sp) - lw x19, 19 * 4(sp) - lw x20, 20 * 4(sp) - lw x21, 21 * 4(sp) - lw x22, 22 * 4(sp) - lw x23, 23 * 4(sp) - lw x24, 24 * 4(sp) - lw x25, 25 * 4(sp) - lw x26, 26 * 4(sp) - lw x27, 27 * 4(sp) - lw x28, 28 * 4(sp) - lw x29, 29 * 4(sp) - lw x30, 30 * 4(sp) - lw x31, 31 * 4(sp) - - addi sp, sp, 32 * 4 - - mret - .endfunc - - - .end \ No newline at end of file diff --git a/CPU/QingKeV3/qkv3.c b/CPU/QingKeV3/qkv3.c deleted file mode 100644 index c598600..0000000 --- a/CPU/QingKeV3/qkv3.c +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/CPU/QingKeV3/qkv3.h b/CPU/QingKeV3/qkv3.h deleted file mode 100644 index f27fe42..0000000 --- a/CPU/QingKeV3/qkv3.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef INCLUDED_QKV3_H -#define INCLUDED_QKV3_H - - -#ifndef INCLUDED_OS_TYPES_H -#include -#endif /*INCLUDED_OS_TYPES_H*/ - -#ifndef INCLUDED_OS_COMPILER_H -#include -#endif /*INCLUDED_OS_COMPILER_H*/ - -#ifndef INCLUDED_RISCV_H -#include -#endif /*INCLUDED_RISCV_H*/ - - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -#ifdef __cplusplus -#define __I volatile /* defines 'read only' permissions */ -#else -#define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -#define QKV3_PFIC ((QKV3_PFIC_Type *) 0xE000E000 ) -#define QKV3_NVIC QKV3_PFIC -#define QKV3_NVIC_KEY1 ((uint32_t)0xFA050000) -#define QKV3_NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define QKV3_NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define QKV3_SysTick ((QKV3_SysTick_Type *) 0xE000F000) - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -typedef enum {QKV3_NoREADY = 0, QKV3_READY = !QKV3_NoREADY} QKV3_ErrorStatus; - -typedef enum {QKV3_DISABLE = 0, QKV3_ENABLE = !QKV3_DISABLE} QKV3_FunctionalState; - -typedef enum {QKV3_RESET = 0, QKV3_SET = !QKV3_RESET} QKV3_FlagStatus, QKV3_ITStatus; - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t VTFBADDRR; - __IO uint32_t CFGR; - __I uint32_t GISR; - uint8_t RESERVED0[0x10]; - __IO uint32_t VTFADDRR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}QKV3_PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO uint32_t CTLR; - __IO uint8_t CNTL0; - __IO uint8_t CNTL1; - __IO uint8_t CNTL2; - __IO uint8_t CNTL3; - __IO uint8_t CNTH0; - __IO uint8_t CNTH1; - __IO uint8_t CNTH2; - __IO uint8_t CNTH3; - __IO uint8_t CMPLR0; - __IO uint8_t CMPLR1; - __IO uint8_t CMPLR2; - __IO uint8_t CMPLR3; - __IO uint8_t CMPHR0; - __IO uint8_t CMPHR1; - __IO uint8_t CMPHR2; - __IO uint8_t CMPHR3; -}QKV3_SysTick_Type; - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_EnableIRQ(uint32_t IRQn) -{ - QKV3_NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_DisableIRQ(uint32_t IRQn) -{ - uint32_t t; - - t = QKV3_NVIC->ITHRESDR; - QKV3_NVIC->ITHRESDR = 0x10; - QKV3_NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); - QKV3_NVIC->ITHRESDR = t; -} - -OS_STATIC_FORCE_INLINE -uint32_t QKV3_NVIC_GetStatusIRQ(uint32_t IRQn) -{ - return((uint32_t) ((QKV3_NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -OS_STATIC_FORCE_INLINE -uint32_t QKV3_NVIC_GetPendingIRQ(uint32_t IRQn) -{ - return((uint32_t) ((QKV3_NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_SetPendingIRQ(uint32_t IRQn) -{ - QKV3_NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_ClearPendingIRQ(uint32_t IRQn) -{ - QKV3_NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -OS_STATIC_FORCE_INLINE -uint32_t QKV3_NVIC_GetActive(uint32_t IRQn) -{ - return((uint32_t)((QKV3_NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_SetPriority(uint32_t IRQn, uint8_t priority) -{ - QKV3_NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -OS_STATIC_FORCE_INLINE -void QKV3_WFI(void) -{ - QKV3_NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -OS_STATIC_FORCE_INLINE -void QKV3_SEV(void) -{ - QKV3_NVIC->SCTLR |= (1<<3)|(1<<5); -} - -OS_STATIC_FORCE_INLINE -void QKV3_WFE(void) -{ - QKV3_NVIC->SCTLR |= (1<<3); - asm volatile ("wfi"); -} - -OS_STATIC_FORCE_INLINE -void QKV3__WFE(void) -{ - QKV3_SEV(); - QKV3_WFE(); - QKV3_WFE(); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_SetFastIRQ(uint32_t addr, uint32_t IRQn, uint8_t num) -{ - if(num > 3) return ; - QKV3_NVIC->VTFBADDRR = addr; - QKV3_NVIC->VTFADDRR[num] = ((uint32_t)IRQn<<24)|(addr&0xfffff); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_SystemReset(void) -{ - QKV3_NVIC->CFGR = QKV3_NVIC_KEY3|(1<<7); -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_HaltPushCfg(QKV3_FunctionalState NewState) -{ - if (NewState != QKV3_DISABLE) - { - QKV3_NVIC->CFGR = QKV3_NVIC_KEY1; - } - else - { - QKV3_NVIC->CFGR = QKV3_NVIC_KEY1|(1<<0); - } -} - -OS_STATIC_FORCE_INLINE -void QKV3_NVIC_INTNestCfg(QKV3_FunctionalState NewState) -{ - if (NewState != QKV3_DISABLE) - { - QKV3_NVIC->CFGR = QKV3_NVIC_KEY1; - } - else - { - QKV3_NVIC->CFGR = QKV3_NVIC_KEY1|(1<<1); - } -} - - - -#endif /*INCLUDED_QKV3_H*/ diff --git a/CPU/QingKeV3/riscv.c b/CPU/QingKeV3/riscv.c deleted file mode 100644 index ab3051b..0000000 --- a/CPU/QingKeV3/riscv.c +++ /dev/null @@ -1,287 +0,0 @@ -#include - -#define __ASM __asm /* asm keyword for GNU Compiler */ -#define __INLINE inline /* inline keyword for GNU Compiler */ - - - -/********************************************************************* - * @fn RISCV_get_MSTATUS - * - * @brief Return the Machine Status Register - * - * @return mstatus value - */ -uint32_t RISCV_get_MSTATUS(void) -{ - uint32_t result; - - __ASM volatile("csrr %0," "mstatus": "=r"(result)); - return (result); -} - -uint32_t RISCV_get_set_MSTATUS(uint32_t value){ - uint32_t result; - __ASM volatile("csrrw %0, mstatus, %1" - : "=r"(result) - :"r"(value) - :"memory"); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MSTATUS - * - * @brief Set the Machine Status Register - * - * @param value - set mstatus value - * - * @return none - */ -void RISCV_set_MSTATUS(uint32_t value) -{ - __ASM volatile("csrw mstatus, %0" : : "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MISA - * - * @brief Return the Machine ISA Register - * - * @return misa value - */ -uint32_t RISCV_get_MISA(void) -{ - uint32_t result; - - __ASM volatile("csrr %0,""misa" : "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MISA - * - * @brief Set the Machine ISA Register - * - * @param value - set misa value - * - * @return none - */ -void RISCV_set_MISA(uint32_t value) -{ - __ASM volatile("csrw misa, %0" : : "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MTVEC - * - * @brief Return the Machine Trap-Vector Base-Address Register - * - * @return mtvec value - */ -uint32_t RISCV_get_MTVEC(void) -{ - uint32_t result; - - __ASM volatile("csrr %0," "mtvec": "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MTVEC - * - * @brief Set the Machine Trap-Vector Base-Address Register - * - * @param value - set mtvec value - * - * @return none - */ -void RISCV_set_MTVEC(uint32_t value) -{ - __ASM volatile("csrw mtvec, %0":: "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MSCRATCH - * - * @brief Return the Machine Seratch Register - * - * @return mscratch value - */ -uint32_t RISCV_get_MSCRATCH(void) -{ - uint32_t result; - - __ASM volatile("csrr %0," "mscratch" : "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MSCRATCH - * - * @brief Set the Machine Seratch Register - * - * @param value - set mscratch value - * - * @return none - */ -void RISCV_set_MSCRATCH(uint32_t value) -{ - __ASM volatile("csrw mscratch, %0" : : "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MEPC - * - * @brief Return the Machine Exception Program Register - * - * @return mepc value - */ -uint32_t RISCV_get_MEPC(void) -{ - uint32_t result; - - __ASM volatile("csrr %0," "mepc" : "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MEPC - * - * @brief Set the Machine Exception Program Register - * - * @return mepc value - */ -void RISCV_set_MEPC(uint32_t value) -{ - __ASM volatile("csrw mepc, %0" : : "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MCAUSE - * - * @brief Return the Machine Cause Register - * - * @return mcause value - */ -uint32_t RISCV_get_MCAUSE(void) -{ - uint32_t result; - - __ASM volatile("csrr %0," "mcause": "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MEPC - * - * @brief Set the Machine Cause Register - * - * @return mcause value - */ -void RISCV_set_MCAUSE(uint32_t value) -{ - __ASM volatile("csrw mcause, %0":: "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MTVAL - * - * @brief Return the Machine Trap Value Register - * - * @return mtval value - */ -uint32_t RISCV_get_MTVAL(void) -{ - uint32_t result; - - __ASM volatile("csrr %0," "mtval" : "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_set_MTVAL - * - * @brief Set the Machine Trap Value Register - * - * @return mtval value - */ -void RISCV_set_MTVAL(uint32_t value) -{ - __ASM volatile("csrw mtval, %0":: "r"(value)); -} - -/********************************************************************* - * @fn RISCV_get_MVENDORID - * - * @brief Return Vendor ID Register - * - * @return mvendorid value - */ -uint32_t RISCV_get_MVENDORID(void) -{ - uint32_t result; - - __ASM volatile("csrr %0,""mvendorid": "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_get_MARCHID - * - * @brief Return Machine Architecture ID Register - * - * @return marchid value - */ -uint32_t RISCV_get_MARCHID(void) -{ - uint32_t result; - - __ASM volatile("csrr %0,""marchid": "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_get_MIMPID - * - * @brief Return Machine Implementation ID Register - * - * @return mimpid value - */ -uint32_t RISCV_get_MIMPID(void) -{ - uint32_t result; - - __ASM volatile("csrr %0,""mimpid": "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_get_MHARTID - * - * @brief Return Hart ID Register - * - * @return mhartid value - */ -uint32_t RISCV_get_MHARTID(void) -{ - uint32_t result; - - __ASM volatile("csrr %0,""mhartid": "=r"(result)); - return (result); -} - -/********************************************************************* - * @fn RISCV_get_SP - * - * @brief Return SP Register - * - * @return SP value - */ -uint32_t RISCV_get_SP(void) -{ - uint32_t result; - - __ASM volatile("mv %0,""sp": "=r"(result):); - return (result); -} diff --git a/CPU/QingKeV3/riscv.h b/CPU/QingKeV3/riscv.h deleted file mode 100644 index dfd1eaa..0000000 --- a/CPU/QingKeV3/riscv.h +++ /dev/null @@ -1,240 +0,0 @@ -#ifndef INCLUDED_RISCV_H -#define INCLUDED_RISCV_H - -#ifndef INCLUDED_OS_TYPES_H -#include -#endif /*INCLUDED_OS_TYPES_H*/ - -#ifndef INCLUDED_OS_COMPILER_H -#include -#endif /*INCLUDED_OS_COMPILER_H*/ - - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -OS_STATIC_FORCE_INLINE -void RISCV_enable_irq() -{ - __asm volatile ("csrs mstatus, %0" : : "r" (0x88) ); -} - -OS_STATIC_FORCE_INLINE -void RISCV_disable_irq() -{ - __asm volatile ("csrc mstatus, %0" : : "r" (0x88) ); -} - -OS_STATIC_FORCE_INLINE -void RISCV_NOP() -{ - __asm volatile ("nop"); -} - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -/********************************************************************* - * @fn __AMOADD_W - * - * @brief Atomic Add with 32bit value - * Atomically ADD 32bit value with value in memory using amoadd.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ADDed - * - * @return return memory value + add value - */ -OS_STATIC_FORCE_INLINE -int32_t RISCV_AMOADD_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoadd.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - - -/********************************************************************* - * @fn __AMOAND_W - * - * @brief Atomic And with 32bit value - * Atomically AND 32bit value with value in memory using amoand.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ANDed - * - * @return return memory value & and value - */ -OS_STATIC_FORCE_INLINE -int32_t RISCV_AMOAND_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoand.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - - -/********************************************************************* - * @fn __AMOMAX_W - * - * @brief Atomic signed MAX with 32bit value - * Atomically signed max compare 32bit value with value in memory using amomax.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return return the bigger value - */ -OS_STATIC_FORCE_INLINE -int32_t RISCV_AMOMAX_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomax.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -OS_STATIC_FORCE_INLINE -uint32_t RISCV_AMOMAXU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amomaxu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMIN_W - * - * @brief Atomic signed MIN with 32bit value - * Atomically signed min compare 32bit value with value in memory using amomin.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return return the smaller value - */ -OS_STATIC_FORCE_INLINE -int32_t RISCV_AMOMIN_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomin.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMINU_W - * - * @brief Atomic unsigned MIN with 32bit value - * Atomically unsigned min compare 32bit value with value in memory using amominu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return return the smaller value - */ -OS_STATIC_FORCE_INLINE -uint32_t RISCV_AMOMINU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amominu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOOR_W - * - * @brief Atomic OR with 32bit value - * Atomically OR 32bit value with value in memory using amoor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ORed - * - * @return return memory value | and value - */ -OS_STATIC_FORCE_INLINE -int32_t RISCV_AMOOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOSWAP_W - * - * @brief Atomically swap new 32bit value into memory using amoswap.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * newval - New value to be stored into the address - * - * @return return the original value in memory - */ -OS_STATIC_FORCE_INLINE -uint32_t RISCV_AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) -{ - uint32_t result; - - __asm volatile ("amoswap.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); - return result; -} - -/********************************************************************* - * @fn __AMOXOR_W - * - * @brief Atomic XOR with 32bit value - * Atomically XOR 32bit value with value in memory using amoxor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be XORed - * - * @return return memory value ^ and value - */ -OS_STATIC_FORCE_INLINE -int32_t RISCV_AMOXOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoxor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/* ------------------------------------------------------------------------------------------------------------------ */ -/* */ - -extern uint32_t RISCV_get_set_MSTATUS(uint32_t value); -extern uint32_t RISCV_get_MSTATUS(void); -extern void RISCV_set_MSTATUS(uint32_t value); -extern uint32_t RISCV_get_MISA(void); -extern void RISCV_set_MISA(uint32_t value); -extern uint32_t RISCV_get_MTVEC(void); -extern void RISCV_set_MTVEC(uint32_t value); -extern uint32_t RISCV_get_MSCRATCH(void); -extern void RISCV_set_MSCRATCH(uint32_t value); -extern uint32_t RISCV_get_MEPC(void); -extern void RISCV_set_MEPC(uint32_t value); -extern uint32_t RISCV_get_MCAUSE(void); -extern void RISCV_set_MCAUSE(uint32_t value); -extern uint32_t RISCV_get_MTVAL(void); -extern void RISCV_set_MTVAL(uint32_t value); -extern uint32_t RISCV_get_MVENDORID(void); -extern uint32_t RISCV_get_MARCHID(void); -extern uint32_t RISCV_get_MIMPID(void); -extern uint32_t RISCV_get_MHARTID(void); -extern uint32_t RISCV_get_SP(void); - -#endif /*INCLUDED_RISCV_H*/ diff --git a/CPU/QingKeV3FV5F/cpu.c b/CPU/QingKeV3FV5F/cpu.c new file mode 100644 index 0000000..942f6ed --- /dev/null +++ b/CPU/QingKeV3FV5F/cpu.c @@ -0,0 +1 @@ +#include diff --git a/CPU/QingKeV3FV5F/cpu.h b/CPU/QingKeV3FV5F/cpu.h new file mode 100644 index 0000000..fc7c7fe --- /dev/null +++ b/CPU/QingKeV3FV5F/cpu.h @@ -0,0 +1,10 @@ +#ifndef INCLUDED_CPU_H +#define INCLUDED_CPU_H + +#ifndef INCLUDED_RISCV_H +#include +#endif /*INCLUDED_RISCV_H*/ + + + +#endif /*INCLUDED_CPU_H*/ diff --git a/CPU/QingKeV3FV5F/os_loopdelay.c b/CPU/QingKeV3FV5F/os_loopdelay.c new file mode 100644 index 0000000..84a7d4a --- /dev/null +++ b/CPU/QingKeV3FV5F/os_loopdelay.c @@ -0,0 +1,10 @@ +#include + +#if defined (__GNUC__) /*!< GNU Compiler */ +__attribute__((naked)) +void os_loop_delay(unsigned long ulCount){ + __asm(" add a0, a0, -1 \n" + " bne x0, a0, os_loop_delay \n" + " ret "); +} +#endif /* __CC_ARM */ \ No newline at end of file diff --git a/CPU/QingKeV3FV5F/os_loopdelay.h b/CPU/QingKeV3FV5F/os_loopdelay.h new file mode 100644 index 0000000..ba0bacd --- /dev/null +++ b/CPU/QingKeV3FV5F/os_loopdelay.h @@ -0,0 +1,34 @@ +#ifndef INCLUDED_OS_LOOPDELAY_H +#define INCLUDED_OS_LOOPDELAY_H + +#ifndef INCLUDED_OS_TYPES_H +#include +#endif /*INCLUDED_OS_TYPES_H*/ + +#define OS_LOOP_DELAY_US(n) (n * SystemCoreClock/3000000) +#define OS_LOOP_DELAY_MS(n) (n * SystemCoreClock/3000) +#define OS_LOOP_DELAY_S(n) (n * SystemCoreClock/3) + +/* + + 72Mhz时钟时,当ulCount为1时,函数耗时3个时钟,延时=3*1/72us=1/24us + + SystemCoreClock=72000000 + + us级延时,延时n微秒 + LoopDelay(n*(SystemCoreClock/3000000)); + + ms级延时,延时n毫秒 + LoopDelay(n*(SystemCoreClock/3000)); + + m级延时,延时n秒 + LoopDelay(n*(SystemCoreClock/3)); +*/ + +void os_loop_delay(unsigned long ulCount); + +#define OS_LoopDelayUS(n) os_loop_delay(OS_LOOP_DELAY_US(n)) +#define OS_LoopDelayMS(n) os_loop_delay(OS_LOOP_DELAY_MS(n)) +#define OS_LoopDelayS(n) os_loop_delay(OS_LOOP_DELAY_S(n)) + +#endif /*INCLUDED_OS_LOOPDELAY_H*/ diff --git a/CPU/QingKeV3/os_port.c b/CPU/QingKeV3FV5F/os_port.c similarity index 87% rename from CPU/QingKeV3/os_port.c rename to CPU/QingKeV3FV5F/os_port.c index 7ee3bb5..f601c9e 100644 --- a/CPU/QingKeV3/os_port.c +++ b/CPU/QingKeV3FV5F/os_port.c @@ -6,7 +6,7 @@ #include "os_systick.h" #include "os_sched.h" #include "os_isr.h" -#include "qkv3.h" +#include "cpu.h" /* ------------------------------------------------------------------------------------------------------------------ */ /* */ @@ -20,7 +20,7 @@ OS_STATIC_FORCE_INLINE uint32_t _SysTick_Config(os_tick_t ticks) { - QKV3_PFIC->CFGR=0xFA050003; /* 关闭硬件压栈和嵌套 */ + QK_PFIC->CFGR=0xFA050003; /* 关闭硬件压栈和嵌套 */ /* 位段值含义: Bit [31:16] :0xFA05 - 解锁密钥 (Key)。为了防止误触发,修改中断全局配置通常需要写入固定的“钥匙”值。 @@ -28,19 +28,19 @@ uint32_t _SysTick_Config(os_tick_t ticks) Bit[0] :1(来自0x3) - 嵌套中断使能 (NEST)。允许高优先级中断打断低优先级中断。 */ - QKV3_NVIC_SetPriority(SysTick_IRQn,0xf0); - QKV3_NVIC_SetPriority(Software_IRQn,0xf0); - QKV3_SysTick->CTLR=0; - QKV3_SysTick->CNTL0=0;QKV3_SysTick->CNTL1=0;QKV3_SysTick->CNTL2=0;QKV3_SysTick->CNTL3=0; - QKV3_SysTick->CNTH0=0;QKV3_SysTick->CNTH1=0;QKV3_SysTick->CNTH2=0;QKV3_SysTick->CNTH3=0; - QKV3_SysTick->CMPLR0=(uint8_t)(ticks-1); - QKV3_SysTick->CMPLR1=(uint8_t)((ticks-1)>>8); - QKV3_SysTick->CMPLR2=(uint8_t)((ticks-1)>>16); - QKV3_SysTick->CMPLR3=(uint8_t)((ticks-1)>>24); - QKV3_SysTick->CMPHR0=0;QKV3_SysTick->CMPHR1=0;QKV3_SysTick->CMPHR2=0;QKV3_SysTick->CMPHR3=0; - QKV3_SysTick->CTLR=0x1; - QKV3_NVIC_EnableIRQ(SysTick_IRQn); - QKV3_NVIC_EnableIRQ(Software_IRQn); + QK_NVIC_SetPriority(SysTick_IRQn,0xf0); + QK_NVIC_SetPriority(Software_IRQn,0xf0); + QK_SysTick->CTLR=0; + QK_SysTick->CNTL0=0;QK_SysTick->CNTL1=0;QK_SysTick->CNTL2=0;QK_SysTick->CNTL3=0; + QK_SysTick->CNTH0=0;QK_SysTick->CNTH1=0;QK_SysTick->CNTH2=0;QK_SysTick->CNTH3=0; + QK_SysTick->CMPLR0=(uint8_t)(ticks-1); + QK_SysTick->CMPLR1=(uint8_t)((ticks-1)>>8); + QK_SysTick->CMPLR2=(uint8_t)((ticks-1)>>16); + QK_SysTick->CMPLR3=(uint8_t)((ticks-1)>>24); + QK_SysTick->CMPHR0=0;QK_SysTick->CMPHR1=0;QK_SysTick->CMPHR2=0;QK_SysTick->CMPHR3=0; + QK_SysTick->CTLR=0x1; + QK_NVIC_EnableIRQ(SysTick_IRQn); + QK_NVIC_EnableIRQ(Software_IRQn); return 0; } @@ -189,7 +189,6 @@ void os_port_context_switch(void* from_sp, void* to_sp){ void SysTick_Handler(void) __attribute__((interrupt())); void SysTick_Handler(void){ - os_isr_enter(); QKV3_SysTick->CTLR=0; QKV3_SysTick->CNTL0=0;QKV3_SysTick->CNTL1=0;QKV3_SysTick->CNTL2=0;QKV3_SysTick->CNTL3=0; QKV3_SysTick->CNTH0=0;QKV3_SysTick->CNTH1=0;QKV3_SysTick->CNTH2=0;QKV3_SysTick->CNTH3=0; @@ -197,6 +196,5 @@ void SysTick_Handler(void){ // 调用系统心跳处理 os_systick_tick(); - os_isr_leave(); } diff --git a/CPU/QingKeV3FV5F/riscv.c b/CPU/QingKeV3FV5F/riscv.c new file mode 100644 index 0000000..17e56eb --- /dev/null +++ b/CPU/QingKeV3FV5F/riscv.c @@ -0,0 +1,816 @@ +#include + +volatile uint32_t QK_WFE_MASK = 0; + +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#define __INLINE inline /*!< inline keyword for GNU Compiler */ + + +/********************************************************************* + * @fn __get_FFLAGS + * + * @brief Return the Floating-Point Accrued Exceptions + * + * @return fflags value + */ +uint32_t RISCV_get_FFLAGS(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "fflags" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_FFLAGS + * + * @brief Set the Floating-Point Accrued Exceptions + * + * @param value - set FFLAGS value + * + * @return none + */ +void RISCV_set_FFLAGS(uint32_t value) +{ + __ASM volatile ("csrw fflags, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_FRM + * + * @brief Return the Floating-Point Dynamic Rounding Mode + * + * @return frm value + */ +uint32_t RISCV_get_FRM(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "frm" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_FRM + * + * @brief Set the Floating-Point Dynamic Rounding Mode + * + * @param value - set frm value + * + * @return none + */ +void RISCV_set_FRM(uint32_t value) +{ + __ASM volatile ("csrw frm, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_FCSR + * + * @brief Return the Floating-Point Control and Status Register + * + * @return fcsr value + */ +uint32_t RISCV_get_FCSR(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "fcsr" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_FCSR + * + * @brief Set the Floating-Point Dynamic Rounding Mode + * + * @param value - set fcsr value + * + * @return none + */ +void RISCV_set_FCSR(uint32_t value) +{ + __ASM volatile ("csrw fcsr, %0" : : "r" (value) ); +} + + + +/********************************************************************* + * @fn __get_MSTATUS + * + * @brief Return the Machine Status Register + * + * @return mstatus value + */ +uint32_t RISCV_get_MSTATUS(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mstatus" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MSTATUS + * + * @brief Set the Machine Status Register + * + * @param value - set mstatus value + * + * @return none + */ +void RISCV_set_MSTATUS(uint32_t value) +{ + __ASM volatile ("csrw mstatus, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MISA + * + * @brief Return the Machine ISA Register + * + * @return misa value + */ +uint32_t RISCV_get_MISA(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "misa" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MISA + * + * @brief Set the Machine ISA Register + * + * @param value - set misa value + * + * @return none + */ +void RISCV_set_MISA(uint32_t value) +{ + __ASM volatile ("csrw misa, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MTVEC + * + * @brief Return the Machine Trap-Vector Base-Address Register + * + * @return mtvec value + */ +uint32_t RISCV_get_MTVEC(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mtvec" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MTVEC + * + * @brief Set the Machine Trap-Vector Base-Address Register + * + * @param value - set mtvec value + * + * @return none + */ +void RISCV_set_MTVEC(uint32_t value) +{ + __ASM volatile ("csrw mtvec, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MSCRATCH + * + * @brief Return the Machine Seratch Register + * + * @return mscratch value + */ +uint32_t RISCV_get_MSCRATCH(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mscratch" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MSCRATCH + * + * @brief Set the Machine Seratch Register + * + * @param value - set mscratch value + * + * @return none + */ +void RISCV_set_MSCRATCH(uint32_t value) +{ + __ASM volatile ("csrw mscratch, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MEPC + * + * @brief Return the Machine Exception Program Register + * + * @return mepc value + */ +uint32_t RISCV_get_MEPC(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mepc" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MEPC + * + * @brief Set the Machine Exception Program Register + * + * @return mepc value + */ +void RISCV_set_MEPC(uint32_t value) +{ + __ASM volatile ("csrw mepc, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MCAUSE + * + * @brief Return the Machine Cause Register + * + * @return mcause value + */ +uint32_t RISCV_get_MCAUSE(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mcause" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MEPC + * + * @brief Set the Machine Cause Register + * + * @return mcause value + */ +void RISCV_set_MCAUSE(uint32_t value) +{ + __ASM volatile ("csrw mcause, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MTVAL + * + * @brief Return the Machine Trap Value Register + * + * @return mtval value + */ +uint32_t RISCV_get_MTVAL(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mtval" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __set_MTVAL + * + * @brief Set the Machine Trap Value Register + * + * @return mtval value + */ +void RISCV_set_MTVAL(uint32_t value) +{ + __ASM volatile ("csrw mtval, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MVENDORID + * + * @brief Return Vendor ID Register + * + * @return mvendorid value + */ +uint32_t RISCV_get_MVENDORID(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mvendorid" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __get_MARCHID + * + * @brief Return Machine Architecture ID Register + * + * @return marchid value + */ +uint32_t RISCV_get_MARCHID(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "marchid" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __get_MIMPID + * + * @brief Return Machine Implementation ID Register + * + * @return mimpid value + */ +uint32_t RISCV_get_MIMPID(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mimpid" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __get_MHARTID + * + * @brief Return Hart ID Register + * + * @return mhartid value + */ +uint32_t RISCV_get_MHARTID(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mhartid" : "=r" (result) ); + return (result); +} + +/********************************************************************* + * @fn __get_SP + * + * @brief Return SP Register + * + * @return SP value + */ +uint32_t RISCV_get_SP(void) +{ + uint32_t result; + + __ASM volatile ( "mv %0," "sp" : "=r"(result) : ); + return (result); +} + +/********************************************************************* + * @fn __set_MCOUNT_INHIBIT + * + * @brief Set Instruction and cycle count shield switch in machine mode + * + * @return mcause value + */ +void RISCV_set_MCOUNT_INHIBIT(uint32_t value) +{ + __ASM volatile ("csrw mcounteren, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MCOUNT_INHIBIT + * + * @brief Return Instruction and cycle count shield switch in machine mode + * + * @return SP value + */ +uint32_t RISCV_get_MCOUNT_INHIBIT(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mcounteren" : "=r"(result) : ); + return (result); +} + +/********************************************************************* + * @fn __set_MCYCLE + * + * @brief Set the number of cycles in machine mode + * + * @return mcause value + */ +void RISCV_set_MCYCLE(uint32_t value) +{ + __ASM volatile ("csrw mcycle, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MCYCLE + * + * @brief Return the number of cycles in machine mode + * + * @return SP value + */ +uint32_t RISCV_get_MCYCLE(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "mcycle" : "=r"(result) : ); + return (result); +} + +/********************************************************************* + * @fn __set_MINSTRET + * + * @brief Set the number of completed instructions in machine mode + * + * @return mcause value + */ +void RISCV_set_MINSTRET(uint32_t value) +{ + __ASM volatile ("csrw minstret, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_MINSTRET + * + * @brief Return the number of completed instructions in machine mode + * + * @return SP value + */ +uint32_t RISCV_get_MINSTRET(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "minstret" : "=r"(result) : ); + return (result); +} + +/********************************************************************* + * @fn __set_UCYCLE + * + * @brief Set the number of cycles in user mode + * + * @return mcause value + */ +void RISCV_set_UCYCLE(uint32_t value) +{ + __ASM volatile ("csrw cycle, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_UCYCLE + * + * @brief Return the number of cycles in user mode + * + * @return SP value + */ +uint32_t RISCV_get_UCYCLE(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "cycle" : "=r"(result) : ); + return (result); +} + +/********************************************************************* + * @fn __set_UINSTRET + * + * @brief Set the number of completed instructions in user mode + * + * @return mcause value + */ +void RISCV_set_UINSTRET(uint32_t value) +{ + __ASM volatile ("csrw instret, %0" : : "r" (value) ); +} + +/********************************************************************* + * @fn __get_UINSTRET + * + * @brief Return the number of completed instructions in user mode + * + * @return SP value + */ +uint32_t RISCV_get_UINSTRET(void) +{ + uint32_t result; + + __ASM volatile ( "csrr %0," "instret" : "=r"(result) : ); + return (result); +} + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* HSEM */ + +/* HSEM Key */ +#define QK_HSEM_KEY (0x5AA50000) + +/********************************************************************* + * @fn HSEM_Take + * + * @brief Take a semaphore in 2 Step mode. + * + * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. + * ProcessID - Process ID from 0 to 255. + * + * @return READY - Take success. + * NoREADY - Take error. + */ +QK_ErrorStatus QK_HSEM_Take(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID) +{ + QK_ErrorStatus status = QK_NoREADY; + + QK_HSEM->RX[HSEM_ID] = ((ProcessID & 0xFF) | ((QK_NVIC_GetCurrentCoreID() << 8) | (1 << 31))); + + if( QK_HSEM->RX[HSEM_ID] == ((ProcessID & 0xFF) | ((QK_NVIC_GetCurrentCoreID() << 8) | (1 << 31)))) + { + status = QK_READY; + } + else + { + status = QK_NoREADY; + } + + return (status); +} + +/********************************************************************* + * @fn HSEM_FastTake + * + * @brief Fast Take a semaphore with 1 Step mode. + * + * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. + * + * @return READY - Take success. + * NoREADY - Take error. + */ +QK_ErrorStatus QK_HSEM_FastTake(QK_HSEM_ID_TypeDef HSEM_ID) +{ + QK_ErrorStatus status = QK_NoREADY; + + if( QK_HSEM->RLRX[HSEM_ID] == ((QK_NVIC_GetCurrentCoreID() << 8) | (1 << 31))) + { + status = QK_READY; + } + else + { + status = QK_NoREADY; + } + + return (status); +} + +/********************************************************************* + * @fn HSEM_GetOneSemTakenState + * + * @brief Get one semaphore state Taken or not. + * + * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. + * + * @return ENABLE - Take. + * DISABLE - No Take. + */ +QK_FunctionalState QK_HSEM_GetOneSemTakenState(QK_HSEM_ID_TypeDef HSEM_ID) +{ + QK_FunctionalState status = QK_DISABLE; + + if( (QK_HSEM->RX[HSEM_ID] & (1 << 31)) == (1 << 31)) + { + status = QK_ENABLE; + } + else + { + status = QK_DISABLE; + } + + return (status); +} + +/********************************************************************* + * @fn HSEM_GetAllSemTakenState + * + * @brief Get all semaphore state Taken or not. + * + * @return All semaphore state Taken or not. + */ +uint32_t QK_HSEM_GetAllSemTakenState(void) +{ + return (QK_HSEM->LSE); +} + +/********************************************************************* + * @fn HSEM_OwnCoreGetAllSemTakenState + * + * @brief Its own core(V3F or V5F) get all semaphore state Taken or not. + * + * @return All semaphore state Taken or not for own core(V3F or V5F) . + */ +uint32_t QK_HSEM_OwnCoreGetAllSemTakenState(void) +{ + return (QK_HSEM->LSM); +} + +/********************************************************************* + * @fn HSEM_ReleaseOneSem + * + * @brief Release one semaphore. + * + * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. + * ProcessID - Process ID from 0 to 255. + * + * @return none + */ +void QK_HSEM_ReleaseOneSem(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID) +{ + QK_HSEM->RX[HSEM_ID] = (ProcessID & 0xFF) | ((QK_NVIC_GetCurrentCoreID() << 8)); +} + +/********************************************************************* + * @fn HSEM_ReleaseAllSem + * + * @brief Release all semaphore. + * + * @return none + */ +void QK_HSEM_ReleaseAllSem(void) +{ + QK_HSEM->CLR = QK_HSEM_KEY | (1<<13) | (1<<12); +} + +/********************************************************************* + * @fn HSEM_ReleaseSem_MatchCID_PID + * + * @brief Release semaphore that matches the ProcessID and CoreID. + * + * @param CoreID - core ID. + * HSEM_Core_ID_V3F - Riscv V3F + * HSEM_Core_ID_V5F - Riscv V5F + * ProcessID - Process ID from 0 to 255. + * + * @return none + */ +void QK_HSEM_ReleaseSem_MatchCID_PID(uint32_t CoreID, uint32_t ProcessID) +{ + QK_HSEM->CLR = QK_HSEM_KEY | CoreID | (ProcessID & 0xFF); +} + +/********************************************************************* + * @fn HSEM_ReleaseSem_MatchCID + * + * @brief Release semaphore that matches the CoreID. + * + * @param CoreID - core ID. + * HSEM_Core_ID_V3F - Riscv V3F + * HSEM_Core_ID_V5F - Riscv V5F + * + * @return none + */ +void QK_HSEM_ReleaseSem_MatchCID(uint32_t CoreID ) +{ + QK_HSEM->CLR = QK_HSEM_KEY | CoreID | (1<<12); +} + +/********************************************************************* + * @fn HSEM_ReleaseSem_MatchPID + * + * @brief Release semaphore that matches the ProcessID and CoreID. + * + * @param ProcessID - Process ID from 0 to 255. + * + * @return none + */ +void QK_HSEM_ReleaseSem_MatchPID(uint32_t ProcessID) +{ + QK_HSEM->CLR = QK_HSEM_KEY | (ProcessID & 0xFF) | (1<<13); +} + +/********************************************************************* + * @fn HSEM_SetClearKey + * + * @brief Set semaphore Key. + * + * @param Key - semaphore key value from 0 to 0xFFFF. + * + * @return none + */ +void QK_HSEM_SetClearKey(uint32_t Key) +{ + QK_HSEM->CLR = (Key << 16); +} + +/********************************************************************* + * @fn HSEM_GetClearKey + * + * @brief Get semaphore Key. + * + * @return semaphore key value from 0 to 0xFFFF. + */ +uint32_t QK_HSEM_GetClearKey(void) +{ + return ((QK_HSEM->KEY >> 16)); +} + +/********************************************************************* + * @fn HSEM_ITConfig + * + * @brief Enables or disables the HSEM interrupts. + * + * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. + * NewState - ENABLE or DISABLE. + * + * @return none + */ +void QK_HSEM_ITConfig(QK_HSEM_ID_TypeDef HSEM_ID, QK_FunctionalState NewState) +{ + if(NewState != QK_DISABLE) + { + QK_HSEM->IER |= (1 << HSEM_ID); + } + else + { + QK_HSEM->IER &= (~(uint32_t)(1 << HSEM_ID)); + } +} + +/********************************************************************* + * @fn HSEM_GetFlagStatus + * + * @brief Checks whether the specified HSEM flag is set or not. + * + * @param HSEM_ID - pointer to a HSEM_ID_TypeDef structure. + * + * @return FlagStatus: SET or RESET. + */ +QK_FlagStatus QK_HSEM_GetFlagStatus(QK_HSEM_ID_TypeDef HSEM_ID) +{ + QK_FlagStatus bitstatus = QK_RESET; + + if((QK_HSEM->ISR & (1<ISR = (1<ISM & (1<ISR = (1< +#endif /*INCLUDED_OS_TYPES_H*/ + +#ifndef INCLUDED_OS_COMPILER_H +#include +#endif /*INCLUDED_OS_COMPILER_H*/ + +#ifndef INCLUDED_OS_MACROS_H +#include +#endif /*INCLUDED_OS_MACROS_H*/ + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +/* IO definitions */ +#ifdef __cplusplus +#define __I volatile /* defines 'read only' permissions */ +#else +#define __I volatile const /* defines 'read only' permissions */ +#endif +#define __O volatile /* defines 'write only' permissions */ +#define __IO volatile /* defines 'read / write' permissions */ + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +typedef enum {QK_NoREADY = 0, QK_READY = !QK_NoREADY} QK_ErrorStatus; + +typedef enum {QK_DISABLE = 0, QK_ENABLE = !QK_DISABLE} QK_FunctionalState; + +typedef enum {QK_RESET = 0, QK_SET = !QK_RESET} QK_FlagStatus, QK_ITStatus; + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +extern volatile uint32_t QK_WFE_MASK; +extern volatile uint32_t WFE_WkupSource; + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + + +/* memory mapped structure for HSEM */ +typedef struct +{ + __IO uint32_t RX[32]; + uint8_t RESERVED0[0x80]; + __I uint32_t RLRX[32]; + uint8_t RESERVED1[0x80]; + __IO uint32_t LSE; + uint8_t RESERVED2[4]; + __IO uint32_t CLR; + __IO uint32_t KEY; + uint8_t RESERVED3[0xF0]; + __IO uint32_t IER; + uint8_t RESERVED4[4]; + __IO uint32_t ISR; + uint8_t RESERVE5[4]; + __I uint32_t ISM; + uint8_t RESERVED6[4]; + __I uint32_t LSM; +}QK_HSEM_Type; + +/* memory mapped structure for IPC */ +typedef struct +{ + __IO uint32_t CTLR; + __I uint32_t ISR; + __I uint32_t ISM; + uint32_t RESERVED0; + __IO uint32_t ENA; + __IO uint32_t STS; + __O uint32_t SET; + __O uint32_t CLR; + __IO uint32_t MSG[4]; +}QK_IPC_Type; + +/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ +typedef struct{ + __I uint32_t ISR[8]; + __I uint32_t IPR[8]; + __IO uint32_t ITHRESDR; + uint32_t RESERVED; + __IO uint32_t CFGR; + __I uint32_t GISR; + __IO uint8_t VTFIDR[4]; + uint8_t RESERVED0[12]; + __IO uint32_t VTFADDR[4]; + uint8_t RESERVED1[0x90]; + __O uint32_t IENR[8]; + uint8_t RESERVED2[0x60]; + __O uint32_t IRER[8]; + uint8_t RESERVED3[0x60]; + __O uint32_t IPSR[8]; + uint8_t RESERVED4[0x60]; + __O uint32_t IPRR[8]; + uint8_t RESERVED5[0x60]; + __IO uint32_t IACTR[8]; + uint8_t RESERVED6[0xE0]; + __IO uint8_t IPRIOR[256]; + uint8_t RESERVED7[0x100]; + __IO uint8_t IALLOCR[256]; + __I uint32_t IAUTR[8]; + __IO uint32_t WAKEIP[2]; + uint8_t RESERVED8[0x58]; + __I uint32_t CSTAR[2]; + uint8_t RESERVED9[0x4F8]; + __IO uint32_t EENR; + __IO uint32_t EPR; + __IO uint32_t EWUPR; + uint8_t RESERVED10[0x84]; + __IO uint32_t SCTLR; +}QK_PFIC_Type; + +/* memory mapped structure for SysTick */ +typedef struct +{ + __IO uint32_t CTLR; + __IO uint32_t ISR; //only for SysTick0 + __IO uint32_t CNT; + uint32_t RESERVED0; + __IO uint32_t CMP; +}QK_SysTick_Type; + + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + + +#define QK_HSEM ((QK_HSEM_Type *) 0xE000C000 ) +#define QK_IPC ((QK_IPC_Type *) 0xE000D000 ) +#define QK_PFIC ((QK_PFIC_Type *) 0xE000E000 ) +#define QK_NVIC QK_PFIC +#define QK_NVIC_KEY3 ((uint32_t)0xBEEF0000) + +#define QK_SysTick0 ((QK_SysTick_Type *) 0xE000F000) +#define QK_SysTick1 ((QK_SysTick_Type *) 0xE000F080) + +/* Core_ID */ +#define QK_Core_ID_V3F ((uint8_t)0x00) +#define QK_Core_ID_V5F ((uint8_t)0x01) + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +/********************************************************************* + * @fn __enable_irq + * + * @brief Enable Global Interrupt + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void RISCV_enable_irq() +{ + __asm volatile ("csrs 0x800, %0" : : "r" (0x88) ); +} + +/********************************************************************* + * @fn __disable_irq + * + * @brief Disable Global Interrupt + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void RISCV_disable_irq() +{ + __asm volatile ("csrc 0x800, %0" : : "r" (0x88) ); + __asm volatile ("fence.i"); +} + +/********************************************************************* + * @fn __NOP + * + * @brief nop + * + * @return none + */ +OS_STATIC_FORCE_INLINE void RISCV_NOP() +{ + __asm volatile ("nop"); +} + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* QingKe RISCV */ + +/********************************************************************* + * @fn NVIC_EnableIRQ + * + * @brief Enable Interrupt + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_EnableIRQ(uint32_t IRQn) +{ + QK_NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/********************************************************************* + * @fn NVIC_DisableIRQ + * + * @brief Disable Interrupt + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_DisableIRQ(uint32_t IRQn) +{ + QK_NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); + __asm volatile ("fence.i"); +} + +/********************************************************************* + * @fn NVIC_GetStatusIRQ + * + * @brief Get Interrupt Enable State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Enable + * 0 - Interrupt Disable + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetStatusIRQ(uint32_t IRQn) +{ + return((uint32_t) ((QK_NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_GetPendingIRQ + * + * @brief Get Interrupt Pending State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Pending Enable + * 0 - Interrupt Pending Disable + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetPendingIRQ(uint32_t IRQn) +{ + return((uint32_t) ((QK_NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_SetPendingIRQ + * + * @brief Set Interrupt Pending + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_SetPendingIRQ(uint32_t IRQn) +{ + QK_NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_ClearPendingIRQ + * + * @brief Clear Interrupt Pending + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_ClearPendingIRQ(uint32_t IRQn) +{ + QK_NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/********************************************************************* + * @fn NVIC_GetActive + * + * @brief Get Interrupt Active State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Active + * 0 - Interrupt No Active + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetActive(uint32_t IRQn) +{ + return((uint32_t)((QK_NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + + +/********************************************************************* + * @fn NVIC_SetPriority + * + * @brief Set Interrupt Priority + * + * @param IRQn - Interrupt Numbers + * V5F: + * interrupt nesting enable- 5~8 Level(CSR-0x804 bit1 = 1 bit[3:2] = 3) + * priority - bit[7:5] - Preemption Priority + * bit[4] - Sub priority + * bit[3:0] - Reserve + * interrupt nesting enable- 3~4 Level(CSR-0x804 bit1 = 1 bit[3:2] = 2) + * priority - bit[7:6] - Preemption Priority + * bit[5:4] - Sub priority + * bit[3:0] - Reserve + * interrupt nesting enable-2 Level(CSR-0x804 bit1 = 1 bit[3:2] = 1) + * priority - bit[7] - Preemption Priority + * bit[6:4] - Sub priority + * bit[3:0] - Reserve + * interrupt nesting disable(CSR-0x804 bit1 = 0) + * priority - bit[7:4] - Sub priority + * bit[3:0] - Reserve + * V3F: + * interrupt nesting enable-2 Level(CSR-0x804 bit1 = 1 bit[3:2] = 1) + * priority - bit[7] - Preemption Priority + * bit[6:4] - Sub priority + * bit[3:0] - Reserve + * interrupt nesting disable(CSR-0x804 bit1 = 0) + * priority - bit[7:4] - Sub priority + * bit[3:0] - Reserve + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_SetPriority(uint32_t IRQn, uint8_t priority) +{ + QK_NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; +} + +/********************************************************************* + * @fn NVIC_GetAllocateIRQ + * + * @brief Get Interrupt Allocate + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Allocate to V5F + * 0 - Allocate to V3F + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetAllocateIRQ(uint32_t IRQn) +{ + return((uint32_t)((QK_NVIC->IALLOCR[(uint32_t)(IRQn)] & (1 << 0))?1:0)); +} + +/********************************************************************* + * @fn NVIC_SetAllocateIRQ + * + * @brief Set Interrupt Allocate + * + * @param IRQn - Interrupt Numbers ( >31 ) + * Core_ID - Core ID + * Core_ID_V5F - V5F + * Core_ID_V3F - V3F + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_SetAllocateIRQ(uint32_t IRQn, uint8_t Core_ID) +{ + if(IRQn > 31) + QK_NVIC->IALLOCR[(uint32_t)(IRQn)] = Core_ID; +} + +/********************************************************************* + * @fn NVIC_OwnCoreGetAllocateIRQ + * + * @brief Own Core Get Interrupt Allocate + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Allocate to own core + * 0 - No allocate to own core + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_OwnCoreGetAllocateIRQ(uint32_t IRQn) +{ + return((uint32_t) ((QK_NVIC->IAUTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/********************************************************************* + * @fn __WFI + * + * @brief Wait for Interrupt + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK__WFI(void) +{ + QK_NVIC->SCTLR &= ~(1<<3); // wfi + asm volatile ("wfi"); +} + +/********************************************************************* + * @fn _SEV + * + * @brief Set Event + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_SEV(void) +{ + uint32_t t; + + t = QK_NVIC->SCTLR; + QK_NVIC->SCTLR |= (1<<3)|(1<<5); + QK_NVIC->SCTLR = (QK_NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); +} + + +/********************************************************************* + * @fn __WFE_IDSET + * + * @brief Set Events ID + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK__WFE_IDSET(uint32_t LINE_ID) +{ + QK_WFE_MASK |= LINE_ID; +} + +/********************************************************************* + * @fn __WFE + * + * @brief Wait for Events + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK__WFE(void) +{ + __attribute__((unused)) uint32_t t=0; + + *(__IO uint32_t*)0x40010400 |= QK_WFE_MASK; + + WFE_WkupSource = 0; + QK_NVIC->EPR = 0xFFFFFFFF; + QK_NVIC->SCTLR |= (1<<3); + asm volatile ("wfi"); + + for(;;) + { + t = *(__IO uint32_t*)0x40010414; + if((t & QK_WFE_MASK) || (QK_WFE_MASK == 0)) + { + break; + } else{ + asm volatile ("wfi"); + } + } + WFE_WkupSource = *(__IO uint32_t*)0x40010414; + *(__IO uint32_t*)0x40010400 &= ~QK_WFE_MASK; + *(__IO uint32_t*)0x40010414 |= QK_WFE_MASK; +} + + +/********************************************************************* + * @fn SetVTFIRQ + * + * @brief Set VTF Interrupt + * + * @param addr - VTF interrupt service function base address. + * IRQn -Interrupt Numbers + * num - VTF Interrupt Numbers + * NewState - DISABLE or ENABLE + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_SetVTFIRQ(uint32_t addr, uint32_t IRQn, uint8_t num, QK_FunctionalState NewState) +{ + if(num > 3) return ; + + if (NewState != QK_DISABLE) + { + QK_NVIC->VTFIDR[num] = IRQn; + QK_NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); + } + else + { + QK_NVIC->VTFIDR[num] = IRQn; + QK_NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); + } +} + +/********************************************************************* + * @fn NVIC_SystemReset + * + * @brief Initiate a system reset request + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_SystemReset(void) +{ + QK_NVIC->CFGR = QK_NVIC_KEY3|(1<<7); +} + +/********************************************************************* + * @fn NVIC_WakeUp_V3F + * + * @brief Wake up V3F and set address for PC + * + * @param addr - V3F wake up address for PC(addr%1024 == 0). + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_WakeUp_V3F(uint32_t addr) +{ + addr &= ~0x3FF; + QK_NVIC->WAKEIP[0] = addr; + QK_NVIC->SCTLR |= (1<<5); +} + + +/********************************************************************* + * @fn NVIC_WakeUp_V5F + * + * @brief Wake up V5F and set address for PC + * + * @param addr - V5F wake up address for PC(addr%1024 == 0). + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_WakeUp_V5F(uint32_t addr) +{ + addr &= ~0x3FF; + QK_NVIC->WAKEIP[1] = addr; + QK_NVIC->SCTLR |= (1<<5); +} + +/********************************************************************* + * @fn NVIC_GetCurrentCoreID + * + * @brief Get Current Core ID + * + * @return 1 - V5F + * 0 - V3F + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetCurrentCoreID(void) +{ + return((uint32_t)(QK_NVIC->SCTLR & (1<<16))?1:0); +} + + +/********************************************************************* + * @fn NVIC_EventWakeUPCmd + * + * @brief Enables or disables the event wake up. + * + * @param EVTn - Event Numbers ( <=31 ) + * NewState - DISABLE or ENABLE + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_EventWakeUPCmd(uint32_t EVTn, QK_FunctionalState NewState) +{ + if(EVTn > 31) return ; + + if (NewState != QK_DISABLE) + { + QK_NVIC->EENR |= 1 << EVTn; + } + else + { + QK_NVIC->EENR &= (~(1 << EVTn)); + } +} + + +/********************************************************************* + * @fn NVIC_ClearPendingWakeUpEvent + * + * @brief Clear wake up event pending + * + * @param EVTn - Event Numbers (from 8 to 31) + * + * @return none + */ +OS_STATIC_FORCE_INLINE +void QK_NVIC_ClearPendingWakeUpEvent(uint32_t EVTn) +{ + if((EVTn > 31) || (EVTn < 8)) return ; + QK_NVIC->EPR = 1 << EVTn; +} + + +/********************************************************************* + * @fn NVIC_GetPendingWakeUpEvent + * + * @brief Get wake up event pending + * + * @param IRQn - Event Numbers( <=31) + * + * @return 1 - Event pending + * 0 - Event no pending + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetPendingWakeUpEvent(uint32_t EVTn) +{ + return((uint32_t)((QK_NVIC->EPR & (1 << EVTn))?1:0)); +} + +/********************************************************************* + * @fn NVIC_GetWakeUpEvent + * + * @brief Get wake up event + * + * @param IRQn - Interrupt Numbers( <=31) + * + * @return 1 - The event wake up core + * 0 - The event do not wake up core + */ +OS_STATIC_FORCE_INLINE +uint32_t QK_NVIC_GetWakeUpEvent(uint32_t EVTn) +{ + return((uint32_t)((QK_NVIC->EWUPR & (1 << EVTn))?1:0)); +} + +/********************************************************************* + * @fn ASM_MCPY + * + * @brief Implement the assembly instruction function of mcpy, copy + * the continuous data from the starting address of SrcAddrStart + * to the ending address of SrcAddrEnd to the starting address + * of DstAddrStart.(Only for V3F) + * + * @param SA - Copy the start address of the source region. + * EA - Copy the end address of the source region. + * DA - Copy the start address of the destination region. + * + * @return none + */ +static inline void QKV3F_ASM_MCPY(uint8_t* DA,uint8_t* SA,uint8_t* EA) +{ + __asm__ volatile("mcpy %2, %0, %1" :"+r"(SA) , "+r"(DA):"r"(EA):"memory"); +} + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* ATOMIC */ + + +/********************************************************************* + * @fn __AMOADD_W + * + * @brief Atomic Add with 32bit value + * Atomically ADD 32bit value with value in memory using amoadd.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ADDed + * + * @return return memory value + add value + */ +OS_STATIC_FORCE_INLINE +int32_t RISCV_AMOADD_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoadd.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOAND_W + * + * @brief Atomic And with 32bit value + * Atomically AND 32bit value with value in memory using amoand.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ANDed + * + * @return return memory value & and value + */ +OS_STATIC_FORCE_INLINE +int32_t RISCV_AMOAND_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoand.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMAX_W + * + * @brief Atomic signed MAX with 32bit value + * Atomically signed max compare 32bit value with value in memory using amomax.d. + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return return the bigger value + */ +OS_STATIC_FORCE_INLINE +int32_t RISCV_AMOMAX_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amomax.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMAXU_W + * + * @brief Atomic unsigned MAX with 32bit value + * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return return the bigger value + */ +OS_STATIC_FORCE_INLINE +uint32_t RISCV_AMOMAXU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __asm volatile ("amomaxu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMIN_W + * + * @brief Atomic signed MIN with 32bit value + * Atomically signed min compare 32bit value with value in memory using amomin.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return return the smaller value + */ +OS_STATIC_FORCE_INLINE +int32_t RISCV_AMOMIN_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amomin.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMINU_W + * + * @brief Atomic unsigned MIN with 32bit value + * Atomically unsigned min compare 32bit value with value in memory using amominu.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return return the smaller value + */ +OS_STATIC_FORCE_INLINE +uint32_t RISCV_AMOMINU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __asm volatile ("amominu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOOR_W + * + * @brief Atomic OR with 32bit value + * Atomically OR 32bit value with value in memory using amoor.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ORed + * + * @return return memory value | and value + */ +OS_STATIC_FORCE_INLINE +int32_t RISCV_AMOOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOSWAP_W + * + * @brief Atomically swap new 32bit value into memory using amoswap.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * newval - New value to be stored into the address + * + * @return return the original value in memory + */ +OS_STATIC_FORCE_INLINE +uint32_t RISCV_AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) +{ + uint32_t result; + + __asm volatile ("amoswap.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/********************************************************************* + * @fn __AMOXOR_W + * + * @brief Atomic XOR with 32bit value + * Atomically XOR 32bit value with value in memory using amoxor.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be XORed + * + * @return return memory value ^ and value + */ +OS_STATIC_FORCE_INLINE +int32_t RISCV_AMOXOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoxor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* Core_Exported_Functions */ + +extern uint32_t RISCV_get_FFLAGS(void); +extern void RISCV_set_FFLAGS(uint32_t value); +extern uint32_t RISCV_get_FRM(void); +extern void RISCV_set_FRM(uint32_t value); +extern uint32_t RISCV_get_FCSR(void); +extern void RISCV_set_FCSR(uint32_t value); +extern void RISCV_set_MSTATUS(uint32_t value); +extern uint32_t RISCV_get_MISA(void); +extern void RISCV_set_MISA(uint32_t value); +extern uint32_t RISCV_get_MTVEC(void); +extern void RISCV_set_MTVEC(uint32_t value); +extern uint32_t RISCV_get_MSCRATCH(void); +extern void RISCV_set_MSCRATCH(uint32_t value); +extern uint32_t RISCV_get_MEPC(void); +extern void RISCV_set_MEPC(uint32_t value); +extern uint32_t RISCV_get_MCAUSE(void); +extern void RISCV_set_MCAUSE(uint32_t value); +extern uint32_t RISCV_get_MTVAL(void); +extern void RISCV_set_MTVAL(uint32_t value); +extern uint32_t RISCV_get_MVENDORID(void); +extern uint32_t RISCV_get_MARCHID(void); +extern uint32_t RISCV_get_MIMPID(void); +extern uint32_t RISCV_get_MHARTID(void); +extern uint32_t RISCV_get_SP(void); +void RISCV_set_MCOUNT_INHIBIT(uint32_t value); +uint32_t RISCV_get_MCOUNT_INHIBIT(void); +void RISCV_set_MCYCLE(uint32_t value); +uint32_t RISCV_get_MCYCLE(void); +void RISCV_set_MINSTRET(uint32_t value); +uint32_t RISCV_get_MINSTRET(void); +void RISCV_set_UCYCLE(uint32_t value); +uint32_t RISCV_get_UCYCLE(void); +void RISCV_set_UINSTRET(uint32_t value); +uint32_t RISCV_get_UINSTRET(void); + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +OS_STATIC_FORCE_INLINE +uint32_t RISCV_get_set_MSTATUS(uint32_t value){ + uint32_t result; + __asm volatile ( "csrrw %0, mstatus, %1" + : "=r" (result) + : "r"(value) + : "memory"); + return (result); +} + +/* ------------------------------------------------------------------------------------------------------------------ */ +/* HSEM */ + + +/* HSEM_ID_enumeration */ +typedef enum +{ + QK_HSEM_ID0 = 0, + QK_HSEM_ID1, + QK_HSEM_ID2, + QK_HSEM_ID3, + QK_HSEM_ID4, + QK_HSEM_ID5, + QK_HSEM_ID6, + QK_HSEM_ID7, + QK_HSEM_ID8, + QK_HSEM_ID9, + QK_HSEM_ID10, + QK_HSEM_ID11, + QK_HSEM_ID12, + QK_HSEM_ID13, + QK_HSEM_ID14, + QK_HSEM_ID15, + QK_HSEM_ID16, + QK_HSEM_ID17, + QK_HSEM_ID18, + QK_HSEM_ID19, + QK_HSEM_ID20, + QK_HSEM_ID21, + QK_HSEM_ID22, + QK_HSEM_ID23, + QK_HSEM_ID24, + QK_HSEM_ID25, + QK_HSEM_ID26, + QK_HSEM_ID27, + QK_HSEM_ID28, + QK_HSEM_ID29, + QK_HSEM_ID30, + QK_HSEM_ID31 +} QK_HSEM_ID_TypeDef; + +/* HSEM_Core_ID */ +#define QK_HSEM_Core_ID_V3F ((uint32_t)0x00000000) +#define QK_HSEM_Core_ID_V5F ((uint32_t)0x00000100) + + +QK_ErrorStatus QK_HSEM_Take(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID); +QK_ErrorStatus QK_HSEM_FastTake(QK_HSEM_ID_TypeDef HSEM_ID); +QK_FunctionalState QK_HSEM_GetOneSemTakenState(QK_HSEM_ID_TypeDef HSEM_ID); +uint32_t QK_HSEM_GetAllSemTakenState(void); +uint32_t QK_HSEM_OwnCoreGetAllSemTakenState(void); +void QK_HSEM_ReleaseOneSem(QK_HSEM_ID_TypeDef HSEM_ID, uint32_t ProcessID); +void QK_HSEM_ReleaseAllSem(void); +void QK_HSEM_ReleaseSem_MatchCID_PID(uint32_t CoreID, uint32_t ProcessID); +void QK_HSEM_ReleaseSem_MatchCID(uint32_t CoreID); +void QK_HSEM_ReleaseSem_MatchPID(uint32_t ProcessID); +void QK_HSEM_SetClearKey(uint32_t Key); +uint32_t QK_HSEM_GetClearKey(void); +void QK_HSEM_ITConfig(QK_HSEM_ID_TypeDef HSEM_ID, QK_FunctionalState NewState); +QK_FlagStatus QK_HSEM_GetFlagStatus(QK_HSEM_ID_TypeDef HSEM_ID); +void QK_HSEM_ClearFlag(QK_HSEM_ID_TypeDef HSEM_ID); +QK_ITStatus QK_HSEM_GetITStatus(QK_HSEM_ID_TypeDef HSEM_ID); +void QK_HSEM_ClearITPendingBit(QK_HSEM_ID_TypeDef HSEM_ID); + + +#endif /*INCLUDED_RISCV_H*/ diff --git a/CPU/QingKeV5/cpu.c b/CPU/QingKeV5/cpu.c new file mode 100644 index 0000000..942f6ed --- /dev/null +++ b/CPU/QingKeV5/cpu.c @@ -0,0 +1 @@ +#include diff --git a/CPU/QingKeV5/cpu.h b/CPU/QingKeV5/cpu.h new file mode 100644 index 0000000..1e55245 --- /dev/null +++ b/CPU/QingKeV5/cpu.h @@ -0,0 +1,6 @@ +#ifndef INCLUDED_CPU_H +#define INCLUDED_CPU_H + + + +#endif /*INCLUDED_CPU_H*/ diff --git a/Kernel/SingleCore/cpu_clz.c b/Kernel/SingleCore/cpu_clz.c index b4a5faf..88f8bd7 100644 --- a/Kernel/SingleCore/cpu_clz.c +++ b/Kernel/SingleCore/cpu_clz.c @@ -1,5 +1,6 @@ #include "cpu_clz.h" #include "os_config.h" +#include "cpu.h" #if !defined(OS_CFG_CPU_CLZ_ASM_PRESENT) || (!OS_CFG_CPU_CLZ_ASM_PRESENT) // 如果配置中没有提供汇编版本的clz函数,则使用C语言实现 diff --git a/Kernel/SingleCore/os_config.h.in b/Kernel/SingleCore/os_config.h.in index e6ac75b..aa59c68 100644 --- a/Kernel/SingleCore/os_config.h.in +++ b/Kernel/SingleCore/os_config.h.in @@ -9,7 +9,6 @@ #cmakedefine OS_CFG_TICKS_PER_SECOND @OS_CFG_TICKS_PER_SECOND@ #cmakedefine OS_CFG_SYSCALL_PRIORITY @OS_CFG_SYSCALL_PRIORITY@ #cmakedefine OS_CFG_PRIORITY_MAX @OS_CFG_PRIORITY_MAX@ -#cmakedefine OS_CFG_CPU_CLZ_ASM_PRESENT @OS_CFG_CPU_CLZ_ASM_PRESENT@ #cmakedefine OS_CFG_IDLE_TASK_STACK_SIZE @OS_CFG_IDLE_TASK_STACK_SIZE@ #cmakedefine OS_CFG_IDLE_TASK_TICKS @OS_CFG_IDLE_TASK_TICKS@ @@ -18,6 +17,12 @@ #cmakedefine OS_CFG_DEVICE_MAX @OS_CFG_DEVICE_MAX@ +#cmakedefine OS_CFG_CPU_CLZ_ASM_PRESENT @OS_CFG_CPU_CLZ_ASM_PRESENT@ +#cmakedefine OS_CFG_CPU_CORE_NAME @OS_CFG_CPU_CORE_NAME@ +#cmakedefine OS_CFG_CPU_FPU_PRESENT @OS_CFG_CPU_FPU_PRESENT@ +#cmakedefine OS_CFG_CPU_MPU_PRESENT @OS_CFG_CPU_MPU_PRESENT@ + + /* ==================================================================================================== */ /* DEFAULT */ @@ -58,4 +63,13 @@ #define OS_CFG_IDLE_TASK_PRIORITY OS_PRIORITY_IDLE #endif /*OS_CFG_IDLE_TASK_PRIORITY*/ +#ifndef OS_CFG_CPU_FPU_PRESENT +#define OS_CFG_CPU_FPU_PRESENT 0 +#endif /* OS_CFG_CPU_FPU_PRESENT */ + +#ifndef OS_CFG_CPU_MPU_PRESENT +#define OS_CFG_CPU_MPU_PRESENT 0 +#endif /* OS_CFG_CPU_MPU_PRESENT */ + + #endif /*INCLUDED_OS_CONFIG_H*/ diff --git a/Kernel/SingleCore/os_port.h b/Kernel/SingleCore/os_port.h index 7a0d3ad..ff275a3 100644 --- a/Kernel/SingleCore/os_port.h +++ b/Kernel/SingleCore/os_port.h @@ -1,6 +1,10 @@ #ifndef INCLUDED_OS_PORT_H #define INCLUDED_OS_PORT_H +#ifndef INCLUDED_CPU_H +#include +#endif /*INCLUDED_CPU_H*/ + #ifndef INCLUDED_OS_TYPES_H #include #endif /*INCLUDED_OS_TYPES_H*/ @@ -9,7 +13,6 @@ #include #endif /*INCLUDED_OS_TASK_H*/ - /* ------------------------------------------------------------------------------------------------------------------ */ /* */ @@ -56,17 +59,37 @@ void os_port_on_switch_success(void); /* ------------------------------------------------------------------------------------------------------------------ */ /* 中断管理 */ -void os_port_disable_irq(void); -void os_port_enable_irq(void); +//void os_port_disable_irq(void); +//void os_port_enable_irq(void); +//os_uint_t os_port_save_disable_irq(void); +//void os_port_restore_irq(os_uint_t level); +//os_uint_t os_port_save_disable_irq_in_isr(void); +//void os_port_restore_irq_in_isr(os_uint_t level); -os_uint_t os_port_save_disable_irq(void); +#ifndef os_port_disable_irq +#define os_port_disable_irq +#endif -void os_port_restore_irq(os_uint_t level); +#ifndef os_port_enable_irq +#define os_port_enable_irq +#endif -os_uint_t os_port_save_disable_irq_in_isr(void); +#ifndef os_port_save_disable_irq +#define os_port_save_disable_irq +#endif -void os_port_restore_irq_in_isr(os_uint_t level); +#ifndef os_port_restore_irq +#define os_port_restore_irq +#endif + +#ifndef os_port_save_disable_irq_in_isr +#define os_port_save_disable_irq_in_isr +#endif + +#ifndef os_port_restore_irq_in_isr +#define os_port_restore_irq_in_isr +#endif /* ------------------------------------------------------------------------------------------------------------------ */ /* 初始化和启动 */ diff --git a/Kernel/SingleCore/os_task.h b/Kernel/SingleCore/os_task.h index 8ffbe1f..45bcb9d 100644 --- a/Kernel/SingleCore/os_task.h +++ b/Kernel/SingleCore/os_task.h @@ -29,6 +29,9 @@ #include #endif /*INCLUDED_OS_SCHED_H*/ +#ifndef INCLUDED_OS_ALIGN_H +#include +#endif /*INCLUDED_OS_ALIGN_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ @@ -76,6 +79,18 @@ os_task_t* os_task_self(void){ return (os_task_t*)g_os_sched_current_task_p; } +/* ------------------------------------------------------------------------------------------------------------------ */ +/* */ + +#define OS_TASK_DEF(Name, StackSize) \ +OS_ALIGNED(OS_ALIGN_SIZE) \ +static uint8_t Name##_Stack[StackSize]; \ +static os_task_t Name; \ +OS_NORETURN \ +static void Name##_TaskEntry(void* param) + +#define OS_TASK_RUN(Name, Param, Ticks, Priority) \ +os_task_init(&Name, Name##_TaskEntry, Param, Name##_Stack, OS_ARRAY_SIZE(Name##_Stack), Ticks, Priority) #endif /*INCLUDED_OS_TASK_H*/