/***********************************************************************
*
*             Copyright 2011 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
*
*       sh_defs.h
*
*   DESCRIPTION
*
*       This file contains all definitions, structures, etc for the
*       Renesas SuperH architecture.
*
*   DATA STRUCTURES
*
*       None
*
*   DEPENDENCIES
*
*       None
*
***********************************************************************/

#ifndef         SUPERH_DEFS_H
#define         SUPERH_DEFS_H

/* Define if the OS timer is part of the architecture (NU_TRUE)
   NOTE:  The OS timer can be located at only one of the following levels of
          abstraction: the processor level or the architecture level. 
          If ESAL_AR_OS_TIMER_USED is NU_TRUE, the OS timer is contained
          within the architecture.  If ESAL_AR_OS_TIMER_USED is NU_FALSE,
          the OS timer is contained within the processor component. */
#define         ESAL_AR_OS_TIMER_USED                   NU_FALSE

/* Define if architecture supports unaligned 16-bit accesses to memory. */
#define         ESAL_AR_UNALIGNED_16BIT_SPT             NU_FALSE

/* Define if architecture supports unaligned 32-bit accesses to memory. */
#define         ESAL_AR_UNALIGNED_32BIT_SPT             NU_FALSE

/* Define number of accesses required to read or write a pointer */
#define         ESAL_AR_PTR_ACCESS                      1

/* Define number of accesses required to read or write a 32-bit value */
#define         ESAL_AR_32BIT_ACCESS                    1

/* Size, in bytes, of architecture system stack.  This stack will be
   utilized when servicing interrupts. */
#define         ESAL_AR_SYSTEM_STACK_SIZE               1024

/* Size, in bytes, of architecture exception stack.  This stack will be
   utilized when servicing exceptions. */
#define         ESAL_AR_EXCEPTION_STACK_SIZE            0

/* Define if interrupt servicing initialization is required at the 
   architecture level. */
#define         ESAL_AR_ISR_INIT_REQUIRED               NU_FALSE

/* Define if architecture mandates that all interrupt handlers perform a
   "return from interrupt" (RTI) instruction in order for the hardware to
   correctly restore the state of execution to the pre-interrupt condition.
   NOTE:  Most architectures allow the state of execution to be restored 
          without needing to perform an RTI.  In most cases, this will be set 
          to NU_FALSE */
#define         ESAL_AR_ISR_RTI_MANDATORY               NU_FALSE

/* Determines where the ISR nesting counter is incremented.  
   When set to 0 the increment occurs in assembly files, when 
   set to 1 the increment will occur in c files. */
#define         ESAL_AR_ISR_INCREMENT_IN_C              NU_TRUE

/* Define bit values for the architecture's status register / machine state register /
   etc that are used to enable and disable interrupts for the given architecture. */
#define         ESAL_AR_INTERRUPTS_DISABLE_BITS         0x000000F0
#define         ESAL_AR_INTERRUPTS_ENABLE_BITS          0x00000000

/* Define if floating point registers will be saved during context switches
   NOTE:  The assembly define must be changed in esal_ar_stk_defs.inc to
          match this define
   NOTE:  This define will dictate what registers are contained
          within solicited (TS) and unsolicited (AR) stack frames. */
#define         ESAL_AR_STK_FPU_SUPPORT                 NU_TRUE

/* Define number of single-precision floating point registers */
#define         ESAL_AR_STK_NUM_FPU_REGS                16

#define         ESAL_TS_RTE_DEPRECATED
/* Define stack frame structure for minimum architecture registers required
   to be saved in order to enter a C environment during in interrupt / exception.
   These registers are the "scratch" registers that will not be preserved across 
   a function call boundary and any interrupt state registers that must preserved
   to allow interrupt nesting. */
typedef struct
{
    UINT32              r0;
    UINT32              r1;
    UINT32              r2;
    UINT32              r3;
    UINT32              r5;
    UINT32              r6;
    UINT32              r7;
    UINT32              pr;
    UINT32              r4;    
    UINT32              rtn_address;
    UINT32              sr;    

} ESAL_AR_STK_MIN;

/* Define stack frame structure for the architecture supported. 
   This stack frame contains all registers that must be preserved
   across an (unsolicited) interrupt context switch.
   NOTE:  This stack frame includes the minimum stack frame
          defined above AND all other registers for the given
          architecture. */
