Newer
Older
AMI-Aptio-BIOS-Reversed / NvramPei / NvramPei.c
@Ajax Dong Ajax Dong 2 days ago 80 KB Init
#include "NvramPei.h"

//
// NvramPei - UEFI Module
// Total functions: 92
//

// Function: InternalMemCopyMem @ 0xffe4d6f4 (0x3f bytes)

char *__cdecl InternalMemCopyMem(char *dst, char *src, unsigned int count)
{
  unsigned int count_1; // edx
  char *dst_1; // edi
  char *src_1; // esi

  count_1 = count; /*0xffe4d6fe*/
  if ( src < dst && &src[count - 1] >= dst ) /*0xffe4d70c*/
  {
    src_1 = &src[count - 1]; /*0xffe4d720*/
    dst_1 = &dst[count - 1]; /*0xffe4d722*/
  }
  else
  {
    count_1 = count & 3; /*0xffe4d710*/
    qmemcpy(dst, src, 4 * (count >> 2)); /*0xffe4d719*/
    src_1 = &src[4 * (count >> 2)]; /*0xffe4d719*/
    dst_1 = &dst[4 * (count >> 2)]; /*0xffe4d719*/
  }
  qmemcpy(dst_1, src_1, count_1); /*0xffe4d729*/
  return dst; /*0xffe4d730*/
}


// Function: InternalMemSetMem @ 0xffe4d734 (0x15 bytes)

void *__cdecl InternalMemSetMem(void *buf, unsigned int count, char value)
{
  memset(buf, value, count); /*0xffe4d741*/
  return buf; /*0xffe4d747*/
}


// Function: InternalMemSetMem32_Safe @ 0xffe4d754 (0x1f bytes)

int __cdecl InternalMemSetMem32_Safe(int Buffer, int Count, int ValueLo, int ValueHi)
{
  do /*0xffe4d76d*/
  {
    *(_DWORD *)(Buffer + 8 * Count - 8) = ValueLo; /*0xffe4d765*/
    *(_DWORD *)(Buffer + 8 * Count-- - 4) = ValueHi; /*0xffe4d769*/
  }
  while ( Count ); /*0xffe4d76d*/
  return Buffer; /*0xffe4d771*/
}


// Function: InternalMemSetMem32 @ 0xffe4d774 (0x15 bytes)

void *__cdecl InternalMemSetMem32(void *buf, unsigned int count, int value)
{
  memset32(buf, value, count); /*0xffe4d781*/
  return buf; /*0xffe4d787*/
}


// Function: _ModuleEntryPoint @ 0xffe4d794 (0x65 bytes)

EFI_STATUS ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
  int v2; // esi
  int v3; // eax

  v2 = (*(int (__cdecl **)(EFI_SYSTEM_TABLE *, void *))(LODWORD(SystemTable->Hdr.Signature) + 24))( /*0xffe4d7a5*/
         SystemTable,
         &unk_FFE51388);
  PeiDebugPrint(64, "PeiGetVariableAddressPpi Status %r\n", v2); /*0xffe4d7af*/
  if ( v2 < 0 ) /*0xffe4d7b9*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v2); /*0xffe4d7c6*/
    v3 = PeiGetDebugService(); /*0xffe4d7ce*/
    if ( v3 ) /*0xffe4d7d5*/
      (*(void (__cdecl **)(const char *, int, const char *))(v3 + 4))( /*0xffe4d7e6*/
        "e:\\hs\\Build\\HR6N0XMLK\\DEBUG_VS2015\\IA32\\AmiModulePkg\\NVRAM\\NvramPei\\DEBUG\\AutoGen.c",
        249,
        "!EFI_ERROR (Status)");
  }
  return DriverEntryPoint((int)ImageHandle, (int *)SystemTable); /*0xffe4d7f2*/
}


// Function: NvramInitHardware @ 0xffe4d7f9 (0xec bytes)

int __thiscall NvramInitHardware(void *this)
{
  int v2; // [esp+Ch] [ebp-4h] BYREF

  v2 = 0; /*0xffe4d7fd*/
  AssertCpuDeadLoop_2(this); /*0xffe4d805*/
  AssertCpuDeadLoop_3(); /*0xffe4d80a*/
  MEMORY[0xFDAE04C8] = MEMORY[0xFDAE04C8] & 0x3F61E0FE | 0x40000101; /*0xffe4d830*/
  PeiDebugPrint(0x80000000, "Set Read Value =%x \n", -38927160); /*0xffe4d835*/
  PeiDebugPrint(0x80000000, "Set Dw0RegMask Value =%x \n", -1063379199); /*0xffe4d848*/
  PeiDebugPrint(0x80000000, "Set Dw0Reg Value =%x \n", 1073742081); /*0xffe4d857*/
  MEMORY[0xFDAE04CC] &= 0xFFFFC3FF; /*0xffe4d86e*/
  PeiDebugPrint(0x80000000, "Set Read Value =%x \n", -38927156); /*0xffe4d873*/
  PeiDebugPrint(0x80000000, "Set Dw1RegMask Value =%x \n", 15360); /*0xffe4d886*/
  PeiDebugPrint(0x80000000, "Set Dw1Reg Value =%x \n", 0); /*0xffe4d896*/
  GpioReadRegister(0x4C8u, &v2); /*0xffe4d8a7*/
  PeiDebugPrint(0x80000000, "Return Value1 =%x \n", v2); /*0xffe4d8b6*/
  GpioReadRegister(0x4CCu, &v2); /*0xffe4d8c7*/
  return PeiDebugPrint(0x80000000, "Return Value2 =%x \n", v2); /*0xffe4d8de*/
}


// Function: NvramPollGppD1 @ 0xffe4d8e5 (0x63 bytes)

char __usercall NvramPollGppD1@<al>(void *NvramBase@<ecx>, int (**ContinueFunc)()@<esi>)
{
  int v3; // eax

  NvramInitHardware(NvramBase); /*0xffe4d8f4*/
  v3 = AssertCpuDeadLoop_1(); /*0xffe4d8fc*/
  PeiReportProgress(ContinueFunc, 0xFFFFFFFF, (int (**)(void))NvramBase, "GPP_D1 %x, status %r\n", 0, v3); /*0xffe4d90d*/
  return 1; /*0xffe4d941*/
}


// Function: PeiGetVariableCompat @ 0xffe4d948 (0x49 bytes)

int __cdecl PeiGetVariableCompat(
        int FileHandle,
        int VariableName,
        int Attributes,
        int DataSize,
        int Buffer,
        int VariableData)
{
  int result; // eax

  PeiDebugPrint(0x80000000, "Deprecated ReadOnlyVariable PPI is used. Use ReadOnlyVariable2 PPI instead\n"); /*0xffe4d955*/
  result = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)FileHandle + 32))( /*0xffe4d96d*/
             FileHandle,
             &unk_FFE512F0,
             0,
             0,
             &FileHandle);
  if ( result >= 0 ) /*0xffe4d975*/
    return (*(int (__cdecl **)(int, int, int, int, int, int))FileHandle)( /*0xffe4d98a*/
             FileHandle,
             VariableName,
             Attributes,
             DataSize,
             Buffer,
             VariableData);
  return result; /*0xffe4d98f*/
}


// Function: PeiGetVariableCompat2 @ 0xffe4d991 (0x44 bytes)

int __cdecl PeiGetVariableCompat2(
        int (**FileHandle)(_DWORD, _DWORD, _DWORD, _DWORD),
        int VariableName,
        int Attributes,
        int DataSize)
{
  int result; // eax

  PeiDebugPrint(0x80000000, "Deprecated ReadOnlyVariable PPI is used. Use ReadOnlyVariable2 PPI instead\n"); /*0xffe4d99e*/
  result = (*((int (__cdecl **)(int (**)(_DWORD, _DWORD, _DWORD, _DWORD), void *, _DWORD, _DWORD, int (***)(_DWORD, _DWORD, _DWORD, _DWORD)))*FileHandle /*0xffe4d9b6*/
            + 8))(
             FileHandle,
             &unk_FFE512F0,
             0,
             0,
             &FileHandle);
  if ( result >= 0 ) /*0xffe4d9be*/
    return FileHandle[1](FileHandle, VariableName, Attributes, DataSize); /*0xffe4d9cd*/
  return result; /*0xffe4d9d3*/
}


// Function: NvramFunctionDispatch @ 0xffe4d9d5 (0x66 bytes)

int __cdecl NvramFunctionDispatch(
        int Context,
        int VariableName,
        int Attributes,
        int DataSize,
        _DWORD *Data,
        int Status)
{
  int result; // eax
  int *v7; // esi

  result = -2147483645; /*0xffe4d9ea*/
  if ( !dword_FFE513D8 ) /*0xffe4d9ec*/
    return NvramGetVariableMultiStore(VariableName, Attributes, DataSize, Data, Status, *(_DWORD *)(Context + 8), Context + 16); /*0xffe4da18*/
  v7 = &dword_FFE513D8; /*0xffe4d9ee*/
  while ( result == -2147483645 ) /*0xffe4d9f5*/
  {
    result = ((int (__cdecl *)(int, int, int, int, _DWORD *, int))*v7++)( /*0xffe4da07*/
               Context,
               VariableName,
               Attributes,
               DataSize,
               Data,
               Status);
    if ( !*v7 ) /*0xffe4da0f*/
    {
      if ( result != -2147483645 ) /*0xffe4da16*/
        return result; /*0xffe4da16*/
      return NvramGetVariableMultiStore(VariableName, Attributes, DataSize, Data, Status, *(_DWORD *)(Context + 8), Context + 16); /*0xffe4da16*/
    }
  }
  return result; /*0xffe4da36*/
}


// Function: NvramVariableServiceDispatch @ 0xffe4da3b (0x5f bytes)

int __cdecl NvramVariableServiceDispatch(int a1, unsigned int *a2, unsigned __int8 *a3, int a4)
{
  int result; // eax
  int *v5; // esi

  result = -2147483645; /*0xffe4da50*/
  if ( !dword_FFE513D4 ) /*0xffe4da52*/
    return NvramGetNextVariableByIndex(a2, a3, a4, *(_DWORD *)(a1 + 8), a1 + 16, (unsigned int *)(a1 + 12)); /*0xffe4da78*/
  v5 = &dword_FFE513D4; /*0xffe4da54*/
  while ( result == -2147483645 ) /*0xffe4da5b*/
  {
    result = ((int (__cdecl *)(int, unsigned int *, unsigned __int8 *, int))*v5++)(a1, a2, a3, a4); /*0xffe4da67*/
    if ( !*v5 ) /*0xffe4da6f*/
    {
      if ( result != -2147483645 ) /*0xffe4da76*/
        return result; /*0xffe4da76*/
      return NvramGetNextVariableByIndex(a2, a3, a4, *(_DWORD *)(a1 + 8), a1 + 16, (unsigned int *)(a1 + 12)); /*0xffe4da76*/
    }
  }
  return result; /*0xffe4da95*/
}


// Function: NvramGetBaseAddresses @ 0xffe4da9a (0x7b bytes)

int __usercall NvramGetBaseAddresses@<eax>(_DWORD *src@<edx>, _DWORD *a2, _DWORD *a3)
{
  int v4; // eax
  int v5; // eax

  v4 = HobFindByGuid(&unk_FFE50F34); /*0xffe4daa4*/
  if ( v4 )
  {
    *src = *(_DWORD *)(v4 + 16); /*0xffe4dab5*/
    *a3 = *(_DWORD *)(v4 + 28); /*0xffe4dabe*/
  }
  else
  {
    PeiDebugPrint(0x80000000, "NVRAM PEI: NVRAM ROM area was not found!!! Using default address.\n");
    *src = -16777216; /*0xffe4dad2*/
    *a3 = 0x80000; /*0xffe4dad9*/
  }
  v5 = HobFindByGuid(&unk_FFE50E84); /*0xffe4dae4*/
  if ( v5 )
  {
    *a2 = *(_DWORD *)(v5 + 16); /*0xffe4daf4*/
  }
  else
  {
    PeiDebugPrint(0x80000000, "NVRAM PEI: NVRAM BACKUP ROM area was not found!!! Using default address.\n");
    *a2 = -16252928; /*0xffe4db09*/
  }
  return 0; /*0xffe4db0f*/
}


// Function: NvramFindDefaultsInFv @ 0xffe4db15 (0x97 bytes)

int __fastcall NvramFindDefaultsInFv(int *SystemTable, int *this)
{
  int v4; // edi
  int v5; // eax
  int result; // eax
  int v7; // eax
  int src[10]; // [esp+Ch] [ebp-34h] BYREF
  int v9; // [esp+34h] [ebp-Ch] BYREF
  int v10; // [esp+38h] [ebp-8h] BYREF
  int v11; // [esp+3Ch] [ebp-4h] BYREF

  v4 = 0; /*0xffe4db22*/
  while ( 1 ) /*0xffe4db24*/
  {
    v5 = *SystemTable; /*0xffe4db24*/
    v11 = 0; /*0xffe4db29*/
    result = (*(int (__cdecl **)(int *, int, int *))(v5 + 56))(SystemTable, v4++, &v11); /*0xffe4db30*/
    if ( result < 0 ) /*0xffe4db39*/
      break; /*0xffe4db39*/
    v7 = *SystemTable; /*0xffe4db3b*/
    v10 = 0; /*0xffe4db40*/
    if ( (*(int (__cdecl **)(void *, int, int *))(v7 + 104))(&unk_FFE50FBC, v11, &v10) >= 0 /*0xffe4db6b*/
      && (*(int (__cdecl **)(int *, int, int, int *))(*SystemTable + 64))(SystemTable, 25, v10, &v9) >= 0 )
    {
      src[0] = v9; /*0xffe4db72*/
      src[1] = (*(_DWORD *)(v9 - 4) & 0xFFFFFF) - 4; /*0xffe4db86*/
      NvramInitStore(src, 0, 7); /*0xffe4db89*/
      if ( NvramOpenDefaultsStore(L"StdDefaults", (int)src, this) ) /*0xffe4db97*/
        return 0; /*0xffe4dba3*/
    }
  }
  return result; /*0xffe4dba5*/
}


// Function: NvramInitDefaults @ 0xffe4dbac (0x3f bytes)

int *__thiscall NvramInitDefaults(int *this)
{
  int *SystemTable; // esi

  SystemTable = (int *)PeiGetServices(); /*0xffe4dbbd*/
  PeiDebugPrint(2, "NVRAM PEI: Built-in NVRAM Defaults are not found\n");
  if ( NvramFindDefaultsInFv(SystemTable, this) < 0 ) /*0xffe4dbd1*/
    return 0; /*0xffe4dbe5*/
  PeiDebugPrint(2, "NVRAM PEI: Using FV_BB NVRAM Defaults\n");
  return this; /*0xffe4dbe7*/
}


// Function: AssertCpuDeadLoop_0 @ 0xffe4dbeb (0x6a bytes)

