mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mike Waychison <mikew@google.com>
To: Greg KH <greg@kroah.com>, Matt Domsch <Matt_Domsch@dell.com>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Duncan Laurie <dlaurie@google.com>,
	Aaron Durbin <adurbin@google.com>,
	x86@kernel.org, linux-kernel@vger.kernel.org,
	Tim Hockin <thockin@google.com>, San Mehat <san@google.com>
Subject: [PATCH v2 12/12] driver: Google Memory Console
Date: Fri, 11 Mar 2011 17:43:58 -0800	[thread overview]
Message-ID: <20110312014358.6133.34911.stgit@mike.mtv.corp.google.com> (raw)
In-Reply-To: <20110312014254.6133.43079.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 exported to userland in
the file /sys/firmware/log.

Signed-off-by: San Mehat <san@google.com>
Signed-off-by: Mike Waychison <mikew@google.com>
---
Changelog:
v2:
   - Removed bits that had this driver muck with the kernel's ring
     dmesg buffer (log_buf).
   - Introduced the log as /sys/firmware/log, a binary file that isn't
     interpreted by the kernel.
   - Don't use C99 fixed width types; use kernel fixed width types.
   - Added file to Documentation/ABI for /sys/firmware/log
---
 Documentation/ABI/testing/sysfs-firmware-log |    7 +
 drivers/firmware/google/Kconfig              |    8 +
 drivers/firmware/google/Makefile             |    1 
 drivers/firmware/google/memconsole.c         |  151 ++++++++++++++++++++++++++
 4 files changed, 167 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-log
 create mode 100644 drivers/firmware/google/memconsole.c

diff --git a/Documentation/ABI/testing/sysfs-firmware-log b/Documentation/ABI/testing/sysfs-firmware-log
new file mode 100644
index 0000000..9b58e7c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-log
@@ -0,0 +1,7 @@
+What:		/sys/firmware/log
+Date:		February 2011
+Contact:	Mike Waychison <mikew@google.com>
+Description:
+		The /sys/firmware/log is a binary file that represents a
+		read-only copy of the firmware's log if one is
+		available.
diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
index dfc3edc..5c3fc2e 100644
--- a/drivers/firmware/google/Kconfig
+++ b/drivers/firmware/google/Kconfig
@@ -22,4 +22,12 @@ config GOOGLE_SMI
 	  clearing the EFI event log and reading and writing NVRAM
 	  variables.
 
