Пример #1
0
Файл: Md5.c Проект: Kohrara/edk
EFI_STATUS
MD5Final (
  IN  MD5_CTX  *Md5Ctx,
  OUT UINT8    *HashVal
  )
/*++

Routine Description:

  GC_TODO: Add function description

Arguments:

  Md5Ctx  - GC_TODO: add argument description
  HashVal - GC_TODO: add argument description

Returns:

  EFI_SUCCESS - GC_TODO: Add description for return value

--*/
{
  UINTN PadLength;

  if (Md5Ctx->Status == EFI_ALREADY_STARTED) {
    //
    // Store Hashed value & Zeroize sensitive context information.
    //
    EfiCopyMem (HashVal, (UINT8 *) Md5Ctx->States, MD5_HASHSIZE);
    EfiZeroMem ((UINT8 *)Md5Ctx, sizeof (*Md5Ctx));
    
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Md5Ctx->Status)) {
    return Md5Ctx->Status;
  }

  PadLength  = Md5Ctx->Count >= 56 ? 120 : 56;
  PadLength -= Md5Ctx->Count;
  MD5UpdateBlock (Md5Ctx, Md5HashPadding, PadLength);
  Md5Ctx->Length = LShiftU64 (Md5Ctx->Length, 3);
  MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) &Md5Ctx->Length, 8);

  EfiZeroMem (Md5Ctx->M, sizeof (Md5Ctx->M));
  Md5Ctx->Length  = 0;
  Md5Ctx->Status  = EFI_ALREADY_STARTED;
  return MD5Final (Md5Ctx, HashVal);
}
Пример #2
0
Файл: Md5.c Проект: Kohrara/edk
EFI_STATUS
MD5Init (
  IN MD5_CTX  *Md5Ctx
  )
/*++

Routine Description:

  GC_TODO: Add function description

Arguments:

  Md5Ctx  - GC_TODO: add argument description

Returns:

  EFI_SUCCESS - GC_TODO: Add description for return value

--*/
{
  EfiZeroMem (Md5Ctx, sizeof (*Md5Ctx));

  //
  // Set magic initialization constants.
  //
  Md5Ctx->States[0] = 0x67452301;
  Md5Ctx->States[1] = 0xefcdab89;
  Md5Ctx->States[2] = 0x98badcfe;
  Md5Ctx->States[3] = 0x10325476;  

  return EFI_SUCCESS;
}
Пример #3
0
VOID
UpdateOrderPage (
  IN UINT16                           UpdatePageId,
  IN BM_MENU_OPTION                   *OptionMenu,
  IN BMM_CALLBACK_DATA                *CallbackData
  )
{
  BM_MENU_ENTRY *NewMenuEntry;
  UINT16        Index;
  IFR_OPTION    *IfrOptionList;

  CallbackData->BmmAskSaveOrNot = TRUE;

  UpdatePageStart (CallbackData);

  CreateMenuStringToken (CallbackData, CallbackData->BmmHiiHandle, OptionMenu);

  EfiZeroMem (CallbackData->BmmFakeNvData.OptionOrder, 100);

  IfrOptionList = EfiAllocateZeroPool (sizeof (IFR_OPTION) * OptionMenu->MenuNumber);
  if (NULL == IfrOptionList) {
    return ;
  }

  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
    NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
    IfrOptionList[Index].StringToken = NewMenuEntry->DisplayStringToken;
    IfrOptionList[Index].Value.u8 = (UINT8) (NewMenuEntry->OptionNumber + 1);
    IfrOptionList[Index].Flags = 0;
    CallbackData->BmmFakeNvData.OptionOrder[Index] = IfrOptionList[Index].Value.u8;
  }

  if (OptionMenu->MenuNumber > 0) {
    CreateOrderedListOpCode (
      OPTION_ORDER_QUESTION_ID,
      VARSTORE_ID_BOOT_MAINT,
      OPTION_ORDER_VAR_OFFSET,
      STRING_TOKEN (STR_CHANGE_ORDER),
      STRING_TOKEN (STR_CHANGE_ORDER),
      0,
      0,
      EFI_IFR_NUMERIC_SIZE_1,
      100,
      IfrOptionList,
      OptionMenu->MenuNumber,
      &gUpdateData
      );
  }

  SafeFreePool (IfrOptionList);

  UpdatePageEnd (CallbackData);

  EfiCopyMem (
    CallbackData->BmmOldFakeNVData.OptionOrder,
    CallbackData->BmmFakeNvData.OptionOrder,
    100
    );
}
Пример #4
0
Файл: Fvb.c Проект: Kohrara/edk
EFI_STATUS
EfiFvbInitialize (
  VOID
  )
/*++

Routine Description:
  Initialize globals and register Fvb Protocol notification function.

Arguments:
  None 

Returns: 
  EFI_SUCCESS - Fvb is successfully initialized
  others                - Fail to initialize

--*/
{
  UINTN Status;
  mFvbCount = 0;

  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,
                  (VOID *) &mFvbEntry
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  EfiZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);

  mFvbEvent = RtEfiLibCreateProtocolNotifyEvent (
    &gEfiFirmwareVolumeBlockProtocolGuid,
    EFI_TPL_CALLBACK,
    FvbNotificationFunction,
    NULL,
    &mFvbRegistration
    );

  //
  // Register SetVirtualAddressMap () notify function
  //
  //  Status = gBS->CreateEvent (
  //                EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
  //                EFI_TPL_NOTIFY,
  //                EfiRuntimeLibFvbVirtualNotifyEvent,
  //                NULL,
  //                &mEfiFvbVirtualNotifyEvent
  //                );
  //  ASSERT_EFI_ERROR (Status);
  //
  gEfiFvbInitialized = TRUE;

  return EFI_SUCCESS;
}
Пример #5
0
VOID
EFIAPI
InvokeAmdInitMid (
    IN EFI_EVENT        Event,
    IN VOID             *Context
)
/*++

Routine Description:

  Installs the AmdInitMid This function gets called
  each time the EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled

Arguments & Return Values: Standard event handling function prototype

--*/
{
    AMD_INTERFACE_PARAMS        AmdInterfaceParams;
    AGESA_STATUS                AgesaStatus;
    AMD_DXE_INIT_MID_PROTOCOL   AmdInitMidProtocol;
    EFI_HANDLE                  Handle;
    STATIC BOOLEAN              InitMidInvoked = FALSE;

    //
    // Prepare for AmdInitMid
    //
    if (!InitMidInvoked) {
        EfiZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS));
        AmdInterfaceParams.StdHeader.ImageBasePtr = 0;
        AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM;
        AmdInterfaceParams.AllocationMethod = PostMemDram;
        AmdInterfaceParams.AgesaFunctionName = AMD_INIT_MID;
        AgesaStatus = AmdCreateStruct (&AmdInterfaceParams);

        ((AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr)->StdHeader = AmdInterfaceParams.StdHeader;

        OemCustomizeInitMid (gBS, (AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr);

        AgesaStatus = AmdInitMid ((AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr);

        OemHookAfterInitMid (gBS, (AMD_MID_PARAMS *)AmdInterfaceParams.NewStructPtr);

        if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) {
            return;
        }
        AmdInitMidProtocol.Revision = AGESA_DXE_INIT_MID_REV;
        Handle = NULL;
        gBS->InstallProtocolInterface (
            &Handle,
            &gAmdDxeInitMidProtocolGuid,
            EFI_NATIVE_INTERFACE,
            &AmdInitMidProtocol
        );
    }
    InitMidInvoked = TRUE;
}
Пример #6
0
EFI_STATUS
CreateOneOfOpCode (
  IN     EFI_QUESTION_ID      QuestionId,
  IN     EFI_VARSTORE_ID      VarStoreId,
  IN     UINT16               VarOffset,
  IN     EFI_STRING_ID        Prompt,
  IN     EFI_STRING_ID        Help,
  IN     UINT8                QuestionFlags,
  IN     UINT8                OneOfFlags,
  IN     IFR_OPTION           *OptionsList,
  IN     UINTN                OptionCount,
  IN OUT EFI_HII_UPDATE_DATA  *Data
  )
{
  UINTN                       Length;
  EFI_IFR_ONE_OF              OneOf;
  UINT8                       *LocalBuffer;

  ASSERT (Data != NULL && Data->Data != NULL);

  if (!IsValidNumricFlags (OneOfFlags) ||
      !IsValidQuestionFlags (QuestionFlags) ||
      ((OptionCount != 0) && (OptionsList == NULL))) {
    return EFI_INVALID_PARAMETER;
  }

  Length = sizeof (EFI_IFR_ONE_OF) + OptionCount * sizeof (EFI_IFR_ONE_OF_OPTION) + sizeof (EFI_IFR_END);
  if (Data->Offset + Length > Data->BufferSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  OneOf.Header.OpCode                   = EFI_IFR_ONE_OF_OP;
  OneOf.Header.Length                   = (UINT8) sizeof (EFI_IFR_ONE_OF);
  OneOf.Header.Scope                    = 1;
  OneOf.Question.Header.Prompt          = Prompt;
  OneOf.Question.Header.Help            = Help;
  OneOf.Question.QuestionId             = QuestionId;
  OneOf.Question.VarStoreId             = VarStoreId;
  OneOf.Question.VarStoreInfo.VarOffset = VarOffset;
  OneOf.Question.Flags                  = QuestionFlags;
  OneOf.Flags                           = OneOfFlags;
  EfiZeroMem ((VOID *) &OneOf.data, sizeof (MINMAXSTEP_DATA));

  LocalBuffer = (UINT8 *) Data->Data + Data->Offset;
  EfiCopyMem (LocalBuffer, &OneOf, sizeof (EFI_IFR_ONE_OF));
  Data->Offset += sizeof (EFI_IFR_ONE_OF);

  CreateOneOfOptionOpCode (OptionCount, OptionsList, (UINT8)(OneOfFlags & EFI_IFR_NUMERIC_SIZE), Data);

  CreateEndOpCode (Data);

  return EFI_SUCCESS;
}
VOID
DgpuSpecialPostForHcfiGpu (
  IN        AMD_CPM_DISPLAY_FEATURE_PROTOCOL  *CpmDisplayFeatureProtocolPtr,
  IN        VOID                              *VBiosImage,
  IN        UINTN                             VBiosImageSize
  )
{
#ifndef AMD_CPM_EDKII
  EFI_STATUS                                  Status;
  EFI_LEGACY_BIOS_PROTOCOL                    *LegacyBios;
  EFI_IA32_REGISTER_SET                       Regs;
  UINT32                                      TempDBuf;
  UINT8                                       *DSegBuffer;
  UINT16                                      Patch;
  CPM_DISPLAY_FEATURE_PRIVATE                 *DisplayFeatureDataPtr;
  UINT8                                       *SaveBufferPtr;
  EFI_LEGACY_REGION_PROTOCOL                  *LegacyRegion;

  DisplayFeatureDataPtr = &CpmDisplayFeatureProtocolPtr->DisplayFeatureData;

  //Step 00. Allocate memory to save original data
  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  0x10000,
                  (VOID**)&SaveBufferPtr
                  );
  if (!EFI_ERROR (Status)) {

    //Locate legacy region protocol
    Status = gBS->LocateProtocol (&gEfiLegacyRegionProtocolGuid, NULL, (VOID**)&LegacyRegion);
    if (!EFI_ERROR (Status)) {

      //Step 01. dGPUVBiosSpecialPost
      Status          = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID**)&LegacyBios);
      if (!EFI_ERROR (Status)) {

        LegacyRegion->UnLock (LegacyRegion, 0xD0000, 0x10000, NULL);

        TempDBuf        = 0x000D0000;
        DSegBuffer      = (UINT8 *) (UINTN)TempDBuf;

        CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (SaveBufferPtr, DSegBuffer, 0x10000);
        CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (DSegBuffer, VBiosImage, VBiosImageSize);

        Patch           = *((UINT16 *) (UINTN) (TempDBuf + 0x40));
        EfiZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

        Regs.X.AX       = DisplayFeatureDataPtr->GfxDevicePfa[0].Raw;
        Status          = LegacyBios->FarCall86 (
                                        LegacyBios,
                                        0xD000,
                                        Patch,
                                        &Regs,
                                        NULL,
                                        0
                                        );
        ASSERT_EFI_ERROR (Status);

        //Step 02. CopyVBiosFromD000
        CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (VBiosImage, DSegBuffer, VBiosImageSize);
        CpmDisplayFeatureProtocolPtr->TableProtocolPtr->CommonFunction.CopyMem (DSegBuffer, SaveBufferPtr, 0x10000);

         // lock the D000:0000 after we restore it
        LegacyRegion->Lock (LegacyRegion, 0xD0000, 0x10000, NULL);
      }
    }
  }
  Status = gBS->FreePool (SaveBufferPtr);
