/**
  The user Entry Point for module PciSioSerial. The user code starts with this function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializePciSioSerial (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gSerialControllerDriver,
             ImageHandle,
             &gPciSioSerialComponentName,
             &gPciSioSerialComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Initialize UART default setting in gSerialDevTempate
  //
  gSerialDevTemplate.SerialMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
  gSerialDevTemplate.SerialMode.DataBits = PcdGet8 (PcdUartDefaultDataBits);
  gSerialDevTemplate.SerialMode.Parity   = PcdGet8 (PcdUartDefaultParity);
  gSerialDevTemplate.SerialMode.StopBits = PcdGet8 (PcdUartDefaultStopBits);
  gSerialDevTemplate.UartDevicePath.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
  gSerialDevTemplate.UartDevicePath.DataBits = PcdGet8 (PcdUartDefaultDataBits);
  gSerialDevTemplate.UartDevicePath.Parity   = PcdGet8 (PcdUartDefaultParity);
  gSerialDevTemplate.UartDevicePath.StopBits = PcdGet8 (PcdUartDefaultStopBits);
  gSerialDevTemplate.ClockRate = PcdGet32 (PcdSerialClockRate);

  return Status;
}
Пример #2
0
/**
  Convert PEI performance log to FPDT String boot record.

  @param  IsStart                 TRUE if the performance log is start log.
  @param  Handle                  Pointer to environment specific context used
                                  to identify the component being measured.
  @param  Token                   Pointer to a Null-terminated ASCII string
                                  that identifies the component being measured.
  @param  Module                  Pointer to a Null-terminated ASCII string
                                  that identifies the module being measured.
  @param  Ticker                  64-bit time stamp.
  @param  Identifier              32-bit identifier. If the value is 0, the created record
                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.

  @retval EFI_SUCCESS              Add FPDT boot record.
  @retval EFI_OUT_OF_RESOURCES     There are not enough resources to record the measurement.
  @retval EFI_UNSUPPORTED          No matched FPDT record.

**/
EFI_STATUS
InsertPeiFpdtMeasurement (
  IN BOOLEAN      IsStart,
  IN CONST VOID   *Handle,  OPTIONAL
  IN CONST CHAR8  *Token,   OPTIONAL
  IN CONST CHAR8  *Module,  OPTIONAL
  IN UINT64       Ticker,
  IN UINT32       Identifier
  )
{
  EFI_HOB_GUID_TYPE                     *GuidHob;
  UINTN                                 PeiPerformanceSize;
  UINT8                                 *PeiFirmwarePerformance;
  FPDT_PEI_EXT_PERF_HEADER              *PeiPerformanceLogHeader;
  FPDT_RECORD_PTR                       FpdtRecordPtr;
  FPDT_BASIC_RECORD_INFO                RecordInfo;
  CONST VOID                            *ModuleGuid;
  UINTN                                 DestMax;
  UINTN                                 StrLength;
  CONST CHAR8                           *StringPtr;
  EFI_STATUS                            Status;
  UINT16                                PeiPerformanceLogEntries;
  UINT64                                TimeStamp;

  StringPtr = NULL;
  FpdtRecordPtr.RecordHeader = NULL;
  PeiPerformanceLogHeader = NULL;

  //
  // Get record info (type, size, ProgressID and Module Guid).
  //
  Status = GetFpdtRecordInfo (IsStart, Handle, Token, Module, &RecordInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // If PERF_START()/PERF_END() have specified the ProgressID,it has high priority.
  // !!! Note: If the Perf is not the known Token used in the core but have same
  // ID with the core Token, this case will not be supported.
  // And in currtnt usage mode, for the unkown ID, there is a general rule:
  // If it is start pref: the lower 4 bits of the ID should be 0.
  // If it is end pref: the lower 4 bits of the ID should not be 0.
  // If input ID doesn't follow the rule, we will adjust it.
  //
  if ((Identifier != 0) && (IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
    return EFI_UNSUPPORTED;
  } else if ((Identifier != 0) && (!IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
    if (IsStart && ((Identifier & 0x000F) != 0)) {
      Identifier &= 0xFFF0;
    } else if ((!IsStart) && ((Identifier & 0x000F) == 0)) {
      Identifier += 1;
    }
    RecordInfo.ProgressID = (UINT16)Identifier;
  }

  //
  // Get the number of PeiPerformanceLogEntries form PCD.
  //
  PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?
                                       PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :
                                       PcdGet8 (PcdMaxPeiPerformanceLogEntries));

  //
  // Create GUID HOB Data.
  //
  GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
  PeiFirmwarePerformance = NULL;
  while (GuidHob != NULL) {
    //
    // PEI Performance HOB was found, then return the existing one.
    //
    PeiFirmwarePerformance  = (UINT8*)GET_GUID_HOB_DATA (GuidHob);
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize > PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
      PeiPerformanceLogHeader->HobIsFull = TRUE;
    }
    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize <= PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
      FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + PeiPerformanceLogHeader->SizeOfAllEntries);
      break;
    }
    //
    // Previous HOB is used, then find next one.
    //
    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
  }

  if (GuidHob == NULL) {
    //
    // PEI Performance HOB was not found, then build one.
    //
    PeiPerformanceSize      = sizeof (FPDT_PEI_EXT_PERF_HEADER) +
                              MAX_RECORD_SIZE * PeiPerformanceLogEntries;
    PeiFirmwarePerformance  = (UINT8*)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize);
    if (PeiFirmwarePerformance != NULL) {
      ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
    }
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
    FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER));
  }

  if (PeiFirmwarePerformance == NULL) {
    //
    // there is no enough resource to store performance data
    //
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get the TimeStamp.
  //
  if (Ticker == 0) {
    Ticker    = GetPerformanceCounter ();
    TimeStamp = GetTimeInNanoSecond (Ticker);
  } else if (Ticker == 1) {
    TimeStamp = 0;
  } else {
    TimeStamp = GetTimeInNanoSecond (Ticker);
  }

  //
  // Get the ModuleGuid.
  //
  if (Handle != NULL) {
    ModuleGuid = Handle;
  } else {
    ModuleGuid = &gEfiCallerIdGuid;
  }

  switch (RecordInfo.Type) {
  case FPDT_GUID_EVENT_TYPE:
    FpdtRecordPtr.GuidEvent->Header.Type       = FPDT_GUID_EVENT_TYPE;
    FpdtRecordPtr.GuidEvent->Header.Length     = RecordInfo.RecordSize;;
    FpdtRecordPtr.GuidEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
    FpdtRecordPtr.GuidEvent->ProgressID        = RecordInfo.ProgressID;
    FpdtRecordPtr.GuidEvent->Timestamp         = TimeStamp;
    CopyMem (&FpdtRecordPtr.GuidEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
    break;

  case FPDT_GUID_QWORD_EVENT_TYPE:
    FpdtRecordPtr.GuidQwordEvent->Header.Type     = FPDT_GUID_QWORD_EVENT_TYPE;
    FpdtRecordPtr.GuidQwordEvent->Header.Length   = RecordInfo.RecordSize;;
    FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;
    FpdtRecordPtr.GuidQwordEvent->ProgressID      = RecordInfo.ProgressID;
    FpdtRecordPtr.GuidQwordEvent->Timestamp       = TimeStamp;
    PeiPerformanceLogHeader->LoadImageCount++;
    FpdtRecordPtr.GuidQwordEvent->Qword           = PeiPerformanceLogHeader->LoadImageCount;
    CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
    break;

  case FPDT_DYNAMIC_STRING_EVENT_TYPE:
    FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
    FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordInfo.RecordSize;
    FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
    FpdtRecordPtr.DynamicStringEvent->ProgressID        = RecordInfo.ProgressID;
    FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
    CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;

    if (Token != NULL) {
      StringPtr                     = Token;
    } else if (Module != NULL) {
      StringPtr                     = Module;
    }
    if (StringPtr != NULL && AsciiStrLen (StringPtr) != 0) {
      DestMax                       = (RecordInfo.RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
      StrLength                     = AsciiStrLen (StringPtr);
      if (StrLength >= DestMax) {
        StrLength                   = DestMax -1;
      }
      AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StrLength);
    } else {
      AsciiStrCpyS (FpdtRecordPtr.DynamicStringEvent->String, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, "unknown name");
    }
    break;

  default:
    //
    // Record is not supported in current PEI phase, return EFI_ABORTED
    //
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}
Пример #3
0
/**
  Initialize the Event Log and log events passed from the PEI phase.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  Out of memory.

**/
EFI_STATUS
EFIAPI
SetupEventLog (
  VOID
  )
{
  EFI_STATUS            Status;
  TCG_PCR_EVENT         *TcgEvent;
  EFI_PEI_HOB_POINTERS  GuidHob;
  EFI_PHYSICAL_ADDRESS  Lasa;
  
  if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
    Lasa = mTcgClientAcpiTemplate.Lasa;
  
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    EfiACPIMemoryNVS,
                    EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
                    &Lasa
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    mTcgClientAcpiTemplate.Lasa = Lasa;
    //
    // To initialize them as 0xFF is recommended 
    // because the OS can know the last entry for that.
    //
    SetMem ((VOID *)(UINTN)mTcgClientAcpiTemplate.Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
    mTcgClientAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);
  
  } else {
    Lasa = mTcgServerAcpiTemplate.Lasa;
  
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    EfiACPIMemoryNVS,
                    EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
                    &Lasa
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    mTcgServerAcpiTemplate.Lasa = Lasa;
    //
    // To initialize them as 0xFF is recommended 
    // because the OS can know the last entry for that.
    //
    SetMem ((VOID *)(UINTN)mTcgServerAcpiTemplate.Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
    mTcgServerAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);
  }

  GuidHob.Raw = GetHobList ();
  while (!EFI_ERROR (Status) && 
         (GuidHob.Raw = GetNextGuidHob (&gTcgEventEntryHobGuid, GuidHob.Raw)) != NULL) {
    TcgEvent    = GET_GUID_HOB_DATA (GuidHob.Guid);
    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
    Status = TcgDxeLogEventI (
               &mTcgDxeData,
               (TCG_PCR_EVENT_HDR*)TcgEvent,
               TcgEvent->Event
               );
  }

  return Status;
}
Пример #4
0
/**
  Function for 'timezone' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunTimeZone (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  //
  // non interactive
  //
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  UINT8         LoopVar;
  EFI_TIME      TheTime;
  BOOLEAN       Found;
  UINTN         TzMinutes;

  ShellStatus  = SHELL_SUCCESS;
  ProblemParam = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  if (PcdGet8(PcdShellSupportLevel) == 2) {
    Status = ShellCommandLineParse (TimeZoneParamList2, &Package, &ProblemParam, TRUE);
  } else {
    ASSERT(PcdGet8(PcdShellSupportLevel) == 3);
    Status = ShellCommandLineParseEx (TimeZoneParamList3, &Package, &ProblemParam, TRUE, TRUE);
  }
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    if (ShellCommandLineGetCount(Package) > 1) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    } else if (ShellCommandLineGetFlag(Package, L"-s")) {
      if ((ShellCommandLineGetFlag(Package, L"-l")) || (ShellCommandLineGetFlag(Package, L"-f"))) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-l or -f");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        ASSERT(PcdGet8(PcdShellSupportLevel) == 3);
        if (ShellCommandLineGetValue(Package, L"-s") == NULL) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellLevel2HiiHandle, L"-s");
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          //
          // Set the time zone
          //
          ShellStatus = CheckAndSetTimeZone(ShellCommandLineGetValue(Package, L"-s"));
          if (ShellStatus != SHELL_SUCCESS) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetValue(Package, L"-s"));
            ShellStatus = SHELL_INVALID_PARAMETER;
          }
        }
      }
    } else if (ShellCommandLineGetFlag(Package, L"-l")) {
      //
      // Print a list of all time zones
      //
      for ( LoopVar = 0
          ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])
          ; LoopVar++
         ){
        ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
      }
    } else {
      //
      // Get Current Time Zone Info
      //
      Status = gRT->GetTime(&TheTime, NULL);
      ASSERT_EFI_ERROR(Status);

      if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
        Found = FALSE;
        for ( LoopVar = 0
            ; LoopVar < sizeof(TimeZoneList) / sizeof(TimeZoneList[0])
            ; LoopVar++
           ){
          if (TheTime.TimeZone == TimeZoneList[LoopVar].TimeZone) {
            if (ShellCommandLineGetFlag(Package, L"-f")) {
              //
              //  Print all info about current time zone
              //
              ShellPrintHiiEx (-1, -1, NULL, TimeZoneList[LoopVar].StringId, gShellLevel2HiiHandle);
            } else {
              //
              // Print basic info only
              //
              if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
                TzMinutes = 0;
              } else {
                TzMinutes = (ABS(TheTime.TimeZone)) % 60;
              }

              ShellPrintHiiEx (
                -1,
                -1,
                NULL,
                STRING_TOKEN(STR_TIMEZONE_SIMPLE),
                gShellLevel2HiiHandle,
                TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(TheTime.TimeZone > 0?L"-":L"+"),
                TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60,
                TzMinutes);
            }
            Found = TRUE;
            break;
          }
        }
        if (!Found) {
          //
          // Print basic info only
          //
          if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
            TzMinutes = 0;
          } else {
            TzMinutes = (ABS(TheTime.TimeZone)) % 60;
          }
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN(STR_TIMEZONE_SIMPLE),
            gShellLevel2HiiHandle,
            TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(TheTime.TimeZone > 0?L"-":L"+"),
            TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60,
            TzMinutes);
          if (ShellCommandLineGetFlag(Package, L"-f")) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle);
          }
        }
      } else {
        //
        // TimeZone was EFI_UNSPECIFIED_TIMEZONE (unknown) from GetTime()
        //
      }
    }
  }

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  return (ShellStatus);
}
Пример #5
0
/**
  Function for 'date' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunDate (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  EFI_TIME      TheTime;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  CONST CHAR16  *Param1;

  ShellStatus  = SHELL_SUCCESS;
  ProblemParam = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (SfoParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      //
      // If there are 0 value parameters, then print the current date
      // else If there are any value paramerers, then print error
      //
      if (ShellCommandLineGetRawValue(Package, 1) == NULL) {
        //
        // get the current date
        //
        Status = gRT->GetTime(&TheTime, NULL);
        ASSERT_EFI_ERROR(Status);

        //
        // ShellPrintEx the date in SFO or regular format
        //
        if (ShellCommandLineGetFlag(Package, L"-sfo")) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_SFO_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year);
        } else {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DATE_FORMAT), gShellLevel2HiiHandle, TheTime.Month, TheTime.Day, TheTime.Year);
        }
      } else {
        if (PcdGet8(PcdShellSupportLevel) == 2) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          //
          // perform level 3 operation here.
          //
          Param1 = ShellCommandLineGetRawValue(Package, 1);
          if (Param1 == NULL) {
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            ShellStatus = CheckAndSetDate(Param1);
          }
          if (ShellStatus != SHELL_SUCCESS) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, Param1);
            ShellStatus = SHELL_INVALID_PARAMETER;
          }
        }
      }
    }
  }
  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  //
  // return the status
  //
  return (ShellStatus);
}
Пример #6
0
/**
  Remove exec permissions from all regions whose type is identified by
  PcdDxeNxMemoryProtectionPolicy.
**/
STATIC
VOID
InitializeDxeNxMemoryProtectionPolicy (
  VOID
  )
{
  UINTN                             MemoryMapSize;
  UINTN                             MapKey;
  UINTN                             DescriptorSize;
  UINT32                            DescriptorVersion;
  EFI_MEMORY_DESCRIPTOR             *MemoryMap;
  EFI_MEMORY_DESCRIPTOR             *MemoryMapEntry;
  EFI_MEMORY_DESCRIPTOR             *MemoryMapEnd;
  EFI_STATUS                        Status;
  UINT64                            Attributes;
  LIST_ENTRY                        *Link;
  EFI_GCD_MAP_ENTRY                 *Entry;
  EFI_PEI_HOB_POINTERS              Hob;
  EFI_HOB_MEMORY_ALLOCATION         *MemoryHob;
  EFI_PHYSICAL_ADDRESS              StackBase;

  //
  // Get the EFI memory map.
  //
  MemoryMapSize = 0;
  MemoryMap     = NULL;

  Status = gBS->GetMemoryMap (
                  &MemoryMapSize,
                  MemoryMap,
                  &MapKey,
                  &DescriptorSize,
                  &DescriptorVersion
                  );
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
  do {
    MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize);
    ASSERT (MemoryMap != NULL);
    Status = gBS->GetMemoryMap (
                    &MemoryMapSize,
                    MemoryMap,
                    &MapKey,
                    &DescriptorSize,
                    &DescriptorVersion
                    );
    if (EFI_ERROR (Status)) {
      FreePool (MemoryMap);
    }
  } while (Status == EFI_BUFFER_TOO_SMALL);
  ASSERT_EFI_ERROR (Status);

  StackBase = 0;
  if (PcdGetBool (PcdCpuStackGuard)) {
    //
    // Get the base of stack from Hob.
    //
    Hob.Raw = GetHobList ();
    while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
      MemoryHob = Hob.MemoryAllocation;
      if (CompareGuid(&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {
        DEBUG ((
          DEBUG_INFO,
          "%a: StackBase = 0x%016lx  StackSize = 0x%016lx\n",
          __FUNCTION__,
          MemoryHob->AllocDescriptor.MemoryBaseAddress,
          MemoryHob->AllocDescriptor.MemoryLength
          ));

        StackBase = MemoryHob->AllocDescriptor.MemoryBaseAddress;
        //
        // Ensure the base of the stack is page-size aligned.
        //
        ASSERT ((StackBase & EFI_PAGE_MASK) == 0);
        break;
      }
      Hob.Raw = GET_NEXT_HOB (Hob);
    }

    //
    // Ensure the base of stack can be found from Hob when stack guard is
    // enabled.
    //
    ASSERT (StackBase != 0);
  }

  DEBUG ((
    DEBUG_INFO,
    "%a: applying strict permissions to active memory regions\n",
    __FUNCTION__
    ));

  MergeMemoryMapForProtectionPolicy (MemoryMap, &MemoryMapSize, DescriptorSize);

  MemoryMapEntry = MemoryMap;
  MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);
  while ((UINTN) MemoryMapEntry < (UINTN) MemoryMapEnd) {

    Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type);
    if (Attributes != 0) {
      SetUefiImageMemoryAttributes (
        MemoryMapEntry->PhysicalStart,
        LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT),
        Attributes);

      //
      // Add EFI_MEMORY_RP attribute for page 0 if NULL pointer detection is
      // enabled.
      //
      if (MemoryMapEntry->PhysicalStart == 0 &&
          PcdGet8 (PcdNullPointerDetectionPropertyMask) != 0) {

        ASSERT (MemoryMapEntry->NumberOfPages > 0);
        SetUefiImageMemoryAttributes (
          0,
          EFI_PAGES_TO_SIZE (1),
          EFI_MEMORY_RP | Attributes);
      }

      //
      // Add EFI_MEMORY_RP attribute for the first page of the stack if stack
      // guard is enabled.
      //
      if (StackBase != 0 &&
          (StackBase >= MemoryMapEntry->PhysicalStart &&
           StackBase <  MemoryMapEntry->PhysicalStart +
                        LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT)) &&
          PcdGetBool (PcdCpuStackGuard)) {

        SetUefiImageMemoryAttributes (
          StackBase,
          EFI_PAGES_TO_SIZE (1),
          EFI_MEMORY_RP | Attributes);
      }

    }
    MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
  }
  FreePool (MemoryMap);

  //
  // Apply the policy for RAM regions that we know are present and
  // accessible, but have not been added to the UEFI memory map (yet).
  //
  if (GetPermissionAttributeForMemoryType (EfiConventionalMemory) != 0) {
    DEBUG ((
      DEBUG_INFO,
      "%a: applying strict permissions to inactive memory regions\n",
      __FUNCTION__
      ));

    CoreAcquireGcdMemoryLock ();

    Link = mGcdMemorySpaceMap.ForwardLink;
    while (Link != &mGcdMemorySpaceMap) {

      Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);

      if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved &&
          Entry->EndAddress < MAX_ADDRESS &&
          (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
            (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) {

        Attributes = GetPermissionAttributeForMemoryType (EfiConventionalMemory) |
                     (Entry->Attributes & CACHE_ATTRIBUTE_MASK);

        DEBUG ((DEBUG_INFO,
          "Untested GCD memory space region: - 0x%016lx - 0x%016lx (0x%016lx)\n",
          Entry->BaseAddress, Entry->EndAddress - Entry->BaseAddress + 1,
          Attributes));

        ASSERT(gCpu != NULL);
        gCpu->SetMemoryAttributes (gCpu, Entry->BaseAddress,
          Entry->EndAddress - Entry->BaseAddress + 1, Attributes);
      }

      Link = Link->ForwardLink;
    }
    CoreReleaseGcdMemoryLock ();
  }
}
Пример #7
0
EFI_STATUS
PspP2CmboxEntry (
  IN       EFI_HANDLE         ImageHandle,
  IN       EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                      Status;

  //We are now in SMM
  //If PSP feature turn off, exit the driver
  if ((CheckPspDevicePresent () == FALSE) ||
      (PcdGet8 (PcdPspPkgEnable) == 0)) {
    return EFI_SUCCESS;
  }

  PSP_DEBUG ("Psp.Drv.P2Cmbox Enter\n");
  //
  // We're now in SMM!
  //
  // Init PSP storage Lib
  //
  PSP_DEBUG ("\tStorage Lib Init\n");
  Status =  PspStorageInit (SystemTable);
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

  // Allocate SMM buffer for PSP-> BIOS communication
  PSP_DEBUG ("\tAllocate SMM buffer for P2C Mbox\n");
  Status = gSmst->SmmAllocatePool (
                    EfiRuntimeServicesData,
                    PSP_DATA_BLOCK_SIZE + 32,
                    &PspToBiosMbox
                    );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }

  //
  // Initialize the data structure
  ZeroMem (PspToBiosMbox, PSP_DATA_BLOCK_SIZE + 32);

  //Align on 32 bytes boundary
  PspToBiosMbox = ALIGN_POINTER ((UINTN) PspToBiosMbox, 32);
  PspToBiosMbox->MboxCmd      = 0;
  *(UINT32 *)&(PspToBiosMbox->MboxSts) = MBOX_STATUS_INITIALIZED;

  #ifdef PSP2BIOS_USING_SW_SMI
  PSP_DEBUG ("\tP2C using SW SMI\n");
  Status = EnablePspSwSmi ();
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }
  #else
  PSP_DEBUG ("\tP2C using fake SMI\n");
  InitFchFakeStsInfo (&mSmmTrigInfo);
  Status = EnablePspFakeStsSmi ();
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }
  #endif
  //Get TsegBase, TsegSize
  LibAmdMsrRead (MSR_SMMADDR, &mTsegBase, NULL);
  mTsegBase &= MSR_SMMADDR_TSEGBASE_BITS;

  LibAmdMsrRead (MSR_SMMMASK, &mTsegSize, NULL);
  mTsegSize = (~(mTsegSize & MSR_SMMMASK_TSEGMASK_BITS) + 1) & MSR_SMMMASK_TSEGMASK_BITS;


  PSP_DEBUG ("\tSMMBase:0x%x SMMLength:0x%x\n\tPSPSmmDataRegion:0x%x PspSmmDataLength:0x%x\n", mTsegBase, mTsegSize, PspToBiosMbox, PSP_DATA_BLOCK_SIZE);
  //Dump mSmmTrigInfo
  PSP_DEBUG ("\tSmmTrigInfo::Addr:0x%x AddrType:0x%x Width:0x%x AndMask:0x%x OrMask:0x%x\n",
              mSmmTrigInfo.Address,
              mSmmTrigInfo.AddressType,
              mSmmTrigInfo.ValueWidth,
              mSmmTrigInfo.ValueAndMask,
              mSmmTrigInfo.ValueOrMask);

  if (PspMboxBiosCmdSmmInfo (
        mTsegBase,
        mTsegSize,
        (UINT64) PspToBiosMbox,
        PSP_DATA_BLOCK_SIZE,
        &mSmmTrigInfo
        )) {
    return (EFI_SUCCESS);
  }
  PSP_DEBUG ("P2Cmbox Exit\n");

  return EFI_SUCCESS;
}
/**
  Process a Question's Option (whether selected or un-selected).

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

  @retval EFI_SUCCESS            Question Option process success.
  @retval Other                  Question Option process fail.

**/
EFI_STATUS
ProcessOptions (
  IN  UI_MENU_SELECTION           *Selection,
  IN  UI_MENU_OPTION              *MenuOption,
  IN  BOOLEAN                     Selected,
  OUT CHAR16                      **OptionString
  )
{
  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;
  LIST_ENTRY                      *Link;
  EFI_HII_VALUE                   HiiValue;
  EFI_HII_VALUE                   *QuestionValue;
  BOOLEAN                         Suppress;
  UINT16                          Maximum;
  QUESTION_OPTION                 *Option;
  UINTN                           Index2;
  UINT8                           *ValueArray;
  UINT8                           ValueType;
  EFI_STRING_ID                   StringId;

  Status        = EFI_SUCCESS;

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

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

  Question = MenuOption->ThisTag;
  QuestionValue = &Question->HiiValue;
  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 = AllocateZeroPool (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 (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);

          FreePool (*OptionString);
          *OptionString = NULL;
          return EFI_NOT_FOUND;
        }

        Suppress = FALSE;
        if ((OneOfOption->SuppressExpression != NULL) &&
            (EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress)) {
          //
          // This option is suppressed
          //
          Suppress = TRUE;
        }

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

          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 = AllocateZeroPool (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) ||
              (EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {
            CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));
            SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
            UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
            break;
          }

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

        FreePool (*OptionString);
        *OptionString = NULL;
        return EFI_NOT_FOUND;
      }

      if ((OneOfOption->SuppressExpression != NULL) &&
          ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
        //
        // 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) ||
              (EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {
            Suppress = FALSE;
            CopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE));
            SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
            UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
            gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | 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);
        ASSERT (StringPtr != NULL);
        NewStrCat (OptionString[0], StringPtr);
        Character[0] = RIGHT_ONEOF_DELIMITER;
        NewStrCat (OptionString[0], Character);

        FreePool (StringPtr);
      }
    }
    break;

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

    *OptionString[0] = LEFT_CHECKBOX_DELIMITER;

    if (Selected) {
      //
      // Since this is a BOOLEAN operation, flip it upon selection
      //
      QuestionValue->Value.b = (BOOLEAN) (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 = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
        FreePool (*OptionString);
        *OptionString = NULL;
        return Status;
      }

      //
      // Save Question value
      //
      Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);
      UpdateStatusBar (Selection, 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 = AllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

      *OptionString[0] = LEFT_NUMERIC_DELIMITER;

      //
      // Formatted print
      //
      PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
      Number = (UINT16) GetStringWidth (FormattedNumber);
      CopyMem (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 = AllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

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

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

      case 2:
        SetUnicodeMem (OptionString[0], 7, L' ');
        UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", 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 = AllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

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

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

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

  case EFI_IFR_STRING_OP:
    if (Selected) {
      StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
      ASSERT (StringPtr);
      CopyMem(StringPtr, Question->BufferValue, Maximum * sizeof (CHAR16));

      Status = ReadString (MenuOption, gPromptForData, StringPtr);
      if (!EFI_ERROR (Status)) {
        HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);
        Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
        if (EFI_ERROR (Status)) {
          HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
        } else {
          CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
          SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE);

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

      FreePool (StringPtr);
    } else {
      *OptionString = AllocateZeroPool (BufferSize);
      ASSERT (*OptionString);

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

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

      //
      // For interactive passwords, old password is validated by callback
      //
      if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)  != 0) {
        //
        // Use a NULL password to test whether old password is required
        //
        *StringPtr = 0;
        Status = PasswordCallback (Selection, MenuOption, StringPtr);
        if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {
          //
          // Callback is not supported, or
          // Callback request to terminate password input
          //
          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)) {
            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;
            }

            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)) {
            FreePool (StringPtr);
            return Status;
          }

          TempString = AllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);
          ASSERT (TempString != NULL);

          TempString[Maximum] = L'\0';

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

            FreePool (StringPtr);
            FreePool (TempString);
            return Status;
          }

          FreePool (TempString);
        }
      }

      //
      // Ask for new password
      //
      ZeroMem (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) != 0) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        FreePool (StringPtr);
        return Status;
      }

      //
      // Confirm new password
      //
      TempString = AllocateZeroPool ((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) != 0) {
          PasswordCallback (Selection, MenuOption, NULL);
        }

        FreePool (StringPtr);
        FreePool (TempString);
        return Status;
      }

      //
      // Compare two typed-in new passwords
      //
      if (StrCmp (StringPtr, TempString) == 0) {
        //
        // Prepare the  Question->HiiValue.Value.string for ValidateQuestion use.
        //
        if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
          StringId = Question->HiiValue.Value.string;
          Question->HiiValue.Value.string = NewString (StringPtr, Selection->FormSet->HiiHandle);
        } else {
          HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);
        }
        
        Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);

        //
        //  Researve the Question->HiiValue.Value.string.
        //
        if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
          DeleteString(Question->HiiValue.Value.string, Selection->FormSet->HiiHandle);
          Question->HiiValue.Value.string = StringId;
        }   
        
        if (EFI_ERROR (Status)) {
          //
          // Reset state machine for interactive password
          //
          if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
            PasswordCallback (Selection, MenuOption, NULL);
          } else {
            //
            // Researve the Question->HiiValue.Value.string.
            //
            HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);            
          }
        } else {
          //
          // Two password match, send it to Configuration Driver
          //
          if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
            PasswordCallback (Selection, MenuOption, StringPtr);
          } else {
            CopyMem (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) != 0) {
          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);
      }

      FreePool (TempString);
      FreePool (StringPtr);
    }
    break;

  default:
    break;
  }

  return Status;
}
/**
  Constructor for the Shell Level 2 Commands library.

  Install the handlers for level 2 UEFI Shell 2.0 commands.

  @param ImageHandle    the image handle of the process
  @param SystemTable    the EFI System Table pointer

  @retval EFI_SUCCESS        the shell command handlers were installed sucessfully
  @retval EFI_UNSUPPORTED    the shell level required was not found.
**/
EFI_STATUS
EFIAPI
ShellLevel2CommandsLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  //
  // if shell level is less than 2 do nothing
  //
  if (PcdGet8(PcdShellSupportLevel) < 2) {
    return (EFI_SUCCESS);
  }

  gShellLevel2HiiHandle = HiiAddPackages (&gShellLevel2HiiGuid, gImageHandle, UefiShellLevel2CommandsLibStrings, NULL);
  if (gShellLevel2HiiHandle == NULL) {
    return (EFI_DEVICE_ERROR);
  }

  //
  // install our shell command handlers that are always installed
  //
  ShellCommandRegisterCommandName(L"attrib",   ShellCommandRunAttrib  , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_ATTRIB) );
  ShellCommandRegisterCommandName(L"cd",       ShellCommandRunCd      , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_CD)     );
  ShellCommandRegisterCommandName(L"cp",       ShellCommandRunCp      , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_CP)     );
  ShellCommandRegisterCommandName(L"load",     ShellCommandRunLoad    , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_LOAD)   );
  ShellCommandRegisterCommandName(L"map",      ShellCommandRunMap     , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MAP)    );
  ShellCommandRegisterCommandName(L"mkdir",    ShellCommandRunMkDir   , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MKDIR)  );
  ShellCommandRegisterCommandName(L"mv",       ShellCommandRunMv      , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_MV)     );
  ShellCommandRegisterCommandName(L"parse",    ShellCommandRunParse   , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_PARSE)  );
  ShellCommandRegisterCommandName(L"reset",    ShellCommandRunReset   , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_RESET)  );
  ShellCommandRegisterCommandName(L"set",      ShellCommandRunSet     , ShellCommandGetManFileNameLevel2, 2, L"",FALSE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_SET)    );
  ShellCommandRegisterCommandName(L"ls",       ShellCommandRunLs      , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_LS)     );
  ShellCommandRegisterCommandName(L"rm",       ShellCommandRunRm      , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_RM)     );
  ShellCommandRegisterCommandName(L"vol",      ShellCommandRunVol     , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_VOL)    );

  //
  // support for permenant (built in) aliases
  //
  ShellCommandRegisterAlias(L"rm", L"del");
  ShellCommandRegisterAlias(L"ls", L"dir");
  ShellCommandRegisterAlias(L"cp", L"copy");
  ShellCommandRegisterAlias(L"mkdir", L"md");
  ShellCommandRegisterAlias(L"cd ..", L"cd..");
  ShellCommandRegisterAlias(L"cd \\", L"cd\\");
  ShellCommandRegisterAlias(L"ren", L"mv");
  //
  // These are installed in level 2 or 3...
  //
  if (PcdGet8(PcdShellSupportLevel) == 2 || PcdGet8(PcdShellSupportLevel) == 3) {
    ShellCommandRegisterCommandName(L"date",     ShellCommandRunDate    , ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_DATE)   );
    ShellCommandRegisterCommandName(L"time",     ShellCommandRunTime    , ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIME)   );
    ShellCommandRegisterCommandName(L"timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, PcdGet8(PcdShellSupportLevel), L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIMEZONE));
  } else {
    DEBUG_CODE_BEGIN();
    //
    // we want to be able to test these so install them under a different name in debug mode...
    //
    ShellCommandRegisterCommandName(L"l2date",     ShellCommandRunDate    , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_DATE)   );
    ShellCommandRegisterCommandName(L"l2time",     ShellCommandRunTime    , ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIME)   );
    ShellCommandRegisterCommandName(L"l2timezone", ShellCommandRunTimeZone, ShellCommandGetManFileNameLevel2, 2, L"", TRUE, gShellLevel2HiiHandle, STRING_TOKEN(STR_GET_HELP_TIMEZONE));
    DEBUG_CODE_END();
  }

  return (EFI_SUCCESS);
}
Пример #10
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
    IN       EFI_PEI_FILE_HANDLE      FileHandle,
    IN CONST EFI_PEI_SERVICES         **PeiServices
)
{
    EFI_STATUS                        Status;
    EFI_BOOT_MODE                     BootMode;
    TIS_TPM_HANDLE                    TpmHandle;

    if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
        DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
        return EFI_UNSUPPORTED;
    }

    if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
        return EFI_UNSUPPORTED;
    }

    //
    // Initialize TPM device
    //
    Status = PeiServicesGetBootMode (&BootMode);
    ASSERT_EFI_ERROR (Status);

    //
    // In S3 path, skip shadow logic. no measurement is required
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
        Status = (**PeiServices).RegisterForShadow(FileHandle);
        if (Status == EFI_ALREADY_STARTED) {
            mImageInMemory = TRUE;
        } else if (Status == EFI_NOT_FOUND) {
            ASSERT_EFI_ERROR (Status);
        }
    }

    if (!mImageInMemory) {
        TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
        Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
        if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
            return Status;
        }

        if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
            Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
            if (EFI_ERROR (Status) ) {
                return Status;
            }
        }

        //
        // TpmSelfTest is optional on S3 path, skip it to save S3 time
        //
        if (BootMode != BOOT_ON_S3_RESUME) {
            Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
            if (EFI_ERROR (Status)) {
                return Status;
            }
        }

        Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
        ASSERT_EFI_ERROR (Status);
    }

    if (mImageInMemory) {
        Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
        if (EFI_ERROR (Status)) {
            return Status;
        }
    }

    return Status;
}
Пример #11
0
VOID
PrePiMain (
  IN  UINTN                     UefiMemoryBase,
  IN  UINTN                     StacksBase,
  IN  UINT64                    StartTimeStamp
  )
{
  EFI_HOB_HANDOFF_INFO_TABLE*   HobList;
  EFI_STATUS                    Status;
  CHAR8                         Buffer[100];
  UINTN                         CharCount;
  UINTN                         StacksSize;

  // Initialize the architecture specific bits
  ArchInitialize ();

  // Declare the PI/UEFI memory region
  HobList = HobConstructor (
    (VOID*)UefiMemoryBase,
    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
    (VOID*)UefiMemoryBase,
    (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks
    );
  PrePeiSetHobList (HobList);

  //
  // Ensure that the loaded image is invalidated in the caches, so that any
  // modifications we made with the caches and MMU off (such as the applied
  // relocations) don't become invisible once we turn them on.
  //
  InvalidateDataCacheRange((VOID *)(UINTN)PcdGet64 (PcdFdBaseAddress), PcdGet32 (PcdFdSize));

  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  ASSERT_EFI_ERROR (Status);

  // Initialize the Serial Port
  SerialPortInitialize ();
  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
    (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
  SerialPortWrite ((UINT8 *) Buffer, CharCount);

  // Create the Stacks HOB (reserve the memory for all stacks)
  StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
  BuildStackHob (StacksBase, StacksSize);

  //TODO: Call CpuPei as a library
  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));

  // Set the Boot Mode
  SetBootMode (ArmPlatformGetBootMode ());

  // Initialize Platform HOBs (CpuHob and FvHob)
  Status = PlatformPeim ();
  ASSERT_EFI_ERROR (Status);

  // Now, the HOB List has been initialized, we can register performance information
  PERF_START (NULL, "PEI", NULL, StartTimeStamp);

  // SEC phase needs to run library constructors by hand.
  ExtractGuidedSectionLibConstructor ();
  LzmaDecompressLibConstructor ();

  // Build HOBs to pass up our version of stuff the DXE Core needs to save space
  BuildPeCoffLoaderHob ();
  BuildExtractSectionHob (
    &gLzmaCustomDecompressGuid,
    LzmaGuidedSectionGetInfo,
    LzmaGuidedSectionExtraction
    );

  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
  Status = DecompressFirstFv ();
  ASSERT_EFI_ERROR (Status);

  // Load the DXE Core and transfer control to it
  Status = LoadDxeCoreFromFv (NULL, 0);
  ASSERT_EFI_ERROR (Status);
}
Пример #12
0
/**
  Measure and log EFI handoff tables, and extend the measurement result into PCR[1].

  @retval EFI_SUCCESS         Operation completed successfully.
  @retval EFI_DEVICE_ERROR    The operation was unsuccessful.

**/
EFI_STATUS
EFIAPI
MeasureHandoffTables (
    VOID
)
{
    EFI_STATUS                        Status;
    SMBIOS_TABLE_ENTRY_POINT          *SmbiosTable;
    TCG_PCR_EVENT_HDR                 TcgEvent;
    EFI_HANDOFF_TABLE_POINTERS        HandoffTables;
    UINTN                             ProcessorNum;
    EFI_CPU_PHYSICAL_LOCATION         *ProcessorLocBuf;

    //
    // Measure SMBIOS with EV_EFI_HANDOFF_TABLES to PCR[1]
    //
    Status = EfiGetSystemConfigurationTable (
                 &gEfiSmbiosTableGuid,
                 (VOID **) &SmbiosTable
             );

    if (!EFI_ERROR (Status)) {
        ASSERT (SmbiosTable != NULL);

        TcgEvent.PCRIndex  = 1;
        TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;
        TcgEvent.EventSize = sizeof (HandoffTables);

        HandoffTables.NumberOfTables = 1;
        HandoffTables.TableEntry[0].VendorGuid  = gEfiSmbiosTableGuid;
        HandoffTables.TableEntry[0].VendorTable = SmbiosTable;

        DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));
        DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));

        Status = TcgDxeHashLogExtendEventI (
                     &mTcgDxeData,
                     (UINT8*)(UINTN)SmbiosTable->TableAddress,
                     SmbiosTable->TableLength,
                     &TcgEvent,
                     (UINT8*)&HandoffTables
                 );
    }

    if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
        //
        // Tcg Server spec.
        // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
        //
        Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);

        if (!EFI_ERROR(Status)) {
            TcgEvent.PCRIndex  = 1;
            TcgEvent.EventType = EV_TABLE_OF_DEVICES;
            TcgEvent.EventSize = sizeof (HandoffTables);

            HandoffTables.NumberOfTables = 1;
            HandoffTables.TableEntry[0].VendorGuid  = gEfiMpServiceProtocolGuid;
            HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;

            Status = TcgDxeHashLogExtendEventI (
                         &mTcgDxeData,
                         (UINT8*)(UINTN)ProcessorLocBuf,
                         sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
                         &TcgEvent,
                         (UINT8*)&HandoffTables
                     );

            FreePool(ProcessorLocBuf);
        }
    }

    return Status;
}
Пример #13
0
/**
  Reset the serial device.

  @param  This              Protocol instance pointer.

  @retval EFI_SUCCESS       The device was reset.
  @retval EFI_DEVICE_ERROR  The serial device could not be reset.

**/
EFI_STATUS
EFIAPI
SerialReset (
    IN EFI_SERIAL_IO_PROTOCOL  *This
)
{
    EFI_STATUS  Status;
    EFI_TPL     Tpl;

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

    //
    // Set the Serial I/O mode and update the device path
    //

    Tpl = gBS->RaiseTPL (TPL_NOTIFY);

    //
    // Set the Serial I/O mode
    //
    This->Mode->ReceiveFifoDepth  = 0;
    This->Mode->Timeout           = 1000000;
    This->Mode->BaudRate          = PcdGet64 (PcdUartDefaultBaudRate);
    This->Mode->DataBits          = (UINT32)PcdGet8 (PcdUartDefaultDataBits);
    This->Mode->Parity            = (UINT32)PcdGet8 (PcdUartDefaultParity);
    This->Mode->StopBits          = (UINT32)PcdGet8 (PcdUartDefaultStopBits);

    //
    // Check if the device path has actually changed
    //
    if (mDevicePath.Uart.BaudRate == This->Mode->BaudRate &&
            mDevicePath.Uart.DataBits == (UINT8)This->Mode->DataBits &&
            mDevicePath.Uart.Parity   == (UINT8)This->Mode->Parity &&
            mDevicePath.Uart.StopBits == (UINT8)This->Mode->StopBits
       ) {
        gBS->RestoreTPL (Tpl);
        return EFI_SUCCESS;
    }

    //
    // Update the device path
    //
    mDevicePath.Uart.BaudRate = This->Mode->BaudRate;
    mDevicePath.Uart.DataBits = (UINT8)This->Mode->DataBits;
    mDevicePath.Uart.Parity   = (UINT8)This->Mode->Parity;
    mDevicePath.Uart.StopBits = (UINT8)This->Mode->StopBits;

    Status = gBS->ReinstallProtocolInterface (
                 gHandle,
                 &gEfiDevicePathProtocolGuid,
                 &mDevicePath,
                 &mDevicePath
             );

    gBS->RestoreTPL (Tpl);

    return Status;
}
Пример #14
0
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;
  UART_DEVICE_PATH              *Uart;
  EFI_TPL                       Tpl;

  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 = PcdGet64 (PcdUartDefaultBaudRate);
  }

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

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

  if (Parity == DefaultParity) {
    Parity = (EFI_PARITY_TYPE) (PcdGet8 (PcdUartDefaultParity));
  }

  if (DataBits == 0) {
    DataBits = PcdGet8 (PcdUartDefaultDataBits);
  }

  if (StopBits == DefaultStopBits) {
    StopBits = (EFI_STOP_BITS_TYPE) PcdGet8 (PcdUartDefaultStopBits);
  }

  //
  // 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 < (ARRAY_SIZE (mBaudRateCurrentSupport)); Index++) {
    if (BaudRate < mBaudRateCurrentSupport[Index]) {
      BaudRate = mBaudRateCurrentSupport[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 (TPL_NOTIFY);

  //
  //  Get current values from NT
  //
  ZeroMem (&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;

  Status = EFI_SUCCESS;
  if (Private->Handle != NULL) {
    Uart = (UART_DEVICE_PATH *) (
             (UINTN) Private->DevicePath
             + GetDevicePathSize (Private->ParentDevicePath)
             - END_DEVICE_PATH_LENGTH
             );
    CopyMem (Uart, &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));
    Status = gBS->ReinstallProtocolInterface (
                    Private->Handle,
                    &gEfiDevicePathProtocolGuid,
                    Private->DevicePath,
                    Private->DevicePath
                    );
  }

  gBS->RestoreTPL (Tpl);

  return Status;
}
Пример #15
0
VOID
PrePiMain (
  IN  UINTN                     UefiMemoryBase,
  IN  UINTN                     StacksBase,
  IN  UINT64                    StartTimeStamp
  )
{
  EFI_HOB_HANDOFF_INFO_TABLE*   HobList;
  ARM_MP_CORE_INFO_PPI*         ArmMpCoreInfoPpi;
  UINTN                         ArmCoreCount;
  ARM_CORE_INFO*                ArmCoreInfoTable;
  EFI_STATUS                    Status;
  CHAR8                         Buffer[100];
  UINTN                         CharCount;
  UINTN                         StacksSize;

  // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
  ASSERT (IS_XIP() ||
          ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
           ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)));

  // Initialize the architecture specific bits
  ArchInitialize ();

  // Initialize the Serial Port
  SerialPortInitialize ();
  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",
    (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
  SerialPortWrite ((UINT8 *) Buffer, CharCount);

  // Initialize the Debug Agent for Source Level Debugging
  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
  SaveAndSetDebugTimerInterrupt (TRUE);

  // Declare the PI/UEFI memory region
  HobList = HobConstructor (
    (VOID*)UefiMemoryBase,
    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
    (VOID*)UefiMemoryBase,
    (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks
    );
  PrePeiSetHobList (HobList);

  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
  ASSERT_EFI_ERROR (Status);

  // Create the Stacks HOB (reserve the memory for all stacks)
  if (ArmIsMpCore ()) {
    StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
                 ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
  } else {
    StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
  }
  BuildStackHob (StacksBase, StacksSize);

  //TODO: Call CpuPei as a library
  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));

  if (ArmIsMpCore ()) {
    // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
    Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);

    // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
    ASSERT_EFI_ERROR (Status);

    // Build the MP Core Info Table
    ArmCoreCount = 0;
    Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
    if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
      // Build MPCore Info HOB
      BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
    }
  }

  // Set the Boot Mode
  SetBootMode (ArmPlatformGetBootMode ());

  // Initialize Platform HOBs (CpuHob and FvHob)
  Status = PlatformPeim ();
  ASSERT_EFI_ERROR (Status);

  // Now, the HOB List has been initialized, we can register performance information
  PERF_START (NULL, "PEI", NULL, StartTimeStamp);

  // SEC phase needs to run library constructors by hand.
  ExtractGuidedSectionLibConstructor ();
  LzmaDecompressLibConstructor ();

  // Build HOBs to pass up our version of stuff the DXE Core needs to save space
  BuildPeCoffLoaderHob ();
  BuildExtractSectionHob (
    &gLzmaCustomDecompressGuid,
    LzmaGuidedSectionGetInfo,
    LzmaGuidedSectionExtraction
    );

  // Assume the FV that contains the SEC (our code) also contains a compressed FV.
  Status = DecompressFirstFv ();
  ASSERT_EFI_ERROR (Status);

  // Load the DXE Core and transfer control to it
  Status = LoadDxeCoreFromFv (NULL, 0);
  ASSERT_EFI_ERROR (Status);
}
Пример #16
0
Файл: Pool.c Проект: b-man/edk2
/**
  Internal function to allocate pool of a particular type.
  Caller must have the memory lock held

  @param  PoolType               Type of pool to allocate
  @param  Size                   The amount of pool to allocate
  @param  NeedGuard              Flag to indicate Guard page is needed or not

  @return The allocate pool, or NULL

**/
VOID *
CoreAllocatePoolI (
  IN EFI_MEMORY_TYPE  PoolType,
  IN UINTN            Size,
  IN BOOLEAN          NeedGuard
  )
{
  POOL        *Pool;
  POOL_FREE   *Free;
  POOL_HEAD   *Head;
  POOL_TAIL   *Tail;
  CHAR8       *NewPage;
  VOID        *Buffer;
  UINTN       Index;
  UINTN       FSize;
  UINTN       Offset, MaxOffset;
  UINTN       NoPages;
  UINTN       Granularity;
  BOOLEAN     HasPoolTail;

  ASSERT_LOCKED (&mPoolMemoryLock);

  if  (PoolType == EfiACPIReclaimMemory   ||
       PoolType == EfiACPIMemoryNVS       ||
       PoolType == EfiRuntimeServicesCode ||
       PoolType == EfiRuntimeServicesData) {

    Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
  } else {
    Granularity = DEFAULT_PAGE_ALLOCATION_GRANULARITY;
  }

  //
  // Adjust the size by the pool header & tail overhead
  //

  HasPoolTail  = !(NeedGuard &&
                   ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0));

  //
  // Adjusting the Size to be of proper alignment so that
  // we don't get an unaligned access fault later when
  // pool_Tail is being initialized
  //
  Size = ALIGN_VARIABLE (Size);

  Size += POOL_OVERHEAD;
  Index = SIZE_TO_LIST(Size);
  Pool = LookupPoolHead (PoolType);
  if (Pool== NULL) {
    return NULL;
  }
  Head = NULL;

  //
  // If allocation is over max size, just allocate pages for the request
  // (slow)
  //
  if (Index >= SIZE_TO_LIST (Granularity) || NeedGuard) {
    if (!HasPoolTail) {
      Size -= sizeof (POOL_TAIL);
    }
    NoPages = EFI_SIZE_TO_PAGES (Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
    NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);
    Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity, NeedGuard);
    if (NeedGuard) {
      Head = AdjustPoolHeadA ((EFI_PHYSICAL_ADDRESS)(UINTN)Head, NoPages, Size);
    }
    goto Done;
  }

  //
  // If there's no free pool in the proper list size, go get some more pages
  //
  if (IsListEmpty (&Pool->FreeList[Index])) {

    Offset = LIST_TO_SIZE (Index);
    MaxOffset = Granularity;

    //
    // Check the bins holding larger blocks, and carve one up if needed
    //
    while (++Index < SIZE_TO_LIST (Granularity)) {
      if (!IsListEmpty (&Pool->FreeList[Index])) {
        Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);
        RemoveEntryList (&Free->Link);
        NewPage = (VOID *) Free;
        MaxOffset = LIST_TO_SIZE (Index);
        goto Carve;
      }
    }

    //
    // Get another page
    //
    NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity),
                                      Granularity, NeedGuard);
    if (NewPage == NULL) {
      goto Done;
    }

    //
    // Serve the allocation request from the head of the allocated block
    //
