Example #1
0
VOID *
EfiLibAllocateZeroPool (
  IN  UINTN   AllocationSize
  )
/*++

Routine Description:

  Allocate BootServicesData pool and zero it.

Arguments:

  AllocationSize  - The size to allocate

Returns:

  Pointer of the buffer allocated.

--*/
{
  VOID  *Memory;

  Memory = EfiLibAllocatePool (AllocationSize);
  if (Memory != NULL) {
    gBS->SetMem (Memory, AllocationSize, 0);
  }

  return Memory;
}
Example #2
0
EFI_STATUS
ValidateDataFromHiiHandle (
  IN      EFI_HII_HANDLE      HiiHandle,
  OUT     BOOLEAN             *Results
  )
/*++

Routine Description:

  Validate that the data associated with the HiiHandle in NVRAM is within
  the reasonable parameters for that FormSet.  Values for strings and passwords
  are not verified due to their not having the equivalent of valid range settings.
  
Arguments:

  HiiHandle -   Handle of the HII database entry to query

  Results -     If return Status is EFI_SUCCESS, Results provides valid data
                TRUE  = NVRAM Data is within parameters
                FALSE = NVRAM Data is NOT within parameters
  
Returns: 

  EFI_OUT_OF_RESOURCES      - No enough buffer to allocate
  
  EFI_SUCCESS               - Data successfully validated
--*/
{
  EFI_STATUS        Status;
  EFI_HII_PROTOCOL  *Hii;
  EFI_GUID          Guid;
  UINT8             *RawData;
  UINT8             *OldData;
  UINTN             RawDataLength;
  UINT8             *VariableData;
  UINTN             Index;
  UINTN             Temp;
  UINTN             SizeOfNvStore;
  UINTN             CachedStart;
  BOOLEAN           GotMatch;

  RawDataLength = DEFAULT_FORM_BUFFER_SIZE;
  SizeOfNvStore = 0;
  CachedStart   = 0;
  GotMatch      = FALSE;
  *Results      = TRUE;

  Status        = GetHiiInterface (&Hii);

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

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

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

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

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

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

  OldData = RawData;

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

  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
    if (RawData[Index] == EFI_IFR_FORM_SET_OP) {
      EfiCopyMem (&Guid, &((EFI_IFR_FORM_SET *) &RawData[Index])->Guid, sizeof (EFI_GUID));
      break;
    }

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

  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
    switch (RawData[Index]) {
    case EFI_IFR_FORM_SET_OP:
      break;

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

    Index = RawData[Index + 1] + Index;
  }
    
  //
  // Allocate memory for our File Form Tags
  //
  VariableData = EfiLibAllocateZeroPool (SizeOfNvStore);
  if (VariableData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gRT->GetVariable (
                  L"Setup",
                  &Guid,
                  NULL,
                  &SizeOfNvStore,
                  (VOID *) VariableData
                  );

  if (EFI_ERROR (Status)) {

    //
    // If there is a variable that exists already and it is larger than what we calculated the
    // storage needs to be, we must assume the variable size from GetVariable is correct and not
    // allow the truncation of the variable.  It is very possible that the user who created the IFR
    // we are cracking is not referring to a variable that was in a previous map, however we cannot
    // allow it's truncation.
    //
    if (Status == EFI_BUFFER_TOO_SMALL) {
      //
      // Free the buffer that was allocated that was too small
      //
      gBS->FreePool (VariableData);

      VariableData = EfiLibAllocatePool (SizeOfNvStore);
      if (VariableData == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      Status = gRT->GetVariable (
                      L"Setup",
                      &Guid,
                      NULL,
                      &SizeOfNvStore,
                      (VOID *) VariableData
                      );
    }
  }

  //
  // Walk through the form and see that the variable data it refers to is ok.
  // This allows for the possibility of stale (obsoleted) data in the variable
  // can be overlooked without causing an error
  //
  for (Index = 0; RawData[Index] != EFI_IFR_END_FORM_SET_OP;) {
    switch (RawData[Index]) {
    case EFI_IFR_ONE_OF_OP:
      //
      // A one_of has no data, its the option that does - cache the storage Id
      //
      CachedStart = ((EFI_IFR_ONE_OF *) &RawData[Index])->QuestionId;
      break;

    case EFI_IFR_ONE_OF_OPTION_OP:
      //
      // A one_of_option can be any value
      //
      if (VariableData[CachedStart] == ((EFI_IFR_ONE_OF_OPTION *) &RawData[Index])->Value) {
        GotMatch = TRUE;
      }
      break;

    case EFI_IFR_END_ONE_OF_OP:
      //
      // At this point lets make sure that the data value in the NVRAM matches one of the options
      //
      if (!GotMatch) {
        *Results = FALSE;
        return EFI_SUCCESS;
      }
      break;

    case EFI_IFR_CHECKBOX_OP:
      //
      // A checkbox is a boolean, so 0 and 1 are valid
      // Remember, QuestionId corresponds to the offset location of the data in the variable
      //
      if (VariableData[((EFI_IFR_CHECK_BOX *) &RawData[Index])->QuestionId] > 1) {
        *Results = FALSE;
        return EFI_SUCCESS;
      }
      break;

    case EFI_IFR_NUMERIC_OP:
        if ((VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] < ((EFI_IFR_NUMERIC *)&RawData[Index])->Minimum) ||
            (VariableData[((EFI_IFR_NUMERIC *)&RawData[Index])->QuestionId] > ((EFI_IFR_NUMERIC *)&RawData[Index])->Maximum)) {
        *Results = FALSE;
        return EFI_SUCCESS;
      }
      break;

    }

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

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

  return EFI_SUCCESS;
}
Example #3
0
EFI_HII_HANDLE
FindHiiHandle (
  IN OUT EFI_HII_PROTOCOL    **HiiProtocol, OPTIONAL
  IN     EFI_GUID            *Guid
  )
/*++

Routine Description:
  Finds HII handle for given pack GUID previously registered with the HII.

Arguments:
  HiiProtocol - pointer to pointer to HII protocol interface. 
                If NULL, the interface will be found but not returned.
                If it points to NULL, the interface will be found and 
                written back to the pointer that is pointed to.
  Guid        - The GUID of the pack that registered with the HII.

Returns:
  Handle to the HII pack previously registered by the memory driver.

--*/
{
  EFI_STATUS        Status;

  EFI_HII_HANDLE    *HiiHandleBuffer;
  EFI_HII_HANDLE    HiiHandle;
  UINT16            HiiHandleBufferLength;
  UINT32            NumberOfHiiHandles;
  EFI_GUID          HiiGuid;
  EFI_HII_PROTOCOL  *HiiProt;
  UINT32            Index;
  UINT16            Length;

  HiiHandle = 0;
  if ((HiiProtocol != NULL) && (*HiiProtocol != NULL)) {
    //
    // The protocol has been passed in
    //
    HiiProt = *HiiProtocol;
  } else {
    gBS->LocateProtocol (
          &gEfiHiiProtocolGuid,
          NULL,
          (VOID **) &HiiProt
          );
    if (HiiProt == NULL) {
      return HiiHandle;
    }

    if (HiiProtocol != NULL) {
      //
      // Return back the HII protocol for the caller as promissed
      //
      *HiiProtocol = HiiProt;
    }
  }
  //
  // Allocate buffer
  //
  HiiHandleBufferLength = 10;
  HiiHandleBuffer       = EfiLibAllocatePool (HiiHandleBufferLength);
  ASSERT (HiiHandleBuffer != NULL);

  //
  // Get the Handles of the packages that were registered with Hii
  //
  Status = HiiProt->FindHandles (
                      HiiProt,
                      &HiiHandleBufferLength,
                      HiiHandleBuffer
                      );

  //
  // Get a bigger bugffer if this one is to small, and try again
  //
  if (Status == EFI_BUFFER_TOO_SMALL) {

    gBS->FreePool (HiiHandleBuffer);

    HiiHandleBuffer = EfiLibAllocatePool (HiiHandleBufferLength);
    ASSERT (HiiHandleBuffer != NULL);

    Status = HiiProt->FindHandles (
                        HiiProt,
                        &HiiHandleBufferLength,
                        HiiHandleBuffer
                        );
  }

  if (EFI_ERROR (Status)) {
    goto lbl_exit;
  }

  NumberOfHiiHandles = HiiHandleBufferLength / sizeof (EFI_HII_HANDLE);

  //
  // Iterate Hii handles and look for the one that matches our Guid
  //
  for (Index = 0; Index < NumberOfHiiHandles; Index++) {

    Length = 0;
    ExtractDataFromHiiHandle (HiiHandleBuffer[Index], &Length, NULL, &HiiGuid);

    if (EfiCompareGuid (&HiiGuid, Guid)) {

      HiiHandle = HiiHandleBuffer[Index];
      break;
    }
  }

lbl_exit:
  gBS->FreePool (HiiHandleBuffer);
  return HiiHandle;
}
Example #4
0
EFI_STATUS
ConvertBmpToGopBlt (
  IN  VOID      *BmpImage,
  IN  UINTN     BmpImageSize,
  IN OUT VOID   **GopBlt,
  IN OUT UINTN  *GopBltSize,
  OUT UINTN     *PixelHeight,
  OUT UINTN     *PixelWidth
  )
/*++

Routine Description:

  Convert a *.BMP graphics image to a GOP/UGA blt buffer. If a NULL Blt buffer
  is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt
  buffer is passed in it will be used if it is big enough.

Arguments:

  BmpImage      - Pointer to BMP file

  BmpImageSize  - Number of bytes in BmpImage

  GopBlt        - Buffer containing GOP version of BmpImage.

  GopBltSize    - Size of GopBlt in bytes.

  PixelHeight   - Height of GopBlt/BmpImage in pixels

  PixelWidth    - Width of GopBlt/BmpImage in pixels


Returns: 

  EFI_SUCCESS           - GopBlt and GopBltSize are returned. 
  EFI_UNSUPPORTED       - BmpImage is not a valid *.BMP image
  EFI_BUFFER_TOO_SMALL  - The passed in GopBlt buffer is not big enough.
                          GopBltSize will contain the required size.
  EFI_OUT_OF_RESOURCES  - No enough buffer to allocate

--*/
{
  UINT8                         *Image;
  UINT8                         *ImageHeader;
  BMP_IMAGE_HEADER              *BmpHeader;
  BMP_COLOR_MAP                 *BmpColorMap;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
  UINT64                        BltBufferSize;
  UINTN                         Index;
  UINTN                         Height;
  UINTN                         Width;
  UINTN                         ImageIndex;
  BOOLEAN                       IsAllocated;

  BmpHeader = (BMP_IMAGE_HEADER *) BmpImage;
  if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') {
    return EFI_UNSUPPORTED;
  }

  if (BmpHeader->CompressionType != 0) {
    return EFI_UNSUPPORTED;
  }

  //
  // Calculate Color Map offset in the image.
  //
  Image       = BmpImage;
  BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER));

  //
  // Calculate graphics image data address in the image
  //
  Image         = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset;
  ImageHeader   = Image;

  BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight);
  //
  // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow
  //
  if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), NULL)) {
     return EFI_UNSUPPORTED;
  }
  BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));

  IsAllocated   = FALSE;
  if (*GopBlt == NULL) {
    *GopBltSize = (UINTN) BltBufferSize;
    *GopBlt     = EfiLibAllocatePool (*GopBltSize);
    IsAllocated = TRUE;
    if (*GopBlt == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    if (*GopBltSize < (UINTN) BltBufferSize) {
      *GopBltSize = (UINTN) BltBufferSize;
      return EFI_BUFFER_TOO_SMALL;
    }
  }

  *PixelWidth   = BmpHeader->PixelWidth;
  *PixelHeight  = BmpHeader->PixelHeight;

  //
  // Convert image from BMP to Blt buffer format
  //
  BltBuffer = *GopBlt;
  for (Height = 0; Height < BmpHeader->PixelHeight; Height++) {
    Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth];
    for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) {
      switch (BmpHeader->BitPerPixel) {
      case 1:
        //
        // Convert 1bit BMP to 24-bit color
        //
        for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) {
          Blt->Red    = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red;
          Blt->Green  = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green;
          Blt->Blue   = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue;
          Blt++;
          Width++;
        }

        Blt --;
        Width --;
        break;

      case 4:
        //
        // Convert BMP Palette to 24-bit color
        //
        Index       = (*Image) >> 4;
        Blt->Red    = BmpColorMap[Index].Red;
        Blt->Green  = BmpColorMap[Index].Green;
        Blt->Blue   = BmpColorMap[Index].Blue;
        if (Width < (BmpHeader->PixelWidth - 1)) {
          Blt++;
          Width++;
          Index       = (*Image) & 0x0f;
          Blt->Red    = BmpColorMap[Index].Red;
          Blt->Green  = BmpColorMap[Index].Green;
          Blt->Blue   = BmpColorMap[Index].Blue;
        }
        break;

      case 8:
        //
        // Convert BMP Palette to 24-bit color
        //
        Blt->Red    = BmpColorMap[*Image].Red;
        Blt->Green  = BmpColorMap[*Image].Green;
        Blt->Blue   = BmpColorMap[*Image].Blue;
        break;

      case 24:
        Blt->Blue   = *Image++;
        Blt->Green  = *Image++;
        Blt->Red    = *Image;
        break;

      default:
        if (IsAllocated) {
          gBS->FreePool (*GopBlt);
          *GopBlt = NULL;
        }
        return EFI_UNSUPPORTED;
        break;
      };

    }

    ImageIndex = (UINTN) (Image - ImageHeader);
    if ((ImageIndex % 4) != 0) {
      //
      // Bmp Image starts each row on a 32-bit boundary!
      //
      Image = Image + (4 - (ImageIndex % 4));
    }
  }

  return EFI_SUCCESS;
}
Example #5
0
EFI_STATUS prepareTapeTest(int initTestFileMarkCnt, int initTestBlockMarkCnt)
{
  EFI_STATUS status;
  char *buffer=NULL;
  UINTN bufferSize = MAX_TAPE_BUFFER_SIZE; 
  EFI_INPUT_KEY Key;
  int index, ii;
  	
  buffer = (char *)EfiLibAllocatePool(bufferSize);
  
  //  1.0 check input parameters
  if((buffer==NULL) || (gTapeIoProtocol==NULL))
  	status = EFI_INVALID_PARAMETER;
  else
    status = EFI_SUCCESS;	
    
  if(status == EFI_SUCCESS)
  {
	Print (L"\r\n  Tape IO protocol Test will lose all data on the Tape? (Y/N)");
	status = gtST->ConIn->ReadKeyStroke (gtST->ConIn, &Key); 
	while(status == EFI_NOT_READY){
        status = gtST->ConIn->ReadKeyStroke(gtST->ConIn, &Key);
        if((status == EFI_SUCCESS) &&
           (Key.UnicodeChar != 'Y') && 
           (Key.UnicodeChar != 'y') && 
           (Key.UnicodeChar != 'N') && 
           (Key.UnicodeChar != 'n'))
        {
          // check for a valid key
          Print (L"\r\n      Invalid selection ......................... enter (Y/N)");
          status = EFI_NOT_READY;
        }
    }

	if((Key.UnicodeChar == 'Y') || (Key.UnicodeChar == 'y'))
	{
        Print (L"\r\n  Preparing tape ... ");
			 	
	  	for(index=0; index<(int)bufferSize; index++)
	  		buffer[index] = (char)index;

	  	//  Note: the returned status has not check after calling TapeIoProtocol()
	  	//  reset tape	driver	  	
	  	status = gTapeIoProtocol->TapeReset(gTapeIoProtocol, 1);  
	  	Print (L"\r\n  Reset tape ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") );
		if(status != EFI_SUCCESS)
			goto prepareTapeTestEnd;
			
	  	//  goto tape begin
	  	status = gTapeIoProtocol->TapeRewind(gTapeIoProtocol);	
	  	Print (L"\r\n  Rewind tape I ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") );
		if(status != EFI_SUCCESS)
			goto prepareTapeTestEnd;
			
	  	//  write some data and FileMark
	  	initTestFileMarkCnt = (initTestFileMarkCnt<TAPE_IO_TEST_FILEMARK_CNT) ? TAPE_IO_TEST_FILEMARK_CNT : initTestFileMarkCnt;
	  	for(index=0; index<initTestFileMarkCnt; index++)
	  	{	  	
	  		Print (L"\r\n  Write tape(%d, %d) ... ", index+1, initTestBlockMarkCnt);
	  		for(ii=0; ii<initTestBlockMarkCnt; ii++)
	  		{
			  	bufferSize = MAX_TAPE_BUFFER_SIZE;
			  	status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer);
			  	Print (L"%s", ((status == EFI_SUCCESS) ? L"." : L"Fail!") );
			  	if(status != EFI_SUCCESS)
					goto prepareTapeTestEnd;
		  	}
		  	
		  	status = gTapeIoProtocol->TapeWriteFM(gTapeIoProtocol, 1);
		  	Print (L" %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") );
		  	if(status != EFI_SUCCESS)
				goto prepareTapeTestEnd;
	  	}
		                            
		//  write some other FileMark
		status = gTapeIoProtocol->TapeWriteFM(gTapeIoProtocol, 10);
		Print (L"\r\n  WriteFM II ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") );

        //  goto tape begin
	  	status = gTapeIoProtocol->TapeRewind(gTapeIoProtocol);
	  	Print (L"\r\n  Rewind tape II ... %s", ((status == EFI_SUCCESS) ? L"O.K." : L"Fail!") );
	  	
	  	if(status != EFI_SUCCESS)
			goto prepareTapeTestEnd;	
    }
    
  } 

