From 9b92c71a211767ecc343566da064d3ff130126ec Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Tue, 12 Mar 2024 16:31:21 +0800 Subject: [PATCH 01/24] Start supporting smp. --- .../preboot_for_imx6q-sabrelite/boot.S | 7 +++---- .../cortex-a9/imx6q-sabrelite/trap_common.c | 6 ++++++ .../cortex-a9/zynq7000-zc702/trap_common.c | 6 ++++++ .../XiZi_AIoT/hardkernel/intr/trap_common.h | 1 + Ubiquitous/XiZi_AIoT/softkernel/main.c | 17 +++++++++++++---- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S index d3f824508..2f5ab4867 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/boot.S @@ -84,11 +84,10 @@ _boot_start: @ check cpu id - cpu0 is primary cpu cmp r5, #0 beq primary_cpu_init - bx r4 @ for secondary cpus, jump to argument function pointer passed in by ROM - - @ control should not return from the secondary cpu entry point - b . + bl bootmain @ for secondary cpus, jump to argument function pointer passed in by ROM + bl . + primary_cpu_init: /* init .bss */ /* clear the .bss section (zero init) */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index 3e1acbc0d..8cb244967 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -213,8 +213,14 @@ static int _is_interruptable(void) return !(val & DIS_INT); } +int _cur_cpu_id() +{ + return cpu_get_current(); +} + static struct XiziTrapDriver xizi_trap_driver = { .sys_irq_init = _sys_irq_init, + .cur_cpu_id = _cur_cpu_id, .cpu_irq_enable = _cpu_irq_enable, .cpu_irq_disable = _cpu_irq_disable, diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c index 4d06f20f4..de89cbd21 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c @@ -215,8 +215,14 @@ static int _is_interruptable(void) return !(val & DIS_INT); } +int _cur_cpu_id() +{ + return cpu_get_current(); +} + static struct XiziTrapDriver xizi_trap_driver = { .sys_irq_init = _sys_irq_init, + .cur_cpu_id = _cur_cpu_id, .cpu_irq_enable = _cpu_irq_enable, .cpu_irq_disable = _cpu_irq_disable, diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h index 327f856b1..19c6831e0 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h @@ -60,6 +60,7 @@ struct XiziTrapDriver { uint32_t curr_int[NR_CPU]; void (*sys_irq_init)(); + int (*cur_cpu_id)(); void (*cpu_irq_enable)(); void (*cpu_irq_disable)(); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index d283b4b27..95dc72341 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -53,11 +53,20 @@ int main(void) if (!hardkernel_init(&hardkernel_tag)) { return -1; } - /* init softkernel */ - if (!softkernel_init(&hardkernel_tag, &softkernel_tag)) { - return -1; + + struct TraceTag main_intr_tag; + AchieveResourceTag(&main_intr_tag, &hardkernel_tag, "intr-ac-resource"); + struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&main_intr_tag); + int cpu_id = p_intr_driver->cur_cpu_id(); + if (cpu_id == 0) { + /* init softkernel */ + if (!softkernel_init(&hardkernel_tag, &softkernel_tag)) { + return -1; + } + show_xizi_bar(); + + int cpu_count = NR_CPU; } - show_xizi_bar(); /* start first task */ char* init_task_param[2] = { "/app/init", 0 }; From 01f4d45e0c7928095593975b3c2f444c7bf86968 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Wed, 13 Mar 2024 17:56:49 +0800 Subject: [PATCH 02/24] Start multi cores in imx6q --- .../arch/arm/armv7-a/cortex-a9/core.h | 4 +- .../preboot_for_imx6q-sabrelite/cortexA9.S | 13 +- .../include/regssrc.h | 1892 +++++++++++++++++ .../XiZi_AIoT/hardkernel/hardkernel_init.c | 28 + .../cortex-a9/imx6q-sabrelite/trap_common.c | 28 +- .../intr/arm/armv7-a/cortex-a9/spinlock.c | 5 +- .../cortex-a9/zynq7000-zc702/trap_common.c | 26 +- .../XiZi_AIoT/hardkernel/intr/trap_common.h | 2 +- .../mmu/arm/armv7-a/cortex-a9/bootmmu.c | 3 +- .../XiZi_AIoT/kernel_actracer/actracer.c | 13 +- Ubiquitous/XiZi_AIoT/services/app/init.c | 6 +- .../services/fs/fs_server/fs_server.c | 2 +- .../XiZi_AIoT/softkernel/include/kern_init.h | 1 + .../XiZi_AIoT/softkernel/include/multicores.h | 5 +- .../XiZi_AIoT/softkernel/include/pagetable.h | 1 + Ubiquitous/XiZi_AIoT/softkernel/main.c | 149 +- .../XiZi_AIoT/softkernel/memory/pagetable.c | 6 + .../softkernel/trap/clock_irq_handler.c | 3 + .../softkernel/trap/default_irq_handler.c | 2 + .../softkernel/trap/software_irq_handler.c | 10 + 20 files changed, 2136 insertions(+), 63 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regssrc.h diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index 81eab608a..e6e96ea7e 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -50,7 +50,7 @@ Modification: #define CPSR_MODE (0x1f) //!< Current processor mode //@} -#define MODE_STACK_SIZE 0x4000 +#define MODE_STACK_SIZE 0x1000 //! @name Interrupt enable bits in CPSR //@{ @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 4 +#define NR_CPU 2 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S index dd2483c3a..3ef2446fc 100755 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/cortexA9.S @@ -71,7 +71,7 @@ arm_set_interrupt_state: cpu_get_current: mrc p15, 0, r0, c0, c0, 5 and r0, r0, #3 - BX lr + BX lr .endfunc @cpu_get_current()@ .global enable_neon_fpu @@ -128,8 +128,8 @@ disable_L1_cache: get_arm_private_peripheral_base: @ Get base address of private perpherial space - mrc p15, 4, r0, c15, c0, 0 @ Read periph base address - @ mov r0, #0x00A00000 + @ mrc p15, 4, r0, c15, c0, 0 @ Read periph base address + mov r0, #0x00A00000 bx lr .endfunc @get_arm_private_peripheral_base()@ @@ -213,7 +213,8 @@ arm_branch_target_cache_invalidate_is: scu_enable: @ mrc p15, 4, r0, c15, c0, 0 @ Read periph base address - mov r0, #0x00A00000 + mov r0, #0x00A00000 + add r0, #0x80000000 ldr r1, [r0, #0x0] @ Read the SCU Control Register orr r1, r1, #0x1 @ Set bit 0 (The Enable bit) @@ -268,7 +269,8 @@ scu_leave_smp: scu_get_cpus_in_smp: @ mrc p15, 4, r0, c15, c0, 0 @ Read periph base address - mov r0, #0x00A00000 + mov r0, #0x00A00000 + add r0, #0x80000000 ldr r0, [r0, #0x004] @ Read SCU Configuration register mov r0, r0, lsr #4 @ Bits 7:4 gives the cores in SMP mode, shift then mask @@ -327,6 +329,7 @@ scu_secure_invalidate: mov r1, r1, lsl r0 @ Shift ways into the correct CPU field mrc p15, 4, r2, c15, c0, 0 @ Read periph base address + add r2, #0x80000000 str r1, [r2, #0x0C] @ Write to SCU Invalidate All in Secure State diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regssrc.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regssrc.h new file mode 100644 index 000000000..ec7b6e288 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/include/regssrc.h @@ -0,0 +1,1892 @@ +/* + * Copyright (c) 2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL FREESCALE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ +/* + * WARNING! DO NOT EDIT THIS FILE DIRECTLY! + * + * This file was generated automatically and any changes may be lost. + */ +#ifndef __HW_SRC_REGISTERS_H__ +#define __HW_SRC_REGISTERS_H__ + +#include "mmio_access.h" +#include "regs.h" + +/* + * i.MX6DQ SRC + * + * SRC + * + * Registers defined in this header file: + * - HW_SRC_SCR - SRC Control Register + * - HW_SRC_SBMR1 - SRC Boot Mode Register 1 + * - HW_SRC_SRSR - SRC Reset Status Register + * - HW_SRC_SISR - SRC Interrupt Status Register + * - HW_SRC_SIMR - SRC Interrupt Mask Register + * - HW_SRC_SBMR2 - SRC Boot Mode Register 2 + * - HW_SRC_GPR1 - SRC General Purpose Register 1 + * - HW_SRC_GPR2 - SRC General Purpose Register 2 + * - HW_SRC_GPR3 - SRC General Purpose Register 3 + * - HW_SRC_GPR4 - SRC General Purpose Register 4 + * - HW_SRC_GPR5 - SRC General Purpose Register 5 + * - HW_SRC_GPR6 - SRC General Purpose Register 6 + * - HW_SRC_GPR7 - SRC General Purpose Register 7 + * - HW_SRC_GPR8 - SRC General Purpose Register 8 + * - HW_SRC_GPR9 - SRC General Purpose Register 9 + * - HW_SRC_GPR10 - SRC General Purpose Register 10 + * + * - hw_src_t - Struct containing all module registers. + */ + +//! @name Module base addresses +//@{ +#ifndef REGS_SRC_BASE +#define HW_SRC_INSTANCE_COUNT (1) //!< Number of instances of the SRC module. +#define REGS_SRC_BASE MMIO_P2V_WO(0x020d8000) //!< Base address for SRC. +#endif +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_SCR - SRC Control Register +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_SCR - SRC Control Register (RW) + * + * Reset value: 0x00000521 + * + * The Reset control register (SCR), contains bits that control operation of the reset controller. + */ +typedef union _hw_src_scr { + reg32_t U; + struct _hw_src_scr_bitfields { + unsigned WARM_RESET_ENABLE : 1; //!< [0] WARM reset enable bit. + unsigned SW_GPU_RST : 1; //!< [1] Software reset for gpu + unsigned SW_VPU_RST : 1; //!< [2] Software reset for vpu + unsigned SW_IPU1_RST : 1; //!< [3] Software reset for ipu1 + unsigned SW_OPEN_VG_RST : 1; //!< [4] Software reset for open_vg + unsigned WARM_RST_BYPASS_COUNT : 2; //!< [6:5] Defines the ckil cycles to count before bypassing the MMDC acknowledge for WARM reset. + unsigned MASK_WDOG_RST : 4; //!< [10:7] Mask wdog_rst_b source. + unsigned EIM_RST : 1; //!< [11] EIM reset is needed in order to reconfigure the eim chip select. + unsigned SW_IPU2_RST : 1; //!< [12] Software reset for ipu2 + unsigned CORE0_RST : 1; //!< [13] Software reset for core0 only. + unsigned CORE1_RST : 1; //!< [14] Software reset for core1 only. + unsigned CORE2_RST : 1; //!< [15] Software reset for core2 only. + unsigned CORE3_RST : 1; //!< [16] Software reset for core3 only. + unsigned CORE0_DBG_RST : 1; //!< [17] Software reset for core0 debug only. + unsigned CORE1_DBG_RST : 1; //!< [18] Software reset for core1 debug only. + unsigned CORE2_DBG_RST : 1; //!< [19] Software reset for core2 debug only. + unsigned CORE3_DBG_RST : 1; //!< [20] Software reset for core3 debug only. + unsigned CORES_DBG_RST : 1; //!< [21] Software reset for debug of arm platform only. + unsigned CORE1_ENABLE : 1; //!< [22] CPU core1 enable. + unsigned CORE2_ENABLE : 1; //!< [23] CPU core2 enable. + unsigned CORE3_ENABLE : 1; //!< [24] CPU core3 enable. + unsigned DBG_RST_MSK_PG : 1; //!< [25] Do not assert debug resets after power gating event of cpu + unsigned RESERVED0 : 6; //!< [31:26] Reserved + } B; +} hw_src_scr_t; +#endif + +/*! + * @name Constants and macros for entire SRC_SCR register + */ +//@{ +#define HW_SRC_SCR_ADDR (REGS_SRC_BASE + 0x0) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_SCR (*(volatile hw_src_scr_t*)HW_SRC_SCR_ADDR) +#define HW_SRC_SCR_RD() (HW_SRC_SCR.U) +#define HW_SRC_SCR_WR(v) (HW_SRC_SCR.U = (v)) +#define HW_SRC_SCR_SET(v) (HW_SRC_SCR_WR(HW_SRC_SCR_RD() | (v))) +#define HW_SRC_SCR_CLR(v) (HW_SRC_SCR_WR(HW_SRC_SCR_RD() & ~(v))) +#define HW_SRC_SCR_TOG(v) (HW_SRC_SCR_WR(HW_SRC_SCR_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_SCR bitfields + */ + +/*! @name Register SRC_SCR, field WARM_RESET_ENABLE[0] (RW) + * + * WARM reset enable bit. WARM reset will be enabled only if warm_reset_enable bit is set. Otherwise + * all WARM reset sources will generate COLD reset. + * + * Values: + * - 0 - WARM reset disabled + * - 1 - WARM reset enabled + */ +//@{ +#define BP_SRC_SCR_WARM_RESET_ENABLE (0) //!< Bit position for SRC_SCR_WARM_RESET_ENABLE. +#define BM_SRC_SCR_WARM_RESET_ENABLE (0x00000001) //!< Bit mask for SRC_SCR_WARM_RESET_ENABLE. + +//! @brief Get value of SRC_SCR_WARM_RESET_ENABLE from a register value. +#define BG_SRC_SCR_WARM_RESET_ENABLE(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_WARM_RESET_ENABLE) >> BP_SRC_SCR_WARM_RESET_ENABLE) + +//! @brief Format value for bitfield SRC_SCR_WARM_RESET_ENABLE. +#define BF_SRC_SCR_WARM_RESET_ENABLE(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_WARM_RESET_ENABLE) & BM_SRC_SCR_WARM_RESET_ENABLE) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the WARM_RESET_ENABLE field to a new value. +#define BW_SRC_SCR_WARM_RESET_ENABLE(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_WARM_RESET_ENABLE) | BF_SRC_SCR_WARM_RESET_ENABLE(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field SW_GPU_RST[1] (RW) + * + * Software reset for gpu this is a self clearing bit. Once it is set to 1, the reset process will + * begin, and once it finishes, this bit will be self cleared. Software can determine that the reset + * has finished once this bit is cleared. Software can also configure SRC to generate interrupt once + * the software has finished. Please refer to SISR register for details. the reset process will + * involve 8 gpu cycles before negating the gpu reset, to allow reset assertion to propagate into + * gpu. + * + * Values: + * - 0 - do not assert gpu reset + * - 1 - assert gpu reset + */ +//@{ +#define BP_SRC_SCR_SW_GPU_RST (1) //!< Bit position for SRC_SCR_SW_GPU_RST. +#define BM_SRC_SCR_SW_GPU_RST (0x00000002) //!< Bit mask for SRC_SCR_SW_GPU_RST. + +//! @brief Get value of SRC_SCR_SW_GPU_RST from a register value. +#define BG_SRC_SCR_SW_GPU_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_SW_GPU_RST) >> BP_SRC_SCR_SW_GPU_RST) + +//! @brief Format value for bitfield SRC_SCR_SW_GPU_RST. +#define BF_SRC_SCR_SW_GPU_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_SW_GPU_RST) & BM_SRC_SCR_SW_GPU_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the SW_GPU_RST field to a new value. +#define BW_SRC_SCR_SW_GPU_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_SW_GPU_RST) | BF_SRC_SCR_SW_GPU_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field SW_VPU_RST[2] (RW) + * + * Software reset for vpu this is a self clearing bit. Once it is set to 1, the reset process will + * begin, and once it finishes, this bit will be self cleared. Software can determine that the reset + * has finished once this bit is cleared. Software can also configure SRC to generate interrupt once + * the software has finished. Please refer to SISR register for details. the reset process will + * involve 8 vpu cycles before negating the vpu reset, to allow reset assertion to propagate into + * vpu. + * + * Values: + * - 0 - do not assert vpu reset + * - 1 - assert vpu reset + */ +//@{ +#define BP_SRC_SCR_SW_VPU_RST (2) //!< Bit position for SRC_SCR_SW_VPU_RST. +#define BM_SRC_SCR_SW_VPU_RST (0x00000004) //!< Bit mask for SRC_SCR_SW_VPU_RST. + +//! @brief Get value of SRC_SCR_SW_VPU_RST from a register value. +#define BG_SRC_SCR_SW_VPU_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_SW_VPU_RST) >> BP_SRC_SCR_SW_VPU_RST) + +//! @brief Format value for bitfield SRC_SCR_SW_VPU_RST. +#define BF_SRC_SCR_SW_VPU_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_SW_VPU_RST) & BM_SRC_SCR_SW_VPU_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the SW_VPU_RST field to a new value. +#define BW_SRC_SCR_SW_VPU_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_SW_VPU_RST) | BF_SRC_SCR_SW_VPU_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field SW_IPU1_RST[3] (RW) + * + * Software reset for ipu1 Note: this is a self clearing bit. Once it is set to 1, the reset process + * will begin, and once it finishes, this bit will be self cleared. Software can determine that the + * reset has finished once this bit is cleared. Software can also configure SRC to generate + * interrupt once the software has finished. Please refer to SISR register for details. + * + * Values: + * - 0 - do not assert ipu1 reset + * - 1 - assert ipu1 reset + */ +//@{ +#define BP_SRC_SCR_SW_IPU1_RST (3) //!< Bit position for SRC_SCR_SW_IPU1_RST. +#define BM_SRC_SCR_SW_IPU1_RST (0x00000008) //!< Bit mask for SRC_SCR_SW_IPU1_RST. + +//! @brief Get value of SRC_SCR_SW_IPU1_RST from a register value. +#define BG_SRC_SCR_SW_IPU1_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_SW_IPU1_RST) >> BP_SRC_SCR_SW_IPU1_RST) + +//! @brief Format value for bitfield SRC_SCR_SW_IPU1_RST. +#define BF_SRC_SCR_SW_IPU1_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_SW_IPU1_RST) & BM_SRC_SCR_SW_IPU1_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the SW_IPU1_RST field to a new value. +#define BW_SRC_SCR_SW_IPU1_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_SW_IPU1_RST) | BF_SRC_SCR_SW_IPU1_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field SW_OPEN_VG_RST[4] (RW) + * + * Software reset for open_vg This is a self clearing bit. Once it is set to 1, the reset process + * will begin, and once it finishes, this bit will be self cleared. Software can determine that the + * reset has finished once this bit is cleared. Software can also configure SRC to generate + * interrupt once the software has finished. Please refer to SISR register for details. The reset + * process will involve 8 open_vg cycles before negating the open_vg reset, to allow reset assertion + * to propagate into open_vg. + * + * Values: + * - 0 - do not assert open_vg reset + * - 1 - assert open_vg reset + */ +//@{ +#define BP_SRC_SCR_SW_OPEN_VG_RST (4) //!< Bit position for SRC_SCR_SW_OPEN_VG_RST. +#define BM_SRC_SCR_SW_OPEN_VG_RST (0x00000010) //!< Bit mask for SRC_SCR_SW_OPEN_VG_RST. + +//! @brief Get value of SRC_SCR_SW_OPEN_VG_RST from a register value. +#define BG_SRC_SCR_SW_OPEN_VG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_SW_OPEN_VG_RST) >> BP_SRC_SCR_SW_OPEN_VG_RST) + +//! @brief Format value for bitfield SRC_SCR_SW_OPEN_VG_RST. +#define BF_SRC_SCR_SW_OPEN_VG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_SW_OPEN_VG_RST) & BM_SRC_SCR_SW_OPEN_VG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the SW_OPEN_VG_RST field to a new value. +#define BW_SRC_SCR_SW_OPEN_VG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_SW_OPEN_VG_RST) | BF_SRC_SCR_SW_OPEN_VG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field WARM_RST_BYPASS_COUNT[6:5] (RW) + * + * Defines the ckil cycles to count before bypassing the MMDC acknowledge for WARM reset. If the + * MMDC acknowledge will not be asserted before this counter has elapsed, then a COLD reset will be + * initiated. + * + * Values: + * - 00 - Counter not to be used - system will wait until MMDC acknowledge until it is asserted. + * - 01 - Wait 16 ckil cycles before changing WARM reset to a COLD reset. + * - 10 - Wait 32 ckil cycles before changing WARM reset to a COLD reset. + * - 11 - Wait 64 ckil cycles before changing WARM reset to a COLD reset + */ +//@{ +#define BP_SRC_SCR_WARM_RST_BYPASS_COUNT (5) //!< Bit position for SRC_SCR_WARM_RST_BYPASS_COUNT. +#define BM_SRC_SCR_WARM_RST_BYPASS_COUNT (0x00000060) //!< Bit mask for SRC_SCR_WARM_RST_BYPASS_COUNT. + +//! @brief Get value of SRC_SCR_WARM_RST_BYPASS_COUNT from a register value. +#define BG_SRC_SCR_WARM_RST_BYPASS_COUNT(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_WARM_RST_BYPASS_COUNT) >> BP_SRC_SCR_WARM_RST_BYPASS_COUNT) + +//! @brief Format value for bitfield SRC_SCR_WARM_RST_BYPASS_COUNT. +#define BF_SRC_SCR_WARM_RST_BYPASS_COUNT(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_WARM_RST_BYPASS_COUNT) & BM_SRC_SCR_WARM_RST_BYPASS_COUNT) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the WARM_RST_BYPASS_COUNT field to a new value. +#define BW_SRC_SCR_WARM_RST_BYPASS_COUNT(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_WARM_RST_BYPASS_COUNT) | BF_SRC_SCR_WARM_RST_BYPASS_COUNT(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field MASK_WDOG_RST[10:7] (RW) + * + * Mask wdog_rst_b source. If these 4 bits are coded from A to 5 then, the wdog_rst_b input to SRC + * will be masked and the wdog_rst_b will not create a reset to the IC. During the time the WDOG + * event is masked using SRC logic, it is likely that the WDOG Reset Status Register (WRSR) bit 1 + * (which indicates a WDOG timeout event) will get asserted. SW / OS developer must prepare for this + * case. Re-enabling the WDOG is possible, by un-masking it in SRC, though it must be preceded by + * servicing the WDOG. However, for the case that the event has been asserted, the status bit (WRSR + * bit-1) will remain asserted, regardless of servicing the WDOG module. (HW reset is the only way + * to cause the de-assertion of that bit). any other code will be coded to 1010 i.e. wdog_rst_b is + * not masked + * + * Values: + * - 0101 - wdog_rst_b is masked + * - 1010 - wdog_rst_b is not masked (default) + */ +//@{ +#define BP_SRC_SCR_MASK_WDOG_RST (7) //!< Bit position for SRC_SCR_MASK_WDOG_RST. +#define BM_SRC_SCR_MASK_WDOG_RST (0x00000780) //!< Bit mask for SRC_SCR_MASK_WDOG_RST. + +//! @brief Get value of SRC_SCR_MASK_WDOG_RST from a register value. +#define BG_SRC_SCR_MASK_WDOG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_MASK_WDOG_RST) >> BP_SRC_SCR_MASK_WDOG_RST) + +//! @brief Format value for bitfield SRC_SCR_MASK_WDOG_RST. +#define BF_SRC_SCR_MASK_WDOG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_MASK_WDOG_RST) & BM_SRC_SCR_MASK_WDOG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the MASK_WDOG_RST field to a new value. +#define BW_SRC_SCR_MASK_WDOG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_MASK_WDOG_RST) | BF_SRC_SCR_MASK_WDOG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field EIM_RST[11] (RW) + * + * EIM reset is needed in order to reconfigure the eim chip select. The software reset bit must de- + * asserted. The eim chip select configuration should be updated. The software bit must be re- + * asserted since this is not self-refresh. + */ +//@{ +#define BP_SRC_SCR_EIM_RST (11) //!< Bit position for SRC_SCR_EIM_RST. +#define BM_SRC_SCR_EIM_RST (0x00000800) //!< Bit mask for SRC_SCR_EIM_RST. + +//! @brief Get value of SRC_SCR_EIM_RST from a register value. +#define BG_SRC_SCR_EIM_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_EIM_RST) >> BP_SRC_SCR_EIM_RST) + +//! @brief Format value for bitfield SRC_SCR_EIM_RST. +#define BF_SRC_SCR_EIM_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_EIM_RST) & BM_SRC_SCR_EIM_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the EIM_RST field to a new value. +#define BW_SRC_SCR_EIM_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_EIM_RST) | BF_SRC_SCR_EIM_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field SW_IPU2_RST[12] (RW) + * + * Software reset for ipu2 this is a self clearing bit. Once it is set to 1, the reset process will + * begin, and once it finishes, this bit will be self cleared. Software can determine that the reset + * has finished once this bit is cleared. Software can also configure SRC to generate interrupt once + * the software has finished. Please refer to SISR register for details. + * + * Values: + * - 0 - do not assert ipu2 reset + * - 1 - assert ipu2 reset + */ +//@{ +#define BP_SRC_SCR_SW_IPU2_RST (12) //!< Bit position for SRC_SCR_SW_IPU2_RST. +#define BM_SRC_SCR_SW_IPU2_RST (0x00001000) //!< Bit mask for SRC_SCR_SW_IPU2_RST. + +//! @brief Get value of SRC_SCR_SW_IPU2_RST from a register value. +#define BG_SRC_SCR_SW_IPU2_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_SW_IPU2_RST) >> BP_SRC_SCR_SW_IPU2_RST) + +//! @brief Format value for bitfield SRC_SCR_SW_IPU2_RST. +#define BF_SRC_SCR_SW_IPU2_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_SW_IPU2_RST) & BM_SRC_SCR_SW_IPU2_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the SW_IPU2_RST field to a new value. +#define BW_SRC_SCR_SW_IPU2_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_SW_IPU2_RST) | BF_SRC_SCR_SW_IPU2_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE0_RST[13] (RW) + * + * Software reset for core0 only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core0 reset + * - 1 - assert core0 reset + */ +//@{ +#define BP_SRC_SCR_CORE0_RST (13) //!< Bit position for SRC_SCR_CORE0_RST. +#define BM_SRC_SCR_CORE0_RST (0x00002000) //!< Bit mask for SRC_SCR_CORE0_RST. + +//! @brief Get value of SRC_SCR_CORE0_RST from a register value. +#define BG_SRC_SCR_CORE0_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE0_RST) >> BP_SRC_SCR_CORE0_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE0_RST. +#define BF_SRC_SCR_CORE0_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE0_RST) & BM_SRC_SCR_CORE0_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE0_RST field to a new value. +#define BW_SRC_SCR_CORE0_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE0_RST) | BF_SRC_SCR_CORE0_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE1_RST[14] (RW) + * + * Software reset for core1 only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core1 reset + * - 1 - assert core1 reset + */ +//@{ +#define BP_SRC_SCR_CORE1_RST (14) //!< Bit position for SRC_SCR_CORE1_RST. +#define BM_SRC_SCR_CORE1_RST (0x00004000) //!< Bit mask for SRC_SCR_CORE1_RST. + +//! @brief Get value of SRC_SCR_CORE1_RST from a register value. +#define BG_SRC_SCR_CORE1_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE1_RST) >> BP_SRC_SCR_CORE1_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE1_RST. +#define BF_SRC_SCR_CORE1_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE1_RST) & BM_SRC_SCR_CORE1_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE1_RST field to a new value. +#define BW_SRC_SCR_CORE1_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE1_RST) | BF_SRC_SCR_CORE1_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE2_RST[15] (RW) + * + * Software reset for core2 only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core2 reset + * - 1 - assert core2 reset + */ +//@{ +#define BP_SRC_SCR_CORE2_RST (15) //!< Bit position for SRC_SCR_CORE2_RST. +#define BM_SRC_SCR_CORE2_RST (0x00008000) //!< Bit mask for SRC_SCR_CORE2_RST. + +//! @brief Get value of SRC_SCR_CORE2_RST from a register value. +#define BG_SRC_SCR_CORE2_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE2_RST) >> BP_SRC_SCR_CORE2_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE2_RST. +#define BF_SRC_SCR_CORE2_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE2_RST) & BM_SRC_SCR_CORE2_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE2_RST field to a new value. +#define BW_SRC_SCR_CORE2_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE2_RST) | BF_SRC_SCR_CORE2_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE3_RST[16] (RW) + * + * Software reset for core3 only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core3 reset + * - 1 - assert core3 reset + */ +//@{ +#define BP_SRC_SCR_CORE3_RST (16) //!< Bit position for SRC_SCR_CORE3_RST. +#define BM_SRC_SCR_CORE3_RST (0x00010000) //!< Bit mask for SRC_SCR_CORE3_RST. + +//! @brief Get value of SRC_SCR_CORE3_RST from a register value. +#define BG_SRC_SCR_CORE3_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE3_RST) >> BP_SRC_SCR_CORE3_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE3_RST. +#define BF_SRC_SCR_CORE3_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE3_RST) & BM_SRC_SCR_CORE3_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE3_RST field to a new value. +#define BW_SRC_SCR_CORE3_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE3_RST) | BF_SRC_SCR_CORE3_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE0_DBG_RST[17] (RW) + * + * Software reset for core0 debug only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core0 debug reset + * - 1 - assert core0 debug reset + */ +//@{ +#define BP_SRC_SCR_CORE0_DBG_RST (17) //!< Bit position for SRC_SCR_CORE0_DBG_RST. +#define BM_SRC_SCR_CORE0_DBG_RST (0x00020000) //!< Bit mask for SRC_SCR_CORE0_DBG_RST. + +//! @brief Get value of SRC_SCR_CORE0_DBG_RST from a register value. +#define BG_SRC_SCR_CORE0_DBG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE0_DBG_RST) >> BP_SRC_SCR_CORE0_DBG_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE0_DBG_RST. +#define BF_SRC_SCR_CORE0_DBG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE0_DBG_RST) & BM_SRC_SCR_CORE0_DBG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE0_DBG_RST field to a new value. +#define BW_SRC_SCR_CORE0_DBG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE0_DBG_RST) | BF_SRC_SCR_CORE0_DBG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE1_DBG_RST[18] (RW) + * + * Software reset for core1 debug only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core1 debug reset + * - 1 - assert core1 debug reset + */ +//@{ +#define BP_SRC_SCR_CORE1_DBG_RST (18) //!< Bit position for SRC_SCR_CORE1_DBG_RST. +#define BM_SRC_SCR_CORE1_DBG_RST (0x00040000) //!< Bit mask for SRC_SCR_CORE1_DBG_RST. + +//! @brief Get value of SRC_SCR_CORE1_DBG_RST from a register value. +#define BG_SRC_SCR_CORE1_DBG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE1_DBG_RST) >> BP_SRC_SCR_CORE1_DBG_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE1_DBG_RST. +#define BF_SRC_SCR_CORE1_DBG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE1_DBG_RST) & BM_SRC_SCR_CORE1_DBG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE1_DBG_RST field to a new value. +#define BW_SRC_SCR_CORE1_DBG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE1_DBG_RST) | BF_SRC_SCR_CORE1_DBG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE2_DBG_RST[19] (RW) + * + * Software reset for core2 debug only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core2 debug reset + * - 1 - assert core2 debug reset + */ +//@{ +#define BP_SRC_SCR_CORE2_DBG_RST (19) //!< Bit position for SRC_SCR_CORE2_DBG_RST. +#define BM_SRC_SCR_CORE2_DBG_RST (0x00080000) //!< Bit mask for SRC_SCR_CORE2_DBG_RST. + +//! @brief Get value of SRC_SCR_CORE2_DBG_RST from a register value. +#define BG_SRC_SCR_CORE2_DBG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE2_DBG_RST) >> BP_SRC_SCR_CORE2_DBG_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE2_DBG_RST. +#define BF_SRC_SCR_CORE2_DBG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE2_DBG_RST) & BM_SRC_SCR_CORE2_DBG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE2_DBG_RST field to a new value. +#define BW_SRC_SCR_CORE2_DBG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE2_DBG_RST) | BF_SRC_SCR_CORE2_DBG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE3_DBG_RST[20] (RW) + * + * Software reset for core3 debug only. this is a self clearing bit. Once it is set to 1, the reset + * process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert core3 debug reset + * - 1 - assert core3 debug reset + */ +//@{ +#define BP_SRC_SCR_CORE3_DBG_RST (20) //!< Bit position for SRC_SCR_CORE3_DBG_RST. +#define BM_SRC_SCR_CORE3_DBG_RST (0x00100000) //!< Bit mask for SRC_SCR_CORE3_DBG_RST. + +//! @brief Get value of SRC_SCR_CORE3_DBG_RST from a register value. +#define BG_SRC_SCR_CORE3_DBG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE3_DBG_RST) >> BP_SRC_SCR_CORE3_DBG_RST) + +//! @brief Format value for bitfield SRC_SCR_CORE3_DBG_RST. +#define BF_SRC_SCR_CORE3_DBG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE3_DBG_RST) & BM_SRC_SCR_CORE3_DBG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE3_DBG_RST field to a new value. +#define BW_SRC_SCR_CORE3_DBG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE3_DBG_RST) | BF_SRC_SCR_CORE3_DBG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORES_DBG_RST[21] (RW) + * + * Software reset for debug of arm platform only. this is a self clearing bit. Once it is set to 1, + * the reset process will begin, and once it finishes, this bit will be self cleared. + * + * Values: + * - 0 - do not assert arm platform debug reset + * - 1 - assert arm platform debug reset + */ +//@{ +#define BP_SRC_SCR_CORES_DBG_RST (21) //!< Bit position for SRC_SCR_CORES_DBG_RST. +#define BM_SRC_SCR_CORES_DBG_RST (0x00200000) //!< Bit mask for SRC_SCR_CORES_DBG_RST. + +//! @brief Get value of SRC_SCR_CORES_DBG_RST from a register value. +#define BG_SRC_SCR_CORES_DBG_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORES_DBG_RST) >> BP_SRC_SCR_CORES_DBG_RST) + +//! @brief Format value for bitfield SRC_SCR_CORES_DBG_RST. +#define BF_SRC_SCR_CORES_DBG_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORES_DBG_RST) & BM_SRC_SCR_CORES_DBG_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORES_DBG_RST field to a new value. +#define BW_SRC_SCR_CORES_DBG_RST(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORES_DBG_RST) | BF_SRC_SCR_CORES_DBG_RST(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE1_ENABLE[22] (RW) + * + * CPU core1 enable. core0 cannot be disabled + * + * Values: + * - 0 - core1 is disabled + * - 1 - core1 is enabled + */ +//@{ +#define BP_SRC_SCR_CORE1_ENABLE (22) //!< Bit position for SRC_SCR_CORE1_ENABLE. +#define BM_SRC_SCR_CORE1_ENABLE (0x00400000) //!< Bit mask for SRC_SCR_CORE1_ENABLE. + +//! @brief Get value of SRC_SCR_CORE1_ENABLE from a register value. +#define BG_SRC_SCR_CORE1_ENABLE(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE1_ENABLE) >> BP_SRC_SCR_CORE1_ENABLE) + +//! @brief Format value for bitfield SRC_SCR_CORE1_ENABLE. +#define BF_SRC_SCR_CORE1_ENABLE(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE1_ENABLE) & BM_SRC_SCR_CORE1_ENABLE) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE1_ENABLE field to a new value. +#define BW_SRC_SCR_CORE1_ENABLE(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE1_ENABLE) | BF_SRC_SCR_CORE1_ENABLE(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE2_ENABLE[23] (RW) + * + * CPU core2 enable. core0 cannot be disabled + * + * Values: + * - 0 - core2 is disabled + * - 1 - core2 is enabled + */ +//@{ +#define BP_SRC_SCR_CORE2_ENABLE (23) //!< Bit position for SRC_SCR_CORE2_ENABLE. +#define BM_SRC_SCR_CORE2_ENABLE (0x00800000) //!< Bit mask for SRC_SCR_CORE2_ENABLE. + +//! @brief Get value of SRC_SCR_CORE2_ENABLE from a register value. +#define BG_SRC_SCR_CORE2_ENABLE(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE2_ENABLE) >> BP_SRC_SCR_CORE2_ENABLE) + +//! @brief Format value for bitfield SRC_SCR_CORE2_ENABLE. +#define BF_SRC_SCR_CORE2_ENABLE(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE2_ENABLE) & BM_SRC_SCR_CORE2_ENABLE) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE2_ENABLE field to a new value. +#define BW_SRC_SCR_CORE2_ENABLE(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE2_ENABLE) | BF_SRC_SCR_CORE2_ENABLE(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field CORE3_ENABLE[24] (RW) + * + * CPU core3 enable. core0 cannot be disabled + * + * Values: + * - 0 - core3 is disabled + * - 1 - core3 is enabled + */ +//@{ +#define BP_SRC_SCR_CORE3_ENABLE (24) //!< Bit position for SRC_SCR_CORE3_ENABLE. +#define BM_SRC_SCR_CORE3_ENABLE (0x01000000) //!< Bit mask for SRC_SCR_CORE3_ENABLE. + +//! @brief Get value of SRC_SCR_CORE3_ENABLE from a register value. +#define BG_SRC_SCR_CORE3_ENABLE(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_CORE3_ENABLE) >> BP_SRC_SCR_CORE3_ENABLE) + +//! @brief Format value for bitfield SRC_SCR_CORE3_ENABLE. +#define BF_SRC_SCR_CORE3_ENABLE(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_CORE3_ENABLE) & BM_SRC_SCR_CORE3_ENABLE) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CORE3_ENABLE field to a new value. +#define BW_SRC_SCR_CORE3_ENABLE(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_CORE3_ENABLE) | BF_SRC_SCR_CORE3_ENABLE(v))) +#endif +//@} + +/*! @name Register SRC_SCR, field DBG_RST_MSK_PG[25] (RW) + * + * Do not assert debug resets after power gating event of cpu + * + * Values: + * - 0 - don't mask cpu debug resets (debug resets will be asserted after power gating event) + * - 1 - makes cpu debug resets (debug resets won't be asserted after power gating event) + */ +//@{ +#define BP_SRC_SCR_DBG_RST_MSK_PG (25) //!< Bit position for SRC_SCR_DBG_RST_MSK_PG. +#define BM_SRC_SCR_DBG_RST_MSK_PG (0x02000000) //!< Bit mask for SRC_SCR_DBG_RST_MSK_PG. + +//! @brief Get value of SRC_SCR_DBG_RST_MSK_PG from a register value. +#define BG_SRC_SCR_DBG_RST_MSK_PG(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SCR_DBG_RST_MSK_PG) >> BP_SRC_SCR_DBG_RST_MSK_PG) + +//! @brief Format value for bitfield SRC_SCR_DBG_RST_MSK_PG. +#define BF_SRC_SCR_DBG_RST_MSK_PG(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SCR_DBG_RST_MSK_PG) & BM_SRC_SCR_DBG_RST_MSK_PG) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the DBG_RST_MSK_PG field to a new value. +#define BW_SRC_SCR_DBG_RST_MSK_PG(v) (HW_SRC_SCR_WR((HW_SRC_SCR_RD() & ~BM_SRC_SCR_DBG_RST_MSK_PG) | BF_SRC_SCR_DBG_RST_MSK_PG(v))) +#endif +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_SBMR1 - SRC Boot Mode Register 1 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_SBMR1 - SRC Boot Mode Register 1 (RO) + * + * Reset value: 0x00000000 + * + * The Boot Mode register (SBMR) contains bits that reflect the status of Boot Mode Pins of the + * chip. The reset value is configuration dependent (depending on boot/fuses/IO pads). + */ +typedef union _hw_src_sbmr1 { + reg32_t U; + struct _hw_src_sbmr1_bitfields { + unsigned BOOT_CFG1 : 8; //!< [7:0] Please refer to fuse map. + unsigned BOOT_CFG2 : 8; //!< [15:8] Please refer to fuse map. + unsigned BOOT_CFG3 : 8; //!< [23:16] Please refer to fuse map. + unsigned BOOT_CFG4 : 8; //!< [31:24] Please refer to fuse map. + } B; +} hw_src_sbmr1_t; +#endif + +/*! + * @name Constants and macros for entire SRC_SBMR1 register + */ +//@{ +#define HW_SRC_SBMR1_ADDR (REGS_SRC_BASE + 0x4) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_SBMR1 (*(volatile hw_src_sbmr1_t*)HW_SRC_SBMR1_ADDR) +#define HW_SRC_SBMR1_RD() (HW_SRC_SBMR1.U) +#endif +//@} + +/* + * constants & macros for individual SRC_SBMR1 bitfields + */ + +/*! @name Register SRC_SBMR1, field BOOT_CFG1[7:0] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR1_BOOT_CFG1 (0) //!< Bit position for SRC_SBMR1_BOOT_CFG1. +#define BM_SRC_SBMR1_BOOT_CFG1 (0x000000ff) //!< Bit mask for SRC_SBMR1_BOOT_CFG1. + +//! @brief Get value of SRC_SBMR1_BOOT_CFG1 from a register value. +#define BG_SRC_SBMR1_BOOT_CFG1(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR1_BOOT_CFG1) >> BP_SRC_SBMR1_BOOT_CFG1) +//@} + +/*! @name Register SRC_SBMR1, field BOOT_CFG2[15:8] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR1_BOOT_CFG2 (8) //!< Bit position for SRC_SBMR1_BOOT_CFG2. +#define BM_SRC_SBMR1_BOOT_CFG2 (0x0000ff00) //!< Bit mask for SRC_SBMR1_BOOT_CFG2. + +//! @brief Get value of SRC_SBMR1_BOOT_CFG2 from a register value. +#define BG_SRC_SBMR1_BOOT_CFG2(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR1_BOOT_CFG2) >> BP_SRC_SBMR1_BOOT_CFG2) +//@} + +/*! @name Register SRC_SBMR1, field BOOT_CFG3[23:16] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR1_BOOT_CFG3 (16) //!< Bit position for SRC_SBMR1_BOOT_CFG3. +#define BM_SRC_SBMR1_BOOT_CFG3 (0x00ff0000) //!< Bit mask for SRC_SBMR1_BOOT_CFG3. + +//! @brief Get value of SRC_SBMR1_BOOT_CFG3 from a register value. +#define BG_SRC_SBMR1_BOOT_CFG3(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR1_BOOT_CFG3) >> BP_SRC_SBMR1_BOOT_CFG3) +//@} + +/*! @name Register SRC_SBMR1, field BOOT_CFG4[31:24] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR1_BOOT_CFG4 (24) //!< Bit position for SRC_SBMR1_BOOT_CFG4. +#define BM_SRC_SBMR1_BOOT_CFG4 (0xff000000) //!< Bit mask for SRC_SBMR1_BOOT_CFG4. + +//! @brief Get value of SRC_SBMR1_BOOT_CFG4 from a register value. +#define BG_SRC_SBMR1_BOOT_CFG4(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR1_BOOT_CFG4) >> BP_SRC_SBMR1_BOOT_CFG4) +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_SRSR - SRC Reset Status Register +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_SRSR - SRC Reset Status Register (RW) + * + * Reset value: 0x00000001 + * + * The SRSR is a write to one clear register which records the source of the reset events for the + * chip. The SRC reset status register will capture all the reset sources that have occurred. This + * register is reset on ipp_reset_b. This is a read-write register, For bit[6-0] - writing zero does + * not have any effect. Writing one will clear the corresponding bit. The individual bits can be + * cleared by writing one to that bit. When the system comes out of reset, this register will have + * bits set corresponding to all the reset sources that occurred during system reset. Software has + * to take care to clear this register by writing one after every reset that occurs so that the + * register will contain the information of recently occurred reset. + */ +typedef union _hw_src_srsr { + reg32_t U; + struct _hw_src_srsr_bitfields { + unsigned IPP_RESET_B : 1; //!< [0] Indicates whether reset was the result of ipp_reset_b pin (Power-up sequence) + unsigned RESERVED0 : 1; //!< [1] Reserved. + unsigned CSU_RESET_B : 1; //!< [2] Indicates whether the reset was the result of the csu_reset_b input. + unsigned IPP_USER_RESET_B : 1; //!< [3] Indicates whether the reset was the result of the ipp_user_reset_b qualified reset. + unsigned WDOG_RST_B : 1; //!< [4] IC Watchdog Time-out reset. + unsigned JTAG_RST_B : 1; //!< [5] HIGH - Z JTAG reset. + unsigned JTAG_SW_RST : 1; //!< [6] JTAG SW reset. + unsigned RESERVED1 : 9; //!< [15:7] Reserved + unsigned WARM_BOOT : 1; //!< [16] WARM boot indication shows that WARM boot was initiated by software. + unsigned RESERVED2 : 15; //!< [31:17] Reserved + } B; +} hw_src_srsr_t; +#endif + +/*! + * @name Constants and macros for entire SRC_SRSR register + */ +//@{ +#define HW_SRC_SRSR_ADDR (REGS_SRC_BASE + 0x8) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_SRSR (*(volatile hw_src_srsr_t*)HW_SRC_SRSR_ADDR) +#define HW_SRC_SRSR_RD() (HW_SRC_SRSR.U) +#define HW_SRC_SRSR_WR(v) (HW_SRC_SRSR.U = (v)) +#define HW_SRC_SRSR_SET(v) (HW_SRC_SRSR_WR(HW_SRC_SRSR_RD() | (v))) +#define HW_SRC_SRSR_CLR(v) (HW_SRC_SRSR_WR(HW_SRC_SRSR_RD() & ~(v))) +#define HW_SRC_SRSR_TOG(v) (HW_SRC_SRSR_WR(HW_SRC_SRSR_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_SRSR bitfields + */ + +/*! @name Register SRC_SRSR, field IPP_RESET_B[0] (W1C) + * + * Indicates whether reset was the result of ipp_reset_b pin (Power-up sequence) + * + * Values: + * - 0 - Reset is not a result of ipp_reset_b pin. + * - 1 - Reset is a result of ipp_reset_b pin. + */ +//@{ +#define BP_SRC_SRSR_IPP_RESET_B (0) //!< Bit position for SRC_SRSR_IPP_RESET_B. +#define BM_SRC_SRSR_IPP_RESET_B (0x00000001) //!< Bit mask for SRC_SRSR_IPP_RESET_B. + +//! @brief Get value of SRC_SRSR_IPP_RESET_B from a register value. +#define BG_SRC_SRSR_IPP_RESET_B(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_IPP_RESET_B) >> BP_SRC_SRSR_IPP_RESET_B) + +//! @brief Format value for bitfield SRC_SRSR_IPP_RESET_B. +#define BF_SRC_SRSR_IPP_RESET_B(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_IPP_RESET_B) & BM_SRC_SRSR_IPP_RESET_B) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the IPP_RESET_B field to a new value. +#define BW_SRC_SRSR_IPP_RESET_B(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_IPP_RESET_B) | BF_SRC_SRSR_IPP_RESET_B(v))) +#endif +//@} + +/*! @name Register SRC_SRSR, field CSU_RESET_B[2] (W1C) + * + * Indicates whether the reset was the result of the csu_reset_b input. If case the csu_reset_b + * occurred during a WARM reset process, during the phase that ipg_clk is not available yet, then + * the occurrence of CSU reset will not be reflected in this bit. + * + * Values: + * - 0 - Reset is not a result of the csu_reset_b event. + * - 1 - Reset is a result of the csu_reset_b event. + */ +//@{ +#define BP_SRC_SRSR_CSU_RESET_B (2) //!< Bit position for SRC_SRSR_CSU_RESET_B. +#define BM_SRC_SRSR_CSU_RESET_B (0x00000004) //!< Bit mask for SRC_SRSR_CSU_RESET_B. + +//! @brief Get value of SRC_SRSR_CSU_RESET_B from a register value. +#define BG_SRC_SRSR_CSU_RESET_B(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_CSU_RESET_B) >> BP_SRC_SRSR_CSU_RESET_B) + +//! @brief Format value for bitfield SRC_SRSR_CSU_RESET_B. +#define BF_SRC_SRSR_CSU_RESET_B(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_CSU_RESET_B) & BM_SRC_SRSR_CSU_RESET_B) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the CSU_RESET_B field to a new value. +#define BW_SRC_SRSR_CSU_RESET_B(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_CSU_RESET_B) | BF_SRC_SRSR_CSU_RESET_B(v))) +#endif +//@} + +/*! @name Register SRC_SRSR, field IPP_USER_RESET_B[3] (W1C) + * + * Indicates whether the reset was the result of the ipp_user_reset_b qualified reset. + * + * Values: + * - 0 - Reset is not a result of the ipp_user_reset_b qualified as COLD reset event. + * - 1 - Reset is a result of the ipp_user_reset_b qualified as COLD reset event. + */ +//@{ +#define BP_SRC_SRSR_IPP_USER_RESET_B (3) //!< Bit position for SRC_SRSR_IPP_USER_RESET_B. +#define BM_SRC_SRSR_IPP_USER_RESET_B (0x00000008) //!< Bit mask for SRC_SRSR_IPP_USER_RESET_B. + +//! @brief Get value of SRC_SRSR_IPP_USER_RESET_B from a register value. +#define BG_SRC_SRSR_IPP_USER_RESET_B(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_IPP_USER_RESET_B) >> BP_SRC_SRSR_IPP_USER_RESET_B) + +//! @brief Format value for bitfield SRC_SRSR_IPP_USER_RESET_B. +#define BF_SRC_SRSR_IPP_USER_RESET_B(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_IPP_USER_RESET_B) & BM_SRC_SRSR_IPP_USER_RESET_B) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the IPP_USER_RESET_B field to a new value. +#define BW_SRC_SRSR_IPP_USER_RESET_B(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_IPP_USER_RESET_B) | BF_SRC_SRSR_IPP_USER_RESET_B(v))) +#endif +//@} + +/*! @name Register SRC_SRSR, field WDOG_RST_B[4] (W1C) + * + * IC Watchdog Time-out reset. Indicates whether the reset was the result of the watchdog time-out + * event. + * + * Values: + * - 0 - Reset is not a result of the watchdog time-out event. + * - 1 - Reset is a result of the watchdog time-out event. + */ +//@{ +#define BP_SRC_SRSR_WDOG_RST_B (4) //!< Bit position for SRC_SRSR_WDOG_RST_B. +#define BM_SRC_SRSR_WDOG_RST_B (0x00000010) //!< Bit mask for SRC_SRSR_WDOG_RST_B. + +//! @brief Get value of SRC_SRSR_WDOG_RST_B from a register value. +#define BG_SRC_SRSR_WDOG_RST_B(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_WDOG_RST_B) >> BP_SRC_SRSR_WDOG_RST_B) + +//! @brief Format value for bitfield SRC_SRSR_WDOG_RST_B. +#define BF_SRC_SRSR_WDOG_RST_B(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_WDOG_RST_B) & BM_SRC_SRSR_WDOG_RST_B) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the WDOG_RST_B field to a new value. +#define BW_SRC_SRSR_WDOG_RST_B(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_WDOG_RST_B) | BF_SRC_SRSR_WDOG_RST_B(v))) +#endif +//@} + +/*! @name Register SRC_SRSR, field JTAG_RST_B[5] (W1C) + * + * HIGH - Z JTAG reset. Indicates whether the reset was the result of HIGH-Z reset from JTAG. + * Connections at chip-level: jtag_rst_b -> sjc_ieee_reset_b + * + * Values: + * - 0 - Reset is not a result of HIGH-Z reset from JTAG. + * - 1 - Reset is a result of HIGH-Z reset from JTAG. + */ +//@{ +#define BP_SRC_SRSR_JTAG_RST_B (5) //!< Bit position for SRC_SRSR_JTAG_RST_B. +#define BM_SRC_SRSR_JTAG_RST_B (0x00000020) //!< Bit mask for SRC_SRSR_JTAG_RST_B. + +//! @brief Get value of SRC_SRSR_JTAG_RST_B from a register value. +#define BG_SRC_SRSR_JTAG_RST_B(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_JTAG_RST_B) >> BP_SRC_SRSR_JTAG_RST_B) + +//! @brief Format value for bitfield SRC_SRSR_JTAG_RST_B. +#define BF_SRC_SRSR_JTAG_RST_B(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_JTAG_RST_B) & BM_SRC_SRSR_JTAG_RST_B) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the JTAG_RST_B field to a new value. +#define BW_SRC_SRSR_JTAG_RST_B(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_JTAG_RST_B) | BF_SRC_SRSR_JTAG_RST_B(v))) +#endif +//@} + +/*! @name Register SRC_SRSR, field JTAG_SW_RST[6] (W1C) + * + * JTAG SW reset. Indicates whether the reset was the result of software reset from JTAG. + * Connections at chip-level: jtag_sw_rst -> sjc_gpccr_reg_2_b + * + * Values: + * - 0 - Reset is not a result of software reset from JTAG. + * - 1 - Reset is a result of software reset from JTAG. + */ +//@{ +#define BP_SRC_SRSR_JTAG_SW_RST (6) //!< Bit position for SRC_SRSR_JTAG_SW_RST. +#define BM_SRC_SRSR_JTAG_SW_RST (0x00000040) //!< Bit mask for SRC_SRSR_JTAG_SW_RST. + +//! @brief Get value of SRC_SRSR_JTAG_SW_RST from a register value. +#define BG_SRC_SRSR_JTAG_SW_RST(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_JTAG_SW_RST) >> BP_SRC_SRSR_JTAG_SW_RST) + +//! @brief Format value for bitfield SRC_SRSR_JTAG_SW_RST. +#define BF_SRC_SRSR_JTAG_SW_RST(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_JTAG_SW_RST) & BM_SRC_SRSR_JTAG_SW_RST) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the JTAG_SW_RST field to a new value. +#define BW_SRC_SRSR_JTAG_SW_RST(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_JTAG_SW_RST) | BF_SRC_SRSR_JTAG_SW_RST(v))) +#endif +//@} + +/*! @name Register SRC_SRSR, field WARM_BOOT[16] (RW) + * + * WARM boot indication shows that WARM boot was initiated by software. This indicates to the + * software that it saved the needed information in the memory before initiating the WARM reset. In + * this case, software will set this bit to '1', before initiating the WARM reset. The warm_boot bit + * should be used as indication only after a warm_reset sequence. Software should clear this bit + * after warm_reset to indicate that the next warm_reset is not performed with warm_boot. Please + * refer to for details on warm_reset. + * + * Values: + * - 0 - WARM boot process not initiated by software. + * - 1 - WARM boot initiated by software. + */ +//@{ +#define BP_SRC_SRSR_WARM_BOOT (16) //!< Bit position for SRC_SRSR_WARM_BOOT. +#define BM_SRC_SRSR_WARM_BOOT (0x00010000) //!< Bit mask for SRC_SRSR_WARM_BOOT. + +//! @brief Get value of SRC_SRSR_WARM_BOOT from a register value. +#define BG_SRC_SRSR_WARM_BOOT(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SRSR_WARM_BOOT) >> BP_SRC_SRSR_WARM_BOOT) + +//! @brief Format value for bitfield SRC_SRSR_WARM_BOOT. +#define BF_SRC_SRSR_WARM_BOOT(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SRSR_WARM_BOOT) & BM_SRC_SRSR_WARM_BOOT) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the WARM_BOOT field to a new value. +#define BW_SRC_SRSR_WARM_BOOT(v) (HW_SRC_SRSR_WR((HW_SRC_SRSR_RD() & ~BM_SRC_SRSR_WARM_BOOT) | BF_SRC_SRSR_WARM_BOOT(v))) +#endif +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_SISR - SRC Interrupt Status Register +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_SISR - SRC Interrupt Status Register (RO) + * + * Reset value: 0x00000000 + */ +typedef union _hw_src_sisr { + reg32_t U; + struct _hw_src_sisr_bitfields { + unsigned GPU_PASSED_RESET : 1; //!< [0] Interrupt generated to indicate that gpu passed software reset and is ready to be used + unsigned VPU_PASSED_RESET : 1; //!< [1] Interrupt generated to indicate that vpu passed software reset and is ready to be used + unsigned IPU1_PASSED_RESET : 1; //!< [2] Interrupt generated to indicate that ipu passed software reset and is ready to be used + unsigned OPEN_VG_PASSED_RESET : 1; //!< [3] Interrupt generated to indicate that open_vg passed software reset and is ready to be used + unsigned IPU2_PASSED_RESET : 1; //!< [4] Interrupt generated to indicate that ipu2 passed software reset and is ready to be used + unsigned CORE0_WDOG_RST_REQ : 1; //!< [5] WDOG reset request from CPU core0. + unsigned CORE1_WDOG_RST_REQ : 1; //!< [6] WDOG reset request from CPU core1. + unsigned CORE2_WDOG_RST_REQ : 1; //!< [7] WDOG reset request from CPU core2. + unsigned CORE3_WDOG_RST_REQ : 1; //!< [8] WDOG reset request from CPU core3. + unsigned RESERVED0 : 23; //!< [31:9] Reserved + } B; +} hw_src_sisr_t; +#endif + +/*! + * @name Constants and macros for entire SRC_SISR register + */ +//@{ +#define HW_SRC_SISR_ADDR (REGS_SRC_BASE + 0x14) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_SISR (*(volatile hw_src_sisr_t*)HW_SRC_SISR_ADDR) +#define HW_SRC_SISR_RD() (HW_SRC_SISR.U) +#endif +//@} + +/* + * constants & macros for individual SRC_SISR bitfields + */ + +/*! @name Register SRC_SISR, field GPU_PASSED_RESET[0] (RO) + * + * Interrupt generated to indicate that gpu passed software reset and is ready to be used + * + * Values: + * - 0 - interrupt generated not due to gpu passed reset + * - 1 - interrupt generated due to gpu passed reset + */ +//@{ +#define BP_SRC_SISR_GPU_PASSED_RESET (0) //!< Bit position for SRC_SISR_GPU_PASSED_RESET. +#define BM_SRC_SISR_GPU_PASSED_RESET (0x00000001) //!< Bit mask for SRC_SISR_GPU_PASSED_RESET. + +//! @brief Get value of SRC_SISR_GPU_PASSED_RESET from a register value. +#define BG_SRC_SISR_GPU_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_GPU_PASSED_RESET) >> BP_SRC_SISR_GPU_PASSED_RESET) +//@} + +/*! @name Register SRC_SISR, field VPU_PASSED_RESET[1] (RO) + * + * Interrupt generated to indicate that vpu passed software reset and is ready to be used + * + * Values: + * - 0 - interrupt generated not due to vpu passed reset + * - 1 - interrupt generated due to vpu passed reset + */ +//@{ +#define BP_SRC_SISR_VPU_PASSED_RESET (1) //!< Bit position for SRC_SISR_VPU_PASSED_RESET. +#define BM_SRC_SISR_VPU_PASSED_RESET (0x00000002) //!< Bit mask for SRC_SISR_VPU_PASSED_RESET. + +//! @brief Get value of SRC_SISR_VPU_PASSED_RESET from a register value. +#define BG_SRC_SISR_VPU_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_VPU_PASSED_RESET) >> BP_SRC_SISR_VPU_PASSED_RESET) +//@} + +/*! @name Register SRC_SISR, field IPU1_PASSED_RESET[2] (RO) + * + * Interrupt generated to indicate that ipu passed software reset and is ready to be used + * + * Values: + * - 0 - interrupt generated not due to ipu passed reset + * - 1 - interrupt generated due to ipu passed reset + */ +//@{ +#define BP_SRC_SISR_IPU1_PASSED_RESET (2) //!< Bit position for SRC_SISR_IPU1_PASSED_RESET. +#define BM_SRC_SISR_IPU1_PASSED_RESET (0x00000004) //!< Bit mask for SRC_SISR_IPU1_PASSED_RESET. + +//! @brief Get value of SRC_SISR_IPU1_PASSED_RESET from a register value. +#define BG_SRC_SISR_IPU1_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_IPU1_PASSED_RESET) >> BP_SRC_SISR_IPU1_PASSED_RESET) +//@} + +/*! @name Register SRC_SISR, field OPEN_VG_PASSED_RESET[3] (RO) + * + * Interrupt generated to indicate that open_vg passed software reset and is ready to be used + * + * Values: + * - 0 - interrupt generated not due to open_vg passed reset + * - 1 - interrupt generated due to open_vg passed reset + */ +//@{ +#define BP_SRC_SISR_OPEN_VG_PASSED_RESET (3) //!< Bit position for SRC_SISR_OPEN_VG_PASSED_RESET. +#define BM_SRC_SISR_OPEN_VG_PASSED_RESET (0x00000008) //!< Bit mask for SRC_SISR_OPEN_VG_PASSED_RESET. + +//! @brief Get value of SRC_SISR_OPEN_VG_PASSED_RESET from a register value. +#define BG_SRC_SISR_OPEN_VG_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_OPEN_VG_PASSED_RESET) >> BP_SRC_SISR_OPEN_VG_PASSED_RESET) +//@} + +/*! @name Register SRC_SISR, field IPU2_PASSED_RESET[4] (RO) + * + * Interrupt generated to indicate that ipu2 passed software reset and is ready to be used + * + * Values: + * - 0 - interrupt generated not due to ipu2 passed reset + * - 1 - interrupt generated due to ipu2 passed reset + */ +//@{ +#define BP_SRC_SISR_IPU2_PASSED_RESET (4) //!< Bit position for SRC_SISR_IPU2_PASSED_RESET. +#define BM_SRC_SISR_IPU2_PASSED_RESET (0x00000010) //!< Bit mask for SRC_SISR_IPU2_PASSED_RESET. + +//! @brief Get value of SRC_SISR_IPU2_PASSED_RESET from a register value. +#define BG_SRC_SISR_IPU2_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_IPU2_PASSED_RESET) >> BP_SRC_SISR_IPU2_PASSED_RESET) +//@} + +/*! @name Register SRC_SISR, field CORE0_WDOG_RST_REQ[5] (RO) + * + * WDOG reset request from CPU core0. Read-only status bit. + */ +//@{ +#define BP_SRC_SISR_CORE0_WDOG_RST_REQ (5) //!< Bit position for SRC_SISR_CORE0_WDOG_RST_REQ. +#define BM_SRC_SISR_CORE0_WDOG_RST_REQ (0x00000020) //!< Bit mask for SRC_SISR_CORE0_WDOG_RST_REQ. + +//! @brief Get value of SRC_SISR_CORE0_WDOG_RST_REQ from a register value. +#define BG_SRC_SISR_CORE0_WDOG_RST_REQ(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_CORE0_WDOG_RST_REQ) >> BP_SRC_SISR_CORE0_WDOG_RST_REQ) +//@} + +/*! @name Register SRC_SISR, field CORE1_WDOG_RST_REQ[6] (RO) + * + * WDOG reset request from CPU core1. Read-only status bit. + */ +//@{ +#define BP_SRC_SISR_CORE1_WDOG_RST_REQ (6) //!< Bit position for SRC_SISR_CORE1_WDOG_RST_REQ. +#define BM_SRC_SISR_CORE1_WDOG_RST_REQ (0x00000040) //!< Bit mask for SRC_SISR_CORE1_WDOG_RST_REQ. + +//! @brief Get value of SRC_SISR_CORE1_WDOG_RST_REQ from a register value. +#define BG_SRC_SISR_CORE1_WDOG_RST_REQ(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_CORE1_WDOG_RST_REQ) >> BP_SRC_SISR_CORE1_WDOG_RST_REQ) +//@} + +/*! @name Register SRC_SISR, field CORE2_WDOG_RST_REQ[7] (RO) + * + * WDOG reset request from CPU core2. Read-only status bit. + */ +//@{ +#define BP_SRC_SISR_CORE2_WDOG_RST_REQ (7) //!< Bit position for SRC_SISR_CORE2_WDOG_RST_REQ. +#define BM_SRC_SISR_CORE2_WDOG_RST_REQ (0x00000080) //!< Bit mask for SRC_SISR_CORE2_WDOG_RST_REQ. + +//! @brief Get value of SRC_SISR_CORE2_WDOG_RST_REQ from a register value. +#define BG_SRC_SISR_CORE2_WDOG_RST_REQ(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_CORE2_WDOG_RST_REQ) >> BP_SRC_SISR_CORE2_WDOG_RST_REQ) +//@} + +/*! @name Register SRC_SISR, field CORE3_WDOG_RST_REQ[8] (RO) + * + * WDOG reset request from CPU core3. Read-only status bit. + */ +//@{ +#define BP_SRC_SISR_CORE3_WDOG_RST_REQ (8) //!< Bit position for SRC_SISR_CORE3_WDOG_RST_REQ. +#define BM_SRC_SISR_CORE3_WDOG_RST_REQ (0x00000100) //!< Bit mask for SRC_SISR_CORE3_WDOG_RST_REQ. + +//! @brief Get value of SRC_SISR_CORE3_WDOG_RST_REQ from a register value. +#define BG_SRC_SISR_CORE3_WDOG_RST_REQ(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SISR_CORE3_WDOG_RST_REQ) >> BP_SRC_SISR_CORE3_WDOG_RST_REQ) +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_SIMR - SRC Interrupt Mask Register +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_SIMR - SRC Interrupt Mask Register (RW) + * + * Reset value: 0x0000001f + */ +typedef union _hw_src_simr { + reg32_t U; + struct _hw_src_simr_bitfields { + unsigned MASK_GPU_PASSED_RESET : 1; //!< [0] mask interrupt generation due to gpu passed reset + unsigned MASK_VPU_PASSED_RESET : 1; //!< [1] mask interrupt generation due to vpu passed reset + unsigned MASK_IPU_PASSED_RESET : 1; //!< [2] mask interrupt generation due to ipu passed reset + unsigned MASK_OPEN_VG_PASSED_RESET : 1; //!< [3] mask interrupt generation due to open_vg passed reset + unsigned MASK_IPU2_PASSED_RESET : 1; //!< [4] mask interrupt generation due to ipu2 passing reset + unsigned RESERVED0 : 27; //!< [31:5] Reserved + } B; +} hw_src_simr_t; +#endif + +/*! + * @name Constants and macros for entire SRC_SIMR register + */ +//@{ +#define HW_SRC_SIMR_ADDR (REGS_SRC_BASE + 0x18) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_SIMR (*(volatile hw_src_simr_t*)HW_SRC_SIMR_ADDR) +#define HW_SRC_SIMR_RD() (HW_SRC_SIMR.U) +#define HW_SRC_SIMR_WR(v) (HW_SRC_SIMR.U = (v)) +#define HW_SRC_SIMR_SET(v) (HW_SRC_SIMR_WR(HW_SRC_SIMR_RD() | (v))) +#define HW_SRC_SIMR_CLR(v) (HW_SRC_SIMR_WR(HW_SRC_SIMR_RD() & ~(v))) +#define HW_SRC_SIMR_TOG(v) (HW_SRC_SIMR_WR(HW_SRC_SIMR_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_SIMR bitfields + */ + +/*! @name Register SRC_SIMR, field MASK_GPU_PASSED_RESET[0] (RW) + * + * mask interrupt generation due to gpu passed reset + * + * Values: + * - 0 - don't mask interrupt due to gpu passed reset - interrupt will be created + * - 1 - mask interrupt due to gpu passed reset + */ +//@{ +#define BP_SRC_SIMR_MASK_GPU_PASSED_RESET (0) //!< Bit position for SRC_SIMR_MASK_GPU_PASSED_RESET. +#define BM_SRC_SIMR_MASK_GPU_PASSED_RESET (0x00000001) //!< Bit mask for SRC_SIMR_MASK_GPU_PASSED_RESET. + +//! @brief Get value of SRC_SIMR_MASK_GPU_PASSED_RESET from a register value. +#define BG_SRC_SIMR_MASK_GPU_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SIMR_MASK_GPU_PASSED_RESET) >> BP_SRC_SIMR_MASK_GPU_PASSED_RESET) + +//! @brief Format value for bitfield SRC_SIMR_MASK_GPU_PASSED_RESET. +#define BF_SRC_SIMR_MASK_GPU_PASSED_RESET(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SIMR_MASK_GPU_PASSED_RESET) & BM_SRC_SIMR_MASK_GPU_PASSED_RESET) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the MASK_GPU_PASSED_RESET field to a new value. +#define BW_SRC_SIMR_MASK_GPU_PASSED_RESET(v) (HW_SRC_SIMR_WR((HW_SRC_SIMR_RD() & ~BM_SRC_SIMR_MASK_GPU_PASSED_RESET) | BF_SRC_SIMR_MASK_GPU_PASSED_RESET(v))) +#endif +//@} + +/*! @name Register SRC_SIMR, field MASK_VPU_PASSED_RESET[1] (RW) + * + * mask interrupt generation due to vpu passed reset + * + * Values: + * - 0 - don't mask interrupt due to vpu passed reset - interrupt will be created + * - 1 - mask interrupt due to vpu passed reset + */ +//@{ +#define BP_SRC_SIMR_MASK_VPU_PASSED_RESET (1) //!< Bit position for SRC_SIMR_MASK_VPU_PASSED_RESET. +#define BM_SRC_SIMR_MASK_VPU_PASSED_RESET (0x00000002) //!< Bit mask for SRC_SIMR_MASK_VPU_PASSED_RESET. + +//! @brief Get value of SRC_SIMR_MASK_VPU_PASSED_RESET from a register value. +#define BG_SRC_SIMR_MASK_VPU_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SIMR_MASK_VPU_PASSED_RESET) >> BP_SRC_SIMR_MASK_VPU_PASSED_RESET) + +//! @brief Format value for bitfield SRC_SIMR_MASK_VPU_PASSED_RESET. +#define BF_SRC_SIMR_MASK_VPU_PASSED_RESET(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SIMR_MASK_VPU_PASSED_RESET) & BM_SRC_SIMR_MASK_VPU_PASSED_RESET) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the MASK_VPU_PASSED_RESET field to a new value. +#define BW_SRC_SIMR_MASK_VPU_PASSED_RESET(v) (HW_SRC_SIMR_WR((HW_SRC_SIMR_RD() & ~BM_SRC_SIMR_MASK_VPU_PASSED_RESET) | BF_SRC_SIMR_MASK_VPU_PASSED_RESET(v))) +#endif +//@} + +/*! @name Register SRC_SIMR, field MASK_IPU_PASSED_RESET[2] (RW) + * + * mask interrupt generation due to ipu passed reset + * + * Values: + * - 0 - don't mask interrupt due to ipu passed reset - interrupt will be created + * - 1 - mask interrupt due to ipu passed reset + */ +//@{ +#define BP_SRC_SIMR_MASK_IPU_PASSED_RESET (2) //!< Bit position for SRC_SIMR_MASK_IPU_PASSED_RESET. +#define BM_SRC_SIMR_MASK_IPU_PASSED_RESET (0x00000004) //!< Bit mask for SRC_SIMR_MASK_IPU_PASSED_RESET. + +//! @brief Get value of SRC_SIMR_MASK_IPU_PASSED_RESET from a register value. +#define BG_SRC_SIMR_MASK_IPU_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SIMR_MASK_IPU_PASSED_RESET) >> BP_SRC_SIMR_MASK_IPU_PASSED_RESET) + +//! @brief Format value for bitfield SRC_SIMR_MASK_IPU_PASSED_RESET. +#define BF_SRC_SIMR_MASK_IPU_PASSED_RESET(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SIMR_MASK_IPU_PASSED_RESET) & BM_SRC_SIMR_MASK_IPU_PASSED_RESET) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the MASK_IPU_PASSED_RESET field to a new value. +#define BW_SRC_SIMR_MASK_IPU_PASSED_RESET(v) (HW_SRC_SIMR_WR((HW_SRC_SIMR_RD() & ~BM_SRC_SIMR_MASK_IPU_PASSED_RESET) | BF_SRC_SIMR_MASK_IPU_PASSED_RESET(v))) +#endif +//@} + +/*! @name Register SRC_SIMR, field MASK_OPEN_VG_PASSED_RESET[3] (RW) + * + * mask interrupt generation due to open_vg passed reset + * + * Values: + * - 0 - don't mask interrupt due to open_vg passed reset - interrupt will be created + * - 1 - mask interrupt due to open_vg passed reset + */ +//@{ +#define BP_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET (3) //!< Bit position for SRC_SIMR_MASK_OPEN_VG_PASSED_RESET. +#define BM_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET (0x00000008) //!< Bit mask for SRC_SIMR_MASK_OPEN_VG_PASSED_RESET. + +//! @brief Get value of SRC_SIMR_MASK_OPEN_VG_PASSED_RESET from a register value. +#define BG_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET) >> BP_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET) + +//! @brief Format value for bitfield SRC_SIMR_MASK_OPEN_VG_PASSED_RESET. +#define BF_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET) & BM_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the MASK_OPEN_VG_PASSED_RESET field to a new value. +#define BW_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET(v) (HW_SRC_SIMR_WR((HW_SRC_SIMR_RD() & ~BM_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET) | BF_SRC_SIMR_MASK_OPEN_VG_PASSED_RESET(v))) +#endif +//@} + +/*! @name Register SRC_SIMR, field MASK_IPU2_PASSED_RESET[4] (RW) + * + * mask interrupt generation due to ipu2 passing reset + * + * Values: + * - 0 - don't mask interrupt due to ipu2 passed reset - interrupt will be created + * - 1 - mask interrupt due to ipu2 passed reset + */ +//@{ +#define BP_SRC_SIMR_MASK_IPU2_PASSED_RESET (4) //!< Bit position for SRC_SIMR_MASK_IPU2_PASSED_RESET. +#define BM_SRC_SIMR_MASK_IPU2_PASSED_RESET (0x00000010) //!< Bit mask for SRC_SIMR_MASK_IPU2_PASSED_RESET. + +//! @brief Get value of SRC_SIMR_MASK_IPU2_PASSED_RESET from a register value. +#define BG_SRC_SIMR_MASK_IPU2_PASSED_RESET(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SIMR_MASK_IPU2_PASSED_RESET) >> BP_SRC_SIMR_MASK_IPU2_PASSED_RESET) + +//! @brief Format value for bitfield SRC_SIMR_MASK_IPU2_PASSED_RESET. +#define BF_SRC_SIMR_MASK_IPU2_PASSED_RESET(v) ((__REG_VALUE_TYPE((v), reg32_t) << BP_SRC_SIMR_MASK_IPU2_PASSED_RESET) & BM_SRC_SIMR_MASK_IPU2_PASSED_RESET) + +#ifndef __LANGUAGE_ASM__ +//! @brief Set the MASK_IPU2_PASSED_RESET field to a new value. +#define BW_SRC_SIMR_MASK_IPU2_PASSED_RESET(v) (HW_SRC_SIMR_WR((HW_SRC_SIMR_RD() & ~BM_SRC_SIMR_MASK_IPU2_PASSED_RESET) | BF_SRC_SIMR_MASK_IPU2_PASSED_RESET(v))) +#endif +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_SBMR2 - SRC Boot Mode Register 2 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_SBMR2 - SRC Boot Mode Register 2 (RO) + * + * Reset value: 0x00000000 + * + * The Boot Mode register (SBMR), contains bits that reflect the status of Boot Mode Pins of the + * chip. The default values for those bits depends on the values of pins/fuses during reset + * sequence, hence the question mark on their default value. + */ +typedef union _hw_src_sbmr2 { + reg32_t U; + struct _hw_src_sbmr2_bitfields { + unsigned SEC_CONFIG : 2; //!< [1:0] Please refer to fuse map. + unsigned RESERVED0 : 1; //!< [2] Reserved + unsigned DIR_BT_DIS : 1; //!< [3] Please refer to fuse map. + unsigned BT_FUSE_SEL : 1; //!< [4] BT_FUSE_SEL (connected to gpio bt_fuse_sel) + unsigned RESERVED1 : 19; //!< [23:5] Reserved. + unsigned BMOD : 2; //!< [25:24] Please refer to fuse map. + unsigned RESERVED2 : 1; //!< [26] Reserved + unsigned TEST_MODE : 3; //!< [29:27] Please refer to fuse map. + unsigned RESERVED3 : 2; //!< [31:30] Reserved + } B; +} hw_src_sbmr2_t; +#endif + +/*! + * @name Constants and macros for entire SRC_SBMR2 register + */ +//@{ +#define HW_SRC_SBMR2_ADDR (REGS_SRC_BASE + 0x1c) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_SBMR2 (*(volatile hw_src_sbmr2_t*)HW_SRC_SBMR2_ADDR) +#define HW_SRC_SBMR2_RD() (HW_SRC_SBMR2.U) +#endif +//@} + +/* + * constants & macros for individual SRC_SBMR2 bitfields + */ + +/*! @name Register SRC_SBMR2, field SEC_CONFIG[1:0] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR2_SEC_CONFIG (0) //!< Bit position for SRC_SBMR2_SEC_CONFIG. +#define BM_SRC_SBMR2_SEC_CONFIG (0x00000003) //!< Bit mask for SRC_SBMR2_SEC_CONFIG. + +//! @brief Get value of SRC_SBMR2_SEC_CONFIG from a register value. +#define BG_SRC_SBMR2_SEC_CONFIG(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR2_SEC_CONFIG) >> BP_SRC_SBMR2_SEC_CONFIG) +//@} + +/*! @name Register SRC_SBMR2, field DIR_BT_DIS[3] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR2_DIR_BT_DIS (3) //!< Bit position for SRC_SBMR2_DIR_BT_DIS. +#define BM_SRC_SBMR2_DIR_BT_DIS (0x00000008) //!< Bit mask for SRC_SBMR2_DIR_BT_DIS. + +//! @brief Get value of SRC_SBMR2_DIR_BT_DIS from a register value. +#define BG_SRC_SBMR2_DIR_BT_DIS(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR2_DIR_BT_DIS) >> BP_SRC_SBMR2_DIR_BT_DIS) +//@} + +/*! @name Register SRC_SBMR2, field BT_FUSE_SEL[4] (RO) + * + * BT_FUSE_SEL (connected to gpio bt_fuse_sel) + */ +//@{ +#define BP_SRC_SBMR2_BT_FUSE_SEL (4) //!< Bit position for SRC_SBMR2_BT_FUSE_SEL. +#define BM_SRC_SBMR2_BT_FUSE_SEL (0x00000010) //!< Bit mask for SRC_SBMR2_BT_FUSE_SEL. + +//! @brief Get value of SRC_SBMR2_BT_FUSE_SEL from a register value. +#define BG_SRC_SBMR2_BT_FUSE_SEL(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR2_BT_FUSE_SEL) >> BP_SRC_SBMR2_BT_FUSE_SEL) +//@} + +/*! @name Register SRC_SBMR2, field BMOD[25:24] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR2_BMOD (24) //!< Bit position for SRC_SBMR2_BMOD. +#define BM_SRC_SBMR2_BMOD (0x03000000) //!< Bit mask for SRC_SBMR2_BMOD. + +//! @brief Get value of SRC_SBMR2_BMOD from a register value. +#define BG_SRC_SBMR2_BMOD(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR2_BMOD) >> BP_SRC_SBMR2_BMOD) +//@} + +/*! @name Register SRC_SBMR2, field TEST_MODE[29:27] (RO) + * + * Please refer to fuse map. + */ +//@{ +#define BP_SRC_SBMR2_TEST_MODE (27) //!< Bit position for SRC_SBMR2_TEST_MODE. +#define BM_SRC_SBMR2_TEST_MODE (0x38000000) //!< Bit mask for SRC_SBMR2_TEST_MODE. + +//! @brief Get value of SRC_SBMR2_TEST_MODE from a register value. +#define BG_SRC_SBMR2_TEST_MODE(r) ((__REG_VALUE_TYPE((r), reg32_t) & BM_SRC_SBMR2_TEST_MODE) >> BP_SRC_SBMR2_TEST_MODE) +//@} + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR1 - SRC General Purpose Register 1 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR1 - SRC General Purpose Register 1 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 1 (GPR1), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr1 { + reg32_t U; + struct _hw_src_gpr1_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr1_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR1 register + */ +//@{ +#define HW_SRC_GPR1_ADDR (REGS_SRC_BASE + 0x20) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR1 (*(volatile hw_src_gpr1_t*)HW_SRC_GPR1_ADDR) +#define HW_SRC_GPR1_RD() (HW_SRC_GPR1.U) +#define HW_SRC_GPR1_WR(v) (HW_SRC_GPR1.U = (v)) +#define HW_SRC_GPR1_SET(v) (HW_SRC_GPR1_WR(HW_SRC_GPR1_RD() | (v))) +#define HW_SRC_GPR1_CLR(v) (HW_SRC_GPR1_WR(HW_SRC_GPR1_RD() & ~(v))) +#define HW_SRC_GPR1_TOG(v) (HW_SRC_GPR1_WR(HW_SRC_GPR1_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR1 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR2 - SRC General Purpose Register 2 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR2 - SRC General Purpose Register 2 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 2(GPR2), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr2 { + reg32_t U; + struct _hw_src_gpr2_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr2_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR2 register + */ +//@{ +#define HW_SRC_GPR2_ADDR (REGS_SRC_BASE + 0x24) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR2 (*(volatile hw_src_gpr2_t*)HW_SRC_GPR2_ADDR) +#define HW_SRC_GPR2_RD() (HW_SRC_GPR2.U) +#define HW_SRC_GPR2_WR(v) (HW_SRC_GPR2.U = (v)) +#define HW_SRC_GPR2_SET(v) (HW_SRC_GPR2_WR(HW_SRC_GPR2_RD() | (v))) +#define HW_SRC_GPR2_CLR(v) (HW_SRC_GPR2_WR(HW_SRC_GPR2_RD() & ~(v))) +#define HW_SRC_GPR2_TOG(v) (HW_SRC_GPR2_WR(HW_SRC_GPR2_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR2 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR3 - SRC General Purpose Register 3 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR3 - SRC General Purpose Register 3 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 3 (GPR3), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr3 { + reg32_t U; + struct _hw_src_gpr3_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr3_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR3 register + */ +//@{ +#define HW_SRC_GPR3_ADDR (REGS_SRC_BASE + 0x28) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR3 (*(volatile hw_src_gpr3_t*)HW_SRC_GPR3_ADDR) +#define HW_SRC_GPR3_RD() (HW_SRC_GPR3.U) +#define HW_SRC_GPR3_WR(v) (HW_SRC_GPR3.U = (v)) +#define HW_SRC_GPR3_SET(v) (HW_SRC_GPR3_WR(HW_SRC_GPR3_RD() | (v))) +#define HW_SRC_GPR3_CLR(v) (HW_SRC_GPR3_WR(HW_SRC_GPR3_RD() & ~(v))) +#define HW_SRC_GPR3_TOG(v) (HW_SRC_GPR3_WR(HW_SRC_GPR3_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR3 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR4 - SRC General Purpose Register 4 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR4 - SRC General Purpose Register 4 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 4 (GPR4), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr4 { + reg32_t U; + struct _hw_src_gpr4_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr4_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR4 register + */ +//@{ +#define HW_SRC_GPR4_ADDR (REGS_SRC_BASE + 0x2c) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR4 (*(volatile hw_src_gpr4_t*)HW_SRC_GPR4_ADDR) +#define HW_SRC_GPR4_RD() (HW_SRC_GPR4.U) +#define HW_SRC_GPR4_WR(v) (HW_SRC_GPR4.U = (v)) +#define HW_SRC_GPR4_SET(v) (HW_SRC_GPR4_WR(HW_SRC_GPR4_RD() | (v))) +#define HW_SRC_GPR4_CLR(v) (HW_SRC_GPR4_WR(HW_SRC_GPR4_RD() & ~(v))) +#define HW_SRC_GPR4_TOG(v) (HW_SRC_GPR4_WR(HW_SRC_GPR4_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR4 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR5 - SRC General Purpose Register 5 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR5 - SRC General Purpose Register 5 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 5(GPR5), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr5 { + reg32_t U; + struct _hw_src_gpr5_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr5_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR5 register + */ +//@{ +#define HW_SRC_GPR5_ADDR (REGS_SRC_BASE + 0x30) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR5 (*(volatile hw_src_gpr5_t*)HW_SRC_GPR5_ADDR) +#define HW_SRC_GPR5_RD() (HW_SRC_GPR5.U) +#define HW_SRC_GPR5_WR(v) (HW_SRC_GPR5.U = (v)) +#define HW_SRC_GPR5_SET(v) (HW_SRC_GPR5_WR(HW_SRC_GPR5_RD() | (v))) +#define HW_SRC_GPR5_CLR(v) (HW_SRC_GPR5_WR(HW_SRC_GPR5_RD() & ~(v))) +#define HW_SRC_GPR5_TOG(v) (HW_SRC_GPR5_WR(HW_SRC_GPR5_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR5 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR6 - SRC General Purpose Register 6 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR6 - SRC General Purpose Register 6 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 6(GPR6), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr6 { + reg32_t U; + struct _hw_src_gpr6_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr6_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR6 register + */ +//@{ +#define HW_SRC_GPR6_ADDR (REGS_SRC_BASE + 0x34) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR6 (*(volatile hw_src_gpr6_t*)HW_SRC_GPR6_ADDR) +#define HW_SRC_GPR6_RD() (HW_SRC_GPR6.U) +#define HW_SRC_GPR6_WR(v) (HW_SRC_GPR6.U = (v)) +#define HW_SRC_GPR6_SET(v) (HW_SRC_GPR6_WR(HW_SRC_GPR6_RD() | (v))) +#define HW_SRC_GPR6_CLR(v) (HW_SRC_GPR6_WR(HW_SRC_GPR6_RD() & ~(v))) +#define HW_SRC_GPR6_TOG(v) (HW_SRC_GPR6_WR(HW_SRC_GPR6_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR6 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR7 - SRC General Purpose Register 7 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR7 - SRC General Purpose Register 7 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 7(GPR7), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr7 { + reg32_t U; + struct _hw_src_gpr7_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr7_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR7 register + */ +//@{ +#define HW_SRC_GPR7_ADDR (REGS_SRC_BASE + 0x38) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR7 (*(volatile hw_src_gpr7_t*)HW_SRC_GPR7_ADDR) +#define HW_SRC_GPR7_RD() (HW_SRC_GPR7.U) +#define HW_SRC_GPR7_WR(v) (HW_SRC_GPR7.U = (v)) +#define HW_SRC_GPR7_SET(v) (HW_SRC_GPR7_WR(HW_SRC_GPR7_RD() | (v))) +#define HW_SRC_GPR7_CLR(v) (HW_SRC_GPR7_WR(HW_SRC_GPR7_RD() & ~(v))) +#define HW_SRC_GPR7_TOG(v) (HW_SRC_GPR7_WR(HW_SRC_GPR7_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR7 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR8 - SRC General Purpose Register 8 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR8 - SRC General Purpose Register 8 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 8(GPR8), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr8 { + reg32_t U; + struct _hw_src_gpr8_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose + } B; +} hw_src_gpr8_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR8 register + */ +//@{ +#define HW_SRC_GPR8_ADDR (REGS_SRC_BASE + 0x3c) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR8 (*(volatile hw_src_gpr8_t*)HW_SRC_GPR8_ADDR) +#define HW_SRC_GPR8_RD() (HW_SRC_GPR8.U) +#define HW_SRC_GPR8_WR(v) (HW_SRC_GPR8.U = (v)) +#define HW_SRC_GPR8_SET(v) (HW_SRC_GPR8_WR(HW_SRC_GPR8_RD() | (v))) +#define HW_SRC_GPR8_CLR(v) (HW_SRC_GPR8_WR(HW_SRC_GPR8_RD() & ~(v))) +#define HW_SRC_GPR8_TOG(v) (HW_SRC_GPR8_WR(HW_SRC_GPR8_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR8 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR9 - SRC General Purpose Register 9 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR9 - SRC General Purpose Register 9 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 9(GPR9), contains read/write bits that can be used for any purpose. + */ +typedef union _hw_src_gpr9 { + reg32_t U; + struct _hw_src_gpr9_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose. + } B; +} hw_src_gpr9_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR9 register + */ +//@{ +#define HW_SRC_GPR9_ADDR (REGS_SRC_BASE + 0x40) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR9 (*(volatile hw_src_gpr9_t*)HW_SRC_GPR9_ADDR) +#define HW_SRC_GPR9_RD() (HW_SRC_GPR9.U) +#define HW_SRC_GPR9_WR(v) (HW_SRC_GPR9.U = (v)) +#define HW_SRC_GPR9_SET(v) (HW_SRC_GPR9_WR(HW_SRC_GPR9_RD() | (v))) +#define HW_SRC_GPR9_CLR(v) (HW_SRC_GPR9_WR(HW_SRC_GPR9_RD() & ~(v))) +#define HW_SRC_GPR9_TOG(v) (HW_SRC_GPR9_WR(HW_SRC_GPR9_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR9 bitfields + */ + +//------------------------------------------------------------------------------------------- +// HW_SRC_GPR10 - SRC General Purpose Register 10 +//------------------------------------------------------------------------------------------- + +#ifndef __LANGUAGE_ASM__ +/*! + * @brief HW_SRC_GPR10 - SRC General Purpose Register 10 (RW) + * + * Reset value: 0x00000000 + * + * The general purpose register 10(GPR10), contains read/write bits that can be used for any + * purpose. + */ +typedef union _hw_src_gpr10 { + reg32_t U; + struct _hw_src_gpr10_bitfields { + unsigned RESERVED0 : 32; //!< [31:0] Read/write bits, for general purpose. + } B; +} hw_src_gpr10_t; +#endif + +/*! + * @name Constants and macros for entire SRC_GPR10 register + */ +//@{ +#define HW_SRC_GPR10_ADDR (REGS_SRC_BASE + 0x44) + +#ifndef __LANGUAGE_ASM__ +#define HW_SRC_GPR10 (*(volatile hw_src_gpr10_t*)HW_SRC_GPR10_ADDR) +#define HW_SRC_GPR10_RD() (HW_SRC_GPR10.U) +#define HW_SRC_GPR10_WR(v) (HW_SRC_GPR10.U = (v)) +#define HW_SRC_GPR10_SET(v) (HW_SRC_GPR10_WR(HW_SRC_GPR10_RD() | (v))) +#define HW_SRC_GPR10_CLR(v) (HW_SRC_GPR10_WR(HW_SRC_GPR10_RD() & ~(v))) +#define HW_SRC_GPR10_TOG(v) (HW_SRC_GPR10_WR(HW_SRC_GPR10_RD() ^ (v))) +#endif +//@} + +/* + * constants & macros for individual SRC_GPR10 bitfields + */ + +//------------------------------------------------------------------------------------------- +// hw_src_t - module struct +//------------------------------------------------------------------------------------------- +/*! + * @brief All SRC module registers. + */ +#ifndef __LANGUAGE_ASM__ +#pragma pack(1) +typedef struct _hw_src { + volatile hw_src_scr_t SCR; //!< SRC Control Register + volatile hw_src_sbmr1_t SBMR1; //!< SRC Boot Mode Register 1 + volatile hw_src_srsr_t SRSR; //!< SRC Reset Status Register + reg32_t _reserved0[2]; + volatile hw_src_sisr_t SISR; //!< SRC Interrupt Status Register + volatile hw_src_simr_t SIMR; //!< SRC Interrupt Mask Register + volatile hw_src_sbmr2_t SBMR2; //!< SRC Boot Mode Register 2 + volatile hw_src_gpr1_t GPR1; //!< SRC General Purpose Register 1 + volatile hw_src_gpr2_t GPR2; //!< SRC General Purpose Register 2 + volatile hw_src_gpr3_t GPR3; //!< SRC General Purpose Register 3 + volatile hw_src_gpr4_t GPR4; //!< SRC General Purpose Register 4 + volatile hw_src_gpr5_t GPR5; //!< SRC General Purpose Register 5 + volatile hw_src_gpr6_t GPR6; //!< SRC General Purpose Register 6 + volatile hw_src_gpr7_t GPR7; //!< SRC General Purpose Register 7 + volatile hw_src_gpr8_t GPR8; //!< SRC General Purpose Register 8 + volatile hw_src_gpr9_t GPR9; //!< SRC General Purpose Register 9 + volatile hw_src_gpr10_t GPR10; //!< SRC General Purpose Register 10 +} hw_src_t; +#pragma pack() + +//! @brief Macro to access all SRC registers. +//! @return Reference (not a pointer) to the registers struct. To get a pointer to the struct, +//! use the '&' operator, like &HW_SRC. +#define HW_SRC (*(hw_src_t*)REGS_SRC_BASE) +#endif + +#endif // __HW_SRC_REGISTERS_H__ +// v18/121106/1.2.2 +// EOF diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c index 00dfc357d..b148dd4c3 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c @@ -36,6 +36,7 @@ Modification: #include "uart_common_ope.h" #include "assert.h" +#include "pagetable.h" #define KERN_BOOT_DRIVER(n, bi, f) \ { \ @@ -196,4 +197,31 @@ bool hardkernel_init(struct TraceTag* _hardkernel_tag) LOG_PRINTF("\n"); } return true; +} + +bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag) +{ + struct TraceTag init_intr_tag, init_icache_tag, init_dcache_tag, init_clock_tag, init_mmu_tag; + AchieveResourceTag(&init_intr_tag, _hardkernel_tag, "intr-ac-resource"); + AchieveResourceTag(&init_icache_tag, _hardkernel_tag, "icache-ac-resource"); + AchieveResourceTag(&init_dcache_tag, _hardkernel_tag, "dcache-ac-resource"); + AchieveResourceTag(&init_clock_tag, _hardkernel_tag, "clock-ac-resource"); + AchieveResourceTag(&init_mmu_tag, _hardkernel_tag, "mmu-ac-resource"); + struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&init_intr_tag); + struct ICacheDone* p_icache_driver = (struct ICacheDone*)AchieveResource(&init_icache_tag); + struct DCacheDone* p_dcache_driver = (struct DCacheDone*)AchieveResource(&init_dcache_tag); + struct XiziClockDriver* p_clock_driver = (struct XiziClockDriver*)AchieveResource(&init_clock_tag); + + // secondary cpu init hardwares + // intr + p_intr_driver->sys_irq_init(cpu_id); + // cache + p_icache_driver->enable(); + p_dcache_driver->enable(); + // clock + p_clock_driver->sys_clock_init(); + p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0); + // mmu + secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag); + return true; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index 8cb244967..f9fcde6c8 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -82,22 +82,22 @@ void handle_fiq(void) panic(""); } -static void _sys_irq_init() +static void _sys_irq_init(int cpu_id) { /* load exception vectors */ - volatile uint32_t* vector_base = &_vector_start; - - // Set Interrupt handler start address - vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction - vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt - vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort - vector_base[4] = (uint32_t)trap_dabort; // Data Abort - vector_base[5] = (uint32_t)handle_reserved; // Reserved - vector_base[6] = (uint32_t)trap_irq_enter; // IRQ - vector_base[7] = (uint32_t)handle_fiq; // FIQ - - init_cpu_mode_stacks(0); + init_cpu_mode_stacks(cpu_id); + if (cpu_id == 0) { + volatile uint32_t* vector_base = &_vector_start; + // Set Interrupt handler start address + vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction + vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt + vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort + vector_base[4] = (uint32_t)trap_dabort; // Data Abort + vector_base[5] = (uint32_t)handle_reserved; // Reserved + vector_base[6] = (uint32_t)trap_irq_enter; // IRQ + vector_base[7] = (uint32_t)handle_fiq; // FIQ + } /* active hardware irq responser */ gic_init(); xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper); @@ -240,7 +240,7 @@ static struct XiziTrapDriver xizi_trap_driver = { struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag) { - xizi_trap_driver.sys_irq_init(); + xizi_trap_driver.sys_irq_init(0); xizi_trap_driver.cpu_irq_disable(); return &xizi_trap_driver; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c index 5d143a444..4581ef0e7 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c @@ -21,6 +21,7 @@ #include "assert.h" #include "spinlock.h" +#include "trap_common.h" bool module_spinlock_use_intr_init(void) { @@ -43,11 +44,11 @@ void spinlock_init(struct spinlock* lock, char* name) extern int _spinlock_lock(struct spinlock* lock, uint32_t timeout); void spinlock_lock(struct spinlock* lock) { - if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK) { + if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpuid()) { ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu); panic(""); } - assert(_spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER) == 0); + _spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER); } void _spinlock_unlock(struct spinlock* lock); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c index de89cbd21..754828883 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c @@ -85,21 +85,23 @@ void handle_fiq(void) panic(""); } -static void _sys_irq_init() +static void _sys_irq_init(int cpu_id) { - /* load exception vectors */ - volatile uint32_t* vector_base = &_vector_start; + if (cpu_id == 0) { + /* load exception vectors */ + volatile uint32_t* vector_base = &_vector_start; - // Set Interrupt handler start address - vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction - vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt - vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort - vector_base[4] = (uint32_t)trap_dabort; // Data Abort - vector_base[5] = (uint32_t)handle_reserved; // Reserved - vector_base[6] = (uint32_t)trap_irq_enter; // IRQ - vector_base[7] = (uint32_t)handle_fiq; // FIQ + // Set Interrupt handler start address + vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction + vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt + vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort + vector_base[4] = (uint32_t)trap_dabort; // Data Abort + vector_base[5] = (uint32_t)handle_reserved; // Reserved + vector_base[6] = (uint32_t)trap_irq_enter; // IRQ + vector_base[7] = (uint32_t)handle_fiq; // FIQ + } - init_cpu_mode_stacks(0); + init_cpu_mode_stacks(cpu_id); /* active hardware irq responser */ XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h index 19c6831e0..06a64ca7d 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h @@ -59,7 +59,7 @@ struct XiziTrapDriver { /* current irq number happening in cpu*/ uint32_t curr_int[NR_CPU]; - void (*sys_irq_init)(); + void (*sys_irq_init)(int); int (*cur_cpu_id)(); void (*cpu_irq_enable)(); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c index 086543471..7468540e8 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c @@ -94,6 +94,7 @@ void bootmain() build_boot_pgdir(); load_boot_pgdir(); __asm__ __volatile__("add sp, sp, %0" ::"r"(KERN_MEM_BASE - PHY_MEM_BASE)); - memset(&kernel_data_begin, 0x00, (uint32_t)kernel_data_end - (uint32_t)kernel_data_begin); + // memset(&kernel_data_begin, 0x00, (uint32_t)kernel_data_end - (uint32_t)kernel_data_begin); + main(); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c index 32dcbf651..205209a85 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c @@ -447,9 +447,11 @@ bool tracer_delete_trace(struct TraceTag* target, struct TraceTag* owner) return true; } +static struct spinlock ac_tracer_lock; void tracer_init(void) { /* init sys_tracer, the manager */ + spinlock_init(&ac_tracer_lock, "tracerlock"); spinlock_init(&sys_tracer.mem_chunk_bitmap_lock, "tracer_mem_chunk_bitmap"); spinlock_init(&sys_tracer.trace_meta_bitmap_lock, "tracer_meta_bitmap"); memset(sys_tracer.mem_chunks_bit_map, 0, sizeof(sys_tracer.mem_chunk_bitmap_lock)); @@ -494,26 +496,31 @@ void tracer_find_tag(struct TraceTag* target, struct TraceTag* const source, cha bool AchieveResourceTag(struct TraceTag* target, struct TraceTag* owner, char* name) { + spinlock_lock(&ac_tracer_lock); tracer_find_tag(target, owner, name); if (target->meta == NULL) { return false; } + spinlock_unlock(&ac_tracer_lock); return true; } void* AchieveResource(struct TraceTag* target) { + spinlock_lock(&ac_tracer_lock); if (target->type == TRACER_OWNER) { return NULL; } void* p_resource = NULL; tracer_read_trace(target, (char*)&p_resource, 0, sizeof(void*)); assert(p_resource != NULL); + spinlock_unlock(&ac_tracer_lock); return p_resource; } bool CreateResourceTag(struct TraceTag* new_tag, struct TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource) { + // spinlock_lock(&ac_tracer_lock); new_tag->type = type; if (type == TRACER_OWNER) { return tracer_create_trace(new_tag, owner, name, type); @@ -527,10 +534,14 @@ bool CreateResourceTag(struct TraceTag* new_tag, struct TraceTag* owner, char* n if (!tracer_create_trace(new_tag, owner, name, type)) { return false; } - return tracer_write_trace(new_tag, (char*)&p_resource, 0, sizeof(void*)) == sizeof(void*); + bool ret = tracer_write_trace(new_tag, (char*)&p_resource, 0, sizeof(void*)) == sizeof(void*); + // spinlock_unlock(&ac_tracer_lock); + return ret; } bool DeleteResource(struct TraceTag* target, struct TraceTag* owner) { + spinlock_lock(&ac_tracer_lock); return tracer_delete_trace(target, owner); + spinlock_unlock(&ac_tracer_lock); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/app/init.c b/Ubiquitous/XiZi_AIoT/services/app/init.c index f9622e996..600770a26 100755 --- a/Ubiquitous/XiZi_AIoT/services/app/init.c +++ b/Ubiquitous/XiZi_AIoT/services/app/init.c @@ -19,7 +19,11 @@ int main(int argc, char* argv[]) { struct Session session; - connect_session(&session, "MemFS", 8092); + printf("connecting MemFS\n"); + while (connect_session(&session, "MemFS", 8092) < 0) { + printf("connecting MemFS\n"); + } + printf("connect MemFS success\n"); int fd; char* shell_task_param[2] = { "/shell", 0 }; diff --git a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c index 1e0d2dbad..98260ac43 100644 --- a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c +++ b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c @@ -66,7 +66,7 @@ int IPC_DO_SERVE_FUNC(Ipc_ls)(char* path) printf("ls: find target Inode failed, ip: %x(%d), dp: %x(%d)\n", ip, ip->inum, dp, dp->inum); return -1; } - if (ip->type != T_DIR) { + if (ip->type != FS_DIRECTORY) { printf("ls: not a dir\n"); return -1; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/kern_init.h b/Ubiquitous/XiZi_AIoT/softkernel/include/kern_init.h index 5bb31dad5..c807a75da 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/kern_init.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/kern_init.h @@ -37,5 +37,6 @@ struct XiziBootNode { }; bool hardkernel_init(struct TraceTag*); +bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag); bool softkernel_init(struct TraceTag* _hardkernel_tag, struct TraceTag* _softkernel_tag); void show_xizi_bar(void); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h index 1db29ac9c..fad604925 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h @@ -30,6 +30,7 @@ Modification: #pragma once #include "core.h" +#include "spinlock.h" #include "trap_common.h" struct CPU { @@ -44,4 +45,6 @@ extern struct CPU global_cpus[NR_CPU]; static inline struct CPU* cur_cpu(void) { return &global_cpus[cur_cpuid()]; -} \ No newline at end of file +} + +struct spinlock whole_kernel_lock; \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h b/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h index bd3f70af4..691430773 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/pagetable.h @@ -72,6 +72,7 @@ uintptr_t* _page_walk(uintptr_t* pgdir, uintptr_t vaddr, bool alloc); extern struct TopLevelPageDirectory kern_pgdir; void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag); +void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag); extern struct XiziPageManager xizi_pager; bool module_pager_init(struct PagerRightGroup*); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 95dc72341..c8f143785 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -27,37 +27,130 @@ Author: AIIT XUOS Lab Modification: 1. first version *************************************************/ +/// @todo use hardkernel +#include "cortex_a9.h" +#include "regssrc.h" + #include "kern_init.h" +#include "multicores.h" #include "assert.h" #include "task.h" #include "trap_common.h" +void configure_cpu(uint32_t cpu) +{ + const unsigned int all_ways = 0xf; + + disable_strict_align_check(); + + // Enable branch prediction + arm_branch_target_cache_invalidate(); + arm_branch_prediction_enable(); + + // Enable L1 caches + // arm_dcache_enable(); + // arm_dcache_invalidate(); + // arm_icache_enable(); + // arm_icache_invalidate(); + + // Invalidate SCU copy of TAG RAMs + scu_secure_invalidate(cpu, all_ways); + + // Join SMP + scu_join_smp(); + scu_enable_maintenance_broadcast(); +} + +typedef void (*cpu_entry_point_t)(void* arg); +typedef struct _core_startup_info { + cpu_entry_point_t entry; //!< Function to call after starting a core. + void* arg; //!< Argument to pass core entry point. +} core_startup_info_t; +static core_startup_info_t s_core_info[NR_CPU] = { { 0 } }; + +static void common_cpu_entry(void) +{ + uint32_t myCoreNumber = cpu_get_current(); + core_startup_info_t* info = &s_core_info[myCoreNumber]; + + // Call the requested entry point for this CPU number. + if (info->entry) { + info->entry(info->arg); + } +} + +extern void _boot_start(); +void cpu_start_secondary(uint8_t coreNumber, cpu_entry_point_t entryPoint, void* arg) +{ + // Save entry point and arg. + s_core_info[coreNumber].entry = entryPoint; + s_core_info[coreNumber].arg = arg; + + // Prepare pointers for ROM code. The entry point is always _start, which does some + // basic preparatory work and then calls the common_cpu_entry function, which itself + // calls the entry point saved in s_core_info. + switch (coreNumber) { + case 1: + HW_SRC_GPR3_WR((uint32_t)&_boot_start); + // HW_SRC_GPR4_WR((uint32_t)common_cpu_entry); + + HW_SRC_SCR.B.CORE1_ENABLE = 1; + break; + + case 2: + HW_SRC_GPR5_WR((uint32_t)&_boot_start); + // HW_SRC_GPR6_WR((uint32_t)common_cpu_entry); + + HW_SRC_SCR.B.CORE2_ENABLE = 1; + break; + + case 3: + HW_SRC_GPR7_WR((uint32_t)&_boot_start); + // HW_SRC_GPR8_WR((uint32_t)common_cpu_entry); + + HW_SRC_SCR.B.CORE3_ENABLE = 1; + break; + } +} + extern uint32_t _binary_init_start[], _binary_default_fs_start[]; -extern int sys_spawn(char* path, char** argv); +static struct TraceTag hardkernel_tag, softkernel_tag; + +static bool init = false; int main(void) { /* init tracer */ - // clang-format off - tracer_init(); // init tracer system - struct TraceTag hardkernel_tag, softkernel_tag; - if (!CreateResourceTag(&hardkernel_tag, RequireRootTag(), "hardkernel", TRACER_OWNER, NULL) || - !CreateResourceTag(&softkernel_tag, RequireRootTag(), "softkernel", TRACER_OWNER, NULL)) { - ERROR("Failed to create hardkernel owner and softkernel owner.\n"); - return -1; - } - // clang-format on + uint32_t cpu_id = cur_cpuid(); - /* init hardkernel */ - if (!hardkernel_init(&hardkernel_tag)) { - return -1; + if (cpu_id == 0) { + tracer_init(); // init tracer system + // clang-format off + if (!CreateResourceTag(&hardkernel_tag, RequireRootTag(), "hardkernel", TRACER_OWNER, NULL) || + !CreateResourceTag(&softkernel_tag, RequireRootTag(), "softkernel", TRACER_OWNER, NULL)) { + ERROR("Failed to create hardkernel owner and softkernel owner.\n"); + return -1; + } + // clang-format on + /* init hardkernel */ + if (!hardkernel_init(&hardkernel_tag)) { + return -1; + } + + spinlock_init(&whole_kernel_lock, "wklock"); + } else { + configure_cpu(cpu_id); + DEBUG_PRINTF("CPU %d started init: %d(at %x).\n", cur_cpuid(), init, &init); + spinlock_lock(&whole_kernel_lock); + secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag); + spinlock_unlock(&whole_kernel_lock); + DEBUG_PRINTF("CPU %d started done.\n", cur_cpuid()); } - struct TraceTag main_intr_tag; - AchieveResourceTag(&main_intr_tag, &hardkernel_tag, "intr-ac-resource"); - struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&main_intr_tag); - int cpu_id = p_intr_driver->cur_cpu_id(); + // struct TraceTag main_intr_tag; + // AchieveResourceTag(&main_intr_tag, &hardkernel_tag, "intr-ac-resource"); + // struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&main_intr_tag); if (cpu_id == 0) { /* init softkernel */ if (!softkernel_init(&hardkernel_tag, &softkernel_tag)) { @@ -66,18 +159,30 @@ int main(void) show_xizi_bar(); int cpu_count = NR_CPU; + scu_enable(); + configure_cpu(cpu_id); + for (int i = 1; i < cpu_count; i++) { + // start secondary cpus + cpu_start_secondary(i, NULL, 0); + } + + /* start first task */ + char* init_task_param[2] = { "/app/init", 0 }; + spawn_embedded_task((char*)_binary_init_start, "init", init_task_param); + char* fs_server_task_param[2] = { "/app/fs_server", 0 }; + spawn_embedded_task((char*)_binary_default_fs_start, "memfs", fs_server_task_param); + + init = true; } - /* start first task */ - char* init_task_param[2] = { "/app/init", 0 }; - spawn_embedded_task((char*)_binary_init_start, "init", init_task_param); - char* fs_server_task_param[2] = { "/app/fs_server", 0 }; - spawn_embedded_task((char*)_binary_default_fs_start, "memfs", fs_server_task_param); + while (!init) + ; /* start scheduler */ struct SchedulerRightGroup scheduler_rights; assert(AchieveResourceTag(&scheduler_rights.mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); + // while (true) { } xizi_task_manager.task_scheduler(scheduler_rights); // never reached diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c index 0ad42a9e3..ab27b1317 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c @@ -293,6 +293,12 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv // dev mem _map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SZ, dev_attr); + // _p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr)); + _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag); +} + +void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag) +{ // _p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr)); _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c index b3453dd2c..9f8035a44 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c @@ -49,6 +49,9 @@ bool clock_intr_handler_init(struct TraceTag* p_clock_driver_tag) uint64_t global_tick = 0; int xizi_clock_handler(int irq, void* tf, void* arg) { + // spinlock_lock(&whole_kernel_lock); + // DEBUG_PRINTF("CPU %d\n", cpu_get_current()); + // spinlock_unlock(&whole_kernel_lock); /* handle clock interrupt using driver */ if (p_clock_driver->is_timer_expired()) { p_clock_driver->clear_clock_intr(); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index 445c64add..bb030490b 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -77,7 +77,9 @@ void intr_irq_dispatch(struct trapframe* tf) // distribute irq irq_handler_t isr = p_intr_driver->sw_irqtbl[irq].handler; if (isr) { + // spinlock_lock(&whole_kernel_lock); isr(irq, tf, NULL); + // spinlock_unlock(&whole_kernel_lock); } else { default_interrupt_routine(); } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index ddf3cccd8..954f42b14 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -48,6 +48,11 @@ bool swi_distributer_init(struct SwiDispatcherRightGroup* _right_group) extern void context_switch(struct context**, struct context*); void software_irq_dispatch(struct trapframe* tf) { + bool is_my_lock = false; + if (whole_kernel_lock.owner_cpu != cur_cpuid()) { + spinlock_lock(&whole_kernel_lock); + is_my_lock = true; + } assert(p_intr_driver != NULL); p_intr_driver->cpu_irq_disable(); @@ -59,6 +64,7 @@ void software_irq_dispatch(struct trapframe* tf) if (cur_task && cur_task->state != DEAD) { cur_task->main_thread.trapframe = tf; // call syscall + int ret = arch_syscall(cur_task->main_thread.trapframe, &syscall_num); if (syscall_num != SYSCALL_EXEC) { @@ -75,5 +81,9 @@ void software_irq_dispatch(struct trapframe* tf) if (syscall_num == SYSCALL_EXIT) { ERROR("Exit reaches"); } + + if (is_my_lock) { + spinlock_unlock(&whole_kernel_lock); + } p_intr_driver->cpu_irq_enable(); } \ No newline at end of file From 3dc6d58bdb806595c83a90b3cc1773c7c90afa48 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Thu, 14 Mar 2024 14:28:11 +0800 Subject: [PATCH 03/24] Support whole kernel lock. TODO: fix spawn. --- .../hardkernel/arch/arm/armv7-a/cortex-a9/core.h | 6 +++--- .../nxp_imx6q_sabrelite.lds | 4 ++-- Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c | 1 - .../hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c | 6 +++++- Ubiquitous/XiZi_AIoT/services/app/shell_port.c | 3 ++- Ubiquitous/XiZi_AIoT/softkernel/load_apps.S | 2 +- Ubiquitous/XiZi_AIoT/softkernel/main.c | 12 ++++++------ Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c | 4 ++-- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 13 ++++++++++++- .../XiZi_AIoT/softkernel/trap/default_irq_handler.c | 7 +++++-- .../softkernel/trap/software_irq_handler.c | 13 +++++-------- 11 files changed, 43 insertions(+), 28 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index e6e96ea7e..c877945ce 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 2 +#define NR_CPU 4 __attribute__((always_inline)) static inline uint32_t user_mode() { @@ -107,11 +107,11 @@ struct context { /// @brief init task context, set return address to trap return /// @param -extern void trap_return(void); +extern void task_prepare_enter(); __attribute__((__always_inline__)) static inline void arch_init_context(struct context* ctx) { memset(ctx, 0, sizeof(*ctx)); - ctx->lr = (uint32_t)(trap_return); + ctx->lr = (uint32_t)(task_prepare_enter + 4); } struct trapframe { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/nxp_imx6q_sabrelite.lds b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/nxp_imx6q_sabrelite.lds index 2e39b0450..7a23ca569 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/nxp_imx6q_sabrelite.lds +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/nxp_imx6q_sabrelite.lds @@ -81,7 +81,7 @@ MEMORY { ocram (rwx) : ORIGIN = 0x00900000, LENGTH = 256K ddr3 (rwx) : ORIGIN = 0x10000000, LENGTH = 1024M - virt_ddr3 (WRX) : ORIGIN = 0x90010000, LENGTH = 1024M + virt_ddr3 (WRX) : ORIGIN = 0x90011000, LENGTH = 1024M } SECTIONS @@ -155,7 +155,7 @@ SECTIONS } > ddr3 /* Other Kernel code is placed over 0x80000000 + 128KB. */ - .text : AT(0x10010000) { + .text : AT(0x10011000) { *(.vectors) . = ALIGN(0x1000); *(.text .text.* .gnu.linkonce.t.*) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c index b148dd4c3..06e6efc53 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c @@ -131,7 +131,6 @@ static bool xizi_gpt_init() struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&intr_driver_tag); p_intr_driver->bind_irq_handler(p_clock_driver->get_clock_int(), xizi_clock_handler); p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), 0, 0); - return true; } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c index 7468540e8..00f484725 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/bootmmu.c @@ -89,12 +89,16 @@ static void load_boot_pgdir() } extern void main(void); +static bool _bss_inited = false; void bootmain() { build_boot_pgdir(); load_boot_pgdir(); __asm__ __volatile__("add sp, sp, %0" ::"r"(KERN_MEM_BASE - PHY_MEM_BASE)); - // memset(&kernel_data_begin, 0x00, (uint32_t)kernel_data_end - (uint32_t)kernel_data_begin); + if (!_bss_inited) { + memset(&kernel_data_begin, 0x00, (uint32_t)kernel_data_end - (uint32_t)kernel_data_begin); + _bss_inited = true; + } main(); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/app/shell_port.c b/Ubiquitous/XiZi_AIoT/services/app/shell_port.c index 52284c9f4..cb1459168 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/shell_port.c +++ b/Ubiquitous/XiZi_AIoT/services/app/shell_port.c @@ -50,7 +50,8 @@ int main(void) shellInit(&shell, shellBuffer, 512); - connect_session(&session_fs, "MemFS", 8092); + while (connect_session(&session_fs, "MemFS", 8092) < 0) + ; if (!session_fs.buf) { printf("session connect faield\n"); return -1; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S b/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S index 71d5278bd..597d60af0 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S +++ b/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S @@ -35,7 +35,7 @@ user_apps: .section .rawdata_init .globl initapp initapp: - .incbin "../services/app/bin/init" + .incbin "../services/app/bin/shell" .section .rawdata_memfs .globl memfs diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index c8f143785..0d4fb4c76 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -94,21 +94,18 @@ void cpu_start_secondary(uint8_t coreNumber, cpu_entry_point_t entryPoint, void* switch (coreNumber) { case 1: HW_SRC_GPR3_WR((uint32_t)&_boot_start); - // HW_SRC_GPR4_WR((uint32_t)common_cpu_entry); HW_SRC_SCR.B.CORE1_ENABLE = 1; break; case 2: HW_SRC_GPR5_WR((uint32_t)&_boot_start); - // HW_SRC_GPR6_WR((uint32_t)common_cpu_entry); HW_SRC_SCR.B.CORE2_ENABLE = 1; break; case 3: HW_SRC_GPR7_WR((uint32_t)&_boot_start); - // HW_SRC_GPR8_WR((uint32_t)common_cpu_entry); HW_SRC_SCR.B.CORE3_ENABLE = 1; break; @@ -148,9 +145,11 @@ int main(void) DEBUG_PRINTF("CPU %d started done.\n", cur_cpuid()); } - // struct TraceTag main_intr_tag; - // AchieveResourceTag(&main_intr_tag, &hardkernel_tag, "intr-ac-resource"); - // struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&main_intr_tag); + struct TraceTag main_intr_tag; + AchieveResourceTag(&main_intr_tag, &hardkernel_tag, "intr-ac-resource"); + struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&main_intr_tag); + p_intr_driver->cpu_irq_disable(); + if (cpu_id == 0) { /* init softkernel */ if (!softkernel_init(&hardkernel_tag, &softkernel_tag)) { @@ -174,6 +173,7 @@ int main(void) init = true; } + // p_intr_driver->cpu_irq_disable(); while (!init) ; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c index ab27b1317..eac957801 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c @@ -293,8 +293,8 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv // dev mem _map_pages((uintptr_t*)kern_pgdir.pd_addr, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, DEV_MEM_SZ, dev_attr); - // _p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr)); - _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag); + _p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr)); + // _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag); } void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag) diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index b90cc944e..86c84cc40 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -112,6 +112,13 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task) } /* alloc a new task with init */ +extern void trap_return(void); +void task_prepare_enter() +{ + spinlock_unlock(&whole_kernel_lock); + trap_return(); +} + static struct TaskMicroDescriptor* _new_task_cb() { // alloc task space @@ -170,10 +177,11 @@ extern void context_switch(struct context**, struct context*); static void _scheduler(struct SchedulerRightGroup right_group) { struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); - struct TaskMicroDescriptor* next_task; + spinlock_lock(&whole_kernel_lock); while (1) { + spinlock_unlock(&whole_kernel_lock); spinlock_lock(&xizi_task_manager.lock); next_task = NULL; /* find next runnable task */ @@ -192,12 +200,15 @@ static void _scheduler(struct SchedulerRightGroup right_group) if (UNLIKELY(next_task == NULL)) { continue; } + + spinlock_lock(&whole_kernel_lock); assert(next_task->state == RUNNING); // p_mmu_driver->LoadPgdirCrit((uintptr_t)V2P(next_task->pgdir.pd_addr), &right_group.intr_driver_tag); p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr)); struct CPU* cpu = cur_cpu(); cpu->task = next_task; + // DEBUG_PRINTF("CPU %d switch to task %s\n", cur_cpuid(), next_task->name); context_switch(&cpu->scheduler, next_task->main_thread.context); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index bb030490b..af1b8f640 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -59,11 +59,14 @@ void intr_irq_dispatch(struct trapframe* tf) assert(p_intr_driver != NULL); p_intr_driver->cpu_irq_disable(); + // enter irq uintptr_t int_info = 0; if ((int_info = p_intr_driver->hw_before_irq()) == 0) { return; } + spinlock_lock(&whole_kernel_lock); + // DEBUG("CPU %d in kernel %s %d\n", cur_cpuid(), __func__, __LINE__); struct TaskMicroDescriptor* current_task = cur_cpu()->task; if (LIKELY(current_task != NULL)) { @@ -77,9 +80,7 @@ void intr_irq_dispatch(struct trapframe* tf) // distribute irq irq_handler_t isr = p_intr_driver->sw_irqtbl[irq].handler; if (isr) { - // spinlock_lock(&whole_kernel_lock); isr(irq, tf, NULL); - // spinlock_unlock(&whole_kernel_lock); } else { default_interrupt_routine(); } @@ -93,5 +94,7 @@ void intr_irq_dispatch(struct trapframe* tf) } assert(current_task == cur_cpu()->task); + // DEBUG("CPU %d out kernel %s %d\n", cur_cpuid(), __func__, __LINE__); + spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index 954f42b14..853ff4524 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -48,14 +48,12 @@ bool swi_distributer_init(struct SwiDispatcherRightGroup* _right_group) extern void context_switch(struct context**, struct context*); void software_irq_dispatch(struct trapframe* tf) { - bool is_my_lock = false; - if (whole_kernel_lock.owner_cpu != cur_cpuid()) { - spinlock_lock(&whole_kernel_lock); - is_my_lock = true; - } + assert(p_intr_driver != NULL); p_intr_driver->cpu_irq_disable(); + spinlock_lock(&whole_kernel_lock); + // DEBUG("CPU %d in kernel %s %d\n", cur_cpuid(), __func__, __LINE__); // get current task struct TaskMicroDescriptor* cur_task = cur_cpu()->task; /// @todo: Handle dead task @@ -82,8 +80,7 @@ void software_irq_dispatch(struct trapframe* tf) ERROR("Exit reaches"); } - if (is_my_lock) { - spinlock_unlock(&whole_kernel_lock); - } + // DEBUG("CPU %d out kernel %s %d\n", cur_cpuid(), __func__, __LINE__); + spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } \ No newline at end of file From 892613a0d59bd69b8e47aa05aca8716d8ab6c830 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Fri, 15 Mar 2024 10:36:29 +0800 Subject: [PATCH 04/24] close cache. --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../hardkernel/cache/cache_common_ope.c | 2 + .../XiZi_AIoT/hardkernel/hardkernel_init.c | 7 +- .../XiZi_AIoT/kernel_actracer/actracer.c | 8 -- Ubiquitous/XiZi_AIoT/softkernel/main.c | 80 ++++++++----------- .../XiZi_AIoT/softkernel/memory/pagetable.c | 4 +- .../softkernel/trap/default_irq_handler.c | 9 ++- .../softkernel/trap/software_irq_handler.c | 9 ++- 8 files changed, 52 insertions(+), 69 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index c877945ce..129f07103 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 4 +#define NR_CPU 1 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c index 6d05e236a..4d5e33d33 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c @@ -233,6 +233,7 @@ struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag) { /* init icache */ icache_done.enable(); + // icache_done.disable(); return &icache_done; } @@ -240,5 +241,6 @@ struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag) { /* init dcache */ dcache_done.enable(); + // dcache_done.disable(); return &dcache_done; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c index 06e6efc53..ebad67c39 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c @@ -214,9 +214,12 @@ bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag) // secondary cpu init hardwares // intr p_intr_driver->sys_irq_init(cpu_id); + p_intr_driver->cpu_irq_disable(); // cache - p_icache_driver->enable(); - p_dcache_driver->enable(); + // p_icache_driver->enable(); + // p_dcache_driver->enable(); + p_icache_driver->disable(); + p_dcache_driver->disable(); // clock p_clock_driver->sys_clock_init(); p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0); diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c index 205209a85..1b009462d 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c @@ -496,31 +496,26 @@ void tracer_find_tag(struct TraceTag* target, struct TraceTag* const source, cha bool AchieveResourceTag(struct TraceTag* target, struct TraceTag* owner, char* name) { - spinlock_lock(&ac_tracer_lock); tracer_find_tag(target, owner, name); if (target->meta == NULL) { return false; } - spinlock_unlock(&ac_tracer_lock); return true; } void* AchieveResource(struct TraceTag* target) { - spinlock_lock(&ac_tracer_lock); if (target->type == TRACER_OWNER) { return NULL; } void* p_resource = NULL; tracer_read_trace(target, (char*)&p_resource, 0, sizeof(void*)); assert(p_resource != NULL); - spinlock_unlock(&ac_tracer_lock); return p_resource; } bool CreateResourceTag(struct TraceTag* new_tag, struct TraceTag* owner, char* name, tracemeta_ac_type type, void* p_resource) { - // spinlock_lock(&ac_tracer_lock); new_tag->type = type; if (type == TRACER_OWNER) { return tracer_create_trace(new_tag, owner, name, type); @@ -535,13 +530,10 @@ bool CreateResourceTag(struct TraceTag* new_tag, struct TraceTag* owner, char* n return false; } bool ret = tracer_write_trace(new_tag, (char*)&p_resource, 0, sizeof(void*)) == sizeof(void*); - // spinlock_unlock(&ac_tracer_lock); return ret; } bool DeleteResource(struct TraceTag* target, struct TraceTag* owner) { - spinlock_lock(&ac_tracer_lock); return tracer_delete_trace(target, owner); - spinlock_unlock(&ac_tracer_lock); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 0d4fb4c76..6766c792c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -37,7 +37,10 @@ Modification: #include "assert.h" #include "task.h" -#include "trap_common.h" +#include "cache_common_ope.h" + +extern uint32_t _binary_init_start[], _binary_default_fs_start[]; +static struct TraceTag hardkernel_tag, softkernel_tag; void configure_cpu(uint32_t cpu) { @@ -55,6 +58,18 @@ void configure_cpu(uint32_t cpu) // arm_icache_enable(); // arm_icache_invalidate(); + struct TraceTag main_icache_tag, main_dcache_tag; + AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); + AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); + struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); + struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); + // p_dcache_driver->enable(); + // p_dcache_driver->invalidateall(); + // p_icache_driver->enable(); + // p_icache_driver->invalidateall(); + p_dcache_driver->disable(); + p_icache_driver->disable(); + // Invalidate SCU copy of TAG RAMs scu_secure_invalidate(cpu, all_ways); @@ -63,59 +78,31 @@ void configure_cpu(uint32_t cpu) scu_enable_maintenance_broadcast(); } -typedef void (*cpu_entry_point_t)(void* arg); -typedef struct _core_startup_info { - cpu_entry_point_t entry; //!< Function to call after starting a core. - void* arg; //!< Argument to pass core entry point. -} core_startup_info_t; -static core_startup_info_t s_core_info[NR_CPU] = { { 0 } }; - -static void common_cpu_entry(void) -{ - uint32_t myCoreNumber = cpu_get_current(); - core_startup_info_t* info = &s_core_info[myCoreNumber]; - - // Call the requested entry point for this CPU number. - if (info->entry) { - info->entry(info->arg); - } -} - extern void _boot_start(); -void cpu_start_secondary(uint8_t coreNumber, cpu_entry_point_t entryPoint, void* arg) +void cpu_start_secondary(uint8_t coreNumber) { - // Save entry point and arg. - s_core_info[coreNumber].entry = entryPoint; - s_core_info[coreNumber].arg = arg; - // Prepare pointers for ROM code. The entry point is always _start, which does some // basic preparatory work and then calls the common_cpu_entry function, which itself // calls the entry point saved in s_core_info. switch (coreNumber) { case 1: HW_SRC_GPR3_WR((uint32_t)&_boot_start); - HW_SRC_SCR.B.CORE1_ENABLE = 1; break; case 2: HW_SRC_GPR5_WR((uint32_t)&_boot_start); - HW_SRC_SCR.B.CORE2_ENABLE = 1; break; case 3: HW_SRC_GPR7_WR((uint32_t)&_boot_start); - HW_SRC_SCR.B.CORE3_ENABLE = 1; break; } } -extern uint32_t _binary_init_start[], _binary_default_fs_start[]; -static struct TraceTag hardkernel_tag, softkernel_tag; - -static bool init = false; +static int core_init_done = 0; int main(void) { /* init tracer */ @@ -135,21 +122,19 @@ int main(void) return -1; } + // scu_enable(); + // configure_cpu(cpu_id); + spinlock_init(&whole_kernel_lock, "wklock"); } else { configure_cpu(cpu_id); - DEBUG_PRINTF("CPU %d started init: %d(at %x).\n", cur_cpuid(), init, &init); spinlock_lock(&whole_kernel_lock); secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag); + DEBUG_PRINTF("CPU %d init done.\n", cur_cpuid()); spinlock_unlock(&whole_kernel_lock); - DEBUG_PRINTF("CPU %d started done.\n", cur_cpuid()); } - struct TraceTag main_intr_tag; - AchieveResourceTag(&main_intr_tag, &hardkernel_tag, "intr-ac-resource"); - struct XiziTrapDriver* p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&main_intr_tag); - p_intr_driver->cpu_irq_disable(); - + spinlock_lock(&whole_kernel_lock); if (cpu_id == 0) { /* init softkernel */ if (!softkernel_init(&hardkernel_tag, &softkernel_tag)) { @@ -158,11 +143,10 @@ int main(void) show_xizi_bar(); int cpu_count = NR_CPU; - scu_enable(); - configure_cpu(cpu_id); + ; for (int i = 1; i < cpu_count; i++) { // start secondary cpus - cpu_start_secondary(i, NULL, 0); + cpu_start_secondary(i); } /* start first task */ @@ -170,19 +154,19 @@ int main(void) spawn_embedded_task((char*)_binary_init_start, "init", init_task_param); char* fs_server_task_param[2] = { "/app/fs_server", 0 }; spawn_embedded_task((char*)_binary_default_fs_start, "memfs", fs_server_task_param); - - init = true; } - // p_intr_driver->cpu_irq_disable(); - - while (!init) - ; /* start scheduler */ struct SchedulerRightGroup scheduler_rights; assert(AchieveResourceTag(&scheduler_rights.mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); - // while (true) { } + + core_init_done |= (1 << cpu_id); + DEBUG("core_init_done: %x\n", core_init_done); + spinlock_unlock(&whole_kernel_lock); + + while (core_init_done != (1 << NR_CPU) - 1) + ; xizi_task_manager.task_scheduler(scheduler_rights); // never reached diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c index eac957801..a2a054119 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/pagetable.c @@ -299,6 +299,6 @@ void load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driv void secondary_cpu_load_kern_pgdir(struct TraceTag* mmu_driver_tag, struct TraceTag* intr_driver_tag) { - // _p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr)); - _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag); + _p_pgtbl_mmu_access->LoadPgdir((uintptr_t)V2P(kern_pgdir.pd_addr)); + // _p_pgtbl_mmu_access->LoadPgdirCrit((uintptr_t)V2P(kern_pgdir.pd_addr), intr_driver_tag); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index af1b8f640..b75cd8219 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -65,8 +65,9 @@ void intr_irq_dispatch(struct trapframe* tf) if ((int_info = p_intr_driver->hw_before_irq()) == 0) { return; } - spinlock_lock(&whole_kernel_lock); - // DEBUG("CPU %d in kernel %s %d\n", cur_cpuid(), __func__, __LINE__); + // spinlock_lock(&whole_kernel_lock); + DSB(); + // DEBUG("CPU %d in\n", cur_cpuid()); struct TaskMicroDescriptor* current_task = cur_cpu()->task; if (LIKELY(current_task != NULL)) { @@ -94,7 +95,7 @@ void intr_irq_dispatch(struct trapframe* tf) } assert(current_task == cur_cpu()->task); - // DEBUG("CPU %d out kernel %s %d\n", cur_cpuid(), __func__, __LINE__); - spinlock_unlock(&whole_kernel_lock); + // DEBUG("CPU %d out\n", cur_cpuid()); + // spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index 853ff4524..8b1535168 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -52,8 +52,9 @@ void software_irq_dispatch(struct trapframe* tf) assert(p_intr_driver != NULL); p_intr_driver->cpu_irq_disable(); - spinlock_lock(&whole_kernel_lock); - // DEBUG("CPU %d in kernel %s %d\n", cur_cpuid(), __func__, __LINE__); + // spinlock_lock(&whole_kernel_lock); + DSB(); + // DEBUG("CPU %d in\n", cur_cpuid()); // get current task struct TaskMicroDescriptor* cur_task = cur_cpu()->task; /// @todo: Handle dead task @@ -80,7 +81,7 @@ void software_irq_dispatch(struct trapframe* tf) ERROR("Exit reaches"); } - // DEBUG("CPU %d out kernel %s %d\n", cur_cpuid(), __func__, __LINE__); - spinlock_unlock(&whole_kernel_lock); + // DEBUG("CPU %d out\n", cur_cpuid()); + // spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } \ No newline at end of file From d987bf03571380f3248813a4d77043ec7df17ff3 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Fri, 15 Mar 2024 16:01:30 +0800 Subject: [PATCH 05/24] Support smp. TODO: delete all inner kernel locks. --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../hardkernel/cache/cache_common_ope.c | 8 +- .../XiZi_AIoT/kernel_actracer/actracer.c | 2 - Ubiquitous/XiZi_AIoT/services/app/Makefile | 14 +- Ubiquitous/XiZi_AIoT/services/app/init.c | 2 +- .../XiZi_AIoT/services/app/simple_client.c | 4 +- .../services/boards/imx6q-sabrelite/Makefile | 2 +- .../boards/imx6q-sabrelite/usyscall.c | 19 +- .../boards/imx6q-sabrelite/usyscall.h | 9 +- .../services/boards/zynq7000-zc702/Makefile | 1 + .../services/boards/zynq7000-zc702/usyscall.c | 19 +- .../services/boards/zynq7000-zc702/usyscall.h | 9 +- .../XiZi_AIoT/services/fs/fs_server/Makefile | 1 + .../services/fs/fs_server/fs_server.c | 25 +- .../XiZi_AIoT/services/fs/libfs/Makefile | 1 + .../services/fs/libfs/libfs_to_client.c | 6 + .../services/fs/libfs/libfs_to_client.h | 3 +- Ubiquitous/XiZi_AIoT/services/lib/Makefile | 2 +- .../XiZi_AIoT/services/lib/ipc/Makefile | 4 +- .../XiZi_AIoT/services/lib/memory/Makefile | 11 +- .../XiZi_AIoT/services/lib/memory/libmem.c | 369 ++++++++++++++++++ .../lib/memory/{libmalloc.h => libmem.h} | 4 +- .../services/shell/letter-shell/Makefile | 5 +- .../services/shell/letter-shell/shell.c | 2 +- .../XiZi_AIoT/softkernel/include/syscall.h | 10 +- Ubiquitous/XiZi_AIoT/softkernel/load_apps.S | 2 +- Ubiquitous/XiZi_AIoT/softkernel/main.c | 31 +- .../XiZi_AIoT/softkernel/syscall/sys_exec.c | 32 +- .../XiZi_AIoT/softkernel/syscall/sys_spawn.c | 10 +- .../XiZi_AIoT/softkernel/syscall/sys_state.c | 41 +- .../XiZi_AIoT/softkernel/syscall/syscall.c | 4 +- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 17 +- .../softkernel/trap/default_irq_handler.c | 4 +- .../softkernel/trap/software_irq_handler.c | 6 +- 34 files changed, 531 insertions(+), 150 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.c rename Ubiquitous/XiZi_AIoT/services/lib/memory/{libmalloc.h => libmem.h} (95%) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index 129f07103..c877945ce 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 1 +#define NR_CPU 4 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c index 4d5e33d33..6f5978f2c 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c @@ -232,15 +232,15 @@ static struct DCacheDone dcache_done = { struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag) { /* init icache */ - icache_done.enable(); - // icache_done.disable(); + // icache_done.enable(); + icache_done.disable(); return &icache_done; } struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag) { /* init dcache */ - dcache_done.enable(); - // dcache_done.disable(); + // dcache_done.enable(); + dcache_done.disable(); return &dcache_done; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c index 1b009462d..8edd6f77d 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c @@ -447,11 +447,9 @@ bool tracer_delete_trace(struct TraceTag* target, struct TraceTag* owner) return true; } -static struct spinlock ac_tracer_lock; void tracer_init(void) { /* init sys_tracer, the manager */ - spinlock_init(&ac_tracer_lock, "tracerlock"); spinlock_init(&sys_tracer.mem_chunk_bitmap_lock, "tracer_mem_chunk_bitmap"); spinlock_init(&sys_tracer.trace_meta_bitmap_lock, "tracer_meta_bitmap"); memset(sys_tracer.mem_chunks_bit_map, 0, sizeof(sys_tracer.mem_chunk_bitmap_lock)); diff --git a/Ubiquitous/XiZi_AIoT/services/app/Makefile b/Ubiquitous/XiZi_AIoT/services/app/Makefile index fd0fb506b..288a23c1b 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/app/Makefile @@ -32,31 +32,31 @@ all: init test_fs simple_client simple_server shell fs_server test_priority read bin: @mkdir -p bin -shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o +shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm -init: init.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o +init: init.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm -test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o +test_fs: test_fs.o libfs_to_client.o libipc.o session.o libserial.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm -simple_client: simple_client.o libserial.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o +simple_client: simple_client.o libserial.o libipc.o session.o simple_service.o libfs_to_client.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm -simple_server: simple_server.o libserial.o libipc.o session.o simple_service.o usyscall.o +simple_server: simple_server.o libserial.o libipc.o session.o simple_service.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm -fs_server: fs_server.o libfs_to_client.o fs.o libserial.o libipc.o session.o block_io.o usyscall.o +fs_server: fs_server.o libfs_to_client.o fs.o libserial.o libipc.o session.o block_io.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm -test_priority: test_priority.o libserial.o usyscall.o +test_priority: test_priority.o libserial.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm diff --git a/Ubiquitous/XiZi_AIoT/services/app/init.c b/Ubiquitous/XiZi_AIoT/services/app/init.c index 600770a26..62a62c401 100755 --- a/Ubiquitous/XiZi_AIoT/services/app/init.c +++ b/Ubiquitous/XiZi_AIoT/services/app/init.c @@ -32,7 +32,7 @@ int main(int argc, char* argv[]) exit(); } - if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) { + if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) { printf("Syscall Spawn shell failed\n"); } diff --git a/Ubiquitous/XiZi_AIoT/services/app/simple_client.c b/Ubiquitous/XiZi_AIoT/services/app/simple_client.c index d3f335146..232916067 100755 --- a/Ubiquitous/XiZi_AIoT/services/app/simple_client.c +++ b/Ubiquitous/XiZi_AIoT/services/app/simple_client.c @@ -113,10 +113,10 @@ int main(int argc, char** argv) itoa(id - 1, id_buf, 10); char* shell_task_param[3] = { "/simple_client", id_buf, 0 }; if ((fd = open(&session, shell_task_param[0])) >= 0) { - if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) { + if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) { printf("Syscall Spawn simple_client failed\n"); } - if (spawn(&session, fd, read, shell_task_param[0], shell_task_param) < 0) { + if (spawn(&session, fd, read, fsize, shell_task_param[0], shell_task_param) < 0) { printf("Syscall Spawn simple_client failed\n"); } close(&session, fd); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile index 71ddf042c..1a44e7a85 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile @@ -13,8 +13,8 @@ cflags = -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=so c_useropts = -O0 INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ - -I$(KERNEL_ROOT)/services/fs/fs_server/include \ -I$(KERNEL_ROOT)/services/lib/ipc \ + -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c index c03893a43..d2f03b56d 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c @@ -10,6 +10,7 @@ * See the Mulan PSL v2 for more details. */ #include "usyscall.h" +#include "libmem.h" static int syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4) @@ -33,14 +34,18 @@ syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4) return ret; } -int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv) +int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv) { - struct KernReadTool read_tool = { - .session = session, - .fd = fd, - .ipc_read = ipc_read, - }; - return syscall(SYSCALL_SPAWN, (intptr_t)&read_tool, (intptr_t)name, (intptr_t)argv, 0); + int file_size = ipc_fsize(session, fd); + void* img = malloc(file_size); + int read_len = 0, cur_read_len = 0; + while (read_len < file_size) { + cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096; + read_len += ipc_read(session, fd, img + read_len, read_len, cur_read_len); + } + int ret = syscall(SYSCALL_SPAWN, (intptr_t)img, (intptr_t)name, (intptr_t)argv, 0); + free(img); + return ret; } int exit() diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h index 65ab3cd6f..40bb944ca 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h @@ -51,15 +51,10 @@ typedef union { } sys_state_info; typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); +typedef int (*ipc_fsize_fn)(struct Session* session, int fd); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); -struct KernReadTool { - struct Session* session; - int fd; - ipc_read_fn ipc_read; -}; - -int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv); +int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv); int exit(); int yield(); int register_server(char* name); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/Makefile b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/Makefile index f312ba643..aa1013cfa 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/Makefile @@ -18,6 +18,7 @@ c_useropts = -O0 INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ -I$(KERNEL_ROOT)/services/fs/fs_server/include \ -I$(KERNEL_ROOT)/services/lib/ipc \ + -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c index c03893a43..d2f03b56d 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c @@ -10,6 +10,7 @@ * See the Mulan PSL v2 for more details. */ #include "usyscall.h" +#include "libmem.h" static int syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4) @@ -33,14 +34,18 @@ syscall(int sys_num, intptr_t a1, intptr_t a2, intptr_t a3, intptr_t a4) return ret; } -int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv) +int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv) { - struct KernReadTool read_tool = { - .session = session, - .fd = fd, - .ipc_read = ipc_read, - }; - return syscall(SYSCALL_SPAWN, (intptr_t)&read_tool, (intptr_t)name, (intptr_t)argv, 0); + int file_size = ipc_fsize(session, fd); + void* img = malloc(file_size); + int read_len = 0, cur_read_len = 0; + while (read_len < file_size) { + cur_read_len = file_size - read_len < 4096 ? file_size - read_len : 4096; + read_len += ipc_read(session, fd, img + read_len, read_len, cur_read_len); + } + int ret = syscall(SYSCALL_SPAWN, (intptr_t)img, (intptr_t)name, (intptr_t)argv, 0); + free(img); + return ret; } int exit() diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h index 65ab3cd6f..40bb944ca 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h @@ -51,15 +51,10 @@ typedef union { } sys_state_info; typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); +typedef int (*ipc_fsize_fn)(struct Session* session, int fd); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); -struct KernReadTool { - struct Session* session; - int fd; - ipc_read_fn ipc_read; -}; - -int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv); +int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv); int exit(); int yield(); int register_server(char* name); diff --git a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/Makefile b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/Makefile index 6e254bcee..e93df4cb0 100644 --- a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/Makefile @@ -18,6 +18,7 @@ c_useropts = -O0 INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ -I$(KERNEL_ROOT)/services/fs/fs_server/include \ -I$(KERNEL_ROOT)/services/lib/ipc \ + -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app diff --git a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c index 98260ac43..ac7eb0cf5 100644 --- a/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c +++ b/Ubiquitous/XiZi_AIoT/services/fs/fs_server/fs_server.c @@ -282,7 +282,7 @@ int IPC_DO_SERVE_FUNC(Ipc_read)(int* fd, char* dst, int* offset, int* len) int cur_read_len = InodeRead(ip, dst, *offset, *len); - return *len; + return cur_read_len; } int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len) @@ -305,18 +305,36 @@ int IPC_DO_SERVE_FUNC(Ipc_write)(int* fd, char* src, int* offset, int* len) return cur_write_len; } +int IPC_DO_SERVE_FUNC(Ipc_fsize)(int* fd) +{ + struct FileDescriptor* fdp = GetFileDescriptor(*fd); + if (!fdp) { + printf("read: fd invalid\n"); + return -1; + } + + struct Inode* ip = fdp->data; + if (ip->type != FS_FILE) { + printf("read: %s Is not a file\n", fdp->path); + return -1; + } + + return ip->size; +} + IPC_SERVER_INTERFACE(Ipc_ls, 1); IPC_SERVER_INTERFACE(Ipc_cd, 1); IPC_SERVER_INTERFACE(Ipc_mkdir, 1); IPC_SERVER_INTERFACE(Ipc_delete, 1); IPC_SERVER_INTERFACE(Ipc_cat, 1); +IPC_SERVER_INTERFACE(Ipc_fsize, 1); IPC_SERVER_INTERFACE(Ipc_open, 1); IPC_SERVER_INTERFACE(Ipc_close, 1); IPC_SERVER_INTERFACE(Ipc_read, 4); IPC_SERVER_INTERFACE(Ipc_write, 4); -IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 9, +IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 10, Ipc_ls, Ipc_cd, Ipc_mkdir, @@ -325,7 +343,8 @@ IPC_SERVER_REGISTER_INTERFACES(IpcFsServer, 9, Ipc_open, Ipc_close, Ipc_read, - Ipc_write); + Ipc_write, + Ipc_fsize); int main(int argc, char* argv[]) { diff --git a/Ubiquitous/XiZi_AIoT/services/fs/libfs/Makefile b/Ubiquitous/XiZi_AIoT/services/fs/libfs/Makefile index ce34b4855..336120483 100644 --- a/Ubiquitous/XiZi_AIoT/services/fs/libfs/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/fs/libfs/Makefile @@ -17,6 +17,7 @@ c_useropts = -O0 INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ -I$(KERNEL_ROOT)/services/lib/ipc \ + -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app diff --git a/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.c b/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.c index ceeb077a8..b2109b944 100644 --- a/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.c +++ b/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.c @@ -63,4 +63,10 @@ IPC_INTERFACE(Ipc_write, 4, fd, src, offset, len, sizeof(int), *(int*)len, sizeo int write(struct Session* session, int fd, char* src, int offset, int len) { return IPC_CALL(Ipc_write)(session, &fd, src, &offset, &len); +} + +IPC_INTERFACE(Ipc_fsize, 1, fd, sizeof(int)); +int fsize(struct Session* session, int fd) +{ + return IPC_CALL(Ipc_fsize)(session, &fd); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.h b/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.h index fd9ab3e9a..c10a67ebf 100644 --- a/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.h +++ b/Ubiquitous/XiZi_AIoT/services/fs/libfs/libfs_to_client.h @@ -15,13 +15,14 @@ #include "libipc.h" IPC_SERVICES(IpcFsServer, Ipc_ls, Ipc_cd, Ipc_mkdir, Ipc_delete, Ipc_cat, - Ipc_open, Ipc_close, Ipc_read, Ipc_write); + Ipc_open, Ipc_close, Ipc_read, Ipc_write, Ipc_fsize); int ls(struct Session* session, char* path); int cd(struct Session* session, char* path); int mkdir(struct Session* session, char* path); int rm(struct Session* session, char* path); int cat(struct Session* session, char* path); +int fsize(struct Session* session, int fd); int open(struct Session* session, char* path); int close(struct Session* session, int fd); diff --git a/Ubiquitous/XiZi_AIoT/services/lib/Makefile b/Ubiquitous/XiZi_AIoT/services/lib/Makefile index 1d6142afd..c242de34a 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/lib/Makefile @@ -1,4 +1,4 @@ -SRC_DIR := ipc +SRC_DIR := ipc memory include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/Makefile b/Ubiquitous/XiZi_AIoT/services/lib/ipc/Makefile index c9c573cf2..48b6ef330 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/Makefile @@ -15,8 +15,8 @@ objdump = ${toolchain}objdump c_useropts = -O0 -INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \ - -I$(KERNEL_ROOT)/services/lib/ipc \ +INC_DIR = -I$(KERNEL_ROOT)/services/lib/ipc \ + -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app diff --git a/Ubiquitous/XiZi_AIoT/services/lib/memory/Makefile b/Ubiquitous/XiZi_AIoT/services/lib/memory/Makefile index 80cb8d3da..54139e413 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/memory/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/lib/memory/Makefile @@ -12,11 +12,14 @@ user_ldflags = -N -Ttext 0 cflags = -std=c11 -march=armv7-a -mtune=cortex-a9 -nostdlib -nodefaultlibs -mfloat-abi=soft -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -ggdb -Wno-unused -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie c_useropts = -O0 -INC_DIR = -I$(KERNEL_ROOT)/services/app \ - -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ - -I$(KERNEL_ROOT)/services/lib/ipc +INC_DIR = -I$(KERNEL_ROOT)/services/app \ + -I$(KERNEL_ROOT)/services/fs/libfs \ + -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ + -I$(KERNEL_ROOT)/services/lib/memory \ + -I$(KERNEL_ROOT)/services/lib/ipc -all: +all: libmem.o + @mv $^ ../../app %.o: %.c @echo "cc $^" diff --git a/Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.c b/Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.c new file mode 100644 index 000000000..feb746b5f --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.c @@ -0,0 +1,369 @@ +/* + * mm.c - malloc using segregated list + * KAIST + * Tony Kim + * + * In this approach, + * Every block has a header and a footer + * in which header contains reallocation information, size, and allocation info + * and footer contains size and allocation info. + * Free list are tagged to the segregated list. + * Therefore all free block contains pointer to the predecessor and successor. + * The segregated list headers are organized by 2^k size. + * + */ + +#include "libmem.h" +#include "usyscall.h" + +/* single word (4) or double word (8) alignment */ +#define ALIGNMENT 8 +/* rounds up to the nearest multiple of ALIGNMENT */ +#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~0x7) + +// My additional Macros +#define WSIZE 4 // word and header/footer size (bytes) +#define DSIZE 8 // double word size (bytes) +#define INITCHUNKSIZE (1 << 6) +#define CHUNKSIZE (1 << 12) //+(1<<7) + +#define LISTLIMIT 20 + +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +// Pack a size and allocated bit into a word +#define PACK(size, alloc) ((size) | (alloc)) + +// Read and write a word at address p +#define GET(p) (*(unsigned int*)(p)) +#define PUT(p, val) (*(unsigned int*)(p) = (val) | GET_TAG(p)) +#define PUT_NOTAG(p, val) (*(unsigned int*)(p) = (val)) + +// Store predecessor or successor pointer for free blocks +#define SET_PTR(p, ptr) (*(unsigned int*)(p) = (unsigned int)(ptr)) + +// Read the size and allocation bit from address p +#define GET_SIZE(p) (GET(p) & ~0x7) +#define GET_ALLOC(p) (GET(p) & 0x1) +#define GET_TAG(p) (GET(p) & 0x2) +#define SET_RATAG(p) (GET(p) |= 0x2) +#define REMOVE_RATAG(p) (GET(p) &= ~0x2) + +// Address of block's header and footer +#define HDRP(ptr) ((char*)(ptr)-WSIZE) +#define FTRP(ptr) ((char*)(ptr) + GET_SIZE(HDRP(ptr)) - DSIZE) + +// Address of (physically) next and previous blocks +#define NEXT_BLKP(ptr) ((char*)(ptr) + GET_SIZE((char*)(ptr)-WSIZE)) +#define PREV_BLKP(ptr) ((char*)(ptr)-GET_SIZE((char*)(ptr)-DSIZE)) + +// Address of free block's predecessor and successor entries +#define PRED_PTR(ptr) ((char*)(ptr)) +#define SUCC_PTR(ptr) ((char*)(ptr) + WSIZE) + +// Address of free block's predecessor and successor on the segregated list +#define PRED(ptr) (*(char**)(ptr)) +#define SUCC(ptr) (*(char**)(SUCC_PTR(ptr))) + +// End of my additional macros + +// Global var +void* segregated_free_lists[LISTLIMIT]; + +// Functions +static void* extend_heap(size_t size); +static void* coalesce(void* ptr); +static void* place(void* ptr, size_t asize); +static void insert_node(void* ptr, size_t size); +static void delete_node(void* ptr); + +static uintptr_t userland_heap_base; +static uintptr_t userland_heap_top; +static uintptr_t requested_heap_size; + +static void* mem_sbrk(size_t size) +{ + uintptr_t userland_heap_size = userland_heap_top - userland_heap_base; + if (userland_heap_size - requested_heap_size >= size) { + void* ret_ptr = (void*)(userland_heap_base + requested_heap_size); + requested_heap_size += size; + return ret_ptr; + } + + uintptr_t size_needed = size - (userland_heap_size - requested_heap_size); + userland_heap_top = mmap(userland_heap_top, (uintptr_t)NULL, size_needed, false); + + return mem_sbrk(size); +} + +static void* extend_heap(size_t size) +{ + void* ptr; + size_t asize; // Adjusted size + + asize = ALIGN(size); + + if ((ptr = mem_sbrk(asize)) == (void*)-1) + return NULL; + + // Set headers and footer + PUT_NOTAG(HDRP(ptr), PACK(asize, 0)); + PUT_NOTAG(FTRP(ptr), PACK(asize, 0)); + PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(0, 1)); + insert_node(ptr, asize); + + return coalesce(ptr); +} + +static void insert_node(void* ptr, size_t size) +{ + int list = 0; + void* search_ptr = ptr; + void* insert_ptr = NULL; + + // Select segregated list + while ((list < LISTLIMIT - 1) && (size > 1)) { + size >>= 1; + list++; + } + + // Keep size ascending order and search + search_ptr = segregated_free_lists[list]; + while ((search_ptr != NULL) && (size > GET_SIZE(HDRP(search_ptr)))) { + insert_ptr = search_ptr; + search_ptr = PRED(search_ptr); + } + + // Set predecessor and successor + if (search_ptr != NULL) { + if (insert_ptr != NULL) { + SET_PTR(PRED_PTR(ptr), search_ptr); + SET_PTR(SUCC_PTR(search_ptr), ptr); + SET_PTR(SUCC_PTR(ptr), insert_ptr); + SET_PTR(PRED_PTR(insert_ptr), ptr); + } else { + SET_PTR(PRED_PTR(ptr), search_ptr); + SET_PTR(SUCC_PTR(search_ptr), ptr); + SET_PTR(SUCC_PTR(ptr), NULL); + segregated_free_lists[list] = ptr; + } + } else { + if (insert_ptr != NULL) { + SET_PTR(PRED_PTR(ptr), NULL); + SET_PTR(SUCC_PTR(ptr), insert_ptr); + SET_PTR(PRED_PTR(insert_ptr), ptr); + } else { + SET_PTR(PRED_PTR(ptr), NULL); + SET_PTR(SUCC_PTR(ptr), NULL); + segregated_free_lists[list] = ptr; + } + } + + return; +} + +static void delete_node(void* ptr) +{ + int list = 0; + size_t size = GET_SIZE(HDRP(ptr)); + + // Select segregated list + while ((list < LISTLIMIT - 1) && (size > 1)) { + size >>= 1; + list++; + } + + if (PRED(ptr) != NULL) { + if (SUCC(ptr) != NULL) { + SET_PTR(SUCC_PTR(PRED(ptr)), SUCC(ptr)); + SET_PTR(PRED_PTR(SUCC(ptr)), PRED(ptr)); + } else { + SET_PTR(SUCC_PTR(PRED(ptr)), NULL); + segregated_free_lists[list] = PRED(ptr); + } + } else { + if (SUCC(ptr) != NULL) { + SET_PTR(PRED_PTR(SUCC(ptr)), NULL); + } else { + segregated_free_lists[list] = NULL; + } + } + + return; +} + +static void* coalesce(void* ptr) +{ + size_t prev_alloc = GET_ALLOC(HDRP(PREV_BLKP(ptr))); + size_t next_alloc = GET_ALLOC(HDRP(NEXT_BLKP(ptr))); + size_t size = GET_SIZE(HDRP(ptr)); + + // Do not coalesce with previous block if the previous block is tagged with Reallocation tag + if (GET_TAG(HDRP(PREV_BLKP(ptr)))) + prev_alloc = 1; + + if (prev_alloc && next_alloc) { // Case 1 + return ptr; + } else if (prev_alloc && !next_alloc) { // Case 2 + delete_node(ptr); + delete_node(NEXT_BLKP(ptr)); + size += GET_SIZE(HDRP(NEXT_BLKP(ptr))); + PUT(HDRP(ptr), PACK(size, 0)); + PUT(FTRP(ptr), PACK(size, 0)); + } else if (!prev_alloc && next_alloc) { // Case 3 + delete_node(ptr); + delete_node(PREV_BLKP(ptr)); + size += GET_SIZE(HDRP(PREV_BLKP(ptr))); + PUT(FTRP(ptr), PACK(size, 0)); + PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0)); + ptr = PREV_BLKP(ptr); + } else { // Case 4 + delete_node(ptr); + delete_node(PREV_BLKP(ptr)); + delete_node(NEXT_BLKP(ptr)); + size += GET_SIZE(HDRP(PREV_BLKP(ptr))) + GET_SIZE(HDRP(NEXT_BLKP(ptr))); + PUT(HDRP(PREV_BLKP(ptr)), PACK(size, 0)); + PUT(FTRP(NEXT_BLKP(ptr)), PACK(size, 0)); + ptr = PREV_BLKP(ptr); + } + + insert_node(ptr, size); + + return ptr; +} + +static void* place(void* ptr, size_t asize) +{ + size_t ptr_size = GET_SIZE(HDRP(ptr)); + size_t remainder = ptr_size - asize; + + delete_node(ptr); + + if (remainder <= DSIZE * 2) { + // Do not split block + PUT(HDRP(ptr), PACK(ptr_size, 1)); + PUT(FTRP(ptr), PACK(ptr_size, 1)); + } + + else if (asize >= 100) { + // Split block + PUT(HDRP(ptr), PACK(remainder, 0)); + PUT(FTRP(ptr), PACK(remainder, 0)); + PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(asize, 1)); + PUT_NOTAG(FTRP(NEXT_BLKP(ptr)), PACK(asize, 1)); + insert_node(ptr, remainder); + return NEXT_BLKP(ptr); + + } + + else { + // Split block + PUT(HDRP(ptr), PACK(asize, 1)); + PUT(FTRP(ptr), PACK(asize, 1)); + PUT_NOTAG(HDRP(NEXT_BLKP(ptr)), PACK(remainder, 0)); + PUT_NOTAG(FTRP(NEXT_BLKP(ptr)), PACK(remainder, 0)); + insert_node(NEXT_BLKP(ptr), remainder); + } + return ptr; +} + +static bool malloc_inited = false; +int mm_init(void) +{ + // init heap + userland_heap_base = task_heap_base(); + userland_heap_top = userland_heap_base; + requested_heap_size = 0; + + int list; + char* heap_start; // Pointer to beginning of heap + + // Initialize segregated free lists + for (list = 0; list < LISTLIMIT; list++) { + segregated_free_lists[list] = NULL; + } + + // Allocate memory for the initial empty heap + if ((long)(heap_start = mem_sbrk(4 * WSIZE)) == -1) + return -1; + + PUT_NOTAG(heap_start, 0); /* Alignment padding */ + PUT_NOTAG(heap_start + (1 * WSIZE), PACK(DSIZE, 1)); /* Prologue header */ + PUT_NOTAG(heap_start + (2 * WSIZE), PACK(DSIZE, 1)); /* Prologue footer */ + PUT_NOTAG(heap_start + (3 * WSIZE), PACK(0, 1)); /* Epilogue header */ + + if (extend_heap(INITCHUNKSIZE) == NULL) + return -1; + + malloc_inited = true; + return 0; +} + +void* malloc(size_t size) +{ + while (!malloc_inited) { + mm_init(); + } + + size_t asize; /* Adjusted block size */ + size_t extendsize; /* Amount to extend heap if no fit */ + void* ptr = NULL; /* Pointer */ + + // Ignore size 0 cases + if (size == 0) + return NULL; + + // Align block size + if (size <= DSIZE) { + asize = 2 * DSIZE; + } else { + asize = ALIGN(size + DSIZE); + } + + int list = 0; + size_t searchsize = asize; + // Search for free block in segregated list + while (list < LISTLIMIT) { + if ((list == LISTLIMIT - 1) || ((searchsize <= 1) && (segregated_free_lists[list] != NULL))) { + ptr = segregated_free_lists[list]; + // Ignore blocks that are too small or marked with the reallocation bit + while ((ptr != NULL) && ((asize > GET_SIZE(HDRP(ptr))) || (GET_TAG(HDRP(ptr))))) { + ptr = PRED(ptr); + } + if (ptr != NULL) + break; + } + + searchsize >>= 1; + list++; + } + + // if free block is not found, extend the heap + if (ptr == NULL) { + extendsize = MAX(asize, CHUNKSIZE); + + if ((ptr = extend_heap(extendsize)) == NULL) + return NULL; + } + + // Place and divide block + ptr = place(ptr, asize); + + // Return pointer to newly allocated block + return ptr; +} + +void free(void* ptr) +{ + size_t size = GET_SIZE(HDRP(ptr)); + + REMOVE_RATAG(HDRP(NEXT_BLKP(ptr))); + PUT(HDRP(ptr), PACK(size, 0)); + PUT(FTRP(ptr), PACK(size, 0)); + + insert_node(ptr, size); + coalesce(ptr); + + return; +} diff --git a/Ubiquitous/XiZi_AIoT/services/lib/memory/libmalloc.h b/Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.h similarity index 95% rename from Ubiquitous/XiZi_AIoT/services/lib/memory/libmalloc.h rename to Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.h index 07669ae80..7f1b9631d 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/memory/libmalloc.h +++ b/Ubiquitous/XiZi_AIoT/services/lib/memory/libmem.h @@ -10,7 +10,7 @@ * See the Mulan PSL v2 for more details. */ /** - * @file libmalloc.h + * @file libmem.h * @brief support malloc and free in userland * @version 3.0 * @author AIIT XUOS Lab @@ -18,7 +18,7 @@ */ /************************************************* -File name: libmalloc.h +File name: libmem.h Description: support malloc and free in userland Others: History: diff --git a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/Makefile b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/Makefile index ac0b851b3..e2bdb095e 100644 --- a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/Makefile @@ -16,9 +16,10 @@ objdump = ${toolchain}objdump c_useropts = -O0 INC_DIR = -I$(KERNEL_ROOT)/services/app \ + -I$(KERNEL_ROOT)/services/fs/libfs \ + -I$(KERNEL_ROOT)/services/lib/memory \ -I$(KERNEL_ROOT)/services/lib/ipc \ - -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ - -I$(KERNEL_ROOT)/services/fs/libfs + -I$(KERNEL_ROOT)/services/boards/$(BOARD) all: shell_cmd_list.o shell_ext.o shell.o @mv $^ ../../app diff --git a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c index 1fa2dd2d6..31b3d538b 100644 --- a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c +++ b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c @@ -1282,7 +1282,7 @@ void shellExec(Shell* shell) if (fd < 0) { shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); } else { - if (spawn(&session_fs, fd, read, shell->parser.param[0], shell->parser.param) < 0) { + if (spawn(&session_fs, fd, read, fsize, shell->parser.param[0], shell->parser.param) < 0) { shellWriteString(shell, shellText[SHELL_TEXT_CMD_NOT_FOUND]); } close(&session_fs, fd); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h index 7429916c7..e564312cc 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h @@ -74,15 +74,9 @@ typedef union { typedef int (*ipc_read_fn)(struct Session* session, int fd, char* dst, int offset, int len); typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offset, int len); -struct KernReadTool { - struct Session* session; - int fd; - ipc_read_fn ipc_read; -}; - int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); -int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv); +int sys_spawn(char* img_start, char* name, char** argv); int sys_exit(); int sys_yield(); @@ -91,7 +85,7 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session); int sys_poll_session(struct Session* userland_session_arr, int arr_capacity); int sys_close_session(struct Session* session); -int sys_exec(struct KernReadTool* read_tool, char* name, char** argv); +int sys_exec(char* img_start, char* name, char** argv); int sys_state(sys_state_option option, sys_state_info* info); int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S b/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S index 597d60af0..71d5278bd 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S +++ b/Ubiquitous/XiZi_AIoT/softkernel/load_apps.S @@ -35,7 +35,7 @@ user_apps: .section .rawdata_init .globl initapp initapp: - .incbin "../services/app/bin/shell" + .incbin "../services/app/bin/init" .section .rawdata_memfs .globl memfs diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 6766c792c..8a87a2597 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -58,17 +58,17 @@ void configure_cpu(uint32_t cpu) // arm_icache_enable(); // arm_icache_invalidate(); - struct TraceTag main_icache_tag, main_dcache_tag; - AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); - AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); - struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); - struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); - // p_dcache_driver->enable(); - // p_dcache_driver->invalidateall(); - // p_icache_driver->enable(); - // p_icache_driver->invalidateall(); - p_dcache_driver->disable(); - p_icache_driver->disable(); + // struct TraceTag main_icache_tag, main_dcache_tag; + // AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); + // AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); + // struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); + // struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); + // // p_dcache_driver->enable(); + // // p_dcache_driver->invalidateall(); + // // p_icache_driver->enable(); + // // p_icache_driver->invalidateall(); + // p_dcache_driver->disable(); + // p_icache_driver->disable(); // Invalidate SCU copy of TAG RAMs scu_secure_invalidate(cpu, all_ways); @@ -122,15 +122,14 @@ int main(void) return -1; } - // scu_enable(); - // configure_cpu(cpu_id); + scu_enable(); + configure_cpu(cpu_id); spinlock_init(&whole_kernel_lock, "wklock"); } else { - configure_cpu(cpu_id); spinlock_lock(&whole_kernel_lock); + configure_cpu(cpu_id); secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag); - DEBUG_PRINTF("CPU %d init done.\n", cur_cpuid()); spinlock_unlock(&whole_kernel_lock); } @@ -162,7 +161,7 @@ int main(void) assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); core_init_done |= (1 << cpu_id); - DEBUG("core_init_done: %x\n", core_init_done); + LOG_PRINTF("CPU %d init done\n", cpu_id); spinlock_unlock(&whole_kernel_lock); while (core_init_done != (1 << NR_CPU) - 1) diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index 2b0d9f5ac..81be8c655 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -66,18 +66,15 @@ Modification: /// @param path path to elf file /// @param argv arguments giving to main /// @return -int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv) +int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv) { + /* load img to task */ + /* 1. load elf header */ struct elfhdr elf; + memcpy((void*)&elf, img_start, sizeof(elf)); + // pgdir for new task struct TopLevelPageDirectory pgdir; pgdir.pd_addr = NULL; - - if (ipc_read(session, fd, (char*)&elf, 0, sizeof(elf)) < sizeof(elf) || elf.magic != ELF_MAGIC) { - ERROR("invalide elf file.\n"); - goto error_exec; - } - - // pgdir for new task if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) { ERROR("create new pgdir failed.\n"); goto error_exec; @@ -88,10 +85,8 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, uintptr_t load_size = 0; struct proghdr ph; for (int sec_idx = 0, off = elf.phoff; sec_idx < elf.phnum; sec_idx++, off += sizeof(ph)) { - if (ipc_read(session, fd, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) { - ERROR("Read elf header failed\n"); - goto error_exec; - } + // load proghdr + memcpy((char*)&ph, img_start + off, sizeof(ph)); if (ph.type != ELF_PROG_LOAD) continue; @@ -114,10 +109,7 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, panic("copy elf file to unmapped addr"); } uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE); - if (read_size != ipc_read(session, fd, P2V(page_paddr), ph.off + addr_offset, read_size)) { - ERROR("read size error, off: %d, read len: %d\n", ph.off + addr_offset, read_size); - goto error_exec; - } + memcpy(P2V(page_paddr), img_start + (ph.off + addr_offset), read_size); } } @@ -193,7 +185,7 @@ error_exec: return -1; } -int sys_exec(struct KernReadTool* read_tool, char* name, char** argv) +int sys_exec(char* img_start, char* name, char** argv) { /// @todo find a source of mmu_driver_tag instead of requiring from root static struct TraceTag mmu_driver_tag; @@ -204,12 +196,8 @@ int sys_exec(struct KernReadTool* read_tool, char* name, char** argv) } struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag); - struct TaskMicroDescriptor* current_task = cur_cpu()->task; - struct Session* session = read_tool->session; - int fd = read_tool->fd; - ipc_read_fn ipc_read = read_tool->ipc_read; - int ret = task_exec(current_task, session, fd, ipc_read, name, argv); + int ret = task_exec(current_task, img_start, name, argv); if (ret >= 0) { spinlock_init(¤t_task->lock, current_task->name); p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr)); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c index 6abb8b643..c4a587aaa 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c @@ -33,8 +33,8 @@ Modification: #include "syscall.h" #include "task.h" -extern int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv); -int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv) +extern int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv); +int sys_spawn(char* img_start, char* name, char** argv) { // alloc a new pcb struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb(); @@ -44,11 +44,7 @@ int sys_spawn(struct KernReadTool* read_tool, char* name, char** argv) } // init trapframe arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0); - - struct Session* session = read_tool->session; - int fd = read_tool->fd; - ipc_read_fn ipc_read = read_tool->ipc_read; - if (UNLIKELY(task_exec(new_task_cb, session, fd, ipc_read, name, argv)) < 0) { + if (UNLIKELY(task_exec(new_task_cb, img_start, name, argv)) < 0) { xizi_task_manager.free_pcb(new_task_cb); return -1; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c index ff25885c5..c37fb65fb 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c @@ -55,8 +55,17 @@ static inline void _padding(char* name) void show_tasks(void) { struct TaskMicroDescriptor* task = NULL; - DEBUG_PRINTF("******************************************************\n"); - DEBUG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n"); + LOG_PRINTF("******************************************************\n"); + for (int i = 0; i < NR_CPU; i++) { + LOG_PRINTF("CPU %d: ", i); + if (global_cpus[i].task != NULL) { + LOG_PRINTF("%s\n", global_cpus[i].task->name); + } else { + LOG_PRINTF("NULL\n"); + } + } + LOG_PRINTF("******************************************************\n"); + LOG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n"); for (int i = 0; i < TASK_MAX_PRIORITY; i++) { if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) { continue; @@ -64,19 +73,19 @@ void show_tasks(void) DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[i], node) { if (task->state == INIT) - DEBUG_PRINTF(" INIT "); + LOG_PRINTF(" INIT "); else if (task->state == READY) - DEBUG_PRINTF(" READY "); + LOG_PRINTF(" READY "); else if (task->state == RUNNING) - DEBUG_PRINTF("RUNNING "); + LOG_PRINTF("RUNNING "); else if (task->state == DEAD) - DEBUG_PRINTF(" DEAD "); + LOG_PRINTF(" DEAD "); _padding(task->name); - DEBUG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick); + LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick); } } - DEBUG_PRINTF("******************************************************\n"); + LOG_PRINTF("******************************************************\n"); return; } @@ -85,8 +94,8 @@ extern struct KBuddy kern_virtmem_buddy; extern uint32_t kernel_data_end[]; void show_mem(void) { - DEBUG_PRINTF("*********************************************************\n"); - DEBUG_PRINTF(" TOTAL(KB) USED(KB) FREE(KB) \n"); + LOG_PRINTF("*********************************************************\n"); + LOG_PRINTF(" TOTAL(KB) USED(KB) FREE(KB) \n"); uint32_t total = (PHY_MEM_STOP - V2P(kernel_data_end)) >> 10; uint32_t used = 0; @@ -96,14 +105,14 @@ void show_mem(void) } used = used >> 10; - DEBUG_PRINTF(" %d %d %d\n", total, total - used, used); - DEBUG_PRINTF("*********************************************************\n"); + LOG_PRINTF(" %d %d %d\n", total, total - used, used); + LOG_PRINTF("*********************************************************\n"); return; } void show_cpu(void) { - DEBUG_PRINTF("**********************************************************\n"); + LOG_PRINTF("**********************************************************\n"); #ifdef ARCH_SMP /// @todo support smp KPrintf(" cpu VALUE \n"); @@ -116,10 +125,10 @@ void show_cpu(void) _padding(current_task->name); - DEBUG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n"); - DEBUG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick); + LOG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n"); + LOG_PRINTF(" %d %s %d %d\n", cpu_id, current_task->name, TASK_CLOCK_TICK - current_task->remain_tick, current_task->remain_tick); - DEBUG_PRINTF("***********************************************************\n"); + LOG_PRINTF("***********************************************************\n"); return; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c index 4dd7660ff..34ebd827d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c @@ -41,7 +41,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u ret = 0; break; case SYSCALL_SPAWN: - ret = sys_spawn((struct KernReadTool*)param1, (char*)param2, (char**)param3); + ret = sys_spawn((char*)param1, (char*)param2, (char**)param3); break; case SYSCALL_EXIT: ret = sys_exit(); @@ -62,7 +62,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u ret = sys_close_session((struct Session*)param1); break; case SYSCALL_EXEC: - ret = sys_exec((struct KernReadTool*)param1, (char*)param2, (char**)param3); + ret = sys_exec((char*)param1, (char*)param2, (char**)param3); break; case SYSCALL_SYS_STATE: ret = sys_state(param1, (sys_state_info*)param2); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 86c84cc40..d2379cbc0 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -181,34 +181,29 @@ static void _scheduler(struct SchedulerRightGroup right_group) spinlock_lock(&whole_kernel_lock); while (1) { - spinlock_unlock(&whole_kernel_lock); - spinlock_lock(&xizi_task_manager.lock); next_task = NULL; /* find next runnable task */ assert(cur_cpu()->task == NULL); if (next_task_emergency != NULL) { next_task = next_task_emergency; - spinlock_lock(&next_task->lock); next_task->state = RUNNING; - spinlock_unlock(&next_task->lock); next_task_emergency = NULL; } else { next_task = xizi_task_manager.next_runnable_task(); } - spinlock_unlock(&xizi_task_manager.lock); + spinlock_unlock(&whole_kernel_lock); + /* not a runnable task */ - if (UNLIKELY(next_task == NULL)) { + if (UNLIKELY(next_task == NULL) || UNLIKELY(next_task->state != RUNNING)) { + spinlock_lock(&whole_kernel_lock); continue; } + /* a runnable task */ spinlock_lock(&whole_kernel_lock); - assert(next_task->state == RUNNING); - // p_mmu_driver->LoadPgdirCrit((uintptr_t)V2P(next_task->pgdir.pd_addr), &right_group.intr_driver_tag); - p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr)); - struct CPU* cpu = cur_cpu(); cpu->task = next_task; - // DEBUG_PRINTF("CPU %d switch to task %s\n", cur_cpuid(), next_task->name); + p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr)); context_switch(&cpu->scheduler, next_task->main_thread.context); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index b75cd8219..f88691a99 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -65,7 +65,7 @@ void intr_irq_dispatch(struct trapframe* tf) if ((int_info = p_intr_driver->hw_before_irq()) == 0) { return; } - // spinlock_lock(&whole_kernel_lock); + spinlock_lock(&whole_kernel_lock); DSB(); // DEBUG("CPU %d in\n", cur_cpuid()); @@ -96,6 +96,6 @@ void intr_irq_dispatch(struct trapframe* tf) assert(current_task == cur_cpu()->task); // DEBUG("CPU %d out\n", cur_cpuid()); - // spinlock_unlock(&whole_kernel_lock); + spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index 8b1535168..b2f71a6bf 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -52,7 +52,7 @@ void software_irq_dispatch(struct trapframe* tf) assert(p_intr_driver != NULL); p_intr_driver->cpu_irq_disable(); - // spinlock_lock(&whole_kernel_lock); + spinlock_lock(&whole_kernel_lock); DSB(); // DEBUG("CPU %d in\n", cur_cpuid()); // get current task @@ -78,10 +78,10 @@ void software_irq_dispatch(struct trapframe* tf) } assert(cur_task == cur_cpu()->task); if (syscall_num == SYSCALL_EXIT) { - ERROR("Exit reaches"); + panic("Exit reaches"); } // DEBUG("CPU %d out\n", cur_cpuid()); - // spinlock_unlock(&whole_kernel_lock); + spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } \ No newline at end of file From b9395573175d46d7641cf3ab78bc42c845ba8647 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Fri, 15 Mar 2024 16:21:36 +0800 Subject: [PATCH 06/24] Use only whole kernel lock --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../XiZi_AIoT/hardkernel/hardkernel_init.c | 2 +- .../cortex-a9/imx6q-sabrelite/trap_common.c | 2 ++ Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c | 8 +------- .../kernel_actracer/actracer_mem_chunk.c | 13 ------------- Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c | 7 ------- .../XiZi_AIoT/softkernel/memory/share_page.c | 17 ----------------- .../softkernel/syscall/sys_connect_session.c | 2 +- .../XiZi_AIoT/softkernel/syscall/sys_exec.c | 3 ++- .../XiZi_AIoT/softkernel/syscall/sys_exit.c | 2 -- .../softkernel/syscall/sys_poll_session.c | 11 ----------- .../XiZi_AIoT/softkernel/task/scheduler.c | 8 -------- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 7 ------- .../softkernel/trap/clock_irq_handler.c | 3 --- 14 files changed, 8 insertions(+), 79 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index c877945ce..129f07103 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 4 +#define NR_CPU 1 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c index ebad67c39..f0d6e6ca7 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c @@ -221,7 +221,7 @@ bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag) p_icache_driver->disable(); p_dcache_driver->disable(); // clock - p_clock_driver->sys_clock_init(); + // p_clock_driver->sys_clock_init(); p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0); // mmu secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index f9fcde6c8..bbc62cc7e 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -34,6 +34,7 @@ Modification: #include "trap_common.h" #include "log.h" +#include "multicores.h" extern void init_stack(uint32_t, uint32_t); extern void user_trap_swi_enter(void); @@ -47,6 +48,7 @@ static struct XiziTrapDriver xizi_trap_driver; void panic(char* s) { xizi_trap_driver.cpu_irq_disable(); + spinlock_unlock(&whole_kernel_lock); KPrintf("panic: %s\n", s); for (;;) ; diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c index 8edd6f77d..c0a259dee 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer.c @@ -60,8 +60,6 @@ static inline int namecmp(const char* s, const char* t) static struct TraceMeta* alloc_trace_meta() { int index = -1; - - spinlock_lock(&sys_tracer.trace_meta_bitmap_lock); for (uint32_t idx = 0; idx < BITS_TRACEMETA_BITMAP; idx++) { if (sys_tracer.trace_meta_bit_map[idx] == 0xFFFFFFFF) { continue; @@ -74,7 +72,6 @@ static struct TraceMeta* alloc_trace_meta() break; } } - spinlock_unlock(&sys_tracer.trace_meta_bitmap_lock); if (index == -1) { panic("Tracer no enough TracerMeta."); @@ -87,15 +84,12 @@ static struct TraceMeta* alloc_trace_meta() static bool dealloc_trace_meta(struct TraceMeta* meta) { int index = meta->index; - - spinlock_lock(&sys_tracer.trace_meta_bitmap_lock); // clear bitmap uint32_t outer_index = index / 32; uint32_t inner_index = index % 32; sys_tracer.trace_meta_bit_map[outer_index] &= (uint32_t)(~(1 << inner_index)); // clear meta sys_tracer.trace_meta_poll[index].type = TRACER_INVALID; - spinlock_unlock(&sys_tracer.trace_meta_bitmap_lock); if (index == -1) { panic("Tracer no enough TracerMeta."); @@ -337,7 +331,7 @@ static struct TraceMeta* tracer_find_meta(struct TraceMeta* const p_owner, char* return p_owner_inside; } if ((vnp = tracer_find_meta_onestep(p_owner_inside, name, NULL)) == 0) { - ERROR("Not such object: %s\n", path); + DEBUG("Not such object: %s\n", path); return NULL; } p_owner_inside = vnp; diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c index 3dc554e69..f9c3ceb76 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c @@ -76,8 +76,6 @@ void mem_chunk_synchronizer_init(uintptr_t mem_chunk_base, uint32_t mem_chunk_si static struct tracer_mem_chunk* tracer_get_mem_chunk_cache(uint32_t chunk_id) { - spinlock_lock(&tracer_mem_chunk_syner.lock); - // cached mem_chunk cache struct tracer_mem_chunk* b; DOUBLE_LIST_FOR_EACH_ENTRY(b, &tracer_mem_chunk_syner.head, list_node) @@ -85,7 +83,6 @@ static struct tracer_mem_chunk* tracer_get_mem_chunk_cache(uint32_t chunk_id) if (b->chunk_id == chunk_id) { if (!(b->flag & TRACER_MEM_CHUNK_BUSY)) { b->flag |= TRACER_MEM_CHUNK_BUSY; - spinlock_unlock(&tracer_mem_chunk_syner.lock); return b; } ERROR("tracer mem_chunk syner is locked\n"); @@ -99,7 +96,6 @@ static struct tracer_mem_chunk* tracer_get_mem_chunk_cache(uint32_t chunk_id) if ((b->flag & TRACER_MEM_CHUNK_BUSY) == 0) { b->chunk_id = chunk_id; b->flag = TRACER_MEM_CHUNK_BUSY; - spinlock_unlock(&tracer_mem_chunk_syner.lock); return b; } } @@ -134,13 +130,9 @@ void tracer_mem_chunk_release(struct tracer_mem_chunk* b) } // move mem_chunk that just used to the head of cache list - spinlock_lock(&tracer_mem_chunk_syner.lock); - doubleListDel(&b->list_node); doubleListAddOnHead(&b->list_node, &tracer_mem_chunk_syner.head); b->flag &= ~TRACER_MEM_CHUNK_BUSY; - - spinlock_unlock(&tracer_mem_chunk_syner.lock); } static void tracer_mem_chunk_zero(uint32_t chunk_id) @@ -157,7 +149,6 @@ static void tracer_mem_chunk_zero(uint32_t chunk_id) static uint32_t find_first_free_mem_chunk() { /// @todo another mem_chunk - spinlock_lock(&sys_tracer.mem_chunk_bitmap_lock); for (uint32_t idx = 0; idx < BITS_MEM_CHUNK_BITMAP; idx++) { if (sys_tracer.mem_chunks_bit_map[idx] == 0xFFFFFFFF) { continue; @@ -165,11 +156,9 @@ static uint32_t find_first_free_mem_chunk() uint32_t position = __builtin_ffs(~sys_tracer.mem_chunks_bit_map[idx]); if (position != 32) { sys_tracer.mem_chunks_bit_map[idx] |= (1 << (position - 1)); - spinlock_unlock(&sys_tracer.mem_chunk_bitmap_lock); return idx * 32 + position; } } - spinlock_unlock(&sys_tracer.mem_chunk_bitmap_lock); panic("Tracer no enough space."); return 0; } @@ -184,11 +173,9 @@ uint32_t tracer_mem_chunk_alloc() void tracer_mem_chunk_free(uint32_t chunk_id) { assert(chunk_id >= 0 && chunk_id < NR_TRACER_MEM_CHUNKS); - spinlock_lock(&sys_tracer.mem_chunk_bitmap_lock); uint32_t idx = chunk_id % 32; uint32_t inner_mem_chunk_bit = chunk_id / 32; // assert mem_chunk is allocated assert((sys_tracer.mem_chunks_bit_map[idx] & (1 << inner_mem_chunk_bit)) != 0); sys_tracer.mem_chunks_bit_map[idx] &= (uint32_t)(~(1 << inner_mem_chunk_bit)); - spinlock_unlock(&sys_tracer.mem_chunk_bitmap_lock); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c index 95d56e0d0..ed5dd8494 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c @@ -75,8 +75,6 @@ static struct KPage* KBuddyPagesAlloc(struct KBuddy* pbuddy, int nPages) struct KFreeList* list = NULL; int i = 0, order = 0; - spinlock_lock(&pbuddy->lock); - // find order for (order = 0; (FREE_LIST_INDEX(order)) < nPages; order++) ; @@ -99,12 +97,10 @@ static struct KPage* KBuddyPagesAlloc(struct KBuddy* pbuddy, int nPages) // set the pages' order _buddy_set_pages_order(page, order); - spinlock_unlock(&pbuddy->lock); return page; } // there is no enough free page to satisfy the nPages - spinlock_unlock(&pbuddy->lock); return NULL; } @@ -116,8 +112,6 @@ static void KBuddyPagesFree(struct KBuddy* pbuddy, struct KPage* page) uint32_t buddy_idx = 0, new_buddy_idx = 0; uint32_t page_idx = page - pbuddy->pages; - spinlock_lock(&pbuddy->lock); - for (; order < MAX_BUDDY_ORDER - 1; order++) { // find and delete buddy to combine buddy_idx = BUDDY_PAGE_INDEX(page_idx, order); @@ -141,7 +135,6 @@ static void KBuddyPagesFree(struct KBuddy* pbuddy, struct KPage* page) doubleListAddOnHead(&page->node, &pbuddy->free_list[order].list_head); pbuddy->free_list[order].n_free_pages++; - spinlock_unlock(&pbuddy->lock); return; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c index 3f6001114..329a3a17c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c @@ -91,23 +91,18 @@ static uintptr_t map_task_share_page(struct TaskMicroDescriptor* task, const uin struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag); struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); - spinlock_lock(&task->lock); // map double vaddr page to support uniform ring buffer r/w uintptr_t vaddr = alloc_share_page_addr(task, nr_pages * 2); if (UNLIKELY(vaddr == 0)) { - spinlock_unlock(&task->lock); return (uintptr_t)NULL; } if (!xizi_pager.map_pages(task->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, false)) { - spinlock_unlock(&task->lock); return (uintptr_t)NULL; } if (!xizi_pager.map_pages(task->pgdir.pd_addr, vaddr + (nr_pages * PAGE_SIZE), paddr, nr_pages * PAGE_SIZE, false)) { xizi_pager.unmap_pages(task->pgdir.pd_addr, vaddr, nr_pages * PAGE_SIZE); - spinlock_unlock(&task->lock); return (uintptr_t)NULL; } - spinlock_unlock(&task->lock); if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(vaddr, 2 * nr_pages * PAGE_SIZE); /// @todo clean range rather than all @@ -123,14 +118,12 @@ uintptr_t task_map_pages(struct TaskMicroDescriptor* task, const uintptr_t vaddr struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag); struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); - spinlock_lock(&task->lock); bool ret = false; if (is_dev) { ret = xizi_pager.map_pages(task->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, true); } else { ret = xizi_pager.map_pages(task->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, false); } - spinlock_unlock(&task->lock); if (!ret) { return (uintptr_t)NULL; } @@ -150,10 +143,8 @@ void unmap_task_share_pages(struct TaskMicroDescriptor* task, const uintptr_t ta struct DCacheDone* p_dcache_done = AchieveResource(&right_group.dcache_driver_tag); struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); - spinlock_lock(&task->lock); xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr, nr_pages * PAGE_SIZE); xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr + (nr_pages * PAGE_SIZE), nr_pages * PAGE_SIZE); - spinlock_unlock(&task->lock); if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(task_vaddr, 2 * nr_pages * PAGE_SIZE); /// @todo clean range rather than all @@ -200,20 +191,16 @@ struct session_backend* create_share_pages(struct TaskMicroDescriptor* client, s session_backend->client_side.buf_addr = client_vaddr; session_backend->client_side.capacity = true_capacity; session_backend->client_side.closed = false; - spinlock_lock(&client->lock); doubleListNodeInit(&session_backend->client_side.node); doubleListAddOnBack(&session_backend->client_side.node, &client->cli_sess_listhead); - spinlock_unlock(&client->lock); // init server side session struct session_backend->server_side.buf_addr = server_vaddr; session_backend->server_side.capacity = true_capacity; session_backend->server_side.head = 0; session_backend->server_side.tail = 0; session_backend->server_side.closed = false; - spinlock_lock(&server->lock); doubleListNodeInit(&session_backend->server_side.node); doubleListAddOnBack(&session_backend->server_side.node, &server->svr_sess_listhead); - spinlock_unlock(&server->lock); return session_backend; } @@ -232,15 +219,11 @@ int delete_share_pages(struct session_backend* session_backend) /* unmap share pages */ if (session_backend->client) { - spinlock_lock(&session_backend->client->lock); doubleListDel(&session_backend->client_side.node); - spinlock_unlock(&session_backend->client->lock); } if (session_backend->server) { - spinlock_lock(&session_backend->server->lock); doubleListDel(&session_backend->server_side.node); - spinlock_unlock(&session_backend->server->lock); } /* free seesion backend */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c index debfb86d3..84fc74109 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c @@ -70,7 +70,7 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session) struct TraceTag server_tag; if (!AchieveResourceTag(&server_tag, &server_identifier_owner, path)) { - ERROR("Not server: %s\n", path); + DEBUG("Not server: %s\n", path); return -1; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index 81be8c655..84d21bc02 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -106,7 +106,8 @@ int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, cha for (int addr_offset = 0; addr_offset < ph.filesz; addr_offset += PAGE_SIZE) { uintptr_t page_paddr = xizi_pager.address_translate(&pgdir, ph.vaddr + addr_offset); if (page_paddr == 0) { - panic("copy elf file to unmapped addr"); + ERROR("copy elf file to unmapped addr"); + goto error_exec; } uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE); memcpy(P2V(page_paddr), img_start + (ph.off + addr_offset), read_size); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c index b318f9843..274ae6f24 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c @@ -85,9 +85,7 @@ int sys_exit() // delete task for pcb_list xizi_task_manager.cur_task_yield_noschedule(); - spinlock_lock(&cur_task->lock); cur_task->state = DEAD; - spinlock_unlock(&cur_task->lock); return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c index e1b826a08..8a3e7b9e4 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c @@ -41,8 +41,6 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) return -1; } - spinlock_lock(&cur_task->lock); - struct double_list_node* cur_node = NULL; struct server_session* server_session = NULL; /* update old sessions */ @@ -54,7 +52,6 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) server_session = CONTAINER_OF(cur_node, struct server_session, node); if (UNLIKELY(server_session->buf_addr != (uintptr_t)userland_session_arr[i].buf)) { ERROR("mismatched old session addr, user buf: %x, server buf: %x\n", userland_session_arr[i].buf, server_session->buf_addr); - spinlock_unlock(&cur_task->lock); return -1; } // update session_backend @@ -63,21 +60,18 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) doubleListDel(cur_node); doubleListAddOnBack(cur_node, &cur_task->svr_sess_listhead); } - spinlock_unlock(&cur_task->lock); /* handle sessions for condition 2, ref. delete_share_pages() */ bool has_delete = true; while (has_delete) { has_delete = false; - spinlock_lock(&cur_task->lock); DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node) { if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) { // client had closed it, then server will close it too struct session_backend* session_backend = SERVER_SESSION_BACKEND(server_session); - spinlock_unlock(&cur_task->lock); if (!session_backend->server_side.closed) { session_backend->server_side.closed = true; xizi_share_page_manager.unmap_task_share_pages(cur_task, session_backend->server_side.buf_addr, session_backend->nr_pages); @@ -87,13 +81,9 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) break; } } - if (!has_delete) { - spinlock_unlock(&cur_task->lock); - } } /* poll with new sessions */ - spinlock_lock(&cur_task->lock); int i = 0; DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node) { @@ -111,7 +101,6 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) if (LIKELY(i < arr_capacity)) { userland_session_arr[i].buf = 0; } - spinlock_unlock(&cur_task->lock); return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c b/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c index bfddb0c32..a8d8048dd 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c @@ -38,20 +38,16 @@ struct TaskMicroDescriptor* max_priority_runnable_task(void) DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node) { - spinlock_lock(&task->lock); if (task->state == READY) { // found a runnable task, stop this look up task->state = RUNNING; - spinlock_unlock(&task->lock); return task; } else if (task->state == DEAD) { // found a killed task, stop this loop // change in pcb_list may break this loop, so find a runnable in next look up - spinlock_unlock(&task->lock); xizi_task_manager.free_pcb(task); return NULL; } - spinlock_unlock(&task->lock); } return NULL; } @@ -63,20 +59,16 @@ struct TaskMicroDescriptor* round_robin_runnable_task(uint32_t priority) DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node) { - spinlock_lock(&task->lock); if (task->state == READY) { // found a runnable task, stop this look up - spinlock_unlock(&task->lock); task->state = RUNNING; return task; } else if (task->state == DEAD) { // found a killed task, stop this loop // change in pcb_list may break this loop, so find a runnable in next look up - spinlock_unlock(&task->lock); xizi_task_manager.free_pcb(task); return NULL; } - spinlock_unlock(&task->lock); } return NULL; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index d2379cbc0..525e66544 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -62,12 +62,10 @@ static void _task_manager_init() /// @brief alloc a new task without init static struct TaskMicroDescriptor* _alloc_task_cb() { - spinlock_lock(&xizi_task_manager.lock); // alloc task and add it to used task list struct TaskMicroDescriptor* task = (struct TaskMicroDescriptor*)slab_alloc(&xizi_task_manager.task_allocator); if (UNLIKELY(task == NULL)) { ERROR("Not enough memory\n"); - spinlock_unlock(&xizi_task_manager.lock); return NULL; } // set pid once task is allocated @@ -76,7 +74,6 @@ static struct TaskMicroDescriptor* _alloc_task_cb() // update pcb used xizi_task_manager.nr_pcb_used += 1; - spinlock_unlock(&xizi_task_manager.lock); return task; } @@ -213,7 +210,6 @@ static void _cur_task_yield_noschedule(void) { yield_cnt++; - spinlock_lock(&xizi_task_manager.lock); struct TaskMicroDescriptor* current_task = cur_cpu()->task; assert(current_task != NULL); @@ -230,16 +226,13 @@ static void _cur_task_yield_noschedule(void) doubleListAddOnBack(¤t_task->node, &xizi_task_manager.task_list_head[current_task->priority]); ready_task_priority |= (1 << current_task->priority); // set current task state - spinlock_lock(¤t_task->lock); current_task->state = READY; current_task->remain_tick = TASK_CLOCK_TICK; - spinlock_unlock(¤t_task->lock); cur_cpu()->task = NULL; if (yield_cnt == 50) { recover_priority(); yield_cnt = 0; } - spinlock_unlock(&xizi_task_manager.lock); } static void _set_cur_task_priority(int priority) diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c index 9f8035a44..b3453dd2c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c @@ -49,9 +49,6 @@ bool clock_intr_handler_init(struct TraceTag* p_clock_driver_tag) uint64_t global_tick = 0; int xizi_clock_handler(int irq, void* tf, void* arg) { - // spinlock_lock(&whole_kernel_lock); - // DEBUG_PRINTF("CPU %d\n", cpu_get_current()); - // spinlock_unlock(&whole_kernel_lock); /* handle clock interrupt using driver */ if (p_clock_driver->is_timer_expired()) { p_clock_driver->clear_clock_intr(); From c60f29277ac216c36020d1bd4ad9973d60b7f47e Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Fri, 15 Mar 2024 18:29:57 +0800 Subject: [PATCH 07/24] Add wklock to dabort and iabort. --- .../XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c | 7 +++---- Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c | 4 +--- Ubiquitous/XiZi_AIoT/softkernel/main.c | 4 ---- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index 129f07103..c877945ce 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 1 +#define NR_CPU 4 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index 9d7224da8..51f99c345 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -44,6 +44,7 @@ Modification: #include "log.h" #include "multicores.h" +#include "spinlock.h" #include "syscall.h" __attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status) @@ -94,6 +95,7 @@ void handle_undefined_instruction(struct trapframe* tf) extern void context_switch(struct context**, struct context*); void dabort_handler(struct trapframe* r) { + spinlock_lock(&whole_kernel_lock); uint32_t dfs, dfa; __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); @@ -105,8 +107,6 @@ void dabort_handler(struct trapframe* r) LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); _abort_reason(dfs); dump_tf(r); - } - if (cur_cpu()->task != NULL) { sys_exit(); context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); } else { // Exception occured in Kernel space: panic @@ -120,6 +120,7 @@ void dabort_handler(struct trapframe* r) void iabort_handler(struct trapframe* r) { + spinlock_lock(&whole_kernel_lock); uint32_t ifs, ifa; __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); @@ -131,8 +132,6 @@ void iabort_handler(struct trapframe* r) LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); _abort_reason(ifs); dump_tf(r); - } - if (cur_cpu()->task != NULL) { sys_exit(); context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); } else { // Exception occured in Kernel space: panic diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c index f9c3ceb76..3c9894d59 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c @@ -85,8 +85,6 @@ static struct tracer_mem_chunk* tracer_get_mem_chunk_cache(uint32_t chunk_id) b->flag |= TRACER_MEM_CHUNK_BUSY; return b; } - ERROR("tracer mem_chunk syner is locked\n"); - panic(""); } } @@ -126,7 +124,7 @@ void tracer_mem_chunk_write(struct tracer_mem_chunk* b) void tracer_mem_chunk_release(struct tracer_mem_chunk* b) { if ((b->flag & TRACER_MEM_CHUNK_BUSY) == 0) { - panic("tracer mem_chunk release but it's busy occupied"); + panic("tracer mem_chunk release but it's not busy occupied"); } // move mem_chunk that just used to the head of cache list diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 8a87a2597..22c6d96bf 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -122,13 +122,9 @@ int main(void) return -1; } - scu_enable(); - configure_cpu(cpu_id); - spinlock_init(&whole_kernel_lock, "wklock"); } else { spinlock_lock(&whole_kernel_lock); - configure_cpu(cpu_id); secondary_cpu_hardkernel_init(cpu_id, &hardkernel_tag); spinlock_unlock(&whole_kernel_lock); } From 50dab7b55311900bc68b9190092db39602dde8bd Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Mon, 18 Mar 2024 11:17:55 +0800 Subject: [PATCH 08/24] test cache --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../hardkernel/cache/cache_common_ope.c | 8 ++-- .../intr/arm/armv7-a/cortex-a9/error_debug.c | 8 +++- .../intr/arm/armv7-a/cortex-a9/spinlock.c | 7 ++++ .../XiZi_AIoT/hardkernel/intr/spinlock.h | 3 +- .../mmu/arm/armv7-a/cortex-a9/mmu.c | 6 +++ .../arm/armv7-a/cortex-a9/pagetable_attr.c | 32 ++++++++------- .../XiZi_AIoT/hardkernel/mmu/mmu_common.h | 1 + Ubiquitous/XiZi_AIoT/services/app/init.c | 9 ++--- Ubiquitous/XiZi_AIoT/softkernel/main.c | 39 ++++++++++++------- .../XiZi_AIoT/softkernel/memory/share_page.c | 12 ++++-- .../softkernel/trap/default_irq_handler.c | 3 -- .../softkernel/trap/software_irq_handler.c | 4 +- 13 files changed, 85 insertions(+), 49 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index c877945ce..129f07103 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 4 +#define NR_CPU 1 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c index 6f5978f2c..4d5e33d33 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c @@ -232,15 +232,15 @@ static struct DCacheDone dcache_done = { struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag) { /* init icache */ - // icache_done.enable(); - icache_done.disable(); + icache_done.enable(); + // icache_done.disable(); return &icache_done; } struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag) { /* init dcache */ - // dcache_done.enable(); - dcache_done.disable(); + dcache_done.enable(); + // dcache_done.disable(); return &dcache_done; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index 51f99c345..dc1ca496f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -95,7 +95,9 @@ void handle_undefined_instruction(struct trapframe* tf) extern void context_switch(struct context**, struct context*); void dabort_handler(struct trapframe* r) { - spinlock_lock(&whole_kernel_lock); + if (!is_spinlock_locked(&whole_kernel_lock)) { + spinlock_lock(&whole_kernel_lock); + } uint32_t dfs, dfa; __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); @@ -120,7 +122,9 @@ void dabort_handler(struct trapframe* r) void iabort_handler(struct trapframe* r) { - spinlock_lock(&whole_kernel_lock); + if (!is_spinlock_locked(&whole_kernel_lock)) { + spinlock_lock(&whole_kernel_lock); + } uint32_t ifs, ifa; __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c index 4581ef0e7..e76712945 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c @@ -20,7 +20,9 @@ #include #include "assert.h" +#include "multicores.h" #include "spinlock.h" +#include "task.h" #include "trap_common.h" bool module_spinlock_use_intr_init(void) @@ -55,4 +57,9 @@ void _spinlock_unlock(struct spinlock* lock); void spinlock_unlock(struct spinlock* lock) { _spinlock_unlock(lock); +} + +bool is_spinlock_locked(struct spinlock* lock) +{ + return lock->owner_cpu != SPINLOCK_STATE_UNLOCK; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h index 7454f9eec..e1e08bb86 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h @@ -41,4 +41,5 @@ struct spinlock { // Mutex. bool module_spinlock_use_intr_init(void); void spinlock_init(struct spinlock* lock, char* name); void spinlock_lock(struct spinlock* lock); -void spinlock_unlock(struct spinlock* lock); \ No newline at end of file +void spinlock_unlock(struct spinlock* lock); +bool is_spinlock_locked(struct spinlock* lock); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/mmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/mmu.c index 7bc5254c2..50d783b90 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/mmu.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/mmu.c @@ -82,6 +82,11 @@ static void tlb_flush_range(uintptr_t vstart, int len) } } +static void tlb_flush_all() +{ + CLEARTLB(0); +} + static struct MmuCommonDone mmu_common_done = { .MmuDevPteAttr = GetDevPteAttr, .MmuPdeAttr = GetPdeAttr, @@ -91,6 +96,7 @@ static struct MmuCommonDone mmu_common_done = { .LoadPgdirCrit = load_pgdir_critical, .LoadPgdir = load_pgdir, + .TlbFlushAll = tlb_flush_all, .TlbFlush = tlb_flush_range, }; diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c index 455b1d759..477b92a4d 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c @@ -30,20 +30,6 @@ Modification: #include "mmu.h" #include "mmu_common.h" -void GetDevPteAttr(uintptr_t* attr) -{ - static char init = 0; - static PageTblEntry dev_pte_attr; - if (init == 0) { - init = 1; - - dev_pte_attr.entry = 0; - dev_pte_attr.desc_type = PAGE_4K; - dev_pte_attr.AP1_0 = AccessPermission_KernelOnly; - } - *attr = dev_pte_attr.entry; -} - void GetUsrPteAttr(uintptr_t* attr) { static char init = 0; @@ -55,6 +41,7 @@ void GetUsrPteAttr(uintptr_t* attr) usr_pte_attr.desc_type = PAGE_4K; usr_pte_attr.B = 1; usr_pte_attr.C = 1; + usr_pte_attr.S = 1; usr_pte_attr.AP1_0 = AccessPermission_KernelUser; } *attr = usr_pte_attr.entry; @@ -68,12 +55,28 @@ void GetUsrDevPteAttr(uintptr_t* attr) init = 1; usr_pte_attr.entry = 0; + usr_pte_attr.S = 1; usr_pte_attr.desc_type = PAGE_4K; usr_pte_attr.AP1_0 = AccessPermission_KernelUser; } *attr = usr_pte_attr.entry; } +void GetDevPteAttr(uintptr_t* attr) +{ + static char init = 0; + static PageTblEntry dev_pte_attr; + if (init == 0) { + init = 1; + + dev_pte_attr.entry = 0; + dev_pte_attr.S = 1; + dev_pte_attr.desc_type = PAGE_4K; + dev_pte_attr.AP1_0 = AccessPermission_KernelOnly; + } + *attr = dev_pte_attr.entry; +} + void GetKernPteAttr(uintptr_t* attr) { static char init = 0; @@ -85,6 +88,7 @@ void GetKernPteAttr(uintptr_t* attr) kern_pte_attr.desc_type = PAGE_4K; kern_pte_attr.B = 1; kern_pte_attr.C = 1; + kern_pte_attr.S = 1; kern_pte_attr.AP1_0 = AccessPermission_KernelOnly; } *attr = kern_pte_attr.entry; diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/mmu_common.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/mmu_common.h index 99aa7d38a..b979f80e8 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/mmu_common.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/mmu_common.h @@ -29,6 +29,7 @@ struct MmuCommonDone void (*LoadPgdirCrit)(uintptr_t pgdir_paddr, struct TraceTag*); void (*LoadPgdir)(uintptr_t pgdir_paddr); + void (*TlbFlushAll)(); void (*TlbFlush)(uintptr_t vaddr, int len); }; diff --git a/Ubiquitous/XiZi_AIoT/services/app/init.c b/Ubiquitous/XiZi_AIoT/services/app/init.c index 62a62c401..3c3fc1446 100755 --- a/Ubiquitous/XiZi_AIoT/services/app/init.c +++ b/Ubiquitous/XiZi_AIoT/services/app/init.c @@ -19,11 +19,10 @@ int main(int argc, char* argv[]) { struct Session session; - printf("connecting MemFS\n"); - while (connect_session(&session, "MemFS", 8092) < 0) { - printf("connecting MemFS\n"); - } - printf("connect MemFS success\n"); + printf("init: connecting MemFS\n"); + while (connect_session(&session, "MemFS", 8092) < 0) + ; + printf("init: connect MemFS success\n"); int fd; char* shell_task_param[2] = { "/shell", 0 }; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 22c6d96bf..0c264e7ed 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -58,18 +58,6 @@ void configure_cpu(uint32_t cpu) // arm_icache_enable(); // arm_icache_invalidate(); - // struct TraceTag main_icache_tag, main_dcache_tag; - // AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); - // AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); - // struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); - // struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); - // // p_dcache_driver->enable(); - // // p_dcache_driver->invalidateall(); - // // p_icache_driver->enable(); - // // p_icache_driver->invalidateall(); - // p_dcache_driver->disable(); - // p_icache_driver->disable(); - // Invalidate SCU copy of TAG RAMs scu_secure_invalidate(cpu, all_ways); @@ -138,7 +126,6 @@ int main(void) show_xizi_bar(); int cpu_count = NR_CPU; - ; for (int i = 1; i < cpu_count; i++) { // start secondary cpus cpu_start_secondary(i); @@ -156,12 +143,38 @@ int main(void) assert(AchieveResourceTag(&scheduler_rights.mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); + struct TraceTag main_icache_tag, main_dcache_tag; + AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); + AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); + struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); + struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); + core_init_done |= (1 << cpu_id); LOG_PRINTF("CPU %d init done\n", cpu_id); spinlock_unlock(&whole_kernel_lock); while (core_init_done != (1 << NR_CPU) - 1) ; + DEBUG_PRINTF("%d", cpu_id); + + // scu_enable(); + // configure_cpu(cpu_id); + // p_dcache_driver->enable(); + // p_icache_driver->enable(); + + // spinlock_lock(&whole_kernel_lock); + // p_dcache_driver->flushall(); + // spinlock_unlock(&whole_kernel_lock); + + // while (true) { + // spinlock_lock(&whole_kernel_lock); + // DEBUG("CPU: %d\n", cpu_id); + // secondary_cpu_load_kern_pgdir(&scheduler_rights.mmu_driver_tag, NULL); + // CLEARTLB(0); + // p_dcache_driver->flushall(); + // spinlock_unlock(&whole_kernel_lock); + // } + xizi_task_manager.task_scheduler(scheduler_rights); // never reached diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c index 329a3a17c..335c28879 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c @@ -105,8 +105,10 @@ static uintptr_t map_task_share_page(struct TaskMicroDescriptor* task, const uin } if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(vaddr, 2 * nr_pages * PAGE_SIZE); + /// @todo clean range rather than all - p_dcache_done->flushall(); + // p_dcache_done->flushall(); + p_dcache_done->invalidateall(); // p_dcache_done->flush(vaddr, vaddr + 2 * nr_pages * PAGE_SIZE); } return vaddr; @@ -129,8 +131,10 @@ uintptr_t task_map_pages(struct TaskMicroDescriptor* task, const uintptr_t vaddr } if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(vaddr, nr_pages * PAGE_SIZE); + /// @todo clean range rather than all - p_dcache_done->flushall(); + // p_dcache_done->flushall(); + p_dcache_done->invalidateall(); // p_dcache_done->flush(vaddr, vaddr + nr_pages * PAGE_SIZE); } @@ -147,8 +151,10 @@ void unmap_task_share_pages(struct TaskMicroDescriptor* task, const uintptr_t ta xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr + (nr_pages * PAGE_SIZE), nr_pages * PAGE_SIZE); if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(task_vaddr, 2 * nr_pages * PAGE_SIZE); + /// @todo clean range rather than all - p_dcache_done->flushall(); + // p_dcache_done->flushall(); + p_dcache_done->invalidateall(); // p_dcache_done->flush(task_vaddr, task_vaddr + 2 * nr_pages * PAGE_SIZE); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index f88691a99..213ab28df 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -66,8 +66,6 @@ void intr_irq_dispatch(struct trapframe* tf) return; } spinlock_lock(&whole_kernel_lock); - DSB(); - // DEBUG("CPU %d in\n", cur_cpuid()); struct TaskMicroDescriptor* current_task = cur_cpu()->task; if (LIKELY(current_task != NULL)) { @@ -95,7 +93,6 @@ void intr_irq_dispatch(struct trapframe* tf) } assert(current_task == cur_cpu()->task); - // DEBUG("CPU %d out\n", cur_cpuid()); spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index b2f71a6bf..623d01309 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -53,8 +53,7 @@ void software_irq_dispatch(struct trapframe* tf) p_intr_driver->cpu_irq_disable(); spinlock_lock(&whole_kernel_lock); - DSB(); - // DEBUG("CPU %d in\n", cur_cpuid()); + // get current task struct TaskMicroDescriptor* cur_task = cur_cpu()->task; /// @todo: Handle dead task @@ -81,7 +80,6 @@ void software_irq_dispatch(struct trapframe* tf) panic("Exit reaches"); } - // DEBUG("CPU %d out\n", cur_cpuid()); spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); } \ No newline at end of file From 08c8f0b9521666c87301f9bd6cb70ba4ab080613 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Tue, 19 Mar 2024 10:12:51 +0800 Subject: [PATCH 09/24] Update spinlock to avoid hungry. --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../hardkernel/cache/cache_common_ope.c | 2 - .../XiZi_AIoT/hardkernel/hardkernel_init.c | 8 +-- .../intr/arm/armv7-a/cortex-a9/spinlock.c | 31 ++++++++++- .../arm/armv7-a/cortex-a9/pagetable_attr.c | 2 - Ubiquitous/XiZi_AIoT/softkernel/main.c | 55 +------------------ .../XiZi_AIoT/softkernel/syscall/sys_exec.c | 2 +- 7 files changed, 39 insertions(+), 63 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index 129f07103..c877945ce 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 1 +#define NR_CPU 4 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c index 4d5e33d33..6d05e236a 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c @@ -233,7 +233,6 @@ struct ICacheDone* hardkernel_icache_init(struct TraceTag* hardkernel_tag) { /* init icache */ icache_done.enable(); - // icache_done.disable(); return &icache_done; } @@ -241,6 +240,5 @@ struct DCacheDone* hardkernel_dcache_init(struct TraceTag* hardkernel_tag) { /* init dcache */ dcache_done.enable(); - // dcache_done.disable(); return &dcache_done; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c index f0d6e6ca7..660b883f9 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c @@ -216,10 +216,10 @@ bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag) p_intr_driver->sys_irq_init(cpu_id); p_intr_driver->cpu_irq_disable(); // cache - // p_icache_driver->enable(); - // p_dcache_driver->enable(); - p_icache_driver->disable(); - p_dcache_driver->disable(); + p_icache_driver->enable(); + p_dcache_driver->enable(); + // p_icache_driver->disable(); + // p_dcache_driver->disable(); // clock // p_clock_driver->sys_clock_init(); p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c index e76712945..de844c1b1 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c @@ -25,8 +25,24 @@ #include "task.h" #include "trap_common.h" +#include "list.h" + +struct lock_node { + int cpu_id; + struct double_list_node node; +}; + +static struct double_list_node lock_request_guard; +static struct lock_node core_lock_request[NR_CPU]; +static struct spinlock request_lock; bool module_spinlock_use_intr_init(void) { + for (int i = 0; i < NR_CPU; i++) { + core_lock_request[i].cpu_id = i; + doubleListNodeInit(&core_lock_request[i].node); + } + doubleListNodeInit(&lock_request_guard); + spinlock_init(&request_lock, "requestlock"); return true; } @@ -44,18 +60,31 @@ void spinlock_init(struct spinlock* lock, char* name) } extern int _spinlock_lock(struct spinlock* lock, uint32_t timeout); +void _spinlock_unlock(struct spinlock* lock); + void spinlock_lock(struct spinlock* lock) { if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpuid()) { ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu); panic(""); } + // _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); + // doubleListAddOnBack(&core_lock_request[cur_cpuid()].node, &lock_request_guard); + // _spinlock_unlock(&request_lock); + + // while (lock_request_guard.next != &core_lock_request[cur_cpuid()].node) + // ; + _spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER); } -void _spinlock_unlock(struct spinlock* lock); void spinlock_unlock(struct spinlock* lock) { + // assert(lock_request_guard.next == &core_lock_request[cur_cpuid()].node); + // _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); + // _double_list_del(core_lock_request[cur_cpuid()].node.prev, core_lock_request[cur_cpuid()].node.next); + // _spinlock_unlock(&request_lock); + _spinlock_unlock(lock); } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c index 477b92a4d..bff47d1b3 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/pagetable_attr.c @@ -55,7 +55,6 @@ void GetUsrDevPteAttr(uintptr_t* attr) init = 1; usr_pte_attr.entry = 0; - usr_pte_attr.S = 1; usr_pte_attr.desc_type = PAGE_4K; usr_pte_attr.AP1_0 = AccessPermission_KernelUser; } @@ -70,7 +69,6 @@ void GetDevPteAttr(uintptr_t* attr) init = 1; dev_pte_attr.entry = 0; - dev_pte_attr.S = 1; dev_pte_attr.desc_type = PAGE_4K; dev_pte_attr.AP1_0 = AccessPermission_KernelOnly; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 0c264e7ed..289ee4d7e 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -42,30 +42,6 @@ Modification: extern uint32_t _binary_init_start[], _binary_default_fs_start[]; static struct TraceTag hardkernel_tag, softkernel_tag; -void configure_cpu(uint32_t cpu) -{ - const unsigned int all_ways = 0xf; - - disable_strict_align_check(); - - // Enable branch prediction - arm_branch_target_cache_invalidate(); - arm_branch_prediction_enable(); - - // Enable L1 caches - // arm_dcache_enable(); - // arm_dcache_invalidate(); - // arm_icache_enable(); - // arm_icache_invalidate(); - - // Invalidate SCU copy of TAG RAMs - scu_secure_invalidate(cpu, all_ways); - - // Join SMP - scu_join_smp(); - scu_enable_maintenance_broadcast(); -} - extern void _boot_start(); void cpu_start_secondary(uint8_t coreNumber) { @@ -87,6 +63,8 @@ void cpu_start_secondary(uint8_t coreNumber) HW_SRC_GPR7_WR((uint32_t)&_boot_start); HW_SRC_SCR.B.CORE3_ENABLE = 1; break; + default: + break; } } @@ -125,8 +103,7 @@ int main(void) } show_xizi_bar(); - int cpu_count = NR_CPU; - for (int i = 1; i < cpu_count; i++) { + for (int i = 1; i < NR_CPU; i++) { // start secondary cpus cpu_start_secondary(i); } @@ -143,38 +120,12 @@ int main(void) assert(AchieveResourceTag(&scheduler_rights.mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); - struct TraceTag main_icache_tag, main_dcache_tag; - AchieveResourceTag(&main_icache_tag, &hardkernel_tag, "icache-ac-resource"); - AchieveResourceTag(&main_dcache_tag, &hardkernel_tag, "dcache-ac-resource"); - struct ICacheDone* p_icache_driver = AchieveResource(&main_icache_tag); - struct DCacheDone* p_dcache_driver = AchieveResource(&main_dcache_tag); - core_init_done |= (1 << cpu_id); LOG_PRINTF("CPU %d init done\n", cpu_id); spinlock_unlock(&whole_kernel_lock); while (core_init_done != (1 << NR_CPU) - 1) ; - DEBUG_PRINTF("%d", cpu_id); - - // scu_enable(); - // configure_cpu(cpu_id); - // p_dcache_driver->enable(); - // p_icache_driver->enable(); - - // spinlock_lock(&whole_kernel_lock); - // p_dcache_driver->flushall(); - // spinlock_unlock(&whole_kernel_lock); - - // while (true) { - // spinlock_lock(&whole_kernel_lock); - // DEBUG("CPU: %d\n", cpu_id); - // secondary_cpu_load_kern_pgdir(&scheduler_rights.mmu_driver_tag, NULL); - // CLEARTLB(0); - // p_dcache_driver->flushall(); - // spinlock_unlock(&whole_kernel_lock); - // } - xizi_task_manager.task_scheduler(scheduler_rights); // never reached diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index 84d21bc02..4d8f9b613 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -106,7 +106,7 @@ int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, cha for (int addr_offset = 0; addr_offset < ph.filesz; addr_offset += PAGE_SIZE) { uintptr_t page_paddr = xizi_pager.address_translate(&pgdir, ph.vaddr + addr_offset); if (page_paddr == 0) { - ERROR("copy elf file to unmapped addr"); + ERROR("copy elf file to unmapped addr\n"); goto error_exec; } uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE); From 620965dc2c42e3e80b693afa09e916b00d1bc1f4 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Tue, 19 Mar 2024 10:22:02 +0800 Subject: [PATCH 10/24] Fix one dabort and iabort lock bug. --- .../intr/arm/armv7-a/cortex-a9/error_debug.c | 4 ++-- .../intr/arm/armv7-a/cortex-a9/spinlock.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index dc1ca496f..318307211 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -95,7 +95,7 @@ void handle_undefined_instruction(struct trapframe* tf) extern void context_switch(struct context**, struct context*); void dabort_handler(struct trapframe* r) { - if (!is_spinlock_locked(&whole_kernel_lock)) { + if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) { spinlock_lock(&whole_kernel_lock); } uint32_t dfs, dfa; @@ -122,7 +122,7 @@ void dabort_handler(struct trapframe* r) void iabort_handler(struct trapframe* r) { - if (!is_spinlock_locked(&whole_kernel_lock)) { + if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) { spinlock_lock(&whole_kernel_lock); } uint32_t ifs, ifa; diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c index de844c1b1..05098c6d1 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c @@ -68,22 +68,22 @@ void spinlock_lock(struct spinlock* lock) ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu); panic(""); } - // _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); - // doubleListAddOnBack(&core_lock_request[cur_cpuid()].node, &lock_request_guard); - // _spinlock_unlock(&request_lock); + _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); + doubleListAddOnBack(&core_lock_request[cur_cpuid()].node, &lock_request_guard); + _spinlock_unlock(&request_lock); - // while (lock_request_guard.next != &core_lock_request[cur_cpuid()].node) - // ; + while (lock_request_guard.next != &core_lock_request[cur_cpuid()].node) + ; _spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER); } void spinlock_unlock(struct spinlock* lock) { - // assert(lock_request_guard.next == &core_lock_request[cur_cpuid()].node); - // _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); - // _double_list_del(core_lock_request[cur_cpuid()].node.prev, core_lock_request[cur_cpuid()].node.next); - // _spinlock_unlock(&request_lock); + assert(lock_request_guard.next == &core_lock_request[cur_cpuid()].node); + _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); + _double_list_del(core_lock_request[cur_cpuid()].node.prev, core_lock_request[cur_cpuid()].node.next); + _spinlock_unlock(&request_lock); _spinlock_unlock(lock); } From 0f5527d73aa1bd0000588322b95875f780c3f8f0 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Thu, 21 Mar 2024 14:54:52 +0800 Subject: [PATCH 11/24] Support smp for imx6q-sabrelite. --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 + .../preboot_for_imx6q-sabrelite/Makefile | 7 +- .../preboot_for_imx6q-sabrelite/smp.c | 81 +++++++++++++++++++ .../preboot_for_zynq7000-zc702/Makefile | 2 +- .../preboot_for_zynq7000-zc702/smp.c | 60 ++++++++++++++ .../intr/arm/armv7-a/cortex-a9/error_debug.c | 4 +- .../cortex-a9/zynq7000-zc702/trap_common.c | 6 +- .../boards/imx6q-sabrelite/usyscall.c | 5 ++ .../boards/imx6q-sabrelite/usyscall.h | 3 + .../services/boards/zynq7000-zc702/usyscall.c | 5 ++ .../services/boards/zynq7000-zc702/usyscall.h | 3 + .../services/shell/letter-shell/shell.c | 5 ++ .../shell/letter-shell/shell_cmd_list.c | 4 + .../XiZi_AIoT/softkernel/include/syscall.h | 5 +- Ubiquitous/XiZi_AIoT/softkernel/main.c | 31 +------ .../XiZi_AIoT/softkernel/syscall/Makefile | 3 +- .../XiZi_AIoT/softkernel/syscall/sys_exit.c | 24 +++--- .../XiZi_AIoT/softkernel/syscall/sys_kill.c | 50 ++++++++++++ .../XiZi_AIoT/softkernel/syscall/syscall.c | 6 +- .../softkernel/trap/default_irq_handler.c | 3 +- .../softkernel/trap/software_irq_handler.c | 5 +- 21 files changed, 257 insertions(+), 57 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/smp.c create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/smp.c create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index c877945ce..11043cb7c 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -193,4 +193,6 @@ __attribute__((__always_inline__)) static inline void arch_set_return(struct tra tf->r0 = (uint32_t)ret; } +void cpu_start_secondary(uint8_t cpu_id); +void start_smp_cache_broadcast(int cpu_id); #endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/Makefile index c03a9757d..4d0deb874 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/Makefile @@ -1,3 +1,8 @@ -SRC_FILES := ivt.c dcd.c imx6q_lowlevel_init.S cortexA9.S boot.S +SRC_FILES := ivt.c \ + dcd.c \ + boot.S \ + imx6q_lowlevel_init.S \ + cortexA9.S \ + smp.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/smp.c b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/smp.c new file mode 100644 index 000000000..2d16645cf --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_imx6q-sabrelite/smp.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file smp.c + * @brief start multicore + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2024.03.10 + */ + +/************************************************* +File name: smp.c +Description: +Others: +History: +1. Date: 2024-03-10 +Author: AIIT XUOS Lab +Modification: +1. No modifications +*************************************************/ +#include "cortex_a9.h" +#include "regssrc.h" + +extern void _boot_start(); +void cpu_start_secondary(uint8_t cpu_id) +{ + // Prepare pointers for ROM code. The entry point is always _start, which does some + // basic preparatory work and then calls the common_cpu_entry function, which itself + // calls the entry point saved in s_core_info. + switch (cpu_id) { + case 1: + HW_SRC_GPR3_WR((uint32_t)&_boot_start); + HW_SRC_SCR.B.CORE1_ENABLE = 1; + break; + + case 2: + HW_SRC_GPR5_WR((uint32_t)&_boot_start); + HW_SRC_SCR.B.CORE2_ENABLE = 1; + break; + + case 3: + HW_SRC_GPR7_WR((uint32_t)&_boot_start); + HW_SRC_SCR.B.CORE3_ENABLE = 1; + break; + default: + break; + } +} + +void start_smp_cache_broadcast(int cpu_id) +{ + return; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/Makefile index 3fa7398fe..93ee942b5 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := boot.S cpu_init.S xil-crt0.S cortexA9.S +SRC_FILES := boot.S cpu_init.S xil-crt0.S cortexA9.S smp.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/smp.c b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/smp.c new file mode 100644 index 000000000..e5e268e68 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/smp.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010-2012, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file smp.c + * @brief start multicore + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2024.03.10 + */ + +/************************************************* +File name: smp.c +Description: +Others: +History: +1. Date: 2024-03-10 +Author: AIIT XUOS Lab +Modification: +1. No modifications +*************************************************/ +#include "cortex_a9.h" + +extern void _boot_start(); +void cpu_start_secondary(uint8_t cpu_id) +{ + return; +} + +void start_smp_cache_broadcast(int cpu_id) +{ + return; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index 318307211..7d18f0156 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -109,7 +109,7 @@ void dabort_handler(struct trapframe* r) LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); _abort_reason(dfs); dump_tf(r); - sys_exit(); + sys_exit(cur_cpu()->task); context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); } else { // Exception occured in Kernel space: panic LOG("program counter: 0x%x caused\n", r->pc); @@ -136,7 +136,7 @@ void iabort_handler(struct trapframe* r) LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); _abort_reason(ifs); dump_tf(r); - sys_exit(); + sys_exit(cur_cpu()->task); context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); } else { // Exception occured in Kernel space: panic LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c index 754828883..eed662bd2 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c @@ -87,6 +87,8 @@ void handle_fiq(void) static void _sys_irq_init(int cpu_id) { + + init_cpu_mode_stacks(cpu_id); if (cpu_id == 0) { /* load exception vectors */ volatile uint32_t* vector_base = &_vector_start; @@ -101,8 +103,6 @@ static void _sys_irq_init(int cpu_id) vector_base[7] = (uint32_t)handle_fiq; // FIQ } - init_cpu_mode_stacks(cpu_id); - /* active hardware irq responser */ XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID); if (NULL == gic_config) { @@ -244,7 +244,7 @@ static struct XiziTrapDriver xizi_trap_driver = { struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag) { - xizi_trap_driver.sys_irq_init(); + xizi_trap_driver.sys_irq_init(0); xizi_trap_driver.cpu_irq_enable(); return &xizi_trap_driver; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c index d2f03b56d..86a92e24e 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c @@ -58,6 +58,11 @@ int yield() return syscall(SYSCALL_YIELD, 0, 0, 0, 0); } +int kill(int pid) +{ + return syscall(SYSCALL_KILL, (intptr_t)pid, 0, 0, 0); +} + int register_server(char* name) { return syscall(SYSCALL_SERVER, (intptr_t)name, 0, 0, 0); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h index 40bb944ca..326739a37 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h @@ -30,6 +30,8 @@ #define SYSCALL_EXEC 9 // run elf using current task #define SYSCALL_SYS_STATE 10 // run system state #define SYSCALL_REGISTER_IRQ 11 // + +#define SYSCALL_KILL 12 // kill the task by id // clang-format on typedef enum { @@ -57,6 +59,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv); int exit(); int yield(); +int kill(int pid); int register_server(char* name); int session(char* path, int capacity, struct Session* user_session); int poll_session(struct Session* userland_session_arr, int arr_capacity); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c index d2f03b56d..86a92e24e 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c @@ -58,6 +58,11 @@ int yield() return syscall(SYSCALL_YIELD, 0, 0, 0, 0); } +int kill(int pid) +{ + return syscall(SYSCALL_KILL, (intptr_t)pid, 0, 0, 0); +} + int register_server(char* name) { return syscall(SYSCALL_SERVER, (intptr_t)name, 0, 0, 0); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h index 40bb944ca..326739a37 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h @@ -30,6 +30,8 @@ #define SYSCALL_EXEC 9 // run elf using current task #define SYSCALL_SYS_STATE 10 // run system state #define SYSCALL_REGISTER_IRQ 11 // + +#define SYSCALL_KILL 12 // kill the task by id // clang-format on typedef enum { @@ -57,6 +59,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv); int exit(); int yield(); +int kill(int pid); int register_server(char* name); int session(char* path, int capacity, struct Session* user_session); int poll_session(struct Session* userland_session_arr, int arr_capacity); diff --git a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c index 31b3d538b..d7588636c 100644 --- a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c +++ b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell.c @@ -1725,6 +1725,11 @@ int shellRun(Shell* shell, const char* cmd) } } +void shellKill(int pid) +{ + kill(pid); +} + /** * @brief ls 打印当前路径下所有文件(文件系统调用) */ diff --git a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c index 266c9747c..762abed40 100644 --- a/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c +++ b/Ubiquitous/XiZi_AIoT/services/shell/letter-shell/shell_cmd_list.c @@ -36,6 +36,7 @@ extern void shellMkdir(const char* path); extern void shellRm(const char* path); extern void shellCat(const char* path); +extern void shellKill(int pid); extern void shellShowTasks(); extern void shellShowMemInfo(); extern void shellShowCpusInfo(); @@ -97,8 +98,11 @@ const ShellCommand shellCommandList[] = { SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN, sh, SHELL_AGENCY_FUNC_NAME(shellRun), run command directly), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN, + kill, shellKill, kill task by id), SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN, ls, shellLs, ls files), + SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN, cd, shellCd, go to target path), SHELL_CMD_ITEM(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | SHELL_CMD_DISABLE_RETURN, diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h index e564312cc..aa78cbf39 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h @@ -44,6 +44,8 @@ Modification: #define SYSCALL_EXEC 9 // run elf using current task #define SYSCALL_SYS_STATE 10 // run system state #define SYSCALL_REGISTER_IRQ 11 // + +#define SYSCALL_KILL 12 // kill the task by id // clang-format on #ifndef __ASSEMBLER__ @@ -77,8 +79,9 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4); int sys_spawn(char* img_start, char* name, char** argv); -int sys_exit(); +int sys_exit(struct TaskMicroDescriptor* ptask); int sys_yield(); +int sys_kill(int id); int sys_register_as_server(char* name); int sys_connect_session(char* path, int capacity, struct Session* user_session); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 289ee4d7e..5bf2df67a 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -28,8 +28,6 @@ Modification: 1. first version *************************************************/ /// @todo use hardkernel -#include "cortex_a9.h" -#include "regssrc.h" #include "kern_init.h" #include "multicores.h" @@ -37,37 +35,9 @@ Modification: #include "assert.h" #include "task.h" -#include "cache_common_ope.h" - extern uint32_t _binary_init_start[], _binary_default_fs_start[]; static struct TraceTag hardkernel_tag, softkernel_tag; -extern void _boot_start(); -void cpu_start_secondary(uint8_t coreNumber) -{ - // Prepare pointers for ROM code. The entry point is always _start, which does some - // basic preparatory work and then calls the common_cpu_entry function, which itself - // calls the entry point saved in s_core_info. - switch (coreNumber) { - case 1: - HW_SRC_GPR3_WR((uint32_t)&_boot_start); - HW_SRC_SCR.B.CORE1_ENABLE = 1; - break; - - case 2: - HW_SRC_GPR5_WR((uint32_t)&_boot_start); - HW_SRC_SCR.B.CORE2_ENABLE = 1; - break; - - case 3: - HW_SRC_GPR7_WR((uint32_t)&_boot_start); - HW_SRC_SCR.B.CORE3_ENABLE = 1; - break; - default: - break; - } -} - static int core_init_done = 0; int main(void) { @@ -126,6 +96,7 @@ int main(void) while (core_init_done != (1 << NR_CPU) - 1) ; + start_smp_cache_broadcast(cpu_id); xizi_task_manager.task_scheduler(scheduler_rights); // never reached diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile index 90620a162..4fd4eb8f8 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile @@ -9,6 +9,7 @@ SRC_FILES := syscall.c \ sys_register_irq.c \ sys_exit.c \ sys_state.c \ - sys_mmap.c + sys_mmap.c \ + sys_kill.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c index 274ae6f24..bd5a99612 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c @@ -36,20 +36,18 @@ Modification: #include "syscall.h" #include "task.h" -int sys_exit() +int sys_exit(struct TaskMicroDescriptor* ptask) { - - struct TaskMicroDescriptor* cur_task = cur_cpu()->task; - assert(cur_task != NULL); + assert(ptask != NULL); /* handle sessions for condition 1, ref. delete_share_pages() */ // close all server_sessions struct server_session* server_session = NULL; - while (!IS_DOUBLE_LIST_EMPTY(&cur_task->svr_sess_listhead)) { - server_session = CONTAINER_OF(cur_task->svr_sess_listhead.next, struct server_session, node); + while (!IS_DOUBLE_LIST_EMPTY(&ptask->svr_sess_listhead)) { + server_session = CONTAINER_OF(ptask->svr_sess_listhead.next, struct server_session, node); // cut the connection from task to session if (!server_session->closed) { - xizi_share_page_manager.unmap_task_share_pages(cur_task, server_session->buf_addr, CLIENT_SESSION_BACKEND(server_session)->nr_pages); + xizi_share_page_manager.unmap_task_share_pages(ptask, server_session->buf_addr, CLIENT_SESSION_BACKEND(server_session)->nr_pages); server_session->closed = true; } doubleListDel(&server_session->node); @@ -61,11 +59,11 @@ int sys_exit() } // close all client_sessions struct client_session* client_session = NULL; - while (!IS_DOUBLE_LIST_EMPTY(&cur_task->cli_sess_listhead)) { - client_session = CONTAINER_OF(cur_task->cli_sess_listhead.next, struct client_session, node); + while (!IS_DOUBLE_LIST_EMPTY(&ptask->cli_sess_listhead)) { + client_session = CONTAINER_OF(ptask->cli_sess_listhead.next, struct client_session, node); // cut the connection from task to session if (!client_session->closed) { - xizi_share_page_manager.unmap_task_share_pages(cur_task, client_session->buf_addr, CLIENT_SESSION_BACKEND(client_session)->nr_pages); + xizi_share_page_manager.unmap_task_share_pages(ptask, client_session->buf_addr, CLIENT_SESSION_BACKEND(client_session)->nr_pages); client_session->closed = true; } doubleListDel(&client_session->node); @@ -76,16 +74,16 @@ int sys_exit() } } - if (cur_task->server_identifier.meta != NULL) { + if (ptask->server_identifier.meta != NULL) { struct TraceTag server_identifier_owner; AchieveResourceTag(&server_identifier_owner, RequireRootTag(), "softkernel/server-identifier"); assert(server_identifier_owner.meta != NULL); - DeleteResource(&cur_task->server_identifier, &server_identifier_owner); + DeleteResource(&ptask->server_identifier, &server_identifier_owner); } // delete task for pcb_list xizi_task_manager.cur_task_yield_noschedule(); - cur_task->state = DEAD; + ptask->state = DEAD; return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c new file mode 100644 index 000000000..5d9bef5c8 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_kill.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +/** + * @file sys_kill.c + * @brief task exit syscall + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2024.03.19 + */ + +/************************************************* +File name: sys_kill.c +Description: task kill syscall +Others: +History: +1. Date: 2023-03-19 +Author: AIIT XUOS Lab +Modification: +1. first version +*************************************************/ +#include "trap_common.h" + +#include "task.h" + +extern int sys_exit(struct TaskMicroDescriptor* task); +int sys_kill(int id) +{ + struct TaskMicroDescriptor* task = NULL; + + for (int prio = 0; prio < TASK_MAX_PRIORITY; prio++) { + DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[prio], node) + { + if (task->pid == id) { + sys_exit(task); + return 0; + } + } + } + + return -1; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c index 34ebd827d..5e3de560c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c @@ -28,6 +28,7 @@ Modification: 1. first version *************************************************/ #include "log.h" +#include "multicores.h" #include "trap_common.h" #include "syscall.h" @@ -44,7 +45,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u ret = sys_spawn((char*)param1, (char*)param2, (char**)param3); break; case SYSCALL_EXIT: - ret = sys_exit(); + ret = sys_exit(cur_cpu()->task); break; case SYSCALL_YIELD: ret = sys_yield(); @@ -73,6 +74,9 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u case SYSCALL_REGISTER_IRQ: ret = sys_register_irq((int)param1, (int)param2); break; + case SYSCALL_KILL: + ret = sys_kill((int)param1); + break; default: ERROR("Unsurport syscall(%d) right now\n", sys_num); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index 213ab28df..ad0aa6d40 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -88,7 +88,8 @@ void intr_irq_dispatch(struct trapframe* tf) p_intr_driver->curr_int[cpu] = 0; p_intr_driver->hw_after_irq(int_info); - if (UNLIKELY(cur_cpu()->task == NULL && current_task != NULL)) { + if ((cur_cpu()->task == NULL && current_task != NULL) || current_task->state != RUNNING) { + cur_cpu()->task = NULL; context_switch(¤t_task->main_thread.context, cur_cpu()->scheduler); } assert(current_task == cur_cpu()->task); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index 623d01309..f462c44e0 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -68,11 +68,10 @@ void software_irq_dispatch(struct trapframe* tf) if (syscall_num != SYSCALL_EXEC) { arch_set_return(tf, ret); } - } else { - ERROR("syscall by killed task.\n"); } - if (cur_cpu()->task == NULL && cur_task != NULL) { + if ((cur_cpu()->task == NULL && cur_task != NULL) || cur_task->state != RUNNING) { + cur_cpu()->task = NULL; context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler); } assert(cur_task == cur_cpu()->task); From 8f3df1e5c2f5acf10c600cbcbafe46b781b9cd8e Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Tue, 26 Mar 2024 09:39:20 +0800 Subject: [PATCH 12/24] clean unnecessary lock initialization in kernel --- .../cortex-a9/preboot_for_zynq7000-zc702/zynq7000-zc702.lds | 1 - Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c | 1 - Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c | 3 --- Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c | 1 - Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c | 1 + Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 3 --- 6 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/zynq7000-zc702.lds b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/zynq7000-zc702.lds index e7293cbfe..209d96510 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/zynq7000-zc702.lds +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_zynq7000-zc702/zynq7000-zc702.lds @@ -72,7 +72,6 @@ SECTIONS PROVIDE(boot_end_addr = .); } > ddr3 - /* Other Kernel code is placed over 0x80000000 + 128KB. */ .text : AT(0x00110000) { *(.vectors) . = ALIGN(0x1000); diff --git a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c index 3c9894d59..44909c21e 100644 --- a/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c +++ b/Ubiquitous/XiZi_AIoT/kernel_actracer/actracer_mem_chunk.c @@ -61,7 +61,6 @@ static void tracer_mem_chunk_sync(struct tracer_mem_chunk* b) void mem_chunk_synchronizer_init(uintptr_t mem_chunk_base, uint32_t mem_chunk_size, uint32_t nr_mem_chunks) { - spinlock_init(&tracer_mem_chunk_syner.lock, "tracer_mem_chunk_syner"); tracer_mem_chunk_syner.mem_chunk_base = mem_chunk_base; tracer_mem_chunk_syner.mem_chunk_size = mem_chunk_size; tracer_mem_chunk_syner.nr_mem_chunks = nr_mem_chunks; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c index ed5dd8494..7b263a625 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c @@ -144,9 +144,6 @@ void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) struct KPage* page = NULL; struct KFreeList* free_list = NULL; - // init spinlock - spinlock_init(&pbuddy->lock, "kbuddy"); - // init global kernel Buddy system pbuddy->mem_start = mem_start; pbuddy->mem_end = mem_end; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index 4d8f9b613..185f21da6 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -200,7 +200,6 @@ int sys_exec(char* img_start, char* name, char** argv) struct TaskMicroDescriptor* current_task = cur_cpu()->task; int ret = task_exec(current_task, img_start, name, argv); if (ret >= 0) { - spinlock_init(¤t_task->lock, current_task->name); p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr)); return ret; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c index 1e96a65c3..1ed2965b5 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c @@ -74,6 +74,7 @@ int user_irq_handler(int irq, void* tf, void* arg) } extern int create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session); +/// @warning no tested. int sys_register_irq(int irq_num, int irq_opcode) { static struct TraceTag intr_ac_tag; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 525e66544..277422fae 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -43,8 +43,6 @@ uint32_t ready_task_priority; static void _task_manager_init() { - // init lock for task list - spinlock_init(&xizi_task_manager.lock, "proclist"); // init task list to NULL for (int i = 0; i < TASK_MAX_PRIORITY; i++) { doubleListNodeInit(&xizi_task_manager.task_list_head[i]); @@ -159,7 +157,6 @@ static struct TaskMicroDescriptor* _new_task_cb() static void _task_set_default_schedule_attr(struct TaskMicroDescriptor* task, struct TraceTag* cwd) { - spinlock_init(&task->lock, task->name); task->remain_tick = TASK_CLOCK_TICK; task->maxium_tick = TASK_CLOCK_TICK * 10; task->state = READY; From f5ad8437b5854ac55c3fd0b5f7561285af2cb51d Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Tue, 26 Mar 2024 10:05:02 +0800 Subject: [PATCH 13/24] use common spinlock.c --- .../armv7-a/cortex-a9/imx6q-sabrelite/clock.c | 21 +++++++++++++++++-- Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile | 1 + .../intr/arm/armv7-a/cortex-a9/Makefile | 3 +-- .../{arm/armv7-a/cortex-a9 => }/spinlock.c | 5 ++--- 4 files changed, 23 insertions(+), 7 deletions(-) rename Ubiquitous/XiZi_AIoT/hardkernel/intr/{arm/armv7-a/cortex-a9 => }/spinlock.c (99%) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c index 2ac07efe0..123093c1d 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c @@ -34,13 +34,30 @@ Modification: #include "clock_common_op.h" #include "irq_numbers.h" +#include "multicores.h" static void _sys_clock_init() { uint32_t freq = get_main_clock(IPG_CLK); gpt_init(CLKSRC_IPG_CLK, freq / 1000000, RESTART_MODE, WAIT_MODE_EN | STOP_MODE_EN); - gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); - gpt_counter_enable(kGPTOutputCompare1); + switch (cur_cpuid()) { + case 0: + gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); + gpt_counter_enable(kGPTOutputCompare1); + break; + case 1: + gpt_set_compare_event(kGPTOutputCompare2, OUTPUT_CMP_DISABLE, 1000); + gpt_counter_enable(kGPTOutputCompare2); + break; + case 2: + gpt_set_compare_event(kGPTOutputCompare3, OUTPUT_CMP_DISABLE, 1000); + gpt_counter_enable(kGPTOutputCompare3); + break; + case 3: + gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); + gpt_counter_enable(kGPTOutputCompare1); + break; + } } static uint32_t _get_clock_int() diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile index 7e69489a2..b199fd1e3 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/Makefile @@ -1,3 +1,4 @@ SRC_DIR := arm/armv7-a/cortex-a9 +SRC_FILES := spinlock.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/Makefile index 8ea2c7e2f..ebcd0d1ff 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/Makefile @@ -1,5 +1,5 @@ -SRC_FILES := vector.S trampoline.S $(BOARD)/trap_common.c error_debug.c spinlock.c hard_spinlock.S +SRC_FILES := vector.S trampoline.S $(BOARD)/trap_common.c error_debug.c hard_spinlock.S ifeq ($(BOARD), imx6q-sabrelite) SRC_DIR := gicv2 @@ -9,7 +9,6 @@ ifeq ($(BOARD), zynq7000-zc702) # SRC_DIR := gicv2 SRC_DIR := gicv3 SRC_FILES += $(BOARD)/xil_assert.c -# SRC_FILES := vector.S trampoline.S imx6q-sabrelite/trap_common.c error_debug.c spinlock.c hard_spinlock.S endif diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c similarity index 99% rename from Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c rename to Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c index 05098c6d1..210edfabd 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/spinlock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c @@ -19,13 +19,12 @@ #include #include -#include "assert.h" -#include "multicores.h" #include "spinlock.h" -#include "task.h" #include "trap_common.h" +#include "assert.h" #include "list.h" +#include "multicores.h" struct lock_node { int cpu_id; From a2e5b49b1999591533f61844ced682ce86da6922 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Tue, 2 Apr 2024 10:56:28 +0800 Subject: [PATCH 14/24] fix sys_poll_session performance bug. --- .../armv7-a/cortex-a9/imx6q-sabrelite/clock.c | 23 ++- .../intr/arm/armv7-a/cortex-a9/error_debug.c | 6 + .../cortex-a9/imx6q-sabrelite/trap_common.c | 2 +- Ubiquitous/XiZi_AIoT/softkernel/include/log.h | 1 + .../XiZi_AIoT/softkernel/include/task.h | 45 +++--- Ubiquitous/XiZi_AIoT/softkernel/main.c | 7 +- .../XiZi_AIoT/softkernel/memory/share_page.c | 8 + .../XiZi_AIoT/softkernel/syscall/sys_exec.c | 8 +- .../XiZi_AIoT/softkernel/syscall/sys_mmap.c | 2 + .../softkernel/syscall/sys_poll_session.c | 35 ++-- .../XiZi_AIoT/softkernel/syscall/sys_spawn.c | 2 +- .../XiZi_AIoT/softkernel/syscall/sys_state.c | 6 +- Ubiquitous/XiZi_AIoT/softkernel/task/Makefile | 2 +- .../softkernel/task/spawn_default_task.c | 151 ------------------ Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 6 +- 15 files changed, 81 insertions(+), 223 deletions(-) delete mode 100644 Ubiquitous/XiZi_AIoT/softkernel/task/spawn_default_task.c diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c index 123093c1d..f2c71ea4a 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c @@ -46,16 +46,14 @@ static void _sys_clock_init() gpt_counter_enable(kGPTOutputCompare1); break; case 1: - gpt_set_compare_event(kGPTOutputCompare2, OUTPUT_CMP_DISABLE, 1000); + gpt_set_compare_event(kGPTOutputCompare2, OUTPUT_CMP_DISABLE, 5000); gpt_counter_enable(kGPTOutputCompare2); break; case 2: - gpt_set_compare_event(kGPTOutputCompare3, OUTPUT_CMP_DISABLE, 1000); + gpt_set_compare_event(kGPTOutputCompare3, OUTPUT_CMP_DISABLE, 10000); gpt_counter_enable(kGPTOutputCompare3); break; - case 3: - gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); - gpt_counter_enable(kGPTOutputCompare1); + default: break; } } @@ -77,7 +75,20 @@ static uint64_t _get_second() static void _clear_clock_intr() { - gpt_get_compare_event(kGPTOutputCompare1); + switch (cur_cpuid()) { + case 0: + gpt_get_compare_event(kGPTOutputCompare1); + break; + case 1: + gpt_get_compare_event(kGPTOutputCompare2); + break; + case 2: + gpt_get_compare_event(kGPTOutputCompare3); + break; + case 3: + gpt_get_compare_event(kGPTOutputCompare1); + break; + } } static bool _is_timer_expired() diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index 7d18f0156..8593903c9 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -116,6 +116,9 @@ void dabort_handler(struct trapframe* r) LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); _abort_reason(dfs); dump_tf(r); + if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) { + spinlock_unlock(&whole_kernel_lock); + } panic("data abort exception\n"); } } @@ -143,6 +146,9 @@ void iabort_handler(struct trapframe* r) LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); _abort_reason(ifs); dump_tf(r); + if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) { + spinlock_unlock(&whole_kernel_lock); + } panic("prefetch abort exception\n"); } } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index bbc62cc7e..258b8ec22 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -94,7 +94,7 @@ static void _sys_irq_init(int cpu_id) // Set Interrupt handler start address vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt - vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort + // vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort vector_base[4] = (uint32_t)trap_dabort; // Data Abort vector_base[5] = (uint32_t)handle_reserved; // Reserved vector_base[6] = (uint32_t)trap_irq_enter; // IRQ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/log.h b/Ubiquitous/XiZi_AIoT/softkernel/include/log.h index 22640817c..8b871fc9a 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/log.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/log.h @@ -34,6 +34,7 @@ Modification: #define OUTPUT_LEVLE_ERROR 2 #define OUTPUT_LEVLE OUTPUT_LEVLE_DEBUG +// #define OUTPUT_LEVLE OUTPUT_LEVLE_LOG extern void KPrintf(char* fmt, ...); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index adc872da6..d79233c9c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -59,33 +59,35 @@ struct Thread { /* Process Control Block */ struct TaskMicroDescriptor { - struct double_list_node node; - - struct spinlock lock; - /* task->lock needed */ + /* task debug resources */ int pid; + char name[TASK_NAME_MAX_LEN]; + + /// @todo support return value + int ret; // state val that be returned to parent /// @todo support parent struct TaskMicroDescriptor* parent; - enum ProcState state; - /// @todo support ret value - int ret; // state val that be returned to parent + + /* task context resources */ + struct Thread main_thread; // will only access by task itself + + /* task memory resources */ struct TopLevelPageDirectory pgdir; // [phy] vm pgtbl base address + uintptr_t heap_base; // mem size of proc used(allocated by kernel) + /// @todo support heap_base + uintptr_t mem_size; + + /* task communication resources */ struct double_list_node cli_sess_listhead; struct double_list_node svr_sess_listhead; struct TraceTag server_identifier; - /* task->lock not necessary */ - struct Thread main_thread; // will only access by task itself + /* task schedule attributes */ + struct double_list_node node; + enum ProcState state; + int priority; // priority int remain_tick; int maxium_tick; - - struct TraceTag cwd; // current directory - - int priority; // priority - - /// @todo support mem_size - uintptr_t mem_size; // mem size of proc used(allocated by kernel) - char name[TASK_NAME_MAX_LEN]; }; struct SchedulerRightGroup { @@ -94,17 +96,10 @@ struct SchedulerRightGroup { }; struct XiziTaskManager { - struct spinlock lock; // lock to organize free and used task list struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */ - int nr_pcb_used; // for debug struct slab_allocator task_allocator; - - /// @todo Add pid to task uint32_t next_pid; - /* number of tcbs in which one page contains */ - int nr_tcb_per_page; - /* init task manager */ void (*init)(); /* new a task control block, checkout #sys_spawn for usage */ @@ -112,7 +107,7 @@ struct XiziTaskManager { /* free a task control block, this calls #free_user_pgdir to free all vitual spaces */ void (*free_pcb)(struct TaskMicroDescriptor*); /* init a task control block, set name, remain_tick, state, cwd, priority, etc. */ - void (*task_set_default_schedule_attr)(struct TaskMicroDescriptor*, struct TraceTag* cwd); + void (*task_set_default_schedule_attr)(struct TaskMicroDescriptor*); /* use by task_scheduler, find next READY task, should be in locked */ struct TaskMicroDescriptor* (*next_runnable_task)(void); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index 5bf2df67a..a3de7b8aa 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -36,8 +36,9 @@ Modification: #include "task.h" extern uint32_t _binary_init_start[], _binary_default_fs_start[]; -static struct TraceTag hardkernel_tag, softkernel_tag; +extern int sys_spawn(char* img_start, char* name, char** argv); +static struct TraceTag hardkernel_tag, softkernel_tag; static int core_init_done = 0; int main(void) { @@ -80,9 +81,9 @@ int main(void) /* start first task */ char* init_task_param[2] = { "/app/init", 0 }; - spawn_embedded_task((char*)_binary_init_start, "init", init_task_param); + sys_spawn((char*)_binary_init_start, "init", init_task_param); char* fs_server_task_param[2] = { "/app/fs_server", 0 }; - spawn_embedded_task((char*)_binary_default_fs_start, "memfs", fs_server_task_param); + sys_spawn((char*)_binary_default_fs_start, "memfs", fs_server_task_param); } /* start scheduler */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c index 335c28879..1ea0713de 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c @@ -178,12 +178,14 @@ struct session_backend* create_share_pages(struct TaskMicroDescriptor* client, s uintptr_t client_vaddr = map_task_share_page(client, V2P_WO(kern_vaddr), nr_pages); if (UNLIKELY(client_vaddr == 0)) { kfree((char*)kern_vaddr); + slab_free(SessionAllocator(), session_backend); return NULL; } uintptr_t server_vaddr = map_task_share_page(server, V2P_WO(kern_vaddr), nr_pages); if (UNLIKELY(server_vaddr == 0)) { unmap_task_share_pages(client, client_vaddr, nr_pages); kfree((char*)kern_vaddr); + slab_free(SessionAllocator(), session_backend); return NULL; } @@ -208,6 +210,9 @@ struct session_backend* create_share_pages(struct TaskMicroDescriptor* client, s doubleListNodeInit(&session_backend->server_side.node); doubleListAddOnBack(&session_backend->server_side.node, &server->svr_sess_listhead); + server->mem_size += true_capacity; + client->mem_size += true_capacity; + return session_backend; } @@ -232,6 +237,9 @@ int delete_share_pages(struct session_backend* session_backend) doubleListDel(&session_backend->server_side.node); } + session_backend->server->mem_size -= session_backend->nr_pages * PAGE_SIZE; + session_backend->client->mem_size -= session_backend->nr_pages * PAGE_SIZE; + /* free seesion backend */ kfree((void*)session_backend->buf_kernel_addr); slab_free(SessionAllocator(), (void*)session_backend); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index 185f21da6..8dc8a6945 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -169,13 +169,11 @@ int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, cha } strncpy(task->name, last, sizeof(task->name)); - struct TopLevelPageDirectory old_pgdir = task->pgdir; + xizi_pager.free_user_pgdir(&task->pgdir); task->pgdir = pgdir; - /// @todo record mem size used b task - task->mem_size = ALIGNUP(load_size, PAGE_SIZE); - - xizi_pager.free_user_pgdir(&old_pgdir); + task->heap_base = ALIGNUP(load_size, PAGE_SIZE); + task->mem_size = task->heap_base + USER_STACK_SIZE; return 0; error_exec: diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c index 0b11adc62..3b2f7e727 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_mmap.c @@ -63,5 +63,7 @@ int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev) load_len += PAGE_SIZE; } } + + cur_task->mem_size += true_len; return vaddr + true_len; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c index 8a3e7b9e4..66275cacb 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c @@ -61,28 +61,6 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) doubleListAddOnBack(cur_node, &cur_task->svr_sess_listhead); } - /* handle sessions for condition 2, ref. delete_share_pages() */ - bool has_delete = true; - while (has_delete) { - has_delete = false; - - DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node) - { - if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) { - // client had closed it, then server will close it too - struct session_backend* session_backend = SERVER_SESSION_BACKEND(server_session); - - if (!session_backend->server_side.closed) { - session_backend->server_side.closed = true; - xizi_share_page_manager.unmap_task_share_pages(cur_task, session_backend->server_side.buf_addr, session_backend->nr_pages); - } - xizi_share_page_manager.delete_share_pages(session_backend); - has_delete = true; - break; - } - } - } - /* poll with new sessions */ int i = 0; DOUBLE_LIST_FOR_EACH_ENTRY(server_session, &cur_task->svr_sess_listhead, node) @@ -90,6 +68,19 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) if (i >= arr_capacity) { break; } + + if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) { + // client had closed it, then server will close it too + struct session_backend* session_backend = SERVER_SESSION_BACKEND(server_session); + + if (!session_backend->server_side.closed) { + session_backend->server_side.closed = true; + xizi_share_page_manager.unmap_task_share_pages(cur_task, session_backend->server_side.buf_addr, session_backend->nr_pages); + } + xizi_share_page_manager.delete_share_pages(session_backend); + break; + } + userland_session_arr[i++] = (struct Session) { .buf = (void*)server_session->buf_addr, .capacity = server_session->capacity, diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c index c4a587aaa..3d473e61b 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_spawn.c @@ -49,7 +49,7 @@ int sys_spawn(char* img_start, char* name, char** argv) return -1; } // init pcb - xizi_task_manager.task_set_default_schedule_attr(new_task_cb, RequireRootTag()); + xizi_task_manager.task_set_default_schedule_attr(new_task_cb); return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c index c37fb65fb..ff9e783e9 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c @@ -65,7 +65,7 @@ void show_tasks(void) } } LOG_PRINTF("******************************************************\n"); - LOG_PRINTF("STAT ID TASK PRI LEFT_TICKS\n"); + LOG_PRINTF("STAT ID TASK PRI MEM(KB)\n"); for (int i = 0; i < TASK_MAX_PRIORITY; i++) { if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[i])) { continue; @@ -82,7 +82,7 @@ void show_tasks(void) LOG_PRINTF(" DEAD "); _padding(task->name); - LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->remain_tick); + LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->mem_size >> 10); } } LOG_PRINTF("******************************************************\n"); @@ -138,7 +138,7 @@ int sys_state(sys_state_option option, sys_state_info* info) info->memblock_info.memblock_start = (uintptr_t)V2P(_binary_fs_img_start); info->memblock_info.memblock_end = (uintptr_t)V2P(_binary_fs_img_end); } else if (option == SYS_STATE_GET_HEAP_BASE) { - return cur_cpu()->task->mem_size; + return cur_cpu()->task->heap_base; } else if (option == SYS_STATE_SET_TASK_PRIORITY) { xizi_task_manager.set_cur_task_priority(info->priority); } else if (option == SYS_STATE_SHOW_TASKS) { diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile index 94bd1ecf3..11d37a8c4 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := task.c scheduler.c spawn_default_task.c +SRC_FILES := task.c scheduler.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/spawn_default_task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/spawn_default_task.c deleted file mode 100644 index 8e1cd6e42..000000000 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/spawn_default_task.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2020 AIIT XUOS Lab - * XiUOS is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ -/** - * @file spawn_default_task.c - * @brief spawn task that embeded in kernel image - * @version 3.0 - * @author AIIT XUOS Lab - * @date 2023.08.25 - */ - -/************************************************* -File name: spawn_default_task.c -Description: spawn task that embeded in kernel image -Others: -History: -1. Date: 2023-08-28 -Author: AIIT XUOS Lab -Modification: -1. first version -*************************************************/ -#include "actracer.h" -#include "assert.h" -#include "kalloc.h" -#include "task.h" - -#include "execelf.h" - -int spawn_embedded_task(char* img_start, char* name, char** argv) -{ - struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb(); - if (UNLIKELY(!new_task_cb)) { - ERROR("Unable to new task control block.\n"); - return -1; - } - // init trapframe - arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0); - - /* load img to task */ - /* 1. load elf header */ - struct elfhdr* elf = (struct elfhdr*)img_start; - // pgdir for new task - struct TopLevelPageDirectory pgdir; - if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) { - ERROR("create new pgdir failed.\n"); - goto error_exec; - } - memcpy(pgdir.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE); - - /* 2. load elf content */ - uint32_t load_size = 0; - struct proghdr ph; - for (int sec_idx = 0, off = elf->phoff; sec_idx < elf->phnum; sec_idx++, off += sizeof(ph)) { - // load proghdr - memcpy((char*)&ph, img_start + off, sizeof(ph)); - - if (ph.type != ELF_PROG_LOAD) - continue; - if (ph.memsz < ph.filesz) { - ERROR("elf header mem size less than file size\n"); - goto error_exec; - } - - // read section - // 1. alloc space - if ((load_size = xizi_pager.resize_user_pgdir(&pgdir, load_size, ph.vaddr + ph.memsz)) - != ph.vaddr + ph.memsz) { - goto error_exec; - } - // 2. copy inode to space - assert(ph.vaddr % PAGE_SIZE == 0); - for (int addr_offset = 0; addr_offset < ph.filesz; addr_offset += PAGE_SIZE) { - uintptr_t page_paddr = xizi_pager.address_translate(&pgdir, ph.vaddr + addr_offset); - if (page_paddr == 0) { - panic("copy elf file to unmapped addr"); - } - uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE); - memcpy(P2V(page_paddr), img_start + (ph.off + addr_offset), read_size); - } - } - - /// elf file content now in memory - // alloc stack page and map to TOP of user vspace - uintptr_t* stack_bottom = (uintptr_t*)kalloc(USER_STACK_SIZE); - if (UNLIKELY(stack_bottom == NULL)) { - ERROR("No memory.\n"); - goto error_exec; - } - xizi_pager.map_pages(pgdir.pd_addr, USER_MEM_TOP - USER_STACK_SIZE, V2P(stack_bottom), USER_STACK_SIZE, false); - - uintptr_t user_vspace_sp = USER_MEM_TOP; - /// @todo change 32 to some macro - uintptr_t user_stack_init[32]; - uintptr_t argc = 0; - uintptr_t copy_len = 0; - for (argc = 0; argv != NULL && argv[argc] != NULL; argc++) { - /// @todo handle with large number of parameters - - // copy param to user stack - copy_len = strlen(argv[argc]) + 1; - user_vspace_sp = (user_vspace_sp - copy_len) & ~3; - uintptr_t copied_len = xizi_pager.cross_vspace_data_copy(&pgdir, user_vspace_sp, (uintptr_t)argv[argc], copy_len); - if (UNLIKELY(copied_len != copy_len)) { - ERROR("Something went wrong when copying params.\n"); - goto error_exec; - } - user_stack_init[argc] = user_vspace_sp; - } - user_stack_init[argc] = 0; - copy_len = (argc + 1) * sizeof(uintptr_t); - user_vspace_sp -= copy_len; - uintptr_t copied_len = xizi_pager.cross_vspace_data_copy(&pgdir, user_vspace_sp, (uintptr_t)user_stack_init, copy_len); - if (UNLIKELY(copied_len != copy_len)) { - ERROR("Something went wrong when copying params.\n"); - goto error_exec; - } - - // init task trapframe, which stores in svc stack - // do not go tp error_exec once we change trapframe! - assert(copied_len == (argc + 1) * sizeof(uintptr_t)); - arch_trapframe_set_sp_pc(new_task_cb->main_thread.trapframe, user_vspace_sp, elf->entry); - arch_set_main_params(new_task_cb->main_thread.trapframe, argc, user_vspace_sp); - - // save program name - strncpy(new_task_cb->name, name, sizeof(new_task_cb->name)); - - struct TopLevelPageDirectory old_pgdir = new_task_cb->pgdir; - new_task_cb->pgdir = pgdir; - - /// @todo record mem size used b task - new_task_cb->mem_size = ALIGNUP(load_size, PAGE_SIZE); - - xizi_pager.free_user_pgdir(&old_pgdir); - - xizi_task_manager.task_set_default_schedule_attr(new_task_cb, RequireRootTag()); - return 0; - -error_exec: - if (pgdir.pd_addr != NULL) { - xizi_pager.free_user_pgdir(&pgdir); - } - return -1; -} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 277422fae..127a3ec9b 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -69,8 +69,6 @@ static struct TaskMicroDescriptor* _alloc_task_cb() // set pid once task is allocated memset(task, 0, sizeof(*task)); task->pid = xizi_task_manager.next_pid++; - // update pcb used - xizi_task_manager.nr_pcb_used += 1; return task; } @@ -98,7 +96,6 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task) // free task back to allocator slab_free(&xizi_task_manager.task_allocator, (void*)task); - xizi_task_manager.nr_pcb_used -= 1; // remove priority if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[task->priority])) { @@ -155,12 +152,11 @@ static struct TaskMicroDescriptor* _new_task_cb() return task; } -static void _task_set_default_schedule_attr(struct TaskMicroDescriptor* task, struct TraceTag* cwd) +static void _task_set_default_schedule_attr(struct TaskMicroDescriptor* task) { task->remain_tick = TASK_CLOCK_TICK; task->maxium_tick = TASK_CLOCK_TICK * 10; task->state = READY; - task->cwd = *cwd; task->priority = TASK_DEFAULT_PRIORITY; doubleListAddOnHead(&task->node, &xizi_task_manager.task_list_head[task->priority]); ready_task_priority |= (1 << task->priority); From fc380de895a3d2e564a119e4d25bda0616a05b4a Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Wed, 24 Apr 2024 10:19:58 +0800 Subject: [PATCH 15/24] Fix some bugs. --- .../armv7-a/cortex-a9/imx6q-sabrelite/clock.c | 32 +------- .../cortex-a9/imx6q-sabrelite/trap_common.c | 6 +- .../intr/arm/armv7-a/cortex-a9/trampoline.S | 82 +++++-------------- .../XiZi_AIoT/softkernel/syscall/sys_exec.c | 6 ++ 4 files changed, 32 insertions(+), 94 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c index f2c71ea4a..6c519f93d 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c @@ -40,22 +40,7 @@ static void _sys_clock_init() { uint32_t freq = get_main_clock(IPG_CLK); gpt_init(CLKSRC_IPG_CLK, freq / 1000000, RESTART_MODE, WAIT_MODE_EN | STOP_MODE_EN); - switch (cur_cpuid()) { - case 0: - gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); - gpt_counter_enable(kGPTOutputCompare1); - break; - case 1: - gpt_set_compare_event(kGPTOutputCompare2, OUTPUT_CMP_DISABLE, 5000); - gpt_counter_enable(kGPTOutputCompare2); - break; - case 2: - gpt_set_compare_event(kGPTOutputCompare3, OUTPUT_CMP_DISABLE, 10000); - gpt_counter_enable(kGPTOutputCompare3); - break; - default: - break; - } + gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); } static uint32_t _get_clock_int() @@ -75,20 +60,7 @@ static uint64_t _get_second() static void _clear_clock_intr() { - switch (cur_cpuid()) { - case 0: - gpt_get_compare_event(kGPTOutputCompare1); - break; - case 1: - gpt_get_compare_event(kGPTOutputCompare2); - break; - case 2: - gpt_get_compare_event(kGPTOutputCompare3); - break; - case 3: - gpt_get_compare_event(kGPTOutputCompare1); - break; - } + gpt_get_compare_event(kGPTOutputCompare1); } static bool _is_timer_expired() diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index 258b8ec22..58e7fb35c 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -47,8 +47,10 @@ static struct XiziTrapDriver xizi_trap_driver; void panic(char* s) { - xizi_trap_driver.cpu_irq_disable(); - spinlock_unlock(&whole_kernel_lock); + // xizi_trap_driver.cpu_irq_disable(); + if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) { + spinlock_unlock(&whole_kernel_lock); + } KPrintf("panic: %s\n", s); for (;;) ; diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S index 6ee8ba751..d636b9b55 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S @@ -47,43 +47,16 @@ trap_return: ldmfd r13!, {r14} ldmfd r13!, {r2} msr spsr_cxsf, r2 - ldr r0, [r13], #4 - ldr r1, [r13], #4 - ldr r2, [r13], #4 - ldr r3, [r13], #4 - ldr r4, [r13], #4 - ldr r5, [r13], #4 - ldr r6, [r13], #4 - ldr r7, [r13], #4 - ldr r8, [r13], #4 - ldr r9, [r13], #4 - ldr r10, [r13], #4 - ldr r11, [r13], #4 - ldr r12, [r13], #4 - ldm r13!, {pc}^ + ldmfd r13!, {r0-r12, pc}^ // restore context and return user_trap_swi_enter: - # save trapframe to swi stack - sub sp, sp, #56 - str r14, [sp, #52] - str r12, [sp, #48] - str r11, [sp, #44] - str r10, [sp, #40] - str r9, [sp, #36] - str r8, [sp, #32] - str r7, [sp, #28] - str r6, [sp, #24] - str r5, [sp, #20] - str r4, [sp, #16] - str r3, [sp, #12] - str r2, [sp, #8] - str r1, [sp, #4] - str r0, [sp] + # save trapframe to swi stack + stmfd sp!, {r0-r12, r14} // save context + mrs r2, spsr // copy spsr to r2 + stmfd r13!, {r2} // save r2(spsr) to the stack - mrs r2, spsr - stmfd r13!, {r2} - stmfd r13!, {r14} - stmfd r13, {sp, lr}^ + stmfd r13!, {r14} // save r14 again to have one uniform trapframe + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 # call syscall handler @@ -92,17 +65,12 @@ user_trap_swi_enter: b trap_return trap_irq_enter: - # save context in irq stack - sub r14, r14, #4 - sub sp, sp, #16 - str r14, [sp, #12] - str r2, [sp, #8] - str r1, [sp, #4] - str r0, [sp] - - mrs r1, spsr - mov r0, r13 // irq stack stop - add r13, r13, #16 // reset IRQ stack + # save it on the stack as r14 is banked + sub r14, r14, #4 // r14 (lr) contains the interrupted PC + stmfd r13!, {r0-r2, r14} // + mrs r1, spsr // save spsr_irq + mov r0, r13 // save stack stop (r13_irq) + add r13, r13, #16 // reset the IRQ stack # switch to the SVC mode mrs r2, cpsr @@ -111,25 +79,15 @@ trap_irq_enter: msr cpsr_cxsf, r2 # build the trap frame - ldr r2, [r0, #12] + ldr r2, [r0, #12] // read the r14_irq, then save it stmfd r13!, {r2} - sub r13, r13, #40 - str r12, [r13, #36] - str r11, [r13, #32] - str r10, [r13, #28] - str r9, [r13, #24] - str r8, [r13, #20] - str r7, [r13, #16] - str r6, [r13, #12] - str r5, [r13, #8] - str r4, [r13, #4] - str r3, [r13] - - ldmfd r0, {r3-r5} + stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked) + ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack stmfd r13!, {r3-r5} - stmfd r13!, {r1} - stmfd r13!, {lr} - stmfd r13, {sp, lr}^ + stmfd r13!, {r1} // save spsr + stmfd r13!, {lr} // save lr_svc + + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 mov r0, r13 // trapframe as parameters diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index 8dc8a6945..ef3011ac9 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -69,9 +69,15 @@ Modification: int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv) { /* load img to task */ + if (img_start == NULL) { + return -1; + } /* 1. load elf header */ struct elfhdr elf; memcpy((void*)&elf, img_start, sizeof(elf)); + if (elf.magic != ELF_MAGIC) { + return -1; + } // pgdir for new task struct TopLevelPageDirectory pgdir; pgdir.pd_addr = NULL; From 213a92330e5e60c7647f7e4a7f488d327d6ffbe9 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Wed, 24 Apr 2024 14:31:00 +0800 Subject: [PATCH 16/24] Optimize session connection and buddy. --- .../cortex-a9/imx6q-sabrelite/memlayout.h | 1 + .../cortex-a9/zynq7000-zc702/memlayout.h | 3 ++- .../XiZi_AIoT/softkernel/include/buddy.h | 6 +++-- .../XiZi_AIoT/softkernel/include/task.h | 3 +++ .../XiZi_AIoT/softkernel/memory/buddy.c | 27 ++++++++++++++++++- .../XiZi_AIoT/softkernel/memory/kalloc.c | 2 +- .../XiZi_AIoT/softkernel/memory/share_page.c | 22 +++++++++++++-- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 5 ++++ 8 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h index eef60ffe4..b6ed98e68 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h @@ -60,6 +60,7 @@ Modification: #define USER_MEM_BASE (0x00000000) #define USER_MEM_TOP DEV_VRTMEM_BASE #define USER_IPC_SPACE_BASE (0x70000000) +#define USER_IPC_USE_ALLOCATOR_WATERMARK (0x70010000) #define USER_IPC_SPACE_TOP (USER_MEM_TOP - USER_STACK_SIZE) /* Deivce memory layout */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h index f68861da0..855d27835 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h @@ -53,13 +53,14 @@ Modification: #define NUM_TOPLEVEL_PDE NUM_LEVEL3_PDE #define PAGE_SIZE LEVEL4_PTE_SIZE -#define MAX_NR_FREE_PAGES ((PHY_MEM_STOP - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT) +#define MAX_NR_FREE_PAGES ((PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT) /* User memory layout */ #define USER_STACK_SIZE PAGE_SIZE #define USER_MEM_BASE (0x00000000) #define USER_MEM_TOP DEV_VRTMEM_BASE #define USER_IPC_SPACE_BASE (0x70000000) +#define USER_IPC_USE_ALLOCATOR_WATERMARK (0x70010000) #define USER_IPC_SPACE_TOP (USER_MEM_TOP - USER_STACK_SIZE) /* Deivce memory layout */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h b/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h index 6c890c840..d8a0354ca 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h @@ -68,7 +68,6 @@ struct KFreeList { struct double_list_node list_head; }; -#define MAX_NR_PAGES MAX_NR_FREE_PAGES struct KBuddy { uint32_t n_pages; uint32_t use_lock; @@ -77,7 +76,7 @@ struct KBuddy { struct KPage* first_page; uint32_t mem_start; uint32_t mem_end; - struct KPage pages[MAX_NR_PAGES]; + struct KPage* pages; }; /********************************************* @@ -89,6 +88,7 @@ struct KBuddy { * @param mem_end free memory region end * @return void */ +bool KBuddyInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end); void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end); /* @@ -105,6 +105,8 @@ char* KBuddyAlloc(struct KBuddy* pbuddy, uint32_t size); */ bool KBuddyFree(struct KBuddy* pbuddy, char* vaddr); +void KBuddyDestory(struct KBuddy* pbuddy); + /* * Print current free pages for debug. */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index d79233c9c..2add2df49 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -31,6 +31,7 @@ Modification: #include "core.h" +#include "buddy.h" #include "list.h" #include "object_allocator.h" #include "pagetable.h" @@ -80,6 +81,7 @@ struct TaskMicroDescriptor { /* task communication resources */ struct double_list_node cli_sess_listhead; struct double_list_node svr_sess_listhead; + struct KBuddy* massive_ipc_allocator; struct TraceTag server_identifier; /* task schedule attributes */ @@ -98,6 +100,7 @@ struct SchedulerRightGroup { struct XiziTaskManager { struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */ struct slab_allocator task_allocator; + struct slab_allocator task_buddy_allocator; uint32_t next_pid; /* init task manager */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c index 7b263a625..702c0409e 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c @@ -29,6 +29,7 @@ Modification: *************************************************/ #include "buddy.h" +#include "kalloc.h" #include "log.h" static void _buddy_split_page(struct KPage* page, uint32_t low_order, uint32_t high_order, struct KFreeList* list) @@ -138,8 +139,15 @@ static void KBuddyPagesFree(struct KBuddy* pbuddy, struct KPage* page) return; } -void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) +bool KBuddyInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) { + if (pbuddy->pages == NULL) { + if ((pbuddy->pages = (struct KPage*)kalloc(((mem_end - mem_start) >> LEVEL4_PTE_SHIFT) * sizeof(struct KPage))) == NULL) { + ERROR("Not space to init a buddy object.\n"); + return false; + } + } + uint32_t i = 0; struct KPage* page = NULL; struct KFreeList* free_list = NULL; @@ -173,6 +181,16 @@ void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) doubleListNodeInit(&page->node); KBuddyPagesFree(pbuddy, page); } + + return true; +} + +void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) +{ +#define MAX_NR_PAGES MAX_NR_FREE_PAGES + static struct KPage kern_free_pages[MAX_NR_PAGES]; + pbuddy->pages = kern_free_pages; + KBuddyInit(pbuddy, mem_start, mem_end); } char* KBuddyAlloc(struct KBuddy* pbuddy, uint32_t size) @@ -211,6 +229,13 @@ bool KBuddyFree(struct KBuddy* pbuddy, char* vaddr) return true; } +void KBuddyDestory(struct KBuddy* pbuddy) +{ + if (pbuddy->pages) { + kfree((void*)pbuddy->pages); + } +} + void KFreePagesInfo(struct KBuddy* pbuddy) { DEBUG("Buddy structure:"); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c index 9ce64eaa3..1d7f272bc 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c @@ -45,7 +45,7 @@ bool module_phymem_init() uint32_t user_freemem_start = PHY_USER_FREEMEM_BASE; uint32_t user_freemem_end = PHY_MEM_STOP; KBuddySysInit(&kern_virtmem_buddy, kern_freemem_start, kern_freemem_end); - KBuddySysInit(&user_phy_freemem_buddy, user_freemem_start, user_freemem_end); + KBuddyInit(&user_phy_freemem_buddy, user_freemem_start, user_freemem_end); LOG_PRINTF("Free memory organized done.\n"); return true; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c index 1ea0713de..9a07aa676 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c @@ -92,8 +92,23 @@ static uintptr_t map_task_share_page(struct TaskMicroDescriptor* task, const uin struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); // map double vaddr page to support uniform ring buffer r/w - uintptr_t vaddr = alloc_share_page_addr(task, nr_pages * 2); - if (UNLIKELY(vaddr == 0)) { + uintptr_t vaddr = (uintptr_t)NULL; + if (task->massive_ipc_allocator != NULL) { + vaddr = (uintptr_t)KBuddyAlloc(task->massive_ipc_allocator, PAGE_SIZE * nr_pages * 2); + } else { + vaddr = alloc_share_page_addr(task, nr_pages * 2); + if (vaddr >= USER_IPC_USE_ALLOCATOR_WATERMARK) { + task->massive_ipc_allocator = (struct KBuddy*)slab_alloc(&xizi_task_manager.task_buddy_allocator); + KBuddyInit(task->massive_ipc_allocator, USER_IPC_USE_ALLOCATOR_WATERMARK, USER_IPC_SPACE_TOP); + if (!task->massive_ipc_allocator) { + ERROR("Alloc task buddy failed.\n"); + return (uintptr_t)NULL; + } + vaddr = (uintptr_t)KBuddyAlloc(task->massive_ipc_allocator, nr_pages * 2); + } + } + + if (UNLIKELY(vaddr == (uintptr_t)NULL)) { return (uintptr_t)NULL; } if (!xizi_pager.map_pages(task->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, false)) { @@ -149,6 +164,9 @@ void unmap_task_share_pages(struct TaskMicroDescriptor* task, const uintptr_t ta xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr, nr_pages * PAGE_SIZE); xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr + (nr_pages * PAGE_SIZE), nr_pages * PAGE_SIZE); + if (task_vaddr >= USER_IPC_USE_ALLOCATOR_WATERMARK) { + KBuddyFree(task->massive_ipc_allocator, (void*)task_vaddr); + } if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(task_vaddr, 2 * nr_pages * PAGE_SIZE); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 127a3ec9b..0299c4972 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -49,6 +49,7 @@ static void _task_manager_init() } // init task (slab) allocator slab_init(&xizi_task_manager.task_allocator, sizeof(struct TaskMicroDescriptor)); + slab_init(&xizi_task_manager.task_buddy_allocator, sizeof(struct KBuddy)); // pid pool xizi_task_manager.next_pid = 0; @@ -95,6 +96,10 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task) doubleListDel(cur_node); // free task back to allocator + if (task->massive_ipc_allocator != NULL) { + KBuddyDestory(task->massive_ipc_allocator); + slab_free(&xizi_task_manager.task_buddy_allocator, (void*)task->massive_ipc_allocator); + } slab_free(&xizi_task_manager.task_allocator, (void*)task); // remove priority From 52b549c14cc465380a993be914799f28854b8e89 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Thu, 25 Apr 2024 09:32:10 +0800 Subject: [PATCH 17/24] support irq --- .../cortex-a9/imx6q-sabrelite/trap_common.c | 2 +- Ubiquitous/XiZi_AIoT/services/app/Makefile | 10 ++- .../XiZi_AIoT/services/app/test_irq_handler.c | 42 ++++++++++ .../services/boards/imx6q-sabrelite/Makefile | 2 +- .../boards/imx6q-sabrelite/test_irq_sender.c | 82 +++++++++++++++++++ .../XiZi_AIoT/softkernel/include/task.h | 1 + .../XiZi_AIoT/softkernel/memory/share_page.c | 2 +- .../softkernel/syscall/sys_register_irq.c | 39 +++++++-- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 2 +- 9 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c create mode 100644 Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index 58e7fb35c..53c0a4be2 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -96,7 +96,7 @@ static void _sys_irq_init(int cpu_id) // Set Interrupt handler start address vector_base[1] = (uint32_t)trap_undefined_instruction; // Undefined Instruction vector_base[2] = (uint32_t)user_trap_swi_enter; // Software Interrupt - // vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort + vector_base[3] = (uint32_t)trap_iabort; // Prefetch Abort vector_base[4] = (uint32_t)trap_dabort; // Data Abort vector_base[5] = (uint32_t)handle_reserved; // Reserved vector_base[6] = (uint32_t)trap_irq_enter; // IRQ diff --git a/Ubiquitous/XiZi_AIoT/services/app/Makefile b/Ubiquitous/XiZi_AIoT/services/app/Makefile index 288a23c1b..2490122ac 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/app/Makefile @@ -23,7 +23,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app -all: init test_fs simple_client simple_server shell fs_server test_priority readme.txt | bin +all: init test_fs simple_client simple_server shell fs_server test_priority test_irq_hdlr test_irq_send readme.txt | bin ../tools/mkfs/mkfs ./fs.img $^ @mv $(filter-out readme.txt, $^) bin @mv *.o bin @@ -32,6 +32,14 @@ all: init test_fs simple_client simple_server shell fs_server test_priority read bin: @mkdir -p bin +test_irq_send: test_irq_sender.o usyscall.o libserial.o + @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} + @${objdump} -S $@ > $@.asm + +test_irq_hdlr: test_irq_handler.o libserial.o libipc.o session.o usyscall.o libmem.o + @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} + @${objdump} -S $@ > $@.asm + shell: shell_port.o libserial.o shell_cmd_list.o shell.o shell_ext.o libfs_to_client.o libipc.o session.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c b/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c new file mode 100644 index 000000000..8aed9eb14 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "libipc.h" +#include "libserial.h" +#include "usyscall.h" + +IPC_SERVICES(IpcSwIntrHandler, Ipc_intr_3); + +enum { + SW_INTERRUPT_3 = 3, +}; + +void sgi_test_handler(void) +{ + printf("TEST_SW_HDLR: In %s()\n", __func__); +} + +int IPC_DO_SERVE_FUNC(Ipc_intr_3)(void* useless) +{ + sgi_test_handler(); + return 0; +} + +IPC_SERVER_INTERFACE(Ipc_intr_3, 1); +IPC_SERVER_REGISTER_INTERFACES(IpcSwIntrHandler, 1, Ipc_intr_3); +int main() +{ + register_irq(SW_INTERRUPT_3, Ipc_intr_3); + ipc_server_loop(&IpcSwIntrHandler); + + exit(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile index 1a44e7a85..96a8dc345 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/Makefile @@ -18,7 +18,7 @@ INC_DIR = -I$(KERNEL_ROOT)/services/fs/libfs \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app -board: libserial.o usyscall.o +board: libserial.o usyscall.o test_irq_sender.o @mv $^ ../../app %.o: %.c diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c new file mode 100644 index 000000000..cd0cc4262 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ +#include "libserial.h" +#include "usyscall.h" + +enum { + SW_INTERRUPT_3 = 3, +}; + +enum { + ARM_PERIPHERAL_BASE = 0x00A00000, + MX6Q_GICD_BASE_OFFSET = 0x1000, + MX6Q_GICC_BASE_OFFSET = 0x100, + + ARM_PERIPHERAL_VIRT_BASE = 0x50000000, +}; + +struct _gicd_registers { + uint32_t CTLR; //!< Distributor Control Register. + uint32_t TYPER; //!< Interrupt Controller Type Register. + uint32_t IIDR; //!< Distributor Implementer Identification Register. + uint32_t _reserved0[29]; + uint32_t IGROUPRn[8]; //!< Interrupt Group Registers. + uint32_t _reserved1[24]; + uint32_t ISENABLERn[32]; //!< Interrupt Set-Enable Registers. + uint32_t ICENABLERn[32]; //!< Interrupt Clear-Enable Registers. + uint32_t ISPENDRn[32]; //!< Interrupt Set-Pending Registers. + uint32_t ICPENDRn[32]; //!< Interrupt Clear-Pending Registers. + uint32_t ICDABRn[32]; //!< Active Bit Registers. + uint32_t _reserved2[32]; + uint8_t IPRIORITYRn[255 * sizeof(uint32_t)]; //!< Interrupt Priority Registers. (Byte accessible) + uint32_t _reserved3; + uint8_t ITARGETSRn[255 * sizeof(uint32_t)]; //!< Interrupt Processor Targets Registers. (Byte accessible) + uint32_t _reserved4; + uint32_t ICFGRn[64]; //!< Interrupt Configuration Registers. + uint32_t _reserved5[128]; + uint32_t SGIR; //!< Software Generated Interrupt Register +}; +typedef volatile struct _gicd_registers gicd_t; + +enum _gicd_sgir_fields { + kBP_GICD_SGIR_TargetListFilter = 24, + kBM_GICD_SGIR_TargetListFilter = (0x3 << kBP_GICD_SGIR_TargetListFilter), + + kBP_GICD_SGIR_CPUTargetList = 16, + kBM_GICD_SGIR_CPUTargetList = (0xff << kBP_GICD_SGIR_CPUTargetList), + + kBP_GICD_SGIR_NSATT = 15, + kBM_GICD_SGIR_NSATT = (1 << kBP_GICD_SGIR_NSATT), + + kBP_GICD_SGIR_SGIINTID = 0, + kBM_GICD_SGIR_SGIINTID = 0xf +}; + +void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list) +{ + gicd_t* gicd = (gicd_t*)(ARM_PERIPHERAL_VIRT_BASE + MX6Q_GICD_BASE_OFFSET); + gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter) // + | (target_list << kBP_GICD_SGIR_CPUTargetList) // + | (irqID & 0xf); +} + +int main() +{ + static char prog_name[] = "TEST_IRQ_SEND"; + printf("%s: Mapping GIC\n", prog_name); + mmap(ARM_PERIPHERAL_VIRT_BASE, ARM_PERIPHERAL_BASE, 0x2000, true); + + printf("%s: Sending soft interrupt\n", prog_name); + gic_send_sgi(SW_INTERRUPT_3, 0, 2); + printf("%s: Soft interrupt send done\n", prog_name); + exit(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index 2add2df49..fa9263196 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -48,6 +48,7 @@ enum ProcState { READY, RUNNING, DEAD, + NEVER_RUN, }; /* Thread Control Block */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c index 9a07aa676..081367e70 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c @@ -104,7 +104,7 @@ static uintptr_t map_task_share_page(struct TaskMicroDescriptor* task, const uin ERROR("Alloc task buddy failed.\n"); return (uintptr_t)NULL; } - vaddr = (uintptr_t)KBuddyAlloc(task->massive_ipc_allocator, nr_pages * 2); + return map_task_share_page(task, paddr, nr_pages); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c index 1ed2965b5..0a953892a 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c @@ -34,40 +34,55 @@ Modification: #include "actracer.h" #include "assert.h" #include "ipc.h" +#include "mmu_common.h" #include "multicores.h" #include "share_page.h" #include "syscall.h" #include "task.h" -static struct TaskMicroDescriptor kernel_irq_proxy; +static struct TaskMicroDescriptor* kernel_irq_proxy; static struct { struct TaskMicroDescriptor* handle_task; - struct Session* session; + struct Session session; int opcode; } irq_forward_table[NR_IRQS]; static void send_irq_to_user(int irq_num) { + struct Session* session = &irq_forward_table[irq_num].session; int len = IPC_ARG_INFO_BASE_OFFSET; + len += sizeof(struct IpcArgInfo); + /* add session tail */ - struct IpcMsg* buf = irq_forward_table[irq_num].session->buf + irq_forward_table[irq_num].session->tail; - irq_forward_table[irq_num].session->tail += len; + struct IpcMsg* buf = session->buf + session->tail; memset((void*)buf, 0, len); + session->tail = (session->tail + len) % session->capacity; + /* construct message */ buf->header.len = len; - buf->header.nr_args = 0; + buf->header.nr_args = 1; buf->header.init = 1; buf->header.opcode = irq_forward_table[irq_num].opcode; buf->header.done = 0; buf->header.magic = IPC_MSG_MAGIC; buf->header.valid = 1; + /* add session head */ - irq_forward_table[irq_num].session->head += len; + session->head = (session->head + len) % session->capacity; } int user_irq_handler(int irq, void* tf, void* arg) { + static struct MmuCommonDone* p_mmu_driver = NULL; + if (p_mmu_driver == NULL) { + struct TraceTag mmu_driver_tag; + AchieveResourceTag(&mmu_driver_tag, RequireRootTag(), "/hardkernel/mmu-ac-resource"); + p_mmu_driver = (struct MmuCommonDone*)AchieveResource(&mmu_driver_tag); + } + p_mmu_driver->LoadPgdir((uintptr_t)V2P(kernel_irq_proxy->pgdir.pd_addr)); send_irq_to_user(irq); + p_mmu_driver->LoadPgdir((uintptr_t)V2P(cur_cpu()->task->pgdir.pd_addr)); + next_task_emergency = irq_forward_table[irq].handle_task; xizi_task_manager.cur_task_yield_noschedule(); return 0; @@ -77,6 +92,7 @@ extern int create_session_inner(struct TaskMicroDescriptor* client, struct TaskM /// @warning no tested. int sys_register_irq(int irq_num, int irq_opcode) { + // init intr resource; static struct TraceTag intr_ac_tag; if (!AchieveResourceTag(&intr_ac_tag, RequireRootTag(), "hardkernel/intr-ac-resource")) { ERROR("intr not initialized.\n"); @@ -84,6 +100,15 @@ int sys_register_irq(int irq_num, int irq_opcode) } struct XiziTrapDriver* p_intr_driver = AchieveResource(&intr_ac_tag); + // init kerenl sender proxy + if (kernel_irq_proxy == NULL) { + kernel_irq_proxy = xizi_task_manager.new_task_cb(); + kernel_irq_proxy->state = NEVER_RUN; + xizi_pager.new_pgdir(&kernel_irq_proxy->pgdir); + memcpy(kernel_irq_proxy->pgdir.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE); + } + + // bind irq to session if (p_intr_driver->sw_irqtbl[irq_num].handler != NULL) { ERROR("irq %d is occupied.\n", irq_num); return -1; @@ -91,7 +116,7 @@ int sys_register_irq(int irq_num, int irq_opcode) struct TaskMicroDescriptor* cur_task = cur_cpu()->task; irq_forward_table[irq_num].handle_task = cur_task; irq_forward_table[irq_num].opcode = irq_opcode; - create_session_inner(&kernel_irq_proxy, cur_task, PAGE_SIZE, irq_forward_table[irq_num].session); + create_session_inner(kernel_irq_proxy, cur_task, PAGE_SIZE, &irq_forward_table[irq_num].session); p_intr_driver->bind_irq_handler(irq_num, user_irq_handler); return 0; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 0299c4972..9fa3f57e1 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -179,7 +179,7 @@ static void _scheduler(struct SchedulerRightGroup right_group) next_task = NULL; /* find next runnable task */ assert(cur_cpu()->task == NULL); - if (next_task_emergency != NULL) { + if (next_task_emergency != NULL && next_task->state == READY) { next_task = next_task_emergency; next_task->state = RUNNING; next_task_emergency = NULL; From 10cc7cc270536866a6fd30ff35d996cd7a11bd82 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Thu, 25 Apr 2024 13:51:18 +0800 Subject: [PATCH 18/24] Unify kernel entrance. --- .../armv7-a/cortex-a9/imx6q-sabrelite/clock.c | 1 + .../intr/arm/armv7-a/cortex-a9/error_debug.c | 33 +++-- .../cortex-a9/imx6q-sabrelite/trap_common.c | 20 +-- .../intr/arm/armv7-a/cortex-a9/trampoline.S | 122 +++++------------- .../XiZi_AIoT/softkernel/include/multicores.h | 5 +- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 2 +- .../softkernel/trap/default_irq_handler.c | 20 ++- .../softkernel/trap/software_irq_handler.c | 8 +- 8 files changed, 79 insertions(+), 132 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c index 6c519f93d..cd144a057 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/clock/arm/armv7-a/cortex-a9/imx6q-sabrelite/clock.c @@ -41,6 +41,7 @@ static void _sys_clock_init() uint32_t freq = get_main_clock(IPG_CLK); gpt_init(CLKSRC_IPG_CLK, freq / 1000000, RESTART_MODE, WAIT_MODE_EN | STOP_MODE_EN); gpt_set_compare_event(kGPTOutputCompare1, OUTPUT_CMP_DISABLE, 1000); + gpt_counter_enable(kGPTOutputCompare1); } static uint32_t _get_clock_int() diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index 8593903c9..1fde315c3 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -46,6 +46,7 @@ Modification: #include "multicores.h" #include "spinlock.h" #include "syscall.h" +#include "trap_common.h" __attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status) { @@ -88,18 +89,30 @@ void dump_tf(struct trapframe* tf) void handle_undefined_instruction(struct trapframe* tf) { // unimplemented trap handler - KPrintf("undefined instruction at %x\n", tf->pc); + xizi_enter_kernel(); + ERROR("undefined instruction at %x\n", tf->pc); panic(""); } +void handle_reserved(void) +{ + // unimplemented trap handler + xizi_enter_kernel(); + panic("Unimplemented Reserved\n"); +} + +void handle_fiq(void) +{ + xizi_enter_kernel(); + panic("Unimplemented FIQ\n"); +} + extern void context_switch(struct context**, struct context*); void dabort_handler(struct trapframe* r) { - if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) { - spinlock_lock(&whole_kernel_lock); - } - uint32_t dfs, dfa; + xizi_enter_kernel(); + uint32_t dfs, dfa; __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); @@ -116,18 +129,13 @@ void dabort_handler(struct trapframe* r) LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); _abort_reason(dfs); dump_tf(r); - if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) { - spinlock_unlock(&whole_kernel_lock); - } panic("data abort exception\n"); } } void iabort_handler(struct trapframe* r) { - if (!is_spinlock_locked(&whole_kernel_lock) || whole_kernel_lock.owner_cpu != cur_cpuid()) { - spinlock_lock(&whole_kernel_lock); - } + xizi_enter_kernel(); uint32_t ifs, ifa; __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); @@ -146,9 +154,6 @@ void iabort_handler(struct trapframe* r) LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); _abort_reason(ifs); dump_tf(r); - if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) { - spinlock_unlock(&whole_kernel_lock); - } panic("prefetch abort exception\n"); } } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index 53c0a4be2..b75cab884 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -42,15 +42,13 @@ extern void trap_iabort(void); extern void trap_dabort(void); extern void trap_irq_enter(void); extern void trap_undefined_instruction(void); +extern void handle_reserved(void); +extern void handle_fiq(void); static struct XiziTrapDriver xizi_trap_driver; void panic(char* s) { - // xizi_trap_driver.cpu_irq_disable(); - if (is_spinlock_locked(&whole_kernel_lock) && whole_kernel_lock.owner_cpu == cur_cpuid()) { - spinlock_unlock(&whole_kernel_lock); - } KPrintf("panic: %s\n", s); for (;;) ; @@ -58,7 +56,6 @@ void panic(char* s) /* stack for different mode*/ static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE]; - extern uint32_t _vector_jumper; extern uint32_t _vector_start; extern uint32_t _vector_end; @@ -73,19 +70,6 @@ void init_cpu_mode_stacks(int cpu_id) } } -void handle_reserved(void) -{ - // unimplemented trap handler - LOG("Unimplemented Reserved\n"); - panic(""); -} - -void handle_fiq(void) -{ - LOG("Unimplemented FIQ\n"); - panic(""); -} - static void _sys_irq_init(int cpu_id) { /* load exception vectors */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S index d636b9b55..6d9dcb009 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S @@ -95,106 +95,54 @@ trap_irq_enter: b trap_return trap_reset_enter: - mov r14, #0 - sub r13, r13, #56 - str r14, [r13, #52] - str r12, [r13, #48] - str r11, [r13, #44] - str r10, [r13, #40] - str r9, [r13, #36] - str r8, [r13, #32] - str r7, [r13, #28] - str r6, [r13, #24] - str r5, [r13, #20] - str r4, [r13, #16] - str r3, [r13, #12] - str r2, [r13, #8] - str r1, [r13, #4] - str r0, [r13] - - mrs r2, spsr - stmfd r13!, {r2} - stmfd r13!, {r14} - stmfd r13, {sp, lr}^ + mov r14, #0 // lr: not defined on reset + stmfd r13!, {r0-r12, r14} + mrs r2, spsr // copy spsr to r2 + stmfd r13!, {r2} // save r2(spsr) to the stack + stmfd r13!, {r14} // save r14 again (it is not really correct) + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - mov r0, r13 + + # call traps (trapframe *fp) + mov r0, r13 // copy r13_svc to r0 bl _vector_jumper trap_dabort: - sub r14, r14, #8 - sub r13, r13, #56 - str r14, [r13, #52] - str r12, [r13, #48] - str r11, [r13, #44] - str r10, [r13, #40] - str r9, [r13, #36] - str r8, [r13, #32] - str r7, [r13, #28] - str r6, [r13, #24] - str r5, [r13, #20] - str r4, [r13, #16] - str r3, [r13, #12] - str r2, [r13, #8] - str r1, [r13, #4] - str r0, [r13] - - mrs r2, spsr - stmfd r13!, {r2} - stmfd r13!, {r14} - stmfd r13, {sp, lr}^ + sub r14, r14, #8 // lr: instruction causing the abort + stmfd r13!, {r0-r12, r14} + mrs r2, spsr // copy spsr to r2 + stmfd r13!, {r2} // save r2(spsr) to the stack + stmfd r13!, {r14} // save r14 again (it is not really correct) + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - mov r0, r13 + + # call traps (trapframe *fp) + mov r0, r13 // save trapframe as the first parameter bl dabort_handler trap_iabort: - sub r14, r14, #4 - sub r13, r13, #56 - str r14, [r13, #52] - str r12, [r13, #48] - str r11, [r13, #44] - str r10, [r13, #40] - str r9, [r13, #36] - str r8, [r13, #32] - str r7, [r13, #28] - str r6, [r13, #24] - str r5, [r13, #20] - str r4, [r13, #16] - str r3, [r13, #12] - str r2, [r13, #8] - str r1, [r13, #4] - str r0, [r13] - - mrs r2, spsr - stmfd r13!, {r2} - stmfd r13!, {r14} - stmfd r13, {sp, lr}^ + sub r14, r14, #4 // lr: instruction causing the abort + stmfd r13!, {r0-r12, r14} + mrs r2, spsr // copy spsr to r2 + stmfd r13!, {r2} // save r2(spsr) to the stack + stmfd r13!, {r14} // save r14 again (it is not really correct) + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - mov r0, r13 + + # call traps (trapframe *fp) + mov r0, r13 // save trapframe as the first parameter bl iabort_handler trap_undefined_instruction: - sub r13, r13, #56 - str r14, [r13, #52] - str r12, [r13, #48] - str r11, [r13, #44] - str r10, [r13, #40] - str r9, [r13, #36] - str r8, [r13, #32] - str r7, [r13, #28] - str r6, [r13, #24] - str r5, [r13, #20] - str r4, [r13, #16] - str r3, [r13, #12] - str r2, [r13, #8] - str r1, [r13, #4] - str r0, [r13] - - mrs r2, spsr - stmfd r13!, {r2} - stmfd r13!, {r14} - stmfd r13, {sp, lr}^ + stmfd r13!, {r0-r12, r14} + mrs r2, spsr // copy spsr to r2 + stmfd r13!, {r2} // save r2(spsr) to the stack + stmfd r13!, {r14} // save r14 again (it is not really correct) + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - mov r0, r13 + + # call traps (trapframe *fp) + mov r0, r13 // save trapframe as the first parameter bl handle_undefined_instruction diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h index fad604925..ed5c90f43 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h @@ -47,4 +47,7 @@ static inline struct CPU* cur_cpu(void) return &global_cpus[cur_cpuid()]; } -struct spinlock whole_kernel_lock; \ No newline at end of file +struct spinlock whole_kernel_lock; + +void xizi_enter_kernel(); +void xizi_leave_kernel(); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 9fa3f57e1..941f19d63 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -171,10 +171,10 @@ struct TaskMicroDescriptor* next_task_emergency = NULL; extern void context_switch(struct context**, struct context*); static void _scheduler(struct SchedulerRightGroup right_group) { + xizi_enter_kernel(); struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); struct TaskMicroDescriptor* next_task; - spinlock_lock(&whole_kernel_lock); while (1) { next_task = NULL; /* find next runnable task */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index ad0aa6d40..4c7e79904 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -56,16 +56,15 @@ void default_interrupt_routine(void) extern void context_switch(struct context**, struct context*); void intr_irq_dispatch(struct trapframe* tf) { - assert(p_intr_driver != NULL); - - p_intr_driver->cpu_irq_disable(); + xizi_enter_kernel(); // enter irq + assert(p_intr_driver != NULL); uintptr_t int_info = 0; if ((int_info = p_intr_driver->hw_before_irq()) == 0) { + xizi_leave_kernel(); return; } - spinlock_lock(&whole_kernel_lock); struct TaskMicroDescriptor* current_task = cur_cpu()->task; if (LIKELY(current_task != NULL)) { @@ -94,6 +93,17 @@ void intr_irq_dispatch(struct trapframe* tf) } assert(current_task == cur_cpu()->task); + xizi_leave_kernel(); +} + +void xizi_enter_kernel() +{ + p_intr_driver->cpu_irq_disable(); + spinlock_lock(&whole_kernel_lock); +} + +void xizi_leave_kernel() +{ spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); -} +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index f462c44e0..c88bffc13 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -48,12 +48,9 @@ bool swi_distributer_init(struct SwiDispatcherRightGroup* _right_group) extern void context_switch(struct context**, struct context*); void software_irq_dispatch(struct trapframe* tf) { - + xizi_enter_kernel(); assert(p_intr_driver != NULL); - p_intr_driver->cpu_irq_disable(); - spinlock_lock(&whole_kernel_lock); - // get current task struct TaskMicroDescriptor* cur_task = cur_cpu()->task; /// @todo: Handle dead task @@ -79,6 +76,5 @@ void software_irq_dispatch(struct trapframe* tf) panic("Exit reaches"); } - spinlock_unlock(&whole_kernel_lock); - p_intr_driver->cpu_irq_enable(); + xizi_leave_kernel(); } \ No newline at end of file From 03039cbdaba09cf954bae5348ad86a268255eec0 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Fri, 26 Apr 2024 11:05:10 +0800 Subject: [PATCH 19/24] fix sys_kill. --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../XiZi_AIoT/hardkernel/hardkernel_init.c | 3 -- .../boards/imx6q-sabrelite/test_irq_sender.c | 15 +++++- .../XiZi_AIoT/services/lib/ipc/libipc.c | 27 ++++++----- .../XiZi_AIoT/services/lib/ipc/session.c | 2 +- .../XiZi_AIoT/services/lib/ipc/session.h | 2 +- .../XiZi_AIoT/softkernel/include/task.h | 3 +- Ubiquitous/XiZi_AIoT/softkernel/main.c | 3 +- .../XiZi_AIoT/softkernel/syscall/sys_exit.c | 2 +- .../softkernel/syscall/sys_register_irq.c | 2 +- .../XiZi_AIoT/softkernel/syscall/sys_yield.c | 2 +- .../XiZi_AIoT/softkernel/task/scheduler.c | 2 - Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 46 ++++++++----------- .../softkernel/trap/clock_irq_handler.c | 2 +- 14 files changed, 61 insertions(+), 52 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index 11043cb7c..f8af8ccc9 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 4 +#define NR_CPU 3 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c index 660b883f9..351a1266f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/hardkernel_init.c @@ -218,10 +218,7 @@ bool secondary_cpu_hardkernel_init(int cpu_id, struct TraceTag* _hardkernel_tag) // cache p_icache_driver->enable(); p_dcache_driver->enable(); - // p_icache_driver->disable(); - // p_dcache_driver->disable(); // clock - // p_clock_driver->sys_clock_init(); p_intr_driver->single_irq_enable(p_clock_driver->get_clock_int(), cpu_id, 0); // mmu secondary_cpu_load_kern_pgdir(&init_mmu_tag, &init_intr_tag); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c index cd0cc4262..223b1f4d8 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c @@ -24,6 +24,19 @@ enum { ARM_PERIPHERAL_VIRT_BASE = 0x50000000, }; +enum _gicd_sgi_filter { + //! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter. + kGicSgiFilter_UseTargetList = 0, + + //! Forward the interrupt to all CPU interfaces except that of the processor that requested + //! the interrupt. + kGicSgiFilter_AllOtherCPUs = 1, + + //! Forward the interrupt only to the CPU interface of the processor that requested the + //! interrupt. + kGicSgiFilter_OnlyThisCPU = 2 +}; + struct _gicd_registers { uint32_t CTLR; //!< Distributor Control Register. uint32_t TYPER; //!< Interrupt Controller Type Register. @@ -76,7 +89,7 @@ int main() mmap(ARM_PERIPHERAL_VIRT_BASE, ARM_PERIPHERAL_BASE, 0x2000, true); printf("%s: Sending soft interrupt\n", prog_name); - gic_send_sgi(SW_INTERRUPT_3, 0, 2); + gic_send_sgi(SW_INTERRUPT_3, 0, kGicSgiFilter_OnlyThisCPU); printf("%s: Soft interrupt send done\n", prog_name); exit(); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c index 0d9582aae..410048c31 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c @@ -178,24 +178,29 @@ void ipc_server_loop(struct IpcNode* ipc_node) a session could be delay in case one of its message(current message) needs to wait for an interrupt message's arrival interfaces[opcode] should explicitly call delay_session() and return to delay this session */ - while (msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1 && msg->header.done != 1) { + while (msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1) { // printf("session %d [%d, %d]\n", session_list[i].id, session_list[i].head, session_list[i].tail); if (session_used_size(&session_list[i]) == 0 && session_forward_tail(&session_list[i], msg->header.len) < 0) { break; } - if (ipc_node->interfaces[msg->header.opcode]) { - ipc_node->interfaces[msg->header.opcode](msg); - // check if this session is delayed by op handler, all messages after the delayed message in current session is blocked. - if (session_delayed) { - session_delayed = false; - break; + + // this is a message needs to handle + if (msg->header.done != 1) { + if (ipc_node->interfaces[msg->header.opcode]) { + ipc_node->interfaces[msg->header.opcode](msg); + // check if this session is delayed by op handler, all messages after the delayed message in current session is blocked. + if (session_delayed) { + session_delayed = false; + break; + } + } else { + printf("Unsupport opcode(%d) for server: %s\n", msg->header.opcode, ipc_node->name); } - } else { - printf("Unsupport opcode(%d) for server: %s\n", msg->header.opcode, ipc_node->name); } + // current msg is a message that needs to ignore // finish this message in server's perspective - while (session_forward_head(&session_list[i], msg->header.len) < 0) { - yield(); + if (session_forward_head(&session_list[i], msg->header.len) < 0) { + break; } msg = IPCSESSION_MSG(&session_list[i]); } diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.c b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.c index 27e88c706..a399dec18 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.c @@ -61,6 +61,6 @@ bool session_free_buf(struct Session* session, int len) if (len > session_used_size(session)) { return false; } - assert(session_forward_head(session, len) != 1); + assert(session_forward_head(session, len) != -1); return true; } diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h index 24952db0c..4979f74ca 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h @@ -55,7 +55,7 @@ __attribute__((__always_inline__)) static inline int session_remain_capacity(str __attribute__((__always_inline__)) static inline int session_forward_head(struct Session* session, int len) { - if (((session->head + len) % session->capacity) > session->tail) { + if (len > session_used_size(session)) { printf("forward head with too much size\n"); return -1; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index fa9263196..726e4f518 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -48,6 +48,7 @@ enum ProcState { READY, RUNNING, DEAD, + BLOCKED, NEVER_RUN, }; @@ -118,7 +119,7 @@ struct XiziTaskManager { /* function that's runing by kernel thread context, schedule use tasks */ void (*task_scheduler)(struct SchedulerRightGroup); /* call to yield current use task */ - void (*cur_task_yield_noschedule)(void); + void (*task_yield_noschedule)(struct TaskMicroDescriptor* task, bool is_blocking); /* set task priority */ void (*set_cur_task_priority)(int priority); }; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/main.c b/Ubiquitous/XiZi_AIoT/softkernel/main.c index a3de7b8aa..e79beecaf 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/main.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/main.c @@ -90,13 +90,14 @@ int main(void) struct SchedulerRightGroup scheduler_rights; assert(AchieveResourceTag(&scheduler_rights.mmu_driver_tag, &hardkernel_tag, "mmu-ac-resource")); assert(AchieveResourceTag(&scheduler_rights.intr_driver_tag, &hardkernel_tag, "intr-ac-resource")); - core_init_done |= (1 << cpu_id); LOG_PRINTF("CPU %d init done\n", cpu_id); spinlock_unlock(&whole_kernel_lock); while (core_init_done != (1 << NR_CPU) - 1) ; + + xizi_enter_kernel(); start_smp_cache_broadcast(cpu_id); xizi_task_manager.task_scheduler(scheduler_rights); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c index bd5a99612..25ebadc11 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c @@ -82,7 +82,7 @@ int sys_exit(struct TaskMicroDescriptor* ptask) } // delete task for pcb_list - xizi_task_manager.cur_task_yield_noschedule(); + xizi_task_manager.task_yield_noschedule(ptask, true); ptask->state = DEAD; return 0; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c index 0a953892a..5b0722070 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c @@ -84,7 +84,7 @@ int user_irq_handler(int irq, void* tf, void* arg) p_mmu_driver->LoadPgdir((uintptr_t)V2P(cur_cpu()->task->pgdir.pd_addr)); next_task_emergency = irq_forward_table[irq].handle_task; - xizi_task_manager.cur_task_yield_noschedule(); + xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); return 0; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c index 6aa426047..f4dc7b868 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c @@ -35,6 +35,6 @@ Modification: int sys_yield() { - xizi_task_manager.cur_task_yield_noschedule(); + xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c b/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c index a8d8048dd..f693ab871 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c @@ -40,7 +40,6 @@ struct TaskMicroDescriptor* max_priority_runnable_task(void) { if (task->state == READY) { // found a runnable task, stop this look up - task->state = RUNNING; return task; } else if (task->state == DEAD) { // found a killed task, stop this loop @@ -61,7 +60,6 @@ struct TaskMicroDescriptor* round_robin_runnable_task(uint32_t priority) if (task->state == READY) { // found a runnable task, stop this look up - task->state = RUNNING; return task; } else if (task->state == DEAD) { // found a killed task, stop this loop diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 941f19d63..8e8898c3b 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -171,7 +171,6 @@ struct TaskMicroDescriptor* next_task_emergency = NULL; extern void context_switch(struct context**, struct context*); static void _scheduler(struct SchedulerRightGroup right_group) { - xizi_enter_kernel(); struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); struct TaskMicroDescriptor* next_task; @@ -182,20 +181,25 @@ static void _scheduler(struct SchedulerRightGroup right_group) if (next_task_emergency != NULL && next_task->state == READY) { next_task = next_task_emergency; next_task->state = RUNNING; - next_task_emergency = NULL; } else { next_task = xizi_task_manager.next_runnable_task(); } + next_task_emergency = NULL; + if (next_task != NULL) { + assert(next_task->state == READY); + next_task->state = RUNNING; + } spinlock_unlock(&whole_kernel_lock); /* not a runnable task */ - if (UNLIKELY(next_task == NULL) || UNLIKELY(next_task->state != RUNNING)) { + if (UNLIKELY(next_task == NULL)) { spinlock_lock(&whole_kernel_lock); continue; } /* a runnable task */ spinlock_lock(&whole_kernel_lock); + assert(next_task->state == RUNNING); struct CPU* cpu = cur_cpu(); cpu->task = next_task; p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr)); @@ -203,34 +207,24 @@ static void _scheduler(struct SchedulerRightGroup right_group) } } -static uint32_t yield_cnt = 0; -static void _cur_task_yield_noschedule(void) +static void _task_yield_noschedule(struct TaskMicroDescriptor* task, bool blocking) { - yield_cnt++; - - struct TaskMicroDescriptor* current_task = cur_cpu()->task; - assert(current_task != NULL); + assert(task != NULL); // rearrage current task position - doubleListDel(¤t_task->node); - // DEBUG("%s,%d\n", current_task->name, strcmp(current_task->name, name1)); - if (current_task->maxium_tick <= 0) { - if (IS_DOUBLE_LIST_EMPTY(&xizi_task_manager.task_list_head[current_task->priority])) { - ready_task_priority &= ~(1 << current_task->priority); + doubleListDel(&task->node); + if (task->state == RUNNING) { + if (!blocking) { + task->state = READY; + } else { + task->state = BLOCKED; } - current_task->priority += 1; - current_task->maxium_tick = TASK_CLOCK_TICK * 10; } - doubleListAddOnBack(¤t_task->node, &xizi_task_manager.task_list_head[current_task->priority]); - ready_task_priority |= (1 << current_task->priority); - // set current task state - current_task->state = READY; - current_task->remain_tick = TASK_CLOCK_TICK; - cur_cpu()->task = NULL; - if (yield_cnt == 50) { - recover_priority(); - yield_cnt = 0; + task->remain_tick = TASK_CLOCK_TICK; + if (task == cur_cpu()->task) { + cur_cpu()->task = NULL; } + doubleListAddOnBack(&task->node, &xizi_task_manager.task_list_head[task->priority]); } static void _set_cur_task_priority(int priority) @@ -261,7 +255,7 @@ struct XiziTaskManager xizi_task_manager = { .next_runnable_task = max_priority_runnable_task, .task_scheduler = _scheduler, - .cur_task_yield_noschedule = _cur_task_yield_noschedule, + .task_yield_noschedule = _task_yield_noschedule, .set_cur_task_priority = _set_cur_task_priority }; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c index b3453dd2c..6c4c92915 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c @@ -58,7 +58,7 @@ int xizi_clock_handler(int irq, void* tf, void* arg) current_task->remain_tick--; current_task->maxium_tick--; if (current_task->remain_tick == 0) { - xizi_task_manager.cur_task_yield_noschedule(); + xizi_task_manager.task_yield_noschedule(current_task, false); } } } From a7cbb0d041ab52293748ea632575f31451ad101b Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Fri, 26 Apr 2024 17:39:23 +0800 Subject: [PATCH 20/24] delete task only when it's not in running. --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- .../intr/arm/armv7-a/cortex-a9/error_debug.c | 68 +++++++++-------- .../cortex-a9/imx6q-sabrelite/trap_common.c | 27 +------ .../cortex-a9/zynq7000-zc702/trap_common.c | 19 ----- .../XiZi_AIoT/hardkernel/intr/trap_common.h | 3 +- .../XiZi_AIoT/services/app/test_irq_handler.c | 5 +- .../XiZi_AIoT/softkernel/include/multicores.h | 3 +- .../XiZi_AIoT/softkernel/include/syscall.h | 2 + .../XiZi_AIoT/softkernel/include/task.h | 2 + .../XiZi_AIoT/softkernel/syscall/sys_exec.c | 5 +- .../XiZi_AIoT/softkernel/syscall/sys_exit.c | 50 +------------ .../softkernel/syscall/sys_register_irq.c | 51 ++++++++++--- .../XiZi_AIoT/softkernel/task/scheduler.c | 13 +--- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 74 ++++++++++++++++--- .../softkernel/trap/default_irq_handler.c | 11 ++- 15 files changed, 175 insertions(+), 160 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index f8af8ccc9..11043cb7c 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 3 +#define NR_CPU 4 __attribute__((always_inline)) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index 1fde315c3..be66c65a2 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -110,50 +110,56 @@ void handle_fiq(void) extern void context_switch(struct context**, struct context*); void dabort_handler(struct trapframe* r) { - xizi_enter_kernel(); - - uint32_t dfs, dfa; - __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); - __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); - - if (r->pc < KERN_MEM_BASE) { // Exception occured in User space: exit - ERROR("dabort in user space: %s\n", cur_cpu()->task->name); - LOG("program counter: 0x%x caused\n", r->pc); - LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); - _abort_reason(dfs); - dump_tf(r); - sys_exit(cur_cpu()->task); - context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); - } else { // Exception occured in Kernel space: panic + if (xizi_is_in_kernel()) { + uint32_t dfs, dfa; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); LOG("program counter: 0x%x caused\n", r->pc); LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); _abort_reason(dfs); dump_tf(r); panic("data abort exception\n"); } + + xizi_enter_kernel(); + + uint32_t dfs, dfa; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); + + ERROR("dabort in user space: %s\n", cur_cpu()->task->name); + LOG("program counter: 0x%x caused\n", r->pc); + LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); + _abort_reason(dfs); + dump_tf(r); + sys_exit(cur_cpu()->task); + context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); } void iabort_handler(struct trapframe* r) { - xizi_enter_kernel(); - uint32_t ifs, ifa; - - __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); - __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::); - - if (r->pc < KERN_MEM_BASE) { // Exception occured in User space: exit - ERROR("iabort in user space: %s\n", cur_cpu()->task->name); - LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task); - LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); - _abort_reason(ifs); - dump_tf(r); - sys_exit(cur_cpu()->task); - context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); - } else { // Exception occured in Kernel space: panic - LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task); + if (xizi_is_in_kernel()) { + uint32_t ifs, ifa; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::); + LOG("program counter: 0x%x caused\n", r->pc); LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); _abort_reason(ifs); dump_tf(r); panic("prefetch abort exception\n"); } + + xizi_enter_kernel(); + + uint32_t ifs, ifa; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::); + + ERROR("iabort in user space: %s\n", cur_cpu()->task->name); + LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task); + LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); + _abort_reason(ifs); + dump_tf(r); + sys_exit(cur_cpu()->task); + context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c index b75cab884..b564f8cb7 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/imx6q-sabrelite/trap_common.c @@ -85,9 +85,10 @@ static void _sys_irq_init(int cpu_id) vector_base[5] = (uint32_t)handle_reserved; // Reserved vector_base[6] = (uint32_t)trap_irq_enter; // IRQ vector_base[7] = (uint32_t)handle_fiq; // FIQ + + gic_init(); } /* active hardware irq responser */ - gic_init(); xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper); } @@ -139,29 +140,6 @@ static void _bind_irq_handler(int irq, irq_handler_t handler) xizi_trap_driver.sw_irqtbl[irq].handler = handler; } -static bool _send_sgi(uint32_t irq, uint32_t bitmask, enum SgiFilterType type) -{ - if (bitmask > (1 << NR_CPU) - 1) { - return false; - } - - enum _gicd_sgi_filter sgi_filter; - switch (type) { - case SgiFilter_TargetList: - sgi_filter = kGicSgiFilter_UseTargetList; - break; - case SgiFilter_AllOtherCPUs: - sgi_filter = kGicSgiFilter_AllOtherCPUs; - break; - default: - sgi_filter = kGicSgiFilter_OnlyThisCPU; - break; - } - gic_send_sgi(irq, bitmask, sgi_filter); - - return true; -} - static uint32_t _hw_before_irq() { @@ -217,7 +195,6 @@ static struct XiziTrapDriver xizi_trap_driver = { .switch_hw_irqtbl = _switch_hw_irqtbl, .bind_irq_handler = _bind_irq_handler, - .send_sgi = _send_sgi, .is_interruptable = _is_interruptable, .hw_before_irq = _hw_before_irq, diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c index eed662bd2..bf91b4a63 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c @@ -164,24 +164,6 @@ static void _bind_irq_handler(int irq, irq_handler_t handler) xizi_trap_driver.sw_irqtbl[irq].handler = handler; } -static bool _send_sgi(uint32_t irq, uint32_t bitmask, enum SgiFilterType type) -{ - if (bitmask > (1 << NR_CPU) - 1) { - return false; - } - - int cpu_id = 0; - while (bitmask != 0) { - if ((bitmask & 0x1) != 0) { - XScuGic_SoftwareIntr(&IntcInstance, irq, cpu_id); - } - cpu_id++; - bitmask >>= 1; - } - - return true; -} - static uint32_t _hw_before_irq() { @@ -233,7 +215,6 @@ static struct XiziTrapDriver xizi_trap_driver = { .switch_hw_irqtbl = _switch_hw_irqtbl, .bind_irq_handler = _bind_irq_handler, - .send_sgi = _send_sgi, .is_interruptable = _is_interruptable, .hw_before_irq = _hw_before_irq, diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h index 06a64ca7d..391910045 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h @@ -66,9 +66,8 @@ struct XiziTrapDriver { void (*cpu_irq_disable)(); void (*single_irq_enable)(int irq, int cpu, int prio); void (*single_irq_disable)(int irq, int cpu); - uint32_t* (*switch_hw_irqtbl)(uint32_t*); - bool (*send_sgi)(uint32_t, uint32_t, enum SgiFilterType); + uint32_t* (*switch_hw_irqtbl)(uint32_t*); void (*bind_irq_handler)(int, irq_handler_t); /* check if no if interruptable */ diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c b/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c index 8aed9eb14..28e8fdd04 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/services/app/test_irq_handler.c @@ -35,7 +35,10 @@ IPC_SERVER_INTERFACE(Ipc_intr_3, 1); IPC_SERVER_REGISTER_INTERFACES(IpcSwIntrHandler, 1, Ipc_intr_3); int main() { - register_irq(SW_INTERRUPT_3, Ipc_intr_3); + if (register_irq(SW_INTERRUPT_3, Ipc_intr_3) == -1) { + printf("TEST_SW_HDLR: bind failed"); + exit(); + } ipc_server_loop(&IpcSwIntrHandler); exit(); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h index ed5c90f43..539a3dac9 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h @@ -50,4 +50,5 @@ static inline struct CPU* cur_cpu(void) struct spinlock whole_kernel_lock; void xizi_enter_kernel(); -void xizi_leave_kernel(); \ No newline at end of file +void xizi_leave_kernel(); +bool xizi_is_in_kernel(); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h index aa78cbf39..7a3747a8c 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h @@ -93,4 +93,6 @@ int sys_state(sys_state_option option, sys_state_info* info); int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev); int sys_register_irq(int irq_num, int irq_opcode); +int sys_unbind_irq_all(struct TaskMicroDescriptor* task); +int sys_unbind_irq(struct TaskMicroDescriptor* task, int irq_num); #endif diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index 726e4f518..a69701ee6 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -64,6 +64,8 @@ struct Thread { struct TaskMicroDescriptor { /* task debug resources */ int pid; + bool bind_irq; + bool dead; char name[TASK_NAME_MAX_LEN]; /// @todo support return value diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c index ef3011ac9..b087fdb98 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exec.c @@ -175,9 +175,10 @@ int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, cha } strncpy(task->name, last, sizeof(task->name)); - xizi_pager.free_user_pgdir(&task->pgdir); + if (task->pgdir.pd_addr != NULL) { + xizi_pager.free_user_pgdir(&task->pgdir); + } task->pgdir = pgdir; - task->heap_base = ALIGNUP(load_size, PAGE_SIZE); task->mem_size = task->heap_base + USER_STACK_SIZE; return 0; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c index 25ebadc11..ca5384910 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_exit.c @@ -39,51 +39,7 @@ Modification: int sys_exit(struct TaskMicroDescriptor* ptask) { assert(ptask != NULL); - - /* handle sessions for condition 1, ref. delete_share_pages() */ - // close all server_sessions - struct server_session* server_session = NULL; - while (!IS_DOUBLE_LIST_EMPTY(&ptask->svr_sess_listhead)) { - server_session = CONTAINER_OF(ptask->svr_sess_listhead.next, struct server_session, node); - // cut the connection from task to session - if (!server_session->closed) { - xizi_share_page_manager.unmap_task_share_pages(ptask, server_session->buf_addr, CLIENT_SESSION_BACKEND(server_session)->nr_pages); - server_session->closed = true; - } - doubleListDel(&server_session->node); - SERVER_SESSION_BACKEND(server_session)->server = NULL; - // delete session (also cut connection from session to task) - if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) { - xizi_share_page_manager.delete_share_pages(SERVER_SESSION_BACKEND(server_session)); - } - } - // close all client_sessions - struct client_session* client_session = NULL; - while (!IS_DOUBLE_LIST_EMPTY(&ptask->cli_sess_listhead)) { - client_session = CONTAINER_OF(ptask->cli_sess_listhead.next, struct client_session, node); - // cut the connection from task to session - if (!client_session->closed) { - xizi_share_page_manager.unmap_task_share_pages(ptask, client_session->buf_addr, CLIENT_SESSION_BACKEND(client_session)->nr_pages); - client_session->closed = true; - } - doubleListDel(&client_session->node); - CLIENT_SESSION_BACKEND(client_session)->client = NULL; - // delete session (also cut connection from session to task) - if (CLIENT_SESSION_BACKEND(client_session)->server_side.closed) { - xizi_share_page_manager.delete_share_pages(CLIENT_SESSION_BACKEND(client_session)); - } - } - - if (ptask->server_identifier.meta != NULL) { - struct TraceTag server_identifier_owner; - AchieveResourceTag(&server_identifier_owner, RequireRootTag(), "softkernel/server-identifier"); - assert(server_identifier_owner.meta != NULL); - DeleteResource(&ptask->server_identifier, &server_identifier_owner); - } - - // delete task for pcb_list - xizi_task_manager.task_yield_noschedule(ptask, true); - ptask->state = DEAD; - + ptask->dead = true; + xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); return 0; -} \ No newline at end of file +} diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c index 5b0722070..b45c2f4cc 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c @@ -79,26 +79,33 @@ int user_irq_handler(int irq, void* tf, void* arg) AchieveResourceTag(&mmu_driver_tag, RequireRootTag(), "/hardkernel/mmu-ac-resource"); p_mmu_driver = (struct MmuCommonDone*)AchieveResource(&mmu_driver_tag); } - p_mmu_driver->LoadPgdir((uintptr_t)V2P(kernel_irq_proxy->pgdir.pd_addr)); - send_irq_to_user(irq); - p_mmu_driver->LoadPgdir((uintptr_t)V2P(cur_cpu()->task->pgdir.pd_addr)); - next_task_emergency = irq_forward_table[irq].handle_task; - xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); + if (irq_forward_table[irq].handle_task != NULL) { + p_mmu_driver->LoadPgdir((uintptr_t)V2P(kernel_irq_proxy->pgdir.pd_addr)); + send_irq_to_user(irq); + p_mmu_driver->LoadPgdir((uintptr_t)V2P(cur_cpu()->task->pgdir.pd_addr)); + + next_task_emergency = irq_forward_table[irq].handle_task; + xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); + } return 0; } extern int create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session); /// @warning no tested. + +static struct XiziTrapDriver* p_intr_driver = NULL; int sys_register_irq(int irq_num, int irq_opcode) { // init intr resource; - static struct TraceTag intr_ac_tag; - if (!AchieveResourceTag(&intr_ac_tag, RequireRootTag(), "hardkernel/intr-ac-resource")) { - ERROR("intr not initialized.\n"); - return -1; + if (p_intr_driver == NULL) { + struct TraceTag intr_ac_tag; + if (!AchieveResourceTag(&intr_ac_tag, RequireRootTag(), "hardkernel/intr-ac-resource")) { + ERROR("intr not initialized.\n"); + return -1; + } + p_intr_driver = (struct XiziTrapDriver*)AchieveResource(&intr_ac_tag); } - struct XiziTrapDriver* p_intr_driver = AchieveResource(&intr_ac_tag); // init kerenl sender proxy if (kernel_irq_proxy == NULL) { @@ -118,6 +125,30 @@ int sys_register_irq(int irq_num, int irq_opcode) irq_forward_table[irq_num].opcode = irq_opcode; create_session_inner(kernel_irq_proxy, cur_task, PAGE_SIZE, &irq_forward_table[irq_num].session); p_intr_driver->bind_irq_handler(irq_num, user_irq_handler); + cur_task->bind_irq = true; + return 0; +} + +int sys_unbind_irq(struct TaskMicroDescriptor* task, int irq_num) +{ + if (irq_forward_table[irq_num].handle_task != task) { + return -1; + } + + irq_forward_table[irq_num].handle_task = NULL; + sys_close_session(&irq_forward_table[irq_num].session); + DEBUG("Unbind: %s to irq %d", task->name, irq_num); + return 0; +} + +int sys_unbind_irq_all(struct TaskMicroDescriptor* task) +{ + for (int idx = 0; idx < NR_IRQS; idx++) { + if (irq_forward_table[idx].handle_task == task) { + sys_unbind_irq(task, idx); + } + } + task->bind_irq = false; return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c b/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c index f693ab871..a19d6a50d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c @@ -38,12 +38,10 @@ struct TaskMicroDescriptor* max_priority_runnable_task(void) DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node) { - if (task->state == READY) { + if (task->state == READY && !task->dead) { // found a runnable task, stop this look up return task; - } else if (task->state == DEAD) { - // found a killed task, stop this loop - // change in pcb_list may break this loop, so find a runnable in next look up + } else if (task->dead && task->state != RUNNING) { xizi_task_manager.free_pcb(task); return NULL; } @@ -57,13 +55,10 @@ struct TaskMicroDescriptor* round_robin_runnable_task(uint32_t priority) DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[priority], node) { - - if (task->state == READY) { + if (task->state == READY && !task->dead) { // found a runnable task, stop this look up return task; - } else if (task->state == DEAD) { - // found a killed task, stop this loop - // change in pcb_list may break this loop, so find a runnable in next look up + } else if (task->dead && task->state != RUNNING) { xizi_task_manager.free_pcb(task); return NULL; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 8e8898c3b..a7c76d4da 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -32,10 +32,11 @@ Modification: #include "core.h" #include "assert.h" +#include "kalloc.h" #include "log.h" #include "multicores.h" -#include "kalloc.h" #include "scheduler.h" +#include "syscall.h" #include "task.h" struct CPU global_cpus[NR_CPU]; @@ -74,6 +75,59 @@ static struct TaskMicroDescriptor* _alloc_task_cb() return task; } +int _task_retrieve_sys_resources(struct TaskMicroDescriptor* ptask) +{ + assert(ptask != NULL); + + /* handle sessions for condition 1, ref. delete_share_pages() */ + // close all server_sessions + struct server_session* server_session = NULL; + while (!IS_DOUBLE_LIST_EMPTY(&ptask->svr_sess_listhead)) { + server_session = CONTAINER_OF(ptask->svr_sess_listhead.next, struct server_session, node); + // cut the connection from task to session + if (!server_session->closed) { + xizi_share_page_manager.unmap_task_share_pages(ptask, server_session->buf_addr, CLIENT_SESSION_BACKEND(server_session)->nr_pages); + server_session->closed = true; + } + doubleListDel(&server_session->node); + SERVER_SESSION_BACKEND(server_session)->server = NULL; + // delete session (also cut connection from session to task) + if (SERVER_SESSION_BACKEND(server_session)->client_side.closed) { + xizi_share_page_manager.delete_share_pages(SERVER_SESSION_BACKEND(server_session)); + } + } + // close all client_sessions + struct client_session* client_session = NULL; + while (!IS_DOUBLE_LIST_EMPTY(&ptask->cli_sess_listhead)) { + client_session = CONTAINER_OF(ptask->cli_sess_listhead.next, struct client_session, node); + // cut the connection from task to session + if (!client_session->closed) { + xizi_share_page_manager.unmap_task_share_pages(ptask, client_session->buf_addr, CLIENT_SESSION_BACKEND(client_session)->nr_pages); + client_session->closed = true; + } + doubleListDel(&client_session->node); + CLIENT_SESSION_BACKEND(client_session)->client = NULL; + // delete session (also cut connection from session to task) + if (CLIENT_SESSION_BACKEND(client_session)->server_side.closed) { + xizi_share_page_manager.delete_share_pages(CLIENT_SESSION_BACKEND(client_session)); + } + } + + if (ptask->server_identifier.meta != NULL) { + struct TraceTag server_identifier_owner; + AchieveResourceTag(&server_identifier_owner, RequireRootTag(), "softkernel/server-identifier"); + assert(server_identifier_owner.meta != NULL); + DeleteResource(&ptask->server_identifier, &server_identifier_owner); + } + + // delete registered irq if there is one + if (ptask->bind_irq) { + sys_unbind_irq_all(ptask); + } + + return 0; +} + /// @brief this function changes task list without locking, so it must be called inside a lock critical area /// @param task static void _dealloc_task_cb(struct TaskMicroDescriptor* task) @@ -83,6 +137,8 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task) return; } + _task_retrieve_sys_resources(task); + // stack is mapped in vspace, so it should be free by pgdir if (task->pgdir.pd_addr) { xizi_pager.free_user_pgdir(&task->pgdir); @@ -112,7 +168,7 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task) extern void trap_return(void); void task_prepare_enter() { - spinlock_unlock(&whole_kernel_lock); + xizi_leave_kernel(); trap_return(); } @@ -124,10 +180,7 @@ static struct TaskMicroDescriptor* _new_task_cb() return NULL; } // init vm - if (!xizi_pager.new_pgdir(&task->pgdir)) { - _dealloc_task_cb(task); - return NULL; - } + task->pgdir.pd_addr = NULL; /* init basic task member */ doubleListNodeInit(&task->cli_sess_listhead); doubleListNodeInit(&task->svr_sess_listhead); @@ -180,14 +233,12 @@ static void _scheduler(struct SchedulerRightGroup right_group) assert(cur_cpu()->task == NULL); if (next_task_emergency != NULL && next_task->state == READY) { next_task = next_task_emergency; - next_task->state = RUNNING; } else { next_task = xizi_task_manager.next_runnable_task(); } next_task_emergency = NULL; if (next_task != NULL) { assert(next_task->state == READY); - next_task->state = RUNNING; } spinlock_unlock(&whole_kernel_lock); @@ -199,11 +250,16 @@ static void _scheduler(struct SchedulerRightGroup right_group) /* a runnable task */ spinlock_lock(&whole_kernel_lock); - assert(next_task->state == RUNNING); + if (next_task->state == READY) { + next_task->state = RUNNING; + } else { + continue; + } struct CPU* cpu = cur_cpu(); cpu->task = next_task; p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr)); context_switch(&cpu->scheduler, next_task->main_thread.context); + assert(next_task->state != RUNNING); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index 4c7e79904..50395ac65 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -62,8 +62,7 @@ void intr_irq_dispatch(struct trapframe* tf) assert(p_intr_driver != NULL); uintptr_t int_info = 0; if ((int_info = p_intr_driver->hw_before_irq()) == 0) { - xizi_leave_kernel(); - return; + goto intr_leave_interrupt; } struct TaskMicroDescriptor* current_task = cur_cpu()->task; @@ -77,7 +76,7 @@ void intr_irq_dispatch(struct trapframe* tf) // distribute irq irq_handler_t isr = p_intr_driver->sw_irqtbl[irq].handler; - if (isr) { + if (isr != NULL) { isr(irq, tf, NULL); } else { default_interrupt_routine(); @@ -93,6 +92,7 @@ void intr_irq_dispatch(struct trapframe* tf) } assert(current_task == cur_cpu()->task); +intr_leave_interrupt: xizi_leave_kernel(); } @@ -106,4 +106,9 @@ void xizi_leave_kernel() { spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); +} + +bool xizi_is_in_kernel() +{ + return is_spinlock_locked(&whole_kernel_lock); } \ No newline at end of file From a24d73f710f9a7effec4d5bbedf50e7be3f395f1 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Sun, 28 Apr 2024 14:44:49 +0800 Subject: [PATCH 21/24] Fully support userland interrupt handler. Use fixed common abort handler. --- .../intr/arm/armv7-a/cortex-a9/error_debug.c | 135 ++++++++---------- .../cortex-a9/zynq7000-zc702/trap_common.c | 41 ++---- .../XiZi_AIoT/hardkernel/intr/spinlock.c | 42 ++++-- .../XiZi_AIoT/hardkernel/intr/spinlock.h | 3 +- .../XiZi_AIoT/hardkernel/intr/trap_common.h | 5 +- Ubiquitous/XiZi_AIoT/services/app/Makefile | 6 + .../XiZi_AIoT/services/app/shell_port.c | 2 +- .../boards/imx6q-sabrelite/test_irq_sender.c | 2 +- .../boards/imx6q-sabrelite/usyscall.c | 4 +- .../boards/imx6q-sabrelite/usyscall.h | 8 +- .../services/boards/zynq7000-zc702/usyscall.c | 4 +- .../services/boards/zynq7000-zc702/usyscall.h | 8 +- .../XiZi_AIoT/services/lib/ipc/libipc.c | 6 +- .../XiZi_AIoT/softkernel/include/multicores.h | 1 + .../XiZi_AIoT/softkernel/include/syscall.h | 8 +- .../softkernel/syscall/sys_register_irq.c | 19 +-- .../XiZi_AIoT/softkernel/syscall/sys_yield.c | 2 +- .../XiZi_AIoT/softkernel/syscall/syscall.c | 2 +- Ubiquitous/XiZi_AIoT/softkernel/task/Makefile | 2 +- .../task/{scheduler.c => schedule.c} | 0 Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 1 + Ubiquitous/XiZi_AIoT/softkernel/trap/Makefile | 3 +- .../XiZi_AIoT/softkernel/trap/abort_handler.c | 86 +++++++++++ .../softkernel/trap/default_irq_handler.c | 22 +-- .../softkernel/trap/software_irq_handler.c | 2 +- 25 files changed, 260 insertions(+), 154 deletions(-) rename Ubiquitous/XiZi_AIoT/softkernel/task/{scheduler.c => schedule.c} (100%) create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index be66c65a2..fc1fe18d7 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -41,30 +41,13 @@ Modification: *************************************************/ #include "core.h" #include "memlayout.h" - -#include "log.h" -#include "multicores.h" #include "spinlock.h" -#include "syscall.h" #include "trap_common.h" -__attribute__((always_inline)) static inline void _abort_reason(uint32_t fault_status) -{ - if ((fault_status & 0xd) == 0x1) // Alignment failure - KPrintf("reason: alignment\n"); - else if ((fault_status & 0xd) == 0x5) // External abort "on translation" - KPrintf("reason: ext. abort on trnslt.\n"); - else if ((fault_status & 0xd) == 0x5) // Translation - KPrintf("reason: sect. translation\n"); - else if ((fault_status & 0xd) == 0x9) // Domain - KPrintf("reason: sect. domain\n"); - else if ((fault_status & 0xd) == 0xd) // Permission - KPrintf("reason: sect. permission\n"); - else if ((fault_status & 0xd) == 0x8) // External abort - KPrintf("reason: ext. abort\n"); - else - KPrintf("reason: unknown???\n"); -} +#include "assert.h" +#include "multicores.h" +#include "syscall.h" +#include "task.h" void dump_tf(struct trapframe* tf) { @@ -86,6 +69,57 @@ void dump_tf(struct trapframe* tf) KPrintf(" pc: 0x%x\n", tf->pc); } +void dabort_reason(struct trapframe* r) +{ + uint32_t fault_status, dfa; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(fault_status)::); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); + LOG("program counter: 0x%x caused\n", r->pc); + LOG("data abort at 0x%x, status 0x%x\n", dfa, fault_status); + + if ((fault_status & 0xd) == 0x1) // Alignment failure + KPrintf("reason: alignment\n"); + else if ((fault_status & 0xd) == 0x5) // External abort "on translation" + KPrintf("reason: ext. abort on trnslt.\n"); + else if ((fault_status & 0xd) == 0x5) // Translation + KPrintf("reason: sect. translation\n"); + else if ((fault_status & 0xd) == 0x9) // Domain + KPrintf("reason: sect. domain\n"); + else if ((fault_status & 0xd) == 0xd) // Permission + KPrintf("reason: sect. permission\n"); + else if ((fault_status & 0xd) == 0x8) // External abort + KPrintf("reason: ext. abort\n"); + else + KPrintf("reason: unknown???\n"); + + dump_tf(r); +} + +void iabort_reason(struct trapframe* r) +{ + uint32_t fault_status, ifa; + __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(fault_status)::); + __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::); + LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, fault_status); + + if ((fault_status & 0xd) == 0x1) // Alignment failure + KPrintf("reason: alignment\n"); + else if ((fault_status & 0xd) == 0x5) // External abort "on translation" + KPrintf("reason: ext. abort on trnslt.\n"); + else if ((fault_status & 0xd) == 0x5) // Translation + KPrintf("reason: sect. translation\n"); + else if ((fault_status & 0xd) == 0x9) // Domain + KPrintf("reason: sect. domain\n"); + else if ((fault_status & 0xd) == 0xd) // Permission + KPrintf("reason: sect. permission\n"); + else if ((fault_status & 0xd) == 0x8) // External abort + KPrintf("reason: ext. abort\n"); + else + KPrintf("reason: unknown???\n"); + + dump_tf(r); +} + void handle_undefined_instruction(struct trapframe* tf) { // unimplemented trap handler @@ -105,61 +139,4 @@ void handle_fiq(void) { xizi_enter_kernel(); panic("Unimplemented FIQ\n"); -} - -extern void context_switch(struct context**, struct context*); -void dabort_handler(struct trapframe* r) -{ - if (xizi_is_in_kernel()) { - uint32_t dfs, dfa; - __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); - __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); - LOG("program counter: 0x%x caused\n", r->pc); - LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); - _abort_reason(dfs); - dump_tf(r); - panic("data abort exception\n"); - } - - xizi_enter_kernel(); - - uint32_t dfs, dfa; - __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 0" : "=r"(dfs)::); - __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 0" : "=r"(dfa)::); - - ERROR("dabort in user space: %s\n", cur_cpu()->task->name); - LOG("program counter: 0x%x caused\n", r->pc); - LOG("data abort at 0x%x, status 0x%x\n", dfa, dfs); - _abort_reason(dfs); - dump_tf(r); - sys_exit(cur_cpu()->task); - context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); -} - -void iabort_handler(struct trapframe* r) -{ - if (xizi_is_in_kernel()) { - uint32_t ifs, ifa; - __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); - __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::); - LOG("program counter: 0x%x caused\n", r->pc); - LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); - _abort_reason(ifs); - dump_tf(r); - panic("prefetch abort exception\n"); - } - - xizi_enter_kernel(); - - uint32_t ifs, ifa; - __asm__ __volatile__("mrc p15, 0, %0, c5, c0, 1" : "=r"(ifs)::); - __asm__ __volatile__("mrc p15, 0, %0, c6, c0, 2" : "=r"(ifa)::); - - ERROR("iabort in user space: %s\n", cur_cpu()->task->name); - LOG("program counter: 0x%x(%s) caused\n", r->pc, cur_cpu()->task); - LOG("prefetch abort at 0x%x, status 0x%x\n", ifa, ifs); - _abort_reason(ifs); - dump_tf(r); - sys_exit(cur_cpu()->task); - context_switch(&cur_cpu()->task->main_thread.context, cur_cpu()->scheduler); -} +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c index bf91b4a63..5cd8145a5 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/zynq7000-zc702/trap_common.c @@ -42,12 +42,13 @@ extern void trap_iabort(void); extern void trap_dabort(void); extern void trap_irq_enter(void); extern void trap_undefined_instruction(void); +extern void handle_reserved(void); +extern void handle_fiq(void); static struct XiziTrapDriver xizi_trap_driver; void panic(char* s) { - xizi_trap_driver.cpu_irq_disable(); KPrintf("panic: %s\n", s); for (;;) ; @@ -55,7 +56,6 @@ void panic(char* s) /* stack for different mode*/ static char mode_stack_pages[NR_CPU][NR_MODE_STACKS][MODE_STACK_SIZE]; - extern uint32_t _vector_jumper; extern uint32_t _vector_start; extern uint32_t _vector_end; @@ -72,19 +72,6 @@ void init_cpu_mode_stacks(int cpu_id) } } -void handle_reserved(void) -{ - // unimplemented trap handler - LOG("Unimplemented Reserved\n"); - panic(""); -} - -void handle_fiq(void) -{ - LOG("Unimplemented FIQ\n"); - panic(""); -} - static void _sys_irq_init(int cpu_id) { @@ -101,18 +88,18 @@ static void _sys_irq_init(int cpu_id) vector_base[5] = (uint32_t)handle_reserved; // Reserved vector_base[6] = (uint32_t)trap_irq_enter; // IRQ vector_base[7] = (uint32_t)handle_fiq; // FIQ - } - /* active hardware irq responser */ - XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID); - if (NULL == gic_config) { - ERROR("Error while looking up gic config\n"); - return; - } - int gic_init_status = XScuGic_CfgInitialize(&IntcInstance, gic_config, gic_config->CpuBaseAddress); - if (gic_init_status != XST_SUCCESS) { - ERROR("Error initializing gic\n"); - return; + /* active hardware irq responser */ + XScuGic_Config* gic_config = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID); + if (NULL == gic_config) { + ERROR("Error while looking up gic config\n"); + return; + } + int gic_init_status = XScuGic_CfgInitialize(&IntcInstance, gic_config, gic_config->CpuBaseAddress); + if (gic_init_status != XST_SUCCESS) { + ERROR("Error initializing gic\n"); + return; + } } xizi_trap_driver.switch_hw_irqtbl((uint32_t*)&_vector_jumper); @@ -226,6 +213,6 @@ static struct XiziTrapDriver xizi_trap_driver = { struct XiziTrapDriver* hardkernel_intr_init(struct TraceTag* hardkernel_tag) { xizi_trap_driver.sys_irq_init(0); - xizi_trap_driver.cpu_irq_enable(); + xizi_trap_driver.cpu_irq_disable(); return &xizi_trap_driver; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c index 210edfabd..9e1014316 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.c @@ -27,8 +27,8 @@ #include "multicores.h" struct lock_node { - int cpu_id; struct double_list_node node; + int cpu_id; }; static struct double_list_node lock_request_guard; @@ -63,15 +63,18 @@ void _spinlock_unlock(struct spinlock* lock); void spinlock_lock(struct spinlock* lock) { - if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpuid()) { + int cur_cpu_id = cur_cpuid(); + if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpu_id) { ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu); panic(""); } + + struct double_list_node* p_lock_node = &core_lock_request[cur_cpu_id].node; _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); - doubleListAddOnBack(&core_lock_request[cur_cpuid()].node, &lock_request_guard); + doubleListAddOnBack(p_lock_node, &lock_request_guard); _spinlock_unlock(&request_lock); - while (lock_request_guard.next != &core_lock_request[cur_cpuid()].node) + while (lock_request_guard.next != p_lock_node) ; _spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER); @@ -79,15 +82,38 @@ void spinlock_lock(struct spinlock* lock) void spinlock_unlock(struct spinlock* lock) { - assert(lock_request_guard.next == &core_lock_request[cur_cpuid()].node); + struct double_list_node* p_lock_node = &core_lock_request[cur_cpuid()].node; + assert(lock_request_guard.next == p_lock_node); _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); - _double_list_del(core_lock_request[cur_cpuid()].node.prev, core_lock_request[cur_cpuid()].node.next); + _double_list_del(p_lock_node->prev, p_lock_node->next); _spinlock_unlock(&request_lock); _spinlock_unlock(lock); } -bool is_spinlock_locked(struct spinlock* lock) +bool spinlock_try_lock(struct spinlock* lock) { - return lock->owner_cpu != SPINLOCK_STATE_UNLOCK; + int cur_cpu_id = cur_cpuid(); + if (lock->owner_cpu != SPINLOCK_STATE_UNLOCK && lock->owner_cpu == cur_cpu_id) { + ERROR("spinlock %s lock double locked by core %d\n", lock->name, lock->owner_cpu); + panic(""); + } + + struct double_list_node* p_lock_node = &core_lock_request[cur_cpu_id].node; + _spinlock_lock(&request_lock, SPINLOCK_LOCK_WAITFOREVER); + doubleListAddOnBack(p_lock_node, &lock_request_guard); + if (lock_request_guard.next != p_lock_node) { + _double_list_del(p_lock_node->prev, p_lock_node->next); + _spinlock_unlock(&request_lock); + return false; + } + _spinlock_unlock(&request_lock); + _spinlock_lock(lock, SPINLOCK_LOCK_WAITFOREVER); + + return true; +} + +bool is_spinlock_hold_by_current_cpu(struct spinlock* lock) +{ + return lock->owner_cpu; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h index e1e08bb86..660db5c19 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h @@ -42,4 +42,5 @@ bool module_spinlock_use_intr_init(void); void spinlock_init(struct spinlock* lock, char* name); void spinlock_lock(struct spinlock* lock); void spinlock_unlock(struct spinlock* lock); -bool is_spinlock_locked(struct spinlock* lock); \ No newline at end of file +bool spinlock_try_lock(struct spinlock* lock); +bool is_spinlock_hold_by_current_cpu(struct spinlock* lock); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h index 391910045..c86c3cc47 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/trap_common.h @@ -100,4 +100,7 @@ void panic(char* s); bool intr_distributer_init(struct IrqDispatcherRightGroup*); void intr_irq_dispatch(struct trapframe* tf); bool swi_distributer_init(struct SwiDispatcherRightGroup*); -void software_irq_dispatch(struct trapframe* tf); \ No newline at end of file +void software_irq_dispatch(struct trapframe* tf); + +void dabort_reason(struct trapframe* r); +void iabort_reason(struct trapframe* r); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/app/Makefile b/Ubiquitous/XiZi_AIoT/services/app/Makefile index 2490122ac..ebf29d76e 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/app/Makefile @@ -23,7 +23,11 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \ -I$(KERNEL_ROOT)/services/boards/$(BOARD) \ -I$(KERNEL_ROOT)/services/app +ifeq ($(BOARD), imx6q-sabrelite) all: init test_fs simple_client simple_server shell fs_server test_priority test_irq_hdlr test_irq_send readme.txt | bin +else +all: init test_fs simple_client simple_server shell fs_server test_priority test_irq_hdlr readme.txt | bin +endif ../tools/mkfs/mkfs ./fs.img $^ @mv $(filter-out readme.txt, $^) bin @mv *.o bin @@ -32,9 +36,11 @@ all: init test_fs simple_client simple_server shell fs_server test_priority test bin: @mkdir -p bin +ifeq ($(BOARD), imx6q-sabrelite) test_irq_send: test_irq_sender.o usyscall.o libserial.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm +endif test_irq_hdlr: test_irq_handler.o libserial.o libipc.o session.o usyscall.o libmem.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} diff --git a/Ubiquitous/XiZi_AIoT/services/app/shell_port.c b/Ubiquitous/XiZi_AIoT/services/app/shell_port.c index cb1459168..ce2453519 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/shell_port.c +++ b/Ubiquitous/XiZi_AIoT/services/app/shell_port.c @@ -35,7 +35,7 @@ signed short userShellRead(char* data, unsigned short len) while (length--) { cur_read = getc(); if (cur_read == 0xff) { - yield(); + yield(SYS_TASK_YIELD_NO_REASON); } // *data++ = getc(); *data++ = cur_read; diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c index 223b1f4d8..a43189c7a 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c @@ -89,7 +89,7 @@ int main() mmap(ARM_PERIPHERAL_VIRT_BASE, ARM_PERIPHERAL_BASE, 0x2000, true); printf("%s: Sending soft interrupt\n", prog_name); - gic_send_sgi(SW_INTERRUPT_3, 0, kGicSgiFilter_OnlyThisCPU); + gic_send_sgi(SW_INTERRUPT_3, 0xF, kGicSgiFilter_UseTargetList); printf("%s: Soft interrupt send done\n", prog_name); exit(); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c index 86a92e24e..c1b49a489 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.c @@ -53,9 +53,9 @@ int exit() return syscall(SYSCALL_EXIT, 0, 0, 0, 0); } -int yield() +int yield(task_yield_reason reason) { - return syscall(SYSCALL_YIELD, 0, 0, 0, 0); + return syscall(SYSCALL_YIELD, (uintptr_t)reason, 0, 0, 0); } int kill(int pid) diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h index 326739a37..e1b9b7273 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/usyscall.h @@ -44,6 +44,12 @@ typedef enum { SYS_STATE_SHOW_CPU_INFO, } sys_state_option; +typedef enum { + SYS_TASK_YIELD_NO_REASON = 0x0, + SYS_TASK_YIELD_FOREVER = 0x1, + SYS_TASK_YIELD_BLOCK_IPC = 0x2, +} task_yield_reason; + typedef union { struct { uintptr_t memblock_start; @@ -58,7 +64,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv); int exit(); -int yield(); +int yield(task_yield_reason reason); int kill(int pid); int register_server(char* name); int session(char* path, int capacity, struct Session* user_session); diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c index 86a92e24e..c1b49a489 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.c @@ -53,9 +53,9 @@ int exit() return syscall(SYSCALL_EXIT, 0, 0, 0, 0); } -int yield() +int yield(task_yield_reason reason) { - return syscall(SYSCALL_YIELD, 0, 0, 0, 0); + return syscall(SYSCALL_YIELD, (uintptr_t)reason, 0, 0, 0); } int kill(int pid) diff --git a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h index 326739a37..e1b9b7273 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/boards/zynq7000-zc702/usyscall.h @@ -44,6 +44,12 @@ typedef enum { SYS_STATE_SHOW_CPU_INFO, } sys_state_option; +typedef enum { + SYS_TASK_YIELD_NO_REASON = 0x0, + SYS_TASK_YIELD_FOREVER = 0x1, + SYS_TASK_YIELD_BLOCK_IPC = 0x2, +} task_yield_reason; + typedef union { struct { uintptr_t memblock_start; @@ -58,7 +64,7 @@ typedef int (*ipc_write_fn)(struct Session* session, int fd, char* src, int offs int spawn(struct Session* session, int fd, ipc_read_fn ipc_read, ipc_fsize_fn ipc_fsize, char* name, char** argv); int exit(); -int yield(); +int yield(task_yield_reason reason); int kill(int pid); int register_server(char* name); int session(char* path, int capacity, struct Session* user_session); diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c index 410048c31..788008706 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c @@ -121,7 +121,7 @@ void ipc_msg_send_wait(struct IpcMsg* msg) msg->header.done = 0; while (msg->header.done == 0) { /// @todo syscall yield with prio decrease - yield(); + yield(SYS_TASK_YIELD_BLOCK_IPC); } assert(msg->header.done == 1); } @@ -138,7 +138,7 @@ int ipc_session_wait(struct Session* session) struct IpcMsg* msg = IPCSESSION_MSG(session); while (msg->header.done == 0) { /// @todo syscall yield with prio decrease - yield(); + yield(SYS_TASK_YIELD_BLOCK_IPC); } assert(msg->header.done == 1); return msg->header.ret_val; @@ -169,7 +169,7 @@ void ipc_server_loop(struct IpcNode* ipc_node) /* handle each session */ for (int i = 0; i < NR_MAX_SESSION; i++) { if (session_list[i].buf == NULL) { - yield(); + yield(SYS_TASK_YIELD_NO_REASON); break; } cur_sess_id = session_list[i].id; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h index 539a3dac9..d0e950565 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/multicores.h @@ -50,5 +50,6 @@ static inline struct CPU* cur_cpu(void) struct spinlock whole_kernel_lock; void xizi_enter_kernel(); +bool xizi_try_enter_kernel(); void xizi_leave_kernel(); bool xizi_is_in_kernel(); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h index 7a3747a8c..052cfff9f 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h @@ -64,6 +64,12 @@ typedef enum { SYS_STATE_SHOW_CPU_INFO, } sys_state_option; +typedef enum { + SYS_TASK_YIELD_NO_REASON = 0x0, + SYS_TASK_YIELD_FOREVER = 0x1, + SYS_TASK_YIELD_BLOCK_IPC = 0x2, +} task_yield_reason; + typedef union { struct { uintptr_t memblock_start; @@ -80,7 +86,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u int sys_spawn(char* img_start, char* name, char** argv); int sys_exit(struct TaskMicroDescriptor* ptask); -int sys_yield(); +int sys_yield(task_yield_reason reason); int sys_kill(int id); int sys_register_as_server(char* name); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c index b45c2f4cc..91016a7dc 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c @@ -34,6 +34,7 @@ Modification: #include "actracer.h" #include "assert.h" #include "ipc.h" +#include "kalloc.h" #include "mmu_common.h" #include "multicores.h" #include "share_page.h" @@ -52,9 +53,10 @@ static void send_irq_to_user(int irq_num) struct Session* session = &irq_forward_table[irq_num].session; int len = IPC_ARG_INFO_BASE_OFFSET; len += sizeof(struct IpcArgInfo); + /* get message space and add session tail */ - /* add session tail */ - struct IpcMsg* buf = session->buf + session->tail; + void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->pgdir, (uintptr_t)session->buf)); + struct IpcMsg* buf = session_kern_vaddr + session->tail; memset((void*)buf, 0, len); session->tail = (session->tail + len) % session->capacity; @@ -73,20 +75,13 @@ static void send_irq_to_user(int irq_num) int user_irq_handler(int irq, void* tf, void* arg) { - static struct MmuCommonDone* p_mmu_driver = NULL; - if (p_mmu_driver == NULL) { - struct TraceTag mmu_driver_tag; - AchieveResourceTag(&mmu_driver_tag, RequireRootTag(), "/hardkernel/mmu-ac-resource"); - p_mmu_driver = (struct MmuCommonDone*)AchieveResource(&mmu_driver_tag); - } - if (irq_forward_table[irq].handle_task != NULL) { - p_mmu_driver->LoadPgdir((uintptr_t)V2P(kernel_irq_proxy->pgdir.pd_addr)); send_irq_to_user(irq); - p_mmu_driver->LoadPgdir((uintptr_t)V2P(cur_cpu()->task->pgdir.pd_addr)); next_task_emergency = irq_forward_table[irq].handle_task; - xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); + if (cur_cpu()->task != NULL) { + xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); + } } return 0; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c index f4dc7b868..19e112468 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c @@ -33,7 +33,7 @@ Modification: #include "log.h" -int sys_yield() +int sys_yield(task_yield_reason reason) { xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); return 0; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c index 5e3de560c..2a4a29248 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c @@ -48,7 +48,7 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u ret = sys_exit(cur_cpu()->task); break; case SYSCALL_YIELD: - ret = sys_yield(); + ret = sys_yield((task_yield_reason)param1); break; case SYSCALL_SERVER: ret = sys_register_as_server((char*)param1); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile index 11d37a8c4..a0f5db6ae 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := task.c scheduler.c +SRC_FILES := task.c schedule.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c b/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c similarity index 100% rename from Ubiquitous/XiZi_AIoT/softkernel/task/scheduler.c rename to Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index a7c76d4da..a81bbc920 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -259,6 +259,7 @@ static void _scheduler(struct SchedulerRightGroup right_group) cpu->task = next_task; p_mmu_driver->LoadPgdir((uintptr_t)V2P(next_task->pgdir.pd_addr)); context_switch(&cpu->scheduler, next_task->main_thread.context); + assert(cur_cpu()->task == NULL); assert(next_task->state != RUNNING); } } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/trap/Makefile index 9fef57c16..0a795948d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/Makefile @@ -1,6 +1,7 @@ SRC_FILES := default_irq_handler.c \ clock_irq_handler.c \ - software_irq_handler.c + software_irq_handler.c \ + abort_handler.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c new file mode 100644 index 000000000..a378ef5f9 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2006-2018 Frans Kaashoek, Robert Morris, Russ Cox, + * Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/** + * @file abort_handler.c + * @brief handle program abort + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2023.11.23 + */ + +/************************************************* +File name: abort_handler.c +Description: handle program abort +Others: +History: +1. Date: 2023-11-23 +Author: AIIT XUOS Lab +Modification: +1. Modify iabort and dabort handler(in dabort_handler() and iabort_handler()) +*************************************************/ +#include "core.h" +#include "memlayout.h" +#include "spinlock.h" +#include "trap_common.h" + +#include "assert.h" +#include "multicores.h" +#include "syscall.h" +#include "task.h" + +extern void context_switch(struct context**, struct context*); +void dabort_handler(struct trapframe* r) +{ + if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) { + assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock)); + dabort_reason(r); + panic("data abort exception\n"); + } + + xizi_enter_kernel(); + + struct TaskMicroDescriptor* cur_task = cur_cpu()->task; + ERROR("dabort in user space: %s\n", cur_task->name); + dabort_reason(r); + sys_exit(cur_task); + assert(cur_cpu()->task == NULL); + context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler); +} + +void iabort_handler(struct trapframe* r) +{ + if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) { + assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock)); + iabort_reason(r); + panic("kernel prefetch abort exception\n"); + } + + xizi_enter_kernel(); + + struct TaskMicroDescriptor* cur_task = cur_cpu()->task; + ERROR("iabort in user space: %s\n", cur_task->name); + iabort_reason(r); + sys_exit(cur_task); + assert(cur_cpu()->task == NULL); + context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler); +} diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index 50395ac65..9d2d36543 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -66,9 +66,8 @@ void intr_irq_dispatch(struct trapframe* tf) } struct TaskMicroDescriptor* current_task = cur_cpu()->task; - if (LIKELY(current_task != NULL)) { - current_task->main_thread.trapframe = tf; - } + assert(current_task != NULL); + current_task->main_thread.trapframe = tf; unsigned cpu = p_intr_driver->hw_cur_int_cpu(int_info); unsigned irq = p_intr_driver->hw_cur_int_num(int_info); @@ -86,7 +85,7 @@ void intr_irq_dispatch(struct trapframe* tf) p_intr_driver->curr_int[cpu] = 0; p_intr_driver->hw_after_irq(int_info); - if ((cur_cpu()->task == NULL && current_task != NULL) || current_task->state != RUNNING) { + if (cur_cpu()->task == NULL || current_task->state != RUNNING) { cur_cpu()->task = NULL; context_switch(¤t_task->main_thread.context, cur_cpu()->scheduler); } @@ -102,13 +101,18 @@ void xizi_enter_kernel() spinlock_lock(&whole_kernel_lock); } +bool xizi_try_enter_kernel() +{ + p_intr_driver->cpu_irq_disable(); + if (spinlock_try_lock(&whole_kernel_lock)) { + return true; + } + + return false; +} + void xizi_leave_kernel() { spinlock_unlock(&whole_kernel_lock); p_intr_driver->cpu_irq_enable(); -} - -bool xizi_is_in_kernel() -{ - return is_spinlock_locked(&whole_kernel_lock); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c index c88bffc13..dce844139 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/software_irq_handler.c @@ -71,10 +71,10 @@ void software_irq_dispatch(struct trapframe* tf) cur_cpu()->task = NULL; context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler); } - assert(cur_task == cur_cpu()->task); if (syscall_num == SYSCALL_EXIT) { panic("Exit reaches"); } + assert(cur_task == cur_cpu()->task); xizi_leave_kernel(); } \ No newline at end of file From e5df6012afbcc15c561bb8c3cacd6d118da3d50c Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Sun, 28 Apr 2024 15:49:41 +0800 Subject: [PATCH 22/24] Support blocking task. --- .../XiZi_AIoT/softkernel/include/task.h | 7 ++++ .../softkernel/syscall/sys_poll_session.c | 9 ++++++ .../XiZi_AIoT/softkernel/syscall/sys_state.c | 8 +++++ .../XiZi_AIoT/softkernel/syscall/sys_yield.c | 12 ++++++- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 32 ++++++++++++++++--- .../XiZi_AIoT/softkernel/trap/abort_handler.c | 2 ++ 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index a69701ee6..da65da17f 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -85,6 +85,7 @@ struct TaskMicroDescriptor { /* task communication resources */ struct double_list_node cli_sess_listhead; struct double_list_node svr_sess_listhead; + bool current_ipc_handled; struct KBuddy* massive_ipc_allocator; struct TraceTag server_identifier; @@ -103,6 +104,7 @@ struct SchedulerRightGroup { struct XiziTaskManager { struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */ + struct double_list_node task_blocked_list_head; struct slab_allocator task_allocator; struct slab_allocator task_buddy_allocator; uint32_t next_pid; @@ -120,8 +122,13 @@ struct XiziTaskManager { struct TaskMicroDescriptor* (*next_runnable_task)(void); /* function that's runing by kernel thread context, schedule use tasks */ void (*task_scheduler)(struct SchedulerRightGroup); + + /* handle task state */ /* call to yield current use task */ void (*task_yield_noschedule)(struct TaskMicroDescriptor* task, bool is_blocking); + /* block and unblock task */ + void (*task_block)(struct TaskMicroDescriptor* task); + void (*task_unblock)(struct TaskMicroDescriptor* task); /* set task priority */ void (*set_cur_task_priority)(int priority); }; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c index 66275cacb..4a9eb2999 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_poll_session.c @@ -55,6 +55,15 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity) return -1; } // update session_backend + // if current session is handled + if (server_session->head != userland_session_arr[i].head) { + struct TaskMicroDescriptor* client = SERVER_SESSION_BACKEND(server_session)->client; + if (client->state == BLOCKED) { + xizi_task_manager.task_unblock(client); + } else { + client->current_ipc_handled = true; + } + } server_session->head = userland_session_arr[i].head; server_session->tail = userland_session_arr[i].tail; doubleListDel(cur_node); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c index ff9e783e9..01309cb22 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c @@ -85,6 +85,14 @@ void show_tasks(void) LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->mem_size >> 10); } } + + DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_blocked_list_head, node) + { + LOG_PRINTF(" BLOCK "); + _padding(task->name); + LOG_PRINTF(" %d %s %d %d\n", task->pid, task->name, task->priority, task->mem_size >> 10); + } + LOG_PRINTF("******************************************************\n"); return; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c index 19e112468..7db762765 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_yield.c @@ -35,6 +35,16 @@ Modification: int sys_yield(task_yield_reason reason) { - xizi_task_manager.task_yield_noschedule(cur_cpu()->task, false); + struct TaskMicroDescriptor* cur_task = cur_cpu()->task; + xizi_task_manager.task_yield_noschedule(cur_task, false); + + // handle ipc block + if ((reason & SYS_TASK_YIELD_BLOCK_IPC) != 0) { + if (cur_task->current_ipc_handled) { + cur_task->current_ipc_handled = false; + } else { + xizi_task_manager.task_block(cur_task); + } + } return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index a81bbc920..b7133e3fe 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -48,6 +48,7 @@ static void _task_manager_init() for (int i = 0; i < TASK_MAX_PRIORITY; i++) { doubleListNodeInit(&xizi_task_manager.task_list_head[i]); } + doubleListNodeInit(&xizi_task_manager.task_blocked_list_head); // init task (slab) allocator slab_init(&xizi_task_manager.task_allocator, sizeof(struct TaskMicroDescriptor)); slab_init(&xizi_task_manager.task_buddy_allocator, sizeof(struct KBuddy)); @@ -271,11 +272,7 @@ static void _task_yield_noschedule(struct TaskMicroDescriptor* task, bool blocki // rearrage current task position doubleListDel(&task->node); if (task->state == RUNNING) { - if (!blocking) { - task->state = READY; - } else { - task->state = BLOCKED; - } + task->state = READY; } task->remain_tick = TASK_CLOCK_TICK; if (task == cur_cpu()->task) { @@ -284,6 +281,28 @@ static void _task_yield_noschedule(struct TaskMicroDescriptor* task, bool blocki doubleListAddOnBack(&task->node, &xizi_task_manager.task_list_head[task->priority]); } +static void _task_block(struct TaskMicroDescriptor* task) +{ + assert(task != NULL); + assert(task->state != RUNNING); + doubleListDel(&task->node); + if (xizi_task_manager.task_list_head[task->priority].next == &xizi_task_manager.task_list_head[task->priority]) { + ready_task_priority &= ~(1 << task->priority); + } + task->state = BLOCKED; + doubleListAddOnHead(&task->node, &xizi_task_manager.task_blocked_list_head); +} + +static void _task_unblock(struct TaskMicroDescriptor* task) +{ + assert(task != NULL); + assert(task->state == BLOCKED); + doubleListDel(&task->node); + task->state = READY; + doubleListAddOnHead(&task->node, &xizi_task_manager.task_list_head[task->priority]); + ready_task_priority |= (1 << task->priority); +} + static void _set_cur_task_priority(int priority) { if (priority < 0 || priority >= TASK_MAX_PRIORITY) { @@ -312,6 +331,9 @@ struct XiziTaskManager xizi_task_manager = { .next_runnable_task = max_priority_runnable_task, .task_scheduler = _scheduler, + + .task_block = _task_block, + .task_unblock = _task_unblock, .task_yield_noschedule = _task_yield_noschedule, .set_cur_task_priority = _set_cur_task_priority }; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c index a378ef5f9..1a8d9b37a 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c @@ -65,6 +65,7 @@ void dabort_handler(struct trapframe* r) sys_exit(cur_task); assert(cur_cpu()->task == NULL); context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler); + panic("dabort end should never be reashed.\n"); } void iabort_handler(struct trapframe* r) @@ -83,4 +84,5 @@ void iabort_handler(struct trapframe* r) sys_exit(cur_task); assert(cur_cpu()->task == NULL); context_switch(&cur_task->main_thread.context, cur_cpu()->scheduler); + panic("iabort end should never be reashed.\n"); } From 695dd912019e817688acd926c4f15338ccd0c498 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Sun, 28 Apr 2024 18:34:45 +0800 Subject: [PATCH 23/24] Close interrupt during trapframe construction. --- .../intr/arm/armv7-a/cortex-a9/error_debug.c | 2 ++ .../hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S | 10 +++++++++- Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h | 2 +- .../arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h | 2 +- .../arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h | 2 +- .../services/boards/imx6q-sabrelite/test_irq_sender.c | 4 +++- Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c | 1 + Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h | 2 +- Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c | 2 ++ .../XiZi_AIoT/softkernel/trap/default_irq_handler.c | 3 +-- 10 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c index fc1fe18d7..af072ff91 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/error_debug.c @@ -51,6 +51,8 @@ Modification: void dump_tf(struct trapframe* tf) { + KPrintf("sp_usr: 0x%x\n", tf->sp_usr); + KPrintf("lr_usr: 0x%x\n", tf->lr_usr); KPrintf("lr_svc: 0x%x\n", tf->lr_svc); KPrintf(" spsr: 0x%x\n", tf->spsr); KPrintf(" r0: 0x%x\n", tf->r0); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S index 6d9dcb009..3dadefdc5 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S @@ -47,10 +47,13 @@ trap_return: ldmfd r13!, {r14} ldmfd r13!, {r2} msr spsr_cxsf, r2 - ldmfd r13!, {r0-r12, pc}^ // restore context and return + ldmfd r13!, {r0-r12} // restore context and return + cpsie i + ldmfd r13!, {pc}^ // restore context and return user_trap_swi_enter: # save trapframe to swi stack + cpsid i stmfd sp!, {r0-r12, r14} // save context mrs r2, spsr // copy spsr to r2 stmfd r13!, {r2} // save r2(spsr) to the stack @@ -66,6 +69,7 @@ user_trap_swi_enter: trap_irq_enter: # save it on the stack as r14 is banked + cpsid i sub r14, r14, #4 // r14 (lr) contains the interrupted PC stmfd r13!, {r0-r2, r14} // mrs r1, spsr // save spsr_irq @@ -95,6 +99,7 @@ trap_irq_enter: b trap_return trap_reset_enter: + cpsid i mov r14, #0 // lr: not defined on reset stmfd r13!, {r0-r12, r14} mrs r2, spsr // copy spsr to r2 @@ -108,6 +113,7 @@ trap_reset_enter: bl _vector_jumper trap_dabort: + cpsid i sub r14, r14, #8 // lr: instruction causing the abort stmfd r13!, {r0-r12, r14} mrs r2, spsr // copy spsr to r2 @@ -121,6 +127,7 @@ trap_dabort: bl dabort_handler trap_iabort: + cpsid i sub r14, r14, #4 // lr: instruction causing the abort stmfd r13!, {r0-r12, r14} mrs r2, spsr // copy spsr to r2 @@ -134,6 +141,7 @@ trap_iabort: bl iabort_handler trap_undefined_instruction: + cpsid i stmfd r13!, {r0-r12, r14} mrs r2, spsr // copy spsr to r2 stmfd r13!, {r2} // save r2(spsr) to the stack diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h index 660db5c19..d082cc67f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/spinlock.h @@ -34,7 +34,7 @@ Modification: #define STACK_DEPTH 32 struct spinlock { // Mutex. - uint32_t owner_cpu; // 1 for locked, 0 for unlocked + volatile uint32_t owner_cpu; // 1 for locked, 0 for unlocked char name[28]; // The call stack (an array of program counters) } __attribute__((aligned(32))); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h index b6ed98e68..26957c7bb 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h @@ -56,7 +56,7 @@ Modification: #define MAX_NR_FREE_PAGES ((PHY_MEM_STOP - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT) /* User memory layout */ -#define USER_STACK_SIZE PAGE_SIZE +#define USER_STACK_SIZE MODE_STACK_SIZE #define USER_MEM_BASE (0x00000000) #define USER_MEM_TOP DEV_VRTMEM_BASE #define USER_IPC_SPACE_BASE (0x70000000) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h index 855d27835..cf480c399 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h @@ -56,7 +56,7 @@ Modification: #define MAX_NR_FREE_PAGES ((PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT) /* User memory layout */ -#define USER_STACK_SIZE PAGE_SIZE +#define USER_STACK_SIZE MODE_STACK_SIZE #define USER_MEM_BASE (0x00000000) #define USER_MEM_TOP DEV_VRTMEM_BASE #define USER_IPC_SPACE_BASE (0x70000000) diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c index a43189c7a..d89dba927 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c @@ -89,7 +89,9 @@ int main() mmap(ARM_PERIPHERAL_VIRT_BASE, ARM_PERIPHERAL_BASE, 0x2000, true); printf("%s: Sending soft interrupt\n", prog_name); - gic_send_sgi(SW_INTERRUPT_3, 0xF, kGicSgiFilter_UseTargetList); + while (1) { + gic_send_sgi(SW_INTERRUPT_3, 0xF, kGicSgiFilter_UseTargetList); + } printf("%s: Soft interrupt send done\n", prog_name); exit(); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c index 788008706..7286146c6 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c @@ -159,6 +159,7 @@ void delay_session(void) void ipc_server_loop(struct IpcNode* ipc_node) { struct Session session_list[NR_MAX_SESSION]; + memset(session_list, 0, sizeof(session_list)); for (;;) { /* if connect sessions are greater than NR_MAX_SESSION, a full round will require multiple polls. diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h index 86148a9a6..c7e399f05 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.h @@ -37,7 +37,7 @@ Modification: #include "ipcargs.h" #include "session.h" -#define NR_MAX_SESSION 16 +#define NR_MAX_SESSION 32 #define IPC_MSG_MAGIC 0xABCDDCBA typedef struct { diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c index 1a8d9b37a..8e13e7d86 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/abort_handler.c @@ -53,6 +53,7 @@ void dabort_handler(struct trapframe* r) { if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) { assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock)); + ERROR("dabort in kernel, current task: %s\n", cur_cpu()->task == NULL ? "NULL" : cur_cpu()->task->name); dabort_reason(r); panic("data abort exception\n"); } @@ -72,6 +73,7 @@ void iabort_handler(struct trapframe* r) { if (r->pc >= DEV_VRTMEM_BASE && is_spinlock_hold_by_current_cpu(&whole_kernel_lock)) { assert(is_spinlock_hold_by_current_cpu(&whole_kernel_lock)); + ERROR("iabort in kernel, current task: %s\n", cur_cpu()->task == NULL ? "NULL" : cur_cpu()->task->name); iabort_reason(r); panic("kernel prefetch abort exception\n"); } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index 9d2d36543..d3fceb839 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -114,5 +114,4 @@ bool xizi_try_enter_kernel() void xizi_leave_kernel() { spinlock_unlock(&whole_kernel_lock); - p_intr_driver->cpu_irq_enable(); -} \ No newline at end of file +} From 8d2d7e3e09fafdc26dfe0bf5c1706df7c4e84a70 Mon Sep 17 00:00:00 2001 From: TXuian <1163589503@qq.com> Date: Mon, 29 Apr 2024 10:46:07 +0800 Subject: [PATCH 24/24] Make sure that kernel is interrupt disabled. --- .../intr/arm/armv7-a/cortex-a9/trampoline.S | 112 +++++++++++------- .../boards/imx6q-sabrelite/test_irq_sender.c | 6 +- .../XiZi_AIoT/services/lib/ipc/libipc.c | 20 ++-- .../XiZi_AIoT/services/lib/ipc/session.h | 2 +- .../softkernel/syscall/sys_connect_session.c | 11 +- .../softkernel/syscall/sys_register_irq.c | 13 +- .../softkernel/trap/default_irq_handler.c | 5 +- 7 files changed, 106 insertions(+), 63 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S index 3dadefdc5..da7018964 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/intr/arm/armv7-a/cortex-a9/trampoline.S @@ -47,9 +47,7 @@ trap_return: ldmfd r13!, {r14} ldmfd r13!, {r2} msr spsr_cxsf, r2 - ldmfd r13!, {r0-r12} // restore context and return - cpsie i - ldmfd r13!, {pc}^ // restore context and return + ldmfd r13!, {r0-r12, pc}^ // restore context and return user_trap_swi_enter: # save trapframe to swi stack @@ -98,62 +96,96 @@ trap_irq_enter: bl intr_irq_dispatch b trap_return -trap_reset_enter: - cpsid i - mov r14, #0 // lr: not defined on reset - stmfd r13!, {r0-r12, r14} - mrs r2, spsr // copy spsr to r2 - stmfd r13!, {r2} // save r2(spsr) to the stack - stmfd r13!, {r14} // save r14 again (it is not really correct) - stmfd r13, {sp, lr}^ // save user mode sp and lr - sub r13, r13, #8 - - # call traps (trapframe *fp) - mov r0, r13 // copy r13_svc to r0 - bl _vector_jumper - trap_dabort: + # save it on the stack as r14 is banked cpsid i - sub r14, r14, #8 // lr: instruction causing the abort - stmfd r13!, {r0-r12, r14} - mrs r2, spsr // copy spsr to r2 - stmfd r13!, {r2} // save r2(spsr) to the stack - stmfd r13!, {r14} // save r14 again (it is not really correct) + sub r14, r14, #8 // r14 (lr) contains the interrupted PC + stmfd r13!, {r0-r2, r14} // + mrs r1, spsr // save spsr_irq + mov r0, r13 // save stack stop (r13_irq) + add r13, r13, #16 // reset the IRQ stack + + # switch to the SVC mode + mrs r2, cpsr + bic r2, r2, #ARM_CPSR_MODE_MASK + orr r2, r2, #ARM_MODE_SVC + msr cpsr_cxsf, r2 + + # build the trap frame + ldr r2, [r0, #12] // read the r14_irq, then save it + stmfd r13!, {r2} + stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked) + ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack + stmfd r13!, {r3-r5} + stmfd r13!, {r1} // save spsr + stmfd r13!, {lr} // save lr_svc + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - # call traps (trapframe *fp) - mov r0, r13 // save trapframe as the first parameter + mov r0, r13 // trapframe as parameters bl dabort_handler trap_iabort: +# save it on the stack as r14 is banked cpsid i - sub r14, r14, #4 // lr: instruction causing the abort - stmfd r13!, {r0-r12, r14} - mrs r2, spsr // copy spsr to r2 - stmfd r13!, {r2} // save r2(spsr) to the stack - stmfd r13!, {r14} // save r14 again (it is not really correct) - stmfd r13, {sp, lr}^ // save user mode sp and lr + sub r14, r14, #4 // r14 (lr) contains the interrupted PC + stmfd r13!, {r0-r2, r14} // + mrs r1, spsr // save spsr_irq + mov r0, r13 // save stack stop (r13_irq) + add r13, r13, #16 // reset the IRQ stack + + # switch to the SVC mode + mrs r2, cpsr + bic r2, r2, #ARM_CPSR_MODE_MASK + orr r2, r2, #ARM_MODE_SVC + msr cpsr_cxsf, r2 + + # build the trap frame + ldr r2, [r0, #12] // read the r14_irq, then save it + stmfd r13!, {r2} + stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked) + ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack + stmfd r13!, {r3-r5} + stmfd r13!, {r1} // save spsr + stmfd r13!, {lr} // save lr_svc + + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - # call traps (trapframe *fp) - mov r0, r13 // save trapframe as the first parameter + mov r0, r13 // trapframe as parameters bl iabort_handler trap_undefined_instruction: + # save it on the stack as r14 is banked cpsid i - stmfd r13!, {r0-r12, r14} - mrs r2, spsr // copy spsr to r2 - stmfd r13!, {r2} // save r2(spsr) to the stack - stmfd r13!, {r14} // save r14 again (it is not really correct) - stmfd r13, {sp, lr}^ // save user mode sp and lr + sub r14, r14, #4 // r14 (lr) contains the interrupted PC + stmfd r13!, {r0-r2, r14} // + mrs r1, spsr // save spsr_irq + mov r0, r13 // save stack stop (r13_irq) + add r13, r13, #16 // reset the IRQ stack + + # switch to the SVC mode + mrs r2, cpsr + bic r2, r2, #ARM_CPSR_MODE_MASK + orr r2, r2, #ARM_MODE_SVC + msr cpsr_cxsf, r2 + + # build the trap frame + ldr r2, [r0, #12] // read the r14_irq, then save it + stmfd r13!, {r2} + stmfd r13!, {r3-r12} // r4-r12 are preserved (non-banked) + ldmfd r0, {r3-r5} // copy r0-r2 over from irq stack + stmfd r13!, {r3-r5} + stmfd r13!, {r1} // save spsr + stmfd r13!, {lr} // save lr_svc + + stmfd r13, {sp, lr}^ // save user mode sp and lr sub r13, r13, #8 - # call traps (trapframe *fp) - mov r0, r13 // save trapframe as the first parameter + mov r0, r13 // trapframe as parameters bl handle_undefined_instruction - init_stack: # set the stack for Other mode mrs r2, cpsr diff --git a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c index d89dba927..21e4a2fef 100644 --- a/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c +++ b/Ubiquitous/XiZi_AIoT/services/boards/imx6q-sabrelite/test_irq_sender.c @@ -88,9 +88,11 @@ int main() printf("%s: Mapping GIC\n", prog_name); mmap(ARM_PERIPHERAL_VIRT_BASE, ARM_PERIPHERAL_BASE, 0x2000, true); - printf("%s: Sending soft interrupt\n", prog_name); - while (1) { + int send_time = 1000; + printf("%s: Sending soft interrupt for %d times\n", prog_name, send_time); + for (int i = 0; i < send_time; i++) { gic_send_sgi(SW_INTERRUPT_3, 0xF, kGicSgiFilter_UseTargetList); + printf("%s: Soft interrupt send 1 time\n", prog_name); } printf("%s: Soft interrupt send done\n", prog_name); exit(); diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c index 7286146c6..e00df4e2d 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/libipc.c @@ -179,24 +179,22 @@ void ipc_server_loop(struct IpcNode* ipc_node) a session could be delay in case one of its message(current message) needs to wait for an interrupt message's arrival interfaces[opcode] should explicitly call delay_session() and return to delay this session */ - while (msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1) { + while (msg->header.magic == IPC_MSG_MAGIC && msg->header.valid == 1 && msg->header.done == 0) { // printf("session %d [%d, %d]\n", session_list[i].id, session_list[i].head, session_list[i].tail); if (session_used_size(&session_list[i]) == 0 && session_forward_tail(&session_list[i], msg->header.len) < 0) { break; } // this is a message needs to handle - if (msg->header.done != 1) { - if (ipc_node->interfaces[msg->header.opcode]) { - ipc_node->interfaces[msg->header.opcode](msg); - // check if this session is delayed by op handler, all messages after the delayed message in current session is blocked. - if (session_delayed) { - session_delayed = false; - break; - } - } else { - printf("Unsupport opcode(%d) for server: %s\n", msg->header.opcode, ipc_node->name); + if (ipc_node->interfaces[msg->header.opcode]) { + ipc_node->interfaces[msg->header.opcode](msg); + // check if this session is delayed by op handler, all messages after the delayed message in current session is blocked. + if (session_delayed) { + session_delayed = false; + break; } + } else { + printf("Unsupport opcode(%d) for server: %s\n", msg->header.opcode, ipc_node->name); } // current msg is a message that needs to ignore // finish this message in server's perspective diff --git a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h index 4979f74ca..196c6bf5b 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h +++ b/Ubiquitous/XiZi_AIoT/services/lib/ipc/session.h @@ -56,7 +56,7 @@ __attribute__((__always_inline__)) static inline int session_remain_capacity(str __attribute__((__always_inline__)) static inline int session_forward_head(struct Session* session, int len) { if (len > session_used_size(session)) { - printf("forward head with too much size\n"); + printf("forward head with too much size, session used size: %d\n", session_used_size(session)); return -1; } session->head = (session->head + len) % session->capacity; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c index 84fc74109..178ef83e3 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_connect_session.c @@ -35,13 +35,13 @@ Modification: #include "syscall.h" #include "task.h" -int create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session) +struct session_backend* create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session) { // create share pages struct session_backend* session_backend = xizi_share_page_manager.create_share_pages(client, server, capacity); if (UNLIKELY(session_backend == NULL)) { DEBUG("create_share_pages failed\n"); - return -1; + return NULL; } // init user_session @@ -51,7 +51,7 @@ int create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDes user_session->tail = 0; user_session->id = session_backend->session_id; - return 0; + return session_backend; } int sys_connect_session(char* path, int capacity, struct Session* user_session) @@ -76,5 +76,8 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session) struct TaskMicroDescriptor* server = AchieveResource(&server_tag); assert(server != NULL); - return create_session_inner(client, server, capacity, user_session); + if (create_session_inner(client, server, capacity, user_session) == NULL) { + return -1; + } + return 0; } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c index 91016a7dc..e7e0eb8cc 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_register_irq.c @@ -45,6 +45,7 @@ static struct TaskMicroDescriptor* kernel_irq_proxy; static struct { struct TaskMicroDescriptor* handle_task; struct Session session; + struct session_backend* p_kernel_session; int opcode; } irq_forward_table[NR_IRQS]; @@ -53,10 +54,16 @@ static void send_irq_to_user(int irq_num) struct Session* session = &irq_forward_table[irq_num].session; int len = IPC_ARG_INFO_BASE_OFFSET; len += sizeof(struct IpcArgInfo); - /* get message space and add session tail */ + /* get message space and add session tail */ void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->pgdir, (uintptr_t)session->buf)); struct IpcMsg* buf = session_kern_vaddr + session->tail; + + /* check if server session is full */ + if (buf->header.magic == IPC_MSG_MAGIC && buf->header.done == 0) { + DEBUG("irq server cannot handle new interrupt by now.\n"); + return; + } memset((void*)buf, 0, len); session->tail = (session->tail + len) % session->capacity; @@ -86,7 +93,7 @@ int user_irq_handler(int irq, void* tf, void* arg) return 0; } -extern int create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session); +extern struct session_backend* create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session); /// @warning no tested. static struct XiziTrapDriver* p_intr_driver = NULL; @@ -118,7 +125,7 @@ int sys_register_irq(int irq_num, int irq_opcode) struct TaskMicroDescriptor* cur_task = cur_cpu()->task; irq_forward_table[irq_num].handle_task = cur_task; irq_forward_table[irq_num].opcode = irq_opcode; - create_session_inner(kernel_irq_proxy, cur_task, PAGE_SIZE, &irq_forward_table[irq_num].session); + irq_forward_table[irq_num].p_kernel_session = create_session_inner(kernel_irq_proxy, cur_task, PAGE_SIZE, &irq_forward_table[irq_num].session); p_intr_driver->bind_irq_handler(irq_num, user_irq_handler); cur_task->bind_irq = true; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c index d3fceb839..7c3dc2c81 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/default_irq_handler.c @@ -97,13 +97,13 @@ intr_leave_interrupt: void xizi_enter_kernel() { - p_intr_driver->cpu_irq_disable(); + /// @warning trampoline is responsible for closing interrupt spinlock_lock(&whole_kernel_lock); } bool xizi_try_enter_kernel() { - p_intr_driver->cpu_irq_disable(); + /// @warning trampoline is responsible for closing interrupt if (spinlock_try_lock(&whole_kernel_lock)) { return true; } @@ -113,5 +113,6 @@ bool xizi_try_enter_kernel() void xizi_leave_kernel() { + /// @warning trampoline is responsible for eabling interrupt by using user's state register spinlock_unlock(&whole_kernel_lock); }