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 #include +#if CONFIG_CHROMEOS +#include +#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 +#include +#include +#include +#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 + +#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__*/