int (__cdecl *(__cdecl **__thiscall sub_FFE4DBEB(void *this))(const char *, int, const char *))(int, int, int, int)
{
  int v1; // eax
  int (__cdecl *(__cdecl **result)(const char *, int, const char *))(int, int, int, int); // eax
  _DWORD *v3; // ecx
  int v4; // [esp+0h] [ebp-8h] BYREF
  _DWORD *v5; // [esp+4h] [ebp-4h] BYREF

  v1 = (*(int (__cdecl **)(void *, void *, _DWORD, int *, _DWORD **))(*(_DWORD *)this + 32))( /*0xffe4dc02*/
         this,
         &unk_FFE50E94,
         0,
         &v4,
         &v5);
  if ( v1 >= 0 ) /*0xffe4dc0a*/
  {
    v3 = v5; /*0xffe4dc3f*/
    *v5 = off_FFE50FD4; /*0xffe4dc47*/
    result = (int (__cdecl *(__cdecl **)(const char *, int, const char *))(int, int, int, int))off_FFE50FD8; /*0xffe4dc49*/
    v3[1] = off_FFE50FD8; /*0xffe4dc4e*/
  }
  else
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v1); /*0xffe4dc17*/
    result = (int (__cdecl *(__cdecl **)(const char *, int, const char *))(int, int, int, int))PeiGetDebugService(); /*0xffe4dc1f*/
    if ( result ) /*0xffe4dc26*/
      return (int (__cdecl *(__cdecl **)(const char *, int, const char *))(int, int, int, int))result[1]( /*0xffe4dc37*/
                                                                                                 "e:\\hs\\AmiModulePkg\\N"
                                                                                                 "VRAM\\NvramPei.c",
                                                                                                 597,
                                                                                                 "!EFI_ERROR (Status)");
  }
  return result; /*0xffe4dc51*/
}


// Function: DriverEntryPoint @ 0xffe4dc55 (0x38a bytes)