Carve:
    Head = (POOL_HEAD *) NewPage;

    //
    // Carve up remaining space into free pool blocks
    //
    Index--;
    while (Offset < MaxOffset) {
      ASSERT (Index < MAX_POOL_LIST);
      FSize = LIST_TO_SIZE(Index);

      while (Offset + FSize <= MaxOffset) {
        Free = (POOL_FREE *) &NewPage[Offset];
        Free->Signature = POOL_FREE_SIGNATURE;
        Free->Index     = (UINT32)Index;
        InsertHeadList (&Pool->FreeList[Index], &Free->Link);
        Offset += FSize;
      }
      Index -= 1;
    }

    ASSERT (Offset == MaxOffset);
    goto Done;
  }

  //
  // Remove entry from free pool list
  //
  Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);
  RemoveEntryList (&Free->Link);

  Head = (POOL_HEAD *) Free;

Done:
  Buffer = NULL;

  if (Head != NULL) {

    //
    // Account the allocation
    //
    Pool->Used += Size;

    //
    // If we have a pool buffer, fill in the header & tail info
    //
    Head->Signature = POOL_HEAD_SIGNATURE;
    Head->Size      = Size;
    Head->Type      = (EFI_MEMORY_TYPE) PoolType;
    Buffer          = Head->Data;

    if (HasPoolTail) {
      Tail            = HEAD_TO_TAIL (Head);
      Tail->Signature = POOL_TAIL_SIGNATURE;
      Tail->Size      = Size;

      Size -= POOL_OVERHEAD;
    } else {
      Size -= SIZE_OF_POOL_HEAD;
    }

    DEBUG_CLEAR_MEMORY (Buffer, Size);

    DEBUG ((
      DEBUG_POOL,
      "AllocatePoolI: Type %x, Addr %p (len %lx) %,ld\n", PoolType,
      Buffer,
      (UINT64)Size,
      (UINT64) Pool->Used
      ));


  } else {
    DEBUG ((DEBUG_ERROR | DEBUG_POOL, "AllocatePool: failed to allocate %ld bytes\n", (UINT64) Size));
  }

  return Buffer;
}
Пример #17
0
VOID
ApicTableUpdate (
  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader,
  IN OUT   EFI_ACPI_TABLE_VERSION       *Version
  )
