/***********************************************************************
*
*             Copyright 2006 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
*
*       csgnu_ppc_defs.h
*
*   DESCRIPTION
*
*       This file contains all definitions, structures, etc for the
*       CS GNU for PPC toolset
*
*   DATA STRUCTURES
*
*       None
*
*   DEPENDENCIES
*
*       None
*
***********************************************************************/

#ifndef         CSGNU_PPC_DEFS_H
#define         CSGNU_PPC_DEFS_H

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

/* Define maximum type alignment for the given toolset.*/
#define         ESAL_TS_MAX_TYPE_ALIGNMENT              ESAL_TS_REQ_STK_ALIGNMENT

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

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

/* Defines, 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 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

/* Defines used to enforce alignment of data structure members (if necessary). */


/* 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   _ld_rom_data_start;
extern UINT32   _ld_ram_data_start;
extern UINT32   _ld_ram_data_end;
extern UINT32   _ld_ram_sdata2_start;
extern UINT32   _ld_ram_sdata2_end;
extern UINT32   _ld_ram_sdata_start;
extern UINT32   _ld_ram_sdata_end;
extern UINT32   _ld_bss_start;
extern UINT32   _ld_bss_end;

/* Macros for memory definitions */
#define         TOOLSET_DATA_START_ADDR     (VOID *)&_ld_ram_data_start
#define         TOOLSET_DATA_END_ADDR       (VOID *)&_ld_ram_data_end
#define         TOOLSET_DATA_SIZE           ((UINT32)&_ld_ram_data_end - (UINT32)&_ld_ram_data_start)
#define         TOOLSET_SDATA2_START_ADDR   (VOID *)&_ld_ram_sdata2_start
#define         TOOLSET_SDATA2_END_ADDR     (VOID *)&_ld_ram_sdata2_end
#define         TOOLSET_SDATA2_SIZE         ((UINT32)&_ld_ram_sdata2_end - (UINT32)&_ld_ram_sdata2_start)
#define         TOOLSET_SDATA_START_ADDR    (VOID *)&_ld_ram_sdata_start
#define         TOOLSET_SDATA_END_ADDR      (VOID *)&_ld_ram_sdata_end
#define         TOOLSET_SDATA_SIZE          ((UINT32)&_ld_ram_sdata_end - (UINT32)&_ld_ram_sdata_start)
#define         TOOLSET_BSS_START_ADDR      (VOID *)&_ld_bss_start
#define         TOOLSET_BSS_END_ADDR        (VOID *)&_ld_bss_end
#define         TOOLSET_BSS_SIZE            ((UINT32)&_ld_bss_end - (UINT32)&_ld_bss_start)

/* Macros for ROM-to-RAM copy */
#define         TOOLSET_DATA_SRC_ADDR       (VOID *)&_ld_rom_data_start
#define         TOOLSET_DATA_DST_ADDR       TOOLSET_DATA_START_ADDR

/* This define is used to add quotes to anything passed in */
#define         ESAL_TS_RTE_QUOTES(x)                   #x

/* Define PPC Architecture SPR register numbers */
#define         ESAL_TS_RTE_DEC                         22
#define         ESAL_TS_RTE_TBL_READ                    268
#define         ESAL_TS_RTE_TBU_READ                    269
#define         ESAL_TS_RTE_SPRG0                       272
#define         ESAL_TS_RTE_SPRG1                       273
#define         ESAL_TS_RTE_SPRG2                       274
#define         ESAL_TS_RTE_SPRG3                       275
#define         ESAL_TS_RTE_TBL_WRITE                   284
#define         ESAL_TS_RTE_TBU_WRITE                   285
#define         ESAL_TS_RTE_PIR                         286
#define         ESAL_TS_RTE_IBAT0U                      528
#define         ESAL_TS_RTE_IBAT0L                      529
#define         ESAL_TS_RTE_IBAT1U                      530
#define         ESAL_TS_RTE_IBAT1L                      531
#define         ESAL_TS_RTE_IBAT2U                      532
#define         ESAL_TS_RTE_IBAT2L                      533
#define         ESAL_TS_RTE_IBAT3U                      534
#define         ESAL_TS_RTE_IBAT3L                      535
#define         ESAL_TS_RTE_DBAT0U                      536
#define         ESAL_TS_RTE_DBAT0L                      537
#define         ESAL_TS_RTE_DBAT1U                      538
#define         ESAL_TS_RTE_DBAT1L                      539
#define         ESAL_TS_RTE_DBAT2U                      540
#define         ESAL_TS_RTE_DBAT2L                      541
#define         ESAL_TS_RTE_DBAT3U                      542
#define         ESAL_TS_RTE_DBAT3L                      543
#define         ESAL_TS_RTE_IVPR                        63
#define         ESAL_TS_RTE_IVOR0                       400
#define         ESAL_TS_RTE_IVOR1                       401
#define         ESAL_TS_RTE_IVOR2                       402
#define         ESAL_TS_RTE_IVOR3                       403
#define         ESAL_TS_RTE_IVOR4                       404
#define         ESAL_TS_RTE_IVOR5                       405
#define         ESAL_TS_RTE_IVOR6                       406
#define         ESAL_TS_RTE_IVOR7                       407
#define         ESAL_TS_RTE_IVOR8                       408
#define         ESAL_TS_RTE_IVOR9                       409
#define         ESAL_TS_RTE_IVOR10                      410
#define         ESAL_TS_RTE_IVOR11                      411
#define         ESAL_TS_RTE_IVOR12                      412
#define         ESAL_TS_RTE_IVOR13                      413
#define         ESAL_TS_RTE_IVOR14                      414
#define         ESAL_TS_RTE_IVOR15                      415

/* IVOR16 to IVOR31 are Reserved for future architectural in the e500 core      */
#define         ESAL_TS_RTE_IVOR32                      528     /* SPE Not Avail    */
#define         ESAL_TS_RTE_IVOR33                      529     /* EFP Data Excpt   */
#define         ESAL_TS_RTE_IVOR34                      530     /* EFP Round Excpt  */
#define         ESAL_TS_RTE_IVOR35                      531     /* Perform Monitor  */
#define         ESAL_TS_RTE_MAS0                    624
#define         ESAL_TS_RTE_MAS1                    625
#define         ESAL_TS_RTE_MAS2                    626
#define         ESAL_TS_RTE_MAS3                    627
#define         ESAL_TS_RTE_MAS4                    628
#define         ESAL_TS_RTE_MAS5                    629
#define         ESAL_TS_RTE_MAS6                    630
#define         ESAL_TS_RTE_MAS7                    944


/* This macro writes the stack pointer. */
#define         ESAL_TS_RTE_SP_WRITE(stack_ptr)                                     \
                {                                                                   \
                    asm volatile(" mr 1, %0 " : : "r" (stack_ptr));                 \
                }

/* This macro gets the stack pointer. */
#define         ESAL_TS_RTE_SP_READ()                                               \
                ({                                                                  \
                    UINT32 stack_reg;                                               \
                    asm volatile(" mr %0, 1 " : "=r" (stack_reg));                  \
                    stack_reg;                                                      \
                })

/* Read Decrementer */
#define         ESAL_TS_RTE_DEC_READ()                                              \
                ({                                                                  \
                    UINT32 dec_reg;                                                 \
                    asm volatile(" mfspr %0, 22 " : "=r" (dec_reg));                \
                    dec_reg;                                                        \
                })

/* Write Decrementer */
#define         ESAL_TS_RTE_DEC_WRITE(value)                                        \
                {                                                                   \
                    asm volatile(" mtspr 22, %0 " : : "r" (value));                 \
                }

/* Read the FPSCR register */
#define         ESAL_TS_RTE_FPSCR_READ(fpscr_val_ptr)                               \
                {                                                                   \
                    asm volatile( " mffs %0 " : "=r" (*(fpscr_val_ptr)));           \
                }

/* Read the MSR register */
#define         ESAL_TS_RTE_MSR_READ(msr_val_ptr)                                   \
                {                                                                   \
                    asm volatile(" mfmsr %0 " : "=r" (*(msr_val_ptr)));             \
                }

/* Write the MSR register */
#define         ESAL_TS_RTE_MSR_WRITE(msr_val)                                      \
                {                                                                   \
                    asm volatile(" mtmsr  %0 " : : "r" (msr_val));                  \
                }

/* Read an SPR register */
#define         ESAL_TS_RTE_SPR_READ(spr_num, spr_val_ptr)                          \
                {                                                                   \
                    asm volatile(" mfspr %0, " ESAL_TS_RTE_QUOTES(spr_num)          \
                                                : "=r" (*(spr_val_ptr)) : );        \
                }

/* Write to an SPR register */
#define         ESAL_TS_RTE_SPR_WRITE(spr_num, spr_val)                             \
                {                                                                   \
                    asm volatile(" mtspr " ESAL_TS_RTE_QUOTES(spr_num) ", %0 "      \
                                                : : "r" (spr_val));                 \
                }

/* Instruction Cache Block Invalidate */
#define         ESAL_TS_RTE_ICBI_EXECUTE(addr, addr_offset)                         \
                {                                                                   \
                    asm volatile(" icbi %0, %1 " : :                                \
                                                "r" (addr), "r" (addr_offset));     \
                }

/* Data Cache Block Invalidate */
#define         ESAL_TS_RTE_DCBI_EXECUTE(addr, addr_offset)                         \
                {                                                                   \
                    asm volatile(" dcbi  %0, %1 " : :                               \
                                                "r" (addr), "r" (addr_offset));     \
                }

/* Data Cache Block Flush */
#define         ESAL_TS_RTE_DCBF_EXECUTE(addr, addr_offset)                         \
                {                                                                   \
                    asm volatile(" dcbf  %0, %1 " : :                               \
                                                "r" (addr), "r" (addr_offset));     \
                }

/* Sync command to sync memory */
#define         ESAL_TS_RTE_SYNC_EXECUTE()                                          \
                {                                                                   \
                    asm volatile(" sync");                                          \
                }

/* Instruction sync command */
#define         ESAL_TS_RTE_ISYNC_EXECUTE()                                         \
                {                                                                   \
                    asm volatile(" isync");                                         \
                }

/* Sync boundary command */
#define         ESAL_TS_RTE_MSYNC_EXECUTE()                                         \
                {                                                                   \
                    asm volatile(" msync");                                         \
                }

/* Translation Lookaside Buffer Load Instruction Entry */
#define         ESAL_TS_RTE_TLBLI_EXECUTE(tlb_val)                                  \
                {                                                                   \
                    asm volatile(" tlbli %0 " : : "r" (tlb_val) );                  \
                }

/* Translation Lookaside Buffer Load Data Entry */
#define         ESAL_TS_RTE_TLBLD_EXECUTE(tlb_val)                                  \
                {                                                                   \
                    asm volatile(" tlbld %0 " : : "r" (tlb_val));                   \
                }

/* Translation Lookaside Buffer Synchronize */
#define         ESAL_TS_RTE_TLBSYNC_EXECUTE()                                       \
                {                                                                   \
                    asm volatile(" tlbsync ");                                      \
                }

/* Translation Lookaside Buffer Invalidate Entry */
#define         ESAL_TS_RTE_TLBIE_EXECUTE(tlb_val)                                  \
                {                                                                   \
                    asm volatile(" tlbie %0 " : : "r" (tlb_val));                   \
                }

/* Translation Lookaside Buffer Invalidate All */
#define         ESAL_TS_RTE_TLBIA_EXECUTE()                                         \
                {                                                                   \
                    asm volatile(" tlbia ");                                        \
                }

/* Translation Lookaside Buffer Read */
#define         ESAL_TS_RTE_TLBRE_EXECUTE()                                         \
                {                                                                   \
                    asm volatile(" tlbre ");                                        \
                }

/* Translation Lookaside Buffer Write */
#define         ESAL_TS_RTE_TLBWE_EXECUTE()                                         \
                {                                                                   \
                    asm volatile(" isync ");                                        \
                    asm volatile(" tlbwe ");                                        \
                    asm volatile(" isync ");                                        \
                    asm volatile(" msync ");                                        \
                }

#define         ESAL_TS_RTE_TLB_N_INVALIDATE(tlb_num)                               \
                {                                                                   \
                    asm volatile("tlbivax 0,%0" : : "r" (tlb_num));                 \
                    asm volatile("TLBSYNC");                                        \
                }


#if (ESAL_TS_PIC_PID_SUPPORT == NU_TRUE)



/* This macro sets the PIC/PID base address register */
#define         ESAL_TS_RTE_PIC_PID_BASE_SET(pic_base, 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)            \
                {                                                                   \
                                                                                    \
                }

#endif  /* ESAL_TS_PIC_PID_SUPPORT == NU_TRUE */

/* This macro gets the current function's return address, see GCC manual for argument usage */
#define         ESAL_GET_RETURN_ADDRESS(level) __builtin_return_address(level)

/* This macro marks a symbol declaration as weakly linked */
#define         ESAL_TS_WEAK_REF(decl) decl __attribute((weak))

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

/* This macro returns the passed value */
#define         ESAL_TS_NO_RETURN(return_val) 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()   asm volatile("" ::: "memory")

/* This macro returns the 2-byte value with the order of the bytes reversed */
#define         ESAL_TS_BYTE_SWAP16(temp16) __builtin_bswap16(temp16)

/* This macro returns the 4-byte value with the order of the bytes reversed */
#define         ESAL_TS_BYTE_SWAP32(temp32) __builtin_bswap32(temp32)

/* This macro returns the 8-byte value with the order of the bytes reversed */
#define         ESAL_TS_BYTE_SWAP64(temp64) __builtin_bswap64(temp64)

#endif  /* CSGNU_PPC_DEFS_H */

