diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-03-10 13:51:38 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-03-12 00:48:20 +0000 |
commit | 07d3b69413317e75b54ee768cd60c5b7582c403b (patch) | |
tree | a71eac4b589e4603d636169ac665bbb2d418e148 /chip/mec1322 | |
parent | 27199e7b64659a2db7114c670b903578858f8d50 (diff) | |
download | chrome-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.mk | 1 | ||||
-rw-r--r-- | chip/mec1322/config_chip.h | 49 | ||||
-rw-r--r-- | chip/mec1322/flash.c | 227 | ||||
-rw-r--r-- | chip/mec1322/system.c | 12 |
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; +} |