/*++

  Routine Description:

    Update the processors information in the APIC table

  Arguments:

    Table   - The table to be set
    Version - Version to publish

  Returns:

    None

--*/
{
  EFI_STATUS                 Status;
  EFI_MP_SERVICES_PROTOCOL   *MpService;
  UINT8                      *CurrPtr;
  UINT8                      *EndPtr;
  UINT8                      CurrIoApic;
  UINT8                      CurrProcessor;
  UINTN                      NumberOfCPUs;
  UINTN                      NumberOfEnabledCPUs;
  UINTN                      BufferSize;
  EFI_PROCESSOR_INFORMATION  MpContext;
  ACPI_APIC_STRUCTURE_PTR    *ApicPtr;  

  CurrIoApic    = 0;
  CurrProcessor = 0;
  //
  // Find the MP Protocol. This is an MP platform, so MP protocol must be
  // there.
  //
  Status = gBS->LocateProtocol (
                   &gEfiMpServiceProtocolGuid,
                   NULL,
                  (VOID**)&MpService
                   );
  if (EFI_ERROR (Status)) {
    //
    // Failed to get MP information, doesn't publish the invalid table
    //
    *Version = EFI_ACPI_TABLE_VERSION_NONE;
    return;
  }

  //
  // Determine the number of processors
  //
  MpService->GetNumberOfProcessors (
              MpService,
              &NumberOfCPUs,
              &NumberOfEnabledCPUs
              );

  CurrPtr = (UINT8*) &(TableHeader[1]);
  CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag
  EndPtr  = (UINT8*) TableHeader;
  EndPtr  = EndPtr + TableHeader->Length;

  while (CurrPtr < EndPtr) {
  
    ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr;
    switch (ApicPtr->AcpiApicCommon.Type) {

      case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC:
        BufferSize = sizeof (EFI_PROCESSOR_INFORMATION);
        ApicPtr->AcpiLocalApic.Flags = 0;
        ApicPtr->AcpiLocalApic.ApicId = 0;
        Status = MpService->GetProcessorInfo (
                              MpService,
                              CurrProcessor,
                              &MpContext
                              );

        if (!EFI_ERROR (Status)) {
          if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) {
            ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED;
          }
          ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId;
        }
        CurrProcessor++;
        break;

      case EFI_ACPI_1_0_IO_APIC:
        //
        // IO APIC entries can be patched here
        //
        if (CurrIoApic == 0) {
          //
          // Update SOC internel IOAPIC base
          //
          ApicPtr->AcpiIoApic.IoApicId      =  PcdGet8 (PcdIoApicSettingIoApicId);
          ApicPtr->AcpiIoApic.IoApicAddress =  (UINT32)FixedPcdGet64(PcdIoApicBaseAddress);
          ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0;
        } else {
          //
          // Porting is required to update other IOAPIC entries if available
          //
          ASSERT (0);
        }
        CurrIoApic++;
        break;
          
      default:
        break;
      };
    CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
  }
}
Пример #18
0
/**
  Performs any early platform specific GPIO Controller manipulation.

**/
VOID
EFIAPI
EarlyPlatformGpioCtrlerManipulation (
  VOID
  )
{
  UINT32                            IohGpioBase;
  UINT32                            Data32;
  UINT32                            Addr;
  UINT32                            DevPcieAddr;
  UINT16                            SaveCmdReg;
  UINT32                            SaveBarReg;
  UINT16                            PciVid;
  UINT16                            PciDid;

  IohGpioBase = (UINT32) PcdGet64 (PcdIohGpioMmioBase);

  DevPcieAddr = PCI_LIB_ADDRESS (
                  PcdGet8 (PcdIohGpioBusNumber),
                  PcdGet8 (PcdIohGpioDevNumber),
                  PcdGet8 (PcdIohGpioFunctionNumber),
                  0
                  );

  //
  // Do nothing if not a supported device.
  //
  PciVid = PciRead16 (DevPcieAddr + PCI_VENDOR_ID_OFFSET);
  PciDid = PciRead16 (DevPcieAddr + PCI_DEVICE_ID_OFFSET);
  if((PciVid != V_IOH_I2C_GPIO_VENDOR_ID) || (PciDid != V_IOH_I2C_GPIO_DEVICE_ID)) {
    return;
  }

  //
  // Save current settings for PCI CMD/BAR registers.
  //
  SaveCmdReg = PciRead16 (DevPcieAddr + PCI_COMMAND_OFFSET);
  SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));

  //
  // Use predefined tempory memory resource.
  //
  PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);
  PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);

  //
  // Gpio Controller Manipulation Tasks.
  //

    //
    // Reset Cypress Expander on Galileo Platform
    //
    Addr = IohGpioBase + GPIO_SWPORTA_DR;
    Data32 = *((volatile UINT32 *) (UINTN)(Addr));
    Data32 |= BIT4;                                 // Cypress Reset line controlled by GPIO<4>
    *((volatile UINT32 *) (UINTN)(Addr)) = Data32;

    Data32 = *((volatile UINT32 *) (UINTN)(Addr));
    Data32 &= ~BIT4;                                // Cypress Reset line controlled by GPIO<4>
    *((volatile UINT32 *) (UINTN)(Addr)) = Data32;

  //
  // Restore settings for PCI CMD/BAR registers
  //
  PciWrite32 ((DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
  PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
}
Пример #19
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_BOOT_MODE                     BootMode;

  if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
      CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  //
  // Update for Performance optimization
  //
  Status = Tpm2RequestUseTpm ();
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
    return Status;
  }

  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  //
  // In S3 path, skip shadow logic. no measurement is required
  //
  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = (**PeiServices).RegisterForShadow(FileHandle);
    if (Status == EFI_ALREADY_STARTED) {
      mImageInMemory = TRUE;
      mFileHandle = FileHandle;
    } else if (Status == EFI_NOT_FOUND) {
      ASSERT_EFI_ERROR (Status);
    }
  }

  if (!mImageInMemory) {
    //
    // Initialize TPM device
    //
    if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
      if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm2Startup (TPM_SU_STATE);
        if (EFI_ERROR (Status) ) {
          Status = Tpm2Startup (TPM_SU_CLEAR);
        }
      } else {
        Status = Tpm2Startup (TPM_SU_CLEAR);
      }
      if (EFI_ERROR (Status) ) {
        return Status;
      }
    }

    //
    // TpmSelfTest is optional on S3 path, skip it to save S3 time
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
      if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {
        Status = Tpm2SelfTest (NO);
        if (EFI_ERROR (Status)) {
          return Status;
        }
      }
    }

    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return Status;
}
Пример #20
0
/**
  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
  permanent memory.

  @param[in] PeiServices            Pointer to the PEI Services Table.
  @param[in] TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
                                Temporary RAM contents.
  @param[in] PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
                                Temporary RAM contents.
  @param[in] CopySize               Amount of memory to migrate from temporary to permanent memory.

  @retval EFI_SUCCESS           The data was successfully returned.
  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
                                TemporaryMemoryBase > PermanentMemoryBase.

**/
EFI_STATUS
EFIAPI
SecTemporaryRamSupport (
  IN CONST EFI_PEI_SERVICES   **PeiServices,
  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
  IN UINTN                    CopySize
  )
{
  IA32_DESCRIPTOR   IdtDescriptor;
  VOID*             OldHeap;
  VOID*             NewHeap;
  VOID*             OldStack;
  VOID*             NewStack;
  UINTN             HeapSize;
  UINTN             StackSize;

  HeapSize   = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;
  StackSize  = CopySize - HeapSize;
    
  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);

  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);
  NewStack = (VOID*)(UINTN)PermanentMemoryBase;

  //
  // Migrate Heap
  //
  CopyMem (NewHeap, OldHeap, HeapSize);

  //
  // Migrate Stack
  //
  CopyMem (NewStack, OldStack, StackSize);


  //
  // We need *not* fix the return address because currently,
  // The PeiCore is executed in flash.
  //

  //
  // Rebase IDT table in permanent memory
  //
  AsmReadIdtr (&IdtDescriptor);
  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;

  AsmWriteIdtr (&IdtDescriptor);

  //
  // Fixed the FSP data pointer
  //
  FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);

  //
  // SecSwitchStack function must be invoked after the memory migration
  // immediatly, also we need fixup the stack change caused by new call into
  // permenent memory.
  //
  SecSwitchStack (
    (UINT32) (UINTN) OldStack,
    (UINT32) (UINTN) NewStack
    );

  return EFI_SUCCESS;
}
Пример #21
0
/**
  Initialize Memory Protection support.
**/
VOID
EFIAPI
CoreInitializeMemoryProtection (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   Event;
  EFI_EVENT   EndOfDxeEvent;
  VOID        *Registration;

  mImageProtectionPolicy = PcdGet32(PcdImageProtectionPolicy);

  InitializeListHead (&mProtectedImageRecordList);

  //
  // Sanity check the PcdDxeNxMemoryProtectionPolicy setting:
  // - code regions should have no EFI_MEMORY_XP attribute
  // - EfiConventionalMemory and EfiBootServicesData should use the
  //   same attribute
  //
  ASSERT ((GetPermissionAttributeForMemoryType (EfiBootServicesCode) & EFI_MEMORY_XP) == 0);
  ASSERT ((GetPermissionAttributeForMemoryType (EfiRuntimeServicesCode) & EFI_MEMORY_XP) == 0);
  ASSERT ((GetPermissionAttributeForMemoryType (EfiLoaderCode) & EFI_MEMORY_XP) == 0);
  ASSERT (GetPermissionAttributeForMemoryType (EfiBootServicesData) ==
          GetPermissionAttributeForMemoryType (EfiConventionalMemory));

  if (mImageProtectionPolicy != 0 || PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) {
    Status = CoreCreateEvent (
               EVT_NOTIFY_SIGNAL,
               TPL_CALLBACK,
               MemoryProtectionCpuArchProtocolNotify,
               NULL,
               &Event
               );
    ASSERT_EFI_ERROR(Status);

    //
    // Register for protocol notifactions on this event
    //
    Status = CoreRegisterProtocolNotify (
               &gEfiCpuArchProtocolGuid,
               Event,
               &Registration
               );
    ASSERT_EFI_ERROR(Status);
  }

  //
  // Register a callback to disable NULL pointer detection at EndOfDxe
  //
  if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7))
       == (BIT0|BIT7)) {
    Status = CoreCreateEventEx (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    DisableNullDetectionAtTheEndOfDxe,
                    NULL,
                    &gEfiEndOfDxeEventGroupGuid,
                    &EndOfDxeEvent
                    );
    ASSERT_EFI_ERROR (Status);
  }

  return ;
}
Пример #22
0
/**

  Entry point to the C language phase of SEC. After the SEC assembly
  code has initialized some temporary memory and set up the stack,
  the control is transferred to this function.


  @param[in] SizeOfRam          Size of the temporary memory available for use.
  @param[in] TempRamBase        Base address of tempory ram
  @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
  @param[in] PeiCore            PeiCore entry point.
  @param[in] BootLoaderStack    BootLoader stack.
  @param[in] ApiIdx             the index of API.

  @return This function never returns.

**/
VOID
EFIAPI
SecStartup (
  IN UINT32                   SizeOfRam,
  IN UINT32                   TempRamBase,
  IN VOID                    *BootFirmwareVolume,
  IN PEI_CORE_ENTRY           PeiCore,
  IN UINT32                   BootLoaderStack,
  IN UINT32                   ApiIdx
  )
{
  EFI_SEC_PEI_HAND_OFF        SecCoreData;
  IA32_DESCRIPTOR             IdtDescriptor;
  SEC_IDT_TABLE               IdtTableInStack;
  UINT32                      Index;
  FSP_GLOBAL_DATA             PeiFspData;
  UINT64                      ExceptionHandler;

  //
  // Process all libraries constructor function linked to SecCore.
  //
  ProcessLibraryConstructorList ();

  //
  // Initialize floating point operating environment
  // to be compliant with UEFI spec.
  //
  InitializeFloatingPointUnits ();


  // |-------------------|---->
  // |Idt Table          |
  // |-------------------|
  // |PeiService Pointer |    PeiStackSize
  // |-------------------|
  // |                   |
  // |      Stack        |
  // |-------------------|---->
  // |                   |
  // |                   |
  // |      Heap         |    PeiTemporayRamSize
  // |                   |
  // |                   |
  // |-------------------|---->  TempRamBase
  IdtTableInStack.PeiService  = NULL;
  ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);
  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
    CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));
  }

  IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;
  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);

  AsmWriteIdtr (&IdtDescriptor);

  //
  // Initialize the global FSP data region
  //
  FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx);

  //
  // Update the base address and length of Pei temporary memory
  //
  SecCoreData.DataSize               = sizeof (EFI_SEC_PEI_HAND_OFF);
  SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
  SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;

  SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;
  SecCoreData.TemporaryRamSize       = SizeOfRam;
  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;
  SecCoreData.StackBase              = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;

  DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));
  DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));
  DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase       - 0x%x\n", SecCoreData.TemporaryRamBase));
  DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize       - 0x%x\n", SecCoreData.TemporaryRamSize));
  DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase    - 0x%x\n", SecCoreData.PeiTemporaryRamBase));
  DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize    - 0x%x\n", SecCoreData.PeiTemporaryRamSize));
  DEBUG ((DEBUG_INFO, "Fsp StackBase              - 0x%x\n", SecCoreData.StackBase));
  DEBUG ((DEBUG_INFO, "Fsp StackSize              - 0x%x\n", SecCoreData.StackSize));

  //
  // Call PeiCore Entry
  //  
  PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);

  //
  // Should never be here
  //
  CpuDeadLoop ();
}
Пример #23
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
  IN       EFI_PEI_FILE_HANDLE      FileHandle,
  IN CONST EFI_PEI_SERVICES         **PeiServices
  )
{
  EFI_STATUS                        Status;
  EFI_STATUS                        Status2;
  EFI_BOOT_MODE                     BootMode;

  if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
    DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
    return EFI_UNSUPPORTED;
  }

  if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
    DEBUG ((EFI_D_ERROR, "TPM error!\n"));
    return EFI_DEVICE_ERROR;
  }

  //
  // Initialize TPM device
  //
  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  //
  // In S3 path, skip shadow logic. no measurement is required
  //
  if (BootMode != BOOT_ON_S3_RESUME) {
    Status = (**PeiServices).RegisterForShadow(FileHandle);
    if (Status == EFI_ALREADY_STARTED) {
      mImageInMemory = TRUE;
    } else if (Status == EFI_NOT_FOUND) {
      ASSERT_EFI_ERROR (Status);
    }
  }

  if (!mImageInMemory) {
    Status = Tpm12RequestUseTpm ();
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
      goto Done;
    }

    if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
      if (BootMode == BOOT_ON_S3_RESUME) {
        Status = Tpm12Startup (TPM_ST_STATE);
      } else {
        Status = Tpm12Startup (TPM_ST_CLEAR);
      }
      if (EFI_ERROR (Status) ) {
        goto Done;
      }
    }

    //
    // TpmSelfTest is optional on S3 path, skip it to save S3 time
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
      Status = Tpm12ContinueSelfTest ();
      if (EFI_ERROR (Status)) {
        goto Done;
      }
    }

    //
    // Only intall TpmInitializedPpi on success
    //
    Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
    ASSERT_EFI_ERROR (Status);
  }

  if (mImageInMemory) {
    Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
    return Status;
  }