typedef struct  ESAL_AR_STK_STRUCT
{
    UINT32              stack_type;
    UINT32              r8;
    UINT32              r9;
    UINT32              r10;
    UINT32              r11;
    UINT32              r12;
    UINT32              r13;
    UINT32              r14;
    UINT32              gbr;
    UINT32              mach;
    UINT32              macl;

#if (ESAL_AR_STK_FPU_SUPPORT == NU_TRUE)

    UINT32              fpscr;
    UINT32              fpr[ESAL_AR_STK_NUM_FPU_REGS];

#endif  /* ESAL_AR_STK_FPU_SUPPORT == NU_TRUE */

    ESAL_AR_STK_MIN     min_stack;

} ESAL_AR_STK;

/* The following definitions / macros / etc are only used if the architecture
   is configured (in esal_ar_cfg.h) to use an architecture level timer for
   the OS timer. */
#if (ESAL_AR_OS_TIMER_USED == NU_TRUE)

#error  No Architecture level timer exists for SH1/2.

#endif  /* ESAL_AR_OS_TIMER_USED == NU_TRUE */

/* Base address for Interrupt Control Register 0 (ICR0) */
#define         ESAL_AR_INT_ICR0_BASE_ADDR              (ESAL_PR_INT_BASE_ADDR +    \
                                                         ESAL_PR_INT_ICR0_OFFSET)
/* Define core cache availability
   NOTE:  A differentiation is made in ESAL between cache that
          is contained on a processor and cache that is
          inherent as part of a core (L2 vs L1 cache). */
#define         ESAL_CO_CACHE_AVAILABLE                 NU_TRUE

/* Define cache related register addresses */
#define         ESAL_CO_MEM_CCR1_ADDR                   (ESAL_DP_PERIPH_BASE + 0x1000)
#define         ESAL_CO_MEM_CCR2_ADDR                   (ESAL_DP_PERIPH_BASE + 0x1004)

/* Define bits for CCR1 */
#define         ESAL_CO_MEM_CCR1_ICF_BIT                ESAL_GE_MEM_32BIT_SET(11)
#define         ESAL_CO_MEM_CCR1_ICE_BIT                ESAL_GE_MEM_32BIT_SET(8)
#define         ESAL_CO_MEM_CCR1_OCF_BIT                ESAL_GE_MEM_32BIT_SET(3)
#define         ESAL_CO_MEM_CCR1_WT_BIT                 ESAL_GE_MEM_32BIT_SET(1)
#define         ESAL_CO_MEM_CCR1_OCE_BIT                ESAL_GE_MEM_32BIT_SET(0)

/* Define ESAL interrupt vector IDs for this architecture.
   These IDs match up with architecture interrupts.
   Values correspond to the index of entries in ESAL_GE_ISR_Interrupt_Handler[].
   Names are of the form ESAL_AR_<Name>_INT_VECTOR_ID, where <Name> comes
   directly from the hardware documentation */
#define         ESAL_AR_NMI_INT_VECTOR_ID               0
#define         ESAL_AR_USER_BREAK_INT_VECTOR_ID        1

/* Define the last ESAL interrupt vector ID for this architecture + 1 */
#define         ESAL_AR_INT_VECTOR_ID_DELIMITER         (ESAL_AR_USER_BREAK_INT_VECTOR_ID + 1)

/* Define ESAL exception vector IDs for the architecture.
   These IDs match up with architecture exceptions.
   Values correspond to the index of entries in ESAL_GE_ISR_Exception_Handler[].
   Names are of the form ESAL_AR_<Name>_EXCEPT_VECTOR_ID, where <Name> comes
   directly from the hardware documentation */
