/**
* @file FpgaLoaderPeim.c
* @brief FPGA Loader PEIM - Decompiled from FpgaLoaderPeim.efi (IA32)
*
*This is a reconstructed C representation of the FPGA bitstream loader PEIM
*from the Purley platform. The driver loads FPGA bitstreams via the MRC
* (Memory Reference Code) hooks PPIs, manages MP services for BSP/AP
*coordination, performs PEI-phase locking, and triggers warm reset after
*FPGA programming.
*
*Binary info:
*MD5: fdd9dee7b3135cc8c394c8873fcefcb8
*SHA256: 0f9c118dd3f96178aea2975ce1294f063ca75226b90529b131f60496b6a2a76a
*Size: 0x2f20 bytes
*Arch: IA32 (32-bit)
*Total functions: 41 (39 named, 2 anonymous -> renamed via debug strings)
*
*Key flow:
*1. FpgaConfigurationGetValues() - reads/creates config HOB
*2. FpgaGetPcdProtocol() - obtains PCD protocol for platform settings
*3. Locate PPIs: ChipServices, MPServices, CoreServices
*4. FpgaMpServicesData() - enumerates processors, finds BSP socket
*5. Per-socket bitstream load via FpgaLoadBitstream() with retry (max 3)
*6. FpgaConfigurationSetValues() - persists updated config to HOB
*7. FpgaDisableUnusedSockets() - power off unused FPGA sockets
*8. Set BIOS scratchpad bit 5 -> warm reset
*9. FpgaPeiLock() on subsequent boots (FPGA already active)
*/
#include "FpgaLoaderPeim.h"
//
// Global variables (.data segment at 0xffd6b964 - 0xffd6ba64)
//
UINT32 dword_FFD6BA38; // PCD protocol UINT32 dword_FFD6BA3C; // (unused alignment)
UINT32 dword_FFD6BA40; // Chip Services PPI UINT32 dword_FFD6BA44; // MP processor data buffer UINT32 dword_FFD6BA48; // MP Services PPI UINT32 dword_FFD6BA4C; // BSP Socket number UINT32 dword_FFD6BA50; // Number of processors UINT32 dword_FFD6BA54; // BSP Index UINT32 dword_FFD6BA58; // Core Services PPI
// ============================================================
// FpgaLoaderEntry
// ============================================================
int FpgaLoaderEntry(int a1, void *a2)
{
int Values; // eax void *v4; // ecx int Values_1; // esi int PcdProtocol; // eax int Status; // ebx int DebugLib; // eax unsigned __int8 ErrorLevel; // bl unsigned __int8 ErrorLevel; // bh bool v12; // zf int ErrorLevel; // eax int Index; // edi int n4_1; // ebp unsigned __int8 v16; // bl int Index; // ebp int Index; // ebx int n4; // edi unsigned __int8 Protocol; // al int v21; // eax unsigned __int8 v22; // [esp+16h] [ebp-36h]
char v23; // [esp+17h] [ebp-35h]
void ( **v25)(_DWORD, int); // [esp+1Ch] [ebp-30h] BYREF _BYTE v26[4]; // [esp+20h] [ebp-2Ch] BYREF _BYTE Table[2]; // [esp+24h] [ebp-28h] BYREF unsigned __int8 v28; // [esp+26h] [ebp-26h]
unsigned __int8 ErrorLevel; // [esp+27h] [ebp-25h]
char v30; // [esp+28h] [ebp-24h]
unsigned __int8 v31; // [esp+29h] [ebp-23h]
unsigned __int8 v32; // [esp+2Ah] [ebp-22h]
_BYTE v33[33]; // [esp+2Bh] [ebp-21h]
Values = FpgaConfigurationGetValues(Table);
Values_1 = Values;
if ( Values )
{
FpgaDebugPrint(0x80000000, "FPGA Loader,FpgaConfigurationGetValues failed, return it's error!, %r\n", Values);
return Values_1;
}
if ( !Table[0] )
{
FpgaDebugPrint(0x80000000, "FPGA Loader,FpgaConfigurationGetValues global enable is False!\n");
return -2147483645;
}
if ( !v28 )
{
FpgaDebugPrint(0x80000000, "FPGA Loader,FpgaConfigurationGetValues no FPGA sockets present!\n");
return -2147483645;
}
PcdProtocol = FpgaGetPcdProtocol(v4);
dword_FFD6BA38 = (*(int ( **)(int))(PcdProtocol + 16))(12);
Status = (*(int ( **)(void *, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a2 + 32))(
a2,
&unk_FFD6B9D4,
0,
0,
&dword_FFD6BA40);
if ( Status < 0 )
{
FpgaDebugPrint(0x80000000, "FPGA Loader, Find MRC Hooks Chip Services Ppi failed, return it's error!\n");
FpgaDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugLib = FpgaGetDebugLib();
if ( DebugLib )
(*(void ( **)(const char *, int, const char *))(DebugLib + 4))(
"e:\\hs\\PurleySktPkg\\Pei\\FpgaLoader\\FpgaLoader.c",
692,
"!EFI_ERROR (Status)");
return Status;
}
ErrorLevel = v32;
if ( v32 && (ErrorLevel = v28, (v32 & v28) != 0) )
{
FpgaDebugPrint(0x80000000, "FPGA Loader, FpgaSktActive = %X! \n", ErrorLevel);
FpgaDebugPrint(0x80000000, "FPGA Loader, FpgaSktPresent = %X! \n", ErrorLevel);
FpgaDebugPrint(0x80000000, "FPGA Loader, FpgaPlatformEnabled = %X! \n", ErrorLevel);
Status = (*(int ( **)(void *, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a2 + 32))(
a2,
&unk_FFD6B9C4,
0,
0,
&dword_FFD6BA48);
if ( Status )
{
FpgaDebugPrint(0x80000000, "FPGA Loader, find Mp services PPI failed, return it's error!\n");
return Status;
}
Status = (*(int ( **)(void *, int, int *, _BYTE *))dword_FFD6BA48)(a2, dword_FFD6BA48, &dword_FFD6BA50, v26);
v12 = Status == 0;
if ( Status >= 0 )
{
Status = FpgaMpServicesData(a2);
v12 = Status == 0;
}
if ( !v12 )
{
FpgaDebugPrint(0x80000000, "FPGA Loader, FpgaMpServicesData failed, return it's error!, %r\n", Status);
return Status;
}
Status = (*(int ( **)(void *, void *, _DWORD, _DWORD, int *))(*(_DWORD *)a2 + 32))(
a2,
&unk_FFD6BA14,
0,
0,
&dword_FFD6BA58);
if ( Status < 0 )
{
FpgaDebugPrint(0x80000000, "FPGA Loader, Find MRC Hooks Core Services PPI failed, return it's error!\n");
FpgaDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
ErrorLevel = FpgaGetDebugLib();
if ( ErrorLevel )
(*(void ( **)(const char *, int, const char *))(ErrorLevel + 4))(
"e:\\hs\\PurleySktPkg\\Pei\\FpgaLoader\\FpgaLoader.c",
742,
"!EFI_ERROR (Status)");
return Status;
}
(*(void ( **)(int, int, _DWORD, int))(dword_FFD6BA58 + 32))(dword_FFD6BA38, 144, 0, 255);
v30 = 0;
if ( ((*(int ( **)(int, _DWORD, _DWORD, int))(dword_FFD6BA40 + 4))(
dword_FFD6BA38,
(unsigned __int8)dword_FFD6BA4C,
0,
318914724)
& 0x20) == 0 )
{
Index = 0;
while ( 1 )
{
v23 = 0;
Index = 0;
n4 = 4;
do
{
v22 = 1 << Index;
FpgaDebugPrint(
0x80000000,
"FPGA Loader, Retry %d, Socket %d, Mask %02x, Started!\n",
Index,
Index,
(unsigned __int8)(1 << Index));
if ( ((unsigned __int8)(1 << Index) & v28) != 0 )
{
if ( (v22 & v32) != 0 )
{
Protocol = v33[Index];
if ( Protocol == 0xFF || (v22 & v31) != 0 )
{
FpgaDebugPrint(
0x80000000,
"FPGA Loader, Socket %d has no GUID assigned or has already programmed, skipping it!\n",
Index);
v30 |= v22;
v33[Index + 8] = 1;
v31 |= 1 << Index;
}
else
{
v23 = 1;
FpgaDebugPrint(0x80000000, "FPGA Loader, Socket %d : BitStreamGuidIndex = %x !\n", Index, Protocol);
}
}
else
{
v33[Index] = -1;
v30 |= 1 << Index;
v33[Index + 8] = 4;
}
}
else
{
v33[Index] = -1;
}
++Index;
--n4;
}
while ( n4 );
if ( v23 == 1 )
FpgaLoadBitstream((int)a2, Table);
if ( v31 == v28 || v31 == v32 )
break;
if ( (unsigned int)++Index >= 3 )
goto LABEL_49;
}
FpgaDebugPrint(0x80000000, "FPGA Loader,All enabled sockets programmed! Exiting retry loop\n");
LABEL_49:
FpgaDebugPrint(0x80000000, "FPGA Loader, Updating configuration values!\n");
FpgaConfigurationSetValues(Table);
FpgaDisableUnusedSockets(Table);
FpgaDebugPrint(
0x80000000,
"Fpga Loader, Set the biosscratchpad1 bit5 to indicate bitstream download was attempted.\n");
v21 = (*(int ( **)(int, _DWORD, _DWORD, int))(dword_FFD6BA40 + 4))(
dword_FFD6BA38,
(unsigned __int8)dword_FFD6BA4C,
0,
318914724);
(*(void ( **)(int, _DWORD, _DWORD, int, int))(dword_FFD6BA40 + 8))(
dword_FFD6BA38,
(unsigned __int8)dword_FFD6BA4C,
0,
318914724,
v21 | 0x20);
FpgaDebugPrint(0x80000000, "FPGA Loader, Warm Reset!!\n");
(*(void ( **)(void *, void *, _DWORD, _DWORD, void ( ***)(_DWORD, int)))(*(_DWORD *)a2 + 32))(
a2,
&unk_FFD6B9E4,
0,
0,
&v25);
(*v25)(v25, 1);
while ( 1 )
;
}
FpgaDebugPrint(0x80000000, "FPGA Loader, FpgaConfigurationGetValues FPGA already active!\n");
Index = 0;
n4_1 = 4;
do
{
v16 = 1 << Index;
if ( (ErrorLevel & (unsigned __int8)(1 << Index)) == 1 << Index )
v33[Index + 8] = 0;
if ( (ErrorLevel & v16) != (v28 & v16) )
{
FpgaDebugPrint(0x80000000, "FPGA Loader,FpgaConfigurationGetValues Sockets[%x] active != present \n", Index);
v33[Index] = -1;
v30 |= v16;
v33[Index + 8] = 9;
}
++Index;
--n4_1;
}
while ( n4_1 );
FpgaDebugPrint(0x80000000, "FPGA Loader, Updating configuration values!\n");
FpgaConfigurationSetValues(Table);
FpgaDisableUnusedSockets(Table);
FpgaPeiLock();
return -2147483628;
}
else
{
FpgaDisableUnusedSockets(Table);
return -2147483645;
}
}
// ============================================================
// FpgaConfigurationGetValues
// ============================================================
int __thiscall FpgaConfigurationGetValues(char *this)
{
char *v3; // esi _BYTE *v4; // ecx char *v5; // edx char v6; // al int Index; // esi int n4; // edi char *v9; // [esp+4h] [ebp-4h] BYREF if ( FpgaConfigurationGetHob(&v9) >= 0 )
{
v3 = v9;
v4 = this + 7;
v5 = v9 + 19;
*(this + 2) = v9[2];
*(this + 3) = v3[3];
*(this + 4) = v3[4];
*(this + 5) = v3[5];
*(this + 6) = v3[6];
*this = *v3;
*(this + 1) = v3[1];
*(this + 31) = v3[31];
*(this + 32) = v3[32];
v6 = v3[37];
Index = v3 - this;
*(this + 37) = v6;
n4 = 4;
do
{
*v4 = v4[Index];
v4[8] = *(v5 - 4);
v4[12] = *v5;
v4[16] = v5[4];
v4[20] = v5[8];
v4[4] = *(v5 - 8);
v4[26] = v5[14];
++v4;
++v5;
--n4;
}
while ( n4 );
return 0;
}
else
{
FpgaDebugPrint(0x80000000, "FpgaConfigurationGetValues-> HOB error, return EFI_NOT_FOUND!\n");
return -2147483634;
}
}
// ============================================================
// FpgaConfigurationSetValues
// ============================================================
int __thiscall FpgaConfigurationSetValues(_BYTE *this)
{
char *v3; // ecx _BYTE *v4; // esi _BYTE *v5; // edx char v6; // al _BYTE *v7; // edi int n4; // ecx char *v9; // [esp+4h] [ebp-4h] BYREF if ( FpgaConfigurationGetHob(&v9) >= 0 )
{
v3 = v9;
v4 = this + 19;
v9[2] = *(this + 2);
v5 = v3 + 7;
v3[3] = *(this + 3);
v3[4] = *(this + 4);
v3[5] = *(this + 5);
v3[6] = *(this + 6);
v3[1] = *(this + 1);
v3[31] = *(this + 31);
v3[32] = *(this + 32);
v6 = *(this + 37);
v7 = (_BYTE *)(this - v3);
v3[37] = v6;
n4 = 4;
do
{
*v5 = v5[(_DWORD)v7];
v5[8] = *(v4 - 4);
v5[12] = *v4;
v5[16] = v4[4];
v5[20] = v4[8];
v5[4] = *(v4 - 8);
v5[26] = v4[14];
++v5;
++v4;
--n4;
}
while ( n4 );
return 0;
}
else
{
FpgaDebugPrint(0x80000000, "FpgaConfigurationSetValues-> HOB error, return EFI_NOT_FOUND!\n");
return -2147483634;
}
}
// ============================================================
// FpgaConfigurationGetHob
// ============================================================
int __thiscall FpgaConfigurationGetHob(char **this)
{
_WORD *HobList; // eax int v4; // ecx int v5; // ecx _WORD *HobByType; // esi int v7; // ecx char *v8; // esi int v9; // ecx int Hob; // eax int Hob_1; // esi unsigned int n4_1; // ebx _BYTE *v13; // eax int Index; // ecx char *Variable; // edi char v16; // al char buf[40]; // [esp+10h] [ebp-28h] BYREF if ( !this )
return -2147483646;
HobList = (_WORD *)FpgaGetHobList();
HobByType = FpgaFindHobByType(v4, HobList);
if ( HobByType )
{
do
{
if ( FpgaHobGuidMatch(v5, (int)(HobByType + 4)) )
break;
HobByType = FpgaFindHobByType(v7, (_WORD *)((char *)HobByType + (unsigned __int16)HobByType[1]));
}
while ( HobByType );
if ( HobByType )
{
v8 = (char *)(HobByType + 12);
LABEL_8:
*this = v8;
return 0;
}
}
FpgaDebugPrint(0x80000000, "FPGA Configuration Get HOB-> HOB is not found, create it!\n");
FpgaZeroMem((int)buf, 0x26u);
Hob = FpgaCreateHob(v9, 62);
Hob_1 = Hob;
if ( Hob )
{
FpgaHobInitGuid((void *)(Hob + 8));
if ( Hob_1 != -24 )
{
v8 = FpgaCopyMem((char *)(Hob_1 + 24), buf, 0x26u);
if ( v8 )
{
FpgaDebugPrint(0x80000000, "FPGA Configuration Get HOB-> create it worked, init it!\n");
n4_1 = 0;
*(_WORD *)(v8 + 5) = -256;
*(_DWORD *)(v8 + 1) = 0;
v13 = v8 + 15;
*(_WORD *)(v8 + 31) = 0;
v8[37] = 0;
Index = 4;
do
{
*(v13 - 8) = -1;
*v13 = 11;
v13[8] = -1;
v13[12] = -1;
*(v13 - 4) = 0;
v13[18] = 0;
++v13;
--Index;
}
while ( Index );
Variable = (char *)FpgaGetVariable();
if ( Variable )
{
FpgaDebugPrint(0x80000000, "FPGA Configuration Get HOB-> Vaiable found use it!\n");
v8[6] = *Variable;
v8[31] = Variable[13];
v8[32] = Variable[14];
v8[37] = Variable[19];
do
{
v8[n4_1 + 23] = Variable[n4_1 + 5];
v8[n4_1 + 27] = Variable[n4_1 + 9];
v16 = Variable[n4_1 + 1];
if ( v16 )
{
if ( v16 == -1 )
v8[n4_1 + 7] = -1;
else v8[n4_1 + 7] = v16 - 1;
}
v8[n4_1 + 33] = Variable[n4_1 + 15];
++n4_1;
}
while ( n4_1 < 4 );
}
*v8 = 1;
goto LABEL_8;
}
}
}
FpgaDebugPrint(0x80000000, "FPGA Configuration Get HOB-> HOB IS NULL, could not create!\n");
return -2147483634;
}
// ============================================================
// FpgaMpServicesData
// ============================================================
int __thiscall FpgaMpServicesData(void *this)
{
int result; // eax unsigned int Index; // esi int v4; // edi int Status; // esi int DebugLib; // eax result = (*(int ( **)(void *, int, int *))(*(_DWORD *)this + 76))(this, 24 *dword_FFD6BA50, &dword_FFD6BA44);
if ( result >= 0 )
{
Index = 0;
if ( dword_FFD6BA50 )
{
v4 = 0;
while ( 1 )
{
result = (*(int ( **)(void *, int, unsigned int, int))(dword_FFD6BA48 + 4))(
this,
dword_FFD6BA48,
Index,
v4 + dword_FFD6BA44);
if ( result < 0 )
break;
++Index;
v4 += 24;
if ( Index >= dword_FFD6BA50 )
goto LABEL_6;
}
}
else
{
LABEL_6:
Status = (*(int ( **)(void *, int, int *))(dword_FFD6BA48 + 24))(this, dword_FFD6BA48, &dword_FFD6BA54);
FpgaDebugPrint(0x80000000, "BSP Index is: %X\n", dword_FFD6BA54);
if ( Status < 0 )
{
FpgaDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugLib = FpgaGetDebugLib();
if ( DebugLib )
(*(void ( **)(const char *, int, const char *))(DebugLib + 4))(
"e:\\hs\\PurleySktPkg\\Pei\\FpgaLoader\\FpgaLoader.c",
102,
"!EFI_ERROR (Status)");
}
dword_FFD6BA4C = *(_DWORD *)(24 *dword_FFD6BA54 + dword_FFD6BA44 + 12);
FpgaDebugPrint(0x80000000, "BSP Socket is: %X\n", dword_FFD6BA4C);
return Status;
}
}
return result;
}
// ============================================================
// FpgaGetPcdProtocol
// ============================================================
void *__thiscall FpgaGetPcdProtocol(void *this)
{
int PeiServices; // eax int Status; // eax int DebugLib; // eax void *this_1; // [esp+0h] [ebp-4h]
this_1 = this;
PeiServices = FpgaGetPeiServices();
Status = (*(int (__stdcall **)(int))(*(_DWORD *)PeiServices + 32))(PeiServices);
if ( Status < 0 )
{
FpgaDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugLib = FpgaGetDebugLib();
if ( DebugLib )
(*(void ( **)(const char *, int, const char *))(DebugLib + 4))(
"e:\\hs\\MdePkg\\Library\\PeiPcdLib\\PeiPcdLib.c",
49,
"!EFI_ERROR (Status)");
}
return this_1;
}
// ============================================================
// FpgaPeiLock
// ============================================================
int FpgaPeiLock()
{
int v0; // esi unsigned int ErrorLevel; // ebx char Index; // al int v3; // eax char v5; // [esp+Ch] [ebp-4h]
v0 = dword_FFD6BA38;
FpgaDebugPrint(0x80000000, "FPGA Loader, Perform PEI lock.\n");
ErrorLevel = *(_DWORD *)(v0 + 246472);
v5 = 0;
FpgaDebugPrint(0x80000000, "FPGA Loader, FpgaPresentBitMap = %X\n", ErrorLevel);
if ( ErrorLevel )
{
Index = 0;
do
{
if ( (ErrorLevel & 1) != 0 )
{
v3 = (*(int ( **)(int, char, _DWORD, int))(dword_FFD6BA40 + 4))(v0, v5, 0, 335561260);
(*(void ( **)(int, char, _DWORD, int, int))(dword_FFD6BA40 + 8))(v0, v5, 0, 335561260, v3 | 1);
Index = v5;
}
++Index;
ErrorLevel >>= 1;
v5 = Index;
}
while ( ErrorLevel );
}
return 0;
}
// ============================================================
// FpgaDisableUnusedSockets
// ============================================================
int __thiscall FpgaDisableUnusedSockets(_BYTE *this)
{
unsigned __int8 Index; // bl int Result; // edi int Status; // esi int v5; // ecx int ErrorLevel; // eax int PeiServices; // eax int Status; // eax int DebugLib; // eax int Status; // eax unsigned __int8 n4_1; // [esp+10h] [ebp-8h]
int v13; // [esp+14h] [ebp-4h] BYREF Index = 0;
Result = -2147483645;
n4_1 = 0;
Status = 0;
do
{
if ( ((unsigned __int8)(1 << Status) & *(this + 2)) != 0 )
{
v5 = (unsigned __int8)*(this + 6);
if ( ((1 << Status) & v5) == 0 )
{
FpgaDebugPrint(
0x80000000,
"FpgaPlatformEnabled = 0x%X. FpgaBitStreamStatus = 0x%X.\n",
v5,
(unsigned __int8)*(this + Status + 15));
FpgaDebugPrint(0x80000000, "Disable Fpga Socket[%x]!!!\n", Status);
ErrorLevel = (*(int ( **)(int, unsigned __int8, int, _DWORD))(dword_FFD6BA40 + 12))(dword_FFD6BA38, n4_1, 182, 0);
if ( ErrorLevel )
FpgaDebugPrint(0x80000000, "Socket[%x ]mailbox command REMOVE_MCP fail return : 0x%x.\n", Status, ErrorLevel);
PeiServices = FpgaGetPeiServices();
Status = (*(int ( **)(int, void *, _DWORD, _DWORD, int *))(*(_DWORD *)PeiServices + 32))(
PeiServices,
&unk_FFD6B9F4,
0,
0,
&v13);
if ( Status < 0 )
{
FpgaDebugPrint(0x80000000, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
DebugLib = FpgaGetDebugLib();
if ( DebugLib )
(*(void ( **)(const char *, int, const char *))(DebugLib + 4))(
"e:\\hs\\PurleyPlatPkg\\Library\\FpgaPlatformHooksLib\\FpgaPlatformHooksLib.c",
176,
"!EFI_ERROR (Status)");
}
Status = (*(int ( **)(unsigned __int8))(v13 + 80))(n4_1);
Result = Status;
if ( Status < 0 )
FpgaDebugPrint(0x80000000, "Socket[%x ] Fpga Power off fail return status = %r.\n", Status, Status);
}
}
++Index;
++Status;
n4_1 = Index;
}
while ( Index < 4u );
return Result;
}
// ============================================================
// FpgaLoadBitstream
// ============================================================
int FpgaLoadBitstream(int a1, _BYTE *a2)
{
int ErrorLevel; // eax int Result; // edi int n38_1; // eax char *AlignedPages; // eax int AlignedPages_1; // ebp unsigned int i; // edi char v10; // bl char v11; // al int ErrorLevel; // eax void *v13; // ecx unsigned int Buffer; // eax int v15; // ecx unsigned int n38_2; // eax int src_2; // eax int ErrorLevel; // eax int Result; // esi double ErrorLevel; // [esp-4h] [ebp-24h]
char *src; // [esp+10h] [ebp-10h] BYREF int src_1; // [esp+14h] [ebp-Ch] BYREF unsigned int n38; // [esp+18h] [ebp-8h] BYREF int v24; // [esp+1Ch] [ebp-4h]
v24 = a1;
ErrorLevel = FpgaFvLibN4PeGet((int)&unk_FFD6B974, (int *)&src, (int *)&n38);
Result = ErrorLevel;
if ( ErrorLevel )
{
FpgaDebugPrint(0x80000000, "Fpga Loader, FpgaFvLibN4PeGet returned error, %r\n", ErrorLevel);
return Result;
}
FpgaDebugPrint(0x80000000, "N4PE Date : %x \n", *((_DWORD *)src + 2));
FpgaDebugPrint(0x80000000, "N4PE BuildNumber : %x \n", *((unsigned __int16 *)src + 29));
FpgaDebugPrint(0x80000000, "N4PE Size : %x \n", *((_DWORD *)src + 4));
FpgaDebugPrint(0x80000000, "N4PE MajorRevisionID : %x \n", *((unsigned __int16 *)src + 3));
FpgaDebugPrint(0x80000000, "N4PE MinorHeaderVersion : %x \n", *(unsigned __int16 *)src);
n38_1 = *((_DWORD *)src + 4);
if ( n38 != n38_1 )
{
FpgaDebugPrint(
0x80000000,
"Fpga Loader, FpgaFvLibLoaderGet returned different size, header->%^04x, returned->%04x\n",
n38_1,
n38);
return -2147483644;
}
AlignedPages = (char *)FpgaAllocateAlignedPages(0x40u, 0x40000u);
AlignedPages_1 = (int)AlignedPages;
if ( !AlignedPages )
return -2147483639;
FpgaCopyMem(AlignedPages, src, n38);
for ( i = 0; i < 4; ++i )
{
v10 = 1 << i;
if ( ((unsigned __int8)(1 << i) & a2[5]) == 0 )
{
v11 = a2[i + 7];
if ( v11 != -1 )
{
if ( v11 )
{
if ( v11 != 1 )
{
ErrorLevel = -2147483645;
LABEL_16:
FpgaDebugPrint(0x80000000, "Fpga Loader, FpgaFvLibBitStreamGet returned error, %r\n", ErrorLevel);
a2[i + 7] = -1;
a2[4] |= v10;
a2[i + 15] = 5;
continue;
}
v13 = &unk_FFD6B964;
}
else
{
v13 = &unk_FFD6B984;
}
ErrorLevel = FpgaFvLibN4PeGet((int)v13, &src_1, (int *)&n38);
if ( ErrorLevel )
goto LABEL_16;
LODWORD(ErrorLevel) = src_1;
FpgaDebugPrint(0x80000000, "BBS ID : %g \n", ErrorLevel);
FpgaDebugPrint(0x80000000, "BBS Size : %x \n", *(_DWORD *)(src_1 + 16));
FpgaDebugPrint(0x80000000, "BBS Data Structure Version : %x \n", *(unsigned __int16 *)(src_1 + 20));
FpgaDebugPrint(0x80000000, "BBS Flags : %x \n", *(unsigned __int16 *)(src_1 + 22));
if ( n38 == *(_DWORD *)(src_1 + 16) )
{
Buffer = FpgaAllocateAlignedPages(1u, 8u);
v15 = Buffer;
if ( !Buffer )
return -2147483639;
*(_DWORD *)Buffer = AlignedPages_1;
*(_WORD *)(Buffer + 8) = 2;
*(_WORD *)(Buffer + 10) = 0;
n38_2 = n38;
*(_DWORD *)(v15 + 4) = AlignedPages_1 >> 31;
*(_DWORD *)(v15 + 12) = n38_2;
src_2 = src_1;
*(_DWORD *)(v15 + 24) = 0;
*(_DWORD *)(v15 + 28) = 0;
*(_QWORD *)(v15 + 16) = src_2;
ErrorLevel = sub_FFD69194(v24, i, v15);
if ( ErrorLevel )
{
FpgaDebugPrint(0x80000000, "Fpga Loader, FpgaLoaderLoadParmRegister returned error, %r\n", ErrorLevel);
a2[i + 7] = -1;
a2[4] |= v10;
a2[i + 15] = 6;
}
}
else
{
FpgaDebugPrint(0x80000000, "Fpga Loader, FpgaFvLibBitStreamGet returned error, %r\n", 0);
a2[i + 7] = -1;
a2[4] |= v10;
a2[i + 15] = 8;
}
}
}
}
(*(void ( **)(int, int, _DWORD, int))(dword_FFD6BA58 + 32))(dword_FFD6BA38, 145, 0, 255);
Result = sub_FFD692A1(v24, a2);
if ( Result )
{
(*(void ( **)(int, int, _DWORD, int))(dword_FFD6BA58 + 32))(dword_FFD6BA38, 146, 0, 255);
FpgaDebugPrint(0x80000000, "Fpga Loader, FpgaLoaderLoadTriggerRegister returned error, %r\n", Result);
}
return Result;
}