/***************************************************************** ***************************************************************** *** ** *** (C)Copyright 2005-2006, American Megatrends Inc. ** *** ** *** All Rights Reserved. ** *** ** *** 6145-F, Northbelt Parkway, Norcross, ** *** ** *** Georgia - 30071, USA. Phone-(770)-246-8600. ** *** ** ***************************************************************** ****************************************************************** * * SDR.c * SDR functions. * * Author: Govind Kothandapani * ******************************************************************/ #define ENABLE_DEBUG_MACROS 0 #include #include "Types.h" #include "Debug.h" #include "MsgHndlr.h" #include "Support.h" #include "IPMI_SDR.h" #include "SDR.h" #include "SDRFunc.h" #include "SEL.h" #include "IPMIDefs.h" #include "IPMDevice.h" #include "IPMI_Events.h" #include "Events.h" #include "Sensor.h" #include "NVRAccess.h" #include "IPMI_IPM.h" #include "Util.h" #include "IPMI_SensorEvent.h" #include "IPMBIfc.h" #include "IPMIConf.h" #include "PDKAccess.h" #include "SharedMem.h" #include "IPMI_Storage.h" #include "PDKCmdsAccess.h" #include "featuredef.h" /* Reserved bit macro definitions */ #define RESERVED_BITS_PARTIALADDSDR 0xF0 //(BIT7 | BIT6 | BIT5 | BIT4) #if SDR_DEVICE == 1 #define SUPPORT_MULTI_CONTROLLER 1 /*** Local Definitions ***/ #define SDR_FIRST_FREE_BYTE(BMCInst) (((_FAR_ INT8U*)g_BMCInfo[BMCInst].SDRConfig.SDRRAM) + g_BMCInfo[BMCInst].SDRConfig.SDRRAM->Size) #define MAX_SDR_LEN 25 #define MAX_RES_LEN 128 #define SDR_VERSION 0x51 #define CMD_RUN_INITIALIZATION_AGENT 0x2C #define MANAGEMENT_DEV_LOC_REC 0x12 #define PARTIAL_ADD_SDR_SUPPORT 0x04 #define RESERVE_SDR_SUPPORT 0x02 #define GET_SDR_REPOSITORY_ALLOC_SUPPORT 0x01 #define NON_MODAL_SUPPORT 0x20 #define NO_SUPPORT 0x00 #define DELETE_SDR_SUPPORT 0x08 #define MAX_OEM_REC_LEN 64 #define SDR_ALLOC_UNIT_SIZE 0x10 #define SDR_MAX_RECORD_SIZE 0x80 #define SDR_ERASE_COMPLETED 0x01 #define SDR_INIT_COMPLETED 0x01 #define ENABLE_SELECTED_EVENT_MSG 0x10 #define DISABLE_SELECTED_EVENT_MSG 0x20 #define OEM_SDR_NM_REC 0x0D /** * @brief Size of SDR Record **/ #define SDR_SIZE(SDRRecHdr) (sizeof (SDRRecHdr_T) + (SDRRecHdr)->Len) /** * @brief Size the SDR Record occupies in the memory **/ #define SDR_SIZE_IN_MEM(SDRRecHdr) \ (((SDR_SIZE(SDRRecHdr) & 0x0f) == 0) ? SDR_SIZE(SDRRecHdr) : \ (SDR_SIZE(SDRRecHdr) & 0xf0) + 0x10) /*** Prototype Declarations ***/ static BOOL PreCheckSDRUpdateModeCmd (_NEAR_ INT8U* pRes,int BMCInst); static INT16U SDR_ReserveSDRRepository (int BMCInst); static _FAR_ SDRRecHdr_T* GetLastSDRRec (int BMCInst); static void UpdateRepositoryInfo (int BMCInst); static _FAR_ SDRRecHdr_T* SDR_GetSDRRec (INT16U RecID, INT16U ReservationID,int BMCInst); static void SDRInitAgent (int BMCInst); static INT8U ValidateSDRSize (INT8U SDRType, INT8U Size); const INT8U SDRSize [][2] = { // { SDR Type, Maximum Length }, { FULL_SDR_REC, 64 }, { COMPACT_SDR_REC, 48 }, { EVENT_ONLY_SDR_REC, 33 }, { ENTITY_ASSOCIATION_SDR_REC, 16 }, { DEV_REL_ENTITY_ASSOCIATION_SDR_REC, 32 }, { GENERIC_DEVICE_LOCATOR_SDR_REC, 32 }, { FRU_DEVICE_LOCATOR_SDR_REC, 32 }, { MGMT_CTRL_DEV_LOCATOR_SDR_REC, 32 }, { MGMT_CTRL_CONFIRMATION_SDR_REC, 32 }, { BMC_MSG_CHANNEL_INFO_REC, 16 }, }; static INT16U SDR_AddSDRRec (_NEAR_ SDRRecHdr_T* pSDRRecHdr,int BMCInst); static INT16U SDR_PartialAddSDR (_NEAR_ INT8U* SDRData, INT8U Offset, INT8U Size,INT8U IsLast, INT16U ReservationID,int BMCInst); #define CLEAR_SDR_INITIATE_ERASE 0xAA #define CLEAR_SDR_GET_STATUS 0x00 static int SDR_ClearSDRRepository (INT16U ReservationID, INT8U InitOrStatus,int BMCInst); static INT16U SDR_DeleteSDR (INT16U ReservationID, INT16U RecID,int BMCInst); /*--------------------------------------- * GetSDRRepositoryInfo *---------------------------------------*/ int GetSDRRepositoryInfo (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; _NEAR_ SDRRepositoryInfo_T* pSDRRepInfoRes = (_NEAR_ SDRRepositoryInfo_T*) pRes; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); _fmemcpy (pSDRRepInfoRes, &g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo, sizeof (SDRRepositoryInfo_T)); pSDRRepInfoRes->CompletionCode = CC_NORMAL; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (SDRRepositoryInfo_T); } /*--------------------------------------- * GetSDRRepositoryAllocInfo *---------------------------------------*/ int GetSDRRepositoryAllocInfo (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; _NEAR_ SDRRepositoryAllocInfo_T* pSDRRepAllocInfoRes = (_NEAR_ SDRRepositoryAllocInfo_T*) pRes; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); _fmemcpy (pSDRRepAllocInfoRes, &g_BMCInfo[BMCInst].SDRConfig.RepositoryAllocInfo, sizeof (SDRRepositoryAllocInfo_T)); pSDRRepAllocInfoRes->CompletionCode = CC_NORMAL; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (SDRRepositoryAllocInfo_T); } /*--------------------------------------- * ReserveSDRRepository *---------------------------------------*/ int ReserveSDRRepository (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; _NEAR_ ReserveSDRRepositoryRes_T* pResSDRRepRes = (_NEAR_ ReserveSDRRepositoryRes_T*) pRes; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); /* Shouldnt allow to reserve when the SDR is in update mode */ if( TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR ) { pResSDRRepRes->CompletionCode = CC_SDR_REP_IN_UPDATE_MODE; return sizeof (pResSDRRepRes->CompletionCode); } pResSDRRepRes->ReservationID = SDR_ReserveSDRRepository (BMCInst); g_BMCInfo[BMCInst].SDRConfig.PartAddbytes = 0; pResSDRRepRes->CompletionCode = CC_NORMAL; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (ReserveSDRRepositoryRes_T); } /*--------------------------------------- * GetSDR *---------------------------------------*/ int GetSDR (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _FAR_ SDRRecHdr_T* pSDRRec; _NEAR_ GetSDRReq_T* pGetSDRReq = (_NEAR_ GetSDRReq_T*) pReq; _NEAR_ GetSDRRes_T* pGetSDRRes = (_NEAR_ GetSDRRes_T*) pRes; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; INT8U SDRLen = 0,*curchannel; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (TRUE != PreCheckSDRUpdateModeCmd (pRes,BMCInst)) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (INT8U); /* error code set in func */ } /* If the Offset is Not zero then its A partial get.. / if SDR is in update mode then check for the reservation id */ if ((pGetSDRReq->Offset == 0) && (FALSE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR )) { pSDRRec = GetSDRRec (pGetSDRReq->RecID,BMCInst); } else { pSDRRec = SDR_GetSDRRec ( pGetSDRReq->RecID, pGetSDRReq->ReservationID,BMCInst ); } if (0 == pSDRRec) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pGetSDRRes->CompletionCode = g_BMCInfo[BMCInst].SDRConfig.SDRError; return sizeof (INT8U); } SDRLen = pSDRRec->Len+sizeof(SDRRecHdr_T); if((0xFF == pGetSDRReq->Size) && (SDRLen >= pGetSDRReq->Offset)) { pGetSDRReq->Size = SDRLen - pGetSDRReq->Offset; } OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel); /* Check for Max Request Bytes */ if (((pGetSDRReq->Size > MAX_SDR_LEN) && (( pBMCInfo->IpmiConfig.PrimaryIPMBSupport == 0x01 && PRIMARY_IPMB_CHANNEL == (*curchannel & 0xF)) || (pBMCInfo->IpmiConfig.SecondaryIPMBSupport == 0x01 && pBMCInfo->SecondaryIPMBCh == (*curchannel & 0xF)))) || (pGetSDRReq->Size > SDRLen) || (pGetSDRReq->Offset > SDRLen) || (pGetSDRReq->Size > (SDRLen-pGetSDRReq->Offset))) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pGetSDRRes->CompletionCode = CC_CANNOT_RETURN_REQ_BYTES; return sizeof (INT8U); } /* Copy the response */ pGetSDRRes->CompletionCode = CC_NORMAL; pGetSDRRes->NextRecID = SDR_GetNextSDRId (pSDRRec->ID,BMCInst); _fmemcpy (pGetSDRRes + 1, ((_FAR_ INT8U*) pSDRRec) + pGetSDRReq->Offset, pGetSDRReq->Size); OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (GetSDRRes_T) + pGetSDRReq->Size; } /*--------------------------------------- * AddSDR *---------------------------------------*/ int AddSDR (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { INT16U RecID; _NEAR_ SDRRecHdr_T* pSDRRec = (_NEAR_ SDRRecHdr_T*) pReq; _NEAR_ AddSDRRes_T* pAddSDRRes = (_NEAR_ AddSDRRes_T*) pRes; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; /*Check the Minimum length of the SDR record*/ if(ReqLen < sizeof(SDRRecHdr_T)) { *pRes = CC_REQ_INV_LEN; return sizeof(INT8U); } /*Check the SDR length*/ if((ReqLen - sizeof(SDRRecHdr_T)) != pSDRRec->Len) { *pRes = CC_REQ_INV_LEN; return sizeof(INT8U); } OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (TRUE != PreCheckSDRUpdateModeCmd (pRes,BMCInst)) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (INT8U); /* error code set in func */ } RecID = SDR_AddSDRRec (pSDRRec,BMCInst); if (INVALID_RECORD_ID == RecID) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pAddSDRRes->CompletionCode = g_BMCInfo[BMCInst].SDRConfig.SDRError; return sizeof (pAddSDRRes->CompletionCode); } pAddSDRRes->CompletionCode = CC_NORMAL; pAddSDRRes->RecID = RecID; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); // To send notification to CIM if(g_PDKCIMEventHandle[PDKCIMEVENT_NOTIFYSERVERUPDATETOCIM] != NULL) { uint8 CMD; // Set bits for SDR Event & Add operation CMD = 0x11; ((int(*)(uint8, uint16))g_PDKCIMEventHandle[PDKCIMEVENT_NOTIFYSERVERUPDATETOCIM])(CMD, RecID); } return sizeof (AddSDRRes_T); } /*--------------------------------------- * PartialAddSDR *---------------------------------------*/ int PartialAddSDR (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { INT8U Size; INT16U RecID; _NEAR_ PartialAddSDRReq_T* pPartialAddReq = (_NEAR_ PartialAddSDRReq_T*) pReq; _NEAR_ PartialAddSDRRes_T* pPartialAddRes = (_NEAR_ PartialAddSDRRes_T*) pRes; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; if( ReqLen < sizeof(PartialAddSDRReq_T)) { pPartialAddRes->CompletionCode = CC_REQ_INV_LEN; return sizeof (pPartialAddRes->CompletionCode); } /* Check for the reserved bytes should b zero */ if ( 0 != (pPartialAddReq->Progress & RESERVED_BITS_PARTIALADDSDR ) ) { pPartialAddRes->CompletionCode = CC_INV_DATA_FIELD; return sizeof(INT8U); } OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (TRUE != PreCheckSDRUpdateModeCmd (pRes,BMCInst)) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (INT8U); /* error code set in func */ } Size = ReqLen - sizeof (PartialAddSDRReq_T); if(0 == pPartialAddReq->Offset ) { g_BMCInfo[BMCInst].SDRConfig.TrackPOffset =0; g_BMCInfo[BMCInst].SDRConfig.TrackRecID =pPartialAddReq->RecID; } else if((g_BMCInfo[BMCInst].SDRConfig.TrackPOffset) != pPartialAddReq->Offset || g_BMCInfo[BMCInst].SDRConfig.TrackRecID != pPartialAddReq->RecID) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pPartialAddRes->CompletionCode = CC_INV_DATA_FIELD; return sizeof (pPartialAddRes->CompletionCode); } RecID = SDR_PartialAddSDR ((_NEAR_ INT8U*)(pPartialAddReq + 1), pPartialAddReq->Offset, Size, pPartialAddReq->Progress & 0xf, pPartialAddReq->ReservationID,BMCInst); if (RecID == INVALID_RECORD_ID) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pPartialAddRes->CompletionCode = g_BMCInfo[BMCInst].SDRConfig.SDRError; return sizeof (pPartialAddRes->CompletionCode); } pPartialAddRes->CompletionCode = CC_NORMAL; pPartialAddRes->RecID = RecID; g_BMCInfo[BMCInst].SDRConfig.TrackPOffset +=Size; g_BMCInfo[BMCInst].SDRConfig.TrackRecID =RecID; //We are updating the available or alloted Record ID OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (PartialAddSDRRes_T); } /*--------------------------------------- * DeleteSDR *---------------------------------------*/ int DeleteSDR (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; _NEAR_ DeleteSDRReq_T* pDeleteSDRReq = (_NEAR_ DeleteSDRReq_T*)pReq; _NEAR_ DeleteSDRRes_T* pDeleteSDRRes = (_NEAR_ DeleteSDRRes_T*)pRes; INT16U RecID; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (TRUE != PreCheckSDRUpdateModeCmd (pRes,BMCInst)) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (INT8U); /* error code set in func */ } RecID=SDR_DeleteSDR ( pDeleteSDRReq->ReservationID, pDeleteSDRReq->RecID,BMCInst); if(RecID == INVALID_RECORD_ID ) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pDeleteSDRRes->CompletionCode = g_BMCInfo[BMCInst].SDRConfig.SDRError; return sizeof (pDeleteSDRRes->CompletionCode); } pDeleteSDRRes->CompletionCode = CC_NORMAL; pDeleteSDRRes->RecID = RecID; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); // To send notification to CIM if(g_PDKCIMEventHandle[PDKCIMEVENT_NOTIFYSERVERUPDATETOCIM] != NULL) { uint8 CMD; // Set bits for SDR Event & Delete operation CMD = 0x13; ((int(*)(uint8, uint16))g_PDKCIMEventHandle[PDKCIMEVENT_NOTIFYSERVERUPDATETOCIM])(CMD, RecID); } return sizeof (DeleteSDRRes_T); } /*--------------------------------------- * ClearSDRRepository *---------------------------------------*/ int ClearSDRRepository (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { int status; _NEAR_ ClearSDRReq_T* pClrSDRReq = (_NEAR_ ClearSDRReq_T*) pReq; _NEAR_ ClearSDRRes_T* pClrSDRRes = (_NEAR_ ClearSDRRes_T*) pRes; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (TRUE != PreCheckSDRUpdateModeCmd (pRes,BMCInst)) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (INT8U); /* error code set in func */ } if(pClrSDRReq->CLR[0] != 'C' || pClrSDRReq->CLR[1] != 'L' || pClrSDRReq->CLR[2] != 'R' ) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pClrSDRRes->CompletionCode= CC_PASSWORD_TEST_FAILED; return sizeof(INT8U); } status = SDR_ClearSDRRepository (pClrSDRReq->ReservationID,pClrSDRReq->InitOrStatus,BMCInst); if (0 != status) { OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pClrSDRRes->CompletionCode = g_BMCInfo[BMCInst].SDRConfig.SDRError; return sizeof (pClrSDRRes->CompletionCode); } pClrSDRRes->CompletionCode = CC_NORMAL; pClrSDRRes->EraseProgress = SDR_ERASE_COMPLETED; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (ClearSDRRes_T); } /*--------------------------------------- * GetSDRRepositoryTime *---------------------------------------*/ int GetSDRRepositoryTime (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { INT32U SDRTime; _NEAR_ GetSDRRepositoryTimeRes_T* pGetSDRTimeRes = (_NEAR_ GetSDRRepositoryTimeRes_T*) pRes; BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); /* Get the time */ SDRTime = GetSelTimeStamp (BMCInst); pGetSDRTimeRes->CompletionCode = CC_NORMAL; pGetSDRTimeRes->Time = SDRTime; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (GetSDRRepositoryTimeRes_T); } /*-------------------------------------- * * SetSDRRepositoryTime * * -------------------------------------*/ int SetSDRRepositoryTime (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _NEAR_ SetSDRRepositoryTimeReq_T* pSetSDRTimeReq = (_NEAR_ SetSDRRepositoryTimeReq_T*) pReq; BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; pSetSDRTimeReq->Time = ipmitoh_u32 (pSetSDRTimeReq->Time); OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); SET_SYSTEM_TIME_STAMP (&pSetSDRTimeReq->Time); /* Resetting the SELTimeUTCOffset to default value */ pBMCInfo->GenConfig.SELTimeUTCOffset = UNSPECIFIED_UTC_OFFSET; /*Write to NVRAM*/ FlushIPMI((INT8U*)&pBMCInfo->GenConfig,(INT8U*)&pBMCInfo->GenConfig,pBMCInfo->IPMIConfLoc.GenConfigAddr, sizeof(GENConfig_T),BMCInst); OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); pRes [0] = CC_NORMAL; return sizeof (*pRes); } /*--------------------------------------- * EnterSDRUpdateMode *---------------------------------------*/ int EnterSDRUpdateMode (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _NEAR_ EnterSDRUpdateModeRes_T* pEnterSDRUpdateModeRes = (_NEAR_ EnterSDRUpdateModeRes_T*) pRes; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; INT8U *curchannel; OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel); OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR = TRUE; g_BMCInfo[BMCInst].SDRConfig.UpdatingChannel = *curchannel & 0xF; pEnterSDRUpdateModeRes->CompletionCode = CC_NORMAL; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (EnterSDRUpdateModeRes_T); } /*------------------------------------------ * ExitSDRUpdateMode *------------------------------------------*/ int ExitSDRUpdateMode (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _NEAR_ ExitSDRUpdateModeRes_T* pExitSDRUpdateModeRes = (_NEAR_ ExitSDRUpdateModeRes_T*) pRes; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (TRUE != PreCheckSDRUpdateModeCmd (pRes,BMCInst)) { return sizeof (INT8U); /* error code set in func */ } g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR = FALSE; pExitSDRUpdateModeRes->CompletionCode = CC_NORMAL; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (ExitSDRUpdateModeRes_T); } /*------------------------------------------------- * RunInitializationAgent *--------------------------------------------------*/ int RunInitializationAgent (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes,_NEAR_ int BMCInst) { _NEAR_ RunInitAgentRes_T* pRunInitAgentRes = (_NEAR_ RunInitAgentRes_T*) pRes; _FAR_ BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; /* Reserved bit Checking */ if((pReq[0] & 0xFE) != 0x00) { pRes [0] = CC_INV_DATA_FIELD; return sizeof (*pRes); } OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SDRConfig.SDRMutex, WAIT_INFINITE); if (0 != pReq[0]) { InitSDR (BMCInst); SDRInitAgent (BMCInst); // The sensor monitor loop has been made 0 for // initializing the sensor scanning bit. pBMCInfo->SenConfig.SensorMonitorLoopCount = 0; } pRunInitAgentRes->CompletionCode = CC_NORMAL; pRunInitAgentRes->Status = SDR_INIT_COMPLETED; OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SDRConfig.SDRMutex); return sizeof (RunInitAgentRes_T); } /*----------------------------------------- * GetSDRRec *-----------------------------------------*/ _FAR_ SDRRecHdr_T* GetSDRRec (INT16U RecID,int BMCInst) { _FAR_ SDRRecHdr_T* pSDRRec; /* If ID == 0x0000 return first record */ if (0 == RecID) { pSDRRec = SDR_GetFirstSDRRec (BMCInst); if (0== pSDRRec) /* is SDR empty? */ { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REC_NOT_PRESENT; return 0; } return pSDRRec; } /* If ID == 0xFFFF return the last record */ if (0xFFFF == RecID) { return GetLastSDRRec (BMCInst); } pSDRRec = SDR_GetFirstSDRRec (BMCInst); while (TRUE) { if (0== pSDRRec) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REC_NOT_PRESENT; return 0; } if (pSDRRec->ID == RecID) { return pSDRRec; } pSDRRec = SDR_GetNextSDRRec (pSDRRec,BMCInst); } } /*----------------------------------------------------- * InitSDR *-----------------------------------------------------*/ int InitSDR (int BMCInst) { _FAR_ INT8U* pSDRRec; _FAR_ SDRRecHdr_T* pSDRRecord; int i; /* Multi-LUN support index will have more than 256 sensors*/ _FAR_ INT8U OEM_Recdata[MAX_OEM_REC_LEN]; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; pBMCInfo->SDRConfig.SDRRAM = (_FAR_ SDRRepository_T*) GetSDRSELNVRAddr(NVRH_SDR, BMCInst); pSDRRec = GetSDRSELNVRAddr (NVRH_SDR + sizeof(SDRRepository_T), BMCInst); pBMCInfo->SDRConfig.SDRRAM->NumRecords = 0; pBMCInfo->SDRConfig.LatestRecordID =0; pBMCInfo->SDRConfig.SDRRAM->Size = 16; /* SDR Repository Header */ #if (0x01 == MARK_FOR_DELETION_SUPPORT) pBMCInfo->SDRConfig.NumMarkedRecords= 0; #endif if (pBMCInfo->SDRConfig.RepositoryInfo.OpSupport & OVERFLOW_FLAG) { pBMCInfo->SDRConfig.RepositoryInfo.OpSupport &= ~OVERFLOW_FLAG; } IPMI_DBG_PRINT ("Init SDR\n"); while (TRUE) { #if (0x01 == MARK_FOR_DELETION_SUPPORT) if ((0x5A == ((_FAR_ E2ROMHdr_T*)pSDRRec)->Valid) || (0x01 == ((_FAR_ E2ROMHdr_T*)pSDRRec)->Valid) ) { //count the records marked for deletion. if (0x01 == ((_FAR_ E2ROMHdr_T*)pSDRRec)->Valid) { pBMCInfo->SDRConfig.NumMarkedRecords++; } else { pBMCInfo->SDRConfig.SDRRAM->NumRecords ++; } #else if (0x5A == ((_FAR_ E2ROMHdr_T*)pSDRRec)->Valid) { pBMCInfo->SDRConfig.SDRRAM->NumRecords ++; #endif pBMCInfo->SDRConfig.LatestRecordID = ((SDRRecHdr_T *)(((_FAR_ E2ROMHdr_T*)pSDRRec)+1))->ID; pBMCInfo->SDRConfig.SDRRAM->Size += ((_FAR_ E2ROMHdr_T*)pSDRRec)->Len; pSDRRec += ((_FAR_ E2ROMHdr_T*)pSDRRec)->Len; } /* if No more Records */ else { break; } } /* Check if SDR (valid record count) Empty */ if (0 == pBMCInfo->SDRConfig.SDRRAM->NumRecords) { #if IPM_DEVICE == 1 pBMCInfo->Msghndlr.SelfTestByte |= GST_SDR_EMPTY; #endif IPMI_DBG_PRINT ("SDR EMPTY \n"); } /* Update the SDR Erase Time Stamp */ pBMCInfo->SDRConfig.RepositoryInfo.EraseTimeStamp = pBMCInfo->GenConfig.SDREraseTime ; /* Update the repository information */ UpdateRepositoryInfo (BMCInst); pSDRRecord = SDR_GetFirstSDRRec (BMCInst); for (i=0; i < pBMCInfo->SDRConfig.SDRRAM->NumRecords && pSDRRecord != NULL; i++) { if ((OEM_SDRFRU_REC == pSDRRecord->Type)||(OEM_SDRNM_REC == pSDRRecord->Type)) { INT8U Rec_len; Rec_len=pSDRRecord->Len ; memcpy(OEM_Recdata , pSDRRecord ,sizeof(SDRRecHdr_T)+Rec_len); if(g_PDKHandle[PDK_PROCESSOEMRECORD] != NULL) { ((void(*)(INT8U *,int))g_PDKHandle[PDK_PROCESSOEMRECORD]) ((INT8U*)&OEM_Recdata,BMCInst); } } if(g_corefeatures.node_manager == ENABLED) { if(OEM_SDRNM_REC == pSDRRecord->Type) { OEM_NMRec_T* sonm; sonm =(OEM_NMRec_T*) ( (UINT8*)pSDRRecord ); if(sonm->RecordSubType == OEM_SDR_NM_REC) pBMCInfo->NMConfig.NMDevSlaveAddress = sonm->NMDevSlaveAddress; } } if(g_PDKHandle[PDK_PROCESSSENSORDATARECORD] != NULL) { ((void(*)(INT8U *,int))g_PDKHandle[PDK_PROCESSSENSORDATARECORD]) ((INT8U*)pSDRRecord,BMCInst); } pSDRRecord = SDR_GetNextSDRRec (pSDRRecord,BMCInst); } if(g_PDKHandle[PDK_AFTERSDRINIT] != NULL) { ((void(*)(INT8U))g_PDKHandle[PDK_AFTERSDRINIT]) (BMCInst); } return 0; } /*----------------------------------------------------------* * SDR_GetNextSDRId *----------------------------------------------------------*/ INT16U SDR_GetNextSDRId (INT16U RecID,int BMCInst) { _FAR_ SDRRecHdr_T* pSDRRec; pSDRRec = GetSDRRec(RecID,BMCInst); if (0 == pSDRRec) { return INVALID_RECORD_ID; } pSDRRec = SDR_GetNextSDRRec (pSDRRec,BMCInst); if (0 == pSDRRec) { /* return last record ID (0xFFFF) */ IPMI_DBG_PRINT (" No Records\n"); return 0xFFFF; } else { return pSDRRec->ID; } } /*-------------------------------------------------- * SDR_GetFirstSDRRec *--------------------------------------------------*/ _FAR_ SDRRecHdr_T* SDR_GetFirstSDRRec (int BMCInst) { return ReadSDRRepository (NULL, BMCInst); } /*-------------------------------------------------- * SDR_GetNextSDRRec *-------------------------------------------------*/ _FAR_ SDRRecHdr_T* SDR_GetNextSDRRec (_FAR_ SDRRecHdr_T* pSDRRec,int BMCInst) { return ReadSDRRepository (pSDRRec,BMCInst); } /*-------------------------------------------------- * ReadSDRRepository *-------------------------------------------------*/ _FAR_ SDRRecHdr_T* ReadSDRRepository (_FAR_ SDRRecHdr_T* pSDRRec,int BMCInst) { _FAR_ E2ROMHdr_T* InternalHdr; INT8U SDRSize=0; if (pSDRRec == 0) { InternalHdr = (_FAR_ E2ROMHdr_T*) GetSDRSELNVRAddr(NVRH_SDR + sizeof(SDRRepository_T), BMCInst); } else { SDRSize = (SDR_ALLOC_UNIT_SIZE -((SDR_SIZE (pSDRRec) + sizeof(E2ROMHdr_T))%SDR_ALLOC_UNIT_SIZE)); if(SDRSize == SDR_ALLOC_UNIT_SIZE) { InternalHdr = (_FAR_ E2ROMHdr_T*)((_FAR_ INT8U*)pSDRRec + SDR_SIZE (pSDRRec)); } else { InternalHdr = (_FAR_ E2ROMHdr_T*)((_FAR_ INT8U*)pSDRRec + SDR_SIZE (pSDRRec)+SDRSize ); } /* is address >= First free byte ? */ if ((_FAR_ INT8U*) InternalHdr >= (_FAR_ INT8U*)SDR_FIRST_FREE_BYTE(BMCInst) ) { /* No more records to read */ IPMI_DBG_PRINT("No more records to read\n"); return 0; } IPMI_DBG_PRINT_1("Reading the next record of %x \n", pSDRRec->ID); } /* is SDR Empty ?*/ if (g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords == 0) { return 0; } #if (0x01 == MARK_FOR_DELETION_SUPPORT) /* Fetch a Valid SDR */ while (TRUE) { if( InternalHdr->Valid == 0x5a ) { IPMI_DBG_PRINT_1("Returning Valid record ID %x \n", ((_FAR_ SDRRecHdr_T*)(InternalHdr+1))->ID ); return ((_FAR_ SDRRecHdr_T*)(InternalHdr+1)); } InternalHdr = (_FAR_ E2ROMHdr_T*) (((INT8U*)InternalHdr) + InternalHdr->Len); /* is address >= First free byte ? */ if ((_FAR_ INT8U*) InternalHdr >= (_FAR_ INT8U*)SDR_FIRST_FREE_BYTE(BMCInst) ) { IPMI_DBG_PRINT("No more valid records found \n"); return 0; } } #else return ((_FAR_ SDRRecHdr_T*)(InternalHdr+1)); #endif } /*-------------------------------------------------- * WriteSDRRepository *-------------------------------------------------*/ void WriteSDRRepository (_FAR_ SDRRecHdr_T* pSDRRec, INT8U Offset, INT8U Size,INT8U SdrSize,int BMCInst) { _FAR_ E2ROMHdr_T* InternalHdr = (_FAR_ E2ROMHdr_T *)SDR_FIRST_FREE_BYTE(BMCInst); _FAR_ INT8U* WriteAddr; /* Update Validity and Length */ if ( Offset < sizeof(SDRRecHdr_T ) && ((Offset + Size) >= sizeof(SDRRecHdr_T)) ) { InternalHdr->Valid = 0x5A; InternalHdr->Len = SdrSize; } WriteAddr = (_FAR_ INT8U*)(InternalHdr+1); memset((WriteAddr + Offset),0,SdrSize); _fmemcpy ((WriteAddr + Offset), pSDRRec, Size); return ; } /** * @brief Cehck the SDR update mode. * @param pRes - Response. * @return TRUE/FALSE **/ static BOOL PreCheckSDRUpdateModeCmd (_NEAR_ INT8U* pRes,int BMCInst) { _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; INT8U *curchannel; OS_THREAD_TLS_GET(g_tls.CurChannel,curchannel); if (TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR) { if (pBMCInfo->IpmiConfig.SYSIfcSupport == 0x01 && SYS_IFC_CHANNEL == (*curchannel & 0xF)) { if (SYS_IFC_CHANNEL != g_BMCInfo[BMCInst].SDRConfig.UpdatingChannel) { *pRes = CC_NODE_BUSY; return FALSE; } } else { return TRUE; } } return TRUE; } /** * @brief Reserve the SDR Repository. * @return Reservation ID. **/ static INT16U SDR_ReserveSDRRepository (int BMCInst) { if (0xffff == g_BMCInfo[BMCInst].SDRConfig.ReservationID) { g_BMCInfo[BMCInst].SDRConfig.ReservationID = 1; }else { g_BMCInfo[BMCInst].SDRConfig.ReservationID++; } g_BMCInfo[BMCInst].SDRConfig.TrackPOffset =0; return g_BMCInfo[BMCInst].SDRConfig.ReservationID; } /** * @brief Get an SDR record. * @param RecID - SDR record ID. * @param ReservationID - SDR Reservation ID. * @return SDR record. **/ static _FAR_ SDRRecHdr_T* SDR_GetSDRRec (INT16U RecID, INT16U ReservationID,int BMCInst) { /* Bail out with error, if both the conditions are False (Reservation not valid) 1. Reservation ID matches, not equal to 0x00 & SDR is not in Update mode / 2. SDR is in Update mode & Reservation ID equals to 0x00 */ if ( !(((g_BMCInfo[BMCInst].SDRConfig.ReservationID == ReservationID) && (0x00 != ReservationID) && (FALSE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR)) || ((TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR) && (0x00 == ReservationID)))) { if( TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR ) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REP_IN_UPDATE_MODE; }else /* Reservation ID doesn't match, return invalid reservation ID */ { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_RESERVATION_ID; } return 0; } return GetSDRRec (RecID,BMCInst); } static INT8U ValidateSDRSize (INT8U SDRType, INT8U Size) { int i; IPMI_DBG_PRINT_2("ValidateSDR Type : 0x%X, Size : 0x%X\n", SDRType, Size); if ((SDRType == OEM_SDRFRU_REC)||(SDRType == OEM_SDRNM_REC)) return TRUE; for (i = 0; i < sizeof (SDRSize)/ 2; i++) { if ((SDRSize[i][0] == SDRType) && (SDRSize[i][1] >= Size)) { return TRUE; } } return FALSE; } /** * @brief Add an SDR record. * @param pSDRRec - SDR record. * @return Record ID. **/ static INT16U SDR_AddSDRRec (_NEAR_ SDRRecHdr_T* pSDRRec,int BMCInst) { INT16U SDRSize; INT8U AllocSize; int nRet; if (FALSE == ValidateSDRSize(pSDRRec->Type, pSDRRec->Len + sizeof (SDRRecHdr_T))) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_REQ_INV_LEN; return INVALID_RECORD_ID; } AllocSize = SDR_SIZE (pSDRRec) + sizeof(E2ROMHdr_T); if(0 != (AllocSize % SDR_ALLOC_UNIT_SIZE)) { SDRSize = AllocSize + (SDR_ALLOC_UNIT_SIZE -(AllocSize % SDR_ALLOC_UNIT_SIZE)); } else { SDRSize = AllocSize; } if (SDRSize > htoipmi_u16 (g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.FreeSpace)) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport |= OVERFLOW_FLAG; g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_OUT_OF_SPACE; return INVALID_RECORD_ID; } /* Update the record ID */ pSDRRec->ID = g_BMCInfo[BMCInst].SDRConfig.LatestRecordID + 1; /* Add this record to the end of the repository */ WriteSDRRepository (pSDRRec, 0, SDR_SIZE (pSDRRec),SDRSize,BMCInst); /* Flush the sdr */ FlushSDR (SDR_FIRST_FREE_BYTE(BMCInst), SDRSize, nRet,BMCInst); #if IPM_DEVICE == 1 if (-1 == nRet) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte |= GST_CANNOT_ACCESS_SDR; } else { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_CANNOT_ACCESS_SDR; } #endif /* Update the fields in SDR Repository */ g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords++; g_BMCInfo[BMCInst].SDRConfig.LatestRecordID++; #if IPM_DEVICE == 1 if (g_BMCInfo[BMCInst].Msghndlr.SelfTestByte & GST_SDR_EMPTY) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_SDR_EMPTY; } #endif g_BMCInfo[BMCInst].SDRConfig.SDRRAM->Size += SDRSize; g_BMCInfo[BMCInst].SDRConfig.SDRRAM->AddTimeStamp = GetSelTimeStamp(BMCInst); g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.AddTimeStamp = GetSelTimeStamp(BMCInst); /* Update the repository info */ UpdateRepositoryInfo (BMCInst); /* Invalidate Reservation ID if any */ SDR_ReserveSDRRepository (BMCInst); return pSDRRec->ID; } /** * @brief Add partial SDR record. * @param SDRData - SDR Data. * @param Offset - SDR offset. * @param Size - Size of the data. * @param IsLast - Is this a last record? * @param ReservationID - SDR reservation id. * @return the record id. **/ static INT16U SDR_PartialAddSDR (_NEAR_ INT8U* SDRData, INT8U Offset, INT8U Size, INT8U IsLast, INT16U ReservationID,int BMCInst) { INT16U RecID; _FAR_ SDRRecHdr_T* pSDRRecInNVR; INT8U SdrSize=0; int nRet; /* Bail out with error, if both the conditions are False (Reservation not valid) 1. Reservation ID matches, not equal to 0x00 & SDR is not in Update mode / 2. SDR is in Update mode & Reservation ID equals to 0x00 */ if ( !(((g_BMCInfo[BMCInst].SDRConfig.ReservationID == ReservationID) && (0x00 != ReservationID) && (FALSE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR)) || ((TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR) && (0x00 == ReservationID)))) { if( TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR ) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REP_IN_UPDATE_MODE; }else //Reservation ID doesn't match, return invalid reservation ID. { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_RESERVATION_ID; } g_BMCInfo[BMCInst].SDRConfig.PartAddbytes=0; return INVALID_RECORD_ID; } pSDRRecInNVR = (_FAR_ SDRRecHdr_T*) (SDR_FIRST_FREE_BYTE(BMCInst) + sizeof (E2ROMHdr_T)); RecID = g_BMCInfo[BMCInst].SDRConfig.LatestRecordID + 1; /* If the header is received completely, validate the size */ if ((Offset + Size) >= sizeof(SDRRecHdr_T)) { if ( Offset < sizeof(SDRRecHdr_T )) { _NEAR_ SDRRecHdr_T SDRHdr; memcpy((INT8U*)&SDRHdr, (INT8U*)pSDRRecInNVR, Offset ); memcpy(((INT8U*)&SDRHdr) + Offset, SDRData, sizeof(SDRRecHdr_T) - Offset); ((_NEAR_ SDRRecHdr_T*) pSDRRecInNVR)->ID = SDRHdr.ID = RecID; memcpy( SDRData, ((INT8U*)&SDRHdr) + Offset, sizeof(SDRRecHdr_T) - Offset ); if (FALSE == ValidateSDRSize(SDRHdr.Type, SDRHdr.Len + sizeof (SDRRecHdr_T))) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_REQ_INV_LEN; return INVALID_RECORD_ID; } SdrSize = SDRHdr.Len + sizeof (SDRRecHdr_T) + sizeof (E2ROMHdr_T); if(0 != (SdrSize % SDR_ALLOC_UNIT_SIZE)) { SdrSize += (SDR_ALLOC_UNIT_SIZE - (SdrSize % SDR_ALLOC_UNIT_SIZE)); } if (SdrSize > ipmitoh_u16 (g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.FreeSpace)) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport |= OVERFLOW_FLAG; g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_OUT_OF_SPACE; return INVALID_RECORD_ID; } g_BMCInfo[BMCInst].SDRConfig.PartAddbytes = SdrSize; if ((Offset + Size) > (SDRHdr.Len + sizeof (SDRRecHdr_T))) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_DATA_FIELD; return INVALID_RECORD_ID; } } else if ((Offset + Size) > (pSDRRecInNVR->Len + sizeof (SDRRecHdr_T))) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_DATA_FIELD; return INVALID_RECORD_ID; } } if ((IsLast == 1) && ((Offset + Size) != (pSDRRecInNVR->Len + sizeof (SDRRecHdr_T)))) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INCOMPLETE_WRITTEN_BYTES; return INVALID_RECORD_ID; } WriteSDRRepository ((_FAR_ SDRRecHdr_T*)SDRData, Offset, Size,SdrSize,BMCInst); /* If this is the last data update the data fields and flush. */ if (IsLast == 1) { /* Flush the sdr */ FlushSDR (SDR_FIRST_FREE_BYTE(BMCInst), g_BMCInfo[BMCInst].SDRConfig.PartAddbytes, nRet,BMCInst); #if IPM_DEVICE == 1 if (-1 == nRet) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte |= GST_CANNOT_ACCESS_SDR; } else { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_CANNOT_ACCESS_SDR; } #endif /* Update the fields in SDR Repository */ g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords ++; g_BMCInfo[BMCInst].SDRConfig.LatestRecordID++; g_BMCInfo[BMCInst].SDRConfig.TrackPOffset=0; #if IPM_DEVICE == 1 if (g_BMCInfo[BMCInst].Msghndlr.SelfTestByte & GST_SDR_EMPTY) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_SDR_EMPTY; } #endif g_BMCInfo[BMCInst].SDRConfig.SDRRAM->Size += g_BMCInfo[BMCInst].SDRConfig.PartAddbytes; g_BMCInfo[BMCInst].SDRConfig.SDRRAM->AddTimeStamp = GetSelTimeStamp(BMCInst); g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.AddTimeStamp = GetSelTimeStamp(BMCInst); /* Update the repository info */ UpdateRepositoryInfo (BMCInst); g_BMCInfo[BMCInst].SDRConfig.PartAddbytes =0; /* Invalidate Reservation ID if any */ SDR_ReserveSDRRepository (BMCInst); // To send notification to CIM if(g_PDKCIMEventHandle[PDKCIMEVENT_NOTIFYSERVERUPDATETOCIM] != NULL) { uint8 CMD; // Set bits for SDR Event & Add operation CMD = 0x11; ((int(*)(uint8, uint16))g_PDKCIMEventHandle[PDKCIMEVENT_NOTIFYSERVERUPDATETOCIM])(CMD, RecID); } } return RecID; } /** * @brief Delete the SDR. * @param ReservationID - SDR reservation id. * @param RecordID - SDR Record ID, which needs to be deleted * @return 0 if success, -1 if error. **/ static INT16U SDR_DeleteSDR (INT16U ReservationID, INT16U RecID,int BMCInst) { //#define MARK_FOR_DELETION _FAR_ SDRRecHdr_T* pSDRRec = NULL; int nRet; BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst]; #if (0x01 == MARK_FOR_DELETION_SUPPORT) _FAR_ E2ROMHdr_T* pRec = NULL; #else _FAR_ INT8U* pDestLocation = NULL; _FAR_ INT8U* pSrcData = NULL; _FAR_ INT8U* pFreeBytes= NULL; _NEAR_ INT8U deleteSDR_Size; _NEAR_ INT16U size; #endif /* Bail out with error, if both the conditions are False (Reservation not valid) 1. Reservation ID matches, not equal to 0x00 & SDR is not in Update mode / 2. SDR is in Update mode & Reservation ID equals to 0x00 */ if ( !(((g_BMCInfo[BMCInst].SDRConfig.ReservationID == ReservationID) && (0x00 != ReservationID) && (FALSE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR)) || ((TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR) && (0x00 == ReservationID)))) { if( TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR ) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REP_IN_UPDATE_MODE; }else /* Reservation ID doesn't match, return invalid reservation ID */ { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_RESERVATION_ID; } return INVALID_RECORD_ID; } while(TRUE) { pSDRRec = ReadSDRRepository(pSDRRec,BMCInst); if (pSDRRec == 0) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REC_NOT_PRESENT; return INVALID_RECORD_ID; } if (pSDRRec->ID == RecID) { #if (0x01 == MARK_FOR_DELETION_SUPPORT) pRec = ((E2ROMHdr_T *) pSDRRec) -1; pRec->Valid = 0x01; /* Mark this record for deletion */ FlushSDR((INT8U *)pRec, sizeof(pRec->Valid), nRet,BMCInst); #if IPM_DEVICE == 1 if (-1 == nRet) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte |= GST_CANNOT_ACCESS_SDR; } else { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_CANNOT_ACCESS_SDR; } #endif g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords--; g_BMCInfo[BMCInst].SDRConfig.NumMarkedRecords++; #else /* Delete SDR - delete the current SDR, and rearrange the subsequent SDR's */ pDestLocation = (INT8U*)(((E2ROMHdr_T *) pSDRRec) -1); deleteSDR_Size = (((E2ROMHdr_T *) pSDRRec) -1)->Len; pSrcData = pDestLocation + deleteSDR_Size; pFreeBytes = (INT8U*)SDR_FIRST_FREE_BYTE(BMCInst); size = (_FAR_ INT8U*) pFreeBytes - (_FAR_ INT8U*)pDestLocation; _fmemcpy (pDestLocation, pSrcData, size-deleteSDR_Size); _fmemset ((pFreeBytes - deleteSDR_Size), '\0', deleteSDR_Size ); g_BMCInfo[BMCInst].SDRConfig.SDRRAM->Size -= deleteSDR_Size; FlushSDR(pDestLocation, size, nRet,BMCInst); #if IPM_DEVICE == 1 if (-1 == nRet) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte |= GST_CANNOT_ACCESS_SDR; } else { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_CANNOT_ACCESS_SDR; } #endif g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords--; #endif /* Update the SDR Erase Timestamp */ g_BMCInfo[BMCInst].SDRConfig.SDRRAM->EraseTimeStamp = GetSelTimeStamp (BMCInst); g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.EraseTimeStamp = GetSelTimeStamp(BMCInst); /* Store the SDR Ease Time Stamp in NVR */ pBMCInfo->GenConfig.SDREraseTime = g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.EraseTimeStamp; FlushIPMI((INT8U*)&pBMCInfo->GenConfig,(INT8U*)&pBMCInfo->GenConfig,pBMCInfo->IPMIConfLoc.GenConfigAddr, sizeof(GENConfig_T),BMCInst); /* Update the repository info */ UpdateRepositoryInfo (BMCInst); /* Invalidate Reservation ID if any */ SDR_ReserveSDRRepository (BMCInst); return RecID; } } } /** * @brief Clear the SDR repository. * @param ReservationID - SDR reservation id. * @param InitOrStatus - Initiate erase or get status flag * @return 0 if success, -1 if error. **/ static int SDR_ClearSDRRepository (INT16U ReservationID, INT8U InitOrStatus,int BMCInst) { int nRet; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; /* Bail out with error, if both the conditions are False (Reservation not valid) 1. Reservation ID matches, not equal to 0x00 & SDR is not in Update mode / 2. SDR is in Update mode & Reservation ID equals to 0x00 */ if ( !(((g_BMCInfo[BMCInst].SDRConfig.ReservationID == ReservationID) && (0x00 != ReservationID) && (FALSE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR)) || ((TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR) && (0x00 == ReservationID)))) { if( TRUE == g_BMCInfo[BMCInst].SDRConfig.UpdatingSDR ) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_SDR_REP_IN_UPDATE_MODE; }else //Reservation ID doesn't match, return invalid reservation ID. { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_RESERVATION_ID; } return -1; } // AAh = initiate erase, 00h = get erasure status. if (InitOrStatus != CLEAR_SDR_INITIATE_ERASE && InitOrStatus != CLEAR_SDR_GET_STATUS) { g_BMCInfo[BMCInst].SDRConfig.SDRError = CC_INV_DATA_FIELD; return -1; } else if (InitOrStatus == CLEAR_SDR_GET_STATUS) { return 0; } _fmemset (((_FAR_ INT8U*)g_BMCInfo[BMCInst].SDRConfig.SDRRAM + 16), 0xFF,(pBMCInfo->IpmiConfig.SDRAllocationSize * 1024) - 16 ); /* Flush the NVRAM */ FlushSDR (g_BMCInfo[BMCInst].SDRConfig.SDRRAM, (pBMCInfo->IpmiConfig.SDRAllocationSize * 1024), nRet,BMCInst); #if IPM_DEVICE == 1 if (-1 == nRet) { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte |= GST_CANNOT_ACCESS_SDR; } else { g_BMCInfo[BMCInst].Msghndlr.SelfTestByte &= ~GST_CANNOT_ACCESS_SDR; } #endif /* Clear the fields of the SDR */ g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords = 0; g_BMCInfo[BMCInst].SDRConfig.LatestRecordID =0; #if (0x01 == MARK_FOR_DELETION_SUPPORT) g_BMCInfo[BMCInst].SDRConfig.NumMarkedRecords=0; #endif if (g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport & OVERFLOW_FLAG) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport &= ~OVERFLOW_FLAG; } #if IPM_DEVICE == 1 g_BMCInfo[BMCInst].Msghndlr.SelfTestByte |= GST_SDR_EMPTY; #endif g_BMCInfo[BMCInst].SDRConfig.SDRRAM->Size = 16; g_BMCInfo[BMCInst].SDRConfig.SDRRAM->EraseTimeStamp = GetSelTimeStamp (BMCInst); g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.EraseTimeStamp = GetSelTimeStamp(BMCInst); /* Store the SDR Ease Time Stamp in NVR */ pBMCInfo->GenConfig.SDREraseTime = g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.EraseTimeStamp; FlushIPMI((INT8U*)&pBMCInfo->GenConfig,(INT8U*)&pBMCInfo->GenConfig,pBMCInfo->IPMIConfLoc.GenConfigAddr, sizeof(GENConfig_T),BMCInst); /* Update the Repository Info */ UpdateRepositoryInfo (BMCInst); /* Invalidate Reservation ID if any */ SDR_ReserveSDRRepository (BMCInst); return 0; } /** * @brief Get the last SDR record. * @return the last SDR record. **/ static _FAR_ SDRRecHdr_T* GetLastSDRRec (int BMCInst) { _FAR_ SDRRecHdr_T* pSDRRec; pSDRRec = SDR_GetFirstSDRRec (BMCInst); while (TRUE) { _FAR_ SDRRecHdr_T* pCurSDRRec; /* Save this record and get the next record */ pCurSDRRec = pSDRRec; pSDRRec = SDR_GetNextSDRRec (pSDRRec,BMCInst); /* If we have reached past the last return the last record */ if (0 == pSDRRec) { return pCurSDRRec; } } } /** * @brief Update SDR repository information. **/ static void UpdateRepositoryInfo (int BMCInst) {_FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; /* Update the version */ g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.Version = SDR_VERSION; /* Update the record count */ g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.RecCt = htoipmi_u16 (g_BMCInfo[BMCInst].SDRConfig.SDRRAM->NumRecords); /* Update the free space available */ g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.FreeSpace = htoipmi_u16 (((pBMCInfo->IpmiConfig.SDRAllocationSize * 1024) - g_BMCInfo[BMCInst].SDRConfig.SDRRAM->Size)); /* Update the the operation support */ g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport=NO_SUPPORT; if(g_PDKCmdsHandle[PDKCMDS_PDKISCOMMANDENABLED]!= NULL) { if(((int(*)(INT8U,INT8U*,INT8U,int))g_PDKCmdsHandle[PDKCMDS_PDKISCOMMANDENABLED])(NETFN_STORAGE,NULL,CMD_RESERVE_SDR_REPOSITORY,BMCInst) == 0) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport|=RESERVE_SDR_SUPPORT; } if(((int(*)(INT8U,INT8U*,INT8U,int))g_PDKCmdsHandle[PDKCMDS_PDKISCOMMANDENABLED])(NETFN_STORAGE,NULL,CMD_GET_SDR_REPOSITORY_ALLOCATION_INFO,BMCInst) == 0) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport|=NON_MODAL_SUPPORT+GET_SDR_REPOSITORY_ALLOC_SUPPORT; } if(((int(*)(INT8U,INT8U*,INT8U,int))g_PDKCmdsHandle[PDKCMDS_PDKISCOMMANDENABLED])(NETFN_STORAGE,NULL,CMD_PARTIAL_ADD_SDR,BMCInst) == 0) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport|=PARTIAL_ADD_SDR_SUPPORT; } if(((int(*)(INT8U,INT8U*,INT8U,int))g_PDKCmdsHandle[PDKCMDS_PDKISCOMMANDENABLED])(NETFN_STORAGE,NULL,CMD_DELETE_SDR,BMCInst) == 0) { g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.OpSupport|=DELETE_SDR_SUPPORT; } } /* Update the repository allocation information */ g_BMCInfo[BMCInst].SDRConfig.RepositoryAllocInfo.NumAllocUnits = htoipmi_u16 (((pBMCInfo->IpmiConfig.SDRAllocationSize * 1024) - 16) / SDR_ALLOC_UNIT_SIZE); /* Because 16 bytes are reserved for header info */ g_BMCInfo[BMCInst].SDRConfig.RepositoryAllocInfo.AllocUnitSize = htoipmi_u16 (SDR_ALLOC_UNIT_SIZE); g_BMCInfo[BMCInst].SDRConfig.RepositoryAllocInfo.NumFreeAllocUnits = htoipmi_u16 (ipmitoh_u16 (g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.FreeSpace) / SDR_ALLOC_UNIT_SIZE); g_BMCInfo[BMCInst].SDRConfig.RepositoryAllocInfo.LargestFreeBlock = htoipmi_u16 (ipmitoh_u16 (g_BMCInfo[BMCInst].SDRConfig.RepositoryInfo.FreeSpace) / SDR_ALLOC_UNIT_SIZE); g_BMCInfo[BMCInst].SDRConfig.RepositoryAllocInfo.MaxRecSize = SDR_MAX_RECORD_SIZE / SDR_ALLOC_UNIT_SIZE; } /** * @brief SDR initialization agent. **/ static void SDRInitAgent (int BMCInst) { INT8U i,Count =0; INT8U CmdRes [MAX_RES_LEN]; _FAR_ SDRRecHdr_T* pSDRRec; HQueue_T IfcQ; _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst]; if(g_PDKHandle[PDK_BEFOREINITAGENT] != NULL) { if(-1 == ((int(*)(int))g_PDKHandle[PDK_BEFOREINITAGENT]) (BMCInst)) { return; } } #if SET_EVENT_RECEIVER == 1 /* Turn off Event Generation */ { SetEvtRcvReq_T SetEvtRcvReq = { 0xFF, 0 }; SetEventReceiver ((_NEAR_ INT8U*)&SetEvtRcvReq, sizeof (SetEvtRcvReq_T), CmdRes,BMCInst); } #endif /* Get the MMC Controller addresses*/ pSDRRec = SDR_GetFirstSDRRec (BMCInst); if(0 != GetQueueHandle(LAN_IFC_Q,&IfcQ,BMCInst)) { IPMI_WARNING("Error in getting LanIfcQ Handle \n"); } for (i=0; i < pBMCInfo->SDRConfig.SDRRAM->NumRecords && pSDRRec != NULL; i++) { if(MANAGEMENT_DEV_LOC_REC == pSDRRec->Type) { _FAR_ MgmtCtrlrDevLocator_T* pMgmtDevLocRec = (_FAR_ MgmtCtrlrDevLocator_T*)pSDRRec; if(pBMCInfo->IpmiConfig.BMCSlaveAddr != pMgmtDevLocRec->DevSlaveAddr ) { pBMCInfo->MgmtTbl[Count].OWNERID=pMgmtDevLocRec->DevSlaveAddr; pBMCInfo->MgmtTbl[Count++].PowerNotification=pMgmtDevLocRec->PowerStateNotification; } } pSDRRec = SDR_GetNextSDRRec (pSDRRec,BMCInst); } pBMCInfo->MgmtTbl[Count].OWNERID= 0xff; #if SUPPORT_MULTI_CONTROLLER == 1 /* Sending the Set Event Reciver Disable Command to all MMC in IPMB BUS */ if(pBMCInfo->IpmiConfig.PrimaryIPMBSupport == 0x01) { for(i=0; iResAddr =pBMCInfo->MgmtTbl[i].OWNERID; pIPMIMsgHdr->NetFnLUN = (NETFN_SENSOR<< 2) | BMC_LUN_00; pIPMIMsgHdr->ChkSum = ~(pIPMIMsgHdr->ResAddr + pIPMIMsgHdr->NetFnLUN) + 1; pIPMIMsgHdr->ReqAddr = pBMCInfo->IpmiConfig.BMCSlaveAddr; pBMCInfo->SDRConfig.IPMB_Seqnum++; if (pBMCInfo->SDRConfig.IPMB_Seqnum >= 0x3F) { pBMCInfo->SDRConfig.IPMB_Seqnum = 0xFF; } pIPMIMsgHdr->RqSeqLUN = pBMCInfo->SDRConfig.IPMB_Seqnum<< 2; /* Request Seq Num */ pIPMIMsgHdr->RqSeqLUN |= BMC_LUN_00; /* LUN =00 */ pIPMIMsgHdr->Cmd = CMD_SET_EVENT_RECEIVER; SetEvtRcvReq->RcvSlaveAddr =0xFF ; SetEvtRcvReq->RcvLUN =BMC_LUN_00; Req.Param=BRIDGING_REQUEST; Req.Channel=PRIMARY_IPMB_CHANNEL; Req.Data [sizeof (IPMIMsgHdr_T) + sizeof(SetEvtRcvReq_T)] = CalculateCheckSum2 (Req.Data, sizeof (IPMIMsgHdr_T) + sizeof(SetEvtRcvReq_T)); Req.Size = sizeof(IPMIMsgHdr_T) + sizeof(SetEvtRcvReq_T) +1 ; //Plus 1 for Check sum /* Post Msg to IPMB task to send the set event receiver */ if ( -1 != IfcQ ) { if(0 != PostMsg(&Req, IPMB_PRIMARY_IFC_Q,BMCInst)) { IPMI_WARNING ("SDR.c : Error posting message to IPMBIfc_Q\n"); } pBMCInfo->MgmtTbl[i].Status =TRUE; } } } #endif #if SUPPORT_MULTI_CONTROLLER == 1 /* Sending the Run Initalization Command to all MMC in IPMB BUS */ if(pBMCInfo->IpmiConfig.PrimaryIPMBSupport == 0x01) { for(i=0; iResAddr =pBMCInfo->MgmtTbl[i].OWNERID; pIPMIMsgHdr->NetFnLUN = (NETFN_STORAGE<< 2) | BMC_LUN_00; /* Get Device ID */ // pIPMIMsgHdr->NetFnLUN = (NETFN_APP<< 2) | BMC_LUN_00; pIPMIMsgHdr->ChkSum = ~(pIPMIMsgHdr->ResAddr + pIPMIMsgHdr->NetFnLUN) + 1; pIPMIMsgHdr->ReqAddr = pBMCInfo->IpmiConfig.BMCSlaveAddr; Req.Channel=PRIMARY_IPMB_CHANNEL; g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum++; if (g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum >= 0x3F) { g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum = 0xFF; } pIPMIMsgHdr->RqSeqLUN = g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum<< 2; /* Request Seq Num */ pIPMIMsgHdr->RqSeqLUN |= BMC_LUN_00; /* LUN =00 */ Req.Param=BRIDGING_REQUEST; pIPMIMsgHdr->Cmd = CMD_RUN_INITIALIZATION_AGENT; Req.Data[sizeof(IPMIMsgHdr_T)]=0x1; Req.Data [sizeof (IPMIMsgHdr_T) + 1] = CalculateCheckSum2 (Req.Data, sizeof (IPMIMsgHdr_T) +1); Req.Size = sizeof(IPMIMsgHdr_T) + 2; //Plus 2 for req data's if ( -1 !=IfcQ ) { if(0 != PostMsg(&Req, IPMB_PRIMARY_IFC_Q,BMCInst)) { IPMI_WARNING ("SDR.c : Error posting message to IPMBIfc_Q\n"); } pBMCInfo->MgmtTbl[i].Status =TRUE; } } } #endif pSDRRec = SDR_GetFirstSDRRec (BMCInst); for (i=0; i < pBMCInfo->SDRConfig.SDRRAM->NumRecords && pSDRRec != NULL; i++) { if (FULL_SDR_REC == pSDRRec->Type) { /* For all records of type 01h */ _FAR_ FullSensorRec_T* pFullRec = (_FAR_ FullSensorRec_T*)pSDRRec; INT16U ValidMask = htoipmi_u16(0x0FFF); // If not a threshold sensor, then 15 event bits are used. if (pFullRec->EventTypeCode != 0x01) { ValidMask = htoipmi_u16(0x7FFF); } /* Disable Event & Scanning messages, if Disable is supported */ if (0x03 != (pFullRec->SensorCaps & 0x03)) { SetSensorEventEnableReq_T SetSEReq; // disable all events for sensor SetSEReq.SensorNum = pFullRec->SensorNum; SetSEReq.Flags = DISABLE_SELECTED_EVENT_MSG; // Event Disabled SetSEReq.AssertionMask = ValidMask; SetSEReq.DeAssertionMask = ValidMask; SetSensorEventEnable ((_NEAR_ INT8U*)&SetSEReq, sizeof (SetSensorEventEnableReq_T), CmdRes,BMCInst); } /* Set Sensor Type */ #if SET_SENSOR_TYPE != UNIMPLEMENTED if (pFullRec->SensorInit & BIT2) { /* Set Sensor Type */ SetSensorTypeReq_T SetSensorTypeReq; SetSensorTypeReq.SensorNum = pFullRec->SensorNum; SetSensorTypeReq.SensorType = pFullRec->SensorType; SetSensorTypeReq.EventTypeCode = pFullRec->EventTypeCode; SetSensorType ((_NEAR_ INT8U*)&SetSensorTypeReq, sizeof(SetSensorTypeReq), CmdRes,BMCInst); } #endif /* Set Sensor Thresholds */ { SetSensorThresholdReq_T SetThresholdReq; SetThresholdReq.SensorNum = pFullRec->SensorNum; SetThresholdReq.SetFlags = ((pFullRec->DiscreteReadingMask >> 8) & 0x3F); if (pFullRec->SensorInit & BIT4) { SetThresholdReq.LowerNonCritical = pFullRec->LowerNonCritical; SetThresholdReq.LowerCritical = pFullRec->LowerCritical; SetThresholdReq.LowerNonRecoverable = pFullRec->LowerNonRecoverable; SetThresholdReq.UpperNonCritical = pFullRec->UpperNonCritical; SetThresholdReq.UpperCritical = pFullRec->UpperCritical; SetThresholdReq.UpperNonRecoverable = pFullRec->UpperNonRecoverable; SetSensorThresholds ((_NEAR_ INT8U*)&SetThresholdReq, sizeof (SetSensorThresholdReq_T), CmdRes,BMCInst); } } /* Set Sensor Hysteresis */ { SetSensorHysterisisReq_T SetHysteresisReq; SetHysteresisReq.SensorNum = pFullRec->SensorNum; SetHysteresisReq.Reserved = 0; if (pFullRec->SensorInit & BIT3) //Added for DR#31091 { SetHysteresisReq.PositiveHysterisis = pFullRec->PositiveHysterisis; SetHysteresisReq.NegativeHysterisis = pFullRec->NegativeHysterisis; SetSensorHysterisis ((_NEAR_ INT8U*)&SetHysteresisReq, sizeof (SetSensorHysterisisReq_T), CmdRes,BMCInst); } } /* Enable Event & Scanning messages, if Disabled */ if (0x03 != (pFullRec->SensorCaps & 0x03)) { SetSensorEventEnableReq_T SetSEReq; SetSEReq.SensorNum = pFullRec->SensorNum; SetSEReq.Flags = (pFullRec->SensorInit & BIT6) | ((pFullRec->SensorInit & BIT5) << 2) | ENABLE_SELECTED_EVENT_MSG; // Event Enabled SetSEReq.AssertionMask = (pFullRec->AssertionEventMask & ValidMask); SetSEReq.DeAssertionMask = (pFullRec->DeAssertionEventMask & ValidMask); SetSensorEventEnable ((_NEAR_ INT8U*)&SetSEReq, sizeof (SetSensorEventEnableReq_T), CmdRes,BMCInst); } } if (pSDRRec->Type == COMPACT_SDR_REC) { _FAR_ CompactSensorRec_T* pCompactRec = (_FAR_ CompactSensorRec_T*)pSDRRec; INT16U ValidMask = htoipmi_u16(0x0FFF); // If not a threshold sensor, then 15 event bits are used. if (pCompactRec->EventTypeCode != 0x01) { ValidMask = htoipmi_u16(0x7FFF); } /* Disable Event & Scanning messages, if Disable is supported */ if (0x03 != (pCompactRec->SensorCaps & 0x03)) { SetSensorEventEnableReq_T SetSEReq; SetSEReq.SensorNum = pCompactRec->SensorNum; SetSEReq.Flags = DISABLE_SELECTED_EVENT_MSG; // Event Disabled SetSEReq.AssertionMask = ValidMask; SetSEReq.DeAssertionMask = ValidMask; SetSensorEventEnable ((_NEAR_ INT8U*)&SetSEReq, sizeof (SetSensorEventEnableReq_T), CmdRes,BMCInst); } /* Set Sensor Type */ #if SET_SENSOR_TYPE != UNIMPLEMENTED if (pCompactRec->SensorInit & BIT2) { /* Set Sensor Type */ SetSensorTypeReq_T SetSensorTypeReq; SetSensorTypeReq.SensorNum = pCompactRec->SensorNum; SetSensorTypeReq.SensorType = pCompactRec->SensorType; SetSensorTypeReq.EventTypeCode = pCompactRec->EventTypeCode; SetSensorType ((_NEAR_ INT8U*)&SetSensorTypeReq, sizeof(SetSensorTypeReq), CmdRes,BMCInst); } #endif /* Set Sensor Hysteresis */ { SetSensorHysterisisReq_T SetHysteresisReq; SetHysteresisReq.SensorNum = pCompactRec->SensorNum; SetHysteresisReq.Reserved = 0; SetHysteresisReq.PositiveHysterisis = pCompactRec->PositiveHysteris; SetHysteresisReq.NegativeHysterisis = pCompactRec->NegativeHysterisis; SetSensorHysterisis ((_NEAR_ INT8U*)&SetHysteresisReq, sizeof (SetSensorHysterisisReq_T), CmdRes,BMCInst); } /* Enable Event & Scanning messages, if Disabled */ if (0x03 != (pCompactRec->SensorCaps & 0x03)) { SetSensorEventEnableReq_T SetSEReq; SetSEReq.SensorNum = pCompactRec->SensorNum; SetSEReq.Flags = (pCompactRec->SensorInit & BIT6) | ((pCompactRec->SensorInit & BIT5) << 2) |ENABLE_SELECTED_EVENT_MSG ; // Event Enabled SetSEReq.AssertionMask = (pCompactRec->AssertionEventMask & ValidMask); SetSEReq.DeAssertionMask = (pCompactRec->DeAssertionEventMask & ValidMask); SetSensorEventEnable ((_NEAR_ INT8U*)&SetSEReq, sizeof (SetSensorEventEnableReq_T), CmdRes,BMCInst); } } pSDRRec = SDR_GetNextSDRRec (pSDRRec,BMCInst); } #if SET_EVENT_RECEIVER == 0 /* Enable Event Generation */ { SetEvtRcvReq_T SetEvtRcvReq = { 0x20, 0 }; SetEventReceiver ((_NEAR_ INT8U*)&SetEvtRcvReq, sizeof (SetEvtRcvReq_T), CmdRes,BMCInst); } #endif #if SUPPORT_MULTI_CONTROLLER == 1 /* Sending the Set Event Reciver enable Command to all MMC in IPMB BUS */ for(i=0;iResAddr =pBMCInfo->MgmtTbl[i].OWNERID; pIPMIMsgHdr->NetFnLUN = (NETFN_SENSOR<< 2) | BMC_LUN_00; pIPMIMsgHdr->ChkSum = ~(pIPMIMsgHdr->ResAddr + pIPMIMsgHdr->NetFnLUN) + 1; pIPMIMsgHdr->ReqAddr = pBMCInfo->IpmiConfig.BMCSlaveAddr; Req.Channel=PRIMARY_IPMB_CHANNEL; g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum++; if (g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum >= 0x3F) { g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum = 0xFF; } pIPMIMsgHdr->RqSeqLUN = g_BMCInfo[BMCInst].SDRConfig.IPMB_Seqnum<< 2; /* Request Seq Num */ pIPMIMsgHdr->RqSeqLUN |= BMC_LUN_00; /* LUN =00 */ pIPMIMsgHdr->Cmd = CMD_SET_EVENT_RECEIVER; SetEvtRcvReq->RcvSlaveAddr = pBMCInfo->IpmiConfig.BMCSlaveAddr; SetEvtRcvReq->RcvLUN =BMC_LUN_00; Req.Param=BRIDGING_REQUEST; Req.Data [sizeof (IPMIMsgHdr_T) + sizeof(SetEvtRcvReq_T)] = CalculateCheckSum2 (Req.Data, sizeof (IPMIMsgHdr_T) + sizeof(SetEvtRcvReq_T)); Req.Size = sizeof(IPMIMsgHdr_T) + sizeof(SetEvtRcvReq_T)+1; // plus 1 for checksum /* Post Msg to IPMB task to send the set event receiver */ if ( -1 != IfcQ ) { if(0 != PostMsg(&Req, IPMB_PRIMARY_IFC_Q,BMCInst)) { IPMI_WARNING ("SDR.c : Error posting message to IPMBIfc_Q\n"); } pBMCInfo->MgmtTbl[i].Status =TRUE; } //PDK_SMCDelay(pBMCInfo->MgmtTbl[i].OWNERID); //PDK_SMCDelay(0x40); //sleep(3); } #endif if(g_PDKHandle[PDK_AFTERINITAGENT] != NULL) { ((int(*)(INT8U,int))g_PDKHandle[PDK_AFTERINITAGENT]) (CmdRes[0],BMCInst); } return; } #endif /* SDR_DEVICE */