cr50: Defragment code

For historical reasons, CCD, reset, and power button control were
scattered around several files.  Consolidate the code in more sensible
(in retrospect) places.

No functional changes, just moving code.

BUG=none
BRANCH=cr50
TEST=make buildall; boot cr50

Change-Id: Ic381a5a5d0627753cc771189aa377e88b81b155e
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/653766
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
This commit is contained in:
Randall Spangler
2017-09-06 14:28:05 -07:00
committed by chrome-bot
parent 5da63f4ea2
commit ccb151d013
13 changed files with 370 additions and 348 deletions

View File

@@ -4,6 +4,7 @@
*
* AP state machine
*/
#include "ccd_config.h"
#include "common.h"
#include "console.h"
#include "gpio.h"

View File

@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
#include "board_id.h"
#include "case_closed_debug.h"
#include "ccd_config.h"
#include "clock.h"
#include "common.h"
#include "console.h"
@@ -915,6 +915,48 @@ void board_reboot_ap(void)
deassert_sys_rst();
}
/**
* Console command to toggle system (AP) reset
*/
static int command_sys_rst(int argc, char **argv)
{
int val;
char *e;
int ms = 20;
if (argc > 1) {
if (!ccd_is_cap_enabled(CCD_CAP_REBOOT_EC_AP))
return EC_ERROR_ACCESS_DENIED;
if (!strcasecmp("pulse", argv[1])) {
if (argc == 3) {
ms = strtoi(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
}
ccprintf("Pulsing AP reset for %dms\n", ms);
assert_sys_rst();
msleep(ms);
deassert_sys_rst();
} else if (parse_bool(argv[1], &val)) {
if (val)
assert_sys_rst();
else
deassert_sys_rst();
} else
return EC_ERROR_PARAM1;
}
ccprintf("SYS_RST_L is %s\n", is_sys_rst_asserted() ?
"asserted" : "deasserted");
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(sysrst, command_sys_rst,
"[pulse [time] | <BOOLEAN>]",
"Assert/deassert SYS_RST_L to reset the AP");
void assert_ec_rst(void)
{
GWRITE(RBOX, ASSERT_EC_RST, 1);
@@ -929,6 +971,40 @@ int is_ec_rst_asserted(void)
return GREAD(RBOX, ASSERT_EC_RST);
}
/**
* Console command to toggle EC reset
*/
static int command_ec_rst(int argc, char **argv)
{
int val;
if (argc > 1) {
if (!ccd_is_cap_enabled(CCD_CAP_REBOOT_EC_AP))
return EC_ERROR_ACCESS_DENIED;
if (!strcasecmp("pulse", argv[1])) {
ccprintf("Pulsing EC reset\n");
assert_ec_rst();
usleep(200);
deassert_ec_rst();
} else if (parse_bool(argv[1], &val)) {
if (val)
assert_ec_rst();
else
deassert_ec_rst();
} else
return EC_ERROR_PARAM1;
}
ccprintf("EC_RST_L is %s\n", is_ec_rst_asserted() ?
"asserted" : "deasserted");
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(ecrst, command_ec_rst,
"[pulse | <BOOLEAN>]",
"Assert/deassert EC_RST_L to reset the EC (and AP)");
/*
* This function duplicates some of the functionality in chip/g/gpio.c in order
* to configure a given strap pin to be either a low gpio output, a gpio input

View File

@@ -29,7 +29,7 @@ dirs-y += chip/$(CHIP)/dcrypto
dirs-y += $(BDIR)/tpm2
# Objects that we need to build
board-y = board.o ap_state.o ec_state.o servo_state.o
board-y = board.o ap_state.o ec_state.o power_button.o servo_state.o
board-${CONFIG_RDD} += rdd.o
board-${CONFIG_USB_SPI} += usb_spi.o
board-${CONFIG_USB_I2C} += usb_i2c.o

View File

@@ -2,8 +2,9 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* EC detect state machine.
* EC state machine
*/
#include "ccd_config.h"
#include "common.h"
#include "console.h"
#include "gpio.h"

118
board/cr50/power_button.c Normal file
View File

@@ -0,0 +1,118 @@
/* Copyright 2017 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 "console.h"
#include "gpio.h"
#include "hooks.h"
#include "physical_presence.h"
#include "rbox.h"
#include "registers.h"
#include "system.h"
#include "system_chip.h"
#include "task.h"
#include "timer.h"
#define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args)
/**
* Enable/disable power button interrupt.
*
* @param enable Enable (!=0) or disable (==0)
*/
static void power_button_enable_interrupt(int enable)
{
if (enable) {
/* Clear any leftover power button interrupts */
GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_FED, 1);
/* Enable power button interrupt */
GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_FED, 1);
task_enable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT);
} else {
GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_FED, 0);
task_disable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT);
}
}
static void power_button_handler(void)
{
CPRINTS("power button pressed");
if (physical_detect_press() != EC_SUCCESS) {
/* Not consumed by physical detect */
#ifdef CONFIG_U2F
/* Track last power button press for U2F */
power_button_record();
#endif
}
GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_FED, 1);
}
DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT, power_button_handler, 1);
#ifdef CONFIG_U2F
static void power_button_init(void)
{
/*
* Enable power button interrupts all the time for U2F.
*
* Ideally U2F should only enable physical presence after the start of
* a U2F request (using atomic operations for the PP enable mask so it
* plays nicely with CCD config), but that doesn't happen yet.
*/
power_button_enable_interrupt(1);
}
DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_DEFAULT);
#endif /* CONFIG_U2F */
void board_physical_presence_enable(int enable)
{
#ifndef CONFIG_U2F
/* Enable/disable power button interrupts */
power_button_enable_interrupt(enable);
#endif
/* Stay awake while we're doing this, just in case. */
if (enable)
disable_sleep(SLEEP_MASK_PHYSICAL_PRESENCE);
else
enable_sleep(SLEEP_MASK_PHYSICAL_PRESENCE);
}
static int command_powerbtn(int argc, char **argv)
{
char *e;
int ms = 200;
if (argc > 1) {
if (!strcasecmp("pulse", argv[1])) {
if (argc == 3) {
ms = strtoi(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
}
ccprintf("Force %dms power button press\n", ms);
rbox_powerbtn_press();
msleep(ms);
rbox_powerbtn_release();
} else if (!strcasecmp("press", argv[1])) {
rbox_powerbtn_press();
} else if (!strcasecmp("release", argv[1])) {
rbox_powerbtn_release();
} else
return EC_ERROR_PARAM1;
}
ccprintf("powerbtn: %s\n",
rbox_powerbtn_override_is_enabled() ? "forced press" :
rbox_powerbtn_is_pressed() ? "pressed\n" : "released\n");
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn,
"[pulse [ms] | press | release]",
"get/set the state of the power button");

View File

@@ -3,7 +3,8 @@
* found in the LICENSE file.
*/
#include "case_closed_debug.h"
#include "case_closed_debug.h" /* For ccd_ext_is_enabled() */
#include "ccd_config.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"
@@ -126,6 +127,11 @@ enum ccd_state_flag {
CCD_ENABLE_SPI = (1 << 6),
};
int console_is_restricted(void)
{
return !ccd_is_cap_enabled(CCD_CAP_GSC_RESTRICTED_CONSOLE);
}
/**
* Return the currently enabled state flags (see enum ccd_state_flag).
*/
@@ -347,8 +353,6 @@ static void ccd_ext_detect(void)
}
DECLARE_HOOK(HOOK_SECOND, ccd_ext_detect, HOOK_PRIO_DEFAULT);
/*****************************************************************************/
static int command_ccd_state(int argc, char **argv)
{
print_ap_state();
@@ -369,107 +373,3 @@ DECLARE_CONSOLE_COMMAND(ccdstate, command_ccd_state,
"",
"Print the case closed debug device state");
static int command_sys_rst(int argc, char **argv)
{
int val;
char *e;
int ms = 20;
if (argc > 1) {
if (!ccd_is_cap_enabled(CCD_CAP_REBOOT_EC_AP))
return EC_ERROR_ACCESS_DENIED;
if (!strcasecmp("pulse", argv[1])) {
if (argc == 3) {
ms = strtoi(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
}
ccprintf("Pulsing AP reset for %dms\n", ms);
assert_sys_rst();
msleep(ms);
deassert_sys_rst();
} else if (parse_bool(argv[1], &val)) {
if (val)
assert_sys_rst();
else
deassert_sys_rst();
} else
return EC_ERROR_PARAM1;
}
ccprintf("SYS_RST_L is %s\n", is_sys_rst_asserted() ?
"asserted" : "deasserted");
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(sysrst, command_sys_rst,
"[pulse [time] | <BOOLEAN>]",
"Assert/deassert SYS_RST_L to reset the AP");
static int command_ec_rst(int argc, char **argv)
{
int val;
if (argc > 1) {
if (!ccd_is_cap_enabled(CCD_CAP_REBOOT_EC_AP))
return EC_ERROR_ACCESS_DENIED;
if (!strcasecmp("pulse", argv[1])) {
ccprintf("Pulsing EC reset\n");
assert_ec_rst();
usleep(200);
deassert_ec_rst();
} else if (parse_bool(argv[1], &val)) {
if (val)
assert_ec_rst();
else
deassert_ec_rst();
} else
return EC_ERROR_PARAM1;
}
ccprintf("EC_RST_L is %s\n", is_ec_rst_asserted() ?
"asserted" : "deasserted");
return EC_SUCCESS;
}
DECLARE_SAFE_CONSOLE_COMMAND(ecrst, command_ec_rst,
"[pulse | <BOOLEAN>]",
"Assert/deassert EC_RST_L to reset the EC (and AP)");
static int command_powerbtn(int argc, char **argv)
{
char *e;
int ms = 200;
if (argc > 1) {
if (!strcasecmp("pulse", argv[1])) {
if (argc == 3) {
ms = strtoi(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
}
ccprintf("Force %dms power button press\n", ms);
rbox_powerbtn_press();
msleep(ms);
rbox_powerbtn_release();
} else if (!strcasecmp("press", argv[1])) {
rbox_powerbtn_press();
} else if (!strcasecmp("release", argv[1])) {
rbox_powerbtn_release();
} else
return EC_ERROR_PARAM1;
}
ccprintf("powerbtn: %s\n",
rbox_powerbtn_override_is_enabled() ? "forced press" :
rbox_powerbtn_is_pressed() ? "pressed\n" : "released\n");
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(powerbtn, command_powerbtn,
"[pulse [ms] | press | release]",
"get/set the state of the power button");

View File

@@ -4,6 +4,7 @@
*/
#include "case_closed_debug.h"
#include "ccd_config.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"

View File

@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
#include "case_closed_debug.h"
#include "ccd_config.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"

View File

@@ -3,22 +3,16 @@
* found in the LICENSE file.
*/
#include "common.h"
#include "case_closed_debug.h"
#include "ccd_config.h"
#include "console.h"
#include "crc8.h"
#include "extension.h"
#include "gpio.h"
#include "hooks.h"
#include "nvmem.h"
#include "nvmem_vars.h"
#include "physical_presence.h"
#include "registers.h"
#include "scratch_reg1.h"
#include "system.h"
#include "system_chip.h"
#include "task.h"
#include "timer.h"
#include "tpm_nvmem_read.h"
#include "tpm_registers.h"
#include "util.h"
@@ -320,82 +314,6 @@ int board_fwmp_allows_unlock(void)
#endif
}
/****************************************************************************/
/* Console control */
int console_is_restricted(void)
{
return !ccd_is_cap_enabled(CCD_CAP_GSC_RESTRICTED_CONSOLE);
}
/****************************************************************************/
/* Stuff for the unlock sequence */
/**
* Enable/disable power button interrupt.
*
* @param enable Enable (!=0) or disable (==0)
*/
static void power_button_enable_interrupt(int enable)
{
if (enable) {
/* Clear any leftover power button interrupts */
GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_FED, 1);
/* Enable power button interrupt */
GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_FED, 1);
task_enable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT);
} else {
GWRITE_FIELD(RBOX, INT_ENABLE, INTR_PWRB_IN_FED, 0);
task_disable_irq(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT);
}
}
static void power_button_handler(void)
{
CPRINTS("power button pressed");
if (physical_detect_press() != EC_SUCCESS) {
/* Not consumed by physical detect */
#ifdef CONFIG_U2F
/* Track last power button press for U2F */
power_button_record();
#endif
}
GWRITE_FIELD(RBOX, INT_STATE, INTR_PWRB_IN_FED, 1);
}
DECLARE_IRQ(GC_IRQNUM_RBOX0_INTR_PWRB_IN_FED_INT, power_button_handler, 1);
#ifdef CONFIG_U2F
static void power_button_init(void)
{
/*
* Enable power button interrupts all the time for U2F.
*
* Ideally U2F should only enable physical presence after the start of
* a U2F request (using atomic operations for the PP enable mask so it
* plays nicely with CCD config), but that doesn't happen yet.
*/
power_button_enable_interrupt(1);
}
DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_DEFAULT);
#endif /* CONFIG_U2F */
void board_physical_presence_enable(int enable)
{
#ifndef CONFIG_U2F
/* Enable/disable power button interrupts */
power_button_enable_interrupt(enable);
#endif
/* Stay awake while we're doing this, just in case. */
if (enable)
disable_sleep(SLEEP_MASK_PHYSICAL_PRESENCE);
else
enable_sleep(SLEEP_MASK_PHYSICAL_PRESENCE);
}
/****************************************************************************/
/* TPM vendor-specific commands */