+config GOOGLE_MEMCONSOLE
+	tristate "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 fb127d7..54a294e 100644
--- a/drivers/firmware/google/Makefile
+++ b/drivers/firmware/google/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_GOOGLE_SMI)		+= gsmi.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..bef93dc
--- /dev/null
+++ b/drivers/firmware/google/memconsole.c
@@ -0,0 +1,151 @@
+/*
+ * 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 <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/module.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 {
+	u32 signature;
+	union {
+		struct {
+			u8  enabled;
+			u32 buffer_addr;
+			u16 start;
+			u16 end;
+			u16 num_chars;
+			u8  wrapped;
+		} __packed v1;
+		struct {
+			u32 buffer_addr;
+			/* Misdocumented as number of pages! */
+			u16 num_bytes;
+			u16 start;
+			u16 end;
+		} __packed v2;
+	};
+} __packed;
+
+static char *memconsole_baseaddr;
+static size_t memconsole_length;
+
+static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
+			       struct bin_attribute *bin_attr, char *buf,
+			       loff_t pos, size_t count)
+{
+	return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr,
+				       memconsole_length);
+}
+
+static struct bin_attribute memconsole_bin_attr = {
+	.attr = {.name = "log", .mode = 0444},
+	.read = memconsole_read,
+};
+
+
+static void found_v1_header(struct biosmemcon_ebda *hdr)
+{
+	printk(KERN_INFO "BIOS console v1 EBDA structure found at %p\n", hdr);
+	printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
+	       "start = %d, end = %d, num = %d\n",
+	       hdr->v1.buffer_addr, hdr->v1.start,
+	       hdr->v1.end, hdr->v1.num_chars);
+
+	memconsole_length = hdr->v1.num_chars;
+	memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr);
+}
+
+static void found_v2_header(struct biosmemcon_ebda *hdr)
+{
+	printk(KERN_INFO "BIOS console v2 EBDA structure found at %p\n", hdr);
+	printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
+	       "start = %d, end = %d, num_bytes = %d\n",
+	       hdr->v2.buffer_addr, hdr->v2.start,
+	       hdr->v2.end, hdr->v2.num_bytes);
+
+	memconsole_length = hdr->v2.end - hdr->v2.start;
+	memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr
+					   + hdr->v2.start);
+}
+
+/*
+ * Search through the EBDA for the BIOS Memory Console, and
+ * set the global variables to point to it.  Return true if found.
+ */
+static bool found_memconsole(void)
+{
+	unsigned int address;
+	size_t length, cur;
+
+	address = get_bios_ebda();
+	if (!address) {
+		printk(KERN_INFO "BIOS EBDA non-existent.\n");
+		return false;
+	}
+
+	/* EBDA length is byte 0 of EBDA (in KB) */
+	length = *(u8 *)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++) {
+		struct biosmemcon_ebda *hdr = phys_to_virt(address + cur);
+
+		/* memconsole v1 */
+		if (hdr->signature == BIOS_MEMCONSOLE_V1_MAGIC) {
+			found_v1_header(hdr);
+			return true;
+		}
+
+		/* memconsole v2 */
+		if (hdr->signature == BIOS_MEMCONSOLE_V2_MAGIC) {
+			found_v2_header(hdr);
+			return true;
+		}
+	}
+
+	printk(KERN_INFO "BIOS console EBDA structure not found!\n");
+	return false;
+}
+
+static int __init memconsole_init(void)
+{
+	int ret;
+
+	if (!found_memconsole())
+		return -ENODEV;
+
+	memconsole_bin_attr.size = memconsole_length;
+
+	ret = sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr);
+
+	return ret;
+}
+
+static void __exit memconsole_exit(void)
+{
+	sysfs_remove_bin_file(firmware_kobj, &memconsole_bin_attr);
+}
+
+module_init(memconsole_init);
+module_exit(memconsole_exit);
+
+MODULE_AUTHOR("Google, Inc.");
+MODULE_LICENSE("GPL");


  parent reply	other threads:[~2011-03-12  1:44 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-12  1:42 [PATCH v2 00/12] google firmware support Mike Waychison
2011-03-12  1:43 ` [PATCH v2 01/12] efivars: move efivars globals into struct efivars Mike Waychison
2011-03-12  1:43 ` [PATCH v2 02/12] efivars: Make efivars bin_attributes dynamic Mike Waychison
2011-03-12  1:43 ` [PATCH v2 03/12] efivars: parameterize efivars Mike Waychison
2011-03-12  1:43 ` [PATCH v2 04/12] efivars: Split out variable registration Mike Waychison
2011-03-12  1:43 ` [PATCH v2 05/12] efivars: Parameterize operations Mike Waychison
2011-03-12  1:43 ` [PATCH v2 06/12] efivars: Expose efivars functionality to external drivers Mike Waychison
2011-03-12  1:43 ` [PATCH v2 07/12] efivars: Add Documentation Mike Waychison
2011-03-12  1:43 ` [PATCH v2 08/12] x86: get_bios_ebda_length() Mike Waychison
2011-03-14 15:43   ` Greg KH
2011-03-12  1:43 ` [PATCH v2 09/12] x86: Better comments for get_bios_ebda() Mike Waychison
2011-03-14 15:43   ` Greg KH
2011-03-12  1:43 ` [PATCH v2 10/12] Introduce CONFIG_GOOGLE_FIRMWARE Mike Waychison
2011-03-14 15:45   ` Greg KH
2011-03-14 19:49     ` Mike Waychison
2011-03-14 19:59       ` Greg KH
2011-03-14 20:06         ` Mike Waychison
2011-03-12  1:43 ` [PATCH v2 11/12] driver: Google EFI SMI Mike Waychison
2011-03-14 15:47   ` Greg KH
2011-03-14 20:01     ` Mike Waychison
2011-03-14 20:13       ` Greg KH
2011-03-14 21:09         ` Mike Waychison
2011-03-14 23:05         ` Alan Cox
2011-03-12  1:43 ` Mike Waychison [this message]
2011-03-14  4:54   ` [PATCH v2 12/12] driver: Google Memory Console H. Peter Anvin
2011-03-14  4:58     ` Tim Hockin
2011-03-14  5:02       ` H. Peter Anvin
2011-03-14  9:22         ` Ingo Molnar
2011-03-14 14:01           ` Tim Hockin
2011-03-14 14:23             ` Ingo Molnar
2011-03-14 15:47               ` Greg KH
2011-03-14 20:03     ` Mike Waychison
2011-03-14 22:46       ` H. Peter Anvin
2011-03-12  3:54 ` [PATCH v2 00/12] google firmware support Matt Domsch
2011-03-14 15:42   ` 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=20110312014358.6133.34911.stgit@mike.mtv.corp.google.com \
    --to=mikew@google.com \
    --cc=Matt_Domsch@dell.com \
    --cc=adurbin@google.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=dlaurie@google.com \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=san@google.com \
    --cc=thockin@google.com \
    --cc=x86@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome