Files
OpenCellular/common/factory_mode.c
Mary Ruthven 5a23e3f49a cr50: refactor rma mode into factory mode
We're doing a bit of refactoring to break out factory mode into its own
file. Now factory reset and rma reset will be two methods of entering
factory mode. Factory mode can be disabled with the disable_factory
vendor command.

Factory mode means all ccd capabilities are set to Always and WP is
permanently disabled. When factory mode is disabled, all capabilities
are reset to Default and WP is reset to follow battery presence.

This adds 56 bytes.

BUG=none
BRANCH=cr50
TEST=verify rma reset will enable factory mode.

Change-Id: I21c6f7b4341e3a18e213e438bbd17c67739b85fa
Signed-off-by: Mary Ruthven <mruthven@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1069789
Commit-Ready: Mary Ruthven <mruthven@chromium.org>
Tested-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2018-05-30 20:38:53 -07:00

95 lines
2.2 KiB
C

/* Copyright 2018 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.
*/
/* CCD factory enable */
#include "ccd_config.h"
#include "console.h"
#include "extension.h"
#include "hooks.h"
#include "system.h"
#include "tpm_registers.h"
#include "tpm_vendor_cmds.h"
#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args)
static uint8_t ccd_hook_active;
static void ccd_config_changed(void)
{
if (!ccd_hook_active)
return;
CPRINTS("%s: saved, rebooting\n", __func__);
cflush();
system_reset(SYSTEM_RESET_HARD);
}
DECLARE_HOOK(HOOK_CCD_CHANGE, ccd_config_changed, HOOK_PRIO_LAST);
static void factory_enable_failed(void)
{
ccd_hook_active = 0;
CPRINTS("factory enable failed");
deassert_ec_rst();
}
DECLARE_DEFERRED(factory_enable_failed);
/* The below time constants are way longer than should be required in practice:
*
* Time it takes to finish processing TPM command
*/
#define TPM_PROCESSING_TIME (1 * SECOND)
/*
* Time it takse TPM reset function to wipe out the NVMEM and reboot the
* device.
*/
#define TPM_RESET_TIME (10 * SECOND)
/* Total time deep sleep should not be allowed. */
#define DISABLE_SLEEP_TIME (TPM_PROCESSING_TIME + TPM_RESET_TIME)
static void factory_enable_deferred(void)
{
int rv;
CPRINTS("%s: reset TPM\n", __func__);
/*
* Let's make sure the rest of the system is out of the way while TPM
* is being wiped out.
*/
assert_ec_rst();
if (tpm_reset_request(1, 1) != EC_SUCCESS) {
CPRINTS("%s: TPM reset failed\n", __func__);
deassert_ec_rst();
return;
}
tpm_reinstate_nvmem_commits();
CPRINTS("%s: TPM reset done, enabling factory mode\n", __func__);
ccd_hook_active = 1;
rv = ccd_reset_config(CCD_RESET_FACTORY);
if (rv != EC_SUCCESS)
factory_enable_failed();
/*
* Make sure we never end up with the EC held in reset, no matter what
* prevents the proper factory reset flow from succeeding.
*/
hook_call_deferred(&factory_enable_failed_data, TPM_RESET_TIME);
}
DECLARE_DEFERRED(factory_enable_deferred);
void enable_ccd_factory_mode(void)
{
delay_sleep_by(DISABLE_SLEEP_TIME);
hook_call_deferred(&factory_enable_deferred_data,
TPM_PROCESSING_TIME);
}