SEL.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. /****************************************************************
  2. ****************************************************************
  3. ** **
  4. ** (C)Copyright 2005-2006, American Megatrends . **
  5. ** **
  6. ** All Rights Reserved. **
  7. ** **
  8. ** 6145-F, Northbelt Parkway, Norcross, **
  9. ** **
  10. ** Georgia - 30071, USA. Phone-(770)-246-8600. **
  11. ** **
  12. ****************************************************************
  13. *****************************************************************
  14. *
  15. * Sel.c
  16. * Sel Command Handler
  17. *
  18. * Author: Bakka Ravinder Reddy <bakkar@ami.com>
  19. *
  20. *****************************************************************/
  21. #define ENABLE_DEBUG_MACROS 0
  22. #include "SEL.h"
  23. #include "com_IPMI_Sensor.h"
  24. #include "SELRecord.h"
  25. #include <string.h>
  26. //#include "Storlead_BMC_LIb.h"
  27. #include "Support.h"
  28. #include "main.h"
  29. #include <stdio.h>
  30. #include "Api.h"
  31. /* Reserved bit macro definitions */
  32. #define RESERVED_BITS_PARTIALADDSELENTRY 0xF0 //(BIT7 | BIT6 | BIT5 | BIT4)
  33. #if SEL_DEVICE == 1
  34. /*** Local Definitions ***/
  35. #define SEL_RECORD_SIZE 16
  36. #define CLR_SEL_PASSWORD_STR_LEN 3
  37. #define CLEAR_SEL_GET_STATUS 0x00
  38. #define CLEAR_SEL_ACTION 0xaa
  39. #define SEL_ERASE_IN_PROGRESS 0x00
  40. #define SEL_ERASE_COMPLETED 0x01
  41. #define SEL_ALLOC_UNIT_SIZE 0x10
  42. #define SEL_MAX_RECORD_SIZE 0x10
  43. #define INVALID_RECORD_ID 0x00
  44. #define OVERFLOW_FLAG 0x80
  45. #define DELETE_SEL_SUPPORT 0x08
  46. #define PARTIAL_ADD_SEL_SUPPORT 0x04
  47. #define RESERVE_SEL_SUPPORT 0x02
  48. #define GET_SEL_ALLOC_SUPPORT 0x01
  49. #define NO_SUPPORT 0x00
  50. #define STATUS_DELETE_SEL ((uint8_t)0xA5)
  51. #define SEL_ALMOST_FULL_PERCENTAGE 75
  52. #define SEL_PARTIAL_ADD_REQUEST_MISC_BYTES 6
  53. #define SEL_PARTIAL_ADD_CMD_MAX_LEN 22
  54. #define SEL_INITIALIZED 0x01
  55. #define SEL_UNINITIALIZED 0x00
  56. #define PRE_CLK_SET 0x00
  57. #define POST_CLK_SET 0x80
  58. /*** Prototype Declaration ***/
  59. static SELRec_T* GetNextSELEntry ( SELRec_T* rec);
  60. static SELRec_T* GetSELRec(uint16_t RecID);
  61. static uint8_t SELTimeClockSync(uint8_t Action);
  62. /*** Global variables ***/
  63. /*** Module variables ***/
  64. //SELRepository_T* m_sel;
  65. #define SENSOR_TYPE_EVT_LOGGING 0x10
  66. /* System Event Message */
  67. static uint8_t m_SysEventMsg [] = {
  68. 0x00, 0x00, //Record ID
  69. 0x02, //Record Type is System
  70. 0x00, 0x00, 0x00, 0x00, //TimeStamp
  71. 0x20, 0x00, //Generator ID is BMC
  72. IPMI_EVM_REVISION,
  73. SENSOR_TYPE_SYSTEM_EVENT,
  74. 0x6F,
  75. 0xFF,
  76. 0xFF,
  77. 0xFF,
  78. 0xFF
  79. };
  80. /*---------------------------------------
  81. * GetSELInfo
  82. *---------------------------------------*/
  83. int
  84. GetSELInfo ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  85. {
  86. SELInfo_T* pSelInfo = ( SELInfo_T*) pRes;
  87. SELRepository_T* m_sel;
  88. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  89. pSelInfo->RecCt = m_sel->NumRecords;
  90. pSelInfo->FreeSpace = (g_BMCInfo.SELConfig.MaxSELRecord - m_sel->NumRecords) * sizeof(SELRec_T);
  91. pSelInfo->AddTimeStamp = (m_sel->AddTimeStamp);
  92. pSelInfo->EraseTimeStamp =( m_sel->EraseTimeStamp);
  93. pSelInfo->CompletionCode = CC_NORMAL;
  94. pSelInfo->Version = SEL_VERSION;
  95. pSelInfo->OpSupport=NO_SUPPORT;
  96. if(g_BMCInfo.SELConfig.SELOverFlow == TRUE)
  97. {
  98. pSelInfo->OpSupport |= OVERFLOW_FLAG;
  99. }
  100. pSelInfo->OpSupport|= RESERVE_SEL_SUPPORT;
  101. pSelInfo->OpSupport|= GET_SEL_ALLOC_SUPPORT;
  102. pSelInfo->OpSupport|=PARTIAL_ADD_SEL_SUPPORT;
  103. pSelInfo->OpSupport|= DELETE_SEL_SUPPORT;
  104. return sizeof (SELInfo_T);
  105. }
  106. /*---------------------------------------
  107. * GetSELAllocationInfo
  108. *---------------------------------------*/
  109. int
  110. GetSELAllocationInfo( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  111. {
  112. SELAllocInfo_T* pAllocInfo = ( SELAllocInfo_T*) pRes;
  113. SELRepository_T* m_sel;
  114. pAllocInfo->CompletionCode = CC_NORMAL;
  115. pAllocInfo->NumAllocUnits = 1;
  116. pAllocInfo->AllocUnitSize = (sizeof (SELRec_T));
  117. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  118. pAllocInfo->NumFreeAllocUnits = ((g_BMCInfo.SELConfig.MaxSELRecord - m_sel->NumRecords));
  119. pAllocInfo->LargestFreeBlock = (sizeof (SELRec_T));
  120. pAllocInfo->MaxRecSize = (sizeof (SELRec_T));
  121. return sizeof (SELAllocInfo_T);
  122. }
  123. /*---------------------------------------
  124. * ReserveSEL
  125. *---------------------------------------*/
  126. int
  127. ReserveSEL ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  128. {
  129. ReserveSELRes_T* pRsvSelRes = ( ReserveSELRes_T*) pRes;
  130. g_BMCInfo.SELConfig.SelReservationID++;
  131. if (0 == g_BMCInfo.SELConfig.SelReservationID) { g_BMCInfo.SELConfig.SelReservationID = 1; }
  132. pRsvSelRes->CompletionCode = CC_NORMAL;
  133. pRsvSelRes->ReservationID = g_BMCInfo.SELConfig.SelReservationID;
  134. g_BMCInfo.SELConfig.PartialAdd=0 ;//Addded for DR#30287
  135. return sizeof (ReserveSELRes_T);
  136. }
  137. /*---------------------------------------
  138. * GetSELEntry
  139. *---------------------------------------*/
  140. int
  141. GetSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  142. {
  143. SELRec_T* pSelRec;
  144. SELRec_T* pNextSelRec;
  145. GetSELReq_T* pGetSelReq = ( GetSELReq_T*) pReq;
  146. GetSELRes_T* pGetSelRes = ( GetSELRes_T*) pRes;
  147. uint16_t LastRecID = 0,FirstRecID = 0;
  148. SELRepository_T* m_sel = NULL;
  149. uint16_t NumRecords = 0;
  150. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  151. NumRecords = m_sel->NumRecords;
  152. pGetSelRes->CompletionCode = CC_NORMAL;
  153. // if (pGetSelReq->ReservationID && g_BMCInfo.SELConfig.RsrvIDCancelled)
  154. // {
  155. // pGetSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  156. // return sizeof (uint8_t);
  157. // }
  158. /* Check if the reservation IDs match */
  159. if ((g_BMCInfo.SELConfig.SelReservationID != pGetSelReq->ReservationID) &&
  160. ((0 != pGetSelReq->Offset) || (pGetSelReq->ReservationID != 0)) )
  161. {
  162. pGetSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  163. return sizeof (uint8_t);
  164. }
  165. if (0 == m_sel->NumRecords)
  166. {
  167. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  168. return sizeof (uint8_t);
  169. }
  170. FirstRecID = m_sel->FirstRecID;
  171. LastRecID = m_sel->LastRecID;
  172. /* If ID == 0x0000 return first record */
  173. if (0 == pGetSelReq->RecID)
  174. {
  175. pSelRec = GetSELRec(FirstRecID);
  176. if (0 == pSelRec)
  177. {
  178. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  179. return sizeof(uint8_t);
  180. }
  181. else
  182. {
  183. pNextSelRec = GetNextSELEntry (pSelRec);
  184. }
  185. if (0 == pNextSelRec)
  186. {
  187. pGetSelRes->NextRecID = 0xFFFF;
  188. }
  189. else
  190. {
  191. pGetSelRes->NextRecID = pNextSelRec->EvtRecord.hdr.ID;
  192. }
  193. pGetSelReq->RecID = FirstRecID;
  194. }
  195. else if (0xFFFF == pGetSelReq->RecID)
  196. {
  197. pSelRec = GetSELRec(LastRecID);
  198. if(0== pSelRec)
  199. {
  200. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  201. return sizeof(uint8_t);
  202. }
  203. pGetSelRes->NextRecID = 0xFFFF;
  204. }
  205. pSelRec = GetSELRec(pGetSelReq->RecID);
  206. if (pSelRec == 0)
  207. {
  208. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  209. return sizeof (uint8_t);
  210. }
  211. if(LastRecID == pGetSelReq->RecID)
  212. {
  213. pGetSelRes->NextRecID = 0xFFFF;
  214. }
  215. else
  216. {
  217. pNextSelRec = GetNextSELEntry (pSelRec);
  218. if (0 == pNextSelRec)
  219. {
  220. /*If the given SEL ID is the maximum SEL record ,then the next SEL ID will be the First SEL ID
  221. in case of Circular SEL Implementation */
  222. if(g_BMCInfo.SELConfig.MaxSELRecord == NumRecords)
  223. {
  224. pGetSelRes->NextRecID = 0;
  225. }
  226. else
  227. {
  228. pGetSelRes->NextRecID = 0xFFFF;
  229. }
  230. }
  231. else
  232. {
  233. pGetSelRes->NextRecID = pNextSelRec->EvtRecord.hdr.ID;
  234. }
  235. }
  236. if ((0xff == pGetSelReq->Size) && (sizeof (SELEventRecord_T) >= pGetSelReq->Offset))
  237. {
  238. pGetSelReq->Size = sizeof (SELEventRecord_T) - pGetSelReq->Offset;
  239. }
  240. // Check for the request bytes and offset not to exceed the actual size of the record
  241. else if ((pGetSelReq->Size > (sizeof(SELEventRecord_T))) ||
  242. (pGetSelReq->Offset > (sizeof(SELEventRecord_T))) ||
  243. (pGetSelReq->Size > ((sizeof(SELEventRecord_T))- pGetSelReq->Offset)))
  244. {
  245. pGetSelRes->CompletionCode = CC_PARAM_OUT_OF_RANGE;
  246. return sizeof (uint8_t);
  247. }
  248. memcpy(pGetSelRes + 1, (( uint8_t*)&pSelRec->EvtRecord) +
  249. pGetSelReq->Offset, pGetSelReq->Size);
  250. return sizeof(GetSELRes_T) + pGetSelReq->Size;
  251. }
  252. /*---------------------------------------
  253. * LockedAddSELEntry with SEL locked
  254. *---------------------------------------*/
  255. int
  256. LockedAddSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  257. {
  258. AddSELRes_T* pAddSelRes = ( AddSELRes_T*) pRes;
  259. SELRecHdr_T* pSelRec = ( SELRecHdr_T*) pReq;
  260. uint16_t index = 0;
  261. uint16_t NumRecords=0;
  262. // m_sel = ( SELRepository_T*)g_BMCInfo.pSEL;
  263. NumRecords = (( SELRepository_T*)g_BMCInfo.pSEL)->NumRecords;
  264. /* If we dont have enough space return invalid ID */
  265. if (NumRecords >= g_BMCInfo.SELConfig.MaxSELRecord)
  266. {
  267. if (((( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex == g_BMCInfo.SELConfig.MaxSELRecord))
  268. {
  269. (( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex = 0;
  270. }
  271. /*Reset the SEL OverFlow Flag in Circular SEL mode*/
  272. g_BMCInfo.SELConfig.SELOverFlow = FALSE;
  273. }
  274. if((( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID == 0xFFFE)
  275. {
  276. (( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID = 0;
  277. }
  278. if( (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID == 0xFFFE)
  279. {
  280. (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID = 0;
  281. }
  282. if(NumRecords == g_BMCInfo.SELConfig.MaxSELRecord)
  283. {
  284. (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID +=1;
  285. }
  286. /* time stamp for record type less than 0xE0*/
  287. if (pSelRec->Type < 0xE0)
  288. {
  289. // The timestamp gets set if the hook is not present or if the hook returns -1
  290. pSelRec->TimeStamp = GetSelTimeStamp ();
  291. }
  292. pSelRec->ID = ((( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID) + 1;
  293. index = (( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex ;
  294. memcpy (&(( SELRepository_T*)g_BMCInfo.pSEL)->SELRecord [index].EvtRecord , pSelRec,
  295. sizeof (SELEventRecord_T));
  296. (( SELRepository_T*)g_BMCInfo.pSEL)->SELRecord [index].Valid = VALID_RECORD;
  297. (( SELRepository_T*)g_BMCInfo.pSEL)->SELRecord [index].Len = sizeof (SELEventRecord_T) + 2;
  298. if (( NumRecords < g_BMCInfo.SELConfig.MaxSELRecord))
  299. {
  300. NumRecords = ++(( SELRepository_T*)g_BMCInfo.pSEL)->NumRecords;
  301. }
  302. /*Update the First SEL entry after clear SEL command*/
  303. if( (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID == 0)
  304. {
  305. (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID = pSelRec->ID;
  306. }
  307. (( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID += 1;
  308. (( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex += 1;
  309. g_BMCInfo.SELConfig.LastEvtTS = (( SELRepository_T*)g_BMCInfo.pSEL)->AddTimeStamp = GetSelTimeStamp ();
  310. pAddSelRes->CompletionCode = CC_NORMAL;
  311. pAddSelRes->RecID = pSelRec->ID;
  312. return sizeof (AddSELRes_T);
  313. }
  314. /*---------------------------------------
  315. * AddSELEntry
  316. *---------------------------------------*/
  317. int
  318. AddSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  319. {
  320. int reslen = 0;
  321. reslen = LockedAddSELEntry(pReq, ReqLen, pRes);
  322. UpdateFlash();
  323. return reslen;
  324. }
  325. /*---------------------------------------
  326. * PartialAddSELEntry
  327. *---------------------------------------*/
  328. int
  329. PartialAddSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  330. {
  331. PartialAddSELReq_T* pParAddSelReq = ( PartialAddSELReq_T*) pReq;
  332. PartialAddSELRes_T* pParAddSelRes = ( PartialAddSELRes_T*) pRes;
  333. uint16_t RecordID=0, ReservationID=0;
  334. uint8_t RecordOffset=0,Len=0;
  335. SELRepository_T* m_sel = ( SELRepository_T*)g_BMCInfo.pSEL;
  336. ReservationID = (uint16_t)(pParAddSelReq->LSBReservationID |
  337. ((uint16_t)pParAddSelReq->MSBReservationID << 8));
  338. RecordID = (uint16_t)(((uint16_t)pParAddSelReq->MSBRecordID << 8) |
  339. pParAddSelReq->LSBRecordID);
  340. RecordOffset = (uint32_t)pParAddSelReq->Offset;
  341. Len = ReqLen;
  342. // /* Checks for the Valid Reservation ID */
  343. // while(g_BMCInfo.SELConfig.RsrvIDCancelled)
  344. // {
  345. // if((ReservationID == 0) && (pParAddSelReq->Progress == 1) && (ReqLen == SEL_PARTIAL_ADD_CMD_MAX_LEN))
  346. // break;
  347. // else
  348. // {
  349. // if(ReqLen < SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)
  350. // {
  351. // pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  352. // return(sizeof(PartialAddSELRes_T));
  353. // }
  354. // else
  355. // {
  356. // pParAddSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  357. // pParAddSelRes->RecID = 0;
  358. // return(sizeof(PartialAddSELRes_T));
  359. // }
  360. // }
  361. // }
  362. /* Check for the reserved bytes should b zero */
  363. if ( 0 != (pParAddSelReq->Progress & RESERVED_BITS_PARTIALADDSELENTRY ) )
  364. {
  365. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  366. return sizeof(uint8_t);
  367. }
  368. if((pParAddSelReq->Progress>1)|| (pParAddSelReq->Offset>SEL_RECORD_SIZE))
  369. {
  370. pParAddSelRes->CompletionCode = CC_PARAM_OUT_OF_RANGE;
  371. return(sizeof(PartialAddSELRes_T));
  372. }
  373. else if(g_BMCInfo.SELConfig.PartialAdd==0)
  374. {
  375. if(((RecordOffset+(Len-SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)==SEL_RECORD_SIZE)&&(pParAddSelReq->Progress!=1))||
  376. (( RecordOffset+(Len-SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)<SEL_RECORD_SIZE)&&(pParAddSelReq->Progress==1))||
  377. (RecordOffset+(Len-SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)>SEL_RECORD_SIZE))
  378. {
  379. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  380. return(sizeof(PartialAddSELRes_T));
  381. }
  382. }
  383. else if((ReservationID==0)&&(Len==SEL_PARTIAL_ADD_CMD_MAX_LEN)&&(pParAddSelReq->Progress!=1))
  384. {
  385. pParAddSelRes->CompletionCode =CC_INV_DATA_FIELD;
  386. return(sizeof(PartialAddSELRes_T));
  387. }
  388. /*Checking for reservation ID <<Added few more condition checking */
  389. if(((ReservationID == g_BMCInfo.SELConfig.SelReservationID)&&(g_BMCInfo.SELConfig.PartialAdd==0)) ||
  390. ((ReservationID == g_BMCInfo.SELConfig.SelReservationID) && (ReqLen <= SEL_PARTIAL_ADD_CMD_MAX_LEN))
  391. ||((ReservationID == 0) && (pParAddSelReq->Progress == 1) && (ReqLen == SEL_PARTIAL_ADD_CMD_MAX_LEN)))
  392. {
  393. if(g_BMCInfo.SELConfig.PartialAdd==0)
  394. {
  395. // Requirement says partial adds must start at 0, with no
  396. // gaps or overlaps. First request must be to RecordID = 0.
  397. if ((RecordID != 0) || (RecordOffset != 0))
  398. {
  399. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  400. return(sizeof(PartialAddSELRes_T));// Modified from sizeof (uint8_t);
  401. }
  402. memset((void *)&g_BMCInfo.SELConfig.SelPartialAddRecord, 0xFF, sizeof(SELEventRecord_T));
  403. // Fill in the record ID into the partial add record. The
  404. // record ID is always the offset in memory of where the
  405. // SEL record starts (which includes a delete time first).
  406. RecordID = g_BMCInfo.SELConfig.SelPartialAddRecord.hdr.ID = m_sel->LastRecID +1;
  407. g_BMCInfo.SELConfig.PartialAddRecordID=RecordID;
  408. g_BMCInfo.SELConfig.PartialAddRecOffset = 0;
  409. g_BMCInfo.SELConfig.PartialAdd=1;
  410. }
  411. else
  412. {
  413. if (RecordID != g_BMCInfo.SELConfig.PartialAddRecordID)
  414. {
  415. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  416. return sizeof (PartialAddSELRes_T);
  417. }
  418. }
  419. if (pParAddSelReq->Offset != g_BMCInfo.SELConfig.PartialAddRecOffset)
  420. {
  421. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  422. return(sizeof(PartialAddSELRes_T));
  423. }
  424. // Checking for Exceeding data values //
  425. if((g_BMCInfo.SELConfig.PartialAddRecOffset + Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES) > SEL_MAX_RECORD_SIZE)
  426. {
  427. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  428. return(sizeof(PartialAddSELRes_T));
  429. }
  430. if((( g_BMCInfo.SELConfig.PartialAddRecOffset + Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES) < SEL_MAX_RECORD_SIZE) &&
  431. (pParAddSelReq->Progress == 1))
  432. {
  433. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  434. return(sizeof(PartialAddSELRes_T));
  435. }
  436. if(((g_BMCInfo.SELConfig.PartialAddRecOffset + Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES) == SEL_MAX_RECORD_SIZE) &&
  437. (pParAddSelReq->Progress != 1))
  438. {
  439. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  440. return(sizeof(PartialAddSELRes_T));
  441. }
  442. memcpy((void *)((uint8_t *)&g_BMCInfo.SELConfig.SelPartialAddRecord + RecordOffset),
  443. (void *)pParAddSelReq->RecordData,
  444. ((uint8_t)(Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)));
  445. g_BMCInfo.SELConfig.PartialAddRecordID=RecordID;
  446. pParAddSelRes->RecID = RecordID;
  447. g_BMCInfo.SELConfig.PartialAddRecOffset += (Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES);
  448. g_BMCInfo.SELConfig.PartialAdd=1;
  449. pParAddSelRes->CompletionCode = CC_NORMAL;
  450. //if the progress bit is 1 indicates that this is the last data of the record so put the entire record in sel repository
  451. if(pParAddSelReq->Progress==1)
  452. {
  453. // Checking for complete filling of gap
  454. if((pParAddSelReq->Offset + Len) == SEL_PARTIAL_ADD_CMD_MAX_LEN)
  455. {
  456. g_BMCInfo.SELConfig.PartialAdd=0;
  457. LockedAddSELEntry ( (uint8_t*)&g_BMCInfo.SELConfig.SelPartialAddRecord, sizeof(SELEventRecord_T), pRes);
  458. }
  459. else
  460. {
  461. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  462. return(sizeof(PartialAddSELRes_T));
  463. }
  464. }
  465. }
  466. else
  467. {
  468. if(ReservationID != g_BMCInfo.SELConfig.SelReservationID)
  469. {
  470. pParAddSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  471. return(sizeof(PartialAddSELRes_T));
  472. }
  473. else
  474. {
  475. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  476. return(sizeof(PartialAddSELRes_T));
  477. }
  478. }
  479. UpdateFlash();
  480. return sizeof (PartialAddSELRes_T);
  481. }
  482. /*---------------------------------------
  483. * DeleteSELEntry
  484. *---------------------------------------*/
  485. int
  486. DeleteSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  487. {
  488. DeleteSELReq_T* pDelSelReq = ( DeleteSELReq_T*) pReq;
  489. DeleteSELRes_T* pDelSelRes = ( DeleteSELRes_T*) pRes;
  490. uint16_t LastRecID = 0,FirstRecID = 0;
  491. SELRepository_T* m_sel = NULL;
  492. SELRec_T *pRec = NULL, *pNextRec = NULL;
  493. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  494. /* Check if the reservation IDs match */
  495. if (((g_BMCInfo.SELConfig.SelReservationID != pDelSelReq->ReservationID) &&
  496. (pDelSelReq->ReservationID != 0)) || (pDelSelReq->ReservationID == 0))
  497. {
  498. pDelSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  499. return sizeof (uint8_t);
  500. }
  501. LastRecID = m_sel->LastRecID;
  502. FirstRecID = m_sel->FirstRecID;
  503. if ( pDelSelReq->RecID == 0x0000 )
  504. {
  505. pDelSelReq->RecID = FirstRecID ;
  506. }
  507. else if ( pDelSelReq->RecID == 0xFFFF )
  508. {
  509. pDelSelReq->RecID = LastRecID;
  510. }
  511. pRec= GetSELRec(pDelSelReq->RecID);
  512. if ( pRec == 0 ||(pRec->Valid != VALID_RECORD) )
  513. {
  514. pDelSelRes->CompletionCode = CC_SDR_REC_NOT_PRESENT;
  515. return sizeof (uint8_t);
  516. }
  517. //Update first record id after delete first sel entity.
  518. if(pDelSelReq->RecID == m_sel->FirstRecID)
  519. {
  520. pNextRec = GetNextSELEntry(pRec);
  521. if(pNextRec != NULL)
  522. {
  523. m_sel->FirstRecID = pNextRec->EvtRecord.hdr.ID;
  524. }
  525. else //No sel
  526. {
  527. m_sel->FirstRecID = 0;
  528. }
  529. }
  530. pRec->Valid = STATUS_DELETE_SEL;
  531. m_sel->NumRecords--;
  532. /*Update the Last Deleted SEL time*/
  533. m_sel->EraseTimeStamp = GetSelTimeStamp ();
  534. // /*Update the First and last Record ID if the requested RecID is either First or Last*/
  535. // FindRecOrder();
  536. pDelSelRes->CompletionCode = CC_NORMAL;
  537. pDelSelRes->RecID = pDelSelReq->RecID;
  538. UpdateFlash();
  539. return sizeof (DeleteSELRes_T);
  540. }
  541. /*---------------------------------------
  542. * ClearSEL
  543. *---------------------------------------*/
  544. int
  545. ClearSEL ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  546. {
  547. ClearSELReq_T* pClrSelReq = ( ClearSELReq_T*) pReq;
  548. ClearSELRes_T* pClrSelRes = ( ClearSELRes_T*) pRes;
  549. SELRepository_T* m_sel = NULL;
  550. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  551. if (memcmp(pClrSelReq->CLR, "CLR", CLR_SEL_PASSWORD_STR_LEN))
  552. {
  553. pClrSelRes->CompletionCode = CC_INV_DATA_FIELD;
  554. return sizeof (uint8_t);
  555. }
  556. if (pClrSelReq->InitOrStatus == CLEAR_SEL_GET_STATUS)
  557. {
  558. pClrSelRes->CompletionCode = CC_NORMAL;
  559. pClrSelRes->EraseProgress = SEL_ERASE_COMPLETED;
  560. return sizeof (ClearSELRes_T);
  561. }
  562. if (pClrSelReq->InitOrStatus != CLEAR_SEL_ACTION)
  563. {
  564. pClrSelRes->CompletionCode = CC_INV_DATA_FIELD;
  565. return sizeof (uint8_t);
  566. }
  567. /* Clear the fields of the SEL */
  568. m_sel->LastRecID = 0;
  569. m_sel->FirstRecID = 0;
  570. m_sel->SELIndex = 0;
  571. m_sel->NumRecords = 0;
  572. memset (&m_sel->SELRecord [0], 0xFF, g_BMCInfo.SELConfig.MaxSELRecord * sizeof (SELRec_T));
  573. /*Update the Last Deleted SEL time*/
  574. g_BMCInfo.SELConfig.LastEvtTS = m_sel->EraseTimeStamp = GetSelTimeStamp ();
  575. pClrSelRes->CompletionCode = CC_NORMAL;
  576. pClrSelRes->EraseProgress = SEL_ERASE_COMPLETED;
  577. g_BMCInfo.SELConfig.SELOverFlow = FALSE;
  578. g_BMCInfo.SELConfig.selalmostfull = 0;
  579. UpdateFlash();
  580. return sizeof (ClearSELRes_T);
  581. }
  582. /*---------------------------------------
  583. * GetSELTime
  584. *---------------------------------------*/
  585. int
  586. GetSELTime ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  587. {
  588. GetSELTimeRes_T* pGetSelTimeRes = ( GetSELTimeRes_T*) pRes;
  589. pGetSelTimeRes->CompletionCode = CC_NORMAL;
  590. pGetSelTimeRes->Time = (GET_SYSTEM_TIME_STAMP ());
  591. return sizeof (GetSELTimeRes_T);
  592. }
  593. /**
  594. * @fn setUTC_Offset
  595. * @brief Set the UTC offset in the linux kernel.
  596. * @param[in] UTCOffset - Offset value in minutes.
  597. * @retval 0, on success.
  598. * 1, on failure.
  599. */
  600. static int setUTC_Offset (int16_t UTCOffset)
  601. {
  602. int mins = 0, hrs = 0;
  603. if ((SEL_UTC_MIN_RANGE > UTCOffset) || (SEL_UTC_MAX_RANGE < UTCOffset) || (0 != (UTCOffset % 15)))
  604. {
  605. return 1;
  606. }
  607. hrs = UTCOffset / 60;
  608. mins = UTCOffset % 60;
  609. printf ("hrs : %d, mins : %d\n", hrs, mins);
  610. g_BMCInfo.IpmiConfig.SELTimeUTCOffset = UTCOffset;
  611. return 0;
  612. }
  613. /*---------------------------------------
  614. * SetSELTime
  615. *---------------------------------------*/
  616. int
  617. SetSELTime ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  618. {
  619. uint32_t localTime = 0;
  620. SetSELTimeReq_T* pSetSelTimeReq = ( SetSELTimeReq_T*) pReq;
  621. localTime = (pSetSelTimeReq->Time);
  622. SELTimeClockSync(PRE_CLK_SET);
  623. SET_SYSTEM_TIME_STAMP (&localTime);
  624. SELTimeClockSync(POST_CLK_SET);
  625. pRes [0] = CC_NORMAL;
  626. return sizeof (*pRes);
  627. }
  628. /*---------------------------------------
  629. * GetSELTimeUTC_Offset
  630. *---------------------------------------*/
  631. int
  632. GetSELTimeUTC_Offset ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  633. {
  634. GetSELTimeUTCOffsetRes_T* pGetSelTimeUTCOffsetRes = ( GetSELTimeUTCOffsetRes_T*) pRes;
  635. pGetSelTimeUTCOffsetRes->CompletionCode = CC_NORMAL;
  636. pGetSelTimeUTCOffsetRes->UTCOffset = (g_BMCInfo.IpmiConfig.SELTimeUTCOffset);
  637. return sizeof (GetSELTimeUTCOffsetRes_T);
  638. }
  639. /*---------------------------------------
  640. * SetSELTimeUTC_Offset
  641. *---------------------------------------*/
  642. int
  643. SetSELTimeUTC_Offset ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  644. {
  645. SetSELTimeUTCOffsetReq_T* pSetSELTimeUTCOffsetReq = ( SetSELTimeUTCOffsetReq_T*) pReq;
  646. SetSELTimeUTCOffsetRes_T* pSetSELTimeUTCOffsetRes = ( SetSELTimeUTCOffsetRes_T*) pRes;
  647. int16_t UTCOffset;
  648. UTCOffset = (int16_t) (pSetSELTimeUTCOffsetReq->UTCOffset);
  649. if (((UTCOffset <= SEL_UTC_MAX_RANGE) && (UTCOffset >= SEL_UTC_MIN_RANGE)) || (UTCOffset == UNSPECIFIED_UTC_OFFSET))
  650. {
  651. if (0 != setUTC_Offset ((UTCOffset == UNSPECIFIED_UTC_OFFSET) ? 0 : UTCOffset))
  652. {
  653. pSetSELTimeUTCOffsetRes->CompletionCode = CC_INV_DATA_FIELD;
  654. return sizeof (*pRes);
  655. }
  656. pSetSELTimeUTCOffsetRes->CompletionCode = CC_NORMAL;
  657. }
  658. else
  659. {
  660. pSetSELTimeUTCOffsetRes->CompletionCode = CC_PARAM_OUT_OF_RANGE;
  661. }
  662. UpdateFlash();
  663. return sizeof (*pRes);
  664. }
  665. /*---------------------------------------
  666. * GetAuxiliaryLogStatus
  667. *---------------------------------------*/
  668. int
  669. GetAuxiliaryLogStatus( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  670. {
  671. return 0;
  672. }
  673. /*---------------------------------------
  674. * SetAuxiliaryLogStatus
  675. *---------------------------------------*/
  676. int
  677. SetAuxiliaryLogStatus( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  678. {
  679. return 0;
  680. }
  681. /*---------------------------------------
  682. * GetNextSELEntry
  683. *---------------------------------------*/
  684. static SELRec_T*
  685. GetNextSELEntry ( SELRec_T* rec)
  686. {
  687. SELRec_T* pRec = rec;
  688. SELRec_T* pLastRec = (((SELRepository_T*)g_BMCInfo.pSEL)->SELRecord + g_BMCInfo.SELConfig.MaxSELRecord - 1);
  689. pRec++;
  690. while (1)
  691. {
  692. if(pRec > pLastRec)
  693. {
  694. pRec = ((SELRepository_T*)g_BMCInfo.pSEL)->SELRecord;
  695. }
  696. if(pRec == rec)
  697. {
  698. break;
  699. }
  700. if (pRec->Valid == VALID_RECORD)
  701. {
  702. return pRec;
  703. }
  704. else if (pRec->Valid == STATUS_DELETE_SEL)
  705. {
  706. pRec++;
  707. }
  708. else
  709. {
  710. break;
  711. }
  712. }
  713. return 0;
  714. }
  715. /*
  716. @ fn GetSELRec
  717. @ brief This function is used to get the SEL Record based Record ID
  718. @ params RecID[in] Record ID BMCInst[in]
  719. @ returns SELRecord pointer on success and 0 on failures
  720. */
  721. static SELRec_T* GetSELRec(uint16_t RecID)
  722. {
  723. int i=0;
  724. SELRepository_T* m_sel;
  725. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  726. for(i=0;i<g_BMCInfo.SELConfig.MaxSELRecord;i++)
  727. {
  728. if((m_sel->SELRecord[i].EvtRecord.hdr.ID == RecID) && (m_sel->SELRecord[i].Valid== VALID_RECORD))
  729. {
  730. return &m_sel->SELRecord[i];
  731. }
  732. }
  733. return 0;
  734. }
  735. /*---------------------------------------
  736. * GetSelTimeStamp
  737. *---------------------------------------*/
  738. uint32_t GetSelTimeStamp()
  739. {
  740. return (GET_SYSTEM_TIME_STAMP());
  741. }
  742. #endif /* SEL_DEVICE */
  743. /*---------------------------------------------------------------------------
  744. * @fn SELTimeClockSync
  745. *
  746. * @brief This function is invoked when set SEL time, generate a pair of
  747. * events(pre and post clock setting) correlating the timestamps
  748. * for events occurring before and after the new clock value.
  749. *
  750. * @param Action - Specify pre-event or post-event.
  751. * @param BMCInst - Index of BMC instance.
  752. *
  753. * @return 0 - if success.
  754. * -1 - if error.
  755. *---------------------------------------------------------------------------*/
  756. static uint8_t SELTimeClockSync(uint8_t Action)
  757. {
  758. SELEventRecord_T *EventRec = (SELEventRecord_T*)m_SysEventMsg;
  759. uint8_t pRes[sizeof(AddSELRes_T)];
  760. EventRec->SensorNum = 0xFF;
  761. EventRec->EvtDirType = 0x6F; // Sensor Specific
  762. EventRec->EvtData1 = 0x05; // Offset 05h - Timestamp Clock Sync
  763. EventRec->EvtData2 = Action;
  764. EventRec->EvtData3 = 0xFF;
  765. LockedAddSELEntry((uint8_t*)EventRec, sizeof(SELEventRecord_T), pRes);
  766. UpdateFlash();
  767. return 0;
  768. }
  769. ///*---------------------------------------------------------------------------
  770. // * @fn SetSELPolicy
  771. // *
  772. // * @brief This function is invoked when switch SEL policy, make appropriate
  773. // * adjustment for environment variables that related to SEL buffer.
  774. // *
  775. // * @param Policy - Specify Linear SEL policy or Circular SEL policy.
  776. // * @param BMCInst - Index of BMC instance.
  777. // *---------------------------------------------------------------------------*/
  778. //void
  779. //SetSELPolicy(uint8_t Policy)
  780. //{
  781. //// SELRepository_T* m_sel = NULL;
  782. // m_sel = (SELRepository_T*)g_BMCInfo.pSEL;
  783. // switch (Policy)
  784. // {
  785. // case LINEAR_SEL:
  786. // /* Reset LastRecID because GetNextSELEntry func will stop finding the next record if RecID >= LastRecRD,
  787. // but RecID may greater than LastRecID in Circular SEL mode. */
  788. ///* LOCK_BMC_SHARED_MEM(BMCInst);
  789. // BMC_GET_SHARED_MEM (BMCInst)->m_LastRecID = m_sel->SELRecord[pBMCInfo->SELConfig.MaxSELRecord].EvtRecord.hdr.ID;
  790. // BMC_GET_SHARED_MEM (BMCInst)->m_SELIndex = m_sel->NumRecords;
  791. // BMC_GET_SHARED_MEM (BMCInst)->m_FirstRecID = m_sel->SELRecord[0].EvtRecord.hdr.ID;
  792. // UNLOCK_BMC_SHARED_MEM(BMCInst);*/
  793. // break;
  794. // case CIRCULAR_SEL:
  795. // /*Update the Last and First Record ID when switch back to Circular-linear-Circular cycle */
  796. //// if(m_sel->NumRecords == g_BMCInfo.SELConfig.MaxSELRecord)
  797. //// {
  798. //// FindRecOrder();
  799. //// }
  800. // break;
  801. // }
  802. //}