Ejemplo n.º 1
0
static int __init
x86_get_mtrr_mem_range(struct range *range, int nr_range,
		       unsigned long extra_remove_base,
		       unsigned long extra_remove_size)
{
	unsigned long base, size;
	mtrr_type type;
	int i;

	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_WRBACK)
			continue;
		base = range_state[i].base_pfn;
		size = range_state[i].size_pfn;
		nr_range = add_range_with_merge(range, RANGE_NUM, nr_range,
						base, base + size);
	}
	if (debug_print) {
		printk(KERN_DEBUG "After WB checking\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
				 range[i].start, range[i].end);
	}

	/* Take out UC ranges: */
	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_UNCACHABLE &&
		    type != MTRR_TYPE_WRPROT)
			continue;
		size = range_state[i].size_pfn;
		if (!size)
			continue;
		base = range_state[i].base_pfn;
		if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
		    (mtrr_state.enabled & 1)) {
			/* Var MTRR contains UC entry below 1M? Skip it: */
			printk(BIOS_BUG_MSG, i);
			if (base + size <= (1<<(20-PAGE_SHIFT)))
				continue;
			size -= (1<<(20-PAGE_SHIFT)) - base;
			base = 1<<(20-PAGE_SHIFT);
		}
		subtract_range(range, RANGE_NUM, base, base + size);
	}
	if (extra_remove_size)
		subtract_range(range, RANGE_NUM, extra_remove_base,
				 extra_remove_base + extra_remove_size);

	if  (debug_print) {
		printk(KERN_DEBUG "After UC checking\n");
		for (i = 0; i < RANGE_NUM; i++) {
			if (!range[i].end)
				continue;
			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
				 range[i].start, range[i].end);
		}
	}

	/* sort the ranges */
	nr_range = clean_sort_range(range, RANGE_NUM);
	if  (debug_print) {
		printk(KERN_DEBUG "After sorting\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
				 range[i].start, range[i].end);
	}

	return nr_range;
}
Ejemplo n.º 2
0
void __init pmsav8_setup(void)
{
	int i, err = 0;
	int region = PMSAv8_KERNEL_REGION;

	/* How many regions are supported ? */
	mpu_max_regions = __mpu_max_regions();

	/* RAM: single chunk of memory */
	add_range(mem,  ARRAY_SIZE(mem), 0,  memblock.memory.regions[0].base,
		  memblock.memory.regions[0].base + memblock.memory.regions[0].size);

	/* IO: cover full 4G range */
	add_range(io, ARRAY_SIZE(io), 0, 0, 0xffffffff);

	/* RAM and IO: exclude kernel */
	subtract_range(mem, ARRAY_SIZE(mem), __pa(KERNEL_START), __pa(KERNEL_END));
	subtract_range(io, ARRAY_SIZE(io),  __pa(KERNEL_START), __pa(KERNEL_END));

#ifdef CONFIG_XIP_KERNEL
	/* RAM and IO: exclude xip */
	subtract_range(mem, ARRAY_SIZE(mem), CONFIG_XIP_PHYS_ADDR, __pa(_exiprom));
	subtract_range(io, ARRAY_SIZE(io), CONFIG_XIP_PHYS_ADDR, __pa(_exiprom));
#endif

#ifndef CONFIG_CPU_V7M
	/* RAM and IO: exclude vectors */
	subtract_range(mem, ARRAY_SIZE(mem),  vectors_base, vectors_base + 2 * PAGE_SIZE);
	subtract_range(io, ARRAY_SIZE(io),  vectors_base, vectors_base + 2 * PAGE_SIZE);
#endif
	/* IO: exclude RAM */
	for (i = 0; i < ARRAY_SIZE(mem); i++)
		subtract_range(io, ARRAY_SIZE(io), mem[i].start, mem[i].end);

	/* Now program MPU */

#ifdef CONFIG_XIP_KERNEL
	/* ROM */
	err |= pmsav8_setup_fixed(PMSAv8_XIP_REGION, CONFIG_XIP_PHYS_ADDR, __pa(_exiprom));
#endif
	/* Kernel */
	err |= pmsav8_setup_fixed(region++, __pa(KERNEL_START), __pa(KERNEL_END));


	/* IO */
	for (i = 0; i < ARRAY_SIZE(io); i++) {
		if (!io[i].end)
			continue;

		err |= pmsav8_setup_io(region++, io[i].start, io[i].end);
	}

	/* RAM */
	for (i = 0; i < ARRAY_SIZE(mem); i++) {
		if (!mem[i].end)
			continue;

		err |= pmsav8_setup_ram(region++, mem[i].start, mem[i].end);
	}

	/* Vectors */
#ifndef CONFIG_CPU_V7M
	err |= pmsav8_setup_vector(region++, vectors_base, vectors_base + 2 * PAGE_SIZE);
#endif
	if (err)
		pr_warn("MPU region initialization failure! %d", err);
	else
		pr_info("Using ARM PMSAv8 Compliant MPU. Used %d of %d regions\n",
			mpu_rgn_info.used, mpu_max_regions);
}
Ejemplo n.º 3
0
static int __init
x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
		       unsigned long extra_remove_base,
		       unsigned long extra_remove_size)
{
	unsigned long i, base, size;
	mtrr_type type;

	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_WRBACK)
			continue;
		base = range_state[i].base_pfn;
		size = range_state[i].size_pfn;
		nr_range = add_range_with_merge(range, nr_range, base,
						base + size - 1);
	}
	if (debug_print) {
		printk(KERN_DEBUG "After WB checking\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
				 range[i].start, range[i].end + 1);
	}

	/* take out UC ranges */
	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_UNCACHABLE &&
		    type != MTRR_TYPE_WRPROT)
			continue;
		size = range_state[i].size_pfn;
		if (!size)
			continue;
		base = range_state[i].base_pfn;
		subtract_range(range, base, base + size - 1);
	}
	if (extra_remove_size)
		subtract_range(range, extra_remove_base,
				 extra_remove_base + extra_remove_size  - 1);

	/* get new range num */
	nr_range = 0;
	for (i = 0; i < RANGE_NUM; i++) {
		if (!range[i].end)
			continue;
		nr_range++;
	}
	if  (debug_print) {
		printk(KERN_DEBUG "After UC checking\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
				 range[i].start, range[i].end + 1);
	}

	/* sort the ranges */
	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
	if  (debug_print) {
		printk(KERN_DEBUG "After sorting\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
				 range[i].start, range[i].end + 1);
	}

	/* clear those is not used */
	for (i = nr_range; i < RANGE_NUM; i++)
		memset(&range[i], 0, sizeof(range[i]));

	return nr_range;
}
Ejemplo n.º 4
0
/* WB를 *range 배열에 merge하면서 정리해 넣고
 * UC와 WP는 이 range 영역에서 빼고 정렬한다.
 */
