void cpu_cache_wbinval_range_check()

in mm/proc.c [351:407]


void cpu_cache_wbinval_range_check(struct vm_area_struct *vma,
				   unsigned long start, unsigned long end,
				   bool flushi, bool wbd)
{
	unsigned long line_size, t_start, t_end;

	if (!flushi && !wbd)
		return;
	line_size = L1_cache_info[DCACHE].line_size;
	start = start & ~(line_size - 1);
	end = (end + line_size - 1) & ~(line_size - 1);

	if ((end - start) > (8 * PAGE_SIZE)) {
		if (wbd)
			cpu_dcache_wbinval_all();
		if (flushi)
			cpu_icache_inval_all();
		return;
	}

	t_start = (start + PAGE_SIZE) & PAGE_MASK;
	t_end = ((end - 1) & PAGE_MASK);

	if ((start & PAGE_MASK) == t_end) {
		if (va_present(vma->vm_mm, start)) {
			if (wbd)
				cpu_dcache_wbinval_range(start, end);
			if (flushi)
				cpu_icache_inval_range(start, end);
		}
		return;
	}

	if (va_present(vma->vm_mm, start)) {
		if (wbd)
			cpu_dcache_wbinval_range(start, t_start);
		if (flushi)
			cpu_icache_inval_range(start, t_start);
	}

	if (va_present(vma->vm_mm, end - 1)) {
		if (wbd)
			cpu_dcache_wbinval_range(t_end, end);
		if (flushi)
			cpu_icache_inval_range(t_end, end);
	}

	while (t_start < t_end) {
		if (va_present(vma->vm_mm, t_start)) {
			if (wbd)
				cpu_dcache_wbinval_page(t_start);
			if (flushi)
				cpu_icache_inval_page(t_start);
		}
		t_start += PAGE_SIZE;
	}
}