Exemplo n.º 1
0
/*++

Routine Description:
  Main entry point to SEC for Unix. This is a unix program

Arguments:
  Argc - Number of command line arguments
  Argv - Array of command line argument strings
  Envp - Array of environment variable strings

Returns:
  0 - Normal exit
  1 - Abnormal exit

**/
int
main (
  IN  int   Argc,
  IN  char  **Argv,
  IN  char  **Envp
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  InitialStackMemory;
  UINT64                InitialStackMemorySize;
  UINTN                 Index;
  UINTN                 Index1;
  UINTN                 Index2;
  UINTN                 PeiIndex;
  CHAR8                 *FileName;
  BOOLEAN               Done;
  EFI_PEI_FILE_HANDLE   FileHandle;
  VOID                  *SecFile;
  CHAR16                *MemorySizeStr;
  CHAR16                *FirmwareVolumesStr;
  UINTN                 *StackPointer;
  FILE                  *GdbTempFile;

  //
  // Xcode does not support sourcing gdb scripts directly, so the Xcode XML
  // has a break point script to source the GdbRun script.
  //
  SecGdbConfigBreak ();

  //
  // If dlopen doesn't work, then we build a gdb script to allow the
  // symbols to be loaded.
  //
  Index = strlen (*Argv);
  gGdbWorkingFileName = AllocatePool (Index + strlen(".gdb") + 1);
  strcpy (gGdbWorkingFileName, *Argv);
  strcat (gGdbWorkingFileName, ".gdb");

  //
  // Empty out the gdb symbols script file.
  //
  GdbTempFile = fopen (gGdbWorkingFileName, "w");
  if (GdbTempFile != NULL) {
    fclose (GdbTempFile);
  }

  printf ("\nEDK II UNIX Host Emulation Environment from http://www.tianocore.org/edk2/\n");

  setbuf (stdout, 0);
  setbuf (stderr, 0);

  MemorySizeStr      = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize);
  FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume);

  //
  // PPIs pased into PEI_CORE
  //
  AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi);

  SecInitThunkProtocol ();

  //
  // Emulator Bus Driver Thunks
  //
  AddThunkProtocol (&gX11ThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE);
  AddThunkProtocol (&gPosixFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE);
  AddThunkProtocol (&gBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE);
  AddThunkProtocol (&gSnpThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuNetworkInterface), TRUE);

  //
  // Emulator other Thunks
  //
  AddThunkProtocol (&gPthreadThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuApCount), FALSE);

  // EmuSecLibConstructor ();

  gPpiList = GetThunkPpiList ();

  //
  // Allocate space for gSystemMemory Array
  //
  gSystemMemoryCount  = CountSeparatorsInString (MemorySizeStr, '!') + 1;
  gSystemMemory       = AllocateZeroPool (gSystemMemoryCount * sizeof (EMU_SYSTEM_MEMORY));
  if (gSystemMemory == NULL) {
    printf ("ERROR : Can not allocate memory for system.  Exiting.\n");
    exit (1);
  }
  //
  // Allocate space for gSystemMemory Array
  //
  gFdInfoCount  = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1;
  gFdInfo       = AllocateZeroPool (gFdInfoCount * sizeof (EMU_FD_INFO));
  if (gFdInfo == NULL) {
    printf ("ERROR : Can not allocate memory for fd info.  Exiting.\n");
    exit (1);
  }

  printf ("  BootMode 0x%02x\n", (unsigned int)PcdGet32 (PcdEmuBootMode));

  //
  // Open up a 128K file to emulate temp memory for SEC.
  //  on a real platform this would be SRAM, or using the cache as RAM.
  //  Set InitialStackMemory to zero so UnixOpenFile will allocate a new mapping
  //
  InitialStackMemorySize  = STACK_SIZE;
  InitialStackMemory = (UINTN)MapMemory (
                                0, (UINT32) InitialStackMemorySize,
                                PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE
                                );
  if (InitialStackMemory == 0) {
    printf ("ERROR : Can not open SecStack Exiting\n");
    exit (1);
  }

  printf ("  OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n",
    (unsigned int)(InitialStackMemorySize / 1024),
    (unsigned long)InitialStackMemory
    );

  for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;
     StackPointer < (UINTN*)(UINTN)((UINTN) InitialStackMemory + (UINT64) InitialStackMemorySize);
     StackPointer ++) {
    *StackPointer = 0x5AA55AA5;
  }

  //
  // Open All the firmware volumes and remember the info in the gFdInfo global
  //
  FileName = (CHAR8 *) AllocatePool (StrLen (FirmwareVolumesStr) + 1);
  if (FileName == NULL) {
    printf ("ERROR : Can not allocate memory for firmware volume string\n");
    exit (1);
  }

  Index2 = 0;
  for (Done = FALSE, Index = 0, PeiIndex = 0, SecFile = NULL;
       FirmwareVolumesStr[Index2] != 0;
       Index++) {
    for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++) {
      FileName[Index1++] = FirmwareVolumesStr[Index2];
    }
    if (FirmwareVolumesStr[Index2] == '!') {
      Index2++;
    }
    FileName[Index1]  = '\0';

    if (Index == 0) {
      // Map FV Recovery Read Only and other areas Read/Write
      Status = MapFd0 (
                FileName,
                &gFdInfo[0].Address,
                &gFdInfo[0].Size
                );
    } else {
      //
      // Open the FD and remember where it got mapped into our processes address space
      // Maps Read Only
      //
      Status = MapFile (
                FileName,
                &gFdInfo[Index].Address,
                &gFdInfo[Index].Size
                );
    }
    if (EFI_ERROR (Status)) {
      printf ("ERROR : Can not open Firmware Device File %s (%x).  Exiting.\n", FileName, (unsigned int)Status);
      exit (1);
    }

    printf ("  FD loaded from %s at 0x%08lx",FileName, (unsigned long)gFdInfo[Index].Address);

    if (SecFile == NULL) {
      //
      // Assume the beginning of the FD is an FV and look for the SEC Core.
      // Load the first one we find.
      //
      FileHandle = NULL;
      Status = PeiServicesFfsFindNextFile (
                  EFI_FV_FILETYPE_SECURITY_CORE,
                  (EFI_PEI_FV_HANDLE)(UINTN)gFdInfo[Index].Address,
                  &FileHandle
                  );
      if (!EFI_ERROR (Status)) {
        Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile);
        if (!EFI_ERROR (Status)) {
          PeiIndex = Index;
          printf (" contains SEC Core");
        }
      }
    }

    printf ("\n");
  }

  if (SecFile == NULL) {
    printf ("ERROR : SEC not found!\n");
    exit (1);
  }

  //
  // Calculate memory regions and store the information in the gSystemMemory
  //  global for later use. The autosizing code will use this data to
  //  map this memory into the SEC process memory space.
  //
  Index1 = 0;
  Index = 0;
  while (1) {
    UINTN val = 0;
    //
    // Save the size of the memory.
    //
    while (MemorySizeStr[Index1] >= '0' && MemorySizeStr[Index1] <= '9') {
      val = val * 10 + MemorySizeStr[Index1] - '0';
      Index1++;
    }
    gSystemMemory[Index++].Size = val * 0x100000;
    if (MemorySizeStr[Index1] == 0) {
      break;
    }
    Index1++;
  }

  printf ("\n");

  //
  // Hand off to SEC
  //
  SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, SecFile);

  //
  // If we get here, then the SEC Core returned. This is an error as SEC should
  //  always hand off to PEI Core and then on to DXE Core.
  //
  printf ("ERROR : SEC returned\n");
  exit (1);
}
Exemplo n.º 2
0
VOID
SecLoadSecCore (
  IN  UINTN   TemporaryRam,
  IN  UINTN   TemporaryRamSize,
  IN  VOID    *BootFirmwareVolumeBase,
  IN  UINTN   BootFirmwareVolumeSize,
  IN  VOID    *SecCorePe32File
  )
