summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorFiras Sammoura <fsammoura@google.com>2023-03-13 21:20:36 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-05-03 01:44:52 +0000
commit7f21c475bb679788a0e04d71780eac8cc78ac5f5 (patch)
treeaf8b07434460c5d3df112d95446edc8ee75517a8 /common
parent200d74d0f3ad8e8f96c112e7416ed2414d55fa76 (diff)
downloadchrome-ec-7f21c475bb679788a0e04d71780eac8cc78ac5f5.tar.gz
ec: Add async FLASH_PROTECT
Create an async FLASH_PROTECT command that is enabled when CONFIG_FLASH_PROTECT_DEFERRED is defined. Disable this configuration for boards cerise, damu, stern,cand willow where there is no flash memory available. Disable this configuration for board hyperdebug where the deferred implementation in not possible because CONFIG_COMMON_RUNTIME is undefined. Enable this configuration otherwise in both the ec and zephyr configuration files. BRANCH=nocturne BUG=b:116396469 TEST=make buildall -j Change-Id: I0605cc600841ec2ec3c1dd2d3d3598b28d20ffcb Signed-off-by: Firas Sammoura <fsammoura@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4335413 Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/flash.c106
1 files changed, 105 insertions, 1 deletions
diff --git a/common/flash.c b/common/flash.c
index 05eceaedd0..4d6b84f6dd 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -1588,8 +1588,108 @@ DECLARE_HOST_COMMAND(EC_CMD_FLASH_ERASE, flash_command_erase,
#endif
);
+#ifdef CONFIG_FLASH_PROTECT_DEFERRED
+struct flash_protect_async {
+ uint32_t mask;
+ uint32_t flags;
+
+ volatile enum ec_status rc;
+} __ec_align4;
+
+static struct flash_protect_async flash_protect_async_data = {
+ .rc = EC_RES_SUCCESS
+};
+
+static void crec_flash_set_protect_deferred(void)
+{
+ if (crec_flash_set_protect(flash_protect_async_data.mask,
+ flash_protect_async_data.flags))
+ flash_protect_async_data.rc = EC_RES_ERROR;
+ else
+ flash_protect_async_data.rc = EC_RES_SUCCESS;
+}
+DECLARE_DEFERRED(crec_flash_set_protect_deferred);
+
+static enum ec_status
+flash_command_protect_v2(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_flash_protect_v2 *p = args->params;
+ struct ec_response_flash_protect *r = args->response;
+ int rc = EC_RES_SUCCESS;
+
+ flash_protect_async_data.mask = p->mask;
+ flash_protect_async_data.flags = p->flags;
+
+ /*
+ * Handle requesting new flags. Note that we ignore the return code
+ * from flash_set_protect(), since errors will be visible to the caller
+ * via the flags in the response. (If we returned error, the caller
+ * wouldn't get the response.)
+ */
+
+ switch (p->action) {
+ case FLASH_PROTECT_ASYNC:
+ if (p->mask) {
+ rc = flash_protect_async_data.rc;
+ if (rc != EC_RES_SUCCESS) {
+ rc = EC_RES_BUSY;
+ break;
+ }
+ hook_call_deferred(
+ &crec_flash_set_protect_deferred_data,
+ 100 * MSEC);
+ /* Not our job to return the result of
+ * the previous command.
+ */
+ flash_protect_async_data.rc = EC_RES_BUSY;
+ }
+ return EC_RES_SUCCESS;
+
+ case FLASH_PROTECT_GET_RESULT:
+ /*
+ * Retrieve the current flags. The caller can use this
+ * to determine which of the requested flags could be
+ * set. This is cleaner than simply returning error,
+ * because it provides information to the caller about
+ * the actual result.
+ */
+ rc = flash_protect_async_data.rc;
+ if (rc == EC_RES_BUSY || rc == EC_RES_ERROR)
+ break;
+
+ r->flags = crec_flash_get_protect();
+
+ /* Indicate which flags are valid on this platform */
+ r->valid_flags = EC_FLASH_PROTECT_GPIO_ASSERTED |
+ EC_FLASH_PROTECT_ERROR_STUCK |
+ EC_FLASH_PROTECT_ERROR_INCONSISTENT |
+ EC_FLASH_PROTECT_ERROR_UNKNOWN |
+ crec_flash_physical_get_valid_flags();
+ r->writable_flags =
+ crec_flash_physical_get_writable_flags(r->flags);
+
+ args->response_size = sizeof(*r);
+
+ /* Ready for another command */
+ flash_protect_async_data.rc = EC_RES_SUCCESS;
+ break;
+
+ default:
+ rc = EC_RES_INVALID_PARAM;
+ }
+
+ return rc;
+}
+#endif
+
static enum ec_status flash_command_protect(struct host_cmd_handler_args *args)
{
+#if defined(CONFIG_FLASH_PROTECT_DEFERRED)
+ if (args->version == 2) {
+ return flash_command_protect_v2(args);
+ }
+#endif
+
const struct ec_params_flash_protect *p = args->params;
struct ec_response_flash_protect *r = args->response;
@@ -1629,7 +1729,11 @@ static enum ec_status flash_command_protect(struct host_cmd_handler_args *args)
* EC_VER_MASK(0) once cros_ec driver can send the correct version.
*/
DECLARE_HOST_COMMAND(EC_CMD_FLASH_PROTECT, flash_command_protect,
- EC_VER_MASK(0) | EC_VER_MASK(1));
+ EC_VER_MASK(0) | EC_VER_MASK(1)
+#ifdef CONFIG_FLASH_PROTECT_DEFERRED
+ | EC_VER_MASK(2)
+#endif
+);
static enum ec_status
flash_command_region_info(struct host_cmd_handler_args *args)