All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Waychison <mikew@google.com>
To: Greg KH <greg@kroah.com>, torvalds@linux-foundation.org
Cc: San Mehat <san@google.com>, Aaron Durbin <adurbin@google.com>,
	Duncan Laurie <dlaurie@google.com>,
	linux-kernel@vger.kernel.org, Tim Hockin <thockin@google.com>
Subject: [PATCH v1 6/6] driver: Google Memory Console
Date: Mon, 24 Jan 2011 16:25:05 -0800	[thread overview]
Message-ID: <20110125002505.12637.84140.stgit@mike.mtv.corp.google.com> (raw)
In-Reply-To: <20110125002433.12637.51091.stgit@mike.mtv.corp.google.com>

This patch introduces the 'memconsole' driver.

Our firmware gives us access to an in-memory log of the firmware's
output.   This gives us visibility in a data-center of headless machines
as to what the firmware is doing.

The memory console is found by the driver by finding a header block in
the EBDA.  The buffer is then copied out, and is currently prepended
to the kernel's dmesg ring-buffer.

Signed-off-by: San Mehat <san@google.com>
Signed-off-by: Mike Waychison <mikew@google.com>
---
 drivers/firmware/google/Kconfig      |    8 ++
 drivers/firmware/google/Makefile     |    1 
 drivers/firmware/google/memconsole.c |  136 ++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+), 0 deletions(-)
 create mode 100644 drivers/firmware/google/memconsole.c

diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
index 0490a62..7218671 100644
--- a/drivers/firmware/google/Kconfig
+++ b/drivers/firmware/google/Kconfig
@@ -28,4 +28,12 @@ config GOOGLE_BOOTLOG
 	  This enables support for displaying boot log information in dmesg
 	  as well as logging the kernel shutdown reasons.
 
+config GOOGLE_MEMCONSOLE
+	bool "Firmware Memory Console"
+	default y
+	help
+	  This option enables the kernel to search for a firmware log in
+	  the EBDA.  If found, this log is prepended to the kernel's
+	  dmesg logs so they are visible to the user.
+
 endmenu
diff --git a/drivers/firmware/google/Makefile b/drivers/firmware/google/Makefile
index d45e10c..cb8598e 100644
--- a/drivers/firmware/google/Makefile
+++ b/drivers/firmware/google/Makefile
@@ -1,3 +1,4 @@
 
 obj-$(CONFIG_GOOGLE_SMI)		+= gsmi.o
 obj-$(CONFIG_GOOGLE_BOOTLOG)		+= bootlog.o
