Jump to content

[80% Solved] Iris Xe iGPU on Tiger Lake successfully loaded ICLLP Frambuffer and VRAM also recognizes 1536MB! + However, some issues.


762 posts in this topic

Recommended Posts

i need to remenber how i setup netdbg listener so i can use it again

 

rsyslog doesn't seem to work

 

it helps a lot cause you get logs in real time over the network

 

maybe i used this long ago the port matches kern_netdbg.cpp

 

image.png.c957ca878ddb1d4e5025e68867076de3.png

 

Edited by jalavoui

By the way, that NetDbg server was only the V1 prototype created by NC, but later I made a V2 server, in Rust, which also had a web interface.

I was able to boot while the latest nblue, but i had to remove all the entries from IOPCIPrimaryMatch, with the other test, in the last nlue version at least it triggered the window server to fail.

 

 

image.png.9af57183b0390804309587497876ee1a.png

 

Strange, using the following command doesnt get any info using netdbg....trying to get the info via my other machine over ethernet, net_dbg compiled with headers...14.5SDK, I have a built in intel ethernet adapter that comes up without needing intelMausi, hmmm.

 

I was going to use homebrew, but decided to use commandline tools, its just that the location for the headers would now be:

/Library/Developer/CommandLineTools/SDKs/MacOSX14.5.sdk/usr/include/c++/v1

Pic

 

image.thumb.png.6440e1e2eb242749e74532e834d4d102.png

 

you will get a safe compile, in addition you should be able to use netdbg=xxx.xxx.xxx.xxx in your boot-args, however when i use "nc -l 8080" on the host in terminal, i doesnt hear anything, netdbg isnt even sending data. Maybe i have to hardcode it.

 

since my host is netdbg=192.168.2.150:8080

 

image.png.d46c3b35e68749ac955e5ab2c331be06.png
 
The host listens using the following command:
nc -l 8080
 

 

Edited by Mastachief

right if the server setup works then you use in code something like this.

if the network connection fails or is not configured you get a hang or crash

 

image.thumb.png.7a049ec0e52857becd5bc6f53f84cf1b.png

 

this is very old code idk why visual remove it. helps a lot for debugging

 

still idk why nc -l 8080 or lighttp can't capture messages

Edited by jalavoui

mac os x GTT calculation

 

image.png.90f02b710fb27781243019dec4772927.png

 

but linux

 

image.png.f38129a692bdb3f051e975e72c982403.png

 

this code can be patched in tgl framebuffer to use other mem values 

patched to linux default 0x400000

 

The stolen bytes patch also wrong - disabling

Edited by jalavoui

Is this with using the latest nblue, or just a few settings? Also, I see that GTT is a UEFI settings that can be modified using RU.efi? Or is it that the values are not being read via the nblue patches?




display props info

 

#define HAS_4TILE(i915)			(IS_DG2(i915) || DISPLAY_VER(i915) >= 14)
#define HAS_ASYNC_FLIPS(i915)		(DISPLAY_VER(i915) >= 5)
#define HAS_CDCLK_CRAWL(i915)		(DISPLAY_INFO(i915)->has_cdclk_crawl)
#define HAS_CDCLK_SQUASH(i915)		(DISPLAY_INFO(i915)->has_cdclk_squash)
#define HAS_CUR_FBC(i915)		(!HAS_GMCH(i915) && IS_DISPLAY_VER(i915, 7, 13))
#define HAS_D12_PLANE_MINIMIZATION(i915) (IS_ROCKETLAKE(i915) || IS_ALDERLAKE_S(i915))
#define HAS_DDI(i915)			(DISPLAY_INFO(i915)->has_ddi)
#define HAS_DISPLAY(i915)		(DISPLAY_RUNTIME_INFO(i915)->pipe_mask != 0)
#define HAS_DMC(i915)			(DISPLAY_RUNTIME_INFO(i915)->has_dmc)
#define HAS_DOUBLE_BUFFERED_M_N(i915)	(DISPLAY_VER(i915) >= 9 || IS_BROADWELL(i915))
#define HAS_DP_MST(i915)		(DISPLAY_INFO(i915)->has_dp_mst)
#define HAS_DP20(i915)			(IS_DG2(i915) || DISPLAY_VER(i915) >= 14)
#define HAS_DPT(i915)			(DISPLAY_VER(i915) >= 13)
#define HAS_DSB(i915)			(DISPLAY_INFO(i915)->has_dsb)
#define HAS_DSC(__i915)			(DISPLAY_RUNTIME_INFO(__i915)->has_dsc)
#define HAS_DSC_MST(__i915)		(DISPLAY_VER(__i915) >= 12 && HAS_DSC(__i915))
#define HAS_FBC(i915)			(DISPLAY_RUNTIME_INFO(i915)->fbc_mask != 0)
#define HAS_FPGA_DBG_UNCLAIMED(i915)	(DISPLAY_INFO(i915)->has_fpga_dbg)
#define HAS_FW_BLC(i915)		(DISPLAY_VER(i915) >= 3)
#define HAS_GMBUS_IRQ(i915)		(DISPLAY_VER(i915) >= 4)
#define HAS_GMBUS_BURST_READ(i915)	(DISPLAY_VER(i915) >= 10 || IS_KABYLAKE(i915))
#define HAS_GMCH(i915)			(DISPLAY_INFO(i915)->has_gmch)
#define HAS_HW_SAGV_WM(i915)		(DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))
#define HAS_IPC(i915)			(DISPLAY_INFO(i915)->has_ipc)
#define HAS_IPS(i915)			(IS_HASWELL_ULT(i915) || IS_BROADWELL(i915))
#define HAS_LRR(i915)			(DISPLAY_VER(i915) >= 12)
#define HAS_LSPCON(i915)		(IS_DISPLAY_VER(i915, 9, 10))
#define HAS_MBUS_JOINING(i915)		(IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)
#define HAS_MSO(i915)			(DISPLAY_VER(i915) >= 12)
#define HAS_OVERLAY(i915)		(DISPLAY_INFO(i915)->has_overlay)
#define HAS_PSR(i915)			(DISPLAY_INFO(i915)->has_psr)
#define HAS_PSR_HW_TRACKING(i915)	(DISPLAY_INFO(i915)->has_psr_hw_tracking)
#define HAS_PSR2_SEL_FETCH(i915)	(DISPLAY_VER(i915) >= 12)
#define HAS_SAGV(i915)			(DISPLAY_VER(i915) >= 9 && !IS_LP(i915))
#define HAS_TRANSCODER(i915, trans)	((DISPLAY_RUNTIME_INFO(i915)->cpu_transcoder_mask & \
					  BIT(trans)) != 0)
