Beispiel #1
0
EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
  EFI_INPUT_KEY efi_input_key;

  int a = 10, b = 20;

  InitializeLib(ImageHandle, SystemTable);
  //Print(L"Hello, world!\n");
  terra_main(L"Hello, Terra from C!\n");
  Print(L"%d + %d = %d\n", a, b, terra_add(a,b));

  Print(L"%s\n", SystemTable->FirmwareVendor);

  EFI_STATUS status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;

  status = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);

  if(EFI_ERROR(status))
    return status;

  status = uefi_call_wrapper(SystemTable->BootServices->LocateProtocol, 3, &GraphicsOutputProtocol, NULL, &gop);

  Print(L"Framebuffer base is at %lx\n", gop->Mode->FrameBufferBase);
  
  print_modes(gop);

  Print(L"\n\n\nHit any key\n");
  WaitForSingleEvent(SystemTable->ConIn->WaitForKey, 0);
  status = uefi_call_wrapper(SystemTable->ConIn->ReadKeyStroke, 2, SystemTable->ConIn, &efi_input_key);
 
  paint_screen(gop, (UINT32)0x00FF0000);
  uefi_call_wrapper(BS->Stall, 1, 2 * 1000 * 1000);
 
  paint_screen(gop, (UINT32)0x0000FF00);
  uefi_call_wrapper(BS->Stall, 1, 2 * 1000 * 1000);
 
  paint_screen(gop, (UINT32)0x000000FF0);

  // FROM: https://github.com/vathpela/gnu-efi/blob/master/apps/t7.c

  Print(L"\n\n\nHit any key to exit this image\n");

  WaitForSingleEvent(SystemTable->ConIn->WaitForKey, 0);
  
  uefi_call_wrapper(SystemTable->ConOut->OutputString, 2, SystemTable->ConOut, L"\n\n");
  
  status = uefi_call_wrapper(SystemTable->ConIn->ReadKeyStroke, 2, SystemTable->ConIn, &efi_input_key);
  
  Print(L"ScanCode: %xh  UnicodeChar: %xh\n", efi_input_key.ScanCode, efi_input_key.UnicodeChar);

  return EFI_SUCCESS;
}
Beispiel #2
0
EFI_STATUS EFIAPI efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab) {

	InitializeLib(image_handle, systab);
	EFI_STATUS Status;
	systab->ConOut->ClearScreen(systab->ConOut); // CLEAR!

    EFI_GUID simplefs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL; // a simple file system protocol in efi
	                      // (different from UEFI specification. In specification, this is called EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID )

	EFI_FILE_IO_INTERFACE *simplefs;                      // the simple file system's interface
	                      // (different from UEFI specification. In specification, this is called EFI_SIMPLE_FILE_SYSTEM_PROTOCOL)
	EFI_FILE *root;               //  root directory
	EFI_FILE *dir;
	CHAR16 *dirname=L"\\stories"; // name of the directory where bmp pictures are put

	status=systab->BootServices->LocateProtocol(&simplefs_guid, NULL, (VOID **)&simplefs);
	if(EFI_ERROR(status)) Print(L"locate protocol failed \n");

	status=simplefs->OpenVolume(simplefs, &root);
	if(EFI_ERROR(status)) Print(L"open volume failed\n");

	status=root->Open(root, &dir, dirname, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY);
	if(EFI_ERROR(status)) Print(L"open directory failed\n");

	VOID *buf;
	INT32 index=1;
	status = readFile(dir, index, systab, buf); // Put the contents of 1.story into buf
	Print(L"%s", buf);

    WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
	uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &Key);

    return Status;
}
Beispiel #3
0
VOID
efi_pause ()
{
	EFI_INPUT_KEY Key;

	WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
	uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &Key);
}
Beispiel #4
0
Datei: key.c Projekt: chengs/UEFI
//获得键盘输入扫描码
UINT16 keyGetInput(){
	EFI_INPUT_KEY Key;
	EFI_STATUS Status;
	WaitForSingleEvent (ST->ConIn->WaitForKey, 0);
	Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key);
	if(Key.UnicodeChar == 0xD) //enter
		return KEY_ENTER;
	else
		return Key.ScanCode;
}
Beispiel #5
0
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
	InitializeLib(image, systab);
	Print(L"HelloLib application started\n");
	Print(L"\n\n\nHit any key to exit this image\n");
	WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
	uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L"\n\n");
	return EFI_SUCCESS;
}
Beispiel #6
0
VOID
WaitForEventWithTimeout (
  IN  EFI_EVENT       Event,
  IN  UINTN           Timeout,
  IN  UINTN           Row,
  IN  UINTN           Column,
  IN  CHAR16          *String,
  IN  EFI_INPUT_KEY   TimeoutKey,
  OUT EFI_INPUT_KEY   *Key
  )
