summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.rules2
-rw-r--r--chip/lm4/config.h9
-rw-r--r--common/build.mk2
-rw-r--r--common/firmware_image.lds.S10
-rw-r--r--common/fmap.c152
-rw-r--r--core/cortex-m/ec.lds.S13
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.*) }
}