diff options
-rw-r--r-- | board/glower/board.h | 7 | ||||
-rw-r--r-- | board/mec1322_evb/board.h | 2 | ||||
-rw-r--r-- | board/mec1322_evb/gpio.inc | 2 | ||||
-rw-r--r-- | board/strago/board.h | 2 | ||||
-rw-r--r-- | board/strago/gpio.inc | 1 | ||||
-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 |
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; +} |