/** * ImcCrashReset - IMC Crash Reset * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID ImcCrashReset ( IN VOID *FchDataPtr ) { UINT8 Msgdata; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; if (!(IsImcEnabled (StdHeader)) ) { return; ///IMC is not enabled } ReadECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); if ( Msgdata != 0xfa) { ReadECmsg (MSG_REGA, AccessWidth8, &Msgdata, StdHeader); if ( Msgdata != 0x5A ) { ReadECmsg (MSG_REGB, AccessWidth8, &Msgdata, StdHeader); if ( Msgdata != 0xA5 ) { // Set up MSG_REGA = 0x5A and MSG_REGB = 0xA5 as a flag to indicate IMC has been // reset once already, this is to prevent repeating the reset forever. Msgdata = 0x5A; WriteECmsg (MSG_REGA, AccessWidth8, &Msgdata, StdHeader); Msgdata = 0xA5; WriteECmsg (MSG_REGB, AccessWidth8, &Msgdata, StdHeader); SoftwareDisableImc (LocalCfgPtr); } } } }
void enable_imc_thermal_zone(void) { AMD_CONFIG_PARAMS StdHeader; UINT8 FunNum; UINT8 regs[9]; int i; regs[0] = 0; regs[1] = 0; FunNum = Fun_80; for (i=0; i<=1; i++) WriteECmsg(MSG_REG0 + i, AccessWidth8, ®s[i], &StdHeader); WriteECmsg(MSG_SYS_TO_IMC, AccessWidth8, &FunNum, &StdHeader); // function number WaitForEcLDN9MailboxCmdAck(&StdHeader); for (i=2; i<=9; i++) ReadECmsg(MSG_REG0 + i, AccessWidth8, ®s[i], &StdHeader); /* enable thermal zone 0 */ regs[2] |= 1; regs[0] = 0; regs[1] = 0; FunNum = Fun_81; for (i=0; i<=9; i++) WriteECmsg(MSG_REG0 + i, AccessWidth8, ®s[i], &StdHeader); WriteECmsg(MSG_SYS_TO_IMC, AccessWidth8, &FunNum, &StdHeader); // function number WaitForEcLDN9MailboxCmdAck(&StdHeader); }
VOID WaitForEcLDN9MailboxCmdAck ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 Msgdata; UINT32 Delaytime; Msgdata = 0; for (Delaytime = 0; Delaytime <= 100000; Delaytime++) { ReadECmsg (MSG_REG0, AccessWidth8, &Msgdata, StdHeader); if ( Msgdata == 0xfa) { break; } FchStall (5, StdHeader); /// Wait for 1ms } }