aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/console.c25
-rw-r--r--core/platform.c4
-rw-r--r--doc/opal-api/opal-console-read-write-1-2.txt16
-rw-r--r--hw/lpc-uart.c30
-rw-r--r--include/console.h4
-rw-r--r--include/opal-api.h3
6 files changed, 59 insertions, 23 deletions
diff --git a/core/console.c b/core/console.c
index 1cee5da..e851fcf 100644
--- a/core/console.c
+++ b/core/console.c
@@ -290,10 +290,29 @@ ssize_t read(int fd __unused, void *buf, size_t req_count)
return count;
}
-void flush_console_driver(void)
+static int64_t opal_console_flush(int64_t term_number)
{
- if (con_driver && con_driver->flush != NULL)
- con_driver->flush();
+ if (term_number != 0)
+ return OPAL_PARAMETER;
+
+ if (con_driver == NULL || con_driver->flush == NULL)
+ return OPAL_UNSUPPORTED;
+
+ return con_driver->flush();
+}
+opal_call(OPAL_CONSOLE_FLUSH, opal_console_flush, 1);
+
+/* Helper function to perform a full synchronous flush */
+void console_complete_flush(void)
+{
+ int64_t ret = opal_console_flush(0);
+
+ if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER)
+ return;
+
+ while (ret != OPAL_SUCCESS) {
+ ret = opal_console_flush(0);
+ }
}
void set_console(struct con_ops *driver)
diff --git a/core/platform.c b/core/platform.c
index 865d5b2..0dfbb88 100644
--- a/core/platform.c
+++ b/core/platform.c
@@ -37,7 +37,7 @@ static int64_t opal_cec_power_down(uint64_t request)
{
printf("OPAL: Shutdown request type 0x%llx...\n", request);
- flush_console_driver();
+ console_complete_flush();
if (platform.cec_power_down)
return platform.cec_power_down(request);
@@ -50,7 +50,7 @@ static int64_t opal_cec_reboot(void)
{
printf("OPAL: Reboot request...\n");
- flush_console_driver();
+ console_complete_flush();
#ifdef ENABLE_FAST_RESET
/* Try a fast reset first */
diff --git a/doc/opal-api/opal-console-read-write-1-2.txt b/doc/opal-api/opal-console-read-write-1-2.txt
index b8fbc12..26f9a16 100644
--- a/doc/opal-api/opal-console-read-write-1-2.txt
+++ b/doc/opal-api/opal-console-read-write-1-2.txt
@@ -1,11 +1,12 @@
OPAL Console calls
------------------
-There are three OPAL calls relating to the OPAL console:
+There are four OPAL calls relating to the OPAL console:
#define OPAL_CONSOLE_WRITE 1
#define OPAL_CONSOLE_READ 2
#define OPAL_CONSOLE_WRITE_BUFFER_SPACE 25
+#define OPAL_CONSOLE_FLUSH 117
The OPAL console calls can support multiple consoles. Each console MUST
be represented in the device tree.
@@ -64,3 +65,16 @@ Returns:
OPAL_CLOSED
Use OPAL_POLL_EVENTS for how to determine
+
+OPAL_CONSOLE_FLUSH
+------------------
+
+Parameters:
+ int64_t term_number
+
+Returns:
+ OPAL_SUCCESS
+ OPAL_UNSUPPORTED - the console does not implement a flush call
+ OPAL_PARAMETER - invalid term_number
+ OPAL_PARTIAL - more to flush, call again
+ OPAL_BUSY - nothing was flushed this call
diff --git a/hw/lpc-uart.c b/hw/lpc-uart.c
index e856563..2a95da5 100644
--- a/hw/lpc-uart.c
+++ b/hw/lpc-uart.c
@@ -156,11 +156,11 @@ static size_t uart_con_write(const char *buf, size_t len)
return written;
}
-static void uart_con_flush_all(void);
+static int64_t uart_con_flush(void);
static struct con_ops uart_con_driver = {
.write = uart_con_write,
- .flush = uart_con_flush_all
+ .flush = uart_con_flush
};
/*
@@ -193,9 +193,11 @@ static uint8_t *out_buf;
static uint32_t out_buf_prod;
static uint32_t out_buf_cons;
-static void uart_flush_out(void)
+/* Asynchronous flush */
+static int64_t uart_con_flush(void)
{
bool tx_was_full = tx_full;
+ uint32_t out_buf_cons_initial = out_buf_cons;
while(out_buf_prod != out_buf_cons) {
if (tx_room == 0) {
@@ -220,6 +222,15 @@ static void uart_flush_out(void)
}
if (tx_full != tx_was_full)
uart_update_ier();
+ if (out_buf_prod != out_buf_cons) {
+ /* Return busy if nothing was flushed this call */
+ if (out_buf_cons == out_buf_cons_initial)
+ return OPAL_BUSY;
+ /* Return partial if there's more to flush */
+ return OPAL_PARTIAL;
+ }
+
+ return OPAL_SUCCESS;
}
static uint32_t uart_tx_buf_space(void)
@@ -246,7 +257,7 @@ static int64_t uart_opal_write(int64_t term_number, int64_t *length,
}
/* Flush out buffer again */
- uart_flush_out();
+ uart_con_flush();
unlock(&uart_lock);
@@ -357,7 +368,7 @@ static void __uart_do_poll(u8 trace_ctx)
lock(&uart_lock);
uart_read_to_buffer();
- uart_flush_out();
+ uart_con_flush();
uart_trace(trace_ctx, 0, tx_full, in_count);
unlock(&uart_lock);
@@ -379,15 +390,6 @@ static void uart_irq(uint32_t chip_id __unused, uint32_t irq_mask __unused)
}
/*
- * Flush the entire buffer all at once
- */
-static void uart_con_flush_all(void)
-{
- while(out_buf_prod != out_buf_cons)
- uart_flush_out();
-}
-
-/*
* Common setup/inits
*/
diff --git a/include/console.h b/include/console.h
index 45f914b..b6fc8bf 100644
--- a/include/console.h
+++ b/include/console.h
@@ -51,7 +51,7 @@ struct con_ops {
size_t (*write)(const char *buf, size_t len);
size_t (*read)(char *buf, size_t len);
bool (*poll_read)(void);
- void (*flush)(void);
+ int64_t (*flush)(void);
};
extern struct lock con_lock;
@@ -62,7 +62,7 @@ extern bool flush_console(void);
extern bool __flush_console(bool flush_to_drivers);
extern void set_console(struct con_ops *driver);
-extern void flush_console_driver(void);
+extern void console_complete_flush(void);
extern int mambo_read(void);
extern void mambo_write(const char *buf, size_t count);
diff --git a/include/opal-api.h b/include/opal-api.h
index 7a11fe8..369aa93 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -162,7 +162,8 @@
#define OPAL_LEDS_GET_INDICATOR 114
#define OPAL_LEDS_SET_INDICATOR 115
#define OPAL_CEC_REBOOT2 116
-#define OPAL_LAST 116
+#define OPAL_CONSOLE_FLUSH 117
+#define OPAL_LAST 117
/* Device tree flags */