Issue Writing to BAR1 After BAR0 is Unavailable

Hello Everyone,

I encountered an issue with PCI memory access in DriverKit. In my case, BAR0 is not available, but BAR1 is ready for use. Here’s the log output:

!!! ERROR : Failed to get BAR0 info (error: 0xe00002f0). !!!
BAR1 - MemoryIndex: 0x00000000, Size: 0x00040000, Type: 0

Issue Description When I initially wrote to BAR0 using memoryIndex = 0, it worked successfully:

AME_Address_Write_32(pAMEData, pAMEData->memoryIndex, AME_HOST_INT_MASK_REGISTER, 0x0F);

However, I mistakenly forgot to update memoryIndex to 1 for BAR1. Surprisingly, the write operation still succeeded.

When I fixed memoryIndex = 1 for BAR1, the write operation no longer had any effect. There was no error, but the expected behavior did not occur.

Relevant API (From IOPCIDevice.iig)

/*!
/*!
* @brief Writes a 32-bit value to the PCI device's aperture at a given memory index.
* @discussion This method writes a 32-bit register on the device and returns its value.
* @param memoryIndex An index into the array of ranges assigned to the device.
* @param offset An offset into the device's memory specified by the index.
* @param data A 32-bit value to be written in host byte order.
*/
void
MemoryWrite32(uint8_t memoryIndex,
uint64_t offset,
uint32_t data) LOCALONLY;

Log Output:

Writes to BAR0 (memoryIndex = 0)

AME_Address_Write_32() called
memoryIndex: 0, offset: 0x34, data: 0xf
Wrote data 0xF to offset 52
AME_Address_Write_32() called
memoryIndex: 0, offset: 0xa0, data: 0x1
Wrote data 0x1 to offset 160
AME_Address_Write_32() called
memoryIndex: 0, offset: 0x20, data: 0xffffffff
Wrote data 0xFFFFFFFF to offset 32

Writes to BAR1 (memoryIndex = 1) – No Response

AME_Address_Write_32() called
memoryIndex: 1, offset: 0x34, data: 0xf

No confirmation log, no visible effect.

Questions

  1. What should memoryIndex be set to for BAR1?
  • The log shows "BAR1 - MemoryIndex: 0x00000000", but should I be using 1 instead?
  1. How can I verify if a write operation to BAR1 is successful?
  • Is there a way to check if the memory region is actually writable?

  • Should I use MemoryRead32() to confirm the written value?

Any guidance would be greatly appreciated!

Best Regards, Charles

This has also been happening to me lately, even on iOS 18.4 RC

Accepted Answer

I think I now understand what the memoryIndex should be set to. Here’s the updated log output:

!!! ERROR : Failed to get BAR0 info (error: 0xe00002f0). !!!
BAR1 - MemoryIndex: 0x00000000, Size: 0x00040000, Type: 0
!!! ERROR : Failed to get BAR2 info (error: 0xe00002f0). !!!

And here’s the function I used to retrieve the BAR information:

IOReturn GetBARInfo(IOPCIDevice* pciDevice, uint8_t barIndex, uint8_t* memoryIndex, uint64_t *barSize, uint8_t* barType)
{
IOReturn ret = pciDevice->GetBARInfo(barIndex, memoryIndex, barSize, barType);
if (ret == kIOReturnSuccess)
{
Log("BAR%d - MemoryIndex: 0x%08x, Size: 0x%08llx, Type: %u", barIndex, *memoryIndex, *barSize, *barType);
}
else
{
LogErr("Failed to get BAR%d info (error: 0x%08x).", barIndex, ret);
}
return ret;
}

And then, use the memoryIndex obtained from GetBARInfo to perform memory read/write operations.

FYI, most of IOPCIFamily is opensourced, so you can actually see the implementation here. The value "0xe00002f0" is kIOReturnNotFound, which is GetBARInfo's default return value if it failed without any other "specific" cause.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Issue Writing to BAR1 After BAR0 is Unavailable
 
 
Q