feat support nuvoton-m2354 bsp for Ubiquitous/XiZi kernel

This commit is contained in:
Liu_Weichao
2022-03-08 15:32:51 +08:00
parent a35e73e7dd
commit 2db01c89dd
152 changed files with 80100 additions and 21 deletions
+4
View File
@@ -26,4 +26,8 @@ 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
@@ -12,7 +12,7 @@
/**
* @file interrupt.c
* @brief support arm cortex-m4 interrupt function
* @brief support arm cortex-m0 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
@@ -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");
}
+131
View File
@@ -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,105 @@
/*
* 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:
BL UpdateRunningTask
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
@@ -82,6 +82,7 @@ Modification:
void SystemInit(void)
{
//cortex-m4 FPU register support
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
RCC->CR |= (uint32_t)0x00000001;
+1 -1
View File
@@ -19,7 +19,7 @@
/**
* @file boot.S
* @brief Contex-M7 start function
* @brief Cortex-M7 start function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
@@ -12,7 +12,7 @@
/**
* @file interrupt.c
* @brief support arm cortex-m4 interrupt function
* @brief support arm cortex-m7 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28