Adjust directory structure
This commit is contained in:
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_DIR := $(ARCH)
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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
|
||||
@@ -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>© 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>© 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>© 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
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
#include "mpu.h"
|
||||
#include "board.h"
|
||||
#include <xs_isolation.h>
|
||||
|
||||
|
||||
void MpuEnable(uint32_t option)
|
||||
{
|
||||
MPU->CTRL = MPU_ENABLE | option;
|
||||
__DSB();
|
||||
__ISB();
|
||||
return ;
|
||||
}
|
||||
|
||||
void MpuDisable(void)
|
||||
{
|
||||
__DMB();
|
||||
MPU->CTRL = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void MpuClearRegion(uint8_t region)
|
||||
{
|
||||
__DMB();
|
||||
MPU->RNR = region;
|
||||
MPU->RBAR = 0;
|
||||
MPU->RASR = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void MpuClearAllRegion(void)
|
||||
{
|
||||
__DMB();
|
||||
for (int i = 0 ; i < 8 ; i++) {
|
||||
MPU->RNR = i;
|
||||
MPU->RBAR = 0;
|
||||
MPU->RASR = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t MpuAllocateRegion(void *task_mpu)
|
||||
{
|
||||
if(task_mpu == NONE)
|
||||
return -1;
|
||||
struct Mpu *mpu = (struct Mpu *)task_mpu;
|
||||
int8_t free_region;
|
||||
|
||||
if ( mpu->count < MPU_MAX_REGION_NUM - 1) {
|
||||
free_region = mpu->count;
|
||||
mpu->count ++;
|
||||
}
|
||||
else
|
||||
free_region = -1;
|
||||
|
||||
return free_region ;
|
||||
}
|
||||
|
||||
|
||||
size_t MpuLog2Ceil(size_t size)
|
||||
{
|
||||
size_t csize = 0;
|
||||
|
||||
while (size > 0) {
|
||||
size >>= 1;
|
||||
csize ++;
|
||||
}
|
||||
|
||||
return csize;
|
||||
}
|
||||
|
||||
int8_t MpuAddRegion(void *task_mpu, x_base addr , size_t size , uint8_t type)
|
||||
{
|
||||
|
||||
if(task_mpu == NONE)
|
||||
return -1;
|
||||
struct Mpu *mpu = (struct Mpu *)task_mpu;
|
||||
uint32_t l2size;
|
||||
int8_t region ;
|
||||
|
||||
region = MpuAllocateRegion(mpu);
|
||||
if (region < 0 ) {
|
||||
// KPrintf("MPU region full \n");
|
||||
return region;
|
||||
}
|
||||
uint32_t flag = 0;
|
||||
switch (type)
|
||||
{
|
||||
case REGION_TYPE_CODE:
|
||||
flag = MPU_RASR_AP_RO_RO | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S;
|
||||
break;
|
||||
case REGION_TYPE_DATA:
|
||||
flag = MPU_RASR_AP_RW_RW | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S ;
|
||||
break;
|
||||
case REGION_TYPE_BSS:
|
||||
flag = MPU_RASR_AP_RW_RW | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S ;
|
||||
break;
|
||||
case REGION_TYPE_HEAP:
|
||||
flag = MPU_RASR_AP_RW_RW | MPU_RASR_TEX_0 | MPU_RASR_C | MPU_RASR_S ;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
l2size = MpuLog2Ceil(size);
|
||||
addr = MPU_ALIGN(addr , 1 << l2size );
|
||||
mpu->region[region].config.rasr = flag |MPU_RASR_REGION_SIZE(l2size) | MPU_ENABLE;
|
||||
mpu->region[region].config.rbar = addr | MPU_RBAR_VALID | region ; //rbar must set region number
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
x_err_t MpuInit(void **task_mpu)
|
||||
{
|
||||
|
||||
x_base addr_start;
|
||||
uint32_t addr_size;
|
||||
uint32_t flag;
|
||||
|
||||
if (MPU->TYPE == 0) {
|
||||
KPrintf("mpu not surport \n");
|
||||
return -1 ;
|
||||
}
|
||||
// KPrintf("mpu init ...\n");
|
||||
|
||||
struct Mpu *mpu;
|
||||
mpu = (struct Mpu *)malloc(sizeof(struct Mpu));
|
||||
memset(mpu, 0, sizeof(struct Mpu));
|
||||
|
||||
if (mpu == NONE)
|
||||
return -ENOMEMORY;
|
||||
|
||||
MpuDisable();
|
||||
MpuClearAllRegion(); //clear
|
||||
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
|
||||
//user flash
|
||||
addr_start = USER_TEXT_START;
|
||||
addr_size = USER_TEXT_END - USER_TEXT_START;
|
||||
MpuAddRegion(mpu, addr_start , addr_size, REGION_TYPE_CODE);
|
||||
|
||||
|
||||
//user sram
|
||||
addr_start = USER_SRAM_START;
|
||||
addr_size = USER_SRAM_END - USER_SRAM_START;
|
||||
MpuAddRegion(mpu, addr_start , addr_size, REGION_TYPE_HEAP);
|
||||
*task_mpu = mpu;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
void MpuFree(void *task_mpu)
|
||||
{
|
||||
if(task_mpu == NONE)
|
||||
return;
|
||||
MpuDisable();
|
||||
MpuClearAllRegion(); //clear
|
||||
x_free(task_mpu);
|
||||
}
|
||||
|
||||
void MpuLoad(void *task_mpu)
|
||||
{
|
||||
// KPrintf("MPU load .. \n");
|
||||
MpuDisable();
|
||||
MpuClearAllRegion(); //clear
|
||||
if(task_mpu == NONE)
|
||||
return;
|
||||
struct Mpu *mpu = (struct Mpu *)task_mpu;
|
||||
|
||||
uint8_t region = 0 ;
|
||||
|
||||
#if 0
|
||||
for ( region = 0 ; region <= mpu->count -1 ; region ++ ){
|
||||
KPrintf("region: %d\n",region);
|
||||
KPrintf("rasr 0x%08x \n",mpu->region[region].config.rasr);
|
||||
KPrintf("rbar 0x%08x \n",mpu->region[region].config.rbar);
|
||||
KPrintf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( region = 0 ; region <= mpu->count -1 ; region ++ ){
|
||||
MPU->RNR = region;
|
||||
MPU->RBAR = mpu->region[region].config.rbar;
|
||||
MPU->RASR = mpu->region[region].config.rasr;
|
||||
}
|
||||
__DSB();
|
||||
__ISB();
|
||||
MpuEnable(MPU_PRIVDEFENA);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
#ifndef MPU_H
|
||||
#define MPU_H
|
||||
|
||||
#include <xs_base.h>
|
||||
#include <xs_klist.h>
|
||||
|
||||
|
||||
#define MPU_ALIGN(size, align) (((size)) & ~((align) - 1))
|
||||
|
||||
#define USER_TEXT_START (uintptr_t)( USERSPACE )
|
||||
#define USER_TEXT_END (uintptr_t)( USERSPACE->us_textend )
|
||||
#define USER_SRAM_START (uintptr_t)( USERSPACE->us_datastart )
|
||||
#define USER_SRAM_END (uintptr_t)( USER_MEMORY_END_ADDRESS )
|
||||
|
||||
|
||||
|
||||
#define MPU_MAX_REGION_NUM 8
|
||||
|
||||
|
||||
/* MPU Control Register Bit Definitions */
|
||||
#define MPU_ENABLE (1 << 0) /* Bit 0: Enable the MPU */
|
||||
#define MPU_HFNMIENA (1 << 1) /* Bit 1: Enable MPU during hard fault, NMI, and FAULTMAS */
|
||||
#define MPU_PRIVDEFENA (1 << 2) /* Bit 2: Enable privileged access to default memory map */
|
||||
|
||||
#define MPU_RBAR_VALID (1 << 4)
|
||||
|
||||
#define MPU_RASR_ENABLE (1 << 0) /* Bit 0: Region enable */
|
||||
#define MPU_RASR_REGION_SIZE(n) ((n-1) << 1)
|
||||
|
||||
#define MPU_RASR_AP_NO_NO (0 << 24) /* P:None U:None */
|
||||
#define MPU_RASR_AP_RW_NO (1 << 24) /* P:RW U:None */
|
||||
#define MPU_RASR_AP_RW_RO (2 << 24) /* P:RW U:RO */
|
||||
#define MPU_RASR_AP_RW_RW (3 << 24) /* P:RW U:RW */
|
||||
#define MPU_RASR_AP_RO_NO (5 << 24) /* P:RO U:None */
|
||||
#define MPU_RASR_AP_RO_RO (6 << 24) /* P:RO U:RO */
|
||||
|
||||
#define MPU_RASR_RASR_XN (1 << 28) /* Bit 28: Instruction access disable */
|
||||
|
||||
#define MPU_RASR_SRD_MASK (0xff << 8)
|
||||
#define MPU_RASR_SRD_0 (0x01 << 8)
|
||||
#define MPU_RASR_SRD_1 (0x02 << 8)
|
||||
#define MPU_RASR_SRD_2 (0x04 << 8)
|
||||
#define MPU_RASR_SRD_3 (0x08 << 8)
|
||||
#define MPU_RASR_SRD_4 (0x10 << 8)
|
||||
#define MPU_RASR_SRD_5 (0x20 << 8)
|
||||
#define MPU_RASR_SRD_6 (0x40 << 8)
|
||||
#define MPU_RASR_SRD_7 (0x80 << 8)
|
||||
|
||||
#define MPU_RASR_TEX_SHIFT (19) /* Bits 19-21: TEX Address Permission */
|
||||
#define MPU_RASR_TEX_MASK (7 << 19)
|
||||
#define MPU_RASR_TEX_0 (0 << 19) /* Strongly Ordered */
|
||||
#define MPU_RASR_TEX_1 (1 << 19) /* Normal */
|
||||
#define MPU_RASR_TEX_2 (2 << 19) /* Device */
|
||||
#define MPU_RASR_TEX_BB(bb) ((4|(bb)) << 19)
|
||||
|
||||
#define MPU_RASR_B (1 << 16) /* Bit 16: Bufferable */
|
||||
#define MPU_RASR_C (1 << 17) /* Bit 17: Cacheable */
|
||||
#define MPU_RASR_S (1 << 18) /* Bit 18: Shareable */
|
||||
|
||||
struct MpuConfig
|
||||
{
|
||||
uint32_t rasr;
|
||||
uint32_t rbar;
|
||||
};
|
||||
|
||||
struct MpuRegion
|
||||
{
|
||||
x_base start;
|
||||
x_base size;
|
||||
struct MpuConfig config;
|
||||
};
|
||||
|
||||
struct Mpu
|
||||
{
|
||||
|
||||
uint8_t count;
|
||||
struct MpuRegion region[MPU_MAX_REGION_NUM];
|
||||
};
|
||||
|
||||
|
||||
void MpuEnable( uint32_t option);
|
||||
void MpuDisable(void);
|
||||
x_err_t MpuInit(void **task_mpu);
|
||||
void MpuLoad(void *task_mpu);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <xsconfig.h>
|
||||
|
||||
.globl SVC_Entry
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "svc_entry.S"
|
||||
|
||||
.text
|
||||
.type SVC_Entry, %function
|
||||
.thumb_func
|
||||
SVC_Entry:
|
||||
MRS r3, PRIMASK
|
||||
CPSID I
|
||||
MRS r0, ipsr
|
||||
MRS r1, psp /* R1=The process stack pointer (PSP) */
|
||||
|
||||
STMDB r1!, {r3-r11} /* Save the remaining registers plus the SP/PRIMASK values */
|
||||
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
MOV r2, #0x00
|
||||
TST lr, #0x10
|
||||
MOVEQ r2, #0x01
|
||||
STMFD r1!, {r2}
|
||||
#endif
|
||||
PUSH {lr}
|
||||
BL Svcall /* R0=IRQ, R1=register save (msp) */
|
||||
POP {lr}
|
||||
|
||||
MOV r1, r0
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
PUSH {lr}
|
||||
BL GetTaskPrivilege
|
||||
POP {lr}
|
||||
#endif
|
||||
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
LDMFD r1!, {r2}
|
||||
#endif
|
||||
|
||||
LDMIA r1!, {r3-r11} /* Recover R4-R11, FPU flag and PRIMASK*/
|
||||
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
ORR lr, lr, #0x10
|
||||
CMP r2, #0
|
||||
BICNE lr, lr, #0x10
|
||||
#endif
|
||||
MSR psp, r1
|
||||
MRS r2, control
|
||||
|
||||
#ifdef TASK_ISOLATION
|
||||
CMP r0, #1
|
||||
BEQ unprivilege
|
||||
|
||||
privilege:
|
||||
BIC r2, r2, #0x01
|
||||
B exit
|
||||
|
||||
unprivilege:
|
||||
ORR r2, r2, #0x01
|
||||
#else
|
||||
BIC r2, r2, #0x01
|
||||
#endif
|
||||
|
||||
exit:
|
||||
MSR control, r2
|
||||
ORR lr, lr, #0x04
|
||||
MSR PRIMASK, r3
|
||||
BX lr
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <xs_base.h>
|
||||
#include <stdint.h>
|
||||
#include "svc_handle.h"
|
||||
#include <xs_service.h>
|
||||
#include <xs_ktask.h>
|
||||
|
||||
static void SvcDispatch(void) __attribute__ ((naked, no_instrument_function));
|
||||
static void SvcDispatch(void)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
" mov r12, sp\n"
|
||||
" sub r12, r12, #36\n"
|
||||
" and r12, r12, #7\n"
|
||||
" add r12, r12, #36\n"
|
||||
" sub sp, sp, r12\n"
|
||||
" str r0, [sp, #0]\n"
|
||||
" str r1, [sp, #4]\n"
|
||||
" str r2, [sp, #8]\n"
|
||||
" str r3, [sp, #12]\n"
|
||||
" str r4, [sp, #16]\n"
|
||||
" str r5, [sp, #20]\n"
|
||||
" str r6, [sp, #24]\n"
|
||||
" str lr, [sp, #28]\n"
|
||||
" str r12, [sp, #32]\n"
|
||||
" mov r0, sp\n"
|
||||
" ldr r12, =SvcHandle\n"
|
||||
" blx r12\n"
|
||||
" ldr lr, [sp, #28]\n"
|
||||
" ldr r2, [sp, #32]\n"
|
||||
" add sp, sp, r2\n"
|
||||
" svc 1"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void _svcall(uintptr_t* contex)
|
||||
{
|
||||
uint32_t svc_number;
|
||||
KTaskDescriptorType tid;
|
||||
|
||||
tid = GetKTaskDescriptor();
|
||||
svc_number = ((char *)contex[REG_INT_PC ])[-2];
|
||||
switch (svc_number) {
|
||||
case 0: //svc handler
|
||||
tid->task_dync_sched_member.svc_return = contex[REG_INT_PC];
|
||||
tid->task_dync_sched_member.isolation_status = 1;
|
||||
contex[REG_INT_PC] = (uint32_t)SvcDispatch & ~1;
|
||||
break;
|
||||
case 1: // svc return
|
||||
contex[REG_INT_PC] = tid->task_dync_sched_member.svc_return;
|
||||
tid->task_dync_sched_member.isolation_status = 0;
|
||||
break;
|
||||
default:
|
||||
KPrintf("unsurport svc call number :%d\n",svc_number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t SvcHandle(uintptr_t *sp)
|
||||
{
|
||||
uint32_t service_num = 0;
|
||||
service_num = ((uint32_t) sp[0]); //r0
|
||||
uint8_t param_num = g_service_table[service_num].param_num;
|
||||
uintptr_t *param = sp + 1;
|
||||
return g_service_table[service_num].fun(service_num,param,param_num) ;
|
||||
}
|
||||
|
||||
|
||||
uint32_t GetTaskPrivilege(void){
|
||||
uint32_t unprivileg = 0;
|
||||
struct TaskDescriptor *task = GetKTaskDescriptor();
|
||||
if (task->task_dync_sched_member.isolation_flag == 1 && task->task_dync_sched_member.isolation_status == 0) {
|
||||
unprivileg = 1;
|
||||
} else {
|
||||
unprivileg = 0;
|
||||
}
|
||||
|
||||
return unprivileg;
|
||||
}
|
||||
@@ -0,0 +1,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>© 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
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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, ®ion->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, ®ion->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
|
||||
@@ -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");
|
||||
}
|
||||
Reference in New Issue
Block a user