From 987e00a34d27892e5a5e84329bc72bffcb39941a Mon Sep 17 00:00:00 2001 From: zhangzheng <1358745329@qq.com> Date: Sat, 27 Apr 2024 03:47:45 +0000 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E6=A0=B8&=E5=A4=9A=E6=A0=B8ipc?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 4 +- .vscode/settings.json | 11 +- mkrtos_bootstrap/CMakeLists.txt | 7 +- mkrtos_configs/aarch64_qemu_defconfig | 3 +- mkrtos_knl/Kconfig | 5 +- mkrtos_knl/arch/aarch64/aarch64_ptregs.h | 21 - mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c | 53 +- mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h | 63 +- mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S | 7 +- mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S | 20 +- mkrtos_knl/arch/aarch64/arm_gicv2.h | 61 +- mkrtos_knl/arch/aarch64/cache.S | 36 + mkrtos_knl/arch/aarch64/exception.c | 28 +- mkrtos_knl/arch/aarch64/ipi.c | 105 +++ mkrtos_knl/arch/aarch64/ipi.h | 32 + mkrtos_knl/arch/aarch64/mmu.c | 2 +- mkrtos_knl/arch/aarch64/mmu.h | 4 - mkrtos_knl/arch/aarch64/psci.c | 2 +- mkrtos_knl/arch/aarch64/sche.s | 35 - mkrtos_knl/arch/aarch64/sche_arch.c | 32 +- mkrtos_knl/arch/aarch64/sche_arch.h | 3 +- mkrtos_knl/arch/aarch64/spin_table.c | 12 +- mkrtos_knl/arch/aarch64/spinlock_arch.c | 23 +- mkrtos_knl/arch/cortex-m3/atomics.c | 72 ++ mkrtos_knl/arch/cortex-m3/atomics.h | 67 ++ mkrtos_knl/arch/cortex-m3/link.lds | 4 + mkrtos_knl/arch/cortex-m3/link.lds.S | 5 + mkrtos_knl/arch/cortex-m3/sche.S | 4 +- mkrtos_knl/arch/cortex-m3/sched_arch.c | 4 +- mkrtos_knl/arch/cortex-m3/stm32f1/arch.c | 2 +- mkrtos_knl/arch/cortex-m3/stm32f1/arch.h | 7 +- mkrtos_knl/arch/cortex-m3/stm32f2/arch.c | 2 +- mkrtos_knl/arch/cortex-m3/stm32f2/arch.h | 7 +- mkrtos_knl/arch/cortex-m33/atomics.c | 72 ++ mkrtos_knl/arch/cortex-m33/atomics.h | 67 ++ mkrtos_knl/arch/cortex-m33/link.lds.S | 5 + mkrtos_knl/arch/cortex-m33/sche.S | 4 +- mkrtos_knl/arch/cortex-m33/sched_arch.c | 4 +- mkrtos_knl/arch/cortex-m33/swm34s/arch.c | 2 +- mkrtos_knl/arch/cortex-m33/swm34s/arch.h | 7 +- mkrtos_knl/arch/cortex-m4/atomics.c | 72 ++ mkrtos_knl/arch/cortex-m4/atomics.h | 67 ++ mkrtos_knl/arch/cortex-m4/link.lds.S | 5 + mkrtos_knl/arch/cortex-m4/sche.S | 4 +- mkrtos_knl/arch/cortex-m4/sched_arch.c | 4 +- mkrtos_knl/arch/cortex-m4/stm32f4/arch.c | 2 +- mkrtos_knl/arch/cortex-m4/stm32f4/arch.h | 7 +- .../drivers/aarch64_qemu/systick/systick.c | 21 +- mkrtos_knl/drivers/aarch64_qemu/uart/uart.c | 6 +- mkrtos_knl/inc/knl/irq.h | 9 +- mkrtos_knl/inc/knl/irq_sender.h | 10 - mkrtos_knl/inc/knl/ref.h | 23 +- mkrtos_knl/inc/knl/scheduler.h | 8 +- mkrtos_knl/inc/knl/slist.h | 15 + mkrtos_knl/inc/knl/spinlock.h | 1 + mkrtos_knl/inc/knl/thread.h | 27 +- mkrtos_knl/inc/knl/util.h | 4 +- mkrtos_knl/knl/irq.c | 18 +- mkrtos_knl/knl/mm/vma.c | 2 +- mkrtos_knl/knl/pre_cpu.c | 3 +- mkrtos_knl/knl/scheduler.c | 53 +- mkrtos_knl/knl/spinlock.c | 15 +- mkrtos_knl/knl/syscall.c | 5 +- mkrtos_knl/knl/task.c | 8 +- mkrtos_knl/knl/thread.c | 748 +++++++++++------- mkrtos_knl/knl/thread_knl.c | 34 +- mkrtos_knl/test/kthread_test.c | 6 +- mkrtos_script/build_f1.sh | 8 +- mkrtos_script/build_f2.sh | 8 +- mkrtos_script/debug_aarch64_qemu.sh | 3 +- mkrtos_script/run_aarch64_qemu.sh | 6 +- mkrtos_user/lib/CMakeLists.txt | 2 +- mkrtos_user/lib/lwip/CMakeLists.txt | 3 +- mkrtos_user/lib/sys_util/inc/u_rpc.h | 2 + mkrtos_user/lib/sys_util/src/u_elf_loader.c | 4 +- mkrtos_user/lib/sys_util/src/u_sleep.c | 3 +- mkrtos_user/server/CMakeLists.txt | 5 +- mkrtos_user/server/drv/CMakeLists.txt | 8 +- mkrtos_user/server/init/src/cons.c | 11 +- mkrtos_user/server/init/src/init.cfg | 6 +- mkrtos_user/server/init/src/parse_cfg.c | 2 +- .../server/init/src/test/thread_cpu_test.c | 44 +- mkrtos_user/server/net/CMakeLists.txt | 59 +- mkrtos_user/server/net/aarch64/link.lds | 233 ++++++ .../server/net/{ => armv7_8m}/link.lds | 0 mkrtos_user/server/net/src/heap_stack.c | 4 +- mkrtos_user/server/net/src/main.c | 5 +- mkrtos_user/server/shell/CMakeLists.txt | 2 +- mkrtos_user/server/test/src/factory_test.c | 1 + 89 files changed, 1809 insertions(+), 691 deletions(-) delete mode 100644 mkrtos_knl/arch/aarch64/aarch64_ptregs.h create mode 100644 mkrtos_knl/arch/aarch64/cache.S create mode 100644 mkrtos_knl/arch/aarch64/ipi.c create mode 100644 mkrtos_knl/arch/aarch64/ipi.h delete mode 100644 mkrtos_knl/arch/aarch64/sche.s create mode 100644 mkrtos_knl/arch/cortex-m3/atomics.c create mode 100644 mkrtos_knl/arch/cortex-m3/atomics.h create mode 100644 mkrtos_knl/arch/cortex-m33/atomics.c create mode 100644 mkrtos_knl/arch/cortex-m33/atomics.h create mode 100644 mkrtos_knl/arch/cortex-m4/atomics.c create mode 100644 mkrtos_knl/arch/cortex-m4/atomics.h create mode 100644 mkrtos_user/server/net/aarch64/link.lds rename mkrtos_user/server/net/{ => armv7_8m}/link.lds (100%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 07a46383e..744079be0 100755 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -47,9 +47,9 @@ "externalConsole": false, // "miDebuggerPath": "/opt/homebrew/bin/arm-none-eabi-gdb", - // "miDebuggerPath": "/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb", + "miDebuggerPath": "/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gdb", // "miDebuggerPath": "/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gdb", - "miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb", + // "miDebuggerPath": "/home/zhangzheng/gcc-arm-10.3-2021.07-aarch64-aarch64-none-elf/bin/aarch64-none-elf-gdb", // "miDebuggerPath": "/home/mkrtos-smart/toolchains/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-gdb", "miDebuggerServerAddress": "127.0.0.1:3333", "MIMode": "gdb", diff --git a/.vscode/settings.json b/.vscode/settings.json index 21b658e9e..7c801e60a 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -73,7 +73,16 @@ "spinlock_arch.h": "c", "app.h": "c", "config.h": "c", - "u_sleep.h": "c" + "u_sleep.h": "c", + "spin_table.h": "c", + "init.h": "c", + "pre_cpu.h": "c", + "ipi.h": "c", + "slist.h": "c", + "atomics.h": "c", + "spinlock.h": "c", + "stdlib.h": "c", + "cpulock.h": "c" }, "cortex-debug.showRTOS": false, "cortex-debug.variableUseNaturalFormat": false, diff --git a/mkrtos_bootstrap/CMakeLists.txt b/mkrtos_bootstrap/CMakeLists.txt index eff672d62..4c0d02029 100755 --- a/mkrtos_bootstrap/CMakeLists.txt +++ b/mkrtos_bootstrap/CMakeLists.txt @@ -120,14 +120,17 @@ if ((DEFINED CONFIG_MMU) AND (CONFIG_MMU STREQUAL "y")) ) add_dependencies( gen_sys_cpio - mkrtos_dump + init_dump_elf + mkrtos_dump_elf + sh_dump_elf + cpiofs_dump_elf + net_dump_elf ) set_source_files_properties(${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio.elf PROPERTIES EXTERNAL_OBJECT true) add_executable(bootstrap.elf ${deps} ${CMAKE_SOURCE_DIR}/build/output/rootfs.cpio.elf ) - add_dependencies(bootstrap.elf gen_sys_cpio) else() add_executable(bootstrap.elf ${deps} diff --git a/mkrtos_configs/aarch64_qemu_defconfig b/mkrtos_configs/aarch64_qemu_defconfig index 7a2a00410..fd2e7bd94 100644 --- a/mkrtos_configs/aarch64_qemu_defconfig +++ b/mkrtos_configs/aarch64_qemu_defconfig @@ -18,7 +18,7 @@ CONFIG_IRQ_REG_TAB_SIZE=288 CONFIG_REGION_NUM=8 CONFIG_OBJ_MAP_TAB_SIZE=32 CONFIG_OBJ_MAP_ENTRY_SIZE=170 -CONFIG_PRINTK_CACHE_SIZE=128 +CONFIG_PRINTK_CACHE_SIZE=512 # end of Knl config # @@ -124,3 +124,4 @@ CONFIG_THREAD_IPC_MSG_LEN=1024 CONFIG_THREAD_MAP_BUF_LEN=256 CONFIG_MSG_BUF_VADDR=0xE0000000 CONFIG_BOOT_FS_VADDR=0xE0001000 +CONFIG_PSCI=y diff --git a/mkrtos_knl/Kconfig b/mkrtos_knl/Kconfig index 43092199c..2619c834a 100644 --- a/mkrtos_knl/Kconfig +++ b/mkrtos_knl/Kconfig @@ -23,14 +23,15 @@ endif config PAGE_SHIFT int "page shift" default 9 + config PSCI + bool "support psci" + default n config SMP bool "support smp." default n -if SMP config CPU int "CPU Core number." default 1 -endif config THREAD_MSG_BUG_LEN int "thread msg buf size" default 128 diff --git a/mkrtos_knl/arch/aarch64/aarch64_ptregs.h b/mkrtos_knl/arch/aarch64/aarch64_ptregs.h deleted file mode 100644 index 207322217..000000000 --- a/mkrtos_knl/arch/aarch64/aarch64_ptregs.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -/* - * pt_regs栈框,用来保存中断现场或者异常现场 - * - * pt_regs栈框通常位于进程的内核栈的顶部。 - * pt_regs栈框通常位于进程的内核栈的顶部。 - * 而sp的栈顶通常 紧挨着 pt_regs栈框,在pt_regs栈框下方。 - * 保存内容: - * x0 ~ x30 通用寄存器 - * sp - * pc - * pstate - */ -typedef struct pt_regs -{ - unsigned long regs[31]; - unsigned long sp; - unsigned long pc; - unsigned long pstate; -} pt_regs_t; diff --git a/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c b/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c index 5d0d015b5..23b214acb 100644 --- a/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c +++ b/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.c @@ -9,43 +9,56 @@ * */ #include "arch.h" +#include "config.h" +#include "init.h" +#include "mk_sys.h" +#include "thread.h" #include "types.h" #include "util.h" -#include "init.h" -#include "config.h" -#include "thread.h" -#include "mk_sys.h" -#include #include -#include #include +#include #include #include #include +#include +#include + __ALIGN__(THREAD_BLOCK_SIZE) -static uint8_t thread_knl_stack[CONFIG_CPU][THREAD_BLOCK_SIZE] = {0}; -void *_estack = &thread_knl_stack[0] + THREAD_BLOCK_SIZE; +uint8_t thread_knl_stack[CONFIG_CPU][THREAD_BLOCK_SIZE] = {0}; +// void *_estack = &thread_knl_stack[0] + THREAD_BLOCK_SIZE; +static umword_t cpu_boot_cn = 0; static void other_cpu_boot(void); extern void _start(void); /** * 进行调度 */ -void to_sche(void) +void arch_to_sche(void) { + umword_t status; + + status = spinlock_lock(&arm_gicv2_get_global()->lock); gic2_set_pending(arm_gicv2_get_global(), SYSTICK_INTR_NO); - // sche_arch_sw_context(); + spinlock_set(&arm_gicv2_get_global()->lock, status); } /** * 进行一些系统的初始化 */ void sys_startup(void) { - timer_init(arch_get_current_cpu_id()); + cpu_boot_cn = 1; + cpu_ipi_init(); for (int i = 1; i < CONFIG_CPU; i++) { - cpu_start_to(i, thread_knl_stack[i], other_cpu_boot); + printk("sp:%lx.\n", &thread_knl_stack[i][0]); + cpu_start_to(i, &thread_knl_stack[i][0] + THREAD_BLOCK_SIZE - MWORD_BYTES, other_cpu_boot); +#if IS_ENABLED(CONFIG_PSCI) psci_cpu_on(i, (umword_t)_start); +#endif } + while (cpu_boot_cn < CONFIG_CPU) + ; + timer_init(arch_get_current_cpu_id()); } void sys_reset(void) { @@ -113,27 +126,29 @@ void arch_init(void) init_arm_hyp(); psci_init(); gic_init(arm_gicv2_get_global(), - 0x08000000, 0x8010000); /*TODO:*/ + GIC2_GICD_REG_BASE, GIC2_GICC_REG_BASE); } INIT_LOW_HARD(arch_init); static void arch_cpu_knl_init(void) { + cli(); init_arm_hyp(); - scheduler_init(); //!< 初始化其他cpu的调度队列 - gic_init(arm_gicv2_get_global(), 0x08000000, 0x8010000); knl_init_1(); + gic_init(arm_gicv2_get_global(), GIC2_GICD_REG_BASE, GIC2_GICC_REG_BASE); + cpu_ipi_init(); timer_init(arch_get_current_cpu_id()); + cpu_boot_cn++; + thread_sched(TRUE); + sti(); } static void other_cpu_boot(void) { - cli(); per_cpu_boot_mapping(FALSE); - mword_t elx = arch_get_currentel(); printk("cpuid %d run el%d.\n", arch_get_current_cpu_id(), elx); arch_cpu_knl_init(); - sti(); while (1) - ; + { + } } diff --git a/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h b/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h index da2498256..77ff7eddd 100755 --- a/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h +++ b/mkrtos_knl/arch/aarch64/aarch64_qemu/arch.h @@ -11,14 +11,23 @@ #pragma once #include "types.h" -#include #include #include #include +#include #define ARCH_WORD_SIZE 64 #define SYSTICK_INTR_NO 30 -#define LOG_INTR_NO 33 +#define LOG_INTR_NO 33 + +#define CPU0_MASK (1 << 0) +#define CPU1_MASK (1 << 1) +#define CPU2_MASK (1 << 2) +#define CPU3_MASK (1 << 3) +#define CPU4_MASK (1 << 4) +#define CPU5_MASK (1 << 5) +#define CPU6_MASK (1 << 6) +#define CPU7_MASK (1 << 7) /// @brief 线程信息 typedef struct @@ -28,7 +37,8 @@ typedef struct umword_t lr; umword_t pc; } pf_s_t; -typedef struct pf { +typedef struct pf +{ struct { umword_t regs[31]; //!< 基础寄存器 @@ -46,7 +56,8 @@ typedef struct pf { umword_t stackframe[2]; } pf_t; -typedef struct sp_info { +typedef struct sp_info +{ umword_t x19; umword_t x20; umword_t x21; @@ -71,26 +82,42 @@ typedef struct sp_info { #define _dsb(ins) \ asm volatile("dsb " #ins : : : "memory") -#define __arch_getl(a) (*(volatile unsigned int *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) #define __arch_putl(v, a) (*(volatile unsigned int *)(a) = (v)) #define __iormb() _barrier() #define __iowmb() _barrier() -#define readl(c) ({ unsigned int __v = __arch_getl(c); __iormb(); __v; }) +#define readl(c) ({ unsigned int __v = __arch_getl(c); __iormb(); __v; }) #define writel(v, c) ({ unsigned int __v = v; __iowmb(); __arch_putl(__v,c); }) -#define read_reg(addr) (*((volatile umword_t *)(addr))) +#define read_reg(addr) \ + ({ \ + unsigned long _val; \ + \ + _barrier(); \ + _val = (*((volatile umword_t *)(addr))); \ + _val; \ + }) #define write_reg(addr, data) \ - do { \ + do \ + { \ _barrier(); \ (*((volatile umword_t *)(addr))) = data; \ _barrier(); \ } while (0) -#define read_reg32(addr) (*((volatile uint32_t *)(addr))) +#define read_reg32(addr) \ + ({ \ + unsigned long _val; \ + \ + _barrier(); \ + _val = (*((volatile umword_t *)(addr))); \ + _val; \ + }) #define write_reg32(addr, data) \ - do { \ + do \ + { \ _barrier(); \ (*((volatile uint32_t *)(addr))) = (uint32_t)data; \ _barrier(); \ @@ -126,19 +153,21 @@ static inline int arch_get_current_cpu_id(void) ({/*TODO:*/ \ 0}) -void to_sche(void); +void arch_to_sche(void); #define get_sp() ( \ { \ mword_t sp; \ - do { \ + do \ + { \ asm volatile("mov %0, sp" : "=r"(sp)); \ } while (0); \ sp; \ }) #define set_sp(sp) ( \ { \ - do { \ + do \ + { \ asm volatile("mov sp, %0" : : "r"(sp)); \ } while (0); \ }) @@ -171,7 +200,8 @@ void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio); * 开中断 */ #define sti() \ - do { \ + do \ + { \ asm volatile( \ "msr daifclr, #3" \ : \ @@ -183,7 +213,8 @@ void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio); * 关中断 */ #define cli() \ - do { \ + do \ + { \ asm volatile( \ "msr daifset, #3" \ : \ @@ -212,3 +243,5 @@ void sys_reset(void); umword_t sys_tick_cnt_get(void); uint32_t arch_get_sys_clk(void); + +#include diff --git a/mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S b/mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S index 50b0e7a2d..f2f257f9c 100644 --- a/mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S +++ b/mkrtos_knl/arch/aarch64/aarch64_qemu/entry.S @@ -13,7 +13,8 @@ string1: .globl sp_addr .section ".data.boot" sp_addr: - .quad per_cpu_stack + THREAD_BLOCK_SIZE - 8 - PT_REGS_SIZE //pt regs is 320 bytes. + .quad thread_knl_stack + THREAD_BLOCK_SIZE - 8//pt regs is 320 bytes. + .align 3 .globl cpio_images .section ".data.boot" @@ -24,13 +25,13 @@ cpio_images: .global cpu_jump_addr .section ".data.boot" cpu_jump_addr: - .zero (32) //TODO: cpu_num*MWORD_BYTES + .zero (CONFIG_CPU * 8) .align 3 .global per_cpu_stack_addr .section ".data.boot" per_cpu_stack_addr: - .zero (32) //TODO: cpu_num*MWORD_BYTES + .zero (CONFIG_CPU * 8) .section ".text.boot" .globl _start diff --git a/mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S b/mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S index b1b0f6025..9763e4fea 100755 --- a/mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S +++ b/mkrtos_knl/arch/aarch64/aarch64_qemu/vector.S @@ -87,10 +87,7 @@ 处理无效的异常向量 */ .macro inv_entry el, reason - //kernel_entry el - mov x0, sp - mov x1, #\reason - mrs x2, esr_el2 + kernel_entry el b bad_mode .endm @@ -157,13 +154,13 @@ el1_sync: b ret_to_user el2_sync_invalid: - inv_entry 1, BAD_SYNC + inv_entry 2, BAD_SYNC el2_irq_invalid: - inv_entry 1, BAD_IRQ + inv_entry 2, BAD_IRQ el2_fiq_invalid: - inv_entry 1, BAD_FIQ + inv_entry 2, BAD_FIQ el2_error_invalid: - inv_entry 1, BAD_ERROR + inv_entry 2, BAD_ERROR el1_irq_invalid: inv_entry 1, BAD_IRQ el1_fiq_invalid: @@ -192,12 +189,6 @@ el2_irq: bl entry_handler kernel_exit 2 - -.global trigger_alignment -trigger_alignment: - ldr x0, =0x80002 - str wzr, [x0] - /* 对于用户进程,暂时还没实现 */ @@ -205,7 +196,6 @@ trigger_alignment: .global ret_to_user ret_to_user: kernel_exit 2 - //inv_entry 0, BAD_ERROR /* 对于内核线程: x19保存了进程回调函数的入口 diff --git a/mkrtos_knl/arch/aarch64/arm_gicv2.h b/mkrtos_knl/arch/aarch64/arm_gicv2.h index 2f344ea35..3526d2848 100644 --- a/mkrtos_knl/arch/aarch64/arm_gicv2.h +++ b/mkrtos_knl/arch/aarch64/arm_gicv2.h @@ -5,6 +5,7 @@ #include #include #include +#include // #include /* * ID0-ID15,分配给SGI (一般会将0-7给REE,8-15给TEE) @@ -20,8 +21,11 @@ typedef struct gic addr_t disp_base_addr; //!< 分发器起始地址 addr_t inter_base_addr; //!< 接口起始地址 + spinlock_t lock; } gic_t; +#define GIC2_GICD_REG_BASE 0x08000000 +#define GIC2_GICC_REG_BASE 0x08010000 // #define GIC2_BASE (0xFF840000) // #define GIC2_GICD_BASE (GIC2_BASE + 0x1000) @@ -55,18 +59,12 @@ typedef struct gic #define MAX_INTR_NO 1020 -static inline void gic2_set_disp_cpu(gic_t *irq, uint64_t cpu_mask) +static inline void gic2_set_sgir(gic_t *irq, uint64_t cpu_mask) { write_reg32(GICD_SGIR(irq->disp_base_addr), read_reg32(GICD_SGIR(irq->disp_base_addr)) | ((cpu_mask & 0xff) << 16UL)); } -static inline void gic2_clear_disp_cpu(gic_t *irq, uint8_t cpu_mask) -{ - write_reg32(GICD_SGIR(irq->disp_base_addr), - read_reg32(GICD_SGIR(irq->disp_base_addr)) & - ((~(cpu_mask & 0xff)) << 16UL)); -} static inline void gic2_set_unmask(gic_t *irq, uint64_t inx) { assert(inx < MAX_INTR_NO); @@ -121,6 +119,17 @@ static inline void gic2_clear_active(gic_t *irq, uint64_t inx) tmp |= (1) << bit_inx; write_reg32((uint32_t *)addr, tmp); } +static inline void gic2_sgi_set_pending(gic_t *irq, uint64_t inx, uint8_t cpu_mask) +{ + assert(inx < 16); + void *addr = (void *)(GICD_SPENDSGIRn(irq->disp_base_addr) + (inx >> 2)); + uint32_t tmp = read_reg32(addr); + uint32_t bit_inx = (inx % 4) << 3; + + tmp &= (~0xff) << bit_inx; + tmp |= cpu_mask << bit_inx; + write_reg32((uint32_t *)addr, tmp); +} static inline void gic2_set_pending(gic_t *irq, uint64_t inx) { assert(inx < MAX_INTR_NO); @@ -227,11 +236,14 @@ static inline void gic_dist_init(gic_t *irq) { gic_disable(irq); - for (int i = 32; i < irq->irqs_number; i++) + if (arch_get_current_cpu_id() == 0) { - gic2_set_unmask(irq, i); - gic2_set_edge_mode(irq, i, 0); - gic2_clear_active(irq, i); + for (int i = 32; i < irq->irqs_number; i++) + { + gic2_set_unmask(irq, i); + gic2_set_edge_mode(irq, i, 0); + gic2_clear_active(irq, i); + } } for (int i = 0; i < 16; i++) { @@ -242,13 +254,15 @@ static inline void gic_dist_init(gic_t *irq) } static inline void gic_inter_init(gic_t *irq) { - - for (int i = 0; i < 32; i++) + // if (arch_get_current_cpu_id() == 0) { - gic2_set_prio(irq, i, 0xa0); + for (int i = 0; i < 32; i++) + { + gic2_set_prio(irq, i, 0); + } } - write_reg32(GICC_PMR(irq->inter_base_addr), 0xf0UL); + gic2_cpu_enable(irq); } static inline void gic2_eoi_irq(gic_t *irq, int inx) @@ -279,20 +293,3 @@ static inline uint32_t gicv2_get_irqnr(gic_t *m_gic) return irqnr; } -// static inline void gic_handle_irq(void) -// { -// extern gic_t m_irq; - -// do -// { -// uint32_t irqstat = -// read_reg32(GICC_IAR(m_irq.inter_base_addr)); -// uint32_t irqnr = irqstat & 0x3ff; - -// if (irqnr == 30) -// handle_timer_irq(); - -// gic2_eoi_irq(&m_irq, irqnr); - -// } while (0); -// } diff --git a/mkrtos_knl/arch/aarch64/cache.S b/mkrtos_knl/arch/aarch64/cache.S new file mode 100644 index 000000000..6de8c4057 --- /dev/null +++ b/mkrtos_knl/arch/aarch64/cache.S @@ -0,0 +1,36 @@ + +.global get_cache_line_size +get_cache_line_size: + mrs x0, ctr_el0 + ubfm x0, x0, #16, #19 + mov x1, #4 + lsl x0, x1, x0 + ret + +/* + flush_cache_range(start, end) + */ +.global flush_cache_range +flush_cache_range: + mov x7, x30 + + mov x8, x0 + mov x9, x1 + + bl get_cache_line_size + sub x3, x0, #1 + bic x4, x8, x3 +1: + dc civac, x4 + add x4, x4, x0 + cmp x4, x9 + b.lo 1b + + dsb ish + + mov x30, x7 + ret + + + + diff --git a/mkrtos_knl/arch/aarch64/exception.c b/mkrtos_knl/arch/aarch64/exception.c index 4ab7a4811..0c6a75a97 100644 --- a/mkrtos_knl/arch/aarch64/exception.c +++ b/mkrtos_knl/arch/aarch64/exception.c @@ -1,25 +1,29 @@ #include #include +#include static const char *const bad_mode_handler[] = { "Sync Abort", "IRQ", "FIQ", "SError"}; - -void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) +static void dump_stack(umword_t pc, umword_t x29) { - printk("Bad mode for %s handler detected, esr=0x%x ec=0x%x far_el2=0x%lx\n", - bad_mode_handler[reason], esr, esr >> 26, read_sysreg(far_el2)); - - mword_t x29; - - asm volatile("mov %0, x29" : "=r"(x29)); - printk("x29 %lx.\n", x29); - for (size_t i = 0; i < 5; i++) + uint64_t result[5]; + printk("pc:0x%x x29:0x%x\n", pc, x29); + for (size_t i = 0; i < sizeof(result) / sizeof(umword_t); i++) { - x29 = *(long *)(x29); - printk("kernel sync instruction addr is %lx\n", *(long *)(x29 + 8)); + result[i] = (*(umword_t *)(x29 + 8)) - 4; + x29 = *(umword_t *)(x29); } + printk("knl pf stack: 0x%x,0x%x,0x%x,0x%x,0x%x\n", result[0], result[1], result[2], result[3], result[4]); +} +void bad_mode(entry_frame_t *regs) +{ + printk("**********panic*************\n"); + // printk("Bad mode for %s handler detected, esr=0x%x ec=0x%x far_el2=0x%lx\n", + // bad_mode_handler[reason], esr, esr >> 26, read_sysreg(far_el2)); + + dump_stack(regs->pc, regs->regs[29]); while (1) ; } diff --git a/mkrtos_knl/arch/aarch64/ipi.c b/mkrtos_knl/arch/aarch64/ipi.c new file mode 100644 index 000000000..2d426c6d7 --- /dev/null +++ b/mkrtos_knl/arch/aarch64/ipi.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ipi_msg_head; +typedef struct ipi_msg_head ipi_msg_head_t; + +typedef struct ipi_msg_head +{ + slist_head_t msg_queue; + spinlock_t lock; +} ipi_msg_head_t; + +static PER_CPU(ipi_msg_head_t, ipi_msg_head); + +void cpu_ipi_to(uint8_t cpu_mask) +{ + mword_t status = spinlock_lock(&arm_gicv2_get_global()->lock); + + gic2_set_sgir(arm_gicv2_get_global(), cpu_mask); + spinlock_set(&arm_gicv2_get_global()->lock, status); +} +void cpu_ipi_to_msg(uint8_t cpu_mask, ipi_msg_t *msg, ipi_action_t act) +{ + assert(msg); + assert(msg->cb); + assert(cpulock_get_status()); + assert(!(cpu_mask & (1 << arch_get_current_cpu_id()))); //!< 不能给自己发ipi,否则可能死锁 + assert(!slist_in_list(&msg->node)); + atomic_set(&msg->flags, 0); + + for (int i = 0; i < CONFIG_CPU; i++) + { + if (!(cpu_mask & (1 << i))) + { + continue; + } + ipi_msg_head_t *head = pre_cpu_get_var_cpu(i, &ipi_msg_head); + umword_t status = spinlock_lock(&head->lock); + + slist_add_append(&head->msg_queue, &msg->node); + + gic2_set_sgir(arm_gicv2_get_global(), (1 << i)); //!< 发送软中断 + spinlock_set(&head->lock, status); + // preemption(); + // thread_sched(TRUE); + if (act == IPI_CALL) + { + do + { + // if (&thread_get_current()->ipi_msg_node != msg) + { + thread_sched(TRUE); + // arch_to_sche(); + // preemption(); + } + } while (atomic_read(&msg->flags) == 0); + } + } +} +/** + * 两个核相互发送消息可能会死锁 + */ +void cpu_ipi_handler(irq_entry_t *entry) +{ + + int cur_cpu = arch_get_current_cpu_id(); + + ipi_msg_head_t *head = pre_cpu_get_var_cpu(cur_cpu, &ipi_msg_head); + + umword_t status = spinlock_lock(&head->lock); + ipi_msg_t *pos; + + slist_foreach_not_next(pos, &head->msg_queue, node) + { + ipi_msg_t *next = slist_next_entry(pos, &head->msg_queue, node); + slist_del(&pos->node); + + assert(pos->cb); + pos->ret = pos->cb(pos); + atomic_set(&pos->flags, 1); + pos = next; + } + + spinlock_set(&head->lock, status); + gic2_eoi_irq(arm_gicv2_get_global(), entry->inx); +} + +void cpu_ipi_init(void) +{ + ipi_msg_head_t *head = pre_cpu_get_current_cpu_var(&ipi_msg_head); + + slist_init(&head->msg_queue); + spinlock_init(&head->lock); + irq_alloc(0, NULL, cpu_ipi_handler); + gic2_set_prio(arm_gicv2_get_global(), 0, 1); + // FIXME:目前IPI的中断优先级必须比tiemr的低,不然可能会死锁。 +} diff --git a/mkrtos_knl/arch/aarch64/ipi.h b/mkrtos_knl/arch/aarch64/ipi.h new file mode 100644 index 000000000..f53e26981 --- /dev/null +++ b/mkrtos_knl/arch/aarch64/ipi.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include + +typedef enum ipi_action +{ + IPI_SEND, //!< 发送消息 + IPI_CALL, //!< 调用 +} ipi_action_t; + +struct ipi_msg; +typedef struct ipi_msg ipi_msg_t; +typedef int (*ipi_cb_func)(ipi_msg_t *head); + +typedef struct ipi_msg +{ + slist_head_t node; //!< 消息在内存中的节点 + mword_t ret; //!< 返回值 + umword_t msg; //!< 第一个消息 + umword_t msg2; //!< 第二个消息 + umword_t msg3; + ipi_cb_func cb; //!< ipi调用的回调函数,这个函数在目标cpu中执行 + umword_t th_time_cn; //!< 时间戳,用于判断线程是否完成切换 + atomic64_t flags; //!< 用于判断目标cpu是否执行完成 +} ipi_msg_t; + +void cpu_ipi_to(uint8_t cpu_mask); +void cpu_ipi_init(void); +void cpu_ipi_to_msg(uint8_t cpu_mask, ipi_msg_t *msg, ipi_action_t act); +void cpu_ipi_check(void); diff --git a/mkrtos_knl/arch/aarch64/mmu.c b/mkrtos_knl/arch/aarch64/mmu.c index d180c1573..4b16f78e5 100644 --- a/mkrtos_knl/arch/aarch64/mmu.c +++ b/mkrtos_knl/arch/aarch64/mmu.c @@ -15,7 +15,7 @@ #define TEXT_BOOT_SECTION ".text.boot" #define TCR_DEFAULT (((1UL) << 31) | (1UL << 23) | \ - (3UL << 12) | (1UL << 10) | (1UL << 8) | ((64UL - CONFIG_ARM64_VA_BITS))) + (3UL << 12) | (1UL << 10) | (1UL << 8) | ((64UL - CONFIG_ARM64_VA_BITS)) | (1UL << 36)) extern char _text_boot[]; extern char _etext_boot[]; diff --git a/mkrtos_knl/arch/aarch64/mmu.h b/mkrtos_knl/arch/aarch64/mmu.h index 81e284028..1e6fef15f 100644 --- a/mkrtos_knl/arch/aarch64/mmu.h +++ b/mkrtos_knl/arch/aarch64/mmu.h @@ -15,10 +15,6 @@ static inline umword_t vpage_attrs_to_page_attrs(enum vpage_prot_attrs attrs) to_attrs = PTE_SHARED | PTE_TYPE_PAGE | PTE_ATTRINDX(MT_NORMAL) | PTE_AF; - if (attrs & VPAGE_PROT_UNCACHE) - { - /*TODO:设置无缓存属性*/ - } if (!(attrs & VPAGE_PROT_IN_KNL)) { to_attrs |= PTE_NG; diff --git a/mkrtos_knl/arch/aarch64/psci.c b/mkrtos_knl/arch/aarch64/psci.c index 105e1de14..fb5f27e8a 100644 --- a/mkrtos_knl/arch/aarch64/psci.c +++ b/mkrtos_knl/arch/aarch64/psci.c @@ -45,7 +45,7 @@ static umword_t psci_func(umword_t func_id) } } -static inline void psci_call( + __attribute__((optimize(0))) static inline void psci_call( umword_t func_id, umword_t res[4], umword_t arg0, diff --git a/mkrtos_knl/arch/aarch64/sche.s b/mkrtos_knl/arch/aarch64/sche.s deleted file mode 100644 index ddc151269..000000000 --- a/mkrtos_knl/arch/aarch64/sche.s +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - - -/* 进程切换: 保存prev进程的上下文,并且恢复next进程 -的上下文 - cpu_switch_to(struct cpu_context *prev, - struct cpu_context *next); - -需要保存的上下文: x19 ~ x29, sp, lr -保存到进程的task_struct->cpu_context - */ -.align -.global cpu_switch_to -cpu_switch_to: - mov x8, x0 - mov x9, sp - stp x19, x20, [x8], #16 - stp x21, x22, [x8], #16 - stp x23, x24, [x8], #16 - stp x25, x26, [x8], #16 - stp x27, x28, [x8], #16 - stp x29, x9, [x8], #16 - str lr, [x8] - - mov x8, x1 - ldp x19, x20, [x8], #16 - ldp x21, x22, [x8], #16 - ldp x23, x24, [x8], #16 - ldp x25, x26, [x8], #16 - ldp x27, x28, [x8], #16 - ldp x29, x9, [x8], #16 - ldr lr, [x8] - mov sp, x9 - ret diff --git a/mkrtos_knl/arch/aarch64/sche_arch.c b/mkrtos_knl/arch/aarch64/sche_arch.c index 5752c1728..e7d5e79f1 100644 --- a/mkrtos_knl/arch/aarch64/sche_arch.c +++ b/mkrtos_knl/arch/aarch64/sche_arch.c @@ -11,15 +11,21 @@ static void sw_mmu(thread_t *next_thread) task_t *next_task = (task_t *)(next_thread->task); umword_t p_next_dir = (umword_t)mm_space_get_pdir(&next_task->mm_space)->dir; + assert(next_task); if (p_curr_dir != p_next_dir) { - _dsb(sy); - write_sysreg(p_next_dir | (next_task->mm_space.asid << 48) /*TODO:*/, vttbr_el2); // 切换用户态页表 - _dsb(ish); - _isb(); - // printk("asid:%lx.\n", (next_task->mm_space.asid << 48)); - // asm volatile("ic iallu"); + assert(get_sp()); + // printk("ttbr:0x%lx\n", p_next_dir | (next_task->mm_space.asid << 48)); + // _dsb(sy); + write_sysreg(p_next_dir | (next_task->mm_space.asid << 48) /*TODO:*/, vttbr_el2); // 切换用户态页表 + _isb(); + // asm volatile("ic iallu"); + // _dsb(ish); + + // asm volatile("tlbi vmalle1"); + // _dsb(ish); + // _isb(); // mword_t vttbr; // // FIXME: could do a compare for the current VMID before loading // // the vttbr and the isb @@ -42,15 +48,25 @@ static void sw_mmu(thread_t *next_thread) // "memory"); } } + void sche_arch_sw_context(void) { + sp_info_t *pev_sp; scheduler_t *sche = scheduler_get_current(); thread_t *cur_th = thread_get_current(); + assert(cur_th->magic == THREAD_MAGIC); + assert(sche->cur_sche); sched_t *next = sche->cur_sche; thread_t *next_th = container_of(next, thread_t, sche); + assert(next_th->magic == THREAD_MAGIC); // 这里切换页表 sw_mmu(next_th); - // 变成了next的sp - cpu_switch_to(&cur_th->sp, &next_th->sp); + assert(arch_get_current_cpu_id() == cur_th->cpu); + // printk("0 sw cpu:%d next_th:0x%lx\n", arch_get_current_cpu_id(), cur_th); + // 切换上下文 + pev_sp = cpu_switch_to(&cur_th->sp, &next_th->sp); + cur_th = container_of(pev_sp, thread_t, sp); + atomic_inc(&cur_th->time_count);/**FIXME:临时处理,代表切换完成*/ + // printk("sw cpu:%d next_th:0x%lx\n", arch_get_current_cpu_id(), cur_th); } diff --git a/mkrtos_knl/arch/aarch64/sche_arch.h b/mkrtos_knl/arch/aarch64/sche_arch.h index f69e06358..d04468a26 100644 --- a/mkrtos_knl/arch/aarch64/sche_arch.h +++ b/mkrtos_knl/arch/aarch64/sche_arch.h @@ -1,6 +1,5 @@ #pragma once -#include -void cpu_switch_to(sp_info_t *prev, +sp_info_t *cpu_switch_to(sp_info_t *prev, sp_info_t *next); void sche_arch_sw_context(void); diff --git a/mkrtos_knl/arch/aarch64/spin_table.c b/mkrtos_knl/arch/aarch64/spin_table.c index d825f683b..b84eebf3b 100644 --- a/mkrtos_knl/arch/aarch64/spin_table.c +++ b/mkrtos_knl/arch/aarch64/spin_table.c @@ -11,18 +11,8 @@ extern mword_t cpu_jump_addr[SYS_CPU_NUM]; extern mword_t per_cpu_stack_addr[SYS_CPU_NUM]; -// 每个cpu的栈指针 -SECTION(DATA_BOOT_SECTION) -__ALIGN__(PAGE_SIZE) -mword_t per_cpu_stack[SYS_CPU_NUM][THREAD_BLOCK_SIZE / MWORD_BYTES]; - -void *get_cpu_stack(int cpu_inx) -{ - return (void *)per_cpu_stack[cpu_inx]; -} - void SECTION(TEXT_BOOT_SECTION) cpu_start_to(int cpu_id, void *stack, void *(fn)(void)) { - per_cpu_stack_addr[cpu_id] = ((addr_t)stack) + THREAD_BLOCK_SIZE - MWORD_BYTES - PT_REGS_SIZE; + per_cpu_stack_addr[cpu_id] = ((addr_t)stack); cpu_jump_addr[cpu_id] = (mword_t)fn; } diff --git a/mkrtos_knl/arch/aarch64/spinlock_arch.c b/mkrtos_knl/arch/aarch64/spinlock_arch.c index 2309ff49d..ccbc95dde 100644 --- a/mkrtos_knl/arch/aarch64/spinlock_arch.c +++ b/mkrtos_knl/arch/aarch64/spinlock_arch.c @@ -1,6 +1,6 @@ -#include #include +#include void spinlock_lock_arch(spinlock_t *lock) { @@ -11,18 +11,23 @@ void spinlock_lock_arch(spinlock_t *lock) "sevl\n" "prfm pstl1keep, [%[lock]]\n" "1: wfe\n" - "ldaxr %x[dummy],[%[lock]]\n" - "cbnz %x[dummy],1b\n" - "orr %x[tmp],%x[dummy],#1\n" - "stxr %w[dummy], %x[tmp], [%[lock]]\n" - "cbnz %w[dummy],1b\n" - : [dummy] "=&r"(dummy), [tmp] "=&r"(tmp), "+m"(lock->val) + "ldaxr %x[d],[%[lock]]\n" + "tst %x[d],#2\n" + "bne 1b\n" + "orr %x[tmp],%x[d],#2\n" + "stxr %w[d], %x[tmp], [%[lock]]\n" + "cbnz %w[d],1b\n" + : [d] "=&r"(dummy), [tmp] "=&r"(tmp), "+m"(lock->val) : [lock] "r"(&lock->val) : "cc"); } void spinlock_unlock_arch(spinlock_t *lock) { + umword_t tmp; + asm volatile( - "stlr wzr, %[lock]" - : [lock] "=Q"(lock->val)); + "ldr %x[tmp], %[lock]\n" + "bic %x[tmp], %x[tmp], #2\n" + "stlr %x[tmp], %[lock]\n" + : [lock] "=Q"(lock->val), [tmp] "=&r"(tmp)); } diff --git a/mkrtos_knl/arch/cortex-m3/atomics.c b/mkrtos_knl/arch/cortex-m3/atomics.c new file mode 100644 index 000000000..8b6588b59 --- /dev/null +++ b/mkrtos_knl/arch/cortex-m3/atomics.c @@ -0,0 +1,72 @@ + +#include +#include +#include +bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new) +{ + bool_t ret = FALSE; + mword_t status = cpulock_lock(); + if (*v == old) { + *v = new; + ret = TRUE; + } + cpulock_set(status); + return ret; +} +void atomic_and(umword_t *l, umword_t val) +{ + mword_t status = cpulock_lock(); + *l &= val; + cpulock_set(status); +} +umword_t atomic_and_return(umword_t *l, umword_t val) +{ + umword_t ret; + mword_t status = cpulock_lock(); + *l &= val; + ret = !!(*l); + cpulock_set(status); + return ret; +} +void atomic_or(umword_t *l, umword_t val) +{ + mword_t status = cpulock_lock(); + *l |= val; + cpulock_set(status); +} +umword_t atomic_sub_return(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + v->counter -= i; + ret = (v->counter); + cpulock_set(status); + return ret; +} +umword_t atomic_add_return(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + v->counter += i; + ret = (v->counter); + cpulock_set(status); + return ret; +} +umword_t atomic_fetch_and(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + ret = (v->counter); + v->counter &= i; + cpulock_set(status); + return ret; +} +umword_t atomic_fetch_or(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + ret = (v->counter); + v->counter |= i; + cpulock_set(status); + return ret; +} diff --git a/mkrtos_knl/arch/cortex-m3/atomics.h b/mkrtos_knl/arch/cortex-m3/atomics.h new file mode 100644 index 000000000..abba94665 --- /dev/null +++ b/mkrtos_knl/arch/cortex-m3/atomics.h @@ -0,0 +1,67 @@ +#pragma once +#include +typedef struct atomic64 +{ + umword_t counter; +} atomic_t; + +#define ATOMIC64_INIT(i) ((atomic_t){(i)}) + +#define atomic_read(v) (*(volatile umword_t *)(&(v)->counter)) +#define atomic_set(v, i) (((v)->counter) = i) + +bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new); +void atomic_and(umword_t *l, umword_t val); +umword_t atomic_and_return(umword_t *l, umword_t val); +void atomic_or(umword_t *l, umword_t val); +umword_t atomic_sub_return(umword_t i, atomic_t *v); +umword_t atomic_add_return(umword_t i, atomic_t *v); +umword_t atomic_fetch_and(umword_t i, atomic_t *v); +umword_t atomic_fetch_or(umword_t i, atomic_t *v); + +static inline void atomic_add(umword_t i, atomic_t *v) +{ + atomic_add_return(i, v); +} +static inline void atomic_sub(umword_t i, atomic_t *v) +{ + atomic_sub_return(i, v); +} +static inline void atomic_inc(atomic_t *v) +{ + atomic_add_return(1, v); +} +static inline void atomic_dec(atomic_t *v) +{ + atomic_sub_return(1, v); +} +static inline umword_t atomic_inc_return(atomic_t *v) +{ + return atomic_add_return(1, v); +} +static inline umword_t atomic_dec_return(atomic_t *v) +{ + return atomic_sub_return(1, v); +} + +static inline umword_t atomic_add_and_test(umword_t i, atomic_t *v) +{ + return atomic_add_return(i, v) == 0; +} + +static inline umword_t atomic_sub_and_test(umword_t i, atomic_t *v) +{ + return atomic_sub_return(i, v) == 0; +} +static inline umword_t atomic_inc_and_test(atomic_t *v) +{ + return atomic_inc_return(v) == 0; +} +static inline umword_t atomic_dec_and_test(atomic_t *v) +{ + return atomic_dec_return(v) == 0; +} +static inline umword_t atomic_add_negative(umword_t i, atomic_t *v) +{ + return (umword_t)atomic_add_return(i, v) < 0; +} diff --git a/mkrtos_knl/arch/cortex-m3/link.lds b/mkrtos_knl/arch/cortex-m3/link.lds index 5985df8f7..b20bf95e5 100644 --- a/mkrtos_knl/arch/cortex-m3/link.lds +++ b/mkrtos_knl/arch/cortex-m3/link.lds @@ -67,6 +67,10 @@ SECTIONS _sdata = .; *(.data) *(.data*) + . = ALIGN(0x4); + _pre_cpu_data_start = .; + KEEP (*(.data.per_cpu)) + _pre_cpu_data_end = .; . = ALIGN(4); _edata = .; } >RAM AT> FLASH diff --git a/mkrtos_knl/arch/cortex-m3/link.lds.S b/mkrtos_knl/arch/cortex-m3/link.lds.S index 860eded91..fa3879631 100644 --- a/mkrtos_knl/arch/cortex-m3/link.lds.S +++ b/mkrtos_knl/arch/cortex-m3/link.lds.S @@ -89,6 +89,11 @@ SECTIONS *(.data) /* .data sections */ *(.data*) /* .data* sections */ + . = ALIGN(0x4); + _pre_cpu_data_start = .; + KEEP (*(.data.per_cpu)) + _pre_cpu_data_end = .; + . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH diff --git a/mkrtos_knl/arch/cortex-m3/sche.S b/mkrtos_knl/arch/cortex-m3/sche.S index 2b89ce385..827b64b38 100755 --- a/mkrtos_knl/arch/cortex-m3/sche.S +++ b/mkrtos_knl/arch/cortex-m3/sche.S @@ -3,7 +3,7 @@ .thumb .global mpu_switch_to -.global sched_reset +.global scheduler .global PendSV_Handler .type PendSV_Handler, %function @@ -22,7 +22,7 @@ PendSV_Handler: mov r2, lr push {r4} - ldr r4, =sched_reset + ldr r4, =scheduler ldr r4, [r4] //! psp为零时,立刻调度一次 CBZ r4, thread_sche diff --git a/mkrtos_knl/arch/cortex-m3/sched_arch.c b/mkrtos_knl/arch/cortex-m3/sched_arch.c index 09d0528d4..2a572de94 100644 --- a/mkrtos_knl/arch/cortex-m3/sched_arch.c +++ b/mkrtos_knl/arch/cortex-m3/sched_arch.c @@ -13,13 +13,13 @@ sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type) assert(next_th->magic == THREAD_MAGIC); - if (sched_reset) + if (sche->sched_reset) { thread_t *cur_th = thread_get_current(); cur_th->sp.knl_sp = ksp; cur_th->sp.user_sp = usp; cur_th->sp.sp_type = sp_type; } - sched_reset = 1; + sche->sched_reset = 1; return &next_th->sp; } diff --git a/mkrtos_knl/arch/cortex-m3/stm32f1/arch.c b/mkrtos_knl/arch/cortex-m3/stm32f1/arch.c index 6cc041a8d..06bc9512e 100644 --- a/mkrtos_knl/arch/cortex-m3/stm32f1/arch.c +++ b/mkrtos_knl/arch/cortex-m3/stm32f1/arch.c @@ -24,7 +24,7 @@ void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE; #define REG0_ADDR 0xE000ED22 #define REG1_ADDR 0xE000ED04 -void to_sche(void) +void arch_to_sche(void) { // 开启pensv中断 write_reg(REG1_ADDR, 0x10000000); diff --git a/mkrtos_knl/arch/cortex-m3/stm32f1/arch.h b/mkrtos_knl/arch/cortex-m3/stm32f1/arch.h index b5846746a..dd81a7cd1 100755 --- a/mkrtos_knl/arch/cortex-m3/stm32f1/arch.h +++ b/mkrtos_knl/arch/cortex-m3/stm32f1/arch.h @@ -70,7 +70,7 @@ typedef struct sp_info ((ret & 0x4) ? 0 : 1); \ }) -void to_sche(void); +void arch_to_sche(void); static inline umword_t arch_get_sp(void) { @@ -111,7 +111,10 @@ static inline umword_t arch_get_user_sp(void) void arch_disable_irq(int inx); void arch_enable_irq(int inx); void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio); - +static inline int arch_get_current_cpu_id(void) +{ + return 0; +} #define sti() \ do \ { \ diff --git a/mkrtos_knl/arch/cortex-m3/stm32f2/arch.c b/mkrtos_knl/arch/cortex-m3/stm32f2/arch.c index 6cc041a8d..06bc9512e 100644 --- a/mkrtos_knl/arch/cortex-m3/stm32f2/arch.c +++ b/mkrtos_knl/arch/cortex-m3/stm32f2/arch.c @@ -24,7 +24,7 @@ void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE; #define REG0_ADDR 0xE000ED22 #define REG1_ADDR 0xE000ED04 -void to_sche(void) +void arch_to_sche(void) { // 开启pensv中断 write_reg(REG1_ADDR, 0x10000000); diff --git a/mkrtos_knl/arch/cortex-m3/stm32f2/arch.h b/mkrtos_knl/arch/cortex-m3/stm32f2/arch.h index c779473b6..25ec60bca 100755 --- a/mkrtos_knl/arch/cortex-m3/stm32f2/arch.h +++ b/mkrtos_knl/arch/cortex-m3/stm32f2/arch.h @@ -71,7 +71,7 @@ typedef struct sp_info ((ret & 0x4) ? 0 : 1); \ }) -void to_sche(void); +void arch_to_sche(void); static inline umword_t arch_get_sp(void) { @@ -112,7 +112,10 @@ static inline umword_t arch_get_user_sp(void) void arch_disable_irq(int inx); void arch_enable_irq(int inx); void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio); - +static inline int arch_get_current_cpu_id(void) +{ + return 0; +} #define sti() \ do \ { \ diff --git a/mkrtos_knl/arch/cortex-m33/atomics.c b/mkrtos_knl/arch/cortex-m33/atomics.c new file mode 100644 index 000000000..8b6588b59 --- /dev/null +++ b/mkrtos_knl/arch/cortex-m33/atomics.c @@ -0,0 +1,72 @@ + +#include +#include +#include +bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new) +{ + bool_t ret = FALSE; + mword_t status = cpulock_lock(); + if (*v == old) { + *v = new; + ret = TRUE; + } + cpulock_set(status); + return ret; +} +void atomic_and(umword_t *l, umword_t val) +{ + mword_t status = cpulock_lock(); + *l &= val; + cpulock_set(status); +} +umword_t atomic_and_return(umword_t *l, umword_t val) +{ + umword_t ret; + mword_t status = cpulock_lock(); + *l &= val; + ret = !!(*l); + cpulock_set(status); + return ret; +} +void atomic_or(umword_t *l, umword_t val) +{ + mword_t status = cpulock_lock(); + *l |= val; + cpulock_set(status); +} +umword_t atomic_sub_return(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + v->counter -= i; + ret = (v->counter); + cpulock_set(status); + return ret; +} +umword_t atomic_add_return(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + v->counter += i; + ret = (v->counter); + cpulock_set(status); + return ret; +} +umword_t atomic_fetch_and(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + ret = (v->counter); + v->counter &= i; + cpulock_set(status); + return ret; +} +umword_t atomic_fetch_or(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + ret = (v->counter); + v->counter |= i; + cpulock_set(status); + return ret; +} diff --git a/mkrtos_knl/arch/cortex-m33/atomics.h b/mkrtos_knl/arch/cortex-m33/atomics.h new file mode 100644 index 000000000..abba94665 --- /dev/null +++ b/mkrtos_knl/arch/cortex-m33/atomics.h @@ -0,0 +1,67 @@ +#pragma once +#include +typedef struct atomic64 +{ + umword_t counter; +} atomic_t; + +#define ATOMIC64_INIT(i) ((atomic_t){(i)}) + +#define atomic_read(v) (*(volatile umword_t *)(&(v)->counter)) +#define atomic_set(v, i) (((v)->counter) = i) + +bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new); +void atomic_and(umword_t *l, umword_t val); +umword_t atomic_and_return(umword_t *l, umword_t val); +void atomic_or(umword_t *l, umword_t val); +umword_t atomic_sub_return(umword_t i, atomic_t *v); +umword_t atomic_add_return(umword_t i, atomic_t *v); +umword_t atomic_fetch_and(umword_t i, atomic_t *v); +umword_t atomic_fetch_or(umword_t i, atomic_t *v); + +static inline void atomic_add(umword_t i, atomic_t *v) +{ + atomic_add_return(i, v); +} +static inline void atomic_sub(umword_t i, atomic_t *v) +{ + atomic_sub_return(i, v); +} +static inline void atomic_inc(atomic_t *v) +{ + atomic_add_return(1, v); +} +static inline void atomic_dec(atomic_t *v) +{ + atomic_sub_return(1, v); +} +static inline umword_t atomic_inc_return(atomic_t *v) +{ + return atomic_add_return(1, v); +} +static inline umword_t atomic_dec_return(atomic_t *v) +{ + return atomic_sub_return(1, v); +} + +static inline umword_t atomic_add_and_test(umword_t i, atomic_t *v) +{ + return atomic_add_return(i, v) == 0; +} + +static inline umword_t atomic_sub_and_test(umword_t i, atomic_t *v) +{ + return atomic_sub_return(i, v) == 0; +} +static inline umword_t atomic_inc_and_test(atomic_t *v) +{ + return atomic_inc_return(v) == 0; +} +static inline umword_t atomic_dec_and_test(atomic_t *v) +{ + return atomic_dec_return(v) == 0; +} +static inline umword_t atomic_add_negative(umword_t i, atomic_t *v) +{ + return (umword_t)atomic_add_return(i, v) < 0; +} diff --git a/mkrtos_knl/arch/cortex-m33/link.lds.S b/mkrtos_knl/arch/cortex-m33/link.lds.S index 860eded91..fa3879631 100644 --- a/mkrtos_knl/arch/cortex-m33/link.lds.S +++ b/mkrtos_knl/arch/cortex-m33/link.lds.S @@ -89,6 +89,11 @@ SECTIONS *(.data) /* .data sections */ *(.data*) /* .data* sections */ + . = ALIGN(0x4); + _pre_cpu_data_start = .; + KEEP (*(.data.per_cpu)) + _pre_cpu_data_end = .; + . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH diff --git a/mkrtos_knl/arch/cortex-m33/sche.S b/mkrtos_knl/arch/cortex-m33/sche.S index 2b89ce385..827b64b38 100755 --- a/mkrtos_knl/arch/cortex-m33/sche.S +++ b/mkrtos_knl/arch/cortex-m33/sche.S @@ -3,7 +3,7 @@ .thumb .global mpu_switch_to -.global sched_reset +.global scheduler .global PendSV_Handler .type PendSV_Handler, %function @@ -22,7 +22,7 @@ PendSV_Handler: mov r2, lr push {r4} - ldr r4, =sched_reset + ldr r4, =scheduler ldr r4, [r4] //! psp为零时,立刻调度一次 CBZ r4, thread_sche diff --git a/mkrtos_knl/arch/cortex-m33/sched_arch.c b/mkrtos_knl/arch/cortex-m33/sched_arch.c index 09d0528d4..2a572de94 100644 --- a/mkrtos_knl/arch/cortex-m33/sched_arch.c +++ b/mkrtos_knl/arch/cortex-m33/sched_arch.c @@ -13,13 +13,13 @@ sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type) assert(next_th->magic == THREAD_MAGIC); - if (sched_reset) + if (sche->sched_reset) { thread_t *cur_th = thread_get_current(); cur_th->sp.knl_sp = ksp; cur_th->sp.user_sp = usp; cur_th->sp.sp_type = sp_type; } - sched_reset = 1; + sche->sched_reset = 1; return &next_th->sp; } diff --git a/mkrtos_knl/arch/cortex-m33/swm34s/arch.c b/mkrtos_knl/arch/cortex-m33/swm34s/arch.c index c241a70a1..7adafb511 100644 --- a/mkrtos_knl/arch/cortex-m33/swm34s/arch.c +++ b/mkrtos_knl/arch/cortex-m33/swm34s/arch.c @@ -24,7 +24,7 @@ void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE; #define REG0_ADDR 0xE000ED22 #define REG1_ADDR 0xE000ED04 -void to_sche(void) +void arch_to_sche(void) { // 开启pensv中断 write_reg(REG1_ADDR, 0x10000000); diff --git a/mkrtos_knl/arch/cortex-m33/swm34s/arch.h b/mkrtos_knl/arch/cortex-m33/swm34s/arch.h index 7461d12f0..0ca03d356 100755 --- a/mkrtos_knl/arch/cortex-m33/swm34s/arch.h +++ b/mkrtos_knl/arch/cortex-m33/swm34s/arch.h @@ -69,7 +69,7 @@ typedef struct sp_info ((ret & 0x4) ? 0 : 1); \ }) -void to_sche(void); +void arch_to_sche(void); static inline umword_t arch_get_sp(void) { @@ -110,7 +110,10 @@ static inline umword_t arch_get_user_sp(void) void arch_disable_irq(int inx); void arch_enable_irq(int inx); void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio); - +static inline int arch_get_current_cpu_id(void) +{ + return 0; +} #define sti() \ do \ { \ diff --git a/mkrtos_knl/arch/cortex-m4/atomics.c b/mkrtos_knl/arch/cortex-m4/atomics.c new file mode 100644 index 000000000..8b6588b59 --- /dev/null +++ b/mkrtos_knl/arch/cortex-m4/atomics.c @@ -0,0 +1,72 @@ + +#include +#include +#include +bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new) +{ + bool_t ret = FALSE; + mword_t status = cpulock_lock(); + if (*v == old) { + *v = new; + ret = TRUE; + } + cpulock_set(status); + return ret; +} +void atomic_and(umword_t *l, umword_t val) +{ + mword_t status = cpulock_lock(); + *l &= val; + cpulock_set(status); +} +umword_t atomic_and_return(umword_t *l, umword_t val) +{ + umword_t ret; + mword_t status = cpulock_lock(); + *l &= val; + ret = !!(*l); + cpulock_set(status); + return ret; +} +void atomic_or(umword_t *l, umword_t val) +{ + mword_t status = cpulock_lock(); + *l |= val; + cpulock_set(status); +} +umword_t atomic_sub_return(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + v->counter -= i; + ret = (v->counter); + cpulock_set(status); + return ret; +} +umword_t atomic_add_return(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + v->counter += i; + ret = (v->counter); + cpulock_set(status); + return ret; +} +umword_t atomic_fetch_and(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + ret = (v->counter); + v->counter &= i; + cpulock_set(status); + return ret; +} +umword_t atomic_fetch_or(umword_t i, atomic_t *v) +{ + umword_t ret; + mword_t status = cpulock_lock(); + ret = (v->counter); + v->counter |= i; + cpulock_set(status); + return ret; +} diff --git a/mkrtos_knl/arch/cortex-m4/atomics.h b/mkrtos_knl/arch/cortex-m4/atomics.h new file mode 100644 index 000000000..abba94665 --- /dev/null +++ b/mkrtos_knl/arch/cortex-m4/atomics.h @@ -0,0 +1,67 @@ +#pragma once +#include +typedef struct atomic64 +{ + umword_t counter; +} atomic_t; + +#define ATOMIC64_INIT(i) ((atomic_t){(i)}) + +#define atomic_read(v) (*(volatile umword_t *)(&(v)->counter)) +#define atomic_set(v, i) (((v)->counter) = i) + +bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new); +void atomic_and(umword_t *l, umword_t val); +umword_t atomic_and_return(umword_t *l, umword_t val); +void atomic_or(umword_t *l, umword_t val); +umword_t atomic_sub_return(umword_t i, atomic_t *v); +umword_t atomic_add_return(umword_t i, atomic_t *v); +umword_t atomic_fetch_and(umword_t i, atomic_t *v); +umword_t atomic_fetch_or(umword_t i, atomic_t *v); + +static inline void atomic_add(umword_t i, atomic_t *v) +{ + atomic_add_return(i, v); +} +static inline void atomic_sub(umword_t i, atomic_t *v) +{ + atomic_sub_return(i, v); +} +static inline void atomic_inc(atomic_t *v) +{ + atomic_add_return(1, v); +} +static inline void atomic_dec(atomic_t *v) +{ + atomic_sub_return(1, v); +} +static inline umword_t atomic_inc_return(atomic_t *v) +{ + return atomic_add_return(1, v); +} +static inline umword_t atomic_dec_return(atomic_t *v) +{ + return atomic_sub_return(1, v); +} + +static inline umword_t atomic_add_and_test(umword_t i, atomic_t *v) +{ + return atomic_add_return(i, v) == 0; +} + +static inline umword_t atomic_sub_and_test(umword_t i, atomic_t *v) +{ + return atomic_sub_return(i, v) == 0; +} +static inline umword_t atomic_inc_and_test(atomic_t *v) +{ + return atomic_inc_return(v) == 0; +} +static inline umword_t atomic_dec_and_test(atomic_t *v) +{ + return atomic_dec_return(v) == 0; +} +static inline umword_t atomic_add_negative(umword_t i, atomic_t *v) +{ + return (umword_t)atomic_add_return(i, v) < 0; +} diff --git a/mkrtos_knl/arch/cortex-m4/link.lds.S b/mkrtos_knl/arch/cortex-m4/link.lds.S index 860eded91..fa3879631 100644 --- a/mkrtos_knl/arch/cortex-m4/link.lds.S +++ b/mkrtos_knl/arch/cortex-m4/link.lds.S @@ -89,6 +89,11 @@ SECTIONS *(.data) /* .data sections */ *(.data*) /* .data* sections */ + . = ALIGN(0x4); + _pre_cpu_data_start = .; + KEEP (*(.data.per_cpu)) + _pre_cpu_data_end = .; + . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM AT> FLASH diff --git a/mkrtos_knl/arch/cortex-m4/sche.S b/mkrtos_knl/arch/cortex-m4/sche.S index 2b89ce385..827b64b38 100755 --- a/mkrtos_knl/arch/cortex-m4/sche.S +++ b/mkrtos_knl/arch/cortex-m4/sche.S @@ -3,7 +3,7 @@ .thumb .global mpu_switch_to -.global sched_reset +.global scheduler .global PendSV_Handler .type PendSV_Handler, %function @@ -22,7 +22,7 @@ PendSV_Handler: mov r2, lr push {r4} - ldr r4, =sched_reset + ldr r4, =scheduler ldr r4, [r4] //! psp为零时,立刻调度一次 CBZ r4, thread_sche diff --git a/mkrtos_knl/arch/cortex-m4/sched_arch.c b/mkrtos_knl/arch/cortex-m4/sched_arch.c index 09d0528d4..2a572de94 100644 --- a/mkrtos_knl/arch/cortex-m4/sched_arch.c +++ b/mkrtos_knl/arch/cortex-m4/sched_arch.c @@ -13,13 +13,13 @@ sp_info_t *schde_to(void *usp, void *ksp, umword_t sp_type) assert(next_th->magic == THREAD_MAGIC); - if (sched_reset) + if (sche->sched_reset) { thread_t *cur_th = thread_get_current(); cur_th->sp.knl_sp = ksp; cur_th->sp.user_sp = usp; cur_th->sp.sp_type = sp_type; } - sched_reset = 1; + sche->sched_reset = 1; return &next_th->sp; } diff --git a/mkrtos_knl/arch/cortex-m4/stm32f4/arch.c b/mkrtos_knl/arch/cortex-m4/stm32f4/arch.c index 359824eee..811682684 100644 --- a/mkrtos_knl/arch/cortex-m4/stm32f4/arch.c +++ b/mkrtos_knl/arch/cortex-m4/stm32f4/arch.c @@ -23,7 +23,7 @@ void *_estack = thread_knl_stack + THREAD_BLOCK_SIZE; #define REG0_ADDR 0xE000ED22 #define REG1_ADDR 0xE000ED04 -void to_sche(void) +void arch_to_sche(void) { // 开启pensv中断 write_reg(REG1_ADDR, 0x10000000); diff --git a/mkrtos_knl/arch/cortex-m4/stm32f4/arch.h b/mkrtos_knl/arch/cortex-m4/stm32f4/arch.h index 18ad0e002..ad5ba2d20 100755 --- a/mkrtos_knl/arch/cortex-m4/stm32f4/arch.h +++ b/mkrtos_knl/arch/cortex-m4/stm32f4/arch.h @@ -70,7 +70,7 @@ typedef struct sp_info ((ret & 0x4) ? 0 : 1); \ }) -void to_sche(void); +void arch_to_sche(void); static inline umword_t arch_get_sp(void) { @@ -111,7 +111,10 @@ static inline umword_t arch_get_user_sp(void) void arch_disable_irq(int inx); void arch_enable_irq(int inx); void arch_set_enable_irq_prio(int inx, int sub_prio, int pre_prio); - +static inline int arch_get_current_cpu_id(void) +{ + return 0; +} #define sti() \ do \ { \ diff --git a/mkrtos_knl/drivers/aarch64_qemu/systick/systick.c b/mkrtos_knl/drivers/aarch64_qemu/systick/systick.c index 7649cc909..f0b3d1506 100755 --- a/mkrtos_knl/drivers/aarch64_qemu/systick/systick.c +++ b/mkrtos_knl/drivers/aarch64_qemu/systick/systick.c @@ -6,23 +6,24 @@ #include #include #include -static umword_t sys_tick_cnt; +#include +static PER_CPU(umword_t, sys_tick_cnt); umword_t sys_tick_cnt_get(void) { - return sys_tick_cnt; + return (*((umword_t *)pre_cpu_get_var_cpu(0, &sys_tick_cnt))); } void systick_handler(irq_entry_t *irq) { - handle_timer_irq(); - gic2_eoi_irq(arm_gicv2_get_global(), SYSTICK_INTR_NO); - // 进行上下文切换 - sys_tick_cnt++; + mword_t status = cpulock_lock(); + (*((umword_t *)pre_cpu_get_current_cpu_var(&sys_tick_cnt)))++; + // 进行上下文切换,超时默认0核处理 thread_timeout_check(1); futex_timeout_times_tick(); - if (thread_sched(FALSE)) - { - sche_arch_sw_context(); - } + gic2_eoi_irq(arm_gicv2_get_global(), SYSTICK_INTR_NO); + handle_timer_irq(); + + thread_sched(TRUE); + cpulock_set(status); } diff --git a/mkrtos_knl/drivers/aarch64_qemu/uart/uart.c b/mkrtos_knl/drivers/aarch64_qemu/uart/uart.c index acdcc6a99..d04b870dc 100755 --- a/mkrtos_knl/drivers/aarch64_qemu/uart/uart.c +++ b/mkrtos_knl/drivers/aarch64_qemu/uart/uart.c @@ -131,6 +131,7 @@ static uint8_t queue_data[QUEUE_LEN]; void uart_tigger(irq_entry_t *irq) { int ch; + mword_t status = cpulock_lock(); ch = read_reg32(UART011_BASE_ADDR + UART01x_DR); if (ch & 0x0f00) @@ -140,15 +141,15 @@ void uart_tigger(irq_entry_t *irq) } ch &= 0xff; q_enqueue(&queue, ch); - mword_t status = cpulock_lock(); if (irq->irq->wait_thread && thread_get_status(irq->irq->wait_thread) == THREAD_SUSPEND) { - thread_ready(irq->irq->wait_thread, TRUE); + thread_ready_remote(irq->irq->wait_thread, FALSE); } cpulock_set(status); end: gic2_eoi_irq(arm_gicv2_get_global(), LOG_INTR_NO); + cpulock_set(status); } void uart_init(void) @@ -180,6 +181,7 @@ void uart_init(void) gic2_set_unmask(arm_gicv2_get_global(), LOG_INTR_NO); gic2_set_target_cpu(arm_gicv2_get_global(), LOG_INTR_NO, 1 << arch_get_current_cpu_id()); + gic2_set_prio(arm_gicv2_get_global(), LOG_INTR_NO, 0); } INIT_HIGH_HAD(uart_init); diff --git a/mkrtos_knl/inc/knl/irq.h b/mkrtos_knl/inc/knl/irq.h index 5463c9046..1c7fa6b26 100755 --- a/mkrtos_knl/inc/knl/irq.h +++ b/mkrtos_knl/inc/knl/irq.h @@ -3,12 +3,19 @@ #include #include +typedef struct irq_entry +{ + irq_sender_t *irq; + int inx; + void (*irq_tigger_func)(struct irq_entry *irq); +} irq_entry_t; + #define IRQ_INVALID_NO ((umword_t)(-1)) // #define CONFIG_IRQ_REG_TAB_SIZE 80 // #define CONFIG_USER_ISR_START_NO 16 bool_t irq_check_usability(int inx); -bool_t irq_alloc(int inx, irq_sender_t *irq, +bool_t irq_alloc(int inx, void *irq, void (*irq_tigger_func)(irq_entry_t *irq)); void irq_free(int inx); irq_entry_t *irq_get(int inx); diff --git a/mkrtos_knl/inc/knl/irq_sender.h b/mkrtos_knl/inc/knl/irq_sender.h index be6579ce6..63f892663 100644 --- a/mkrtos_knl/inc/knl/irq_sender.h +++ b/mkrtos_knl/inc/knl/irq_sender.h @@ -4,16 +4,6 @@ #include #include #include -struct irq_sender; -typedef struct irq_sender irq_sender_t; -struct irq_entry; -typedef struct irq_entry irq_entry_t; - -typedef struct irq_entry -{ - irq_sender_t *irq; - void (*irq_tigger_func)(irq_entry_t *irq); -} irq_entry_t; typedef struct irq_sender { diff --git a/mkrtos_knl/inc/knl/ref.h b/mkrtos_knl/inc/knl/ref.h index bdef86654..7c4859091 100644 --- a/mkrtos_knl/inc/knl/ref.h +++ b/mkrtos_knl/inc/knl/ref.h @@ -3,36 +3,29 @@ #include "cpulock.h" #include "types.h" #include "kobject.h" - +#include typedef struct ref_counter { - int val; + atomic_t val; } ref_counter_t; static inline void ref_counter_init(ref_counter_t *ref) { - ref->val = 0; + atomic_set(&ref->val, 0); } static inline void ref_counter_inc(ref_counter_t *ref) { - /*TODO:原子变量*/ - umword_t status = cpulock_lock(); - ref->val++; - cpulock_set(status); + atomic_inc(&ref->val); } static inline int ref_counter_dec(ref_counter_t *ref) { - int ret = 0; - /*TODO:原子变量*/ - umword_t status = cpulock_lock(); - ret = ref->val; - ref->val--; - cpulock_set(status); - return ret; + umword_t old_val = atomic_read(&ref->val); + atomic_dec_return(&ref->val); + return old_val; } static inline int ref_counter_val(ref_counter_t *ref) { - return ref->val; + return atomic_read(&ref->val); } int ref_counter_dec_and_release(ref_counter_t *ref, kobject_t *kobj); diff --git a/mkrtos_knl/inc/knl/scheduler.h b/mkrtos_knl/inc/knl/scheduler.h index 56572a5ec..720c0c99f 100755 --- a/mkrtos_knl/inc/knl/scheduler.h +++ b/mkrtos_knl/inc/knl/scheduler.h @@ -11,7 +11,8 @@ #include "slist.h" #define PRIO_MAX WORD_BITS -extern umword_t sched_reset; +// extern umword_t sched_reset; + typedef struct sched { int prio; @@ -26,6 +27,7 @@ static void sched_init(sched_t *sche) typedef struct scheduler { + umword_t sched_reset; // 放到第一个方便汇编操作 slist_head_t prio_list[PRIO_MAX]; umword_t bitmap[PRIO_MAX / WORD_BITS]; sched_t *cur_sche; @@ -35,8 +37,8 @@ typedef struct scheduler scheduler_t *scheduler_get_current(void); void scheduler_init(void); sched_t *scheduler_next(void); -void scheduler_add(sched_t *node); -void scheduler_add_to_cpu(sched_t *node, int cpu); +bool_t scheduler_add(sched_t *node); +bool_t scheduler_add_to_cpu(sched_t *node, int cpu); sched_t *scheduler_next_cpu(int cpu); void scheduler_del(sched_t *node); void scheduler_reset(void); diff --git a/mkrtos_knl/inc/knl/slist.h b/mkrtos_knl/inc/knl/slist.h index c4f7a2511..0e00e638e 100755 --- a/mkrtos_knl/inc/knl/slist.h +++ b/mkrtos_knl/inc/knl/slist.h @@ -47,6 +47,19 @@ static inline bool_t slist_in_list(slist_head_t *item) } return TRUE; } +static inline bool_t slist_in_list_check(slist_head_t *head, slist_head_t *item) +{ + slist_head_t *_head = head; + + head = head->next; + + while (head != _head) { + if (item == head) { + return TRUE; + } + head = head->next; + } +} /** * @brief 在头部添加一个节点 * @@ -85,6 +98,8 @@ static inline void slist_del(slist_head_t *item) { item->prev->next = item->next; item->next->prev = item->prev; + + // slist_init(item); } /** diff --git a/mkrtos_knl/inc/knl/spinlock.h b/mkrtos_knl/inc/knl/spinlock.h index 3579c89b7..ea93f8796 100755 --- a/mkrtos_knl/inc/knl/spinlock.h +++ b/mkrtos_knl/inc/knl/spinlock.h @@ -12,3 +12,4 @@ void spinlock_invalidate(spinlock_t *lock); bool_t spinlock_is_invalidation(spinlock_t *lock); mword_t spinlock_lock(spinlock_t *lock); void spinlock_set(spinlock_t *lock, mword_t status); +mword_t spinlock_status(spinlock_t *lock); diff --git a/mkrtos_knl/inc/knl/thread.h b/mkrtos_knl/inc/knl/thread.h index 7f5c42cb9..be256eafd 100755 --- a/mkrtos_knl/inc/knl/thread.h +++ b/mkrtos_knl/inc/knl/thread.h @@ -16,6 +16,7 @@ #include "arch.h" #include "ref.h" #include +#include struct task; typedef struct task task_t; struct thread; @@ -98,7 +99,6 @@ typedef struct msg_buf #endif msg_tag_t tag; //!< 存放发送的临时标识 } msg_buf_t; - #define THREAD_MAGIC 0xdeadead //!< 用于栈溢出检测 typedef struct thread { @@ -111,11 +111,23 @@ typedef struct thread slist_head_t futex_node; //!< futex使用 - msg_buf_t msg; //!< 每个线程独有的消息缓存区 - slist_head_t wait_send_head; //!< 等待头,那些节点等待给当前线程发送数据 - thread_t *last_send_th; //!< 当前线程上次接收到谁的数据 - kobject_t *ipc_kobj; //!< 发送者放到一个ipc对象中 - umword_t user_id; //!< 接收到的user_id +#if IS_ENABLED(CONFIG_SMP) + ipi_msg_t ipi_msg_node; +#endif + int cpu; + atomic_t time_count; + umword_t time_count_last; + + spinlock_t ipc_lock; + + msg_buf_t msg; //!< 每个线程独有的消息缓存区 + + slist_head_t wait_send_head; //!< 等待头,那些节点等待给当前线程发送数据 + spinlock_t wait_send_head_lock; //!< 等待锁 + + thread_t *last_send_th; //!< 当前线程上次接收到谁的数据 + kobject_t *ipc_kobj; //!< 发送者放到一个ipc对象中 + umword_t user_id; //!< 接收到的user_id enum thread_state status; //!< 线程状态 enum thread_ipc_state ipc_status; //!< ipc状态 @@ -161,6 +173,7 @@ static inline thread_t *thread_get_current(void) return th; } task_t *thread_get_current_task(void); +task_t *thread_get_task(thread_t *th); task_t *thread_get_bind_task(thread_t *th); static inline pf_t *thread_get_current_pf(void) @@ -179,6 +192,8 @@ void thread_suspend(thread_t *th); void thread_dead(thread_t *th); void thread_todead(thread_t *th, bool_t is_sche); void thread_ready(thread_t *th, bool_t is_sche); +void thread_ready_remote(thread_t *th, bool_t is_sche); +void thread_suspend_sw(thread_t *th, bool_t is_sche); void thread_timeout_check(ssize_t tick); msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id); diff --git a/mkrtos_knl/inc/knl/util.h b/mkrtos_knl/inc/knl/util.h index e9829dea4..3065eb657 100755 --- a/mkrtos_knl/inc/knl/util.h +++ b/mkrtos_knl/inc/knl/util.h @@ -5,8 +5,8 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) //!< 最小值 #define MAX(a, b) ((a) > (b) ? (a) : (b)) //!< 最大值 -#define MK_SET_BIT(a, b) ((a) |= 1 << (b)) //!< 设置BIT -#define MK_CLR_BIT(a, b) ((a) &= ~(1 << (b))) //!< 清除BIT +#define MK_SET_BIT(a, b) ((a) |= 1UL << (b)) //!< 设置BIT +#define MK_CLR_BIT(a, b) ((a) &= ~(1UL << (b))) //!< 清除BIT #define MK_GET_BIT(a, b) (((a) >> (b)) & 0x1) //!< 获取某位的bit #define ABS(a) ((a) < 0 ? -(a) : (a)) //!< 取绝对值 diff --git a/mkrtos_knl/knl/irq.c b/mkrtos_knl/knl/irq.c index bfdabc87b..66f8c9b13 100755 --- a/mkrtos_knl/knl/irq.c +++ b/mkrtos_knl/knl/irq.c @@ -18,7 +18,9 @@ #include #include #include -/*TODO:换成更节省内存的方式*/ +#include + +static spinlock_t lock; static irq_entry_t irqs[CONFIG_IRQ_REG_TAB_SIZE] = {0}; static void irq_tigger(irq_entry_t *irq); @@ -44,14 +46,19 @@ bool_t irq_check_usability(int inx) * @param irq_tigger_func * @return bool_t */ -bool_t irq_alloc(int inx, irq_sender_t *irq, void (*irq_tigger_func)(irq_entry_t *irq)) +bool_t irq_alloc(int inx, void *irq, void (*irq_tigger_func)(irq_entry_t *irq)) { + umword_t status = spinlock_lock(&lock); + if (irqs[inx].irq_tigger_func != NULL) { + spinlock_set(&lock, status); return FALSE; } irqs[inx].irq = irq; + irqs[inx].inx = inx; irqs[inx].irq_tigger_func = irq_tigger_func; + spinlock_set(&lock, status); return TRUE; } /** @@ -83,7 +90,7 @@ void entry_handler(void) { umword_t isr_no = arch_get_isr_no(); - if (isr_no <= 0) + if (isr_no < 0) { return; } @@ -93,10 +100,7 @@ void entry_handler(void) { assert(isr_no < CONFIG_IRQ_REG_TAB_SIZE); } - // if (isr_no != 30) - // { - // printk("==============%d.\n", isr_no); - // } + if (!irq_check_usability(isr_no)) { if (irqs[isr_no].irq_tigger_func) diff --git a/mkrtos_knl/knl/mm/vma.c b/mkrtos_knl/knl/mm/vma.c index 2ef11ad68..c02b45e86 100644 --- a/mkrtos_knl/knl/mm/vma.c +++ b/mkrtos_knl/knl/mm/vma.c @@ -389,7 +389,7 @@ mword_t task_vma_lock_two(task_vma_t *task_vma_0, task_vma_t *task_vma_1, mword_ void task_vma_unlock_two(task_vma_t *task_vma_0, task_vma_t *task_vma_1, mword_t status0, mword_t status1) { task_vma_unlock(task_vma_1, status1); - task_vma_unlock(task_vma_0, status1); + task_vma_unlock(task_vma_0, status0); } /** * 分配步骤 diff --git a/mkrtos_knl/knl/pre_cpu.c b/mkrtos_knl/knl/pre_cpu.c index a97f71d83..6df0aedeb 100644 --- a/mkrtos_knl/knl/pre_cpu.c +++ b/mkrtos_knl/knl/pre_cpu.c @@ -5,8 +5,8 @@ #include #include #include -#if IS_ENABLED(CONFIG_SMP) #include +#if IS_ENABLED(CONFIG_SMP) extern char _pre_cpu_data_start[]; extern char _pre_cpu_data_end[]; @@ -35,6 +35,7 @@ INIT_KOBJ_MEM(pre_cpu_init); void pre_cpu_init(void) { } +INIT_KOBJ_MEM(pre_cpu_init); #endif void *pre_cpu_get_var_cpu(uint32_t cpu_inx, void *mem_addr) diff --git a/mkrtos_knl/knl/scheduler.c b/mkrtos_knl/knl/scheduler.c index e73d87351..cf6dc9966 100755 --- a/mkrtos_knl/knl/scheduler.c +++ b/mkrtos_knl/knl/scheduler.c @@ -9,20 +9,19 @@ * */ #include "scheduler.h" -#include "util.h" #include "assert.h" -#include "thread.h" #include "init.h" +#include "thread.h" +#include "util.h" #include #include -static PER_CPU(scheduler_t, scheduler); -umword_t sched_reset = 0; +PER_CPU(scheduler_t, scheduler); void scheduler_reset(void) { scheduler_t *sched = scheduler_get_current(); - sched_reset = 0; + sched->sched_reset = 0; sched->cur_sche = NULL; } @@ -36,18 +35,20 @@ scheduler_t *scheduler_get_cpu(int inx) } void scheduler_init(void) { - for (int i = 0; i < PRIO_MAX; i++) - { - slist_init(&(scheduler_get_current()->prio_list[i])); + for (int j = 0; j < CONFIG_CPU; j++) { + for (int i = 0; i < PRIO_MAX; i++) { + slist_init(&(scheduler_get_cpu(j)->prio_list[i])); + } } } INIT_KOBJ(scheduler_init); -void scheduler_add(sched_t *node) +bool_t scheduler_add(sched_t *node) { - scheduler_add_to_cpu(node, arch_get_current_cpu_id()); + return scheduler_add_to_cpu(node, arch_get_current_cpu_id()); } -void scheduler_add_to_cpu(sched_t *node, int cpu) +bool_t scheduler_add_to_cpu(sched_t *node, int cpu) { + int ret = 0; thread_t *node_th = container_of(node, thread_t, sche); assert(node_th->magic == THREAD_MAGIC); @@ -56,15 +57,16 @@ void scheduler_add_to_cpu(sched_t *node, int cpu) assert(node->prio >= 0); assert(node->prio < PRIO_MAX); - if (node->prio > sched->max_prio) - { + if (node->prio > sched->max_prio) { sched->max_prio = node->prio; sched->cur_sche = NULL; + ret = 1; } MK_SET_BIT(sched->bitmap[node->prio / PRIO_MAX], node->prio % PRIO_MAX); slist_add(&(sched->prio_list[node->prio]), &node->node); + return 0; } void scheduler_del(sched_t *node) { @@ -74,19 +76,12 @@ void scheduler_del(sched_t *node) assert(node->prio >= 0); assert(node->prio < PRIO_MAX); slist_del(&node->node); - // slist_init(&node->node); - // if (node == &cur_th->sche) - // { // 删除的是当前的,重新调度 - // sched->cur_sche = NULL; - // } - if (slist_is_empty(&sched->prio_list[node->prio])) - { + + if (slist_is_empty(&sched->prio_list[node->prio])) { MK_CLR_BIT(sched->bitmap[node->prio / PRIO_MAX], node->prio % PRIO_MAX); - for (mword_t i = (PRIO_MAX / WORD_BITS - 1); i >= 0; i--) - { + for (mword_t i = (PRIO_MAX / WORD_BITS - 1); i >= 0; i--) { int ret = clz(sched->bitmap[i]); - if (ret != WORD_BITS) - { + if (ret != WORD_BITS) { int max_prio = (i + 1) * WORD_BITS - ret - 1; assert(!slist_is_empty(&sched->prio_list[max_prio])); sched->max_prio = max_prio; @@ -102,15 +97,11 @@ sched_t *scheduler_next_cpu(int cpu) sched_t *next_sch = NULL; slist_head_t *next = NULL; - if (sche->cur_sche == NULL) - { + if (sche->cur_sche == NULL || slist_is_empty(&sche->cur_sche->node)) { next = slist_first(&sche->prio_list[sche->max_prio]); - } - else - { + } else { next = sche->cur_sche->node.next; - if (next == &(sche->prio_list[sche->max_prio])) - { + if (next == &(sche->prio_list[sche->max_prio])) { next = slist_first(&sche->prio_list[sche->max_prio]); } } diff --git a/mkrtos_knl/knl/spinlock.c b/mkrtos_knl/knl/spinlock.c index b64001949..762014fc5 100755 --- a/mkrtos_knl/knl/spinlock.c +++ b/mkrtos_knl/knl/spinlock.c @@ -14,9 +14,9 @@ #include #include #if IS_ENABLED(CONFIG_SMP) -#include #include #endif +#include void spinlock_init(spinlock_t *lock) { lock->val &= ~3UL; @@ -24,15 +24,20 @@ void spinlock_init(spinlock_t *lock) void spinlock_invalidate(spinlock_t *lock) { // TODO:原子操作 - umword_t status = 0; - status = cpulock_lock(); - lock->val |= 1UL; - cpulock_set(status); + // umword_t status = 0; + // status = cpulock_lock(); + // lock->val |= 1UL; + // cpulock_set(status); + atomic_or(&lock->val, 1UL); } bool_t spinlock_is_invalidation(spinlock_t *lock) { return lock->val & 1UL; } +mword_t spinlock_status(spinlock_t *lock) +{ + return !!(lock->val & 0x2UL); +} mword_t spinlock_lock(spinlock_t *lock) { umword_t status = 0; diff --git a/mkrtos_knl/knl/syscall.c b/mkrtos_knl/knl/syscall.c index f4aebe563..9553581cb 100644 --- a/mkrtos_knl/knl/syscall.c +++ b/mkrtos_knl/knl/syscall.c @@ -38,12 +38,13 @@ void syscall_entry(entry_frame_t *entry) goto end; } } - // sti(); //开启中断 + umword_t status = cpulock_get_status(); + sti(); //开启中断 if (kobj->invoke_func) { kobj->invoke_func(kobj, sys_p, msg_tag_init(entry->regs[0]), entry); } - // cli(); //关闭中断 + cpulock_set(status); end:; #if !IS_ENABLED(CONFIG_MMU) addr_t u_sp = arch_get_user_sp(); diff --git a/mkrtos_knl/knl/task.c b/mkrtos_knl/knl/task.c index c2cc343fc..84c0b41cf 100755 --- a/mkrtos_knl/knl/task.c +++ b/mkrtos_knl/knl/task.c @@ -339,9 +339,9 @@ void task_init(task_t *task, ram_limit_t *ram, int is_knl) task->kobj.stage_2_func = task_release_stage2; #if IS_ENABLED(CONFIG_MMU) - knl_pdir_init(&task->mm_space.mem_dir, task->mm_space.mem_dir.dir, 3); + knl_pdir_init(&task->mm_space.mem_dir, task->mm_space.mem_dir.dir, 3/*TODO:*/); #else - mm_space_add(&task->mm_space, CONFIG_KNL_TEXT_ADDR, CONFIG_KNL_TEXT_SIZE, REGION_RO); // TODO:这里应该用config.配置 + mm_space_add(&task->mm_space, CONFIG_KNL_TEXT_ADDR, CONFIG_KNL_TEXT_SIZE, REGION_RO); #endif } @@ -387,7 +387,7 @@ static void task_release_stage2(kobject_t *kobj) // if (cur_tk == tk) // { thread_sched(TRUE); - to_sche(); + // arch_to_sche(); // } // mm_trace(); printk("release tk %x\n", tk); @@ -399,7 +399,7 @@ void task_kill(task_t *tk) obj_unmap(&tk->obj_space, vpage_create3(KOBJ_DELETE_RIGHT, 0, TASK_PROT), &kobj_list); kobj_del_list_to_do(&kobj_list); thread_sched(TRUE); - to_sche(); + // arch_to_sche(); } task_t *task_create(ram_limit_t *lim, int is_knl) { diff --git a/mkrtos_knl/knl/thread.c b/mkrtos_knl/knl/thread.c index ff63ca05b..518dcf8fc 100755 --- a/mkrtos_knl/knl/thread.c +++ b/mkrtos_knl/knl/thread.c @@ -9,28 +9,30 @@ * */ -#include "types.h" -#include "kobject.h" -#include "ram_limit.h" -#include "factory.h" #include "thread.h" -#include "mm_wrap.h" -#include "string.h" -#include "init.h" -#include "task.h" -#include "thread.h" -#include "slist.h" -#include "thread_task_arch.h" +#include "access.h" +#include "arch.h" #include "assert.h" #include "err.h" -#include "map.h" -#include "access.h" +#include "factory.h" +#include "init.h" #include "ipc.h" -#include "arch.h" +#include "kobject.h" +#include "map.h" +#include "mm_wrap.h" +#include "ram_limit.h" +#include "slist.h" +#include "string.h" +#include "task.h" +#include "thread.h" +#include "thread_task_arch.h" +#include "types.h" +#include #include - -enum thread_op -{ +#if IS_ENABLED(CONFIG_SMP) +#include +#endif +enum thread_op { SET_EXEC_REGS, RUN_THREAD, BIND_TASK, @@ -39,8 +41,7 @@ enum thread_op YIELD, DO_IPC = 6, //!< 与ipc对象中的额IPC_DO一致 }; -enum IPC_TYPE -{ +enum IPC_TYPE { IPC_CALL, IPC_REPLY, IPC_WAIT, @@ -52,8 +53,7 @@ static bool_t thread_put(kobject_t *kobj); static void thread_release_stage1(kobject_t *kobj); static void thread_release_stage2(kobject_t *kobj); -typedef struct thread_wait_entry -{ +typedef struct thread_wait_entry { slist_head_t node; slist_head_t node_timeout; thread_t *th; @@ -73,10 +73,9 @@ static PER_CPU(slist_head_t, wait_recv_queue); static void thread_timeout_init(void) { - for (int i = 0; i < CONFIG_CPU; i++) - { - slist_init(pre_cpu_get_var_cpu(i, &wait_send_queue)); - slist_init(pre_cpu_get_var_cpu(i, &wait_recv_queue)); + for (int i = 0; i < CONFIG_CPU; i++) { + slist_init(pre_cpu_get_var_cpu(i, (&wait_send_queue))); + slist_init(pre_cpu_get_var_cpu(i, (&wait_recv_queue))); } } @@ -109,6 +108,7 @@ void thread_init(thread_t *th, ram_limit_t *lim) slist_init(&th->wait_send_head); ref_counter_init(&th->ref); ref_counter_inc(&th->ref); + th->cpu = 0; th->lim = lim; th->kobj.invoke_func = thread_syscall; th->kobj.put_func = thread_put; @@ -128,19 +128,14 @@ static void thread_release_stage1(kobject_t *kobj) thread_t *cur = thread_get_current(); kobject_invalidate(kobj); - if (cur != th) - { + if (cur != th) { //! 线程在运行中,则挂起线程 - if (th->status == THREAD_READY) - { + if (th->status == THREAD_READY) { thread_suspend(th); } th->ipc_status = THREAD_IPC_ABORT; - } - else - { - if (cur->status == THREAD_READY) - { + } else { + if (cur->status == THREAD_READY) { thread_suspend(th); } cur->ipc_status = THREAD_IPC_ABORT; @@ -152,15 +147,13 @@ static void thread_release_stage1(kobject_t *kobj) assert(pos->th->status == THREAD_SUSPEND); thread_wait_entry_t *next = slist_next_entry(pos, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_send_queue), node_timeout); - if (pos->th != th) - { + if (pos->th != th) { pos->th->ipc_status = THREAD_IPC_ABORT; thread_ready(pos->th, TRUE); } slist_del(&pos->node_timeout); - if (slist_in_list(&pos->node)) - { + if (slist_in_list(&pos->node)) { slist_del(&pos->node); } pos = next; @@ -172,15 +165,13 @@ static void thread_release_stage1(kobject_t *kobj) assert(pos2->th->status == THREAD_SUSPEND); thread_wait_entry_t *next = slist_next_entry(pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue), node); - if (pos2->th != th) - { + slist_del(&pos2->node); + if (pos2->th != th) { pos2->th->ipc_status = THREAD_IPC_ABORT; thread_ready(pos2->th, TRUE); } - slist_del(&pos2->node); pos2 = next; } - thread_unbind(th); } static void thread_release_stage2(kobject_t *kobj) @@ -189,10 +180,10 @@ static void thread_release_stage2(kobject_t *kobj) thread_t *cur_th = thread_get_current(); // printk("release thread 0x%x\n", kobj); - if (cur_th == th) - { + if (cur_th == th) { scheduler_reset(); - thread_sched(TRUE); + thread_sched(FALSE); + arch_to_sche(); } #if IS_ENABLED(CONFIG_BUDDY_SLAB) mm_limit_free_buddy(th->lim, kobj, THREAD_BLOCK_SIZE); @@ -233,14 +224,32 @@ void thread_bind(thread_t *th, kobject_t *tk) */ void thread_unbind(thread_t *th) { - if (th->task) - { + if (th->task) { task_t *tsk = container_of(th->task, task_t, kobj); ref_counter_dec_and_release(&tsk->ref_cn, &th->kobj); th->task = NULL; } } +void thread_suspend_sw(thread_t *th, bool_t is_sche) +{ + assert(slist_in_list(&th->sche.node)); + assert(th->cpu == arch_get_current_cpu_id()); + umword_t status = cpulock_lock(); + + scheduler_del(&th->sche); + th->status = THREAD_SUSPEND; + + /* 当前线程才能够切出,不是当前线程执行这个也没有效果,而且还会导致当前线程切出*/ + if (th == thread_get_current() && is_sche) { + thread_sched(TRUE); + } else { + arch_to_sche(); //!< 触发调度中断 + } + // arch_to_sche(); + // printk("suspend: cpu:%d sp:0x%lx\n", arch_get_current_cpu_id(), th->sp.sp); + cpulock_set(status); +} /** * @brief 挂起一个线程 * @@ -248,14 +257,9 @@ void thread_unbind(thread_t *th) */ void thread_suspend(thread_t *th) { - // if (!slist_in_list(&th->sche.node)) - // { - assert(slist_in_list(&th->sche.node)); - // } - scheduler_del(&th->sche); - th->status = THREAD_SUSPEND; - thread_sched(TRUE); + thread_suspend_sw(th, TRUE); } + /** * @brief 线程死亡 * @@ -263,8 +267,7 @@ void thread_suspend(thread_t *th) */ void thread_dead(thread_t *th) { - if (!slist_in_list(&th->sche.node)) - { + if (!slist_in_list(&th->sche.node)) { assert(slist_in_list(&th->sche.node)); } scheduler_del(&th->sche); @@ -284,16 +287,21 @@ bool_t thread_sched(bool_t is_sche) thread_t *th = thread_get_current(); assert(th->magic == THREAD_MAGIC); - if (next_sche == &th->sche) - { + if (next_sche == &th->sche) { + //!< 线程没有发生变化,则不用切换 cpulock_set(status); return FALSE; } - if (is_sche) - { - to_sche(); + if (is_sche) { + // 立刻进行切换 +#if IS_ENABLED(CONFIG_MMU) + sche_arch_sw_context(); +#else + arch_to_sche(); +#endif } + // printk("sched: cpu:%d sp:0x%lx\n", arch_get_current_cpu_id(), th->sp.sp); cpulock_set(status); return TRUE; } @@ -310,8 +318,7 @@ void thread_ready_to_cpu(thread_t *th, int cpu, bool_t is_sche) assert(!slist_in_list(&th->sche.node)); scheduler_add_to_cpu(&th->sche, cpu); th->status = THREAD_READY; - if (is_sche) - { + if (is_sche) { umword_t status = cpulock_lock(); sched_t *next_sche = scheduler_next_cpu(cpu); @@ -319,6 +326,28 @@ void thread_ready_to_cpu(thread_t *th, int cpu, bool_t is_sche) } cpulock_set(status); } +#if IS_ENABLED(CONFIG_SMP) +static int thread_ready_remote_handler(ipi_msg_t *msg) +{ + thread_ready((thread_t *)(msg->msg), msg->msg2); + return 0; +} +#endif +void thread_ready_remote(thread_t *th, bool_t is_sche) +{ +#if IS_ENABLED(CONFIG_SMP) + if (th->cpu == arch_get_current_cpu_id()) { + thread_ready(th, is_sche); + } else { + th->ipi_msg_node.msg = (umword_t)th; + th->ipi_msg_node.msg2 = is_sche; + th->ipi_msg_node.cb = thread_ready_remote_handler; + cpu_ipi_to_msg(1 << th->cpu, &th->ipi_msg_node, IPI_CALL); + } +#else + thread_ready(th, is_sche); +#endif +} /** * @brief 线程进入就绪态 * @@ -326,7 +355,20 @@ void thread_ready_to_cpu(thread_t *th, int cpu, bool_t is_sche) */ void thread_ready(thread_t *th, bool_t is_sche) { - thread_ready_to_cpu(th, arch_get_current_cpu_id(), is_sche); + bool_t ret; + umword_t status = cpulock_lock(); + + assert(!slist_in_list(&th->sche.node)); + assert(th->cpu == arch_get_current_cpu_id()); + th->status = THREAD_READY; + ret = scheduler_add(&th->sche); + if (is_sche && ret && th == thread_get_current()) { + // ready线程的优先级大于最大优先级 + thread_sched(TRUE); + } else { + arch_to_sche(); + } + cpulock_set(status); } void thread_todead(thread_t *th, bool_t is_sche) { @@ -336,8 +378,7 @@ void thread_todead(thread_t *th, bool_t is_sche) // } scheduler_add(&th->sche); th->status = THREAD_TODEAD; - if (is_sche) - { + if (is_sche) { thread_sched(TRUE); } } @@ -352,14 +393,14 @@ thread_t *thread_create(ram_limit_t *ram) thread_t *th = NULL; #if IS_ENABLED(CONFIG_BUDDY_SLAB) - th = mm_limit_alloc_buddy(ram, PAGE_SIZE); + th = mm_limit_alloc_buddy(ram, THREAD_BLOCK_SIZE); #else th = mm_limit_alloc_align(ram, THREAD_BLOCK_SIZE, THREAD_BLOCK_SIZE); #endif - if (!th) - { + if (!th) { return NULL; } + // assert(((mword_t)th & (~(THREAD_BLOCK_SIZE - 1))) == 0); memset(th, 0, THREAD_BLOCK_SIZE); thread_init(th, ram); printk("create thread 0x%x\n", th); @@ -379,22 +420,22 @@ void thread_timeout_check(ssize_t tick) { assert(pos->th->status == THREAD_SUSPEND); thread_wait_entry_t *next = slist_next_entry(pos, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_send_queue), node_timeout); - if (pos->times > 0) - { + if (pos->times > 0) { pos->times -= tick; - if (pos->times <= 0) - { + if (pos->times <= 0) { pos->th->ipc_status = THREAD_TIMEOUT; + slist_del(&pos->node_timeout); - if (slist_in_list(&pos->node)) - { + if (slist_in_list(&pos->node)) { slist_del(&pos->node); } + // printk("send timeout:0x%lx\n", pos->th); thread_ready(pos->th, TRUE); } } pos = next; } + thread_wait_entry_t *pos2; slist_foreach_not_next(pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue), node) @@ -403,13 +444,13 @@ void thread_timeout_check(ssize_t tick) thread_wait_entry_t *next = slist_next_entry(pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue), node); - if (pos2->times > 0) - { + if (pos2->times > 0) { pos2->times -= tick; - if (pos2->times <= 0) - { + if (pos2->times <= 0) { pos2->th->ipc_status = THREAD_TIMEOUT; + assert(slist_in_list(&pos2->node)); slist_del(&pos2->node); + // printk("recv timeout:0x%lx\n", pos2->th); thread_ready(pos2->th, TRUE); } } @@ -419,12 +460,13 @@ void thread_timeout_check(ssize_t tick) static void thread_timeout_del_recv(thread_t *th) { thread_wait_entry_t *pos2; + assert(th->cpu == arch_get_current_cpu_id()); + slist_foreach_not_next(pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue), node) { thread_wait_entry_t *next = slist_next_entry(pos2, (slist_head_t *)pre_cpu_get_current_cpu_var(&wait_recv_queue), node); - if (pos2->th == th) - { + if (pos2->th == th) { slist_del(&pos2->node); break; @@ -432,6 +474,30 @@ static void thread_timeout_del_recv(thread_t *th) pos2 = next; } } +#if IS_ENABLED(CONFIG_SMP) +static int thread_timeout_del_recv_remote_handler(ipi_msg_t *msg) +{ + thread_timeout_del_recv((void *)(msg->msg)); + thread_ready((void *)(msg->msg), TRUE); //!< 直接唤醒接受者 + return 0; +} +#endif +void thread_timeout_del_recv_remote(thread_t *th) +{ +#if IS_ENABLED(CONFIG_SMP) + if (th->cpu == arch_get_current_cpu_id()) { + thread_timeout_del_recv(th); + thread_ready(th, TRUE); //!< 直接唤醒接受者 + } else { + th->ipi_msg_node.msg = (umword_t)th; + th->ipi_msg_node.cb = thread_timeout_del_recv_remote_handler; + cpu_ipi_to_msg(1 << th->cpu, &th->ipi_msg_node, IPI_CALL); + } +#else + thread_timeout_del_recv(th); + thread_ready(th, TRUE); //!< 直接唤醒接受者 +#endif +} /** * @brief ipc传输时的数据拷贝 * @@ -452,22 +518,19 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag) src_ipc = src; dst_ipc = dst; - if (tag.map_buf_len > 0) - { + if (tag.map_buf_len > 0) { kobj_del_list_t del; int map_len = tag.map_buf_len; kobj_del_list_init(&del); - for (int i = 0; i < map_len; i++) - { + for (int i = 0; i < map_len; i++) { int ret = 0; vpage_t dst_page = vpage_create_raw(dst_ipc->map_buf[i]); vpage_t src_page = vpage_create_raw(src_ipc->map_buf[i]); - if (src_page.flags & VPAGE_FLAGS_MAP) - { + if (src_page.flags & VPAGE_FLAGS_MAP) { ret = obj_map_src_dst(&dst_tk->obj_space, &src_tk->obj_space, vpage_get_obj_handler(dst_page), vpage_get_obj_handler(src_page), @@ -475,8 +538,7 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag) vpage_get_attrs(src_page), &del); } - if (ret < 0) - { + if (ret < 0) { return ret; } } @@ -487,73 +549,115 @@ static int ipc_data_copy(thread_t *dst_th, thread_t *src_th, msg_tag_t tag) dst_th->msg.tag = tag; return 0; } +#if IS_ENABLED(CONFIG_SMP) +static int thread_del_wait_send_handler(ipi_msg_t *msg) +{ + thread_wait_entry_t *wait = (void *)msg->msg; + if (slist_in_list(&wait->node_timeout)) { + slist_del(&wait->node_timeout); + } + thread_ready(wait->th, TRUE); + return 0; +} +#endif +int thread_del_wait_send_remote(thread_wait_entry_t *wait) +{ +#if IS_ENABLED(CONFIG_SMP) + thread_t *th = wait->th; + + if (th->cpu != arch_get_current_cpu_id()) { + th->ipi_msg_node.msg = (umword_t)wait; + th->ipi_msg_node.cb = thread_del_wait_send_handler; + cpu_ipi_to_msg(1 << th->cpu, &th->ipi_msg_node, IPI_CALL); + } else { + if (slist_in_list(&wait->node_timeout)) { + slist_del(&wait->node_timeout); + } + thread_ready(wait->th, TRUE); + } +#else + if (slist_in_list(&wait->node_timeout)) { + slist_del(&wait->node_timeout); + } + thread_ready(wait->th, TRUE); +#endif + return 0; +} /** * @brief 当前线程接收数据 * * @return int */ static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout, - umword_t *ret_user_id, ipc_t *ipc_kobj) + umword_t *ret_user_id, ipc_t *ipc_kobj, thread_t *recv_obj) { - int ret = 0; assert(ret_msg); assert(ret_user_id); + int ret = 0; thread_t *cur_th = thread_get_current(); umword_t lock_status; thread_wait_entry_t wait; + //!< 有发送者 + slist_head_t *ready_head = NULL; lock_status = cpulock_lock(); - cur_th->ipc_status = THREAD_RECV; //!< 因为接收挂起 - if (ipc_kobj) - { + if (ipc_kobj) { /*IPC对象的引用计数+1*/ ref_counter_inc(&ipc_kobj->ref); cur_th->ipc_kobj = &ipc_kobj->kobj; - } - else - { + } else { cur_th->ipc_kobj = NULL; } - if (!slist_is_empty(&cur_th->wait_send_head)) - { - //!< 有发送者 - slist_head_t *mslist = slist_first(&cur_th->wait_send_head); - thread_wait_entry_t *wait = container_of(mslist, thread_wait_entry_t, node); + // 先吧当前线程从调度队列中删除 + if (!recv_obj) { + lock_status = spinlock_lock(&cur_th->wait_send_head_lock); + } + assert(slist_in_list(&cur_th->sche.node)); + assert(cur_th->cpu == arch_get_current_cpu_id()); + cur_th->status = THREAD_SUSPEND; + cur_th->ipc_status = THREAD_RECV; //!< 因为接收挂起 + scheduler_del(&cur_th->sche); - slist_del(mslist); //!< 删除唤醒的线程 - if (slist_in_list(&wait->node_timeout)) - { - slist_del(&wait->node_timeout); - } - thread_ready(wait->th, TRUE); + if (recv_obj) { + // thread_ready_remote(recv_obj, TRUE); + thread_timeout_del_recv_remote(recv_obj); } - else - { - //!< 加入等待队列 - if (timeout.recv_timeout) - { + if (!slist_is_empty(&cur_th->wait_send_head) && !recv_obj) { + ready_head = slist_first(&cur_th->wait_send_head); + slist_del(ready_head); //!< 从当前线程中删除唤醒的线程 + if (!recv_obj) { + spinlock_set(&cur_th->wait_send_head_lock, lock_status); + } + thread_wait_entry_t *wait = container_of(ready_head, thread_wait_entry_t, node); + assert(wait->th->status == THREAD_SUSPEND); + + thread_del_wait_send_remote(wait); + } else { + + if (timeout.recv_timeout) { thread_wait_entry_init(&wait, cur_th, timeout.recv_timeout); - slist_add_append(pre_cpu_get_current_cpu_var(&wait_recv_queue), &wait.node); //!< 放到等待队列中 + // printk("add timeout:0x%lx\n", cur_th); + slist_add_append(pre_cpu_get_current_cpu_var(&wait_recv_queue), + &wait.node); //!< 放到等待队列中 + } + if (!recv_obj) { + spinlock_set(&cur_th->wait_send_head_lock, lock_status); } } - thread_suspend(cur_th); //!< 挂起 - preemption(); //!< 进行调度 + + thread_sched(TRUE); + preemption(); //!< 进行调度 // if (slist_in_list(&wait.node)) // { // slist_del(&wait.node); // } - if (cur_th->ipc_status == THREAD_IPC_ABORT) - { + if (cur_th->ipc_status == THREAD_IPC_ABORT) { cur_th->ipc_status = THREAD_NONE; ret = -ESHUTDOWN; - } - else if (cur_th->ipc_status == THREAD_TIMEOUT) - { + } else if (cur_th->ipc_status == THREAD_TIMEOUT) { cur_th->ipc_status = THREAD_NONE; ret = -ERTIMEDOUT; - } - else - { + } else { cur_th->ipc_status = THREAD_NONE; *ret_msg = cur_th->msg.tag; *ret_user_id = cur_th->user_id; @@ -562,7 +666,59 @@ static int thread_ipc_recv(msg_tag_t *ret_msg, ipc_timeout_t timeout, return ret; } +static int thread_ipc_reply_inner(thread_t *form, thread_t *to, msg_tag_t in_tag) +{ + if (to->status != THREAD_SUSPEND && + to->ipc_status != THREAD_RECV) { + to->last_send_th = NULL; + return -1; + } + //!< 发送数据给上一次的发送者 + int ret = ipc_data_copy(to, form, in_tag); //!< 拷贝数据 + if (ret < 0) { + in_tag.prot = ret; + } + to->msg.tag = in_tag; + if (to->ipc_status != THREAD_IPC_ABORT) { + thread_ready_remote(to, TRUE); //!< 直接唤醒接受者 + } + to->last_send_th = NULL; + ref_counter_dec_and_release(&to->ref, &to->kobj); + return 0; +} +#if IS_ENABLED(CONFIG_SMP) +static int thread_ipc_reply_handler(ipi_msg_t *msg) +{ + thread_t *form; + thread_t *to; + msg_tag_t in_tag; + + form = (thread_t *)msg->msg; + to = (thread_t *)msg->msg2; + in_tag = msg_tag_init(msg->msg3); + + return thread_ipc_reply_inner(form, to, in_tag); +} +#endif +int thread_ipc_reply_remote(thread_t *form, thread_t *to, msg_tag_t in_tag) +{ +#if IS_ENABLED(CONFIG_SMP) + if (to->cpu == arch_get_current_cpu_id()) { + return thread_ipc_reply_inner(form, to, in_tag); + } else { + to->ipi_msg_node.msg = (umword_t)form; + to->ipi_msg_node.msg2 = (umword_t)to; + to->ipi_msg_node.msg3 = (umword_t)in_tag.raw; + to->ipi_msg_node.cb = thread_ipc_reply_handler; + cpu_ipi_to_msg(1 << to->cpu, &to->ipi_msg_node, IPI_CALL); + + return to->ipi_msg_node.ret; + } +#else + return thread_ipc_reply_inner(form, to, in_tag); +#endif +} /** * @brief 当前线程回复数据给上一次的发送者,回复完成后则释放上一次的接收者指针 * @@ -573,127 +729,156 @@ static int thread_ipc_reply(msg_tag_t in_tag) { thread_t *cur_th = thread_get_current(); umword_t status; + thread_t *last_th; + int ret; - if (cur_th->last_send_th == NULL) - { + if (cur_th->last_send_th == NULL) { return -1; } status = cpulock_lock(); - if (cur_th->last_send_th == NULL) - { + if (cur_th->last_send_th == NULL) { cpulock_set(status); return -1; } - if (cur_th->last_send_th->status != THREAD_SUSPEND && - cur_th->last_send_th->ipc_status != THREAD_RECV) - { - cur_th->last_send_th = NULL; - cpulock_set(status); - return -1; - } - //!< 发送数据给上一次的发送者 - int ret = ipc_data_copy(cur_th->last_send_th, cur_th, in_tag); //!< 拷贝数据 + // printk("0x%x reply.\n", cur_th); - if (ret < 0) - { - // cpulock_set(status); - // return ret; - in_tag.prot = ret; - } - if (cur_th->last_send_th->ipc_status != THREAD_IPC_ABORT) - { - thread_ready(cur_th->last_send_th, TRUE); //!< 直接唤醒接受者 - } - cur_th->last_send_th->msg.tag = in_tag; - ref_counter_dec_and_release(&cur_th->last_send_th->ref, &cur_th->last_send_th->kobj); - cur_th->last_send_th = NULL; + last_th = cur_th->last_send_th; + ret = thread_ipc_reply_inner(cur_th, last_th, in_tag); cpulock_set(status); return ret; } - -__attribute__((optimize(0))) int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag, - ipc_timeout_t timout, umword_t *ret_user_id, bool_t is_call) +#if IS_ENABLED(CONFIG_SMP) +static int thread_remote_suspend_handler(ipi_msg_t *msg) { - int ret = -EINVAL; - if (is_call) - { - assert(is_call && ret_tag); + thread_t *th = (thread_t *)msg->msg; + assert(th); + thread_suspend(th); + return 0; +} +#endif +int thread_suspend_remote(thread_t *th) +{ +#if IS_ENABLED(CONFIG_SMP) + if (th->cpu != arch_get_current_cpu_id()) { + th->ipi_msg_node.msg = (umword_t)th; + th->ipi_msg_node.cb = thread_remote_suspend_handler; + cpu_ipi_to_msg(1 << th->cpu, &th->ipi_msg_node, IPI_CALL); + } else { + thread_suspend(th); } - thread_t *cur_th = thread_get_current(); - thread_t *recv_kobj = to_th; - mword_t lock_stats = spinlock_lock(&cur_th->kobj.lock); +#else + thread_suspend(th); +#endif + return 0; +} + +/** + * @brief 等待某个线程进入挂起状态 + * + * @param recv_th + * @param timeout + * @return int + */ +static int thread_wait_recv_thread(thread_t *recv_th, ipc_timeout_t timeout) +{ + int ret = 0; + thread_t *cur_th = thread_get_current(); + mword_t lock_status; - if (lock_stats < 0) - { - //!< 锁已经无效了 - return -EACCES; - } again_check: - if (recv_kobj->status == THREAD_READY) - { + lock_status = spinlock_lock(&recv_th->wait_send_head_lock); + if (recv_th->status != THREAD_SUSPEND && recv_th->ipc_status != THREAD_RECV) { + + // TODO:这里有互斥问题,recv_th可能recv的线程不是同一个核,这里就会出现互斥问题。 thread_wait_entry_t wait; - cur_th->ipc_status = THREAD_SEND; //!< 因为发送挂起 + assert(slist_in_list(&cur_th->sche.node)); + assert(cur_th->cpu == arch_get_current_cpu_id()); + cur_th->ipc_status = THREAD_RECV; //!< 因为接收挂起 + cur_th->status = THREAD_SUSPEND; + scheduler_del(&cur_th->sche); - thread_wait_entry_init(&wait, cur_th, timout.send_timeout); - slist_add_append(&recv_kobj->wait_send_head, &wait.node); //!< 放到线程的等待队列中 + thread_wait_entry_init(&wait, cur_th, timeout.send_timeout); + + slist_add_append(&recv_th->wait_send_head, &wait.node); //!< 放到线程的等待队列中 slist_add_append(pre_cpu_get_current_cpu_var(&wait_send_queue), &wait.node_timeout); - thread_suspend(cur_th); //!< 挂起 + spinlock_set(&recv_th->wait_send_head_lock, lock_status); + + thread_sched(TRUE); preemption(); - if (cur_th->ipc_status == THREAD_IPC_ABORT) - { + if (cur_th->ipc_status == THREAD_IPC_ABORT) { cur_th->ipc_status = THREAD_NONE; ret = -ESHUTDOWN; goto end; - } - else if (cur_th->ipc_status == THREAD_TIMEOUT) - { + } else if (cur_th->ipc_status == THREAD_TIMEOUT) { ret = -EWTIMEDOUT; goto end; } cur_th->ipc_status = THREAD_NONE; goto again_check; + } else { + spinlock_set(&recv_th->wait_send_head_lock, lock_status); } - else if (recv_kobj->status == THREAD_SUSPEND && recv_kobj->ipc_status == THREAD_RECV) - { - thread_timeout_del_recv(recv_kobj); +end: + return ret; +} +__attribute__((optimize(0))) int thread_ipc_call(thread_t *to_th, msg_tag_t in_tag, msg_tag_t *ret_tag, + ipc_timeout_t timout, umword_t *ret_user_id, bool_t is_call) +{ + int ret = -EINVAL; + if (is_call) { + assert(is_call && ret_tag); + } + thread_t *cur_th = thread_get_current(); + thread_t *recv_kobj = to_th; + mword_t lock_stats = spinlock_lock(&to_th->kobj.lock); + + if (lock_stats < 0) { + //!< 锁已经无效了 + return -EACCES; + } + // printk("0x%x call.\n", cur_th); + ret = thread_wait_recv_thread(recv_kobj, timout); + if (ret < 0) { + goto end; + } + // 下面开始数据接收的流程 + if (recv_kobj->status == THREAD_SUSPEND && recv_kobj->ipc_status == THREAD_RECV) { //!< 开始发送数据 ret = ipc_data_copy(recv_kobj, cur_th, in_tag); //!< 拷贝数据 - if (ret < 0) - { + if (ret < 0) { //!< 拷贝失败 goto end; } - thread_ready(recv_kobj, TRUE); //!< 直接唤醒接受者 - if (is_call) - { - if (recv_kobj->ipc_kobj) - { + if (is_call) { + if (recv_kobj->ipc_kobj) { // 绑定回复的ipc到当前的线程 assert(ipc_bind(((ipc_t *)(recv_kobj->ipc_kobj)), -1, 0, cur_th) >= 0); ref_counter_dec_and_release(&((ipc_t *)(recv_kobj->ipc_kobj))->ref, recv_kobj->ipc_kobj); recv_kobj->ipc_kobj = NULL; recv_kobj->last_send_th = NULL; - } - else - { - recv_kobj->last_send_th = cur_th; //!< 设置接收者的上一次发送者是谁 + } else { ref_counter_inc(&cur_th->ref); //!< 作为发送者增加一次引用 + recv_kobj->last_send_th = cur_th; //!< 设置接收者的上一次发送者是谁 } - ret = thread_ipc_recv(ret_tag, timout, ret_user_id, NULL); //!< 当前线程进行接收 - if (ret < 0) - { + + ret = thread_ipc_recv(ret_tag, timout, ret_user_id, NULL, recv_kobj); //!< 当前线程进行接收 + if (ret < 0) { //!< 接收超时 goto end; } + } else { + thread_timeout_del_recv_remote(recv_kobj); } preemption(); + } else { + assert(0); } ret = 0; end: - spinlock_set(&cur_th->kobj.lock, lock_stats); + spinlock_set(&to_th->kobj.lock, lock_stats); return ret; } /** @@ -714,10 +899,8 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id) obj_handler_t th_hd = 0; int ret = -EINVAL; - switch (ipc_type) - { - case IPC_CALL: - { + switch (ipc_type) { + case IPC_CALL: { msg_tag_t in_tag = msg_tag_init(f->regs[0]); msg_tag_t recv_tag; th_hd = f->regs[2]; @@ -725,35 +908,30 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id) to_th->user_id = user_id; ret = thread_ipc_call(to_th, in_tag, &recv_tag, ipc_tm_out, &f->regs[1], TRUE); - if (ret < 0) - { + if (ret < 0) { return msg_tag_init4(0, 0, 0, ret); } return recv_tag; } - case IPC_REPLY: - { + case IPC_REPLY: { msg_tag_t in_tag = msg_tag_init(f->regs[0]); ret = thread_ipc_reply(in_tag); return msg_tag_init4(0, 0, 0, ret); } case IPC_RECV: - case IPC_WAIT: - { + case IPC_WAIT: { msg_tag_t ret_msg; ipc_timeout_t ipc_tm_out = ipc_timeout_create(f->regs[3]); kobject_t *ipc_kobj = obj_space_lookup_kobj_cmp_type(&cur_task->obj_space, f->regs[4], IPC_TYPE); - int ret = thread_ipc_recv(&ret_msg, ipc_tm_out, &f->regs[1], (ipc_t *)ipc_kobj); - if (ret < 0) - { + int ret = thread_ipc_recv(&ret_msg, ipc_tm_out, &f->regs[1], (ipc_t *)ipc_kobj, NULL); + if (ret < 0) { return msg_tag_init4(0, 0, 0, ret); } return ret_msg; } - case IPC_SEND: - { + case IPC_SEND: { msg_tag_t in_tag = msg_tag_init(f->regs[0]); msg_tag_t recv_tag; // th_hd = f->regs[2]; @@ -770,6 +948,31 @@ msg_tag_t thread_do_ipc(kobject_t *kobj, entry_frame_t *f, umword_t user_id) return msg_tag_init4(0, 0, 0, ret); } +#if IS_ENABLED(CONFIG_SMP) +static int thread_remote_migration(ipi_msg_t *msg) +{ + thread_t *th = (thread_t *)msg->msg; + umword_t tagcpu = msg->msg2; + int cur_cpu = arch_get_current_cpu_id(); + assert(th); + assert(tagcpu == cur_cpu); + assert(th->cpu != cur_cpu); + + // 等待切换完成 + while (atomic_read(&th->time_count) == msg->th_time_cn) + ; + assert(!slist_in_list(&th->sche.node)); + assert(th->cpu != cur_cpu); + + assert(th->status == THREAD_SUSPEND || th->status == THREAD_IDLE); + assert(th->magic == THREAD_MAGIC); + th->cpu = cur_cpu; + // 在新的核上调度 + thread_ready(th, TRUE); + return 0; +} + +#endif static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f) { msg_tag_t tag = msg_tag_init4(0, 0, 0, -EINVAL); @@ -777,16 +980,13 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t thread_t *tag_th = container_of(kobj, thread_t, kobj); thread_t *cur_th = thread_get_current(); - if (sys_p.prot != THREAD_PROT) - { + if (sys_p.prot != THREAD_PROT) { f->regs[0] = msg_tag_init4(0, 0, 0, -EPROTO).raw; return; } - switch (sys_p.op) - { - case SET_EXEC_REGS: - { + switch (sys_p.op) { + case SET_EXEC_REGS: { umword_t stack_bottom = 0; if (f->regs[4]) //!< cp_stack @@ -795,13 +995,10 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t } thread_set_exc_regs(tag_th, f->regs[1], f->regs[2], f->regs[3], stack_bottom); tag = msg_tag_init4(0, 0, 0, 0); - } - break; - case MSG_BUG_SET: - { + } break; + case MSG_BUG_SET: { task_t *tag_tk = thread_get_bind_task(tag_th); - if (is_rw_access(tag_tk, (void *)(f->regs[1]), THREAD_MSG_BUG_LEN, FALSE)) - { + if (is_rw_access(tag_tk, (void *)(f->regs[1]), THREAD_MSG_BUG_LEN, FALSE)) { #if IS_ENABLED(CONFIG_MMU) thread_set_msg_buf(tag_th, (void *)mm_get_paddr(mm_space_get_pdir(&tag_tk->mm_space), f->regs[1], PAGE_SHIFT), (void *)(f->regs[1])); @@ -810,88 +1007,99 @@ static void thread_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_t (void *)(f->regs[1])); #endif tag = msg_tag_init4(0, 0, 0, 0); - } - else - { + } else { //!< 内存不可访问 tag = msg_tag_init4(0, 0, 0, -EACCES); } } - case MSG_BUG_GET: - { + case MSG_BUG_GET: { f->regs[1] = (umword_t)(thread_get_msg_buf(tag_th)); f->regs[2] = THREAD_MSG_BUG_LEN; - if (thread_get_msg_buf(tag_th) == NULL) - { + if (thread_get_msg_buf(tag_th) == NULL) { tag = msg_tag_init4(0, 0, 0, -EACCES); - } - else - { + } else { tag = msg_tag_init4(0, 0, 0, 0); } - } - break; - case RUN_THREAD: - { + } break; + case RUN_THREAD: { task_t *tag_tsk = thread_get_bind_task(tag_th); - if (tag_tsk == NULL) - { + if (tag_tsk == NULL) { tag = msg_tag_init4(0, 0, 0, -EACCES); break; } - if (task_pid_get(tag_tsk) == -1) - { + if (task_pid_get(tag_tsk) == -1) { //!< 只有设置了pid才能启动,pid只有init进程能够设置,这就使得只有pid能够启动应用程序 tag = msg_tag_init4(0, 0, 0, -EACCES); break; } + int cur_cpu = arch_get_current_cpu_id(); umword_t status = cpulock_lock(); - if (!slist_in_list(&tag_th->sche.node)) - { - tag_th->sche.prio = (f->regs[1] >= PRIO_MAX ? PRIO_MAX - 1 : f->regs[1]); - if (f->regs[2] >= CONFIG_CPU) - { - thread_ready(tag_th, TRUE); - } - else - { - thread_ready_to_cpu(tag_th, f->regs[2], TRUE); + +#if IS_ENABLED(CONFIG_SMP) + if (f->regs[2] >= CONFIG_CPU) { + f->regs[2] = cur_cpu; + } + + if (tag_th->cpu != cur_cpu) { + atomic_set(&tag_th->ipi_msg_node.flags, 0); + + // 目标cpu和线程当前cpu不在同一个cpu上,则需要先让目标cpu吧线程挂起,然后再进行迁移 + thread_suspend_remote(tag_th); + } else { + if (slist_in_list(&tag_th->sche.node)) { + // 当前核先挂起线程 + // thread_suspend(tag_th); + tag_th->status = THREAD_SUSPEND; + scheduler_del(&tag_th->sche); } } - else - { + tag_th->sche.prio = (f->regs[1] >= PRIO_MAX ? PRIO_MAX - 1 : f->regs[1]); + + if (f->regs[2] != tag_th->cpu) { + // 目标核运行该线程 + tag_th->ipi_msg_node.msg = (umword_t)tag_th; + tag_th->ipi_msg_node.msg2 = f->regs[2]; + tag_th->ipi_msg_node.th_time_cn = tag_th->status == THREAD_IDLE ? 1 : atomic_read(&tag_th->time_count); + tag_th->ipi_msg_node.cb = thread_remote_migration; + cpu_ipi_to_msg(1 << f->regs[2], &tag_th->ipi_msg_node, IPI_CALL); + assert(tag_th->cpu == f->regs[2]); + } else { + if (tag_th->cpu == cur_cpu) { + thread_ready(tag_th, TRUE); + } else { + assert(0); + } + } +#else + if (!slist_in_list(&tag_th->sche.node)) { + thread_ready(tag_th, TRUE); + } else { thread_suspend(tag_th); tag_th->sche.prio = (f->regs[1] >= PRIO_MAX ? PRIO_MAX - 1 : f->regs[1]); thread_ready(tag_th, TRUE); } +#endif cpulock_set(status); tag = msg_tag_init4(0, 0, 0, 0); - } - break; - case BIND_TASK: - { + } break; + case BIND_TASK: { kobject_t *task_kobj = obj_space_lookup_kobj_cmp_type(&task->obj_space, f->regs[1], TASK_TYPE); - if (task_kobj == NULL) - { + if (task_kobj == NULL) { f->regs[0] = msg_tag_init4(0, 0, 0, -ENOENT).raw; return; } thread_bind(tag_th, task_kobj); tag = msg_tag_init4(0, 0, 0, 0); // printk("thread bind to %d\n", f->regs[1]); - } - break; - case YIELD: - { + } break; + case YIELD: { thread_sched(TRUE); + // arch_to_sche(); tag = msg_tag_init4(0, 0, 0, 0); - } - break; - case DO_IPC: - { + } break; + case DO_IPC: { tag = thread_do_ipc(kobj, f, 0); - } - break; + } break; } f->regs[0] = tag.raw; } @@ -910,8 +1118,7 @@ static kobject_t *thread_create_func(ram_limit_t *lim, umword_t arg0, umword_t a umword_t arg2, umword_t arg3) { kobject_t *kobj = (kobject_t *)thread_create(lim); - if (!kobj) - { + if (!kobj) { return NULL; } return kobj; @@ -936,8 +1143,7 @@ task_t *thread_get_current_task(void) thread_t *cur = thread_get_current(); kobject_t *kobj = cur->task; - if (!kobj) - { + if (!kobj) { return NULL; } return container_of( diff --git a/mkrtos_knl/knl/thread_knl.c b/mkrtos_knl/knl/thread_knl.c index 6d882cd63..835d7a0b3 100755 --- a/mkrtos_knl/knl/thread_knl.c +++ b/mkrtos_knl/knl/thread_knl.c @@ -9,19 +9,19 @@ * */ -#include "types.h" +#include "app.h" +#include "arch.h" +#include "factory.h" +#include "globals.h" #include "init.h" +#include "knl_misc.h" +#include "map.h" +#include "mm_wrap.h" #include "printk.h" #include "task.h" #include "thread.h" -#include "factory.h" -#include "globals.h" -#include "arch.h" -#include "map.h" -#include "app.h" -#include "mm_wrap.h" #include "thread_task_arch.h" -#include "knl_misc.h" +#include "types.h" #include #if IS_ENABLED(CONFIG_KNL_TEST) #include @@ -34,8 +34,7 @@ #endif #include -static uint8_t knl_msg_buf[THREAD_MSG_BUG_LEN]; -static thread_t *knl_thread; +static uint8_t knl_msg_buf[CONFIG_CPU][THREAD_MSG_BUG_LEN]; static task_t knl_task; static thread_t *init_thread; static task_t *init_task; @@ -94,6 +93,8 @@ static void knl_main(void) */ void knl_init_1(void) { + thread_t *knl_thread; + knl_thread = thread_get_current(); thread_init(knl_thread, &root_factory_get()->limit); @@ -101,9 +102,10 @@ void knl_init_1(void) task_knl_init(&knl_task); thread_knl_pf_set(knl_thread, knl_main); thread_bind(knl_thread, &knl_task.kobj); - thread_set_msg_buf(knl_thread, knl_msg_buf, knl_msg_buf); + thread_set_msg_buf(knl_thread, knl_msg_buf[arch_get_current_cpu_id()], + knl_msg_buf[arch_get_current_cpu_id()]); + knl_thread->cpu = arch_get_current_cpu_id(); thread_ready(knl_thread, FALSE); - } INIT_STAGE1(knl_init_1); @@ -126,7 +128,7 @@ static void knl_init_2(void) init_thread = thread_create(&root_factory_get()->limit); assert(init_thread); - init_task = task_create(&root_factory_get()->limit, FALSE); + init_task = task_create(&root_factory_get()->limit, FALSE); assert(init_task); #if IS_ENABLED(CONFIG_ELF_LAUNCH) @@ -226,12 +228,12 @@ void start_kernel(void) print_mkrtos_info(); cli(); sys_startup(); //!< 开始调度 - thread_sched(TRUE); - // to_sche(); + thread_sched(FALSE); + arch_to_sche(); sti(); while (1) { - // knl_main(); + knl_main(); } } diff --git a/mkrtos_knl/test/kthread_test.c b/mkrtos_knl/test/kthread_test.c index b0e50a575..917a56dbc 100644 --- a/mkrtos_knl/test/kthread_test.c +++ b/mkrtos_knl/test/kthread_test.c @@ -47,7 +47,8 @@ void kthread_test_init(void) assert(thread2); thread_bind(thread2, &cur_tk->kobj); thread_knl_pf_set(thread2, th_test); - thread_ready(thread2, FALSE); + thread2->sche.prio=2; + thread_ready(thread2, TRUE); thread_t *thread3; @@ -55,5 +56,6 @@ void kthread_test_init(void) assert(thread3); thread_bind(thread3, &cur_tk->kobj); thread_knl_pf_set(thread3, th_test2); - thread_ready(thread3, FALSE); + thread3->sche.prio=2; + thread_ready(thread3, TRUE); } \ No newline at end of file diff --git a/mkrtos_script/build_f1.sh b/mkrtos_script/build_f1.sh index 82e849320..3bff00896 100755 --- a/mkrtos_script/build_f1.sh +++ b/mkrtos_script/build_f1.sh @@ -2,12 +2,12 @@ # export TOOLCHAIN=/home/zhangzheng/mkrtos-tools/gcc/gcc-arm-none-eabi-5_4-2016q3/bin/ # export TOOLCHAIN_LIB=/home/zhangzheng/mkrtos-tools/gcc/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m -# export TOOLCHAIN=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/bin/ -# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp +export TOOLCHAIN=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/bin/ +export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp # export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/ # export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp -export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/ -export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m/ +# export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/ +# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m/ export BOARD=STM32F103ZET6 export CROSS_COMPILE_NAME=arm-none-eabi- diff --git a/mkrtos_script/build_f2.sh b/mkrtos_script/build_f2.sh index 5266850b6..b452f4226 100755 --- a/mkrtos_script/build_f2.sh +++ b/mkrtos_script/build_f2.sh @@ -4,10 +4,10 @@ # export TOOLCHAIN_LIB=/home/zhangzheng/mkrtos-tools/gcc/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m/ # export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/ # export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp -# export TOOLCHAIN=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/bin/ -# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp -export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/ -export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m/ +export TOOLCHAIN=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/bin/ +export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp +# export TOOLCHAIN=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/bin/ +# export TOOLCHAIN_LIB=/home/zhangzheng/gcc-arm-none-eabi-5_4-2016q3/lib/gcc/arm-none-eabi/5.4.1/armv7-m/ export BOARD=STM32F205 export CROSS_COMPILE_NAME=arm-none-eabi- diff --git a/mkrtos_script/debug_aarch64_qemu.sh b/mkrtos_script/debug_aarch64_qemu.sh index b09f3eb66..f0500d598 100755 --- a/mkrtos_script/debug_aarch64_qemu.sh +++ b/mkrtos_script/debug_aarch64_qemu.sh @@ -8,9 +8,10 @@ fi # -machine virt,virtualization=on,gic-version=2,highmem=off,secure=off,dumpdtb=virt.dtb qemu-system-aarch64 \ -machine virt,virtualization=on,gic-version=2,highmem=off,secure=off\ + -device virtio-gpu-pci \ -cpu cortex-a57 \ -nographic \ -m size=512 \ - -smp 4,cores=4 \ + -smp 4\ -kernel $PWD/build/output/bootstrap.elf \ -S -gdb tcp::$1 diff --git a/mkrtos_script/run_aarch64_qemu.sh b/mkrtos_script/run_aarch64_qemu.sh index 520b3b020..a4c9852cd 100755 --- a/mkrtos_script/run_aarch64_qemu.sh +++ b/mkrtos_script/run_aarch64_qemu.sh @@ -1,8 +1,12 @@ #!/bin/bash # -machine virt,virtualization=on,gic-version=2,highmem=off,secure=off,dumpdtb=virt.dtb +# -display gtk,gl=on +# -drive file=$XXX,if=none,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 +# -device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp::$2-:6666 -object filter-dump,id=f1, netdev=net0,file=dump.dat qemu-system-aarch64 \ - -machine virt,virtualization=on,gic-version=2,highmem=off,secure=off\ + -machine virt,virtualization=on,gic-version=2,highmem=off,secure=off \ + -device virtio-gpu-pci \ -cpu cortex-a53 \ -nographic \ -m size=512 \ diff --git a/mkrtos_user/lib/CMakeLists.txt b/mkrtos_user/lib/CMakeLists.txt index 5fada088b..70af343e7 100644 --- a/mkrtos_user/lib/CMakeLists.txt +++ b/mkrtos_user/lib/CMakeLists.txt @@ -7,7 +7,6 @@ if (${ARCH_NAME} STREQUAL "armv7_8m") add_subdirectory(stm32f1_bsp) add_subdirectory(mlibc) add_subdirectory(mr) - add_subdirectory(lwip) # add_subdirectory(at_device) elseif(${CONFIG_ARCH} STREQUAL "aarch64") add_subdirectory(mkrtos-musl) @@ -20,4 +19,5 @@ add_subdirectory(libc_backend) add_subdirectory(cpio) add_subdirectory(letter-shell/demo/mkrtos) add_subdirectory(printf) +add_subdirectory(lwip) diff --git a/mkrtos_user/lib/lwip/CMakeLists.txt b/mkrtos_user/lib/lwip/CMakeLists.txt index 6bc754542..aa904ff53 100644 --- a/mkrtos_user/lib/lwip/CMakeLists.txt +++ b/mkrtos_user/lib/lwip/CMakeLists.txt @@ -37,12 +37,11 @@ target_include_directories( target_link_libraries( lwip PUBLIC - muslc + ${LIBC_NAME} sys util ) add_dependencies(lwip - muslc util sys ) diff --git a/mkrtos_user/lib/sys_util/inc/u_rpc.h b/mkrtos_user/lib/sys_util/inc/u_rpc.h index ca6b6d0d3..d6941231a 100644 --- a/mkrtos_user/lib/sys_util/inc/u_rpc.h +++ b/mkrtos_user/lib/sys_util/inc/u_rpc.h @@ -371,6 +371,8 @@ RPC_ARRAY_DEF(uint32_t, uint8_t, 32) RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 32) RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 48) RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 64) +RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 128) +RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 256) /** * @brief Construct a new rpc type def object diff --git a/mkrtos_user/lib/sys_util/src/u_elf_loader.c b/mkrtos_user/lib/sys_util/src/u_elf_loader.c index 3e7c7b471..b8191c228 100644 --- a/mkrtos_user/lib/sys_util/src/u_elf_loader.c +++ b/mkrtos_user/lib/sys_util/src/u_elf_loader.c @@ -29,7 +29,7 @@ #include #include #include - +#include /** * @brief 向栈中存放数据 * @@ -314,7 +314,7 @@ int app_load(const char *name, uenv_t *cur_env, pid_t *pid, char *argv[], int ar } /*启动线程运行*/ - tag = thread_run(hd_thread, 2); + tag = thread_run_cpu(hd_thread, 2, rand() % CONFIG_CPU); assert(msg_tag_get_prot(tag) >= 0); task_unmap(TASK_THIS, vpage_create_raw3(0, 0, hd_thread)); handler_free(hd_thread); diff --git a/mkrtos_user/lib/sys_util/src/u_sleep.c b/mkrtos_user/lib/sys_util/src/u_sleep.c index 60ed90aeb..c764665e4 100644 --- a/mkrtos_user/lib/sys_util/src/u_sleep.c +++ b/mkrtos_user/lib/sys_util/src/u_sleep.c @@ -12,5 +12,6 @@ static obj_handler_t hd = HANDLER_INVALID; void u_sleep_ms(size_t ms) { - thread_ipc_wait(ipc_timeout_create2(0, ms / (1000 / CONFIG_SYS_SCHE_HZ)), NULL, -1); + umword_t sleep_tick = ROUND_UP(ms, (1000 / CONFIG_SYS_SCHE_HZ)); + thread_ipc_wait(ipc_timeout_create2(0, sleep_tick), NULL, -1); } diff --git a/mkrtos_user/server/CMakeLists.txt b/mkrtos_user/server/CMakeLists.txt index 56ee253a5..dcfc8477c 100644 --- a/mkrtos_user/server/CMakeLists.txt +++ b/mkrtos_user/server/CMakeLists.txt @@ -8,9 +8,6 @@ if (${ARCH_NAME} STREQUAL "armv7_8m") set(START_INIT_LIB start_init) # add_subdirectory(app) - add_subdirectory(drv) - # add_subdirectory(net) - # add_subdirectory(tcc-0.9.27) elseif(${CONFIG_ARCH} STREQUAL "aarch64" ) set( START_LIB @@ -37,4 +34,6 @@ add_subdirectory(tinycc-arm-thumb) add_subdirectory(fs) add_subdirectory(hello) add_subdirectory(test) +add_subdirectory(drv) +add_subdirectory(net) diff --git a/mkrtos_user/server/drv/CMakeLists.txt b/mkrtos_user/server/drv/CMakeLists.txt index f66164081..bc82b1180 100644 --- a/mkrtos_user/server/drv/CMakeLists.txt +++ b/mkrtos_user/server/drv/CMakeLists.txt @@ -4,6 +4,10 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMKRTOS_DRV ") # add_subdirectory(mr_drv) # add_subdirectory(rtthread_drv) +if (${BOARD} STREQUAL "STM32F103ZET6") + add_subdirectory(dm9000_drv) +elseif(${BOARD} STREQUAL "STM32F205" ) -# add_subdirectory(dm9000_drv) -# add_subdirectory(lcd_drv) \ No newline at end of file +elseif(${BOARD} STREQUAL "SWM34" ) + add_subdirectory(lcd_drv) +endif() diff --git a/mkrtos_user/server/init/src/cons.c b/mkrtos_user/server/init/src/cons.c index 398feda8b..f95fefb1c 100644 --- a/mkrtos_user/server/init/src/cons.c +++ b/mkrtos_user/server/init/src/cons.c @@ -15,8 +15,14 @@ #include #include #include +#include -static ATTR_ALIGN(8) uint8_t cons_stack[1024]; +#if IS_ENABLED(CONFIG_MMU) +#define CONS_STACK_SIZE 1024 +#else +#define CONS_STACK_SIZE 512 +#endif +static ATTR_ALIGN(8) uint8_t cons_stack[CONS_STACK_SIZE]; // static uint8_t cons_msg_buf[MSG_BUG_LEN]; static cons_t cons_obj; static obj_handler_t cons_th; @@ -49,7 +55,7 @@ void console_init(void) cons_svr_obj_init(&cons_obj); meta_reg_svr_obj(&cons_obj.svr, CONS_PROT); u_thread_create(&cons_th, (char *)cons_stack + sizeof(cons_stack) - 8, NULL, console_read_func); - u_thread_run(cons_th, 2); + u_thread_run(cons_th, 16); ulog_write_str(LOG_PROT, "cons svr init...\n"); } /** @@ -96,6 +102,7 @@ int console_read(uint8_t *data, size_t len) } else { + memcpy(data, "1234\r\n", 6); pthread_spin_lock(&cons_obj.r_lock); if (q_queue_len(&cons_obj.r_queue) == 0) { diff --git a/mkrtos_user/server/init/src/init.cfg b/mkrtos_user/server/init/src/init.cfg index 8d84fcff8..69e3c8fa0 100644 --- a/mkrtos_user/server/init/src/init.cfg +++ b/mkrtos_user/server/init/src/init.cfg @@ -3,6 +3,6 @@ # fatfs # dm9000_drv # net -# cpiofs -sh -# lcd_drv \ No newline at end of file +# lcd_drv +cpiofs +sh \ No newline at end of file diff --git a/mkrtos_user/server/init/src/parse_cfg.c b/mkrtos_user/server/init/src/parse_cfg.c index 31dba34dc..b95ca002f 100644 --- a/mkrtos_user/server/init/src/parse_cfg.c +++ b/mkrtos_user/server/init/src/parse_cfg.c @@ -74,7 +74,7 @@ int parse_cfg(const char *parse_cfg_file_name, uenv_t *env) } pid_t pid; char *args[] = { - name, + "xx",/**FIXME: */ "-t" }; int ret = app_load(name, env, &pid, args, 2, NULL, 0); diff --git a/mkrtos_user/server/init/src/test/thread_cpu_test.c b/mkrtos_user/server/init/src/test/thread_cpu_test.c index 7168eab71..106aa4f74 100644 --- a/mkrtos_user/server/init/src/test/thread_cpu_test.c +++ b/mkrtos_user/server/init/src/test/thread_cpu_test.c @@ -11,12 +11,15 @@ #include "u_sleep.h" #include "u_vmam.h" #include +#include static umword_t th1_hd = 0; static umword_t th2_hd = 0; #define STACK_SIZE 4096 static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; static __attribute__((aligned(8))) uint8_t stack1[STACK_SIZE]; + +#if IS_ENABLED(CONFIG_MMU) //! 读取系统寄存器 #define read_sysreg(reg) ({ \ unsigned long _val; \ @@ -28,20 +31,43 @@ static inline int arch_get_current_cpu_id(void) { return read_sysreg(mpidr_el1) & 0XFFUL; } +#else +static inline int arch_get_current_cpu_id(void) +{ + return 0; +} +#endif static void thread_test_func(void) { - printf("[u]thread run %d cpu.\n", arch_get_current_cpu_id()); + u_sleep_ms(500); + printf("[u]thread1 run %d cpu.\n", arch_get_current_cpu_id()); + while (1) + { + thread_run_cpu(th1_hd, 2, rand() % (CONFIG_CPU)); + u_sleep_ms(5); /*TODO:*/ + printf("[u]thread1 run %d cpu.\n", arch_get_current_cpu_id()); + } handler_free_umap(th1_hd); printf("Error\n"); } - +static void thread_test_func2(void) +{ + u_sleep_ms(500); + while (1) + { + thread_run_cpu(th2_hd, 2, rand() % (CONFIG_CPU)); + u_sleep_ms(5); /*TODO:*/ + printf("[u]thread2 run %d cpu.\n", arch_get_current_cpu_id()); + } + handler_free_umap(th2_hd); + printf("Error\n"); +} void thread_cpu_test(void) { th1_hd = handler_alloc(); assert(th1_hd != HANDLER_INVALID); msg_tag_t tag; void *mem; - u_sleep_ms(500); tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd)); assert(msg_tag_get_prot(tag) >= 0); @@ -50,12 +76,12 @@ void thread_cpu_test(void) tag = thread_exec_regs(th1_hd, (umword_t)thread_test_func, (umword_t)stack0 + STACK_SIZE - 8, TASK_RAM_BASE(), 0); assert(msg_tag_get_prot(tag) >= 0); tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RW, 0, 0), PAGE_SIZE, 0, (addr_t *)(&mem)); - assert(msg_tag_get_prot(tag) >= 0); + assert(msg_tag_get_prot(tag) >= 0); memset((void *)mem, 0, PAGE_SIZE); // 设置msgbuff tag = thread_msg_buf_set(th1_hd, mem); - assert(msg_tag_get_prot(tag) >= 0); - tag = thread_run_cpu(th1_hd, 2, 1); + assert(msg_tag_get_prot(tag) >= 0); + tag = thread_run_cpu(th1_hd, 2, 3); th2_hd = handler_alloc(); assert(th2_hd != HANDLER_INVALID); @@ -64,7 +90,7 @@ void thread_cpu_test(void) assert(msg_tag_get_prot(tag) >= 0); tag = thread_bind_task(th2_hd, TASK_THIS); assert(msg_tag_get_prot(tag) >= 0); - tag = thread_exec_regs(th2_hd, (umword_t)thread_test_func, (umword_t)stack1 + STACK_SIZE - 8, TASK_RAM_BASE(), 0); + tag = thread_exec_regs(th2_hd, (umword_t)thread_test_func2, (umword_t)stack1 + STACK_SIZE - 8, TASK_RAM_BASE(), 0); assert(msg_tag_get_prot(tag) >= 0); tag = u_vmam_alloc(VMA_PROT, vma_addr_create(VPAGE_PROT_RW, 0, 0), PAGE_SIZE, 0, (addr_t *)(&mem)); assert(msg_tag_get_prot(tag) >= 0); @@ -72,7 +98,5 @@ void thread_cpu_test(void) // 设置msgbuff tag = thread_msg_buf_set(th2_hd, mem); assert(msg_tag_get_prot(tag) >= 0); - tag = thread_run_cpu(th2_hd, 2, 3); - - u_sleep_ms(500); + tag = thread_run_cpu(th2_hd, 2, 2); } diff --git a/mkrtos_user/server/net/CMakeLists.txt b/mkrtos_user/server/net/CMakeLists.txt index 5a2b767f0..4344edd6a 100644 --- a/mkrtos_user/server/net/CMakeLists.txt +++ b/mkrtos_user/server/net/CMakeLists.txt @@ -2,26 +2,21 @@ cmake_minimum_required(VERSION 3.13) file(GLOB_RECURSE deps *.c *.S) -# file(GLOB bsp_src -# ${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/*.c -# ) -# list(APPEND deps ${bsp_src}) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_STDPERIPH_DRIVER=1 -DSTM32F10X_HD\ -") - - add_executable(net.elf ${deps} + ${START_SRC} ) target_link_libraries(net.elf PUBLIC - start - muslc + ${START_LIB} + ${LIBC_NAME} lwip + --whole-archive + libc_be sys sys_util sys_svr + --no-whole-archive ${GCC_LIB_PATH}/libgcc.a ) target_include_directories( @@ -34,29 +29,9 @@ target_include_directories( ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/lwip/src/include ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/lwip/src/include/lwip/apps ${CMAKE_SOURCE_DIR}/mkrtos_user/server/net/inc - - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/ - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/src/internal - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/src/include - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/src/internal - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/include - ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/include - - # ${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc - # ${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/Include - # ${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - # ${CMAKE_SOURCE_DIR}/mkrtos_bsp/STM32/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport - -) -add_dependencies(net.elf -muslc -lwip -start ) set_target_properties(net.elf PROPERTIES LINK_FLAGS -"-T ${CMAKE_CURRENT_LIST_DIR}/link.lds -pie --gc-section -no-dynamic-linker " -#--no-warn-rwx-segments +"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker " ) add_custom_target( net_dump ALL @@ -71,13 +46,17 @@ add_custom_target( COMMAND cp net.elf ${CMAKE_SOURCE_DIR}/build/output/net.elf ) - +if ((DEFINED CONFIG_ELF_LAUNCH) AND (CONFIG_ELF_LAUNCH STREQUAL "y")) + add_custom_target( + net_dump_elf ALL + COMMAND + cp net.elf ${CMAKE_SOURCE_DIR}/build/output/cpio/net + ) + add_dependencies(net_dump_elf shell_dump) +endif() add_dependencies(net_dump net.elf) -add_dependencies(net_dump sys) -add_dependencies(net_dump sys_util) -add_dependencies(net_dump mr) -add_dependencies(net_dump sys_svr) -add_dependencies(net_dump start) -add_dependencies(net_dump muslc) -add_dependencies(net_dump lwip) +add_dependencies(net.elf sys) +add_dependencies(net.elf sys_util) +add_dependencies(net.elf sys_svr) +add_dependencies(net.elf lwip) \ No newline at end of file diff --git a/mkrtos_user/server/net/aarch64/link.lds b/mkrtos_user/server/net/aarch64/link.lds new file mode 100644 index 000000000..17d87bdc3 --- /dev/null +++ b/mkrtos_user/server/net/aarch64/link.lds @@ -0,0 +1,233 @@ +/* Script for -z combreloc */ +/* Copyright (C) 2014-2021 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", + "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SEARCH_DIR("//aarch64-none-elf/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x01400000)); . = SEGMENT_START("text-segment", 0x01400000); + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + *(.rela.ifunc) + } + .rela.plt : + { + *(.rela.plt) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .init : + { + KEEP (*(SORT_NONE(.init))) + } =0x1f2003d5 + .plt : { *(.plt) *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(SORT(.text.sorted.*)) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf.em. */ + *(.gnu.warning) + . = ALIGN(4); + _shell_command_start = .; + KEEP(*(shellCommand)) + _shell_command_end = .; + } =0x1f2003d5 + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } =0x1f2003d5 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got) *(.igot) } + .got.plt : { *(.got.plt) *(.igot.plt) } + .data : + { + __data_start = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + __bss_start__ = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 64 / 8 : 1); + } + _bss_end__ = .; __bss_end__ = .; + . = ALIGN(64 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(64 / 8); + __end__ = .; + _end = .; PROVIDE (end = .); + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} \ No newline at end of file diff --git a/mkrtos_user/server/net/link.lds b/mkrtos_user/server/net/armv7_8m/link.lds similarity index 100% rename from mkrtos_user/server/net/link.lds rename to mkrtos_user/server/net/armv7_8m/link.lds diff --git a/mkrtos_user/server/net/src/heap_stack.c b/mkrtos_user/server/net/src/heap_stack.c index 8dd4239c3..283abdc21 100644 --- a/mkrtos_user/server/net/src/heap_stack.c +++ b/mkrtos_user/server/net/src/heap_stack.c @@ -1,4 +1,5 @@ - +#include +#if !IS_ENABLED(CONFIG_MMU) #define HEAP_SIZE 10 * 1024 #define STACK_SIZE (1024+256) @@ -15,3 +16,4 @@ __attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE]; __attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE]; +#endif \ No newline at end of file diff --git a/mkrtos_user/server/net/src/main.c b/mkrtos_user/server/net/src/main.c index 3013a0c15..e99d147a7 100644 --- a/mkrtos_user/server/net/src/main.c +++ b/mkrtos_user/server/net/src/main.c @@ -6,7 +6,7 @@ #include #include #include "u_sleep.h" -#include "libc.h" +// #include "libc.h" #include "lwiperf.h" #include "u_prot.h" #include "u_mm.h" @@ -20,12 +20,11 @@ umword_t addr; umword_t size; obj_handler_t net_drv_hd; -extern void EXTI15_10_IRQHandler(void); int main(int args, char *argv[]) { int ret; msg_tag_t tag; - + printf("net startup..\n"); ret = ns_query("/dm9000", &net_drv_hd); assert(ret >= 0); diff --git a/mkrtos_user/server/shell/CMakeLists.txt b/mkrtos_user/server/shell/CMakeLists.txt index 82853f397..171cfa2c4 100644 --- a/mkrtos_user/server/shell/CMakeLists.txt +++ b/mkrtos_user/server/shell/CMakeLists.txt @@ -10,8 +10,8 @@ target_link_libraries(sh.elf PUBLIC -Bstatic ${LIBC_NAME} - ${START_LIB} --whole-archive + ${START_LIB} libc_be sys sys_util diff --git a/mkrtos_user/server/test/src/factory_test.c b/mkrtos_user/server/test/src/factory_test.c index 679df76a9..dbf93a400 100644 --- a/mkrtos_user/server/test/src/factory_test.c +++ b/mkrtos_user/server/test/src/factory_test.c @@ -15,4 +15,5 @@ static void factory_test(void) msg_tag_t tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd)); assert(msg_tag_get_prot(tag) >= 0); handler_free_umap(hd); + printf("%s test ok.\n", __func__); }