diff options
author | Bill Richardson <wfrichar@chromium.org> | 2012-04-27 10:23:14 -0700 |
---|---|---|
committer | Bill Richardson <wfrichar@chromium.org> | 2012-05-01 15:54:39 -0700 |
commit | 8d921af0bb4f189c10d11bb0bfce286fb92d348c (patch) | |
tree | 31dd1245146630cf90d10bdb96ef8013236ecaf0 | |
parent | a5027ece4cb02a736db3db1e971bffd699422dec (diff) | |
download | chrome-ec-8d921af0bb4f189c10d11bb0bfce286fb92d348c.tar.gz |
Add basic FMAP to EC firmware image.
This is very basic, so you can only rely on RO_SECTION, RW_SECTION_A, and
RW_SECTION_B for now. We'll fill in more regions as we add vboot stuff.
Still, you should be able to do things like this:
flashrom -p internal:bus=lpc -r ec.bin
flashrom -p internal:bus=lpc -w ec.bin -i RW_SECTION:ec.B.flat
BUG=chrome-os-partner:8198
TEST=manual
Build the image, look for the FMAP in it.
cd src/platform/ec
make BOARD=link
dump_fmap ./build/link/ec.bin
Change-Id: I0adbbfb8e975faae805bda271873fcef46590cf4
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | Makefile.rules | 2 | ||||
-rw-r--r-- | chip/lm4/config.h | 9 | ||||
-rw-r--r-- | common/build.mk | 2 | ||||
-rw-r--r-- | common/firmware_image.lds.S | 10 | ||||
-rw-r--r-- | common/fmap.c | 152 | ||||
-rw-r--r-- | core/cortex-m/ec.lds.S | 13 |
6 files changed, 184 insertions, 4 deletions
diff --git a/Makefile.rules b/Makefile.rules index 647a7b27c3..ea7a961777 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -15,6 +15,7 @@ _dir_create := $(foreach d,$(dirs),$(shell [ -d $(out)/$(d) ] || \ mkdir -p $(out)/$(d))) section = $(subst .,,$(suffix $(1))) +section_is = $(subst .,,SECTION_IS_$(suffix $(1))) # Decrease verbosity unless you pass V=1 quiet = $(if $(V),,@echo ' $(2)' $(subst $(out)/,,$@) ; )$(cmd_$(1)) @@ -22,6 +23,7 @@ silent = $(if $(V),,1>/dev/null) # commands to build all targets cmd_lds = $(CPP) -P -C -MMD -MF $@.d -MT $@ $(CPPFLAGS) \ + -D$(call section_is,$*) \ -DSECTION=$(call section,$*) $< -o $@ cmd_obj_to_bin = $(OBJCOPY) --gap-fill=0xff -O binary $^ $@ cmd_flat_to_obj = $(CC) -T $(out)/firmware_image.lds -nostdlib $(CPPFLAGS) \ diff --git a/chip/lm4/config.h b/chip/lm4/config.h index 387671c22e..bb82dd7b31 100644 --- a/chip/lm4/config.h +++ b/chip/lm4/config.h @@ -22,6 +22,15 @@ #define CONFIG_FW_A_OFF CONFIG_FW_IMAGE_SIZE #define CONFIG_FW_B_OFF (2 * CONFIG_FW_IMAGE_SIZE) +/* FIXME(wfrichar): Replace with real GBB size & location. */ +#define CONFIG_FW_RO_GBB_SIZE CONFIG_FLASH_BANK_SIZE +#define CONFIG_FW_RO_GBB_OFF (CONFIG_FW_RO_OFF + CONFIG_FW_IMAGE_SIZE - \ + CONFIG_FW_RO_GBB_SIZE) +#define CONFIG_FW_RO_SIZE (CONFIG_FW_IMAGE_SIZE - CONFIG_FW_RO_GBB_SIZE) +#define CONFIG_FW_A_SIZE CONFIG_FW_IMAGE_SIZE +#define CONFIG_FW_B_SIZE CONFIG_FW_IMAGE_SIZE + + /* Number of IRQ vectors on the NVIC */ #define CONFIG_IRQ_COUNT 132 diff --git a/common/build.mk b/common/build.mk index 6595e5d263..2c32fc292e 100644 --- a/common/build.mk +++ b/common/build.mk @@ -7,7 +7,7 @@ common-y=main.o message.o util.o console.o vboot.o uart_buffering.o common-y+=memory_commands.o shared_mem.o system_common.o hooks.o -common-y+=gpio_commands.o version.o +common-y+=gpio_commands.o version.o fmap.o common-$(CONFIG_BATTERY_ATL706486)+=battery_atl706486.o common-$(CONFIG_CHARGER_BQ24725)+=charger_bq24725.o common-$(CONFIG_EOPTION)+=eoption.o diff --git a/common/firmware_image.lds.S b/common/firmware_image.lds.S index c282e7ac28..3b2ef7f561 100644 --- a/common/firmware_image.lds.S +++ b/common/firmware_image.lds.S @@ -16,15 +16,19 @@ SECTIONS . = ALIGN(CONFIG_FLASH_BANK_SIZE); .image.RO : AT(CONFIG_FW_RO_OFF) { *(.image.RO) - } > FLASH + } > FLASH =0xff . = ALIGN(CONFIG_FLASH_BANK_SIZE); .image.A : AT(CONFIG_FW_A_OFF) { *(.image.A) - } > FLASH + } > FLASH =0xff #ifndef CONFIG_NO_RW_B . = ALIGN(CONFIG_FLASH_BANK_SIZE); .image.B : AT(CONFIG_FW_B_OFF) { *(.image.B) - } > FLASH + } > FLASH =0xff #endif + /* NOTE: EC implementation reserves one bank for itself */ + .padding : AT(CONFIG_FLASH_SIZE - CONFIG_FLASH_BANK_SIZE - 1) { + BYTE(0xff); + } > FLASH =0xff } diff --git a/common/fmap.c b/common/fmap.c new file mode 100644 index 0000000000..8ee698d615 --- /dev/null +++ b/common/fmap.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdint.h> +#include "config.h" + +/* FMAP structs. See http://code.google.com/p/flashmap/wiki/FmapSpec */ +#define FMAP_NAMELEN 32 +#define FMAP_SIGNATURE "__FMAP__" +#define FMAP_SIGNATURE_SIZE 8 +#define FMAP_VER_MAJOR 1 +#define FMAP_VER_MINOR 0 +#define FMAP_SEARCH_STRIDE 64 /* Spec revision 1.01 */ + +typedef struct _FmapHeader { + char fmap_signature[FMAP_SIGNATURE_SIZE]; + uint8_t fmap_ver_major; + uint8_t fmap_ver_minor; + uint64_t fmap_base; + uint32_t fmap_size; + char fmap_name[FMAP_NAMELEN]; + uint16_t fmap_nareas; +} __attribute__((packed)) FmapHeader; + +#define FMAP_AREA_STATIC (1 << 0) /* can be checksummed */ +#define FMAP_AREA_COMPRESSED (1 << 1) /* may be compressed */ +#define FMAP_AREA_RO (1 << 2) /* writes may fail */ + +typedef struct _FmapAreaHeader { + uint32_t area_offset; + uint32_t area_size; + char area_name[FMAP_NAMELEN]; + uint16_t area_flags; +} __attribute__((packed)) FmapAreaHeader; + + +#define NUM_EC_FMAP_AREAS 14 + +const struct _ec_fmap { + FmapHeader header; + FmapAreaHeader area[NUM_EC_FMAP_AREAS]; +} ec_fmap __attribute__((section(".google"))) = { + /* Header */ + { + .fmap_signature = {'_', '_', 'F', 'M', 'A', 'P', '_', '_'}, + .fmap_ver_major = FMAP_VER_MAJOR, + .fmap_ver_minor = FMAP_VER_MINOR, + .fmap_base = CONFIG_FLASH_BASE, + .fmap_size = CONFIG_FLASH_SIZE, + .fmap_name = "EC_FMAP", + .fmap_nareas = NUM_EC_FMAP_AREAS, + }, + + { + /* RO Firmware */ + { + .area_name = "RO_SECTION", + .area_offset = CONFIG_FW_RO_OFF, + .area_size = CONFIG_FW_IMAGE_SIZE, + .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO, + }, + { + .area_name = "BOOT_STUB", + .area_offset = CONFIG_FW_RO_OFF, + .area_size = CONFIG_FW_RO_SIZE, + .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO, + }, + { + .area_name = "RO_FRID", /* FIXME: Where is it? */ + .area_offset = CONFIG_FW_RO_OFF, + .area_size = 0, + .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO, + }, + + /* Other RO stuff: FMAP, GBB, etc. */ + { + /* FIXME(wfrichar): GBB != FMAP. Use the right terms */ + .area_name = "FMAP", + .area_offset = CONFIG_FW_RO_GBB_OFF, + .area_size = CONFIG_FW_RO_GBB_SIZE, + .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO, + }, + { + .area_name = "GBB", + .area_offset = CONFIG_FW_RO_GBB_OFF, + .area_size = 0, + .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO, + }, + { + /* A dummy region to identify it as EC firmware */ + .area_name = "EC_IMAGE", + .area_offset = CONFIG_FW_RO_GBB_OFF, + .area_size = 0, /* Always zero */ + .area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO, + }, + + /* Firmware A */ + { + .area_name = "RW_SECTION_A", + .area_offset = CONFIG_FW_A_OFF, + .area_size = CONFIG_FW_IMAGE_SIZE, + .area_flags = FMAP_AREA_STATIC, + }, + { + .area_name = "FW_MAIN_A", + .area_offset = CONFIG_FW_A_OFF, + .area_size = CONFIG_FW_IMAGE_SIZE, + .area_flags = FMAP_AREA_STATIC, + }, + { + .area_name = "RW_FWID_A", /* FIXME: Where is it? */ + .area_offset = CONFIG_FW_A_OFF, + .area_size = 0, + .area_flags = FMAP_AREA_STATIC, + }, + { + .area_name = "VBLOCK_A", + .area_offset = CONFIG_FW_A_OFF, + .area_size = 0, + .area_flags = FMAP_AREA_STATIC, + }, + + /* Firmware B */ + { + .area_name = "RW_SECTION_B", + .area_offset = CONFIG_FW_B_OFF, + .area_size = CONFIG_FW_IMAGE_SIZE, + .area_flags = FMAP_AREA_STATIC, + }, + { + .area_name = "FW_MAIN_B", + .area_offset = CONFIG_FW_B_OFF, + .area_size = CONFIG_FW_IMAGE_SIZE, + .area_flags = FMAP_AREA_STATIC, + }, + { + .area_name = "RW_FWID_B", /* FIXME: Where is it? */ + .area_offset = CONFIG_FW_B_OFF, + .area_size = 0, + .area_flags = FMAP_AREA_STATIC, + }, + { + .area_name = "VBLOCK_B", + .area_offset = CONFIG_FW_A_OFF, + .area_size = 0, + .area_flags = FMAP_AREA_STATIC, + }, + } +}; diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S index 32114b59da..00e7cf9e68 100644 --- a/core/cortex-m/ec.lds.S +++ b/core/cortex-m/ec.lds.S @@ -78,6 +78,18 @@ SECTIONS . = ALIGN(4); __data_end = .; } > IRAM +#ifdef SECTION_IS_RO + .google CONFIG_FW_RO_GBB_OFF : AT(CONFIG_FW_RO_GBB_OFF) { + *(.google) + . += 16; + } > FLASH + ASSERT(SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.data) + SIZEOF(.google) + <= CONFIG_FW_IMAGE_SIZE, "Too much stuff to fit in the image") +#else + /DISCARD/ : { + *(.google) + } +#endif .bss : { . = ALIGN(4); __bss_start = .; @@ -89,5 +101,6 @@ SECTIONS * can expand to use all the remaining RAM. */ __shared_mem_buf = .; } > IRAM + /DISCARD/ : { *(.ARM.*) } } |