#define         ESAL_AR_GEN_ILLEGAL_INST_EXCEPT_VECTOR_ID   0
#define         ESAL_AR_RAM_ERROR_EXCEPT_VECTOR_ID          1
#define         ESAL_AR_SLOT_ILLEGAL_INST_EXCEPT_VECTOR_ID  2
#define         ESAL_AR_CPU_ADDR_ERROR_EXCEPT_VECTOR_ID     3
#define         ESAL_AR_BUS_ERROR_EXCEPT_VECTOR_ID          4
#define         ESAL_AR_FPU_EXCEPTION_EXCEPT_VECTOR_ID      5
#define         ESAL_AR_HUDI_EXCEPT_VECTOR_ID               6
#define         ESAL_AR_BANK_OVERFLOW_EXCEPT_VECTOR_ID      7
#define         ESAL_AR_BANK_UNDERFLOW_EXCEPT_VECTOR_ID     8
#define         ESAL_AR_INTEGER_DIV_BY_0_EXCEPT_VECTOR_ID   9
#define         ESAL_AR_INTEGER_OVERFLOW_EXCEPT_VECTOR_ID   10
#define         ESAL_AR_TRAP_0_EXCEPT_VECTOR_ID             11
#define         ESAL_AR_TRAP_1_EXCEPT_VECTOR_ID             12
#define         ESAL_AR_TRAP_2_EXCEPT_VECTOR_ID             13
#define         ESAL_AR_TRAP_3_EXCEPT_VECTOR_ID             14
#define         ESAL_AR_TRAP_4_EXCEPT_VECTOR_ID             15
#define         ESAL_AR_TRAP_5_EXCEPT_VECTOR_ID             16
#define         ESAL_AR_TRAP_6_EXCEPT_VECTOR_ID             17
#define         ESAL_AR_TRAP_7_EXCEPT_VECTOR_ID             18
#define         ESAL_AR_TRAP_8_EXCEPT_VECTOR_ID             19
#define         ESAL_AR_TRAP_9_EXCEPT_VECTOR_ID             20
#define         ESAL_AR_TRAP_10_EXCEPT_VECTOR_ID            21
#define         ESAL_AR_TRAP_11_EXCEPT_VECTOR_ID            22
#define         ESAL_AR_TRAP_12_EXCEPT_VECTOR_ID            23
#define         ESAL_AR_TRAP_13_EXCEPT_VECTOR_ID            24
#define         ESAL_AR_TRAP_14_EXCEPT_VECTOR_ID            25
#define         ESAL_AR_TRAP_15_EXCEPT_VECTOR_ID            26
#define         ESAL_AR_TRAP_16_EXCEPT_VECTOR_ID            27
#define         ESAL_AR_TRAP_17_EXCEPT_VECTOR_ID            28
#define         ESAL_AR_TRAP_18_EXCEPT_VECTOR_ID            29
#define         ESAL_AR_TRAP_19_EXCEPT_VECTOR_ID            30
#define         ESAL_AR_TRAP_20_EXCEPT_VECTOR_ID            31
#define         ESAL_AR_TRAP_21_EXCEPT_VECTOR_ID            32
#define         ESAL_AR_TRAP_22_EXCEPT_VECTOR_ID            33
#define         ESAL_AR_TRAP_23_EXCEPT_VECTOR_ID            34
#define         ESAL_AR_TRAP_24_EXCEPT_VECTOR_ID            35
#define         ESAL_AR_TRAP_25_EXCEPT_VECTOR_ID            36
#define         ESAL_AR_TRAP_26_EXCEPT_VECTOR_ID            37
#define         ESAL_AR_TRAP_27_EXCEPT_VECTOR_ID            38
#define         ESAL_AR_TRAP_28_EXCEPT_VECTOR_ID            39
#define         ESAL_AR_TRAP_29_EXCEPT_VECTOR_ID            40
#define         ESAL_AR_TRAP_30_EXCEPT_VECTOR_ID            41
#define         ESAL_AR_TRAP_31_EXCEPT_VECTOR_ID            42

/* Define the last ESAL exception vector ID for this architecture + 1 */
#define         ESAL_AR_EXCEPT_VECTOR_ID_DELIMITER          (ESAL_AR_TRAP_31_EXCEPT_VECTOR_ID + 1)

/* Define variable(s) required to save / restore architecture interrupt state.
   These variable(s) are used in conjunction with the ESAL_AR_INT_ALL_DISABLE() and
   ESAL_AR_INT_ALL_RESTORE() macros to hold any data that must be preserved in
   order to allow these macros to function correctly. */
#define         ESAL_AR_INT_CONTROL_VARS            INT  esal_ar_int_tmp;

/* This macro locks out interrupts and saves the current
   architecture status register / state register to the specified
   address.  This function does not attempt to mask any bits in
   the return register value and can be used as a quick method
   to guard a critical section.
   NOTE:  This macro is used in conjunction with ESAL_AR_INT_ALL_RESTORE
          defined below and ESAL_AR_INT_CONTROL_VARS defined above. */
#define         ESAL_AR_INT_ALL_DISABLE()                                       \
                {                                                               \
                    ESAL_TS_RTE_SR_READ(&esal_ar_int_tmp);                      \
                    ESAL_TS_RTE_SR_WRITE(ESAL_AR_INTERRUPTS_DISABLE_BITS);      \
                }

/* This macro restores the architecture status / state register
   used to lockout interrupts to the value provided.  The
   intent of this function is to be a fast mechanism to restore the
   interrupt level at the end of a critical section to its
   original level.
   NOTE:  This macro is used in conjunction with ESAL_AR_INT_ALL_DISABLE
          and ESAL_AR_INT_CONTROL_VARS defined above. */
