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; }
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); }
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; }
/* 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; }
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; }