int __fastcall DriverEntryPoint(int ImageHandle, int *SystemTable)
{
  int v3; // eax
  int result; // eax
  _DWORD *v5; // edi
  _DWORD *v6; // edi
  int *src; // ebx
  int (__cdecl *v8)(int, unsigned int *, unsigned __int8 *, _BYTE *); // eax
  int (*v9)(void); // edi
  char *v10; // esi
  unsigned int v11; // eax
  int v12; // edi
  unsigned __int8 v13; // al
  char v14; // al
  int *v15; // esi
  int v16; // eax
  int *v17; // esi
  int *v18; // esi
  unsigned __int8 v19; // al
  unsigned __int8 v20; // al
  unsigned __int8 v21; // cl
  unsigned __int8 v22; // al
  int v23; // eax
  int (*v24)(void); // eax
  _DWORD *v25; // edi
  int v26; // ecx
  int v27; // eax
  const char *NVRAM_PEI:_Using_FV_BB_NVRAM_Defaults_n; // [esp-4h] [ebp-DCh]
  char v29; // [esp+12h] [ebp-C6h]
  char v30; // [esp+12h] [ebp-C6h]
  bool v31; // [esp+13h] [ebp-C5h] BYREF
  int v32; // [esp+14h] [ebp-C4h] BYREF
  char *v33; // [esp+18h] [ebp-C0h] BYREF
  int n2; // [esp+1Ch] [ebp-BCh]
  _DWORD *v35; // [e... [7827 chars total]


// Function: NvramGetVariableDataPtr @ 0xffe4dfdf (0x1a bytes)

int __fastcall NvramGetVariableDataPtr(int i, int ia)
{
  if ( (*(_DWORD *)(i + 6) & 0x4000000) != 0 ) /*0xffe4dfe6*/
    return i + 10; /*0xffe4dfe8*/
  else
    return *(_DWORD *)(ia + 8) - 16 * *(unsigned __int8 *)(i + 10); /*0xffe4dff6*/
}


// Function: NvramGetPrevStoreEnd @ 0xffe4dff9 (0x24 bytes)

_BYTE *__thiscall NvramGetPrevStoreEnd(_BYTE *this)
{
  _BYTE *v1; // esi

  v1 = this + (unsigned __int16)UnalignedRead16(this + 4) - 2; /*0xffe4e00a*/
  return &v1[-(unsigned __int16)UnalignedRead16(v1) + 2]; /*0xffe4e01b*/
}


// Function: NvramVerifyChecksum @ 0xffe4e01d (0x75 bytes)

char __thiscall NvramVerifyChecksum(_BYTE *this)
{
  char v2; // bl
  _BYTE *v3; // esi
  _BYTE *i; // ebp
  unsigned int v5; // eax

  v2 = 0; /*0xffe4e021*/
  if ( (*(_DWORD *)(this + 6) & 0x10000000) == 0 || (*NvramGetPrevStoreEnd(this) & 1) == 0 ) /*0xffe4e034*/
    return 0; /*0xffe4e08d*/
  v3 = this + 4; /*0xffe4e038*/
  for ( i = this + 10; i < this + (unsigned __int16)UnalignedRead16(this + 4); ++i ) /*0xffe4e052*/
    v2 += *i; /*0xffe4e054*/
  if ( (this + 6 < this + 4 ? 0xFFFFFFFE : 0) != 0xFFFFFFFE )
  {
    v5 = 0; /*0xffe4e078*/
    do
    {
      v2 += *v3++; /*0xffe4e07a*/
      ++v5; /*0xffe4e07d*/
    }
    while ( v5 < (this + 6 < this + 4 ? 0 : 2) );
  }
  return -(char)(v2 + *(this + 9)); /*0xffe4e08f*/
}


// Function: NvramGetVariablePayload @ 0xffe4e092 (0xb5 bytes)

// positive sp value has been detected, the output may be wrong!
_BYTE *__cdecl NvramGetVariablePayload(_DWORD *p_n16)
{
  _BYTE *v1; // ecx
  int v2; // ebp
  _BYTE *v3; // edi
  _BYTE *v4; // esi
  int n10; // esi
  unsigned __int16 v7; // ax
  int v8; // [esp+Ch] [ebp-8h]
  int v9; // [esp+10h] [ebp-4h]

  v2 = 0; /*0xffe4e096*/
  v3 = v1; /*0xffe4e09d*/
  v4 = 0; /*0xffe4e09f*/
  while ( NvramValidateStoreEntry(v1, v8) ) /*0xffe4e0d5*/
  {
    if ( (UnalignedRead32(v3 + 6) & 0xFFFFFF) == 0xFFFFFF ) /*0xffe4e0b5*/
      goto LABEL_6; /*0xffe4e0b5*/
    v4 = v3; /*0xffe4e0ba*/
    v3 += UnalignedRead32(v3 + 6) & 0xFFFFFF; /*0xffe4e0c6*/
    v1 = v3; /*0xffe4e0c8*/
  }
  v3 = v4; /*0xffe4e0d7*/
LABEL_6:
  if ( !v3 ) /*0xffe4e0db*/
    return 0; /*0xffe4e0dd*/
  n10 = 10; /*0xffe4e0ea*/
  if ( (*(_DWORD *)(v3 + 6) & 0x8000000) == 0 )
    n10 = v9 + ((*(_DWORD *)(v3 + 6) & 0x4000000) != 0 ? 26 : 11);
  if ( p_n16 ) /*0xffe4e10a*/
  {
    if ( (*(_DWORD *)(v3 + 6) & 0x10000000) != 0 ) /*0xffe4e113*/
    {
      v7 = UnalignedRead16(v3 + 4); /*0xffe4e118*/
      v2 = (unsigned __int16)UnalignedRead16(&v3[v7 - 2]); /*0xffe4e12a*/
    }
    *p_n16 = (unsigned __int16)UnalignedRead16(v3 + 4) - v2 - n10; /*0xffe4e13c*/
  }
  return &v3[n10]; /*0xffe4e141*/
}


// Function: NvramValidateStoreEntry @ 0xffe4e147 (0xbe bytes)

char __fastcall NvramValidateStoreEntry(_BYTE *this, int a2)
{
  int n0xA; // edi
  char v4; // bl
  unsigned int n0xA_1; // ebp
  int *v6; // edi

  n0xA = (unsigned __int16)UnalignedRead16(this + 4); /*0xffe4e15b*/
  v4 = 0; /*0xffe4e163*/
  if ( UnalignedRead32(this) == 1380013646 && *(this + 9) != 0xFF && (_WORD)n0xA != 0xFFFF && (unsigned int)n0xA > 0xA ) /*0xffe4e187*/
  {
    n0xA_1 = n0xA; /*0xffe4e18e*/
    if ( n0xA <= *(_DWORD *)(a2 + 12) - (int)this ) /*0xffe4e197*/
    {
      v6 = (int *)(this + 6); /*0xffe4e199*/
      if ( ((UnalignedRead32(this + 6) & 0xFFFFFF) == 0xFFFFFF /*0xffe4e1f1*/
         || (UnalignedRead32(this + 6) & 0xFFFFFFu) >= n0xA_1
         && (UnalignedRead32(this + 6) & 0xFFFFFFu) <= *(_DWORD *)(a2 + 12) - (int)this)
        && ((*v6 & 0x10000000) == 0 || (*NvramGetPrevStoreEnd(this) & 1) == 0 || *v6 >= 0 || !NvramVerifyChecksum(this)) )
      {
        return 1; /*0xffe4e1fc*/
      }
    }
  }
  return v4; /*0xffe4e1fe*/
}


// Function: NvramGetNextEntry @ 0xffe4e205 (0x87 bytes)

unsigned int __fastcall NvramGetNextEntry(unsigned int a1, int a2)
{
  unsigned __int16 n0xA; // ax

  while ( !a1 || a1 >= *(_DWORD *)(a2 + 12) ) /*0xffe4e212*/
  {
    a1 = 0; /*0xffe4e275*/
LABEL_15:
    if ( !a1 || *(char *)(a1 + 9) < 0 && (*(_DWORD *)(a1 + 6) & 0x8000000) == 0 ) /*0xffe4e288*/
      return a1; /*0xffe4e288*/
  }
  if ( !NvramValidateStoreEntry((_BYTE *)a1, a2) /*0xffe4e231*/
    || (a1 += (unsigned __int16)UnalignedRead16((void *)(a1 + 4)), a1 < *(_DWORD *)(a2 + 12)) )
  {
    while ( a1 < *(_DWORD *)(a2 + 12) ) /*0xffe4e271*/
    {
      if ( NvramValidateStoreEntry((_BYTE *)a1, a2) ) /*0xffe4e23e*/
        goto LABEL_15; /*0xffe4e245*/
      n0xA = UnalignedRead16((void *)(a1 + 4)); /*0xffe4e24a*/
      if ( n0xA == 0xFFFF || n0xA <= 0xAu || n0xA > (int)(*(_DWORD *)(a2 + 12) - a1) ) /*0xffe4e26a*/
        break; /*0xffe4e26a*/
      a1 += n0xA; /*0xffe4e26c*/
    }
  }
  return 0; /*0xffe4e235*/
}


// Function: NvramGetFirstEntry @ 0xffe4e28c (0x37 bytes)

unsigned int __thiscall NvramGetFirstEntry(unsigned int *this)
{
  unsigned int v2; // esi

  v2 = *(this + 4); /*0xffe4e292*/
  if ( !NvramValidateStoreEntry((_BYTE *)v2, (int)this) ) /*0xffe4e297*/
    return 0; /*0xffe4e2a0*/
  if ( *(char *)(v2 + 9) >= 0 || (*(_DWORD *)(v2 + 6) & 0x8000000) != 0 ) /*0xffe4e2b2*/
    return NvramGetNextEntry(v2, (int)this); /*0xffe4e2be*/
  return v2; /*0xffe4e2a2*/
}


// Function: NvramCompareVariableName @ 0xffe4e2c3 (0x11c bytes)

bool __fastcall NvramCompareVariableName(int i, int ia_1, int ia, int iaa)
{
  int v5; // edi
  int v6; // ebx
  _BYTE *Attributes; // esi
  _BYTE *v8; // eax
  _BYTE *v9; // edi
  _BYTE *v10; // ebx
  int v11; // esi
  int v12; // eax
  bool v13; // zf
  char v16; // [esp+14h] [ebp-4h]

  v5 = *(_DWORD *)(i + 6); /*0xffe4e2d3*/
  v6 = *(_DWORD *)(ia + 6); /*0xffe4e2db*/
  v16 = HIBYTE(v5) & 2; /*0xffe4e2e6*/
  if ( (HIBYTE(v5) & 2) != (HIBYTE(v6) & 2) ) /*0xffe4e2f2*/
    return 0; /*0xffe4e2f2*/
  if ( ((*(_BYTE *)(iaa + 28) ^ *(_BYTE *)(ia_1 + 28)) & 1) != 0 ) /*0xffe4e304*/
    return 0; /*0xffe4e304*/
  Attributes = (_BYTE *)NvramGetVariableDataPtr(ia, iaa); /*0xffe4e318*/
  v8 = (_BYTE *)NvramGetVariableDataPtr(i, ia_1); /*0xffe4e31a*/
  if ( CompareMem(v8, Attributes) ) /*0xffe4e323*/
    return 0; /*0xffe4e323*/
  v9 = (_BYTE *)(i + ((v5 & 0x4000000) != 0 ? 26 : 11));
  v10 = (_BYTE *)(ia + ((v6 & 0x4000000) != 0 ? 26 : 11));
  v11 = i - (_DWORD)v9 + (unsigned __int16)UnalignedRead16((void *)(i + 4)); /*0xffe4e361*/
  v12 = ia - (_DWORD)v10 + (unsigned __int16)UnalignedRead16((void *)(ia + 4)); /*0xffe4e374*/
  if ( v11 >= v12 ) /*0xffe4e378*/
    v11 = v12; /*0xffe4e37a*/
  if ( v16 ) /*0xffe4e381*/
  {
    while ( *v9 && *v9 == *v10 && v11 > 0 ) /*0xffe4e3af*/
    {
      ++v9; /*0xffe4e3b1*/
      ++v10; /*0xffe4e3b2*/
      --v11; /*0xffe4e3b3*/
    }
    v13 = *v9 == *v10; /*0xffe4e3bc*/
  }
  else
  {
    while ( (*v9 || v9[1]) && *v9 == *v10 && v9[1] == v10[1] && v11 > 0 ) /*0xffe4e39c*/
    {
      v9 += 2; /*0xffe4e39e*/
      v10 += 2; /*0xffe4e3a1*/
      v11 -= 2; /*0xffe4e3a4*/
    }
    if ( *v9 != *v10 ) /*0xffe4e3d1*/
      return 0; /*0xffe4e3d1*/
    v13 = v9[1] == v10[1]; /*0xffe4e3d6*/
  }
  return v13 && v11 > 0; /*0xffe4e3c2*/
}


// Function: NvramMatchVariableName @ 0xffe4e3df (0xeb bytes)

char __fastcall NvramMatchVariableName(
        int i,
        _WORD *j,
        _BYTE *Attributes,
        _DWORD *a4,
        int ia,
        int a6,
        int a7,
        int a8,
        int a9,
        int a10,
        _DWORD *a11,
        int iaa)
{
  _BYTE *v13; // ebx
  int v14; // ebp
  _WORD *k; // ecx
  _BYTE *v16; // ebx
  _BYTE *v19; // [esp+14h] [ebp-8h]
  _BYTE *v20; // [esp+18h] [ebp-4h]

  v19 = (_BYTE *)NvramGetVariableDataPtr(i, ia); /*0xffe4e3f8*/
  v13 = (_BYTE *)(i + ((*(_DWORD *)(i + 6) & 0x4000000) != 0 ? 26 : 11));
  v20 = v13; /*0xffe4e413*/
  v14 = i - (_DWORD)v13 + (unsigned __int16)UnalignedRead16((void *)(i + 4)); /*0xffe4e421*/
  if ( (*(_DWORD *)(i + 6) & 0x2000000) != 0 ) /*0xffe4e429*/
  {
    for ( k = j; *v13 && (unsigned __int8)*v13 == *k && v14 > 0; ++k ) /*0xffe4e42b*/
    {
      ++v13; /*0xffe4e441*/
      --v14; /*0xffe4e445*/
    }
    if ( (unsigned __int8)*v13 != *k || v14 <= 0 ) /*0xffe4e452*/
      return 0; /*0xffe4e452*/
    v16 = v13 + 1; /*0xffe4e454*/
  }
  else
  {
    if ( UnalignedRead16(v13) && UnalignedRead16(v13) == *j && v14 > 0 ) /*0xffe4e469*/
      JUMPOUT(0xFFE4E475); /*0xffe4e475*/
    if ( UnalignedRead16(v13) != *j || v14 <= 0 ) /*0xffe4e496*/
      return 0; /*0xffe4e496*/
    v16 = v13 + 2; /*0xffe4e498*/
  }
  if ( CompareMem(v19, Attributes) ) /*0xffe4e4a4*/
    return 0; /*0xffe4e4c9*/
  if ( a4 ) /*0xffe4e4b4*/
    *a4 = v16 - v20; /*0xffe4e4ba*/
  return 1; /*0xffe4e4c2*/
}


// Function: NvramFindVariable @ 0xffe4e4ca (0x44 bytes)

// positive sp value has been detected, the output may be wrong!
unsigned int __fastcall NvramFindVariable(_WORD *i, _BYTE *Attributes, _DWORD *a3, int ia)
{
  unsigned int i_1; // eax
  unsigned int i_2; // esi
  int v8; // [esp-28h] [ebp-34h]
  int v9; // [esp-24h] [ebp-30h]
  int v10; // [esp-20h] [ebp-2Ch]
  int v11; // [esp-1Ch] [ebp-28h]
  _DWORD *v12; // [esp-18h] [ebp-24h]
  unsigned int *ia_1; // [esp-14h] [ebp-20h]
  int ia_2; // [esp-10h] [ebp-1Ch]

  for ( i_1 = NvramGetFirstEntry(ia_1); ; i_1 = NvramGetNextEntry(i_2, ia) ) /*0xffe4e4d5*/
  {
    i_2 = i_1; /*0xffe4e500*/
    if ( !i_1 ) /*0xffe4e504*/
      break; /*0xffe4e504*/
    if ( NvramMatchVariableName(i_1, i, Attributes, v12, (int)ia_1, v8, v9, v10, v11, (int)v12, ia_1, ia_2) ) /*0xffe4e4e9*/
      return i_2; /*0xffe4e50a*/
  }
  return i_1; /*0xffe4e506*/
}


// Function: NvramGetVariableAttrSize @ 0xffe4e50e (0x65 bytes)

int __fastcall NvramGetVariableAttrSize(int a1, int i, _DWORD *DataSize)
{
  if ( !a1 || !i || !DataSize || (*(_DWORD *)(a1 + 6) & 0x8000000) != 0 ) /*0xffe4e526*/
    return -2147483646; /*0xffe4e56c*/
  *DataSize = 2; /*0xffe4e528*/
  if ( (*(_DWORD *)(a1 + 6) & 0x1000000) != 0 ) /*0xffe4e535*/
    *DataSize = 6; /*0xffe4e537*/
  if ( (*(_BYTE *)(i + 28) & 1) != 0 ) /*0xffe4e541*/
    *DataSize |= 1u; /*0xffe4e543*/
  if ( (*(_DWORD *)(a1 + 6) & 0x20000000) != 0 ) /*0xffe4e54d*/
    *DataSize |= 8u; /*0xffe4e54f*/
  if ( (*(_DWORD *)(a1 + 6) & 0x40000000) != 0 ) /*0xffe4e559*/
    *DataSize |= *NvramGetPrevStoreEnd((_BYTE *)a1) & 0x30; /*0xffe4e566*/
  return 0; /*0xffe4e56a*/
}


// Function: NvramReadVariableData @ 0xffe4e573 (0x6f bytes)

int __cdecl NvramReadVariableData(_DWORD *DataSize, unsigned int *Data, unsigned int Status, int i)
{
  _BYTE *v4; // ecx
  int v5; // esi
  char *src; // eax
  unsigned int p_n16_1; // ecx
  bool v8; // cf
  unsigned int p_n16; // [esp+8h] [ebp-4h] BYREF

  v5 = (int)v4; /*0xffe4e578*/
  if ( !v4 || !NvramValidateStoreEntry(v4, i) ) /*0xffe4e584*/
    return -2147483634; /*0xffe4e5d7*/
  if ( DataSize ) /*0xffe4e591*/
    NvramGetVariableAttrSize(v5, i, DataSize); /*0xffe4e59b*/
  src = NvramGetVariablePayload(&p_n16); /*0xffe4e5ac*/
  p_n16_1 = p_n16; /*0xffe4e5b6*/
  v8 = *Data < p_n16; /*0xffe4e5b9*/
  *Data = p_n16; /*0xffe4e5bb*/
  if ( v8 ) /*0xffe4e5bd*/
    return -2147483643; /*0xffe4e5bf*/
  NvramCopyMem(Status, src, p_n16_1); /*0xffe4e5cb*/
  return 0; /*0xffe4e5dc*/
}


// Function: NvramGetVariable @ 0xffe4e5e2 (0x51 bytes)

int __fastcall NvramGetVariable(_WORD *i, int Attributes, _DWORD *DataSize, unsigned int *Data, int Status, int ia)
{
  int v7; // [esp+4h] [ebp-4h] BYREF

  if ( !i || !Attributes || !Data || !Status && *Data ) /*0xffe4e5fc*/
    return -2147483646; /*0xffe4e629*/
  NvramFindVariable(i, Attributes, (int)&v7, ia); /*0xffe4e608*/
  return NvramReadVariableData(DataSize, Data, Status, ia); /*0xffe4e62e*/
}


// Function: NvramGetVariableName @ 0xffe4e633 (0x118 bytes)

int __fastcall NvramGetVariableName(int i, unsigned __int8 *a2, unsigned int *a3, unsigned int dst, int ia)
{
  unsigned __int8 *v6; // ebx
  unsigned __int8 *v7; // edi
  _BYTE *v8; // esi
  int v9; // ecx
  int v11; // eax
  unsigned int v13; // esi
  bool v14; // cc
  char *src; // eax
  __int16 v16; // cx
  int v17; // edi
  __int16 v18; // ax
  char *src_1; // [esp+10h] [ebp-4h]

  v6 = a2; /*0xffe4e638*/
  if ( !i || !a3 || !a2 || !dst ) /*0xffe4e65c*/
    return -2147483646; /*0xffe4e740*/
  v7 = (unsigned __int8 *)(i + ((*(_DWORD *)(i + 6) & 0x4000000) != 0 ? 26 : 11));
  v8 = v7; /*0xffe4e67a*/
  v9 = i - (_DWORD)v7 + (unsigned __int16)UnalignedRead16((void *)(i + 4)); /*0xffe4e688*/
  if ( (*(_DWORD *)(i + 6) & 0x2000000) != 0 ) /*0xffe4e691*/
  {
    do /*0xffe4e69f*/
    {
      if ( !*v8++ ) /*0xffe4e693*/
        break; /*0xffe4e698*/
      v11 = v9--; /*0xffe4e69a*/
    }
    while ( v11 > 0 ); /*0xffe4e69f*/
    if ( v9 <= 0 ) /*0xffe4e6a3*/
      return -2147483638; /*0xffe4e6aa*/
    v13 = 2 * (v8 - v7); /*0xffe4e6b1*/
  }
  else
  {
    while ( *v8 || v8[1] ) /*0xffe4e6be*/
    {
      if ( v9 <= 0 ) /*0xffe4e6c2*/
        return -2147483638; /*0xffe4e6c2*/
      v8 += 2; /*0xffe4e6c4*/
      v9 -= 2; /*0xffe4e6c7*/
    }
    if ( v9 <= 0 ) /*0xffe4e6ce*/
      return -2147483638; /*0xffe4e6ce*/
    v13 = v8 - v7 + 2; /*0xffe4e6d2*/
  }
  v14 = v13 <= *a3; /*0xffe4e6d9*/
  *a3 = v13; /*0xffe4e6db*/
  if ( !v14 ) /*0xffe4e6dd*/
    return -2147483643; /*0xffe4e6df*/
  src = (char *)NvramGetVariableDataPtr(i, ia); /*0xffe4e6ee*/
  src_1 = src; /*0xffe4e6fa*/
  if ( (*(_DWORD *)(i + 6) & 0x2000000) != 0 ) /*0xffe4e6fe*/
  {
    do /*0xffe4e70d*/
    {
      v16 = *v7++; /*0xffe4e700*/
      *(_WORD *)v6 = v16; /*0xffe4e704*/
      v6 += 2; /*0xffe4e707*/
    }
    while ( v16 ); /*0xffe4e70d*/
  }
  else
  {
    v17 = v7 - v6; /*0xffe4e711*/
    do /*0xffe4e724*/
    {
      v18 = UnalignedRead16(&v6[v17]); /*0xffe4e716*/
      *(_WORD *)v6 = v18; /*0xffe4e71b*/
      v6 += 2; /*0xffe4e71e*/
    }
    while ( v18 ); /*0xffe4e724*/
    src = src_1; /*0xffe4e726*/
  }
  NvramCopyMem(dst, src, 0x10u); /*0xffe4e731*/
  *(_DWORD *)(ia + 24) = i; /*0xffe4e739*/
  return 0; /*0xffe4e745*/
}


// Function: NvramReadVariableDataLoop @ 0xffe4e74b (0x3e bytes)

int __fastcall NvramReadVariableDataLoop(unsigned int i, unsigned __int8 *a2, unsigned int *a3, unsigned int Attributes, int ia)
{
  int result; // eax

  while ( 1 ) /*0xffe4e761*/
  {
    result = NvramGetVariableName(i, a2, a3, Attributes, ia); /*0xffe4e761*/
    if ( result != -2147483638 ) /*0xffe4e76e*/
      break; /*0xffe4e76e*/
    i = NvramGetNextEntry(i, ia); /*0xffe4e77b*/
    if ( !i ) /*0xffe4e77f*/
      return -2147483634; /*0xffe4e781*/
  }
  return result; /*0xffe4e786*/
}


// Function: NvramLocateVariable @ 0xffe4e789 (0x95 bytes)

// positive sp value has been detected, the output may be wrong!
int __fastcall NvramLocateVariable(_WORD *i, _BYTE *Attributes, int ia, int p_i, int p_p_i, int a6)
{
  int ia_1; // esi
  unsigned int v9; // eax
  _BYTE *v10; // ecx
  unsigned int v11; // eax
  int v13; // [esp-14h] [ebp-28h]
  int v14; // [esp-10h] [ebp-24h]
  int v15; // [esp-Ch] [ebp-20h]
  int v16; // [esp-8h] [ebp-1Ch]
  int v17; // [esp-4h] [ebp-18h]
  _DWORD *ia_3; // [esp+0h] [ebp-14h]
  int ia_2; // [esp+4h] [ebp-10h]
  unsigned int *v20; // [esp+Ch] [ebp-8h]

  if ( !i || !Attributes ) /*0xffe4e798*/
    return -2147483646; /*0xffe4e798*/
  ia_1 = ia_2; /*0xffe4e79a*/
  if ( !*i ) /*0xffe4e7a0*/
  {
    v9 = NvramGetFirstEntry((unsigned int *)ia_2); /*0xffe4e7a7*/
    goto LABEL_11; /*0xffe4e7ac*/
  }
  v10 = *(_BYTE **)(ia_2 + 24); /*0xffe4e7ae*/
  if ( !v10 /*0xffe4e7c8*/
    || !NvramValidateStoreEntry(v10, ia_2)
    || !NvramMatchVariableName(*(_DWORD *)(ia_2 + 24), i, Attributes, 0, ia_2, v13, v14, v15, v16, v17, ia_3, ia_2) )
  {
    v11 = NvramFindVariable(i, Attributes, &a6, ia_1); /*0xffe4e7e3*/
    if ( v11 ) /*0xffe4e7ec*/
      goto LABEL_10; /*0xffe4e7ec*/
    return -2147483646; /*0xffe4e813*/
  }
  v11 = *(_DWORD *)(ia_1 + 24); /*0xffe4e7d4*/
LABEL_10:
  v9 = NvramGetNextEntry(v11, ia_1); /*0xffe4e7ee*/
LABEL_11:
  if ( v9 ) /*0xffe4e7f9*/
  {
    if ( v20 ) /*0xffe4e80b*/
      *v20 = v9; /*0xffe4e80d*/
    return 0; /*0xffe4e80f*/
  }
  else
  {
    *(_DWORD *)(ia_1 + 24) = 0; /*0xffe4e7fb*/
    return -2147483634; /*0xffe4e7fe*/
  }
}


// Function: NvramInitStore @ 0xffe4e81e (0x5d bytes)

char __fastcall NvramInitStore(int *src, int a2, char n7)
{
  int v5; // esi
  int v6; // edx
  int v7; // edx
  unsigned int v8; // eax
  _BYTE *v9; // ecx

  v5 = *src; /*0xffe4e829*/
  v6 = src[1]; /*0xffe4e82b*/
  src[9] = 0; /*0xffe4e82e*/
  v7 = v5 + v6; /*0xffe4e832*/
  *((_BYTE *)src + 28) = n7; /*0xffe4e834*/
  src[8] = a2; /*0xffe4e837*/
  src[3] = v7; /*0xffe4e83a*/
  src[2] = v7 - 16; /*0xffe4e840*/
  src[4] = v5 + a2; /*0xffe4e846*/
  src[6] = 0; /*0xffe4e84b*/
  src[5] = 0; /*0xffe4e84e*/
  v8 = NvramGetFirstEntry((unsigned int *)src); /*0xffe4e851*/
  v9 = (_BYTE *)src[4]; /*0xffe4e856*/
  if ( v9 != (_BYTE *)v8 ) /*0xffe4e85b*/
  {
    if ( v8 ) /*0xffe4e85f*/
    {
      src[4] = v8; /*0xffe4e861*/
    }
    else
    {
      LOBYTE(v8) = NvramValidateStoreEntry(v9, (int)src); /*0xffe4e868*/
      if ( !(_BYTE)v8 ) /*0xffe4e86f*/
      {
        v8 = src[4]; /*0xffe4e871*/
        src[3] = v8; /*0xffe4e874*/
      }
    }
  }
  return v8; /*0xffe4e877*/
}


// Function: NvramOpenDefaultsStore @ 0xffe4e87b (0x4f bytes)

int *__fastcall NvramOpenDefaultsStore(_WORD *i, int src, int *this)
{
  _BYTE *v4; // eax
  int v5; // [esp+4h] [ebp-4h] BYREF

  if ( !NvramFindVariable(i, Attributes, (int)&v5, src) ) /*0xffe4e88c*/
    return 0; /*0xffe4e88c*/
  v4 = NvramGetVariablePayload(this + 1); /*0xffe4e8a8*/
  *this = (int)v4; /*0xffe4e8ad*/
  if ( !v4 ) /*0xffe4e8b3*/
    return 0; /*0xffe4e899*/
  NvramInitStore(this, 0, 7); /*0xffe4e8bc*/
  return this; /*0xffe4e8c5*/
}


// Function: NvramGetVariableMultiStore @ 0xffe4e8ca (0x71 bytes)

int __fastcall NvramGetVariableMultiStore(
        _WORD *VariableName,
        int Attributes,
        _DWORD *DataSize,
        unsigned int *Data,
        int Status,
        unsigned int a6,
        int i)
{
  _WORD *VariableName_1; // eax
  unsigned int v9; // esi
  int result; // eax

  VariableName_1 = VariableName; /*0xffe4e8cd*/
  if ( !VariableName ) /*0xffe4e8d9*/
    return -2147483646; /*0xffe4e8d9*/
  if ( !Attributes ) /*0xffe4e8dd*/
    return -2147483646; /*0xffe4e8dd*/
  if ( !Data ) /*0xffe4e8e5*/
    return -2147483646; /*0xffe4e8e5*/
  v9 = 0; /*0xffe4e8e7*/
  if ( !Status ) /*0xffe4e8ed*/
  {
    if ( *Data ) /*0xffe4e8ef*/
      return -2147483646; /*0xffe4e930*/
  }
  if ( !a6 ) /*0xffe4e8f7*/
    return -2147483634; /*0xffe4e929*/
  while ( 1 ) /*0xffe4e90c*/
  {
    result = NvramGetVariable(VariableName_1, Attributes, DataSize, Data, Status, i); /*0xffe4e90c*/
    if ( result != -2147483634 ) /*0xffe4e919*/
      break; /*0xffe4e919*/
    VariableName_1 = VariableName; /*0xffe4e91b*/
    ++v9; /*0xffe4e91f*/
    i += 40; /*0xffe4e920*/
    if ( v9 >= a6 ) /*0xffe4e927*/
      return -2147483634; /*0xffe4e927*/
  }
  return result; /*0xffe4e935*/
}


// Function: NvramGetNextVariableByIndex @ 0xffe4e93b (0x1a2 bytes)

int __fastcall NvramGetNextVariableByIndex(
        unsigned int *a1,
        unsigned __int8 *i,
        _BYTE *Attributes,
        unsigned int a4,
        unsigned int *ia,
        unsigned int *a6)
{
  unsigned __int8 *i_1; // ebx
  unsigned int *v7; // edi
  unsigned int v8; // esi
  int v9; // ebx
  unsigned int *ia_3; // eax
  unsigned int p_i_1; // eax
  unsigned int v12; // ecx
  unsigned int *ia_2; // ebx
  unsigned int j; // eax
  unsigned int j_2; // eax
  int v16; // eax
  int v18; // [esp+0h] [ebp-2Ch]
  int v19; // [esp+Ch] [ebp-20h]
  int v21; // [esp+14h] [ebp-18h]
  unsigned int v22; // [esp+18h] [ebp-14h]
  unsigned int j_1; // [esp+1Ch] [ebp-10h]
  unsigned int *ia_1; // [esp+24h] [ebp-8h]
  int p_i; // [esp+28h] [ebp-4h] BYREF

  i_1 = i; /*0xffe4e944*/
  if ( !a1 || !i || !Attributes ) /*0xffe4e962*/
    return -2147483646; /*0xffe4ead1*/
  v7 = a6; /*0xffe4e96b*/
  v19 = *(unsigned __int16 *)i; /*0xffe4e970*/
  if ( a6 ) /*0xffe4e975*/
  {
    if ( !*(_WORD *)i ) /*0xffe4e968*/
      *a6 = 0; /*0xffe4e97c*/
    v8 = *a6; /*0xffe4e97f*/
  }
  else
  {
    v8 = 0; /*0xffe4e983*/
  }
  if ( v8 < a4 ) /*0xffe4e988*/
  {
    while ( 1 ) /*0xffe4e99f*/
    {
      ia_1 = &ia[10 * v8]; /*0xffe4e99f*/
      v9 = NvramLocateVariable(i_1, Attributes, (int)ia_1, (int)&p_i, (int)&p_i, v18); /*0xffe4e9a7*/
      v21 = v9; /*0xffe4e9ac*/
      if ( v9 >= 0 ) /*0xffe4e9b1*/
      {
        ia_3 = &ia[10 * v8]; /*0xffe4e9b7*/
        if ( (ia_1[7] & 4) != 0 ) /*0xffe4e9be*/
        {
          p_i_1 = p_i; /*0xffe4e9c4*/
          if ( !p_i ) /*0xffe4e9c9*/
            goto LABEL_26; /*0xffe4e9c9*/
          do /*0xffe4ea2f*/
          {
            v12 = 0; /*0xffe4e9ce*/
            v22 = 0; /*0xffe4e9d0*/
            if ( v8 ) /*0xffe4e9d5*/
            {
              ia_2 = ia; /*0xffe4e9d7*/
              do /*0xffe4ea18*/
              {
                for ( j = NvramGetFirstEntry(ia_2); ; j = NvramGetNextEntry(j_1, (int)ia_2) ) /*0xffe4e9dc*/
                {
                  j_1 = j; /*0xffe4e9ff*/
                  if ( !j ) /*0xffe4ea04*/
                  {
                    j_2 = 0; /*0xffe4ea06*/
                    goto LABEL_20; /*0xffe4ea06*/
                  }
                  if ( NvramCompareVariableName(p_i, (int)ia_1, j, (int)ia_2) ) /*0xffe4e9ea*/
                    break; /*0xffe4e9ea*/
                }
                j_2 = j_1; /*0xffe4ea49*/
LABEL_20:
                v12 = v22; /*0xffe4ea08*/
                if ( j_2 ) /*0xffe4ea0d*/
                  break; /*0xffe4ea0d*/
                v12 = v22 + 1; /*0xffe4ea0f*/
                ia_2 += 10; /*0xffe4ea10*/
                v22 = v12; /*0xffe4ea13*/
              }
              while ( v12 < v8 ); /*0xffe4ea18*/
              p_i_1 = p_i; /*0xffe4ea1a*/
            }
            if ( v12 == v8 ) /*0xffe4ea1f*/
              break; /*0xffe4ea1f*/
            p_i_1 = NvramGetNextEntry(p_i_1, (int)ia_1); /*0xffe4ea25*/
            p_i = p_i_1; /*0xffe4ea2a*/
          }
          while ( p_i_1 ); /*0xffe4ea2f*/
          v7 = a6; /*0xffe4ea31*/
          v9 = v21; /*0xffe4ea34*/
          if ( p_i_1 ) /*0xffe4ea39*/
          {
            ia_3 = &ia[10 * v8]; /*0xffe4ea4e*/
          }
          else
          {
LABEL_26:
            ia_3 = &ia[10 * v8]; /*0xffe4ea3b*/
            v9 = -2147483634; /*0xffe4ea3e*/
            ia_1[6] = 0; /*0xffe4ea43*/
          }
        }
        if ( v9 >= 0 ) /*0xffe4ea53*/
        {
          v16 = NvramReadVariableDataLoop(p_i, i, a1, (unsigned int)Attributes, (int)ia_3); /*0xffe4ea63*/
          v9 = v16; /*0xffe4ea68*/
          if ( v16 != -2147483634 ) /*0xffe4ea73*/
          {
            if ( v16 < 0 ) /*0xffe4eab0*/
              *(_WORD *)i = v19; /*0xffe4eab8*/
            if ( v7 ) /*0xffe4eabd*/
              *v7 = v8; /*0xffe4eabf*/
            return v9; /*0xffe4eabf*/
          }
          ia_1[6] = 0; /*0xffe4ea78*/
        }
      }
      if ( v9 == -2147483634 ) /*0xffe4ea82*/
      {
        *(_WORD *)i = 0; /*0xffe4ea89*/
      }
      else if ( v7 && v8 && v8 == *v7 ) /*0xffe4ea98*/
      {
        v8 = -1; /*0xffe4ea9a*/
        *v7 = 0; /*0xffe4ea9d*/
      }
      if ( ++v8 >= a4 ) /*0xffe4eaa4*/
        goto LABEL_46; /*0xffe4eaa4*/
      i_1 = i; /*0xffe4eaa6*/
    }
  }
  v9 = v19; /*0xffe4eac5*/
LABEL_46:
  if ( v7 ) /*0xffe4eaca*/
    *v7 = 0; /*0xffe4eacc*/
  return v9; /*0xffe4ead6*/
}


// Function: NvramValidateStoreHeader @ 0xffe4eadd (0x4a bytes)

unsigned int __thiscall NvramValidateStoreHeader(int this)
{
  unsigned int n72; // eax
  int n0x48; // edx
  unsigned int n0x14; // eax

  if ( *(_DWORD *)(this + 40) != 1213613663 ) /*0xffe4eae4*/
    return 0; /*0xffe4eae4*/
  n72 = 72; /*0xffe4eae8*/
  if ( *(_WORD *)(this + 48) != 72 ) /*0xffe4eaed*/
    return 0; /*0xffe4eaed*/
  n0x48 = *(unsigned __int16 *)(this + 52); /*0xffe4eaef*/
  if ( !(_WORD)n0x48 ) /*0xffe4eaf6*/
    return n72; /*0xffe4eaf6*/
  if ( (unsigned __int16)n0x48 >= 0x48u /*0xffe4eb15*/
    && (unsigned __int16)n0x48 <= 0xD4u
    && (n0x14 = *(_DWORD *)(n0x48 + this + 16), n0x14 >= 0x14)
    && n0x14 <= 0xA0 )
  {
    return n0x48 + n0x14 + (-(n0x48 + n0x14) & 7); /*0xffe4eb21*/
  }
  else
  {
    return 0; /*0xffe4eb24*/
  }
}


// Function: NvramGetStoreAttributes @ 0xffe4eb27 (0x1f bytes)

char __thiscall NvramGetStoreAttributes(char *this)
{
  unsigned int v2; // eax
  char *v3; // eax
  char result; // al

  v2 = NvramValidateStoreHeader((int)this); /*0xffe4eb2a*/
  if ( !v2 ) /*0xffe4eb31*/
    return 32; /*0xffe4eb31*/
  v3 = this + v2 + 23; /*0xffe4eb36*/
  if ( !v3 ) /*0xffe4eb38*/
    return 32; /*0xffe4eb38*/
  result = ~*v3; /*0xffe4eb3c*/
  if ( !result ) /*0xffe4eb40*/
    return 32; /*0xffe4eb42*/
  return result; /*0xffe4eb44*/
}


// Function: NvramCheckAttrCompatibility @ 0xffe4eb46 (0x6f bytes)

char __fastcall NvramCheckAttrCompatibility(char *a1, char *a2, bool *a3)
{
  char v4; // bl
  char n32; // al
  char v6; // cl
  bool v7; // ah
  bool v8; // dl

  v4 = NvramGetStoreAttributes(a1); /*0xffe4eb4f*/
  if ( a2 ) /*0xffe4eb53*/
    n32 = NvramGetStoreAttributes(a2); /*0xffe4eb57*/
  else
    n32 = 32; /*0xffe4eb5e*/
  v6 = 1; /*0xffe4eb62*/
  v7 = (v4 & 4) != 0 && (v4 & 0xE0) == 0; /*0xffe4eb71*/
  v8 = (n32 & 4) != 0 && (n32 & 0xE0) == 0; /*0xffe4eb7f*/
  if ( a3 ) /*0xffe4eb87*/
    *a3 = v8; /*0xffe4eb89*/
  if ( !v7 || !v8 ) /*0xffe4eb91*/
    return v7; /*0xffe4eb91*/
  if ( (n32 & 0x10) == 0 ) /*0xffe4eb95*/
  {
    if ( (v4 & 0x10) != 0 ) /*0xffe4eb9a*/
      return 0; /*0xffe4eb9e*/
    if ( (v4 & 8) != 0 ) /*0xffe4eba3*/
      return (n32 & 8) != 0; /*0xffe4ebac*/
    return v7; /*0xffe4ebae*/
  }
  return v6; /*0xffe4ebb0*/
}


// Function: GpioReadPad @ 0xffe4ebb5 (0xb9 bytes)

int __cdecl GpioReadPad(int a1, int a2, int *a3)
{
  _DWORD *v4; // eax
  int v5; // ecx
  _DWORD *v6; // esi
  int v7; // [esp+4h] [ebp-8h] BYREF
  unsigned int n3; // [esp+8h] [ebp-4h] BYREF

  if ( !GpioCheckPadDefinition(0x1030001u) )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Incorrect GpioPad define used on this chipset (Group=%d, Pad=%d)!\n", 3, 1);
    return -2147483645; /*0xffe4ebe4*/
  }
  v4 = GpioGetControllerInfo(&n3); /*0xffe4ebec*/
  v6 = v4; /*0xffe4ebf5*/
  if ( n3 <= 3 )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Group argument (%d) exceeds GPIO group range\n", 3);
    return -2147483646; /*0xffe4ec12*/
  }
  if ( v4[59] <= 1u )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Pin number (%d) exceeds possible range for this group\n", 1);
    return -2147483646; /*0xffe4ec24*/
  }
  GpioGetPadOwnership(v5, &v7); /*0xffe4ec29*/
  if ( v7 )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Accessing pad not owned by host (Group=%d, Pad=%d)!\n", 3, 1);
    return -2147483645; /*0xffe4ec3d*/
  }
  *a3 = *(_DWORD *)((unsigned __int16)(v6[58] + 8) | ((*((unsigned __int8 *)v6 + 180) | 0xFFFFFD00) << 16)) & 2; /*0xffe4ec65*/
  return 0; /*0xffe4ec69*/
}