#endif

  return;
}
Пример #8
0
STATIC
EFI_STATUS
EFIAPI
WinNtSerialIoDriverBindingStart (
    IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
    IN  EFI_HANDLE                    Handle,
    IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
)
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Handle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
    EFI_STATUS                          Status;
    EFI_WIN_NT_IO_PROTOCOL              *WinNtIo;
    WIN_NT_SERIAL_IO_PRIVATE_DATA       *Private;
    HANDLE                              NtHandle;
    UART_DEVICE_PATH                    Node;
    EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
    EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
    UINTN                               EntryCount;
    UINTN                               Index;
    EFI_SERIAL_IO_PROTOCOL              *SerialIo;

    Private   = NULL;
    NtHandle  = INVALID_HANDLE_VALUE;

    //
    // Grab the protocols we need
    //
    Status = gBS->OpenProtocol (
                 Handle,
                 &gEfiDevicePathProtocolGuid,
                 &ParentDevicePath,
                 This->DriverBindingHandle,
                 Handle,
                 EFI_OPEN_PROTOCOL_BY_DRIVER
             );
    if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
        return Status;
    }

    //
    // Grab the IO abstraction we need to get any work done
    //
    Status = gBS->OpenProtocol (
                 Handle,
                 &gEfiWinNtIoProtocolGuid,
                 &WinNtIo,
                 This->DriverBindingHandle,
                 Handle,
                 EFI_OPEN_PROTOCOL_BY_DRIVER
             );
    if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
        gBS->CloseProtocol (
            Handle,
            &gEfiDevicePathProtocolGuid,
            This->DriverBindingHandle,
            Handle
        );
        return Status;
    }

    if (Status == EFI_ALREADY_STARTED) {

        if (RemainingDevicePath == NULL) {
            return EFI_SUCCESS;
        }

        //
        // Make sure a child handle does not already exist.  This driver can only
        // produce one child per serial port.
        //
        Status = gBS->OpenProtocolInformation (
                     Handle,
                     &gEfiWinNtIoProtocolGuid,
                     &OpenInfoBuffer,
                     &EntryCount
                 );
        if (EFI_ERROR (Status)) {
            return Status;
        }

        Status = EFI_ALREADY_STARTED;
        for (Index = 0; Index < EntryCount; Index++) {
            if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
                Status = gBS->OpenProtocol (
                             OpenInfoBuffer[Index].ControllerHandle,
                             &gEfiSerialIoProtocolGuid,
                             &SerialIo,
                             This->DriverBindingHandle,
                             Handle,
                             EFI_OPEN_PROTOCOL_GET_PROTOCOL
                         );
                if (!EFI_ERROR (Status)) {
                    EfiCopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH));
                    Status = SerialIo->SetAttributes (
                                 SerialIo,
                                 Node.BaudRate,
                                 SerialIo->Mode->ReceiveFifoDepth,
                                 SerialIo->Mode->Timeout,
                                 Node.Parity,
                                 Node.DataBits,
                                 Node.StopBits
                             );
                }
                break;
            }
        }

        gBS->FreePool (OpenInfoBuffer);
        return Status;
    }

    //
    // Check to see if we can access the hardware device. If it's Open in NT we
    // will not get access.
    //
    NtHandle = WinNtIo->WinNtThunk->CreateFile (
                   WinNtIo->EnvString,
                   GENERIC_READ | GENERIC_WRITE,
                   0,
                   NULL,
                   OPEN_EXISTING,
                   0,
                   NULL
               );
    if (NtHandle == INVALID_HANDLE_VALUE) {
        Status = EFI_DEVICE_ERROR;
        goto Error;
    }

    //
    // Construct Private data
    //
    Status = gBS->AllocatePool (
                 EfiBootServicesData,
                 sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA),
                 &Private
             );
    if (EFI_ERROR (Status)) {
        goto Error;
    }

    //
    // This signature must be valid before any member function is called
    //
    Private->Signature              = WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE;
    Private->NtHandle               = NtHandle;
    Private->ControllerHandle       = Handle;
    Private->Handle                 = NULL;
    Private->WinNtThunk             = WinNtIo->WinNtThunk;
    Private->ParentDevicePath       = ParentDevicePath;
    Private->ControllerNameTable    = NULL;

    Private->SoftwareLoopbackEnable = FALSE;
    Private->HardwareLoopbackEnable = FALSE;
    Private->HardwareFlowControl    = FALSE;
    Private->Fifo.First             = 0;
    Private->Fifo.Last              = 0;
    Private->Fifo.Surplus           = SERIAL_MAX_BUFFER_SIZE;

    EfiLibAddUnicodeString (
        LANGUAGE_CODE_ENGLISH,
        gWinNtSerialIoComponentName.SupportedLanguages,
        &Private->ControllerNameTable,
        WinNtIo->EnvString
    );

    Private->SerialIo.Revision      = SERIAL_IO_INTERFACE_REVISION;
    Private->SerialIo.Reset         = WinNtSerialIoReset;
    Private->SerialIo.SetAttributes = WinNtSerialIoSetAttributes;
    Private->SerialIo.SetControl    = WinNtSerialIoSetControl;
    Private->SerialIo.GetControl    = WinNtSerialIoGetControl;
    Private->SerialIo.Write         = WinNtSerialIoWrite;
    Private->SerialIo.Read          = WinNtSerialIoRead;
    Private->SerialIo.Mode          = &Private->SerialIoMode;

    if (RemainingDevicePath != NULL) {
        //
        // Match the configuration of the RemainingDevicePath. IsHandleSupported()
        // already checked to make sure the RemainingDevicePath contains settings
        // that we can support.
        //
        EfiCopyMem (&Private->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH));
    } else {
        //
        // Build the device path by appending the UART node to the ParentDevicePath
        // from the WinNtIo handle. The Uart setings are zero here, since
        // SetAttribute() will update them to match the default setings.
        //
        EfiZeroMem (&Private->UartDevicePath, sizeof (UART_DEVICE_PATH));
        Private->UartDevicePath.Header.Type     = MESSAGING_DEVICE_PATH;
        Private->UartDevicePath.Header.SubType  = MSG_UART_DP;
        SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));
    }

    //
    // Build the device path by appending the UART node to the ParentDevicePath
    // from the WinNtIo handle. The Uart setings are zero here, since
    // SetAttribute() will update them to match the current setings.
    //
    Private->DevicePath = EfiAppendDevicePathNode (
                              ParentDevicePath,
                              (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
                          );
    if (Private->DevicePath == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error;
    }

    //
    // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
    //
    Private->SerialIoMode.ControlMask       = SERIAL_CONTROL_MASK;
    Private->SerialIoMode.Timeout           = SERIAL_TIMEOUT_DEFAULT;
    Private->SerialIoMode.BaudRate          = Private->UartDevicePath.BaudRate;
    Private->SerialIoMode.ReceiveFifoDepth  = SERIAL_FIFO_DEFAULT;
    Private->SerialIoMode.DataBits          = Private->UartDevicePath.DataBits;
    Private->SerialIoMode.Parity            = Private->UartDevicePath.Parity;
    Private->SerialIoMode.StopBits          = Private->UartDevicePath.StopBits;

    //
    // Issue a reset to initialize the COM port
    //
    Status = Private->SerialIo.Reset (&Private->SerialIo);
    if (EFI_ERROR (Status)) {
        goto Error;
    }

    //
    // Create new child handle
    //
    Status = gBS->InstallMultipleProtocolInterfaces (
                 &Private->Handle,
                 &gEfiSerialIoProtocolGuid,
                 &Private->SerialIo,
                 &gEfiDevicePathProtocolGuid,
                 Private->DevicePath,
                 NULL
             );
    if (EFI_ERROR (Status)) {
        goto Error;
    }

    //
    // Open For Child Device
    //
    Status = gBS->OpenProtocol (
                 Handle,
                 &gEfiWinNtIoProtocolGuid,
                 &WinNtIo,
                 This->DriverBindingHandle,
                 Private->Handle,
                 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
             );
    if (EFI_ERROR (Status)) {
        goto Error;
    }

    return EFI_SUCCESS;

Error:
    //
    // Use the Stop() function to free all resources allocated in Start()
    //
    if (Private != NULL) {
        if (Private->Handle != NULL) {
            This->Stop (This, Handle, 1, &Private->Handle);
        } else {
            if (NtHandle != INVALID_HANDLE_VALUE) {
                Private->WinNtThunk->CloseHandle (NtHandle);
            }

            if (Private->DevicePath != NULL) {
                gBS->FreePool (Private->DevicePath);
            }

            EfiLibFreeUnicodeStringTable (Private->ControllerNameTable);

            gBS->FreePool (Private);
        }
    }

    This->Stop (This, Handle, 0, NULL);

    return Status;
}
Пример #9
0
STATIC
EFI_STATUS
EFIAPI
WinNtSerialIoSetAttributes (
    IN EFI_SERIAL_IO_PROTOCOL *This,
    IN UINT64                 BaudRate,
    IN UINT32                 ReceiveFifoDepth,
    IN UINT32                 Timeout,
    IN EFI_PARITY_TYPE        Parity,
    IN UINT8                  DataBits,
    IN EFI_STOP_BITS_TYPE     StopBits
)
/*++

Routine Description:

  This function is used to set the attributes.

Arguments:

  This              - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
  BaudRate          - The Baud rate of the serial device.
  ReceiveFifoDepth  - The request depth of fifo on receive side.
  Timeout           - the request timeout for a single charact.
  Parity            - The type of parity used in serial device.
  DataBits          - Number of deata bits used in serial device.
  StopBits          - Number of stop bits used in serial device.

Returns:
  Status code

  None

--*/
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_DEVICE_ERROR - add return value to function comment
// TODO:    EFI_DEVICE_ERROR - add return value to function comment
// TODO:    EFI_DEVICE_ERROR - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_DEVICE_ERROR - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
    EFI_STATUS                    Status;
    UINTN                         Index;
    WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;
    COMMTIMEOUTS                  PortTimeOuts;
    DWORD                         ConvertedTime;
    BOOL                          Result;
    EFI_DEVICE_PATH_PROTOCOL      *NewDevicePath;
    EFI_TPL                       Tpl;

    //
    // for BaudRate, currently we support
    // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,38400,57600,115200
    //

    UINT64 BaudRateCurrentSupport[] = {50, 75, 110, 134, 150, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200, 38400, 57600, 115200, SERIAL_PORT_MAX_BAUD_RATE+1};

    Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);

    //
    //  Some of our arguments have defaults if a null value is passed in, and
    //   we must set the default values if a null argument is passed in.
    //
    if (BaudRate == 0) {
        BaudRate = SERIAL_BAUD_DEFAULT;
    }

    if (ReceiveFifoDepth == 0) {
        ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;
    }

    if (Timeout == 0) {
        Timeout = SERIAL_TIMEOUT_DEFAULT;
    }

    if (Parity == DefaultParity) {
        Parity = NoParity;
    }

    if (DataBits == 0) {
        DataBits = SERIAL_DATABITS_DEFAULT;
    }

    if (StopBits == DefaultStopBits) {
        StopBits = OneStopBit;
    }

    //
    // Make sure all parameters are valid
    //
    if ((BaudRate > SERIAL_PORT_MAX_BAUD_RATE) || (BaudRate < SERIAL_PORT_MIN_BAUD_RATE)) {
        return EFI_INVALID_PARAMETER;
    }

    //
    //The lower baud rate supported by the serial device will be selected without exceeding the unsupported BaudRate parameter
    //

    for (Index = 1; Index < (sizeof (BaudRateCurrentSupport) / sizeof (BaudRateCurrentSupport[0])); Index++) {
        if (BaudRate < BaudRateCurrentSupport[Index]) {
            BaudRate = BaudRateCurrentSupport[Index-1];
            break;
        }
    }

    if ((ReceiveFifoDepth < 1) || (ReceiveFifoDepth > SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH)) {
        return EFI_INVALID_PARAMETER;
    }

    if ((Timeout < SERIAL_PORT_MIN_TIMEOUT) || (Timeout > SERIAL_PORT_MAX_TIMEOUT)) {
        return EFI_INVALID_PARAMETER;
    }

    if ((Parity < NoParity) || (Parity > SpaceParity)) {
        return EFI_INVALID_PARAMETER;
    }

    if ((StopBits < OneStopBit) || (StopBits > TwoStopBits)) {
        return EFI_INVALID_PARAMETER;
    }

    //
    // Now we only support DataBits=7,8.
    //
    if ((DataBits < 7) || (DataBits > 8)) {
        return EFI_INVALID_PARAMETER;
    }

    //
    // Now we only support DataBits=7,8.
    // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits.
    //
    if (StopBits == OneFiveStopBits) {
        return EFI_INVALID_PARAMETER;
    }

    //
    // See if the new attributes already match the current attributes
    //
    if (Private->UartDevicePath.BaudRate       == BaudRate         &&
            Private->UartDevicePath.DataBits       == DataBits         &&
            Private->UartDevicePath.Parity         == Parity           &&
            Private->UartDevicePath.StopBits       == StopBits         &&
            Private->SerialIoMode.ReceiveFifoDepth == ReceiveFifoDepth &&
            Private->SerialIoMode.Timeout          == Timeout             ) {
        return EFI_SUCCESS;
    }

    Tpl     = gBS->RaiseTPL (EFI_TPL_NOTIFY);

    //
    //  Get current values from NT
    //
    EfiZeroMem (&Private->NtDCB, sizeof (DCB));
    Private->NtDCB.DCBlength = sizeof (DCB);

    if (!Private->WinNtThunk->GetCommState (Private->NtHandle, &Private->NtDCB)) {
        Private->NtError = Private->WinNtThunk->GetLastError ();
        DEBUG ((EFI_D_ERROR, "SerialSetAttributes: GetCommState %d\n", Private->NtError));
        gBS->RestoreTPL (Tpl);
        return EFI_DEVICE_ERROR;
    }

    //
    // Map EFI com setting to NT
    //
    Private->NtDCB.BaudRate         = ConvertBaud2Nt (BaudRate);
    Private->NtDCB.ByteSize         = ConvertData2Nt (DataBits);
    Private->NtDCB.Parity           = ConvertParity2Nt (Parity);
    Private->NtDCB.StopBits         = ConvertStop2Nt (StopBits);

    Private->NtDCB.fBinary          = TRUE;
    Private->NtDCB.fParity          = Private->NtDCB.Parity == NOPARITY ? FALSE : TRUE;
    Private->NtDCB.fOutxCtsFlow     = FALSE;
    Private->NtDCB.fOutxDsrFlow     = FALSE;
    Private->NtDCB.fDtrControl      = DTR_CONTROL_ENABLE;
    Private->NtDCB.fDsrSensitivity  = FALSE;
    Private->NtDCB.fOutX            = FALSE;
    Private->NtDCB.fInX             = FALSE;
    Private->NtDCB.fRtsControl      = RTS_CONTROL_ENABLE;
    Private->NtDCB.fNull            = FALSE;

    //
    //  Set new values
    //
    Result = Private->WinNtThunk->SetCommState (Private->NtHandle, &Private->NtDCB);
    if (!Result) {
        Private->NtError = Private->WinNtThunk->GetLastError ();
        DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommState %d\n", Private->NtError));
        gBS->RestoreTPL (Tpl);
        return EFI_DEVICE_ERROR;
    }

    //
    //  Set com port read/write timeout values
    //
    ConvertedTime = ConvertTime2Nt (Timeout);
    PortTimeOuts.ReadIntervalTimeout = MAXDWORD;
    PortTimeOuts.ReadTotalTimeoutMultiplier = 0;
    PortTimeOuts.ReadTotalTimeoutConstant = ConvertedTime;
    PortTimeOuts.WriteTotalTimeoutMultiplier = ConvertedTime == 0 ? 1 : ConvertedTime;
    PortTimeOuts.WriteTotalTimeoutConstant = 0;

    if (!Private->WinNtThunk->SetCommTimeouts (Private->NtHandle, &PortTimeOuts)) {
        Private->NtError = Private->WinNtThunk->GetLastError ();
        DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommTimeouts %d\n", Private->NtError));
        gBS->RestoreTPL (Tpl);
        return EFI_DEVICE_ERROR;
    }

    //
    //  Update mode
    //
    Private->SerialIoMode.BaudRate          = BaudRate;
    Private->SerialIoMode.ReceiveFifoDepth  = ReceiveFifoDepth;
    Private->SerialIoMode.Timeout           = Timeout;
    Private->SerialIoMode.Parity            = Parity;
    Private->SerialIoMode.DataBits          = DataBits;
    Private->SerialIoMode.StopBits          = StopBits;

    //
    // See if Device Path Node has actually changed
    //
    if (Private->UartDevicePath.BaudRate     == BaudRate &&
            Private->UartDevicePath.DataBits     == DataBits &&
            Private->UartDevicePath.Parity       == Parity   &&
            Private->UartDevicePath.StopBits     == StopBits    ) {
        gBS->RestoreTPL(Tpl);
        return EFI_SUCCESS;
    }

    //
    // Update the device path
    //
    Private->UartDevicePath.BaudRate  = BaudRate;
    Private->UartDevicePath.DataBits  = DataBits;
    Private->UartDevicePath.Parity    = (UINT8) Parity;
    Private->UartDevicePath.StopBits  = (UINT8) StopBits;

    NewDevicePath = EfiAppendDevicePathNode (
                        Private->ParentDevicePath,
                        (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
                    );
    if (NewDevicePath == NULL) {
        gBS->RestoreTPL (Tpl);
        return EFI_DEVICE_ERROR;
    }

    if (Private->Handle != NULL) {
        Status = gBS->ReinstallProtocolInterface (
                     Private->Handle,
                     &gEfiDevicePathProtocolGuid,
                     Private->DevicePath,
                     NewDevicePath
                 );
        if (EFI_ERROR (Status)) {
            gBS->RestoreTPL (Tpl);
            return Status;
        }
    }

    if (Private->DevicePath != NULL) {
        gBS->FreePool (Private->DevicePath);
    }

    Private->DevicePath = NewDevicePath;

    gBS->RestoreTPL (Tpl);

    return EFI_SUCCESS;
}
Пример #10
0
EFI_STATUS
EFIAPI
TslOpen (
  EFI_TSL_INIT_INTERFACE          *This,
  IN OUT EFI_HANDLE               *LibHandle,
  OUT VOID                        **PrivateLibInterface
  )
/*++

Routine Description:

  One interface function of the TslInit to open the support library.

Arguments:

  This                - the protocol instance structure.
  LibHandle           - a library handle to bind the TestRecoveryLibrary
                        protocol.
  PrivateLibInterface - private interface of TestRecoveryLibrary protocol.

Returns:

  EFI_SUCCESS           - open the TestRecoveryLibrary successfully.
  EFI_INVALID_PARAMETER - invalid parameter, LibHandle is NULL.
  EFI_ALREADY_STARTED   - the TestRecoveryLibrary has been bind on the LibHandle
                          before.

--*/
{
  EFI_STATUS                      Status;
  TEST_RECOVERY_PRIVATE_DATA      *Private;
  TSL_INIT_PRIVATE_DATA           *TslPrivate;

  //
  // Check parameter
  //
  if (LibHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  TslPrivate = TSL_INIT_PRIVATE_DATA_FROM_THIS (This);
  //
  // Open the TestRecoveryLibrary protocol to perform the supported test.
  //
  if (*LibHandle != NULL) {
    Status = gBS->OpenProtocol (
                    *LibHandle,
                    &gEfiTestRecoveryLibraryGuid,
                    NULL,
                    TslPrivate->ImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      return EFI_ALREADY_STARTED;
    }
  }

  //
  // Initialize the TestRecoveryLibrary private data
  //
  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof (TEST_RECOVERY_PRIVATE_DATA),
                  (VOID **)&Private
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  EfiZeroMem (Private, sizeof(TEST_RECOVERY_PRIVATE_DATA));
  Private->Signature = TEST_RECOVERY_PRIVATE_DATA_SIGNATURE;
  Private->TestRecovery.LibraryRevision     = 0x10000;
  Private->TestRecovery.Name                = gTrlName;
  Private->TestRecovery.Description         = gTrlDescription;
  Private->TestRecovery.ReadResetRecord     = TrlReadResetRecord;
  Private->TestRecovery.WriteResetRecord    = TrlWriteResetRecord;
  Private->PrivateInterface.SetConfig       = TrlSetConfig;

  if (PrivateLibInterface != NULL) {
    *PrivateLibInterface = (VOID *)&(Private->PrivateInterface);
  }

  //
  // Install TestRecoveryLibrary protocol
  //
  Status = gBS->InstallProtocolInterface (
                  LibHandle,
                  &gEfiTestRecoveryLibraryGuid,
                  EFI_NATIVE_INTERFACE,
                  &(Private->TestRecovery)
                  );

  return Status;
}
Пример #11
0
EFI_STATUS
EFIAPI
MiscSubclassDriverEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++
Description:

  Standard EFI driver point.  This driver parses the mMiscSubclassDataTable
  structure and reports any generated data to the DataHub.

Arguments:

  ImageHandle
    Handle for the image of this driver

  SystemTable
    Pointer to the EFI System Table

Returns:

  EFI_SUCCESS
    The data was successfully reported to the Data Hub.

--*/
{
  EFI_MISC_SUBCLASS_DRIVER_DATA RecordData;
  EFI_DATA_HUB_PROTOCOL         *DataHub;
#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
  EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
  EFI_HII_PACKAGE_LIST_HEADER   *PackageList;
#else
  EFI_HII_PROTOCOL              *Hii;
  EFI_HII_PACKAGES              *PackageList;
#endif
  EFI_HII_HANDLE                HiiHandle;
  EFI_STATUS                    EfiStatus;
  UINTN                         Index;
  BOOLEAN                       LogRecordData;
  EFI_EVENT                     Event;
  VOID                          *Registration;

  //
  //
  //
  EfiInitializeDriverLib (ImageHandle, SystemTable);

  //
  // Initialize constant portion of subclass header.
  //
  RecordData.Header.Version     = EFI_MISC_SUBCLASS_VERSION;
  RecordData.Header.HeaderSize  = sizeof (EFI_SUBCLASS_TYPE1_HEADER);
  RecordData.Header.Instance    = 1;
  RecordData.Header.SubInstance = 1;

  //
  // Locate data hub protocol.
  //
  EfiStatus = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);

  if (EFI_ERROR (EfiStatus)) {
    DEBUG ((EFI_D_ERROR, "Could not locate DataHub protocol.  %r\n", EfiStatus));
    return EfiStatus;
  } else if (DataHub == NULL) {
    DEBUG ((EFI_D_ERROR, "LocateProtocol(DataHub) returned NULL pointer!\n"));
    return EFI_DEVICE_ERROR;
  }
  //
  // Locate hii protocol.
  //
#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
  EfiStatus = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase);

  if (EFI_ERROR (EfiStatus)) {
    DEBUG ((EFI_D_ERROR, "Could not locate HiiDatabase protocol.  %r\n", EfiStatus));
    return EfiStatus;
  } else if (HiiDatabase == NULL) {
    DEBUG ((EFI_D_ERROR, "LocateProtocol(HiiDatabase) returned NULL pointer!\n"));
    return EFI_DEVICE_ERROR;
  }
  //
  // Add our default strings to the HII database. They will be modified later.
  //
  PackageList = PreparePackageList (1, &gEfiMiscSubClassGuid, MiscSubclassStrings);
  EfiStatus = HiiDatabase->NewPackageList (HiiDatabase, PackageList, ImageHandle, &HiiHandle);