prepareTapeTestEnd:     
  if(buffer!=NULL)
  	gBS->FreePool(buffer);	  

  logMsg(gTapeBBTestMainAssertionGuid02E,
  			"EFI_TAPE_IO_PROTOCOL Test", 
  			"prepare for tape testing", 
  			status, 
  			EFI_SUCCESS
  		);  
  		
  Print (L"\r\n  prepareTapeTest Completed.\r\n");		
  return status;	  
}
Example #6
0
EFI_STATUS
BBTestTapeFunctionWrite (
  IN EFI_BB_TEST_PROTOCOL             *_This,
  IN VOID                             *ClientInterface,
  IN EFI_TEST_LEVEL                   TestLevel,
  IN EFI_HANDLE                       SupportHandle
  )
{
  EFI_STATUS status;
  char *buffer=NULL;
  UINTN bufferSize = MAX_TAPE_BUFFER_SIZE; 
  
  getStandardLibInterface(SupportHandle);
  //
  // Enter a function. It is put at the entry point of a function
  LogEnterFunction( LoggingLib, 
  							L"BBTestTapeFunctionWrite",
  							L"%a:%d : EnterFunction",
  							__FILE__, (UINTN)__LINE__ );  
  							
  buffer = (char *)EfiLibAllocatePool(bufferSize);
  
  //  2.0 check input parameters
  gTapeIoProtocol = (EFI_TAPE_IO_PROTOCOL *)ClientInterface;
  if((buffer==NULL)||(_This==NULL) || (LoggingLib==NULL) || (gTapeIoProtocol==NULL))
  	status = EFI_INVALID_PARAMETER;
  else
    status = EFI_SUCCESS;
  logMsg(gTapeBBTestMainAssertionGuid008,
  			"EFI_TAPE_IO_PROTOCOL write test", 
  			"check input parameters", 
  			status, 
  			EFI_SUCCESS
  		);  

  if(status != EFI_SUCCESS)
  	goto BBTestTapeFunctionWriteEnd;	
  	
  //  2.1 TapeWrite with valid parameters
  status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer);
  logMsg(gTapeBBTestMainAssertionGuid009,
  			"EFI_TAPE_IO_PROTOCOL.TapeWrite", 
  			"with valid parameters", 
  			status, 
  			EFI_SUCCESS
  		);

  switch(status)
  {
  	case EFI_SUCCESS:
  	case EFI_END_OF_MEDIA:	 
  		 break;
  	  	
  	case EFI_NO_MEDIA:
  	case EFI_MEDIA_CHANGED:
  	case EFI_DEVICE_ERROR:
  	case EFI_INVALID_PARAMETER:
  	case EFI_NOT_READY:
  	case EFI_TIMEOUT:
  	case EFI_WRITE_PROTECTED:
  	case EFI_UNSUPPORTED:
  	default:
  		 goto BBTestTapeFunctionWriteEnd;
  		 break;
  }

  //  2.2.1 TapeWrite with invalid parameters
  bufferSize = MAX_TAPE_BUFFER_SIZE;
  status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, NULL);
  logMsg(gTapeBBTestMainAssertionGuid00A,
  			"EFI_TAPE_IO_PROTOCOL.TapeWrite(Buffer=NULL)", 
  			"with invalid parameters", 
  			status, 
  			EFI_INVALID_PARAMETER
  		);

  //  2.2.2 TapeWrite with invalid parameters
  bufferSize = MAX_TAPE_BUFFER_SIZE;
  status = gTapeIoProtocol->TapeWrite(NULL, &bufferSize, buffer);
  logMsg(gTapeBBTestMainAssertionGuid00B,
  			"EFI_TAPE_IO_PROTOCOL.TapeWrite", 
  			"with invalid parameters(EFI_TAPE_IO_PROTOCOL=NULL)", 
  			status, 
  			EFI_INVALID_PARAMETER
  		);

  //  2.3.1 TapeWrite with invalid parameters
  bufferSize = 0;
  status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, NULL);
  logMsg(gTapeBBTestMainAssertionGuid00C,
  			"EFI_TAPE_IO_PROTOCOL.TapeWrite", 
  			"with invalid parameters(bufferSize=0,buffer=NULL)", 
  			status, 
  			EFI_INVALID_PARAMETER
  		);

  //  2.3.2 TapeWrite with valid parameters
  bufferSize = 0;
  status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer);
  logMsg(gTapeBBTestMainAssertionGuid00E,
  			"EFI_TAPE_IO_PROTOCOL.TapeWrite", 
  			"with valid parameters(bufferSize=0,buffer!=NULL)", 
  			status, 
  			EFI_SUCCESS
  		);
  		
