blob: 39a4dccedb0ea5be1069dfedb28ad3ce168def6c [file] [log] [blame]
// Copyright 2021 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.
package firmware
import (
"context"
"time"
"chromiumos/tast/common/servo"
"chromiumos/tast/ctxutil"
"chromiumos/tast/testing"
"chromiumos/tast/testing/hwdep"
)
func init() {
testing.AddTest(&testing.Test{
Func: FpFlashFpMcuHello,
Desc: "Validate that flash_fp_mcu can communicate with the FPMCU's bootloader",
Contacts: []string{
"hesling@chromium.org", // Test author
"chromeos-fingerprint@google.com",
},
Attr: []string{"group:mainline", "group:fingerprint-cq"},
// On hatch+bloonchipper(Dratini) flash_fp_mcu --hello takes about
// 4 seconds and the full test with reboot takes about 30 seconds.
// Given flash_fp_mcu can run into scenarios were it needs to retry a
// few times, we delegate a minute for flash_fp_mcu and a minute for
// the reboot cleanup.
Timeout: 2 * time.Minute,
SoftwareDeps: []string{"biometrics_daemon"},
HardwareDeps: hwdep.D(hwdep.Fingerprint()),
Vars: []string{"servo"},
})
}
// FpFlashFpMcuHello checks if the flash_fp_mcu script can properly communicate
// with the FPMCU's ROM/vendor bootloader (not EC RO).
// This is achieved by invoking flash_fp_mcu with the "--hello" option.
//
// This does not have any preconditions, other than being able to disable the
// hardware write protect. This is because the *communication* with the
// bootloader should always be possible, regardless of the firmware/software-wp
// status of the FPMCU. However, flash_fp_mcu can fail if the FPMCU's FW
// doesn't respond after being returned to the normal operating mode.
// See https://source.chromium.org/search?q=file:flash_fp_mcu for behavior.
func FpFlashFpMcuHello(ctx context.Context, s *testing.State) {
defer func(ctx context.Context) {
// The flash_fp_mcu script will reboot the FPMCU. This causes the FPMCU
// to lose the at-boot TPM seed (provided by bio_crypto_init). The only
// way to restore the correct TPM seed is to reboot the DUT.
//
// This is also needed for Zork, where the cros-ec driver cannot be
// rebound without a DUT reboot.
testing.ContextLog(ctx, "Rebooting DUT to restore TPM seed")
if err := s.DUT().Reboot(ctx); err != nil {
s.Fatal("Failed to reboot device on test exit: ", err)
}
}(ctx)
// Reduce overall ctx time for servo and flash_fp_mcu by a minute to
// reserve the remaining minute for the above cleanup.
ctx, cancel := ctxutil.Shorten(ctx, time.Minute)
defer cancel()
servoSpec, ok := s.Var("servo")
if !ok {
servoSpec = ""
}
servop, err := servo.NewProxy(ctx, servoSpec, s.DUT().KeyFile(), s.DUT().KeyDir())
if err != nil {
s.Fatal("Failed to connect to servo: ", err)
}
defer servop.Close(ctx)
if err := servop.Servo().SetFWWPState(ctx, servo.FWWPStateOff); err != nil {
s.Fatal("Failed to disable hardware write protection: ", err)
}
testing.ContextLog(ctx, "Running flash_fp_mcu --hello")
cmd := s.DUT().Conn().CommandContext(ctx, "flash_fp_mcu", "--hello")
out, err := cmd.CombinedOutput()
s.Log("flash_fp_mcu output:", "\n", string(out))
if err != nil {
s.Fatal("Error encountered when running flash_fp_mcu: ", err)
}
}