Jump to content

ATI Radeon unsupported cards debugging


8 posts in this topic

Recommended Posts

This must be the worst graphic card ever made http://www.notebookcheck.net/AMD-Radeon-R2-Mullins-Beema.115402.0.html

 

Anyway atm i got this...

 

9852.jpg

 

 

This is just a small step in making it full usuable. Current stage loads framebuffer only.

 

Tested on ATI 0x9852 - os x 10.11.4

 

 

Howto use

 

- Download latest attach

- Get your card bios rom file.

- Open and paste in ATY,bin_image in AMD8000Controller.kext plist file.

- Care if you're changing aty_config parameters.

- reboot and cross fingers.

 

 

V02 fixes

- no need to edit framebuffer/connectors in kext/clover/dsdt - they will be auto assigned from bios table.

- removed patch from 7000. added info.plist from 8000

- out of sync when using a 2nd screen can be fixed using the attached s.zip script + fixedid (move edid folder to s/l/displays)

 

 

 

 

Developper notes

 

- Debug tool from http://www.insanelymac.com/forum/topic/312254-realtek-ethernet-panic-debug-driver-using-xcode-ui/

- i've just compiled DisableMonitor.app from github - maybe usefull for some1

v01.zip

v02.zip

DisableMonitor.zip

atomdis.zip

s.zip

FixEDID.zip

  • Like 4
  • 1 month later...

Update for Mac OS X Siera 10.12.5

 

Sierra added legacy support.kext

 

edit AMDLegacySupport.kext info.plist with your card for legacy framebuffer or use AMDSupport.kext if it fails

 

 

debug functions for framebuffer/controller start

ATIController::start

PP_Initialize_internal
AtiAtomBiosDceInterface::parseHotPlugId:
AtiAtomBiosUtilities::getGpioPinLutInfo(unsigned char)
AtiAtomBiosDceInterface::populateConnectorInfo
CIDisplayEngineClock::GetDPRefClkFrequency
parseSenseId
CIDpAudioConnection::init
reorderConnectorBuffer

acceleration functions

this is my lldbinit file atm

settings set target.load-script-from-symbol-file true
settings set target.process.thread.step-out-avoid-nodebug true
settings set target.process.detach-keeps-stopped true
settings set plugin.process.kdp-remote.packet-timeout 30
kdp-remote 192.168.2.4
showlldbtypesummaries
command script import /sim/trace.py
target modules add /sim/1
target modules add /sim/2
target modules add /sim/3
target modules add /sim/4
target modules add /sim/5
target modules add /sim/6
target modules add /sim/7
target modules add /sim/8
target modules add /sim/9
target modules add /sim/10
b ATIController::start
b AMDRadeonX4000_AMDGraphicsAccelerator::start
b IOGraphicsAccelerator2::start
b AMDRadeonX4000_AMDAccelDisplayMachine::init
b PP_Initialize_internal
b CAILEarlyASICInit
b AMDBonaireHardware::powerUp
b Cail_MCILWaitForIsGfxHung
b Bonaire_LoadUcode
b get_asic_caps_set_from_table
b CopyDDI_CAPS
b PHM_Initialize
b findDeviceAsicCaps
b PECI_SetupInitInfo
b createPCIDeviceList

traced ucode sample (for 0x9852) 

 

#9 rlc

#114 ce
#217 pfp
#179 me
#76 sdma

 

 

kextwait en0 helper

 

modify the info.plist (see attach) to load this kext after en0 is plugged to a router

the 30sec delay will help avoid invalid IP address on debug start and

will make the debugger stop on a start function (works on amd/intel drivers)

 

 

AMDLegacySupport.kext.zip

AMDSupport.kext.zip

Info.plist.zip

kextwait.kext.zip

  • Like 1
  • 1 month later...

i would like to figure out why i get wrong bios reading - i'm shure must be some memory address mapping. check this code from amd8000controller:

            }
          }
        }
      }
    }
  }
  else
  {
    v9 = -536870211;
  }
  return (unsigned int)v9;
}

probably this canbe fixed for any card.how? idk

 

 

all cards need tobe assigned special functions in order to work. code is here (from AMDRadeonX4000.kext)

