Vladimir Serbinenko (phcoder@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10350
-gerrit
commit b4a2b32cb30c2ccb064b63837cb7aa239d0616be Author: Vladimir Serbinenko phcoder@gmail.com Date: Thu May 28 14:24:09 2015 +0200
Revert fmap and boot_device commits
Those commits miss tseg_relocate somewhere and so SMI hangs on shutdown. Revert the commit until we figure out where is the mistake or switch sandy/ivy/nehalem to SMM modules (preffered).
This reverts commit 0424c95a6dafdb65070538d6c5aa394b75eb9850. This reverts commit c6588c5af94e568bddd8111c3fca736f464042cf.
Change-Id: I1e330c2730092e9b81d98ee861605bc32a6a7ab3 Signed-off-by: Vladimir Serbinenko phcoder@gmail.com --- src/Kconfig | 9 -- src/arch/riscv/rom_media.c | 66 ++++++------ src/arch/x86/lib/Makefile.inc | 3 - src/arch/x86/lib/mmap_boot.c | 31 ------ src/arch/x86/lib/rom_media.c | 57 +++++----- src/cpu/allwinner/a10/bootblock_media.c | 8 +- src/cpu/ti/am335x/bootblock_media.c | 47 ++------ src/cpu/ti/am335x/nand.c | 10 +- src/drivers/elog/elog.c | 49 ++++++--- src/include/boot_device.h | 41 ------- src/include/fmap.h | 35 ------ src/include/fmap_serialized.h | 73 ------------- src/lib/Makefile.inc | 11 -- src/lib/boot_device.c | 38 ------- src/lib/cbfs_spi.c | 97 +++++------------ src/lib/fmap.c | 119 --------------------- src/mainboard/emulation/qemu-armv7/media.c | 45 ++------ src/mainboard/google/butterfly/mainboard.c | 41 +++---- src/mainboard/google/panther/lan.c | 25 ++--- src/northbridge/intel/haswell/mrccache.c | 28 +++-- src/northbridge/intel/sandybridge/mrccache.c | 29 +++-- src/soc/intel/common/mrc_cache.c | 27 ++--- src/soc/nvidia/tegra124/Makefile.inc | 4 + src/soc/nvidia/tegra124/cbfs.c | 29 +++++ src/soc/nvidia/tegra124/include/soc/spi.h | 5 + src/soc/nvidia/tegra124/spi.c | 116 +++++++------------- src/soc/nvidia/tegra132/Makefile.inc | 4 + src/soc/nvidia/tegra132/cbfs.c | 28 +++++ src/soc/nvidia/tegra132/include/soc/spi.h | 5 + src/soc/nvidia/tegra132/spi.c | 116 +++++++------------- src/soc/samsung/exynos5250/alternate_cbfs.c | 118 +++++++------------- src/soc/samsung/exynos5250/include/soc/spi.h | 9 +- src/soc/samsung/exynos5250/spi.c | 85 +++++++++------ src/soc/samsung/exynos5420/alternate_cbfs.c | 118 +++++++------------- src/soc/samsung/exynos5420/include/soc/spi.h | 9 +- src/soc/samsung/exynos5420/spi.c | 78 ++++++++++---- src/vendorcode/google/chromeos/Kconfig | 9 ++ src/vendorcode/google/chromeos/Makefile.inc | 4 + src/vendorcode/google/chromeos/cros_vpd.c | 30 +++--- src/vendorcode/google/chromeos/fmap.h | 79 ++++++++++++++ .../google/chromeos/vboot2/vboot_handoff.c | 2 +- 41 files changed, 665 insertions(+), 1072 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index 26e1194..5cfb06f 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -244,15 +244,6 @@ config CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM The relocated ramstage is saved in an area specified by the by the board and/or chipset.
-config FLASHMAP_OFFSET - hex "Flash Map Offset" - default 0x00670000 if NORTHBRIDGE_INTEL_SANDYBRIDGE - default 0x00610000 if NORTHBRIDGE_INTEL_IVYBRIDGE - default CBFS_SIZE if !ARCH_X86 - default 0 - help - Offset of flash map in firmware image - choice prompt "Bootblock behaviour" default BOOTBLOCK_SIMPLE diff --git a/src/arch/riscv/rom_media.c b/src/arch/riscv/rom_media.c index f18030c..8d3376c 100644 --- a/src/arch/riscv/rom_media.c +++ b/src/arch/riscv/rom_media.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright 2015 Google Inc. + * Copyright (C) 2013 The Chromium OS 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 @@ -17,59 +17,40 @@ * along with this program; if not, write to the Free Software * Foundation, Inc. */ -#include <boot_device.h> #include <cbfs.h> -#include <console/console.h> #include <string.h>
-/* This assumes that the CBFS resides at 0x0, which is true for the default - * configuration. */ -static const struct mem_region_device gboot_dev = - MEM_REGION_DEV_INIT(NULL, CONFIG_ROM_SIZE); +#ifdef LIBPAYLOAD +# define printk(x...) +# define init_default_cbfs_media libpayload_init_default_cbfs_media + extern int libpayload_init_default_cbfs_media(struct cbfs_media *media); +#else +# include <console/console.h> +#endif
-const struct region_device *boot_device_ro(void) -{ - return &gboot_dev.rdev; -} +// Implementation of memory-mapped ROM media source on X86.
static int rom_media_open(struct cbfs_media *media) { return 0; }
static void *rom_media_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; void *ptr; - printk(BIOS_INFO, "%s: media %p, offset %lx, size %ld.\n", __func__, media, offset, count); - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1;
+ ptr = (void*)offset; return ptr; }
static void *rom_media_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - return NULL; }
static size_t rom_media_read(struct cbfs_media *media, void *dest, size_t offset, size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - + void *ptr = rom_media_map(media, offset, count); + memcpy(dest, ptr, count); + rom_media_unmap(media, ptr); return count; }
@@ -78,8 +59,25 @@ static int rom_media_close(struct cbfs_media *media) { }
static int init_rom_media_cbfs(struct cbfs_media *media) { - boot_device_init(); - media->context = (void *)boot_device_ro(); + /* this assumes that the CBFS resides at 0x0, + * which is true for the default configuration + */ + int32_t *cbfs_header_ptr = (int32_t*)(uintptr_t)(CONFIG_CBFS_SIZE - 4); + uint64_t cbfs_header_offset = CONFIG_CBFS_SIZE + *cbfs_header_ptr; + struct cbfs_header *header = (struct cbfs_header*) cbfs_header_offset; + if (CBFS_HEADER_MAGIC != ntohl(header->magic)) { + printk(BIOS_ERR, "Invalid CBFS master header at %p\n", header); + printk(BIOS_ERR, "Expected %08lx and got %08lx\n", (unsigned long) CBFS_HEADER_MAGIC, (unsigned long) ntohl(header->magic)); + return -1; + } else { + uint32_t romsize = ntohl(header->romsize); + media->context = (void*)(uintptr_t)romsize; +#if defined(CONFIG_ROM_SIZE) + if (CONFIG_ROM_SIZE != romsize) + printk(BIOS_INFO, "Warning: rom size unmatch (%d/%d)\n", + CONFIG_ROM_SIZE, romsize); +#endif + } media->open = rom_media_open; media->close = rom_media_close; media->map = rom_media_map; diff --git a/src/arch/x86/lib/Makefile.inc b/src/arch/x86/lib/Makefile.inc index e308be9..c7e8b62 100644 --- a/src/arch/x86/lib/Makefile.inc +++ b/src/arch/x86/lib/Makefile.inc @@ -6,7 +6,6 @@ romstage-y += memset.c romstage-y += memcpy.c romstage-y += memmove.c romstage-y += rom_media.c -romstage-y += mmap_boot.c
endif # CONFIG_ARCH_ROMSTAGE_X86_32
@@ -23,7 +22,6 @@ ramstage-y += memcpy.c ramstage-y += memmove.c ramstage-y += ebda.c ramstage-y += rom_media.c -ramstage-y += mmap_boot.c ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c ramstage-$(CONFIG_COOP_MULTITASKING) += thread_switch.S ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c @@ -34,7 +32,6 @@ smm-y += memset.c smm-y += memcpy.c smm-y += memmove.c smm-y += rom_media.c -smm-y += mmap_boot.c
rmodules_x86_32-y += memset.c rmodules_x86_32-y += memcpy.c diff --git a/src/arch/x86/lib/mmap_boot.c b/src/arch/x86/lib/mmap_boot.c deleted file mode 100644 index eb7b23e..0000000 --- a/src/arch/x86/lib/mmap_boot.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc. - * - * 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. - */ - -#include <boot_device.h> - -/* The ROM is memory mapped just below 4GiB. Form a pointer for the base. */ -#define rom_base ((void *)(uintptr_t)(-(int32_t)CONFIG_ROM_SIZE)) - -static const struct mem_region_device boot_dev = - MEM_REGION_DEV_INIT(rom_base, CONFIG_ROM_SIZE); - -const struct region_device *boot_device_ro(void) -{ - return &boot_dev.rdev; -} diff --git a/src/arch/x86/lib/rom_media.c b/src/arch/x86/lib/rom_media.c index d4663c7..659e5e4 100644 --- a/src/arch/x86/lib/rom_media.c +++ b/src/arch/x86/lib/rom_media.c @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc. */ - -#include <boot_device.h> #include <cbfs.h> #include <string.h>
@@ -38,19 +36,14 @@ static int x86_rom_open(struct cbfs_media *media) {
static void *x86_rom_map(struct cbfs_media *media, size_t offset, size_t count) { void *ptr; - const struct region_device *boot_dev; - - boot_dev = media->context; + // Some address (ex, pointer to master header) may be given in memory + // mapped location. To workaround that, we handle >0xf0000000 as real + // memory pointer.
- /* Extremely large offsets are considered relative to end of region. */ if ((uint32_t)offset > (uint32_t)0xf0000000) - offset += region_device_sz(boot_dev); - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - + ptr = (void*)offset; + else + ptr = (void*)(0 - (uint32_t)media->context + offset); return ptr; }
@@ -60,13 +53,7 @@ static void *x86_rom_unmap(struct cbfs_media *media, const void *address) {
static size_t x86_rom_read(struct cbfs_media *media, void *dest, size_t offset, size_t count) { - void *ptr; - - ptr = x86_rom_map(media, offset, count); - - if (ptr == (void *)-1) - return 0; - + void *ptr = x86_rom_map(media, offset, count); memcpy(dest, ptr, count); x86_rom_unmap(media, ptr); return count; @@ -76,14 +63,30 @@ static int x86_rom_close(struct cbfs_media *media) { return 0; }
-static int init_x86rom_cbfs_media(struct cbfs_media *media) { - boot_device_init(); - - media->context = (void *)boot_device_ro(); - - if (media->context == NULL) +int init_x86rom_cbfs_media(struct cbfs_media *media); +int init_x86rom_cbfs_media(struct cbfs_media *media) { + // On X86, we always keep a reference of pointer to CBFS header in + // 0xfffffffc, and the pointer is still a memory-mapped address. + // Since the CBFS core always use ROM offset, we need to figure out + // header->romsize even before media is initialized. + struct cbfs_header *header = (struct cbfs_header*) + *(uint32_t*)(0xfffffffc); + if (CBFS_HEADER_MAGIC != ntohl(header->magic)) { +#if defined(CONFIG_ROM_SIZE) + printk(BIOS_ERR, "Invalid CBFS master header at %p\n", header); + media->context = (void*)CONFIG_ROM_SIZE; +#else return -1; - +#endif + } else { + uint32_t romsize = ntohl(header->romsize); + media->context = (void*)romsize; +#if defined(CONFIG_ROM_SIZE) + if (CONFIG_ROM_SIZE != romsize) + printk(BIOS_INFO, "Warning: rom size unmatch (%d/%d)\n", + CONFIG_ROM_SIZE, romsize); +#endif + } media->open = x86_rom_open; media->close = x86_rom_close; media->map = x86_rom_map; diff --git a/src/cpu/allwinner/a10/bootblock_media.c b/src/cpu/allwinner/a10/bootblock_media.c index a585bca..a5863b6 100644 --- a/src/cpu/allwinner/a10/bootblock_media.c +++ b/src/cpu/allwinner/a10/bootblock_media.c @@ -4,17 +4,11 @@ * Copyright (C) 2013 Alexandru Gagniuc mr.nuke.me@gmail.com * Subject to the GNU GPL v2, or (at your option) any later version. */ -#include <boot_device.h> #include <cbfs.h> #include <console/console.h>
-const struct region_device *boot_device_ro(void) -{ - return NULL; -} - int init_default_cbfs_media(struct cbfs_media *media) { printk(BIOS_ERR, "Oh my! I don't know how to access CBFS yet."); - return -1; + return 0; } diff --git a/src/cpu/ti/am335x/bootblock_media.c b/src/cpu/ti/am335x/bootblock_media.c index 79724ee..9824fc3 100644 --- a/src/cpu/ti/am335x/bootblock_media.c +++ b/src/cpu/ti/am335x/bootblock_media.c @@ -17,21 +17,11 @@ * Foundation, Inc. */
-#include <boot_device.h> #include <cbfs.h> #include <console/console.h> #include <string.h> #include <symbols.h>
-/* FIXME: No idea how big the internal SRAM actually is. */ -static const struct mem_region_device gboot_dev = - MEM_REGION_DEV_INIT(_dram, CONFIG_ROM_SIZE); - -const struct region_device *boot_device_ro(void) -{ - return &gboot_dev.rdev; -} - static int dummy_open(struct cbfs_media *media) { return 0; @@ -45,48 +35,33 @@ static int dummy_close(struct cbfs_media *media) static void * on_chip_memory_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; - void *ptr; - - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - - return ptr; + return _dram + offset; }
static void * dummy_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - return NULL; }
static size_t on_chip_memory_read(struct cbfs_media *media, void *dest, size_t offset, size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - + void *ptr = media->map(media, offset, count); + memcpy(dest, ptr, count); + media->unmap(media, ptr); return count; }
int init_default_cbfs_media(struct cbfs_media *media) { - boot_device_init(); + struct cbfs_header *header = + (struct cbfs_header *)(_dram + CONFIG_CBFS_HEADER_ROM_OFFSET); + + if (CBFS_HEADER_MAGIC != ntohl(header->magic)) { + printk(BIOS_ERR, "Invalid CBFS master header at %p\n", header); + return -1; + }
- media->context = (void *)boot_device_ro(); media->open = dummy_open; media->close = dummy_close; media->map = on_chip_memory_map; diff --git a/src/cpu/ti/am335x/nand.c b/src/cpu/ti/am335x/nand.c index dd05fb6..a8c945b 100644 --- a/src/cpu/ti/am335x/nand.c +++ b/src/cpu/ti/am335x/nand.c @@ -17,16 +17,10 @@ * Foundation, Inc. */
-#include <boot_device.h> #include <cbfs.h>
-const struct region_device *boot_device_ro(void) -{ - return NULL; -} - int init_default_cbfs_media(struct cbfs_media *media) { - /* FIXME: add support for reading coreboot from NAND */ - return -1; + /* FIXME: add support for reading coreboot from NAND */ + return 0; } diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c index 8dce86b..da1f6fa 100644 --- a/src/drivers/elog/elog.c +++ b/src/drivers/elog/elog.c @@ -26,7 +26,6 @@ #include <pc80/mc146818rtc.h> #endif #include <bcd.h> -#include <fmap.h> #include <rtc.h> #include <smbios.h> #include <spi-generic.h> @@ -36,6 +35,7 @@ #include <elog.h> #include "elog_internal.h"
+#include <vendorcode/google/chromeos/fmap.h>
#if !IS_ENABLED(CONFIG_CHROMEOS) && CONFIG_ELOG_FLASH_BASE == 0 #error "CONFIG_ELOG_FLASH_BASE is invalid" @@ -86,6 +86,26 @@ static inline u32 get_rom_size(void) }
/* + * Convert a memory mapped flash address into a flash offset + */ +static inline u32 elog_flash_address_to_offset(u8 *address) +{ +#if CONFIG_ARCH_X86 + /* For x86, assume address is memory-mapped near 4GB */ + u32 rom_size; + + if (!elog_spi) + return 0; + + rom_size = get_rom_size(); + + return (u32)address - ((u32)~0UL - rom_size + 1); +#else + return (u32)(uintptr_t)address; +#endif +} + +/* * Pointer to an event log header in the event data area */ static inline struct event_header* @@ -497,22 +517,21 @@ static void elog_find_flash(void) { elog_debug("elog_find_flash()\n");
- if (IS_ENABLED(CONFIG_CHROMEOS)) { - /* Find the ELOG base and size in FMAP */ - struct region r; - - if (fmap_locate_area("RW_ELOG", &r) < 0) { - printk(BIOS_WARNING, - "ELOG: Unable to find RW_ELOG in FMAP\n"); - flash_base = total_size = 0; - } else { - flash_base = region_offset(&r); - total_size = MIN(region_sz(&r), CONFIG_ELOG_AREA_SIZE); - } +#if CONFIG_CHROMEOS + /* Find the ELOG base and size in FMAP */ + u8 *flash_base_ptr; + int fmap_size = find_fmap_entry("RW_ELOG", (void **)&flash_base_ptr); + if (fmap_size < 0) { + printk(BIOS_WARNING, "ELOG: Unable to find RW_ELOG in FMAP\n"); + flash_base = total_size = 0; } else { - flash_base = CONFIG_ELOG_FLASH_BASE; - total_size = CONFIG_ELOG_AREA_SIZE; + flash_base = elog_flash_address_to_offset(flash_base_ptr); + total_size = MIN(fmap_size, CONFIG_ELOG_AREA_SIZE); } +#else + flash_base = CONFIG_ELOG_FLASH_BASE; + total_size = CONFIG_ELOG_AREA_SIZE; +#endif log_size = total_size - sizeof(struct elog_header); full_threshold = log_size - ELOG_MIN_AVAILABLE_ENTRIES * MAX_EVENT_SIZE; shrink_size = MIN(total_size * ELOG_SHRINK_PERCENTAGE / 100, diff --git a/src/include/boot_device.h b/src/include/boot_device.h deleted file mode 100644 index 0848ea5..0000000 --- a/src/include/boot_device.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc. - * - * 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. - */ - -#ifndef _BOOT_DEVICE_H_ -#define _BOOT_DEVICE_H_ - -#include <region.h> - -/* Return the region_device for the read-only boot device. */ -const struct region_device *boot_device_ro(void); - -/* - * Create a sub-region of the read-only boot device. - * Returns 0 on success, < 0 on error. - */ -int boot_device_ro_subregion(const struct region *sub, - struct region_device *subrd); - -/* - * Initialize the boot device. This may be called multiple times within - * a stage so boot device implementations should account for this behavior. - **/ -void boot_device_init(void); - -#endif /* _BOOT_DEVICE_H_ */ diff --git a/src/include/fmap.h b/src/include/fmap.h deleted file mode 100644 index e575bbf..0000000 --- a/src/include/fmap.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc. - * - * 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. - */ - -#ifndef _FMAP_H_ -#define _FMAP_H_ - -#include <region.h> - -/* Locate the named area in the fmap and fill in a region device representing - * that area. The region is a sub-region of the readonly boot media. Return - * 0 on success, < 0 on error. */ -int fmap_locate_area_as_rdev(const char *name, struct region_device *area); - -/* Locate the named area in the fmap and fill in a region with the - * offset and size of that area within the boot media. Return 0 on success, - * < 0 on error. */ -int fmap_locate_area(const char *name, struct region *r); - -#endif diff --git a/src/include/fmap_serialized.h b/src/include/fmap_serialized.h deleted file mode 100644 index 3585f0b..0000000 --- a/src/include/fmap_serialized.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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_SERIALIZED_H__ -#define FLASHMAP_SERIALIZED_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)); - -#endif /* FLASHMAP_SERIALIZED_H__ */ diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 5ec9de7..11562bd 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -31,19 +31,15 @@ bootblock-y += memchr.c bootblock-y += memcmp.c bootblock-y += mem_pool.c bootblock-y += region.c -bootblock-y += boot_device.c -bootblock-y += fmap.c
verstage-y += prog_ops.c verstage-y += delay.c verstage-y += cbfs.c verstage-y += cbfs_core.c verstage-y += halt.c -verstage-y += fmap.c verstage-y += memcmp.c verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c verstage-y += region.c -verstage-y += boot_device.c verstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c
@@ -64,7 +60,6 @@ $(foreach arch,$(ARCH_SUPPORTED),\ $(eval rmodules_$(arch)-y += memcmp.c) \ $(eval rmodules_$(arch)-y += rmodule.ld))
-romstage-y += fmap.c romstage-$(CONFIG_I2C_TPM) += delay.c romstage-y += cbfs.c cbfs_core.c romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c @@ -92,7 +87,6 @@ ramstage-y += hardwaremain.c ramstage-y += selfboot.c ramstage-y += coreboot_table.c ramstage-y += bootmem.c -ramstage-y += fmap.c ramstage-y += memchr.c ramstage-y += memcmp.c ramstage-y += malloc.c @@ -147,12 +141,7 @@ ramstage-y += mem_pool.c
romstage-y += region.c ramstage-y += region.c -romstage-y += boot_device.c -ramstage-y += boot_device.c
-smm-y += region.c -smm-y += boot_device.c -smm-y += fmap.c smm-y += cbfs.c cbfs_core.c memcmp.c smm-$(CONFIG_COMPILER_GCC) += gcc.c
diff --git a/src/lib/boot_device.c b/src/lib/boot_device.c deleted file mode 100644 index e0353fc..0000000 --- a/src/lib/boot_device.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc. - * - * 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. - */ - -#include <boot_device.h> - -void __attribute__((weak)) boot_device_init(void) -{ - /* Provide weak do-nothing init. */ -} - -int boot_device_ro_subregion(const struct region *sub, - struct region_device *subrd) -{ - const struct region_device *boot_dev; - - boot_dev = boot_device_ro(); - - if (boot_dev == NULL) - return -1; - - return rdev_chain(subrd, boot_dev, region_offset(sub), region_sz(sub)); -} diff --git a/src/lib/cbfs_spi.c b/src/lib/cbfs_spi.c index 6758220..6c8d78d 100644 --- a/src/lib/cbfs_spi.c +++ b/src/lib/cbfs_spi.c @@ -23,52 +23,17 @@ * SPI. */
-#include <boot_device.h> #include <cbfs.h> -#include <region.h> #include <spi_flash.h> #include <symbols.h>
-static struct spi_flash *spi_flash_info; - -static ssize_t spi_readat(const struct region_device *rd, void *b, - size_t offset, size_t size) -{ - if (spi_flash_info->read(spi_flash_info, offset, size, b)) - return -1; - return size; -} - -static const struct region_device_ops spi_ops = { - .mmap = mmap_helper_rdev_mmap, - .munmap = mmap_helper_rdev_munmap, - .readat = spi_readat, +/* SPI flash as CBFS media. */ +struct cbfs_spi_context { + struct spi_flash *spi_flash_info; + struct cbfs_simple_buffer buffer; };
-static struct mmap_helper_region_device mdev = - MMAP_HELPER_REGION_INIT(&spi_ops, 0, CONFIG_ROM_SIZE); - -void boot_device_init(void) -{ - int bus = CONFIG_BOOT_MEDIA_SPI_BUS; - int cs = 0; - - if (spi_flash_info != NULL) - return; - - spi_flash_info = spi_flash_probe(bus, cs); - - mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size); -} - -/* Return the CBFS boot device. */ -const struct region_device *boot_device_ro(void) -{ - if (spi_flash_info == NULL) - return NULL; - - return &mdev.rdev; -} +static struct cbfs_spi_context spi_context;
static int cbfs_media_open(struct cbfs_media *media) { @@ -84,58 +49,52 @@ static size_t cbfs_media_read(struct cbfs_media *media, void *dest, size_t offset, size_t count) { - const struct region_device *boot_dev; + struct cbfs_spi_context *context = media->context;
- boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; + return context->spi_flash_info->read + (context->spi_flash_info, offset, count, dest) ? 0 : count; }
static void *cbfs_media_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; - void *ptr; - - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); + struct cbfs_spi_context *context = media->context;
- if (ptr == NULL) - return (void *)-1; - - return ptr; + return cbfs_simple_buffer_map(&context->buffer, media, offset, count); }
static void *cbfs_media_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); + struct cbfs_spi_context *context = media->context;
- return NULL; + return cbfs_simple_buffer_unmap(&context->buffer, address); }
-int init_default_cbfs_media(struct cbfs_media *media) +static int init_cbfs_media_context(void) { - boot_device_init(); + if (!spi_context.spi_flash_info) { + + spi_context.spi_flash_info = spi_flash_probe + (CONFIG_BOOT_MEDIA_SPI_BUS, 0);
- media->context = (void *)boot_device_ro(); + if (!spi_context.spi_flash_info) + return -1;
- if (media->context == NULL) - return -1; + spi_context.buffer.buffer = (void *)_cbfs_cache; + spi_context.buffer.size = _cbfs_cache_size; + } + return 0;
+} +int init_default_cbfs_media(struct cbfs_media *media) +{ + media->context = &spi_context; media->open = cbfs_media_open; media->close = cbfs_media_close; media->read = cbfs_media_read; media->map = cbfs_media_map; media->unmap = cbfs_media_unmap;
- return 0; + return init_cbfs_media_context(); } diff --git a/src/lib/fmap.c b/src/lib/fmap.c deleted file mode 100644 index 0f48cdc..0000000 --- a/src/lib/fmap.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2012-2015 Google Inc. - * - * 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. - */ - -#include <boot_device.h> -#include <console/console.h> -#include <fmap.h> -#include <fmap_serialized.h> -#include <stddef.h> -#include <string.h> - -/* - * See http://code.google.com/p/flashmap/ for more information on FMAP. - */ - -static int find_fmap_directory(struct region_device *fmrd) -{ - const struct region_device *boot; - struct fmap *fmap; - size_t fmap_size; - size_t offset = CONFIG_FLASHMAP_OFFSET; - - boot_device_init(); - boot = boot_device_ro(); - - if (boot == NULL) - return -1; - - fmap_size = sizeof(struct fmap); - - fmap = rdev_mmap(boot, offset, fmap_size); - - if (fmap == NULL) - return -1; - - if (memcmp(fmap->signature, FMAP_SIGNATURE, sizeof(fmap->signature))) { - printk(BIOS_DEBUG, "No FMAP found at %zx offset.\n", offset); - rdev_munmap(boot, fmap); - return -1; - } - - printk(BIOS_DEBUG, "FMAP: Found "%s" version %d.%d at %zx.\n", - fmap->name, fmap->ver_major, fmap->ver_minor, offset); - printk(BIOS_DEBUG, "FMAP: base = %llx size = %x #areas = %d\n", - (long long)fmap->base, fmap->size, fmap->nareas); - - fmap_size += fmap->nareas * sizeof(struct fmap_area); - - rdev_munmap(boot, fmap); - - return rdev_chain(fmrd, boot, offset, fmap_size); -} - -int fmap_locate_area_as_rdev(const char *name, struct region_device *area) -{ - struct region ar; - - if (fmap_locate_area(name, &ar)) - return -1; - - return boot_device_ro_subregion(&ar, area); -} - -int fmap_locate_area(const char *name, struct region *ar) -{ - struct region_device fmrd; - size_t offset; - - if (find_fmap_directory(&fmrd)) - return -1; - - /* Start reading the areas just after fmap header. */ - offset = sizeof(struct fmap); - - while (1) { - struct fmap_area *area; - - area = rdev_mmap(&fmrd, offset, sizeof(*area)); - - if (area == NULL) - return -1; - - if (strcmp((const char *)area->name, name)) { - rdev_munmap(&fmrd, area); - offset += sizeof(struct fmap_area); - continue; - } - - 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); - - ar->offset = area->offset; - ar->size = area->size; - - rdev_munmap(&fmrd, area); - - return 0; - } - - printk(BIOS_DEBUG, "FMAP: area %s not found\n", name); - - return -1; -} diff --git a/src/mainboard/emulation/qemu-armv7/media.c b/src/mainboard/emulation/qemu-armv7/media.c index e0f2251..8c71263 100644 --- a/src/mainboard/emulation/qemu-armv7/media.c +++ b/src/mainboard/emulation/qemu-armv7/media.c @@ -12,20 +12,12 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#include <boot_device.h> #include <cbfs.h> #include <string.h> #include <symbols.h> #include <console/console.h>
-/* Maps directly to qemu memory mapped space of 0x10000 up to rom size. */ -static const struct mem_region_device gboot_dev = - MEM_REGION_DEV_INIT((void *)0x10000, CONFIG_ROM_SIZE); - -const struct region_device *boot_device_ro(void) -{ - return &gboot_dev.rdev; -} +/* Simple memory-mapped ROM emulation. */
static int emu_rom_open(struct cbfs_media *media) { @@ -34,40 +26,26 @@ static int emu_rom_open(struct cbfs_media *media)
static void *emu_rom_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; - void *ptr; - - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - - return ptr; + if (offset + count > CONFIG_ROM_SIZE) + return (void *)-1; + return (void*)(offset + 0x10000); }
static void *emu_rom_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - return NULL; }
static size_t emu_rom_read(struct cbfs_media *media, void *dest, size_t offset, size_t count) { - const struct region_device *boot_dev; + void *ptr = emu_rom_map(media, offset, count);
- boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) + if (ptr == (void *)-1) return 0;
+ memcpy(dest, ptr, count); + emu_rom_unmap(media, ptr); return count; }
@@ -76,11 +54,10 @@ static int emu_rom_close(struct cbfs_media *media) return 0; }
-static int init_emu_rom_cbfs_media(struct cbfs_media *media) -{ - boot_device_init(); +int init_emu_rom_cbfs_media(struct cbfs_media *media);
- media->context = (void *)boot_device_ro(); +int init_emu_rom_cbfs_media(struct cbfs_media *media) +{ media->open = emu_rom_open; media->close = emu_rom_close; media->map = emu_rom_map; diff --git a/src/mainboard/google/butterfly/mainboard.c b/src/mainboard/google/butterfly/mainboard.c index e09336d..bd2fbd5 100644 --- a/src/mainboard/google/butterfly/mainboard.c +++ b/src/mainboard/google/butterfly/mainboard.c @@ -20,13 +20,11 @@
#include <types.h> #include <string.h> -#include <cbfs.h> #include <device/device.h> #include <device/pci_def.h> #include <device/pci_ops.h> #include <console/console.h> #include <drivers/intel/gma/int15.h> -#include <fmap.h> #include <pc80/mc146818rtc.h> #include <arch/acpi.h> #include <arch/io.h> @@ -38,6 +36,11 @@ #include <smbios.h> #include <device/pci.h> #include <ec/quanta/ene_kb3940q/ec.h> +#if CONFIG_CHROMEOS +#include <vendorcode/google/chromeos/fmap.h> +#else +#include <cbfs.h> +#endif
static unsigned int search(char *p, char *a, unsigned int lengthp, unsigned int lengtha) @@ -197,30 +200,20 @@ static void mainboard_init(device_t dev) size_t search_length = -1; u16 io_base = 0; struct device *ethernet_dev = NULL; - void *vpd_file; - - if (IS_ENABLED(CONFIG_CHROMEOS)) { - struct region_device rdev; - - if (fmap_locate_area_as_rdev("RO_VPD", &rdev) == 0) { - vpd_file = rdev_mmap_full(&rdev); - - if (vpd_file != NULL) { - search_length = region_device_sz(&rdev); - search_address = (uintptr_t)vpd_file; - } - } +#if CONFIG_CHROMEOS + char **vpd_region_ptr = NULL; + search_length = find_fmap_entry("RO_VPD", (void **)vpd_region_ptr); + search_address = (unsigned long)(*vpd_region_ptr); +#else + void *vpd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "vpd.bin", + CBFS_TYPE_RAW, &search_length); + if (vpd_file) { + search_address = (unsigned long)vpd_file; } else { - vpd_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "vpd.bin", CBFS_TYPE_RAW, - &search_length); - if (vpd_file) { - search_address = (unsigned long)vpd_file; - } else { - search_length = -1; - search_address = 0; - } + search_length = -1; + search_address = 0; } +#endif
/* Initialize the Embedded Controller */ butterfly_ec_init(); diff --git a/src/mainboard/google/panther/lan.c b/src/mainboard/google/panther/lan.c index 8a648cb..9fd325f 100644 --- a/src/mainboard/google/panther/lan.c +++ b/src/mainboard/google/panther/lan.c @@ -24,8 +24,8 @@ #include <console/console.h> #include <device/device.h> #include <device/pci.h> -#include <fmap.h> #include <southbridge/intel/bd82x6x/pch.h> +#include <vendorcode/google/chromeos/fmap.h> #include "onboard.h"
static unsigned int search(char *p, u8 *a, unsigned int lengthp, @@ -117,24 +117,15 @@ static void program_mac_address(u16 io_base) u32 high_dword = 0xD0BA00A0; /* high dword of mac address */ u32 low_dword = 0x0000AD0B; /* low word of mac address as a dword */
- if (IS_ENABLED(CONFIG_CHROMEOS)) { - struct region_device rdev; - - if (fmap_locate_area_as_rdev("RO_VPD", &rdev) == 0) { - search_address = rdev_mmap_full(&rdev); - - if (search_address != NULL) - search_length = region_device_sz(&rdev); - } - } else { - search_address = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "vpd.bin", - CBFS_TYPE_RAW, - &search_length); - } +#if CONFIG_CHROMEOS + search_length = find_fmap_entry("RO_VPD", &search_address); +#else + search_address = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "vpd.bin", + CBFS_TYPE_RAW, &search_length); +#endif
if (search_length <= 0) - printk(BIOS_ERR, "LAN: VPD not found.\n"); + printk(BIOS_ERR, "LAN: find_fmap_entry returned -1.\n"); else get_mac_address(&high_dword, &low_dword, search_address, search_length); diff --git a/src/northbridge/intel/haswell/mrccache.c b/src/northbridge/intel/haswell/mrccache.c index d72c2c3..3bb7fa5 100644 --- a/src/northbridge/intel/haswell/mrccache.c +++ b/src/northbridge/intel/haswell/mrccache.c @@ -22,7 +22,6 @@ #include <bootstate.h> #include <console/console.h> #include <cbfs.h> -#include <fmap.h> #include <ip_checksum.h> #include <device/device.h> #include <cbmem.h> @@ -30,6 +29,9 @@ #include "haswell.h" #include <spi-generic.h> #include <spi_flash.h> +#if CONFIG_CHROMEOS +#include <vendorcode/google/chromeos/fmap.h> +#endif
/* convert a pointer to flash area into the offset inside the flash */ static inline u32 to_flash_offset(struct spi_flash *flash, void *p) { @@ -64,22 +66,16 @@ static int is_mrc_cache(struct mrc_data_container *mrc_cache) */ static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) { - size_t region_size = 0; - - if (IS_ENABLED(CONFIG_CHROMEOS)) { - struct region_device rdev; - - if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev) == 0) { - region_size = region_device_sz(&rdev); - *mrc_region_ptr = rdev_mmap_full(&rdev); - } - } else { - *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "mrc.cache", - CBFS_TYPE_MRC_CACHE, - ®ion_size); - } +#if CONFIG_CHROMEOS + return find_fmap_entry("RW_MRC_CACHE", (void **)mrc_region_ptr); +#else + size_t region_size; + *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, + "mrc.cache", + CBFS_TYPE_MRC_CACHE, + ®ion_size); return region_size; +#endif }
/* diff --git a/src/northbridge/intel/sandybridge/mrccache.c b/src/northbridge/intel/sandybridge/mrccache.c index e17c54b..e5f74e8 100644 --- a/src/northbridge/intel/sandybridge/mrccache.c +++ b/src/northbridge/intel/sandybridge/mrccache.c @@ -22,7 +22,6 @@ #include <bootstate.h> #include <console/console.h> #include <cbfs.h> -#include <fmap.h> #include <ip_checksum.h> #include <device/device.h> #include <cbmem.h> @@ -30,6 +29,9 @@ #include "sandybridge.h" #include <spi-generic.h> #include <spi_flash.h> +#if CONFIG_CHROMEOS +#include <vendorcode/google/chromeos/fmap.h> +#endif
/* convert a pointer to flash area into the offset inside the flash */ static inline u32 to_flash_offset(struct spi_flash *flash, void *p) { @@ -64,22 +66,17 @@ static int is_mrc_cache(struct mrc_data_container *mrc_cache) */ static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr) { - size_t region_size = 0; - - if (IS_ENABLED(CONFIG_CHROMEOS)) { - struct region_device rdev; - - if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev) == 0) { - region_size = region_device_sz(&rdev); - *mrc_region_ptr = rdev_mmap_full(&rdev); - } - } else { - *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, - "mrc.cache", - CBFS_TYPE_MRC_CACHE, - ®ion_size); - } +#if CONFIG_CHROMEOS + return find_fmap_entry("RW_MRC_CACHE", (void **)mrc_region_ptr); +#else + size_t region_size; + *mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, + "mrc.cache", + CBFS_TYPE_MRC_CACHE, + ®ion_size); return region_size; +#endif + }
/* diff --git a/src/soc/intel/common/mrc_cache.c b/src/soc/intel/common/mrc_cache.c index 6783f18..9366aa5 100644 --- a/src/soc/intel/common/mrc_cache.c +++ b/src/soc/intel/common/mrc_cache.c @@ -20,8 +20,10 @@ #include <string.h> #include <console/console.h> #include <cbmem.h> -#include <fmap.h> #include <ip_checksum.h> +#if CONFIG_CHROMEOS +#include <vendorcode/google/chromeos/fmap.h> +#endif #include "mrc_cache.h"
#define MRC_DATA_ALIGN 0x1000 @@ -37,23 +39,16 @@ struct mrc_data_region { /* common code */ static int mrc_cache_get_region(struct mrc_data_region *region) { - if (IS_ENABLED(CONFIG_CHROMEOS)) { - struct region_device rdev; - - if (fmap_locate_area_as_rdev("RW_MRC_CACHE", &rdev)) - return -1; - - region->size = region_device_sz(&rdev); - region->base = rdev_mmap_full(&rdev); - - if (region->base == NULL) - return -1; - +#if CONFIG_CHROMEOS + int ret; + ret = find_fmap_entry("RW_MRC_CACHE", ®ion->base); + if (ret >= 0) { + region->size = ret; return 0; - } else { - region->base = (void *)CONFIG_MRC_SETTINGS_CACHE_BASE; - region->size = CONFIG_MRC_SETTINGS_CACHE_SIZE; } +#endif + region->base = (void *)CONFIG_MRC_SETTINGS_CACHE_BASE; + region->size = CONFIG_MRC_SETTINGS_CACHE_SIZE; return 0; }
diff --git a/src/soc/nvidia/tegra124/Makefile.inc b/src/soc/nvidia/tegra124/Makefile.inc index 46ce59d..78054f4 100644 --- a/src/soc/nvidia/tegra124/Makefile.inc +++ b/src/soc/nvidia/tegra124/Makefile.inc @@ -2,6 +2,7 @@ ifeq ($(CONFIG_SOC_NVIDIA_TEGRA124),y)
bootblock-y += bootblock.c bootblock-y += bootblock_asm.S +bootblock-y += cbfs.c bootblock-y += clock.c bootblock-y += dma.c bootblock-y += i2c.c @@ -21,6 +22,7 @@ bootblock-$(CONFIG_DRIVERS_UART) += uart.c endif
verstage-y += verstage.c +verstage-y += cbfs.c verstage-y += dma.c verstage-y += monotonic_timer.c verstage-y += spi.c @@ -32,6 +34,7 @@ verstage-y += clock.c verstage-y += i2c.c verstage-y += cache.c
+romstage-y += cbfs.c romstage-y += cbmem.c romstage-y += clock.c romstage-y += dma.c @@ -48,6 +51,7 @@ romstage-y += ../tegra/pinmux.c romstage-y += cache.c romstage-$(CONFIG_DRIVERS_UART) += uart.c
+ramstage-y += cbfs.c ramstage-y += cbmem.c ramstage-y += clock.c ramstage-y += display.c diff --git a/src/soc/nvidia/tegra124/cbfs.c b/src/soc/nvidia/tegra124/cbfs.c new file mode 100644 index 0000000..d82ca9a --- /dev/null +++ b/src/soc/nvidia/tegra124/cbfs.c @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2013 Google Inc. + * + * 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. + */ + + +#include <cbfs.h> /* This driver serves as a CBFS media source. */ +#include <soc/spi.h> +#include <symbols.h> + +int init_default_cbfs_media(struct cbfs_media *media) +{ + return initialize_tegra_spi_cbfs_media(media, + _cbfs_cache, _cbfs_cache_size); +} diff --git a/src/soc/nvidia/tegra124/include/soc/spi.h b/src/soc/nvidia/tegra124/include/soc/spi.h index cfa3cd2..ab04632 100644 --- a/src/soc/nvidia/tegra124/include/soc/spi.h +++ b/src/soc/nvidia/tegra124/include/soc/spi.h @@ -61,6 +61,11 @@ struct tegra_spi_channel { enum spi_xfer_mode xfer_mode; };
+struct cbfs_media; +int initialize_tegra_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size); + struct tegra_spi_channel *tegra_spi_init(unsigned int bus);
#endif /* __NVIDIA_TEGRA124_SPI_H__ */ diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 0cf5495..683edd1 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -21,7 +21,6 @@ #include <arch/cache.h> #include <arch/io.h> #include <assert.h> -#include <boot_device.h> #include <console/console.h> #include <cbfs.h> #include <delay.h> @@ -34,7 +33,6 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <symbols.h> #include <timer.h>
@@ -802,6 +800,12 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return ret; }
+/* SPI as CBFS media. */ +struct tegra_spi_media { + struct spi_slave *slave; + struct cbfs_simple_buffer buffer; +}; + static int tegra_spi_cbfs_open(struct cbfs_media *media) { DEBUG_SPI("tegra_spi_cbfs_open\n"); @@ -819,17 +823,16 @@ static int tegra_spi_cbfs_close(struct cbfs_media *media) #define JEDEC_FAST_READ_DUAL 0x3b #define JEDEC_FAST_READ_DUAL_OUTSIZE 0x05
-static struct spi_slave *boot_slave; - -static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest, - size_t offset, size_t count) +static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest, + size_t offset, size_t count) { + struct tegra_spi_media *spi = (struct tegra_spi_media *)media->context; u8 spi_read_cmd[JEDEC_FAST_READ_DUAL_OUTSIZE]; unsigned int read_cmd_bytes; int ret = count; struct tegra_spi_channel *channel;
- channel = to_tegra_spi(boot_slave->bus); + channel = to_tegra_spi(spi->slave->bus);
if (channel->dual_mode) { /* @@ -850,9 +853,9 @@ static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest, spi_read_cmd[2] = (offset >> 8) & 0xff; spi_read_cmd[3] = offset & 0xff;
- spi_claim_bus(boot_slave); + spi_claim_bus(spi->slave);
- if (spi_xfer(boot_slave, spi_read_cmd, + if (spi_xfer(spi->slave, spi_read_cmd, read_cmd_bytes, NULL, 0) < 0) { ret = -1; printk(BIOS_ERR, "%s: Failed to transfer %u bytes\n", @@ -863,7 +866,7 @@ static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest, if (channel->dual_mode) { setbits_le32(&channel->regs->command1, SPI_CMD1_BOTH_EN_BIT); } - if (spi_xfer(boot_slave, NULL, 0, dest, count)) { + if (spi_xfer(spi->slave, NULL, 0, dest, count)) { ret = -1; printk(BIOS_ERR, "%s: Failed to transfer %u bytes\n", __func__, count); @@ -873,70 +876,56 @@ static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest,
tegra_spi_cbfs_read_exit: /* de-assert /CS */ - spi_release_bus(boot_slave); - return ret; -} - -static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - printk(BIOS_ERR, "%s: reading %zx bytes from %zx\n", - __func__, count, offset); - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; + spi_release_bus(spi->slave); + return (ret < 0) ? 0 : ret; }
static void *tegra_spi_cbfs_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; + struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context; void *map; - DEBUG_SPI("tegra_spi_cbfs_map\n"); - - boot_dev = media->context; - - map = rdev_mmap(boot_dev, offset, count); - - if (map == NULL) - map = (void *)-1; - + map = cbfs_simple_buffer_map(&spi->buffer, media, offset, count); return map; }
static void *tegra_spi_cbfs_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - + struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context; DEBUG_SPI("tegra_spi_cbfs_unmap\n"); - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; + return cbfs_simple_buffer_unmap(&spi->buffer, address); }
-int init_default_cbfs_media(struct cbfs_media *media) +int initialize_tegra_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size) { - DEBUG_SPI("Initializing CBFS media on SPI\n"); + // TODO Replace static variable to support multiple streams. + static struct tegra_spi_media context; + static struct tegra_spi_channel *channel; + + channel = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1]; + channel->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
- boot_device_init(); + DEBUG_SPI("Initializing CBFS media on SPI\n");
- media->context = (void *)boot_device_ro(); + context.slave = &channel->slave; + context.buffer.allocated = context.buffer.last_allocate = 0; + context.buffer.buffer = buffer_address; + context.buffer.size = buffer_size; + media->context = (void*)&context; media->open = tegra_spi_cbfs_open; media->close = tegra_spi_cbfs_close; media->read = tegra_spi_cbfs_read; media->map = tegra_spi_cbfs_map; media->unmap = tegra_spi_cbfs_unmap;
+#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1 + channel->dual_mode = 1; +#endif + return 0; }
@@ -948,32 +937,3 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
return &channel->slave; } - -static const struct region_device_ops tegra_spi_ops = { - .mmap = mmap_helper_rdev_mmap, - .munmap = mmap_helper_rdev_munmap, - .readat = tegra_spi_readat, -}; - -static struct mmap_helper_region_device mdev = - MMAP_HELPER_REGION_INIT(&tegra_spi_ops, 0, CONFIG_ROM_SIZE); - -const struct region_device *boot_device_ro(void) -{ - return &mdev.rdev; -} - -void boot_device_init(void) -{ - struct tegra_spi_channel *boot_chan; - - boot_chan = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1]; - boot_chan->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT; - -#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1 - boot_chan->dual_mode = 1; -#endif - boot_slave = &boot_chan->slave; - - mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size); -} diff --git a/src/soc/nvidia/tegra132/Makefile.inc b/src/soc/nvidia/tegra132/Makefile.inc index c192055..365dab3 100644 --- a/src/soc/nvidia/tegra132/Makefile.inc +++ b/src/soc/nvidia/tegra132/Makefile.inc @@ -2,6 +2,7 @@ ifeq ($(CONFIG_SOC_NVIDIA_TEGRA132),y)
bootblock-y += bootblock.c bootblock-y += bootblock_asm.S +bootblock-y += cbfs.c bootblock-y += clock.c bootblock-y += spi.c bootblock-y += i2c.c @@ -22,6 +23,7 @@ bootblock-$(CONFIG_DRIVERS_UART) += uart.c endif
verstage-y += verstage.c +verstage-y += cbfs.c verstage-y += dma.c verstage-y += monotonic_timer.c verstage-y += spi.c @@ -37,6 +39,7 @@ verstage-y += i2c.c romstage-y += 32bit_reset.S romstage-y += romstage_asm.S romstage-y += addressmap.c +romstage-y += cbfs.c romstage-y += cbmem.c romstage-y += ccplex.c romstage-y += clock.c @@ -60,6 +63,7 @@ romstage-$(CONFIG_DRIVERS_UART) += uart.c
ramstage-y += 32bit_reset.S ramstage-y += addressmap.c +ramstage-y += cbfs.c ramstage-y += cbmem.c ramstage-y += cpu.c ramstage-y += cpu_lib.S diff --git a/src/soc/nvidia/tegra132/cbfs.c b/src/soc/nvidia/tegra132/cbfs.c new file mode 100644 index 0000000..7aeb59b --- /dev/null +++ b/src/soc/nvidia/tegra132/cbfs.c @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2014 Google Inc. + * + * 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. + */ + +#include <cbfs.h> /* This driver serves as a CBFS media source. */ +#include <soc/spi.h> +#include <symbols.h> + +int init_default_cbfs_media(struct cbfs_media *media) +{ + return initialize_tegra_spi_cbfs_media(media, + _cbfs_cache, _cbfs_cache_size); +} diff --git a/src/soc/nvidia/tegra132/include/soc/spi.h b/src/soc/nvidia/tegra132/include/soc/spi.h index 4c91c27..2fd9562 100644 --- a/src/soc/nvidia/tegra132/include/soc/spi.h +++ b/src/soc/nvidia/tegra132/include/soc/spi.h @@ -62,6 +62,11 @@ struct tegra_spi_channel { enum spi_xfer_mode xfer_mode; };
+struct cbfs_media; +int initialize_tegra_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size); + struct tegra_spi_channel *tegra_spi_init(unsigned int bus);
#endif /* __NVIDIA_TEGRA132_SPI_H__ */ diff --git a/src/soc/nvidia/tegra132/spi.c b/src/soc/nvidia/tegra132/spi.c index 1650057..7ca66e1 100644 --- a/src/soc/nvidia/tegra132/spi.c +++ b/src/soc/nvidia/tegra132/spi.c @@ -21,7 +21,6 @@ #include <arch/cache.h> #include <arch/io.h> #include <assert.h> -#include <boot_device.h> #include <cbfs.h> #include <console/console.h> #include <delay.h> @@ -34,7 +33,6 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <symbols.h> #include <timer.h>
@@ -817,6 +815,12 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return ret; }
+/* SPI as CBFS media. */ +struct tegra_spi_media { + struct spi_slave *slave; + struct cbfs_simple_buffer buffer; +}; + static int tegra_spi_cbfs_open(struct cbfs_media *media) { DEBUG_SPI("tegra_spi_cbfs_open\n"); @@ -834,17 +838,16 @@ static int tegra_spi_cbfs_close(struct cbfs_media *media) #define JEDEC_FAST_READ_DUAL 0x3b #define JEDEC_FAST_READ_DUAL_OUTSIZE 0x05
-static struct spi_slave *boot_slave; - -static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest, - size_t offset, size_t count) +static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest, + size_t offset, size_t count) { + struct tegra_spi_media *spi = (struct tegra_spi_media *)media->context; u8 spi_read_cmd[JEDEC_FAST_READ_DUAL_OUTSIZE]; unsigned int read_cmd_bytes; int ret = count; struct tegra_spi_channel *channel;
- channel = to_tegra_spi(boot_slave->bus); + channel = to_tegra_spi(spi->slave->bus);
if (channel->dual_mode) { /* @@ -865,9 +868,9 @@ static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest, spi_read_cmd[2] = (offset >> 8) & 0xff; spi_read_cmd[3] = offset & 0xff;
- spi_claim_bus(boot_slave); + spi_claim_bus(spi->slave);
- if (spi_xfer(boot_slave, spi_read_cmd, + if (spi_xfer(spi->slave, spi_read_cmd, read_cmd_bytes, NULL, 0) < 0) { ret = -1; printk(BIOS_ERR, "%s: Failed to transfer %zu bytes\n", @@ -878,7 +881,7 @@ static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest, if (channel->dual_mode) { setbits_le32(&channel->regs->command1, SPI_CMD1_BOTH_EN_BIT); } - if (spi_xfer(boot_slave, NULL, 0, dest, count)) { + if (spi_xfer(spi->slave, NULL, 0, dest, count)) { ret = -1; printk(BIOS_ERR, "%s: Failed to transfer %zu bytes\n", __func__, count); @@ -888,70 +891,56 @@ static ssize_t tegra_spi_readat(const struct region_device *rdev, void *dest,
tegra_spi_cbfs_read_exit: /* de-assert /CS */ - spi_release_bus(boot_slave); - return ret; -} - -static size_t tegra_spi_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) -{ - const struct region_device *boot_dev; - - boot_dev = media->context; - - DEBUG_SPI("%s: reading %zx bytes from %zx\n", __func__, count, offset); - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; - - return count; + spi_release_bus(spi->slave); + return (ret < 0) ? 0 : ret; }
static void *tegra_spi_cbfs_map(struct cbfs_media *media, size_t offset, size_t count) { - const struct region_device *boot_dev; + struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context; void *map; - DEBUG_SPI("tegra_spi_cbfs_map\n"); - - boot_dev = media->context; - - map = rdev_mmap(boot_dev, offset, count); - - if (map == NULL) - map = (void *)-1; - + map = cbfs_simple_buffer_map(&spi->buffer, media, offset, count); return map; }
static void *tegra_spi_cbfs_unmap(struct cbfs_media *media, const void *address) { - const struct region_device *boot_dev; - + struct tegra_spi_media *spi = (struct tegra_spi_media*)media->context; DEBUG_SPI("tegra_spi_cbfs_unmap\n"); - - boot_dev = media->context; - - rdev_munmap(boot_dev, (void *)address); - - return NULL; + return cbfs_simple_buffer_unmap(&spi->buffer, address); }
-int init_default_cbfs_media(struct cbfs_media *media) +int initialize_tegra_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size) { - DEBUG_SPI("Initializing CBFS media on SPI\n"); + // TODO Replace static variable to support multiple streams. + static struct tegra_spi_media context; + static struct tegra_spi_channel *channel; + + channel = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1]; + channel->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT;
- boot_device_init(); + DEBUG_SPI("Initializing CBFS media on SPI\n");
- media->context = (void *)boot_device_ro(); + context.slave = &channel->slave; + context.buffer.allocated = context.buffer.last_allocate = 0; + context.buffer.buffer = buffer_address; + context.buffer.size = buffer_size; + media->context = (void*)&context; media->open = tegra_spi_cbfs_open; media->close = tegra_spi_cbfs_close; media->read = tegra_spi_cbfs_read; media->map = tegra_spi_cbfs_map; media->unmap = tegra_spi_cbfs_unmap;
+#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1 + channel->dual_mode = 1; +#endif + return 0; }
@@ -963,32 +952,3 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
return &channel->slave; } - -static const struct region_device_ops tegra_spi_ops = { - .mmap = mmap_helper_rdev_mmap, - .munmap = mmap_helper_rdev_munmap, - .readat = tegra_spi_readat, -}; - -static struct mmap_helper_region_device mdev = - MMAP_HELPER_REGION_INIT(&tegra_spi_ops, 0, CONFIG_ROM_SIZE); - -const struct region_device *boot_device_ro(void) -{ - return &mdev.rdev; -} - -void boot_device_init(void) -{ - struct tegra_spi_channel *boot_chan; - - boot_chan = &tegra_spi_channels[CONFIG_BOOT_MEDIA_SPI_BUS - 1]; - boot_chan->slave.cs = CONFIG_BOOT_MEDIA_SPI_CHIP_SELECT; - -#if CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B == 1 - boot_chan->dual_mode = 1; -#endif - boot_slave = &boot_chan->slave; - - mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size); -} diff --git a/src/soc/samsung/exynos5250/alternate_cbfs.c b/src/soc/samsung/exynos5250/alternate_cbfs.c index 546018a..2e2aeec 100644 --- a/src/soc/samsung/exynos5250/alternate_cbfs.c +++ b/src/soc/samsung/exynos5250/alternate_cbfs.c @@ -19,7 +19,6 @@
#include <assert.h> -#include <boot_device.h> #include <cbfs.h> /* This driver serves as a CBFS media source. */ #include <console/console.h> #include <soc/alternate_cbfs.h> @@ -46,7 +45,7 @@ * rest of the firmware's lifetime and all subsequent stages (which will not * have __PRE_RAM__ defined) can just directly reference it there. */ -static int usb_cbfs_open(void) +static int usb_cbfs_open(struct cbfs_media *media) { #ifdef __PRE_RAM__ static int first_run = 1; @@ -81,7 +80,7 @@ static int usb_cbfs_open(void) * this seems like a safer approach. It also makes it easy to pass our image * down to payloads. */ -static int sdmmc_cbfs_open(void) +static int sdmmc_cbfs_open(struct cbfs_media *media) { #ifdef __PRE_RAM__ /* @@ -112,109 +111,66 @@ static int sdmmc_cbfs_open(void) return 0; }
-static int exynos_cbfs_open(struct cbfs_media *media) { - return 0; -} - -static int exynos_cbfs_close(struct cbfs_media *media) { - return 0; -} - -static size_t exynos_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; +static int alternate_cbfs_close(struct cbfs_media *media) { return 0; }
+static size_t alternate_cbfs_read(struct cbfs_media *media, void *dest, + size_t offset, size_t count) +{ + ASSERT(offset + count < _cbfs_cache_size); + memcpy(dest, _cbfs_cache + offset, count); return count; }
-static void *exynos_cbfs_map(struct cbfs_media *media, size_t offset, - size_t count) { - const struct region_device *boot_dev; - void *ptr; - - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - - return ptr; +static void *alternate_cbfs_map(struct cbfs_media *media, size_t offset, + size_t count) +{ + ASSERT(offset + count < _cbfs_cache_size); + return _cbfs_cache + offset; }
-static void *exynos_cbfs_unmap(struct cbfs_media *media, - const void *address) { - const struct region_device *boot_dev; +static void *alternate_cbfs_unmap(struct cbfs_media *media, + const void *buffer) { return 0; }
- boot_dev = media->context; +static int initialize_exynos_sdmmc_cbfs_media(struct cbfs_media *media) +{ + printk(BIOS_DEBUG, "Using Exynos alternate boot mode SDMMC\n");
- rdev_munmap(boot_dev, (void *)address); + media->open = sdmmc_cbfs_open; + media->close = alternate_cbfs_close; + media->read = alternate_cbfs_read; + media->map = alternate_cbfs_map; + media->unmap = alternate_cbfs_unmap;
- return NULL; + return 0; }
-int init_default_cbfs_media(struct cbfs_media *media) +static int initialize_exynos_usb_cbfs_media(struct cbfs_media *media) { - boot_device_init(); + printk(BIOS_DEBUG, "Using Exynos alternate boot mode USB A-A\n");
- media->context = (void *)boot_device_ro(); - - if (media->context == NULL) - return -1; - - media->open = exynos_cbfs_open; - media->close = exynos_cbfs_close; - media->read = exynos_cbfs_read; - media->map = exynos_cbfs_map; - media->unmap = exynos_cbfs_unmap; + media->open = usb_cbfs_open; + media->close = alternate_cbfs_close; + media->read = alternate_cbfs_read; + media->map = alternate_cbfs_map; + media->unmap = alternate_cbfs_unmap;
return 0; }
-static struct mem_region_device alternate_rdev = MEM_REGION_DEV_INIT(NULL, 0); - -const struct region_device *boot_device_ro(void) +int init_default_cbfs_media(struct cbfs_media *media) { if (*iram_secondary_base == SECONDARY_BASE_BOOT_USB) - return &alternate_rdev.rdev; - - switch (exynos_power->om_stat & OM_STAT_MASK) { - case OM_STAT_SDMMC: - return &alternate_rdev.rdev; - case OM_STAT_SPI: - return exynos_spi_boot_device(); - default: - printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n", - exynos_power->om_stat); - return NULL; - } -} - -void boot_device_init(void) -{ - mem_region_device_init(&alternate_rdev, _cbfs_cache, _cbfs_cache_size); - - if (*iram_secondary_base == SECONDARY_BASE_BOOT_USB) { - printk(BIOS_DEBUG, "Using Exynos alternate boot mode USB A-A\n"); - usb_cbfs_open(); - return; - } + return initialize_exynos_usb_cbfs_media(media);
switch (exynos_power->om_stat & OM_STAT_MASK) { case OM_STAT_SDMMC: - printk(BIOS_DEBUG, "Using Exynos alternate boot mode SDMMC\n"); - sdmmc_cbfs_open(); - break; + return initialize_exynos_sdmmc_cbfs_media(media); case OM_STAT_SPI: - exynos_init_spi_boot_device(); - break; + return initialize_exynos_spi_cbfs_media(media, + _cbfs_cache, _cbfs_cache_size); default: printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n", exynos_power->om_stat); + return 1; } } diff --git a/src/soc/samsung/exynos5250/include/soc/spi.h b/src/soc/samsung/exynos5250/include/soc/spi.h index 298db1a..92236ae 100644 --- a/src/soc/samsung/exynos5250/include/soc/spi.h +++ b/src/soc/samsung/exynos5250/include/soc/spi.h @@ -20,7 +20,8 @@ #ifndef CPU_SAMSUNG_EXYNOS5250_SPI_H #define CPU_SAMSUNG_EXYNOS5250_SPI_H
-#include <boot_device.h> +/* This driver serves as a CBFS media source. */ +#include <cbfs.h>
/* SPI peripheral register map; padded to 64KB */ struct exynos_spi { @@ -91,6 +92,8 @@ int exynos_spi_open(struct exynos_spi *regs); int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off); int exynos_spi_close(struct exynos_spi *regs);
-void exynos_init_spi_boot_device(void); -const struct region_device *exynos_spi_boot_device(void); +/* Serve as CBFS media source */ +int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size); #endif diff --git a/src/soc/samsung/exynos5250/spi.c b/src/soc/samsung/exynos5250/spi.c index adf31e4..4f32487 100644 --- a/src/soc/samsung/exynos5250/spi.c +++ b/src/soc/samsung/exynos5250/spi.c @@ -20,13 +20,11 @@
#include <arch/io.h> #include <assert.h> -#include <boot_device.h> #include <console/console.h> #include <soc/clk.h> #include <soc/gpio.h> #include <soc/spi.h> #include <stdlib.h> -#include <symbols.h>
#if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI # define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "EXYNOS_SPI: " x) @@ -146,47 +144,70 @@ int exynos_spi_close(struct exynos_spi *regs) return 0; }
-static struct exynos_spi *boot_slave_regs; +// SPI as CBFS media. +struct exynos_spi_media { + struct exynos_spi *regs; + struct cbfs_simple_buffer buffer; +};
-static ssize_t exynos_spi_readat(const struct region_device *rdev, void *dest, - size_t offset, size_t count) -{ +static int exynos_spi_cbfs_open(struct cbfs_media *media) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + DEBUG_SPI("exynos_spi_cbfs_open\n"); + return exynos_spi_open(spi->regs); +} + +static int exynos_spi_cbfs_close(struct cbfs_media *media) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + DEBUG_SPI("exynos_spi_cbfs_close\n"); + return exynos_spi_close(spi->regs); +} + +static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest, + size_t offset, size_t count) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; int bytes; DEBUG_SPI("exynos_spi_cbfs_read(%u)\n", count); - exynos_spi_open(boot_slave_regs); - bytes = exynos_spi_read(boot_slave_regs, dest, count, offset); - exynos_spi_close(boot_slave_regs); + bytes = exynos_spi_read(spi->regs, dest, count, offset); + // Flush and re-open the device. + exynos_spi_close(spi->regs); + exynos_spi_open(spi->regs); return bytes; }
-static void *exynos_spi_map(const struct region_device *rdev, - size_t offset, size_t count) -{ +static void *exynos_spi_cbfs_map(struct cbfs_media *media, size_t offset, + size_t count) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; DEBUG_SPI("exynos_spi_cbfs_map\n"); - // exynos: spi_rx_tx may work in 4 byte-width-transmission mode and - // requires buffer memory address to be aligned. + // See exynos_spi_rx_tx for I/O alignment limitation. if (count % 4) count += 4 - (count % 4); - return mmap_helper_rdev_mmap(rdev, offset, count); + return cbfs_simple_buffer_map(&spi->buffer, media, offset, count); }
-static const struct region_device_ops exynos_spi_ops = { - .mmap = exynos_spi_map, - .munmap = mmap_helper_rdev_munmap, - .readat = exynos_spi_readat, -}; - -static struct mmap_helper_region_device mdev = - MMAP_HELPER_REGION_INIT(&exynos_spi_ops, 0, CONFIG_ROM_SIZE); - -void exynos_init_spi_boot_device(void) -{ - boot_slave_regs = (void *)EXYNOS5_SPI1_BASE; - - mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size); +static void *exynos_spi_cbfs_unmap(struct cbfs_media *media, + const void *address) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + DEBUG_SPI("exynos_spi_cbfs_unmap\n"); + return cbfs_simple_buffer_unmap(&spi->buffer, address); }
-const struct region_device *exynos_spi_boot_device(void) -{ - return &mdev.rdev; +int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size) { + // TODO Replace static variable to support multiple streams. + static struct exynos_spi_media context; + DEBUG_SPI("initialize_exynos_spi_cbfs_media\n"); + + context.regs = (void*)EXYNOS5_SPI1_BASE; + context.buffer.allocated = context.buffer.last_allocate = 0; + context.buffer.buffer = buffer_address; + context.buffer.size = buffer_size; + media->context = (void*)&context; + media->open = exynos_spi_cbfs_open; + media->close = exynos_spi_cbfs_close; + media->read = exynos_spi_cbfs_read; + media->map = exynos_spi_cbfs_map; + media->unmap = exynos_spi_cbfs_unmap; + + return 0; } diff --git a/src/soc/samsung/exynos5420/alternate_cbfs.c b/src/soc/samsung/exynos5420/alternate_cbfs.c index 9bba748..b30ed6b 100644 --- a/src/soc/samsung/exynos5420/alternate_cbfs.c +++ b/src/soc/samsung/exynos5420/alternate_cbfs.c @@ -20,7 +20,6 @@
#include <arch/cache.h> #include <assert.h> -#include <boot_device.h> #include <cbfs.h> /* This driver serves as a CBFS media source. */ #include <console/console.h> #include <soc/alternate_cbfs.h> @@ -47,7 +46,7 @@ * rest of the firmware's lifetime and all subsequent stages (which will not * have __PRE_RAM__ defined) can just directly reference it there. */ -static int usb_cbfs_open(void) +static int usb_cbfs_open(struct cbfs_media *media) { #ifdef __PRE_RAM__ static int first_run = 1; @@ -85,7 +84,7 @@ static int usb_cbfs_open(void) * this seems like a safer approach. It also makes it easy to pass our image * down to payloads. */ -static int sdmmc_cbfs_open(void) +static int sdmmc_cbfs_open(struct cbfs_media *media) { #ifdef __PRE_RAM__ /* @@ -119,109 +118,66 @@ static int sdmmc_cbfs_open(void) return 0; }
-static int exynos_cbfs_open(struct cbfs_media *media) { - return 0; -} - -static int exynos_cbfs_close(struct cbfs_media *media) { - return 0; -} - -static size_t exynos_cbfs_read(struct cbfs_media *media, void *dest, - size_t offset, size_t count) { - const struct region_device *boot_dev; - - boot_dev = media->context; - - if (rdev_readat(boot_dev, dest, offset, count) < 0) - return 0; +static int alternate_cbfs_close(struct cbfs_media *media) { return 0; }
+static size_t alternate_cbfs_read(struct cbfs_media *media, void *dest, + size_t offset, size_t count) +{ + ASSERT(offset + count < _cbfs_cache_size); + memcpy(dest, _cbfs_cache + offset, count); return count; }
-static void *exynos_cbfs_map(struct cbfs_media *media, size_t offset, - size_t count) { - const struct region_device *boot_dev; - void *ptr; - - boot_dev = media->context; - - ptr = rdev_mmap(boot_dev, offset, count); - - if (ptr == NULL) - return (void *)-1; - - return ptr; +static void *alternate_cbfs_map(struct cbfs_media *media, size_t offset, + size_t count) +{ + ASSERT(offset + count < _cbfs_cache_size); + return _cbfs_cache + offset; }
-static void *exynos_cbfs_unmap(struct cbfs_media *media, - const void *address) { - const struct region_device *boot_dev; +static void *alternate_cbfs_unmap(struct cbfs_media *media, + const void *buffer) { return 0; }
- boot_dev = media->context; +static int initialize_exynos_sdmmc_cbfs_media(struct cbfs_media *media) +{ + printk(BIOS_DEBUG, "Using Exynos alternate boot mode SDMMC\n");
- rdev_munmap(boot_dev, (void *)address); + media->open = sdmmc_cbfs_open; + media->close = alternate_cbfs_close; + media->read = alternate_cbfs_read; + media->map = alternate_cbfs_map; + media->unmap = alternate_cbfs_unmap;
- return NULL; + return 0; }
-int init_default_cbfs_media(struct cbfs_media *media) +static int initialize_exynos_usb_cbfs_media(struct cbfs_media *media) { - boot_device_init(); + printk(BIOS_DEBUG, "Using Exynos alternate boot mode USB A-A\n");
- media->context = (void *)boot_device_ro(); - - if (media->context == NULL) - return -1; - - media->open = exynos_cbfs_open; - media->close = exynos_cbfs_close; - media->read = exynos_cbfs_read; - media->map = exynos_cbfs_map; - media->unmap = exynos_cbfs_unmap; + media->open = usb_cbfs_open; + media->close = alternate_cbfs_close; + media->read = alternate_cbfs_read; + media->map = alternate_cbfs_map; + media->unmap = alternate_cbfs_unmap;
return 0; }
-static struct mem_region_device alternate_rdev = MEM_REGION_DEV_INIT(NULL, 0); - -const struct region_device *boot_device_ro(void) +int init_default_cbfs_media(struct cbfs_media *media) { if (*iram_secondary_base == SECONDARY_BASE_BOOT_USB) - return &alternate_rdev.rdev; - - switch (exynos_power->om_stat & OM_STAT_MASK) { - case OM_STAT_SDMMC: - return &alternate_rdev.rdev; - case OM_STAT_SPI: - return exynos_spi_boot_device(); - default: - printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n", - exynos_power->om_stat); - return NULL; - } -} - -void boot_device_init(void) -{ - mem_region_device_init(&alternate_rdev, _cbfs_cache, _cbfs_cache_size); - - if (*iram_secondary_base == SECONDARY_BASE_BOOT_USB) { - printk(BIOS_DEBUG, "Using Exynos alternate boot mode USB A-A\n"); - usb_cbfs_open(); - return; - } + return initialize_exynos_usb_cbfs_media(media);
switch (exynos_power->om_stat & OM_STAT_MASK) { case OM_STAT_SDMMC: - printk(BIOS_DEBUG, "Using Exynos alternate boot mode SDMMC\n"); - sdmmc_cbfs_open(); - break; + return initialize_exynos_sdmmc_cbfs_media(media); case OM_STAT_SPI: - exynos_init_spi_boot_device(); - break; + return initialize_exynos_spi_cbfs_media(media, + _cbfs_cache, _cbfs_cache_size); default: printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n", exynos_power->om_stat); + return 1; } } diff --git a/src/soc/samsung/exynos5420/include/soc/spi.h b/src/soc/samsung/exynos5420/include/soc/spi.h index 77d5ffc..cf77800 100644 --- a/src/soc/samsung/exynos5420/include/soc/spi.h +++ b/src/soc/samsung/exynos5420/include/soc/spi.h @@ -20,7 +20,8 @@ #ifndef CPU_SAMSUNG_EXYNOS5420_SPI_H #define CPU_SAMSUNG_EXYNOS5420_SPI_H
-#include <boot_device.h> +/* This driver serves as a CBFS media source. */ +#include <cbfs.h>
/* SPI peripheral register map; padded to 64KB */ struct exynos_spi { @@ -90,6 +91,8 @@ check_member(exynos_spi, fb_clk, 0x2c); #define SPI_RX_BYTE_SWAP (1 << 6) #define SPI_RX_HWORD_SWAP (1 << 7)
-void exynos_init_spi_boot_device(void); -const struct region_device *exynos_spi_boot_device(void); +/* Serve as CBFS media source */ +int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size); #endif diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index 2edc337..5f29803 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -26,7 +26,6 @@ #include <spi_flash.h> #include <stdlib.h> #include <string.h> -#include <symbols.h>
#define EXYNOS_SPI_MAX_TRANSFER_BYTES (65535)
@@ -243,43 +242,76 @@ static int exynos_spi_read(struct spi_slave *slave, void *dest, uint32_t len, return len; }
-static struct exynos_spi_slave *boot_slave; +// SPI as CBFS media. +struct exynos_spi_media { + struct spi_slave *slave; + struct cbfs_simple_buffer buffer; +}; + +static int exynos_spi_cbfs_open(struct cbfs_media *media) +{ + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + DEBUG_SPI("exynos_spi_cbfs_open\n"); + return spi_claim_bus(spi->slave); +} + +static int exynos_spi_cbfs_close(struct cbfs_media *media) +{ + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + DEBUG_SPI("exynos_spi_cbfs_close\n"); + spi_release_bus(spi->slave); + return 0; +}
-static ssize_t exynos_spi_readat(const struct region_device *rdev, void *dest, - size_t offset, size_t count) +static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest, + size_t offset, size_t count) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + int bytes; DEBUG_SPI("exynos_spi_cbfs_read(%u)\n", count); - return exynos_spi_read(&boot_slave->slave, dest, count, offset); + bytes = exynos_spi_read(spi->slave, dest, count, offset); + return bytes; }
-static void *exynos_spi_map(const struct region_device *rdev, - size_t offset, size_t count) +static void *exynos_spi_cbfs_map(struct cbfs_media *media, size_t offset, + size_t count) { + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; DEBUG_SPI("exynos_spi_cbfs_map\n"); // exynos: spi_rx_tx may work in 4 byte-width-transmission mode and // requires buffer memory address to be aligned. if (count % 4) count += 4 - (count % 4); - return mmap_helper_rdev_mmap(rdev, offset, count); + return cbfs_simple_buffer_map(&spi->buffer, media, offset, count); }
-static const struct region_device_ops exynos_spi_ops = { - .mmap = exynos_spi_map, - .munmap = mmap_helper_rdev_munmap, - .readat = exynos_spi_readat, -}; - -static struct mmap_helper_region_device mdev = - MMAP_HELPER_REGION_INIT(&exynos_spi_ops, 0, CONFIG_ROM_SIZE); - -void exynos_init_spi_boot_device(void) +static void *exynos_spi_cbfs_unmap(struct cbfs_media *media, + const void *address) { - boot_slave = &exynos_spi_slaves[1]; - - mmap_helper_device_init(&mdev, _cbfs_cache, _cbfs_cache_size); + struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; + DEBUG_SPI("exynos_spi_cbfs_unmap\n"); + return cbfs_simple_buffer_unmap(&spi->buffer, address); }
-const struct region_device *exynos_spi_boot_device(void) +int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, + void *buffer_address, + size_t buffer_size) { - return &mdev.rdev; + // TODO Replace static variable to support multiple streams. + static struct exynos_spi_media context; + static struct exynos_spi_slave *eslave = &exynos_spi_slaves[1]; + DEBUG_SPI("initialize_exynos_spi_cbfs_media\n"); + + context.slave = &eslave->slave; + context.buffer.allocated = context.buffer.last_allocate = 0; + context.buffer.buffer = buffer_address; + context.buffer.size = buffer_size; + media->context = (void*)&context; + media->open = exynos_spi_cbfs_open; + media->close = exynos_spi_cbfs_close; + media->read = exynos_spi_cbfs_read; + media->map = exynos_spi_cbfs_map; + media->unmap = exynos_spi_cbfs_unmap; + + return 0; } diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig index 0b0b862..0fc0d54 100644 --- a/src/vendorcode/google/chromeos/Kconfig +++ b/src/vendorcode/google/chromeos/Kconfig @@ -94,6 +94,15 @@ config CHROMEOS_RAMOOPS_RAM_SIZE default 0x00100000 depends on CHROMEOS_RAMOOPS
+config FLASHMAP_OFFSET + hex "Flash Map Offset" + default 0x00670000 if NORTHBRIDGE_INTEL_SANDYBRIDGE + default 0x00610000 if NORTHBRIDGE_INTEL_IVYBRIDGE + default CBFS_SIZE if !ARCH_X86 + default 0 + help + Offset of flash map in firmware image + config EC_SOFTWARE_SYNC bool "Enable EC software sync" default n diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc index df24435..6e416ee 100644 --- a/src/vendorcode/google/chromeos/Makefile.inc +++ b/src/vendorcode/google/chromeos/Makefile.inc @@ -34,7 +34,11 @@ ramstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c
ramstage-$(CONFIG_ELOG) += elog.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += gnvs.c +verstage-y += fmap.c +romstage-y += fmap.c +ramstage-y += fmap.c ramstage-$(CONFIG_CHROMEOS_RAMOOPS) += ramoops.c +smm-y += fmap.c romstage-y += vpd_decode.c cros_vpd.c ramstage-y += vpd_decode.c cros_vpd.c vpd_mac.c vpd_serialno.c vpd_calibration.c ifeq ($(CONFIG_ARCH_X86)$(CONFIG_ARCH_MIPS),) diff --git a/src/vendorcode/google/chromeos/cros_vpd.c b/src/vendorcode/google/chromeos/cros_vpd.c index fed1d82..c0e4830 100644 --- a/src/vendorcode/google/chromeos/cros_vpd.c +++ b/src/vendorcode/google/chromeos/cros_vpd.c @@ -6,11 +6,12 @@
#include <console/console.h>
-#include <fmap.h> +#include <cbfs.h> #include <stdlib.h> #include <string.h>
#include "cros_vpd.h" +#include "fmap.h" #include "lib_vpd.h" #include "vpd_tables.h"
@@ -34,7 +35,9 @@ static int cros_vpd_load(uint8_t **vpd_address, int32_t *vpd_size) MAYBE_STATIC int result = -1; struct google_vpd_info info; int32_t base; - struct region_device vpd; + + const struct fmap_area *area; + struct cbfs_media media;
if (cached) { *vpd_address = cached_address; @@ -43,31 +46,32 @@ static int cros_vpd_load(uint8_t **vpd_address, int32_t *vpd_size) }
cached = 1; - if (fmap_locate_area_as_rdev("RO_VPD", &vpd)) { + area = find_fmap_area(fmap_find(), "RO_VPD"); + if (!area) { printk(BIOS_ERR, "%s: No RO_VPD FMAP section.\n", __func__); return result; } - - base = 0; - cached_size = region_device_sz(&vpd); - - if ((cached_size < GOOGLE_VPD_2_0_OFFSET + sizeof(info)) || - rdev_chain(&vpd, &vpd, GOOGLE_VPD_2_0_OFFSET, - cached_size - GOOGLE_VPD_2_0_OFFSET)) { + if (area->size <= GOOGLE_VPD_2_0_OFFSET + sizeof(info)) { printk(BIOS_ERR, "%s: Too small (%d) for Google VPD 2.0.\n", - __func__, cached_size); + __func__, area->size); return result; }
+ base = area->offset + GOOGLE_VPD_2_0_OFFSET; + cached_size = area->size - GOOGLE_VPD_2_0_OFFSET; + init_default_cbfs_media(&media); + media.open(&media); + /* Try if we can find a google_vpd_info, otherwise read whole VPD. */ - if (rdev_readat(&vpd, &info, base, sizeof(info)) == sizeof(info) && + if (media.read(&media, &info, base, sizeof(info)) == sizeof(info) && memcmp(info.header.magic, VPD_INFO_MAGIC, sizeof(info.header.magic)) == 0 && cached_size >= info.size + sizeof(info)) { base += sizeof(info); cached_size = info.size; }
- cached_address = rdev_mmap(&vpd, base, cached_size); + cached_address = media.map(&media, base, cached_size); + media.close(&media); if (cached_address) { *vpd_address = cached_address; *vpd_size = cached_size; diff --git a/src/vendorcode/google/chromeos/fmap.h b/src/vendorcode/google/chromeos/fmap.h new file mode 100644 index 0000000..05d3fb6 --- /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_REVERSED_SIGNATURE "__PAMF__" /* avoid magic number in .rodata */ +#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__*/ diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c index 955d72f..6b3d7dc 100644 --- a/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c +++ b/src/vendorcode/google/chromeos/vboot2/vboot_handoff.c @@ -26,13 +26,13 @@ #include <cbmem.h> #include <console/console.h> #include <console/vtxprintf.h> -#include <fmap.h> #include <stdlib.h> #include <timestamp.h> #define NEED_VB20_INTERNALS /* TODO: remove me! */ #include <vb2_api.h> #include <vboot_struct.h> #include "../chromeos.h" +#include "../fmap.h" #include "../vboot_handoff.h" #include "misc.h"