cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dma.c (1422B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2#include <linux/acpi.h>
      3#include <linux/acpi_iort.h>
      4#include <linux/device.h>
      5#include <linux/dma-direct.h>
      6
      7void acpi_arch_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
      8{
      9	int ret;
     10	u64 end, mask;
     11	u64 dmaaddr = 0, size = 0, offset = 0;
     12
     13	/*
     14	 * If @dev is expected to be DMA-capable then the bus code that created
     15	 * it should have initialised its dma_mask pointer by this point. For
     16	 * now, we'll continue the legacy behaviour of coercing it to the
     17	 * coherent mask if not, but we'll no longer do so quietly.
     18	 */
     19	if (!dev->dma_mask) {
     20		dev_warn(dev, "DMA mask not set\n");
     21		dev->dma_mask = &dev->coherent_dma_mask;
     22	}
     23
     24	if (dev->coherent_dma_mask)
     25		size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
     26	else
     27		size = 1ULL << 32;
     28
     29	ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
     30	if (ret == -ENODEV)
     31		ret = iort_dma_get_ranges(dev, &size);
     32	if (!ret) {
     33		/*
     34		 * Limit coherent and dma mask based on size retrieved from
     35		 * firmware.
     36		 */
     37		end = dmaaddr + size - 1;
     38		mask = DMA_BIT_MASK(ilog2(end) + 1);
     39		dev->bus_dma_limit = end;
     40		dev->coherent_dma_mask = min(dev->coherent_dma_mask, mask);
     41		*dev->dma_mask = min(*dev->dma_mask, mask);
     42	}
     43
     44	*dma_addr = dmaaddr;
     45	*dma_size = size;
     46
     47	ret = dma_direct_set_offset(dev, dmaaddr + offset, dmaaddr, size);
     48
     49	dev_dbg(dev, "dma_offset(%#08llx)%s\n", offset, ret ? " failed!" : "");
     50}