/*******************************************************************************
 * (c) Copyright 2015 Microsemi Corporation.  All rights reserved.
 *
 *
 *
 * SVN $Revision: $
 * SVN $Date: $
 */

#ifndef __MR_OS_MAP_H__
#define __MR_OS_MAP_H__


/*
 * osal.h
 *
 */

#include <api_oam_sdk/common/constants/inc/mr_constants.h>
#include <api_oam_sdk/common/types/inc/mr_api_types.h>
#include "stdio.h"
#include "egl_types.h"
#include "core_uart_apb.h"
//VR #include "m2sxxx.h"
//Resolve using RISC-V HAL
#ifdef __GNUC__
#ifndef OS_PACKED_STRUCT
#define 	OS_PACKED_STRUCT	__attribute__((__packed__))
#endif
#else
#ifndef OS_PACKED_STRUCT
#define 	OS_PACKED_STRUCT
#endif
#endif

/******************************************
 *
 * Mapping of Semaphores to FreeRTOS OS
 *
 ******************************************/
#ifndef API_FOR_WIN_HOST
#include <FreeRTOS.h>
#include <semphr.h>
#include <queue.h>
#include <timers.h>
#include <task.h>
#include "hal.h"
//VR#include "hal.h"
//Resolve using RISC-V HAL
#define OS_ARCH_DECL_PROTECT(lev)				psr_t lev
#define OS_ARCH_PROTECT(lev)					lev = HAL_disable_interrupts()
#define OS_ARCH_UNPROTECT(lev)					HAL_restore_interrupts(lev)

typedef tmrTIMER_CALLBACK 	osTimeoutCallback_t;
typedef xSemaphoreHandle 	osSemaphore_t;
typedef xSemaphoreHandle 	osMutex_t;
typedef xTaskHandle			osTaskHandle_t;
typedef xQueueHandle		osQueueHandle_t;

#define osDisableIRQ(_irq_num_)					;//HAL_disable_interrupts()//PLIC_DisableIRQ(_irq_num_) //VRNVIC_DisableIRQ(_irq_num_)
#define osEnableIRQ(_irq_num_)					;//HAL_enable_interrupts()//PLIC_EnableIRQ(_irq_num_) //VRNVIC_EnableIRQ(_irq_num_)
// Switch to RISC-V Interrupt handler functions

#define osTaskDelete(taskHandle)				vTaskDelete(taskHandle)
#define osSemaphoreCreateBinary(sem) 			vSemaphoreCreateBinary( (sem) )
#define osSemaphoreDelete(sem) 					vSemaphoreDelete( (sem) )
#define osSemaphoreTake(sem,timeOut) 			xSemaphoreTake( (sem), (portTickType) ((timeOut) == 0 ? portMAX_DELAY : (timeOut)) )
#define osSemaphoreGive(sem) 					xSemaphoreGive((sem))
#define osSemaphoreGiveFromISR(sem, swCtxt) 	xSemaphoreGiveFromISR((sem),(swCtxt))

#define osCreateQueue(size,dataSize)			xQueueCreate(size,dataSize)
#define osQueueReceive(queue, msg, timeOut)		xQueueReceive(queue, msg, (TickType_t) ((timeOut) == 0 ? portMAX_DELAY : (0)) )
#define osQueueSend(queue,msg,timeout)			xQueueSendToBack(queue,msg,timeout)

#define osMutexCreate() 						xSemaphoreCreateMutex()
#define osRecursiveMutexCreate() 				xSemaphoreCreateRecursiveMutex()
#define osMutexGive(mut) 						xSemaphoreGive((mut))
#define osRecursiveMutexGive(mut) 				xSemaphoreGiveRecursive((mut))
#define osMutexTake(mut,timeOut) 				xSemaphoreTake((mut),(portTickType) ((timeOut) == 0 ? portMAX_DELAY : (timeOut)) )
#define osRecursiveMutexTake(mut,timeOut) 		xSemaphoreTakeRecursive((mut),(portTickType) ((timeOut) == 0 ? portMAX_DELAY : (timeOut)) )

#define osGetTimerID(timerHandle) 				pvTimerGetTimerID( timerHandle )

#define	osSleepMS(timeMS)						vTaskDelay(timeMS * portTICK_RATE_MS)

