diff options
author | gonzo <gonzo@FreeBSD.org> | 2012-11-30 03:11:03 +0000 |
---|---|---|
committer | gonzo <gonzo@FreeBSD.org> | 2012-11-30 03:11:03 +0000 |
commit | df6a0a2978f573b82f6c7a317da896198d42df22 (patch) | |
tree | 2dd5bd1cf83330b92c78a41774d05c1cad114f8e /sys/arm | |
parent | d948e0882e798da2fb0f38e973079ae7839f2115 (diff) | |
download | FreeBSD-src-df6a0a2978f573b82f6c7a317da896198d42df22.zip FreeBSD-src-df6a0a2978f573b82f6c7a317da896198d42df22.tar.gz |
Get reserved memory regions and exclude them from available memory map
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/machdep.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 08d6fc1..e358f96 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -1144,7 +1144,9 @@ physmap_init(struct mem_region *availmem_regions, int availmem_regions_sz) void * initarm(struct arm_boot_params *abp) { + struct mem_region memory_regions[FDT_MEM_REGIONS]; struct mem_region availmem_regions[FDT_MEM_REGIONS]; + struct mem_region reserved_regions[FDT_MEM_REGIONS]; struct pv_addr kernel_l1pt; struct pv_addr dpcpu; vm_offset_t dtbp, freemempos, l2_start, lastaddr; @@ -1154,7 +1156,12 @@ initarm(struct arm_boot_params *abp) void *kmdp; u_int l1pagetable; int i = 0, j = 0, err_devmap = 0; + int memory_regions_sz; int availmem_regions_sz; + int reserved_regions_sz; + vm_offset_t start, end; + vm_offset_t rstart, rend; + int curr; lastaddr = parse_boot_param(abp); memsize = 0; @@ -1185,10 +1192,73 @@ initarm(struct arm_boot_params *abp) while (1); /* Grab physical memory regions information from device tree. */ - if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz, + if (fdt_get_mem_regions(memory_regions, &memory_regions_sz, &memsize) != 0) while(1); + /* Grab physical memory regions information from device tree. */ + if (fdt_get_reserved_regions(reserved_regions, &reserved_regions_sz) != 0) + reserved_regions_sz = 0; + + /* + * Now exclude all the reserved regions + */ + curr = 0; + for (i = 0; i < memory_regions_sz; i++) { + start = memory_regions[i].mr_start; + end = start + memory_regions[i].mr_size; + for (j = 0; j < reserved_regions_sz; j++) { + rstart = reserved_regions[j].mr_start; + rend = rstart + reserved_regions[j].mr_size; + /* + * Restricted region is before available + * Skip restricted region + */ + if (rend <= start) + continue; + /* + * Restricted region is behind available + * No further processing required + */ + if (rstart >= end) + break; + /* + * Restricted region includes memory region + * skip availble region + */ + if ((start >= rstart) && (rend >= end)) { + start = rend; + end = rend; + break; + } + /* + * Memory region includes restricted region + */ + if ((rstart > start) && (end > rend)) { + availmem_regions[curr].mr_start = start; + availmem_regions[curr++].mr_size = rstart - start; + start = rend; + break; + } + /* + * Memory region partially overlaps with restricted + */ + if ((rstart >= start) && (rstart <= end)) { + end = rstart; + } + else if ((rend >= start) && (rend <= end)) { + start = rend; + } + } + + if (end > start) { + availmem_regions[curr].mr_start = start; + availmem_regions[curr++].mr_size = end - start; + } + } + + availmem_regions_sz = curr; + /* Platform-specific initialisation */ pmap_bootstrap_lastaddr = initarm_lastaddr(); |