#else
  EfiStatus = gBS->LocateProtocol (&gEfiHiiProtocolGuid, NULL, &Hii);

  if (EFI_ERROR (EfiStatus)) {
    DEBUG ((EFI_D_ERROR, "Could not locate Hii protocol.  %r\n", EfiStatus));
    return EfiStatus;
  } else if (Hii == NULL) {
    DEBUG ((EFI_D_ERROR, "LocateProtocol(Hii) returned NULL pointer!\n"));
    return EFI_DEVICE_ERROR;
  }
  //
  // Add our default strings to the HII database. They will be modified later.
  //
  PackageList = PreparePackages (1, &gEfiMiscSubClassGuid, MiscSubclassStrings);
  EfiStatus   = Hii->NewPack (Hii, PackageList, &HiiHandle);
#endif
  gBS->FreePool (PackageList);

  if (EFI_ERROR (EfiStatus)) {
    DEBUG ((EFI_D_ERROR, "Could not log default strings to Hii.  %r\n", EfiStatus));
    return EfiStatus;
  }
  //
  //
  //
  for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {
    //
    // Stupidity check!  Do nothing if RecordLen is zero.
    // %%TBD - Should this be an error or a mechanism for ignoring
    // records in the Data Table?
    //
    if (mMiscSubclassDataTable[Index].RecordLen == 0) {
      DEBUG (
        (EFI_D_ERROR,
        "mMiscSubclassDataTable[%d].RecordLen == 0\n",
        Index)
        );

      continue;
    }
    //
    // Initialize per-record portion of subclass header and
    // copy static data into data portion of subclass record.
    //
    RecordData.Header.RecordType = mMiscSubclassDataTable[Index].RecordType;

    if (mMiscSubclassDataTable[Index].RecordData == NULL) {
      EfiZeroMem (
        &RecordData.Record,
        mMiscSubclassDataTable[Index].RecordLen
        );
    } else {
      EfiCopyMem (
        &RecordData.Record,
        mMiscSubclassDataTable[Index].RecordData,
        mMiscSubclassDataTable[Index].RecordLen
        );
    }
    //
    // If the entry does not have a function pointer, just log the data.
    //
    if (mMiscSubclassDataTable[Index].Function == NULL) {
      //
      // Log RecordData to Data Hub.
      //
      EfiStatus = DataHub->LogData (
                            DataHub,
                            &gEfiMiscSubClassGuid,
                            &gEfiMiscSubClassGuid,
                            EFI_DATA_RECORD_CLASS_DATA,
                            &RecordData,
                            sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen
                            );

      if (EFI_ERROR (EfiStatus)) {
        DEBUG (
          (EFI_D_ERROR,
          "LogData(%d bytes) == %r\n",
          sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,
          EfiStatus)
          );
      }

      continue;
    }
    //
    // The entry has a valid function pointer.
    // Keep calling the function and logging data until there
    // is no more data to log.
    //
    for (;;) {
      //
      //
      //
      EfiStatus = (*mMiscSubclassDataTable[Index].Function)
        (
          mMiscSubclassDataTable[Index].RecordType, &mMiscSubclassDataTable[Index].RecordLen, &RecordData.Record, &
            LogRecordData
        );

      //
      //
      //
      if (EFI_ERROR (EfiStatus)) {
        break;
      }

      if (!LogRecordData) {
        break;
      }
      //
      //
      //
      EfiStatus = DataHub->LogData (
                            DataHub,
                            &gEfiMiscSubClassGuid,
                            &gEfiMiscSubClassGuid,
                            EFI_DATA_RECORD_CLASS_DATA,
                            &RecordData,
                            sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen
                            );

      if (EFI_ERROR (EfiStatus)) {
        DEBUG (
          (EFI_D_ERROR,
          "LogData(%d bytes) == %r\n",
          sizeof (EFI_SUBCLASS_TYPE1_HEADER) + mMiscSubclassDataTable[Index].RecordLen,
          EfiStatus)
          );
      }
    }
  }
  //
  // Install notify function to fetch memory data through WinNtIo protocol and store to data hub.
  //
  EfiStatus = gBS->CreateEvent (
                    EFI_EVENT_NOTIFY_SIGNAL,
                    EFI_TPL_CALLBACK,
                    WinNtIoProtocolNotifyFunction,
                    ImageHandle,
                    &Event
                    );
  ASSERT (!EFI_ERROR (EfiStatus));

  EfiStatus = gBS->RegisterProtocolNotify (
                    &gEfiWinNtIoProtocolGuid,
                    Event,
                    &Registration
                    );
  ASSERT (!EFI_ERROR (EfiStatus));

  return EFI_SUCCESS;
}
Пример #12
0
EFI_STATUS
AddOpCode (
  IN      VOID                *FormBuffer,
  IN OUT  VOID                *OpCodeData
  )
/*++

Routine Description:

  Add op-code data to the FormBuffer
  
Arguments:
  
  FormBuffer      - Form buffer to be inserted to
  
  OpCodeData      - Op-code data to be inserted
  
Returns: 

  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate
  
  EFI_SUCCESS             - Op-code data successfully inserted

--*/
{
  EFI_HII_PACK_HEADER *NewBuffer;
  UINT8               *Source;
  UINT8               *Destination;

  //
  // Pre-allocate a buffer sufficient for us to work on.
  // We will use it as a destination scratch pad to build data on
  // and when complete shift the data back to the original buffer
  //
  NewBuffer = EfiLibAllocateZeroPool (DEFAULT_FORM_BUFFER_SIZE);
  if (NewBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Source      = (UINT8 *) FormBuffer;
  Destination = (UINT8 *) NewBuffer;

  //
  // Copy the IFR Package header to the new buffer
  //
  EfiCopyMem (Destination, Source, sizeof (EFI_HII_PACK_HEADER));

  //
  // Advance Source and Destination to next op-code
  //
  Source      = Source + sizeof (EFI_HII_PACK_HEADER);
  Destination = Destination + sizeof (EFI_HII_PACK_HEADER);

  //
  // Copy data to the new buffer until we run into the end_form
  //
  for (; ((EFI_IFR_OP_HEADER *) Source)->OpCode != EFI_IFR_END_FORM_OP;) {
    //
    // If the this opcode is an end_form_set we better be creating and endform
    // Nonetheless, we will add data before the end_form_set.  This also provides
    // for interesting behavior in the code we will run, but has no bad side-effects
    // since we will possibly do a 0 byte copy in this particular end-case.
    //
    if (((EFI_IFR_OP_HEADER *) Source)->OpCode == EFI_IFR_END_FORM_SET_OP) {
      break;
    }

    //
    // Copy data to new buffer
    //
    EfiCopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);

    //
    // Adjust Source/Destination to next op-code location
    //
    Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;
    Source      = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;
  }

  //
  // Prior to the end_form is where we insert the new op-code data
  //
  EfiCopyMem (Destination, OpCodeData, ((EFI_IFR_OP_HEADER *) OpCodeData)->Length);
  Destination       = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;

  NewBuffer->Length = (UINT32) (NewBuffer->Length + (UINT32) (((EFI_IFR_OP_HEADER *) OpCodeData)->Length));

  //
  // Copy end-form data to new buffer
  //
  EfiCopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);

  //
  // Adjust Source/Destination to next op-code location
  //
  Destination = Destination + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;
  Source      = Source + (UINTN) ((EFI_IFR_OP_HEADER *) Source)->Length;

  //
  // Copy end-formset data to new buffer
  //
  EfiCopyMem (Destination, Source, ((EFI_IFR_OP_HEADER *) Source)->Length);

  //
  // Zero out the original buffer and copy the updated data in the new buffer to the old buffer
  //
  EfiZeroMem (FormBuffer, DEFAULT_FORM_BUFFER_SIZE);
  EfiCopyMem (FormBuffer, NewBuffer, DEFAULT_FORM_BUFFER_SIZE);

  //
  // Free the newly created buffer since we don't need it anymore
  //
  gBS->FreePool (NewBuffer);
  return EFI_SUCCESS;
}
Пример #13
0
EFI_DEBUG_STATUS
DebuggerInstructionBranch (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
/*++

Routine Description:

  DebuggerCommand - InstructionBranch
  
Arguments:

  CommandArg      - The argument for this command
  DebuggerPrivate - EBC Debugger private data structure
  InterruptType   - Interrupt type.
  SystemContext   - EBC system context.

Returns:

  EFI_DEBUG_CONTINUE - formal return value
  
--*/
{
  UINTN  Index;

  //
  // Check argument
  //
  if (CommandArg != NULL) {
    if (EfiStriCmp (CommandArg, L"c") == 0) {
      //
      // Clear Trace
      //
      DebuggerPrivate->TraceEntryCount = 0;
      EfiZeroMem (DebuggerPrivate->TraceEntry, sizeof(DebuggerPrivate->TraceEntry));
      EDBPrint (L"Instruction Trace is cleared\n");
    } else {
      EDBPrint (L"Trace argument Invalid\n");
    }
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Check Trace Entry Count
  //
  if (DebuggerPrivate->TraceEntryCount == 0) {
    EDBPrint (L"No Instruction Trace\n");
    return EFI_DEBUG_CONTINUE;
  } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
    EDBPrint (L"Instruction Trace Crash, re-initialize!\n");
    DebuggerPrivate->TraceEntryCount = 0;
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Go through each Trace entry and print
  //
  EDBPrint (L"Instruction Trace (->Latest):\n");
  EDBPrint (L"    Source Addr        Destination Addr   Type\n");
  EDBPrint (L"  ================== ================== ========\n");
//EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000  (CALLEX)\n");
  for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) {
    EDBPrint (
      L"  0x%016lx 0x%016lx  %s\n",
      DebuggerPrivate->TraceEntry[Index].SourceAddress,
      DebuggerPrivate->TraceEntry[Index].DestAddress,
      EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type)
      );
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}
Пример #14
0
/**
 *---------------------------------------------------------------------------------------
 *
 *  AgesaDxeCallout
 *
 *  Description:
 *     AGESA DXE Call out dispatcher
 *
 *  Parameters:
 *    @param[in]         Param1
 *    @param[in]         Param2
 *    @param[in, out]    *ConfigPtr
 *
 *    @retval         AGESA_STATUS
 *
 *---------------------------------------------------------------------------------------
 **/
EFI_STATUS
AgesaDxeCallout (
    IN       UINT32       Param1,
    IN       UINTN        Param2,
    IN OUT   VOID         *ConfigPtr
)
{
    EFI_STATUS                Status;
    AGESA_STATUS              AgesaStatus;
    AGESA_BUFFER_PARAMS       *BufferConfigPtr;
    AGESA_DXE_BUFFER_MANAGER  *AgesaLocateBufferPtr;
    AGESA_DXE_BUFFER_MANAGER  *PreviousBufferPtr;

    Status = EFI_UNSUPPORTED;
    AgesaStatus = AGESA_UNSUPPORTED;
    BufferConfigPtr = (AGESA_BUFFER_PARAMS *) ConfigPtr;
    AgesaLocateBufferPtr = NULL;
    PreviousBufferPtr = NULL;

    switch (Param1) {
    case AGESA_ALLOCATE_BUFFER:
        if (Param2 == HEAP_CALLOUT_BOOTTIME) {
            Status = gBS->AllocatePool (
                         EfiBootServicesData,
                         BufferConfigPtr->BufferLength,
                         &BufferConfigPtr->BufferPointer
                     );
        } else if (Param2 == HEAP_CALLOUT_RUNTIME) {
            Status = gBS->AllocatePool (
                         EfiACPIMemoryNVS,
                         BufferConfigPtr->BufferLength,
                         &BufferConfigPtr->BufferPointer
                     );
        }
        if (EFI_ERROR (Status)) {
            return Status;
        }
        //
        // Initialize the memory
        //
        EfiZeroMem (BufferConfigPtr->BufferPointer, BufferConfigPtr->BufferLength);

        //
        // Create the first buffer for AGESA_ALLOCATE_BUFFER Manager
        //
        AgesaBufferManager->BufferLength = BufferConfigPtr->BufferLength;
        AgesaBufferManager->BufferHandle = BufferConfigPtr->BufferHandle;
        AgesaBufferManager->BufferPtr = BufferConfigPtr->BufferPointer;

        Status = gBS->AllocatePool (
                     EfiBootServicesData,
                     sizeof (AGESA_DXE_BUFFER_MANAGER),
                     &AgesaBufferManager->NextAgesaBufferManagerPtr
                 );

        ASSERT_EFI_ERROR (Status);

        if (EFI_ERROR (Status)) {
            return Status;
        }
        EfiZeroMem (AgesaBufferManager->NextAgesaBufferManagerPtr, sizeof (AGESA_DXE_BUFFER_MANAGER));
        AgesaBufferManager = AgesaBufferManager->NextAgesaBufferManagerPtr;
        AgesaBufferManager->NextAgesaBufferManagerPtr = NULL;
        break;

    case AGESA_DEALLOCATE_BUFFER:
        AgesaLocateBufferPtr = mAgesaDxePrivate->BufferManagerPtr;
        while (AgesaLocateBufferPtr->NextAgesaBufferManagerPtr != NULL) {
            if (AgesaLocateBufferPtr->BufferHandle == BufferConfigPtr->BufferHandle) {
                //
                // Before deleting the current buffer from the link, setup the link from
                // previous to next buffer pointer to maintain the continuity of the link
                // list.
                //
                PreviousBufferPtr->NextAgesaBufferManagerPtr = AgesaLocateBufferPtr->NextAgesaBufferManagerPtr;
                Status = gBS->FreePool (AgesaLocateBufferPtr);
                break;
            }
            PreviousBufferPtr = AgesaLocateBufferPtr;
            AgesaLocateBufferPtr = AgesaLocateBufferPtr->NextAgesaBufferManagerPtr;
        }
        break;

    case AGESA_LOCATE_BUFFER:
        AgesaLocateBufferPtr = mAgesaDxePrivate->BufferManagerPtr;
        while (AgesaLocateBufferPtr->NextAgesaBufferManagerPtr != NULL) {
            if (AgesaLocateBufferPtr->BufferHandle == BufferConfigPtr->BufferHandle) {
                BufferConfigPtr->BufferPointer = AgesaLocateBufferPtr->BufferPtr;
                BufferConfigPtr->BufferLength = (UINT32) AgesaLocateBufferPtr->BufferLength;
                Status = EFI_SUCCESS;
                break;
            }
            AgesaLocateBufferPtr = AgesaLocateBufferPtr->NextAgesaBufferManagerPtr;
        }
        break;

    default:
        break;
    }
    return Status;
}
Пример #15
0
EFI_STATUS
EFIAPI
AgesaDxeDriverEntryPoint (
    IN       EFI_HANDLE                       ImageHandle,
    IN       EFI_SYSTEM_TABLE                 *SystemTable
)
{
    EFI_STATUS                  Status;
    AMD_INTERFACE_PARAMS        AmdInterfaceParams;
    AGESA_STATUS                AgesaStatus;
    AMD_ENV_PARAMS              AmdInitEnvParams;
    EFI_EVENT                   ReadyToBootEvent;
    EFI_HANDLE                  Handle;
    AMD_BUFFER_MANAGER_PROTOCOL *BufferMgr;

    //
    // Initialize Global Variable
    //
    EfiInitializeDriverLib (ImageHandle, SystemTable);

    //
    // Initialize the configuration structure and private data area
    //
    // Allocate memory for the private data
    Status = gBS->AllocatePool (
                 EfiBootServicesData,
                 sizeof (AGESA_DXE_PRIVATE_DATA),
                 &mAgesaDxePrivate);

    ASSERT_EFI_ERROR (Status);

    if (EFI_ERROR (Status)) {
        return Status;
    }
    //
    // Install the AMD_AGESA_MMIO_PROTOCOL
    //
    mAgesaDxePrivate->MmioMapManager.AmdMmioMapManager = AmdMmioMapManager;

    Handle = NULL;
    gBS->InstallProtocolInterface (
        &Handle,
        &gAmdAgesaMmioProtocolGuid,
        EFI_NATIVE_INTERFACE,
        &mAgesaDxePrivate->MmioMapManager
    );
    //
    // Initialize the private data structure
    //
    mAgesaDxePrivate->Signature = AGESA_DXE_PRIVATE_DATA_SIGNATURE;

    //
    // Create the first buffer for AGESA_ALLOCATE_BUFFER Manager
    //
    Status = gBS->AllocatePool (
                 EfiBootServicesData,
                 sizeof (AGESA_DXE_BUFFER_MANAGER),
                 &mAgesaDxePrivate->BufferManagerPtr
             );

    ASSERT_EFI_ERROR (Status);

    if (EFI_ERROR (Status)) {
        return Status;
    }
    EfiZeroMem (mAgesaDxePrivate->BufferManagerPtr, sizeof (AGESA_DXE_BUFFER_MANAGER));
    mAgesaDxePrivate->BufferManagerPtr->NextAgesaBufferManagerPtr = NULL;
    AgesaBufferManager = mAgesaDxePrivate->BufferManagerPtr;

    //
    // Rebuild persist heap from HOB.
    //
    Status = RebuildHeap (&mAgesaDxePrivate->HeapManagerPtr);
    if (EFI_ERROR (Status)) {
        return EFI_OUT_OF_RESOURCES;
    }

    //
    // Invoke AmdInitEnv
    //
    EfiZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS));
    EfiZeroMem (&AmdInitEnvParams, sizeof (AMD_ENV_PARAMS));
    AmdInterfaceParams.StdHeader.ImageBasePtr = 0;
    AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM;
    AmdInterfaceParams.AllocationMethod = ByHost;
    AmdInterfaceParams.AgesaFunctionName = AMD_INIT_ENV;
    AmdInterfaceParams.NewStructPtr = &AmdInitEnvParams;
    AmdInterfaceParams.NewStructSize = sizeof (AMD_ENV_PARAMS);
    AgesaStatus = AmdCreateStruct (&AmdInterfaceParams);

    AmdInitEnvParams.StdHeader = AmdInterfaceParams.StdHeader;

    OemCustomizeInitEnv (gBS, &AmdInitEnvParams);

    AgesaStatus = AmdInitEnv (&AmdInitEnvParams);

    OemHookAfterInitEnv (gBS, &AmdInitEnvParams);

    if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) {
        return EFI_DEVICE_ERROR;
    }

    //
    // Install AmdBufferManagerProtocol which notifies other dependent drivers
    //
    Status = gBS->AllocatePool (
                 EfiBootServicesData,
                 sizeof (AMD_BUFFER_MANAGER_PROTOCOL),
                 &BufferMgr
             );
    ASSERT_EFI_ERROR (Status);

    BufferMgr->StdHeader = AmdInitEnvParams.StdHeader;
    BufferMgr->DxeBufferManager = mAgesaDxePrivate->BufferManagerPtr;
    BufferMgr->AmdBufferCallout = AgesaDxeCallout;

    Handle = NULL;
    gBS->InstallProtocolInterface (
        &Handle,
        &gAmdBufferManagerProtocolGuid,
        EFI_NATIVE_INTERFACE,
        BufferMgr
    );


    //
    // Register the event handling function for AmdInitMid to be launched after
    // PciIo protocol
    //
    Status = gBS->CreateEventEx (
                 EFI_EVENT_NOTIFY_SIGNAL,
                 EFI_TPL_NOTIFY,
                 InvokeAmdInitMid,
                 NULL,
                 &PciIoProtocolInstallEventGuid,
                 &PciIoEvent
             );

    Status = gBS->RegisterProtocolNotify (
                 &gEfiPciIoProtocolGuid,
                 PciIoEvent,
                 &mRegistrationForPciIo
             );

    //
    // Set up call back for AmdInitLate after AmdInitMid has been launched.
    //
    Status = gBS->CreateEventEx (
                 EFI_EVENT_NOTIFY_SIGNAL,
                 EFI_TPL_NOTIFY,
                 InvokeAmdInitLate,
                 NULL,
                 &AmdInitMidProtocolInstallEventGuid,
                 &AmdInitMidEvent
             );

    Status = gBS->RegisterProtocolNotify (
                 &gAmdDxeInitMidProtocolGuid,
                 AmdInitMidEvent,
                 &(mRegistrationForAmdInitMid)
             );


    //
    // Initialize AMD CPU Interface protocol
    //
    mAgesaDxePrivate->CpuInterface.CreateProcessorTables = AmdCpuCreateProcessorTables;

    // Invoke AmdInitRtb
    // Register the event handling function to do last minute configuration and
    // preparation for system suspend-to-RAM mode.
    //
    Status = gBS->CreateEventEx (
                 EFI_EVENT_NOTIFY_SIGNAL,
                 EFI_TPL_NOTIFY,
                 AgesaInitRtb,
                 NULL,
                 &gEfiEventReadyToBootGuid,
                 &ReadyToBootEvent
             );

    return EFI_SUCCESS;
}
Пример #16
0
EFI_STATUS
RebuildHeap (
    IN OUT   HEAP_MANAGER                 **HeapManagerPtr
)
{
    EFI_STATUS                  Status;
    AGESA_STATUS                AgesaStatus;
    UINTN                       BufferSize;
    UINTN                       AlignTo16ByteInDxeMem;
    UINTN                       TotalAlignTo16ByteInHob;
    EFI_PEI_HOB_POINTERS        Hob;
    VOID                        *HobList;
    VOID                        *HeapBufferInHob;
    HEAP_MANAGER                *HeapManagerInHob;
    BUFFER_NODE                 *HeapHeaderNodeInHob;
    BUFFER_NODE                 *HeapCurrentNodeInHob;
    BUFFER_NODE                 *HeapPreNodeInHob;

    HEAP_MANAGER                *HeapManagerInDxeMem;
    BUFFER_NODE                 *HeapHeaderNodeInDxeMem;
    BUFFER_NODE                 *HeapCurrentNodeInDxeMem;
    BUFFER_NODE                 *HeapPreNodeInDxeMem;
    UINT32                      OffsetOfHeapCurrentNodeInDxeMem;

    AGESA_BUFFER_PARAMS         AllocParams;

    Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
    ASSERT_EFI_ERROR (Status);

    Hob.Raw = HobList;
    HeapBufferInHob = NULL;

    while (!END_OF_HOB_LIST (Hob)) {
        Status = GetNextGuidHob (
                     &HobList,
                     &gAmdHeapHobGuid,
                     &HeapBufferInHob,
                     &BufferSize
                 );

        if (Status == EFI_SUCCESS ) {
            HeapManagerInHob = (HEAP_MANAGER *) HeapBufferInHob;
            HeapHeaderNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapManagerInHob + HeapManagerInHob->FirstActiveBufferOffset);
            HeapCurrentNodeInHob = HeapHeaderNodeInHob;
            //
            // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers
            //    Reserve maximum pad size for each heap node.
            // 2. Allocate memory for heap buffers
            // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment
            //

            //
            // 1. Analyse heap buffer from HOB data to calculate the final size for recreating the heap buffers.
            //    Reserve maximum pad size for each heap node.
            //
            TotalAlignTo16ByteInHob = 0;
            do {
                HeapPreNodeInHob = HeapCurrentNodeInHob;
                TotalAlignTo16ByteInHob += 0xF;
                HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode);
            } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET);

            //
            // 2. Allocate memory for heap buffers
            //
            AllocParams.BufferLength = (UINT32) (HeapManagerInHob->UsedSize + TotalAlignTo16ByteInHob + 0x0F);
            AllocParams.BufferHandle = AMD_HEAP_IN_MAIN_MEMORY_HANDLE;
            if ((AgesaStatus = AgesaAllocateBuffer (0, &AllocParams)) != AGESA_SUCCESS) {
                if (AGESA_ERROR > AgesaStatus) {
                    return EFI_OUT_OF_RESOURCES;
                }
            }
            EfiZeroMem (AllocParams.BufferPointer, AllocParams.BufferLength);
            *HeapManagerPtr = AllocParams.BufferPointer;

            //
            // 3. Copying heap manager data from HOB include extracing 1-byte alignment to 16-byte alignment
            //
            HeapManagerInDxeMem = *HeapManagerPtr;
            HeapManagerInDxeMem->FirstActiveBufferOffset = sizeof (HEAP_MANAGER);
            HeapManagerInDxeMem->UsedSize = sizeof (HEAP_MANAGER);
            HeapHeaderNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapManagerInDxeMem->FirstActiveBufferOffset);
            OffsetOfHeapCurrentNodeInDxeMem = HeapManagerInDxeMem->FirstActiveBufferOffset;
            HeapCurrentNodeInDxeMem = HeapHeaderNodeInDxeMem;
            HeapCurrentNodeInHob = HeapHeaderNodeInHob;

            HeapPreNodeInHob = NULL;
            do {
                // Create BUFFER_NODE with 16-byte alignment padding considered.
                // The beginning of data buffer is on 16-byte boundary address.
                // The structure of a heap buffer would be looked like below.
                //
                // +---------------------------------------------------------------------------------+
                // | BUFFER_NODE | Pad | IDS SENTINEL ("Head") | Data buffer | IDS SENTINEL ("Tail") |
                // +---------------------------------------------------------------------------------+
                //
                AlignTo16ByteInDxeMem = ((0x10 - (((UINTN) (VOID *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + SIZE_OF_SENTINEL) & 0xF)) & 0xF);
                HeapCurrentNodeInDxeMem->BufferHandle = HeapCurrentNodeInHob->BufferHandle;
                HeapCurrentNodeInDxeMem->BufferSize = (UINT32) (HeapCurrentNodeInHob->BufferSize + AlignTo16ByteInDxeMem);
                HeapCurrentNodeInDxeMem->Persist = HeapCurrentNodeInHob->Persist;
                HeapCurrentNodeInDxeMem->PadSize = (UINT8) AlignTo16ByteInDxeMem;
                HeapCurrentNodeInDxeMem->OffsetOfNextNode = OffsetOfHeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + HeapCurrentNodeInDxeMem->BufferSize;
                // Copy buffer data
                gBS->CopyMem (
                    (UINT8 *) ((UINT8 *) HeapCurrentNodeInDxeMem + sizeof (BUFFER_NODE) + AlignTo16ByteInDxeMem),
                    (UINT8 *) ((UINT8 *) HeapCurrentNodeInHob + sizeof (BUFFER_NODE)),
                    HeapCurrentNodeInHob->BufferSize
                );
                // Point to the next heap node
                HeapPreNodeInHob = HeapCurrentNodeInHob;
                HeapPreNodeInDxeMem = HeapCurrentNodeInDxeMem;
                HeapCurrentNodeInHob = (BUFFER_NODE *) ((UINT8 *) HeapBufferInHob + HeapCurrentNodeInHob->OffsetOfNextNode);
                HeapCurrentNodeInDxeMem = (BUFFER_NODE *) ((UINT8 *) HeapManagerInDxeMem + HeapCurrentNodeInDxeMem->OffsetOfNextNode);
                OffsetOfHeapCurrentNodeInDxeMem = (UINT32) ((UINTN) HeapCurrentNodeInDxeMem - (UINTN) HeapManagerInDxeMem);

            } while (HeapPreNodeInHob->OffsetOfNextNode != AMD_HEAP_INVALID_HEAP_OFFSET);
            //
            // Finalize the last heap node
            //
            HeapManagerInDxeMem->UsedSize = (UINT32) HeapPreNodeInDxeMem->OffsetOfNextNode;
            HeapPreNodeInDxeMem->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;

            //
            // Finalize Heap Manager pointer
            // No free buffer node is provide after heap recreation.
            //
            *HeapManagerPtr = HeapManagerInDxeMem;
            HeapManagerInDxeMem->FirstActiveBufferOffset = (UINT32) ((UINT8 *) HeapHeaderNodeInDxeMem - (UINT8 *) HeapManagerInDxeMem);
            HeapManagerInDxeMem->FirstFreeSpaceOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
            HeapManagerInDxeMem->Signature = HeapManagerInHob->Signature;

            return EFI_SUCCESS;
        }
    }

    return EFI_NOT_FOUND;
}
Пример #17
0
EFI_STATUS
GetNumericInput (
  IN  UI_MENU_SELECTION           *Selection,
  IN  UI_MENU_OPTION              *MenuOption
  )
