// XGMI TA command surface, decompiled with restored names, prototypes and types. // Source: psp_out/versions_win/ta_32-0-0-20_20a3d1a4.bin // Handlers resolved from fw/cmdmaps/xgmi.json; loc_* labels mapped to their // containing function. Generated by fw/ta_surface.py. // ================ cmd 0xb @ 0x403034 ================ int __fastcall xgmi_cmd0B(void *ctx, struct ta_params *params) { if ( params == nullptr ) return 2; if ( dword_406038 == 1 ) return 13; if ( *(_BYTE *)ctx != 0 ) JUMPOUT(0x402D1C); return 4; } // ================ cmd 0x1 @ 0x403058 ================ int __fastcall xgmi_cmd01(void *ctx, struct ta_params *params) { if ( params == nullptr ) return 2; if ( dword_406038 == 1 ) return 13; if ( *(_BYTE *)ctx == 0 ) return 4; *(_QWORD *)params = *((_QWORD *)ctx + 5 * dword_406020 + 4); xgmi_sysdrv_rpc_53(a1: 4); return 0; } // ================ cmd 0x5 @ 0x4030a8 ================ int __fastcall xgmi_cmd05(void *ctx, struct ta_params *params) { int v3; // r5 int v4; // r0 int v5; // r0 int v7; // [sp+4h] [bp-4h] BYREF v7 = 0; if ( params == nullptr ) return 2; if ( *(_BYTE *)ctx == 0 ) return 4; v3 = 1; if ( xgmi_sysdrv_rpc_1052(a1: 1, a2: (int)&v7) == 0 ) { v4 = v7; *(_DWORD *)params = (v7 & 0x40) == 0; if ( (v4 & 0x10000) != 0 ) { v5 = 1; } else if ( (v4 & 0x20000) != 0 ) { v5 = 2; } else if ( (v4 & 0x40000) != 0 ) { v5 = 8; } else if ( (v4 & 0x80000) != 0 ) { v5 = 9; } else if ( (v4 & 0x100000) != 0 ) { v5 = 10; } else if ( (v4 & 0x200000) != 0 ) { v5 = 16; } else { if ( (v4 & 0x400000) == 0 ) { v3 = 0; *((_DWORD *)params + 1) = 0; return v3; } v5 = 18; } *((_DWORD *)params + 1) = v5; return 0; } return v3; } // ================ cmd 0x3 @ 0x40311a ================ // COPY AUDIT: 1 call(s) with a non-literal length. // xgmi_cmd03(_BYTE *a1, int a2, int a3) len=int a3 // // Guards seen in this function: // if ( a2 != 0 && a3 != 0 ) /*0x403120*/ // if ( dword_406038 == 1 ) /*0x40312e*/ // else if ( *a1 != 0 ) /*0x403136*/ // // Heuristic lead, not a verdict: a non-literal length may still be bounded elsewhere (HDCP carries bounded ubfx and unbounded ldrb paths in one function). int __fastcall xgmi_cmd03(void *ctx, struct ta_params *params) { int v2; // r2 int result; // r0 result = 2; if ( params != nullptr && v2 != 0 ) { if ( dword_406038 == 1 ) { return 13; } else if ( *(_BYTE *)ctx != 0 ) { return sub_402D7C(a1: (int)ctx, a2: (int)params, a3: v2); } else { return 4; } } return result; } // ================ cmd 0x0 @ 0x403144 ================ // COPY AUDIT: 3 call(s) with a non-literal length. // xgmi_cmd00(_BYTE *a1, int *a2, int a3) len=int a3 // sub_403E80(a1: 4, a2: "XGMI nodes %d", v12) len=v12 // sub_402ED2(a1: v11, a2: a1, a3) len=a3 // // Guards seen in this function: // if ( a2 == nullptr ) /*0x40315a*/ // if ( dword_406038 == 1 ) /*0x403168*/ // if ( dword_406018 != 0 ) /*0x40317a*/ // if ( *a1 != 0 && byte_406014 == 0 ) /*0x40318a*/ // if ( sub_403D42(a1: v11) != 0 ) /*0x4031a6*/ // if ( v12 > 0x40 ) /*0x4031b6*/ // // Heuristic lead, not a verdict: a non-literal length may still be bounded elsewhere (HDCP carries bounded ubfx and unbounded ldrb paths in one function). int __fastcall xgmi_cmd00(void *ctx, struct ta_params *params) { int result; // r0 char v5; // r0 BOOL v6; // r0 int v7; // r1 BOOL v8; // r0 struct ta_params *v9; // r1 _DWORD v10[261]; // [sp+0h] [bp-414h] BYREF xgmi_lib_zero_fill_words(dst: v10, len: 0x414u); if ( params == nullptr ) return 2; if ( dword_406038 == 1 ) { *(_BYTE *)ctx = 1; dword_406018 = 1; return 0; } if ( dword_406018 != 0 ) { v5 = byte_406014; if ( *(_BYTE *)ctx != 0 && byte_406014 == 0 ) { v6 = true; v7 = 1; goto LABEL_15; } } else { v5 = byte_406014; } LOBYTE(v10[1]) = v5; if ( xgmi_sysdrv_rpc_104B(a1: (int)v10) != 0 ) return 9; xgmi_sysdrv_rpc_53(a1: 4); if ( v10[2] > 0x40u ) return 7; v7 = dword_406018; if ( dword_406018 != 0 ) v7 = 1; v6 = byte_406014 == 0; LABEL_15: if ( v7 != 0 && v6 ) { v8 = true; goto LABEL_18; } if ( xgmi_sysdrv_rpc_1048(a1: (int)&dword_406034) != 0 ) return 9; if ( (unsigned int)dword_406034 <= 0x20 ) { result = xgmi_cmd00__h1(ctx: v10, params: v9); if ( result != 0 ) { LABEL_24: *(_DWORD *)params = result; return result; } v8 = byte_406014 == 0; LABEL_18: if ( *(_BYTE *)ctx != 0 && v8 ) result = 0; else result = xgmi_cmd00__h2(ctx: v10, params: (struct ta_params *)ctx); goto LABEL_24; } return 7; } // ================ cmd 0x6 @ 0x403238 ================ int __fastcall xgmi_cmd06(void *ctx, struct ta_params *params) { int v3; // r5 int v4; // r0 int v6; // [sp+4h] [bp-4h] BYREF v6 = 0; if ( params == nullptr ) return 2; if ( *(_BYTE *)ctx == 0 ) return 4; xgmi_lib_zero_fill_words(dst: params, len: 0x84u); v3 = 1; if ( xgmi_sysdrv_rpc_1052(a1: 1, a2: (int)&v6) == 0 ) { *(_DWORD *)params = v6; if ( xgmi_sysdrv_rpc_1052(a1: 2, a2: (int)&v6) != 0 ) { v4 = 4; } else { *((_DWORD *)params + 1) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 3, a2: (int)&v6) != 0 ) { v4 = 8; } else { *((_DWORD *)params + 2) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 4, a2: (int)&v6) != 0 ) { v4 = 12; } else { *((_DWORD *)params + 3) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 5, a2: (int)&v6) != 0 ) { v4 = 16; } else { *((_DWORD *)params + 4) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 6, a2: (int)&v6) != 0 ) { v4 = 20; } else { *((_DWORD *)params + 5) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 7, a2: (int)&v6) != 0 ) { v4 = 24; } else { *((_DWORD *)params + 6) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 8, a2: (int)&v6) != 0 ) { v4 = 28; } else { *((_DWORD *)params + 7) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 9, a2: (int)&v6) != 0 ) { v4 = 32; } else { *((_DWORD *)params + 8) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 10, a2: (int)&v6) != 0 ) { v4 = 36; } else { *((_DWORD *)params + 9) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 11, a2: (int)&v6) != 0 ) { v4 = 40; } else { *((_DWORD *)params + 10) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 12, a2: (int)&v6) != 0 ) { v4 = 44; } else { *((_DWORD *)params + 11) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 13, a2: (int)&v6) != 0 ) { v4 = 48; } else { *((_DWORD *)params + 12) = v6; if ( xgmi_sysdrv_rpc_1052(a1: 14, a2: (int)&v6) == 0 ) { v3 = 0; *((_DWORD *)params + 13) = v6; v4 = 56; goto LABEL_33; } v4 = 52; } } } } } } } } } } } } v3 = 1; LABEL_33: *((_DWORD *)params + 32) = v4; } return v3; } // ================ cmd 0x8 @ 0x403364 ================ int __fastcall xgmi_cmd08(void *ctx, struct ta_params *params) { int v4; // [sp+4h] [bp-4h] BYREF v4 = 0; if ( params == nullptr ) return 2; if ( *(_BYTE *)ctx == 0 ) return 4; *(_DWORD *)params = 0; *((_DWORD *)params + 1) = 0; if ( xgmi_sysdrv_rpc_1052(a1: 9, a2: (int)&v4) != 0 ) return 1; *(_DWORD *)params = v4; if ( xgmi_sysdrv_rpc_1052(a1: 10, a2: (int)&v4) != 0 ) return 1; *((_DWORD *)params + 1) = v4; return 0; } // ================ cmd 0x9 @ 0x4033a8 ================ int __fastcall xgmi_cmd09(void *ctx, struct ta_params *params) { int v2; // r2 bool v3; // zf int result; // r0 if ( params == nullptr ) return 2; if ( *(_BYTE *)ctx == 0 ) return 4; if ( *(_DWORD *)params == 0 ) return 3; v2 = *((unsigned __int8 *)params + 8); v3 = v2 == 4; if ( v2 != 4 ) v3 = v2 == 2; if ( !v3 ) return 3; result = xgmi_sysdrv_rpc_1061(a1: *(_DWORD *)params, a2: (int)params + 4, a3: v2); if ( result != 0 ) return 11; return result; } // ================ cmd 0x4 @ 0x4033d8 ================ int __fastcall xgmi_cmd04(void *ctx, struct ta_params *params) { if ( params == nullptr ) return 2; if ( dword_406038 == 1 ) return 13; if ( *(_BYTE *)ctx != 0 ) return sub_402EFE(a1: (int)ctx, a2: (int)params); return 4; } // ================ cmd 0x7 @ 0x4033fc ================ int __fastcall xgmi_cmd07(void *ctx, struct ta_params *params) { unsigned int v2; // r1 if ( params == nullptr ) return 2; if ( *(_BYTE *)ctx == 0 ) return 4; v2 = *(_DWORD *)params; if ( v2 <= 0xFF ) return xgmi_sysdrv_rpc_1053(a1: 256, a2: v2) != 0; else return 3; } // ================ cmd 0xa @ 0x403426 ================ int __fastcall xgmi_cmd0A(void *ctx, struct ta_params *params) { int v2; // r2 bool v3; // zf int result; // r0 if ( params == nullptr ) return 2; if ( *(_BYTE *)ctx == 0 ) return 4; if ( *(_DWORD *)params == 0 ) return 3; v2 = *((unsigned __int8 *)params + 8); v3 = v2 == 4; if ( v2 != 4 ) v3 = v2 == 2; if ( !v3 ) return 3; result = xgmi_sysdrv_rpc_1062(a1: *(_DWORD *)params, a2: *((_DWORD *)params + 1), a3: v2); if ( result != 0 ) return 11; return result; } // --------------------------------------------------------------- // COMMANDS ENTERED AT AN INTERNAL LABEL, NOT AT A FUNCTION ENTRY. // These dispatch into the middle of a larger function, which is what a // switch-style dispatcher produces. IDA refuses to split them out, and // undefining the owner to force a split was not worth the risk, so the // containing function is reproduced below IN FULL. Read the command's // code at the stated offset -- the function as a whole is NOT the handler. // --------------------------------------------------------------- // cmd 0x2 -> 0x402fec (enters xgmi_cmd00__h6+0x88) // ---- containing function xgmi_cmd00__h6 @ 0x402f64 (entered mid-body by the commands above) ---- int __fastcall xgmi_cmd00__h6(void *ctx, struct ta_params *params) { int v2; // r2 _DWORD *v3; // r3 _DWORD *v6; // r8 int v7; // r9 int v8; // r4 _QWORD *v10; // r1 int a1; // [sp+Ch] [bp-4Ch] BYREF _BYTE dst[68]; // [sp+10h] [bp-48h] BYREF int v13; // [sp+54h] [bp-4h] v13 = dword_403C7C; v6 = v3; v7 = v2; a1 = 0; xgmi_lib_zero_fill_words(dst, len: 0x40u); v8 = xgmi_sysdrv_rpc_1((int)&a1, a2: 1342177282, a3: 5, a4: 0); if ( v8 == 0 ) { v8 = xgmi_sysdrv_rpc_D(a1, a2: (int)ctx, a3: (int)params, a4: (int)dst); if ( v8 == 0 ) { xgmi_TA_InvokeCommandEntryPoint__h1(a1: v7); *v6 = 64; v8 = 0; } } if ( a1 != 0 ) xgmi_sysdrv_rpc_2(a1); if ( dword_403C7C == v13 ) return v8; v10 = (_QWORD *)((unsigned __int64)((__int64 (__fastcall *)(int))loc_403C80)(a1: dword_403C7C - v13) >> 32); if ( v10 == nullptr ) return 2; if ( dword_406038 == 1 ) return 13; if ( dword_406018 == 0 ) return 4; *v10 = *(_QWORD *)&dword_406028; xgmi_sysdrv_rpc_53(a1: 4); return 0; }