Add Nuclei RISC-V support
This kernel is setup for rv32 arch with gcc compiler. Signed-off-by: linzewen <linzewen@nucleisys.com>
This commit is contained in:
parent
f96848e4ce
commit
6c8da43bc9
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ARCH_CONTEXT_H
|
||||
#define _LOS_ARCH_CONTEXT_H
|
||||
|
||||
#include "los_compiler.h"
|
||||
#include "los_context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_hw
|
||||
*/
|
||||
typedef unsigned long STACK_TYPE;
|
||||
|
||||
typedef struct {
|
||||
STACK_TYPE epc; /* epc - epc - program counter */
|
||||
STACK_TYPE ra; /* x1 - ra - return address for jumps */
|
||||
STACK_TYPE t0; /* x5 - t0 - temporary register 0 */
|
||||
STACK_TYPE t1; /* x6 - t1 - temporary register 1 */
|
||||
STACK_TYPE t2; /* x7 - t2 - temporary register 2 */
|
||||
STACK_TYPE s0_fp; /* x8 - s0/fp - saved register 0 or frame pointer */
|
||||
STACK_TYPE s1; /* x9 - s1 - saved register 1 */
|
||||
STACK_TYPE a0; /* x10 - a0 - return value or function argument 0 */
|
||||
STACK_TYPE a1; /* x11 - a1 - return value or function argument 1 */
|
||||
STACK_TYPE a2; /* x12 - a2 - function argument 2 */
|
||||
STACK_TYPE a3; /* x13 - a3 - function argument 3 */
|
||||
STACK_TYPE a4; /* x14 - a4 - function argument 4 */
|
||||
STACK_TYPE a5; /* x15 - a5 - function argument 5 */
|
||||
#ifndef __riscv_32e
|
||||
STACK_TYPE a6; /* x16 - a6 - function argument 6 */
|
||||
STACK_TYPE a7; /* x17 - s7 - function argument 7 */
|
||||
STACK_TYPE s2; /* x18 - s2 - saved register 2 */
|
||||
STACK_TYPE s3; /* x19 - s3 - saved register 3 */
|
||||
STACK_TYPE s4; /* x20 - s4 - saved register 4 */
|
||||
STACK_TYPE s5; /* x21 - s5 - saved register 5 */
|
||||
STACK_TYPE s6; /* x22 - s6 - saved register 6 */
|
||||
STACK_TYPE s7; /* x23 - s7 - saved register 7 */
|
||||
STACK_TYPE s8; /* x24 - s8 - saved register 8 */
|
||||
STACK_TYPE s9; /* x25 - s9 - saved register 9 */
|
||||
STACK_TYPE s10; /* x26 - s10 - saved register 10 */
|
||||
STACK_TYPE s11; /* x27 - s11 - saved register 11 */
|
||||
STACK_TYPE t3; /* x28 - t3 - temporary register 3 */
|
||||
STACK_TYPE t4; /* x29 - t4 - temporary register 4 */
|
||||
STACK_TYPE t5; /* x30 - t5 - temporary register 5 */
|
||||
STACK_TYPE t6; /* x31 - t6 - temporary register 6 */
|
||||
#endif
|
||||
STACK_TYPE mstatus; /* - machine status register */
|
||||
} TaskContext;
|
||||
|
||||
extern VOID HalStartToRun(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_HW_H */
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
#ifndef _LOS_HWI_H
|
||||
#define _LOS_HWI_H
|
||||
|
||||
#include "nuclei_sdk_soc.h"
|
||||
#include "los_compiler.h"
|
||||
#include "los_config.h"
|
||||
#include "los_interrupt.h"
|
||||
#include "los_arch_context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Count of Nuclei system interrupt vector.
|
||||
*/
|
||||
#define OS_RISCV_SYS_VECTOR_CNT 19
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Count of Nuclei interrupt vector maxium, which is configurable.
|
||||
*/
|
||||
#define OS_RISCV_CUSTOM_IRQ_VECTOR_CNT SOC_INT_MAX
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Count of Nuclei interrupt vector.
|
||||
*/
|
||||
#define OS_RISCV_VECTOR_CNT (OS_RISCV_SYS_VECTOR_CNT + OS_RISCV_CUSTOM_IRQ_VECTOR_CNT)
|
||||
|
||||
/**
|
||||
* Maximum number of supported hardware devices that generate hardware interrupts.
|
||||
*/
|
||||
#define OS_HWI_MAX_NUM (OS_RISCV_VECTOR_CNT-1)
|
||||
|
||||
extern VOID HalHwiDefaultHandler(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: Invalid interrupt number.
|
||||
*
|
||||
* Value: 0x02000900
|
||||
*
|
||||
* Solution: Ensure that the interrupt number is valid. The value range of the interrupt number applicable
|
||||
* for a risc-v platform is [0, OS_RISCV_VECTOR_CNT].
|
||||
*/
|
||||
#define OS_ERRNO_HWI_NUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x00)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: Null hardware interrupt handling function.
|
||||
*
|
||||
* Value: 0x02000901
|
||||
*
|
||||
* Solution: Pass in a valid non-null hardware interrupt handling function.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: Insufficient interrupt resources for hardware interrupt creation.
|
||||
*
|
||||
* Value: 0x02000902
|
||||
*
|
||||
* Solution: Increase the configured maximum number of supported hardware interrupts.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: Insufficient memory for hardware interrupt initialization.
|
||||
*
|
||||
* Value: 0x02000903
|
||||
*
|
||||
* Solution: Expand the configured memory.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: The interrupt has already been created.
|
||||
*
|
||||
* Value: 0x02000904
|
||||
*
|
||||
* Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: Invalid interrupt priority.
|
||||
*
|
||||
* Value: 0x02000905
|
||||
*
|
||||
* Solution: Ensure that the interrupt priority is valid.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: Incorrect interrupt creation mode.
|
||||
*
|
||||
* Value: 0x02000906
|
||||
*
|
||||
* Solution: The interrupt creation mode can be only set to ECLIC_NON_VECTOR_INTERRUPT or ECLIC_VECTOR_INTERRUPT of which the
|
||||
* value can be 0 or 1.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: The interrupt has already been created as a fast interrupt.
|
||||
*
|
||||
* Value: 0x02000907
|
||||
*
|
||||
* Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code: The API is called during an interrupt, which is forbidden.
|
||||
*
|
||||
* Value: 0x02000908
|
||||
*
|
||||
* * Solution: Do not call the API during an interrupt.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code:the hwi support SHARED error.
|
||||
*
|
||||
* Value: 0x02000909
|
||||
*
|
||||
* * Solution:check the input params hwiMode and irqParam of HalHwiCreate or HalHwiDelete whether adapt the current
|
||||
* hwi.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code:Invalid interrupt Arg.
|
||||
*
|
||||
* Value: 0x0200090a
|
||||
*
|
||||
* * Solution:check the interrupt Arg, Arg should only be ECLIC_LEVEL_TRIGGER, ECLIC_POSTIVE_EDGE_TRIGGER or
|
||||
* ECLIC_NEGTIVE_EDGE_TRIGGER.
|
||||
*/
|
||||
#define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a)
|
||||
|
||||
/**
|
||||
* @ingroup los_hwi
|
||||
* Hardware interrupt error code:The interrupt corresponded to the hwi number or devid has not been created.
|
||||
*
|
||||
* Value: 0x0200090b
|
||||
*
|
||||
* * Solution:check the hwi number or devid, make sure the hwi number or devid need to delete.
|
||||
*/
|
||||
// #define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b)
|
||||
|
||||
extern UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp);
|
||||
|
||||
extern VOID DisplayTaskInfo(VOID);
|
||||
|
||||
extern UINT32 g_intCount;
|
||||
|
||||
__attribute__((always_inline)) static inline VOID HalIntEnter(VOID)
|
||||
{
|
||||
g_intCount += 1;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline VOID HalIntExit(VOID)
|
||||
{
|
||||
g_intCount -= 1;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline UINT32 HalIsIntAcvive(VOID)
|
||||
{
|
||||
return (g_intCount > 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_HWI_H */
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ARCH_TIMER_H
|
||||
#define _LOS_ARCH_TIMER_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_compiler.h"
|
||||
#include "los_context.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cpluscplus */
|
||||
#endif /* __cpluscplus */
|
||||
|
||||
UINT32 HalTickStart(OS_TICK_HANDLER handler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cpluscplus */
|
||||
#endif /* __cpluscplus */
|
||||
|
||||
#endif /* _LOS_ARCH_TIMER_H */
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "los_arch_context.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "los_arch_timer.h"
|
||||
#include "los_task.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_timer.h"
|
||||
#include "nuclei_sdk_soc.h"
|
||||
|
||||
#define INITIAL_MSTATUS ( MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL)
|
||||
|
||||
#define ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalArchInit(VOID)
|
||||
{
|
||||
HalHwiInit();
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID HalSysExit(VOID)
|
||||
{
|
||||
HalIntLock();
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID *HalTskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT8 *stk;
|
||||
TaskContext *context = NULL;
|
||||
|
||||
/* initialize the task stack, write magic num to stack top */
|
||||
*((UINT32 *)(topStack)) = OS_TASK_MAGIC_WORD;
|
||||
|
||||
stk = ((UINT8 *)topStack) + stackSize + sizeof(STACK_TYPE);
|
||||
stk = (UINT8 *)ALIGN_DOWN((unsigned long)stk, REGBYTES);
|
||||
context = (TaskContext *)(stk - sizeof(TaskContext));
|
||||
|
||||
for (index = 1; index < sizeof(TaskContext)/ sizeof(STACK_TYPE); index ++) {
|
||||
((STACK_TYPE *)context)[index] = OS_TASK_STACK_INIT;
|
||||
}
|
||||
context->ra = (STACK_TYPE)HalSysExit;
|
||||
context->a0 = (STACK_TYPE)taskID;
|
||||
context->epc = (STACK_TYPE)OsTaskEntry;
|
||||
|
||||
context->mstatus = INITIAL_MSTATUS;
|
||||
|
||||
|
||||
return (VOID *)context;
|
||||
}
|
||||
|
||||
extern BOOL g_taskScheduled;
|
||||
extern LosTask g_losTask;
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 HalStartSchedule(OS_TICK_HANDLER handler)
|
||||
{
|
||||
UINT32 ret;
|
||||
__disable_irq();
|
||||
ret = HalTickStart(handler);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
g_taskScheduled = TRUE;
|
||||
/* Set newTask to runTask */
|
||||
g_losTask.runTask = g_losTask.newTask;
|
||||
g_losTask.runTask->taskStatus |= OS_TASK_STATUS_RUNNING;
|
||||
HalStartToRun();
|
||||
return LOS_OK; /* never return */
|
||||
}
|
||||
|
||||
VOID HalTaskSchedule(VOID)
|
||||
{
|
||||
SysTimer_SetSWIRQ();
|
||||
}
|
||||
|
||||
VOID HalTaskSwitch(VOID)
|
||||
{
|
||||
SysTimer_ClearSWIRQ();
|
||||
g_losTask.runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING;
|
||||
/* Set newTask to runTask */
|
||||
g_losTask.runTask = g_losTask.newTask;
|
||||
g_losTask.runTask->taskStatus |= OS_TASK_STATUS_RUNNING;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT VOID HalTaskScheduleCheck(VOID)
|
||||
{
|
||||
#if (LOSCFG_BASE_CORE_TSK_MONITOR == 1)
|
||||
OsTaskSwitchCheck();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
VOID HalEnterSleep(LOS_SysSleepEnum sleep)
|
||||
{
|
||||
__WFI();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
#ifndef __riscv_32e
|
||||
#define portRegNum 30
|
||||
#else
|
||||
#define portRegNum 14
|
||||
#endif
|
||||
|
||||
#define portCONTEXT_SIZE ( portRegNum * REGBYTES )
|
||||
|
||||
.section .text
|
||||
.align 4
|
||||
|
||||
.type HalIntLock, %function
|
||||
.global HalIntLock
|
||||
HalIntLock:
|
||||
csrr a0, mstatus // return value
|
||||
li t0, MSTATUS_MIE // mie
|
||||
csrrc zero, mstatus, t0
|
||||
ret
|
||||
|
||||
.type HalIntUnLock, %function
|
||||
.global HalIntUnLock
|
||||
HalIntUnLock:
|
||||
csrr a0, mstatus // return value
|
||||
li t0, MSTATUS_MIE // mie
|
||||
csrrs zero, mstatus, t0
|
||||
ret
|
||||
|
||||
.type HalIntRestore, %function
|
||||
.global HalIntRestore
|
||||
HalIntRestore:
|
||||
csrw mstatus, a0
|
||||
ret
|
||||
|
||||
|
||||
/* Start the first task. This also clears the bit that indicates the FPU is
|
||||
in use in case the FPU was used before the scheduler was started - which
|
||||
would otherwise result in the unnecessary leaving of space in the stack
|
||||
for lazy saving of FPU registers. */
|
||||
.type HalStartToRun, %function
|
||||
.global HalStartToRun
|
||||
.align 3
|
||||
HalStartToRun:
|
||||
/* Setup Interrupt Stack using
|
||||
The stack that was used by main()
|
||||
before the scheduler is started is
|
||||
no longer required after the scheduler is started.
|
||||
Interrupt stack pointer is stored in CSR_MSCRATCH */
|
||||
la t0, _sp
|
||||
csrw CSR_MSCRATCH, t0
|
||||
/* get stack pointer */
|
||||
la t0, g_losTask
|
||||
LOAD t1, 0x0(t0)
|
||||
LOAD sp, 0(t1)
|
||||
//LOAD sp, 0x0(sp) /* Read sp from first TCB member */
|
||||
|
||||
/* Pop PC from stack and set MEPC */
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
/* Pop mstatus from stack and set it */
|
||||
LOAD t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
/* Interrupt still disable here */
|
||||
/* Restore Registers from Stack */
|
||||
LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
LOAD x5, 2 * REGBYTES(sp)
|
||||
LOAD x6, 3 * REGBYTES(sp)
|
||||
LOAD x7, 4 * REGBYTES(sp)
|
||||
LOAD x8, 5 * REGBYTES(sp)
|
||||
LOAD x9, 6 * REGBYTES(sp)
|
||||
LOAD x10, 7 * REGBYTES(sp)
|
||||
LOAD x11, 8 * REGBYTES(sp)
|
||||
LOAD x12, 9 * REGBYTES(sp)
|
||||
LOAD x13, 10 * REGBYTES(sp)
|
||||
LOAD x14, 11 * REGBYTES(sp)
|
||||
LOAD x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 13 * REGBYTES(sp)
|
||||
LOAD x17, 14 * REGBYTES(sp)
|
||||
LOAD x18, 15 * REGBYTES(sp)
|
||||
LOAD x19, 16 * REGBYTES(sp)
|
||||
LOAD x20, 17 * REGBYTES(sp)
|
||||
LOAD x21, 18 * REGBYTES(sp)
|
||||
LOAD x22, 19 * REGBYTES(sp)
|
||||
LOAD x23, 20 * REGBYTES(sp)
|
||||
LOAD x24, 21 * REGBYTES(sp)
|
||||
LOAD x25, 22 * REGBYTES(sp)
|
||||
LOAD x26, 23 * REGBYTES(sp)
|
||||
LOAD x27, 24 * REGBYTES(sp)
|
||||
LOAD x28, 25 * REGBYTES(sp)
|
||||
LOAD x29, 26 * REGBYTES(sp)
|
||||
LOAD x30, 27 * REGBYTES(sp)
|
||||
LOAD x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
mret
|
||||
|
||||
.extern HalTaskSwitch
|
||||
.align 2
|
||||
.global eclic_msip_handler
|
||||
eclic_msip_handler:
|
||||
addi sp, sp, -portCONTEXT_SIZE
|
||||
STORE x1, 1 * REGBYTES(sp) /* RA */
|
||||
STORE x5, 2 * REGBYTES(sp)
|
||||
STORE x6, 3 * REGBYTES(sp)
|
||||
STORE x7, 4 * REGBYTES(sp)
|
||||
STORE x8, 5 * REGBYTES(sp)
|
||||
STORE x9, 6 * REGBYTES(sp)
|
||||
STORE x10, 7 * REGBYTES(sp)
|
||||
STORE x11, 8 * REGBYTES(sp)
|
||||
STORE x12, 9 * REGBYTES(sp)
|
||||
STORE x13, 10 * REGBYTES(sp)
|
||||
STORE x14, 11 * REGBYTES(sp)
|
||||
STORE x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 13 * REGBYTES(sp)
|
||||
STORE x17, 14 * REGBYTES(sp)
|
||||
STORE x18, 15 * REGBYTES(sp)
|
||||
STORE x19, 16 * REGBYTES(sp)
|
||||
STORE x20, 17 * REGBYTES(sp)
|
||||
STORE x21, 18 * REGBYTES(sp)
|
||||
STORE x22, 19 * REGBYTES(sp)
|
||||
STORE x23, 20 * REGBYTES(sp)
|
||||
STORE x24, 21 * REGBYTES(sp)
|
||||
STORE x25, 22 * REGBYTES(sp)
|
||||
STORE x26, 23 * REGBYTES(sp)
|
||||
STORE x27, 24 * REGBYTES(sp)
|
||||
STORE x28, 25 * REGBYTES(sp)
|
||||
STORE x29, 26 * REGBYTES(sp)
|
||||
STORE x30, 27 * REGBYTES(sp)
|
||||
STORE x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
/* Push mstatus to stack */
|
||||
csrr t0, CSR_MSTATUS
|
||||
STORE t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
|
||||
/* Push additional registers */
|
||||
|
||||
/* Store sp to task stack */
|
||||
la t0, g_losTask
|
||||
LOAD t0, 0(t0)
|
||||
STORE sp, 0(t0)
|
||||
|
||||
csrr t0, CSR_MEPC
|
||||
STORE t0, 0(sp)
|
||||
|
||||
/* Switch task context */
|
||||
jal HalTaskSwitch
|
||||
/* Load new task */
|
||||
la t0, g_losTask
|
||||
LOAD t0, 0(t0)
|
||||
LOAD sp, 0x0(t0) /* Read sp from first TCB member */
|
||||
|
||||
/* Pop PC from stack and set MEPC */
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
csrw CSR_MEPC, t0
|
||||
/* Pop additional registers */
|
||||
|
||||
/* Pop mstatus from stack and set it */
|
||||
LOAD t0, (portRegNum - 1) * REGBYTES(sp)
|
||||
csrw CSR_MSTATUS, t0
|
||||
/* Interrupt still disable here */
|
||||
/* Restore Registers from Stack */
|
||||
LOAD x1, 1 * REGBYTES(sp) /* RA */
|
||||
LOAD x5, 2 * REGBYTES(sp)
|
||||
LOAD x6, 3 * REGBYTES(sp)
|
||||
LOAD x7, 4 * REGBYTES(sp)
|
||||
LOAD x8, 5 * REGBYTES(sp)
|
||||
LOAD x9, 6 * REGBYTES(sp)
|
||||
LOAD x10, 7 * REGBYTES(sp)
|
||||
LOAD x11, 8 * REGBYTES(sp)
|
||||
LOAD x12, 9 * REGBYTES(sp)
|
||||
LOAD x13, 10 * REGBYTES(sp)
|
||||
LOAD x14, 11 * REGBYTES(sp)
|
||||
LOAD x15, 12 * REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 13 * REGBYTES(sp)
|
||||
LOAD x17, 14 * REGBYTES(sp)
|
||||
LOAD x18, 15 * REGBYTES(sp)
|
||||
LOAD x19, 16 * REGBYTES(sp)
|
||||
LOAD x20, 17 * REGBYTES(sp)
|
||||
LOAD x21, 18 * REGBYTES(sp)
|
||||
LOAD x22, 19 * REGBYTES(sp)
|
||||
LOAD x23, 20 * REGBYTES(sp)
|
||||
LOAD x24, 21 * REGBYTES(sp)
|
||||
LOAD x25, 22 * REGBYTES(sp)
|
||||
LOAD x26, 23 * REGBYTES(sp)
|
||||
LOAD x27, 24 * REGBYTES(sp)
|
||||
LOAD x28, 25 * REGBYTES(sp)
|
||||
LOAD x29, 26 * REGBYTES(sp)
|
||||
LOAD x30, 27 * REGBYTES(sp)
|
||||
LOAD x31, 28 * REGBYTES(sp)
|
||||
#endif
|
||||
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
mret
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_EXC_S
|
||||
#define _LOS_EXC_S
|
||||
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
.section .text.entry
|
||||
.align 8
|
||||
|
||||
/**
|
||||
* \brief Global interrupt disabled
|
||||
* \details
|
||||
* This function disable global interrupt.
|
||||
* \remarks
|
||||
* - All the interrupt requests will be ignored by CPU.
|
||||
*/
|
||||
.macro DISABLE_MIE
|
||||
csrc CSR_MSTATUS, MSTATUS_MIE
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for context save
|
||||
* \details
|
||||
* This macro save ABI defined caller saved registers in the stack.
|
||||
* \remarks
|
||||
* - This Macro could use to save context when you enter to interrupt
|
||||
* or exception
|
||||
*/
|
||||
/* Save caller registers */
|
||||
.macro SAVE_CONTEXT
|
||||
csrrw sp, CSR_MSCRATCHCSWL, sp
|
||||
/* Allocate stack space for context saving */
|
||||
#ifndef __riscv_32e
|
||||
addi sp, sp, -20*REGBYTES
|
||||
#else
|
||||
addi sp, sp, -14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
|
||||
STORE x1, 0*REGBYTES(sp)
|
||||
STORE x4, 1*REGBYTES(sp)
|
||||
STORE x5, 2*REGBYTES(sp)
|
||||
STORE x6, 3*REGBYTES(sp)
|
||||
STORE x7, 4*REGBYTES(sp)
|
||||
STORE x10, 5*REGBYTES(sp)
|
||||
STORE x11, 6*REGBYTES(sp)
|
||||
STORE x12, 7*REGBYTES(sp)
|
||||
STORE x13, 8*REGBYTES(sp)
|
||||
STORE x14, 9*REGBYTES(sp)
|
||||
STORE x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
STORE x16, 14*REGBYTES(sp)
|
||||
STORE x17, 15*REGBYTES(sp)
|
||||
STORE x28, 16*REGBYTES(sp)
|
||||
STORE x29, 17*REGBYTES(sp)
|
||||
STORE x30, 18*REGBYTES(sp)
|
||||
STORE x31, 19*REGBYTES(sp)
|
||||
#endif /* __riscv_32e */
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore caller registers
|
||||
* \details
|
||||
* This macro restore ABI defined caller saved registers from stack.
|
||||
* \remarks
|
||||
* - You could use this macro to restore context before you want return
|
||||
* from interrupt or exeception
|
||||
*/
|
||||
/* Restore caller registers */
|
||||
.macro RESTORE_CONTEXT
|
||||
LOAD x1, 0*REGBYTES(sp)
|
||||
LOAD x4, 1*REGBYTES(sp)
|
||||
LOAD x5, 2*REGBYTES(sp)
|
||||
LOAD x6, 3*REGBYTES(sp)
|
||||
LOAD x7, 4*REGBYTES(sp)
|
||||
LOAD x10, 5*REGBYTES(sp)
|
||||
LOAD x11, 6*REGBYTES(sp)
|
||||
LOAD x12, 7*REGBYTES(sp)
|
||||
LOAD x13, 8*REGBYTES(sp)
|
||||
LOAD x14, 9*REGBYTES(sp)
|
||||
LOAD x15, 10*REGBYTES(sp)
|
||||
#ifndef __riscv_32e
|
||||
LOAD x16, 14*REGBYTES(sp)
|
||||
LOAD x17, 15*REGBYTES(sp)
|
||||
LOAD x28, 16*REGBYTES(sp)
|
||||
LOAD x29, 17*REGBYTES(sp)
|
||||
LOAD x30, 18*REGBYTES(sp)
|
||||
LOAD x31, 19*REGBYTES(sp)
|
||||
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 20*REGBYTES
|
||||
#else
|
||||
/* De-allocate the stack space */
|
||||
addi sp, sp, 14*REGBYTES
|
||||
#endif /* __riscv_32e */
|
||||
csrrw sp, CSR_MSCRATCHCSWL, sp
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for save necessary CSRs to stack
|
||||
* \details
|
||||
* This macro store MCAUSE, MEPC, MSUBM to stack.
|
||||
*/
|
||||
.macro SAVE_CSR_CONTEXT
|
||||
/* Store CSR mcause to stack using pushmcause */
|
||||
csrrwi x0, CSR_PUSHMCAUSE, 11
|
||||
/* Store CSR mepc to stack using pushmepc */
|
||||
csrrwi x0, CSR_PUSHMEPC, 12
|
||||
/* Store CSR msub to stack using pushmsub */
|
||||
csrrwi x0, CSR_PUSHMSUBM, 13
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Macro for restore necessary CSRs from stack
|
||||
* \details
|
||||
* This macro restore MSUBM, MEPC, MCAUSE from stack.
|
||||
*/
|
||||
.macro RESTORE_CSR_CONTEXT
|
||||
LOAD x5, 13*REGBYTES(sp)
|
||||
csrw CSR_MSUBM, x5
|
||||
LOAD x5, 12*REGBYTES(sp)
|
||||
csrw CSR_MEPC, x5
|
||||
LOAD x5, 11*REGBYTES(sp)
|
||||
csrw CSR_MCAUSE, x5
|
||||
.endm
|
||||
|
||||
/**
|
||||
* \brief Exception/NMI Entry
|
||||
* \details
|
||||
* This function provide common entry functions for exception/nmi.
|
||||
* \remarks
|
||||
* This function provide a default exception/nmi entry.
|
||||
* ABI defined caller save register and some CSR registers
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.trap
|
||||
/* In CLIC mode, the exeception entry must be 64bytes aligned */
|
||||
.align 6
|
||||
.global exc_entry
|
||||
exc_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/*
|
||||
* Set the exception handler function arguments
|
||||
* argument 1: mcause value
|
||||
* argument 2: current stack point(SP) value
|
||||
*/
|
||||
csrr a0, mcause
|
||||
mv a1, sp
|
||||
/*
|
||||
* TODO: Call the exception handler function
|
||||
* By default, the function template is provided in
|
||||
* system_Device.c, you can adjust it as you want
|
||||
*/
|
||||
call core_exception_handler
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/**
|
||||
* \brief Non-Vector Interrupt Entry
|
||||
* \details
|
||||
* This function provide common entry functions for handling
|
||||
* non-vector interrupts
|
||||
* \remarks
|
||||
* This function provide a default non-vector interrupt entry.
|
||||
* ABI defined caller save register and some CSR registers need
|
||||
* to be saved before enter interrupt handler and be restored before return.
|
||||
*/
|
||||
.section .text.irq
|
||||
/* In CLIC mode, the interrupt entry must be 4bytes aligned */
|
||||
.align 2
|
||||
.extern g_intCount
|
||||
.global irq_entry
|
||||
/* This label will be set to MTVT2 register */
|
||||
irq_entry:
|
||||
/* Save the caller saving registers (context) */
|
||||
SAVE_CONTEXT
|
||||
/* Save the necessary CSR registers */
|
||||
SAVE_CSR_CONTEXT
|
||||
|
||||
/* This special CSR read/write operation, which is actually
|
||||
* claim the CLIC to find its pending highest ID, if the ID
|
||||
* is not 0, then automatically enable the mstatus.MIE, and
|
||||
* jump to its vector-entry-label, and update the link register
|
||||
*/
|
||||
la t0, g_intCount
|
||||
lw t1, 0(t0)
|
||||
add t1, t1, 0x1
|
||||
sw t1, 0(t0)
|
||||
|
||||
csrrw ra, CSR_JALMNXTI, ra
|
||||
|
||||
/* Critical section with interrupts disabled */
|
||||
DISABLE_MIE
|
||||
|
||||
la t0, g_intCount
|
||||
lw t1, 0(t0)
|
||||
li t2, 0x1
|
||||
sub t1, t1, t2
|
||||
sw t1, 0(t0)
|
||||
|
||||
/* Restore the necessary CSR registers */
|
||||
RESTORE_CSR_CONTEXT
|
||||
/* Restore the caller saving registers (context) */
|
||||
RESTORE_CONTEXT
|
||||
|
||||
/* Return to regular code */
|
||||
mret
|
||||
|
||||
/* Default Handler for Exceptions / Interrupts */
|
||||
.global default_intexc_handler
|
||||
Undef_Handler:
|
||||
default_intexc_handler:
|
||||
1:
|
||||
j 1b
|
||||
|
||||
#endif /* _LOS_TRAP_S */
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "los_arch.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "los_arch_context.h"
|
||||
#include "los_task.h"
|
||||
#include "los_debug.h"
|
||||
#include "nuclei_sdk_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
UINT32 g_intCount = 0;
|
||||
|
||||
// LosExcInfo g_excInfo;
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalHwiInit(VOID)
|
||||
{
|
||||
// already setup interrupt vectors
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Function : HalHwiCreate
|
||||
Description : create hardware interrupt
|
||||
Input : hwiNum --- hwi num to create
|
||||
hwiPrio --- priority of the hwi
|
||||
mode --- hwi interrupt mode, between vector or non-vector
|
||||
handler --- hwi handler
|
||||
arg --- set trig mode of the hwi handler
|
||||
Level Triggerred = 0
|
||||
Postive/Rising Edge Triggered = 1
|
||||
Negtive/Falling Edge Triggered = 3
|
||||
Output : None
|
||||
Return : LOS_OK on success or error code on failure
|
||||
*****************************************************************************/
|
||||
UINT32 HalHwiCreate(HWI_HANDLE_T hwiNum,
|
||||
HWI_PRIOR_T hwiPrio,
|
||||
HWI_MODE_T mode,
|
||||
HWI_PROC_FUNC handler,
|
||||
HWI_ARG_T arg)
|
||||
{
|
||||
if (hwiNum > SOC_INT_MAX){
|
||||
return OS_ERRNO_HWI_NUM_INVALID;
|
||||
}
|
||||
if (mode > ECLIC_VECTOR_INTERRUPT){
|
||||
return OS_ERRNO_HWI_MODE_INVALID;
|
||||
}
|
||||
if (arg > ECLIC_NEGTIVE_EDGE_TRIGGER){
|
||||
return OS_ERRNO_HWI_ARG_INVALID;
|
||||
}
|
||||
|
||||
/* set interrupt vector mode */
|
||||
ECLIC_SetShvIRQ(hwiNum, mode);
|
||||
/* set interrupt trigger mode and polarity */
|
||||
ECLIC_SetTrigIRQ(hwiNum, arg);
|
||||
/* set interrupt level */
|
||||
// default to 0
|
||||
ECLIC_SetLevelIRQ(hwiNum, 0);
|
||||
/* set interrupt priority */
|
||||
ECLIC_SetPriorityIRQ(hwiNum, hwiPrio);
|
||||
if (handler != NULL) {
|
||||
/* set interrupt handler entry to vector table */
|
||||
ECLIC_SetVector(hwiNum, (rv_csr_t)handler);
|
||||
}
|
||||
/* enable interrupt */
|
||||
ECLIC_EnableIRQ(hwiNum);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Function : HalHwiDelete
|
||||
Description : Delete hardware interrupt
|
||||
Input : hwiNum --- hwi num to delete
|
||||
Return : LOS_OK on success or error code on failure
|
||||
*****************************************************************************/
|
||||
LITE_OS_SEC_TEXT UINT32 HalHwiDelete(HWI_HANDLE_T hwiNum)
|
||||
{
|
||||
// change func to default func
|
||||
ECLIC_SetVector(hwiNum, HalHwiDefaultHandler);
|
||||
// disable interrupt
|
||||
ECLIC_DisableIRQ(hwiNum);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalHwiDefaultHandler
|
||||
Description : default handler of the hardware interrupt
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_INIT VOID HalHwiDefaultHandler(VOID)
|
||||
{
|
||||
PRINT_ERR("default handler\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalDisplayTaskInfo
|
||||
Description : display the task list
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
VOID HalDisplayTaskInfo(VOID)
|
||||
{
|
||||
TSK_INFO_S taskInfo;
|
||||
UINT32 index;
|
||||
UINT32 ret;
|
||||
|
||||
PRINTK("ID Pri Status name \r\n");
|
||||
PRINTK("-- --- --------- ----\r\n");
|
||||
|
||||
for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT; index++) {
|
||||
ret = LOS_TaskInfoGet(index, &taskInfo);
|
||||
if (ret != LOS_OK) {
|
||||
continue;
|
||||
}
|
||||
PRINTK("%d %d %s %s \r\n",
|
||||
taskInfo.uwTaskID, taskInfo.usTaskPrio, OsConvertTskStatus(taskInfo.usTaskStatus), taskInfo.acName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalUnalignedAccessFix
|
||||
Description : Unaligned acess fixes are not supported by default
|
||||
Input : None
|
||||
Output : None
|
||||
Return : None
|
||||
**************************************************************************** */
|
||||
WEAK UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp)
|
||||
{
|
||||
/* Unaligned acess fixes are not supported by default */
|
||||
PRINTK("Unaligned acess fixes are not support by default!\r\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2021 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* 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 the copyright holder 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.
|
||||
*/
|
||||
|
||||
#include "los_tick.h"
|
||||
#include "los_config.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "nuclei_sdk_hal.h"
|
||||
#include "los_timer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 0
|
||||
|
||||
#define SYSTICK_TICK_CONST (SOC_TIMER_FREQ / LOSCFG_BASE_CORE_TICK_PER_SECOND)
|
||||
|
||||
static OS_TICK_HANDLER systick_handler = (OS_TICK_HANDLER)NULL;
|
||||
|
||||
extern UINT32 g_intCount;
|
||||
|
||||
WEAK UINT32 HalTickStart(OS_TICK_HANDLER handler)
|
||||
{
|
||||
SysTick_Config(SYSTICK_TICK_CONST);
|
||||
ECLIC_DisableIRQ(SysTimer_IRQn);
|
||||
ECLIC_SetLevelIRQ(SysTimer_IRQn, configKERNEL_INTERRUPT_PRIORITY);
|
||||
ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
|
||||
ECLIC_EnableIRQ(SysTimer_IRQn);
|
||||
|
||||
/* Set SWI interrupt level to lowest level/priority, SysTimerSW as Vector Interrupt */
|
||||
ECLIC_SetShvIRQ(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT);
|
||||
ECLIC_SetLevelIRQ(SysTimerSW_IRQn, configKERNEL_INTERRUPT_PRIORITY);
|
||||
ECLIC_EnableIRQ(SysTimerSW_IRQn);
|
||||
g_sysClock = SystemCoreClock;
|
||||
g_cyclesPerTick = g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||
g_intCount = 0;
|
||||
g_ullTickCount = 0;
|
||||
|
||||
systick_handler = handler;
|
||||
|
||||
return LOS_OK; /* never return */
|
||||
}
|
||||
|
||||
#define HalTickSysTickHandler eclic_mtip_handler
|
||||
|
||||
void HalTickSysTickHandler( void )
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
|
||||
SysTick_Reload(SYSTICK_TICK_CONST);
|
||||
/* Do systick handler. */
|
||||
if ((void *)systick_handler != NULL) {
|
||||
systick_handler();
|
||||
}
|
||||
|
||||
LOS_IntRestore(intSave);
|
||||
}
|
||||
/* ****************************************************************************
|
||||
Function : HalGetCpuCycle
|
||||
Description : Get System cycle count
|
||||
Input : none
|
||||
output : cntHi --- CpuTick High 4 byte
|
||||
cntLo --- CpuTick Low 4 byte
|
||||
return : none
|
||||
**************************************************************************** */
|
||||
LITE_OS_SEC_TEXT_MINOR VOID HalGetCpuCycle(UINT32 *cntHi, UINT32 *cntLo)
|
||||
{
|
||||
volatile uint32_t high0, low, high;
|
||||
|
||||
high0 = __RV_CSR_READ(CSR_MCYCLEH);
|
||||
low = __RV_CSR_READ(CSR_MCYCLE);
|
||||
high = __RV_CSR_READ(CSR_MCYCLEH);
|
||||
if (high0 != high) {
|
||||
low = __RV_CSR_READ(CSR_MCYCLE);
|
||||
}
|
||||
*cntHi = high;
|
||||
*cntLo = low;
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK VOID HalDelay(UINT32 ticks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK UINT64 HalGetExpandTick(VOID)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
WEAK INT32 HalGetRtcTime(UINT64 *usec)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
WEAK INT32 HalGetRtcTimeZone(INT32 *timeZone)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
WEAK INT32 HalSetRtcTime(UINT64 utcTime, UINT64 *usec)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
WEAK INT32 HalSetRtcTimeZone(INT32 timeZone)
|
||||
{
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CORE_COMPATIABLE_H__
|
||||
#define __CORE_COMPATIABLE_H__
|
||||
/*!
|
||||
* @file core_compatiable.h
|
||||
* @brief ARM compatiable function definitions header file
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ===== ARM Compatiable Functions ===== */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_ARMCompatiable_Functions ARM Compatiable Functions
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief A few functions that compatiable with ARM CMSIS-Core.
|
||||
* \details
|
||||
*
|
||||
* Here we provided a few functions that compatiable with ARM CMSIS-Core,
|
||||
* mostly used in the DSP and NN library.
|
||||
* @{
|
||||
*/
|
||||
/** \brief Instruction Synchronization Barrier, compatiable with ARM */
|
||||
#define __ISB() __RWMB()
|
||||
|
||||
/** \brief Data Synchronization Barrier, compatiable with ARM */
|
||||
#define __DSB() __RWMB()
|
||||
|
||||
/** \brief Data Memory Barrier, compatiable with ARM */
|
||||
#define __DMB() __RWMB()
|
||||
|
||||
/** \brief LDRT Unprivileged (8 bit), ARM Compatiable */
|
||||
#define __LDRBT(ptr) __LB((ptr))
|
||||
/** \brief LDRT Unprivileged (16 bit), ARM Compatiable */
|
||||
#define __LDRHT(ptr) __LH((ptr))
|
||||
/** \brief LDRT Unprivileged (32 bit), ARM Compatiable */
|
||||
#define __LDRT(ptr) __LW((ptr))
|
||||
|
||||
/** \brief STRT Unprivileged (8 bit), ARM Compatiable */
|
||||
#define __STRBT(val, ptr) __SB((ptr), (val))
|
||||
/** \brief STRT Unprivileged (16 bit), ARM Compatiable */
|
||||
#define __STRHT(val, ptr) __SH((ptr), (val))
|
||||
/** \brief STRT Unprivileged (32 bit), ARM Compatiable */
|
||||
#define __STRT(val, ptr) __SW((ptr), (val))
|
||||
|
||||
/* ===== Saturation Operations ===== */
|
||||
/**
|
||||
* \brief Signed Saturate
|
||||
* \details Saturates a signed value.
|
||||
* \param [in] value Value to be saturated
|
||||
* \param [in] sat Bit position to saturate to (1..32)
|
||||
* \return Saturated value
|
||||
*/
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1)
|
||||
#define __SSAT(val, sat) __RV_SCLIP32((val), (sat-1))
|
||||
#else
|
||||
__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U)) {
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max) {
|
||||
return max;
|
||||
} else if (val < min) {
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unsigned Saturate
|
||||
* \details Saturates an unsigned value.
|
||||
* \param [in] value Value to be saturated
|
||||
* \param [in] sat Bit position to saturate to (0..31)
|
||||
* \return Saturated value
|
||||
*/
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1)
|
||||
#define __USAT(val, sat) __RV_UCLIP32((val), (sat))
|
||||
#else
|
||||
__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U) {
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max) {
|
||||
return max;
|
||||
} else if (val < 0) {
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ===== Data Processing Operations ===== */
|
||||
/**
|
||||
* \brief Reverse byte order (32 bit)
|
||||
* \details Reverses the byte order in unsigned integer value.
|
||||
* For example, 0x12345678 becomes 0x78563412.
|
||||
* \param [in] value Value to reverse
|
||||
* \return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = ((value & 0xff000000) >> 24)
|
||||
| ((value & 0x00ff0000) >> 8 )
|
||||
| ((value & 0x0000ff00) << 8 )
|
||||
| ((value & 0x000000ff) << 24);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reverse byte order (16 bit)
|
||||
* \details Reverses the byte order within each halfword of a word.
|
||||
* For example, 0x12345678 becomes 0x34127856.
|
||||
* \param [in] value Value to reverse
|
||||
* \return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
result = ((value & 0xff000000) >> 8)
|
||||
| ((value & 0x00ff00000) << 8 )
|
||||
| ((value & 0x0000ff00) >> 8 )
|
||||
| ((value & 0x000000ff) << 8) ;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reverse byte order (16 bit)
|
||||
* \details Reverses the byte order in a 16-bit value
|
||||
* and returns the signed 16-bit result.
|
||||
* For example, 0x0080 becomes 0x8000.
|
||||
* \param [in] value Value to reverse
|
||||
* \return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
|
||||
{
|
||||
int16_t result;
|
||||
result = ((value & 0xff00) >> 8) | ((value & 0x00ff) << 8);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Rotate Right in unsigned value (32 bit)
|
||||
* \details Rotate Right (immediate) provides the value of
|
||||
* the contents of a register rotated by a variable number of bits.
|
||||
* \param [in] op1 Value to rotate
|
||||
* \param [in] op2 Number of Bits to rotate(0-31)
|
||||
* \return Rotated value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
op2 = op2 & 0x1F;
|
||||
if (op2 == 0U) {
|
||||
return op1;
|
||||
}
|
||||
return (op1 >> op2) | (op1 << (32U - op2));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reverse bit order of value
|
||||
* \details Reverses the bit order of the given value.
|
||||
* \param [in] value Value to reverse
|
||||
* \return Reversed value
|
||||
*/
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1)
|
||||
#define __RBIT(value) __RV_BITREVI((value), 31)
|
||||
#else
|
||||
__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value != 0U; value >>= 1U) {
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
return result;
|
||||
}
|
||||
#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */
|
||||
|
||||
/**
|
||||
* \brief Count leading zeros
|
||||
* \details Counts the number of leading zeros of a data value.
|
||||
* \param [in] data Value to count the leading zeros
|
||||
* \return number of leading zeros in value
|
||||
*/
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1)
|
||||
#define __CLZ(data) __RV_CLZ32(data)
|
||||
#else
|
||||
__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint32_t temp = ~data;
|
||||
while (temp & 0x80000000) {
|
||||
temp <<= 1;
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* defined(__DSP_PRESENT) && (__DSP_PRESENT == 1) */
|
||||
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_ARMCompatiable_Functions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __CORE_COMPATIABLE_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CORE_FEATURE_CACHE_H__
|
||||
#define __CORE_FEATURE_CACHE_H__
|
||||
/*!
|
||||
* @file core_feature_cache.h
|
||||
* @brief Cache feature API header file for Nuclei N/NX Core
|
||||
*/
|
||||
/*
|
||||
* Cache Feature Configuration Macro:
|
||||
* 1. __ICACHE_PRESENT: Define whether I-Cache Unit is present or not.
|
||||
* * 0: Not present
|
||||
* * 1: Present
|
||||
* 1. __DCACHE_PRESENT: Define whether D-Cache Unit is present or not.
|
||||
* * 0: Not present
|
||||
* * 1: Present
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1)
|
||||
|
||||
/* ########################## Cache functions #################################### */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_Cache Cache Functions
|
||||
* \brief Functions that configure Instruction and Data Cache.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_Cache */
|
||||
|
||||
/**
|
||||
* \defgroup NMSIS_Core_ICache I-Cache Functions
|
||||
* \ingroup NMSIS_Core_Cache
|
||||
* \brief Functions that configure Instruction Cache.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Enable ICache
|
||||
* \details
|
||||
* This function enable I-Cache
|
||||
* \remarks
|
||||
* - This \ref CSR_MCACHE_CTL register control I Cache enable.
|
||||
* \sa
|
||||
* - \ref DisableICache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void EnableICache (void)
|
||||
{
|
||||
__RV_CSR_SET(CSR_MCACHE_CTL, CSR_MCACHE_CTL_IE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable ICache
|
||||
* \details
|
||||
* This function Disable I-Cache
|
||||
* \remarks
|
||||
* - This \ref CSR_MCACHE_CTL register control I Cache enable.
|
||||
* \sa
|
||||
* - \ref EnableICache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void DisableICache (void)
|
||||
{
|
||||
__RV_CSR_CLEAR(CSR_MCACHE_CTL, CSR_MCACHE_CTL_IE);
|
||||
}
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_ICache */
|
||||
#endif /* defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1) */
|
||||
|
||||
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1)
|
||||
/**
|
||||
* \defgroup NMSIS_Core_DCache D-Cache Functions
|
||||
* \ingroup NMSIS_Core_Cache
|
||||
* \brief Functions that configure Data Cache.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Enable DCache
|
||||
* \details
|
||||
* This function enable D-Cache
|
||||
* \remarks
|
||||
* - This \ref CSR_MCACHE_CTL register control D Cache enable.
|
||||
* \sa
|
||||
* - \ref DisableDCache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void EnableDCache (void)
|
||||
{
|
||||
__RV_CSR_SET(CSR_MCACHE_CTL, CSR_MCACHE_CTL_DE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable DCache
|
||||
* \details
|
||||
* This function Disable D-Cache
|
||||
* \remarks
|
||||
* - This \ref CSR_MCACHE_CTL register control D Cache enable.
|
||||
* \sa
|
||||
* - \ref EnableDCache
|
||||
*/
|
||||
__STATIC_FORCEINLINE void DisableDCache (void)
|
||||
{
|
||||
__RV_CSR_CLEAR(CSR_MCACHE_CTL, CSR_MCACHE_CTL_DE);
|
||||
}
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_DCache */
|
||||
#endif /* defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /** __CORE_FEATURE_CACHE_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,897 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CORE_FEATURE_ECLIC__
|
||||
#define __CORE_FEATURE_ECLIC__
|
||||
/*!
|
||||
* @file core_feature_eclic.h
|
||||
* @brief ECLIC feature API header file for Nuclei N/NX Core
|
||||
*/
|
||||
/*
|
||||
* ECLIC Feature Configuration Macro:
|
||||
* 1. __ECLIC_PRESENT: Define whether Enhanced Core Local Interrupt Controller (ECLIC) Unit is present or not
|
||||
* * 0: Not present
|
||||
* * 1: Present
|
||||
* 2. __ECLIC_BASEADDR: Base address of the ECLIC unit.
|
||||
* 3. ECLIC_GetInfoCtlbits(): Define the number of hardware bits are actually implemented in the clicintctl registers.
|
||||
* Valid number is 1 - 8.
|
||||
* 4. __ECLIC_INTNUM : Define the external interrupt number of ECLIC Unit
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
|
||||
/**
|
||||
* \defgroup NMSIS_Core_ECLIC_Registers Register Define and Type Definitions Of ECLIC
|
||||
* \ingroup NMSIS_Core_Registers
|
||||
* \brief Type definitions and defines for eclic registers.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Union type to access CLICFG configure register.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint8_t _reserved0:1; /*!< bit: 0 Overflow condition code flag */
|
||||
uint8_t nlbits:4; /*!< bit: 29 Carry condition code flag */
|
||||
uint8_t _reserved1:2; /*!< bit: 30 Zero condition code flag */
|
||||
uint8_t _reserved2:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint8_t w; /*!< Type used for byte access */
|
||||
} CLICCFG_Type;
|
||||
|
||||
/**
|
||||
* \brief Union type to access CLICINFO information register.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t numint:13; /*!< bit: 0..12 number of maximum interrupt inputs supported */
|
||||
uint32_t version:8; /*!< bit: 13..20 20:17 for architecture version,16:13 for implementation version */
|
||||
uint32_t intctlbits:4; /*!< bit: 21..24 specifies how many hardware bits are actually implemented in the clicintctl registers */
|
||||
uint32_t _reserved0:7; /*!< bit: 25..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CLICINFO_Type;
|
||||
|
||||
/**
|
||||
* \brief Access to the structure of a vector interrupt controller.
|
||||
*/
|
||||
typedef struct {
|
||||
__IOM uint8_t INTIP; /*!< Offset: 0x000 (R/W) Interrupt set pending register */
|
||||
__IOM uint8_t INTIE; /*!< Offset: 0x001 (R/W) Interrupt set enable register */
|
||||
__IOM uint8_t INTATTR; /*!< Offset: 0x002 (R/W) Interrupt set attributes register */
|
||||
__IOM uint8_t INTCTRL; /*!< Offset: 0x003 (R/W) Interrupt configure register */
|
||||
} CLIC_CTRL_Type;
|
||||
|
||||
typedef struct {
|
||||
__IOM uint8_t CFG; /*!< Offset: 0x000 (R/W) CLIC configuration register */
|
||||
uint8_t RESERVED0[3];
|
||||
__IM uint32_t INFO; /*!< Offset: 0x004 (R/ ) CLIC information register */
|
||||
uint8_t RESERVED1[3];
|
||||
__IOM uint8_t MTH; /*!< Offset: 0x00B (R/W) CLIC machine mode threshold register */
|
||||
uint32_t RESERVED2[0x3FD];
|
||||
CLIC_CTRL_Type CTRL[4096]; /*!< Offset: 0x1000 (R/W) CLIC register structure for INTIP, INTIE, INTATTR, INTCTL */
|
||||
} CLIC_Type;
|
||||
|
||||
#define CLIC_CLICCFG_NLBIT_Pos 1U /*!< CLIC CLICCFG: NLBIT Position */
|
||||
#define CLIC_CLICCFG_NLBIT_Msk (0xFUL << CLIC_CLICCFG_NLBIT_Pos) /*!< CLIC CLICCFG: NLBIT Mask */
|
||||
|
||||
#define CLIC_CLICINFO_CTLBIT_Pos 21U /*!< CLIC INTINFO: __ECLIC_GetInfoCtlbits() Position */
|
||||
#define CLIC_CLICINFO_CTLBIT_Msk (0xFUL << CLIC_CLICINFO_CTLBIT_Pos) /*!< CLIC INTINFO: __ECLIC_GetInfoCtlbits() Mask */
|
||||
|
||||
#define CLIC_CLICINFO_VER_Pos 13U /*!< CLIC CLICINFO: VERSION Position */
|
||||
#define CLIC_CLICINFO_VER_Msk (0xFFUL << CLIC_CLICCFG_NLBIT_Pos) /*!< CLIC CLICINFO: VERSION Mask */
|
||||
|
||||
#define CLIC_CLICINFO_NUM_Pos 0U /*!< CLIC CLICINFO: NUM Position */
|
||||
#define CLIC_CLICINFO_NUM_Msk (0xFFFUL << CLIC_CLICINFO_NUM_Pos) /*!< CLIC CLICINFO: NUM Mask */
|
||||
|
||||
#define CLIC_INTIP_IP_Pos 0U /*!< CLIC INTIP: IP Position */
|
||||
#define CLIC_INTIP_IP_Msk (0x1UL << CLIC_INTIP_IP_Pos) /*!< CLIC INTIP: IP Mask */
|
||||
|
||||
#define CLIC_INTIE_IE_Pos 0U /*!< CLIC INTIE: IE Position */
|
||||
#define CLIC_INTIE_IE_Msk (0x1UL << CLIC_INTIE_IE_Pos) /*!< CLIC INTIE: IE Mask */
|
||||
|
||||
#define CLIC_INTATTR_TRIG_Pos 1U /*!< CLIC INTATTR: TRIG Position */
|
||||
#define CLIC_INTATTR_TRIG_Msk (0x3UL << CLIC_INTATTR_TRIG_Pos) /*!< CLIC INTATTR: TRIG Mask */
|
||||
|
||||
#define CLIC_INTATTR_SHV_Pos 0U /*!< CLIC INTATTR: SHV Position */
|
||||
#define CLIC_INTATTR_SHV_Msk (0x1UL << CLIC_INTATTR_SHV_Pos) /*!< CLIC INTATTR: SHV Mask */
|
||||
|
||||
#define ECLIC_MAX_NLBITS 8U /*!< Max nlbit of the CLICINTCTLBITS */
|
||||
#define ECLIC_MODE_MTVEC_Msk 3U /*!< ECLIC Mode mask for MTVT CSR Register */
|
||||
|
||||
#define ECLIC_NON_VECTOR_INTERRUPT 0x0 /*!< Non-Vector Interrupt Mode of ECLIC */
|
||||
#define ECLIC_VECTOR_INTERRUPT 0x1 /*!< Vector Interrupt Mode of ECLIC */
|
||||
|
||||
/**\brief ECLIC Trigger Enum for different Trigger Type */
|
||||
typedef enum ECLIC_TRIGGER {
|
||||
ECLIC_LEVEL_TRIGGER = 0x0, /*!< Level Triggerred, trig[0] = 0 */
|
||||
ECLIC_POSTIVE_EDGE_TRIGGER = 0x1, /*!< Postive/Rising Edge Triggered, trig[1] = 0, trig[0] = 1 */
|
||||
ECLIC_NEGTIVE_EDGE_TRIGGER = 0x3, /*!< Negtive/Falling Edge Triggered, trig[1] = 1, trig[0] = 0 */
|
||||
ECLIC_MAX_TRIGGER = 0x3 /*!< MAX Supported Trigger Mode */
|
||||
} ECLIC_TRIGGER_Type;
|
||||
|
||||
#ifndef __ECLIC_BASEADDR
|
||||
/* Base address of ECLIC(__ECLIC_BASEADDR) should be defined in <Device.h> */
|
||||
#error "__ECLIC_BASEADDR is not defined, please check!"
|
||||
#endif
|
||||
|
||||
#ifndef __ECLIC_INTCTLBITS
|
||||
/* Define __ECLIC_INTCTLBITS to get via ECLIC->INFO if not defined */
|
||||
#define __ECLIC_INTCTLBITS (__ECLIC_GetInfoCtlbits())
|
||||
#endif
|
||||
|
||||
/* ECLIC Memory mapping of Device */
|
||||
#define ECLIC_BASE __ECLIC_BASEADDR /*!< ECLIC Base Address */
|
||||
#define ECLIC ((CLIC_Type *) ECLIC_BASE) /*!< CLIC configuration struct */
|
||||
|
||||
/** @} */ /* end of group NMSIS_Core_ECLIC_Registers */
|
||||
|
||||
/* ########################## ECLIC functions #################################### */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_IntExc Interrupts and Exceptions
|
||||
* \brief Functions that manage interrupts and exceptions via the ECLIC.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Definition of IRQn numbers
|
||||
* \details
|
||||
* The core interrupt enumeration names for IRQn values are defined in the file <b><Device>.h</b>.
|
||||
* - Interrupt ID(IRQn) from 0 to 18 are reserved for core internal interrupts.
|
||||
* - Interrupt ID(IRQn) start from 19 represent device-specific external interrupts.
|
||||
* - The first device-specific interrupt has the IRQn value 19.
|
||||
*
|
||||
* The table below describes the core interrupt names and their availability in various Nuclei Cores.
|
||||
*/
|
||||
/* The following enum IRQn definition in this file
|
||||
* is only used for doxygen documentation generation,
|
||||
* The <Device>.h is the real file to define it by vendor
|
||||
*/
|
||||
#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__)
|
||||
typedef enum IRQn {
|
||||
/* ========= Nuclei N/NX Core Specific Interrupt Numbers =========== */
|
||||
/* Core Internal Interrupt IRQn definitions */
|
||||
Reserved0_IRQn = 0, /*!< Internal reserved */
|
||||
Reserved1_IRQn = 1, /*!< Internal reserved */
|
||||
Reserved2_IRQn = 2, /*!< Internal reserved */
|
||||
SysTimerSW_IRQn = 3, /*!< System Timer SW interrupt */
|
||||
Reserved3_IRQn = 4, /*!< Internal reserved */
|
||||
Reserved4_IRQn = 5, /*!< Internal reserved */
|
||||
Reserved5_IRQn = 6, /*!< Internal reserved */
|
||||
SysTimer_IRQn = 7, /*!< System Timer Interrupt */
|
||||
Reserved6_IRQn = 8, /*!< Internal reserved */
|
||||
Reserved7_IRQn = 9, /*!< Internal reserved */
|
||||
Reserved8_IRQn = 10, /*!< Internal reserved */
|
||||
Reserved9_IRQn = 11, /*!< Internal reserved */
|
||||
Reserved10_IRQn = 12, /*!< Internal reserved */
|
||||
Reserved11_IRQn = 13, /*!< Internal reserved */
|
||||
Reserved12_IRQn = 14, /*!< Internal reserved */
|
||||
Reserved13_IRQn = 15, /*!< Internal reserved */
|
||||
Reserved14_IRQn = 16, /*!< Internal reserved */
|
||||
Reserved15_IRQn = 17, /*!< Internal reserved */
|
||||
Reserved16_IRQn = 18, /*!< Internal reserved */
|
||||
|
||||
/* ========= Device Specific Interrupt Numbers =================== */
|
||||
/* ToDo: add here your device specific external interrupt numbers.
|
||||
* 19~max(NUM_INTERRUPT, 1023) is reserved number for user.
|
||||
* Maxmum interrupt supported could get from clicinfo.NUM_INTERRUPT.
|
||||
* According the interrupt handlers defined in startup_Device.S
|
||||
* eg.: Interrupt for Timer#1 eclic_tim1_handler -> TIM1_IRQn */
|
||||
FirstDeviceSpecificInterrupt_IRQn = 19, /*!< First Device Specific Interrupt */
|
||||
SOC_INT_MAX, /*!< Number of total interrupts */
|
||||
} IRQn_Type;
|
||||
#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */
|
||||
|
||||
#ifdef NMSIS_ECLIC_VIRTUAL
|
||||
#ifndef NMSIS_ECLIC_VIRTUAL_HEADER_FILE
|
||||
#define NMSIS_ECLIC_VIRTUAL_HEADER_FILE "nmsis_eclic_virtual.h"
|
||||
#endif
|
||||
#include NMSIS_ECLIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define ECLIC_SetCfgNlbits __ECLIC_SetCfgNlbits
|
||||
#define ECLIC_GetCfgNlbits __ECLIC_GetCfgNlbits
|
||||
#define ECLIC_GetInfoVer __ECLIC_GetInfoVer
|
||||
#define ECLIC_GetInfoCtlbits __ECLIC_GetInfoCtlbits
|
||||
#define ECLIC_GetInfoNum __ECLIC_GetInfoNum
|
||||
#define ECLIC_SetMth __ECLIC_SetMth
|
||||
#define ECLIC_GetMth __ECLIC_GetMth
|
||||
#define ECLIC_EnableIRQ __ECLIC_EnableIRQ
|
||||
#define ECLIC_GetEnableIRQ __ECLIC_GetEnableIRQ
|
||||
#define ECLIC_DisableIRQ __ECLIC_DisableIRQ
|
||||
#define ECLIC_SetPendingIRQ __ECLIC_SetPendingIRQ
|
||||
#define ECLIC_GetPendingIRQ __ECLIC_GetPendingIRQ
|
||||
#define ECLIC_ClearPendingIRQ __ECLIC_ClearPendingIRQ
|
||||
#define ECLIC_SetTrigIRQ __ECLIC_SetTrigIRQ
|
||||
#define ECLIC_GetTrigIRQ __ECLIC_GetTrigIRQ
|
||||
#define ECLIC_SetShvIRQ __ECLIC_SetShvIRQ
|
||||
#define ECLIC_GetShvIRQ __ECLIC_GetShvIRQ
|
||||
#define ECLIC_SetCtrlIRQ __ECLIC_SetCtrlIRQ
|
||||
#define ECLIC_GetCtrlIRQ __ECLIC_GetCtrlIRQ
|
||||
#define ECLIC_SetLevelIRQ __ECLIC_SetLevelIRQ
|
||||
#define ECLIC_GetLevelIRQ __ECLIC_GetLevelIRQ
|
||||
#define ECLIC_SetPriorityIRQ __ECLIC_SetPriorityIRQ
|
||||
#define ECLIC_GetPriorityIRQ __ECLIC_GetPriorityIRQ
|
||||
|
||||
#endif /* NMSIS_ECLIC_VIRTUAL */
|
||||
|
||||
#ifdef NMSIS_VECTAB_VIRTUAL
|
||||
#ifndef NMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define NMSIS_VECTAB_VIRTUAL_HEADER_FILE "nmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include NMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define ECLIC_SetVector __ECLIC_SetVector
|
||||
#define ECLIC_GetVector __ECLIC_GetVector
|
||||
#endif /* (NMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
/**
|
||||
* \brief Set nlbits value
|
||||
* \details
|
||||
* This function set the nlbits value of CLICCFG register.
|
||||
* \param [in] nlbits nlbits value
|
||||
* \remarks
|
||||
* - nlbits is used to set the width of level in the CLICINTCTL[i].
|
||||
* \sa
|
||||
* - \ref ECLIC_GetCfgNlbits
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetCfgNlbits(uint32_t nlbits)
|
||||
{
|
||||
ECLIC->CFG &= ~CLIC_CLICCFG_NLBIT_Msk;
|
||||
ECLIC->CFG |= (uint8_t)((nlbits <<CLIC_CLICCFG_NLBIT_Pos) & CLIC_CLICCFG_NLBIT_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get nlbits value
|
||||
* \details
|
||||
* This function get the nlbits value of CLICCFG register.
|
||||
* \return nlbits value of CLICCFG register
|
||||
* \remarks
|
||||
* - nlbits is used to set the width of level in the CLICINTCTL[i].
|
||||
* \sa
|
||||
* - \ref ECLIC_SetCfgNlbits
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetCfgNlbits(void)
|
||||
{
|
||||
return ((uint32_t)((ECLIC->CFG & CLIC_CLICCFG_NLBIT_Msk) >> CLIC_CLICCFG_NLBIT_Pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the ECLIC version number
|
||||
* \details
|
||||
* This function gets the hardware version information from CLICINFO register.
|
||||
* \return hardware version number in CLICINFO register.
|
||||
* \remarks
|
||||
* - This function gets harware version information from CLICINFO register.
|
||||
* - Bit 20:17 for architecture version, bit 16:13 for implementation version.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetInfoNum
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoVer(void)
|
||||
{
|
||||
return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_VER_Msk) >> CLIC_CLICINFO_VER_Pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get CLICINTCTLBITS
|
||||
* \details
|
||||
* This function gets CLICINTCTLBITS from CLICINFO register.
|
||||
* \return CLICINTCTLBITS from CLICINFO register.
|
||||
* \remarks
|
||||
* - In the CLICINTCTL[i] registers, with 2 <= CLICINTCTLBITS <= 8.
|
||||
* - The implemented bits are kept left-justified in the most-significant bits of each 8-bit
|
||||
* CLICINTCTL[I] register, with the lower unimplemented bits treated as hardwired to 1.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetInfoNum
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoCtlbits(void)
|
||||
{
|
||||
return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_CTLBIT_Msk) >> CLIC_CLICINFO_CTLBIT_Pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get number of maximum interrupt inputs supported
|
||||
* \details
|
||||
* This function gets number of maximum interrupt inputs supported from CLICINFO register.
|
||||
* \return number of maximum interrupt inputs supported from CLICINFO register.
|
||||
* \remarks
|
||||
* - This function gets number of maximum interrupt inputs supported from CLICINFO register.
|
||||
* - The num_interrupt field specifies the actual number of maximum interrupt inputs supported in this implementation.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetInfoCtlbits
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetInfoNum(void)
|
||||
{
|
||||
return ((uint32_t)((ECLIC->INFO & CLIC_CLICINFO_NUM_Msk) >> CLIC_CLICINFO_NUM_Pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set Machine Mode Interrupt Level Threshold
|
||||
* \details
|
||||
* This function sets machine mode interrupt level threshold.
|
||||
* \param [in] mth Interrupt Level Threshold.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetMth
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetMth(uint8_t mth)
|
||||
{
|
||||
ECLIC->MTH = mth;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get Machine Mode Interrupt Level Threshold
|
||||
* \details
|
||||
* This function gets machine mode interrupt level threshold.
|
||||
* \return Interrupt Level Threshold.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetMth
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint8_t __ECLIC_GetMth(void)
|
||||
{
|
||||
return (ECLIC->MTH);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Enable a specific interrupt
|
||||
* \details
|
||||
* This function enables the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_DisableIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get a specific interrupt enable status
|
||||
* \details
|
||||
* This function returns the interrupt enable status for the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \returns
|
||||
* - 0 Interrupt is not enabled
|
||||
* - 1 Interrupt is pending
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_EnableIRQ
|
||||
* - \ref ECLIC_DisableIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t) (ECLIC->CTRL[IRQn].INTIE) & CLIC_INTIE_IE_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable a specific interrupt
|
||||
* \details
|
||||
* This function disables the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Number of the external interrupt to disable
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_EnableIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTIE &= ~CLIC_INTIE_IE_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the pending specific interrupt
|
||||
* \details
|
||||
* This function returns the pending status of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \returns
|
||||
* - 0 Interrupt is not pending
|
||||
* - 1 Interrupt is pending
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetPendingIRQ
|
||||
* - \ref ECLIC_ClearPendingIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE int32_t __ECLIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return((uint32_t)(ECLIC->CTRL[IRQn].INTIP) & CLIC_INTIP_IP_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set a specific interrupt to pending
|
||||
* \details
|
||||
* This function sets the pending bit for the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetPendingIRQ
|
||||
* - \ref ECLIC_ClearPendingIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTIP |= CLIC_INTIP_IP_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear a specific interrupt from pending
|
||||
* \details
|
||||
* This function removes the pending state of the specific interrupt \em IRQn.
|
||||
* \em IRQn cannot be a negative number.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetPendingIRQ
|
||||
* - \ref ECLIC_GetPendingIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTIP &= ~ CLIC_INTIP_IP_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set trigger mode and polarity for a specific interrupt
|
||||
* \details
|
||||
* This function set trigger mode and polarity of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \param [in] trig
|
||||
* - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER
|
||||
* - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER
|
||||
* - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER
|
||||
* - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
*
|
||||
* \sa
|
||||
* - \ref ECLIC_GetTrigIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetTrigIRQ(IRQn_Type IRQn, uint32_t trig)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_TRIG_Msk;
|
||||
ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(trig<<CLIC_INTATTR_TRIG_Pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get trigger mode and polarity for a specific interrupt
|
||||
* \details
|
||||
* This function get trigger mode and polarity of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \return
|
||||
* - 00 level trigger, \ref ECLIC_LEVEL_TRIGGER
|
||||
* - 01 positive edge trigger, \ref ECLIC_POSTIVE_EDGE_TRIGGER
|
||||
* - 02 level trigger, \ref ECLIC_LEVEL_TRIGGER
|
||||
* - 03 negative edge trigger, \ref ECLIC_NEGTIVE_EDGE_TRIGGER
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetTrigIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetTrigIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return ((int32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_TRIG_Msk)>>CLIC_INTATTR_TRIG_Pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set interrupt working mode for a specific interrupt
|
||||
* \details
|
||||
* This function set selective hardware vector or non-vector working mode of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \param [in] shv
|
||||
* - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT
|
||||
* - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetShvIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk;
|
||||
ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(shv<<CLIC_INTATTR_SHV_Pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get interrupt working mode for a specific interrupt
|
||||
* \details
|
||||
* This function get selective hardware vector or non-vector working mode of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \return shv
|
||||
* - 0 non-vector mode, \ref ECLIC_NON_VECTOR_INTERRUPT
|
||||
* - 1 vector mode, \ref ECLIC_VECTOR_INTERRUPT
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetShvIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ECLIC_GetShvIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return ((int32_t)(((ECLIC->CTRL[IRQn].INTATTR) & CLIC_INTATTR_SHV_Msk)>>CLIC_INTATTR_SHV_Pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Modify ECLIC Interrupt Input Control Register for a specific interrupt
|
||||
* \details
|
||||
* This function modify ECLIC Interrupt Input Control(CLICINTCTL[i]) register of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \param [in] intctrl Set value for CLICINTCTL[i] register
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetCtrlIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl)
|
||||
{
|
||||
ECLIC->CTRL[IRQn].INTCTRL = intctrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get ECLIC Interrupt Input Control Register value for a specific interrupt
|
||||
* \details
|
||||
* This function modify ECLIC Interrupt Input Control register of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \return value of ECLIC Interrupt Input Control register
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetCtrlIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint8_t __ECLIC_GetCtrlIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
return (ECLIC->CTRL[IRQn].INTCTRL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set ECLIC Interrupt level of a specific interrupt
|
||||
* \details
|
||||
* This function set interrupt level of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \param [in] lvl_abs Interrupt level
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* - If lvl_abs to be set is larger than the max level allowed, it will be force to be max level.
|
||||
* - When you set level value you need use clciinfo.nlbits to get the width of level.
|
||||
* Then we could know the maximum of level. CLICINTCTLBITS is how many total bits are
|
||||
* present in the CLICINTCTL register.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetLevelIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs)
|
||||
{
|
||||
uint8_t nlbits = __ECLIC_GetCfgNlbits();
|
||||
uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
|
||||
|
||||
if (nlbits == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nlbits > intctlbits) {
|
||||
nlbits = intctlbits;
|
||||
}
|
||||
uint8_t maxlvl = ((1 << nlbits) - 1);
|
||||
if (lvl_abs > maxlvl) {
|
||||
lvl_abs = maxlvl;
|
||||
}
|
||||
uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits);
|
||||
uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn);
|
||||
cur_ctrl = cur_ctrl << nlbits;
|
||||
cur_ctrl = cur_ctrl >> nlbits;
|
||||
__ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | lvl));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get ECLIC Interrupt level of a specific interrupt
|
||||
* \details
|
||||
* This function get interrupt level of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \return Interrupt level
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetLevelIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint8_t __ECLIC_GetLevelIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
uint8_t nlbits = __ECLIC_GetCfgNlbits();
|
||||
uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
|
||||
|
||||
if (nlbits == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nlbits > intctlbits) {
|
||||
nlbits = intctlbits;
|
||||
}
|
||||
uint8_t intctrl = __ECLIC_GetCtrlIRQ(IRQn);
|
||||
uint8_t lvl_abs = intctrl >> (ECLIC_MAX_NLBITS - nlbits);
|
||||
return lvl_abs;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get ECLIC Interrupt priority of a specific interrupt
|
||||
* \details
|
||||
* This function get interrupt priority of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \param [in] pri Interrupt priority
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* - If pri to be set is larger than the max priority allowed, it will be force to be max priority.
|
||||
* - Priority width is CLICINTCTLBITS minus clciinfo.nlbits if clciinfo.nlbits
|
||||
* is less than CLICINTCTLBITS. Otherwise priority width is 0.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetPriorityIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetPriorityIRQ(IRQn_Type IRQn, uint8_t pri)
|
||||
{
|
||||
uint8_t nlbits = __ECLIC_GetCfgNlbits();
|
||||
uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
|
||||
if (nlbits < intctlbits) {
|
||||
uint8_t maxpri = ((1 << (intctlbits - nlbits)) - 1);
|
||||
if (pri > maxpri) {
|
||||
pri = maxpri;
|
||||
}
|
||||
pri = pri << (ECLIC_MAX_NLBITS - intctlbits);
|
||||
uint8_t mask = ((uint8_t)(-1)) >> intctlbits;
|
||||
pri = pri | mask;
|
||||
uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn);
|
||||
cur_ctrl = cur_ctrl >> (ECLIC_MAX_NLBITS - nlbits);
|
||||
cur_ctrl = cur_ctrl << (ECLIC_MAX_NLBITS - nlbits);
|
||||
__ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | pri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get ECLIC Interrupt priority of a specific interrupt
|
||||
* \details
|
||||
* This function get interrupt priority of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \return Interrupt priority
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetPriorityIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint8_t __ECLIC_GetPriorityIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
uint8_t nlbits = __ECLIC_GetCfgNlbits();
|
||||
uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
|
||||
if (nlbits < intctlbits) {
|
||||
uint8_t cur_ctrl = __ECLIC_GetCtrlIRQ(IRQn);
|
||||
uint8_t pri = cur_ctrl << nlbits;
|
||||
pri = pri >> nlbits;
|
||||
pri = pri >> (ECLIC_MAX_NLBITS - intctlbits);
|
||||
return pri;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set Interrupt Vector of a specific interrupt
|
||||
* \details
|
||||
* This function set interrupt handler address of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \param [in] vector Interrupt handler address
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* - You can set the \ref CSR_CSR_MTVT to set interrupt vector table entry address.
|
||||
* - If your vector table is placed in readonly section, the vector for IRQn will not be modified.
|
||||
* For this case, you need to use the correct irq handler name defined in your vector table as
|
||||
* your irq handler function name.
|
||||
* - This function will only work correctly when the vector table is placed in an read-write enabled section.
|
||||
* \sa
|
||||
* - \ref ECLIC_GetVector
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ECLIC_SetVector(IRQn_Type IRQn, rv_csr_t vector)
|
||||
{
|
||||
#if __RISCV_XLEN == 32
|
||||
volatile uint32_t vec_base;
|
||||
vec_base = ((uint32_t)__RV_CSR_READ(CSR_MTVT));
|
||||
(* (unsigned long *) (vec_base + ((int32_t)IRQn) * 4)) = vector;
|
||||
#elif __RISCV_XLEN == 64
|
||||
volatile uint64_t vec_base;
|
||||
vec_base = ((uint64_t)__RV_CSR_READ(CSR_MTVT));
|
||||
(* (unsigned long *) (vec_base + ((int32_t)IRQn) * 8)) = vector;
|
||||
#else // TODO Need cover for XLEN=128 case in future
|
||||
volatile uint64_t vec_base;
|
||||
vec_base = ((uint64_t)__RV_CSR_READ(CSR_MTVT));
|
||||
(* (unsigned long *) (vec_base + ((int32_t)IRQn) * 8)) = vector;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get Interrupt Vector of a specific interrupt
|
||||
* \details
|
||||
* This function get interrupt handler address of the specific interrupt \em IRQn.
|
||||
* \param [in] IRQn Interrupt number
|
||||
* \return Interrupt handler address
|
||||
* \remarks
|
||||
* - IRQn must not be negative.
|
||||
* - You can read \ref CSR_CSR_MTVT to get interrupt vector table entry address.
|
||||
* \sa
|
||||
* - \ref ECLIC_SetVector
|
||||
*/
|
||||
__STATIC_FORCEINLINE rv_csr_t __ECLIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
#if __RISCV_XLEN == 32
|
||||
return (*(uint32_t *)(__RV_CSR_READ(CSR_MTVT)+IRQn*4));
|
||||
#elif __RISCV_XLEN == 64
|
||||
return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT)+IRQn*8));
|
||||
#else // TODO Need cover for XLEN=128 case in future
|
||||
return (*(uint64_t *)(__RV_CSR_READ(CSR_MTVT)+IRQn*8));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set Exception entry address
|
||||
* \details
|
||||
* This function set exception handler address to 'CSR_MTVEC'.
|
||||
* \param [in] addr Exception handler address
|
||||
* \remarks
|
||||
* - This function use to set exception handler address to 'CSR_MTVEC'. Address is 4 bytes align.
|
||||
* \sa
|
||||
* - \ref __get_exc_entry
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_exc_entry(rv_csr_t addr)
|
||||
{
|
||||
addr &= (rv_csr_t)(~0x3F);
|
||||
addr |= ECLIC_MODE_MTVEC_Msk;
|
||||
__RV_CSR_WRITE(CSR_MTVEC, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get Exception entry address
|
||||
* \details
|
||||
* This function get exception handler address from 'CSR_MTVEC'.
|
||||
* \return Exception handler address
|
||||
* \remarks
|
||||
* - This function use to get exception handler address from 'CSR_MTVEC'. Address is 4 bytes align
|
||||
* \sa
|
||||
* - \ref __set_exc_entry
|
||||
*/
|
||||
__STATIC_FORCEINLINE rv_csr_t __get_exc_entry(void)
|
||||
{
|
||||
unsigned long addr = __RV_CSR_READ(CSR_MTVEC);
|
||||
return (addr & ~ECLIC_MODE_MTVEC_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set Non-vector interrupt entry address
|
||||
* \details
|
||||
* This function set Non-vector interrupt address.
|
||||
* \param [in] addr Non-vector interrupt entry address
|
||||
* \remarks
|
||||
* - This function use to set non-vector interrupt entry address to 'CSR_MTVT2' if
|
||||
* - CSR_MTVT2 bit0 is 1. If 'CSR_MTVT2' bit0 is 0 then set address to 'CSR_MTVEC'
|
||||
* \sa
|
||||
* - \ref __get_nonvec_entry
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_nonvec_entry(rv_csr_t addr)
|
||||
{
|
||||
if (__RV_CSR_READ(CSR_MTVT2) & 0x1){
|
||||
__RV_CSR_WRITE(CSR_MTVT2, addr | 0x01);
|
||||
} else {
|
||||
addr &= (rv_csr_t)(~0x3F);
|
||||
addr |= ECLIC_MODE_MTVEC_Msk;
|
||||
__RV_CSR_WRITE(CSR_MTVEC, addr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get Non-vector interrupt entry address
|
||||
* \details
|
||||
* This function get Non-vector interrupt address.
|
||||
* \return Non-vector interrupt handler address
|
||||
* \remarks
|
||||
* - This function use to get non-vector interrupt entry address from 'CSR_MTVT2' if
|
||||
* - CSR_MTVT2 bit0 is 1. If 'CSR_MTVT2' bit0 is 0 then get address from 'CSR_MTVEC'.
|
||||
* \sa
|
||||
* - \ref __set_nonvec_entry
|
||||
*/
|
||||
__STATIC_FORCEINLINE rv_csr_t __get_nonvec_entry(void)
|
||||
{
|
||||
if (__RV_CSR_READ(CSR_MTVT2) & 0x1) {
|
||||
return __RV_CSR_READ(CSR_MTVT2) & (~(rv_csr_t)(0x1));
|
||||
} else {
|
||||
rv_csr_t addr = __RV_CSR_READ(CSR_MTVEC);
|
||||
return (addr & ~ECLIC_MODE_MTVEC_Msk);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get NMI interrupt entry from 'CSR_MNVEC'
|
||||
* \details
|
||||
* This function get NMI interrupt address from 'CSR_MNVEC'.
|
||||
* \return NMI interrupt handler address
|
||||
* \remarks
|
||||
* - This function use to get NMI interrupt handler address from 'CSR_MNVEC'. If CSR_MMISC_CTL[9] = 1 'CSR_MNVEC'
|
||||
* - will be equal as mtvec. If CSR_MMISC_CTL[9] = 0 'CSR_MNVEC' will be equal as reset vector.
|
||||
* - NMI entry is defined via \ref CSR_MMISC_CTL, writing to \ref CSR_MNVEC will be ignored.
|
||||
*/
|
||||
__STATIC_FORCEINLINE rv_csr_t __get_nmi_entry(void)
|
||||
{
|
||||
return __RV_CSR_READ(CSR_MNVEC);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Save necessary CSRs into variables for vector interrupt nesting
|
||||
* \details
|
||||
* This macro is used to declare variables which are used for saving
|
||||
* CSRs(MCAUSE, MEPC, MSUB), and it will read these CSR content into
|
||||
* these variables, it need to be used in a vector-interrupt if nesting
|
||||
* is required.
|
||||
* \remarks
|
||||
* - Interrupt will be enabled after this macro is called
|
||||
* - It need to be used together with \ref RESTORE_IRQ_CSR_CONTEXT
|
||||
* - Don't use variable names __mcause, __mpec, __msubm in your ISR code
|
||||
* - If you want to enable interrupt nesting feature for vector interrupt,
|
||||
* you can do it like this:
|
||||
* \code
|
||||
* // __INTERRUPT attribute will generates function entry and exit sequences suitable
|
||||
* // for use in an interrupt handler when this attribute is present
|
||||
* __INTERRUPT void eclic_mtip_handler(void)
|
||||
* {
|
||||
* // Must call this to save CSRs
|
||||
* SAVE_IRQ_CSR_CONTEXT();
|
||||
* // !!!Interrupt is enabled here!!!
|
||||
* // !!!Higher priority interrupt could nest it!!!
|
||||
*
|
||||
* // put you own interrupt handling code here
|
||||
*
|
||||
* // Must call this to restore CSRs
|
||||
* RESTORE_IRQ_CSR_CONTEXT();
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
#define SAVE_IRQ_CSR_CONTEXT() \
|
||||
rv_csr_t __mcause = __RV_CSR_READ(CSR_MCAUSE); \
|
||||
rv_csr_t __mepc = __RV_CSR_READ(CSR_MEPC); \
|
||||
rv_csr_t __msubm = __RV_CSR_READ(CSR_MSUBM); \
|
||||
__enable_irq();
|
||||
|
||||
/**
|
||||
* \brief Restore necessary CSRs from variables for vector interrupt nesting
|
||||
* \details
|
||||
* This macro is used restore CSRs(MCAUSE, MEPC, MSUB) from pre-defined variables
|
||||
* in \ref SAVE_IRQ_CSR_CONTEXT macro.
|
||||
* \remarks
|
||||
* - Interrupt will be disabled after this macro is called
|
||||
* - It need to be used together with \ref SAVE_IRQ_CSR_CONTEXT
|
||||
*/
|
||||
#define RESTORE_IRQ_CSR_CONTEXT() \
|
||||
__disable_irq(); \
|
||||
__RV_CSR_WRITE(CSR_MSUBM, __msubm); \
|
||||
__RV_CSR_WRITE(CSR_MEPC, __mepc); \
|
||||
__RV_CSR_WRITE(CSR_MCAUSE, __mcause);
|
||||
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_IntExc */
|
||||
|
||||
#endif /* defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /** __CORE_FEATURE_ECLIC__ */
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CORE_FEATURE_FPU_H__
|
||||
#define __CORE_FEATURE_FPU_H__
|
||||
/*!
|
||||
* @file core_feature_fpu.h
|
||||
* @brief FPU feature API header file for Nuclei N/NX Core
|
||||
*/
|
||||
/*
|
||||
* FPU Feature Configuration Macro:
|
||||
* 1. __FPU_PRESENT: Define whether Floating Point Unit(FPU) is present or not
|
||||
* * 0: Not present
|
||||
* * 1: Single precision FPU present, __RISCV_FLEN == 32
|
||||
* * 2: Double precision FPU present, __RISCV_FLEN == 64
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ===== FPU Operations ===== */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_FPU_Functions FPU Functions
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief Functions that related to the RISC-V FPU (F and D extension).
|
||||
* \details
|
||||
*
|
||||
* Nuclei provided floating point unit by RISC-V F and D extension.
|
||||
* * `F extension` adds single-precision floating-point computational
|
||||
* instructions compliant with the IEEE 754-2008 arithmetic standard, __RISCV_FLEN = 32.
|
||||
* The F extension adds 32 floating-point registers, f0-f31, each 32 bits wide,
|
||||
* and a floating-point control and status register fcsr, which contains the
|
||||
* operating mode and exception status of the floating-point unit.
|
||||
* * `D extension` adds double-precision floating-point computational instructions
|
||||
* compliant with the IEEE 754-2008 arithmetic standard.
|
||||
* The D extension widens the 32 floating-point registers, f0-f31, to 64 bits, __RISCV_FLEN = 64
|
||||
* @{
|
||||
*/
|
||||
#if defined(__FPU_PRESENT) && (__FPU_PRESENT > 0)
|
||||
|
||||
#if __FPU_PRESENT == 1
|
||||
/** \brief Refer to the width of the floating point register in bits(either 32 or 64) */
|
||||
#define __RISCV_FLEN 32
|
||||
#elif __FPU_PRESENT == 2
|
||||
#define __RISCV_FLEN 64
|
||||
#else
|
||||
#define __RISCV_FLEN __riscv_flen
|
||||
#endif /* __FPU_PRESENT == 1 */
|
||||
|
||||
/** \brief Get FCSR CSR Register */
|
||||
#define __get_FCSR() __RV_CSR_READ(CSR_FCSR)
|
||||
/** \brief Set FCSR CSR Register with val */
|
||||
#define __set_FCSR(val) __RV_CSR_WRITE(CSR_FCSR, (val))
|
||||
/** \brief Get FRM CSR Register */
|
||||
#define __get_FRM() __RV_CSR_READ(CSR_FRM)
|
||||
/** \brief Set FRM CSR Register with val */
|
||||
#define __set_FRM(val) __RV_CSR_WRITE(CSR_FRM, (val))
|
||||
/** \brief Get FFLAGS CSR Register */
|
||||
#define __get_FFLAGS() __RV_CSR_READ(CSR_FFLAGS)
|
||||
/** \brief Set FFLAGS CSR Register with val */
|
||||
#define __set_FFLAGS(val) __RV_CSR_WRITE(CSR_FFLAGS, (val))
|
||||
|
||||
/** \brief Enable FPU Unit */
|
||||
#define __enable_FPU() __RV_CSR_SET(CSR_MSTATUS, MSTATUS_FS)
|
||||
/**
|
||||
* \brief Disable FPU Unit
|
||||
* \details
|
||||
* * We can save power by disable FPU Unit.
|
||||
* * When FPU Unit is disabled, any access to FPU related CSR registers
|
||||
* and FPU instructions will cause illegal Instuction Exception.
|
||||
* */
|
||||
#define __disable_FPU() __RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_FS)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Load a single-precision value from memory into float point register freg using flw instruction
|
||||
* \details The FLW instruction loads a single-precision floating point value from memory
|
||||
* address (addr + ofs) into floating point register freg(f0-f31)
|
||||
* \param [in] freg The floating point register, eg. FREG(0), f0
|
||||
* \param [in] addr The memory base address, 4 byte aligned required
|
||||
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
|
||||
* \remarks
|
||||
* * FLW and FSW operations need to make sure the address is 4 bytes aligned,
|
||||
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
|
||||
* * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical
|
||||
* NaNs are preserved
|
||||
*
|
||||
*/
|
||||
#define __RV_FLW(freg, addr, ofs) \
|
||||
({ \
|
||||
register rv_csr_t __addr = (rv_csr_t)(addr); \
|
||||
__ASM volatile("flw " STRINGIFY(freg) ", %0(%1) " \
|
||||
: : "I"(ofs), "r"(__addr) \
|
||||
: "memory"); \
|
||||
})
|
||||
|
||||
/**
|
||||
* \brief Store a single-precision value from float point freg into memory using fsw instruction
|
||||
* \details The FSW instruction stores a single-precision value from floating point register to memory
|
||||
* \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0
|
||||
* \param [in] addr The memory base address, 4 byte aligned required
|
||||
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
|
||||
* \remarks
|
||||
* * FLW and FSW operations need to make sure the address is 4 bytes aligned,
|
||||
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
|
||||
* * FLW and FSW do not modify the bits being transferred; in particular, the payloads of non-canonical
|
||||
* NaNs are preserved
|
||||
*
|
||||
*/
|
||||
#define __RV_FSW(freg, addr, ofs) \
|
||||
({ \
|
||||
register rv_csr_t __addr = (rv_csr_t)(addr); \
|
||||
__ASM volatile("fsw " STRINGIFY(freg) ", %0(%1) " \
|
||||
: : "I"(ofs), "r"(__addr) \
|
||||
: "memory"); \
|
||||
})
|
||||
|
||||
/**
|
||||
* \brief Load a double-precision value from memory into float point register freg using fld instruction
|
||||
* \details The FLD instruction loads a double-precision floating point value from memory
|
||||
* address (addr + ofs) into floating point register freg(f0-f31)
|
||||
* \param [in] freg The floating point register, eg. FREG(0), f0
|
||||
* \param [in] addr The memory base address, 8 byte aligned required
|
||||
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
|
||||
* \attention
|
||||
* * Function only available for double precision floating point unit, FLEN = 64
|
||||
* \remarks
|
||||
* * FLD and FSD operations need to make sure the address is 8 bytes aligned,
|
||||
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
|
||||
* * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical
|
||||
* NaNs are preserved.
|
||||
*/
|
||||
#define __RV_FLD(freg, addr, ofs) \
|
||||
({ \
|
||||
register rv_csr_t __addr = (rv_csr_t)(addr); \
|
||||
__ASM volatile("fld " STRINGIFY(freg) ", %0(%1) " \
|
||||
: : "I"(ofs), "r"(__addr) \
|
||||
: "memory"); \
|
||||
})
|
||||
|
||||
/**
|
||||
* \brief Store a double-precision value from float point freg into memory using fsd instruction
|
||||
* \details The FSD instruction stores double-precision value from floating point register to memory
|
||||
* \param [in] freg The floating point register(f0-f31), eg. FREG(0), f0
|
||||
* \param [in] addr The memory base address, 8 byte aligned required
|
||||
* \param [in] ofs a 12-bit immediate signed byte offset value, should be an const value
|
||||
* \attention
|
||||
* * Function only available for double precision floating point unit, FLEN = 64
|
||||
* \remarks
|
||||
* * FLD and FSD operations need to make sure the address is 8 bytes aligned,
|
||||
* otherwise it will cause exception code 4(Load address misaligned) or 6 (Store/AMO address misaligned)
|
||||
* * FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical
|
||||
* NaNs are preserved.
|
||||
*
|
||||
*/
|
||||
#define __RV_FSD(freg, addr, ofs) \
|
||||
({ \
|
||||
register rv_csr_t __addr = (rv_csr_t)(addr); \
|
||||
__ASM volatile("fsd " STRINGIFY(freg) ", %0(%1) " \
|
||||
: : "I"(ofs), "r"(__addr) \
|
||||
: "memory"); \
|
||||
})
|
||||
|
||||
/**
|
||||
* \def __RV_FLOAD
|
||||
* \brief Load a float point value from memory into float point register freg using flw/fld instruction
|
||||
* \details
|
||||
* * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32):
|
||||
* It will call \ref __RV_FLW to load a single-precision floating point value from memory to floating point register
|
||||
* * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64):
|
||||
* It will call \ref __RV_FLD to load a double-precision floating point value from memory to floating point register
|
||||
*
|
||||
* \attention
|
||||
* Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent
|
||||
*/
|
||||
/**
|
||||
* \def __RV_FSTORE
|
||||
* \brief Store a float value from float point freg into memory using fsw/fsd instruction
|
||||
* \details
|
||||
* * For Single-Precison Floating-Point Mode(__FPU_PRESENT == 1, __RISCV_FLEN == 32):
|
||||
* It will call \ref __RV_FSW to store floating point register into memory
|
||||
* * For Double-Precison Floating-Point Mode(__FPU_PRESENT == 2, __RISCV_FLEN == 64):
|
||||
* It will call \ref __RV_FSD to store floating point register into memory
|
||||
*
|
||||
* \attention
|
||||
* Function behaviour is different for __FPU_PRESENT = 1 or 2, please see the real function this macro represent
|
||||
*/
|
||||
#if __FPU_PRESENT == 1
|
||||
#define __RV_FLOAD __RV_FLW
|
||||
#define __RV_FSTORE __RV_FSW
|
||||
/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */
|
||||
typedef uint32_t rv_fpu_t;
|
||||
#elif __FPU_PRESENT == 2
|
||||
#define __RV_FLOAD __RV_FLD
|
||||
#define __RV_FSTORE __RV_FSD
|
||||
/** \brief Type of FPU register, depends on the FLEN defined in RISC-V */
|
||||
typedef uint64_t rv_fpu_t;
|
||||
#endif /* __FPU_PRESENT == 2 */
|
||||
|
||||
/**
|
||||
* \brief Save FPU context into variables for interrupt nesting
|
||||
* \details
|
||||
* This macro is used to declare variables which are used for saving
|
||||
* FPU context, and it will store the nessary fpu registers into
|
||||
* these variables, it need to be used in a interrupt when in this
|
||||
* interrupt fpu registers are used.
|
||||
* \remarks
|
||||
* - It need to be used together with \ref RESTORE_FPU_CONTEXT
|
||||
* - Don't use variable names __fpu_context in your ISR code
|
||||
* - If you isr code will use fpu registers, and this interrupt is nested.
|
||||
* Then you can do it like this:
|
||||
* \code
|
||||
* void eclic_mtip_handler(void)
|
||||
* {
|
||||
* // !!!Interrupt is enabled here!!!
|
||||
* // !!!Higher priority interrupt could nest it!!!
|
||||
*
|
||||
* // Necessary only when you need to use fpu registers
|
||||
* // in this isr handler functions
|
||||
* SAVE_FPU_CONTEXT();
|
||||
*
|
||||
* // put you own interrupt handling code here
|
||||
*
|
||||
* // pair of SAVE_FPU_CONTEXT()
|
||||
* RESTORE_FPU_CONTEXT();
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
#define SAVE_FPU_CONTEXT() \
|
||||
rv_fpu_t __fpu_context[20]; \
|
||||
__RV_FSTORE(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \
|
||||
__RV_FSTORE(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES);
|
||||
|
||||
/**
|
||||
* \brief Restore necessary fpu registers from variables for interrupt nesting
|
||||
* \details
|
||||
* This macro is used restore necessary fpu registers from pre-defined variables
|
||||
* in \ref SAVE_FPU_CONTEXT macro.
|
||||
* \remarks
|
||||
* - It need to be used together with \ref SAVE_FPU_CONTEXT
|
||||
*/
|
||||
#define RESTORE_FPU_CONTEXT() \
|
||||
__RV_FLOAD(FREG(0), __fpu_context, 0 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(1), __fpu_context, 1 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(2), __fpu_context, 2 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(3), __fpu_context, 3 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(4), __fpu_context, 4 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(5), __fpu_context, 5 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(6), __fpu_context, 6 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(7), __fpu_context, 7 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(10), __fpu_context, 8 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(11), __fpu_context, 9 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(12), __fpu_context, 10 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(13), __fpu_context, 11 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(14), __fpu_context, 12 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(15), __fpu_context, 13 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(16), __fpu_context, 14 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(17), __fpu_context, 15 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(28), __fpu_context, 16 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(29), __fpu_context, 17 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(30), __fpu_context, 18 << LOG_FPREGBYTES); \
|
||||
__RV_FLOAD(FREG(31), __fpu_context, 19 << LOG_FPREGBYTES);
|
||||
#else
|
||||
#define SAVE_FPU_CONTEXT()
|
||||
#define RESTORE_FPU_CONTEXT()
|
||||
#endif /* __FPU_PRESENT > 0 */
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_FPU_Functions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /** __RISCV_EXT_FPU_H__ */
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CORE_FEATURE_PMP_H__
|
||||
#define __CORE_FEATURE_PMP_H__
|
||||
/*!
|
||||
* @file core_feature_pmp.h
|
||||
* @brief PMP feature API header file for Nuclei N/NX Core
|
||||
*/
|
||||
/*
|
||||
* PMP Feature Configuration Macro:
|
||||
* 1. __PMP_PRESENT: Define whether Physical Memory Protection(PMP) is present or not
|
||||
* * 0: Not present
|
||||
* * 1: Present
|
||||
* 2. __PMP_ENTRY_NUM: Define the number of PMP entries, only 8 or 16 is configurable.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1)
|
||||
/* ===== PMP Operations ===== */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_PMP_Functions PMP Functions
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief Functions that related to the RISCV Phyiscal Memory Protection.
|
||||
* \details
|
||||
* Optional physical memory protection (PMP) unit provides per-hart machine-mode
|
||||
* control registers to allow physical memory access privileges (read, write, execute)
|
||||
* to be specified for each physical memory region.
|
||||
*
|
||||
* The PMP can supports region access control settings as small as four bytes.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#ifndef __PMP_ENTRY_NUM
|
||||
/* numbers of PMP entries(__PMP_ENTRY_NUM) should be defined in <Device.h> */
|
||||
#error "__PMP_ENTRY_NUM is not defined, please check!"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Get 8bit PMPxCFG Register by PMP entry index
|
||||
* \details Return the content of the PMPxCFG Register.
|
||||
* \param [in] idx PMP region index(0-15)
|
||||
* \return PMPxCFG Register value
|
||||
*/
|
||||
__STATIC_INLINE uint8_t __get_PMPxCFG(uint32_t idx)
|
||||
{
|
||||
rv_csr_t pmpcfg = 0;
|
||||
|
||||
if (idx >= __PMP_ENTRY_NUM) return 0;
|
||||
#if __RISCV_XLEN == 32
|
||||
if (idx < 4) {
|
||||
pmpcfg = __RV_CSR_READ(CSR_PMPCFG0);
|
||||
} else if ((idx >=4) && (idx < 8)) {
|
||||
idx -= 4;
|
||||
pmpcfg = __RV_CSR_READ(CSR_PMPCFG1);
|
||||
} else if ((idx >=8) && (idx < 12)) {
|
||||
idx -= 8;
|
||||
pmpcfg = __RV_CSR_READ(CSR_PMPCFG2);
|
||||
} else {
|
||||
idx -= 12;
|
||||
pmpcfg = __RV_CSR_READ(CSR_PMPCFG3);
|
||||
}
|
||||
|
||||
idx = idx << 3;
|
||||
return (uint8_t)((pmpcfg>>idx) & 0xFF);
|
||||
#elif __RISCV_XLEN == 64
|
||||
if (idx < 8) {
|
||||
pmpcfg = __RV_CSR_READ(CSR_PMPCFG0);
|
||||
} else {
|
||||
idx -= 8;
|
||||
pmpcfg = __RV_CSR_READ(CSR_PMPCFG2);
|
||||
}
|
||||
idx = idx << 3;
|
||||
return (uint8_t)((pmpcfg>>idx) & 0xFF);
|
||||
#else
|
||||
// TODO Add RV128 Handling
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set 8bit PMPxCFG by pmp entry index
|
||||
* \details Set the given pmpxcfg value to the PMPxCFG Register.
|
||||
* \param [in] idx PMPx region index(0-15)
|
||||
* \param [in] pmpxcfg PMPxCFG register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PMPxCFG(uint32_t idx, uint8_t pmpxcfg)
|
||||
{
|
||||
rv_csr_t pmpcfgx = 0;
|
||||
if (idx >= __PMP_ENTRY_NUM) return;
|
||||
|
||||
#if __RISCV_XLEN == 32
|
||||
if (idx < 4) {
|
||||
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG0);
|
||||
idx = idx << 3;
|
||||
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
|
||||
__RV_CSR_WRITE(CSR_PMPCFG0, pmpcfgx);
|
||||
} else if ((idx >=4) && (idx < 8)) {
|
||||
idx -= 4;
|
||||
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG1);
|
||||
idx = idx << 3;
|
||||
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
|
||||
__RV_CSR_WRITE(CSR_PMPCFG1, pmpcfgx);
|
||||
} else if ((idx >=8) && (idx < 12)) {
|
||||
idx -= 8;
|
||||
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG2);
|
||||
idx = idx << 3;
|
||||
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
|
||||
__RV_CSR_WRITE(CSR_PMPCFG2, pmpcfgx);
|
||||
} else {
|
||||
idx -= 12;
|
||||
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG3);
|
||||
idx = idx << 3;
|
||||
pmpcfgx = (pmpcfgx & ~(0xFFUL << idx)) | ((rv_csr_t)pmpxcfg << idx);
|
||||
__RV_CSR_WRITE(CSR_PMPCFG3, pmpcfgx);
|
||||
}
|
||||
#elif __RISCV_XLEN == 64
|
||||
if (idx < 8) {
|
||||
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG0);
|
||||
idx = idx << 3;
|
||||
pmpcfgx = (pmpcfgx & ~(0xFFULL << idx)) | ((rv_csr_t)pmpxcfg << idx);
|
||||
__RV_CSR_WRITE(CSR_PMPCFG0, pmpcfgx);
|
||||
} else {
|
||||
idx -= 8;
|
||||
pmpcfgx = __RV_CSR_READ(CSR_PMPCFG2);
|
||||
idx = idx << 3;
|
||||
pmpcfgx = (pmpcfgx & ~(0xFFULL << idx)) | ((rv_csr_t)pmpxcfg << idx);
|
||||
__RV_CSR_WRITE(CSR_PMPCFG2, pmpcfgx);
|
||||
}
|
||||
#else
|
||||
// TODO Add RV128 Handling
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get PMPCFGx Register by index
|
||||
* \details Return the content of the PMPCFGx Register.
|
||||
* \param [in] idx PMPCFG CSR index(0-3)
|
||||
* \return PMPCFGx Register value
|
||||
* \remark
|
||||
* - For RV64, only idx = 0 and idx = 2 is allowed.
|
||||
* pmpcfg0 and pmpcfg2 hold the configurations
|
||||
* for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal
|
||||
* - For RV32, pmpcfg0–pmpcfg3, hold the configurations
|
||||
* pmp0cfg–pmp15cfg for the 16 PMP entries
|
||||
*/
|
||||
__STATIC_INLINE rv_csr_t __get_PMPCFGx(uint32_t idx)
|
||||
{
|
||||
switch (idx) {
|
||||
case 0: return __RV_CSR_READ(CSR_PMPCFG0);
|
||||
case 1: return __RV_CSR_READ(CSR_PMPCFG1);
|
||||
case 2: return __RV_CSR_READ(CSR_PMPCFG2);
|
||||
case 3: return __RV_CSR_READ(CSR_PMPCFG3);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set PMPCFGx by index
|
||||
* \details Write the given value to the PMPCFGx Register.
|
||||
* \param [in] idx PMPCFG CSR index(0-3)
|
||||
* \param [in] pmpcfg PMPCFGx Register value to set
|
||||
* \remark
|
||||
* - For RV64, only idx = 0 and idx = 2 is allowed.
|
||||
* pmpcfg0 and pmpcfg2 hold the configurations
|
||||
* for the 16 PMP entries, pmpcfg1 and pmpcfg3 are illegal
|
||||
* - For RV32, pmpcfg0–pmpcfg3, hold the configurations
|
||||
* pmp0cfg–pmp15cfg for the 16 PMP entries
|
||||
*/
|
||||
__STATIC_INLINE void __set_PMPCFGx(uint32_t idx, rv_csr_t pmpcfg)
|
||||
{
|
||||
switch (idx) {
|
||||
case 0: __RV_CSR_WRITE(CSR_PMPCFG0, pmpcfg); break;
|
||||
case 1: __RV_CSR_WRITE(CSR_PMPCFG1, pmpcfg); break;
|
||||
case 2: __RV_CSR_WRITE(CSR_PMPCFG2, pmpcfg); break;
|
||||
case 3: __RV_CSR_WRITE(CSR_PMPCFG3, pmpcfg); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get PMPADDRx Register by index
|
||||
* \details Return the content of the PMPADDRx Register.
|
||||
* \param [in] idx PMP region index(0-15)
|
||||
* \return PMPADDRx Register value
|
||||
*/
|
||||
__STATIC_INLINE rv_csr_t __get_PMPADDRx(uint32_t idx)
|
||||
{
|
||||
switch (idx) {
|
||||
case 0: return __RV_CSR_READ(CSR_PMPADDR0);
|
||||
case 1: return __RV_CSR_READ(CSR_PMPADDR1);
|
||||
case 2: return __RV_CSR_READ(CSR_PMPADDR2);
|
||||
case 3: return __RV_CSR_READ(CSR_PMPADDR3);
|
||||
case 4: return __RV_CSR_READ(CSR_PMPADDR4);
|
||||
case 5: return __RV_CSR_READ(CSR_PMPADDR5);
|
||||
case 6: return __RV_CSR_READ(CSR_PMPADDR6);
|
||||
case 7: return __RV_CSR_READ(CSR_PMPADDR7);
|
||||
case 8: return __RV_CSR_READ(CSR_PMPADDR8);
|
||||
case 9: return __RV_CSR_READ(CSR_PMPADDR9);
|
||||
case 10: return __RV_CSR_READ(CSR_PMPADDR10);
|
||||
case 11: return __RV_CSR_READ(CSR_PMPADDR11);
|
||||
case 12: return __RV_CSR_READ(CSR_PMPADDR12);
|
||||
case 13: return __RV_CSR_READ(CSR_PMPADDR13);
|
||||
case 14: return __RV_CSR_READ(CSR_PMPADDR14);
|
||||
case 15: return __RV_CSR_READ(CSR_PMPADDR15);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set PMPADDRx by index
|
||||
* \details Write the given value to the PMPADDRx Register.
|
||||
* \param [in] idx PMP region index(0-15)
|
||||
* \param [in] pmpaddr PMPADDRx Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PMPADDRx(uint32_t idx, rv_csr_t pmpaddr)
|
||||
{
|
||||
switch (idx) {
|
||||
case 0: __RV_CSR_WRITE(CSR_PMPADDR0, pmpaddr); break;
|
||||
case 1: __RV_CSR_WRITE(CSR_PMPADDR1, pmpaddr); break;
|
||||
case 2: __RV_CSR_WRITE(CSR_PMPADDR2, pmpaddr); break;
|
||||
case 3: __RV_CSR_WRITE(CSR_PMPADDR3, pmpaddr); break;
|
||||
case 4: __RV_CSR_WRITE(CSR_PMPADDR4, pmpaddr); break;
|
||||
case 5: __RV_CSR_WRITE(CSR_PMPADDR5, pmpaddr); break;
|
||||
case 6: __RV_CSR_WRITE(CSR_PMPADDR6, pmpaddr); break;
|
||||
case 7: __RV_CSR_WRITE(CSR_PMPADDR7, pmpaddr); break;
|
||||
case 8: __RV_CSR_WRITE(CSR_PMPADDR8, pmpaddr); break;
|
||||
case 9: __RV_CSR_WRITE(CSR_PMPADDR9, pmpaddr); break;
|
||||
case 10: __RV_CSR_WRITE(CSR_PMPADDR10, pmpaddr); break;
|
||||
case 11: __RV_CSR_WRITE(CSR_PMPADDR11, pmpaddr); break;
|
||||
case 12: __RV_CSR_WRITE(CSR_PMPADDR12, pmpaddr); break;
|
||||
case 13: __RV_CSR_WRITE(CSR_PMPADDR13, pmpaddr); break;
|
||||
case 14: __RV_CSR_WRITE(CSR_PMPADDR14, pmpaddr); break;
|
||||
case 15: __RV_CSR_WRITE(CSR_PMPADDR15, pmpaddr); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_PMP_Functions */
|
||||
#endif /* defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /** __CORE_FEATURE_PMP_H__ */
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CORE_FEATURE_TIMER_H__
|
||||
#define __CORE_FEATURE_TIMER_H__
|
||||
/*!
|
||||
* @file core_feature_timer.h
|
||||
* @brief System Timer feature API header file for Nuclei N/NX Core
|
||||
*/
|
||||
/*
|
||||
* System Timer Feature Configuration Macro:
|
||||
* 1. __SYSTIMER_PRESENT: Define whether Private System Timer is present or not.
|
||||
* * 0: Not present
|
||||
* * 1: Present
|
||||
* 2. __SYSTIMER_BASEADDR: Define the base address of the System Timer.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1)
|
||||
/**
|
||||
* \defgroup NMSIS_Core_SysTimer_Registers Register Define and Type Definitions Of System Timer
|
||||
* \ingroup NMSIS_Core_Registers
|
||||
* \brief Type definitions and defines for system timer registers.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Structure type to access the System Timer (SysTimer).
|
||||
* \details
|
||||
* Structure definition to access the system timer(SysTimer).
|
||||
* \remarks
|
||||
* - MSFTRST register is introduced in Nuclei N Core version 1.3(\ref __NUCLEI_N_REV >= 0x0103)
|
||||
* - MSTOP register is renamed to MTIMECTL register in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104)
|
||||
* - CMPCLREN and CLKSRC bit in MTIMECTL register is introduced in Nuclei N Core version 1.4(\ref __NUCLEI_N_REV >= 0x0104)
|
||||
*/
|
||||
typedef struct {
|
||||
__IOM uint64_t MTIMER; /*!< Offset: 0x000 (R/W) System Timer current value 64bits Register */
|
||||
__IOM uint64_t MTIMERCMP; /*!< Offset: 0x008 (R/W) System Timer compare Value 64bits Register */
|
||||
__IOM uint32_t RESERVED0[0x3F8]; /*!< Offset: 0x010 - 0xFEC Reserved */
|
||||
__IOM uint32_t MSFTRST; /*!< Offset: 0xFF0 (R/W) System Timer Software Core Reset Register */
|
||||
__IOM uint32_t RESERVED1; /*!< Offset: 0xFF4 Reserved */
|
||||
__IOM uint32_t MTIMECTL; /*!< Offset: 0xFF8 (R/W) System Timer Control Register, previously MSTOP register */
|
||||
__IOM uint32_t MSIP; /*!< Offset: 0xFFC (R/W) System Timer SW interrupt Register */
|
||||
} SysTimer_Type;
|
||||
|
||||
/* Timer Control / Status Register Definitions */
|
||||
#define SysTimer_MTIMECTL_TIMESTOP_Pos 0U /*!< SysTick Timer MTIMECTL: TIMESTOP bit Position */
|
||||
#define SysTimer_MTIMECTL_TIMESTOP_Msk (1UL << SysTimer_MTIMECTL_TIMESTOP_Pos) /*!< SysTick Timer MTIMECTL: TIMESTOP Mask */
|
||||
#define SysTimer_MTIMECTL_CMPCLREN_Pos 1U /*!< SysTick Timer MTIMECTL: CMPCLREN bit Position */
|
||||
#define SysTimer_MTIMECTL_CMPCLREN_Msk (1UL << SysTimer_MTIMECTL_CMPCLREN_Pos) /*!< SysTick Timer MTIMECTL: CMPCLREN Mask */
|
||||
#define SysTimer_MTIMECTL_CLKSRC_Pos 2U /*!< SysTick Timer MTIMECTL: CLKSRC bit Position */
|
||||
#define SysTimer_MTIMECTL_CLKSRC_Msk (1UL << SysTimer_MTIMECTL_CLKSRC_Pos) /*!< SysTick Timer MTIMECTL: CLKSRC Mask */
|
||||
|
||||
#define SysTimer_MSIP_MSIP_Pos 0U /*!< SysTick Timer MSIP: MSIP bit Position */
|
||||
#define SysTimer_MSIP_MSIP_Msk (1UL << SysTimer_MSIP_MSIP_Pos) /*!< SysTick Timer MSIP: MSIP Mask */
|
||||
|
||||
#define SysTimer_MTIMER_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMER value Mask */
|
||||
#define SysTimer_MTIMERCMP_Msk (0xFFFFFFFFFFFFFFFFULL) /*!< SysTick Timer MTIMERCMP value Mask */
|
||||
#define SysTimer_MTIMECTL_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MTIMECTL/MSTOP value Mask */
|
||||
#define SysTimer_MSIP_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSIP value Mask */
|
||||
#define SysTimer_MSFTRST_Msk (0xFFFFFFFFUL) /*!< SysTick Timer MSFTRST value Mask */
|
||||
|
||||
#define SysTimer_MSFRST_KEY (0x80000A5FUL) /*!< SysTick Timer Software Reset Request Key */
|
||||
|
||||
#ifndef __SYSTIMER_BASEADDR
|
||||
/* Base address of SYSTIMER(__SYSTIMER_BASEADDR) should be defined in <Device.h> */
|
||||
#error "__SYSTIMER_BASEADDR is not defined, please check!"
|
||||
#endif
|
||||
/* System Timer Memory mapping of Device */
|
||||
#define SysTimer_BASE __SYSTIMER_BASEADDR /*!< SysTick Base Address */
|
||||
#define SysTimer ((SysTimer_Type *) SysTimer_BASE) /*!< SysTick configuration struct */
|
||||
/** @} */ /* end of group NMSIS_Core_SysTimer_Registers */
|
||||
|
||||
/* ################################## SysTimer function ############################################ */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_SysTimer SysTimer Functions
|
||||
* \brief Functions that configure the Core System Timer.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \brief Set system timer load value
|
||||
* \details
|
||||
* This function set the system timer load value in MTIMER register.
|
||||
* \param [in] value value to set system timer MTIMER register.
|
||||
* \remarks
|
||||
* - Load value is 64bits wide.
|
||||
* - \ref SysTimer_GetLoadValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetLoadValue(uint64_t value)
|
||||
{
|
||||
SysTimer->MTIMER = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer load value
|
||||
* \details
|
||||
* This function get the system timer current value in MTIMER register.
|
||||
* \return current value(64bit) of system timer MTIMER register.
|
||||
* \remarks
|
||||
* - Load value is 64bits wide.
|
||||
* - \ref SysTimer_SetLoadValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint64_t SysTimer_GetLoadValue(void)
|
||||
{
|
||||
return SysTimer->MTIMER;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set system timer compare value
|
||||
* \details
|
||||
* This function set the system Timer compare value in MTIMERCMP register.
|
||||
* \param [in] value compare value to set system timer MTIMERCMP register.
|
||||
* \remarks
|
||||
* - Compare value is 64bits wide.
|
||||
* - If compare value is larger than current value timer interrupt generate.
|
||||
* - Modify the load value or compare value less to clear the interrupt.
|
||||
* - \ref SysTimer_GetCompareValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetCompareValue(uint64_t value)
|
||||
{
|
||||
SysTimer->MTIMERCMP = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer compare value
|
||||
* \details
|
||||
* This function get the system timer compare value in MTIMERCMP register.
|
||||
* \return compare value of system timer MTIMERCMP register.
|
||||
* \remarks
|
||||
* - Compare value is 64bits wide.
|
||||
* - \ref SysTimer_SetCompareValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint64_t SysTimer_GetCompareValue(void)
|
||||
{
|
||||
return SysTimer->MTIMERCMP;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable system timer counter running
|
||||
* \details
|
||||
* Enable system timer counter running by clear
|
||||
* TIMESTOP bit in MTIMECTL register.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_Start(void)
|
||||
{
|
||||
SysTimer->MTIMECTL &= ~(SysTimer_MTIMECTL_TIMESTOP_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stop system timer counter running
|
||||
* \details
|
||||
* Stop system timer counter running by set
|
||||
* TIMESTOP bit in MTIMECTL register.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_Stop(void)
|
||||
{
|
||||
SysTimer->MTIMECTL |= SysTimer_MTIMECTL_TIMESTOP_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set system timer control value
|
||||
* \details
|
||||
* This function set the system timer MTIMECTL register value.
|
||||
* \param [in] mctl value to set MTIMECTL register
|
||||
* \remarks
|
||||
* - Bit TIMESTOP is used to start and stop timer.
|
||||
* Clear TIMESTOP bit to 0 to start timer, otherwise to stop timer.
|
||||
* - Bit CMPCLREN is used to enable auto MTIMER clear to zero when MTIMER >= MTIMERCMP.
|
||||
* Clear CMPCLREN bit to 0 to stop auto clear MTIMER feature, otherwise to enable it.
|
||||
* - Bit CLKSRC is used to select timer clock source.
|
||||
* Clear CLKSRC bit to 0 to use *mtime_toggle_a*, otherwise use *core_clk_aon*
|
||||
* - \ref SysTimer_GetControlValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetControlValue(uint32_t mctl)
|
||||
{
|
||||
SysTimer->MTIMECTL = (mctl & SysTimer_MTIMECTL_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer control value
|
||||
* \details
|
||||
* This function get the system timer MTIMECTL register value.
|
||||
* \return MTIMECTL register value
|
||||
* \remarks
|
||||
* - \ref SysTimer_SetControlValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t SysTimer_GetControlValue(void)
|
||||
{
|
||||
return (SysTimer->MTIMECTL & SysTimer_MTIMECTL_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Trigger or set software interrupt via system timer
|
||||
* \details
|
||||
* This function set the system timer MSIP bit in MSIP register.
|
||||
* \remarks
|
||||
* - Set system timer MSIP bit and generate a SW interrupt.
|
||||
* - \ref SysTimer_ClearSWIRQ
|
||||
* - \ref SysTimer_GetMsipValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetSWIRQ(void)
|
||||
{
|
||||
SysTimer->MSIP |= SysTimer_MSIP_MSIP_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear system timer software interrupt pending request
|
||||
* \details
|
||||
* This function clear the system timer MSIP bit in MSIP register.
|
||||
* \remarks
|
||||
* - Clear system timer MSIP bit in MSIP register to clear the software interrupt pending.
|
||||
* - \ref SysTimer_SetSWIRQ
|
||||
* - \ref SysTimer_GetMsipValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_ClearSWIRQ(void)
|
||||
{
|
||||
SysTimer->MSIP &= ~SysTimer_MSIP_MSIP_Msk;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get system timer MSIP register value
|
||||
* \details
|
||||
* This function get the system timer MSIP register value.
|
||||
* \return Value of Timer MSIP register.
|
||||
* \remarks
|
||||
* - Bit0 is SW interrupt flag.
|
||||
* Bit0 is 1 then SW interrupt set. Bit0 is 0 then SW interrupt clear.
|
||||
* - \ref SysTimer_SetSWIRQ
|
||||
* - \ref SysTimer_ClearSWIRQ
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t SysTimer_GetMsipValue(void)
|
||||
{
|
||||
return (uint32_t)(SysTimer->MSIP & SysTimer_MSIP_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set system timer MSIP register value
|
||||
* \details
|
||||
* This function set the system timer MSIP register value.
|
||||
* \param [in] msip value to set MSIP register
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SetMsipValue(uint32_t msip)
|
||||
{
|
||||
SysTimer->MSIP = (msip & SysTimer_MSIP_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Do software reset request
|
||||
* \details
|
||||
* This function will do software reset request through MTIMER
|
||||
* - Software need to write \ref SysTimer_MSFRST_KEY to generate software reset request
|
||||
* - The software request flag can be cleared by reset operation to clear
|
||||
* \remarks
|
||||
* - The software reset is sent to SoC, SoC need to generate reset signal and send back to Core
|
||||
* - This function will not return, it will do while(1) to wait the Core reset happened
|
||||
*/
|
||||
__STATIC_FORCEINLINE void SysTimer_SoftwareReset(void)
|
||||
{
|
||||
SysTimer->MSFTRST = SysTimer_MSFRST_KEY;
|
||||
while(1);
|
||||
}
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) && defined(__ECLIC_PRESENT) && (__ECLIC_PRESENT == 1)
|
||||
/**
|
||||
* \brief System Tick Configuration
|
||||
* \details Initializes the System Timer and its non-vector interrupt, and starts the System Tick Timer.
|
||||
*
|
||||
* In our default implementation, the timer counter will be set to zero, and it will start a timer compare non-vector interrupt
|
||||
* when it matchs the ticks user set, during the timer interrupt user should reload the system tick using \ref SysTick_Reload function
|
||||
* or similar function written by user, so it can produce period timer interrupt.
|
||||
* \param [in] ticks Number of ticks between two interrupts.
|
||||
* \return 0 Function succeeded.
|
||||
* \return 1 Function failed.
|
||||
* \remarks
|
||||
* - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced,
|
||||
* but we assume that the CMPCLREN bit is set to 0, so MTIMER register will not be
|
||||
* auto cleared to 0 when MTIMER >= MTIMERCMP.
|
||||
* - When the variable \ref __Vendor_SysTickConfig is set to 1, then the
|
||||
* function \ref SysTick_Config is not included.
|
||||
* - In this case, the file <b><Device>.h</b> must contain a vendor-specific implementation
|
||||
* of this function.
|
||||
* - If user need this function to start a period timer interrupt, then in timer interrupt handler
|
||||
* routine code, user should call \ref SysTick_Reload with ticks to reload the timer.
|
||||
* - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0
|
||||
* \sa
|
||||
* - \ref SysTimer_SetCompareValue; SysTimer_SetLoadValue
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint64_t ticks)
|
||||
{
|
||||
SysTimer_SetLoadValue(0);
|
||||
SysTimer_SetCompareValue(ticks);
|
||||
ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
|
||||
ECLIC_SetLevelIRQ(SysTimer_IRQn, 0);
|
||||
ECLIC_EnableIRQ(SysTimer_IRQn);
|
||||
return (0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief System Tick Reload
|
||||
* \details Reload the System Timer Tick when the MTIMECMP reached TIME value
|
||||
*
|
||||
* \param [in] ticks Number of ticks between two interrupts.
|
||||
* \return 0 Function succeeded.
|
||||
* \return 1 Function failed.
|
||||
* \remarks
|
||||
* - For \ref __NUCLEI_N_REV >= 0x0104, the CMPCLREN bit in MTIMECTL is introduced,
|
||||
* but for this \ref SysTick_Config function, we assume this CMPCLREN bit is set to 0,
|
||||
* so in interrupt handler function, user still need to set the MTIMERCMP or MTIMER to reload
|
||||
* the system tick, if vendor want to use this timer's auto clear feature, they can define
|
||||
* \ref __Vendor_SysTickConfig to 1, and implement \ref SysTick_Config and \ref SysTick_Reload functions.
|
||||
* - When the variable \ref __Vendor_SysTickConfig is set to 1, then the
|
||||
* function \ref SysTick_Reload is not included.
|
||||
* - In this case, the file <b><Device>.h</b> must contain a vendor-specific implementation
|
||||
* of this function.
|
||||
* - This function only available when __SYSTIMER_PRESENT == 1 and __ECLIC_PRESENT == 1 and __Vendor_SysTickConfig == 0
|
||||
* - Since the MTIMERCMP value might overflow, if overflowed, MTIMER will be set to 0, and MTIMERCMP set to ticks
|
||||
* \sa
|
||||
* - \ref SysTimer_SetCompareValue
|
||||
* - \ref SysTimer_SetLoadValue
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t SysTick_Reload(uint64_t ticks)
|
||||
{
|
||||
uint64_t cur_ticks = SysTimer->MTIMER;
|
||||
uint64_t reload_ticks = ticks + cur_ticks;
|
||||
|
||||
if (__USUALLY(reload_ticks > cur_ticks)) {
|
||||
SysTimer->MTIMERCMP = reload_ticks;
|
||||
} else {
|
||||
/* When added the ticks value, then the MTIMERCMP < TIMER,
|
||||
* which means the MTIMERCMP is overflowed,
|
||||
* so we need to reset the counter to zero */
|
||||
SysTimer->MTIMER = 0;
|
||||
SysTimer->MTIMERCMP = ticks;
|
||||
}
|
||||
|
||||
return (0UL);
|
||||
}
|
||||
|
||||
#endif /* defined(__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) */
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_SysTimer */
|
||||
|
||||
#endif /* defined(__SYSTIMER_PRESENT) && (__SYSTIMER_PRESENT == 1) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /** __CORE_FEATURE_TIMER_H__ */
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __NMSIS_COMPILER_H
|
||||
#define __NMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*!
|
||||
* @file nmsis_compiler.h
|
||||
* @brief NMSIS compiler generic header file
|
||||
*/
|
||||
#if defined ( __GNUC__ )
|
||||
/** GNU GCC Compiler */
|
||||
#include "nmsis_gcc.h"
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __NMSIS_COMPILER_H */
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2019 Arm Limited. All rights reserved.
|
||||
* -- Adaptable modifications made for Nuclei Processors. --
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __NMSIS_CORE_H__
|
||||
#define __NMSIS_CORE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nmsis_version.h"
|
||||
|
||||
/**
|
||||
* \ingroup NMSIS_Core_VersionControl
|
||||
* @{
|
||||
*/
|
||||
/* The following enum __NUCLEI_N_REV/__NUCLEI_NX_REV definition in this file
|
||||
* is only used for doxygen documentation generation,
|
||||
* The <device>.h is the real file to define it by vendor
|
||||
*/
|
||||
#if defined(__ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__)
|
||||
/**
|
||||
* \brief Nuclei N class core revision number
|
||||
* \details
|
||||
* Reversion number format: [15:8] revision number, [7:0] patch number
|
||||
* \attention
|
||||
* This define is exclusive with \ref __NUCLEI_NX_REV
|
||||
*/
|
||||
#define __NUCLEI_N_REV (0x0104)
|
||||
/**
|
||||
* \brief Nuclei NX class core revision number
|
||||
* \details
|
||||
* Reversion number format: [15:8] revision number, [7:0] patch number
|
||||
* \attention
|
||||
* This define is exclusive with \ref __NUCLEI_N_REV
|
||||
*/
|
||||
#define __NUCLEI_NX_REV (0x0100)
|
||||
#endif /* __ONLY_FOR_DOXYGEN_DOCUMENT_GENERATION__ */
|
||||
/** @} */ /* End of Group NMSIS_Core_VersionControl */
|
||||
|
||||
#include "nmsis_compiler.h" /* NMSIS compiler specific defines */
|
||||
|
||||
/* === Include Nuclei Core Related Headers === */
|
||||
/* Include core base feature header file */
|
||||
#include "core_feature_base.h"
|
||||
|
||||
#ifndef __NMSIS_GENERIC
|
||||
/* Include core eclic feature header file */
|
||||
#include "core_feature_eclic.h"
|
||||
/* Include core systimer feature header file */
|
||||
#include "core_feature_timer.h"
|
||||
#endif
|
||||
|
||||
/* Include core fpu feature header file */
|
||||
#include "core_feature_fpu.h"
|
||||
/* Include core dsp feature header file */
|
||||
#include "core_feature_dsp.h"
|
||||
/* Include core pmp feature header file */
|
||||
#include "core_feature_pmp.h"
|
||||
/* Include core cache feature header file */
|
||||
#include "core_feature_cache.h"
|
||||
|
||||
/* Include compatiable functions header file */
|
||||
#include "core_compatiable.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __NMSIS_CORE_H__ */
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __NMSIS_GCC_H__
|
||||
#define __NMSIS_GCC_H__
|
||||
/*!
|
||||
* @file nmsis_gcc.h
|
||||
* @brief NMSIS compiler GCC header file
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "riscv_encoding.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ######################### Startup and Lowlevel Init ######################## */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_CompilerControl Compiler Control
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief Compiler agnostic \#define symbols for generic c/c++ source code
|
||||
* \details
|
||||
*
|
||||
* The NMSIS-Core provides the header file <b>nmsis_compiler.h</b> with consistent \#define symbols for generate C or C++ source files that should be compiler agnostic.
|
||||
* Each NMSIS compliant compiler should support the functionality described in this section.
|
||||
*
|
||||
* The header file <b>nmsis_compiler.h</b> is also included by each Device Header File <device.h> so that these definitions are available.
|
||||
* @{
|
||||
*/
|
||||
/* ignore some GCC warnings */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/* Fallback for __has_builtin */
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) (0)
|
||||
#endif
|
||||
|
||||
/* NMSIS compiler specific defines */
|
||||
/** \brief Pass information from the compiler to the assembler. */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
|
||||
/** \brief Recommend that function should be inlined by the compiler. */
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
|
||||
/** \brief Define a static function that may be inlined by the compiler. */
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
/** \brief Define a static function that should be always inlined by the compiler. */
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
|
||||
#endif
|
||||
|
||||
/** \brief Inform the compiler that a function does not return. */
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((__noreturn__))
|
||||
#endif
|
||||
|
||||
/** \brief Inform that a variable shall be retained in executable image. */
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
|
||||
/** \brief restrict pointer qualifier to enable additional optimizations. */
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
|
||||
/** \brief specified the vector size of the variable, measured in bytes */
|
||||
#ifndef __VECTOR_SIZE
|
||||
#define __VECTOR_SIZE(x) __attribute__((vector_size(x)))
|
||||
#endif
|
||||
|
||||
/** \brief Request smallest possible alignment. */
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
|
||||
/** \brief Request smallest possible alignment for a structure. */
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
|
||||
/** \brief Request smallest possible alignment for a union. */
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
/** \brief Packed struct for unaligned uint16_t write access */
|
||||
__PACKED_STRUCT T_UINT16_WRITE {
|
||||
uint16_t v;
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
/** \brief Pointer for unaligned write of a uint16_t variable. */
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
/** \brief Packed struct for unaligned uint16_t read access */
|
||||
__PACKED_STRUCT T_UINT16_READ {
|
||||
uint16_t v;
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
/** \brief Pointer for unaligned read of a uint16_t variable. */
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
/** \brief Packed struct for unaligned uint32_t write access */
|
||||
__PACKED_STRUCT T_UINT32_WRITE {
|
||||
uint32_t v;
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
/** \brief Pointer for unaligned write of a uint32_t variable. */
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
/** \brief Packed struct for unaligned uint32_t read access */
|
||||
__PACKED_STRUCT T_UINT32_READ {
|
||||
uint32_t v;
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
/** \brief Pointer for unaligned read of a uint32_t variable. */
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
|
||||
/** \brief Minimum `x` bytes alignment for a variable. */
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
/** \brief restrict pointer qualifier to enable additional optimizations. */
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
/** \brief Barrier to prevent compiler from reordering instructions. */
|
||||
#ifndef __COMPILER_BARRIER
|
||||
#define __COMPILER_BARRIER() __ASM volatile("":::"memory")
|
||||
#endif
|
||||
|
||||
/** \brief provide the compiler with branch prediction information, the branch is usually true */
|
||||
#ifndef __USUALLY
|
||||
#define __USUALLY(exp) __builtin_expect((exp), 1)
|
||||
#endif
|
||||
|
||||
/** \brief provide the compiler with branch prediction information, the branch is rarely true */
|
||||
#ifndef __RARELY
|
||||
#define __RARELY(exp) __builtin_expect((exp), 0)
|
||||
#endif
|
||||
|
||||
/** \brief Use this attribute to indicate that the specified function is an interrupt handler. */
|
||||
#ifndef __INTERRUPT
|
||||
#define __INTERRUPT __attribute__((interrupt))
|
||||
#endif
|
||||
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_CompilerControl */
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
* \defgroup NMSIS_Core_PeriphAccess Peripheral Access
|
||||
* \brief Naming conventions and optional features for accessing peripherals.
|
||||
*
|
||||
* The section below describes the naming conventions, requirements, and optional features
|
||||
* for accessing device specific peripherals.
|
||||
* Most of the rules also apply to the core peripherals.
|
||||
*
|
||||
* The **Device Header File <device.h>** contains typically these definition
|
||||
* and also includes the core specific header files.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/** \brief Defines 'read only' permissions */
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile
|
||||
#else
|
||||
#define __I volatile const
|
||||
#endif
|
||||
/** \brief Defines 'write only' permissions */
|
||||
#define __O volatile
|
||||
/** \brief Defines 'read / write' permissions */
|
||||
#define __IO volatile
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
/** \brief Defines 'read only' structure member permissions */
|
||||
#define __IM volatile const
|
||||
/** \brief Defines 'write only' structure member permissions */
|
||||
#define __OM volatile
|
||||
/** \brief Defines 'read/write' structure member permissions */
|
||||
#define __IOM volatile
|
||||
|
||||
/**
|
||||
* \brief Mask and shift a bit field value for use in a register bit range.
|
||||
* \details The macro \ref _VAL2FLD uses the #define's _Pos and _Msk of the related bit
|
||||
* field to shift bit-field values for assigning to a register.
|
||||
*
|
||||
* **Example**:
|
||||
* \code
|
||||
* ECLIC->CFG = _VAL2FLD(CLIC_CLICCFG_NLBIT, 3);
|
||||
* \endcode
|
||||
* \param[in] field Name of the register bit field.
|
||||
* \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
* \return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
* \brief Mask and shift a register value to extract a bit filed value.
|
||||
* \details The macro \ref _FLD2VAL uses the #define's _Pos and _Msk of the related bit
|
||||
* field to extract the value of a bit field from a register.
|
||||
*
|
||||
* **Example**:
|
||||
* \code
|
||||
* nlbits = _FLD2VAL(CLIC_CLICCFG_NLBIT, ECLIC->CFG);
|
||||
* \endcode
|
||||
* \param[in] field Name of the register bit field.
|
||||
* \param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
* \return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/** @} */ /* end of group NMSIS_Core_PeriphAccess */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __NMSIS_GCC_H__ */
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __NMSIS_VERSION_H
|
||||
#define __NMSIS_VERSION_H
|
||||
|
||||
/**
|
||||
* \defgroup NMSIS_Core_VersionControl Version Control
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief Version \#define symbols for NMSIS release specific C/C++ source code
|
||||
* \details
|
||||
*
|
||||
* We followed the [semantic versioning 2.0.0](https://semver.org/) to control NMSIS version.
|
||||
* The version format is **MAJOR.MINOR.PATCH**, increment the:
|
||||
* 1. MAJOR version when you make incompatible API changes,
|
||||
* 2. MINOR version when you add functionality in a backwards compatible manner, and
|
||||
* 3. PATCH version when you make backwards compatible bug fixes.
|
||||
*
|
||||
* The header file `nmsis_version.h` is included by each core header so that these definitions are available.
|
||||
*
|
||||
* **Example Usage for NMSIS Version Check**:
|
||||
* \code
|
||||
* #if defined(__NMSIS_VERSION) && (__NMSIS_VERSION >= 0x00010105)
|
||||
* #warning "Yes, we have NMSIS 1.1.5 or later"
|
||||
* #else
|
||||
* #error "We need NMSIS 1.1.5 or later!"
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file nmsis_version.h
|
||||
* \brief NMSIS Version definitions
|
||||
**/
|
||||
|
||||
/**
|
||||
* \brief Represent the NMSIS major version
|
||||
* \details
|
||||
* The NMSIS major version can be used to
|
||||
* differentiate between NMSIS major releases.
|
||||
* */
|
||||
#define __NMSIS_VERSION_MAJOR (1U)
|
||||
|
||||
/**
|
||||
* \brief Represent the NMSIS minor version
|
||||
* \details
|
||||
* The NMSIS minor version can be used to
|
||||
* query a NMSIS release update including new features.
|
||||
*
|
||||
**/
|
||||
#define __NMSIS_VERSION_MINOR (0U)
|
||||
|
||||
/**
|
||||
* \brief Represent the NMSIS patch version
|
||||
* \details
|
||||
* The NMSIS patch version can be used to
|
||||
* show bug fixes in this package.
|
||||
**/
|
||||
#define __NMSIS_VERSION_PATCH (1U)
|
||||
/**
|
||||
* \brief Represent the NMSIS Version
|
||||
* \details
|
||||
* NMSIS Version format: **MAJOR.MINOR.PATCH**
|
||||
* * MAJOR: \ref __NMSIS_VERSION_MAJOR, stored in `bits [31:16]` of \ref __NMSIS_VERSION
|
||||
* * MINOR: \ref __NMSIS_VERSION_MINOR, stored in `bits [15:8]` of \ref __NMSIS_VERSION
|
||||
* * PATCH: \ref __NMSIS_VERSION_PATCH, stored in `bits [7:0]` of \ref __NMSIS_VERSION
|
||||
**/
|
||||
#define __NMSIS_VERSION ((__NMSIS_VERSION_MAJOR << 16U) | (__NMSIS_VERSION_MINOR << 8) | __NMSIS_VERSION_PATCH)
|
||||
|
||||
/** @} */ /* End of Doxygen Group NMSIS_Core_VersionControl */
|
||||
#endif
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __RISCV_BITS_H__
|
||||
#define __RISCV_BITS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
# define SLL32 sllw
|
||||
# define STORE sd
|
||||
# define LOAD ld
|
||||
# define LWU lwu
|
||||
# define LOG_REGBYTES 3
|
||||
#else
|
||||
# define SLL32 sll
|
||||
# define STORE sw
|
||||
# define LOAD lw
|
||||
# define LWU lw
|
||||
# define LOG_REGBYTES 2
|
||||
#endif /* __riscv_xlen */
|
||||
|
||||
#define REGBYTES (1 << LOG_REGBYTES)
|
||||
|
||||
#if __riscv_flen == 64
|
||||
# define FPSTORE fsd
|
||||
# define FPLOAD fld
|
||||
# define LOG_FPREGBYTES 3
|
||||
#else
|
||||
# define FPSTORE fsw
|
||||
# define FPLOAD flw
|
||||
# define LOG_FPREGBYTES 2
|
||||
#endif /* __riscv_flen */
|
||||
#define FPREGBYTES (1 << LOG_FPREGBYTES)
|
||||
|
||||
#define __rv_likely(x) __builtin_expect((x), 1)
|
||||
#define __rv_unlikely(x) __builtin_expect((x), 0)
|
||||
|
||||
#define __RV_ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
|
||||
#define __RV_ROUNDDOWN(a, b) ((a)/(b)*(b))
|
||||
|
||||
#define __RV_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define __RV_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define __RV_CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
|
||||
|
||||
#define __RV_EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
|
||||
#define __RV_INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#define _AC(X,Y) X
|
||||
#define _AT(T,X) X
|
||||
#else
|
||||
#define __AC(X,Y) (X##Y)
|
||||
#define _AC(X,Y) __AC(X,Y)
|
||||
#define _AT(T,X) ((T)(X))
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#define _UL(x) (_AC(x, UL))
|
||||
#define _ULL(x) (_AC(x, ULL))
|
||||
|
||||
#define _BITUL(x) (_UL(1) << (x))
|
||||
#define _BITULL(x) (_ULL(1) << (x))
|
||||
|
||||
#define UL(x) (_UL(x))
|
||||
#define ULL(x) (_ULL(x))
|
||||
|
||||
#define STR(x) XSTR(x)
|
||||
#define XSTR(x) #x
|
||||
#define __STR(s) #s
|
||||
#define STRINGIFY(s) __STR(s)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /** __RISCV_BITS_H__ */
|
|
@ -0,0 +1,617 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __RISCV_ENCODING_H__
|
||||
#define __RISCV_ENCODING_H__
|
||||
|
||||
#include "riscv_bits.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* \defgroup NMSIS_Core_CSR_Encoding Core CSR Encodings
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief NMSIS Core CSR Encodings
|
||||
* \details
|
||||
*
|
||||
* The following macros are used for CSR encodings
|
||||
* @{
|
||||
*/
|
||||
#define MSTATUS_UIE 0x00000001
|
||||
#define MSTATUS_SIE 0x00000002
|
||||
#define MSTATUS_HIE 0x00000004
|
||||
#define MSTATUS_MIE 0x00000008
|
||||
#define MSTATUS_UPIE 0x00000010
|
||||
#define MSTATUS_SPIE 0x00000020
|
||||
#define MSTATUS_HPIE 0x00000040
|
||||
#define MSTATUS_MPIE 0x00000080
|
||||
#define MSTATUS_SPP 0x00000100
|
||||
#define MSTATUS_MPP 0x00001800
|
||||
#define MSTATUS_FS 0x00006000
|
||||
#define MSTATUS_XS 0x00018000
|
||||
#define MSTATUS_MPRV 0x00020000
|
||||
#define MSTATUS_PUM 0x00040000
|
||||
#define MSTATUS_MXR 0x00080000
|
||||
#define MSTATUS_VM 0x1F000000
|
||||
#define MSTATUS32_SD 0x80000000
|
||||
#define MSTATUS64_SD 0x8000000000000000
|
||||
|
||||
#define MSTATUS_FS_INITIAL 0x00002000
|
||||
#define MSTATUS_FS_CLEAN 0x00004000
|
||||
#define MSTATUS_FS_DIRTY 0x00006000
|
||||
|
||||
#define SSTATUS_UIE 0x00000001
|
||||
#define SSTATUS_SIE 0x00000002
|
||||
#define SSTATUS_UPIE 0x00000010
|
||||
#define SSTATUS_SPIE 0x00000020
|
||||
#define SSTATUS_SPP 0x00000100
|
||||
#define SSTATUS_FS 0x00006000
|
||||
#define SSTATUS_XS 0x00018000
|
||||
#define SSTATUS_PUM 0x00040000
|
||||
#define SSTATUS32_SD 0x80000000
|
||||
#define SSTATUS64_SD 0x8000000000000000
|
||||
|
||||
#define CSR_MCACHE_CTL_IE 0x00000001
|
||||
#define CSR_MCACHE_CTL_DE 0x00010000
|
||||
|
||||
#define DCSR_XDEBUGVER (3U<<30)
|
||||
#define DCSR_NDRESET (1<<29)
|
||||
#define DCSR_FULLRESET (1<<28)
|
||||
#define DCSR_EBREAKM (1<<15)
|
||||
#define DCSR_EBREAKH (1<<14)
|
||||
#define DCSR_EBREAKS (1<<13)
|
||||
#define DCSR_EBREAKU (1<<12)
|
||||
#define DCSR_STOPCYCLE (1<<10)
|
||||
#define DCSR_STOPTIME (1<<9)
|
||||
#define DCSR_CAUSE (7<<6)
|
||||
#define DCSR_DEBUGINT (1<<5)
|
||||
#define DCSR_HALT (1<<3)
|
||||
#define DCSR_STEP (1<<2)
|
||||
#define DCSR_PRV (3<<0)
|
||||
|
||||
#define DCSR_CAUSE_NONE 0
|
||||
#define DCSR_CAUSE_SWBP 1
|
||||
#define DCSR_CAUSE_HWBP 2
|
||||
#define DCSR_CAUSE_DEBUGINT 3
|
||||
#define DCSR_CAUSE_STEP 4
|
||||
#define DCSR_CAUSE_HALT 5
|
||||
|
||||
#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
|
||||
#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
|
||||
#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
|
||||
|
||||
#define MCONTROL_SELECT (1<<19)
|
||||
#define MCONTROL_TIMING (1<<18)
|
||||
#define MCONTROL_ACTION (0x3f<<12)
|
||||
#define MCONTROL_CHAIN (1<<11)
|
||||
#define MCONTROL_MATCH (0xf<<7)
|
||||
#define MCONTROL_M (1<<6)
|
||||
#define MCONTROL_H (1<<5)
|
||||
#define MCONTROL_S (1<<4)
|
||||
#define MCONTROL_U (1<<3)
|
||||
#define MCONTROL_EXECUTE (1<<2)
|
||||
#define MCONTROL_STORE (1<<1)
|
||||
#define MCONTROL_LOAD (1<<0)
|
||||
|
||||
#define MCONTROL_TYPE_NONE 0
|
||||
#define MCONTROL_TYPE_MATCH 2
|
||||
|
||||
#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
|
||||
#define MCONTROL_ACTION_DEBUG_MODE 1
|
||||
#define MCONTROL_ACTION_TRACE_START 2
|
||||
#define MCONTROL_ACTION_TRACE_STOP 3
|
||||
#define MCONTROL_ACTION_TRACE_EMIT 4
|
||||
|
||||
#define MCONTROL_MATCH_EQUAL 0
|
||||
#define MCONTROL_MATCH_NAPOT 1
|
||||
#define MCONTROL_MATCH_GE 2
|
||||
#define MCONTROL_MATCH_LT 3
|
||||
#define MCONTROL_MATCH_MASK_LOW 4
|
||||
#define MCONTROL_MATCH_MASK_HIGH 5
|
||||
|
||||
#define MIP_SSIP (1 << IRQ_S_SOFT)
|
||||
#define MIP_HSIP (1 << IRQ_H_SOFT)
|
||||
#define MIP_MSIP (1 << IRQ_M_SOFT)
|
||||
#define MIP_STIP (1 << IRQ_S_TIMER)
|
||||
#define MIP_HTIP (1 << IRQ_H_TIMER)
|
||||
#define MIP_MTIP (1 << IRQ_M_TIMER)
|
||||
#define MIP_SEIP (1 << IRQ_S_EXT)
|
||||
#define MIP_HEIP (1 << IRQ_H_EXT)
|
||||
#define MIP_MEIP (1 << IRQ_M_EXT)
|
||||
|
||||
#define MIE_SSIE MIP_SSIP
|
||||
#define MIE_HSIE MIP_HSIP
|
||||
#define MIE_MSIE MIP_MSIP
|
||||
#define MIE_STIE MIP_STIP
|
||||
#define MIE_HTIE MIP_HTIP
|
||||
#define MIE_MTIE MIP_MTIP
|
||||
#define MIE_SEIE MIP_SEIP
|
||||
#define MIE_HEIE MIP_HEIP
|
||||
#define MIE_MEIE MIP_MEIP
|
||||
|
||||
/* === Nuclei custom CSR bit mask === */
|
||||
|
||||
#define WFE_WFE (0x1)
|
||||
#define TXEVT_TXEVT (0x1)
|
||||
#define SLEEPVALUE_SLEEPVALUE (0x1)
|
||||
|
||||
#define MCOUNTINHIBIT_IR (1<<2)
|
||||
#define MCOUNTINHIBIT_CY (1<<0)
|
||||
|
||||
#define MILM_CTL_ILM_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10)
|
||||
#define MILM_CTL_ILM_EN (1<<0)
|
||||
|
||||
#define MDLM_CTL_DLM_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10)
|
||||
#define MDLM_CTL_DLM_EN (1<<0)
|
||||
|
||||
#define MSUBM_PTYP (0x3<<8)
|
||||
#define MSUBM_TYP (0x3<<6)
|
||||
|
||||
#define MDCAUSE_MDCAUSE (0x3)
|
||||
|
||||
#define MMISC_CTL_NMI_CAUSE_FFF (1<<9)
|
||||
#define MMISC_CTL_MISALIGN (1<<6)
|
||||
#define MMISC_CTL_BPU (1<<3)
|
||||
|
||||
#define MCACHE_CTL_IC_EN (1<<0)
|
||||
#define MCACHE_CTL_IC_SCPD_MOD (1<<1)
|
||||
#define MCACHE_CTL_DC_EN (1<<16)
|
||||
|
||||
#define MTVT2_MTVT2EN (1<<0)
|
||||
#define MTVT2_COMMON_CODE_ENTRY (((1ULL<<((__riscv_xlen)-2))-1)<<2)
|
||||
|
||||
#define MCFG_INFO_TEE (1<<0)
|
||||
#define MCFG_INFO_ECC (1<<1)
|
||||
#define MCFG_INFO_CLIC (1<<2)
|
||||
#define MCFG_INFO_PLIC (1<<3)
|
||||
#define MCFG_INFO_FIO (1<<4)
|
||||
#define MCFG_INFO_PPI (1<<5)
|
||||
#define MCFG_INFO_NICE (1<<6)
|
||||
#define MCFG_INFO_ILM (1<<7)
|
||||
#define MCFG_INFO_DLM (1<<8)
|
||||
#define MCFG_INFO_ICACHE (1<<9)
|
||||
#define MCFG_INFO_DCACHE (1<<10)
|
||||
|
||||
#define MICFG_IC_SET (0xF<<0)
|
||||
#define MICFG_IC_WAY (0x7<<4)
|
||||
#define MICFG_IC_LSIZE (0x7<<7)
|
||||
#define MICFG_ILM_SIZE (0x1F<<16)
|
||||
#define MICFG_ILM_XONLY (1<<21)
|
||||
|
||||
#define MDCFG_DC_SET (0xF<<0)
|
||||
#define MDCFG_DC_WAY (0x7<<4)
|
||||
#define MDCFG_DC_LSIZE (0x7<<7)
|
||||
#define MDCFG_DLM_SIZE (0x1F<<16)
|
||||
|
||||
#define MPPICFG_INFO_PPI_SIZE (0x1F<<1)
|
||||
#define MPPICFG_INFO_PPI_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10)
|
||||
|
||||
#define MFIOCFG_INFO_FIO_SIZE (0x1F<<1)
|
||||
#define MFIOCFG_INFO_FIO_BPA (((1ULL<<((__riscv_xlen)-10))-1)<<10)
|
||||
|
||||
#define SIP_SSIP MIP_SSIP
|
||||
#define SIP_STIP MIP_STIP
|
||||
|
||||
#define PRV_U 0
|
||||
#define PRV_S 1
|
||||
#define PRV_H 2
|
||||
#define PRV_M 3
|
||||
|
||||
#define VM_MBARE 0
|
||||
#define VM_MBB 1
|
||||
#define VM_MBBID 2
|
||||
#define VM_SV32 8
|
||||
#define VM_SV39 9
|
||||
#define VM_SV48 10
|
||||
|
||||
#define IRQ_S_SOFT 1
|
||||
#define IRQ_H_SOFT 2
|
||||
#define IRQ_M_SOFT 3
|
||||
#define IRQ_S_TIMER 5
|
||||
#define IRQ_H_TIMER 6
|
||||
#define IRQ_M_TIMER 7
|
||||
#define IRQ_S_EXT 9
|
||||
#define IRQ_H_EXT 10
|
||||
#define IRQ_M_EXT 11
|
||||
#define IRQ_COP 12
|
||||
#define IRQ_HOST 13
|
||||
|
||||
#define DEFAULT_RSTVEC 0x00001000
|
||||
#define DEFAULT_NMIVEC 0x00001004
|
||||
#define DEFAULT_MTVEC 0x00001010
|
||||
#define CONFIG_STRING_ADDR 0x0000100C
|
||||
#define EXT_IO_BASE 0x40000000
|
||||
#define DRAM_BASE 0x80000000
|
||||
|
||||
/* === FPU FRM Rounding Mode === */
|
||||
/** FPU Round to Nearest, ties to Even*/
|
||||
#define FRM_RNDMODE_RNE 0x0
|
||||
/** FPU Round Towards Zero */
|
||||
#define FRM_RNDMODE_RTZ 0x1
|
||||
/** FPU Round Down (towards -inf) */
|
||||
#define FRM_RNDMODE_RDN 0x2
|
||||
/** FPU Round Up (towards +inf) */
|
||||
#define FRM_RNDMODE_RUP 0x3
|
||||
/** FPU Round to nearest, ties to Max Magnitude */
|
||||
#define FRM_RNDMODE_RMM 0x4
|
||||
/**
|
||||
* In instruction's rm, selects dynamic rounding mode.
|
||||
* In Rounding Mode register, Invalid */
|
||||
#define FRM_RNDMODE_DYN 0x7
|
||||
|
||||
/* === FPU FFLAGS Accrued Exceptions === */
|
||||
/** FPU Inexact */
|
||||
#define FFLAGS_AE_NX (1<<0)
|
||||
/** FPU Underflow */
|
||||
#define FFLAGS_AE_UF (1<<1)
|
||||
/** FPU Overflow */
|
||||
#define FFLAGS_AE_OF (1<<2)
|
||||
/** FPU Divide by Zero */
|
||||
#define FFLAGS_AE_DZ (1<<3)
|
||||
/** FPU Invalid Operation */
|
||||
#define FFLAGS_AE_NV (1<<4)
|
||||
|
||||
/** Floating Point Register f0-f31, eg. f0 -> FREG(0) */
|
||||
#define FREG(idx) f##idx
|
||||
|
||||
|
||||
/* === PMP CFG Bits === */
|
||||
#define PMP_R 0x01
|
||||
#define PMP_W 0x02
|
||||
#define PMP_X 0x04
|
||||
#define PMP_A 0x18
|
||||
#define PMP_A_TOR 0x08
|
||||
#define PMP_A_NA4 0x10
|
||||
#define PMP_A_NAPOT 0x18
|
||||
#define PMP_L 0x80
|
||||
|
||||
#define PMP_SHIFT 2
|
||||
#define PMP_COUNT 16
|
||||
|
||||
// page table entry (PTE) fields
|
||||
#define PTE_V 0x001 // Valid
|
||||
#define PTE_R 0x002 // Read
|
||||
#define PTE_W 0x004 // Write
|
||||
#define PTE_X 0x008 // Execute
|
||||
#define PTE_U 0x010 // User
|
||||
#define PTE_G 0x020 // Global
|
||||
#define PTE_A 0x040 // Accessed
|
||||
#define PTE_D 0x080 // Dirty
|
||||
#define PTE_SOFT 0x300 // Reserved for Software
|
||||
|
||||
#define PTE_PPN_SHIFT 10
|
||||
|
||||
#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
|
||||
|
||||
#ifdef __riscv
|
||||
|
||||
#ifdef __riscv64
|
||||
# define MSTATUS_SD MSTATUS64_SD
|
||||
# define SSTATUS_SD SSTATUS64_SD
|
||||
# define RISCV_PGLEVEL_BITS 9
|
||||
#else
|
||||
# define MSTATUS_SD MSTATUS32_SD
|
||||
# define SSTATUS_SD SSTATUS32_SD
|
||||
# define RISCV_PGLEVEL_BITS 10
|
||||
#endif /* __riscv64 */
|
||||
|
||||
#define RISCV_PGSHIFT 12
|
||||
#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
|
||||
|
||||
#endif /* __riscv */
|
||||
|
||||
#define DOWNLOAD_MODE_FLASHXIP 0
|
||||
#define DOWNLOAD_MODE_FLASH 1
|
||||
#define DOWNLOAD_MODE_ILM 2
|
||||
#define DOWNLOAD_MODE_DDR 3
|
||||
|
||||
/**
|
||||
* \defgroup NMSIS_Core_CSR_Registers Core CSR Registers
|
||||
* \ingroup NMSIS_Core
|
||||
* \brief NMSIS Core CSR Register Definitions
|
||||
* \details
|
||||
*
|
||||
* The following macros are used for CSR Register Defintions.
|
||||
* @{
|
||||
*/
|
||||
/* === Standard RISC-V CSR Registers === */
|
||||
#define CSR_USTATUS 0x0
|
||||
#define CSR_FFLAGS 0x1
|
||||
#define CSR_FRM 0x2
|
||||
#define CSR_FCSR 0x3
|
||||
#define CSR_CYCLE 0xc00
|
||||
#define CSR_TIME 0xc01
|
||||
#define CSR_INSTRET 0xc02
|
||||
#define CSR_HPMCOUNTER3 0xc03
|
||||
#define CSR_HPMCOUNTER4 0xc04
|
||||
#define CSR_HPMCOUNTER5 0xc05
|
||||
#define CSR_HPMCOUNTER6 0xc06
|
||||
#define CSR_HPMCOUNTER7 0xc07
|
||||
#define CSR_HPMCOUNTER8 0xc08
|
||||
#define CSR_HPMCOUNTER9 0xc09
|
||||
#define CSR_HPMCOUNTER10 0xc0a
|
||||
#define CSR_HPMCOUNTER11 0xc0b
|
||||
#define CSR_HPMCOUNTER12 0xc0c
|
||||
#define CSR_HPMCOUNTER13 0xc0d
|
||||
#define CSR_HPMCOUNTER14 0xc0e
|
||||
#define CSR_HPMCOUNTER15 0xc0f
|
||||
#define CSR_HPMCOUNTER16 0xc10
|
||||
#define CSR_HPMCOUNTER17 0xc11
|
||||
#define CSR_HPMCOUNTER18 0xc12
|
||||
#define CSR_HPMCOUNTER19 0xc13
|
||||
#define CSR_HPMCOUNTER20 0xc14
|
||||
#define CSR_HPMCOUNTER21 0xc15
|
||||
#define CSR_HPMCOUNTER22 0xc16
|
||||
#define CSR_HPMCOUNTER23 0xc17
|
||||
#define CSR_HPMCOUNTER24 0xc18
|
||||
#define CSR_HPMCOUNTER25 0xc19
|
||||
#define CSR_HPMCOUNTER26 0xc1a
|
||||
#define CSR_HPMCOUNTER27 0xc1b
|
||||
#define CSR_HPMCOUNTER28 0xc1c
|
||||
#define CSR_HPMCOUNTER29 0xc1d
|
||||
#define CSR_HPMCOUNTER30 0xc1e
|
||||
#define CSR_HPMCOUNTER31 0xc1f
|
||||
#define CSR_SSTATUS 0x100
|
||||
#define CSR_SIE 0x104
|
||||
#define CSR_STVEC 0x105
|
||||
#define CSR_SSCRATCH 0x140
|
||||
#define CSR_SEPC 0x141
|
||||
#define CSR_SCAUSE 0x142
|
||||
#define CSR_SBADADDR 0x143
|
||||
#define CSR_SIP 0x144
|
||||
#define CSR_SPTBR 0x180
|
||||
#define CSR_MSTATUS 0x300
|
||||
#define CSR_MISA 0x301
|
||||
#define CSR_MEDELEG 0x302
|
||||
#define CSR_MIDELEG 0x303
|
||||
#define CSR_MIE 0x304
|
||||
#define CSR_MTVEC 0x305
|
||||
#define CSR_MCOUNTEREN 0x306
|
||||
#define CSR_MSCRATCH 0x340
|
||||
#define CSR_MEPC 0x341
|
||||
#define CSR_MCAUSE 0x342
|
||||
#define CSR_MBADADDR 0x343
|
||||
#define CSR_MTVAL 0x343
|
||||
#define CSR_MIP 0x344
|
||||
#define CSR_PMPCFG0 0x3a0
|
||||
#define CSR_PMPCFG1 0x3a1
|
||||
#define CSR_PMPCFG2 0x3a2
|
||||
#define CSR_PMPCFG3 0x3a3
|
||||
#define CSR_PMPADDR0 0x3b0
|
||||
#define CSR_PMPADDR1 0x3b1
|
||||
#define CSR_PMPADDR2 0x3b2
|
||||
#define CSR_PMPADDR3 0x3b3
|
||||
#define CSR_PMPADDR4 0x3b4
|
||||
#define CSR_PMPADDR5 0x3b5
|
||||
#define CSR_PMPADDR6 0x3b6
|
||||
#define CSR_PMPADDR7 0x3b7
|
||||
#define CSR_PMPADDR8 0x3b8
|
||||
#define CSR_PMPADDR9 0x3b9
|
||||
#define CSR_PMPADDR10 0x3ba
|
||||
#define CSR_PMPADDR11 0x3bb
|
||||
#define CSR_PMPADDR12 0x3bc
|
||||
#define CSR_PMPADDR13 0x3bd
|
||||
#define CSR_PMPADDR14 0x3be
|
||||
#define CSR_PMPADDR15 0x3bf
|
||||
#define CSR_TSELECT 0x7a0
|
||||
#define CSR_TDATA1 0x7a1
|
||||
#define CSR_TDATA2 0x7a2
|
||||
#define CSR_TDATA3 0x7a3
|
||||
#define CSR_DCSR 0x7b0
|
||||
#define CSR_DPC 0x7b1
|
||||
#define CSR_DSCRATCH 0x7b2
|
||||
#define CSR_MCYCLE 0xb00
|
||||
#define CSR_MINSTRET 0xb02
|
||||
#define CSR_MHPMCOUNTER3 0xb03
|
||||
#define CSR_MHPMCOUNTER4 0xb04
|
||||
#define CSR_MHPMCOUNTER5 0xb05
|
||||
#define CSR_MHPMCOUNTER6 0xb06
|
||||
#define CSR_MHPMCOUNTER7 0xb07
|
||||
#define CSR_MHPMCOUNTER8 0xb08
|
||||
#define CSR_MHPMCOUNTER9 0xb09
|
||||
#define CSR_MHPMCOUNTER10 0xb0a
|
||||
#define CSR_MHPMCOUNTER11 0xb0b
|
||||
#define CSR_MHPMCOUNTER12 0xb0c
|
||||
#define CSR_MHPMCOUNTER13 0xb0d
|
||||
#define CSR_MHPMCOUNTER14 0xb0e
|
||||
#define CSR_MHPMCOUNTER15 0xb0f
|
||||
#define CSR_MHPMCOUNTER16 0xb10
|
||||
#define CSR_MHPMCOUNTER17 0xb11
|
||||
#define CSR_MHPMCOUNTER18 0xb12
|
||||
#define CSR_MHPMCOUNTER19 0xb13
|
||||
#define CSR_MHPMCOUNTER20 0xb14
|
||||
#define CSR_MHPMCOUNTER21 0xb15
|
||||
#define CSR_MHPMCOUNTER22 0xb16
|
||||
#define CSR_MHPMCOUNTER23 0xb17
|
||||
#define CSR_MHPMCOUNTER24 0xb18
|
||||
#define CSR_MHPMCOUNTER25 0xb19
|
||||
#define CSR_MHPMCOUNTER26 0xb1a
|
||||
#define CSR_MHPMCOUNTER27 0xb1b
|
||||
#define CSR_MHPMCOUNTER28 0xb1c
|
||||
#define CSR_MHPMCOUNTER29 0xb1d
|
||||
#define CSR_MHPMCOUNTER30 0xb1e
|
||||
#define CSR_MHPMCOUNTER31 0xb1f
|
||||
#define CSR_MUCOUNTEREN 0x320
|
||||
#define CSR_MSCOUNTEREN 0x321
|
||||
#define CSR_MHPMEVENT3 0x323
|
||||
#define CSR_MHPMEVENT4 0x324
|
||||
#define CSR_MHPMEVENT5 0x325
|
||||
#define CSR_MHPMEVENT6 0x326
|
||||
#define CSR_MHPMEVENT7 0x327
|
||||
#define CSR_MHPMEVENT8 0x328
|
||||
#define CSR_MHPMEVENT9 0x329
|
||||
#define CSR_MHPMEVENT10 0x32a
|
||||
#define CSR_MHPMEVENT11 0x32b
|
||||
#define CSR_MHPMEVENT12 0x32c
|
||||
#define CSR_MHPMEVENT13 0x32d
|
||||
#define CSR_MHPMEVENT14 0x32e
|
||||
#define CSR_MHPMEVENT15 0x32f
|
||||
#define CSR_MHPMEVENT16 0x330
|
||||
#define CSR_MHPMEVENT17 0x331
|
||||
#define CSR_MHPMEVENT18 0x332
|
||||
#define CSR_MHPMEVENT19 0x333
|
||||
#define CSR_MHPMEVENT20 0x334
|
||||
#define CSR_MHPMEVENT21 0x335
|
||||
#define CSR_MHPMEVENT22 0x336
|
||||
#define CSR_MHPMEVENT23 0x337
|
||||
#define CSR_MHPMEVENT24 0x338
|
||||
#define CSR_MHPMEVENT25 0x339
|
||||
#define CSR_MHPMEVENT26 0x33a
|
||||
#define CSR_MHPMEVENT27 0x33b
|
||||
#define CSR_MHPMEVENT28 0x33c
|
||||
#define CSR_MHPMEVENT29 0x33d
|
||||
#define CSR_MHPMEVENT30 0x33e
|
||||
#define CSR_MHPMEVENT31 0x33f
|
||||
#define CSR_MVENDORID 0xf11
|
||||
#define CSR_MARCHID 0xf12
|
||||
#define CSR_MIMPID 0xf13
|
||||
#define CSR_MHARTID 0xf14
|
||||
#define CSR_CYCLEH 0xc80
|
||||
#define CSR_TIMEH 0xc81
|
||||
#define CSR_INSTRETH 0xc82
|
||||
#define CSR_HPMCOUNTER3H 0xc83
|
||||
#define CSR_HPMCOUNTER4H 0xc84
|
||||
#define CSR_HPMCOUNTER5H 0xc85
|
||||
#define CSR_HPMCOUNTER6H 0xc86
|
||||
#define CSR_HPMCOUNTER7H 0xc87
|
||||
#define CSR_HPMCOUNTER8H 0xc88
|
||||
#define CSR_HPMCOUNTER9H 0xc89
|
||||
#define CSR_HPMCOUNTER10H 0xc8a
|
||||
#define CSR_HPMCOUNTER11H 0xc8b
|
||||
#define CSR_HPMCOUNTER12H 0xc8c
|
||||
#define CSR_HPMCOUNTER13H 0xc8d
|
||||
#define CSR_HPMCOUNTER14H 0xc8e
|
||||
#define CSR_HPMCOUNTER15H 0xc8f
|
||||
#define CSR_HPMCOUNTER16H 0xc90
|
||||
#define CSR_HPMCOUNTER17H 0xc91
|
||||
#define CSR_HPMCOUNTER18H 0xc92
|
||||
#define CSR_HPMCOUNTER19H 0xc93
|
||||
#define CSR_HPMCOUNTER20H 0xc94
|
||||
#define CSR_HPMCOUNTER21H 0xc95
|
||||
#define CSR_HPMCOUNTER22H 0xc96
|
||||
#define CSR_HPMCOUNTER23H 0xc97
|
||||
#define CSR_HPMCOUNTER24H 0xc98
|
||||
#define CSR_HPMCOUNTER25H 0xc99
|
||||
#define CSR_HPMCOUNTER26H 0xc9a
|
||||
#define CSR_HPMCOUNTER27H 0xc9b
|
||||
#define CSR_HPMCOUNTER28H 0xc9c
|
||||
#define CSR_HPMCOUNTER29H 0xc9d
|
||||
#define CSR_HPMCOUNTER30H 0xc9e
|
||||
#define CSR_HPMCOUNTER31H 0xc9f
|
||||
#define CSR_MCYCLEH 0xb80
|
||||
#define CSR_MINSTRETH 0xb82
|
||||
#define CSR_MHPMCOUNTER3H 0xb83
|
||||
#define CSR_MHPMCOUNTER4H 0xb84
|
||||
#define CSR_MHPMCOUNTER5H 0xb85
|
||||
#define CSR_MHPMCOUNTER6H 0xb86
|
||||
#define CSR_MHPMCOUNTER7H 0xb87
|
||||
#define CSR_MHPMCOUNTER8H 0xb88
|
||||
#define CSR_MHPMCOUNTER9H 0xb89
|
||||
#define CSR_MHPMCOUNTER10H 0xb8a
|
||||
#define CSR_MHPMCOUNTER11H 0xb8b
|
||||
#define CSR_MHPMCOUNTER12H 0xb8c
|
||||
#define CSR_MHPMCOUNTER13H 0xb8d
|
||||
#define CSR_MHPMCOUNTER14H 0xb8e
|
||||
#define CSR_MHPMCOUNTER15H 0xb8f
|
||||
#define CSR_MHPMCOUNTER16H 0xb90
|
||||
#define CSR_MHPMCOUNTER17H 0xb91
|
||||
#define CSR_MHPMCOUNTER18H 0xb92
|
||||
#define CSR_MHPMCOUNTER19H 0xb93
|
||||
#define CSR_MHPMCOUNTER20H 0xb94
|
||||
#define CSR_MHPMCOUNTER21H 0xb95
|
||||
#define CSR_MHPMCOUNTER22H 0xb96
|
||||
#define CSR_MHPMCOUNTER23H 0xb97
|
||||
#define CSR_MHPMCOUNTER24H 0xb98
|
||||
#define CSR_MHPMCOUNTER25H 0xb99
|
||||
#define CSR_MHPMCOUNTER26H 0xb9a
|
||||
#define CSR_MHPMCOUNTER27H 0xb9b
|
||||
#define CSR_MHPMCOUNTER28H 0xb9c
|
||||
#define CSR_MHPMCOUNTER29H 0xb9d
|
||||
#define CSR_MHPMCOUNTER30H 0xb9e
|
||||
#define CSR_MHPMCOUNTER31H 0xb9f
|
||||
|
||||
/* === CLIC CSR Registers === */
|
||||
#define CSR_MTVT 0x307
|
||||
#define CSR_MNXTI 0x345
|
||||
#define CSR_MINTSTATUS 0x346
|
||||
#define CSR_MSCRATCHCSW 0x348
|
||||
#define CSR_MSCRATCHCSWL 0x349
|
||||
#define CSR_MCLICBASE 0x350
|
||||
|
||||
/* === Nuclei custom CSR Registers === */
|
||||
#define CSR_MCOUNTINHIBIT 0x320
|
||||
#define CSR_MILM_CTL 0x7C0
|
||||
#define CSR_MDLM_CTL 0x7C1
|
||||
#define CSR_MNVEC 0x7C3
|
||||
#define CSR_MSUBM 0x7C4
|
||||
#define CSR_MDCAUSE 0x7C9
|
||||
#define CSR_MCACHE_CTL 0x7CA
|
||||
#define CSR_MMISC_CTL 0x7D0
|
||||
#define CSR_MSAVESTATUS 0x7D6
|
||||
#define CSR_MSAVEEPC1 0x7D7
|
||||
#define CSR_MSAVECAUSE1 0x7D8
|
||||
#define CSR_MSAVEEPC2 0x7D9
|
||||
#define CSR_MSAVECAUSE2 0x7DA
|
||||
#define CSR_MSAVEDCAUSE1 0x7DB
|
||||
#define CSR_MSAVEDCAUSE2 0x7DC
|
||||
#define CSR_PUSHMSUBM 0x7EB
|
||||
#define CSR_MTVT2 0x7EC
|
||||
#define CSR_JALMNXTI 0x7ED
|
||||
#define CSR_PUSHMCAUSE 0x7EE
|
||||
#define CSR_PUSHMEPC 0x7EF
|
||||
#define CSR_MPPICFG_INFO 0x7F0
|
||||
#define CSR_MFIOCFG_INFO 0x7F1
|
||||
#define CSR_SLEEPVALUE 0x811
|
||||
#define CSR_TXEVT 0x812
|
||||
#define CSR_WFE 0x810
|
||||
#define CSR_MICFG_INFO 0xFC0
|
||||
#define CSR_MDCFG_INFO 0xFC1
|
||||
#define CSR_MCFG_INFO 0xFC2
|
||||
|
||||
/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Registers **/
|
||||
|
||||
/* Exception Code in MCAUSE CSR */
|
||||
#define CAUSE_MISALIGNED_FETCH 0x0
|
||||
#define CAUSE_FAULT_FETCH 0x1
|
||||
#define CAUSE_ILLEGAL_INSTRUCTION 0x2
|
||||
#define CAUSE_BREAKPOINT 0x3
|
||||
#define CAUSE_MISALIGNED_LOAD 0x4
|
||||
#define CAUSE_FAULT_LOAD 0x5
|
||||
#define CAUSE_MISALIGNED_STORE 0x6
|
||||
#define CAUSE_FAULT_STORE 0x7
|
||||
#define CAUSE_USER_ECALL 0x8
|
||||
#define CAUSE_SUPERVISOR_ECALL 0x9
|
||||
#define CAUSE_HYPERVISOR_ECALL 0xa
|
||||
#define CAUSE_MACHINE_ECALL 0xb
|
||||
|
||||
/* Exception Subcode in MDCAUSE CSR */
|
||||
#define DCAUSE_FAULT_FETCH_PMP 0x1
|
||||
#define DCAUSE_FAULT_FETCH_INST 0x2
|
||||
|
||||
#define DCAUSE_FAULT_LOAD_PMP 0x1
|
||||
#define DCAUSE_FAULT_LOAD_INST 0x2
|
||||
#define DCAUSE_FAULT_LOAD_NICE 0x3
|
||||
|
||||
#define DCAUSE_FAULT_STORE_PMP 0x1
|
||||
#define DCAUSE_FAULT_STORE_INST 0x2
|
||||
|
||||
/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Encoding **/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __RISCV_ENCODING_H__ */
|
|
@ -0,0 +1,379 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Project: NMSIS DSP Library
|
||||
* Title: riscv_common_tables.h
|
||||
* Description: Extern declaration for common tables
|
||||
*
|
||||
* $Date: 27. January 2017
|
||||
* $Revision: V.1.5.1
|
||||
*
|
||||
* Target Processor: RISC-V Cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _RISCV_COMMON_TABLES_H
|
||||
#define _RISCV_COMMON_TABLES_H
|
||||
|
||||
#include "riscv_math.h"
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FFT_ALLOW_TABLES)
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREV_1024)
|
||||
extern const uint16_t riscvBitRevTable[1024];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_16)
|
||||
extern const float32_t twiddleCoef_16[32];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_32)
|
||||
extern const float32_t twiddleCoef_32[64];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_64)
|
||||
extern const float32_t twiddleCoef_64[128];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_128)
|
||||
extern const float32_t twiddleCoef_128[256];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_256)
|
||||
extern const float32_t twiddleCoef_256[512];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_512)
|
||||
extern const float32_t twiddleCoef_512[1024];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_1024)
|
||||
extern const float32_t twiddleCoef_1024[2048];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_2048)
|
||||
extern const float32_t twiddleCoef_2048[4096];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_F32_4096)
|
||||
extern const float32_t twiddleCoef_4096[8192];
|
||||
#define twiddleCoef twiddleCoef_4096
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_16)
|
||||
extern const q31_t twiddleCoef_16_q31[24];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_32)
|
||||
extern const q31_t twiddleCoef_32_q31[48];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_64)
|
||||
extern const q31_t twiddleCoef_64_q31[96];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_128)
|
||||
extern const q31_t twiddleCoef_128_q31[192];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_256)
|
||||
extern const q31_t twiddleCoef_256_q31[384];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_512)
|
||||
extern const q31_t twiddleCoef_512_q31[768];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_1024)
|
||||
extern const q31_t twiddleCoef_1024_q31[1536];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_2048)
|
||||
extern const q31_t twiddleCoef_2048_q31[3072];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q31_4096)
|
||||
extern const q31_t twiddleCoef_4096_q31[6144];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_16)
|
||||
extern const q15_t twiddleCoef_16_q15[24];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_32)
|
||||
extern const q15_t twiddleCoef_32_q15[48];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_64)
|
||||
extern const q15_t twiddleCoef_64_q15[96];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_128)
|
||||
extern const q15_t twiddleCoef_128_q15[192];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_256)
|
||||
extern const q15_t twiddleCoef_256_q15[384];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_512)
|
||||
extern const q15_t twiddleCoef_512_q15[768];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_1024)
|
||||
extern const q15_t twiddleCoef_1024_q15[1536];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_2048)
|
||||
extern const q15_t twiddleCoef_2048_q15[3072];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_Q15_4096)
|
||||
extern const q15_t twiddleCoef_4096_q15[6144];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_32)
|
||||
extern const float32_t twiddleCoef_rfft_32[32];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_64)
|
||||
extern const float32_t twiddleCoef_rfft_64[64];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_128)
|
||||
extern const float32_t twiddleCoef_rfft_128[128];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_256)
|
||||
extern const float32_t twiddleCoef_rfft_256[256];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_512)
|
||||
extern const float32_t twiddleCoef_rfft_512[512];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_1024)
|
||||
extern const float32_t twiddleCoef_rfft_1024[1024];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_2048)
|
||||
extern const float32_t twiddleCoef_rfft_2048[2048];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_TWIDDLECOEF_RFFT_F32_4096)
|
||||
extern const float32_t twiddleCoef_rfft_4096[4096];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
/* floating-point bit reversal tables */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_16)
|
||||
#define RISCVBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20)
|
||||
extern const uint16_t riscvBitRevIndexTable16[RISCVBITREVINDEXTABLE_16_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_32)
|
||||
#define RISCVBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48)
|
||||
extern const uint16_t riscvBitRevIndexTable32[RISCVBITREVINDEXTABLE_32_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_64)
|
||||
#define RISCVBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56)
|
||||
extern const uint16_t riscvBitRevIndexTable64[RISCVBITREVINDEXTABLE_64_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_128)
|
||||
#define RISCVBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208)
|
||||
extern const uint16_t riscvBitRevIndexTable128[RISCVBITREVINDEXTABLE_128_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_256)
|
||||
#define RISCVBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440)
|
||||
extern const uint16_t riscvBitRevIndexTable256[RISCVBITREVINDEXTABLE_256_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_512)
|
||||
#define RISCVBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448)
|
||||
extern const uint16_t riscvBitRevIndexTable512[RISCVBITREVINDEXTABLE_512_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_1024)
|
||||
#define RISCVBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800)
|
||||
extern const uint16_t riscvBitRevIndexTable1024[RISCVBITREVINDEXTABLE_1024_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_2048)
|
||||
#define RISCVBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808)
|
||||
extern const uint16_t riscvBitRevIndexTable2048[RISCVBITREVINDEXTABLE_2048_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FLT_4096)
|
||||
#define RISCVBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032)
|
||||
extern const uint16_t riscvBitRevIndexTable4096[RISCVBITREVINDEXTABLE_4096_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
|
||||
/* fixed-point bit reversal tables */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_16)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_16[RISCVBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_32)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_32[RISCVBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_64)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_64[RISCVBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_128)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_128[RISCVBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_256)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_256[RISCVBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_512)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_512[RISCVBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_1024)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_1024[RISCVBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_2048)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_2048[RISCVBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_BITREVIDX_FXT_4096)
|
||||
#define RISCVBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
|
||||
extern const uint16_t riscvBitRevIndexTable_fixed_4096[RISCVBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_REALCOEF_F32)
|
||||
extern const float32_t realCoefA[8192];
|
||||
extern const float32_t realCoefB[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_REALCOEF_Q31)
|
||||
extern const q31_t realCoefAQ31[8192];
|
||||
extern const q31_t realCoefBQ31[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_REALCOEF_Q15)
|
||||
extern const q15_t realCoefAQ15[8192];
|
||||
extern const q15_t realCoefBQ15[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_128)
|
||||
extern const float32_t Weights_128[256];
|
||||
extern const float32_t cos_factors_128[128];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_512)
|
||||
extern const float32_t Weights_512[1024];
|
||||
extern const float32_t cos_factors_512[512];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_2048)
|
||||
extern const float32_t Weights_2048[4096];
|
||||
extern const float32_t cos_factors_2048[2048];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_F32_8192)
|
||||
extern const float32_t Weights_8192[16384];
|
||||
extern const float32_t cos_factors_8192[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_128)
|
||||
extern const q15_t WeightsQ15_128[256];
|
||||
extern const q15_t cos_factorsQ15_128[128];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_512)
|
||||
extern const q15_t WeightsQ15_512[1024];
|
||||
extern const q15_t cos_factorsQ15_512[512];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_2048)
|
||||
extern const q15_t WeightsQ15_2048[4096];
|
||||
extern const q15_t cos_factorsQ15_2048[2048];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q15_8192)
|
||||
extern const q15_t WeightsQ15_8192[16384];
|
||||
extern const q15_t cos_factorsQ15_8192[8192];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_128)
|
||||
extern const q31_t WeightsQ31_128[256];
|
||||
extern const q31_t cos_factorsQ31_128[128];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_512)
|
||||
extern const q31_t WeightsQ31_512[1024];
|
||||
extern const q31_t cos_factorsQ31_512[512];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_2048)
|
||||
extern const q31_t WeightsQ31_2048[4096];
|
||||
extern const q31_t cos_factorsQ31_2048[2048];
|
||||
#endif
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FFT_TABLES) || defined(RISCV_TABLE_DCT4_Q31_8192)
|
||||
extern const q31_t WeightsQ31_8192[16384];
|
||||
extern const q31_t cos_factorsQ31_8192[8192];
|
||||
#endif
|
||||
|
||||
#endif /* if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FFT_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FAST_ALLOW_TABLES)
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_RECIP_Q15)
|
||||
extern const q15_t riscvRecipTableQ15[64];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_RECIP_Q31)
|
||||
extern const q31_t riscvRecipTableQ31[64];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
|
||||
|
||||
/* Tables for Fast Math Sine and Cosine */
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_SIN_F32)
|
||||
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_SIN_Q31)
|
||||
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
|
||||
|
||||
#if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_ALL_FAST_TABLES) || defined(RISCV_TABLE_SIN_Q15)
|
||||
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
|
||||
#endif /* !defined(RISCV_DSP_CONFIG_TABLES) defined(RISCV_ALL_FAST_TABLES) */
|
||||
|
||||
#endif /* if !defined(RISCV_DSP_CONFIG_TABLES) || defined(RISCV_FAST_TABLES) */
|
||||
|
||||
#endif /* RISCV_COMMON_TABLES_H */
|
|
@ -0,0 +1,67 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Project: NMSIS DSP Library
|
||||
* Title: riscv_const_structs.h
|
||||
* Description: Constant structs that are initialized for user convenience.
|
||||
* For example, some can be given as arguments to the riscv_cfft_f32() function.
|
||||
*
|
||||
* $Date: 27. January 2017
|
||||
* $Revision: V.1.5.1
|
||||
*
|
||||
* Target Processor: RISC-V Cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _RISCV_CONST_STRUCTS_H
|
||||
#define _RISCV_CONST_STRUCTS_H
|
||||
|
||||
#include "riscv_math.h"
|
||||
#include "riscv_common_tables.h"
|
||||
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len16;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len32;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len64;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len128;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len256;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len512;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len1024;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len2048;
|
||||
extern const riscv_cfft_instance_f32 riscv_cfft_sR_f32_len4096;
|
||||
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len16;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len32;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len64;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len128;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len256;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len512;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len1024;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len2048;
|
||||
extern const riscv_cfft_instance_q31 riscv_cfft_sR_q31_len4096;
|
||||
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len16;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len32;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len64;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len128;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len256;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len512;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len1024;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len2048;
|
||||
extern const riscv_cfft_instance_q15 riscv_cfft_sR_q15_len4096;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,57 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Project: NMSIS NN Library
|
||||
* Title: riscv_nn_tables.h
|
||||
* Description: Extern declaration for NN tables
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: RISC-V Cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _RISCV_NN_TABLES_H
|
||||
#define _RISCV_NN_TABLES_H
|
||||
|
||||
#include "riscv_math.h"
|
||||
|
||||
/**
|
||||
* @brief tables for various activation functions
|
||||
*
|
||||
*/
|
||||
|
||||
extern const q15_t sigmoidTable_q15[256];
|
||||
extern const q7_t sigmoidTable_q7[256];
|
||||
|
||||
extern const q7_t tanhTable_q7[256];
|
||||
extern const q15_t tanhTable_q15[256];
|
||||
|
||||
/**
|
||||
* @brief 2-way tables for various activation functions
|
||||
*
|
||||
* 2-way table, H table for value larger than 1/4
|
||||
* L table for value smaller than 1/4, H table for remaining
|
||||
* We have this only for the q15_t version. It does not make
|
||||
* sense to have it for q7_t type
|
||||
*/
|
||||
extern const q15_t sigmoidHTable_q15[192];
|
||||
extern const q15_t sigmoidLTable_q15[128];
|
||||
|
||||
#endif /* RISCV_NN_TABLES_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: NMSIS NN Library
|
||||
* Title: riscv_nnsupportfunctions.h
|
||||
* Description: Public header file of support functions for NMSIS NN Library
|
||||
*
|
||||
* $Date: July 2019
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: RISC-V Cores
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#ifndef _RISCV_NNSUPPORTFUNCTIONS_H_
|
||||
#define _RISCV_NNSUPPORTFUNCTIONS_H_
|
||||
|
||||
#include "riscv_math.h"
|
||||
#include "riscv_common_tables.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define LEFT_SHIFT(_shift) (_shift > 0 ? _shift : 0)
|
||||
#define RIGHT_SHIFT(_shift) (_shift > 0 ? 0 : -_shift)
|
||||
#define Q31_MIN (0x80000000L)
|
||||
#define Q31_MAX (0x7FFFFFFFL)
|
||||
|
||||
#define MAX(A,B) (A) > (B) ? (A) : (B)
|
||||
#define MIN(A,B) (A) < (B) ? (A) : (B)
|
||||
|
||||
/**
|
||||
* @brief Union for SIMD access of q31/q15/q7 types
|
||||
*/
|
||||
union riscv_nnword
|
||||
{
|
||||
q31_t word;
|
||||
/**< q31 type */
|
||||
q15_t half_words[2];
|
||||
/**< q15 type */
|
||||
q7_t bytes[4];
|
||||
/**< q7 type */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct for specifying activation function types
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RISCV_SIGMOID = 0,
|
||||
/**< Sigmoid activation function */
|
||||
RISCV_TANH = 1,
|
||||
/**< Tanh activation function */
|
||||
} riscv_nn_activation_type;
|
||||
|
||||
/**
|
||||
* @defgroup nndata_convert Neural Network Data Conversion Functions
|
||||
*
|
||||
* Perform data type conversion in-between neural network operations
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Converts the elements of the q7 vector to q15 vector without left-shift
|
||||
* @param[in] *pSrc points to the q7 input vector
|
||||
* @param[out] *pDst points to the q15 output vector
|
||||
* @param[in] blockSize length of the input vector
|
||||
* @return none.
|
||||
*
|
||||
*/
|
||||
void riscv_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
|
||||
|
||||
void riscv_q7_to_q7_no_shift(const q7_t * pSrc, q7_t * pDst, uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief Non-saturating addition of elements of a q7 vector
|
||||
* @param[in] *input Pointer to the q7 input vector
|
||||
* @param[out] *output Pointer to the q31 output variable.
|
||||
* @param[in] block_size length of the input vector
|
||||
* @return none.
|
||||
* \par Description:
|
||||
*
|
||||
* 2^24 samples can be added without saturating the result.
|
||||
*
|
||||
* The equation used for the conversion process is:
|
||||
*
|
||||
* <pre>
|
||||
* sum = input[0] + input[1] + .. + input[block_size -1]
|
||||
* </pre>
|
||||
*
|
||||
* */
|
||||
void riscv_nn_add_q7(const q7_t *input, q31_t *output, uint32_t block_size);
|
||||
|
||||
/**
|
||||
* @brief Converts the elements of the q7 vector to reordered q15 vector without left-shift
|
||||
* @param[in] *pSrc points to the q7 input vector
|
||||
* @param[out] *pDst points to the q15 output vector
|
||||
* @param[in] blockSize length of the input vector
|
||||
* @return none.
|
||||
*
|
||||
*/
|
||||
void riscv_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
|
||||
|
||||
void riscv_q7_to_q7_reordered_no_shift(const q7_t * pSrc, q7_t * pDst, uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief Converts the elements from a q7 vector to a q15 vector with an added offset
|
||||
* @param[in] *src points to the q7 input vector
|
||||
* @param[out] *dst points to the q15 output vector
|
||||
* @param[in] block_size length of the input vector
|
||||
* @param[in] offset q7 offset to be added to each input vector element.
|
||||
* @return none.
|
||||
*
|
||||
* \par Description:
|
||||
*
|
||||
* The equation used for the conversion process is:
|
||||
*
|
||||
* <pre>
|
||||
* dst[n] = (q15_t) src[n] + offset; 0 <= n < block_size.
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
void riscv_q7_to_q15_with_offset(const q7_t *src, q15_t *dst, uint32_t block_size, q7_t offset);
|
||||
|
||||
#if defined (RISCV_MATH_DSP)
|
||||
|
||||
/**
|
||||
* @brief read and expand one q7 word into two q15 words
|
||||
*/
|
||||
|
||||
__STATIC_FORCEINLINE void *read_and_pad(void *source, q31_t * out1, q31_t * out2)
|
||||
{
|
||||
q31_t inA = *__SIMD32(source)++;
|
||||
q31_t inAbuf1 = __SXTB16(__ROR(inA, 8));
|
||||
q31_t inAbuf2 = __SXTB16(inA);
|
||||
|
||||
*out2 = __PKHTB(inAbuf1, inAbuf2, 16);
|
||||
*out1 = __PKHBT(inAbuf2, inAbuf1, 16);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read and expand one q7 word into two q15 words with reordering
|
||||
*/
|
||||
|
||||
__STATIC_FORCEINLINE q7_t *read_and_pad_reordered(q7_t *source, q31_t * out1, q31_t * out2)
|
||||
{
|
||||
q31_t inA = read_q7x4_ia(&source);
|
||||
*out2 = __SXTB16(__ROR(inA, 8));
|
||||
*out1 = __SXTB16(inA);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read and expand one q7 word into two q15 words with reordering and add an offset
|
||||
*/
|
||||
__STATIC_FORCEINLINE q7_t *read_and_pad_reordered_with_offset(q7_t *source, q31_t * out1, q31_t * out2,q31_t offset)
|
||||
{
|
||||
q31_t inA = read_q7x4_ia(&source);
|
||||
|
||||
*out2 = __SXTB16(__ROR(inA, 8));
|
||||
*out1 = __SXTB16(inA);
|
||||
*out1 = __QADD16(*out1,offset);
|
||||
*out2 = __QADD16(*out2,offset);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup NNBasicMath Basic Math Functions for Neural Network Computation
|
||||
*
|
||||
* Basic Math Functions for Neural Network Computation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief q7 vector multiplication with variable output shifts
|
||||
* @param[in] *pSrcA pointer to the first input vector
|
||||
* @param[in] *pSrcB pointer to the second input vector
|
||||
* @param[out] *pDst pointer to the output vector
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void riscv_nn_mult_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
const uint16_t out_shift,
|
||||
uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief q7 vector multiplication with variable output shifts
|
||||
* @param[in] *pSrcA pointer to the first input vector
|
||||
* @param[in] *pSrcB pointer to the second input vector
|
||||
* @param[out] *pDst pointer to the output vector
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void riscv_nn_mult_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
const uint16_t out_shift,
|
||||
uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief macro for adding rounding offset
|
||||
*/
|
||||
#ifndef RISCV_NN_TRUNCATE
|
||||
#define NN_ROUND(out_shift) ( (0x1 << out_shift) >> 1 )
|
||||
#else
|
||||
#define NN_ROUND(out_shift) 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Saturating doubling high multiply. Result matches
|
||||
* NEON instruction VQRDMULH.
|
||||
* @param[in] m1 Multiplicand
|
||||
* @param[in] m2 Multiplier
|
||||
* @return Result of multiplication.
|
||||
*
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t riscv_nn_sat_doubling_high_mult(const q31_t m1, const q31_t m2)
|
||||
{
|
||||
q31_t result = 0;
|
||||
// Rounding offset to add for a right shift of 31
|
||||
q63_t mult = 1 << 30;
|
||||
|
||||
if ((m1 < 0) ^ (m2 < 0))
|
||||
{
|
||||
mult = 1 - mult;
|
||||
}
|
||||
// Gets resolved as a SMLAL instruction
|
||||
mult = mult + (q63_t)m1 * m2;
|
||||
|
||||
// Utilize all of the upper 32 bits. This is the doubling step
|
||||
// as well.
|
||||
result = mult / (1UL << 31);
|
||||
|
||||
if ((m1 == m2) && (m1 == Q31_MIN))
|
||||
{
|
||||
result = Q31_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rounding divide by power of two.
|
||||
* @param[in] dividend - Dividend
|
||||
* @param[in] exponent - Divisor = power(2, exponent)
|
||||
* Range: [0, 31]
|
||||
* @return Rounded result of division. Midpoint is rounded away from zero.
|
||||
*
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t riscv_nn_divide_by_power_of_two(const q31_t dividend, const q31_t exponent)
|
||||
{
|
||||
q31_t result = 0;
|
||||
const q31_t remainder_mask = (1l << exponent) - 1;
|
||||
int32_t remainder = remainder_mask & dividend;
|
||||
|
||||
// Basic division
|
||||
result = dividend >> exponent;
|
||||
|
||||
// Adjust 'result' for rounding (mid point away from zero)
|
||||
q31_t threshold = remainder_mask >> 1;
|
||||
if (result < 0)
|
||||
{
|
||||
threshold++;
|
||||
}
|
||||
if (remainder > threshold)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requantize a given value.
|
||||
* @param[in] val Value to be requantized
|
||||
* @param[in] multiplier multiplier
|
||||
* @param[in] shift left or right shift for 'val * multiplier'
|
||||
*
|
||||
* @return Returns (val * multiplier)/(2 ^ shift)
|
||||
*
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t riscv_nn_requantize(const q31_t val, const q31_t multiplier, const q31_t shift)
|
||||
{
|
||||
return riscv_nn_divide_by_power_of_two(riscv_nn_sat_doubling_high_mult(val * (1 << LEFT_SHIFT(shift)), multiplier),
|
||||
RIGHT_SHIFT(shift));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read 2 q15 elements and post increment pointer.
|
||||
@param[in] in_q15 Pointer to pointer that holds address of input.
|
||||
@return q31 value
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t riscv_nn_read_q15x2_ia(const q15_t **in_q15)
|
||||
{
|
||||
q31_t val;
|
||||
|
||||
memcpy(&val, *in_q15, 4);
|
||||
*in_q15 += 2;
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Read 4 q7 from q7 pointer and post increment pointer.
|
||||
@param[in] in_q7 Pointer to pointer that holds address of input.
|
||||
@return q31 value
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t riscv_nn_read_q7x4_ia(const q7_t **in_q7)
|
||||
{
|
||||
q31_t val;
|
||||
memcpy(&val, *in_q7, 4);
|
||||
*in_q7 += 4;
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue