/**************************************************************************//**
  * \file     CPU.h
  * \brief    Processors driver header file
  * \details
  * \author   Zhang Xuan
  * \version  V1.0.0
  * \date     30-Aug-2018
  * \par      History:
  *           V1.0.0 Initial release
  * \par      Copyright:
  *           (c) Heilongjiang TYW Electronics co., LTD
******************************************************************************/
#ifndef _CPU_H_
#define _CPU_H_

/* Includes ------------------------------------------------------------------*/
#include "s6j3360drv.h"

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/* Exported types ------------------------------------------------------------*/
/**
 *****************************************************************************
 ** \brief CPU mode
 *****************************************************************************/
typedef enum en_cpu_mode
{
    CpuUserMode     = 0x10,     /*!< User mode */
    /* Privileged modes start here */
    CpuSystemMode   = 0x1F,     /*!< System mode */
    CpuFiqMode      = 0x11,     /*!< Fast interrupt mode */
    CpuIrqMode      = 0x12,     /*!< Interrupt mode */
    CpuSvcMode      = 0x13,     /*!< Supervisor mode */
    CpuAbtMode      = 0x17,     /*!< Data abort mode */
    CpuUndefMode    = 0x1B      /*!< Undefined mode */
} en_cpu_mode_t;





/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/**
 *****************************************************************************
 ** \defgroup CpuGroup CPU Mode Functions (CPU)
 **
 ** \brief This section describes the interface for the CPU Mode functions.
 **
 ** Provided functions of CPU module:
 **
 ** - Cpu_CpuIsInPrivilegedMode()
 ** - Cpu_GetSystemMode()
 ** - CPU_SET_SYSTEMCONTROL()
 ** - CPU_GET_SYSTEMCONTROL()
 ** - CPU_GET_MPU_TYPE()
 ** - CPU_SET_MPU_REGIONNUMBER()
 ** - CPU_SET_MPU_REGIONBASE()
 ** - CPU_GET_MPU_REGIONBASE()
 ** - CPU_SET_MPU_REGIONSIZE_ENABLE()
 ** - CPU_GET_MPU_REGIONSIZE_ENABLE()
 ** - CPU_SET_MPU_REGIONACCESS()
 ** - CPU_GET_MPU_REGIONACCESS()
 **
 ** Cpu_CpuIsInPrivilegedMode() is used to check whether CPU is in privileged mode.
 ** Cpu_GetSystemMode() is used to get current CPU mode.
 ** On the CR5, cpu modes are follows:
 ** - User mode (unprivileged)
 ** - System mode
 ** - Supvervisor mode
 ** - IRQ mode
 ** - FIQ mode
 ** - Abort mode
 ** - Undefined mode
 **
 ** Other functions can be used to set/get a coprocesser registers.
 **
 *****************************************************************************/
/* @{ */

/** Macro for setting CP15 System Control Register */
#define CPU_SET_SYSTEMCONTROL(u32Value)         MCR(15, 0, (u32Value), 1, 0, 0)

/** Macro for getting CP15 System Control Register */
#define CPU_GET_SYSTEMCONTROL()                 MRC(15, 0, 1, 0, 0)

/** Macro for getting CP15 MPU Type Register */
#define CPU_GET_MPU_TYPE()                      MRC(15, 0, 0, 0, 4)

/** Macro for setting CP15 Memory Region Number Register */
#define CPU_SET_MPU_REGIONNUMBER(u32Value)      MCR(15, 0, (u32Value), 6, 2, 0)

/** Macro for setting CP15 Region Base Register */
#define CPU_SET_MPU_REGIONBASE(u32Value)        MCR(15, 0, (u32Value), 6, 1, 0)

/** Macro for getting CP15 Region Base Register */
#define CPU_GET_MPU_REGIONBASE()                MRC(15, 0, 6, 1, 0)

/** Macro for setting CP15 Region Size and Enable Register */
#define CPU_SET_MPU_REGIONSIZE_ENABLE(u32Value) MCR(15, 0, (u32Value), 6, 1, 2)

/** Macro for getting CP15 Region Size and Enable Register */
#define CPU_GET_MPU_REGIONSIZE_ENABLE()         MRC(15, 0, 6, 1, 2)

/** Macro for setting CP15 Region Access Control Register */
#define CPU_SET_MPU_REGIONACCESS(u32Value)      MCR(15, 0, (u32Value), 6, 1, 4)

/** Macro for getting CP15 Region Access Control Register */
#define CPU_GET_MPU_REGIONACCESS()              MRC(15, 0, 6, 1, 4)

/* Exported functions ------------------------------------------------------- */
extern void          CPU_Config_MPU(void);
extern void          CPU_Config_Caches(void);

extern boolean_t     Cpu_CpuIsInPrivilegedMode(void);
extern uint32_t      Cpu_GetSystemMode(void);
extern en_result_t   Cpu_InvalidateDCacheArea(uint32_t u32StartAddress, uint32_t u32ByteSize);

/* @} */
#ifdef __cplusplus
}
#endif

#endif /* _CPU_H_ */