Esempio 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;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}