220 lines
4.4 KiB
C++
220 lines
4.4 KiB
C++
|
//++
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
//
|
||
|
// blflash.cpp
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// This module implements flash support for the boot loader.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
#include "bl.h"
|
||
|
|
||
|
struct FLASH_HEADER
|
||
|
{
|
||
|
UINT8 Label[18];
|
||
|
UINT8 HeadSize;
|
||
|
UINT8 SpecSize;
|
||
|
UINT32 PageSize;
|
||
|
UINT32 MajorVersion;
|
||
|
UINT32 MinorVersion;
|
||
|
};
|
||
|
|
||
|
struct FLASH_FILE
|
||
|
{
|
||
|
UINT32 PathOffset;
|
||
|
UINT32 DataOffset;
|
||
|
UINT32 Size;
|
||
|
};
|
||
|
|
||
|
static PUINT8 BlFlashBase = NULL;
|
||
|
static FLASH_FILE * BlFlashImages = NULL;
|
||
|
|
||
|
FLASH_FILE *
|
||
|
BlFlashRecordIsValid(
|
||
|
FLASH_FILE *Current
|
||
|
)
|
||
|
|
||
|
//++
|
||
|
//
|
||
|
// Routine Description:
|
||
|
//
|
||
|
// Find the next valid flash file record.
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// Pointer to the next valid flash file record, if the query operation was successful.
|
||
|
// NULL, if there are no remaining valid record.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
{
|
||
|
for (;; Current++) {
|
||
|
if ((Current->DataOffset == 0xffffffff && Current->Size == 0xffffffff) ||
|
||
|
(Current->DataOffset == 0 && Current->Size == 0)) {
|
||
|
continue;
|
||
|
}
|
||
|
else if (Current->DataOffset == 0xffffffff && Current->Size == 0) {
|
||
|
return NULL;
|
||
|
}
|
||
|
return Current;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FLASH_FILE *
|
||
|
BlFlashFindFile(
|
||
|
PCSTR Path
|
||
|
)
|
||
|
|
||
|
//++
|
||
|
//
|
||
|
// Routine Description:
|
||
|
//
|
||
|
// Find the flash file record matching this path name.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Path - Supplies the path to the file to query.
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// Pointer to the flash file record, if the query operation was successful.
|
||
|
// NULL, otherwise.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
{
|
||
|
for (FLASH_FILE *File = BlFlashImages; File != NULL; File = BlFlashRecordIsValid(File + 1)) {
|
||
|
if (BlRtlEqualStringI(Path, (PCSTR)(BlFlashBase + File->PathOffset))) {
|
||
|
return File;
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOLEAN
|
||
|
BlFlashGetFileSize(
|
||
|
PCSTR Path,
|
||
|
PUINT32 FileSize
|
||
|
)
|
||
|
|
||
|
//++
|
||
|
//
|
||
|
// Routine Description:
|
||
|
//
|
||
|
// This function queries the size of the specified file.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Path - Supplies the path to the file to query.
|
||
|
//
|
||
|
// FileSize - Receives the size of the file.
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// TRUE, if the query operation was successful.
|
||
|
// FALSE, otherwise.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
{
|
||
|
FLASH_FILE * File = BlFlashFindFile(Path);
|
||
|
|
||
|
if (File != NULL) {
|
||
|
|
||
|
*FileSize = File->Size;
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//++
|
||
|
//
|
||
|
// Routine Description:
|
||
|
//
|
||
|
// This function reads from the specified file.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// Path - Supplies the path to the file to read.
|
||
|
//
|
||
|
// Buffer - Receives data.
|
||
|
//
|
||
|
// NumberOfBytes - Supplies the number of bytes to read.
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// TRUE, if the read operation was successful.
|
||
|
// FALSE, otherwise.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
BOOLEAN
|
||
|
BlFlashReadFile(
|
||
|
PCSTR Path,
|
||
|
PVOID Buffer,
|
||
|
UINT32 NumberOfBytes
|
||
|
)
|
||
|
{
|
||
|
(void)Path;
|
||
|
(void)NumberOfBytes;
|
||
|
(void)Buffer;
|
||
|
|
||
|
FLASH_FILE * File = BlFlashFindFile(Path);
|
||
|
|
||
|
if (File != NULL) {
|
||
|
|
||
|
BlRtlCopyMemory(Buffer, BlFlashBase + File->DataOffset, NumberOfBytes);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
BlFlashInitialize(
|
||
|
PVOID SearchBegin,
|
||
|
PVOID SearchLimit
|
||
|
)
|
||
|
{
|
||
|
// walk through at 64KB boundaries looking for flash image.
|
||
|
for (FLASH_HEADER * Search = (FLASH_HEADER *)SearchBegin;
|
||
|
Search <= (FLASH_HEADER *)SearchLimit;
|
||
|
Search = (FLASH_HEADER *)(((PUINT8)Search) + 0x10000)) {
|
||
|
|
||
|
if (!BlRtlEqualStringI((PCSTR)Search->Label, "SingularityFlash!")) {
|
||
|
continue;
|
||
|
}
|
||
|
if (Search->HeadSize != sizeof(FLASH_HEADER)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (Search->SpecSize != sizeof(FLASH_FILE)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (Search->MajorVersion != ~0u || Search->MinorVersion != ~0u) {
|
||
|
BlRtlPrintf("--- Version %x.%x didn't match\n",
|
||
|
Search->MajorVersion, Search->MinorVersion);
|
||
|
continue;
|
||
|
}
|
||
|
if (Search->PageSize != 0x1000) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
BlFlashBase = (PUINT8)Search;
|
||
|
BlFlashImages = BlFlashRecordIsValid((FLASH_FILE *)(Search + 1));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
BlFsGetFileSize = BlFlashGetFileSize;
|
||
|
BlFsReadFile = BlFlashReadFile;
|
||
|
}
|