HalpInterruptParseMadt

INT64 __fastcall HalpInterruptParseMadt(_MAPIC *MadtTable, UINT64 Phase, INT64 a3, UINT8 a4){
  unsigned int v5; 
  unsigned int v6; 
  int v7; 
  unsigned int *APICTables; 
  char *v9; 
  char *v10; 
  unsigned int *v11; 
  __int64 v12; 
  char *v13; 
  unsigned int *v14; 
  char v15; 
  bool v16; 
  unsigned int v17; 
  char *v18; 
  __int64 v19; 
  unsigned int *v20; 
  __int64 v21; 
  __int64 v22; 
  __int64 v23; 
  unsigned int *v24; 
  unsigned int v25; 
  _DWORD *v26; 
  __int64 v27; 
  __int64 v29; 
  unsigned int *v30; 
  char v31; 
  _DWORD *v32; 
  unsigned int v33; 
  unsigned int v34; 
  _DWORD *v35; 
  int v36; 
  int v37; 
  int v38; 
  int v39; 
  unsigned int v40; 
  _DWORD *v41; 
  unsigned int v42; 
  ULONG_PTR v43; 
  __int64 v44; 
  ULONG_PTR v45; 
  unsigned __int64 v46; 
  __int128 v47; 
  __int128 v48; 
  __int128 v49; 
  __int128 v50; 
  ULONG_PTR v51; 
  __int64 v52; 
  _DWORD *v53; 
  unsigned int v54; 
  PSTR v55; 
  __int64 v56; 
  unsigned int v57; 
  int v58; 
  int v59; 
  __int64 *v60; 
  __int64 v61; 
  __int64 v62; 
  PSTR v63; 
  int v64; 
  char v65; 
  int v66; 
  unsigned int v67; 
  ULONG_PTR v68; 
  __int64 v69; 
  int v70; 
  unsigned int v71; 
  PSTR MemoryInternal; 
  _OWORD *v73; 
  unsigned __int64 v74; 
  __int128 v75; 
  __int128 v76; 
  __int128 v77; 
  __int128 v78; 
  ULONG_PTR v79; 
  __int64 v80; 
  ULONG_PTR v81; 
  unsigned __int64 v82; 
  __int128 v83; 
  __int128 v84; 
  __int128 v85; 
  __int128 v86; 
  __int64 v87; 
  unsigned int v88; 
  v87 = 0i64;
  v5 = 0;
  v6 = 0;
  v88 = 0;
  v7 = 0;
  APICTables = MadtTable->APICTables;
  v9 = (char *)MadtTable + MadtTable->Header.Length;
  v10 = (char *)MadtTable->APICTables + 2;
  v11 = MadtTable->APICTables;
  if( (_DWORD)Phase )
  {
    if( v10 > v9 )
    {
LABEL_39:
      if( (unsigned int)HalpInterruptProcessorCount > 1 )
      {
        v34 = 0;
        if( (_DWORD)HalpInterruptProcessorCount )
        {
          v35 = (_DWORD *)(HalpInterruptProcessorState + 8);
          while( *v35 != HalpInterruptP0LocalId )
          {
            ++v34;
            v35 += 16;
            if( v34 >= (unsigned int)HalpInterruptProcessorCount )
              goto LABEL_44;
          }
          v5 = v34;
        }
LABEL_44:
        v36 = ~(*((_DWORD *)KeGetCurrentPrcb() + 39) - 1);
        v37 = v36 & HalpInterruptP0LocalId;
        v38 = ~(*((_DWORD *)KeGetCurrentPrcb() + 39) * *((_DWORD *)KeGetCurrentPrcb() + 38) - 1);
        v39 = v38 & HalpInterruptP0LocalId;
        if( v5 )
        {
          v73 = (_OWORD *)HalpInterruptProcessorState;
          v74 = (unsigned __int64)v5 << 6;
          v75 = *(_OWORD *)HalpInterruptProcessorState;
          v76 = *(_OWORD *)(HalpInterruptProcessorState + 16);
          v77 = *(_OWORD *)(HalpInterruptProcessorState + 32);
          v78 = *(_OWORD *)(HalpInterruptProcessorState + 48);
          *(_OWORD *)HalpInterruptProcessorState = *(_OWORD *)(v74 + HalpInterruptProcessorState);
          v73[1] = *(_OWORD *)((char *)v73 + v74 + 16);
          v73[2] = *(_OWORD *)((char *)v73 + v74 + 32);
          v73[3] = *(_OWORD *)((char *)v73 + v74 + 48);
          *(_OWORD *)((char *)v73 + v74) = v75;
          *(_OWORD *)((char *)v73 + v74 + 16) = v76;
          *(_OWORD *)((char *)v73 + v74 + 32) = v77;
          *(_OWORD *)((char *)v73 + v74 + 48) = v78;
        }
        v40 = 1;
        if( (unsigned int)HalpInterruptProcessorCount > 1 )
        {
          v41 = (_DWORD *)(HalpInterruptProcessorState + 72);
          do
          {
            if( (v36 & *v41) != v37 )
              break;
            ++v40;
            v41 += 16;
          }
          while( v40 < (unsigned int)HalpInterruptProcessorCount );
        }
        v42 = v40 + 1;
        if( v40 + 1 < (unsigned int)HalpInterruptProcessorCount )
        {
          v43 = HalpInterruptProcessorState + ((unsigned __int64)v42 << 6);
          v44 = (unsigned int)HalpInterruptProcessorCount - v42;
          do
          {
            if( (v36 & *(_DWORD *)(v43 + 8)) == v37 )
            {
              v45 = HalpInterruptProcessorState;
              v46 = (unsigned __int64)v40++ << 6;
              v47 = *(_OWORD *)(v46 + HalpInterruptProcessorState);
              v48 = *(_OWORD *)(v46 + HalpInterruptProcessorState + 16);
              v49 = *(_OWORD *)(v46 + HalpInterruptProcessorState + 32);
              v50 = *(_OWORD *)(v46 + HalpInterruptProcessorState + 48);
              *(_OWORD *)(v46 + HalpInterruptProcessorState) = *(_OWORD *)v43;
              *(_OWORD *)(v46 + v45 + 16) = *(_OWORD *)(v43 + 16);
              *(_OWORD *)(v46 + v45 + 32) = *(_OWORD *)(v43 + 32);
              *(_OWORD *)(v46 + v45 + 48) = *(_OWORD *)(v43 + 48);
              *(_OWORD *)v43 = v47;
              *(_OWORD *)(v43 + 16) = v48;
              *(_OWORD *)(v43 + 32) = v49;
              *(_OWORD *)(v43 + 48) = v50;
            }
            v43 += 64i64;
            --v44;
          }
          while( v44 );
        }
        if( v40 > 1 )
          HalpInterruptHyperThreading = 1;
        v51 = HalpInterruptProcessorState;
        HalpInterruptSortProcessorTable(HalpInterruptProcessorState + 64, v40 - 1);
        v52 = v40;
        if( v40 < (unsigned int)HalpInterruptProcessorCount )
        {
          v53 = (_DWORD *)(((unsigned __int64)v40 << 6) + v51 + 8);
          do
          {
            if( (v38 & *v53) != v39 )
              break;
            ++v40;
            v53 += 16;
          }
          while( v40 < (unsigned int)HalpInterruptProcessorCount );
        }
        v54 = v40 + 1;
        if( v40 + 1 < (unsigned int)HalpInterruptProcessorCount )
        {
          v79 = HalpInterruptProcessorState + ((unsigned __int64)v54 << 6);
          v80 = (unsigned int)HalpInterruptProcessorCount - v54;
          do
          {
            if( (v38 & *(_DWORD *)(v79 + 8)) == v39 )
            {
              v81 = HalpInterruptProcessorState;
              v82 = (unsigned __int64)v40++ << 6;
              v83 = *(_OWORD *)(v82 + HalpInterruptProcessorState);
              v84 = *(_OWORD *)(v82 + HalpInterruptProcessorState + 16);
              v85 = *(_OWORD *)(v82 + HalpInterruptProcessorState + 32);
              v86 = *(_OWORD *)(v82 + HalpInterruptProcessorState + 48);
              *(_OWORD *)(v82 + HalpInterruptProcessorState) = *(_OWORD *)v79;
              *(_OWORD *)(v82 + v81 + 16) = *(_OWORD *)(v79 + 16);
              *(_OWORD *)(v82 + v81 + 32) = *(_OWORD *)(v79 + 32);
              *(_OWORD *)(v82 + v81 + 48) = *(_OWORD *)(v79 + 48);
              *(_OWORD *)v79 = v83;
              *(_OWORD *)(v79 + 16) = v84;
              *(_OWORD *)(v79 + 32) = v85;
              *(_OWORD *)(v79 + 48) = v86;
            }
            v79 += 64i64;
            --v80;
          }
          while( v80 );
        }
        HalpInterruptSortProcessorTable(HalpInterruptProcessorState + (v52 << 6), v40 - (unsigned int)v52);
        HalpInterruptSortProcessorTable(
          HalpInterruptProcessorState + ((unsigned __int64)v40 << 6),
          (unsigned int)HalpInterruptProcessorCount - v40);
        if( HalpInterruptBlockHyperthreading && HalpInterruptHyperThreading )
          HalpInterruptBlockSmtSiblings();
      }
      return v88;
    }
    while( 1 )
    {
      v29 = *((unsigned __int8 *)v11 + 1);
      if( (unsigned __int8)v29 < 2u || (char *)v11 + v29 > v9 )
        goto LABEL_39;
      v30 = v11;
      v11 = (unsigned int *)((char *)v11 + v29);
      v31 = *(_BYTE *)v30;
      if( *(_BYTE *)v30 || (_BYTE)v29 != 8 )
      {
        if( v31 == 9 && (_BYTE)v29 == 16 )
        {
          v32 = (_DWORD *)(HalpInterruptProcessorState + ((unsigned __int64)v6 << 6));
          if( (v30[2] & 1) == 0 )
            goto LABEL_38;
          *v32 = v30[1];
          v32[1] = v30[3];
          v33 = v30[1];
          goto LABEL_37;
        }
        if( v31 == 11
          && (unsigned __int8)v29 >= 0x28u
          && ((unsigned int)HalpInterruptGicVersion < 3 || (unsigned __int8)v29 >= 0x4Cu) )
        {
          v68 = HalpInterruptProcessorState + ((unsigned __int64)v6 << 6);
          if( (v30[3] & 1) != 0 )
          {
            v69 = *((_QWORD *)v30 + 3);
            if( v30[4] == 1 && v69 )
              v70 = HalpInterruptMapParkedPage(v69, HalpInterruptProcessorState + ((unsigned __int64)v6 << 6));
            else
              v70 = -1073741811;
            v88 = v70;
            if( v70 == -1073741670 )
              return 3221225626i64;
            if( v70 >= 0 )
            {
              if( (unsigned int)HalpInterruptGicVersion < 3 )
                v71 = v30[1];
              else
                v71 = (*(_QWORD *)(v30 + 17) >> 8) & 0xFF000000 | v30[17] & 0xFFFFFF;
              *(_DWORD *)v68 = v71;
              *(_DWORD *)(v68 + 4) = v30[2];
              *(_DWORD *)(v68 + 8) = v30[1];
              *(_DWORD *)(v68 + 40) = v30[5];
              if( *((_BYTE *)v30 + 1) < 0x4Cu )
              {
                *(_QWORD *)(v68 + 48) = 0i64;
                *(_BYTE *)(v68 + 45) = 0;
              }
              else
              {
                *(_QWORD *)(v68 + 48) = *(_QWORD *)(v30 + 17);
                *(_BYTE *)(v68 + 45) = 1;
                if( *((_BYTE *)v30 + 1) >= 0x4Du )
                  *(_BYTE *)(v68 + 44) = *((_BYTE *)v30 + 76);
              }
              if( (v30[3] & 2) != 0 )
                *(_BYTE *)(v68 + 14) = 1;
              ++v6;
            }
          }
        }
        else
        {
          if( v31 == 3 && (_BYTE)v29 == 8 )
          {
            MemoryInternal = HalpMmAllocateMemoryInternal(0x18ui64, MmCached);
            v63 = MemoryInternal;
            if( !MemoryInternal )
              return 3221225626i64;
            MemoryInternal[8] = 0;
            *((_DWORD *)MemoryInternal + 4) = *((unsigned __int16 *)v30 + 1);
            v66 = v30[1];
            goto LABEL_90;
          }
          if( v31 == 4 && (_BYTE)v29 == 6 || v31 == 10 && (_BYTE)v29 == 12 )
          {
            v63 = HalpMmAllocateMemoryInternal(0x18ui64, MmCached);
            if( !v63 )
              return 3221225626i64;
            *(_OWORD *)v63 = 0i64;
            *((_QWORD *)v63 + 2) = 0i64;
            v63[8] = 1;
            if( *(_BYTE *)v30 == 4 )
            {
              v64 = *((unsigned __int8 *)v30 + 2);
              *((_DWORD *)v63 + 3) = v64;
              if( *((_BYTE *)v30 + 2) == 0xFF )
                v64 = -1;
              *((_DWORD *)v63 + 3) = v64;
              *((_DWORD *)v63 + 4) = *(unsigned __int16 *)((char *)v30 + 3);
              v65 = *((_BYTE *)v30 + 5);
            }
            else
            {
              *((_DWORD *)v63 + 3) = v30[1];
              *((_DWORD *)v63 + 4) = *((unsigned __int16 *)v30 + 1);
              v65 = *((_BYTE *)v30 + 8);
            }
            v66 = -(v65 != 0) - 4;
LABEL_90:
            *((_DWORD *)v63 + 5) = v66;
            *(_QWORD *)v63 = HalpInterruptNmiSources;
            HalpInterruptNmiSources = (__int64)v63;
            goto LABEL_38;
          }
          if( v31 == 2 && (_BYTE)v29 == 10 )
          {
            if( (int)HalpInterruptGsiToLine(v30[1], &v87) >= 0 )
            {
              v55 = HalpMmAllocateMemoryInternal(0x28ui64, MmCached);
              v56 = (__int64)v55;
              if( !v55 )
                return 3221225626i64;
              *(_OWORD *)v55 = 0i64;
              *((_OWORD *)v55 + 1) = 0i64;
              *((_QWORD *)v55 + 4) = 0i64;
              v57 = *((unsigned __int8 *)v30 + 3);
              if( v57 < 8 )
              {
                v58 = 45056;
              }
              else
              {
                v57 -= 8;
                v58 = 45057;
              }
              *(_DWORD *)(v56 + 16) = v58;
              *(_DWORD *)(v56 + 20) = v57;
              *(_QWORD *)(v56 + 24) = v87;
              v59 = 2;
              if( (v30[2] & 3) < 2 )
                v59 = 1;
              *(_DWORD *)(v56 + 36) = v59;
              *(_DWORD *)(v56 + 32) = (v30[2] & 8) == 0;
              v60 = (__int64 *)qword_140C49608;
              if( *(__int64 **)qword_140C49608 != &HalpInterruptOverrides )
                __fastfail(3u);
              *(_QWORD *)v56 = &HalpInterruptOverrides;
              *(_QWORD *)(v56 + 8) = v60;
              *v60 = v56;
              qword_140C49608 = v56;
            }
            v88 = 0;
          }
        }
      }
      else
      {
        v32 = (_DWORD *)(HalpInterruptProcessorState + ((unsigned __int64)v6 << 6));
        if( (v30[1] & 1) != 0 )
        {
          *v32 = *((unsigned __int8 *)v30 + 3);
          v32[1] = *((unsigned __int8 *)v30 + 2);
          v33 = *((unsigned __int8 *)v30 + 3);
LABEL_37:
          v32[2] = v33;
          ++v6;
        }
      }
LABEL_38:
      if( (char *)v11 + 2 > v9 )
        goto LABEL_39;
    }
  }
  if( v10 <= v9 )
  {
    while( 1 )
    {
      v12 = *((unsigned __int8 *)v11 + 1);
      if( (unsigned __int8)v12 < 2u )
        goto LABEL_13;
      v13 = (char *)v11 + v12;
      if( (char *)v11 + v12 > v9 )
        goto LABEL_13;
      v14 = v11;
      v11 = (unsigned int *)((char *)v11 + v12);
      v15 = *(_BYTE *)v14;
      if( !*(_BYTE *)v14 && (_BYTE)v12 == 8 )
        break;
      if( v15 == 9 && (_BYTE)v12 == 16 )
      {
        v16 = (v14[2] & 1) == 0;
        goto LABEL_8;
      }
      if( v15 == 1 && (_BYTE)v12 == 12 )
      {
        ++HalpInterruptIoApicCount;
      }
      else if( v15 == 11 && (unsigned __int8)v12 >= 0x28u )
      {
        v16 = (v14[3] & 1) == 0;
        goto LABEL_8;
      }
LABEL_12:
      if( v13 + 2 > v9 )
        goto LABEL_13;
    }
    v16 = (v14[1] & 1) == 0;
LABEL_8:
    if( !v16 )
      LODWORD(HalpInterruptProcessorCount) = HalpInterruptProcessorCount + 1;
    if( ++v7 > (unsigned int)HalpInterruptMaxProcessors )
      HalpInterruptMaxProcessors = v7;
    goto LABEL_12;
  }
LABEL_13:
  HalpInterruptIoApic = (__int64)HalpMmAllocateMemoryInternal((unsigned int)(16 * HalpInterruptIoApicCount), MmCached);
  if( HalpInterruptIoApic )
  {
    v17 = 0;
    v18 = (char *)MadtTable + MadtTable->Header.Length;
    if( v10 <= v18 )
    {
      do
      {
        v19 = *((unsigned __int8 *)APICTables + 1);
        if( (unsigned __int8)v19 < 2u || (char *)APICTables + v19 > v18 )
          break;
        v20 = APICTables;
        APICTables = (unsigned int *)((char *)APICTables + v19);
        if( *(_BYTE *)v20 == 1 && (_BYTE)v19 == 12 )
        {
          v61 = HalpInterruptIoApic;
          v62 = 2i64 * v17++;
          *(_DWORD *)(HalpInterruptIoApic + 8 * v62) = *((unsigned __int8 *)v20 + 2);
          *(_DWORD *)(v61 + 8 * v62 + 4) = v20[1];
          *(_DWORD *)(v61 + 8 * v62 + 8) = v20[2];
        }
      }
      while( (char *)APICTables + 2 <= v18 );
    }
    if( HalpInterruptIoApicCount )
    {
      v21 = (unsigned int)HalpInterruptIoApicCount;
      v22 = (unsigned int)HalpInterruptIoApicCount;
      v23 = HalpInterruptIoApic + 8;
      v24 = (unsigned int *)(HalpInterruptIoApic + 12);
      do
      {
        v25 = *(v24 - 1);
        v26 = (_DWORD *)v23;
        *v24 = -1;
        v27 = v21;
        do
        {
          if( *v26 > v25 )
          {
            v67 = *v26 - v25;
            if( v67 < *v24 )
              *v24 = v67;
          }
          v26 += 4;
          --v27;
        }
        while( v27 );
        v24 += 4;
        --v22;
      }
      while( v22 );
    }
    return v88;
  }
  HalpInterruptLastProblem = 30;
  return 3221225495i64;
}

Referenced by:

HalpInterruptParseAcpiTables