// Function: GpioReadReg @ 0xffe4ec6e (0xf0 bytes)

int __fastcall GpioReadReg(int n4, unsigned __int8 n3, unsigned int a3, int a4, int a5, int a6, _DWORD *a7)
{
  int v8; // edi
  _DWORD *v10; // ebp
  int v12; // esi
  int v13; // esi
  int v14; // esi
  int v15; // esi
  int v16; // eax
  unsigned int n3_1; // [esp+14h] [ebp-4h] BYREF

  LOWORD(v8) = 0; /*0xffe4ec7c*/
  v10 = GpioGetControllerInfo(&n3_1); /*0xffe4ec86*/
  if ( n3 >= n3_1 )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Group argument (%d) exceeds GPIO group range\n", n3);
    return -2147483646; /*0xffe4eca6*/
  }
  if ( n4 ) /*0xffe4ecad*/
  {
    v12 = n4 - 1; /*0xffe4ecaf*/
    if ( v12 ) /*0xffe4ecb2*/
    {
      v13 = v12 - 1; /*0xffe4ecb4*/
      if ( v13 ) /*0xffe4ecb7*/
      {
        v14 = v13 - 1; /*0xffe4ecb9*/
        if ( v14 ) /*0xffe4ecbc*/
        {
          v15 = v14 - 1; /*0xffe4ecbe*/
          if ( v15 ) /*0xffe4ecc1*/
          {
            if ( v15 != 1 ) /*0xffe4ecc6*/
            {
              v16 = PeiGetDebugService(); /*0xffe4ecc8*/
              if ( v16 ) /*0xffe4eccf*/
                (*(void (__cdecl **)(const char *, int, const char *))(v16 + 4))( /*0xffe4ece0*/
                  "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
                  218,
                  "((BOOLEAN)(0==1))");
              goto LABEL_19; /*0xffe4ece6*/
            }
            v8 = v10[15 * n3 + 12]; /*0xffe4eceb*/
          }
          else
          {
            v8 = v10[15 * n3 + 11]; /*0xffe4ecf4*/
          }
        }
        else
        {
          v8 = v10[15 * n3 + 10]; /*0xffe4ecfd*/
        }
      }
      else
      {
        v8 = v10[15 * n3 + 8]; /*0xffe4ed06*/
      }
    }
    else
    {
      v8 = v10[15 * n3 + 6]; /*0xffe4ed0f*/
    }
  }
  else
  {
    v8 = v10[15 * n3 + 2]; /*0xffe4ed18*/
  }
  if ( v8 == -1 ) /*0xffe4ed1f*/
    return -2147483646; /*0xffe4ed1f*/
