diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2015-05-19 17:05:38 +0800 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-05-21 14:41:27 +1000 |
commit | 8ab7a78c23c5e62566646aa9d5ac8749dfd73837 (patch) | |
tree | 310420a33e60e9d0c1abf48bcd35429e56bd36b3 /core/mem_region.c | |
parent | 7dabb99c1bae83091aa778b172e898d70d7d46bf (diff) | |
download | blackbird-skiboot-8ab7a78c23c5e62566646aa9d5ac8749dfd73837.tar.gz blackbird-skiboot-8ab7a78c23c5e62566646aa9d5ac8749dfd73837.zip |
core: Add node-style memory reservation to device tree
Linux supports a newer memory reservation layout in the device-tree,
where each reservation is represented by a subnode under a top-level
"reserved-memory" node.
This change adds these nodes, using the mem_region names as the property
names (minus any cell addresses). The reserved-memory node looks like
this:
/ {
name = "reserved-memory";
ranges;
#address-cells = <0x2>;
#size-cells = <0x2>;
ibm,firmware-code@30000000 {
reg = <0x0 0x30000000 0x0 0x200000>;
};
ibm,firmware-data@30e00000 {
reg = <0x0 0x30e00000 0x0 0xc00000>;
};
ibm,firmware-stacks@31a00000 {
reg = <0x0 0x31a00000 0x0 0x8000000>;
};
ibm,firmware-allocs-memory@39a00000 {
reg = <0x0 0x39a00000 0x0 0x1c0200>;
};
ibm,firmware-heap@30200000 {
reg = <0x0 0x30200000 0x0 0xc00000>;
};
};
We also store a pointer to the reservation nodes in struct mem_region,
so they can be used by other skiboot code.
We keep the property-style reservation information (reserved-names and
reserved-ranges) unchanged.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/mem_region.c')
-rw-r--r-- | core/mem_region.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/core/mem_region.c b/core/mem_region.c index ea20c5ef..0a1538dc 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -927,11 +927,30 @@ void mem_region_release_unused(void) unlock(&mem_region_lock); } +static void mem_region_add_dt_reserved_node(struct dt_node *parent, + struct mem_region *region) +{ + char *name, *p; + + name = strdup(region->name); + + /* remove any cell addresses in the region name; we have our own cell + * addresses here */ + p = strchr(name, '@'); + if (p) + *p = '\0'; + + region->node = dt_new_addr(parent, name, region->start); + dt_add_property_u64s(region->node, "reg", region->start, region->len); + free(name); +} + void mem_region_add_dt_reserved(void) { int names_len, ranges_len, len; struct mem_region *region; void *names, *ranges; + struct dt_node *node; uint64_t *range; char *name; @@ -944,6 +963,12 @@ void mem_region_add_dt_reserved(void) lock(&mem_region_lock); mem_regions_finalised = true; + /* establish top-level reservation node */ + node = dt_new(dt_root, "reserved-memory"); + dt_add_property_cells(node, "#address-cells", 2); + dt_add_property_cells(node, "#size-cells", 2); + dt_add_property(node, "ranges", NULL, 0); + /* First pass: calculate length of property data */ list_for_each(®ions, region, list) { if (!region_is_reserved(region)) @@ -969,6 +994,8 @@ void mem_region_add_dt_reserved(void) (long long)(region->start + region->len - 1), region->name); + mem_region_add_dt_reserved_node(node, region); + range[0] = cpu_to_fdt64(region->start); range[1] = cpu_to_fdt64(region->len); range += 2; |