static int __init
x86_get_mtrr_mem_range(struct range *range, int nr_range,
		       unsigned long extra_remove_base,
		       unsigned long extra_remove_size)
{
	unsigned long base, size;
	mtrr_type type;
	int i;
	/* WB영역중 중첩되는 range를 합친다. */
	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_WRBACK)
			continue; /* WB가 아니면 패스 */
		base = range_state[i].base_pfn;
		size = range_state[i].size_pfn;
		/* WB영역중에서 중첩되는 부분을 합쳐서 range 배열에 넣는다. */
		nr_range = add_range_with_merge(range, RANGE_NUM, nr_range,
						base, base + size);
	}
	if (debug_print) {
		printk(KERN_DEBUG "After WB checking\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
				 range[i].start, range[i].end);
	}

	/* Take out UC ranges: */
	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		/* UC나 WP가 아니면 패스 */
		if (type != MTRR_TYPE_UNCACHABLE &&
		    type != MTRR_TYPE_WRPROT)
			continue;
		size = range_state[i].size_pfn;
		if (!size)
			continue;
		base = range_state[i].base_pfn;
		/* base는 4KB 단위다. 256 이하, 즉 1M 이하이면서
		 * fixed(1M) mtrr가 있으면서 enable인 예외상황을 가리킨다.
		 * 즉 fixed mtrr과 variable mtrr이 중첩되서 생기는 버그 경고이다.
		 */
		if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
		    (mtrr_state.enabled & 1)) {
			/* Var MTRR contains UC entry below 1M? Skip it: */
			printk(BIOS_BUG_MSG, i);
			if (base + size <= (1<<(20-PAGE_SHIFT)))
				continue;
			size -= (1<<(20-PAGE_SHIFT)) - base;
			base = 1<<(20-PAGE_SHIFT);
		}
		/* WB가 모인 range에서 UC, WP영역과 겹치는 부분을 뺀다. */
		subtract_range(range, RANGE_NUM, base, base + size);
	}
	if (extra_remove_size)	/* 인자로 들어온 4G 넘는 영역을 빼준다. */
		subtract_range(range, RANGE_NUM, extra_remove_base,
				 extra_remove_base + extra_remove_size);

	if  (debug_print) {
		printk(KERN_DEBUG "After UC checking\n");
		for (i = 0; i < RANGE_NUM; i++) {
			if (!range[i].end)
				continue;
			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
				 range[i].start, range[i].end);
		}
	}

	/* sort the ranges */
	nr_range = clean_sort_range(range, RANGE_NUM); /* 정렬 */
	if  (debug_print) {
		printk(KERN_DEBUG "After sorting\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016llx - %016llx\n",
				 range[i].start, range[i].end);
	}

	return nr_range;
}
Ejemplo n.º 5
0
static int __init
x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
		       unsigned long extra_remove_base,
		       unsigned long extra_remove_size)
{
	unsigned long base, size;
	mtrr_type type;
	int i;

	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_WRBACK)
			continue;
		base = range_state[i].base_pfn;
		size = range_state[i].size_pfn;
		nr_range = add_range_with_merge(range, nr_range, base,
						base + size - 1);
	}
	if (debug_print) {
		printk(KERN_DEBUG "After WB checking\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
				 range[i].start, range[i].end + 1);
	}

	
	for (i = 0; i < num_var_ranges; i++) {
		type = range_state[i].type;
		if (type != MTRR_TYPE_UNCACHABLE &&
		    type != MTRR_TYPE_WRPROT)
			continue;
		size = range_state[i].size_pfn;
		if (!size)
			continue;
		base = range_state[i].base_pfn;
		if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
		    (mtrr_state.enabled & 1)) {
			
			printk(BIOS_BUG_MSG, i);
			if (base + size <= (1<<(20-PAGE_SHIFT)))
				continue;
			size -= (1<<(20-PAGE_SHIFT)) - base;
			base = 1<<(20-PAGE_SHIFT);
		}
		subtract_range(range, base, base + size - 1);
	}
	if (extra_remove_size)
		subtract_range(range, extra_remove_base,
				 extra_remove_base + extra_remove_size  - 1);

	
	nr_range = 0;
	for (i = 0; i < RANGE_NUM; i++) {
		if (!range[i].end)
			continue;
		nr_range++;
	}
	if  (debug_print) {
		printk(KERN_DEBUG "After UC checking\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
				 range[i].start, range[i].end + 1);
	}

	
	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
	if  (debug_print) {
		printk(KERN_DEBUG "After sorting\n");
		for (i = 0; i < nr_range; i++)
			printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
				 range[i].start, range[i].end + 1);
	}

	
	for (i = nr_range; i < RANGE_NUM; i++)
		memset(&range[i], 0, sizeof(range[i]));

	return nr_range;
}