/*++

Routine Description:
  function prints a string for the given number of seconds until either the
  timeout expires, or the user presses a key.

Arguments:
  Event            - The event to wait for

  Timeout          - A timeout value in 1 second units.

  Row              - A row to print String

  Column           - A column to print String

  String           - The string to display on the standard output device

  TimeoutKey       - The key to return in Key if a timeout occurs

  Key              - Either the key the user pressed or TimeoutKey if the Timeout expired.

Returns:

  none

--*/
{
  EFI_STATUS      Status;

  while (Timeout > 0) {
    PrintAt (Column, Row, String, Timeout);
    Status = WaitForSingleEvent (Event, 10000000);
    if (Status == EFI_SUCCESS) {
      if (!EFI_ERROR(tST->ConIn->ReadKeyStroke (tST->ConIn, Key))) {
        return;
      }
    }
    Timeout--;
  }
  *Key = TimeoutKey;
}
Beispiel #7
0
EFI_STATUS
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
	EFI_INPUT_KEY efi_input_key;
	EFI_STATUS efi_status;

	InitializeLib(image, systab);

	Print(L"HelloLib application started\n");

	Print(L"\n\n\nHit any key to exit this image\n");
	WaitForSingleEvent(ST->ConIn->WaitForKey, 0);

	uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L"\n\n");

	efi_status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &efi_input_key);

	Print(L"ScanCode: %xh  UnicodeChar: %xh CallRtStatus: %x\n",
		efi_input_key.ScanCode, efi_input_key.UnicodeChar, efi_status);

	return EFI_SUCCESS;
}
Beispiel #8
0
VOID
WaitForEventWithTimeout (
    IN  EFI_EVENT       Event,
    IN  UINTN           Timeout,
    IN  UINTN           Row,
    IN  UINTN           Column,
    IN  CHAR16          *String,
    IN  EFI_INPUT_KEY   TimeoutKey,
    OUT EFI_INPUT_KEY   *Key
    )
{
    EFI_STATUS      Status;

    do {
        PrintAt (Column, Row, String, Timeout);
        Status = WaitForSingleEvent (Event, 10000000);
        if (Status == EFI_SUCCESS) {
            if (!EFI_ERROR(uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key))) {
                return;
            }
        }
    } while (Timeout > 0);
    CopyMem(Key, &TimeoutKey, sizeof(EFI_INPUT_KEY));
}
Beispiel #9
0
/**
  Function show progress bar to wait for user input.


  @param   TimeoutDefault  The fault time out value before the system continue to boot.

  @retval  EFI_SUCCESS       User pressed some key except "Enter"
  @retval  EFI_TIME_OUT      Timeout expired or user press "Enter"

**/
EFI_STATUS
ShowProgress (
  IN UINT16                       TimeoutDefault
  )
{
  CHAR16                        *TmpStr;
  UINT16                        TimeoutRemain;
  EFI_STATUS                    Status;
  EFI_INPUT_KEY                 Key;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;

  if (TimeoutDefault != 0) {
    DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));

    SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
    SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
    SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
    
    TmpStr = GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION));

    if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
      //
      // Clear the progress status bar first
      //
      if (TmpStr != NULL) {
        PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
      }
    }
    

    TimeoutRemain = TimeoutDefault;
    while (TimeoutRemain != 0) {
      DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));

      Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
      if (Status != EFI_TIMEOUT) {
        break;
      }
      TimeoutRemain--;
      
      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
        //
        // Show progress
        //
        if (TmpStr != NULL) {
          PlatformBdsShowProgress (
            Foreground,
            Background,
            TmpStr,
            Color,
            ((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault),
            0
            );
        }
      }
    }
    
    if (TmpStr != NULL) {
      gBS->FreePool (TmpStr);
    }

    //
    // Timeout expired
    //
    if (TimeoutRemain == 0) {
      return EFI_TIMEOUT;
    }
  }

  //
  // User pressed some key
  //
  if (!PcdGetBool (PcdConInConnectOnDemand)) {
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
      //
      // User pressed enter, equivalent to select "continue"
      //
      return EFI_TIMEOUT;
    }
  }

  return EFI_SUCCESS;
}
Beispiel #10
0
EFI_STATUS
pciUtilAdv(
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
/*++

Routine Description:
  Collect PCI Data

Arguments:

Returns:
  
--*/
{

  
  BOOLEAN       isWaiting;
  UINT8         *Value8;
  UINT16        BarRow;
  UINT16        BarOffset;
  UINT16        BarStartPosition;
  UINT16        BarEndPosition;
  UINT16        PciDeviceNumber;
  UINT16        ConfCol;
  UINT16        ConfColStart;
  UINT16        ConfColEnd;
  UINT16        ConfColOffset; 
  UINT16        ConfRow;
  UINT16        ConfRowEnd;
  UINT16        ConfRowStart;
  UINT16        ConfRowOffset;
  CHAR16        StrInput[3];
  SHELL_MODE    Mode;      
//  EFI_STATUS    Status;
  EFI_INPUT_KEY KeyBuffer;
  PCITable      PciTable[30];
 // UINTN  V;
  
  
  InitializeShellApplication(ImageHandle, SystemTable);

  isWaiting = 1;
  PciDeviceNumber = 0;
  BarStartPosition = 0;
  BarRow =    0;
  BarOffset = 2;
  ConfColOffset = 3;
  ConfCol = 0;
  ConfColStart = 0;
  ConfColEnd = ConfColStart + 15;
  ConfRow = 0;
  ConfRowOffset = 1;
  ConfRowEnd = 15;
  ConfRowStart = 0;

  Mode = DEVICE_LIST_MODE;
 

  ReadoutPCI(&PciDeviceNumber,
             PciTable
             );  

  BarEndPosition = BarRow + PciDeviceNumber;

//  Print(L"%d\n\r", PciDeviceNumber);

  DumpPCI(PciDeviceNumber,
          PciTable);
  
 while(isWaiting){
	 // Block Wait for Key
	 WaitForSingleEvent (ST->ConIn->WaitForKey, 100);
	 ST->ConIn->ReadKeyStroke (ST->ConIn, &KeyBuffer);

	 
	 switch ( KeyBuffer.ScanCode + Mode ) {

	   //
	   // Press ESC
	   //
	   case 0x117:

	     ST->ConOut->OutputString(ST->ConOut,L"hello, world\n\r");
		   ST->ConOut->SetAttribute(ST->ConOut, 
									       EFI_BACKGROUND_BLACK
									       );
		   ST->ConOut->ClearScreen(ST->ConOut);
		   isWaiting = 0;

       
	     break;

       //
         // Press ESC
         //
         case 0x217:
       
           ST->ConOut->OutputString(ST->ConOut,L"hello, world\n\r");
           ST->ConOut->SetAttribute(ST->ConOut, 
                             EFI_BACKGROUND_BLACK
                             );
           ST->ConOut->ClearScreen(ST->ConOut);
           isWaiting = 0;
       
           
           break;

       

       //
       // Press Move Up 1 Row - DEVICE_LIST_MODE
	     //
       case 0x101:
        
         
         if (BarRow == BarStartPosition){
               BarRow = BarStartPosition;             
         }

         else
           BarRow--;
          
         ST->ConOut->ClearScreen(ST->ConOut);      
         ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0);
         
         DumpPCI(PciDeviceNumber,
                 PciTable);
         
         ST->ConOut->SetCursorPosition(ST->ConOut, 0, BarRow + BarOffset);
  
         ST->ConOut->SetAttribute(ST->ConOut, 
  									       EFI_BACKGROUND_GREEN
  									       );
  	   	// ST->ConOut->OutputString(ST->ConOut,L"hello, Rachel\n\r");

         Print(L" %-02x   ",
               PciTable[ BarRow - BarStartPosition].Bus
               );

         Print(L"%-02x      ",
               PciTable[ BarRow - BarStartPosition].Device
               );

         Print(L"%-02x      ",
                  PciTable[ BarRow - BarStartPosition].Func
               );

         Print(L"%-04x     ",
               PciTable[ BarRow - BarStartPosition].PCIData.Hdr.VendorId
               );

         Print(L"%-04x    ",
                PciTable[ BarRow - BarStartPosition].PCIData.Hdr.DeviceId
                );

         
         Print(L"%-04x    ",
                PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemVendorID
                );

         Print(L"%-04x",
                PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemID
                );

        
         ST->ConOut->SetAttribute(ST->ConOut, 
  			       EFI_BACKGROUND_BLACK
  			       );
  
         ST->ConOut->SetAttribute(ST->ConOut, 
  		                            EFI_LIGHTGRAY
  		                            );
  
         
  
         break;
         
       //
       // Press Move Down 1 Row - DEVICE_LIST_MODE
       // 
       case 0x102:

         BarRow++;
         if (BarRow >= BarEndPosition){
               BarRow = BarEndPosition - 1;
         } 
         
         ST->ConOut->ClearScreen(ST->ConOut);      
         ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0);
         
         DumpPCI(PciDeviceNumber,
                  PciTable);

         
         ST->ConOut->SetCursorPosition(ST->ConOut, 0, BarRow + BarOffset);
         
         ST->ConOut->SetAttribute(ST->ConOut, 
                           EFI_BACKGROUND_GREEN
                           );
//         ST->ConOut->OutputString(ST->ConOut,L"hello, Rachel\n\r");


         Print(L" %-02x   ",
               PciTable[ BarRow - BarStartPosition].Bus
               );

         Print(L"%-02x      ",
               PciTable[ BarRow - BarStartPosition].Device
               );

         Print(L"%-02x      ",
                  PciTable[ BarRow - BarStartPosition].Func
               );

         Print(L"%-04x     ",
               PciTable[ BarRow - BarStartPosition].PCIData.Hdr.VendorId
               );

         Print(L"%-04x    ",
                PciTable[ BarRow - BarStartPosition].PCIData.Hdr.DeviceId
                );

         
         Print(L"%-04x    ",
                PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemVendorID
                );

         Print(L"%-04x",
                PciTable[ BarRow - BarStartPosition].PCIData.Device.SubsystemID
                );

         ST->ConOut->SetAttribute(ST->ConOut, 
               EFI_BACKGROUND_BLACK
               );
         
         ST->ConOut->SetAttribute(ST->ConOut, 
                                  EFI_LIGHTGRAY
                                  );

  
         break;



        //
       // Press Move Up 1 Row - CONF_MODE
	     //
       case 0x201:

        
         
         if (ConfRow == ConfRowStart){
               ConfRow = ConfRowStart;
         } 

         else
          ConfRow--;
    
         DumpPciConfigureSpace( BarRow,
                               PciTable);

          
         ST->ConOut->SetAttribute(ST->ConOut, 
  			                          EFI_RED
  			                          );



         ST->ConOut->SetCursorPosition(
                                       ST->ConOut,
                                       ConfCol * 3 + ConfColOffset,
                                       ConfRow + ConfRowOffset
                                       );


         Value8 = (UINT8*) (PciTable + BarRow);
         
         Print(L"%-02x", *(Value8 + ( ConfRow * 16) + ConfCol) );
         //Print(L" Row = %d", ConfRow);

  
         ST->ConOut->SetAttribute(ST->ConOut, 
  		                            EFI_BACKGROUND_BLUE
  		                            );
  

         break;


        //
       // Press Move Down 1 Row - CONF_MODE
       // 
       case 0x202:

         ConfRow++;
         if (ConfRow >= ConfRowEnd){
               ConfRow = ConfRowEnd;
         } 
         
         ST->ConOut->ClearScreen(ST->ConOut);      
         ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0);
         
         DumpPciConfigureSpace(BarRow,
                  PciTable);

        ST->ConOut->SetAttribute(ST->ConOut, 
                                   EFI_RED
                                   );      
        
         ST->ConOut->SetCursorPosition(ST->ConOut, 
                                       ConfCol * 3 + ConfColOffset, 
                                       ConfRow + ConfRowOffset                                      
                                       );

         Value8 = (UINT8*) (PciTable + BarRow);
         
         Print(L"%-02x", *(Value8 + (ConfRow  * 16 + ConfCol)) );  
         //Print(L" Row = %d", ConfRow);

         ST->ConOut->SetAttribute(ST->ConOut, 
               EFI_BACKGROUND_BLUE
               );
         
     
         break; 



         //
         // Press Move Right - CONF MODE 
         //
         case 0x203:
           
            ConfCol++;
            if (ConfCol >= ConfColEnd){
                  ConfCol= ConfColEnd;
            } 
            
            ST->ConOut->ClearScreen(ST->ConOut);      
            ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0);
            
            DumpPciConfigureSpace(BarRow,
                     PciTable);
   
           ST->ConOut->SetAttribute(ST->ConOut, 
                                      EFI_RED
                                      );      
           
            ST->ConOut->SetCursorPosition(ST->ConOut, 
                                          ConfCol *3 + ConfColOffset, 
                                          ConfRow + ConfRowOffset                                      
                                          );
   
            Value8 = (UINT8*) (PciTable + BarRow);
            
            Print(L"%-02x", *(Value8 + (ConfRow  * 16 + ConfCol)) );  
