All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <swboyd@chromium.org>
To: linux-kernel@vger.kernel.org, patrick.rudolph@9elements.com
Cc: Patrick Rudolph <patrick.rudolph@9elements.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Filipe Brandenburger <filbranden@chromium.org>,
	Duncan Laurie <dlaurie@chromium.org>,
	Aaron Durbin <adurbin@chromium.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Samuel Holland <samuel@sholland.org>,
	Julius Werner <jwerner@chromium.org>
Subject: Re: [PATCH 1/2] firmware: coreboot: Export the binary FMAP
Date: Tue, 08 Oct 2019 15:47:59 -0700	[thread overview]
Message-ID: <5d9d1220.1c69fb81.e1df.24e4@mx.google.com> (raw)
In-Reply-To: <20191008115342.28483-1-patrick.rudolph@9elements.com>

Quoting patrick.rudolph@9elements.com (2019-10-08 04:53:25)
> From: Patrick Rudolph <patrick.rudolph@9elements.com>
> 
> Expose coreboot's binary FMAP[1] to /sys/firmware/fmap.
> 
> coreboot copies the FMAP to a CBMEM buffer at boot since CB:35377[2],
> allowing an architecture independ way of exposing the FMAP to userspace.
> 
> Will be used by fwupd[3] to determine the current firmware layout.
> 
> [1]: https://doc.coreboot.org/lib/flashmap.html
> [2]: https://review.coreboot.org/c/coreboot/+/35377
> [3]: https://fwupd.org/
> 
> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
> ---
>  drivers/firmware/google/Kconfig           |   8 ++
>  drivers/firmware/google/Makefile          |   1 +
>  drivers/firmware/google/fmap-coreboot.c   | 156 ++++++++++++++++++++++
>  drivers/firmware/google/fmap-coreboot.h   |  13 ++
>  drivers/firmware/google/fmap_serialized.h |  59 ++++++++
>  5 files changed, 237 insertions(+)
>  create mode 100644 drivers/firmware/google/fmap-coreboot.c
>  create mode 100644 drivers/firmware/google/fmap-coreboot.h
>  create mode 100644 drivers/firmware/google/fmap_serialized.h
> 
> diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
> index a3a6ca659ffa..5fbbd7b8fef6 100644
> --- a/drivers/firmware/google/Kconfig
> +++ b/drivers/firmware/google/Kconfig
> @@ -74,4 +74,12 @@ config GOOGLE_VPD
>           This option enables the kernel to expose the content of Google VPD
>           under /sys/firmware/vpd.
>  
> +config GOOGLE_FMAP
> +       tristate "Coreboot FMAP access"
> +       depends on GOOGLE_COREBOOT_TABLE
> +       help
> +         This option enables the kernel to search for a Google FMAP in
> +         the coreboot table.  If found, this binary file is exported to userland
> +         in the file /sys/firmware/fmap.
> +
>  endif # GOOGLE_FIRMWARE
> diff --git a/drivers/firmware/google/Makefile b/drivers/firmware/google/Makefile
> index d17caded5d88..6d31fe167700 100644
> --- a/drivers/firmware/google/Makefile
> +++ b/drivers/firmware/google/Makefile
> @@ -6,6 +6,7 @@ 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
> +obj-$(CONFIG_GOOGLE_FMAP)                  += fmap-coreboot.o
>  
>  vpd-sysfs-y := vpd.o vpd_decode.o
>  obj-$(CONFIG_GOOGLE_VPD)               += vpd-sysfs.o
> diff --git a/drivers/firmware/google/fmap-coreboot.c b/drivers/firmware/google/fmap-coreboot.c
> new file mode 100644
> index 000000000000..14050030ebc6
> --- /dev/null
> +++ b/drivers/firmware/google/fmap-coreboot.c
> @@ -0,0 +1,156 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * fmap-coreboot.c
> + *
> + * Exports the binary FMAP through coreboot table.
> + *
> + * Copyright 2012-2013 David Herrmann <dh.herrmann@gmail.com>
> + * Copyright 2017 Google Inc.
> + * Copyright 2019 9elements Agency GmbH <patrick.rudolph@9elements.com>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/string.h>
> +#include <linux/io.h>
> +
> +#include "coreboot_table.h"
> +#include "fmap_serialized.h"
> +
> +#define CB_TAG_FMAP 0x37
> +
> +static void *fmap;
> +static u32 fmap_size;
> +
> +/*
> + * Convert FMAP region to name.
> + * The caller has to free the string.
> + * Return NULL if no containing region was found.
> + */
> +const char *coreboot_fmap_region_to_name(const u32 start, const u32 size)
> +{
> +       const char *name = NULL;
> +       struct fmap *iter;
> +       u32 size_old = ~0;
> +       int i;
> +
> +       iter = fmap;
> +       /* Find smallest containing region */
> +       for (i = 0; i < iter->nareas && fmap; i++) {
> +               if (iter->areas[i].offset <= start &&
> +                   iter->areas[i].size >= size &&
> +                   iter->areas[i].size <= size_old) {
> +                       size_old = iter->areas[i].size;
> +                       name = iter->areas[i].name;
> +               }
> +       }
> +
> +       if (name)
> +               return kstrdup(name, GFP_KERNEL);
> +       return NULL;
> +}
> +EXPORT_SYMBOL(coreboot_fmap_region_to_name);
> +
> +static ssize_t fmap_read(struct file *filp, struct kobject *kobp,
> +                        struct bin_attribute *bin_attr, char *buf,
> +                        loff_t pos, size_t count)
> +{
> +       if (!fmap)
> +               return -ENODEV;
> +
> +       return memory_read_from_buffer(buf, count, &pos, fmap, fmap_size);
> +}
> +
> +static int fmap_probe(struct coreboot_device *dev)
> +{
> +       struct lb_cbmem_ref *cbmem_ref = &dev->cbmem_ref;
> +       struct fmap *header;
> +
> +       if (!cbmem_ref)
> +               return -ENODEV;

This is impossible.

> +
> +       header = memremap(cbmem_ref->cbmem_addr, sizeof(*header), MEMREMAP_WB);
> +       if (!header) {
> +               pr_warn("coreboot: Failed to remap FMAP\n");
> +               return -ENOMEM;
> +       }
> +
> +       /* Validate FMAP signature */
> +       if (memcmp(header->signature, FMAP_SIGNATURE,
> +                  sizeof(header->signature))) {
> +               pr_warn("coreboot: FMAP signature mismatch\n");
> +               memunmap(header);
> +               return -ENODEV;
> +       }
> +
> +       /* Validate FMAP version */
> +       if (header->ver_major != FMAP_VER_MAJOR) {
> +               pr_warn("coreboot: FMAP version not supported\n");
> +               memunmap(header);
> +               return -ENODEV;
> +       }
> +
> +       pr_info("coreboot: Got valid FMAP v%u.%u for 0x%x byte ROM\n",
> +               header->ver_major, header->ver_minor, header->size);
> +
> +       fmap_size = sizeof(*header) + header->nareas * sizeof(struct fmap_area);
> +       memunmap(header);
> +
> +       fmap = devm_memremap(&dev->dev, cbmem_ref->cbmem_addr, fmap_size,
> +                            MEMREMAP_WB);
> +       if (!fmap) {
> +               pr_warn("coreboot: Failed to remap FMAP\n");
> +               return -ENOMEM;
> +       }
> +
> +       return 0;
> +}
> +
> +static int fmap_remove(struct coreboot_device *dev)
> +{
> +       struct platform_device *pdev = dev_get_drvdata(&dev->dev);
> +
> +       platform_device_unregister(pdev);
> +
> +       return 0;
> +}
> +
> +static struct coreboot_driver fmap_driver = {
> +       .probe = fmap_probe,
> +       .remove = fmap_remove,
> +       .drv = {
> +               .name = "fmap",
> +       },
> +       .tag = CB_TAG_FMAP,
> +};
> +
> +static struct bin_attribute fmap_bin_attr = {
> +       .attr = {.name = "fmap", .mode = 0444},
> +       .read = fmap_read,
> +};
> +
> +static int __init coreboot_fmap_init(void)
> +{
> +       int err;
> +
> +       err = sysfs_create_bin_file(firmware_kobj, &fmap_bin_attr);
> +       if (err)
> +               return err;
> +
> +       return coreboot_driver_register(&fmap_driver);
> +}
> +
> +static void coreboot_fmap_exit(void)
> +{
> +       coreboot_driver_unregister(&fmap_driver);
> +       sysfs_remove_bin_file(firmware_kobj, &fmap_bin_attr);
> +}
> +
> +module_init(coreboot_fmap_init);
> +module_exit(coreboot_fmap_exit);
> +
> +MODULE_AUTHOR("9elements Agency GmbH");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/firmware/google/fmap-coreboot.h b/drivers/firmware/google/fmap-coreboot.h
> new file mode 100644
> index 000000000000..7107a01af0e3
> --- /dev/null
> +++ b/drivers/firmware/google/fmap-coreboot.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * bootmedia-coreboot.h
> + *
> + * Copyright 2019 9elements Agency GmbH <patrick.rudolph@9elements.com>
> + */
> +
> +#ifndef __FMAP_COREBOOT_H
> +#define __FMAP_COREBOOT_H
> +
> +const char *coreboot_fmap_region_to_name(const u32 start, const u32 size);
> +
> +#endif /* __FMAP_COREBOOT_H */
> diff --git a/drivers/firmware/google/fmap_serialized.h b/drivers/firmware/google/fmap_serialized.h
> new file mode 100644
> index 000000000000..a001e47fa244
> --- /dev/null
> +++ b/drivers/firmware/google/fmap_serialized.h
> @@ -0,0 +1,59 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright 2010, Google Inc.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met:
> + *    * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above
> + * copyright notice, this list of conditions and the following disclaimer
> + * in the documentation and/or other materials provided with the
> + * distribution.
> + *    * Neither the name of Google Inc. nor the names of its
> + * contributors may be used to endorse or promote products derived from
> + * this software without specific prior written permission.
> + *
> + */
> +
> +#ifndef FLASHMAP_SERIALIZED_H__
> +#define FLASHMAP_SERIALIZED_H__
> +
> +#define FMAP_SIGNATURE         "__FMAP__"
> +#define FMAP_VER_MAJOR         1       /* this header's FMAP major version */
> +#define FMAP_VER_MINOR         1       /* this header's FMAP minor version */
> +#define FMAP_STRLEN            32      /* maximum length for strings,
> +                                        * including null-terminator
> +                                        */
> +
> +enum fmap_flags {
> +       FMAP_AREA_STATIC        = 1 << 0,
> +       FMAP_AREA_COMPRESSED    = 1 << 1,
> +       FMAP_AREA_RO            = 1 << 2,
> +       FMAP_AREA_PRESERVE      = 1 << 3,
> +};
> +
> +/* Mapping of volatile and static regions in firmware binary */
> +struct fmap_area {
> +       u32 offset;                /* offset relative to base */
> +       u32 size;                  /* size in bytes */
> +       u8  name[FMAP_STRLEN];     /* descriptive name */
> +       u16 flags;                 /* flags for this area */
> +} __packed;
> +
> +struct fmap {
> +       u8  signature[8];       /* "__FMAP__" (0x5F5F464D41505F5F) */
> +       u8  ver_major;          /* major version */
> +       u8  ver_minor;          /* minor version */
> +       u64 base;               /* address of the firmware binary */
> +       u32 size;               /* size of firmware binary in bytes */
> +       u8  name[FMAP_STRLEN];  /* name of this firmware binary */
> +       u16 nareas;             /* number of areas described by
> +                                * fmap_areas[] below
> +                                */
> +       struct fmap_area areas[];
> +} __packed;
> +
> +#endif /* FLASHMAP_SERIALIZED_H__ */
> -- 
> 2.21.0
> 

      parent reply	other threads:[~2019-10-08 22:48 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-08 11:53 [PATCH 1/2] firmware: coreboot: Export the binary FMAP patrick.rudolph
2019-10-08 11:53 ` [PATCH 2/2] firmware: coreboot: Export active CBFS partition patrick.rudolph
2019-10-08 22:47   ` Stephen Boyd
2019-10-09 21:19     ` Julius Werner
2019-10-10  9:46       ` patrick.rudolph
2019-10-10 14:09         ` Stephen Boyd
2019-10-10 18:37           ` Julius Werner
2019-10-16 20:12             ` Stephen Boyd
2019-10-19  2:14               ` Julius Werner
2019-10-11  0:03       ` Samuel Holland
2019-10-08 12:03 ` [PATCH 1/2] firmware: coreboot: Export the binary FMAP Greg Kroah-Hartman
2019-10-08 22:47 ` Stephen Boyd [this message]

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=5d9d1220.1c69fb81.e1df.24e4@mx.google.com \
    --to=swboyd@chromium.org \
    --cc=adurbin@chromium.org \
    --cc=dlaurie@chromium.org \
    --cc=filbranden@chromium.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jwerner@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patrick.rudolph@9elements.com \
    --cc=samuel@sholland.org \
    --cc=tglx@linutronix.de \
    /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.