summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/fizz/ec.tasklist4
-rw-r--r--common/system.c8
-rw-r--r--common/vboot/vboot.c72
-rw-r--r--include/vboot.h11
-rw-r--r--power/intel_x86.c15
5 files changed, 67 insertions, 43 deletions
diff --git a/board/fizz/ec.tasklist b/board/fizz/ec.tasklist
index 82a214f38d..b60ae990a7 100644
--- a/board/fizz/ec.tasklist
+++ b/board/fizz/ec.tasklist
@@ -21,9 +21,9 @@
*/
#define CONFIG_TASK_LIST \
- TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
+ TASK_ALWAYS(HOOKS, hook_task, NULL, 2048) \
/* Larger stack for RW verification (i.e. sha256, rsa) */ \
- TASK_NOTEST(CHIPSET, chipset_task, NULL, 2048) \
+ TASK_NOTEST(CHIPSET, chipset_task, NULL, TASK_STACK_SIZE) \
TASK_NOTEST(PDCMD, pd_command_task, NULL, TASK_STACK_SIZE) \
TASK_ALWAYS(HOSTCMD, host_command_task, NULL, LARGER_TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) \
diff --git a/common/system.c b/common/system.c
index 66e7be5192..1f9a2062c1 100644
--- a/common/system.c
+++ b/common/system.c
@@ -983,13 +983,9 @@ static int command_sysjump(int argc, char **argv)
/* Handle named images */
if (!strcasecmp(argv[1], "RO"))
return system_run_image_copy(SYSTEM_IMAGE_RO);
- else if (!strcasecmp(argv[1], "RW") || !strcasecmp(argv[1], "A")) {
- /*
- * TODO(crosbug.com/p/11149): remove "A" once all scripts are
- * updated to use "RW".
- */
+ else if (!strcasecmp(argv[1], "RW") || !strcasecmp(argv[1], "A"))
return system_run_image_copy(SYSTEM_IMAGE_RW);
- } else if (!strcasecmp(argv[1], "B")) {
+ else if (!strcasecmp(argv[1], "B")) {
#ifdef CONFIG_RW_B
return system_run_image_copy(SYSTEM_IMAGE_RW_B);
#else
diff --git a/common/vboot/vboot.c b/common/vboot/vboot.c
index 27c57b27c2..27a47fd125 100644
--- a/common/vboot/vboot.c
+++ b/common/vboot/vboot.c
@@ -11,6 +11,7 @@
#include "charge_manager.h"
#include "chipset.h"
#include "console.h"
+#include "hooks.h"
#include "host_command.h"
#include "rsa.h"
#include "rwsig.h"
@@ -21,8 +22,8 @@
#include "vboot.h"
#include "vb21_struct.h"
-#define CPRINTS(format, args...) cprints(CC_VBOOT, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_VBOOT,"VB " format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_VBOOT,"VB " format, ## args)
enum vboot_ec_slot {
VBOOT_EC_SLOT_A,
@@ -145,48 +146,89 @@ static int verify_and_jump(void)
static void request_power(void)
{
/* TODO: Blink LED */
+ CPRINTS("%s", __func__);
}
static void request_recovery(void)
{
/* TODO: Blink LED */
+ CPRINTS("%s", __func__);
}
static int is_manual_recovery(void)
{
- return host_get_events() & EC_HOST_EVENT_KEYBOARD_RECOVERY;
+ return host_is_event_set(EC_HOST_EVENT_KEYBOARD_RECOVERY);
}
-void vboot_main(void)
+static void vboot_main(void);
+DECLARE_DEFERRED(vboot_main);
+static void vboot_main(void)
{
+ const int check_charge_manager_frequency_usec = 10 * MSEC;
int port = charge_manager_get_active_charge_port();
- if (port >= CONFIG_USB_PD_PORT_COUNT) {
- /* AC is not type-c. No chance to boot. */
- request_power();
+ if (port == CHARGE_PORT_NONE) {
+ /* We loop here until charge manager is ready */
+ hook_call_deferred(&vboot_main_data,
+ check_charge_manager_frequency_usec);
+ return;
+ }
+
+ CPRINTS("Checking power");
+
+ if (system_can_boot_ap()) {
+ /*
+ * We are here for the two cases:
+ * 1. Booting on RO with a barrel jack adapter. We can continue
+ * to boot AP with EC-RO. We'll jump later in softsync.
+ * 2. Booting on RW with a type-c charger. PD negotiation is
+ * done and we can boot AP.
+ */
+ CPRINTS("Got enough power");
return;
}
- if (pd_comm_is_enabled(port))
- /* Normal RW boot or unlocked RO boot.
- * Hoping enough power will be supplied after PD negotiation. */
+ if (system_get_image_copy() != SYSTEM_IMAGE_RO || !system_is_locked()) {
+ /*
+ * If we're here, it means PD negotiation was attempted but
+ * we didn't get enough power to boot AP. This happens on RW
+ * or unlocked RO.
+ *
+ * This could be caused by a weak type-c charger. If that's
+ * the case, users need to plug a better charger. We could
+ * also be here because PD negotiation is still taking place.
+ * If so, we'll briefly show request power sign but it will
+ * be immediately corrected.
+ */
+ request_power();
return;
+ }
- /* PD communication is disabled. Probably this is RO image */
- CPRINTS("PD comm disabled");
+ CPRINTS("Booting RO on weak battery/charger");
if (is_manual_recovery()) {
+ CPRINTS("Manual recovery requested");
if (battery_is_present() || has_matrix_keyboard()) {
request_power();
return;
}
- CPRINTS("Enable C%d PD communication", port);
+ /* We don't request_power because we don't want to assume all
+ * devices support a non type-c charger. We open up a security
+ * hole by allowing EC-RO to do PD negotiation but attackers
+ * don't gain meaningful advantage on devices without a matrix
+ * keyboard */
+ CPRINTS("Enable C%d PD comm", port);
pd_comm_enable(port, 1);
/* TODO: Inform PD task and make it negotiate */
return;
}
- if (!is_vboot_ec_supported() && !is_low_power_ap_boot_supported()) {
+ if (!is_vboot_ec_supported()) {
+ if (is_low_power_ap_boot_supported())
+ /* If a device supports this feature, AP's boot power
+ * threshold should be set low. That will let EC-RO
+ * boot AP and softsync take care of RW verification. */
+ return;
request_power();
return;
}
@@ -197,3 +239,5 @@ void vboot_main(void)
/* Failed to jump. Need recovery. */
request_recovery();
}
+
+DECLARE_HOOK(HOOK_INIT, vboot_main, HOOK_PRIO_DEFAULT);
diff --git a/include/vboot.h b/include/vboot.h
index 14f7a8f13c..b9f03c6423 100644
--- a/include/vboot.h
+++ b/include/vboot.h
@@ -46,14 +46,3 @@ int vboot_is_padding_valid(const uint8_t *data, uint32_t start, uint32_t end);
*/
int vboot_verify(const uint8_t *data, int len,
const struct rsa_public_key *key, const uint8_t *sig);
-
-/**
- * Verify RW image and jump to it
- *
- * Calling this API results in one of the followings:
- * 1. Returns, expecting PD will provide enough power after negotiation
- * 2. Jumps to RW (no return)
- * 3. Returns, requesting more power
- * 4. Returns, requesting recovery
- */
-void vboot_main(void);
diff --git a/power/intel_x86.c b/power/intel_x86.c
index 90a8682d7c..954ec5d29a 100644
--- a/power/intel_x86.c
+++ b/power/intel_x86.c
@@ -278,16 +278,11 @@ enum power_state common_intel_x86_power_handle_state(enum power_state state)
* because when entering S5, EC enables EC_ROP_SLP_SUS pin
* which causes (short-powered) system to brown out.
*/
- {
- if (!system_can_boot_ap()) {
- vboot_main();
- while (!system_can_boot_ap())
- /* LED blinks as HOOK_TICK events trigger.
- * We can print percent & power as they
- * improve. */
- msleep(200);
- }
- }
+ while (!system_can_boot_ap())
+ /* LED blinks as HOOK_TICK events trigger.
+ * We can print percent & power as they
+ * improve. */
+ msleep(200);
#endif
power_s5_up = 1;
return POWER_S5;