LABEL_19:
  if ( a3 > (unsigned int)(v10[15 * n3 + 14] - 1) >> 5 ) /*0xffe4ed32*/
    return -2147483646; /*0xffe4ed32*/
  *a7 = *(_DWORD *)((unsigned __int16)(v8 + 4 * a3) | ((LOBYTE(v10[15 * n3]) | 0xFFFFFD00) << 16)); /*0xffe4ed53*/
  return 0; /*0xffe4ed57*/
}


// Function: AssertCpuDeadLoop @ 0xffe4ed5e (0x12a bytes)

int __thiscall AssertCpuDeadLoop(char *n4)
{
  unsigned int v2; // edi
  _DWORD *v3; // ebx
  int v5; // eax
  char *v6; // esi
  int v7; // eax
  signed int v8; // eax
  signed int v9; // esi
  int v10; // eax
  int v11; // [esp-18h] [ebp-38h]
  int v12; // [esp-14h] [ebp-34h]
  int v13; // [esp-10h] [ebp-30h]
  int v14; // [esp-Ch] [ebp-2Ch]
  char v15; // [esp+17h] [ebp-9h] BYREF
  int v16; // [esp+18h] [ebp-8h] BYREF
  unsigned int n3; // [esp+1Ch] [ebp-4h] BYREF

  v2 = 0; /*0xffe4ed67*/
  v16 = 0; /*0xffe4ed69*/
  v3 = GpioGetControllerInfo(&n3); /*0xffe4ed7b*/
  if ( n3 <= 3 )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Group argument (%d) exceeds GPIO group range\n", 3);
    return -2147483646; /*0xffe4ed98*/
  }
  if ( n4 == (char *)4 ) /*0xffe4eda7*/
  {
    v2 = v3[56]; /*0xffe4edd2*/
  }
  else
  {
    if ( n4 != (char *)5 ) /*0xffe4edac*/
    {
      v5 = PeiGetDebugService(); /*0xffe4edae*/
      if ( v5 ) /*0xffe4edb5*/
        (*(void (__cdecl **)(const char *, int, const char *))(v5 + 4))( /*0xffe4edc2*/
          "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
          364,
          "((BOOLEAN)(0==1))");
      goto LABEL_11; /*0xffe4edc8*/
    }
    v2 = v3[57]; /*0xffe4edca*/
  }
  if ( v2 == -1 ) /*0xffe4eddb*/
    return -2147483646; /*0xffe4eddb*/
LABEL_11:
  v6 = n4 - 4; /*0xffe4eddd*/
  if ( v6 ) /*0xffe4ede0*/
  {
    if ( v6 == (char *)1 ) /*0xffe4ede5*/
    {
      AssertCpuDeadLoop_6(3u, 0, &v16); /*0xffe4ee0f*/
    }
    else
    {
      v7 = PeiGetDebugService(); /*0xffe4ede7*/
      if ( v7 ) /*0xffe4edee*/
        (*(void (__cdecl **)(const char *, int, const char *))(v7 + 4))( /*0xffe4edfb*/
          "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
          442,
          "((BOOLEAN)(0==1))");
    }
  }
  else
  {
    AssertCpuDeadLoop_5(3u, 0, &v16); /*0xffe4ee22*/
  }
  n3 = 0; /*0xffe4ee32*/
  v8 = SpiFlashCycle(v2, v11, v12, v13, v14, &n3, &v15); /*0xffe4ee43*/
  v9 = v8; /*0xffe4ee48*/
  if ( v8 < 0 ) /*0xffe4ee4f*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v8); /*0xffe4ee5c*/
    v10 = PeiGetDebugService(); /*0xffe4ee64*/
    if ( v10 ) /*0xffe4ee6b*/
      (*(void (__cdecl **)(const char *, int, const char *))(v10 + 4))( /*0xffe4ee78*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        460,
        "!EFI_ERROR (Status)");
  }
  return v9; /*0xffe4ee80*/
}


// Function: AssertCpuDeadLoop_1 @ 0xffe4ee88 (0x4f bytes)

int __fastcall AssertCpuDeadLoop_1(int a1, int *a2)
{
  int v3; // eax
  int v4; // edi
  int v5; // eax

  v3 = GpioReadPad(a1, a1, a2); /*0xffe4ee90*/
  v4 = v3; /*0xffe4ee95*/
  if ( v3 < 0 ) /*0xffe4ee9c*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v3); /*0xffe4eea9*/
    v5 = PeiGetDebugService(); /*0xffe4eeb1*/
    if ( v5 ) /*0xffe4eeb8*/
      (*(void (__cdecl **)(const char *, int, const char *))(v5 + 4))( /*0xffe4eec9*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        935,
        "!EFI_ERROR (Status)");
  }
  *a2 = (unsigned int)*a2 >> 1; /*0xffe4eecf*/
  return v4; /*0xffe4eed3*/
}


// Function: GpioGetPadOwnership @ 0xffe4eed7 (0xaa bytes)

int __fastcall GpioGetPadOwnership(int a1, int *a2)
{
  _DWORD *v3; // eax
  int v4; // eax
  int v6; // eax
  unsigned int n3; // [esp+4h] [ebp-4h] BYREF

  v3 = GpioGetControllerInfo(&n3); /*0xffe4eee1*/
  if ( n3 <= 3 )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Group argument (%d) exceeds GPIO group range\n", 3);
    v4 = PeiGetDebugService(); /*0xffe4ef00*/
    if ( v4 ) /*0xffe4ef07*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0xffe4ef18*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        1389,
        "((BOOLEAN)(0==1))");
    return -2147483646; /*0xffe4ef23*/
  }
  if ( v3[59] <= 1u )
  {
    PeiDebugPrint(0x80000000, "GPIO ERROR: Pin number (%d) exceeds possible range for this group\n", 1);
    v6 = PeiGetDebugService(); /*0xffe4ef42*/
    if ( v6 ) /*0xffe4ef49*/
      (*(void (__cdecl **)(const char *, int, const char *))(v6 + 4))( /*0xffe4ef55*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        1398,
        "((BOOLEAN)(0==1))");
    return -2147483646; /*0xffe4ef55*/
  }
  *a2 = (*(_DWORD *)(*((unsigned __int16 *)v3 + 92) | ((*((unsigned __int8 *)v3 + 180) | 0xFFFFFD00) << 16)) >> 4) & 3; /*0xffe4ef78*/
  return 0; /*0xffe4ef7c*/
}


// Function: AssertCpuDeadLoop_5 @ 0xffe4ef81 (0x53 bytes)

int __fastcall AssertCpuDeadLoop_5(unsigned __int8 n259, unsigned int a2, _DWORD *a3)
{
  int v3; // eax
  int v4; // esi
  int v5; // eax
  int v7; // [esp-10h] [ebp-18h]
  int v8; // [esp-Ch] [ebp-14h]
  int v9; // [esp-8h] [ebp-10h]

  v3 = GpioReadReg(4, n259, a2, v7, v8, v9, a3); /*0xffe4ef90*/
  v4 = v3; /*0xffe4ef95*/
  if ( v3 < 0 ) /*0xffe4ef9c*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v3); /*0xffe4efa9*/
    v5 = PeiGetDebugService(); /*0xffe4efb1*/
    if ( v5 ) /*0xffe4efb8*/
      (*(void (__cdecl **)(const char *, int, const char *))(v5 + 4))( /*0xffe4efc9*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        1451,
        "!EFI_ERROR (Status)");
  }
  return v4; /*0xffe4efd1*/
}


// Function: AssertCpuDeadLoop_6 @ 0xffe4efd4 (0x53 bytes)

int __fastcall AssertCpuDeadLoop_6(unsigned __int8 n259, unsigned int a2, _DWORD *a3)
{
  int v3; // eax
  int v4; // esi
  int v5; // eax
  int v7; // [esp-10h] [ebp-18h]
  int v8; // [esp-Ch] [ebp-14h]
  int v9; // [esp-8h] [ebp-10h]

  v3 = GpioReadReg(5, n259, a2, v7, v8, v9, a3); /*0xffe4efe3*/
  v4 = v3; /*0xffe4efe8*/
  if ( v3 < 0 ) /*0xffe4efef*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v3); /*0xffe4effc*/
    v5 = PeiGetDebugService(); /*0xffe4f004*/
    if ( v5 ) /*0xffe4f00b*/
      (*(void (__cdecl **)(const char *, int, const char *))(v5 + 4))( /*0xffe4f01c*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        1517,
        "!EFI_ERROR (Status)");
  }
  return v4; /*0xffe4f024*/
}


// Function: AssertCpuDeadLoop_2 @ 0xffe4f027 (0x4c bytes)

int __cdecl AssertCpuDeadLoop_2()
{
  int v0; // eax
  int v1; // esi
  int v2; // eax

  v0 = AssertCpuDeadLoop((char *)4); /*0xffe4f02f*/
  v1 = v0; /*0xffe4f034*/
  if ( v0 < 0 ) /*0xffe4f03b*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v0); /*0xffe4f048*/
    v2 = PeiGetDebugService(); /*0xffe4f050*/
    if ( v2 ) /*0xffe4f057*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f068*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        1584,
        "!EFI_ERROR (Status)");
  }
  return v1; /*0xffe4f036*/
}


// Function: AssertCpuDeadLoop_3 @ 0xffe4f073 (0x4c bytes)

int AssertCpuDeadLoop_3()
{
  int v0; // eax
  int v1; // esi
  int v2; // eax

  v0 = AssertCpuDeadLoop((char *)5); /*0xffe4f07b*/
  v1 = v0; /*0xffe4f080*/
  if ( v0 < 0 ) /*0xffe4f087*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v0); /*0xffe4f094*/
    v2 = PeiGetDebugService(); /*0xffe4f09c*/
    if ( v2 ) /*0xffe4f0a3*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f0b4*/
        "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmGpioLib\\GpioLib.c",
        1712,
        "!EFI_ERROR (Status)");
  }
  return v1; /*0xffe4f082*/
}


// Function: GpioGetControllerInfo @ 0xffe4f0bf (0x21 bytes)

void *__thiscall GpioGetControllerInfo(unsigned int *p_n3)
{
  if ( PchGetSeries() == 1 ) /*0xffe4f0ca*/
  {
    *p_n3 = 13; /*0xffe4f0cc*/
    return &unk_FFE50FDC; /*0xffe4f0d2*/
  }
  else
  {
    *p_n3 = 0; /*0xffe4f0d9*/
    return 0; /*0xffe4f0dc*/
  }
}


// Function: GpioCheckPadDefinition @ 0xffe4f0e0 (0x36 bytes)

bool __thiscall GpioCheckPadDefinition(unsigned int n16973825)
{
  int n2; // eax

  n2 = PchDetectSku(); /*0xffe4f0e3*/
  if ( n2 == 1 ) /*0xffe4f0eb*/
    return (n16973825 & 0xFF000000) == 0x1000000; /*0xffe4f0f3*/
  if ( n2 != 2 ) /*0xffe4f102*/
    return 0; /*0xffe4f102*/
  return (n16973825 & 0xFF000000) == 0x2000000; /*0xffe4f0fd*/
}


// Function: PchDetectSku @ 0xffe4f116 (0xe7 bytes)

int PchDetectSku()
{
  int n3; // eax
  int n3_1; // esi
  int v2; // eax
  unsigned __int16 n0xA1C0; // ax
  int v4; // eax

  n3 = n3_0; /*0xffe4f116*/
  n3_1 = 3; /*0xffe4f11e*/
  if ( n3_0 == 3 )
  {
    v2 = LpcReadConfig(0); /*0xffe4f129*/
    n0xA1C0 = IoRead16((unsigned __int16 *)(v2 + 2)); /*0xffe4f137*/
    if ( n0xA1C0 >= 0xA1C0u && n0xA1C0 <= 0xA1CFu || n0xA1C0 == 0xA243 || n0xA1C0 >= 0xA240u && n0xA1C0 <= 0xA24Fu )
    {
      n3_1 = 1; /*0xffe4f1f2*/
    }
    else if ( n0xA1C0 == 0x9D40
           || n0xA1C0 == 0x9D41
           || n0xA1C0 == 0x9D42
           || n0xA1C0 == 0x9D43
           || n0xA1C0 == 0x9D46
           || n0xA1C0 == 0x9D48 )
    {
      n3_1 = 2; /*0xffe4f1ed*/
    }
    else
    {
      PeiDebugPrint(0x80000000, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", n0xA1C0);
      v4 = PeiGetDebugService(); /*0xffe4f1cb*/
      if ( v4 ) /*0xffe4f1d2*/
        (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0xffe4f1e3*/
          "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmPchInfoLib\\PchInfoLib.c",
          252,
          "((BOOLEAN)(0==1))");
    }
    n3_0 = n3_1; /*0xffe4f1f3*/
    return n3_1; /*0xffe4f1f9*/
  }
  return n3; /*0xffe4f1fb*/
}


// Function: PchGetSeries @ 0xffe4f1fd (0xa4 bytes)

int PchGetSeries()
{
  int n2; // eax
  int n2_1; // esi
  int v2; // eax
  unsigned __int16 n0xA1C0; // ax
  int v4; // eax

  n2 = n2; /*0xffe4f1fd*/
  n2_1 = 2; /*0xffe4f205*/
  if ( n2 == 2 )
  {
    v2 = LpcReadConfig(0); /*0xffe4f210*/
    n0xA1C0 = IoRead16((unsigned __int16 *)(v2 + 2)); /*0xffe4f21e*/
    if ( n0xA1C0 >= 0xA1C0u && n0xA1C0 <= 0xA1CFu || n0xA1C0 == 0xA243 || n0xA1C0 >= 0xA240u && n0xA1C0 <= 0xA24Fu )
    {
      n2_1 = 1; /*0xffe4f296*/
    }
    else
    {
      PeiDebugPrint(0x80000000, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", n0xA1C0);
      v4 = PeiGetDebugService(); /*0xffe4f274*/
      if ( v4 ) /*0xffe4f27b*/
        (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0xffe4f28c*/
          "e:\\hs\\PurleySktPkg\\SouthClusterLbg\\Library\\PeiDxeSmmPchInfoLib\\PchInfoLib.c",
          290,
          "((BOOLEAN)(0==1))");
    }
    n2 = n2_1; /*0xffe4f297*/
    return n2_1; /*0xffe4f29d*/
  }
  return n2; /*0xffe4f29f*/
}


// Function: LpcReadConfig @ 0xffe4f2a1 (0x3f bytes)

int __cdecl LpcReadConfig(int a1)
{
  _DWORD v2[5]; // [esp+0h] [ebp-14h] BYREF

  v2[3] = 0; /*0xffe4f2af*/
  v2[2] = 512; /*0xffe4f2b7*/
  v2[1] = 0; /*0xffe4f2cb*/
  MmioAddrCalc(0, 0, (int)v2, &a1, (int *)((a1 & 7 | 0xF8) << 12)); /*0xffe4f2d1*/
  return a1; /*0xffe4f2dc*/
}


// Function: AssertCpuDeadLoop_4 @ 0xffe4f2e0 (0x6e bytes)

int AssertCpuDeadLoop_4()
{
  int v0; // eax
  int v1; // eax
  int v2; // eax
  int v3; // eax
  int v5; // [esp+4h] [ebp-4h] BYREF

  v0 = PeiGetServices(); /*0xffe4f2e5*/
  v1 = (*(int (__cdecl **)(int, int *))(*(_DWORD *)v0 + 48))(v0, &v5); /*0xffe4f2f1*/
  if ( v1 < 0 ) /*0xffe4f2fd*/
  {
    PeiDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v1); /*0xffe4f30a*/
    v2 = PeiGetDebugService(); /*0xffe4f312*/
    if ( v2 ) /*0xffe4f319*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f323*/
        "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
        50,
        "!EFI_ERROR (Status)");
  }
  if ( !v5 ) /*0xffe4f32d*/
  {
    v3 = PeiGetDebugService(); /*0xffe4f32f*/
    if ( v3 ) /*0xffe4f336*/
      (*(void (__cdecl **)(const char *, int, const char *))(v3 + 4))( /*0xffe4f340*/
        "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
        51,
        "HobList != ((void *) 0)");
  }
  return v5; /*0xffe4f349*/
}


// Function: HobFindByType @ 0xffe4f34e (0x45 bytes)

_WORD *__fastcall HobFindByType(int a1, _WORD *i)
{
  _WORD *i_1; // esi
  int v3; // eax

  i_1 = i; /*0xffe4f34f*/
  if ( !i ) /*0xffe4f353*/
  {
    v3 = PeiGetDebugService(); /*0xffe4f355*/
    if ( v3 ) /*0xffe4f35c*/
      (*(void (__cdecl **)(const char *, int, const char *))(v3 + 4))( /*0xffe4f36a*/
        "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
        82,
        "HobStart != ((void *) 0)");
  }
  while ( 1 ) /*0xffe4f383*/
  {
    if ( *i_1 == 0xFFFF ) /*0xffe4f389*/
      return 0; /*0xffe4f38e*/
    if ( *i_1 == 4 ) /*0xffe4f37b*/
      break; /*0xffe4f37b*/
    i_1 = (_WORD *)((char *)i_1 + (unsigned __int16)i_1[1]); /*0xffe4f381*/
  }
  return i_1; /*0xffe4f38d*/
}


// Function: Assert @ 0xffe4f393 (0x30 bytes)

char *__cdecl NvramFindGuidHob()
{
  char *i; // edx
  int v1; // ecx
  char *v2; // eax
  char *v3; // esi

  for ( i = (char *)AssertCpuDeadLoop_4(); ; i = &v3[*((unsigned __int16 *)v3 + 1)] ) /*0xffe4f399*/
  {
    v2 = (char *)HobFindByType(v1, i); /*0xffe4f3b4*/
    v3 = v2; /*0xffe4f3b9*/
    if ( !v2 || CompareGuid((int)i_0, v2 + 8) ) /*0xffe4f3a5*/
      break; /*0xffe4f3a5*/
  }
  return v3; /*0xffe4f3c1*/
}


// Function: HobGetByGuid @ 0xffe4f3c3 (0x50 bytes)

const char *__fastcall HobGetByGuid(int a1, int a2)
{
  int v3; // eax
  int v4; // eax
  int v6; // [esp+4h] [ebp-4h] BYREF

  v3 = PeiGetServices(); /*0xffe4f3ca*/
  if ( (*(int (__cdecl **)(int, int, int, int *))(*(_DWORD *)v3 + 52))(v3, 4, a2, &v6) < 0 ) /*0xffe4f3e2*/
    v6 = 0; /*0xffe4f3e4*/
  if ( !v6 ) /*0xffe4f3ec*/
  {
    v4 = PeiGetDebugService(); /*0xffe4f3ee*/
    if ( v4 ) /*0xffe4f3f5*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0xffe4f406*/
        "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
        250,
        "Hob != ((void *) 0)");
  }
  return (const char *)v6; /*0xffe4f3df*/
}


