[coreboot] New patch to review for coreboot: cc6df55 SandyBridge/IvyBridge: Use flash map to find MRC cache

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Tue Nov 6 23:51:45 CET 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1701

-gerrit

commit cc6df553628d3aaa39ad5797c4d0e4c4747bcbd8
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Thu Aug 9 13:44:38 2012 -0700

    SandyBridge/IvyBridge: Use flash map to find MRC cache
    
    Until now, the MRC cache position and size was hard coded in Kconfig.
    However, on ChromeOS devices, it should be determined by reading the
    FMAP.
    
    This patch provides a minimalistic FMAP parser (libflashmap was too
    complex and OS centered) to allow reading the in-ROM flash map and
    look for sections.
    
    This will also be needed on some partner devices where coreboot will
    have to find the VPD in order to set up the device's mac address
    correctly.
    
    The MRC cache implementation demonstrates how to use the FMAP parser.
    
    Change-Id: I34964b72587443a6ca4f27407d778af8728565f8
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 src/northbridge/intel/sandybridge/Kconfig    |  13 +--
 src/northbridge/intel/sandybridge/mrccache.c |  18 ++--
 src/vendorcode/google/chromeos/Kconfig       |   7 ++
 src/vendorcode/google/chromeos/Makefile.inc  |   2 +
 src/vendorcode/google/chromeos/fmap.c        | 126 +++++++++++++++++++++++++++
 src/vendorcode/google/chromeos/fmap.h        |  79 +++++++++++++++++
 6 files changed, 230 insertions(+), 15 deletions(-)

diff --git a/src/northbridge/intel/sandybridge/Kconfig b/src/northbridge/intel/sandybridge/Kconfig
index 7dfd10d..2295899 100644
--- a/src/northbridge/intel/sandybridge/Kconfig
+++ b/src/northbridge/intel/sandybridge/Kconfig
@@ -44,16 +44,14 @@ config MRC_CACHE_BASE
 
 config MRC_CACHE_LOCATION
 	hex
+	depends on !CHROMEOS
 	default 0x1ec000
 
 config MRC_CACHE_SIZE
 	hex
+	depends on !CHROMEOS
 	default 0x10000
 
-config MRC_CACHE_ALIGNMENT
-	hex
-	default 0x1000
-
 config DCACHE_RAM_BASE
 	hex
 	default 0xff7f0000
@@ -85,17 +83,14 @@ config MRC_CACHE_BASE
 
 config MRC_CACHE_LOCATION
 	hex
+	depends on !CHROMEOS
 	default 0x370000
 
 config MRC_CACHE_SIZE
 	hex
+	depends on !CHROMEOS
 	default 0x10000
 
-config MRC_CACHE_ALIGNMENT
-	hex
-	default 0x1000
-
-
 config DCACHE_RAM_BASE
 	hex
 	default 0xff7e0000
diff --git a/src/northbridge/intel/sandybridge/mrccache.c b/src/northbridge/intel/sandybridge/mrccache.c
index 00b3bdd..2a7727c 100644
--- a/src/northbridge/intel/sandybridge/mrccache.c
+++ b/src/northbridge/intel/sandybridge/mrccache.c
@@ -28,6 +28,9 @@
 #include "sandybridge.h"
 #include <spi.h>
 #include <spi_flash.h>
+#if CONFIG_CHROMEOS
+#include <vendorcode/google/chromeos/fmap.h>
+#endif
 
 struct mrc_data_container *next_mrc_block(struct mrc_data_container *mrc_cache)
 {
@@ -49,18 +52,21 @@ int is_mrc_cache(struct mrc_data_container *mrc_cache)
 }
 
 /* Right now, the offsets for the MRC cache area are hard-coded in the
- * northbridge Kconfig. In order to make this more flexible, there are
- * a number of options:
+ * northbridge Kconfig if CONFIG_CHROMEOS is not set. In order to make
+ * this more flexible, there are two of options:
  *  - Have each mainboard Kconfig supply a hard-coded offset
- *  - For ChromeOS devices: implement native FMAP
- *  - For non-ChromeOS devices: use CBFS
+ *  - Use CBFS
  */
 u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
 {
-
-	u32 region_size = CONFIG_MRC_CACHE_SIZE;
+	u32 region_size;
+#if CONFIG_CHROMEOS
+	region_size =  find_fmap_entry("RW_MRC_CACHE", (void **)mrc_region_ptr);
+#else
+	region_size = CONFIG_MRC_CACHE_SIZE;
 	*mrc_region_ptr = (struct mrc_data_container *)
 		(CONFIG_MRC_CACHE_BASE + CONFIG_MRC_CACHE_LOCATION);
+#endif
 
 	return region_size;
 }
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index 179bbb1..ace0c18 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -57,4 +57,11 @@ config CHROMEOS_RAMOOPS_RAM_SIZE
 	default 0x00100000
 	depends on CHROMEOS_RAMOOPS
 
+config FLASHMAP_OFFSET
+	hex
+	default 0x00670000 if NORTHBRIDGE_INTEL_SANDYBRIDGE
+	default 0x005f0000 if NORTHBRIDGE_INTEL_IVYBRIDGE
+	help
+	  Offset of flash map in firmware image
+
 endmenu
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index c1b1cce..6e5ea9b 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -23,3 +23,5 @@ romstage-y += vbnv.c
 ramstage-y += vbnv.c
 romstage-y += vboot.c
 ramstage-y += gnvs.c
