/*
*********************************************************************************************************
*                                               uC/OS-II
*                                        The Real-Time Kernel
*
*                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
*                                          All Rights Reserved
*
* File : OS_CPU.H
* By   : Jean J. Labrosse
*
* Modified by : Lance Simms, LLNL 9/21/10
*   Adjusted to work with PXA270 microprocessor
*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*
*NOTE: AN-1018 claims that the short is 16 bits and the int is 32 bits for the IAR compiler (pg. 11)
*      One can verify with the sizeof() operator that the long long is a 64 bit type
*/
typedef unsigned char      BOOLEAN;
typedef unsigned char      INT8U;                    /* Unsigned 8 bit  character                           */
typedef signed   char      INT8S;                    /* Signed   8 bit  character                           */
typedef unsigned short     INT16U;                   /* Unsigned 16 bit integer                             */
typedef signed   short     INT16S;                   /* Signed   16 bit integer                             */
typedef unsigned int       INT32U;                   /* Unsigned 32 bit integer                             */
typedef signed   int       INT32S;                   /* Signed   32 bit integer                             */
typedef unsigned long long INT64U;                   /* Unsigned 64 bit integer                             */
typedef signed   long long INT64S;                   /* Signed   64 bit integer                             */
typedef float              FP32;                     /* Single precision floating point                     */
typedef double             FP64;                     /* Double precision floating point                     */

//MICRIUM TYPES
typedef unsigned int       OS_STK;                   /* Each stack entry is 32 bits wide                    */
typedef unsigned int       OS_CPU_SR;                /* Define size of CPU status register (CPSR)           */

//SSA PAYLOAD TYPES
typedef struct {                                     /* Structure to hold errors for the payload            */
  INT64U BusTimeError;
  INT32U ErrorCode;
} PayloadError;

typedef struct {                                     /* Structure to hold directory entries                 */
  INT16U FieldTag;                                   /* NOTE: I've verified that these are 12 bytes wide:   */
  INT16U FieldType;                                  /*  PayloadDirEntry Pay1 = {2, 4, 2, 4};               */
  INT32U Count;                                      /*  printf("Size of Struct: %zu\n\r", sizeof(Pay1));   */
  INT32U DataOrOffset;                               /* This gives 12 bytes                                 */
} PayloadDirEntry;

/*
***********************************************************************************************************
*PROCESSOR SPECIFICS 
***********************************************************************************************************
*/

#define OS_CRITICAL_METHOD 3

//OS_CRITICAL_METHOD==1 : This is the method in C that is accessible with the IAR C/C++ compielr (see p. 30
//                        in the IAR C/C++ Development Guide)
#if OS_CRITICAL_METHOD==1
#include <intrinsics.h>
#define  OS_ENTER_CRITICAL() (__enable_interrupt())
#define  OS_EXIT_CRITICAL()  (__disable_interrupt())
#endif

//OS_CRITICAL_METHOD==2 : This is the method in assembly that does not concern maintaining state of CSPR
#if OS_CRITICAL_METHOD==2
#define  OS_ENTER_CRITICAL() asm (MRS R0, CPSR; ORR R1, R0, 0x80; MSR CPSR_c, R1)
#define  OS_EXIT_CRITICAL()  asm (MRS R0, CPSR; AND R1, R0, 0x7F; MSR CPSR_c, R1)
#endif

//OS_CRITICAL_METHOD==3; This attempts to leave CPSR in same state as it was before interrupt
#if OS_CRITICAL_METHOD==3
#define  OS_ENTER_CRITICAL() (cpu_sr = OS_CPU_SR_Save())    /* Disable interrupts with R0 holding CPSR state   */
#define  OS_EXIT_CRITICAL()  (OS_CPU_SR_Restore(cpu_sr))    /* Enable  interrupts with R0 returning CPSR state */
#endif

#define OS_STK_GROWTH 1                                     /* Stack grows from high memory to low memory with ARM architecture*/
#define OS_TASK_SW()  OSCtxSw()                             /* Task level context swtich needs an assembly lanuage function to switch task */

/*
***********************************************************************************************************
*FUNCTION DEFINITIONS
***********************************************************************************************************
*/

//Interrupt save and restore
#if OS_CRITICAL_METHOD == 3 
__arm  OS_CPU_SR  OS_CPU_SR_Save(void);           /* See OS_CPU_A.S                                    */ 
__arm  void       OS_CPU_SR_Restore(OS_CPU_SR cpu_sr); 
#endif 

//IRQ and FIQ handlers.  These are located in bsp.c
__arm  void       OS_CPU_IRQ_ISR(void);                  /* See OS_CPU_A.S                                    */
__arm  void       OS_CPU_FIQ_ISR(void);

void       OS_CPU_IRQ_ISR_Handler(void);          /* See BSP code                                      */
void       OS_CPU_FIQ_ISR_Handler(void);

//Context Switching and Stack Handling functions.  Note: the Release Notes document says these functions must be placed here.
__arm  void       OSCtxSw(void); 
__arm  void       OSIntCtxSw(void); 
__arm  void       OSStartHighRdy(void); 