#define HAS_VRR(i915)			(DISPLAY_VER(i915) >= 11)
#define HAS_AS_SDP(i915)		(DISPLAY_VER(i915) >= 13)
#define HAS_CMRR(i915)			(DISPLAY_VER(i915) >= 20)
#define INTEL_NUM_PIPES(i915)		(hweight8(DISPLAY_RUNTIME_INFO(i915)->pipe_mask))
#define I915_HAS_HOTPLUG(i915)		(DISPLAY_INFO(i915)->has_hotplug)
#define OVERLAY_NEEDS_PHYSICAL(i915)	(DISPLAY_INFO(i915)->overlay_needs_physical)
#define SUPPORTS_TV(i915)		(DISPLAY_INFO(i915)->supports_tv)

 

i have HP chromebook pro c640 tiger-lake cpu, 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz   2.42 GHz.

im already on post installation. i get an applecredentedialsmanager error....can someone look into my efi folder and what im doing wrong

OC.zip

Sorry, its Not a iGPU related issue based on your EFI, visit another thread for answers.

 

also, you have -igfxvesa in our boot-args so it should have booted regardless, best bet is to redo your installation, also chromebooks ahve additional settings needed in ACPI section patching, check reddit or dortiana guide....

Edited by Mastachief

found this in linux logs - to investigate what workarounds where applyed...

 

image.png.837fcaa7c5687d0bbf0330dad1dcff0c.png

 

wonder if this is why i got bcs hangs on acelerator

 

find some at gen12_gt_workarounds_init()

 

...

 

image.png.af740c7426793f5ed5e4399d574093f3.png

 

how i gonna fix this thing...

#define __MASKED_FIELD(mask, value) ((mask) << 16 | (value))
#define _MASKED_FIELD(mask, value) ({ __MASKED_FIELD(mask, value); })
#define _MASKED_BIT_ENABLE(a)	({ __typeof(a) _a = (a); _MASKED_FIELD(_a, _a); })
#define _MASKED_BIT_DISABLE(a)	(_MASKED_FIELD((a), 0))
	
	void wa_add(uint32_t reg, uint32_t clear, uint32_t set, uint32_t read_mask, bool masked_reg)//wrong code
	{
		uint32_t old, val;
		
		if (masked_reg) {
			/* Keep the enable mask, reset the actual target bits */
			set &= ~(set >> 16);
		}

		old = readReg32( reg) ;

		val = (old & ~clear) | set;
		writeReg32( reg, val);
	}

 

Edited by jalavoui

scheduler 5 in tgl = INTEL_SUBMISSION_ELSP ?

 

image.png.67421ccb5edfaef304d8645fc45c170a.png

 

image.png.8961685b652d7c8f00a6b91154e61c54.png

 

image.png.2543bd40c71b7fc8893cea748785c5ee.png

 

#define HAS_EXECLISTS(i915) HAS_LOGICAL_RING_CONTEXTS(i915)

Edited by jalavoui

memory setup on igpu - explains lots of things

 

#define HAS_LMEM(i915) HAS_REGION(i915, INTEL_REGION_LMEM_0)

 

#define GEN_DEFAULT_REGIONS \

.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_STOLEN_SMEM)

 

#define DGFX_FEATURES \

.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_LMEM_0) | BIT(INTEL_REGION_STOLEN_LMEM), \

 