#if 0  		  		
  //  2.4 do TapeWrite with valid parameters until not EFI_SUCCESS
  while(status==EFI_SUCCESS)
  {
  	bufferSize = MAX_TAPE_BUFFER_SIZE;
  	status = gTapeIoProtocol->TapeWrite(gTapeIoProtocol, &bufferSize, buffer);
  }
  logMsg(gTapeBBTestMainAssertionGuid00D,
  			"EFI_TAPE_IO_PROTOCOL.TapeWrite", 
  			"do with valid parameters until not EFI_SUCCESS", 
  			status, 
  			EFI_SUCCESS
  		);
#endif
  		  
BBTestTapeFunctionWriteEnd:	
  if(buffer!=NULL)
  	gBS->FreePool(buffer);		
  	    							
  //
  // Exit a function. It is put at the exit point of a function
  LogExitFunction( LoggingLib, 
  							L"BBTestTapeFunctionWrite",
  							L"%a:%d : ExitFunction",
  							__FILE__, (UINTN)__LINE__ );
  
						

  return EFI_SUCCESS;
}
Example #7
0
EFI_STATUS BBTestTapeFunctionRead(  
  IN EFI_BB_TEST_PROTOCOL             *_This,
  IN VOID                             *ClientInterface,
  IN EFI_TEST_LEVEL                   TestLevel,
  IN EFI_HANDLE                       SupportHandle
  )
{
  EFI_STATUS status;
  char *buffer=NULL;
  UINTN bufferSize = MAX_TAPE_BUFFER_SIZE; 
  UINTN index;
  
  getStandardLibInterface(SupportHandle);
  //
  // Enter a function. It is put at the entry point of a function
  LogEnterFunction( LoggingLib, 
  							L"BBTestTapeFunctionRead",
  							L"%a:%d : EnterFunction",
  							__FILE__, (UINTN)__LINE__ );  
  							
  buffer = (char *)EfiLibAllocatePool(bufferSize);
  
  //  1.0 check input parameters
  gTapeIoProtocol = (EFI_TAPE_IO_PROTOCOL *)ClientInterface;
  if((buffer==NULL)||(_This==NULL) || (LoggingLib==NULL) || (gTapeIoProtocol==NULL))
  	status = EFI_INVALID_PARAMETER;
  else
    status = EFI_SUCCESS;
  logMsg(gTapeBBTestMainAssertionGuid001,
  			"EFI_TAPE_IO_PROTOCOL read test", 
  			"check input parameters", 
  			status, 
  			EFI_SUCCESS
  		);
  		
  if(status != EFI_SUCCESS)
  	goto BBTestTapeFunctionReadEnd;		

  //  1.0.1 prepare Reading data
  prepareTapeTest(TAPE_IO_TEST_FILEMARK_CNT, TAPE_IO_TEST_BLOCKMARK_CNT);
  if(status != EFI_SUCCESS)
  	goto BBTestTapeFunctionReadEnd;	
  	  	      
  //  1.1 TapeRead with valid parameters
  status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, buffer);
  logMsg(gTapeBBTestMainAssertionGuid002,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"with valid parameters", 
  			status, 
  			EFI_SUCCESS
  		);

  switch(status)
  {
  	case EFI_SUCCESS:  	
  	case EFI_END_OF_FILE:	
		  //  1.1.1 verify reading data ...
		  for(index=0; index<bufferSize; index++)
		  	if(buffer[index]!=(char)(index&0xff))
		  		break;
		  
		  logMsg(gTapeBBTestMainAssertionGuid02F,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"verify reading data", 
  			((index==bufferSize)?EFI_SUCCESS:EFI_LOAD_ERROR), 
  			EFI_SUCCESS
  			);				    			 
		   
  		 break;
  	  	
  	case EFI_NO_MEDIA:
  	case EFI_MEDIA_CHANGED:
  	case EFI_DEVICE_ERROR:
  	case EFI_INVALID_PARAMETER:
  	case EFI_NOT_READY:
  	case EFI_TIMEOUT:
  	default:
  		 goto BBTestTapeFunctionReadEnd;
  		 break;
  }
  

  //  1.2.1 TapeRead with invalid parameters
  status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, NULL);
  logMsg(gTapeBBTestMainAssertionGuid003,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"with invalid parameters(Buffer=NULL)", 
  			status, 
  			EFI_INVALID_PARAMETER
  		);

  //  1.2.2 TapeRead with invalid parameters
  status = gTapeIoProtocol->TapeRead(NULL, &bufferSize, buffer);
  logMsg(gTapeBBTestMainAssertionGuid004,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"with invalid parameters(EFI_TAPE_IO_PROTOCOL=NULL)", 
  			status, 
  			EFI_INVALID_PARAMETER
  		);
  		
  //  1.3.1 TapeRead with valid parameters
  bufferSize = 0;
  status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, NULL);
  logMsg(gTapeBBTestMainAssertionGuid005,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"with valid parameters(bufferSize=0,buffer=NULL)", 
  			status, 
  			EFI_SUCCESS
  		);

  //  1.3.2 TapeRead with valid parameters
  bufferSize = 0;
  status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, buffer);
  logMsg(gTapeBBTestMainAssertionGuid007,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"with valid parameters(bufferSize=0,buffer!=NULL)", 
  			status, 
  			EFI_SUCCESS
  		);
  		  		