#define	OS_TICKS_PER_SEC						(1000)
#define OS_TICKS_PER_MS							(OS_TICKS_PER_SEC/1000)
#define OS_TIMEOUT 								(0xffffffffUL)

#define osGetTickCount							xTaskGetTickCount

#define OS_STACK_THREAD_PRIO               		5
#define osTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask )

extern osMutex_t	ts_printf_mutex;
//#define ts_printf(str...)  do{ osMutexTake(ts_printf_mutex,0);printf(str);osMutexGive(ts_printf_mutex);} while (0)
extern void ts_printf(const char * s, ...);
#ifdef CPP
	extern "C" {
#endif
void * osCreateTimoutTimer(uint32_t tOutMilliSec, uint32_t	ID,osTimeoutCallback_t tOutCallback );
void osTaskGetRunTimeStats( signed char *pcWriteBuffer );
void osTaskGetTaskStats( signed char *pcWriteBuffer );
void init_ts_printf(void);
void init_ts_mem_mgnt(void);

void ts_free(void *memPtr) PRIVILEGED_FUNCTION;
void * ts_malloc(uint32_t size) PRIVILEGED_FUNCTION;

#ifdef CPP
	}
#endif
#else
#define osGetTimerID(timerHandle) (NULL)
#define osSemaphoreTake(sem,timeOut)
#define osSemaphoreGive(sem)

typedef int osSemaphore_t;
typedef void * osTimeoutCallback_t;
void * osCreateTimoutTimer(uint32_t tOutMilliSec,uint32_t	ID,void * tOutCallback );

#define ts_printf(str,...) printf(str,...)
#endif

typedef struct mrDeviceInfo_d {
	osSemaphore_t	wanTxSem;			// Semaphore used to protect Wan Tx buffer
	osSemaphore_t	lanTxSem;			// Semaphore used to protect Lan Tx buffer
	osSemaphore_t	halSem;				// Semaphore used to protect Indirect Mem access to MetRoam

#if MR_ENABLE_CAPT_PKT_SEMAPHORES
	osSemaphore_t	wanCaptPktSem;		// Semaphore used to notify task of pending captured packet on Wan/Lan
#ifndef MR_SINGLE_CAPT_PKT_SEMAPHORE
	osSemaphore_t	lanCaptPktSem;		// Semaphore used to notify task of pending captured packet on Lan
#endif
#endif

	boolean_t		mrNetIfEnabled[PHY_COUNT];
	uint8_t			*mgntMAC;			// Storage to hold the mgnt (CPU) MAC to avoid having to re-read from serial flash
	uint8_t			*wanMAC;			// Storage to hold the WAN MAC to avoid having to re-read from serial flash
	uint8_t			*lanMAC;			// Storage to hold the LAN MAC to avoid having to re-read from serial flash
} mrDeviceInfo_t;

#define IOWR(addr,size,value)			HW_set_32bit_reg(addr,value)
#define IORD(addr,size)					HW_get_32bit_reg(addr)

# define mr_htons(s)						((((s) & 0xFF00) >> 8) | \
											(((s) & 0x00FF) << 8))

# define mr_htonl(l)						(((((l) >> 24) & 0x000000FF)) | \
											((((l) >> 8) & 0x0000FF00)) | \
											(((l) & 0x0000FF00) << 8) | \
											(((l) & 0x000000FF) << 24))

# define mr_ntohs(s)						(mr_htons(s))
# define mr_ntohl(l)						(mr_htonl(l))

#define KB(x) (x * 1024)

#define IP4_ADDR_TO_UINT32_T(ipaddr, a,b,c,d) \
        (ipaddr) = ((uint32_t)((d) & 0xff) << 24) | \
                         ((uint32_t)((c) & 0xff) << 16) | \
                         ((uint32_t)((b) & 0xff) << 8)  | \
                          (uint32_t)((a) & 0xff)

#define BIT_SET(n)						(0x1 << (n))
// ----------------------------------------------------------------------------
// Re-Map Architecture Specific IRQ numbers
// ----------------------------------------------------------------------------
#define OS_OAM_IRQ							1//(External_1_IRQn) //VR(FabricIrq0_IRQn)
//FabricIrq<n>_IRQn --> External_<n+1>_IRQn
#endif //__MR_OS_MAP_H__