//            Print(L" Col = %d", ConfCol);
   
            ST->ConOut->SetAttribute(ST->ConOut, 
                  EFI_BACKGROUND_BLUE
                  );
            
     
          
          

           break;


         //
         // Press Move Left - CONF_MODE
         //
         case 0x204: 

            
            if (ConfCol == ConfColStart){
                  ConfCol= ConfColStart;
            } 

            else
              ConfCol--;
            
            ST->ConOut->ClearScreen(ST->ConOut);      
            ST->ConOut->SetCursorPosition(ST->ConOut, 0, 0);
            
            DumpPciConfigureSpace(BarRow,
                     PciTable);
   
           ST->ConOut->SetAttribute(ST->ConOut, 
                                      EFI_RED
                                      );      
           
            ST->ConOut->SetCursorPosition(ST->ConOut, 
                                          ConfCol * 3 + ConfColOffset, 
                                          ConfRow + ConfRowOffset                                      
                                          );
   
            Value8 = (UINT8*) (PciTable + BarRow);
            
            Print(L"%-02x", *(Value8 + (ConfRow  * 16 + ConfCol)) );  
//            Print(L" Col = %d", ConfCol);
   
            ST->ConOut->SetAttribute(ST->ConOut, 
                  EFI_BACKGROUND_BLUE
                  );
            
       
     

          
           break;
       
              //
              // Press F1  - Dump PCI
              // 
              case 0x20B:
       
               DumpPCI(1,
                       PciTable);

               Mode = DEVICE_LIST_MODE;
       
                break;


         


       //
       // Press F2 - Dump Conf Space
       // 
       case 0x10C:


//           DrawDumpPciConfigureSpaceBorder();
           DumpPciConfigureSpace(BarRow, 
                                 PciTable);

           Mode = CONFIGURE_SPACE_MODE;

         break; 

       //
       // Press "F3" - CONF_MODE
       //
       case 0x20D:
    
    
            DumpPciConfigureSpaceWord(BarRow,
                                      PciTable
                                      );
   
               Mode = CONFIGURE_SPACE_MODE;
    
             break; 

         

	  default:	     
	    break;
	 }


   //
   //  Press "Enter" - DEVICE_LIST_MODE
   //
	 if ( (KeyBuffer.UnicodeChar == 0x000D) && ( Mode == DEVICE_LIST_MODE) ){

       Mode = CONFIGURE_SPACE_MODE;
       DumpPciConfigureSpace( BarRow,
                              PciTable);

   

	 	}


   //
   // Press "Enter" - CONF_MODEs
   //
   else
   if( (KeyBuffer.UnicodeChar == 0x000D) && (Mode == CONFIGURE_SPACE_MODE) )
   {
//       Mode = DEVICE_LIST_MODE;


       ST->ConOut->SetAttribute(ST->ConOut, 
                           EFI_RED
                           );      
       
       ST->ConOut->SetCursorPosition(ST->ConOut, 
                                          0, 
                                          22                                     
                                          );


        
       Input( L"Modify Value to :",
              StrInput, 
              sizeof(StrInput)/sizeof(CHAR16)
              );

  //    V = xtoi(StrInput);
       WriteValueToPciConfigSpace8(StrInput,
                                   PciTable,
                                   BarRow,
                                   ConfRow *16 + ConfCol
                                   );
  
      
      

       DumpPciConfigureSpace( BarRow, 
                              PciTable);

 /*      
             ST->ConOut->SetCursorPosition(ST->ConOut, 
                                          0, 
                                          22                                     
                                          );
       Print(L"%-02x", V);

   */    

	 }





  
}

 return EFI_SUCCESS;
}
Beispiel #11
0
void WaitKey(void) {
	ST->ConIn->Reset(ST->ConIn, FALSE);
	WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
}
Beispiel #12
0
EFI_STATUS EfiMain(EFI_HANDLE hImage, EFI_SYSTEM_TABLE *pST)
{
    EFI_LOADED_IMAGE *pImage;
    EFI_STATUS nStatus;
    EFI_HANDLE hDriver, *hBlkDevs;
    UINTN nBlkDevs;
    EFI_DEVICE_PATH *pBootPart, *pBootDisk = NULL;

    g_hImage = hImage;
    InitializeLib(hImage, pST);
    Print(L"%H\n*** UEFI:NTFS multiboot ***");

    if (EFI_ERROR((nStatus = BS->OpenProtocol(hImage, &LoadedImageProtocol, &pImage, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) {
        Print(L"%E\nUnable to convert handle to interface: %r\n", nStatus);
        goto end;
    }

    pBootPart = DevicePathFromHandle(pImage->DeviceHandle);
    pBootDisk = GetParentDevice(pBootPart);

    CHAR16 *pszDev = DevicePathToStr(pBootDisk);
    Print(L"%N\nDisk: %s\n", pszDev);
    FreePool(pszDev);

    Print(L"%H\n[ INFO ] Disconnecting problematic File System drivers\n");
    DisconnectBlockingDrivers();

    Print(L"%H\n[ WAIT ] Loading NTFS driver");
    EFI_DEVICE_PATH *pDrvPath = FileDevicePath(pImage->DeviceHandle, DriverPath);
    if (pDrvPath == NULL) {
        Print(L"%E\r[ FAIL ] Unable to construct path to NTFS driver\n");
        goto end;
    }
    nStatus = BS->LoadImage(FALSE, hImage, pDrvPath, NULL, 0, &hDriver);
    FreePool(pDrvPath);
    if (EFI_ERROR(nStatus)) {
        Print(L"%E\r[ FAIL ] Unable to load NTFS driver: %r\n", nStatus);
        goto end;
    }
    if (EFI_ERROR((nStatus = BS->StartImage(hDriver, NULL, NULL)))) {
        Print(L"%E\r[ FAIL ] Unable to start NTFS driver: %r\n", nStatus);
        goto end;
    }

    Print(L"%H\r[  OK  ] NTFS driver loaded and started\n");

    LINKED_LOADER_PATH_LIST_NODE *list = NULL;
    EFI_DEVICE_PATH *ldr;

    if (EFI_ERROR((nStatus = BS->LocateHandleBuffer(ByProtocol, &BlockIoProtocol, NULL, &nBlkDevs, &hBlkDevs)))) {
        Print(L"%E\r[ FAIL ] Unable to enumerate block devices: %r\n", nStatus);
        goto end;
    }
    for (UINTN i = 0; i < nBlkDevs; i++) {
        EFI_DEVICE_PATH *pDevice = DevicePathFromHandle(hBlkDevs[i]);
        pszDev = DevicePathToStr(pDevice);
        Print(L"%N\r[ INFO ] Probing %d devices... [%d] %s", nBlkDevs, i + 1, pszDev);
        FreePool(pszDev);

        if (CompareDevicePaths(pDevice, pBootPart) == 0) continue;
        if (CompareDevicePaths(pDevice, pBootDisk) == 0) continue;

        EFI_DEVICE_PATH *pDisk = GetParentDevice(pDevice);
        _Bool probe = CompareDevicePaths(pDisk, pBootDisk) == 0;
        FreePool(pDisk);
#if !defined(_DEBUG)
        if (!probe) continue;
#endif

        EFI_BLOCK_IO *blkIo;
        if (EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &BlockIoProtocol, &blkIo, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) {
            Print(L"%E\n[ WARN ] Unable to open block device, skipping: %r\n", nStatus);
            continue;
        }

        //No media or not a partition.
        if ((blkIo->Media == NULL) || (!blkIo->Media->LogicalPartition))
            continue;

        CHAR8 *buffer = AllocatePool(blkIo->Media->BlockSize);
        if (buffer == NULL) {
            Print(L"%E\n[ WARN ] Unable to allocate buffer of size %d\n", blkIo->Media->BlockSize);
            continue;
        }

        nStatus = blkIo->ReadBlocks(blkIo, blkIo->Media->MediaId, 0, blkIo->Media->BlockSize, buffer);
        _Bool isNTFS = CompareMem(&buffer[3], NTFSMagic, sizeof(NTFSMagic)) == 0;
        FreePool(buffer);
        if (EFI_ERROR(nStatus)) {
            Print(L"%E\n[ WARN ] Unable to read block device, skipping: %r\n", nStatus);
            continue;
        }
        if (!isNTFS) continue;

        Print(L"%H\n[ WAIT ] Attaching NTFS driver to device");
        EFI_FILE_IO_INTERFACE *fs;
        nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, NULL, hImage, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
        if (nStatus == EFI_UNSUPPORTED) {
            nStatus = BS->ConnectController(hBlkDevs[i], NULL, NULL, TRUE);
        }
        for (UINTN j = 0; j < NUM_RETRIES; j++) {
            if ((!EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, &fs, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL))))) {
                break;
            }
            Print(L".");
            BS->Stall(DELAY * 1000000);
        }
        if(EFI_ERROR(nStatus)) {
            Print(L"%E\r[ WARN ] Unable to attach NTFS driver, skipping: %r\n", nStatus);
            continue;
        }
        Print(L"%H\r[  OK  ] NTFS driver attached to current device\n");

        Print(L"%H\r[ WAIT ] Locating EFI boot loader");
        EFI_FILE *fsRoot;
        if (EFI_ERROR((nStatus = fs->OpenVolume(fs, &fsRoot)))) {
            Print(L"%E\r[ WARN ] Unable to open root directory, skipping: %r\n", nStatus);
            continue;
        }
        CHAR16 *loader = StrDuplicate(LoaderPath);
        if (EFI_ERROR((nStatus = SetPathCase(fsRoot, loader)))) {
            FreePool(loader);
            Print(L"%E\r[ WARN ] Unable to locate EFI boot loader on this device: %r\n", nStatus);
            continue;
        }
        Print(L"%H\r[  OK  ] EFI boot loader located at %s\n", loader);

        ldr = FileDevicePath(hBlkDevs[i], loader);
        ListAppend(&list, ldr);
        FreePool(loader);
    }

    UINTN nListEntries = 0, nBootEntry = 0, nPage = 0, nTotalPage = 0;
    EFI_INPUT_KEY key;
    _Bool interactive = FALSE;
    ListTraverse(&list, CountEntries, 0, 0, &nListEntries);

    switch (nListEntries) {
    case 0:
        Print(L"%E\n[ FAIL ] No bootable partition\n", nStatus);
        nStatus = EFI_NOT_FOUND;
        goto end;
    case 1:
        goto boot;
    default:
        nTotalPage = (nListEntries - 1) / PAGE_SIZE + 1;
        while (1) {
            ST->ConOut->ClearScreen(ST->ConOut);
            Print(L"%H*** UEFI:NTFS Multiboot ***\n");
            pszDev = DevicePathToStr(pBootDisk);
            Print(L"%NDisk: %s\n\n%H", pszDev);
            FreePool(pszDev);

            ListTraverse(&list, DisplayEntries, nPage * PAGE_SIZE, PAGE_SIZE, NULL);

            Print(L"%N\nPage %hd / %hd, %hd entries\n", nPage + 1, nTotalPage, nListEntries);
            Print(L"%H\n[F1 - F8] [1 - 8] %N Boot corresponding entry");
            Print(L"%H\n[PgUp]  [<]  [-]  %N Previous page");
            Print(L"%H\n[PgDn]  [>]  [+]  %N Next page");

            if (!interactive) {
                INTN nCountDown = AUTOBOOT_TIME;
                Print(L"%N\n\n");
                while (nCountDown >= 0) {
                    Print(L"\rWill automatically boot the first entry in %d seconds...", nCountDown);
                    if (WaitForSingleEvent(ST->ConIn->WaitForKey, 1000 * 1000 * 10) != EFI_TIMEOUT) {
                        interactive = TRUE;
                        break;
                    }
                    nCountDown--;
                }
                if (!interactive) {
                    goto boot;
                }
            }
            else {
                WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
            }
            ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
            switch (key.UnicodeChar) {
            case L'1':case L'2':case L'3':case L'4':case L'5':case L'6':case L'7':case L'8':
                nBootEntry = nPage * PAGE_SIZE + (key.UnicodeChar - L'1');
                goto boot;
            case L'+':case L'=':case L'>':case L'.':
                if ((nPage + 1) != nTotalPage) {
                    nPage++;
                }
                break;
            case L'-':case L'_': case L'<': case L',':
                if (nPage != 0) {
                    nPage--;
                }
                break;
            default:
                switch (key.ScanCode) {
                case 0x09:
                    if (nPage != 0) {
                        nPage--;
                    }
                    break;
                case 0x0a:
                    if ((nPage + 1) != nTotalPage) {
                        nPage++;
                    }
                    break;
                case 0x0b:case 0x0c:case 0x0d:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:
                    nBootEntry = nPage * PAGE_SIZE + (key.ScanCode - 0x0b);
                    goto boot;
                }
            }
        }
    }

boot:
    ldr = NULL;
    Print(L"%H");
    ST->ConOut->ClearScreen(ST->ConOut);
    ListTraverse(&list, ReadEntry, nBootEntry, 1, &ldr);
    ListTraverse(&list, DisplayEntries, nBootEntry, 1, NULL);
    if (ldr == NULL) {
        Print(L"%E\n[ FAIL ] No such boot entry\n", nStatus);
        nStatus = EFI_NOT_FOUND;
        goto end;
    }

    ldr = DuplicateDevicePath(ldr);
    ListTraverse(&list, DestroyEntries, 0, 0, NULL);
    ListDestroy(&list);

    EFI_HANDLE hChain;
    nStatus = BS->LoadImage(FALSE, hImage, ldr, NULL, 0, &hChain);
    FreePool(ldr);
    if (EFI_ERROR(nStatus)) {
        Print(L"%E\n[ FAIL ] Unable to load boot loader: %r\n", nStatus);
        goto end;
    }
    Print(L"%N");
    if (EFI_ERROR((nStatus = BS->StartImage(hChain, NULL, NULL)))) {
        Print(L"%E\n[ FAIL ] Unable to start boot loader: %r\n", nStatus);
        goto end;
    }

end:
    if (pBootDisk) FreePool(pBootDisk);
    if (EFI_ERROR(nStatus)) {
        Print(L"Press any key to exit\n");
        WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
        ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
    }
    return nStatus;
}
Beispiel #13
0
EFI_STATUS
MainInputBarRefresh (
  VOID
  )
