示例#1
0
// Sets the screen resolution to the specified value, if possible.
// If the specified value is not valid, displays a warning with the valid
// modes on UEFI systems, or silently fails on EFI 1.x systems. Note that
// this function attempts to set ANY screen resolution, even 0x0 or
// ridiculously large values.
// Returns TRUE if successful, FALSE if not.
BOOLEAN egSetScreenSize(IN UINTN ScreenWidth, IN UINTN ScreenHeight) {
   EFI_STATUS Status = EFI_SUCCESS;
   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
   UINT32 ModeNum = 0;
   UINTN Size;
   BOOLEAN ModeSet = FALSE;
   UINT32 UGAWidth, UGAHeight, UGADepth, UGARefreshRate;

   if (GraphicsOutput != NULL) { // GOP mode (UEFI)
      // Do a loop through the modes to see if the specified one is available;
      // and if so, switch to it....
      while ((Status == EFI_SUCCESS) && (!ModeSet)) {
         Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
         if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info)) &&
             (Info->HorizontalResolution == ScreenWidth) && (Info->VerticalResolution == ScreenHeight)) {
            Status = refit_call2_wrapper(GraphicsOutput->SetMode, GraphicsOutput, ModeNum);
            ModeSet = (Status == EFI_SUCCESS);
         } // if
         ModeNum++;
      } // while()

      if (ModeSet) {
         egScreenWidth = ScreenWidth;
         egScreenHeight = ScreenHeight;
      } else {// If unsuccessful, display an error message for the user....
         Print(L"Error setting mode %d x %d; using default mode!\nAvailable modes are:\n", ScreenWidth, ScreenHeight);
         ModeNum = 0;
         Status = EFI_SUCCESS;
         while (Status == EFI_SUCCESS) {
            Status = refit_call4_wrapper(GraphicsOutput->QueryMode, GraphicsOutput, ModeNum, &Size, &Info);
            if ((Status == EFI_SUCCESS) && (Size >= sizeof(*Info))) {
               Print(L"Mode %d: %d x %d\n", ModeNum, Info->HorizontalResolution, Info->VerticalResolution);
            } // else
            ModeNum++;
         } // while()
         PauseForKey();
      } // if()
   } else if (UgaDraw != NULL) { // UGA mode (EFI 1.x)
      // Try to use current color depth & refresh rate for new mode. Maybe not the best choice
      // in all cases, but I don't know how to probe for alternatives....
      Status = refit_call5_wrapper(UgaDraw->GetMode, UgaDraw, &UGAWidth, &UGAHeight, &UGADepth, &UGARefreshRate);
      Status = refit_call5_wrapper(UgaDraw->SetMode, UgaDraw, ScreenWidth, ScreenHeight, UGADepth, UGARefreshRate);
      if (Status == EFI_SUCCESS) {
         egScreenWidth = ScreenWidth;
         egScreenHeight = ScreenHeight;
         ModeSet = TRUE;
      } else {
         // TODO: Find a list of supported modes and display it.
         // NOTE: Below doesn't actually appear unless we explicitly switch to text mode.
         // This is just a placeholder until something better can be done....
         Print(L"Error setting mode %d x %d; unsupported mode!\n");
      } // if/else
   } // if/else if
   return (ModeSet);
} // BOOLEAN egSetScreenSize()
示例#2
0
VOID egInitScreen(VOID)
{
    EFI_STATUS Status = EFI_SUCCESS;
    UINT32 UGAWidth, UGAHeight, UGADepth, UGARefreshRate;

    // get protocols
    Status = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **) &ConsoleControl);
    if (EFI_ERROR(Status))
        ConsoleControl = NULL;

    Status = LibLocateProtocol(&UgaDrawProtocolGuid, (VOID **) &UgaDraw);
    if (EFI_ERROR(Status))
        UgaDraw = NULL;

    Status = LibLocateProtocol(&GraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
    if (EFI_ERROR(Status))
        GraphicsOutput = NULL;

    // get screen size
    egHasGraphics = FALSE;
    if (GraphicsOutput != NULL) {
        egScreenWidth = GraphicsOutput->Mode->Info->HorizontalResolution;
        egScreenHeight = GraphicsOutput->Mode->Info->VerticalResolution;
        egHasGraphics = TRUE;
    } else if (UgaDraw != NULL) {
        Status = refit_call5_wrapper(UgaDraw->GetMode, UgaDraw, &UGAWidth, &UGAHeight, &UGADepth, &UGARefreshRate);
        if (EFI_ERROR(Status)) {
            UgaDraw = NULL;   // graphics not available
        } else {
            egScreenWidth  = UGAWidth;
            egScreenHeight = UGAHeight;
            egHasGraphics = TRUE;
        }
    }
}
示例#3
0
EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, OUT UINT8 **FileData, OUT UINTN *FileDataLength)
{
    EFI_STATUS          Status;
    EFI_FILE_HANDLE     FileHandle;
    EFI_FILE_INFO       *FileInfo;
    UINT64              ReadSize;
    UINTN               BufferSize;
    UINT8               *Buffer;

    Status = refit_call5_wrapper(BaseDir->Open, BaseDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
    if (EFI_ERROR(Status)) {
        return Status;
    }

    FileInfo = LibFileInfo(FileHandle);
    if (FileInfo == NULL) {
        refit_call1_wrapper(FileHandle->Close, FileHandle);
        return EFI_NOT_FOUND;
    }
    ReadSize = FileInfo->FileSize;
    if (ReadSize > MAX_FILE_SIZE)
        ReadSize = MAX_FILE_SIZE;
    FreePool(FileInfo);

    BufferSize = (UINTN)ReadSize;   // was limited to 1 GB above, so this is safe
    Buffer = (UINT8 *) AllocatePool(BufferSize);
    if (Buffer == NULL) {
        refit_call1_wrapper(FileHandle->Close, FileHandle);
        return EFI_OUT_OF_RESOURCES;
    }

    Status = refit_call3_wrapper(FileHandle->Read, FileHandle, &BufferSize, Buffer);
    refit_call1_wrapper(FileHandle->Close, FileHandle);
    if (EFI_ERROR(Status)) {
        FreePool(Buffer);
        return Status;
    }

    *FileData = Buffer;
    *FileDataLength = BufferSize;
    return EFI_SUCCESS;
}
示例#4
0
static int scan_disks(int (*hook)(struct fsw_volume *, struct fsw_volume *), struct fsw_volume *master)
{
    EFI_STATUS  Status;
    EFI_HANDLE *Handles;
    UINTN       HandleCount = 0;
    UINTN       i;
    UINTN       scanned = 0;

    // Driver hangs if compiled with GNU-EFI unless there's a Print() statement somewhere.
    // I'm still trying to track that down; in the meantime, work around it....
#if defined(__MAKEWITH_GNUEFI)
    Print(L" ");
#endif
    DPRINT(L"Scanning disks\n");
    Status = refit_call5_wrapper(BS->LocateHandleBuffer, ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &HandleCount, &Handles);
    if (Status == EFI_NOT_FOUND)
        return -1;  // no filesystems. strange, but true...
    for (i = 0; i < HandleCount; i++) {
        EFI_DISK_IO *diskio;
        EFI_BLOCK_IO *blockio;
        Status = refit_call3_wrapper(BS->HandleProtocol, Handles[i], &gEfiDiskIoProtocolGuid, (VOID **) &diskio);
        if (Status != 0)
            continue;
        Status = refit_call3_wrapper(BS->HandleProtocol, Handles[i], &gEfiBlockIoProtocolGuid, (VOID **) &blockio);
        if (Status != 0)
            continue;
        struct fsw_volume *vol = create_dummy_volume(diskio, blockio->Media->MediaId);
        if(vol) {
            DPRINT(L"Checking disk %d\n", i);
            if(hook(master, vol) == FSW_SUCCESS)
                scanned++;
            free_dummy_volume(vol);
        }
    }
    return scanned;
}
示例#5
0
/**
    Internal helper function.

    Update the BBS Table so that devices of DeviceType have their boot priority
    updated to a high/bootable value.

    See "DeviceType values" in 
    http://www.intel.com/content/dam/doc/reference-guide/efi-compatibility-support-module-specification-v097.pdf

    NOTE: This function should probably be refactored! Currently, all devices of
    type are enabled. This should be updated so that only a specific device is
    enabled. The wrong device could boot if there are multiple targets of the same
    type.

    @param DeviceType   The device type that we wish to enable
**/
VOID UpdateBbsTable (BDS_COMMON_OPTION *Option) {
   UINT16  Idx;
   EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
   EFI_STATUS                Status;
   UINT16                       HddCount = 0;
   HDD_INFO                     *HddInfo = NULL; 
   UINT16                       BbsCount = 0; 
   BBS_TABLE                 *LocalBbsTable = NULL;
   BBS_BBS_DEVICE_PATH       *OptionBBS;
   CHAR16                    Desc[100];

   Status = refit_call3_wrapper(gBS->LocateProtocol, &gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios);
   if (EFI_ERROR (Status) || (Option == NULL)) {
      return;
   }

   OptionBBS = (BBS_BBS_DEVICE_PATH *) Option->DevicePath;
   Status = refit_call5_wrapper(LegacyBios->GetBbsInfo, LegacyBios, &HddCount, &HddInfo, &BbsCount, &LocalBbsTable);

//    Print (L"\n");
//    Print (L" NO  Prio bb/dd/ff cl/sc Type Stat segm:offs\n");
//    Print (L"=============================================\n");

   for (Idx = 0; Idx < BbsCount; Idx++) {
      if(LocalBbsTable[Idx].DeviceType == 0) {
         continue;
      }

      BdsBuildLegacyDevNameString (&LocalBbsTable[Idx], Idx, sizeof (Desc), Desc);

      // Set devices of a particular type to BootPriority of 0 or 1. 0 is the highest priority.
      if (LocalBbsTable[Idx].DeviceType == OptionBBS->DeviceType) {
         if (StriCmp(Desc, Option->Description) == 0) {
            // This entry exactly matches what we're looking for; make it highest priority
            LocalBbsTable[Idx].BootPriority = 0;
         } else {
            // This entry doesn't exactly match, but is the right disk type; make it a bit lower
            // in priority. Done mainly as a fallback in case of string-matching weirdness.
            LocalBbsTable[Idx].BootPriority = 1;
         } // if/else
      } else if (LocalBbsTable[Idx].BootPriority <= 1) {
         // Something's got a high enough boot priority to interfere with booting
         // our chosen entry, so bump it down a bit....
         LocalBbsTable[Idx].BootPriority = 2;
      } // if/else if

//          Print (
//            L" %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n",
//            (UINTN) Idx,
//            (UINTN) LocalBbsTable[Idx].BootPriority,
//            (UINTN) LocalBbsTable[Idx].Bus,
//            (UINTN) LocalBbsTable[Idx].Device,
//            (UINTN) LocalBbsTable[Idx].Function,
//            (UINTN) LocalBbsTable[Idx].Class,
//            (UINTN) LocalBbsTable[Idx].SubClass,
//            (UINTN) LocalBbsTable[Idx].DeviceType,
//            (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,
//            (UINTN) LocalBbsTable[Idx].BootHandlerSegment,
//            (UINTN) LocalBbsTable[Idx].BootHandlerOffset,
//            (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),
//            (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset)
//            );
//          Print(L"%s\n", Desc);

   } // for
//    PauseForKey();
}
示例#6
0
文件: fsw_efi.c 项目: ohnx/rEFInd
fsw_status_t fsw_efi_read_block(struct fsw_volume *vol, fsw_u64 phys_bno, void *buffer) {
   int              i, ReadCache = -1;
   FSW_VOLUME_DATA  *Volume = (FSW_VOLUME_DATA *)vol->host_data;
   EFI_STATUS       Status = EFI_SUCCESS;
   BOOLEAN          ReadOneBlock = FALSE;
   fsw_u64          StartRead = phys_bno * vol->phys_blocksize;

   if (buffer == NULL)
      return (fsw_status_t) EFI_BAD_BUFFER_SIZE;

   // Initialize static data structures, if necessary....
   if (LastRead < 0) {
      fsw_efi_clear_cache();
   } // if

   // Look for a cache hit on the current query....
   i = 0;
   do {
      if ((Caches[i].Volume == Volume) &&
	  (Caches[i].CacheValid == TRUE) &&
          (StartRead >= Caches[i].CacheStart) &&
          ((StartRead + vol->phys_blocksize) <= (Caches[i].CacheStart + CACHE_SIZE))) {
         ReadCache = i;
      }
      i++;
   } while ((i < NUM_CACHES) && (ReadCache < 0));

   // No cache hit found; load new cache and pass it on....
   if (ReadCache < 0) {
      if (LastRead == -1)
         LastRead = 1;
      ReadCache = 1 - LastRead; // NOTE: If NUM_CACHES > 2, this must become more complex
      Caches[ReadCache].CacheValid = FALSE;
      if (Caches[ReadCache].Cache == NULL)
         Caches[ReadCache].Cache = AllocatePool(CACHE_SIZE);
      if (Caches[ReadCache].Cache != NULL) {
         Status = refit_call5_wrapper(Volume->DiskIo->ReadDisk, Volume->DiskIo, Volume->MediaId,
                                      StartRead, CACHE_SIZE, Caches[ReadCache].Cache);
         if (!EFI_ERROR(Status)) {
            Caches[ReadCache].CacheStart = StartRead;
            Caches[ReadCache].CacheValid = TRUE;
            Caches[ReadCache].Volume = Volume;
            LastRead = ReadCache;
         } else {
            ReadOneBlock = TRUE;
         }
      } else {
         ReadOneBlock = TRUE;
      } // if cache memory allocated
   } // if (ReadCache < 0)

   if (Caches[ReadCache].Cache != NULL && Caches[ReadCache].CacheValid == TRUE && vol->phys_blocksize > 0) {
      CopyMem(buffer, &Caches[ReadCache].Cache[StartRead - Caches[ReadCache].CacheStart], vol->phys_blocksize);
   } else {
      ReadOneBlock = TRUE;
   }

   if (ReadOneBlock) { // Something's failed, so try a simple disk read of one block....
      Status = refit_call5_wrapper(Volume->DiskIo->ReadDisk, Volume->DiskIo, Volume->MediaId,
                                   phys_bno * vol->phys_blocksize,
                                   vol->phys_blocksize,
                                   buffer);
   }
   Volume->LastIOStatus = Status;

   return Status;
} // fsw_status_t *fsw_efi_read_block()