#if 0  		  		  		
  //  1.4 do TapeRead with valid parameters until not EFI_SUCCESS  
  while(status==EFI_SUCCESS)
  {  	
  	bufferSize = MAX_TAPE_BUFFER_SIZE;
  	status = gTapeIoProtocol->TapeRead(gTapeIoProtocol, &bufferSize, buffer);
  }
  logMsg(gTapeBBTestMainAssertionGuid006,
  			"EFI_TAPE_IO_PROTOCOL.TapeRead", 
  			"do with valid parameters until not EFI_SUCCESS", 
  			status, 
  			EFI_SUCCESS
  		);
#endif
  		  
BBTestTapeFunctionReadEnd:		
  if(buffer!=NULL)
  	gBS->FreePool(buffer);					
  //
  // Exit a function. It is put at the exit point of a function
  LogExitFunction( LoggingLib, 
  							L"BBTestTapeFunctionRead",
  							L"%a:%d : ExitFunction",
  							__FILE__, (UINTN)__LINE__ );
							

  return EFI_SUCCESS;
}
Example #8
0
VOID
ProcessHelpString (
  IN  CHAR16  *StringPtr,
  OUT CHAR16  **FormattedString,
  IN  UINTN   RowCount
  )
/*++

Routine Description:
  Process the help string: Split StringPtr to several lines of strings stored in
  FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.

Arguments:
  StringPtr        - The entire help string.
  MenuOption       - The MenuOption for this Question.
  RowCount         - TRUE: if Question is selected.
  OptionString     - Pointer of the Option String to be displayed.

Returns:
  None.

--*/
{
  CONST UINTN BlockWidth = (UINTN) gHelpBlockWidth - 1;
  UINTN AllocateSize;
  //
  // [PrevCurrIndex, CurrIndex) forms a range of a screen-line
  //
  UINTN CurrIndex;
  UINTN PrevCurrIndex;
  UINTN LineCount;
  UINTN VirtualLineCount;
  //
  // GlyphOffset stores glyph width of current screen-line
  //
  UINTN GlyphOffset;
  //
  // GlyphWidth equals to 2 if we meet width directive
  //
  UINTN GlyphWidth;
  //
  // during scanning, we remember the position of last space character
  // in case that if next word cannot put in current line, we could restore back to the position
  // of last space character
  // while we should also remmeber the glyph width of the last space character for restoring
  //
  UINTN LastSpaceIndex;
  UINTN LastSpaceGlyphWidth;
  //
  // every time we begin to form a new screen-line, we should remember glyph width of single character
  // of last line
  //
  UINTN LineStartGlyphWidth;
  UINTN *IndexArray;
  UINTN *OldIndexArray;

  //
  // every three elements of IndexArray form a screen-line of string:[ IndexArray[i*3], IndexArray[i*3+1] )
  // IndexArray[i*3+2] stores the initial glyph width of single character. to save this is because we want
  // to bring the width directive of the last line to current screen-line.
  // e.g.: "\wideabcde ... fghi", if "fghi" also has width directive but is splitted to the next screen-line
  // different from that of "\wideabcde", we should remember the width directive.
  //
  AllocateSize  = 0x20;
  IndexArray    = EfiLibAllocatePool (AllocateSize * sizeof (UINTN) * 3);

  if (*FormattedString != NULL) {
    gBS->FreePool (*FormattedString);
    *FormattedString = NULL;
  }

  for (PrevCurrIndex = 0, CurrIndex  = 0, LineCount   = 0, LastSpaceIndex = 0,
       IndexArray[0] = 0, GlyphWidth = 1, GlyphOffset = 0, LastSpaceGlyphWidth = 1, LineStartGlyphWidth = 1;
       (StringPtr[CurrIndex] != CHAR_NULL);
       CurrIndex ++) {

    if (LineCount == AllocateSize) {
      AllocateSize += 0x10;
      OldIndexArray  = IndexArray;
      IndexArray = EfiLibAllocatePool (AllocateSize * sizeof (UINTN) * 3);
      EfiCopyMem (IndexArray, OldIndexArray, LineCount * sizeof (UINTN) * 3);
      gBS->FreePool (OldIndexArray);
    }
    switch (StringPtr[CurrIndex]) {

      case NARROW_CHAR:
      case WIDE_CHAR:
        GlyphWidth = ((StringPtr[CurrIndex] == WIDE_CHAR) ? 2 : 1);
        if (CurrIndex == 0) {
          LineStartGlyphWidth = GlyphWidth;
        }
        break;

      //
      // char is '\n'
      // "\r\n" isn't handled here, handled by case CHAR_CARRIAGE_RETURN
      //
      case CHAR_LINEFEED:
        //
        // Store a range of string as a line
        //
        IndexArray[LineCount*3]   = PrevCurrIndex;
        IndexArray[LineCount*3+1] = CurrIndex;
        IndexArray[LineCount*3+2] = LineStartGlyphWidth;
        LineCount ++;
        //
        // Reset offset and save begin position of line
        //
        GlyphOffset = 0;
        LineStartGlyphWidth = GlyphWidth;
        PrevCurrIndex = CurrIndex + 1;
        break;

      //
      // char is '\r'
      // "\r\n" and "\r" both are handled here
      //
      case CHAR_CARRIAGE_RETURN:
        if (StringPtr[CurrIndex + 1] == CHAR_LINEFEED) {
          //
          // next char is '\n'
          //
          IndexArray[LineCount*3]   = PrevCurrIndex;
          IndexArray[LineCount*3+1] = CurrIndex;
          IndexArray[LineCount*3+2] = LineStartGlyphWidth;
          LineCount ++;
          CurrIndex ++;
        }
        GlyphOffset = 0;
        LineStartGlyphWidth = GlyphWidth;
        PrevCurrIndex = CurrIndex + 1;
        break;

      //
      // char is space or other char
      //
      default:
        GlyphOffset     += GlyphWidth;
        if (GlyphOffset >= BlockWidth) {
          if (LastSpaceIndex > PrevCurrIndex) {
            //
            // LastSpaceIndex points to space inside current screen-line,
            // restore to LastSpaceIndex
            // (Otherwise the word is too long to fit one screen-line, just cut it)
            //
            CurrIndex  = LastSpaceIndex;
            GlyphWidth = LastSpaceGlyphWidth;
          } else if (GlyphOffset > BlockWidth) {
            //
            // the word is too long to fit one screen-line and we don't get the chance
            // of GlyphOffset == BlockWidth because GlyphWidth = 2
            //
            CurrIndex --;
          }

          IndexArray[LineCount*3]   = PrevCurrIndex;
          IndexArray[LineCount*3+1] = CurrIndex + 1;
          IndexArray[LineCount*3+2] = LineStartGlyphWidth;
          LineStartGlyphWidth = GlyphWidth;
          LineCount ++;
          //
          // Reset offset and save begin position of line
          //
          GlyphOffset                 = 0;
          PrevCurrIndex               = CurrIndex + 1;
        }

        //
        // LastSpaceIndex: remember position of last space
        //
        if (StringPtr[CurrIndex] == CHAR_SPACE) {
          LastSpaceIndex      = CurrIndex;
          LastSpaceGlyphWidth = GlyphWidth;
        }
        break;
    }
  }

  if (GlyphOffset > 0) {
    IndexArray[LineCount*3]   = PrevCurrIndex;
    IndexArray[LineCount*3+1] = CurrIndex;
    IndexArray[LineCount*3+2] = GlyphWidth;
    LineCount ++;
  }

  if (LineCount == 0) {
    //
    // in case we meet null string
    //
    IndexArray[0] = 0;
    IndexArray[1] = 1;
    //
    // we assume null string's glyph width is 1
    //
    IndexArray[1] = 1;
    LineCount ++;
  }

  VirtualLineCount = RowCount * (LineCount / RowCount + (LineCount % RowCount > 0));
  *FormattedString = EfiLibAllocateZeroPool (VirtualLineCount * (BlockWidth + 1) * sizeof (CHAR16) * 2);

  for (CurrIndex = 0; CurrIndex < LineCount; CurrIndex ++) {
    *(*FormattedString + CurrIndex * 2 * (BlockWidth + 1)) = (IndexArray[CurrIndex*3+2] == 2) ? WIDE_CHAR : NARROW_CHAR;
    StrnCpy (
      *FormattedString + CurrIndex * 2 * (BlockWidth + 1) + 1,
      StringPtr + IndexArray[CurrIndex*3],
      IndexArray[CurrIndex*3+1]-IndexArray[CurrIndex*3]
      );
  }

  gBS->FreePool (IndexArray);
}
Example #9
0
EFI_STATUS
EFIAPI
FdcControllerDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
/*++

Routine Description:

Arguments:

Returns:

--*/
// GC_TODO:    This - add argument and description to function comment
// GC_TODO:    Controller - add argument and description to function comment
// GC_TODO:    RemainingDevicePath - add argument and description to function comment
{
  EFI_STATUS                                Status;
  FDC_BLK_IO_DEV                            *FdcDev;
  EFI_INTERFACE_DEFINITION_FOR_ISA_IO       *IsaIo;
  UINTN                                     Index;
  EFI_LIST_ENTRY                            *List;
  BOOLEAN                                   Found;
  EFI_DEVICE_PATH_PROTOCOL                  *ParentDevicePath;

  FdcDev  = NULL;
  IsaIo   = NULL;

  //
  // Open the device path protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Report enable progress code
  //
  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_ENABLE,
    0,
    &gEfiCallerIdGuid,
    ParentDevicePath
    );

  //
  // Open the ISA I/O Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  EFI_ISA_IO_PROTOCOL_VERSION,
                  (VOID **) &IsaIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Allocate the Floppy Disk Controller's Device structure
  //
  FdcDev = EfiLibAllocateZeroPool (sizeof (FDC_BLK_IO_DEV));
  if (FdcDev == NULL) {
    goto Done;
  }
  //
  // Initialize the Floppy Disk Controller's Device structure
  //
  FdcDev->Signature       = FDC_BLK_IO_DEV_SIGNATURE;
  FdcDev->Handle          = Controller;
  FdcDev->IsaIo           = IsaIo;
  FdcDev->Disk            = IsaIo->ResourceList->Device.UID;
  FdcDev->Cache           = NULL;
  FdcDev->Event           = NULL;
  FdcDev->ControllerState = NULL;
  FdcDev->DevicePath      = ParentDevicePath;

  ADD_FLOPPY_NAME (FdcDev);
  
  //
  // Look up the base address of the Floppy Disk Controller
  //
  for (Index = 0; FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {
    if (FdcDev->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {
      FdcDev->BaseAddress = (UINT16) FdcDev->IsaIo->ResourceList->ResourceItem[Index].StartRange;
    }
  }
  //
  // Maintain the list of controller list
  //
  Found = FALSE;
  List  = gControllerHead.ForwardLink;
  while (List != &gControllerHead) {
    FdcDev->ControllerState = FLOPPY_CONTROLLER_FROM_LIST_ENTRY (List);
    if (FdcDev->BaseAddress == FdcDev->ControllerState->BaseAddress) {
      Found = TRUE;
      break;
    }

    List = List->ForwardLink;
  }

  if (!Found) {
    //
    // The Controller is new
    //
    FdcDev->ControllerState = EfiLibAllocatePool (sizeof (FLOPPY_CONTROLLER_CONTEXT));
    if (FdcDev->ControllerState == NULL) {
      goto Done;
    }

    FdcDev->ControllerState->Signature          = FLOPPY_CONTROLLER_CONTEXT_SIGNATURE;
    FdcDev->ControllerState->FddResetPerformed  = FALSE;
    FdcDev->ControllerState->NeedRecalibrate    = FALSE;
    FdcDev->ControllerState->BaseAddress        = FdcDev->BaseAddress;
    FdcDev->ControllerState->NumberOfDrive      = 0;

    InsertTailList (&gControllerHead, &FdcDev->ControllerState->Link);
  }
  //
  // Create a timer event for each Floppd Disk Controller.
  // This timer event is used to control the motor on and off
  //
  Status = gBS->CreateEvent (
                  EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
                  EFI_TPL_NOTIFY,
                  FddTimerProc,
                  FdcDev,
                  &FdcDev->Event
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Reset the Floppy Disk Controller
  //
  if (!FdcDev->ControllerState->FddResetPerformed) {
    FdcDev->ControllerState->FddResetPerformed  = TRUE;
    FdcDev->ControllerState->FddResetStatus     = FddReset (FdcDev);
  }

  if (EFI_ERROR (FdcDev->ControllerState->FddResetStatus)) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }

  ReportStatusCodeWithDevicePath (
    EFI_PROGRESS_CODE,
    EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_PRESENCE_DETECT,
    0,
    &gEfiCallerIdGuid,
    ParentDevicePath
    );

  //
  // Discover the Floppy Drive
  //
  Status = DiscoverFddDevice (FdcDev);
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }
  //
  // Install protocol interfaces for the serial device.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiBlockIoProtocolGuid,
                  &FdcDev->BlkIo,
                  NULL
                  );

  FdcDev->ControllerState->NumberOfDrive++;