+obj-$(CONFIG_GOOGLE_MEMCONSOLE)		+= memconsole.o
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
new file mode 100644
index 0000000..6777a64
--- /dev/null
+++ b/drivers/firmware/google/memconsole.c
@@ -0,0 +1,136 @@
+/*
+ * memconsole.c
+ *
+ * Infrastructure for importing the BIOS memory based console
+ * into the kernel log ringbuffer.
+ *
+ * Copyright 2010 Google Inc. All rights reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/bios_ebda.h>
+
+#define BIOS_MEMCONSOLE_V1_MAGIC	0xDEADBABE
+#define BIOS_MEMCONSOLE_V2_MAGIC	(('M')|('C'<<8)|('O'<<16)|('N'<<24))
+
+struct biosmemcon_ebda {
+	uint32_t signature;
+	union {
+		struct {
+			uint8_t  enabled;
+			uint32_t buffer_addr;
+			uint16_t start;
+			uint16_t end;
+			uint16_t num_chars;
+			uint8_t  wrapped;
+		} __packed v1;
+		struct {
+			uint32_t buffer_addr;
+			/* Misdocumented as number of pages! */
+			uint16_t  num_bytes;
+			uint16_t start;
+			uint16_t end;
+		} __packed v2;
+	} ptr;
+} __packed;
+
+static void __init sanitize_buffer(char *buffer, size_t length) {
+	size_t cur;
+
+	/* sanitize BIOS output by converting non-ascii into space */
+	for (cur = 0; cur < length; cur++) {
+		if (!isascii(buffer[cur]) || buffer[cur] == 0)
+			buffer[cur] = ' ';
+	}
+}
+
+/*
+ * Search through the EBDA for the BIOS Memory Console, and
+ * prepend it to our ring buffer
+ */
+static int __init inject_memconsole(void)
+{
+	static struct biosmemcon_ebda __initdata hdr = {0};
+	unsigned int address;
+	size_t length, cur;
+	uint32_t *bp;
+	char *virtp;
+	int found = 0;
+
+	address = get_bios_ebda();
+	if (!address) {
+		printk(KERN_INFO "BIOS EBDA non-existent.\n");
+		return 0;
+	}
+
+	/* EBDA length is byte 0 of EBDA (in KB) */
+	length = *(uint8_t *)phys_to_virt(address);
+	length <<= 10; /* convert to bytes */
+
+	/*
+	 * Search through EBDA for BIOS memory console structure
+	 * note: signature is not necessarily dword-aligned
+	 */
+	for (cur = 0; cur < length; cur++) {
+		bp = phys_to_virt(address + cur);
+
+		/* memconsole v1 */
+		if (*bp == BIOS_MEMCONSOLE_V1_MAGIC) {
+			memcpy(&hdr, bp, sizeof(hdr));
+			found = 1;
+			break;
+		}
+
+		/* memconsole v2 */
+		if (*bp == BIOS_MEMCONSOLE_V2_MAGIC) {
+			memcpy(&hdr, bp, sizeof(hdr));
+			found = 2;
+			break;
+		}
+	}
+
+	/*
+	 * At this point hdr points to the EBDA structure
+	 * Shift the contents of the kernel ring by the size of
+	 * the contents in the bios ring.
+	 */
+
+	switch (found) {
+	case 1:
+		printk(KERN_INFO "BIOS console v1 EBDA structure found at %p\n",
+		       bp);
+		printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
+		       "start = %d, end = %d, num = %d\n",
+		       hdr.ptr.v1.buffer_addr, hdr.ptr.v1.start,
+		       hdr.ptr.v1.end, hdr.ptr.v1.num_chars);
+
+		length = hdr.ptr.v1.num_chars;
+		virtp = phys_to_virt(hdr.ptr.v1.buffer_addr);
+		sanitize_buffer(virtp, length);
+		prepend_to_dmesg(virtp, length);
+
+		break;
+	case 2:
+		printk(KERN_INFO "BIOS console v2 EBDA structure found at %p\n",
+		       bp);
+		printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
+		       "start = %d, end = %d, num_bytes = %d\n",
+		       hdr.ptr.v2.buffer_addr, hdr.ptr.v2.start,
+		       hdr.ptr.v2.end, hdr.ptr.v2.num_bytes);
+
+		length = hdr.ptr.v2.end - hdr.ptr.v2.start;
+		virtp = phys_to_virt(hdr.ptr.v2.buffer_addr + hdr.ptr.v2.start);
+		sanitize_buffer(virtp, length);
+		prepend_to_dmesg(virtp, length);
+
+		break;
+	case 0:
+	default:
+		printk("BIOS console EBDA structure not found!\n");
+	}
+	return 0;
+}
+device_initcall(inject_memconsole);


  parent reply	other threads:[~2011-01-25  0:25 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-25  0:24 [PATCH v1 0/6] google firmware support Mike Waychison
2011-01-25  0:24 ` [PATCH v1 1/6] Add oops notification chain Mike Waychison
2011-01-25  2:06   ` Greg KH
2011-01-25 20:01     ` Mike Waychison
2011-01-25 21:36       ` Jeff Garzik
2011-01-25 21:43         ` Aaron Durbin
2011-01-25 21:54           ` Jeff Garzik
2011-01-25 22:21             ` Aaron Durbin
2011-01-26  2:48               ` Greg KH
2011-01-26 21:50                 ` Mike Waychison
2011-01-25  0:24 ` [PATCH v1 2/6] Introduce CONFIG_GOOGLE_FIRMWARE Mike Waychison
2011-01-25  0:24 ` [PATCH v1 3/6] driver: Google EFI SMI Mike Waychison
2011-01-25  3:17   ` Greg KH
2011-01-25 23:12     ` Mike Waychison
2011-01-26  2:46       ` Greg KH
2011-01-26 23:58         ` Mike Waychison
2011-01-27  1:22           ` Mike Waychison
2011-01-27 23:41             ` Mike Waychison
2011-01-28  2:56               ` Greg KH
2011-02-20  4:44               ` Matt Domsch
2011-02-21 13:58                 ` Matthew Garrett
2011-01-27 10:43           ` Alan Cox
2011-01-27 19:22             ` Mike Waychison
2011-01-28  2:55               ` Greg KH
2011-01-28  2:59           ` Greg KH
2011-01-25  0:24 ` [PATCH v1 4/6] driver: Google Bootlog Mike Waychison
2011-01-25  0:49   ` Alan Cox
2011-01-25  1:38     ` Mike Waychison
2011-01-25  9:43       ` Alan Cox
2011-01-25  0:25 ` [PATCH v1 5/6] Allow prepending to the dmesg Mike Waychison
2011-01-25  1:01   ` Andrew Morton
2011-01-25  0:25 ` Mike Waychison [this message]
2011-01-25  2:00   ` [PATCH v1 6/6] driver: Google Memory Console Greg KH
2011-01-25  3:01 ` [PATCH v1 0/6] google firmware support Greg KH
2011-01-25 19:58   ` Mike Waychison
2011-01-26  2:47     ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110125002505.12637.84140.stgit@mike.mtv.corp.google.com \
    --to=mikew@google.com \
    --cc=adurbin@google.com \
    --cc=dlaurie@google.com \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=san@google.com \
    --cc=thockin@google.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.