/*++
Routine Description: 

  refresh function for MainInputBar, it will wait for user input

Arguments:  

  VOID

Returns:  

  EFI_SUCCESS

--*/
{
  EFI_EDITOR_COLOR_UNION  Orig;
  EFI_EDITOR_COLOR_UNION  New;
  EFI_INPUT_KEY           Key;
  UINTN                   Size;
  EFI_STATUS              Status;
  BOOLEAN                 NoDisplay;
  UINTN                   Limit;
  UINTN                   PromptLen;

  //
  // variable initialization
  //
  Size    = 0;
  Status  = EFI_SUCCESS;

  //
  // free status string
  //
  EditorFreePool (MainEditor.StatusBar->StatusString);
  MainEditor.StatusBar->StatusString = PoolPrint (L"");
  if (MainEditor.StatusBar->StatusString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // back up the old screen attributes
  //
  Orig                  = MainEditor.ColorAttributes;
  New.Colors.Foreground = Orig.Colors.Background;
  New.Colors.Background = Orig.Colors.Foreground;

  Out->SetAttribute (Out, New.Data);

  //
  // clear input bar
  //
  EditorClearLine (INPUT_BAR_LOCATION);

  Out->SetCursorPosition (Out, 0, INPUT_BAR_LOCATION - 1);
  PrintToken (STRING_TOKEN (STR_EDIT_LIBINPUTBAR_MAININPUTBAR), HiiHandle, MainInputBar.Prompt);

  //
  // that's the maximum input length that can be displayed on screen
  //
  PromptLen = StrLen (MainInputBar.Prompt);
  Limit     = MainEditor.ScreenSize.Column - PromptLen;

  //
  // this is a selection prompt, cursor will stay in edit area
  // actually this is for search , search/replace
  //
  if (StrStr (MainInputBar.Prompt, L"Yes/No")) {
    NoDisplay = TRUE;
    FileBufferRestorePosition ();
    Out->SetAttribute (Out, Orig.Data);
  } else {
    NoDisplay = FALSE;
  }
  //
  // wait for user input
  //
  for (;;) {
    WaitForSingleEvent (In->WaitForKey, 0);
    Status = In->ReadKeyStroke (In, &Key);
    if (EFI_ERROR (Status)) {
      continue;
    }
    //
    // pressed ESC
    //
    if (Key.ScanCode == SCAN_CODE_ESC) {
      Size    = 0;
      Status  = EFI_NOT_READY;
      break;
    }
    //
    // return pressed
    //
    if (Key.UnicodeChar == CHAR_LF || Key.UnicodeChar == CHAR_CR) {
      break;
    } else if (Key.UnicodeChar == CHAR_BS) {
      //
      // backspace
      //
      if (Size > 0) {
        Size--;
        MainInputBar.ReturnString[Size] = L'\0';
        if (!NoDisplay) {

          MainInputBarPrintInput ();

        }
      }
    } else if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) {
      //
      // VALID ASCII char pressed
      //
      MainInputBar.ReturnString[Size] = Key.UnicodeChar;

      //
      // should be less than specified length
      //
      if (Size >= MainInputBar.StringSize) {
        continue;
      }

      Size++;

      MainInputBar.ReturnString[Size] = L'\0';

      if (!NoDisplay) {

        MainInputBarPrintInput ();

      } else {
        //
        // if just choose yes/no
        //
        break;
      }

    }
  }

  MainInputBar.ReturnString[Size] = 0;

  FileBufferRestorePosition ();

  //
  // restore screen attributes
  //
  Out->SetAttribute (Out, Orig.Data);

  StatusBarNeedRefresh = TRUE;

  return Status;
}