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 + -
显示快捷键?