summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Debug/IdsIdtTable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/IDS/Debug/IdsIdtTable.c')
-rw-r--r--src/vendorcode/amd/agesa/f15tn/Proc/IDS/Debug/IdsIdtTable.c329
1 files changed, 329 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Debug/IdsIdtTable.c b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Debug/IdsIdtTable.c
new file mode 100644
index 0000000000..f7e6a560eb
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Debug/IdsIdtTable.c
@@ -0,0 +1,329 @@
+/**
+ * @file
+ *
+ * Adding IDT table for debugging exception
+ *
+ * Contains IDT related function
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: IDS
+ * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
+ */
+/*****************************************************************************
+ * Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
+ *
+ * AMD is granting you permission to use this software (the Materials)
+ * pursuant to the terms and conditions of your Software License Agreement
+ * with AMD. This header does *NOT* give you permission to use the Materials
+ * or any rights under AMD's intellectual property. Your use of any portion
+ * of these Materials shall constitute your acceptance of those terms and
+ * conditions. If you do not agree to the terms and conditions of the Software
+ * License Agreement, please do not use any portion of these Materials.
+ *
+ * CONFIDENTIALITY: The Materials and all other information, identified as
+ * confidential and provided to you by AMD shall be kept confidential in
+ * accordance with the terms and conditions of the Software License Agreement.
+ *
+ * LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION
+ * PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+ * MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE,
+ * OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE.
+ * IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
+ * INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE,
+ * GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER
+ * RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE
+ * EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES,
+ * THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
+ *
+ * AMD does not assume any responsibility for any errors which may appear in
+ * the Materials or any other related information provided to you by AMD, or
+ * result from use of the Materials or any related information.
+ *
+ * You agree that you will not reverse engineer or decompile the Materials.
+ *
+ * NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
+ * further information, software, technical information, know-how, or show-how
+ * available to you. Additionally, AMD retains the right to modify the
+ * Materials at any time, without notice, and is not obligated to provide such
+ * modified Materials to you.
+ *
+ * U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
+ * "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is
+ * subject to the restrictions as set forth in FAR 52.227-14 and
+ * DFAR252.227-7013, et seq., or its successor. Use of the Materials by the
+ * Government constitutes acknowledgement of AMD's proprietary rights in them.
+ *
+ * EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any
+ * direct product thereof will be exported directly or indirectly, into any
+ * country prohibited by the United States Export Administration Act and the
+ * regulations thereunder, without the required authorization from the U.S.
+ * government nor will be used for any purpose prohibited by the same.
+ ******************************************************************************
+ */
+
+ /*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+#include "AGESA.h"
+#include "Ids.h"
+#include "IdsLib.h"
+#include "amdlib.h"
+#include "AMD.h"
+#include "GeneralServices.h"
+#include "cpuApicUtilities.h"
+#include "heapManager.h"
+#include "cpuRegisters.h"
+#include "Filecode.h"
+CODE_GROUP (G1_PEICC)
+RDATA_GROUP (G1_PEICC)
+
+#define FILECODE PROC_IDS_DEBUG_IDSIDTTABLE_FILECODE
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+ IDS_STATUS
+STATIC
+IdsReplaceIdtr (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+IDS_STATUS
+STATIC
+IdsRestoreIdtr (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+IDS_STATUS
+STATIC
+IdsUpdateExceptionVector (
+ IN VOID *DataPtr,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ );
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+extern UINT64 IdsExceptionHandler;
+extern UINT32 SizeIdtDescriptor;
+extern UINT32 SizeTotalIdtDescriptors;
+
+/**
+ * IDS IDT table.
+ *
+ * This is the top level interface for IDS IDT table function.
+ * Adding a 'jmp $' into every exception handler.
+ * So debugger could use HDT to skip 'jmp $' and execute the iret,
+ * then they could find which instruction cause the exception.
+ *
+ * @param[in] IdsIdtFuncId IDT indicator value, see @ref IDS_IDT_FUNC_ID
+ * @param[in] DataPtr Points to data that may used by IdsIdtTable routine
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ **/
+IDS_STATUS
+IdsExceptionTrap (
+ IN IDS_IDT_FUNC_ID IdsIdtFuncId,
+ IN VOID *DataPtr,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ IDS_STATUS ReturnFlag;
+ AGESA_STATUS Ignored;
+
+ ReturnFlag = IDS_SUCCESS;
+ switch (IdsIdtFuncId) {
+ case IDS_IDT_REPLACE_IDTR_FOR_BSC:
+ if (IsBsp (StdHeader, &Ignored)) {
+ ReturnFlag = IdsReplaceIdtr (StdHeader);
+ }
+ break;
+ case IDS_IDT_RESTORE_IDTR_FOR_BSC:
+ if (IsBsp (StdHeader, &Ignored)) {
+ ReturnFlag = IdsRestoreIdtr (StdHeader);
+ }
+ break;
+ case IDS_IDT_UPDATE_EXCEPTION_VECTOR_FOR_AP:
+ ReturnFlag = IdsUpdateExceptionVector (DataPtr, StdHeader);
+ break;
+ default:
+ return IDS_UNSUPPORTED;
+ break;
+ }
+ return ReturnFlag;
+}
+
+/*---------------------------------------------------------------------------------------
+ * L O C A L F U N C T I O N S
+ *---------------------------------------------------------------------------------------
+ */
+
+/**
+ * Replace IDTR of BSC.
+ *
+ * Save IDTR of BSC to heap and replace IDTR.
+ *
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ **/
+IDS_STATUS
+STATIC
+IdsReplaceIdtr (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ ALLOCATE_HEAP_PARAMS AllocParams;
+ LOCATE_HEAP_PTR LocateHeap;
+ IDT_BASE_LIMIT IdtInfo;
+
+ // Save IDTR to Heap
+ AllocParams.BufferHandle = IDS_SAVE_IDTR_HANDLE;
+ AllocParams.RequestedBufferSize = sizeof (IDT_BASE_LIMIT);
+ AllocParams.Persist = HEAP_TEMP_MEM;
+ if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) {
+ return IDS_UNSUPPORTED;
+ }
+ GetIdtr ((IDT_BASE_LIMIT *) AllocParams.BufferPtr, StdHeader);
+
+ // Check if host env has their own IDT
+ if (((IDT_BASE_LIMIT *) AllocParams.BufferPtr)->Base == 0) {
+ // Load AGESA's IDT
+ LocateHeap.BufferHandle = IDS_BSC_IDT_HANDLE;
+ // Check if we already allocated heap for creating IDT
+ if (HeapLocateBuffer (&LocateHeap, StdHeader) != AGESA_SUCCESS) {
+ // Create IDT for BSC in heap
+ AllocParams.BufferHandle = IDS_BSC_IDT_HANDLE;
+ AllocParams.RequestedBufferSize = sizeof (IDT_DESCRIPTOR) * 32;
+ AllocParams.Persist = HEAP_SYSTEM_MEM;
+ if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) {
+ return IDS_UNSUPPORTED;
+ }
+ IdtInfo.Base = (UINT64) AllocParams.BufferPtr;
+ } else {
+ IdtInfo.Base = (UINT64) LocateHeap.BufferPtr;
+ }
+ IdsUpdateExceptionVector ((VOID *) &IdtInfo, StdHeader);
+ SetIdtr (&IdtInfo, StdHeader);
+ } else {
+ return IDS_UNSUPPORTED;
+ }
+ return IDS_SUCCESS;
+}
+
+/**
+ * Restore IDTR of BSC.
+ *
+ * Restore IDTR of BSC from heap.
+ *
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ **/
+IDS_STATUS
+STATIC
+IdsRestoreIdtr (
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ LOCATE_HEAP_PTR LocateHeap;
+ IDT_BASE_LIMIT IdtInfo;
+
+ IdtInfo.Base = 0;
+ IdtInfo.Limit = 0;
+ GetIdtr (&IdtInfo, StdHeader);
+
+ LocateHeap.BufferHandle = IDS_BSC_IDT_HANDLE;
+ if (HeapLocateBuffer (&LocateHeap, StdHeader) != AGESA_SUCCESS) {
+ // If AGESA loaded its own IDT, there must be a buffer with handle IDS_BSC_IDT_HANDLE in heap
+ return IDS_UNSUPPORTED;
+ }
+ // If current IDTR.Base != address of AGESA's own IDT, it is possibile that Host env load their own IDT
+ if (IdtInfo.Base != ((UINT64) (LocateHeap.BufferPtr))) {
+ return IDS_UNSUPPORTED;
+ } else {
+ LocateHeap.BufferHandle = IDS_SAVE_IDTR_HANDLE;
+ if (HeapLocateBuffer (&LocateHeap, StdHeader) != AGESA_SUCCESS) {
+ return IDS_UNSUPPORTED;
+ }
+ SetIdtr ((IDT_BASE_LIMIT *) LocateHeap.BufferPtr, StdHeader);
+ HeapDeallocateBuffer (IDS_SAVE_IDTR_HANDLE, StdHeader);
+ }
+ return IDS_SUCCESS;
+}
+
+/**
+ * Update exception vector.
+ *
+ * Adding a 'jmp $' into every exception handler.
+ * So debugger could use HDT to skip 'jmp $' and execute the iret,
+ * then they could find which instruction cause the exception.
+ *
+ * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS.
+ *
+ * @retval IDS_SUCCESS Backend function is called successfully.
+ * @retval IDS_UNSUPPORTED No Backend function is found.
+ **/
+IDS_STATUS
+STATIC
+IdsUpdateExceptionVector (
+ IN VOID *DataPtr,
+ IN OUT AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ IDT_DESCRIPTOR *IdtDesc;
+ UINT8 DescSize;
+ UINT16 Selector;
+ UINT16 i;
+ UINT64 HandlerOffset;
+ UINT64 EferRegister;
+ AGESA_STATUS Ignored;
+
+ LibAmdMsrRead (MSR_EXTENDED_FEATURE_EN, &EferRegister, StdHeader);
+ if ((EferRegister & 0x100) != 0) {
+ DescSize = 16;
+ } else {
+ DescSize = 8;
+ }
+
+ // Update limit
+ ((IDT_BASE_LIMIT *) DataPtr)->Limit = (UINT16) ((DescSize * 32) - 1);
+ // Update IDT
+ IdtDesc = (IDT_DESCRIPTOR *) (((IDT_BASE_LIMIT *) DataPtr)->Base);
+ HandlerOffset = (UINT64) IdsExceptionHandler;
+ GetCsSelector (&Selector, StdHeader);
+
+ ASSERT (SizeTotalIdtDescriptors == (SizeIdtDescriptor * 32));
+ for (i = 0; i < 32; i++) {
+ // Vector - 2 NMI handler for APs is used by AGESA. So we should not replace that handler.
+ if ((i == 2) && (!IsBsp (StdHeader, &Ignored))) {
+ IdtDesc = (IDT_DESCRIPTOR *) (((UINT8 *) IdtDesc) + DescSize);
+ HandlerOffset += SizeIdtDescriptor;
+ continue;
+ }
+ IdtDesc->OffsetLo = (UINT16) HandlerOffset & 0xFFFF;
+ IdtDesc->OffsetHi = (UINT16) (HandlerOffset >> 16);
+ IdtDesc->Flags = IDT_DESC_PRESENT | IDT_DESC_TYPE_INT32;
+ IdtDesc->Selector = Selector;
+ IdtDesc->Rsvd = 0;
+ if ((EferRegister & 0x100) != 0) {
+ IdtDesc->Offset64 = (UINT32) (HandlerOffset >> 32);
+ IdtDesc->Rsvd64 = 0;
+ }
+ IdtDesc = (IDT_DESCRIPTOR *) (((UINT8 *) IdtDesc) + DescSize);
+ HandlerOffset += SizeIdtDescriptor;
+ }
+ return IDS_SUCCESS;
+}
+