mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
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>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
27199e7b64
commit
07d3b69413
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,25 +47,36 @@
|
||||
/* Default task stack size */
|
||||
#define TASK_STACK_SIZE 512
|
||||
|
||||
#define CONFIG_FLASH_BASE 0x00100000
|
||||
|
||||
#define CONFIG_FLASH_PHYSICAL_SIZE 0x00018000
|
||||
|
||||
/* Size of one firmware image in RAM */
|
||||
|
||||
/****************************************************************************/
|
||||
/* 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
|
||||
|
||||
/* One page size for write */
|
||||
#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256
|
||||
|
||||
/* 96KB flash used for program memory */
|
||||
#define CONFIG_FLASH_PHYSICAL_SIZE 0x00018000
|
||||
/* Program memory base address */
|
||||
#define CONFIG_FLASH_BASE 0x00100000
|
||||
|
||||
#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 */
|
||||
|
||||
227
chip/mec1322/flash.c
Normal file
227
chip/mec1322/flash.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user