Page MenuHomeFreeBSD

sdhci: extend bus_dma_tag boundary to 64-bit space
ClosedPublic

Authored by mw on May 31 2021, 7:49 AM.

Details

Summary

This patch adds support for the SDHCI_CAN_DO_64BIT
capability, so that to allow 64-bit DMA operation
for the controllers which support this feature.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

mw requested review of this revision.May 31 2021, 7:49 AM
mw created this revision.
This revision is now accepted and ready to land.Jun 1 2021, 7:31 AM

Unfortunately, it looks bad.
Up until SDHCI v3.0, SDMA is strictly 32-bit, only ADMA mode (which we don't support yet, it is optionally 64-bit). As you can see at https://cgit.freebsd.org/src/tree/sys/dev/sdhci/sdhci.c#n1977, the driver ends up writing only the 32-part of buffer physical address to the DMA base register.

To enable 64-bit SDMA, the driver should check to see if the controller is SDHCI v4.0 compatible and supports 64-bit DMA.
If so, it should:

  • switch the controller to v4.0 mode - bit "Host Version 4 Enable" in the Host Control 2 register.
  • enable 64 bit DMA mode - bit "64-bit" addressing in in Host Control 2 register.
  • select SDMA mode in Host Control 1 register.
  • wrote physical address of DMA buffer to ADMA System address register (not to SDMA System Address).

In its current state, the driver can silently corrupt memory by ignoring the upper 32 bits of the DMA address.
Fortunately, the DMA buffer is allocated early enough in most systems to be in the lower 4G of memory.

@mmel Hi. I rechecked and you are right. Additional handling should be done in generic code. FYI, the SoC that needed the change had no < 4G physical address space at all, however it adds the upper 32-bit on HW level. Since current patch is incomplete, I'll revert for now.