[Skiboot] [RFC PATCH 11/12] core/console: Split memcons into msglog and inmem_con

Oliver O'Halloran oohall at gmail.com
Tue May 19 15:46:32 AEST 2020


Seperate the single "memcons" into "msglog" for the skiboot log buffer
and "inmem_con" for the in-memory console that's used for systems
without a console (i.e. cronus booted systems).

Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
---
 core/console.c             | 68 ++++++++++++++++++++++++++++----------
 core/init.c                |  2 +-
 core/opal.c                |  2 +-
 include/console.h          |  5 +--
 include/mem-map.h          | 10 ++++--
 platforms/ibm-fsp/common.c | 11 ++++--
 6 files changed, 70 insertions(+), 28 deletions(-)

diff --git a/core/console.c b/core/console.c
index d37a4cb128e2..bfeb7aae39e0 100644
--- a/core/console.c
+++ b/core/console.c
@@ -30,8 +30,21 @@ static struct opal_con_ops *opal_con_driver = &dummy_opal_con;
 
 static struct lock con_lock = LOCK_UNLOCKED;
 
+/* The descriptors are is mapped via TCEs so we keep it alone in a page */
+struct memcons_desc msglog_desc __section(".data.memcons") = {
+	.magic		= CPU_TO_BE64(MEMCONS_MAGIC),
+	.obuf_phys	= CPU_TO_BE64(MSGLOG_START),
+	.obuf_size	= CPU_TO_BE32(MSGLOG_LEN),
+};
+
+struct memcons msglog = {
+	.desc = &msglog_desc,
+	.obuf      = (char *) MSGLOG_START,
+	.obuf_size =          MSGLOG_LEN,
+};
+
 /* This is mapped via TCEs so we keep it alone in a page */