Done:
  if (EFI_ERROR (Status)) {

    ReportStatusCodeWithDevicePath (
      EFI_ERROR_CODE | EFI_ERROR_MINOR,
      EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_CONTROLLER_ERROR,
      0,
      &gEfiCallerIdGuid,
      ParentDevicePath
      );

    //
    // Close the device path protocol
    //
    gBS->CloseProtocol (
           Controller,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );

    //
    // Close the ISA I/O Protocol
    //
    if (IsaIo != NULL) {
      gBS->CloseProtocol (
             Controller,
             EFI_ISA_IO_PROTOCOL_VERSION,
             This->DriverBindingHandle,
             Controller
             );
    }
    //
    // If a Floppy Disk Controller Device structure was allocated, then free it
    //
    if (FdcDev != NULL) {
      if (FdcDev->Event != NULL) {
        //
        // Close the event for turning the motor off
        //
        gBS->CloseEvent (FdcDev->Event);
      }

      EfiLibFreeUnicodeStringTable (FdcDev->ControllerNameTable);
      gBS->FreePool (FdcDev);
    }
  }

  return Status;
}
Example #10
0
EFI_STATUS
PartitionInstallElToritoChildHandles (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Handle,
  IN  EFI_DISK_IO_PROTOCOL         *DiskIo,
  IN  EFI_BLOCK_IO_PROTOCOL        *BlockIo,
  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
/*++

Routine Description:
  Install child handles if the Handle supports El Torito format.

Arguments:
  This       - Calling context.       
  Handle     - Parent Handle 
  DiskIo     - Parent DiskIo interface
  BlockIo    - Parent BlockIo interface
  DevicePath - Parent Device Path

Returns:
  EFI_SUCCESS       - some child handle(s) was added
  EFI_MEDIA_CHANGED - Media changed Detected
  !EFI_SUCCESS      - no child handle was added

--*/
{
  EFI_STATUS              Status;
  UINT32                  VolDescriptorLba;
  UINT32                  Lba;
  EFI_BLOCK_IO_MEDIA      *Media;
  CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
  ELTORITO_CATALOG        *Catalog;
  UINTN                   Check;
  UINTN                   Index;
  UINTN                   BootEntry;
  UINTN                   MaxIndex;
  UINT16                  *CheckBuffer;
  CDROM_DEVICE_PATH       CdDev;
  UINT32                  SubBlockSize;
  UINT32                  SectorCount;
  EFI_STATUS              Found;
  UINTN                   Dummy;
  UINT32                  VolSpaceSize;

  Found         = EFI_NOT_FOUND;
  Media         = BlockIo->Media;
  VolSpaceSize  = 0;

  //
  // CD_ROM has the fixed block size as 2048 bytes
  //
  if (Media->BlockSize != 2048) {
    return EFI_NOT_FOUND;
  }

  VolDescriptor = EfiLibAllocatePool ((UINTN) Media->BlockSize);

  if (VolDescriptor == NULL) {
    return EFI_NOT_FOUND;
  }

  Catalog = (ELTORITO_CATALOG *) VolDescriptor;

  //
  // the ISO-9660 volume descriptor starts at 32k on the media
  // and CD_ROM has the fixed block size as 2048 bytes, so...
  //
  //
  // ((16*2048) / Media->BlockSize) - 1;
  //
  VolDescriptorLba = 15;
  //
  // Loop: handle one volume descriptor per time
  //
  while (TRUE) {

    VolDescriptorLba += 1;
    if (VolDescriptorLba > Media->LastBlock) {
      //
      // We are pointing past the end of the device so exit
      //
      break;
    }

    Status = DiskIo->ReadDisk (
                        DiskIo,
                        Media->MediaId,
                        MultU64x32 (VolDescriptorLba, Media->BlockSize),
                        Media->BlockSize,
                        VolDescriptor
                        );
    if (EFI_ERROR (Status)) {
      Found = Status;
      break;
    }
    //
    // Check for valid volume descriptor signature
    //
    if (VolDescriptor->Type == CDVOL_TYPE_END ||
        EfiCompareMem (VolDescriptor->Id, CDVOL_ID, sizeof (VolDescriptor->Id)) != 0
        ) {
      //
      // end of Volume descriptor list
      //
      break;
    }
    //
    // Read the Volume Space Size from Primary Volume Descriptor 81-88 byte,
    // the 32-bit numerical values is stored in Both-byte orders
    //
    if (VolDescriptor->Type == CDVOL_TYPE_CODED) {
      VolSpaceSize = VolDescriptor->VolSpaceSize[0];
    }
    //
    // Is it an El Torito volume descriptor?
    //
    if (EfiCompareMem (VolDescriptor->SystemId, CDVOL_ELTORITO_ID, sizeof (CDVOL_ELTORITO_ID) - 1) != 0) {
      continue;
    }
    //
    // Read in the boot El Torito boot catalog
    //
    Lba = UNPACK_INT32 (VolDescriptor->EltCatalog);
    if (Lba > Media->LastBlock) {
      continue;
    }

    Status = DiskIo->ReadDisk (
                        DiskIo,
                        Media->MediaId,
                        MultU64x32 (Lba, Media->BlockSize),
                        Media->BlockSize,
                        Catalog
                        );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "EltCheckDevice: error reading catalog %r\n", Status));
      continue;
    }
    //
    // We don't care too much about the Catalog header's contents, but we do want
    // to make sure it looks like a Catalog header
    //
    if (Catalog->Catalog.Indicator != ELTORITO_ID_CATALOG || Catalog->Catalog.Id55AA != 0xAA55) {
      DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header IDs not correct\n"));
      continue;
    }

    Check       = 0;
    CheckBuffer = (UINT16 *) Catalog;
    for (Index = 0; Index < sizeof (ELTORITO_CATALOG) / sizeof (UINT16); Index += 1) {
      Check += CheckBuffer[Index];
    }

    if (Check & 0xFFFF) {
      DEBUG ((EFI_D_ERROR, "EltCheckBootCatalog: El Torito boot catalog header checksum failed\n"));
      continue;
    }

    MaxIndex = Media->BlockSize / sizeof (ELTORITO_CATALOG);
    for (Index = 1, BootEntry = 1; Index < MaxIndex; Index += 1) {
      //
      // Next entry
      //
      Catalog += 1;

      //
      // Check this entry
      //
      if (Catalog->Boot.Indicator != ELTORITO_ID_SECTION_BOOTABLE || Catalog->Boot.Lba == 0) {
        continue;
      }

      SubBlockSize  = 512;
      SectorCount   = Catalog->Boot.SectorCount;

      switch (Catalog->Boot.MediaType) {

      case ELTORITO_NO_EMULATION:
        SubBlockSize = Media->BlockSize;
        break;

      case ELTORITO_HARD_DISK:
        break;

      case ELTORITO_12_DISKETTE:
        SectorCount = 0x50 * 0x02 * 0x0F;
        break;

      case ELTORITO_14_DISKETTE:
        SectorCount = 0x50 * 0x02 * 0x12;
        break;

      case ELTORITO_28_DISKETTE:
        SectorCount = 0x50 * 0x02 * 0x24;
        break;

      default:
        DEBUG ((EFI_D_INIT, "EltCheckDevice: unsupported El Torito boot media type %x\n", Catalog->Boot.MediaType));
        SectorCount   = 0;
        SubBlockSize  = Media->BlockSize;
        break;
      }
      //
      // Create child device handle
      //
      CdDev.Header.Type     = MEDIA_DEVICE_PATH;
      CdDev.Header.SubType  = MEDIA_CDROM_DP;
      SetDevicePathNodeLength (&CdDev.Header, sizeof (CdDev));

      if (Index == 1) {
        //
        // This is the initial/default entry
        //
        BootEntry = 0;
      }

      CdDev.BootEntry = (UINT32) BootEntry;
      BootEntry++;
      CdDev.PartitionStart = Catalog->Boot.Lba;
      if (SectorCount < 2) {
        //
        //When the SectorCount < 2, set the Partition as the whole CD.
        //
        CdDev.PartitionSize = (VolSpaceSize > Media->LastBlock + 1) ? 
          (UINT32)(Media->LastBlock - Catalog->Boot.Lba + 1) : (UINT32)(VolSpaceSize - Catalog->Boot.Lba);
      } else {
        CdDev.PartitionSize = DivU64x32 (
                                MultU64x32 (SectorCount,
                                SubBlockSize) + Media->BlockSize - 1,
                                Media->BlockSize,
                                &Dummy
                                );
      }

      Status = PartitionInstallChildHandle (
                This,
                Handle,
                DiskIo,
                BlockIo,
                DevicePath,
                (EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
                Catalog->Boot.Lba,
                Catalog->Boot.Lba + CdDev.PartitionSize - 1,
                SubBlockSize,
                FALSE
                );
      if (!EFI_ERROR (Status)) {
        Found = EFI_SUCCESS;
      }
    }
  }

  gBS->FreePool (VolDescriptor);

  return Found;
}
Example #11
0
EFI_STATUS
IfrCatenate (
  IN FORM_BROWSER_FORMSET  *FormSet,
  OUT  EFI_HII_VALUE       *Result
  )
