Newer
Older
AMI-Aptio-BIOS-Reversed / AhciRecovery / AhciRecovery.c
@Ajax Dong Ajax Dong 2 days ago 98 KB Init
/*
 *AhciRecovery.c - Decompiled source for AhciRecovery.efi
 *
 *Copyright (c) HR650X BIOS Decompilation Project
 */

#include "AhciRecovery.h"

char *InternalMemCopyMem(char *dst, char *src, unsigned int count)
{
 unsigned int count_1; // edx char *dst_1; // edi char *src_1; // esi count_1 = count; /*0xffda6d7a*/
 if ( src < dst && &src[count - 1] >= dst ) /*0xffda6d88*/
 {
 src_1 = &src[count - 1]; /*0xffda6d9c*/
 dst_1 = &dst[count - 1]; /*0xffda6d9e*/
 }
 else
 {
 count_1 = count & 3; /*0xffda6d8c*/
 qmemcpy(dst, src, 4 * (count >> 2)); /*0xffda6d95*/
 src_1 = &src[4 * (count >> 2)]; /*0xffda6d95*/
 dst_1 = &dst[4 * (count >> 2)]; /*0xffda6d95*/
 }
 qmemcpy(dst_1, src_1, count_1); /*0xffda6da5*/
 return dst; /*0xffda6dac*/
}

void *InternalMemSetMem16(void *buf, unsigned int count, char value)
{
 memset(buf, value, count); /*0xffda6dbd*/
 return buf; /*0xffda6dc3*/
}

int InternalMemCopyMem8(int a1, int a2, int a3, int a4)
{
 do /*0xffda6e09*/
 {
 *(_DWORD *)(a1 + 8 *a2 - 8) = a3; /*0xffda6e01*/
 *(_DWORD *)(a1 + 8 *a2-- - 4) = a4; /*0xffda6e05*/
 }
 while ( a2 ); /*0xffda6e09*/
 return a1; /*0xffda6e0d*/
}

void *InternalMemSetMem32(void *buf, unsigned int count, int value)
{
 memset32(buf, value, count); /*0xffda6e1d*/
 return buf; /*0xffda6e23*/
}

EFI_STATUS ModuleEntryPoint(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
 int Signature; // eax int v3; // eax EFI_STATUS v4; // esi int ErrorLevel; // eax if ( !::SystemTable ) /*0xffda6e30*/
 {
 Signature = SystemTable->Hdr.Signature; /*0xffda6e32*/
 ::SystemTable = (int)SystemTable; /*0xffda6e34*/
 dword_FFDAB284 = *(_DWORD *)(Signature + 100); /*0xffda6e3d*/
 }
 v3 = (*(int ( **)(EFI_SYSTEM_TABLE *, void *))(LODWORD(SystemTable->Hdr.Signature) + 36))( /*0xffda6e4b*/
 SystemTable,
 &unk_FFDAB200);
 v4 = v3; /*0xffda6e4e*/
 if ( v3 < 0 ) /*0xffda6e54*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v3); /*0xffda6e61*/
 ErrorLevel = DebugGetErrorLevel(); /*0xffda6e69*/
 if ( ErrorLevel ) /*0xffda6e70*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffda6e81*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 2358,
 "!EFI_ERROR (Status)");
 }
 return v4; /*0xffda6e8a*/
}

int SataPortGetDeviceCount(int a1, int a2, _DWORD *a3)
{
 int result; // eax if ( !a2 ) /*0xffda6e91*/
 return -2147483646; /*0xffda6e93*/
 result = sub_FFDA6EBE(a1, a2 - 12, a3); /*0xffda6ea8*/
 if ( result >= 0 ) /*0xffda6eb2*/
 {
 *a3 = *(_DWORD *)(a2 + 33); /*0xffda6eb7*/
 return 0; /*0xffda6eb9*/
 }
 return result; /*0xffda6e98*/
}

int SataPortGetDevice(void *SystemTable, int a2, _DWORD *a3)
{
 int result; // eax if ( !a2 ) /*0xffda6ec5*/
 return -2147483646; /*0xffda6ecd*/
 if ( !*(_BYTE *)(a2 + 44) ) /*0xffda6ece*/
 {
 result = sub_FFDA77F9(SystemTable, a2); /*0xffda6eda*/
 if ( result < 0 ) /*0xffda6ee1*/
 return result; /*0xffda6ee1*/
 *(_BYTE *)(a2 + 44) = 1; /*0xffda6ee3*/
 }
 *a3 = *(_DWORD *)(a2 + 45); /*0xffda6eee*/
 return 0; /*0xffda6ecc*/
}

int SataPortRead(int SystemTable, int a2, unsigned int a3, _DWORD *a4)
{
 int v4; // esi int result; // eax _DWORD *v6; // esi if ( !a2 || !a3 || !a4 ) /*0xffda6f0c*/
 return -2147483646; /*0xffda6f3c*/
 v4 = *(_DWORD *)(a2 - 12 + 4 *a3 + 45); /*0xffda6f15*/
 if ( *(_BYTE *)(a2 + 32) || (result = sub_FFDA6F44(SystemTable, a2 - 12, a3, (_DWORD *)(v4 + 7)), result >= 0) ) /*0xffda6f2f*/
 {
 v6 = (_DWORD *)(v4 + 23); /*0xffda6f31*/
 *a4 = *v6++; /*0xffda6f36*/
 a4[1] = *v6++; /*0xffda6f37*/
 a4[2] = *v6; /*0xffda6f38*/
 a4[3] = v6[1]; /*0xffda6f39*/
 return 0; /*0xffda6f34*/
 }
 return result; /*0xffda6f41*/
}

int SataPortGetDeviceInfo(void *SystemTable, int a2, unsigned int a3, _DWORD *a4)
{
 int result; // eax int v5; // esi _DWORD *v6; // esi if ( !a3 || !a2 || !a4 ) /*0xffda6f5b*/
 return -2147483646; /*0xffda6f5b*/
 if ( !*(_BYTE *)(a2 + 44) ) /*0xffda6f5d*/
 {
 result = sub_FFDA77F9(SystemTable, a2); /*0xffda6f68*/
 if ( result < 0 ) /*0xffda6f6f*/
 return result; /*0xffda6f6f*/
 *(_BYTE *)(a2 + 44) = 1; /*0xffda6f71*/
 }
 if ( a3 > *(_DWORD *)(a2 + 45) ) /*0xffda6f78*/
 return -2147483646; /*0xffda6fa6*/
 v5 = *(_DWORD *)(a2 + 4 *a3 + 45); /*0xffda6f7a*/
 if ( !*(_BYTE *)(v5 + 39) ) /*0xffda6f7e*/
 {
 if ( *(_DWORD *)(v5 + 40) == 1 ) /*0xffda6f88*/
 sub_FFDA936E((int)SystemTable, v5); /*0xffda6f8f*/
 *(_BYTE *)(v5 + 39) = 1; /*0xffda6f94*/
 }
 v6 = (_DWORD *)(v5 + 7); /*0xffda6f9b*/
 *a4 = *v6++; /*0xffda6fa0*/
 a4[1] = *v6++; /*0xffda6fa1*/
 a4[2] = *v6; /*0xffda6fa2*/
 a4[3] = v6[1]; /*0xffda6fa3*/
 return 0; /*0xffda6fab*/
}

int SataPortReadExt(int SystemTable, int a2, unsigned int a3, unsigned __int64 a4, unsigned int a5, int a6)
{
 if ( a2 && a3 ) /*0xffda6fc0*/
 return sub_FFDA6FEB(SystemTable, a2 - 12, a3, a4, a5, a6); /*0xffda6fd8*/
 else return -2147483646; /*0xffda6fe2*/
}

int SataPortReadMultiBlock(
 void *SystemTable,
 int a2,
 unsigned int a3,
 unsigned __int64 a4,
 unsigned int a5,
 int a6)
{
 int result; // eax int v7; // edi int v8; // [esp+10h] [ebp-10h] BYREF int v9; // [esp+14h] [ebp-Ch]
 unsigned int v10; // [esp+18h] [ebp-8h]
 unsigned int v11; // [esp+1Ch] [ebp-4h]

 v8 = 0; /*0xffda6ff4*/
 v9 = 0; /*0xffda7005*/
 v10 = 0; /*0xffda7006*/
 v11 = 0; /*0xffda7007*/
 if ( !a2 || !a3 || !a6 ) /*0xffda701f*/
 return -2147483646; /*0xffda70ff*/
 if ( !a5 ) /*0xffda7029*/
 return 0; /*0xffda702d*/
 if ( !*(_BYTE *)(a2 + 44) ) /*0xffda7032*/
 {
 result = sub_FFDA77F9(SystemTable, a2); /*0xffda703d*/
 if ( result < 0 ) /*0xffda7044*/
 return result; /*0xffda7044*/
 *(_BYTE *)(a2 + 44) = 1; /*0xffda704a*/
 }
 v7 = *(_DWORD *)(a2 + 4 *a3 + 45); /*0xffda704e*/
 if ( *(_BYTE *)(v7 + 39) ) /*0xffda7052*/
 {
 (*(void ( **)(int *, int, int))(*(_DWORD *)SystemTable + 80))(&v8, v7 + 7, 16); /*0xffda7083*/
LABEL_13:
 if ( !(a5 % v11) ) /*0xffda708e*/
 {
 if ( !(_BYTE)v9 ) /*0xffda709c*/
 return -2147483636; /*0xffda70a3*/
 if ( *(_DWORD *)(v7 + 40) ) /*0xffda70a5*/
 return sub_FFDA8E17(v7, a6, a5, a4); /*0xffda70fd*/
 if ( a4 <= v10 && a4 + a5 / v11 <= v10 + 1 ) /*0xffda70cd*/
 return sub_FFDA8BAB(v7, a6, a5, a4, HIDWORD(a4), v11); /*0xffda70e4*/
 }
 return -2147483646; /*0xffda70cd*/
 }
 result = SataPortGetDeviceInfo(SystemTable, a2, a3, &v8); /*0xffda7062*/
 if ( !result ) /*0xffda706c*/
 goto LABEL_13; /*0xffda706c*/
 return result; /*0xffda7104*/
}

int __thiscall AhciEnumerateSataControllers(void *this)
{
 int MmioBase; // ebx unsigned __int8 LoopCount; // al char BusIndex; // dl int Status; // ebp unsigned __int64 BdfAddr; // kr00_8 int MiscFlags; // edx unsigned int MmioBase_2; // ecx int MiscFlags2; // edx int BAR5Space; // eax unsigned __int64 BdfAddr2; // kr08_8 int AllocStatus; // eax int AllocStatus_1; // esi int n6; // edx int CtrlrBase; // eax int *HobPtr; // edx int HobResult; // eax int SavedBusIdx; // ecx int ErrorLevel; // eax int DbgLvl2; // eax unsigned __int8 DevNum; // [esp+10h] [ebp-14h] BYREF unsigned __int8 BusNum; // [esp+11h] [ebp-13h] BYREF unsigned __int8 LoopCount_1; // [esp+12h] [ebp-12h]
 char UseMmio; // [esp+13h] [ebp-11h]
 int FuncNum; // [esp+14h] [ebp-10h] BYREF int PciIoHandle; // [esp+18h] [ebp-Ch] BYREF unsigned int MmioBase_1; // [esp+1Ch] [ebp-8h] BYREF int MiscFlags2_1; // [esp+20h] [ebp-4h]

 MmioBase = ::MmioBase; /*0xffda710f*/
 LoopCount = 0; /*0xffda7115*/
 PciIoHandle = 0; /*0xffda711c*/
 MmioBase_1 = 0; /*0xffda7120*/
 MiscFlags2_1 = 0; /*0xffda7124*/
 BusNum = 0; /*0xffda7128*/
 DevNum = 0; /*0xffda712c*/
 LOBYTE(FuncNum) = 0; /*0xffda7130*/
 LoopCount_1 = 0; /*0xffda7134*/
 if ( byte_FFDAB331 ) /*0xffda713e*/
 {
 MmioBase = ::MmioBase - 0x100000; /*0xffda7140*/
 ::MmioBase -= 0x100000; /*0xffda7146*/
 }
 BusIndex = n6; /*0xffda714c*/
 while ( (unsigned __int8)BusIndex < 6u ) /*0xffda7155*/
 {
 Status = (*(int ( **)(void *, void *, _DWORD, _DWORD, int *))(*(_DWORD *)this + 32))( /*0xffda7171*/
 this,
 &unk_FFDAB1F0,
 LoopCount,
 0,
 &PciIoHandle);
 if ( Status < 0 ) /*0xffda7178*/
 goto LABEL_23; /*0xffda7178*/
 ++LoopCount_1; /*0xffda717e*/
 if ( (*(int ( **)(void *, int, unsigned __int8 *, unsigned __int8 *, int *))PciIoHandle)( /*0xffda719e*/
 this,
 PciIoHandle,
 &BusNum,
 &DevNum,
 &FuncNum) < 0 )
 goto LABEL_18; /*0xffda719e*/
 BdfAddr = (unsigned __int8)FuncNum + ((DevNum + ((unsigned __int64)BusNum << 8)) << 8); /*0xffda71d8*/
 if ( (*(int ( **)(void *, int, int, int, _DWORD, unsigned int *))dword_FFDAB284)( /*0xffda71f4*/
 this,
 dword_FFDAB284,
 3,
 ((_DWORD)BdfAddr << 8) + 36,
 ((BdfAddr << 8) + 36) >> 32,
 &MmioBase_1) < 0 )
 goto LABEL_18; /*0xffda71f4*/
 dword_FFDAB2F0 = -16; /*0xffda7207*/
 dword_FFDAB290 = -1; /*0xffda720f*/
 if ( (MmioBase_1 & 4) != 0 ) /*0xffda720d*/
 {
 MiscFlags = -1; /*0xffda7216*/
 dword_FFDAB294 = -1; /*0xffda7219*/
 byte_FFDAB330 = 1; /*0xffda7220*/
 }
 else
 {
 MiscFlags = 0; /*0xffda7230*/
 dword_FFDAB294 = 0; /*0xffda7232*/
 byte_FFDAB330 = 0; /*0xffda7238*/
 }
 MmioBase_2 = MmioBase_1 & 0xFFFFFFF0; /*0xffda723e*/
 ::MiscFlags = MiscFlags; /*0xffda7242*/
 MiscFlags2 = MiscFlags2_1 & MiscFlags; /*0xffda724a*/
 if ( __PAIR64__(MmioBase_1 & 0xFFFFFFF0, MiscFlags2) ) /*0xffda7250*/
 {
 ::BAR5Space = 0; /*0xffda72e5*/
 UseMmio = 0; /*0xffda72ec*/
 MmioBase_1 &= 0xFFFFFFF0; /*0xffda72f1*/
 MiscFlags2_1 = MiscFlags2; /*0xffda72f5*/
 }
 else
 {
 BAR5Space = AhciReadBAR5Space(BusNum, DevNum, FuncNum); /*0xffda7262*/
 MiscFlags2_1 = 0; /*0xffda7267*/
 ::BAR5Space = BAR5Space; /*0xffda726c*/
 MmioBase_1 = MmioBase; /*0xffda727f*/
 BdfAddr2 = (unsigned __int8)FuncNum + ((DevNum + ((unsigned __int64)BusNum << 8)) << 8); /*0xffda72a5*/
 if ( (*(int ( **)(void *, int, int, int, _DWORD, unsigned int *))(dword_FFDAB284 + 4))( /*0xffda72d4*/
 this,
 dword_FFDAB284,
 (byte_FFDAB330 != 0) + 2,
 ((_DWORD)BdfAddr2 << 8) + 36,
 ((BdfAddr2 << 8) + 36) >> 32,
 &MmioBase_1) < 0 )
 goto LABEL_18; /*0xffda72d4*/
 MmioBase_2 = MmioBase_1; /*0xffda72da*/
 UseMmio = 1; /*0xffda72de*/
 }
 if ( (*(int ( **)(void *, int, unsigned int))(PciIoHandle + 4))(this, PciIoHandle, MmioBase_2) < 0 ) /*0xffda7308*/
 {
LABEL_18:
 BusIndex = n6; /*0xffda73de*/
 goto LABEL_19; /*0xffda73de*/
 }
 AllocStatus = (*(int ( **)(void *, int, int *))(*(_DWORD *)this + 76))( /*0xffda7322*/
 this,
 78,
 &ControllerInfo[(unsigned __int8)n6]);
 AllocStatus_1 = AllocStatus; /*0xffda7325*/
 if ( AllocStatus < 0 ) /*0xffda732c*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus); /*0xffda73fc*/
 ErrorLevel = DebugGetErrorLevel(); /*0xffda7404*/
 if ( ErrorLevel ) /*0xffda740b*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffda7417*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 615,
 "!EFI_ERROR (Status1)");
 return AllocStatus_1; /*0xffda7417*/
 }
 (*(void ( **)(int, int, _DWORD))(*(_DWORD *)this + 84))(ControllerInfo[(unsigned __int8)n6], 78, 0); /*0xffda7346*/
 n6 = (unsigned __int8)n6; /*0xffda7349*/
 *(_BYTE *)(ControllerInfo[(unsigned __int8)n6] + 70) = BusNum; /*0xffda7363*/
 *(_BYTE *)(ControllerInfo[n6] + 71) = DevNum; /*0xffda7371*/
 *(_BYTE *)(ControllerInfo[n6] + 72) = FuncNum; /*0xffda737f*/
 *(_DWORD *)ControllerInfo[n6] = MmioBase_1; /*0xffda738d*/
 CtrlrBase = ControllerInfo[n6]; /*0xffda738f*/
 HobPtr = (int *)::HobPtr; /*0xffda739a*/
 *(_BYTE *)(CtrlrBase + 77) = UseMmio; /*0xffda73a0*/
 n7 = FuncNum; /*0xffda73a7*/
 n0x1F = DevNum; /*0xffda73b0*/
 HobResult = HobCreateOrAppend(HobPtr, (int)&unk_FFDAB218); /*0xffda73b5*/
 MmioBase += ::BAR5Space; /*0xffda73c0*/
 SavedBusIdx = (unsigned __int8)n6; /*0xffda73c7*/
 BusIndex = ++n6; /*0xffda73ca*/
 *(_DWORD *)(ControllerInfo[SavedBusIdx] + 73) = HobResult; /*0xffda73d9*/
LABEL_19:
 if ( Status ) /*0xffda73e6*/
 {
LABEL_23:
 if ( ControllerInfo[0] ) /*0xffda7420*/
 {
 if ( !byte_FFDAB331 ) /*0xffda7434*/
 goto LABEL_27; /*0xffda7434*/
 }
 else if ( byte_FFDAB331 ) /*0xffda7429*/
 {
LABEL_27:
 ::MmioBase += 0x100000; /*0xffda7436*/
 }
 return 0; /*0xffda7442*/
 }
 LoopCount = LoopCount_1; /*0xffda73e8*/
 }
 AllocStatus_1 = -2147483639; /*0xffda7444*/
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", -2147483639); /*0xffda7454*/
 DbgLvl2 = DebugGetErrorLevel(); /*0xffda745c*/
 if ( DbgLvl2 ) /*0xffda7463*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl2 + 4))( /*0xffda7474*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 520,
 "!EFI_ERROR (Status)");
 return AllocStatus_1; /*0xffda747c*/
}

int AhciReadBAR5Space(unsigned __int8 BusNum, unsigned __int8 n0x1F, unsigned __int8 n7)
{
 unsigned __int64 v3; // rdi _DWORD v5[2]; // [esp+10h] [ebp-8h] BYREF v5[0] = 0; /*0xffda7494*/
 v5[1] = 0; /*0xffda74a7*/
 v3 = ((n7 + ((n0x1F + ((unsigned __int64)BusNum << 8)) << 8)) << 8) + 36; /*0xffda74cd*/
 (*(void ( **)(int, int, int, _DWORD, _DWORD, int *))(dword_FFDAB284 + 4))( /*0xffda74ec*/
 SystemTable,
 dword_FFDAB284,
 (byte_FFDAB330 != 0) + 2,
 v3,
 HIDWORD(v3),
 &dword_FFDAB290);
 (*(void ( **)(int, int, int, _DWORD, _DWORD, _DWORD *))dword_FFDAB284)( /*0xffda7511*/
 SystemTable,
 dword_FFDAB284,
 (byte_FFDAB330 != 0) + 2,
 v3,
 HIDWORD(v3),
 v5);
 return -(v5[0] & dword_FFDAB2F0); /*0xffda7524*/
}

