From: Greg Kroah-Hartman <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Cc: Mike Waychison <mikew@google.com>, San Mehat <san@google.com>,
Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 31/44] driver: Google Memory Console
Date: Thu, 19 May 2011 17:10:49 -0700 [thread overview]
Message-ID: <1305850262-9575-31-git-send-email-gregkh@suse.de> (raw)
In-Reply-To: <1305850262-9575-1-git-send-email-gregkh@suse.de>
From: Mike Waychison <mikew@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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
Documentation/ABI/testing/sysfs-firmware-log | 7 +
drivers/firmware/google/Kconfig | 8 ++
drivers/firmware/google/Makefile | 1 +
drivers/firmware/google/memconsole.c | 166 ++++++++++++++++++++++++++
4 files changed, 182 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 4a03835..640dc6b 100644
--- a/drivers/firmware/google/Kconfig
+++ b/drivers/firmware/google/Kconfig
@@ -7,3 +7,11 @@ config GOOGLE_SMI
platforms. This provides an interface for writing to and
clearing the EFI event log and reading and writing NVRAM
variables.
+
+config GOOGLE_MEMCONSOLE
+ tristate "Firmware Memory Console"
+ depends on DMI
+ help
+ This option enables the kernel to search for a firmware log in
+ the EBDA on Google servers. If found, this log is exported to
+ userland in the file /sys/firmware/log.
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..2a90ba6
--- /dev/null
+++ b/drivers/firmware/google/memconsole.c
@@ -0,0 +1,166 @@
+/*
+ * 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 <linux/dmi.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 struct dmi_system_id memconsole_dmi_table[] __initdata = {
+ {
+ .ident = "Google Board",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
+ },
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(dmi, memconsole_dmi_table);
+
+static int __init memconsole_init(void)
+{
+ int ret;
+
+ if (!dmi_check_system(memconsole_dmi_table))
+ return -ENODEV;
+
+ 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");
--
1.7.4.2
next prev parent reply other threads:[~2011-05-20 0:12 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-20 0:08 [GIT PATCH] driver core merge for .40 Greg KH
2011-05-20 0:10 ` [PATCH 01/44] device: add dev_WARN_ONCE Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 02/44] efivars: memory leak on error in create_efivars_bin_attributes() Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 03/44] efivars: handle errors from register_efivars() Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 04/44] firmware: Fix grammar in sysfs-firmware-dmi doc Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 05/44] drivers: make device_type const Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 06/44] kernel/ksysfs.c: expose file_caps_enabled in sysfs Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 07/44] HOWTO: sync up Documentaion/ja_JP/HOWTO Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 08/44] uio_netx: Add support for netPLC cards Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 09/44] uio: fix finding mm index for vma Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 10/44] uio: fix allocating minor id for uio device Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 11/44] uio: clean uioinfo when uninstall uio driver Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 12/44] printk: /dev/kmsg - properly support writev() to avoid interleaved printk() lines Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 13/44] kmsg: properly support writev to avoid interleaved printk lines fix Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 14/44] drivers:misc:ti-st: handle delayed tty receive Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 15/44] drivers:misc:ti-st: remove rfkill dependency Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 16/44] driver-core: fix race between device_register and driver_register Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 17/44] drivers/base/core.c: Fixed brace coding style issue Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 18/44] driver core/platform_device_add_data: set platform_data to NULL if !data Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 19/44] driver core/platform_device_add_data: free platform data before overwriting Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 20/44] driver core/platform_device_add_resources: set resource to NULL if !res Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 21/44] driver core/platform_device_add_resources: free resource before overwriting Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 22/44] driver core: let dev_set_drvdata return int instead of void as it can fail Greg Kroah-Hartman
2011-05-20 7:53 ` [22/44] " Milton Miller
2011-05-20 8:01 ` Uwe Kleine-König
2011-05-20 0:10 ` [PATCH 23/44] drivers:base:fix the coding format of memory.c Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 24/44] Add a strtobool function matching semantics of existing in kernel equivalents Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 25/44] debugfs: move to new strtobool Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 26/44] params.c: Use new strtobool function to process boolean inputs Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 27/44] misc: fix ti-st build issues Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 28/44] x86: get_bios_ebda_length() Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 29/44] x86: Better comments for get_bios_ebda() Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 30/44] driver: Google EFI SMI Greg Kroah-Hartman
2011-05-20 0:10 ` Greg Kroah-Hartman [this message]
2011-05-20 0:10 ` [PATCH 32/44] Introduce CONFIG_GOOGLE_FIRMWARE Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 33/44] Allow setting of number of raw devices as a module parameter Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 34/44] efivars: prevent oops on unload when efi is not enabled Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 35/44] reboot: disable usermodehelper to prevent fs access Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 36/44] RAW driver: Remove call to kobject_put() Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 37/44] Translated Documentation/email-clients.txt Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 38/44] driver core: Add the device driver-model structures to kerneldoc Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 39/44] driver core: remove the driver-model structures from the documentation Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 40/44] SYSFS: Fix erroneous comments for sysfs_update_group() Greg Kroah-Hartman
2011-05-20 0:10 ` [PATCH 41/44] memory hotplug: Speed up add/remove when blocks are larger than PAGES_PER_SECTION Greg Kroah-Hartman
2011-05-20 0:11 ` [PATCH 42/44] drivers/base/memory.c: fix warning due to "memory hotplug: Speed up add/remove when blocks are larger than PAGES_PER_SECTION" Greg Kroah-Hartman
2011-05-20 0:11 ` [PATCH 43/44] sysfs: remove "last sysfs file:" line from the oops messages Greg Kroah-Hartman
2011-05-20 0:11 ` [PATCH 44/44] debugfs: Silence DEBUG_STRICT_USER_COPY_CHECKS=y warning Greg Kroah-Hartman
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=1305850262-9575-31-git-send-email-gregkh@suse.de \
--to=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=mikew@google.com \
--cc=san@google.com \
/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