From 43d245bae2107430622f6baddad4265b874d422d Mon Sep 17 00:00:00 2001 From: Paul Mathieu Date: Sun, 8 May 2022 20:55:58 -0700 Subject: [PATCH] arm: add uart echo app --- arm/hal/lib/common/clocking/xil_clocking.c | 128 ++ arm/hal/lib/common/clocking/xil_clocking.h | 65 + arm/hal/lib/common/intr/xinterrupt_wrap.c | 446 ++++++ arm/hal/lib/common/intr/xinterrupt_wrap.h | 74 + arm/hal/lib/common/print.c | 36 + arm/hal/lib/common/sleep.h | 99 ++ arm/hal/lib/common/versal/xil_error_node.h | 479 ++++++ arm/hal/lib/common/versal/xil_hw.h | 89 ++ arm/hal/lib/common/xbasic_types.h | 113 ++ arm/hal/lib/common/xdebug.h | 73 + arm/hal/lib/common/xenv.h | 169 +++ arm/hal/lib/common/xenv_standalone.h | 350 +++++ arm/hal/lib/common/xil_assert.c | 126 ++ arm/hal/lib/common/xil_assert.h | 176 +++ arm/hal/lib/common/xil_cache_vxworks.h | 74 + arm/hal/lib/common/xil_hal.h | 43 + arm/hal/lib/common/xil_io.h | 412 +++++ arm/hal/lib/common/xil_macroback.h | 1112 ++++++++++++++ arm/hal/lib/common/xil_mem.c | 70 + arm/hal/lib/common/xil_mem.h | 47 + arm/hal/lib/common/xil_printf.c | 447 ++++++ arm/hal/lib/common/xil_printf.h | 53 + arm/hal/lib/common/xil_sleepcommon.c | 85 ++ arm/hal/lib/common/xil_testcache.c | 341 +++++ arm/hal/lib/common/xil_testcache.h | 54 + arm/hal/lib/common/xil_testio.c | 273 ++++ arm/hal/lib/common/xil_testio.h | 76 + arm/hal/lib/common/xil_testmem.c | 1575 ++++++++++++++++++++ arm/hal/lib/common/xil_testmem.h | 165 ++ arm/hal/lib/common/xil_types.h | 203 +++ arm/hal/lib/common/xil_util.c | 1238 +++++++++++++++ arm/hal/lib/common/xil_util.h | 232 +++ arm/hal/lib/common/xplatform_info.c | 147 ++ arm/hal/lib/common/xplatform_info.h | 115 ++ arm/hal/lib/common/xstatus.h | 522 +++++++ arm/hal/uart/Makefile | 39 + arm/hal/uart/xuartlite.c | 655 ++++++++ arm/hal/uart/xuartlite.h | 274 ++++ arm/hal/uart/xuartlite_g.c | 63 + arm/hal/uart/xuartlite_i.h | 100 ++ arm/hal/uart/xuartlite_intr.c | 309 ++++ arm/hal/uart/xuartlite_l.c | 95 ++ arm/hal/uart/xuartlite_l.h | 310 ++++ arm/hal/uart/xuartlite_selftest.c | 114 ++ arm/hal/uart/xuartlite_sinit.c | 122 ++ arm/hal/uart/xuartlite_stats.c | 118 ++ arm/main.cc | 48 +- arm/makefile | 25 +- 48 files changed, 11971 insertions(+), 8 deletions(-) create mode 100644 arm/hal/lib/common/clocking/xil_clocking.c create mode 100644 arm/hal/lib/common/clocking/xil_clocking.h create mode 100644 arm/hal/lib/common/intr/xinterrupt_wrap.c create mode 100644 arm/hal/lib/common/intr/xinterrupt_wrap.h create mode 100644 arm/hal/lib/common/print.c create mode 100644 arm/hal/lib/common/sleep.h create mode 100644 arm/hal/lib/common/versal/xil_error_node.h create mode 100644 arm/hal/lib/common/versal/xil_hw.h create mode 100644 arm/hal/lib/common/xbasic_types.h create mode 100644 arm/hal/lib/common/xdebug.h create mode 100644 arm/hal/lib/common/xenv.h create mode 100644 arm/hal/lib/common/xenv_standalone.h create mode 100644 arm/hal/lib/common/xil_assert.c create mode 100644 arm/hal/lib/common/xil_assert.h create mode 100644 arm/hal/lib/common/xil_cache_vxworks.h create mode 100644 arm/hal/lib/common/xil_hal.h create mode 100644 arm/hal/lib/common/xil_io.h create mode 100644 arm/hal/lib/common/xil_macroback.h create mode 100644 arm/hal/lib/common/xil_mem.c create mode 100644 arm/hal/lib/common/xil_mem.h create mode 100644 arm/hal/lib/common/xil_printf.c create mode 100644 arm/hal/lib/common/xil_printf.h create mode 100644 arm/hal/lib/common/xil_sleepcommon.c create mode 100644 arm/hal/lib/common/xil_testcache.c create mode 100644 arm/hal/lib/common/xil_testcache.h create mode 100644 arm/hal/lib/common/xil_testio.c create mode 100644 arm/hal/lib/common/xil_testio.h create mode 100644 arm/hal/lib/common/xil_testmem.c create mode 100644 arm/hal/lib/common/xil_testmem.h create mode 100644 arm/hal/lib/common/xil_types.h create mode 100644 arm/hal/lib/common/xil_util.c create mode 100644 arm/hal/lib/common/xil_util.h create mode 100644 arm/hal/lib/common/xplatform_info.c create mode 100644 arm/hal/lib/common/xplatform_info.h create mode 100644 arm/hal/lib/common/xstatus.h create mode 100644 arm/hal/uart/Makefile create mode 100644 arm/hal/uart/xuartlite.c create mode 100644 arm/hal/uart/xuartlite.h create mode 100644 arm/hal/uart/xuartlite_g.c create mode 100644 arm/hal/uart/xuartlite_i.h create mode 100644 arm/hal/uart/xuartlite_intr.c create mode 100644 arm/hal/uart/xuartlite_l.c create mode 100644 arm/hal/uart/xuartlite_l.h create mode 100644 arm/hal/uart/xuartlite_selftest.c create mode 100644 arm/hal/uart/xuartlite_sinit.c create mode 100644 arm/hal/uart/xuartlite_stats.c diff --git a/arm/hal/lib/common/clocking/xil_clocking.c b/arm/hal/lib/common/clocking/xil_clocking.c new file mode 100644 index 0000000..50df3c5 --- /dev/null +++ b/arm/hal/lib/common/clocking/xil_clocking.c @@ -0,0 +1,128 @@ +/****************************************************************************** +* Copyright (c) 2020 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_clocking.c +* +* The xil_clocking.c file contains clocking related functions and macros. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 7.2 sd  02/06/20 First release of clocking
+* 7.2 sd  03/20/20 Added checking for isolation case
+* 
+* +******************************************************************************/ + +#include "xil_clocking.h" +/************************** Variable Definitions *****************************/ + +#if defined (XPAR_XCRPSU_0_DEVICE_ID) && defined (XCLOCKING) + +XClock ClockInstance; /* Instance of clock Controller */ +XClockPs_Config *ConfigPtr; + + +XStatus Xil_ClockInit(void) +{ + XStatus Status = XST_FAILURE; + + /* Lookup clock configurations */ + ConfigPtr = XClock_LookupConfig(XPAR_XCLOCKPS_DEVICE_ID); + + /* Initialize the Clock controller driver */ + Status = XClock_CfgInitialize(&ClockInstance, ConfigPtr); + return Status; +} + +XStatus Xil_ClockEnable(XClock_OutputClks ClockId) +{ + + XStatus Status = XST_FAILURE; + + Status = XClock_EnableClock(ClockId); + return Status; +} + +XStatus Xil_ClockDisable(XClock_OutputClks ClockId) +{ + XStatus Status = XST_FAILURE; + + Status = XClock_DisableClock(ClockId); + return Status; +} + +XStatus Xil_ClockGetRate(XClock_OutputClks ClockId, XClockRate *Rate) +{ + XStatus Status = XST_FAILURE; + + Xil_AssertNonvoid(Rate != NULL); + + Status = XClock_GetRate(ClockId, Rate); + if (XST_SUCCESS == Status) { + xdbg_printf(XDBG_DEBUG_GENERAL, "Operating rate = %lx\n",*Rate); + } else { + xdbg_printf(XDBG_DEBUG_ERROR, "Failed: Fetching rate\r\n"); + } + return Status; +} + +XStatus Xil_ClockSetRate(XClock_OutputClks ClockId, XClockRate Rate, + XClockRate *SetRate) +{ + XStatus Status = XST_FAILURE; + + Xil_AssertNonvoid(SetRate != NULL); + + if (Rate == 0) { + return XST_FAILURE; + } + Status = XClock_SetRate(ClockId, Rate, SetRate); + if (XST_SUCCESS != Status) { + xdbg_printf(XDBG_DEBUG_ERROR, "Failed Setting rate\n"); + } + return Status; +} + +#else +XStatus Xil_ClockGetRate(XClock_OutputClks ClockId, XClockRate *Rate) +{ + (void) ClockId; + (void) Rate; + return XST_FAILURE; +} + +XStatus Xil_ClockSetRate(XClock_OutputClks ClockId, XClockRate Rate, + XClockRate *SetRate) { + (void) ClockId; + (void) Rate; + (void) SetRate; + return XST_FAILURE; +} + +XStatus Xil_ClockInit(void) +{ + return XST_SUCCESS; +} + +XStatus Xil_ClockEnable(XClock_OutputClks ClockId) +{ + (void) ClockId; + return XST_SUCCESS; +} + +XStatus Xil_ClockDisable(XClock_OutputClks ClockId) +{ + (void) ClockId; + return XST_SUCCESS; +} + +#endif /* XCLOCKING */ diff --git a/arm/hal/lib/common/clocking/xil_clocking.h b/arm/hal/lib/common/clocking/xil_clocking.h new file mode 100644 index 0000000..ee4f9e0 --- /dev/null +++ b/arm/hal/lib/common/clocking/xil_clocking.h @@ -0,0 +1,65 @@ +/****************************************************************************** +* Copyright (c) 2020 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_clocking.h +* +* The xil_clocking.h file contains clocking related functions and macros. +* certain conditions. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 7.2 sd  12/11/19 First release
+* 7.2 sd  03/20/20 Added checking for isolation case
+* 7.7 sk  01/10/22 Add function prototype for Xil_ClockGetRate to fix
+* 		   misra_c_2012_rule_8_4 violation.
+* 
+* +******************************************************************************/ + +#ifndef XIL_CLOCKING_H /* prevent circular inclusions */ +#define XIL_CLOCKING_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xdebug.h" +#include "xil_printf.h" +#include "xil_types.h" +#include "xil_assert.h" +#include "xparameters.h" +#include "xstatus.h" +#if defined (XPAR_XCRPSU_0_DEVICE_ID) +#include "xclockps.h" +#else +typedef u32 XClock_OutputClks; +typedef u64 XClockRate; +#endif + +/***************************** Include Files *********************************/ + + +/************************** Constant Definitions *****************************/ + + +XStatus Xil_ClockDisable(XClock_OutputClks ClockId); +XStatus Xil_ClockEnable(XClock_OutputClks ClockId); +XStatus Xil_ClockInit(void); +XStatus Xil_ClockGet(void); +XStatus Xil_ClockSetRate(XClock_OutputClks ClockId, XClockRate Rate, XClockRate *SetRate); +XStatus Xil_ClockGetRate(XClock_OutputClks ClockId, XClockRate *Rate); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/arm/hal/lib/common/intr/xinterrupt_wrap.c b/arm/hal/lib/common/intr/xinterrupt_wrap.c new file mode 100644 index 0000000..7956ba7 --- /dev/null +++ b/arm/hal/lib/common/intr/xinterrupt_wrap.c @@ -0,0 +1,446 @@ +/****************************************************************************** +* Copyright (c) 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xinterrupt_wrap.c +* +* The xinterrupt_wrap.c file contains interrupt related functions and macros. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 7.2   mus  22/11/21 First release of xil interrupt support
+* 
+* +******************************************************************************/ + +#include "xinterrupt_wrap.h" + +#ifdef XIL_INTERRUPT + +#if defined (XPAR_SCUGIC) /* available in xscugic.h */ +XScuGic XScuGicInstance; +#endif + +#if defined (XPAR_AXI_INTC) /* available in xintc.h */ +XIntc XIntcInstance ; +#endif + +/*****************************************************************************/ +/** +* +* @brief Initializes the interrupt controller. +* +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return XST_SUCCESS if initialization was successful +* XST_FAILURE in case of failure +* +* @note None. +* +******************************************************************************/ +int XConfigInterruptCntrl(UINTPTR IntcParent) { + int Status = XST_FAILURE; + UINTPTR BaseAddr = XGet_BaseAddr(IntcParent); + + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + XScuGic_Config *CfgPtr = NULL; + if (XScuGicInstance.IsReady != XIL_COMPONENT_IS_READY) { + CfgPtr = XScuGic_LookupConfigBaseAddr(BaseAddr); + Status = XScuGic_CfgInitialize(&XScuGicInstance, CfgPtr, 0); + } else { + Status = XST_SUCCESS; + } + return Status; + #else + return XST_FAILURE; + #endif + } else { + #if defined (XPAR_AXI_INTC) + if (XIntcInstance.IsStarted != XIL_COMPONENT_IS_STARTED) + Status = XIntc_Initialize(&XIntcInstance, BaseAddr); + else + Status = XST_SUCCESS; + return Status; + #else + return XST_FAILURE; + #endif + } +} + +/*****************************************************************************/ +/** +* +* @brief connects to the interrupt controller. +* +* @param IntrId: Interrupt Id. +* @param IntrHandler: Interrupt handler. +* @param CallBackRef: Callback reference for handler. +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return XST_SUCCESS if initialization was successful +* XST_FAILURE in case of failure +* +* @note None. +* +******************************************************************************/ +int XConnectToInterruptCntrl(u32 IntrId, void *IntrHandler, void *CallBackRef, UINTPTR IntcParent) +{ + int Status; + + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + + #if defined (XPAR_SCUGIC) + u16 IntrNum = XGet_IntrId(IntrId); + u16 Offset = XGet_IntrOffset(IntrId); + + IntrNum += Offset; + Status = XScuGic_Connect(&XScuGicInstance, IntrNum, \ + (Xil_ExceptionHandler) IntrHandler, CallBackRef); + return Status; + #else + return XST_FAILURE; + #endif + } else { + #if defined (XPAR_AXI_INTC) + Status = XIntc_Connect(&XIntcInstance, IntrId, \ + (XInterruptHandler)IntrHandler, CallBackRef); + return Status; + #else + return XST_FAILURE; + #endif + + } +} + +/*****************************************************************************/ +/** +* +* @brief disconnects the interrupt controller. +* +* @param IntrId: Interrupt Id. +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return XST_SUCCESS if initialization was successful +* XST_FAILURE in case of failure +* +* @note None. +* +******************************************************************************/ +int XDisconnectInterruptCntrl(u32 IntrId, UINTPTR IntcParent) +{ + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) { + #if defined (XPAR_SCUGIC) + u16 IntrNum = XGet_IntrId(IntrId); + u16 Offset = XGet_IntrOffset(IntrId); + + IntrNum += Offset; + XScuGic_Disconnect(&XScuGicInstance, IntrNum); + #else + return XST_FAILURE; + #endif + } else { + #if defined (XPAR_AXI_INTC) + XIntc_Disconnect(&XIntcInstance, IntrId); + #else + return XST_FAILURE; + #endif + } + return XST_FAILURE; +} + +/*****************************************************************************/ +/** +* +* @brief Starts the interrupt controller. +* +* @param Mode: Interrupt controller mode type. +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return XST_SUCCESS if initialization was successful +* XST_FAILURE in case of failure +* +* @note None. +* +******************************************************************************/ +int XStartInterruptCntrl(u32 Mode, UINTPTR IntcParent) +{ +#if defined (XPAR_AXI_INTC) + int Status = XST_FAILURE; +#else + (void) Mode; +#endif + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + /* + * For XPAR_SCUGIC, XConfigInterruptCntrl starts controller + * hence returning without doing anything + */ + return 0; + } else { + #if defined (XPAR_AXI_INTC) + if (XIntcInstance.IsStarted != XIL_COMPONENT_IS_STARTED) + Status = XIntc_Start(&XIntcInstance, Mode); + else + Status = XST_SUCCESS; + return Status; + #else + return XST_FAILURE; + #endif + + } + +} + +/*****************************************************************************/ +/** +* +* @brief Enable the interrupt id. +* +* @param IntrId: Interrupt Id. +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XEnableIntrId( u32 IntrId, UINTPTR IntcParent) +{ + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + u16 IntrNum = XGet_IntrId(IntrId); + u16 Offset = XGet_IntrOffset(IntrId); + IntrNum += Offset; + XScuGic_Enable(&XScuGicInstance, IntrNum); + #endif + + } else { + #if defined (XPAR_AXI_INTC) + XIntc_Enable(&XIntcInstance, IntrId); + #endif + } + +} + +/*****************************************************************************/ +/** +* +* @brief disable the interrupt id. +* +* @param IntrId: Interrupt Id. +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XDisableIntrId( u32 IntrId, UINTPTR IntcParent) +{ + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + u16 IntrNum = XGet_IntrId(IntrId); + u16 Offset = XGet_IntrOffset(IntrId); + + IntrNum += Offset; + XScuGic_Disable(&XScuGicInstance, IntrNum); + #endif + } else { + #if defined (XPAR_AXI_INTC) + XIntc_Disable(&XIntcInstance, IntrId); + #endif + } + +} + +/*****************************************************************************/ +/** +* +* @brief Configures the priority and trigger type. +* +* @param IntrId: Interrupt Id. +* @param Priority: Priority of the interrupt +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XSetPriorityTriggerType( u32 IntrId, u8 Priority, UINTPTR IntcParent) +{ +#if defined (XPAR_SCUGIC) + u8 Trigger = (((XGet_TriggerType(IntrId) == 1) || (XGet_TriggerType(IntrId) == 2)) ? XINTR_IS_EDGE_TRIGGERED + : XINTR_IS_LEVEL_TRIGGERED); +#else + (void) Priority; +#endif + u16 IntrNum = XGet_IntrId(IntrId); + u16 Offset = XGet_IntrOffset(IntrId); + + IntrNum += Offset; + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + XScuGic_SetPriorityTriggerType(&XScuGicInstance, IntrNum, Priority, Trigger); + #endif + } + + +} + +/*****************************************************************************/ +/** +* +* @brief Gets the priority of the interrupt controller. +* +* @param IntrId: Interrupt Id. +* @param Priority: Priority of the interrupt +* @param Trigger: Trigger type of the interrupt +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XGetPriorityTriggerType( u32 IntrId, u8 *Priority, u8 *Trigger, UINTPTR IntcParent) +{ +#if !defined (XPAR_SCUGIC) + (void) IntrId; + (void) Priority; + (void) Trigger; +#endif + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + XScuGic_GetPriorityTriggerType(&XScuGicInstance, IntrId, Priority, Trigger); + #endif + } +} + +/*****************************************************************************/ +/** +* +* @brief stops the interrupt controller. +* +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XStopInterruptCntrl( UINTPTR IntcParent) +{ + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + XScuGic_Stop(&XScuGicInstance); + #endif + } else { + #if defined (XPAR_AXI_INTC) + XIntc_Stop(&XIntcInstance); + #endif + + } + +} + +/*****************************************************************************/ +/** +* +* @brief Registers the interrupt handler. +* +* @param IntrHandler: Interrupt handler. +* @param IntcParent: Interrupt controller baseaddress and type. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XRegisterInterruptHandler(void *IntrHandler, UINTPTR IntcParent) +{ + if (XGet_IntcType(IntcParent) == XINTC_TYPE_IS_SCUGIC) + { + #if defined (XPAR_SCUGIC) + if (IntrHandler == NULL) + { + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \ + (Xil_ExceptionHandler) XScuGic_InterruptHandler, + &XScuGicInstance); + } else { + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \ + (Xil_ExceptionHandler) IntrHandler, + &XScuGicInstance); + + } + #endif + } else { + #if defined (XPAR_AXI_INTC) + if (IntrHandler == NULL) + { + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \ + (Xil_ExceptionHandler) XIntc_InterruptHandler, + &XIntcInstance); + } else { + Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, \ + (Xil_ExceptionHandler) IntrHandler, + &XIntcInstance); + } + #endif + } +} + +/*****************************************************************************/ +/** +* +* @brief Setup the interrupt system. +* +* @param DriverInstance: Driver instance pointer. +* @param IntrHandler: Interrupt handler funtion pointer. +* @param IntrId: Interrupt Id. +* @param IntcParent: Interrupt controller baseaddress and type. +* @param Priority: Interrupt priority. +* +* @return XST_SUCCESS if initialization was successful +* XST_FAILURE in case of failure +* +* @note None. +* +******************************************************************************/ +int XSetupInterruptSystem(void *DriverInstance, void *IntrHandler, u32 IntrId, UINTPTR IntcParent, u16 Priority) +{ + int Status; + + Status = XConfigInterruptCntrl(IntcParent); + if (Status != XST_SUCCESS) + return XST_FAILURE; + XSetPriorityTriggerType( IntrId, Priority, IntcParent); + Status = XConnectToInterruptCntrl( IntrId, (Xil_ExceptionHandler) IntrHandler, \ + DriverInstance, IntcParent); + if (Status != XST_SUCCESS) + return XST_FAILURE; + #if defined (XPAR_AXI_INTC) + XStartInterruptCntrl(XIN_REAL_MODE, IntcParent); + #endif + XEnableIntrId(IntrId, IntcParent); + XRegisterInterruptHandler(NULL, IntcParent); + Xil_ExceptionInit(); + Xil_ExceptionEnable(); + return XST_SUCCESS; +} +#endif diff --git a/arm/hal/lib/common/intr/xinterrupt_wrap.h b/arm/hal/lib/common/intr/xinterrupt_wrap.h new file mode 100644 index 0000000..0731ff1 --- /dev/null +++ b/arm/hal/lib/common/intr/xinterrupt_wrap.h @@ -0,0 +1,74 @@ +/****************************************************************************** +* Copyright (c) 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ +/*****************************************************************************/ +/** +* +* @file xinterrupt_wrap.h +* +* The xinterrupt_wrap.h file contains interrupt related functions and macros. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 7.2   mus  22/11/21 First release of xil interrupt support
+* 
+* +******************************************************************************/ + +#ifndef XINTERRUPT_WRAP_H /* prevent circular inclusions */ +#define XINTERRUPT_WRAP_H /* by using protection macros */ + +#include "xil_types.h" +#include "xstatus.h" +#include "xparameters.h" +#include "xil_exception.h" + +#ifdef XIL_INTERRUPT +#if defined(XPAR_AXI_INTC) +#include "xintc.h" +#endif + +#if defined(XPAR_SCUGIC) +#include "xscugic.h" +#define XSPI_INTR_OFFSET 32U +#endif + +#define XINTERRUPT_DEFAULT_PRIORITY 0xA0U /* AXI INTC doesnt support priority setting, it is default priority for GIC interrupts */ +#define XINTC_TYPE_IS_SCUGIC 0U +#define XINTC_TYPE_IS_INTC 1U +#define XINTR_IS_EDGE_TRIGGERED 3U +#define XINTR_IS_LEVEL_TRIGGERED 1U + +#define XINTC_TYPE_MASK 0x1 +#define XINTC_INTR_TYPE_MASK 0x100000 +#define XINTC_BASEADDR_MASK 0xFFFFFFFFFFFFFFFE +#define XINTC_INTRID_MASK 0xFFF +#define XINTC_TRIGGER_MASK 0xF000 +#define XINTC_TRIGGER_SHIFT 12 +#define XINTC_INTR_TYPE_SHIFT 20U +#define XGet_IntcType(IntParent) (IntParent & XINTC_TYPE_MASK) +#define XGet_IntrType(IntId) ((IntId & XINTC_INTR_TYPE_MASK) >> XINTC_INTR_TYPE_SHIFT) +#define XGet_BaseAddr(IntParent) (IntParent & XINTC_BASEADDR_MASK) +#define XGet_IntrId(IntId) (IntId & XINTC_INTRID_MASK) +#define XGet_TriggerType(IntId) ((IntId & XINTC_TRIGGER_MASK) >> XINTC_TRIGGER_SHIFT) +#define XGet_IntrOffset(IntId) (( XGet_IntrType(IntId) == 1) ? 16 : 32) /* For PPI offset is 16 and for SPI it is 32 */ + +extern int XConfigInterruptCntrl(UINTPTR IntcParent); +extern int XConnectToInterruptCntrl(u32 IntrId, void *IntrHandler, void *CallBackRef, UINTPTR IntcParent); +extern int XDisconnectInterruptCntrl(u32 IntrId, UINTPTR IntcParent); +extern int XStartInterruptCntrl(u32 Mode, UINTPTR IntcParent); +extern void XEnableIntrId( u32 IntrId, UINTPTR IntcParent); +extern void XDisableIntrId( u32 IntrId, UINTPTR IntcParent); +extern void XSetPriorityTriggerType( u32 IntrId, u8 Priority, UINTPTR IntcParent); +extern void XGetPriorityTriggerType( u32 IntrId, u8 *Priority, u8 *Trigger, UINTPTR IntcParent); +extern void XStopInterruptCntrl( UINTPTR IntcParent); +extern void XRegisterInterruptHandler( void *IntrHandler, UINTPTR IntcParent); +extern int XSetupInterruptSystem(void *DriverInstance, void *IntrHandler, u32 IntrId, UINTPTR IntcParent, u16 Priority); +#endif + +#endif /* end of protection macro */ diff --git a/arm/hal/lib/common/print.c b/arm/hal/lib/common/print.c new file mode 100644 index 0000000..e8ac3d4 --- /dev/null +++ b/arm/hal/lib/common/print.c @@ -0,0 +1,36 @@ +/* print.c -- print a string on the output device. + * + * Copyright (c) 1995 Cygnus Support + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + * + */ + +/* + * print -- do a raw print of a string + */ +#include "xil_printf.h" + +void print(const char8 *ptr) +{ +#if defined (__aarch64__) && (HYP_GUEST == 1) && (EL1_NONSECURE == 1) && defined (XEN_USE_PV_CONSOLE) + XPVXenConsole_Write(ptr); +#else +#ifdef STDOUT_BASEADDRESS + while (*ptr != (char8)0) { + outbyte (*ptr); + ptr++; + } +#else +(void)ptr; +#endif +#endif +} diff --git a/arm/hal/lib/common/sleep.h b/arm/hal/lib/common/sleep.h new file mode 100644 index 0000000..73b2ea0 --- /dev/null +++ b/arm/hal/lib/common/sleep.h @@ -0,0 +1,99 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +/*****************************************************************************/ +/** +* @file sleep.h +* +* This header file contains ARM Cortex A53,A9,R5,Microblaze specific sleep +* related APIs. +* +*
+* MODIFICATION HISTORY :
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 6.6   srm  11/02/17 Added processor specific sleep routines
+*								 function prototypes.
+* 7.7	sk   01/10/22 Typecast sleep declaration argument from unsigned int to
+* 		      u32 to fix misra_c_2012_directive_4_6 violation.
+* 7.7	sk   01/10/22 Modify the return type of sleep_R5 and usleep_R5 from
+* 		      unsigned to void to fix misra_c_2012_rule_17_7 violation.
+* 7.7	sk   03/02/22 Update usleep_R5 and usleep parameter types to fix misra_
+*		      c_2012_directive_4_6 violation.
+*
+* 
+* +******************************************************************************/ + +#ifndef SLEEP_H +#define SLEEP_H + +#include "xil_types.h" +#include "xil_io.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ +/** +* +* This macro polls an address periodically until a condition is met or till the +* timeout occurs. +* The minimum timeout for calling this macro is 100us. If the timeout is less +* than 100us, it still waits for 100us. Also the unit for the timeout is 100us. +* If the timeout is not a multiple of 100us, it waits for a timeout of +* the next usec value which is a multiple of 100us. +* +* @param IO_func - accessor function to read the register contents. +* Depends on the register width. +* @param ADDR - Address to be polled +* @param VALUE - variable to read the value +* @param COND - Condition to checked (usually involves VALUE) +* @param TIMEOUT_US - timeout in micro seconds +* +* @return 0 - when the condition is met +* -1 - when the condition is not met till the timeout period +* +* @note none +* +*****************************************************************************/ +#define Xil_poll_timeout(IO_func, ADDR, VALUE, COND, TIMEOUT_US) \ + ( { \ + u64 timeout = TIMEOUT_US/100; \ + if(TIMEOUT_US%100!=0) \ + timeout++; \ + for(;;) { \ + VALUE = IO_func(ADDR); \ + if(COND) \ + break; \ + else { \ + usleep(100); \ + timeout--; \ + if(timeout==0) \ + break; \ + } \ + } \ + (timeout>0) ? 0 : -1; \ + } ) + +void usleep(ULONG useconds); +void sleep(u32 seconds); +void usleep_R5(ULONG useconds); +void sleep_R5(u32 seconds); +int usleep_MB(unsigned long useconds); +unsigned sleep_MB(unsigned int seconds); +int usleep_A53(unsigned long useconds); +unsigned sleep_A53(unsigned int seconds); +int usleep_A9(unsigned long useconds); +unsigned sleep_A9(unsigned int seconds); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arm/hal/lib/common/versal/xil_error_node.h b/arm/hal/lib/common/versal/xil_error_node.h new file mode 100644 index 0000000..2d5f3f9 --- /dev/null +++ b/arm/hal/lib/common/versal/xil_error_node.h @@ -0,0 +1,479 @@ +/****************************************************************************** +* Copyright (c) 2021 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_error_node.h +* +* This is the file which contains node IDs information for error events. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who 	 Date        Changes
+* ----- -------- -------- -----------------------------------------------------
+* 7.7   bsv      12/22/2021 Initial release
+*       ma       01/17/2022 Add PLM exceptions to SW errors list
+*
+* 
+* +* @note +* +******************************************************************************/ +#ifndef XIL_ERROR_NODE_H +#define XIL_ERROR_NODE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Constant Definitions *****************************/ +/**@name Versal Event Node IDs + * @defgroup xileventnodes Event Node IDs + * @ingroup xilnodeids + * @{ + */ + /** + * Error Event Node Ids + */ +#define XIL_NODETYPE_EVENT_ERROR_PMC_ERR1 (0x28100000U) +#define XIL_NODETYPE_EVENT_ERROR_PMC_ERR2 (0x28104000U) +#define XIL_NODETYPE_EVENT_ERROR_PSM_ERR1 (0x28108000U) +#define XIL_NODETYPE_EVENT_ERROR_PSM_ERR2 (0x2810C000U) +#define XIL_NODETYPE_EVENT_ERROR_SW_ERR (0x28110000U) +/** + * @} + */ + +/**@name Versal Error event Mask + * @defgroup xilerroreventmask Error Event Mask + * @ingroup xilnodeids + * @{ + * @defgroup pmcerr1 Error Event Mask for PMC ERR1 + * @ingroup xilerroreventmask + * @{ + * @brief Error Events belong to PMC ERR1 Node + */ + +/** Error event mask for PMC Boot Correctable Error. + * Set by ROM code during ROM execution during Boot. */ +#define XIL_EVENT_ERROR_MASK_BOOT_CR (0x00000001U) + +/** Error event mask for PMC Boot Non-Correctable Error. + * Set by ROM code during ROM execution during Boot. */ +#define XIL_EVENT_ERROR_MASK_BOOT_NCR (0x00000002U) + +/** Error event mask for PMC Firmware Boot Correctable Error. + * Set by PLM during firmware execution during Boot. */ +#define XIL_EVENT_ERROR_MASK_FW_CR (0x00000004U) + +/** Error event mask for PMC Firmware Boot Non-Correctable Error. + * Set by PLM during firmware execution during Boot. */ +#define XIL_EVENT_ERROR_MASK_FW_NCR (0x00000008U) + +/** Error event mask for General Software Correctable Error. + * Set by any processors after Boot. */ +#define XIL_EVENT_ERROR_MASK_GSW_CR (0x00000010U) + +/** Error event mask for General Software Non-Correctable Error. + * Set by any processors after Boot. */ +#define XIL_EVENT_ERROR_MASK_GSW_NCR (0x00000020U) + +/** Error event mask for CFU Error. */ +#define XIL_EVENT_ERROR_MASK_CFU (0x00000040U) + +/** Error event mask for CFRAME Error. */ +#define XIL_EVENT_ERROR_MASK_CFRAME (0x00000080U) + +/** Error event mask for PSM Correctable Error, + * Summary from PSM Error Management. */ +#define XIL_EVENT_ERROR_MASK_PMC_PSM_CR (0x00000100U) + +/** Error event mask for PSM Non-Correctable Error, + * Summary from PSM Error Management. */ +#define XIL_EVENT_ERROR_MASK_PMC_PSM_NCR (0x00000200U) + +/** Error event mask for DDRMC MB Correctable ECC Error. */ +#define XIL_EVENT_ERROR_MASK_DDRMB_CR (0x00000400U) + +/** Error event mask for DDRMC MB Non-Correctable ECC Error. */ +#define XIL_EVENT_ERROR_MASK_DDRMB_NCR (0x00000800U) + +/** Error event mask for NoC Type1 Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_NOCTYPE1_CR (0x00001000U) + +/** Error event mask for NoC Type1 Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_NOCTYPE1_NCR (0x00002000U) + +/** Error event mask for NoC User Error. */ +#define XIL_EVENT_ERROR_MASK_NOCUSER (0x00004000U) + +/** Error event mask for MMCM Lock Error. */ +#define XIL_EVENT_ERROR_MASK_MMCM (0x00008000U) + +/** Error event mask for ME Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_AIE_CR (0x00010000U) + +/** Error event mask for ME Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_AIE_NCR (0x00020000U) + +/** Error event mask for DDRMC MC Correctable ECC Error. */ +#define XIL_EVENT_ERROR_MASK_DDRMC_CR (0x00040000U) + +/** Error event mask for DDRMC MC Non-Correctable ECC Error. */ +#define XIL_EVENT_ERROR_MASK_DDRMC_NCR (0x00080000U) + +/** Error event mask for GT Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_GT_CR (0x00100000U) + +/** Error event mask for GT Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_GT_NCR (0x00200000U) + +/** Error event mask for PL Sysmon Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_PLSMON_CR (0x00400000U) + +/** Error event mask for PL Sysmon Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_PLSMON_NCR (0x00800000U) + +/** Error event mask for User defined PL generic error. */ +#define XIL_EVENT_ERROR_MASK_PL0 (0x01000000U) + +/** Error event mask for User defined PL generic error. */ +#define XIL_EVENT_ERROR_MASK_PL1 (0x02000000U) + +/** Error event mask for User defined PL generic error. */ +#define XIL_EVENT_ERROR_MASK_PL2 (0x04000000U) + +/** Error event mask for User defined PL generic error. */ +#define XIL_EVENT_ERROR_MASK_PL3 (0x08000000U) + +/** Error event mask for NPI Root Error. */ +#define XIL_EVENT_ERROR_MASK_NPIROOT (0x10000000U) + +/** Error event mask for SSIT Error from Slave SLR1, + * Only used in Master SLR. */ +#define XIL_EVENT_ERROR_MASK_SSIT3 (0x20000000U) + +/** Error event mask for SSIT Error from Slave SLR2, + * Only used in Master SLR. */ +#define XIL_EVENT_ERROR_MASK_SSIT4 (0x40000000U) + +/** Error event mask for SSIT Error from Slave SLR3, + * Only used in Master SLR. */ +#define XIL_EVENT_ERROR_MASK_SSIT5 (0x80000000U) +/** + * @} + */ + +/** + * @defgroup pmcerr2 Error Event Mask for PMC ERR2 + * @ingroup xilerroreventmask + * @{ + * @brief Error Events belong to PMC ERR2 Node + */ +/** Error event mask for General purpose PMC error, + * can be triggered by any of the following peripherals:, + * - PMC Global Regsiters,- PMC Clock & Reset (CRP),- PMC IOU Secure SLCR, + * - PMC IOU SLCR,- BBRAM Controller,- PMC Analog Control Registers, + * - RTC Control Registers. */ +#define XIL_EVENT_ERROR_MASK_PMCAPB (0x00000001U) + +/** Error event mask for PMC ROM Validation Error. */ +#define XIL_EVENT_ERROR_MASK_PMCROM (0x00000002U) + +/** Error event mask for PMC PPU0 MB TMR Fatal Error. */ +#define XIL_EVENT_ERROR_MASK_MB_FATAL0 (0x00000004U) + +/** Error event mask for PMC PPU1 MB TMR Fatal Error. */ +#define XIL_EVENT_ERROR_MASK_MB_FATAL1 (0x00000008U) + +/** Error event mask for PMC Switch and PMC IOU Parity Errors. */ +#define XIL_EVENT_ERROR_MASK_PMCPAR (0x00000010U) + +/** Error event mask for PMC Correctable Errors:, + * PPU0 RAM correctable error.,PPU1 instruction RAM correctable error., + * PPU1 data RAM correctable error. */ +#define XIL_EVENT_ERROR_MASK_PMC_CR (0x00000020U) + +/** Error event mask for PMC Non-Correctable Errors: + * PPU0 RAM non-correctable error, PPU1 instruction RAM non-correctable error, + * PPU1 data RAM non-correctable error, PRAM non-correctable error. */ +#define XIL_EVENT_ERROR_MASK_PMC_NCR (0x00000040U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[0]. + * Indicates an alarm condition on any of SUPPLY0 to SUPPLY31. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON0 (0x00000080U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[1]. + * Indicates an alarm condition on any of SUPPLY32 to SUPPLY63. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON1 (0x00000100U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[2]. + * Indicates an alarm condition on any of SUPPLY64 to SUPPLY95. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON2 (0x00000200U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[3]. + * Indicates an alarm condition on any of SUPPLY96 to SUPPLY127. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON3 (0x00000400U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[4]. + * Indicates an alarm condition on any of SUPPLY128 to SUPPLY159. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON4 (0x00000800U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[8]. + * Indicates an over-temperature alarm. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON8 (0x00008000U) + +/** Error event mask for PMC Temperature Shutdown Alert and Power Supply + * Failure Detection Errors from PMC Sysmon alarm[9]. + * Indicates a device temperature alarm. */ +#define XIL_EVENT_ERROR_MASK_PMCSMON9 (0x00010000U) + +/** Error event mask for CFI Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_CFI (0x00020000U) + +/** Error event mask for CFRAME SEU CRC Error. */ +#define XIL_EVENT_ERROR_MASK_SEUCRC (0x00040000U) + +/** Error event mask for CFRAME SEU ECC Error. */ +#define XIL_EVENT_ERROR_MASK_SEUECC (0x00080000U) + +/** Error event mask for RTC Alarm Error. */ +#define XIL_EVENT_ERROR_MASK_RTCALARM (0x00400000U) + +/** Error event mask for PMC NPLL Lock Error, + * this error can be unmasked after the NPLL is locked to alert when the + * NPLL loses lock. */ +#define XIL_EVENT_ERROR_MASK_NPLL (0x00800000U) + +/** Error event mask for PMC PPLL Lock Error, + * this error can be unmasked after the PPLL is locked to alert when the + * PPLL loses lock. */ +#define XIL_EVENT_ERROR_MASK_PPLL (0x01000000U) + +/** Error event mask for Clock Monitor Errors, collected from CRP's + * CLKMON_STATUS register. */ +#define XIL_EVENT_ERROR_MASK_CLKMON (0x02000000U) + +/** Error event mask for PMC Interconnect Timeout Errors. + * Collected from: Interconnect mission interrupt status register, + * Interconnect latent status register, Timeout interrupt status register + * for SERBs. */ +#define XIL_EVENT_ERROR_MASK_PMCTO (0x04000000U) + +/** Error event mask for PMC XMPU Errors: Register access error on APB, + * Read permission violation, Write permission violation, Security violation. */ +#define XIL_EVENT_ERROR_MASK_PMCXMPU (0x08000000U) + +/** Error event mask for PMC XPPU Errors: Register access error on APB, + * Master ID not found, Read permission violation, Master ID parity error, + * Master ID access violation, TrustZone violation, Aperture parity error. */ +#define XIL_EVENT_ERROR_MASK_PMCXPPU (0x10000000U) + +/** Error event mask for For Master SLR: SSIT Error from Slave SLR1, + * For Slave SLRs: SSIT Error0 from Master SLR. */ +#define XIL_EVENT_ERROR_MASK_SSIT0 (0x20000000U) + +/** Error event mask for For Master SLR: SSIT Error from Slave SLR2, + * For Slave SLRs: SSIT Error1 from Master SLR. */ +#define XIL_EVENT_ERROR_MASK_SSIT1 (0x40000000U) + +/** Error event mask for For Master SLR: SSIT Error from Slave SLR3, + * For Slave SLRs: SSIT Error2 from Master SLR. */ +#define XIL_EVENT_ERROR_MASK_SSIT2 (0x80000000U) +/** + * @} + */ + +/** + * @defgroup psmerr1 Error Event Mask for PSM ERR1 + * @ingroup xilerroreventmask + * @{ + * @brief Error Events belong to PSM ERR1 Node + */ +/** Error event mask for PS Software can write to trigger register to + * generate this Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_PS_SW_CR (0x00000001U) + +/** Error event mask for PS Software can write to trigger register to + * generate this Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_PS_SW_NCR (0x00000002U) + +/** Error event mask for PSM Firmware can write to trigger register to + * generate this Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_PSM_B_CR (0x00000004U) + +/** Error event mask for PSM Firmware can write to trigger register to + * generate this Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_PSM_B_NCR (0x00000008U) + +/** Error event mask for Or of MB Fatal1, Fatal2, Fatal3 Error. */ +#define XIL_EVENT_ERROR_MASK_MB_FATAL (0x00000010U) + +/** Error event mask for PSM Correctable. */ +#define XIL_EVENT_ERROR_MASK_PSM_CR (0x00000020U) + +/** Error event mask for PSM Non-Correctable. */ +#define XIL_EVENT_ERROR_MASK_PSM_NCR (0x00000040U) + +/** Error event mask for Non-Correctable ECC Error during an OCM access. */ +#define XIL_EVENT_ERROR_MASK_OCM_ECC (0x00000080U) + +/** Error event mask for Non-Correctable ECC Error during APU L2 Cache access. */ +#define XIL_EVENT_ERROR_MASK_L2_ECC (0x00000100U) + +/** Error event mask for ECC Errors during a RPU memory access. + * Floating-point operation exceptions. RPU REG APB error. */ +#define XIL_EVENT_ERROR_MASK_RPU_ECC (0x00000200U) + +/** Error event mask for RPU Lockstep Errors from R5_0. + * The Lockstep error is not initialized until RPU clock is enabled. + * Therefore the error outcomes are masked by default and are expected to be + * unmasked after processor clock is enabled and before its reset is released. */ +#define XIL_EVENT_ERROR_MASK_RPU_LS (0x00000400U) + +/** Error event mask for RPU Common Cause Failures ORed together. + * The CCF Error register with the masking capability has to reside in the RPU. */ +#define XIL_EVENT_ERROR_MASK_RPU_CCF (0x00000800U) + +/** Error event mask for APU GIC AXI Error by the AXI4 master port, + * such as SLVERR or DECERR. */ +#define XIL_EVENT_ERROR_MASK_GIC_AXI (0x00001000U) + +/** Error event mask for APU GIC ECC Error, + * a Non-Correctable ECC error occurred in any ECC-protected RAM. */ +#define XIL_EVENT_ERROR_MASK_GIC_ECC (0x00002000U) + +/** Error event mask for APLL Lock Errors. + * The error can be unmasked after the PLL is locked to alert when the + * PLL loses lock. */ +#define XIL_EVENT_ERROR_MASK_APLL_LOCK (0x00004000U) + +/** Error event mask for RPLL Lock Errors. + * The error can be unmasked after the PLL is locked to alert when the + * PLL loses lock. */ +#define XIL_EVENT_ERROR_MASK_RPLL_LOCK (0x00008000U) + +/** Error event mask for CPM Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_CPM_CR (0x00010000U) + +/** Error event mask for CPM Non-Correctable Error. */ +#define XIL_EVENT_ERROR_MASK_CPM_NCR (0x00020000U) + +/** Error event mask for LPD APB Errors from: IPI REG, USB2 REG, CRL REG, + * LPD AFIFM4 REG, LPD IOU REG, LPD IOU SECURE SLCR REG, LPD SLCR REG, + * LPD SLCR SECURE REG. */ +#define XIL_EVENT_ERROR_MASK_LPD_APB (0x00040000U) + +/** Error event mask for FPD APB Errors from: FPD AFIFM0 REG, FPD AFIFM2 REG, + * FPD SLCR REG,FPD SLCR SECURE REG, CRF REG. */ +#define XIL_EVENT_ERROR_MASK_FPD_APB (0x00080000U) + +/** Error event mask for Data parity errors from the interfaces connected + * to the LPD interconnect. */ +#define XIL_EVENT_ERROR_MASK_LPD_PAR (0x00100000U) + +/** Error event mask for Data parity errors from the interfaces connected + * to the FPD interconnect. */ +#define XIL_EVENT_ERROR_MASK_FPD_PAR (0x00200000U) + +/** Error event mask for LPD IO Peripheral Unit Parity Error. */ +#define XIL_EVENT_ERROR_MASK_IOU_PAR (0x00400000U) + +/** Error event mask for Data parity errors from the interfaces connected + * to the PSM interconnect. */ +#define XIL_EVENT_ERROR_MASK_PSM_PAR (0x00800000U) + +/** Error event mask for LPD Interconnect Timeout errors. + * Collected from: Timeout errors at the slaves connected to the LPD + * interconnect, Address decode error, Interconnect mission errors for + * the slaves connected to the LPD interconnect. */ +#define XIL_EVENT_ERROR_MASK_LPD_TO (0x01000000U) + +/** Error event mask for FPD Interconnect Timeout errors. + * Collected from: Coresight debug trace alarms, Timeout errors at the + * slaves connected to the FPD interconnect, Address decode error, + * Data parity errors on the interfaces connected to the FPD interconnect. */ +#define XIL_EVENT_ERROR_MASK_FPD_TO (0x02000000U) + +/** Error event mask for PSM Interconnect Timeout Errors. + * Collected from: Interconnect mission errors for PSM_LOCAL slave or + * PSM_GLOBAL slave or MDM slave or LPD interconnect or PSM master, + * Interconnect latent errors for PSM_LOCAL slave or PSM_GLOBAL slave or + * MDM slave or LPD interconnect or PSM master, Timeout errors at the slaves + * connected to the PSM interconnect. */ +#define XIL_EVENT_ERROR_MASK_PSM_TO (0x04000000U) + +/** Error event mask for XRAM Correctable error. + * Only applicable in devices that have XRAM. */ +#define XIL_EVENT_ERROR_MASK_XRAM_CR (0x08000000U) + +/** Error event mask for XRAM Non-Correctable error. + * Only applicable in devices that have XRAM. */ +#define XIL_EVENT_ERROR_MASK_XRAM_NCR (0x10000000U) +/** + * @} + */ + +/** + * @defgroup psmerr2 Error Event Mask for PSM ERR2 + * @ingroup xilerroreventmask + * @brief Error Events belong to PSM ERR2 Node + * @{ + */ +/** Error event mask for Error from Watchdog Timer in the LPD Subsystem. */ +#define XIL_EVENT_ERROR_MASK_LPD_SWDT (0x00000001U) + +/** Error event mask for Error from Watchdog Timer in the FPD Subsystem. */ +#define XIL_EVENT_ERROR_MASK_FPD_SWDT (0x00000002U) + +/** Error event mask for LPD XMPU Errors: Register access error on APB, + * Read permission violation, Write permission violation, Security violation. */ +#define XIL_EVENT_ERROR_MASK_LPD_XMPU (0x00040000U) + +/** Error event mask for LPD XPPU Errors: Register access error on APB, + * Master ID not found, Read permission violation, Master ID parity error, + * Master ID access violation, TrustZone violation, Aperture parity error. */ +#define XIL_EVENT_ERROR_MASK_LPD_XPPU (0x00080000U) + +/** Error event mask for FPD XMPU Errors: Register access error on APB, + * Read permission violation, Write permission violation, Security violation. */ +#define XIL_EVENT_ERROR_MASK_FPD_XMPU (0x00100000U) +/** + * @} + */ + +/** + * @defgroup swerr Error Event Mask for Software error events + * @ingroup xilerroreventmask + * @{ + * @brief Error Events belong to SW ERR Node + */ +/** Error event mask for Software error events */ +/** Health Boot Monitoring errors */ +#define XIL_EVENT_ERROR_MASK_HB_MON_0 (0x00000001U) +#define XIL_EVENT_ERROR_MASK_HB_MON_1 (0x00000002U) +#define XIL_EVENT_ERROR_MASK_HB_MON_2 (0x00000004U) +#define XIL_EVENT_ERROR_MASK_HB_MON_3 (0x00000008U) +#define XIL_EVENT_ERROR_MASK_PLM_EXCEPTION (0x00000010U) +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* XIL_ERROR_NODE_H */ diff --git a/arm/hal/lib/common/versal/xil_hw.h b/arm/hal/lib/common/versal/xil_hw.h new file mode 100644 index 0000000..4cc3c28 --- /dev/null +++ b/arm/hal/lib/common/versal/xil_hw.h @@ -0,0 +1,89 @@ +/****************************************************************************** +* Copyright (c) 2021 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +/*****************************************************************************/ +/** +* +* @file xil_hw.h +* +* This is the header file which contains definitions for the hardware +* registers. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date        Changes
+* ----- ---- -------- -------------------------------------------------------
+* 7.7   bsv   02/21/2017 Initial release
+* 7.8   skd   03/09/2022 Compilation warning fix
+*
+* 
+* +* @note +* +******************************************************************************/ + +#ifndef XIL_HW_H +#define XIL_HW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +/**@cond xil_internal + * @{ + */ + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ +/* + * PMC_GLOBAL Base Address + */ +#define PMC_GLOBAL_BASEADDR (0XF1110000U) + +/* + * Register: PMC_GLOBAL_DOMAIN_ISO_CNTRL + */ +#define PMC_GLOBAL_DOMAIN_ISO_CNTRL_PMC_PL_CFRAME_MASK (0X00000400U) +#define PMC_GLOBAL_DOMAIN_ISO_CNTRL_PMC_PL_TEST_MASK (0X00000800U) +/* + * Definitions required from pmc_tap.h + */ +#define PMC_TAP_BASEADDR (0XF11A0000U) +#define PMC_TAP_IDCODE (PMC_TAP_BASEADDR + 0X00000000U) +#define PMC_TAP_VERSION (PMC_TAP_BASEADDR + 0X00000004U) +#define PMC_TAP_VERSION_PMC_VERSION_MASK (0X000000FFU) +/* + * Definitions required from crp.h + */ +#define CRP_BASEADDR (0XF1260000U) +#define CRP_RESET_REASON (CRP_BASEADDR + 0X00000220U) +#define CRP_RST_NONPS (CRP_BASEADDR + 0X00000320U) +#define CRP_RST_NONPS_NPI_RESET_MASK (0X10U) +/* + * Register: CRP_RST_PS + */ +#define CRP_RST_PS (CRP_BASEADDR + 0x0000031CU) +/* + * Register: PMC_IOU_SLCR + */ +#define PMC_IOU_SLCR_BASEADDR (0XF1060000U) + +/** + * @} + * @endcond + */ + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_HW_H */ diff --git a/arm/hal/lib/common/xbasic_types.h b/arm/hal/lib/common/xbasic_types.h new file mode 100644 index 0000000..99b1375 --- /dev/null +++ b/arm/hal/lib/common/xbasic_types.h @@ -0,0 +1,113 @@ +/****************************************************************************** +* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xbasic_types.h +* +* +* @note Dummy File for backwards compatibility +* + +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a adk   1/31/14  Added in bsp common folder for backward compatibility
+* 7.0   aru   01/21/19 Modified the typedef of u32,u16,u8
+* 7.0 	aru   02/06/19 Included stdint.h and stddef.h
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XBASIC_TYPES_H /* prevent circular inclusions */ +#define XBASIC_TYPES_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** @name Legacy types + * Deprecated legacy types. + * @{ + */ +typedef uint8_t Xuint8; /**< unsigned 8-bit */ +typedef char Xint8; /**< signed 8-bit */ +typedef uint16_t Xuint16; /**< unsigned 16-bit */ +typedef short Xint16; /**< signed 16-bit */ +typedef uint32_t Xuint32; /**< unsigned 32-bit */ +typedef long Xint32; /**< signed 32-bit */ +typedef float Xfloat32; /**< 32-bit floating point */ +typedef double Xfloat64; /**< 64-bit double precision FP */ +typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */ + +#if !defined __XUINT64__ +typedef struct +{ + Xuint32 Upper; + Xuint32 Lower; +} Xuint64; +#endif + +/** @name New types + * New simple types. + * @{ + */ +#ifndef __KERNEL__ +#ifndef XIL_TYPES_H +typedef Xuint32 u32; +typedef Xuint16 u16; +typedef Xuint8 u8; +#endif +#else +#include +#endif + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +/* + * Xilinx NULL, TRUE and FALSE legacy support. Deprecated. + * Please use NULL, TRUE and FALSE + */ +#define XNULL NULL +#define XTRUE TRUE +#define XFALSE FALSE + +/* + * This file is deprecated and users + * should use xil_types.h and xil_assert.h\n\r + */ +#warning The xbasics_type.h file is deprecated and users should use xil_types.h and xil_assert. +#warning Please refer the Standalone BSP UG647 for further details + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + +/** + *@endcond + */ diff --git a/arm/hal/lib/common/xdebug.h b/arm/hal/lib/common/xdebug.h new file mode 100644 index 0000000..29be8d2 --- /dev/null +++ b/arm/hal/lib/common/xdebug.h @@ -0,0 +1,73 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +#ifndef XDEBUG +#define XDEBUG + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(DEBUG) && !defined(NDEBUG) + +#ifndef XDEBUG_WARNING +#define XDEBUG_WARNING +#warning DEBUG is enabled +#endif + +int printf(const char *format, ...); + +#define XDBG_DEBUG_ERROR 0x00000001U /* error condition messages */ +#define XDBG_DEBUG_GENERAL 0x00000002U /* general debug messages */ +#define XDBG_DEBUG_ALL 0xFFFFFFFFU /* all debugging data */ + +#define XDBG_DEBUG_FIFO_REG 0x00000100U /* display register reads/writes */ +#define XDBG_DEBUG_FIFO_RX 0x00000101U /* receive debug messages */ +#define XDBG_DEBUG_FIFO_TX 0x00000102U /* transmit debug messages */ +#define XDBG_DEBUG_FIFO_ALL 0x0000010FU /* all fifo debug messages */ + +#define XDBG_DEBUG_TEMAC_REG 0x00000400U /* display register reads/writes */ +#define XDBG_DEBUG_TEMAC_RX 0x00000401U /* receive debug messages */ +#define XDBG_DEBUG_TEMAC_TX 0x00000402U /* transmit debug messages */ +#define XDBG_DEBUG_TEMAC_ALL 0x0000040FU /* all temac debug messages */ + +#define XDBG_DEBUG_TEMAC_ADPT_RX 0x00000800U /* receive debug messages */ +#define XDBG_DEBUG_TEMAC_ADPT_TX 0x00000801U /* transmit debug messages */ +#define XDBG_DEBUG_TEMAC_ADPT_IOCTL 0x00000802U /* ioctl debug messages */ +#define XDBG_DEBUG_TEMAC_ADPT_MISC 0x00000803U /* debug msg for other routines */ +#define XDBG_DEBUG_TEMAC_ADPT_ALL 0x0000080FU /* all temac adapter debug messages */ + + +#define xdbg_current_types (XDBG_DEBUG_GENERAL | XDBG_DEBUG_ERROR | XDBG_DEBUG_TEMAC_REG | XDBG_DEBUG_FIFO_RX | XDBG_DEBUG_FIFO_TX | XDBG_DEBUG_FIFO_REG) + +#define xdbg_stmnt(x) x + +/* In VxWorks, if _WRS_GNU_VAR_MACROS is defined, special syntax is needed for + * macros that accept variable number of arguments + */ +#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS) +#define xdbg_printf(type, args...) (((type) & xdbg_current_types) ? printf (## args) : 0) +#else /* ANSI Syntax */ +#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0) +#endif + +#else /* defined(DEBUG) && !defined(NDEBUG) */ + +#define xdbg_stmnt(x) + +/* See VxWorks comments above */ +#if defined(XENV_VXWORKS) && defined(_WRS_GNU_VAR_MACROS) +#define xdbg_printf(type, args...) +#else /* ANSI Syntax */ +#define xdbg_printf(...) +#endif +#endif /* defined(DEBUG) && !defined(NDEBUG) */ + +#ifdef __cplusplus +} +#endif + +#endif /* XDEBUG */ diff --git a/arm/hal/lib/common/xenv.h b/arm/hal/lib/common/xenv.h new file mode 100644 index 0000000..d8aef59 --- /dev/null +++ b/arm/hal/lib/common/xenv.h @@ -0,0 +1,169 @@ +/****************************************************************************** +* Copyright (c) 2002 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xenv.h +* +* Defines common services that are typically found in a host operating. +* environment. This include file simply includes an OS specific file based +* on the compile-time constant BUILD_ENV_*, where * is the name of the target +* environment. +* +* All services are defined as macros. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b ch   10/24/02 Added XENV_LINUX
+* 1.00a rmm  04/17/02 First release
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XENV_H /* prevent circular inclusions */ +#define XENV_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Select which target environment we are operating under + */ + +/* VxWorks target environment */ +#if defined XENV_VXWORKS +#include "xenv_vxworks.h" + +/* Linux target environment */ +#elif defined XENV_LINUX +#include "xenv_linux.h" + +/* Unit test environment */ +#elif defined XENV_UNITTEST +#include "ut_xenv.h" + +/* Integration test environment */ +#elif defined XENV_INTTEST +#include "int_xenv.h" + +/* Standalone environment selected */ +#else +#include "xenv_standalone.h" +#endif + + +/* + * The following comments specify the types and macro wrappers that are + * expected to be defined by the target specific header files + */ + +/**************************** Type Definitions *******************************/ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP + * + * A structure that contains a time stamp used by other time stamp macros + * defined below. This structure is processor dependent. + */ + + +/***************** Macros (Inline Functions) Definitions *********************/ + +/*****************************************************************************/ +/** + * + * XENV_MEM_COPY(void *DestPtr, void *SrcPtr, unsigned Bytes) + * + * Copies a non-overlapping block of memory. + * + * @param DestPtr is the destination address to copy data to. + * @param SrcPtr is the source address to copy data from. + * @param Bytes is the number of bytes to copy. + * + * @return None + */ + +/*****************************************************************************/ +/** + * + * XENV_MEM_FILL(void *DestPtr, char Data, unsigned Bytes) + * + * Fills an area of memory with constant data. + * + * @param DestPtr is the destination address to set. + * @param Data contains the value to set. + * @param Bytes is the number of bytes to set. + * + * @return None + */ +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) + * + * Samples the processor's or external timer's time base counter. + * + * @param StampPtr is the storage for the retrieved time stamp. + * + * @return None + */ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_DELTA_US(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) + * + * Computes the delta between the two time stamps. + * + * @param Stamp1Ptr - First sampled time stamp. + * @param Stamp1Ptr - Sedond sampled time stamp. + * + * @return An unsigned int value with units of microseconds. + */ + +/*****************************************************************************/ +/** + * + * XENV_TIME_STAMP_DELTA_MS(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr) + * + * Computes the delta between the two time stamps. + * + * @param Stamp1Ptr - First sampled time stamp. + * @param Stamp1Ptr - Sedond sampled time stamp. + * + * @return An unsigned int value with units of milliseconds. + */ + +/*****************************************************************************//** + * + * XENV_USLEEP(unsigned delay) + * + * Delay the specified number of microseconds. + * + * @param delay is the number of microseconds to delay. + * + * @return None + */ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + +/** + *@endcond + */ diff --git a/arm/hal/lib/common/xenv_standalone.h b/arm/hal/lib/common/xenv_standalone.h new file mode 100644 index 0000000..9794da0 --- /dev/null +++ b/arm/hal/lib/common/xenv_standalone.h @@ -0,0 +1,350 @@ +/****************************************************************************** +* Copyright (c) 2002 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xenv_standalone.h +* +* Defines common services specified by xenv.h. +* +* @note +* This file is not intended to be included directly by driver code. +* Instead, the generic xenv.h file is intended to be included by driver +* code. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a wgr  02/28/07 Added cache handling macros.
+* 1.00a wgr  02/27/07 Simplified code. Deprecated old-style macro names.
+* 1.00a rmm  01/24/06 Implemented XENV_USLEEP. Assume implementation is being
+*                     used under Xilinx standalone BSP.
+* 1.00a xd   11/03/04 Improved support for doxygen.
+* 1.00a rmm  03/21/02 First release
+* 1.00a wgr  03/22/07 Converted to new coding style.
+* 1.00a rpm  06/29/07 Added udelay macro for standalone
+* 1.00a xd   07/19/07 Included xparameters.h as XPAR_ constants are referred
+*                     to in MICROBLAZE section
+* 1.00a ecm  09/19/08 updated for v7.20 of Microblaze, new functionality
+*
+* 
+* +* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XENV_STANDALONE_H +#define XENV_STANDALONE_H + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +/****************************************************************************** + * + * Get the processor dependent includes + * + ******************************************************************************/ + +#include + +#if defined __MICROBLAZE__ +# include "mb_interface.h" +# include "xparameters.h" /* XPAR constants used below in MB section */ + +#elif defined __PPC__ +# include "sleep.h" +# include "xcache_l.h" /* also include xcache_l.h for caching macros */ +#endif + +/****************************************************************************** + * + * MEMCPY / MEMSET related macros. + * + * The following are straight forward implementations of memset and memcpy. + * + * NOTE: memcpy may not work if source and target memory area are overlapping. + * + ******************************************************************************/ +/*****************************************************************************/ +/** + * + * Copies a non-overlapping block of memory. + * + * @param DestPtr + * Destination address to copy data to. + * + * @param SrcPtr + * Source address to copy data from. + * + * @param Bytes + * Number of bytes to copy. + * + * @return None. + * + * @note + * The use of XENV_MEM_COPY is deprecated. Use memcpy() instead. + * + * @note + * This implementation MAY BREAK work if source and target memory + * area are overlapping. + * + *****************************************************************************/ + +#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \ + memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes) + + + +/*****************************************************************************/ +/** + * + * Fills an area of memory with constant data. + * + * @param DestPtr + * Destination address to copy data to. + * + * @param Data + * Value to set. + * + * @param Bytes + * Number of bytes to copy. + * + * @return None. + * + * @note + * The use of XENV_MEM_FILL is deprecated. Use memset() instead. + * + *****************************************************************************/ + +#define XENV_MEM_FILL(DestPtr, Data, Bytes) \ + memset((void *) DestPtr, (s32) Data, (size_t) Bytes) + + + +/****************************************************************************** + * + * TIME related macros + * + ******************************************************************************/ + +/** + * A structure that contains a time stamp used by other time stamp macros + * defined below. This structure is processor dependent. + */ +typedef s32 XENV_TIME_STAMP; + +/*****************************************************************************/ +/** + * + * Time is derived from the 64 bit PPC timebase register + * + * @param StampPtr is the storage for the retrieved time stamp. + * + * @return None. + * + * @note + * + * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr) + *

+ * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_GET(StampPtr) + +/*****************************************************************************/ +/** + * + * This macro is not yet implemented and always returns 0. + * + * @param Stamp1Ptr is the first sampled time stamp. + * @param Stamp2Ptr is the second sampled time stamp. + * + * @return 0 + * + * @note + * + * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0) + +/*****************************************************************************/ +/** + * + * This macro is not yet implemented and always returns 0. + * + * @param Stamp1Ptr is the first sampled time stamp. + * @param Stamp2Ptr is the second sampled time stamp. + * + * @return 0 + * + * @note + * + * This macro must be implemented by the user. + * + *****************************************************************************/ +#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0) + +/*****************************************************************************/ +/** + * XENV_USLEEP(unsigned delay) + * + * Delay the specified number of microseconds. Not implemented without OS + * support. + * + * @param delay + * Number of microseconds to delay. + * + * @return None. + * + *****************************************************************************/ + +#ifdef __PPC__ +#define XENV_USLEEP(delay) usleep(delay) +#define udelay(delay) usleep(delay) +#else +#define XENV_USLEEP(delay) +#define udelay(delay) +#endif + + +/****************************************************************************** + * + * CACHE handling macros / mappings + * + ******************************************************************************/ +/****************************************************************************** + * + * Processor independent macros + * + ******************************************************************************/ + +#define XCACHE_ENABLE_CACHE() \ + { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); } + +#define XCACHE_DISABLE_CACHE() \ + { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); } + + +/****************************************************************************** + * + * MicroBlaze case + * + * NOTE: Currently the following macros will only work on systems that contain + * only ONE MicroBlaze processor. Also, the macros will only be enabled if the + * system is built using a xparameters.h file. + * + ******************************************************************************/ + +#if defined __MICROBLAZE__ + +/* Check if MicroBlaze data cache was built into the core. + */ +#if (XPAR_MICROBLAZE_USE_DCACHE == 1) +# define XCACHE_ENABLE_DCACHE() microblaze_enable_dcache() +# define XCACHE_DISABLE_DCACHE() microblaze_disable_dcache() +# define XCACHE_INVALIDATE_DCACHE() microblaze_invalidate_dcache() + +# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ + microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len)) + +#if (XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK == 1) +# define XCACHE_FLUSH_DCACHE() microblaze_flush_dcache() +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + microblaze_flush_dcache_range((s32)(Addr), (s32)(Len)) +#else +# define XCACHE_FLUSH_DCACHE() microblaze_invalidate_dcache() +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len)) +#endif /*XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK*/ + +#else +# define XCACHE_ENABLE_DCACHE() +# define XCACHE_DISABLE_DCACHE() +# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) +# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) +#endif /*XPAR_MICROBLAZE_USE_DCACHE*/ + + +/* Check if MicroBlaze instruction cache was built into the core. + */ +#if (XPAR_MICROBLAZE_USE_ICACHE == 1) +# define XCACHE_ENABLE_ICACHE() microblaze_enable_icache() +# define XCACHE_DISABLE_ICACHE() microblaze_disable_icache() + +# define XCACHE_INVALIDATE_ICACHE() microblaze_invalidate_icache() + +# define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \ + microblaze_invalidate_icache_range((s32)(Addr), (s32)(Len)) + +#else +# define XCACHE_ENABLE_ICACHE() +# define XCACHE_DISABLE_ICACHE() +#endif /*XPAR_MICROBLAZE_USE_ICACHE*/ + + +/****************************************************************************** + * + * PowerPC case + * + * Note that the XCACHE_ENABLE_xxx functions are hardcoded to enable a + * specific memory region (0x80000001). Each bit (0-30) in the regions + * bitmask stands for 128MB of memory. Bit 31 stands for the upper 2GB + * range. + * + * regions --> cached address range + * ------------|-------------------------------------------------- + * 0x80000000 | [0, 0x7FFFFFF] + * 0x00000001 | [0xF8000000, 0xFFFFFFFF] + * 0x80000001 | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF] + * + ******************************************************************************/ + +#elif defined __PPC__ + +#define XCACHE_ENABLE_DCACHE() XCache_EnableDCache(0x80000001) +#define XCACHE_DISABLE_DCACHE() XCache_DisableDCache() +#define XCACHE_ENABLE_ICACHE() XCache_EnableICache(0x80000001) +#define XCACHE_DISABLE_ICACHE() XCache_DisableICache() + +#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \ + XCache_InvalidateDCacheRange((u32)(Addr), (u32)(Len)) + +#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \ + XCache_FlushDCacheRange((u32)(Addr), (u32)(Len)) + +#define XCACHE_INVALIDATE_ICACHE() XCache_InvalidateICache() + + +/****************************************************************************** + * + * Unknown processor / architecture + * + ******************************************************************************/ + +#else +/* #error "Unknown processor / architecture. Must be MicroBlaze or PowerPC." */ +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef XENV_STANDALONE_H */ + + /** + *@endcond + */ diff --git a/arm/hal/lib/common/xil_assert.c b/arm/hal/lib/common/xil_assert.c new file mode 100644 index 0000000..b3dd7e9 --- /dev/null +++ b/arm/hal/lib/common/xil_assert.c @@ -0,0 +1,126 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_assert.c +* @addtogroup common_assert_apis Assert APIs and Macros +* @{ +* +* This file contains basic assert related functions for Xilinx software IP. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 Initial release
+* 6.0   kvn  05/31/16 Make Xil_AsserWait a global variable
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + +/** + * @brief This variable allows testing to be done easier with asserts. An assert + * sets this variable such that a driver can evaluate this variable + * to determine if an assert occurred. + */ +u32 Xil_AssertStatus; + +/** + * @brief This variable allows the assert functionality to be changed for testing + * such that it does not wait infinitely. Use the debugger to disable the + * waiting during testing of asserts. + */ +s32 Xil_AssertWait = 1; + +/* The callback function to be invoked when an assert is taken */ +static Xil_AssertCallback Xil_AssertCallbackRoutine = NULL; + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* @brief Implement assert. Currently, it calls a user-defined callback +* function if one has been set. Then, it potentially enters an +* infinite loop depending on the value of the Xil_AssertWait +* variable. +* +* @param File: filename of the source +* @param Line: linenumber within File +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void Xil_Assert(const char8 *File, s32 Line) +{ + /* if the callback has been set then invoke it */ + if (Xil_AssertCallbackRoutine != 0) { + (*Xil_AssertCallbackRoutine)(File, Line); + } + + /* if specified, wait indefinitely such that the assert will show up + * in testing + */ + while (Xil_AssertWait != 0) { + } +} + +/*****************************************************************************/ +/** +* +* @brief Set up a callback function to be invoked when an assert occurs. +* If a callback is already installed, then it will be replaced. +* +* @param Routine: callback to be invoked when an assert is taken +* +* @return None. +* +* @note This function has no effect if NDEBUG is set +* +******************************************************************************/ +void Xil_AssertSetCallback(Xil_AssertCallback Routine) +{ + Xil_AssertCallbackRoutine = Routine; +} + +/*****************************************************************************/ +/** +* +* @brief Null handler function. This follows the XInterruptHandler +* signature for interrupt handlers. It can be used to assign a null +* handler (a stub) to an interrupt controller vector table. +* +* @param NullParameter: arbitrary void pointer and not used. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XNullHandler(void *NullParameter) +{ + (void) NullParameter; +} +/** +* @} End of "addtogroup common_assert_apis". +*/ diff --git a/arm/hal/lib/common/xil_assert.h b/arm/hal/lib/common/xil_assert.h new file mode 100644 index 0000000..e8b87b5 --- /dev/null +++ b/arm/hal/lib/common/xil_assert.h @@ -0,0 +1,176 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_assert.h +* +* @addtogroup common_assert_apis Assert APIs and Macros +* +* The xil_assert.h file contains assert related functions and macros. +* Assert APIs/Macros specifies that a application program satisfies certain +* conditions at particular points in its execution. These function can be +* used by application programs to ensure that, application code is satisfying +* certain conditions. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* 6.0   kvn  05/31/16 Make Xil_AsserWait a global variable
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XIL_ASSERT_H /* prevent circular inclusions */ +#define XIL_ASSERT_H /* by using protection macros */ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************** Include Files *********************************/ + + +/************************** Constant Definitions *****************************/ + +#define XIL_ASSERT_NONE 0U +#define XIL_ASSERT_OCCURRED 1U +#define XNULL NULL + +extern u32 Xil_AssertStatus; +extern s32 Xil_AssertWait; +extern void Xil_Assert(const char8 *File, s32 Line); +/** + *@endcond + */ +void XNullHandler(void *NullParameter); + +/** + * This data type defines a callback to be invoked when an + * assert occurs. The callback is invoked only when asserts are enabled + */ +typedef void (*Xil_AssertCallback) (const char8 *File, s32 Line); + +/***************** Macros (Inline Functions) Definitions *********************/ + +#ifndef NDEBUG + +/*****************************************************************************/ +/** +* @brief This assert macro is to be used for void functions. This in +* conjunction with the Xil_AssertWait boolean can be used to +* accommodate tests so that asserts which fail allow execution to +* continue. +* +* @param Expression: expression to be evaluated. If it evaluates to +* false, the assert occurs. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertVoid(Expression) \ +{ \ + if (Expression) { \ + Xil_AssertStatus = XIL_ASSERT_NONE; \ + } else { \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return; \ + } \ +} + +/*****************************************************************************/ +/** +* @brief This assert macro is to be used for functions that do return a +* value. This in conjunction with the Xil_AssertWait boolean can be +* used to accommodate tests so that asserts which fail allow execution +* to continue. +* +* @param Expression: expression to be evaluated. If it evaluates to false, +* the assert occurs. +* +* @return Returns 0 unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertNonvoid(Expression) \ +{ \ + if (Expression) { \ + Xil_AssertStatus = XIL_ASSERT_NONE; \ + } else { \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return 0; \ + } \ +} + +/*****************************************************************************/ +/** +* @brief Always assert. This assert macro is to be used for void functions. +* Use for instances where an assert should always occur. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertVoidAlways() \ +{ \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return; \ +} + +/*****************************************************************************/ +/** +* @brief Always assert. This assert macro is to be used for functions that +* do return a value. Use for instances where an assert should always +* occur. +* +* @return Returns void unless the Xil_AssertWait variable is true, in which +* case no return is made and an infinite loop is entered. +* +******************************************************************************/ +#define Xil_AssertNonvoidAlways() \ +{ \ + Xil_Assert(__FILE__, __LINE__); \ + Xil_AssertStatus = XIL_ASSERT_OCCURRED; \ + return 0; \ +} + + +#else + +#define Xil_AssertVoid(Expression) +#define Xil_AssertVoidAlways() +#define Xil_AssertNonvoid(Expression) +#define Xil_AssertNonvoidAlways() + +#endif + +/************************** Function Prototypes ******************************/ + +void Xil_AssertSetCallback(Xil_AssertCallback Routine); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_assert_apis". +*/ diff --git a/arm/hal/lib/common/xil_cache_vxworks.h b/arm/hal/lib/common/xil_cache_vxworks.h new file mode 100644 index 0000000..77e1f3d --- /dev/null +++ b/arm/hal/lib/common/xil_cache_vxworks.h @@ -0,0 +1,74 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_cache_vxworks.h +* +* Contains the cache related functions for VxWorks that is wrapped by +* xil_cache. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  12/11/09 Initial release
+*
+* 
+* +* @note +* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XIL_CACHE_VXWORKS_H +#define XIL_CACHE_VXWORKS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "vxWorks.h" +#include "vxLib.h" +#include "sysLibExtra.h" +#include "cacheLib.h" + +#if (CPU_FAMILY==PPC) + +#define Xil_DCacheEnable() cacheEnable(DATA_CACHE) + +#define Xil_DCacheDisable() cacheDisable(DATA_CACHE) + +#define Xil_DCacheInvalidateRange(Addr, Len) \ + cacheInvalidate(DATA_CACHE, (void *)(Addr), (Len)) + +#define Xil_DCacheFlushRange(Addr, Len) \ + cacheFlush(DATA_CACHE, (void *)(Addr), (Len)) + +#define Xil_ICacheEnable() cacheEnable(INSTRUCTION_CACHE) + +#define Xil_ICacheDisable() cacheDisable(INSTRUCTION_CACHE) + +#define Xil_ICacheInvalidateRange(Addr, Len) \ + cacheInvalidate(INSTRUCTION_CACHE, (void *)(Addr), (Len)) + + +#else +#error "Unknown processor / architecture. Must be PPC for VxWorks." +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/** + *@endcond + */ \ No newline at end of file diff --git a/arm/hal/lib/common/xil_hal.h b/arm/hal/lib/common/xil_hal.h new file mode 100644 index 0000000..4b289a7 --- /dev/null +++ b/arm/hal/lib/common/xil_hal.h @@ -0,0 +1,43 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2020 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_hal.h +* +* Contains all the HAL header files. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/28/09 Initial release
+*
+* 
+* +* @note +* +******************************************************************************/ + +#ifndef XIL_HAL_H +#define XIL_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xil_cache.h" +#include "xil_io.h" +#include "xil_assert.h" +#include "xil_exception.h" +#include "xil_types.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arm/hal/lib/common/xil_io.h b/arm/hal/lib/common/xil_io.h new file mode 100644 index 0000000..41c85bd --- /dev/null +++ b/arm/hal/lib/common/xil_io.h @@ -0,0 +1,412 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_io.h +* +* @addtogroup common_io_interfacing_apis Register IO interfacing APIs +* +* The xil_io.h file contains the interface for the general I/O component, which +* encapsulates the Input/Output functions for the processors that do not +* require any special I/O handling. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 5.00 	pkp  	 05/29/14 First release
+* 6.00  mus      08/19/16 Remove checking of __LITTLE_ENDIAN__ flag for
+*                         ARM processors
+* 7.20  har      01/03/20 Added Xil_SecureOut32 for avoiding blindwrite for
+*                         CR-1049218
+* 7.30  kpt      09/21/20 Moved Xil_EndianSwap16 and Xil_EndianSwap32 to
+*                         xil_io.h and made them as static inline
+*       am       10/13/20 Changed the return type of Xil_SecureOut32 function
+*                         from u32 to int
+* 7.50  dp       02/12/21 Fix compilation error in Xil_EndianSwap32() that occur
+*                         when -Werror=conversion compiler flag is enabled
+* 7.5   mus      05/17/21 Update the functions with comments. It fixes CR#1067739.
+*
+* 
+******************************************************************************/ + +#ifndef XIL_IO_H /* prevent circular inclusions */ +#define XIL_IO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +//#include "xil_printf.h" +#include "xstatus.h" + +#if defined (__MICROBLAZE__) +#include "mb_interface.h" +#else +//#include "xpseudo_asm.h" +#endif + +/************************** Function Prototypes ******************************/ +#ifdef ENABLE_SAFETY +extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal); +#endif + +/***************** Macros (Inline Functions) Definitions *********************/ +#if defined __GNUC__ +#if defined (__MICROBLAZE__) +# define INST_SYNC mbar(0) +# define DATA_SYNC mbar(1) +# else +# define SYNCHRONIZE_IO dmb() +# define INST_SYNC isb() +# define DATA_SYNC dsb() +# endif +#else +# define SYNCHRONIZE_IO +# define INST_SYNC +# define DATA_SYNC +# define INST_SYNC +# define DATA_SYNC +#endif + +#if defined (__GNUC__) || defined (__ICCARM__) || defined (__MICROBLAZE__) +#define INLINE inline +#else +#define INLINE __inline +#endif + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading +* from the specified address and returning the 8 bit Value read from +* that address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 8 bit Value read from the specified input address. + +* +******************************************************************************/ +static INLINE u8 Xil_In8(UINTPTR Addr) +{ + return *(volatile u8 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading from +* the specified address and returning the 16 bit Value read from that +* address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 16 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u16 Xil_In16(UINTPTR Addr) +{ + return *(volatile u16 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by +* reading from the specified address and returning the 32 bit Value +* read from that address. +* +* @param Addr: contains the address to perform the input operation +* +* @return The 32 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u32 Xil_In32(UINTPTR Addr) +{ + return *(volatile u32 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an input operation for a memory location by reading the +* 64 bit Value read from that address. +* +* +* @param Addr: contains the address to perform the input operation +* +* @return The 64 bit Value read from the specified input address. +* +******************************************************************************/ +static INLINE u64 Xil_In64(UINTPTR Addr) +{ + return *(volatile u64 *) Addr; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for an memory location by +* writing the 8 bit Value to the the specified address. +* +* @param Addr: contains the address to perform the output operation +* @param Value: contains the 8 bit Value to be written at the specified +* address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out8(UINTPTR Addr, u8 Value) +{ + /* write 8 bit value to specified address */ + volatile u8 *LocalAddr = (volatile u8 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 16 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains the Value to be written at the specified address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out16(UINTPTR Addr, u16 Value) +{ + /* write 16 bit value to specified address */ + volatile u16 *LocalAddr = (volatile u16 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 32 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains the 32 bit Value to be written at the specified +* address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out32(UINTPTR Addr, u32 Value) +{ + /* write 32 bit value to specified address */ +#ifndef ENABLE_SAFETY + volatile u32 *LocalAddr = (volatile u32 *)Addr; + *LocalAddr = Value; +#else + XStl_RegUpdate(Addr, Value); +#endif +} + +/*****************************************************************************/ +/** +* +* @brief Performs an output operation for a memory location by writing the +* 64 bit Value to the the specified address. +* +* @param Addr contains the address to perform the output operation +* @param Value contains 64 bit Value to be written at the specified address. +* +* @return None. +* +******************************************************************************/ +static INLINE void Xil_Out64(UINTPTR Addr, u64 Value) +{ + /* write 64 bit value to specified address */ + volatile u64 *LocalAddr = (volatile u64 *)Addr; + *LocalAddr = Value; +} + +/*****************************************************************************/ +/** + * + * @brief Performs an output operation for a memory location by writing the + * 32 bit Value to the the specified address and then reading it + * back to verify the value written in the register. + * + * @param Addr contains the address to perform the output operation + * @param Value contains 32 bit Value to be written at the specified address + * + * @return Returns Status + * - XST_SUCCESS on success + * - XST_FAILURE on failure + * + *****************************************************************************/ +static INLINE int Xil_SecureOut32(UINTPTR Addr, u32 Value) +{ + int Status = XST_FAILURE; + u32 ReadReg; + u32 ReadRegTemp; + + /* writing 32 bit value to specified address */ + Xil_Out32(Addr, Value); + + /* verify value written to specified address with multiple reads */ + ReadReg = Xil_In32(Addr); + ReadRegTemp = Xil_In32(Addr); + + if( (ReadReg == Value) && (ReadRegTemp == Value) ) { + Status = XST_SUCCESS; + } + + return Status; +} + +/*****************************************************************************/ +/** +* +* @brief Perform a 16-bit endian conversion. +* +* @param Data: 16 bit value to be converted +* +* @return 16 bit Data with converted endianness +* +******************************************************************************/ +static INLINE __attribute__((always_inline)) u16 Xil_EndianSwap16(u16 Data) +{ + return (u16) (((Data & 0xFF00U) >> 8U) | ((Data & 0x00FFU) << 8U)); +} + +/*****************************************************************************/ +/** +* +* @brief Perform a 32-bit endian conversion. +* +* @param Data: 32 bit value to be converted +* +* @return 32 bit data with converted endianness +* +******************************************************************************/ +static INLINE __attribute__((always_inline)) u32 Xil_EndianSwap32(u32 Data) +{ + u16 LoWord; + u16 HiWord; + + /* get each of the half words from the 32 bit word */ + + LoWord = (u16) (Data & 0x0000FFFFU); + HiWord = (u16) ((Data & 0xFFFF0000U) >> 16U); + + /* byte swap each of the 16 bit half words */ + + LoWord = (u16)(((LoWord & 0xFF00U) >> 8U) | ((LoWord & 0x00FFU) << 8U)); + HiWord = (u16)(((HiWord & 0xFF00U) >> 8U) | ((HiWord & 0x00FFU) << 8U)); + + /* swap the half words before returning the value */ + + return ((((u32)LoWord) << (u32)16U) | (u32)HiWord); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +# define Xil_In16LE Xil_In16 +# define Xil_In32LE Xil_In32 +# define Xil_Out16LE Xil_Out16 +# define Xil_Out32LE Xil_Out32 +# define Xil_Htons Xil_EndianSwap16 +# define Xil_Htonl Xil_EndianSwap32 +# define Xil_Ntohs Xil_EndianSwap16 +# define Xil_Ntohl Xil_EndianSwap32 +# else +# define Xil_In16BE Xil_In16 +# define Xil_In32BE Xil_In32 +# define Xil_Out16BE Xil_Out16 +# define Xil_Out32BE Xil_Out32 +# define Xil_Htons(Data) (Data) +# define Xil_Htonl(Data) (Data) +# define Xil_Ntohs(Data) (Data) +# define Xil_Ntohl(Data) (Data) +#endif +#else +# define Xil_In16LE Xil_In16 +# define Xil_In32LE Xil_In32 +# define Xil_Out16LE Xil_Out16 +# define Xil_Out32LE Xil_Out32 +# define Xil_Htons Xil_EndianSwap16 +# define Xil_Htonl Xil_EndianSwap32 +# define Xil_Ntohs Xil_EndianSwap16 +# define Xil_Ntohl Xil_EndianSwap32 +#endif + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE u16 Xil_In16BE(UINTPTR Addr) +#else +static INLINE u16 Xil_In16LE(UINTPTR Addr) +#endif +#else +static INLINE u16 Xil_In16BE(UINTPTR Addr) +#endif +{ + u16 value = Xil_In16(Addr); + return Xil_EndianSwap16(value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE u32 Xil_In32BE(UINTPTR Addr) +#else +static INLINE u32 Xil_In32LE(UINTPTR Addr) +#endif +#else +static INLINE u32 Xil_In32BE(UINTPTR Addr) +#endif +{ + u32 value = Xil_In32(Addr); + return Xil_EndianSwap32(value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) +#else +static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value) +#endif +#else +static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value) +#endif +{ + Value = Xil_EndianSwap16(Value); + Xil_Out16(Addr, Value); +} + +#if defined (__MICROBLAZE__) +#ifdef __LITTLE_ENDIAN__ +static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) +#else +static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value) +#endif +#else +static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value) +#endif +{ + Value = Xil_EndianSwap32(Value); + Xil_Out32(Addr, Value); +} + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_io_interfacing_apis". +*/ diff --git a/arm/hal/lib/common/xil_macroback.h b/arm/hal/lib/common/xil_macroback.h new file mode 100644 index 0000000..fac185e --- /dev/null +++ b/arm/hal/lib/common/xil_macroback.h @@ -0,0 +1,1112 @@ +/****************************************************************************** +* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + + +/*********************************************************************/ +/** + * @file xil_macroback.h + * + * This header file is meant to bring back the removed _m macros. + * This header file must be included last. + * The following macros are not defined here due to the driver change: + * XGpio_mSetDataDirection + * XGpio_mGetDataReg + * XGpio_mSetDataReg + * XIIC_RESET + * XIIC_CLEAR_STATS + * XSpi_mReset + * XSysAce_mSetCfgAddr + * XSysAce_mIsCfgDone + * XTft_mSetPixel + * XTft_mGetPixel + * XWdtTb_mEnableWdt + * XWdtTb_mDisbleWdt + * XWdtTb_mRestartWdt + * XWdtTb_mGetTimebaseReg + * XWdtTb_mHasReset + * + * Please refer the corresponding driver document for replacement. + * + *********************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XIL_MACROBACK_H +#define XIL_MACROBACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************/ +/** + * Macros for Driver XCan + * + *********************************************************************/ +#ifndef XCan_mReadReg +#define XCan_mReadReg XCan_ReadReg +#endif + +#ifndef XCan_mWriteReg +#define XCan_mWriteReg XCan_WriteReg +#endif + +#ifndef XCan_mIsTxDone +#define XCan_mIsTxDone XCan_IsTxDone +#endif + +#ifndef XCan_mIsTxFifoFull +#define XCan_mIsTxFifoFull XCan_IsTxFifoFull +#endif + +#ifndef XCan_mIsHighPriorityBufFull +#define XCan_mIsHighPriorityBufFull XCan_IsHighPriorityBufFull +#endif + +#ifndef XCan_mIsRxEmpty +#define XCan_mIsRxEmpty XCan_IsRxEmpty +#endif + +#ifndef XCan_mIsAcceptFilterBusy +#define XCan_mIsAcceptFilterBusy XCan_IsAcceptFilterBusy +#endif + +#ifndef XCan_mCreateIdValue +#define XCan_mCreateIdValue XCan_CreateIdValue +#endif + +#ifndef XCan_mCreateDlcValue +#define XCan_mCreateDlcValue XCan_CreateDlcValue +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDmaCentral + * + *********************************************************************/ +#ifndef XDmaCentral_mWriteReg +#define XDmaCentral_mWriteReg XDmaCentral_WriteReg +#endif + +#ifndef XDmaCentral_mReadReg +#define XDmaCentral_mReadReg XDmaCentral_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDsAdc + * + *********************************************************************/ +#ifndef XDsAdc_mWriteReg +#define XDsAdc_mWriteReg XDsAdc_WriteReg +#endif + +#ifndef XDsAdc_mReadReg +#define XDsAdc_mReadReg XDsAdc_ReadReg +#endif + +#ifndef XDsAdc_mIsEmpty +#define XDsAdc_mIsEmpty XDsAdc_IsEmpty +#endif + +#ifndef XDsAdc_mSetFstmReg +#define XDsAdc_mSetFstmReg XDsAdc_SetFstmReg +#endif + +#ifndef XDsAdc_mGetFstmReg +#define XDsAdc_mGetFstmReg XDsAdc_GetFstmReg +#endif + +#ifndef XDsAdc_mEnableConversion +#define XDsAdc_mEnableConversion XDsAdc_EnableConversion +#endif + +#ifndef XDsAdc_mDisableConversion +#define XDsAdc_mDisableConversion XDsAdc_DisableConversion +#endif + +#ifndef XDsAdc_mGetFifoOccyReg +#define XDsAdc_mGetFifoOccyReg XDsAdc_GetFifoOccyReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XDsDac + * + *********************************************************************/ +#ifndef XDsDac_mWriteReg +#define XDsDac_mWriteReg XDsDac_WriteReg +#endif + +#ifndef XDsDac_mReadReg +#define XDsDac_mReadReg XDsDac_ReadReg +#endif + +#ifndef XDsDac_mIsEmpty +#define XDsDac_mIsEmpty XDsDac_IsEmpty +#endif + +#ifndef XDsDac_mFifoIsFull +#define XDsDac_mFifoIsFull XDsDac_FifoIsFull +#endif + +#ifndef XDsDac_mGetVacancy +#define XDsDac_mGetVacancy XDsDac_GetVacancy +#endif + +/*********************************************************************/ +/** + * Macros for Driver XEmacLite + * + *********************************************************************/ +#ifndef XEmacLite_mReadReg +#define XEmacLite_mReadReg XEmacLite_ReadReg +#endif + +#ifndef XEmacLite_mWriteReg +#define XEmacLite_mWriteReg XEmacLite_WriteReg +#endif + +#ifndef XEmacLite_mGetTxStatus +#define XEmacLite_mGetTxStatus XEmacLite_GetTxStatus +#endif + +#ifndef XEmacLite_mSetTxStatus +#define XEmacLite_mSetTxStatus XEmacLite_SetTxStatus +#endif + +#ifndef XEmacLite_mGetRxStatus +#define XEmacLite_mGetRxStatus XEmacLite_GetRxStatus +#endif + +#ifndef XEmacLite_mSetRxStatus +#define XEmacLite_mSetRxStatus XEmacLite_SetRxStatus +#endif + +#ifndef XEmacLite_mIsTxDone +#define XEmacLite_mIsTxDone XEmacLite_IsTxDone +#endif + +#ifndef XEmacLite_mIsRxEmpty +#define XEmacLite_mIsRxEmpty XEmacLite_IsRxEmpty +#endif + +#ifndef XEmacLite_mNextTransmitAddr +#define XEmacLite_mNextTransmitAddr XEmacLite_NextTransmitAddr +#endif + +#ifndef XEmacLite_mNextReceiveAddr +#define XEmacLite_mNextReceiveAddr XEmacLite_NextReceiveAddr +#endif + +#ifndef XEmacLite_mIsMdioConfigured +#define XEmacLite_mIsMdioConfigured XEmacLite_IsMdioConfigured +#endif + +#ifndef XEmacLite_mIsLoopbackConfigured +#define XEmacLite_mIsLoopbackConfigured XEmacLite_IsLoopbackConfigured +#endif + +#ifndef XEmacLite_mGetReceiveDataLength +#define XEmacLite_mGetReceiveDataLength XEmacLite_GetReceiveDataLength +#endif + +#ifndef XEmacLite_mGetTxActive +#define XEmacLite_mGetTxActive XEmacLite_GetTxActive +#endif + +#ifndef XEmacLite_mSetTxActive +#define XEmacLite_mSetTxActive XEmacLite_SetTxActive +#endif + +/*********************************************************************/ +/** + * Macros for Driver XGpio + * + *********************************************************************/ +#ifndef XGpio_mWriteReg +#define XGpio_mWriteReg XGpio_WriteReg +#endif + +#ifndef XGpio_mReadReg +#define XGpio_mReadReg XGpio_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XHwIcap + * + *********************************************************************/ +#ifndef XHwIcap_mFifoWrite +#define XHwIcap_mFifoWrite XHwIcap_FifoWrite +#endif + +#ifndef XHwIcap_mFifoRead +#define XHwIcap_mFifoRead XHwIcap_FifoRead +#endif + +#ifndef XHwIcap_mSetSizeReg +#define XHwIcap_mSetSizeReg XHwIcap_SetSizeReg +#endif + +#ifndef XHwIcap_mGetControlReg +#define XHwIcap_mGetControlReg XHwIcap_GetControlReg +#endif + +#ifndef XHwIcap_mStartConfig +#define XHwIcap_mStartConfig XHwIcap_StartConfig +#endif + +#ifndef XHwIcap_mStartReadBack +#define XHwIcap_mStartReadBack XHwIcap_StartReadBack +#endif + +#ifndef XHwIcap_mGetStatusReg +#define XHwIcap_mGetStatusReg XHwIcap_GetStatusReg +#endif + +#ifndef XHwIcap_mIsTransferDone +#define XHwIcap_mIsTransferDone XHwIcap_IsTransferDone +#endif + +#ifndef XHwIcap_mIsDeviceBusy +#define XHwIcap_mIsDeviceBusy XHwIcap_IsDeviceBusy +#endif + +#ifndef XHwIcap_mIntrGlobalEnable +#define XHwIcap_mIntrGlobalEnable XHwIcap_IntrGlobalEnable +#endif + +#ifndef XHwIcap_mIntrGlobalDisable +#define XHwIcap_mIntrGlobalDisable XHwIcap_IntrGlobalDisable +#endif + +#ifndef XHwIcap_mIntrGetStatus +#define XHwIcap_mIntrGetStatus XHwIcap_IntrGetStatus +#endif + +#ifndef XHwIcap_mIntrDisable +#define XHwIcap_mIntrDisable XHwIcap_IntrDisable +#endif + +#ifndef XHwIcap_mIntrEnable +#define XHwIcap_mIntrEnable XHwIcap_IntrEnable +#endif + +#ifndef XHwIcap_mIntrGetEnabled +#define XHwIcap_mIntrGetEnabled XHwIcap_IntrGetEnabled +#endif + +#ifndef XHwIcap_mIntrClear +#define XHwIcap_mIntrClear XHwIcap_IntrClear +#endif + +#ifndef XHwIcap_mGetWrFifoVacancy +#define XHwIcap_mGetWrFifoVacancy XHwIcap_GetWrFifoVacancy +#endif + +#ifndef XHwIcap_mGetRdFifoOccupancy +#define XHwIcap_mGetRdFifoOccupancy XHwIcap_GetRdFifoOccupancy +#endif + +#ifndef XHwIcap_mSliceX2Col +#define XHwIcap_mSliceX2Col XHwIcap_SliceX2Col +#endif + +#ifndef XHwIcap_mSliceY2Row +#define XHwIcap_mSliceY2Row XHwIcap_SliceY2Row +#endif + +#ifndef XHwIcap_mSliceXY2Slice +#define XHwIcap_mSliceXY2Slice XHwIcap_SliceXY2Slice +#endif + +#ifndef XHwIcap_mReadReg +#define XHwIcap_mReadReg XHwIcap_ReadReg +#endif + +#ifndef XHwIcap_mWriteReg +#define XHwIcap_mWriteReg XHwIcap_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XIic + * + *********************************************************************/ +#ifndef XIic_mReadReg +#define XIic_mReadReg XIic_ReadReg +#endif + +#ifndef XIic_mWriteReg +#define XIic_mWriteReg XIic_WriteReg +#endif + +#ifndef XIic_mEnterCriticalRegion +#define XIic_mEnterCriticalRegion XIic_IntrGlobalDisable +#endif + +#ifndef XIic_mExitCriticalRegion +#define XIic_mExitCriticalRegion XIic_IntrGlobalEnable +#endif + +#ifndef XIIC_GINTR_DISABLE +#define XIIC_GINTR_DISABLE XIic_IntrGlobalDisable +#endif + +#ifndef XIIC_GINTR_ENABLE +#define XIIC_GINTR_ENABLE XIic_IntrGlobalEnable +#endif + +#ifndef XIIC_IS_GINTR_ENABLED +#define XIIC_IS_GINTR_ENABLED XIic_IsIntrGlobalEnabled +#endif + +#ifndef XIIC_WRITE_IISR +#define XIIC_WRITE_IISR XIic_WriteIisr +#endif + +#ifndef XIIC_READ_IISR +#define XIIC_READ_IISR XIic_ReadIisr +#endif + +#ifndef XIIC_WRITE_IIER +#define XIIC_WRITE_IIER XIic_WriteIier +#endif + +#ifndef XIic_mClearIisr +#define XIic_mClearIisr XIic_ClearIisr +#endif + +#ifndef XIic_mSend7BitAddress +#define XIic_mSend7BitAddress XIic_Send7BitAddress +#endif + +#ifndef XIic_mDynSend7BitAddress +#define XIic_mDynSend7BitAddress XIic_DynSend7BitAddress +#endif + +#ifndef XIic_mDynSendStartStopAddress +#define XIic_mDynSendStartStopAddress XIic_DynSendStartStopAddress +#endif + +#ifndef XIic_mDynSendStop +#define XIic_mDynSendStop XIic_DynSendStop +#endif + +#ifndef XIic_mSend10BitAddrByte1 +#define XIic_mSend10BitAddrByte1 XIic_Send10BitAddrByte1 +#endif + +#ifndef XIic_mSend10BitAddrByte2 +#define XIic_mSend10BitAddrByte2 XIic_Send10BitAddrByte2 +#endif + +#ifndef XIic_mSend7BitAddr +#define XIic_mSend7BitAddr XIic_Send7BitAddr +#endif + +#ifndef XIic_mDisableIntr +#define XIic_mDisableIntr XIic_DisableIntr +#endif + +#ifndef XIic_mEnableIntr +#define XIic_mEnableIntr XIic_EnableIntr +#endif + +#ifndef XIic_mClearIntr +#define XIic_mClearIntr XIic_ClearIntr +#endif + +#ifndef XIic_mClearEnableIntr +#define XIic_mClearEnableIntr XIic_ClearEnableIntr +#endif + +#ifndef XIic_mFlushRxFifo +#define XIic_mFlushRxFifo XIic_FlushRxFifo +#endif + +#ifndef XIic_mFlushTxFifo +#define XIic_mFlushTxFifo XIic_FlushTxFifo +#endif + +#ifndef XIic_mReadRecvByte +#define XIic_mReadRecvByte XIic_ReadRecvByte +#endif + +#ifndef XIic_mWriteSendByte +#define XIic_mWriteSendByte XIic_WriteSendByte +#endif + +#ifndef XIic_mSetControlRegister +#define XIic_mSetControlRegister XIic_SetControlRegister +#endif + +/*********************************************************************/ +/** + * Macros for Driver XIntc + * + *********************************************************************/ +#ifndef XIntc_mMasterEnable +#define XIntc_mMasterEnable XIntc_MasterEnable +#endif + +#ifndef XIntc_mMasterDisable +#define XIntc_mMasterDisable XIntc_MasterDisable +#endif + +#ifndef XIntc_mEnableIntr +#define XIntc_mEnableIntr XIntc_EnableIntr +#endif + +#ifndef XIntc_mDisableIntr +#define XIntc_mDisableIntr XIntc_DisableIntr +#endif + +#ifndef XIntc_mAckIntr +#define XIntc_mAckIntr XIntc_AckIntr +#endif + +#ifndef XIntc_mGetIntrStatus +#define XIntc_mGetIntrStatus XIntc_GetIntrStatus +#endif + +/*********************************************************************/ +/** + * Macros for Driver XLlDma + * + *********************************************************************/ +#ifndef XLlDma_mBdRead +#define XLlDma_mBdRead XLlDma_BdRead +#endif + +#ifndef XLlDma_mBdWrite +#define XLlDma_mBdWrite XLlDma_BdWrite +#endif + +#ifndef XLlDma_mWriteReg +#define XLlDma_mWriteReg XLlDma_WriteReg +#endif + +#ifndef XLlDma_mReadReg +#define XLlDma_mReadReg XLlDma_ReadReg +#endif + +#ifndef XLlDma_mBdClear +#define XLlDma_mBdClear XLlDma_BdClear +#endif + +#ifndef XLlDma_mBdSetStsCtrl +#define XLlDma_mBdSetStsCtrl XLlDma_BdSetStsCtrl +#endif + +#ifndef XLlDma_mBdGetStsCtrl +#define XLlDma_mBdGetStsCtrl XLlDma_BdGetStsCtrl +#endif + +#ifndef XLlDma_mBdSetLength +#define XLlDma_mBdSetLength XLlDma_BdSetLength +#endif + +#ifndef XLlDma_mBdGetLength +#define XLlDma_mBdGetLength XLlDma_BdGetLength +#endif + +#ifndef XLlDma_mBdSetId +#define XLlDma_mBdSetId XLlDma_BdSetId +#endif + +#ifndef XLlDma_mBdGetId +#define XLlDma_mBdGetId XLlDma_BdGetId +#endif + +#ifndef XLlDma_mBdSetBufAddr +#define XLlDma_mBdSetBufAddr XLlDma_BdSetBufAddr +#endif + +#ifndef XLlDma_mBdGetBufAddr +#define XLlDma_mBdGetBufAddr XLlDma_BdGetBufAddr +#endif + +#ifndef XLlDma_mBdGetLength +#define XLlDma_mBdGetLength XLlDma_BdGetLength +#endif + +#ifndef XLlDma_mGetTxRing +#define XLlDma_mGetTxRing XLlDma_GetTxRing +#endif + +#ifndef XLlDma_mGetRxRing +#define XLlDma_mGetRxRing XLlDma_GetRxRing +#endif + +#ifndef XLlDma_mGetCr +#define XLlDma_mGetCr XLlDma_GetCr +#endif + +#ifndef XLlDma_mSetCr +#define XLlDma_mSetCr XLlDma_SetCr +#endif + +#ifndef XLlDma_mBdRingCntCalc +#define XLlDma_mBdRingCntCalc XLlDma_BdRingCntCalc +#endif + +#ifndef XLlDma_mBdRingMemCalc +#define XLlDma_mBdRingMemCalc XLlDma_BdRingMemCalc +#endif + +#ifndef XLlDma_mBdRingGetCnt +#define XLlDma_mBdRingGetCnt XLlDma_BdRingGetCnt +#endif + +#ifndef XLlDma_mBdRingGetFreeCnt +#define XLlDma_mBdRingGetFreeCnt XLlDma_BdRingGetFreeCnt +#endif + +#ifndef XLlDma_mBdRingSnapShotCurrBd +#define XLlDma_mBdRingSnapShotCurrBd XLlDma_BdRingSnapShotCurrBd +#endif + +#ifndef XLlDma_mBdRingNext +#define XLlDma_mBdRingNext XLlDma_BdRingNext +#endif + +#ifndef XLlDma_mBdRingPrev +#define XLlDma_mBdRingPrev XLlDma_BdRingPrev +#endif + +#ifndef XLlDma_mBdRingGetSr +#define XLlDma_mBdRingGetSr XLlDma_BdRingGetSr +#endif + +#ifndef XLlDma_mBdRingSetSr +#define XLlDma_mBdRingSetSr XLlDma_BdRingSetSr +#endif + +#ifndef XLlDma_mBdRingGetCr +#define XLlDma_mBdRingGetCr XLlDma_BdRingGetCr +#endif + +#ifndef XLlDma_mBdRingSetCr +#define XLlDma_mBdRingSetCr XLlDma_BdRingSetCr +#endif + +#ifndef XLlDma_mBdRingBusy +#define XLlDma_mBdRingBusy XLlDma_BdRingBusy +#endif + +#ifndef XLlDma_mBdRingIntEnable +#define XLlDma_mBdRingIntEnable XLlDma_BdRingIntEnable +#endif + +#ifndef XLlDma_mBdRingIntDisable +#define XLlDma_mBdRingIntDisable XLlDma_BdRingIntDisable +#endif + +#ifndef XLlDma_mBdRingIntGetEnabled +#define XLlDma_mBdRingIntGetEnabled XLlDma_BdRingIntGetEnabled +#endif + +#ifndef XLlDma_mBdRingGetIrq +#define XLlDma_mBdRingGetIrq XLlDma_BdRingGetIrq +#endif + +#ifndef XLlDma_mBdRingAckIrq +#define XLlDma_mBdRingAckIrq XLlDma_BdRingAckIrq +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMbox + * + *********************************************************************/ +#ifndef XMbox_mWriteReg +#define XMbox_mWriteReg XMbox_WriteReg +#endif + +#ifndef XMbox_mReadReg +#define XMbox_mReadReg XMbox_ReadReg +#endif + +#ifndef XMbox_mWriteMBox +#define XMbox_mWriteMBox XMbox_WriteMBox +#endif + +#ifndef XMbox_mReadMBox +#define XMbox_mReadMBox XMbox_ReadMBox +#endif + +#ifndef XMbox_mFSLReadMBox +#define XMbox_mFSLReadMBox XMbox_FSLReadMBox +#endif + +#ifndef XMbox_mFSLWriteMBox +#define XMbox_mFSLWriteMBox XMbox_FSLWriteMBox +#endif + +#ifndef XMbox_mFSLIsEmpty +#define XMbox_mFSLIsEmpty XMbox_FSLIsEmpty +#endif + +#ifndef XMbox_mFSLIsFull +#define XMbox_mFSLIsFull XMbox_FSLIsFull +#endif + +#ifndef XMbox_mIsEmpty +#define XMbox_mIsEmpty XMbox_IsEmptyHw +#endif + +#ifndef XMbox_mIsFull +#define XMbox_mIsFull XMbox_IsFullHw +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMpmc + * + *********************************************************************/ +#ifndef XMpmc_mReadReg +#define XMpmc_mReadReg XMpmc_ReadReg +#endif + +#ifndef XMpmc_mWriteReg +#define XMpmc_mWriteReg XMpmc_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XMutex + * + *********************************************************************/ +#ifndef XMutex_mWriteReg +#define XMutex_mWriteReg XMutex_WriteReg +#endif + +#ifndef XMutex_mReadReg +#define XMutex_mReadReg XMutex_ReadReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XPcie + * + *********************************************************************/ +#ifndef XPcie_mReadReg +#define XPcie_mReadReg XPcie_ReadReg +#endif + +#ifndef XPcie_mWriteReg +#define XPcie_mWriteReg XPcie_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSpi + * + *********************************************************************/ +#ifndef XSpi_mIntrGlobalEnable +#define XSpi_mIntrGlobalEnable XSpi_IntrGlobalEnable +#endif + +#ifndef XSpi_mIntrGlobalDisable +#define XSpi_mIntrGlobalDisable XSpi_IntrGlobalDisable +#endif + +#ifndef XSpi_mIsIntrGlobalEnabled +#define XSpi_mIsIntrGlobalEnabled XSpi_IsIntrGlobalEnabled +#endif + +#ifndef XSpi_mIntrGetStatus +#define XSpi_mIntrGetStatus XSpi_IntrGetStatus +#endif + +#ifndef XSpi_mIntrClear +#define XSpi_mIntrClear XSpi_IntrClear +#endif + +#ifndef XSpi_mIntrEnable +#define XSpi_mIntrEnable XSpi_IntrEnable +#endif + +#ifndef XSpi_mIntrDisable +#define XSpi_mIntrDisable XSpi_IntrDisable +#endif + +#ifndef XSpi_mIntrGetEnabled +#define XSpi_mIntrGetEnabled XSpi_IntrGetEnabled +#endif + +#ifndef XSpi_mSetControlReg +#define XSpi_mSetControlReg XSpi_SetControlReg +#endif + +#ifndef XSpi_mGetControlReg +#define XSpi_mGetControlReg XSpi_GetControlReg +#endif + +#ifndef XSpi_mGetStatusReg +#define XSpi_mGetStatusReg XSpi_GetStatusReg +#endif + +#ifndef XSpi_mSetSlaveSelectReg +#define XSpi_mSetSlaveSelectReg XSpi_SetSlaveSelectReg +#endif + +#ifndef XSpi_mGetSlaveSelectReg +#define XSpi_mGetSlaveSelectReg XSpi_GetSlaveSelectReg +#endif + +#ifndef XSpi_mEnable +#define XSpi_mEnable XSpi_Enable +#endif + +#ifndef XSpi_mDisable +#define XSpi_mDisable XSpi_Disable +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSysAce + * + *********************************************************************/ +#ifndef XSysAce_mGetControlReg +#define XSysAce_mGetControlReg XSysAce_GetControlReg +#endif + +#ifndef XSysAce_mSetControlReg +#define XSysAce_mSetControlReg XSysAce_SetControlReg +#endif + +#ifndef XSysAce_mOrControlReg +#define XSysAce_mOrControlReg XSysAce_OrControlReg +#endif + +#ifndef XSysAce_mAndControlReg +#define XSysAce_mAndControlReg XSysAce_AndControlReg +#endif + +#ifndef XSysAce_mGetErrorReg +#define XSysAce_mGetErrorReg XSysAce_GetErrorReg +#endif + +#ifndef XSysAce_mGetStatusReg +#define XSysAce_mGetStatusReg XSysAce_GetStatusReg +#endif + +#ifndef XSysAce_mWaitForLock +#define XSysAce_mWaitForLock XSysAce_WaitForLock +#endif + +#ifndef XSysAce_mEnableIntr +#define XSysAce_mEnableIntr XSysAce_EnableIntr +#endif + +#ifndef XSysAce_mDisableIntr +#define XSysAce_mDisableIntr XSysAce_DisableIntr +#endif + +#ifndef XSysAce_mIsReadyForCmd +#define XSysAce_mIsReadyForCmd XSysAce_IsReadyForCmd +#endif + +#ifndef XSysAce_mIsMpuLocked +#define XSysAce_mIsMpuLocked XSysAce_IsMpuLocked +#endif + +#ifndef XSysAce_mIsIntrEnabled +#define XSysAce_mIsIntrEnabled XSysAce_IsIntrEnabled +#endif + +/*********************************************************************/ +/** + * Macros for Driver XSysMon + * + *********************************************************************/ +#ifndef XSysMon_mIsEventSamplingModeSet +#define XSysMon_mIsEventSamplingModeSet XSysMon_IsEventSamplingModeSet +#endif + +#ifndef XSysMon_mIsDrpBusy +#define XSysMon_mIsDrpBusy XSysMon_IsDrpBusy +#endif + +#ifndef XSysMon_mIsDrpLocked +#define XSysMon_mIsDrpLocked XSysMon_IsDrpLocked +#endif + +#ifndef XSysMon_mRawToTemperature +#define XSysMon_mRawToTemperature XSysMon_RawToTemperature +#endif + +#ifndef XSysMon_mRawToVoltage +#define XSysMon_mRawToVoltage XSysMon_RawToVoltage +#endif + +#ifndef XSysMon_mTemperatureToRaw +#define XSysMon_mTemperatureToRaw XSysMon_TemperatureToRaw +#endif + +#ifndef XSysMon_mVoltageToRaw +#define XSysMon_mVoltageToRaw XSysMon_VoltageToRaw +#endif + +#ifndef XSysMon_mReadReg +#define XSysMon_mReadReg XSysMon_ReadReg +#endif + +#ifndef XSysMon_mWriteReg +#define XSysMon_mWriteReg XSysMon_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XTmrCtr + * + *********************************************************************/ +#ifndef XTimerCtr_mReadReg +#define XTimerCtr_mReadReg XTimerCtr_ReadReg +#endif + +#ifndef XTmrCtr_mWriteReg +#define XTmrCtr_mWriteReg XTmrCtr_WriteReg +#endif + +#ifndef XTmrCtr_mSetControlStatusReg +#define XTmrCtr_mSetControlStatusReg XTmrCtr_SetControlStatusReg +#endif + +#ifndef XTmrCtr_mGetControlStatusReg +#define XTmrCtr_mGetControlStatusReg XTmrCtr_GetControlStatusReg +#endif + +#ifndef XTmrCtr_mGetTimerCounterReg +#define XTmrCtr_mGetTimerCounterReg XTmrCtr_GetTimerCounterReg +#endif + +#ifndef XTmrCtr_mSetLoadReg +#define XTmrCtr_mSetLoadReg XTmrCtr_SetLoadReg +#endif + +#ifndef XTmrCtr_mGetLoadReg +#define XTmrCtr_mGetLoadReg XTmrCtr_GetLoadReg +#endif + +#ifndef XTmrCtr_mEnable +#define XTmrCtr_mEnable XTmrCtr_Enable +#endif + +#ifndef XTmrCtr_mDisable +#define XTmrCtr_mDisable XTmrCtr_Disable +#endif + +#ifndef XTmrCtr_mEnableIntr +#define XTmrCtr_mEnableIntr XTmrCtr_EnableIntr +#endif + +#ifndef XTmrCtr_mDisableIntr +#define XTmrCtr_mDisableIntr XTmrCtr_DisableIntr +#endif + +#ifndef XTmrCtr_mLoadTimerCounterReg +#define XTmrCtr_mLoadTimerCounterReg XTmrCtr_LoadTimerCounterReg +#endif + +#ifndef XTmrCtr_mHasEventOccurred +#define XTmrCtr_mHasEventOccurred XTmrCtr_HasEventOccurred +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUartLite + * + *********************************************************************/ +#ifndef XUartLite_mUpdateStats +#define XUartLite_mUpdateStats XUartLite_UpdateStats +#endif + +#ifndef XUartLite_mWriteReg +#define XUartLite_mWriteReg XUartLite_WriteReg +#endif + +#ifndef XUartLite_mReadReg +#define XUartLite_mReadReg XUartLite_ReadReg +#endif + +#ifndef XUartLite_mClearStats +#define XUartLite_mClearStats XUartLite_ClearStats +#endif + +#ifndef XUartLite_mSetControlReg +#define XUartLite_mSetControlReg XUartLite_SetControlReg +#endif + +#ifndef XUartLite_mGetStatusReg +#define XUartLite_mGetStatusReg XUartLite_GetStatusReg +#endif + +#ifndef XUartLite_mIsReceiveEmpty +#define XUartLite_mIsReceiveEmpty XUartLite_IsReceiveEmpty +#endif + +#ifndef XUartLite_mIsTransmitFull +#define XUartLite_mIsTransmitFull XUartLite_IsTransmitFull +#endif + +#ifndef XUartLite_mIsIntrEnabled +#define XUartLite_mIsIntrEnabled XUartLite_IsIntrEnabled +#endif + +#ifndef XUartLite_mEnableIntr +#define XUartLite_mEnableIntr XUartLite_EnableIntr +#endif + +#ifndef XUartLite_mDisableIntr +#define XUartLite_mDisableIntr XUartLite_DisableIntr +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUartNs550 + * + *********************************************************************/ +#ifndef XUartNs550_mUpdateStats +#define XUartNs550_mUpdateStats XUartNs550_UpdateStats +#endif + +#ifndef XUartNs550_mReadReg +#define XUartNs550_mReadReg XUartNs550_ReadReg +#endif + +#ifndef XUartNs550_mWriteReg +#define XUartNs550_mWriteReg XUartNs550_WriteReg +#endif + +#ifndef XUartNs550_mClearStats +#define XUartNs550_mClearStats XUartNs550_ClearStats +#endif + +#ifndef XUartNs550_mGetLineStatusReg +#define XUartNs550_mGetLineStatusReg XUartNs550_GetLineStatusReg +#endif + +#ifndef XUartNs550_mGetLineControlReg +#define XUartNs550_mGetLineControlReg XUartNs550_GetLineControlReg +#endif + +#ifndef XUartNs550_mSetLineControlReg +#define XUartNs550_mSetLineControlReg XUartNs550_SetLineControlReg +#endif + +#ifndef XUartNs550_mEnableIntr +#define XUartNs550_mEnableIntr XUartNs550_EnableIntr +#endif + +#ifndef XUartNs550_mDisableIntr +#define XUartNs550_mDisableIntr XUartNs550_DisableIntr +#endif + +#ifndef XUartNs550_mIsReceiveData +#define XUartNs550_mIsReceiveData XUartNs550_IsReceiveData +#endif + +#ifndef XUartNs550_mIsTransmitEmpty +#define XUartNs550_mIsTransmitEmpty XUartNs550_IsTransmitEmpty +#endif + +/*********************************************************************/ +/** + * Macros for Driver XUsb + * + *********************************************************************/ +#ifndef XUsb_mReadReg +#define XUsb_mReadReg XUsb_ReadReg +#endif + +#ifndef XUsb_mWriteReg +#define XUsb_mWriteReg XUsb_WriteReg +#endif + +/*********************************************************************/ +/** + * Macros for Driver XPmonPsv + * + *********************************************************************/ +#ifndef XpsvPmon_CfgInitialize +#define XpsvPmon_CfgInitialize XPmonPsv_CfgInitialize +#endif + +#ifndef XpsvPmon_LookupConfig +#define XpsvPmon_LookupConfig XPmonPsv_LookupConfig +#endif + +#ifndef XpsvPmon_WriteReg +#define XpsvPmon_WriteReg XPmonPsv_WriteReg +#endif + +#ifndef XpsvPmon_SetMetrics +#define XpsvPmon_SetMetrics XPmonPsv_SetMetrics +#endif + +#ifndef XpsvPmon_GetMetrics +#define XpsvPmon_GetMetrics XPmonPsv_GetMetrics +#endif + +#ifndef XpsvPmon_ResetCounter +#define XpsvPmon_ResetCounter XPmonPsv_ResetCounter +#endif + +#ifndef XpsvPmon_GetWriteCounter +#define XpsvPmon_GetWriteCounter XPmonPsv_GetWriteCounter +#endif + +#ifndef XpsvPmon_GetReadCounter +#define XpsvPmon_GetReadCounter XPmonPsv_GetReadCounter +#endif + +#ifndef XpsvPmon_EnableCounters +#define XpsvPmon_EnableCounters XPmonPsv_EnableCounters +#endif + +#ifndef XpsvPmon_StopCounter +#define XpsvPmon_StopCounter XPmonPsv_StopCounter +#endif + +#ifndef XpsvPmon_SetPort +#define XpsvPmon_SetPort XPmonPsv_SetPort +#endif + +#ifndef XpsvPmon_SetSrc +#define XpsvPmon_SetSrc XPmonPsv_SetSrc +#endif + +#ifndef XpsvPmon_Unlock +#define XpsvPmon_Unlock XPmonPsv_Unlock +#endif + +#ifndef XpsvPmon_Lock +#define XpsvPmon_Lock XPmonPsv_Lock +#endif + + +#ifndef XpsvPmon_RequestCounter +#define XpsvPmon_RequestCounter XPmonPsv_RequestCounter +#endif + +#ifndef XPmonpsv_Config +#define XPmonpsv_Config XPmonPsv_Config +#endif + +typedef XPmonPsv XpsvPmon; +#ifdef __cplusplus +} +#endif + +#endif +/** + *@endcond + */ \ No newline at end of file diff --git a/arm/hal/lib/common/xil_mem.c b/arm/hal/lib/common/xil_mem.c new file mode 100644 index 0000000..44e7d9a --- /dev/null +++ b/arm/hal/lib/common/xil_mem.c @@ -0,0 +1,70 @@ +/******************************************************************************/ +/** +* Copyright (c) 2015 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* @file xil_mem.c +* +* This file contains xil mem copy function to use in case of word aligned +* data copies. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.1   nsk      11/07/16 First release.
+* 7.7	sk	 01/10/22 Update Xil_MemCpy functions variables typecast
+* 			  from int to s32 to fix misra_c_2012_directive_4_6
+* 			  violations.
+* 7.7	sk	 01/10/22 Include xil_mem.h header file to fix Xil_MemCpy
+* 			  prototype misra_c_2012_rule_8_4 violation.
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_mem.h" + +/***************** Inline Functions Definitions ********************/ +/*****************************************************************************/ +/** +* @brief This function copies memory from once location to other. +* +* @param dst: pointer pointing to destination memory +* +* @param src: pointer pointing to source memory +* +* @param cnt: 32 bit length of bytes to be copied +* +*****************************************************************************/ +void Xil_MemCpy(void* dst, const void* src, u32 cnt) +{ + char *d = (char*)(void *)dst; + const char *s = src; + + while (cnt >= sizeof (s32)) { + *(s32*)d = *(s32*)s; + d += sizeof (s32); + s += sizeof (s32); + cnt -= sizeof (s32); + } + while (cnt >= sizeof (u16)) { + *(u16*)d = *(u16*)s; + d += sizeof (u16); + s += sizeof (u16); + cnt -= sizeof (u16); + } + while ((cnt) > 0U){ + *d = *s; + d += 1U; + s += 1U; + cnt -= 1U; + } +} diff --git a/arm/hal/lib/common/xil_mem.h b/arm/hal/lib/common/xil_mem.h new file mode 100644 index 0000000..d6bc637 --- /dev/null +++ b/arm/hal/lib/common/xil_mem.h @@ -0,0 +1,47 @@ +/******************************************************************************/ +/** +* Copyright (c) 2015 - 2020 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* @file xil_mem.h +* +* @addtogroup common_mem_operation_api Customized APIs for Memory Operations +* +* The xil_mem.h file contains prototype for functions related +* to memory operations. These APIs are applicable for all processors supported +* by Xilinx. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.1   nsk      11/07/16 First release.
+* 7.0   mus      01/07/19 Add cpp extern macro
+*
+* 
+* +*****************************************************************************/ +#ifndef XIL_MEM_H /* prevent circular inclusions */ +#define XIL_MEM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************** Function Prototypes *****************************/ + +void Xil_MemCpy(void* dst, const void* src, u32 cnt); + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_MEM_H */ +/** +* @} End of "addtogroup common_mem_operation_api". +*/ \ No newline at end of file diff --git a/arm/hal/lib/common/xil_printf.c b/arm/hal/lib/common/xil_printf.c new file mode 100644 index 0000000..bf104fd --- /dev/null +++ b/arm/hal/lib/common/xil_printf.c @@ -0,0 +1,447 @@ +/****************************************************************************** +* Copyright (c) 1995 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +*******************************************************************************/ +/*---------------------------------------------------*/ +/* Modified from : */ +/* Public Domain version of printf */ +/* Rud Merriam, Compsult, Inc. Houston, Tx. */ +/* For Embedded Systems Programming, 1991 */ +/* */ +/*---------------------------------------------------*/ +#include "xil_printf.h" +#include "xil_types.h" +#include "xil_assert.h" +#include +#include +#include + +static void padding( const s32 l_flag,const struct params_s *par); +static void outs(const charptr lp, struct params_s *par); +static s32 getnum( charptr* linep); + +typedef struct params_s { + s32 len; + s32 num1; + s32 num2; + char8 pad_character; + s32 do_padding; + s32 left_flag; + s32 unsigned_flag; +} params_t; + + +/*---------------------------------------------------*/ +/* The purpose of this routine is to output data the */ +/* same as the standard printf function without the */ +/* overhead most run-time libraries involve. Usually */ +/* the printf brings in many kilobytes of code and */ +/* that is unacceptable in most embedded systems. */ +/*---------------------------------------------------*/ + + +/*---------------------------------------------------*/ +/* */ +/* This routine puts pad characters into the output */ +/* buffer. */ +/* */ +static void padding( const s32 l_flag, const struct params_s *par) +{ + s32 i; + + if ((par->do_padding != 0) && (l_flag != 0) && (par->len < par->num1)) { + i=(par->len); + for (; i<(par->num1); i++) { +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( par->pad_character); +#endif + } + } +} + +/*---------------------------------------------------*/ +/* */ +/* This routine moves a string to the output buffer */ +/* as directed by the padding and positioning flags. */ +/* */ +static void outs(const charptr lp, struct params_s *par) +{ + charptr LocalPtr; + LocalPtr = lp; + /* pad on left if needed */ + if(LocalPtr != NULL) { + par->len = (s32)strlen( LocalPtr); + padding( !(par->left_flag), par); + /* Move string to the buffer */ + while (((*LocalPtr) != (char8)0) && ((par->num2) != 0)) { + (par->num2)--; +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte(*LocalPtr); +#endif + LocalPtr += 1; + } +} + + /* Pad on right if needed */ + /* CR 439175 - elided next stmt. Seemed bogus. */ + padding( par->left_flag, par); +} + +/*---------------------------------------------------*/ +/* */ +/* This routine moves a number to the output buffer */ +/* as directed by the padding and positioning flags. */ +/* */ + +static void outnum( const s32 n, const s32 base, struct params_s *par) +{ + s32 negative; + s32 i; + char8 outbuf[32]; + const char8 digits[] = "0123456789ABCDEF"; + u32 num; + for(i = 0; i<32; i++) { + outbuf[i] = '0'; + } + + /* Check if number is negative */ + if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) { + negative = 1; + num =(-(n)); + } + else{ + num = n; + negative = 0; + } + + /* Build number (backwards) in outbuf */ + i = 0; + do { + outbuf[i] = digits[(num % (u32)base)]; + i++; + num /= base; + } while (num > 0U); + + if (negative != 0) { + outbuf[i] = '-'; + i++; + } + + outbuf[i] = '\0'; + i--; + + /* Move the converted number to the buffer and */ + /* add in the padding where needed. */ + par->len = (s32)strlen(outbuf); + padding( !(par->left_flag), par); + while (&outbuf[i] >= outbuf) { +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( outbuf[i] ); +#endif + i--; +} + padding( par->left_flag, par); +} +/*---------------------------------------------------*/ +/* */ +/* This routine moves a 64-bit number to the output */ +/* buffer as directed by the padding and positioning */ +/* flags. */ +/* */ +#if defined (__aarch64__) || defined (__arch64__) +static void outnum1( const s64 n, const s32 base, params_t *par) +{ + s32 negative; + s32 i; + char8 outbuf[64]; + const char8 digits[] = "0123456789ABCDEF"; + u64 num; + for(i = 0; i<64; i++) { + outbuf[i] = '0'; + } + + /* Check if number is negative */ + if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) { + negative = 1; + num =(-(n)); + } + else{ + num = (n); + negative = 0; + } + + /* Build number (backwards) in outbuf */ + i = 0; + do { + outbuf[i] = digits[(num % base)]; + i++; + num /= base; + } while (num > 0); + + if (negative != 0) { + outbuf[i] = '-'; + i++; + } + + outbuf[i] = '\0'; + i--; + + /* Move the converted number to the buffer and */ + /* add in the padding where needed. */ + par->len = (s32)strlen(outbuf); + padding( !(par->left_flag), par); + while (&outbuf[i] >= outbuf) { + outbyte( outbuf[i] ); + i--; +} + padding( par->left_flag, par); +} +#endif +/*---------------------------------------------------*/ +/* */ +/* This routine gets a number from the format */ +/* string. */ +/* */ +static s32 getnum(charptr* linep) +{ + s32 n = 0; + s32 ResultIsDigit = 0; + charptr cptr = *linep; + + while (cptr != NULL) { + ResultIsDigit = isdigit(((u8)*cptr)); + if (ResultIsDigit == 0) { + break; + } + n = ((n*10) + (((s32)*cptr) - (s32)'0')); + cptr += 1; + } + + *linep = ((charptr)(cptr)); + return(n); +} + +/*---------------------------------------------------*/ +/* */ +/* This routine operates just like a printf/sprintf */ +/* routine. It outputs a set of data under the */ +/* control of a formatting string. Not all of the */ +/* standard C format control are supported. The ones */ +/* provided are primarily those needed for embedded */ +/* systems work. Primarily the floating point */ +/* routines are omitted. Other formats could be */ +/* added easily by following the examples shown for */ +/* the supported formats. */ +/* */ + +/* void esp_printf( const func_ptr f_ptr, + const charptr ctrl1, ...) */ +#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE +void xil_printf( const char8 *ctrl1, ...){ + XPVXenConsole_Printf(ctrl1); +} +#else +void xil_printf( const char8 *ctrl1, ...) +{ + va_list argp; + + va_start(argp, ctrl1); + + xil_vprintf(ctrl1, argp); + + va_end(argp); +} +#endif + +/* This routine is equivalent to vprintf routine */ +void xil_vprintf(const char8 *ctrl1, va_list argp) +{ + s32 Check; +#if defined (__aarch64__) || defined (__arch64__) + s32 long_flag; +#endif + s32 dot_flag; + + params_t par; + + u8 ch; + char8 *ctrl = (char8 *)ctrl1; + + while ((ctrl != NULL) && (*ctrl != (char8)0)) { + + /* move format string chars to buffer until a */ + /* format control is found. */ + if (*ctrl != '%') { +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte(*ctrl); +#endif + ctrl += 1; + continue; + } + + /* initialize all the flags for this format. */ + dot_flag = 0; +#if defined (__aarch64__) || defined (__arch64__) + long_flag = 0; +#endif + par.unsigned_flag = 0; + par.left_flag = 0; + par.do_padding = 0; + par.pad_character = ' '; + par.num2=32767; + par.num1=0; + par.len=0; + + try_next: + if(ctrl != NULL) { + ctrl += 1; + } + if(ctrl != NULL) { + ch = (u8)*ctrl; + } else { + break; + } + + if (isdigit(ch) != 0) { + if (dot_flag != 0) { + par.num2 = getnum(&ctrl); + } + else { + if (ch == (u8)'0') { + par.pad_character = '0'; + } + if(ctrl != NULL) { + par.num1 = getnum(&ctrl); + } + par.do_padding = 1; + } + if(ctrl != NULL) { + ctrl -= 1; + } + goto try_next; + } + + switch (tolower(ch)) { + case '%': +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( '%'); +#endif + Check = 1; + break; + + case '-': + par.left_flag = 1; + Check = 0; + break; + + case '.': + dot_flag = 1; + Check = 0; + break; + + case 'l': + #if defined (__aarch64__) || defined (__arch64__) + long_flag = 1; + #endif + Check = 0; + break; + + case 'u': + par.unsigned_flag = 1; + /* fall through */ + case 'i': + case 'd': + #if defined (__aarch64__) || defined (__arch64__) + if (long_flag != 0){ + outnum1((s64)va_arg(argp, s64), 10L, &par); + } + else { + outnum( va_arg(argp, s32), 10L, &par); + } + #else + outnum( va_arg(argp, s32), 10L, &par); + #endif + Check = 1; + break; + case 'p': + #if defined (__aarch64__) || defined (__arch64__) + par.unsigned_flag = 1; + outnum1((s64)va_arg(argp, s64), 16L, &par); + Check = 1; + break; + #endif + case 'X': + case 'x': + par.unsigned_flag = 1; + #if defined (__aarch64__) || defined (__arch64__) + if (long_flag != 0) { + outnum1((s64)va_arg(argp, s64), 16L, &par); + } + else { + outnum((s32)va_arg(argp, s32), 16L, &par); + } + #else + outnum((s32)va_arg(argp, s32), 16L, &par); + #endif + Check = 1; + break; + + case 's': + outs( va_arg( argp, char *), &par); + Check = 1; + break; + + case 'c': +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( (char8)va_arg( argp, s32)); +#endif + Check = 1; + break; + + case '\\': + switch (*ctrl) { + case 'a': +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( ((char8)0x07)); +#endif + break; + case 'h': +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( ((char8)0x08)); +#endif + break; + case 'r': +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( ((char8)0x0D)); +#endif + break; + case 'n': +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( ((char8)0x0D)); + outbyte( ((char8)0x0A)); +#endif + break; + default: +#if defined(STDOUT_BASEADDRESS) || defined(VERSAL_PLM) + outbyte( *ctrl); +#endif + break; + } + ctrl += 1; + Check = 0; + break; + + default: + Check = 1; + break; + } + if(Check == 1) { + if(ctrl != NULL) { + ctrl += 1; + } + continue; + } + goto try_next; + } +} +/*---------------------------------------------------*/ diff --git a/arm/hal/lib/common/xil_printf.h b/arm/hal/lib/common/xil_printf.h new file mode 100644 index 0000000..062ad6b --- /dev/null +++ b/arm/hal/lib/common/xil_printf.h @@ -0,0 +1,53 @@ +/****************************************************************************** +* Copyright (c) 1995 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +*******************************************************************************/ + #ifndef XIL_PRINTF_H + #define XIL_PRINTF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include "xil_types.h" +#include "xparameters.h" +#include "bspconfig.h" +#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE +#include "xen_console.h" +#endif + +/*----------------------------------------------------*/ +/* Use the following parameter passing structure to */ +/* make xil_printf re-entrant. */ +/*----------------------------------------------------*/ + +struct params_s; + + +/*---------------------------------------------------*/ +/* The purpose of this routine is to output data the */ +/* same as the standard printf function without the */ +/* overhead most run-time libraries involve. Usually */ +/* the printf brings in many kilobytes of code and */ +/* that is unacceptable in most embedded systems. */ +/*---------------------------------------------------*/ + +typedef char8* charptr; +typedef s32 (*func_ptr)(int c); + +/* */ + +void xil_printf( const char8 *ctrl1, ...); +void xil_vprintf(const char8 *ctrl1, va_list argp); +void print( const char8 *ptr); +extern void outbyte (char c); +extern char inbyte(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ diff --git a/arm/hal/lib/common/xil_sleepcommon.c b/arm/hal/lib/common/xil_sleepcommon.c new file mode 100644 index 0000000..d6cc001 --- /dev/null +++ b/arm/hal/lib/common/xil_sleepcommon.c @@ -0,0 +1,85 @@ +/****************************************************************************** +* Copyright (c) 2017 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +*@file xil_sleepcommon.c +* +* This file contains the sleep API's +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.6 	srm  	 11/02/17 First release
+* 7.7	sk	 01/10/22 Typecast sleep function argument from unsigned
+* 			  int to u32 to fix misra_c_2012_directive_4_6
+* 			  violation.
+* 7.7	sk	 03/02/22 Update usleep argument type to fix misra_c_2012_
+* 			  directive_4_6 violation.
+* 
+******************************************************************************/ + + +/***************************** Include Files *********************************/ +#include "xil_io.h" +#include "sleep.h" + +/**************************** Constant Definitions *************************/ + + +/*****************************************************************************/ +/** +* +* This API gives delay in sec +* +* @param seconds - delay time in seconds +* +* @return none +* +* @note none +* +*****************************************************************************/ + void sleep(u32 seconds) + { +#if defined (ARMR5) + sleep_R5(seconds); +#elif defined (__aarch64__) || defined (ARMA53_32) + sleep_A53(seconds); +#elif defined (__MICROBLAZE__) + sleep_MB(seconds); +#else + sleep_A9(seconds); +#endif + + } + +/****************************************************************************/ +/** +* +* This API gives delay in usec +* +* @param useconds - delay time in useconds +* +* @return none +* +* @note none +* +*****************************************************************************/ + void usleep(ULONG useconds) + { +#if defined (ARMR5) + usleep_R5(useconds); +#elif defined (__aarch64__) || defined (ARMA53_32) + usleep_A53(useconds); +#elif defined (__MICROBLAZE__) + usleep_MB(useconds); +#else + usleep_A9(useconds); +#endif + + } diff --git a/arm/hal/lib/common/xil_testcache.c b/arm/hal/lib/common/xil_testcache.c new file mode 100644 index 0000000..f101c14 --- /dev/null +++ b/arm/hal/lib/common/xil_testcache.c @@ -0,0 +1,341 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_testcache.c +* @addtogroup common_test_utils +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date	 Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/28/09 Initial release
+* 4.1   asa  05/09/14 Ensured that the address uses for cache test is aligned
+*				      cache line.
+* 
+* +******************************************************************************/ +#ifdef __ARM__ +#include "xil_cache.h" +#include "xil_testcache.h" +#include "xil_types.h" +#include "xpseudo_asm.h" +#ifdef __aarch64__ +#include "xreg_cortexa53.h" +#else +#include "xreg_cortexr5.h" +#endif + +#include "xil_types.h" + +extern void xil_printf(const char8 *ctrl1, ...); + +#define DATA_LENGTH 128 + +#ifdef __aarch64__ +static INTPTR Data[DATA_LENGTH] __attribute__ ((aligned(64))); +#else +static INTPTR Data[DATA_LENGTH] __attribute__ ((aligned(32))); +#endif + + +/*****************************************************************************/ +/** +* +* @brief Perform DCache range related API test such as Xil_DCacheFlushRange +* and Xil_DCacheInvalidateRange. This test function writes a constant +* value to the Data array, flushes the range, writes a new value, then +* invalidates the corresponding range. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ +s32 Xil_TestDCacheRange(void) +{ + s32 Index; + s32 Status = 0; + u32 CtrlReg; + INTPTR Value; + + xil_printf("-- Cache Range Test --\n\r"); + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0xA0A00505; + + xil_printf(" initialize Data done:\r\n"); + + Xil_DCacheFlushRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR)); + + xil_printf(" flush range done\r\n"); + + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + if (Value != 0xA0A00505) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + if (!Status) { + xil_printf(" Flush worked\r\n"); + } + else { + xil_printf("Error: flush dcache range not working\r\n"); + } + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0xA0A0C505; + + + + Xil_DCacheFlushRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR)); + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = Index + 3; + + Xil_DCacheInvalidateRange((INTPTR)Data, DATA_LENGTH * sizeof(INTPTR)); + + xil_printf(" invalidate dcache range done\r\n"); + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0xA0A0A05; + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + if (Value != 0xA0A0A05) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + + if (!Status) { + xil_printf(" Invalidate worked\r\n"); + } + else { + xil_printf("Error: Invalidate dcache range not working\r\n"); + } + xil_printf("-- Cache Range Test Complete --\r\n"); + return Status; + +} + +/*****************************************************************************/ +/** +* @brief Perform DCache all related API test such as Xil_DCacheFlush and +* Xil_DCacheInvalidate. This test function writes a constant value +* to the Data array, flushes the DCache, writes a new value, +* then invalidates the DCache. +* +* @return +* - 0 is returned for a pass +* - -1 is returned for a failure +*****************************************************************************/ +s32 Xil_TestDCacheAll(void) +{ + s32 Index; + s32 Status; + INTPTR Value; + u32 CtrlReg; + + xil_printf("-- Cache All Test --\n\r"); + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0x50500A0A; + xil_printf(" initialize Data done:\r\n"); + + Xil_DCacheFlush(); + xil_printf(" flush all done\r\n"); + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + + if (Value != 0x50500A0A) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + if (!Status) { + xil_printf(" Flush all worked\r\n"); + } + else { + xil_printf("Error: Flush dcache all not working\r\n"); + } + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0x505FFA0A; + + Xil_DCacheFlush(); + + + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = Index + 3; + + Xil_DCacheInvalidate(); + + xil_printf(" invalidate all done\r\n"); + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + for (Index = 0; Index < DATA_LENGTH; Index++) + Data[Index] = 0x50CFA0A; + dsb(); + #ifdef __aarch64__ + CtrlReg = mfcp(SCTLR_EL3); + CtrlReg |= (XREG_CONTROL_DCACHE_BIT); + mtcp(SCTLR_EL3,CtrlReg); + #else + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + #endif + dsb(); + Status = 0; + + for (Index = 0; Index < DATA_LENGTH; Index++) { + Value = Data[Index]; + if (Value != 0x50CFA0A) { + Status = -1; + xil_printf("Data[%d] = %x\r\n", Index, Value); + break; + } + } + + if (!Status) { + xil_printf(" Invalidate all worked\r\n"); + } + else { + xil_printf("Error: Invalidate dcache all not working\r\n"); + } + + xil_printf("-- DCache all Test Complete --\n\r"); + + return Status; +} + +/*****************************************************************************/ +/** +* @brief Perform Xil_ICacheInvalidateRange() on a few function pointers. +* +* @return +* - 0 is returned for a pass +* +* @note The function will hang if it fails. +*****************************************************************************/ +s32 Xil_TestICacheRange(void) +{ + + Xil_ICacheInvalidateRange((INTPTR)Xil_TestICacheRange, 1024); + Xil_ICacheInvalidateRange((INTPTR)Xil_TestDCacheRange, 1024); + Xil_ICacheInvalidateRange((INTPTR)Xil_TestDCacheAll, 1024); + + xil_printf("-- Invalidate icache range done --\r\n"); + + return 0; +} + +/*****************************************************************************/ +/** +* @brief Perform Xil_ICacheInvalidate() on a few function pointers. +* +* @return +* - 0 is returned for a pass +* +* @note The function will hang if it fails. +*****************************************************************************/ +s32 Xil_TestICacheAll(void) +{ + Xil_ICacheInvalidate(); + xil_printf("-- Invalidate icache all done --\r\n"); + return 0; +} +#endif diff --git a/arm/hal/lib/common/xil_testcache.h b/arm/hal/lib/common/xil_testcache.h new file mode 100644 index 0000000..5798c21 --- /dev/null +++ b/arm/hal/lib/common/xil_testcache.h @@ -0,0 +1,54 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_testcache.h +* +* @addtogroup common_test_utils +*

Cache test

+* The xil_testcache.h file contains utility functions to test cache. +* +* @{ +*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  07/29/09 First release
+* 
+* +******************************************************************************/ + +/** +*@cond nocomments +*/ + +#ifndef XIL_TESTCACHE_H /* prevent circular inclusions */ +#define XIL_TESTCACHE_H /* by using protection macros */ + +#include "xil_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern s32 Xil_TestDCacheRange(void); +extern s32 Xil_TestDCacheAll(void); +extern s32 Xil_TestICacheRange(void); +extern s32 Xil_TestICacheAll(void); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + +/** + *@endcond + */ + +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/arm/hal/lib/common/xil_testio.c b/arm/hal/lib/common/xil_testio.c new file mode 100644 index 0000000..c05acd9 --- /dev/null +++ b/arm/hal/lib/common/xil_testio.c @@ -0,0 +1,273 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_testio.c +* @addtogroup common_test_utils +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xil_testio.h" +#include "xil_assert.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ +/************************** Function Prototypes *****************************/ + + + +/** + * + * Endian swap a 16-bit word. + * @param Data is the 16-bit word to be swapped. + * @return The endian swapped value. + * + */ +static u16 Swap16(u16 Data) +{ + return ((Data >> 8U) & 0x00FFU) | ((Data << 8U) & 0xFF00U); +} + +/** + * + * Endian swap a 32-bit word. + * @param Data is the 32-bit word to be swapped. + * @return The endian swapped value. + * + */ +static u32 Swap32(u32 Data) +{ + u16 Lo16; + u16 Hi16; + + u16 Swap16Lo; + u16 Swap16Hi; + + Hi16 = (u16)((Data >> 16U) & 0x0000FFFFU); + Lo16 = (u16)(Data & 0x0000FFFFU); + + Swap16Lo = Swap16(Lo16); + Swap16Hi = Swap16(Hi16); + + return (((u32)(Swap16Lo)) << 16U) | ((u32)Swap16Hi); +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 8-bit wide register IO test where the +* register is accessed using Xil_Out8 and Xil_In8, and comparing +* the written values by reading them back. +* +* @param Addr: a pointer to the region of memory to be tested. +* @param Length: Length of the block. +* @param Value: constant used for writing the memory. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ + +s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value) +{ + u8 ValueIn; + s32 Index; + s32 Status = 0; + + for (Index = 0; Index < Length; Index++) { + Xil_Out8((INTPTR)Addr, Value); + + ValueIn = Xil_In8((INTPTR)Addr); + + if ((Value != ValueIn) && (Status == 0)) { + Status = -1; + break; + } + } + return Status; + +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 16-bit wide register IO test. Each location +* is tested by sequentially writing a 16-bit wide register, reading +* the register, and comparing value. This function tests three kinds +* of register IO functions, normal register IO, little-endian register +* IO, and big-endian register IO. When testing little/big-endian IO, +* the function performs the following sequence, Xil_Out16LE/Xil_Out16BE, +* Xil_In16, Compare In-Out values, Xil_Out16, Xil_In16LE/Xil_In16BE, +* Compare In-Out values. Whether to swap the read-in value before +* comparing is controlled by the 5th argument. +* +* @param Addr: a pointer to the region of memory to be tested. +* @param Length: Length of the block. +* @param Value: constant used for writing the memory. +* @param Kind: Type of test. Acceptable values are: +* XIL_TESTIO_DEFAULT, XIL_TESTIO_LE, XIL_TESTIO_BE. +* @param Swap: indicates whether to byte swap the read-in value. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ + +s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap) +{ + u16 *TempAddr16; + u16 ValueIn = 0U; + s32 Index; + TempAddr16 = Addr; + Xil_AssertNonvoid(TempAddr16 != NULL); + + for (Index = 0; Index < Length; Index++) { + switch (Kind) { + case XIL_TESTIO_LE: + Xil_Out16LE((INTPTR)TempAddr16, Value); + break; + case XIL_TESTIO_BE: + Xil_Out16BE((INTPTR)TempAddr16, Value); + break; + default: + Xil_Out16((INTPTR)TempAddr16, Value); + break; + } + + ValueIn = Xil_In16((INTPTR)TempAddr16); + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap16(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + + /* second round */ + Xil_Out16((INTPTR)TempAddr16, Value); + + switch (Kind) { + case XIL_TESTIO_LE: + ValueIn = Xil_In16LE((INTPTR)TempAddr16); + break; + case XIL_TESTIO_BE: + ValueIn = Xil_In16BE((INTPTR)TempAddr16); + break; + default: + ValueIn = Xil_In16((INTPTR)TempAddr16); + break; + } + + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap16(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + TempAddr16 += sizeof(u16); + } + return 0; +} + + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 32-bit wide register IO test. Each location +* is tested by sequentially writing a 32-bit wide register, reading +* the register, and comparing value. This function tests three kinds +* of register IO functions, normal register IO, little-endian register IO, +* and big-endian register IO. When testing little/big-endian IO, +* the function perform the following sequence, Xil_Out32LE/ +* Xil_Out32BE, Xil_In32, Compare, Xil_Out32, Xil_In32LE/Xil_In32BE, Compare. +* Whether to swap the read-in value *before comparing is controlled +* by the 5th argument. +* @param Addr: a pointer to the region of memory to be tested. +* @param Length: Length of the block. +* @param Value: constant used for writing the memory. +* @param Kind: type of test. Acceptable values are: +* XIL_TESTIO_DEFAULT, XIL_TESTIO_LE, XIL_TESTIO_BE. +* @param Swap: indicates whether to byte swap the read-in value. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +*****************************************************************************/ +s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap) +{ + u32 *TempAddr; + u32 ValueIn = 0U; + s32 Index; + TempAddr = Addr; + Xil_AssertNonvoid(TempAddr != NULL); + + for (Index = 0; Index < Length; Index++) { + switch (Kind) { + case XIL_TESTIO_LE: + Xil_Out32LE((INTPTR)TempAddr, Value); + break; + case XIL_TESTIO_BE: + Xil_Out32BE((INTPTR)TempAddr, Value); + break; + default: + Xil_Out32((INTPTR)TempAddr, Value); + break; + } + + ValueIn = Xil_In32((INTPTR)TempAddr); + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap32(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + + /* second round */ + Xil_Out32((INTPTR)TempAddr, Value); + + + switch (Kind) { + case XIL_TESTIO_LE: + ValueIn = Xil_In32LE((INTPTR)TempAddr); + break; + case XIL_TESTIO_BE: + ValueIn = Xil_In32BE((INTPTR)TempAddr); + break; + default: + ValueIn = Xil_In32((INTPTR)TempAddr); + break; + } + + if ((Kind != 0) && (Swap != 0)) { + ValueIn = Swap32(ValueIn); + } + + if (Value != ValueIn) { + return -1; + } + TempAddr += sizeof(u32); + } + return 0; +} diff --git a/arm/hal/lib/common/xil_testio.h b/arm/hal/lib/common/xil_testio.h new file mode 100644 index 0000000..5a1bda3 --- /dev/null +++ b/arm/hal/lib/common/xil_testio.h @@ -0,0 +1,76 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_testio.h +* +* @addtogroup common_test_utils Test Utilities for Memory and Caches +*

I/O test

+* The xil_testio.h file contains utility functions to test endian related memory +* IO functions. +* +* A subset of the memory tests can be selected or all of the tests can be run +* in order. If there is an error detected by a subtest, the test stops and the +* failure code is returned. Further tests are not run even if all of the tests +* are selected. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00 hbm  08/05/09 First release
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XIL_TESTIO_H /* prevent circular inclusions */ +#define XIL_TESTIO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ + + +#define XIL_TESTIO_DEFAULT 0 +#define XIL_TESTIO_LE 1 +#define XIL_TESTIO_BE 2 + +/** + *@endcond + */ + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +extern s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value); +extern s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap); +extern s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/arm/hal/lib/common/xil_testmem.c b/arm/hal/lib/common/xil_testmem.c new file mode 100644 index 0000000..aaa0617 --- /dev/null +++ b/arm/hal/lib/common/xil_testmem.c @@ -0,0 +1,1575 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_testmem.c +* @addtogroup common_test_utils +* +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 7.5   mus  03/10/21 Added new set of Xil_TestMem32, Xil_TestMem16 and
+*                     Xil_TestMem8 APIs to support memory test for memory
+*                     regions mapped at extended addresses
+*                     (addresses > 4 GB). These new set of APIs would be
+*                     compiled only for 32 bit Microblaze processor, if
+*                     XPAR_MICROBLAZE_ADDR_SIZE is greater than 32.
+*                     It fixes CR#1089129.
+* 7.6   mus  07/29/21 Updated Xil_TestMem8 to fix issues reported by static
+*                     analysis tool. It fixes CR#1105956.
+* 7.7	sk   01/10/22 Remove commented macro to fix misra_c_2012_directive_4_4
+* 		      violation.
+* 7.7	sk   01/10/22 Modify operands to fix misra_c_2012_rule_10_1 violation.
+* 7.7	sk   01/10/22 Typecast to make the both left and right sides expressions
+* 		      of same type and fix misra_c_2012_rule_10_6 violation.
+* 7.7	sk   01/10/22 Modify varaiable name from I to i to fix misra_c_2012_rule_
+* 		      21_2 violation.
+* 7.7	sk   01/10/22 Remove arithematic operations on pointer varaible to fix
+* 		      misra_c_2012_rule_18_4 violation.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ +#include "xil_testmem.h" +#include "xil_io.h" +#include "xil_assert.h" + +/************************** Constant Definitions ****************************/ +/************************** Function Prototypes *****************************/ + +static u32 RotateLeft(u32 Input, u8 Width); + +/* define ROTATE_RIGHT to give access to this functionality */ +#ifdef ROTATE_RIGHT +static u32 RotateRight(u32 Input, u8 Width); +#endif /* ROTATE_RIGHT */ + +#if defined(__MICROBLAZE__) && !defined(__arch64__) && (XPAR_MICROBLAZE_ADDR_SIZE > 32) + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 8-bit wide memory test. +* +* @param Addrlow: lower 32 bit address of memory to be tested. +* @param Addrhigh: upper 32 bit address of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: type of test selected. See xil_testmem.h for possible +* values. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem8(u32 Addrlow, u32 Addrhigh, u32 Words, u8 Pattern, u8 Subtest) +{ + u32 I; + u32 j; + u8 Val; + u8 WordMem8; + s32 Status = 0; + u64 Addr = (Addrlow + ((u64)Addrhigh << 32)); + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + + /* + * select the proper Subtest(s) + */ + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from XIL_TESTMEM_INIT_VALUE + */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + sbea(Addr+I, Val); + Val++; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = XIL_TESTMEM_INIT_VALUE; + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference + * Val + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem8 = lbuea(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking ones test + */ + + for (j = 0U; j < NUM_OF_BITS_IN_BYTE; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + Val = (u8)((u32)1 << j); + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + for (I = 0U; I < NUM_OF_BITS_IN_BYTE; I++) { + /* write memory location */ + sbea(Addr+I, Val); + Val = (u8)RotateLeft(Val, 8U); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u8)((u32)1 << j); + /* Read the values from each location that was written */ + for (I = 0U; I < NUM_OF_BITS_IN_BYTE; I++) { + /* read memory location */ + WordMem8 = lbuea(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + Val = (u8)RotateLeft(Val, NUM_OF_BITS_IN_BYTE); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible initial test + * Patterns for walking zeros test + */ + + for (j = 0U; j < NUM_OF_BITS_IN_BYTE; j++) { + /* + * Generate an initial value for walking ones test to test + * for bad data bits + */ + Val = (u8) (~(1U << j)); + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + for (I = 0U; I < NUM_OF_BITS_IN_BYTE; I++) { + /* write memory location */ + sbea(Addr+I, Val); + Val = ~((u8)RotateLeft(~Val, NUM_OF_BITS_IN_BYTE)); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u8) (~(1U << j)); + /* Read the values from each location that was written */ + for (I = 0U; I < NUM_OF_BITS_IN_BYTE; I++) { + /* read memory location */ + WordMem8 = lbuea(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + + Val = ~((u8)RotateLeft(~Val, NUM_OF_BITS_IN_BYTE)); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + Val = (u8) (~((INTPTR) (Addr + I))); + sbea(Addr+I, Val); + } + + /* + * Check every word within the words + * of tested memory + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem8 = lbuea(Addr+I); + Val = (u8) (~((INTPTR) (Addr+I))); + if ((WordMem8 ^ Val) != 0x00U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + + if (Pattern == (u8)0) { + Val = 0xA5U; + } + else { + Val = Pattern; + } + /* + * Fill the memory with fixed Pattern + */ + for (I = 0U; I < Words; I++) { + /* write memory location */ + sbea(Addr+I, Val); + } + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed Pattern + */ + + for (I = 0U; I < Words; I++) { + /* read memory location */ + WordMem8 = lbuea(Addr+I); + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 16-bit wide memory test. +* +* @param Addrlow: lower 32 bit address of memory to be tested. +* @param Addrhigh: upper 32 bit address of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant Pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: type of test selected. See xil_testmem.h for possible +* values. +* +* @return +* +* - -1 is returned for a failure +* - 0 is returned for a pass +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem16(u32 Addrlow,u32 Addrhigh, u32 Words, u16 Pattern, u8 Subtest) +{ + u32 I; + u32 j; + u16 Val; + u16 WordMem16; + s32 Status = 0; + u64 Addr = (Addrlow + ((u64)Addrhigh << 32)); + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + + /* + * selectthe proper Subtest(s) + */ + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'XIL_TESTMEM_INIT_VALUE' + */ + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * Words);) { + /* write memory location */ + shea(Addr+I, Val); + Val++; + I = I + NUM_OF_BYTES_IN_HW; + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = XIL_TESTMEM_INIT_VALUE; + + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference val + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * Words);) { + /* read memory location */ + WordMem16 = lhuea(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val++; + I = I + NUM_OF_BYTES_IN_HW; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial test + * Patterns for walking ones test + */ + + for (j = 0U; j < NUM_OF_BITS_IN_HW; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = (u16)((u32)1 << j); + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * NUM_OF_BITS_IN_HW); ) { + /* write memory location */ + shea(Addr+I,Val); + Val = (u16)RotateLeft(Val, 16U); + I = I + NUM_OF_BYTES_IN_HW; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u16)((u32)1 << j); + /* Read the values from each location that was written */ + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * NUM_OF_BITS_IN_HW); ) { + /* read memory location */ + WordMem16 = lhuea(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val = (u16)RotateLeft(Val, NUM_OF_BITS_IN_HW); + I = I + NUM_OF_BYTES_IN_HW; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking zeros test + */ + + for (j = 0U; j < NUM_OF_BITS_IN_HW; j++) { + /* + * Generate an initial value for walking ones + * test to test for bad + * data bits + */ + + Val = ~(1U << j); + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * NUM_OF_BITS_IN_HW);) { + shea(Addr+I, Val); + Val = ~((u16)RotateLeft(~Val, 16U)); + I = I + NUM_OF_BYTES_IN_HW; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = ~(1U << j); + /* Read the values from each location that was written */ + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * NUM_OF_BITS_IN_HW); ) { + WordMem16= lhuea(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val = ~((u16)RotateLeft(~Val, NUM_OF_BITS_IN_HW)); + I = I + NUM_OF_BYTES_IN_HW; + } + + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * Words);) { + /* write memory location */ + Val = (u16) (~((INTPTR)((Addr+I)))); + shea(Addr+I, Val); + I = I + NUM_OF_BYTES_IN_HW; + } + /* + * Check every word within the words + * of tested memory + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_HW*Words); ) { + /* read memory location */ + WordMem16 = lhuea(Addr+I); + Val = (u16) (~((INTPTR) ((Addr+I)))); + if ((WordMem16 ^ Val) != 0x0000U) { + Status = -1; + goto End_Label; + } + I = I + NUM_OF_BYTES_IN_HW; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + if (Pattern == (u16)0) { + Val = 0xDEADU; + } + else { + Val = Pattern; + } + + /* + * Fill the memory with fixed pattern + */ + + for (I = 0U; I < (2*Words);) { + /* write memory location */ + shea(Addr+I, Val); + I = I + NUM_OF_BYTES_IN_HW; + } + + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed pattern + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_HW * Words);) { + /* read memory location */ + WordMem16=lhuea(Addr+I); + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + I = I + NUM_OF_BYTES_IN_HW; + } + } +End_Label: + return Status; +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 32-bit wide memory test. +* +* @param Addrlow: lower 32 bit address of memory to be tested. +* @param Addrhigh: upper 32 bit address of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: test type selected. See xil_testmem.h for possible +* values. +* +* @return +* - 0 is returned for a pass +* - 1 is returned for a failure +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem32(u32 Addrlow, u32 Addrhigh, u32 Words, u32 Pattern, u8 Subtest) +{ + u32 I; + u32 j; + u32 Val; + u32 WordMem32; + s32 Status = 0; + u64 Addr = (Addrlow + ((u64)Addrhigh << 32)); + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= (u8)XIL_TESTMEM_MAXTEST); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'XIL_TESTMEM_INIT_VALUE' + */ + for (I = 0U; I <(NUM_OF_BYTES_IN_WORD * Words);) { + swea(Addr+I, Val); + Val++; + I = I + NUM_OF_BYTES_IN_WORD; + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = XIL_TESTMEM_INIT_VALUE; + + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference + * Val + */ + + for (I = 0U; I < ( NUM_OF_BYTES_IN_WORD * Words);) { + WordMem32 = lwea(Addr+I); + + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + + Val++; + I = I + NUM_OF_BYTES_IN_WORD; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking ones test + */ + + for (j = 0U; j < NUM_OF_BITS_IN_WORD; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = (1U << j); + + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_WORD * NUM_OF_BITS_IN_WORD);) { + /* write memory location */ + swea(Addr+I, Val); + Val = (u32) RotateLeft(Val, NUM_OF_BITS_IN_WORD); + I = I + NUM_OF_BYTES_IN_WORD; + } + + /* + * Restore the reference 'val' to the + * initial value + */ + Val = 1U << j; + + /* Read the values from each location that was + * written */ + for (I = 0U; I < ((u32)32 * NUM_OF_BYTES_IN_WORD);) { + /* read memory location */ + + WordMem32 = lwea(Addr+I); + + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + + Val = (u32)RotateLeft(Val, NUM_OF_BITS_IN_WORD); + I = I + NUM_OF_BYTES_IN_WORD; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible + * initial test Patterns for walking zeros test + */ + + for (j = 0U; j < NUM_OF_BITS_IN_WORD; j++) { + + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = ~(1U << j); + + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + + for (I = 0U; I < (NUM_OF_BITS_IN_WORD * NUM_OF_BYTES_IN_WORD);) { + /* write memory location */ + swea(Addr+I, Val); + Val = ~((u32)RotateLeft(~Val, NUM_OF_BITS_IN_WORD)); + I = I + NUM_OF_BYTES_IN_WORD; + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + + Val = ~(1U << j); + + /* Read the values from each location that was + * written */ + for (I = 0U; I < (NUM_OF_BITS_IN_WORD * NUM_OF_BYTES_IN_WORD);) { + /* read memory location */ + WordMem32 = lwea(Addr+I); + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + Val = ~((u32)RotateLeft(~Val, NUM_OF_BITS_IN_WORD)); + I = I + NUM_OF_BYTES_IN_WORD; + } + + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (I = 0U; I < (NUM_OF_BYTES_IN_WORD * Words);) { + /* write memory location */ + Val = (u32) (~((INTPTR) (Addr+I))); + swea(Addr+I, Val); + I = I + NUM_OF_BYTES_IN_WORD; + } + + /* + * Check every word within the words + * of tested memory + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_WORD * Words);) { + /* Read the location */ + WordMem32 = lwea(Addr+I); + Val = (u32) (~((INTPTR) (Addr+I))); + + if ((WordMem32 ^ Val) != 0x00000000U) { + Status = -1; + goto End_Label; + } + I = I + NUM_OF_BYTES_IN_WORD; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + + if (Pattern == (u32)0) { + Val = 0xDEADBEEFU; + } + else { + Val = Pattern; + } + + /* + * Fill the memory with fixed Pattern + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_WORD * Words);) { + /* write memory location */ + swea(Addr+I, Val); + I = I + NUM_OF_BYTES_IN_WORD; + } + + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed Pattern + */ + + for (I = 0U; I < (NUM_OF_BYTES_IN_WORD * Words);) { + + /* read memory location */ + + WordMem32 = lwea(Addr+I); + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + I = I + NUM_OF_BYTES_IN_WORD; + } + } + +End_Label: + return Status; +} + +#else +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 32-bit wide memory test. +* +* @param Addr: pointer to the region of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: test type selected. See xil_testmem.h for possible +* values. +* +* @return +* - 0 is returned for a pass +* - 1 is returned for a failure +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest) +{ + u32 i; + u32 j; + u32 Val; + u32 FirtVal; + u32 WordMem32; + s32 Status = 0; + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= (u8)XIL_TESTMEM_MAXTEST); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + FirtVal = XIL_TESTMEM_INIT_VALUE; + + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'FirtVal' + */ + for (i = 0U; i < Words; i++) { + Addr[i] = Val; + Val++; + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = FirtVal; + + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference + * Val + */ + + for (i = 0U; i < Words; i++) { + WordMem32 = Addr[i]; + + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking ones test + */ + + for (j = 0U; j < (u32)32; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = (1UL << j); + + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + + for (i = 0U; i < (u32)32; i++) { + /* write memory location */ + Addr[i] = Val; + Val = (u32) RotateLeft(Val, 32U); + } + + /* + * Restore the reference 'val' to the + * initial value + */ + Val = 1UL << j; + + /* Read the values from each location that was + * written */ + for (i = 0U; i < (u32)32; i++) { + /* read memory location */ + + WordMem32 = Addr[i]; + + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + + Val = (u32)RotateLeft(Val, 32U); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible + * initial test Patterns for walking zeros test + */ + + for (j = 0U; j < (u32)32; j++) { + + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = ~(1UL << j); + + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + + for (i = 0U; i < (u32)32; i++) { + /* write memory location */ + Addr[i] = Val; + Val = ~((u32)RotateLeft(~Val, 32U)); + } + + /* + * Restore the reference 'Val' to the + * initial value + */ + + Val = ~(1UL << j); + + /* Read the values from each location that was + * written */ + for (i = 0U; i < (u32)32; i++) { + /* read memory location */ + WordMem32 = Addr[i]; + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + Val = ~((u32)RotateLeft(~Val, 32U)); + } + + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (i = 0U; i < Words; i++) { + /* write memory location */ + Val = ~(u32) (UINTPTR) &Addr[i]; + Addr[i] = Val; + } + + /* + * Check every word within the words + * of tested memory + */ + + for (i = 0U; i < Words; i++) { + /* Read the location */ + WordMem32 = Addr[i]; + Val = ~(u32) (UINTPTR) &Addr[i]; + + if ((WordMem32 ^ Val) != 0x00000000U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + + if (Pattern == (u32)0) { + Val = 0xDEADBEEFU; + } + else { + Val = Pattern; + } + + /* + * Fill the memory with fixed Pattern + */ + + for (i = 0U; i < Words; i++) { + /* write memory location */ + Addr[i] = Val; + } + + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed Pattern + */ + + for (i = 0U; i < Words; i++) { + + /* read memory location */ + + WordMem32 = Addr[i]; + if (WordMem32 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 16-bit wide memory test. +* +* @param Addr: pointer to the region of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant Pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: type of test selected. See xil_testmem.h for possible +* values. +* +* @return +* +* - -1 is returned for a failure +* - 0 is returned for a pass +* +* @note Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest) +{ + u32 i; + u32 j; + u16 Val; + u16 FirtVal; + u16 WordMem16; + s32 Status = 0; + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + FirtVal = XIL_TESTMEM_INIT_VALUE; + + /* + * selectthe proper Subtest(s) + */ + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'FirtVal' + */ + for (i = 0U; i < Words; i++) { + /* write memory location */ + Addr[i] = Val; + Val++; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = FirtVal; + + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference val + */ + + for (i = 0U; i < Words; i++) { + /* read memory location */ + WordMem16 = Addr[i]; + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial test + * Patterns for walking ones test + */ + + for (j = 0U; j < (u32)16; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + + Val = (u16)((u32)1 << j); + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + + for (i = 0U; i < (u32)16; i++) { + /* write memory location */ + Addr[i] = Val; + Val = (u16)RotateLeft(Val, 16U); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u16)((u32)1 << j); + /* Read the values from each location that was written */ + for (i = 0U; i < (u32)16; i++) { + /* read memory location */ + WordMem16 = Addr[i]; + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val = (u16)RotateLeft(Val, 16U); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking zeros test + */ + + for (j = 0U; j < (u32)16; j++) { + /* + * Generate an initial value for walking ones + * test to test for bad + * data bits + */ + + Val = (u16) (~((u16)1U << j)); + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + + for (i = 0U; i < (u32)16; i++) { + /* write memory location */ + Addr[i] = Val; + Val = ~((u16)RotateLeft(~((u32)Val), 16U)); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u16) (~((u16)1U << j)); + /* Read the values from each location that was written */ + for (i = 0U; i < (u32)16; i++) { + /* read memory location */ + WordMem16 = Addr[i]; + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + Val = ~((u16)RotateLeft(~((u32)Val), 16U)); + } + + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (i = 0U; i < Words; i++) { + /* write memory location */ + Val = ~(u16) (UINTPTR) &Addr[i]; + Addr[i] = Val; + } + /* + * Check every word within the words + * of tested memory + */ + + for (i = 0U; i < Words; i++) { + /* read memory location */ + WordMem16 = Addr[i]; + Val = ~(u16) (UINTPTR) &Addr[i]; + if ((WordMem16 ^ Val) != 0x0000U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + if (Pattern == (u16)0) { + Val = 0xDEADU; + } + else { + Val = Pattern; + } + + /* + * Fill the memory with fixed pattern + */ + + for (i = 0U; i < Words; i++) { + /* write memory location */ + Addr[i] = Val; + } + + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed pattern + */ + + for (i = 0U; i < Words; i++) { + /* read memory location */ + WordMem16 = Addr[i]; + if (WordMem16 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} + + +/*****************************************************************************/ +/** +* +* @brief Perform a destructive 8-bit wide memory test. +* +* @param Addr: pointer to the region of memory to be tested. +* @param Words: length of the block. +* @param Pattern: constant used for the constant pattern test, if 0, +* 0xDEADBEEF is used. +* @param Subtest: type of test selected. See xil_testmem.h for possible +* values. +* +* @return +* - -1 is returned for a failure +* - 0 is returned for a pass +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** Width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*****************************************************************************/ +s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest) +{ + u32 i; + u32 j; + u8 Val; + u8 FirtVal; + u8 WordMem8; + s32 Status = 0; + + Xil_AssertNonvoid(Words != (u32)0); + Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST); + + /* + * variable initialization + */ + Val = XIL_TESTMEM_INIT_VALUE; + FirtVal = XIL_TESTMEM_INIT_VALUE; + + /* + * select the proper Subtest(s) + */ + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INCREMENT)) { + /* + * Fill the memory with incrementing + * values starting from 'FirtVal' + */ + for (i = 0U; i < Words; i++) { + /* write memory location */ + Addr[i] = Val; + Val++; + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = FirtVal; + /* + * Check every word within the words + * of tested memory and compare it + * with the incrementing reference + * Val + */ + + for (i = 0U; i < Words; i++) { + /* read memory location */ + WordMem8 = Addr[i]; + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + Val++; + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKONES)) { + /* + * set up to cycle through all possible initial + * test Patterns for walking ones test + */ + + for (j = 0U; j < (u32)8; j++) { + /* + * Generate an initial value for walking ones test + * to test for bad data bits + */ + Val = (u8)((u32)1 << j); + /* + * START walking ones test + * Write a one to each data bit indifferent locations + */ + for (i = 0U; i < (u32)8; i++) { + /* write memory location */ + Addr[i] = Val; + Val = (u8)RotateLeft(Val, 8U); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u8)((u32)1 << j); + /* Read the values from each location that was written */ + for (i = 0U; i < (u32)8; i++) { + /* read memory location */ + WordMem8 = Addr[i]; + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + Val = (u8)RotateLeft(Val, 8U); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_WALKZEROS)) { + /* + * set up to cycle through all possible initial test + * Patterns for walking zeros test + */ + + for (j = 0U; j < (u32)8; j++) { + /* + * Generate an initial value for walking ones test to test + * for bad data bits + */ + Val = (u8) (~(1U << j)); + /* + * START walking zeros test + * Write a one to each data bit indifferent locations + */ + for (i = 0U; i < (u32)8; i++) { + /* write memory location */ + Addr[i] = Val; + Val = ~((u8)RotateLeft(~((u32)Val), 8U)); + } + /* + * Restore the reference 'Val' to the + * initial value + */ + Val = (u8) (~(1U << j)); + /* Read the values from each location that was written */ + for (i = 0U; i < (u32)8; i++) { + /* read memory location */ + WordMem8 = Addr[i]; + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + + Val = ~((u8)RotateLeft(~((u32)Val), 8U)); + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_INVERSEADDR)) { + /* Fill the memory with inverse of address */ + for (i = 0U; i < Words; i++) { + /* write memory location */ + Val = ~(u8) (UINTPTR) &Addr[i]; + Addr[i] = Val; + } + + /* + * Check every word within the words + * of tested memory + */ + + for (i = 0U; i < Words; i++) { + /* read memory location */ + WordMem8 = Addr[i]; + Val = ~(u8) (UINTPTR) &Addr[i]; + if ((WordMem8 ^ Val) != 0x00U) { + Status = -1; + goto End_Label; + } + } + } + + if((Subtest == XIL_TESTMEM_ALLMEMTESTS) || (Subtest == XIL_TESTMEM_FIXEDPATTERN)) { + /* + * Generate an initial value for + * memory testing + */ + + if (Pattern == (u8)0) { + Val = 0xA5U; + } + else { + Val = Pattern; + } + /* + * Fill the memory with fixed Pattern + */ + for (i = 0U; i < Words; i++) { + /* write memory location */ + Addr[i] = Val; + } + /* + * Check every word within the words + * of tested memory and compare it + * with the fixed Pattern + */ + + for (i = 0U; i < Words; i++) { + /* read memory location */ + WordMem8 = Addr[i]; + if (WordMem8 != Val) { + Status = -1; + goto End_Label; + } + } + } + +End_Label: + return Status; +} +#endif + +/*****************************************************************************/ +/** +* +* @brief Rotates the provided value to the left one bit position +* +* @param Input is value to be rotated to the left +* @param Width is the number of bits in the input data +* +* @return The resulting unsigned long value of the rotate left +* +* +*****************************************************************************/ +static u32 RotateLeft(u32 Input, u8 Width) +{ + u32 Msb; + u32 ReturnVal; + u32 WidthMask; + u32 MsbMask; + u32 LocalInput = Input; + + /* + * set up the WidthMask and the MsbMask + */ + + MsbMask = 1UL << (Width - 1U); + + WidthMask = (MsbMask << (u32)1) - (u32)1; + + /* + * set the Width of the Input to the correct width + */ + + LocalInput = LocalInput & WidthMask; + + Msb = LocalInput & MsbMask; + + ReturnVal = LocalInput << 1U; + + if (Msb != 0x00000000U) { + ReturnVal = ReturnVal | (u32)0x00000001; + } + + ReturnVal = ReturnVal & WidthMask; + + return ReturnVal; + +} + +#ifdef ROTATE_RIGHT +/*****************************************************************************/ +/** +* +* @brief Rotates the provided value to the right one bit position +* +* @param Input: value to be rotated to the right +* @param Width: number of bits in the input data +* +* @return +* The resulting u32 value of the rotate right +* +*****************************************************************************/ +static u32 RotateRight(u32 Input, u8 Width) +{ + u32 Lsb; + u32 ReturnVal; + u32 WidthMask; + u32 MsbMask; + u32 LocalInput = Input; + /* + * set up the WidthMask and the MsbMask + */ + + MsbMask = 1U << (Width - 1U); + + WidthMask = (MsbMask << 1U) - 1U; + + /* + * set the width of the input to the correct width + */ + + LocalInput = LocalInput & WidthMask; + + ReturnVal = LocalInput >> 1U; + + Lsb = LocalInput & 0x00000001U; + + if (Lsb != 0x00000000U) { + ReturnVal = ReturnVal | MsbMask; + } + + ReturnVal = ReturnVal & WidthMask; + + return ReturnVal; + +} +#endif /* ROTATE_RIGHT */ diff --git a/arm/hal/lib/common/xil_testmem.h b/arm/hal/lib/common/xil_testmem.h new file mode 100644 index 0000000..7e29233 --- /dev/null +++ b/arm/hal/lib/common/xil_testmem.h @@ -0,0 +1,165 @@ +/****************************************************************************** +* Copyright (c) 2009 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_testmem.h +* @addtogroup common_test_utils Test Utilities for Memory and Caches +* +* - Cache test: xil_testcache.h contains utility functions to test cache. +* +* - I/O test: The Xil_testio.h file contains endian related memory IO functions. A +* subset of the memory tests can be selected or all of the tests can be run in order. +* If there is an error detected by a subtest, the test stops and the failure code is +* returned. Further tests are not run even if all of the tests are selected. +* +* - Memory test: The xil_testmem.h file contains utility functions to test memory. +* A subset of the memory tests can be selected or all of the tests can be run +* in order. If there is an error detected by a subtest, the test stops and the +* failure code is returned. Further tests are not run even if all of the tests are selected. +* +* +* Following list describes the supported memory tests: +* +* - XIL_TESTMEM_ALLMEMTESTS: This test runs all of the subtests. +* +* - XIL_TESTMEM_INCREMENT: This test +* starts at 'XIL_TESTMEM_INIT_VALUE' and uses the incrementing value as the +* test value for memory. +* +* - XIL_TESTMEM_WALKONES: Also known as the Walking ones test. This test +* uses a walking '1' as the test value for memory. +* @code +* location 1 = 0x00000001 +* location 2 = 0x00000002 +* ... +* @endcode +* +* - XIL_TESTMEM_WALKZEROS: Also known as the Walking zero's test. +* This test uses the inverse value of the walking ones test +* as the test value for memory. +* @code +* location 1 = 0xFFFFFFFE +* location 2 = 0xFFFFFFFD +* ... +*@endcode +* +* - XIL_TESTMEM_INVERSEADDR: Also known as the inverse address test. +* This test uses the inverse of the address of the location under test +* as the test value for memory. +* +* - XIL_TESTMEM_FIXEDPATTERN: Also known as the fixed pattern test. +* This test uses the provided patters as the test value for memory. +* If zero is provided as the pattern the test uses '0xDEADBEEF". +* +* @warning +* The tests are DESTRUCTIVE. Run before any initialized memory spaces +* have been set up. +* The address provided to the memory tests is not checked for +* validity except for the NULL case. It is possible to provide a code-space +* pointer for this test to start with and ultimately destroy executable code +* causing random failures. +* +* @note +* Used for spaces where the address range of the region is smaller than +* the data width. If the memory range is greater than 2 ** width, +* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will +* repeat on a boundary of a power of two making it more difficult to detect +* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR +* tests suffer the same problem. Ideally, if large blocks of memory are to be +* tested, break them up into smaller regions of memory to allow the test +* patterns used not to repeat over the region tested. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver    Who    Date    Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a hbm  08/25/09 First release
+* 7.5   mus  03/10/21 Added new set of Xil_TestMem32, Xil_TestMem16 and
+*                     Xil_TestMem8 APIs to support memory test for memory
+*                     regions mapped at extended addresses
+*                     (addresses > 4 GB). These new set of APIs would be
+*                     compiled only for 32 bit Microblaze processor, if
+*                     XPAR_MICROBLAZE_ADDR_SIZE is greater than 32.
+*                     It fixes CR#1089129.
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XIL_TESTMEM_H /* prevent circular inclusions */ +#define XIL_TESTMEM_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ +#include "xil_types.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + +/* xutil_memtest defines */ + +#define XIL_TESTMEM_INIT_VALUE 1U + +/** @name Memory subtests + * @{ + */ +/** + * See the detailed description of the subtests in the file description. + */ +#define XIL_TESTMEM_ALLMEMTESTS 0x00U +#define XIL_TESTMEM_INCREMENT 0x01U +#define XIL_TESTMEM_WALKONES 0x02U +#define XIL_TESTMEM_WALKZEROS 0x03U +#define XIL_TESTMEM_INVERSEADDR 0x04U +#define XIL_TESTMEM_FIXEDPATTERN 0x05U +#define XIL_TESTMEM_MAXTEST XIL_TESTMEM_FIXEDPATTERN +/* @} */ + +#if !defined(__aarch64__) && !defined(__arch64__) +#define NUM_OF_BITS_IN_BYTE 8U +#define NUM_OF_BYTES_IN_HW 2U +#define NUM_OF_BITS_IN_HW 16U +#define NUM_OF_BYTES_IN_WORD 4U +#define NUM_OF_BITS_IN_WORD 32U +#endif +/***************** Macros (Inline Functions) Definitions *********************/ + +/** + *@endcond + */ + +/************************** Function Prototypes ******************************/ + +/* xutil_testmem prototypes */ +#if defined(__MICROBLAZE__) && !defined(__arch64__) && (XPAR_MICROBLAZE_ADDR_SIZE > 32) +extern s32 Xil_TestMem32(u32 AddrLow, u32 AddrHigh, u32 Words, u32 Pattern, u8 Subtest); +extern s32 Xil_TestMem16(u32 AddrLow, u32 AddrHigh, u32 Words, u16 Pattern, u8 Subtest); +extern s32 Xil_TestMem8(u32 AddrLow, u32 AddrHigh, u32 Words, u8 Pattern, u8 Subtest); +#else +extern s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest); +extern s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest); +extern s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_test_utils". +*/ diff --git a/arm/hal/lib/common/xil_types.h b/arm/hal/lib/common/xil_types.h new file mode 100644 index 0000000..1d18bfb --- /dev/null +++ b/arm/hal/lib/common/xil_types.h @@ -0,0 +1,203 @@ +/****************************************************************************** +* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_types.h +* +* @addtogroup common_types Basic Data types for Xilinx® Software IP +* +* The xil_types.h file contains basic types for Xilinx software IP. These data types +* are applicable for all processors supported by Xilinx. +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a hbm  07/14/09 First release
+* 3.03a sdm  05/30/11 Added Xuint64 typedef and XUINT64_MSW/XUINT64_LSW macros
+* 5.00 	pkp  05/29/14 Made changes for 64 bit architecture
+*	srt  07/14/14 Use standard definitions from stdint.h and stddef.h
+*		      Define LONG and ULONG datatypes and mask values
+* 7.00  mus  01/07/19 Add cpp extern macro
+* 7.1   aru  08/19/19 Shift the value in UPPER_32_BITS only if it
+*                     is 64-bit processor
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ +#ifndef XIL_TYPES_H /* prevent circular inclusions */ +#define XIL_TYPES_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/************************** Constant Definitions *****************************/ + +#ifndef TRUE +# define TRUE 1U +#endif + +#ifndef FALSE +# define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +#define XIL_COMPONENT_IS_READY 0x11111111U /**< In device drivers, This macro will be + assigend to "IsReady" member of driver + instance to indicate that driver + instance is initialized and ready to use. */ +#define XIL_COMPONENT_IS_STARTED 0x22222222U /**< In device drivers, This macro will be assigend to + "IsStarted" member of driver instance + to indicate that driver instance is + started and it can be enabled. */ + +/* @name New types + * New simple types. + * @{ + */ +#ifndef __KERNEL__ +#ifndef XBASIC_TYPES_H +/* + * guarded against xbasic_types.h. + */ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +/** @}*/ +#define __XUINT64__ +typedef struct +{ + u32 Upper; + u32 Lower; +} Xuint64; + + +/*****************************************************************************/ +/** +* @brief Return the most significant half of the 64 bit data type. +* +* @param x is the 64 bit word. +* +* @return The upper 32 bits of the 64 bit word. +* +******************************************************************************/ +#define XUINT64_MSW(x) ((x).Upper) + +/*****************************************************************************/ +/** +* @brief Return the least significant half of the 64 bit data type. +* +* @param x is the 64 bit word. +* +* @return The lower 32 bits of the 64 bit word. +* +******************************************************************************/ +#define XUINT64_LSW(x) ((x).Lower) + +#endif /* XBASIC_TYPES_H */ + +/* + * xbasic_types.h does not typedef s* or u64 + */ +/** @{ */ +typedef char char8; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; +typedef uint64_t u64; +typedef int sint32; + +typedef intptr_t INTPTR; +typedef uintptr_t UINTPTR; +typedef ptrdiff_t PTRDIFF; +/** @}*/ +#if !defined(LONG) || !defined(ULONG) +typedef long LONG; +typedef unsigned long ULONG; +#endif + +#define ULONG64_HI_MASK 0xFFFFFFFF00000000U +#define ULONG64_LO_MASK ~ULONG64_HI_MASK + +#else +#include +#endif + +/** @{ */ +/** + * This data type defines an interrupt handler for a device. + * The argument points to the instance of the component + */ +typedef void (*XInterruptHandler) (void *InstancePtr); + +/** + * This data type defines an exception handler for a processor. + * The argument points to the instance of the component + */ +typedef void (*XExceptionHandler) (void *InstancePtr); + +/** + * @brief Returns 32-63 bits of a number. + * @param n : Number being accessed. + * @return Bits 32-63 of number. + * + * @note A basic shift-right of a 64- or 32-bit quantity. + * Use this to suppress the "right shift count >= width of type" + * warning when that quantity is 32-bits. + */ +#if defined (__aarch64__) || defined (__arch64__) +#define UPPER_32_BITS(n) ((u32)(((n) >> 16) >> 16)) +#else +#define UPPER_32_BITS(n) 0U +#endif +/** + * @brief Returns 0-31 bits of a number + * @param n : Number being accessed. + * @return Bits 0-31 of number + */ +#define LOWER_32_BITS(n) ((u32)(n)) + + + + +/************************** Constant Definitions *****************************/ + +#ifndef TRUE +#define TRUE 1U +#endif + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef NULL +#define NULL 0U +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** + *@endcond + */ +/** +* @} End of "addtogroup common_types". +*/ diff --git a/arm/hal/lib/common/xil_util.c b/arm/hal/lib/common/xil_util.c new file mode 100644 index 0000000..8cd6ced --- /dev/null +++ b/arm/hal/lib/common/xil_util.c @@ -0,0 +1,1238 @@ +/******************************************************************************/ +/** +* Copyright (c) 2019 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* @file xil_util.c +* +* xil_util.c file contains xil utility functions +* Except few functions, most of these functions are wrappers to standard functions. +* The standard string functions do not validate the input and that results into +* buffer overflows. To avoid it, the wrapper function validates the input and +* then passed to standard function. There are few constant time functions +* ( xxx_CT() ) which are used to compare the data in constant time. +* The constant time functions should be used while comparing secure data +* like password, keys which prevent disclosing of the data using +* timing analysis. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.4   mmd      04/21/19 First release.
+* 7.2   nava     08/01/20 Updated Xil_WaitForEvent() and Xil_WaitForEvents(()
+*                         API to use microsecond timeout instead of a free
+*                         counter.
+* 7.3   kal      06/30/20 Converted Xil_Ceil macro to API.
+*       rpo      08/19/20 Added function for read,modify,write
+*       kal      09/22/20 Changed the param type from const char to const char*
+*                         to avoid copying key onto stack
+*       td       10/16/20 Added Xil_Strcpy, Xil_Strcat, Xil_SecureMemCpy and
+*                         Xil_MemCmp functions
+* 7.4   am       11/26/20 Added Xil_StrCpyRange function
+* 7.6   kpt      07/15/21 Added Xil_SecureZeroize function
+* 7.7   kpt      11/09/21 Added Xil_SMemCmp, Xil_SMemCmp_CT, Xil_SMemCpy,
+*                         Xil_SMemSet, Xil_SStrCat, Xil_SStrCmp, Xil_SStrCmp_CT
+*                         Xil_SStrCpy functions
+*       kpt      11/25/21 Added strnlen function to fix ARMCC compilation
+*                         failure
+* 7.7	sk	 01/10/22 Update functions return type and update RetVal variable
+* 			  data type to fix misra_c_2012_directive_4_6 misrac
+* 			  violations.
+* 7.7	sk	 01/10/22 Update values from signed to unsigned to fix
+* 			  misra_c_2012_rule_10_4 violation.
+* 7.7	sk	 01/10/22 Add explicit parentheses to fix misra_c_2012_rule_12_1
+* 			  violation.
+* 7.7	sk	 01/10/22 Typecast character strings to u8 to fix misra_c_2012_rule_
+* 			  10_3 violation.
+* 7.7	sk	 01/10/22 Modify the code to reduce multiple break statements
+* 			  and fix misra_c_2012_rule_15_4 violation.
+* 7.7	sk	 01/10/22 Modify Xil_SMemCmp_CT and Xil_SMemCmp function argument
+* 			  type to fix misra_c_2012_rule_8_3 violation.
+* 7.7	sk	 01/10/22 Update conditional expression to fix misra_c_2012_rule_14_4
+* 			  violation.
+*       bm       01/20/22 Fix compilation warnings in Xil_SMemCpy
+*       mmd      02/28/22 Added Xil_SMemMove function
+* 7.7	sk	 03/02/22 Add explicit parentheses to fix misra_c_2012_rule_12_1
+* 			  violation.
+* 7.7	sk	 03/02/22 Add const qualifier to varaibles to fix misra_c_2012_rule_
+* 			  11_8 violation.
+* 7.7	sk	 03/02/22 Typecast expression with unsigned int to fix
+* 			  misra_c_2012_rule_10_7 violation.
+* 7.7	sk	 03/02/22 Typecast variables with unsigned or signed to fix misra_c
+* 			  _2012_rule_10_3 violation.
+* 7.7	sk	 03/02/22 Add const to unmodified variable to fix misra_c_2012
+* 			   _rule_8_13 violation.
+* 7.7	sk	 03/02/22 Typecast the function with void as return type is
+* 			  not used and fix misra_c_2012_rule_17_7 violation.
+* 7.7	sk	 03/02/22 Remove increment operations during comparision to
+* 			  fix misra_c_2012_rule_13_3 violation.
+* 7.7	sk	 03/02/22 Update values from signed to unsigned to fix
+* 			  misra_c_2012_rule_10_4 violation.
+*
+* 
+* +*****************************************************************************/ + +/****************************** Include Files *********************************/ +#include "xil_util.h" +#include "sleep.h" + +/************************** Constant Definitions ****************************/ +#define MAX_NIBBLES 8U + +/************************** Function Prototypes *****************************/ + +#ifdef __ARMCC_VERSION +/******************************************************************************/ +/** + * + * This API returns the length of the input string + * + * @param StartPtr is the pointer to the input string + * @param StrSize is the maximum length of the input string + * + * @return Returns the length of the input string + * + ******************************************************************************/ +static size_t strnlen (const char *StartPtr, size_t StrSize) +{ + const char *EndPtr = StartPtr; + size_t StrLen = 0U; + + EndPtr = memchr(StartPtr, '\0', StrSize); + if (EndPtr == NULL) { + StrLen = StrSize; + } + else { + StrLen = (size_t) (EndPtr - StartPtr); + } + + return StrLen; +} +#endif + +/******************************************************************************/ +/** +* This API ceils the provided float value. +* +* @param Value is a float variable which has to ceiled to nearest +* integer. +* +* @return Returns ceiled value. +* +*******************************************************************************/ +s32 Xil_Ceil(float Value) +{ + s32 Result = Value; + + if (Value > Result) { + Result = Result + 1; + } + + return Result; +} + +/****************************************************************************/ +/** + * Converts the char into the equivalent nibble. + * Ex: 'a' -> 0xa, 'A' -> 0xa, '9'->0x9 + * + * @param InChar - Input character to be converted to nibble. + * Valid characters are between 0-9, a-f, A-F + * @param Num - Memory location where nibble is to be stored + * + * @return + * XST_SUCCESS - Character converted to nibble + * XST_FAILURE - Invalid input character + * + * @note None. + * + *****************************************************************************/ + +u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num) +{ + u32 Status; + + /* Convert the char to nibble */ + if ((InChar >= (u8)'0') && (InChar <= (u8)'9')) { + *Num = InChar - (u8)'0'; + Status = XST_SUCCESS; + } + else if ((InChar >= (u8)'a') && (InChar <= (u8)'f')) { + *Num = InChar - (u8)'a' + 10U; + Status = XST_SUCCESS; + } + else if ((InChar >= (u8)'A') && (InChar <= (u8)'F')) { + *Num = InChar - (u8)'A' + 10U; + Status = XST_SUCCESS; + } + else { + Status = XST_FAILURE; + } + + return Status; +} + +/****************************************************************************/ +/* + * Converts the string into the equivalent Hex buffer. + * Ex: "abc123" -> {0xab, 0xc1, 0x23} + * + * @param Str - Pointer to string to be converted to Hex. + * Accepted characters in string are between 0-9, a-f and A-F + * @param Buf - Pointer to memory location where converted hex values are to + * be stored. + * @param Len - Length of input string + * + * @return + * XST_SUCCESS - Input string is converted to hex + * XST_FAILURE - Invalid character in inpit string + * + * @note None. + * + *****************************************************************************/ +u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len) +{ + u32 Status = XST_FAILURE; + u8 ConvertedLen = 0U, index = 0U; + u8 Nibble[MAX_NIBBLES] = {0U}; + u8 i; + + while (ConvertedLen < Len) { + for (i = 0U; i < MAX_NIBBLES; i++) { + Status = Xil_ConvertCharToNibble((u8)Str[ConvertedLen], + &Nibble[i]); + ConvertedLen = ConvertedLen +1U; + if (Status != XST_SUCCESS) { + /* Error converting char to nibble */ + goto END; + } + } + + buf[index] = (((u32)Nibble[0] << (u8)28U) | ((u32)Nibble[1] << (u8)24U) | + ((u32)Nibble[2] << (u8)20U) | ((u32)Nibble[3] << (u8)16U) | + ((u32)Nibble[4] << (u8)12U) | ((u32)Nibble[5] << (u8)8U) | + ((u32)Nibble[6] << (u8)4U) | (u32)Nibble[7]); + index++; + } +END: + return Status; +} + +/****************************************************************************/ +/* + * Waits for the event + * + * @param RegAddr - Address of register to be checked for event(s) occurrence + * @param EventMask - Mask indicating event(s) to be checked + * @param Event - Specific event(s) value to be checked + * @param Timeout - Max number of microseconds to wait for an event(s). + * + * @return + * XST_SUCCESS - On occurrence of the event(s). + * XST_FAILURE - Event did not occur before counter reaches 0 + * + * @note None. + * + *****************************************************************************/ +u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout) +{ + u32 EventStatus; + u32 PollCount = Timeout; + u32 Status = XST_FAILURE; + + while(PollCount > 0U) { + EventStatus = Xil_In32(RegAddr) & EventMask; + if (EventStatus == Event) { + Status = XST_SUCCESS; + break; + } + PollCount--; + usleep(1U); + } + + return Status; +} + + +/******************************************************************************/ +/** + * Waits for the events. Returns on occurrence of first event / timeout. + * + * @param EventsRegAddr - Address of register to be checked for event(s) + * occurrence + * @param EventsMask - Mask indicating event(s) to be checked + * @param WaitEvents - Specific event(s) to be checked + * @param Timeout - Max number of microseconds to wait for an event(s). + * @param Events - Mask of Events occurred returned in memory pointed by + * this variable + * + * @return + * XST_SUCCESS - On occurrence of the event(s). + * XST_FAILURE - Event did not occur before counter reaches 0 + * + ******************************************************************************/ +u32 Xil_WaitForEvents(u32 EventsRegAddr, u32 EventsMask, u32 WaitEvents, + u32 Timeout, u32* Events) +{ + u32 EventStatus; + u32 PollCount = Timeout; + u32 Status = XST_TIMEOUT; + + *Events = 0x00; + do { + EventStatus = Xil_In32(EventsRegAddr); + EventStatus &= EventsMask; + if((EventStatus & WaitEvents) != 0U) { + Status = XST_SUCCESS; + *Events = EventStatus; + break; + } + PollCount--; + usleep(1U); + } + while(PollCount > 0U); + + return Status; +} + +/******************************************************************************/ +/** + * Checks whether the passed character is a valid hex digit + * + * @param Ch - Pointer to the input character + * + * @return + * XST_SUCCESS - on valid hex digit + * XST_FAILURE - on invalid hex digit + * + * @note None. + * + ******************************************************************************/ +u32 Xil_IsValidHexChar(const char *Ch) +{ + u32 Status = XST_FAILURE; + + if(NULL == Ch) { + goto END; + } + if (((*Ch >= '0') && (*Ch <='9'))|| + ((*Ch >= 'a') && (*Ch <='f'))|| + ((*Ch >= 'A') && (*Ch <='F'))) { + + Status = XST_SUCCESS; + } +END: + return Status; +} + +/******************************************************************************/ +/** + * Validate the input string contains only hexadecimal characters + * + * @param HexStr - Pointer to string to be validated + * + * @return + * XST_SUCCESS - On valid input hex string + * XST_INVALID_PARAM - On invalid length of the input string + * XST_FAILURE - On non hexadecimal character in string + * + * @note None + * + ******************************************************************************/ +u32 Xil_ValidateHexStr(const char *HexStr) +{ + u32 Idx; + u32 Len; + u32 Status = XST_INVALID_PARAM; + + if(NULL == HexStr) { + goto END; + } + + Len = Xil_Strnlen(HexStr, XIL_MAX_HEX_STR_LEN + 1U); + if (Len > XIL_MAX_HEX_STR_LEN) { + goto END; + } + + for (Idx = 0U; Idx < Len; Idx++) { + Status = Xil_IsValidHexChar(&HexStr[Idx]); + if (Status != XST_SUCCESS) { + break; + } + } + +END: + return Status; +} + +/****************************************************************************/ +/** + * Converts the string into the equivalent Hex buffer. + * Ex: "abc123" -> {0xab, 0xc1, 0x23} + * + * @param Str is a Input String. Will support the lower and upper case values. + * Value should be between 0-9, a-f and A-F + * @param Buf is Output buffer. + * @param Len of the input string. Should have even values + * + * @return + * - XST_SUCCESS no errors occurred. + * - XST_FAILURE an error when input parameters are not valid + * - an error when input buffer has invalid values + * + * TDD Test Cases: + * ---Initialization--- + * Len is odd + * Len is zero + * Str is NULL + * Buf is NULL + * ---Functionality--- + * Str input with only numbers + * Str input with All values in A-F + * Str input with All values in a-f + * Str input with values in a-f, 0-9, A-F + * Str input with values in a-z, 0-9, A-Z + * Boundary Cases + * Memory Bounds of buffer checking + * ****************************************************************************/ +u32 Xil_ConvertStringToHexBE(const char *Str, u8 *Buf, u32 Len) +{ + u32 ConvertedLen; + u8 LowerNibble = 0U; + u8 UpperNibble = 0U; + u32 Status = (u32)XST_FAILURE; + + if ((Str == NULL) || (Buf == NULL)) { + Status = (u32)XST_INVALID_PARAM; + goto END; + } + + if ((Len == 0U) || ((Len % XIL_SIZE_OF_BYTE_IN_BITS) != 0U)) { + Status = (u32)XST_INVALID_PARAM; + goto END; + } + + if(Len != (strlen(Str) * XIL_SIZE_OF_NIBBLE_IN_BITS)) { + Status = (u32)XST_INVALID_PARAM; + goto END; + } + + ConvertedLen = 0U; + while (ConvertedLen < (Len / XIL_SIZE_OF_NIBBLE_IN_BITS)) { + if ((Xil_ConvertCharToNibble(((u8)Str[ConvertedLen]),&UpperNibble) + == (u32)XST_SUCCESS) && (Xil_ConvertCharToNibble(((u8)Str[ConvertedLen+1U]), + &LowerNibble) == (u32)XST_SUCCESS)) { + Buf[ConvertedLen/2U] = + (UpperNibble << XIL_SIZE_OF_NIBBLE_IN_BITS) | + LowerNibble; + } + else { + Status = (u32)XST_INVALID_PARAM; + goto END; + } + ConvertedLen += 2U; + } + Status = (u32)XST_SUCCESS; +END: + return Status; +} + +/******************************************************************************/ +/** + * Converts the string into the equivalent Hex buffer. + * Ex: "abc123" -> {0x23, 0xc1, 0xab} + * + * @param Str - Input String to be converted to hex number in little + * endian format. Valid characters of input strin are between + * 0-9, a-f and A-F + * @param Buf - Pointer to memory location where converted hex numbers are to + * be stored. + * @param Len - Expected number of output bits + * + * @return + * XST_SUCCESS - Input string is converted to hex number(s) + * XST_FAILURE - Invalid input character detected in input string + * + * @note + * + ******************************************************************************/ +u32 Xil_ConvertStringToHexLE(const char *Str, u8 *Buf, u32 Len) +{ + u32 ConvertedLen; + u8 LowerNibble = 0U; + u8 UpperNibble = 0U; + u32 StrIndex; + u32 Status = XST_FAILURE; + + if ((NULL == Str) || (NULL == Buf)) { + Status = XST_INVALID_PARAM; + goto END; + } + + if ((Len == 0U) || ((Len % XIL_SIZE_OF_BYTE_IN_BITS) != 0U)) { + Status = XST_INVALID_PARAM; + goto END; + } + + if(Len != (strlen(Str) * XIL_SIZE_OF_NIBBLE_IN_BITS)) { + Status = XST_INVALID_PARAM; + goto END; + } + + StrIndex = (Len / XIL_SIZE_OF_BYTE_IN_BITS) - 1U; + ConvertedLen = 0U; + while (ConvertedLen < (Len / XIL_SIZE_OF_NIBBLE_IN_BITS)) { + if ((Xil_ConvertCharToNibble(((u8)Str[ConvertedLen]), + &UpperNibble) == XST_SUCCESS) && + (Xil_ConvertCharToNibble(((u8)Str[ConvertedLen + 1U]), + &LowerNibble) == XST_SUCCESS)) { + Buf[StrIndex] = + (UpperNibble << XIL_SIZE_OF_NIBBLE_IN_BITS) | + LowerNibble; + StrIndex = StrIndex - 1U; + } + else { + Status = XST_INVALID_PARAM; + goto END; + } + ConvertedLen += 2U; + } + + Status = XST_SUCCESS; +END: + return Status; +} + +/******************************************************************************/ +/** + * Returns the length of input string. + * + * @param Str - Input string + * @param MaxLen - Maximum expected length of the input string + * + * @return + * Returns length of the input string if length is less than MaxLen. + * Returns MaxLen if the length of the input string is >= MaxLen. + * + * @note + * + ******************************************************************************/ +u32 Xil_Strnlen(const char *Str, u32 MaxLen) +{ + const char *InStr = Str; + u32 StrLen = 0U; + + if (NULL == Str) { + goto END; + } + + while(StrLen < MaxLen) { + if ('\0' == *InStr) { + break; + } + StrLen++; + InStr++; + } + +END: + return StrLen; +} + +/*****************************************************************************/ +/** + * @brief This function will Read, Modify and Write to an address. + * + * @param Addr denotes Address + * @param Mask denotes the bits to be modified + * @param Value is the value to be written to the address + * + * @return None + * + *****************************************************************************/ +void Xil_UtilRMW32(u32 Addr, u32 Mask, u32 Value) +{ + u32 Val; + + Val = Xil_In32(Addr); + Val = (Val & (~Mask)) | (Mask & Value); + Xil_Out32(Addr, Val); +} + +/*****************************************************************************/ +/** + * @brief This functions copies source string to destination string. This + * function is a safe version of strcpy + * + * @param DestPtr is pointer to destination string + * @param SrcPtr is pointer to source string + * @param Size is the maximum number of bytes of the source string + * to be copied + * + * @return XST_SUCCESS on success and error code on failure + * + ******************************************************************************/ +int Xil_Strcpy(char *DestPtr, const char *SrcPtr, const u32 Size) +{ + int Status = XST_FAILURE; + u32 Count; + + if ((SrcPtr == NULL) || (DestPtr == NULL) || (Size == 0U)) { + goto END; + } + + for (Count = 0U; (SrcPtr[Count] != '\0') && (Count < Size); ++Count) { + DestPtr[Count] = SrcPtr[Count]; + } + if (Count == Size) { + DestPtr[0U] = '\0'; + goto END; + } + DestPtr[Count] = '\0'; + Status = XST_SUCCESS; + +END: + return Status; +} + +/****************************************************************************/ +/** + * @brief Copies specified range from source string to destination string + * + * @param Src is a pointer to source string + * @param Dest is a pointer to destination string + * @param From is 0 based index from where string copy starts + * @param To is 0 based index till which string is copied + * @param MaxSrcLen is the maximum length of source string + * @param MaxDstLen is the maximum length of destination string + * + * @return XST_SUCCESS on success + * XST_FAILURE on failure + * + * @note None + * + ****************************************************************************/ +int Xil_StrCpyRange(const u8 *Src, u8 *Dest, u32 From, u32 To, u32 MaxSrcLen, + u32 MaxDstLen) +{ + int Status = XST_FAILURE; + u32 SrcLength; + u32 Index; + + if ((Src == NULL) || (Dest == NULL)) { + Status = XST_INVALID_PARAM; + goto END; + } + + if ((To >= MaxSrcLen) || (To < From)) { + Status = XST_INVALID_PARAM; + goto END; + } + + if ((To - From + 1U) >= MaxDstLen) { + Status = XST_INVALID_PARAM; + goto END; + } + + SrcLength = Xil_Strnlen((const char *)Src, MaxSrcLen); + if (To >= SrcLength) { + Status = XST_INVALID_PARAM; + goto END; + } + + for (Index = From; (Index <= To) && (Src[Index]!= (u8)'\0'); Index++) { + Dest[Index - From] = Src[Index]; + } + + Dest[Index - From] = (u8)'\0'; + Status = XST_SUCCESS; + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function appends string2 to string1. This function is a safe + * version of strcat + * + * @param Str1Ptr is pointer to string1 + * @param Str2Ptr is pointer to string2 + * @param Size is the maximum number of bytes Str1 can hold + * + * @return XST_SUCCESS on success and error code on failure + * + ******************************************************************************/ +int Xil_Strcat(char* Str1Ptr, const char* Str2Ptr, const u32 Size) +{ + int Status = XST_FAILURE; + u32 Count = 0U; + u32 CountTmp = 0U; + + if ((Str1Ptr == NULL) || (Str2Ptr == NULL) || (Size == 0U)) { + goto END; + } + + while ((Count < Size) && (Str1Ptr[Count] != '\0')) { + Count++; + } + + while ((Str2Ptr[CountTmp] != '\0') && (Count < Size)) { + Str1Ptr[Count] = Str2Ptr[CountTmp]; + Count++; + CountTmp++; + } + if (Count == Size) { + Str1Ptr[0U] = '\0'; + goto END; + } + Str1Ptr[Count] = '\0'; + Status = XST_SUCCESS; + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function copies Len bytes from source memory to destination + * memory. If Len is greater than DestPtrLen, then DestPtr is also + * filled with 0s till DestPtrLen bytes and is considered as a failure. + * This function is a secure implementation of memcpy + * + * @param DestPtr is pointer to destination address + * @param DestPtrLen is the memory alloted to the destination buffer + * @param SrcPtr is pointer to source address + * @param Len is number of bytes to be copied + * + * @return XST_SUCCESS on success and error code on failure + * + ******************************************************************************/ +int Xil_SecureMemCpy(void * DestPtr, u32 DestPtrLen, const void * SrcPtr, u32 Len) +{ + int Status = XST_FAILURE; + u8 *Dest = (u8 *)DestPtr; + const u8 *Src = (const u8 *)SrcPtr; + + if ((DestPtr == NULL) || (SrcPtr == NULL)) { + goto END; + } + + if (Len > DestPtrLen) { + while (DestPtrLen != 0U) { + *Dest = 0U; + Dest++; + DestPtrLen--; + } + goto END; + } + + /* Loop and copy. */ + while (Len != 0U) { + *Dest = *Src; + Dest++; + Src++; + Len--; + } + Status = XST_SUCCESS; + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function compares Len bytes from memory1 and memory2. This + * function is a secure implementation of memcmp + * + * @param Buf1Ptr is pointer to memory1 + * @param Buf2Ptr is pointer to memory2 + * @param Len is number of byets to be compared + * + * @return 0 if contents of both the memory regions are same, + * -1 if first non-matching character has lower value in Buf1Ptr + * 1 if first non-matching character is greater value in Buf1Ptr + * + ******************************************************************************/ +int Xil_MemCmp(const void * Buf1Ptr, const void * Buf2Ptr, u32 Len) +{ + volatile int RetVal = 1; + const u8 *Buf1 = Buf1Ptr; + const u8 *Buf2 = Buf2Ptr; + u32 Size = Len; + + /* Assert validates the input arguments */ + if ((Buf1 == NULL) || (Buf2 == NULL) || (Len == 0x0U)) { + goto END; + } + + /* Loop and compare */ + while (Size != 0U) { + if (*Buf1 > *Buf2) { + RetVal = 1; + goto END; + } else if (*Buf1 < *Buf2) { + RetVal = -1; + goto END; + } else { + Buf1++; + Buf2++; + Size--; + } + } + + /* Make sure size is zero to know the whole of data is compared */ + if (Size == 0U) { + RetVal = 0; + } + +END: + return RetVal; +} + +/*****************************************************************************/ +/** + * @brief This function is used to zeroize the memory + * + * @param DataPtr Pointer to the memory which need to be zeroized. + * @param Length Length of the data in bytes. + * + * @return + * - XST_SUCCESS: If Zeroization is successful. + * - XST_FAILURE: If Zeroization is not successful. + ********************************************************************************/ +int Xil_SecureZeroize(u8 *DataPtr, const u32 Length) +{ + u32 Index; + int Status = XST_FAILURE; + + /* Clear the data */ + (void)memset(DataPtr, 0, Length); + + /* Read it back to verify */ + for (Index = 0U; Index < Length; Index++) { + if (DataPtr[Index] != 0x00U) { + goto END; + } + } + if (Index == Length) { + Status = XST_SUCCESS; + } + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function compares two memory regions for specified number + * of bytes. This function takes size of two memory regions to + * make sure not to read from or write to out of bound memory + * region. + * + * @param Src1 - Pointer to first memory range + * @param Src1Size - Maximum size of first memory range + * @param Src2 - Pointer to second memory range + * @param Src2Size - Maximum size of second memory range + * @param CmpLen - Number of bytes to be compared + * + * @return + * XST_SUCCESS - If specified number of bytes matches + * XST_FAILURE - If there is a mistmatch found during comparison + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SMemCmp(const void *Src1, const u32 Src1Size, + const void *Src2, const u32 Src2Size, const u32 CmpLen) +{ + int Status = XST_FAILURE; + + if ((Src1 == NULL) || (Src2 == NULL)) { + Status = XST_INVALID_PARAM; + } + else if ((CmpLen == 0U) || (Src1Size < CmpLen) || (Src2Size < CmpLen)) { + Status = XST_INVALID_PARAM; + } + else { + Status = memcmp (Src1, Src2, CmpLen); + if (Status != 0) { + Status = XST_FAILURE; + } + } + + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function compares two memory regions for specified number + * of bytes. This function takes size of two memory regions to + * make sure not to read from or write to out of bound memory + * region. + * Note that this function compares till end to make it execute + * in constant time irrespective of the content of input memory. + * + * @param Src1 - Pointer to first memory range + * @param Src1Size - Maximum size of first memory range + * @param Src2 - Pointer to second memory range + * @param Src2Size - Maximum size of second memory range + * @param CmpLen - Number of bytes to be compared + * + * @return + * XST_SUCCESS - If specified number of bytes matches + * XST_FAILURE - If mistmatch + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SMemCmp_CT(const void *Src1, const u32 Src1Size, + const void *Src2, const u32 Src2Size, const u32 CmpLen) +{ + volatile int Status = XST_FAILURE; + volatile int StatusRedundant = XST_FAILURE; + volatile u32 Data = 0U; + volatile u32 DataRedundant = 0xFFFFFFFFU; + u32 Cnt = CmpLen; + const u8 *Src_1 = (const u8 *)Src1; + const u8 *Src_2 = (const u8 *)Src2; + + + if ((Src1 == NULL) || (Src2 == NULL)) { + Status = XST_INVALID_PARAM; + } + else if ((CmpLen == 0U) || (Src1Size < CmpLen) || (Src2Size < CmpLen)) { + Status = XST_INVALID_PARAM; + } + else { + while (Cnt >= sizeof(u32)) { + Data |= (*(const u32 *)Src_1 ^ *(const u32 *)Src_2); + DataRedundant &= ~Data; + Src_1 += sizeof(u32); + Src_2 += sizeof(u32); + Cnt -= sizeof(u32); + } + + while (Cnt > 0U) { + Data |= (u32)(*Src_1 ^ *Src_2); + DataRedundant &= ~Data; + Src_1++; + Src_2++; + Cnt--; + } + + if ((Data == 0U) && (DataRedundant == 0xFFFFFFFFU)) { + Status = XST_SUCCESS; + StatusRedundant = XST_SUCCESS; + } + } + + return (Status | StatusRedundant); +} + +/*****************************************************************************/ +/** + * @brief This is wrapper function to memcpy function. This function + * takes size of two memory regions to make sure not read from + * or write to out of bound memory region. + * + * @param Dest - Pointer to destination memory + * @param DestSize - Memory available at destination + * @param Src - Pointer to source memory + * @param SrcSize - Maximum data that can be copied from source + * @param CopyLen - Number of bytes to be copied + * + * @return + * XST_SUCCESS - Copy is successful + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SMemCpy(void *Dest, const u32 DestSize, + const void *Src, const u32 SrcSize, const u32 CopyLen) +{ + int Status = XST_FAILURE; + const u8 *Src8 = (const u8 *) Src; + const u8 *Dst8 = (u8 *) Dest; + void * volatile DestTemp = Dest; + const void * volatile SrcTemp = Src; + + if ((Dest == NULL) || (Src == NULL)) { + Status = XST_INVALID_PARAM; + } + else if ((CopyLen == 0U) || (DestSize < CopyLen) || (SrcSize < CopyLen)) { + Status = XST_INVALID_PARAM; + } + /* Return error for overlap string */ + else if ((Src8 < Dst8) && (&Src8[CopyLen - 1U] >= Dst8)) { + Status = XST_INVALID_PARAM; + } + else if ((Dst8 < Src8) && (&Dst8[CopyLen - 1U] >= Src8)) { + Status = XST_INVALID_PARAM; + } + else { + (void)memcpy(DestTemp, SrcTemp, CopyLen); + Status = XST_SUCCESS; + } + + return Status; +} + +/*****************************************************************************/ +/** + * @brief This is wrapper function to memset function. This function + * writes specified byte to destination specified number of times. + * This function also takes maximum string size that destination + * holds to make sure not to write out of bound area. + * + * @param Dest - Pointer to destination memory + * @param DestSize - Memory available at destination + * @param Data - Any value from 0 to 255 + * @param Len - Number of bytes to be copied + * + * @return + * XST_SUCCESS - Copy is successful + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SMemSet(void *Dest, const u32 DestSize, + const u8 Data, const u32 Len) +{ + int Status = XST_FAILURE; + + if ((Dest == NULL) || (DestSize < Len) || (Len == 0U)) { + Status = XST_INVALID_PARAM; + } + else { + (void)memset(Dest, (s32)Data, Len); + Status = XST_SUCCESS; + } + + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function concatenates two strings. This function + * takes size of both strings to make sure not to read from / + * write to out of bound area. + * + * @param DestStr - Pointer to destination string + * @param DestSize - Maximum string size that detination can hold + * @param SrcStr - Pointer to source string + * @param SrcSize - Maximum string size that source can hold + * + * @return + * XST_SUCCESS - Copy is successful + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SStrCat (u8 *DestStr, const u32 DestSize, + const u8 *SrcStr, const u32 SrcSize) +{ + int Status = XST_FAILURE; + u32 SrcLen; + u32 DstLen; + + if ((DestStr == NULL) || (SrcStr == NULL)) { + Status = XST_INVALID_PARAM; + goto END; + } + + SrcLen = strnlen((const char*)SrcStr, SrcSize); + DstLen = strnlen((const char*)DestStr, DestSize); + + if ((DestSize <= DstLen) || (SrcSize <= SrcLen)) { + Status = XST_INVALID_PARAM; + } + else if (DestSize <= (SrcLen + DstLen)) { + Status = XST_INVALID_PARAM; + } + else { + (void)strcat((char*)DestStr, (const char*)SrcStr); + Status = XST_SUCCESS; + } + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function compares two strings. It also takes maximum string + * size that Src1 and Src2 can hold to make sure not to read out of + * bound data for comparison. + * + * @param Str1 - Pointer to first string + * @param Str1Size - Maximum string size that Str1 can hold + * @param Str2 - Pointer to second string + * @param Str2Size - Maximum string size that Str2 can hold + * + * @return + * XST_SUCCESS - If both strings are same + * XST_FAILURE - If there is difference between two strings + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SStrCmp(const u8 *Str1, const u32 Str1Size, + const u8 *Str2, const u32 Str2Size) +{ + int Status = XST_FAILURE; + u32 Str1Len = 0U; + u32 Str2Len = 0U; + + if ((Str1 == NULL) || (Str2 == NULL)) { + Status = XST_INVALID_PARAM; + goto END; + } + + Str1Len = strnlen((const char*)Str1, Str1Size); + Str2Len = strnlen((const char*)Str2, Str2Size); + + if ((Str1Size <= Str1Len) || (Str2Size <= Str2Len)) { + Status = XST_INVALID_PARAM; + } + else if ((Str1Len < Str2Len) || (Str1Len > Str2Len)) { + Status = XST_FAILURE; + } + else { + Status = memcmp(Str1, Str2, Str1Len); + if (Status != 0) { + Status = XST_FAILURE; + } + } + +END: + return Status; +} + + +/*****************************************************************************/ +/** + * @brief This function compares two strings. It also takes maximum string + * size that Src1 and Src2 can hold to make sure not to read out of + * bound data for comparison. This function compares each character + * of the strings so that execution time of the function is not + * dependent on the content of two input strings. The execution + * time is constant when string size are same. + * + * @param Str1 - Pointer to first string + * @param Str1Size - Maximum string size that Str1 can hold + * @param Str2 - Pointer to second string + * @param Str2Size - Maximum string size that Str2 can hold + * + * @return + * XST_SUCCESS - If both strings are same + * XST_FAILURE - If there is difference between two strings + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SStrCmp_CT (const u8 *Str1, const u32 Str1Size, + const u8 *Str2, const u32 Str2Size) +{ + int Status = XST_FAILURE; + u32 Str1Len = 0U; + u32 Str2Len = 0U; + + if ((Str1 == NULL) || (Str2 == NULL)) { + Status = XST_INVALID_PARAM; + goto END; + } + + Str1Len = strnlen((const char*)Str1, Str1Size); + Str2Len = strnlen((const char*)Str2, Str2Size); + + if ((Str1Size <= Str1Len) || (Str2Size <= Str2Len)) { + Status = XST_INVALID_PARAM; + } + else if (Str1Len != Str2Len) { + Status = XST_FAILURE; + } + else { + Status = Xil_SMemCmp_CT (Str1, Str1Size, Str2, Str2Size, Str1Len); + } + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This function copies one string to other. This function + * takes size of both strings to make sure not to read from / + * write to out of bound area. + * + * @param DestStr - Pointer to destination string + * @param DestSize - Maximum string size that detination can hold + * @param SrcStr - Pointer to source string + * @param SrcSize - Maximum string size that source can hold + * + * @return + * XST_SUCCESS - Copy is successful + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SStrCpy(u8 *DestStr, const u32 DestSize, + const u8 *SrcStr, const u32 SrcSize) +{ + int Status = XST_FAILURE; + u32 SrcLen = 0U; + + if ((DestStr == NULL) || (SrcStr == NULL)) { + Status = XST_INVALID_PARAM; + goto END; + } + + SrcLen = strnlen((const char*)SrcStr, SrcSize); + + if ((DestSize <= SrcLen) || (SrcSize <= SrcLen)) { + Status = XST_INVALID_PARAM; + } + else { + (void)memcpy(DestStr, SrcStr, SrcLen + 1U); + Status = XST_SUCCESS; + } + +END: + return Status; +} + +/*****************************************************************************/ +/** + * @brief This is wrapper function to memmove function. This function + * takes size of two memory regions to avoid out of bound memory region. + * + * @param Dest - Pointer to destination memory + * @param DestSize - Memory available at destination + * @param Src - Pointer to source memory + * @param SrcSize - Maximum data that can be copied from source + * @param CopyLen - Number of bytes to be copied + * + * @return + * XST_SUCCESS - Copy is successful + * XST_INVALID_PARAM - Invalid inputs + * + *****************************************************************************/ +int Xil_SMemMove(void *Dest, const u32 DestSize, + const void *Src, const u32 SrcSize, const u32 CopyLen) +{ + volatile int Status = XST_FAILURE; + void *Output = NULL; + + if ((Dest == NULL) || (Src == NULL)) { + Status = XST_INVALID_PARAM; + } + else if ((CopyLen == 0U) || (DestSize < CopyLen) || (SrcSize < CopyLen)) { + Status = XST_INVALID_PARAM; + } + else { + Output = memmove(Dest, Src, CopyLen); + if (Output != NULL) { + Status = XST_SUCCESS; + } + } + + return Status; +} \ No newline at end of file diff --git a/arm/hal/lib/common/xil_util.h b/arm/hal/lib/common/xil_util.h new file mode 100644 index 0000000..c56d669 --- /dev/null +++ b/arm/hal/lib/common/xil_util.h @@ -0,0 +1,232 @@ +/******************************************************************************/ +/** +* Copyright (c) 2019 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* @file xil_util.h +* @addtogroup common_utilities Common Utility APIs +* @{ +* @details +* +* xil_util.h file contains xil utility functions declarations +* Except few functions, most of these functions are wrappers to standard functions. +* The standard string functions do not validate the input and that results into +* buffer overflows. To avoid it, the wrapper function validates the input and +* then passed to standard function. There are few constant time functions +* ( xxx_CT() ) which are used to compare the data in constant time. +* The constant time functions should be used while comparing secure data +* like password, keys which prevent disclosing of the data using +* timing analysis. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who      Date     Changes
+* ----- -------- -------- -----------------------------------------------
+* 6.4   mmd      04/21/19 First release.
+* 6.5   kal      02/29/20 Added Xil_ConvertStringToHexBE API
+* 7.3   kal      06/30/20 Converted Xil_Ceil macro to API
+*       rpo      08/19/20 Added function for read, modify and write
+*       bsv      08/21/20 Added XSECURE_TEMPORAL_CHECK macro to add
+*                         redundancy in security critical functions, to avoid
+*                         glitches from altering the return values of security
+*                         critical functions. The macro requires a label to be
+*                         passed to "go to" in case of error.
+*      kpt       09/03/20 Added XSECURE_TEMPORAL_IMPL macro for redundancy
+*      kal       09/22/20 Changed the param type from const char to const char*
+*                         to avoid copying key onto stack
+*      td        10/16/20 Added Xil_Strcpy, Xil_Strcat, Xil_SecureMemCpy and
+*                         Xil_MemCmp functions
+*      am        10/13/20 Resolved Coverity warning
+*      td        11/19/20 Updated XSECURE_TEMPORAL_CHECK and
+*                         XSECURE_TEMPORAL_IMPL to fix MISRA C Rule 15.3
+* 7.4  am        11/26/20 Added Xil_StrCpyRange function
+* 7.6  kpt       07/15/21 Added Xil_SecureZeroize function
+* 7.7  kpt       11/09/21 Added Xil_SMemCmp, Xil_SMemCmp_CT, Xil_SMemCpy,
+*                         Xil_SMemSet, Xil_SStrCat, Xil_SStrCmp, Xil_SStrCmp_CT
+*                         Xil_SStrCpy functions
+* 7.7	sk	 01/10/22 Update functions return type to fix misra_c_2012_
+* 			  directive_4_6 violations.
+*      mmd       02/28/22 Added Xil_SMemMove function prototype
+*
+* 
+* +*****************************************************************************/ + +#ifndef XIL_UTIL_H_ +#define XIL_UTIL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "xil_types.h" +#include "xil_io.h" +#include "xstatus.h" + +/*************************** Constant Definitions *****************************/ +#define XIL_SIZE_OF_NIBBLE_IN_BITS 4U +#define XIL_SIZE_OF_BYTE_IN_BITS 8U + +/* Maximum string length handled by Xil_ValidateHexStr function */ +#define XIL_MAX_HEX_STR_LEN 512U + + +/****************** Macros (Inline Functions) Definitions *********************/ +#ifdef __GNUC__ +/******************************************************************************/ +/** + * + * Updates the return value of the called function into Var and VarTmp variables + * for redundancy. This is to avoid glitches from altering the return values of + * security critical functions. + * + * @param Var is the variable which holds the return value of function + * executed + * @param VarTmp is the variable which holds the value stored in Var + * @param Function is the function to be executed + * @param Other params are arguments to the called function + * + * @return None + * + ******************************************************************************/ +#define XSECURE_TEMPORAL_IMPL(Var, VarTmp, Function, ...) \ + { \ + Var = XST_FAILURE; \ + VarTmp = XST_FAILURE; \ + Var = Function(__VA_ARGS__); \ + VarTmp = Var; \ + } + +/******************************************************************************/ +/** + * + * Adds redundancy while checking the status of the called function. + * This is to avoid glitches from altering the return values of security + * critical functions. The macro requires a label to be passed to "go to" + * in case of error. + * + * @param Label is the label defined in function and the control + * will jump to the label in case of XST_FAILURE + * @param Status is the variable which holds the return value of + * function executed + * @param Function is the function to be executed + * @param Other params are arguments to the called function + * + * @return None + * + ******************************************************************************/ +#define XSECURE_TEMPORAL_CHECK(Label, Status, Function, ...) \ + { \ + volatile int StatusTmp = XST_FAILURE; \ + XSECURE_TEMPORAL_IMPL(Status, StatusTmp, Function, __VA_ARGS__); \ + if ((Status != XST_SUCCESS) || \ + (StatusTmp != XST_SUCCESS)) { \ + Status |= StatusTmp;\ + goto Label; \ + } \ + } +#endif + +/*************************** Function Prototypes ******************************/ +/* Ceils the provided float value */ +s32 Xil_Ceil(float Value); + +/* Converts input character to nibble */ +u32 Xil_ConvertCharToNibble(u8 InChar, u8 *Num); + +/* Convert input hex string to array of 32-bits integers */ +u32 Xil_ConvertStringToHex(const char *Str, u32 *buf, u8 Len); + +/* Waits for specified event */ +u32 Xil_WaitForEvent(u32 RegAddr, u32 EventMask, u32 Event, u32 Timeout); + +/* Waits for specified events */ +u32 Xil_WaitForEvents(u32 EventsRegAddr, u32 EventsMask, u32 WaitEvents, + u32 Timeout, u32* Events); + +/* Validate input hex character */ +u32 Xil_IsValidHexChar(const char *Ch); + +/* Validate the input string contains only hexadecimal characters */ +u32 Xil_ValidateHexStr(const char *HexStr); + +/* Convert string to hex numbers in little enidian format */ +u32 Xil_ConvertStringToHexLE(const char *Str, u8 *Buf, u32 Len); + +/* Returns length of the input string */ +u32 Xil_Strnlen(const char *Str, u32 MaxLen); + +/* Convert string to hex numbers in big endian format */ +u32 Xil_ConvertStringToHexBE(const char * Str, u8 * Buf, u32 Len); + +/*Read, Modify and Write to an address*/ +void Xil_UtilRMW32(u32 Addr, u32 Mask, u32 Value); + +/* Copies source string to destination string */ +int Xil_Strcpy(char *DestPtr, const char *SrcPtr, const u32 Size); + +/* Copies specified range from source string to destination string */ +int Xil_StrCpyRange(const u8 *Src, u8 *Dest, u32 From, u32 To, u32 MaxSrcLen, + u32 MaxDstLen); + +/* Appends string2 to string1 */ +int Xil_Strcat(char* Str1Ptr, const char* Str2Ptr, const u32 Size); + +/* Copies Len bytes from source memory to destination memory */ +int Xil_SecureMemCpy(void * DestPtr, u32 DestPtrLen, const void * SrcPtr, u32 Len); + +/* Compares Len bytes from memory1 and memory2 */ +int Xil_MemCmp(const void * Buf1Ptr, const void * Buf2Ptr, u32 Len); + +/* Zeroizes the memory of given length */ +int Xil_SecureZeroize(u8 *DataPtr, const u32 Length); + +/* Copies Len bytes from source memory to destination memory */ +int Xil_SMemCpy (void *Dest, const u32 DestSize, + const void *Src, const u32 SrcSize, const u32 CopyLen); + +/* Copies Len bytes from source memory to destination memory, allows + overlapped memory between source and destination */ +int Xil_SMemMove(void *Dest, const u32 DestSize, + const void *Src, const u32 SrcSize, const u32 CopyLen); + +/* Compares Len bytes between source and destination memory */ +int Xil_SMemCmp (const void *Src1, const u32 Src1Size, + const void *Src2, const u32 Src2Size, const u32 CmpLen); + +/* Compares Len bytes between source and destination memory with constant time */ +int Xil_SMemCmp_CT (const void *Src1, const u32 Src1Size, + const void *Src2, const u32 Src2Size, const u32 CmpLen); + +/* Sets the destination memory of given length with given data */ +int Xil_SMemSet (void *Dest, const u32 DestSize, + const u8 Data, const u32 Len); + +/* Copies source string to destination string */ +int Xil_SStrCpy (u8 *DestStr, const u32 DestSize, + const u8 *SrcStr, const u32 SrcSize); + +/* Compares source string with destination string */ +int Xil_SStrCmp (const u8 *Str1, const u32 Str1Size, + const u8 *Str2, const u32 Str2Size); + +/* Compares source string with destination string with constant time */ +int Xil_SStrCmp_CT (const u8 *Str1, const u32 Str1Size, + const u8 *Str2, const u32 Str2Size); + +/* Concatenates source string to destination string */ +int Xil_SStrCat (u8 *DestStr, const u32 DestSize, + const u8 *SrcStr, const u32 SrcSize); + +#ifdef __cplusplus +} +#endif + +#endif /* XIL_UTIL_H_ */ +/** +* @} End of "addtogroup common_utilities". +*/ diff --git a/arm/hal/lib/common/xplatform_info.c b/arm/hal/lib/common/xplatform_info.c new file mode 100644 index 0000000..e1b4e55 --- /dev/null +++ b/arm/hal/lib/common/xplatform_info.c @@ -0,0 +1,147 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xplatform_info.c +* @addtogroup common_platform_info Hardware Platform Information +* @{ +* This file contains information about hardware for which the code is built +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 5.00  pkp  12/15/14 Initial release
+* 5.04  pkp  01/12/16 Added platform information support for Cortex-A53 32bit
+*					  mode
+* 6.00  mus  17/08/16 Removed unused variable from XGetPlatform_Info
+* 6.4   ms   05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
+*                     function for PMUFW.
+*       ms   06/13/17 Added PSU_PMU macro to provide support of
+*                     XGetPlatform_Info function for PMUFW.
+*       mus  08/17/17 Add EL1 NS mode support for
+*                     XGet_Zynq_UltraMp_Platform_info and XGetPSVersion_Info
+*                     APIs.
+* 7.0	aru 03/15/19  Check for versal before aarch64 and armr5
+*		      in XGetPlatform_Info()
+* 7.2   adk 08/01/20  Added versal support for the XGetPSVersion_Info function.
+* 7.6   mus 08/23/21  Updated prototypes for functions which are not taking any
+*                     arguments with void keyword. This has been done to fix
+*                     compilation warnings with "-Wstrict-prototypes" flag.
+*                     It fixes CR#1108601.
+* 7.6    mus 08/30/21 Updated flag checking to fix compilation warnings
+*                     reported with "-Wundef" flag. It fixes CR#1108601.
+
+* 7.7    mus 11/02/21 Updated XGet_Zynq_UltraMp_Platform_info and
+*                     XGetPSVersion_Info to fix compilation warning
+*                     reported with "-Wundef" flag CR#1111453
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_io.h" +#include "xplatform_info.h" +#if defined (__aarch64__) +#include "bspconfig.h" +#include "xil_smc.h" +#endif +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Variable Definitions *****************************/ + + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/** +* +* @brief This API is used to provide information about platform +* +* @return The information about platform defined in xplatform_info.h +* +******************************************************************************/ +u32 XGetPlatform_Info(void) +{ +#if defined (versal) + return XPLAT_VERSAL; +#elif defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) || defined (PSU_PMU) + return XPLAT_ZYNQ_ULTRA_MP; +#elif defined (__microblaze__) + return XPLAT_MICROBLAZE; +#else + return XPLAT_ZYNQ; +#endif +} + +/*****************************************************************************/ +/** +* +* @brief This API is used to provide information about zynq ultrascale MP platform +* +* @return The information about zynq ultrascale MP platform defined in +* xplatform_info.h +* +******************************************************************************/ +#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) +u32 XGet_Zynq_UltraMp_Platform_info(void) +{ +#if defined (__aarch64__) && (EL1_NONSECURE == 1) + XSmc_OutVar reg; + /* + * This SMC call will return, + * idcode - upper 32 bits of reg.Arg0 + * version - lower 32 bits of reg.Arg1 + */ + reg = Xil_Smc(GET_CHIPID_SMC_FID,0,0, 0, 0, 0, 0, 0); + return (u32)((reg.Arg1 >> XPLAT_INFO_SHIFT) & XPLAT_INFO_MASK); +#else + u32 reg; + reg = ((Xil_In32(XPLAT_PS_VERSION_ADDRESS) >> XPLAT_INFO_SHIFT ) + & XPLAT_INFO_MASK); + return reg; +#endif +} +#endif + +/*****************************************************************************/ +/** +* +* @brief This API is used to provide information about PS Silicon version +* +* @return The information about PS Silicon version. +* +******************************************************************************/ +#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) || defined (PSU_PMU) || defined (versal) +u32 XGetPSVersion_Info(void) +{ +#if defined (__aarch64__) && (EL1_NONSECURE == 1) + /* + * This SMC call will return, + * idcode - upper 32 bits of reg.Arg0 + * version - lower 32 bits of reg.Arg1 + */ + XSmc_OutVar reg; + reg = Xil_Smc(GET_CHIPID_SMC_FID,0,0, 0, 0, 0, 0, 0); + return (u32)((reg.Arg1 & XPS_VERSION_INFO_MASK) >> + XPS_VERSION_INFO_SHIFT); +#else + u32 reg; + reg = (Xil_In32(XPLAT_PS_VERSION_ADDRESS) + & XPS_VERSION_INFO_MASK); + return (reg >> XPS_VERSION_INFO_SHIFT); +#endif +} +#endif +/** @} */ diff --git a/arm/hal/lib/common/xplatform_info.h b/arm/hal/lib/common/xplatform_info.h new file mode 100644 index 0000000..933a69a --- /dev/null +++ b/arm/hal/lib/common/xplatform_info.h @@ -0,0 +1,115 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xplatform_info.h +* +* +* @addtogroup common_platform_info APIs to Get Platform Information +* +* +* The xplatform_info.h file contains definitions for various available Xilinx® +* platforms. Also, it contains prototype of APIs, which can be used to get the +* platform information. +* +* @{ +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date    Changes
+* ----- ---- --------- -------------------------------------------------------
+* 6.4    ms   05/23/17 Added PSU_PMU macro to support XGetPSVersion_Info
+*                      function for PMUFW.
+* 7.2    adk  08/01/20 Added versal support for the XGetPSVersion_Info function.
+* 7.6    mus  08/23/21 Updated prototypes for functions which are not taking any
+*                      arguments with void keyword. This has been done to fix
+*                      compilation warnings with "-Wstrict-prototypes" flag.
+*                      It fixes CR#1108601.
+* 7.6    mus  08/30/21 Updated flag checking to fix compilation warnings
+*                      reported with "-Wundef" flag.
+* 7.7	 sk   01/10/22 Update XPLAT_INFO_MASK from signed to unsigned to fix
+*		       misra_c_2012_rule_10_4 violation.
+* 
+* +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XPLATFORM_INFO_H /* prevent circular inclusions */ +#define XPLATFORM_INFO_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" + +/************************** Constant Definitions *****************************/ +#if defined (versal) +#define XPAR_PMC_TAP_BASEADDR 0xF11A0000U +#define XPAR_PMC_TAP_VERSION_OFFSET 0x00000004U +#define XPLAT_PS_VERSION_ADDRESS (XPAR_PMC_TAP_BASEADDR + \ + XPAR_PMC_TAP_VERSION_OFFSET) +#else +#define XPAR_CSU_BASEADDR 0xFFCA0000U +#define XPAR_CSU_VER_OFFSET 0x00000044U +#define XPLAT_PS_VERSION_ADDRESS (XPAR_CSU_BASEADDR + \ + XPAR_CSU_VER_OFFSET) +#endif +#define XPLAT_ZYNQ_ULTRA_MP_SILICON 0x0 +#define XPLAT_ZYNQ_ULTRA_MP 0x1 +#define XPLAT_ZYNQ_ULTRA_MPVEL 0x2 +#define XPLAT_ZYNQ_ULTRA_MPQEMU 0x3 +#define XPLAT_ZYNQ 0x4 +#define XPLAT_MICROBLAZE 0x5 +#define XPLAT_VERSAL 0x6U + +#define XPS_VERSION_1 0x0 +#define XPS_VERSION_2 0x1 +#define XPLAT_INFO_MASK (0xFU) + +#if defined (versal) +#define XPS_VERSION_INFO_MASK 0xFF00U +#define XPS_VERSION_INFO_SHIFT 0x8U +#define XPLAT_INFO_SHIFT 0x18U +#else +#define XPS_VERSION_INFO_MASK (0xF) +#define XPS_VERSION_INFO_SHIFT 0x0U +#define XPLAT_INFO_SHIFT 0xCU +#endif + +/**************************** Type Definitions *******************************/ +/** + *@endcond + */ +/***************** Macros (Inline Functions) Definitions *********************/ + + +u32 XGetPlatform_Info(void); + +#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) || defined (PSU_PMU) || defined (versal) +u32 XGetPSVersion_Info(void); +#endif + +#if defined (ARMR5) || defined (__aarch64__) || defined (ARMA53_32) +u32 XGet_Zynq_UltraMp_Platform_info(void); +#endif +/************************** Function Prototypes ******************************/ + + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ +/** +* @} End of "addtogroup common_platform_info". +*/ diff --git a/arm/hal/lib/common/xstatus.h b/arm/hal/lib/common/xstatus.h new file mode 100644 index 0000000..1e9e6fb --- /dev/null +++ b/arm/hal/lib/common/xstatus.h @@ -0,0 +1,522 @@ +/****************************************************************************** +* Copyright (c) 2002 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xstatus.h +* +* @addtogroup common_status_codes Xilinx software status codes +* +* The xstatus.h file contains the Xilinx software status codes.These codes are +* used throughout the Xilinx device drivers. +* +* @{ +******************************************************************************/ + +/** + *@cond nocomments + */ + +#ifndef XSTATUS_H /* prevent circular inclusions */ +#define XSTATUS_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files *********************************/ + +#include "xil_types.h" +#include "xil_assert.h" + +/************************** Constant Definitions *****************************/ + +/*********************** Common statuses 0 - 500 *****************************/ +/** +@name Common Status Codes for All Device Drivers +@{ +*/ +#define XST_SUCCESS 0L +#define XST_FAILURE 1L +#define XST_DEVICE_NOT_FOUND 2L +#define XST_DEVICE_BLOCK_NOT_FOUND 3L +#define XST_INVALID_VERSION 4L +#define XST_DEVICE_IS_STARTED 5L +#define XST_DEVICE_IS_STOPPED 6L +#define XST_FIFO_ERROR 7L /*!< An error occurred during an + operation with a FIFO such as + an underrun or overrun, this + error requires the device to + be reset */ +#define XST_RESET_ERROR 8L /*!< An error occurred which requires + the device to be reset */ +#define XST_DMA_ERROR 9L /*!< A DMA error occurred, this error + typically requires the device + using the DMA to be reset */ +#define XST_NOT_POLLED 10L /*!< The device is not configured for + polled mode operation */ +#define XST_FIFO_NO_ROOM 11L /*!< A FIFO did not have room to put + the specified data into */ +#define XST_BUFFER_TOO_SMALL 12L /*!< The buffer is not large enough + to hold the expected data */ +#define XST_NO_DATA 13L /*!< There was no data available */ +#define XST_REGISTER_ERROR 14L /*!< A register did not contain the + expected value */ +#define XST_INVALID_PARAM 15L /*!< An invalid parameter was passed + into the function */ +#define XST_NOT_SGDMA 16L /*!< The device is not configured for + scatter-gather DMA operation */ +#define XST_LOOPBACK_ERROR 17L /*!< A loopback test failed */ +#define XST_NO_CALLBACK 18L /*!< A callback has not yet been + registered */ +#define XST_NO_FEATURE 19L /*!< Device is not configured with + the requested feature */ +#define XST_NOT_INTERRUPT 20L /*!< Device is not configured for + interrupt mode operation */ +#define XST_DEVICE_BUSY 21L /*!< Device is busy */ +#define XST_ERROR_COUNT_MAX 22L /*!< The error counters of a device + have maxed out */ +#define XST_IS_STARTED 23L /*!< Used when part of device is + already started i.e. + sub channel */ +#define XST_IS_STOPPED 24L /*!< Used when part of device is + already stopped i.e. + sub channel */ +#define XST_DATA_LOST 26L /*!< Driver defined error */ +#define XST_RECV_ERROR 27L /*!< Generic receive error */ +#define XST_SEND_ERROR 28L /*!< Generic transmit error */ +#define XST_NOT_ENABLED 29L /*!< A requested service is not + available because it has not + been enabled */ +#define XST_NO_ACCESS 30L /* Generic access error */ +#define XST_TIMEOUT 31L /*!< Event timeout occurred */ + +/** @} */ +/***************** Utility Component statuses 401 - 500 *********************/ +/** +@name Utility Component Status Codes 401 - 500 +@{ +*/ +#define XST_MEMTEST_FAILED 401L /*!< Memory test failed */ + +/** @} */ +/***************** Common Components statuses 501 - 1000 *********************/ +/** +@name Packet Fifo Status Codes 501 - 510 +@{ +*/ +/********************* Packet Fifo statuses 501 - 510 ************************/ + +#define XST_PFIFO_LACK_OF_DATA 501L /*!< Not enough data in FIFO */ +#define XST_PFIFO_NO_ROOM 502L /*!< Not enough room in FIFO */ +#define XST_PFIFO_BAD_REG_VALUE 503L /*!< Self test, a register value + was invalid after reset */ +#define XST_PFIFO_ERROR 504L /*!< Generic packet FIFO error */ +#define XST_PFIFO_DEADLOCK 505L /*!< Packet FIFO is reporting + * empty and full simultaneously + */ +/** @} */ +/** +@name DMA Status Codes 511 - 530 +@{ +*/ +/************************** DMA statuses 511 - 530 ***************************/ + +#define XST_DMA_TRANSFER_ERROR 511L /*!< Self test, DMA transfer + failed */ +#define XST_DMA_RESET_REGISTER_ERROR 512L /*!< Self test, a register value + was invalid after reset */ +#define XST_DMA_SG_LIST_EMPTY 513L /*!< Scatter gather list contains + no buffer descriptors ready + to be processed */ +#define XST_DMA_SG_IS_STARTED 514L /*!< Scatter gather not stopped */ +#define XST_DMA_SG_IS_STOPPED 515L /*!< Scatter gather not running */ +#define XST_DMA_SG_LIST_FULL 517L /*!< All the buffer descriptors of + the scatter gather list are + being used */ +#define XST_DMA_SG_BD_LOCKED 518L /*!< The scatter gather buffer + descriptor which is to be + copied over in the scatter + list is locked */ +#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /*!< No buffer descriptors have been + put into the scatter gather + list to be committed */ +#define XST_DMA_SG_COUNT_EXCEEDED 521L /*!< The packet count threshold + specified was larger than the + total # of buffer descriptors + in the scatter gather list */ +#define XST_DMA_SG_LIST_EXISTS 522L /*!< The scatter gather list has + already been created */ +#define XST_DMA_SG_NO_LIST 523L /*!< No scatter gather list has + been created */ +#define XST_DMA_SG_BD_NOT_COMMITTED 524L /*!< The buffer descriptor which was + being started was not committed + to the list */ +#define XST_DMA_SG_NO_DATA 525L /*!< The buffer descriptor to start + has already been used by the + hardware so it can't be reused + */ +#define XST_DMA_SG_LIST_ERROR 526L /*!< General purpose list access + error */ +#define XST_DMA_BD_ERROR 527L /*!< General buffer descriptor + error */ +/** @} */ +/** +@name IPIF Status Codes Codes 531 - 550 +@{ +*/ +/************************** IPIF statuses 531 - 550 ***************************/ + +#define XST_IPIF_REG_WIDTH_ERROR 531L /*!< An invalid register width + was passed into the function */ +#define XST_IPIF_RESET_REGISTER_ERROR 532L /*!< The value of a register at + reset was not valid */ +#define XST_IPIF_DEVICE_STATUS_ERROR 533L /*!< A write to the device interrupt + status register did not read + back correctly */ +#define XST_IPIF_DEVICE_ACK_ERROR 534L /*!< The device interrupt status + register did not reset when + acked */ +#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /*!< The device interrupt enable + register was not updated when + other registers changed */ +#define XST_IPIF_IP_STATUS_ERROR 536L /*!< A write to the IP interrupt + status register did not read + back correctly */ +#define XST_IPIF_IP_ACK_ERROR 537L /*!< The IP interrupt status register + did not reset when acked */ +#define XST_IPIF_IP_ENABLE_ERROR 538L /*!< IP interrupt enable register was + not updated correctly when other + registers changed */ +#define XST_IPIF_DEVICE_PENDING_ERROR 539L /*!< The device interrupt pending + register did not indicate the + expected value */ +#define XST_IPIF_DEVICE_ID_ERROR 540L /*!< The device interrupt ID register + did not indicate the expected + value */ +#define XST_IPIF_ERROR 541L /*!< Generic ipif error */ +/** @} */ + +/****************** Device specific statuses 1001 - 4095 *********************/ +/** +@name Ethernet Status Codes 1001 - 1050 +@{ +*/ +/********************* Ethernet statuses 1001 - 1050 *************************/ + +#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /*!< Memory space is not big enough + * to hold the minimum number of + * buffers or descriptors */ +#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /*!< Memory allocation failed */ +#define XST_EMAC_MII_READ_ERROR 1003L /*!< MII read error */ +#define XST_EMAC_MII_BUSY 1004L /*!< An MII operation is in progress */ +#define XST_EMAC_OUT_OF_BUFFERS 1005L /*!< Driver is out of buffers */ +#define XST_EMAC_PARSE_ERROR 1006L /*!< Invalid driver init string */ +#define XST_EMAC_COLLISION_ERROR 1007L /*!< Excess deferral or late + * collision on polled send */ +/** @} */ +/** +@name UART Status Codes 1051 - 1075 +@{ +*/ +/*********************** UART statuses 1051 - 1075 ***************************/ +#define XST_UART + +#define XST_UART_INIT_ERROR 1051L +#define XST_UART_START_ERROR 1052L +#define XST_UART_CONFIG_ERROR 1053L +#define XST_UART_TEST_FAIL 1054L +#define XST_UART_BAUD_ERROR 1055L +#define XST_UART_BAUD_RANGE 1056L + +/** @} */ +/** +@name IIC Status Codes 1076 - 1100 +@{ +*/ +/************************ IIC statuses 1076 - 1100 ***************************/ + +#define XST_IIC_SELFTEST_FAILED 1076 /*!< self test failed */ +#define XST_IIC_BUS_BUSY 1077 /*!< bus found busy */ +#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /*!< mastersend attempted with */ + /* general call address */ +#define XST_IIC_STAND_REG_RESET_ERROR 1079 /*!< A non parameterizable reg */ + /* value after reset not valid */ +#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /*!< Tx fifo included in design */ + /* value after reset not valid */ +#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /*!< Rx fifo included in design */ + /* value after reset not valid */ +#define XST_IIC_TBA_REG_RESET_ERROR 1082 /*!< 10 bit addr incl in design */ + /* value after reset not valid */ +#define XST_IIC_CR_READBACK_ERROR 1083 /*!< Read of the control register */ + /* didn't return value written */ +#define XST_IIC_DTR_READBACK_ERROR 1084 /*!< Read of the data Tx reg */ + /* didn't return value written */ +#define XST_IIC_DRR_READBACK_ERROR 1085 /*!< Read of the data Receive reg */ + /* didn't return value written */ +#define XST_IIC_ADR_READBACK_ERROR 1086 /*!< Read of the data Tx reg */ + /* didn't return value written */ +#define XST_IIC_TBA_READBACK_ERROR 1087 /*!< Read of the 10 bit addr reg */ + /* didn't return written value */ +#define XST_IIC_NOT_SLAVE 1088 /*!< The device isn't a slave */ +#define XST_IIC_ARB_LOST 1089 /*!< Arbitration lost for master */ +/** @} */ +/** +@name ATMC Status Codes 1101 - 1125 +@{ +*/ +/*********************** ATMC statuses 1101 - 1125 ***************************/ + +#define XST_ATMC_ERROR_COUNT_MAX 1101L /*!< the error counters in the ATM + controller hit the max value + which requires the statistics + to be cleared */ +/** @} */ +/** +@name Flash Status Codes 1126 - 1150 +@{ +*/ +/*********************** Flash statuses 1126 - 1150 **************************/ + +#define XST_FLASH_BUSY 1126L /*!< Flash is erasing or programming + */ +#define XST_FLASH_READY 1127L /*!< Flash is ready for commands */ +#define XST_FLASH_ERROR 1128L /*!< Flash had detected an internal + error. Use XFlash_DeviceControl + to retrieve device specific codes + */ +#define XST_FLASH_ERASE_SUSPENDED 1129L /*!< Flash is in suspended erase state + */ +#define XST_FLASH_WRITE_SUSPENDED 1130L /*!< Flash is in suspended write state + */ +#define XST_FLASH_PART_NOT_SUPPORTED 1131L /*!< Flash type not supported by + driver */ +#define XST_FLASH_NOT_SUPPORTED 1132L /*!< Operation not supported */ +#define XST_FLASH_TOO_MANY_REGIONS 1133L /*!< Too many erase regions */ +#define XST_FLASH_TIMEOUT_ERROR 1134L /*!< Programming or erase operation + aborted due to a timeout */ +#define XST_FLASH_ADDRESS_ERROR 1135L /*!< Accessed flash outside its + addressible range */ +#define XST_FLASH_ALIGNMENT_ERROR 1136L /*!< Write alignment error */ +#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /*!< Couldn't return immediately from + write/erase function with + XFL_NON_BLOCKING_WRITE/ERASE + option cleared */ +#define XST_FLASH_CFI_QUERY_ERROR 1138L /*!< Failed to query the device */ +/** @} */ +/** +@name SPI Status Codes 1151 - 1175 +@{ +*/ +/*********************** SPI statuses 1151 - 1175 ****************************/ + +#define XST_SPI_MODE_FAULT 1151 /*!< master was selected as slave */ +#define XST_SPI_TRANSFER_DONE 1152 /*!< data transfer is complete */ +#define XST_SPI_TRANSMIT_UNDERRUN 1153 /*!< slave underruns transmit register */ +#define XST_SPI_RECEIVE_OVERRUN 1154 /*!< device overruns receive register */ +#define XST_SPI_NO_SLAVE 1155 /*!< no slave has been selected yet */ +#define XST_SPI_TOO_MANY_SLAVES 1156 /*!< more than one slave is being + * selected */ +#define XST_SPI_NOT_MASTER 1157 /*!< operation is valid only as master */ +#define XST_SPI_SLAVE_ONLY 1158 /*!< device is configured as slave-only + */ +#define XST_SPI_SLAVE_MODE_FAULT 1159 /*!< slave was selected while disabled */ +#define XST_SPI_SLAVE_MODE 1160 /*!< device has been addressed as slave */ +#define XST_SPI_RECEIVE_NOT_EMPTY 1161 /*!< device received data in slave mode */ + +#define XST_SPI_COMMAND_ERROR 1162 /*!< unrecognised command - qspi only */ +#define XST_SPI_POLL_DONE 1163 /*!< controller completed polling the + device for status */ +/** @} */ +/** +@name OPB Arbiter Status Codes 1176 - 1200 +@{ +*/ +/********************** OPB Arbiter statuses 1176 - 1200 *********************/ + +#define XST_OPBARB_INVALID_PRIORITY 1176 /*!< the priority registers have either + * one master assigned to two or more + * priorities, or one master not + * assigned to any priority + */ +#define XST_OPBARB_NOT_SUSPENDED 1177 /*!< an attempt was made to modify the + * priority levels without first + * suspending the use of priority + * levels + */ +#define XST_OPBARB_PARK_NOT_ENABLED 1178 /*!< bus parking by id was enabled but + * bus parking was not enabled + */ +#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /*!< the arbiter must be in fixed + * priority mode to allow the + * priorities to be changed + */ +/** @} */ +/** +@name INTC Status Codes 1201 - 1225 +@{ +*/ +/************************ Intc statuses 1201 - 1225 **************************/ + +#define XST_INTC_FAIL_SELFTEST 1201 /*!< self test failed */ +#define XST_INTC_CONNECT_ERROR 1202 /*!< interrupt already in use */ +/** @} */ +/** +@name TmrCtr Status Codes 1226 - 1250 +@{ +*/ +/********************** TmrCtr statuses 1226 - 1250 **************************/ + +#define XST_TMRCTR_TIMER_FAILED 1226 /*!< self test failed */ +/** @} */ +/** +@name WdtTb Status Codes 1251 - 1275 +@{ +*/ +/********************** WdtTb statuses 1251 - 1275 ***************************/ + +#define XST_WDTTB_TIMER_FAILED 1251L +/** @} */ +/** +@name PlbArb status Codes 1276 - 1300 +@{ +*/ +/********************** PlbArb statuses 1276 - 1300 **************************/ + +#define XST_PLBARB_FAIL_SELFTEST 1276L +/** @} */ +/** +@name Plb2Opb Status Codes 1301 - 1325 +@{ +*/ +/********************** Plb2Opb statuses 1301 - 1325 *************************/ + +#define XST_PLB2OPB_FAIL_SELFTEST 1301L +/** @} */ +/** +@name Opb2Plb Status 1326 - 1350 +@{ +*/ +/********************** Opb2Plb statuses 1326 - 1350 *************************/ + +#define XST_OPB2PLB_FAIL_SELFTEST 1326L +/** @} */ +/** +@name SysAce Status Codes 1351 - 1360 +@{ +*/ +/********************** SysAce statuses 1351 - 1360 **************************/ + +#define XST_SYSACE_NO_LOCK 1351L /*!< No MPU lock has been granted */ +/** @} */ +/** +@name PCI Bridge Status Codes 1361 - 1375 +@{ +*/ +/********************** PCI Bridge statuses 1361 - 1375 **********************/ + +#define XST_PCI_INVALID_ADDRESS 1361L +/** @} */ +/** +@name FlexRay Constants 1400 - 1409 +@{ +*/ +/********************** FlexRay constants 1400 - 1409 *************************/ + +#define XST_FR_TX_ERROR 1400 +#define XST_FR_TX_BUSY 1401 +#define XST_FR_BUF_LOCKED 1402 +#define XST_FR_NO_BUF 1403 +/** @} */ +/** +@name USB constants 1410 - 1420 +@{ +*/ +/****************** USB constants 1410 - 1420 *******************************/ + +#define XST_USB_ALREADY_CONFIGURED 1410 +#define XST_USB_BUF_ALIGN_ERROR 1411 +#define XST_USB_NO_DESC_AVAILABLE 1412 +#define XST_USB_BUF_TOO_BIG 1413 +#define XST_USB_NO_BUF 1414 +/** @} */ +/** +@name HWICAP constants 1421 - 1429 +@{ +*/ +/****************** HWICAP constants 1421 - 1429 *****************************/ + +#define XST_HWICAP_WRITE_DONE 1421 + +/** @} */ +/** +@name AXI VDMA constants 1430 - 1440 +@{ +*/ +/****************** AXI VDMA constants 1430 - 1440 *****************************/ + +#define XST_VDMA_MISMATCH_ERROR 1430 +/** @} */ +/** +@name NAND Flash Status Codes 1441 - 1459 +@{ +*/ +/*********************** NAND Flash statuses 1441 - 1459 *********************/ + +#define XST_NAND_BUSY 1441L /*!< Flash is erasing or + * programming + */ +#define XST_NAND_READY 1442L /*!< Flash is ready for commands + */ +#define XST_NAND_ERROR 1443L /*!< Flash had detected an + * internal error. + */ +#define XST_NAND_PART_NOT_SUPPORTED 1444L /*!< Flash type not supported by + * driver + */ +#define XST_NAND_OPT_NOT_SUPPORTED 1445L /*!< Operation not supported + */ +#define XST_NAND_TIMEOUT_ERROR 1446L /*!< Programming or erase + * operation aborted due to a + * timeout + */ +#define XST_NAND_ADDRESS_ERROR 1447L /*!< Accessed flash outside its + * addressible range + */ +#define XST_NAND_ALIGNMENT_ERROR 1448L /*!< Write alignment error + */ +#define XST_NAND_PARAM_PAGE_ERROR 1449L /*!< Failed to read parameter + * page of the device + */ +#define XST_NAND_CACHE_ERROR 1450L /*!< Flash page buffer error + */ + +#define XST_NAND_WRITE_PROTECTED 1451L /*!< Flash is write protected + */ +/** @} */ + +/**************************** Type Definitions *******************************/ + +typedef s32 XStatus; + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + +/** + *@endcond + */ + +/** +* @} End of "addtogroup common_status_codes". +*/ diff --git a/arm/hal/uart/Makefile b/arm/hal/uart/Makefile new file mode 100644 index 0000000..5feeb49 --- /dev/null +++ b/arm/hal/uart/Makefile @@ -0,0 +1,39 @@ +DRIVER_LIB_VERSION = 1.0 +COMPILER= +ARCHIVER= +CP=cp +COMPILER_FLAGS= +EXTRA_COMPILER_FLAGS= +LIB=libxil.a + +CC_FLAGS = $(COMPILER_FLAGS) +ECC_FLAGS = $(EXTRA_COMPILER_FLAGS) + +RELEASEDIR=../../../lib/ +INCLUDEDIR=../../../include/ +INCLUDES=-I./. -I$(INCLUDEDIR) + +SRCFILES:=$(wildcard *.c) + +OBJECTS = $(addprefix $(RELEASEDIR), $(addsuffix .o, $(basename $(wildcard *.c)))) + +libs: $(OBJECTS) + +DEPFILES := $(SRCFILES:%.c=$(RELEASEDIR)%.d) + +include $(wildcard $(DEPFILES)) + +include $(wildcard ../../../../dep.mk) + +$(RELEASEDIR)%.o: %.c + ${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) $(DEPENDENCY_FLAGS) $< -o $@ + +.PHONY: include +include: $(addprefix $(INCLUDEDIR),$(wildcard *.h)) + +$(INCLUDEDIR)%.h: %.h + $(CP) $< $@ + +clean: + rm -rf ${OBJECTS} + rm -rf $(DEPFILES) diff --git a/arm/hal/uart/xuartlite.c b/arm/hal/uart/xuartlite.c new file mode 100644 index 0000000..877ac9e --- /dev/null +++ b/arm/hal/uart/xuartlite.c @@ -0,0 +1,655 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite.c +* @addtogroup uartlite_v3_7 +* @{ +* +* Contains required functions for the XUartLite driver. See the xuartlite.h +* header file for more details on this driver. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
+* 1.00b rmm  05/13/03 Fixed diab compiler warnings relating to asserts
+* 1.01a jvb  12/13/05 Changed Initialize() into CfgInitialize(), and made
+*                     CfgInitialize() take a pointer to a config structure
+*                     instead of a device id. Moved Initialize() into
+*                     xgpio_sinit.c, and had Initialize() call CfgInitialize()
+*                     after it retrieved the config structure using the device
+*                     id. Removed include of xparameters.h along with any
+*                     dependencies on xparameters.h and the _g.c config table.
+* 1.01a wsy  05/08/06 fix CR220811 and CR224103.
+* 1.12a mta  03/31/07 Updated to new coding conventions
+* 1.13a sv   01/21/08 Updated driver to support access through DCR bus
+* 1.14a sdm  09/26/08 Updated code to avoid race condition in
+*		      XUartLite_SendBuffer
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. The macros have been
+*		      renamed to remove _m from the name. XUartLite_mClearStats
+*		      macro is removed and XUartLite_ClearStats function should
+*		      be used in its place.
+* 2.00a hvm  08/11/11 Removed the SetOptions related information in the
+*			Recv and RecvBuffer function header notes section.
+*			CR620849.
+* 2.01a adk  18/04/13 Updated the code to avoid unused variable
+*			 warnings when compiling with the -Wextra -Wall flags
+*			 In the file xuartlite.c. CR:704999.
+* 3.1	nsk  21/07/15 Updated XUartLite_ReceiveBuffer function to update the
+*		      receive data into user buffer in critical region.
+*		      CR#865787.
+* 3.2   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototype of XUartLite_CfgInitialize API.
+* 3.6   rna  02/19/21 Added 'XUartLite_GetSR' internal API to read Status
+*                     register and update the error stats.
+*
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartlite.h" +#include "xuartlite_i.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ +/************************** Function Prototypes *****************************/ + +static void StubHandler(void *CallBackRef, unsigned int ByteCount); + +/****************************************************************************/ +/** +* +* Initialize a XUartLite instance. The receive and transmit FIFOs of the +* UART are not flushed, so the user may want to flush them. The hardware +* device does not have any way to disable the receiver such that any valid +* data may be present in the receive FIFO. This function disables the UART +* interrupt. The baudrate and format of the data are fixed in the hardware +* at hardware build time. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param Config is a reference to a structure containing information +* about a specific UART Lite device. This function initializes an +* InstancePtr object for a specific device specified by the +* contents of Config. This function can initialize multiple +* instance objects with the use of multiple calls giving different +* Config information on each call. +* @param EffectiveAddr is the device base address in the virtual memory +* address space. The caller is responsible for keeping the address +* mapping from EffectiveAddr to the device physical base address +* unchanged once this function is invoked. Unexpected errors may +* occur if the address mapping changes after this function is +* called. If address translation is not used, use +* Config->BaseAddress for this parameters, passing the physical +* address instead. +* +* @return +* - XST_SUCCESS if everything starts up as expected. +* +* @note The Config pointer argument is not used by this function, +* but is provided to keep the function signature consistent +* with other drivers. +* +*****************************************************************************/ +int XUartLite_CfgInitialize(XUartLite *InstancePtr, XUartLite_Config *Config, + UINTPTR EffectiveAddr) +{ + (void) Config; + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Set some default values, including setting the callback + * handlers to stubs. + */ + InstancePtr->SendBuffer.NextBytePtr = NULL; + InstancePtr->SendBuffer.RemainingBytes = 0; + InstancePtr->SendBuffer.RequestedBytes = 0; + + InstancePtr->ReceiveBuffer.NextBytePtr = NULL; + InstancePtr->ReceiveBuffer.RemainingBytes = 0; + InstancePtr->ReceiveBuffer.RequestedBytes = 0; + + InstancePtr->IsReady = XIL_COMPONENT_IS_READY; + +#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0) + InstancePtr->RegBaseAddress = ((EffectiveAddr >> 2)) & 0xFFF; +#else + InstancePtr->RegBaseAddress = EffectiveAddr; +#endif + + InstancePtr->RecvHandler = StubHandler; + InstancePtr->SendHandler = StubHandler; + + /* Write to the control register to disable the interrupts, don't + * reset the FIFOs are the user may want the data that's present + */ + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, 0); + + /* + * Clear the statistics for this driver + */ + XUartLite_ClearStats(InstancePtr); + + return XST_SUCCESS; +} + +/****************************************************************************/ +/** +* +* This functions sends the specified buffer of data using the UART in either +* polled or interrupt driven modes. This function is non-blocking such that it +* will return before the data has been sent by the UART. If the UART is busy +* sending data, it will return and indicate zero bytes were sent. +* +* In a polled mode, this function will only send as much data as the UART can +* buffer in the FIFO. The application may need to call it repeatedly to +* send a buffer. +* +* In interrupt mode, this function will start sending the specified buffer and +* then the interrupt handler of the driver will continue sending data until the +* buffer has been sent. A callback function, as specified by the application, +* will be called to indicate the completion of sending the buffer. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param DataBufferPtr is pointer to a buffer of data to be sent. +* @param NumBytes contains the number of bytes to be sent. A value of +* zero will stop a previous send operation that is in progress +* in interrupt mode. Any data that was already put into the +* transmit FIFO will be sent. +* +* @return The number of bytes actually sent. +* +* @note The number of bytes is not asserted so that this function may +* be called with a value of zero to stop an operation that is +* already in progress. +* +******************************************************************************/ +unsigned int XUartLite_Send(XUartLite *InstancePtr, u8 *DataBufferPtr, + unsigned int NumBytes) +{ + unsigned int BytesSent; + u32 StatusRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(DataBufferPtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(((signed)NumBytes) >= 0); + + /* + * Enter a critical region by disabling the UART interrupts to allow + * this call to stop a previous operation that may be interrupt driven. + */ + StatusRegister = XUartLite_GetSR(InstancePtr); + + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, 0); + + /* + * Setup the specified buffer to be sent by setting the instance + * variables so it can be sent with polled or interrupt mode + */ + InstancePtr->SendBuffer.RequestedBytes = NumBytes; + InstancePtr->SendBuffer.RemainingBytes = NumBytes; + InstancePtr->SendBuffer.NextBytePtr = DataBufferPtr; + + /* + * Restore the interrupt enable register to it's previous value such + * that the critical region is exited. + * This is done here to minimize the amount of time the interrupt is + * disabled since there is only one interrupt and the receive could + * be filling up while interrupts are blocked. + */ + + StatusRegister &= XUL_CR_ENABLE_INTR; + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, StatusRegister); + + /* + * Send the buffer using the UART and return the number of bytes sent + */ + BytesSent = XUartLite_SendBuffer(InstancePtr); + + return BytesSent; +} + + +/****************************************************************************/ +/** +* +* This function will attempt to receive a specified number of bytes of data +* from the UART and store it into the specified buffer. This function is +* designed for either polled or interrupt driven modes. It is non-blocking +* such that it will return if no data has already received by the UART. +* +* In a polled mode, this function will only receive as much data as the UART +* can buffer in the FIFO. The application may need to call it repeatedly to +* receive a buffer. Polled mode is the default mode of operation for the driver. +* +* In interrupt mode, this function will start receiving and then the interrupt +* handler of the driver will continue receiving data until the buffer has been +* received. A callback function, as specified by the application, will be called +* to indicate the completion of receiving the buffer or when any receive errors +* or timeouts occur. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param DataBufferPtr is pointer to buffer for data to be received into. +* @param NumBytes is the number of bytes to be received. A value of zero +* will stop a previous receive operation that is in progress in +* interrupt mode. +* +* @return The number of bytes received. +* +* @note The number of bytes is not asserted so that this function +* may be called with a value of zero to stop an operation +* that is already in progress. +* +*****************************************************************************/ +unsigned int XUartLite_Recv(XUartLite *InstancePtr, u8 *DataBufferPtr, + unsigned int NumBytes) +{ + unsigned int ReceivedCount; + u32 StatusRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(DataBufferPtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + Xil_AssertNonvoid(((signed)NumBytes) >= 0); + + /* + * Enter a critical region by disabling all the UART interrupts to allow + * this call to stop a previous operation that may be interrupt driven + */ + StatusRegister = XUartLite_GetSR(InstancePtr); + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, 0); + + /* + * Setup the specified buffer to be received by setting the instance + * variables so it can be received with polled or interrupt mode + */ + InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes; + InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes; + InstancePtr->ReceiveBuffer.NextBytePtr = DataBufferPtr; + + /* + * Restore the interrupt enable register to it's previous value such + * that the critical region is exited + */ + StatusRegister &= XUL_CR_ENABLE_INTR; + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, StatusRegister); + + /* + * Receive the data from the UART and return the number of bytes + * received + * This is done here to minimize the amount of time the interrupt is + * disabled since there is only one interrupt and the transmit could + * be emptying out while interrupts are blocked. + */ + ReceivedCount = XUartLite_ReceiveBuffer(InstancePtr); + + return ReceivedCount; + +} + +/****************************************************************************/ +/** +* +* This function resets the FIFOs, both transmit and receive, of the UART such +* that they are emptied. Since the UART does not have any way to disable it +* from receiving data, it may be necessary for the application to reset the +* FIFOs to get rid of any unwanted data. +* +* @param InstancePtr is a pointer to the XUartLite instance . +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartLite_ResetFifos(XUartLite *InstancePtr) +{ + u32 Register; + + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Read the status register 1st such that the next write to the control + * register won't destroy the state of the interrupt enable bit + */ + Register = XUartLite_ReadReg(InstancePtr->RegBaseAddress, + XUL_STATUS_REG_OFFSET); + + /* + * Mask off the interrupt enable bit to maintain it's state. + */ + Register &= XUL_SR_INTR_ENABLED; + + /* + * Write to the control register to reset both FIFOs, these bits are + * self-clearing such that there's no need to clear them + */ + XUartLite_WriteReg(InstancePtr->RegBaseAddress, XUL_CONTROL_REG_OFFSET, + Register | XUL_CR_FIFO_TX_RESET | XUL_CR_FIFO_RX_RESET); +} + +/****************************************************************************/ +/** +* +* This function determines if the specified UART is sending data. If the +* transmitter register is not empty, it is sending data. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return A value of TRUE if the UART is sending data, otherwise FALSE. +* +* @note None. +* +*****************************************************************************/ +int XUartLite_IsSending(XUartLite *InstancePtr) +{ + u32 StatusRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Read the status register to determine if the transmitter is empty + */ + StatusRegister = XUartLite_ReadReg(InstancePtr->RegBaseAddress, + XUL_STATUS_REG_OFFSET); + + /* + * If the transmitter is not empty then indicate that the UART is still + * sending some data + */ + return ((StatusRegister & XUL_SR_TX_FIFO_EMPTY) == 0); +} + + +/**************************************************************************** +* +* This function provides a stub handler such that if the application does not +* define a handler but enables interrupts, this function will be called. +* +* @param CallBackRef has no purpose but is necessary to match the +* interface for a handler. +* @param ByteCount has no purpose but is necessary to match the +* interface for a handler. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void StubHandler(void *CallBackRef, unsigned int ByteCount) +{ + (void) CallBackRef; + (void) ByteCount; + /* + * Assert occurs always since this is a stub and should never be called + */ + Xil_AssertVoidAlways(); +} + + +/****************************************************************************/ +/** +* +* This function sends a buffer that has been previously specified by setting +* up the instance variables of the instance. This function is designed to be +* an internal function for the XUartLite component such that it may be called +* from a shell function that sets up the buffer or from an interrupt handler. +* +* This function sends the specified buffer of data to the UART in either +* polled or interrupt driven modes. This function is non-blocking such that +* it will return before the data has been sent by the UART. +* +* In a polled mode, this function will only send as much data as the UART can +* buffer, either in the transmitter or in the FIFO if present and enabled. +* The application may need to call it repeatedly to send a buffer. +* +* In interrupt mode, this function will start sending the specified buffer and +* then the interrupt handler of the driver will continue until the buffer +* has been sent. A callback function, as specified by the application, will +* be called to indicate the completion of sending the buffer. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return NumBytes is the number of bytes actually sent (put into the +* UART transmitter and/or FIFO). +* +* @note None. +* +*****************************************************************************/ +unsigned int XUartLite_SendBuffer(XUartLite *InstancePtr) +{ + unsigned int SentCount = 0; + u8 StatusRegister; + u8 IntrEnableStatus; + + /* + * Read the status register to determine if the transmitter is full + */ + StatusRegister = XUartLite_GetSR(InstancePtr); + + /* + * Enter a critical region by disabling all the UART interrupts to allow + * this call to stop a previous operation that may be interrupt driven + */ + StatusRegister = XUartLite_GetSR(InstancePtr); + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, 0); + + /* + * Save the status register contents to restore the interrupt enable + * register to it's previous value when that the critical region is + * exited + */ + IntrEnableStatus = StatusRegister; + + /* + * Fill the FIFO from the the buffer that was specified + */ + + while (((StatusRegister & XUL_SR_TX_FIFO_FULL) == 0) && + (SentCount < InstancePtr->SendBuffer.RemainingBytes)) { + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_TX_FIFO_OFFSET, + InstancePtr->SendBuffer.NextBytePtr[ + SentCount]); + + SentCount++; + + StatusRegister = XUartLite_GetSR(InstancePtr); + } + + /* + * Update the buffer to reflect the bytes that were sent from it + */ + InstancePtr->SendBuffer.NextBytePtr += SentCount; + InstancePtr->SendBuffer.RemainingBytes -= SentCount; + + /* + * Increment associated counters + */ + InstancePtr->Stats.CharactersTransmitted += SentCount; + + /* + * Restore the interrupt enable register to it's previous value such + * that the critical region is exited + */ + IntrEnableStatus &= XUL_CR_ENABLE_INTR; + XUartLite_WriteReg(InstancePtr->RegBaseAddress, XUL_CONTROL_REG_OFFSET, + IntrEnableStatus); + + /* + * Return the number of bytes that were sent, although they really were + * only put into the FIFO, not completely sent yet + */ + return SentCount; +} + +/****************************************************************************/ +/** +* +* This function receives a buffer that has been previously specified by setting +* up the instance variables of the instance. This function is designed to be +* an internal function for the XUartLite component such that it may be called +* from a shell function that sets up the buffer or from an interrupt handler. +* +* This function will attempt to receive a specified number of bytes of data +* from the UART and store it into the specified buffer. This function is +* designed for either polled or interrupt driven modes. It is non-blocking +* such that it will return if there is no data has already received by the +* UART. +* +* In a polled mode, this function will only receive as much data as the UART +* can buffer, either in the receiver or in the FIFO if present and enabled. +* The application may need to call it repeatedly to receive a buffer. Polled +* mode is the default mode of operation for the driver. +* +* In interrupt mode, this function will start receiving and then the interrupt +* handler of the driver will continue until the buffer has been received. A +* callback function, as specified by the application, will be called to indicate +* the completion of receiving the buffer or when any receive errors or timeouts +* occur. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return The number of bytes received. +* +* @note None. +* +*****************************************************************************/ +unsigned int XUartLite_ReceiveBuffer(XUartLite *InstancePtr) +{ + u8 StatusRegister; + u8 StatusRegisterVal; + unsigned int ReceivedCount = 0; + + /* + * Enter a critical region by disabling all the UART interrupts to allow + * this call to stop a previous operation that may be interrupt driven + */ + StatusRegisterVal = XUartLite_GetSR(InstancePtr); + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, 0); + /* + * Loop until there is not more data buffered by the UART or the + * specified number of bytes is received + */ + + while (ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes) { + /* + * Read the Status Register to determine if there is any data in + * the receiver/FIFO + */ + StatusRegister = XUartLite_GetSR(InstancePtr); + + /* + * If there is data ready to be removed, then put the next byte + * received into the specified buffer and update the stats to + * reflect any receive errors for the byte + */ + if (StatusRegister & XUL_SR_RX_FIFO_VALID_DATA) { + InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount++]= + XUartLite_ReadReg(InstancePtr->RegBaseAddress, + XUL_RX_FIFO_OFFSET); + + } + + /* + * There's no more data buffered, so exit such that this + * function does not block waiting for data + */ + else { + break; + } + } + + /* + * Update the receive buffer to reflect the number of bytes that was + * received + */ + InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount; + InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount; + + /* + * Increment associated counters in the statistics + */ + InstancePtr->Stats.CharactersReceived += ReceivedCount; + + /* + * Restore the interrupt enable register to it's previous value such + * that the critical region is exited + */ + StatusRegisterVal &= XUL_CR_ENABLE_INTR; + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, StatusRegisterVal); + + return ReceivedCount; +} + +/****************************************************************************/ +/** +* +* This function reads the status register and updates the error stats, before +* returning the status register value. The status register is a clear on read +* register, so the errors if occurred have to be recorded everytime status +* register is read. This function is designed to be an internal function for +* the XUartLite component such that it may be called from wherever the status +* register needs to be read from the other driver functions. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return The value of status register. +* +* @note None. +* +*****************************************************************************/ +u8 XUartLite_GetSR(XUartLite *InstancePtr) +{ + u8 StatusRegister; + + StatusRegister = XUartLite_GetStatusReg(InstancePtr->RegBaseAddress); + /* + * Update Stats everytime status reg is read as it is a clear on read + * register and as a result, there is a chance of missing the errors. + */ + XUartLite_UpdateStats(InstancePtr, StatusRegister); + return StatusRegister; +} + +/** @} */ diff --git a/arm/hal/uart/xuartlite.h b/arm/hal/uart/xuartlite.h new file mode 100644 index 0000000..a4f2ab4 --- /dev/null +++ b/arm/hal/uart/xuartlite.h @@ -0,0 +1,274 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite.h +* @addtogroup uartlite_v3_7 +* @{ +* @details +* +* This component contains the implementation of the XUartLite component which is +* the driver for the Xilinx UART Lite device. This UART is a minimal hardware +* implementation with minimal features. Most of the features, including baud +* rate, parity, and number of data bits are only configurable when the hardware +* device is built, rather than at run time by software. +* +* The device has 16 byte transmit and receive FIFOs and supports interrupts. +* The device does not have any way to disable the receiver such that the +* receive FIFO may contain unwanted data. The FIFOs are not flushed when the +* driver is initialized, but a function is provided to allow the user to +* reset the FIFOs if desired. +* +* The driver defaults to no interrupts at initialization such that interrupts +* must be enabled if desired. An interrupt is generated when the transmit FIFO +* transitions from having data to being empty or when any data is contained in +* the receive FIFO. +* +* In order to use interrupts, it's necessary for the user to connect the driver +* interrupt handler, XUartLite_InterruptHandler, to the interrupt system of the +* application. This function does not save and restore the processor context +* such that the user must provide it. Send and receive handlers may be set for +* the driver such that the handlers are called when transmit and receive +* interrupts occur. The handlers are called from interrupt context and are +* designed to allow application specific processing to be performed. +* +* The functions, XUartLite_Send and XUartLite_Recv, are provided in the driver +* to allow data to be sent and received. They are designed to be used in +* polled or interrupt modes. +* +* The driver provides a status for each received byte indicating any parity +* frame or overrun error. The driver provides statistics which allow visibility +* into these errors. +* +* Initialization & Configuration +* +* The XUartLite_Config structure is used by the driver to configure itself. This +* configuration structure is typically created by the tool-chain based on HW +* build properties. +* +* To support multiple runtime loading and initialization strategies employed +* by various operating systems, the driver instance can be initialized in one +* of the following ways: +* +* - XUartLite_Initialize(InstancePtr, DeviceId) - The driver looks up its own +* configuration structure created by the tool-chain based on an ID provided +* by the tool-chain. +* +* - XUartLite_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) - Uses a +* configuration structure provided by the caller. If running in a system +* with address translation, the provided virtual memory base address +* replaces the physical address present in the configuration structure. +* +* RTOS Independence +* +* This driver is intended to be RTOS and processor independent. It works +* with physical addresses only. Any needs for dynamic memory management, +* threads or thread mutual exclusion, virtual memory, or cache control must +* be satisfied by the layer above this driver. +* +* @note +* +* The driver is partitioned such that a minimal implementation may be used. +* More features require additional files to be linked in. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
+* 1.01a jvb  12/14/05 I separated dependency on the static config table and
+*                     xparameters.h from the driver initialization by moving
+*                     _Initialize and _LookupConfig to _sinit.c. I also added
+*                     the new _CfgInitialize routine.
+* 1.02a rpm  02/14/07 Added check for outstanding transmission before
+*                     calling the send callback (avoids extraneous
+*                     callback invocations) in interrupt service routine.
+* 1.12a mta  03/31/07 Updated to new coding conventions
+* 1.13a sv   01/21/08 Updated driver to support access through DCR bus
+* 1.14a sdm  08/22/08 Removed support for static interrupt handlers from the MDD
+*		      file
+* 1.14a sdm  09/26/08 Updated code to avoid race condition in
+*		      XUartLite_SendBuffer
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. The macros have been
+*		      renamed to remove _m from the name. XUartLite_mClearStats
+*		      macro is removed and XUartLite_ClearStats function should
+*		      be used in its place.
+* 2.01a adk  18/04/13 Updated the code to avoid unused variable
+*		      warnings when compiling with the -Wextra -Wall flags
+*		      In the file xuartlite.c. CR:704999.
+*		      Added notes for CR 710483 that the XUL_FIFO_SIZE is not
+*		      used in the driver. This is the size of the FIFO for
+*		      Transmit/Receive FIFOs which cannot be changed.
+* 3.0 adk 17/12/13  Fixed CR:741186,761863 Changes are made in the file 
+*		      xuartlite_selftest.c      
+* 3.0 adk 19/12/13  Update the driver as per new TCL API's
+* 3.1 nsk 21/07/15  Updated XUartLite_ReceiveBuffer function in xuartlite.c
+*		    to update the receive data into user buffer in critical
+*		    region.CR#865787.
+* 3.2   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototype of XUartLite_CfgInitialize API.
+*       ms   01/23/17 Added xil_printf statement in main function for all
+*                     examples to ensure that "Successfully ran" and "Failed"
+*                     strings are available in all examples. This is a fix
+*                     for CR-965028.
+*       ms   03/17/17 Added readme.txt file in examples folder for doxygen
+*                     generation.
+* 3.3   sne 09/09/19  Updated driver tcl file for supporting pl and ps ip's.
+* 3.3	sne 09/13/19  Updated driver tcl file for mdm & tmr_sem ip's.
+* 3.7	adk 31/01/22  Fix interrupt controller name in SMP designs, Changes are
+* 		      made in the interrupt app tcl file.
+* 3.7	adk 14/02/22  When generating peripheral tests for TMR subsystem based
+* 		      designs don't pull the driver examples when uartlite is
+* 		      configured as a TMR SEM fix for CR-1121291, changes are
+* 		      made in the uartlite_tapp.tcl file.
+* 
+* +*****************************************************************************/ + +#ifndef XUARTLITE_H /* prevent circular inclusions */ +#define XUARTLITE_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/** + * Callback function. The first argument is a callback reference passed in by + * the upper layer when setting the callback functions, and passed back to the + * upper layer when the callback is invoked. + * The second argument is the ByteCount which is the number of bytes that + * actually moved from/to the buffer provided in the _Send/_Receive call. + */ +typedef void (*XUartLite_Handler)(void *CallBackRef, unsigned int ByteCount); + +/** + * Statistics for the XUartLite driver + */ +typedef struct { + u32 TransmitInterrupts; /**< Number of transmit interrupts */ + u32 ReceiveInterrupts; /**< Number of receive interrupts */ + u32 CharactersTransmitted; /**< Number of characters transmitted */ + u32 CharactersReceived; /**< Number of characters received */ + u32 ReceiveOverrunErrors; /**< Number of receive overruns */ + u32 ReceiveParityErrors; /**< Number of receive parity errors */ + u32 ReceiveFramingErrors; /**< Number of receive framing errors */ +} XUartLite_Stats; + +/** + * The following data type is used to manage the buffers that are handled + * when sending and receiving data in the interrupt mode. It is intended + * for internal use only. + */ +typedef struct { + u8 *NextBytePtr; + unsigned int RequestedBytes; + unsigned int RemainingBytes; +} XUartLite_Buffer; + +/** + * This typedef contains configuration information for the device. + */ +typedef struct { + u16 DeviceId; /**< Unique ID of device */ + UINTPTR RegBaseAddr; /**< Register base address */ + u32 BaudRate; /**< Fixed baud rate */ + u8 UseParity; /**< Parity generator enabled when TRUE */ + u8 ParityOdd; /**< Parity generated is odd when TRUE, even + when FALSE */ + u8 DataBits; /**< Fixed data bits */ +} XUartLite_Config; + +/** + * The XUartLite driver instance data. The user is required to allocate a + * variable of this type for every UART Lite device in the system. A pointer + * to a variable of this type is then passed to the driver API functions. + */ +typedef struct { + XUartLite_Stats Stats; /* Component Statistics */ + UINTPTR RegBaseAddress; /* Base address of registers */ + u32 IsReady; /* Device is initialized and ready */ + + XUartLite_Buffer SendBuffer; + XUartLite_Buffer ReceiveBuffer; + + XUartLite_Handler RecvHandler; + void *RecvCallBackRef; /* Callback ref for recv handler */ + XUartLite_Handler SendHandler; + void *SendCallBackRef; /* Callback ref for send handler */ +} XUartLite; + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Function Prototypes *****************************/ + +/* + * Initialization functions in xuartlite_sinit.c + */ +int XUartLite_Initialize(XUartLite *InstancePtr, u16 DeviceId); +XUartLite_Config *XUartLite_LookupConfig(u16 DeviceId); + +/* + * Required functions, in file xuart.c + */ +int XUartLite_CfgInitialize(XUartLite *InstancePtr, + XUartLite_Config *Config, + UINTPTR EffectiveAddr); + +void XUartLite_ResetFifos(XUartLite *InstancePtr); + +unsigned int XUartLite_Send(XUartLite *InstancePtr, u8 *DataBufferPtr, + unsigned int NumBytes); +unsigned int XUartLite_Recv(XUartLite *InstancePtr, u8 *DataBufferPtr, + unsigned int NumBytes); + +int XUartLite_IsSending(XUartLite *InstancePtr); + +/* + * Functions for statistics, in file xuartlite_stats.c + */ +void XUartLite_GetStats(XUartLite *InstancePtr, XUartLite_Stats *StatsPtr); +void XUartLite_ClearStats(XUartLite *InstancePtr); + +/* + * Functions for self-test, in file xuartlite_selftest.c + */ +int XUartLite_SelfTest(XUartLite *InstancePtr); + +/* + * Functions for interrupts, in file xuartlite_intr.c + */ +void XUartLite_EnableInterrupt(XUartLite *InstancePtr); +void XUartLite_DisableInterrupt(XUartLite *InstancePtr); + +void XUartLite_SetRecvHandler(XUartLite *InstancePtr, XUartLite_Handler FuncPtr, + void *CallBackRef); +void XUartLite_SetSendHandler(XUartLite *InstancePtr, XUartLite_Handler FuncPtr, + void *CallBackRef); + +void XUartLite_InterruptHandler(XUartLite *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + +/** @} */ diff --git a/arm/hal/uart/xuartlite_g.c b/arm/hal/uart/xuartlite_g.c new file mode 100644 index 0000000..ea93030 --- /dev/null +++ b/arm/hal/uart/xuartlite_g.c @@ -0,0 +1,63 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_g.c +* @addtogroup uartlite_v3_7 +* @{ +* +* This file contains a configuration table that specifies the configuration of +* UART Lite devices in the system. Each device in the system should have an +* entry in the table. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xuartlite.h" +#include "xparameters.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Prototypes ******************************/ + +/** + * The configuration table for UART Lite devices + */ +XUartLite_Config XUartLite_ConfigTable[XPAR_XUARTLITE_NUM_INSTANCES] = +{ + { + XPAR_UARTLITE_0_DEVICE_ID, /* Unique ID of device */ + XPAR_UARTLITE_0_BASEADDR, /* Device base address */ + XPAR_UARTLITE_0_BAUDRATE, /* Fixed baud rate */ + XPAR_UARTLITE_0_USE_PARITY, /* Fixed parity */ + XPAR_UARTLITE_0_ODD_PARITY, /* Fixed parity type */ + XPAR_UARTLITE_0_DATA_BITS /* Fixed data bits */ + }, +}; + + +/** @} */ diff --git a/arm/hal/uart/xuartlite_i.h b/arm/hal/uart/xuartlite_i.h new file mode 100644 index 0000000..c91fd08 --- /dev/null +++ b/arm/hal/uart/xuartlite_i.h @@ -0,0 +1,100 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_i.h +* @addtogroup uartlite_v3_7 +* @{ +* +* Contains data which is shared between the files of the XUartLite component. +* It is intended for internal use only. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Reparitioned the driver for smaller files
+* 1.00b rpm  04/24/02 Moved register definitions to xuartlite_l.h and
+*                     updated macro naming convention
+* 2.00a ktn  10/20/09 The macros have been renamed to remove _m from
+*		      the name. XUartLite_mClearStats macro is removed and
+*		      XUartLite_ClearStats function should be used in its place.
+* 3.6   rna  02/19/21 Added 'XUartLite_GetSR' internal API.
+* 
+* +*****************************************************************************/ + +#ifndef XUARTLITE_I_H /* prevent circular inclusions */ +#define XUARTLITE_I_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xuartlite.h" +#include "xuartlite_l.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/**************************************************************************** +* +* Update the statistics of the instance. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param StatusRegister contains the contents of the UART status +* register to update the statistics with. +* +* @return None. +* +* @note +* +* Signature: void XUartLite_UpdateStats(XUartLite *InstancePtr, +* u32 StatusRegister) +* +*****************************************************************************/ +#define XUartLite_UpdateStats(InstancePtr, StatusRegister) \ +{ \ + if ((StatusRegister) & XUL_SR_OVERRUN_ERROR) \ + { \ + (InstancePtr)->Stats.ReceiveOverrunErrors++; \ + } \ + if ((StatusRegister) & XUL_SR_PARITY_ERROR) \ + { \ + (InstancePtr)->Stats.ReceiveParityErrors++; \ + } \ + if ((StatusRegister) & XUL_SR_FRAMING_ERROR) \ + { \ + (InstancePtr)->Stats.ReceiveFramingErrors++; \ + } \ +} + +/************************** Variable Definitions ****************************/ + +/* the configuration table */ +extern XUartLite_Config XUartLite_ConfigTable[]; + +/************************** Function Prototypes *****************************/ + +unsigned int XUartLite_SendBuffer(XUartLite *InstancePtr); +unsigned int XUartLite_ReceiveBuffer(XUartLite *InstancePtr); +u8 XUartLite_GetSR(XUartLite *InstancePtr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + +/** @} */ diff --git a/arm/hal/uart/xuartlite_intr.c b/arm/hal/uart/xuartlite_intr.c new file mode 100644 index 0000000..5c42c8c --- /dev/null +++ b/arm/hal/uart/xuartlite_intr.c @@ -0,0 +1,309 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_intr.c +* @addtogroup uartlite_v3_7 +* @{ +* +* This file contains interrupt-related functions for the UART Lite component +* (XUartLite). +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
+* 1.02a rpm  02/14/07 Added check for outstanding transmission before
+*			calling the send callback (avoids extraneous
+*			callback invocations)
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. The macros have been
+*		      renamed to remove _m from the name.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xuartlite.h" +#include "xuartlite_i.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/************************** Function Prototypes *****************************/ + +static void ReceiveDataHandler(XUartLite *InstancePtr); +static void SendDataHandler(XUartLite *InstancePtr); + +/************************** Variable Definitions ****************************/ + +typedef void (*Handler)(XUartLite *InstancePtr); + +/****************************************************************************/ +/** +* +* This function sets the handler that will be called when an event (interrupt) +* occurs in the driver. The purpose of the handler is to allow application +* specific processing to be performed. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param FuncPtr is the pointer to the callback function. +* @param CallBackRef is the upper layer callback reference passed back +* when the callback function is invoked. +* +* @return None. +* +* @note There is no assert on the CallBackRef since the driver doesn't +* know what it is (nor should it) +* +*****************************************************************************/ +void XUartLite_SetRecvHandler(XUartLite *InstancePtr, + XUartLite_Handler FuncPtr, void *CallBackRef) +{ + /* + * Assert validates the input arguments + * CallBackRef not checked, no way to know what is valid + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->RecvHandler = FuncPtr; + InstancePtr->RecvCallBackRef = CallBackRef; +} + +/****************************************************************************/ +/** +* +* This function sets the handler that will be called when an event (interrupt) +* occurs in the driver. The purpose of the handler is to allow application +* specific processing to be performed. +* +* @param InstancePtr is a pointer to the XUartLite instance . +* @param FuncPtr is the pointer to the callback function. +* @param CallBackRef is the upper layer callback reference passed back +* when the callback function is invoked. +* +* @return None. +* +* @note There is no assert on the CallBackRef since the driver doesn't +* know what it is (nor should it) +* +*****************************************************************************/ +void XUartLite_SetSendHandler(XUartLite *InstancePtr, + XUartLite_Handler FuncPtr, void *CallBackRef) +{ + /* + * Assert validates the input arguments + * CallBackRef not checked, no way to know what is valid + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(FuncPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->SendHandler = FuncPtr; + InstancePtr->SendCallBackRef = CallBackRef; +} + +/****************************************************************************/ +/** +* +* This function is the interrupt handler for the UART lite driver. +* It must be connected to an interrupt system by the user such that it is +* called when an interrupt for any UART lite occurs. This function +* does not save or restore the processor context such that the user must +* ensure this occurs. +* +* @param InstancePtr contains a pointer to the instance of the UART that +* the interrupt is for. +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XUartLite_InterruptHandler(XUartLite *InstancePtr) +{ + u32 IsrStatus; + + Xil_AssertVoid(InstancePtr != NULL); + + /* + * Read the status register to determine which, coulb be both + * interrupt is active + */ + IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress, + XUL_STATUS_REG_OFFSET); + + if ((IsrStatus & (XUL_SR_RX_FIFO_FULL | + XUL_SR_RX_FIFO_VALID_DATA)) != 0) { + ReceiveDataHandler(InstancePtr); + } + + if (((IsrStatus & XUL_SR_TX_FIFO_EMPTY) != 0) && + (InstancePtr->SendBuffer.RequestedBytes > 0)) { + SendDataHandler(InstancePtr); + } +} + +/****************************************************************************/ +/** +* +* This function handles the interrupt when data is received, either a single +* byte when FIFOs are not enabled, or multiple bytes with the FIFO. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void ReceiveDataHandler(XUartLite *InstancePtr) +{ + /* + * If there are bytes still to be received in the specified buffer + * go ahead and receive them + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { + XUartLite_ReceiveBuffer(InstancePtr); + } + + /* + * If the last byte of a message was received then call the application + * handler, this code should not use an else from the previous check of + * the number of bytes to receive because the call to receive the buffer + * updates the bytes to receive + */ + if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) { + InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef, + InstancePtr->ReceiveBuffer.RequestedBytes - + InstancePtr->ReceiveBuffer.RemainingBytes); + } + + /* + * Update the receive stats to reflect the receive interrupt + */ + InstancePtr->Stats.ReceiveInterrupts++; +} + +/****************************************************************************/ +/** +* +* This function handles the interrupt when data has been sent, the transmit +* FIFO is empty (transmitter holding register). +* +* @param InstancePtr is a pointer to the XUartLite instance . +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +static void SendDataHandler(XUartLite *InstancePtr) +{ + /* + * If there are not bytes to be sent from the specified buffer, + * call the callback function + */ + if (InstancePtr->SendBuffer.RemainingBytes == 0) { + int SaveReq; + + /* + * Save and zero the requested bytes since transmission + * is complete + */ + SaveReq = InstancePtr->SendBuffer.RequestedBytes; + InstancePtr->SendBuffer.RequestedBytes = 0; + + /* + * Call the application handler to indicate + * the data has been sent + */ + InstancePtr->SendHandler(InstancePtr->SendCallBackRef, SaveReq); + } + /* + * Otherwise there is still more data to send in the specified buffer + * so go ahead and send it + */ + else { + XUartLite_SendBuffer(InstancePtr); + } + + /* + * Update the transmit stats to reflect the transmit interrupt + */ + InstancePtr->Stats.TransmitInterrupts++; +} + + +/*****************************************************************************/ +/** +* +* This function disables the UART interrupt. After calling this function, +* data may still be received by the UART but no interrupt will be generated +* since the hardware device has no way to disable the receiver. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartLite_DisableInterrupt(XUartLite *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write to the control register to disable the interrupts, the only + * other bits in this register are the FIFO reset bits such that + * writing them to zero will not affect them. + */ + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, 0); +} + +/*****************************************************************************/ +/** +* +* This function enables the UART interrupt such that an interrupt will occur +* when data is received or data has been transmitted. The device contains +* 16 byte receive and transmit FIFOs such that an interrupt is generated +* anytime there is data in the receive FIFO and when the transmit FIFO +* transitions from not empty to empty. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartLite_EnableInterrupt(XUartLite *InstancePtr) +{ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Write to the control register to enable the interrupts, the only + * other bits in this register are the FIFO reset bits such that + * writing them to zero will not affect them. + */ + XUartLite_WriteReg(InstancePtr->RegBaseAddress, + XUL_CONTROL_REG_OFFSET, XUL_CR_ENABLE_INTR); +} + +/** @} */ diff --git a/arm/hal/uart/xuartlite_l.c b/arm/hal/uart/xuartlite_l.c new file mode 100644 index 0000000..2bc4f73 --- /dev/null +++ b/arm/hal/uart/xuartlite_l.c @@ -0,0 +1,95 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_l.c +* @addtogroup uartlite_v3_7 +* @{ +* +* This file contains low-level driver functions that can be used to access the +* device. The user should refer to the hardware device specification for more +* details of the device operation. + +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm  04/25/02 First release
+* 1.12a rpm  07/16/07 Fixed arg type for RecvByte
+* 2.00a ktn  10/20/09 The macros have been renamed to remove _m from the name.
+* 3.2   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototypes of XUartLite_SendByte,
+*                     XUartLite_RecvByte APIs.
+* 
+* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xuartlite_l.h" + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Prototypes ******************************/ + + +/****************************************************************************/ +/** +* +* This functions sends a single byte using the UART. It is blocking in that it +* waits for the transmitter to become non-full before it writes the byte to +* the transmit register. +* +* @param BaseAddress is the base address of the device +* @param Data is the byte of data to send +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XUartLite_SendByte(UINTPTR BaseAddress, u8 Data) +{ + while (XUartLite_IsTransmitFull(BaseAddress)); + + XUartLite_WriteReg(BaseAddress, XUL_TX_FIFO_OFFSET, Data); +} + + +/****************************************************************************/ +/** +* +* This functions receives a single byte using the UART. It is blocking in that +* it waits for the receiver to become non-empty before it reads from the +* receive register. +* +* @param BaseAddress is the base address of the device +* +* @return The byte of data received. +* +* @note None. +* +******************************************************************************/ +u8 XUartLite_RecvByte(UINTPTR BaseAddress) +{ + while (XUartLite_IsReceiveEmpty(BaseAddress)); + + return (u8)XUartLite_ReadReg(BaseAddress, XUL_RX_FIFO_OFFSET); +} + +/** @} */ diff --git a/arm/hal/uart/xuartlite_l.h b/arm/hal/uart/xuartlite_l.h new file mode 100644 index 0000000..9a6046a --- /dev/null +++ b/arm/hal/uart/xuartlite_l.h @@ -0,0 +1,310 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_l.h +* @addtogroup uartlite_v3_7 +* @{ +* +* This header file contains identifiers and low-level driver functions (or +* macros) that can be used to access the device. High-level driver functions +* are defined in xuartlite.h. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00b rpm  04/25/02 First release
+* 1.00b rpm  07/07/03 Removed references to XUartLite_GetControlReg macro
+*                     since the control register is write-only
+* 1.12a mta  03/21/07 Updated to new coding style
+* 1.13a sv   01/21/08 Updated driver to support access through DCR bus
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. The macros have been
+*		      renamed to remove _m from the name.
+* 3.2   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
+*                     Changed the prototypes of XUartLite_SendByte,
+*                     XUartLite_RecvByte APIs.
+* 
+* +*****************************************************************************/ + +#ifndef XUARTLITE_L_H /* prevent circular inclusions */ +#define XUARTLITE_L_H /* by using protection macros */ + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xil_io.h" + +/* + * XPAR_XUARTLITE_USE_DCR_BRIDGE has to be set to 1 if the UartLite device is + * accessed through a DCR bus connected to a bridge. + */ +#define XPAR_XUARTLITE_USE_DCR_BRIDGE 0 + +#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0) +#include "xio_dcr.h" +#endif + + +/************************** Constant Definitions ****************************/ + +/* UART Lite register offsets */ + +#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0) +#define XUL_RX_FIFO_OFFSET 0 /* receive FIFO, read only */ +#define XUL_TX_FIFO_OFFSET 1 /* transmit FIFO, write only */ +#define XUL_STATUS_REG_OFFSET 2 /* status register, read only */ +#define XUL_CONTROL_REG_OFFSET 3 /* control reg, write only */ + +#else + +#define XUL_RX_FIFO_OFFSET 0 /* receive FIFO, read only */ +#define XUL_TX_FIFO_OFFSET 4 /* transmit FIFO, write only */ +#define XUL_STATUS_REG_OFFSET 8 /* status register, read only */ +#define XUL_CONTROL_REG_OFFSET 12 /* control reg, write only */ + +#endif + +/* Control Register bit positions */ + +#define XUL_CR_ENABLE_INTR 0x10 /* enable interrupt */ +#define XUL_CR_FIFO_RX_RESET 0x02 /* reset receive FIFO */ +#define XUL_CR_FIFO_TX_RESET 0x01 /* reset transmit FIFO */ + +/* Status Register bit positions */ + +#define XUL_SR_PARITY_ERROR 0x80 +#define XUL_SR_FRAMING_ERROR 0x40 +#define XUL_SR_OVERRUN_ERROR 0x20 +#define XUL_SR_INTR_ENABLED 0x10 /* interrupt enabled */ +#define XUL_SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */ +#define XUL_SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ +#define XUL_SR_RX_FIFO_FULL 0x02 /* receive FIFO full */ +#define XUL_SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ + +/* The following constant specifies the size of the Transmit/Receive FIFOs. + * The FIFO size is fixed to 16 in the Uartlite IP and the size is not + * configurable. This constant is not used in the driver. + */ +#define XUL_FIFO_SIZE 16 + +/* Stop bits are fixed at 1. Baud, parity, and data bits are fixed on a + * per instance basis + */ +#define XUL_STOP_BITS 1 + +/* Parity definitions + */ +#define XUL_PARITY_NONE 0 +#define XUL_PARITY_ODD 1 +#define XUL_PARITY_EVEN 2 + +/**************************** Type Definitions ******************************/ + +/***************** Macros (Inline Functions) Definitions ********************/ + +/* + * Define the appropriate I/O access method to memory mapped I/O or DCR. + */ +#if (XPAR_XUARTLITE_USE_DCR_BRIDGE != 0) + +#define XUartLite_In32 XIo_DcrIn +#define XUartLite_Out32 XIo_DcrOut + +#else + +#define XUartLite_In32 Xil_In32 +#define XUartLite_Out32 Xil_Out32 + +#endif + + +/****************************************************************************/ +/** +* +* Write a value to a UartLite register. A 32 bit write is performed. +* +* @param BaseAddress is the base address of the UartLite device. +* @param RegOffset is the register offset from the base to write to. +* @param Data is the data written to the register. +* +* @return None. +* +* @note C-style signature: +* void XUartLite_WriteReg(u32 BaseAddress, u32 RegOffset, +* u32 Data) +* +****************************************************************************/ +#define XUartLite_WriteReg(BaseAddress, RegOffset, Data) \ + XUartLite_Out32((BaseAddress) + (RegOffset), (u32)(Data)) + +/****************************************************************************/ +/** +* +* Read a value from a UartLite register. A 32 bit read is performed. +* +* @param BaseAddress is the base address of the UartLite device. +* @param RegOffset is the register offset from the base to read from. +* +* @return Data read from the register. +* +* @note C-style signature: +* u32 XUartLite_ReadReg(u32 BaseAddress, u32 RegOffset) +* +****************************************************************************/ +#define XUartLite_ReadReg(BaseAddress, RegOffset) \ + XUartLite_In32((BaseAddress) + (RegOffset)) + + +/****************************************************************************/ +/** +* +* Set the contents of the control register. Use the XUL_CR_* constants defined +* above to create the bit-mask to be written to the register. +* +* @param BaseAddress is the base address of the device +* @param Mask is the 32-bit value to write to the control register +* +* @return None. +* +* @note C-style Signature: +* void XUartLite_SetControlReg(u32 BaseAddress, u32 Mask); +* +*****************************************************************************/ +#define XUartLite_SetControlReg(BaseAddress, Mask) \ + XUartLite_WriteReg((BaseAddress), XUL_CONTROL_REG_OFFSET, (Mask)) + + +/****************************************************************************/ +/** +* +* Get the contents of the status register. Use the XUL_SR_* constants defined +* above to interpret the bit-mask returned. +* +* @param BaseAddress is the base address of the device +* +* @return A 32-bit value representing the contents of the status register. +* +* @note C-style Signature: +* u32 XUartLite_GetStatusReg(u32 BaseAddress); +* +*****************************************************************************/ +#define XUartLite_GetStatusReg(BaseAddress) \ + XUartLite_ReadReg((BaseAddress), XUL_STATUS_REG_OFFSET) + + +/****************************************************************************/ +/** +* +* Check to see if the receiver has data. +* +* @param BaseAddress is the base address of the device +* +* @return TRUE if the receiver is empty, FALSE if there is data present. +* +* @note C-style Signature: +* int XUartLite_IsReceiveEmpty(u32 BaseAddress); +* +*****************************************************************************/ +#define XUartLite_IsReceiveEmpty(BaseAddress) \ + ((XUartLite_GetStatusReg((BaseAddress)) & XUL_SR_RX_FIFO_VALID_DATA) != \ + XUL_SR_RX_FIFO_VALID_DATA) + + +/****************************************************************************/ +/** +* +* Check to see if the transmitter is full. +* +* @param BaseAddress is the base address of the device +* +* @return TRUE if the transmitter is full, FALSE otherwise. +* +* @note C-style Signature: +* int XUartLite_IsTransmitFull(u32 BaseAddress); +* +*****************************************************************************/ +#define XUartLite_IsTransmitFull(BaseAddress) \ + ((XUartLite_GetStatusReg((BaseAddress)) & XUL_SR_TX_FIFO_FULL) == \ + XUL_SR_TX_FIFO_FULL) + + +/****************************************************************************/ +/** +* +* Check to see if the interrupt is enabled. +* +* @param BaseAddress is the base address of the device +* +* @return TRUE if the interrupt is enabled, FALSE otherwise. +* +* @note C-style Signature: +* int XUartLite_IsIntrEnabled(u32 BaseAddress); +* +*****************************************************************************/ +#define XUartLite_IsIntrEnabled(BaseAddress) \ + ((XUartLite_GetStatusReg((BaseAddress)) & XUL_SR_INTR_ENABLED) == \ + XUL_SR_INTR_ENABLED) + + +/****************************************************************************/ +/** +* +* Enable the device interrupt. We cannot read the control register, so we +* just write the enable interrupt bit and clear all others. Since the only +* other ones are the FIFO reset bits, this works without side effects. +* +* @param BaseAddress is the base address of the device +* +* @return None. +* +* @note C-style Signature: +* void XUartLite_EnableIntr(u32 BaseAddress); +* +*****************************************************************************/ +#define XUartLite_EnableIntr(BaseAddress) \ + XUartLite_SetControlReg((BaseAddress), XUL_CR_ENABLE_INTR) + + +/****************************************************************************/ +/** +* +* Disable the device interrupt. We cannot read the control register, so we +* just clear all bits. Since the only other ones are the FIFO reset bits, +* this works without side effects. +* +* @param BaseAddress is the base address of the device +* +* @return None. +* +* @note C-style Signature: +* void XUartLite_DisableIntr(u32 BaseAddress); +* +*****************************************************************************/ +#define XUartLite_DisableIntr(BaseAddress) \ + XUartLite_SetControlReg((BaseAddress), 0) + +/************************** Function Prototypes *****************************/ + +void XUartLite_SendByte(UINTPTR BaseAddress, u8 Data); +u8 XUartLite_RecvByte(UINTPTR BaseAddress); + +#ifdef __cplusplus +} +#endif + +#endif /* end of protection macro */ + + +/** @} */ diff --git a/arm/hal/uart/xuartlite_selftest.c b/arm/hal/uart/xuartlite_selftest.c new file mode 100644 index 0000000..43a3ddc --- /dev/null +++ b/arm/hal/uart/xuartlite_selftest.c @@ -0,0 +1,114 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_selftest.c +* @addtogroup uartlite_v3_7 +* @{ +* +* This file contains the self-test functions for the UART Lite component +* (XUartLite). +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. The macros have been
+*		      renamed to remove _m from the name.
+* 3.0 adk 17/12/13  Fixed CR:741186,761863 Reset the FIFO's before reading 
+*		      the status register We don't know the status of the Status
+* 		      Register in case of if there is more than one uartlite IP
+*		      instance in the h/w design.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xstatus.h" +#include "xuartlite.h" +#include "xuartlite_i.h" +#include "xil_io.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* +* Runs a self-test on the device hardware. Since there is no way to perform a +* loopback in the hardware, this test can only check the state of the status +* register to verify it is correct. This test assumes that the hardware +* device is still in its reset state, but has been initialized with the +* Initialize function. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return +* - XST_SUCCESS if the self-test was successful. +* - XST_FAILURE if the self-test failed, the status register +* value was not correct +* +* @note None. +* +******************************************************************************/ +int XUartLite_SelfTest(XUartLite *InstancePtr) +{ + u32 StatusRegister; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* + * Reset the FIFO's before reading the status register. + * It is likely that the Uartlite IP may not always have an + * empty Tx and Rx FIFO when a selftest is performed if more than one + * uartlite instance is present in the h/w design. + */ + XUartLite_ResetFifos(InstancePtr); + + /* + * Read the Status register value to check if it is the correct value + * after a reset + */ + StatusRegister = XUartLite_ReadReg(InstancePtr->RegBaseAddress, + XUL_STATUS_REG_OFFSET); + + /* + * If the status register is any other value other than + * XUL_SR_TX_FIFO_EMPTY then the test is a failure since this is + * the not the value after reset + */ + if (StatusRegister != XUL_SR_TX_FIFO_EMPTY) { + return XST_FAILURE; + } + + return XST_SUCCESS; +} + + +/** @} */ diff --git a/arm/hal/uart/xuartlite_sinit.c b/arm/hal/uart/xuartlite_sinit.c new file mode 100644 index 0000000..e8ab0d9 --- /dev/null +++ b/arm/hal/uart/xuartlite_sinit.c @@ -0,0 +1,122 @@ +/****************************************************************************** +* Copyright (C) 2005 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_sinit.c +* @addtogroup uartlite_v3_7 +* @{ +* +* The implementation of the XUartLite component's static initialization +* functionality. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.01a jvb  10/13/05 First release
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xstatus.h" +#include "xparameters.h" +#include "xuartlite_i.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + +/**************************************************************************** +* +* Looks up the device configuration based on the unique device ID. The table +* UartliteConfigTable contains the configuration info for each device in the +* system. +* +* @param DeviceId is the unique device ID to match on. +* +* @return A pointer to the configuration data for the device, or +* NULL if no match was found. +* +* @note None. +* +******************************************************************************/ +XUartLite_Config *XUartLite_LookupConfig(u16 DeviceId) +{ + XUartLite_Config *CfgPtr = NULL; + u32 Index; + + for (Index=0; Index < XPAR_XUARTLITE_NUM_INSTANCES; Index++) { + if (XUartLite_ConfigTable[Index].DeviceId == DeviceId) { + CfgPtr = &XUartLite_ConfigTable[Index]; + break; + } + } + + return CfgPtr; +} + +/****************************************************************************/ +/** +* +* Initialize a XUartLite instance. The receive and transmit FIFOs of the +* UART are not flushed, so the user may want to flush them. The hardware +* device does not have any way to disable the receiver such that any valid +* data may be present in the receive FIFO. This function disables the UART +* interrupt. The baudrate and format of the data are fixed in the hardware +* at hardware build time. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param DeviceId is the unique id of the device controlled by this +* XUartLite instance. Passing in a device id associates the +* generic XUartLite instance to a specific device, as chosen by +* the caller or application developer. +* +* @return +* - XST_SUCCESS if everything starts up as expected. +* - XST_DEVICE_NOT_FOUND if the device is not found in the +* configuration table. +* +* @note None. +* +*****************************************************************************/ +int XUartLite_Initialize(XUartLite *InstancePtr, u16 DeviceId) +{ + XUartLite_Config *ConfigPtr; + + /* + * Assert validates the input arguments + */ + Xil_AssertNonvoid(InstancePtr != NULL); + + /* + * Lookup the device configuration in the configuration table. Use this + * configuration info when initializing this component. + */ + ConfigPtr = XUartLite_LookupConfig(DeviceId); + + if (ConfigPtr == (XUartLite_Config *)NULL) { + return XST_DEVICE_NOT_FOUND; + } + return XUartLite_CfgInitialize(InstancePtr, ConfigPtr, + ConfigPtr->RegBaseAddr); +} + +/** @} */ diff --git a/arm/hal/uart/xuartlite_stats.c b/arm/hal/uart/xuartlite_stats.c new file mode 100644 index 0000000..caed8e8 --- /dev/null +++ b/arm/hal/uart/xuartlite_stats.c @@ -0,0 +1,118 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_stats.c +* @addtogroup uartlite_v3_7 +* @{ +* +* This file contains the statistics functions for the UART Lite component +* (XUartLite). +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a ecm  08/31/01 First release
+* 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
+* 2.00a ktn  10/20/09 Updated to use HAL Processor APIs.
+*		      XUartLite_mClearStats macro is removed.
+* 
+* +*****************************************************************************/ + +/***************************** Include Files ********************************/ + +#include "xil_types.h" +#include "xil_assert.h" +#include "xuartlite.h" +#include "xuartlite_i.h" + +/************************** Constant Definitions ****************************/ + + +/**************************** Type Definitions ******************************/ + + +/***************** Macros (Inline Functions) Definitions ********************/ + + +/************************** Variable Definitions ****************************/ + + +/************************** Function Prototypes *****************************/ + + +/****************************************************************************/ +/** +* +* Returns a snapshot of the current statistics in the structure specified. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* @param StatsPtr is a pointer to a XUartLiteStats structure to where the +* statistics are to be copied. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartLite_GetStats(XUartLite *InstancePtr, XUartLite_Stats *StatsPtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(StatsPtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + /* Copy the stats from the instance to the specified stats */ + + StatsPtr->TransmitInterrupts = InstancePtr->Stats.TransmitInterrupts; + StatsPtr->ReceiveInterrupts = InstancePtr->Stats.ReceiveInterrupts; + StatsPtr->CharactersTransmitted = + InstancePtr->Stats.CharactersTransmitted; + StatsPtr->CharactersReceived = InstancePtr->Stats.CharactersReceived; + StatsPtr->ReceiveOverrunErrors = + InstancePtr->Stats.ReceiveOverrunErrors; + StatsPtr->ReceiveFramingErrors = + InstancePtr->Stats.ReceiveFramingErrors; + StatsPtr->ReceiveParityErrors = InstancePtr->Stats.ReceiveParityErrors; +} + +/****************************************************************************/ +/** +* +* This function zeros the statistics for the given instance. +* +* @param InstancePtr is a pointer to the XUartLite instance. +* +* @return None. +* +* @note None. +* +*****************************************************************************/ +void XUartLite_ClearStats(XUartLite *InstancePtr) +{ + /* + * Assert validates the input arguments + */ + Xil_AssertVoid(InstancePtr != NULL); + Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); + + InstancePtr->Stats.TransmitInterrupts = 0; + InstancePtr->Stats.ReceiveInterrupts = 0; + InstancePtr->Stats.CharactersTransmitted = 0; + InstancePtr->Stats.CharactersReceived = 0; + InstancePtr->Stats.ReceiveOverrunErrors = 0; + InstancePtr->Stats.ReceiveFramingErrors = 0; + InstancePtr->Stats.ReceiveParityErrors = 0; + +} + +/** @} */ diff --git a/arm/main.cc b/arm/main.cc index 75320d3..0bf5354 100644 --- a/arm/main.cc +++ b/arm/main.cc @@ -1,13 +1,55 @@ #include +#include "xuartlite.h" + struct Gpio { volatile uint32_t data; }; #define gpio0 ((Gpio*) 0x40000000) -int main() { - gpio0->data = 42; +namespace { - while (true) {} +constexpr uintptr_t kUart0BaseAddress = 0x40001000; +XUartLite uart0; +XUartLite_Config uart0_config = { + .DeviceId = 0, + .RegBaseAddr = kUart0BaseAddress, + .BaudRate = 115200, + .UseParity = false, + .DataBits = 8, +}; + +[[maybe_unused]] +void sleep(int ms) { + for (int i = 0; i < ms; i++) { + // sleep for 1 ms + for (int j = 0; j < 50000; j++) { + asm(""); + } + } } + +} // namespace + +int main() { + int recv = 0; + gpio0->data = 37; + + XUartLite_CfgInitialize(&uart0, &uart0_config, uart0_config.RegBaseAddr); + + while (true) { + uint8_t c; + int received_bytes = XUartLite_Recv(&uart0, &c, 1); + if (received_bytes < 1) { + continue; + } + recv++; + gpio0->data = recv & 0xff; + XUartLite_Send(&uart0, &c, 1); + if (c == '\r') { + c = '\n'; + XUartLite_Send(&uart0, &c, 1); + } + } +} \ No newline at end of file diff --git a/arm/makefile b/arm/makefile index eb944cd..072b80e 100644 --- a/arm/makefile +++ b/arm/makefile @@ -4,17 +4,32 @@ CXX = arm-none-eabi-g++ OBJCOPY = arm-none-eabi-objcopy linker_script = bootloader.ld +includes = +sources = -CFLAGS = -march=armv6-m -g -ffunction-sections -fdata-sections -O2 +CFLAGS = -march=armv6-m -g -ffunction-sections -fdata-sections -O2 -Werror -Wall CXXFLAGS = $(CFLAGS) -std=c++20 -fno-exceptions -LDFLAGS = -march=armv6-m -g --specs=nano.specs --specs=nosys.specs -Wl,--gc-sections -Wl,-T$(linker_script) -O2 +LDFLAGS = -march=armv6-m \ + -g --specs=nano.specs --specs=nosys.specs \ + -Wl,--gc-sections -Wl,-T$(linker_script) -O2 \ + -Wl,--print-memory-usage -all: bootloader.bin +sources += hal/lib/common/xil_assert.c +includes += -Ihal/lib/common + +sources += hal/uart/xuartlite.c hal/uart/xuartlite_stats.c +includes += -Ihal/uart + +objects = main.o vector_table.o $(sources:.c=.o) + +CFLAGS += $(includes) + +all: bootloader.elf %.bin: %.elf $(OBJCOPY) -O binary $< $@ -bootloader.elf: main.o vector_table.o +bootloader.elf: $(objects) %.elf: $(LD) $(LDFLAGS) -o $@ $^ @@ -22,4 +37,4 @@ bootloader.elf: main.o vector_table.o .PHONY: clean clean: - rm -rf *.elf *.bin *.o \ No newline at end of file + rm -rf *.elf *.bin $(objects) \ No newline at end of file