@@ -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");
@@ -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
@@ -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;
@@ -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,
@@ -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)
@@ -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;
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@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(-)