SEL.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  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.IpmiConfig.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.IpmiConfig.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 = MAX_SEL_RECORD;
  116. pAllocInfo->AllocUnitSize = (sizeof (SELRec_T));
  117. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  118. pAllocInfo->NumFreeAllocUnits = ((g_BMCInfo.IpmiConfig.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.IpmiConfig.SELConfig.SelReservationID++;
  131. if (0 == g_BMCInfo.IpmiConfig.SELConfig.SelReservationID) { g_BMCInfo.IpmiConfig.SELConfig.SelReservationID = 1; }
  132. pRsvSelRes->CompletionCode = CC_NORMAL;
  133. pRsvSelRes->ReservationID = g_BMCInfo.IpmiConfig.SELConfig.SelReservationID;
  134. g_BMCInfo.IpmiConfig.SELConfig.PartialAdd=0 ;//Addded for DR#30287
  135. FlushIPMIToFlash();
  136. return sizeof (ReserveSELRes_T);
  137. }
  138. /*---------------------------------------
  139. * GetSELEntry
  140. *---------------------------------------*/
  141. int
  142. GetSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  143. {
  144. SELRec_T* pSelRec;
  145. SELRec_T* pNextSelRec;
  146. GetSELReq_T* pGetSelReq = ( GetSELReq_T*) pReq;
  147. GetSELRes_T* pGetSelRes = ( GetSELRes_T*) pRes;
  148. uint16_t LastRecID = 0,FirstRecID = 0;
  149. SELRepository_T* m_sel = NULL;
  150. uint16_t NumRecords = 0;
  151. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  152. NumRecords = m_sel->NumRecords;
  153. pGetSelRes->CompletionCode = CC_NORMAL;
  154. // if (pGetSelReq->ReservationID && g_BMCInfo.SELConfig.RsrvIDCancelled)
  155. // {
  156. // pGetSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  157. // return sizeof (uint8_t);
  158. // }
  159. /* Check if the reservation IDs match */
  160. if ((g_BMCInfo.IpmiConfig.SELConfig.SelReservationID != pGetSelReq->ReservationID) &&
  161. ((0 != pGetSelReq->Offset) || (pGetSelReq->ReservationID != 0)) )
  162. {
  163. pGetSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  164. return sizeof (uint8_t);
  165. }
  166. if (0 == m_sel->NumRecords)
  167. {
  168. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  169. return sizeof (uint8_t);
  170. }
  171. FirstRecID = m_sel->FirstRecID;
  172. LastRecID = m_sel->LastRecID;
  173. //printf("---> FirstRecID %d, LastRecID %d\n", FirstRecID, LastRecID);
  174. /* If ID == 0x0000 return first record */
  175. if (0 == pGetSelReq->RecID)
  176. {
  177. pSelRec = GetSELRec(FirstRecID);
  178. if (0 == pSelRec)
  179. {
  180. printf("Warning: Not find SEL Record\n");
  181. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  182. return sizeof(uint8_t);
  183. }
  184. else
  185. {
  186. pNextSelRec = GetNextSELEntry (pSelRec);
  187. }
  188. if (0 == pNextSelRec)
  189. {
  190. pGetSelRes->NextRecID = 0xFFFF;
  191. }
  192. else
  193. {
  194. pGetSelRes->NextRecID = pNextSelRec->EvtRecord.hdr.ID;
  195. }
  196. pGetSelReq->RecID = FirstRecID;
  197. }
  198. else if (0xFFFF == pGetSelReq->RecID)
  199. {
  200. pSelRec = GetSELRec(LastRecID);
  201. if(0== pSelRec)
  202. {
  203. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  204. return sizeof(uint8_t);
  205. }
  206. pGetSelRes->NextRecID = 0xFFFF;
  207. }
  208. pSelRec = GetSELRec(pGetSelReq->RecID);
  209. if (pSelRec == 0)
  210. {
  211. pGetSelRes->CompletionCode = CC_SEL_REC_NOT_PRESENT;
  212. return sizeof (uint8_t);
  213. }
  214. if(LastRecID == pGetSelReq->RecID)
  215. {
  216. pGetSelRes->NextRecID = 0xFFFF;
  217. }
  218. else
  219. {
  220. pNextSelRec = GetNextSELEntry (pSelRec);
  221. if (0 == pNextSelRec)
  222. {
  223. /*If the given SEL ID is the maximum SEL record ,then the next SEL ID will be the First SEL ID
  224. in case of Circular SEL Implementation */
  225. if(g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord == NumRecords)
  226. {
  227. pGetSelRes->NextRecID = 0;
  228. }
  229. else
  230. {
  231. pGetSelRes->NextRecID = 0xFFFF;
  232. }
  233. }
  234. else
  235. {
  236. pGetSelRes->NextRecID = pNextSelRec->EvtRecord.hdr.ID;
  237. }
  238. }
  239. if ((0xff == pGetSelReq->Size) && (sizeof (SELEventRecord_T) >= pGetSelReq->Offset))
  240. {
  241. pGetSelReq->Size = sizeof (SELEventRecord_T) - pGetSelReq->Offset;
  242. }
  243. // Check for the request bytes and offset not to exceed the actual size of the record
  244. else if ((pGetSelReq->Size > (sizeof(SELEventRecord_T))) ||
  245. (pGetSelReq->Offset > (sizeof(SELEventRecord_T))) ||
  246. (pGetSelReq->Size > ((sizeof(SELEventRecord_T))- pGetSelReq->Offset)))
  247. {
  248. pGetSelRes->CompletionCode = CC_PARAM_OUT_OF_RANGE;
  249. return sizeof (uint8_t);
  250. }
  251. memcpy(pGetSelRes + 1, (( uint8_t*)&pSelRec->EvtRecord) +
  252. pGetSelReq->Offset, pGetSelReq->Size);
  253. return sizeof(GetSELRes_T) + pGetSelReq->Size;
  254. }
  255. /*---------------------------------------
  256. * LockedAddSELEntry with SEL locked
  257. *---------------------------------------*/
  258. int
  259. LockedAddSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  260. {
  261. AddSELRes_T* pAddSelRes = ( AddSELRes_T*) pRes;
  262. SELRecHdr_T* pSelRec = ( SELRecHdr_T*) pReq;
  263. uint16_t index = 0;
  264. uint16_t NumRecords=0;
  265. // m_sel = ( SELRepository_T*)g_BMCInfo.pSEL;
  266. NumRecords = (( SELRepository_T*)g_BMCInfo.pSEL)->NumRecords;
  267. /* If we dont have enough space return invalid ID */
  268. if (NumRecords >= g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord)
  269. {
  270. if (((( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex == g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord))
  271. {
  272. (( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex = 0;
  273. }
  274. /*Reset the SEL OverFlow Flag in Circular SEL mode*/
  275. g_BMCInfo.IpmiConfig.SELConfig.SELOverFlow = FALSE;
  276. }
  277. if((( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID == 0xFFFE)
  278. {
  279. (( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID = 0;
  280. }
  281. if( (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID == 0xFFFE)
  282. {
  283. (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID = 0;
  284. }
  285. if(NumRecords == g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord)
  286. {
  287. (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID +=1;
  288. }
  289. /* time stamp for record type less than 0xE0*/
  290. if (pSelRec->Type < 0xE0)
  291. {
  292. // The timestamp gets set if the hook is not present or if the hook returns -1
  293. pSelRec->TimeStamp = GetSelTimeStamp ();
  294. }
  295. pSelRec->ID = ((( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID) + 1;
  296. index = (( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex ;
  297. memcpy (&(( SELRepository_T*)g_BMCInfo.pSEL)->SELRecord [index].EvtRecord , pSelRec,
  298. sizeof (SELEventRecord_T));
  299. (( SELRepository_T*)g_BMCInfo.pSEL)->SELRecord [index].Valid = VALID_RECORD;
  300. (( SELRepository_T*)g_BMCInfo.pSEL)->SELRecord [index].Len = sizeof (SELEventRecord_T) + 2;
  301. if (( NumRecords < g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord))
  302. {
  303. NumRecords = ++(( SELRepository_T*)g_BMCInfo.pSEL)->NumRecords;
  304. }
  305. /*Update the First SEL entry after clear SEL command*/
  306. if( (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID == 0)
  307. {
  308. (( SELRepository_T*)g_BMCInfo.pSEL)->FirstRecID = pSelRec->ID;
  309. }
  310. (( SELRepository_T*)g_BMCInfo.pSEL)->LastRecID += 1;
  311. (( SELRepository_T*)g_BMCInfo.pSEL)->SELIndex += 1;
  312. g_BMCInfo.IpmiConfig.SELConfig.LastEvtTS = (( SELRepository_T*)g_BMCInfo.pSEL)->AddTimeStamp = GetSelTimeStamp ();
  313. pAddSelRes->CompletionCode = CC_NORMAL;
  314. pAddSelRes->RecID = pSelRec->ID;
  315. FlushSELToFlash();
  316. FlushIPMIToFlash();
  317. return sizeof (AddSELRes_T);
  318. }
  319. /*---------------------------------------
  320. * AddSELEntry
  321. *---------------------------------------*/
  322. int
  323. AddSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  324. {
  325. int reslen = 0;
  326. reslen = LockedAddSELEntry(pReq, ReqLen, pRes);
  327. FlushSELToFlash();
  328. return reslen;
  329. }
  330. /*---------------------------------------
  331. * PartialAddSELEntry
  332. *---------------------------------------*/
  333. int
  334. PartialAddSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  335. {
  336. PartialAddSELReq_T* pParAddSelReq = ( PartialAddSELReq_T*) pReq;
  337. PartialAddSELRes_T* pParAddSelRes = ( PartialAddSELRes_T*) pRes;
  338. uint16_t RecordID=0, ReservationID=0;
  339. uint8_t RecordOffset=0,Len=0;
  340. SELRepository_T* m_sel = ( SELRepository_T*)g_BMCInfo.pSEL;
  341. ReservationID = (uint16_t)(pParAddSelReq->LSBReservationID |
  342. ((uint16_t)pParAddSelReq->MSBReservationID << 8));
  343. RecordID = (uint16_t)(((uint16_t)pParAddSelReq->MSBRecordID << 8) |
  344. pParAddSelReq->LSBRecordID);
  345. RecordOffset = (uint32_t)pParAddSelReq->Offset;
  346. Len = ReqLen;
  347. // /* Checks for the Valid Reservation ID */
  348. // while(g_BMCInfo.SELConfig.RsrvIDCancelled)
  349. // {
  350. // if((ReservationID == 0) && (pParAddSelReq->Progress == 1) && (ReqLen == SEL_PARTIAL_ADD_CMD_MAX_LEN))
  351. // break;
  352. // else
  353. // {
  354. // if(ReqLen < SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)
  355. // {
  356. // pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  357. // return(sizeof(PartialAddSELRes_T));
  358. // }
  359. // else
  360. // {
  361. // pParAddSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  362. // pParAddSelRes->RecID = 0;
  363. // return(sizeof(PartialAddSELRes_T));
  364. // }
  365. // }
  366. // }
  367. /* Check for the reserved bytes should b zero */
  368. if ( 0 != (pParAddSelReq->Progress & RESERVED_BITS_PARTIALADDSELENTRY ) )
  369. {
  370. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  371. return sizeof(uint8_t);
  372. }
  373. if((pParAddSelReq->Progress>1)|| (pParAddSelReq->Offset>SEL_RECORD_SIZE))
  374. {
  375. pParAddSelRes->CompletionCode = CC_PARAM_OUT_OF_RANGE;
  376. return(sizeof(PartialAddSELRes_T));
  377. }
  378. else if(g_BMCInfo.IpmiConfig.SELConfig.PartialAdd==0)
  379. {
  380. if(((RecordOffset+(Len-SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)==SEL_RECORD_SIZE)&&(pParAddSelReq->Progress!=1))||
  381. (( RecordOffset+(Len-SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)<SEL_RECORD_SIZE)&&(pParAddSelReq->Progress==1))||
  382. (RecordOffset+(Len-SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)>SEL_RECORD_SIZE))
  383. {
  384. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  385. return(sizeof(PartialAddSELRes_T));
  386. }
  387. }
  388. else if((ReservationID==0)&&(Len==SEL_PARTIAL_ADD_CMD_MAX_LEN)&&(pParAddSelReq->Progress!=1))
  389. {
  390. pParAddSelRes->CompletionCode =CC_INV_DATA_FIELD;
  391. return(sizeof(PartialAddSELRes_T));
  392. }
  393. /*Checking for reservation ID <<Added few more condition checking */
  394. if(((ReservationID == g_BMCInfo.IpmiConfig.SELConfig.SelReservationID)&&(g_BMCInfo.IpmiConfig.SELConfig.PartialAdd==0)) ||
  395. ((ReservationID == g_BMCInfo.IpmiConfig.SELConfig.SelReservationID) && (ReqLen <= SEL_PARTIAL_ADD_CMD_MAX_LEN))
  396. ||((ReservationID == 0) && (pParAddSelReq->Progress == 1) && (ReqLen == SEL_PARTIAL_ADD_CMD_MAX_LEN)))
  397. {
  398. if(g_BMCInfo.IpmiConfig.SELConfig.PartialAdd==0)
  399. {
  400. // Requirement says partial adds must start at 0, with no
  401. // gaps or overlaps. First request must be to RecordID = 0.
  402. if ((RecordID != 0) || (RecordOffset != 0))
  403. {
  404. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  405. return(sizeof(PartialAddSELRes_T));// Modified from sizeof (uint8_t);
  406. }
  407. memset((void *)&g_BMCInfo.IpmiConfig.SELConfig.SelPartialAddRecord, 0xFF, sizeof(SELEventRecord_T));
  408. // Fill in the record ID into the partial add record. The
  409. // record ID is always the offset in memory of where the
  410. // SEL record starts (which includes a delete time first).
  411. RecordID = g_BMCInfo.IpmiConfig.SELConfig.SelPartialAddRecord.hdr.ID = m_sel->LastRecID +1;
  412. g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecordID=RecordID;
  413. g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecOffset = 0;
  414. g_BMCInfo.IpmiConfig.SELConfig.PartialAdd=1;
  415. }
  416. else
  417. {
  418. if (RecordID != g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecordID)
  419. {
  420. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  421. return sizeof (PartialAddSELRes_T);
  422. }
  423. }
  424. if (pParAddSelReq->Offset != g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecOffset)
  425. {
  426. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  427. return(sizeof(PartialAddSELRes_T));
  428. }
  429. // Checking for Exceeding data values //
  430. if((g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecOffset + Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES) > SEL_MAX_RECORD_SIZE)
  431. {
  432. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  433. return(sizeof(PartialAddSELRes_T));
  434. }
  435. if((( g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecOffset + Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES) < SEL_MAX_RECORD_SIZE) &&
  436. (pParAddSelReq->Progress == 1))
  437. {
  438. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  439. return(sizeof(PartialAddSELRes_T));
  440. }
  441. if(((g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecOffset + Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES) == SEL_MAX_RECORD_SIZE) &&
  442. (pParAddSelReq->Progress != 1))
  443. {
  444. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  445. return(sizeof(PartialAddSELRes_T));
  446. }
  447. memcpy((void *)((uint8_t *)&g_BMCInfo.IpmiConfig.SELConfig.SelPartialAddRecord + RecordOffset),
  448. (void *)pParAddSelReq->RecordData,
  449. ((uint8_t)(Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES)));
  450. g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecordID=RecordID;
  451. pParAddSelRes->RecID = RecordID;
  452. g_BMCInfo.IpmiConfig.SELConfig.PartialAddRecOffset += (Len - SEL_PARTIAL_ADD_REQUEST_MISC_BYTES);
  453. g_BMCInfo.IpmiConfig.SELConfig.PartialAdd=1;
  454. pParAddSelRes->CompletionCode = CC_NORMAL;
  455. //if the progress bit is 1 indicates that this is the last data of the record so put the entire record in sel repository
  456. if(pParAddSelReq->Progress==1)
  457. {
  458. // Checking for complete filling of gap
  459. if((pParAddSelReq->Offset + Len) == SEL_PARTIAL_ADD_CMD_MAX_LEN)
  460. {
  461. g_BMCInfo.IpmiConfig.SELConfig.PartialAdd=0;
  462. LockedAddSELEntry ( (uint8_t*)&g_BMCInfo.IpmiConfig.SELConfig.SelPartialAddRecord, sizeof(SELEventRecord_T), pRes);
  463. }
  464. else
  465. {
  466. pParAddSelRes->CompletionCode = CC_REQ_INV_LEN;
  467. return(sizeof(PartialAddSELRes_T));
  468. }
  469. }
  470. }
  471. else
  472. {
  473. if(ReservationID != g_BMCInfo.IpmiConfig.SELConfig.SelReservationID)
  474. {
  475. pParAddSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  476. return(sizeof(PartialAddSELRes_T));
  477. }
  478. else
  479. {
  480. pParAddSelRes->CompletionCode = CC_INV_DATA_FIELD;
  481. return(sizeof(PartialAddSELRes_T));
  482. }
  483. }
  484. FlushSELToFlash();
  485. FlushIPMIToFlash();
  486. return sizeof (PartialAddSELRes_T);
  487. }
  488. /*---------------------------------------
  489. * DeleteSELEntry
  490. *---------------------------------------*/
  491. int
  492. DeleteSELEntry ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  493. {
  494. DeleteSELReq_T* pDelSelReq = ( DeleteSELReq_T*) pReq;
  495. DeleteSELRes_T* pDelSelRes = ( DeleteSELRes_T*) pRes;
  496. uint16_t LastRecID = 0,FirstRecID = 0;
  497. SELRepository_T* m_sel = NULL;
  498. SELRec_T *pRec = NULL, *pNextRec = NULL;
  499. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  500. /* Check if the reservation IDs match */
  501. if (((g_BMCInfo.IpmiConfig.SELConfig.SelReservationID != pDelSelReq->ReservationID) &&
  502. (pDelSelReq->ReservationID != 0)) || (pDelSelReq->ReservationID == 0))
  503. {
  504. pDelSelRes->CompletionCode = CC_INV_RESERVATION_ID;
  505. return sizeof (uint8_t);
  506. }
  507. LastRecID = m_sel->LastRecID;
  508. FirstRecID = m_sel->FirstRecID;
  509. if ( pDelSelReq->RecID == 0x0000 )
  510. {
  511. pDelSelReq->RecID = FirstRecID ;
  512. }
  513. else if ( pDelSelReq->RecID == 0xFFFF )
  514. {
  515. pDelSelReq->RecID = LastRecID;
  516. }
  517. pRec= GetSELRec(pDelSelReq->RecID);
  518. if ( pRec == 0 ||(pRec->Valid != VALID_RECORD) )
  519. {
  520. pDelSelRes->CompletionCode = CC_SDR_REC_NOT_PRESENT;
  521. return sizeof (uint8_t);
  522. }
  523. //Update first record id after delete first sel entity.
  524. if(pDelSelReq->RecID == m_sel->FirstRecID)
  525. {
  526. pNextRec = GetNextSELEntry(pRec);
  527. if(pNextRec != NULL)
  528. {
  529. m_sel->FirstRecID = pNextRec->EvtRecord.hdr.ID;
  530. }
  531. else //No sel
  532. {
  533. m_sel->FirstRecID = 0;
  534. }
  535. }
  536. pRec->Valid = STATUS_DELETE_SEL;
  537. m_sel->NumRecords--;
  538. /*Update the Last Deleted SEL time*/
  539. m_sel->EraseTimeStamp = GetSelTimeStamp ();
  540. // /*Update the First and last Record ID if the requested RecID is either First or Last*/
  541. // FindRecOrder();
  542. pDelSelRes->CompletionCode = CC_NORMAL;
  543. pDelSelRes->RecID = pDelSelReq->RecID;
  544. FlushSELToFlash();
  545. FlushIPMIToFlash();
  546. return sizeof (DeleteSELRes_T);
  547. }
  548. /*---------------------------------------
  549. * ClearSEL
  550. *---------------------------------------*/
  551. int
  552. ClearSEL ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  553. {
  554. ClearSELReq_T* pClrSelReq = ( ClearSELReq_T*) pReq;
  555. ClearSELRes_T* pClrSelRes = ( ClearSELRes_T*) pRes;
  556. SELRepository_T* m_sel = NULL;
  557. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  558. if (memcmp(pClrSelReq->CLR, "CLR", CLR_SEL_PASSWORD_STR_LEN))
  559. {
  560. pClrSelRes->CompletionCode = CC_INV_DATA_FIELD;
  561. return sizeof (uint8_t);
  562. }
  563. if (pClrSelReq->InitOrStatus == CLEAR_SEL_GET_STATUS)
  564. {
  565. pClrSelRes->CompletionCode = CC_NORMAL;
  566. pClrSelRes->EraseProgress = SEL_ERASE_COMPLETED;
  567. return sizeof (ClearSELRes_T);
  568. }
  569. if (pClrSelReq->InitOrStatus != CLEAR_SEL_ACTION)
  570. {
  571. pClrSelRes->CompletionCode = CC_INV_DATA_FIELD;
  572. return sizeof (uint8_t);
  573. }
  574. /* Clear the fields of the SEL */
  575. m_sel->LastRecID = 0;
  576. m_sel->FirstRecID = 0;
  577. m_sel->SELIndex = 0;
  578. m_sel->NumRecords = 0;
  579. memset (&m_sel->SELRecord [0], 0xFF, g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord * sizeof (SELRec_T));
  580. /*Update the Last Deleted SEL time*/
  581. g_BMCInfo.IpmiConfig.SELConfig.LastEvtTS = m_sel->EraseTimeStamp = GetSelTimeStamp ();
  582. pClrSelRes->CompletionCode = CC_NORMAL;
  583. pClrSelRes->EraseProgress = SEL_ERASE_COMPLETED;
  584. g_BMCInfo.IpmiConfig.SELConfig.SELOverFlow = FALSE;
  585. g_BMCInfo.IpmiConfig.SELConfig.selalmostfull = 0;
  586. FlushSELToFlash();
  587. FlushIPMIToFlash();
  588. return sizeof (ClearSELRes_T);
  589. }
  590. /*---------------------------------------
  591. * GetSELTime
  592. *---------------------------------------*/
  593. int
  594. GetSELTime ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  595. {
  596. GetSELTimeRes_T* pGetSelTimeRes = ( GetSELTimeRes_T*) pRes;
  597. pGetSelTimeRes->CompletionCode = CC_NORMAL;
  598. pGetSelTimeRes->Time = (GET_SYSTEM_TIME_STAMP ());
  599. return sizeof (GetSELTimeRes_T);
  600. }
  601. /**
  602. * @fn setUTC_Offset
  603. * @brief Set the UTC offset in the linux kernel.
  604. * @param[in] UTCOffset - Offset value in minutes.
  605. * @retval 0, on success.
  606. * 1, on failure.
  607. */
  608. static int setUTC_Offset (int16_t UTCOffset)
  609. {
  610. int mins = 0, hrs = 0;
  611. if ((SEL_UTC_MIN_RANGE > UTCOffset) || (SEL_UTC_MAX_RANGE < UTCOffset) || (0 != (UTCOffset % 15)))
  612. {
  613. return 1;
  614. }
  615. hrs = UTCOffset / 60;
  616. mins = UTCOffset % 60;
  617. printf ("hrs : %d, mins : %d\n", hrs, mins);
  618. g_BMCInfo.IpmiConfig.SELTimeUTCOffset = UTCOffset;
  619. FlushIPMIToFlash();
  620. return 0;
  621. }
  622. /*---------------------------------------
  623. * SetSELTime
  624. *---------------------------------------*/
  625. int
  626. SetSELTime ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  627. {
  628. uint32_t localTime = 0;
  629. SetSELTimeReq_T* pSetSelTimeReq = ( SetSELTimeReq_T*) pReq;
  630. localTime = (pSetSelTimeReq->Time);
  631. SELTimeClockSync(PRE_CLK_SET);
  632. SET_SYSTEM_TIME_STAMP (&localTime);
  633. SELTimeClockSync(POST_CLK_SET);
  634. pRes [0] = CC_NORMAL;
  635. return sizeof (*pRes);
  636. }
  637. /*---------------------------------------
  638. * GetSELTimeUTC_Offset
  639. *---------------------------------------*/
  640. int
  641. GetSELTimeUTC_Offset ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  642. {
  643. GetSELTimeUTCOffsetRes_T* pGetSelTimeUTCOffsetRes = ( GetSELTimeUTCOffsetRes_T*) pRes;
  644. pGetSelTimeUTCOffsetRes->CompletionCode = CC_NORMAL;
  645. pGetSelTimeUTCOffsetRes->UTCOffset = (g_BMCInfo.IpmiConfig.SELTimeUTCOffset);
  646. return sizeof (GetSELTimeUTCOffsetRes_T);
  647. }
  648. /*---------------------------------------
  649. * SetSELTimeUTC_Offset
  650. *---------------------------------------*/
  651. int
  652. SetSELTimeUTC_Offset ( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  653. {
  654. SetSELTimeUTCOffsetReq_T* pSetSELTimeUTCOffsetReq = ( SetSELTimeUTCOffsetReq_T*) pReq;
  655. SetSELTimeUTCOffsetRes_T* pSetSELTimeUTCOffsetRes = ( SetSELTimeUTCOffsetRes_T*) pRes;
  656. int16_t UTCOffset;
  657. UTCOffset = (int16_t) (pSetSELTimeUTCOffsetReq->UTCOffset);
  658. if (((UTCOffset <= SEL_UTC_MAX_RANGE) && (UTCOffset >= SEL_UTC_MIN_RANGE)) || (UTCOffset == UNSPECIFIED_UTC_OFFSET))
  659. {
  660. if (0 != setUTC_Offset ((UTCOffset == UNSPECIFIED_UTC_OFFSET) ? 0 : UTCOffset))
  661. {
  662. pSetSELTimeUTCOffsetRes->CompletionCode = CC_INV_DATA_FIELD;
  663. return sizeof (*pRes);
  664. }
  665. pSetSELTimeUTCOffsetRes->CompletionCode = CC_NORMAL;
  666. }
  667. else
  668. {
  669. pSetSELTimeUTCOffsetRes->CompletionCode = CC_PARAM_OUT_OF_RANGE;
  670. }
  671. return sizeof (*pRes);
  672. }
  673. /*---------------------------------------
  674. * GetAuxiliaryLogStatus
  675. *---------------------------------------*/
  676. int
  677. GetAuxiliaryLogStatus( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  678. {
  679. return 0;
  680. }
  681. /*---------------------------------------
  682. * SetAuxiliaryLogStatus
  683. *---------------------------------------*/
  684. int
  685. SetAuxiliaryLogStatus( uint8_t* pReq, uint8_t ReqLen, uint8_t* pRes)
  686. {
  687. return 0;
  688. }
  689. /*---------------------------------------
  690. * GetNextSELEntry
  691. *---------------------------------------*/
  692. static SELRec_T*
  693. GetNextSELEntry ( SELRec_T* rec)
  694. {
  695. SELRec_T* pRec = rec;
  696. SELRec_T* pLastRec = (((SELRepository_T*)g_BMCInfo.pSEL)->SELRecord + g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord - 1);
  697. pRec++;
  698. while (1)
  699. {
  700. if(pRec > pLastRec)
  701. {
  702. pRec = ((SELRepository_T*)g_BMCInfo.pSEL)->SELRecord;
  703. }
  704. if(pRec == rec)
  705. {
  706. break;
  707. }
  708. if (pRec->Valid == VALID_RECORD)
  709. {
  710. return pRec;
  711. }
  712. else if (pRec->Valid == STATUS_DELETE_SEL)
  713. {
  714. pRec++;
  715. }
  716. else
  717. {
  718. break;
  719. }
  720. }
  721. return 0;
  722. }
  723. /*
  724. @ fn GetSELRec
  725. @ brief This function is used to get the SEL Record based Record ID
  726. @ params RecID[in] Record ID BMCInst[in]
  727. @ returns SELRecord pointer on success and 0 on failures
  728. */
  729. static SELRec_T* GetSELRec(uint16_t RecID)
  730. {
  731. int i=0;
  732. //int j;
  733. SELRepository_T* m_sel;
  734. m_sel = ( SELRepository_T*) g_BMCInfo.pSEL;
  735. for(i=0;i<g_BMCInfo.IpmiConfig.SELConfig.MaxSELRecord;i++)
  736. {
  737. // printf("i = %d: ", i);
  738. // for(j=0;j<18;j++)
  739. // printf("%#x ", ((uint8_t*)(&m_sel->SELRecord[i]))[j]);
  740. // printf("\n");
  741. if((m_sel->SELRecord[i].EvtRecord.hdr.ID == RecID) && (m_sel->SELRecord[i].Valid== VALID_RECORD))
  742. {
  743. return &m_sel->SELRecord[i];
  744. }
  745. }
  746. return 0;
  747. }
  748. /*---------------------------------------
  749. * GetSelTimeStamp
  750. *---------------------------------------*/
  751. uint32_t GetSelTimeStamp()
  752. {
  753. return (GET_SYSTEM_TIME_STAMP());
  754. }
  755. #endif /* SEL_DEVICE */
  756. /*---------------------------------------------------------------------------
  757. * @fn SELTimeClockSync
  758. *
  759. * @brief This function is invoked when set SEL time, generate a pair of
  760. * events(pre and post clock setting) correlating the timestamps
  761. * for events occurring before and after the new clock value.
  762. *
  763. * @param Action - Specify pre-event or post-event.
  764. * @param BMCInst - Index of BMC instance.
  765. *
  766. * @return 0 - if success.
  767. * -1 - if error.
  768. *---------------------------------------------------------------------------*/
  769. static uint8_t SELTimeClockSync(uint8_t Action)
  770. {
  771. SELEventRecord_T *EventRec = (SELEventRecord_T*)m_SysEventMsg;
  772. uint8_t pRes[sizeof(AddSELRes_T)];
  773. EventRec->body.sysEventRecord.SensorNum = 0xFF;
  774. EventRec->body.sysEventRecord.EvtDirType = 0x6F; // Sensor Specific
  775. EventRec->body.sysEventRecord.EvtData1 = 0x05; // Offset 05h - Timestamp Clock Sync
  776. EventRec->body.sysEventRecord.EvtData2 = Action;
  777. EventRec->body.sysEventRecord.EvtData3 = 0xFF;
  778. LockedAddSELEntry((uint8_t*)EventRec, sizeof(SELEventRecord_T), pRes);
  779. return 0;
  780. }