/*++

Routine Description:
  Evaluate opcode EFI_IFR_CATENATE.

Arguments:
  FormSet     - Formset which contains this opcode.
  Result      - Evaluation result for this opcode.

Returns:
  EFI_SUCCESS - Opcode evaluation success.
  Other       - Opcode evaluation failed.

--*/
{
  EFI_STATUS     Status;
  EFI_HII_VALUE  Value;
  CHAR16         *String[2];
  UINTN          Index;
  CHAR16         *StringPtr;

  //
  // String[0] - The second string
  // String[1] - The first string
  //
  String[0] = NULL;
  String[1] = NULL;
  StringPtr = NULL;
  Status = EFI_SUCCESS;

  for (Index = 0; Index < 2; Index++) {
    Status = PopExpression (&Value);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    if (Value.Type != EFI_IFR_TYPE_STRING) {
      Status = EFI_UNSUPPORTED;
      goto Done;
    }

    String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);
    if (String== NULL) {
      Status = EFI_NOT_FOUND;
      goto Done;
    }
  }

  StringPtr= EfiLibAllocatePool (EfiStrSize (String[1]) + EfiStrSize (String[0]));
  ASSERT (StringPtr != NULL);
  EfiStrCpy (StringPtr, String[1]);
  EfiStrCat (StringPtr, String[0]);

  Result->Type = EFI_IFR_TYPE_STRING;
  Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);

