LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/5] coreboot table bus and framebuffer driver
@ 2018-01-25  1:41 Samuel Holland
  2018-01-25  1:41 ` [PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus Samuel Holland
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Samuel Holland @ 2018-01-25  1:41 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner,
	Dmitry Torokhov, Guenter Roeck, Samuel Holland

On many systems, coreboot[1] firmware can initialize graphics hardware
and set up a high-resolution linear framebuffer. It exports information
about this framebuffer, along with various other information, in a table
discoverable via ACPI or a device tree.

coreboot also supports booting Linux directly from flash as a "payload".
Projects such as Heads[2], u-root[3], and petitboot[4] provide a minimal
userland that can then be used to chainload (via kexec) into a full
Linux system loaded from disk or over the network.

Fitting even a minimal Linux system on an SPI flash chip is challenging.
Reusing the framebuffer setup from coreboot provides an enormous benefit
to these projects by allowing them to omit full graphics drivers from
their kernel builds. It also speeds up boot times by avoiding duplicated
effort, and because coreboot's graphics initialization is often much
faster than the Linux driver.

Patch 1 of this series expands coreboot table support into an enumerable
bus that devices can hang off of. Patches 2-3 convert the existing
drivers to use the new bus structure instead of ad-hoc platform devices,
and patch 4 removes the old coreboot_table_find function.

Finally, patch 5 adds a new driver for the coreboot-initialized
framebuffer. It improves on earlier work[5] by being architecture-
independent and not needing to scan through low memory.

This patchset has been tested on a Lenovo ThinkPad X220, and earlier
versions of these patches have been tested by various members of the
coreboot community on other hardware.

[1]: https://www.coreboot.org/Welcome_to_coreboot
[2]: https://github.com/osresearch/heads
[3]: https://github.com/u-root/u-root
[4]: https://www.kernel.org/pub/linux/kernel/people/geoff/petitboot/petitboot.html
[5]: https://mail.coreboot.org/pipermail/coreboot/2014-September/078551.html

Samuel Holland (5):
  firmware: coreboot: Expose the coreboot table as a bus
  firmware: memconsole: Probe via coreboot bus
  firmware: vpd: Probe via coreboot bus
  firmware: coreboot: Remove unused coreboot_table_find
  firmware: coreboot: Add coreboot framebuffer driver

 drivers/firmware/google/Kconfig                |   8 ++
 drivers/firmware/google/Makefile               |   1 +
 drivers/firmware/google/coreboot_table-acpi.c  |   2 +-
 drivers/firmware/google/coreboot_table-of.c    |   2 +-
 drivers/firmware/google/coreboot_table.c       | 130 ++++++++++++++++++-------
 drivers/firmware/google/coreboot_table.h       |  72 +++++++++++---
 drivers/firmware/google/framebuffer-coreboot.c | 115 ++++++++++++++++++++++
 drivers/firmware/google/memconsole-coreboot.c  |  49 ++++------
 drivers/firmware/google/vpd.c                  |  43 +++-----
 9 files changed, 313 insertions(+), 109 deletions(-)
 create mode 100644 drivers/firmware/google/framebuffer-coreboot.c

-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus
  2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
@ 2018-01-25  1:41 ` Samuel Holland
  2018-01-25  1:41 ` [PATCH 2/5] firmware: memconsole: Probe via coreboot bus Samuel Holland
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Samuel Holland @ 2018-01-25  1:41 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner,
	Dmitry Torokhov, Guenter Roeck, Samuel Holland

This simplifies creating device drivers for hardware or information
described in the coreboot table. It also avoids needing to search
through the table every time a driver is loaded.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/firmware/google/coreboot_table-acpi.c |   2 +-
 drivers/firmware/google/coreboot_table-of.c   |   2 +-
 drivers/firmware/google/coreboot_table.c      | 121 ++++++++++++++++++++++++--
 drivers/firmware/google/coreboot_table.h      |  49 +++++++++--
 4 files changed, 156 insertions(+), 18 deletions(-)

diff --git a/drivers/firmware/google/coreboot_table-acpi.c b/drivers/firmware/google/coreboot_table-acpi.c
index fb98db2d20e2..77197fe3d42f 100644
--- a/drivers/firmware/google/coreboot_table-acpi.c
+++ b/drivers/firmware/google/coreboot_table-acpi.c
@@ -53,7 +53,7 @@ static int coreboot_table_acpi_probe(struct platform_device *pdev)
 	if (!ptr)
 		return -ENOMEM;
 
-	return coreboot_table_init(ptr);
+	return coreboot_table_init(&pdev->dev, ptr);
 }
 
 static int coreboot_table_acpi_remove(struct platform_device *pdev)
diff --git a/drivers/firmware/google/coreboot_table-of.c b/drivers/firmware/google/coreboot_table-of.c
index 727acdc83e83..f15bf404c579 100644
--- a/drivers/firmware/google/coreboot_table-of.c
+++ b/drivers/firmware/google/coreboot_table-of.c
@@ -34,7 +34,7 @@ static int coreboot_table_of_probe(struct platform_device *pdev)
 	if (!ptr)
 		return -ENOMEM;
 
-	return coreboot_table_init(ptr);
+	return coreboot_table_init(&pdev->dev, ptr);
 }
 
 static int coreboot_table_of_remove(struct platform_device *pdev)
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index 0019d3ec18dd..04fc08e81744 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -4,6 +4,7 @@
  * Module providing coreboot table access.
  *
  * Copyright 2017 Google Inc.
+ * Copyright 2017 Samuel Holland <samuel@sholland.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2.0 as published by
@@ -15,21 +16,87 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/device.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "coreboot_table.h"
 
-struct coreboot_table_entry {
-	u32 tag;
-	u32 size;
-};
+#define CB_DEV(d) container_of(d, struct coreboot_device, dev)
+#define CB_DRV(d) container_of(d, struct coreboot_driver, drv)
 
 static struct coreboot_table_header __iomem *ptr_header;
 
+static int coreboot_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct coreboot_device *device = CB_DEV(dev);
+	struct coreboot_driver *driver = CB_DRV(drv);
+
+	return device->entry.tag == driver->tag;
+}
+
+static int coreboot_bus_probe(struct device *dev)
+{
+	int ret = -ENODEV;
+	struct coreboot_device *device = CB_DEV(dev);
+	struct coreboot_driver *driver = CB_DRV(dev->driver);
+
+	if (driver->probe)
+		ret = driver->probe(device);
+
+	return ret;
+}
+
+static int coreboot_bus_remove(struct device *dev)
+{
+	int ret = 0;
+	struct coreboot_device *device = CB_DEV(dev);
+	struct coreboot_driver *driver = CB_DRV(dev->driver);
+
+	if (driver->remove)
+		ret = driver->remove(device);
+
+	return ret;
+}
+
+static struct bus_type coreboot_bus_type = {
+	.name		= "coreboot",
+	.match		= coreboot_bus_match,
+	.probe		= coreboot_bus_probe,
+	.remove		= coreboot_bus_remove,
+};
+
+static int __init coreboot_bus_init(void)
+{
+	return bus_register(&coreboot_bus_type);
+}
+module_init(coreboot_bus_init);
+
+static void coreboot_device_release(struct device *dev)
+{
+	struct coreboot_device *device = CB_DEV(dev);
+
+	kfree(device);
+}
+
+int coreboot_driver_register(struct coreboot_driver *driver)
+{
+	driver->drv.bus = &coreboot_bus_type;
+
+	return driver_register(&driver->drv);
+}
+EXPORT_SYMBOL(coreboot_driver_register);
+
+void coreboot_driver_unregister(struct coreboot_driver *driver)
+{
+	driver_unregister(&driver->drv);
+}
+EXPORT_SYMBOL(coreboot_driver_unregister);
+
 /*
  * This function parses the coreboot table for an entry that contains the base
  * address of the given entry tag. The coreboot table consists of a header
@@ -73,18 +140,58 @@ int coreboot_table_find(int tag, void *data, size_t data_size)
 }
 EXPORT_SYMBOL(coreboot_table_find);
 
-int coreboot_table_init(void __iomem *ptr)
+int coreboot_table_init(struct device *dev, void __iomem *ptr)
 {
+	int i, ret;
+	void *ptr_entry;
+	struct coreboot_device *device;
+	struct coreboot_table_entry entry;
+	struct coreboot_table_header header;
+
 	ptr_header = ptr;
+	memcpy_fromio(&header, ptr_header, sizeof(header));
 
-	return 0;
+	if (strncmp(header.signature, "LBIO", sizeof(header.signature))) {
+		pr_warn("coreboot_table: coreboot table missing or corrupt!\n");
+		return -ENODEV;
+	}
+
+	ptr_entry = (void *)ptr_header + header.header_bytes;
+	for (i = 0; i < header.table_entries; i++) {
+		memcpy_fromio(&entry, ptr_entry, sizeof(entry));
+
+		device = kzalloc(sizeof(struct device) + entry.size, GFP_KERNEL);
+		if (!device) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		dev_set_name(&device->dev, "coreboot%d", i);
+		device->dev.parent = dev;
+		device->dev.bus = &coreboot_bus_type;
+		device->dev.release = coreboot_device_release;
+		memcpy_fromio(&device->entry, ptr_entry, entry.size);
+
+		ret = device_register(&device->dev);
+		if (ret) {
+			put_device(&device->dev);
+			break;
+		}
+
+		ptr_entry += entry.size;
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL(coreboot_table_init);
 
 int coreboot_table_exit(void)
 {
-	if (ptr_header)
+	if (ptr_header) {
+		bus_unregister(&coreboot_bus_type);
 		iounmap(ptr_header);
+		ptr_header = NULL;
+	}
 
 	return 0;
 }
diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
index 6eff1ae0c5d3..88e6a1c06028 100644
--- a/drivers/firmware/google/coreboot_table.h
+++ b/drivers/firmware/google/coreboot_table.h
@@ -4,6 +4,7 @@
  * Internal header for coreboot table access.
  *
  * Copyright 2017 Google Inc.
+ * Copyright 2017 Samuel Holland <samuel@sholland.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2.0 as published by
@@ -20,14 +21,6 @@
 
 #include <linux/io.h>
 
-/* List of coreboot entry structures that is used */
-struct lb_cbmem_ref {
-	uint32_t tag;
-	uint32_t size;
-
-	uint64_t cbmem_addr;
-};
-
 /* Coreboot table header structure */
 struct coreboot_table_header {
 	char signature[4];
@@ -38,11 +31,49 @@ struct coreboot_table_header {
 	u32 table_entries;
 };
 
+/* List of coreboot entry structures that is used */
+/* Generic */
+struct coreboot_table_entry {
+	u32 tag;
+	u32 size;
+};
+
+/* Points to a CBMEM entry */
+struct lb_cbmem_ref {
+	u32 tag;
+	u32 size;
+
+	u64 cbmem_addr;
+};
+
+/* A device, additionally with information from coreboot. */
+struct coreboot_device {
+	struct device dev;
+	union {
+		struct coreboot_table_entry entry;
+		struct lb_cbmem_ref cbmem_ref;
+	};
+};
+
+/* A driver for handling devices described in coreboot tables. */
+struct coreboot_driver {
+	int (*probe)(struct coreboot_device *);
+	int (*remove)(struct coreboot_device *);
+	struct device_driver drv;
+	u32 tag;
+};
+
+/* Register a driver that uses the data from a coreboot table. */
+int coreboot_driver_register(struct coreboot_driver *driver);
+
+/* Unregister a driver that uses the data from a coreboot table. */
+void coreboot_driver_unregister(struct coreboot_driver *driver);
+
 /* Retrieve coreboot table entry with tag *tag* and copy it to data */
 int coreboot_table_find(int tag, void *data, size_t data_size);
 
 /* Initialize coreboot table module given a pointer to iomem */
-int coreboot_table_init(void __iomem *ptr);
+int coreboot_table_init(struct device *dev, void __iomem *ptr);
 
 /* Cleanup coreboot table module */
 int coreboot_table_exit(void);
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/5] firmware: memconsole: Probe via coreboot bus
  2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
  2018-01-25  1:41 ` [PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus Samuel Holland
@ 2018-01-25  1:41 ` Samuel Holland
  2018-01-25  1:41 ` [PATCH 3/5] firmware: vpd: " Samuel Holland
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Samuel Holland @ 2018-01-25  1:41 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner,
	Dmitry Torokhov, Guenter Roeck, Samuel Holland

Remove the ad-hoc coreboot table search. Now the driver will only be
probed when the necessary coreboot table entry has already been found.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/firmware/google/memconsole-coreboot.c | 49 ++++++++++-----------------
 1 file changed, 17 insertions(+), 32 deletions(-)

diff --git a/drivers/firmware/google/memconsole-coreboot.c b/drivers/firmware/google/memconsole-coreboot.c
index 52738887735c..b29e10757bfb 100644
--- a/drivers/firmware/google/memconsole-coreboot.c
+++ b/drivers/firmware/google/memconsole-coreboot.c
@@ -15,9 +15,9 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
 
 #include "memconsole.h"
 #include "coreboot_table.h"
@@ -73,18 +73,19 @@ static ssize_t memconsole_coreboot_read(char *buf, loff_t pos, size_t count)
 	return done;
 }
 