int __thiscall AhciConfigRootBridge(void *this)
{
 unsigned int MmioBase; // eax int result; // eax int LoopCount; // edx int *SataDevInfoPtr; // ebx unsigned __int8 *SataDevInfo; // edi unsigned __int8 BridgeIndex; // cl _BYTE *BridgeEntry; // eax unsigned __int64 BdfAddr; // kr20_8 unsigned __int8 LoopCount2; // bl int AllocStatus; // eax int AllocStatus_1; // esi int n12_1; // edx int CtrlrIdx; // eax int CtrlrInfo; // edi unsigned __int64 BdfAddr64; // kr30_8 int ErrorLevel; // eax int DbgLvl2; // eax unsigned __int64 BdfAddr642; // [esp-24h] [ebp-48h]
 char ByteVal; // [esp+17h] [ebp-Dh] BYREF int n12; // [esp+18h] [ebp-Ch]
 _DWORD RegPair[2]; // [esp+1Ch] [ebp-8h] BYREF RegPair[0] = 0; /*0xffda7536*/
 RegPair[1] = 0; /*0xffda753a*/
 if ( ControllerInfo[0] || !byte_FFDAB331 ) /*0xffda754c*/
 {
 MmioBase = ::MmioBase; /*0xffda755f*/
 }
 else
 {
 MmioBase = ::MmioBase - 0x100000; /*0xffda7553*/
 ::MmioBase -= 0x100000; /*0xffda7558*/
 }
 result = AhciPciBusEnumerate((int *)HobPtr, 0, MmioBase, 1); /*0xffda756f*/
 if ( result < 0 ) /*0xffda7578*/
 return result; /*0xffda7578*/
 DebugPrint(64, "\n No Root bridge Entry added for Ahci device Enumeration "); /*0xffda7585*/
 LoopCount = 12; /*0xffda758e*/
 ByteVal = 0; /*0xffda758f*/
 SataDevInfoPtr = SataDevInfoPtr; /*0xffda7593*/
 n12 = 12; /*0xffda7598*/
 do /*0xffda7675*/
 {
 SataDevInfo = (unsigned __int8 *)*SataDevInfoPtr; /*0xffda759c*/
 if ( *SataDevInfoPtr && !SataDevInfo[5] ) /*0xffda75a6*/
 {
 BridgeIndex = 0; /*0xffda75b0*/
 while ( 1 ) /*0xffda75b5*/
 {
 BridgeEntry = (_BYTE *)dword_FFDAB2B0[BridgeIndex]; /*0xffda75b5*/
 if ( BridgeEntry ) /*0xffda75be*/
 {
 if ( *BridgeEntry == SataDevInfo[1] ) /*0xffda75c5*/
 break; /*0xffda75c5*/
 }
 if ( ++BridgeIndex >= 6u ) /*0xffda75d0*/
 {
 BdfAddr = SataDevInfo[4] + ((((unsigned __int64)*SataDevInfo << 8) + SataDevInfo[3]) << 8); /*0xffda7602*/
 (*(void ( **)(void *, int, _DWORD, int, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda7617*/
 this,
 dword_FFDAB284,
 0,
 ((_DWORD)BdfAddr << 8) + 25,
 ((BdfAddr << 8) + 25) >> 32,
 &ByteVal);
 BdfAddr642 = ((*(unsigned __int8 *)(*SataDevInfoPtr + 4) /*0xffda765c*/
 + ((((unsigned __int64)*(unsigned __int8 *)*SataDevInfoPtr << 8)
 + *(unsigned __int8 *)(*SataDevInfoPtr + 3)) << 8)) << 8)
 + 26;
 (*(void ( **)(void *, int, _DWORD, _DWORD, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda7661*/
 this,
 dword_FFDAB284,
 0,
 BdfAddr642,
 HIDWORD(BdfAddr642),
 &ByteVal);
 LoopCount = n12; /*0xffda7664*/
 break; /*0xffda7664*/
 }
 }
 }
 ++SataDevInfoPtr; /*0xffda766b*/
 n12 = --LoopCount; /*0xffda7671*/
 }
 while ( LoopCount ); /*0xffda7675*/
 LoopCount2 = 0; /*0xffda767b*/
 while ( 1 ) /*0xffda7680*/
 {
 n12 = LoopCount2; /*0xffda7680*/
 if ( !dword_FFDAB2B0[LoopCount2] ) /*0xffda768c*/
 goto LABEL_20; /*0xffda768c*/
 if ( (unsigned __int8)n6 >= 6u ) /*0xffda7699*/
 break; /*0xffda7699*/
 AllocStatus = (*(int ( **)(void *, int, int *))(*(_DWORD *)this + 76))( /*0xffda76b0*/
 this,
 78,
 &ControllerInfo[(unsigned __int8)n6]);
 AllocStatus_1 = AllocStatus; /*0xffda76b3*/
 if ( AllocStatus < 0 ) /*0xffda76ba*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus); /*0xffda77a2*/
 ErrorLevel = DebugGetErrorLevel(); /*0xffda77aa*/
 if ( ErrorLevel ) /*0xffda77b1*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffda77bd*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 987,
 "!EFI_ERROR (Status)");
 return AllocStatus_1; /*0xffda77bd*/
 }
 (*(void ( **)(int, int, _DWORD))(*(_DWORD *)this + 84))(ControllerInfo[(unsigned __int8)n6], 78, 0); /*0xffda76d5*/
 n12_1 = n12; /*0xffda76e1*/
 CtrlrIdx = (unsigned __int8)n6++; /*0xffda76e5*/
 CtrlrInfo = ControllerInfo[CtrlrIdx]; /*0xffda76f0*/
 *(_BYTE *)(CtrlrInfo + 70) = *(_BYTE *)dword_FFDAB2B0[n12]; /*0xffda7700*/
 *(_BYTE *)(CtrlrInfo + 71) = *(_BYTE *)(dword_FFDAB2B0[n12_1] + 1); /*0xffda770d*/
 *(_BYTE *)(CtrlrInfo + 72) = *(_BYTE *)(dword_FFDAB2B0[n12_1] + 2); /*0xffda771a*/
 *(_DWORD *)CtrlrInfo = *(_DWORD *)(dword_FFDAB2B0[n12_1] + 4); /*0xffda7727*/
 *(_BYTE *)(CtrlrInfo + 77) = 1; /*0xffda7729*/
 *(_DWORD *)(CtrlrInfo + 73) = *(_DWORD *)(dword_FFDAB2B0[n12_1] + 8); /*0xffda7737*/
 BdfAddr64 = *(unsigned __int8 *)(CtrlrInfo + 72) /*0xffda776b*/
 + ((*(unsigned __int8 *)(CtrlrInfo + 71) + ((unsigned __int64)*(unsigned __int8 *)(CtrlrInfo + 70) << 8)) << 8);
 (*(void ( **)(void *, int, int, _DWORD, _DWORD, _DWORD *))dword_FFDAB284)( /*0xffda777a*/
 this,
 dword_FFDAB284,
 1,
 (_DWORD)BdfAddr64 << 8,
 BdfAddr64 >> 24,
 RegPair);
LABEL_20:
 if ( ++LoopCount2 > (unsigned __int8)byte_FFDAB2E9 ) /*0xffda7787*/
 return 0; /*0xffda778d*/
 }
 AllocStatus_1 = -2147483639; /*0xffda77bf*/
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", -2147483639); /*0xffda77cf*/
 DbgLvl2 = DebugGetErrorLevel(); /*0xffda77d7*/
 if ( DbgLvl2 ) /*0xffda77de*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl2 + 4))( /*0xffda77ef*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 980,
 "!EFI_ERROR (Status)");
 return AllocStatus_1; /*0xffda778f*/
}

int AhciDeviceDetectionAndConfig(void *SystemTable, int a2)
{
 void *InitStatus_1; // ecx int result; // eax void *InitStatus; // ecx int *ControllerInfo; // ebx int inited; // esi unsigned __int8 PortMapShifted; // dl unsigned __int8 PortIndex; // dh int PortIndex_1; // esi int Index; // eax unsigned __int8 DeviceInfo; // bl int HobHandle; // eax int IsAtapi; // esi int v16; // eax bool v17; // zf unsigned __int8 AtaCount; // [esp+12h] [ebp-16h]
 unsigned __int8 SavedPortMap; // [esp+13h] [ebp-15h]
 unsigned __int8 SavedPortIdx; // [esp+14h] [ebp-14h]
 int ControllerCount; // [esp+18h] [ebp-10h]
 _DWORD DevInfoArr[3]; // [esp+1Ch] [ebp-Ch] BYREF DevInfoArr[0] = 786690; /*0xffda780a*/
 AtaCount = 0; /*0xffda781b*/
 DevInfoArr[1] = 167985616; /*0xffda781f*/
 DevInfoArr[2] = 0; /*0xffda7827*/
 DebugPrint(64, "\nDevice Detection and Configuration starts\n"); /*0xffda782b*/
 HobPtr = HobCreateOrAppend(0, (int)DevInfoArr); /*0xffda783f*/
 LOBYTE(InitStatus_1) = 0; /*0xffda7844*/
 AhciSetupPciIoAccess(InitStatus_1); /*0xffda7846*/
 result = AhciEnumerateSataControllers(SystemTable); /*0xffda784d*/
 if ( result >= 0 )
 {
 result = AhciConfigRootBridge(SystemTable); /*0xffda785c*/
 if ( result >= 0 )
 {
 if ( (*(int ( **)(void *, void *, _DWORD, _DWORD, int *))(*(_DWORD *)SystemTable + 32))(
 SystemTable,
 &unk_FFDAB1A0,
 0,
 0,
 &dword_FFDAB2C8) >= 0 )
 {
 LOBYTE(InitStatus) = 1; /*0xffda788c*/
 AhciSetupPciIoAccess(InitStatus); /*0xffda788e*/
 ControllerInfo = ::ControllerInfo; /*0xffda7893*/
 ControllerCount = 6; /*0xffda7898*/
 do /*0xffda7955*/
 {
 if ( *ControllerInfo ) /*0xffda78a0*/
 {
 inited = AhciInitController(SystemTable, *ControllerInfo); /*0xffda78b3*/
 DebugPrint( /*0xffda78cc*/
 64,
 "\n AhciInitController Status for the SATA Controller at Bus:%x, Device :%x, Function :%x is :%r",
 *(unsigned __int8 *)(*ControllerInfo + 70),
 *(unsigned __int8 *)(*ControllerInfo + 71),
 *(unsigned __int8 *)(*ControllerInfo + 72),
 inited);
 if ( inited >= 0 ) /*0xffda78d6*/
 {
 *(_DWORD *)(*ControllerInfo + 8) = *(_DWORD *)(*(_DWORD *)*ControllerInfo + 12); /*0xffda78e1*/
 if ( *(_DWORD *)(*ControllerInfo + 8) ) /*0xffda78e6*/
 {
 PortMapShifted = *(_BYTE *)(*ControllerInfo + 8); /*0xffda78ec*/
 for ( PortIndex = 0; ; ++PortIndex ) /*0xffda78ef*/
 {
 SavedPortIdx = PortIndex; /*0xffda7941*/
 SavedPortMap = PortMapShifted; /*0xffda7945*/
 if ( !PortMapShifted ) /*0xffda794b*/
 break; /*0xffda794b*/
 if ( (PortMapShifted & 1) != 0 ) /*0xffda78f6*/
 {
 PortIndex_1 = PortIndex; /*0xffda78fa*/
 if ( ((1 << PortIndex) & *(_DWORD *)(*ControllerInfo + 8)) != 0 ) /*0xffda7907*/
 {
 Index = AhciDetectAndConfigureDevice((int)SystemTable, a2, (int *)*ControllerInfo, PortIndex, 255); /*0xffda7917*/
 DebugPrint( /*0xffda792d*/
 64,
 "\nDetectAndConfigureDevice Status at Port:%x and PMPort:%x is %r\n",
 PortIndex_1,
 255,
 Index);
 PortMapShifted = SavedPortMap; /*0xffda7932*/
 PortIndex = SavedPortIdx; /*0xffda7939*/
 }
 }
 PortMapShifted >>= 1; /*0xffda793d*/
 }
 }
 }
 }
 ++ControllerInfo; /*0xffda794d*/
 --ControllerCount; /*0xffda7950*/
 }
 while ( ControllerCount ); /*0xffda7955*/
 (*(void ( **)(void *))(*(_DWORD *)SystemTable + 36))(SystemTable); /*0xffda7963*/
 DeviceInfo = 0; /*0xffda7967*/
 if ( *(_DWORD *)(a2 + 45) ) /*0xffda7969*/
 {
 HobHandle = 0; /*0xffda7970*/
 do /*0xffda79c4*/
 {
 IsAtapi = *(_DWORD *)(a2 + 4 *HobHandle + 49); /*0xffda7972*/
 word_FFDAB224 = *(unsigned __int8 *)(IsAtapi + 4); /*0xffda797a*/
 LOBYTE(HobHandle) = *(_BYTE *)(IsAtapi + 5); /*0xffda7980*/
 if ( (_BYTE)HobHandle == 0xFF ) /*0xffda7985*/
 LOWORD(HobHandle) = -1; /*0xffda7987*/
 else LOWORD(HobHandle) = (unsigned __int8)HobHandle; /*0xffda798e*/
 ::HobHandle = HobHandle; /*0xffda7991*/
 word_FFDAB228 = 0; /*0xffda7999*/
 v16 = HobCreateOrAppend(*(int **)(*(_DWORD *)IsAtapi + 73), (int)&DevInfoArr_); /*0xffda79a9*/
 v17 = *(_DWORD *)(IsAtapi + 40) == 0; /*0xffda79ae*/
 *(_DWORD *)(IsAtapi + 63) = v16; /*0xffda79b3*/
 if ( v17 ) /*0xffda79b6*/
 ++AtaCount; /*0xffda79b8*/
 HobHandle = ++DeviceInfo; /*0xffda79be*/
 }
 while ( (unsigned int)DeviceInfo < *(_DWORD *)(a2 + 45) ); /*0xffda79c4*/
 }
 DebugPrint(64, "\nNumber of AHCI ATA Device Found:%d \n", AtaCount); /*0xffda79d3*/
 DebugPrint(64, "\nNumber of AHCI ATAPI Device Found: %d \n", *(_DWORD *)(a2 + 45) - AtaCount);
 return 0; /*0xffda79f0*/
 }
 else
 {
 return -2147483641; /*0xffda7882*/
 }
 }
 }
 return result; /*0xffda79f2*/
}

int AhciSetupPciIoAccess(void *InitStatus)
{
 void ( **PcdDb)(int, _DWORD); // eax unsigned __int64 MmioBase_1; // rax _DWORD *v3; // eax __int64 v4; // rax void *v5; // ecx int ( **v6)(int); // eax int (**v7)(void); // eax int ( **v8)(int); // eax void *v10; // [esp-4h] [ebp-14h]
 void *v11; // [esp-4h] [ebp-14h]
 void *v12; // [esp-4h] [ebp-14h]
 __int64 MmioBase; // [esp+8h] [ebp-8h] BYREF MmioBase = 0; /*0xffda7a03*/
 if ( (_BYTE)InitStatus ) /*0xffda7a0b*/
 {
 BYTE4(MmioBase) = byte_FFDAB2E8 - 1; /*0xffda7a14*/
 PcdDb = (void ( **)(int, _DWORD))PeiGetPcdDb(InitStatus); /*0xffda7a17*/
 PcdDb[15](13, HIDWORD(MmioBase)); /*0xffda7a21*/
 LODWORD(MmioBase_1) = PeiSetMemAttr((unsigned int)MmioBase); /*0xffda7a2b*/
 }
 else
 {
 v3 = PeiGetPcdDb(InitStatus); /*0xffda7a35*/
 v4 = ((__int64 ( *)(int))v3[4])(14); /*0xffda7a3c*/
 v5 = v10; /*0xffda7a41*/
 if ( !v4 ) /*0xffda7a42*/
 {
 AhciAllocPciResource(&MmioBase); /*0xffda7a47*/
 PeiSetMemAttr(MmioBase); /*0xffda7a52*/
 v5 = v11; /*0xffda7a58*/
 }
 v6 = (int ( **)(int))PeiGetPcdDb(v5); /*0xffda7a59*/
 MmioBase = v6[4](14); /*0xffda7a64*/
 v7 = (int (**)(void))PeiGetPcdDb(v12); /*0xffda7a69*/
 byte_FFDAB2E8 = v7[1]() + 1; /*0xffda7a76*/
 v8 = (int ( **)(int))PeiGetPcdDb((void *)0xD); /*0xffda7a7b*/
 LODWORD(MmioBase_1) = v8[4](5); /*0xffda7a82*/
 if ( (unsigned int)MmioBase <= MmioBase_1 ) /*0xffda7a92*/
 byte_FFDAB331 = 1; /*0xffda7a94*/
 }
 return MmioBase_1; /*0xffda7a9b*/
}

int __thiscall AhciAllocPciResource(__int64 *this)
{
 _DWORD *v2; // eax void *v3; // ecx _DWORD *v4; // eax __int64 v5; // rax unsigned int v6; // esi unsigned int v7; // ebx _WORD *i; // edx int n0xFFFF; // ecx __int64 v10; // rax _DWORD *v11; // eax v2 = sub_FFDAA7E4(this); /*0xffda7aa5*/
 *this = ((__int64 ( *)(int))v2[4])(5); /*0xffda7aaf*/
 v4 = sub_FFDAA7E4(v3); /*0xffda7ab4*/
 v5 = ((__int64 ( *)(int))v4[4])(5); /*0xffda7abb*/
 v6 = v5 - 0x100000; /*0xffda7ac2*/
 v7 = ((unsigned __int64)(v5 + 4293918720LL) >> 32) - 1; /*0xffda7aca*/
 for ( i = (_WORD *)sub_FFDAA921(); ; i = (_WORD *)(v10 + *(unsigned __int16 *)(v10 + 2)) ) /*0xffda7ad2*/
 {
 LODWORD(v10) = sub_FFDAA98F(n0xFFFF, i); /*0xffda7b08*/
 if ( !(_DWORD)v10 ) /*0xffda7b0f*/
 break; /*0xffda7b0f*/
 n0xFFFF = 0xFFFF; /*0xffda7ad6*/
 if ( *(_WORD *)v10 == 0xFFFF ) /*0xffda7ade*/
 break; /*0xffda7ade*/
 if ( *(_QWORD *)(v10 + 32) <= __PAIR64__(v7, v6) ) /*0xffda7aea*/
 {
 n0xFFFF = (*(_QWORD *)(v10 + 32) + *(_QWORD *)(v10 + 40)) >> 32; /*0xffda7af5*/
 if ( *(_QWORD *)(v10 + 32) + *(_QWORD *)(v10 + 40) >= __PAIR64__(v7, v6) ) /*0xffda7b00*/
 {
 v11 = sub_FFDAA7E4((void *)n0xFFFF); /*0xffda7b13*/
 v10 = ((__int64 ( *)(int))v11[4])(5) + 0x10000000; /*0xffda7b1d*/
 *this = v10; /*0xffda7b26*/
 return v10; /*0xffda7b26*/
 }
 }
 }
 return v10; /*0xffda7b2b*/
}

int AhciReadPciEcamConfig(
 unsigned __int8 a1,
 unsigned __int8 n0x1F,
 unsigned __int8 n7,
 char a4,
 char a5,
 int a6)
{
 char v6; // bh unsigned __int8 v7; // ch unsigned __int8 v8; // cl char v9; // cl unsigned __int8 v10; // bl int v11; // eax int result; // eax int v13; // eax _BYTE *v14; // eax unsigned __int8 v15; // al int *SataDevInfoPtr; // ecx int *SataDevInfoPtr_1; // edi int n12; // edx int n12_2; // ebp _BYTE *v20; // esi int v21; // esi unsigned __int8 n0x1Fa_1; // bl unsigned __int8 v23; // bh _BYTE *v24; // eax __int64 v25; // kr00_8 unsigned __int8 v26; // [esp+11h] [ebp-3h] BYREF unsigned __int8 n0x1Fa; // [esp+12h] [ebp-2h]
 unsigned __int8 v28; // [esp+13h] [ebp-1h]
 int n12_1; // [esp+20h] [ebp+Ch]

 v6 = 0; /*0xffda7b32*/
 n0x1Fa = n0x1F; /*0xffda7b34*/
 v7 = a1; /*0xffda7b38*/
 v26 = 0; /*0xffda7b3a*/
 v28 = a1; /*0xffda7b41*/
 if ( !a5 ) /*0xffda7b49*/
 {
 v8 = 0; /*0xffda7b4b*/
 while ( !dword_FFDAB2B0[v8] ) /*0xffda7b58*/
 {
 if ( ++v8 >= 6u ) /*0xffda7b5f*/
 goto LABEL_5; /*0xffda7b5f*/
 }
 v13 = v8; /*0xffda7bac*/
 v9 = a4; /*0xffda7baf*/
 v14 = (_BYTE *)dword_FFDAB2B0[v13]; /*0xffda7bb3*/
 if ( *v14 != a4 ) /*0xffda7bbc*/
 goto LABEL_6; /*0xffda7bbc*/
 if ( !v14[3] ) /*0xffda7bc2*/
 return -2147483645; /*0xffda7bf7*/
 result = AhciPciSetSubordinateBus(v7, n0x1F, n7, HIWORD(a6)); /*0xffda7bd3*/
 if ( result < 0 ) /*0xffda7bdd*/
 return result; /*0xffda7bdd*/
 n0x1F = n0x1Fa; /*0xffda7be3*/
 v6 = 1; /*0xffda7be7*/
 v7 = v28; /*0xffda7be9*/
 }
LABEL_5:
 v9 = a4; /*0xffda7b61*/
LABEL_6:
 v10 = 0; /*0xffda7b65*/
 while ( 1 ) /*0xffda7b6a*/
 {
 v11 = dword_FFDAB300[v10]; /*0xffda7b6a*/
 if ( v11 ) /*0xffda7b73*/
 {
 if ( v9 == *(_BYTE *)v11 ) /*0xffda7b77*/
 {
 v6 = 1; /*0xffda7b7d*/
 result = AhciPciSetSubordinateBus(v7, n0x1F, n7, *(_WORD *)(v11 + 4)); /*0xffda7b87*/
 if ( result < 0 ) /*0xffda7b91*/
 return result; /*0xffda7b91*/
 }
 }
 if ( ++v10 >= 0xCu ) /*0xffda7b9c*/
 break; /*0xffda7b9c*/
 v9 = a4; /*0xffda7b9e*/
 n0x1F = n0x1Fa; /*0xffda7ba2*/
 v7 = v28; /*0xffda7ba6*/
 }
 if ( !v6 && !a5 ) /*0xffda7c04*/
 {
 if ( byte_FFDAB331 ) /*0xffda7c0c*/
 MmioBase += 0x100000; /*0xffda7c0e*/
 else MmioBase -= 0x100000; /*0xffda7c1a*/
 }
 v15 = v26; /*0xffda7c24*/
 SataDevInfoPtr = SataDevInfoPtr; /*0xffda7c28*/
 SataDevInfoPtr_1 = SataDevInfoPtr; /*0xffda7c31*/
 n12 = 12; /*0xffda7c35*/
 n12_1 = 12; /*0xffda7c36*/
 n12_2 = 12; /*0xffda7c3a*/
 do /*0xffda7c62*/
 {
 v20 = (_BYTE *)*SataDevInfoPtr_1; /*0xffda7c3c*/
 if ( *SataDevInfoPtr_1 && a4 == *v20 ) /*0xffda7c44*/
 {
 if ( v15 ) /*0xffda7c48*/
 {
 if ( v20[2] <= v15 ) /*0xffda7c54*/
 goto LABEL_30; /*0xffda7c54*/
 v15 = v20[2]; /*0xffda7c56*/
 }
 else
 {
 v15 = v20[2]; /*0xffda7c4a*/
 }
 v26 = v15; /*0xffda7c58*/
 }
LABEL_30:
 ++SataDevInfoPtr_1; /*0xffda7c5c*/
 --n12_2; /*0xffda7c5f*/
 }
 while ( n12_2 ); /*0xffda7c62*/
 if ( v15 ) /*0xffda7c66*/
 {
 do /*0xffda7c80*/
 {
 v21 = *SataDevInfoPtr; /*0xffda7c68*/
 if ( *SataDevInfoPtr ) /*0xffda7c68*/
 {
 if ( a4 == *(_BYTE *)(v21 + 1) ) /*0xffda7c71*/
 {
 *(_BYTE *)(v21 + 2) = v15; /*0xffda7c73*/
 v15 = v26; /*0xffda7c76*/
 }
 }
 ++SataDevInfoPtr; /*0xffda7c7a*/
 --n12; /*0xffda7c7d*/
 }
 while ( n12 ); /*0xffda7c80*/
 n0x1Fa_1 = n0x1Fa; /*0xffda7c82*/
 v23 = v28; /*0xffda7c86*/
 }
 else
 {
 n0x1Fa_1 = n0x1Fa; /*0xffda7c8c*/
 v23 = v28; /*0xffda7c90*/
 do /*0xffda7cc1*/
 {
 v24 = (_BYTE *)*SataDevInfoPtr; /*0xffda7c94*/
 if ( *SataDevInfoPtr ) /*0xffda7c94*/
 {
 if ( *v24 == v28 && v24[3] == n0x1Fa ) /*0xffda7ca1*/
 {
 n12 = n12_1; /*0xffda7caa*/
 if ( v24[4] == n7 ) /*0xffda7cae*/
 v26 = v24[1]; /*0xffda7cb3*/
 }
 }
 ++SataDevInfoPtr; /*0xffda7cb7*/
 n12_1 = --n12; /*0xffda7cbd*/
 }
 while ( n12 ); /*0xffda7cc1*/
 }
 v25 = n7 + ((n0x1Fa_1 + ((unsigned __int64)v23 << 8)) << 8); /*0xffda7cf5*/
 (*(void ( **)(int, int, _DWORD, int, _DWORD, unsigned __int8 *))(dword_FFDAB284 + 4))( /*0xffda7d0f*/
 SystemTable,
 dword_FFDAB284,
 0,
 ((_DWORD)v25 << 8) + 26,
 (unsigned __int64)((v25 << 8) + 26) >> 32,
 &v26);
 return 0; /*0xffda7d17*/
}

bool AhciIsPciDevicePresent(unsigned __int8 a1, unsigned __int8 n0x1F, unsigned __int8 n7)
{
 int v3; // esi int v5; // [esp+8h] [ebp-8h] BYREF char v6; // [esp+Eh] [ebp-2h] BYREF char v7; // [esp+Fh] [ebp-1h] BYREF v7 = 0; /*0xffda7d31*/
 v6 = 0; /*0xffda7d3d*/
 v3 = (n7 + ((n0x1F + (a1 << 8)) << 8)) << 8; /*0xffda7d40*/
 v5 = 0; /*0xffda7d48*/
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))dword_FFDAB284)( /*0xffda7d5c*/
 SystemTable,
 dword_FFDAB284,
 0,
 v3 + 25,
 0,
 &v7);
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))dword_FFDAB284)( /*0xffda7d74*/
 SystemTable,
 dword_FFDAB284,
 0,
 v3 + 26,
 0,
 &v6);
 (*(void ( **)(int, int, int, int, _DWORD, int *))dword_FFDAB284)( /*0xffda7d8d*/
 SystemTable,
 dword_FFDAB284,
 1,
 v3 + 32,
 0,
 &v5);
 return v7 && v6 && (_WORD)v5; /*0xffda7da8*/
}

