singrdk/base/boot/SingLdrPc/blflash.cpp

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