-static int memconsole_coreboot_init(phys_addr_t physaddr)
+static int memconsole_probe(struct coreboot_device *dev)
 {
 	struct cbmem_cons __iomem *tmp_cbmc;
 
-	tmp_cbmc = memremap(physaddr, sizeof(*tmp_cbmc), MEMREMAP_WB);
+	tmp_cbmc = memremap(dev->cbmem_ref.cbmem_addr,
+			    sizeof(*tmp_cbmc), MEMREMAP_WB);
 
 	if (!tmp_cbmc)
 		return -ENOMEM;
 
 	/* Read size only once to prevent overrun attack through /dev/mem. */
 	cbmem_console_size = tmp_cbmc->size_dont_access_after_boot;
-	cbmem_console = memremap(physaddr,
+	cbmem_console = memremap(dev->cbmem_ref.cbmem_addr,
 				 cbmem_console_size + sizeof(*cbmem_console),
 				 MEMREMAP_WB);
 	memunmap(tmp_cbmc);
@@ -93,26 +94,11 @@ static int memconsole_coreboot_init(phys_addr_t physaddr)
 		return -ENOMEM;
 
 	memconsole_setup(memconsole_coreboot_read);
-	return 0;
-}
-
-static int memconsole_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct lb_cbmem_ref entry;
-
-	ret = coreboot_table_find(CB_TAG_CBMEM_CONSOLE, &entry, sizeof(entry));
-	if (ret)
-		return ret;
-
-	ret = memconsole_coreboot_init(entry.cbmem_addr);
-	if (ret)
-		return ret;
 
 	return memconsole_sysfs_init();
 }
 
