/* * Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD"). * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ //* Function: * //* This file contains the code for recording event history. #include "VSA2.H" #include "SYSMGR.H" #include "PROTOS.H" extern EVENT_ENTRY Events[]; extern ULONG MsgPacket[]; extern UCHAR VSM_Filter; #if HISTORY EVENT NonReportableEvents[] = { EVENT_A20, EVENT_GRAPHICS, EVENT_ACPI_TIMER }; #define UNREPORT_COUNT (sizeof(NonReportableEvents)/sizeof(EVENT)) // // Event history // EVENT_HISTORY History[HISTORY]; int HistoryWrap = 0; int HistoryStart = 0; int HistoryEnd = 0; //***************************************************************************** // // Record the event history // //***************************************************************************** void Keep_History(EVENT Event, EVENT EventIndex) { int i; ULONG ParamMask, Param2; UCHAR VSM_Type; register EVENT_ENTRY * EventPtr; EventPtr = &Events[EventIndex]; VSM_Type = Get_VSM_Type(EventPtr->Vsm); // Filter out VSM(s) if (VSM_Filter != VSM_ANY && VSM_Type != VSM_Filter) return; // // Filter events from reporting // for (i=0; i < UNREPORT_COUNT; i++) { if (Event == NonReportableEvents[i]) return; } // Generate mask for Param1 ParamMask = 0xFFFFFFFF; Param2 = EventPtr->Param2; switch (Event) { case EVENT_PCI_TRAP: // Report all PCI events together by PCI function ParamMask = ~Param2; break; case EVENT_GPIO: // Get current edge Param2 = EventPtr->CurrentEdge; break; case EVENT_SOFTWARE_SMI: // Don't report APM calls CPU_Busy or CPU_Idle if ((EventPtr->Param1 & 0xFF00) == 0x5300) { switch (EventPtr->Param1 & 0x00FF) { case 0x05: case 0x06: return; } break; } break; case EVENT_VIRTUAL_REGISTER: // Report all VR events together by classes ParamMask = 0x0000FF00; break; } // If it's the same event for the same VSM... if ((History[HistoryEnd].Event == Event) && (History[HistoryEnd].Vsm == EventPtr->Vsm) ) { switch (Event) { case EVENT_IO_TRAP: if (History[HistoryEnd].Param1 != (MsgPacket[2] & 0x0000FFFFL)) { break; } // Events to be recorded together if (Param1 & ParamMask) matches case EVENT_PCI_TRAP: case EVENT_SOFTWARE_SMI: case EVENT_VIRTUAL_REGISTER: if (History[HistoryEnd].Param1 != (MsgPacket[1] & ParamMask)) { break; } default: // Record together if 1st two parameters match if (History[HistoryEnd].Param1 == EventPtr->Param1 && History[HistoryEnd].Param2 == EventPtr->Param2 ) { History[HistoryEnd].Count++; Store_Timestamp(&History[HistoryEnd].TimeStamp); return; } } // end switch } // // Report event in a new history entry. // // Increment HistoryEnd unless it's the 1st event if (History[HistoryEnd].Vsm) { HistoryEnd++; if (HistoryEnd >= HISTORY) { HistoryEnd = 0; HistoryWrap = 1; } // Increment HistoryStart index too if HistoryEnd has wrapped if (HistoryWrap) { HistoryStart++; if (HistoryStart >= HISTORY) HistoryStart = 0; } } History[HistoryEnd].Vsm = EventPtr->Vsm; History[HistoryEnd].Event = Event; History[HistoryEnd].Param1 = MsgPacket[1] & ParamMask; History[HistoryEnd].Param2 = Param2; History[HistoryEnd].Count = 1; Store_Timestamp(&History[HistoryEnd].TimeStamp); } void Initialize_History(void) { // Initialize timestamp field of history buffer entry "previous" to 1st entry Store_Timestamp(&History[HISTORY-1].TimeStamp); HistoryWrap = 0; HistoryStart = 0; HistoryEnd = 0; } #else void Initialize_History(void) { } #endif