diff options
-rw-r--r-- | chip/g/system.c | 4 | ||||
-rw-r--r-- | chip/host/system.c | 4 | ||||
-rw-r--r-- | chip/ish/system.c | 6 | ||||
-rw-r--r-- | chip/it83xx/system.c | 28 | ||||
-rw-r--r-- | chip/lm4/system.c | 4 | ||||
-rw-r--r-- | chip/mec1322/system.c | 26 | ||||
-rw-r--r-- | chip/npcx/system.c | 115 | ||||
-rw-r--r-- | chip/nrf51/system.c | 4 | ||||
-rw-r--r-- | chip/stm32/system.c | 55 | ||||
-rw-r--r-- | common/system.c | 13 | ||||
-rw-r--r-- | include/system.h | 31 |
11 files changed, 182 insertions, 108 deletions
diff --git a/chip/g/system.c b/chip/g/system.c index 47b3848146..1400fa7060 100644 --- a/chip/g/system.c +++ b/chip/g/system.c @@ -231,12 +231,12 @@ int system_battery_cutoff_support_required(void) } /* TODO(crosbug.com/p/33822): Where can we store stuff persistently? */ -int system_get_vbnvcontext(uint8_t *block) +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) { return 0; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { return 0; } diff --git a/chip/host/system.c b/chip/host/system.c index 194a9565ab..3820048fad 100644 --- a/chip/host/system.c +++ b/chip/host/system.c @@ -188,12 +188,12 @@ const char *system_get_chip_revision(void) return ""; } -int system_get_vbnvcontext(uint8_t *block) +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) { return EC_ERROR_UNIMPLEMENTED; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { return EC_ERROR_UNIMPLEMENTED; } diff --git a/chip/ish/system.c b/chip/ish/system.c index 75f1d5a4a8..7110e85645 100644 --- a/chip/ish/system.c +++ b/chip/ish/system.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 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. */ @@ -76,12 +76,12 @@ const char *system_get_chip_revision(void) return buf; } -int system_get_vbnvcontext(uint8_t *block) +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) { return EC_ERROR_UNIMPLEMENTED; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { return EC_ERROR_UNIMPLEMENTED; } diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c index 32ab43231f..055c586cd8 100644 --- a/chip/it83xx/system.c +++ b/chip/it83xx/system.c @@ -226,25 +226,37 @@ const char *system_get_chip_revision(void) return buf; } -int system_get_vbnvcontext(uint8_t *block) +static int bram_idx_lookup(enum system_bbram_idx idx) { - int i; + if (idx >= SYSTEM_BBRAM_IDX_VBNVBLOCK0 && + idx <= SYSTEM_BBRAM_IDX_VBNVBLOCK15) + return BRAM_IDX_NVCONTEXT + + idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0; + return -1; +} + +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) +{ + int bram_idx = bram_idx_lookup(idx); - for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) - block[i] = IT83XX_BRAM_BANK0((BRAM_IDX_NVCONTEXT + i)); + if (bram_idx < 0) + return EC_ERROR_INVAL; + *value = IT83XX_BRAM_BANK0(bram_idx); return EC_SUCCESS; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { - int i; + int bram_idx = bram_idx_lookup(idx); - for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) - IT83XX_BRAM_BANK0((BRAM_IDX_NVCONTEXT + i)) = block[i]; + if (bram_idx < 0) + return EC_ERROR_INVAL; + IT83XX_BRAM_BANK0(bram_idx) = value; return EC_SUCCESS; } + #define BRAM_NVCONTEXT_SIZE (BRAM_IDX_NVCONTEXT_END - BRAM_IDX_NVCONTEXT + 1) BUILD_ASSERT(EC_VBNV_BLOCK_SIZE <= BRAM_NVCONTEXT_SIZE); diff --git a/chip/lm4/system.c b/chip/lm4/system.c index cb1cf8cef0..684b520dae 100644 --- a/chip/lm4/system.c +++ b/chip/lm4/system.c @@ -600,12 +600,12 @@ const char *system_get_chip_name(void) } } -int system_get_vbnvcontext(uint8_t *block) +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) { return EC_ERROR_UNIMPLEMENTED; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { return EC_ERROR_UNIMPLEMENTED; } diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c index 26d89c10e3..54ff2f45c8 100644 --- a/chip/mec1322/system.c +++ b/chip/mec1322/system.c @@ -23,7 +23,7 @@ /* Indices for hibernate data registers (RAM backed by VBAT) */ enum hibdata_index { HIBDATA_INDEX_SCRATCHPAD = 0, /* General-purpose scratchpad */ - HIBDATA_INDEX_SAVED_RESET_FLAGS /* Saved reset flags */ + HIBDATA_INDEX_SAVED_RESET_FLAGS, /* Saved reset flags */ }; static void check_reset_cause(void) @@ -166,14 +166,30 @@ const char *system_get_chip_revision(void) return buf; } -int system_get_vbnvcontext(uint8_t *block) +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) { - return EC_ERROR_UNIMPLEMENTED; + enum hibdata_index hibdata; + + switch (idx) { + default: + return EC_ERROR_UNIMPLEMENTED; + } + + *value = MEC1322_VBAT_RAM(hibdata); + return EC_SUCCESS; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { - return EC_ERROR_UNIMPLEMENTED; + enum hibdata_index hibdata; + + switch (idx) { + default: + return EC_ERROR_UNIMPLEMENTED; + } + + MEC1322_VBAT_RAM(hibdata) = value; + return EC_SUCCESS; } int system_set_scratchpad(uint32_t value) diff --git a/chip/npcx/system.c b/chip/npcx/system.c index d17a200015..bec553be53 100644 --- a/chip/npcx/system.c +++ b/chip/npcx/system.c @@ -6,21 +6,21 @@ /* System module for Chrome EC : NPCX hardware specific implementation */ #include "clock.h" +#include "clock_chip.h" #include "common.h" #include "console.h" #include "cpu.h" +#include "gpio.h" +#include "hooks.h" #include "host_command.h" +#include "hwtimer_chip.h" #include "registers.h" +#include "rom_chip.h" #include "system.h" -#include "hooks.h" +#include "system_chip.h" #include "task.h" #include "timer.h" #include "util.h" -#include "gpio.h" -#include "hwtimer_chip.h" -#include "system_chip.h" -#include "clock_chip.h" -#include "rom_chip.h" /* Flags for BBRM_DATA_INDEX_WAKE */ #define HIBERNATE_WAKE_MTC (1 << 0) /* MTC alarm */ @@ -83,6 +83,13 @@ void system_watchdog_reset(void) interrupt_enable(); } +/* Return true if index is stored as a single byte in bbram */ +static int bbram_is_byte_access(enum bbram_data_index index) +{ + return (index >= BBRM_DATA_INDEX_VBNVCNTXT && + index < BBRM_DATA_INDEX_RAMLOG); +} + /** * Read battery-backed ram (BBRAM) at specified index. * @@ -91,8 +98,10 @@ void system_watchdog_reset(void) static uint32_t bbram_data_read(enum bbram_data_index index) { uint32_t value = 0; + int bytes = bbram_is_byte_access(index) ? 1 : 4; + /* Check index */ - if (index < 0 || index >= NPCX_BBRAM_SIZE) + if (index < 0 || index + bytes >= NPCX_BBRAM_SIZE) return 0; /* BBRAM is valid */ @@ -100,12 +109,14 @@ static uint32_t bbram_data_read(enum bbram_data_index index) return 0; /* Read BBRAM */ - value += NPCX_BBRAM(index + 3); - value = value << 8; - value += NPCX_BBRAM(index + 2); - value = value << 8; - value += NPCX_BBRAM(index + 1); - value = value << 8; + if (bytes == 4) { + value += NPCX_BBRAM(index + 3); + value = value << 8; + value += NPCX_BBRAM(index + 2); + value = value << 8; + value += NPCX_BBRAM(index + 1); + value = value << 8; + } value += NPCX_BBRAM(index); return value; @@ -118,6 +129,8 @@ static uint32_t bbram_data_read(enum bbram_data_index index) */ static int bbram_data_write(enum bbram_data_index index, uint32_t value) { + int bytes = bbram_is_byte_access(index) ? 1 : 4; + /* Check index */ if (index < 0 || index >= NPCX_BBRAM_SIZE) return EC_ERROR_INVAL; @@ -127,15 +140,48 @@ static int bbram_data_write(enum bbram_data_index index, uint32_t value) return EC_ERROR_INVAL; /* Write BBRAM */ - NPCX_BBRAM(index) = value & 0xFF; - NPCX_BBRAM(index + 1) = (value >> 8) & 0xFF; - NPCX_BBRAM(index + 2) = (value >> 16) & 0xFF; - NPCX_BBRAM(index + 3) = (value >> 24) & 0xFF; + NPCX_BBRAM(index) = value & 0xFF; + if (bytes == 4) { + NPCX_BBRAM(index + 1) = (value >> 8) & 0xFF; + NPCX_BBRAM(index + 2) = (value >> 16) & 0xFF; + NPCX_BBRAM(index + 3) = (value >> 24) & 0xFF; + } /* Wait for write-complete */ return EC_SUCCESS; } +/* Map idx to a returned BBRM_DATA_INDEX_*, or return -1 on invalid idx */ +static int bbram_idx_lookup(enum system_bbram_idx idx) +{ + if (idx >= SYSTEM_BBRAM_IDX_VBNVBLOCK0 && + idx <= SYSTEM_BBRAM_IDX_VBNVBLOCK15) + return BBRM_DATA_INDEX_VBNVCNTXT + + idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0; + return -1; +} + +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) +{ + int bbram_idx = bbram_idx_lookup(idx); + + if (bbram_idx < 0) + return EC_ERROR_INVAL; + + *value = bbram_data_read(bbram_idx); + return EC_SUCCESS; +} + +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) +{ + int bbram_idx = bbram_idx_lookup(idx); + + if (bbram_idx < 0) + return EC_ERROR_INVAL; + + return bbram_data_write(bbram_idx, value); +} + /* MTC functions */ uint32_t system_get_rtc_sec(void) { @@ -679,41 +725,6 @@ const char *system_get_chip_revision(void) BUILD_ASSERT(BBRM_DATA_INDEX_VBNVCNTXT + EC_VBNV_BLOCK_SIZE <= NPCX_BBRAM_SIZE); /** - * Get/Set VbNvContext in non-volatile storage. The block should be 16 bytes - * long, which is the current size of VbNvContext block. - * - * @param block Pointer to a buffer holding VbNvContext. - * @return 0 on success, !0 on error. - */ -int system_get_vbnvcontext(uint8_t *block) -{ - int i; - - if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR)) { - memset(block, 0, EC_VBNV_BLOCK_SIZE); - return EC_SUCCESS; - } - - for (i = 0; i < EC_VBNV_BLOCK_SIZE; ++i) - block[i] = NPCX_BBRAM(BBRM_DATA_INDEX_VBNVCNTXT + i); - - return EC_SUCCESS; -} - -int system_set_vbnvcontext(const uint8_t *block) -{ - int i; - - if (IS_BIT_SET(NPCX_BKUP_STS, NPCX_BKUP_STS_IBBR)) - return EC_ERROR_INVAL; - - for (i = 0; i < EC_VBNV_BLOCK_SIZE; i++) - NPCX_BBRAM(BBRM_DATA_INDEX_VBNVCNTXT + i) = block[i]; - - return EC_SUCCESS; -} - -/** * Set a scratchpad register to the specified value. * * The scratchpad register must maintain its contents across a diff --git a/chip/nrf51/system.c b/chip/nrf51/system.c index 94c36202e4..61bd2311a8 100644 --- a/chip/nrf51/system.c +++ b/chip/nrf51/system.c @@ -107,13 +107,13 @@ void system_reset(int flags) ; } -int system_get_vbnvcontext(uint8_t *block) +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) { CPRINTS("TODO: implement %s()", __func__); return EC_ERROR_UNIMPLEMENTED; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { CPRINTS("TODO: implement %s()", __func__); return EC_ERROR_UNIMPLEMENTED; diff --git a/chip/stm32/system.c b/chip/stm32/system.c index d296a90fa5..458b90402f 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -336,36 +336,47 @@ const char *system_get_chip_revision(void) return ""; } -int system_get_vbnvcontext(uint8_t *block) +static int bkpdata_index_lookup(enum system_bbram_idx idx, int *msb) { - enum bkpdata_index i; - uint16_t value; - - for (i = BKPDATA_INDEX_VBNV_CONTEXT0; - i <= BKPDATA_INDEX_VBNV_CONTEXT7; i++) { - value = bkpdata_read(i); - *block++ = (uint8_t)(value & 0xff); - *block++ = (uint8_t)(value >> 8); + *msb = 0; + + if (idx >= SYSTEM_BBRAM_IDX_VBNVBLOCK0 && + idx <= SYSTEM_BBRAM_IDX_VBNVBLOCK15) { + *msb = (idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0) % 2; + return BKPDATA_INDEX_VBNV_CONTEXT0 + + (idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0) / 2; } + return -1; +} + +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) +{ + int msb = 0; + int bkpdata_index = bkpdata_index_lookup(idx, &msb); + + if (bkpdata_index < 0) + return EC_ERROR_INVAL; + *value = (bkpdata_read(bkpdata_index) >> (8 * msb)) & 0xff; return EC_SUCCESS; } -int system_set_vbnvcontext(const uint8_t *block) +int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { - enum bkpdata_index i; - uint16_t value; - int err; - - for (i = BKPDATA_INDEX_VBNV_CONTEXT0; - i <= BKPDATA_INDEX_VBNV_CONTEXT7; i++) { - value = *block++; - value |= ((uint16_t)*block++) << 8; - err = bkpdata_write(i, value); - if (err) - return err; - } + uint16_t read; + int msb = 0; + int bkpdata_index = bkpdata_index_lookup(idx, &msb); + + if (bkpdata_index < 0) + return EC_ERROR_INVAL; + + read = bkpdata_read(bkpdata_index); + if (msb) + read = (read & 0xff) | (value << 8); + else + read = (read & 0xff00) | value; + bkpdata_write(bkpdata_index, read); return EC_SUCCESS; } diff --git a/common/system.c b/common/system.c index 25acdbf544..a5824f0a72 100644 --- a/common/system.c +++ b/common/system.c @@ -1227,17 +1227,22 @@ int host_command_vbnvcontext(struct host_cmd_handler_args *args) { const struct ec_params_vbnvcontext *p = args->params; struct ec_response_vbnvcontext *r; + int i; switch (p->op) { case EC_VBNV_CONTEXT_OP_READ: r = args->response; - if (system_get_vbnvcontext(r->block)) - return EC_RES_ERROR; + for (i = 0; i < EC_VBNV_BLOCK_SIZE; ++i) + if (system_get_bbram(SYSTEM_BBRAM_IDX_VBNVBLOCK0 + i, + r->block + i)) + return EC_RES_ERROR; args->response_size = sizeof(*r); break; case EC_VBNV_CONTEXT_OP_WRITE: - if (system_set_vbnvcontext(p->block)) - return EC_RES_ERROR; + for (i = 0; i < EC_VBNV_BLOCK_SIZE; ++i) + if (system_set_bbram(SYSTEM_BBRAM_IDX_VBNVBLOCK0 + i, + p->block[i])) + return EC_RES_ERROR; break; default: return EC_RES_ERROR; diff --git a/include/system.h b/include/system.h index 50d1e29609..c3028e4a09 100644 --- a/include/system.h +++ b/include/system.h @@ -267,15 +267,34 @@ const char *system_get_chip_vendor(void); const char *system_get_chip_name(void); const char *system_get_chip_revision(void); +/* + * Common bbram entries. Chips don't necessarily need to implement + * all of these, error will be returned from system_get/set_bbram if + * not implemented. + */ +enum system_bbram_idx { + /* + * TODO(crbug.com/693210): Consider boards without vbnvcontext + * host command. + */ + SYSTEM_BBRAM_IDX_VBNVBLOCK0 = 0, + /* + * ... + * 16 total bytes of VB NVRAM. + * ... + */ + SYSTEM_BBRAM_IDX_VBNVBLOCK15 = 15, +}; + /** - * Get/Set VbNvContext in non-volatile storage. The block should be 16 bytes - * long, which is the current size of VbNvContext block. + * Get/Set byte in battery-backed storage. * - * @param block Pointer to a buffer holding VbNvContext. - * @return 0 on success, !0 on error. + * @param idx bbram byte to get / set. + * @param value byte to read / write from / to bbram. + * @return 0 on success, !0 on error. */ -int system_get_vbnvcontext(uint8_t *block); -int system_set_vbnvcontext(const uint8_t *block); +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value); +int system_set_bbram(enum system_bbram_idx idx, uint8_t value); /** * Put the EC in hibernate (lowest EC power state). |