/****************************************************************
 ****************************************************************
 **                                                            **
 **    (C)Copyright 2005-2006, American Megatrends Inc.        **
 **                                                            **
 **            All Rights Reserved.                            **
 **                                                            **
 **        6145-F, Northbelt Parkway, Norcross,                **
 **                                                            **
 **        Georgia - 30071, USA. Phone-(770)-246-8600.         **
 **                                                            **
 ****************************************************************
*****************************************************************
 *
 * IPMdevice.c
 * IPMDevice Commands Handler
 *
 * Author: Govind Kothandapani <govindk@ami.com>
 *       : Rama Bisa <ramab@ami.com>
 *       : Basavaraj Astekar <basavaraja@ami.com>
 *       : Bakka Ravinder Reddy <bakkar@ami.com>
 *
 *****************************************************************/
#define ENABLE_DEBUG_MACROS 0
#include "Types.h"
#include "IPMDevice.h"
#include "MsgHndlr.h"
#include "Support.h"
#include "IPMIDefs.h"
#include "IPMI_IPM.h"
#include "Util.h"
#include "SharedMem.h"
//#include <flashlib.h>
#include "WDT.h"
//#include "PDKAccess.h"
//#include "IPMIConf.h"
#include "Sensor.h"


//common source for versions
//#include <version.h>

#if IPM_DEVICE == 1

/*** Local macro definitions ***/
#define ACPI_SET_SYS_PWR_STATE          0x80
#define ACPI_SET_DEV_PWR_STATE          0x80
#define ACPI_SYS_PWR_STATE_MASK         0x7F
#define ACPI_DEV_PWR_STATE_MASK         0x7F
#define ACPI_MAX_SYS_PWR_STATE			16
#define ACPI_MAX_DEV_PWR_STATE			7
#define ACPI_FLAG_SET					1
#define ACPI_FLAG_UNSET					0


/*** Global Variables ***/

extern _FAR_ WDTTmrMgr_T   g_WDTTmrMgr;



//To get the data across the processes added in Shared memory structure in SharedMem.h
//_FAR_ INT8U     g_ACPISysPwrState;
//_FAR_ INT8U     g_ACPIDevPwrState;

/*** Module Variables ***/

#define WORKING_STATE 0x0
#define S1_SLEEPING_STATE  0x1

//notice
static INT8U  MfgID[]       = {0x12,0x34,0x56};//     /**< Contains Manufacturer ID */
static INT16U g_ProdID      = 0xaabb;

#define FW_INFO_FILE "/proc/ractrends/Helper/FwInfo"

static void GetFirmwareVersion(unsigned int* Major,unsigned int* Minor,unsigned int* Rev)
{
//    char aline[82];
//    int AuxVer;
//    int i = 0, count = 0;
//
//    FILE* fp = fopen(FW_INFO_FILE,"rb");
//    if(fp == NULL)
//    {
//        IPMI_DBG_PRINT("Unable to find firmware version info!!!\n");
//        *Major = 0;
//        *Minor = 0;
//        *Rev = 0;
//        return;
//    }
//
//    fgets(aline,79,fp);
//    
//    for(i = 0; i < 79; i++) 
//    {
//        if (aline[i] == '\0')
//            break;
//        if (aline[i] == '.')
//            ++count;
//    }
//    
//    if(count == 3)
//        sscanf(aline,"FW_VERSION=%d.%d.%d.%d",Major,Minor,&AuxVer,Rev);
//    else
//        sscanf(aline,"FW_VERSION=%d.%d.%d",Major,Minor,Rev);    
//
//    fclose(fp);
//
//    return;
}

/*---------------------------------------
 * GetDevID
 *---------------------------------------*/