int AhciPciSetSubordinateBus(
 unsigned __int8 a1,
 unsigned __int8 n0x1F,
 unsigned __int8 n7,
 unsigned __int16 a4)
{
 int v6; // eax int v8; // esi unsigned __int16 v9; // si int v10; // edx int v11; // eax int v12; // ecx char v13; // [esp+13h] [ebp-Dh] BYREF int v14; // [esp+14h] [ebp-Ch] BYREF int v15; // [esp+18h] [ebp-8h]

 v14 = 0; /*0xffda7dc2*/
 if ( (unsigned __int8)n0xC < 0xCu ) /*0xffda7dc6*/
 {
 v8 = (n7 + ((n0x1F + (a1 << 8)) << 8)) << 8; /*0xffda7e24*/
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))dword_FFDAB284)( /*0xffda7e34*/
 SystemTable,
 dword_FFDAB284,
 0,
 v8 + 4,
 0,
 &v13);
 v13 |= 6u; /*0xffda7e36*/
 (*(void ( **)(int, int, int, int, _DWORD, int *))dword_FFDAB284)( /*0xffda7e54*/
 SystemTable,
 dword_FFDAB284,
 1,
 v8 + 32,
 0,
 &v14);
 if ( !(_WORD)v14 || (unsigned __int16)v14 > a4 ) /*0xffda7e67*/
 (*(void ( **)(int, int, int, int, _DWORD, unsigned __int16 *))(dword_FFDAB284 + 4))( /*0xffda7e7f*/
 SystemTable,
 dword_FFDAB284,
 1,
 v8 + 32,
 0,
 &a4);
 (*(void ( **)(int, int, int, int, _DWORD, unsigned __int16 *))(dword_FFDAB284 + 4))( /*0xffda7e9f*/
 SystemTable,
 dword_FFDAB284,
 1,
 v8 + 34,
 0,
 &a4);
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda7eb6*/
 SystemTable,
 dword_FFDAB284,
 0,
 v8 + 4,
 0,
 &v13);
 v9 = a4; /*0xffda7ec3*/
 BYTE2(v15) = n7; /*0xffda7ec8*/
 v10 = *(_DWORD *)SystemTable; /*0xffda7ed3*/
 LOBYTE(v15) = a1; /*0xffda7ed5*/
 BYTE1(v15) = n0x1F; /*0xffda7ed9*/
 HIBYTE(v15) = 1; /*0xffda7ee4*/
 if ( (*(int ( **)(int, int, int *))(v10 + 76))(SystemTable, 6, &dword_FFDAB300[(unsigned __int8)n0xC]) >= 0 ) /*0xffda7ef5*/
 {
 v11 = (unsigned __int8)n0xC++; /*0xffda7f04*/
 v12 = dword_FFDAB300[v11]; /*0xffda7f0f*/
 *(_DWORD *)v12 = v15; /*0xffda7f1a*/
 *(_WORD *)(v12 + 4) = v9; /*0xffda7f1e*/
 return 0; /*0xffda7f1c*/
 }
 else
 {
 return -2147483639; /*0xffda7ef7*/
 }
 }
 else
 {
 sub_FFDAA8D9(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", -2147483639); /*0xffda7dd8*/
 v6 = sub_FFDAA8A8(); /*0xffda7de0*/
 if ( v6 ) /*0xffda7de7*/
 (*(void ( **)(const char *, int, const char *))(v6 + 4))( /*0xffda7df8*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 1472,
 "!EFI_ERROR (Status)");
 return -2147483639; /*0xffda7dfe*/
 }
}

char AhciPciFindRootBridgeByBus(char a1, char a2)
{
 char result; // al int *v3; // edi int n12; // ebp unsigned __int8 *v5; // ebx unsigned __int64 v6; // kr10_8 _BYTE v7[7]; // [esp+10h] [ebp-8h] BYREF char v8; // [esp+17h] [ebp-1h]

 result = a1; /*0xffda7f30*/
 v7[0] = a2; /*0xffda7f32*/
 v8 = a1; /*0xffda7f38*/
 v3 = dword_FFDAB340; /*0xffda7f3c*/
 n12 = 12; /*0xffda7f41*/
 do /*0xffda7fa7*/
 {
 v5 = (unsigned __int8 *)*v3; /*0xffda7f42*/
 if ( *v3 ) /*0xffda7f42*/
 {
 if ( result == v5[1] ) /*0xffda7f4b*/
 {
 v6 = v5[4] + ((((unsigned __int64)*v5 << 8) + v5[3]) << 8); /*0xffda7f7d*/
 (*(void ( **)(int, int, _DWORD, int, _DWORD, _BYTE *))(dword_FFDAB284 + 4))( /*0xffda7f97*/
 SystemTable,
 dword_FFDAB284,
 0,
 ((_DWORD)v6 << 8) + 26,
 ((v6 << 8) + 26) >> 32,
 v7);
 result = v8; /*0xffda7f9a*/
 }
 }
 ++v3; /*0xffda7fa1*/
 --n12; /*0xffda7fa4*/
 }
 while ( n12 ); /*0xffda7fa7*/
 return result; /*0xffda7fa9*/
}

{"addr":"0xffda7fb0","code":"int AhciPciBusEnumerate(int *HobPtr, unsigned __int8 a2, unsigned int MmioBase, char a4)\n{\n unsigned __int8 n0x1F_1; // bh\n int v5; // esi\n unsigned __int8 n7_2; // bl\n int n0x1F_2; // ebp\n int v8; // esi\n char v9; // al\n int v10; // eax\n char v11; // al\n unsigned int MmioBase_2; // edi\n int *HobPtr_2; // esi\n int v14; // ecx\n int v15; // edx\n unsigned __int8 v16; // bl\n int result; // eax\n unsigned __int64 v18; // kr00_8\n unsigned __int8 v19; // cl\n _BYTE *v20; // edx\n int v21; // esi\n unsigned int MmioBase_3; // esi\n __int64 v23; // kr08_8\n int v24; // edi\n unsigned int *v25; // edi\n int v26; // eax\n int ErrorLevel; // eax\n int v28; // [esp-Ch] [ebp-68h]\n char v30; // [esp+11h] [ebp-4Bh]\n char v31; // [esp+12h] [ebp-4Ah] BYREF\n unsigned __int8 n0x1F; // [esp+13h] [ebp-49h]\n __int16 v33; // [esp+14h] [ebp-48h] BYREF\n unsigned int MmioBase_1; // [esp+18h] [ebp-44h] BYREF\n unsigned int v35; // [esp+1Ch] [ebp-40h] BYREF\n unsigned __int8 n7[4]; /... [12405 chars total]","refs":[{"addr":"0xffdab2a0","name":"MmioBase"},{"addr":"0xffdab331","name":"byte_FFDAB331"},{"addr":"0xffdaa8d9","name":"DebugPrint"},{"addr":"0xffdaac70","name":"aAhcirecoveryEn","string":"\n AhciRecovery: Enumerating Bus:%x Dev:%x Func:%x"},{"addr":"0xffdaaa90","name":"aAssertEfiError","string":"\nASSERT_EFI_ERROR (Status = %r)\n"},{"addr":"0xffdaa8a8","name":"DebugGetErrorLevel"},{"addr":"0xffdaaac8","name":"aEHsAmimodulepk","string":"e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c"},{"addr":"0xffdaaab4","name":"aEfiErrorStatus","string":"!EFI_ERROR (Status)"},{"addr":"0xffdab29c","name":"n6"},{"addr":"0xffdab2e9","name":"byte_FFDAB2E9"}]}
Output truncated. Run: curl -o .ida-mcp/e8ed2f09-657a-466e-94e0-40f015e800dc.json http://127.0.0.1:13352/output/e8ed2f09-657a-466e-94e0-40f015e800dc.json int AhciResetAndInitControllers()
{
 int *ControllerInfo; // ebx int ControllerCount; // ebp int CtrlrPtr; // eax _DWORD *AhciBase; // esi unsigned __int8 PortIndex; // cl int PortOffset; // edi int PollStatus; // eax int ErrorLevel; // eax int PollStatus2; // eax int DbgLvl2; // eax unsigned __int64 PairResult; // kr20_8 int *SataDevInfoPtr; // ebx int SataDevCount; // ebp unsigned __int64 DevBdfAddr; // kr30_8 unsigned __int8 DevIndex; // al _BYTE *DevEntryPtr; // eax int DevInfoBase; // ecx unsigned __int8 BusNum; // dl unsigned __int8 DevFuncNum; // dh unsigned __int8 RegValue; // cl int RegOffset; // esi unsigned __int64 BdfAddr64; // [esp-3Ch] [ebp-54h]
 unsigned __int64 BdfAddr642; // [esp-24h] [ebp-3Ch]
 unsigned __int8 PortIndex_1; // [esp+11h] [ebp-7h]
 unsigned __int8 DevIndex_1; // [esp+11h] [ebp-7h]
 char ByteValue; // [esp+12h] [ebp-6h] BYREF char StatusFlags; // [esp+13h] [ebp-5h] BYREF int MmioBase; // [esp+14h] [ebp-4h] BYREF MmioBase = 0; /*0xffda8540*/
 ByteValue = 0; /*0xffda854b*/
 ControllerInfo = ::ControllerInfo; /*0xffda8550*/
 ControllerCount = 6; /*0xffda8555*/
 do /*0xffda86f0*/
 {
 CtrlrPtr = *ControllerInfo; /*0xffda8556*/
 if ( *ControllerInfo ) /*0xffda8556*/
 {
 AhciBase = *(_DWORD **)CtrlrPtr; /*0xffda8560*/
 PortIndex = 0; /*0xffda8562*/
 PortIndex_1 = 0; /*0xffda8564*/
 if ( *(_BYTE *)(CtrlrPtr + 68) ) /*0xffda8568*/
 {
 do /*0xffda867b*/
 {
 if ( ((1 << PortIndex) & *(_DWORD *)(*ControllerInfo + 8)) != 0 ) /*0xffda8580*/
 {
 PortOffset = PortIndex << 7; /*0xffda8591*/
 *(_DWORD *)((char *)AhciBase + PortOffset + 280) &= ~1u; /*0xffda859b*/
 PollStatus = AhciPortPollRegister((int)AhciBase, PortIndex_1, 0x18u, 0x8000, 500); /*0xffda85a3*/
 if ( PollStatus < 0 ) /*0xffda85ad*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", PollStatus); /*0xffda85ba*/
 ErrorLevel = DebugGetErrorLevel(); /*0xffda85c2*/
 if ( ErrorLevel ) /*0xffda85c9*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffda85da*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 2013,
 "!EFI_ERROR (Status)");
 }
 *(_DWORD *)((char *)AhciBase + PortOffset + 280) &= ~0x10u; /*0xffda85e6*/
 PollStatus2 = AhciPortPollRegister((int)AhciBase, PortIndex_1, 0x18u, 0x4000, 500); /*0xffda85fa*/
 if ( PollStatus2 < 0 ) /*0xffda8604*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", PollStatus2); /*0xffda8611*/
 DbgLvl2 = DebugGetErrorLevel(); /*0xffda8619*/
 if ( DbgLvl2 ) /*0xffda8620*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl2 + 4))( /*0xffda8631*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 2025,
 "!EFI_ERROR (Status)");
 }
 *(_DWORD *)((char *)AhciBase + PortOffset + 260) = _PAIR64__(0, 0); /*0xffda8640*/
 *(_DWORD *)((char *)AhciBase + PortOffset + 256) = 0; /*0xffda864b*/
 *(_DWORD *)((char *)AhciBase + PortOffset + 268) = _PAIR64__(0, 0); /*0xffda8657*/
 *(_DWORD *)((char *)AhciBase + PortOffset + 264) = 0; /*0xffda8661*/
 }
 PortIndex = PortIndex_1 + 1; /*0xffda8672*/
 PortIndex_1 = PortIndex; /*0xffda8674*/
 }
 while ( PortIndex < *(_BYTE *)(*ControllerInfo + 68) ); /*0xffda867b*/
 }
 if ( (*AhciBase & 0x40000) == 0 ) /*0xffda8688*/
 AhciBase[1] = 0; /*0xffda868a*/
 if ( *(_BYTE *)(*ControllerInfo + 77) ) /*0xffda8693*/
 {
 PairResult = *(unsigned __int8 *)(*ControllerInfo + 72) /*0xffda86ca*/
 + ((*(unsigned __int8 *)(*ControllerInfo + 71)
 + ((unsigned __int64)*(unsigned __int8 *)(*ControllerInfo + 70) << 8)) << 8);
 (*(void ( **)(int, int, int, int, _DWORD, int *))(dword_FFDAB284 + 4))( /*0xffda86e4*/
 SystemTable,
 dword_FFDAB284,
 2,
 ((_DWORD)PairResult << 8) + 36,
 ((PairResult << 8) + 36) >> 32,
 &MmioBase);
 }
 }
 ++ControllerInfo; /*0xffda86ea*/
 --ControllerCount; /*0xffda86ed*/
 }
 while ( ControllerCount ); /*0xffda86f0*/
 SataDevInfoPtr = ::SataDevInfoPtr; /*0xffda86f8*/
 SataDevCount = 12; /*0xffda86fd*/
 do /*0xffda88d7*/
 {
 if ( *SataDevInfoPtr ) /*0xffda86fe*/
 {
 DevBdfAddr = *(unsigned __int8 *)(*SataDevInfoPtr + 4) /*0xffda8738*/
 + ((((unsigned __int64)*(unsigned __int8 *)*SataDevInfoPtr << 8)
 + *(unsigned __int8 *)(*SataDevInfoPtr + 3)) << 8);
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda8752*/
 SystemTable,
 dword_FFDAB284,
 0,
 ((_DWORD)DevBdfAddr << 8) + 24,
 ((DevBdfAddr << 8) + 24) >> 32,
 &ByteValue);
 BdfAddr642 = ((*(unsigned __int8 *)(*SataDevInfoPtr + 4) /*0xffda8797*/
 + ((((unsigned __int64)*(unsigned __int8 *)*SataDevInfoPtr << 8)
 + *(unsigned __int8 *)(*SataDevInfoPtr + 3)) << 8)) << 8)
 + 25;
 (*(void ( **)(int, int, _DWORD, _DWORD, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda87a1*/
 SystemTable,
 dword_FFDAB284,
 0,
 BdfAddr642,
 HIDWORD(BdfAddr642),
 &ByteValue);
 BdfAddr64 = ((*(unsigned __int8 *)(*SataDevInfoPtr + 4) /*0xffda87e6*/
 + ((((unsigned __int64)*(unsigned __int8 *)*SataDevInfoPtr << 8)
 + *(unsigned __int8 *)(*SataDevInfoPtr + 3)) << 8)) << 8)
 + 26;
 (*(void ( **)(int, int, _DWORD, _DWORD, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda87f0*/
 SystemTable,
 dword_FFDAB284,
 0,
 BdfAddr64,
 HIDWORD(BdfAddr64),
 &ByteValue);
 DevIndex = 0; /*0xffda87f6*/
 DevIndex_1 = 0; /*0xffda87f8*/
 do /*0xffda88cb*/
 {
 DevEntryPtr = (_BYTE *)dword_FFDAB300[DevIndex]; /*0xffda87ff*/
 if ( !DevEntryPtr ) /*0xffda8808*/
 break; /*0xffda8808*/
 DevInfoBase = *SataDevInfoPtr; /*0xffda880e*/
 BusNum = *(_BYTE *)*SataDevInfoPtr; /*0xffda8810*/
 if ( *DevEntryPtr == BusNum ) /*0xffda8814*/
 {
 DevFuncNum = *(_BYTE *)(DevInfoBase + 3); /*0xffda881a*/
 if ( DevEntryPtr[1] == DevFuncNum ) /*0xffda8820*/
 {
 RegValue = *(_BYTE *)(DevInfoBase + 4); /*0xffda8826*/
 if ( DevEntryPtr[2] == RegValue ) /*0xffda882c*/
 {
 RegOffset = (RegValue + ((DevFuncNum + (BusNum << 8)) << 8)) << 8; /*0xffda884f*/
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))dword_FFDAB284)( /*0xffda8861*/
 SystemTable,
 dword_FFDAB284,
 0,
 RegOffset + 4,
 0,
 &StatusFlags);
 StatusFlags &= 0xF9u; /*0xffda8863*/
 (*(void ( **)(int, int, int, int, _DWORD, int *))(dword_FFDAB284 + 4))( /*0xffda8881*/
 SystemTable,
 dword_FFDAB284,
 1,
 RegOffset + 32,
 0,
 &MmioBase);
 (*(void ( **)(int, int, int, int, _DWORD, int *))(dword_FFDAB284 + 4))( /*0xffda889d*/
 SystemTable,
 dword_FFDAB284,
 1,
 RegOffset + 34,
 0,
 &MmioBase);
 (*(void ( **)(int, int, _DWORD, int, _DWORD, char *))(dword_FFDAB284 + 4))( /*0xffda88b9*/
 SystemTable,
 dword_FFDAB284,
 0,
 RegOffset + 4,
 0,
 &StatusFlags);
 }
 }
 }
 DevIndex = DevIndex_1 + 1; /*0xffda88c3*/
 DevIndex_1 = DevIndex; /*0xffda88c5*/
 }
 while ( DevIndex < 0xCu ); /*0xffda88cb*/
 }
 ++SataDevInfoPtr; /*0xffda88d1*/
 --SataDevCount; /*0xffda88d4*/
 }
 while ( SataDevCount ); /*0xffda88d7*/
 return 0; /*0xffda88dd*/
}

int HobBuildFromData(int *SystemTable, _BYTE *a2)
{
 int v5; // eax int v6; // ecx int v7; // edi int v8; // esi int v9; // [esp+8h] [ebp-4h] BYREF if ( !a2 ) /*0xffda88f0*/
 return 0; /*0xffda88f2*/
 v5 = sub_FFDA892B(a2); /*0xffda88fa*/
 v6 = *SystemTable; /*0xffda88ff*/
 v7 = v5; /*0xffda8902*/
 v9 = 0; /*0xffda8904*/
 (*(void ( **)(int *, int, int *))(v6 + 76))(SystemTable, v5, &v9); /*0xffda8910*/
 v8 = v9; /*0xffda8916*/
 (*(void ( **)(int, _BYTE *, int))(*SystemTable + 80))(v9, a2, v7); /*0xffda891d*/
 return v8; /*0xffda8927*/
}

int __thiscall HobCalcTotalSize(_BYTE *this)
{
 _BYTE *this_1; // edx int v3; // esi int v4; // eax this_1 = this; /*0xffda892b*/
 if ( !this ) /*0xffda892f*/
 return 0; /*0xffda8931*/
 v3 = 0; /*0xffda8935*/
 while ( 1 ) /*0xffda8938*/
 {
 if ( *this_1 == 127 && this_1[1] == 0xFF ) /*0xffda8943*/
 return v3 + 4; /*0xffda8963*/
 v4 = ((unsigned __int8)this_1[3] << 8) + (unsigned __int8)this_1[2]; /*0xffda8950*/
 if ( !*this_1 || !v4 ) /*0xffda8958*/
 break; /*0xffda8958*/
 v3 += v4; /*0xffda895a*/
 this_1 += v4; /*0xffda895c*/
 }
 return v3; /*0xffda8933*/
}

int __usercall HobCreateOrAppend@<eax>(int *HobPtr@<edx>, int DevInfoArr)
{
 int SystemTable; // ebp int *HobPtr_1; // esi int DevInfoArra_3; // eax int v6; // edi int v7; // ecx int v8; // edx int DevInfoArra_1; // [esp+Ch] [ebp-8h] BYREF int DevInfoArra_2; // [esp+10h] [ebp-4h]
 int DevInfoArra; // [esp+18h] [ebp+4h]

 SystemTable = SystemTable; /*0xffda8972*/
 HobPtr_1 = HobPtr; /*0xffda8979*/
 if ( DevInfoArr ) /*0xffda897d*/
 {
 if ( HobPtr ) /*0xffda899a*/
 v6 = HobCalcTotalSize(HobPtr) - 4; /*0xffda89a3*/
 else v6 = 0; /*0xffda89a8*/
 v7 = *(unsigned __int8 *)(DevInfoArr + 3); /*0xffda89aa*/
 v8 = *(_DWORD *)SystemTable; /*0xffda89b2*/
 DevInfoArra_1 = 0; /*0xffda89b5*/
 (*(void ( **)(int, int, int *))(v8 + 76))( /*0xffda89cb*/
 SystemTable,
 v6 + (v7 << 8) + *(unsigned __int8 *)(DevInfoArr + 2) + 4,
 &DevInfoArra_1);
 DevInfoArra_2 = DevInfoArra_1; /*0xffda89d5*/
 DevInfoArra = DevInfoArra_1; /*0xffda89d9*/
 if ( v6 ) /*0xffda89df*/
 {
 (*(void ( **)(int, int *, int))(*(_DWORD *)SystemTable + 80))(DevInfoArra_1, HobPtr_1, v6); /*0xffda89e7*/
 DevInfoArra += v6; /*0xffda89ed*/
 }
 (*(void ( **)(int, int, int))(*(_DWORD *)SystemTable + 80))( /*0xffda8a08*/
 DevInfoArra,
 DevInfoArr,
 *(unsigned __int8 *)(DevInfoArr + 2) + (*(unsigned __int8 *)(DevInfoArr + 3) << 8));
 DevInfoArra_3 = DevInfoArra_2; /*0xffda8a1c*/
 *(_DWORD *)(*(unsigned __int8 *)(DevInfoArr + 2) + DevInfoArra + (*(unsigned __int8 *)(DevInfoArr + 3) << 8)) = dword_FFDAB23C; /*0xffda8a26*/
 }
 else
 {
 if ( !HobPtr ) /*0xffda8986*/
 HobPtr = &dword_FFDAB23C; /*0xffda8990*/
 return HobBuildFromData((int *)SystemTable, HobPtr); /*0xffda898b*/
 }
 return DevInfoArra_3; /*0xffda8a29*/
}

int AhciRecoveryInstallProtocol(int a1)
{
 int AllocStatus; // eax int DbgLvl; // eax int ProtocolBase; // eax int InstallStatus; // eax int ErrorLevel; // eax int InstallStatus2; // eax int InstallStatus2_1; // esi int DbgLvl3; // eax int ProtocolBase_1; // [esp+4h] [ebp-4h] BYREF ProtocolBase_1 = 0; /*0xffda8a33*/
 if ( byte_FFDAB288 ) /*0xffda8a3d*/
 return 0; /*0xffda8a3f*/
 AllocStatus = (*(int ( **)(int, int, int *))(*(_DWORD *)a1 + 76))(a1, 97, &ProtocolBase_1); /*0xffda8a55*/
 if ( AllocStatus >= 0 ) /*0xffda8a5d*/
 {
 (*(void ( **)(int, int, _DWORD))(*(_DWORD *)a1 + 84))(ProtocolBase_1, 97, 0); /*0xffda8aa5*/
 *(_BYTE *)(ProtocolBase_1 + 44) = 0; /*0xffda8ab2*/
 *(_DWORD *)(ProtocolBase_1 + 45) = 0; /*0xffda8ab9*/
 ProtocolBase = ProtocolBase_1; /*0xffda8abc*/
 *(_DWORD *)(ProtocolBase_1 + 36) = 1229146177; /*0xffda8ac0*/
 *(_DWORD *)(ProtocolBase + 40) = 1128616543; /*0xffda8ac7*/
 *(_DWORD *)ProtocolBase_1 = SataPortGetDevice; /*0xffda8ad2*/
 *(_DWORD *)(ProtocolBase_1 + 4) = SataPortGetDeviceInfo; /*0xffda8adc*/
 *(_DWORD *)(ProtocolBase_1 + 8) = SataPortReadMultiBlock; /*0xffda8ae7*/
 ::ProtocolBase = ProtocolBase_1; /*0xffda8af2*/
 InstallStatus = (*(int ( **)(int, void *))(*(_DWORD *)a1 + 24))(a1, &unk_FFDAB240); /*0xffda8af9*/
 if ( InstallStatus < 0 ) /*0xffda8b10*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", InstallStatus); /*0xffda8b19*/
 ErrorLevel = DebugGetErrorLevel(); /*0xffda8b21*/
 if ( ErrorLevel ) /*0xffda8b28*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffda8b31*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 2318,
 "!EFI_ERROR (Status)");
 }
 *(_DWORD *)(ProtocolBase_1 + 20) = SataPortGetDeviceCount; /*0xffda8b41*/
 *(_DWORD *)(ProtocolBase_1 + 24) = SataPortRead; /*0xffda8b4c*/
 *(_DWORD *)(ProtocolBase_1 + 28) = SataPortReadExt; /*0xffda8b57*/
 dword_FFDAB254 = ProtocolBase_1 + 12; /*0xffda8b65*/
 InstallStatus2 = (*(int ( **)(int, void *))(*(_DWORD *)a1 + 24))(a1, &unk_FFDAB24C); /*0xffda8b6c*/
 InstallStatus2_1 = InstallStatus2; /*0xffda8b6f*/
 if ( InstallStatus2 < 0 ) /*0xffda8b75*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", InstallStatus2); /*0xffda8b7e*/
 DbgLvl3 = DebugGetErrorLevel(); /*0xffda8b86*/
 if ( DbgLvl3 ) /*0xffda8b8d*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl3 + 4))( /*0xffda8b96*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 2327,
 "!EFI_ERROR (Status)");
 }
 byte_FFDAB288 = 1; /*0xffda8b9d*/
 return InstallStatus2_1; /*0xffda8ba4*/
 }
 else
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus); /*0xffda8a6a*/
 DbgLvl = DebugGetErrorLevel(); /*0xffda8a72*/
 if ( DbgLvl ) /*0xffda8a79*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl + 4))( /*0xffda8a8a*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciRecovery.c",
 2301,
 "!EFI_ERROR (Status)");
 return -2147483639; /*0xffda8a90*/
 }
}

