summaryrefslogtreecommitdiff
path: root/chip/mec1322
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 /chip/mec1322
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>
Diffstat (limited to 'chip/mec1322')
-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
4 files changed, 271 insertions, 18 deletions
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;
+}