View File

@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
#include "case_closed_debug.h"
#include "ccd_config.h"
#include "common.h"
#include "link_defs.h"
#include "gpio.h"

View File

@@ -5,7 +5,7 @@
* Case Closed Debug configuration
*/
#include "case_closed_debug.h"
#include "ccd_config.h"
#include "common.h"
#include "console.h"
#include "cryptoc/sha256.h"

View File

@@ -48,156 +48,4 @@ enum ccd_mode ccd_get_mode(void);
*/
int ccd_ext_is_enabled(void);
/******************************************************************************/
/* New CCD "V1" configuration. Eventually this will supersede the above code */
/* Case-closed debugging state */
enum ccd_state {
CCD_STATE_LOCKED = 0,
CCD_STATE_UNLOCKED,
CCD_STATE_OPENED,
/* Number of CCD states */
CCD_STATE_COUNT
};
/* Flags */
enum ccd_flag {
/* Flags that can only be set internally; fill from bottom up */
/*
* Test lab mode is enabled. This MUST be in the first byte so that
* it's in a constant position across all versions of CCD config.
*
* Note: This is used internally by CCD config. Do NOT test this
* to control other things; use capabilities for those.
*/
CCD_FLAG_TEST_LAB = (1 << 0),
/*
* What state were we in when the password was set?
* (0=opened, 1=unlocked)
*/
CCD_FLAG_PASSWORD_SET_WHEN_UNLOCKED = (1 << 1),
/* (flags in the middle are unused) */
/* Flags that can be set via ccd_set_flags(); fill from top down */
/* Override write protect at boot */
CCD_FLAG_OVERRIDE_WP_AT_BOOT = (1 << 22),
/*
* If overriding WP at boot, set it to what value
* (0=disabled, 1=enabled)
*/
CCD_FLAG_OVERRIDE_WP_STATE_ENABLED = (1 << 23),
};
/* Capabilities */
enum ccd_capability {
/* UARTs to/from AP and EC */
CCD_CAP_GSC_RX_AP_TX = 0,
CCD_CAP_GSC_TX_AP_RX = 1,
CCD_CAP_GSC_RX_EC_TX = 2,
CCD_CAP_GSC_TX_EC_RX = 3,
/* Access to AP SPI flash */
CCD_CAP_AP_FLASH = 4,
/* Access to EC flash (SPI or internal) */
CCD_CAP_EC_FLASH = 5,
/* Override WP temporarily or at boot */
CCD_CAP_OVERRIDE_WP = 6,
/* Reboot EC or AP */
CCD_CAP_REBOOT_EC_AP = 7,
/* GSC restricted console commands */
CCD_CAP_GSC_RESTRICTED_CONSOLE = 8,
/* Allow ccd-unlock or ccd-open without AP reboot */
CCD_CAP_UNLOCK_WITHOUT_AP_REBOOT = 9,
/* Allow ccd-unlock or ccd-open without short physical presence */
CCD_CAP_UNLOCK_WITHOUT_SHORT_PP = 10,
/* Allow ccd-open without wiping TPM data */
CCD_CAP_OPEN_WITHOUT_TPM_WIPE = 11,
/* Allow ccd-open without long physical presence */
CCD_CAP_OPEN_WITHOUT_LONG_PP = 12,
/* Allow removing the battery to bypass physical presence requirement */
CCD_CAP_REMOVE_BATTERY_BYPASSES_PP = 13,
/* Allow GSC firmware update without wiping TPM data */
CCD_CAP_GSC_FW_UPDATE_WITHOUT_TPM_WIPE = 14,
/* Access to I2C via USB */
CCD_CAP_I2C = 15,
/* Number of currently defined capabilities */
CCD_CAP_COUNT
};
/**
* Initialize CCD configuration at boot.
*
* This must be called before any command which gets/sets the configuration.
*
* @param state Initial case-closed debugging state. This should be
* CCD_STATE_LOCKED unless this is a debug build, or if
* a previous value is being restored after a low-power
* resume.
*/
void ccd_config_init(enum ccd_state state);
/**
* Get a single CCD flag.
*
* @param flag Flag to get
* @return 1 if flag is set, 0 if flag is clear
*/
int ccd_get_flag(enum ccd_flag flag);
/**
* Set a single CCD flag.
*
* @param flag Flag to set
* @param value New value for flag (0=clear, non-zero=set)
* @return EC_SUCCESS or non-zero error code.
*/
int ccd_set_flag(enum ccd_flag flag, int value);
/**
* Check if a CCD capability is enabled in the current CCD mode.
*
* @param cap Capability to check
* @return 1 if capability is enabled, 0 if disabled
*/
int ccd_is_cap_enabled(enum ccd_capability cap);
/**
* Get the current CCD state.
*
* This is intended for use by the board if it needs to back up the CCD state
* across low-power states and then restore it when calling ccd_config_init().
* Do NOT use this to gate debug capabilities; use ccd_is_cap_enabled() or
* ccd_get_flag() instead.
*
* @return The current CCD state.
*/
enum ccd_state ccd_get_state(void);
/**
* Force CCD disabled.
*
* This should be called if security checks fail and for some reason the board
* can't immediately reboot. It locks CCD and disables all CCD capabilities
* until reboot.
*/
void ccd_disable(void);
#endif /* __CROS_EC_CASE_CLOSED_DEBUG_H */

