#***********************************************************************
#*
#*             Copyright 2012 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
#*
#*      tensilica_defs.inc
#*
#*  DESCRIPTION
#*
#*      This file contains the architecture specific definitions,
#*      constants, etc, for Tensilica
#*
#*  DATA STRUCTURES
#*
#*      None
#*
#*  DEPENDENCIES
#*
#*      None
#*
#***********************************************************************

#include <xtensa/config/core.h>

/* Define xtensa architecture stack frame size 
 * NOTE : Size must be a 16-byte multiple to keep stacks 16-byte aligned */
#define         ESAL_AR_STK_FRAME_SIZE            (((0x74 + XCHAL_NCP_SA_SIZE) + 15) & (~0xF))

/* Define size of register spill save area in bytes */
#define         ESAL_AR_STK_SAVE_AREA_SIZE        16

/* Define bit mask to clear PS.INTLEVEL field */
#define         ESAL_AR_STK_PS_INTLEVEL_CLEAR      (~(PS_INTLEVEL_MASK))

/* Define xtensa architecture stack frame offsets */
#define         ESAL_AR_STK_OFFSET_TYPE           0x00     /* 0 (solicited) or dispatch return PC */
#define         ESAL_AR_STK_OFFSET_PC             0x04
#define         ESAL_AR_STK_OFFSET_PS             0x08
#define         ESAL_AR_STK_OFFSET_A0             0x0C
#define         ESAL_AR_STK_OFFSET_A1             0x10
#define         ESAL_AR_STK_OFFSET_A2             0x14
#define         ESAL_AR_STK_OFFSET_A3             0x18
#define         ESAL_AR_STK_OFFSET_A4             0x1C
#define         ESAL_AR_STK_OFFSET_A5             0x20
#define         ESAL_AR_STK_OFFSET_A6             0x24
#define         ESAL_AR_STK_OFFSET_A7             0x28
#define         ESAL_AR_STK_OFFSET_A8             0x2C
#define         ESAL_AR_STK_OFFSET_A9             0x30
#define         ESAL_AR_STK_OFFSET_A10            0x34
#define         ESAL_AR_STK_OFFSET_A11            0x38
#define         ESAL_AR_STK_OFFSET_A12            0x3C
#define         ESAL_AR_STK_OFFSET_A13            0x40
#define         ESAL_AR_STK_OFFSET_A14            0x44
#define         ESAL_AR_STK_OFFSET_A15            0x48
#define         ESAL_AR_STK_OFFSET_SAR            0x4C
#define         ESAL_AR_STK_OFFSET_LBEG           0x50    /* Loop option only */
#define         ESAL_AR_STK_OFFSET_LEND           0x54    /* Loop option only */
#define         ESAL_AR_STK_OFFSET_LCOUNT         0x58    /* Loop option only */
#define         ESAL_AR_STK_OFFSET_EXCCAUSE       0x5C    /* temp: EXCCAUSE register value */
#define         ESAL_AR_STK_OFFSET_THISLEVEL      0x60    /* temp: mask of interrupts at this level */
#define         ESAL_AR_STK_OFFSET_PS_C           0x64    /* temp: PS value to use for C code */
#define         ESAL_AR_STK_OFFSET_EXTRA          0x70    /* Extra register save base offset */

/* Define architecture ESAL interrupt vector IDs.
   These IDs match up with architecture interrupt Levels.
   Values correspond to the index of entries in ESAL_GE_ISR_Interrupt_Handler[]. */

#define         ESAL_AR_LEVEL1_INT_VECTOR_ID      0
#define         ESAL_AR_LEVEL2_INT_VECTOR_ID      1
#define         ESAL_AR_LEVEL3_INT_VECTOR_ID      2
#define         ESAL_AR_LEVEL4_INT_VECTOR_ID      3
#define         ESAL_AR_LEVEL5_INT_VECTOR_ID      4
#define         ESAL_AR_LEVEL6_INT_VECTOR_ID      5
#define         ESAL_AR_LEVEL7_INT_VECTOR_ID      6

/* Define to allow conditional assembling of lowlevel ISR hook.
   Setting this to TRUE will allow a low-level hook to be executed in the
   interrupt handlers */

#define         ESAL_AR_ISR_HOOK_ENABLED         0

