blob: bb69f5b18abf292936d714b37ff9c86bddc2ec83 [file] [log] [blame]
// Copyright 2020 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 main
import (
"firmware/internal/pkg/dutio"
"fmt"
)
// TODO(kmshelton): Move the dut definition into the dutio package and make SendSSHCommand a method on dut.
type dut struct {
hostname string
model string
phase string
crOSVersion string
biosVersion string
ecROVersion string
ecRWVersion string
gscVersion string
cpuArch string
cpuModel string
cpuSpeed string
totalMemory string
memoryType string
mmcModel string
mmcFirmwareVersion string
nvmeModel string
nvmeFirmwareVersion string
vpd string
}
// setModel interfaces with a DUT and sets the model field (the DUT's market identifier).
func (d *dut) setModel() error {
// TODO(kmshelton): Here and elsewhere: use dbus instead of executing commands directly
// on the DUT (by exposing such functionality in dutio).
out, err := dutio.SendSSHCommand(d.hostname, "cros_config / name")
if err != nil {
return err
}
// TODO(kmshelton): Add some validation on out (here and elsewhere).
d.model = out
return nil
}
// setPhase interfaces with a DUT and sets the phase field (the DUT's hardware stage).
func (d *dut) setPhase() error {
// Phase is not implemented in dut.sh (which this utility replaces), likely because
// getting phase involves interfacing with the HWID database.
// TODO(b:150699151): Implement this setter (interface with the HWID database).
d.phase = ""
return nil
}
// setCrOSVersion interfaces with a DUT and sets the crOSVersion field (the DUT's version of ChromeOS).
func (d *dut) setCrOSVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "grep '^CHROMEOS_RELEASE_DESCRIPTION=' /etc/lsb-release | cut -d= -f2")
if err != nil {
return err
}
d.crOSVersion = out
return nil
}
// setBIOSVersion interfaces with a DUT and sets the biosVersion field (the DUT's application processor firmware version).
func (d *dut) setBIOSVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "echo $(crossystem ro_fwid) / $(crossystem fwid)")
if err != nil {
return err
}
d.biosVersion = out
return nil
}
// setECROVersion interfaces with a DUT and sets the ecROVersion field (the version of the DUT's read-only copy of the primary
// embedded controller's firmware version).
func (d *dut) setECROVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "ectool version | awk '/^RO/{print $3}'")
if err != nil {
return err
}
d.ecROVersion = out
return nil
}
// setECRWVersion interfaces with a DUT and sets the ecRWVersion field (the version of the DUT's read-write copy of the primary
// embedded controller's firmware version).
func (d *dut) setECRWVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "ectool version | awk '/^RW/{print $3}'")
if err != nil {
return err
}
d.ecRWVersion = out
return nil
}
// setGSCVersion interfaces with a DUT and sets the gscVersion field (the version of the DUT's Google Security Chip firmware).
func (d *dut) setGSCVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "echo $(grep ^RO /var/cache/cr50-version) / $(grep ^RW /var/cache/cr50-version)")
if err != nil {
return err
}
d.gscVersion = out
return nil
}
// setCPUArch interfaces with a DUT and sets the cpuArch field (the architecture of the central processing unit).
func (d *dut) setCPUArch() error {
out, err := dutio.SendSSHCommand(d.hostname, "lscpu | awk '/^Architecture:/{print $2}'")
if err != nil {
return err
}
d.cpuArch = out
return nil
}
// setCPUModel interfaces with a DUT and sets the cpuModel field (the market identifier of the central processing unit).
func (d *dut) setCPUModel() error {
out, err := dutio.SendSSHCommand(d.hostname, "lscpu | grep '^Model name:' | cut -d: -f2-")
if err != nil {
return err
}
d.cpuModel = out
return nil
}
// setCPUSpeed interfaces with a DUT and sets the cpuSpeed field (the clock frequency of the central processing unit).
func (d *dut) setCPUSpeed() error {
out, err := dutio.SendSSHCommand(d.hostname, "lscpu | grep '^CPU max MHz:' | cut -d: -f2-")
if err != nil {
return err
}
d.cpuSpeed = out
return nil
}
// setTotalMemory interfaces with a DUT and sets the totalMemory field (the size of the main memory).
func (d *dut) setTotalMemory() error {
out, err := dutio.SendSSHCommand(d.hostname, "grep '^MemTotal:' /proc/meminfo 2>/dev/null | cut -d: -f2-")
if err != nil {
return err
}
d.totalMemory = out
return nil
}
// setMemoryType interfaces with a DUT and sets the memoryType field (the technology class of the main memory).
func (d *dut) setMemoryType() error {
out, err := dutio.SendSSHCommand(d.hostname, "mosys memory spd print id 2>/dev/null | cut -d'|' -f2- | sort -u")
if err != nil {
return err
}
d.memoryType = out
return nil
}
// setMMCModel interfaces with a DUT and sets the mmcModel field (the multimedia card market identifier).
func (d *dut) setMMCModel() error {
out, err := dutio.SendSSHCommand(d.hostname, "if [ -e /dev/mmcblk ]; then cat /dev/mmcblk/device/name; else true; fi")
if err != nil {
return err
}
d.mmcModel = out
return nil
}
// setMMCFirmwareVersion interfaces with a DUT and sets the version of the multimedia card's firmware.
func (d *dut) setMMCFirmwareVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "if [ -e /dev/mmcblk ]; then cat /dev/mmcblk/device/firmware; else true; fi")
if err != nil {
return err
}
d.mmcFirmwareVersion = out
return nil
}
// setNVMEModel interfaces with a DUT and sets the nvmeModel (the market identifier of the non-volatile memory express solid state drive).
func (d *dut) setNVMEModel() error {
out, err := dutio.SendSSHCommand(d.hostname, "if [ -e /dev/nvme0n1 ]; then cat /dev/nvme0n1/device/name; else true; fi")
if err != nil {
return err
}
d.nvmeModel = out
return nil
}
// setNVMEFirmwareVersion interfaces with a DUT and sets the nvmeFirmwareVersion field (the firmware version of the non-volatile
// memory express solid state drive).
func (d *dut) setNVMEFirmwareVersion() error {
out, err := dutio.SendSSHCommand(d.hostname, "if [ -e /dev/nvme0n1 ]; then cat /dev/nvme0n1/device/fwrev; else true; fi")
if err != nil {
return err
}
d.nvmeFirmwareVersion = out
return nil
}
// setVPD interfaces with a DUT and sets the vpd field (the "Vital Product Data").
func (d *dut) setVPD() error {
out, err := dutio.SendSSHCommand(d.hostname, "vpd -l")
if err != nil {
return err
}
d.vpd = out
return nil
}
// newDUT initializes all the fields in a dut struct.
func newDUT(hostname string) dut {
d := dut{hostname: hostname}
d.setModel()
d.setPhase()
d.setCrOSVersion()
d.setBIOSVersion()
d.setECROVersion()
d.setECRWVersion()
d.setGSCVersion()
d.setCPUArch()
d.setCPUModel()
d.setCPUSpeed()
d.setTotalMemory()
d.setMemoryType()
d.setMMCModel()
d.setMMCFirmwareVersion()
d.setNVMEModel()
d.setNVMEFirmwareVersion()
d.setVPD()
return d
}
func main() {
fmt.Println("This utility is undergoing incremental development. Please use crostestutils/provingground/firmware/dut.sh for now.")
// TODO(kmshelton): Unhardcode the hostname.
d := newDUT("chromeos1-row1-rack8-host2.cros.corp.google.com")
fmt.Printf("%+v\n", d)
}