msm_shared: Write LK log to RAM buffer

LK log messages are written to static RAM buffer.
The size of the buffer can be set with compile time define.

The LK log starts with a cookie (4bytes), max log size (4b) and
actual log size written (4b). If size written is greater than max
size then overlap has occured and latest prints have overwritten
the first ones (circular write).

Writting LK log is enabled per target with compile time define.

Change-Id: I52d3e06d0b286578d18a32969455501e2a275833
diff --git a/platform/msm_shared/debug.c b/platform/msm_shared/debug.c
index 78f20c6..3349db7 100644
--- a/platform/msm_shared/debug.c
+++ b/platform/msm_shared/debug.c
@@ -30,6 +30,7 @@
  * SUCH DAMAGE.
  */
 
+#include <stdlib.h>
 #include <debug.h>
 #include <printf.h>
 #include <arch/arm/dcc.h>
@@ -53,8 +54,49 @@
 		timeout--;
 	}
 }
+
+#if WITH_DEBUG_LOG_BUF
+
+#ifndef LK_LOG_BUF_SIZE
+#define LK_LOG_BUF_SIZE    (4096) /* align on 4k */
+#endif
+
+#define LK_LOG_COOKIE    0x474f4c52 /* "RLOG" in ASCII */
+
+struct lk_log {
+	struct lk_log_header {
+		unsigned cookie;
+		unsigned max_size;
+		unsigned size_written;
+		unsigned idx;
+	} header;
+	char data[LK_LOG_BUF_SIZE];
+};
+
+static struct lk_log log = {
+	.header = {
+		.cookie = LK_LOG_COOKIE,
+		.max_size = sizeof(log.data),
+		.size_written = 0,
+		.idx = 0,
+	},
+	.data = {0}
+};
+
+static void log_putc(char c)
+{
+	log.data[log.header.idx++] = c;
+	log.header.size_written++;
+	if (unlikely(log.header.idx >= log.header.max_size))
+		log.header.idx = 0;
+}
+#endif /* WITH_DEBUG_LOG_BUF */
+
 void _dputc(char c)
 {
+#if WITH_DEBUG_LOG_BUF
+	log_putc(c);
+#endif
 #if WITH_DEBUG_DCC
 	if (c == '\n') {
 		write_dcc('\r');