CFT: move servo_lib out of firmwareservice No reason to bury this library so deep in the firmwareservice. See what this library does in README.md BUG=None TEST=local testing Change-Id: I8a36c216d1292fc2fd65b104d023e5b9c002ff29 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/3345755 Auto-Submit: Sergey Frolov <sfrolov@google.com> Reviewed-by: Jaques Clapauch <jaquesc@google.com> Tested-by: Sergey Frolov <sfrolov@google.com> Reviewed-by: Otabek Kasimov <otabek@google.com> Commit-Queue: Jaques Clapauch <jaquesc@google.com>
diff --git a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_config.go b/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_config.go deleted file mode 100644 index 45003c5..0000000 --- a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_config.go +++ /dev/null
@@ -1,42 +0,0 @@ -// 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 servo_lib provides servo-related variables, such as dut-controls -// to be run before and after flashing, and a programmer argument. -package servo_lib - -import "fmt" - -type ServoConfig struct { - dut_on [][]string - dut_off [][]string - programmer string -} - -type UnsupportedServoError struct { - servoType ServoType - board string -} - -func (m *UnsupportedServoError) Error() string { - return fmt.Sprintf("board %v does not support servo %v", m.board, m.servoType.string) -} - -func GetServoConfig(board, servoSerial string, servoType ServoType) (*ServoConfig, error) { - dut_on := [][]string{{"cpu_fw_spi:on"}} - dut_off := [][]string{{"cpu_fw_spi:off"}} - programmer := "" - if servoType.IsV2() { - programmer = fmt.Sprintf("ft2232_spi:type=google-servo-v2,serial=%v", servoSerial) - } else if servoType.IsMicro() || servoType.IsC2D2() { - programmer = fmt.Sprintf("raiden_debug_spi:serial=%v", servoSerial) - } else if servoType.IsCCD() { - dut_on = nil - dut_off = nil - programmer = fmt.Sprintf("raiden_debug_spi:target=AP,serial=%v", servoSerial) - } else { - return nil, &UnsupportedServoError{servoType, board} - } - return &ServoConfig{dut_on, dut_off, programmer}, nil -}
diff --git a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_type.go b/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_type.go deleted file mode 100644 index 70f1871..0000000 --- a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_type.go +++ /dev/null
@@ -1,40 +0,0 @@ -// 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 servo_lib - -import "strings" - -type ServoType struct { - string -} - -func NewServoType(servo_type string) ServoType { - return ServoType{servo_type} -} - -func (s *ServoType) IsV2() bool { - return strings.Contains(s.string, "servo_v2") -} -func (s *ServoType) IsV4() bool { - return strings.Contains(s.string, "servo_v4") -} -func (s *ServoType) IsC2D2() bool { - return strings.Contains(s.string, "c2d2") -} -func (s *ServoType) IsCCD() bool { - return strings.Contains(s.string, "ccd") -} -func (s *ServoType) IsMicro() bool { - return strings.Contains(s.string, "servo_micro") -} - -func (s *ServoType) GetSerialNumberOption() string { - if s.IsV4() && s.IsCCD() { - return "ccd_serialname" - } - if s.IsV4() && s.IsMicro() { - return "servo_micro_serialname" - } - return "serialname" -}
diff --git a/src/chromiumos/test/provision/lib/servo_lib/OWNERS b/src/chromiumos/test/provision/lib/servo_lib/OWNERS new file mode 100644 index 0000000..5ea8372 --- /dev/null +++ b/src/chromiumos/test/provision/lib/servo_lib/OWNERS
@@ -0,0 +1,3 @@ +sfrolov@google.com + +include ../../OWNERS
diff --git a/src/chromiumos/test/provision/lib/servo_lib/README.md b/src/chromiumos/test/provision/lib/servo_lib/README.md new file mode 100644 index 0000000..d5386a9 --- /dev/null +++ b/src/chromiumos/test/provision/lib/servo_lib/README.md
@@ -0,0 +1,16 @@ +# servo lib + +This module allows users to get correct servo-related variables for +flashing, specifically, dut-controls to be run before and after flashing +and the programmer argument. + +These arguments mostly* depend on type of the servo in use. Thus, this +module provides utilities to parse the type of the servo. + +\* - However, some boards require special arguments, configs for which may +be found +[here](https://source.corp.google.com/chromeos_public/chromite/lib/firmware/ap_firmware_config/). +TODO: get labstations to install those configs via either `cros` tool +(requires cros_sdk) or simply by installing an +[ebuild](https://source.corp.google.com/chromeos_public/src/third_party/chromiumos-overlay/sys-firmware/ap-firmware-config/ap-firmware-config-0.0.1-r238.ebuild;l=1) +and use them.
diff --git a/src/chromiumos/test/provision/lib/servo_lib/servo_config.go b/src/chromiumos/test/provision/lib/servo_lib/servo_config.go new file mode 100644 index 0000000..decb05d --- /dev/null +++ b/src/chromiumos/test/provision/lib/servo_lib/servo_config.go
@@ -0,0 +1,62 @@ +// Copyright 2022 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 servo_lib provides servo-related variables, such as dut-controls +// to be run before and after flashing, and a programmer argument. +package servo_lib + +import "fmt" + +// ServoConfig structure holds the servo-related variables that are necessary +// for provisioning firmware over Servo. +type ServoConfig struct { + // dut-controls to run before flashing. + DutOn [][]string + // dut-controls to run after flashing. + DutOff [][]string + // programmer (-p) argument for futility. + Programmer string + // extra arguments to provide to futility, such as --fast or --force. + ExtraArgs []string + // servo_type in use. + ServoType ServoType +} + +type UnsupportedServoError struct { + ServoType ServoType + Board string +} + +func (m *UnsupportedServoError) Error() string { + return fmt.Sprintf("board %v does not support servo %v", m.Board, m.ServoType.string) +} + +// GetServoConfig returns ServoConfig, that depends on the |board| and |servoType|, +// and contains variables, necessary to flash that setup over Servo. One of those +// variables is a programmer argument, which needs to include |servoSerial| - serial +// number of the given DUT. +// Returns an error if a given |board| cannot be flashed using given |servoType|. +func GetServoConfig(board, servoSerial string, servoType ServoType) (*ServoConfig, error) { + dutOn := [][]string{{"cpu_fw_spi:on"}} + dutOff := [][]string{{"cpu_fw_spi:off"}} + programmer := "" + extraArgs := []string{} + if servoType.IsV2() { + programmer = fmt.Sprintf("ft2232_spi:type=google-servo-v2,serial=%v", servoSerial) + } else if servoType.IsMicro() || servoType.IsC2D2() { + programmer = fmt.Sprintf("raiden_debug_spi:serial=%v", servoSerial) + } else if servoType.IsCCD() { + dutOn = nil + dutOff = nil + programmer = fmt.Sprintf("raiden_debug_spi:target=AP,serial=%v", servoSerial) + // By default, futility will verify images by re-reading them, + // but this is extremely slow on CCDs (roughly over 30 mins), + // so we turn verification off with "--fast". + // Verification doesn't save DUTs from bricking. + extraArgs = []string{"--fast"} + } else { + return nil, &UnsupportedServoError{servoType, board} + } + return &ServoConfig{dutOn, dutOff, programmer, extraArgs, servoType}, nil +}
diff --git a/src/chromiumos/test/provision/lib/servo_lib/servo_type.go b/src/chromiumos/test/provision/lib/servo_lib/servo_type.go new file mode 100644 index 0000000..b0506ed --- /dev/null +++ b/src/chromiumos/test/provision/lib/servo_lib/servo_type.go
@@ -0,0 +1,82 @@ +// Copyright 2022 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 servo_lib + +import ( + "fmt" + "strings" +) + +// ServoType is the used servo type, as reported by `dut-control servo_type`. +// ServoType determines arguments to use with futility when flashing. +type ServoType struct { + string +} + +func NewServoType(servo_type string) ServoType { + return ServoType{servo_type} +} + +func (s *ServoType) IsV2() bool { + return strings.Contains(s.string, "servo_v2") +} +func (s *ServoType) IsV4() bool { + return strings.Contains(s.string, "servo_v4") +} +func (s *ServoType) IsC2D2() bool { + return strings.Contains(s.string, "c2d2") +} +func (s *ServoType) IsCCD() bool { + return strings.Contains(s.string, "ccd") +} +func (s *ServoType) IsMicro() bool { + return strings.Contains(s.string, "servo_micro") +} + +func (s *ServoType) GetSerialNumberOption() string { + if s.IsV4() && s.IsCCD() { + return "ccd_serialname" + } + if s.IsV4() && s.IsMicro() { + return "servo_micro_serialname" + } + return "serialname" +} + +func (s *ServoType) IsMultipleServos() bool { + return strings.Contains(s.string, "_and_") +} + +// PickServoSubtype allows to pick a single servo from dual servo types, +// such as "servo_v4p1_with_servo_micro_and_ccd_cr50". +// PickServoSubtype assumes that the servo is dual, use IsMultipleServos() +// function to check for that. +// |preferCCD| tells the function to pick the CCD servo, otherwise other servo +// type (likely servo_micro) will be chosen. Example: +// If preferCCD is true, string above will return "servo_v4p1_with_ccd_cr50". +// If preferCCD is false, it will return "servo_v4p1_with_servo_micro". +func (s *ServoType) PickServoSubtype(preferCCD bool) string { + withSplit := strings.Split(s.string, "_with_") + if len(withSplit) <= 1 { + return strings.Split(s.string, "_and_")[0] + } + + // for "servo_v4p1_with_servo_micro_and_ccd_cr50" this would return "servo_v4p1" + servoVer := withSplit[0] + + servoSubtypes := strings.Split(withSplit[1], "_and_") + subtypeToUse := "" + for _, servoSubType := range servoSubtypes { + subtypeToUse = servoSubType + isCCD := strings.Contains(servoSubType, "ccd") + if isCCD && preferCCD { + break + } + if !isCCD && !preferCCD { + break + } + } + + return fmt.Sprintf("%v_with_%v", servoVer, subtypeToUse) +}
diff --git a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_type_test.go b/src/chromiumos/test/provision/lib/servo_lib/servo_type_test.go similarity index 78% rename from src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_type_test.go rename to src/chromiumos/test/provision/lib/servo_lib/servo_type_test.go index c53e29d..3c648e0 100644 --- a/src/chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib/servo_type_test.go +++ b/src/chromiumos/test/provision/lib/servo_lib/servo_type_test.go
@@ -1,10 +1,10 @@ -// Copyright 2021 The Chromium OS Authors. All rights reserved. +// Copyright 2022 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 servo_lib_test import ( - servo_lib "chromiumos/test/provision/cmd/provisionserver/bootstrap/services/firmwareservice/servo/lib" + "chromiumos/test/provision/lib/servo_lib" "testing" ) @@ -98,3 +98,19 @@ } } } + +func TestPickServoSubtype(t *testing.T) { + dualServoType := servo_lib.NewServoType("servo_v4p1_with_servo_micro_and_ccd_cr50") + + expectedPreferCCD := "servo_v4p1_with_ccd_cr50" + expectedNoPreferCCD := "servo_v4p1_with_servo_micro" + + if gotPreferCCD := dualServoType.PickServoSubtype(true /*prefer CCD*/); gotPreferCCD != expectedPreferCCD { + t.Errorf("%v PickOneFromDual(true) expected: %v, got: %v", + dualServoType, expectedPreferCCD, gotPreferCCD) + } + if gotNoPreferCCD := dualServoType.PickServoSubtype(false /*prefer CCD*/); gotNoPreferCCD != expectedNoPreferCCD { + t.Errorf("%v PickOneFromDual(true) expected: %v, got: %v", + dualServoType, expectedNoPreferCCD, gotNoPreferCCD) + } +}