summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivya Jyothi <divya.jyothi@intel.com>2015-04-16 21:34:20 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-04-23 07:04:41 +0000
commit9aea3710b22a5e235ddd03a62daa0d60dc913aa9 (patch)
treeb761ef6c4ee75bfa7e3c846a8ad1998e444aefe0
parent19a201dd949863e0c8a99da71b14fb6f40d846b8 (diff)
downloadchrome-ec-9aea3710b22a5e235ddd03a62daa0d60dc913aa9.tar.gz
mec1322: lfw loader + RO/RW architecture
mec1322 only has 96KB program memory, vs 256KB flash space on lm4.We no longer have enough program memory to load both RO and RW at boot. We'll want to implement a small loader program that will load either RO or RW from flash, and then jump to the loaded image. CONFIG_FW_INCLUDE_RO is enabled to include RO image into the build. pack.py script is altered to load the (lfw + R)O on boot. Software sync is not added.Distinguish between RO/RW is yet to be added. flash_ec is altered to support padding 0xFFs to 256k ec.bin to match the size of the SPI flash of the board. BUG=chromium:37510 BRANCH=None TEST=Make -j buildall,Verified ec.bin to be 256k. Verified RW image at offset 0h and (lfw + RO) at offset 2000h. On boot sysjump to lfw. lfw checks in shared SRAM (currently RO) and jumps to RO image. Change-Id: Ib9b114e2f24a615d5e5bd8b3803be621d1e5bd17 Signed-off-by: Divya Jyothi <divya.jyothi@intel.com> Reviewed-on: https://chromium-review.googlesource.com/265807 Reviewed-by: Shawn N <shawnn@chromium.org> Reviewed-by: Icarus W Sparry <icarus.w.sparry@intel.com>
-rw-r--r--chip/mec1322/build.mk7
-rw-r--r--chip/mec1322/config_chip.h96
-rwxr-xr-xchip/mec1322/util/pack_ec.py85
-rw-r--r--common/firmware_image.lds.S7
-rwxr-xr-xutil/flash_ec65
5 files changed, 185 insertions, 75 deletions
diff --git a/chip/mec1322/build.mk b/chip/mec1322/build.mk
index 2d49949e4f..109bb05dd2 100644
--- a/chip/mec1322/build.mk
+++ b/chip/mec1322/build.mk
@@ -33,9 +33,10 @@ CHIP_SPI_SIZE_KB?=256
# Commands to convert $^ to $@.tmp
cmd_obj_to_bin = $(OBJCOPY) --gap-fill=0xff -O binary $< $@.tmp1 ; \
${SCRIPTDIR}/pack_ec.py -o $@.tmp -i $@.tmp1 \
- --payload_key ${SCRIPTDIR}/rsakey_sign_payload.pem \
- --header_key ${SCRIPTDIR}/rsakey_sign_header.pem \
- --spi_size ${CHIP_SPI_SIZE_KB} ; rm -f $@.tmp1
+ --loader_file $(mec1322-lfw-flat) \
+ --payload_key ${SCRIPTDIR}/rsakey_sign_payload.pem \
+ --header_key ${SCRIPTDIR}/rsakey_sign_header.pem \
+ --spi_size ${CHIP_SPI_SIZE_KB} ; rm -f $@.tmp1
mec1322-lfw = chip/mec1322/lfw/ec_lfw
mec1322-lfw-flat = $(out)/$(mec1322-lfw)-lfw.flat
diff --git a/chip/mec1322/config_chip.h b/chip/mec1322/config_chip.h
index b02fdc2242..8129ee469c 100644
--- a/chip/mec1322/config_chip.h
+++ b/chip/mec1322/config_chip.h
@@ -36,12 +36,35 @@
/* Memory mapping */
/*
- * The memory region for RAM is actually 0x00100000-0x00120000. The lower 96K
- * stores code and the higher 32K stores data. To reflect this, let's say
- * the lower 96K is flash, and the higher 32K is RAM.
+ * The memory region for RAM is actually 0x00100000-0x00120000.
+ * RAM for Loader = 2k
+ * RAM for RO/RW = 24k
+ * CODE size of the Loader is 4k
+ * As per the above configuartion the upper 26k
+ * is used to store data.The rest is for code.
+ * the lower 100K is flash[ 4k Loader and 96k RO/RW],
+ * and the higher 26K is RAM shared by loader and RO/RW.
*/
-#define CONFIG_RAM_BASE 0x00118000
-#define CONFIG_RAM_SIZE 0x00008000
+
+/****************************************************************************/
+/* Define our RAM layout. */
+
+#define CONFIG_MEC_SRAM_BASE_START 0x00100000
+#define CONFIG_MEC_SRAM_BASE_END 0x00120000
+#define CONFIG_MEC_SRAM_SIZE (CONFIG_MEC_SRAM_BASE_END - \
+ CONFIG_MEC_SRAM_BASE_START)
+
+/* 2k RAM for Loader */
+#define CONFIG_RAM_SIZE_LOADER 0x00000800
+/* 24k RAM for RO /RW */
+#define CONFIG_RAM_SIZE_RORW 0x00006000
+
+#define CONFIG_RAM_SIZE_TOTAL (CONFIG_RAM_SIZE_LOADER + \
+ CONFIG_RAM_SIZE_RORW)
+#define CONFIG_RAM_BASE_RORW (CONFIG_MEC_SRAM_BASE_END - \
+ CONFIG_RAM_SIZE_TOTAL)
+#define CONFIG_RAM_BASE CONFIG_RAM_BASE_RORW
+#define CONFIG_RAM_SIZE CONFIG_RAM_SIZE_TOTAL
/* System stack size */
#define CONFIG_STACK_SIZE 4096
@@ -65,32 +88,47 @@
/* One page size for write */
#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256
-/* 96KB flash used for program memory */
-#define CONFIG_FLASH_PHYSICAL_SIZE 0x00018000
+/* Loader code Image size 4k*/
+#define CONFIG_LOADER_IMAGE_SIZE 0x00001000
+
+/* Independent of the Flash Physical size of the board
+256KB Max size used. Located at the top most segment */
+#define CONFIG_FLASH_PHYSICAL_SIZE 0x00040000
+
/* Program memory base address */
#define CONFIG_FLASH_BASE 0x00100000
#define CONFIG_CDRAM_BASE 0x00100000
#define CONFIG_CDRAM_SIZE 0x00020000
+#define CONFIG_FW_LOADER_OFF 0
+#define CONFIG_FW_LOADER_SIZE CONFIG_LOADER_IMAGE_SIZE
+
/* Size of one firmware image in flash */
#ifndef CONFIG_FW_IMAGE_SIZE
-#define CONFIG_FW_IMAGE_SIZE (CONFIG_FLASH_PHYSICAL_SIZE / 2)
+#define CONFIG_FW_IMAGE_SIZE (96 * 1024)
#endif
-/* RO firmware must start at beginning of flash */
-#define CONFIG_FW_RO_OFF 0
+/* RO/RW firmware must be after Loader code */
+#define CONFIG_FW_RO_OFF CONFIG_FW_LOADER_SIZE
+
+#define CONFIG_FW_RO_SIZE CONFIG_FW_IMAGE_SIZE
+#define CONFIG_FLASH_SIZE CONFIG_FLASH_PHYSICAL_SIZE
-#define CONFIG_FW_RO_SIZE CONFIG_FW_IMAGE_SIZE
-#define CONFIG_FLASH_SIZE CONFIG_FLASH_PHYSICAL_SIZE
+#define CONFIG_FW_INCLUDE_RO
+#define CONFIG_FW_RW_OFF CONFIG_FW_RO_OFF
+#define CONFIG_FW_RW_SIZE CONFIG_FW_RO_SIZE
+/* Write protect Loader and RO Image */
+#define CONFIG_FW_WP_RO_OFF CONFIG_FW_LOADER_OFF
+/* Write protect 128k section of 256k physical flash
+which contains Loader and RO Images */
+#define CONFIG_FW_WP_RO_SIZE (CONFIG_FLASH_PHYSICAL_SIZE >> 1)
/****************************************************************************/
/* SPI Flash Memory Mapping */
-/*
- * Size of total image used ( 256k = lfw + RSA Keys + RO + RW images)
- * located at the end of the flash.
- */
+/* Size of tolal image used ( 256k = lfw + RSA Keys + RO + RW images)
+ located at the end of the flash */
#define CONFIG_FLASH_BASE_SPI (CONFIG_SPI_FLASH_SIZE - (0x40000))
#define CONFIG_RO_WP_SPI_OFF 0x20000
@@ -100,29 +138,14 @@
CONFIG_RO_SPI_OFF)
#define CONFIG_RW_IMAGE_FLASHADDR (CONFIG_FLASH_BASE_SPI + \
CONFIG_RW_SPI_OFF)
-/* Memory Location shared between lfw and RO/RW image */
-/*
- * TODO(crosbug.com/p/37510): Alter to the right value when lfw + Ro/RW
- * architecture is enabled.
- */
-#define SHARED_RAM_LFW_RORW 0
+/* Memory Lcation shared between lfw and RO/RWimage */
+#define SHARED_RAM_LFW_RORW (CONFIG_MEC_SRAM_BASE_START + \
+ (CONFIG_LOADER_IMAGE_SIZE - 4))
-/*
- * TODO(crosbug.com/p/37510): Implement a lfw to load either RO or RW at
- * runtime. Since this doesn't exist yet and we're running low on program
- * memory, only flash + load RW for now.
- */
-#undef CONFIG_FW_INCLUDE_RO
-#define CONFIG_FW_RW_OFF CONFIG_FW_RO_OFF
-#define CONFIG_FW_RW_SIZE CONFIG_FLASH_PHYSICAL_SIZE
-
-/* TODO(crosbug.com/p/23796): why 2 sets of configs with the same numbers? */
-#define CONFIG_FW_WP_RO_OFF CONFIG_FW_RO_OFF
-#define CONFIG_FW_WP_RO_SIZE CONFIG_FW_RO_SIZE
/* Non-memmapped, external SPI */
-/* #define CONFIG_CODERAM_ARCH */
-#undef CONFIG_FLASH_MAPPED
+/* #define CONFIG_CODERAM_ARCH
+#undef CONFIG_FLASH_MAPPED*/
#undef CONFIG_FLASH_PSTATE
#define CONFIG_SPI_FLASH
@@ -142,3 +165,4 @@
#define CONFIG_SWITCH
#endif /* __CROS_EC_CONFIG_CHIP_H */
+
diff --git a/chip/mec1322/util/pack_ec.py b/chip/mec1322/util/pack_ec.py
index de7dbee5c8..c96aa41f6d 100755
--- a/chip/mec1322/util/pack_ec.py
+++ b/chip/mec1322/util/pack_ec.py
@@ -18,6 +18,7 @@ LOAD_ADDR = 0x100000
HEADER_SIZE = 0x140
SPI_CLOCK_LIST = [48, 24, 12, 8]
SPI_READ_CMD_LIST = [0x3, 0xb, 0x3b]
+IMAGE_SIZE = 96 * 1024
CRC_TABLE = [0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d]
@@ -37,15 +38,20 @@ def GetEntryPoint(payload_file):
s = f.read(4)
return struct.unpack('<I', s)[0]
-def GetPayload(payload_file):
+def GetPayloadFromOffset(payload_file,offset):
"""Read payload and pad it to 64-byte aligned."""
with open(payload_file, 'rb') as f:
+ f.seek(offset)
payload = bytearray(f.read())
rem_len = len(payload) % 64
if rem_len:
payload += '\0' * (64 - rem_len)
return payload
+def GetPayload(payload_file):
+ """Read payload and pad it to 64-byte aligned."""
+ return GetPayloadFromOffset(payload_file, 0)
+
def GetPublicKey(pem_file):
"""Extract public exponent and modulus from PEM file."""
s = subprocess.check_output(['openssl', 'rsa', '-in', pem_file,
@@ -79,7 +85,7 @@ def GetSpiReadCmdParameter(args):
def PadZeroTo(data, size):
data.extend('\0' * (size - len(data)))
-def BuildHeader(args, payload_len):
+def BuildHeader(args, payload_len, rorofile):
# Identifier and header version
header = bytearray(['C', 'S', 'M', 'S', '\0'])
@@ -88,7 +94,7 @@ def BuildHeader(args, payload_len):
header.append(GetSpiReadCmdParameter(args))
header.extend(struct.pack('<I', LOAD_ADDR))
- header.extend(struct.pack('<I', GetEntryPoint(args.input)))
+ header.extend(struct.pack('<I', GetEntryPoint(rorofile)))
header.append((payload_len >> 6) & 0xff)
header.append((payload_len >> 14) & 0xff)
PadZeroTo(header, 0x14)
@@ -127,8 +133,24 @@ def BuildTag(args):
tag.append(Crc8(0, tag))
return tag
-
-def main():
+def PacklfwRoImage(rorw_file, loader_file):
+ """TODO:Clean up to get rid of Temp file and just use memory
+ to save data"""
+ """Create a temp file with the
+ first IMAGE_SIZE bytes from the rorw file and the
+ bytes from the loader_file appended
+ return the filename"""
+ fo=tempfile.NamedTemporaryFile(delete=False) # Need to keep file around
+ with open(loader_file,'rb') as fin1:
+ pro = fin1.read()
+ fo.write(pro)
+ with open(rorw_file, 'rb') as fin:
+ ro = fin.read(IMAGE_SIZE)
+ fo.write(ro)
+ fo.close()
+ return fo.name
+
+def parseargs():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input",
help="EC binary to pack, usually ec.bin or ec.RO.flat.",
@@ -142,15 +164,24 @@ def main():
parser.add_argument("--payload_key",
help="PEM key file for signing payload",
default="rsakey_sign_payload.pem")
+ parser.add_argument("--loader_file",
+ help="EC loader binary",
+ default="ecloader.bin")
parser.add_argument("-s", "--spi_size", type=int,
- help="Size of the SPI flash in KB",
- default=4096)
+ help="Size of the SPI flash in MB",
+ default=4)
parser.add_argument("-l", "--header_loc", type=int,
help="Location of header in SPI flash",
- default=0)
+ default=0x170000)
parser.add_argument("-p", "--payload_offset", type=int,
help="The offset of payload from the header",
default=0x240)
+ parser.add_argument("-r", "--rwpayload_loc", type=int,
+ help="The offset of payload from the header",
+ default=0x190000)
+ parser.add_argument("-z", "--romstart", type=int,
+ help="The first location to output of the rom",
+ default=0)
parser.add_argument("-c", "--chip_select", type=int,
help="Chip select signal to use, either 0 or 1.",
default=0)
@@ -160,29 +191,49 @@ def main():
parser.add_argument("--spi_read_cmd", type=int,
help="SPI read command. 0x3, 0xB, or 0x3B.",
default=0xb)
- args = parser.parse_args()
+ return parser.parse_args()
+
+# Debug helper routine
+def dumpsects(spi_list):
+ for s in spi_list:
+ print "%x %d %s\n"%(s[0],len(s[1]),s[2])
+
+def main():
+ args = parseargs()
spi_size = args.spi_size * 1024
+ args.header_loc = spi_size - (128 * 1024)
+ args.rwpayload_loc = spi_size - (256 * 1024)
+ args.romstart = spi_size - (256 * 1024)
+
spi_list = []
- payload = GetPayload(args.input)
+ rorofile=PacklfwRoImage(args.input, args.loader_file)
+ payload = GetPayload(rorofile)
payload_len = len(payload)
+ #print payload_len
payload_signature = SignByteArray(payload, args.payload_key)
- header = BuildHeader(args, payload_len)
+ header = BuildHeader(args, payload_len, rorofile)
header_signature = SignByteArray(header, args.header_key)
tag = BuildTag(args)
+ # truncate the RW to 128k
+ payloadrw = GetPayloadFromOffset(args.input,IMAGE_SIZE)[:128*1024]
+ os.remove(rorofile) # clean up the temp file
- spi_list.append((args.header_loc, header))
- spi_list.append((args.header_loc + HEADER_SIZE, header_signature))
- spi_list.append((args.header_loc + args.payload_offset, payload))
+ spi_list.append((args.header_loc, header, "header"))
+ spi_list.append((args.header_loc + HEADER_SIZE, header_signature, "header_signature"))
+ spi_list.append((args.header_loc + args.payload_offset, payload, "payload"))
spi_list.append((args.header_loc + args.payload_offset + payload_len,
- payload_signature))
- spi_list.append((spi_size - 256, tag))
+ payload_signature, "payload_signature"))
+ spi_list.append((spi_size - 256, tag, "tag"))
+ spi_list.append((args.rwpayload_loc, payloadrw, "payloadrw"))
+
spi_list = sorted(spi_list)
+ #dumpsects(spi_list)
with open(args.output, 'wb') as f:
- addr = 0
+ addr = args.romstart
for s in spi_list:
assert addr <= s[0]
if addr < s[0]:
diff --git a/common/firmware_image.lds.S b/common/firmware_image.lds.S
index e2de7a2c1c..e17e25546a 100644
--- a/common/firmware_image.lds.S
+++ b/common/firmware_image.lds.S
@@ -18,7 +18,14 @@ SECTIONS
*(.image.RO)
} > FLASH =0xff
. = ALIGN(CONFIG_FLASH_BANK_SIZE);
+#if (CONFIG_FW_RO_OFF == CONFIG_FW_RW_OFF)
+/* This is applicable to ECs in which RO and RW execution is
+mapped to the same location but we still have to generate an ec.bin with RO
+and RW images at different Flash offset */
+ .image.RW : AT(CONFIG_FLASH_BASE + CONFIG_FW_RO_OFF + CONFIG_FW_RO_SIZE) {
+#else
.image.RW : AT(CONFIG_FLASH_BASE + CONFIG_FW_RW_OFF) {
+#endif
*(.image.RW)
} > FLASH =0xff
.padding : AT(CONFIG_FLASH_BASE + CONFIG_FLASH_SIZE - 1) {
diff --git a/util/flash_ec b/util/flash_ec
index aca12e8fc7..db83d69d7c 100755
--- a/util/flash_ec
+++ b/util/flash_ec
@@ -82,13 +82,6 @@ BOARDS_STM32=(
spring
zinger
)
-
-BOARDS_PRIVATE_SPI_PP3300=(
- cyan
- glower
- strago
-)
-
BOARDS_STM32_PROG_EN=(
plankton
)
@@ -103,6 +96,12 @@ BOARDS_NPCX=(
npcx_evb
)
+BOARDS_MEC1322=(
+ cyan
+ glower
+ strago
+)
+
# Flags
DEFINE_string board "${DEFAULT_BOARD}" \
"The board to run debugger on."
@@ -221,9 +220,7 @@ BOARD=${FLAGS_board}
BOARD_ROOT=/build/${BOARD}
# Possible default EC images
-if $(in_array "${BOARDS_PRIVATE_SPI_PP3300[@]}" "${BOARD}"); then
- EC_FILE=ec.spi.bin
-elif [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then
+if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then
EC_FILE=ec.RO.flat
else
EC_FILE=ec.bin
@@ -288,9 +285,6 @@ if [[ "${MCU}" == "usbpd" ]] ; then
servo_VARS+=" prog_en"
fi
fi
-if $(in_array "${BOARDS_PRIVATE_SPI_PP3300[@]}" "${BOARD}"); then
- servo_VARS+=" spi1_buf_en spi1_buf_on_flex_en spi_hold"
-fi
toad_VARS="${MCU}_uart_parity \
${MCU}_uart_baudrate boot_mode"
@@ -468,10 +462,43 @@ function flash_npcx() {
fi
}
-function flash_private_spi_pp3300() {
- dut_control cold_reset:on spi1_vref:pp3300
- dut_control spi1_buf_en:on spi1_buf_on_flex_en:on spi_hold:off
- sudo flashrom -p ft2232_spi:type=servo-v2,port=B -w "${IMG}"
+function flash_mec1322() {
+ TOOL_PATH="${EC_DIR}/build/${BOARD}/util:/usr/sbin/:$PATH"
+ FLASHROM=$(PATH="${TOOL_PATH}" which flashrom)
+ FLASHROM_PARAM="-p ft2232_spi:type=servo-v2,port=B"
+
+ if [ ! -x "$FLASHROM" ]; then
+ die "no flashrom util found."
+ fi
+
+ dut_control cold_reset:on
+
+ # Turn on SPI1 interface on servo for 3.3V SPI Flash Chip
+ dut-control spi1_vref:pp3300 spi1_buf_en:on spi1_buf_on_flex_en:on
+
+ SPI_SIZE=$(sudo ${FLASHROM} ${FLASHROM_PARAM} --get-size 2>/dev/null | tail -n 1)
+ IMG_SIZE=$(stat -c%s "$IMG")
+ PATCH_SIZE=$((${SPI_SIZE} - ${IMG_SIZE}))
+
+ # Temp image
+ T=/tmp/flash_mec_$$
+
+ { # Patch temp image up to SPI_SIZE
+ if [[ ${IMG_SIZE} -lt ${SPI_SIZE} ]] ; then
+ dd if=/dev/zero bs=${PATCH_SIZE} count=1 | tr '\0' '\377'
+ fi
+ cat $IMG
+ } > $T
+
+ sudo ${FLASHROM} ${FLASHROM_PARAM} -w "${T}"
+
+ rm $T
+
+ # Turn off SPI1 interface on servo
+ dut_control spi1_vref:off spi1_buf_en:off spi1_buf_on_flex_en:off
+
+ # Do not save/restore servo settings
+ save=
}
if dut_control boot_mode 2>/dev/null ; then
@@ -505,8 +532,8 @@ elif [ "${BOARD}" == "link" ]; then
flash_link
elif $(in_array "${BOARDS_NPCX[@]}" "${BOARD}"); then
flash_npcx
-elif $(in_array "${BOARDS_PRIVATE_SPI_PP3300[@]}" "${BOARD}"); then
- flash_private_spi_pp3300
+elif $(in_array "${BOARDS_MEC1322[@]}" "${BOARD}"); then
+ flash_mec1322
else
die "board ${BOARD} not supported"
fi