예제 #1
0
/**
  A notification for CPU_ARCH protocol.

  @param[in]  Event                 Event whose notification function is being invoked.
  @param[in]  Context               Pointer to the notification function's context,
                                    which is implementation-dependent.

**/
VOID
EFIAPI
MemoryProtectionCpuArchProtocolNotify (
  IN EFI_EVENT                Event,
  IN VOID                     *Context
  )
{
  EFI_STATUS                  Status;
  EFI_LOADED_IMAGE_PROTOCOL   *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL    *LoadedImageDevicePath;
  UINTN                       NoHandles;
  EFI_HANDLE                  *HandleBuffer;
  UINTN                       Index;

  DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n"));
  Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Apply the memory protection policy on non-BScode/RTcode regions.
  //
  if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) {
    InitializeDxeNxMemoryProtectionPolicy ();
  }

  //
  // Call notify function meant for Heap Guard.
  //
  HeapGuardCpuArchProtocolNotify ();

  if (mImageProtectionPolicy == 0) {
    return;
  }

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiLoadedImageProtocolGuid,
                  NULL,
                  &NoHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status) && (NoHandles == 0)) {
    return ;
  }

  for (Index = 0; Index < NoHandles; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiLoadedImageProtocolGuid,
                    (VOID **)&LoadedImage
                    );
    if (EFI_ERROR(Status)) {
      continue;
    }
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiLoadedImageDevicePathProtocolGuid,
                    (VOID **)&LoadedImageDevicePath
                    );
    if (EFI_ERROR(Status)) {
      LoadedImageDevicePath = NULL;
    }

    ProtectUefiImage (LoadedImage, LoadedImageDevicePath);
  }

  CoreCloseEvent (Event);
  return;
}
예제 #2
0
/**
  Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().
  This notify function is registered for every architectural protocol. This handler
  updates mArchProtocol[] array entry with protocol instance data and sets it's
  present flag to TRUE. If any constructor is required it is executed. The EFI
  System Table headers are updated.

  @param  Event          The Event that is being processed, not used.
  @param  Context        Event Context, not used.

**/
VOID
EFIAPI
GenericProtocolNotify (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS                      Status;
  EFI_CORE_PROTOCOL_NOTIFY_ENTRY  *Entry;
  VOID                            *Protocol;
  LIST_ENTRY                      *Link;
  LIST_ENTRY                      TempLinkNode;

  Protocol = NULL;

  //
  // Get Entry from Context
  //
  Entry = (EFI_CORE_PROTOCOL_NOTIFY_ENTRY *)Context;

  //
  // See if the expected protocol is present in the handle database
  //
  Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Mark the protocol as present
  //
  Entry->Present = TRUE;

  //
  // Update protocol global variable if one exists. Entry->Protocol points to a global variable
  // if one exists in the DXE core for this Architectural Protocol
  //
  if (Entry->Protocol != NULL) {
    *(Entry->Protocol) = Protocol;
  }

  //
  // Do special operations for Architectural Protocols
  //

  if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {
    //
    // Register the Core timer tick handler with the Timer AP
    //
    gTimer->RegisterHandler (gTimer, CoreTimerTick);
  }

  if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {
    //
    // When runtime architectural protocol is available, updates CRC32 in the Debug Table
    //
    CoreUpdateDebugTableCrc32 ();

    //
    // Update the Runtime Architectural protocol with the template that the core was
    // using so there would not need to be a dependency on the Runtime AP
    //

    //
    // Copy all the registered Image to new gRuntime protocol
    //
    for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {
      CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));
      InsertTailList (&gRuntime->ImageHead, Link);
    }
    //
    // Copy all the registered Event to new gRuntime protocol
    //
    for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {
      CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY));
      InsertTailList (&gRuntime->EventHead, Link);
    }

    //
    // Clean up gRuntimeTemplate
    //
    gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;
    gRuntimeTemplate.ImageHead.BackLink    = &gRuntimeTemplate.ImageHead;
    gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;
    gRuntimeTemplate.EventHead.BackLink    = &gRuntimeTemplate.EventHead;
  }

  //
  // It's over kill to do them all every time, but it saves a lot of code.
  //
  CalculateEfiHdrCrc (&gDxeCoreRT->Hdr);
  CalculateEfiHdrCrc (&gBS->Hdr);
  CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
  CalculateEfiHdrCrc (&gDxeCoreDS->Hdr);
}