+romstage-y += fmap.c
+ramstage-y += fmap.c
diff --git a/src/vendorcode/google/chromeos/fmap.c b/src/vendorcode/google/chromeos/fmap.c
new file mode 100644
index 0000000..0871529
--- /dev/null
+++ b/src/vendorcode/google/chromeos/fmap.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <console/console.h>
+#include "fmap.h"
+
+static int fmap_try_find(void *fmap)
+{
+	if (!memcmp(fmap, FMAP_SIGNATURE,
+	    sizeof(FMAP_SIGNATURE)-1))
+		return 1;
+	return 0;
+}
+
+/* Find FMAP data structure in ROM.
+ * See http://code.google.com/p/flashmap/ for more information on FMAP.
+ */
+const struct fmap *fmap_find(void)
+{
+	const struct fmap *fmap = NULL;
+
+	/* FIXME: Get rid of the hard codes. The "easy" way would be to
+	 * do a binary search, but since ROM accesses are slow, we don't
+	 * want to spend a lot of time looking for the FMAP. An elegant
+	 * solution would be to store a pointer to the FMAP in the CBFS
+	 * master header; that would require some more changes to cbfstool
+	 * and possibly cros_bundle_firmware.
+	 * FIXME: Use CONFIG_ROMSIZE instead of CONFIG_MRC_CACHE_BASE
+	 * (and get rid of CONFIG_MRC_CACHE_BASE), once we are building
+	 * coreboot images with ME firmware etc built in instead of just
+	 * the CBFS part.
+	 */
+	if (fmap_try_find((void *)CONFIG_MRC_CACHE_BASE +
+						CONFIG_FLASHMAP_OFFSET))
+		fmap = (const struct fmap  *)(CONFIG_MRC_CACHE_BASE +
+						CONFIG_FLASHMAP_OFFSET);
+	if (fmap) {
+		printk(BIOS_DEBUG, "FMAP: Found \"%s\" version %d.%d at %p.\n",
+			fmap->name, fmap->ver_major, fmap->ver_minor, fmap);
+		printk(BIOS_DEBUG, "FMAP: base = %llx size = %x #areas = %d\n",
+			(unsigned long long)fmap->base, fmap->size,
+			fmap->nareas);
+	} else
+		printk(BIOS_DEBUG, "No FMAP found.\n");
+
+	return fmap;
+}
+
+const struct fmap_area *find_fmap_area(const struct fmap *fmap,
+							const char name[])
+{
+	const struct fmap_area *area = NULL;
+
+	if (fmap) {
+		int i;
+		for (i = 0; i < fmap->nareas; i++) {
+			if (!strcmp((const char *)fmap->areas[i].name, name)) {
+				area = &fmap->areas[i];
+				break;
+			}
+		}
+	}
+
+	if (area) {
+		printk(BIOS_DEBUG, "FMAP: area %s found\n", name);
+		printk(BIOS_DEBUG, "FMAP:   offset: %x\n", area->offset);
+		printk(BIOS_DEBUG, "FMAP:   size:   %d bytes\n", area->size);
+	} else {
+		printk(BIOS_DEBUG, "FMAP: area %s not found\n", name);
+	}
+
+	return area;
+}
+
+int find_fmap_entry(const char name[], void **pointer)
+{
+#ifndef __PRE_RAM__
+	static
+#endif
+	const struct fmap *fmap = NULL;
+	const struct fmap_area *area;
+	void *base = NULL;
+
+	if (!fmap)
+		fmap = fmap_find();
+
+	area = find_fmap_area(fmap, name);
+
+	if (!area)
+		return -1;
+
+	/* Right now cros_bundle_firmware does not write a valid
+	 * base address into the FMAP. Hence, if base is 0, assume
+	 * 4GB-8MB as base address.
+	 */
+	if (fmap->base) {
+		base = (void *)(unsigned long)fmap->base;
+	} else {
+		printk(BIOS_WARNING, "FMAP: No valid base address, using"
+				" 0x%08x\n", CONFIG_MRC_CACHE_BASE);
+		base = (void *)CONFIG_MRC_CACHE_BASE;
+	}
+
+	*pointer = base + area->offset;
+
+	return area->size;
+}
diff --git a/src/vendorcode/google/chromeos/fmap.h b/src/vendorcode/google/chromeos/fmap.h
new file mode 100644
index 0000000..a3d2abd
--- /dev/null
+++ b/src/vendorcode/google/chromeos/fmap.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#ifndef FLASHMAP_LIB_FMAP_H__
+#define FLASHMAP_LIB_FMAP_H__
+
+#include <stdint.h>
+
+#define FMAP_SIGNATURE		"__FMAP__"
+#define FMAP_VER_MAJOR		1	/* this header's FMAP minor 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,
+};
+
+/* Mapping of volatile and static regions in firmware binary */
+struct fmap_area {
+	uint32_t offset;                /* offset relative to base */
+	uint32_t size;                  /* size in bytes */
+	uint8_t  name[FMAP_STRLEN];     /* descriptive name */
+	uint16_t flags;                 /* flags for this area */
+}  __attribute__((packed));
+
+struct fmap {
+	uint8_t  signature[8];		/* "__FMAP__" (0x5F5F464D41505F5F) */
+	uint8_t  ver_major;		/* major version */
+	uint8_t  ver_minor;		/* minor version */
+	uint64_t base;			/* address of the firmware binary */
+	uint32_t size;			/* size of firmware binary in bytes */
+	uint8_t  name[FMAP_STRLEN];	/* name of this firmware binary */
+	uint16_t nareas;		/* number of areas described by
+					   fmap_areas[] below */
+	struct fmap_area areas[];
+} __attribute__((packed));
+
+
+/* coreboot specific function prototypes */
+const struct fmap *fmap_find(void);
+const struct fmap_area *find_fmap_area(const struct fmap *fmap,
+							const char name[]);
+int find_fmap_entry(const char name[], void **pointer);
+#endif	/* FLASHMAP_LIB_FMAP_H__*/




More information about the coreboot mailing list