diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2017-07-12 11:12:58 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-07-14 04:01:45 -0700 |
commit | 921e9b71258c318f364457d97a94d3fb9e1bbbfc (patch) | |
tree | 1ff1afcf36153e7884fb6c0086c7dc063564a9a8 /common | |
parent | a53d2f5949942899cdb5d7b43f5ecc3820f0627e (diff) | |
download | chrome-ec-921e9b71258c318f364457d97a94d3fb9e1bbbfc.tar.gz |
vboot: Jump to RW early
This change makes EC run vboot in the HOOK task. The vboot routine
requires battery and charger info. It waits in a deferred call
loop until the charge manager is initialized.
BUG=b:63586051
BRANCH=none
TEST=Verify the following cases:
A. Hardware reboot (type-c/BJ)
1. Unplug AC in S0 then plug in AC: BOOT/BOOT
2. Unplug AC in S5 then plug in AC: S5/S5
3. Unplug AC after A.2 then plug in AC: S5/S5
4. Press PB in S5: BOOT/BOOT
B. Software reboot (type-c/BJ)
1. Run EC reboot command in S0: BOOT/BOOT
2. Run EC reboot command in S5: BOOT/BOOT
3. Run EC reboot ap-off command in S0: S5/S5
4. Run EC reboot ap-off command in S5: S5/S5
5. Run host reboot command: BOOT/BOOT
6. Run host shutdown command: S5/S5
C. Recovery tests
1. Press RB and PB in S0: FAIL(*1)/PASS
2. Press RB and PB in S5: FAIL(*1)/PASS(*2)
3. Unplug AC in S0 then press RB and plug in AC: PASS/PASS
4. Unplug AC in S5 then press RB and plug in AC: PASS(*2)/PASS(*2)
*1: b:63668669
*2: b:63669512. Requires one more PB press.
Change-Id: I28f37fdad7f83d0d44570b9003e8c6a4b83b832f
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/568699
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/system.c | 8 | ||||
-rw-r--r-- | common/vboot/vboot.c | 72 |
2 files changed, 60 insertions, 20 deletions
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); |