Adjust directory structure

This commit is contained in:
Zhao_Jiasheng
2021-06-03 17:38:11 +08:00
parent 92301257f3
commit 89a2236b18
1993 changed files with 40 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
config ARCH_CPU_64BIT
bool
config ARCH_RISCV
bool
config ARCH_ARM
bool
config ARCH_RISCV64
select ARCH_RISCV
select ARCH_CPU_64BIT
bool
+3
View File
@@ -0,0 +1,3 @@
SRC_DIR := $(ARCH)
include $(KERNEL_ROOT)/compiler.mk
+16
View File
@@ -0,0 +1,16 @@
#公共部分
SRC_DIR := shared
ifeq ($(CONFIG_BOARD_CORTEX_M3_EVB),y)
SRC_DIR +=cortex-m3
endif
ifeq ($(CONFIG_BOARD_STM32F407_EVB),y)
SRC_DIR +=cortex-m4
endif
ifeq ($(CONFIG_BOARD_CORTEX_M7_EVB),y)
SRC_DIR +=cortex-m7
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,3 @@
SRC_FILES := boot.c interrupt.c interrupt_vector.S
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 0
#define SYSTICK_IRQN 15
#define UART1_IRQn 21
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
@@ -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 XiUOS
*************************************************/
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.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 XiUOS
*************************************************/
//*****************************************************************************
//
// 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 IsrEntry //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,7 @@
SRC_FILES := system_init.c boot.S interrupt_vector.S coreclock.c interrupt.c svc_entry.S
ifeq ($(CONFIG_TASK_ISOLATION),y)
SRC_FILES += svc_handle.c mpu.c
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
+110
View File
@@ -0,0 +1,110 @@
/**
******************************************************************************
* @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 XiUOS
*************************************************/
.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 stm32f407_start
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 XiUOS
*************************************************/
#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,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 XiUOS
*************************************************/
.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
+203
View File
@@ -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);
}
+97
View File
@@ -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,99 @@
/**
******************************************************************************
* @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 XiUOS
*************************************************/
#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)
{
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,29 @@
/*
* 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
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
+148
View File
@@ -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 Contex-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,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-m4 interrupt function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-28
*/
#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,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,154 @@
/*
* 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 ("LDR r4, =KtaskSwitchInterruptFlag");
asm volatile ("LDR r5, [r4]");
asm volatile ("CMP r5, #1");
asm volatile ("BEQ Arm32SwitchReswitch");
asm volatile ("MOV r5, #1");
asm volatile ("STR r5, [r4]");
asm volatile ("LDR r4, =InterruptFromKtask");
asm volatile ("STR r0, [r4]");
asm volatile ("B Arm32SwitchReswitch");
}
void __attribute__((naked)) Arm32SwitchReswitch()
{
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 ("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");
}
+118
View File
@@ -0,0 +1,118 @@
/*
* 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:
PUSH {lr}
BL UpdateRunningTask
POP {lr}
#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,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
+28
View File
@@ -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 __KSWITCH_H__
#define __KSWITCH_H__
#ifdef SEPARATE_COMPILE
#if defined(ARCH_RISCV)
#include "risc-v/shared/kswitch.h"
#endif
#if defined(ARCH_ARM)
#include "arm/cortex-m4/kswitch.h"
#endif
#endif
#endif
+19
View File
@@ -0,0 +1,19 @@
SRC_DIR := shared
ifeq ($(CONFIG_BOARD_FE310_EVB),y)
SRC_DIR +=fe310
endif
ifeq ($(CONFIG_BOARD_K210_EVB),y)
SRC_DIR +=k210
endif
ifeq ($(CONFIG_BOARD_MAIX_GO_EVB),y)
SRC_DIR +=k210
endif
ifeq ($(CONFIG_BOARD_AIIT_RISCV_EVB),y)
SRC_DIR +=k210
endif
include $(KERNEL_ROOT)/compiler.mk
+206
View File
@@ -0,0 +1,206 @@
This software, except as otherwise noted in subrepositories,
is licensed under the Apache 2 license, quoted below.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 SiFive, Inc.
Licensed 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.
@@ -0,0 +1,3 @@
SRC_FILES := interrupt.c boot.S tick.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 <stdint.h>
#include <plic_driver.h>
#define ARCH_MAX_IRQ_NUM IRQN_MAX
#define ARCH_IRQ_NUM_OFFSET 0
uint32_t GetInterruptNumber(void);
void HwInterruptAck(uint32_t irq);
int32_t ArchEnableHwIrq(int irq_num);
int32_t ArchDisableHwIrq(int irq_num);
#endif
+134
View File
@@ -0,0 +1,134 @@
// See LICENSE for license details.
/**
* @file boot.S
* @brief hifive1-rev-B-board start function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: boot.S
Description: hifive1-rev-B-board start function
Others: take freedom-e-sdk v20180402/bsp/env/start.S for references
https://github.com/sifive/freedom-e-sdk/releases/tag/v20180402
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. See LICENSE details in xiuos/arch/risc-v/fe310/LICENSE
2. Modify entry function name
3. Modify OS startup function
4. Add interrupt entry function.
*************************************************/
#include <sifive/smp.h>
/* This is defined in sifive/platform.h, but that can't be included from
* assembly. */
#define CLINT_CTRL_ADDR 0x02000000
#include <encoding.h>
#include "register_para.h"
#include "boot.h"
.section .init
.globl _begin
.type _begin,@function
_begin:
.cfi_startproc
.cfi_undefined ra
.option push
.option norelax
la gp, __global_pointer$
.option pop
la sp, _sp
/* Load data section */
la a0, _data_lma
la a1, _data
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
2:
/* Clear bss section */
la a0, __bss_start
la a1, _end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/* Call global constructors */
//la a0, __libc_fini_array
//call atexit
//call __libc_init_array
#ifndef __riscv_float_abi_soft
/* Enable FPU */
li t0, MSTATUS_FS
csrs mstatus, t0
csrr t1, mstatus
and t1, t1, t0
beqz t1, 1f
fssr x0
1:
#endif
auipc ra, 0
addi sp, sp, -16
sw ra, 8(sp)
/* argc = argv = 0 */
li a0, 0
li a1, 0
call entry
/* tail exit */
1:
j 1b
.cfi_endproc
.section .text.entry
.align 2
.global save_hw_context
save_hw_context:
/* save all from thread context */
SAVE_X_REGISTERS
/* save break thread stack to s0 */
move s0, sp
#ifdef TASK_ISOLATION
csrr a0, mcause
srli a0, a0, 31
andi a0, a0, 0x1
beqz a0, 1f
#endif
/* switch to interrupt stack */
la sp, _sp
1:
/* interrupt handle */
csrr a0, mcause
csrr a1, mepc
mv a2, sp
call HandleTrap
/* switch to from_thread stack */
move sp, s0
mv a0, fp
call KTaskOsAssignAfterIrq
j SwitchKTaskContextExit
@@ -0,0 +1,281 @@
/*
* 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 <arch_interrupt.h>
#include <board.h>
#include <encoding.h>
#include <platform.h>
#include <plic_driver.h>
#include <xs_assign.h>
#include <xs_base.h>
#include <xs_isr.h>
#include <xs_ktask.h>
#ifdef TASK_ISOLATION
#include <xs_isolation.h>
#include <xs_service.h>
#endif
#define MAX_HANDLERS PLIC_NUM_INTERRUPTS
extern plic_instance_t g_plic ;
x_base DisableLocalInterrupt()
{
x_base level;
asm volatile ("csrrci %0, mstatus, 8" : "=r"(level));
return level;
}
void EnableLocalInterrupt(x_base level)
{
asm volatile ("csrw mstatus, %0" :: "r"(level));
}
/**
* This function will mask a interrupt.
* @param vector the interrupt number
*/
int32_t ArchDisableHwIrq(int irq)
{
PLIC_disable_interrupt(&g_plic, irq);
return 0;
}
/**
* This function will un-mask a interrupt.
* @param vector the interrupt number
*/
int32_t ArchEnableHwIrq(int irq)
{
PLIC_enable_interrupt(&g_plic, irq);
PLIC_set_priority(&g_plic, irq, 1);
return 0;
}
uint32_t GetInterruptNumber(void)
{
return (uint32_t)PLIC_claim_interrupt(&g_plic);
}
void HwInterruptAck(uint32_t irq)
{
PLIC_complete_interrupt(&g_plic, irq);
}
/**
* This function will be call when external machine-level
* interrupt from PLIC occurred.
*/
uintptr_t HandleIrqMExt(uintptr_t cause, uintptr_t epc)
{
uint32_t irq;
/* get irq number */
irq = GetInterruptNumber();
/* get interrupt service routine */
isrManager.done->handleIrq(irq);
HwInterruptAck(irq);
}
extern int TickIsr(void);
#ifdef TASK_ISOLATION
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
{
int cause = mcause & MCAUSE_CAUSE ;
if (mcause & MCAUSE_INT) {
isrManager.done->incCounter();
switch (cause) {
case IRQ_M_EXT:
HandleIrqMExt(mcause, epc);
break;
case IRQ_M_TIMER:
CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK;
TickIsr();
break;
}
isrManager.done->decCounter();
}else {
x_base temp;
temp = DISABLE_INTERRUPT();
KTaskDescriptorType tid;
extern long ShowTask();
tid = GetKTaskDescriptor();
if(cause == CAUSE_USER_ECALL) {
tid->task_dync_sched_member.isolation_status = 1;
sp[0] += 4;
unsigned long service_num = (unsigned long)(sp[10]);
//KPrintf("Environment call from U-mode,service_num: %ld\n",service_num);
uint8_t param_num = g_service_table[service_num].param_num;
uintptr_t *param = sp + 11;
ENABLE_INTERRUPT(temp);
sp[10] = g_service_table[service_num].fun(service_num,param,param_num) ;
tid->task_dync_sched_member.isolation_status = 0;
} else if( cause == CAUSE_MACHINE_ECALL) {
unsigned long service_num = (unsigned long)(sp[10]);
KPrintf("Environment call from M-mode, task:%s, flag: %d,service_num: %d\n \n",tid->task_base_info.name,tid->task_dync_sched_member.isolation_flag, service_num);
sp[0] += 4;
ENABLE_INTERRUPT(temp);
}
else if (cause == CAUSE_FAULT_LOAD || cause == CAUSE_FAULT_STORE || cause == CAUSE_FAULT_FETCH ){
if ( tid->task_dync_sched_member.isolation_flag == 1) {
x_ubase fault_addr = READ_CSR(mtval);
// KPrintf("access fault ,addr : 0x%08x\n",fault_addr);
x_bool result ;
result = mem_access.FaultHandle(tid->task_dync_sched_member.isolation , fault_addr);
if(result)
mem_access.Load(tid->task_dync_sched_member.isolation);
else{
KPrintf("\nSegmentation fault, task: %s\n",tid->task_base_info.name);
KTaskQuit();
}
}else
goto __print;
}
else
{
KPrintf("\nException:\n");
tid = GetKTaskDescriptor();
switch (cause)
{
case CAUSE_MISALIGNED_FETCH:
KPrintf("Instruction address misaligned");
break;
case CAUSE_FAULT_FETCH:
KPrintf("Instruction access fault");
break;
case CAUSE_ILLEGAL_INSTRUCTION:
KPrintf("Illegal instruction");
break;
case CAUSE_BREAKPOINT:
KPrintf("Breakpoint");
break;
case CAUSE_MISALIGNED_LOAD:
KPrintf("Load address misaligned");
break;
case CAUSE_FAULT_LOAD:
KPrintf("Load access fault");
break;
case CAUSE_MISALIGNED_STORE:
KPrintf("Store address misaligned");
break;
case CAUSE_FAULT_STORE:
KPrintf("Store access fault");
break;
case CAUSE_SUPERVISOR_ECALL:
KPrintf("Environment call from S-mode");
break;
case CAUSE_HYPERVISOR_ECALL:
KPrintf("Environment call from H-mode");
break;
default:
KPrintf("Uknown exception : %08lX", cause);
break;
}
__print:
KPrintf("\n");
//PrintStackFrame(sp);
KPrintf("exception pc => 0x%08x\n", epc);
KPrintf("current thread: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
while(RET_TRUE);
}
}
return epc;
}
#else
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
{
int cause = mcause & MCAUSE_CAUSE ;
if (mcause & MCAUSE_INT)
{
isrManager.done->incCounter();
switch (cause)
{
case IRQ_M_EXT:
HandleIrqMExt(mcause, epc);
break;
case IRQ_M_TIMER:
CLINT_MTIMECMP_ADDR = CLINT_MTIME_ADDR + TICK;
TickIsr();
break;
}
isrManager.done->decCounter();
}
else
{
KTaskDescriptorType tid;
extern long ShowTask();
DISABLE_INTERRUPT();
tid = GetKTaskDescriptor();
KPrintf("\nException:\n");
switch (cause)
{
case CAUSE_MISALIGNED_FETCH:
KPrintf("Instruction address misaligned");
break;
case CAUSE_FAULT_FETCH:
KPrintf("Instruction access fault");
break;
case CAUSE_ILLEGAL_INSTRUCTION:
KPrintf("Illegal instruction");
break;
case CAUSE_BREAKPOINT:
KPrintf("Breakpoint");
break;
case CAUSE_MISALIGNED_LOAD:
KPrintf("Load address misaligned");
break;
case CAUSE_FAULT_LOAD:
KPrintf("Load access fault");
break;
case CAUSE_MISALIGNED_STORE:
KPrintf("Store address misaligned");
break;
case CAUSE_FAULT_STORE:
KPrintf("Store access fault");
break;
case CAUSE_SUPERVISOR_ECALL:
KPrintf("Environment call from S-mode");
break;
case CAUSE_HYPERVISOR_ECALL:
KPrintf("Environment call from H-mode");
break;
default:
KPrintf("Uknown exception : %08lX", cause);
break;
}
KPrintf("\n");
//PrintStackFrame(sp);
KPrintf("exception pc => 0x%08x\n", epc);
KPrintf("current thread: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
while (RET_TRUE);
}
return epc;
}
#endif
+23
View File
@@ -0,0 +1,23 @@
/*
* 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 <encoding.h>
#include <clint.h>
#include <xs_ktick.h>
static volatile unsigned long tick_cycles = 0;
int TickIsr(void)
{
TickAndTaskTimesliceUpdate();
return 0;
}
@@ -0,0 +1,7 @@
SRC_FILES := interrupt.c boot.S tick.c
ifeq ($(CONFIG_ARCH_SMP),y)
SRC_FILES += smp_support.c
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 <plic.h>
#define ARCH_MAX_IRQ_NUM IRQN_MAX
#define ARCH_IRQ_NUM_OFFSET 0
int32 ArchEnableHwIrq(uint32 irq_num);
int32 ArchDisableHwIrq(uint32 irq_num);
#endif
+113
View File
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/01 Bernard The first version
* 2018/12/27 Jesven Add SMP support
*/
/*************************************************
File name: boot.S
Description: K210 boot code
Others: take RT-Thread v4.0.2/libcpu/risc-v/k210/startup_gcc.S
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
*************************************************/
#include "boot.h"
#define MSTATUS_FS 0x00006000U
#define __STACKSIZE__ 4096
#define K210_CPU0_STACKTOP (__stack_tp0)
#define K210_CPU1_STACKTOP (__stack_tp1)
.globl _begin
.section ".start", "ax"
_begin:
j 1f
.word 0xdeadbeef
.align 3
.globl g_wake_up
g_wake_up:
.dword 1
.dword 0
1:
csrw mideleg, 0
csrw medeleg, 0
csrw mie, 0
csrw mip, 0
la t0, save_hw_context
csrw mtvec, t0
ZERO_X_REGISTERS
li t0, MSTATUS_FS
csrs mstatus, t0
#ifndef BSP_USING_QEMU
ZERO_F_REGISTERS
#endif
.option push
.option norelax
la gp, __global_pointer$
.option pop
csrr a0, mhartid
bnez a0, 1f
la sp, K210_CPU0_STACKTOP
j 2f
1:
la sp, K210_CPU1_STACKTOP
2:
j Kd233Start
.data
.globl cpu2_boot_flag
.align 3
cpu2_boot_flag:
.8byte 0
.section .text.entry
.align 2
.globl save_hw_context
save_hw_context:
SAVE_X_REGISTERS
mv fp, sp
csrr t0, mhartid
#ifdef TASK_ISOLATION
csrr a0, mcause
srli a0, a0, 63
andi a0, a0, 0x1
beqz a0, 1f
#endif
la sp, __stack_start__
addi t1, t0, 1
li t2, __STACKSIZE__
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */
1:
csrr a0, mcause
csrr a1, mepc
mv a2, fp
call HandleTrap
mv sp, fp
mv a0, fp
call KTaskOsAssignAfterIrq
j SwitchKTaskContextExit
@@ -0,0 +1,423 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed 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 interrupt.c
* @brief support k210 interrupt configure
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-29
*/
/*************************************************
File name: interrupt.c
Description: support k210 interrupt configure
Others: take plic.c for references from Canaan k210 SDK
* https://canaan-creative.com/developer
History:
1. Date: 2021-04-29
Author: AIIT XUOS Lab
Modification:
1. support K210 interrupt configure
*************************************************/
#include "tick.h"
#include <clint.h>
#include <interrupt.h>
#include <plic.h>
#include <xs_assign.h>
#include <xs_base.h>
#include <xs_isr.h>
#include <xs_ktask.h>
#ifdef TASK_ISOLATION
#include <xs_service.h>
#endif
#define CPU_NUM 2
x_base DisableLocalInterrupt()
{
x_base level;
asm volatile ("csrrci %0, mstatus, 8" : "=r"(level));
return level;
}
void EnableLocalInterrupt(x_base level)
{
asm volatile ("csrw mstatus, %0" :: "r"(level));
}
int EnableHwclintIpi(void)
{
SET_CSR(mie, MIP_MSIP);
return 0;
}
int DisableHwclintIpi(void)
{
CLEAR_CSR(mie, MIP_MSIP);
return 0;
}
int EnableHwplicIrq(plic_irq_t irq_number)
{
unsigned long core_id = 0;
if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number)
return -1;
uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32];
current |= (uint32_t)1 << (irq_number % 32);
plic->target_enables.target[core_id].enable[irq_number / 32] = current;
return 0;
}
int DisableHwplicIrq(plic_irq_t irq_number)
{
unsigned long core_id = 0;
if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number)
return -1;
uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32];
current &= ~((uint32_t)1 << (irq_number % 32));
plic->target_enables.target[core_id].enable[irq_number / 32] = current;
return 0;
}
void InitHwinterrupt(void)
{
int idx;
int cpuid;
cpuid = current_coreid();
for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++)
plic->target_enables.target[cpuid].enable[idx] = 0;
for (idx = 0; idx < PLIC_NUM_SOURCES; idx++)
plic->source_priorities.priority[idx] = 0;
plic->targets.target[cpuid].priority_threshold = 0;
SET_CSR(mie, MIP_MEIP);
}
void InitHwScondaryInterrupt(void)
{
int idx;
int cpuid;
cpuid = current_coreid();
for (idx = 0; idx < ((PLIC_NUM_SOURCES + 32u) / 32u); idx ++)
plic->target_enables.target[cpuid].enable[idx] = 0;
plic->targets.target[cpuid].priority_threshold = 0;
SET_CSR(mie, MIP_MEIP);
}
int32 ArchEnableHwIrq(uint32 irq_num)
{
plic_set_priority(irq_num, 1);
EnableHwplicIrq(irq_num);
}
int32 ArchDisableHwIrq(uint32 irq_num)
{
DisableHwplicIrq(irq_num);
}
__attribute__((weak))
void PlicIrqHandle(plic_irq_t irq)
{
KPrintf("UN-handled interrupt %d occurred!!!\n", irq);
return ;
}
uintptr_t HandleIrqMExt(uintptr_t cause, uintptr_t epc)
{
if (READ_CSR(mip) & MIP_MEIP) {
uint64_t core_id = current_coreid();
uint64_t ie_flag = READ_CSR(mie);
uint32_t int_num = plic->targets.target[core_id].claim_complete;
uint32_t int_threshold = plic->targets.target[core_id].priority_threshold;
plic->targets.target[core_id].priority_threshold = plic->source_priorities.priority[int_num];
CLEAR_CSR(mie, MIP_MTIP | MIP_MSIP);
isrManager.done->handleIrq(int_num);
plic->targets.target[core_id].claim_complete = int_num;
SET_CSR(mstatus, MSTATUS_MPIE | MSTATUS_MPP);
WRITE_CSR(mie, ie_flag);
plic->targets.target[core_id].priority_threshold = int_threshold;
}
return epc;
}
struct ExceptionStackFrame
{
uint64_t x1;
uint64_t x2;
uint64_t x3;
uint64_t x4;
uint64_t x5;
uint64_t x6;
uint64_t x7;
uint64_t x8;
uint64_t x9;
uint64_t x10;
uint64_t x11;
uint64_t x12;
uint64_t x13;
uint64_t x14;
uint64_t x15;
uint64_t x16;
uint64_t x17;
uint64_t x18;
uint64_t x19;
uint64_t x20;
uint64_t x21;
uint64_t x22;
uint64_t x23;
uint64_t x24;
uint64_t x25;
uint64_t x26;
uint64_t x27;
uint64_t x28;
uint64_t x29;
uint64_t x30;
uint64_t x31;
};
void PrintStackFrame(uintptr_t * sp)
{
struct ExceptionStackFrame * esf = (struct ExceptionStackFrame *)(sp+1);
KPrintf("\n=================================================================\n");
KPrintf("x1 (ra : Return address ) ==> 0x%08x%08x\n", esf->x1 >> 32 , esf->x1 & UINT32_MAX);
KPrintf("x2 (sp : Stack pointer ) ==> 0x%08x%08x\n", esf->x2 >> 32 , esf->x2 & UINT32_MAX);
KPrintf("x3 (gp : Global pointer ) ==> 0x%08x%08x\n", esf->x3 >> 32 , esf->x3 & UINT32_MAX);
KPrintf("x4 (tp : Task pointer ) ==> 0x%08x%08x\n", esf->x4 >> 32 , esf->x4 & UINT32_MAX);
KPrintf("x5 (t0 : Temporary ) ==> 0x%08x%08x\n", esf->x5 >> 32 , esf->x5 & UINT32_MAX);
KPrintf("x6 (t1 : Temporary ) ==> 0x%08x%08x\n", esf->x6 >> 32 , esf->x6 & UINT32_MAX);
KPrintf("x7 (t2 : Temporary ) ==> 0x%08x%08x\n", esf->x7 >> 32 , esf->x7 & UINT32_MAX);
KPrintf("x8 (s0/fp: Save register,frame pointer ) ==> 0x%08x%08x\n", esf->x8 >> 32 , esf->x8 & UINT32_MAX);
KPrintf("x9 (s1 : Save register ) ==> 0x%08x%08x\n", esf->x9 >> 32 , esf->x9 & UINT32_MAX);
KPrintf("x10(a0 : Function argument,return value) ==> 0x%08x%08x\n", esf->x10 >> 32 , esf->x10 & UINT32_MAX);
KPrintf("x11(a1 : Function argument,return value) ==> 0x%08x%08x\n", esf->x11 >> 32 , esf->x11 & UINT32_MAX);
KPrintf("x12(a2 : Function argument ) ==> 0x%08x%08x\n", esf->x12 >> 32 , esf->x12 & UINT32_MAX);
KPrintf("x13(a3 : Function argument ) ==> 0x%08x%08x\n", esf->x13 >> 32 , esf->x13 & UINT32_MAX);
KPrintf("x14(a4 : Function argument ) ==> 0x%08x%08x\n", esf->x14 >> 32 , esf->x14 & UINT32_MAX);
KPrintf("x15(a5 : Function argument ) ==> 0x%08x%08x\n", esf->x15 >> 32 , esf->x15 & UINT32_MAX);
KPrintf("x16(a6 : Function argument ) ==> 0x%08x%08x\n", esf->x16 >> 32 , esf->x16 & UINT32_MAX);
KPrintf("x17(a7 : Function argument ) ==> 0x%08x%08x\n", esf->x17 >> 32 , esf->x17 & UINT32_MAX);
KPrintf("x18(s2 : Save register ) ==> 0x%08x%08x\n", esf->x18 >> 32 , esf->x18 & UINT32_MAX);
KPrintf("x19(s3 : Save register ) ==> 0x%08x%08x\n", esf->x19 >> 32 , esf->x19 & UINT32_MAX);
KPrintf("x20(s4 : Save register ) ==> 0x%08x%08x\n", esf->x20 >> 32 , esf->x20 & UINT32_MAX);
KPrintf("x21(s5 : Save register ) ==> 0x%08x%08x\n", esf->x21 >> 32 , esf->x21 & UINT32_MAX);
KPrintf("x22(s6 : Save register ) ==> 0x%08x%08x\n", esf->x22 >> 32 , esf->x22 & UINT32_MAX);
KPrintf("x23(s7 : Save register ) ==> 0x%08x%08x\n", esf->x23 >> 32 , esf->x23 & UINT32_MAX);
KPrintf("x24(s8 : Save register ) ==> 0x%08x%08x\n", esf->x24 >> 32 , esf->x24 & UINT32_MAX);
KPrintf("x25(s9 : Save register ) ==> 0x%08x%08x\n", esf->x25 >> 32 , esf->x25 & UINT32_MAX);
KPrintf("x26(s10 : Save register ) ==> 0x%08x%08x\n", esf->x26 >> 32 , esf->x26 & UINT32_MAX);
KPrintf("x27(s11 : Save register ) ==> 0x%08x%08x\n", esf->x27 >> 32 , esf->x27 & UINT32_MAX);
KPrintf("x28(t3 : Temporary ) ==> 0x%08x%08x\n", esf->x28 >> 32 , esf->x28 & UINT32_MAX);
KPrintf("x29(t4 : Temporary ) ==> 0x%08x%08x\n", esf->x29 >> 32 , esf->x29 & UINT32_MAX);
KPrintf("x30(t5 : Temporary ) ==> 0x%08x%08x\n", esf->x30 >> 32 , esf->x30 & UINT32_MAX);
KPrintf("x31(t6 : Temporary ) ==> 0x%08x%08x\n", esf->x31 >> 32 , esf->x31 & UINT32_MAX);
KPrintf("=================================================================\n");
}
#ifdef TASK_ISOLATION
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
{
int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK;
if (mcause & (1UL << 63)) {
isrManager.done->incCounter();
switch (cause) {
case IRQ_M_SOFT: {
uint64_t core_id = current_coreid();
clint_ipi_clear(core_id);
DO_KTASK_ASSIGN;
}
break;
case IRQ_M_EXT:
HandleIrqMExt(mcause, epc);
break;
case IRQ_M_TIMER:
TickIsr();
break;
}
isrManager.done->decCounter();
} else {
x_base temp;
temp = DISABLE_INTERRUPT();
KTaskDescriptorType tid;
extern long ShowTask();
tid = GetKTaskDescriptor();
if(cause == CAUSE_USER_ECALL) {
tid->task_dync_sched_member.isolation_status = 1;
sp[0] += 4;
unsigned long service_num = (unsigned long)(sp[10]);
//KPrintf("Environment call from U-mode,service_num: %ld\n",service_num);
uint8_t param_num = g_service_table[service_num].param_num;
uintptr_t *param = sp + 11;
ENABLE_INTERRUPT(temp);
sp[10] = g_service_table[service_num].fun(service_num,param,param_num) ;
tid->task_dync_sched_member.isolation_status = 0;
} else if (cause == CAUSE_MACHINE_ECALL) {
unsigned long service_num = (unsigned long)(sp[10]);
KPrintf("Environment call from M-mode, task:%s, flag: %d,service_num: %d\n \n",tid->task_base_info.name,tid->task_dync_sched_member.isolation_flag, service_num);
sp[0] += 4;
ENABLE_INTERRUPT(temp);
} else {
KPrintf("\nException:\n");
tid = GetKTaskDescriptor();
switch (cause) {
case CAUSE_MISALIGNED_FETCH:
KPrintf("Instruction address misaligned");
break;
case CAUSE_FAULT_FETCH:
KPrintf("Instruction access fault");
break;
case CAUSE_ILLEGAL_INSTRUCTION:
KPrintf("Illegal instruction");
break;
case CAUSE_BREAKPOINT:
KPrintf("Breakpoint");
break;
case CAUSE_MISALIGNED_LOAD:
KPrintf("Load address misaligned");
break;
case CAUSE_FAULT_LOAD:
KPrintf("Load access fault");
break;
case CAUSE_MISALIGNED_STORE:
KPrintf("Store address misaligned");
break;
case CAUSE_FAULT_STORE:
KPrintf("Store access fault");
break;
case CAUSE_SUPERVISOR_ECALL:
KPrintf("Environment call from S-mode");
break;
case CAUSE_HYPERVISOR_ECALL:
KPrintf("Environment call from H-mode");
break;
default:
KPrintf("Uknown exception : %08lX", cause);
break;
}
KPrintf("\n");
PrintStackFrame(sp);
KPrintf("exception pc => 0x%08x\n", epc);
KPrintf("current thread: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
while (RET_TRUE);
}
}
return epc;
}
#else
uintptr_t HandleTrap(uintptr_t mcause, uintptr_t epc, uintptr_t * sp)
{
int cause = mcause & CAUSE_MACHINE_IRQ_REASON_MASK;
if (mcause & (1UL << 63)) {
isrManager.done->incCounter();
switch (cause) {
case IRQ_M_SOFT: {
uint64_t core_id = current_coreid();
clint_ipi_clear(core_id);
DO_KTASK_ASSIGN;
}
break;
case IRQ_M_EXT:
HandleIrqMExt(mcause, epc);
break;
case IRQ_M_TIMER:
TickIsr();
break;
}
isrManager.done->decCounter();
} else {
KTaskDescriptorType tid;
extern long ShowTask();
DISABLE_INTERRUPT();
tid = GetKTaskDescriptor();
KPrintf("\nException:\n");
switch (cause) {
case CAUSE_MISALIGNED_FETCH:
KPrintf("Instruction address misaligned");
break;
case CAUSE_FAULT_FETCH:
KPrintf("Instruction access fault");
break;
case CAUSE_ILLEGAL_INSTRUCTION:
KPrintf("Illegal instruction");
break;
case CAUSE_BREAKPOINT:
KPrintf("Breakpoint");
break;
case CAUSE_MISALIGNED_LOAD:
KPrintf("Load address misaligned");
break;
case CAUSE_FAULT_LOAD:
KPrintf("Load access fault");
break;
case CAUSE_MISALIGNED_STORE:
KPrintf("Store address misaligned");
break;
case CAUSE_FAULT_STORE:
KPrintf("Store access fault");
break;
case CAUSE_USER_ECALL:
KPrintf("Environment call from U-mode");
break;
case CAUSE_SUPERVISOR_ECALL:
KPrintf("Environment call from S-mode");
break;
case CAUSE_HYPERVISOR_ECALL:
KPrintf("Environment call from H-mode");
break;
case CAUSE_MACHINE_ECALL:
KPrintf("Environment call from M-mode");
break;
default:
KPrintf("Uknown exception : %08lX", cause);
break;
}
KPrintf("\n");
PrintStackFrame(sp);
KPrintf("exception pc => 0x%08x\n", epc);
KPrintf("current task: %.*s\n", NAME_NUM_MAX, tid->task_base_info.name);
#ifdef TOOL_SHELL
ShowTask();
#endif
while (RET_TRUE);
}
return epc;
}
#endif
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/12/23 Bernard The first version
* 2018/12/27 Jesven Add secondary cpu boot
*/
/*************************************************
File name: smp_support.c
Description: SMP support routines
Others: take RT-Thread v4.0.2/libcpu/risc-v/k210/cpuport_smp.c
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
*************************************************/
#include "board.h"
#include <atomic.h>
#include <clint.h>
#include <encoding.h>
#include <xs_spinlock.h>
#include <stdint.h>
#include <xs_assign.h>
void HwSendIpi(int ipi_vector, unsigned int cpu_mask)
{
int idx;
for (idx = 0; idx < CPU_NUMBERS; idx ++)
if (cpu_mask & (1 << idx))
clint_ipi_send(idx);
}
int GetCpuId(void)
{
return READ_CSR(mhartid);
}
void InitHwSpinlock(HwSpinlock *lock)
{
((spinlock_t *)lock)->lock = 0;
}
void HwLockSpinlock(HwSpinlock *lock)
{
spinlock_lock((spinlock_t *)lock);
}
void HwUnlockSpinlock(HwSpinlock *lock)
{
spinlock_unlock((spinlock_t *)lock);
}
extern uint64 cpu2_boot_flag;
void StartupSecondaryCpu(void)
{
mb();
cpu2_boot_flag = 0x2018050420191010;
}
extern void InitHwScondaryInterrupt(void);
extern int InitHwTick(void);
extern int EnableHwclintIpi(void);
void SecondaryCpuCStart(void)
{
HwLockSpinlock(&AssignSpinLock);
InitHwScondaryInterrupt();
InitHwTick();
EnableHwclintIpi();
StartupOsAssign();
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/28 Bernard The unify RISC-V porting code.
*/
/*************************************************
File name: tick.c
Description: system tick interrupt related routines
Others: take RT-Thread v4.0.2/libcpu/risc-v/k210/tick.c
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
*************************************************/
#include <clint.h>
#include <encoding.h>
#include <sysctl.h>
#include <xs_ktick.h>
static volatile unsigned long tick_cycles = 0;
int TickIsr(void)
{
uint64_t core_id = current_coreid();
clint->mtimecmp[core_id] += tick_cycles;
TickAndTaskTimesliceUpdate();
return 0;
}
int InitHwTick(void)
{
unsigned long core_id = current_coreid();
unsigned long interval = 1000 / TICK_PER_SECOND;
CLEAR_CSR(mie, MIP_MTIP);
#ifdef BSP_USING_QEMU
tick_cycles = (10000000 / TICK_PER_SECOND);
#else
tick_cycles = interval * SysctlClockGetFreq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1;
#endif
clint->mtimecmp[core_id] = clint->mtime + tick_cycles;
SET_CSR(mie, MIP_MTIP);
return 0;
}
+19
View File
@@ -0,0 +1,19 @@
/*
* 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 TICK_H__
#define TICK_H__
int TickIsr(void);
int InitHwTick(void);
#endif
@@ -0,0 +1,9 @@
SRC_FILES +=riscv64_switch.c
SRC_FILES +=prepare_rhwstack.c
ifeq ($(CONFIG_TASK_ISOLATION),y)
SRC_FILES += pmp.c
endif
include $(KERNEL_ROOT)/compiler.mk
+126
View File
@@ -0,0 +1,126 @@
/*
* 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 "register_para.h"
.macro ZERO_X_REGISTERS
xor zero, zero, zero
xor ra, ra, ra
xor sp, sp, sp
xor gp, gp, gp
xor tp, tp, tp
xor t0, t0, t0
xor t1, t1, t1
xor t2, t2, t2
xor s0, s0, s0
xor s1, s1, s1
xor a0, a0, a0
xor a1, a1, a1
xor a2, a2, a2
xor a3, a3, a3
xor a4, a4, a4
xor a5, a5, a5
xor a6, a6, a6
xor a7, a7, a7
xor s2, s2, s2
xor s3, s3, s3
xor s4, s4, s4
xor s5, s5, s5
xor s6, s6, s6
xor s7, s7, s7
xor s8, s8, s8
xor s9, s9, s9
xor s10, s10, s10
xor s11, s11, s11
xor t3, t3, t3
xor t4, t4, t4
xor t5, t5, t5
xor t6, t6, t6
.endm
.macro ZERO_F_REGISTERS
FSubDS f0, f0, f0
FSubDS f1, f1, f1
FSubDS f2, f2, f2
FSubDS f3, f3, f3
FSubDS f4, f4, f4
FSubDS f5, f5, f5
FSubDS f6, f6, f6
FSubDS f7, f7, f7
FSubDS f8, f8, f8
FSubDS f9, f9, f9
FSubDS f10,f10,f10
FSubDS f11,f11,f11
FSubDS f12,f12,f12
FSubDS f13,f13,f13
FSubDS f14,f14,f14
FSubDS f15,f15,f15
FSubDS f16,f16,f16
FSubDS f17,f17,f17
FSubDS f18,f18,f18
FSubDS f19,f19,f19
FSubDS f20,f20,f20
FSubDS f21,f21,f21
FSubDS f22,f22,f22
FSubDS f23,f23,f23
FSubDS f24,f24,f24
FSubDS f25,f25,f25
FSubDS f26,f26,f26
FSubDS f27,f27,f27
FSubDS f28,f28,f28
FSubDS f29,f29,f29
FSubDS f30,f30,f30
FSubDS f31,f31,f31
.endm
.macro SAVE_X_REGISTERS
addi sp, sp, -32 * RegLength
StoreD ra, 1 * RegLength(sp)
csrr ra, mstatus
StoreD ra, 2 * RegLength(sp)
csrr ra, mepc
StoreD ra, 0 * RegLength(sp)
StoreD tp, 4 * RegLength(sp)
StoreD t0, 5 * RegLength(sp)
StoreD t1, 6 * RegLength(sp)
StoreD t2, 7 * RegLength(sp)
StoreD s0, 8 * RegLength(sp)
StoreD s1, 9 * RegLength(sp)
StoreD a0, 10 * RegLength(sp)
StoreD a1, 11 * RegLength(sp)
StoreD a2, 12 * RegLength(sp)
StoreD a3, 13 * RegLength(sp)
StoreD a4, 14 * RegLength(sp)
StoreD a5, 15 * RegLength(sp)
StoreD a6, 16 * RegLength(sp)
StoreD a7, 17 * RegLength(sp)
StoreD s2, 18 * RegLength(sp)
StoreD s3, 19 * RegLength(sp)
StoreD s4, 20 * RegLength(sp)
StoreD s5, 21 * RegLength(sp)
StoreD s6, 22 * RegLength(sp)
StoreD s7, 23 * RegLength(sp)
StoreD s8, 24 * RegLength(sp)
StoreD s9, 25 * RegLength(sp)
StoreD s10, 26 * RegLength(sp)
StoreD s11, 27 * RegLength(sp)
StoreD t3, 28 * RegLength(sp)
StoreD t4, 29 * RegLength(sp)
StoreD t5, 30 * RegLength(sp)
StoreD t6, 31 * RegLength(sp)
.endm
@@ -0,0 +1,324 @@
/****************************************************************************
*
* 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: risc-v ecall function
Others: take incubator-nuttx arch/risc-v/include/rv64gc/syscall.h for references
https://github.com/apache/incubator-nuttx/tree/master/arch/risc-v/include/rv64gc
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_RISC_V_KSWITCH_H__
#define __XS_RISC_V_KSWITCH_H__
#include <stdint.h>
#include "../../../kernel/include/xs_service.h"
#ifdef TASK_ISOLATION
/****************************************************************************
* Name: KSwitch0
*
* Description:
* ecall with zero parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch0(unsigned int nbr)
{
register long r0 asm("a0") = (long)(nbr);
asm volatile
(
"ecall"
:: "r"(r0)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: KSwitch1
*
* Description:
* ecall with one parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch1(unsigned int nbr, uintptr_t parm1)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: KSwitch2
*
* Description:
* ecall with two parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch2(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: KSwitch3
*
* Description:
* ecall with three parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch3(unsigned int knum, uintptr_t arg1,
uintptr_t arg2, uintptr_t arg3)
{
register long reg0 asm("a0") = (long)(knum);
register long reg1 asm("a1") = (long)(arg1);
register long reg2 asm("a2") = (long)(arg2);
register long reg3 asm("a3") = (long)(arg3);
asm volatile
(
"ecall"
:: "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3)
);
asm volatile("nop" : "=r"(reg0));
return reg0;
}
/****************************************************************************
* Name: KSwitch4
*
* Description:
* ecall with four parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch4(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
register long r4 asm("a4") = (long)(parm4);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: KSwitch5
*
* Description:
* ecall with five parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch5(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
register long r4 asm("a4") = (long)(parm4);
register long r5 asm("a5") = (long)(parm5);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
/****************************************************************************
* Name: KSwitch6
*
* Description:
* ecall with six parameters.
*
****************************************************************************/
static inline uintptr_t KSwitch6(unsigned int nbr, uintptr_t parm1,
uintptr_t parm2, uintptr_t parm3,
uintptr_t parm4, uintptr_t parm5,
uintptr_t parm6)
{
register long r0 asm("a0") = (long)(nbr);
register long r1 asm("a1") = (long)(parm1);
register long r2 asm("a2") = (long)(parm2);
register long r3 asm("a3") = (long)(parm3);
register long r4 asm("a4") = (long)(parm4);
register long r5 asm("a5") = (long)(parm5);
register long r6 asm("a6") = (long)(parm6);
asm volatile
(
"ecall"
:: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6)
);
asm volatile("nop" : "=r"(r0));
return r0;
}
#else
static inline unsigned long KSwitch0(unsigned int knum)
{
uintptr_t param[1] = {0};
uint8_t num = 0;
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 = 0;
param[0] = arg1;
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 = 0;
param[0] = arg1;
param[1] = arg2;
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 = 0;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
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 = 0;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
param[3] = arg4;
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 = 0;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
param[3] = arg4;
param[4] = arg5;
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 = 0;
param[0] = arg1;
param[1] = arg2;
param[2] = arg3;
param[3] = arg4;
param[4] = arg5;
param[5] = arg6;
SERVICETABLE[knum].fun(knum, param, num );
}
#endif
#endif
+517
View File
@@ -0,0 +1,517 @@
/*
* 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 "pmp.h"
#include <board.h>
#include <encoding.h>
#include <xs_isolation.h>
#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)( USERSPACE->us_bssend )
/**
* This function add a pmp tor region to task pmp config
*
* @param task_pmp the task pmp config structure
* @param start the memory start address
* @param size the memory address size
* @param type the memory type
*
* @return EOK
*/
x_err_t PmpAddTorRegion(void *task_pmp, x_ubase start , size_t size , uint8_t type )
{
if( task_pmp == NONE)
return -ERROR;
if (size == 0)
return EOK;
struct Pmp *pmp;
pmp = (struct Pmp *)task_pmp ;
struct PmpRegionTor *region ;
region = (struct PmpRegionTor *)x_malloc(sizeof(struct PmpRegionTor ));
if (region == NONE)
return -ENOMEM;
uint8_t flag = 0;
switch (type)
{
case REGION_TYPE_CODE:
flag = PMP_R | PMP_X ;
break;
case REGION_TYPE_DATA :
flag = PMP_R | PMP_W ;
break;
case REGION_TYPE_BSS :
flag = PMP_R | PMP_W ;
break;
case REGION_TYPE_HEAP :
flag = PMP_R | PMP_W ;
break;
default:
break;
}
memset(region,0,sizeof(struct PmpRegionTor ));
InitDoubleLinkList(&(region->link));
region->region_type = PMP_TOR_TYPE;
region->start = start;
region->end = start + size ;
region->entry[0].pmpcfg = PMP_NA4 | flag;
region->entry[0].pmpaddr = TO_PMP_ADDR(start);
region->entry[1].pmpcfg = PMP_TOR | flag;
region->entry[1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP(region->end,4));
if (pmp->count <= PMP_MAX_ENTRY_NUMBER - 2 )
{
DoubleLinkListInsertNodeAfter(&pmp->tor_list, &region->link);
pmp->count = pmp->count + 2 ;
}else
{
struct PmpRegionTor *node ;
node = (struct PmpRegionTor *)pmp->tor_list.node_next ;
DoubleLinkListRmNode(&(node->link));
DoubleLinkListInsertNodeAfter(&pmp->tor_list, &region->link);
DoubleLinkListInsertNodeAfter(&pmp->tor_swap_list, &node->link);
node->swap_count ++;
}
return EOK;
}
/**
* This function free a pmp region
*
* @param task_pmp the task pmp config structure
* @param addr the memory address
*
* @return EOK
*/
x_err_t PmpClearRegion(void *task_pmp, x_ubase addr)
{
// KPrintf("PmpClearRegion\n");
if( task_pmp == NONE)
return -ERROR;
struct Pmp *pmp;
pmp = (struct Pmp *)task_pmp ;
struct PmpRegionTor *tor_node = NONE;
DoubleLinklistType *link = NONE;
if (!IsDoubleLinkListEmpty(&pmp->tor_list)) {
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list) {
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
if ( addr = tor_node->start ){
pmp->count = pmp->count -2;
goto __free ;
}
}
}
if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list)) {
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) {
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
if ( addr = tor_node->start ) {
goto __free;
}
}
}
__free:
DoubleLinkListRmNode(&(tor_node->link));
x_free(tor_node);
return EOK;
}
/**
* This function init a task pmp config structure and add some pmp region
*
* @param task_pmp the task pmp config structure
* @param stack_start the task stack address
* @param stack_size the task stack size
*
* @return EOK
*/
x_err_t PmpInitIsolation(void **task_pmp, x_ubase stack_start , size_t stack_size)
{
struct Pmp *pmp ;
pmp = (struct Pmp *)x_malloc(sizeof(struct Pmp));
if(pmp == NONE)
return -ENOMEMORY;
memset(pmp,0,sizeof(struct Pmp));
InitDoubleLinkList(&(pmp->tor_list));
InitDoubleLinkList(&(pmp->tor_swap_list));
uint8_t index = 0;
// text
if (USER_TEXT_END - USER_TEXT_START > 0 ) {
pmp->pmp_entry_reserve[index].pmpcfg = PMP_NA4 | PMP_R | PMP_X ;
pmp->pmp_entry_reserve[index].pmpaddr = TO_PMP_ADDR(USER_TEXT_START);
pmp->pmp_entry_reserve[index + 1].pmpcfg = PMP_TOR | PMP_R | PMP_X ;
pmp->pmp_entry_reserve[index + 1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP(USER_TEXT_END,4));
index = index + 2 ;
pmp->count = pmp->count + 2;
pmp->reserve = pmp->reserve + 2;
}
// data & bss
if (USER_SRAM_END - USER_SRAM_START > 0 ) {
pmp->pmp_entry_reserve[index].pmpcfg = PMP_NA4 | PMP_R | PMP_W ;
pmp->pmp_entry_reserve[index].pmpaddr = TO_PMP_ADDR(USER_SRAM_START);
pmp->pmp_entry_reserve[index + 1].pmpcfg = PMP_TOR | PMP_R | PMP_W ;
pmp->pmp_entry_reserve[index + 1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP(USER_SRAM_END,4));
index = index + 2 ;
pmp->count = pmp->count + 2;
pmp->reserve = pmp->reserve + 2;
}
if (stack_size > 0 ) {
pmp->pmp_entry_reserve[index].pmpcfg = PMP_NA4 | PMP_R | PMP_W | PMP_X ;
pmp->pmp_entry_reserve[index].pmpaddr = TO_PMP_ADDR(stack_start);
pmp->pmp_entry_reserve[index + 1].pmpcfg = PMP_TOR | PMP_R | PMP_W | PMP_X ;
pmp->pmp_entry_reserve[index + 1].pmpaddr = TO_PMP_ADDR(ALIGN_MEN_UP((stack_start + stack_size),4));
pmp->count = pmp->count + 2;
pmp->reserve = pmp->reserve + 2;
}
*task_pmp = (void *)pmp;
return EOK;
}
/**
* This function free task pmp config structure
*
* @param task_pmp the task pmp config structure
*
*/
void PmpFree(void *task_pmp){
// KPrintf("pmp free \n");
if( task_pmp == NONE)
return ;
struct Pmp *pmp;
pmp = (struct Pmp *)task_pmp ;
struct PmpRegionTor *tor_node = NONE;
DoubleLinklistType *link = NONE;
if (!IsDoubleLinkListEmpty(&(pmp->tor_list)) ){
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list)
{
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
DoubleLinkListRmNode(&(tor_node->link));
x_free(tor_node);
}
}
if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list)) {
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) {
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
DoubleLinkListRmNode(&(tor_node->link));
x_free(tor_node);
}
}
x_free(pmp);
}
/**
* This function write value to pmp config register
* @param index pmpcfg register index
* @param value pmpcfg register value
*
*/
void WritePmpcfg(uint8_t index , x_ubase value)
{
if ( index == 0 ) {
WRITE_CSR(pmpcfg0, value);
}else if ( index == 1 ) {
WRITE_CSR(pmpcfg1, value);
}else if ( index == 2 ) {
WRITE_CSR(pmpcfg2, value);
}else if ( index == 3 ) {
WRITE_CSR(pmpcfg3, value);
}
}
/**
* This function write value to pmp addr register
* @param index pmpaddr register index
* @param value pmpaddr register value
*
*/
void WritePmpaddr(uint8_t index, x_ubase value)
{
if ( index == 0 ) {
WRITE_CSR(pmpaddr0, value);
}else if ( index == 1 ) {
WRITE_CSR(pmpaddr1, value);
}else if ( index == 2 ) {
WRITE_CSR(pmpaddr2, value);
}else if ( index == 3 ) {
WRITE_CSR(pmpaddr3, value);
}else if ( index == 4 ) {
WRITE_CSR(pmpaddr4, value);
}else if ( index == 5 ) {
WRITE_CSR(pmpaddr5, value);
}else if ( index == 6 ) {
WRITE_CSR(pmpaddr6, value);
}else if ( index == 7 ) {
WRITE_CSR(pmpaddr7, value);
}else if ( index == 8 ) {
WRITE_CSR(pmpaddr8, value);
}else if ( index == 9 ) {
WRITE_CSR(pmpaddr9, value);
}else if ( index == 10 ) {
WRITE_CSR(pmpaddr10, value);
}else if ( index == 11 ) {
WRITE_CSR(pmpaddr11, value);
}else if ( index == 12 ) {
WRITE_CSR(pmpaddr12, value);
}else if ( index == 13 ) {
WRITE_CSR(pmpaddr13, value);
}else if ( index == 14 ) {
WRITE_CSR(pmpaddr14, value);
}else if ( index == 15 ) {
WRITE_CSR(pmpaddr15, value);
}
}
/**
* This function handle user task access memory fault, check addr in pmp swap list or not ,if addr is in
* pmp swap list, swap in to pmp list.
*
* @param task_pmp the task pmp config structure
* @param addr access addr when fault
*
* @return EOK
*/
x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr)
{
if( task_pmp == NONE)
return RET_FALSE;
struct Pmp *pmp;
pmp = (struct Pmp *)task_pmp ;
x_bool ret = RET_FALSE;
uint8_t region_type;
DoubleLinklistType *link = NONE;
struct PmpRegionTor *tor_node = NONE;
if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list) ) {
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) {
tor_node = CONTAINER_OF(link, struct PmpRegionTor, link);
if ( addr >= tor_node->start && addr <= (tor_node->end) ) {
region_type = PMP_TOR;
goto __swap;
}
}
}
goto __exit;
__swap:
if ( region_type = PMP_TOR ) {
if( pmp->count < PMP_MAX_ENTRY_NUMBER - 2) {
DoubleLinkListRmNode(&(tor_node->link));
DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link);
pmp->count = pmp->count + 2;
} else {
struct PmpRegionTor *swap_node;
swap_node = (struct PmpRegionTor *)pmp->tor_list.node_next;
DoubleLinkListRmNode(&(swap_node->link));
DoubleLinkListRmNode(&(tor_node->link));
DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link);
DoubleLinkListInsertNodeBefore(&pmp->tor_swap_list, &swap_node->link);
swap_node->swap_count ++;
}
}
ret = RET_TRUE;
__exit:
return ret;
}
#if defined(ARCH_RISCV64)
/**
* This function clear pmp registers.
*/
void PmpClear(void)
{
WRITE_CSR(pmpcfg0, 0);
WRITE_CSR(pmpcfg2, 0);
WRITE_CSR(pmpaddr0, 0);
WRITE_CSR(pmpaddr1, 0);
WRITE_CSR(pmpaddr2, 0);
WRITE_CSR(pmpaddr3, 0);
WRITE_CSR(pmpaddr4, 0);
WRITE_CSR(pmpaddr5, 0);
WRITE_CSR(pmpaddr6, 0);
WRITE_CSR(pmpaddr7, 0);
WRITE_CSR(pmpaddr8, 0);
WRITE_CSR(pmpaddr9, 0);
WRITE_CSR(pmpaddr10, 0);
WRITE_CSR(pmpaddr11, 0);
WRITE_CSR(pmpaddr12, 0);
WRITE_CSR(pmpaddr13, 0);
WRITE_CSR(pmpaddr14, 0);
WRITE_CSR(pmpaddr15, 0);
}
/**
* This function load task pmp config to pmp register.
* @param task_pmp the task pmp config structure
*
*/
void PmpLoad(void *task_pmp)
{
// KPrintf("pmpLoad \n");
if( task_pmp == NONE)
return ;
struct Pmp *pmp;
pmp = (struct Pmp *)task_pmp ;
PmpClear();
uint8_t index = 0;
x_ubase pmpcfg0 = 0 ;
x_ubase pmpcfg2 = 0 ;
for( int i = 0 ; i < pmp->reserve; i++){
pmpcfg0 |= pmp->pmp_entry_reserve[i].pmpcfg << ( index * 8) ;
WritePmpaddr(index , pmp->pmp_entry_reserve[i].pmpaddr );
index ++ ;
}
DoubleLinklistType *link = NONE;
struct PmpRegionTor *node2 = NONE;
if (!IsDoubleLinkListEmpty(&pmp->tor_list) ){
DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list)
{
node2 = CONTAINER_OF(link, struct PmpRegionTor, link);
WritePmpaddr(index ,node2->entry[0].pmpaddr );
if (index < 8)
pmpcfg0 |= node2->entry[0].pmpcfg << ( index * 8);
else
pmpcfg2 |= node2->entry[0].pmpcfg << ( (index - 8) * 8);
index ++;
WritePmpaddr(index ,node2->entry[1].pmpaddr );
if (index < 8)
pmpcfg0 |= node2->entry[1].pmpcfg << ( index * 8);
else
pmpcfg2 |= node2->entry[1].pmpcfg << ( (index - 8) * 8);
index ++;
}
}
WritePmpcfg(0, pmpcfg0 );
WritePmpcfg(2, pmpcfg2 );
}
#else
/**
* This function clear pmp registers.
*/
void PmpClear(void)
{
WRITE_CSR(pmpcfg0, 0);
WRITE_CSR(pmpcfg1, 0);
WRITE_CSR(pmpcfg2, 0);
WRITE_CSR(pmpcfg3, 0);
WRITE_CSR(pmpaddr0, 0);
WRITE_CSR(pmpaddr1, 0);
WRITE_CSR(pmpaddr2, 0);
WRITE_CSR(pmpaddr3, 0);
WRITE_CSR(pmpaddr4, 0);
WRITE_CSR(pmpaddr5, 0);
WRITE_CSR(pmpaddr6, 0);
WRITE_CSR(pmpaddr7, 0);
WRITE_CSR(pmpaddr8, 0);
WRITE_CSR(pmpaddr9, 0);
WRITE_CSR(pmpaddr10, 0);
WRITE_CSR(pmpaddr11, 0);
WRITE_CSR(pmpaddr12, 0);
WRITE_CSR(pmpaddr13, 0);
WRITE_CSR(pmpaddr14, 0);
WRITE_CSR(pmpaddr15, 0);
}
#define PMP_CFG_CONVERSE(a,b,c,d) ( ((uint32_t)(d) << 24) | ((uint32_t)(c) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(a) )
/**
* This function load task pmp config to pmp register.
* @param task_pmp the task pmp config structure
*
*/
void PmpLoad(void *task_pmp)
{
// KPrintf("pmpLoad \n");
if( task_pmp == NONE)
return ;
struct Pmp *pmp;
pmp = (struct Pmp *)task_pmp ;
PmpClear();
uint8_t index = 0;
uint8_t pmpcfg[16] = { 0 } ;
uint32_t pmpcfg0 = 0 ;
uint32_t pmpcfg1 = 0 ;
uint32_t pmpcfg2 = 0 ;
uint32_t pmpcfg3 = 0 ;
for( int i = 0 ; i < pmp->reserve; i++){
pmpcfg[index] = pmp->pmp_entry_reserve[i].pmpcfg ;
WritePmpaddr(index , pmp->pmp_entry_reserve[i].pmpaddr );
index ++ ;
}
DoubleLinklistType *node = NONE;
struct PmpRegionTor *tor_node = NONE;
if (!IsDoubleLinkListEmpty(&(pmp->tor_list)) ){
DOUBLE_LINKLIST_FOR_EACH(node, &(pmp->tor_list))
{
tor_node = CONTAINER_OF(node, struct PmpRegionTor, link);
WritePmpaddr(index ,tor_node->entry[0].pmpaddr );
pmpcfg[index] = tor_node->entry[0].pmpcfg;
index ++;
WritePmpaddr(index ,tor_node->entry[1].pmpaddr );
pmpcfg[index] = tor_node->entry[1].pmpcfg;
index ++;
}
}
pmpcfg0 = PMP_CFG_CONVERSE(pmpcfg[0], pmpcfg[1], pmpcfg[2], pmpcfg[3]);
pmpcfg1 = PMP_CFG_CONVERSE(pmpcfg[4], pmpcfg[5], pmpcfg[6], pmpcfg[7]);
pmpcfg2 = PMP_CFG_CONVERSE(pmpcfg[8], pmpcfg[9], pmpcfg[10], pmpcfg[11]);
pmpcfg3 = PMP_CFG_CONVERSE(pmpcfg[12], pmpcfg[13], pmpcfg[14], pmpcfg[15]);
WritePmpcfg(0, pmpcfg0);
WritePmpcfg(1, pmpcfg1);
WritePmpcfg(2, pmpcfg2);
WritePmpcfg(3, pmpcfg3);
}
#endif
+93
View File
@@ -0,0 +1,93 @@
/*
* 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 PMP_H
#define PMP_H
#include <xs_klist.h>
#define PMP_MAX_ENTRY_NUMBER 16
#define PMP_ENTRY_RESERVE 6
#define PMP_ENTRY_MAX 255
#define PMP_R 0x01 /* Allow read */
#define PMP_W 0x02 /* Allow write */
#define PMP_X 0x04 /* Allow execute */
#define PMP_L 0x80 /* PMP entry is locked */
#define PMP_OFF 0x00 /* Null region */
#define PMP_TOR 0x08 /* Top of range */
#define PMP_NA4 0x10 /* Naturally aligned four-byte region */
#define PMP_NAPOT 0x18 /* Naturally aligned power-of-two region */
#define PMP_TOR_TYPE 0 /* Top of range */
#define PMP_NAPOT_TYPE 1 /* Naturally aligned power-of-two region */
#define PMP_SHIFT_ADDR 2
#define PMP_TYPE_MASK 0x18
#define TO_PMP_ADDR(addr) ((addr) >> PMP_SHIFT_ADDR)
#define FROM_PMP_ADDR(addr) ((addr) << PMP_SHIFT_ADDR)
#define TO_NAPOT_RANGE(size) (((size) - 1) >> 1)
#define TO_PMP_NAPOT(addr, size) TO_PMP_ADDR(addr | TO_NAPOT_RANGE(size))
struct PmpEntry
{
uint8_t pmpcfg;
#if defined(ARCH_RISCV64)
uint64_t pmpaddr;
#else
uint32_t pmpaddr;
#endif
};
struct PmpRegionNapot
{
x_ubase start ;
x_ubase end;
uint16_t swap_count;
uint8_t region_type;
struct PmpEntry entry;
DoubleLinklistType link;
};
struct PmpRegionTor
{
x_ubase start ;
x_ubase end;
uint16_t swap_count;
uint8_t region_type;
struct PmpEntry entry[2];
DoubleLinklistType link;
};
struct Pmp
{
uint8_t count;
uint8_t reserve;
struct PmpEntry pmp_entry_reserve[PMP_ENTRY_RESERVE];
DoubleLinklistType tor_list;
DoubleLinklistType tor_swap_list;
};
x_err_t PmpAddTorRegion(void *task_pmp, x_ubase start , size_t size , uint8_t flag );
x_err_t PmpInitIsolation(void **task_pmp, x_ubase stack_start , size_t stack_size);
void PmpFree(void *task_pmp);
void PmpClear(void);
x_err_t PmpClearRegion(void *task_pmp, x_ubase addr);
void PmpLoad(void *task_pmp);
x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr);
#endif
@@ -0,0 +1,113 @@
/*
* 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 "register_para.h"
#include <board.h>
#include <xs_base.h>
#include <xs_ktask.h>
#include <xs_isr.h>
#ifdef TASK_ISOLATION
#include "encoding.h"
#include <stdint.h>
#include <xs_isolation.h>
#endif
struct StackRegisterContext
{
x_ubase epc;
x_ubase ra;
x_ubase mstatus;
x_ubase gp;
x_ubase tp;
x_ubase t0;
x_ubase t1;
x_ubase t2;
x_ubase s0_fp;
x_ubase s1;
x_ubase a0;
x_ubase a1;
x_ubase a2;
x_ubase a3;
x_ubase a4;
x_ubase a5;
x_ubase a6;
x_ubase a7;
x_ubase s2;
x_ubase s3;
x_ubase s4;
x_ubase s5;
x_ubase s6;
x_ubase s7;
x_ubase s8;
x_ubase s9;
x_ubase s10;
x_ubase s11;
x_ubase t3;
x_ubase t4;
x_ubase t5;
x_ubase t6;
};
uint8 KTaskStackSetup(struct TaskDescriptor *task)
{
struct StackRegisterContext *stack_contex;
int i;
task->stack_point = (uint8 *)ALIGN_MEN_DOWN((x_ubase)(task->task_base_info.stack_start + task->task_base_info.stack_depth), RegLength);
task->stack_point -= sizeof(struct StackRegisterContext);
stack_contex = (struct StackRegisterContext *)task->stack_point;
for (i = 0; i < sizeof(struct StackRegisterContext) / sizeof(x_ubase); i++)
((x_ubase *)stack_contex)[i] = 0xfadeface;
#ifdef SEPARATE_COMPILE
if (task->task_dync_sched_member.isolation_flag == 1) {
stack_contex->ra = (unsigned long)USERSPACE->us_taskquit;
} else {
stack_contex->ra = (x_ubase)KTaskQuit;
}
#else
stack_contex->ra = (x_ubase)KTaskQuit;
#endif
stack_contex->a0 = (x_ubase)task->task_base_info.func_param;
stack_contex->epc = (x_ubase)task->task_base_info.func_entry;
#ifdef TASK_ISOLATION
stack_contex->tp = (x_ubase)task;
if(task->task_dync_sched_member.isolation_flag == 1)
stack_contex->mstatus = 0x00006080;
else
#endif
stack_contex->mstatus = 0x00007880;
return EOK;
}
#ifdef TASK_ISOLATION
void RestoreMstatus(uintptr_t *sp)
{
struct TaskDescriptor *tid;
tid = (struct TaskDescriptor *)(sp[4]);
if(tid->task_dync_sched_member.isolation_flag == 1 && tid->task_dync_sched_member.isolation_status == 0){
CLEAR_CSR(mstatus, (MSTATUS_MPP));
#ifdef MOMERY_PROTECT_ENABLE
mem_access.Load(tid->task_dync_sched_member.isolation);
#endif
}else{
SET_CSR(mstatus, MSTATUS_MPP);
}
}
#endif
@@ -0,0 +1,109 @@
/*
* 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 RISCV_PLIC_H__
#define RISCV_PLIC_H__
#ifndef PLIC_BASE_ADDR
#define PLIC_BASE_ADDR 0x0
#endif
#define PLIC_PRIORITY_OFFSET (0x00000000UL)
#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2
#define PLIC_PENDING_OFFSET (0x00001000UL)
#define PLIC_PENDING_SHIFT_PER_SOURCE 0
#define PLIC_ENABLE_OFFSET (0x00002000UL)
#define PLIC_ENABLE_SHIFT_PER_TARGET 7
#define PLIC_THRESHOLD_OFFSET (0x00200000UL)
#define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
#define PLIC_CLAIM_OFFSET (0x00200004UL)
#define PLIC_CLAIM_SHIFT_PER_TARGET 12
#if defined(__GNUC__) && !defined(__ASSEMBLER__)
__attribute__((always_inline)) static inline void PlicSetFeature(unsigned int feature)
{
volatile unsigned int *feature_ptr = (volatile unsigned int *)PLIC_BASE_ADDR;
*feature_ptr = feature;
}
__attribute__((always_inline)) static inline void PlicSetThreshold(unsigned int threshold)
{
unsigned int hart_id = READ_CSR(mhartid);
volatile unsigned int *threshold_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_THRESHOLD_OFFSET +
(hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
*threshold_ptr = threshold;
}
__attribute__((always_inline)) static inline void PlicSetPriority(unsigned int source, unsigned int priority)
{
volatile unsigned int *priority_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_PRIORITY_OFFSET +
(source << PLIC_PRIORITY_SHIFT_PER_SOURCE));
*priority_ptr = priority;
}
__attribute__((always_inline)) static inline void PlicSetPending(unsigned int source)
{
volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_PENDING_OFFSET +
((source >> 5) << 2));
*current_ptr = (1 << (source & 0x1F));
}
__attribute__((always_inline)) static inline void PlicIrqEnable(unsigned int source)
{
unsigned int hart_id = READ_CSR(mhartid);
volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_ENABLE_OFFSET +
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
((source >> 5) << 2));
unsigned int current = *current_ptr;
current = current | (1 << (source & 0x1F));
*current_ptr = current;
}
__attribute__((always_inline)) static inline void PlicIrqDisable(unsigned int source)
{
unsigned int hart_id = READ_CSR(mhartid);
volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_ENABLE_OFFSET +
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
((source >> 5) << 2));
unsigned int current = *current_ptr;
current = current & ~((1 << (source & 0x1F)));
*current_ptr = current;
}
__attribute__((always_inline)) static inline unsigned int PlicIrqClaim(void)
{
unsigned int hart_id = READ_CSR(mhartid);
volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_CLAIM_OFFSET +
(hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
return *claim_addr;
}
__attribute__((always_inline)) static inline void PlicIrqComplete(unsigned int source)
{
unsigned int hart_id = READ_CSR(mhartid);
volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR +
PLIC_CLAIM_OFFSET +
(hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
*claim_addr = source;
}
#endif
#endif
@@ -0,0 +1,43 @@
/*
* 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 RISCV_OPS_H__
#define RISCV_OPS_H__
#if defined(__GNUC__) && !defined(__ASSEMBLER__)
#define READ_CSR(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define WRITE_CSR(reg, val) ({ \
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
else \
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
#define SET_CSR(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define CLEAR_CSR(reg, bit) ({ unsigned long __tmp; \
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#endif
#endif
@@ -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 CPUPORT_H__
#define CPUPORT_H__
#include <xsconfig.h>
#ifdef ARCH_CPU_64BIT
#define StoreD sd
#define LoadD ld
#define FSubDS fsub.d
#define RegLength 8
#define StoreDS "sd"
#define LoadDS "ld"
#define RegLengthS "8"
#else
#define StoreD sw
#define LoadD lw
#define FSubDS fsub.s
#define RegLength 4
#define StoreDS "sw"
#define LoadDS "lw"
#define RegLengthS "4"
#endif
#endif
@@ -0,0 +1,134 @@
/*
* 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 "register_para.h"
#include <xs_base.h>
#include <xs_ktask.h>
void __attribute__((naked)) SwitchKTaskContextExit()
{
asm volatile (LoadDS " a0, 0 * " RegLengthS "(sp)");
asm volatile ("csrw mepc, a0");
#ifdef TASK_ISOLATION
asm volatile (LoadDS " a0, 2 * " RegLengthS "(sp)");
asm volatile ("csrw mstatus, a0");
asm volatile ("mv a0, sp");
asm volatile ("jal RestoreMstatus");
#else
asm volatile ("li t0, 0x00001800");
asm volatile ("csrw mstatus, t0");
asm volatile (LoadDS " a0, 2 * " RegLengthS "(sp)");
asm volatile ("csrs mstatus, a0");
#endif
asm volatile (LoadDS " ra, 1 * " RegLengthS "(sp)");
asm volatile (LoadDS " tp, 4 * " RegLengthS "(sp)");
asm volatile (LoadDS " t0, 5 * " RegLengthS "(sp)");
asm volatile (LoadDS " t1, 6 * " RegLengthS "(sp)");
asm volatile (LoadDS " t2, 7 * " RegLengthS "(sp)");
asm volatile (LoadDS " s0, 8 * " RegLengthS "(sp)");
asm volatile (LoadDS " s1, 9 * " RegLengthS "(sp)");
asm volatile (LoadDS " a0, 10 * " RegLengthS "(sp)");
asm volatile (LoadDS " a1, 11 * " RegLengthS "(sp)");
asm volatile (LoadDS " a2, 12 * " RegLengthS "(sp)");
asm volatile (LoadDS " a3, 13 * " RegLengthS "(sp)");
asm volatile (LoadDS " a4, 14 * " RegLengthS "(sp)");
asm volatile (LoadDS " a5, 15 * " RegLengthS "(sp)");
asm volatile (LoadDS " a6, 16 * " RegLengthS "(sp)");
asm volatile (LoadDS " a7, 17 * " RegLengthS "(sp)");
asm volatile (LoadDS " s2, 18 * " RegLengthS "(sp)");
asm volatile (LoadDS " s3, 19 * " RegLengthS "(sp)");
asm volatile (LoadDS " s4, 20 * " RegLengthS "(sp)");
asm volatile (LoadDS " s5, 21 * " RegLengthS "(sp)");
asm volatile (LoadDS " s6, 22 * " RegLengthS "(sp)");
asm volatile (LoadDS " s7, 23 * " RegLengthS "(sp)");
asm volatile (LoadDS " s8, 24 * " RegLengthS "(sp)");
asm volatile (LoadDS " s9, 25 * " RegLengthS "(sp)");
asm volatile (LoadDS " s10, 26 * " RegLengthS "(sp)");
asm volatile (LoadDS " s11, 27 * " RegLengthS "(sp)");
asm volatile (LoadDS " t3, 28 * " RegLengthS "(sp)");
asm volatile (LoadDS " t4, 29 * " RegLengthS "(sp)");
asm volatile (LoadDS " t5, 30 * " RegLengthS "(sp)");
asm volatile (LoadDS " t6, 31 * " RegLengthS "(sp)");
asm volatile ("addi sp, sp, 32 * " RegLengthS "");
asm volatile ("mret");
}
void __attribute__((naked)) SaveMpie()
{
asm volatile (StoreDS " a0, 2 * " RegLengthS "(sp)");
asm volatile (StoreDS " tp, 4 * " RegLengthS "(sp)");
asm volatile (StoreDS " t0, 5 * " RegLengthS "(sp)");
asm volatile (StoreDS " t1, 6 * " RegLengthS "(sp)");
asm volatile (StoreDS " t2, 7 * " RegLengthS "(sp)");
asm volatile (StoreDS " s0, 8 * " RegLengthS "(sp)");
asm volatile (StoreDS " s1, 9 * " RegLengthS "(sp)");
asm volatile (StoreDS " a0, 10 * " RegLengthS "(sp)");
asm volatile (StoreDS " a1, 11 * " RegLengthS "(sp)");
asm volatile (StoreDS " a2, 12 * " RegLengthS "(sp)");
asm volatile (StoreDS " a3, 13 * " RegLengthS "(sp)");
asm volatile (StoreDS " a4, 14 * " RegLengthS "(sp)");
asm volatile (StoreDS " a5, 15 * " RegLengthS "(sp)");
asm volatile (StoreDS " a6, 16 * " RegLengthS "(sp)");
asm volatile (StoreDS " a7, 17 * " RegLengthS "(sp)");
asm volatile (StoreDS " s2, 18 * " RegLengthS "(sp)");
asm volatile (StoreDS " s3, 19 * " RegLengthS "(sp)");
asm volatile (StoreDS " s4, 20 * " RegLengthS "(sp)");
asm volatile (StoreDS " s5, 21 * " RegLengthS "(sp)");
asm volatile (StoreDS " s6, 22 * " RegLengthS "(sp)");
asm volatile (StoreDS " s7, 23 * " RegLengthS "(sp)");
asm volatile (StoreDS " s8, 24 * " RegLengthS "(sp)");
asm volatile (StoreDS " s9, 25 * " RegLengthS "(sp)");
asm volatile (StoreDS " s10, 26 * " RegLengthS "(sp)");
asm volatile (StoreDS " s11, 27 * " RegLengthS "(sp)");
asm volatile (StoreDS " t3, 28 * " RegLengthS "(sp)");
asm volatile (StoreDS " t4, 29 * " RegLengthS "(sp)");
asm volatile (StoreDS " t5, 30 * " RegLengthS "(sp)");
asm volatile (StoreDS " t6, 31 * " RegLengthS "(sp)");
asm volatile (LoadDS " sp, (a1)");
asm volatile ("mv a0, a2");
asm volatile ("jal RestoreCpusLockStatus");
asm volatile ("j SwitchKTaskContextExit");
}
void __attribute__((naked)) SwitchKtaskContextTo(x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile (LoadDS " sp, (a0)\n");
asm volatile ("mv a0, a1");
asm volatile ("jal RestoreCpusLockStatus");
asm volatile (LoadDS " a7, 2 * " RegLengthS "(sp)");
asm volatile ("csrw mstatus, a7");
asm volatile ("j SwitchKTaskContextExit");
}
void __attribute__((naked)) SwitchKtaskContext(x_ubase from, x_ubase to, struct TaskDescriptor *to_task)
{
asm volatile ("addi sp, sp, -32 * " RegLengthS);
asm volatile (StoreDS " sp, (a0)");
asm volatile (StoreDS " x1, 0 * " RegLengthS "(sp)");
asm volatile (StoreDS " x1, 1 * " RegLengthS "(sp)");
asm volatile ("csrr a0, mstatus");
#ifndef TASK_ISOLATION
asm volatile ("andi a0, a0, 8");
asm volatile ("beqz a0, SaveMpie");
asm volatile ("li a0, 0x80");
#endif
asm volatile ("j SaveMpie");
}
void __attribute__((naked)) HwInterruptcontextSwitch(x_ubase from, x_ubase to, struct TaskDescriptor *to_task, void *context)
{
asm volatile (StoreDS " a3, 0(a0)");
asm volatile (LoadDS " sp, 0(a1)");
asm volatile ("move a0, a2");
asm volatile ("call RestoreCpusLockStatus");
asm volatile ("j SwitchKTaskContextExit");
}