/*++

Routine Description:
  This routine reads a numeric value from the user input.

Arguments:
  Selection        -  Pointer to current selection.
  MenuOption       -  Pointer to the current input menu.

Returns:
  EFI_SUCCESS       - If numerical input is read successfully
  EFI_DEVICE_ERROR  - If operation fails

--*/
{
  EFI_STATUS              Status;
  UINTN                   Column;
  UINTN                   Row;
  CHAR16                  InputText[23];
  CHAR16                  FormattedNumber[22];
  UINT64                  PreviousNumber[20];
  UINTN                   Count;
  UINTN                   Loop;
  BOOLEAN                 ManualInput;
  BOOLEAN                 HexInput;
  BOOLEAN                 DateOrTime;
  UINTN                   InputWidth;
  UINT64                  EditValue;
  UINT64                  Step;
  UINT64                  Minimum;
  UINT64                  Maximum;
  UINTN                   EraseLen;
  UINT8                   Digital;
  EFI_INPUT_KEY           Key;
  EFI_HII_VALUE           *QuestionValue;
  FORM_BROWSER_FORM       *Form;
  FORM_BROWSER_FORMSET    *FormSet;
  FORM_BROWSER_STATEMENT  *Question;

  Column            = MenuOption->OptCol;
  Row               = MenuOption->Row;
  PreviousNumber[0] = 0;
  Count             = 0;
  InputWidth        = 0;
  Digital           = 0;

  FormSet       = Selection->FormSet;
  Form          = Selection->Form;
  Question      = MenuOption->ThisTag;
  QuestionValue = &Question->HiiValue;
  Step          = Question->Step;
  Minimum       = Question->Minimum;
  Maximum       = Question->Maximum;

  if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
    DateOrTime = TRUE;
  } else {
    DateOrTime = FALSE;
  }

  //
  // Prepare Value to be edit
  //
  EraseLen = 0;
  EditValue = 0;
  if (Question->Operand == EFI_IFR_DATE_OP) {
    Step = 1;
    Minimum = 1;

    switch (MenuOption->Sequence) {
    case 0:
      Maximum = 12;
      EraseLen = 4;
      EditValue = QuestionValue->Value.date.Month;
      break;

    case 1:
      Maximum = 31;
      EraseLen = 3;
      EditValue = QuestionValue->Value.date.Day;
      break;

    case 2:
      Maximum = 0xffff;
      EraseLen = 5;
      EditValue = QuestionValue->Value.date.Year;
      break;

    default:
      break;
    }
  } else if (Question->Operand == EFI_IFR_TIME_OP) {
    Step = 1;
    Minimum = 0;

    switch (MenuOption->Sequence) {
    case 0:
      Maximum = 23;
      EraseLen = 4;
      EditValue = QuestionValue->Value.time.Hour;
      break;

    case 1:
      Maximum = 59;
      EraseLen = 3;
      EditValue = QuestionValue->Value.time.Minute;
      break;

    case 2:
      Maximum = 59;
      EraseLen = 3;
      EditValue = QuestionValue->Value.time.Second;
      break;

    default:
      break;
    }
  } else {
    //
    // Numeric
    //
    EraseLen = gOptionBlockWidth;
    EditValue = QuestionValue->Value.u64;
    if (Maximum == 0) {
      Maximum = (UINT64) -1;
    }
  }

  if (Step == 0) {
    ManualInput = TRUE;
  } else {
    ManualInput = FALSE;
  }

  if ((Question->Operand == EFI_IFR_NUMERIC_OP) &&
      ((Question->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {
    HexInput = TRUE;
  } else {
    HexInput = FALSE;
  }

  if (ManualInput) {
    if (HexInput) {
      InputWidth = Question->StorageWidth * 2;
    } else {
      switch (Question->StorageWidth) {
      case 1:
        InputWidth = 3;
        break;

      case 2:
        InputWidth = 5;
        break;

      case 4:
        InputWidth = 10;
        break;

      case 8:
        InputWidth = 20;
        break;

      default:
        InputWidth = 0;
        break;
      }
    }

    InputText[0] = LEFT_NUMERIC_DELIMITER;
    SetUnicodeMem (InputText + 1, InputWidth, L' ');
    InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
    InputText[InputWidth + 2] = L'\0';

    PrintAt (Column, Row, InputText);
    Column++;
  }

  //
  // First time we enter this handler, we need to check to see if
  // we were passed an increment or decrement directive
  //
  do {
    Key.UnicodeChar = CHAR_NULL;
    if (gDirection != 0) {
      Key.ScanCode  = gDirection;
      gDirection    = 0;
      goto TheKey2;
    }

    Status = WaitForKeyStroke (&Key);

TheKey2:
    switch (Key.UnicodeChar) {

    case '+':
    case '-':
      if (Key.UnicodeChar == '+') {
        Key.ScanCode = SCAN_RIGHT;
      } else {
        Key.ScanCode = SCAN_LEFT;
      }
      Key.UnicodeChar = CHAR_NULL;
      goto TheKey2;

    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_LEFT:
      case SCAN_RIGHT:
        if (DateOrTime) {
          //
          // By setting this value, we will return back to the caller.
          // We need to do this since an auto-refresh will destroy the adjustment
          // based on what the real-time-clock is showing.  So we always commit
          // upon changing the value.
          //
          gDirection = SCAN_DOWN;
        }

        if (!ManualInput) {
          if (Key.ScanCode == SCAN_LEFT) {
            if (EditValue > Step) {
              EditValue = EditValue - Step;
            } else {
              EditValue = Minimum;
            }
          } else if (Key.ScanCode == SCAN_RIGHT) {
            EditValue = EditValue + Step;
            if (EditValue > Maximum) {
              EditValue = Maximum;
            }
          }

          EfiZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
          if (Question->Operand == EFI_IFR_DATE_OP) {
            if (MenuOption->Sequence == 2) {
              //
              // Year
              //
              SPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINTN) EditValue);
            } else {
              //
              // Month/Day
              //
              SPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINTN) EditValue);
            }

            if (MenuOption->Sequence == 0) {
              FormattedNumber[EraseLen - 2] = DATE_SEPARATOR;
            } else if (MenuOption->Sequence == 1) {
              FormattedNumber[EraseLen - 1] = DATE_SEPARATOR;
            }
          } else if (Question->Operand == EFI_IFR_TIME_OP) {
            SPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINTN) EditValue);

            if (MenuOption->Sequence == 0) {
              FormattedNumber[EraseLen - 2] = TIME_SEPARATOR;
            } else if (MenuOption->Sequence == 1) {
              FormattedNumber[EraseLen - 1] = TIME_SEPARATOR;
            }
          } else {
            QuestionValue->Value.u64 = EditValue;
            PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
          }

          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
          for (Loop = 0; Loop < EraseLen; Loop++) {
            PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
          }
          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT);

          if (MenuOption->Sequence == 0) {
            PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);
            Column = MenuOption->OptCol + 1;
          }

          PrintStringAt (Column, Row, FormattedNumber);

          if (!DateOrTime || MenuOption->Sequence == 2) {
            PrintChar (RIGHT_NUMERIC_DELIMITER);
          }

  		  goto EnterCarriageReturn;
        }
        break;

      case SCAN_UP:
      case SCAN_DOWN:
        goto EnterCarriageReturn;

      case SCAN_ESC:
        return EFI_DEVICE_ERROR;

      default:
        break;
      }

      break;