159
include/ccd_config.h Normal file
View File

@@ -0,0 +1,159 @@
/* Copyright 2017 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.
*
* Case Closed Debugging configuration
*/
#ifndef __CROS_EC_CCD_CONFIG_H
#define __CROS_EC_CCD_CONFIG_H
/* Case-closed debugging state */
enum ccd_state {
CCD_STATE_LOCKED = 0,
CCD_STATE_UNLOCKED,
CCD_STATE_OPENED,
/* Number of CCD states */
CCD_STATE_COUNT
};
/* Flags */
enum ccd_flag {
/* Flags that can only be set internally; fill from bottom up */
/*
* Test lab mode is enabled. This MUST be in the first byte so that
* it's in a constant position across all versions of CCD config.
*
* Note: This is used internally by CCD config. Do NOT test this
* to control other things; use capabilities for those.
*/
CCD_FLAG_TEST_LAB = (1 << 0),
/*
* What state were we in when the password was set?
* (0=opened, 1=unlocked)
*/
CCD_FLAG_PASSWORD_SET_WHEN_UNLOCKED = (1 << 1),
/* (flags in the middle are unused) */
/* Flags that can be set via ccd_set_flags(); fill from top down */
/* Override write protect at boot */
CCD_FLAG_OVERRIDE_WP_AT_BOOT = (1 << 22),
/*
* If overriding WP at boot, set it to what value
* (0=disabled, 1=enabled)
*/
CCD_FLAG_OVERRIDE_WP_STATE_ENABLED = (1 << 23),
};
/* Capabilities */
enum ccd_capability {
/* UARTs to/from AP and EC */
CCD_CAP_GSC_RX_AP_TX = 0,
CCD_CAP_GSC_TX_AP_RX = 1,
CCD_CAP_GSC_RX_EC_TX = 2,
CCD_CAP_GSC_TX_EC_RX = 3,
/* Access to AP SPI flash */
CCD_CAP_AP_FLASH = 4,
/* Access to EC flash (SPI or internal) */
CCD_CAP_EC_FLASH = 5,
/* Override WP temporarily or at boot */
CCD_CAP_OVERRIDE_WP = 6,
/* Reboot EC or AP */
CCD_CAP_REBOOT_EC_AP = 7,
/* GSC restricted console commands */
CCD_CAP_GSC_RESTRICTED_CONSOLE = 8,
/* Allow ccd-unlock or ccd-open without AP reboot */
CCD_CAP_UNLOCK_WITHOUT_AP_REBOOT = 9,
/* Allow ccd-unlock or ccd-open without short physical presence */
CCD_CAP_UNLOCK_WITHOUT_SHORT_PP = 10,
/* Allow ccd-open without wiping TPM data */
CCD_CAP_OPEN_WITHOUT_TPM_WIPE = 11,
/* Allow ccd-open without long physical presence */
CCD_CAP_OPEN_WITHOUT_LONG_PP = 12,
/* Allow removing the battery to bypass physical presence requirement */
CCD_CAP_REMOVE_BATTERY_BYPASSES_PP = 13,
/* Allow GSC firmware update without wiping TPM data */
CCD_CAP_GSC_FW_UPDATE_WITHOUT_TPM_WIPE = 14,
/* Access to I2C via USB */
CCD_CAP_I2C = 15,
/* Number of currently defined capabilities */
CCD_CAP_COUNT
};
/**
* Initialize CCD configuration at boot.
*
* This must be called before any command which gets/sets the configuration.
*
* @param state Initial case-closed debugging state. This should be
* CCD_STATE_LOCKED unless this is a debug build, or if
* a previous value is being restored after a low-power
* resume.
*/
void ccd_config_init(enum ccd_state state);
/**
* Get a single CCD flag.
*
* @param flag Flag to get
* @return 1 if flag is set, 0 if flag is clear
*/
int ccd_get_flag(enum ccd_flag flag);
/**
* Set a single CCD flag.
*
* @param flag Flag to set
* @param value New value for flag (0=clear, non-zero=set)
* @return EC_SUCCESS or non-zero error code.
*/
int ccd_set_flag(enum ccd_flag flag, int value);
/**
* Check if a CCD capability is enabled in the current CCD mode.
*
* @param cap Capability to check
* @return 1 if capability is enabled, 0 if disabled
*/
int ccd_is_cap_enabled(enum ccd_capability cap);
/**
* Get the current CCD state.
*
* This is intended for use by the board if it needs to back up the CCD state
* across low-power states and then restore it when calling ccd_config_init().
* Do NOT use this to gate debug capabilities; use ccd_is_cap_enabled() or
* ccd_get_flag() instead.
*
* @return The current CCD state.
*/
enum ccd_state ccd_get_state(void);
/**
* Force CCD disabled.
*
* This should be called if security checks fail and for some reason the board
* can't immediately reboot. It locks CCD and disables all CCD capabilities
* until reboot.
*/
void ccd_disable(void);
#endif /* __CROS_EC_CCD_CONFIG_H */