#define         ESAL_AR_INT_ALL_RESTORE()                                       \
                {                                                               \
                    ESAL_TS_RTE_SR_WRITE(esal_ar_int_tmp);                      \
                }

/* This macro locks-out interrupts but doesn't save the status
   register / control register value. */
#define         ESAL_AR_INT_FAST_ALL_DISABLE()                                  \
                {                                                               \
                    ESAL_TS_RTE_SR_WRITE(ESAL_AR_INTERRUPTS_DISABLE_BITS);      \
                }

/* This macro unlocks interrupts but doesn't save the status
   register / control register value. */
#define         ESAL_AR_INT_FAST_ALL_ENABLE()                                   \
                {                                                               \
                    ESAL_TS_RTE_SR_WRITE(ESAL_AR_INTERRUPTS_ENABLE_BITS);       \
                }

/* This macro sets the interrupt related bits in the status register / control
   register to the specified value. */
#define         ESAL_AR_INT_BITS_SET(set_bits)                                  \
                {                                                               \
                    INT     tmp_val;                                            \
                                                                                \
                    ESAL_TS_RTE_SR_READ(&tmp_val);                              \
                    tmp_val &= ~ESAL_AR_INTERRUPTS_DISABLE_BITS;                \
                    tmp_val |= set_bits;                                        \
                    ESAL_TS_RTE_SR_WRITE(tmp_val);                              \
                }

/* This macro gets the interrupt related bits from the status register / control
   register. */
#define         ESAL_AR_INT_BITS_GET(get_bits_ptr)                              \
                {                                                               \
                    INT     tmp_val;                                            \
                                                                                \
                    ESAL_TS_RTE_SR_READ(&tmp_val);                              \
                    tmp_val &= ESAL_AR_INTERRUPTS_DISABLE_BITS;                 \
                    *get_bits_ptr = tmp_val;                                    \
                }

#if (ESAL_CO_CACHE_AVAILABLE == NU_TRUE)

/* This macro invalidates all of the cache at the core level. */
#define         ESAL_CO_MEM_CACHE_ALL_INVALIDATE()                          \
                {                                                           \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        (ESAL_CO_MEM_CCR1_ICF_BIT |         \
                                         ESAL_CO_MEM_CCR1_OCF_BIT));        \
                }

/* This macro invalidates all of the instruction cache at the core level. */
#define         ESAL_CO_MEM_ICACHE_ALL_INVALIDATE()                         \
                {                                                           \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        ESAL_CO_MEM_CCR1_ICF_BIT);          \
                }

/* This macro invalidates all of the data cache at the core level. */
#define         ESAL_CO_MEM_DCACHE_ALL_INVALIDATE()                         \
                {                                                           \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        ESAL_CO_MEM_CCR1_OCF_BIT);          \
                }

/* This macro invalidates all instruction cache for the specified address
   range at the core level. */
#define         ESAL_CO_MEM_ICACHE_INVALIDATE(addr, size)                   \
                {                                                           \
                    /* Invalidate by address is not avaliable, */           \
                    /* so invalidate all. */                                \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        ESAL_CO_MEM_CCR1_ICF_BIT);          \
                }

/* This macro invalidates all data cache for the specified address
   range at the core level. */
#define         ESAL_CO_MEM_DCACHE_INVALIDATE(addr, size)                   \
                {                                                           \
                    /* Invalidate by address is not avaliable, */           \
                    /* so invalidate all. */                                \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        ESAL_CO_MEM_CCR1_OCF_BIT);          \
                }

/* This macro flushes all data cache to physical memory (writeback cache)
   and invalidates all data cache entries at the core level. */
#define         ESAL_CO_MEM_DCACHE_ALL_FLUSH_INVAL()                        \
                {                                                           \
                    /* Data cache can not be flushed in this core, */       \
                    /* so invalidated all data cache without flusing. */    \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        ESAL_CO_MEM_CCR1_OCF_BIT);          \
                }

/* This macro flushes all data cache to physical memory (writeback cache)
   for the given address range, then invalidates all data cache entries
   at the core level. */
#define         ESAL_CO_MEM_DCACHE_FLUSH_INVAL(addr, size)                  \
                {                                                           \
                    /* Invalidate and flush by address is not avaliable, */ \
                    /* so invalidate all. */                                \
                    ESAL_GE_MEM_WRITE32(ESAL_CO_MEM_CCR1_ADDR,              \
                                        ESAL_CO_MEM_CCR1_OCF_BIT);          \
                }

#endif  /* ESAL_CO_CACHE_AVAILABLE == NU_TRUE */

#endif  /* SUPERH_DEFS_H */