int
GetDevID (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
    _NEAR_ GetDevIDRes_T*  pGetDevIDRes = (_NEAR_ GetDevIDRes_T*) pRes;
    char MfgID[3]={0x12,0x34,0x56};

    pGetDevIDRes->CompletionCode      = CC_NORMAL;
    pGetDevIDRes->DeviceID            = DEVICE_ID;
    pGetDevIDRes->DevRevision         = IPMI_DEV_REVISION;
    pGetDevIDRes->FirmwareRevision1   = 0x01;// Major | (inFlashMode << 7);
    pGetDevIDRes->FirmwareRevision2   = 0x08;//MinorBCD;  //DO NOT CHANGE THIS ASSIGNMENT. INSTEAD SET THE VALUE OF THE VARIABLE Minor IN THE FIRSTTIME LOOP
    pGetDevIDRes->IPMIVersion         = IPMI_VERSION;
    pGetDevIDRes->DevSupport          = 0xbf;//DEV_SUPPORT;
    pGetDevIDRes->ProdID              = 0xaabb;//htoipmi_u16 (g_ProdID);
    pGetDevIDRes->AuxFirmwareRevision = 0x00000001;
    _fmemcpy (pGetDevIDRes->MfgID, MfgID, sizeof (MfgID));
    SessionSequenceNumberCount=SessionSequenceNumberCount+1;

    return sizeof (GetDevIDRes_T);
}


/*---------------------------------------
 * ColdReset
 *---------------------------------------*/
int
ColdReset (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//    g_BMCInfo[BMCInst].Msghndlr.ColdReset = 1;
//    /* PDK Module Post Set Reboot Cause*/
//    if(g_PDKHandle[PDK_SETREBOOTCAUSE] != NULL)
//    {
//        ((INT8U(*)(INT8U,int)) g_PDKHandle[PDK_SETREBOOTCAUSE])(SETREBOOTCAUSE_COLD_WARM_RESET_CMD,BMCInst);
//    }
//
//    *pRes = CC_NORMAL;
    return sizeof (*pRes);
}


/*---------------------------------------
 * WarmReset
 *---------------------------------------*/
int
WarmReset (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//	int i=0;
//	FILE *sensorfp;
//	_FAR_ SensorSharedMem_T*	pSenSharedMem; 
//	_FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
//	pSenSharedMem = (_FAR_ SensorSharedMem_T*)&pBMCInfo->SensorSharedMem;
//	SensorThresholds BySensor;
//	INT8U TotalNumSensors;
//	char SensorFileName[MAX_SEN_NAME_SIZE];
//
//	memset(SensorFileName,0,MAX_SEN_NAME_SIZE);
//
//	SENSORTHRESH_FILE(BMCInst, SensorFileName);
//	
//	sensorfp = fopen(SensorFileName,"wb");
//	if(sensorfp == NULL)
//	{
//		TCRIT("Cannot open file for writing\n");
//	  *pRes = CC_UNSPECIFIED_ERR;
//   	return sizeof (*pRes);
//	} 
//
//	OS_THREAD_MUTEX_ACQUIRE(&g_BMCInfo[BMCInst].SensorSharedMemMutex, WAIT_INFINITE);
//
//	TotalNumSensors = g_BMCInfo[BMCInst].SenConfig.NumThreshSensors+g_BMCInfo[BMCInst].SenConfig.NumNonThreshSensors;
//
//	for(i=1;i<=TotalNumSensors;i++)
//	{
//		if(pSenSharedMem->SensorInfo[i].EventTypeCode == THRESHOLD_SENSOR_CLASS)
//		{
//
//			memset(&BySensor,0,sizeof(SensorThresholds));
//
//			BySensor.SensorNum = pSenSharedMem->SensorInfo[i].SensorNumber;
//			BySensor.SensorTypeCode = pSenSharedMem->SensorInfo[i].SensorTypeCode;
//			BySensor.LowerCritical = pSenSharedMem->SensorInfo [i].LowerCritical;
//			BySensor.LowerNonCritical = pSenSharedMem->SensorInfo[i].LowerNonCritical;
//			BySensor.LowerNonRecoverable = pSenSharedMem->SensorInfo[i].LowerNonRecoverable;
//			BySensor.UpperCritical = pSenSharedMem->SensorInfo [i].UpperCritical;
//			BySensor.UpperNonCritical = pSenSharedMem->SensorInfo[i].UpperNonCritical;
//			BySensor.UpperNonRecoverable = pSenSharedMem->SensorInfo[i].UpperNonRecoverable;
//
//			if(sizeof(SensorThresholds) != fwrite((char *)&BySensor,sizeof(char),sizeof(SensorThresholds),sensorfp))
//			{ 
//				TCRIT("Cannot Write SensorThresholds\n");
//				fclose(sensorfp);
//				OS_THREAD_MUTEX_RELEASE(&g_BMCInfo[BMCInst].SensorSharedMemMutex);
//				unlink(SensorFileName);
//				*pRes = CC_UNSPECIFIED_ERR;
//				return sizeof (*pRes);
//			} 
//
//		}
//		
//	}
//
//	fclose(sensorfp);
//	OS_THREAD_MUTEX_RELEASE(&g_BMCInfo[BMCInst].SensorSharedMemMutex);
//
//	g_BMCInfo[BMCInst].Msghndlr.WarmReset = 1;
//
//    /* PDK Module Post Set Reboot Cause*/
//    if(g_PDKHandle[PDK_SETREBOOTCAUSE] != NULL)
//    {
//        ((INT8U(*)(INT8U,int)) g_PDKHandle[PDK_SETREBOOTCAUSE])(SETREBOOTCAUSE_COLD_WARM_RESET_CMD,BMCInst);
//    }
//	*pRes = CC_NORMAL;
//	return sizeof (*pRes);
}


