Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 212868d3 authored by David Brownell's avatar David Brownell Committed by Haavard Skinnemoen
Browse files

[AVR32] Fix incorrect invalidation of shared cachelines



Fix bug in dma_map_single(..., DMA_FROM_DEVICE) caused by incorrect
invalidation of shared cachelines at the beginning and/or end of
the specified buffer.  Those shared cachelines need to be flushed,
since they may hold valid data (which must not be discarded).

Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarHaavard Skinnemoen <hskinnemoen@atmel.com>
parent 58febc0b
Loading
Loading
Loading
Loading
+24 −8
Original line number Diff line number Diff line
@@ -22,18 +22,34 @@

void invalidate_dcache_region(void *start, size_t size)
{
	unsigned long v, begin, end, linesz;
	unsigned long v, begin, end, linesz, mask;
	int flush = 0;

	linesz = boot_cpu_data.dcache.linesz;
	mask = linesz - 1;

	//printk("invalidate dcache: %p + %u\n", start, size);
	/* when first and/or last cachelines are shared, flush them
	 * instead of invalidating ... never discard valid data!
	 */
	begin = (unsigned long)start;
	end = begin + size - 1;

	/* You asked for it, you got it */
	begin = (unsigned long)start & ~(linesz - 1);
	end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
	if (begin & mask) {
		flush_dcache_line(start);
		begin += linesz;
		flush = 1;
	}
	if ((end & mask) != mask) {
		flush_dcache_line((void *)end);
		end -= linesz;
		flush = 1;
	}

	for (v = begin; v < end; v += linesz)
	/* remaining cachelines only need invalidation */
	for (v = begin; v <= end; v += linesz)
		invalidate_dcache_line((void *)v);
	if (flush)
		flush_write_buffer();
}

void clean_dcache_region(void *start, size_t size)