/*++

Copyright (c) 2006 - 2007, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  DebugImageInfo.c
    
Abstract:

  Support functions for managing debug image info table when loading and unloading
  images.

--*/

#include <DxeMain.h>


static EFI_DEBUG_IMAGE_INFO_TABLE_HEADER  mDebugInfoTableHeader = {
  0,          // volatile UINT32                 UpdateStatus;
  0,          // UINT32                          TableSize;
  NULL        // EFI_DEBUG_IMAGE_INFO            *EfiDebugImageInfoTable;
};

static EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;

    
VOID
CoreInitializeDebugImageInfoTable (
  VOID
  )
/*++

Routine Description:

  Creates and initializes the DebugImageInfo Table.  Also creates the configuration
  table and registers it into the system table.

Arguments:
  None

Returns:
  NA

Notes:
  This function allocates memory, frees it, and then allocates memory at an
  address within the initial allocation. Since this function is called early
  in DXE core initialization (before drivers are dispatched), this should not
  be a problem.

--*/
{ 
  EFI_STATUS                          Status;
  EFI_PHYSICAL_ADDRESS                Mem;
  UINTN                               NumberOfPages; 

  //
  // Allocate boot services memory for the structure. It's required to be aligned on
  // a 4M boundary, so allocate a 4M block (plus what we require), free it up, calculate
  // a 4M aligned address within the memory we just freed, and then allocate memory at that
  // address for our initial structure.
  //
  NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER));  

  Status = CoreAllocatePages (AllocateAnyPages, EfiBootServicesData, NumberOfPages , &Mem); 
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR(Status)) {
    return;
  }
  Status = CoreFreePages (Mem, NumberOfPages); 
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR(Status)) {
    return;
  }
  //
  // Now get a 4M aligned address within the memory range we were given.
  // Then allocate memory at that address
  //
  Mem = (Mem + FOUR_MEG_MASK) & (~FOUR_MEG_MASK);
  
  Status = CoreAllocatePages (AllocateAddress, EfiBootServicesData, NumberOfPages - FOUR_MEG_PAGES, &Mem); 
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR(Status)) {
    return;
  }
  //
  // We now have a 4M aligned page allocated, so fill in the data structure.
  // Ideally we would update the CRC now as well, but the service may not yet be available.
  // See comments in the CoreUpdateDebugTableCrc32() function below for details.
  //
  mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem;
  mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
  mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST;
  mDebugTable->Crc32 = 0;
  Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
  ASSERT_EFI_ERROR (Status);
}

VOID
CoreUpdateDebugTableCrc32 (
  VOID
  )
/*++

Routine Description:

  Update the CRC32 in the Debug Table.
  Since the CRC32 service is made available by the Runtime driver, we have to
  wait for the Runtime Driver to be installed before the CRC32 can be computed.
  This function is called elsewhere by the core when the runtime architectural
  protocol is produced.

Arguments:
  None

Returns:
  NA

--*/
{
  ASSERT(mDebugTable != NULL);
  mDebugTable->Crc32 = 0;
  gDxeCoreBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
}

VOID
CoreNewDebugImageInfoEntry (
  IN  UINT32                      ImageInfoType,
  IN  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage,
  IN  EFI_HANDLE                  ImageHandle
  )
/*++

Routine Description:

  Adds a new DebugImageInfo structure to the DebugImageInfo Table.  Re-Allocates
  the table if it's not large enough to accomidate another entry.

Arguments:

  ImageInfoType     - type of debug image information
  LoadedImage       - pointer to the loaded image protocol for the image being loaded
  ImageHandle       - image handle for the image being loaded

Returns:
  NA

--*/
{    
  EFI_DEBUG_IMAGE_INFO      *Table;
  EFI_DEBUG_IMAGE_INFO      *NewTable;
  UINTN                     Index;
  UINTN                     MaxTableIndex;
  UINTN                     TableSize;

  //
  // Set the flag indicating that we're in the process of updating the table.
  //
  mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

  Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
  MaxTableIndex = mDebugInfoTableHeader.TableSize;

  for (Index = 0; Index < MaxTableIndex; Index++) {
    if (Table[Index].NormalImage == NULL) {
      //
      // We have found a free entry so exit the loop
      //
      break;
    }
  }
  if (Index == MaxTableIndex) {
    //
    //  Table is full, so re-allocate another page for a larger table...
    //
    TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;
    NewTable = CoreAllocateZeroBootServicesPool (TableSize + EFI_PAGE_SIZE);
    if (NewTable == NULL) {
      mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
      return;
    }
    //
    // Copy the old table into the new one
    //
    CopyMem (NewTable, Table, TableSize);
    //
    // Free the old table
    //
    CoreFreePool (Table);
    //
    // Update the table header
    //
    Table = NewTable;
    mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
    mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
  }
  //
  // Allocate data for new entry
  //
  Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
  if (Table[Index].NormalImage != NULL) {
    //
    // Update the entry
    //
    Table[Index].NormalImage->ImageInfoType               = (UINT32) ImageInfoType;
    Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
    Table[Index].NormalImage->ImageHandle                 = ImageHandle;
  }
  mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
}


VOID
CoreRemoveDebugImageInfoEntry (
  EFI_HANDLE ImageHandle
  )
/*++

Routine Description:

  Removes and frees an entry from the DebugImageInfo Table.

Arguments:

  ImageHandle       - image handle for the image being unloaded

Returns:

  NA

--*/
{    
  EFI_DEBUG_IMAGE_INFO  *Table;
  UINTN                 Index;

  mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;

  Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;

  for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {
    if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {
      //
      // Found a match. Free up the record, then NULL the pointer to indicate the slot
      // is free.
      //
      CoreFreePool (Table[Index].NormalImage);
      Table[Index].NormalImage = NULL;
      break;
    }
  }
  mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
}

