原始版本
This commit is contained in:
13
RT_Thread/libcpu/c-sky/common/SConscript
Normal file
13
RT_Thread/libcpu/c-sky/common/SConscript
Normal file
@ -0,0 +1,13 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
Import('rtconfig')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
248
RT_Thread/libcpu/c-sky/common/csi_core.h
Normal file
248
RT_Thread/libcpu/c-sky/common/csi_core.h
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* @file csi_core.h
|
||||
* @brief CSI Core Layer Header File
|
||||
* @version V1.0
|
||||
* @date 02. June 2017
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _CORE_H_
|
||||
#define _CORE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "csi_gcc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* ################################## NVIC function ############################################ */
|
||||
|
||||
/**
|
||||
\brief initialize the NVIC interrupt controller
|
||||
\param [in] prio_bits the priority bits of NVIC interrupt controller.
|
||||
*/
|
||||
void drv_nvic_init(uint32_t prio_bits);
|
||||
|
||||
/**
|
||||
\brief Enable External Interrupt
|
||||
\details Enables a device-specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] irq_num External interrupt number. Value cannot be negative.
|
||||
*/
|
||||
void drv_nvic_enable_irq(int32_t irq_num);
|
||||
/**
|
||||
\brief Disable External Interrupt
|
||||
\details Disables a device-specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] irq_num External interrupt number. Value cannot be negative.
|
||||
*/
|
||||
void drv_nvic_disable_irq(int32_t irq_num);
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
|
||||
\param [in] irq_num Interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
*/
|
||||
uint32_t drv_nvic_get_pending_irq(int32_t irq_num);
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of an external interrupt.
|
||||
\param [in] irq_num Interrupt number. Value cannot be negative.
|
||||
*/
|
||||
void drv_nvic_set_pending_irq(int32_t irq_num);
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of an external interrupt.
|
||||
\param [in] irq_num External interrupt number. Value cannot be negative.
|
||||
*/
|
||||
void drv_nvic_clear_pending_irq(int32_t irq_num);
|
||||
|
||||
/**
|
||||
\brief Get Active Interrupt
|
||||
\details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
|
||||
\param [in] irq_num Device specific interrupt number.
|
||||
\return 0 Interrupt status is not active.
|
||||
\return 1 Interrupt status is active.
|
||||
\note irq_num must not be negative.
|
||||
*/
|
||||
uint32_t drv_nvic_get_active(int32_t irq_num);
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of an interrupt.
|
||||
\note The priority cannot be set for every core interrupt.
|
||||
\param [in] irq_num Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
*/
|
||||
void drv_nvic_set_prio(int32_t irq_num, uint32_t priority);
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of an interrupt.
|
||||
The interrupt number can be positive to specify an external (device specific) interrupt,
|
||||
or negative to specify an internal (core) interrupt.
|
||||
\param [in] irq_num Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
uint32_t drv_nvic_get_prio(int32_t irq_num);
|
||||
|
||||
/*@} end of CSI_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## Cache functions #################################### */
|
||||
|
||||
/**
|
||||
\brief Enable I-Cache
|
||||
\details Turns on I-Cache
|
||||
*/
|
||||
void drv_icache_enable(void);
|
||||
|
||||
/**
|
||||
\brief Disable I-Cache
|
||||
\details Turns off I-Cache
|
||||
*/
|
||||
void drv_icache_disable(void);
|
||||
|
||||
/**
|
||||
\brief Invalidate I-Cache
|
||||
\details Invalidates I-Cache
|
||||
*/
|
||||
void drv_icache_invalid(void);
|
||||
|
||||
/**
|
||||
\brief Enable D-Cache
|
||||
\details Turns on D-Cache
|
||||
\note I-Cache also turns on.
|
||||
*/
|
||||
void drv_dcache_enable(void);
|
||||
|
||||
/**
|
||||
\brief Disable D-Cache
|
||||
\details Turns off D-Cache
|
||||
\note I-Cache also turns off.
|
||||
*/
|
||||
void drv_dcache_disable(void);
|
||||
|
||||
/**
|
||||
\brief Invalidate D-Cache
|
||||
\details Invalidates D-Cache
|
||||
\note I-Cache also invalid
|
||||
*/
|
||||
void drv_dcache_invalid(void);
|
||||
|
||||
/**
|
||||
\brief Clean D-Cache
|
||||
\details Cleans D-Cache
|
||||
\note I-Cache also cleans
|
||||
*/
|
||||
void drv_dcache_clean(void);
|
||||
|
||||
/**
|
||||
\brief Clean & Invalidate D-Cache
|
||||
\details Cleans and Invalidates D-Cache
|
||||
\note I-Cache also flush.
|
||||
*/
|
||||
void drv_dcache_clean_invalid(void);
|
||||
|
||||
|
||||
/**
|
||||
\brief D-Cache Invalidate by address
|
||||
\details Invalidates D-Cache for the given address
|
||||
\param[in] addr address (aligned to 16-byte boundary)
|
||||
\param[in] dsize size of memory block (in number of bytes)
|
||||
*/
|
||||
void drv_dcache_invalid_range(uint32_t *addr, int32_t dsize);
|
||||
|
||||
/**
|
||||
\brief D-Cache Clean by address
|
||||
\details Cleans D-Cache for the given address
|
||||
\param[in] addr address (aligned to 16-byte boundary)
|
||||
\param[in] dsize size of memory block (in number of bytes)
|
||||
*/
|
||||
void drv_dcache_clean_range(uint32_t *addr, int32_t dsize);
|
||||
|
||||
/**
|
||||
\brief D-Cache Clean and Invalidate by address
|
||||
\details Cleans and invalidates D_Cache for the given address
|
||||
\param[in] addr address (aligned to 16-byte boundary)
|
||||
\param[in] dsize size of memory block (in number of bytes)
|
||||
*/
|
||||
void drv_dcache_clean_invalid_range(uint32_t *addr, int32_t dsize);
|
||||
|
||||
/**
|
||||
\brief setup cacheable range Cache
|
||||
\details setup Cache range
|
||||
*/
|
||||
void drv_cache_set_range(uint32_t index, uint32_t baseAddr, uint32_t size, uint32_t enable);
|
||||
|
||||
/**
|
||||
\brief Enable cache profile
|
||||
\details Turns on Cache profile
|
||||
*/
|
||||
void drv_cache_enable_profile(void);
|
||||
|
||||
/**
|
||||
\brief Disable cache profile
|
||||
\details Turns off Cache profile
|
||||
*/
|
||||
void drv_cache_disable_profile(void);
|
||||
/**
|
||||
\brief Reset cache profile
|
||||
\details Reset Cache profile
|
||||
*/
|
||||
void drv_cache_reset_profile(void);
|
||||
|
||||
/**
|
||||
\brief cache access times
|
||||
\details Cache access times
|
||||
\note every 256 access add 1.
|
||||
*/
|
||||
uint32_t drv_cache_get_access_time(void);
|
||||
|
||||
/**
|
||||
\brief cache miss times
|
||||
\details Cache miss times
|
||||
\note every 256 miss add 1.
|
||||
*/
|
||||
uint32_t drv_cache_get_miss_time(void);
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
|
||||
/**
|
||||
\brief CORE timer Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\param [in] irq_num core timer Interrupt number.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
uint32_t drv_coret_config(uint32_t ticks, int32_t irq_num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CORE_H_ */
|
||||
36
RT_Thread/libcpu/c-sky/common/csi_gcc.h
Normal file
36
RT_Thread/libcpu/c-sky/common/csi_gcc.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* @file csi_gcc.h
|
||||
* @brief CSI Header File for GCC.
|
||||
* @version V1.0
|
||||
* @date 02. June 2017
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _CSI_GCC_H_
|
||||
#define _CSI_GCC_H_
|
||||
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __ALWAYS_INLINE __attribute__((always_inline)) static inline
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "csi_reg.h"
|
||||
#include "csi_instr.h"
|
||||
#include "csi_simd.h"
|
||||
|
||||
#endif /* _CSI_GCC_H_ */
|
||||
447
RT_Thread/libcpu/c-sky/common/csi_instr.h
Normal file
447
RT_Thread/libcpu/c-sky/common/csi_instr.h
Normal file
@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* @file csi_instr.h
|
||||
* @brief CSI Header File for instruct.
|
||||
* @version V1.0
|
||||
* @date 02. June 2017
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _CSI_INSTR_H_
|
||||
#define _CSI_INSTR_H_
|
||||
|
||||
|
||||
#define __CSI_GCC_OUT_REG(r) "=r" (r)
|
||||
#define __CSI_GCC_USE_REG(r) "r" (r)
|
||||
|
||||
/**
|
||||
\brief No Operation
|
||||
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__ALWAYS_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile("nop");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||
*/
|
||||
__ALWAYS_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile("wait");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
\details Wait For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
|
||||
*/
|
||||
__ALWAYS_INLINE void __WAIT(void)
|
||||
{
|
||||
__ASM volatile("wait");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Doze For Interrupt
|
||||
\details Doze For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
|
||||
*/
|
||||
__ALWAYS_INLINE void __DOZE(void)
|
||||
{
|
||||
__ASM volatile("doze");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Stop For Interrupt
|
||||
\details Stop For Interrupt is a hint instruction that suspends execution until one interrupt occurs.
|
||||
*/
|
||||
__ALWAYS_INLINE void __STOP(void)
|
||||
{
|
||||
__ASM volatile("stop");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or memory,
|
||||
after the instruction has been completed.
|
||||
*/
|
||||
__ALWAYS_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile("sync"::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
\details Acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__ALWAYS_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile("sync"::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
\details Ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__ALWAYS_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile("sync"::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in integer value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
return __builtin_bswap32(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in two unsigned short values.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
#if (__CK80X >= 2)
|
||||
__ASM volatile("revh %0, %1" : __CSI_GCC_OUT_REG(result) : __CSI_GCC_USE_REG(value));
|
||||
#else
|
||||
result = ((value & 0xFF000000) >> 8) | ((value & 0x00FF0000) << 8) |
|
||||
((value & 0x0000FF00) >> 8) | ((value & 0x000000FF) << 8);
|
||||
#endif
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order in signed short value
|
||||
\details Reverses the byte order in a signed short value with sign extension to integer.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__ALWAYS_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
return (short)(((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\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
|
||||
\return Rotated value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32U - op2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\details Causes the processor to enter Debug state
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
*/
|
||||
__ALWAYS_INLINE void __BKPT()
|
||||
{
|
||||
__ASM volatile("bkpt");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\details Reverses the bit order of the given value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__CK80X >= 0x03U)
|
||||
__ASM volatile("brev %0, %1" : "=r"(result) : "r"(value));
|
||||
#else
|
||||
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
#endif
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\details Counts the number of leading zeros of a data value.
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __builtin_clz
|
||||
/**
|
||||
\details This function saturates a signed value.
|
||||
\param [in] x Value to be saturated
|
||||
\param [in] y Bit position to saturate to [1..32]
|
||||
\return Saturated value.
|
||||
*/
|
||||
__ALWAYS_INLINE int32_t __SSAT(int32_t x, uint32_t y)
|
||||
{
|
||||
int32_t posMax, negMin;
|
||||
uint32_t i;
|
||||
|
||||
posMax = 1;
|
||||
|
||||
for (i = 0; i < (y - 1); i++)
|
||||
{
|
||||
posMax = posMax * 2;
|
||||
}
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
posMax = (posMax - 1);
|
||||
|
||||
if (x > posMax)
|
||||
{
|
||||
x = posMax;
|
||||
}
|
||||
|
||||
// x &= (posMax * 2 + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
negMin = -posMax;
|
||||
|
||||
if (x < negMin)
|
||||
{
|
||||
x = negMin;
|
||||
}
|
||||
|
||||
// x &= (posMax * 2 - 1);
|
||||
}
|
||||
|
||||
return (x);
|
||||
}
|
||||
|
||||
/**
|
||||
\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
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __USAT(uint32_t value, uint32_t sat)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
|
||||
{
|
||||
result = 0xFFFFFFFF >> (32 - sat);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = value;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate for internal use
|
||||
\details Saturates an unsigned value, should not call directly.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __IUSAT(uint32_t value, uint32_t sat)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
if (value & 0x80000000) /* only overflow set bit-31 */
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else if ((((0xFFFFFFFF >> sat) << sat) & value) != 0)
|
||||
{
|
||||
result = 0xFFFFFFFF >> (32 - sat);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = value;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Rotate Right with Extend
|
||||
\details This function moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
\note carry input will always 0.
|
||||
\param [in] op1 Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __RRX(uint32_t op1)
|
||||
{
|
||||
#if (__CK80X >= 2)
|
||||
uint32_t res = 0;
|
||||
__ASM volatile("bgeni t0, 31\n\t"
|
||||
"lsri %0, 1\n\t"
|
||||
"movt %1, t0\n\t"
|
||||
"or %1, %1, %0\n\t"
|
||||
: "=r"(op1), "=r"(res): "0"(op1), "1"(res): "t0");
|
||||
return res;
|
||||
#else
|
||||
uint32_t res = 0;
|
||||
__ASM volatile("movi r7, 0\n\t"
|
||||
"bseti r7, 31\n\t"
|
||||
"lsri %0, 1\n\t"
|
||||
"bf 1f\n\t"
|
||||
"mov %1, r7\n\t"
|
||||
"1:\n\t"
|
||||
"or %1, %1, %0\n\t"
|
||||
: "=r"(op1), "=r"(res): "0"(op1), "1"(res): "r7");
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
\param [in] addr Pointer to location
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__ALWAYS_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
//#warning "__LDRBT"
|
||||
__ASM volatile("ldb %0, (%1, 0)" : "=r"(result) : "r"(addr));
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
\param [in] addr Pointer to location
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__ALWAYS_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
//#warning "__LDRHT"
|
||||
__ASM volatile("ldh %0, (%1, 0)" : "=r"(result) : "r"(addr));
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
\param [in] addr Pointer to location
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __LDRT(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
//#warning "__LDRT"
|
||||
__ASM volatile("ldw %0, (%1, 0)" : "=r"(result) : "r"(addr));
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] addr Pointer to location
|
||||
*/
|
||||
__ALWAYS_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
//#warning "__STRBT"
|
||||
__ASM volatile("stb %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] addr Pointer to location
|
||||
*/
|
||||
__ALWAYS_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
//#warning "__STRHT"
|
||||
__ASM volatile("sth %1, (%0, 0)" :: "r"(addr), "r"((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] addr Pointer to location
|
||||
*/
|
||||
__ALWAYS_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
//#warning "__STRT"
|
||||
__ASM volatile("stw %1, (%0, 0)" :: "r"(addr), "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/*@}*/ /* end of group CSI_Core_InstructionInterface */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type, always 0.
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_FPUType(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _CSI_INSTR_H_ */
|
||||
366
RT_Thread/libcpu/c-sky/common/csi_reg.h
Normal file
366
RT_Thread/libcpu/c-sky/common/csi_reg.h
Normal file
@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* @file csi_reg.h
|
||||
* @brief CSI Header File for reg.
|
||||
* @version V1.0
|
||||
* @date 02. June 2017
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _CSI_REG_H_
|
||||
#define _CSI_REG_H_
|
||||
|
||||
#include<csi_gcc.h>
|
||||
|
||||
/**
|
||||
\brief Enable IRQ Interrupts
|
||||
\details Enables IRQ interrupts by setting the IE-bit in the PSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__ALWAYS_INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile("psrset ie");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by clearing the IE-bit in the PSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__ALWAYS_INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile("psrclr ie");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get PSR
|
||||
\details Returns the content of the PSR Register.
|
||||
\return PSR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_PSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, psr" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set PSR
|
||||
\details Writes the given value to the PSR Register.
|
||||
\param [in] psr PSR Register value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_PSR(uint32_t psr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, psr" : : "r"(psr));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get SP
|
||||
\details Returns the content of the SP Register.
|
||||
\return SP Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_SP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mov %0, sp" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set SP
|
||||
\details Writes the given value to the SP Register.
|
||||
\param [in] sp SP Register value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_SP(uint32_t sp)
|
||||
{
|
||||
__ASM volatile("mov sp, %0" : : "r"(sp): "sp");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get VBR Register
|
||||
\details Returns the content of the VBR Register.
|
||||
\return VBR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_VBR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, vbr" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set VBR
|
||||
\details Writes the given value to the VBR Register.
|
||||
\param [in] vbr VBR Register value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_VBR(uint32_t vbr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, vbr" : : "r"(vbr));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get EPC Register
|
||||
\details Returns the content of the EPC Register.
|
||||
\return EPC Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_EPC(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, epc" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set EPC
|
||||
\details Writes the given value to the EPC Register.
|
||||
\param [in] epc EPC Register value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_EPC(uint32_t epc)
|
||||
{
|
||||
__ASM volatile("mtcr %0, epc" : : "r"(epc));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get EPSR
|
||||
\details Returns the content of the EPSR Register.
|
||||
\return EPSR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_EPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, epsr" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set EPSR
|
||||
\details Writes the given value to the EPSR Register.
|
||||
\param [in] epsr EPSR Register value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_EPSR(uint32_t epsr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, epsr" : : "r"(epsr));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get CPUID Register
|
||||
\details Returns the content of the CPUID Register.
|
||||
\return CPUID Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_CPUID(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<13, 0>" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
#if (__SOFTRESET_PRESENT == 1U)
|
||||
/**
|
||||
\brief Set SRCR
|
||||
\details Assigns the given value to the SRCR.
|
||||
\param [in] srcr SRCR value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_SRCR(uint32_t srcr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, cr<31, 0>\n" : : "r"(srcr));
|
||||
}
|
||||
#endif /* __SOFTRESET_PRESENT == 1U */
|
||||
|
||||
#if (__MGU_PRESENT == 1U)
|
||||
/**
|
||||
\brief Get CCR
|
||||
\details Returns the current value of the CCR.
|
||||
\return CCR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_CCR(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<18, 0>\n" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set CCR
|
||||
\details Assigns the given value to the CCR.
|
||||
\param [in] ccr CCR value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_CCR(uint32_t ccr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, cr<18, 0>\n" : : "r"(ccr));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get CAPR
|
||||
\details Returns the current value of the CAPR.
|
||||
\return CAPR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_CAPR(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<19, 0>\n" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set CAPR
|
||||
\details Assigns the given value to the CAPR.
|
||||
\param [in] capr CAPR value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_CAPR(uint32_t capr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, cr<19, 0>\n" : : "r"(capr));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set PACR
|
||||
\details Assigns the given value to the PACR.
|
||||
|
||||
\param [in] pacr PACR value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_PACR(uint32_t pacr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, cr<20, 0>\n" : : "r"(pacr));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get PACR
|
||||
\details Returns the current value of PACR.
|
||||
\return PACR value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_PACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<20, 0>" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set PRSR
|
||||
\details Assigns the given value to the PRSR.
|
||||
|
||||
\param [in] prsr PRSR value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_PRSR(uint32_t prsr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, cr<21, 0>\n" : : "r"(prsr));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get PRSR
|
||||
\details Returns the current value of PRSR.
|
||||
\return PRSR value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_PRSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<21, 0>" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
#endif /* __MGU_PRESENT == 1U */
|
||||
|
||||
/**
|
||||
\brief Get user sp
|
||||
\details Returns the current value of user r14.
|
||||
\return UR14 value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_UR14(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<14, 1>" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Enable interrupts and exceptions
|
||||
\details Enables interrupts and exceptions by setting the IE-bit and EE-bit in the PSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__ALWAYS_INLINE void __enable_excp_irq(void)
|
||||
{
|
||||
__ASM volatile("psrset ee, ie");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable interrupts and exceptions
|
||||
\details Disables interrupts and exceptions by clearing the IE-bit and EE-bit in the PSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__ALWAYS_INLINE void __disable_excp_irq(void)
|
||||
{
|
||||
__ASM volatile("psrclr ee, ie");
|
||||
}
|
||||
|
||||
#if (__GSR_GCR_PRESENT == 1U)
|
||||
/**
|
||||
\brief Get GSR
|
||||
\details Returns the content of the GSR Register.
|
||||
\return GSR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_GSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<12, 0>" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get GCR
|
||||
\details Returns the content of the GCR Register.
|
||||
\return GCR Register value
|
||||
*/
|
||||
__ALWAYS_INLINE uint32_t __get_GCR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile("mfcr %0, cr<11, 0>" : "=r"(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set GCR
|
||||
\details Writes the given value to the GCR Register.
|
||||
\param [in] gcr GCR Register value to set
|
||||
*/
|
||||
__ALWAYS_INLINE void __set_GCR(uint32_t gcr)
|
||||
{
|
||||
__ASM volatile("mtcr %0, cr<11, 0>" : : "r"(gcr));
|
||||
}
|
||||
|
||||
#endif /* (__GSR_GCR_PRESENT == 1U) */
|
||||
|
||||
|
||||
#endif /* _CSI_REG_H_ */
|
||||
1483
RT_Thread/libcpu/c-sky/common/csi_simd.h
Normal file
1483
RT_Thread/libcpu/c-sky/common/csi_simd.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user