123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- /****************************************************************
- ****************************************************************
- ** **
- ** (C)Copyright 2005-2006, American Megatrends Inc. **
- ** **
- ** All Rights Reserved. **
- ** **
- ** 6145-F, Northbelt Parkway, Norcross, **
- ** **
- ** Georgia - 30071, USA. Phone-(770)-246-8600. **
- ** **
- ****************************************************************
- ****************************************************************/
- /*****************************************************************
- *
- * WDT.c
- * WadtchDog TimeOut function
- *
- * Author: Govind Kothandapani <govindk@ami.com>
- * : Rama Bisa <ramab@ami.com>
- * : Basavaraj Astekar <basavaraja@ami.com>
- * : Bakka Ravinder Reddy <bakkar@ami.com>
- *
- *****************************************************************/
- #define ENABLE_DEBUG_MACROS 0
- #include "Types.h"
- #include "WDT.h"
- #include "Message.h"
- #include "Debug.h"
- #include "WDT.h"
- #include "IPMIDefs.h"
- #include "NVRAccess.h"
- #include "IPMI_Sensor.h"
- #include "Events.h"
- #include "Platform.h"
- #include "SharedMem.h"
- #include "ChassisDevice.h"
- #include "ChassisAPI.h"
- #include"IPMI_KCS.h"
- #include "ChassisCtrl.h"
- #include "PDKAccess.h"
- #include "IPMIConf.h"
- #include "Util.h"
- #include "LANConfig.h"
- #include <sys/prctl.h>
- #include "featuredef.h"
- #include "featuredef.h"
- #include "flashlib.h"
- /*** Local macro definitions ***/
- #define PRE_TIMEOUT 1
- #define WDT_TIMEOUT 2
- #define PRETIMEOUT_ACTION_TAKEN 0x08
- #define TIMEOUT_NO_ACTION_TAKEN 0x00
- #define TIMEOUT_ACTION_HARD_RESET 0x01
- #define TIMEOUT_ACTION_POWER_DOWN 0x02
- #define TIMEOUT_ACTION_POWER_CYCLE 0x03
- #define PRE_TIMEOUT_SMI 0x10
- #define PRE_TIMEOUT_NMI_DIAG 0x20
- #define PRE_TIMEOUT_MESSAGING_INTR 0x30
- /*** Global variables **/
- _FAR_ WDTTmrMgr_T g_WDTTmrMgr;
- /*----------------------------------------------------------------
- * WatchDog2 Event Offsets
- *---------------------------------------------------------------*/
- #define IPMI_WDT_TIMER_EXPIRED 0x00 //Watch Dog Expired Status only offset
- #define IPMI_WDT_HARD_RESET 0x01
- #define IPMI_WDT_POWER_DOWN 0x02
- #define IPMI_WDT_POWER_CYCLE 0x03
- #define IPMI_WDT_TIMER_INTERRUPT 0x08
- #define MAX_WDT_MS_VALUE(Hertz) (0xFFFFFFFF * 1000)/Hertz
- /*** Function Prototypes ***/
- static void WDTTmrAction (INT8U TmrAction, int BMCInst);
- /* Declare Thread Mutex */
- //OS_THREAD_MUTEX_DECLARE(hWDTSharedMemMutex);
- /**
- * WDTTimerTask
- **/
- void *
- WDTTimerTask (void *pArg)
- {
- int *inst = (int*) pArg;
- int BMCInst = *inst;
- _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
- INT32U WDTInterval = 0,WDTPreInterval = 0,jiffycmp = 0;
- long long jiffyvalue=0,jiffystart = 0;
- unsigned long Hertz = sysconf(_SC_CLK_TCK);
- prctl(PR_SET_NAME,__FUNCTION__,0,0,0);
- /* Get the Shared memory mutex handle */
- OS_THREAD_MUTEX_INIT(pBMCInfo->hWDTSharedMemMutex, PTHREAD_MUTEX_RECURSIVE);
- while(TRUE)
- {
- /* Will be waiting till the Watchdog timer is armed*/
- sem_wait(&pBMCInfo->WDTSem);
- /* If no timer to process return */
- if (FALSE == BMC_GET_SHARED_MEM(BMCInst)->IsWDTPresent)
- {
- continue;
- }
- WDTInterval = pBMCInfo->WDTConfig.InitCountDown * WDT_COUNT_MS;
- if ((pBMCInfo->WDTConfig.TmrActions & 0x70) == 0)
- {
- WDTPreInterval = WDTInterval+1;
- }
- else
- {
- WDTPreInterval = 1000 * pBMCInfo->WDTConfig.PreTimeOutInterval;
- }
- if(GetJiffySysCtlvalue(JIFFY_VALUE,&jiffyvalue) == 1)
- {
- IPMI_ERROR("Error in getting Jiffy value \n");
- return 0;
- }
- jiffystart = jiffyvalue;
- while(1)
- {
- if(GetJiffySysCtlvalue(JIFFY_VALUE,&jiffyvalue) == 1)
- {
- IPMI_ERROR("Error in getting Jiffy value \n");
- return 0;
- }
- if (pBMCInfo->HostOFFStopWDT == TRUE)
- {
- pBMCInfo->HostOFFStopWDT = FALSE;
- break;
- }
- if(pBMCInfo->SetWDTUpdated == TRUE && (TRUE == BMC_GET_SHARED_MEM(BMCInst)->IsWDTPresent))
- {
- jiffystart = jiffyvalue;
- WDTInterval = pBMCInfo->WDTConfig.InitCountDown * WDT_COUNT_MS;
- if ((pBMCInfo->WDTConfig.TmrActions & 0x70) == 0)
- {
- WDTPreInterval = WDTInterval+1;
-
- }
- else
- {
- WDTPreInterval = 1000 * pBMCInfo->WDTConfig.PreTimeOutInterval;
- }
- pBMCInfo->SetWDTUpdated = FALSE;
- }
- else if(pBMCInfo->SetWDTUpdated == TRUE && (FALSE== BMC_GET_SHARED_MEM(BMCInst)->IsWDTPresent))
- {
- /* Restore Initial countdown value */
- g_WDTTmrMgr.TmrInterval = pBMCInfo->WDTConfig.InitCountDown;
- break;
- }
- if(jiffyvalue < jiffystart)
- {
- /* To handle Jiffy Overflow condition */
- jiffycmp = (MAX_WDT_MS_VALUE(Hertz) -jiffystart) + jiffyvalue;
- }
- else
- {
- jiffycmp = jiffyvalue - jiffystart;
- }
- if((jiffycmp > WDTInterval) ||(jiffycmp > (WDTInterval-WDTPreInterval)))
- {
- if((jiffycmp > (WDTInterval-WDTPreInterval)) && (pBMCInfo->WDTPreTmtStat == FALSE)
- && ((pBMCInfo->WDTConfig.TmrActions & 0x70) != 0))
- {
- /* take pretimeout actions */
- if(pBMCInfo->TriggerEvent.WDTTimeExpire)
- {
- if(0 == send_signal_by_name("Adviserd",SIGUSR2))
- {
- TDBG("Signal Sent successfully to adviser to start recording video\n");
- }
- else
- {
- TDBG("Cannot Send Signal to adviser to start recording video\n");
- }
- }
- WDTTmrAction (g_WDTTmrMgr.WDTTmr.TmrActions & 0x70, BMCInst);
- pBMCInfo->WDTPreTmtStat = TRUE;
- }
- else if(jiffycmp > WDTInterval)
- {
- g_WDTTmrMgr.TmrPresent = FALSE;
- OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->hWDTSharedMemMutex, WAIT_INFINITE)
- BMC_GET_SHARED_MEM(BMCInst)->IsWDTRunning=FALSE;
- BMC_GET_SHARED_MEM(BMCInst)->IsWDTPresent =FALSE;
- // Modify ARP status to resume the thread
- // after receiving set Watchdog Timer command
- //BMC_GET_SHARED_MEM(BMCInst)->GratArpStatus = RESUME_ARPS;
-
- INT8U i = 0;
- for (i = 0; i < MAX_LAN_CHANNELS; i++)
- {
- if((pBMCInfo->LanIfcConfig[i].Enabled == TRUE)
- && (pBMCInfo->LanIfcConfig[i].Up_Status == LAN_IFC_UP))
- {
- BMC_GET_SHARED_MEM(BMCInst)->ArpSuspendStatus[i] = RESUME_ARPS;
- UpdateArpStatus(pBMCInfo->LanIfcConfig[i].Ethindex, BMC_GET_SHARED_MEM(BMCInst)->IsWDTRunning, BMCInst);
- }
- }
-
- OS_THREAD_MUTEX_RELEASE(&pBMCInfo->hWDTSharedMemMutex);
- /* Take WDT timeout Actions */
- pBMCInfo->WDTPreTmtStat = FALSE;
- g_WDTTmrMgr.TmrInterval = 0;
- if(pBMCInfo->TriggerEvent.WDTTimeExpire)
- {
- if(0 == send_signal_by_name("Adviserd",SIGUSR2))
- {
- TDBG("Signal Sent successfully to adviser to start recording video\n");
- }
- else
- {
- TDBG("Cannot Send Signal to adviser to start recording video\n");
- }
- }
- WDTTmrAction (g_WDTTmrMgr.WDTTmr.TmrActions & 0x07, BMCInst);
- break;
- }
-
- }
- if((jiffycmp -WDTInterval) > 20)
- {
- /* Made to sleep for 100ms to reduce CPU Usage */
- usleep(WDT_SLEEP_TIME);
- g_WDTTmrMgr.TmrInterval = pBMCInfo->WDTConfig.InitCountDown - (jiffycmp/WDT_COUNT_MS);
- }
- }
- }
- }
- /**
- * @brief Takes action depending on the argument.
- * @param TmrAction Timeout action.
- **/
- static void
- WDTTmrAction (INT8U TmrAction, int BMCInst)
- {
- int i = 0;
- INT8U u8EventOffset;
- INT8U readFlags = 0;
- _FAR_ BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
- _FAR_ SensorInfo_T* pSensorInfo;
- SensorSharedMem_T* pSMSharedMem;
- if(IsCardInFlashMode()){
- return;
- }
-
- if (TmrAction & 0x70)
- {
- pBMCInfo->WDTConfig.PreTimeoutActionTaken = g_WDTTmrMgr.WDTTmr.PreTimeoutActionTaken = PRETIMEOUT_ACTION_TAKEN;
- if (pBMCInfo->IpmiConfig.KCS1IfcSupport == 1)
- {
- SET_SMS_ATN (0, BMCInst);
- if(g_corefeatures.kcs_obf_bit == ENABLED)
- {
- SET_OBF (0, BMCInst);
- }
- }
- if (pBMCInfo->IpmiConfig.KCS2IfcSupport == 1)
- {
- SET_SMS_ATN (1, BMCInst);
- if(g_corefeatures.kcs_obf_bit == ENABLED)
- {
- SET_OBF (1, BMCInst);
- }
- }
- if (pBMCInfo->IpmiConfig.KCS3IfcSuppport == 1)
- {
- SET_SMS_ATN (2, BMCInst);
- if(g_corefeatures.kcs_obf_bit == ENABLED)
- {
- SET_OBF (2, BMCInst);
- }
- }
- }
- else
- {
- pBMCInfo->WDTConfig.ExpirationFlag |= 0x1 << (pBMCInfo->WDTConfig.TmrUse & 0x07);
- // Based on the IPMI spec 27.7, the WDT expiration flag should not be preserved on any AC cycle.
- // update the WDT expiration flag in the global memory pool, not persistant in the flash
- g_WDTTmrMgr.WDTTmr.ExpirationFlag |= 0x1 << (pBMCInfo->WDTConfig.TmrUse & 0x07);
- }
- // setup sensor event offset
- u8EventOffset = TmrAction;
- if(g_corefeatures.wdt_flush_support == ENABLED )
- {
- FlushIPMI((INT8U*)&pBMCInfo->WDTConfig,(INT8U*)&pBMCInfo->WDTConfig,pBMCInfo->IPMIConfLoc.WDTDATAddr,
- sizeof(WDTConfig_T),BMCInst);
- }
- if(g_PDKHandle[PDK_BEFOREWATCHDOGACTION] != NULL)
- {
- if( (((int(*)(INT8U,WDTTmrMgr_T*,int))g_PDKHandle[PDK_BEFOREWATCHDOGACTION]) (TmrAction, &g_WDTTmrMgr,BMCInst)) != 0)
- {
- return;
- }
- }
- else
- {
- if (g_PDKHandle[PDK_PREWATCHDOGACTION] != NULL)
- {
- if( (((int(*)(INT8U*, WDTTmrMgr_T*, int))g_PDKHandle[PDK_PREWATCHDOGACTION]) (&TmrAction, &g_WDTTmrMgr,BMCInst)) != 0)
- {
- return;
- }
- }
- }
- switch (TmrAction)
- {
- case TIMEOUT_NO_ACTION_TAKEN:
- break;
- case TIMEOUT_ACTION_HARD_RESET:
- //Added for GetSystem RestartCause //
- pBMCInfo->ChassisConfig.SysRestartCause = RESTART_CAUSE_WDT_EXPIRATION;
- //API_OnSetRestartCause(RESTART_CAUSE_WDT_EXPIRATION, TRUE);
- OnSetRestartCause(pBMCInfo->ChassisConfig.SysRestartCause, TRUE,BMCInst);
- // perform the chassis control action
- Platform_HostColdReset (BMCInst);
- break;
- case TIMEOUT_ACTION_POWER_DOWN:
- //Added for GetSystem RestartCause //
- pBMCInfo->ChassisConfig.SysRestartCause = RESTART_CAUSE_WDT_EXPIRATION;
- //API_OnSetRestartCause(RESTART_CAUSE_WDT_EXPIRATION, TRUE);
- OnSetRestartCause(pBMCInfo->ChassisConfig.SysRestartCause, TRUE,BMCInst);
- // perform the chassis control action
- Platform_HostPowerOff (BMCInst);
- break;
- case TIMEOUT_ACTION_POWER_CYCLE:
- //Added for GetSystem RestartCause //
- pBMCInfo->ChassisConfig.SysRestartCause = RESTART_CAUSE_WDT_EXPIRATION;
- //API_OnSetRestartCause(RESTART_CAUSE_WDT_EXPIRATION, TRUE);
- OnSetRestartCause(pBMCInfo->ChassisConfig.SysRestartCause, TRUE,BMCInst);
- // perform the chassis control action
- Platform_HostPowerCycle (BMCInst);
- break;
- case PRE_TIMEOUT_NMI_DIAG:
- // perform the NMI
- Platform_HostDiagInt (BMCInst);
- // fall through
- case PRE_TIMEOUT_SMI:
- case PRE_TIMEOUT_MESSAGING_INTR:
- // setup sensor event offset to be the timer interrupt (08h)
- u8EventOffset = IPMI_WDT_TIMER_INTERRUPT;
- break;
- default:
- IPMI_ERROR("Invalid Timer Action for watchdog.\n");
- break;
- }
- // save the system restart cause even if there is no change
- FlushIPMI((INT8U*)&pBMCInfo->ChassisConfig,(INT8U*)&pBMCInfo->ChassisConfig,pBMCInfo->IPMIConfLoc.ChassisConfigAddr,sizeof(ChassisConfig_T),BMCInst);
- // pass the WDT event offset
- if(g_corefeatures.internal_sensor == ENABLED)
- {
- SetWD2SensorReading((1 << u8EventOffset), g_WDTTmrMgr.WDTTmr.TmrUse,g_WDTTmrMgr.WDTTmr.TmrActions,BMCInst);
-
- /* Get the Sensor Shared Memory */
- pSMSharedMem = (_FAR_ SensorSharedMem_T*)&pBMCInfo->SensorSharedMem;
- for (i = 0; i < pBMCInfo->SenConfig.ValidSensorCnt; i++)
- {
- /* When the SensorType is WatchDog, calling WD2EventLog here to create EventLog instead through SensorMonitor */
- if(pSMSharedMem->SensorInfo[pBMCInfo->SenConfig.ValidSensorList [i]].SensorTypeCode == SENSOR_TYPE_WATCHDOG2)
- {
- pSensorInfo = (SensorInfo_T*)&pSMSharedMem->SensorInfo[pBMCInfo->SenConfig.ValidSensorList [i]];
- WD2EventLog(pSensorInfo,&readFlags,BMCInst);
- }
- }
- }
- if(g_PDKHandle[PDK_WATCHDOGACTION] != NULL)
- {
- ((void(*)(INT8U,WDTTmrMgr_T*,int))g_PDKHandle[PDK_WATCHDOGACTION]) (TmrAction,&g_WDTTmrMgr,BMCInst);
- }
- /* Clearing don't log bit after Watchdog timeout */
- g_WDTTmrMgr.WDTTmr.TmrUse &= 0x7F;
- }
- /*-----------------------------------------------------------------
- * @fn StopWDTTimer
- *
- * @brief This is provided to stop Watchdog Timer.
- *
- * @return None.
- *-----------------------------------------------------------------*/
- void
- StopWDTTimer (int BMCInst)
- {
- BMCInfo_t* pBMCInfo = &g_BMCInfo[BMCInst];
- g_WDTTmrMgr.TmrPresent = FALSE;
- OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->hWDTSharedMemMutex, WAIT_INFINITE);
- BMC_GET_SHARED_MEM(BMCInst)->IsWDTRunning = FALSE;
- BMC_GET_SHARED_MEM(BMCInst)->IsWDTPresent = FALSE;
- OS_THREAD_MUTEX_RELEASE(&pBMCInfo->hWDTSharedMemMutex);
- }
|