EnterCarriageReturn:

    case CHAR_CARRIAGE_RETURN:
      //
      // Store Edit value back to Question
      //
      if (Question->Operand == EFI_IFR_DATE_OP) {
        switch (MenuOption->Sequence) {
        case 0:
          QuestionValue->Value.date.Month = (UINT8) EditValue;
          break;

        case 1:
          QuestionValue->Value.date.Day = (UINT8) EditValue;
          break;

        case 2:
          QuestionValue->Value.date.Year = (UINT16) EditValue;
          break;

        default:
          break;
        }
      } else if (Question->Operand == EFI_IFR_TIME_OP) {
        switch (MenuOption->Sequence) {
        case 0:
          QuestionValue->Value.time.Hour = (UINT8) EditValue;
          break;

        case 1:
          QuestionValue->Value.time.Minute = (UINT8) EditValue;
          break;

        case 2:
          QuestionValue->Value.time.Second = (UINT8) EditValue;
          break;

        default:
          break;
        }
      } else {
        //
        // Numeric
        //
        QuestionValue->Value.u64 = EditValue;
      }

      //
      // Check to see if the Value is something reasonable against consistency limitations.
      // If not, let's kick the error specified.
      //
      Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
      if (EFI_ERROR (Status)) {
        //
        // Input value is not valid, restore Question Value
        //
        GetQuestionValue (FormSet, Form, Question, TRUE);
      } else {
        SetQuestionValue (FormSet, Form, Question, TRUE);
        if (!DateOrTime || (Question->Storage != NULL)) {
          //
          // NV flag is unnecessary for RTC type of Date/Time
          //
          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
        }
      }

      return Status;
      break;

    case CHAR_BACKSPACE:
      if (ManualInput) {
        if (Count == 0) {
          break;
        }
        //
        // Remove a character
        //
        EditValue = PreviousNumber[Count - 1];
        UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE);
        Count--;
        Column--;
        PrintAt (Column, Row, L" ");
      }
      break;

    default:
      if (ManualInput) {
        if (HexInput) {
          if (!IsHexDigit (&Digital, Key.UnicodeChar)) {
            UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE);
            break;
          }
        } else {
          if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {
            UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE);
            break;
          }
        }

        //
        // If Count exceed input width, there is no way more is valid
        //
        if (Count >= InputWidth) {
          break;
        }
        //
        // Someone typed something valid!
        //
        if (Count != 0) {
          if (HexInput) {
            EditValue = LShiftU64 (EditValue, 4) + Digital;
          } else {
            //
            // EditValue = EditValue * 10 + (Key.UnicodeChar - L'0');
            //
            EditValue = LShiftU64 (EditValue, 3) + LShiftU64 (EditValue, 1) + (Key.UnicodeChar - L'0');
          }
        } else {
          if (HexInput) {
            EditValue = Digital;
          } else {
            EditValue = Key.UnicodeChar - L'0';
          }
        }

        if (EditValue > Maximum) {
          UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE);
          EditValue = PreviousNumber[Count];
          break;
        } else {
          UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE);
        }

        Count++;
        PreviousNumber[Count] = EditValue;

        PrintCharAt (Column, Row, Key.UnicodeChar);
        Column++;
      }
      break;
    }
  } while (TRUE);

  return EFI_SUCCESS;
}
Пример #18
0
//
// /////////////////////////////////////////////////////////////////////
//
//  Udp Read Routine - called by base code - e.g. TFTP - already locked
//
EFI_STATUS
TcpRead (
  IN PXE_BASECODE_DEVICE            *Private,
  IN UINT16                         OpFlags,
  IN OUT EFI_IP_ADDRESS             *DestIpPtr, OPTIONAL
  IN OUT EFI_PXE_BASE_CODE_TCP_PORT *DestPortPtr, OPTIONAL
  IN OUT EFI_IP_ADDRESS             *SrcIpPtr, OPTIONAL
  IN OUT EFI_PXE_BASE_CODE_TCP_PORT *SrcPortPtr, OPTIONAL
  IN UINTN                          *HeaderSizePtr, OPTIONAL
  IN VOID                           *HeaderPtr,
  IN OUT UINTN                      *BufferSizePtr,
  IN VOID                           *BufferPtr
  )
/*++
Routine description:
  TCP read packet.

Parameters:
  Private := Pointer to PxeBc interface
  OpFlags := 
  DestIpPtr := 
  DestPortPtr := 
  SrcIpPtr := 
  SrcPortPtr := 
  HeaderSizePtr := 
  HeaderPtr := 
  BufferSizePtr := 
  BufferPtr := 

Returns:
  EFI_SUCCESS := 
  EFI_DEVICE_ERROR := 
  EFI_INVALID_PARAMETER := 
  other := 
--*/
{
  EFI_IP_ADDRESS  TmpSrcIp;
  EFI_IP_ADDRESS  TmpDestIp;
  EFI_STATUS      StatCode;
  UINTN           BufferSize;
  UINTN           HeaderSize;

  //
  // combination structure of pseudo header/tcp header
  //
#pragma pack (1)
  struct {
    IPV4_HEADER         Ipv4Hdr;
    TCPV4_PSEUDO_HEADER Tcpv4Phdr;
    TCPV4_HEADER        Tcpv4Hdr;
    UINT8               ProtHdr[64];
  } Hdrs;
#pragma pack ()

  HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;
  //
  // Yes, I now require a Header Allocated
  //
  if (HeaderPtr == 0) {
    return EFI_DEVICE_ERROR;
  }

  HeaderSize = sizeof Hdrs.Ipv4Hdr + sizeof Hdrs.Tcpv4Hdr;
  EfiZeroMem (Hdrs.ProtHdr, 64);

  Hdrs.ProtHdr[0] = 'M';
  Hdrs.ProtHdr[1] = 'A';
  Hdrs.ProtHdr[2] = 'R';
  Hdrs.ProtHdr[3] = 'M';
  Hdrs.ProtHdr[4] = 'A';
  Hdrs.ProtHdr[5] = 'R';

  DEBUG ((EFI_D_NET, "\nTcpRead()  BufferSize = %xh", *BufferSizePtr));

  //
  // read [with filtering]
  // check parameters
  //
  if (BufferSizePtr == NULL ||
      BufferPtr == NULL ||
      (HeaderSize != 0 && HeaderPtr == NULL) ||
      (OpFlags &~UDP_FILTER_MASK)
      //
      // if filtering on a particular IP/Port, need it
      //
      ||
      (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr == NULL) ||
      (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && SrcPortPtr == NULL) ||
      (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && DestPortPtr == NULL)
      ) {
    DEBUG ((EFI_D_INFO, "\nTcpRead()  Exit #1  Invalid Parameter"));
    return EFI_INVALID_PARAMETER;
  }

  BufferSize = *BufferSizePtr;
  //
  // in case we loop
  //
  // we need source and dest IPs for pseudo header
  //
  if (SrcIpPtr == NULL) {
    SrcIpPtr = &TmpSrcIp;
  }

  if (DestIpPtr == NULL) {
    DestIpPtr = &TmpDestIp;
    TmpDestIp = Private->EfiBc.Mode->StationIp;
  }

  for (;;) {
    *BufferSizePtr = BufferSize;

    DEBUG ((EFI_D_NET, "\nSize of Hdrs.Tcpv4Hdr = %d", sizeof Hdrs.Tcpv4Hdr));

    //
    // Let's receive the IP and TCP header at the Hdrs.Ipv4Hdr location
    // and the data for the TCP will be passed back in the BufferPtr.
    //
    StatCode = IpReceive (
                Private,
                OpFlags,
                SrcIpPtr,
                DestIpPtr,
                PROT_TCP,
                HeaderPtr,
                HeaderSize,
                BufferPtr,
                BufferSizePtr,
                0
                );

    EfiCopyMem (&Hdrs.Ipv4Hdr, HeaderPtr, HeaderSize);

    DEBUG (
      (EFI_D_NET,
      "\nTcpRead()  BufferSize = %xh  Ipv+Tcp = %d",
      *BufferSizePtr,
      sizeof Hdrs.Ipv4Hdr + sizeof Hdrs.Tcpv4Hdr)
      );

    DEBUG (
      (EFI_D_NET,
      "\nTcpRead()  Destination IP address is:  %d.%d.%d.%d\n",
      Hdrs.Ipv4Hdr.DestAddr.B[0],
      Hdrs.Ipv4Hdr.DestAddr.B[1],
      Hdrs.Ipv4Hdr.DestAddr.B[2],
      Hdrs.Ipv4Hdr.DestAddr.B[3])
      );

    DEBUG (
      (EFI_D_NET,
      "\nTcpRead()  Source IP address is:  %d.%d.%d.%d\n",
      Hdrs.Ipv4Hdr.SrcAddr.B[0],
      Hdrs.Ipv4Hdr.SrcAddr.B[1],
      Hdrs.Ipv4Hdr.SrcAddr.B[2],
      Hdrs.Ipv4Hdr.SrcAddr.B[3])
      );

    if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {
      UINT16  SPort;
      UINT16  DPort;

      SPort = NTOHS (Hdrs.Tcpv4Hdr.SrcPort);
      DPort = NTOHS (Hdrs.Tcpv4Hdr.DestPort);

      //
      // do filtering
      //
      if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && *SrcPortPtr != SPort) {
        continue;
      }

      if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && *DestPortPtr != DPort) {
        continue;
      }
      //
      // check checksum
      //
      if (StatCode == EFI_SUCCESS && Hdrs.Tcpv4Hdr.Checksum) {
        Hdrs.Tcpv4Phdr.SrcAddr.L    = SrcIpPtr->Addr[0];
        Hdrs.Tcpv4Phdr.DestAddr.L   = DestIpPtr->Addr[0];
        Hdrs.Tcpv4Phdr.Zero         = 0;
        Hdrs.Tcpv4Phdr.Protocol     = PROT_TCP;
        Hdrs.Tcpv4Phdr.TotalLength  = (UINT16) (NTOHS (Hdrs.Ipv4Hdr.TotalLength) - sizeof Hdrs.Ipv4Hdr);
        Hdrs.Tcpv4Phdr.TotalLength  = HTONS (Hdrs.Tcpv4Phdr.TotalLength);

        if (Hdrs.Tcpv4Hdr.Checksum == 0xffff) {
          Hdrs.Tcpv4Hdr.Checksum = 0;
        }
        //
        // The HeaderPtr has the IP header in it, let's skip it and start the
        // checksum at the TCP pseudo header.
        //
        if (IpChecksum2 (
              (UINT16 *) HeaderPtr + sizeof Hdrs.Ipv4Hdr,
              sizeof Hdrs.Tcpv4Hdr + sizeof Hdrs.Tcpv4Phdr,
              (UINT16 *) BufferPtr,
              *BufferSizePtr
              )) {
          DEBUG (
            (EFI_D_NET,
            "\nTcpRead()  Hdrs.Ipv4hdr == %xh",
            &Hdrs.Ipv4Hdr)
            );
          DEBUG (
            (EFI_D_NET,
            "\nTcpRead()  Hdrs.Tcpv4hdr == %xh",
            &Hdrs.Tcpv4Hdr)
            );
          DEBUG ((EFI_D_NET, "\nTcpRead()  Header size == %d", HeaderSize));
          DEBUG ((EFI_D_NET, "\nTcpRead()  BufferPtr == %xh", BufferPtr));
          DEBUG ((EFI_D_NET, "\nTcpRead()  Buffer size == %d", *BufferSizePtr));
          DEBUG ((EFI_D_NET, "\nTcpRead()  Exit #2  Device Error"));

          //
          // Invalid checksum for a zero lenght buffer is okay.
          //
          if (*BufferSizePtr > 0) {
            return EFI_DEVICE_ERROR;
          }
        }
      }

      DEBUG ((EFI_D_NET, "\nTcpRead()  PASSED!!!!!!!!"));

      //
      // all passed
      //
      if (SrcPortPtr != NULL) {
        *SrcPortPtr = SPort;
      }

      if (DestPortPtr != NULL) {
        *DestPortPtr = DPort;
      }
    }

    if ((StatCode != EFI_SUCCESS) && (StatCode != EFI_TIMEOUT)) {
      DEBUG (
        (EFI_D_INFO,
        "\nTcpRead()  Exit #3  %Xh %r",
        StatCode,
        StatCode)
        );
    }

    return StatCode;
  }
}
Пример #19
0
EFI_STATUS
ProcessOptions (
  IN  UI_MENU_SELECTION           *Selection,
  IN  UI_MENU_OPTION              *MenuOption,
  IN  BOOLEAN                     Selected,
  OUT CHAR16                      **OptionString
  )