LABEL_23:
  result = CailCapsEnabled(v1, 328LL);
  if ( result )
  {
    Cail_Greenland_InitFunctionPointer(a1, 328LL);
    result = CailCapsEnabled(v1, 83LL);
    if ( result )
      result = Cail_Raven_InitFunctionPointer(a1, 83LL);
  }
  return result;
}

small changes might help. on a bogus card like the1 i have i get a wrong family id of 120 (should be 125. where can this be fixed? check next function

signed __int64 __fastcall get_asic_caps_set_from_table(__int64 a1, __int64 a2, int a3)
{
  __int64 v3; // r13@1
  __int64 v4; // rcx@1
  signed __int64 result; // rax@1
  __int64 v6; // r9@2
  __int64 v7; // r8@2
  char *v8; // rbx@2
  signed int v9; // er14@2
  signed int v10; // er12@2
  unsigned int v11; // er11@2
  __int64 v12; // rcx@4
  signed int v13; // esi@8
  unsigned __int64 v14; // rsi@9
  signed __int64 v15; // r12@18
  __int64 v16; // rcx@19
  __int64 v17; // rbx@22
  int v18; // eax@22
  __int64 *v19; // rax@24
  __int64 v20; // rax@26
  __int64 *v21; // rax@28
  __int64 v22; // r14@28
  int v23; // eax@29
  int v24; // ecx@31
  unsigned int v25; // esi@32
  char *v26; // rdx@32
  bool v27; // cl@35
  int v28; // ecx@37
  int v29; // ecx@41
  unsigned int v30; // ecx@43
  int v31; // edi@43

  v3 = a2;
  v4 = CAILAsicCapsInitTable[1];
  result = 5LL;
  if ( v4 == 0xFFFFFFFFLL )
    return result;
  v6 = *(_DWORD *)(a2 + 4);
  v7 = *(_DWORD *)(a2 + 28);
  v8 = (char *)&CAILAsicCapsInitTable[2];
  v9 = -1;
  v10 = 0;
  v11 = 0;
  while ( 1 )
  {
    if ( v4 == v6 )
    {
      v12 = *((_QWORD *)v8 + 2);
      if ( v12 == 0xFFFFFFFFLL || a3 || v12 == *(_DWORD *)(v3 + 16) )
        break;
    }
LABEL_14:
    ++v10;
    v4 = *((_QWORD *)v8 + 6);
    v8 += 56;
    v13 = v9;
    if ( v4 == 0xFFFFFFFFLL )
      goto LABEL_17;
  }
  if ( !a3 )
  {
    v13 = v10;
    if ( *(_QWORD *)v8 == v7 )
      goto LABEL_17;
    v14 = *((_QWORD *)v8 + 1);
    if ( v11 < v14 )
      v9 = v10;
    if ( v11 >= v14 )
      LODWORD(v14) = v11;
    v11 = v14;
    goto LABEL_14;
  }
  v13 = v10;
LABEL_17:
  if ( v13 != -1 )
  {
    v15 = 7LL * v13;
    if ( CAILAsicCapsInitTable[v15 + 1] == *(_DWORD *)(v3 + 4) )
    {
      v16 = CAILAsicCapsInitTable[v15 + 4];
      if ( v16 == 0xFFFFFFFFLL || a3 || v16 == *(_DWORD *)(v3 + 16) )
      {
        v17 = *(_QWORD *)CAILAsicCapsInitTable[v15 + 6];
        *(_QWORD *)(v3 + 456) = &CAILAsicCapsInitTable[v15];
        *(_DWORD *)(v3 + 24) = CAILAsicCapsInitTable[v15];
        v18 = CAILAsicCapsInitTable[v15 + 3];
        *(_DWORD *)(v3 + 32) = v18;
        *(_DWORD *)(v3 + 36) = v18;
        Cail_Detect_Grenada(a1);
        if ( *(_DWORD *)v17 >= 3u )
        {
          if ( *(_DWORD *)v17 >= 5u )
          {
            v19 = *(__int64 **)(v17 + 48);
            if ( v19 || (v19 = *(__int64 **)(CAILAsicCapsInitTable[v15 + 6] + 16LL)) != 0LL )
            {
              v20 = *v19;
              goto LABEL_28;
            }
            goto LABEL_30;
          }
          v20 = *(_QWORD *)(v17 + 48);
          if ( !v20 )
            goto LABEL_30;
LABEL_28:
          v21 = (__int64 *)(v20 + 8);
          v22 = *v21;
          if ( *v21 )
          {
            v23 = GetStringLength(*v21);
            *(_DWORD *)(v3 + 1204) = StringToUlong(v22, (unsigned int)v23);
          }
          else
          {
LABEL_30:
            *(_DWORD *)(v3 + 1204) = 0;
          }
        }
        MemoryCopy(v3 + 464, CAILAsicCapsInitTable[v15 + 5], 64LL);
        LOWORD(v24) = CAILAsicCapsExceptionTable[0];
        result = 0LL;
        if ( CAILAsicCapsExceptionTable[0] != 0xFFFF )
        {
          v25 = *(_WORD *)(v3 + 4);
          v26 = (char *)&CAILAsicCapsExceptionTable[5];
          do
          {
            if ( (unsigned __int16)v24 > v25 )
              break;
            if ( (unsigned __int16)v24 == v25 )
            {
              v27 = (unsigned __int8)*(v26 - 6) == *(_BYTE *)(v3 + 16) || (unsigned __int8)*(v26 - 6) == 255;
              if ( *(v26 - 4) )
              {
                if ( v27 )
                {
                  v28 = *((_WORD *)v26 - 4);
                  if ( v28 == 0xFFFF || v28 == *(_DWORD *)(v3 + 8) )
                    *(_DWORD *)(v3 + 4LL * ((unsigned int)*((_WORD *)v26 - 1) >> 5) + 464) |= 1 << *((_WORD *)v26 - 1);
                }
              }
              else if ( v27 )
              {
                v29 = *((_WORD *)v26 - 4);
                if ( v29 == 0xFFFF || v29 == *(_DWORD *)(v3 + 8) )
                {
                  v30 = *((_WORD *)v26 - 1);
                  v31 = __ROL4__(-2, v30);
                  *(_DWORD *)(v3 + 4LL * (v30 >> 5) + 464) &= v31;
                }
              }
            }
            v24 = *(_WORD *)v26;
            v26 += 10;
          }
          while ( v24 != 0xFFFF );
        }
      }
    }
  }
  return result;
}

this is also valid for the 8000controller.kext - check here

__int64 __fastcall findDeviceAsicCaps(__int64 a1)
{
  unsigned int i; // [sp+4h] [bp-14h]@1
  char v3; // [sp+17h] [bp-1h]@9

  for ( i = 0; i < 0x9C; ++i )
  {
    if ( *((_DWORD *)&CAIL_ASIC_CAPS_TABLE + 8 * (signed int)i) == *(_DWORD *)(a1 + 24)
      && *((_DWORD *)&CAIL_ASIC_CAPS_TABLE + 8 * (signed int)i + 1) == *(_DWORD *)(a1 + 16)
      && *((_DWORD *)&CAIL_ASIC_CAPS_TABLE + 8 * (signed int)i + 3) == *(_DWORD *)(a1 + 28)
      && *((_DWORD *)&CAIL_ASIC_CAPS_TABLE + 8 * (signed int)i + 2) == *(_DWORD *)(a1 + 20)
      && (*((_DWORD *)&CAIL_ASIC_CAPS_TABLE + 8 * (signed int)i + 4) == *(_BYTE *)(a1 + 35)
       || -1 == *((_DWORD *)&CAIL_ASIC_CAPS_TABLE + 8 * (signed int)i + 4)) )
    {
      *(_QWORD *)(a1 + 40) = *((_QWORD *)&CAIL_ASIC_CAPS_TABLE + 4 * (signed int)i + 3);
      v3 = 1;
      return v3 & 1;
    }
  }
  v3 = 0;
  return v3 & 1;
}

some fixes can bemade in order to get the right card family.etc.

  • 4 months later...

The Amdsupport patch doesn't fix hotplugsid - this makes multiple screens detection fails.

 

setting CFG_NO_HDCP to off does fix this. (on 1st multiscreen detection you might need to use the sleep trick).

 

in attach the info.plist I'm using on 8000controller

notice the ATY,bin_image is also added (delete or replace for your card)

 

other parameters will depend on which controller u're using so change with care.

 

this works fine on 10.12 but not so good for 10.11

 

if edid detection fails just use the fixedid tool posted above.

 

Info.plist.zip

  • Slice pinned this topic
  • 10 months later...
  • 7 months later...
  • 9 months later...

using kextutil -s /sim -l "kext" you can create debug symbols to load into ldb or xcode

 

sample list from /sim folder:

 

com.apple.AppleGraphicsDeviceControl.sym
com.apple.driver.AppleMobileFileIntegrity.sym
com.apple.iokit.IOACPIFamily.sym
com.apple.iokit.IOAcceleratorFamily2.sym
com.apple.iokit.IOGraphicsFamily.sym
com.apple.iokit.IOPCIFamily.sym
com.apple.iokit.IOReportFamily.sym
com.apple.iokit.IOSurface.sym
com.apple.kec.corecrypto.sym
com.apple.kext.AMD8000Controller.sym
com.apple.kext.AMDFramebuffer.sym
com.apple.kext.AMDRadeonX4000.sym
com.apple.kext.AMDRadeonX4000HWServices.sym
com.apple.kext.AMDRadeonX4050HWLibs.sym
com.apple.kext.AMDSupport.sym
com.apple.kext.CoreTrust.sym

this helps a lot if you are debugging with diferrent os x versions

 

AMDRadeonX4000_AMDHardware::setupCAIL

 

memset((char *)this + 1488, 0, 0x20000uLL);
  v2 = (*(__int64 (__fastcall **)(_QWORD, const char *))(**((_QWORD **)this + 2) + 696LL))(
         *((_QWORD *)this + 2),
         "ATY,bin_image");
  if ( v2 )
  {
    v1 = (const void *)(*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v2 + 376LL))(v2);
    if ( v1 )
    {
      if ( (*(unsigned int (__fastcall **)(__int64))(*(_QWORD *)v2 + 320LL))(v2) == 0x10000 )
      {
        memcpy((char *)this + 1488, v1, 0x10000uLL);
        v3 = IOMalloc(760LL, v1);
        *((_QWORD *)this + 184) = v3;
        if ( !(unsigned int)AMDRadeonX4000_AMDHardware::MCIL_Initialize(v3) )
        {
          *(_QWORD *)(*((_QWORD *)this + 184) + 8LL) = this;
          LOBYTE(v1) = (*(unsigned int (**)(void))(**((_QWORD **)this + 87) + 16LL))() == 0;
          return (unsigned int)v1;
        }
      }
    }
    goto LABEL_6;
  }