/*---------------------------------------
 * GetSelfTestResults
 *---------------------------------------*/
int
GetSelfTestResults (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//    _NEAR_ GetSelfTestRes_T*  pGetSelfTest = (_NEAR_ GetSelfTestRes_T*) pRes;
//
//    pGetSelfTest->CompletionCode  = CC_NORMAL;
//    pGetSelfTest->TestResultByte1 = ( 0 == g_BMCInfo[BMCInst].Msghndlr.SelfTestByte ) ?
//                                     GST_NO_ERROR: GST_CORRUPTED_DEVICES;
//    pGetSelfTest->TestResultByte2 = g_BMCInfo[BMCInst].Msghndlr.SelfTestByte;
//
//    if(g_PDKHandle[PDK_GETSELFTESTRESULTS] != NULL)
//    {
//         ((void(*)(INT8U *,int))g_PDKHandle[PDK_GETSELFTESTRESULTS]) ((_FAR_ INT8U*)pGetSelfTest,BMCInst);
//    }
//
//    return sizeof (GetSelfTestRes_T);
}


/*---------------------------------------
 * MfgTestOn
 *---------------------------------------*/
int
MfgTestOn (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//
//    g_BMCInfo[BMCInst].Msghndlr.ManufacturingTestOnMode = TRUE;
//
//    *pRes = CC_NORMAL;
//    return sizeof (*pRes);
}


/*---------------------------------------
 * SetACPIPwrState
 *---------------------------------------*/