Done:
  EfiLibSafeFreePool (String[0]);
  EfiLibSafeFreePool (String[1]);
  EfiLibSafeFreePool (StringPtr);

  return Status;
}
Example #12
0
STATIC
EFI_STATUS
GrowStack (
  IN OUT EFI_HII_VALUE  **Stack,
  IN OUT EFI_HII_VALUE  **StackPtr,
  IN OUT EFI_HII_VALUE  **StackEnd
  )
/*++

Routine Description:
  Grow size of the stack

Arguments:
  Stack     - On input: old stack; On output: new stack
  StackPtr  - On input: old stack pointer; On output: new stack pointer
  StackEnd  - On input: old stack end; On output: new stack end

Returns:
  EFI_SUCCESS          - Grow stack success.
  EFI_OUT_OF_RESOURCES - No enough memory for stack space.

--*/
{
  UINTN           Size;
  EFI_HII_VALUE  *NewStack;

  Size = EXPRESSION_STACK_SIZE_INCREMENT;
  if (*StackPtr != NULL) {
    Size = Size + (*StackEnd - *Stack);
  }

  NewStack = EfiLibAllocatePool (Size * sizeof (EFI_HII_VALUE));
  if (NewStack == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (*StackPtr != NULL) {
    //
    // Copy from Old Stack to the New Stack
    //
    EfiCopyMem (
      NewStack,
      *Stack,
      (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)
      );

    //
    // Free The Old Stack
    //
    gBS->FreePool (*Stack);
  }

  //
  // Make the Stack pointer point to the old data in the new stack
  //
  *StackPtr = NewStack + (*StackPtr - *Stack);
  *Stack    = NewStack;
  *StackEnd = NewStack + Size;

  return EFI_SUCCESS;
}
Example #13
0
EFI_STATUS
EfiLibAddUnicodeString (
  IN      CHAR8                     *Language,
  IN      CHAR8                     *SupportedLanguages,
  IN OUT  EFI_UNICODE_STRING_TABLE  **UnicodeStringTable,
  IN      CHAR16                    *UnicodeString
  )
/*++

Routine Description:

  Add an translation to the dictionary if this language if supported.
  
Arguments:

  Language              - The name of language to translate to
  SupportedLanguages    - Supported languages set
  UnicodeStringTable    - Translation dictionary
  UnicodeString         - The corresponding string for the language to be translated to

Returns: 

  EFI_INVALID_PARAMETER - Invalid parameter
  EFI_UNSUPPORTED       - System not supported this language
  EFI_ALREADY_STARTED   - Already has a translation item of this language
  EFI_OUT_OF_RESOURCES  - No enough buffer to be allocated
  EFI_SUCCESS           - String successfully translated

--*/
{
  UINTN                     NumberOfEntries;
  EFI_UNICODE_STRING_TABLE  *OldUnicodeStringTable;
  EFI_UNICODE_STRING_TABLE  *NewUnicodeStringTable;
  UINTN                     UnicodeStringLength;

  //
  // Make sure the parameter are valid
  //
  if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If there are no supported languages, then a Unicode String can not be added
  //
  if (SupportedLanguages == NULL) {
    return EFI_UNSUPPORTED;
  }

  //
  // If the Unicode String is empty, then a Unicode String can not be added
  //
  if (UnicodeString[0] == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Make sure Language is a member of SupportedLanguages
  //
  while (*SupportedLanguages != 0) {
    if (EfiLibCompareLanguage (Language, SupportedLanguages)) {

      //
      // Determine the size of the Unicode String Table by looking for a NULL Language entry
      //
      NumberOfEntries = 0;
      if (*UnicodeStringTable != NULL) {
        OldUnicodeStringTable = *UnicodeStringTable;
        while (OldUnicodeStringTable->Language != NULL) {
          if (EfiLibCompareLanguage (Language, OldUnicodeStringTable->Language)) {
            return EFI_ALREADY_STARTED;
          }

          OldUnicodeStringTable++;
          NumberOfEntries++;
        }
      }

      //
      // Allocate space for a new Unicode String Table.  It must hold the current number of
      // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table
      // marker
      //
      NewUnicodeStringTable = EfiLibAllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));
      if (NewUnicodeStringTable == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // If the current Unicode String Table contains any entries, then copy them to the
      // newly allocated Unicode String Table.
      //
      if (*UnicodeStringTable != NULL) {
        EfiCopyMem (
          NewUnicodeStringTable,
          *UnicodeStringTable,
          NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)
          );
      }

      //
      // Allocate space for a copy of the Language specifier
      //
      NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrLen(Language) + 1, Language);
      if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {
        gBS->FreePool (NewUnicodeStringTable);
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Compute the length of the Unicode String
      //
      for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)
        ;

      //
      // Allocate space for a copy of the Unicode String
      //
      NewUnicodeStringTable[NumberOfEntries].UnicodeString = EfiLibAllocateCopyPool (
                                                              (UnicodeStringLength + 1) * sizeof (CHAR16),
                                                              UnicodeString
                                                              );
      if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {
        gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);
        gBS->FreePool (NewUnicodeStringTable);
        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Mark the end of the Unicode String Table
      //
      NewUnicodeStringTable[NumberOfEntries + 1].Language       = NULL;
      NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString  = NULL;

      //
      // Free the old Unicode String Table
      //
      if (*UnicodeStringTable != NULL) {
        gBS->FreePool (*UnicodeStringTable);
      }

      //
      // Point UnicodeStringTable at the newly allocated Unicode String Table
      //
      *UnicodeStringTable = NewUnicodeStringTable;

      return EFI_SUCCESS;
    }

    SupportedLanguages = NextSupportedLanguage(SupportedLanguages);
  }

  return EFI_UNSUPPORTED;
}
Example #14
0
EFI_STATUS
FtwReclaimWorkSpace (
  IN EFI_FTW_LITE_DEVICE  *FtwLiteDevice,
  IN BOOLEAN              PreserveRecord
  )