this code validates the bios ATY,bin_image to  0x10000 ( 65536 bytes) 

this means the bios as to be filled with "FF" (use a hex editor)

found this on 10.14 - it causes the driver to fail on config stage and on loading

note that 0x10000 is the bios legacy size

 

on the hardware libs theres also a validation

 

AmdCailServices::earlyInitialize

memset((void *)(a1 + 21), 0, (size_t)&loc_20000);
      v5 = (*(__int64 (__fastcall **)(_QWORD, const char *))(**(_QWORD **)(a1 + 8) + 696LL))(
             *(_QWORD *)(a1 + 8),
             "ATY,bin_image");
      if ( !v5 )
      {
        kprintf("AMD Error: ");
        kprintf("Unable to find ROM image\n");
        return (unsigned int)-536870212;
      }
      v6 = (const void *)(*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v5 + 376LL))(v5);
      if ( (*(unsigned int (__fastcall **)(__int64))(*(_QWORD *)v5 + 320LL))(v5) > 0x1FFFF )
        v7 = (size_t)&loc_20000;
      else
        v7 = (*(unsigned int (__fastcall **)(__int64))(*(_QWORD *)v5 + 320LL))(v5);
      v9 = a1 + 21;
      v10 = v6;
      memmove((void *)(v3 + 21), v6, v7);

 

loc_20000 = 0x20000 (131072 bytes)

 

Edited by jalavoui
×
×
  • Create New...