summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-03-10 13:51:38 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-03-12 00:48:20 +0000
commit07d3b69413317e75b54ee768cd60c5b7582c403b (patch)
treea71eac4b589e4603d636169ac665bbb2d418e148
parent27199e7b64659a2db7114c670b903578858f8d50 (diff)
downloadchrome-ec-07d3b69413317e75b54ee768cd60c5b7582c403b.tar.gz
mec1322: Add flash physical interface functions
Add physical flash interface for read / write / protection of external SPI on mec1322. BUG=chrome-os-partner:36167 TEST=Manual on glower: flashread 0xf000 0x200 --> dumps 0xff flashwrite 0xf000 0x200 flashread 0xf000 0x200 --> dumps write pattern flasherase 0xf000 0x1000 flashread 0xf000 0x200 --> dumps 0xff spi_flash_prot 0 0x10000 flashinfo --> shows first 64KB protected spi_flashwrite 0xf000 0x200 --> access denied spi_flashwrite 0x1f000 0x200 --> OK flashread 0x1f000 0x200 --> dumps write pattern BRANCH=None Change-Id: I2cb20a49934999fc0dd9b3425eb99708711637c5 Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/257132 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--board/glower/board.h7
-rw-r--r--board/mec1322_evb/board.h2
-rw-r--r--board/mec1322_evb/gpio.inc2
-rw-r--r--board/strago/board.h2
-rw-r--r--board/strago/gpio.inc1
-rw-r--r--chip/mec1322/build.mk1
-rw-r--r--chip/mec1322/config_chip.h49
-rw-r--r--chip/mec1322/flash.c227
-rw-r--r--chip/mec1322/system.c12
9 files changed, 282 insertions, 21 deletions
diff --git a/board/glower/board.h b/board/glower/board.h
index 0f021a6261..a755ddbd83 100644
--- a/board/glower/board.h
+++ b/board/glower/board.h
@@ -49,10 +49,15 @@
#define CONFIG_WATCHDOG_HELP
#define CONFIG_CLOCK_CRYSTAL
#define CONFIG_WAKE_PIN GPIO_POWER_BUTTON_L
+
+/* 512kb SPI flash */
+#define CONFIG_SPI_FLASH_SIZE 0x00080000
+#define CONFIG_SPI_FLASH_W25X40
#define CONFIG_SPI_PORT 1
#define CONFIG_SPI_CS_GPIO GPIO_PVT_CS0
-#undef CONFIG_CONSOLE_CMDHELP
+#define CONFIG_CMD_FLASH
+#define CONFIG_CMD_SPI_FLASH
#undef CONFIG_TASK_PROFILING
/* Modules we want to exclude */
diff --git a/board/mec1322_evb/board.h b/board/mec1322_evb/board.h
index eccd28a76e..e75f53e62e 100644
--- a/board/mec1322_evb/board.h
+++ b/board/mec1322_evb/board.h
@@ -14,6 +14,8 @@
#define CONFIG_FANS 1
#define CONFIG_ADC
#define CONFIG_WAKE_PIN GPIO_S1
+#define CONFIG_SPI_FLASH_SIZE 0x00800000
+#define CONFIG_SPI_FLASH_W25Q64
#define CONFIG_SPI_PORT 0
#define CONFIG_SPI_CS_GPIO GPIO_SHD_CS0
diff --git a/board/mec1322_evb/gpio.inc b/board/mec1322_evb/gpio.inc
index 35baf9c77d..64e4024ef9 100644
--- a/board/mec1322_evb/gpio.inc
+++ b/board/mec1322_evb/gpio.inc
@@ -22,7 +22,7 @@ GPIO(SHD_CS0, PORT(15), 0, GPIO_ODR_HIGH, NULL)
* emulate anyway, to make it more convenient to debug other code.
*/
UNIMPLEMENTED(RECOVERY_L) /* Recovery signal from DOWN button */
-UNIMPLEMENTED(WP) /* Write protect input */
+UNIMPLEMENTED(WP_L) /* Write protect input */
UNIMPLEMENTED(ENTERING_RW) /* EC entering RW code */
ALTERNATE(PORT(16), 0x24, 1, MODULE_UART, 0) /* UART0 */
diff --git a/board/strago/board.h b/board/strago/board.h
index 6f67928ed4..aa34254306 100644
--- a/board/strago/board.h
+++ b/board/strago/board.h
@@ -23,13 +23,13 @@
#define CONFIG_POWER_COMMON
#define CONFIG_EXTPOWER_GPIO
-#define CONFIG_SPI
#define CONFIG_SPI_PORT 1
#define CONFIG_SPI_CS_GPIO GPIO_PVT_CS0
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_SIZE 4194304
/* TODO: Add flash protect support for the SPI part strago actually has */
#define CONFIG_SPI_FLASH_W25Q64
+
/* Modules we want to exclude */
#undef CONFIG_EEPROM
#undef CONFIG_EOPTION
diff --git a/board/strago/gpio.inc b/board/strago/gpio.inc
index 3244f6fc63..d2c1c99fee 100644
--- a/board/strago/gpio.inc
+++ b/board/strago/gpio.inc
@@ -37,6 +37,7 @@ GPIO(PVT_CS0, PORT(14), 6, GPIO_ODR_HIGH, NU
* emulate anyway, to make it more convenient to debug other code.
*/
UNIMPLEMENTED(ENTERING_RW) /* EC entering RW code */
+UNIMPLEMENTED(WP_L) /* SPI WP Input */
/* Alternate functions GPIO definition */
ALTERNATE(PORT(16), 0x24, 1, MODULE_UART, 0) /* UART0 */
diff --git a/chip/mec1322/build.mk b/chip/mec1322/build.mk
index abd69b227d..9c9ecd16b5 100644
--- a/chip/mec1322/build.mk
+++ b/chip/mec1322/build.mk
@@ -15,6 +15,7 @@ CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4
chip-y=clock.o gpio.o hwtimer.o system.o uart.o jtag.o
chip-$(CONFIG_ADC)+=adc.o
chip-$(CONFIG_FANS)+=fan.o
+chip-$(CONFIG_FLASH)+=flash.o
chip-$(CONFIG_I2C)+=i2c.o
chip-$(CONFIG_LPC)+=lpc.o
chip-$(CONFIG_PWM)+=pwm.o
diff --git a/chip/mec1322/config_chip.h b/chip/mec1322/config_chip.h
index 9a0d770f50..797a895c3e 100644
--- a/chip/mec1322/config_chip.h
+++ b/chip/mec1322/config_chip.h
@@ -47,25 +47,36 @@
/* Default task stack size */
#define TASK_STACK_SIZE 512
-#define CONFIG_FLASH_BASE 0x00100000
+/****************************************************************************/
+/* Define our flash layout. */
+/* Protect bank size 4K bytes */
+#define CONFIG_FLASH_BANK_SIZE 0x00001000
+/* Sector erase size 4K bytes */
+#define CONFIG_FLASH_ERASE_SIZE 0x00001000
+/* Minimum write size */
+#define CONFIG_FLASH_WRITE_SIZE 0x00000004
-#define CONFIG_FLASH_PHYSICAL_SIZE 0x00018000
+/* One page size for write */
+#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256
-/* Size of one firmware image in RAM */
+/* 96KB flash used for program memory */
+#define CONFIG_FLASH_PHYSICAL_SIZE 0x00018000
+/* Program memory base address */
+#define CONFIG_FLASH_BASE 0x00100000
-/****************************************************************************/
-/* Define our flash layout. */
+#define CONFIG_CDRAM_BASE 0x00100000
+#define CONFIG_CDRAM_SIZE 0x00020000
/* 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 (CONFIG_FLASH_PHYSICAL_SIZE / 2)
#endif
/* RO firmware must start at beginning of flash */
-#define CONFIG_FW_RO_OFF 0
+#define CONFIG_FW_RO_OFF 0
-#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
/*
* TODO(crosbug.com/p/37510): Implement a loader to load either RO or RW at
@@ -73,14 +84,18 @@
* 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
+#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
+#define CONFIG_FW_WP_RO_OFF CONFIG_FW_RO_OFF
+#define CONFIG_FW_WP_RO_SIZE CONFIG_FW_RO_SIZE
-#define CONFIG_FLASH_BANK_SIZE 4
+/* Non-memmapped, external SPI */
+/* #define CONFIG_CODERAM_ARCH */
+#undef CONFIG_FLASH_MAPPED
+#undef CONFIG_FLASH_PSTATE
+#define CONFIG_SPI_FLASH
/****************************************************************************/
/* Customize the build */
@@ -91,12 +106,10 @@
#define CONFIG_SWITCH
#define CONFIG_MPU
#endif
+#define CONFIG_DMA
+#define CONFIG_FPU
#define CONFIG_I2C
#define CONFIG_LPC
-#define CONFIG_FPU
#define CONFIG_SPI
-#define CONFIG_DMA
-
-#undef CONFIG_FLASH
#endif /* __CROS_EC_CONFIG_CHIP_H */
diff --git a/chip/mec1322/flash.c b/chip/mec1322/flash.c
new file mode 100644
index 0000000000..fb6f56fc48
--- /dev/null
+++ b/chip/mec1322/flash.c
@@ -0,0 +1,227 @@
+/* Copyright 2015 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 "common.h"
+#include "console.h"
+#include "flash.h"
+#include "host_command.h"
+#include "shared_mem.h"
+#include "spi.h"
+#include "spi_flash.h"
+#include "system.h"
+#include "util.h"
+#include "watchdog.h"
+
+#define PAGE_SIZE 256
+
+/**
+ * Read from physical flash.
+ *
+ * @param offset Flash offset to write.
+ * @param size Number of bytes to write.
+ * @param data Destination buffer for data. Must be 32-bit aligned.
+ */
+int flash_physical_read(int offset, int size, char *data)
+{
+ int ret;
+
+ /* Fail if offset, size, and data aren't at least word-aligned */
+ if ((offset | size | (uint32_t)(uintptr_t)data) & 3)
+ return EC_ERROR_INVAL;
+
+ spi_enable(1);
+ ret = spi_flash_read((uint8_t *)data, offset, size);
+ spi_enable(0);
+ return ret;
+}
+
+/**
+ * Write to physical flash.
+ *
+ * Offset and size must be a multiple of CONFIG_FLASH_WRITE_SIZE.
+ *
+ * @param offset Flash offset to write.
+ * @param size Number of bytes to write.
+ * @param data Data to write to flash. Must be 32-bit aligned.
+ */
+int flash_physical_write(int offset, int size, const char *data)
+{
+ int ret, i, write_size;
+
+ /* Fail if offset, size, and data aren't at least word-aligned */
+ if ((offset | size | (uint32_t)(uintptr_t)data) & 3)
+ return EC_ERROR_INVAL;
+
+ spi_enable(1);
+ for (i = 0; i < size; i += write_size) {
+ write_size = MIN(size, SPI_FLASH_MAX_WRITE_SIZE);
+ ret = spi_flash_write(offset + i,
+ write_size,
+ (uint8_t *)data + i);
+ if (ret != EC_SUCCESS)
+ break;
+ /* BUG: Multi-page writes fail if no delay */
+ msleep(1);
+ }
+ spi_enable(0);
+ return ret;
+}
+
+/**
+ * Erase physical flash.
+ *
+ * Offset and size must be a multiple of CONFIG_FLASH_ERASE_SIZE.
+ *
+ * @param offset Flash offset to erase.
+ * @param size Number of bytes to erase.
+ */
+int flash_physical_erase(int offset, int size)
+{
+ int ret;
+
+ spi_enable(1);
+ ret = spi_flash_erase(offset, size);
+ spi_enable(0);
+ return ret;
+}
+
+/**
+ * Read physical write protect setting for a flash bank.
+ *
+ * @param bank Bank index to check.
+ * @return non-zero if bank is protected until reboot.
+ */
+int flash_physical_get_protect(int bank)
+{
+ uint32_t addr = bank * CONFIG_FLASH_BANK_SIZE;
+ int ret;
+
+ spi_enable(1);
+ ret = spi_flash_check_protect(addr, CONFIG_FLASH_BANK_SIZE);
+ spi_enable(0);
+ return ret;
+}
+
+/**
+ * Protect flash now.
+ *
+ * @param all Protect all (=1) or just read-only and pstate (=0).
+ * @return non-zero if error.
+ */
+int flash_physical_protect_now(int all)
+{
+ int offset, size, ret;
+
+ if (all) {
+ offset = 0;
+ size = CONFIG_FLASH_PHYSICAL_SIZE;
+ } else {
+ offset = CONFIG_FW_RO_OFF;
+ size = CONFIG_FW_RO_SIZE;
+ }
+
+ spi_enable(1);
+ ret = spi_flash_set_protect(offset, size);
+ spi_enable(0);
+ return ret;
+}
+
+/**
+ * Return flash protect state flags from the physical layer.
+ *
+ * This should only be called by flash_get_protect().
+ *
+ * Uses the EC_FLASH_PROTECT_* flags from ec_commands.h
+ */
+uint32_t flash_physical_get_protect_flags(void)
+{
+ uint32_t flags = 0;
+
+ spi_enable(1);
+ if (spi_flash_check_protect(CONFIG_FW_RO_OFF, CONFIG_FW_RO_SIZE)) {
+ flags |= EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RO_NOW;
+ if (spi_flash_check_protect(CONFIG_FW_RW_OFF,
+ CONFIG_FW_RW_SIZE))
+ flags |= EC_FLASH_PROTECT_ALL_NOW;
+ }
+ spi_enable(0);
+ return flags;
+}
+
+/**
+ * Return the valid flash protect flags.
+ *
+ * @return A combination of EC_FLASH_PROTECT_* flags from ec_commands.h
+ */
+uint32_t flash_physical_get_valid_flags(void)
+{
+ return EC_FLASH_PROTECT_RO_AT_BOOT |
+ EC_FLASH_PROTECT_RO_NOW |
+ EC_FLASH_PROTECT_ALL_NOW;
+}
+
+/**
+ * Return the writable flash protect flags.
+ *
+ * @param cur_flags The current flash protect flags.
+ * @return A combination of EC_FLASH_PROTECT_* flags from ec_commands.h
+ */
+uint32_t flash_physical_get_writable_flags(uint32_t cur_flags)
+{
+ uint32_t ret = 0;
+ enum spi_flash_wp wp_status = spi_flash_check_wp();
+
+ if (wp_status == SPI_WP_NONE || (wp_status == SPI_WP_HARDWARE &&
+ !(cur_flags & EC_FLASH_PROTECT_GPIO_ASSERTED)))
+ ret = EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RO_NOW |
+ EC_FLASH_PROTECT_ALL_NOW;
+
+ return ret;
+}
+
+/**
+ * Enable write protect for the specified range.
+ *
+ * Once write protect is enabled, it will STAY enabled until the system is
+ * hard-rebooted with the hardware write protect pin deasserted. If the write
+ * protect pin is deasserted, the protect setting is ignored, and the entire
+ * flash will be writable.
+ *
+ * @param range The range to protect.
+ * @return EC_SUCCESS, or nonzero if error.
+ */
+int flash_physical_protect_at_boot(enum flash_wp_range range)
+{
+ int offset, size, ret;
+
+ switch (range) {
+ case FLASH_WP_NONE:
+ offset = size = 0;
+ break;
+ case FLASH_WP_RO:
+ offset = CONFIG_FW_RO_OFF;
+ size = CONFIG_FW_RO_SIZE;
+ break;
+ case FLASH_WP_ALL:
+ offset = 0;
+ size = CONFIG_FLASH_PHYSICAL_SIZE;
+ break;
+ }
+
+ spi_enable(1);
+ ret = spi_flash_set_protect(offset, size);
+ spi_enable(0);
+ return ret;
+}
+
+/**
+ * Initialize the module.
+ *
+ * Applies at-boot protection settings if necessary.
+ */
+int flash_pre_init(void)
+{
+ return EC_SUCCESS;
+}
diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c
index e682852935..b94e93ff07 100644
--- a/chip/mec1322/system.c
+++ b/chip/mec1322/system.c
@@ -369,3 +369,15 @@ void htimer_interrupt(void)
/* Time to wake up */
}
DECLARE_IRQ(MEC1322_IRQ_HTIMER, htimer_interrupt, 1);
+
+/* TODO(crosbug.com/p/37510): Implement bootloader */
+enum system_image_copy_t system_get_shrspi_image_copy(void)
+{
+ return SYSTEM_IMAGE_RW;
+}
+
+/* TODO(crosbug.com/p/37510): Implement bootloader */
+uint32_t system_get_lfw_address(uint32_t flash_addr)
+{
+ return CONFIG_FW_RO_OFF;
+}