/***********************************************************************
*
*             Copyright 2010 Mentor Graphics Corporation
*                         All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS
* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS
* SUBJECT TO LICENSE TERMS.
*
************************************************************************

************************************************************************
*
*   FILE NAME
*
*       rvct_arm_defs.h
*
*   DESCRIPTION
*
*       This file contains all definitions, structures, etc for the
*       RVCT toolset
*
*   DATA STRUCTURES
*
*       None
*
*   DEPENDENCIES
*
*       None
*
***********************************************************************/

#ifndef         RVCT_ARM_DEFS_H
#define         RVCT_ARM_DEFS_H

/* Define required for RTL support. */
#ifndef         ESAL_TS_RTL_SUPPORT
#define         ESAL_TS_RTL_SUPPORT                     NU_TRUE
#endif

/* Define required stack pointer alignment for the given toolset.*/
#define         ESAL_TS_REQ_STK_ALIGNMENT               8

/* Define if toolset supports 64-bit data types (long long) */
#define         ESAL_TS_64BIT_SUPPORT                   NU_TRUE

/* Define, in bytes, toolset minimum required alignment for structures */
#define         ESAL_TS_STRUCT_ALIGNMENT                4

/* Size, in bits, of integers for the given toolset / architecture */
#define         ESAL_TS_INTEGER_SIZE                    32

/* Size, in bits, of code pointer for the given toolset / architecture */
#define         ESAL_TS_CODE_PTR_SIZE                   32

/* Size, in bits, of data pointer for the given toolset / architecture */
#define         ESAL_TS_DATA_PTR_SIZE                   32

/* Define structure padding requirement. */

#define         ESAL_TS_PAD_1BYTE_ALIGN 3
#define         ESAL_TS_PAD_2BYTE_ALIGN 2
#define         ESAL_TS_PAD_3BYTE_ALIGN 1 

/* Define if necessary to copy code / data from ROM to RAM */
#define         ESAL_TS_ROM_TO_RAM_COPY_SUPPORT         CFG_NU_OS_KERN_PLUS_CORE_ROM_TO_RAM_COPY

/* Define, in bytes, toolset maximum alignment for data types. */
#define         ESAL_TS_MAX_TYPE_ALIGNMENT              ESAL_TS_REQ_STK_ALIGNMENT

/* Define tool specific type for HUGE and FAR data pointers - these will usually
   be defined to nothing.  Some 16-bit architectures may require these
   to be defined differently to access data across memory pages */
#define         ESAL_TS_HUGE_PTR_TYPE
#define         ESAL_TS_FAR_PTR_TYPE

/* Define if position-independent code / data (PIC/PID) support (if available)
   is enabled.
   NOTE:  This may be required to be set to NU_TRUE when utilizing any
          OS components requiring position-independent code / data */
#define         ESAL_TS_PIC_PID_SUPPORT                 NU_FALSE

/* External variable declarations */
extern UINT32       Image$$bss$$ZI$$Base;
extern UINT32       Image$$bss$$ZI$$Length;
extern UINT32       Image$$bss$$ZI$$Limit;
extern UINT32       Image$$text$$Limit;
extern UINT32       Image$$data$$Base;
extern UINT32       Image$$data$$Length;
extern UINT32       Image$$ibss$$ZI$$Base;
extern UINT32       Image$$ibss$$ZI$$Length;


/* Macros for memory definitions */
#define TOOLSET_BSS_START_ADDR      (VOID *)&Image$$bss$$ZI$$Base
#define TOOLSET_BSS_END_ADDR        (VOID *)&Image$$bss$$ZI$$Limit
#define TOOLSET_BSS_SIZE            (UINT32)&Image$$bss$$ZI$$Length
#define TOOLSET_IBSS_START_ADDR     (VOID *)&Image$$ibss$$ZI$$Base
#define TOOLSET_IBSS_SIZE           (UINT32)&Image$$ibss$$ZI$$Length

#define TOOLSET_DATA_SRC_ADDR       (ESAL_GE_MEM_ALIGNED_CHECK((VOID *)&Image$$text$$Limit, 4)?(VOID *)&Image$$text$$Limit:ESAL_GE_MEM_PTR_ALIGN((VOID *)&Image$$text$$Limit,4))
#define TOOLSET_DATA_DST_ADDR       (VOID *)&Image$$data$$Base
#define TOOLSET_DATA_SIZE           (UINT32)&Image$$data$$Length