Done:
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n"));
    BuildGuidHob (&gTpmErrorHobGuid,0);
    REPORT_STATUS_CODE (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
      );
  }
  //
  // Always intall TpmInitializationDonePpi no matter success or fail.
  // Other driver can know TPM initialization state by TpmInitializedPpi.
  //
  Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
  ASSERT_EFI_ERROR (Status2);

  return Status;
}
Пример #24
0
/**
  This routine reads a numeric value from the user input.

  @param  Selection         Pointer to current selection.
  @param  MenuOption        Pointer to the current input menu.

  @retval EFI_SUCCESS       If numerical input is read successfully
  @retval EFI_DEVICE_ERROR  If operation fails

**/
EFI_STATUS
GetNumericInput (
    IN  UI_MENU_SELECTION           *Selection,
    IN  UI_MENU_OPTION              *MenuOption
)
{
    EFI_STATUS              Status;
    UINTN                   Column;
    UINTN                   Row;
    CHAR16                  InputText[MAX_NUMERIC_INPUT_WIDTH];
    CHAR16                  FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1];
    UINT64                  PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3];
    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;

    //
    // Only two case, user can enter to this function: Enter and +/- case.
    // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT
    //
    ManualInput        = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE);

    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:
            switch (QuestionValue->Value.date.Month) {
            case 2:
                if ((QuestionValue->Value.date.Year % 4) == 0  &&
                        ((QuestionValue->Value.date.Year % 100) != 0 ||
                         (QuestionValue->Value.date.Year % 400) == 0)) {
                    Maximum = 29;
                } else {
                    Maximum = 28;
                }
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                Maximum = 30;
                break;
            default:
                Maximum = 31;
                break;
            }

            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 ((Question->Operand == EFI_IFR_NUMERIC_OP) &&
            ((Question->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {
        HexInput = TRUE;
    } else {
        HexInput = FALSE;
    }

    //
    // Enter from "Enter" input, clear the old word showing.
    //
    if (ManualInput) {
        if (Question->Operand == EFI_IFR_NUMERIC_OP) {
            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' ');
            ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH);
            InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
            InputText[InputWidth + 2] = L'\0';

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

        if (Question->Operand == EFI_IFR_DATE_OP) {
            if (MenuOption->Sequence == 2) {
                InputWidth = 4;
            } else {
                InputWidth = 2;
            }

            if (MenuOption->Sequence == 0) {
                InputText[0] = LEFT_NUMERIC_DELIMITER;
                SetUnicodeMem (InputText + 1, InputWidth, L' ');
            } else {
                SetUnicodeMem (InputText, InputWidth, L' ');
            }

            if (MenuOption->Sequence == 2) {
                InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
            } else {
                InputText[InputWidth + 1] = DATE_SEPARATOR;
            }
            InputText[InputWidth + 2] = L'\0';

            PrintAt (Column, Row, InputText);
            if (MenuOption->Sequence == 0) {
                Column++;
            }
        }

        if (Question->Operand == EFI_IFR_TIME_OP) {
            InputWidth = 2;

            if (MenuOption->Sequence == 0) {
                InputText[0] = LEFT_NUMERIC_DELIMITER;
                SetUnicodeMem (InputText + 1, InputWidth, L' ');
            } else {
                SetUnicodeMem (InputText, InputWidth, L' ');
            }

            if (MenuOption->Sequence == 2) {
                InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
            } else {
                InputText[InputWidth + 1] = TIME_SEPARATOR;
            }
            InputText[InputWidth + 2] = L'\0';

            PrintAt (Column, Row, InputText);
            if (MenuOption->Sequence == 0) {
                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 && !ManualInput) {
                    //
                    // 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 ((Step != 0) && !ManualInput) {
                    if (Key.ScanCode == SCAN_LEFT) {
                        if (EditValue >= Minimum + Step) {
                            EditValue = EditValue - Step;
                        } else if (EditValue > Minimum) {
                            EditValue = Minimum;
                        } else {
                            EditValue = Maximum;
                        }
                    } else if (Key.ScanCode == SCAN_RIGHT) {
                        if (EditValue + Step <= Maximum) {
                            EditValue = EditValue + Step;
                        } else if (EditValue < Maximum) {
                            EditValue = Maximum;
                        } else {
                            EditValue = Minimum;
                        }
                    }

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

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

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

                    gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
                    for (Loop = 0; Loop < EraseLen; Loop++) {
                        PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
                    }
                    gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));

                    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:
            //
            // Validate input value with Minimum value.
            //
            if (EditValue < Minimum) {
                UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
                break;
            } else {
                UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
            }

            //
            // 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;
            }

            //
            // Adjust the value to the correct one.
            // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01
            //              2013.03.29 -> 2013.02.29 -> 2013.02.28
            //
            if (Question->Operand == EFI_IFR_DATE_OP &&
                    (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) {
                AdjustQuestionValue (Question, (UINT8)MenuOption->Sequence);
            }

            //
            // 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 (Selection, 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 (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
                Count--;
                Column--;
                PrintAt (Column, Row, L" ");
            }
            break;

        default:
            if (ManualInput) {
                if (HexInput) {
                    if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) {
                        Digital = (UINT8) (Key.UnicodeChar - L'0');
                    } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) {
                        Digital = (UINT8) (Key.UnicodeChar - L'A' + 0x0A);
                    } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {
                        Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A);
                    } else {
                        UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
                        break;
                    }
                } else {
                    if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {
                        UpdateStatusBar (Selection, 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 = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');
                    }
                } else {
                    if (HexInput) {
                        EditValue = Digital;
                    } else {
                        EditValue = Key.UnicodeChar - L'0';
                    }
                }

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

                Count++;
                ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0])));
                PreviousNumber[Count] = EditValue;

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

}
Пример #25
0
/**
  Function for 'time' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunTime (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  CHAR16        *Message;
  EFI_TIME      TheTime;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  INT16         Tz;
  UINT8         Daylight;
  CONST CHAR16  *TempLocation;
  UINTN         TzMinutes;

  ShellStatus  = SHELL_SUCCESS;
  ProblemParam = NULL;

  //
  // Initialize variables
  //
  Message = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  if (PcdGet8(PcdShellSupportLevel) == 2) {
    Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE);
  } else {
    ASSERT(PcdGet8(PcdShellSupportLevel) == 3);
    Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE);
  }
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    Status = gRT->GetTime(&TheTime, NULL);
    ASSERT_EFI_ERROR(Status);
    if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      //
      // If there are no parameters, then print the current time
      //
      if (ShellCommandLineGetRawValue(Package, 1) == NULL
        && !ShellCommandLineGetFlag(Package, L"-d")
        && !ShellCommandLineGetFlag(Package, L"-tz")) {
        //
        // ShellPrintEx the current time
        //
        if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
          TzMinutes = 0;
        } else {
          TzMinutes = (ABS(TheTime.TimeZone)) % 60;
        }

        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_TIME_FORMAT),
          gShellLevel2HiiHandle,
          TheTime.Hour,
          TheTime.Minute,
          TheTime.Second,
          TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?L" ":(TheTime.TimeZone > 0?L"-":L"+"),
          TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60,
          TzMinutes
         );
         ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);
      } else if (ShellCommandLineGetFlag(Package, L"-d") && ShellCommandLineGetValue(Package, L"-d") == NULL) {
        if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
          TzMinutes = 0;
        } else {
          TzMinutes = (ABS(TheTime.TimeZone)) % 60;
        }

        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_TIME_FORMAT),
          gShellLevel2HiiHandle,
          TheTime.Hour,
          TheTime.Minute,
          TheTime.Second,
          TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?L" ":(TheTime.TimeZone > 0?L"-":L"+"),
          TheTime.TimeZone==EFI_UNSPECIFIED_TIMEZONE?0:(ABS(TheTime.TimeZone)) / 60,
          TzMinutes
         );
          switch (TheTime.Daylight) {
            case 0:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle);
              break;
            case EFI_TIME_ADJUST_DAYLIGHT:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);
              break;
            case EFI_TIME_IN_DAYLIGHT:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);
              break;
            case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);
              break;
            default:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);
          }
      } else {
        if (PcdGet8(PcdShellSupportLevel) == 2) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle);
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          //
          // perform level 3 operation here.
          //
          if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) {
            if (TempLocation[0] == L'-') {
              Tz = (INT16)(0 - ShellStrToUintn(++TempLocation));
            } else {
              Tz = (INT16)ShellStrToUintn(TempLocation);
            }
            if (!(Tz >= -1440 && Tz <= 1440) && Tz != EFI_UNSPECIFIED_TIMEZONE) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-tz");
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          } else {
            //
            // intentionally out of bounds value will prevent changing it...
            //
            Tz = 1441;
          }
          TempLocation = ShellCommandLineGetValue(Package, L"-d");
          if (TempLocation != NULL) {
            Daylight = (UINT8)ShellStrToUintn(TempLocation);
            if (Daylight != 0 && Daylight != 1 && Daylight != 3) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-d");
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          } else {
            //
            // invalid = will not use
            //
            Daylight = 0xFF;
          }
          if (ShellStatus == SHELL_SUCCESS) {
            ShellStatus = CheckAndSetTime(ShellCommandLineGetRawValue(Package, 1), Tz, Daylight);
            if (ShellStatus != SHELL_SUCCESS) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ShellCommandLineGetRawValue(Package, 1));
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          }
        }
      }
    }
  }

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  //
  // return the status
  //
  return (ShellStatus);
}
/**

  Publish the smbios type 1.

  @param Event      Event whose notification function is being invoked (gEfiDxeSmmReadyToLockProtocolGuid).
  @param Context    Pointer to the notification functions context, which is implementation dependent.

  @retval None

**/
EFI_STATUS
EFIAPI
AddSmbiosManuCallback (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{

  CHAR8                             *OptionalStrStart;
  UINTN                             ManuStrLen;
  UINTN                             VerStrLen;
  UINTN                             PdNameStrLen;
  UINTN                             SerialNumStrLen;
  UINTN                             SkuNumberStrLen;
  UINTN				                FamilyNameStrLen;
  EFI_STATUS                        Status;
  EFI_STRING                        Manufacturer;
  EFI_STRING                        ProductName;
  EFI_STRING                        Version;
  EFI_STRING                        SerialNumber;
  EFI_STRING                        SkuNumber;
  EFI_STRING			            FamilyName;
  STRING_REF                        TokenToGet;
  EFI_SMBIOS_HANDLE                 SmbiosHandle;
  SMBIOS_TABLE_TYPE1                *SmbiosRecord;
  EFI_MISC_SYSTEM_MANUFACTURER      *ForType1InputData;
  EFI_SMBIOS_PROTOCOL               *Smbios;
  CHAR16                            Buffer[40];
  
  CHAR16                            *MacStr; 
  EFI_HANDLE                        *Handles;
  UINTN                             BufferSize;
  CHAR16                            PlatformNameBuffer[40];

  ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)Context;

  //
  // First check for invalid parameters.
  //
  if (Context == NULL || mPlatformInfo == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID *) &Smbios);
  ASSERT_EFI_ERROR (Status);


  if (BOARD_ID_MINNOW2_COMPATIBLE == mPlatformInfo->BoardId) {
    // Detect the board is compatible board platform
    UnicodeSPrint (PlatformNameBuffer, sizeof (PlatformNameBuffer),L"%s",L"Minnowboard Compatible ");
  } else {
    UnicodeSPrint (PlatformNameBuffer, sizeof (PlatformNameBuffer),L"%s",L"Minnowboard Max ");
  }

  //
  // Silicon Steppings
  //
  switch (PchStepping()) {
    case PchA0:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"A0 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A0");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "A0 Stepping Detected\n"));
      break;
    case PchA1:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"A1 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"A1");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "A1 Stepping Detected\n"));
      break;
    case PchB0:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B0 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B0");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "B0 Stepping Detected\n"));
      break;
    case PchB1:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B1 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B1");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "B1 Stepping Detected\n"));
      break;
    case PchB2:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B2 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B2");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "B2 Stepping Detected\n"));
      break;
    case PchB3:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"B3 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"B3");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "B3 Stepping Detected\n"));
      break;
    case PchC0:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"C0 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"C0");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "C0 Stepping Detected\n"));
      break;
   case PchD0:
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s%s", PlatformNameBuffer, L"D0 PLATFORM");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), Buffer, NULL);
      UnicodeSPrint (Buffer, sizeof (Buffer),L"%s",L"D0");
      HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_VERSION), Buffer, NULL);
      DEBUG ((EFI_D_ERROR, "D0 Stepping Detected\n"));
      break;
    default:
      DEBUG ((EFI_D_ERROR, "Unknow Stepping Detected\n"));
      break;
    }

  if (BOARD_ID_MINNOW2_COMPATIBLE == mPlatformInfo->BoardId) {
    UnicodeSPrint (Buffer, sizeof (Buffer),L"Compatible Vendor");
    HiiSetString(mHiiHandle,STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER), Buffer, NULL);
  }
  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER);
  Manufacturer = SmbiosMiscGetString (TokenToGet);
  ManuStrLen = StrLen(Manufacturer);
  if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) {
    return EFI_UNSUPPORTED;
  }

  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME);
  ProductName = SmbiosMiscGetString (TokenToGet);
  PdNameStrLen = StrLen(ProductName);
  if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
    return EFI_UNSUPPORTED;
  }

  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION);
  Version = SmbiosMiscGetString (TokenToGet);
  VerStrLen = StrLen(Version);
  if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) {
    return EFI_UNSUPPORTED;
  }

  //
  //Get handle infomation
  //
  BufferSize = 0;
  Handles = NULL;
  Status = gBS->LocateHandle (
                  ByProtocol, 
                  &gEfiSimpleNetworkProtocolGuid,
                  NULL,
                  &BufferSize,
                  Handles
                  );

  if (Status == EFI_BUFFER_TOO_SMALL) {
  	Handles = AllocateZeroPool(BufferSize);
  	if (Handles == NULL) {
  		return (EFI_OUT_OF_RESOURCES);
  	}
  	Status = gBS->LocateHandle(
  	                ByProtocol,
  	                &gEfiSimpleNetworkProtocolGuid,
  	                NULL,
  	                &BufferSize,
  	                Handles
  	                );
 }
 	                
  //
  //Get the MAC string
  //
  Status = NetLibGetMacString (
             *Handles,
             NULL,
             &MacStr
             );
  if (EFI_ERROR (Status)) {	
    return Status;
  }
  SerialNumber = MacStr; 
  SerialNumStrLen = StrLen(SerialNumber);
  if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) {
    return EFI_UNSUPPORTED;
  }
  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SKU_NUMBER);
  SkuNumber = SmbiosMiscGetString (TokenToGet);
  SkuNumberStrLen = StrLen(SkuNumber);
  if (SkuNumberStrLen > SMBIOS_STRING_MAX_LENGTH) {
    return EFI_UNSUPPORTED;
  }
  TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_FAMILY_NAME1);
  FamilyName = SmbiosMiscGetString (TokenToGet);
  FamilyNameStrLen = StrLen(FamilyName);
  if (FamilyNameStrLen > SMBIOS_STRING_MAX_LENGTH) {
    return EFI_UNSUPPORTED;
  }

  //
  // Two zeros following the last string.
  //
  SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1);
  ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen + 1 + FamilyNameStrLen + 1 + 1);

  SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION;
  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1);

  //
  // Make handle chosen by smbios protocol.add automatically.
  //
  SmbiosRecord->Hdr.Handle = 0;

  //
  // Manu will be the 1st optional string following the formatted structure.
  //
  SmbiosRecord->Manufacturer = 1;

  //
  // ProductName will be the 2nd optional string following the formatted structure.
  //
  SmbiosRecord->ProductName = 2;

  //
  // Version will be the 3rd optional string following the formatted structure.
  //
  SmbiosRecord->Version = 3;

  //
  // Version will be the 4th optional string following the formatted structure.
  //
  SmbiosRecord->SerialNumber = 4;

  SmbiosRecord->SKUNumber= 5;
  SmbiosRecord->Family= 6;

  //
  // Unique UUID
  //
  ForType1InputData->SystemUuid.Data1 = PcdGet32 (PcdProductSerialNumber);
  ForType1InputData->SystemUuid.Data4[0] = PcdGet8 (PcdEmmcManufacturerId);

  CopyMem ((UINT8 *) (&SmbiosRecord->Uuid),&ForType1InputData->SystemUuid,16);

  SmbiosRecord->WakeUpType = (UINT8)ForType1InputData->SystemWakeupType;

  OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1);
  UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart);
  UnicodeStrToAsciiStr(ProductName, OptionalStrStart + ManuStrLen + 1);
  UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1);
  UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1);

  UnicodeStrToAsciiStr(SkuNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 +  VerStrLen + 1 + SerialNumStrLen + 1);
  UnicodeStrToAsciiStr(FamilyName, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + SkuNumberStrLen +1);

  //
  // Now we have got the full smbios record, call smbios protocol to add this record.
  //
  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  Status = Smbios-> Add(
                      Smbios,
                      NULL,
                      &SmbiosHandle,
                      (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord
                      );
  FreePool(SmbiosRecord);
  return Status;
}
Пример #27
0
/**
  Install TCG ACPI Table when ACPI Table Protocol is available.

  A system's firmware uses an ACPI table to identify the system's TCG capabilities 
  to the Post-Boot environment. The information in this ACPI table is not guaranteed 
  to be valid until the Host Platform transitions from pre-boot state to post-boot state.  

  @param[in]  Event     Event whose notification function is being invoked
  @param[in]  Context   Pointer to the notification function's context
**/
VOID
EFIAPI
InstallAcpiTable (
  IN EFI_EVENT                      Event,
  IN VOID*                          Context
  )
{
  UINTN                             TableKey;
  EFI_STATUS                        Status;
  EFI_ACPI_TABLE_PROTOCOL           *AcpiTable;
  UINT8                             Checksum;
  UINT64                            OemTableId;

  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
  if (EFI_ERROR (Status)) {
    return;
  }

  if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
    CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));
    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
    mTcgClientAcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);
    mTcgClientAcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);
    mTcgClientAcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    //
    // The ACPI table must be checksumed before calling the InstallAcpiTable() 
    // service of the ACPI table protocol to install it.
    //
    Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));
    mTcgClientAcpiTemplate.Header.Checksum = Checksum;

    Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            &mTcgClientAcpiTemplate,
                            sizeof (mTcgClientAcpiTemplate),
                            &TableKey
                            );
  } else {
    CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));
    OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
    CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
    mTcgServerAcpiTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);
    mTcgServerAcpiTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);
    mTcgServerAcpiTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);
    //
    // The ACPI table must be checksumed before calling the InstallAcpiTable() 
    // service of the ACPI table protocol to install it.
    //
    Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));
    mTcgServerAcpiTemplate.Header.Checksum = Checksum;

    mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress);
    Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            &mTcgServerAcpiTemplate,
                            sizeof (mTcgServerAcpiTemplate),
                            &TableKey
                            );
  }

  if (EFI_ERROR (Status)) {
    DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));
  }
}
Пример #28
0
/**
  Function for 'time' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunTime (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  EFI_TIME      TheTime;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  INT16         Tz;
  UINT8         Daylight;
  CONST CHAR16  *TempLocation;
  UINTN         TzMinutes;

  //
  // Initialize variables
  //
  ShellStatus  = SHELL_SUCCESS;
  ProblemParam = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  if (PcdGet8(PcdShellSupportLevel) == 2) {
    Status = ShellCommandLineParseEx (TimeParamList2, &Package, &ProblemParam, TRUE, TRUE);
  } else {
    ASSERT(PcdGet8(PcdShellSupportLevel) == 3);
    Status = ShellCommandLineParseEx (TimeParamList3, &Package, &ProblemParam, TRUE, TRUE);
  }
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"time", ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    Status = gRT->GetTime(&TheTime, NULL);
    if (EFI_ERROR(Status)) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_WARN), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", Status);
      return (SHELL_DEVICE_ERROR);
    }

    if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    } else if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time");
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      //
      // If there are no parameters, then print the current time
      //
      if (ShellCommandLineGetRawValue(Package, 1) == NULL
        && !ShellCommandLineGetFlag(Package, L"-d")
        && !ShellCommandLineGetFlag(Package, L"-tz")) {
        //
        // ShellPrintEx the current time
        //
        if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
          TzMinutes = 0;
        } else {
          TzMinutes = (ABS(TheTime.TimeZone)) % 60;
        }

        if (TheTime.TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_TIME_FORMAT),
            gShellLevel2HiiHandle,
            TheTime.Hour,
            TheTime.Minute,
            TheTime.Second,
            (TheTime.TimeZone > 0?L"-":L"+"),
            ((ABS(TheTime.TimeZone)) / 60),
            TzMinutes
            );
        } else {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_TIME_FORMAT_LOCAL),
            gShellLevel2HiiHandle,
            TheTime.Hour,
            TheTime.Minute,
            TheTime.Second
            );
        }
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);
      } else if (ShellCommandLineGetFlag(Package, L"-d") && ShellCommandLineGetValue(Package, L"-d") == NULL) {
        if (TheTime.TimeZone == EFI_UNSPECIFIED_TIMEZONE) {
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_TIME_FORMAT_LOCAL),
            gShellLevel2HiiHandle,
            TheTime.Hour,
            TheTime.Minute,
            TheTime.Second
            );
        } else {
          TzMinutes = (ABS(TheTime.TimeZone)) % 60;
          ShellPrintHiiEx (
            -1,
            -1,
            NULL,
            STRING_TOKEN (STR_TIME_FORMAT),
            gShellLevel2HiiHandle,
            TheTime.Hour,
            TheTime.Minute,
            TheTime.Second,
            (TheTime.TimeZone > 0?L"-":L"+"),
            ((ABS(TheTime.TimeZone)) / 60),
            TzMinutes
           );
        }
          switch (TheTime.Daylight) {
            case 0:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle);
              break;
            case EFI_TIME_ADJUST_DAYLIGHT:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);
              break;
            case EFI_TIME_IN_DAYLIGHT:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);
              break;
            case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);
              break;
            default:
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"time", L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);
          }
      } else {
        if (PcdGet8(PcdShellSupportLevel) == 2) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel2HiiHandle, L"time");
          ShellStatus = SHELL_INVALID_PARAMETER;
        } else {
          //
          // perform level 3 operation here.
          //
          if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) {
            if (gUnicodeCollation->StriColl(gUnicodeCollation, (CHAR16 *)TempLocation, L"_local") == 0) {
              Tz = EFI_UNSPECIFIED_TIMEZONE;
            } else if (TempLocation[0] == L'-') {

              Tz = (INT16) ShellStrToUintn (++TempLocation);
              //
              // When the argument of "time [-tz tz]" is not numeric, ShellStrToUintn() returns "-1".
              // Here we can detect the argument error by checking the return of ShellStrToUintn().
              //
              if (Tz == -1) {
                Tz = 1441; //make it to be out of bounds value
              } else {
                Tz *= (-1); //sign convert
              }
            } else {
              if (TempLocation[0] == L'+') {
                Tz = (INT16)ShellStrToUintn (++TempLocation);
              } else {
                Tz = (INT16)ShellStrToUintn (TempLocation);
              }
              //
              // Detect the return of ShellStrToUintn() to make sure the argument is valid.
              //
              if (Tz == -1) {
                Tz = 1441; //make it to be out of bounds value
              }
            }
            if (!(Tz >= -1440 && Tz <= 1440) && Tz != EFI_UNSPECIFIED_TIMEZONE) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-tz");
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          } else {
            //
            // intentionally out of bounds value will prevent changing it...
            //
            Tz = 1441;
          }
          TempLocation = ShellCommandLineGetValue(Package, L"-d");
          if (TempLocation != NULL) {
            Daylight = (UINT8)ShellStrToUintn(TempLocation);
            //
            // The argument of "time [-d dl]" is unsigned, if the first character is '-',
            // the argument is incorrect.  That's because ShellStrToUintn() will skip past
            // any '-' sign and convert what's next, forgetting the sign is here.
            //
            if (TempLocation[0] == '-') {
              Daylight = 0xff; //make it invalid = will not use
            }
            if (Daylight != 0 && Daylight != 1 && Daylight != 3) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"time", TempLocation, L"-d");
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          } else {
            //
            // invalid = will not use
            //
            Daylight = 0xFF;
          }
          if (ShellStatus == SHELL_SUCCESS) {
            ShellStatus = CheckAndSetTime(ShellCommandLineGetRawValue(Package, 1), Tz, Daylight);
            if (ShellStatus != SHELL_SUCCESS) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel2HiiHandle, L"time", ShellCommandLineGetRawValue(Package, 1));
              ShellStatus = SHELL_INVALID_PARAMETER;
            }
          }
        }
      }
    }
  }

  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  //
  // return the status
  //
  return (ShellStatus);
}
Пример #29
0
EFI_STATUS
FchSmmRegisterSwSmi (
  VOID
  )
{
  EFI_STATUS                               Status;
  FCH_SMM_SW_DISPATCH2_PROTOCOL            *AmdSwDispatch;
  FCH_SMM_SW_REGISTER_CONTEXT              SwRegisterContext;
  EFI_HANDLE                               SwHandle;
  FCH_MISC                                 *FchMisc;

  FchMisc = &gFchInitInSmm.FchPolicy.Misc;

  //
  //  Locate SMM SW dispatch protocol
  //
  Status = gSmst->SmmLocateProtocol (
                  &gFchSmmSwDispatch2ProtocolGuid,
                  NULL,
                  &AmdSwDispatch
                  );
  ASSERT_EFI_ERROR (Status);

  SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemBeforePciRestoreSwSmi); // use of PCD in place of FCHOEM_BEFORE_PCI_RESTORE_SWSMI    0xD3
  SwRegisterContext.Order       = 0x80;
  Status = AmdSwDispatch->Register (
                            AmdSwDispatch,
                            AmdSmiBeforePciS3RestoreCallback,
                            &SwRegisterContext,
                            &SwHandle
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }


  SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemAfterPciRestoreSwSmi); // use of PCD in place of FCHOEM_AFTER_PCI_RESTORE_SWSMI    0xD4
  SwRegisterContext.Order       = 0x80;
  Status = AmdSwDispatch->Register (
                            AmdSwDispatch,
                            AmdSmiAfterPciS3RestoreCallback,
                            &SwRegisterContext,
                            &SwHandle
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }


  SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemEnableAcpiSwSmi); // use of PCD in place of FCHOEM_ENABLE_ACPI_SWSMI           0xA0
  SwRegisterContext.Order       = 0x80;
  Status = AmdSwDispatch->Register (
                            AmdSwDispatch,
                            AmdSmiAcpiOnCallback,
                            &SwRegisterContext,
                            &SwHandle
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }


  SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemDisableAcpiSwSmi); // use of PCD in place of FCHOEM_DISABLE_ACPI_SWSMI          0xA1
  SwRegisterContext.Order       = 0x80;
  Status = AmdSwDispatch->Register (
                            AmdSwDispatch,
                            AmdSmiAcpiOffCallback,
                            &SwRegisterContext,
                            &SwHandle
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

#ifdef FCH_SPI_PROTECT_SMI
  SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemSpiUnlockSwSmi); // use of PCD in place of FCHOEM_SPI_UNLOCK_SWSMI            0xAA
  SwRegisterContext.Order       = 0x80;
  Status = AmdSwDispatch->Register (
                            AmdSwDispatch,
                            AmdSmiSpiUnlockCallback,
                            &SwRegisterContext,
                            &SwHandle
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemSpiLockSwSmi); // use of PCD in place of FCHOEM_SPI_LOCK_SWSMI              0xAB
  SwRegisterContext.Order       = 0x80;
  Status = AmdSwDispatch->Register (
                            AmdSwDispatch,
                            AmdSmiSpiLockCallback,
                            &SwRegisterContext,
                            &SwHandle
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }
#endif

  if (FchMisc->LongTimer.Enable || FchMisc->ShortTimer.Enable) {
    SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemStartTimerSmi); // use of PCD in place of FCHOEM_START_TIMER_SMI             0xBC
    SwRegisterContext.Order       = 0x80;
    Status = AmdSwDispatch->Register (
                              AmdSwDispatch,
                              AmdStartTimerSmiCallback,
                              &SwRegisterContext,
                              &SwHandle
                              );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    SwRegisterContext.AmdSwValue  = PcdGet8(PcdFchOemStopTimerSmi); // use of PCD in place of FCHOEM_STOP_TIMER_SMI              0xBD
    SwRegisterContext.Order       = 0x80;
    Status = AmdSwDispatch->Register (
                              AmdSwDispatch,
                              AmdStopTimerSmiCallback,
                              &SwRegisterContext,
                              &SwHandle
                              );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}
Пример #30
0
/**
  Entry point of this module.

  @param[in] FileHandle   Handle of the file being invoked.
  @param[in] PeiServices  Describes the list of possible PEI Services.

  @return Status.

**/
EFI_STATUS
EFIAPI
PeimEntryMA (
    IN       EFI_PEI_FILE_HANDLE      FileHandle,
    IN CONST EFI_PEI_SERVICES         **PeiServices
)
{
    EFI_STATUS                        Status;
    EFI_STATUS                        Status2;
    EFI_BOOT_MODE                     BootMode;
    TPM_PCRINDEX                      PcrIndex;
    BOOLEAN                           S3ErrorReport;

    if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
            CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
        DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
        return EFI_UNSUPPORTED;
    }

    if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
        DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
        return EFI_DEVICE_ERROR;
    }

    Status = PeiServicesGetBootMode (&BootMode);
    ASSERT_EFI_ERROR (Status);

    //
    // In S3 path, skip shadow logic. no measurement is required
    //
    if (BootMode != BOOT_ON_S3_RESUME) {
        Status = (**PeiServices).RegisterForShadow(FileHandle);
        if (Status == EFI_ALREADY_STARTED) {
            mImageInMemory = TRUE;
            mFileHandle = FileHandle;
        } else if (Status == EFI_NOT_FOUND) {
            ASSERT_EFI_ERROR (Status);
        }
    }

    if (!mImageInMemory) {
        //
        // Initialize TPM device
        //
        Status = Tpm2RequestUseTpm ();
        if (EFI_ERROR (Status)) {
            DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n"));
            goto Done;
        }

        S3ErrorReport = FALSE;
        if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
            if (BootMode == BOOT_ON_S3_RESUME) {
                Status = Tpm2Startup (TPM_SU_STATE);
                if (EFI_ERROR (Status) ) {
                    Status = Tpm2Startup (TPM_SU_CLEAR);
                    if (!EFI_ERROR(Status)) {
                        S3ErrorReport = TRUE;
                    }
                }
            } else {
                Status = Tpm2Startup (TPM_SU_CLEAR);
            }
            if (EFI_ERROR (Status) ) {
                goto Done;
            }
        }

        //
        // Update Tpm2HashMask according to PCR bank.
        //
        SyncPcrAllocationsAndPcrMask ();

        if (S3ErrorReport) {
            //
            // The system firmware that resumes from S3 MUST deal with a
            // TPM2_Startup error appropriately.
            // For example, issue a TPM2_Startup(TPM_SU_CLEAR) command and
            // configuring the device securely by taking actions like extending a
            // separator with an error digest (0x01) into PCRs 0 through 7.
            //
            for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {
                Status = MeasureSeparatorEventWithError (PcrIndex);
                if (EFI_ERROR (Status)) {
                    DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n"));
                }
            }
        }

        //
        // TpmSelfTest is optional on S3 path, skip it to save S3 time
        //
        if (BootMode != BOOT_ON_S3_RESUME) {
            if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {
                Status = Tpm2SelfTest (NO);
                if (EFI_ERROR (Status)) {
                    goto Done;
                }
            }
        }

        //
        // Only intall TpmInitializedPpi on success
        //
        Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
        ASSERT_EFI_ERROR (Status);
    }

    if (mImageInMemory) {
        Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
        return Status;
    }

Done:
    if (EFI_ERROR (Status)) {
        DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n"));
        BuildGuidHob (&gTpmErrorHobGuid,0);
        REPORT_STATUS_CODE (
            EFI_ERROR_CODE | EFI_ERROR_MINOR,
            (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
        );
    }
    //
    // Always intall TpmInitializationDonePpi no matter success or fail.
    // Other driver can know TPM initialization state by TpmInitializedPpi.
    //
    Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
    ASSERT_EFI_ERROR (Status2);

    return Status;
}