/*++

Routine Description:
  Process a Question's Option (whether selected or un-selected).

Arguments:
  Selection        - Pointer to UI_MENU_SELECTION.
  MenuOption       - The MenuOption for this Question.
  Selected         - TRUE: if Question is selected.
  OptionString     - Pointer of the Option String to be displayed.

Returns:
  EFI_SUCCESS      - Question Option process success.
  Other            - Question Option process fail.

--*/
{
  EFI_STATUS                      Status;
  CHAR16                          *StringPtr;
  CHAR16                          *TempString;
  UINTN                           Index;
  FORM_BROWSER_STATEMENT          *Question;
  CHAR16                          FormattedNumber[21];
  UINT16                          Number;
  CHAR16                          Character[2];
  EFI_INPUT_KEY                   Key;
  UINTN                           BufferSize;
  QUESTION_OPTION                 *OneOfOption;
  EFI_LIST_ENTRY                  *Link;
  EFI_HII_VALUE                   HiiValue;
  EFI_HII_VALUE                   *QuestionValue;
  BOOLEAN                         Suppress;
  UINT16                          Minimum;
  UINT16                          Maximum;
  QUESTION_OPTION                 *Option;
  UINTN                           Index2;
  UINT8                           *ValueArray;
  UINT8                           ValueType;

  Status        = EFI_SUCCESS;

  StringPtr     = NULL;
  Character[1]  = L'\0';
  *OptionString = NULL;

  EfiZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
  BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow;

  Question = MenuOption->ThisTag;
  QuestionValue = &Question->HiiValue;
  Minimum = (UINT16) Question->Minimum;
  Maximum = (UINT16) Question->Maximum;

  ValueArray = Question->BufferValue;
  ValueType = Question->ValueType;

  switch (Question->Operand) {
  case EFI_IFR_ORDERED_LIST_OP:
    //
    // Check whether there are Options of this OrderedList
    //
    if (IsListEmpty (&Question->OptionListHead)) {
      break;
    }

    //
    // Initialize Option value array
    //
    if (GetArrayData (ValueArray, ValueType, 0) == 0) {
      GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0);
    }

    if (Selected) {
      //
      // Go ask for input
      //
      Status = GetSelectionInputPopUp (Selection, MenuOption);
    } else {
      //
      // We now know how many strings we will have, so we can allocate the
      // space required for the array or strings.
      //
      *OptionString = EfiLibAllocateZeroPool (Question->MaxContainers * BufferSize);
      ASSERT (*OptionString);

      HiiValue.Type = ValueType;
      HiiValue.Value.u64 = 0;
      for (Index = 0; Index < Question->MaxContainers; Index++) {
        HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
        if (HiiValue.Value.u64 == 0) {
          //
          // Values for the options in ordered lists should never be a 0
          //
          break;
        }

        OneOfOption = ValueToOption (Question, &HiiValue);
        if (OneOfOption == NULL) {
          //
          // Show error message
          //
          do {
            CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

          //
          // The initial value of the orderedlist is invalid, force to be valid value
          //
          Link = GetFirstNode (&Question->OptionListHead);
          Index2 = 0;
          while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {
            Option = QUESTION_OPTION_FROM_LINK (Link);
            SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);
            Index2++;
            Link = GetNextNode (&Question->OptionListHead, Link);
          }
          SetArrayData (ValueArray, ValueType, Index2, 0);

          Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
          UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);

          gBS->FreePool (*OptionString);
          *OptionString = NULL;
          return EFI_NOT_FOUND;
        }

        Suppress = FALSE;
        if ((OneOfOption->SuppressExpression != NULL) &&
            (OneOfOption->SuppressExpression->Result.Value.b)) {
          //
          // This option is suppressed
          //
          Suppress = TRUE;
        }

        if (!Suppress) {
          Character[0] = LEFT_ONEOF_DELIMITER;
          NewStrCat (OptionString[0], Character);
          StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
          NewStrCat (OptionString[0], StringPtr);
          Character[0] = RIGHT_ONEOF_DELIMITER;
          NewStrCat (OptionString[0], Character);
          Character[0] = CHAR_CARRIAGE_RETURN;
          NewStrCat (OptionString[0], Character);

          gBS->FreePool (StringPtr);
        }
      }
    }
    break;

  case EFI_IFR_ONE_OF_OP:
    //
    // Check whether there are Options of this OneOf
    //
    if (IsListEmpty (&Question->OptionListHead)) {
      break;
    }

    if (Selected) {
      //
      // Go ask for input
      //
      Status = GetSelectionInputPopUp (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      OneOfOption = ValueToOption (Question, QuestionValue);
      if (OneOfOption == NULL) {
        //
        // Show error message
        //
        do {
          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

        //
        // Force the Question value to be valid
        //
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          Option = QUESTION_OPTION_FROM_LINK (Link);

          if ((Option->SuppressExpression == NULL) ||
              !Option->SuppressExpression->Result.Value.b) {
            EfiCopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));
            SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
            UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
            break;
          }

          Link = GetNextNode (&Question->OptionListHead, Link);
        }

        gBS->FreePool (*OptionString);
        *OptionString = NULL;
        return EFI_NOT_FOUND;
      }

      if ((OneOfOption->SuppressExpression != NULL) &&
          (OneOfOption->SuppressExpression->Result.Value.b)) {
        //
        // This option is suppressed
        //
        Suppress = TRUE;
      } else {
        Suppress = FALSE;
      }

      if (Suppress) {
        //
        // Current selected option happen to be suppressed,
        // enforce to select on a non-suppressed option
        //
        Link = GetFirstNode (&Question->OptionListHead);
        while (!IsNull (&Question->OptionListHead, Link)) {
          OneOfOption = QUESTION_OPTION_FROM_LINK (Link);

          if ((OneOfOption->SuppressExpression == NULL) ||
              !OneOfOption->SuppressExpression->Result.Value.b) {
            Suppress = FALSE;
            EfiCopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));
            SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
            UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
            gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
            break;
          }

          Link = GetNextNode (&Question->OptionListHead, Link);
        }
      }

      if (!Suppress) {
        Character[0] = LEFT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], Character);
        StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
        NewStrCat (OptionString[0], StringPtr);
        Character[0] = RIGHT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], Character);

        gBS->FreePool (StringPtr);
      }
    }
    break;

  case EFI_IFR_CHECKBOX_OP:
    *OptionString = EfiLibAllocateZeroPool (BufferSize);
    ASSERT (*OptionString);

    *OptionString[0] = LEFT_CHECKBOX_DELIMITER;

    if (Selected) {
      //
      // Since this is a BOOLEAN operation, flip it upon selection
      //
      QuestionValue->Value.b = QuestionValue->Value.b ? FALSE : TRUE;

      //
      // Perform inconsistent check
      //
      Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
      if (EFI_ERROR (Status)) {
        //
        // Inconsistent check fail, restore Question Value
        //
        QuestionValue->Value.b = QuestionValue->Value.b ? FALSE : TRUE;
        gBS->FreePool (*OptionString);
        *OptionString = NULL;
        return Status;
      }

      //
      // Save Question value
      //
      Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
      UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
    }

    if (QuestionValue->Value.b) {
      *(OptionString[0] + 1) = CHECK_ON;
    } else {
      *(OptionString[0] + 1) = CHECK_OFF;
    }
    *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
    break;

  case EFI_IFR_NUMERIC_OP:
    if (Selected) {
      //
      // Go ask for input
      //
      Status = GetNumericInput (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      *OptionString[0] = LEFT_NUMERIC_DELIMITER;

      //
      // Formatted print
      //
      PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
      Number = (UINT16) GetStringWidth (FormattedNumber);
      EfiCopyMem (OptionString[0] + 1, FormattedNumber, Number);

      *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
    }
    break;

  case EFI_IFR_DATE_OP:
    if (Selected) {
      //
      // This is similar to numerics
      //
      Status = GetNumericInput (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      switch (MenuOption->Sequence) {
      case 0:
        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
        SPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.date.Month);
        *(OptionString[0] + 3) = DATE_SEPARATOR;
        break;

      case 1:
        SetUnicodeMem (OptionString[0], 4, L' ');
        SPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.date.Day);
        *(OptionString[0] + 6) = DATE_SEPARATOR;
        break;

      case 2:
        SetUnicodeMem (OptionString[0], 7, L' ');
        SPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%4d", (UINTN) QuestionValue->Value.date.Year);
        *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;
        break;
      }
    }
    break;

  case EFI_IFR_TIME_OP:
    if (Selected) {
      //
      // This is similar to numerics
      //
      Status = GetNumericInput (Selection, MenuOption);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      switch (MenuOption->Sequence) {
      case 0:
        *OptionString[0] = LEFT_NUMERIC_DELIMITER;
        SPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Hour);
        *(OptionString[0] + 3) = TIME_SEPARATOR;
        break;

      case 1:
        SetUnicodeMem (OptionString[0], 4, L' ');
        SPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Minute);
        *(OptionString[0] + 6) = TIME_SEPARATOR;
        break;

      case 2:
        SetUnicodeMem (OptionString[0], 7, L' ');
        SPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", (UINTN) QuestionValue->Value.time.Second);
        *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;
        break;
      }
    }
    break;

  case EFI_IFR_STRING_OP:
    if (Selected) {
      StringPtr = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (StringPtr);

      Status = ReadString (MenuOption, gPromptForData, StringPtr);
      if (!EFI_ERROR (Status)) {
        EfiCopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
        SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);

        UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
      }

      gBS->FreePool (StringPtr);
    } else {
      *OptionString = EfiLibAllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      if (((CHAR16 *) Question->BufferValue)[0] == 0x0000) {
        *(OptionString[0]) = '_';
      } else {
        if ((Maximum * sizeof (CHAR16)) < BufferSize) {
          BufferSize = Maximum * sizeof (CHAR16);
        }
        EfiCopyMem (OptionString[0], (CHAR16 *) Question->BufferValue, BufferSize);
      }
    }
    break;

  case EFI_IFR_PASSWORD_OP:
    if (Selected) {
      StringPtr = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (StringPtr);

      //
      // For interactive passwords, old password is validated by callback
      //
      if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
        //
        // Use a NULL password to test whether old password is required
        //
        *StringPtr = 0;
        Status = PasswordCallback (Selection, MenuOption, StringPtr);
        if (Status == EFI_NOT_AVAILABLE_YET) {
          //
          // Callback request to terminate password input
          //
          gBS->FreePool (StringPtr);
          return EFI_SUCCESS;
        }

        if (EFI_ERROR (Status)) {
          //
          // Old password exist, ask user for the old password
          //
          Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
          if (EFI_ERROR (Status)) {
            gBS->FreePool (StringPtr);
            return Status;
          }

          //
          // Check user input old password
          //
          Status = PasswordCallback (Selection, MenuOption, StringPtr);
          if (EFI_ERROR (Status)) {
            if (Status == EFI_NOT_READY) {
              //
              // Typed in old password incorrect
              //
              PasswordInvalid ();
            } else {
              Status = EFI_SUCCESS;
            }

            gBS->FreePool (StringPtr);
            return Status;
          }
        }
      } else {
        //
        // For non-interactive password, validate old password in local
        //
        if (*((CHAR16 *) Question->BufferValue) != 0) {
          //
          // There is something there!  Prompt for password
          //
          Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
          if (EFI_ERROR (Status)) {
            gBS->FreePool (StringPtr);
            return Status;
          }

          TempString = EfiLibAllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);
          TempString[Maximum] = L'\0';

          if (EfiStrCmp (StringPtr, TempString) != 0) {
            //
            // Typed in old password incorrect
            //
            PasswordInvalid ();

            gBS->FreePool (StringPtr);
            gBS->FreePool (TempString);
            return Status;
          }

          gBS->FreePool (TempString);
        }
      }

      //
      // Ask for new password
      //
      EfiZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
      Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
      if (EFI_ERROR (Status)) {
        //
        // Reset state machine for interactive password
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        gBS->FreePool (StringPtr);
        return Status;
      }

      //
      // Confirm new password
      //
      TempString = EfiLibAllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (TempString);
      Status = ReadString (MenuOption, gConfirmPassword, TempString);
      if (EFI_ERROR (Status)) {
        //
        // Reset state machine for interactive password
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        gBS->FreePool (StringPtr);
        gBS->FreePool (TempString);
        return Status;
      }

      //
      // Compare two typed-in new passwords
      //
      if (EfiStrCmp (StringPtr, TempString) == 0) {
        //
        // Two password match, send it to Configuration Driver
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, StringPtr);
        } else {
          EfiCopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
          SetQuestionValue (Selection->FormSet, Selection->Form, Question, FALSE);
        }
      } else {
        //
        // Reset state machine for interactive password
        //
        if (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        //
        // Two password mismatch, prompt error message
        //
        do {
          CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
      }

      gBS->FreePool (TempString);
      gBS->FreePool (StringPtr);
    }
    break;

  default:
    break;
  }

  return Status;
}
Пример #20
0
EFI_STATUS
AddString (
  IN      VOID                *StringBuffer,
  IN      CHAR16              *Language,
  IN      CHAR16              *String,
  IN OUT  STRING_REF          *StringToken
  )
/*++

Routine Description:

  Add a string to the incoming buffer and return the token and offset data
  
Arguments:
  
  StringBuffer      - The incoming buffer
  
  Language          - Currrent language
  
  String            - The string to be added
  
  StringToken       - The index where the string placed
  
Returns: 

  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate
  
  EFI_SUCCESS             - String successfully added to the incoming buffer

--*/
{
  EFI_HII_STRING_PACK *StringPack;
  EFI_HII_STRING_PACK *StringPackBuffer;
  VOID                *NewBuffer;
  RELOFST             *PackSource;
  RELOFST             *PackDestination;
  UINT8               *Source;
  UINT8               *Destination;
  UINTN               Index;
  BOOLEAN             Finished;

  StringPack  = (EFI_HII_STRING_PACK *) StringBuffer;
  Finished    = FALSE;

  //
  // Pre-allocate a buffer sufficient for us to work on.
  // We will use it as a destination scratch pad to build data on
  // and when complete shift the data back to the original buffer
  //
  NewBuffer = EfiLibAllocateZeroPool (DEFAULT_STRING_BUFFER_SIZE);
  if (NewBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StringPackBuffer = (EFI_HII_STRING_PACK *) NewBuffer;

  //
  // StringPack is terminated with a length 0 entry
  //
  for (; StringPack->Header.Length != 0;) {
    //
    // If this stringpack's language is same as CurrentLanguage, use it
    //
    if (EfiCompareMem ((VOID *) ((CHAR8 *) (StringPack) + StringPack->LanguageNameString), Language, 3) == 0) {
      //
      // We have some data in this string pack, copy the string package up to the string data
      //
      EfiCopyMem (&StringPackBuffer->Header, &StringPack->Header, sizeof (StringPack));

      //
      // These are references in the structure to tokens, need to increase them by the space occupied by an additional StringPointer
      //
      StringPackBuffer->LanguageNameString = (UINT16) (StringPackBuffer->LanguageNameString + (UINT16) sizeof (RELOFST));
      StringPackBuffer->PrintableLanguageName = (UINT16) (StringPackBuffer->PrintableLanguageName + (UINT16) sizeof (RELOFST));

      PackSource      = (RELOFST *) (StringPack + 1);
      PackDestination = (RELOFST *) (StringPackBuffer + 1);
      for (Index = 0; PackSource[Index] != 0x0000; Index++) {
        //
        // Copy the stringpointers from old to new buffer
        // remember that we are adding a string, so the string offsets will all go up by sizeof (RELOFST)
        //
        PackDestination[Index] = (UINT16) (PackDestination[Index] + sizeof (RELOFST));
      }
      
      //
      // Add a new stringpointer in the new buffer since we are adding a string.  Null terminate it
      //
      PackDestination[Index] = (UINT16)(PackDestination[Index-1] + 
                                        EfiStrSize((CHAR16 *)((CHAR8 *)(StringPack) + PackSource[Index-1])));
      PackDestination[Index + 1] = (UINT16) 0;

      //
      // Index is the token value for the new string
      //
      *StringToken = (UINT16) Index;

      //
      // Source now points to the beginning of the old buffer strings
      // Destination now points to the beginning of the new buffer strings
      //
      Source      = (UINT8 *) &PackSource[Index + 1];
      Destination = (UINT8 *) &PackDestination[Index + 2];

      //
      // This should copy all the strings from the old buffer to the new buffer
      //
      for (; Index != 0; Index--) {
        //
        // Copy Source string to destination buffer
        //
        EfiStrCpy ((CHAR16 *) Destination, (CHAR16 *) Source);

        //
        // Adjust the source/destination to the next string location
        //
        Destination = Destination + EfiStrSize ((CHAR16 *) Source);
        Source      = Source + EfiStrSize ((CHAR16 *) Source);
      }
      
      //
      // This copies the new string to the destination buffer
      //
      EfiStrCpy ((CHAR16 *) Destination, (CHAR16 *) String);

      //
      // Adjust the size of the changed string pack by adding the size of the new string
      // along with the size of the additional offset entry for the new string
      //
      StringPackBuffer->Header.Length = (UINT32) ((UINTN) StringPackBuffer->Header.Length + EfiStrSize (String) + sizeof (RELOFST));

      //
      // Advance the buffers to point to the next spots.
      //
      StringPackBuffer  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPackBuffer->Header.Length);
      StringPack        = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);
      Finished          = TRUE;
      continue;
    }
    //
    // This isn't the language of the stringpack we were asked to add a string to
    // so we need to copy it to the new buffer.
    //
    EfiCopyMem (&StringPackBuffer->Header, &StringPack->Header, StringPack->Header.Length);

    //
    // Advance the buffers to point to the next spots.
    //
    StringPackBuffer  = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPackBuffer) + StringPack->Header.Length);
    StringPack        = (EFI_HII_STRING_PACK *) ((CHAR8 *) (StringPack) + StringPack->Header.Length);
  }
  
  //
  // If we didn't copy the new data to a stringpack yet
  //
  if (!Finished) {
    PackDestination = (RELOFST *) (StringPackBuffer + 1);
    //
    // Pointing to a new string pack location
    //
    StringPackBuffer->Header.Length = (UINT32)
      (
        sizeof (EFI_HII_STRING_PACK) -
        sizeof (EFI_STRING) +
        sizeof (RELOFST) +
        sizeof (RELOFST) +
        EfiStrSize (Language) +
        EfiStrSize (String)
      );
    StringPackBuffer->Header.Type           = EFI_HII_STRING;
    StringPackBuffer->LanguageNameString    = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);
    StringPackBuffer->PrintableLanguageName = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);
    StringPackBuffer->Attributes            = 0;
    PackDestination[0]                      = (UINT16) ((UINTN) &PackDestination[3] - (UINTN) StringPackBuffer);
    PackDestination[1]                      = (UINT16) (PackDestination[0] + EfiStrSize (Language));
    PackDestination[2]                      = (UINT16) 0;

    //
    // The first string location will be set to destination.  The minimum number of strings
    // associated with a stringpack will always be token 0 stored as the languagename (e.g. ENG, SPA, etc)
    // and token 1 as the new string being added and and null entry for the stringpointers
    //
    Destination = (CHAR8 *) &PackDestination[3];

    //
    // Copy the language name string to the new buffer
    //
    EfiStrCpy ((CHAR16 *) Destination, Language);

    //
    // Advance the destination to the new empty spot
    //
    Destination = Destination + EfiStrSize (Language);

    //
    // Copy the string to the new buffer
    //
    EfiStrCpy ((CHAR16 *) Destination, String);

    //
    // Since we are starting with a new string pack - we know the new string is token 1
    //
    *StringToken = (UINT16) 1;
  }

  //
  // Zero out the original buffer and copy the updated data in the new buffer to the old buffer
  //
  EfiZeroMem (StringBuffer, DEFAULT_STRING_BUFFER_SIZE);
  EfiCopyMem (StringBuffer, NewBuffer, DEFAULT_STRING_BUFFER_SIZE);

  //
  // Free the newly created buffer since we don't need it anymore
  //
  gBS->FreePool (NewBuffer);
  return EFI_SUCCESS;
}
Пример #21
0
EFI_STATUS
AmdFchWheaInitEntryEinj (
  VOID
  )
{
  EFI_ACPI_SUPPORT_PROTOCOL       *AcpiSupport;
  EFI_STATUS                      Status;
  INTN                            Index;
  UINTN                           Handle;
  EFI_ACPI_TABLE_VERSION          Version;
  EFI_ACPI_DESCRIPTION_HEADER     *Table;
  EFI_ACPI_DESCRIPTION_HEADER     *NewTable;

  Status = gBS->LocateProtocol (
                  &gEfiAcpiSupportGuid,
                  NULL,
                  &AcpiSupport
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Search EINJ table
  //
  Index  = 0;
  Handle = 0;
  do {
    Table  = NULL;
    Status = AcpiSupport->GetAcpiTable (
                            AcpiSupport,
                            Index,
                            &Table,
                            &Version,
                            &Handle
                            );
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // Check Signture and update EINJ table
    //
    if (Table->Signature == 0x4A4E4945) {
      //
      // allocate memory for new Table
      //
      Status = gBS->AllocatePool (
                      EfiReservedMemoryType,
                      MAX_EINJ_SIZE,
                      &NewTable
                      );
      if (Status != EFI_SUCCESS) {
        return Status;
      }
      EfiZeroMem (NewTable, MAX_EINJ_SIZE);
      //
      // Copy Table
      //
      EfiCopyMem (NewTable, Table, Table->Length);
      //
      // Update new table
      //
      AmdFchUpdateEinj (NewTable);

      if (!EFI_ERROR (Status)) {
      // Patch EINJ table here and save table back.

        //
        // Remove previous table
        //
        gBS->FreePool (Table);
        Table = NULL;
        Status = AcpiSupport->SetAcpiTable (
                                AcpiSupport,
                                Table,
                                TRUE,
                                Version,
                                &Handle
                                );
        //
        // Add new table
        //
        Handle = 0;
        Status = AcpiSupport->SetAcpiTable (
                                AcpiSupport,
                                NewTable,
                                TRUE,
                                Version,
                                &Handle
                                );
        gBS->FreePool (NewTable);
        return Status;
      }
      gBS->FreePool (NewTable);
    }
    gBS->FreePool (Table);
    Index++;
  } while (TRUE);

  return Status;
}
Пример #22
0
EFI_STATUS
EFIAPI
WinNtConsoleDriverBindingStart (
    IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
    IN  EFI_HANDLE                   Handle,
    IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
)
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    This - add argument and description to function comment
// TODO:    Handle - add argument and description to function comment
// TODO:    RemainingDevicePath - add argument and description to function comment
{
    EFI_STATUS                      Status;
    EFI_WIN_NT_IO_PROTOCOL          *WinNtIo;
    WIN_NT_SIMPLE_TEXT_PRIVATE_DATA *Private;

    //
    // Grab the IO abstraction we need to get any work done
    //
    Status = gBS->OpenProtocol (
                 Handle,
                 &gEfiWinNtIoProtocolGuid,
                 &WinNtIo,
                 This->DriverBindingHandle,
                 Handle,
                 EFI_OPEN_PROTOCOL_BY_DRIVER
             );
    if (EFI_ERROR (Status)) {
        return Status;
    }

    Status = gBS->AllocatePool (
                 EfiBootServicesData,
                 sizeof (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA),
                 &Private
             );
    if (EFI_ERROR (Status)) {
        goto Done;
    }

    EfiZeroMem (Private, sizeof (WIN_NT_SIMPLE_TEXT_PRIVATE_DATA));

    Private->Signature  = WIN_NT_SIMPLE_TEXT_PRIVATE_DATA_SIGNATURE;
    Private->Handle     = Handle;
    Private->WinNtIo    = WinNtIo;
    Private->WinNtThunk = WinNtIo->WinNtThunk;

    WinNtSimpleTextOutOpenWindow (Private);
    WinNtSimpleTextInAttachToWindow (Private);

    Status = gBS->InstallMultipleProtocolInterfaces (
                 &Handle,
                 &gEfiSimpleTextOutProtocolGuid,
                 &Private->SimpleTextOut,
                 &gEfiSimpleTextInProtocolGuid,
                 &Private->SimpleTextIn,
                 NULL
             );
    if (!EFI_ERROR (Status)) {
        return Status;
    }

Done:
    gBS->CloseProtocol (
        Handle,
        &gEfiWinNtIoProtocolGuid,
        This->DriverBindingHandle,
        Handle
    );
    if (Private != NULL) {

        EfiLibFreeUnicodeStringTable (Private->ControllerNameTable);

        if (Private->NtOutHandle != NULL) {
            Private->WinNtThunk->CloseHandle (Private->NtOutHandle);
        }

        if (Private->SimpleTextIn.WaitForKey != NULL) {
            gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
        }

        gBS->FreePool (Private);
    }

    return Status;
}
Пример #23
0
EFI_DEBUG_STATUS
DebuggerCallStack (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
/*++

Routine Description:

  DebuggerCommand - CallStack
  
Arguments:

  CommandArg      - The argument for this command
  DebuggerPrivate - EBC Debugger private data structure
  InterruptType   - Interrupt type.
  SystemContext   - EBC system context.

Returns:

  EFI_DEBUG_CONTINUE - formal return value
  
--*/
{
  INTN                           Index;
  UINTN                          SubIndex;
  CHAR8                          *FuncName;
  EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry;
  BOOLEAN                        ShowParameter;
  UINTN                          ParameterNumber;

  ShowParameter = FALSE;
  ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER;

  //
  // Check argument
  //
  if (CommandArg != NULL) {
    if (EfiStriCmp (CommandArg, L"c") == 0) {
      //
      // Clear Call-Stack
      //
      DebuggerPrivate->CallStackEntryCount = 0;
      EfiZeroMem (DebuggerPrivate->CallStackEntry, sizeof(DebuggerPrivate->CallStackEntry));
      EDBPrint (L"Call-Stack is cleared\n");
      return EFI_DEBUG_CONTINUE;
    } else if (EfiStriCmp (CommandArg, L"p") == 0) {
      //
      // Print Call-Stack with parameter
      //
      ShowParameter = TRUE;
      CommandArg = StrGetNextTokenLine (L" ");
      if (CommandArg != NULL) {
        //
        // Try to get the parameter number
        //
        ParameterNumber = Atoi (CommandArg);
        if (ParameterNumber > 16) {
          EDBPrint (L"Call-Stack argument Invalid\n");
          return EFI_DEBUG_CONTINUE;
        }
      }
    } else {
      EDBPrint (L"Call-Stack argument Invalid\n");
      return EFI_DEBUG_CONTINUE;
    }
  }

  //
  // Check CallStack Entry Count
  //
  if (DebuggerPrivate->CallStackEntryCount == 0) {
    EDBPrint (L"No Call-Stack\n");
    return EFI_DEBUG_CONTINUE;
  } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
    EDBPrint (L"Call-Stack Crash, re-initialize!\n");
    DebuggerPrivate->CallStackEntryCount = 0;
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Go through each CallStack entry and print
  //
  EDBPrint (L"Call-Stack (TOP):\n");
  EDBPrint (L"         Caller             Callee        Name\n");
  EDBPrint (L"  ================== ================== ========\n");
//EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n");
  for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) {
    //
    // Get CallStack and print
    //
    CallStackEntry = &DebuggerPrivate->CallStackEntry[Index];
    EDBPrint (
      L"  0x%016lx 0x%016lx",
      CallStackEntry->SourceAddress,
      CallStackEntry->DestAddress
      );
    FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress);
    if (FuncName != NULL) {
      EDBPrint (L" %a()", FuncName);
    }
    EDBPrint (L"\n");

    if (ShowParameter) {
      //
      // Print parameter
      //
      if (sizeof(UINTN) == sizeof(UINT64)) {
        EDBPrint (
          L"    Parameter Address (0x%016lx) (\n",
          CallStackEntry->ParameterAddr
          );
        if (ParameterNumber == 0) {
          EDBPrint (L"        )\n");
          continue;
        }
        //
        // Print each parameter
        //
        for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
          if (SubIndex % 2 == 0) {
            EDBPrint (L"        ");
          }
          EDBPrint (
            L"0x%016lx, ",
            CallStackEntry->Parameter[SubIndex]
            );
          if (SubIndex % 2 == 1) {
            EDBPrint (L"\n");
          }
        }
        if (SubIndex % 2 == 0) {
          EDBPrint (L"        ");
        }
        EDBPrint (
          L"0x%016lx\n",
          CallStackEntry->Parameter[SubIndex]
          );
        EDBPrint (L"        )\n");
        //
        // break only for parameter
        //
        if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
            (Index != 0)) {
          if (SetPageBreak ()) {
            break;
          }
        }
      } else {
        EDBPrint (
          L"    Parameter Address (0x%08x) (\n",
          CallStackEntry->ParameterAddr
          );
        if (ParameterNumber == 0) {
          EDBPrint (L"        )\n");
          continue;
        }
        //
        // Print each parameter
        //
        for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
          if (SubIndex % 4 == 0) {
            EDBPrint (L"        ");
          }
          EDBPrint (
            L"0x%08x, ",
            CallStackEntry->Parameter[SubIndex]
            );
          if (SubIndex % 4 == 3) {
            EDBPrint (L"\n");
          }
        }
        if (SubIndex % 4 == 0) {
          EDBPrint (L"        ");
        }
        EDBPrint (
          L"0x%08x\n",
          CallStackEntry->Parameter[SubIndex]
          );
        EDBPrint (L"        )\n");
        //
        // break only for parameter
        //
        if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
            (Index != 0)) {
          if (SetPageBreak ()) {
            break;
          }
        }
      }
    }
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}
Пример #24
0
/********************************************************************************
 * Name: AmdFchWheaInitEntry
 *
 * Description
 *   AmdFchWheaInit Entrypoint
 *
 * Input
 *
 * Output
 *   EFI_UNSUPPORTED : unsupported function
 *
 *********************************************************************************/