-static int memconsole_remove(struct platform_device *pdev)
+static int memconsole_remove(struct coreboot_device *dev)
 {
 	memconsole_exit();
 
@@ -122,28 +108,27 @@ static int memconsole_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver memconsole_driver = {
+static struct coreboot_driver memconsole_driver = {
 	.probe = memconsole_probe,
 	.remove = memconsole_remove,
-	.driver = {
+	.drv = {
 		.name = "memconsole",
 	},
+	.tag = CB_TAG_CBMEM_CONSOLE,
 };
 
-static int __init platform_memconsole_init(void)
+static void coreboot_memconsole_exit(void)
 {
-	struct platform_device *pdev;
-
-	pdev = platform_device_register_simple("memconsole", -1, NULL, 0);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	platform_driver_register(&memconsole_driver);
+	coreboot_driver_unregister(&memconsole_driver);
+}
 
-	return 0;
+static int __init coreboot_memconsole_init(void)
+{
+	return coreboot_driver_register(&memconsole_driver);
 }
 
-module_init(platform_memconsole_init);
+module_exit(coreboot_memconsole_exit);
+module_init(coreboot_memconsole_init);
 
 MODULE_AUTHOR("Google, Inc.");
 MODULE_LICENSE("GPL");
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/5] firmware: vpd: Probe via coreboot bus
  2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
  2018-01-25  1:41 ` [PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus Samuel Holland
  2018-01-25  1:41 ` [PATCH 2/5] firmware: memconsole: Probe via coreboot bus Samuel Holland
@ 2018-01-25  1:41 ` Samuel Holland
  2018-01-25  1:41 ` [PATCH 4/5] firmware: coreboot: Remove unused coreboot_table_find Samuel Holland
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Samuel Holland @ 2018-01-25  1:41 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner,
	Dmitry Torokhov, Guenter Roeck, Samuel Holland

Remove the ad-hoc coreboot table search. Now the driver will only be
probed when the necessary coreboot table entry has already been found.
Furthermore, since the coreboot bus takes care of creating the device, a
separate platform device is no longer needed.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/firmware/google/vpd.c | 43 ++++++++++++-------------------------------
 1 file changed, 12 insertions(+), 31 deletions(-)

diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c
index e4b40f2b4627..e9db895916c3 100644
--- a/drivers/firmware/google/vpd.c
+++ b/drivers/firmware/google/vpd.c
@@ -286,20 +286,15 @@ static int vpd_sections_init(phys_addr_t physaddr)
 	return 0;
 }
 
-static int vpd_probe(struct platform_device *pdev)
+static int vpd_probe(struct coreboot_device *dev)
 {
 	int ret;
-	struct lb_cbmem_ref entry;
-
-	ret = coreboot_table_find(CB_TAG_VPD, &entry, sizeof(entry));
-	if (ret)
-		return ret;
 
 	vpd_kobj = kobject_create_and_add("vpd", firmware_kobj);
 	if (!vpd_kobj)
 		return -ENOMEM;
 
-	ret = vpd_sections_init(entry.cbmem_addr);
+	ret = vpd_sections_init(dev->cbmem_ref.cbmem_addr);
 	if (ret) {
 		kobject_put(vpd_kobj);
 		return ret;
@@ -308,7 +303,7 @@ static int vpd_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int vpd_remove(struct platform_device *pdev)
+static int vpd_remove(struct coreboot_device *dev)
 {
 	vpd_section_destroy(&ro_vpd);
 	vpd_section_destroy(&rw_vpd);
@@ -318,41 +313,27 @@ static int vpd_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver vpd_driver = {
+static struct coreboot_driver vpd_driver = {
 	.probe = vpd_probe,
 	.remove = vpd_remove,
-	.driver = {
+	.drv = {
 		.name = "vpd",
 	},
+	.tag = CB_TAG_VPD,
 };
 
-static struct platform_device *vpd_pdev;
-
-static int __init vpd_platform_init(void)
+static int __init coreboot_vpd_init(void)
 {
-	int ret;
-
-	ret = platform_driver_register(&vpd_driver);
-	if (ret)
-		return ret;
-
-	vpd_pdev = platform_device_register_simple("vpd", -1, NULL, 0);
-	if (IS_ERR(vpd_pdev)) {
-		platform_driver_unregister(&vpd_driver);
-		return PTR_ERR(vpd_pdev);
-	}
-
-	return 0;
+	return coreboot_driver_register(&vpd_driver);
 }
 
-static void __exit vpd_platform_exit(void)
+static void __exit coreboot_vpd_exit(void)
 {
-	platform_device_unregister(vpd_pdev);
-	platform_driver_unregister(&vpd_driver);
+	coreboot_driver_unregister(&vpd_driver);
 }
 
-module_init(vpd_platform_init);
-module_exit(vpd_platform_exit);
+module_init(coreboot_vpd_init);
+module_exit(coreboot_vpd_exit);
 
 MODULE_AUTHOR("Google, Inc.");
 MODULE_LICENSE("GPL");
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 4/5] firmware: coreboot: Remove unused coreboot_table_find
  2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
                   ` (2 preceding siblings ...)
  2018-01-25  1:41 ` [PATCH 3/5] firmware: vpd: " Samuel Holland
@ 2018-01-25  1:41 ` Samuel Holland
  2018-01-25  1:41 ` [PATCH 5/5] firmware: coreboot: Add coreboot framebuffer driver Samuel Holland
  2018-03-14 18:08 ` [PATCH 0/5] coreboot table bus and " Greg Kroah-Hartman
  5 siblings, 0 replies; 10+ messages in thread
From: Samuel Holland @ 2018-01-25  1:41 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner,
	Dmitry Torokhov, Guenter Roeck, Samuel Holland

Now that all users of the coreboot_table_find function have been updated
to hang off the coreboot table bus instead, remove it.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/firmware/google/coreboot_table.c | 43 --------------------------------
 drivers/firmware/google/coreboot_table.h |  3 ---
 2 files changed, 46 deletions(-)

diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index 04fc08e81744..19db5709ae28 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -97,49 +97,6 @@ void coreboot_driver_unregister(struct coreboot_driver *driver)
 }
 EXPORT_SYMBOL(coreboot_driver_unregister);
 
-/*
- * This function parses the coreboot table for an entry that contains the base
- * address of the given entry tag. The coreboot table consists of a header
- * directly followed by a number of small, variable-sized entries, which each
- * contain an identifying tag and their length as the first two fields.
- */
-int coreboot_table_find(int tag, void *data, size_t data_size)
-{
-	struct coreboot_table_header header;
-	struct coreboot_table_entry entry;
-	void *ptr_entry;
-	int i;
-
-	if (!ptr_header)
-		return -EPROBE_DEFER;
-
-	memcpy_fromio(&header, ptr_header, sizeof(header));
-
-	if (strncmp(header.signature, "LBIO", sizeof(header.signature))) {
-		pr_warn("coreboot_table: coreboot table missing or corrupt!\n");
-		return -ENODEV;
-	}
-
-	ptr_entry = (void *)ptr_header + header.header_bytes;
-
-	for (i = 0; i < header.table_entries; i++) {
-		memcpy_fromio(&entry, ptr_entry, sizeof(entry));
-		if (entry.tag == tag) {
-			if (data_size < entry.size)
-				return -EINVAL;
-
-			memcpy_fromio(data, ptr_entry, entry.size);
-
-			return 0;
-		}
-
-		ptr_entry += entry.size;
-	}
-
-	return -ENOENT;
-}
-EXPORT_SYMBOL(coreboot_table_find);
-
 int coreboot_table_init(struct device *dev, void __iomem *ptr)
 {
 	int i, ret;
diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
index 88e6a1c06028..26a3f3f3ac9c 100644
--- a/drivers/firmware/google/coreboot_table.h
+++ b/drivers/firmware/google/coreboot_table.h
@@ -69,9 +69,6 @@ int coreboot_driver_register(struct coreboot_driver *driver);
 /* Unregister a driver that uses the data from a coreboot table. */
 void coreboot_driver_unregister(struct coreboot_driver *driver);
 
-/* Retrieve coreboot table entry with tag *tag* and copy it to data */
-int coreboot_table_find(int tag, void *data, size_t data_size);
-
 /* Initialize coreboot table module given a pointer to iomem */
 int coreboot_table_init(struct device *dev, void __iomem *ptr);
 
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 5/5] firmware: coreboot: Add coreboot framebuffer driver
  2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
                   ` (3 preceding siblings ...)
  2018-01-25  1:41 ` [PATCH 4/5] firmware: coreboot: Remove unused coreboot_table_find Samuel Holland
@ 2018-01-25  1:41 ` Samuel Holland
  2018-03-14 18:08 ` [PATCH 0/5] coreboot table bus and " Greg Kroah-Hartman
  5 siblings, 0 replies; 10+ messages in thread
From: Samuel Holland @ 2018-01-25  1:41 UTC (permalink / raw)
  To: linux-kernel, Greg Kroah-Hartman
  Cc: coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner,
	Dmitry Torokhov, Guenter Roeck, Samuel Holland

Register a simplefb framebuffer when the coreboot table contains a
framebuffer entry.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 drivers/firmware/google/Kconfig                |   8 ++
 drivers/firmware/google/Makefile               |   1 +
 drivers/firmware/google/coreboot_table.h       |  22 +++++
 drivers/firmware/google/framebuffer-coreboot.c | 115 +++++++++++++++++++++++++
 4 files changed, 146 insertions(+)
 create mode 100644 drivers/firmware/google/framebuffer-coreboot.c

diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
index f16b381a569c..a456a000048b 100644
--- a/drivers/firmware/google/Kconfig
+++ b/drivers/firmware/google/Kconfig
@@ -55,6 +55,14 @@ config GOOGLE_MEMCONSOLE_X86_LEGACY
 	  the EBDA on Google servers.  If found, this log is exported to
 	  userland in the file /sys/firmware/log.
 
+config GOOGLE_FRAMEBUFFER_COREBOOT
+	tristate "Coreboot Framebuffer"
+	depends on FB_SIMPLE
+	depends on GOOGLE_COREBOOT_TABLE
+	help
+	  This option enables the kernel to search for a framebuffer in
+	  the coreboot table.  If found, it is registered with simplefb.
+
 config GOOGLE_MEMCONSOLE_COREBOOT
 	tristate "Firmware Memory Console"
 	depends on GOOGLE_COREBOOT_TABLE
diff --git a/drivers/firmware/google/Makefile b/drivers/firmware/google/Makefile
index dcd3675efcfc..d0b3fba96194 100644
--- a/drivers/firmware/google/Makefile
+++ b/drivers/firmware/google/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_GOOGLE_SMI)		+= gsmi.o
 obj-$(CONFIG_GOOGLE_COREBOOT_TABLE)        += coreboot_table.o
 obj-$(CONFIG_GOOGLE_COREBOOT_TABLE_ACPI)   += coreboot_table-acpi.o
 obj-$(CONFIG_GOOGLE_COREBOOT_TABLE_OF)     += coreboot_table-of.o
+obj-$(CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT)  += framebuffer-coreboot.o
 obj-$(CONFIG_GOOGLE_MEMCONSOLE)            += memconsole.o
 obj-$(CONFIG_GOOGLE_MEMCONSOLE_COREBOOT)   += memconsole-coreboot.o
 obj-$(CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY) += memconsole-x86-legacy.o
diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
index 26a3f3f3ac9c..8ad95a94481b 100644
--- a/drivers/firmware/google/coreboot_table.h
+++ b/drivers/firmware/google/coreboot_table.h
@@ -3,6 +3,7 @@
  *
  * Internal header for coreboot table access.
  *
+ * Copyright 2014 Gerd Hoffmann <kraxel@redhat.com>
  * Copyright 2017 Google Inc.
  * Copyright 2017 Samuel Holland <samuel@sholland.org>
  *
@@ -46,12 +47,33 @@ struct lb_cbmem_ref {
 	u64 cbmem_addr;
 };
 
+/* Describes framebuffer setup by coreboot */
+struct lb_framebuffer {
+	u32 tag;
+	u32 size;
+
+	u64 physical_address;
+	u32 x_resolution;
+	u32 y_resolution;
+	u32 bytes_per_line;
+	u8  bits_per_pixel;
+	u8  red_mask_pos;
+	u8  red_mask_size;
+	u8  green_mask_pos;
+	u8  green_mask_size;
+	u8  blue_mask_pos;
+	u8  blue_mask_size;
+	u8  reserved_mask_pos;
+	u8  reserved_mask_size;
+};
+
 /* A device, additionally with information from coreboot. */
 struct coreboot_device {
 	struct device dev;
 	union {
 		struct coreboot_table_entry entry;
 		struct lb_cbmem_ref cbmem_ref;
+		struct lb_framebuffer framebuffer;
 	};
 };
 
diff --git a/drivers/firmware/google/framebuffer-coreboot.c b/drivers/firmware/google/framebuffer-coreboot.c
new file mode 100644
index 000000000000..b8b49c067157
--- /dev/null
+++ b/drivers/firmware/google/framebuffer-coreboot.c
@@ -0,0 +1,115 @@
+/*
+ * framebuffer-coreboot.c
+ *
+ * Memory based framebuffer accessed through coreboot table.
+ *
+ * Copyright 2012-2013 David Herrmann <dh.herrmann@gmail.com>
+ * Copyright 2017 Google Inc.
+ * Copyright 2017 Samuel Holland <samuel@sholland.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_data/simplefb.h>
+#include <linux/platform_device.h>
+
+#include "coreboot_table.h"
+
+#define CB_TAG_FRAMEBUFFER 0x12
+
+static const struct simplefb_format formats[] = SIMPLEFB_FORMATS;
+
+static int framebuffer_probe(struct coreboot_device *dev)
+{
+	int i;
+	u32 length;
+	struct lb_framebuffer *fb = &dev->framebuffer;
+	struct platform_device *pdev;
+	struct resource res;
+	struct simplefb_platform_data pdata = {
+		.width = fb->x_resolution,
+		.height = fb->y_resolution,
+		.stride = fb->bytes_per_line,
+		.format = NULL,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+		if (fb->bits_per_pixel     == formats[i].bits_per_pixel &&
+		    fb->red_mask_pos       == formats[i].red.offset &&
+		    fb->red_mask_size      == formats[i].red.length &&
+		    fb->green_mask_pos     == formats[i].green.offset &&
+		    fb->green_mask_size    == formats[i].green.length &&
+		    fb->blue_mask_pos      == formats[i].blue.offset &&
+		    fb->blue_mask_size     == formats[i].blue.length &&
+		    fb->reserved_mask_pos  == formats[i].transp.offset &&
+		    fb->reserved_mask_size == formats[i].transp.length)
+			pdata.format = formats[i].name;
+	}
+	if (!pdata.format)
+		return -ENODEV;
+
+	memset(&res, 0, sizeof(res));
+	res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	res.name = "Coreboot Framebuffer";
+	res.start = fb->physical_address;
+	length = PAGE_ALIGN(fb->y_resolution * fb->bytes_per_line);
+	res.end = res.start + length - 1;
+	if (res.end <= res.start)
+		return -EINVAL;
+
+	pdev = platform_device_register_resndata(&dev->dev,
+						 "simple-framebuffer", 0,
+						 &res, 1, &pdata,
+						 sizeof(pdata));
+	if (IS_ERR(pdev))
+		pr_warn("coreboot: could not register framebuffer\n");
+	else
+		dev_set_drvdata(&dev->dev, pdev);
+
+	return PTR_ERR_OR_ZERO(pdev);
+}
+
+static int framebuffer_remove(struct coreboot_device *dev)
+{
+	struct platform_device *pdev = dev_get_drvdata(&dev->dev);
+
+	platform_device_unregister(pdev);
+
+	return 0;
+}
+
+static struct coreboot_driver framebuffer_driver = {
+	.probe = framebuffer_probe,
+	.remove = framebuffer_remove,
+	.drv = {
+		.name = "framebuffer",
+	},
+	.tag = CB_TAG_FRAMEBUFFER,
+};
+
+static int __init coreboot_framebuffer_init(void)
+{
+	return coreboot_driver_register(&framebuffer_driver);
+}
+
+static void coreboot_framebuffer_exit(void)
+{
+	coreboot_driver_unregister(&framebuffer_driver);
+}
+
+module_init(coreboot_framebuffer_init);
+module_exit(coreboot_framebuffer_exit);
+
+MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
+MODULE_LICENSE("GPL");
-- 
2.13.6

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/5] coreboot table bus and framebuffer driver
  2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
                   ` (4 preceding siblings ...)
  2018-01-25  1:41 ` [PATCH 5/5] firmware: coreboot: Add coreboot framebuffer driver Samuel Holland
@ 2018-03-14 18:08 ` Greg Kroah-Hartman
  2018-03-14 21:18   ` Julius Werner
  5 siblings, 1 reply; 10+ messages in thread
From: Greg Kroah-Hartman @ 2018-03-14 18:08 UTC (permalink / raw)
  To: Samuel Holland
  Cc: linux-kernel, coreboot, Thierry Escande, Wei-Ning Huang,
	Julius Werner, Dmitry Torokhov, Guenter Roeck

On Wed, Jan 24, 2018 at 07:41:15PM -0600, Samuel Holland wrote:
> On many systems, coreboot[1] firmware can initialize graphics hardware
> and set up a high-resolution linear framebuffer. It exports information
> about this framebuffer, along with various other information, in a table
> discoverable via ACPI or a device tree.
> 
> coreboot also supports booting Linux directly from flash as a "payload".
> Projects such as Heads[2], u-root[3], and petitboot[4] provide a minimal
> userland that can then be used to chainload (via kexec) into a full
> Linux system loaded from disk or over the network.
> 
> Fitting even a minimal Linux system on an SPI flash chip is challenging.
> Reusing the framebuffer setup from coreboot provides an enormous benefit
> to these projects by allowing them to omit full graphics drivers from
> their kernel builds. It also speeds up boot times by avoiding duplicated
> effort, and because coreboot's graphics initialization is often much
> faster than the Linux driver.
> 
> Patch 1 of this series expands coreboot table support into an enumerable
> bus that devices can hang off of. Patches 2-3 convert the existing
> drivers to use the new bus structure instead of ad-hoc platform devices,
> and patch 4 removes the old coreboot_table_find function.
> 
> Finally, patch 5 adds a new driver for the coreboot-initialized
> framebuffer. It improves on earlier work[5] by being architecture-
> independent and not needing to scan through low memory.
> 
> This patchset has been tested on a Lenovo ThinkPad X220, and earlier
> versions of these patches have been tested by various members of the
> coreboot community on other hardware.

It would be great to get some of the google developers to ack these, as
this touches their code...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/5] coreboot table bus and framebuffer driver
  2018-03-14 18:08 ` [PATCH 0/5] coreboot table bus and " Greg Kroah-Hartman
@ 2018-03-14 21:18   ` Julius Werner
  2018-03-14 21:22     ` Julius Werner
  0 siblings, 1 reply; 10+ messages in thread
From: Julius Werner @ 2018-03-14 21:18 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Dmitry Torokhov, Guenter Roeck
  Cc: samuel, LKML, Coreboot, Thierry Escande, Wei-Ning Huang, Julius Werner

[-- Attachment #1: Type: text/plain, Size: 746 bytes --]

>
> It would be great to get some of the google developers to ack these, as
> this touches their code...


>From the coreboot point of view I guess we're fine with it since it claims
to maintain all of the existing functionality. It's just changing the
kernel-level plumbing for these drivers and I don't really have the
expertise to comment on whether this is better or worse than the old code
(maybe Dmitry or Guenter will?). It seems a little odd to me to call this a
"bus", but if we think that's the most fitting abstraction the kernel has
for it, I'm okay with that. All I care about is that it will work (in all
combinations... e.g. regardless of probe order and even if some parts are
compiled as modules and loaded/unloaded at runtime).

[-- Attachment #2: Type: text/html, Size: 965 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/5] coreboot table bus and framebuffer driver
  2018-03-14 21:18   ` Julius Werner
@ 2018-03-14 21:22     ` Julius Werner
  2018-04-23 11:37       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 10+ messages in thread
From: Julius Werner @ 2018-03-14 21:22 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Guenter Roeck, Dmitry Torokhov
  Cc: samuel, LKML, Coreboot, Julius Werner

[resend in plain text]

> It would be great to get some of the google developers to ack these, as
> this touches their code...

 From the coreboot point of view I guess we're fine with it since it claims
to maintain all of the existing functionality. It's just changing the
kernel-level plumbing for these drivers and I don't really have the
expertise to comment on whether this is better or worse than the old code
(maybe Dmitry or Guenter will?). It seems a little odd to me to call this a
"bus", but if we think that's the most fitting abstraction the kernel has
for it, I'm okay with that. All I care about is that it will work (in all
combinations... e.g. regardless of probe order and even if some parts are
compiled as modules and loaded/unloaded at runtime).

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/5] coreboot table bus and framebuffer driver
  2018-03-14 21:22     ` Julius Werner
@ 2018-04-23 11:37       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 10+ messages in thread
From: Greg Kroah-Hartman @ 2018-04-23 11:37 UTC (permalink / raw)
  To: Julius Werner; +Cc: Guenter Roeck, Dmitry Torokhov, samuel, LKML, Coreboot

On Wed, Mar 14, 2018 at 09:22:04PM +0000, Julius Werner wrote:
> [resend in plain text]
> 
> > It would be great to get some of the google developers to ack these, as
> > this touches their code...
> 
>  From the coreboot point of view I guess we're fine with it since it claims
> to maintain all of the existing functionality. It's just changing the
> kernel-level plumbing for these drivers and I don't really have the
> expertise to comment on whether this is better or worse than the old code
> (maybe Dmitry or Guenter will?). It seems a little odd to me to call this a
> "bus", but if we think that's the most fitting abstraction the kernel has
> for it, I'm okay with that. All I care about is that it will work (in all
> combinations... e.g. regardless of probe order and even if some parts are
> compiled as modules and loaded/unloaded at runtime).

Thanks for the response, patches are all now queued up.

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-04-23 11:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-25  1:41 [PATCH 0/5] coreboot table bus and framebuffer driver Samuel Holland
2018-01-25  1:41 ` [PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus Samuel Holland
2018-01-25  1:41 ` [PATCH 2/5] firmware: memconsole: Probe via coreboot bus Samuel Holland
2018-01-25  1:41 ` [PATCH 3/5] firmware: vpd: " Samuel Holland
2018-01-25  1:41 ` [PATCH 4/5] firmware: coreboot: Remove unused coreboot_table_find Samuel Holland
2018-01-25  1:41 ` [PATCH 5/5] firmware: coreboot: Add coreboot framebuffer driver Samuel Holland
2018-03-14 18:08 ` [PATCH 0/5] coreboot table bus and " Greg Kroah-Hartman
2018-03-14 21:18   ` Julius Werner
2018-03-14 21:22     ` Julius Werner
2018-04-23 11:37       ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).