modify XiUOS DIR : (1.add plc_demo in APP_Framework/control_app; 2.add industrial_network、industrial_fieldbus and industrial_wlan; 3.add XiZi_AIoT and modify XiZi as XiZi_IIoT.)

This commit is contained in:
Liu_Weichao
2022-09-27 20:39:52 +08:00
parent dbca22a1a6
commit e14fa6ff8e
5009 changed files with 1019 additions and 3084 deletions
+53
View File
@@ -0,0 +1,53 @@
# The following three platforms support compatiable instructions.
ifeq ($(CONFIG_BOARD_CORTEX_M3_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m3
endif
ifeq ($(CONFIG_BOARD_CORTEX_M4_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m4
endif
ifeq ($(CONFIG_BOARD_STM32F103_NANO),y)
SRC_DIR := shared
SRC_DIR += cortex-m3
endif
ifeq ($(CONFIG_BOARD_STM32F407_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m4
endif
ifeq ($(CONFIG_BOARD_CORTEX_M4_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m4
endif
ifeq ($(CONFIG_BOARD_HC32F4A0_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m4
endif
ifeq ($(CONFIG_BOARD_CORTEX_M7_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m7
endif
ifeq ($(CONFIG_BOARD_IMXRT1176_SBC_EVB),y)
SRC_DIR := shared
SRC_DIR += cortex-m7
endif
# cortex-m0 is ARMv6-m
ifeq ($(CONFIG_BOARD_CORTEX_M0_EVB),y)
SRC_DIR += cortex-m0
endif
ifeq ($(CONFIG_BOARD_NUVOTON_M2354),y)
SRC_DIR += cortex-m23
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,3 @@
SRC_FILES := boot.c interrupt.c interrupt_vector.S pendsv.S prepare_ahwstack.c arm32_switch.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,28 @@
/*
* 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.
*/
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include <xs_base.h>
#define ARCH_MAX_IRQ_NUM (48)
#define ARCH_IRQ_NUM_OFFSET 0
#define SYSTICK_IRQN 15
#define UART1_IRQn 18
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
@@ -0,0 +1,241 @@
/*
* 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 <xs_base.h>
#include <xs_ktask.h>
#define SCB_VTOR "0xE000ED08"
#define NVIC_INT_CTRL "0xE000ED04"
#define NVIC_SYSPRI2 "0xE000ED20"
#define NVIC_PENDSV_PRI "0x00FF0000"
#define NVIC_PENDSVSET "0x10000000"
/* We replaced instructions that were not supported in thumb mode. */
void __attribute__((naked)) HwInterruptcontextSwitch(x_ubase from, x_ubase to, struct TaskDescriptor *to_task, void *context)
{
asm volatile ("PUSH {R4}");
asm volatile ("PUSH {R5}");
asm volatile ("LDR r4, =KtaskSwitchInterruptFlag");
asm volatile ("LDR r5, [r4]");
asm volatile ("CMP r5, #1");
asm volatile ("POP {R5}");
asm volatile ("POP {R4}");
asm volatile ("BEQ Arm32SwitchReswitch");
asm volatile ("PUSH {R4}");
asm volatile ("PUSH {R5}");
asm volatile ("LDR r4, =KtaskSwitchInterruptFlag");
asm volatile ("MOV r5, #1");
asm volatile ("STR r5, [r4]");
asm volatile ("LDR r4, =InterruptFromKtask");
asm volatile ("STR r0, [r4]");
asm volatile ("POP {R5}");
asm volatile ("POP {R4}");
asm volatile ("B Arm32SwitchReswitch");
}
void __attribute__((naked)) Arm32SwitchReswitch()
{
asm volatile ("PUSH {R4}");
asm volatile ("LDR r4, =InterruptToKtask");
asm volatile ("STR r1, [r4]");
asm volatile ("LDR r4, =InterruptToKtaskDescriptor");
asm volatile ("STR r2, [r4]");
asm volatile ("LDR r0, =" NVIC_INT_CTRL);
asm volatile ("LDR r1, =" NVIC_PENDSVSET);
asm volatile ("STR r1, [r0]");
asm volatile ("POP {R4}");
asm volatile ("BX LR");
}
void __attribute__((naked)) SwitchKtaskContext(x_ubase from, x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile("B HwInterruptcontextSwitch");
}
void SwitchKtaskContextTo(x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile ("LDR r2, =InterruptToKtask");
asm volatile ("STR r0, [r2]");
asm volatile ("LDR r2, =InterruptToKtaskDescriptor");
asm volatile ("STR r1, [r2]");
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
asm volatile ("MRS r2, CONTROL");
asm volatile ("BIC r2, #0x04");
asm volatile ("MSR CONTROL, r2");
#endif
asm volatile ("LDR r1, =InterruptFromKtask");
asm volatile ("MOV r0, #0x0");
asm volatile ("STR r0, [r1]");
asm volatile ("LDR r1, =KtaskSwitchInterruptFlag");
asm volatile ("MOV r0, #1");
asm volatile ("STR r0, [r1]");
asm volatile ("LDR r0, =" NVIC_SYSPRI2);
asm volatile ("LDR r1, =" NVIC_PENDSV_PRI);
// asm volatile ("LDR.W r2, [r0,#0x00]");
asm volatile ("LDR r2, [r0,#0x00]");
asm volatile ("ORR r1,r1,r2");
asm volatile ("STR r1, [r0]");
asm volatile ("LDR r0, =" NVIC_INT_CTRL);
asm volatile ("LDR r1, =" NVIC_PENDSVSET);
asm volatile ("STR r1, [r0]");
asm volatile ("LDR r0, =" SCB_VTOR);
asm volatile ("LDR r0, [r0]");
asm volatile ("LDR r0, [r0]");
asm volatile ("NOP");
asm volatile ("MSR msp, r0");
asm volatile ("CPSIE F");
asm volatile ("CPSIE I");
asm volatile ("BX lr");
}
void __attribute__((naked)) HardFaultHandler()
{
asm volatile ("MRS r0, msp");
// asm volatile ("TST lr, #0x04");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("TST r1, r2");
asm volatile ("BEQ Arm32SwitchGetSpDone");
asm volatile ("MRS r0, psp");
asm volatile ("B Arm32SwitchGetSpDone");
}
void __attribute__((naked)) Arm32SwitchGetSpDone()
{
asm volatile ("MRS r3, primask");
// asm volatile ("STMFD r0!, {r3 - r11}");
asm volatile ("SUB r0, r0, #0x24");
asm volatile ("STMIA r0!, {r3 - r7}");
asm volatile ("MOV r3, r8");
asm volatile ("MOV r4, r9");
asm volatile ("MOV r5, r10");
asm volatile ("MOV r6, r11");
asm volatile ("STMIA r0!, {r3 - r6}");
asm volatile ("SUB r0, r0, #0x24");
// asm volatile ("STMFD r0!, {lr}");
asm volatile ("SUB r0, r0, #0x4");
asm volatile ("MOV r0, lr");
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
asm volatile ("MOV r4, #0x00");
// asm volatile ("TST lr, #0x10");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x10");
asm volatile ("TST r1, r2");
asm volatile ("MOVEQ r4, #0x01");
asm volatile ("STMFD r0!, {r4}");
#endif
// asm volatile ("TST lr, #0x04");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("TST r1, r2");
asm volatile ("BEQ Arm32SwitchUpdateMsp");
asm volatile ("MSR psp, r0");
asm volatile ("B Arm32SwitchUpdateDone");
asm volatile ("B Arm32SwitchUpdateMsp");
}
void __attribute__((naked)) Arm32SwitchUpdateMsp()
{
asm volatile ("MSR msp, r0");
asm volatile ("B Arm32SwitchUpdateDone");
}
void __attribute__((naked)) Arm32SwitchUpdateDone()
{
asm volatile ("PUSH {LR}");
asm volatile ("BL HwHardFaultException");
// asm volatile ("POP {LR}");
asm volatile ("POP {R1}");
asm volatile ("MOV lr, r1");
// asm volatile ("ORR lr, lr, #0x04");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("ORR r1, r2");
asm volatile ("MOV lr, r1");
asm volatile ("BX lr");
}
void __attribute__((naked)) MemFaultHandler()
{
asm volatile ("MRS r0, msp");
// asm volatile ("TST lr, #0x04");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("TST r1, r2");
asm volatile ("BEQ Arm32Switch1");
asm volatile ("MRS r0, psp");
asm volatile ("B Arm32Switch1");
}
void __attribute__((naked)) Arm32Switch1()
{
asm volatile ("MRS r3, primask");
// asm volatile ("STMFD r0!, {r3 - r11}");
asm volatile ("SUB r0, r0, #0x24");
asm volatile ("STMIA r0!, {r3 - r7}");
asm volatile ("MOV r3, r8");
asm volatile ("MOV r4, r9");
asm volatile ("MOV r5, r10");
asm volatile ("MOV r6, r11");
asm volatile ("STMIA r0!, {r3 - r6}");
asm volatile ("SUB r0, r0, #0x24");
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
asm volatile ("MOV r4, #0x00");
// asm volatile ("TST lr, #0x10");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x10");
asm volatile ("TST r1, r2");
asm volatile ("MOV lr, r1");
asm volatile ("MOVEQ r4, #0x01");
asm volatile ("STMFD r0!, {r4}");
#endif
// asm volatile ("STMFD r0!, {lr}");
asm volatile ("SUB r0, r0, #0x4");
asm volatile ("MOV r0, lr");
asm volatile ("PUSH {LR}");
asm volatile ("BL MemFaultHandle");
// asm volatile ("POP {LR}");
asm volatile ("POP {R5}");
asm volatile ("MOV lr, r5");
// asm volatile ("ORR lr, lr, #0x04");
asm volatile ("MOV r5, lr");
asm volatile ("MOV r6, #0x04");
asm volatile ("ORR r5, r6");
asm volatile ("MOV lr, r5");
asm volatile ("BX lr");
}
@@ -0,0 +1,75 @@
//*****************************************************************************
//
// startup_gcc.c - Startup code for use with GNU tools.
//
// Copyright (c) 2013 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 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.
//
// Neither the name of Texas Instruments Incorporated 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
// OWNER 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.
//
// This is part of revision 10636 of the Stellaris Firmware Development Package.
//
//*****************************************************************************
/**
* @file boot.c
* @brief derived from Stellaris Firmware Development Package
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-13
*/
/*************************************************
File name: boot.c
Description: Reset and init function
Others:
History:
1. Date: 2021-05-13
Author: AIIT XUOS Lab
Modification:
1. take startup_gcc.c from revision 10636 of the Stellaris Firmware Development Package for XiZi kernel
*************************************************/
extern unsigned _sdata[], _edata[],
_sbss[], _ebss[], _etext[], _sidata[];
extern int entry(void);
void
Reset_Handler(void)
{
unsigned *p, *q;
p = _sdata; q = _sidata;
while (p < _edata) *p++ = *q++;
p = _sbss;
while (p < _ebss) *p++ = 0;
entry();
}
@@ -0,0 +1,83 @@
/*
* 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 interrupt.c
* @brief support arm cortex-m0 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
*/
#include <xs_base.h>
#include <xs_isr.h>
x_base __attribute__((naked)) DisableLocalInterrupt()
{
asm volatile ("MRS r0, PRIMASK");
asm volatile ("CPSID I");
asm volatile ("BX LR ");
}
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
{
asm volatile ("MSR PRIMASK, r0");
asm volatile ("BX LR");
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
return EOK;
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
return EOK;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry()
{
uint32 ipsr;
__asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
isrManager.done->incCounter();
isrManager.done->handleIrq(ipsr);
KTaskOsAssignAfterIrq(NONE);
isrManager.done->decCounter();
}
void UsageFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{
}
}
void BusFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{
}
}
void NMI_Handler(int irqn, void *arg)
{
while (1)
{
}
}
@@ -0,0 +1,122 @@
//*****************************************************************************
//
// startup_gcc.c - Startup code for use with GNU tools.
//
// Copyright (c) 2013 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 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.
//
// Neither the name of Texas Instruments Incorporated 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
// OWNER 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.
//
// This is part of revision 10636 of the Stellaris Firmware Development Package.
//
//*****************************************************************************
/**
* @file interrupt_vector.S
* @brief derived from Stellaris Firmware Development Package
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-13
*/
/*************************************************
File name: interrupt_vector.S
Description: vector table for a Cortex M3
Others:
History:
1. Date: 2021-05-13
Author: AIIT XUOS Lab
Modification:
1. take startup_gcc.c from revision 10636 of the Stellaris Firmware Development Package for XiZi kernel
*************************************************/
//*****************************************************************************
//
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000.
//
//*****************************************************************************
.globl InterruptVectors
/******************************************************************************
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type InterruptVectors, %object
.size InterruptVectors, .-InterruptVectors
InterruptVectors:
.word _sp
.word Reset_Handler
.word NMI_Handler // NMI_Handler
.word HardFaultHandler
.word MemFaultHandler // MemManage_Handler
.word BusFault_Handler // BusFault_Handler
.word UsageFault_Handler // UsageFault_Handler
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry // SVC_Handler
.word IsrEntry // DebugMon_Handler
.word IsrEntry
.word PendSV_Handler // PendSV_Handler
.word IsrEntry // systick
.word IsrEntry
.word IsrEntry
.word IsrEntry // UART
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
@@ -0,0 +1,159 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2009-10-11 Bernard first version
* 2012-01-01 aozima support context switch load/store FPU register.
* 2013-06-18 aozima add restore MSP feature.
* 2013-06-23 aozima support lazy stack optimized.
* 2018-07-24 aozima enhancement hard fault exception handler.
*/
/*************************************************
File name: pendsv.S
Description: PendSV interrupt handler
Others: take RT-Thread v4.0.2/libcpu/arm/cortex-m4/context_gcc.S for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
*************************************************/
#include <xsconfig.h>
.cpu cortex-m0
.syntax unified
.thumb
.text
.equ SCB_VTOR, 0xE000ED08
.equ NVIC_INT_CTRL, 0xE000ED04
.equ NVIC_SYSPRI2, 0xE000ED20
.equ NVIC_PENDSV_PRI, 0x00FF0000
.equ NVIC_PENDSVSET, 0x10000000
.globl PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
MRS r3, PRIMASK
CPSID I
LDR r0, =KtaskSwitchInterruptFlag
LDR r1, [r0]
/*CBZ r1, switch_to_task*/
CMP r1, #0
BEQ pendsv_exit
MOVS r1, #0x00
STR r1, [r0]
LDR r0, =InterruptFromKtask
LDR r1, [r0]
/*CBZ r1, switch_to_task*/
CMP r1, #0
BEQ switch_to_task
MRS r1, psp
/*STMFD r1!, {r3 - r11}*/
SUBS r1, #0x24
STMIA r1!, {r3 - r7}
MOV r3, r8
MOV r4, r9
MOV r5, r10
MOV r6, r11
STMIA r1!, {r3 - r6}
SUBS r1, #0x24
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
MOV r4, #0x00
TST lr, #0x10
MOVEQ r4, #0x01
/*STMFD r1!, {r4}*/
SUBS r1, #0x4
STMIA r1!, {r4}
SUBS r1, #0x4
#endif
LDR r0, [r0]
STR r1, [r0]
switch_to_task:
PUSH {lr}
BL UpdateRunningTask
POP {r0}
MOV lr, r0
#ifdef TASK_ISOLATION
PUSH {lr}
BL GetTaskPrivilege
/*POP {lr}*/
POP {r0}
MOV lr, r0
#endif
LDR r1, =InterruptToKtask
LDR r1, [r1]
LDR r1, [r1]
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
LDMFD r1!, {r2}
#endif
/*LDMFD r1!, {r3 - r11}*/
ADDS r1, #0x14
LDMFD r1!, {r3 - r6}
MOV r8, r3
MOV r9, r4
MOV r10, r5
MOV r11, r6
SUBS r1, #0x24
LDMFD r1!, {r3 - r7}
ADDS r1, #0x10
MSR psp, r1
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
/*ORR lr, lr, #0x10*/
MOV r2, lr
MOVS r3, #0x10
ORRS r2, r3
MOV lr, r2
CMP r2, #0
BICNE lr, lr, #0x10
#endif
MRS r2, control
#ifdef TASK_ISOLATION
CMP r0, #1
BEQ unprivilege
privilege:
BIC r2, r2, #0x01
B exit
unprivilege:
/*ORR r2, r2, #0x01*/
MOVS r1, #0x01
ORRS r2, r1
#else
/*BIC r2, r2, #0x01*/
MOVS r0, #0x01
BICS r2, r0
#endif
exit:
MSR control, r2
pendsv_exit:
/*ORR lr, lr, #0x04*/
MOV r0, lr
MOVS r1, #0x04
ORRS r0, r1
MOV lr, r0
MSR PRIMASK, r3
BX lr
@@ -0,0 +1,411 @@
/*
* 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 <xs_base.h>
#include <xs_ktask.h>
#include <xs_assign.h>
#include "svc_handle.h"
#include <board.h>
#include <shell.h>
#if (defined ( __GNUC__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__))
#define USE_FPU 1
#else
#define USE_FPU 0
#endif
uint32 InterruptFromKtask;
uint32 InterruptToKtask;
uint32 KtaskSwitchInterruptFlag;
uint32 InterruptToKtaskDescriptor;
#define RunningKTask Assign.os_running_task
static x_err_t (*ExceptionHook)(void *context) = NONE;
struct ExceptionStackRegister
{
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r12;
uint32 lr;
uint32 pc;
uint32 psr;
};
struct StackRegisterContent
{
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
uint32 flag;
#endif
uint32 primask;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
// uint32 exc_ret;
struct ExceptionStackRegister ExErrorStackContex;
};
struct ExceptionStackFrameFpu
{
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r12;
uint32 lr;
uint32 pc;
uint32 psr;
#if USE_FPU
uint32 S0;
uint32 S1;
uint32 S2;
uint32 S3;
uint32 S4;
uint32 S5;
uint32 S6;
uint32 S7;
uint32 S8;
uint32 S9;
uint32 S10;
uint32 S11;
uint32 S12;
uint32 S13;
uint32 S14;
uint32 S15;
uint32 FPSCR;
uint32 NO_NAME;
#endif
};
struct StackFrameFpu
{
uint32 flag;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
#if USE_FPU
uint32 s16;
uint32 s17;
uint32 s18;
uint32 s19;
uint32 s20;
uint32 s21;
uint32 s22;
uint32 s23;
uint32 s24;
uint32 s25;
uint32 s26;
uint32 s27;
uint32 s28;
uint32 s29;
uint32 s30;
uint32 s31;
#endif
struct ExceptionStackFrameFpu ExErrorStackContex;
};
uint8 KTaskStackSetup(struct TaskDescriptor *task)
{
struct StackRegisterContent* StackContex;
int i = 0;
task->stack_point = (uint8 *)ALIGN_MEN_DOWN((x_ubase)(task->task_base_info.stack_start + task->task_base_info.stack_depth), 8);
task->stack_point -= sizeof(struct StackRegisterContent);
StackContex = (struct StackRegisterContent*)task->stack_point;
for (i = 0; i < sizeof(struct StackRegisterContent) / sizeof(uint32); i++)
((uint32 *)StackContex)[i] = 0xfadeface;
StackContex->ExErrorStackContex.r0 = (unsigned long)task->task_base_info.func_param;
StackContex->ExErrorStackContex.pc = (unsigned long)task->task_base_info.func_entry ;
StackContex->ExErrorStackContex.psr = 0x01000000L;
StackContex->primask = 0x00000000L;
#ifdef SEPARATE_COMPILE
if(task->task_dync_sched_member.isolation_flag == 1 ) {
StackContex->ExErrorStackContex.lr = (unsigned long)USERSPACE->us_taskquit;
} else {
StackContex->ExErrorStackContex.lr = (unsigned long)KTaskQuit;
}
#else
StackContex->ExErrorStackContex.lr = (unsigned long)KTaskQuit;
#endif
#if USE_FPU
StackContex->flag = 0;
#endif
return EOK;
}
void HwExceptionInstall(x_err_t (*exception_handle)(void *context))
{
ExceptionHook = exception_handle;
}
#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28)
#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C)
#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34)
#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38)
#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C)
#define SCB_RESET_VALUE 0x05FA0004
#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28)
#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29)
#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A)
#ifdef TOOL_SHELL
static void UsageFaultTrack(void)
{
KPrintf("usage fault:\n");
KPrintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
if(SCB_CFSR_UFSR & (1<<0))
KPrintf("UNDEFINSTR ");
if(SCB_CFSR_UFSR & (1<<1))
KPrintf("INVSTATE ");
if(SCB_CFSR_UFSR & (1<<2))
KPrintf("INVPC ");
if(SCB_CFSR_UFSR & (1<<3))
KPrintf("NOCP ");
if(SCB_CFSR_UFSR & (1<<8))
KPrintf("UNALIGNED ");
if(SCB_CFSR_UFSR & (1<<9))
KPrintf("DIVBYZERO ");
KPrintf("\n");
}
static void BusFaultTrack(void)
{
KPrintf("bus fault:\n");
KPrintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
if(SCB_CFSR_BFSR & (1<<0))
KPrintf("IBUSERR ");
if(SCB_CFSR_BFSR & (1<<1))
KPrintf("PRECISERR ");
if(SCB_CFSR_BFSR & (1<<2))
KPrintf("IMPRECISERR ");
if(SCB_CFSR_BFSR & (1<<3))
KPrintf("UNSTKERR ");
if(SCB_CFSR_BFSR & (1<<4))
KPrintf("STKERR ");
if(SCB_CFSR_BFSR & (1<<7))
KPrintf("SCB->BFAR:%08X\n", SCB_BFAR);
else
KPrintf("\n");
}
static void MemManageFaultTrack(void)
{
KPrintf("mem manage fault:\n");
KPrintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
if(SCB_CFSR_MFSR & (1<<0))
KPrintf("IACCVIOL ");
if(SCB_CFSR_MFSR & (1<<1))
KPrintf("DACCVIOL ");
if(SCB_CFSR_MFSR & (1<<3))
KPrintf("MUNSTKERR ");
if(SCB_CFSR_MFSR & (1<<4))
KPrintf("MSTKERR ");
if(SCB_CFSR_MFSR & (1<<7))
KPrintf("SCB->MMAR:%08X\n", SCB_MMAR);
else
KPrintf("\n");
}
static void HardFaultTrack(void)
{
if(SCB_HFSR & (1UL<<1))
KPrintf("failed vector fetch\n");
if(SCB_HFSR & (1UL<<30)) {
if(SCB_CFSR_BFSR)
BusFaultTrack();
if(SCB_CFSR_MFSR)
MemManageFaultTrack();
if(SCB_CFSR_UFSR)
UsageFaultTrack();
}
if(SCB_HFSR & (1UL<<31))
KPrintf("debug event\n");
}
#endif
struct ExceptionInfo
{
uint32 ExcReturn;
struct StackRegisterContent stackframe;
};
void HwHardFaultException(struct ExceptionInfo *ExceptionInfo)
{
extern long ShowTask(void);
struct ExErrorStackContex* ExceptionStack = (struct ExErrorStackContex*)&ExceptionInfo->stackframe.ExErrorStackContex;
struct StackRegisterContent* context = (struct StackRegisterContent*)&ExceptionInfo->stackframe;
if (ExceptionHook != NONE) {
x_err_t result = ExceptionHook(ExceptionStack);
if (result == EOK) return;
}
KPrintf("psr: 0x%08x\n", context->ExErrorStackContex.psr);
KPrintf("r00: 0x%08x\n", context->ExErrorStackContex.r0);
KPrintf("r01: 0x%08x\n", context->ExErrorStackContex.r1);
KPrintf("r02: 0x%08x\n", context->ExErrorStackContex.r2);
KPrintf("r03: 0x%08x\n", context->ExErrorStackContex.r3);
KPrintf("r04: 0x%08x\n", context->r4);
KPrintf("r05: 0x%08x\n", context->r5);
KPrintf("r06: 0x%08x\n", context->r6);
KPrintf("r07: 0x%08x\n", context->r7);
KPrintf("r08: 0x%08x\n", context->r8);
KPrintf("r09: 0x%08x\n", context->r9);
KPrintf("r10: 0x%08x\n", context->r10);
KPrintf("r11: 0x%08x\n", context->r11);
//KPrintf("exc_ret: 0x%08x\n", context->exc_ret);
KPrintf("r12: 0x%08x\n", context->ExErrorStackContex.r12);
KPrintf(" lr: 0x%08x\n", context->ExErrorStackContex.lr);
KPrintf(" pc: 0x%08x\n", context->ExErrorStackContex.pc);
if (ExceptionInfo->ExcReturn & (1 << 2)) {
KPrintf("hard fault on task: %s\r\n\r\n", GetKTaskDescriptor()->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
} else {
KPrintf("hard fault on handler\r\n\r\n");
}
if ( (ExceptionInfo->ExcReturn & 0x10) == 0)
KPrintf("FPU active!\r\n");
#ifdef TOOL_SHELL
HardFaultTrack();
#endif
while (1);
}
void UpdateRunningTask(void)
{
RunningKTask = (struct TaskDescriptor *)InterruptToKtaskDescriptor;
}
void MemFaultExceptionPrint(struct ExceptionInfo *ExceptionInfo)
{
extern long ShowTask(void);
struct ExErrorStackContex* ExceptionStack = (struct ExErrorStackContex*)&ExceptionInfo->stackframe.ExErrorStackContex;
struct StackRegisterContent* context = (struct StackRegisterContent*)&ExceptionInfo->stackframe;
if (ExceptionHook != NONE) {
x_err_t result = ExceptionHook(ExceptionStack);
if (result == EOK) return;
}
KPrintf("psr: 0x%08x\n", context->ExErrorStackContex.psr);
KPrintf("r00: 0x%08x\n", context->ExErrorStackContex.r0);
KPrintf("r01: 0x%08x\n", context->ExErrorStackContex.r1);
KPrintf("r02: 0x%08x\n", context->ExErrorStackContex.r2);
KPrintf("r03: 0x%08x\n", context->ExErrorStackContex.r3);
KPrintf("r04: 0x%08x\n", context->r4);
KPrintf("r05: 0x%08x\n", context->r5);
KPrintf("r06: 0x%08x\n", context->r6);
KPrintf("r07: 0x%08x\n", context->r7);
KPrintf("r08: 0x%08x\n", context->r8);
KPrintf("r09: 0x%08x\n", context->r9);
KPrintf("r10: 0x%08x\n", context->r10);
KPrintf("r11: 0x%08x\n", context->r11);
KPrintf("exc_ret: 0x%08x\n", ExceptionInfo->ExcReturn);
KPrintf("r12: 0x%08x\n", context->ExErrorStackContex.r12);
KPrintf(" lr: 0x%08x\n", context->ExErrorStackContex.lr);
KPrintf(" pc: 0x%08x\n", context->ExErrorStackContex.pc);
if (ExceptionInfo->ExcReturn & (1 << 2)) {
KPrintf("hard fault on task: %s\r\n\r\n", GetKTaskDescriptor()->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
} else {
KPrintf("hard fault on handler\r\n\r\n");
}
if ((ExceptionInfo->ExcReturn & 0x10) == 0)
KPrintf("FPU active!\r\n");
#ifdef TOOL_SHELL
HardFaultTrack();
#endif
while (1);
}
void MemFaultHandle(uintptr_t *sp)
{
#ifdef TASK_ISOLATION
struct TaskDescriptor *task;
task = GetKTaskDescriptor();
if( task->task_dync_sched_member.isolation_flag == 1){
KPrintf("\nSegmentation fault, task: %s\n", task->task_base_info.name);
KTaskQuit();
}
else
#endif
{
MemFaultExceptionPrint((struct ExceptionInfo *)sp);
}
}
__attribute__((weak)) void HwCpuReset(void)
{
SCB_AIRCR = SCB_RESET_VALUE;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), Reboot, HwCpuReset, reset machine );
@@ -0,0 +1,58 @@
/*
* 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.
*/
#ifndef __INC_SVC_HANDLE_H__
#define __INC_SVC_HANDLE_H__
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
#define INT_FPU_REGS (1)
#else
#define INT_FPU_REGS (0)
#endif
#define HW_INT_REGS (8)
#define SW_INT_REGS (9 + INT_FPU_REGS)
#define REG_INT_R0 (SW_INT_REGS + 0) /* R0 */
#define REG_INT_R1 (SW_INT_REGS + 1) /* R1 */
#define REG_INT_R2 (SW_INT_REGS + 2) /* R2 */
#define REG_INT_R3 (SW_INT_REGS + 3) /* R3 */
#define REG_INT_R12 (SW_INT_REGS + 4) /* R12 */
#define REG_INT_R14 (SW_INT_REGS + 5) /* R14 = LR */
#define REG_INT_PC (SW_INT_REGS + 6) /* R15 = PC */
#define REG_INT_XPSR (SW_INT_REGS + 7) /* xPSR */
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
#define REG_INT_FPU_FLAG (0) /* fpu flag */
#define REG_INT_PRIMASK (1) /* PRIMASK */
#define REG_INT_R4 (2) /* R4 */
#define REG_INT_R5 (3) /* R5 */
#define REG_INT_R6 (4) /* R6 */
#define REG_INT_R7 (5) /* R7 */
#define REG_INT_R8 (6) /* R8 */
#define REG_INT_R9 (7) /* R9 */
#define REG_INT_R10 (8) /* R10 */
#define REG_INT_R11 (9) /* R11 */
#else
#define REG_INT_PRIMASK (0) /* PRIMASK */
#define REG_INT_R4 (1) /* R4 */
#define REG_INT_R5 (2) /* R5 */
#define REG_INT_R6 (3) /* R6 */
#define REG_INT_R7 (4) /* R7 */
#define REG_INT_R8 (5) /* R8 */
#define REG_INT_R9 (6) /* R9 */
#define REG_INT_R10 (7) /* R10 */
#define REG_INT_R11 (8) /* R11 */
#endif
#endif
@@ -0,0 +1,3 @@
SRC_FILES := boot.S interrupt.c interrupt_vector.S pendsv.S prepare_ahwstack.c arm32_switch.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,28 @@
/*
* 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.
*/
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include <xs_base.h>
#define ARCH_MAX_IRQ_NUM (256)
#define ARCH_IRQ_NUM_OFFSET 14
#define SYSTICK_IRQ_NUM -1
#define UART0_IRQ_NUM 36
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
@@ -0,0 +1,179 @@
/*
* 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 <xs_base.h>
#include <xs_ktask.h>
#define SCB_VTOR "0xE000ED08"
#define NVIC_INT_CTRL "0xE000ED04"
#define NVIC_SYSPRI2 "0xE000ED20"
#define NVIC_PENDSV_PRI "0xFFFF0000"
#define NVIC_PENDSVSET "0x10000000"
void __attribute__((naked)) HwInterruptcontextSwitch(x_ubase from, x_ubase to, struct TaskDescriptor *to_task, void *context)
{
asm volatile ("LDR r3, =InterruptFromKtask");
asm volatile ("STR r0, [r3]");
asm volatile ("LDR r3, =InterruptToKtask");
asm volatile ("STR r1, [r3]");
asm volatile ("LDR r3, =InterruptToKtaskDescriptor");
asm volatile ("STR r2, [r3]");
asm volatile ("LDR r2, =KtaskSwitchInterruptFlag");
asm volatile ("LDR r3, [r2]");
asm volatile ("CMP r3, #1");
asm volatile ("BEQ Arm32SwitchReswitch");
asm volatile ("MOVS r3, #1");
asm volatile ("STR r3, [r2]");
asm volatile ("B Arm32SwitchReswitch");
}
void __attribute__((naked)) Arm32SwitchReswitch()
{
asm volatile ("LDR r2, =InterruptToKtask");
asm volatile ("STR r1, [r2]");
asm volatile ("LDR r0, =" NVIC_INT_CTRL);/* trigger the PendSV exception (causes context switch) */
asm volatile ("LDR r1, =" NVIC_PENDSVSET);
asm volatile ("STR r1, [r0]");
asm volatile ("BX lr");
}
void __attribute__((naked)) SwitchKtaskContext(x_ubase from, x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile("B HwInterruptcontextSwitch");
}
void SwitchKtaskContextTo(x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile ("LDR r2, =InterruptToKtask");
asm volatile ("STR r0, [r2]");
asm volatile ("LDR r2, =InterruptToKtaskDescriptor");
asm volatile ("STR r1, [r2]");
asm volatile ("LDR r1, =InterruptFromKtask");
asm volatile ("MOV r0, #0x0");
asm volatile ("STR r0, [r1]");
asm volatile ("LDR r1, =KtaskSwitchInterruptFlag");
asm volatile ("MOV r0, #1");
asm volatile ("STR r0, [r1]");
asm volatile ("LDR r0, =" NVIC_SYSPRI2);
asm volatile ("LDR r1, =" NVIC_PENDSV_PRI);
asm volatile ("LDR r2, [r0,#0x00]");
asm volatile ("ORR r1,r1,r2");
asm volatile ("STR r1, [r0]");
asm volatile ("LDR r0, =" NVIC_INT_CTRL);
asm volatile ("LDR r1, =" NVIC_PENDSVSET);
asm volatile ("STR r1, [r0]");
asm volatile ("LDR r0, =" SCB_VTOR);
asm volatile ("LDR r0, [r0]");
asm volatile ("LDR r0, [r0]");
asm volatile ("NOP");
asm volatile ("MSR msp, r0");
asm volatile ("CPSIE I");
//asm volatile ("BX lr");
}
void __attribute__((naked)) Arm32SwitchGetSpDone()
{
asm volatile ("MRS r3, primask");
asm volatile ("SUB r0, r0, #0x24");
asm volatile ("STMIA r0!, {r3 - r7}");
asm volatile ("MOV r3, r8");
asm volatile ("MOV r4, r9");
asm volatile ("MOV r5, r10");
asm volatile ("MOV r6, r11");
asm volatile ("STMIA r0!, {r3 - r6}");
asm volatile ("SUB r0, r0, #0x24");
asm volatile ("SUB r0, r0, #0x4");
asm volatile ("MOV r0, lr");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("TST r1, r2");
asm volatile ("BEQ Arm32SwitchUpdateMsp");
asm volatile ("MSR psp, r0");
asm volatile ("B Arm32SwitchUpdateDone");
asm volatile ("B Arm32SwitchUpdateMsp");
}
void __attribute__((naked)) Arm32SwitchUpdateMsp()
{
asm volatile ("MSR msp, r0");
asm volatile ("B Arm32SwitchUpdateDone");
}
void __attribute__((naked)) Arm32SwitchUpdateDone()
{
asm volatile ("PUSH {LR}");
asm volatile ("BL HwHardFaultException");
asm volatile ("POP {R1}");
asm volatile ("MOV lr, r1");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("ORR r1, r2");
asm volatile ("MOV lr, r1");
asm volatile ("BX lr");
}
void __attribute__((naked)) MemFaultHandler()
{
asm volatile ("MRS r0, msp");
// asm volatile ("TST lr, #0x04");
asm volatile ("MOV r1, lr");
asm volatile ("MOV r2, #0x04");
asm volatile ("TST r1, r2");
asm volatile ("BEQ Arm32Switch1");
asm volatile ("MRS r0, psp");
asm volatile ("B Arm32Switch1");
}
void __attribute__((naked)) Arm32Switch1()
{
asm volatile ("MRS r3, primask");
asm volatile ("SUB r0, r0, #0x24");
asm volatile ("STMIA r0!, {r3 - r7}");
asm volatile ("MOV r3, r8");
asm volatile ("MOV r4, r9");
asm volatile ("MOV r5, r10");
asm volatile ("MOV r6, r11");
asm volatile ("STMIA r0!, {r3 - r6}");
asm volatile ("SUB r0, r0, #0x24");
asm volatile ("SUB r0, r0, #0x4");
asm volatile ("MOV r0, lr");
asm volatile ("PUSH {LR}");
asm volatile ("BL MemFaultHandle");
asm volatile ("POP {R5}");
asm volatile ("MOV lr, r5");
asm volatile ("MOV r5, lr");
asm volatile ("MOV r6, #0x04");
asm volatile ("ORR r5, r6");
asm volatile ("MOV lr, r5");
asm volatile ("BX lr");
}
@@ -0,0 +1,131 @@
/****************************************************************************//**
* @file startup_M2354.S
* @version V1.00
* @brief CMSIS Device Startup File
*
* SPDX-License-Identifier: Apache-2.0
* @copyright (C) 2018-2020 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
/**
* @file boot.S
* @brief derived from M2354_SERIES_BSP_CMSIS_V3.00.002
* @version 1.1
* @author AIIT XUOS Lab
* @date 2022-02-23
*/
/*************************************************
File name: boot.S
Description: Reset and init function
Others:
History:
1. Date: 2022-02-23
Author: AIIT XUOS Lab
Modification:
1. take startup_M2354.S for XiUOS
*************************************************/
.syntax unified
.arch armv8 - m.base
.fpu softvfp
.thumb
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Check SecureWorld */
MOV R0, R15
LSLS R0, R0, #3
BMI.N GotoSystemInit
/* Unlock Register */
LDR R0, =0x40000100
LDR R1, =0x59
STR R1, [R0]
LDR R1, =0x16
STR R1, [R0]
LDR R1, =0x88
STR R1, [R0]
/* power gating */
/* M32(0x400001f4) = 0xfffffffful; */
LDR R0, =0x400001f4
LDR R1, =0xffffffff
STR R1, [R0]
/* M32(0x400000dC) = 0ul; */
LDR R0, =0x400000dC
LDR R1, =0x0
STR R1, [R0]
/* Enable GPIO clks, SRAM clks, Trace clk */
/* CLK->AHBCLK |= (0xffful << 20) | (1ul << 14); */
LDR R0, =0x40000200
LDR R1, [R0,#0x4]
LDR R2, =0xfff02000
ORRS R1, R1, R2
STR R1, [R0,#0x4]
GotoSystemInit:
/* Lock register */
LDR R0, =0x40000100
MOVS R1, #0
STR R1, [R0]
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2, #4]
adds r2, r2, #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call the application's entry point.*/
bl entry
bx lr
.size Reset_Handler, .-Reset_Handler
@@ -0,0 +1,83 @@
/*
* 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 interrupt.c
* @brief support arm cortex-m23 interrupt function
* @version 1.1
* @author AIIT XUOS Lab
* @date 2022-02-24
*/
#include <xs_base.h>
#include <xs_isr.h>
x_base __attribute__((naked)) DisableLocalInterrupt()
{
asm volatile ("MRS r0, PRIMASK");
asm volatile ("CPSID I");
asm volatile ("BX LR ");
}
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
{
asm volatile ("MSR PRIMASK, r0");
asm volatile ("BX LR");
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
return EOK;
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
return EOK;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry()
{
uint32 ipsr;
__asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
isrManager.done->incCounter();
isrManager.done->handleIrq(ipsr);
KTaskOsAssignAfterIrq(NONE);
isrManager.done->decCounter();
}
void UsageFault_Handler()
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{
}
}
void BusFault_Handler()
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{
}
}
void NMI_Handler()
{
while (1)
{
}
}
@@ -0,0 +1,197 @@
/****************************************************************************//**
* @file startup_M2354.S
* @version V1.00
* @brief CMSIS Device Startup File
*
* SPDX-License-Identifier: Apache-2.0
* @copyright (C) 2018-2020 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
/**
* @file interrupt_vector.S
* @brief derived from M2354_SERIES_BSP_CMSIS_V3.00.002
* @version 1.1
* @author AIIT XUOS Lab
* @date 2022-02-23
*/
/*************************************************
File name: interrupt_vector.S
Description: vector table for a M2354KJFAE
Others:
History:
1. Date: 2022-02-23
Author: AIIT XUOS Lab
Modification:
1. take startup_M2354.S for XiUOS
*************************************************/
.align 2
.thumb_func
.global __PC
.type __PC, % function
__PC:
MOV r0, lr
BLX lr
.size __PC, . - __PC
.global HardFaultHandler
.type HardFaultHandler, %function
HardFaultHandler:
/* get current context */
MRS R0, PSP /* get fault thread stack pointer */
PUSH {LR}
BL HwHardFaultException
POP {PC}
/*******************************************************************************
*
* The minimal vector table for a Cortex M23. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*******************************************************************************/
.globl InterruptVectors
.section .isr_vector,"a",%progbits
.type InterruptVectors, %object
.size InterruptVectors, . - InterruptVectors
InterruptVectors:
.long _sp /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFaultHandler /* Hard Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long IsrEntry /* SVCall Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long IsrEntry /*BOD_IRQHandler 0 */
.long IsrEntry /*IRC_IRQHandler 1 */
.long IsrEntry /*PWRWU_IRQHandler 2 */
.long IsrEntry /*SRAM_IRQHandler 3 */
.long IsrEntry /*CLKFAIL_IRQHandler 4 */
.long IsrEntry /*Default_Handler 5 */
.long IsrEntry /*RTC_IRQHandler 6 */
.long IsrEntry /*RTC_TAMPER_IRQHandler 7 */
.long IsrEntry /*WDT_IRQHandler 8 */
.long IsrEntry /*WWDT_IRQHandler 9 */
.long IsrEntry /*EINT0_IRQHandler 10 */
.long IsrEntry /*EINT1_IRQHandler 11 */
.long IsrEntry /*EINT2_IRQHandler 12 */
.long IsrEntry /*EINT3_IRQHandler 13 */
.long IsrEntry /*EINT4_IRQHandler 14 */
.long IsrEntry /*EINT5_IRQHandler 15 */
.long IsrEntry /*GPA_IRQHandler 16 */
.long IsrEntry /*GPB_IRQHandler 17 */
.long IsrEntry /*GPC_IRQHandler 18 */
.long IsrEntry /*GPD_IRQHandler 19 */
.long IsrEntry /*GPE_IRQHandler 20 */
.long IsrEntry /*GPF_IRQHandler 21 */
.long IsrEntry /*QSPI0_IRQHandler 22 */
.long IsrEntry /*SPI0_IRQHandler 23 */
.long IsrEntry /*BRAKE0_IRQHandler 24 */
.long IsrEntry /*EPWM0_P0_IRQHandler 25 */
.long IsrEntry /*EPWM0_P1_IRQHandler 26 */
.long IsrEntry /*EPWM0_P2_IRQHandler 27 */
.long IsrEntry /*BRAKE1_IRQHandler 28 */
.long IsrEntry /*EPWM1_P0_IRQHandler 29 */
.long IsrEntry /*EPWM1_P1_IRQHandler 30 */
.long IsrEntry /*EPWM1_P2_IRQHandler 31 */
.long IsrEntry /*TMR0_IRQHandler 32 */
.long IsrEntry /*TMR1_IRQHandler 33 */
.long IsrEntry /*TMR2_IRQHandler 34 */
.long IsrEntry /*TMR3_IRQHandler 35 */
.long UART0_IRQHandler /*UART0_IRQHandler 36 */
.long IsrEntry /*UART1_IRQHandler 37 */
.long IsrEntry /*I2C0_IRQHandler 38 */
.long IsrEntry /*I2C1_IRQHandler 39 */
.long IsrEntry /*PDMA0_IRQHandler 40 */
.long IsrEntry /*DAC_IRQHandler 41 */
.long IsrEntry /*EADC0_IRQHandler 42 */
.long IsrEntry /*EADC1_IRQHandler 43 */
.long IsrEntry /*ACMP01_IRQHandler 44 */
.long IsrEntry /*Default_Handler 45 */
.long IsrEntry /*EADC2_IRQHandler 46 */
.long IsrEntry /*EADC3_IRQHandler 47 */
.long IsrEntry /*UART2_IRQHandler 48 */
.long IsrEntry /*UART3_IRQHandler 49 */
.long IsrEntry /*Default_Handler 50 */
.long IsrEntry /*SPI1_IRQHandler 51 */
.long IsrEntry /*SPI2_IRQHandler 52 */
.long IsrEntry /*USBD_IRQHandler 53 */
.long IsrEntry /*USBH_IRQHandler 54 */
.long IsrEntry /*USBOTG_IRQHandler 55 */
.long IsrEntry /*CAN0_IRQHandler 56 */
.long IsrEntry /*Default_Handler 57 */
.long IsrEntry /*SC0_IRQHandler 58 */
.long IsrEntry /*SC1_IRQHandler 59 */
.long IsrEntry /*SC2_IRQHandler 60 */
.long IsrEntry /*Default_Handler 61 */
.long IsrEntry /*SPI3_IRQHandler 62 */
.long IsrEntry /*Default_Handler 63 */
.long IsrEntry /*SDH0_IRQHandler 64 */
.long IsrEntry /*Default_Handler 65 */
.long IsrEntry /*Default_Handler 66 */
.long IsrEntry /*Default_Handler 67 */
.long IsrEntry /*I2S0_IRQHandler 68 */
.long IsrEntry /*Default_Handler 69 */
.long IsrEntry /*OPA0_IRQHandler 70 */
.long IsrEntry /*CRPT_IRQHandler 71 */
.long IsrEntry /*GPG_IRQHandler 72 */
.long IsrEntry /*EINT6_IRQHandler 73 */
.long IsrEntry /*UART4_IRQHandler 74 */
.long IsrEntry /*UART5_IRQHandler 75 */
.long IsrEntry /*USCI0_IRQHandler 76 */
.long IsrEntry /*USCI1_IRQHandler 77 */
.long IsrEntry /*BPWM0_IRQHandler 78 */
.long IsrEntry /*BPWM1_IRQHandler 79 */
.long IsrEntry /*Default_Handler 80 */
.long IsrEntry /*Default_Handler 81 */
.long IsrEntry /*I2C2_IRQHandler 82 */
.long IsrEntry /*Default_Handler 83 */
.long IsrEntry /*QEI0_IRQHandler 84 */
.long IsrEntry /*QEI1_IRQHandler 85 */
.long IsrEntry /*ECAP0_IRQHandler 86 */
.long IsrEntry /*ECAP1_IRQHandler 87 */
.long IsrEntry /*GPH_IRQHandler 88 */
.long IsrEntry /*EINT7_IRQHandler 89 */
.long IsrEntry /*Default_Handler 90 */
.long IsrEntry /*Default_Handler 91 */
.long IsrEntry /*Default_Handler 92 */
.long IsrEntry /*Default_Handler 93 */
.long IsrEntry /*Default_Handler 94 */
.long IsrEntry /*Default_Handler 95 */
.long IsrEntry /*Default_Handler 96 */
.long IsrEntry /*Default_Handler 97 */
.long IsrEntry /*PDMA1_IRQHandler 98 */
.long IsrEntry /*SCU_IRQHandler 99 */
.long IsrEntry /*LCD_IRQHandler 100 */
.long IsrEntry /*TRNG_IRQHandler 101 */
.long IsrEntry /*Default_Handler 102 */
.long IsrEntry /*Default_Handler 103 */
.long IsrEntry /*Default_Handler 104 */
.long IsrEntry /*Default_Handler 105 */
.long IsrEntry /*Default_Handler 106 */
.long IsrEntry /*Default_Handler 107 */
.long IsrEntry /*Default_Handler 108 */
.long IsrEntry /*KS_IRQHandler 109 */
.long IsrEntry /*TAMPER_IRQHandler 110 */
.long IsrEntry /*EWDT_IRQHandler 111 */
.long IsrEntry /*EWWDT_IRQHandler 112 */
.long IsrEntry /*NS_ISP_IRQHandler 113 */
.long IsrEntry /*TMR4_IRQHandler 114 */
.long IsrEntry /*TMR5_IRQHandler 115 */
.end
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-01-25 Bernard first version
* 2012-06-01 aozima set pendsv priority to 0xFF.
* 2012-08-17 aozima fixed bug: store r8 - r11.
* 2013-02-20 aozima port to gcc.
* 2013-06-18 aozima add restore MSP feature.
* 2013-11-04 bright fixed hardfault bug for gcc.
* 2019-03-31 xuzhuoyi port to Cortex-M23.
*/
/*************************************************
File name: pendsv.S
Description: PendSV interrupt handler
Others: take RT-Thread v4.0.2/libcpu/arm/cortex-m23/context_gcc.S for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2022-02-28
Author: AIIT XUOS Lab
*************************************************/
#include <xsconfig.h>
.cpu cortex-m23
.syntax unified
.thumb
.text
.equ SCB_VTOR, 0xE000ED08
.equ NVIC_INT_CTRL, 0xE000ED04
.equ NVIC_SYSPRI2, 0xE000ED20
.equ NVIC_PENDSV_PRI, 0xFFFF0000
.equ NVIC_PENDSVSET, 0x10000000
/* R0 --> switch from thread stack
* R1 --> switch to thread stack
* psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
*/
.global PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
/* disable interrupt to protect context switch */
MRS R2, PRIMASK
CPSID I
LDR R0, =KtaskSwitchInterruptFlag
LDR R1, [R0]
CMP R1, #0x00
BEQ pendsv_exit /* pendsv aLReady handled */
/* clear KtaskSwitchInterruptFlag to 0 */
MOVS R1, #0
STR R1, [R0]
LDR R0, =InterruptFromKtask
LDR R1, [R0]
CMP R1, #0x00
BEQ switch_to_task /* skip register save at the first time */
MRS R1, PSP /* get from thread stack pointer */
SUBS R1, R1, #0x20 /* space for {R4 - R7} and {R8 - R11} */
LDR R0, [R0]
STR R1, [R0] /* update from thread stack pointer */
STMIA R1!, {R4 - R7} /* push thread {R4 - R7} register to thread stack */
MOV R4, R8 /* mov thread {R8 - R11} to {R4 - R7} */
MOV R5, R9
MOV R6, R10
MOV R7, R11
STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */
switch_to_task:
LDR R1, =InterruptToKtask
LDR R1, [R1]
LDR R1, [R1] /* load thread stack pointer */
LDMIA R1!, {R4 - R7} /* pop thread {R4 - R7} register from thread stack */
PUSH {R4 - R7} /* push {R4 - R7} to MSP for copy {R8 - R11} */
LDMIA R1!, {R4 - R7} /* pop thread {R8 - R11} high register from thread stack to {R4 - R7} */
MOV R8, R4 /* mov {R4 - R7} to {R8 - R11} */
MOV R9, R5
MOV R10, R6
MOV R11, R7
POP {R4 - R7} /* pop {R4 - R7} from MSP */
MSR PSP, R1 /* update stack pointer */
pendsv_exit:
/* restore interrupt */
MSR PRIMASK, R2
MOVS R0, #0x03
RSBS R0, R0, #0x00
BX R0
@@ -0,0 +1,411 @@
/*
* 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 <xs_base.h>
#include <xs_ktask.h>
#include <xs_assign.h>
#include "svc_handle.h"
#include <board.h>
#include <shell.h>
#if (defined ( __GNUC__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__))
#define USE_FPU 1
#else
#define USE_FPU 0
#endif
uint32 InterruptFromKtask;
uint32 InterruptToKtask;
uint32 KtaskSwitchInterruptFlag;
uint32 InterruptToKtaskDescriptor;
#define RunningKTask Assign.os_running_task
static x_err_t (*ExceptionHook)(void *context) = NONE;
struct ExceptionStackRegister
{
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r12;
uint32 lr;
uint32 pc;
uint32 psr;
};
struct StackRegisterContent
{
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
uint32 flag;
#endif
//uint32 primask;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
// uint32 exc_ret;
struct ExceptionStackRegister ExErrorStackContex;
};
struct ExceptionStackFrameFpu
{
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r12;
uint32 lr;
uint32 pc;
uint32 psr;
#if USE_FPU
uint32 S0;
uint32 S1;
uint32 S2;
uint32 S3;
uint32 S4;
uint32 S5;
uint32 S6;
uint32 S7;
uint32 S8;
uint32 S9;
uint32 S10;
uint32 S11;
uint32 S12;
uint32 S13;
uint32 S14;
uint32 S15;
uint32 FPSCR;
uint32 NO_NAME;
#endif
};
struct StackFrameFpu
{
uint32 flag;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
#if USE_FPU
uint32 s16;
uint32 s17;
uint32 s18;
uint32 s19;
uint32 s20;
uint32 s21;
uint32 s22;
uint32 s23;
uint32 s24;
uint32 s25;
uint32 s26;
uint32 s27;
uint32 s28;
uint32 s29;
uint32 s30;
uint32 s31;
#endif
struct ExceptionStackFrameFpu ExErrorStackContex;
};
uint8 KTaskStackSetup(struct TaskDescriptor *task)
{
struct StackRegisterContent* StackContex;
int i = 0;
task->stack_point = (uint8 *)ALIGN_MEN_DOWN((x_ubase)(task->task_base_info.stack_start + task->task_base_info.stack_depth), 8);
task->stack_point -= sizeof(struct StackRegisterContent);
StackContex = (struct StackRegisterContent*)task->stack_point;
for (i = 0; i < sizeof(struct StackRegisterContent) / sizeof(uint32); i++)
((uint32 *)StackContex)[i] = 0xfadeface;
StackContex->ExErrorStackContex.r0 = (unsigned long)task->task_base_info.func_param;
StackContex->ExErrorStackContex.pc = (unsigned long)task->task_base_info.func_entry ;
StackContex->ExErrorStackContex.psr = 0x01000000L;
//StackContex->primask = 0x00000000L;
#ifdef SEPARATE_COMPILE
if(task->task_dync_sched_member.isolation_flag == 1 ) {
StackContex->ExErrorStackContex.lr = (unsigned long)USERSPACE->us_taskquit;
} else {
StackContex->ExErrorStackContex.lr = (unsigned long)KTaskQuit;
}
#else
StackContex->ExErrorStackContex.lr = (unsigned long)KTaskQuit;
#endif
#if USE_FPU
StackContex->flag = 0;
#endif
return EOK;
}
void HwExceptionInstall(x_err_t (*exception_handle)(void *context))
{
ExceptionHook = exception_handle;
}
#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28)
#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C)
#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34)
#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38)
#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C)
#define SCB_RESET_VALUE 0x05FA0004
#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28)
#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29)
#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A)
#ifdef TOOL_SHELL
static void UsageFaultTrack(void)
{
KPrintf("usage fault:\n");
KPrintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
if(SCB_CFSR_UFSR & (1<<0))
KPrintf("UNDEFINSTR ");
if(SCB_CFSR_UFSR & (1<<1))
KPrintf("INVSTATE ");
if(SCB_CFSR_UFSR & (1<<2))
KPrintf("INVPC ");
if(SCB_CFSR_UFSR & (1<<3))
KPrintf("NOCP ");
if(SCB_CFSR_UFSR & (1<<8))
KPrintf("UNALIGNED ");
if(SCB_CFSR_UFSR & (1<<9))
KPrintf("DIVBYZERO ");
KPrintf("\n");
}
static void BusFaultTrack(void)
{
KPrintf("bus fault:\n");
KPrintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
if(SCB_CFSR_BFSR & (1<<0))
KPrintf("IBUSERR ");
if(SCB_CFSR_BFSR & (1<<1))
KPrintf("PRECISERR ");
if(SCB_CFSR_BFSR & (1<<2))
KPrintf("IMPRECISERR ");
if(SCB_CFSR_BFSR & (1<<3))
KPrintf("UNSTKERR ");
if(SCB_CFSR_BFSR & (1<<4))
KPrintf("STKERR ");
if(SCB_CFSR_BFSR & (1<<7))
KPrintf("SCB->BFAR:%08X\n", SCB_BFAR);
else
KPrintf("\n");
}
static void MemManageFaultTrack(void)
{
KPrintf("mem manage fault:\n");
KPrintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
if(SCB_CFSR_MFSR & (1<<0))
KPrintf("IACCVIOL ");
if(SCB_CFSR_MFSR & (1<<1))
KPrintf("DACCVIOL ");
if(SCB_CFSR_MFSR & (1<<3))
KPrintf("MUNSTKERR ");
if(SCB_CFSR_MFSR & (1<<4))
KPrintf("MSTKERR ");
if(SCB_CFSR_MFSR & (1<<7))
KPrintf("SCB->MMAR:%08X\n", SCB_MMAR);
else
KPrintf("\n");
}
static void HardFaultTrack(void)
{
if(SCB_HFSR & (1UL<<1))
KPrintf("failed vector fetch\n");
if(SCB_HFSR & (1UL<<30)) {
if(SCB_CFSR_BFSR)
BusFaultTrack();
if(SCB_CFSR_MFSR)
MemManageFaultTrack();
if(SCB_CFSR_UFSR)
UsageFaultTrack();
}
if(SCB_HFSR & (1UL<<31))
KPrintf("debug event\n");
}
#endif
struct ExceptionInfo
{
uint32 ExcReturn;
struct StackRegisterContent stackframe;
};
void HwHardFaultException(struct ExceptionInfo *ExceptionInfo)
{
extern long ShowTask(void);
struct ExErrorStackContex* ExceptionStack = (struct ExErrorStackContex*)&ExceptionInfo->stackframe.ExErrorStackContex;
struct StackRegisterContent* context = (struct StackRegisterContent*)&ExceptionInfo->stackframe;
if (ExceptionHook != NONE) {
x_err_t result = ExceptionHook(ExceptionStack);
if (result == EOK) return;
}
KPrintf("psr: 0x%08x\n", context->ExErrorStackContex.psr);
KPrintf("r00: 0x%08x\n", context->ExErrorStackContex.r0);
KPrintf("r01: 0x%08x\n", context->ExErrorStackContex.r1);
KPrintf("r02: 0x%08x\n", context->ExErrorStackContex.r2);
KPrintf("r03: 0x%08x\n", context->ExErrorStackContex.r3);
KPrintf("r04: 0x%08x\n", context->r4);
KPrintf("r05: 0x%08x\n", context->r5);
KPrintf("r06: 0x%08x\n", context->r6);
KPrintf("r07: 0x%08x\n", context->r7);
KPrintf("r08: 0x%08x\n", context->r8);
KPrintf("r09: 0x%08x\n", context->r9);
KPrintf("r10: 0x%08x\n", context->r10);
KPrintf("r11: 0x%08x\n", context->r11);
//KPrintf("exc_ret: 0x%08x\n", context->exc_ret);
KPrintf("r12: 0x%08x\n", context->ExErrorStackContex.r12);
KPrintf(" lr: 0x%08x\n", context->ExErrorStackContex.lr);
KPrintf(" pc: 0x%08x\n", context->ExErrorStackContex.pc);
if (ExceptionInfo->ExcReturn & (1 << 2)) {
KPrintf("hard fault on task: %s\r\n\r\n", GetKTaskDescriptor()->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
} else {
KPrintf("hard fault on handler\r\n\r\n");
}
if ( (ExceptionInfo->ExcReturn & 0x10) == 0)
KPrintf("FPU active!\r\n");
#ifdef TOOL_SHELL
HardFaultTrack();
#endif
while (1);
}
void UpdateRunningTask(void)
{
RunningKTask = (struct TaskDescriptor *)InterruptToKtaskDescriptor;
}
void MemFaultExceptionPrint(struct ExceptionInfo *ExceptionInfo)
{
extern long ShowTask(void);
struct ExErrorStackContex* ExceptionStack = (struct ExErrorStackContex*)&ExceptionInfo->stackframe.ExErrorStackContex;
struct StackRegisterContent* context = (struct StackRegisterContent*)&ExceptionInfo->stackframe;
if (ExceptionHook != NONE) {
x_err_t result = ExceptionHook(ExceptionStack);
if (result == EOK) return;
}
KPrintf("psr: 0x%08x\n", context->ExErrorStackContex.psr);
KPrintf("r00: 0x%08x\n", context->ExErrorStackContex.r0);
KPrintf("r01: 0x%08x\n", context->ExErrorStackContex.r1);
KPrintf("r02: 0x%08x\n", context->ExErrorStackContex.r2);
KPrintf("r03: 0x%08x\n", context->ExErrorStackContex.r3);
KPrintf("r04: 0x%08x\n", context->r4);
KPrintf("r05: 0x%08x\n", context->r5);
KPrintf("r06: 0x%08x\n", context->r6);
KPrintf("r07: 0x%08x\n", context->r7);
KPrintf("r08: 0x%08x\n", context->r8);
KPrintf("r09: 0x%08x\n", context->r9);
KPrintf("r10: 0x%08x\n", context->r10);
KPrintf("r11: 0x%08x\n", context->r11);
KPrintf("exc_ret: 0x%08x\n", ExceptionInfo->ExcReturn);
KPrintf("r12: 0x%08x\n", context->ExErrorStackContex.r12);
KPrintf(" lr: 0x%08x\n", context->ExErrorStackContex.lr);
KPrintf(" pc: 0x%08x\n", context->ExErrorStackContex.pc);
if (ExceptionInfo->ExcReturn & (1 << 2)) {
KPrintf("hard fault on task: %s\r\n\r\n", GetKTaskDescriptor()->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
} else {
KPrintf("hard fault on handler\r\n\r\n");
}
if ((ExceptionInfo->ExcReturn & 0x10) == 0)
KPrintf("FPU active!\r\n");
#ifdef TOOL_SHELL
HardFaultTrack();
#endif
while (1);
}
void MemFaultHandle(uintptr_t *sp)
{
#ifdef TASK_ISOLATION
struct TaskDescriptor *task;
task = GetKTaskDescriptor();
if( task->task_dync_sched_member.isolation_flag == 1){
KPrintf("\nSegmentation fault, task: %s\n", task->task_base_info.name);
KTaskQuit();
}
else
#endif
{
MemFaultExceptionPrint((struct ExceptionInfo *)sp);
}
}
__attribute__((weak)) void HwCpuReset(void)
{
SCB_AIRCR = SCB_RESET_VALUE;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), Reboot, HwCpuReset, reset machine );
@@ -0,0 +1,58 @@
/*
* 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.
*/
#ifndef __INC_SVC_HANDLE_H__
#define __INC_SVC_HANDLE_H__
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
#define INT_FPU_REGS (1)
#else
#define INT_FPU_REGS (0)
#endif
#define HW_INT_REGS (8)
#define SW_INT_REGS (9 + INT_FPU_REGS)
#define REG_INT_R0 (SW_INT_REGS + 0) /* R0 */
#define REG_INT_R1 (SW_INT_REGS + 1) /* R1 */
#define REG_INT_R2 (SW_INT_REGS + 2) /* R2 */
#define REG_INT_R3 (SW_INT_REGS + 3) /* R3 */
#define REG_INT_R12 (SW_INT_REGS + 4) /* R12 */
#define REG_INT_R14 (SW_INT_REGS + 5) /* R14 = LR */
#define REG_INT_PC (SW_INT_REGS + 6) /* R15 = PC */
#define REG_INT_XPSR (SW_INT_REGS + 7) /* xPSR */
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
#define REG_INT_FPU_FLAG (0) /* fpu flag */
#define REG_INT_PRIMASK (1) /* PRIMASK */
#define REG_INT_R4 (2) /* R4 */
#define REG_INT_R5 (3) /* R5 */
#define REG_INT_R6 (4) /* R6 */
#define REG_INT_R7 (5) /* R7 */
#define REG_INT_R8 (6) /* R8 */
#define REG_INT_R9 (7) /* R9 */
#define REG_INT_R10 (8) /* R10 */
#define REG_INT_R11 (9) /* R11 */
#else
#define REG_INT_PRIMASK (0) /* PRIMASK */
#define REG_INT_R4 (1) /* R4 */
#define REG_INT_R5 (2) /* R5 */
#define REG_INT_R6 (3) /* R6 */
#define REG_INT_R7 (4) /* R7 */
#define REG_INT_R8 (5) /* R8 */
#define REG_INT_R9 (6) /* R9 */
#define REG_INT_R10 (7) /* R10 */
#define REG_INT_R11 (8) /* R11 */
#endif
#endif
@@ -0,0 +1,11 @@
ifeq ($(CONFIG_BOARD_CORTEX_M3_EVB),y)
SRC_FILES := boot.c interrupt_vector_evb.S
endif
ifeq ($(CONFIG_BOARD_STM32F103_NANO),y)
SRC_FILES := boot.S interrupt_vector_nano.S
endif
SRC_FILES += interrupt.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,36 @@
/*
* 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.
*/
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include <xs_base.h>
#ifdef BOARD_CORTEX_M3_EVB
#define ARCH_MAX_IRQ_NUM (256)
#endif
#ifdef BOARD_STM32F103_NANO
#define ARCH_MAX_IRQ_NUM (64)
#endif
#define ARCH_IRQ_NUM_OFFSET 0
#ifdef BOARD_CORTEX_M3_EVB
#define SYSTICK_IRQN 15
#define UART1_IRQn 21
#endif
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
@@ -0,0 +1,114 @@
/**
*************** (C) COPYRIGHT 2017 STMicroelectronics ************************
* @file startup_stm32f103xb.s
* @author MCD Application Team
* @brief STM32F103xB Devices vector table for Atollic toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Configure the clock system
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/**
* @file boot.S
* @brief derived from ST standard peripheral library
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-11-30
*/
/*************************************************
File name: boot.S
Description: Reset and init function
Others:
History:
1. Date: 2021-11-30
Author: AIIT XUOS Lab
Modification:
1. take startup_stm32f103xb.s for XiZi kernel
*************************************************/
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.equ BootRAM, 0xF108F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call the application's entry point.*/
bl entry
bx lr
.size Reset_Handler, .-Reset_Handler
@@ -0,0 +1,97 @@
//*****************************************************************************
//
// startup_gcc.c - Startup code for use with GNU tools.
//
// Copyright (c) 2013 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 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.
//
// Neither the name of Texas Instruments Incorporated 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
// OWNER 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.
//
// This is part of revision 10636 of the Stellaris Firmware Development Package.
//
//*****************************************************************************
/**
* @file boot.c
* @brief derived from Stellaris Firmware Development Package
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-13
*/
/*************************************************
File name: boot.c
Description: Reset and init function
Others:
History:
1. Date: 2021-05-13
Author: AIIT XUOS Lab
Modification:
1. take startup_gcc.c from revision 10636 of the Stellaris Firmware Development Package for XiZi kernel
*************************************************/
extern unsigned long _sidata;
extern unsigned long _sdata;
extern unsigned long _edata;
extern unsigned long _sbss;
extern unsigned long _ebss;
extern int entry(void);
void
Reset_Handler(void)
{
unsigned long *pulSrc, *pulDest;
//
// Copy the data segment initializers from flash to SRAM.
//
pulSrc = &_sidata;
for(pulDest = &_sdata; pulDest < &_edata; )
{
*pulDest++ = *pulSrc++;
}
//
// Zero fill the bss segment.
//
__asm(" ldr r0, =_sbss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
" .thumb_func\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
//
// Call the application's entry point.
//
entry();
}
@@ -0,0 +1,84 @@
/*
* 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 interrupt.c
* @brief support arm cortex-m4 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
*/
#include <xs_base.h>
#include <xs_isr.h>
x_base __attribute__((naked)) DisableLocalInterrupt()
{
asm volatile ("MRS r0, PRIMASK");
asm volatile ("CPSID I");
asm volatile ("BX LR ");
}
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
{
asm volatile ("MSR PRIMASK, r0");
asm volatile ("BX LR");
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
return EOK;
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
return EOK;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry()
{
uint32 ipsr;
__asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
isrManager.done->incCounter();
isrManager.done->handleIrq(ipsr);
KTaskOsAssignAfterIrq(NONE);
isrManager.done->decCounter();
}
void UsageFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{
}
}
void BusFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{
}
}
void NMI_Handler(int irqn, void *arg)
{
while (1)
{
}
}
@@ -0,0 +1,138 @@
//*****************************************************************************
//
// startup_gcc.c - Startup code for use with GNU tools.
//
// Copyright (c) 2013 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 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.
//
// Neither the name of Texas Instruments Incorporated 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
// OWNER 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.
//
// This is part of revision 10636 of the Stellaris Firmware Development Package.
//
//*****************************************************************************
/**
* @file interrupt_vector_evb.S
* @brief derived from Stellaris Firmware Development Package
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-13
*/
/*************************************************
File name: interrupt_vector_evb.S
Description: vector table for a Cortex M3
Others:
History:
1. Date: 2021-05-13
Author: AIIT XUOS Lab
Modification:
1. take startup_gcc.c from revision 10636 of the Stellaris Firmware Development Package for XiZi kernel
*************************************************/
//*****************************************************************************
//
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000.
//
//*****************************************************************************
.globl InterruptVectors
/******************************************************************************
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type InterruptVectors, %object
.size InterruptVectors, .-InterruptVectors
InterruptVectors:
.word _sp
.word Reset_Handler
.word NMI_Handler //NMI_Handler
.word HardFaultHandler
.word MemFaultHandler //MemManage_Handler
.word BusFault_Handler //BusFault_Handler
.word UsageFault_Handler //UsageFault_Handler
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry //SVC_Handler
.word IsrEntry //DebugMon_Handler
.word IsrEntry
.word PendSV_Handler
.word SysTick_Handler //systick
.word IsrEntry // GPIO Port A
.word IsrEntry // GPIO Port B
.word IsrEntry // GPIO Port C
.word IsrEntry // GPIO Port D
.word IsrEntry // GPIO Port E
.word IsrEntry // UART0 Rx and Tx
.word IsrEntry // UART1 Rx and Tx
.word IsrEntry // SSI Rx and Tx
.word IsrEntry // I2C Master and Slave
.word IsrEntry // PWM Fault
.word IsrEntry // PWM Generator 0
.word IsrEntry // PWM Generator 1
.word IsrEntry // PWM Generator 2
.word IsrEntry // Quadrature Encoder
.word IsrEntry // ADC Sequence 0
.word IsrEntry // ADC Sequence 1
.word IsrEntry // ADC Sequence 2
.word IsrEntry // ADC Sequence 3
.word IsrEntry // Watchdog timer
.word IsrEntry // Timer 0 subtimer A
.word IsrEntry // Timer 0 subtimer B
.word IsrEntry // Timer 1 subtimer A
.word IsrEntry // Timer 1 subtimer B
.word IsrEntry // Timer 2 subtimer A
.word IsrEntry // Timer 2 subtimer B
.word IsrEntry // Analog Comparator 0
.word IsrEntry // Analog Comparator 1
.word IsrEntry // Analog Comparator 2
.word IsrEntry // System Control (PLL, OSC,
.word IsrEntry // FLASH Control
.word IsrEntry // GPIO Port F
.word IsrEntry // GPIO Port G
.word IsrEntry // GPIO Port H
.word IsrEntry // UART2 Rx and Tx
.word IsrEntry // SSI1 Rx and Tx
.word IsrEntry // Timer 3 subtimer A
.word IsrEntry // Timer 3 subtimer B
.word IsrEntry // I2C1 Master and Slave
.word IsrEntry // Quadrature Encoder 1
.word IsrEntry // CAN0
.word IsrEntry // CAN1
.word IsrEntry // CAN2
.word IsrEntry // Ethernet
.word IsrEntry // Hibernate
.word IsrEntry // USB0
.word IsrEntry // PWM Generator 3
.word IsrEntry // uDMA Software Transfer
.word IsrEntry // uDMA Error
@@ -0,0 +1,130 @@
/**
*************** (C) COPYRIGHT 2017 STMicroelectronics ************************
* @file startup_stm32f103xb.s
* @author MCD Application Team
* @brief STM32F103xB Devices vector table for Atollic toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Configure the clock system
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/**
* @file interrupt_vector_nano.S
* @brief derived from Stellaris Firmware Development Package
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-12-02
*/
/*************************************************
File name: interrupt_vector_nano.S
Description: vector table for a stm32f103xb
Others:
History:
1. Date: 2021-12-02
Author: AIIT XUOS Lab
Modification:
1. take startup_stm32f103xb.s for XiZi kernel reference
*************************************************/
//*****************************************************************************
//
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000.
//
//*****************************************************************************
.globl InterruptVectors
/******************************************************************************
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type InterruptVectors, %object
.size InterruptVectors, .-InterruptVectors
InterruptVectors:
.word _sp
.word Reset_Handler
.word NMI_Handler
.word HardFaultHandler
.word MemFaultHandler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word IsrEntry
.word IsrEntry
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word UartIsr1
.word IsrEntry //UartIsr2
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
@@ -0,0 +1,21 @@
ifeq ($(CONFIG_BOARD_CORTEX_M4_EVB),y)
SRC_FILES := interrupt.c system_init.c boot.S interrupt_vector.S coreclock.c svc_entry.S
ifeq ($(CONFIG_TASK_ISOLATION),y)
SRC_FILES += svc_handle.c mpu.c
endif
endif
ifeq ($(CONFIG_BOARD_STM32F407_EVB),y)
SRC_FILES := interrupt.c system_init.c boot.S interrupt_vector.S coreclock.c svc_entry.S
ifeq ($(CONFIG_TASK_ISOLATION),y)
SRC_FILES += svc_handle.c mpu.c
endif
endif
ifeq ($(CONFIG_BOARD_HC32F4A0_EVB),y)
SRC_DIR += hc32f4a0
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,25 @@
/*
* 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.
*/
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include <xs_base.h>
#define ARCH_MAX_IRQ_NUM (256 + 16)
#define ARCH_IRQ_NUM_OFFSET 16
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
@@ -0,0 +1,111 @@
/**
******************************************************************************
* @file startup_stm32f407xx.s
* @author MCD Application Team
* @brief STM32F407xx Devices vector table for GCC based toolchains.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M4 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of STMicroelectronics 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 boot.S
* @brief derived from ST standard peripheral library
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: boot.S
Description: Reset and init function
Others:
History:
1. Date: 2021-04-29
Author: AIIT XUOS Lab
Modification:
1. take startup_stm32f407xx.s for XiZi kernel
*************************************************/
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.word _sidata
.word _sdata
.word _edata
.word __bss_start
.word __bss_end
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr sp, =__stack_tp
movs r1, #0
/* Copy the data segment initializers from flash to SRAM */
DataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcs DataInitEnd
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
b DataInit
DataInitEnd:
ldr r2, =__bss_start
/* Zero fill the bss segment. */
BSSInit:
ldr r3, = __bss_end
cmp r2, r3
bcs BSSInitEnd
movs r3, #0
str r3, [r2], #4
b BSSInit
BSSInitEnd:
bl SystemInit
bl entry
bx lr
.size Reset_Handler, .-Reset_Handler
@@ -0,0 +1,109 @@
/**
******************************************************************************
* @file system_stm32f4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of STMicroelectronics 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 coreclock.c
* @brief support SystemCoreClockUpdate function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
*/
/*************************************************
File name: coreclock.c
Description: support SystemCoreClockUpdate function
Others:
History:
1. Date: 2021-04-29
Author: AIIT XUOS Lab
Modification:
1. take system_stm32f4xx.c for XiZi kernel
*************************************************/
#include "stm32f4xx.h"
uint32_t system_core_clock = 16000000;
const uint8_t ahb_presc_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t apb_presc_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp) {
case 0x00:
system_core_clock = HSI_VALUE;
break;
case 0x04:
system_core_clock = HSE_VALUE;
break;
case 0x08:
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
if (pllsource != 0)
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
else
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
system_core_clock = pllvco/pllp;
break;
default:
system_core_clock = HSI_VALUE;
break;
}
tmp = ahb_presc_table[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
system_core_clock >>= tmp;
}
@@ -0,0 +1,3 @@
SRC_FILES := interrupt.c boot.S interrupt_vector.S
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,201 @@
;/*****************************************************************************
; * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved.
; *
; * This software component is licensed by XHSC under BSD 3-Clause license
; * (the "License"); You may not use this file except in compliance with the
; * License. You may obtain a copy of the License at:
; * opensource.org/licenses/BSD-3-Clause
; *
; */
/*****************************************************************************/
/* Startup for GCC */
/* Version V1.0 */
/* Date 2022-03-31 */
/* Target-mcu HC32F4A0 */
/*****************************************************************************/
/**
* @file boot.S
* @brief derived from XHSC library
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-09-08
*/
/*************************************************
File name: boot.S
Description: Reset and init function
Others:
History:
1. Date: 2022-09-08
Author: AIIT XUOS Lab
Modification:
1. take startup_hc32f4a0.S for XiZi kernel
*************************************************/
/*
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
.syntax unified
.arch armv7e-m
.cpu cortex-m4
.fpu softvfp
.thumb
/*
;<h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
;</h>
*/
.equ Stack_Size, 0x00002000
.section .stack
.align 3
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
/*
;<h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
;</h>
*/
.equ Heap_Size, 0x00002000
.if Heap_Size != 0 /* Heap is provided */
.section .heap
.align 3
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.space Heap_Size
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.endif
/*
;<h> Reset handler start.
*/
.section .text.Reset_Handler
.align 2
.weak Reset_Handler
.type Reset_Handler, %function
.globl Reset_Handler
Reset_Handler:
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
StackInit:
ldr r1, =__StackLimit
ldr r2, =__StackTop
movs r0, 0
StackInitLoop:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt StackInitLoop
ClrSramSR:
ldr r0, =0x40050810
movw r1, #0x1FF
str r1, [r0]
/* Copy data from read only memory to RAM. */
CopyData:
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
CopyLoop:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt CopyLoop
CopyData1:
ldr r1, =__etext_ramb
ldr r2, =__data_start_ramb__
ldr r3, =__data_end_ramb__
CopyLoop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt CopyLoop1
/* This part of work usually is done in C library startup code.
* Otherwise, define this macro to enable it in this startup.
*
* There are two schemes too.
* One can clear multiple BSS sections. Another can only clear one section.
* The former is more size expensive than the latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise define macro __STARTUP_CLEAR_BSS to choose the later.
*/
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
/* Clear BSS section. */
ClearBss:
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
ClearLoop:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt ClearLoop
ClearBss1:
ldr r1, =__bss_start_ramb__
ldr r2, =__bss_end_ramb__
movs r0, 0
ClearLoop1:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt ClearLoop1
/* Call the clock system initialization function. */
bl SystemInit
/* Call the application's entry point. */
bl entry
bx lr
.size Reset_Handler, . - Reset_Handler
/*
;<h> Reset handler end.
*/
/*
;<h> Default handler start.
*/
.section .text.Default_Handler, "ax", %progbits
.align 2
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/*
;<h> Default handler end.
*/
@@ -0,0 +1,83 @@
/*
* 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 interrupt.c
* @brief support hc32f4a0 board arm cortex-m4 interrupt function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-09-14
*/
#include <xs_base.h>
#include <xs_isr.h>
x_base __attribute__((naked)) DisableLocalInterrupt()
{
asm volatile ("MRS r0, PRIMASK");
asm volatile ("CPSID I");
asm volatile ("BX LR ");
}
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
{
asm volatile ("MSR PRIMASK, r0");
asm volatile ("BX LR");
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
return EOK;
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
return EOK;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry()
{
uint32 ipsr;
__asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
isrManager.done->incCounter();
isrManager.done->handleIrq(ipsr);
KTaskOsAssignAfterIrq(NONE);
isrManager.done->decCounter();
}
void UsageFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{
}
}
void BusFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{
}
}
void NMI_Handler(int irqn, void *arg)
{
while (1)
{
}
}
@@ -0,0 +1,213 @@
;/*****************************************************************************
; * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved.
; *
; * This software component is licensed by XHSC under BSD 3-Clause license
; * (the "License"); You may not use this file except in compliance with the
; * License. You may obtain a copy of the License at:
; * opensource.org/licenses/BSD-3-Clause
; *
; */
/*****************************************************************************/
/* Startup for GCC */
/* Version V1.0 */
/* Date 2022-03-31 */
/* Target-mcu HC32F4A0 */
/*****************************************************************************/
/**
* @file interrupt_vector.S
* @brief derived from XHSC library
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-09-08
*/
/*************************************************
File name: interrupt_vector.S
Description: Interrupt Vectors
Others:
History:
1. Date: 2022-09-08
Author: AIIT XUOS Lab
Modification:
1. take startup_hc32f4a0.s for XiZi kernel
*************************************************/
/*
;<h> Interrupt vector table start.
*/
.section .isr_vector, "a", %progbits
.align 2
.type InterruptVectors, %object
.globl InterruptVectors
.globl InterruptVectors_End
.globl InterruptVectors_Size
InterruptVectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* -14 NMI Handler */
.long HardFaultHandler /* -13 Hard Fault Handler */
.long MemFaultHandler /* -12 MPU Fault Handler */
.long BusFault_Handler /* -11 Bus Fault Handler */
.long UsageFault_Handler /* -10 Usage Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long IsrEntry /* -5 SVCall Handler */
.long IsrEntry /* -4 Debug Monitor Handler */
.long 0 /* Reserved */
.long PendSV_Handler /* -2 PendSV Handler */
.long SysTick_Handler /* -1 SysTick Handler */
/* Interrupts */
.long IRQ000_Handler
.long IRQ001_Handler
.long IRQ002_Handler
.long IRQ003_Handler
.long IRQ004_Handler
.long IRQ005_Handler
.long IRQ006_Handler
.long IRQ007_Handler
.long IRQ008_Handler
.long IRQ009_Handler
.long IRQ010_Handler
.long IRQ011_Handler
.long IRQ012_Handler
.long IRQ013_Handler
.long IRQ014_Handler
.long IRQ015_Handler
.long IRQ016_Handler
.long IRQ017_Handler
.long IRQ018_Handler
.long IRQ019_Handler
.long IRQ020_Handler
.long IRQ021_Handler
.long IRQ022_Handler
.long IRQ023_Handler
.long IRQ024_Handler
.long IRQ025_Handler
.long IRQ026_Handler
.long IRQ027_Handler
.long IRQ028_Handler
.long IRQ029_Handler
.long IRQ030_Handler
.long IRQ031_Handler
.long IRQ032_Handler
.long IRQ033_Handler
.long IRQ034_Handler
.long IRQ035_Handler
.long IRQ036_Handler
.long IRQ037_Handler
.long IRQ038_Handler
.long IRQ039_Handler
.long IRQ040_Handler
.long IRQ041_Handler
.long IRQ042_Handler
.long IRQ043_Handler
.long IRQ044_Handler
.long IRQ045_Handler
.long IRQ046_Handler
.long IRQ047_Handler
.long IRQ048_Handler
.long IRQ049_Handler
.long IRQ050_Handler
.long IRQ051_Handler
.long IRQ052_Handler
.long IRQ053_Handler
.long IRQ054_Handler
.long IRQ055_Handler
.long IRQ056_Handler
.long IRQ057_Handler
.long IRQ058_Handler
.long IRQ059_Handler
.long IRQ060_Handler
.long IRQ061_Handler
.long IRQ062_Handler
.long IRQ063_Handler
.long IRQ064_Handler
.long IRQ065_Handler
.long IRQ066_Handler
.long IRQ067_Handler
.long IRQ068_Handler
.long IRQ069_Handler
.long IRQ070_Handler
.long IRQ071_Handler
.long IRQ072_Handler
.long IRQ073_Handler
.long IRQ074_Handler
.long IRQ075_Handler
.long IRQ076_Handler
.long IRQ077_Handler
.long IRQ078_Handler
.long IRQ079_Handler
.long IRQ080_Handler
.long IRQ081_Handler
.long IRQ082_Handler
.long IRQ083_Handler
.long IRQ084_Handler
.long IRQ085_Handler
.long IRQ086_Handler
.long IRQ087_Handler
.long IRQ088_Handler
.long IRQ089_Handler
.long IRQ090_Handler
.long IRQ091_Handler
.long IRQ092_Handler
.long IRQ093_Handler
.long IRQ094_Handler
.long IRQ095_Handler
.long IRQ096_Handler
.long IRQ097_Handler
.long IRQ098_Handler
.long IRQ099_Handler
.long IRQ100_Handler
.long IRQ101_Handler
.long IRQ102_Handler
.long IRQ103_Handler
.long IRQ104_Handler
.long IRQ105_Handler
.long IRQ106_Handler
.long IRQ107_Handler
.long IRQ108_Handler
.long IRQ109_Handler
.long IRQ110_Handler
.long IRQ111_Handler
.long IRQ112_Handler
.long IRQ113_Handler
.long IRQ114_Handler
.long IRQ115_Handler
.long IRQ116_Handler
.long IRQ117_Handler
.long IRQ118_Handler
.long IRQ119_Handler
.long IRQ120_Handler
.long IRQ121_Handler
.long IRQ122_Handler
.long IRQ123_Handler
.long IRQ124_Handler
.long IRQ125_Handler
.long IRQ126_Handler
.long IRQ127_Handler
.long IRQ128_Handler
.long IRQ129_Handler
.long IRQ130_Handler
.long IRQ131_Handler
.long IRQ132_Handler
.long IRQ133_Handler
.long IRQ134_Handler
.long IRQ135_Handler
.long IRQ136_Handler
.long IRQ137_Handler
.long IRQ138_Handler
.long IRQ139_Handler
.long IRQ140_Handler
.long IRQ141_Handler
.long IRQ142_Handler
.long IRQ143_Handler
InterruptVectors_End:
.equ InterruptVectors_Size, InterruptVectors_End - InterruptVectors
.size InterruptVectors, . - InterruptVectors
/*
;<h> Interrupt vector table end.
*/
@@ -0,0 +1,90 @@
/*
* 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 interrupt.c
* @brief support arm cortex-m4 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
*/
#include <xs_base.h>
#include <xs_isr.h>
#include <misc.h>
#include <stm32f4xx.h>
extern void _svcall(uintptr_t* contex);
x_base __attribute__((naked)) DisableLocalInterrupt()
{
asm volatile ("MRS r0, PRIMASK");
asm volatile ("CPSID I");
asm volatile ("BX LR ");
}
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
{
asm volatile ("MSR PRIMASK, r0");
asm volatile ("BX LR");
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
NVIC_InitTypeDef nvic_init;
nvic_init.NVIC_IRQChannel = irq_num;
nvic_init.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init.NVIC_IRQChannelSubPriority = 0;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_init);
return EOK;
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
NVIC_InitTypeDef nvic_init;
nvic_init.NVIC_IRQChannel = irq_num;
nvic_init.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init.NVIC_IRQChannelSubPriority = 0;
nvic_init.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&nvic_init);
return EOK;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry()
{
uint32 ipsr;
__asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
isrManager.done->incCounter();
isrManager.done->handleIrq(ipsr);
KTaskOsAssignAfterIrq(NONE);
isrManager.done->decCounter();
}
uintptr_t *Svcall(unsigned int ipsr , uintptr_t* contex )
{
#ifdef TASK_ISOLATION
_svcall(contex);
#endif
return contex;
}
@@ -0,0 +1,171 @@
/**
******************************************************************************
* @file startup_stm32f407xx.s
* @author MCD Application Team
* @brief STM32F407xx Devices vector table for GCC based toolchains.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M4 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of STMicroelectronics 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 interrupt_vector.S
* @brief derived from ST standard peripheral library
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: interrupt_vector.S
Description: Interrupt Vectors
Others:
History:
1. Date: 2021-04-29
Author: AIIT XUOS Lab
Modification:
1. take startup_stm32f407xx.s for XiZi kernel
*************************************************/
.globl InterruptVectors
/******************************************************************************
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type InterruptVectors, %object
.size InterruptVectors, .-InterruptVectors
InterruptVectors:
.word __stack_end__
.word Reset_Handler
.word NMI_Handler
.word HardFaultHandler
.word MemFaultHandler
.word BusFault_Handler
.word UsageFault_Handler
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word IsrEntry
.word SVC_Entry /* SVC */
.word IsrEntry /* DebugMon */
.word IsrEntry
.word PendSV_Handler
.word IsrEntry /* SysTick */
.word IsrEntry /* Window WatchDog */
.word IsrEntry /* PVD through EXTI Line detection */
.word IsrEntry /* Tamper and TimeStamps through the EXTI line */
.word IsrEntry /* RTC Wakeup through the EXTI line */
.word IsrEntry /* FLASH */
.word IsrEntry /* RCC */
.word IsrEntry /* EXTI Line0 */
.word IsrEntry /* EXTI Line1 */
.word IsrEntry /* EXTI Line2 */
.word IsrEntry /* EXTI Line3 */
.word IsrEntry /* EXTI Line4 */
.word IsrEntry /* DMA1 Stream 0 */
.word IsrEntry /* DMA1 Stream 1 */
.word IsrEntry /* DMA1 Stream 2 */
.word IsrEntry /* DMA1 Stream 3 */
.word IsrEntry /* DMA1 Stream 4 */
.word IsrEntry /* DMA1 Stream 5 */
.word IsrEntry /* DMA1 Stream 6 */
.word IsrEntry /* ADC1, ADC2 and ADC3s */
.word IsrEntry /* CAN1 TX */
.word IsrEntry /* CAN1 RX0 */
.word IsrEntry /* CAN1 RX1 */
.word IsrEntry /* CAN1 SCE */
.word IsrEntry /* External Line[9:5]s */
.word IsrEntry /* TIM1 Break and TIM9 */
.word IsrEntry /* TIM1 Update and TIM10 */
.word IsrEntry /* TIM1 Trigger and Commutation and TIM11 */
.word IsrEntry /* TIM1 Capture Compare */
.word IsrEntry /* TIM2 */
.word IsrEntry /* TIM3 */
.word IsrEntry /* TIM4 */
.word IsrEntry /* I2C1 Event */
.word IsrEntry /* I2C1 Error */
.word IsrEntry /* I2C2 Event */
.word IsrEntry /* I2C2 Error */
.word IsrEntry /* SPI1 */
.word IsrEntry /* SPI2 */
.word IsrEntry /* USART1 */
.word IsrEntry /* USART2 */
.word IsrEntry /* USART3 */
.word IsrEntry /* External Line[15:10]s */
.word IsrEntry /* RTC Alarm (A and B) through EXTI Line */
.word IsrEntry /* USB OTG FS Wakeup through EXTI line */
.word IsrEntry /* TIM8 Break and TIM12 */
.word IsrEntry /* TIM8 Update and TIM13 */
.word IsrEntry /* TIM8 Trigger and Commutation and TIM14 */
.word IsrEntry /* TIM8 Capture Compare */
.word IsrEntry /* DMA1 Stream7 */
.word IsrEntry /* FSMC */
.word IsrEntry /* SDIO */
.word IsrEntry /* TIM5 */
.word IsrEntry /* SPI3 */
.word IsrEntry /* UART4 */
.word IsrEntry /* UART5 */
.word IsrEntry /* TIM6 and DAC1&2 underrun errors */
.word IsrEntry /* TIM7 */
.word IsrEntry /* DMA2 Stream 0 */
.word IsrEntry /* DMA2 Stream 1 */
.word IsrEntry /* DMA2 Stream 2 */
.word IsrEntry /* DMA2 Stream 3 */
.word IsrEntry /* DMA2 Stream 4 */
.word IsrEntry /* Ethernet */
.word IsrEntry /* Ethernet Wakeup through EXTI line */
.word IsrEntry /* CAN2 TX */
.word IsrEntry /* CAN2 RX0 */
.word IsrEntry /* CAN2 RX1 */
.word IsrEntry /* CAN2 SCE */
.word IsrEntry /* USB OTG FS */
.word IsrEntry /* DMA2 Stream 5 */
.word IsrEntry /* DMA2 Stream 6 */
.word IsrEntry /* DMA2 Stream 7 */
.word IsrEntry /* USART6 */
.word IsrEntry /* I2C3 event */
.word IsrEntry /* I2C3 error */
.word IsrEntry /* USB OTG HS End Point 1 Out */
.word IsrEntry /* USB OTG HS End Point 1 In */
.word IsrEntry /* USB OTG HS Wakeup through EXTI */
.word IsrEntry /* USB OTG HS */
.word IsrEntry /* DCMI */
.word IsrEntry /* CRYP crypto */
.word IsrEntry /* Hash and Rng */
.word IsrEntry /* FPU */
@@ -0,0 +1,292 @@
/****************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/**
* @file kswitch.h
* @brief risc-v ecall function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: kswitch.h
Description: arm svc function
Others: take incubator-nuttx arch/arm/include/armv7-m/syscall.h for references
https://github.com/apache/incubator-nuttx/tree/master/arch/arm/include/armv7-m/syscall.h
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. Modify function name for a unified
2. Add some functions when there is no system call
*************************************************/
#ifndef __XS_ARM_M4_KSWITCH_H__
#define __XS_ARM_M4_KSWITCH_H__
#include <stdint.h>
// #include <xs_service.h>
#include "../../../kernel/include/xs_service.h"
#ifdef TASK_ISOLATION
#define KERNEL_SWITCH 0x00
/****************************************************************************
* kernel switch functions
****************************************************************************/
/* SVC call with call number and no parameters */
static inline unsigned long KSwitch0(unsigned int nbr)
{
register long reg0 __asm__("r0") = (long)(nbr);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0)
: "memory"
);
return reg0;
}
/* SVC call with call number and one parameter */
static inline unsigned long KSwitch1(unsigned int nbr, unsigned long parm1)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg1 __asm__("r1") = (long)(parm1);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0), "r"(reg1)
: "memory"
);
return reg0;
}
/* SVC call with call number and two parameters */
static inline unsigned long KSwitch2(unsigned int nbr, unsigned long parm1,
unsigned long parm2)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg2 __asm__("r2") = (long)(parm2);
register long reg1 __asm__("r1") = (long)(parm1);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0), "r"(reg1), "r"(reg2)
: "memory"
);
return reg0;
}
/* SVC call with call number and four parameters.
*
*/
static inline unsigned long KSwitch3(unsigned int nbr, unsigned long parm1,
unsigned long parm2, unsigned long parm3)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg1 __asm__("r1") = (long)(parm1);
register long reg2 __asm__("r2") = (long)(parm2);
register long reg3 __asm__("r3") = (long)(parm3);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0), "r"(reg1), "r"(reg2),
"r"(reg3)
: "memory"
);
return reg0;
}
static inline unsigned long KSwitch4(unsigned int nbr, unsigned long parm1,
unsigned long parm2, unsigned long parm3,
unsigned long parm4)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg4 __asm__("r4") = (long)(parm4);
register long reg3 __asm__("r3") = (long)(parm3);
register long reg2 __asm__("r2") = (long)(parm2);
register long reg1 __asm__("r1") = (long)(parm1);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0), "r"(reg1), "r"(reg2),
"r"(reg3), "r"(reg4)
: "memory"
);
return reg0;
}
/* SVC call with call number and five parameters.
*
*/
static inline unsigned long KSwitch5(unsigned int nbr, unsigned long parm1,
unsigned long parm2, unsigned long parm3,
unsigned long parm4, unsigned long parm5)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg5 __asm__("r5") = (long)(parm5);
register long reg4 __asm__("r4") = (long)(parm4);
register long reg3 __asm__("r3") = (long)(parm3);
register long reg2 __asm__("r2") = (long)(parm2);
register long reg1 __asm__("r1") = (long)(parm1);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0), "r"(reg1), "r"(reg2),
"r"(reg3), "r"(reg4), "r"(reg5)
: "memory"
);
return reg0;
}
/* SVC call with call number and six parameters.
*
*/
static inline unsigned long KSwitch6(unsigned int nbr, unsigned long parm1,
unsigned long parm2, unsigned long parm3,
unsigned long parm4, unsigned long parm5,
unsigned long parm6)
{
register long reg0 __asm__("r0") = (long)(nbr);
register long reg6 __asm__("r6") = (long)(parm6);
register long reg5 __asm__("r5") = (long)(parm5);
register long reg4 __asm__("r4") = (long)(parm4);
register long reg3 __asm__("r3") = (long)(parm3);
register long reg2 __asm__("r2") = (long)(parm2);
register long reg1 __asm__("r1") = (long)(parm1);
__asm__ __volatile__
(
"svc %1"
: "=r"(reg0)
: "i"(KERNEL_SWITCH), "r"(reg0), "r"(reg1), "r"(reg2),
"r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6)
: "memory"
);
return reg0;
}
#else
static inline unsigned long KSwitch0(unsigned int knum)
{
uintptr_t param[1] = {0};
uint8_t num = 0;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
static inline unsigned long KSwitch1(unsigned int knum, unsigned long arg1)
{
uintptr_t param[1] = {0};
uint8_t num = 1;
param[0] = arg1;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
static inline unsigned long KSwitch2(unsigned int knum, unsigned long arg1,
unsigned long arg2)
{
uintptr_t param[2] = {0};
uint8_t num = 2;
param[0] = arg1;
param[1] = arg2;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
static inline unsigned long KSwitch3(unsigned int knum, unsigned long arg1,
unsigned long arg2, unsigned long arg3)
{
uintptr_t param[3] = {0};
uint8_t num = 3;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
static inline unsigned long KSwitch4(unsigned int knum, unsigned long arg1,
unsigned long arg2, unsigned long arg3,
unsigned long arg4)
{
uintptr_t param[4] = {0};
uint8_t num = 4;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
param[3] = arg4;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
static inline unsigned long KSwitch5(unsigned int knum, unsigned long arg1,
unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
uintptr_t param[5] = {0};
uint8_t num = 5;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
param[3] = arg4;
param[4] = arg5;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
static inline unsigned long KSwitch6(unsigned int knum, unsigned long arg1,
unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5,
unsigned long arg6)
{
uintptr_t param[6] = {0};
uint8_t num = 6;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
param[3] = arg4;
param[4] = arg5;
param[5] = arg6;
(struct KernelService*)SERVICETABLE[knum].fun(knum, param, num);
}
#endif
#endif
@@ -0,0 +1,203 @@
/*
* 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 "stm32f4xx.h"
#include "mpu.h"
#include "board.h"
#include <xs_isolation.h>
void MpuEnable(uint32_t option)
{
MPU->CTRL = MPU_ENABLE | option;
__DSB();
__ISB();
return ;
}
void MpuDisable(void)
{
__DMB();
MPU->CTRL = 0;
return;
}
void MpuClearRegion(uint8_t region)
{
__DMB();
MPU->RNR = region;
MPU->RBAR = 0;
MPU->RASR = 0;
return;
}
void MpuClearAllRegion(void)
{
__DMB();
for (int i = 0 ; i < 8 ; i++) {
MPU->RNR = i;
MPU->RBAR = 0;
MPU->RASR = 0;
}
return;
}
int8_t MpuAllocateRegion(void *task_mpu)
{
if(task_mpu == NONE)
return -1;
struct Mpu *mpu = (struct Mpu *)task_mpu;
int8_t free_region;
if ( mpu->count < MPU_MAX_REGION_NUM - 1) {
free_region = mpu->count;
mpu->count ++;
}
else
free_region = -1;
return free_region ;
}
size_t MpuLog2Ceil(size_t size)
{
size_t csize = 0;
while (size > 0) {
size >>= 1;
csize ++;
}
return csize;
}
int8_t MpuAddRegion(void *task_mpu, x_base addr , size_t size , uint8_t type)
{
if(task_mpu == NONE)
return -1;
struct Mpu *mpu = (struct Mpu *)task_mpu;
uint32_t l2size;
int8_t region ;
region = MpuAllocateRegion(mpu);
if (region < 0 ) {
// KPrintf("MPU region full \n");
return region;
}
uint32_t flag = 0;
switch (type)
{
case REGION_TYPE_CODE:
flag = MPU_RASR_AP_RO_RO | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S;
break;
case REGION_TYPE_DATA:
flag = MPU_RASR_AP_RW_RW | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S ;
break;
case REGION_TYPE_BSS:
flag = MPU_RASR_AP_RW_RW | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S ;
break;
case REGION_TYPE_HEAP:
flag = MPU_RASR_AP_RW_RW | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S ;
break;
default:
break;
}
l2size = MpuLog2Ceil(size);
addr = MPU_ALIGN(addr , 1 << l2size );
mpu->region[region].config.rasr = flag |MPU_RASR_REGION_SIZE(l2size) | MPU_ENABLE;
mpu->region[region].config.rbar = addr | MPU_RBAR_VALID | region ; //rbar must set region number
return region;
}
x_err_t MpuInit(void **task_mpu)
{
x_base addr_start;
uint32_t addr_size;
uint32_t flag;
if (MPU->TYPE == 0) {
KPrintf("mpu not surport \n");
return -1 ;
}
// KPrintf("mpu init ...\n");
struct Mpu *mpu;
mpu = (struct Mpu *)malloc(sizeof(struct Mpu));
memset(mpu, 0, sizeof(struct Mpu));
if (mpu == NONE)
return -ENOMEMORY;
MpuDisable();
MpuClearAllRegion(); //clear
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
//user flash
addr_start = USER_TEXT_START;
addr_size = USER_TEXT_END - USER_TEXT_START;
MpuAddRegion(mpu, addr_start , addr_size, REGION_TYPE_CODE);
//user sram
addr_start = USER_SRAM_START;
addr_size = USER_SRAM_END - USER_SRAM_START;
MpuAddRegion(mpu, addr_start , addr_size, REGION_TYPE_HEAP);
*task_mpu = mpu;
return EOK;
}
void MpuFree(void *task_mpu)
{
if(task_mpu == NONE)
return;
MpuDisable();
MpuClearAllRegion(); //clear
x_free(task_mpu);
}
void MpuLoad(void *task_mpu)
{
// KPrintf("MPU load .. \n");
MpuDisable();
MpuClearAllRegion(); //clear
if(task_mpu == NONE)
return;
struct Mpu *mpu = (struct Mpu *)task_mpu;
uint8_t region = 0 ;
#if 0
for ( region = 0 ; region <= mpu->count -1 ; region ++ ){
KPrintf("region: %d\n",region);
KPrintf("rasr 0x%08x \n",mpu->region[region].config.rasr);
KPrintf("rbar 0x%08x \n",mpu->region[region].config.rbar);
KPrintf("\n");
}
#endif
for ( region = 0 ; region <= mpu->count -1 ; region ++ ){
MPU->RNR = region;
MPU->RBAR = mpu->region[region].config.rbar;
MPU->RASR = mpu->region[region].config.rasr;
}
__DSB();
__ISB();
MpuEnable(MPU_PRIVDEFENA);
}
@@ -0,0 +1,97 @@
/*
* 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.
*/
#ifndef MPU_H
#define MPU_H
#include <xs_base.h>
#include <xs_klist.h>
#define MPU_ALIGN(size, align) (((size)) & ~((align) - 1))
#define USER_TEXT_START (uintptr_t)( USERSPACE )
#define USER_TEXT_END (uintptr_t)( USERSPACE->us_textend )
#define USER_SRAM_START (uintptr_t)( USERSPACE->us_datastart )
#define USER_SRAM_END (uintptr_t)( USER_MEMORY_END_ADDRESS )
#define MPU_MAX_REGION_NUM 8
/* MPU Control Register Bit Definitions */
#define MPU_ENABLE (1 << 0) /* Bit 0: Enable the MPU */
#define MPU_HFNMIENA (1 << 1) /* Bit 1: Enable MPU during hard fault, NMI, and FAULTMAS */
#define MPU_PRIVDEFENA (1 << 2) /* Bit 2: Enable privileged access to default memory map */
#define MPU_RBAR_VALID (1 << 4)
#define MPU_RASR_ENABLE (1 << 0) /* Bit 0: Region enable */
#define MPU_RASR_REGION_SIZE(n) ((n-1) << 1)
#define MPU_RASR_AP_NO_NO (0 << 24) /* P:None U:None */
#define MPU_RASR_AP_RW_NO (1 << 24) /* P:RW U:None */
#define MPU_RASR_AP_RW_RO (2 << 24) /* P:RW U:RO */
#define MPU_RASR_AP_RW_RW (3 << 24) /* P:RW U:RW */
#define MPU_RASR_AP_RO_NO (5 << 24) /* P:RO U:None */
#define MPU_RASR_AP_RO_RO (6 << 24) /* P:RO U:RO */
#define MPU_RASR_RASR_XN (1 << 28) /* Bit 28: Instruction access disable */
#define MPU_RASR_SRD_MASK (0xff << 8)
#define MPU_RASR_SRD_0 (0x01 << 8)
#define MPU_RASR_SRD_1 (0x02 << 8)
#define MPU_RASR_SRD_2 (0x04 << 8)
#define MPU_RASR_SRD_3 (0x08 << 8)
#define MPU_RASR_SRD_4 (0x10 << 8)
#define MPU_RASR_SRD_5 (0x20 << 8)
#define MPU_RASR_SRD_6 (0x40 << 8)
#define MPU_RASR_SRD_7 (0x80 << 8)
#define MPU_RASR_TEX_SHIFT (19) /* Bits 19-21: TEX Address Permission */
#define MPU_RASR_TEX_MASK (7 << 19)
#define MPU_RASR_TEX_0 (0 << 19) /* Strongly Ordered */
#define MPU_RASR_TEX_1 (1 << 19) /* Normal */
#define MPU_RASR_TEX_2 (2 << 19) /* Device */
#define MPU_RASR_TEX_BB(bb) ((4|(bb)) << 19)
#define MPU_RASR_B (1 << 16) /* Bit 16: Bufferable */
#define MPU_RASR_C (1 << 17) /* Bit 17: Cacheable */
#define MPU_RASR_S (1 << 18) /* Bit 18: Shareable */
struct MpuConfig
{
uint32_t rasr;
uint32_t rbar;
};
struct MpuRegion
{
x_base start;
x_base size;
struct MpuConfig config;
};
struct Mpu
{
uint8_t count;
struct MpuRegion region[MPU_MAX_REGION_NUM];
};
void MpuEnable( uint32_t option);
void MpuDisable(void);
x_err_t MpuInit(void **task_mpu);
void MpuLoad(void *task_mpu);
#endif
@@ -0,0 +1,81 @@
/*
* 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 <xsconfig.h>
.globl SVC_Entry
.syntax unified
.thumb
.file "svc_entry.S"
.text
.type SVC_Entry, %function
.thumb_func
SVC_Entry:
MRS r3, PRIMASK
CPSID I
MRS r0, ipsr
MRS r1, psp /* R1=The process stack pointer (PSP) */
STMDB r1!, {r3-r11} /* Save the remaining registers plus the SP/PRIMASK values */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
MOV r2, #0x00
TST lr, #0x10
MOVEQ r2, #0x01
STMFD r1!, {r2}
#endif
PUSH {lr}
BL Svcall /* R0=IRQ, R1=register save (msp) */
POP {lr}
MOV r1, r0
#ifdef TASK_ISOLATION
PUSH {lr}
BL GetTaskPrivilege
POP {lr}
#endif
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
LDMFD r1!, {r2}
#endif
LDMIA r1!, {r3-r11} /* Recover R4-R11, FPU flag and PRIMASK*/
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
ORR lr, lr, #0x10
CMP r2, #0
BICNE lr, lr, #0x10
#endif
MSR psp, r1
MRS r2, control
#ifdef TASK_ISOLATION
CMP r0, #1
BEQ unprivilege
privilege:
BIC r2, r2, #0x01
B exit
unprivilege:
ORR r2, r2, #0x01
#else
BIC r2, r2, #0x01
#endif
exit:
MSR control, r2
ORR lr, lr, #0x04
MSR PRIMASK, r3
BX lr
@@ -0,0 +1,92 @@
/*
* 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 <xs_base.h>
#include <stdint.h>
#include "svc_handle.h"
#include <xs_service.h>
#include <xs_ktask.h>
static void SvcDispatch(void) __attribute__ ((naked, no_instrument_function));
static void SvcDispatch(void)
{
__asm__ __volatile__
(
" mov r12, sp\n"
" sub r12, r12, #36\n"
" and r12, r12, #7\n"
" add r12, r12, #36\n"
" sub sp, sp, r12\n"
" str r0, [sp, #0]\n"
" str r1, [sp, #4]\n"
" str r2, [sp, #8]\n"
" str r3, [sp, #12]\n"
" str r4, [sp, #16]\n"
" str r5, [sp, #20]\n"
" str r6, [sp, #24]\n"
" str lr, [sp, #28]\n"
" str r12, [sp, #32]\n"
" mov r0, sp\n"
" ldr r12, =SvcHandle\n"
" blx r12\n"
" ldr lr, [sp, #28]\n"
" ldr r2, [sp, #32]\n"
" add sp, sp, r2\n"
" svc 1"
);
}
void _svcall(uintptr_t* contex)
{
uint32_t svc_number;
KTaskDescriptorType tid;
tid = GetKTaskDescriptor();
svc_number = ((char *)contex[REG_INT_PC ])[-2];
switch (svc_number) {
case 0: //svc handler
tid->task_dync_sched_member.svc_return = contex[REG_INT_PC];
tid->task_dync_sched_member.isolation_status = 1;
contex[REG_INT_PC] = (uint32_t)SvcDispatch & ~1;
break;
case 1: // svc return
contex[REG_INT_PC] = tid->task_dync_sched_member.svc_return;
tid->task_dync_sched_member.isolation_status = 0;
break;
default:
KPrintf("unsurport svc call number :%d\n",svc_number);
break;
}
}
uintptr_t SvcHandle(uintptr_t *sp)
{
uint32_t service_num = 0;
service_num = ((uint32_t) sp[0]); //r0
uint8_t param_num = g_service_table[service_num].param_num;
uintptr_t *param = sp + 1;
return g_service_table[service_num].fun(service_num,param,param_num) ;
}
uint32_t GetTaskPrivilege(void){
uint32_t unprivileg = 0;
struct TaskDescriptor *task = GetKTaskDescriptor();
if (task->task_dync_sched_member.isolation_flag == 1 && task->task_dync_sched_member.isolation_status == 0) {
unprivileg = 1;
} else {
unprivileg = 0;
}
return unprivileg;
}
@@ -0,0 +1,100 @@
/**
******************************************************************************
* @file system_stm32f4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of STMicroelectronics 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 system_init.c
* @brief support SystemInit function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
*/
/*************************************************
File name: system_init.c
Description: support SystemInit function
Others:
History:
1. Date: 2021-04-29
Author: AIIT XUOS Lab
Modification:
1. take system_stm32f4xx.c for XiZi kernel
*************************************************/
#include "stm32f4xx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#define VECT_TAB_OFFSET 0x00
void SystemInit(void)
{
//cortex-m4 FPU register support
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
RCC->CR |= (uint32_t)0x00000001;
RCC->CFGR = 0x00000000;
RCC->CR &= (uint32_t)0xFEF6FFFF;
RCC->PLLCFGR = 0x24003010;
RCC->CR &= (uint32_t)0xFFFBFFFF;
RCC->CIR = 0x00000000;
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
#endif
}
@@ -0,0 +1,3 @@
SRC_FILES := boot.S interrupt.c interrupt_vector.S
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,38 @@
/*
* 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.
*/
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include <xs_base.h>
#define ARCH_MAX_IRQ_NUM (256)
//#define ARCH_IRQ_NUM_OFFSET 0
//#define SYSTICK_IRQN 15
//#define UART1_IRQn 36
//#define UART2_IRQn 37
#define ARCH_IRQ_NUM_OFFSET 16
#define SYSTICK_IRQN -1
#define UART1_IRQn 20
#define UART2_IRQn 21
#define USB1_IRQn 113
#define USB2_IRQn 112
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
@@ -0,0 +1,148 @@
/* ------------------------------------------------------------------------- */
/* @file: startup_MIMXRT1052.s */
/* @purpose: CMSIS Cortex-M7 Core Device Startup File */
/* MIMXRT1052 */
/* @version: 1.0 */
/* @date: 2018-9-21 */
/* @build: b180921 */
/* ------------------------------------------------------------------------- */
/* */
/* Copyright 1997-2016 Freescale Semiconductor, Inc. */
/* Copyright 2016-2018 NXP */
/* All rights reserved. */
/* */
/* SPDX-License-Identifier: BSD-3-Clause */
/*****************************************************************************/
/* Version: GCC for ARM Embedded Processors */
/*****************************************************************************/
/**
* @file boot.S
* @brief Cortex-M7 start function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
*/
/*************************************************
File name: boot.S
Description: Contex-M7 start function function
Others: take startup_MIMXRT1052.s for references
History:
1. Date: 2021-05-28
Author: AIIT XUOS Lab
Modification:
1. add OS entry function
*************************************************/
.syntax unified
.arch armv7-m
.text
.thumb
/* Reset Handler */
.thumb_func
.align 2
.globl Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
cpsid i /* Mask interrupts */
.equ VTOR, 0xE000ED08
ldr r0, =VTOR
ldr r1, =__isr_vector
str r1, [r0]
ldr r2, [r1]
msr msp, r2
#ifndef __NO_SYSTEM_INIT
ldr r0,=SystemInit
blx r0
#endif
/* Loop to copy data from read only memory to RAM. The ranges
* of copy from/to are specified by following symbols evaluated in
* linker script.
* __etext: End of code section, i.e., begin of data sections to copy from.
* __data_start__/__data_end__: RAM address range that data should be
* __noncachedata_start__/__noncachedata_end__ : none cachable region
* copied to. Both must be aligned to 4 bytes boundary. */
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
#if 1
/* Here are two copies of loop implemenations. First one favors code size
* and the second one favors performance. Default uses the first one.
* Change to "#if 0" to use the second one */
.LC0:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .LC0
#else
subs r3, r2
ble .LC1
.LC0:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .LC0
.LC1:
#endif
#ifdef __STARTUP_INITIALIZE_NONCACHEDATA
ldr r2, =__noncachedata_start__
ldr r3, =__noncachedata_init_end__
#if 1
.LC2:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .LC2
#else
subs r3, r2
ble .LC3
.LC2:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .LC2
.LC3:
#endif
/* zero inited ncache section initialization */
ldr r3, =__noncachedata_end__
movs r0,0
.LC4:
cmp r2,r3
itt lt
strlt r0,[r2],#4
blt .LC4
#endif /* __STARTUP_INITIALIZE_NONCACHEDATA */
#ifdef __STARTUP_CLEAR_BSS
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* Loop to zero out BSS section, which uses following symbols
* in linker script:
* __bss_start__: start of BSS section. Must align to 4
* __bss_end__: end of BSS section. Must align to 4
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.LC5:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .LC5
#endif /* __STARTUP_CLEAR_BSS */
ldr r0,=entry
blx r0
.size Reset_Handler, . - Reset_Handler
@@ -0,0 +1,85 @@
/*
* 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 interrupt.c
* @brief support arm cortex-m7 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
*/
#include <xs_base.h>
#include <xs_isr.h>
#include "fsl_common.h"
x_base __attribute__((naked)) DisableLocalInterrupt()
{
asm volatile ("MRS r0, PRIMASK");
asm volatile ("CPSID I");
asm volatile ("BX LR ");
}
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
{
asm volatile ("MSR PRIMASK, r0");
asm volatile ("BX LR");
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
EnableIRQ(irq_num);
return EOK;
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
DisableIRQ(irq_num);
return EOK;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry()
{
uint32 ipsr;
__asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
isrManager.done->incCounter();
isrManager.done->handleIrq(ipsr);
KTaskOsAssignAfterIrq(NONE);
isrManager.done->decCounter();
}
void UsageFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Usage Fault exception occurs */
while (1)
{
}
}
void BusFault_Handler(int irqn, void *arg)
{
/* Go to infinite loop when Bus Fault exception occurs */
while (1)
{
}
}
void NMI_Handler(int irqn, void *arg)
{
while (1)
{
}
}
@@ -0,0 +1,308 @@
/* ------------------------------------------------------------------------- */
/* @file: startup_MIMXRT1052.s */
/* @purpose: CMSIS Cortex-M7 Core Device Startup File */
/* MIMXRT1052 */
/* @version: 1.0 */
/* @date: 2018-9-21 */
/* @build: b180921 */
/* ------------------------------------------------------------------------- */
/* */
/* Copyright 1997-2016 Freescale Semiconductor, Inc. */
/* Copyright 2016-2018 NXP */
/* All rights reserved. */
/* */
/* SPDX-License-Identifier: BSD-3-Clause */
/*****************************************************************************/
/* Version: GCC for ARM Embedded Processors */
/*****************************************************************************/
/**
* @file interrupt_vector.S
* @brief vector table for Cortex M7
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
*/
/*************************************************
File name: interrupt_vector.S
Description: vector table for a Cortex M7
Others:
History:
1. Date: 2021-05-28
Author: AIIT XUOS Lab
Modification:
1. add IsrEntry as default isr function
*************************************************/
.syntax unified
.arch armv7-m
.section .isr_vector, "a"
.align 2
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler*/
.long HardFaultHandler /* Hard Fault Handler*/
.long MemFaultHandler /* MPU Fault Handler*/
.long BusFault_Handler /* Bus Fault Handler*/
.long UsageFault_Handler /* Usage Fault Handler*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long 0 /* Reserved*/
.long IsrEntry /* SVCall Handler*/
.long IsrEntry /* Debug Monitor Handler*/
.long 0 /* Reserved*/
.long PendSV_Handler /* PendSV Handler*/
.long IsrEntry /* SysTick Handler*/
/* External Interrupts*/
.long IsrEntry /* DMA channel 0/16 transfer complete*/
.long IsrEntry /* DMA channel 1/17 transfer complete*/
.long IsrEntry /* DMA channel 2/18 transfer complete*/
.long IsrEntry /* DMA channel 3/19 transfer complete*/
.long IsrEntry /* DMA channel 4/20 transfer complete*/
.long IsrEntry /* DMA channel 5/21 transfer complete*/
.long IsrEntry /* DMA channel 6/22 transfer complete*/
.long IsrEntry /* DMA channel 7/23 transfer complete*/
.long IsrEntry /* DMA channel 8/24 transfer complete*/
.long IsrEntry /* DMA channel 9/25 transfer complete*/
.long IsrEntry /* DMA channel 10/26 transfer complete*/
.long IsrEntry /* DMA channel 11/27 transfer complete*/
.long IsrEntry /* DMA channel 12/28 transfer complete*/
.long IsrEntry /* DMA channel 13/29 transfer complete*/
.long IsrEntry /* DMA channel 14/30 transfer complete*/
.long IsrEntry /* DMA channel 15/31 transfer complete*/
.long IsrEntry /* DMA error interrupt channels 0-15 / 16-31*/
.long IsrEntry /* CTI0_Error*/
.long IsrEntry /* CTI1_Error*/
.long IsrEntry /* CorePlatform exception IRQ*/
.long IsrEntry /* LPUART1 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART2 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART3 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART4 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART5 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART6 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART7 TX interrupt and RX interrupt*/
.long IsrEntry /* LPUART8 TX interrupt and RX interrupt*/
.long IsrEntry /* LPI2C1 interrupt*/
.long IsrEntry /* LPI2C2 interrupt*/
.long IsrEntry /* LPI2C3 interrupt*/
.long IsrEntry /* LPI2C4 interrupt*/
.long IsrEntry /* LPSPI1 single interrupt vector for all sources*/
.long IsrEntry /* LPSPI2 single interrupt vector for all sources*/
.long IsrEntry /* LPSPI3 single interrupt vector for all sources*/
.long IsrEntry /* LPSPI4 single interrupt vector for all sources*/
.long IsrEntry /* CAN1 interrupt*/
.long IsrEntry /* CAN2 interrupt*/
.long IsrEntry /* FlexRAM address out of range Or access hit IRQ*/
.long IsrEntry /* Keypad nterrupt*/
.long IsrEntry /* TSC interrupt*/
.long IsrEntry /* GPR interrupt*/
.long IsrEntry /* LCDIF interrupt*/
.long IsrEntry /* CSI interrupt*/
.long IsrEntry /* PXP interrupt*/
.long IsrEntry /* WDOG2 interrupt*/
.long IsrEntry /* SRTC Consolidated Interrupt. Non TZ*/
.long IsrEntry /* SRTC Security Interrupt. TZ*/
.long IsrEntry /* ON-OFF button press shorter than 5 secs (pulse event)*/
.long IsrEntry /* CSU interrupt*/
.long IsrEntry /* DCP_IRQ interrupt*/
.long IsrEntry /* DCP_VMI_IRQ interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* TRNG interrupt*/
.long IsrEntry /* SJC interrupt*/
.long IsrEntry /* BEE interrupt*/
.long IsrEntry /* SAI1 interrupt*/
.long IsrEntry /* SAI1 interrupt*/
.long IsrEntry /* SAI3 interrupt*/
.long IsrEntry /* SAI3 interrupt*/
.long IsrEntry /* SPDIF interrupt*/
.long IsrEntry /* Brown-out event interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* TempSensor low/high interrupt*/
.long IsrEntry /* TempSensor panic interrupt*/
.long IsrEntry /* USBPHY (UTMI0), Interrupt*/
.long IsrEntry /* USBPHY (UTMI0), Interrupt*/
.long IsrEntry /* ADC1 interrupt*/
.long IsrEntry /* ADC2 interrupt*/
.long IsrEntry /* DCDC interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* Active HIGH Interrupt from INT0 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT1 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT2 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT3 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT4 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT5 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT6 from GPIO*/
.long IsrEntry /* Active HIGH Interrupt from INT7 from GPIO*/
.long IsrEntry /* Combined interrupt indication for GPIO1 signal 0 throughout 15*/
.long IsrEntry /* Combined interrupt indication for GPIO1 signal 16 throughout 31*/
.long IsrEntry /* Combined interrupt indication for GPIO2 signal 0 throughout 15*/
.long IsrEntry /* Combined interrupt indication for GPIO2 signal 16 throughout 31*/
.long IsrEntry /* Combined interrupt indication for GPIO3 signal 0 throughout 15*/
.long IsrEntry /* Combined interrupt indication for GPIO3 signal 16 throughout 31*/
.long IsrEntry /* Combined interrupt indication for GPIO4 signal 0 throughout 15*/
.long IsrEntry /* Combined interrupt indication for GPIO4 signal 16 throughout 31*/
.long IsrEntry /* Combined interrupt indication for GPIO5 signal 0 throughout 15*/
.long IsrEntry /* Combined interrupt indication for GPIO5 signal 16 throughout 31*/
.long IsrEntry /* FLEXIO1 interrupt*/
.long IsrEntry /* FLEXIO2 interrupt*/
.long IsrEntry /* WDOG1 interrupt*/
.long IsrEntry /* RTWDOG interrupt*/
.long IsrEntry /* EWM interrupt*/
.long IsrEntry /* CCM IRQ1 interrupt*/
.long IsrEntry /* CCM IRQ2 interrupt*/
.long IsrEntry /* GPC interrupt*/
.long IsrEntry /* SRC interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* GPT1 interrupt*/
.long IsrEntry /* GPT2 interrupt*/
.long IsrEntry /* PWM1 capture 0, compare 0, or reload 0 interrupt*/
.long IsrEntry /* PWM1 capture 1, compare 1, or reload 0 interrupt*/
.long IsrEntry /* PWM1 capture 2, compare 2, or reload 0 interrupt*/
.long IsrEntry /* PWM1 capture 3, compare 3, or reload 0 interrupt*/
.long IsrEntry /* PWM1 fault or reload error interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* FlexSPI0 interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* USDHC1 interrupt*/
.long IsrEntry /* USDHC2 interrupt*/
.long IsrEntry /* USBO2 USB OTG2*/
.long IsrEntry /* USBO2 USB OTG1*/
.long IsrEntry /* ENET interrupt*/
.long IsrEntry /* ENET_1588_Timer interrupt*/
.long IsrEntry /* XBAR1 interrupt*/
.long IsrEntry /* XBAR1 interrupt*/
.long IsrEntry /* ADCETC IRQ0 interrupt*/
.long IsrEntry /* ADCETC IRQ1 interrupt*/
.long IsrEntry /* ADCETC IRQ2 interrupt*/
.long IsrEntry /* ADCETC Error IRQ interrupt*/
.long IsrEntry /* PIT interrupt*/
.long IsrEntry /* ACMP interrupt*/
.long IsrEntry /* ACMP interrupt*/
.long IsrEntry /* ACMP interrupt*/
.long IsrEntry /* ACMP interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* Reserved interrupt*/
.long IsrEntry /* ENC1 interrupt*/
.long IsrEntry /* ENC2 interrupt*/
.long IsrEntry /* ENC3 interrupt*/
.long IsrEntry /* ENC4 interrupt*/
.long IsrEntry /* TMR1 interrupt*/
.long IsrEntry /* TMR2 interrupt*/
.long IsrEntry /* TMR3 interrupt*/
.long IsrEntry /* TMR4 interrupt*/
.long IsrEntry /* PWM2 capture 0, compare 0, or reload 0 interrupt*/
.long IsrEntry /* PWM2 capture 1, compare 1, or reload 0 interrupt*/
.long IsrEntry /* PWM2 capture 2, compare 2, or reload 0 interrupt*/
.long IsrEntry /* PWM2 capture 3, compare 3, or reload 0 interrupt*/
.long IsrEntry /* PWM2 fault or reload error interrupt*/
.long IsrEntry /* PWM3 capture 0, compare 0, or reload 0 interrupt*/
.long IsrEntry /* PWM3 capture 1, compare 1, or reload 0 interrupt*/
.long IsrEntry /* PWM3 capture 2, compare 2, or reload 0 interrupt*/
.long IsrEntry /* PWM3 capture 3, compare 3, or reload 0 interrupt*/
.long IsrEntry /* PWM3 fault or reload error interrupt*/
.long IsrEntry /* PWM4 capture 0, compare 0, or reload 0 interrupt*/
.long IsrEntry /* PWM4 capture 1, compare 1, or reload 0 interrupt*/
.long IsrEntry /* PWM4 capture 2, compare 2, or reload 0 interrupt*/
.long IsrEntry /* PWM4 capture 3, compare 3, or reload 0 interrupt*/
.long IsrEntry /* PWM4 fault or reload error interrupt*/
.long IsrEntry /* 168*/
.long IsrEntry /* 169*/
.long IsrEntry /* 170*/
.long IsrEntry /* 171*/
.long IsrEntry /* 172*/
.long IsrEntry /* 173*/
.long IsrEntry /* 174*/
.long IsrEntry /* 175*/
.long IsrEntry /* 176*/
.long IsrEntry /* 177*/
.long IsrEntry /* 178*/
.long IsrEntry /* 179*/
.long IsrEntry /* 180*/
.long IsrEntry /* 181*/
.long IsrEntry /* 182*/
.long IsrEntry /* 183*/
.long IsrEntry /* 184*/
.long IsrEntry /* 185*/
.long IsrEntry /* 186*/
.long IsrEntry /* 187*/
.long IsrEntry /* 188*/
.long IsrEntry /* 189*/
.long IsrEntry /* 190*/
.long IsrEntry /* 191*/
.long IsrEntry /* 192*/
.long IsrEntry /* 193*/
.long IsrEntry /* 194*/
.long IsrEntry /* 195*/
.long IsrEntry /* 196*/
.long IsrEntry /* 197*/
.long IsrEntry /* 198*/
.long IsrEntry /* 199*/
.long IsrEntry /* 200*/
.long IsrEntry /* 201*/
.long IsrEntry /* 202*/
.long IsrEntry /* 203*/
.long IsrEntry /* 204*/
.long IsrEntry /* 205*/
.long IsrEntry /* 206*/
.long IsrEntry /* 207*/
.long IsrEntry /* 208*/
.long IsrEntry /* 209*/
.long IsrEntry /* 210*/
.long IsrEntry /* 211*/
.long IsrEntry /* 212*/
.long IsrEntry /* 213*/
.long IsrEntry /* 214*/
.long IsrEntry /* 215*/
.long IsrEntry /* 216*/
.long IsrEntry /* 217*/
.long IsrEntry /* 218*/
.long IsrEntry /* 219*/
.long IsrEntry /* 220*/
.long IsrEntry /* 221*/
.long IsrEntry /* 222*/
.long IsrEntry /* 223*/
.long IsrEntry /* 224*/
.long IsrEntry /* 225*/
.long IsrEntry /* 226*/
.long IsrEntry /* 227*/
.long IsrEntry /* 228*/
.long IsrEntry /* 229*/
.long IsrEntry /* 230*/
.long IsrEntry /* 231*/
.long IsrEntry /* 232*/
.long IsrEntry /* 233*/
.long IsrEntry /* 234*/
.long IsrEntry /* 235*/
.long IsrEntry /* 236*/
.long IsrEntry /* 237*/
.long IsrEntry /* 238*/
.long IsrEntry /* 239*/
.long IsrEntry /* 240*/
.long IsrEntry /* 241*/
.long IsrEntry /* 242*/
.long IsrEntry /* 243*/
.long IsrEntry /* 244*/
.long IsrEntry /* 245*/
.long IsrEntry /* 246*/
.long IsrEntry /* 247*/
.long IsrEntry /* 248*/
.long IsrEntry /* 249*/
.long IsrEntry /* 250*/
.long IsrEntry /* 251*/
.long IsrEntry /* 252*/
.long IsrEntry /* 253*/
.long IsrEntry /* 254*/
.long 0xFFFFFFFF /* Reserved for user TRIM value*/
.size __isr_vector, . - __isr_vector
.text
.thumb
@@ -0,0 +1,4 @@
SRC_FILES := pendsv.S prepare_ahwstack.c arm32_switch.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,175 @@
/*
* 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 <xs_base.h>
#include <xs_ktask.h>
#define SCB_VTOR "0xE000ED08"
#define NVIC_INT_CTRL "0xE000ED04"
#define NVIC_SYSPRI2 "0xE000ED20"
#define NVIC_PENDSV_PRI "0x00FF0000"
#define NVIC_PENDSVSET "0x10000000"
void __attribute__((naked)) HwInterruptcontextSwitch(x_ubase from, x_ubase to, struct TaskDescriptor *to_task, void *context)
{
asm volatile ("PUSH {R4}");
asm volatile ("PUSH {R5}");
asm volatile ("LDR r4, =KtaskSwitchInterruptFlag");
asm volatile ("LDR r5, [r4]");
asm volatile ("CMP r5, #1");
asm volatile ("POP {R5}");
asm volatile ("POP {R4}");
asm volatile ("BEQ Arm32SwitchReswitch");
asm volatile ("PUSH {R4}");
asm volatile ("PUSH {R5}");
asm volatile ("LDR r4, =KtaskSwitchInterruptFlag");
asm volatile ("MOV r5, #1");
asm volatile ("STR r5, [r4]");
asm volatile ("LDR r4, =InterruptFromKtask");
asm volatile ("STR r0, [r4]");
asm volatile ("POP {R5}");
asm volatile ("POP {R4}");
asm volatile ("B Arm32SwitchReswitch");
}
void __attribute__((naked)) Arm32SwitchReswitch()
{
asm volatile ("PUSH {R4}");
asm volatile ("LDR r4, =InterruptToKtask");
asm volatile ("STR r1, [r4]");
asm volatile ("LDR r4, =InterruptToKtaskDescriptor");
asm volatile ("STR r2, [r4]");
asm volatile ("LDR r0, =" NVIC_INT_CTRL);
asm volatile ("LDR r1, =" NVIC_PENDSVSET);
asm volatile ("STR r1, [r0]");
asm volatile ("POP {R4}");
asm volatile ("BX LR");
}
void __attribute__((naked)) SwitchKtaskContext(x_ubase from, x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile("B HwInterruptcontextSwitch");
}
void __attribute__((naked)) SwitchKtaskContextTo(x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile ("LDR r2, =InterruptToKtask");
asm volatile ("STR r0, [r2]");
asm volatile ("LDR r2, =InterruptToKtaskDescriptor");
asm volatile ("STR r1, [r2]");
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
asm volatile ("MRS r2, CONTROL");
asm volatile ("BIC r2, #0x04");
asm volatile ("MSR CONTROL, r2");
#endif
asm volatile ("LDR r1, =InterruptFromKtask");
asm volatile ("MOV r0, #0x0");
asm volatile ("STR r0, [r1]");
asm volatile ("LDR r1, =KtaskSwitchInterruptFlag");
asm volatile ("MOV r0, #1");
asm volatile ("STR r0, [r1]");
asm volatile ("LDR r0, =" NVIC_SYSPRI2);
asm volatile ("LDR r1, =" NVIC_PENDSV_PRI);
asm volatile ("LDR.W r2, [r0,#0x00]");
asm volatile ("ORR r1,r1,r2");
asm volatile ("STR r1, [r0]");
asm volatile ("LDR r0, =" NVIC_INT_CTRL);
asm volatile ("LDR r1, =" NVIC_PENDSVSET);
asm volatile ("STR r1, [r0]");
asm volatile ("LDR r0, =" SCB_VTOR);
asm volatile ("LDR r0, [r0]");
asm volatile ("LDR r0, [r0]");
asm volatile ("NOP");
asm volatile ("MSR msp, r0");
asm volatile ("CPSIE F");
asm volatile ("CPSIE I");
asm volatile ("BX lr");
}
void __attribute__((naked)) HardFaultHandler()
{
asm volatile ("MRS r0, msp");
asm volatile ("TST lr, #0x04");
asm volatile ("BEQ Arm32SwitchGetSpDone");
asm volatile ("MRS r0, psp");
asm volatile ("B Arm32SwitchGetSpDone");
}
void __attribute__((naked)) Arm32SwitchGetSpDone()
{
asm volatile ("MRS r3, primask");
asm volatile ("STMFD r0!, {r3 - r11}");
asm volatile ("STMFD r0!, {lr}");
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
asm volatile ("MOV r4, #0x00");
asm volatile ("TST lr, #0x10");
asm volatile ("MOVEQ r4, #0x01");
asm volatile ("STMFD r0!, {r4}");
#endif
asm volatile ("TST lr, #0x04");
asm volatile ("BEQ Arm32SwitchUpdateMsp");
asm volatile ("MSR psp, r0");
asm volatile ("B Arm32SwitchUpdateDone");
asm volatile ("B Arm32SwitchUpdateMsp");
}
void __attribute__((naked)) Arm32SwitchUpdateMsp()
{
asm volatile ("MSR msp, r0");
asm volatile ("B Arm32SwitchUpdateDone");
}
void __attribute__((naked)) Arm32SwitchUpdateDone()
{
asm volatile ("PUSH {LR}");
asm volatile ("BL HwHardFaultException");
asm volatile ("POP {LR}");
asm volatile ("ORR lr, lr, #0x04");
asm volatile ("BX lr");
}
void __attribute__((naked)) MemFaultHandler()
{
asm volatile ("MRS r0, msp");
asm volatile ("TST lr, #0x04");
asm volatile ("BEQ Arm32Switch1");
asm volatile ("MRS r0, psp");
asm volatile ("B Arm32Switch1");
}
void __attribute__((naked)) Arm32Switch1()
{
asm volatile ("MRS r3, primask");
asm volatile ("STMFD r0!, {r3 - r11}");
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
asm volatile ("MOV r4, #0x00");
asm volatile ("TST lr, #0x10");
asm volatile ("MOVEQ r4, #0x01");
asm volatile ("STMFD r0!, {r4}");
#endif
asm volatile ("STMFD r0!, {lr}");
asm volatile ("PUSH {LR}");
asm volatile ("BL MemFaultHandle");
asm volatile ("POP {LR}");
asm volatile ("ORR lr, lr, #0x04");
asm volatile ("BX lr");
}
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2009-10-11 Bernard first version
* 2012-01-01 aozima support context switch load/store FPU register.
* 2013-06-18 aozima add restore MSP feature.
* 2013-06-23 aozima support lazy stack optimized.
* 2018-07-24 aozima enhancement hard fault exception handler.
*/
/*************************************************
File name: pendsv.S
Description: PendSV interrupt handler
Others: take RT-Thread v4.0.2/libcpu/arm/cortex-m4/context_gcc.S for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
*************************************************/
#include <xsconfig.h>
.cpu cortex-m4
.syntax unified
.thumb
.text
.equ SCB_VTOR, 0xE000ED08
.equ NVIC_INT_CTRL, 0xE000ED04
.equ NVIC_SYSPRI2, 0xE000ED20
.equ NVIC_PENDSV_PRI, 0x00FF0000
.equ NVIC_PENDSVSET, 0x10000000
.globl PendSV_Handler
.type PendSV_Handler, %function
PendSV_Handler:
MRS r3, PRIMASK
CPSID I
LDR r0, =KtaskSwitchInterruptFlag
LDR r1, [r0]
CBZ r1, pendsv_exit
MOV r1, #0x00
STR r1, [r0]
LDR r0, =InterruptFromKtask
LDR r1, [r0]
CBZ r1, switch_to_task
MRS r1, psp
STMFD r1!, {r3 - r11}
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
MOV r4, #0x00
TST lr, #0x10
MOVEQ r4, #0x01
STMFD r1!, {r4}
#endif
LDR r0, [r0]
STR r1, [r0]
switch_to_task:
#ifdef TASK_ISOLATION
PUSH {lr}
BL GetTaskPrivilege
POP {lr}
#endif
LDR r1, =InterruptToKtask
LDR r1, [r1]
LDR r1, [r1]
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
LDMFD r1!, {r2}
#endif
LDMFD r1!, {r3 - r11}
MSR psp, r1
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
ORR lr, lr, #0x10
CMP r2, #0
BICNE lr, lr, #0x10
#endif
MRS r2, control
#ifdef TASK_ISOLATION
CMP r0, #1
BEQ unprivilege
privilege:
BIC r2, r2, #0x01
B exit
unprivilege:
ORR r2, r2, #0x01
#else
BIC r2, r2, #0x01
#endif
exit:
MSR control, r2
pendsv_exit:
ORR lr, lr, #0x04
MSR PRIMASK, r3
BX lr
@@ -0,0 +1,413 @@
/*
* 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 <xs_base.h>
#include <xs_ktask.h>
#include <xs_assign.h>
#include "svc_handle.h"
#include <board.h>
#ifdef TOOL_SHELL
#include <shell.h>
#endif
#if (defined ( __GNUC__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__))
#define USE_FPU 1
#else
#define USE_FPU 0
#endif
uint32 InterruptFromKtask;
uint32 InterruptToKtask;
uint32 KtaskSwitchInterruptFlag;
uint32 InterruptToKtaskDescriptor;
#define RunningKTask Assign.os_running_task
static x_err_t (*ExceptionHook)(void *context) = NONE;
struct ExceptionStackRegister
{
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r12;
uint32 lr;
uint32 pc;
uint32 psr;
};
struct StackRegisterContent
{
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
uint32 flag;
#endif
uint32 primask;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
// uint32 exc_ret;
struct ExceptionStackRegister ExErrorStackContex;
};
struct ExceptionStackFrameFpu
{
uint32 r0;
uint32 r1;
uint32 r2;
uint32 r3;
uint32 r12;
uint32 lr;
uint32 pc;
uint32 psr;
#if USE_FPU
uint32 S0;
uint32 S1;
uint32 S2;
uint32 S3;
uint32 S4;
uint32 S5;
uint32 S6;
uint32 S7;
uint32 S8;
uint32 S9;
uint32 S10;
uint32 S11;
uint32 S12;
uint32 S13;
uint32 S14;
uint32 S15;
uint32 FPSCR;
uint32 NO_NAME;
#endif
};
struct StackFrameFpu
{
uint32 flag;
uint32 r4;
uint32 r5;
uint32 r6;
uint32 r7;
uint32 r8;
uint32 r9;
uint32 r10;
uint32 r11;
#if USE_FPU
uint32 s16;
uint32 s17;
uint32 s18;
uint32 s19;
uint32 s20;
uint32 s21;
uint32 s22;
uint32 s23;
uint32 s24;
uint32 s25;
uint32 s26;
uint32 s27;
uint32 s28;
uint32 s29;
uint32 s30;
uint32 s31;
#endif
struct ExceptionStackFrameFpu ExErrorStackContex;
};
uint8 KTaskStackSetup(struct TaskDescriptor *task)
{
struct StackRegisterContent* StackContex;
int i = 0;
task->stack_point = (uint8 *)ALIGN_MEN_DOWN((x_ubase)(task->task_base_info.stack_start + task->task_base_info.stack_depth), 8);
task->stack_point -= sizeof(struct StackRegisterContent);
StackContex = (struct StackRegisterContent*)task->stack_point;
for (i = 0; i < sizeof(struct StackRegisterContent) / sizeof(uint32); i++)
((uint32 *)StackContex)[i] = 0xfadeface;
StackContex->ExErrorStackContex.r0 = (unsigned long)task->task_base_info.func_param;
StackContex->ExErrorStackContex.pc = (unsigned long)task->task_base_info.func_entry ;
StackContex->ExErrorStackContex.psr = 0x01000000L;
StackContex->primask = 0x00000000L;
#ifdef SEPARATE_COMPILE
if(task->task_dync_sched_member.isolation_flag == 1 ) {
StackContex->ExErrorStackContex.lr = (unsigned long)USERSPACE->us_taskquit;
} else {
StackContex->ExErrorStackContex.lr = (unsigned long)KTaskQuit;
}
#else
StackContex->ExErrorStackContex.lr = (unsigned long)KTaskQuit;
#endif
#if USE_FPU
StackContex->flag = 0;
#endif
return EOK;
}
void HwExceptionInstall(x_err_t (*exception_handle)(void *context))
{
ExceptionHook = exception_handle;
}
#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28)
#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C)
#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34)
#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38)
#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C)
#define SCB_RESET_VALUE 0x05FA0004
#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28)
#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29)
#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A)
#ifdef TOOL_SHELL
static void UsageFaultTrack(void)
{
KPrintf("usage fault:\n");
KPrintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
if(SCB_CFSR_UFSR & (1<<0))
KPrintf("UNDEFINSTR ");
if(SCB_CFSR_UFSR & (1<<1))
KPrintf("INVSTATE ");
if(SCB_CFSR_UFSR & (1<<2))
KPrintf("INVPC ");
if(SCB_CFSR_UFSR & (1<<3))
KPrintf("NOCP ");
if(SCB_CFSR_UFSR & (1<<8))
KPrintf("UNALIGNED ");
if(SCB_CFSR_UFSR & (1<<9))
KPrintf("DIVBYZERO ");
KPrintf("\n");
}
static void BusFaultTrack(void)
{
KPrintf("bus fault:\n");
KPrintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
if(SCB_CFSR_BFSR & (1<<0))
KPrintf("IBUSERR ");
if(SCB_CFSR_BFSR & (1<<1))
KPrintf("PRECISERR ");
if(SCB_CFSR_BFSR & (1<<2))
KPrintf("IMPRECISERR ");
if(SCB_CFSR_BFSR & (1<<3))
KPrintf("UNSTKERR ");
if(SCB_CFSR_BFSR & (1<<4))
KPrintf("STKERR ");
if(SCB_CFSR_BFSR & (1<<7))
KPrintf("SCB->BFAR:%08X\n", SCB_BFAR);
else
KPrintf("\n");
}
static void MemManageFaultTrack(void)
{
KPrintf("mem manage fault:\n");
KPrintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
if(SCB_CFSR_MFSR & (1<<0))
KPrintf("IACCVIOL ");
if(SCB_CFSR_MFSR & (1<<1))
KPrintf("DACCVIOL ");
if(SCB_CFSR_MFSR & (1<<3))
KPrintf("MUNSTKERR ");
if(SCB_CFSR_MFSR & (1<<4))
KPrintf("MSTKERR ");
if(SCB_CFSR_MFSR & (1<<7))
KPrintf("SCB->MMAR:%08X\n", SCB_MMAR);
else
KPrintf("\n");
}
static void HardFaultTrack(void)
{
if(SCB_HFSR & (1UL<<1))
KPrintf("failed vector fetch\n");
if(SCB_HFSR & (1UL<<30)) {
if(SCB_CFSR_BFSR)
BusFaultTrack();
if(SCB_CFSR_MFSR)
MemManageFaultTrack();
if(SCB_CFSR_UFSR)
UsageFaultTrack();
}
if(SCB_HFSR & (1UL<<31))
KPrintf("debug event\n");
}
#endif
struct ExceptionInfo
{
uint32 ExcReturn;
struct StackRegisterContent stackframe;
};
void HwHardFaultException(struct ExceptionInfo *ExceptionInfo)
{
extern long ShowTask(void);
struct ExErrorStackContex* ExceptionStack = (struct ExErrorStackContex*)&ExceptionInfo->stackframe.ExErrorStackContex;
struct StackRegisterContent* context = (struct StackRegisterContent*)&ExceptionInfo->stackframe;
if (ExceptionHook != NONE) {
x_err_t result = ExceptionHook(ExceptionStack);
if (result == EOK) return;
}
KPrintf("psr: 0x%08x\n", context->ExErrorStackContex.psr);
KPrintf("r00: 0x%08x\n", context->ExErrorStackContex.r0);
KPrintf("r01: 0x%08x\n", context->ExErrorStackContex.r1);
KPrintf("r02: 0x%08x\n", context->ExErrorStackContex.r2);
KPrintf("r03: 0x%08x\n", context->ExErrorStackContex.r3);
KPrintf("r04: 0x%08x\n", context->r4);
KPrintf("r05: 0x%08x\n", context->r5);
KPrintf("r06: 0x%08x\n", context->r6);
KPrintf("r07: 0x%08x\n", context->r7);
KPrintf("r08: 0x%08x\n", context->r8);
KPrintf("r09: 0x%08x\n", context->r9);
KPrintf("r10: 0x%08x\n", context->r10);
KPrintf("r11: 0x%08x\n", context->r11);
//KPrintf("exc_ret: 0x%08x\n", context->exc_ret);
KPrintf("r12: 0x%08x\n", context->ExErrorStackContex.r12);
KPrintf(" lr: 0x%08x\n", context->ExErrorStackContex.lr);
KPrintf(" pc: 0x%08x\n", context->ExErrorStackContex.pc);
if (ExceptionInfo->ExcReturn & (1 << 2)) {
KPrintf("hard fault on task: %s\r\n\r\n", GetKTaskDescriptor()->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
} else {
KPrintf("hard fault on handler\r\n\r\n");
}
if ( (ExceptionInfo->ExcReturn & 0x10) == 0)
KPrintf("FPU active!\r\n");
#ifdef TOOL_SHELL
HardFaultTrack();
#endif
while (1);
}
void UpdateRunningTask(void)
{
RunningKTask = (struct TaskDescriptor *)InterruptToKtaskDescriptor;
}
void MemFaultExceptionPrint(struct ExceptionInfo *ExceptionInfo)
{
extern long ShowTask(void);
struct ExErrorStackContex* ExceptionStack = (struct ExErrorStackContex*)&ExceptionInfo->stackframe.ExErrorStackContex;
struct StackRegisterContent* context = (struct StackRegisterContent*)&ExceptionInfo->stackframe;
if (ExceptionHook != NONE) {
x_err_t result = ExceptionHook(ExceptionStack);
if (result == EOK) return;
}
KPrintf("psr: 0x%08x\n", context->ExErrorStackContex.psr);
KPrintf("r00: 0x%08x\n", context->ExErrorStackContex.r0);
KPrintf("r01: 0x%08x\n", context->ExErrorStackContex.r1);
KPrintf("r02: 0x%08x\n", context->ExErrorStackContex.r2);
KPrintf("r03: 0x%08x\n", context->ExErrorStackContex.r3);
KPrintf("r04: 0x%08x\n", context->r4);
KPrintf("r05: 0x%08x\n", context->r5);
KPrintf("r06: 0x%08x\n", context->r6);
KPrintf("r07: 0x%08x\n", context->r7);
KPrintf("r08: 0x%08x\n", context->r8);
KPrintf("r09: 0x%08x\n", context->r9);
KPrintf("r10: 0x%08x\n", context->r10);
KPrintf("r11: 0x%08x\n", context->r11);
KPrintf("exc_ret: 0x%08x\n", ExceptionInfo->ExcReturn);
KPrintf("r12: 0x%08x\n", context->ExErrorStackContex.r12);
KPrintf(" lr: 0x%08x\n", context->ExErrorStackContex.lr);
KPrintf(" pc: 0x%08x\n", context->ExErrorStackContex.pc);
if (ExceptionInfo->ExcReturn & (1 << 2)) {
KPrintf("hard fault on task: %s\r\n\r\n", GetKTaskDescriptor()->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
} else {
KPrintf("hard fault on handler\r\n\r\n");
}
if ((ExceptionInfo->ExcReturn & 0x10) == 0)
KPrintf("FPU active!\r\n");
#ifdef TOOL_SHELL
HardFaultTrack();
#endif
while (1);
}
void MemFaultHandle(uintptr_t *sp)
{
#ifdef TASK_ISOLATION
struct TaskDescriptor *task;
task = GetKTaskDescriptor();
if( task->task_dync_sched_member.isolation_flag == 1){
KPrintf("\nSegmentation fault, task: %s\n", task->task_base_info.name);
KTaskQuit();
}
else
#endif
{
MemFaultExceptionPrint((struct ExceptionInfo *)sp);
}
}
__attribute__((weak)) void HwCpuReset(void)
{
SCB_AIRCR = SCB_RESET_VALUE;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), Reboot, HwCpuReset, reset machine );
@@ -0,0 +1,58 @@
/*
* 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.
*/
#ifndef __INC_SVC_HANDLE_H__
#define __INC_SVC_HANDLE_H__
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
#define INT_FPU_REGS (1)
#else
#define INT_FPU_REGS (0)
#endif
#define HW_INT_REGS (8)
#define SW_INT_REGS (9 + INT_FPU_REGS)
#define REG_INT_R0 (SW_INT_REGS + 0) /* R0 */
#define REG_INT_R1 (SW_INT_REGS + 1) /* R1 */
#define REG_INT_R2 (SW_INT_REGS + 2) /* R2 */
#define REG_INT_R3 (SW_INT_REGS + 3) /* R3 */
#define REG_INT_R12 (SW_INT_REGS + 4) /* R12 */
#define REG_INT_R14 (SW_INT_REGS + 5) /* R14 = LR */
#define REG_INT_PC (SW_INT_REGS + 6) /* R15 = PC */
#define REG_INT_XPSR (SW_INT_REGS + 7) /* xPSR */
#if defined ( __VFP_FP__ ) && !defined(__SOFTFP__)
#define REG_INT_FPU_FLAG (0) /* fpu flag */
#define REG_INT_PRIMASK (1) /* PRIMASK */
#define REG_INT_R4 (2) /* R4 */
#define REG_INT_R5 (3) /* R5 */
#define REG_INT_R6 (4) /* R6 */
#define REG_INT_R7 (5) /* R7 */
#define REG_INT_R8 (6) /* R8 */
#define REG_INT_R9 (7) /* R9 */
#define REG_INT_R10 (8) /* R10 */
#define REG_INT_R11 (9) /* R11 */
#else
#define REG_INT_PRIMASK (0) /* PRIMASK */
#define REG_INT_R4 (1) /* R4 */
#define REG_INT_R5 (2) /* R5 */
#define REG_INT_R6 (3) /* R6 */
#define REG_INT_R7 (4) /* R7 */
#define REG_INT_R8 (5) /* R8 */
#define REG_INT_R9 (6) /* R9 */
#define REG_INT_R10 (7) /* R10 */
#define REG_INT_R11 (8) /* R11 */
#endif
#endif