-struct memcons_desc memcons_desc __section(".data.memcons") = {
+struct memcons_desc inmem_con_desc __section(".data.memcons") = {
 	.magic		= CPU_TO_BE64(MEMCONS_MAGIC),
 	.obuf_phys	= CPU_TO_BE64(INMEM_CON_START),
 	.ibuf_phys	= CPU_TO_BE64(INMEM_CON_START + INMEM_CON_OUT_LEN),
@@ -39,8 +52,8 @@ struct memcons_desc memcons_desc __section(".data.memcons") = {
 	.ibuf_size	= CPU_TO_BE32(INMEM_CON_IN_LEN),
 };
 
-struct memcons memcons = {
-	.desc = &memcons_desc,
+struct memcons inmem_con = {
+	.desc = &inmem_con_desc,
 	.obuf      = (char *) INMEM_CON_START,
 	.obuf_size =          INMEM_CON_OUT_LEN,
 
@@ -90,7 +103,7 @@ struct dt_node *add_opal_console_node(int index, const char *type,
 
 void clear_console(void)
 {
-	memset(memcons.obuf, 0, memcons.obuf_size);
+	memset(msglog.obuf, 0, msglog.obuf_size);
 }
 
 /*
@@ -106,7 +119,7 @@ static bool __flush_console(bool flush_to_drivers, bool need_unlock)
 	static bool in_flush, more_flush;
 
 	/* Is there anything to flush ? Bail out early if not */
-	if (memcons.out_pos == flush_head || !con_driver)
+	if (msglog.out_pos == flush_head || !con_driver)
 		return false;
 
 	/*
@@ -145,7 +158,7 @@ static bool __flush_console(bool flush_to_drivers, bool need_unlock)
 	 *     flush_head.
 	 */
 	if (!flush_to_drivers) {
-		flush_head = memcons.out_pos;
+		flush_head = msglog.out_pos;
 		in_flush = false;
 		return false;
 	}
@@ -153,14 +166,14 @@ static bool __flush_console(bool flush_to_drivers, bool need_unlock)
 	do {
 		more_flush = false;
 
-		if (flush_head > memcons.out_pos) {
+		if (flush_head > msglog.out_pos) {
 			req = INMEM_CON_OUT_LEN - flush_head;
 			more_flush = true;
 		} else
-			req = memcons.out_pos - flush_head;
+			req = msglog.out_pos - flush_head;
 
 		unlock(&con_lock);
-		len = con_driver->write(memcons.obuf + flush_head, req);
+		len = con_driver->write(msglog.obuf + flush_head, req);
 		lock(&con_lock);
 
 		flush_head = (flush_head + len) % INMEM_CON_OUT_LEN;
@@ -171,7 +184,7 @@ static bool __flush_console(bool flush_to_drivers, bool need_unlock)
 	} while(more_flush);
 
 	in_flush = false;
-	return flush_head != memcons.out_pos;
+	return flush_head != msglog.out_pos;
 }
 
 bool flush_console(void)
@@ -213,11 +226,11 @@ static void inmem_write(struct memcons *mcon, char c)
 
 static void write_char(char c)
 {
-	inmem_write(&memcons, c);
+	inmem_write(&msglog, c);
 
 	/* If head reaches tail, push tail around & drop chars */
-	if (flush_head == memcons.desc->out_pos)
-		flush_head = (memcons.desc->out_pos + 1) % memcons.desc->obuf_size;
+	if (flush_head == msglog.desc->out_pos)
+		flush_head = (msglog.desc->out_pos + 1) % msglog.desc->obuf_size;
 }
 
 ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count)
@@ -248,6 +261,16 @@ ssize_t write(int fd __unused, const void *buf, size_t count)
 	return console_write(true, buf, count);
 }
 
+/* flushes the msglog into the inmem_con */
+static size_t msglog_glue(const char *buf, size_t len)
+{
+	return write(0, buf, len);
+}
+
+static struct con_ops dummy_con_glue = {
+	.write = msglog_glue,
+};
+
 static size_t inmem_read(struct memcons *mcon, char *buf, size_t req)
 {
 	size_t read = 0;
@@ -268,8 +291,9 @@ ssize_t read(int fd __unused, void *buf, size_t req_count)
 	bool need_unlock = lock_recursive(&con_lock);
 	size_t count = 0;
 
+	/* NB: we are reading the input buffer of inmem_con, *not* msglog */
 	if (!count)
-		count = inmem_read(&memcons, buf, req_count);
+		count = inmem_read(&inmem_con, buf, req_count);
 	if (need_unlock)
 		unlock(&con_lock);
 	return count;
@@ -329,6 +353,8 @@ void init_opal_console(void)
 		prlog(PR_WARNING, "OPAL: Dummy console forced, %s ignored\n",
 		      opal_con_driver->name);
 
+		/* FIXME: Do this earlier? */
+		set_console(&dummy_con_glue);
 		opal_con_driver = &dummy_opal_con;
 	}
 
@@ -344,9 +370,15 @@ void init_opal_console(void)
 			opal_con_driver->space, 2);
 }
 
-void memcons_add_properties(void)
+void msglog_add_properties(void)
 {
-	dt_add_property_u64(opal_node, "ibm,opal-memcons", (u64) &memcons_desc);
+	/*
+	 * This property is poorly named for historical reasons. OSes (Linux
+	 * at least) use this to read the skiboot msglog so it should point
+	 * at that. The input buffer is pointed to by the descriptor never referenced directly by the OS
+	 * since all console IO goes via the OPAL API calls.
+	 */
+	dt_add_property_u64(opal_node, "ibm,opal-memcons", (u64) &msglog_desc);
 }
 
 /*
@@ -418,7 +450,7 @@ static void dummy_console_poll(void *data __unused)
 	bool has_data = false;
 
 	lock(&con_lock);
-	if (memcons.desc->in_prod != memcons.desc->in_cons)
+	if (inmem_con.desc->in_prod != inmem_con.desc->in_cons)
 		has_data = true;
 	if (has_data)
 		opal_update_pending_evt(OPAL_EVENT_CONSOLE_INPUT,
@@ -432,7 +464,7 @@ void dummy_console_add_nodes(void)
 {
 	struct dt_property *p;
 
-	add_opal_console_node(0, "raw", be32_to_cpu(memcons.desc->obuf_size));
+	add_opal_console_node(0, "raw", be32_to_cpu(inmem_con.desc->obuf_size));
 
 	/* Mambo might have left a crap one, clear it */
 	p = __dt_find_property(dt_chosen, "linux,stdout-path");
diff --git a/core/init.c b/core/init.c
index 595d087fa4f3..bcc2bd78a46c 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1013,7 +1013,7 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
 	/*
 	 * Point to our mem console
 	 */
-	debug_descriptor.memcons_phys = cpu_to_be64((uint64_t)&memcons);
+	debug_descriptor.memcons_phys = cpu_to_be64((uint64_t)&inmem_con);
 
 	/*
 	 * Before first printk, ensure console buffer is clear or
diff --git a/core/opal.c b/core/opal.c
index 64fdfe62aff2..b46369a68b22 100644
--- a/core/opal.c
+++ b/core/opal.c
@@ -419,7 +419,7 @@ void add_opal_node(void)
 
 	add_opal_firmware_node();
 	add_associativity_ref_point();
-	memcons_add_properties();
+	msglog_add_properties();
 }
 
 static struct lock evt_lock = LOCK_UNLOCKED;
diff --git a/include/console.h b/include/console.h
index 280f920aba44..820cb1de6452 100644
--- a/include/console.h
+++ b/include/console.h
@@ -47,7 +47,8 @@ struct memcons {
 	bool has_wrapped;
 };
 
-extern struct memcons memcons;
+extern struct memcons msglog;
+extern struct memcons inmem_con;
 
 #define INMEM_CON_IN_LEN	16
 #define INMEM_CON_OUT_LEN	(INMEM_CON_LEN - INMEM_CON_IN_LEN)
@@ -93,7 +94,7 @@ extern void enable_mambo_console(void);
 ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count);
 
 extern void clear_console(void);
-extern void memcons_add_properties(void);
+extern void msglog_add_properties(void);
 extern void dummy_console_add_nodes(void);
 
 struct dt_node *add_opal_console_node(int index, const char *type,
diff --git a/include/mem-map.h b/include/mem-map.h
index b654012576b9..797117d7bc82 100644
--- a/include/mem-map.h
+++ b/include/mem-map.h
@@ -88,12 +88,16 @@
 #define HEAP_SIZE		0x00b00000
 
 /* This is the location of our console buffer at base + 16M */
-#define INMEM_CON_START		(SKIBOOT_BASE + 0x01000000)
-#define INMEM_CON_LEN  		0x100000
+#define MSGLOG_START		(SKIBOOT_BASE + 0x01000000)
+#define MSGLOG_LEN  		0x100000
 
 /* This is the location of HBRT console buffer at base + 17M */
 #define HBRT_CON_START		(SKIBOOT_BASE + 0x01100000)
-#define HBRT_CON_LEN  		0x100000
+#define HBRT_CON_LEN  		0x080000
+
+/* This is the location of HBRT console buffer at base + 17.5M */
+#define INMEM_CON_START		(SKIBOOT_BASE + 0x01180000)
+#define INMEM_CON_LEN  		0x080000
 
 /* Tell FSP to put the init data at base + 20M, allocate 8M */
 #define SPIRA_HEAP_BASE		(SKIBOOT_BASE + 0x01200000)
diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c
index 6a20dc7ac36a..3cf18b0e56bf 100644
--- a/platforms/ibm-fsp/common.c
+++ b/platforms/ibm-fsp/common.c
@@ -21,13 +21,18 @@ static void map_debug_areas(void)
 	/* Our memcons is in a section of its own and already
 	 * aligned to 4K. The buffers are mapped as a whole
 	 */
-	fsp_tce_map(PSI_DMA_MEMCONS, memcons.desc, 0x1000);
+	fsp_tce_map(PSI_DMA_MEMCONS, inmem_con.desc, 0x1000);
 	fsp_tce_map(PSI_DMA_LOG_BUF, (void*)INMEM_CON_START, INMEM_CON_LEN);
 
+	/*
+	 * FIXME: should this be mapping the msglog, or the inmem console,
+	 * or both? What actually does DMAs here?
+	 */
+
 	debug_descriptor.memcons_tce = cpu_to_be32(PSI_DMA_MEMCONS);
-	t = be64_to_cpu(memcons.desc->obuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF;
+	t = be64_to_cpu(inmem_con.desc->obuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF;
 	debug_descriptor.memcons_obuf_tce = cpu_to_be32(t);
-	t = be64_to_cpu(memcons.desc->ibuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF;
+	t = be64_to_cpu(inmem_con.desc->ibuf_phys) - INMEM_CON_START + PSI_DMA_LOG_BUF;
 	debug_descriptor.memcons_ibuf_tce = cpu_to_be32(t);
 
 	t = PSI_DMA_TRACE_BASE;
-- 
2.26.2



More information about the Skiboot mailing list