// Function: HobCreateGuid @ 0xffe4f413 (0x46 bytes)

const char *__fastcall HobCreateGuid(int a1, unsigned int n0xFFE0)
{
  int v2; // eax
  const char *result; // eax
  const char *v4; // esi

  if ( n0xFFE0 > 0xFFE0 ) /*0xffe4f41c*/
  {
    v2 = PeiGetDebugService(); /*0xffe4f41e*/
    if ( v2 ) /*0xffe4f425*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f436*/
        "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
        421,
        "DataLength <= (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE))");
  }
  result = HobGetByGuid(); /*0xffe4f43f*/
  v4 = result; /*0xffe4f444*/
  if ( result ) /*0xffe4f448*/
  {
    CopyGuid(result + 8); /*0xffe4f44f*/
    return v4 + 24; /*0xffe4f454*/
  }
  return result; /*0xffe4f44a*/
}


// Function: IoOr16 @ 0xffe4f459 (0x16 bytes)

unsigned __int16 __thiscall IoOr16(unsigned __int16 *this)
{
  __int16 v2; // ax

  v2 = IoRead16(this); /*0xffe4f45c*/
  return IoWrite16(this, v2 | 1); /*0xffe4f469*/
}


// Function: IoAndThenOr16 @ 0xffe4f46f (0x1c bytes)

unsigned __int16 __cdecl IoAndThenOr16(__int16 n4864)
{
  unsigned __int16 *v1; // ecx
  unsigned __int16 *v2; // esi
  char v3; // al

  v2 = v1; /*0xffe4f470*/
  v3 = IoRead16(v1); /*0xffe4f472*/
  return IoWrite16(v2, n4864 | v3 & 0x7F); /*0xffe4f485*/
}


// Function: IoRead16 @ 0xffe4f48b (0x2e bytes)

int __fastcall IoRead16(unsigned __int16 *a1)
{
  int v2; // eax

  if ( ((unsigned __int8)a1 & 1) != 0 ) /*0xffe4f491*/
  {
    v2 = PeiGetDebugService(); /*0xffe4f493*/
    if ( v2 ) /*0xffe4f49a*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f4ab*/
        "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
        151,
        "(Address & 1) == 0");
  }
  return *a1; /*0xffe4f4b7*/
}


// Function: IoWrite16 @ 0xffe4f4b9 (0x33 bytes)

unsigned __int16 __fastcall IoWrite16(unsigned __int16 *this, unsigned __int16 n61440)
{
  int v4; // eax

  if ( ((unsigned __int8)this & 1) != 0 ) /*0xffe4f4c3*/
  {
    v4 = PeiGetDebugService(); /*0xffe4f4c5*/
    if ( v4 ) /*0xffe4f4cc*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0xffe4f4dd*/
        "e:\\hs\\MdePkg\\Library\\BaseIoLibIntrinsic\\IoLib.c",
        183,
        "(Address & 1) == 0");
  }
  *this = n61440; /*0xffe4f4e3*/
  return n61440; /*0xffe4f4e9*/
}


// Function: UnalignedRead16 @ 0xffe4f4ec (0x27 bytes)

__int16 __thiscall UnalignedRead16(void *this)
{
  int v2; // eax

  if ( !this ) /*0xffe4f4f1*/
  {
    v2 = PeiGetDebugService(); /*0xffe4f4f3*/
    if ( v2 ) /*0xffe4f4fa*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f508*/
        "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
        38,
        "Buffer != ((void *) 0)");
  }
  return *(_WORD *)this; /*0xffe4f511*/
}


// Function: UnalignedRead32 @ 0xffe4f513 (0x29 bytes)

int __thiscall UnalignedRead32(void *this)
{
  int v2; // eax

  if ( !this ) /*0xffe4f518*/
  {
    v2 = PeiGetDebugService(); /*0xffe4f51a*/
    if ( v2 ) /*0xffe4f521*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f532*/
        "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
        141,
        "Buffer != ((void *) 0)");
  }
  return *(_DWORD *)this; /*0xffe4f53a*/
}


// Function: UnalignedRead64 @ 0xffe4f53c (0x2c bytes)

__int64 __thiscall UnalignedRead64(void *this)
{
  int v2; // eax

  if ( !this ) /*0xffe4f541*/
  {
    v2 = PeiGetDebugService(); /*0xffe4f543*/
    if ( v2 ) /*0xffe4f54a*/
      (*(void (__cdecl **)(const char *, int, const char *))(v2 + 4))( /*0xffe4f55b*/
        "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
        192,
        "Buffer != ((void *) 0)");
  }
  return *(_QWORD *)this; /*0xffe4f566*/
}


// Function: UnalignedWrite64 @ 0xffe4f568 (0x34 bytes)

int __thiscall UnalignedWrite64(char *this, int a2, int a3)
{
  int v4; // eax

  if ( !this ) /*0xffe4f56d*/
  {
    v4 = PeiGetDebugService(); /*0xffe4f56f*/
    if ( v4 ) /*0xffe4f576*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))( /*0xffe4f587*/
        "e:\\hs\\MdePkg\\Library\\BaseLib\\Unaligned.c",
        219,
        "Buffer != ((void *) 0)");
  }
  *(_DWORD *)this = a2; /*0xffe4f595*/
  *((_DWORD *)this + 1) = a3; /*0xffe4f597*/
  return a2; /*0xffe4f59a*/
}


// Function: RShiftU64 @ 0xffe4f59c (0x27 bytes)

unsigned __int64 __cdecl RShiftU64(unsigned __int64 a1)
{
  return a1 >> 16; /*0xffe4f5bf*/
}


// Function: CopyGuid @ 0xffe4f5c3 (0x31 bytes)

char *__thiscall CopyGuid(char *this)
{
  __int64 v2; // rax
  __int64 v3; // rax

  v2 = UnalignedRead64(i_0); /*0xffe4f5cb*/
  UnalignedWrite64(this, v2, SHIDWORD(v2)); /*0xffe4f5d4*/
  v3 = UnalignedRead64(&unk_FFE50EEC); /*0xffe4f5de*/
  UnalignedWrite64(this + 8, v3, SHIDWORD(v3)); /*0xffe4f5e8*/
  return this; /*0xffe4f5f2*/
}


// Function: CompareGuid @ 0xffe4f5f4 (0x5f bytes)

bool __fastcall CompareGuid(int i, char *this)
{
  __int64 v4; // rax
  int v5; // ebp
  __int64 v6; // rax
  int v7; // edi
  __int64 v8; // kr00_8
  __int64 v9; // rax
  int v11; // [esp+10h] [ebp-Ch]
  int v12; // [esp+14h] [ebp-8h]

  v4 = UnalignedRead64((void *)i); /*0xffe4f5ff*/
  v12 = HIDWORD(v4); /*0xffe4f606*/
  v5 = v4; /*0xffe4f60a*/
  v6 = UnalignedRead64(this); /*0xffe4f60c*/
  v11 = HIDWORD(v6); /*0xffe4f614*/
  v7 = v6; /*0xffe4f618*/
  v8 = UnalignedRead64((void *)(i + 8)); /*0xffe4f626*/
  v9 = UnalignedRead64(this + 8); /*0xffe4f628*/
  return v5 == v7 && v12 == v11 && v8 == v9; /*0xffe4f64b*/
}


// Function: CopyMemSafe @ 0xffe4f653 (0x71 bytes)

char *__fastcall CopyMemSafe(char *dst, char *n60, unsigned int count)
{
  char *dst_1; // eax
  int v6; // eax
  int v7; // eax

  dst_1 = dst; /*0xffe4f65b*/
  if ( count ) /*0xffe4f662*/
  {
    if ( count - 1 > ~(unsigned int)dst ) /*0xffe4f66c*/
    {
      v6 = PeiGetDebugService(); /*0xffe4f66e*/
      if ( v6 ) /*0xffe4f675*/
        (*(void (__cdecl **)(const char *, int, const char *))(v6 + 4))(aEHsMdepkgLibra_4, 56, aLength10xfffff); /*0xffe4f683*/
    }
    if ( count - 1 > ~(unsigned int)n60 ) /*0xffe4f690*/
    {
      v7 = PeiGetDebugService(); /*0xffe4f692*/
      if ( v7 ) /*0xffe4f699*/
        (*(void (__cdecl **)(const char *, int, const char *))(v7 + 4))(aEHsMdepkgLibra_4, 57, aLength10xfffff_0); /*0xffe4f6a7*/
    }
    if ( dst == n60 ) /*0xffe4f6af*/
      return dst; /*0xffe4f6b1*/
    else
      return InternalMemCopyMem(dst, n60, count); /*0xffe4f6b8*/
  }
  return dst_1; /*0xffe4f6c0*/
}


// Function: PeiGetDebugService @ 0xffe4f73a (0x31 bytes)