int AtaNonDataCommand(int a1, int a2, unsigned int a3, unsigned int a4, unsigned int a5, unsigned int a6)
{
 unsigned int n256; // ebx unsigned int v7; // ebp int v8; // edi unsigned int v9; // eax unsigned int n256_1; // esi __int16 v11; // ax unsigned int v13; // ecx unsigned int n256_2; // eax char v15; // [esp+13h] [ebp-41h]
 unsigned int v17; // [esp+1Ch] [ebp-38h]
 unsigned int v18; // [esp+1Ch] [ebp-38h]
 int v20; // [esp+2Ch] [ebp-28h] BYREF unsigned int v21; // [esp+30h] [ebp-24h]
 __int16 v22; // [esp+36h] [ebp-1Eh]
 char v23; // [esp+38h] [ebp-1Ch]
 char v24; // [esp+39h] [ebp-1Bh]
 char v25; // [esp+3Ah] [ebp-1Ah]
 char v26; // [esp+3Bh] [ebp-19h]
 char v27; // [esp+3Ch] [ebp-18h]
 char v28; // [esp+3Dh] [ebp-17h]
 char n64; // [esp+3Eh] [ebp-16h]
 char n36; // [esp+3Fh] [ebp-15h]
 int v31; // [esp+58h] [ebp+4h]
 unsigned int v32; // [esp+58h] [ebp+4h]
 unsigned int v33; // [esp+64h] [ebp+10h]
 int v34; // [esp+64h] [ebp+10h]
 unsigned int v35; // [esp+64h] [ebp+10h]

 n256 = 256; /*0xffda8bbf*/
 v15 = *(_BYTE *)(a1 + 44); /*0xffda8bc4*/
 if ( v15 ) /*0xffda8bd0*/
 n256 = 0x2000; /*0xffda8bd2*/
 v7 = a6; /*0xffda8bdb*/
 if ( a6 > a3 ) /*0xffda8be5*/
 v7 = a3; /*0xffda8be7*/
 v8 = 0; /*0xffda8beb*/
 v9 = a3 / v7; /*0xffda8bed*/
 n256_1 = a3 / v7; /*0xffda8bf4*/
 if ( v15 )
 {
 if ( v9 )
 {
 v17 = a5; /*0xffda8c12*/
 v31 = a4; /*0xffda8c1a*/
 while ( 1 )
 {
 v33 = v8 < 0 || v8 <= 0 && n256_1 <= n256 ? n256_1 : n256;
 (*(void ( **)(int *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(&v20, 37, 0); /*0xffda8c42*/
 n64 = 64; /*0xffda8c4c*/
 v22 = v33; /*0xffda8c51*/
 v11 = sub_FFDAA85A(v31, v17); /*0xffda8c5e*/
 v26 = v11; /*0xffda8c6c*/
 v25 = BYTE1(v31); /*0xffda8c73*/
 v28 = HIBYTE(v11); /*0xffda8c7c*/
 v20 = a2; /*0xffda8c87*/
 v27 = BYTE2(v31); /*0xffda8c8f*/
 v23 = v31; /*0xffda8c9b*/
 v24 = HIBYTE(v31); /*0xffda8ca3*/
 n36 = 36; /*0xffda8cab*/
 v34 = v7 *v33; /*0xffda8cb0*/
 v21 = v34; /*0xffda8cb4*/
 if ( sub_FFDA9D23((int *)a1, (int)&v20) < 0 ) /*0xffda8cc0*/
 break; /*0xffda8cc0*/
 a2 += v34; /*0xffda8cc8*/
 v17 = (v21 / v7 + __PAIR64__(v17, v31)) >> 32; /*0xffda8cda*/
 v31 += v21 / v7; /*0xffda8cd6*/
 v8 = (__PAIR64__(v8, n256_1) - n256) >> 32; /*0xffda8ce1*/
 n256_1 -= n256; /*0xffda8ce1*/
 if ( __SPAIR64__(v8, n256_1) <= 0 ) /*0xffda8cf3*/
 return 0; /*0xffda8cf3*/
 }
 return -2147483641; /*0xffda8d03*/
 }
 }
 else if ( v9 )
 {
 v18 = a5; /*0xffda8d22*/
 v32 = a4; /*0xffda8d26*/
 while ( 1 )
 {
 v35 = v8 < 0 || v8 <= 0 && n256_1 <= n256 ? n256_1 : 0;
 (*(void ( **)(int *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(&v20, 37, 0); /*0xffda8d4f*/
 v22 = v35; /*0xffda8d64*/
 v23 = v32; /*0xffda8d6b*/
 n64 = HIBYTE(v32) & 0xF | 0x40; /*0xffda8d6f*/
 v27 = BYTE2(v32); /*0xffda8d81*/
 v25 = BYTE1(v32); /*0xffda8d81*/
 n36 = 32; /*0xffda8d89*/
 v20 = a2; /*0xffda8d8e*/
 v13 = v35 ? n256_1 : n256;
 v21 = v7 *v13; /*0xffda8daf*/
 if ( sub_FFDA9D23((int *)a1, (int)&v20) < 0 ) /*0xffda8dc0*/
 break; /*0xffda8dc0*/
 if ( v35 ) /*0xffda8dcf*/
 n256_2 = n256_1; /*0xffda8dd9*/
 else n256_2 = n256; /*0xffda8dd1*/
 a2 += v7 *n256_2; /*0xffda8de4*/
 v18 = (v21 / v7 + __PAIR64__(v18, v32)) >> 32; /*0xffda8df2*/
 v32 += v21 / v7; /*0xffda8dee*/
 v8 = (__PAIR64__(v8, n256_1) - n256) >> 32; /*0xffda8df9*/
 n256_1 -= n256; /*0xffda8df9*/
 if ( __SPAIR64__(v8, n256_1) <= 0 ) /*0xffda8e07*/
 return 0; /*0xffda8e07*/
 }
 return -2147483641; /*0xffda8dc0*/
 }
 return 0; /*0xffda8e0f*/
}

int AtaPioDataTransfer(int a1, int a2, unsigned int a3, __int64 a4)
{
 int v5; // ecx int v6; // eax int result; // eax signed int n0xFFFF_1; // edi int n0xFFFF; // ebx int v10; // ebp int v11; // ebp int v13; // [esp+14h] [ebp-30h]
 int v14; // [esp+1Ch] [ebp-28h] BYREF int v15; // [esp+20h] [ebp-24h]
 char n40; // [esp+31h] [ebp-13h]
 char v17; // [esp+32h] [ebp-12h]
 char v18; // [esp+33h] [ebp-11h]
 char v19; // [esp+34h] [ebp-10h]
 char v20; // [esp+35h] [ebp-Fh]
 char v21; // [esp+36h] [ebp-Eh]
 char v22; // [esp+38h] [ebp-Ch]
 char n0xFFFF_2; // [esp+39h] [ebp-Bh]

 v5 = -2147483641; /*0xffda8e29*/
 if ( *(_BYTE *)(a1 + 11) )
 {
 n0xFFFF_1 = a3 / *(_DWORD *)(a1 + 19); /*0xffda8e6d*/
 if ( n0xFFFF_1 <= 0 ) /*0xffda8e71*/
 return v5; /*0xffda8e71*/
 v13 = a4; /*0xffda8e83*/
 while ( 1 ) /*0xffda8e97*/
 {
 (*(void ( **)(int *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(&v14, 37, 0); /*0xffda8e97*/
 n0xFFFF = 0xFFFF; /*0xffda8e9d*/
 if ( n0xFFFF_1 <= 0xFFFF ) /*0xffda8ea8*/
 n0xFFFF = n0xFFFF_1; /*0xffda8eaa*/
 v10 = *(_DWORD *)(a1 + 19); /*0xffda8eb7*/
 v17 = 32 * *(_BYTE *)(a1 + 45); /*0xffda8ebd*/
 v18 = HIBYTE(v13); /*0xffda8ec6*/
 v19 = BYTE2(v13); /*0xffda8ecf*/
 v20 = BYTE1(v13); /*0xffda8ed8*/
 v11 = n0xFFFF *v10; /*0xffda8ede*/
 v21 = v13; /*0xffda8ee4*/
 v22 = BYTE1(n0xFFFF); /*0xffda8ee8*/
 n40 = 40; /*0xffda8ef3*/
 n0xFFFF_2 = n0xFFFF; /*0xffda8ef8*/
 v14 = a2; /*0xffda8efc*/
 v15 = v11; /*0xffda8f00*/
 v5 = AtaCommandIssue(a1, &v14); /*0xffda8f0a*/
 if ( v5 ) /*0xffda8f0e*/
 break; /*0xffda8f0e*/
 if ( v15 != v11 ) /*0xffda8f14*/
 return -2147483641; /*0xffda8f3e*/
 a2 += v11; /*0xffda8f16*/
 v13 += n0xFFFF; /*0xffda8f1d*/
 n0xFFFF_1 -= n0xFFFF; /*0xffda8f25*/
 if ( n0xFFFF_1 <= 0 ) /*0xffda8f29*/
 return v5; /*0xffda8f29*/
 }
 if ( *(_BYTE *)(a1 + 46) == 2 ) /*0xffda8f44*/
 v5 = AtaWaitDeviceReady((_BYTE *)a1); /*0xffda8f4d*/
 if ( v5 != -2147483635 ) /*0xffda8f56*/
 return v5; /*0xffda8f56*/
 v5 = AtaIdentifyDeviceSetup(SystemTable, a1); /*0xffda8f65*/
 if ( !v5 ) /*0xffda8f69*/
 return -2147483635; /*0xffda8f6d*/
 result = -2147483636; /*0xffda8f6f*/
 if ( v5 != -2147483636 ) /*0xffda8f76*/
 return v5; /*0xffda8f38*/
 *(_BYTE *)(a1 + 11) = 0; /*0xffda8f78*/
 *(_BYTE *)(a1 + 25) = 0; /*0xffda8f7c*/
 }
 else
 {
 v6 = AtaIdentifyDeviceSetup(SystemTable, a1); /*0xffda8e39*/
 if ( v6 )
 return v6 != -2147483636 ? -2147483641 : -2147483636;
 else return -2147483635; /*0xffda8e44*/
 }
 return result; /*0xffda8f31*/
}

int AhciDetectAndConfigureDevice(int SystemTable, int a2, int *a3, char i, char n255)
{
 int PortStatus; // esi int AllocStatus; // eax int AllocResult; // ebx int DbgLvl; // eax int DeviceInfo; // edi int ClbHi; // edx int ClbLo; // ecx int FbHi; // edx int SigType; // eax int DbgLvl2; // eax int SectorCount; // eax int SectorCountHi; // eax bool CarryFlag; // cf char DeviceType; // al __int16 RemovableMedia; // ax int AhciBase; // [esp+10h] [ebp-210h]
 int SavedResult; // [esp+1Ch] [ebp-204h]
 _DWORD v25[30]; // [esp+20h] [ebp-200h] BYREF int Word56_57; // [esp+98h] [ebp-188h]
 int Word82; // [esp+C6h] [ebp-15Ah]
 int Word117_118; // [esp+E8h] [ebp-138h]
 int Word117_118Hi; // [esp+ECh] [ebp-134h]
 int Word129; // [esp+F4h] [ebp-12Ch]
 unsigned __int16 Word200; // [esp+10Ah] [ebp-116h]
 unsigned __int16 Word202; // [esp+10Ch] [ebp-114h]

 AhciBase = *a3; /*0xffda8f9f*/
 if ( *(_DWORD *)(a2 + 45) >= 0xCu ) /*0xffda8fa3*/
 return -2147483639; /*0xffda8faa*/
 (*(void ( **)(_DWORD *, int, _DWORD))(*(_DWORD *)::SystemTable + 84))(v25, 512, 0); /*0xffda8fc2*/
 if ( n255 == -1 )
 {
 PortStatus = AhciPortInit(a3, i, 0xFFu); /*0xffda8fe9*/
 DebugPrint(64, "\n CheckDevicePresence at port :%x and PMPort: %x is :%r", (unsigned __int8)i, 255, PortStatus);
 if ( PortStatus < 0 ) /*0xffda9011*/
 return PortStatus; /*0xffda9015*/
 AllocStatus = (*(int ( **)(int, int, int))(*(_DWORD *)::SystemTable + 76))( /*0xffda9032*/
 ::SystemTable,
 67,
 a2 + 4 * *(_DWORD *)(a2 + 45) + 49);
 AllocResult = AllocStatus; /*0xffda9035*/
 SavedResult = AllocStatus; /*0xffda903a*/
 if ( AllocStatus < 0 ) /*0xffda9040*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus); /*0xffda904d*/
 DbgLvl = DebugGetErrorLevel(); /*0xffda9055*/
 if ( DbgLvl ) /*0xffda905c*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl + 4))( /*0xffda906d*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciCtrl.c",
 361,
 "!EFI_ERROR (Status)");
 return AllocResult; /*0xffda9075*/
 }
 DeviceInfo = *(_DWORD *)(a2 + 4 * *(_DWORD *)(a2 + 45) + 49); /*0xffda9081*/
 (*(void ( **)(int, int, _DWORD))(*(_DWORD *)SystemTable + 84))(DeviceInfo, 67, 0); /*0xffda908c*/
 *(_BYTE *)(DeviceInfo + 4) = i; /*0xffda909d*/
 *(_BYTE *)(DeviceInfo + 5) = -1; /*0xffda90a7*/
 *(_DWORD *)(DeviceInfo + 47) = *(_DWORD *)((((unsigned __int8)i + 2) << 7) + AhciBase) | ReturnZero(); /*0xffda90cf*/
 *(_DWORD *)(DeviceInfo + 51) = ClbHi; /*0xffda90d4*/
 *(_DWORD *)(DeviceInfo + 55) = *(_DWORD *)(((unsigned __int8)i << 7) + AhciBase + 264) | ReturnZero(); /*0xffda90f2*/
 ClbLo = 0; /*0xffda90f5*/
 AllocResult = SavedResult; /*0xffda90fb*/
 *(_DWORD *)(DeviceInfo + 59) = FbHi; /*0xffda90ff*/
 SigType = *(_DWORD *)(((unsigned __int8)i << 7) + AhciBase + 292); /*0xffda9102*/
 if ( SigType == 257 ) /*0xffda9119*/
 {
 ++*(_DWORD *)(a2 + 45); /*0xffda911f*/
 *(_DWORD *)(DeviceInfo + 19) = 512; /*0xffda9127*/
 *(_DWORD *)(DeviceInfo + 27) = 512; /*0xffda912c*/
 *(_DWORD *)(DeviceInfo + 40) = 0; /*0xffda9136*/
 *(_BYTE *)(DeviceInfo + 6) = 1; /*0xffda9139*/
 *(_BYTE *)(DeviceInfo + 23) = 18; /*0xffda913d*/
 *(_DWORD *)(DeviceInfo + 7) = 7; /*0xffda9141*/
 *(_BYTE *)(DeviceInfo + 11) = 1; /*0xffda9148*/
 *(_WORD *)(DeviceInfo + 25) = 1; /*0xffda914c*/
 *(_DWORD *)DeviceInfo = a3; /*0xffda9152*/
 AllocResult = AtaGetIdentifyData((int *)DeviceInfo, 0, 0, (int)v25); /*0xffda915c*/
 DebugPrint(64, "\n AtaGetIdentifyData Status :%r", AllocResult); /*0xffda9166*/
 if ( AllocResult < 0 ) /*0xffda9170*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocResult); /*0xffda917d*/
 DbgLvl2 = DebugGetErrorLevel(); /*0xffda9185*/
 if ( DbgLvl2 ) /*0xffda918c*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl2 + 4))( /*0xffda919c*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciCtrl.c",
 399,
 "!EFI_ERROR (Status)");
 return AllocResult; /*0xffda919c*/
 }
 if ( (v25[0] & 0x8000) != 0 ) /*0xffda91a9*/
 return AllocResult; /*0xffda91a9*/
 *(_DWORD *)(DeviceInfo + 15) = Word56_57 - 1; /*0xffda91b7*/
 SectorCount = Word56_57; /*0xffda91ba*/
 *(_DWORD *)(DeviceInfo + 35) = 0; /*0xffda91c1*/
 *(_DWORD *)(DeviceInfo + 31) = SectorCount - 1; /*0xffda91c6*/
 LOBYTE(SectorCount) = LOBYTE(v25[0]) >> 7; /*0xffda91d0*/
 *(_BYTE *)(DeviceInfo + 44) = 0; /*0xffda91d2*/
 *(_BYTE *)(DeviceInfo + 24) = SectorCount; /*0xffda91d6*/
 if ( (Word82 & 0x400) != 0 ) /*0xffda91e4*/
 {
 SectorCountHi = Word117_118Hi; /*0xffda91ed*/
 CarryFlag = Word117_118 != 0; /*0xffda91f4*/
 *(_DWORD *)(DeviceInfo + 31) = Word117_118 - 1; /*0xffda91f7*/
 *(_BYTE *)(DeviceInfo + 44) = 1; /*0xffda91fd*/
 *(_DWORD *)(DeviceInfo + 35) = CarryFlag + SectorCountHi - 1; /*0xffda9201*/
 }
 if ( (Word129 & 0xD000) != 0x5000 ) /*0xffda9218*/
 return AllocResult; /*0xffda9218*/
 *(_DWORD *)(DeviceInfo + 19) = 2 * (Word200 + (Word202 << 16)); /*0xffda9235*/
 SigType = 257; /*0xffda924d*/
 ClbLo = 2 * (Word200 + (Word202 << 16)); /*0xffda9251*/
 *(_DWORD *)(DeviceInfo + 27) = ClbLo; /*0xffda9253*/
 }
 if ( SigType == -351010559 ) /*0xffda925b*/
 {
 *(_DWORD *)(DeviceInfo + 40) = 1; /*0xffda9261*/
 *(_DWORD *)DeviceInfo = a3; /*0xffda926a*/
 *(_BYTE *)(DeviceInfo + 23) = 1; /*0xffda926c*/
 DeviceType = LOBYTE(v25[0]) >> 7; /*0xffda9277*/
 *(_BYTE *)(DeviceInfo + 26) = 1; /*0xffda9279*/
 *(_BYTE *)(DeviceInfo + 24) = DeviceType; /*0xffda927d*/
 AllocResult = AtaGetIdentifyData((int *)DeviceInfo, ClbLo, ClbLo, (int)v25); /*0xffda928c*/
 RemovableMedia = v25[0] & 0x1F00; /*0xffda929a*/
 if ( (v25[0] & 0x1F00) == 0x500 || !RemovableMedia || RemovableMedia == 1792 ) /*0xffda92b1*/
 {
 ++*(_DWORD *)(a2 + 45); /*0xffda92b7*/
 *(_BYTE *)(DeviceInfo + 6) = 1; /*0xffda92bf*/
 *(_DWORD *)(DeviceInfo + 7) = 1; /*0xffda92c3*/
 *(_BYTE *)(DeviceInfo + 11) = 0; /*0xffda92ca*/
 *(_BYTE *)(DeviceInfo + 25) = 0; /*0xffda92ce*/
 *(_DWORD *)(DeviceInfo + 19) = 2048; /*0xffda92d2*/
 *(_DWORD *)(DeviceInfo + 27) = 2048; /*0xffda92d5*/
 }
 }
 return AllocResult; /*0xffda92d8*/
 }
 return -2147483641; /*0xffda92e2*/
}

int __thiscall AtaWaitDeviceReady(_BYTE *this)
{
 int n0x3E8; // ebx char v3; // al int v4; // edi char n3; // cl _DWORD v7[5]; // [esp+Ch] [ebp-28h] BYREF char v8; // [esp+21h] [ebp-13h]
 char v9; // [esp+22h] [ebp-12h]

 n0x3E8 = 0; /*0xffda92fd*/
 (*(void ( **)(_DWORD *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(v7, 37, 0); /*0xffda9308*/
 v3 = 32 * *(this + 45); /*0xffda9311*/
 v8 = 0; /*0xffda9314*/
 v9 = v3; /*0xffda9317*/
 v7[0] = 0; /*0xffda931a*/
 v7[1] = 256; /*0xffda931d*/
 do /*0xffda9363*/
 {
 v4 = AtaCommandIssue((int)this, v7); /*0xffda932f*/
 if ( !v4 ) /*0xffda9334*/
 break; /*0xffda9334*/
 n3 = *(this + 46); /*0xffda9336*/
 if ( n3 == 1 ) /*0xffda933c*/
 break; /*0xffda933c*/
 if ( n3 == 3 ) /*0xffda9341*/
 break; /*0xffda9341*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 100000); /*0xffda9354*/
 ++n0x3E8; /*0xffda935f*/
 }
 while ( (unsigned __int16)n0x3E8 < 0x3E8u ); /*0xffda9363*/
 return v4; /*0xffda9367*/
}

int AtaIdentifyDeviceSetup(int SystemTable, int a2)
{
 int result; // eax char AlignShift; // al unsigned __int8 RetryCount; // bl int CmdResult; // ebp unsigned __int8 *DataBuf; // edx int SectorCount2; // eax bool v10; // cf unsigned __int8 *DataBuf_2; // edi int SectorCount; // eax unsigned __int8 *DataBuf_1; // [esp+14h] [ebp-2Ch] BYREF _DWORD v14[5]; // [esp+18h] [ebp-28h] BYREF char BufSize; // [esp+2Dh] [ebp-13h]
 char AlignShift_1; // [esp+2Eh] [ebp-12h]

 (*(void ( **)(_DWORD *, int, _DWORD))(*(_DWORD *)::SystemTable + 84))(v14, 37, 0); /*0xffda938f*/
 result = AtaWaitDeviceReady((_BYTE *)a2); /*0xffda9397*/
 if ( result == -2147483635 || !result ) /*0xffda93a5*/
 {
 result = (*(int ( **)(int, int, unsigned __int8 **))(*(_DWORD *)SystemTable + 76))( /*0xffda93b8*/
 SystemTable,
 256,
 &DataBuf_1);
 if ( result >= 0 ) /*0xffda93c0*/
 {
 AlignShift = 32 * *(_BYTE *)(a2 + 45); /*0xffda93c9*/
 RetryCount = 0; /*0xffda93cc*/
 BufSize = 37; /*0xffda93d0*/
 AlignShift_1 = AlignShift; /*0xffda93d5*/
 do /*0xffda9418*/
 {
 (*(void ( **)(unsigned __int8 *, int, _DWORD))(*(_DWORD *)::SystemTable + 84))(DataBuf_1, 8, 0); /*0xffda93e8*/
 v14[0] = DataBuf_1; /*0xffda93f6*/
 v14[1] = 8; /*0xffda93fc*/
 CmdResult = AtaCommandIssue(a2, v14); /*0xffda9405*/
 if ( *(_BYTE *)(a2 + 46) < 2u ) /*0xffda940d*/
 break; /*0xffda940d*/
 ++RetryCount; /*0xffda9413*/
 }
 while ( RetryCount < 5u ); /*0xffda9418*/
 if ( CmdResult ) /*0xffda941c*/
 {
 DataBuf_2 = DataBuf_1; /*0xffda9487*/
 if ( DataBuf_1[8] == 3 ) /*0xffda948f*/
 return CmdResult; /*0xffda951e*/
 *(_DWORD *)(a2 + 15) = DataBuf_1[7] | ((DataBuf_1[6] | ((DataBuf_1[5] | (DataBuf_1[4] << 8)) << 8)) << 8); /*0xffda94b4*/
 SectorCount = DataBuf_2[7] | ((DataBuf_2[6] | ((DataBuf_2[5] | (DataBuf_2[4] << 8)) << 8)) << 8); /*0xffda94d4*/
 --*(_DWORD *)(a2 + 15); /*0xffda94d6*/
 *(_DWORD *)(a2 + 31) = SectorCount; /*0xffda94da*/
 v10 = (*(_DWORD *)(a2 + 31))-- != 0; /*0xffda94dd*/
 *(_DWORD *)(a2 + 35) = SectorCount >> 31; /*0xffda94e1*/
 *(_DWORD *)(a2 + 35) = v10 + *(_DWORD *)(a2 + 35) - 1; /*0xffda94e4*/
 *(_DWORD *)(a2 + 19) = DataBuf_2[11] | ((DataBuf_2[10] | (DataBuf_2[9] << 8)) << 8); /*0xffda94fe*/
 *(_DWORD *)(a2 + 27) = DataBuf_2[11] | ((DataBuf_2[10] | (DataBuf_2[9] << 8)) << 8); /*0xffda9517*/
 }
 else
 {
 DataBuf = DataBuf_1; /*0xffda941e*/
 *(_DWORD *)(a2 + 15) = DataBuf_1[3] | ((DataBuf_1[2] | ((DataBuf_1[1] | (*DataBuf_1 << 8)) << 8)) << 8); /*0xffda9440*/
 SectorCount2 = DataBuf[3] | ((DataBuf[2] | ((DataBuf[1] | (*DataBuf << 8)) << 8)) << 8); /*0xffda945f*/
 *(_BYTE *)(a2 + 25) = 1; /*0xffda9461*/
 --*(_DWORD *)(a2 + 15); /*0xffda9465*/
 *(_DWORD *)(a2 + 31) = SectorCount2; /*0xffda9469*/
 v10 = (*(_DWORD *)(a2 + 31))-- != 0; /*0xffda9471*/
 *(_DWORD *)(a2 + 35) = SectorCount2 >> 31; /*0xffda9475*/
 *(_DWORD *)(a2 + 35) = v10 + *(_DWORD *)(a2 + 35) - 1; /*0xffda9478*/
 *(_DWORD *)(a2 + 19) = 2048; /*0xffda947c*/
 *(_DWORD *)(a2 + 27) = 2048; /*0xffda947f*/
 }
 *(_BYTE *)(a2 + 11) = 1; /*0xffda951a*/
 return CmdResult; /*0xffda951a*/
 }
 }
 return result; /*0xffda9520*/
}

int __thiscall AtaIdentifyDeviceSetType(_BYTE *this)
{
 char v2; // bl int v3; // edi int SystemTable; // eax int v5; // edx char n58; // cl char n2; // al unsigned __int8 v9; // [esp+13h] [ebp-129h]
 _DWORD v10[5]; // [esp+14h] [ebp-128h] BYREF char n3; // [esp+29h] [ebp-113h]
 char v12; // [esp+2Dh] [ebp-10Fh]
 _BYTE v13[256]; // [esp+3Ch] [ebp-100h] BYREF v2 = 0; /*0xffda9533*/
 v3 = **(_DWORD **)this; /*0xffda9544*/
 v9 = *(this + 4); /*0xffda9549*/
 SystemTable = SystemTable; /*0xffda954d*/
 *(this + 46) = 4; /*0xffda9552*/
 (*(void ( **)(_BYTE *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(v13, 256, 0); /*0xffda9558*/
 (*(void ( **)(_DWORD *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(v10, 37, 0); /*0xffda956a*/
 n3 = 3; /*0xffda9571*/
 v12 = -1; /*0xffda957b*/
 v10[1] = 256; /*0xffda9582*/
 v10[0] = v13; /*0xffda9586*/
 v5 = AtaCommandIssue((int)this, v10); /*0xffda958f*/
 if ( v5 < 0 ) /*0xffda9596*/
 v2 = *(_BYTE *)((v9 << 7) + v3 + 288); /*0xffda95a2*/
 if ( (v2 & 0x21) == 0 && v5 >= 0 ) /*0xffda95b0*/
 {
 v5 = -2147483641; /*0xffda95b6*/
 n58 = v13[12]; /*0xffda95bb*/
 n2 = v13[2] & 0xF; /*0xffda95bf*/
 *(this + 46) = 4; /*0xffda95c1*/
 if ( n2 == 2 && n58 == 58 ) /*0xffda95cc*/
 {
 v5 = -2147483636; /*0xffda95ce*/
 *(this + 46) = 1; /*0xffda95d1*/
 }
 if ( n2 == 2 && n58 == 4 && v13[13] == 1 ) /*0xffda95e8*/
 {
 v5 = -2147483635; /*0xffda95ea*/
 *(this + 46) = 2; /*0xffda95ec*/
 }
 if ( n2 == 6 && n58 == 40 ) /*0xffda95f6*/
 {
 v5 = -2147483635; /*0xffda95f8*/
 *(this + 46) = 3; /*0xffda95fa*/
 }
 if ( n2 == 7 && n58 == 39 ) /*0xffda9605*/
 {
 v5 = -2147483640; /*0xffda9607*/
 *(this + 46) = 5; /*0xffda960c*/
 }
 if ( n2 == 6 && n58 == 41 ) /*0xffda9617*/
 *(this + 46) = 6; /*0xffda9619*/
 if ( n2 == 5 && v13[0] == 112 ) /*0xffda9625*/
 *(this + 46) = 7; /*0xffda9627*/
 }
 return v5; /*0xffda962b*/
}

int AtaCommandIssue(int this, _BYTE *a2)
{
 unsigned int *v4; // ebp _BYTE *v5; // ecx int result; // eax int v7; // ebx int **this_1; // ecx unsigned __int8 v9; // [esp+13h] [ebp-Dh]
 int *v10; // [esp+14h] [ebp-Ch]
 _BYTE *v11; // [esp+18h] [ebp-8h]
 int v12; // [esp+1Ch] [ebp-4h]

 v4 = *(unsigned int **)(this + 47); /*0xffda964d*/
 v10 = *(int **)this; /*0xffda9650*/
 v5 = *(_BYTE **)(*(_DWORD *)this + 24); /*0xffda9654*/
 v12 = *v10; /*0xffda9659*/
 v9 = *(_BYTE *)(this + 4); /*0xffda9660*/
 a2[14] = a2[4]; /*0xffda9667*/
 v11 = v5; /*0xffda966d*/
 a2[16] = BYTE1(*((_DWORD *)a2 + 1)); /*0xffda9676*/
 a2[19] = -96; /*0xffda9679*/
 result = AhciCmdEnginePreInit((int **)this, 1); /*0xffda967d*/
 if ( result >= 0 ) /*0xffda9684*/
 {
 v7 = AhciCheckTfdBusy((unsigned __int8 *)this); /*0xffda9691*/
 this_1 = (int **)this; /*0xffda9693*/
 if ( v7 >= 0 ) /*0xffda9697*/
 {
 AhciSetupCmdHeader(this, (int)v4, v10[6], v10[7]); /*0xffda96a9*/
 AtaCommandSetupFis(this, a2, v4, v11); /*0xffda96b8*/
 AtaCommandSetAtaFlags((int)a2, v4, (int)v11); /*0xffda96c1*/
 AtaCommandBuildSgList((int *)this, (int *)a2, (int)v4, (int)v11); /*0xffda96cc*/
 *v4 &= ~0x40u; /*0xffda96d1*/
 v11[1] |= 0x80u; /*0xffda96d8*/
 result = AtaCommandStart((unsigned __int8 *)this); /*0xffda96de*/
 if ( result < 0 ) /*0xffda96e5*/
 return result; /*0xffda96e5*/
 v7 = AtaCommandPoll((_BYTE *)this); /*0xffda96ef*/
 if ( v7 < 0 && *(_DWORD *)(this + 40) == 1 && (*(_BYTE *)((v9 << 7) + v12 + 288) & 1) != 0 ) /*0xffda9712*/
 return AtaIdentifyDeviceSetType((_BYTE *)this); /*0xffda971b*/
 *(_BYTE *)(this + 46) = 0; /*0xffda971d*/
 this_1 = (int **)this; /*0xffda9721*/
 *((_DWORD *)a2 + 1) = v4[1]; /*0xffda9726*/
 }
 AhciCmdEnginePreInit(this_1, 0); /*0xffda972b*/
 return v7; /*0xffda9730*/
 }
 return result; /*0xffda9732*/
}

int __usercall AtaGetIdentifyData@<eax>(int **DeviceInfo@<edx>, int ClbLo, int a3, int a4)
{
 bool v5; // zf int result; // eax int v7; // [esp+Ch] [ebp-28h] BYREF int n512; // [esp+10h] [ebp-24h]
 char v9; // [esp+1Eh] [ebp-16h]
 char v10; // [esp+1Fh] [ebp-15h]

 (*(void ( **)(int *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(&v7, 37, 0); /*0xffda9753*/
 v5 = DeviceInfo[10] == 0; /*0xffda9756*/
 v7 = a4; /*0xffda9765*/
 n512 = 512; /*0xffda976d*/
 v9 = 0; /*0xffda9772*/
 v10 = !v5 ? -95 : -20;
 result = AtaCommandSubmit(DeviceInfo, (int)&v7); /*0xffda9780*/
 if ( n512 != 512 ) /*0xffda9789*/
 return -2147483641; /*0xffda978b*/
 return result; /*0xffda9790*/
}

int __usercall AhciPortInit@<eax>(int *AhciBase@<edx>, unsigned __int8 i, unsigned __int8 n255)
{
 unsigned __int8 i_1; // cl int v5; // esi _DWORD *v6; // edi int v7; // eax int result; // eax i_1 = i; /*0xffda979a*/
 v5 = i << 7; /*0xffda97a4*/
 v6 = (_DWORD *)*AhciBase; /*0xffda97a8*/
 *(_DWORD *)((char *)v6 + v5 + 300) |= 0x300u; /*0xffda97aa*/
 *(_DWORD *)((char *)v6 + v5 + 304) |= 0x7FF0F03u; /*0xffda97b5*/
 *(_DWORD *)((char *)v6 + v5 + 272) |= 0xFFC000FF; /*0xffda97c0*/
 if ( (*v6 & 0x8000000) != 0 ) /*0xffda97d2*/
 {
 if ( (*(_BYTE *)(v5 + *AhciBase + 296) & 0xF) == 3 ) /*0xffda97e2*/
 {
 *(_DWORD *)((char *)v6 + v5 + 280) |= 2u; /*0xffda982b*/
 }
 else
 {
 *(_DWORD *)((char *)v6 + v5 + 280) |= 0x10u; /*0xffda97e4*/
 AhciPortWaitRegister((int)v6, i, i, 0x4000, 0x4000); /*0xffda97f9*/
 *(_DWORD *)((char *)v6 + v5 + 280) |= 2u; /*0xffda9803*/
 v7 = AhciPortWaitDeviceReady(AhciBase, i, 255); /*0xffda9810*/
 *(_DWORD *)((char *)v6 + v5 + 280) &= ~0x10u; /*0xffda9815*/
 if ( v7 < 0 ) /*0xffda9822*/
 return -2147483641; /*0xffda9829*/
 i_1 = i; /*0xffda9835*/
 }
 }
 if ( (*((_BYTE *)v6 + v5 + 296) & 0xF) == 3 && (*(_DWORD *)((char *)v6 + v5 + 280) & 0x100000) != 0 ) /*0xffda9852*/
 *(_DWORD *)((char *)v6 + v5 + 280) |= 4u; /*0xffda9854*/
 result = AhciPortDeviceDetect(AhciBase, i_1); /*0xffda9861*/
 if ( result < 0 ) /*0xffda9869*/
 return AhciPortCOMRESET( /*0xffda9890*/
 AhciBase,
 i,
 n255,
 (unsigned __int8)(*((_BYTE *)AhciBase + v5 + 300) & 0xF0) >> 4,
 (unsigned __int16)(*(_WORD *)((_BYTE *)AhciBase + v5 + 300) & 0xFF0) >> 8);
 return result; /*0xffda9898*/
}

int AhciPortDeviceDetect(int *AhciBase, unsigned __int8 i)
{
 int v2; // esi int i_1; // ecx int v5; // edi int result; // eax unsigned __int8 i_2; // cl unsigned int j; // ebp int n257; // eax unsigned __int8 v10; // al int i_3; // [esp+Ch] [ebp-4h]

 v2 = *AhciBase; /*0xffda98a1*/
 i_1 = AhciBase[9]; /*0xffda98a5*/
 v5 = i << 7; /*0xffda98ac*/
 i_3 = i_1; /*0xffda98af*/
 if ( (*(_DWORD *)(v5 + v2 + 296) & 0xF) != 3 ) /*0xffda98be*/
 {
 DebugPrint( /*0xffda98ce*/
 0x80000000,
 "Device detection or Phy communication not established, Serial Ata Status Register:%x\n",
 *(_DWORD *)(v5 + v2 + 296) & 0xF);
 return -2147483641; /*0xffda98db*/
 }
 *(_DWORD *)(v5 + v2 + 312) = 0; /*0xffda98eb*/
 *(_BYTE *)(i_1 + 64) = 0; /*0xffda98f2*/
 *(_DWORD *)(v5 + v2 + 280) |= 0x11u; /*0xffda98fa*/
 result = AhciPortWaitRegister(v2, i, i_1, 0x4000, 0x4000); /*0xffda9908*/
 if ( result >= 0 ) /*0xffda9912*/
 {
 result = AhciPortWaitRegister(v2, i, i_2, 0x8000, 0x8000); /*0xffda9925*/
 if ( result >= 0 ) /*0xffda992f*/
 {
 for ( j = 0; j < 0x7530; ++j ) /*0xffda9936*/
 {
 if ( (unsigned __int16)*(_DWORD *)(v5 + v2 + 292) == 257 ) /*0xffda9943*/
 break; /*0xffda9943*/
 if ( *(_BYTE *)(i_3 + 64) == 52 ) /*0xffda994d*/
 break; /*0xffda994d*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 1000); /*0xffda9960*/
 }
 *(_DWORD *)(v5 + v2 + 280) &= ~1u; /*0xffda996f*/
 result = AhciPortPollRegister(v2, i, 0x18u, 0x8000, 500); /*0xffda9988*/
 if ( result >= 0 ) /*0xffda9992*/
 {
 *(_DWORD *)(v5 + v2 + 280) &= ~0x10u; /*0xffda9994*/
 result = AhciPortPollRegister(v2, i, 0x18u, 0x4000, 500); /*0xffda99a8*/
 if ( result >= 0 ) /*0xffda99b2*/
 {
 n257 = *(_DWORD *)(v5 + v2 + 292); /*0xffda99b4*/
 if ( n257 != 257 && n257 != -351010559 && n257 != -1771503359 ) /*0xffda99ce*/
 {
 DebugPrint(0x80000000, " Invalid ATA/ATAPI/PM Signature :%x\n", *(_DWORD *)(v5 + v2 + 292)); /*0xffda99d6*/
 return -2147483641; /*0xffda99fe*/
 }
 v10 = *(_BYTE *)(v5 + v2 + 288); /*0xffda99d8*/
 if ( (v10 & 0x88) != 0 ) /*0xffda99e1*/
 {
 DebugPrint(0x80000000, " BSY or DRQ Bit Set in TFD :%x\n", v10); /*0xffda99f1*/
 return -2147483641; /*0xffda99f1*/
 }
 return 0; /*0xffda9a00*/
 }
 }
 }
 }
 return result; /*0xffda9a03*/
}

int AhciInitController(void *SystemTable, int a2)
{
 int *AhciBase; // ebx int GhcReg; // eax unsigned int PortMap; // eax _DWORD *CmdListPtr; // esi int PortCountAligned; // ecx __int16 PortCountAligned2; // ax int AllocStatus; // eax int ErrorLevel; // eax int CmdListAddr; // ecx int FisAddr; // esi int PortCount; // eax int FisHiPtr; // edx _DWORD *CmdTablePtr; // esi int AllocStatus2; // eax int DbgLvl2; // eax int AllocStatus3; // eax int DbgLvl3; // eax unsigned int PortMask; // ecx unsigned __int8 PortIdx; // al int PortOffset; // esi int ComresetStatus; // eax int DbgLvl4; // eax unsigned __int64 FisAddr64; // [esp-10h] [ebp-2Ch]
 unsigned __int8 PortIdx_1; // [esp+16h] [ebp-6h]
 unsigned __int8 CmdSlotIndex; // [esp+17h] [ebp-5h]
 unsigned int PortMask_1; // [esp+18h] [ebp-4h]

 AhciBase = *(int **)a2; /*0xffda9a13*/
 if ( !*(_DWORD *)a2 ) /*0xffda9a13*/
 return -2147483641; /*0xffda9a13*/
 GhcReg = *AhciBase; /*0xffda9a23*/
 *(_DWORD *)(a2 + 4) = *AhciBase; /*0xffda9a25*/
 if ( GhcReg == -1 ) /*0xffda9a2b*/
 return -2147483641; /*0xffda9a2b*/
 PortMap = AhciBase[3]; /*0xffda9a2d*/
 *(_DWORD *)(a2 + 8) = PortMap; /*0xffda9a30*/
 if ( !PortMap ) /*0xffda9a35*/
 return -2147483641; /*0xffda9a35*/
 *(_BYTE *)(a2 + 68) = 0; /*0xffda9a37*/
 do /*0xffda9a44*/
 {
 if ( (PortMap & 1) != 0 ) /*0xffda9a3d*/
 ++*(_BYTE *)(a2 + 68); /*0xffda9a3f*/
 PortMap >>= 1; /*0xffda9a42*/
 }
 while ( PortMap ); /*0xffda9a44*/
 if ( (*(_DWORD *)(a2 + 4) & 0x1Fu) + 1 < *(unsigned __int8 *)(a2 + 68) ) /*0xffda9a53*/
 return -2147483641; /*0xffda9a1e*/
 if ( (*AhciBase & 0x40000) == 0 ) /*0xffda9a5c*/
 AhciBase[1] |= 0x80000000; /*0xffda9a5e*/
 CmdListPtr = (_DWORD *)(a2 + 36); /*0xffda9a69*/
 PortCountAligned = *(unsigned __int8 *)(a2 + 68) << 8; /*0xffda9a6c*/
 PortCountAligned2 = *(unsigned __int8 *)(a2 + 68) << 8; /*0xffda9a6f*/
 *(_BYTE *)(a2 + 69) = 1; /*0xffda9a71*/
 AllocStatus = (*(int ( **)(void *, int, int, int))(*(_DWORD *)SystemTable + 72))( /*0xffda9a8d*/
 SystemTable,
 4,
 (PortCountAligned >> 12) + ((PortCountAligned2 & 0xFFF) != 0),
 a2 + 36);
 if ( AllocStatus < 0 ) /*0xffda9a95*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus); /*0xffda9aa2*/
 ErrorLevel = DebugGetErrorLevel(); /*0xffda9aaa*/
 if ( ErrorLevel ) /*0xffda9ab1*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffda9ac2*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciCtrl.c",
 1132,
 "!EFI_ERROR (Status)");
 return -2147483639; /*0xffda9acd*/
 }
 (*(void ( **)(_DWORD, int, _DWORD))(*(_DWORD *)::SystemTable + 84))( /*0xffda9ae5*/
 *CmdListPtr,
 *(unsigned __int8 *)(a2 + 68) << 8,
 0);
 CmdListAddr = *CmdListPtr; /*0xffda9aef*/
 FisAddr = *(_DWORD *)(a2 + 40); /*0xffda9af1*/
 PortCount = *(unsigned __int8 *)(a2 + 68); /*0xffda9af4*/
 *(_DWORD *)(a2 + 56) = FisAddr; /*0xffda9af9*/
 PortCount <<= 8; /*0xffda9afc*/
 *(_DWORD *)(a2 + 52) = CmdListAddr; /*0xffda9b01*/
 *(_DWORD *)(a2 + 44) = CmdListAddr + PortCount; /*0xffda9b04*/
 FisHiPtr = FisAddr + __CFADD__(CmdListAddr, PortCount); /*0xffda9b07*/
 CmdTablePtr = (_DWORD *)(a2 + 12); /*0xffda9b09*/
 *(_DWORD *)(a2 + 48) = FisHiPtr; /*0xffda9b0d*/
 AllocStatus2 = (*(int ( **)(void *, int, int, int))(*(_DWORD *)SystemTable + 72))(SystemTable, 4, 1, a2 + 12); /*0xffda9b18*/
 if ( AllocStatus2 < 0 ) /*0xffda9b20*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus2); /*0xffda9b2d*/
 DbgLvl2 = DebugGetErrorLevel(); /*0xffda9b35*/
 if ( DbgLvl2 ) /*0xffda9b3c*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl2 + 4))( /*0xffda9b48*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciCtrl.c",
 1154,
 "!EFI_ERROR (Status)");
 return -2147483639; /*0xffda9b48*/
 }
 (*(void ( **)(_DWORD, int, _DWORD))(*(_DWORD *)::SystemTable + 84))(*CmdTablePtr, 1024, 0); /*0xffda9b5d*/
 *(_DWORD *)(a2 + 60) = *CmdTablePtr; /*0xffda9b65*/
 *(_DWORD *)(a2 + 64) = *(_DWORD *)(a2 + 16); /*0xffda9b6e*/
 *(_DWORD *)(a2 + 20) = 32; /*0xffda9b72*/
 AllocStatus3 = (*(int ( **)(void *, int, int, int))(*(_DWORD *)SystemTable + 72))(SystemTable, 4, 2, a2 + 24); /*0xffda9b81*/
 if ( AllocStatus3 < 0 ) /*0xffda9b89*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", AllocStatus3); /*0xffda9b96*/
 DbgLvl3 = DebugGetErrorLevel(); /*0xffda9b9e*/
 if ( DbgLvl3 ) /*0xffda9ba5*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl3 + 4))( /*0xffda9bb5*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciCtrl.c",
 1168,
 "!EFI_ERROR (Status)");
 return -2147483639; /*0xffda9bb5*/
 }
 (*(void ( **)(_DWORD, int, _DWORD))(*(_DWORD *)::SystemTable + 84))(*(_DWORD *)(a2 + 24), 4224, 0); /*0xffda9bcb*/
 PortMask = *(_DWORD *)(a2 + 8); /*0xffda9bce*/
 PortIdx = 0; /*0xffda9bd1*/
 *(_DWORD *)(a2 + 32) = 4224; /*0xffda9bd6*/
 PortMask_1 = PortMask; /*0xffda9bd9*/
 PortIdx_1 = 0; /*0xffda9bdd*/
 for ( CmdSlotIndex = 0; PortMask; PortIdx_1 = PortIdx ) /*0xffda9be7*/
 {
 if ( (PortMask & 1) != 0 ) /*0xffda9bf5*/
 {
 PortOffset = PortIdx << 7; /*0xffda9c01*/
 *(int *)((char *)AhciBase + PortOffset + 280) &= ~1u; /*0xffda9c0d*/
 if ( AhciPortPollRegister((int)AhciBase, PortIdx, 0x18u, 0x8000, 500) >= 0 /*0xffda9c3a*/
 || (ComresetStatus = AhciPortCOMRESET((int *)a2, PortIdx_1, 0xFFu, 0, 3), ComresetStatus >= 0) )
 {
 *(int *)((char *)AhciBase + PortOffset + 280) &= ~0x10u; /*0xffda9c7c*/
 if ( AhciPortPollRegister((int)AhciBase, PortIdx_1, 0x18u, 0x4000, 500) >= 0 ) /*0xffda9c96*/
 {
 *(int *)((char *)AhciBase + PortOffset + 304) |= 0x7FF0F03u; /*0xffda9c98*/
 *(int *)((char *)AhciBase + PortOffset + 260) = _PAIR64__(*(_DWORD *)(a2 + 12), *(_DWORD *)(a2 + 16)); /*0xffda9cae*/
 *(int *)((char *)AhciBase + PortOffset + 256) = *(_DWORD *)(a2 + 12); /*0xffda9cb8*/
 FisAddr64 = *(_QWORD *)(a2 + 36) + ((unsigned __int64)CmdSlotIndex << 8); /*0xffda9cd3*/
 *(int *)((char *)AhciBase + PortOffset + 268) = _PAIR64__(FisAddr64, HIDWORD(FisAddr64)); /*0xffda9ce0*/
 *(int *)((char *)AhciBase + PortOffset + 264) = *(_DWORD *)(a2 + 36) + (CmdSlotIndex++ << 8); /*0xffda9cf2*/
 }
 }
 else
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", ComresetStatus); /*0xffda9c47*/
 DbgLvl4 = DebugGetErrorLevel(); /*0xffda9c4f*/
 if ( DbgLvl4 ) /*0xffda9c56*/
 (*(void ( **)(const char *, int, const char *))(DbgLvl4 + 4))( /*0xffda9c6b*/
 "e:\\hs\\AmiModulePkg\\AhciRecovery\\AhciCtrl.c",
 1200,
 "!EFI_ERROR (Status)");
 }
 PortMask = PortMask_1; /*0xffda9cfd*/
 PortIdx = PortIdx_1; /*0xffda9d01*/
 }
 PortMask >>= 1; /*0xffda9d05*/
 ++PortIdx; /*0xffda9d07*/
 PortMask_1 = PortMask; /*0xffda9d09*/
 }
 return 0; /*0xffda9d1b*/
}

int AtaCommandSubmit(int **DeviceInfo, int a2)
{
 unsigned int *v4; // ebx int result; // eax int v6; // esi int **DeviceInfo_1; // ecx int *v8; // [esp+10h] [ebp-8h]
 _BYTE *v9; // [esp+14h] [ebp-4h]

 v4 = *(unsigned int **)((char *)DeviceInfo + 47); /*0xffda9d31*/
 v8 = *DeviceInfo; /*0xffda9d34*/
 v9 = (_BYTE *)(*DeviceInfo)[6]; /*0xffda9d3b*/
 result = AhciCmdEnginePreInit(DeviceInfo, 1); /*0xffda9d3f*/
 if ( result >= 0 ) /*0xffda9d46*/
 {
 v6 = AhciCheckTfdBusy((unsigned __int8 *)DeviceInfo); /*0xffda9d4f*/
 DeviceInfo_1 = DeviceInfo; /*0xffda9d51*/
 if ( v6 >= 0 ) /*0xffda9d55*/
 {
 AhciSetupCmdHeader((int)DeviceInfo, (int)v4, v8[6], v8[7]); /*0xffda9d63*/
 AtaCommandSetupFis((int)DeviceInfo, (_BYTE *)a2, v4, v9); /*0xffda9d72*/
 AtaCommandSetAtaFlags(a2, v4, (int)v9); /*0xffda9d7b*/
 AtaCommandBuildSgList((int *)DeviceInfo, (int *)a2, (int)v4, (int)v9); /*0xffda9d86*/
 *v4 &= ~0x40u; /*0xffda9d8b*/
 v9[1] |= 0x80u; /*0xffda9d91*/
 result = AtaCommandStart((unsigned __int8 *)DeviceInfo); /*0xffda9d97*/
 if ( result < 0 ) /*0xffda9d9e*/
 return result; /*0xffda9d9e*/
 v6 = AtaCommandPoll(DeviceInfo); /*0xffda9dac*/
 *(_DWORD *)(a2 + 4) = v4[1]; /*0xffda9dae*/
 DeviceInfo_1 = DeviceInfo; /*0xffda9db1*/
 }
 AhciCmdEnginePreInit(DeviceInfo_1, 0); /*0xffda9db5*/
 return v6; /*0xffda9dba*/
 }
 return result; /*0xffda9dbc*/
}

int __thiscall AtaCommandPoll(_BYTE *this)
{
 char v1; // dl int v2; // ebx int v3; // ebp int v4; // esi unsigned __int8 v5; // al unsigned int n0xEA60_1; // ecx int v7; // edi int v8; // eax char v10; // [esp+12h] [ebp-6h]
 unsigned __int8 v11; // [esp+13h] [ebp-5h]
 int v12; // [esp+14h] [ebp-4h]
 unsigned int n0xEA60; // [esp+14h] [ebp-4h]

 v1 = 0; /*0xffda9dc7*/
 v2 = v12; /*0xffda9dca*/
 v3 = *(_DWORD *)(this + 55); /*0xffda9dcf*/
 v4 = **(_DWORD **)this; /*0xffda9dd3*/
 v5 = *(this + 4); /*0xffda9dd5*/
 n0xEA60_1 = 0; /*0xffda9dd8*/
 v11 = v5; /*0xffda9dde*/
 v10 = 0; /*0xffda9de2*/
 v7 = v5 << 7; /*0xffda9de6*/
 do /*0xffda9e5d*/
 {
 v8 = *(_DWORD *)(v7 + v4 + 304); /*0xffda9de9*/
 if ( (v8 & 0x7FA0F00) != 0 || (v2 = *(_DWORD *)(v7 + v4 + 272), (v2 & 0xF9800050) != 0) ) /*0xffda9e08*/
 {
 *(_DWORD *)(v7 + v4 + 304) |= 0x7FF0F03u; /*0xffda9ebc*/
 *(_DWORD *)(v7 + v4 + 272) |= 0xFFC000FF; /*0xffda9ec7*/
 sub_FFDAA8D9(0x80000000, "PxSERR Port Serial ATA Error Data32_SERR:%x Data32_IS :%x\n", v8, v2); /*0xffda9ede*/
 return -2147483641; /*0xffda9ede*/
 }
 if ( *(_BYTE *)(v3 + 32) == 95 ) /*0xffda9e12*/
 {
 v1 = 1; /*0xffda9e14*/
 *(_BYTE *)(v3 + 32) = 0; /*0xffda9e16*/
 v10 = 1; /*0xffda9e1a*/
 }
 if ( *(_BYTE *)(v3 + 64) == 52 || v1 && (*(_DWORD *)(v7 + v4 + 288) & 0x88) == 0 ) /*0xffda9e31*/
 break; /*0xffda9e31*/
 n0xEA60 = n0xEA60_1 + 1; /*0xffda9e45*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 500); /*0xffda9e49*/
 n0xEA60_1 = n0xEA60; /*0xffda9e4c*/
 v1 = v10; /*0xffda9e53*/
 }
 while ( n0xEA60 < 0xEA60 ); /*0xffda9e5d*/
 sub_FFDAA36D(v4, v11, 0x38u, 0xFFFF, 200); /*0xffda9e71*/
 if ( *(_DWORD *)(v7 + v4 + 312) ) /*0xffda9e79*/
 {
 sub_FFDAA8D9(0x80000000, "Command Issue (CI) not clear Data32_CI:%x\n", *(_DWORD *)(v7 + v4 + 312)); /*0xffda9e95*/
 }
 else
 {
 if ( (*(_DWORD *)(v7 + v4 + 288) & 9) == 0 ) /*0xffda9ea8*/
 return 0; /*0xffda9eba*/
 sub_FFDAA8D9(0x80000000, "BSY and DRQ not cleared Task File Data Reg:%x\n", *(_DWORD *)(v7 + v4 + 288)); /*0xffda9eb6*/
 }
 return -2147483641; /*0xffda9eeb*/
}

int AtaCommandSetupFis(int this, _BYTE *a2, unsigned int *a3, _BYTE *a4)
{
 char v6; // cl

 (*(void ( **)(_BYTE *, int, _DWORD))(*(_DWORD *)SystemTable + 84))(a4, 4224, 0); /*0xffda9f0c*/
 *a4 = 39; /*0xffda9f0f*/
 if ( *(_BYTE *)(this + 5) == 0xFF ) /*0xffda9f1a*/
 v6 = 0; /*0xffda9f1c*/
 else v6 = *(_BYTE *)(this + 5); /*0xffda9f20*/
 a4[1] ^= (v6 ^ a4[1]) & 0xF; /*0xffda9f2e*/
 a4[2] = a2[19]; /*0xffda9f34*/
 a4[3] = a2[8]; /*0xffda9f3a*/
 a4[11] = a2[9]; /*0xffda9f40*/
 a4[4] = a2[12]; /*0xffda9f46*/
 a4[8] = a2[13]; /*0xffda9f4c*/
 a4[5] = a2[14]; /*0xffda9f52*/
 a4[9] = a2[15]; /*0xffda9f58*/
 a4[6] = a2[16]; /*0xffda9f5e*/
 a4[10] = a2[17]; /*0xffda9f64*/
 a4[12] = a2[10]; /*0xffda9f6a*/
 a4[13] = a2[11]; /*0xffda9f70*/
 a4[7] = a2[18]; /*0xffda9f76*/
 a4[15] = a2[20]; /*0xffda9f7c*/
 *a3 = *a3 & 0xFFFFFFE0 | 5; /*0xffda9f89*/
 return 0; /*0xffda9f84*/
}

int __usercall AtaCommandSetAtaFlags@<eax>(int a1@<edx>, _DWORD *a2, int a3)
{
 (*(void ( **)(int, int, int))(*(_DWORD *)SystemTable + 80))(a3 + 64, a1 + 21, 16); /*0xffda9fa5*/
 if ( *(_BYTE *)(a3 + 2) == 0xA0 ) /*0xffda9fb0*/
 *a2 |= 0x20u; /*0xffda9fb6*/
 return 0; /*0xffda9faf*/
}

int AtaCommandBuildSgList(int *this, int *a2, int a3, int a4)
{
 unsigned __int16 v6; // di int *v7; // esi unsigned int n0x400000; // ebx int n0x3FFFFF; // eax int v10; // ecx int v12; // [esp+1Ch] [ebp+8h]

 v6 = 0; /*0xffda9fc9*/
 v12 = *this; /*0xffda9fcb*/
 v7 = (int *)(a4 + 128); /*0xffda9fcf*/
 n0x400000 = a2[1]; /*0xffda9fd2*/
 while ( n0x400000 ) /*0xffdaa03f*/
 {
 *v7 = *a2; /*0xffda9fda*/
 v7[1] = sub_FFDAA85A(*a2, 0); /*0xffda9fe6*/
 n0x3FFFFF = 0x3FFFFF; /*0xffda9fe9*/
 if ( n0x400000 < 0x400000 ) /*0xffda9ff6*/
 n0x3FFFFF = n0x400000 - 1; /*0xffda9ff8*/
 v6 += 16; /*0xffda9ffe*/
 v10 = v7[3] ^ (n0x3FFFFF ^ v7[3]) & 0x3FFFFF; /*0xffdaa00d*/
 v7[3] = v10 & 0x7FFFFFFF; /*0xffdaa017*/
 n0x400000 += -1 - (v10 & 0x3FFFFF); /*0xffdaa023*/
 if ( (unsigned int)v6 + 128 >= *(_DWORD *)(v12 + 32) ) /*0xffdaa02e*/
 break; /*0xffdaa02e*/
 *a2 += (v10 & 0x3FFFFF) + 1; /*0xffdaa037*/
 v7 += 4; /*0xffdaa03a*/
 }
 *(v7 - 1) |= 0x80000000; /*0xffdaa045*/
 *(_WORD *)(a3 + 2) = v6 >> 4; /*0xffdaa050*/
 return 0; /*0xffdaa056*/
}

int __thiscall AtaCommandStart(unsigned __int8 *this)
{
 unsigned __int8 i; // dl int v3; // esi int v4; // edi int result; // eax i = *(this + 4); /*0xffdaa064*/
 v3 = i << 7; /*0xffdaa06a*/
 v4 = **(_DWORD **)this; /*0xffdaa06d*/
 *(_DWORD *)(v3 + v4 + 304) |= 0x7FF0F03u; /*0xffdaa077*/
 *(_DWORD *)(v3 + v4 + 272) |= 0xFFC000FF; /*0xffdaa084*/
 *(_DWORD *)(v3 + v4 + 280) |= 0x10u; /*0xffdaa08f*/
 result = AhciPortWaitRegister(v4, i, (unsigned __int8)this, 0x4000, 0x4000); /*0xffdaa097*/
 if ( result >= 0 ) /*0xffdaa0a1*/
 {
 (*(void ( **)(_DWORD, int, _DWORD))(*(_DWORD *)SystemTable + 84))(*(_DWORD *)(this + 55), 256, 0); /*0xffdaa0b4*/
 *(_DWORD *)(v3 + v4 + 280) |= 1u; /*0xffdaa0b7*/
 *(_DWORD *)(v3 + v4 + 312) |= 1u; /*0xffdaa0c2*/
 return 0; /*0xffdaa0ca*/
 }
 return result; /*0xffdaa0cc*/
}

int AhciSetupCmdHeader(int this, int a2, int a3, unsigned int a4)
{
 int v6; // eax

 (*(void ( **)(int, int, _DWORD))(*(_DWORD *)SystemTable + 84))(a2, 32, 0); /*0xffdaa0e3*/
 *(_DWORD *)a2 &= 0xFFFFF47F; /*0xffdaa0e6*/
 LOBYTE(v6) = *(_BYTE *)(this + 5); /*0xffdaa0ef*/
 if ( (_BYTE)v6 == 0xFF ) /*0xffdaa0f4*/
 v6 = 0; /*0xffdaa0f6*/
 else v6 = (unsigned __int8)v6; /*0xffdaa0fa*/
 *(_DWORD *)a2 ^= (*(_DWORD *)a2 ^ (v6 << 12)) & 0xF000; /*0xffdaa10b*/
 *(_DWORD *)(a2 + 4) = 0; /*0xffdaa10f*/
 *(_WORD *)(a2 + 2) = 0; /*0xffdaa112*/
 *(_DWORD *)(a2 + 8) = a3; /*0xffdaa11b*/
 *(_DWORD *)(a2 + 12) = sub_FFDAA85A(a3, a4); /*0xffdaa125*/
 return 0; /*0xffdaa12a*/
}

int __thiscall AhciCheckTfdBusy(unsigned __int8 *this)
{
 unsigned __int8 v1; // bl int v2; // edx int *v3; // esi int v4; // ecx int result; // eax v1 = *(this + 4); /*0xffdaa12f*/
 v2 = 0; /*0xffdaa132*/
 v3 = *(int **)this; /*0xffdaa135*/
 v4 = v1 << 7; /*0xffdaa13b*/
 if ( (*(_BYTE *)(v4 + *v3 + 288) & 0x88) == 0 ) /*0xffdaa149*/
 return v2; /*0xffdaa149*/
 result = sub_FFDAA40C( /*0xffdaa171*/
 v3,
 v1,
 255,
 (unsigned __int8)(*(_BYTE *)(v4 + *v3 + 300) & 0xF0) >> 4,
 (unsigned __int16)(*(_WORD *)(v4 + *v3 + 300) & 0xFF0) >> 8);
 v2 = result; /*0xffdaa176*/
 if ( result >= 0 ) /*0xffdaa17d*/
 return v2; /*0xffdaa17f*/
 return result; /*0xffdaa181*/
}

int AhciCmdEnginePreInit(int **this, char a2)
{
 unsigned __int8 PortIndex; // bl int *AhciBase; // ebp int MmioBase; // esi int PortOffset; // edi int PortPlus2Off; // ebp int SstsHi; // edx __int64 SctlPair; // rax int SstsHi2; // edx int PortOff2; // edi int Result; // ebx int ClbPair; // eax int FbPair; // eax int QwordFb; // [esp-10h] [ebp-3Ch]
 unsigned int SstsHi2_1; // [esp-Ch] [ebp-38h]
 unsigned __int8 PortIndex_1; // [esp+16h] [ebp-16h]
 int CmdBase; // [esp+18h] [ebp-14h]
 unsigned int SstsHi_1; // [esp+1Ch] [ebp-10h]
 int *AhciBase_1; // [esp+20h] [ebp-Ch]
 unsigned int SavedPortMask; // [esp+24h] [ebp-8h]
 int FisBase2; // [esp+28h] [ebp-4h]

 PortIndex = *((_BYTE *)this + 4); /*0xffdaa189*/
 FisBase2 = *(int *)((char *)this + 55); /*0xffdaa191*/
 SavedPortMask = *(unsigned int *)((char *)this + 59); /*0xffdaa198*/
 PortIndex_1 = PortIndex; /*0xffdaa1a3*/
 CmdBase = *(int *)((char *)this + 47); /*0xffdaa1a7*/
 AhciBase = *this; /*0xffdaa1ac*/
 AhciBase_1 = *this; /*0xffdaa1b1*/
 SstsHi_1 = *(unsigned int *)((char *)this + 51); /*0xffdaa1b5*/
 MmioBase = **this; /*0xffdaa1ba*/
 if ( a2 ) /*0xffdaa1c0*/
 {
 PortOffset = PortIndex << 7; /*0xffdaa1cb*/
 PortPlus2Off = (PortIndex + 2) << 7; /*0xffdaa1d3*/
 if ( (*(_DWORD *)(MmioBase + PortPlus2Off) | ReturnZero()) != CmdBase || SstsHi != SstsHi_1 ) /*0xffdaa1f4*/
 {
 LODWORD(SctlPair) = *(_DWORD *)(MmioBase + PortPlus2Off) | ReturnZero(); /*0xffdaa208*/
 ::SctlPair = SctlPair; /*0xffdaa20a*/
 ::QwordFb = *(_DWORD *)(PortOffset + MmioBase + 264) | ReturnZero(); /*0xffdaa231*/
 ::SstsHi2 = SstsHi2; /*0xffdaa23a*/
 *(_DWORD *)(PortOffset + MmioBase + 260) = _PAIR64__(CmdBase, SstsHi_1); /*0xffdaa249*/
 *(_DWORD *)(MmioBase + PortPlus2Off) = CmdBase; /*0xffdaa254*/
 *(_DWORD *)(PortOffset + MmioBase + 268) = _PAIR64__(FisBase2, SavedPortMask); /*0xffdaa261*/
 *(_DWORD *)(PortOffset + MmioBase + 264) = FisBase2; /*0xffdaa26b*/
 }
 AhciBase = AhciBase_1; /*0xffdaa272*/
 }
 PortOff2 = PortIndex << 7; /*0xffdaa280*/
 *(_DWORD *)(PortOff2 + MmioBase + 280) &= ~1u; /*0xffdaa28c*/
 if ( AhciPortPollRegister(MmioBase, PortIndex, 0x18u, 0x8000, 500) < 0 ) /*0xffdaa29e*/
 {
 Result = AhciPortCOMRESET(AhciBase, PortIndex, 0xFFu, 0, 0); /*0xffdaa2b2*/
 if ( Result < 0 ) /*0xffdaa2b9*/
 goto LABEL_11; /*0xffdaa2b9*/
 PortIndex = PortIndex_1; /*0xffdaa2bb*/
 }
 *(_DWORD *)(PortOff2 + MmioBase + 280) &= ~0x10u; /*0xffdaa2bf*/
 Result = AhciPortPollRegister(MmioBase, PortIndex, 0x18u, 0x4000, 500); /*0xffdaa2dc*/
 if ( Result >= 0 ) /*0xffdaa2e3*/
 {
 *(_DWORD *)(PortOff2 + MmioBase + 304) |= 0x7FF0F03u; /*0xffdaa2e5*/
 *(_DWORD *)(PortOff2 + MmioBase + 272) |= 0xFFC000FF; /*0xffdaa2f0*/
 }
LABEL_11:
 if ( !a2 && ::SctlPair ) /*0xffdaa312*/
 {
 ClbPair = _PAIR64__(::SctlPair, HIDWORD(::SctlPair)); /*0xffdaa316*/
 SstsHi2_1 = ::SstsHi2; /*0xffdaa31b*/
 *(_DWORD *)(PortOff2 + MmioBase + 260) = ClbPair; /*0xffdaa321*/
 QwordFb = ::QwordFb; /*0xffdaa32d*/
 *(_DWORD *)(PortOff2 + MmioBase + 256) = ::SctlPair; /*0xffdaa333*/
 FbPair = _PAIR64__(QwordFb, SstsHi2_1); /*0xffdaa33a*/
 ::SctlPair = 0; /*0xffdaa33f*/
 *(_DWORD *)(PortOff2 + MmioBase + 268) = FbPair; /*0xffdaa350*/
 *(_DWORD *)(PortOff2 + MmioBase + 264) = ::QwordFb; /*0xffdaa35c*/
 }
 return Result; /*0xffdaa363*/
}

int AhciPortPollRegister(int a1, unsigned __int8 a2, unsigned __int8 a3, int a4, int a5)
{
 int v6; // esi char n10; // bl v6 = a1 + ((a2 + 2) << 7); /*0xffdaa383*/
 while ( 2 ) /*0xffdaa385*/
 {
 n10 = 10; /*0xffdaa385*/
 do /*0xffdaa3a7*/
 {
 if ( (*(_DWORD *)(v6 + a3) & a4) == 0 ) /*0xffdaa38e*/
 return 0; /*0xffdaa3b5*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 100); /*0xffdaa39e*/
 --n10; /*0xffdaa3a4*/
 }
 while ( n10 ); /*0xffdaa3a7*/
 if ( --a5 ) /*0xffdaa3ac*/
 continue; /*0xffdaa3ac*/
 break;
 }
 return -2147483641; /*0xffdaa3b7*/
}

int AhciPortWaitRegister(int a1, unsigned __int8 i, unsigned __int8 ia, int n0x4000, int a5)
{
 int n500; // esi int v7; // edi char n10; // bl n500 = 500; /*0xffdaa3c5*/
 v7 = i << 7; /*0xffdaa3ca*/
 while ( 2 ) /*0xffdaa3cd*/
 {
 n10 = 10; /*0xffdaa3cd*/
 do /*0xffdaa3f7*/
 {
 if ( (n0x4000 & *(_DWORD *)(v7 + a1 + 280)) == a5 ) /*0xffdaa3de*/
 return 0; /*0xffdaa405*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 100); /*0xffdaa3ee*/
 --n10; /*0xffdaa3f4*/
 }
 while ( n10 ); /*0xffdaa3f7*/
 if ( --n500 ) /*0xffdaa3fc*/
 continue; /*0xffdaa3fc*/
 break;
 }
 return -2147483641; /*0xffdaa407*/
}

int AhciPortCOMRESET(int *AhciBase, unsigned __int8 i, char n255, unsigned __int8 a4, unsigned __int8 n3)
{
 int v6; // edi int v7; // esi int v8; // ebp int result; // eax unsigned __int8 i_2; // cl int v11; // ebx int v12; // eax int i_1; // [esp+1Ch] [ebp-4h]

 v6 = *AhciBase; /*0xffdaa41b*/
 v7 = i << 7; /*0xffdaa426*/
 i_1 = i; /*0xffdaa429*/
 v8 = *(_DWORD *)(v7 + *AhciBase + 264); /*0xffdaa42d*/
 if ( !v8 ) /*0xffdaa436*/
 return -2147483641; /*0xffdaa438*/
 if ( byte_FFDAB370 ) /*0xffdaa449*/
 return 0; /*0xffdaa44b*/
 byte_FFDAB370 = 1; /*0xffdaa45c*/
 *(_DWORD *)(v7 + v6 + 280) &= ~1u; /*0xffdaa465*/
 result = AhciPortPollRegister(v6, i, 0x18u, 0x8000, 500); /*0xffdaa471*/
 if ( result >= 0 ) /*0xffdaa47b*/
 {
 *(_DWORD *)(v7 + v6 + 304) |= 0x7FF0F03u; /*0xffdaa481*/
 *(_DWORD *)(v7 + v6 + 272) |= 0xFFC000FF; /*0xffdaa491*/
 *(_DWORD *)(v7 + v6 + 280) |= 0x10u; /*0xffdaa49e*/
 result = AhciPortWaitRegister(v6, i, i_2, 0x4000, 0x4000); /*0xffdaa4ac*/
 if ( result >= 0 ) /*0xffdaa4b6*/
 {
 v11 = 0; /*0xffdaa4bc*/
 *(_BYTE *)(v8 + 64) = 0; /*0xffdaa4c3*/
 if ( n255 == -1 ) /*0xffdaa4cb*/
 {
 *(_DWORD *)(v7 + v6 + 300) = *(_DWORD *)(v7 + v6 + 300) & 0xFFFFF000 | (16 * (a4 + 16 *n3) + 1); /*0xffdaa4ee*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 1000); /*0xffdaa501*/
 *(_DWORD *)(v7 + v6 + 300) &= 0xFFFFFFF0; /*0xffdaa507*/
 }
 else
 {
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 1000); /*0xffdaa51d*/
 }
 v12 = AhciPortWaitDeviceReady(AhciBase, i, n255); /*0xffdaa52f*/
 *(_DWORD *)(v7 + v6 + 280) &= ~0x10u; /*0xffdaa534*/
 byte_FFDAB370 = 0; /*0xffdaa53c*/
 if ( v12 < 0 ) /*0xffdaa545*/
 v11 = -2147483641; /*0xffdaa547*/
 DebugPrint(64, "\n GeneratePortReset Status at Port :%x, PMPort :%x :%r", i_1, (unsigned __int8)n255, v12); /*0xffdaa560*/
 return v11; /*0xffdaa568*/
 }
 }
 return result; /*0xffdaa56a*/
}

int AhciPortWaitDeviceReady(int *AhciBase, unsigned __int8 PortIndex, char n255)
{
 unsigned int WaitCount; // esi int InitRetries; // ebp int DevStatus; // eax unsigned __int8 SavedPortIdx; // dl int Status; // esi unsigned int LoopJ; // ebp unsigned __int8 i_1; // dl _DWORD *R11; // ecx unsigned __int8 SerPortIdx; // dl _DWORD *R13; // ecx unsigned __int8 i; // [esp+17h] [ebp-11h]
 int AhciBasea; // [esp+18h] [ebp-10h]
 int PortState; // [esp+1Ch] [ebp-Ch]
 unsigned int LoopK; // [esp+20h] [ebp-8h]
 int PortOffset; // [esp+24h] [ebp-4h]

 i = PortIndex; /*0xffdaa57f*/
 WaitCount = 0; /*0xffdaa583*/
 InitRetries = 0; /*0xffdaa585*/
 AhciBasea = *AhciBase; /*0xffdaa589*/
 while ( 1 ) /*0xffdaa596*/
 {
 DevStatus = AhciPortReadReg(AhciBase, PortIndex, n255, 0) & 0xF; /*0xffdaa596*/
 if ( DevStatus == 3 || DevStatus == 1 ) /*0xffdaa5a4*/
 break; /*0xffdaa5a4*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 1000); /*0xffdaa5b7*/
 PortIndex = i; /*0xffdaa5ba*/
 if ( (unsigned int)++InitRetries >= 0xA ) /*0xffdaa5c5*/
 return -2147483641; /*0xffdaa5cc*/
 }
 for ( LoopJ = 0; LoopJ < 0x7530; LoopJ += n255 == -1 ? 1 : 100 )
 {
 if ( (AhciPortReadReg(AhciBase, SavedPortIdx, n255, 0) & 0xF) == 0 ) /*0xffdaa5e1*/
 return -2147483641; /*0xffdaa787*/
 if ( (AhciPortReadReg(R11, i_1, n255, 2) & 0x4000000) != 0 ) /*0xffdaa5f7*/
 break; /*0xffdaa5f7*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 1000); /*0xffdaa60a*/
 SavedPortIdx = i; /*0xffdaa60d*/
 }
 PortOffset = SavedPortIdx << 7; /*0xffdaa636*/
 PortState = ReturnZero() | *(_DWORD *)(AhciBasea + PortOffset + 264); /*0xffdaa656*/
 do
 {
 if ( (AhciPortReadReg(AhciBase, i, n255, 2) & 0x7FA0F00) != 0 ) /*0xffdaa672*/
 AhciPortClearSerr(R13, SerPortIdx, n255); /*0xffdaa677*/
 if ( *(_BYTE *)(PortState + 64) == 52 ) /*0xffdaa683*/
 break; /*0xffdaa683*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 1000); /*0xffdaa696*/
 WaitCount += n255 == -1 ? 1 : 100;
 }
 while ( WaitCount < 0x7530 );
 for ( LoopK = 0; LoopK < 0x64; ++LoopK ) /*0xffdaa6b9*/
 {
 AhciPortClearSerr(AhciBase, i, n255); /*0xffdaa6ca*/
 if ( (*(_BYTE *)(PortState + 66) & 0x89) == (*(_DWORD *)(AhciBasea + PortOffset + 288) & 0x89) ) /*0xffdaa6eb*/
 break; /*0xffdaa6eb*/
 (*(void ( **)(int, int, int))(dword_FFDAB2C8 + 4))(SystemTable, dword_FFDAB2C8, 100); /*0xffdaa6fb*/
 }
 Status = 0; /*0xffdaa715*/
 if ( (*(_BYTE *)(PortState + 66) & 0x81) != 0 )
 {
 Status = -2147483641; /*0xffdaa721*/
 DebugPrint(0x80000000, "AHCI: BSY or ERR Bit not clear :%x \n", *(unsigned __int8 *)(PortState + 66));
 }
 if ( (*(_DWORD *)(AhciBasea + PortOffset + 272) & 0x7C000000) != 0 ) /*0xffdaa749*/
 {
 Status = -2147483641; /*0xffdaa756*/
 DebugPrint(0x80000000, " Port x Interrupt Status :%x \n", *(_DWORD *)(AhciBasea + PortOffset + 272)); /*0xffdaa75b*/
 }
 AhciPortClearSerr(AhciBase, i, n255); /*0xffdaa76c*/
 *(_DWORD *)(AhciBasea + PortOffset + 272) |= 0xFFC000FF; /*0xffdaa778*/
 return Status; /*0xffdaa78c*/
}

int AhciPortReadReg(_DWORD *R11, unsigned __int8 i, char n255, char n2)
{
 int result; // eax int n40; // esi result = 0; /*0xffdaa795*/
 n40 = 40; /*0xffdaa79e*/
 if ( n255 == -1 ) /*0xffdaa79f*/
 {
 if ( n2 == 2 ) /*0xffdaa7a6*/
 n40 = 48; /*0xffdaa7aa*/
 return *(_DWORD *)(*R11 + ((i + 2) << 7) + n40); /*0xffdaa7b6*/
 }
 return result; /*0xffdaa7b9*/
}

int AhciPortClearSerr(_DWORD *R13, unsigned __int8 i, char n255)
{
 if ( n255 == -1 ) /*0xffdaa7c3*/
 *(_DWORD *)(*R13 + ((i + 2) << 7) + 48) |= 0x7FF0F03u; /*0xffdaa7dc*/
 return 0; /*0xffdaa7e2*/
}

void *__thiscall PeiGetPcdDb(void *this)
{
 int v1; // eax int v2; // eax int v3; // eax void *this_1; // [esp+0h] [ebp-4h]

 this_1 = this; /*0xffdaa7e7*/
 v1 = sub_FFDAAA23(); /*0xffdaa7e8*/
 v2 = (*(int (__stdcall **)(int))(*(_DWORD *)v1 + 32))(v1); /*0xffdaa7fd*/
 if ( v2 < 0 ) /*0xffdaa805*/
 {
 sub_FFDAA8D9(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v2); /*0xffdaa812*/
 v3 = sub_FFDAA8A8(); /*0xffdaa81a*/
 if ( v3 ) /*0xffdaa821*/
 (*(void ( **)(const char *, int, const char *))(v3 + 4))( /*0xffdaa82f*/
 "e:\\hs\\MdePkg\\Library\\PeiPcdLib\\PeiPcdLib.c",
 49,
 "!EFI_ERROR (Status)");
 }
 return this_1; /*0xffdaa83a*/
}

__int64 PeiSetMemAttr(__int64 MmioBase)
{
 void *v1; // ecx void *PcdDb; // eax PcdDb = PeiGetPcdDb(v1); /*0xffdaa83c*/
 (*((void ( **)(int, _DWORD, _DWORD))PcdDb + 18))(14, MmioBase, HIDWORD(MmioBase)); /*0xffdaa84b*/
 return MmioBase; /*0xffdaa859*/
}

__int64 _PAIR64__(int a1, unsigned int a2)
{
 return a2; /*0xffdaa87d*/
}

int ReturnZero()
{
 return 0; /*0xffdaa8a4*/
}

int DebugGetErrorLevel()
{
 int v0; // eax int v2; // [esp+0h] [ebp-8h] BYREF int v3; // [esp+4h] [ebp-4h] BYREF v0 = sub_FFDAAA23(); /*0xffdaa8ad*/
 if ( (*(int ( **)(int, void *, _DWORD, int *, int *))(*(_DWORD *)v0 + 32))(v0, &unk_FFDAB190, 0, &v2, &v3) >= 0 ) /*0xffdaa8cc*/
 return v3; /*0xffdaa8d2*/
 else return 0; /*0xffdaa8ce*/
}

int DebugPrint(int a1, const char *a2, ...)
{
 int result; // eax int ( **v3)(int, const char *, char *); // esi va_list va; // [esp+10h] [ebp+Ch] BYREF va_start(va, a2);
 result = DebugGetErrorLevel(); /*0xffdaa8da*/
 v3 = (int ( **)(int, const char *, char *))result; /*0xffdaa8df*/
 if ( result ) /*0xffdaa8e3*/
 {
 result = sub_FFDAA9D4(); /*0xffdaa8e5*/
 if ( (result & a1) != 0 ) /*0xffdaa8f0*/
 return (*v3)(a1, a2, (char *)va); /*0xffdaa8fc*/
 }
 return result; /*0xffdaa901*/
}

int DebugAssert(
 int e:__hs__MdePkg__Library__PeiServicesTablePointerLibIdt__PeiServ,
 int n48,
 int PeiServices____((void__)_0))
{
 int result; // eax result = DebugGetErrorLevel(); /*0xffdaa909*/
 if ( result ) /*0xffdaa910*/
 return (*(int ( **)(int, int, int))(result + 4))( /*0xffdaa918*/
 e:__hs__MdePkg__Library__PeiServicesTablePointerLibIdt__PeiServ,
 n48,
 PeiServices____((void__)_0));
 return result; /*0xffdaa91e*/
}

int HobGetHandoffInfoTable()
{
 int v0; // eax int v1; // eax int v2; // eax int v3; // eax int v5; // [esp+4h] [ebp-4h] BYREF v0 = sub_FFDAAA23(); /*0xffdaa926*/
 v1 = (*(int ( **)(int, int *))(*(_DWORD *)v0 + 48))(v0, &v5); /*0xffdaa932*/
 if ( v1 < 0 ) /*0xffdaa93e*/
 {
 DebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", v1); /*0xffdaa94b*/
 v2 = DebugGetErrorLevel(); /*0xffdaa953*/
 if ( v2 ) /*0xffdaa95a*/
 (*(void ( **)(const char *, int, const char *))(v2 + 4))( /*0xffdaa964*/
 "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
 50,
 "!EFI_ERROR (Status)");
 }
 if ( !v5 ) /*0xffdaa96e*/
 {
 v3 = DebugGetErrorLevel(); /*0xffdaa970*/
 if ( v3 ) /*0xffdaa977*/
 (*(void ( **)(const char *, int, const char *))(v3 + 4))( /*0xffdaa981*/
 "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
 51,
 "HobList != ((void *) 0)");
 }
 return v5; /*0xffdaa98a*/
}

_WORD *HobGetNextResource(int n0xFFFF, _WORD *i)
{
 _WORD *i_1; // esi int ErrorLevel; // eax i_1 = i; /*0xffdaa990*/
 if ( !i ) /*0xffdaa994*/
 {
 ErrorLevel = DebugGetErrorLevel(); /*0xffdaa996*/
 if ( ErrorLevel ) /*0xffdaa99d*/
 (*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))( /*0xffdaa9ab*/
 "e:\\hs\\MdePkg\\Library\\PeiHobLib\\HobLib.c",
 82,
 "HobStart != ((void *) 0)");
 }
 while ( 1 ) /*0xffdaa9c4*/
 {
 if ( *i_1 == 0xFFFF ) /*0xffdaa9ca*/
 return 0; /*0xffdaa9cf*/
 if ( *i_1 == 3 ) /*0xffdaa9bc*/
 break; /*0xffdaa9bc*/
 i_1 = (_WORD *)((char *)i_1 + (unsigned __int16)i_1[1]); /*0xffdaa9c2*/
 }
 return i_1; /*0xffdaa9ce*/
}

int PchGetRtcPowerStatus()
{
 unsigned __int8 v0; // al char n3; // al char n3_1; // cl v0 = __inbyte(0x70u); /*0xffdaa9da*/
 __outbyte(0x70u, v0 & 0x80 | 0x4A); /*0xffdaa9df*/
 n3 = __inbyte(0x71u); /*0xffdaa9e6*/
 n3_1 = n3; /*0xffdaa9e7*/
 if ( (unsigned __int8)n3 <= 3u ) /*0xffdaa9ec*/
 {
LABEL_4:
 if ( !n3_1 ) /*0xffdaaa07*/
 return 0; /*0xffdaaa07*/
 goto LABEL_5; /*0xffdaaa07*/
 }
 n3_1 = n3; /*0xffdaa9ee*/
 if ( !n3 ) /*0xffdaa9f6*/
 {
 n3_1 = MEMORY[0xFDAF0490] & 2 | 1; /*0xffdaaa02*/
 goto LABEL_4; /*0xffdaaa02*/
 }
LABEL_5:
 if ( n3_1 != -1 )
 return n3_1 != 1 ? -2147483578 : -2147483644;
 return 0; /*0xffdaaa1f*/
}

int PeiServicesGetPointer()
{
 int v0; // esi _BYTE v2[2]; // [esp+4h] [ebp-8h] BYREF int v3; // [esp+6h] [ebp-6h]

 sub_FFDAAA55(v2); /*0xffdaaa2c*/
 v0 = *(_DWORD *)(v3 - 4); /*0xffdaaa34*/
 if ( !v0 ) /*0xffdaaa39*/
 DebugAssert( /*0xffdaaa48*/
 (int)"e:\\hs\\MdePkg\\Library\\PeiServicesTablePointerLibIdt\\PeiServicesTablePointer.c",
 48,
 (int)"PeiServices != ((void *) 0)");
 return v0; /*0xffdaaa50*/
}

void *__thiscall AsmReadIdtr(void *this)
{
 void *this_1; // eax if ( !this ) /*0xffdaaa5b*/
 DebugAssert((int)"e:\\hs\\MdePkg\\Library\\BaseLib\\X86ReadIdtr.c", 37, (int)"Idtr != ((void *) 0)"); /*0xffdaaa6a*/
 this_1 = this; /*0xffdaaa70*/
 __sidt(this); /*0xffdaaa73*/
 return this_1; /*0xffdaaa77*/
}