/*++

Routine Description:
  This is the service to load the SEC Core from the Firmware Volume

Arguments:
  TemporaryRam            - Memory to use for SEC.
  TemporaryRamSize        - Size of Memory to use for SEC
  BootFirmwareVolumeBase  - Start of the Boot FV
  SecCorePe32File         - SEC Core PE32

Returns:
  Success means control is transfered and thus we should never return

--*/
{
  EFI_STATUS                  Status;
  VOID                        *TopOfStack;
  VOID                        *SecCoreEntryPoint;
  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
  UINTN                       SecStackSize;

  //
  // Compute Top Of Memory for Stack and PEI Core Allocations
  //
  SecStackSize = TemporaryRamSize >> 1;

  //
  // |-----------| <---- TemporaryRamBase + TemporaryRamSize
  // |   Heap    |
  // |           |
  // |-----------| <---- StackBase / PeiTemporaryMemoryBase
  // |           |
  // |  Stack    |
  // |-----------| <---- TemporaryRamBase
  //
  TopOfStack  = (VOID *)(TemporaryRam + SecStackSize);

  //
  // Reservet space for storing PeiCore's parament in stack.
  //
  TopOfStack  = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);
  TopOfStack  = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);

  //
  // Bind this information into the SEC hand-off state
  //
  SecCoreData                         = (EFI_SEC_PEI_HAND_OFF*)(UINTN)TopOfStack;
  SecCoreData->DataSize               = sizeof (EFI_SEC_PEI_HAND_OFF);
  SecCoreData->BootFirmwareVolumeBase = BootFirmwareVolumeBase;
  SecCoreData->BootFirmwareVolumeSize = BootFirmwareVolumeSize;
  SecCoreData->TemporaryRamBase       = (VOID*)TemporaryRam;
  SecCoreData->TemporaryRamSize       = TemporaryRamSize;
  SecCoreData->StackBase              = SecCoreData->TemporaryRamBase;
  SecCoreData->StackSize              = SecStackSize;
  SecCoreData->PeiTemporaryRamBase    = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + SecStackSize);
  SecCoreData->PeiTemporaryRamSize    = TemporaryRamSize - SecStackSize;

  //
  // Load the PEI Core from a Firmware Volume
  //
  Status = SecPeCoffGetEntryPoint (
            SecCorePe32File,
            &SecCoreEntryPoint
            );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Transfer control to the SEC Core
  //
  SwitchStack (
    (SWITCH_STACK_ENTRY_POINT)(UINTN)SecCoreEntryPoint,
    SecCoreData,
    GetThunkPpiList (),
    TopOfStack
    );
  //
  // If we get here, then the SEC Core returned.  This is an error
  //
  return ;
}