int
SetACPIPwrState (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//    _NEAR_ SetACPIPwrStateReq_T*  pSetACPIReq = (_NEAR_ SetACPIPwrStateReq_T*) pReq;
//    const INT8U SysPowerState[ACPI_MAX_SYS_PWR_STATE]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x20,0x21,0x2A,0x7F};
//    const INT8U DevPowerState[ACPI_MAX_DEV_PWR_STATE]={0x00,0x01,0x02,0x03,0x2A,0x7F};
//    INT8U TempState = 0,State=0,Ret = 0,StateFlag=0;
//
//    TempState = (pSetACPIReq->ACPISysPwrState & ACPI_SYS_PWR_STATE_MASK);
//    for(State = 0;State<(ACPI_MAX_SYS_PWR_STATE-1);State++)
//    {
//        if(TempState != SysPowerState[State])
//        {
//            continue;
//        }
//        else
//        {
//            StateFlag = ACPI_FLAG_SET;
//            break;
//        }		
//    }
//    if(StateFlag !=ACPI_FLAG_SET)
//    {
//        *pRes = CC_INV_DATA_FIELD;
//        return sizeof (*pRes);
//    }
//    StateFlag = ACPI_FLAG_UNSET;
//    TempState = (pSetACPIReq->ACPIDevPwrState & ACPI_DEV_PWR_STATE_MASK);
//    for(State = 0;State<(ACPI_MAX_DEV_PWR_STATE-1);State++)
//    {
//        if(TempState != DevPowerState[State])
//        {
//            continue;
//        }
//        else
//        {
//            StateFlag = ACPI_FLAG_SET;
//            break;
//        }
//    }
//    if(StateFlag !=ACPI_FLAG_SET)
//    {
//        *pRes = CC_INV_DATA_FIELD;
//        return sizeof (*pRes);
//    }
//	
//    /*Perform OEM action*/
//    if(g_PDKHandle[PDK_CHECKACPIPOWERSTATE] != NULL)	//empty
//    {
//        Ret = ((int(*)(INT8U,INT8U))g_PDKHandle[PDK_CHECKACPIPOWERSTATE]) (pSetACPIReq->ACPISysPwrState,pSetACPIReq->ACPIDevPwrState);
//        if(Ret == 1)
//        {
//           *pRes = CC_INV_DATA_FIELD;
//           return sizeof (*pRes);
//        }
//    }
//
//    /* Perform OEM action */
//    if(g_PDKHandle[PDK_ONACPISTATECHANGE] != NULL)		//empty
//    {
//        ((void(*)(int,int))g_PDKHandle[PDK_ONACPISTATECHANGE]) (pSetACPIReq->ACPISysPwrState & ACPI_SYS_PWR_STATE_MASK,BMCInst);
//    }
//
//    //To get the data across the processes added in Shared memory structure in SharedMem.h
//
//    LOCK_BMC_SHARED_MEM(BMCInst);
//    /* if set System power state bit is set */
//    if (0 != (pSetACPIReq->ACPISysPwrState & ACPI_SET_SYS_PWR_STATE))
//    {
//        if((BMC_GET_SHARED_MEM (BMCInst)->m_ACPISysPwrState == WORKING_STATE	) &&
//            ((pSetACPIReq->ACPISysPwrState & ACPI_SYS_PWR_STATE_MASK) == S1_SLEEPING_STATE))
//
//        {
//            //We are disable the Watch dog timer when State change from Working state to Sleep state s1 
//            BMC_GET_SHARED_MEM(BMCInst)->IsWDTPresent =FALSE;
//            BMC_GET_SHARED_MEM (BMCInst)->IsWDTRunning=FALSE;
//        }
//
//        BMC_GET_SHARED_MEM (BMCInst)->m_ACPISysPwrState  = pSetACPIReq->ACPISysPwrState & ACPI_SYS_PWR_STATE_MASK;
//    }
//
//    /* if set Devicepower state bit is set */
//    if (0 != (pSetACPIReq->ACPIDevPwrState & ACPI_SET_DEV_PWR_STATE))
//    {
//       BMC_GET_SHARED_MEM (BMCInst)->m_ACPIDevPwrState = pSetACPIReq->ACPIDevPwrState & ACPI_DEV_PWR_STATE_MASK;
//    }
//
//    UNLOCK_BMC_SHARED_MEM (BMCInst);
//
//    *pRes = CC_NORMAL;
//    return sizeof (*pRes);
}


/*---------------------------------------
 * GetACPIPwrState
 *---------------------------------------*/
int
GetACPIPwrState (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//    _NEAR_ GetACPIPwrStateRes_T*  pGetACPIRes = (_NEAR_ GetACPIPwrStateRes_T*) pRes;
//
//    pGetACPIRes->CompletionCode  = CC_NORMAL;
//
//    LOCK_BMC_SHARED_MEM(BMCInst);
//    pGetACPIRes->ACPISysPwrState = BMC_GET_SHARED_MEM (BMCInst)-> m_ACPISysPwrState;
//    pGetACPIRes->ACPIDevPwrState =  BMC_GET_SHARED_MEM (BMCInst)->m_ACPIDevPwrState;
//    UNLOCK_BMC_SHARED_MEM (BMCInst);
//
//    return sizeof (GetACPIPwrStateRes_T);
}


/*---------------------------------------
 * GetDevGUID
 *---------------------------------------*/
int
GetDevGUID (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst)
{
//    _NEAR_ GetDevGUIDRes_T*  pGetDevGUIDRes = (_NEAR_ GetDevGUIDRes_T*) pRes;
//
//    pGetDevGUIDRes->CompletionCode  = CC_NORMAL;
//    LOCK_BMC_SHARED_MEM (BMCInst);
//    _fmemcpy (pGetDevGUIDRes->Node, BMC_GET_SHARED_MEM (BMCInst)->DeviceGUID, 16);
//    UNLOCK_BMC_SHARED_MEM (BMCInst);
//
//    return sizeof (GetDevGUIDRes_T);
}

#endif  /* IPM_DEVICE */