int PeiGetDebugService()
{
  int v0; // eax
  int v2; // [esp+0h] [ebp-8h] BYREF
  int v3; // [esp+4h] [ebp-4h] BYREF

  v0 = PeiGetServices(); /*0xffe4f73f*/
  if ( (*(int (__cdecl **)(int, void *, _DWORD, int *, int *))(*(_DWORD *)v0 + 32))(v0, &unk_FFE50EA4, 0, &v2, &v3) >= 0 ) /*0xffe4f75e*/
    return v3; /*0xffe4f764*/
  else
    return 0; /*0xffe4f760*/
}


// Function: PeiDebugPrint @ 0xffe4f76b (0x2a bytes)

int PeiDebugPrint(int a1, const char *a2, ...)
{
  int result; // eax
  int (__cdecl **v3)(int, const char *, int *); // esi
  va_list va; // [esp+10h] [ebp+Ch] BYREF

  va_start(va, a2);
  result = PeiGetDebugService(); /*0xffe4f76c*/
  v3 = (int (__cdecl **)(int, const char *, int *))result; /*0xffe4f771*/
  if ( result ) /*0xffe4f775*/
  {
    result = CmosReadDiagStatus(); /*0xffe4f777*/
    if ( (result & a1) != 0 ) /*0xffe4f782*/
      return (*v3)(a1, a2, (int *)va); /*0xffe4f78e*/
  }
  return result; /*0xffe4f793*/
}


// Function: PeiAssertCall @ 0xffe4f795 (0x1e bytes)

int __fastcall PeiAssertCall(
        int e:__hs__MdePkg__Library__PeiServicesTablePointerLibIdt__PeiServ,
        int n48,
        int PeiServices____((void__)_0))
{
  int result; // eax

  result = PeiGetDebugService(); /*0xffe4f79b*/
  if ( result ) /*0xffe4f7a2*/
    return (*(int (__cdecl **)(int, int, int))(result + 4))( /*0xffe4f7aa*/
             e:__hs__MdePkg__Library__PeiServicesTablePointerLibIdt__PeiServ,
             n48,
             PeiServices____((void__)_0));
  return result; /*0xffe4f7b0*/
}


// Function: PeiGetServices @ 0xffe4f7b3 (0x32 bytes)

int PeiGetServices()
{
  int v0; // esi
  __int64 v2; // [esp+4h] [ebp-8h] BYREF

  X86ReadIdtr(&v2); /*0xffe4f7bc*/
  v0 = *(_DWORD *)(*(_DWORD *)((char *)&v2 + 2) - 4); /*0xffe4f7c4*/
  if ( !v0 ) /*0xffe4f7c9*/
    PeiAssertCall( /*0xffe4f7d8*/
      (int)"e:\\hs\\MdePkg\\Library\\PeiServicesTablePointerLibIdt\\PeiServicesTablePointer.c",
      48,
      (int)"PeiServices != ((void *) 0)");
  return v0; /*0xffe4f7e0*/
}


// Function: PeiReportProgress @ 0xffe4f7e5 (0x72 bytes)

int PeiReportProgress(unsigned int a1, int (**thisa)(void), char *GPP_D1_%x__status_%r_n, ...)
{
  int result; // eax
  char *GPP_D1_%x__status_%r_n_1; // eax
  va_list va; // [esp+18h] [ebp+14h] BYREF

  va_start(va, GPP_D1_%x__status_%r_n);
  result = (*((int (__stdcall **)(int (**)(void)))*thisa + 8))(thisa); /*0xffe4f7fe*/
  if ( result >= 0 ) /*0xffe4f806*/
  {
    if ( thisa ) /*0xffe4f80e*/
    {
      result = CmosReadDiagStatus(); /*0xffe4f810*/
      if ( (result & a1) != 0 ) /*0xffe4f81a*/
      {
        GPP_D1_%x__status_%r_n_1 = GPP_D1_%x__status_%r_n; /*0xffe4f81c*/
        if ( *GPP_D1_%x__status_%r_n ) /*0xffe4f81f*/
        {
          do /*0xffe4f83f*/
          {
            if ( *GPP_D1_%x__status_%r_n_1 == 37 ) /*0xffe4f827*/
            {
              if ( *++GPP_D1_%x__status_%r_n_1 == 115 ) /*0xffe4f82f*/
              {
                *GPP_D1_%x__status_%r_n_1 = 97; /*0xffe4f831*/
              }
              else if ( *GPP_D1_%x__status_%r_n_1 == 71 ) /*0xffe4f839*/
              {
                *GPP_D1_%x__status_%r_n_1 = 103; /*0xffe4f83b*/
              }
            }
            ++GPP_D1_%x__status_%r_n_1; /*0xffe4f83e*/
          }
          while ( *GPP_D1_%x__status_%r_n_1 ); /*0xffe4f83f*/
          GPP_D1_%x__status_%r_n_1 = GPP_D1_%x__status_%r_n; /*0xffe4f844*/
        }
        return ((int (__cdecl *)(unsigned int, char *, char *))*thisa)(a1, GPP_D1_%x__status_%r_n_1, (char *)va); /*0xffe4f84d*/
      }
    }
  }
  return result; /*0xffe4f855*/
}


// Function: CompareMem @ 0xffe4f857 (0x5f bytes)

int __fastcall CompareMem(_BYTE *a1, _BYTE *Attributes)
{
  _BYTE *v2; // esi
  _BYTE *v3; // edi
  int n4; // ebx
  int v5; // ecx

  v2 = a1; /*0xffe4f859*/
  v3 = a1 + 16; /*0xffe4f85e*/
  n4 = (unsigned __int8)a1 & 3; /*0xffe4f861*/
  if ( ((unsigned __int8)a1 & 3) != 0 && n4 == ((unsigned __int8)Attributes & 3) ) /*0xffe4f86d*/
  {
    v5 = 4 - n4; /*0xffe4f872*/
    if ( n4 != 4 ) /*0xffe4f874*/
    {
      do /*0xffe4f881*/
      {
        if ( *v2 != *Attributes ) /*0xffe4f87a*/
          break; /*0xffe4f87a*/
        ++v2; /*0xffe4f87c*/
        ++Attributes; /*0xffe4f87d*/
        --v5; /*0xffe4f87e*/
      }
      while ( v5 ); /*0xffe4f881*/
    }
  }
  while ( v2 <= v3 - 4 && *(_DWORD *)v2 == *(_DWORD *)Attributes ) /*0xffe4f88c*/
  {
    v2 += 4; /*0xffe4f88e*/
    Attributes += 4; /*0xffe4f891*/
  }
  while ( 1 ) /*0xffe4f8a2*/
  {
    if ( v2 >= v3 ) /*0xffe4f8a4*/
      return 0; /*0xffe4f8ab*/
    if ( *v2 != *Attributes ) /*0xffe4f89e*/
      break; /*0xffe4f89e*/
    ++v2; /*0xffe4f8a0*/
    ++Attributes; /*0xffe4f8a1*/
  }
  return (char)*v2 - (char)*Attributes; /*0xffe4f8a8*/
}


// Function: CheckSocketIioConfig @ 0xffe4f8b6 (0x99 bytes)

char __cdecl CheckSocketIioConfig(int SystemTable, _DWORD *src)
{
  char v2; // bl
  _DWORD *v4; // eax
  int v5; // esi
  int n814; // [esp+8h] [ebp-4h] BYREF

  n814 = 0; /*0xffe4f8d1*/
  v2 = 0; /*0xffe4f8d5*/
  if ( ((int (__cdecl *)(_DWORD *, const __int16 *, void *, _DWORD, int *, _DWORD))*src)( /*0xffe4f8eb*/
         src,
         L"Setup",
         &unk_FFE50F64,
         0,
         &n814,
         0) == -2147483643
    && n814 != 814 )
  {
    return 0; /*0xffe4f8ed*/
  }
  if ( !off_FFE51304 ) /*0xffe4f8fa*/
    return 1; /*0xffe4f943*/
  v4 = &off_FFE51304; /*0xffe4f8fe*/
  v5 = 0; /*0xffe4f903*/
  while ( 1 ) /*0xffe4f90a*/
  {
    n814 = 0; /*0xffe4f90a*/
    if ( ((int (__cdecl *)(_DWORD *, char *, _DWORD, _DWORD, int *, _DWORD))*src)( /*0xffe4f92f*/
           src,
           (&off_FFE51308)[v5],
           *v4,
           0,
           &n814,
           0) == -2147483643
      && n814 != dword_FFE5130C[v5] ) // "S\x00o\x00c\x00k\x00e\x00t\x00I\x00i\x00o\x00C\x00o\x00n\x00f\x00i\x00g"
    {
      break; /*0xffe4f92f*/
    }
    v5 = 3 * (unsigned __int8)++v2; /*0xffe4f936*/
    v4 = (_UNKNOWN **)((char *)&off_FFE51304 + v5 * 4); /*0xffe4f939*/
    if ( !*(_UNKNOWN **)((char *)&off_FFE51304 + v5 * 4) ) /*0xffe4f93f*/
      return 1; /*0xffe4f941*/
  }
  return 0; /*0xffe4f947*/
}


// Function: FvLocateFileHob @ 0xffe4f94f (0xdd bytes)

char *FvLocateFileHob()
{
  int v0; // eax
  int v1; // esi
  int v2; // eax
  int v3; // ecx
  char *v4; // esi
  char *v5; // eax
  char *v6; // edx
  int v7; // ecx
  char *v8; // ebx
  char *n60; // ebp
  unsigned int count; // eax
  int v11; // edi
  int v13; // [esp+8h] [ebp-8h] BYREF
  int v14; // [esp+Ch] [ebp-4h] BYREF

  v13 = 0; /*0xffe4f955*/
  v14 = 0; /*0xffe4f959*/
  v0 = PeiGetServices(); /*0xffe4f95d*/
  if ( (*(int (__cdecl **)(int, _DWORD, int *))(*(_DWORD *)v0 + 56))(v0, 0, &v13) < 0 ) /*0xffe4f973*/
    return 0; /*0xffe4f973*/
  v1 = v13; /*0xffe4f979*/
  v2 = PeiGetServices(); /*0xffe4f97d*/
  if ( (*(int (__cdecl **)(void *, int, int *))(*(_DWORD *)v2 + 104))(&unk_FFE50ED4, v1, &v14) < 0 ) /*0xffe4f997*/
    return 0; /*0xffe4f997*/
  v4 = (char *)(v14 + 44); /*0xffe4f9a1*/
  if ( *(_DWORD *)(v14 + 44) != 1280134994 ) /*0xffe4f9aa*/
    return 0; /*0xffe4fa25*/
  v5 = (char *)HobCreateGuid(v3, 48 * *(_DWORD *)(v14 + 56) + 16); /*0xffe4f9b6*/
  v6 = v5; /*0xffe4f9bb*/
  if ( v5 ) /*0xffe4f9bf*/
  {
    *(_DWORD *)v5 = *((_DWORD *)v4 + 1); /*0xffe4f9c4*/
    v7 = *((_DWORD *)v4 + 2); /*0xffe4f9c6*/
    *((_DWORD *)v5 + 3) = 0; /*0xffe4f9c9*/
    v8 = v5 + 16; /*0xffe4f9cc*/
    *((_DWORD *)v5 + 1) = v7; /*0xffe4f9cf*/
    *((_DWORD *)v5 + 2) = 48; /*0xffe4f9d2*/
    n60 = v4 + 16; /*0xffe4f9e1*/
    if ( v4 + 16 < &v4[*((_DWORD *)v4 + 2) * *((_DWORD *)v4 + 3) + 16] ) /*0xffe4f9ea*/
    {
      count = *((_DWORD *)v4 + 2); /*0xffe4f9ec*/
      v11 = 16 - (_DWORD)v6; /*0xffe4f9ef*/
      do /*0xffe4fa1d*/
      {
        CopyMemSafe(v8 + 8, n60, count); /*0xffe4f9f7*/
        *((_DWORD *)v8 + 1) = 0; /*0xffe4f9fc*/
        *(_DWORD *)v8 = &v8[v11 + 8]; /*0xffe4fa05*/
        v8 += 48; /*0xffe4fa07*/
        count = *((_DWORD *)v4 + 2); /*0xffe4fa0a*/
        n60 += count; /*0xffe4fa0d*/
      }
      while ( n60 < &v4[count * *((_DWORD *)v4 + 3) + 16] ); /*0xffe4fa1d*/
    }
  }
  return v4; /*0xffe4fa27*/
}


// Function: Assert_0 @ 0xffe4fa2c (0x23 bytes)

unsigned int __thiscall Assert_0(void *this)
{
  char *v1; // ecx

  v1 = Assert(); /*0xffe4fa32*/
  if ( !v1 ) /*0xffe4fa36*/
  {
    FvLocateFileHob(); /*0xffe4fa38*/
    v1 = Assert(); /*0xffe4fa42*/
  }
  return v1 != 0 ? (unsigned int)(v1 + 48) : 0;
}


// Function: HobSearchByGuid @ 0xffe4fa4f (0x41 bytes)

unsigned int __thiscall HobSearchByGuid(char *i)
{
  char *v1; // esi
  char *v2; // edi
  unsigned int v3; // esi

  if ( i /*0xffe4fa83*/
    && (v1 = i - 8, v2 = &v1[-*(_DWORD *)v1], CompareGuid((int)(v2 + 8), i_0))
    && (v3 = (unsigned int)&v1[*((_DWORD *)v2 + 8)], (unsigned int)(v2 + 40) <= v3)
    && (unsigned int)&v2[*((unsigned __int16 *)v2 + 1)] > v3 )
  {
    return v3 + 8; /*0xffe4fa85*/
  }
  else
  {
    return 0; /*0xffe4fa8a*/
  }
}


// Function: HobFindByGuid @ 0xffe4fa90 (0x32 bytes)

char *__thiscall HobFindByGuid(char *this)
{
  char *i_1; // esi
  unsigned int i; // eax

  i_1 = 0; /*0xffe4fa95*/
  if ( this ) /*0xffe4fa99*/
  {
    for ( i = NvramGetFirstGuidHob(this); ; i = HobSearchByGuid(i_1) ) /*0xffe4fa9b*/
    {
      i_1 = (char *)i; /*0xffe4fab6*/
      if ( !i || CompareGuid(i, this) ) /*0xffe4faa6*/
        break; /*0xffe4faa6*/
    }
  }
  return i_1; /*0xffe4fabc*/
}


// Function: GpioReadRegister @ 0xffe4fac2 (0x5b bytes)

int __usercall GpioReadRegister@<eax>(unsigned __int16 n0x4C8@<dx>, _DWORD *a2)
{
  unsigned __int8 *v3; // eax
  int v4; // eax
  unsigned int n3; // [esp+8h] [ebp-4h] BYREF

  v3 = (unsigned __int8 *)GpioGetControllerInfo(&n3); /*0xffe4facd*/
  if ( n3 > 3 ) /*0xffe4fad6*/
  {
    *a2 = *(_DWORD *)(n0x4C8 | ((v3[180] | 0xFFFFFD00) << 16)); /*0xffe4fb14*/
    return 0; /*0xffe4fb16*/
  }
  else
  {
    v4 = PeiGetDebugService(); /*0xffe4fad8*/
    if ( v4 ) /*0xffe4fadf*/
      (*(void (__cdecl **)(const char *, int, const char *))(v4 + 4))(aEHsPurleysktpk_1, 59, "((BOOLEAN)(0==1))"); /*0xffe4faed*/
    return -2147483646; /*0xffe4faf3*/
  }
}