/*++

Routine Description:
    Reclaim the work space on the working block.

Arguments:
    FtwLiteDevice     - Point to private data of FTW driver
    PreserveRecord    - Whether to preserve the working record is needed

Returns:
    EFI_SUCCESS           - The function completed successfully
    EFI_OUT_OF_RESOURCES  - Allocate memory error
    EFI_ABORTED           - The function could not complete successfully

--*/
{
  EFI_STATUS                              Status;
  UINT8                                   *TempBuffer;
  UINTN                                   TempBufferSize;
  UINT8                                   *Ptr;
  UINTN                                   Length;
  UINTN                                   Index;
  UINTN                                   SpareBufferSize;
  UINT8                                   *SpareBuffer;
  EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *WorkingBlockHeader;
  EFI_FTW_LITE_RECORD                     *Record;

  DEBUG ((EFI_D_FTW_LITE, "FtwLite: start to reclaim work space\n"));

  //
  // Read all original data from working block to a memory buffer
  //
  TempBufferSize = FtwLiteDevice->SpareAreaLength;
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  TempBufferSize,
                  &TempBuffer
                  );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  EfiZeroMem (TempBuffer, TempBufferSize);

  Ptr = TempBuffer;
  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
    Length = FtwLiteDevice->SizeOfSpareBlock;
    Status = FtwLiteDevice->FtwFvBlock->Read (
                                          FtwLiteDevice->FtwFvBlock,
                                          FtwLiteDevice->FtwWorkBlockLba + Index,
                                          0,
                                          &Length,
                                          Ptr
                                          );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (TempBuffer);
      return EFI_ABORTED;
    }

    Ptr += Length;
  }
  //
  // Clean up the workspace, remove all the completed records.
  //
  Ptr = TempBuffer +
    ((UINTN) (FtwLiteDevice->FtwWorkSpaceLba - FtwLiteDevice->FtwWorkBlockLba)) *
    FtwLiteDevice->SizeOfSpareBlock +
    FtwLiteDevice->FtwWorkSpaceBase;

  //
  // Clear the content of buffer that will save the new work space data
  //
  EfiSetMem (Ptr, FtwLiteDevice->FtwWorkSpaceSize, FTW_ERASED_BYTE);

  //
  // Copy EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER to buffer
  //
  EfiCopyMem (
    Ptr,
    FtwLiteDevice->FtwWorkSpaceHeader,
    sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER)
    );

  if (PreserveRecord) {
    //
    // Get the last record
    //
    Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);
    Record = FtwLiteDevice->FtwLastRecord;
    if (!EFI_ERROR (Status)                       &&
        Record                 != NULL            &&
        Record->WriteAllocated == FTW_VALID_STATE &&
        Record->WriteCompleted != FTW_VALID_STATE) {
      EfiCopyMem (
        (UINT8 *) Ptr + sizeof (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER),
        Record,
        WRITE_TOTAL_SIZE
        );
    }
  }
  
  EfiCopyMem (
    FtwLiteDevice->FtwWorkSpace,
    Ptr,
    FtwLiteDevice->FtwWorkSpaceSize
    );

  Status = FtwGetLastRecord (FtwLiteDevice, &FtwLiteDevice->FtwLastRecord);

  //
  // Set the WorkingBlockValid and WorkingBlockInvalid as INVALID
  //
  WorkingBlockHeader                      = (EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER *) Ptr;
  WorkingBlockHeader->WorkingBlockValid   = FTW_INVALID_STATE;
  WorkingBlockHeader->WorkingBlockInvalid = FTW_INVALID_STATE;

  //
  // Try to keep the content of spare block
  // Save spare block into a spare backup memory buffer (Sparebuffer)
  //
  SpareBufferSize = FtwLiteDevice->SpareAreaLength;
  SpareBuffer     = EfiLibAllocatePool (SpareBufferSize);
  if (SpareBuffer == NULL) {
    gBS->FreePool (TempBuffer);
    return EFI_OUT_OF_RESOURCES;
  }

  Ptr = SpareBuffer;
  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
    Length = FtwLiteDevice->SizeOfSpareBlock;
    Status = FtwLiteDevice->FtwBackupFvb->Read (
                                            FtwLiteDevice->FtwBackupFvb,
                                            FtwLiteDevice->FtwSpareLba + Index,
                                            0,
                                            &Length,
                                            Ptr
                                            );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (TempBuffer);
      gBS->FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr += Length;
  }
  //
  // Write the memory buffer to spare block
  //
  Status  = FtwEraseSpareBlock (FtwLiteDevice);
  Ptr     = TempBuffer;
  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
    Length = FtwLiteDevice->SizeOfSpareBlock;
    Status = FtwLiteDevice->FtwBackupFvb->Write (
                                            FtwLiteDevice->FtwBackupFvb,
                                            FtwLiteDevice->FtwSpareLba + Index,
                                            0,
                                            &Length,
                                            Ptr
                                            );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (TempBuffer);
      gBS->FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr += Length;
  }
  //
  // Free TempBuffer
  //
  gBS->FreePool (TempBuffer);

  //
  // Write the spare block to working block
  //
  Status = FlushSpareBlockToWorkingBlock (FtwLiteDevice);
  if (EFI_ERROR (Status)) {
    gBS->FreePool (SpareBuffer);
    return Status;
  }
  //
  // Restore spare backup buffer into spare block , if no failure happened during FtwWrite.
  //
  Status  = FtwEraseSpareBlock (FtwLiteDevice);
  Ptr     = SpareBuffer;
  for (Index = 0; Index < FtwLiteDevice->NumberOfSpareBlock; Index += 1) {
    Length = FtwLiteDevice->SizeOfSpareBlock;
    Status = FtwLiteDevice->FtwBackupFvb->Write (
                                            FtwLiteDevice->FtwBackupFvb,
                                            FtwLiteDevice->FtwSpareLba + Index,
                                            0,
                                            &Length,
                                            Ptr
                                            );
    if (EFI_ERROR (Status)) {
      gBS->FreePool (SpareBuffer);
      return EFI_ABORTED;
    }

    Ptr += Length;
  }

  gBS->FreePool (SpareBuffer);

  DEBUG ((EFI_D_FTW_LITE, "FtwLite: reclaim work space success\n"));

  return EFI_SUCCESS;
}