#define HAS_LMEMBAR_SMEM_STOLEN(i915) (!HAS_LMEM(i915) && \

      GRAPHICS_VER_FULL(i915) >= IP_VER(12, 70))

 

 

image.png.6a3a3c4f849bfdbfa9620bf181b982db.png

Edited by jalavoui

Resume from display on-sleep doesn't give artifacts with the latest release with tglframe in LE
 
image.thumb.png.9864c4093ee9958b1449ecd97b78986e.png
 
hackintool boot.rtf

It booted, first boot was previous nblue,

 

the attached hackintool boot.rtf is a boot log.

Edited by Mastachief

that pic looks like a boot hang. did you verify info.plist for double entries (tgl frame / tgl graph kexts)

 

why this dam AI's don't show full code...

 

void __thiscall IntelAccelerator::getGPUInfo(IntelAccelerator *this) {
  uint gpuSku;
  uint vedBoxEnableFuses;
  uint veBoxUnitsEnabled;
  long hardwareCaps;
  byte bitMask;
  char initResult;
  ulong veBoxUnits;
  int numSlices;
  int numSubSlices;
  uint euDisableFuses;
  uint executionUnitCount;
  ulong veBoxUnitsMask;
  uint maxEUPerSubSlice;
  
  SafeForceWake(this, true, 5);
  hardwareCaps = *(long *)(this + 0x1240);
  vedBoxEnableFuses = *(uint *)(hardwareCaps + 0x9138);
  veBoxUnitsEnabled = *(uint *)(hardwareCaps + 0x913c);
  gpuSku = *(uint *)(hardwareCaps + 0x9134);
  euDisableFuses = *(uint *)(hardwareCaps + 0x9140);
  executionUnitCount = ~euDisableFuses & 0xf00ff;
  maxEUPerSubSlice = *(uint *)(hardwareCaps + 0xd00);
  numSubSlices = 0;
  SafeForceWake(this, false, 5);
  _IOLog("[IGPU] HWCAPS - GPU Sku: %u\n", *(undefined4 *)(this + 0x1120));
  _kprintf("[IGPU] HWCAPS - GPU Sku: %u\n", (ulong)*(uint *)(this + 0x1120));
  _IOLog("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x  VEBox units enabled:%u   VDBox units enabled:%u\n", executionUnitCount, POPCOUNT(executionUnitCount >> 8), POPCOUNT(~euDisableFuses & 0xff));
  _kprintf("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x  VEBox units enabled:%u   VDBox units enabled:%u\n", (ulong)executionUnitCount, (ulong)(uint)POPCOUNT(executionUnitCount >> 8));
  veBoxUnitsMask = *(ulong *)(this + 0x1300);
  if (veBoxUnitsMask != 0) {
    veBoxUnits = 0;
    if (veBoxUnitsMask != 0) {
      for (; (veBoxUnitsMask >> veBoxUnits & 1) == 0; veBoxUnits = veBoxUnits + 1) {
      }
    }
    do {
      if ((veBoxUnits - 3 < 3) && ((*(uint *)(&DAT_000d1cb1 + veBoxUnits * 0x79) & executionUnitCount) == 0)) {
        bitMask = (&kIGHwCsDesc)[veBoxUnits * 0x79] & 0x3f;
        *(ulong *)(this + (long)(&DAT_00001300 + (ulong)((byte)(&kIGHwCsDesc)[veBoxUnits * 0x79] >> 6) * 8)) = *(ulong *)(this + (long)(&DAT_00001300 + (ulong)((byte)(&kIGHwCsDesc)[veBoxUnits * 0x79] >> 6) * 8)) & (-2L << bitMask | 0xfffffffffffffffeU >> 0x40 - bitMask);
      }
      if (4 < veBoxUnits) break;
      veBoxUnitsMask = -2L << ((byte)veBoxUnits & 0x3f) & *(ulong *)(this + (long)(&DAT_00001300 + (veBoxUnits + 1 >> 6) * 8));
      veBoxUnits = 0;
      if (veBoxUnitsMask != 0) {
        for (; (veBoxUnitsMask >> veBoxUnits & 1) == 0; veBoxUnits = veBoxUnits + 1) {
        }
      }
    } while (veBoxUnitsMask != 0);
  }
  *(undefined4 *)(this + 0x115c) = 0;
  numSlices = 0;
  do {
    numSubSlices = numSubSlices + (vedBoxEnableFuses >> ((byte)numSlices & 0x1f) & 1);
    numSlices = numSlices + 1;
  } while (numSlices != 8);
  *(int *)(this + 0x115c) = numSubSlices;
  _IOLog("[IGPU] HWCAPS - NumSlices:%d      SliceCountFuse:0x%x\n", numSubSlices, vedBoxEnableFuses);
  _kprintf("[IGPU] HWCAPS - NumSlices:%d      SliceCountFuse:0x%x\n", (ulong)*(uint *)(this + 0x115c), (ulong)vedBoxEnableFuses);
  *(int *)(this + 0x1158) = POPCOUNT(veBoxUnitsEnabled) * 2;
  _IOLog("[IGPU] HWCAPS - NumSubSlices:%u   DualSubSliceCountFuse:0x%x\n", POPCOUNT(veBoxUnitsEnabled) * 2, veBoxUnitsEnabled);
  _kprintf("[IGPU] HWCAPS - NumSubSlices:%u   DualSubSliceCountFuse:0x%x\n", (ulong)*(uint *)(this + 0x1158), (ulong)veBoxUnitsEnabled);
  vedBoxEnableFuses = POPCOUNT(gpuSku & 0xff);
  numSubSlices = 8 - vedBoxEnableFuses;
  *(int *)(this + 0x116c) = numSubSlices;
  *(int *)(this + 0x1124) = *(int *)(this + 0x1158) * numSubSlices;
  _IOLog("[IGPU] HWCAPS - MaxEUPerSubSlice:%u   EUDisableFuses:0x%x  ExecutionUnitCount:%u\n", numSubSlices, vedBoxEnableFuses);
  _kprintf("[IGPU] HWCAPS - MaxEUPerSubSlice:%u   EUDisableFuses:0x%x  ExecutionUnitCount:%u\n", (ulong)*(uint *)(this + 0x116c), (ulong)vedBoxEnableFuses, (ulong)*(uint *)(this + 0x1124));
  *(undefined8 *)(this + 0x1150) = 0x1c2000003e8;
  _IOLog("[IGPU] HWCAPS - fMaxFrequencyInMhz:%u   fMinFrequencyInMhz:%u   cap.Value:%u\n", 1000, 0x1c2, 0x90014);
  _kprintf("[IGPU] HWCAPS - fMaxFrequencyInMhz:%u   fMinFrequencyInMhz:%u   cap.Value:%u\n", (ulong)*(uint *)(this + 0x1150), (ulong)*(uint *)(this + 0x1154), 0x90014);
  vedBoxEnableFuses = *(uint *)(this + 0x115c);
  veBoxUnitsMask = *(ulong *)(this + 0x1190);
  *(ulong *)(this + 0x1190) = (veBoxUnitsMask & 0xfffffffffffffff7) + (ulong)(1 < vedBoxEnableFuses) * 8;
  *(uint *)(this + 0xdd8) = vedBoxEnableFuses;
  numSubSlices = *(int *)(this + 0x1158);
  *(int *)(this + 0xddc) = numSubSlices;
  if (*(int *)(this + 0x1120) == 1) {
    *(undefined4 *)(this + 0x1164) = 8;
    if ((vedBoxEnableFuses != 1) || (numSubSlices != 0xc)) {
      _IOLog("[IGPU] HWCAPS - ERROR: Invalid NumSlice or NumSubSlices for TGLHP GT2 1x6x16 (6 dual-subslices meaning 12 subslices) -- NumSlice = %u, NumSubSlices = %u!\n");
      _kprintf("[IGPU] HWCAPS - ERROR: Invalid NumSlice or NumSubSlices for TGLHP GT2 1x6x16 (6 dual-subslices meaning 12 subslices) -- NumSlice = %u, NumSubSlices = %u!\n", (ulong)*(uint *)(this + 0x115c), (ulong)*(uint *)(this + 0x1158));
    }
  } else {
    if (*(int *)(this + 0x1120) != 2) {
      getGPUInfo();
    }
    if ((vedBoxEnableFuses == 1) && (numSubSlices == 0xc)) {
      *(undefined4 *)(this + 0x1164) = 8;
    } else if ((vedBoxEnableFuses == 1) && (((veBoxUnitsMask & 0x20) != 0 && (numSubSlices == 4)))) {
      *(undefined4 *)(this + 0x1164) = 4;
    } else {
      _IOLog("[IGPU] HWCAPS - ERROR: Invalid NumSlice or NumSubSlices for TGLLP GT2 -- NumSlice = %u, NumSubSlices = %u!\n");
      _kprintf("[IGPU] HWCAPS - ERROR: Invalid NumSlice

if you guys can help plz do it. we lack clear code understanding so we can move to structured variables

Edited by jalavoui

Double entries for my igpu 9A498086?

Appears it's single entry,

Do you mean you want to put the calculations into functions? That might fix the pointers....

 

or to encapsulates the structures to avoid errors?

 

The AI's show full code on my ChatGPT Paid versions....but you have to give it the code in a text file, compressing it in a zip works too, but the content cant be too much in the text file, its good for identify how many times a particular error repeats in a log by doing a count. Word limit in the text input window is 4096 characters, but you can bypass it by also parsing your log or code you want analyzed by saving it as a pdf file and then attaching it, then you have to make it write sections of the code at a time.

 

Code Refactoring example...

// Define meaningful constants for hardware offsets.
#define GPU_SKU_OFFSET 0x9134
#define VEDBOX_ENABLE_FUSES_OFFSET 0x9138
#define VEBOX_UNITS_ENABLED_OFFSET 0x913C
#define EU_DISABLE_FUSES_OFFSET 0x9140
#define MAX_EU_PER_SUBSLICE_OFFSET 0xD00
#define NUM_SLICES_REGISTER 0x115c
#define NUM_SUBSLICES_REGISTER 0x1158
#define EXECUTION_UNIT_COUNT_REGISTER 0x1124
#define MAX_FREQUENCY_REGISTER 0x1150
#define MIN_FREQUENCY_REGISTER 0x1154

// Struct to encapsulate hardware capabilities.
struct HardwareCaps {
    uint32_t gpuSku;             // GPU SKU (model identifier).
    uint32_t vedBoxEnableFuses;  // VED Box enable fuses.
    uint32_t veBoxUnitsEnabled;  // VE Box units enabled.
    uint32_t euDisableFuses;     // Execution Unit disable fuses.
    uint32_t maxEUPerSubSlice;   // Max Execution Units per sub-slice.
};

// Struct to encapsulate slice and subslice topology.
struct SliceInfo {
    uint32_t numSlices;          // Total number of active slices.
    uint32_t numSubSlices;       // Total number of active sub-slices.
    uint32_t sliceFuses;         // Bitmask representing slice fuses.
    uint32_t subSliceFuses;      // Bitmask representing subslice fuses.
};

// Struct to encapsulate execution unit details.
struct ExecutionUnitInfo {
    uint32_t totalEUs;           // Total execution units.
    uint32_t disabledEUs;        // Number of disabled execution units.
    uint32_t enabledEUs;         // Number of enabled execution units.
    uint32_t executionUnitCount; // Final execution unit count after computation.
};

// Function to safely enable/disable force wake for hardware.
void SafeForceWake(IntelAccelerator *this, bool enable, int timeout) {
    // Implementation to manage hardware force-wake.
    // `enable` specifies whether to enable or disable force wake.
    // `timeout` specifies the duration to wait for readiness.
}

// Function to log hardware capabilities.
void LogGPUInfo(const HardwareCaps* caps) {
    printf("[IGPU] HWCAPS - GPU Sku: %u\n", caps->gpuSku);
    printf("[IGPU] HWCAPS - VEDBOXEnableFuses: 0x%x  VEBox units enabled: %u\n",
           caps->vedBoxEnableFuses, caps->veBoxUnitsEnabled);
    printf("[IGPU] HWCAPS - MaxEUPerSubSlice: %u\n", caps->maxEUPerSubSlice);
}

// Function to validate slice and subslice configuration.
void ValidateSliceConfiguration(const SliceInfo* sliceInfo) {
    if (sliceInfo->numSlices == 1 && sliceInfo->numSubSlices == 12) {
        // Valid configuration for TGLLP GT2.
        return;
    }
    // Log error if the configuration is invalid.
    printf("[IGPU] HWCAPS - ERROR: Invalid NumSlice or NumSubSlices for TGLLP GT2 -- NumSlice = %u, NumSubSlices = %u!\n",
           sliceInfo->numSlices, sliceInfo->numSubSlices);
}

// Function to populate execution unit information.
void PopulateExecutionUnitInfo(IntelAccelerator *this, ExecutionUnitInfo *euInfo) {
    euInfo->disabledEUs = *(uint32_t *)(this + EU_DISABLE_FUSES_OFFSET);
    euInfo->enabledEUs = ~euInfo->disabledEUs & 0xf00ff;
    euInfo->executionUnitCount = *(uint32_t *)(this + EXECUTION_UNIT_COUNT_REGISTER);
    euInfo->totalEUs = __builtin_popcount(euInfo->enabledEUs);
}

// Function to populate slice information from hardware.
void PopulateSliceInfo(IntelAccelerator *this, SliceInfo *sliceInfo) {
    sliceInfo->sliceFuses = *(uint32_t *)(this + VEDBOX_ENABLE_FUSES_OFFSET);
    sliceInfo->numSlices = __builtin_popcount(sliceInfo->sliceFuses);  // Count active slices.
    sliceInfo->subSliceFuses = *(uint32_t *)(this + VEBOX_UNITS_ENABLED_OFFSET);
    sliceInfo->numSubSlices = __builtin_popcount(sliceInfo->subSliceFuses);  // Count active sub-slices.

    // Validate the populated slice configuration.
    ValidateSliceConfiguration(sliceInfo);
}

// Main function to extract GPU information.
void IntelAccelerator::getGPUInfo() {
    // Initialize the structs to hold extracted data.
    HardwareCaps caps;
    SliceInfo sliceInfo;
    ExecutionUnitInfo euInfo;

    // Enable force wake to access hardware registers.
    SafeForceWake(this, true, 5);

    // Populate hardware capabilities.
    caps.gpuSku = *(uint32_t *)(this + GPU_SKU_OFFSET);
    caps.vedBoxEnableFuses = *(uint32_t *)(this + VEDBOX_ENABLE_FUSES_OFFSET);
    caps.veBoxUnitsEnabled = *(uint32_t *)(this + VEBOX_UNITS_ENABLED_OFFSET);
    caps.euDisableFuses = *(uint32_t *)(this + EU_DISABLE_FUSES_OFFSET);
    caps.maxEUPerSubSlice = *(uint32_t *)(this + MAX_EU_PER_SUBSLICE_OFFSET);

    // Log the GPU information.
    LogGPUInfo(&caps);

    // Populate execution unit information.
    PopulateExecutionUnitInfo(this, &euInfo);

    // Populate and validate slice and subslice information.
    PopulateSliceInfo(this, &sliceInfo);

    // Update registers with slice and subslice information.
    *(uint32_t *)(this + NUM_SLICES_REGISTER) = sliceInfo.numSlices;
    *(uint32_t *)(this + NUM_SUBSLICES_REGISTER) = sliceInfo.numSubSlices;
    *(uint32_t *)(this + EXECUTION_UNIT_COUNT_REGISTER) = euInfo.totalEUs * sliceInfo.numSubSlices;

    // Log the final configuration.
    printf("[IGPU] HWCAPS - NumSlices: %u, NumSubSlices: %u, ExecutionUnitCount: %u\n",
           sliceInfo.numSlices, sliceInfo.numSubSlices, euInfo.executionUnitCount);

    // Update frequency registers (example values, adjust as needed).
    *(uint32_t *)(this + MAX_FREQUENCY_REGISTER) = 1000;  // Max frequency in MHz.
    *(uint32_t *)(this + MIN_FREQUENCY_REGISTER) = 450;   // Min frequency in MHz.

    // Disable force wake after operations are complete.
    SafeForceWake(this, false, 5);
}

 

Slice function helper example.

 

void ValidateSliceConfiguration(const SliceInfo* sliceInfo) {
    if (sliceInfo->numSlices == 1 && sliceInfo->numSubSlices == 12) {
        // Valid configuration for TGLLP GT2.
        return;
    }

    // Log the error for invalid configuration.
    _IOLog("[IGPU] HWCAPS - ERROR: Invalid NumSlice or NumSubSlices for TGLLP GT2 -- NumSlice = %u, NumSubSlices = %u!\n",
           sliceInfo->numSlices, sliceInfo->numSubSlices);
    _kprintf("[IGPU] HWCAPS - ERROR: Invalid NumSlice or NumSubSlices for TGLLP GT2 -- NumSlice = %u, NumSubSlices = %u!\n",
             (unsigned long)sliceInfo->numSlices, (unsigned long)sliceInfo->numSubSlices);
}

 

kIGHwCsDesc code refactor response.

 

#define VEBOX_UNITS_MASK_OFFSET 0x1300
#define EXECUTION_UNIT_COUNT_REGISTER 0x1124
#define EU_DISABLE_FUSES_OFFSET 0x9140
#define DAT_BASE_ADDRESS 0x00001300
#define DAT_OFFSET 0x79

// Logging macros.
#define _IOLog(...) IOLog("[Lilu][Tigerlake GPU] " __VA_ARGS__)
#define _kprintf(...) kprintf("[Tigerlake GPU Debug] " __VA_ARGS__)

// Function to calculate VEBox and VDBox information.
void LogBoxInfo(uint32_t executionUnitCount, uint32_t euDisableFuses) {
    // Calculate and log VEBox and VDBox information.
    uint32_t veBoxEnabledCount = __builtin_popcount(executionUnitCount >> 8);
    uint32_t vdBoxEnabledCount = __builtin_popcount(~euDisableFuses & 0xff);

    // Unified log output for VEBox and VDBox data.
    _IOLog("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x VEBox units enabled:%u VDBox units enabled:%u\n",
           executionUnitCount, veBoxEnabledCount, vdBoxEnabledCount);

    _kprintf("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x VEBox units enabled:%u VDBox units enabled:%u\n",
             executionUnitCount, veBoxEnabledCount, vdBoxEnabledCount);
}

// Function to handle VEBox unit processing and modify `kIGHwCsDesc`.
void HandleVEBoxUnits(void *this, uint32_t executionUnitCount, uint64_t veBoxUnitsMask, uint64_t *kIGHwCsDesc) {
    uint64_t veBoxUnits = 0;
    uint8_t bitMask;

    // Process VEBox units mask.
    if (veBoxUnitsMask != 0) {
        do {
            // Locate the first active VEBox unit in the mask.
            while ((veBoxUnitsMask >> veBoxUnits & 1) == 0) {
                veBoxUnits++;
            }

            // Perform unit-specific logic using `kIGHwCsDesc`.
            if ((veBoxUnits - 3 < 3) &&
                ((*(uint32_t *)((uint8_t *)kIGHwCsDesc + veBoxUnits * DAT_OFFSET) & executionUnitCount) == 0)) {
                bitMask = ((uint8_t *)kIGHwCsDesc)[veBoxUnits * DAT_OFFSET] & 0x3f;
                *(uint64_t *)(this + DAT_BASE_ADDRESS +
                              ((uint64_t)((uint8_t *)kIGHwCsDesc)[veBoxUnits * DAT_OFFSET] >> 6) * 8) &=
                    (-2L << bitMask | 0xfffffffffffffffeU >> (0x40 - bitMask));
            }

            // Update VEBox mask to proceed to the next unit.
            veBoxUnitsMask = -2L << (veBoxUnits & 0x3f) &
                             *(uint64_t *)(this + DAT_BASE_ADDRESS + ((veBoxUnits + 1) >> 6) * 8);
            veBoxUnits = 0;

        } while (veBoxUnitsMask != 0);
    }
}

// Main function to retrieve GPU information.
void IntelAccelerator::getGPUInfo() {
    uint32_t executionUnitCount, euDisableFuses;
    uint64_t veBoxUnitsMask;

    // Retrieve execution unit and VEBox mask data.
    executionUnitCount = *(uint32_t *)(this + EXECUTION_UNIT_COUNT_REGISTER);
    euDisableFuses = *(uint32_t *)(this + EU_DISABLE_FUSES_OFFSET);
    veBoxUnitsMask = *(uint64_t *)(this + VEBOX_UNITS_MASK_OFFSET);

    // Log VEBox and VDBox information.
    LogBoxInfo(executionUnitCount, euDisableFuses);

    // Handle VEBox units processing using modular function.
    HandleVEBoxUnits(this, executionUnitCount, veBoxUnitsMask, kIGHwCsDesc);
}

 

Edited by Mastachief

i ment when  i upload nblue i forget to remove tgl graph ids and for most ppl it hangs on boot cause they dont have tgl graph installed in /s/le

 

image.png.8332cf28b29544fe93ac77dab2f528a1.png

 

the ai code will help. let me check something in getGPUInfo()

this part of code uses and changes kIGHwCsDesc

 

  veBoxUnitsMask = *(ulong *)(this + 0x1300);
  if (veBoxUnitsMask != 0) {
    veBoxUnits = 0;
    if (veBoxUnitsMask != 0) {
      for (; (veBoxUnitsMask >> veBoxUnits & 1) == 0; veBoxUnits = veBoxUnits + 1) {
      }
    }
    do {
      if ((veBoxUnits - 3 < 3) && ((*(uint *)(&DAT_000d1cb1 + veBoxUnits * 0x79) & executionUnitCount) == 0)) {
        bitMask = (&kIGHwCsDesc)[veBoxUnits * 0x79] & 0x3f;
        *(ulong *)(this + (long)(&DAT_00001300 + (ulong)((byte)(&kIGHwCsDesc)[veBoxUnits * 0x79] >> 6) * 8)) = *(ulong *)(this + (long)(&DAT_00001300 + (ulong)((byte)(&kIGHwCsDesc)[veBoxUnits * 0x79] >> 6) * 8)) & (-2L << bitMask | 0xfffffffffffffffeU >> 0x40 - bitMask);
      }
      if (4 < veBoxUnits) break;
      veBoxUnitsMask = -2L << ((byte)veBoxUnits & 0x3f) & *(ulong *)(this + (long)(&DAT_00001300 + (veBoxUnits + 1 >> 6) * 8));
      veBoxUnits = 0;
      if (veBoxUnitsMask != 0) {
        for (; (veBoxUnitsMask >> veBoxUnits & 1) == 0; veBoxUnits = veBoxUnits + 1) {
        }
      }
    } while (veBoxUnitsMask != 0);
  }

this specific pointer kIGHwCsDesc is also referenced by other functions

 

 image.png.804e78e1d32a978086ba208a088e9316.png

 

i need tobe sure ai code didin't break this. guess only by testing

 

the ai code "forgot" this part - when tgl code is a bit confusing as it is just a print

  _IOLog("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x  VEBox units enabled:%u   VDBox units enabled:%u\n", executionUnitCount, POPCOUNT(executionUnitCount >> 8), POPCOUNT(~euDisableFuses & 0xff));
 

anyway this also doesn't make sense to me so guess ai decision is good cause the next load line does same print but with another calculation variable

kprintf("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x  VEBox units enabled:%u   VDBox units enabled:%u\n", (ulong)executionUnitCount, (ulong)(uint)POPCOUNT(executionUnitCount >> 8));

 

there's also other variables in original code that the "ai" choose to ignore...

  *(ulong *)(this + 0x1190) = (veBoxUnitsMask & 0xfffffffffffffff7) + (ulong)(1 < vedBoxEnableFuses) * 8;

  *(uint *)(this + 0xdd8) = vedBoxEnableFuses;

  numSubSlices = *(int *)(this + 0x1158);

  *(int *)(this + 0xddc) = numSubSlices;

 

 

 

masta can you try guess this function ? i can't get a decent decompile of this settings

image.png.3defa94ed01cde3880112ecd8f4cd692.png

 

ghidra as some kind of plugin to integrate payd ai - maybe you can check it

Edited by jalavoui
  • Thanks 1

Code Guess

I am looking at a few of the github plug-ins, I'll build one and install to my extensions folder in a while, just need to redo my xcode for a bit.

https://github.com/evyatar9/GptHidra

Are you using the binary from the Accelerator2 kext from the DTK?
 



 

ulong __thiscall IntelAccelerator::initHardwareCaps(IntelAccelerator *this) {   uint uVar1;  // Temporary variable for intermediate calculations.   int iVar2;   // Another intermediate variable.   int iVar3;   // Unused or temporary.   int iVar4;   // Unused or temporary.   undefined unaff_R14;  // Placeholder for unused register.   ulong uVar5; // Possibly a return value or intermediate result.   // Check a specific condition on hardware capability (e.g., GPU SKU or type).   if (*(int *)(this + 0x1120) == 2) {       // Initialize specific hardware capability fields or registers.       *(uint64_t *)(this + 0x112c) = 0x222000000C0;    // Capability setting 1.       *(uint64_t *)(this + 0x1134) = 0x22200000150;    // Capability setting 2.       *(uint64_t *)(this + 0x113c) = 0x150;            // Capability setting 3.       *(uint64_t *)(this + 0x1174) = 0x200000007;      // Capability setting 4.       *(uint64_t *)(this + 0x117c) = 0x1000000080;     // Capability setting 5.       *(uint64_t *)(this + 0x1160) = 0xF00;            // Capability setting 6.       *(uint32_t *)(this + 0x1148) = 6;                // Some count or limit.       // Perform a calculation on a hardware field and assign it to `uVar1`.       uVar1 = *(uint32_t *)(this + 0x1158) >> 1;       // Initialize intermediate variables for further use (though they appear unused here).       iVar3 = 2;       iVar2 = 0x80;   }   // Return or update some value (hypothetical; not clear from the image).   return uVar5;}
 

 your ghidra is setup very well, on my decompile i dont get as much info as you.

 

do you decompile using clang?
 

Edited by Mastachief

better use the acelerator from current os x version cause if from dtk we will get tons of dependencies.

 

i just took a better look at this code  

 

_kprintf("[IGPU] HWCAPS - GPU Sku: %u\n", (ulong)*(uint *)(this + 0x1120));
  _IOLog("[IGPU] HWCAPS - VEDBOXEnableFuses:0x%x  VEBox units enabled:%u   VDBox units enabled:%u\n",

executionUnitCount,

POPCOUNT(executionUnitCount >> 8),

POPCOUNT(~euDisableFuses & 0xff));

 

the values print fine issue is the hwcaps that bring wrong values and mess it all. 

 

 

 

masta the analysys is correct. maybe those are flag values similiar to linux code

 

one struct that would help is the framebufer properties. wg struct seems not to work.

 

this is the function. maybe analyse also from icl as they seem very similar

goal is create a working structure so i can disable patches with bytes

and maybe the connectors structure so we can change pipes and some display properties

image.png.2ff4f3145e1cf164264a1d0a691adde5.png

 

this is standard ghidra install

Edited by jalavoui

this code does some setup to agdc with vendor id = apple

 

image.png.bf838638a8ad48476692fe1995ac9788.png

image.png.f63ec05d58e26eed3b2119c865b9b29e.png

 

so how todo this?

 

image.png.d876ec9347247255c011a3603f960a29.png

 

in bninja

image.png.c262556d436e95297b5457d5f8b4ba9a.png

 

image.png.f30e51f2c4a0db3e5305bee70ccfaef2.png

 

image.png.f55c2a42994adef1e2694df80349652a.png

 

Edited by jalavoui
  • Like 1

1st step of config is in IntelAccelerator::getGPUInfo(IntelAccelerator *this) - patched to get ring setup

 

next call are this values. they need a fix so rings start transmitting packets

 

image.png.0068ae167b7da548624fefd7799fd91e.png

 

final values calc

image.png.532e0b782ffa249782d96a15283551f6.png

 

 

where in linux this code can be found ?

this is current graphics stage - wrong config settings tobe fixed

 

Edited by jalavoui

Linux and OSX calculates values using different variable names, the BAR0 and BAR1 would be the same config space though.

 

image.thumb.png.4b8675796133620a860b9de2cf6adc1d.png

 

Here is the info you may need, all the files are in the zip

 

Info.zip

 

System is not under load in i915_engine_info.txt,

 

System is under load in full_i915_engine_info_dump while under load.txt

 

the included register dump is while the system is under load.

 

Power Management status changes how the igpu reacts, the ringbuffer will also not have any values until the system is under load, seems that theres a "GPU idle" flag under "i915_runtime_pm_status" that if not under load is a "yes"

root@becoolio-Latitude-5520:/sys/kernel/debug/dri/0000:00:02.0# cat /sys/kernel/debug/dri/0000:00:02.0/i915_runtime_pm_status
Runtime power status: enabled
GPU idle: yes
IRQs disabled: no
Usage count: 7
PCI device power state: D0 [0]

 

When the system is under load the following is noted. this what creates the difference between the two (2)  i915_engine_info dumps.

root@becoolio-Latitude-5520:/sys/kernel/debug/dri/0000:00:02.0# cat /sys/kernel/debug/dri/0000:00:02.0/i915_runtime_pm_status
Runtime power status: enabled
GPU idle: no
IRQs disabled: no
Usage count: 11
PCI device power state: D0 [0]

Let me know if you need any info jala.

Edited by Mastachief
  • Like 1
×
×
  • Create New...