efildr.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,225 行 · 第 1/4 页
C
2,225 行
if (p < Image->ImageBase || p > Image->ImageEof) {
// DEBUG((D_LOAD|D_ERROR, "ImageAddress: pointer is outside of image\n"));
p = NULL;
}
// DEBUG((D_LOAD, "ImageAddress: ImageBase %x, ImageEof %x, Address %x, p %x\n",
// Image->ImageBase, Image->ImageEof,
// Address, p));
return p;
}
INTERNAL
EFI_STATUS
Bios32SetImageType (
IN OUT EFILDR_LOADED_IMAGE *Image,
IN UINTN ImageType
)
{
EFI_MEMORY_TYPE CodeType, DataType;
switch (ImageType) {
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
CodeType = EfiLoaderCode;
DataType = EfiLoaderData;
break;
case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
CodeType = EfiBootServicesCode;
DataType = EfiBootServicesData;
break;
case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
CodeType = EfiRuntimeServicesCode;
DataType = EfiRuntimeServicesData;
break;
default:
return EFI_INVALID_PARAMETER;
}
Image->Type = ImageType;
Image->Info.ImageCodeType = CodeType;
Image->Info.ImageDataType = DataType;
return EFI_SUCCESS;
}
INTERNAL
EFI_STATUS
Bios32CheckImageMachineType (
IN UINTN MachineType
)
// Determine if machine type is supported by the local machine
{
EFI_STATUS Status;
Status = EFI_UNSUPPORTED;
#if EFI32
if (MachineType == EFI_IMAGE_MACHINE_IA32) {
Status = EFI_SUCCESS;
}
#endif
#if EFI64
if (MachineType == EFI_IMAGE_MACHINE_IA64) {
Status = EFI_SUCCESS;
}
#endif
#if EFI_FCODE
if (MachineType == EFI_IMAGE_MACHINE_FCODE) {
Status = EFI_SUCCESS;
}
#endif
return Status;
}
EFI_STATUS
EfiAddMemoryDescriptor(
UINTN *NoDesc,
EFI_MEMORY_DESCRIPTOR *Desc,
EFI_MEMORY_TYPE Type,
EFI_PHYSICAL_ADDRESS BaseAddress,
UINTN NoPages,
UINT64 Attribute
)
{
UINTN i;
UINTN Temp;
UINTN Index;
if (NoPages == 0) {
return EFI_SUCCESS;
}
//
// See if the new memory descriptor needs to be carved out of an existing memory descriptor
//
Index = *NoDesc;
for(i=0;i<Index;i++) {
if (Desc[i].Type == EfiConventionalMemory) {
Temp = ((UINT32)(BaseAddress - Desc[i].PhysicalStart) / EFI_PAGE_SIZE) + NoPages;
if (Desc[i].PhysicalStart < BaseAddress && Desc[i].NumberOfPages >= Temp) {
if (Desc[i].NumberOfPages > Temp) {
Desc[*NoDesc].Type = EfiConventionalMemory;
Desc[*NoDesc].PhysicalStart = BaseAddress + (NoPages * EFI_PAGE_SIZE);
Desc[*NoDesc].NumberOfPages = Desc[i].NumberOfPages - Temp;
Desc[*NoDesc].VirtualStart = 0;
Desc[*NoDesc].Attribute = Desc[i].Attribute;
*NoDesc = *NoDesc + 1;
}
Desc[i].NumberOfPages = Temp - NoPages;
}
if (Desc[i].PhysicalStart == BaseAddress && Desc[i].NumberOfPages==NoPages) {
Desc[i].Type = Type;
Desc[i].Attribute = Attribute;
return EFI_SUCCESS;
}
if (Desc[i].PhysicalStart == BaseAddress && Desc[i].NumberOfPages>NoPages) {
Desc[i].NumberOfPages -= NoPages;
Desc[i].PhysicalStart += NoPages * EFI_PAGE_SIZE;
}
}
}
//
// Add the new memory descriptor
//
Desc[*NoDesc].Type = Type;
Desc[*NoDesc].PhysicalStart = BaseAddress;
Desc[*NoDesc].NumberOfPages = NoPages;
Desc[*NoDesc].VirtualStart = 0;
Desc[*NoDesc].Attribute = Attribute;
*NoDesc = *NoDesc + 1;
return(EFI_SUCCESS);
}
UINTN
FindSpace(
UINTN NoPages,
IN UINT32 *NumberOfMemoryMapEntries,
IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
)
{
EFI_PHYSICAL_ADDRESS MaxPhysicalStart;
UINT64 MaxNoPages;
UINTN Index;
MaxPhysicalStart = 0;
for (Index = 0;Index < *NumberOfMemoryMapEntries; Index++) {
if (EfiMemoryDescriptor[Index].Type == EfiConventionalMemory &&
EfiMemoryDescriptor[Index].NumberOfPages >= NoPages) {
if (EfiMemoryDescriptor[Index].PhysicalStart > MaxPhysicalStart) {
if (EfiMemoryDescriptor[Index].PhysicalStart + EFILDRLShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000000) {
MaxPhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
MaxNoPages = EfiMemoryDescriptor[Index].NumberOfPages;
}
else if (EfiMemoryDescriptor[Index].PhysicalStart + (NoPages << EFI_PAGE_SHIFT) <= 0x100000000) {
MaxPhysicalStart = 0x100000000 - (NoPages << EFI_PAGE_SHIFT);
MaxNoPages = NoPages;
}
}
}
}
if (!MaxPhysicalStart)
return 0;
return (UINTN)(MaxPhysicalStart + EFILDRLShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT));
}
UINT64
EFILDRLShiftU64 (
IN UINT64 Operand,
IN UINTN Count
)
// Left shift 64bit by 32bit and get a 64bit result
{
UINT64 Result;
_asm {
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
mov ecx, Count
and ecx, 63
shld edx, eax, cl
shl eax, cl
cmp ecx, 32
jc short ls10
mov edx, eax
xor eax, eax
ls10:
mov dword ptr Result[0], eax
mov dword ptr Result[4], edx
}
return Result;
}
VOID
EFILDRZeroMem (
IN VOID *Buffer,
IN UINTN Size
)
{
UINT8 *pt;
pt = Buffer;
while (Size--) {
*(pt++) = 0;
}
}
VOID
EFILDRCopyMem (
IN VOID *Dest,
IN VOID *Src,
IN UINTN len
)
{
CHAR8 *d, *s;
d = Dest;
s = Src;
while (len--) {
*(d++) = *(s++);
}
}
UINTN
EFILDRstrcmpa (
IN CHAR8 *s1,
IN CHAR8 *s2
)
// compare strings
{
while (*s1) {
if (*s1 != *s2) {
break;
}
s1 += 1;
s2 += 1;
}
return *s1 - *s2;
}
VOID ClearScreen()
{
UINT32 i;
Cursor = (UINT8 *)(0x000b8000 + 160);
for(i=0;i<80*49;i++) {
*Cursor = ' ';
Cursor += 2;
}
Cursor = (UINT8 *)(0x000b8000 + 160);
}
VOID PrintValue(UINT32 Value)
{
UINT32 i;
UINT8 ch;
for(i=0;i<8;i++) {
ch = (UINT8)((Value >> ((7-i)*4)) & 0x0f) + '0';
if (ch>'9') {
ch = ch - '0' -10 + 'A';
}
*Cursor = ch;
Cursor += 2;
}
}
VOID PrintString(UINT8 *String)
{
UINT32 i;
for(i=0;String[i]!=0;i++) {
if (String[i] == '\n') {
Cursor = (UINT8 *)(0xb8000 + (((((UINT32)Cursor-0xb8000) + 160) / 160) * 160));
} else {
*Cursor = String[i];
Cursor += 2;
}
}
}
//
// EFI Decompression Algorithm code
//
VOID
Bios32FillBuf (
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfBits
)
/*++
Routine Description:
Shift mBitBuf NumOfBits left. Read in NumOfBits of bits from source.
Arguments:
Sd - The global scratch data
NumOfBit - The number of bits to shift and read.
Returns: (VOID)
--*/
{
Sd->mBitBuf = (UINT16)(Sd->mBitBuf << NumOfBits);
while (NumOfBits > Sd->mBitCount) {
Sd->mBitBuf |= (UINT16)(Sd->mSubBitBuf <<
(NumOfBits = (UINT16)(NumOfBits - Sd->mBitCount)));
if (Sd->mCompSize > 0) {
//
// Get 1 byte into SubBitBuf
//
Sd->mCompSize --;
Sd->mSubBitBuf = 0;
Sd->mSubBitBuf = Sd->mSrcBase[Sd->mInBuf ++];
Sd->mBitCount = 8;
} else {
Sd->mSubBitBuf = 0;
Sd->mBitCount = 8;
}
}
Sd->mBitCount = (UINT16)(Sd->mBitCount - NumOfBits);
Sd->mBitBuf |= Sd->mSubBitBuf >> Sd->mBitCount;
}
UINT16
Bios32GetBits(
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfBits
)
/*++
Routine Description:
Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
NumOfBits of bits from source. Returns NumOfBits of bits that are
popped out.
Arguments:
Sd - The global scratch data.
NumOfBits - The number of bits to pop and read.
Returns:
The bits that are popped out.
--*/
{
UINT16 OutBits;
OutBits = (UINT16)(Sd->mBitBuf >> (BITBUFSIZ - NumOfBits));
Bios32FillBuf (Sd, NumOfBits);
return OutBits;
}
UINT16
Bios32MakeTable (
IN SCRATCH_DATA *Sd,
IN UINT16 NumOfChar,
IN UINT8 *BitLen,
IN UINT16 TableBits,
OUT UINT16 *Table
)
/*++
Routine Description:
Creates Huffman Code mapping table according to code length array.
Arguments:
Sd - The global scratch data
NumOfChar - Number of symbols in the symbol set
BitLen - Code length array
TableBits - The width of the mapping table
Table - The table
Returns:
0 - OK.
BAD_TABLE - The table is corrupted.
--*/
{
UINT16 Count[17];
UINT16 Weight[17];
UINT16 Start[18];
UINT16 *p;
UINT16 k;
UINT16 i;
UINT16 Len;
UINT16 Char;
UINT16 JuBits;
UINT16 Avail;
UINT16 NextCode;
UINT16 Mask;
for (i = 1; i <= 16; i ++) {
Count[i] = 0;
}
for (i = 0; i < NumOfChar; i++) {
Count[BitLen[i]]++;
}
Start[1] = 0;
for (i = 1; i <= 16; i ++) {
Start[i + 1] = (UINT16)(Start[i] + (Count[i] << (16 - i)));
}
if (Start[17] != 0) {/*(1U << 16)*/
return (UINT16)BAD_TABLE;
}
JuBits = (UINT16)(16 - TableBits);
for (i = 1; i <= TableBits; i ++) {
Start[i] >>= JuBits;
Weight[i] = (UINT16)(1U << (TableBits - i));
}
while (i <= 16) {
Weight[i++] = (UINT16)(1U << (16 - i));
}
i = (UINT16)(Start[TableBits + 1] >> JuBits);
if (i != 0) {
k = (UINT16)(1U << TableBits);
while (i != k) {
Table[i++] = 0;
}
}
Avail = NumOfChar;
Mask = (UINT16)(1U << (15 - TableBits));
for (Char = 0; Char < NumOfChar; Char++) {
Len = BitLen[Char];
if (Len == 0) {
continue;
}
NextCode = (UINT16)(Start[Len] + Weight[Len]);
if (Len <= TableBits) {
for (i = Start[Len]; i < NextCode; i ++) {
Table[i] = Char;
}
} else {
k = Start[Len];
p = &Table[k >> JuBits];
i = (UINT16)(Len - TableBits);
while (i != 0) {
if (*p == 0) {
Sd->mRight[Avail] = Sd->mLeft[Avail] = 0;
*p = Avail ++;
}
if (k & Mask) {
p = &Sd->mRight[*p];
} else {
p = &Sd->mLeft[*p];
}
k <<= 1;
i --;
}
*p = Char;
}
Start[Len] = NextCode;
}
//
// Succeeds
//
return 0;
}
UINT16
Bios32DecodeP (
IN SCRATCH_DATA *Sd
)
/*++
Routine description:
Decodes a position value.
Arguments:
Sd - the global scratch data
Returns:
The position value decoded.
--*/
{
UINT16 Val;
UINT16 Mask;
Val = Sd->mPTTable[Sd->mBitBuf >> (BITBUFSIZ - 8)];
if (Val >= NP) {
Mask = 1U << (BITBUFSIZ - 1 - 8);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?