summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2012-08-09 13:44:38 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2012-11-07 08:28:28 +0100
commit357bb2daf09090192c09ddde501a7e07337614e1 (patch)
treeaa5b66674f5b94e35a1b4a9d38b73aeb62b6a2ba
parenta60ca36c4282c3998d4fc38d55e3dc668017b3ef (diff)
downloadcoreboot-357bb2daf09090192c09ddde501a7e07337614e1.tar.xz
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@google.com> Reviewed-on: http://review.coreboot.org/1701 Reviewed-by: Marc Jones <marcj303@gmail.com> Tested-by: build bot (Jenkins)
-rw-r--r--src/northbridge/intel/sandybridge/Kconfig13
-rw-r--r--src/northbridge/intel/sandybridge/mrccache.c18
-rw-r--r--src/vendorcode/google/chromeos/Kconfig7
-rw-r--r--src/vendorcode/google/chromeos/Makefile.inc2
-rw-r--r--src/vendorcode/google/chromeos/fmap.c126
-rw-r--r--src/vendorcode/google/chromeos/fmap.h79
6 files changed, 230 insertions, 15 deletions
diff --git a/src/northbridge/intel/sandybridge/Kconfig b/src/northbridge/intel/sandybridge/Kconfig
index 7dfd10d3ba..229589998f 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 00b3bdd362..2a7727c876 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 179bbb1f27..ace0c1805f 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 c1b1ccef3e..6e5ea9ba78 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 0000000000..0871529a75
--- /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 0000000000..a3d2abd582
--- /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__*/