/* Extern function references */
extern VOID     ESAL_TS_RTE_SP_Write(VOID* stack_ptr);
extern VOID     ESAL_TS_RTE_BRK_Execute(UINT32 unused);
extern VOID     ESAL_TS_RTE_SMI_Execute(UINT r0_val, INT r12_op);
extern VOID     ESAL_TS_RTE_PRIMASK_READ(INT * primask_ptr);
extern VOID     ESAL_TS_RTE_PRIMASK_WRITE(INT primask);

/* This macro writes the stack pointer. */
#define         ESAL_TS_RTE_SP_WRITE(stack_ptr)                                     \
                {                                                                   \
                    /* Set hardware stack pointer to passed in address */           \
                    ESAL_TS_RTE_SP_Write(stack_ptr);                                \
                }

/* This macro reads the stack pointer. */
#define         ESAL_TS_RTE_SP_READ()                                               \
                    /* Get architecture stack pointer  */                           \
                    (VOID *)__current_sp()

/* This macro disables all interrupts */
#define         ESAL_TS_RTE_CPSID_EXECUTE()                                         \
                {                                                                   \
                    __disable_irq();                                                \
                }

/* This macro enables all interrupts */
#define         ESAL_TS_RTE_CPSIE_EXECUTE()                                         \
                {                                                                   \
                    __enable_irq();                                                 \
                }

/* This macro executes a ISB instruction */
#define         ESAL_TS_RTE_ISB_EXECUTE()                                           \
                {                                                                   \
                    __asm                                                           \
                    {                                                               \
                        ISB                                                         \
                    }                                                               \
                }

/* This macro executes a DSB instruction */
#define         ESAL_TS_RTE_DSB_EXECUTE()                                           \
                {                                                                   \
                    __asm                                                           \
                    {                                                               \
                        NOP                                                         \
                    }                                                               \
                }

/* This macro executes a NOP instruction */
#define         ESAL_TS_RTE_NOP_EXECUTE()                                           \
                {                                                                   \
                    __asm                                                           \
                    {                                                               \
                        NOP                                                         \
                    }                                                               \
                }

/* This macro executes a WFI instruction */
#define         ESAL_TS_RTE_WFI_EXECUTE()   __wfi()

/* This macro executes a breakpoint instruction
   NOTE:  This instruction is only usable by ARM v5 cores. */
#define         ESAL_TS_RTE_BRK_EXECUTE(brk_point_val)                              \
                {                                                                   \
                    /* Call function - BKPT not allowed in inline asm */            \
                    ESAL_TS_RTE_BRK_Execute(brk_point_val);                         \
                }

#if (ESAL_TS_PIC_PID_SUPPORT == NU_TRUE)

/* Reserve an AAPCS callee-saved register (v6 = r9) for use by position-independent code (PIC)
   and position-independent data (PID).  */
__global_reg(6) UINT32 ESAL_TS_RTE_PIC_Base;

/* This macro sets the PIC/PID base address register */
#define         ESAL_TS_RTE_PIC_PID_BASE_SET(pic_base, pid_base)                    \
                {                                                                   \
                    /* Access unused param */                                       \
                    NU_UNUSED_PARAM(pic_base);                                    \
                                                                                    \
                    /* Set the PIC/PID register (r9) */                             \
                    ESAL_TS_RTE_PIC_Base = (UINT32)pid_base;                        \
                }

/* This macro gets the PIC/PID base address register */
#define         ESAL_TS_RTE_PIC_PID_BASE_GET(pic_base_ptr, pid_base_ptr)            \
                {                                                                   \
                    UINT32 *temp32_ptr = (UINT32 *)pid_base_ptr;                    \
                                                                                    \
                    /* Access unused param */                                       \
                    NU_UNUSED_PARAM(pic_base_ptr);                                \
                                                                                    \
                    /* Read the PIC/PID register (r9) */                            \
                    *temp32_ptr = ESAL_TS_RTE_PIC_Base;                             \
                }

#endif  /* ESAL_TS_PIC_PID_SUPPORT == NU_TRUE */

/* This macro defines a symbol declaration as weakly linked */
#define         ESAL_TS_WEAK_REF(decl) __weak decl

/* This macro marks a symbol definition as weakly linked */
#define         ESAL_TS_WEAK_DEF(decl) __weak decl

/* This macro returns the passed value */
#define         ESAL_TS_NO_RETURN(return_val)

/* This macro generates deprecation warnings */
#define         ESAL_TS_RTE_DEPRECATED __attribute__((deprecated))

/* This macro places a compiler memory barrier to ensure read / write commands
 * cannot be re-ordered around it */
#define         ESAL_TS_RTE_COMPILE_MEM_BARRIER()   __schedule_barrier()

#endif  /* RVCT_ARM_DEFS_H */

