diff mbox

hdata/memory: Add memory reservations to the DT

Message ID 20170720060958.32396-1-oohall@gmail.com
State Accepted
Headers show

Commit Message

Oliver O'Halloran July 20, 2017, 6:09 a.m. UTC
Currently we just add these to a list of pre-boot reserved regions
which is then converted into a the contents of the /reserved-memory/
node just before Skiboot jumps into the firmware kernel.

This approach is insufficent because we need to add the ibm,prd-instance
labels to the various hostboot reserved regions. To do this we want to
create these resevation nodes inside the HDAT parser rather than having
the mem_region flattening code handle it. On P8 systems Hostboot placed
its memory reservations under the /ibm,hostboot/ node and this patch
makes the HDAT parser do the same.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 hdata/memory.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 hdata/spira.h  |  5 ++++-
 2 files changed, 55 insertions(+), 4 deletions(-)

Comments

Stewart Smith July 25, 2017, 8:19 a.m. UTC | #1
Oliver O'Halloran <oohall@gmail.com> writes:
> Currently we just add these to a list of pre-boot reserved regions
> which is then converted into a the contents of the /reserved-memory/
> node just before Skiboot jumps into the firmware kernel.
>
> This approach is insufficent because we need to add the ibm,prd-instance
> labels to the various hostboot reserved regions. To do this we want to
> create these resevation nodes inside the HDAT parser rather than having
> the mem_region flattening code handle it. On P8 systems Hostboot placed
> its memory reservations under the /ibm,hostboot/ node and this patch
> makes the HDAT parser do the same.
>
> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
> ---
>  hdata/memory.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
>  hdata/spira.h  |  5 ++++-
>  2 files changed, 55 insertions(+), 4 deletions(-)

Merged to master as of efa238b10f835808d110a66135e12c72367b97dc
diff mbox

Patch

diff --git a/hdata/memory.c b/hdata/memory.c
index d6550e61f584..b80d33cde860 100644
--- a/hdata/memory.c
+++ b/hdata/memory.c
@@ -403,12 +403,42 @@  static void get_msareas(struct dt_node *root,
 	}
 }
 
+static struct dt_node *dt_hb_reserves;
+
+static struct dt_node *add_hb_reserve_node(const char *name, u64 start, u64 end)
+{
+	struct dt_node *node, *hb;
+
+	if (!dt_hb_reserves) {
+		hb = dt_new_check(dt_root, "ibm,hostboot");
+		dt_add_property_cells(hb, "#size-cells", 2);
+		dt_add_property_cells(hb, "#address-cells", 2);
+
+		dt_hb_reserves = dt_new_check(hb, "reserved-memory");
+		dt_add_property(dt_hb_reserves, "ranges", NULL, 0);
+		dt_add_property_cells(dt_hb_reserves, "#size-cells", 2);
+		dt_add_property_cells(dt_hb_reserves, "#address-cells", 2);
+	}
+
+	node = dt_new_addr(dt_hb_reserves, name, start);
+	if (!node) {
+		prerror("Unable to create node for %s@%llx\n",
+			name, (unsigned long long) start);
+		return NULL;
+	}
+
+	dt_add_property_u64s(node, "reg", start, end - start + 1);
+
+	return node;
+}
+
 #define HRMOR_BIT (1ul << 63)
 
 static void get_hb_reserved_mem(struct HDIF_common_hdr *ms_vpd)
 {
 	const struct msvpd_hb_reserved_mem *hb_resv_mem;
 	u64 start_addr, end_addr, label_size;
+	struct dt_node *node;
 	int count, i;
 	char *label;
 
@@ -472,7 +502,17 @@  static void get_hb_reserved_mem(struct HDIF_common_hdr *ms_vpd)
 		prlog(PR_DEBUG, "MEM: Reserve '%s' %#" PRIx64 "-%#" PRIx64 " (type/inst=0x%08x)\n",
 		      label, start_addr, end_addr, be32_to_cpu(hb_resv_mem->type_instance));
 
-		mem_reserve_fw(label, start_addr, end_addr - start_addr + 1);
+		node = add_hb_reserve_node(label, start_addr, end_addr);
+		if (!node) {
+			prerror("unable to add node?\n");
+			continue;
+		}
+
+		/* the three low bytes of type_instance is the instance data */
+		dt_add_property_cells(node, "ibm,prd-instance",
+			(be32_to_cpu(hb_resv_mem->type_instance) & 0xffffff));
+
+		dt_add_property_string(node, "ibm,prd-label", label);
 	}
 }
 
@@ -502,6 +542,7 @@  static void parse_trace_reservations(struct HDIF_common_hdr *ms_vpd)
 
 	for (i = 0; i < count; i++) {
 		const struct msvpd_trace *trace_area;
+		struct dt_node *node;
 		u64 start, end;
 
 		trace_area = HDIF_get_iarray_item(ms_vpd,
@@ -514,10 +555,17 @@  static void parse_trace_reservations(struct HDIF_common_hdr *ms_vpd)
 		end = be64_to_cpu(trace_area->end) & ~HRMOR_BIT;
 
 		prlog(PR_INFO,
-			"MSVPD: Trace area: 0x%.16"PRIx64"-0x%.16"PRIx64"\n",
+			"MS VPD: Trace area: 0x%.16"PRIx64"-0x%.16"PRIx64"\n",
 			start, end);
 
-		mem_reserve_hwbuf("trace-area", start, end - start);
+		node = add_hb_reserve_node("trace-area", start, end);
+		if (!node) {
+			prerror("MEM: Unable to reserve trace area %p-%p\n",
+				(void *) start, (void *) end);
+			continue;
+		}
+
+		dt_add_property(node, "no-map", NULL, 0);
 	}
 }
 
diff --git a/hdata/spira.h b/hdata/spira.h
index caea057e3b79..4867b6d1ae5b 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -530,7 +530,10 @@  struct msvpd_hb_reserved_mem {
 	__be64		end_addr;
 	__be32		label_size;
 	uint8_t		label[64];
-	__be64		reserved;
+	uint8_t		rw_perms;
+#define HB_RESERVE_READABLE 0x80
+#define HB_RESERVE_WRITEABLE 0x40
+	uint8_t		reserved[7];
 } __packed;
 
 /* Child index 0: MS area child structure */