// Function: PeiGetVariableAddressAmi @ 0xffe4fb4f (0xf8 bytes)

int __cdecl PeiGetVariableAddressAmi(_WORD *i, _BYTE *Attributes, int *a3)
{
  int v3; // eax
  int v4; // esi
  int result; // eax
  int v6; // ebx
  int j; // edi
  _BYTE *v8; // eax
  _BYTE *v9; // ebp
  int v10; // [esp+10h] [ebp-Ch] BYREF
  int v11; // [esp+14h] [ebp-8h] BYREF
  int p_n16; // [esp+18h] [ebp-4h] BYREF

  PeiDebugPrint(64, asc_FFE50C1C); /*0xffe4fb5d*/
  if ( !i || !Attributes ) /*0xffe4fb74*/
    return -2147483646; /*0xffe4fc3a*/
  v3 = PeiGetServices(); /*0xffe4fb7a*/
  v4 = 0; /*0xffe4fb83*/
  result = (*(int (__cdecl **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)v3 + 32))(v3, &unk_FFE50E94, 0, 0, &v10); /*0xffe4fb90*/
  if ( result >= 0 ) /*0xffe4fb98*/
  {
    v6 = v10; /*0xffe4fb9e*/
    if ( *(_DWORD *)(v10 + 8) ) /*0xffe4fba2*/
    {
      for ( j = v10 + 16; ; j += 40 ) /*0xffe4fba7*/
      {
        PeiDebugPrint(64, asc_FFE50C40, v4); /*0xffe4fbb2*/
        v8 = (_BYTE *)NvramFindVariable(i, Attributes, &v11, j); /*0xffe4fbc5*/
        if ( v8 ) /*0xffe4fbd1*/
        {
          if ( NvramValidateStoreEntry(v8, j) ) /*0xffe4fbd7*/
          {
            PeiDebugPrint(64, asc_FFE50C68); /*0xffe4fbe7*/
            v9 = NvramGetVariablePayload(&p_n16); /*0xffe4fc04*/
            PeiDebugPrint(64, "PeiGetVariableAddressAmi 3\n"); /*0xffe4fc06*/
            if ( v9 ) /*0xffe4fc10*/
              break; /*0xffe4fc10*/
          }
        }
        if ( (unsigned int)++v4 >= *(_DWORD *)(v6 + 8) ) /*0xffe4fc19*/
          return -2147483634; /*0xffe4fc19*/
      }
      PeiDebugPrint(64, "PeiGetVariableAddressAmi 4\n"); /*0xffe4fc29*/
      *a3 = (int)v9; /*0xffe4fc34*/
      return 0; /*0xffe4fc36*/
    }
    else
    {
      return -2147483634; /*0xffe4fc1b*/
    }
  }
  return result; /*0xffe4fc3f*/
}


// Function: MmioAddrCalc @ 0xffe4fc47 (0x1e bytes)

int *__cdecl MmioAddrCalc(int a1, int a2, _DWORD *a3, int *a4)
{
  int v4; // ecx

  v4 = MemGetBaseAddress((int)a3) + (*a3 & 0xFFFFFFF); /*0xffe4fc5b*/
  *a4 = v4; /*0xffe4fc62*/
  return a4; /*0xffe4fc61*/
}


// Function: SpiFlashCycle @ 0xffe4fc65 (0xfe bytes)

unsigned int __cdecl SpiFlashCycle(unsigned __int64 a1, int a2, int a3, int a4, int a5, _DWORD *p_n3, _BYTE *a7)
{
  int v7; // ecx
  int v8; // esi
  __int16 v9; // ax
  int n0xFFFFFFF; // edi
  int n0xFFFFFFF_1; // ebx
  unsigned int result; // eax
  unsigned __int8 v13; // al
  char v14; // al
  bool v15; // [esp+17h] [ebp-5h]
  int v16; // [esp+18h] [ebp-4h]

  v16 = v7; /*0xffe4fc6e*/
  v8 = LpcReadConfig(1); /*0xffe4fc78*/
  v9 = IoRead16((unsigned __int16 *)v8); /*0xffe4fc7c*/
  v15 = v9 != -1; /*0xffe4fc8c*/
  if ( v9 == -1 ) /*0xffe4fc92*/
    *(_BYTE *)(v8 + 225) = 0; /*0xffe4fc94*/
  n0xFFFFFFF = 0xFFFFFFF; /*0xffe4fc9a*/
  n0xFFFFFFF_1 = 0xFFFFFFF; /*0xffe4fca5*/
  do /*0xffe4fcb5*/
  {
    if ( (IoRead16((unsigned __int16 *)(v8 + 216)) & 1) == 0 ) /*0xffe4fcb0*/
      break; /*0xffe4fcb0*/
    --n0xFFFFFFF_1; /*0xffe4fcb2*/
  }
  while ( n0xFFFFFFF_1 ); /*0xffe4fcb5*/
  if ( !n0xFFFFFFF_1 ) /*0xffe4fcb9*/
    goto LABEL_7; /*0xffe4fcb9*/
  *a7 = 4; /*0xffe4fcdd*/
  *(_DWORD *)(v8 + 208) = (unsigned __int16)a1 | (v16 << 24); /*0xffe4fce1*/
  *(_DWORD *)(v8 + 220) = RShiftU64(a1); /*0xffe4fcf3*/
  IoAndThenOr16(4864); /*0xffe4fcf9*/
  IoWrite16((unsigned __int16 *)(v8 + 218), 0xF000u); /*0xffe4fd0c*/
  *(_DWORD *)(v8 + 212) = *p_n3; /*0xffe4fd19*/
  IoOr16((unsigned __int16 *)(v8 + 216)); /*0xffe4fd1f*/
  do /*0xffe4fd35*/
  {
    v13 = IoRead16((unsigned __int16 *)(v8 + 216)); /*0xffe4fd26*/
    if ( (v13 & 1) == 0 ) /*0xffe4fd30*/
      break; /*0xffe4fd30*/
    --n0xFFFFFFF; /*0xffe4fd32*/
  }
  while ( n0xFFFFFFF ); /*0xffe4fd35*/
  if ( n0xFFFFFFF )
  {
    v14 = (v13 >> 1) & 3; /*0xffe4fd3d*/
    *a7 = v14; /*0xffe4fd3f*/
    result = v14 != 0 ? 0x80000007 : 0;
  }
  else
  {
LABEL_7:
    result = -2147483641; /*0xffe4fcbb*/
  }
  if ( !v15 ) /*0xffe4fd52*/
    *(_BYTE *)(v8 + 225) = 1; /*0xffe4fd54*/
  return result; /*0xffe4fd5b*/
}


// Function: CmosReadDiagStatus @ 0xffe4fd63 (0x4f bytes)

int CmosReadDiagStatus()
{
  unsigned __int8 v0; // al
  char n3; // al
  char n3_1; // cl

  v0 = __inbyte(0x70u); /*0xffe4fd69*/
  __outbyte(0x70u, v0 & 0x80 | 0x4A); /*0xffe4fd6e*/
  n3 = __inbyte(0x71u); /*0xffe4fd75*/
  n3_1 = n3; /*0xffe4fd76*/
  if ( (unsigned __int8)n3 <= 3u ) /*0xffe4fd7b*/
  {
LABEL_4:
    if ( !n3_1 ) /*0xffe4fd96*/
      return 0; /*0xffe4fd96*/
    goto LABEL_5; /*0xffe4fd96*/
  }
  n3_1 = n3; /*0xffe4fd7d*/
  if ( !n3 ) /*0xffe4fd85*/
  {
    n3_1 = MEMORY[0xFDAF0490] & 2 | 1; /*0xffe4fd91*/
    goto LABEL_4; /*0xffe4fd91*/
  }
LABEL_5:
  if ( n3_1 != -1 )
    return n3_1 != 1 ? -2147483578 : -2147483644;
  return 0; /*0xffe4fdae*/
}


// Function: X86ReadIdtr @ 0xffe4fdb2 (0x23 bytes)

void *__thiscall X86ReadIdtr(void *this)
{
  void *this_1; // eax

  if ( !this ) /*0xffe4fdb8*/
    PeiAssertCall((int)"e:\\hs\\MdePkg\\Library\\BaseLib\\X86ReadIdtr.c", 37, (int)"Idtr != ((void *) 0)"); /*0xffe4fdc7*/
  this_1 = this; /*0xffe4fdcd*/
  __sidt(this); /*0xffe4fdd0*/
  return this_1; /*0xffe4fdd4*/
}


// Function: MemAllocResource @ 0xffe4fdd5 (0x9b bytes)

int __cdecl MemAllocResource(_DWORD *a1, int n8)
{
  int v3; // [esp+Ch] [ebp-4h]

  v3 = sub_FFE4F72B(6); /*0xffe4fe05*/
  a1[1] = 16 * n8 + 16; /*0xffe4fe0e*/
  if ( !a1[4] && !a1[5] ) /*0xffe4fe2a*/
  {
    *(_DWORD *)(v3 + 16) = sub_FFE4F71C(5); /*0xffe4fe4f*/
    *(_DWORD *)(v3 + 20) = 0; /*0xffe4fe66*/
  }
  return 0; /*0xffe4fe6c*/
}


// Function: MemGetBaseAddress @ 0xffe4fe70 (0x17e bytes)

int __cdecl MemGetBaseAddress(int a1)
{
  int v2; // [esp+Ch] [ebp-Ch]
  int v3; // [esp+10h] [ebp-8h]
  int v4; // [esp+14h] [ebp-4h]

  if ( *(_DWORD *)(a1 + 12) ) /*0xffe4fe85*/
  {
    v3 = *(_DWORD *)(*(_DWORD *)(a1 + 12) + 4 * (unsigned __int16)*(_DWORD *)(a1 + 4) + 255544); /*0xffe4ff7b*/
    v4 = *(_DWORD *)(*(_DWORD *)(a1 + 12) + 4 * (unsigned __int16)*(_DWORD *)(a1 + 4) + 255560); /*0xffe4ff97*/
  }
  else
  {
    v2 = sub_FFE4F72B(6); /*0xffe4fe98*/
    if ( *(_DWORD *)(v2 + 4) ) /*0xffe4fe9e*/
    {
      v3 = *(_DWORD *)(v2 + 16 * (unsigned __int16)*(_DWORD *)(a1 + 4) + 20); /*0xffe4feb9*/
      v4 = *(_DWORD *)(v2 + 16 * (unsigned __int16)*(_DWORD *)(a1 + 4) + 16); /*0xffe4fed1*/
    }
    else
    {
      MemAllocResource(dword_FFE51398, 8); /*0xffe4fee4*/
      v3 = dword_FFE513AC[4 * (unsigned __int16)*(_DWORD *)(a1 + 4)]; /*0xffe4feff*/
      v4 = dword_FFE513A8[4 * (unsigned __int16)*(_DWORD *)(a1 + 4)]; /*0xffe4ff16*/
      if ( !v4 && !v3 ) /*0xffe4ff23*/
      {
        v4 = sub_FFE4F71C(5); /*0xffe4ff50*/
        v3 = 0; /*0xffe4ff5d*/
      }
    }
  }
  if ( !v4 && !v3 ) /*0xffe4ffa4*/
    return sub_FFE4F71C(5); /*0xffe4ffd1*/
  return v4; /*0xffe4ffea*/
}


// Function: NvramCopyMem @ 0xffe50054 (0x91 bytes)

unsigned int __cdecl NvramCopyMem(unsigned int dst, char *src, unsigned int n16)
{
  char *src_1; // esi
  unsigned int dst_1; // edi
  unsigned int n16_1; // ecx
  char v10; // dl
  char *n4; // eax
  unsigned int count; // eax
  int count_1; // ebx
  char n16_2; // al
  unsigned int v15; // ecx
  int n16_3; // eax

  __asm { pushfw } /*0xffe5005a*/
  src_1 = src; /*0xffe5005f*/
  dst_1 = dst; /*0xffe50062*/
  n16_1 = n16; /*0xffe50065*/
  v10 = 0; /*0xffe50068*/
  n4 = &src[-dst]; /*0xffe5006c*/
  if ( (unsigned int)src < dst ) /*0xffe5006e*/
  {
    n4 = (char *)(dst - (_DWORD)src); /*0xffe50073*/
    if ( (unsigned int)&src[n16] >= dst ) /*0xffe50077*/
    {
      src_1 = &src[n16]; /*0xffe50079*/
      dst_1 = n16 + dst; /*0xffe5007b*/
      v10 = 1; /*0xffe5007e*/
    }
  }
  if ( n16 < 4 || (unsigned int)n4 < 4 ) /*0xffe50089*/
    goto LABEL_19; /*0xffe50089*/
  count = (unsigned __int8)src_1 & 3; /*0xffe5008f*/
  count_1 = dst_1 & 3; /*0xffe50092*/
  if ( v10 ) /*0xffe50097*/
  {
    --src_1; /*0xffe50099*/
    --dst_1; /*0xffe5009a*/
  }
  if ( count == count_1 && count ) /*0xffe500a1*/
  {
    if ( !v10 ) /*0xffe500a5*/
      count = 4 - count; /*0xffe500a9*/
    qmemcpy((void *)dst_1, src_1, count); /*0xffe500af*/
    src_1 += count; /*0xffe500af*/
    dst_1 += count; /*0xffe500af*/
    n16_1 = n16 - count; /*0xffe500b1*/
  }
  if ( v10 ) /*0xffe500b5*/
  {
    src_1 -= 3; /*0xffe500b7*/
    dst_1 -= 3; /*0xffe500ba*/
  }
  n16_2 = n16_1; /*0xffe500bd*/
  v15 = n16_1 >> 2; /*0xffe500bf*/
  qmemcpy((void *)dst_1, src_1, 4 * v15); /*0xffe500c2*/
  src_1 += 4 * v15; /*0xffe500c2*/
  dst_1 += 4 * v15; /*0xffe500c2*/
  n16_3 = n16_2 & 3; /*0xffe500c4*/
  if ( n16_3 ) /*0xffe500c7*/
  {
    if ( v10 ) /*0xffe500cb*/
    {
      src_1 += 4; /*0xffe500cd*/
      dst_1 += 4; /*0xffe500d0*/
    }
    n16_1 = n16_3; /*0xffe500d3*/
LABEL_19:
    if ( v10 ) /*0xffe500d7*/
    {
      --src_1; /*0xffe500d9*/
      --dst_1; /*0xffe500da*/
    }
    qmemcpy((void *)dst_1, src_1, n16_1); /*0xffe500db*/
  }
  __asm { popfw } /*0xffe500dd*/
  return dst; /*0xffe500e0*/
}