#***********************************************************************
#* ESAL_AR_STK_MIN_INT_SAVE
#*
#* Save minimal amount of registers required for handling interrupts.
#* ESAL_AR_STK_Unsolicited_Switch() will save the rest.
#***********************************************************************

    .macro ESAL_AR_STK_MIN_SAVE

    s32i    a0, a3, ESAL_AR_STK_OFFSET_A0
    s32i    a1, a3, ESAL_AR_STK_OFFSET_A1
    s32i    a2, a3, ESAL_AR_STK_OFFSET_A2

    .endm

    .macro ESAL_AR_STK_FULL_SAVE

    s32i    a4, a3, ESAL_AR_STK_OFFSET_A4
    s32i    a5, a3, ESAL_AR_STK_OFFSET_A5
    s32i    a6, a3, ESAL_AR_STK_OFFSET_A6
    s32i    a7, a3, ESAL_AR_STK_OFFSET_A7
    s32i    a8, a3, ESAL_AR_STK_OFFSET_A8
    s32i    a9, a3, ESAL_AR_STK_OFFSET_A9
    s32i    a10, a3, ESAL_AR_STK_OFFSET_A10
    s32i    a11, a3, ESAL_AR_STK_OFFSET_A11
    s32i    a12, a3, ESAL_AR_STK_OFFSET_A12
    s32i    a13, a3, ESAL_AR_STK_OFFSET_A13
    s32i    a14, a3, ESAL_AR_STK_OFFSET_A14
    s32i    a15, a3, ESAL_AR_STK_OFFSET_A15

    #if XCHAL_HAVE_LOOPS

    rsr     a0, LBEG
    s32i    a0, a3, ESAL_AR_STK_OFFSET_LBEG
    rsr     a0, LEND
    s32i    a0, a3, ESAL_AR_STK_OFFSET_LEND
    rsr     a0, LCOUNT
    s32i    a0, a3, ESAL_AR_STK_OFFSET_LCOUNT

    #endif

    .endm

#***********************************************************************
#* ESAL_AR_STK_MIN_INT_RESTORE
#*
#* Restore minimal amount of registers required for handling interrupts.
#***********************************************************************

    .macro ESAL_AR_STK_MIN_RESTORE

    l32i    a0, a3, ESAL_AR_STK_OFFSET_A0
    l32i    a1, a3, ESAL_AR_STK_OFFSET_A1
    l32i    a2, a3, ESAL_AR_STK_OFFSET_A2
    l32i    a3, a3, ESAL_AR_STK_OFFSET_A3

    .endm

    .macro ESAL_AR_STK_FULL_RESTORE

    #if XCHAL_HAVE_LOOPS

    l32i    a4, a3, ESAL_AR_STK_OFFSET_LBEG
    wsr     a4, LBEG
    l32i    a4, a3, ESAL_AR_STK_OFFSET_LEND
    wsr     a4, LEND
    l32i    a4, a3, ESAL_AR_STK_OFFSET_LCOUNT
    wsr     a4, LCOUNT

    #endif

    l32i    a4, a3, ESAL_AR_STK_OFFSET_A4
    l32i    a5, a3, ESAL_AR_STK_OFFSET_A5
    l32i    a6, a3, ESAL_AR_STK_OFFSET_A6
    l32i    a7, a3, ESAL_AR_STK_OFFSET_A7
    l32i    a8, a3, ESAL_AR_STK_OFFSET_A8
    l32i    a9, a3, ESAL_AR_STK_OFFSET_A9
    l32i    a10, a3, ESAL_AR_STK_OFFSET_A10
    l32i    a11, a3, ESAL_AR_STK_OFFSET_A11
    l32i    a12, a3, ESAL_AR_STK_OFFSET_A12
    l32i    a13, a3, ESAL_AR_STK_OFFSET_A13
    l32i    a14, a3, ESAL_AR_STK_OFFSET_A14
    l32i    a15, a3, ESAL_AR_STK_OFFSET_A15

    .endm

/* Define stack frame size for the toolset / architecture supported. 
 * NOTE : Size must be a 16-byte multiple to keep stacks 16-byte aligned */
#define         ESAL_TS_STK_SIZE            (((0x20 + XCHAL_NCP_SA_SIZE) + 15) & (~0xF))

/* Define xtensa stack frame offsets */
#define         ESAL_TS_STK_OFFSET_TYPE           0x0
#define         ESAL_TS_STK_OFFSET_A0             0x4
#define         ESAL_TS_STK_OFFSET_A12            0x8
#define         ESAL_TS_STK_OFFSET_A13            0xC
#define         ESAL_TS_STK_OFFSET_A14            0x10
#define         ESAL_TS_STK_OFFSET_A15            0x14
#define         ESAL_TS_STK_OFFSET_EXTRA          0x20    /* Extra register save base offset */