EFI_STATUS
AmdFchWheaInitEntry (
  IN EFI_HANDLE                             ImageHandle,
  IN EFI_SYSTEM_TABLE                       *SystemTable
  )
{
  EFI_STATUS                                Status;
  BOOLEAN                                   InSmm;
  FCH_INIT_PROTOCOL                         *AmdFchInit;
  EFI_SMM_BASE_PROTOCOL                     *SmmBase;
  FCH_SMM_SW_DISPATCH_PROTOCOL              *AmdSwDispatch;
  FCH_SMM_SW_REGISTER_CONTEXT               SwRegisterContext;
  EFI_HANDLE                                SwHandle;
  FCH_SMM_MISC_DISPATCH_PROTOCOL            *AmdFchSmmMiscDispatch;
  FCH_SMM_MISC_REGISTER_CONTEXT             MiscRegisterContext;
  EFI_HANDLE                                MiscHandle;
  EFI_SMM_SYSTEM_TABLE                      *mSmst;
  EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL                  *ImageDevicePath;
  EFI_DEVICE_PATH_PROTOCOL                  *CompleteFilePath;
  EFI_HANDLE                                SmmImageHandle;
  EFI_EVENT                                 InstallAmdTableEvent;
  EFI_HANDLE                                Handle;
  UINT8                                     *buffer;

  InSmm    = FALSE;
  DxeInitializeDriverLib (ImageHandle, SystemTable);

  Status = gBS->LocateProtocol (
                  &gFchInitProtocolGuid,
                  NULL,
                  &AmdFchInit
                  );
  ASSERT_EFI_ERROR (Status);

  if (AmdFchInit->FchPolicy.Gpp.PcieAer == 0) {
    return Status;
  }

  Status = gBS->LocateProtocol (
                  &gEfiSmmBaseProtocolGuid,
                  NULL,
                  &SmmBase
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SmmBase->GetSmstLocation (
             SmmBase,
             &mSmst
             );
  SmmBase->InSmm (
             SmmBase,
             &InSmm
             );

  if (!InSmm) {
    Status = EfiCreateEventReadyToBoot (
               EFI_TPL_CALLBACK,
               AmdWheaCheckInstallTables,
               NULL,
               &InstallAmdTableEvent
               );

    //
    //  Allocate memory and Initialize for Data block
    //
    Status = gBS->AllocatePool (
                    EfiReservedMemoryType,
                    sizeof (AMD_FCH_WHEA_EINJ_BUFFER),
                    (VOID **)&buffer
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    EfiZeroMem (buffer, sizeof (AMD_FCH_WHEA_EINJ_BUFFER));

    mEinjData = (AMD_FCH_WHEA_EINJ_BUFFER *)buffer;
    mEinjData->Valid             = FALSE;
    mEinjData->PlatformEinjValid = FALSE;

    //
    //  Allocate memory and Initialize for Error Data block
    //
    Status = gBS->AllocatePool (
                    EfiReservedMemoryType,
                    MAX_ERROR_BLOCK_SIZE,
                    (VOID **)&buffer
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    EfiZeroMem (buffer, MAX_ERROR_BLOCK_SIZE);

    mEinjData->AmdHwErrBlk = (GENERIC_ERROR_STATUS_BLOCK *)buffer;

    AmdErrBlkAddressUpdate ();

    Handle = ImageHandle;
    Status = gBS->InstallProtocolInterface (
                    &Handle,
                    &mEfiAmdFchWheaDataGuid,
                    EFI_NATIVE_INTERFACE,
                    mEinjData
                    );
    if (EFI_ERROR (Status)) {
      return (Status);
    }

    if (ImageHandle != NULL) {
      Status = gBS->HandleProtocol (
                      ImageHandle,
                      &gEfiLoadedImageProtocolGuid,
                      &LoadedImage
                      );
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Status = gBS->HandleProtocol (
                      LoadedImage->DeviceHandle,
                      &gEfiDevicePathProtocolGuid,
                      (VOID*) &ImageDevicePath
                      );
      if (EFI_ERROR (Status)) {
        return Status;
      }

      CompleteFilePath = AppendDevicePath (
                           ImageDevicePath,
                           LoadedImage->FilePath
                           );

      // Load the image in memory to SMRAM, this automatically triggers SMI
      SmmBase->Register (
                 SmmBase,
                 CompleteFilePath,
                 NULL,
                 0,
                 &SmmImageHandle,
                 FALSE
                 );
    }
  } else {
    Status = gBS->LocateProtocol (
                    &mEfiAmdFchWheaDataGuid,
                    NULL,
                    &mEinjData
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gBS->LocateProtocol (
                    &gFchSmmSwDispatchProtocolGuid,
                    NULL,
                    &AmdSwDispatch
                    );
    ASSERT_EFI_ERROR (Status);

    SwRegisterContext.AmdSwValue  = EINJ_TRIGGER_ACTION_SWSMI;
    Status = AmdSwDispatch->Register (
                              AmdSwDispatch,
                              AmdSmiEinjTriggerActionCallBack,
                              &SwRegisterContext,
                              &SwHandle
                              );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gBS->LocateProtocol (
                    &gFchSmmMiscDispatchProtocolGuid,
                    NULL,
                    &AmdFchSmmMiscDispatch
                    );
    ASSERT_EFI_ERROR (Status);

    MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88;
    MiscRegisterContext.SmiStatusBit = BIT21;
    MiscRegisterContext.Order        = 0x80;
    Status = AmdFchSmmMiscDispatch->Register (
                                      AmdFchSmmMiscDispatch,
                                      AmdMiscFchWheaHwSmiCallback,
                                      &MiscRegisterContext,
                                      &MiscHandle
                                      );

    MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88;
    MiscRegisterContext.SmiStatusBit = BIT22;
    MiscRegisterContext.Order        = 0x80;
    Status = AmdFchSmmMiscDispatch->Register (
                                      AmdFchSmmMiscDispatch,
                                      AmdMiscFchWheaHwSmiCallback,
                                      &MiscRegisterContext,
                                      &MiscHandle
                                      );

    MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88;
    MiscRegisterContext.SmiStatusBit = BIT23;
    MiscRegisterContext.Order        = 0x80;
    Status = AmdFchSmmMiscDispatch->Register (
                                      AmdFchSmmMiscDispatch,
                                      AmdMiscFchWheaHwSmiCallback,
                                      &MiscRegisterContext,
                                      &MiscHandle
                                      );

    MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88;
    MiscRegisterContext.SmiStatusBit = BIT24;
    MiscRegisterContext.Order        = 0x80;
    Status = AmdFchSmmMiscDispatch->Register (
                                      AmdFchSmmMiscDispatch,
                                      AmdMiscFchWheaHwSmiCallback,
                                      &MiscRegisterContext,
                                      &MiscHandle
                                      );

    ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB4) &= ~(BIT11 + BIT13 + BIT15 + BIT17);
    ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB4) |= (BIT10 + BIT12 + BIT14 + BIT16);
  }
  return Status;
}
Пример #25
0
EFI_STATUS
ExtractDataFromHiiHandle (
  IN      EFI_HII_HANDLE      HiiHandle,
  IN OUT  UINT16              *ImageLength,
  OUT     UINT8               *DefaultImage,
  OUT     EFI_GUID            *Guid
  )
/*++

Routine Description:

  Extract information pertaining to the HiiHandle
  
Arguments:
  
  HiiHandle       - Hii handle
  
  ImageLength     - For input, length of DefaultImage;
                    For output, length of actually required
                    
  DefaultImage    - Image buffer prepared by caller
  
  Guid            - Guid information about the form
  
Returns: 

  EFI_OUT_OF_RESOURCES    - No enough buffer to allocate
  
  EFI_BUFFER_TOO_SMALL    - DefualtImage has no enough ImageLength
  
  EFI_SUCCESS             - Successfully extract data from Hii database.
  
  
--*/
{
  EFI_STATUS        Status;
  EFI_HII_PROTOCOL  *Hii;
  UINTN             DataLength;
  UINT8             *RawData;
  UINT8             *OldData;
  UINTN             Index;
  UINTN             Temp;
  UINTN             SizeOfNvStore;
  UINTN             CachedStart;

  DataLength    = DEFAULT_FORM_BUFFER_SIZE;
  SizeOfNvStore = 0;
  CachedStart   = 0;

  Status        = GetHiiInterface (&Hii);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Allocate space for retrieval of IFR data
  //
  RawData = EfiLibAllocateZeroPool ((UINTN) DataLength);
  if (RawData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get all the forms associated with this HiiHandle
  //
  Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData);

  if (EFI_ERROR (Status)) {
    gBS->FreePool (RawData);

    //
    // Allocate space for retrieval of IFR data
    //
    RawData = EfiLibAllocateZeroPool ((UINTN) DataLength);
    if (RawData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Get all the forms associated with this HiiHandle
    //
    Status = Hii->GetForms (Hii, HiiHandle, 0, &DataLength, RawData);
  }

  OldData = RawData;

  //
  // Point RawData to the beginning of the form data
  //
  RawData = (UINT8 *) ((UINTN) RawData + sizeof (EFI_HII_PACK_HEADER));

  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
    switch (RawData[Index]) {
    case EFI_IFR_FORM_SET_OP:
      //
      // Copy the GUID information from this handle
      //
      EfiCopyMem (Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
      break;

    case EFI_IFR_ONE_OF_OP:
    case EFI_IFR_CHECKBOX_OP:
    case EFI_IFR_NUMERIC_OP:
    case EFI_IFR_DATE_OP:
    case EFI_IFR_TIME_OP:
    case EFI_IFR_PASSWORD_OP:
    case EFI_IFR_STRING_OP:
      //
      // Remember, multiple op-codes may reference the same item, so let's keep a running
      // marker of what the highest QuestionId that wasn't zero length.  This will accurately
      // maintain the Size of the NvStore
      //
      if (((EFI_IFR_ONE_OF *) &RawData[Index])->Width != 0) {
        Temp = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;
        if (SizeOfNvStore < Temp) {
          SizeOfNvStore = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId + ((EFI_IFR_ONE_OF *) &RawData[Index])->Width;
        }
      }
    }

    Index = RawData[Index + 1] + Index;
  }
    
  //
  // Return an error if buffer is too small
  //
  if (SizeOfNvStore > *ImageLength) {
    gBS->FreePool (OldData);
    *ImageLength = (UINT16) SizeOfNvStore;
    return EFI_BUFFER_TOO_SMALL;
  }

  EfiZeroMem (DefaultImage, SizeOfNvStore);

  //
  // Copy the default image information to the user's buffer
  //
  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
    switch (RawData[Index]) {
    case EFI_IFR_ONE_OF_OP:
      CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId;
      break;

    case EFI_IFR_ONE_OF_OPTION_OP:
      if (((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Flags & EFI_IFR_FLAG_DEFAULT) {
        EfiCopyMem (&DefaultImage[CachedStart], &((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value, 2);
      }
      break;

    case EFI_IFR_CHECKBOX_OP:
      DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId] = ((EFI_IFR_CHECK_BOX *) &RawData[Index])->Flags;
      break;

    case EFI_IFR_NUMERIC_OP:
      EfiCopyMem (
        &DefaultImage[((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId],
        &((EFI_IFR_NUMERIC *) &RawData[Index])->Default,
        2
        );
      break;

    }

    Index = RawData[Index + 1] + Index;
  }

  *ImageLength = (UINT16) SizeOfNvStore;

  //
  // Free our temporary repository of form data
  //
  gBS->FreePool (OldData);

  return EFI_SUCCESS;
}
Пример #26
0
EFI_STATUS
EFIAPI
GetProposedResources (
  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
  IN EFI_HANDLE                                       RootBridgeHandle,
  OUT VOID                                            **Configuration
  )
/*++

Routine Description:
  This function returns the proposed resource settings for the specified 
  PCI Root Bridge

Arguments:
  This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
  RootBridgeHandle -- The PCI Root Bridge handle
  Configuration -- The pointer to the pointer to the PCI I/O 
                   and memory resource descriptor
    
Returns:

--*/
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_INVALID_PARAMETER - add return value to function comment
{
  EFI_LIST_ENTRY                    *List;
  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance;
  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance;
  UINTN                             Index;
  UINTN                             Number;
  VOID                              *Buffer;
  UINT8                             *Temp;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
  EFI_STATUS                        Status;
  UINT64                            ResStatus;

  Buffer  = NULL;
  Number  = 0;
  //
  // Get the Host Bridge Instance from the resource allocation protocol
  //
  HostBridgeInstance  = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
  List                = HostBridgeInstance->Head.ForwardLink;

  //
  // Enumerate the root bridges in this host bridge
  //
  while (List != &HostBridgeInstance->Head) {
    RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
    if (RootBridgeHandle == RootBridgeInstance->Handle) {
      for (Index = 0; Index < TypeBus; Index++) {
        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
          Number++;
        }
      }

      if (Number > 0) {
        Status = gBS->AllocatePool (
                        EfiBootServicesData,
                        Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
                        &Buffer
                        );

        if (EFI_ERROR (Status)) {
          return EFI_OUT_OF_RESOURCES;
        }

        EfiZeroMem (Buffer, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Number + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
      } else {
        return EFI_INVALID_PARAMETER;
      }

      Temp = Buffer;
      for (Index = 0; Index < TypeBus; Index++) {
        if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
          ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
          ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;

          switch (Index) {
          case TypeIo:
            //
            // Io
            //
            ptr->Desc                   = 0x8A;
            ptr->Len                    = 0x2B;
            ptr->ResType                = 1;
            ptr->GenFlag                = 0;
            ptr->SpecificFlag           = 0;
            ptr->AddrRangeMin           = RootBridgeInstance->ResAllocNode[Index].Base;
            ptr->AddrRangeMax           = 0;
            ptr->AddrTranslationOffset  = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
            ptr->AddrLen                = RootBridgeInstance->ResAllocNode[Index].Length;
            break;

          case TypeMem32:
            //
            // Memory 32
            //
            ptr->Desc                   = 0x8A;
            ptr->Len                    = 0x2B;
            ptr->ResType                = 0;
            ptr->GenFlag                = 0;
            ptr->SpecificFlag           = 0;
            ptr->AddrSpaceGranularity   = 32;
            ptr->AddrRangeMin           = RootBridgeInstance->ResAllocNode[Index].Base;
            ptr->AddrRangeMax           = 0;
            ptr->AddrTranslationOffset  = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
            ptr->AddrLen                = RootBridgeInstance->ResAllocNode[Index].Length;
            break;

          case TypePMem32:
            //
            // Prefetch memory 32
            //
            ptr->Desc                   = 0x8A;
            ptr->Len                    = 0x2B;
            ptr->ResType                = 0;
            ptr->GenFlag                = 0;
            ptr->SpecificFlag           = 6;
            ptr->AddrSpaceGranularity   = 32;
            ptr->AddrRangeMin           = 0;
            ptr->AddrRangeMax           = 0;
            ptr->AddrTranslationOffset  = EFI_RESOURCE_NONEXISTENT;
            ptr->AddrLen                = 0;
            break;

          case TypeMem64:
            //
            // Memory 64
            //
            ptr->Desc                   = 0x8A;
            ptr->Len                    = 0x2B;
            ptr->ResType                = 0;
            ptr->GenFlag                = 0;
            ptr->SpecificFlag           = 0;
            ptr->AddrSpaceGranularity   = 64;
            ptr->AddrRangeMin           = 0;
            ptr->AddrRangeMax           = 0;
            ptr->AddrTranslationOffset  = EFI_RESOURCE_NONEXISTENT;
            ptr->AddrLen                = 0;
            break;

          case TypePMem64:
            //
            // Prefetch memory 64
            //
            ptr->Desc                   = 0x8A;
            ptr->Len                    = 0x2B;
            ptr->ResType                = 0;
            ptr->GenFlag                = 0;
            ptr->SpecificFlag           = 6;
            ptr->AddrSpaceGranularity   = 64;
            ptr->AddrRangeMin           = 0;
            ptr->AddrRangeMax           = 0;
            ptr->AddrTranslationOffset  = EFI_RESOURCE_NONEXISTENT;
            ptr->AddrLen                = 0;
            break;
          }

          Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
        }
      }

      ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc      = 0x79;
      ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum  = 0x0;

      *Configuration = Buffer;

      return EFI_SUCCESS;
    }

    List = List->ForwardLink;
  }

  return EFI_INVALID_PARAMETER;
}
EFI_STATUS
LoadBmp (
  IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL  **BltBuffer,
  IN UINTN                          *Width,
  IN UINTN                          *Height
  )
/*++

Routine Description:

  Assistant function for loading a bmp file

Arguments:

  BltBuffer - Buffer for loading a bmp file
  Width     - Width of the bmp file
  Height    - Height of the bmp file

Returns:

  EFI_SUCCESS - No error returns

--*/
{

  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
  EFI_STATUS                    Status;
  UINTN                         IndexX;
  UINTN                         IndexY;
  UINTN                         m;
  UINTN                         Wx;
  UINTN                         Hy;

  Wx  = 150;
  Hy  = 150;

  Status = gtBS->AllocatePool (
                   EfiBootServicesData,
                   Wx * Hy * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL),
                   (VOID **) &Blt
                   );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  EfiZeroMem (Blt, Wx * Hy * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

  for (IndexY = 0; IndexY < Hy / 3; IndexY++) {
    for (IndexX = 0; IndexX < Wx; IndexX++) {
      m               = IndexY * Wx + IndexX;

      Blt[m].Blue     = 0xFF;
      Blt[m].Green    = 0x00;
      Blt[m].Red      = 0x00;
      Blt[m].Reserved = 0x00;
    }
  }

  for (IndexY = Hy / 3; IndexY < (Hy / 3) * 2; IndexY++) {
    for (IndexX = 0; IndexX < Wx; IndexX++) {
      m               = IndexY * Wx + IndexX;

      Blt[m].Blue     = 0x00;
      Blt[m].Green    = 0xFF;
      Blt[m].Red      = 0x00;
      Blt[m].Reserved = 0x00;
    }
  }

  for (IndexY = (Hy / 3) * 2; IndexY < Hy; IndexY++) {
    for (IndexX = 0; IndexX < Wx; IndexX++) {
      m               = IndexY * Wx + IndexX;

      Blt[m].Blue     = 0x00;
      Blt[m].Green    = 0x00;
      Blt[m].Red      = 0xFF;
      Blt[m].Reserved = 0x00;
    }
  }

  *BltBuffer  = Blt;
  *Width      = Wx;
  *Height     = Hy;
  return EFI_SUCCESS;
}
Пример #28
0
VOID
EFIAPI
InvokeAmdInitLate (
    IN EFI_EVENT        Event,
    IN VOID             *Context
)
/*++

Routine Description:

  Invoke AmdinitLate entry point. This function gets called
  each time the EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled

Arguments & Return Values: Standard event handling function prototype

--*/
{
    AMD_INTERFACE_PARAMS              AmdInterfaceParams;
    AGESA_STATUS                      AgesaStatus;
    AMD_DXE_INIT_LATE_PROTOCOL        AmdInitLateProtocol;
    EFI_HANDLE                        Handle;

    //
    // Prepare for AmdInitLate
    //
    EfiZeroMem (&AmdInterfaceParams, sizeof (AMD_INTERFACE_PARAMS));
    AmdInterfaceParams.StdHeader.ImageBasePtr = 0;
    AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM;
    AmdInterfaceParams.AllocationMethod = PostMemDram;
    AmdInterfaceParams.AgesaFunctionName = AMD_INIT_LATE;
    AgesaStatus = AmdCreateStruct (&AmdInterfaceParams);

    ((AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr)->StdHeader = AmdInterfaceParams.StdHeader;

    OemCustomizeInitLate (gBS, (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr);

    AgesaStatus = AmdInitLate ((AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr);

    OemHookAfterInitLate (gBS, (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr);

    if ((AgesaStatus == AGESA_CRITICAL) || (AgesaStatus == AGESA_FATAL)) {
        return;
    }

    mAgesaDxePrivate->LateParamsPtr = (AMD_LATE_PARAMS *)AmdInterfaceParams.NewStructPtr;

    //
    // Now Install the AmdDxeInitLateProtocol which helps notify any consumer
    // which is depending upon it.
    //
    AmdInitLateProtocol.Revision = AGESA_DXE_INIT_LATE_REV;
    Handle = NULL;
    gBS->InstallProtocolInterface (
        &Handle,
        &gAmdDxeInitLateProtocolGuid,
        EFI_NATIVE_INTERFACE,
        &AmdInitLateProtocol
    );
    //
    // Install the AMD_AGESA_DXE_PROTOCOL to notify OEM to override default value
    //
    Handle = NULL;

    gBS->InstallProtocolInterface (
        &Handle,
        &gAmdAgesaDxeProtocolGuid,
        EFI_NATIVE_INTERFACE,
        &mAgesaDxePrivate->CpuInterface
    );


    //
    // Install AgesaDxeMiscellaneous Protocol
    //
    Handle = NULL;
    gBS->CopyMem (
        &mAgesaDxePrivate->AgesaMiscServices.StdHeader,
        &AmdInterfaceParams.StdHeader,
        sizeof (AMD_CONFIG_PARAMS)
    );

    mAgesaDxePrivate->AgesaMiscServices.GetDimmInfo = AgesaGetDimmInfo;

    gBS->InstallProtocolInterface (
        &Handle,
        &gAmdAgesaDxeMiscServicesProtocolGuid,
        EFI_NATIVE_INTERFACE,
        &mAgesaDxePrivate->AgesaMiscServices
    );

    return;
}
Пример #29
0
VOID
WriteBootToOsPerformanceData (
  VOID
  )
/*++

Routine Description:

  Allocates a block of memory and writes performance data of booting to OS into it.

Arguments:

  None

Returns:

  None

--*/
{
  EFI_STATUS                Status;
  EFI_CPU_ARCH_PROTOCOL     *Cpu;
  EFI_PERFORMANCE_PROTOCOL  *DrvPerf;
  UINT32                    mAcpiLowMemoryLength;
  UINT32                    LimitCount;
  EFI_PERF_HEADER           mPerfHeader;
  EFI_PERF_DATA             mPerfData;
  EFI_GAUGE_DATA            *DumpData;
  EFI_HANDLE                *Handles;
  UINTN                     NoHandles;
  UINT8                     *Ptr;
  UINT8                     *PdbFileName;
  UINT32                    mIndex;
  UINT64                    Ticker;
  UINT64                    Freq;
  UINT32                    Duration;
  UINT64                    CurrentTicker;
  UINT64                    TimerPeriod;

  //
  // Retrive time stamp count as early as possilbe
  //
  Ticker = EfiReadTsc ();

  //
  // Get performance architecture protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiPerformanceProtocolGuid,
                  NULL,
                  &DrvPerf
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Get CPU frequency
  //
  Status = gBS->LocateProtocol (
                  &gEfiCpuArchProtocolGuid,
                  NULL,
                  &Cpu
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Get Cpu Frequency
  //
  Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod);
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Put Detailed performance data into memory
  //
  Handles = NULL;
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &NoHandles,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }

  //
  // Allocate a block of memory that contain performance data to OS
  // if it is not allocated yet.
  //
  if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    EfiReservedMemoryType,
                    4,
                    &mAcpiLowMemoryBase
                    );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (Handles);
      return ;
    }
  }

  mAcpiLowMemoryLength  = EFI_PAGES_TO_SIZE(4);
  Ptr                   = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (EFI_PERF_HEADER));
  LimitCount            = (mAcpiLowMemoryLength - sizeof (EFI_PERF_HEADER)) / sizeof (EFI_PERF_DATA);

  //
  // Initialize performance data structure
  //
  EfiZeroMem (&mPerfHeader, sizeof (EFI_PERF_HEADER));

  Freq                = DivU64x32 (1000000000000, (UINTN) TimerPeriod, NULL);

  mPerfHeader.CpuFreq = Freq;

  //
  // Record BDS raw performance data
  //
  mPerfHeader.BDSRaw = Ticker;

  //
  // Get DXE drivers performance
  //
  for (mIndex = 0; mIndex < NoHandles; mIndex++) {

    Ticker = 0;
    PdbFileName = NULL;
    DumpData = DrvPerf->GetGauge (
                          DrvPerf,    // Context
                          NULL,       // Handle
                          NULL,       // Token
                          NULL,       // Host
                          NULL        // PrecGauge
                          );
    while (DumpData) {
      if (DumpData->Handle == Handles[mIndex]) {
      	PdbFileName = &(DumpData->PdbFileName[0]);
      	if (DumpData->StartTick < DumpData->EndTick) {
      	  Ticker += (DumpData->EndTick - DumpData->StartTick);
      	}
      }

      DumpData = DrvPerf->GetGauge (
                            DrvPerf,  // Context
                            NULL,     // Handle
                            NULL,     // Token
                            NULL,     // Host
                            DumpData  // PrecGauge
                            );
    }

    Duration = (UINT32) DivU64x32 (
                          Ticker,
                          (UINT32) Freq,
                          NULL
                          );

    if (Duration > 0) {
      EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA));

      if (PdbFileName != NULL) {
        EfiAsciiStrCpy (mPerfData.Token, PdbFileName);
      }
      mPerfData.Duration = Duration;

      EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA));
      Ptr += sizeof (EFI_PERF_DATA);

      mPerfHeader.Count++;
      if (mPerfHeader.Count == LimitCount) {
        goto Done;
      }
    }
  }

  gBS->FreePool (Handles);

  //
  // Get inserted performance data
  //
  DumpData = DrvPerf->GetGauge (
                        DrvPerf,      // Context
                        NULL,         // Handle
                        NULL,         // Token
                        NULL,         // Host
                        NULL          // PrecGauge
                        );
  while (DumpData) {
    if ((DumpData->Handle) || (DumpData->StartTick > DumpData->EndTick)) {
      DumpData = DrvPerf->GetGauge (
                            DrvPerf,  // Context
                            NULL,     // Handle
                            NULL,     // Token
                            NULL,     // Host
                            DumpData  // PrecGauge
                            );
      continue;
    }

    EfiZeroMem (&mPerfData, sizeof (EFI_PERF_DATA));

    ConvertChar16ToChar8 ((UINT8 *) mPerfData.Token, DumpData->Token);
    mPerfData.Duration = (UINT32) DivU64x32 (
                                    DumpData->EndTick - DumpData->StartTick,
                                    (UINT32) Freq,
                                    NULL
                                    );

    EfiCopyMem (Ptr, &mPerfData, sizeof (EFI_PERF_DATA));
    Ptr += sizeof (EFI_PERF_DATA);

    mPerfHeader.Count++;
    if (mPerfHeader.Count == LimitCount) {
      goto Done;
    }

    DumpData = DrvPerf->GetGauge (
                          DrvPerf,    // Context
                          NULL,       // Handle
                          NULL,       // Token
                          NULL,       // Host
                          DumpData    // PrecGauge
                          );
  }

Done:

  mPerfHeader.Signiture = 0x66726550;

  //
  // Put performance data to memory
  //
  EfiCopyMem (
    (UINTN *) (UINTN) mAcpiLowMemoryBase,
    &mPerfHeader,
    sizeof (EFI_PERF_HEADER)
    );

  gRT->SetVariable (
        L"PerfDataMemAddr",
        &gEfiGenericVariableGuid,
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        sizeof (UINT32),
        (VOID *) &mAcpiLowMemoryBase
        );

  return ;
}
Пример #30
0
EFI_STATUS
TestRecoveryEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++

Routine Description:

  Test recovery library driver's entry point.

Arguments:

  ImageHandle   - the driver image handle.
  SystemTable   - the system table.

Returns:

  EFI_SUCCESS         - the driver is loaded successfully.
  EFI_ALREADY_STARTED - the driver has already been loaded before.

--*/
{
  EFI_STATUS                     Status;
  EFI_LOADED_IMAGE_PROTOCOL      *LoadedImage;
  TSL_INIT_PRIVATE_DATA          *Private;

  // Initialize driver lib
  EfiInitializeDriverLib (ImageHandle, SystemTable);

  //
  // Fill in the Unload() function
  //
  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&LoadedImage,
                  ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  LoadedImage->Unload = TslInitUnload;

  //
  // Open the TslInit protocol to perform the supported test.
  //
  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiTslInitInterfaceGuid,
                  NULL,
                  ImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Initialize the TslInit private data
  //
  Status = gBS->AllocatePool(
                  EfiBootServicesData,
                  sizeof (TSL_INIT_PRIVATE_DATA),
                  (VOID **)&Private
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  EfiZeroMem (Private, sizeof(TSL_INIT_PRIVATE_DATA));
  Private->Signature            = TSL_INIT_PRIVATE_DATA_SIGNATURE;
  Private->ImageHandle          = ImageHandle;
  Private->TslInit.Revision     = 0x10000;
  Private->TslInit.LibraryGuid  = gEfiTestRecoveryLibraryGuid;
  Private->TslInit.Open         = TslOpen;
  Private->TslInit.Close        = TslClose;

  //
  // Install TslInit protocol
  //
  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gEfiTslInitInterfaceGuid,
                  EFI_NATIVE_INTERFACE,
                  &(Private->TslInit)
                  );

  return Status;
}