summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2020-01-03 14:29:41 -0800
committerCommit Bot <commit-bot@chromium.org>2020-01-07 00:17:10 +0000
commitcee40844bcbd751ca854cae30cb6756c446880cd (patch)
tree68b6449b4ee410f4ba28fe0da6b5d168addc78f1
parent943645d993c88754b2db1e86734210256c505e07 (diff)
downloadchrome-ec-cee40844bcbd751ca854cae30cb6756c446880cd.tar.gz
utils/extras: do not build unnecessary tools
The vast majority of tools built from the ./util directory and many built from ./extra/usb_updater directory are not used by Cr50, let's not build them. Also eliminating some irrelevant pre-upload checks. BRANCH=cr50, cr50-mp BUG=b:145912698 TEST=verified that all the following commands succeed: make buildall -j make BOARD=cr50 CR50_DEV=1 -j make BOARD=cr50 CR50_SQA=1 -j make -C extra/usb_updater Change-Id: I0040ceab95ad280bda86ef599b3e902addcbdcde Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1986943 Reviewed-by: Namyoon Woo <namyoon@chromium.org>
-rw-r--r--Makefile2
-rw-r--r--PRESUBMIT.cfg4
-rw-r--r--extra/usb_updater/Makefile6
l---------extra/usb_updater/ecusb1
-rwxr-xr-xextra/usb_updater/fw_update.py421
-rw-r--r--extra/usb_updater/sample_descriptor87
-rw-r--r--extra/usb_updater/servo_micro.json15
-rwxr-xr-xextra/usb_updater/servo_updater.py305
-rw-r--r--extra/usb_updater/servo_v4.json15
-rw-r--r--extra/usb_updater/usb_updater2.c1244
-rwxr-xr-xutil/battery_temp56
-rw-r--r--util/build.mk110
-rw-r--r--util/cbi-util.c492
-rw-r--r--util/chargen69
-rw-r--r--util/comm-dev.c293
-rw-r--r--util/comm-host.c157
-rw-r--r--util/comm-host.h103
-rw-r--r--util/comm-i2c.c255
-rw-r--r--util/comm-lpc.c316
-rw-r--r--util/comm-servo-spi.c357
-rw-r--r--util/cros_ec_dev.h98
-rw-r--r--util/ec3po/__init__.py25
-rwxr-xr-xutil/ec3po/console.py1125
-rwxr-xr-xutil/ec3po/console_unittest.py1626
-rw-r--r--util/ec3po/interpreter.py462
-rwxr-xr-xutil/ec3po/interpreter_unittest.py366
-rwxr-xr-xutil/ec3po/run_tests.sh9
-rw-r--r--util/ec3po/threadproc_shim.py66
-rw-r--r--util/ec_flash.c231
-rw-r--r--util/ec_flash.h62
-rw-r--r--util/ec_panicinfo.c126
-rw-r--r--util/ec_panicinfo.h19
-rw-r--r--util/ec_parse_panicinfo.c22
-rw-r--r--util/ec_sb_firmware_update.c843
-rw-r--r--util/ec_sb_firmware_update.h126
-rw-r--r--util/ec_uartd.c159
-rw-r--r--util/ecst.c2519
-rw-r--r--util/ecst.h278
-rw-r--r--util/ectool.c9397
-rw-r--r--util/ectool.h42
-rw-r--r--util/ectool_keyscan.c678
-rw-r--r--util/export_taskinfo.c43
-rwxr-xr-xutil/flash_ec1439
-rw-r--r--util/flash_fp_mcu298
-rwxr-xr-xutil/flash_pd.py348
-rwxr-xr-xutil/g_regs77
-rw-r--r--util/gdbinit172
-rw-r--r--util/gen_emmc_transfer_data.c158
-rw-r--r--util/gen_ipi_table.c58
-rw-r--r--util/gen_touchpad_hash.c174
-rw-r--r--util/genvif.c698
-rwxr-xr-xutil/host_command_check.sh135
-rwxr-xr-xutil/inject-keys.py127
-rw-r--r--util/iteflash.c2142
-rw-r--r--util/iteflash.md119
-rw-r--r--util/lbcc.c690
-rw-r--r--util/lbplay.c165
-rwxr-xr-xutil/linux_ec_commands_h_check.sh25
-rw-r--r--util/lock/android.c51
-rw-r--r--util/lock/android.h54
-rw-r--r--util/lock/build.mk10
-rw-r--r--util/lock/file_lock.c262
-rw-r--r--util/lock/gec_lock.c45
-rw-r--r--util/lock/gec_lock.h51
-rw-r--r--util/lock/ipc_lock.h69
-rw-r--r--util/lock/locks.h38
-rwxr-xr-xutil/make_linux_ec_commands_h.sh76
-rw-r--r--util/misc_util.c175
-rw-r--r--util/openocd/lm4_chip.cfg11
-rw-r--r--util/openocd/lm4x_cmds.tcl51
-rw-r--r--util/openocd/npcx.cfg61
-rw-r--r--util/openocd/npcx_chip.cfg11
-rw-r--r--util/openocd/npcx_cmds.tcl184
-rw-r--r--util/openocd/nrf51_chip.cfg14
-rw-r--r--util/openocd/nrf51_cmds.tcl22
-rw-r--r--util/openocd/servo.cfg14
-rw-r--r--util/powerd_lock.c63
-rw-r--r--util/powerd_lock.h41
-rw-r--r--util/run_ects.py92
-rw-r--r--util/stm32mon.c1698
-rwxr-xr-xutil/tagbranch.sh84
-rw-r--r--util/temp_metrics.conf396
-rwxr-xr-xutil/test-inject-keys.sh111
-rwxr-xr-xutil/uart_stress_tester.py540
-rwxr-xr-xutil/unpack_ftb.py116
-rw-r--r--util/uut/cmd.c482
-rw-r--r--util/uut/cmd.h69
-rw-r--r--util/uut/com_port.h149
-rw-r--r--util/uut/l_com_port.c446
-rw-r--r--util/uut/lib_crc.c109
-rw-r--r--util/uut/lib_crc.h68
-rw-r--r--util/uut/main.c749
-rw-r--r--util/uut/main.h74
-rw-r--r--util/uut/opr.c550
-rw-r--r--util/uut/opr.h59
95 files changed, 1 insertions, 36549 deletions
diff --git a/Makefile b/Makefile
index 41e87a173b..4bcf468c5c 100644
--- a/Makefile
+++ b/Makefile
@@ -273,8 +273,6 @@ ifneq ($(PBDIR),)
include $(PBDIR)/build.mk
endif
include test/build.mk
-include util/build.mk
-include util/lock/build.mk
includes+=$(includes-y)
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
index eb8325b4dd..219253c9e9 100644
--- a/PRESUBMIT.cfg
+++ b/PRESUBMIT.cfg
@@ -1,7 +1,6 @@
[Hook Overrides]
branch_check: true
checkpatch_check: true
-kerneldoc_check: true
signoff_check: true
# We are using Linux style indentation with tabs
@@ -10,10 +9,7 @@ tab_check: false
[Hook Overrides Options]
checkpatch_check: --no-tree --ignore=MSLEEP,VOLATILE,SPDX_LICENSE_TAG
-kerneldoc_check: --include_regex=\bec_commands\.h$
[Hook Scripts]
presubmit_check = util/presubmit_check.sh
config_option_check = util/config_option_check.py
-host_command_check = util/host_command_check.sh
-ec_commands_h = util/linux_ec_commands_h_check.sh
diff --git a/extra/usb_updater/Makefile b/extra/usb_updater/Makefile
index 2f8f70a6d3..04adfff4dd 100644
--- a/extra/usb_updater/Makefile
+++ b/extra/usb_updater/Makefile
@@ -4,7 +4,7 @@
CC ?= gcc
PKG_CONFIG ?= pkg-config
-PROGRAMS := gsctool usb_updater2
+PROGRAMS := gsctool
LIBS :=
LFLAGS :=
CFLAGS := -std=gnu99 \
@@ -56,10 +56,6 @@ gsctool: $(GSCTOOL_OBJS) Makefile
gsctool.o: generated_version.h
-# common EC code USB updater
-usb_updater2: usb_updater2.c Makefile
- $(CC) $(CFLAGS) $< $(LFLAGS) $(LIBS) $(LIBS_common) -o $@
-
.PHONY: clean
generated_version.h: $(GSCTOOL_SOURCES)
diff --git a/extra/usb_updater/ecusb b/extra/usb_updater/ecusb
deleted file mode 120000
index c06ee0f51b..0000000000
--- a/extra/usb_updater/ecusb
+++ /dev/null
@@ -1 +0,0 @@
-../tigertool/ecusb/ \ No newline at end of file
diff --git a/extra/usb_updater/fw_update.py b/extra/usb_updater/fw_update.py
deleted file mode 100755
index 3755ba9d20..0000000000
--- a/extra/usb_updater/fw_update.py
+++ /dev/null
@@ -1,421 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2016 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.
-
-# Upload firmware over USB
-
-from __future__ import print_function
-
-import argparse
-import array
-import json
-import os
-import struct
-import sys
-import time
-from pprint import pprint
-import usb
-
-
-debug = False
-def debuglog(msg):
- if debug:
- print(msg)
-
-def log(msg):
- print(msg)
- sys.stdout.flush()
-
-
-"""Sends firmware update to CROS EC usb endpoint."""
-
-class Supdate(object):
- """Class to access firmware update endpoints.
-
- Usage:
- d = Supdate()
-
- Instance Variables:
- _dev: pyUSB device object
- _read_ep: pyUSB read endpoint for this interface
- _write_ep: pyUSB write endpoint for this interface
- """
- USB_SUBCLASS_GOOGLE_UPDATE = 0x53
- USB_CLASS_VENDOR = 0xFF
-
- def __init__(self):
- pass
-
-
- def connect_usb(self, serialname=None ):
- """Initial discovery and connection to USB endpoint.
-
- This searches for a USB device matching the VID:PID specified
- in the config file, optionally matching a specified serialname.
-
- Args:
- serialname: Find the device with this serial, in case multiple
- devices are attached.
-
- Returns:
- True on success.
- Raises:
- Exception on error.
- """
- # Find the stm32.
- vendor = self._brdcfg['vid']
- product = self._brdcfg['pid']
-
- dev_g = usb.core.find(idVendor=vendor, idProduct=product, find_all=True)
- dev_list = list(dev_g)
- if dev_list is None:
- raise Exception("Update", "USB device not found")
-
- # Check if we have multiple stm32s and we've specified the serial.
- dev = None
- if serialname:
- for d in dev_list:
- if usb.util.get_string(d, d.iSerialNumber) == serialname:
- dev = d
- break
- if dev is None:
- raise SusbError("USB device(%s) not found" % serialname)
- else:
- try:
- dev = dev_list[0]
- except:
- dev = dev_list.next()
-
- debuglog("Found stm32: %04x:%04x" % (vendor, product))
- self._dev = dev
-
- # Get an endpoint instance.
- try:
- dev.set_configuration()
- except:
- pass
- cfg = dev.get_active_configuration()
-
- intf = usb.util.find_descriptor(cfg, custom_match=lambda i: \
- i.bInterfaceClass==self.USB_CLASS_VENDOR and \
- i.bInterfaceSubClass==self.USB_SUBCLASS_GOOGLE_UPDATE)
-
- self._intf = intf
- debuglog("Interface: %s" % intf)
- debuglog("InterfaceNumber: %s" % intf.bInterfaceNumber)
-
- read_ep = usb.util.find_descriptor(
- intf,
- # match the first IN endpoint
- custom_match = \
- lambda e: \
- usb.util.endpoint_direction(e.bEndpointAddress) == \
- usb.util.ENDPOINT_IN
- )
-
- self._read_ep = read_ep
- debuglog("Reader endpoint: 0x%x" % read_ep.bEndpointAddress)
-
- write_ep = usb.util.find_descriptor(
- intf,
- # match the first OUT endpoint
- custom_match = \
- lambda e: \
- usb.util.endpoint_direction(e.bEndpointAddress) == \
- usb.util.ENDPOINT_OUT
- )
-
- self._write_ep = write_ep
- debuglog("Writer endpoint: 0x%x" % write_ep.bEndpointAddress)
-
- return True
-
-
- def wr_command(self, write_list, read_count=1, wtimeout=100, rtimeout=2000):
- """Write command to logger logic..
-
- This function writes byte command values list to stm, then reads
- byte status.
-
- Args:
- write_list: list of command byte values [0~255].
- read_count: number of status byte values to read.
- wtimeout: mS to wait for write success
- rtimeout: mS to wait for read success
-
- Returns:
- status byte, if one byte is read,
- byte list, if multiple bytes are read,
- None, if no bytes are read.
-
- Interface:
- write: [command, data ... ]
- read: [status ]
- """
- debuglog("wr_command(write_list=[%s] (%d), read_count=%s)" % (
- list(bytearray(write_list)), len(write_list), read_count))
-
- # Clean up args from python style to correct types.
- write_length = 0
- if write_list:
- write_length = len(write_list)
- if not read_count:
- read_count = 0
-
- # Send command to stm32.
- if write_list:
- cmd = write_list
- ret = self._write_ep.write(cmd, wtimeout)
- debuglog("RET: %s " % ret)
-
- # Read back response if necessary.
- if read_count:
- bytesread = self._read_ep.read(512, rtimeout)
- debuglog("BYTES: [%s]" % bytesread)
-
- if len(bytesread) != read_count:
- debuglog("Unexpected bytes read: %d, expected: %d" % (len(bytesread), read_count))
- pass
-
- debuglog("STATUS: 0x%02x" % int(bytesread[0]))
- if read_count == 1:
- return bytesread[0]
- else:
- return bytesread
-
- return None
-
- def stop(self):
- """Finalize system flash and exit."""
- cmd = struct.pack(">I", 0xB007AB1E)
- read = self.wr_command(cmd, read_count=4)
-
- if len(read) == 4:
- log("Finished flashing")
- return
-
- raise Exception("Update", "Stop failed [%s]" % read)
-
-
- def write_file(self):
- """Write the update region packet by packet to USB
-
- This sends write packets of size 128B out, in 32B chunks.
- Overall, this will write all data in the inactive code region.
-
- Raises:
- Exception if write failed or address out of bounds.
- """
- region = self._region
- flash_base = self._brdcfg["flash"]
- offset = self._base - flash_base
- if offset != self._brdcfg['regions'][region][0]:
- raise Exception("Update", "Region %s offset 0x%x != available offset 0x%x" % (
- region, self._brdcfg['regions'][region][0], offset))
-
- length = self._brdcfg['regions'][region][1]
- log("Sending")
-
- # Go to the correct region in the ec.bin file.
- self._binfile.seek(offset)
-
- # Send 32 bytes at a time. Must be less than the endpoint's max packet size.
- maxpacket = 32
-
- # While data is left, create update packets.
- while length > 0:
- # Update packets are 128B. We can use any number
- # but the micro must malloc this memory.
- pagesize = min(length, 128)
-
- # Packet is:
- # packet size: page bytes transferred plus 3 x 32b values header.
- # cmd: n/a
- # base: flash address to write this packet.
- # data: 128B of data to write into flash_base
- cmd = struct.pack(">III", pagesize + 12, 0, offset + flash_base)
- read = self.wr_command(cmd, read_count=0)
-
- # Push 'todo' bytes out the pipe.
- todo = pagesize
- while todo > 0:
- packetsize = min(maxpacket, todo)
- data = self._binfile.read(packetsize)
- if len(data) != packetsize:
- raise Exception("Update", "No more data from file")
- for i in range(0, 10):
- try:
- self.wr_command(data, read_count=0)
- break
- except:
- log("Timeout fail")
- todo -= packetsize
- # Done with this packet, move to the next one.
- length -= pagesize
- offset += pagesize
-
- # Validate that the micro thinks it successfully wrote the data.
- read = self.wr_command("", read_count=4)
- result = struct.unpack("<I", read)
- result = result[0]
- if result != 0:
- raise Exception("Update", "Upload failed with rc: 0x%x" % result)
-
-
- def start(self):
- """Start a transaction and erase currently inactive region.
-
- This function sends a start command, and receives the base of the
- preferred inactive region. This could be RW, RW_B,
- or RO (if there's no RW_B)
-
- Note that the region is erased here, so you'd better program the RO if
- you just erased it. TODO(nsanders): Modify the protocol to allow active
- region select or query before erase.
- """
-
- # Size is 3 uint32 fields
- # packet: [packetsize, cmd, base]
- size = 4 + 4 + 4
- # Return value is [status, base_addr]
- expected = 4 + 4
-
- cmd = struct.pack("<III", size, 0, 0)
- read = self.wr_command(cmd, read_count=expected)
-
- if len(read) == 4:
- raise Exception("Update", "Protocol version 0 not supported")
- elif len(read) == expected:
- base, version = struct.unpack(">II", read)
- log("Update protocol v. %d" % version)
- log("Available flash region base: %x" % base)
- else:
- raise Exception("Update", "Start command returned %d bytes" % len(read))
-
- if base < 256:
- raise Exception("Update", "Start returned error code 0x%x" % base)
-
- self._base = base
- flash_base = self._brdcfg["flash"]
- self._offset = self._base - flash_base
-
- # Find our active region.
- for region in self._brdcfg['regions']:
- if (self._offset >= self._brdcfg['regions'][region][0]) and \
- (self._offset < (self._brdcfg['regions'][region][0] + \
- self._brdcfg['regions'][region][1])):
- log("Active region: %s" % region)
- self._region = region
-
-
- def load_board(self, brdfile):
- """Load firmware layout file.
-
- example as follows:
- {
- "board": "servo micro",
- "vid": 6353,
- "pid": 20506,
- "flash": 134217728,
- "regions": {
- "RW": [65536, 65536],
- "PSTATE": [61440, 4096],
- "RO": [0, 61440]
- }
- }
-
- Args:
- brdfile: path to board description file.
- """
- with open(brdfile) as data_file:
- data = json.load(data_file)
-
- # TODO(nsanders): validate this data before moving on.
- self._brdcfg = data;
- if debug:
- pprint(data)
-
- log("Board is %s" % self._brdcfg['board'])
- # Cast hex strings to int.
- self._brdcfg['flash'] = int(self._brdcfg['flash'], 0)
- self._brdcfg['vid'] = int(self._brdcfg['vid'], 0)
- self._brdcfg['pid'] = int(self._brdcfg['pid'], 0)
-
- log("Flash Base is %x" % self._brdcfg['flash'])
- self._flashsize = 0
- for region in self._brdcfg['regions']:
- base = int(self._brdcfg['regions'][region][0], 0)
- length = int(self._brdcfg['regions'][region][1], 0)
- log("region %s\tbase:0x%08x size:0x%08x" % (
- region, base, length))
- self._flashsize += length
-
- # Convert these to int because json doesn't support hex.
- self._brdcfg['regions'][region][0] = base
- self._brdcfg['regions'][region][1] = length
-
- log("Flash Size: 0x%x" % self._flashsize)
-
- def load_file(self, binfile):
- """Open and verify size of the target ec.bin file.
-
- Args:
- binfile: path to ec.bin
-
- Raises:
- Exception on file not found or filesize not matching.
- """
- self._filesize = os.path.getsize(binfile)
- self._binfile = open(binfile)
-
- if self._filesize != self._flashsize:
- raise Exception("Update", "Flash size 0x%x != file size 0x%x" % (self._flashsize, self._filesize))
-
-
-
-# Generate command line arguments
-parser = argparse.ArgumentParser(description="Update firmware over usb")
-parser.add_argument('-b', '--board', type=str, help="Board configuration json file", default="board.json")
-parser.add_argument('-f', '--file', type=str, help="Complete ec.bin file", default="ec.bin")
-parser.add_argument('-s', '--serial', type=str, help="Serial number", default="")
-parser.add_argument('-l', '--list', action="store_true", help="List regions")
-parser.add_argument('-v', '--verbose', action="store_true", help="Chatty output")
-
-def main():
- global debug
- args = parser.parse_args()
-
-
- brdfile = args.board
- serial = args.serial
- binfile = args.file
- if args.verbose:
- debug = True
-
- with open(brdfile) as data_file:
- names = json.load(data_file)
-
- p = Supdate()
- p.load_board(brdfile)
- p.connect_usb(serialname=serial)
- p.load_file(binfile)
-
- # List solely prints the config.
- if (args.list):
- return
-
- # Start transfer and erase.
- p.start()
- # Upload the bin file
- log("Uploading %s" % binfile)
- p.write_file()
-
- # Finalize
- log("Done. Finalizing.")
- p.stop()
-
-if __name__ == "__main__":
- main()
-
-
diff --git a/extra/usb_updater/sample_descriptor b/extra/usb_updater/sample_descriptor
deleted file mode 100644
index 1566e9e2e1..0000000000
--- a/extra/usb_updater/sample_descriptor
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2018 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.
-#
-# Hash descriptor database file consists of sections for various Chrome OS
-# boards. Each board description section starts with a line of 4 characters
-# which is the board ID (the same as the board's RLZ code).
-#
-# Each board description section includes variable number of range
-# descriptor entries, each entry consisting of semicolon separated fields:
-#
-# {a|e|g}:{h|d}:base_addr:size[:value[:value[:value...]]]]
-#
-# Where
-#
-# - the first sindgle character field defines the way the range is accessed:
-# a - AP flash
-# e - EC flash
-# g - EC flash requiring gang programming mode
-# - the second single character field defines the range type
-# h - Cr50 returns the hash of the range
-# d - Cr50 returns actual contents of the range (hex dump)
-# - the third and and forth fields are base address and size of the range
-# - ranges of type 'h' include one or more values for the hash of the range.
-#
-# Descriptor entries can be split along multiple lines. Each entry is
-# terminated by an empty line. Board description section is completed when
-# another board ID or end of file is encountered.
-#
-# All values are expressed in hex. Repeating empty lines and lines starting
-# with '#' are ignored.
-#
-
-QZUX
-
-# 1: Valid hash section.
-a:h:0:10000:
-756c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf3503:
-336c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf3503:
-446c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf3503
-
-# 2: Valid dump section.
-a:d:10:10
-
-# 3: Valid hash section.
-e:h:0:100:
-55d262badc1116520a7ae1d3fda380c0382b4b87f0db10de6495053ba3aadb87:
-444442badc1116520a7ae1d3fda380c0382b4b87f0db10de6495053ba3aadb87:
-443322badc1116520a7ae1d3fda380c0382b4b87f0db10de6495053ba3aadb87
-
-# 4: Invalid dump section (includes hash)
-a:d:20:10:55d262badc1116520a7ae1d3fda380c0382b4b87f0db10de6495053ba3aadb87
-
-# 5: Invalid hash section (does not include hash)
-e:h:0:100:
-
-# 6: Another invalid hash section (does not include hash)
-e:h:0:100:
-
-# extra empty lines
-
-
-# 7: Invalid hash section (hash too short)
-e:h:0:100:
-55d262badc1116520a7ae1d3fda380c0382b4b87f0db10de6495053ba3aadb8
-
-# 8: Invalid hash section (hash too long)
-a:h:0:10000:
-756c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf35034:
-336c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf3503
-
-# 9: Invalid hash section (hash includes non-hex value)
-a:h:0:10000:
-756c41b90ac9aa23a6c98ce13549dccd7xe0a83f8537eb834d9cfc3d12bf3503:
-336c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf3505
-
-# 10: Invalid hash section (hash does not include 3 variants)
-a:h:0:10000:
-756c41b90ac9aa23a6c98ce13549dccd75e0a83f8537eb834d9cfc3d12bf3503:
-336c41b90ac9aa23a6c98ce13549dccd72e0a83f8537eb834d9cfc3d12bf3505
-
-# 11: Invalid dump section (size includes non hex character)
-a:d:10:10x
-
-ABCD
-
-a:d:10:10
diff --git a/extra/usb_updater/servo_micro.json b/extra/usb_updater/servo_micro.json
deleted file mode 100644
index 71b1fd25dc..0000000000
--- a/extra/usb_updater/servo_micro.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "Comment": "This file describes the updateable sections of the flash.",
- "board": "servo_micro",
- "vid": "0x18d1",
- "pid": "0x501a",
- "console": "3",
- "Comment on flash": "This is the base address of writeable flash",
- "flash": "0x8000000",
- "Comment on region format": "name: [baseoffset, length]",
- "regions": {
- "RW": ["0x10000", "0x10000"],
- "PSTATE": ["0xf000", "0x1000"],
- "RO": ["0x0000", "0xf000"]
- }
-}
diff --git a/extra/usb_updater/servo_updater.py b/extra/usb_updater/servo_updater.py
deleted file mode 100755
index c819230f21..0000000000
--- a/extra/usb_updater/servo_updater.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2016 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.
-
-from __future__ import print_function
-
-import argparse
-import errno
-import os
-import re
-import subprocess
-import time
-import tempfile
-
-import json
-import fw_update
-import ecusb.tiny_servo_common as c
-
-
-class ServoUpdaterException(Exception):
- """Raised on exceptions generated by servo_updater."""
-
-
-DEFAULT_BASE_PATH = '/usr/'
-TEST_IMAGE_BASE_PATH = '/usr/local/'
-
-COMMON_PATH = 'share/servo_updater'
-
-FIRMWARE_DIR = "firmware/"
-CONFIGS_DIR = "configs/"
-
-if os.path.exists(os.path.join(DEFAULT_BASE_PATH, COMMON_PATH)):
- BASE_PATH = DEFAULT_BASE_PATH
-elif os.path.exists(os.path.join(TEST_IMAGE_BASE_PATH, COMMON_PATH)):
- BASE_PATH = TEST_IMAGE_BASE_PATH
-else:
- raise ServoUpdaterException('servo_updater/ dir not found in known spots.')
-
-FIRMWARE_PATH = os.path.join(BASE_PATH, COMMON_PATH, FIRMWARE_DIR)
-CONFIGS_PATH = os.path.join(BASE_PATH, COMMON_PATH, CONFIGS_DIR)
-
-for p in [FIRMWARE_PATH, CONFIGS_PATH]:
- if not os.path.exists(p):
- raise ServoUpdaterException('Could not find required path %r' % p)
-
-def flash(brdfile, serialno, binfile):
- """Call fw_update to upload to updater USB endpoint."""
- p = fw_update.Supdate()
- p.load_board(brdfile)
- p.connect_usb(serialname=serialno)
- p.load_file(binfile)
-
- # Start transfer and erase.
- p.start()
- # Upload the bin file
- print("Uploading %s" % binfile)
- p.write_file()
-
- # Finalize
- print("Done. Finalizing.")
- p.stop()
-
-def flash2(vidpid, serialno, binfile):
- """Call fw update via usb_updater2 commandline."""
- tool = 'usb_updater2'
- cmd = "%s -d %s" % (tool, vidpid)
- if serialno:
- cmd += " -S %s" % serialno
- cmd += " -n"
- cmd += " %s" % binfile
-
- print(cmd)
- help_cmd = '%s --help' % tool
- with open('/dev/null') as devnull:
- sanity_check = subprocess.call(help_cmd.split(), stdout=devnull,
- stderr=devnull)
- if sanity_check:
- raise ServoUpdaterException('%s exit with res = %d. Make sure the tool '
- 'is available on the device.' % (help_cmd,
- sanity_check))
- res = subprocess.call(cmd.split())
-
- if res in (0, 1, 2):
- return res
- else:
- raise ServoUpdaterException("%s exit with res = %d" % (cmd, res))
-
-def connect(vidpid, iface, serialno, debuglog=False):
- """Connect to console.
-
- Args:
- vidpid: vidpid of desired device.
- iface: interface to connect.
- serialno: serial number, to differentiate multiple devices.
- debuglog: do chatty log.
-
- Returns:
- a connected pty object.
- """
- # Make sure device is up.
- c.wait_for_usb(vidpid, serialname=serialno)
-
- # make a console.
- pty = c.setup_tinyservod(vidpid, iface,
- serialname=serialno, debuglog=debuglog)
-
- return pty
-
-def select(vidpid, iface, serialno, region, debuglog=False):
- """Ensure the servo is in the expected ro/rw partition."""
-
- if region not in ["rw", "ro"]:
- raise Exception("Region must be ro or rw")
-
- pty = connect(vidpid, iface, serialno)
-
- if region is "ro":
- cmd = "reboot"
- else:
- cmd = "sysjump %s" % region
- pty._issue_cmd(cmd)
- time.sleep(1)
- pty.close()
-
-def do_version(vidpid, iface, serialno):
- """Check version via ec console 'pty'.
-
- Args:
- see connect()
-
- Returns:
- detected version number
-
- Commands are:
- # > version
- # ...
- # Build: tigertail_v1.1.6749-74d1a312e
- """
- pty = connect(vidpid, iface, serialno)
-
- cmd = '\r\nversion\r\n'
- regex = 'Build:\s+(\S+)[\r\n]+'
-
- results = pty._issue_cmd_get_results(cmd, [regex])[0]
- pty.close()
-
- return results[1].strip(' \t\r\n\0')
-
-def do_updater_version(vidpid, iface, serialno):
- """Check whether this uses python updater or c++ updater
-
- Args:
- see connect()
-
- Returns:
- updater version number. 2 or 6.
- """
- vers = do_version(vidpid, iface, serialno)
-
- # Servo versions below 58 are from servo-9040.B. Versions starting with _v2
- # are newer than anything _v1, no need to check the exact number. Updater
- # version is not directly queryable.
- if re.search('_v[2-9]\.\d', vers):
- return 6
- m = re.search('_v1\.1\.(\d\d\d\d)', vers)
- if m:
- version_number = int(m.group(1))
- if version_number < 5800:
- return 2
- else:
- return 6
- raise ServoUpdaterException(
- "Can't determine updater target from vers: [%s]" % vers)
-
-def findfiles(cname, fname):
- """Select config and firmware binary files.
-
- This checks default file names and paths.
- In: /usr/share/servo_updater/[firmware|configs]
- check for board.json, board.bin
-
- Args:
- cname: config name, or board name. eg. "servo_v4".
- fname: firmware binary name. Can be None to try default.
- Returns:
- cname, fname: validated filenames selected from the path.
- """
- if not os.path.isfile(cname):
- # If not an existing file, try checking on the default path.
- newname = CONFIGS_PATH + cname
- if os.path.isfile(newname):
- cname = newname
- elif os.path.isfile(newname + ".json"):
- # Try appending ".json" to convert board name to config file.
- cname = newname + ".json"
- else:
- raise ServoUpdaterException("Can't find file: %s." % cname)
-
- if not fname:
- # If None, try defaults.
- dev = None
- for default_f in ['servo_v4', 'servo_micro', 'sweetberry']:
- if default_f in cname:
- dev = default_f
- if os.path.isfile(FIRMWARE_PATH + dev + ".bin"):
- fname = FIRMWARE_PATH + dev + ".bin"
- elif not os.path.isfile(fname):
- # If a name is specified but not found, try the default path.
- if os.path.isfile(FIRMWARE_PATH + fname):
- fname = FIRMWARE_PATH + fname
- else:
- raise ServoUpdaterException("Can't find file: %s." % fname)
-
- return cname, fname
-
-def find_available_version(boardname, binfile):
- """Find the version string from the binary file.
-
- Args:
- boardname: the name of the board, eg. "servo_micro"
- binfile: the binary to search
-
- Returns:
- the version string.
- """
- rawstrings = subprocess.check_output(
- ['cbfstool', binfile, 'read', '-r', 'RO_FRID', '-f', '/dev/stdout'])
- m = re.match(r'%s_v\S+' % boardname, rawstrings)
- if m:
- newvers = m.group(0).strip(' \t\r\n\0')
- else:
- raise ServoUpdaterException("Can't find version from file: %s." % binfile)
-
- return newvers
-
-def main():
- parser = argparse.ArgumentParser(description="Image a servo micro device")
- parser.add_argument('-s', '--serialno', type=str,
- help="serial number to program", default=None)
- parser.add_argument('-b', '--board', type=str,
- help="Board configuration json file", default="servo_v4")
- parser.add_argument('-f', '--file', type=str,
- help="Complete ec.bin file", default=None)
- parser.add_argument('--force', action="store_true",
- help="Update even if version match", default=False)
- parser.add_argument('-v', '--verbose', action="store_true",
- help="Chatty output")
- parser.add_argument('-r', '--reboot', action="store_true",
- help="Always reboot, even after probe.")
-
- args = parser.parse_args()
-
- brdfile, binfile = findfiles(args.board, args.file)
-
- serialno = args.serialno
- debuglog = (args.verbose is True)
-
- with open(brdfile) as data_file:
- data = json.load(data_file)
-
- vidpid = "%04x:%04x" % (int(data['vid'], 0), int(data['pid'], 0))
- iface = int(data['console'], 0)
- boardname = data['board']
-
- if not args.force:
- vers = do_version(vidpid, iface, serialno)
- print("Current %s version is %s" % (boardname, vers))
-
- newvers = find_available_version(boardname, binfile)
- print("Available %s version is %s" % (boardname, newvers))
-
- if newvers == vers:
- print("No version update needed")
- if args.reboot is True:
- select(vidpid, iface, serialno, "ro", debuglog=debuglog)
- return
- else:
- print("Updating to recommended version.")
-
-
- select(vidpid, iface, serialno, "ro", debuglog=debuglog)
-
- vers = do_updater_version(vidpid, iface, serialno)
- if vers == 2:
- flash(brdfile, serialno, binfile)
- elif vers == 6:
- flash2(vidpid, serialno, binfile)
- else:
- raise ServoUpdaterException("Can't detect updater version")
-
- select(vidpid, iface, serialno, "rw", debuglog=debuglog)
-
- vers = do_updater_version(vidpid, iface, serialno)
- if vers == 2:
- flash(brdfile, serialno, binfile)
- elif vers == 6:
- flash2(vidpid, serialno, binfile)
- else:
- raise ServoUpdaterException("Can't detect updater version")
-
- select(vidpid, iface, serialno, "ro", debuglog=debuglog)
-
-if __name__ == "__main__":
- main()
diff --git a/extra/usb_updater/servo_v4.json b/extra/usb_updater/servo_v4.json
deleted file mode 100644
index e041f56b68..0000000000
--- a/extra/usb_updater/servo_v4.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "Comment": "This file describes the updateable sections of the flash.",
- "board": "servo_v4",
- "vid": "0x18d1",
- "pid": "0x501b",
- "console": "0",
- "Comment on flash": "This is the base address of writeable flash",
- "flash": "0x8000000",
- "Comment on region format": "name: [baseoffset, length]",
- "regions": {
- "RW": ["0x10000", "0x10000"],
- "PSTATE": ["0xf000", "0x1000"],
- "RO": ["0x0000", "0xf000"]
- }
-}
diff --git a/extra/usb_updater/usb_updater2.c b/extra/usb_updater/usb_updater2.c
deleted file mode 100644
index 10bfeee7bb..0000000000
--- a/extra/usb_updater/usb_updater2.c
+++ /dev/null
@@ -1,1244 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#include <asm/byteorder.h>
-#include <endian.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <libusb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <fmap.h>
-
-#ifndef __packed
-#define __packed __attribute__((packed))
-#endif
-
-#include "compile_time_macros.h"
-#include "misc_util.h"
-#include "usb_descriptor.h"
-#include "update_fw.h"
-#include "vb21_struct.h"
-
-#ifdef DEBUG
-#define debug printf
-#else
-#define debug(fmt, args...)
-#endif
-
-/*
- * This file contains the source code of a Linux application used to update
- * EC device firmware (common code only, gsctool takes care of cr50).
- */
-
-#define VID USB_VID_GOOGLE
-#define PID 0x5022
-#define SUBCLASS USB_SUBCLASS_GOOGLE_UPDATE
-#define PROTOCOL USB_PROTOCOL_GOOGLE_UPDATE
-
-enum exit_values {
- noop = 0, /* All up to date, no update needed. */
- all_updated = 1, /* Update completed, reboot required. */
- rw_updated = 2, /* RO was not updated, reboot required. */
- update_error = 3 /* Something went wrong. */
-};
-
-struct usb_endpoint {
- struct libusb_device_handle *devh;
- uint8_t ep_num;
- int chunk_len;
-};
-
-struct transfer_descriptor {
- /*
- * offsets of section available for update (not currently active).
- */
- uint32_t offset;
-
- struct usb_endpoint uep;
-};
-
-/* Information about the target */
-static struct first_response_pdu targ;
-
-static uint16_t protocol_version;
-static uint16_t header_type;
-static char *progname;
-static char *short_opts = "bd:efg:hjlnp:rsS:tuw";
-static const struct option long_opts[] = {
- /* name hasarg *flag val */
- {"binvers", 1, NULL, 'b'},
- {"device", 1, NULL, 'd'},
- {"entropy", 0, NULL, 'e'},
- {"fwver", 0, NULL, 'f'},
- {"tp_debug", 1, NULL, 'g'},
- {"help", 0, NULL, 'h'},
- {"jump_to_rw", 0, NULL, 'j'},
- {"follow_log", 0, NULL, 'l'},
- {"no_reset", 0, NULL, 'n'},
- {"tp_update", 1, NULL, 'p'},
- {"reboot", 0, NULL, 'r'},
- {"stay_in_ro", 0, NULL, 's'},
- {"serial", 1, NULL, 'S'},
- {"tp_info", 0, NULL, 't'},
- {"unlock_rollback", 0, NULL, 'u'},
- {"unlock_rw", 0, NULL, 'w'},
- {},
-};
-
-/* Release USB device and return error to the OS. */
-static void shut_down(struct usb_endpoint *uep)
-{
- libusb_close(uep->devh);
- libusb_exit(NULL);
- exit(update_error);
-}
-
-static void usage(int errs)
-{
- printf("\nUsage: %s [options] <binary image>\n"
- "\n"
- "This updates EC firmware over USB (common code EC, no cr50).\n"
- "The required argument is the full RO+RW image.\n"
- "\n"
- "Options:\n"
- "\n"
- " -b,--binvers Report versions of image's "
- "RW and RO, do not update\n"
- " -d,--device VID:PID USB device (default %04x:%04x)\n"
- " -e,--entropy Add entropy to device secret\n"
- " -f,--fwver Report running firmware versions.\n"
- " -g,--tp_debug <hex data> Touchpad debug command\n"
- " -h,--help Show this message\n"
- " -j,--jump_to_rw Tell EC to jump to RW\n"
- " -l,--follow_log Get console log\n"
- " -p,--tp_update file Update touchpad FW\n"
- " -r,--reboot Tell EC to reboot\n"
- " -s,--stay_in_ro Tell EC to stay in RO\n"
- " -S,--serial Device serial number\n"
- " -t,--tp_info Get touchpad information\n"
- " -u,--unlock_rollback Tell EC to unlock the rollback region\n"
- " -w,--unlock_rw Tell EC to unlock the RW region\n"
- "\n", progname, VID, PID);
-
- exit(errs ? update_error : noop);
-}
-
-static void str2hex(const char *str, uint8_t *data, int *len)
-{
- int i;
- int slen = strlen(str);
-
- if (slen/2 > *len) {
- fprintf(stderr, "Hex string too long.\n");
- exit(update_error);
- }
-
- if (slen % 2 != 0) {
- fprintf(stderr, "Hex string length not a multiple of 2.\n");
- exit(update_error);
- }
-
- for (i = 0, *len = 0; i < slen; i += 2, (*len)++) {
- char *end;
- char tmp[3];
-
- tmp[0] = str[i];
- tmp[1] = str[i+1];
- tmp[2] = 0;
-
- data[*len] = strtol(tmp, &end, 16);
-
- if (*end != 0) {
- fprintf(stderr, "Invalid hex string.\n");
- exit(update_error);
- }
- }
-}
-
-static void hexdump(const uint8_t *data, int len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- printf("%02x", data[i]);
- if ((i % 16) == 15)
- printf("\n");
- }
-
- if ((len % 16) != 0)
- printf("\n");
-}
-
-static void dump_touchpad_info(const uint8_t *data, int len)
-{
- const struct touchpad_info *info = (const struct touchpad_info *)data;
-
- if (len != sizeof(struct touchpad_info)) {
- fprintf(stderr, "Hex string length is not %zu",
- sizeof(struct touchpad_info));
- hexdump(data, len);
- return;
- }
-
- printf("\n");
- printf("status: 0x%02x\n", info->status);
- printf("vendor: 0x%04x\n", info->vendor);
- printf("fw_address: 0x%08x\n", info->fw_address);
- printf("fw_size: 0x%08x\n", info->fw_size);
-
- printf("allowed_fw_hash:\n");
- hexdump(info->allowed_fw_hash, sizeof(info->allowed_fw_hash));
-
- switch (info->vendor) {
- case 0x04f3: /* ELAN */
- case 0x0483: /* ST */
- printf("id: 0x%04x\n", info->elan.id);
- printf("fw_version: 0x%04x\n", info->elan.fw_version);
- printf("fw_fw_checksum: 0x%04x\n", info->elan.fw_checksum);
- break;
- default:
- fprintf(stderr, "Unknown vendor, vendor specific data:\n");
- hexdump((const uint8_t *)&info->elan, sizeof(info->elan));
- break;
- }
-}
-
-/* Read file into buffer */
-static uint8_t *get_file_or_die(const char *filename, size_t *len_ptr)
-{
- FILE *fp;
- struct stat st;
- uint8_t *data;
- size_t len;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- perror(filename);
- exit(update_error);
- }
- if (fstat(fileno(fp), &st)) {
- perror("stat");
- exit(update_error);
- }
-
- len = st.st_size;
-
- data = malloc(len);
- if (!data) {
- perror("malloc");
- exit(update_error);
- }
-
- if (fread(data, st.st_size, 1, fp) != 1) {
- perror("fread");
- exit(update_error);
- }
-
- fclose(fp);
-
- *len_ptr = len;
- return data;
-}
-
-#define USB_ERROR(m, r) \
- fprintf(stderr, "%s:%d, %s returned %d (%s)\n", __FILE__, __LINE__, \
- m, r, libusb_strerror(r))
-
-/*
- * Actual USB transfer function, the 'allow_less' flag indicates that the
- * valid response could be shortef than allotted memory, the 'rxed_count'
- * pointer, if provided along with 'allow_less' lets the caller know how mavy
- * bytes were received.
- */
-static void do_xfer(struct usb_endpoint *uep, void *outbuf, int outlen,
- void *inbuf, int inlen, int allow_less,
- size_t *rxed_count)
-{
-
- int r, actual;
-
- /* Send data out */
- if (outbuf && outlen) {
- actual = 0;
- r = libusb_bulk_transfer(uep->devh, uep->ep_num,
- outbuf, outlen,
- &actual, 2000);
- if (r < 0) {
- USB_ERROR("libusb_bulk_transfer", r);
- exit(update_error);
- }
- if (actual != outlen) {
- fprintf(stderr, "%s:%d, only sent %d/%d bytes\n",
- __FILE__, __LINE__, actual, outlen);
- shut_down(uep);
- }
- }
-
- /* Read reply back */
- if (inbuf && inlen) {
-
- actual = 0;
- r = libusb_bulk_transfer(uep->devh, uep->ep_num | 0x80,
- inbuf, inlen,
- &actual, 5000);
- if (r < 0) {
- USB_ERROR("libusb_bulk_transfer", r);
- exit(update_error);
- }
- if ((actual != inlen) && !allow_less) {
- fprintf(stderr, "%s:%d, only received %d/%d bytes\n",
- __FILE__, __LINE__, actual, inlen);
- hexdump(inbuf, actual);
- shut_down(uep);
- }
-
- if (rxed_count)
- *rxed_count = actual;
- }
-}
-
-static void xfer(struct usb_endpoint *uep, void *outbuf,
- size_t outlen, void *inbuf, size_t inlen, int allow_less)
-{
- do_xfer(uep, outbuf, outlen, inbuf, inlen, allow_less, NULL);
-}
-
-/* Return 0 on error, since it's never gonna be EP 0 */
-static int find_endpoint(const struct libusb_interface_descriptor *iface,
- struct usb_endpoint *uep)
-{
- const struct libusb_endpoint_descriptor *ep;
-
- if (iface->bInterfaceClass == 255 &&
- iface->bInterfaceSubClass == SUBCLASS &&
- iface->bInterfaceProtocol == PROTOCOL &&
- iface->bNumEndpoints) {
- ep = &iface->endpoint[0];
- uep->ep_num = ep->bEndpointAddress & 0x7f;
- uep->chunk_len = ep->wMaxPacketSize;
- return 1;
- }
-
- return 0;
-}
-
-/* Return -1 on error */
-static int find_interface(struct usb_endpoint *uep)
-{
- int iface_num = -1;
- int r, i, j;
- struct libusb_device *dev;
- struct libusb_config_descriptor *conf = 0;
- const struct libusb_interface *iface0;
- const struct libusb_interface_descriptor *iface;
-
- dev = libusb_get_device(uep->devh);
- r = libusb_get_active_config_descriptor(dev, &conf);
- if (r < 0) {
- USB_ERROR("libusb_get_active_config_descriptor", r);
- goto out;
- }
-
- for (i = 0; i < conf->bNumInterfaces; i++) {
- iface0 = &conf->interface[i];
- for (j = 0; j < iface0->num_altsetting; j++) {
- iface = &iface0->altsetting[j];
- if (find_endpoint(iface, uep)) {
- iface_num = i;
- goto out;
- }
- }
- }
-
-out:
- libusb_free_config_descriptor(conf);
- return iface_num;
-}
-
-/* Returns true if parsed. */
-static int parse_vidpid(const char *input, uint16_t *vid_ptr, uint16_t *pid_ptr)
-{
- char *copy, *s, *e = 0;
-
- copy = strdup(input);
-
- s = strchr(copy, ':');
- if (!s)
- return 0;
- *s++ = '\0';
-
- *vid_ptr = (uint16_t) strtoul(copy, &e, 16);
- if (!*optarg || (e && *e))
- return 0;
-
- *pid_ptr = (uint16_t) strtoul(s, &e, 16);
- if (!*optarg || (e && *e))
- return 0;
-
- return 1;
-}
-
-static libusb_device_handle *check_device(libusb_device *dev,
- uint16_t vid, uint16_t pid, char *serialno)
-{
- struct libusb_device_descriptor desc;
- libusb_device_handle *handle = NULL;
- char sn[256];
- int ret;
- int match = 1;
- int snvalid = 0;
-
- ret = libusb_get_device_descriptor(dev, &desc);
- if (ret < 0)
- return NULL;
-
- ret = libusb_open(dev, &handle);
-
- if (ret != LIBUSB_SUCCESS)
- return NULL;
-
- if (desc.iSerialNumber) {
- ret = libusb_get_string_descriptor_ascii(handle,
- desc.iSerialNumber, (unsigned char *)sn, sizeof(sn));
- if (ret > 0)
- snvalid = 1;
- }
-
- if (vid != 0 && vid != desc.idVendor)
- match = 0;
- if (pid != 0 && pid != desc.idProduct)
- match = 0;
- if (serialno != NULL && (!snvalid || strstr(sn, serialno) == NULL))
- match = 0;
-
- if (match)
- return handle;
-
- libusb_close(handle);
- return NULL;
-}
-
-static void usb_findit(uint16_t vid, uint16_t pid,
- char *serialno, struct usb_endpoint *uep)
-{
- int iface_num, r, i;
- libusb_device **devs;
- libusb_device_handle *devh = NULL;
- ssize_t count;
-
- memset(uep, 0, sizeof(*uep));
-
- r = libusb_init(NULL);
- if (r < 0) {
- USB_ERROR("libusb_init", r);
- exit(update_error);
- }
-
- count = libusb_get_device_list(NULL, &devs);
- if (count < 0)
- return;
-
- for (i = 0; devs[i]; i++) {
- devh = check_device(devs[i], vid, pid, serialno);
- if (devh) {
- printf("Found device.\n");
- break;
- }
- }
-
- libusb_free_device_list(devs, 1);
-
- if (!devh) {
- fprintf(stderr, "Can't find device\n");
- exit(update_error);
- }
-
- uep->devh = devh;
-
- iface_num = find_interface(uep);
- if (iface_num < 0) {
- fprintf(stderr, "USB FW update not supported by that device\n");
- shut_down(uep);
- }
- if (!uep->chunk_len) {
- fprintf(stderr, "wMaxPacketSize isn't valid\n");
- shut_down(uep);
- }
-
- printf("found interface %d endpoint %d, chunk_len %d\n",
- iface_num, uep->ep_num, uep->chunk_len);
-
- libusb_set_auto_detach_kernel_driver(uep->devh, 1);
- r = libusb_claim_interface(uep->devh, iface_num);
- if (r < 0) {
- USB_ERROR("libusb_claim_interface", r);
- shut_down(uep);
- }
-
- printf("READY\n-------\n");
-}
-
-static int transfer_block(struct usb_endpoint *uep,
- struct update_frame_header *ufh,
- uint8_t *transfer_data_ptr, size_t payload_size)
-{
- size_t transfer_size;
- uint32_t reply;
- int actual;
- int r;
-
- /* First send the header. */
- xfer(uep, ufh, sizeof(*ufh), NULL, 0, 0);
-
- /* Now send the block, chunk by chunk. */
- for (transfer_size = 0; transfer_size < payload_size;) {
- int chunk_size;
-
- chunk_size = MIN(uep->chunk_len, payload_size - transfer_size);
- xfer(uep, transfer_data_ptr, chunk_size, NULL, 0, 0);
- transfer_data_ptr += chunk_size;
- transfer_size += chunk_size;
- }
-
- /* Now get the reply. */
- r = libusb_bulk_transfer(uep->devh, uep->ep_num | 0x80,
- (void *) &reply, sizeof(reply),
- &actual, 5000);
- if (r) {
- if (r == -7) {
- fprintf(stderr, "Timeout!\n");
- return r;
- }
- USB_ERROR("libusb_bulk_transfer", r);
- shut_down(uep);
- }
-
- reply = *((uint8_t *)&reply);
- if (reply) {
- fprintf(stderr, "Error: status %#x\n", reply);
- exit(update_error);
- }
-
- return 0;
-}
-
-/**
- * Transfer an image section (typically RW or RO).
- *
- * td - transfer descriptor to use to communicate with the target
- * data_ptr - pointer at the section base in the image
- * section_addr - address of the section in the target memory space
- * data_len - section size
- * smart_update - non-zero to enable the smart trailing of 0xff.
- */
-static void transfer_section(struct transfer_descriptor *td,
- uint8_t *data_ptr,
- uint32_t section_addr,
- size_t data_len,
- uint8_t smart_update)
-{
- /*
- * Actually, we can skip trailing chunks of 0xff, as the entire
- * section space must be erased before the update is attempted.
- *
- * FIXME: We can be smarter than this and skip blocks within the image.
- */
- if (smart_update)
- while (data_len && (data_ptr[data_len - 1] == 0xff))
- data_len--;
-
- printf("sending 0x%zx bytes to %#x\n", data_len, section_addr);
- while (data_len) {
- size_t payload_size;
- uint32_t block_base;
- int max_retries;
-
- /* prepare the header to prepend to the block. */
- payload_size = MIN(data_len, targ.common.maximum_pdu_size);
-
- block_base = htobe32(section_addr);
-
- struct update_frame_header ufh;
-
- ufh.block_size = htobe32(payload_size +
- sizeof(struct update_frame_header));
- ufh.cmd.block_base = block_base;
- ufh.cmd.block_digest = 0;
- for (max_retries = 10; max_retries; max_retries--)
- if (!transfer_block(&td->uep, &ufh,
- data_ptr, payload_size))
- break;
-
- if (!max_retries) {
- fprintf(stderr,
- "Failed to transfer block, %zd to go\n",
- data_len);
- exit(update_error);
- }
- data_len -= payload_size;
- data_ptr += payload_size;
- section_addr += payload_size;
- }
-}
-
-/*
- * Each RO or RW section of the new image can be in one of the following
- * states.
- */
-enum upgrade_status {
- not_needed = 0, /* Version below or equal that on the target. */
- not_possible, /*
- * RO is newer, but can't be transferred due to
- * target RW shortcomings.
- */
- needed /*
- * This section needs to be transferred to the
- * target.
- */
-};
-
-/* This array describes all sections of the new image. */
-static struct {
- const char *name;
- uint32_t offset;
- uint32_t size;
- enum upgrade_status ustatus;
- char version[32];
- int32_t rollback;
- uint32_t key_version;
-} sections[] = {
- {"RO"},
- {"RW"}
-};
-
-static const struct fmap_area *fmap_find_area_or_die(const struct fmap *fmap,
- const char *name)
-{
- const struct fmap_area *fmaparea;
-
- fmaparea = fmap_find_area(fmap, name);
- if (!fmaparea) {
- fprintf(stderr, "Cannot find FMAP area %s\n", name);
- exit(update_error);
- }
-
- return fmaparea;
-}
-
-/*
- * Scan the new image and retrieve versions of all sections.
- */
-static void fetch_header_versions(const uint8_t *image, size_t len)
-{
- const struct fmap *fmap;
- const struct fmap_area *fmaparea;
- long int offset;
- size_t i;
-
- offset = fmap_find(image, len);
- if (offset < 0) {
- fprintf(stderr, "Cannot find FMAP in image\n");
- exit(update_error);
- }
- fmap = (const struct fmap *)(image+offset);
-
- /* FIXME: validate fmap struct more than this? */
- if (fmap->size != len) {
- fprintf(stderr, "Mismatch between FMAP size and image size\n");
- exit(update_error);
- }
-
- for (i = 0; i < ARRAY_SIZE(sections); i++) {
- const char *fmap_name;
- const char *fmap_fwid_name;
- const char *fmap_rollback_name = NULL;
- const char *fmap_key_name = NULL;
-
- if (!strcmp(sections[i].name, "RO")) {
- fmap_name = "EC_RO";
- fmap_fwid_name = "RO_FRID";
- } else if (!strcmp(sections[i].name, "RW")) {
- fmap_name = "EC_RW";
- fmap_fwid_name = "RW_FWID";
- fmap_rollback_name = "RW_RBVER";
- /*
- * Key version comes from key RO (RW signature does not
- * contain the key version.
- */
- fmap_key_name = "KEY_RO";
- } else {
- fprintf(stderr, "Invalid section name\n");
- exit(update_error);
- }
-
- fmaparea = fmap_find_area_or_die(fmap, fmap_name);
-
- /* FIXME: endianness? */
- sections[i].offset = fmaparea->offset;
- sections[i].size = fmaparea->size;
-
- fmaparea = fmap_find_area_or_die(fmap, fmap_fwid_name);
-
- if (fmaparea->size != sizeof(sections[i].version)) {
- fprintf(stderr, "Invalid fwid size\n");
- exit(update_error);
- }
- memcpy(sections[i].version, image+fmaparea->offset,
- fmaparea->size);
-
- sections[i].rollback = -1;
- if (fmap_rollback_name) {
- fmaparea = fmap_find_area(fmap, fmap_rollback_name);
- if (fmaparea)
- memcpy(&sections[i].rollback,
- image+fmaparea->offset,
- sizeof(sections[i].rollback));
- }
-
- sections[i].key_version = -1;
- if (fmap_key_name) {
- fmaparea = fmap_find_area(fmap, fmap_key_name);
- if (fmaparea) {
- const struct vb21_packed_key *key =
- (const void *)(image+fmaparea->offset);
- sections[i].key_version = key->key_version;
- }
- }
- }
-}
-
-static int show_headers_versions(const void *image)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(sections); i++) {
- printf("%s off=%08x/%08x v=%.32s rb=%d kv=%d\n",
- sections[i].name, sections[i].offset, sections[i].size,
- sections[i].version, sections[i].rollback,
- sections[i].key_version);
- }
- return 0;
-}
-
-/*
- * Pick sections to transfer based on information retrieved from the target,
- * the new image, and the protocol version the target is running.
- */
-static void pick_sections(struct transfer_descriptor *td)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(sections); i++) {
- uint32_t offset = sections[i].offset;
-
- /* Skip currently active section. */
- if (offset != td->offset)
- continue;
-
- sections[i].ustatus = needed;
- }
-}
-
-static void setup_connection(struct transfer_descriptor *td)
-{
- size_t rxed_size;
- size_t i;
- uint32_t error_code;
-
- /*
- * Need to be backwards compatible, communicate with targets running
- * different protocol versions.
- */
- union {
- struct first_response_pdu rpdu;
- uint32_t legacy_resp;
- } start_resp;
-
- /* Send start request. */
- printf("start\n");
-
- struct update_frame_header ufh;
- uint8_t inbuf[td->uep.chunk_len];
- int actual = 0;
-
- /* Flush all data from endpoint to recover in case of error. */
- while (!libusb_bulk_transfer(td->uep.devh,
- td->uep.ep_num | 0x80,
- (void *)&inbuf, td->uep.chunk_len,
- &actual, 10)) {
- printf("flush\n");
- }
-
- memset(&ufh, 0, sizeof(ufh));
- ufh.block_size = htobe32(sizeof(ufh));
- do_xfer(&td->uep, &ufh, sizeof(ufh), &start_resp,
- sizeof(start_resp), 1, &rxed_size);
-
- /* We got something. Check for errors in response */
- if (rxed_size < 8) {
- fprintf(stderr, "Unexpected response size %zd: ", rxed_size);
- for (i = 0; i < rxed_size; i++)
- fprintf(stderr, " %02x", ((uint8_t *)&start_resp)[i]);
- fprintf(stderr, "\n");
- exit(update_error);
- }
-
- protocol_version = be16toh(start_resp.rpdu.protocol_version);
- if (protocol_version < 5 || protocol_version > 6) {
- fprintf(stderr, "Unsupported protocol version %d\n",
- protocol_version);
- exit(update_error);
- }
-
- header_type = be16toh(start_resp.rpdu.header_type);
-
- printf("target running protocol version %d (type %d)\n",
- protocol_version, header_type);
- if (header_type != UPDATE_HEADER_TYPE_COMMON) {
- fprintf(stderr, "Unsupported header type %d\n",
- header_type);
- exit(update_error);
- }
-
- error_code = be32toh(start_resp.rpdu.return_value);
-
- if (error_code) {
- fprintf(stderr, "Target reporting error %d\n", error_code);
- shut_down(&td->uep);
- exit(update_error);
- }
-
- td->offset = be32toh(start_resp.rpdu.common.offset);
- memcpy(targ.common.version, start_resp.rpdu.common.version,
- sizeof(start_resp.rpdu.common.version));
- targ.common.maximum_pdu_size =
- be32toh(start_resp.rpdu.common.maximum_pdu_size);
- targ.common.flash_protection =
- be32toh(start_resp.rpdu.common.flash_protection);
- targ.common.min_rollback = be32toh(start_resp.rpdu.common.min_rollback);
- targ.common.key_version = be32toh(start_resp.rpdu.common.key_version);
-
- printf("maximum PDU size: %d\n", targ.common.maximum_pdu_size);
- printf("Flash protection status: %04x\n", targ.common.flash_protection);
- printf("version: %32s\n", targ.common.version);
- printf("key_version: %d\n", targ.common.key_version);
- printf("min_rollback: %d\n", targ.common.min_rollback);
- printf("offset: writable at %#x\n", td->offset);
-
- pick_sections(td);
-}
-
-/*
- * Channel TPM extension/vendor command over USB. The payload of the USB frame
- * in this case consists of the 2 byte subcommand code concatenated with the
- * command body. The caller needs to indicate if a response is expected, and
- * if it is - of what maximum size.
- */
-static int ext_cmd_over_usb(struct usb_endpoint *uep, uint16_t subcommand,
- void *cmd_body, size_t body_size,
- void *resp, size_t *resp_size,
- int allow_less)
-{
- struct update_frame_header *ufh;
- uint16_t *frame_ptr;
- size_t usb_msg_size;
-
- usb_msg_size = sizeof(struct update_frame_header) +
- sizeof(subcommand) + body_size;
-
- ufh = malloc(usb_msg_size);
- if (!ufh) {
- printf("%s: failed to allocate %zd bytes\n",
- __func__, usb_msg_size);
- return -1;
- }
-
- ufh->block_size = htobe32(usb_msg_size);
- ufh->cmd.block_digest = 0;
- ufh->cmd.block_base = htobe32(UPDATE_EXTRA_CMD);
- frame_ptr = (uint16_t *)(ufh + 1);
- *frame_ptr = htobe16(subcommand);
-
- if (body_size)
- memcpy(frame_ptr + 1, cmd_body, body_size);
-
- xfer(uep, ufh, usb_msg_size, resp, resp_size ? *resp_size : 0,
- allow_less);
-
- free(ufh);
- return 0;
-}
-
-/*
- * Indicate to the target that update image transfer has been completed. Upon
- * receiveing of this message the target state machine transitions into the
- * 'rx_idle' state. The host may send an extension command to reset the target
- * after this.
- */
-static void send_done(struct usb_endpoint *uep)
-{
- uint32_t out;
-
- /* Send stop request, ignoring reply. */
- out = htobe32(UPDATE_DONE);
- xfer(uep, &out, sizeof(out), &out, 1, 0);
-}
-
-static void send_subcommand(struct transfer_descriptor *td, uint16_t subcommand,
- void *cmd_body, size_t body_size,
- uint8_t *response, size_t response_size)
-{
- send_done(&td->uep);
-
- ext_cmd_over_usb(&td->uep, subcommand,
- cmd_body, body_size,
- response, &response_size, 0);
- printf("sent command %x, resp %x\n", subcommand, response[0]);
-}
-
-/* Returns number of successfully transmitted image sections. */
-static int transfer_image(struct transfer_descriptor *td,
- uint8_t *data, size_t data_len)
-{
- size_t i;
- int num_txed_sections = 0;
-
- for (i = 0; i < ARRAY_SIZE(sections); i++)
- if (sections[i].ustatus == needed) {
- transfer_section(td,
- data + sections[i].offset,
- sections[i].offset,
- sections[i].size, 1);
- num_txed_sections++;
- }
-
- /*
- * Move USB receiver sate machine to idle state so that vendor
- * commands can be processed later, if any.
- */
- send_done(&td->uep);
-
- if (!num_txed_sections)
- printf("nothing to do\n");
- else
- printf("-------\nupdate complete\n");
- return num_txed_sections;
-}
-
-static void generate_reset_request(struct transfer_descriptor *td)
-{
- size_t response_size;
- uint8_t response;
- uint16_t subcommand;
- uint8_t command_body[2]; /* Max command body size. */
- size_t command_body_size;
-
- if (protocol_version < 6) {
- /*
- * Send a second stop request, which should reboot
- * without replying.
- */
- send_done(&td->uep);
- /* Nothing we can do over /dev/tpm0 running versions below 6. */
- return;
- }
-
- /*
- * If the user explicitly wants it, request post reset instead of
- * immediate reset. In this case next time the target reboots, the h1
- * will reboot as well, and will consider running the uploaded code.
- *
- * In case target RW version is 19 or above, to reset the target the
- * host is supposed to send the command to enable the uploaded image
- * disabled by default.
- *
- * Otherwise the immediate reset command would suffice.
- */
- /* Most common case. */
- command_body_size = 0;
- response_size = 1;
- subcommand = UPDATE_EXTRA_CMD_IMMEDIATE_RESET;
- ext_cmd_over_usb(&td->uep, subcommand,
- command_body, command_body_size,
- &response, &response_size, 0);
-
- printf("reboot not triggered\n");
-}
-
-static void get_random(uint8_t *data, int len)
-{
- FILE *fp;
- int i = 0;
-
- fp = fopen("/dev/random", "rb");
- if (!fp) {
- perror("Can't open /dev/random");
- exit(update_error);
- }
-
- while (i < len) {
- int ret = fread(data+i, len-i, 1, fp);
-
- if (ret < 0) {
- perror("fread");
- exit(update_error);
- }
-
- i += ret;
- }
-
- fclose(fp);
-}
-
-static void read_console(struct transfer_descriptor *td)
-{
- uint8_t payload[] = { 0x1 };
- uint8_t response[64];
- size_t response_size = 64;
- struct timespec sleep_duration = { /* 100 ms */
- .tv_sec = 0,
- .tv_nsec = 100l * 1000l * 1000l,
- };
-
- send_done(&td->uep);
-
- printf("\n");
- while (1) {
- response_size = 1;
- ext_cmd_over_usb(&td->uep,
- UPDATE_EXTRA_CMD_CONSOLE_READ_INIT,
- NULL, 0,
- response, &response_size, 0);
-
- while (1) {
- response_size = 64;
- ext_cmd_over_usb(&td->uep,
- UPDATE_EXTRA_CMD_CONSOLE_READ_NEXT,
- payload, sizeof(payload),
- response, &response_size, 1);
- if (response[0] == 0)
- break;
- /* make sure it's null-terminated. */
- response[response_size - 1] = 0;
- printf("%s", (const char *)response);
- }
- nanosleep(&sleep_duration, NULL);
- }
-}
-
-int main(int argc, char *argv[])
-{
- struct transfer_descriptor td;
- int errorcnt;
- uint8_t *data = 0;
- size_t data_len = 0;
- uint16_t vid = VID, pid = PID;
- char *serialno = NULL;
- int i;
- size_t j;
- int transferred_sections = 0;
- int binary_vers = 0;
- int show_fw_ver = 0;
- int no_reset_request = 0;
- int touchpad_update = 0;
- int extra_command = -1;
- uint8_t extra_command_data[50];
- int extra_command_data_len = 0;
- uint8_t extra_command_answer[64];
- int extra_command_answer_len = 1;
-
- progname = strrchr(argv[0], '/');
- if (progname)
- progname++;
- else
- progname = argv[0];
-
- /* Usb transfer - default mode. */
- memset(&td, 0, sizeof(td));
-
- errorcnt = 0;
- opterr = 0; /* quiet, you */
- while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) {
- switch (i) {
- case 'b':
- binary_vers = 1;
- break;
- case 'd':
- if (!parse_vidpid(optarg, &vid, &pid)) {
- printf("Invalid argument: \"%s\"\n", optarg);
- errorcnt++;
- }
- break;
- case 'e':
- get_random(extra_command_data, 32);
- extra_command_data_len = 32;
- extra_command = UPDATE_EXTRA_CMD_INJECT_ENTROPY;
- break;
- case 'f':
- show_fw_ver = 1;
- break;
- case 'g':
- extra_command = UPDATE_EXTRA_CMD_TOUCHPAD_DEBUG;
- /* Maximum length. */
- extra_command_data_len = 50;
- str2hex(optarg,
- extra_command_data, &extra_command_data_len);
- hexdump(extra_command_data, extra_command_data_len);
- extra_command_answer_len = 64;
- break;
- case 'h':
- usage(errorcnt);
- break;
- case 'j':
- extra_command = UPDATE_EXTRA_CMD_JUMP_TO_RW;
- break;
- case 'l':
- extra_command = UPDATE_EXTRA_CMD_CONSOLE_READ_INIT;
- break;
- case 'n':
- no_reset_request = 1;
- break;
- case 'p':
- touchpad_update = 1;
-
- data = get_file_or_die(optarg, &data_len);
- printf("read %zd(%#zx) bytes from %s\n",
- data_len, data_len, argv[optind]);
-
- break;
- case 'r':
- extra_command = UPDATE_EXTRA_CMD_IMMEDIATE_RESET;
- break;
- case 's':
- extra_command = UPDATE_EXTRA_CMD_STAY_IN_RO;
- break;
- case 'S':
- serialno = optarg;
- break;
- case 't':
- extra_command = UPDATE_EXTRA_CMD_TOUCHPAD_INFO;
- extra_command_answer_len =
- sizeof(struct touchpad_info);
- break;
- case 'u':
- extra_command = UPDATE_EXTRA_CMD_UNLOCK_ROLLBACK;
- break;
- case 'w':
- extra_command = UPDATE_EXTRA_CMD_UNLOCK_RW;
- break;
- case 0: /* auto-handled option */
- break;
- case '?':
- if (optopt)
- printf("Unrecognized option: -%c\n", optopt);
- else
- printf("Unrecognized option: %s\n",
- argv[optind - 1]);
- errorcnt++;
- break;
- case ':':
- printf("Missing argument to %s\n", argv[optind - 1]);
- errorcnt++;
- break;
- default:
- printf("Internal error at %s:%d\n", __FILE__, __LINE__);
- exit(update_error);
- }
- }
-
- if (errorcnt)
- usage(errorcnt);
-
- if (!show_fw_ver && extra_command == -1 && !touchpad_update) {
- if (optind >= argc) {
- fprintf(stderr,
- "\nERROR: Missing required <binary image>\n\n");
- usage(1);
- }
-
- data = get_file_or_die(argv[optind], &data_len);
- printf("read %zd(%#zx) bytes from %s\n",
- data_len, data_len, argv[optind]);
-
- fetch_header_versions(data, data_len);
-
- if (binary_vers)
- exit(show_headers_versions(data));
- } else {
- if (optind < argc)
- printf("Ignoring binary image %s\n", argv[optind]);
- }
-
- usb_findit(vid, pid, serialno, &td.uep);
-
- setup_connection(&td);
-
- if (show_fw_ver) {
- printf("Current versions:\n");
- printf("Writable %32s\n", targ.common.version);
- }
-
- if (data) {
- if (touchpad_update) {
- transfer_section(&td,
- data,
- 0x80000000,
- data_len, 0);
- free(data);
-
- send_done(&td.uep);
- } else {
- transferred_sections = transfer_image(&td,
- data, data_len);
- free(data);
-
- if (transferred_sections && !no_reset_request)
- generate_reset_request(&td);
- }
- } else if (extra_command == UPDATE_EXTRA_CMD_CONSOLE_READ_INIT) {
- read_console(&td);
- } else if (extra_command > -1) {
- send_subcommand(&td, extra_command,
- extra_command_data, extra_command_data_len,
- extra_command_answer, extra_command_answer_len);
-
- switch (extra_command) {
- case UPDATE_EXTRA_CMD_TOUCHPAD_INFO:
- dump_touchpad_info(extra_command_answer,
- extra_command_answer_len);
- break;
- case UPDATE_EXTRA_CMD_TOUCHPAD_DEBUG:
- hexdump(extra_command_answer, extra_command_answer_len);
- break;
- }
- }
-
- libusb_close(td.uep.devh);
- libusb_exit(NULL);
-
- if (!transferred_sections)
- return noop;
- /*
- * We should indicate if RO update was not done because of the
- * insufficient RW version.
- */
- for (j = 0; j < ARRAY_SIZE(sections); j++)
- if (sections[j].ustatus == not_possible) {
- /* This will allow scripting repeat attempts. */
- printf("Failed to update RO, run the command again\n");
- return rw_updated;
- }
-
- printf("image updated\n");
- return all_updated;
-}
diff --git a/util/battery_temp b/util/battery_temp
deleted file mode 100755
index c69e3d4778..0000000000
--- a/util/battery_temp
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-# Copyright 2018 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.
-#
-# Description: Read and output temperature of device's primary battery in
-# degrees Celsius.
-#
-# TODO(tbroch) revisit for detachables with multiple batteries.
-
-# Read battery temperature from sysfs power_supply and return in degC.
-batt_temp_sysfs() {
- local temp=""
-
- for psdir in /sys/class/power_supply/* ; do
- if [[ -e "${psdir}/temp" ]] ; then
- pstype=$(cat $psdir/type)
- if [[ "${pstype}" -eq "Battery" ]] ; then
- temp=$(bc <<< "scale=2; $(cat ${psdir}/temp)/10")
- break
- fi
- fi
- done
- echo ${temp}
-}
-
-# Read battery temperature from EC and return in degC.
-batt_temp_ec() {
- local temp=""
-
- local sensor_str=$(ectool tempsinfo all 2>/dev/null | grep Battery)
- if [[ $? -eq 0 ]] && [[ ! -z "${sensor_str}" ]] ; then
- local idx=$(echo ${sensor_str} | cut -d: -f1)
- # ectool temps <idx> looks like 'Reading temperature...298 K'
- temp_str=$(ectool temps ${idx})
- temp="${temp_str//[!0-9]/}"
- if [[ -z "${temp}" ]] ; then
- temp="error"
- else
- temp=$(bc <<< "scale=2; ${temp} - 273.15")
- fi
- fi
- echo $temp
-}
-
-# Main
-TEMP_DEGC=$(batt_temp_sysfs)
-if [[ -z "${TEMP_DEGC}" ]] ; then
- TEMP_DEGC=$(batt_temp_ec)
-fi
-
-if [[ -z "${TEMP_DEGC}" ]] ; then
- echo "unknown"
-else
- echo ${TEMP_DEGC}
-fi
diff --git a/util/build.mk b/util/build.mk
deleted file mode 100644
index 9b9f44c814..0000000000
--- a/util/build.mk
+++ /dev/null
@@ -1,110 +0,0 @@
-# -*- makefile -*-
-# Copyright 2014 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.
-#
-# Host tools build
-#
-
-host-util-bin=ectool lbplay stm32mon ec_sb_firmware_update lbcc \
- ec_parse_panicinfo cbi-util iteflash
-build-util-bin=ec_uartd
-build-util-art+=util/export_taskinfo.so
-ifeq ($(CHIP),npcx)
-build-util-bin+=ecst
-endif
-host-util-bin+=uartupdatetool
-uartupdatetool-objs=uut/main.o uut/cmd.o uut/opr.o uut/l_com_port.o \
- uut/lib_crc.o
-$(out)/util/uartupdatetool: HOST_CFLAGS+=-Iutil/
-# Build on a limited subset of boards to save build time
-ifeq ($(BOARD),nocturne_fp)
-build-util-bin+=ectool_servo
-endif
-
-# If the util/ directory in the private repo is symlinked into util/private,
-# we want to build host-side tools from it, too.
-ifneq ("$(wildcard util/private/build.mk)","")
-include util/private/build.mk
-endif
-
-comm-objs=$(util-lock-objs:%=lock/%) comm-host.o comm-dev.o
-comm-objs+=comm-lpc.o comm-i2c.o misc_util.o
-
-iteflash-objs = iteflash.o usb_if.o
-ectool-objs=ectool.o ectool_keyscan.o ec_flash.o ec_panicinfo.o $(comm-objs)
-ectool_servo-objs=$(ectool-objs) comm-servo-spi.o
-ec_sb_firmware_update-objs=ec_sb_firmware_update.o $(comm-objs) misc_util.o
-ec_sb_firmware_update-objs+=powerd_lock.o
-lbplay-objs=lbplay.o $(comm-objs)
-
-util/ectool.c: $(out)/ec_version.h
-
-ec_parse_panicinfo-objs=ec_parse_panicinfo.o ec_panicinfo.o
-
-# USB type-C Vendor Information File generation
-ifeq ($(CONFIG_USB_POWER_DELIVERY),y)
-build-util-bin+=genvif
-build-util-art+=$(BOARD)_vif.txt
-
-# usb_pd_policy.c can be in baseboard, or board, or both.
-genvif-pd-srcs=$(sort $(wildcard $(BASEDIR)/usb_pd_policy.c \
- board/$(BOARD)/usb_pd_policy.c))
-genvif-pd-objs=$(genvif-pd-srcs:%.c=$(out)/util/%.o)
-deps-$(CONFIG_USB_POWER_DELIVERY) += $(genvif-pd-objs:%.o=%.o.d)
-
-$(out)/util/genvif: $(genvif-pd-objs) board/$(BOARD)/board.h \
- include/usb_pd.h include/usb_pd_tcpm.h
-$(out)/util/genvif: BUILD_LDFLAGS+=$(genvif-pd-objs) -flto
-
-STANDALONE_FLAGS=-ffreestanding -fno-builtin -nostdinc \
- -Ibuiltin/ -D"__keep= " -DVIF_BUILD=$(EMPTY)
-
-$(out)/util/%/usb_pd_policy.o: %/usb_pd_policy.c
- -@ mkdir -p $(@D)
- $(call quiet,c_to_vif,BUILDCC)
-endif # CONFIG_USB_POWER_DELIVERY
-
-ifneq ($(CONFIG_BOOTBLOCK),)
-build-util-bin += gen_emmc_transfer_data
-
-# Bootblock is only packed in RO image.
-$(out)/util/gen_emmc_transfer_data: BUILD_LDFLAGS += -DSECTION_IS_RO=$(EMPTY)
-endif # CONFIG_BOOTBLOCK
-
-ifneq ($(CONFIG_IPI),)
-build-util-bin += gen_ipi_table
-
-$(out)/util/gen_ipi_table: board/$(BOARD)/board.h
-$(out)/ipi_table_gen.inc: $(out)/util/gen_ipi_table
- $(call quiet,ipi_table,IPITBL )
-endif
-
-ifneq ($(CONFIG_TOUCHPAD_HASH_FW),)
-build-util-bin += gen_touchpad_hash
-
-# Assume RW section (touchpad FW must be identical for both RO+RW)
-$(out)/util/gen_touchpad_hash: BUILD_LDFLAGS += -DSECTION_IS_RW=$(EMPTY)
-
-OPENSSL_CFLAGS := $(shell $(PKG_CONFIG) --libs openssl)
-OPENSSL_LDFLAGS := $(shell $(PKG_CONFIG) --libs openssl)
-
-$(out)/util/gen_touchpad_hash: BUILD_CFLAGS += $(OPENSSL_CFLAGS)
-$(out)/util/gen_touchpad_hash: BUILD_LDFLAGS += $(OPENSSL_LDFLAGS)
-
-deps-y += $(out)/util/gen_touchpad_hash.d
-endif # CONFIG_TOUCHPAD_VIRTUAL_OFF
-
-cbi-util-objs=../common/crc8.o ../common/cbi.o
-
-$(out)/util/export_taskinfo.so: $(out)/util/export_taskinfo_ro.o \
- $(out)/util/export_taskinfo_rw.o
- $(call quiet,link_taskinfo,BUILDLD)
-
-$(out)/util/export_taskinfo_ro.o: util/export_taskinfo.c
- $(call quiet,c_to_taskinfo,BUILDCC,RO)
-
-$(out)/util/export_taskinfo_rw.o: util/export_taskinfo.c
- $(call quiet,c_to_taskinfo,BUILDCC,RW)
-
-deps-y += $(out)/util/export_taskinfo_ro.o.d $(out)/util/export_taskinfo_rw.o.d
diff --git a/util/cbi-util.c b/util/cbi-util.c
deleted file mode 100644
index ad050f36c5..0000000000
--- a/util/cbi-util.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/* Copyright 2018 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.
- *
- * Cros Board Info utility
- */
-
-#include <compile_time_macros.h>
-#include <errno.h>
-#include <dirent.h>
-#include <getopt.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "cros_board_info.h"
-#include "crc8.h"
-
-#define ARGS_MASK_BOARD_VERSION BIT(0)
-#define ARGS_MASK_FILENAME BIT(1)
-#define ARGS_MASK_SIZE BIT(2)
-#define ARGS_MASK_SKU_ID BIT(3)
-
-/* TODO: Set it by macro */
-const char cmd_name[] = "cbi-util";
-
-/* Command line options */
-enum {
- OPT_FILENAME,
- OPT_BOARD_VERSION,
- OPT_OEM_ID,
- OPT_SKU_ID,
- OPT_DRAM_PART_NUM,
- OPT_OEM_NAME,
- OPT_MODEL_ID,
- OPT_SIZE,
- OPT_ERASE_BYTE,
- OPT_SHOW_ALL,
- OPT_HELP,
-};
-
-static const struct option opts_create[] = {
- {"file", 1, 0, OPT_FILENAME},
- {"board_version", 1, 0, OPT_BOARD_VERSION},
- {"oem_id", 1, 0, OPT_OEM_ID},
- {"sku_id", 1, 0, OPT_SKU_ID},
- {"dram_part_num", 1, 0, OPT_DRAM_PART_NUM},
- {"oem_name", 1, 0, OPT_OEM_NAME},
- {"model_id", 1, 0, OPT_MODEL_ID},
- {"size", 1, 0, OPT_SIZE},
- {"erase_byte", 1, 0, OPT_ERASE_BYTE},
- {NULL, 0, 0, 0}
-};
-
-static const struct option opts_show[] = {
- {"file", 1, 0, OPT_FILENAME},
- {"all", 0, 0, OPT_SHOW_ALL},
- {NULL, 0, 0, 0}
-};
-
-static const char *field_name[] = {
- /* Same order as enum cbi_data_tag */
- "BOARD_VERSION",
- "OEM_ID",
- "SKU_ID",
- "DRAM_PART_NUM",
- "OEM_NAME",
- "MODEL_ID",
-};
-BUILD_ASSERT(ARRAY_SIZE(field_name) == CBI_TAG_COUNT);
-
-const char help_create[] =
- "\n"
- "'%s create [ARGS]' creates an EEPROM image file.\n"
- "Required ARGS are:\n"
- " --file <file> Path to output file\n"
- " --board_version <value> Board version\n"
- " --sku_id <value> SKU ID\n"
- " --size <size> Size of output file in bytes\n"
- "<value> must be a positive integer <= 0XFFFFFFFF and field size can\n"
- "be optionally specified by <value:size> notation: e.g. 0xabcd:4.\n"
- "<size> must be a positive integer <= 0XFFFF.\n"
- "Optional ARGS are:\n"
- " --dram_part_num <string> DRAM PART NUM\n"
- " --oem_id <value> OEM ID\n"
- " --oem_name <string> OEM NAME\n"
- " --erase_byte <uint8> Byte used for empty space. Default:0xff\n"
- " --format_version <uint16> Data format version\n"
- " --model_id <value> Model ID\n"
- "<string> is a string\n"
- "\n";
-
-const char help_show[] =
- "\n"
- "'%s show [ARGS]' shows data in an EEPROM image file.\n"
- "Required ARGS are:\n"
- " --file <file> Path to input file\n"
- "Optional ARGS are:\n"
- " --all Dump all information\n"
- "It also validates the contents against the checksum and\n"
- "returns non-zero if validation fails.\n"
- "\n";
-
-struct integer_field {
- uint32_t val;
- int size;
-};
-
-static void print_help_create(void)
-{
- printf(help_create, cmd_name);
-}
-
-static void print_help_show(void)
-{
- printf(help_show, cmd_name);
-}
-
-static void print_help(void)
-{
- printf("\nUsage: %s <create|show> [ARGS]\n"
- "\n"
- "Utility for CBI:Cros Board Info images.\n", cmd_name);
- print_help_create();
- print_help_show();
-}
-
-static int write_file(const char *filename, const char *buf, int size)
-{
- FILE *f;
- int i;
-
- /* Write to file */
- f = fopen(filename, "wb");
- if (!f) {
- perror("Error opening output file");
- return -1;
- }
- i = fwrite(buf, 1, size, f);
- fclose(f);
- if (i != size) {
- perror("Error writing to file");
- return -1;
- }
-
- return 0;
-}
-
-static uint8_t *read_file(const char *filename, uint32_t *size_ptr)
-{
- FILE *f;
- uint8_t *buf;
- long size;
-
- *size_ptr = 0;
-
- f = fopen(filename, "rb");
- if (!f) {
- fprintf(stderr, "Unable to open file %s\n", filename);
- return NULL;
- }
-
- fseek(f, 0, SEEK_END);
- size = ftell(f);
- rewind(f);
-
- if (size < 0 || size > UINT32_MAX) {
- fclose(f);
- return NULL;
- }
-
- buf = malloc(size);
- if (!buf) {
- fclose(f);
- return NULL;
- }
-
- if (1 != fread(buf, size, 1, f)) {
- fprintf(stderr, "Unable to read from %s\n", filename);
- fclose(f);
- free(buf);
- return NULL;
- }
-
- fclose(f);
-
- *size_ptr = size;
- return buf;
-}
-
-static int estimate_field_size(uint32_t value)
-{
- if (value <= UINT8_MAX)
- return 1;
- if (value <= UINT16_MAX)
- return 2;
- return 4;
-}
-
-static int parse_integer_field(const char *arg, struct integer_field *f)
-{
- uint64_t val;
- char *e;
- char *ch;
-
- val = strtoul(arg, &e, 0);
- if (val > UINT32_MAX || !*arg || (e && *e && *e != ':')) {
- fprintf(stderr, "Invalid integer value\n");
- return -1;
- }
- f->val = val;
-
- ch = strchr(arg, ':');
- if (ch) {
- ch++;
- val = strtoul(ch, &e , 0);
- if (val < 1 || 4 < val || !*ch || (e && *e)) {
- fprintf(stderr, "Invalid size suffix\n");
- return -1;
- }
- f->size = val;
- } else {
- f->size = estimate_field_size(f->val);
- }
-
- if (f->val > (1ull << f->size * 8)) {
- fprintf(stderr, "Value (0x%x) exceeds field size (%d)\n",
- f->val, f->size);
- return -1;
- }
-
- return 0;
-}
-
-static int cmd_create(int argc, char **argv)
-{
- uint8_t *cbi;
- struct board_info {
- struct integer_field ver;
- struct integer_field oem;
- struct integer_field sku;
- struct integer_field model;
- const char *dram_part_num;
- const char *oem_name;
- } bi;
- struct cbi_header *h;
- int rv;
- uint8_t *p;
- const char *filename;
- uint32_t set_mask = 0;
- uint16_t size;
- uint8_t erase = 0xff;
- int i;
-
- memset(&bi, 0, sizeof(bi));
-
- while ((i = getopt_long(argc, argv, "", opts_create, NULL)) != -1) {
- uint64_t val;
- char *e;
- switch (i) {
- case '?': /* Unhandled option */
- print_help_create();
- return -1;
- case OPT_HELP:
- print_help_create();
- return 0;
- case OPT_BOARD_VERSION:
- if (parse_integer_field(optarg, &bi.ver))
- return -1;
- set_mask |= ARGS_MASK_BOARD_VERSION;
- break;
- case OPT_ERASE_BYTE:
- erase = strtoul(optarg, &e, 0);
- if (!*optarg || (e && *e)) {
- fprintf(stderr, "Invalid --erase_byte\n");
- return -1;
- }
- break;
- case OPT_FILENAME:
- filename = optarg;
- set_mask |= ARGS_MASK_FILENAME;
- break;
- case OPT_OEM_ID:
- if (parse_integer_field(optarg, &bi.oem))
- return -1;
- break;
- case OPT_SIZE:
- val = strtoul(optarg, &e, 0);
- if (val > UINT16_MAX || !*optarg || (e && *e)) {
- fprintf(stderr, "Invalid --size\n");
- return -1;
- }
- size = val;
- set_mask |= ARGS_MASK_SIZE;
- break;
- case OPT_SKU_ID:
- if (parse_integer_field(optarg, &bi.sku))
- return -1;
- set_mask |= ARGS_MASK_SKU_ID;
- break;
- case OPT_DRAM_PART_NUM:
- bi.dram_part_num = optarg;
- break;
- case OPT_OEM_NAME:
- bi.oem_name = optarg;
- break;
- case OPT_MODEL_ID:
- if (parse_integer_field(optarg, &bi.model))
- return -1;
- break;
- }
- }
-
- if (set_mask != (ARGS_MASK_BOARD_VERSION | ARGS_MASK_FILENAME |
- ARGS_MASK_SIZE | ARGS_MASK_SKU_ID)) {
- fprintf(stderr, "Missing required arguments\n");
- print_help_create();
- return -1;
- }
-
- cbi = malloc(size);
- if (!cbi) {
- fprintf(stderr, "Failed to allocate memory\n");
- return -1;
- }
- memset(cbi, erase, size);
-
- h = (struct cbi_header *)cbi;
- memcpy(h->magic, cbi_magic, sizeof(cbi_magic));
- h->major_version = CBI_VERSION_MAJOR;
- h->minor_version = CBI_VERSION_MINOR;
- p = h->data;
- p = cbi_set_data(p, CBI_TAG_BOARD_VERSION, &bi.ver.val, bi.ver.size);
- p = cbi_set_data(p, CBI_TAG_OEM_ID, &bi.oem.val, bi.oem.size);
- p = cbi_set_data(p, CBI_TAG_SKU_ID, &bi.sku.val, bi.sku.size);
- p = cbi_set_data(p, CBI_TAG_MODEL_ID, &bi.model.val, bi.model.size);
- p = cbi_set_string(p, CBI_TAG_DRAM_PART_NUM, bi.dram_part_num);
- p = cbi_set_string(p, CBI_TAG_OEM_NAME, bi.oem_name);
-
- h->total_size = p - cbi;
- h->crc = cbi_crc8(h);
-
- /* Output image */
- rv = write_file(filename, cbi, size);
- free(cbi);
- if (rv) {
- fprintf(stderr, "Unable to write CBI image to %s\n", filename);
- return rv;
- }
-
- fprintf(stderr, "CBI image is created successfully\n");
-
- return 0;
-}
-
-static void print_string(const uint8_t *buf, enum cbi_data_tag tag)
-{
- struct cbi_data *d = cbi_find_tag(buf, tag);
- const char *name;
-
- if (!d)
- return;
-
- name = d->tag < CBI_TAG_COUNT ? field_name[d->tag] : "???";
-
- printf(" %s: %.*s (%u, %u)\n", name, d->size, (const char *)d->value,
- d->tag, d->size);
-}
-
-static void print_integer(const uint8_t *buf, enum cbi_data_tag tag)
-{
- uint32_t v;
- struct cbi_data *d = cbi_find_tag(buf, tag);
- const char *name;
-
- if (!d)
- return;
-
- name = d->tag < CBI_TAG_COUNT ? field_name[d->tag] : "???";
-
- switch (d->size) {
- case 1:
- v = *(uint8_t *)d->value;
- break;
- case 2:
- v = *(uint16_t *)d->value;
- break;
- case 4:
- v = *(uint32_t *)d->value;
- break;
- default:
- printf(" %s: Integer of size %d not supported\n",
- name, d->size);
- return;
- }
- printf(" %s: %u (0x%x, %u, %u)\n", name, v, v, d->tag, d->size);
-}
-
-static int cmd_show(int argc, char **argv)
-{
- uint8_t *buf;
- uint32_t size;
- struct cbi_header *h;
- uint32_t set_mask = 0;
- const char *filename;
- int show_all = 0;
- int i;
-
- while ((i = getopt_long(argc, argv, "", opts_show, NULL)) != -1) {
- switch (i) {
- case '?': /* Unhandled option */
- print_help_show();
- return -1;
- case OPT_HELP:
- print_help_show();
- return 0;
- case OPT_FILENAME:
- filename = optarg;
- set_mask |= ARGS_MASK_FILENAME;
- break;
- case OPT_SHOW_ALL:
- show_all = 1;
- break;
- }
- }
-
- if (set_mask != ARGS_MASK_FILENAME) {
- fprintf(stderr, "Missing required arguments\n");
- print_help_show();
- return -1;
- }
-
- buf = read_file(filename, &size);
- if (!buf) {
- fprintf(stderr, "Unable to read CBI image\n");
- return -1;
- }
-
- h = (struct cbi_header *)buf;
- printf("CBI image: %s\n", filename);
-
- if (memcmp(h->magic, cbi_magic, sizeof(cbi_magic))) {
- fprintf(stderr, "Invalid Magic\n");
- free(buf);
- return -1;
- }
-
- if (cbi_crc8(h) != h->crc) {
- fprintf(stderr, "Invalid CRC\n");
- free(buf);
- return -1;
- }
-
- printf(" TOTAL_SIZE: %u\n", h->total_size);
- if (show_all)
- printf(" CBI_VERSION: %u\n", h->version);
- printf(" Data Field: name: value (hex, tag, size)\n");
- print_integer(buf, CBI_TAG_BOARD_VERSION);
- print_integer(buf, CBI_TAG_OEM_ID);
- print_integer(buf, CBI_TAG_SKU_ID);
- print_integer(buf, CBI_TAG_MODEL_ID);
- print_string(buf, CBI_TAG_DRAM_PART_NUM);
- print_string(buf, CBI_TAG_OEM_NAME);
-
- free(buf);
-
- printf("Data validated successfully\n");
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- if (argc < 2) {
- fprintf(stderr, "Unknown option or missing value\n");
- print_help();
- return -1;
- }
-
- if (!strncmp(argv[1], "create", sizeof("create")))
- return cmd_create(--argc, ++argv);
- else if (!strncmp(argv[1], "show", sizeof("show")))
- return cmd_show(--argc, ++argv);
-
- fprintf(stderr, "Unknown option or missing value\n");
- print_help();
-
- return -1;
-}
diff --git a/util/chargen b/util/chargen
deleted file mode 100644
index 42c40f13e4..0000000000
--- a/util/chargen
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2019 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.
-
-import sys
-
-def chargen(modulo, max_chars):
- """Generate a stream of characters on the console.
-
- The stream is an ever incrementing pattern of characters from the
- following set: 0..9A..Za..z.
-
- Args:
- modulo: an int, restart the pattern every modulo characters, if
- modulo is non zero
- max_chars: an int, stop printing after this number of characters if non
- zero, if zero - print indefinitely
- """
-
- base = '0'
- c = base
- counter = 0
- while True:
- sys.stdout.write(c)
- counter = counter + 1
-
- if (max_chars != 0) and (counter == max_chars):
- sys.stdout.write('\n')
- return
-
- if modulo and ((counter % modulo) == 0):
- c = base
- continue
-
- if c == 'z':
- c = base
- elif c == 'Z':
- c = 'a'
- elif c == '9':
- c = 'A'
- else:
- c = '%c' % (ord(c) + 1)
-
-
-def main(args):
- '''Process command line arguments and invoke chargen if args are valid'''
-
- modulo = 0
- max_chars = 0
-
- try:
- if len(args) > 0:
- modulo = int(args[0])
- if len(args) > 1:
- max_chars = int(args[1])
- except ValueError:
- sys.stderr.write('usage %s:'
- "['seq_length' ['max_chars']]\n")
- sys.exit(1)
-
- try:
- chargen(modulo, max_chars)
- except KeyboardInterrupt:
- print
-
-if __name__ == '__main__':
- main(sys.argv[1:])
- sys.exit(0)
diff --git a/util/comm-dev.c b/util/comm-dev.c
deleted file mode 100644
index 679f15225f..0000000000
--- a/util/comm-dev.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "cros_ec_dev.h"
-#include "comm-host.h"
-#include "ec_commands.h"
-#include "misc_util.h"
-
-static int fd = -1;
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0]))
-#endif
-
-static const char * const meanings[] = {
- "SUCCESS",
- "INVALID_COMMAND",
- "ERROR",
- "INVALID_PARAM",
- "ACCESS_DENIED",
- "INVALID_RESPONSE",
- "INVALID_VERSION",
- "INVALID_CHECKSUM",
- "IN_PROGRESS",
- "UNAVAILABLE",
- "TIMEOUT",
- "OVERFLOW",
- "INVALID_HEADER",
- "REQUEST_TRUNCATED",
- "RESPONSE_TOO_BIG",
- "BUS_ERROR",
- "BUSY",
- "INVALID_HEADER_VERSION",
- "INVALID_HEADER_CRC",
- "INVALID_DATA_CRC",
- "DUP_UNAVAILABLE",
-};
-
-static const char *strresult(int i)
-{
- if (i < 0 || i >= ARRAY_SIZE(meanings))
- return "<unknown>";
- return meanings[i];
-}
-
-/* Old ioctl format, used by Chrome OS 3.18 and older */
-
-static int ec_command_dev(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- struct cros_ec_command s_cmd;
- int r;
-
- s_cmd.command = command;
- s_cmd.version = version;
- s_cmd.result = 0xff;
- s_cmd.outsize = outsize;
- s_cmd.outdata = (uint8_t *)outdata;
- s_cmd.insize = insize;
- s_cmd.indata = indata;
-
- r = ioctl(fd, CROS_EC_DEV_IOCXCMD, &s_cmd);
- if (r < 0) {
- fprintf(stderr, "ioctl %d, errno %d (%s), EC result %d (%s)\n",
- r, errno, strerror(errno), s_cmd.result,
- strresult(s_cmd.result));
- if (errno == EAGAIN && s_cmd.result == EC_RES_IN_PROGRESS) {
- s_cmd.command = EC_CMD_RESEND_RESPONSE;
- r = ioctl(fd, CROS_EC_DEV_IOCXCMD, &s_cmd);
- fprintf(stderr,
- "ioctl %d, errno %d (%s), EC result %d (%s)\n",
- r, errno, strerror(errno), s_cmd.result,
- strresult(s_cmd.result));
- }
- } else if (s_cmd.result != EC_RES_SUCCESS) {
- fprintf(stderr, "EC result %d (%s)\n", s_cmd.result,
- strresult(s_cmd.result));
- return -EECRESULT - s_cmd.result;
- }
-
- return r;
-}
-
-static int ec_readmem_dev(int offset, int bytes, void *dest)
-{
- struct cros_ec_readmem s_mem;
- struct ec_params_read_memmap r_mem;
- int r;
- static int fake_it;
-
- if (!fake_it) {
- s_mem.offset = offset;
- s_mem.bytes = bytes;
- s_mem.buffer = dest;
- r = ioctl(fd, CROS_EC_DEV_IOCRDMEM, &s_mem);
- if (r < 0 && errno == ENOTTY)
- fake_it = 1;
- else
- return r;
- }
-
- r_mem.offset = offset;
- r_mem.size = bytes;
- return ec_command_dev(EC_CMD_READ_MEMMAP, 0,
- &r_mem, sizeof(r_mem),
- dest, bytes);
-}
-
-/* New ioctl format, used by Chrome OS 4.4 and later as well as upstream 4.0+ */
-
-static int ec_command_dev_v2(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- struct cros_ec_command_v2 *s_cmd;
- int r;
-
- assert(outsize == 0 || outdata != NULL);
- assert(insize == 0 || indata != NULL);
-
- s_cmd = malloc(sizeof(struct cros_ec_command_v2) +
- MAX(outsize, insize));
- if (s_cmd == NULL)
- return -EC_RES_ERROR;
-
- s_cmd->command = command;
- s_cmd->version = version;
- s_cmd->result = 0xff;
- s_cmd->outsize = outsize;
- s_cmd->insize = insize;
- memcpy(s_cmd->data, outdata, outsize);
-
- r = ioctl(fd, CROS_EC_DEV_IOCXCMD_V2, s_cmd);
- if (r < 0) {
- fprintf(stderr, "ioctl %d, errno %d (%s), EC result %d (%s)\n",
- r, errno, strerror(errno), s_cmd->result,
- strresult(s_cmd->result));
- if (errno == EAGAIN && s_cmd->result == EC_RES_IN_PROGRESS) {
- s_cmd->command = EC_CMD_RESEND_RESPONSE;
- r = ioctl(fd, CROS_EC_DEV_IOCXCMD_V2, &s_cmd);
- fprintf(stderr,
- "ioctl %d, errno %d (%s), EC result %d (%s)\n",
- r, errno, strerror(errno), s_cmd->result,
- strresult(s_cmd->result));
- }
- } else {
- memcpy(indata, s_cmd->data, MIN(r, insize));
- if (s_cmd->result != EC_RES_SUCCESS) {
- fprintf(stderr, "EC result %d (%s)\n", s_cmd->result,
- strresult(s_cmd->result));
- r = -EECRESULT - s_cmd->result;
- }
- }
- free(s_cmd);
-
- return r;
-}
-
-static int ec_readmem_dev_v2(int offset, int bytes, void *dest)
-{
- struct cros_ec_readmem_v2 s_mem;
- struct ec_params_read_memmap r_mem;
- int r;
- static int fake_it;
-
- if (!fake_it) {
- s_mem.offset = offset;
- s_mem.bytes = bytes;
- r = ioctl(fd, CROS_EC_DEV_IOCRDMEM_V2, &s_mem);
- if (r < 0 && errno == ENOTTY) {
- fake_it = 1;
- } else {
- memcpy(dest, s_mem.buffer, bytes);
- return r;
- }
- }
-
- r_mem.offset = offset;
- r_mem.size = bytes;
- return ec_command_dev_v2(EC_CMD_READ_MEMMAP, 0,
- &r_mem, sizeof(r_mem),
- dest, bytes);
-}
-
-/*
- * Attempt to communicate with kernel using old ioctl format.
- * If it returns ENOTTY, assume that this kernel uses the new format.
- */
-static int ec_dev_is_v2(void)
-{
- struct ec_params_hello h_req = {
- .in_data = 0xa0b0c0d0
- };
- struct ec_response_hello h_resp;
- struct cros_ec_command s_cmd = { };
- int r;
-
- s_cmd.command = EC_CMD_HELLO;
- s_cmd.result = 0xff;
- s_cmd.outsize = sizeof(h_req);
- s_cmd.outdata = (uint8_t *)&h_req;
- s_cmd.insize = sizeof(h_resp);
- s_cmd.indata = (uint8_t *)&h_resp;
-
- r = ioctl(fd, CROS_EC_DEV_IOCXCMD, &s_cmd);
- if (r < 0 && errno == ENOTTY)
- return 1;
-
- return 0;
-}
-
-static int ec_pollevent_dev(unsigned long mask, void *buffer, size_t buf_size,
- int timeout)
-{
- int rv;
- struct pollfd pf = { .fd = fd, .events = POLLIN };
-
- ioctl(fd, CROS_EC_DEV_IOCEVENTMASK_V2, mask);
-
- rv = poll(&pf, 1, timeout);
- if (rv != 1)
- return rv;
-
- if (pf.revents != POLLIN)
- return -pf.revents;
-
- return read(fd, buffer, buf_size);
-}
-
-int comm_init_dev(const char *device_name)
-{
- int (*ec_cmd_readmem)(int offset, int bytes, void *dest);
- char version[80];
- char device[80] = "/dev/";
- int r;
- char *s;
-
- strncat(device, (device_name ? device_name : CROS_EC_DEV_NAME), 40);
- fd = open(device, O_RDWR);
- if (fd < 0)
- return 1;
-
- r = read(fd, version, sizeof(version)-1);
- if (r <= 0) {
- close(fd);
- return 2;
- }
- version[r] = '\0';
- s = strchr(version, '\n');
- if (s)
- *s = '\0';
- if (strcmp(version, CROS_EC_DEV_VERSION)) {
- close(fd);
- return 3;
- }
-
- if (ec_dev_is_v2()) {
- ec_command_proto = ec_command_dev_v2;
- ec_cmd_readmem = ec_readmem_dev_v2;
- } else {
- ec_command_proto = ec_command_dev;
- ec_cmd_readmem = ec_readmem_dev;
- }
-
- if (ec_cmd_readmem(EC_MEMMAP_ID, 2, version) == 2 &&
- version[0] == 'E' && version[1] == 'C')
- ec_readmem = ec_cmd_readmem;
- ec_pollevent = ec_pollevent_dev;
-
- /*
- * Set temporary size, will be updated later.
- */
- ec_max_outsize = EC_PROTO2_MAX_PARAM_SIZE - 8;
- ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
-
- return 0;
-}
diff --git a/util/comm-host.c b/util/comm-host.c
deleted file mode 100644
index dd42df1aa8..0000000000
--- a/util/comm-host.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "comm-host.h"
-#include "cros_ec_dev.h"
-#include "ec_commands.h"
-#include "misc_util.h"
-
-
-int (*ec_command_proto)(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize);
-
-int (*ec_readmem)(int offset, int bytes, void *dest);
-
-int (*ec_pollevent)(unsigned long mask, void *buffer, size_t buf_size,
- int timeout);
-
-int ec_max_outsize, ec_max_insize;
-void *ec_outbuf;
-void *ec_inbuf;
-static int command_offset;
-
-int comm_init_dev(const char *device_name) __attribute__((weak));
-int comm_init_lpc(void) __attribute__((weak));
-int comm_init_i2c(int i2c_bus) __attribute__((weak));
-int comm_init_servo_spi(const char *device_name) __attribute__((weak));
-
-static int fake_readmem(int offset, int bytes, void *dest)
-{
- struct ec_params_read_memmap p;
- int c;
- char *buf;
-
- p.offset = offset;
-
- if (bytes) {
- p.size = bytes;
- c = ec_command(EC_CMD_READ_MEMMAP, 0, &p, sizeof(p),
- dest, p.size);
- if (c < 0)
- return c;
- return p.size;
- }
-
- p.size = EC_MEMMAP_TEXT_MAX;
-
- c = ec_command(EC_CMD_READ_MEMMAP, 0, &p, sizeof(p), dest, p.size);
- if (c < 0)
- return c;
-
- buf = dest;
- for (c = 0; c < EC_MEMMAP_TEXT_MAX; c++) {
- if (buf[c] == 0)
- return c;
- }
-
- buf[EC_MEMMAP_TEXT_MAX - 1] = 0;
- return EC_MEMMAP_TEXT_MAX - 1;
-}
-
-void set_command_offset(int offset)
-{
- command_offset = offset;
-}
-
-int ec_command(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- /* Offset command code to support sub-devices */
- return ec_command_proto(command_offset + command, version,
- outdata, outsize,
- indata, insize);
-}
-
-int comm_init_alt(int interfaces, const char *device_name, int i2c_bus)
-{
- bool dev_is_cros_ec;
-
- /* Default memmap access */
- ec_readmem = fake_readmem;
-
- if ((interfaces & COMM_SERVO) && comm_init_servo_spi &&
- !comm_init_servo_spi(device_name))
- return 0;
-
- /* Do not fallback to other communication methods if target is not a
- * cros_ec device */
- dev_is_cros_ec = !strcmp(CROS_EC_DEV_NAME, device_name);
-
- /* Fallback to direct LPC on x86 */
- if (dev_is_cros_ec && (interfaces & COMM_LPC) &&
- comm_init_lpc && !comm_init_lpc())
- return 0;
-
- /* Fallback to direct I2C */
- if ((dev_is_cros_ec || i2c_bus != -1) && (interfaces & COMM_I2C) &&
- comm_init_i2c && !comm_init_i2c(i2c_bus))
- return 0;
-
- /* Give up */
- fprintf(stderr, "Unable to establish host communication\n");
- return 1;
-}
-
-int comm_init_buffer(void)
-{
- int allow_large_buffer;
- struct ec_response_get_protocol_info info;
-
- allow_large_buffer = kernel_version_ge(3, 14, 0);
- if (allow_large_buffer < 0) {
- fprintf(stderr, "Unable to check linux version\n");
- return 1;
- }
-
- /* Allocate shared I/O buffers */
- ec_outbuf = malloc(ec_max_outsize);
- ec_inbuf = malloc(ec_max_insize);
- if (!ec_outbuf || !ec_inbuf) {
- fprintf(stderr, "Unable to allocate buffers\n");
- return 1;
- }
-
- /* read max request / response size from ec for protocol v3+ */
- if (ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0, &info,
- sizeof(info)) == sizeof(info)) {
- int outsize = info.max_request_packet_size -
- sizeof(struct ec_host_request);
- int insize = info.max_response_packet_size -
- sizeof(struct ec_host_response);
- if ((allow_large_buffer) || (outsize < ec_max_outsize))
- ec_max_outsize = outsize;
- if ((allow_large_buffer) || (insize < ec_max_insize))
- ec_max_insize = insize;
-
- ec_outbuf = realloc(ec_outbuf, ec_max_outsize);
- ec_inbuf = realloc(ec_inbuf, ec_max_insize);
-
- if (!ec_outbuf || !ec_inbuf) {
- fprintf(stderr, "Unable to reallocate buffers\n");
- return 1;
- }
- }
-
- return 0;
-}
diff --git a/util/comm-host.h b/util/comm-host.h
deleted file mode 100644
index 309c97eeb5..0000000000
--- a/util/comm-host.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright 2013 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.
- *
- * For hysterical raisins, there are several mechanisms for communicating with
- * the EC. This abstracts them.
- */
-
-#ifndef __UTIL_COMM_HOST_H
-#define __UTIL_COMM_HOST_H
-
-#include "common.h"
-#include "ec_commands.h"
-
-/* ec_command return value for non-success result from EC */
-#define EECRESULT 1000
-
-/* Maximum output and input sizes for EC command, in bytes */
-extern int ec_max_outsize, ec_max_insize;
-
-/*
- * Maximum-size output and input buffers, for use by callers. This saves each
- * caller needing to allocate/free its own buffers.
- */
-extern void *ec_outbuf;
-extern void *ec_inbuf;
-
-/* Interfaces to allow for comm_init() */
-enum comm_interface {
- COMM_DEV = BIT(0),
- COMM_LPC = BIT(1),
- COMM_I2C = BIT(2),
- COMM_SERVO = BIT(3),
- COMM_ALL = -1
-};
-
-/**
- * Initialize alternative interfaces
- *
- * @param interfaces Interfaces to try; use COMM_ALL to try all of them.
- * @param device_name For DEV option, the device file to use.
- * @param i2c_bus For I2C option, the bus number to use (or -1 to autodetect).
- * @return 0 in case of success, or error code.
- */
-int comm_init_alt(int interfaces, const char *device_name, int i2c_bus);
-
-/**
- * Initialize dev interface
- *
- * @return 0 in case of success, or error code.
- */
-int comm_init_dev(const char *device_name);
-
-/**
- * Initialize input & output buffers
- *
- * @return 0 in case of success, or error code.
- */
-int comm_init_buffer(void);
-
-/**
- * Send a command to the EC. Returns the length of output data returned (0 if
- * none), or negative on error.
- */
-int ec_command(int command, int version,
- const void *outdata, int outsize, /* to the EC */
- void *indata, int insize); /* from the EC */
-
-/**
- * Set the offset to be applied to the command number when ec_command() calls
- * ec_command_proto().
- */
-void set_command_offset(int offset);
-
-/**
- * Send a command to the EC. Returns the length of output data returned (0 if
- * none), or negative on error. This is the low-level interface implemented
- * by the protocol-specific driver. DO NOT call this version directly from
- * anywhere but ec_command(), or the --device option will not work.
- */
-extern int (*ec_command_proto)(int command, int version,
- const void *outdata, int outsize, /* to EC */
- void *indata, int insize); /* from EC */
-
-/**
- * Return the content of the EC information area mapped as "memory".
- * The offsets are defined by the EC_MEMMAP_ constants. Returns the number
- * of bytes read, or negative on error. Specifying bytes=0 will read a
- * string (always including the trailing '\0').
- */
-extern int (*ec_readmem)(int offset, int bytes, void *dest);
-
-/**
- * Wait for a MKBP event matching 'mask' for at most 'timeout' milliseconds.
- * Then read the incoming event content in 'buffer' (or at most
- * 'buf_size' bytes of it).
- * Return the size of the event read on success, 0 in case of timeout,
- * or a negative value in case of error.
- */
-extern int (*ec_pollevent)(unsigned long mask, void *buffer, size_t buf_size,
- int timeout);
-
-#endif /* __UTIL_COMM_HOST_H */
diff --git a/util/comm-i2c.c b/util/comm-i2c.c
deleted file mode 100644
index d88454ee3b..0000000000
--- a/util/comm-i2c.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/* Copyright 2012 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.
- */
-
-#define _GNU_SOURCE /* for asprintf */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "comm-host.h"
-#include "i2c.h"
-
-#define EC_I2C_ADDR 0x1e
-
-#define I2C_ADAPTER_NODE "/sys/class/i2c-adapter/i2c-%d/%d-%04x/name"
-#define I2C_ADAPTER_NAME "cros-ec-i2c"
-#define I2C_MAX_ADAPTER 32
-#define I2C_NODE "/dev/i2c-%d"
-
-#ifdef DEBUG
-#define debug(format, arg...) printf(format, ##arg)
-#else
-#define debug(...)
-#endif
-
-static int i2c_fd = -1;
-
-static int sum_bytes(const void *data, int length)
-{
- const uint8_t *bytes = (const uint8_t *)data;
- int sum = 0;
- int i;
-
- for (i = 0; i < length; i++)
- sum += bytes[i];
- return sum;
-}
-
-static void dump_buffer(const uint8_t *data, int length)
-{
- int i;
-
- for (i = 0; i < length; i++)
- fprintf(stderr, "%02X ", data[i]);
- fprintf(stderr, "\n");
-}
-
-/*
- * Sends a command to the EC (protocol v3). Returns the command status code
- * (>= 0), or a negative EC_RES_* value on error.
- */
-static int ec_command_i2c_3(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- int ret = -EC_RES_ERROR;
- int error;
- int req_len, resp_len;
- uint8_t *req_buf = NULL;
- uint8_t *resp_buf = NULL;
- struct ec_host_request *req;
- struct ec_host_response *resp;
- uint8_t command_return_code;
- struct i2c_msg i2c_msg;
- struct i2c_rdwr_ioctl_data data;
-
- if (outsize > ec_max_outsize) {
- fprintf(stderr, "Request is too large (%d > %d).\n", outsize,
- ec_max_outsize);
- return -EC_RES_ERROR;
- }
- if (insize > ec_max_insize) {
- fprintf(stderr, "Response would be too large (%d > %d).\n",
- insize, ec_max_insize);
- return -EC_RES_ERROR;
- }
- req_len = I2C_REQUEST_HEADER_SIZE + sizeof(struct ec_host_request)
- + outsize;
- req_buf = calloc(1, req_len);
- if (!req_buf)
- goto done;
-
- req_buf[0] = EC_COMMAND_PROTOCOL_3;
- req = (struct ec_host_request *)&req_buf[1];
- req->struct_version = EC_HOST_REQUEST_VERSION;
- req->checksum = 0;
- req->command = command;
- req->command_version = version;
- req->reserved = 0;
- req->data_len = outsize;
-
- memcpy(&req_buf[I2C_REQUEST_HEADER_SIZE
- + sizeof(struct ec_host_request)],
- outdata, outsize);
-
- req->checksum =
- (uint8_t)(-sum_bytes(&req_buf[I2C_REQUEST_HEADER_SIZE],
- req_len - I2C_REQUEST_HEADER_SIZE));
-
- i2c_msg.addr = EC_I2C_ADDR;
- i2c_msg.flags = 0;
- i2c_msg.len = req_len;
- i2c_msg.buf = (char *)req_buf;
-
- resp_len = I2C_RESPONSE_HEADER_SIZE + sizeof(struct ec_host_response)
- + insize;
- resp_buf = calloc(1, resp_len);
- if (!resp_buf)
- goto done;
- memset(resp_buf, 0, resp_len);
-
- if (IS_ENABLED(DEBUG)) {
- fprintf(stderr, "Sending: 0x");
- dump_buffer(req_buf, req_len);
- }
-
- /*
- * Combining these two ioctls makes the write-read interval too short
- * for some chips (such as the MAX32660) to handle.
- */
- data.msgs = &i2c_msg;
- data.nmsgs = 1;
- error = ioctl(i2c_fd, I2C_RDWR, &data);
- if (error < 0) {
- fprintf(stderr, "I2C write failed: %d (err: %d, %s)\n",
- error, errno, strerror(errno));
- goto done;
- }
-
- i2c_msg.addr = EC_I2C_ADDR;
- i2c_msg.flags = I2C_M_RD;
- i2c_msg.len = resp_len;
- i2c_msg.buf = (char *)resp_buf;
- error = ioctl(i2c_fd, I2C_RDWR, &data);
- if (error < 0) {
- fprintf(stderr, "I2C read failed: %d (err: %d, %s)\n",
- error, errno, strerror(errno));
- goto done;
- }
-
- if (IS_ENABLED(DEBUG)) {
- fprintf(stderr, "Received: 0x");
- dump_buffer(resp_buf, resp_len);
- }
-
- command_return_code = resp_buf[0];
- if (command_return_code != EC_RES_SUCCESS) {
- debug("command 0x%02x returned an error %d\n", command,
- command_return_code);
- ret = -EECRESULT - command_return_code;
- goto done;
- }
-
- if (resp_buf[1] > sizeof(struct ec_host_response) + insize) {
- debug("EC returned too much data.\n");
- ret = -EC_RES_RESPONSE_TOO_BIG;
- goto done;
- }
-
- resp = (struct ec_host_response *)(&resp_buf[2]);
- if (resp->struct_version != EC_HOST_RESPONSE_VERSION) {
- debug("EC response version mismatch.\n");
- ret = -EC_RES_INVALID_RESPONSE;
- goto done;
- }
-
- if ((uint8_t)sum_bytes(&resp_buf[I2C_RESPONSE_HEADER_SIZE], resp_buf[1])
- != 0) {
- debug("Bad checksum on EC response.\n");
- ret = -EC_RES_INVALID_CHECKSUM;
- goto done;
- }
-
- memcpy(indata, &resp_buf[I2C_RESPONSE_HEADER_SIZE
- + sizeof(struct ec_host_response)],
- insize);
-
- ret = resp->data_len;
-done:
- if (req_buf)
- free(req_buf);
- if (resp_buf)
- free(resp_buf);
-
- return ret;
-}
-
-int comm_init_i2c(int i2c_bus)
-{
- char *file_path;
- char buffer[64];
- int i;
-
- if (i2c_bus != -1) {
- i = i2c_bus;
-
- if (i >= I2C_MAX_ADAPTER) {
- fprintf(stderr, "Invalid I2C bus number %d. (The highest possible bus number is %d.)\n",
- i, I2C_MAX_ADAPTER);
- return -1;
- }
- } else {
- /* find the device number based on the adapter name */
- for (i = 0; i < I2C_MAX_ADAPTER; i++) {
- FILE *f;
-
- if (asprintf(&file_path, I2C_ADAPTER_NODE,
- i, i, EC_I2C_ADDR) < 0)
- return -1;
- f = fopen(file_path, "r");
- if (f) {
- if (fgets(buffer, sizeof(buffer), f) &&
- !strncmp(buffer, I2C_ADAPTER_NAME, 6)) {
- free(file_path);
- fclose(f);
- break;
- }
- fclose(f);
- }
- free(file_path);
- }
- if (i == I2C_MAX_ADAPTER) {
- fprintf(stderr, "Cannot find I2C adapter\n");
- return -1;
- }
- }
-
- if (asprintf(&file_path, I2C_NODE, i) < 0)
- return -1;
- debug("using I2C adapter %s\n", file_path);
- i2c_fd = open(file_path, O_RDWR);
- if (i2c_fd < 0)
- fprintf(stderr, "Cannot open %s : %d\n", file_path, errno);
-
- free(file_path);
-
- ec_command_proto = ec_command_i2c_3;
- ec_max_outsize = I2C_MAX_HOST_PACKET_SIZE - I2C_REQUEST_HEADER_SIZE
- - sizeof(struct ec_host_request);
- ec_max_insize = I2C_MAX_HOST_PACKET_SIZE - I2C_RESPONSE_HEADER_SIZE
- - sizeof(struct ec_host_response);
-
- return 0;
-}
diff --git a/util/comm-lpc.c b/util/comm-lpc.c
deleted file mode 100644
index a3a8f64ff7..0000000000
--- a/util/comm-lpc.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* Copyright 2013 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.
- */
-
-/* The I/O asm funcs exist only on x86. */
-#if defined(__i386__) || defined(__x86_64__)
-
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/io.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-#include "comm-host.h"
-
-#define INITIAL_UDELAY 5 /* 5 us */
-#define MAXIMUM_UDELAY 10000 /* 10 ms */
-
-/*
- * Wait for the EC to be unbusy. Returns 0 if unbusy, non-zero if
- * timeout.
- */
-static int wait_for_ec(int status_addr, int timeout_usec)
-{
- int i;
- int delay = INITIAL_UDELAY;
-
- for (i = 0; i < timeout_usec; i += delay) {
- /*
- * Delay first, in case we just sent out a command but the EC
- * hasn't raised the busy flag. However, I think this doesn't
- * happen since the LPC commands are executed in order and the
- * busy flag is set by hardware. Minor issue in any case,
- * since the initial delay is very short.
- */
- usleep(MIN(delay, timeout_usec - i));
-
- if (!(inb(status_addr) & EC_LPC_STATUS_BUSY_MASK))
- return 0;
-
- /* Increase the delay interval after a few rapid checks */
- if (i > 20)
- delay = MIN(delay * 2, MAXIMUM_UDELAY);
- }
- return -1; /* Timeout */
-}
-
-static int ec_command_lpc(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- struct ec_lpc_host_args args;
- const uint8_t *d;
- uint8_t *dout;
- int csum;
- int i;
-
- /* Fill in args */
- args.flags = EC_HOST_ARGS_FLAG_FROM_HOST;
- args.command_version = version;
- args.data_size = outsize;
-
- /* Initialize checksum */
- csum = command + args.flags + args.command_version + args.data_size;
-
- /* Write data and update checksum */
- for (i = 0, d = (uint8_t *)outdata; i < outsize; i++, d++) {
- outb(*d, EC_LPC_ADDR_HOST_PARAM + i);
- csum += *d;
- }
-
- /* Finalize checksum and write args */
- args.checksum = (uint8_t)csum;
- for (i = 0, d = (const uint8_t *)&args; i < sizeof(args); i++, d++)
- outb(*d, EC_LPC_ADDR_HOST_ARGS + i);
-
- outb(command, EC_LPC_ADDR_HOST_CMD);
-
- if (wait_for_ec(EC_LPC_ADDR_HOST_CMD, 1000000)) {
- fprintf(stderr, "Timeout waiting for EC response\n");
- return -EC_RES_ERROR;
- }
-
- /* Check result */
- i = inb(EC_LPC_ADDR_HOST_DATA);
- if (i) {
- fprintf(stderr, "EC returned error result code %d\n", i);
- return -EECRESULT - i;
- }
-
- /* Read back args */
- for (i = 0, dout = (uint8_t *)&args; i < sizeof(args); i++, dout++)
- *dout = inb(EC_LPC_ADDR_HOST_ARGS + i);
-
- /*
- * If EC didn't modify args flags, then somehow we sent a new-style
- * command to an old EC, which means it would have read its params
- * from the wrong place.
- */
- if (!(args.flags & EC_HOST_ARGS_FLAG_TO_HOST)) {
- fprintf(stderr, "EC protocol mismatch\n");
- return -EC_RES_INVALID_RESPONSE;
- }
-
- if (args.data_size > insize) {
- fprintf(stderr, "EC returned too much data\n");
- return -EC_RES_INVALID_RESPONSE;
- }
-
- /* Start calculating response checksum */
- csum = command + args.flags + args.command_version + args.data_size;
-
- /* Read response and update checksum */
- for (i = 0, dout = (uint8_t *)indata; i < args.data_size;
- i++, dout++) {
- *dout = inb(EC_LPC_ADDR_HOST_PARAM + i);
- csum += *dout;
- }
-
- /* Verify checksum */
- if (args.checksum != (uint8_t)csum) {
- fprintf(stderr, "EC response has invalid checksum\n");
- return -EC_RES_INVALID_CHECKSUM;
- }
-
- /* Return actual amount of data received */
- return args.data_size;
-}
-
-static int ec_command_lpc_3(int command, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- struct ec_host_request rq;
- struct ec_host_response rs;
- const uint8_t *d;
- uint8_t *dout;
- int csum = 0;
- int i;
-
- /* Fail if output size is too big */
- if (outsize + sizeof(rq) > EC_LPC_HOST_PACKET_SIZE)
- return -EC_RES_REQUEST_TRUNCATED;
-
- /* Fill in request packet */
- /* TODO(crosbug.com/p/23825): This should be common to all protocols */
- rq.struct_version = EC_HOST_REQUEST_VERSION;
- rq.checksum = 0;
- rq.command = command;
- rq.command_version = version;
- rq.reserved = 0;
- rq.data_len = outsize;
-
- /* Copy data and start checksum */
- for (i = 0, d = (const uint8_t *)outdata; i < outsize; i++, d++) {
- outb(*d, EC_LPC_ADDR_HOST_PACKET + sizeof(rq) + i);
- csum += *d;
- }
-
- /* Finish checksum */
- for (i = 0, d = (const uint8_t *)&rq; i < sizeof(rq); i++, d++)
- csum += *d;
-
- /* Write checksum field so the entire packet sums to 0 */
- rq.checksum = (uint8_t)(-csum);
-
- /* Copy header */
- for (i = 0, d = (const uint8_t *)&rq; i < sizeof(rq); i++, d++)
- outb(*d, EC_LPC_ADDR_HOST_PACKET + i);
-
- /* Start the command */
- outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
-
- if (wait_for_ec(EC_LPC_ADDR_HOST_CMD, 1000000)) {
- fprintf(stderr, "Timeout waiting for EC response\n");
- return -EC_RES_ERROR;
- }
-
- /* Check result */
- i = inb(EC_LPC_ADDR_HOST_DATA);
- if (i) {
- fprintf(stderr, "EC returned error result code %d\n", i);
- return -EECRESULT - i;
- }
-
- /* Read back response header and start checksum */
- csum = 0;
- for (i = 0, dout = (uint8_t *)&rs; i < sizeof(rs); i++, dout++) {
- *dout = inb(EC_LPC_ADDR_HOST_PACKET + i);
- csum += *dout;
- }
-
- if (rs.struct_version != EC_HOST_RESPONSE_VERSION) {
- fprintf(stderr, "EC response version mismatch\n");
- return -EC_RES_INVALID_RESPONSE;
- }
-
- if (rs.reserved) {
- fprintf(stderr, "EC response reserved != 0\n");
- return -EC_RES_INVALID_RESPONSE;
- }
-
- if (rs.data_len > insize) {
- fprintf(stderr, "EC returned too much data\n");
- return -EC_RES_RESPONSE_TOO_BIG;
- }
-
- /* Read back data and update checksum */
- for (i = 0, dout = (uint8_t *)indata; i < rs.data_len; i++, dout++) {
- *dout = inb(EC_LPC_ADDR_HOST_PACKET + sizeof(rs) + i);
- csum += *dout;
- }
-
- /* Verify checksum */
- if ((uint8_t)csum) {
- fprintf(stderr, "EC response has invalid checksum\n");
- return -EC_RES_INVALID_CHECKSUM;
- }
-
- /* Return actual amount of data received */
- return rs.data_len;
-}
-
-static int ec_readmem_lpc(int offset, int bytes, void *dest)
-{
- int i = offset;
- char *s = dest;
- int cnt = 0;
-
- if (offset >= EC_MEMMAP_SIZE - bytes)
- return -1;
-
- if (bytes) { /* fixed length */
- for (; cnt < bytes; i++, s++, cnt++)
- *s = inb(EC_LPC_ADDR_MEMMAP + i);
- } else { /* string */
- for (; i < EC_MEMMAP_SIZE; i++, s++) {
- *s = inb(EC_LPC_ADDR_MEMMAP + i);
- cnt++;
- if (!*s)
- break;
- }
- }
-
- return cnt;
-}
-
-int comm_init_lpc(void)
-{
- int i;
- int byte = 0xff;
-
- /* Request I/O privilege */
- if (iopl(3) < 0) {
- perror("Error getting I/O privilege");
- return -3;
- }
-
- /*
- * Test if the I/O port has been configured for Chromium EC LPC
- * interface. Chromium EC guarantees that at least one status bit will
- * be 0, so if the command and data bytes are both 0xff, very likely
- * that Chromium EC is not present. See crosbug.com/p/10963.
- */
- byte &= inb(EC_LPC_ADDR_HOST_CMD);
- byte &= inb(EC_LPC_ADDR_HOST_DATA);
- if (byte == 0xff) {
- fprintf(stderr, "Port 0x%x,0x%x are both 0xFF.\n",
- EC_LPC_ADDR_HOST_CMD, EC_LPC_ADDR_HOST_DATA);
- fprintf(stderr,
- "Very likely this board doesn't have a Chromium EC.\n");
- return -4;
- }
-
- /*
- * Test if LPC command args are supported.
- *
- * The cheapest way to do this is by looking for the memory-mapped
- * flag. This is faster than sending a new-style 'hello' command and
- * seeing whether the EC sets the EC_HOST_ARGS_FLAG_FROM_HOST flag
- * in args when it responds.
- */
- if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) != 'E' ||
- inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) != 'C') {
- fprintf(stderr, "Missing Chromium EC memory map.\n");
- return -5;
- }
-
- /* Check which command version we'll use */
- i = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_HOST_CMD_FLAGS);
-
- if (i & EC_HOST_CMD_FLAG_VERSION_3) {
- /* Protocol version 3 */
- ec_command_proto = ec_command_lpc_3;
- ec_max_outsize = EC_LPC_HOST_PACKET_SIZE -
- sizeof(struct ec_host_request);
- ec_max_insize = EC_LPC_HOST_PACKET_SIZE -
- sizeof(struct ec_host_response);
-
- } else if (i & EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED) {
- /* Protocol version 2 */
- ec_command_proto = ec_command_lpc;
- ec_max_outsize = ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
-
- } else {
- fprintf(stderr, "EC doesn't support protocols we need.\n");
- return -5;
- }
-
- /* Either one supports reading mapped memory directly. */
- ec_readmem = ec_readmem_lpc;
- return 0;
-}
-
-#endif
diff --git a/util/comm-servo-spi.c b/util/comm-servo-spi.c
deleted file mode 100644
index 4010d2ec64..0000000000
--- a/util/comm-servo-spi.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* Copyright 2018 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.
- */
-/*
- * Transport using the Servo V2 SPI1 interface through the FT4232 MPSSE
- * hardware engine (driven by libftdi) in order to send host commands V3
- * directly to a MCU slave SPI controller.
- *
- * It allows to drive a MCU with the cros_ec host SPI interface directly from
- * a developer workstation or another test system.
- *
- * The USB serial number of the servo board can be passed in the 'name'
- * parameter, e.g. :
- * sudo ectool_servo --name=905537-00474 version
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <libftdi1/ftdi.h>
-
-#include "comm-host.h"
-#include "cros_ec_dev.h"
-
-/* Servo V2 SPI1 interface identifiers */
-#define SERVO_V2_USB_VID 0x18d1
-#define SERVO_V2_USB_PID 0x5003
-#define SERVO_V2_USB_SPI1_INTERFACE INTERFACE_B
-
-/* SPI clock frequency in Hz */
-#define SPI_CLOCK_FREQ 1000000
-
-#define FTDI_LATENCY_1MS 2
-
-/* Timeout when waiting for the EC answer to our request */
-#define RESP_TIMEOUT 2 /* second */
-
-#ifdef DEBUG
-#define debug(format, arg...) printf(format, ##arg)
-#else
-#define debug(...)
-#endif
-
-/* Communication context */
-static struct ftdi_context ftdi;
-
-/* Size of a MPSSE command packet */
-#define MPSSE_CMD_SIZE 3
-
-enum mpsse_commands {
- ENABLE_ADAPTIVE_CLOCK = 0x96,
- DISABLE_ADAPTIVE_CLOCK = 0x97,
- TCK_X5 = 0x8A,
- TCK_D5 = 0x8B,
- TRISTATE_IO = 0x9E,
-};
-
-enum mpsse_pins {
- SCLK = 1,
- MOSI = 2,
- MISO = 4,
- CS_L = 8,
-};
-/* SCLK/MOSI/CS_L are outputs, MISO is an input */
-#define PINS_DIR (SCLK | MOSI | CS_L)
-
-/* SPI mode 0:
- * propagates data on the falling edge
- * and reads data on the rising edge of the clock.
- */
-#define SPI_CMD_TX (MPSSE_DO_WRITE | MPSSE_WRITE_NEG)
-#define SPI_CMD_RX (MPSSE_DO_READ)
-#define SPI_CMD_TXRX (MPSSE_DO_WRITE | MPSSE_DO_READ | MPSSE_WRITE_NEG)
-
-static int raw_read(uint8_t *buf, int size)
-{
- int rlen;
-
- while (size) {
- rlen = ftdi_read_data(&ftdi, buf, size);
- if (rlen < 0)
- break;
- buf += rlen;
- size -= rlen;
- }
- return !!size;
-}
-
-static int mpsse_set_pins(uint8_t levels)
-{
- uint8_t buf[MPSSE_CMD_SIZE] = {0};
-
- buf[0] = SET_BITS_LOW;
- buf[1] = levels;
- buf[2] = PINS_DIR;
-
- return ftdi_write_data(&ftdi, buf, sizeof(buf)) != sizeof(buf);
-}
-
-static int send_request(int cmd, int version,
- const uint8_t *outdata, size_t outsize)
-{
- uint8_t *txbuf;
- struct ec_host_request *request;
- size_t i;
- int ret = -EC_RES_ERROR;
- uint8_t csum = 0;
- size_t block_size = sizeof(struct ec_host_request) + outsize;
- size_t total_len = MPSSE_CMD_SIZE + block_size;
-
- txbuf = calloc(1, total_len);
- if (!txbuf)
- return -ENOMEM;
-
- /* MPSSE block size is the full command minus 1 byte */
- txbuf[0] = SPI_CMD_TXRX;
- txbuf[1] = ((block_size - 1) & 0xFF);
- txbuf[2] = (((block_size - 1) >> 8) & 0xFF);
-
- /* Command header first */
- request = (struct ec_host_request *)(txbuf + MPSSE_CMD_SIZE);
- request->struct_version = EC_HOST_REQUEST_VERSION;
- request->checksum = 0;
- request->command = cmd;
- request->command_version = version;
- request->reserved = 0;
- request->data_len = outsize;
-
- /* copy the data to transmit after the command header */
- memcpy(txbuf + MPSSE_CMD_SIZE + sizeof(struct ec_host_request),
- outdata, outsize);
-
- /* Compute the checksum */
- for (i = MPSSE_CMD_SIZE; i < total_len; i++)
- csum += txbuf[i];
- request->checksum = -csum;
-
- if (ftdi_write_data(&ftdi, txbuf, total_len) != total_len)
- goto free_request;
-
- if (raw_read(txbuf, block_size) != 0)
- goto free_request;
-
- /* Make sure the EC was listening */
- ret = 0;
- for (i = 0; i < block_size; i++) {
- switch (txbuf[i]) {
- case EC_SPI_PAST_END:
- case EC_SPI_RX_BAD_DATA:
- case EC_SPI_NOT_READY:
- ret = txbuf[i];
- /* Fall-through */
- default:
- break;
- }
- if (ret)
- break;
- }
-
-free_request:
- free(txbuf);
- return ret;
-}
-
-static int spi_read(void *buf, size_t size)
-{
- uint8_t cmd[MPSSE_CMD_SIZE];
-
- cmd[0] = SPI_CMD_RX;
- cmd[1] = ((size - 1) & 0xFF);
- cmd[2] = (((size - 1) >> 8) & 0xFF);
-
- if (ftdi_write_data(&ftdi, cmd, sizeof(cmd)) != sizeof(cmd))
- return -EC_RES_ERROR;
-
- return raw_read(buf, size) != 0;
-}
-
-static int get_response(uint8_t *bodydest, size_t bodylen)
-{
- uint8_t sum = 0;
- size_t i;
- struct ec_host_response hdr;
- uint8_t status;
- time_t deadline = time(NULL) + RESP_TIMEOUT;
-
- /*
- * Read a byte at a time until we see the start of the frame.
- * This is slow, but often still faster than the EC.
- */
- while (time(NULL) < deadline) {
- if (spi_read(&status, sizeof(status)))
- goto read_error;
- if (status == EC_SPI_FRAME_START)
- break;
- }
- if (status != EC_SPI_FRAME_START) {
- fprintf(stderr, "timeout wait for response\n");
- return -EC_RES_ERROR;
- }
-
- /* Now read the response header */
- if (spi_read(&hdr, sizeof(hdr)))
- goto read_error;
-
- /* Check the header */
- if (hdr.struct_version != EC_HOST_RESPONSE_VERSION) {
- fprintf(stderr, "response version %d (should be %d)\n",
- hdr.struct_version,
- EC_HOST_RESPONSE_VERSION);
- return -EC_RES_ERROR;
- }
- if (hdr.data_len > bodylen) {
- fprintf(stderr, "response data_len %d is > %zd\n",
- hdr.data_len, bodylen);
- return -EC_RES_ERROR;
- }
-
- /* Read the data if needed */
- if (hdr.data_len && spi_read(bodydest, hdr.data_len))
- goto read_error;
-
- /* Verify the checksum */
- for (i = 0; i < sizeof(struct ec_host_response); i++)
- sum += ((uint8_t *)&hdr)[i];
- for (i = 0; i < hdr.data_len; i++)
- sum += bodydest[i];
- if (sum) {
- fprintf(stderr, "Checksum invalid\n");
- return -EC_RES_ERROR;
- }
-
- return hdr.result ? -EECRESULT - hdr.result : 0;
-
-read_error:
- fprintf(stderr, "Read failed: %s\n", ftdi_get_error_string(&ftdi));
- return -EC_RES_ERROR;
-}
-
-static int ec_command_servo_spi(int cmd, int version,
- const void *outdata, int outsize,
- void *indata, int insize)
-{
- int ret = -EC_RES_ERROR;
-
- /* Set the chip select low */
- if (mpsse_set_pins(0) != 0) {
- fprintf(stderr, "Start failed: %s\n",
- ftdi_get_error_string(&ftdi));
- return -EC_RES_ERROR;
- }
-
- if (send_request(cmd, version, outdata, outsize) == 0)
- ret = get_response(indata, insize);
-
- if (mpsse_set_pins(CS_L) != 0) {
- fprintf(stderr, "Stop failed: %s\n",
- ftdi_get_error_string(&ftdi));
- return -EC_RES_ERROR;
- }
- /* SPI protocol gap ... */
- usleep(10);
-
- return ret;
-}
-
-static int mpsse_set_clock(uint32_t freq)
-{
- uint32_t system_clock = 0;
- uint16_t divisor = 0;
- uint8_t buf[MPSSE_CMD_SIZE] = {0};
-
- if (freq > 6000000) {
- buf[0] = TCK_X5;
- system_clock = 60000000;
- } else {
- buf[0] = TCK_D5;
- system_clock = 12000000;
- }
-
- if (ftdi_write_data(&ftdi, buf, 1) != 1)
- return -EC_RES_ERROR;
-
- divisor = (((system_clock / freq) / 2) - 1);
-
- buf[0] = TCK_DIVISOR;
- buf[1] = (divisor & 0xFF);
- buf[2] = ((divisor >> 8) & 0xFF);
-
- return ftdi_write_data(&ftdi, buf, MPSSE_CMD_SIZE) != MPSSE_CMD_SIZE;
-}
-
-static void servo_spi_close(void)
-{
- ftdi_set_bitmode(&ftdi, 0, BITMODE_RESET);
- ftdi_usb_close(&ftdi);
- ftdi_deinit(&ftdi);
-}
-
-int comm_init_servo_spi(const char *device_name)
-{
- int status;
- uint8_t buf[MPSSE_CMD_SIZE] = {0};
- /* if the user mentioned a device name, use it as serial string */
- const char *serial = strcmp(CROS_EC_DEV_NAME, device_name) ?
- device_name : NULL;
-
- if (ftdi_init(&ftdi))
- return -EC_RES_ERROR;
- ftdi_set_interface(&ftdi, SERVO_V2_USB_SPI1_INTERFACE);
-
- status = ftdi_usb_open_desc(&ftdi, SERVO_V2_USB_VID, SERVO_V2_USB_PID,
- NULL, serial);
- if (status) {
- debug("Can't find a Servo v2 USB device\n");
- return -EC_RES_ERROR;
- }
-
- status |= ftdi_usb_reset(&ftdi);
- status |= ftdi_set_latency_timer(&ftdi, FTDI_LATENCY_1MS);
- status |= ftdi_set_bitmode(&ftdi, 0, BITMODE_RESET);
- if (status)
- goto err_close;
-
- ftdi_set_bitmode(&ftdi, 0, BITMODE_MPSSE);
- if (mpsse_set_clock(SPI_CLOCK_FREQ))
- goto err_close;
-
- /* Disable FTDI internal loopback */
- buf[0] = LOOPBACK_END;
- if (ftdi_write_data(&ftdi, buf, 1) != 1)
- goto err_close;
- /* Ensure adaptive clock is disabled */
- buf[0] = DISABLE_ADAPTIVE_CLOCK;
- if (ftdi_write_data(&ftdi, buf, 1) != 1)
- goto err_close;
- /* Set the idle pin states */
- if (mpsse_set_pins(CS_L) != 0)
- goto err_close;
-
- ec_command_proto = ec_command_servo_spi;
- /* Set temporary size, will be updated later. */
- ec_max_outsize = EC_PROTO2_MAX_PARAM_SIZE - 8;
- ec_max_insize = EC_PROTO2_MAX_PARAM_SIZE;
-
- return 0;
-
-err_close:
- servo_spi_close();
- return -EC_RES_ERROR;
-}
diff --git a/util/cros_ec_dev.h b/util/cros_ec_dev.h
deleted file mode 100644
index 41930f97dd..0000000000
--- a/util/cros_ec_dev.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#ifndef __UTIL_CROS_EC_DEV_H
-#define __UTIL_CROS_EC_DEV_H
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-#include "ec_commands.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define CROS_EC_DEV_NAME "cros_ec"
-#define CROS_EC_DEV_VERSION "1.0.0"
-
-/*
- * @version: Command version number (often 0)
- * @command: Command to send (EC_CMD_...)
- * @outdata: Outgoing data to EC
- * @outsize: Outgoing length in bytes
- * @indata: Where to put the incoming data from EC
- * @insize: On call, how much we can accept. On return, how much we got.
- * @result: EC's response to the command (separate from communication failure)
- * ioctl returns zero on success, negative on error
- */
-struct cros_ec_command {
- uint32_t version;
- uint32_t command;
- uint8_t *outdata;
- uint32_t outsize;
- uint8_t *indata;
- uint32_t insize;
- uint32_t result;
-};
-
-/*
- * @offset: within EC_LPC_ADDR_MEMMAP region
- * @bytes: number of bytes to read. zero means "read a string" (including '\0')
- * (at most only EC_MEMMAP_SIZE bytes can be read)
- * @buffer: where to store the result
- * ioctl returns the number of bytes read, negative on error
- */
-struct cros_ec_readmem {
- uint32_t offset;
- uint32_t bytes;
- char *buffer;
-};
-
-#define CROS_EC_DEV_IOC ':'
-#define CROS_EC_DEV_IOCXCMD _IOWR(':', 0, struct cros_ec_command)
-#define CROS_EC_DEV_IOCRDMEM _IOWR(':', 1, struct cros_ec_readmem)
-
-/*
- * @version: Command version number (often 0)
- * @command: Command to send (EC_CMD_...)
- * @outsize: Outgoing length in bytes
- * @insize: Max number of bytes to accept from EC
- * @result: EC's response to the command (separate from communication failure)
- * @data: Where to put the incoming data from EC and outgoing data to EC
- */
-struct cros_ec_command_v2 {
- uint32_t version;
- uint32_t command;
- uint32_t outsize;
- uint32_t insize;
- uint32_t result;
- uint8_t data[0];
-};
-
-/*
- * @offset: within EC_LPC_ADDR_MEMMAP region
- * @bytes: number of bytes to read. zero means "read a string" (including '\0')
- * (at most only EC_MEMMAP_SIZE bytes can be read)
- * @buffer: where to store the result
- * ioctl returns the number of bytes read, negative on error
- */
-struct cros_ec_readmem_v2 {
- uint32_t offset;
- uint32_t bytes;
- uint8_t buffer[EC_MEMMAP_SIZE];
-};
-
-#define CROS_EC_DEV_IOC_V2 0xEC
-#define CROS_EC_DEV_IOCXCMD_V2 _IOWR(CROS_EC_DEV_IOC_V2, 0, \
- struct cros_ec_command_v2)
-#define CROS_EC_DEV_IOCRDMEM_V2 _IOWR(CROS_EC_DEV_IOC_V2, 1, \
- struct cros_ec_readmem_v2)
-#define CROS_EC_DEV_IOCEVENTMASK_V2 _IO(CROS_EC_DEV_IOC_V2, 2)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __UTIL_CROS_EC_DEV_H */
diff --git a/util/ec3po/__init__.py b/util/ec3po/__init__.py
deleted file mode 100644
index 9bebfa5842..0000000000
--- a/util/ec3po/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 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.
-
-"""The EC console interpreter.
-
-EC-3PO is a console interpreter which migrates the rich debug console from the
-EC itself to the host. This allows for a rich debug console without impacting
-EC image sizes while also allowing the development of new console features.
-
-The package consists of two modules: console and interpreter. The console
-module provides the interactive console interface between the user and the
-interpreter. It handles the presentation of the EC console including editing
-methods as well as session-persistent command history.
-
-The interpreter module provides the interpretation layer between the EC UART and
-the user. The user does not necessarily have to be the interactive console, but
-could be something like autotest. The interpreter is also responsible for the
-automatic command retrying if the EC drops a character in a command. This is a
-stopgap until all commands are communicated via host commands.
-"""
-
-import console
-import interpreter
-import threadproc_shim
diff --git a/util/ec3po/console.py b/util/ec3po/console.py
deleted file mode 100755
index 3643ea498a..0000000000
--- a/util/ec3po/console.py
+++ /dev/null
@@ -1,1125 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2015 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.
-
-"""EC-3PO Interactive Console Interface
-
-console provides the console interface between the user and the interpreter. It
-handles the presentation of the EC console including editing methods as well as
-session-persistent command history.
-"""
-
-from __future__ import print_function
-
-import argparse
-import binascii
-import copy
-import ctypes
-from datetime import datetime
-# pylint: disable=cros-logging-import
-import logging
-import os
-import pty
-import re
-import select
-import stat
-import sys
-import traceback
-
-import interpreter
-import threadproc_shim
-
-
-PROMPT = '> '
-CONSOLE_INPUT_LINE_SIZE = 80 # Taken from the CONFIG_* with the same name.
-CONSOLE_MAX_READ = 100 # Max bytes to read at a time from the user.
-LOOK_BUFFER_SIZE = 256 # Size of search window when looking for the enhanced EC
- # image string.
-
-# In console_init(), the EC will print a string saying that the EC console is
-# enabled. Enhanced images will print a slightly different string. These
-# regular expressions are used to determine at reboot whether the EC image is
-# enhanced or not.
-ENHANCED_IMAGE_RE = re.compile(r'Enhanced Console is enabled '
- r'\(v([0-9]+\.[0-9]+\.[0-9]+)\)')
-NON_ENHANCED_IMAGE_RE = re.compile(r'Console is enabled; ')
-
-# The timeouts are really only useful for enhanced EC images, but otherwise just
-# serve as a delay for non-enhanced EC images. Therefore, we can keep this
-# value small enough so that there's not too much of a delay, but long enough
-# that enhanced EC images can respond in time. Once we've detected an enhanced
-# EC image, we can increase the timeout for stability just in case it takes a
-# bit longer to receive an ACK for some reason.
-NON_ENHANCED_EC_INTERROGATION_TIMEOUT = 0.3 # Maximum number of seconds to wait
- # for a response to an
- # interrogation of a non-enhanced
- # EC image.
-ENHANCED_EC_INTERROGATION_TIMEOUT = 1.0 # Maximum number of seconds to wait for
- # a response to an interrogation of an
- # enhanced EC image.
-INTERROGATION_MODES = ['never', 'always', 'auto'] # List of modes which control
- # when interrogations are
- # performed with the EC.
-# Format for printing host timestamp
-HOST_STRFTIME="%Y-%m-%d %H:%M:%S "
-
-
-class EscState(object):
- """Class which contains an enumeration for states of ESC sequences."""
- ESC_START = 1
- ESC_BRACKET = 2
- ESC_BRACKET_1 = 3
- ESC_BRACKET_3 = 4
- ESC_BRACKET_8 = 5
-
-
-class ControlKey(object):
- """Class which contains codes for various control keys."""
- BACKSPACE = 0x08
- CTRL_A = 0x01
- CTRL_B = 0x02
- CTRL_D = 0x04
- CTRL_E = 0x05
- CTRL_F = 0x06
- CTRL_K = 0x0b
- CTRL_N = 0xe
- CTRL_P = 0x10
- CARRIAGE_RETURN = 0x0d
- ESC = 0x1b
-
-
-class Console(object):
- """Class which provides the console interface between the EC and the user.
-
- This class essentially represents the console interface between the user and
- the EC. It handles all of the console editing behaviour
-
- Attributes:
- logger: A logger for this module.
- master_pty: File descriptor to the master side of the PTY. Used for driving
- output to the user and receiving user input.
- user_pty: A string representing the PTY name of the served console.
- cmd_pipe: A socket.socket or multiprocessing.Connection object which
- represents the console side of the command pipe. This must be a
- bidirectional pipe. Console commands and responses utilize this pipe.
- dbg_pipe: A socket.socket or multiprocessing.Connection object which
- represents the console's read-only side of the debug pipe. This must be a
- unidirectional pipe attached to the intepreter. EC debug messages use
- this pipe.
- oobm_queue: A Queue.Queue or multiprocessing.Queue which is used for out of
- band management for the interactive console.
- input_buffer: A string representing the current input command.
- input_buffer_pos: An integer representing the current position in the buffer
- to insert a char.
- partial_cmd: A string representing the command entered on a line before
- pressing the up arrow keys.
- esc_state: An integer represeting the current state within an escape
- sequence.
- line_limit: An integer representing the maximum number of characters on a
- line.
- history: A list of strings containing the past entered console commands.
- history_pos: An integer representing the current history buffer position.
- This index is used to show previous commands.
- prompt: A string representing the console prompt displayed to the user.
- enhanced_ec: A boolean indicating if the EC image that we are currently
- communicating with is enhanced or not. Enhanced EC images will support
- packed commands and host commands over the UART. This defaults to False
- until we perform some handshaking.
- interrogation_timeout: A float representing the current maximum seconds to
- wait for a response to an interrogation.
- receiving_oobm_cmd: A boolean indicating whether or not the console is in
- the middle of receiving an out of band command.
- pending_oobm_cmd: A string containing the pending OOBM command.
- interrogation_mode: A string containing the current mode of whether
- interrogations are performed with the EC or not and how often.
- raw_debug: Flag to indicate whether per interrupt data should be logged to
- debug
- output_line_log_buffer: buffer for lines coming from the EC to log to debug
- """
-
- def __init__(self, master_pty, user_pty, interface_pty, cmd_pipe, dbg_pipe,
- name=None):
- """Initalises a Console object with the provided arguments.
-
- Args:
- master_pty: File descriptor to the master side of the PTY. Used for driving
- output to the user and receiving user input.
- user_pty: A string representing the PTY name of the served console.
- interface_pty: A string representing the PTY name of the served command
- interface.
- cmd_pipe: A socket.socket or multiprocessing.Connection object which
- represents the console side of the command pipe. This must be a
- bidirectional pipe. Console commands and responses utilize this pipe.
- dbg_pipe: A socket.socket or multiprocessing.Connection object which
- represents the console's read-only side of the debug pipe. This must be a
- unidirectional pipe attached to the intepreter. EC debug messages use
- this pipe.
- name: the console source name
- """
- # Create a unique logger based on the console name
- console_prefix = ('%s - ' % name) if name else ''
- logger = logging.getLogger('%sEC3PO.Console' % console_prefix)
- self.logger = interpreter.LoggerAdapter(logger, {'pty': user_pty})
- self.master_pty = master_pty
- self.user_pty = user_pty
- self.interface_pty = interface_pty
- self.cmd_pipe = cmd_pipe
- self.dbg_pipe = dbg_pipe
- self.oobm_queue = threadproc_shim.Queue()
- self.input_buffer = ''
- self.input_buffer_pos = 0
- self.partial_cmd = ''
- self.esc_state = 0
- self.line_limit = CONSOLE_INPUT_LINE_SIZE
- self.history = []
- self.history_pos = 0
- self.prompt = PROMPT
- self.enhanced_ec = False
- self.interrogation_timeout = NON_ENHANCED_EC_INTERROGATION_TIMEOUT
- self.receiving_oobm_cmd = False
- self.pending_oobm_cmd = ''
- self.interrogation_mode = 'auto'
- self.timestamp_enabled = True
- self.look_buffer = ''
- self.raw_debug = False
- self.output_line_log_buffer = ''
-
- def __str__(self):
- """Show internal state of Console object as a string."""
- string = []
- string.append('master_pty: %s' % self.master_pty)
- string.append('user_pty: %s' % self.user_pty)
- string.append('interface_pty: %s' % self.interface_pty)
- string.append('cmd_pipe: %s' % self.cmd_pipe)
- string.append('dbg_pipe: %s' % self.dbg_pipe)
- string.append('oobm_queue: %s' % self.oobm_queue)
- string.append('input_buffer: %s' % self.input_buffer)
- string.append('input_buffer_pos: %d' % self.input_buffer_pos)
- string.append('esc_state: %d' % self.esc_state)
- string.append('line_limit: %d' % self.line_limit)
- string.append('history: [\'' + '\', \''.join(self.history) + '\']')
- string.append('history_pos: %d' % self.history_pos)
- string.append('prompt: \'%s\'' % self.prompt)
- string.append('partial_cmd: \'%s\''% self.partial_cmd)
- string.append('interrogation_mode: \'%s\'' % self.interrogation_mode)
- string.append('look_buffer: \'%s\'' % self.look_buffer)
- return '\n'.join(string)
-
- def LogConsoleOutput(self, data):
- """Log to debug user MCU output to master_pty when line is filled.
-
- Args:
- data: string received from MCU
- """
- output_data = '%s%s' % (self.output_line_log_buffer, data)
- ends_in_nl = output_data[-1] == '\n'
- data_lines = output_data.splitlines()
- for line in data_lines[:-1]:
- self.logger.debug(line)
- if ends_in_nl:
- self.logger.debug(data_lines[-1])
- self.output_line_log_buffer = ''
- else:
- self.output_line_log_buffer = data_lines[-1]
-
- def PrintHistory(self):
- """Print the history of entered commands."""
- fd = self.master_pty
- # Make it pretty by figuring out how wide to pad the numbers.
- wide = (len(self.history) / 10) + 1
- for i in range(len(self.history)):
- line = ' %*d %s\r\n' % (wide, i, self.history[i])
- os.write(fd, line)
-
- def ShowPreviousCommand(self):
- """Shows the previous command from the history list."""
- # There's nothing to do if there's no history at all.
- if not self.history:
- self.logger.debug('No history to print.')
- return
-
- # Don't do anything if there's no more history to show.
- if self.history_pos == 0:
- self.logger.debug('No more history to show.')
- return
-
- self.logger.debug('current history position: %d.', self.history_pos)
-
- # Decrement the history buffer position.
- self.history_pos -= 1
- self.logger.debug('new history position.: %d', self.history_pos)
-
- # Save the text entered on the console if any.
- if self.history_pos == len(self.history)-1:
- self.logger.debug('saving partial_cmd: \'%s\'', self.input_buffer)
- self.partial_cmd = self.input_buffer
-
- # Backspace the line.
- for _ in range(self.input_buffer_pos):
- self.SendBackspace()
-
- # Print the last entry in the history buffer.
- self.logger.debug('printing previous entry %d - %s', self.history_pos,
- self.history[self.history_pos])
- fd = self.master_pty
- prev_cmd = self.history[self.history_pos]
- os.write(fd, prev_cmd)
- # Update the input buffer.
- self.input_buffer = prev_cmd
- self.input_buffer_pos = len(prev_cmd)
-
- def ShowNextCommand(self):
- """Shows the next command from the history list."""
- # Don't do anything if there's no history at all.
- if not self.history:
- self.logger.debug('History buffer is empty.')
- return
-
- fd = self.master_pty
-
- self.logger.debug('current history position: %d', self.history_pos)
- # Increment the history position.
- self.history_pos += 1
-
- # Restore the partial cmd.
- if self.history_pos == len(self.history):
- self.logger.debug('Restoring partial command of \'%s\'', self.partial_cmd)
- # Backspace the line.
- for _ in range(self.input_buffer_pos):
- self.SendBackspace()
- # Print the partially entered command if any.
- os.write(fd, self.partial_cmd)
- self.input_buffer = self.partial_cmd
- self.input_buffer_pos = len(self.input_buffer)
- # Now that we've printed it, clear the partial cmd storage.
- self.partial_cmd = ''
- # Reset history position.
- self.history_pos = len(self.history)
- return
-
- self.logger.debug('new history position: %d', self.history_pos)
- if self.history_pos > len(self.history)-1:
- self.logger.debug('No more history to show.')
- self.history_pos -= 1
- self.logger.debug('Reset history position to %d', self.history_pos)
- return
-
- # Backspace the line.
- for _ in range(self.input_buffer_pos):
- self.SendBackspace()
-
- # Print the newer entry from the history buffer.
- self.logger.debug('printing next entry %d - %s', self.history_pos,
- self.history[self.history_pos])
- next_cmd = self.history[self.history_pos]
- os.write(fd, next_cmd)
- # Update the input buffer.
- self.input_buffer = next_cmd
- self.input_buffer_pos = len(next_cmd)
- self.logger.debug('new history position: %d.', self.history_pos)
-
- def SliceOutChar(self):
- """Remove a char from the line and shift everything over 1 column."""
- fd = self.master_pty
- # Remove the character at the input_buffer_pos by slicing it out.
- self.input_buffer = self.input_buffer[0:self.input_buffer_pos] + \
- self.input_buffer[self.input_buffer_pos+1:]
- # Write the rest of the line
- moved_col = os.write(fd, self.input_buffer[self.input_buffer_pos:])
- # Write a space to clear out the last char
- moved_col += os.write(fd, ' ')
- # Update the input buffer position.
- self.input_buffer_pos += moved_col
- # Reset the cursor
- self.MoveCursor('left', moved_col)
-
- def HandleEsc(self, byte):
- """HandleEsc processes escape sequences.
-
- Args:
- byte: An integer representing the current byte in the sequence.
- """
- # We shouldn't be handling an escape sequence if we haven't seen one.
- assert self.esc_state != 0
-
- if self.esc_state is EscState.ESC_START:
- self.logger.debug('ESC_START')
- if byte == ord('['):
- self.esc_state = EscState.ESC_BRACKET
- return
-
- else:
- self.logger.error('Unexpected sequence. %c', byte)
- self.esc_state = 0
-
- elif self.esc_state is EscState.ESC_BRACKET:
- self.logger.debug('ESC_BRACKET')
- # Left Arrow key was pressed.
- if byte == ord('D'):
- self.logger.debug('Left arrow key pressed.')
- self.MoveCursor('left', 1)
- self.esc_state = 0 # Reset the state.
- return
-
- # Right Arrow key.
- elif byte == ord('C'):
- self.logger.debug('Right arrow key pressed.')
- self.MoveCursor('right', 1)
- self.esc_state = 0 # Reset the state.
- return
-
- # Up Arrow key.
- elif byte == ord('A'):
- self.logger.debug('Up arrow key pressed.')
- self.ShowPreviousCommand()
- # Reset the state.
- self.esc_state = 0 # Reset the state.
- return
-
- # Down Arrow key.
- elif byte == ord('B'):
- self.logger.debug('Down arrow key pressed.')
- self.ShowNextCommand()
- # Reset the state.
- self.esc_state = 0 # Reset the state.
- return
-
- # For some reason, minicom sends a 1 instead of 7. /shrug
- # TODO(aaboagye): Figure out why this happens.
- elif byte == ord('1') or byte == ord('7'):
- self.esc_state = EscState.ESC_BRACKET_1
-
- elif byte == ord('3'):
- self.esc_state = EscState.ESC_BRACKET_3
-
- elif byte == ord('8'):
- self.esc_state = EscState.ESC_BRACKET_8
-
- else:
- self.logger.error(r'Bad or unhandled escape sequence. got ^[%c\(%d)',
- chr(byte), byte)
- self.esc_state = 0
- return
-
- elif self.esc_state is EscState.ESC_BRACKET_1:
- self.logger.debug('ESC_BRACKET_1')
- # HOME key.
- if byte == ord('~'):
- self.logger.debug('Home key pressed.')
- self.MoveCursor('left', self.input_buffer_pos)
- self.esc_state = 0 # Reset the state.
- self.logger.debug('ESC sequence complete.')
- return
-
- elif self.esc_state is EscState.ESC_BRACKET_3:
- self.logger.debug('ESC_BRACKET_3')
- # DEL key.
- if byte == ord('~'):
- self.logger.debug('Delete key pressed.')
- if self.input_buffer_pos != len(self.input_buffer):
- self.SliceOutChar()
- self.esc_state = 0 # Reset the state.
-
- elif self.esc_state is EscState.ESC_BRACKET_8:
- self.logger.debug('ESC_BRACKET_8')
- # END key.
- if byte == ord('~'):
- self.logger.debug('End key pressed.')
- self.MoveCursor('right',
- len(self.input_buffer) - self.input_buffer_pos)
- self.esc_state = 0 # Reset the state.
- self.logger.debug('ESC sequence complete.')
- return
-
- else:
- self.logger.error('Unexpected sequence. %c', byte)
- self.esc_state = 0
-
- else:
- self.logger.error('Unexpected sequence. %c', byte)
- self.esc_state = 0
-
- def ProcessInput(self):
- """Captures the input determines what actions to take."""
- # There's nothing to do if the input buffer is empty.
- if len(self.input_buffer) == 0:
- return
-
- # Don't store 2 consecutive identical commands in the history.
- if (self.history and self.history[-1] != self.input_buffer
- or not self.history):
- self.history.append(self.input_buffer)
-
- # Split the command up by spaces.
- line = self.input_buffer.split(' ')
- self.logger.debug('cmd: %s', self.input_buffer)
- cmd = line[0].lower()
-
- # The 'history' command is a special case that we handle locally.
- if cmd == 'history':
- self.PrintHistory()
- return
-
- # Send the command to the interpreter.
- self.logger.debug('Sending command to interpreter.')
- self.cmd_pipe.send(self.input_buffer)
-
- def CheckForEnhancedECImage(self):
- """Performs an interrogation of the EC image.
-
- Send a SYN and expect an ACK. If no ACK or the response is incorrect, then
- assume that the current EC image that we are talking to is not enhanced.
-
- Returns:
- is_enhanced: A boolean indicating whether the EC responded to the
- interrogation correctly.
-
- Raises:
- EOFError: Allowed to propagate through from self.dbg_pipe.recv().
- """
- # Send interrogation byte and wait for the response.
- self.logger.debug('Performing interrogation.')
- self.cmd_pipe.send(interpreter.EC_SYN)
-
- response = ''
- if self.dbg_pipe.poll(self.interrogation_timeout):
- response = self.dbg_pipe.recv()
- self.logger.debug('response: \'%s\'', binascii.hexlify(response))
- else:
- self.logger.debug('Timed out waiting for EC_ACK')
-
- # Verify the acknowledgment.
- is_enhanced = response == interpreter.EC_ACK
-
- if is_enhanced:
- # Increase the interrogation timeout for stability purposes.
- self.interrogation_timeout = ENHANCED_EC_INTERROGATION_TIMEOUT
- self.logger.debug('Increasing interrogation timeout to %rs.',
- self.interrogation_timeout)
- else:
- # Reduce the timeout in order to reduce the perceivable delay.
- self.interrogation_timeout = NON_ENHANCED_EC_INTERROGATION_TIMEOUT
- self.logger.debug('Reducing interrogation timeout to %rs.',
- self.interrogation_timeout)
-
- return is_enhanced
-
- def HandleChar(self, byte):
- """HandleChar does a certain action when it receives a character.
-
- Args:
- byte: An integer representing the character received from the user.
-
- Raises:
- EOFError: Allowed to propagate through from self.CheckForEnhancedECImage()
- i.e. from self.dbg_pipe.recv().
- """
- fd = self.master_pty
-
- # Enter the OOBM prompt mode if the user presses '%'.
- if byte == ord('%'):
- self.logger.debug('Begin OOBM command.')
- self.receiving_oobm_cmd = True
- # Print a "prompt".
- os.write(self.master_pty, '\r\n% ')
- return
-
- # Add chars to the pending OOBM command if we're currently receiving one.
- if self.receiving_oobm_cmd and byte != ControlKey.CARRIAGE_RETURN:
- self.pending_oobm_cmd += chr(byte)
- self.logger.debug('%s', chr(byte))
- os.write(self.master_pty, chr(byte))
- return
-
- if byte == ControlKey.CARRIAGE_RETURN:
- if self.receiving_oobm_cmd:
- # Terminate the command and place it in the OOBM queue.
- self.logger.debug('End OOBM command.')
- if self.pending_oobm_cmd:
- self.oobm_queue.put(self.pending_oobm_cmd)
- self.logger.debug('Placed \'%s\' into OOBM command queue.',
- self.pending_oobm_cmd)
-
- # Reset the state.
- os.write(self.master_pty, '\r\n' + self.prompt)
- self.input_buffer = ''
- self.input_buffer_pos = 0
- self.receiving_oobm_cmd = False
- self.pending_oobm_cmd = ''
- return
-
- if self.interrogation_mode == 'never':
- self.logger.debug('Skipping interrogation because interrogation mode'
- ' is set to never.')
- elif self.interrogation_mode == 'always':
- # Only interrogate the EC if the interrogation mode is set to 'always'.
- self.enhanced_ec = self.CheckForEnhancedECImage()
- self.logger.debug('Enhanced EC image? %r', self.enhanced_ec)
-
- if not self.enhanced_ec:
- # Send everything straight to the EC to handle.
- self.cmd_pipe.send(chr(byte))
- # Reset the input buffer.
- self.input_buffer = ''
- self.input_buffer_pos = 0
- self.logger.log(1, 'Reset input buffer.')
- return
-
- # Keep handling the ESC sequence if we're in the middle of it.
- if self.esc_state != 0:
- self.HandleEsc(byte)
- return
-
- # When we're at the end of the line, we should only allow going backwards,
- # backspace, carriage return, up, or down. The arrow keys are escape
- # sequences, so we let the escape...escape.
- if (self.input_buffer_pos >= self.line_limit and
- byte not in [ControlKey.CTRL_B, ControlKey.ESC, ControlKey.BACKSPACE,
- ControlKey.CTRL_A, ControlKey.CARRIAGE_RETURN,
- ControlKey.CTRL_P, ControlKey.CTRL_N]):
- return
-
- # If the input buffer is full we can't accept new chars.
- buffer_full = len(self.input_buffer) >= self.line_limit
-
-
- # Carriage_Return/Enter
- if byte == ControlKey.CARRIAGE_RETURN:
- self.logger.debug('Enter key pressed.')
- # Put a carriage return/newline and the print the prompt.
- os.write(fd, '\r\n')
-
- # TODO(aaboagye): When we control the printing of all output, print the
- # prompt AFTER printing all the output. We can't do it yet because we
- # don't know how much is coming from the EC.
-
- # Print the prompt.
- os.write(fd, self.prompt)
- # Process the input.
- self.ProcessInput()
- # Now, clear the buffer.
- self.input_buffer = ''
- self.input_buffer_pos = 0
- # Reset history buffer pos.
- self.history_pos = len(self.history)
- # Clear partial command.
- self.partial_cmd = ''
-
- # Backspace
- elif byte == ControlKey.BACKSPACE:
- self.logger.debug('Backspace pressed.')
- if self.input_buffer_pos > 0:
- # Move left 1 column.
- self.MoveCursor('left', 1)
- # Remove the character at the input_buffer_pos by slicing it out.
- self.SliceOutChar()
-
- self.logger.debug('input_buffer_pos: %d', self.input_buffer_pos)
-
- # Ctrl+A. Move cursor to beginning of the line
- elif byte == ControlKey.CTRL_A:
- self.logger.debug('Control+A pressed.')
- self.MoveCursor('left', self.input_buffer_pos)
-
- # Ctrl+B. Move cursor left 1 column.
- elif byte == ControlKey.CTRL_B:
- self.logger.debug('Control+B pressed.')
- self.MoveCursor('left', 1)
-
- # Ctrl+D. Delete a character.
- elif byte == ControlKey.CTRL_D:
- self.logger.debug('Control+D pressed.')
- if self.input_buffer_pos != len(self.input_buffer):
- # Remove the character by slicing it out.
- self.SliceOutChar()
-
- # Ctrl+E. Move cursor to end of the line.
- elif byte == ControlKey.CTRL_E:
- self.logger.debug('Control+E pressed.')
- self.MoveCursor('right',
- len(self.input_buffer) - self.input_buffer_pos)
-
- # Ctrl+F. Move cursor right 1 column.
- elif byte == ControlKey.CTRL_F:
- self.logger.debug('Control+F pressed.')
- self.MoveCursor('right', 1)
-
- # Ctrl+K. Kill line.
- elif byte == ControlKey.CTRL_K:
- self.logger.debug('Control+K pressed.')
- self.KillLine()
-
- # Ctrl+N. Next line.
- elif byte == ControlKey.CTRL_N:
- self.logger.debug('Control+N pressed.')
- self.ShowNextCommand()
-
- # Ctrl+P. Previous line.
- elif byte == ControlKey.CTRL_P:
- self.logger.debug('Control+P pressed.')
- self.ShowPreviousCommand()
-
- # ESC sequence
- elif byte == ControlKey.ESC:
- # Starting an ESC sequence
- self.esc_state = EscState.ESC_START
-
- # Only print printable chars.
- elif IsPrintable(byte):
- # Drop the character if we're full.
- if buffer_full:
- self.logger.debug('Dropped char: %c(%d)', byte, byte)
- return
- # Print the character.
- os.write(fd, chr(byte))
- # Print the rest of the line (if any).
- extra_bytes_written = os.write(fd,
- self.input_buffer[self.input_buffer_pos:])
-
- # Recreate the input buffer.
- self.input_buffer = (self.input_buffer[0:self.input_buffer_pos] +
- ('%c' % byte) +
- self.input_buffer[self.input_buffer_pos:])
- # Update the input buffer position.
- self.input_buffer_pos += 1 + extra_bytes_written
-
- # Reset the cursor if we wrote any extra bytes.
- if extra_bytes_written:
- self.MoveCursor('left', extra_bytes_written)
-
- self.logger.debug('input_buffer_pos: %d', self.input_buffer_pos)
-
- def MoveCursor(self, direction, count):
- """MoveCursor moves the cursor left or right by count columns.
-
- Args:
- direction: A string that should be either 'left' or 'right' representing
- the direction to move the cursor on the console.
- count: An integer representing how many columns the cursor should be
- moved.
-
- Raises:
- AssertionError: If the direction is not equal to 'left' or 'right'.
- """
- # If there's nothing to move, we're done.
- if not count:
- return
- fd = self.master_pty
- seq = '\033[' + str(count)
- if direction == 'left':
- # Bind the movement.
- if count > self.input_buffer_pos:
- count = self.input_buffer_pos
- seq += 'D'
- self.logger.debug('move cursor left %d', count)
- self.input_buffer_pos -= count
-
- elif direction == 'right':
- # Bind the movement.
- if (count + self.input_buffer_pos) > len(self.input_buffer):
- count = 0
- seq += 'C'
- self.logger.debug('move cursor right %d', count)
- self.input_buffer_pos += count
-
- else:
- raise AssertionError(('The only valid directions are \'left\' and '
- '\'right\''))
-
- self.logger.debug('input_buffer_pos: %d', self.input_buffer_pos)
- # Move the cursor.
- if count != 0:
- os.write(fd, seq)
-
- def KillLine(self):
- """Kill the rest of the line based on the input buffer position."""
- # Killing the line is killing all the text to the right.
- diff = len(self.input_buffer) - self.input_buffer_pos
- self.logger.debug('diff: %d', diff)
- # Diff shouldn't be negative, but if it is for some reason, let's try to
- # correct the cursor.
- if diff < 0:
- self.logger.warning('Resetting input buffer position to %d...',
- len(self.input_buffer))
- self.MoveCursor('left', -diff)
- return
- if diff:
- self.MoveCursor('right', diff)
- for _ in range(diff):
- self.SendBackspace()
- self.input_buffer_pos -= diff
- self.input_buffer = self.input_buffer[0:self.input_buffer_pos]
-
- def SendBackspace(self):
- """Backspace a character on the console."""
- os.write(self.master_pty, '\033[1D \033[1D')
-
- def ProcessOOBMQueue(self):
- """Retrieve an item from the OOBM queue and process it."""
- item = self.oobm_queue.get()
- self.logger.debug('OOBM cmd: %s', item)
- cmd = item.split(' ')
-
- if cmd[0] == 'loglevel':
- # An integer is required in order to set the log level.
- if len(cmd) < 2:
- self.logger.debug('Insufficient args')
- self.PrintOOBMHelp()
- return
- try:
- self.logger.debug('Log level change request.')
- new_log_level = int(cmd[1])
- self.logger.logger.setLevel(new_log_level)
- self.logger.info('Log level changed to %d.', new_log_level)
-
- # Forward the request to the interpreter as well.
- self.cmd_pipe.send(item)
- except ValueError:
- # Ignoring the request if an integer was not provided.
- self.PrintOOBMHelp()
-
- elif cmd[0] == 'timestamp':
- mode = cmd[1].lower()
- self.timestamp_enabled = mode == 'on'
- self.logger.info('%sabling uart timestamps.',
- 'En' if self.timestamp_enabled else 'Dis')
-
- elif cmd[0] == 'rawdebug':
- mode = cmd[1].lower()
- self.raw_debug = mode == 'on'
- self.logger.info('%sabling per interrupt debug logs.',
- 'En' if self.raw_debug else 'Dis')
-
- elif cmd[0] == 'interrogate' and len(cmd) >= 2:
- enhanced = False
- mode = cmd[1]
- if len(cmd) >= 3 and cmd[2] == 'enhanced':
- enhanced = True
-
- # Set the mode if correct.
- if mode in INTERROGATION_MODES:
- self.interrogation_mode = mode
- self.logger.debug('Updated interrogation mode to %s.', mode)
-
- # Update the assumptions of the EC image.
- self.enhanced_ec = enhanced
- self.logger.debug('Enhanced EC image is now %r', self.enhanced_ec)
-
- # Send command to interpreter as well.
- self.cmd_pipe.send('enhanced ' + str(self.enhanced_ec))
- else:
- self.PrintOOBMHelp()
-
- else:
- self.PrintOOBMHelp()
-
- def PrintOOBMHelp(self):
- """Prints out the OOBM help."""
- # Print help syntax.
- os.write(self.master_pty, '\r\n' + 'Known OOBM commands:\r\n')
- os.write(self.master_pty, ' interrogate <never | always | auto> '
- '[enhanced]\r\n')
- os.write(self.master_pty, ' loglevel <int>\r\n')
-
- def CheckBufferForEnhancedImage(self, data):
- """Adds data to a look buffer and checks to see for enhanced EC image.
-
- The EC's console task prints a string upon initialization which says that
- "Console is enabled; type HELP for help.". The enhanced EC images print a
- different string as a part of their init. This function searches through a
- "look" buffer, scanning for the presence of either of those strings and
- updating the enhanced_ec state accordingly.
-
- Args:
- data: A string containing the data sent from the interpreter.
- """
- self.look_buffer += data
-
- # Search the buffer for any of the EC image strings.
- enhanced_match = re.search(ENHANCED_IMAGE_RE, self.look_buffer)
- non_enhanced_match = re.search(NON_ENHANCED_IMAGE_RE, self.look_buffer)
-
- # Update the state if any matches were found.
- if enhanced_match or non_enhanced_match:
- if enhanced_match:
- self.enhanced_ec = True
- elif non_enhanced_match:
- self.enhanced_ec = False
-
- # Inform the interpreter of the result.
- self.cmd_pipe.send('enhanced ' + str(self.enhanced_ec))
- self.logger.debug('Enhanced EC image? %r', self.enhanced_ec)
-
- # Clear look buffer since a match was found.
- self.look_buffer = ''
-
- # Move the sliding window.
- self.look_buffer = self.look_buffer[-LOOK_BUFFER_SIZE:]
-
-
-def IsPrintable(byte):
- """Determines if a byte is printable.
-
- Args:
- byte: An integer potentially representing a printable character.
-
- Returns:
- A boolean indicating whether the byte is a printable character.
- """
- return byte >= ord(' ') and byte <= ord('~')
-
-def StartLoop(console, command_active, shutdown_pipe=None):
- """Starts the infinite loop of console processing.
-
- Args:
- console: A Console object that has been properly initialzed.
- command_active: ctypes data object or multiprocessing.Value indicating if
- servod owns the console, or user owns the console. This prevents input
- collisions.
- shutdown_pipe: A file object for a pipe or equivalent that becomes readable
- (not blocked) to indicate that the loop should exit. Can be None to never
- exit the loop.
- """
- try:
- console.logger.debug('Console is being served on %s.', console.user_pty)
- console.logger.debug('Console master is on %s.', console.master_pty)
- console.logger.debug('Command interface is being served on %s.',
- console.interface_pty)
- console.logger.debug(console)
-
- # This checks for HUP to indicate if the user has connected to the pty.
- ep = select.epoll()
- ep.register(console.master_pty, select.EPOLLHUP)
-
- # This is used instead of "break" to avoid exiting the loop in the middle of
- # an iteration.
- continue_looping = True
-
- # Used for determining when to print host timestamps
- tm_req = True
-
- while continue_looping:
- # Check to see if pts is connected to anything
- events = ep.poll(0)
- master_connected = not events
-
- # Check to see if pipes or the console are ready for reading.
- read_list = [console.interface_pty,
- console.cmd_pipe, console.dbg_pipe]
- if master_connected:
- read_list.append(console.master_pty)
- if shutdown_pipe is not None:
- read_list.append(shutdown_pipe)
-
- # Check if any input is ready, or wait for .1 sec and re-poll if
- # a user has connected to the pts.
- select_output = select.select(read_list, [], [], .1)
- if not select_output:
- continue
- ready_for_reading = select_output[0]
-
- for obj in ready_for_reading:
- if obj is console.master_pty:
- if not command_active.value:
- # Convert to bytes so we can look for non-printable chars such as
- # Ctrl+A, Ctrl+E, etc.
- try:
- line = bytearray(os.read(console.master_pty, CONSOLE_MAX_READ))
- console.logger.debug('Input from user: %s, locked:%s',
- str(line).strip(), command_active.value)
- for i in line:
- try:
- # Handle each character as it arrives.
- console.HandleChar(i)
- except EOFError:
- console.logger.debug(
- 'ec3po console received EOF from dbg_pipe in HandleChar()'
- ' while reading console.master_pty')
- continue_looping = False
- break
- except OSError:
- console.logger.debug('Ptm read failed, probably user disconnect.')
-
- elif obj is console.interface_pty:
- if command_active.value:
- # Convert to bytes so we can look for non-printable chars such as
- # Ctrl+A, Ctrl+E, etc.
- line = bytearray(os.read(console.interface_pty, CONSOLE_MAX_READ))
- console.logger.debug('Input from interface: %s, locked:%s',
- str(line).strip(), command_active.value)
- for i in line:
- try:
- # Handle each character as it arrives.
- console.HandleChar(i)
- except EOFError:
- console.logger.debug(
- 'ec3po console received EOF from dbg_pipe in HandleChar()'
- ' while reading console.interface_pty')
- continue_looping = False
- break
-
- elif obj is console.cmd_pipe:
- try:
- data = console.cmd_pipe.recv()
- except EOFError:
- console.logger.debug('ec3po console received EOF from cmd_pipe')
- continue_looping = False
- else:
- # Write it to the user console.
- if console.raw_debug:
- console.logger.debug('|CMD|-%s->\'%s\'',
- ('u' if master_connected else '') +
- ('i' if command_active.value else ''),
- data.strip())
- if master_connected:
- os.write(console.master_pty, data)
- if command_active.value:
- os.write(console.interface_pty, data)
-
- elif obj is console.dbg_pipe:
- try:
- data = console.dbg_pipe.recv()
- except EOFError:
- console.logger.debug('ec3po console received EOF from dbg_pipe')
- continue_looping = False
- else:
- if console.interrogation_mode == 'auto':
- # Search look buffer for enhanced EC image string.
- console.CheckBufferForEnhancedImage(data)
- # Write it to the user console.
- if len(data) > 1 and console.raw_debug:
- console.logger.debug('|DBG|-%s->\'%s\'',
- ('u' if master_connected else '') +
- ('i' if command_active.value else ''),
- data.strip())
- console.LogConsoleOutput(data)
- if master_connected:
- end = len(data) - 1
- if console.timestamp_enabled:
- # A timestamp is required at the beginning of this line
- if tm_req is True:
- now = datetime.now()
- tm = now.strftime(HOST_STRFTIME)
- os.write(console.master_pty, tm)
- tm_req = False
-
- # Insert timestamps into the middle where appropriate
- # except if the last character is a newline
- nls_found = data.count('\n', 0, end)
- now = datetime.now()
- tm = now.strftime('\n' + HOST_STRFTIME)
- data_tm = data.replace('\n', tm, nls_found)
- else:
- data_tm = data
-
- # timestamp required on next input
- if data[end] == '\n':
- tm_req = True
- os.write(console.master_pty, data_tm)
- if command_active.value:
- os.write(console.interface_pty, data)
-
- elif obj is shutdown_pipe:
- console.logger.debug(
- 'ec3po console received shutdown pipe unblocked notification')
- continue_looping = False
-
- while not console.oobm_queue.empty():
- console.logger.debug('OOBM queue ready for reading.')
- console.ProcessOOBMQueue()
-
- except KeyboardInterrupt:
- pass
-
- # TODO(crbug.com/894870): Stop suppressing all exceptions.
- except:
- traceback.print_exc()
-
- finally:
- ep.unregister(console.master_pty)
- console.dbg_pipe.close()
- console.cmd_pipe.close()
- os.close(console.master_pty)
- os.close(console.interface_pty)
- if shutdown_pipe is not None:
- shutdown_pipe.close()
- console.logger.debug('Exit ec3po console loop for %s', console.user_pty)
-
-
-def main(argv):
- """Kicks off the EC-3PO interactive console interface and interpreter.
-
- We create some pipes to communicate with an interpreter, instantiate an
- interpreter, create a PTY pair, and begin serving the console interface.
-
- Args:
- argv: A list of strings containing the arguments this module was called
- with.
- """
- # Set up argument parser.
- parser = argparse.ArgumentParser(description=('Start interactive EC console '
- 'and interpreter.'))
- parser.add_argument('ec_uart_pty',
- help=('The full PTY name that the EC UART'
- ' is present on. eg: /dev/pts/12'))
- parser.add_argument('--log-level',
- default='info',
- help='info, debug, warning, error, or critical')
-
- # Parse arguments.
- opts = parser.parse_args(argv)
-
- # Set logging level.
- opts.log_level = opts.log_level.lower()
- if opts.log_level == 'info':
- log_level = logging.INFO
- elif opts.log_level == 'debug':
- log_level = logging.DEBUG
- elif opts.log_level == 'warning':
- log_level = logging.WARNING
- elif opts.log_level == 'error':
- log_level = logging.ERROR
- elif opts.log_level == 'critical':
- log_level = logging.CRITICAL
- else:
- parser.error('Invalid log level. (info, debug, warning, error, critical)')
-
- # Start logging with a timestamp, module, and log level shown in each log
- # entry.
- logging.basicConfig(level=log_level, format=('%(asctime)s - %(module)s -'
- ' %(levelname)s - %(message)s'))
-
- # Create some pipes to communicate between the interpreter and the console.
- # The command pipe is bidirectional.
- cmd_pipe_interactive, cmd_pipe_interp = threadproc_shim.Pipe()
- # The debug pipe is unidirectional from interpreter to console only.
- dbg_pipe_interactive, dbg_pipe_interp = threadproc_shim.Pipe(duplex=False)
-
- # Create an interpreter instance.
- itpr = interpreter.Interpreter(opts.ec_uart_pty, cmd_pipe_interp,
- dbg_pipe_interp, log_level)
-
- # Spawn an interpreter process.
- itpr_process = threadproc_shim.ThreadOrProcess(
- target=interpreter.StartLoop, args=(itpr,))
- # Make sure to kill the interpreter when we terminate.
- itpr_process.daemon = True
- # Start the interpreter.
- itpr_process.start()
-
- # Open a new pseudo-terminal pair
- (master_pty, user_pty) = pty.openpty()
- # Set the permissions to 660.
- os.chmod(os.ttyname(user_pty), (stat.S_IRGRP | stat.S_IWGRP |
- stat.S_IRUSR | stat.S_IWUSR))
- # Create a console.
- console = Console(master_pty, os.ttyname(user_pty), cmd_pipe_interactive,
- dbg_pipe_interactive)
- # Start serving the console.
- v = threadproc_shim.Value(ctypes.c_bool, False)
- StartLoop(console, v)
-
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/util/ec3po/console_unittest.py b/util/ec3po/console_unittest.py
deleted file mode 100755
index 3c194d8419..0000000000
--- a/util/ec3po/console_unittest.py
+++ /dev/null
@@ -1,1626 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2015 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.
-
-"""Unit tests for the EC-3PO Console interface."""
-
-from __future__ import print_function
-
-import binascii
-# pylint: disable=cros-logging-import
-import logging
-import mock
-import tempfile
-import unittest
-
-import console
-import interpreter
-import threadproc_shim
-
-ESC_STRING = chr(console.ControlKey.ESC)
-
-class Keys(object):
- """A class that contains the escape sequences for special keys."""
- LEFT_ARROW = [console.ControlKey.ESC, ord('['), ord('D')]
- RIGHT_ARROW = [console.ControlKey.ESC, ord('['), ord('C')]
- UP_ARROW = [console.ControlKey.ESC, ord('['), ord('A')]
- DOWN_ARROW = [console.ControlKey.ESC, ord('['), ord('B')]
- HOME = [console.ControlKey.ESC, ord('['), ord('1'), ord('~')]
- END = [console.ControlKey.ESC, ord('['), ord('8'), ord('~')]
- DEL = [console.ControlKey.ESC, ord('['), ord('3'), ord('~')]
-
-class OutputStream(object):
- """A class that has methods which return common console output."""
-
- @staticmethod
- def MoveCursorLeft(count):
- """Produces what would be printed to the console if the cursor moved left.
-
- Args:
- count: An integer representing how many columns to move left.
-
- Returns:
- string: A string which contains what would be printed to the console if
- the cursor moved left.
- """
- string = ESC_STRING
- string += '[' + str(count) + 'D'
- return string
-
- @staticmethod
- def MoveCursorRight(count):
- """Produces what would be printed to the console if the cursor moved right.
-
- Args:
- count: An integer representing how many columns to move right.
-
- Returns:
- string: A string which contains what would be printed to the console if
- the cursor moved right.
- """
- string = ESC_STRING
- string += '[' + str(count) + 'C'
- return string
-
-BACKSPACE_STRING = ''
-# Move cursor left 1 column.
-BACKSPACE_STRING += OutputStream.MoveCursorLeft(1)
-# Write a space.
-BACKSPACE_STRING += ' '
-# Move cursor left 1 column.
-BACKSPACE_STRING += OutputStream.MoveCursorLeft(1)
-
-def StringToByteList(string):
- """Converts a string to list of bytes.
-
- Args:
- string: A literal string to turn into a list of bytes.
-
- Returns:
- A list of integers representing the byte value of each character in the
- string.
- """
- return [ord(c) for c in string]
-
-def BadConsoleOutput(expected, got):
- """Format the console output into readable text.
-
- Args:
- expected: A list of bytes representing the expected output console
- stream.
- got: A list of byte representing the actual output console stream.
-
- Returns:
- string: A formatted string which shows the expected console output stream
- and the actual console output stream.
- """
- esc_state = 0
- string = 'Incorrect console output stream.\n'
- string += 'exp: |'
- count = 0
- for char in expected:
- if esc_state != 0:
- if esc_state == console.EscState.ESC_START:
- if char == '[':
- esc_state = console.EscState.ESC_BRACKET
- elif esc_state == console.EscState.ESC_BRACKET:
- if char == 'D':
- string += '[cursor left ' + str(count) + ' cols]'
- esc_state = 0
- elif char == 'C':
- string += '[cursor right ' + str(count) + ' cols]'
- esc_state = 0
- else:
- count = int(char)
- # Print if it's printable.
- elif console.IsPrintable(ord(char)):
- string += char
- else:
- # It might be a sequence of some type.
- if ord(char) == console.ControlKey.ESC:
- # Need to look at the following sequence.
- esc_state = console.EscState.ESC_START
- else:
- string += '{' + binascii.hexlify(char) + '}'
-
- string += '|\n\ngot: |'
- for char in got:
- if esc_state != 0:
- if esc_state == console.EscState.ESC_START:
- if char == '[':
- esc_state = console.EscState.ESC_BRACKET
- elif esc_state == console.EscState.ESC_BRACKET:
- if char == 'D':
- string += '[cursor left ' + str(count) + ' cols]'
- esc_state = 0
- elif char == 'C':
- string += '[cursor right ' + str(count) + ' cols]'
- esc_state = 0
- else:
- count = int(char)
- # Print if it's printable.
- elif console.IsPrintable(ord(char)):
- string += char
- else:
- # It might be a sequence of some type.
- if ord(char) == console.ControlKey.ESC:
- # Need to look at the following sequence.
- esc_state = console.EscState.ESC_START
- else:
- string += '{' + binascii.hexlify(char) + '}'
- string += '|\n\n'
-
- # TODO(aaboagye): It would be nice to replace all those move left 1, ' ',
- # move left 1, with backspace.
-
- return string
-
-def CheckConsoleOutput(test_case, exp_console_out):
- """Verify what was sent out the console matches what we expect.
-
- Args:
- test_case: A unittest.TestCase object representing the current unit test.
- exp_console_out: A string representing the console output stream.
- """
- # Read what was sent out the console.
- test_case.tempfile.seek(0)
- console_out = test_case.tempfile.read()
-
- test_case.assertEqual(exp_console_out,
- console_out,
- (BadConsoleOutput(exp_console_out, console_out)
- + str(test_case.console)))
-
-def CheckInputBuffer(test_case, exp_input_buffer):
- """Verify that the input buffer contains what we expect.
-
- Args:
- test_case: A unittest.TestCase object representing the current unit test.
- exp_input_buffer: A string containing the contents of the current input
- buffer.
- """
- test_case.assertEqual(exp_input_buffer, test_case.console.input_buffer,
- ('input buffer does not match expected.\n'
- 'expected: |' + exp_input_buffer + '|\n'
- 'got: |' + test_case.console.input_buffer +
- '|\n' + str(test_case.console)))
-
-def CheckInputBufferPosition(test_case, exp_pos):
- """Verify the input buffer position.
-
- Args:
- test_case: A unittest.TestCase object representing the current unit test.
- exp_pos: An integer representing the expected input buffer position.
- """
- test_case.assertEqual(exp_pos, test_case.console.input_buffer_pos,
- 'input buffer position is incorrect.\ngot: ' +
- str(test_case.console.input_buffer_pos) + '\nexp: ' +
- str(exp_pos) + '\n' + str(test_case.console))
-
-def CheckHistoryBuffer(test_case, exp_history):
- """Verify that the items in the history buffer are what we expect.
-
- Args:
- test_case: A unittest.TestCase object representing the current unit test.
- exp_history: A list of strings representing the expected contents of the
- history buffer.
- """
- # First, check to see if the length is what we expect.
- test_case.assertEqual(len(exp_history), len(test_case.console.history),
- ('The number of items in the history is unexpected.\n'
- 'exp: ' + str(len(exp_history)) + '\n'
- 'got: ' + str(len(test_case.console.history)) + '\n'
- 'internal state:\n' + str(test_case.console)))
-
- # Next, check the actual contents of the history buffer.
- for i in range(len(exp_history)):
- test_case.assertEqual(exp_history[i], test_case.console.history[i],
- ('history buffer contents are incorrect.\n'
- 'exp: ' + exp_history[i] + '\n'
- 'got: ' + test_case.console.history[i] + '\n'
- 'internal state:\n' + str(test_case.console)))
-
-
-class TestConsoleEditingMethods(unittest.TestCase):
- """Test case to verify all console editing methods."""
-
- def setUp(self):
- """Setup the test harness."""
- # Setup logging with a timestamp, the module, and the log level.
- logging.basicConfig(level=logging.DEBUG,
- format=('%(asctime)s - %(module)s -'
- ' %(levelname)s - %(message)s'))
-
- # Create a temp file and set both the master and slave PTYs to the file to
- # create a loopback.
- self.tempfile = tempfile.TemporaryFile()
-
- # Create some dummy pipes. These won't be used since we'll mock out sends
- # to the interpreter.
- dummy_pipe_end_0, dummy_pipe_end_1 = threadproc_shim.Pipe()
- self.console = console.Console(self.tempfile.fileno(), self.tempfile,
- tempfile.TemporaryFile(),
- dummy_pipe_end_0, dummy_pipe_end_1, "EC")
-
- # Console editing methods are only valid for enhanced EC images, therefore
- # we have to assume that the "EC" we're talking to is enhanced. By default,
- # the console believes that the EC it's communicating with is NOT enhanced
- # which is why we have to override it here.
- self.console.enhanced_ec = True
- self.console.CheckForEnhancedECImage = mock.MagicMock(return_value=True)
-
- def test_EnteringChars(self):
- """Verify that characters are echoed onto the console."""
- test_str = 'abc'
- input_stream = StringToByteList(test_str)
-
- # Send the characters in.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Check the input position.
- exp_pos = len(test_str)
- CheckInputBufferPosition(self, exp_pos)
-
- # Verify that the input buffer is correct.
- expected_buffer = test_str
- CheckInputBuffer(self, expected_buffer)
-
- # Check console output
- exp_console_out = test_str
- CheckConsoleOutput(self, exp_console_out)
-
- def test_EnteringDeletingMoreCharsThanEntered(self):
- """Verify that we can press backspace more than we have entered chars."""
- test_str = 'spamspam'
- input_stream = StringToByteList(test_str)
-
- # Send the characters in.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Now backspace 1 more than what we sent.
- input_stream = []
- for _ in range(len(test_str) + 1):
- input_stream.append(console.ControlKey.BACKSPACE)
-
- # Send that sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # First, verify that input buffer position is 0.
- CheckInputBufferPosition(self, 0)
-
- # Next, examine the output stream for the correct sequence.
- exp_console_out = test_str
- for _ in range(len(test_str)):
- exp_console_out += BACKSPACE_STRING
-
- # Now, verify that we got what we expected.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_EnteringMoreThanCharLimit(self):
- """Verify that we drop characters when the line is too long."""
- test_str = self.console.line_limit * 'o' # All allowed.
- test_str += 5 * 'x' # All should be dropped.
- input_stream = StringToByteList(test_str)
-
- # Send the characters in.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # First, we expect that input buffer position should be equal to the line
- # limit.
- exp_pos = self.console.line_limit
- CheckInputBufferPosition(self, exp_pos)
-
- # The input buffer should only hold until the line limit.
- exp_buffer = test_str[0:self.console.line_limit]
- CheckInputBuffer(self, exp_buffer)
-
- # Lastly, check that the extra characters are not printed.
- exp_console_out = exp_buffer
- CheckConsoleOutput(self, exp_console_out)
-
- def test_ValidKeysOnLongLine(self):
- """Verify that we can still press valid keys if the line is too long."""
- # Fill the line.
- test_str = self.console.line_limit * 'o'
- exp_console_out = test_str
- # Try to fill it even more; these should all be dropped.
- test_str += 5 * 'x'
- input_stream = StringToByteList(test_str)
-
- # We should be able to press the following keys:
- # - Backspace
- # - Arrow Keys/CTRL+B/CTRL+F/CTRL+P/CTRL+N
- # - Delete
- # - Home/CTRL+A
- # - End/CTRL+E
- # - Carriage Return
-
- # Backspace 1 character
- input_stream.append(console.ControlKey.BACKSPACE)
- exp_console_out += BACKSPACE_STRING
- # Refill the line.
- input_stream.extend(StringToByteList('o'))
- exp_console_out += 'o'
-
- # Left arrow key.
- input_stream.extend(Keys.LEFT_ARROW)
- exp_console_out += OutputStream.MoveCursorLeft(1)
-
- # Right arrow key.
- input_stream.extend(Keys.RIGHT_ARROW)
- exp_console_out += OutputStream.MoveCursorRight(1)
-
- # CTRL+B
- input_stream.append(console.ControlKey.CTRL_B)
- exp_console_out += OutputStream.MoveCursorLeft(1)
-
- # CTRL+F
- input_stream.append(console.ControlKey.CTRL_F)
- exp_console_out += OutputStream.MoveCursorRight(1)
-
- # Let's press enter now so we can test up and down.
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- exp_console_out += '\r\n' + self.console.prompt
-
- # Up arrow key.
- input_stream.extend(Keys.UP_ARROW)
- exp_console_out += test_str[:self.console.line_limit]
-
- # Down arrow key.
- input_stream.extend(Keys.DOWN_ARROW)
- # Since the line was blank, we have to backspace the entire line.
- exp_console_out += self.console.line_limit * BACKSPACE_STRING
-
- # CTRL+P
- input_stream.append(console.ControlKey.CTRL_P)
- exp_console_out += test_str[:self.console.line_limit]
-
- # CTRL+N
- input_stream.append(console.ControlKey.CTRL_N)
- # Since the line was blank, we have to backspace the entire line.
- exp_console_out += self.console.line_limit * BACKSPACE_STRING
-
- # Press the Up arrow key to reprint the long line.
- input_stream.extend(Keys.UP_ARROW)
- exp_console_out += test_str[:self.console.line_limit]
-
- # Press the Home key to jump to the beginning of the line.
- input_stream.extend(Keys.HOME)
- exp_console_out += OutputStream.MoveCursorLeft(self.console.line_limit)
-
- # Press the End key to jump to the end of the line.
- input_stream.extend(Keys.END)
- exp_console_out += OutputStream.MoveCursorRight(self.console.line_limit)
-
- # Press CTRL+A to jump to the beginning of the line.
- input_stream.append(console.ControlKey.CTRL_A)
- exp_console_out += OutputStream.MoveCursorLeft(self.console.line_limit)
-
- # Press CTRL+E to jump to the end of the line.
- input_stream.extend(Keys.END)
- exp_console_out += OutputStream.MoveCursorRight(self.console.line_limit)
-
- # Move left one column so we can delete a character.
- input_stream.extend(Keys.LEFT_ARROW)
- exp_console_out += OutputStream.MoveCursorLeft(1)
-
- # Press the delete key.
- input_stream.extend(Keys.DEL)
- # This should look like a space, and then move cursor left 1 column since
- # we're at the end of line.
- exp_console_out += ' ' + OutputStream.MoveCursorLeft(1)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify everything happened correctly.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_BackspaceOnEmptyLine(self):
- """Verify that we can backspace on an empty line with no bad effects."""
- # Send a single backspace.
- test_str = [console.ControlKey.BACKSPACE]
-
- # Send the characters in.
- for byte in test_str:
- self.console.HandleChar(byte)
-
- # Check the input position.
- exp_pos = 0
- CheckInputBufferPosition(self, exp_pos)
-
- # Check that buffer is empty.
- exp_input_buffer = ''
- CheckInputBuffer(self, exp_input_buffer)
-
- # Check that the console output is empty.
- exp_console_out = ''
- CheckConsoleOutput(self, exp_console_out)
-
- def test_BackspaceWithinLine(self):
- """Verify that we shift the chars over when backspacing within a line."""
- # Misspell 'help'
- test_str = 'heelp'
- input_stream = StringToByteList(test_str)
- # Use the arrow key to go back to fix it.
- # Move cursor left 1 column.
- input_stream.extend(2*Keys.LEFT_ARROW)
- # Backspace once to remove the extra 'e'.
- input_stream.append(console.ControlKey.BACKSPACE)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify the input buffer
- exp_input_buffer = 'help'
- CheckInputBuffer(self, exp_input_buffer)
-
- # Verify the input buffer position. It should be at 2 (cursor over the 'l')
- CheckInputBufferPosition(self, 2)
-
- # We expect the console output to be the test string, with two moves to the
- # left, another move left, and then the rest of the line followed by a
- # space.
- exp_console_out = test_str
- exp_console_out += 2 * OutputStream.MoveCursorLeft(1)
-
- # Move cursor left 1 column.
- exp_console_out += OutputStream.MoveCursorLeft(1)
- # Rest of the line and a space. (test_str in this case)
- exp_console_out += 'lp '
- # Reset the cursor 2 + 1 to the left.
- exp_console_out += OutputStream.MoveCursorLeft(3)
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_JumpToBeginningOfLineViaCtrlA(self):
- """Verify that we can jump to the beginning of a line with Ctrl+A."""
- # Enter some chars and press CTRL+A
- test_str = 'abc'
- input_stream = StringToByteList(test_str) + [console.ControlKey.CTRL_A]
-
- # Send the characters in.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # We expect to see our test string followed by a move cursor left.
- exp_console_out = test_str
- exp_console_out += OutputStream.MoveCursorLeft(len(test_str))
-
- # Check to see what whas printed on the console.
- CheckConsoleOutput(self, exp_console_out)
-
- # Check that the input buffer position is now 0.
- CheckInputBufferPosition(self, 0)
-
- # Check input buffer still contains our test string.
- CheckInputBuffer(self, test_str)
-
- def test_JumpToBeginningOfLineViaHomeKey(self):
- """Jump to beginning of line via HOME key."""
- test_str = 'version'
- input_stream = StringToByteList(test_str)
- input_stream.extend(Keys.HOME)
-
- # Send out the stream.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # First, verify that input buffer position is now 0.
- CheckInputBufferPosition(self, 0)
-
- # Next, verify that the input buffer did not change.
- CheckInputBuffer(self, test_str)
-
- # Lastly, check that the cursor moved correctly.
- exp_console_out = test_str
- exp_console_out += OutputStream.MoveCursorLeft(len(test_str))
- CheckConsoleOutput(self, exp_console_out)
-
- def test_JumpToEndOfLineViaEndKey(self):
- """Jump to the end of the line using the END key."""
- test_str = 'version'
- input_stream = StringToByteList(test_str)
- input_stream += [console.ControlKey.CTRL_A]
- # Now, jump to the end of the line.
- input_stream.extend(Keys.END)
-
- # Send out the stream.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the input buffer position is correct. This should be at the
- # end of the test string.
- CheckInputBufferPosition(self, len(test_str))
-
- # The expected output should be the test string, followed by a jump to the
- # beginning of the line, and lastly a jump to the end of the line.
- exp_console_out = test_str
- exp_console_out += OutputStream.MoveCursorLeft(len(test_str))
- # Now the jump back to the end of the line.
- exp_console_out += OutputStream.MoveCursorRight(len(test_str))
-
- # Verify console output stream.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_JumpToEndOfLineViaCtrlE(self):
- """Enter some chars and then try to jump to the end. (Should be a no-op)"""
- test_str = 'sysinfo'
- input_stream = StringToByteList(test_str)
- input_stream.append(console.ControlKey.CTRL_E)
-
- # Send out the stream
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the input buffer position isn't any further than we expect.
- # At this point, the position should be at the end of the test string.
- CheckInputBufferPosition(self, len(test_str))
-
- # Now, let's try to jump to the beginning and then jump back to the end.
- input_stream = [console.ControlKey.CTRL_A, console.ControlKey.CTRL_E]
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Perform the same verification.
- CheckInputBufferPosition(self, len(test_str))
-
- # Lastly try to jump again, beyond the end.
- input_stream = [console.ControlKey.CTRL_E]
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Perform the same verification.
- CheckInputBufferPosition(self, len(test_str))
-
- # We expect to see the test string, a jump to the beginning of the line, and
- # one jump to the end of the line.
- exp_console_out = test_str
- # Jump to beginning.
- exp_console_out += OutputStream.MoveCursorLeft(len(test_str))
- # Jump back to end.
- exp_console_out += OutputStream.MoveCursorRight(len(test_str))
-
- # Verify the console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_MoveLeftWithArrowKey(self):
- """Move cursor left one column with arrow key."""
- test_str = 'tastyspam'
- input_stream = StringToByteList(test_str)
- input_stream.extend(Keys.LEFT_ARROW)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the input buffer position is 1 less than the length.
- CheckInputBufferPosition(self, len(test_str) - 1)
-
- # Also, verify that the input buffer is not modified.
- CheckInputBuffer(self, test_str)
-
- # We expect the test string, followed by a one column move left.
- exp_console_out = test_str + OutputStream.MoveCursorLeft(1)
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_MoveLeftWithCtrlB(self):
- """Move cursor back one column with Ctrl+B."""
- test_str = 'tastyspam'
- input_stream = StringToByteList(test_str)
- input_stream.append(console.ControlKey.CTRL_B)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the input buffer position is 1 less than the length.
- CheckInputBufferPosition(self, len(test_str) - 1)
-
- # Also, verify that the input buffer is not modified.
- CheckInputBuffer(self, test_str)
-
- # We expect the test string, followed by a one column move left.
- exp_console_out = test_str + OutputStream.MoveCursorLeft(1)
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_MoveRightWithArrowKey(self):
- """Move cursor one column to the right with the arrow key."""
- test_str = 'version'
- input_stream = StringToByteList(test_str)
- # Jump to beginning of line.
- input_stream.append(console.ControlKey.CTRL_A)
- # Press right arrow key.
- input_stream.extend(Keys.RIGHT_ARROW)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the input buffer position is 1.
- CheckInputBufferPosition(self, 1)
-
- # Also, verify that the input buffer is not modified.
- CheckInputBuffer(self, test_str)
-
- # We expect the test string, followed by a jump to the beginning of the
- # line, and finally a move right 1.
- exp_console_out = test_str + OutputStream.MoveCursorLeft(len((test_str)))
-
- # A move right 1 column.
- exp_console_out += OutputStream.MoveCursorRight(1)
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_MoveRightWithCtrlF(self):
- """Move cursor forward one column with Ctrl+F."""
- test_str = 'panicinfo'
- input_stream = StringToByteList(test_str)
- input_stream.append(console.ControlKey.CTRL_A)
- # Now, move right one column.
- input_stream.append(console.ControlKey.CTRL_F)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the input buffer position is 1.
- CheckInputBufferPosition(self, 1)
-
- # Also, verify that the input buffer is not modified.
- CheckInputBuffer(self, test_str)
-
- # We expect the test string, followed by a jump to the beginning of the
- # line, and finally a move right 1.
- exp_console_out = test_str + OutputStream.MoveCursorLeft(len((test_str)))
-
- # A move right 1 column.
- exp_console_out += OutputStream.MoveCursorRight(1)
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_ImpossibleMoveLeftWithArrowKey(self):
- """Verify that we can't move left at the beginning of the line."""
- # We shouldn't be able to move left if we're at the beginning of the line.
- input_stream = Keys.LEFT_ARROW
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Nothing should have been output.
- exp_console_output = ''
- CheckConsoleOutput(self, exp_console_output)
-
- # The input buffer position should still be 0.
- CheckInputBufferPosition(self, 0)
-
- # The input buffer itself should be empty.
- CheckInputBuffer(self, '')
-
- def test_ImpossibleMoveRightWithArrowKey(self):
- """Verify that we can't move right at the end of the line."""
- # We shouldn't be able to move right if we're at the end of the line.
- input_stream = Keys.RIGHT_ARROW
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Nothing should have been output.
- exp_console_output = ''
- CheckConsoleOutput(self, exp_console_output)
-
- # The input buffer position should still be 0.
- CheckInputBufferPosition(self, 0)
-
- # The input buffer itself should be empty.
- CheckInputBuffer(self, '')
-
- def test_KillEntireLine(self):
- """Verify that we can kill an entire line with Ctrl+K."""
- test_str = 'accelinfo on'
- input_stream = StringToByteList(test_str)
- # Jump to beginning of line and then kill it with Ctrl+K.
- input_stream.extend([console.ControlKey.CTRL_A, console.ControlKey.CTRL_K])
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # First, we expect that the input buffer is empty.
- CheckInputBuffer(self, '')
-
- # The buffer position should be 0.
- CheckInputBufferPosition(self, 0)
-
- # What we expect to see on the console stream should be the following. The
- # test string, a jump to the beginning of the line, then jump back to the
- # end of the line and replace the line with spaces.
- exp_console_out = test_str
- # Jump to beginning of line.
- exp_console_out += OutputStream.MoveCursorLeft(len(test_str))
- # Jump to end of line.
- exp_console_out += OutputStream.MoveCursorRight(len(test_str))
- # Replace line with spaces, which looks like backspaces.
- for _ in range(len(test_str)):
- exp_console_out += BACKSPACE_STRING
-
- # Verify the console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_KillPartialLine(self):
- """Verify that we can kill a portion of a line."""
- test_str = 'accelread 0 1'
- input_stream = StringToByteList(test_str)
- len_to_kill = 5
- for _ in range(len_to_kill):
- # Move cursor left
- input_stream.extend(Keys.LEFT_ARROW)
- # Now kill
- input_stream.append(console.ControlKey.CTRL_K)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # First, check that the input buffer was truncated.
- exp_input_buffer = test_str[:-len_to_kill]
- CheckInputBuffer(self, exp_input_buffer)
-
- # Verify the input buffer position.
- CheckInputBufferPosition(self, len(test_str) - len_to_kill)
-
- # The console output stream that we expect is the test string followed by a
- # move left of len_to_kill, then a jump to the end of the line and backspace
- # of len_to_kill.
- exp_console_out = test_str
- for _ in range(len_to_kill):
- # Move left 1 column.
- exp_console_out += OutputStream.MoveCursorLeft(1)
- # Then jump to the end of the line
- exp_console_out += OutputStream.MoveCursorRight(len_to_kill)
- # Backspace of len_to_kill
- for _ in range(len_to_kill):
- exp_console_out += BACKSPACE_STRING
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_InsertingCharacters(self):
- """Verify that we can insert charcters within the line."""
- test_str = 'accel 0 1' # Here we forgot the 'read' part in 'accelread'
- input_stream = StringToByteList(test_str)
- # We need to move over to the 'l' and add read.
- insertion_point = test_str.find('l') + 1
- for i in range(len(test_str) - insertion_point):
- # Move cursor left.
- input_stream.extend(Keys.LEFT_ARROW)
- # Now, add in 'read'
- added_str = 'read'
- input_stream.extend(StringToByteList(added_str))
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # First, verify that the input buffer is correct.
- exp_input_buffer = test_str[:insertion_point] + added_str
- exp_input_buffer += test_str[insertion_point:]
- CheckInputBuffer(self, exp_input_buffer)
-
- # Verify that the input buffer position is correct.
- exp_input_buffer_pos = insertion_point + len(added_str)
- CheckInputBufferPosition(self, exp_input_buffer_pos)
-
- # The console output stream that we expect is the test string, followed by
- # move cursor left until the 'l' was found, the added test string while
- # shifting characters around.
- exp_console_out = test_str
- for i in range(len(test_str) - insertion_point):
- # Move cursor left.
- exp_console_out += OutputStream.MoveCursorLeft(1)
-
- # Now for each character, write the rest of the line will be shifted to the
- # right one column.
- for i in range(len(added_str)):
- # Printed character.
- exp_console_out += added_str[i]
- # The rest of the line
- exp_console_out += test_str[insertion_point:]
- # Reset the cursor back left
- reset_dist = len(test_str[insertion_point:])
- exp_console_out += OutputStream.MoveCursorLeft(reset_dist)
-
- # Verify the console output.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_StoreCommandHistory(self):
- """Verify that entered commands are stored in the history."""
- test_commands = []
- test_commands.append('help')
- test_commands.append('version')
- test_commands.append('accelread 0 1')
- input_stream = []
- for c in test_commands:
- input_stream.extend(StringToByteList(c))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # We expect to have the test commands in the history buffer.
- exp_history_buf = test_commands
- CheckHistoryBuffer(self, exp_history_buf)
-
- def test_CycleUpThruCommandHistory(self):
- """Verify that the UP arrow key will print itmes in the history buffer."""
- # Enter some commands.
- test_commands = ['version', 'accelrange 0', 'battery', 'gettime']
- input_stream = []
- for command in test_commands:
- input_stream.extend(StringToByteList(command))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Now, hit the UP arrow key to print the previous entries.
- for i in range(len(test_commands)):
- input_stream.extend(Keys.UP_ARROW)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The expected output should be test commands with prompts printed in
- # between, followed by line kills with the previous test commands printed.
- exp_console_out = ''
- for i in range(len(test_commands)):
- exp_console_out += test_commands[i] + '\r\n' + self.console.prompt
-
- # When we press up, the line should be cleared and print the previous buffer
- # entry.
- for i in range(len(test_commands)-1, 0, -1):
- exp_console_out += test_commands[i]
- # Backspace to the beginning.
- for i in range(len(test_commands[i])):
- exp_console_out += BACKSPACE_STRING
-
- # The last command should just be printed out with no backspacing.
- exp_console_out += test_commands[0]
-
- # Now, verify.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_UpArrowOnEmptyHistory(self):
- """Ensure nothing happens if the history is empty."""
- # Press the up arrow key twice.
- input_stream = 2 * Keys.UP_ARROW
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # We expect nothing to have happened.
- exp_console_out = ''
- exp_input_buffer = ''
- exp_input_buffer_pos = 0
- exp_history_buf = []
-
- # Verify.
- CheckConsoleOutput(self, exp_console_out)
- CheckInputBufferPosition(self, exp_input_buffer_pos)
- CheckInputBuffer(self, exp_input_buffer)
- CheckHistoryBuffer(self, exp_history_buf)
-
- def test_UpArrowDoesNotGoOutOfBounds(self):
- """Verify that pressing the up arrow many times won't go out of bounds."""
- # Enter one command.
- test_str = 'help version'
- input_stream = StringToByteList(test_str)
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- # Then press the up arrow key twice.
- input_stream.extend(2 * Keys.UP_ARROW)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the history buffer is correct.
- exp_history_buf = [test_str]
- CheckHistoryBuffer(self, exp_history_buf)
-
- # We expect that the console output should only contain our entered command,
- # a new prompt, and then our command aggain.
- exp_console_out = test_str + '\r\n' + self.console.prompt
- # Pressing up should reprint the command we entered.
- exp_console_out += test_str
-
- # Verify.
- CheckConsoleOutput(self, exp_console_out)
-
- def test_CycleDownThruCommandHistory(self):
- """Verify that we can select entries by hitting the down arrow."""
- # Enter at least 4 commands.
- test_commands = ['version', 'accelrange 0', 'battery', 'gettime']
- input_stream = []
- for command in test_commands:
- input_stream.extend(StringToByteList(command))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Now, hit the UP arrow key twice to print the previous two entries.
- for i in range(2):
- input_stream.extend(Keys.UP_ARROW)
-
- # Now, hit the DOWN arrow key twice to print the newer entries.
- input_stream.extend(2*Keys.DOWN_ARROW)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The expected output should be commands that we entered, followed by
- # prompts, then followed by our last two commands in reverse. Then, we
- # should see the last entry in the list, followed by the saved partial cmd
- # of a blank line.
- exp_console_out = ''
- for i in range(len(test_commands)):
- exp_console_out += test_commands[i] + '\r\n' + self.console.prompt
-
- # When we press up, the line should be cleared and print the previous buffer
- # entry.
- for i in range(len(test_commands)-1, 1, -1):
- exp_console_out += test_commands[i]
- # Backspace to the beginning.
- for i in range(len(test_commands[i])):
- exp_console_out += BACKSPACE_STRING
-
- # When we press down, it should have cleared the last command (which we
- # covered with the previous for loop), and then prints the next command.
- exp_console_out += test_commands[3]
- for i in range(len(test_commands[3])):
- exp_console_out += BACKSPACE_STRING
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- # Verify input buffer.
- exp_input_buffer = '' # Empty because our partial command was empty.
- exp_input_buffer_pos = len(exp_input_buffer)
- CheckInputBuffer(self, exp_input_buffer)
- CheckInputBufferPosition(self, exp_input_buffer_pos)
-
- def test_SavingPartialCommandWhenNavigatingHistory(self):
- """Verify that partial commands are saved when navigating history."""
- # Enter a command.
- test_str = 'accelinfo'
- input_stream = StringToByteList(test_str)
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Enter a partial command.
- partial_cmd = 'ver'
- input_stream.extend(StringToByteList(partial_cmd))
-
- # Hit the UP arrow key.
- input_stream.extend(Keys.UP_ARROW)
- # Then, the DOWN arrow key.
- input_stream.extend(Keys.DOWN_ARROW)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The expected output should be the command we entered, a prompt, the
- # partial command, clearing of the partial command, the command entered,
- # clearing of the command entered, and then the partial command.
- exp_console_out = test_str + '\r\n' + self.console.prompt
- exp_console_out += partial_cmd
- for _ in range(len(partial_cmd)):
- exp_console_out += BACKSPACE_STRING
- exp_console_out += test_str
- for _ in range(len(test_str)):
- exp_console_out += BACKSPACE_STRING
- exp_console_out += partial_cmd
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- # Verify input buffer.
- exp_input_buffer = partial_cmd
- exp_input_buffer_pos = len(exp_input_buffer)
- CheckInputBuffer(self, exp_input_buffer)
- CheckInputBufferPosition(self, exp_input_buffer_pos)
-
- def test_DownArrowOnEmptyHistory(self):
- """Ensure nothing happens if the history is empty."""
- # Then press the up down arrow twice.
- input_stream = 2 * Keys.DOWN_ARROW
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # We expect nothing to have happened.
- exp_console_out = ''
- exp_input_buffer = ''
- exp_input_buffer_pos = 0
- exp_history_buf = []
-
- # Verify.
- CheckConsoleOutput(self, exp_console_out)
- CheckInputBufferPosition(self, exp_input_buffer_pos)
- CheckInputBuffer(self, exp_input_buffer)
- CheckHistoryBuffer(self, exp_history_buf)
-
- def test_DeleteCharsUsingDELKey(self):
- """Verify that we can delete characters using the DEL key."""
- test_str = 'version'
- input_stream = StringToByteList(test_str)
-
- # Hit the left arrow key 2 times.
- input_stream.extend(2 * Keys.LEFT_ARROW)
-
- # Press the DEL key.
- input_stream.extend(Keys.DEL)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The expected output should be the command we entered, 2 individual cursor
- # moves to the left, and then removing a char and shifting everything to the
- # left one column.
- exp_console_out = test_str
- exp_console_out += 2 * OutputStream.MoveCursorLeft(1)
-
- # Remove the char by shifting everything to the left one, slicing out the
- # remove char.
- exp_console_out += test_str[-1:] + ' '
-
- # Reset the cursor by moving back 2 columns because of the 'n' and space.
- exp_console_out += OutputStream.MoveCursorLeft(2)
-
- # Verify console output.
- CheckConsoleOutput(self, exp_console_out)
-
- # Verify input buffer. The input buffer should have the char sliced out and
- # be positioned where the char was removed.
- exp_input_buffer = test_str[:-2] + test_str[-1:]
- exp_input_buffer_pos = len(exp_input_buffer) - 1
- CheckInputBuffer(self, exp_input_buffer)
- CheckInputBufferPosition(self, exp_input_buffer_pos)
-
- def test_RepeatedCommandInHistory(self):
- """Verify that we don't store 2 consecutive identical commands in history"""
- # Enter a few commands.
- test_commands = ['version', 'accelrange 0', 'battery', 'gettime']
- # Repeat the last command.
- test_commands.append(test_commands[len(test_commands)-1])
-
- input_stream = []
- for command in test_commands:
- input_stream.extend(StringToByteList(command))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Verify that the history buffer is correct. The last command, since
- # it was repeated, should not have been added to the history.
- exp_history_buf = test_commands[0:len(test_commands)-1]
- CheckHistoryBuffer(self, exp_history_buf)
-
-
-class TestConsoleCompatibility(unittest.TestCase):
- """Verify that console can speak to enhanced and non-enhanced EC images."""
- def setUp(self):
- """Setup the test harness."""
- # Setup logging with a timestamp, the module, and the log level.
- logging.basicConfig(level=logging.DEBUG,
- format=('%(asctime)s - %(module)s -'
- ' %(levelname)s - %(message)s'))
- # Create a temp file and set both the master and slave PTYs to the file to
- # create a loopback.
- self.tempfile = tempfile.TemporaryFile()
-
- # Mock out the pipes.
- dummy_pipe_end_0, dummy_pipe_end_1 = mock.MagicMock(), mock.MagicMock()
- self.console = console.Console(self.tempfile.fileno(), self.tempfile,
- tempfile.TemporaryFile(),
- dummy_pipe_end_0, dummy_pipe_end_1, "EC")
-
- @mock.patch('console.Console.CheckForEnhancedECImage')
- def test_ActAsPassThruInNonEnhancedMode(self, mock_check):
- """Verify we simply pass everything thru to non-enhanced ECs.
-
- Args:
- mock_check: A MagicMock object replacing the CheckForEnhancedECImage()
- method.
- """
- # Set the interrogation mode to always so that we actually interrogate.
- self.console.interrogation_mode = 'always'
-
- # Assume EC interrogations indicate that the image is non-enhanced.
- mock_check.return_value = False
-
- # Press enter, followed by the command, and another enter.
- input_stream = []
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- test_command = 'version'
- input_stream.extend(StringToByteList(test_command))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Expected calls to send down the pipe would be each character of the test
- # command.
- expected_calls = []
- expected_calls.append(mock.call(chr(console.ControlKey.CARRIAGE_RETURN)))
- for char in test_command:
- expected_calls.append(mock.call(char))
- expected_calls.append(mock.call(chr(console.ControlKey.CARRIAGE_RETURN)))
-
- # Verify that the calls happened.
- self.console.cmd_pipe.send.assert_has_calls(expected_calls)
-
- # Since we're acting as a pass-thru, the input buffer should be empty and
- # input_buffer_pos is 0.
- CheckInputBuffer(self, '')
- CheckInputBufferPosition(self, 0)
-
- @mock.patch('console.Console.CheckForEnhancedECImage')
- def test_TransitionFromNonEnhancedToEnhanced(self, mock_check):
- """Verify that we transition correctly to enhanced mode.
-
- Args:
- mock_check: A MagicMock object replacing the CheckForEnhancedECImage()
- method.
- """
- # Set the interrogation mode to always so that we actually interrogate.
- self.console.interrogation_mode = 'always'
-
- # First, assume that the EC interrogations indicate an enhanced EC image.
- mock_check.return_value = True
- # But our current knowledge of the EC image (which was actually the
- # 'previous' EC) was a non-enhanced image.
- self.console.enhanced_ec = False
-
- test_command = 'sysinfo'
- input_stream = []
- input_stream.extend(StringToByteList(test_command))
-
- expected_calls = []
- # All keystrokes to the console should be directed straight through to the
- # EC until we press the enter key.
- for char in test_command:
- expected_calls.append(mock.call(char))
-
- # Press the enter key.
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- # The enter key should not be sent to the pipe since we should negotiate
- # to an enhanced EC image.
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # At this point, we should have negotiated to enhanced.
- self.assertTrue(self.console.enhanced_ec, msg=('Did not negotiate to '
- 'enhanced EC image.'))
-
- # The command would have been dropped however, so verify this...
- CheckInputBuffer(self, '')
- CheckInputBufferPosition(self, 0)
- # ...and repeat the command.
- input_stream = StringToByteList(test_command)
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Since we're enhanced now, we should have sent the entire command as one
- # string with no trailing carriage return
- expected_calls.append(mock.call(test_command))
-
- # Verify all of the calls.
- self.console.cmd_pipe.send.assert_has_calls(expected_calls)
-
- @mock.patch('console.Console.CheckForEnhancedECImage')
- def test_TransitionFromEnhancedToNonEnhanced(self, mock_check):
- """Verify that we transition correctly to non-enhanced mode.
-
- Args:
- mock_check: A MagicMock object replacing the CheckForEnhancedECImage()
- method.
- """
- # Set the interrogation mode to always so that we actually interrogate.
- self.console.interrogation_mode = 'always'
-
- # First, assume that the EC interrogations indicate an non-enhanced EC
- # image.
- mock_check.return_value = False
- # But our current knowledge of the EC image (which was actually the
- # 'previous' EC) was an enhanced image.
- self.console.enhanced_ec = True
-
- test_command = 'sysinfo'
- input_stream = []
- input_stream.extend(StringToByteList(test_command))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # But, we will negotiate to non-enhanced however, dropping this command.
- # Verify this.
- self.assertFalse(self.console.enhanced_ec, msg=('Did not negotiate to'
- 'non-enhanced EC image.'))
- CheckInputBuffer(self, '')
- CheckInputBufferPosition(self, 0)
-
- # The carriage return should have passed through though.
- expected_calls = []
- expected_calls.append(mock.call(chr(console.ControlKey.CARRIAGE_RETURN)))
-
- # Since the command was dropped, repeat the command.
- input_stream = StringToByteList(test_command)
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # Since we're not enhanced now, we should have sent each character in the
- # entire command separately and a carriage return.
- for char in test_command:
- expected_calls.append(mock.call(char))
- expected_calls.append(mock.call(chr(console.ControlKey.CARRIAGE_RETURN)))
-
- # Verify all of the calls.
- self.console.cmd_pipe.send.assert_has_calls(expected_calls)
-
- def test_EnhancedCheckIfTimedOut(self):
- """Verify that the check returns false if it times out."""
- # Make the debug pipe "time out".
- self.console.dbg_pipe.poll.return_value = False
- self.assertFalse(self.console.CheckForEnhancedECImage())
-
- def test_EnhancedCheckIfACKReceived(self):
- """Verify that the check returns true if the ACK is received."""
- # Make the debug pipe return EC_ACK.
- self.console.dbg_pipe.poll.return_value = True
- self.console.dbg_pipe.recv.return_value = interpreter.EC_ACK
- self.assertTrue(self.console.CheckForEnhancedECImage())
-
- def test_EnhancedCheckIfWrong(self):
- """Verify that the check returns false if byte received is wrong."""
- # Make the debug pipe return the wrong byte.
- self.console.dbg_pipe.poll.return_value = True
- self.console.dbg_pipe.recv.return_value = '\xff'
- self.assertFalse(self.console.CheckForEnhancedECImage())
-
- def test_EnhancedCheckUsingBuffer(self):
- """Verify that given reboot output, enhanced EC images are detected."""
- enhanced_output_stream = """
---- UART initialized after reboot ---
-[Reset cause: reset-pin soft]
-[Image: RO, jerry_v1.1.4363-2af8572-dirty 2016-02-23 13:26:20 aaboagye@lithium.mtv.corp.google.com]
-[0.001695 KB boot key 0]
-[0.001790 Inits done]
-[0.001923 not sysjump; forcing AP shutdown]
-[0.002047 EC triggered warm reboot]
-[0.002155 assert GPIO_PMIC_WARM_RESET_L for 4 ms]
-[0.006326 auto_power_on set due to reset_flag 0x22]
-[0.006477 Wait for battery stabilized during 1000000]
-[0.007368 battery responded with status c0]
-[0.009099 hash start 0x00010000 0x0000eb7c]
-[0.009307 KB init state: -- -- -- -- -- -- -- -- -- -- -- -- --]
-[0.009531 KB wait]
-Enhanced Console is enabled (v1.0.0); type HELP for help.
-> [0.009782 event set 0x00002000]
-[0.009903 hostcmd init 0x2000]
-[0.010031 power state 0 = G3, in 0x0000]
-[0.010173 power state 4 = G3->S5, in 0x0000]
-[0.010324 power state 1 = S5, in 0x0000]
-[0.010466 power on 2]
-[0.010566 power state 5 = S5->S3, in 0x0000]
-[0.037713 event set 0x00000080]
-[0.037836 event set 0x00400000]
-[0.038675 Battery 89% / 1092h:15 to empty]
-[0.224060 hash done 41dac382e3a6e3d2ea5b4d789c1bc46525cae7cc5ff6758f0de8d8369b506f57]
-[0.375150 POWER_GOOD seen]
-"""
- for line in enhanced_output_stream.split('\n'):
- self.console.CheckBufferForEnhancedImage(line)
-
- # Since the enhanced console string was present in the output, the console
- # should have caught it.
- self.assertTrue(self.console.enhanced_ec)
-
- # Also should check that the command was sent to the interpreter.
- self.console.cmd_pipe.send.assert_called_once_with('enhanced True')
-
- # Now test the non-enhanced EC image.
- self.console.cmd_pipe.reset_mock()
- non_enhanced_output_stream = """
---- UART initialized after reboot ---
-[Reset cause: reset-pin soft]
-[Image: RO, jerry_v1.1.4363-2af8572-dirty 2016-02-23 13:03:15 aaboagye@lithium.mtv.corp.google.com]
-[0.001695 KB boot key 0]
-[0.001790 Inits done]
-[0.001923 not sysjump; forcing AP shutdown]
-[0.002047 EC triggered warm reboot]
-[0.002156 assert GPIO_PMIC_WARM_RESET_L for 4 ms]
-[0.006326 auto_power_on set due to reset_flag 0x22]
-[0.006477 Wait for battery stabilized during 1000000]
-[0.007368 battery responded with status c0]
-[0.008951 hash start 0x00010000 0x0000ed78]
-[0.009159 KB init state: -- -- -- -- -- -- -- -- -- -- -- -- --]
-[0.009383 KB wait]
-Console is enabled; type HELP for help.
-> [0.009602 event set 0x00002000]
-[0.009722 hostcmd init 0x2000]
-[0.009851 power state 0 = G3, in 0x0000]
-[0.009993 power state 4 = G3->S5, in 0x0000]
-[0.010144 power state 1 = S5, in 0x0000]
-[0.010285 power on 2]
-[0.010385 power state 5 = S5->S3, in 0x0000]
-"""
- for line in non_enhanced_output_stream.split('\n'):
- self.console.CheckBufferForEnhancedImage(line)
-
- # Since the default console string is present in the output, it should be
- # determined to be non enhanced now.
- self.assertFalse(self.console.enhanced_ec)
-
- # Check that command was also sent to the interpreter.
- self.console.cmd_pipe.send.assert_called_once_with('enhanced False')
-
-
-class TestOOBMConsoleCommands(unittest.TestCase):
- """Verify that OOBM console commands work correctly."""
- def setUp(self):
- """Setup the test harness."""
- # Setup logging with a timestamp, the module, and the log level.
- logging.basicConfig(level=logging.DEBUG,
- format=('%(asctime)s - %(module)s -'
- ' %(levelname)s - %(message)s'))
- # Create a temp file and set both the master and slave PTYs to the file to
- # create a loopback.
- self.tempfile = tempfile.TemporaryFile()
-
- # Mock out the pipes.
- dummy_pipe_end_0, dummy_pipe_end_1 = mock.MagicMock(), mock.MagicMock()
- self.console = console.Console(self.tempfile.fileno(), self.tempfile,
- tempfile.TemporaryFile(),
- dummy_pipe_end_0, dummy_pipe_end_1, "EC")
- self.console.oobm_queue = mock.MagicMock()
-
- @mock.patch('console.Console.CheckForEnhancedECImage')
- def test_InterrogateCommand(self, mock_check):
- """Verify that 'interrogate' command works as expected.
-
- Args:
- mock_check: A MagicMock object replacing the CheckForEnhancedECIMage()
- method.
- """
- input_stream = []
- expected_calls = []
- mock_check.side_effect = [False]
-
- # 'interrogate never' should disable the interrogation from happening at
- # all.
- cmd = 'interrogate never'
- # Enter the OOBM prompt.
- input_stream.extend(StringToByteList('%'))
- # Type the command
- input_stream.extend(StringToByteList(cmd))
- # Press enter.
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- input_stream = []
-
- # The OOBM queue should have been called with the command being put.
- expected_calls.append(mock.call.put(cmd))
- self.console.oobm_queue.assert_has_calls(expected_calls)
-
- # Process the OOBM queue.
- self.console.oobm_queue.get.side_effect = [cmd]
- self.console.ProcessOOBMQueue()
-
- # Type out a few commands.
- input_stream.extend(StringToByteList('version'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('flashinfo'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('sysinfo'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The Check function should NOT have been called at all.
- mock_check.assert_not_called()
-
- # The EC image should be assumed to be not enhanced.
- self.assertFalse(self.console.enhanced_ec, 'The image should be assumed to'
- ' be NOT enhanced.')
-
- # Reset the mocks.
- mock_check.reset_mock()
- self.console.oobm_queue.reset_mock()
-
- # 'interrogate auto' should not interrogate at all. It should only be
- # scanning the output stream for the 'console is enabled' strings.
- cmd = 'interrogate auto'
- # Enter the OOBM prompt.
- input_stream.extend(StringToByteList('%'))
- # Type the command
- input_stream.extend(StringToByteList(cmd))
- # Press enter.
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- input_stream = []
- expected_calls = []
-
- # The OOBM queue should have been called with the command being put.
- expected_calls.append(mock.call.put(cmd))
- self.console.oobm_queue.assert_has_calls(expected_calls)
-
- # Process the OOBM queue.
- self.console.oobm_queue.get.side_effect = [cmd]
- self.console.ProcessOOBMQueue()
-
- # Type out a few commands.
- input_stream.extend(StringToByteList('version'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('flashinfo'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('sysinfo'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The Check function should NOT have been called at all.
- mock_check.assert_not_called()
-
- # The EC image should be assumed to be not enhanced.
- self.assertFalse(self.console.enhanced_ec, 'The image should be assumed to'
- ' be NOT enhanced.')
-
- # Reset the mocks.
- mock_check.reset_mock()
- self.console.oobm_queue.reset_mock()
-
- # 'interrogate always' should, like its name implies, interrogate always
- # after each press of the enter key. This was the former way of doing
- # interrogation.
- cmd = 'interrogate always'
- # Enter the OOBM prompt.
- input_stream.extend(StringToByteList('%'))
- # Type the command
- input_stream.extend(StringToByteList(cmd))
- # Press enter.
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- input_stream = []
- expected_calls = []
-
- # The OOBM queue should have been called with the command being put.
- expected_calls.append(mock.call.put(cmd))
- self.console.oobm_queue.assert_has_calls(expected_calls)
-
- # Process the OOBM queue.
- self.console.oobm_queue.get.side_effect = [cmd]
- self.console.ProcessOOBMQueue()
-
- # The Check method should be called 3 times here.
- mock_check.side_effect = [False, False, False]
-
- # Type out a few commands.
- input_stream.extend(StringToByteList('help list'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('taskinfo'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('hibdelay'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The Check method should have been called 3 times here.
- expected_calls = [mock.call(), mock.call(), mock.call()]
- mock_check.assert_has_calls(expected_calls)
-
- # The EC image should be assumed to be not enhanced.
- self.assertFalse(self.console.enhanced_ec, 'The image should be assumed to'
- ' be NOT enhanced.')
-
- # Now, let's try to assume that the image is enhanced while still disabling
- # interrogation.
- mock_check.reset_mock()
- self.console.oobm_queue.reset_mock()
- input_stream = []
- cmd = 'interrogate never enhanced'
- # Enter the OOBM prompt.
- input_stream.extend(StringToByteList('%'))
- # Type the command
- input_stream.extend(StringToByteList(cmd))
- # Press enter.
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- input_stream = []
- expected_calls = []
-
- # The OOBM queue should have been called with the command being put.
- expected_calls.append(mock.call.put(cmd))
- self.console.oobm_queue.assert_has_calls(expected_calls)
-
- # Process the OOBM queue.
- self.console.oobm_queue.get.side_effect = [cmd]
- self.console.ProcessOOBMQueue()
-
- # Type out a few commands.
- input_stream.extend(StringToByteList('chgstate'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('hash'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
- input_stream.extend(StringToByteList('sysjump rw'))
- input_stream.append(console.ControlKey.CARRIAGE_RETURN)
-
- # Send the sequence out.
- for byte in input_stream:
- self.console.HandleChar(byte)
-
- # The check method should have never been called.
- mock_check.assert_not_called()
-
- # The EC image should be assumed to be enhanced.
- self.assertTrue(self.console.enhanced_ec, 'The image should be'
- ' assumed to be enhanced.')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/util/ec3po/interpreter.py b/util/ec3po/interpreter.py
deleted file mode 100644
index 23eb6a6071..0000000000
--- a/util/ec3po/interpreter.py
+++ /dev/null
@@ -1,462 +0,0 @@
-# Copyright 2015 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.
-
-"""EC-3PO EC Interpreter
-
-interpreter provides the interpretation layer between the EC UART and the user.
-It receives commands through its command pipe, formats the commands for the EC,
-and sends the command to the EC. It also presents data from the EC to either be
-displayed via the interactive console interface, or some other consumer. It
-additionally supports automatic command retrying if the EC drops a character in
-a command.
-"""
-
-from __future__ import print_function
-
-import binascii
-# pylint: disable=cros-logging-import
-import copy
-import logging
-import os
-import Queue
-import select
-import traceback
-
-
-COMMAND_RETRIES = 3 # Number of attempts to retry a command.
-EC_MAX_READ = 1024 # Max bytes to read at a time from the EC.
-EC_SYN = '\xec' # Byte indicating EC interrogation.
-EC_ACK = '\xc0' # Byte representing correct EC response to interrogation.
-
-
-class LoggerAdapter(logging.LoggerAdapter):
- """Class which provides a small adapter for the logger."""
-
- def process(self, msg, kwargs):
- """Prepends the served PTY to the beginning of the log message."""
- return '%s - %s' % (self.extra['pty'], msg), kwargs
-
-
-class Interpreter(object):
- """Class which provides the interpretation layer between the EC and user.
-
- This class essentially performs all of the intepretation for the EC and the
- user. It handles all of the automatic command retrying as well as the
- formation of commands for EC images which support that.
-
- Attributes:
- logger: A logger for this module.
- ec_uart_pty: An opened file object to the raw EC UART PTY.
- ec_uart_pty_name: A string containing the name of the raw EC UART PTY.
- cmd_pipe: A socket.socket or multiprocessing.Connection object which
- represents the Interpreter side of the command pipe. This must be a
- bidirectional pipe. Commands and responses will utilize this pipe.
- dbg_pipe: A socket.socket or multiprocessing.Connection object which
- represents the Interpreter side of the debug pipe. This must be a
- unidirectional pipe with write capabilities. EC debug output will utilize
- this pipe.
- cmd_retries: An integer representing the number of attempts the console
- should retry commands if it receives an error.
- log_level: An integer representing the numeric value of the log level.
- inputs: A list of objects that the intpreter selects for reading.
- Initially, these are the EC UART and the command pipe.
- outputs: A list of objects that the interpreter selects for writing.
- ec_cmd_queue: A FIFO queue used for sending commands down to the EC UART.
- last_cmd: A string that represents the last command sent to the EC. If an
- error is encountered, the interpreter will attempt to retry this command
- up to COMMAND_RETRIES.
- enhanced_ec: A boolean indicating if the EC image that we are currently
- communicating with is enhanced or not. Enhanced EC images will support
- packed commands and host commands over the UART. This defaults to False
- and is changed depending on the result of an interrogation.
- interrogating: A boolean indicating if we are in the middle of interrogating
- the EC.
- connected: A boolean indicating if the interpreter is actually connected to
- the UART and listening.
- """
- def __init__(self, ec_uart_pty, cmd_pipe, dbg_pipe, log_level=logging.INFO,
- name=None):
- """Intializes an Interpreter object with the provided args.
-
- Args:
- ec_uart_pty: A string representing the EC UART to connect to.
- cmd_pipe: A socket.socket or multiprocessing.Connection object which
- represents the Interpreter side of the command pipe. This must be a
- bidirectional pipe. Commands and responses will utilize this pipe.
- dbg_pipe: A socket.socket or multiprocessing.Connection object which
- represents the Interpreter side of the debug pipe. This must be a
- unidirectional pipe with write capabilities. EC debug output will
- utilize this pipe.
- cmd_retries: An integer representing the number of attempts the console
- should retry commands if it receives an error.
- log_level: An optional integer representing the numeric value of the log
- level. By default, the log level will be logging.INFO (20).
- name: the console source name
- """
- # Create a unique logger based on the interpreter name
- interpreter_prefix = ('%s - ' % name) if name else ''
- logger = logging.getLogger('%sEC3PO.Interpreter' % interpreter_prefix)
- self.logger = LoggerAdapter(logger, {'pty': ec_uart_pty})
- self.ec_uart_pty = open(ec_uart_pty, 'a+')
- self.ec_uart_pty_name = ec_uart_pty
- self.cmd_pipe = cmd_pipe
- self.dbg_pipe = dbg_pipe
- self.cmd_retries = COMMAND_RETRIES
- self.log_level = log_level
- self.inputs = [self.ec_uart_pty, self.cmd_pipe]
- self.outputs = []
- self.ec_cmd_queue = Queue.Queue()
- self.last_cmd = ''
- self.enhanced_ec = False
- self.interrogating = False
- self.connected = True
-
- def __str__(self):
- """Show internal state of the Interpreter object.
-
- Returns:
- A string that shows the values of the attributes.
- """
- string = []
- string.append('%r' % self)
- string.append('ec_uart_pty: %s' % self.ec_uart_pty)
- string.append('cmd_pipe: %r' % self.cmd_pipe)
- string.append('dbg_pipe: %r' % self.dbg_pipe)
- string.append('cmd_retries: %d' % self.cmd_retries)
- string.append('log_level: %d' % self.log_level)
- string.append('inputs: %r' % self.inputs)
- string.append('outputs: %r' % self.outputs)
- string.append('ec_cmd_queue: %r' % self.ec_cmd_queue)
- string.append('last_cmd: \'%s\'' % self.last_cmd)
- string.append('enhanced_ec: %r' % self.enhanced_ec)
- string.append('interrogating: %r' % self.interrogating)
- return '\n'.join(string)
-
- def EnqueueCmd(self, command):
- """Enqueue a command to be sent to the EC UART.
-
- Args:
- command: A string which contains the command to be sent.
- """
- self.ec_cmd_queue.put(command)
- self.logger.log(1, 'Commands now in queue: %d', self.ec_cmd_queue.qsize())
-
- # Add the EC UART as an output to be serviced.
- if self.connected and self.ec_uart_pty not in self.outputs:
- self.outputs.append(self.ec_uart_pty)
-
- def PackCommand(self, raw_cmd):
- r"""Packs a command for use with error checking.
-
- For error checking, we pack console commands in a particular format. The
- format is as follows:
-
- &&[x][x][x][x]&{cmd}\n\n
- ^ ^ ^^ ^^ ^ ^-- 2 newlines.
- | | || || |-- the raw console command.
- | | || ||-- 1 ampersand.
- | | ||____|--- 2 hex digits representing the CRC8 of cmd.
- | |____|-- 2 hex digits reprsenting the length of cmd.
- |-- 2 ampersands
-
- Args:
- raw_cmd: A pre-packed string which contains the raw command.
-
- Returns:
- A string which contains the packed command.
- """
- # Don't pack a single carriage return.
- if raw_cmd != '\r':
- # The command format is as follows.
- # &&[x][x][x][x]&{cmd}\n\n
- packed_cmd = []
- packed_cmd.append('&&')
- # The first pair of hex digits are the length of the command.
- packed_cmd.append('%02x' % len(raw_cmd))
- # Then the CRC8 of cmd.
- packed_cmd.append('%02x' % Crc8(raw_cmd))
- packed_cmd.append('&')
- # Now, the raw command followed by 2 newlines.
- packed_cmd.append(raw_cmd)
- packed_cmd.append('\n\n')
- return ''.join(packed_cmd)
- else:
- return raw_cmd
-
- def ProcessCommand(self, command):
- """Captures the input determines what actions to take.
-
- Args:
- command: A string representing the command sent by the user.
- """
- if command == "disconnect":
- if self.connected:
- self.logger.debug('UART disconnect request.')
- # Drop all pending commands if any.
- while not self.ec_cmd_queue.empty():
- c = self.ec_cmd_queue.get()
- self.logger.debug('dropped: \'%s\'', c)
- if self.enhanced_ec:
- # Reset retry state.
- self.cmd_retries = COMMAND_RETRIES
- self.last_cmd = ''
- # Get the UART that the interpreter is attached to.
- fileobj = self.ec_uart_pty
- self.logger.debug('fileobj: %r', fileobj)
- # Remove the descriptor from the inputs and outputs.
- self.inputs.remove(fileobj)
- if fileobj in self.outputs:
- self.outputs.remove(fileobj)
- self.logger.debug('Removed fileobj. Remaining inputs: %r', self.inputs)
- # Close the file.
- fileobj.close()
- # Mark the interpreter as disconnected now.
- self.connected = False
- self.logger.debug('Disconnected from %s.', self.ec_uart_pty_name)
- return
-
- elif command == "reconnect":
- if not self.connected:
- self.logger.debug('UART reconnect request.')
- # Reopen the PTY.
- fileobj = open(self.ec_uart_pty_name, 'a+')
- self.logger.debug('fileobj: %r', fileobj)
- self.ec_uart_pty = fileobj
- # Add the descriptor to the inputs.
- self.inputs.append(fileobj)
- self.logger.debug('fileobj added. curr inputs: %r', self.inputs)
- # Mark the interpreter as connected now.
- self.connected = True
- self.logger.debug('Connected to %s.', self.ec_uart_pty_name)
- return
-
- elif command.startswith('enhanced'):
- self.enhanced_ec = command.split(' ')[1] == 'True'
- return
-
- # Ignore any other commands while in the disconnected state.
- self.logger.log(1, 'command: \'%s\'', command)
- if not self.connected:
- self.logger.debug('Ignoring command because currently disconnected.')
- return
-
- # Remove leading and trailing spaces only if this is an enhanced EC image.
- # For non-enhanced EC images, commands will be single characters at a time
- # and can be spaces.
- if self.enhanced_ec:
- command = command.strip(' ')
-
- # There's nothing to do if the command is empty.
- if len(command) == 0:
- return
-
- # Handle log level change requests.
- if command.startswith('loglevel'):
- self.logger.debug('Log level change request.')
- new_log_level = int(command.split(' ')[1])
- self.logger.logger.setLevel(new_log_level)
- self.logger.info('Log level changed to %d.', new_log_level)
- return
-
- # Check for interrogation command.
- if command == EC_SYN:
- # User is requesting interrogation. Send SYN as is.
- self.logger.debug('User requesting interrogation.')
- self.interrogating = True
- # Assume the EC isn't enhanced until we get a response.
- self.enhanced_ec = False
- elif self.enhanced_ec:
- # Enhanced EC images require the plaintext commands to be packed.
- command = self.PackCommand(command)
- # TODO(aaboagye): Make a dict of commands and keys and eventually,
- # handle partial matching based on unique prefixes.
-
- self.EnqueueCmd(command)
-
- def HandleCmdRetries(self):
- """Attempts to retry commands if possible."""
- if self.cmd_retries > 0:
- # The EC encountered an error. We'll have to retry again.
- self.logger.warning('Retrying command...')
- self.cmd_retries -= 1
- self.logger.warning('Retries remaining: %d', self.cmd_retries)
- # Retry the command and add the EC UART to the writers again.
- self.EnqueueCmd(self.last_cmd)
- self.outputs.append(self.ec_uart_pty)
- else:
- # We're out of retries, so just give up.
- self.logger.error('Command failed. No retries left.')
- # Clear the command in progress.
- self.last_cmd = ''
- # Reset the retry count.
- self.cmd_retries = COMMAND_RETRIES
-
- def SendCmdToEC(self):
- """Sends a command to the EC."""
- # If we're retrying a command, just try to send it again.
- if self.cmd_retries < COMMAND_RETRIES:
- cmd = self.last_cmd
- else:
- # If we're not retrying, we should not be writing to the EC if we have no
- # items in our command queue.
- assert not self.ec_cmd_queue.empty()
- # Get the command to send.
- cmd = self.ec_cmd_queue.get()
-
- # Send the command.
- self.ec_uart_pty.write(cmd)
- self.ec_uart_pty.flush()
- self.logger.log(1, 'Sent command to EC.')
-
- if self.enhanced_ec and cmd != EC_SYN:
- # Now, that we've sent the command, store the current command as the last
- # command sent. If we encounter an error string, we will attempt to retry
- # this command.
- if cmd != self.last_cmd:
- self.last_cmd = cmd
- # Reset the retry count.
- self.cmd_retries = COMMAND_RETRIES
-
- # If no command is pending to be sent, then we can remove the EC UART from
- # writers. Might need better checking for command retry logic in here.
- if self.ec_cmd_queue.empty():
- # Remove the EC UART from the writers while we wait for a response.
- self.logger.debug('Removing EC UART from writers.')
- self.outputs.remove(self.ec_uart_pty)
-
- def HandleECData(self):
- """Handle any debug prints from the EC."""
- self.logger.log(1, 'EC has data')
- # Read what the EC sent us.
- data = os.read(self.ec_uart_pty.fileno(), EC_MAX_READ)
- self.logger.log(1, 'got: \'%s\'', binascii.hexlify(data))
- if '&E' in data and self.enhanced_ec:
- # We received an error, so we should retry it if possible.
- self.logger.warning('Error string found in data.')
- self.HandleCmdRetries()
- return
-
- # If we were interrogating, check the response and update our knowledge
- # of the current EC image.
- if self.interrogating:
- self.enhanced_ec = data == EC_ACK
- if self.enhanced_ec:
- self.logger.debug('The current EC image seems enhanced.')
- else:
- self.logger.debug('The current EC image does NOT seem enhanced.')
- # Done interrogating.
- self.interrogating = False
- # For now, just forward everything the EC sends us.
- self.logger.log(1, 'Forwarding to user...')
- self.dbg_pipe.send(data)
-
- def HandleUserData(self):
- """Handle any incoming commands from the user.
-
- Raises:
- EOFError: Allowed to propagate through from self.cmd_pipe.recv().
- """
- self.logger.log(1, 'Command data available. Begin processing.')
- data = self.cmd_pipe.recv()
- # Process the command.
- self.ProcessCommand(data)
-
-
-def Crc8(data):
- """Calculates the CRC8 of data.
-
- The generator polynomial used is: x^8 + x^2 + x + 1.
- This is the same implementation that is used in the EC.
-
- Args:
- data: A string of data that we wish to calculate the CRC8 on.
-
- Returns:
- crc >> 8: An integer representing the CRC8 value.
- """
- crc = 0
- for byte in data:
- crc ^= (ord(byte) << 8)
- for _ in range(8):
- if crc & 0x8000:
- crc ^= (0x1070 << 3)
- crc <<= 1
- return crc >> 8
-
-
-def StartLoop(interp, shutdown_pipe=None):
- """Starts an infinite loop of servicing the user and the EC.
-
- StartLoop checks to see if there are any commands to process, processing them
- if any, and forwards EC output to the user.
-
- When sending a command to the EC, we send the command once and check the
- response to see if the EC encountered an error when receiving the command. An
- error condition is reported to the interpreter by a string with at least one
- '&' and 'E'. The full string is actually '&&EE', however it's possible that
- the leading ampersand or trailing 'E' could be dropped. If an error is
- encountered, the interpreter will retry up to the amount configured.
-
- Args:
- interp: An Interpreter object that has been properly initialised.
- shutdown_pipe: A file object for a pipe or equivalent that becomes readable
- (not blocked) to indicate that the loop should exit. Can be None to never
- exit the loop.
- """
- try:
- # This is used instead of "break" to avoid exiting the loop in the middle of
- # an iteration.
- continue_looping = True
-
- while continue_looping:
- # The inputs list is created anew in each loop iteration because the
- # Interpreter class sometimes modifies the interp.inputs list.
- if shutdown_pipe is None:
- inputs = interp.inputs
- else:
- inputs = list(interp.inputs)
- inputs.append(shutdown_pipe)
-
- readable, writeable, _ = select.select(inputs, interp.outputs, [])
-
- for obj in readable:
- # Handle any debug prints from the EC.
- if obj is interp.ec_uart_pty:
- interp.HandleECData()
-
- # Handle any commands from the user.
- elif obj is interp.cmd_pipe:
- try:
- interp.HandleUserData()
- except EOFError:
- interp.logger.debug(
- 'ec3po interpreter received EOF from cmd_pipe in '
- 'HandleUserData()')
- continue_looping = False
-
- elif obj is shutdown_pipe:
- interp.logger.debug(
- 'ec3po interpreter received shutdown pipe unblocked notification')
- continue_looping = False
-
- for obj in writeable:
- # Send a command to the EC.
- if obj is interp.ec_uart_pty:
- interp.SendCmdToEC()
-
- except KeyboardInterrupt:
- pass
-
- # TODO(crbug.com/894870): Stop suppressing all exceptions.
- except:
- traceback.print_exc()
-
- finally:
- interp.cmd_pipe.close()
- interp.dbg_pipe.close()
- interp.ec_uart_pty.close()
- if shutdown_pipe is not None:
- shutdown_pipe.close()
- interp.logger.debug('Exit ec3po interpreter loop for %s',
- interp.ec_uart_pty_name)
diff --git a/util/ec3po/interpreter_unittest.py b/util/ec3po/interpreter_unittest.py
deleted file mode 100755
index de2335158b..0000000000
--- a/util/ec3po/interpreter_unittest.py
+++ /dev/null
@@ -1,366 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2015 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.
-
-"""Unit tests for the EC-3PO interpreter."""
-
-from __future__ import print_function
-
-# pylint: disable=cros-logging-import
-import logging
-import mock
-import tempfile
-import unittest
-
-import interpreter
-import threadproc_shim
-
-class TestEnhancedECBehaviour(unittest.TestCase):
- """Test case to verify all enhanced EC interpretation tasks."""
- def setUp(self):
- """Setup the test harness."""
- # Setup logging with a timestamp, the module, and the log level.
- logging.basicConfig(level=logging.DEBUG,
- format=('%(asctime)s - %(module)s -'
- ' %(levelname)s - %(message)s'))
-
- # Create a tempfile that would represent the EC UART PTY.
- self.tempfile = tempfile.NamedTemporaryFile()
-
- # Create the pipes that the interpreter will use.
- self.cmd_pipe_user, self.cmd_pipe_itpr = threadproc_shim.Pipe()
- self.dbg_pipe_user, self.dbg_pipe_itpr = threadproc_shim.Pipe(duplex=False)
-
- # Mock the open() function so we can inspect reads/writes to the EC.
- self.ec_uart_pty = mock.mock_open()
- with mock.patch('__builtin__.open', self.ec_uart_pty):
- # Create an interpreter.
- self.itpr = interpreter.Interpreter(self.tempfile.name,
- self.cmd_pipe_itpr,
- self.dbg_pipe_itpr,
- log_level=logging.DEBUG,
- name="EC")
-
- @mock.patch('interpreter.os')
- def test_HandlingCommandsThatProduceNoOutput(self, mock_os):
- """Verify that the Interpreter correctly handles non-output commands.
-
- Args:
- mock_os: MagicMock object replacing the 'os' module for this test
- case.
- """
- # The interpreter init should open the EC UART PTY.
- expected_ec_calls = [mock.call(self.tempfile.name, 'a+')]
- # Have a command come in the command pipe. The first command will be an
- # interrogation to determine if the EC is enhanced or not.
- self.cmd_pipe_user.send(interpreter.EC_SYN)
- self.itpr.HandleUserData()
- # At this point, the command should be queued up waiting to be sent, so
- # let's actually send it to the EC.
- self.itpr.SendCmdToEC()
- expected_ec_calls.extend([mock.call().write(interpreter.EC_SYN),
- mock.call().flush()])
- # Now, assume that the EC sends only 1 response back of EC_ACK.
- mock_os.read.side_effect = [interpreter.EC_ACK]
- # When reading the EC, the interpreter will call file.fileno() to pass to
- # os.read().
- expected_ec_calls.append(mock.call().fileno())
- # Simulate the response.
- self.itpr.HandleECData()
-
- # Now that the interrogation was complete, it's time to send down the real
- # command.
- test_cmd = 'chan save'
- # Send the test command down the pipe.
- self.cmd_pipe_user.send(test_cmd)
- self.itpr.HandleUserData()
- self.itpr.SendCmdToEC()
- # Since the EC image is enhanced, we should have sent a packed command.
- expected_ec_calls.append(mock.call().write(self.itpr.PackCommand(test_cmd)))
- expected_ec_calls.append(mock.call().flush())
-
- # Now that the first command was sent, we should send another command which
- # produces no output. The console would send another interrogation.
- self.cmd_pipe_user.send(interpreter.EC_SYN)
- self.itpr.HandleUserData()
- self.itpr.SendCmdToEC()
- expected_ec_calls.extend([mock.call().write(interpreter.EC_SYN),
- mock.call().flush()])
- # Again, assume that the EC sends only 1 response back of EC_ACK.
- mock_os.read.side_effect = [interpreter.EC_ACK]
- # When reading the EC, the interpreter will call file.fileno() to pass to
- # os.read().
- expected_ec_calls.append(mock.call().fileno())
- # Simulate the response.
- self.itpr.HandleECData()
-
- # Now send the second test command.
- test_cmd = 'chan 0'
- self.cmd_pipe_user.send(test_cmd)
- self.itpr.HandleUserData()
- self.itpr.SendCmdToEC()
- # Since the EC image is enhanced, we should have sent a packed command.
- expected_ec_calls.append(mock.call().write(self.itpr.PackCommand(test_cmd)))
- expected_ec_calls.append(mock.call().flush())
-
- # Finally, verify that the appropriate writes were actually sent to the EC.
- self.ec_uart_pty.assert_has_calls(expected_ec_calls)
-
- @mock.patch('interpreter.os')
- def test_CommandRetryingOnError(self, mock_os):
- """Verify that commands are retried if an error is encountered.
-
- Args:
- mock_os: MagicMock object replacing the 'os' module for this test
- case.
- """
- # The interpreter init should open the EC UART PTY.
- expected_ec_calls = [mock.call(self.tempfile.name, 'a+')]
- # Have a command come in the command pipe. The first command will be an
- # interrogation to determine if the EC is enhanced or not.
- self.cmd_pipe_user.send(interpreter.EC_SYN)
- self.itpr.HandleUserData()
- # At this point, the command should be queued up waiting to be sent, so
- # let's actually send it to the EC.
- self.itpr.SendCmdToEC()
- expected_ec_calls.extend([mock.call().write(interpreter.EC_SYN),
- mock.call().flush()])
- # Now, assume that the EC sends only 1 response back of EC_ACK.
- mock_os.read.side_effect = [interpreter.EC_ACK]
- # When reading the EC, the interpreter will call file.fileno() to pass to
- # os.read().
- expected_ec_calls.append(mock.call().fileno())
- # Simulate the response.
- self.itpr.HandleECData()
-
- # Let's send a command that is received on the EC-side with an error.
- test_cmd = 'accelinfo'
- self.cmd_pipe_user.send(test_cmd)
- self.itpr.HandleUserData()
- self.itpr.SendCmdToEC()
- packed_cmd = self.itpr.PackCommand(test_cmd)
- expected_ec_calls.extend([mock.call().write(packed_cmd),
- mock.call().flush()])
- # Have the EC return the error string twice.
- mock_os.read.side_effect = ['&&EE', '&&EE']
- for i in range(2):
- # When reading the EC, the interpreter will call file.fileno() to pass to
- # os.read().
- expected_ec_calls.append(mock.call().fileno())
- # Simulate the response.
- self.itpr.HandleECData()
-
- # Since an error was received, the EC should attempt to retry the command.
- expected_ec_calls.extend([mock.call().write(packed_cmd),
- mock.call().flush()])
- # Verify that the retry count was decremented.
- self.assertEqual(interpreter.COMMAND_RETRIES-i-1, self.itpr.cmd_retries,
- 'Unexpected cmd_remaining count.')
- # Actually retry the command.
- self.itpr.SendCmdToEC()
-
- # Now assume that the last one goes through with no trouble.
- expected_ec_calls.extend([mock.call().write(packed_cmd),
- mock.call().flush()])
- self.itpr.SendCmdToEC()
-
- # Verify all the calls.
- self.ec_uart_pty.assert_has_calls(expected_ec_calls)
-
- def test_PackCommandsForEnhancedEC(self):
- """Verify that the interpreter packs commands for enhanced EC images."""
- # Assume current EC image is enhanced.
- self.itpr.enhanced_ec = True
- # Receive a command from the user.
- test_cmd = 'gettime'
- self.cmd_pipe_user.send(test_cmd)
- # Mock out PackCommand to see if it was called.
- self.itpr.PackCommand = mock.MagicMock()
- # Have the interpreter handle the command.
- self.itpr.HandleUserData()
- # Verify that PackCommand() was called.
- self.itpr.PackCommand.assert_called_once_with(test_cmd)
-
- def test_DontPackCommandsForNonEnhancedEC(self):
- """Verify the interpreter doesn't pack commands for non-enhanced images."""
- # Assume current EC image is not enhanced.
- self.itpr.enhanced_ec = False
- # Receive a command from the user.
- test_cmd = 'gettime'
- self.cmd_pipe_user.send(test_cmd)
- # Mock out PackCommand to see if it was called.
- self.itpr.PackCommand = mock.MagicMock()
- # Have the interpreter handle the command.
- self.itpr.HandleUserData()
- # Verify that PackCommand() was called.
- self.itpr.PackCommand.assert_not_called()
-
- @mock.patch('interpreter.os')
- def test_KeepingTrackOfInterrogation(self, mock_os):
- """Verify that the interpreter can track the state of the interrogation.
-
- Args:
- mock_os: MagicMock object replacing the 'os' module. for this test
- case.
- """
- # Upon init, the interpreter should assume that the current EC image is not
- # enhanced.
- self.assertFalse(self.itpr.enhanced_ec, msg=('State of enhanced_ec upon'
- ' init is not False.'))
-
- # Assume an interrogation request comes in from the user.
- self.cmd_pipe_user.send(interpreter.EC_SYN)
- self.itpr.HandleUserData()
-
- # Verify the state is now within an interrogation.
- self.assertTrue(self.itpr.interrogating, 'interrogating should be True')
- # The state of enhanced_ec should not be changed yet because we haven't
- # received a valid response yet.
- self.assertFalse(self.itpr.enhanced_ec, msg=('State of enhanced_ec is '
- 'not False.'))
-
- # Assume that the EC responds with an EC_ACK.
- mock_os.read.side_effect = [interpreter.EC_ACK]
- self.itpr.HandleECData()
-
- # Now, the interrogation should be complete and we should know that the
- # current EC image is enhanced.
- self.assertFalse(self.itpr.interrogating, msg=('interrogating should be '
- 'False'))
- self.assertTrue(self.itpr.enhanced_ec, msg='enhanced_ec sholud be True')
-
- # Now let's perform another interrogation, but pretend that the EC ignores
- # it.
- self.cmd_pipe_user.send(interpreter.EC_SYN)
- self.itpr.HandleUserData()
-
- # Verify interrogating state.
- self.assertTrue(self.itpr.interrogating, 'interrogating sholud be True')
- # We should assume that the image is not enhanced until we get the valid
- # response.
- self.assertFalse(self.itpr.enhanced_ec, 'enhanced_ec should be False now.')
-
- # Let's pretend that we get a random debug print. This should clear the
- # interrogating flag.
- mock_os.read.side_effect = '[1660.593076 HC 0x103]'
- self.itpr.HandleECData()
-
- # Verify that interrogating flag is cleared and enhanced_ec is still False.
- self.assertFalse(self.itpr.interrogating, 'interrogating should be False.')
- self.assertFalse(self.itpr.enhanced_ec,
- 'enhanced_ec should still be False.')
-
-
-class TestUARTDisconnection(unittest.TestCase):
- """Test case to verify interpreter disconnection/reconnection."""
- def setUp(self):
- """Setup the test harness."""
- # Setup logging with a timestamp, the module, and the log level.
- logging.basicConfig(level=logging.DEBUG,
- format=('%(asctime)s - %(module)s -'
- ' %(levelname)s - %(message)s'))
-
- # Create a tempfile that would represent the EC UART PTY.
- self.tempfile = tempfile.NamedTemporaryFile()
-
- # Create the pipes that the interpreter will use.
- self.cmd_pipe_user, self.cmd_pipe_itpr = threadproc_shim.Pipe()
- self.dbg_pipe_user, self.dbg_pipe_itpr = threadproc_shim.Pipe(duplex=False)
-
- # Mock the open() function so we can inspect reads/writes to the EC.
- self.ec_uart_pty = mock.mock_open()
- with mock.patch('__builtin__.open', self.ec_uart_pty):
- # Create an interpreter.
- self.itpr = interpreter.Interpreter(self.tempfile.name,
- self.cmd_pipe_itpr,
- self.dbg_pipe_itpr,
- log_level=logging.DEBUG,
- name="EC")
-
- # First, check that interpreter is initialized to connected.
- self.assertTrue(self.itpr.connected, ('The interpreter should be'
- ' initialized in a connected state'))
-
- def test_DisconnectStopsECTraffic(self):
- """Verify that when in disconnected state, no debug prints are sent."""
- # Let's send a disconnect command through the command pipe.
- self.cmd_pipe_user.send('disconnect')
- self.itpr.HandleUserData()
-
- # Verify interpreter is disconnected from EC.
- self.assertFalse(self.itpr.connected, ('The interpreter should be'
- 'disconnected.'))
- # Verify that the EC UART is no longer a member of the inputs. The
- # interpreter will never pull data from the EC if it's not a member of the
- # inputs list.
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs)
-
- def test_CommandsDroppedWhenDisconnected(self):
- """Verify that when in disconnected state, commands are dropped."""
- # Send a command, followed by 'disconnect'.
- self.cmd_pipe_user.send('taskinfo')
- self.itpr.HandleUserData()
- self.cmd_pipe_user.send('disconnect')
- self.itpr.HandleUserData()
-
- # Verify interpreter is disconnected from EC.
- self.assertFalse(self.itpr.connected, ('The interpreter should be'
- 'disconnected.'))
- # Verify that the EC UART is no longer a member of the inputs nor outputs.
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs)
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs)
-
- # Have the user send a few more commands in the disconnected state.
- command = 'help\n'
- for char in command:
- self.cmd_pipe_user.send(char)
- self.itpr.HandleUserData()
-
- # The command queue should be empty.
- self.assertEqual(0, self.itpr.ec_cmd_queue.qsize())
-
- # Now send the reconnect command.
- self.cmd_pipe_user.send('reconnect')
- with mock.patch('__builtin__.open', mock.mock_open()):
- self.itpr.HandleUserData()
-
- # Verify interpreter is connected.
- self.assertTrue(self.itpr.connected)
- # Verify that EC UART is a member of the inputs.
- self.assertTrue(self.itpr.ec_uart_pty in self.itpr.inputs)
- # Since no command was sent after reconnection, verify that the EC UART is
- # not a member of the outputs.
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs)
-
- def test_ReconnectAllowsECTraffic(self):
- """Verify that when connected, EC UART traffic is allowed."""
- # Let's send a disconnect command through the command pipe.
- self.cmd_pipe_user.send('disconnect')
- self.itpr.HandleUserData()
-
- # Verify interpreter is disconnected.
- self.assertFalse(self.itpr.connected, ('The interpreter should be'
- 'disconnected.'))
- # Verify that the EC UART is no longer a member of the inputs nor outputs.
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.inputs)
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs)
-
- # Issue reconnect command through the command pipe.
- self.cmd_pipe_user.send('reconnect')
- with mock.patch('__builtin__.open', mock.mock_open()):
- self.itpr.HandleUserData()
-
- # Verify interpreter is connected.
- self.assertTrue(self.itpr.connected, ('The interpreter should be'
- 'connected.'))
- # Verify that the EC UART is now a member of the inputs.
- self.assertTrue(self.itpr.ec_uart_pty in self.itpr.inputs)
- # Since we have issued no commands during the disconnected state, no
- # commands are pending and therefore the PTY should not be added to the
- # outputs.
- self.assertFalse(self.itpr.ec_uart_pty in self.itpr.outputs)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/util/ec3po/run_tests.sh b/util/ec3po/run_tests.sh
deleted file mode 100755
index f0ef348273..0000000000
--- a/util/ec3po/run_tests.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 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.
-
-# Discover all the unit tests in the ec3po directory and run them.
-python2 -m unittest discover -b -s util/ec3po/ -p *_unittest.py \
- && touch util/ec3po/.tests-passed
diff --git a/util/ec3po/threadproc_shim.py b/util/ec3po/threadproc_shim.py
deleted file mode 100644
index d5f5d19245..0000000000
--- a/util/ec3po/threadproc_shim.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2018 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.
-
-"""This is a shim library for the ec3po transition from subprocesses to threads.
-
-This is necessary because ec3po is split between the platform/ec/ and
-third_party/hdctools/ repositories, so the transition cannot happen atomically
-in one change. See http://b/79684405 #39.
-
-This contains only the multiprocessing objects or threading-oriented equivalents
-that are actually in use by ec3po. There is no need for further functionality,
-because this shim will be deleted after the migration is complete.
-
-TODO(b/79684405): Stop using multiprocessing.Pipe. The
-multiprocessing.Connection objects it returns serialize and deserialize objects
-(via Python pickling), which is necessary for sending them between processes,
-but is unnecessary overhead between threads. This will not be a simple change,
-because the ec3po Console and Interpreter classes use the underlying pipe/socket
-pairs with select/poll/epoll alongside other file descriptors. A drop-in
-replacement would be non-trivial and add undesirable complexity. The correct
-solution will be to split off the polling of the pipes/queues from this module
-into separate threads, so that they can be transitioned to another form of
-cross-thread synchronization, e.g. directly waiting on Queue.Queue.get() or a
-lower-level thread synchronization primitive.
-
-TODO(b/79684405): After this library has been updated to contain
-threading-oriented equivalents to its original multiprocessing implementations,
-and some reasonable amount of time has elapsed for thread-based ec3po problems
-to be discovered, migrate both the platform/ec/ and third_party/hdctools/ sides
-of ec3po off of this shim and then delete this file. IMPORTANT: This should
-wait until after completing the TODO above to stop using multiprocessing.Pipe!
-"""
-
-# Imports to bring objects into this namespace for users of this module.
-from Queue import Queue
-from multiprocessing import Pipe
-from threading import Thread as ThreadOrProcess
-
-# True if this module has ec3po using subprocesses, False if using threads.
-USING_SUBPROCS = False
-
-
-def _DoNothing():
- """Do-nothing function for use as a callback with DoIf()."""
-
-
-def DoIf(subprocs=_DoNothing, threads=_DoNothing):
- """Return a callback or not based on ec3po use of subprocesses or threads.
-
- Args:
- subprocs: callback that does not require any args - This will be returned
- (not called!) if and only if ec3po is using subprocesses. This is
- OPTIONAL, the default value is a do-nothing callback that returns None.
- threads: callback that does not require any args - This will be returned
- (not called!) if and only if ec3po is using threads. This is OPTIONAL,
- the default value is a do-nothing callback that returns None.
-
- Returns:
- Either the subprocs or threads argument will be returned.
- """
- return subprocs if USING_SUBPROCS else threads
-
-
-def Value(ctype, *args):
- return ctype(*args)
diff --git a/util/ec_flash.c b/util/ec_flash.c
deleted file mode 100644
index 3bae077200..0000000000
--- a/util/ec_flash.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "comm-host.h"
-#include "misc_util.h"
-#include "timer.h"
-
-static const uint32_t ERASE_ASYNC_TIMEOUT = 10 * SECOND;
-static const uint32_t ERASE_ASYNC_WAIT = 500 * MSEC;
-static const int FLASH_ERASE_BUSY_RV = -EECRESULT - EC_RES_BUSY;
-
-int ec_flash_read(uint8_t *buf, int offset, int size)
-{
- struct ec_params_flash_read p;
- int rv;
- int i;
-
- /* Read data in chunks */
- for (i = 0; i < size; i += ec_max_insize) {
- p.offset = offset + i;
- p.size = MIN(size - i, ec_max_insize);
- rv = ec_command(EC_CMD_FLASH_READ, 0,
- &p, sizeof(p), ec_inbuf, p.size);
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- return rv;
- }
- memcpy(buf + i, ec_inbuf, p.size);
- }
-
- return 0;
-}
-
-int ec_flash_verify(const uint8_t *buf, int offset, int size)
-{
- uint8_t *rbuf = malloc(size);
- int rv;
- int i;
-
- if (!rbuf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- rv = ec_flash_read(rbuf, offset, size);
- if (rv < 0) {
- free(rbuf);
- return rv;
- }
-
- for (i = 0; i < size; i++) {
- if (buf[i] != rbuf[i]) {
- fprintf(stderr, "Mismatch at offset 0x%x: "
- "want 0x%02x, got 0x%02x\n",
- i, buf[i], rbuf[i]);
- free(rbuf);
- return -1;
- }
- }
-
- free(rbuf);
- return 0;
-}
-
-/**
- * @param info_response pointer to response that will be filled on success
- * @return Zero or positive on success, negative on failure
- */
-static int get_flash_info_v2(struct ec_response_flash_info_2 *info_response)
-{
- struct ec_params_flash_info_2 info_params = {
- /*
- * By setting this to zero we indicate that we don't care
- * about getting the bank description in the response.
- */
- .num_banks_desc = 0
- };
-
- return ec_command(EC_CMD_FLASH_INFO, 2, &info_params,
- sizeof(info_params), info_response,
- sizeof(*info_response));
-}
-
-/**
- * @param info_response pointer to response that will be filled on success
- * @return Zero or positive on success, negative on failure
- */
-static int get_flash_info_v0(struct ec_response_flash_info *info_response)
-{
- return ec_command(EC_CMD_FLASH_INFO, 0, NULL, 0, info_response,
- sizeof(*info_response));
-}
-
-/**
- * @return Write size on success, negative on failure
- */
-static int get_flash_write_size(void)
-{
- int rv = 0;
- int write_size;
- int flash_info_version = -1;
- struct ec_response_flash_info info_response_v0 = { 0 };
- struct ec_response_flash_info_2 info_response_v2 = { 0 };
-
- if (ec_cmd_version_supported(EC_CMD_FLASH_INFO, 2))
- flash_info_version = 2;
- else if (ec_cmd_version_supported(EC_CMD_FLASH_INFO, 0))
- flash_info_version = 0;
-
- if (flash_info_version < 0)
- return -1;
-
- if (flash_info_version == 2) {
- rv = get_flash_info_v2(&info_response_v2);
- write_size = info_response_v2.write_ideal_size;
- } else {
- rv = get_flash_info_v0(&info_response_v0);
- write_size = info_response_v0.write_block_size;
- }
-
- if (rv < 0)
- return rv;
-
- return write_size;
-}
-
-int ec_flash_write(const uint8_t *buf, int offset, int size)
-{
- struct ec_params_flash_write *p =
- (struct ec_params_flash_write *)ec_outbuf;
- int write_size;
- int pdata_max_size = (int)(ec_max_outsize - sizeof(*p));
- int step;
- int rv;
- int i;
-
- /*
- * Determine whether we can use version 1 of the EC_CMD_FLASH_WRITE
- * command with more data, or only version 0.
- */
- if (!ec_cmd_version_supported(EC_CMD_FLASH_WRITE, EC_VER_FLASH_WRITE))
- pdata_max_size = EC_FLASH_WRITE_VER0_SIZE;
-
- write_size = get_flash_write_size();
- if (write_size < 0)
- return write_size;
-
- /*
- * shouldn't ever happen, but report an error rather than a division
- * by zero in the next statement.
- */
- if (write_size == 0)
- return -1;
-
- step = (pdata_max_size / write_size) * write_size;
-
- if (!step) {
- fprintf(stderr, "Write block size %d > max param size %d\n",
- write_size, pdata_max_size);
- return -1;
- }
-
- /* Write data in chunks */
- printf("Write size %d...\n", step);
-
- for (i = 0; i < size; i += step) {
- p->offset = offset + i;
- p->size = MIN(size - i, step);
- memcpy(p + 1, buf + i, p->size);
- rv = ec_command(EC_CMD_FLASH_WRITE, 0, p, sizeof(*p) + p->size,
- NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Write error at offset %d\n", i);
- return rv;
- }
- }
-
- return 0;
-}
-
-int ec_flash_erase(int offset, int size)
-{
- struct ec_params_flash_erase p;
-
- p.offset = offset;
- p.size = size;
-
- return ec_command(EC_CMD_FLASH_ERASE, 0, &p, sizeof(p), NULL, 0);
-}
-
-int ec_flash_erase_async(int offset, int size)
-{
- struct ec_params_flash_erase_v1 p = { 0 };
- uint32_t timeout = 0;
- int rv = FLASH_ERASE_BUSY_RV;
-
- p.cmd = FLASH_ERASE_SECTOR_ASYNC;
- p.params.offset = offset;
- p.params.size = size;
-
- rv = ec_command(EC_CMD_FLASH_ERASE, 1, &p, sizeof(p), NULL, 0);
-
- if (rv < 0)
- return rv;
-
- rv = FLASH_ERASE_BUSY_RV;
-
- while (rv < 0 && timeout < ERASE_ASYNC_TIMEOUT) {
- /*
- * The erase is not complete until FLASH_ERASE_GET_RESULT
- * returns success. It's important that we retry even when the
- * underlying ioctl returns an error (not just
- * FLASH_ERASE_BUSY_RV).
- *
- * See https://crrev.com/c/511805 for details.
- */
- usleep(ERASE_ASYNC_WAIT);
- timeout += ERASE_ASYNC_WAIT;
- p.cmd = FLASH_ERASE_GET_RESULT;
- rv = ec_command(EC_CMD_FLASH_ERASE, 1, &p, sizeof(p), NULL, 0);
- }
- return rv;
-}
diff --git a/util/ec_flash.h b/util/ec_flash.h
deleted file mode 100644
index f4aea3b7a3..0000000000
--- a/util/ec_flash.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#ifndef __UTIL_EC_FLASH_H
-#define __UTIL_EC_FLASH_H
-
-/**
- * Read EC flash memory
- *
- * @param buf Destination buffer
- * @param offset Offset in EC flash to read
- * @param size Number of bytes to read
- *
- * @return 0 if success, negative if error.
- */
-int ec_flash_read(uint8_t *buf, int offset, int size);
-
-/**
- * Verify EC flash memory
- *
- * @param buf Source buffer to verify against EC flash
- * @param offset Offset in EC flash to check
- * @param size Number of bytes to check
- *
- * @return 0 if success, negative if error.
- */
-int ec_flash_verify(const uint8_t *buf, int offset, int size);
-
-/**
- * Write EC flash memory
- *
- * @param buf Source buffer
- * @param offset Offset in EC flash to write
- * @param size Number of bytes to write
- *
- * @return 0 if success, negative if error.
- */
-int ec_flash_write(const uint8_t *buf, int offset, int size);
-
-/**
- * Erase EC flash memory
- *
- * @param offset Offset in EC flash to erase
- * @param size Number of bytes to erase
- *
- * @return 0 if success, negative if error.
- */
-int ec_flash_erase(int offset, int size);
-
-/**
- * Erase EC flash memory asynchronously
- *
- * @param offset Offset in EC flash to erase
- * @param size Number of bytes to erase
- *
- * @return 0 if success, negative if error.
- */
-int ec_flash_erase_async(int offset, int size);
-
-#endif
diff --git a/util/ec_panicinfo.c b/util/ec_panicinfo.c
deleted file mode 100644
index f614770619..0000000000
--- a/util/ec_panicinfo.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright 2016 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.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include "compile_time_macros.h"
-#include "ec_panicinfo.h"
-
-static void print_panic_reg(int regnum, const uint32_t *regs, int index)
-{
- static const char * const regname[] = {
- "r0 ", "r1 ", "r2 ", "r3 ", "r4 ",
- "r5 ", "r6 ", "r7 ", "r8 ", "r9 ",
- "r10", "r11", "r12", "sp ", "lr ",
- "pc "};
-
- printf("%s:", regname[regnum]);
- if (regs)
- printf("%08x", regs[index]);
- else
- printf(" ");
- printf((regnum & 3) == 3 ? "\n" : " ");
-}
-
-static int parse_panic_info_cm(const struct panic_data *pdata)
-{
- const uint32_t *lregs = pdata->cm.regs;
- const uint32_t *sregs = NULL;
- enum {
- ORIG_UNKNOWN = 0,
- ORIG_PROCESS,
- ORIG_HANDLER
- } origin = ORIG_UNKNOWN;
- int i;
- const char *panic_origins[3] = {"", "PROCESS", "HANDLER"};
-
- printf("Saved panic data:%s\n",
- (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
-
- if (pdata->struct_version == 2)
- origin = ((lregs[11] & 0xf) == 1 || (lregs[11] & 0xf) == 9) ?
- ORIG_HANDLER : ORIG_PROCESS;
-
- /*
- * In pdata struct, 'regs', which is allocated before 'frame', has
- * one less elements in version 1. Therefore, if the data is from
- * version 1, shift 'sregs' by one element to align with 'frame' in
- * version 1.
- */
- if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID)
- sregs = pdata->cm.frame - (pdata->struct_version == 1 ? 1 : 0);
-
- printf("=== %s EXCEPTION: %02x ====== xPSR: %08x ===\n",
- panic_origins[origin],
- lregs[1] & 0xff, sregs ? sregs[7] : -1);
- for (i = 0; i < 4; ++i)
- print_panic_reg(i, sregs, i);
- for (i = 4; i < 10; ++i)
- print_panic_reg(i, lregs, i - 1);
- print_panic_reg(10, lregs, 9);
- print_panic_reg(11, lregs, 10);
- print_panic_reg(12, sregs, 4);
- print_panic_reg(13, lregs, origin == ORIG_HANDLER ? 2 : 0);
- print_panic_reg(14, sregs, 5);
- print_panic_reg(15, sregs, 6);
-
- return 0;
-}
-
-static int parse_panic_info_nds32(const struct panic_data *pdata)
-{
- const uint32_t *regs = pdata->nds_n8.regs;
- uint32_t itype = pdata->nds_n8.itype;
- uint32_t ipc = pdata->nds_n8.ipc;
- uint32_t ipsw = pdata->nds_n8.ipsw;
-
- printf("Saved panic data:%s\n",
- (pdata->flags & PANIC_DATA_FLAG_OLD_HOSTCMD ? "" : " (NEW)"));
-
- printf("=== EXCEP: ITYPE=%x ===\n", itype);
- printf("R0 %08x R1 %08x R2 %08x R3 %08x\n",
- regs[0], regs[1], regs[2], regs[3]);
- printf("R4 %08x R5 %08x R6 %08x R7 %08x\n",
- regs[4], regs[5], regs[6], regs[7]);
- printf("R8 %08x R9 %08x R10 %08x R15 %08x\n",
- regs[8], regs[9], regs[10], regs[11]);
- printf("FP %08x GP %08x LP %08x SP %08x\n",
- regs[12], regs[13], regs[14], regs[15]);
- printf("IPC %08x IPSW %05x\n", ipc, ipsw);
- printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff));
-
- return 0;
-}
-
-int parse_panic_info(const struct panic_data *pdata)
-{
- /*
- * We only understand panic data with version <= 2. Warn the user
- * of higher versions.
- */
- if (pdata->struct_version > 2)
- fprintf(stderr,
- "Unknown panic data version (%d). "
- "Following data may be incorrect!\n",
- pdata->struct_version);
-
- /* Validate magic number */
- if (pdata->magic != PANIC_DATA_MAGIC)
- fprintf(stderr,
- "Incorrect panic magic (%d). "
- "Following data may be incorrect!\n",
- pdata->magic);
-
- switch (pdata->arch) {
- case PANIC_ARCH_CORTEX_M:
- return parse_panic_info_cm(pdata);
- case PANIC_ARCH_NDS32_N8:
- return parse_panic_info_nds32(pdata);
- default:
- fprintf(stderr, "Unknown architecture (%d).\n", pdata->arch);
- break;
- }
- return -1;
-}
diff --git a/util/ec_panicinfo.h b/util/ec_panicinfo.h
deleted file mode 100644
index f70c58e59f..0000000000
--- a/util/ec_panicinfo.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright 2016 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.
- */
-
-#ifndef EC_PANICINFO_H
-#define EC_PANICINFO_H
-
-#include "panic.h"
-
-/**
- * Prints panic information to stdout.
- *
- * @param pdata Panic information to print
- * @return 0 if success or non-zero error code if error.
- */
-int parse_panic_info(const struct panic_data *pdata);
-
-#endif /* EC_PANICINFO_H */
diff --git a/util/ec_parse_panicinfo.c b/util/ec_parse_panicinfo.c
deleted file mode 100644
index 5db8ed2e05..0000000000
--- a/util/ec_parse_panicinfo.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2016 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.
- *
- * Standalone utility to parse EC panicinfo.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include "ec_panicinfo.h"
-
-int main(int argc, char *argv[])
-{
- struct panic_data pdata;
-
- if (fread(&pdata, sizeof(pdata), 1, stdin) != 1) {
- fprintf(stderr, "Error reading panicinfo from stdin.\n");
- return 1;
- }
-
- return parse_panic_info(&pdata) ? 1 : 0;
-}
diff --git a/util/ec_sb_firmware_update.c b/util/ec_sb_firmware_update.c
deleted file mode 100644
index 72d3baf175..0000000000
--- a/util/ec_sb_firmware_update.c
+++ /dev/null
@@ -1,843 +0,0 @@
-/* Copyright 2014 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.
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "comm-host.h"
-#include "compile_time_macros.h"
-#include "ec_sb_firmware_update.h"
-#include "ec_commands.h"
-#include "lock/gec_lock.h"
-#include "misc_util.h"
-#include "powerd_lock.h"
-
-/* Subcommands: [check|update] */
-enum {
- OP_UNKNOWN = 0,
- OP_CHECK = 1,
- OP_UPDATE = 2,
-};
-
-struct delay_value {
- uint32_t steps;
- uint32_t value;
-};
-
-/* Default retry counter on errors */
-#define SB_FW_UPDATE_DEFAULT_RETRY_CNT 3
-/* Default delay value */
-#define SB_FW_UPDATE_DEFAULT_DELAY 1000
-
-#define DELAY_US_BEGIN 500000
-#define DELAY_US_END 1000000
-#define DELAY_US_BUSY 1000000
-#define DELAY_US_WRITE_END 50000
-
-static struct delay_value sb_delays[] = {
- {1, 100000},
- {2, 9000000},
- {4, 100000},
- {771, 30000},
- {2200, 10000},
- {0xFFFFFF, 50000},
-};
-
-enum fw_update_state {
- S0_READ_STATUS = 0,
- S1_READ_INFO = 1,
- S2_WRITE_PREPARE = 2,
- S3_READ_STATUS = 3,
- S4_WRITE_UPDATE = 4,
- S5_READ_STATUS = 5,
- S6_WRITE_BLOCK = 6,
- S7_READ_STATUS = 7,
- S8_WRITE_END = 8,
- S9_READ_STATUS = 9,
- S10_TERMINAL = 10
-};
-
-#define MAX_FW_IMAGE_NAME_SIZE 80
-
-/* Firmware Update Control Flags */
-enum {
- F_AC_PRESENT = 0x1, /* AC Present */
- F_VERSION_CHECK = 0x2, /* do firmware version check */
- F_UPDATE = 0x4, /* do firmware update */
- F_NEED_UPDATE = 0x8, /* need firmware update */
- F_POWERD_DISABLED = 0x10, /* powerd is disabled */
- F_LFCC_ZERO = 0x20, /* last full charge is zero */
- F_BATT_DISCHARGE = 0x40 /* battery discharging */
-};
-
-struct fw_update_ctrl {
- uint32_t flags; /* fw update control flags */
- int size; /* size of battery firmware image */
- char *ptr; /* current read pointer of the firmware image */
- int offset; /* current block write offset */
- struct sb_fw_header *fw_img_hdr; /*pointer to firmware image header*/
- struct sb_fw_update_status status;
- struct sb_fw_update_info info;
- int err_retry_cnt;
- int fec_err_retry_cnt;
- int busy_retry_cnt;
- int step_size;
- int rv;
- char image_name[MAX_FW_IMAGE_NAME_SIZE];
- char msg[256];
-};
-
-/*
- * Global Firmware Update Control Data Structure
- */
-static struct fw_update_ctrl fw_update;
-
-static uint32_t get_delay_value(uint32_t offset, uint32_t step_size)
-{
- int sz = ARRAY_SIZE(sb_delays);
- int i;
- for (i = 0; i < sz; i++) {
- if (offset <= sb_delays[i].steps * step_size)
- return sb_delays[i].value;
- }
- return sb_delays[sz-1].value;
-}
-
-static void print_battery_firmware_image_hdr(
- struct sb_fw_header *hdr)
-{
- printf("Latest Battery Firmware:\n");
- printf("\t%c%c%c%c hdr_ver:%04x major_minor:%04x\n",
- hdr->signature[0],
- hdr->signature[1],
- hdr->signature[2],
- hdr->signature[3],
- hdr->hdr_version, hdr->pkg_version_major_minor);
-
- printf("\tmaker:0x%04x hwid:0x%04x fw_ver:0x%04x tbl_ver:0x%04x\n",
- hdr->vendor_id, hdr->battery_type, hdr->fw_version,
- hdr->data_table_version);
-
- printf("\tbinary offset:0x%08x size:0x%08x chk_sum:0x%02x\n",
- hdr->fw_binary_offset, hdr->fw_binary_size, hdr->checksum);
-}
-
-static void print_info(struct sb_fw_update_info *info)
-{
- printf("\nCurrent Battery Firmware:\n");
- printf("\tmaker:0x%04x hwid:0x%04x fw_ver:0x%04x tbl_ver:0x%04x\n",
- info->maker_id,
- info->hardware_id,
- info->fw_version,
- info->data_version);
- return;
-}
-
-static void print_status(struct sb_fw_update_status *sts)
-{
- printf("f_maker_id:%d f_hw_id:%d f_fw_ver:%d f_permnent:%d\n",
- sts->v_fail_maker_id,
- sts->v_fail_hw_id,
- sts->v_fail_fw_version,
- sts->v_fail_permanent);
- printf("permanent failure:%d abnormal:%d fw_update:%d\n",
- sts->permanent_failure,
- sts->abnormal_condition,
- sts->fw_update_supported);
- printf("fw_update_mode:%d fw_corrupted:%d cmd_reject:%d\n",
- sts->fw_update_mode,
- sts->fw_corrupted,
- sts->cmd_reject);
- printf("invliad data:%d fw_fatal_err:%d fec_err:%d busy:%d\n",
- sts->invalid_data,
- sts->fw_fatal_error,
- sts->fec_error,
- sts->busy);
- printf("\n");
- return;
-}
-
-/* @return 1 (True) if img signature is valid */
-static int check_battery_firmware_image_signature(
- struct sb_fw_header *hdr)
-{
- return (hdr->signature[0] == 'B') &&
- (hdr->signature[1] == 'T') &&
- (hdr->signature[2] == 'F') &&
- (hdr->signature[3] == 'W');
-}
-
-/* @return 1 (True) if img checksum is valid. */
-static int check_battery_firmware_image_checksum(
- struct sb_fw_header *hdr)
-{
- int i;
- uint8_t sum = 0;
- uint8_t *img = (uint8_t *)hdr;
-
- img += hdr->fw_binary_offset;
- for (i = 0; i < hdr->fw_binary_size; i++)
- sum += img[i];
- sum += hdr->checksum;
- return sum == 0;
-}
-
-/* @return 1 (True) if img versions are ok to update. */
-static int check_battery_firmware_image_version(
- struct sb_fw_header *hdr,
- struct sb_fw_update_info *p)
-{
- /*
- * If the battery firmware has a newer fw version
- * or a newer data table version, then it is ok to update.
- */
- return (hdr->fw_version > p->fw_version)
- || (hdr->data_table_version > p->data_version);
-}
-
-
-static int check_battery_firmware_ids(
- struct sb_fw_header *hdr,
- struct sb_fw_update_info *p)
-{
- return ((hdr->vendor_id == p->maker_id) &&
- (hdr->battery_type == p->hardware_id));
-}
-
-/* check_if_need_update_fw
- * @return 1 (true) if need; 0 (false) if not.
- */
-static int check_if_valid_fw(
- struct sb_fw_header *hdr,
- struct sb_fw_update_info *info)
-{
- return check_battery_firmware_image_signature(hdr)
- && check_battery_firmware_ids(hdr, info)
- && check_battery_firmware_image_checksum(hdr);
-}
-
-/* check_if_need_update_fw
- * @return 1 (true) if need; 0 (false) if not.
- */
-static int check_if_need_update_fw(
- struct sb_fw_header *hdr,
- struct sb_fw_update_info *info)
-{
- return check_battery_firmware_image_version(hdr, info);
-}
-
-static void log_msg(struct fw_update_ctrl *fw_update,
- enum fw_update_state state, const char *msg)
-{
- sprintf(fw_update->msg,
- "Battery Firmware Updater State:%d %s", state, msg);
-}
-
-
-static char *read_fw_image(struct fw_update_ctrl *fw_update)
-{
- int size;
- char *buf;
- fw_update->size = 0;
- fw_update->ptr = NULL;
- fw_update->fw_img_hdr = (struct sb_fw_header *)NULL;
-
- /* Read the input file */
- buf = read_file(fw_update->image_name, &size);
- if (!buf)
- return NULL;
-
- fw_update->size = size;
- fw_update->ptr = buf;
- fw_update->fw_img_hdr = (struct sb_fw_header *)buf;
- print_battery_firmware_image_hdr(fw_update->fw_img_hdr);
-
- if (fw_update->fw_img_hdr->fw_binary_offset >= fw_update->size ||
- fw_update->size < 256) {
- printf("Load Firmware Image[%s] Error offset:%d size:%d\n",
- fw_update->image_name,
- fw_update->fw_img_hdr->fw_binary_offset,
- fw_update->size);
- free(buf);
- return NULL;
- }
- return buf;
-}
-
-static int get_status(struct sb_fw_update_status *status)
-{
- int rv = EC_RES_SUCCESS;
- int cnt = 0;
-
- struct ec_params_sb_fw_update *param =
- (struct ec_params_sb_fw_update *)ec_outbuf;
-
- struct ec_response_sb_fw_update *resp =
- (struct ec_response_sb_fw_update *)ec_inbuf;
-
- param->hdr.subcmd = EC_SB_FW_UPDATE_STATUS;
- do {
- usleep(SB_FW_UPDATE_DEFAULT_DELAY);
- rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
- param, sizeof(struct ec_sb_fw_update_header),
- resp, SB_FW_UPDATE_CMD_STATUS_SIZE);
- } while ((rv < 0) && (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT));
-
- if (rv < 0) {
- memset(status, 0, SB_FW_UPDATE_CMD_STATUS_SIZE);
- return -EC_RES_ERROR;
- }
-
- memcpy(status, resp->status.data, SB_FW_UPDATE_CMD_STATUS_SIZE);
- return EC_RES_SUCCESS;
-}
-
-static int get_info(struct sb_fw_update_info *info)
-{
- int rv = EC_RES_SUCCESS;
- int cnt = 0;
-
- struct ec_params_sb_fw_update *param =
- (struct ec_params_sb_fw_update *)ec_outbuf;
-
- struct ec_response_sb_fw_update *resp =
- (struct ec_response_sb_fw_update *)ec_inbuf;
-
- param->hdr.subcmd = EC_SB_FW_UPDATE_INFO;
- do {
- usleep(SB_FW_UPDATE_DEFAULT_DELAY);
- rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
- param, sizeof(struct ec_sb_fw_update_header),
- resp, SB_FW_UPDATE_CMD_INFO_SIZE);
- } while ((rv < 0) && (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT));
-
- if (rv < 0) {
- memset(info, 0, SB_FW_UPDATE_CMD_INFO_SIZE);
- return -EC_RES_ERROR;
- }
-
- memcpy(info, resp->info.data, SB_FW_UPDATE_CMD_INFO_SIZE);
- return EC_RES_SUCCESS;
-}
-
-static int send_subcmd(int subcmd)
-{
- int rv = EC_RES_SUCCESS;
-
- struct ec_params_sb_fw_update *param =
- (struct ec_params_sb_fw_update *)ec_outbuf;
-
- param->hdr.subcmd = subcmd;
- rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
- param, sizeof(struct ec_sb_fw_update_header), NULL, 0);
- if (rv < 0) {
- printf("Firmware Update subcmd:%d Error\n", subcmd);
- return -EC_RES_ERROR;
- }
- return EC_RES_SUCCESS;
-}
-
-static int write_block(struct fw_update_ctrl *fw_update,
- int offset, int bsize)
-{
- int rv;
-
- struct ec_params_sb_fw_update *param =
- (struct ec_params_sb_fw_update *)ec_outbuf;
-
- memcpy(param->write.data, fw_update->ptr+offset, bsize);
-
- param->hdr.subcmd = EC_SB_FW_UPDATE_WRITE;
- rv = ec_command(EC_CMD_SB_FW_UPDATE, 0,
- param, sizeof(struct ec_params_sb_fw_update), NULL, 0);
- if (rv < 0) {
- printf("Firmware Update Write Error ptr:%p offset@%x\n",
- fw_update->ptr, offset);
- return -EC_RES_ERROR;
- }
- return EC_RES_SUCCESS;
-}
-
-static void dump_data(uint8_t *data, int offset, int size)
-{
- int i = 0;
-
- printf("Offset:0x%X\n", offset);
- for (i = 0; i < size; i++) {
- if ((i%16) == 0)
- printf("\n");
- printf("%02X ", data[i]);
- }
- printf("\n");
-}
-
-static enum fw_update_state s0_read_status(struct fw_update_ctrl *fw_update)
-{
- if (fw_update->busy_retry_cnt == 0) {
- fw_update->rv = -1;
- log_msg(fw_update, S0_READ_STATUS, "Busy");
- return S10_TERMINAL;
- }
-
- fw_update->busy_retry_cnt--;
-
- fw_update->rv = get_status(&fw_update->status);
- if (fw_update->rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S0_READ_STATUS, "Interface Error");
- return S10_TERMINAL;
- }
-
- if (!((fw_update->status.abnormal_condition == 0)
- && (fw_update->status.fw_update_supported == 1))) {
- return S0_READ_STATUS;
- }
-
- if (fw_update->status.busy) {
- usleep(DELAY_US_BUSY);
- return S0_READ_STATUS;
- } else
- return S1_READ_INFO;
-}
-
-static enum fw_update_state s1_read_battery_info(
- struct fw_update_ctrl *fw_update)
-{
- int rv;
-
- if (fw_update->err_retry_cnt == 0) {
- fw_update->rv = -1;
- log_msg(fw_update, S1_READ_INFO, "Retry Error");
- return S10_TERMINAL;
- }
-
- fw_update->err_retry_cnt--;
-
- rv = get_info(&fw_update->info);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S1_READ_INFO, "Interface Error");
- return S10_TERMINAL;
- }
- print_info(&fw_update->info);
-
- sprintf(fw_update->image_name,
- "/lib/firmware/battery/maker.%04x.hwid.%04x.bin",
- fw_update->info.maker_id,
- fw_update->info.hardware_id);
-
- if (NULL == read_fw_image(fw_update)) {
- fw_update->rv = 0;
- log_msg(fw_update, S1_READ_INFO, "Open Image File");
- return S10_TERMINAL;
- }
-
- rv = get_status(&fw_update->status);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S1_READ_INFO, "Interface Error");
- return S10_TERMINAL;
- }
-
- rv = check_if_valid_fw(fw_update->fw_img_hdr, &fw_update->info);
- if (rv == 0) {
- fw_update->rv = -EC_RES_INVALID_PARAM;
- log_msg(fw_update, S1_READ_INFO, "Invalid Firmware");
- return S10_TERMINAL;
- }
-
- rv = check_if_need_update_fw(fw_update->fw_img_hdr, &fw_update->info);
- if (rv == 0 && (fw_update->flags & F_VERSION_CHECK)) {
- fw_update->rv = 0;
- log_msg(fw_update, S1_READ_INFO, "Latest Firmware");
- return S10_TERMINAL;
- }
-
- fw_update->flags |= F_NEED_UPDATE;
-
- if (!(fw_update->flags & F_UPDATE)) {
- fw_update->rv = 0;
- return S10_TERMINAL;
- }
-
- if (!(fw_update->flags & F_AC_PRESENT)) {
- fw_update->rv = 0;
- log_msg(fw_update, S1_READ_INFO,
- "Require AC Adapter Connected.");
- return S10_TERMINAL;
- }
-
- if ((fw_update->flags & F_BATT_DISCHARGE) &&
- (fw_update->flags & F_AC_PRESENT)) {
- /*
- * If battery discharge due to battery learning mode,
- * we can't update battery FW, because device will shutdown
- * during FW update.
- */
- fw_update->rv = 0;
- log_msg(fw_update, S1_READ_INFO,
- "battery can't update in learning mode");
- return S10_TERMINAL;
- }
-
- return S2_WRITE_PREPARE;
-}
-
-static enum fw_update_state s2_write_prepare(struct fw_update_ctrl *fw_update)
-{
- int rv;
-
- rv = disable_power_management();
- if (0 == rv)
- fw_update->flags |= F_POWERD_DISABLED;
-
- rv = send_subcmd(EC_SB_FW_UPDATE_PREPARE);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S2_WRITE_PREPARE, "Interface Error");
- return S10_TERMINAL;
- }
- return S3_READ_STATUS;
-}
-
-static enum fw_update_state s3_read_status(struct fw_update_ctrl *fw_update)
-{
- int rv;
-
- rv = get_status(&fw_update->status);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S3_READ_STATUS, "Interface Error");
- return S10_TERMINAL;
- }
- return S4_WRITE_UPDATE;
-
-}
-
-static enum fw_update_state s4_write_update(struct fw_update_ctrl *fw_update)
-{
- int rv;
-
- rv = send_subcmd(EC_SB_FW_UPDATE_BEGIN);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S4_WRITE_UPDATE, "Interface Error");
- return S10_TERMINAL;
- }
- usleep(DELAY_US_BEGIN);
- return S5_READ_STATUS;
-}
-
-static enum fw_update_state s5_read_status(struct fw_update_ctrl *fw_update)
-{
- int rv = get_status(&fw_update->status);
-
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S5_READ_STATUS, "Interface Error");
- return S10_TERMINAL;
- }
- if (fw_update->status.fw_update_mode == 0)
- return S2_WRITE_PREPARE;
-
- /* Init Write Block Loop Controls */
- fw_update->ptr += fw_update->fw_img_hdr->fw_binary_offset;
- fw_update->size -= fw_update->fw_img_hdr->fw_binary_offset;
- fw_update->offset = 0;
-
- return S6_WRITE_BLOCK;
-}
-
-static enum fw_update_state s6_write_block(struct fw_update_ctrl *fw_update)
-{
- int rv;
- int bsize;
- int offset = fw_update->offset;
-
- if (offset >= fw_update->size)
- return S8_WRITE_END;
-
- bsize = fw_update->step_size;
-
- if ((offset & 0xFFFF) == 0x0)
- printf("\n%X\n", offset);
-
- if (fw_update->fec_err_retry_cnt == 0) {
- fw_update->rv = -1;
- log_msg(fw_update, S6_WRITE_BLOCK, "FEC Retry Error");
- return S10_TERMINAL;
- }
- fw_update->fec_err_retry_cnt--;
-
- rv = write_block(fw_update, offset, bsize);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S6_WRITE_BLOCK, "Interface Error");
- return S10_TERMINAL;
- }
-
- /*
- * Add more delays after the last few (3) block writes.
- * 3 is chosen based on current test results.
- */
- if ((offset + 3*fw_update->step_size) >= fw_update->size)
- usleep(DELAY_US_WRITE_END);
-
- usleep(get_delay_value(offset, fw_update->step_size));
-
- return S7_READ_STATUS;
-}
-
-static enum fw_update_state s7_read_status(struct fw_update_ctrl *fw_update)
-{
- int rv;
- int offset = fw_update->offset;
- int bsize;
- int cnt = 0;
-
- bsize = fw_update->step_size;
- do {
- usleep(SB_FW_UPDATE_DEFAULT_DELAY);
- rv = get_status(&fw_update->status);
- if (rv) {
- dump_data(fw_update->ptr+offset, offset, bsize);
- print_status(&fw_update->status);
- fw_update->rv = -1;
- log_msg(fw_update, S7_READ_STATUS, "Interface Error");
- return S10_TERMINAL;
- }
- } while (fw_update->status.busy &&
- (cnt++ < SB_FW_UPDATE_DEFAULT_RETRY_CNT));
-
- if (fw_update->status.fec_error) {
- dump_data(fw_update->ptr+offset, offset, bsize);
- print_status(&fw_update->status);
- fw_update->rv = 0;
- return S6_WRITE_BLOCK;
- }
- if (fw_update->status.permanent_failure ||
- fw_update->status.v_fail_permanent) {
- dump_data(fw_update->ptr+offset, offset, bsize);
- print_status(&fw_update->status);
- fw_update->rv = -1;
- log_msg(fw_update, S7_READ_STATUS, "Battery Permanent Error");
- return S8_WRITE_END;
- }
- if (fw_update->status.v_fail_maker_id ||
- fw_update->status.v_fail_hw_id ||
- fw_update->status.v_fail_fw_version ||
- fw_update->status.fw_corrupted ||
- fw_update->status.cmd_reject ||
- fw_update->status.invalid_data ||
- fw_update->status.fw_fatal_error) {
-
- dump_data(fw_update->ptr+offset, offset, bsize);
- print_status(&fw_update->status);
- fw_update->rv = 0;
- return S1_READ_INFO;
- }
-
- fw_update->fec_err_retry_cnt = SB_FW_UPDATE_FEC_ERROR_RETRY_CNT;
- fw_update->offset += fw_update->step_size;
- return S6_WRITE_BLOCK;
-}
-
-
-static enum fw_update_state s8_write_end(struct fw_update_ctrl *fw_update)
-{
- int rv;
-
- rv = send_subcmd(EC_SB_FW_UPDATE_END);
- if (rv && (0 == fw_update->rv)) {
- fw_update->rv = -1;
- log_msg(fw_update, S8_WRITE_END, "Interface Error");
- }
-
- if (fw_update->rv)
- return S10_TERMINAL;
-
- usleep(DELAY_US_END);
- fw_update->busy_retry_cnt = SB_FW_UPDATE_BUSY_ERROR_RETRY_CNT;
- return S9_READ_STATUS;
-}
-
-static enum fw_update_state s9_read_status(struct fw_update_ctrl *fw_update)
-{
- int rv;
-
- if (fw_update->busy_retry_cnt == 0) {
- fw_update->rv = -1;
- log_msg(fw_update, S9_READ_STATUS, "Busy");
- return S10_TERMINAL;
- }
-
- rv = get_status(&fw_update->status);
- if (rv) {
- fw_update->rv = -1;
- log_msg(fw_update, S9_READ_STATUS, "Interface Error");
- return S10_TERMINAL;
- }
- if ((fw_update->status.fw_update_mode == 1)
- || (fw_update->status.busy == 1)) {
- usleep(SB_FW_UPDATE_DEFAULT_DELAY);
- fw_update->busy_retry_cnt--;
- return S9_READ_STATUS;
- }
- log_msg(fw_update, S9_READ_STATUS, "Complete");
- fw_update->flags &= ~F_NEED_UPDATE;
- return S10_TERMINAL;
-}
-
-
-typedef enum fw_update_state (*fw_state_func)(struct fw_update_ctrl *fw_update);
-
-fw_state_func state_table[] = {
- s0_read_status,
- s1_read_battery_info,
- s2_write_prepare,
- s3_read_status,
- s4_write_update,
- s5_read_status,
- s6_write_block,
- s7_read_status,
- s8_write_end,
- s9_read_status
-};
-
-
-/**
- * Update Smart Battery Firmware
- *
- * @param fw_update struct fw_update_ctrl
- *
- * @return 0 if success, negative if error.
- */
-static int ec_sb_firmware_update(struct fw_update_ctrl *fw_update)
-{
- enum fw_update_state state;
-
- fw_update->err_retry_cnt = SB_FW_UPDATE_ERROR_RETRY_CNT;
- fw_update->fec_err_retry_cnt = SB_FW_UPDATE_FEC_ERROR_RETRY_CNT;
- fw_update->busy_retry_cnt = SB_FW_UPDATE_BUSY_ERROR_RETRY_CNT;
- fw_update->step_size = SB_FW_UPDATE_CMD_WRITE_BLOCK_SIZE;
-
- state = S0_READ_STATUS;
- while (state != S10_TERMINAL)
- state = state_table[state](fw_update);
-
- if (fw_update->fw_img_hdr)
- free(fw_update->fw_img_hdr);
-
- return fw_update->rv;
-}
-
-#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */
-void usage(char *argv[])
-{
- printf("Usage: %s [check|update]\n"
- " check: check if AC Adaptor is connected.\n"
- " update: trigger battery firmware update.\n",
- argv[0]);
-}
-
-int main(int argc, char *argv[])
-{
- int rv = 0;
- int op = OP_UNKNOWN;
- uint8_t val = 0;
-
- if (argc != 2) {
- usage(argv);
- return -1;
- }
-
- if (!strcmp(argv[1], "check"))
- op = OP_CHECK;
- else if (!strcmp(argv[1], "update"))
- op = OP_UPDATE;
- else {
- op = OP_UNKNOWN;
- usage(argv);
- return -1;
- }
-
- if (comm_init_dev(NULL)) {
- printf("Couldn't initialize /dev.\n");
- return -1;
- }
-
- if (comm_init_buffer()) {
- fprintf(stderr, "Couldn't initialize buffers\n");
- return -1;
- }
-
- fw_update.flags = 0;
- rv = ec_readmem(EC_MEMMAP_BATT_FLAG, sizeof(val), &val);
- if (rv <= 0) {
- printf("EC Memmap read error:%d\n", rv);
- goto out;
- }
-
- rv = get_status(&fw_update.status);
- if (rv) {
- fw_update.rv = -1;
- log_msg(&fw_update, S1_READ_INFO, "Interface Error");
- return S10_TERMINAL;
- }
-
- if (fw_update.status.fw_update_mode) {
- /*
- * Previous battery firmware update was interrupted,
- * and we may not detect the presence of AC correctly.
- * Therefore, lie about our AC status.
- */
- fw_update.flags |= F_AC_PRESENT;
- printf("Assuming AC_PRESENT due to interrupted FW update\n");
- } else {
- if (val & EC_BATT_FLAG_AC_PRESENT) {
- fw_update.flags |= F_AC_PRESENT;
- printf("AC_PRESENT\n");
- }
- }
-
- if (val & EC_BATT_FLAG_DISCHARGING) {
- fw_update.flags |= F_BATT_DISCHARGE;
- printf("Battery is in discharge state\n");
- }
- rv = ec_readmem(EC_MEMMAP_BATT_LFCC, sizeof(val), &val);
- if (rv <= 0) {
- printf("EC Memmap read error:%d\n", rv);
- goto out;
- }
- if (val == 0)
- fw_update.flags |= F_LFCC_ZERO;
-
- if (op == OP_UPDATE)
- fw_update.flags |= F_UPDATE;
-
- fw_update.flags |= F_VERSION_CHECK;
-
- rv = ec_sb_firmware_update(&fw_update);
- printf("Battery Firmware Update:0x%02x %s\n%s\n",
- fw_update.flags,
- ((rv) ? "FAIL " : " "),
- fw_update.msg);
-
- /* Update battery firmware update interface to be protected */
- if (!(fw_update.flags & F_NEED_UPDATE))
- rv |= send_subcmd(EC_SB_FW_UPDATE_PROTECT);
-
- if (fw_update.flags & F_POWERD_DISABLED)
- rv |= restore_power_management();
-out:
- if (rv)
- return -1;
- else
- return fw_update.flags & (F_LFCC_ZERO | F_NEED_UPDATE);
-}
diff --git a/util/ec_sb_firmware_update.h b/util/ec_sb_firmware_update.h
deleted file mode 100644
index 5bddebaf4a..0000000000
--- a/util/ec_sb_firmware_update.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright 2014 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.
- *
- * Smart battery Firmware Update driver.
- * Ref: Common Smart Battery System Interface Specification v8.0.
- *
- * cmd.0x35, Write Word
- * 0x1000: Prepare to Update
- * 0x2000: End of Update
- * 0xF000: Update Firmware
- *
- * cmd.0x35, Read Word
- * Firmware Update Status
- *
- * cmd.0x36 Write Block
- * Send 32 byte firmware image
- *
- * cmd.0x37 Read Word
- * Get Battery Information
- * sequence:=b1,b0,b3,b2,b5,b5,b7,b6
- *
- * Command Sequence for Battery FW Update
- *
- * 0. cmd.0x35.read
- * 1. cmd.0x37.read
- * 2. cmd.0x35.write.0x1000
- * 3. cmd.0x35.read.status (optional)
- * 4. cmd.0x35.write.0xF000
- * 5. cmd.0x35.read.status
- * if bit8-0, go to step 2
- * 6. cmd.0x36.write.32byte
- * 7. cmd.0x35.read.status
- * if FEC.b13=1, go to step 6
- * if fatal.b12=1, go to step 2
- * if b11,b10,b9,b2,b1,b0; go to step 1
- * if b5,b3; go to step 8
- * (repeat 6,7)
- * 8. cmd.0x36.write.0x2000
- * 9. cmd.0x35.read.status
- */
-
-#ifndef __UTIL_EC_SB_FIRMWARE_UPDATE_H
-#define __UTIL_EC_SB_FIRMWARE_UPDATE_H
-
-struct sb_fw_header {
- uint8_t signature[4]; /* "BTFW" */
- uint16_t hdr_version; /* 0x0100 */
- uint16_t pkg_version_major_minor;
-
- uint16_t vendor_id; /* 8,9 */
- uint16_t battery_type; /* A B */
-
- uint16_t fw_version; /* C D */
- uint16_t data_table_version; /* E F */
- uint32_t fw_binary_offset; /*0x10 0x11 0x12 0x13 */
- uint32_t fw_binary_size; /* 0x14 0x15 0x16 0x17 */
- uint8_t checksum; /* 0x18 */
-};
-
-/**
- * sb.fw.update.cmd.0x35, Read Word
- * Firmware Update Status
- */
-struct sb_fw_update_status {
- uint16_t v_fail_maker_id:1; /* b0 */
- uint16_t v_fail_hw_id:1; /* b1 */
- uint16_t v_fail_fw_version:1; /* b2 */
- uint16_t v_fail_permanent:1; /* b3 */
-
- uint16_t rsvd5:1; /* b4 */
- uint16_t permanent_failure:1; /* b5 */
- uint16_t abnormal_condition:1; /* b6 */
- uint16_t fw_update_supported:1; /* b7 */
-
- uint16_t fw_update_mode:1; /* b8 */
- uint16_t fw_corrupted:1; /* b9 */
- uint16_t cmd_reject:1; /* b10 */
- uint16_t invalid_data:1; /* b11 */
-
- uint16_t fw_fatal_error:1; /* b12 */
- uint16_t fec_error:1; /* b13 */
- uint16_t busy:1; /* b14 */
- uint16_t rsvd15:1; /* b15 */
-} __packed;
-
-/**
- * sb.fw.update.cmd.0x37 Read Word
- * Get Battery Information
- * sequence:=b1,b0,b3,b2,b5,b5,b7,b6
- */
-struct sb_fw_update_info {
- uint16_t maker_id; /* b0, b1 */
- uint16_t hardware_id; /* b2, b3 */
- uint16_t fw_version; /* b4, b5 */
- uint16_t data_version;/* b6, b7 */
-} __packed;
-
-/**
- * smart.battery.maker.id
- */
-enum sb_maker_id {
- sb_maker_id_lgc = 0x0001, /* b0=0; b1=1 */
- sb_maker_id_panasonic = 0x0002,
- sb_maker_id_sanyo = 0x0003,
- sb_maker_id_sony = 0x0004,
- sb_maker_id_simplo = 0x0005,
- sb_maker_id_celxpert = 0x0006,
-};
-
-/*
- * Ref: Common Smart Battery System Interface Specification v8.0 page 21-24.
- * case 1. If permanent error:b5,b3, go to setp8.
- * case 2. If error:b11,b10,b9 b2,b1,b0, go to step1. Retry < 3 times.
- * case 3. If firmware update fatal error:b12, go to step2. Retry < 3 times.
- * In order to simply the implementation, I merged case 2 and 3.
- * If firmware update fatal error:b12, go to step1 as well.
- * case 4. If error.FEC.b13=1, go to step6. Retry < 3 times.
- * case 5. If battery interface is busy, retry < 10 times.
- * Delay 1 second between retries.
- */
-#define SB_FW_UPDATE_ERROR_RETRY_CNT 2
-#define SB_FW_UPDATE_FEC_ERROR_RETRY_CNT 2
-#define SB_FW_UPDATE_BUSY_ERROR_RETRY_CNT 4
-
-#endif
diff --git a/util/ec_uartd.c b/util/ec_uartd.c
deleted file mode 100644
index 4fc0323619..0000000000
--- a/util/ec_uartd.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Copyright 2011 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.
- */
-/* ec_uartd.c - UART daemon for BD-ICDI-B board for EC debugging
- *
- * based on chromeos_public/src/third_party/hdctools/src/ftdiuart.c
- *
- * compile with:
- * gcc -o ftdi_uartd ftdi_uartd.c -lftdi
- */
-
-/* Force header files to define grantpt(), posix_openpt(), cfmakeraw() */
-#define _DEFAULT_SOURCE /* Newer glibc */
-#define _BSD_SOURCE /* Older glibc */
-#define _XOPEN_SOURCE 600
-/* Force header file to declare ptsname_r(), etc. */
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <errno.h>
-#include <fcntl.h>
-#include <ftdi.h>
-#include <getopt.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <termios.h>
-#include <unistd.h>
-
-static const int ftdi_id[][2] = { {0x0403, 0xbcda},
- {0x0403, 0xbcd9} };
-
-int main(int argc, char **argv)
-{
- struct ftdi_context fcontext;
- struct termios tty_cfg;
- char ptname[PATH_MAX];
- char buf[1024];
- int fd;
- int rv;
- int i;
- int device_opened;
-
- /* Init */
- if (ftdi_init(&fcontext) < 0) {
- fprintf(stderr, "ftdi_init failed\n");
- return 1;
- }
-
- /* Open interface B (UART) in the FTDI device and set 115kbaud */
- ftdi_set_interface(&fcontext, INTERFACE_B);
- device_opened = 0;
- for (i = 0; i < sizeof(ftdi_id) / sizeof(ftdi_id[0]); ++i) {
- rv = ftdi_usb_open(&fcontext, ftdi_id[i][0], ftdi_id[i][1]);
- if (rv >= 0) {
- fprintf(stderr, "Using FTDI device %04x:%04x\n",
- ftdi_id[i][0], ftdi_id[i][1]);
- device_opened = 1;
- break;
- }
- }
- if (!device_opened) {
- fprintf(stderr, "error opening ftdi device: %d (%s)\n",
- rv, ftdi_get_error_string(&fcontext));
- return 2;
- }
-
- rv = ftdi_set_baudrate(&fcontext, 115200);
- if (rv < 0) {
- fprintf(stderr, "error setting baudrate: %d (%s)\n",
- rv, ftdi_get_error_string(&fcontext));
- return 2;
- }
-
- /* Set DTR; this muxes RX on the ICDI board */
- ftdi_setdtr(&fcontext, 1);
-
- /* Open the pty */
- fd = posix_openpt(O_RDWR | O_NOCTTY);
- if (fd == -1) {
- perror("opening pty master");
- return 3;
- }
- if (grantpt(fd) == -1) {
- perror("grantpt");
- return 3;
- }
- if (unlockpt(fd) == -1) {
- perror("unlockpt");
- return 3;
- }
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
- perror("fcntl setfl -> nonblock");
- return 3;
- }
- if (ptsname_r(fd, ptname, PATH_MAX) != 0) {
- perror("getting name of pty");
- return 3;
- }
- fprintf(stderr, "pty name = %s\n", ptname);
- if (!isatty(fd)) {
- perror("not a TTY device\n");
- return 3;
- }
- cfmakeraw(&tty_cfg);
- tcsetattr(fd, TCSANOW, &tty_cfg);
- if (chmod(ptname, 0666) == -1) {
- perror("setting pty attributes");
- return 3;
- }
-
- /* Read and write data forever */
- while (1) {
- int bytes = read(fd, buf, sizeof(buf));
- if (bytes > 0) {
- rv = ftdi_write_data(&fcontext, buf, bytes);
- if (rv != bytes) {
- perror("writing to uart");
- break;
- }
- }
-
- usleep(1000);
-
- bytes = ftdi_read_data(&fcontext, buf, sizeof(buf));
- if (bytes > 0) {
- int bytes_remaining = bytes;
- char *buf_ptr = buf;
-
-retry_write:
- while (bytes_remaining &&
- ((bytes = write(fd, buf_ptr,
- bytes_remaining)) > 0)) {
- buf_ptr += bytes;
- bytes_remaining -= bytes;
- }
-
- if ((bytes == -1) &&
- ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
- goto retry_write;
-
- if (bytes == -1)
- perror("writing ftdi data to pty");
-
- } else if (bytes < 0) {
- perror("failed ftdi_read_data");
- break;
- }
- }
-
- /* Cleanup */
- close(fd);
- ftdi_usb_close(&fcontext);
- ftdi_deinit(&fcontext);
- return 0;
-}
diff --git a/util/ecst.c b/util/ecst.c
deleted file mode 100644
index 22f9f6c0e8..0000000000
--- a/util/ecst.c
+++ /dev/null
@@ -1,2519 +0,0 @@
-/*
- * Copyright 2015 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.
- */
-
-/*
- * This utility is used to generate/modify the firmware header which holds
- * data used by NPCX ROM code (booter).
- */
-
-#include "ecst.h"
-
-/* Global Variables */
-enum verbose_level g_verbose;
-char input_file_name[NAME_SIZE];
-char output_file_name[NAME_SIZE];
-char arg_file_name[NAME_SIZE];
-char g_hdr_input_name[NAME_SIZE];
-char hdr_args[MAX_ARGS][ARG_SIZE];
-char tmp_hdr_args[MAX_ARGS][ARG_SIZE];
-FILE *input_file_pointer;
-FILE *g_hfd_pointer;
-FILE *arg_file_pointer;
-FILE *api_file_pointer;
-FILE *g_hdr_pointer;
-void *gh_console;
-unsigned short g_text_atrib;
-unsigned short g_bg_atrib;
-enum calc_type g_calc_type;
-unsigned int ptr_fw_addr;
-unsigned int fw_offset;
-int is_ptr_merge;
-unsigned int g_ram_start_address;
-unsigned int g_ram_size;
-int api_file_size_bytes;
-int is_mrider15 = FALSE;
-
-/* Chips information, RAM start address and RAM size. */
-struct chip_info chip_info[] = {{NPCX5M5G_RAM_ADDR, NPCX5M5G_RAM_SIZE},
- {NPCX5M6G_RAM_ADDR, NPCX5M6G_RAM_SIZE},
- {NPCX7M5X_RAM_ADDR, NPCX7M5X_RAM_SIZE},
- {NPCX7M6X_RAM_ADDR, NPCX7M6X_RAM_SIZE},
- {NPCX7M7X_RAM_ADDR, NPCX7M7X_RAM_SIZE},};
-
-/* Support chips name strings */
-const char *supported_chips = "npcx5m5g, npcx5m6g, npcx7m5g, npcx7m6g, "
- "npcx7m6f, npcx7m6fb, npcx7m6fc, npcx7m7wb, or npcx7m7wc";
-
-static unsigned int calc_api_csum_bin(void);
-static unsigned int initialize_crc_32(void);
-static unsigned int update_crc_32(unsigned int crc, char c);
-static unsigned int finalize_crc_32(unsigned int crc);
-
-/*
- * Expects a path in `path`, returning a transformation as follows in `result`
- *
- * The last element of `path` is prefixed with `prefix` if the resulting
- * string fits in an array of `resultsz` characters (incl 0-termination).
- *
- * On success returns TRUE,
- * on error (path too long) prints an error on the TERR channel
- * and returns FALSE.
- */
-static int splice_into_path(char *result, const char *path, int resultsz,
- const char *prefix) {
- char *last_delim, *result_last_delim;
-
- if (strlen(path) + strlen(prefix) + 1 > resultsz) {
- my_printf(TERR,
- "\n\nfilename '%s' with prefix '%s' too long\n\n",
- path, prefix);
- my_printf(TINF,
- "\n\n%zu + %zu + 1 needs to fit in %d bytes\n\n",
- strlen(path), strlen(prefix), resultsz);
- return FALSE;
- }
-
- last_delim = strrchr(path, '/');
-
- if (last_delim == NULL) {
- /* no delimiter: prefix and exit */
- sprintf(result, "%s%s", prefix, path);
- return TRUE;
- }
-
- /* delimiter: copy, then patch in the prefix */
- strcpy(result, path);
- result_last_delim = result + (last_delim - path);
- sprintf(result_last_delim + 1, "%s%s", prefix, last_delim + 1);
- return TRUE;
-}
-
-/*
- *----------------------------------------------------------------------
- * Function: main()
- * Parameters: argc, argv
- * Return: 0
- * Description: Parse the arguments
- * Chose manipulation routine according to arguments
- *
- * In case of bin, save optional parameters given by user
- *----------------------------------------------------------------------
- */
-int main(int argc, char *argv[])
-
-{
-
- int mode_choose = FALSE;
- /* Do we get a bin File? */
- int main_fw_hdr_flag = FALSE;
- /* Do we get a API bin File? */
- int main_api_flag = FALSE;
- /* Do we need to create a BootLoader Header file? */
- int main_hdr_flag = FALSE;
-
- /* Following variables: common to all modes */
- int main_status = TRUE;
- unsigned int main_temp = 0L;
- char main_str_temp[TMP_STR_SIZE];
- char *end_ptr;
-
- int arg_num;
- int arg_ind;
- int tmp_ind;
- int tmp_arg_num;
- int cur_arg_index;
- FILE *tmp_file;
-
- /* Following variables are used when bin file is provided */
- struct tbinparams bin_params;
-
- bin_params.bin_params = 0;
-
- input_file_name[0] = '\0';
- memset(input_file_name, 0, NAME_SIZE);
- output_file_name[0] = '\0';
- memset(output_file_name, 0, NAME_SIZE);
- arg_file_name[0] = '\0';
- memset(arg_file_name, 0, NAME_SIZE);
- g_hdr_input_name[0] = '\0';
- memset(g_hdr_input_name, 0, NAME_SIZE);
-
- /* Initialize Global variables */
- g_verbose = NO_VERBOSE;
-
- g_ram_start_address = chip_info[DEFAULT_CHIP].ram_addr;
- g_ram_size = chip_info[DEFAULT_CHIP].ram_size;
-
- /* Set default values */
- g_calc_type = CALC_TYPE_NONE;
- bin_params.spi_max_clk = SPI_MAX_CLOCK_DEFAULT;
- bin_params.spi_clk_ratio = 0x00;
- bin_params.spi_read_mode = SPI_READ_MODE_DEFAULT;
- bin_params.fw_load_addr =
- chip_info[DEFAULT_CHIP].ram_addr;
- bin_params.fw_ep =
- chip_info[DEFAULT_CHIP].ram_addr;
- bin_params.fw_err_detec_s_addr = FW_CRC_START_ADDR;
- bin_params.fw_err_detec_e_addr = FW_CRC_START_ADDR;
- bin_params.flash_size = FLASH_SIZE_DEFAULT;
- bin_params.fw_hdr_offset = 0;
-
- ptr_fw_addr = 0x00000000;
- fw_offset = 0x00000000;
- is_ptr_merge = FALSE;
-
- /* Get Standard Output Handler */
-
- /* Wrong Number of Arguments ? No problem */
- if (argc < 3)
- exit_with_usage();
-
- /* Read all arguments to local array. */
- for (arg_num = 0; arg_num < argc; arg_num++)
- strncpy(hdr_args[arg_num], argv[arg_num], ARG_SIZE);
-
- /* Loop all arguments. */
- /* Parse the Arguments - supports ecrp and bin */
- for (arg_ind = 1; arg_ind < arg_num; arg_ind++) {
- /* -h display help screen */
- if (str_cmp_no_case(hdr_args[arg_ind], "-h") == 0)
- exit_with_usage();
-
- /* -v verbose */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-v") == 0)
- g_verbose = REGULAR_VERBOSE;
-
- /* Super verbose. */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-vv") == 0)
- g_verbose = SUPER_VERBOSE;
-
- else if (str_cmp_no_case(hdr_args[arg_ind],
- "-mode") == 0) {
- mode_choose = TRUE;
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%s", main_str_temp) != 1)) {
- my_printf(TERR, "\nCannot read operation mode");
- my_printf(TERR, ", bt, bh or api. !\n");
- main_status = FALSE;
- } else {
- /* bt, bh and api should not coexist */
- if (main_fw_hdr_flag ||
- main_api_flag ||
- main_hdr_flag) {
- my_printf(TERR, "\nOperation modes bt");
- my_printf(TERR, ", bh, and api should");
- my_printf(TERR, " not coexist.\n");
- main_status = FALSE;
- }
-
- if (str_cmp_no_case(main_str_temp, "bt") == 0)
- main_fw_hdr_flag = TRUE;
- else if (str_cmp_no_case(main_str_temp,
- "bh") == 0)
- main_hdr_flag = TRUE;
- else if (str_cmp_no_case(main_str_temp,
- "api") == 0)
- main_api_flag = TRUE;
- else {
- my_printf(TERR,
- "\nInvalid operation mode ");
- my_printf(TERR,
- "(%s)\n", main_str_temp);
- main_status = FALSE;
- }
- }
- }
-
- else if (str_cmp_no_case(hdr_args[arg_ind], "-chip") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%s",
- main_str_temp) != 1)) {
- my_printf(TERR, "\nCannot read chip name %s.\n",
- supported_chips);
- main_status = FALSE;
- } else {
- if ((str_cmp_no_case(main_str_temp,
- "npcx7m7wb") == 0) ||
- (str_cmp_no_case(main_str_temp,
- "npcx7m7wc") == 0)) {
- if ((bin_params.bin_params
- & BIN_FW_LOAD_START_ADDR) ==
- 0x00000000)
- bin_params.fw_load_addr =
- chip_info[NPCX7M7].ram_addr;
-
- if ((bin_params.bin_params
- & BIN_FW_ENTRY_POINT) ==
- 0x00000000)
- bin_params.fw_ep =
- chip_info[NPCX7M7].ram_addr;
-
- g_ram_start_address =
- chip_info[NPCX7M7].ram_addr;
- g_ram_size =
- chip_info[NPCX7M7].ram_size;
- } else if ((str_cmp_no_case(main_str_temp,
- "npcx7m6f") == 0) ||
- (str_cmp_no_case(main_str_temp,
- "npcx7m6fb") == 0) ||
- (str_cmp_no_case(main_str_temp,
- "npcx7m6fc") == 0) ||
- (str_cmp_no_case(main_str_temp,
- "npcx7m6g") == 0)) {
- if ((bin_params.bin_params
- & BIN_FW_LOAD_START_ADDR) ==
- 0x00000000)
- bin_params.fw_load_addr =
- chip_info[NPCX7M6].ram_addr;
-
- if ((bin_params.bin_params &
- BIN_FW_ENTRY_POINT) ==
- 0x00000000)
- bin_params.fw_ep =
- chip_info[NPCX7M6].ram_addr;
-
- g_ram_start_address =
- chip_info[NPCX7M6].ram_addr;
- g_ram_size =
- chip_info[NPCX7M6].ram_size;
- } else if (str_cmp_no_case(main_str_temp,
- "npcx7m5g") == 0) {
- if ((bin_params.bin_params
- & BIN_FW_LOAD_START_ADDR) ==
- 0x00000000)
- bin_params.fw_load_addr =
- chip_info[NPCX7M5].ram_addr;
-
- if ((bin_params.bin_params &
- BIN_FW_ENTRY_POINT) ==
- 0x00000000)
- bin_params.fw_ep =
- chip_info[NPCX7M5].ram_addr;
-
- g_ram_start_address =
- chip_info[NPCX7M5].ram_addr;
- g_ram_size =
- chip_info[NPCX7M5].ram_size;
- } else if (str_cmp_no_case(main_str_temp,
- "npcx5m5g") == 0) {
- if ((bin_params.bin_params
- & BIN_FW_LOAD_START_ADDR) ==
- 0x00000000)
- bin_params.fw_load_addr =
- chip_info[NPCX5M5G].ram_addr;
-
- if ((bin_params.bin_params &
- BIN_FW_ENTRY_POINT) == 0x00000000)
- bin_params.fw_ep =
- chip_info[NPCX5M5G].ram_addr;
-
- g_ram_start_address =
- chip_info[NPCX5M5G].ram_addr;
- g_ram_size =
- chip_info[NPCX5M5G].ram_size;
-
- is_mrider15 = TRUE;
-
- } else if (str_cmp_no_case(main_str_temp,
- "npcx5m6g") == 0) {
- if ((bin_params.bin_params &
- BIN_FW_LOAD_START_ADDR) ==
- 0x00000000)
- bin_params.fw_load_addr =
- chip_info[NPCX5M6G].ram_addr;
-
- if ((bin_params.bin_params &
- BIN_FW_ENTRY_POINT) ==
- 0x00000000)
- bin_params.fw_ep =
- chip_info[NPCX5M6G].ram_addr;
-
- g_ram_start_address =
- chip_info[NPCX5M6G].ram_addr;
- g_ram_size =
- chip_info[NPCX5M6G].ram_size;
-
- is_mrider15 = TRUE;
-
- } else {
- my_printf(TERR,
- "\nInvalid chip name (%s) ",
- main_str_temp);
- my_printf(TERR, ", it should be %s.\n",
- supported_chips);
- main_status = FALSE;
- }
-
- }
- /* -argfile Read argument file. File name must be after it.*/
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-argfile") == 0) {
- arg_ind++;
- if (arg_ind < arg_num) {
- strncpy(arg_file_name,
- hdr_args[arg_ind],
- sizeof(arg_file_name) - 1);
- arg_file_pointer = fopen(arg_file_name, "rt");
- if (arg_file_pointer == NULL) {
- my_printf(TERR,
- "\n\nCannot open %s\n\n",
- arg_file_name);
- main_status = FALSE;
- } else {
- cur_arg_index = arg_ind;
-
- /* Copy the arguments to temp array. */
- for (tmp_ind = 0;
- (tmp_ind + arg_ind + 1) < arg_num;
- tmp_ind++)
- strncpy(tmp_hdr_args[tmp_ind],
- hdr_args
- [tmp_ind+arg_ind+1],
- ARG_SIZE);
-
- tmp_arg_num = tmp_ind;
-
- /* Read arguments from file to array */
- for (arg_ind++;
- fscanf(arg_file_pointer,
- "%s",
- hdr_args[arg_ind]) == 1;
- arg_ind++)
- ;
-
- fclose(arg_file_pointer);
- arg_file_pointer = NULL;
-
- /* Copy back the restored arguments. */
- for (tmp_ind = 0;
- tmp_ind < tmp_arg_num;
- tmp_ind++) {
- strncpy(hdr_args[arg_ind++],
- tmp_hdr_args[tmp_ind],
- ARG_SIZE);
- }
- arg_num = arg_ind;
- arg_ind = cur_arg_index;
- }
-
- } else {
- my_printf(TERR,
- "\nMissing Argument File Name\n");
- main_status = FALSE;
- }
- /* -i get input file name. */
- } else if (str_cmp_no_case(hdr_args[arg_ind], "-i") == 0) {
- arg_ind++;
- if (arg_ind < arg_num) {
- strncpy(input_file_name,
- hdr_args[arg_ind],
- sizeof(input_file_name) - 1);
- } else {
- my_printf(TERR, "\nMissing Input File Name\n");
- main_status = FALSE;
- }
- /* -o Get output file name. */
- } else if (str_cmp_no_case(hdr_args[arg_ind], "-o") == 0) {
- arg_ind++;
- if (arg_ind < arg_num) {
- strncpy(output_file_name,
- hdr_args[arg_ind],
- sizeof(output_file_name) - 1);
- } else {
- my_printf(TERR,
- "\nMissing Output File Name.\n");
- main_status = FALSE;
- }
- /* -usearmrst get FW entry point from FW image offset 4.*/
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-usearmrst") == 0) {
- if ((bin_params.bin_params &
- BIN_FW_ENTRY_POINT) != 0x00000000) {
- my_printf(TERR, "\n-usearmrst not allowed, ");
- my_printf(TERR, "FW entry point already set ");
- my_printf(TERR, "using -fwep !\n");
- main_status = FALSE;
- } else
- bin_params.bin_params |=
- BIN_FW_USER_ARM_RESET;
- /* -nohcrs disable header CRC*/
- } else if (str_cmp_no_case(hdr_args[arg_ind], "-nohcrc") == 0)
- bin_params.bin_params |=
- BIN_FW_HDR_CRC_DISABLE;
- /* -ph merg header in BIN file. */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-ph") == 0) {
- bin_params.bin_params |=
- BIN_FW_HDR_OFFSET;
- if ((strlen(hdr_args[arg_ind+1]) == 0) ||
- (sscanf(hdr_args[arg_ind+1],
- "%x",
- &main_temp) != 1))
- bin_params.fw_hdr_offset = 0;
- else {
- arg_ind++;
- bin_params.fw_hdr_offset = main_temp;
- }
- /* -spimaxclk Get SPI flash max clock. */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-spimaxclk") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%d", &main_temp) != 1)) {
- my_printf(TERR, "\nCannot read SPI Flash Max");
- my_printf(TERR, " Clock !\n");
- main_status = FALSE;
- } else
- bin_params.spi_max_clk =
- (unsigned char) main_temp;
- /* -spiclkratio Get SPI flash max clock ratio. */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-spiclkratio") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%d", &main_temp) != 1)) {
- my_printf(TERR,
- "\nCannot read SPI Clock Ratio\n");
- main_status = FALSE;
- } else
- bin_params.spi_clk_ratio =
- (unsigned char)main_temp;
-
- /* spireadmode get SPI read mode. */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-spireadmode") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%20s",
- main_str_temp) != 1)) {
- my_printf(TERR, "\nCannot read SPI Flash");
- my_printf(TERR, " Read Mode !\n");
- main_status = FALSE;
- } else {
- if (str_cmp_no_case(main_str_temp,
- SPI_NORMAL_MODE_VAL) == 0)
- bin_params.spi_read_mode =
- (unsigned char) SPI_NORMAL_MODE;
- else if (str_cmp_no_case(main_str_temp,
- SPI_SINGLE_MODE_VAL) == 0)
- bin_params.spi_read_mode =
- (unsigned char)
- SPI_SINGLE_MODE;
- else if (str_cmp_no_case(main_str_temp,
- SPI_DUAL_MODE_VAL) == 0)
- bin_params.spi_read_mode =
- (unsigned char)
- SPI_DUAL_MODE;
- else if (str_cmp_no_case(main_str_temp,
- SPI_QUAD_MODE_VAL) == 0)
- bin_params.spi_read_mode =
- (unsigned char)
- SPI_QUAD_MODE;
- else {
- my_printf(TERR,
- "\nInvalid SPI Flash Read ");
- my_printf(TERR,
- "Mode (%s), it should be ",
- main_str_temp);
- my_printf(TERR,
- "normal, singleMode, ");
- my_printf(TERR,
- "dualMode or quadMode !\n");
- main_status = FALSE;
- }
- }
-
- }
- /* -unlimburst enable unlimited burst */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-unlimburst") == 0)
- bin_params.bin_params |= BIN_UNLIM_BURST_ENABLE;
- /* -nofcrc disable FW CRC. */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-nofcrc") == 0)
- bin_params.bin_params |= BIN_FW_CRC_DISABLE;
-
- /* -fwloadaddr, Get the FW load address. */
- else if (str_cmp_no_case(hdr_args[arg_ind],
- "-fwloadaddr") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%x",
- &main_temp) != 1)) {
- my_printf(TERR, "\nCannot read FW Load ");
- my_printf(TERR, "\nstart address !\n");
- main_status = FALSE;
- } else {
- /* Check that the address is 16-bytes aligned */
- if ((main_temp &
- ADDR_16_BYTES_ALIGNED_MASK) != 0) {
- my_printf(TERR,
- "\nFW load address start ");
- my_printf(TERR,
- "address (0x%08X) is not ",
- main_temp);
- my_printf(TERR,
- "16-bytes aligned !\n");
- main_status = FALSE;
- } else {
- bin_params.fw_load_addr =
- main_temp;
- bin_params.bin_params |=
- BIN_FW_LOAD_START_ADDR;
- }
- }
- /* -fwep, Get the FW entry point. */
- } else if (str_cmp_no_case(hdr_args[arg_ind], "-fwep") == 0) {
- if ((bin_params.bin_params & BIN_FW_USER_ARM_RESET)
- != 0x00000000) {
- my_printf(TERR,
- "\n-fwep not allowed, FW entry point");
- my_printf(TERR,
- " already set using -usearmrst!\n");
- main_status = FALSE;
- } else {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%x",
- &main_temp) != 1)) {
- my_printf(TERR,
- "\nCan't read FW E-Point\n");
- main_status = FALSE;
- } else {
- bin_params.fw_ep =
- main_temp;
- bin_params.bin_params |=
- BIN_FW_ENTRY_POINT;
- }
- }
- /*
- * -crcstart, Get the address from where to calculate
- * the FW CRC.
- */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-crcstart") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%x",
- &main_temp) != 1)) {
- my_printf(TERR,
- "\nCannot read FW CRC");
- my_printf(TERR,
- " start address !\n");
- main_status = FALSE;
- } else {
- bin_params.fw_err_detec_e_addr =
- bin_params.fw_err_detec_e_addr -
- bin_params.fw_err_detec_s_addr
- + main_temp;
- bin_params.fw_err_detec_s_addr =
- main_temp;
- bin_params.bin_params |= BIN_FW_CKS_START;
- }
- /* -crcsize, Get the area size that need to be CRCed. */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-crcsize") == 0) {
- arg_ind++;
- main_temp = 0x00;
- if (hdr_args[arg_ind] == NULL)
- end_ptr = NULL;
- else
- main_temp = strtol(hdr_args[arg_ind],
- &end_ptr, 16);
-
- if (hdr_args[arg_ind] == end_ptr) {
- my_printf(TERR,
- "\nCannot read FW CRC area size !\n");
- main_status = FALSE;
- } else {
- bin_params.fw_err_detec_e_addr =
- bin_params.fw_err_detec_s_addr
- + main_temp - 1;
- bin_params.bin_params |= BIN_FW_CKS_SIZE;
- }
- }
- /* -fwlen, Get the FW length. */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-fwlen") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%x",
- &main_temp) != 1)) {
- my_printf(TERR, "\nCannot read FW length !\n");
- main_status = FALSE;
- } else {
- bin_params.fw_len = main_temp;
- bin_params.bin_params |= BIN_FW_LENGTH;
- }
- }
- /* flashsize, Get the flash size. */
- else if (str_cmp_no_case(hdr_args[arg_ind],
- "-flashsize") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%d",
- &main_temp) != 1)) {
- my_printf(TERR, "\nCannot read Flash size !\n");
- main_status = FALSE;
- } else
- bin_params.flash_size = main_temp;
- /* -apisign, Get the method for error detect calculation. */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-apisign") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%s",
- main_str_temp) != 1)) {
- my_printf(TERR, "\nCannot read API sign, CRC,");
- my_printf(TERR, " CheckSum or None. !\n");
- main_status = FALSE;
- } else {
- if (!main_api_flag) {
- my_printf(TERR, "\n-apisign is valid ");
- my_printf(TERR, "-only with -api.\n");
- main_status = FALSE;
- }
-
- if (str_cmp_no_case(main_str_temp, "crc") == 0)
- g_calc_type = CALC_TYPE_CRC;
-
- else if (str_cmp_no_case(main_str_temp,
- "checksum") == 0)
- g_calc_type = CALC_TYPE_CHECKSUM;
-
- else {
- my_printf(TERR,
- "\nInvalid API sign (%s)\n",
- main_str_temp);
- main_status = FALSE;
- }
-
- }
- /* -pointer, Get the FW image address. */
- } else if (str_cmp_no_case(hdr_args[arg_ind],
- "-pointer") == 0) {
- arg_ind++;
- if ((hdr_args[arg_ind] == NULL) ||
- (sscanf(hdr_args[arg_ind],
- "%x",
- &main_temp) != 1)) {
- my_printf(TERR,
- "\nCannot read FW Image address !\n");
- main_status = FALSE;
- } else {
- /* Check that the address is 16-bytes aligned */
- if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK)
- != 0) {
- my_printf(TERR,
- "\nFW Image address (0x%08X)"
- " isn't 16-bytes aligned !\n",
- main_temp);
- main_status = FALSE;
- }
-
- if (main_temp > MAX_FLASH_SIZE) {
- my_printf(TERR,
- "\nPointer address (0x%08X) ",
- main_temp);
- my_printf(TERR,
- "is higher from flash size");
- my_printf(TERR,
- " (0x%08X) !\n",
- MAX_FLASH_SIZE);
- main_status = FALSE;
- } else {
- ptr_fw_addr = main_temp;
- is_ptr_merge = FALSE;
- }
- }
- }
- /* -bhoffset, BootLoader Header Offset (BH location in BT). */
- else if (str_cmp_no_case(hdr_args[arg_ind], "-bhoffset") == 0) {
- arg_ind++;
- main_temp = 0x00;
- if (hdr_args[arg_ind] == NULL)
- end_ptr = NULL;
- else
- main_temp = strtol(hdr_args[arg_ind],
- &end_ptr, 16);
-
- if (hdr_args[arg_ind] == end_ptr) {
- my_printf(TERR, "\nCannot read BootLoader");
- my_printf(TERR, " Header Offset !\n");
- main_status = FALSE;
- } else {
- /* Check that the address is 16-bytes aligned */
- if ((main_temp & ADDR_16_BYTES_ALIGNED_MASK)
- != 0) {
- my_printf(TERR,
- "\nFW Image address (0x%08X) ",
- main_temp);
- my_printf(TERR,
- "is not 16-bytes aligned!\n");
- }
-
- if (main_temp > MAX_FLASH_SIZE) {
- my_printf(TERR,
- "\nFW Image address (0x%08X)",
- main_temp);
- my_printf(TERR,
- " is higher from flash size");
- my_printf(TERR,
- " (0x%08X) !\n",
- MAX_FLASH_SIZE);
- main_status = FALSE;
- } else {
- fw_offset = main_temp;
- is_ptr_merge = TRUE;
- }
- }
- } else {
- my_printf(TERR,
- "\nUnknown flag: %s\n",
- hdr_args[arg_ind]);
- main_status = FALSE;
- }
- }
-
- /*
- * If the input and output file have the same name then exit with error.
- */
- if (strcmp(output_file_name, input_file_name) == 0) {
- my_printf(TINF,
- "Input file name (%s) should be differed from\n",
- input_file_name);
- my_printf(TINF, "Output file name (%s).\n", output_file_name);
- main_status = FALSE;
- }
-
- /* No problems reading argv? So go on... */
- if (main_status) {
-
- /* if output file already exist, then delete it. */
- tmp_file = fopen(output_file_name, "w");
- if (tmp_file != NULL)
- fclose(tmp_file);
-
- /* If no mode choose than "bt" is the default mode.*/
- if (mode_choose == FALSE)
- main_fw_hdr_flag = TRUE;
-
- /* Chose manipulation routine according to arguments */
- if (main_fw_hdr_flag)
- main_status = main_bin(bin_params);
- else if (main_api_flag)
- main_status = main_api();
- else if (main_hdr_flag)
- main_status = main_hdr();
- else
- exit_with_usage();
- }
-
- /* Be sure there's no open file before you leave */
- if (input_file_pointer)
- fclose(input_file_pointer);
- if (g_hfd_pointer)
- fclose(g_hfd_pointer);
- if (api_file_pointer)
- fclose(api_file_pointer);
-
- /* Delete temprary header file. */
- remove(g_hdr_input_name);
-
- /* Say Bye Bye */
- if (main_status) {
- my_printf(TPAS, "\n\n******************************");
- my_printf(TPAS, "\n*** SUCCESS ***");
- my_printf(TPAS, "\n******************************\n");
-
- exit(EXIT_SUCCESS);
- } else {
- my_printf(TERR, "\n\n******************************");
- my_printf(TERR, "\n*** FAILED ***");
- my_printf(TERR, "\n******************************\n");
-
- exit(EXIT_FAILURE);
- }
-
-}
-
-/*
- *-----------------------------------------------------------------------
- * Function: exit_with_usage()
- * Parameters: none
- * Return: none
- * Description: No Words...
- *-----------------------------------------------------------------------
- */
-void exit_with_usage(void)
-{
- my_printf(TUSG,
- "\nECST, Embedded Controller Sign Tool, version %d.%d.%d",
- T_VER, T_REV_MAJOR, T_REV_MINOR);
- my_printf(TUSG, "\n");
- my_printf(TUSG, "\nUsage:");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "\n ECST -mode <bt|bh|api> -i <filename> [Flags]");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "\nOperation Modes: ");
- my_printf(TUSG, "\n bt - BootLoader Table");
- my_printf(TUSG, "\n bh - BootLoader Header");
- my_printf(TUSG, "\n api - Download from Flash API");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "\nCommon flags:");
- my_printf(TUSG, "\n -mode <type> - Operation mode: ");
- my_printf(TUSG, "bt|bh|api (default is bt)");
- my_printf(TUSG, "\n -i <filename> - Input file name; ");
- my_printf(TUSG, "must differ from the output file name");
- my_printf(TUSG, "\n -o <filename> - Output file name ");
- my_printf(TUSG, "(default is out_<input_filename>.bin)");
- my_printf(TUSG, "\n -argfile <filename> - Arguments file name; ");
- my_printf(TUSG, "includes multiple flags");
- my_printf(TUSG, "\n -chip <name> - Supported EC Chip Name: ");
- my_printf(TUSG, "%s. ", supported_chips);
- my_printf(TUSG, "(default is npcx5m5g)");
- my_printf(TUSG, "\n -v - Verbose; prints ");
- my_printf(TUSG, "information messages");
- my_printf(TUSG, "\n -vv - Super Verbose; prints ");
- my_printf(TUSG, "intermediate calculations");
- my_printf(TUSG, "\n -h - Show this help screen");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "\nBootLoader Table mode flags:");
- my_printf(TUSG, "\n -nohcrc - Disable CRC on header ");
- my_printf(TUSG, "(default is ON)");
- my_printf(TUSG, "\n -nofcrc - Disable CRC on firmware ");
- my_printf(TUSG, "(default is ON)");
- my_printf(TUSG, "\n -spimaxclk <val> - SPI Flash Maximum Clock, in");
- my_printf(TUSG, " MHz: 20|25|33|40|50 (default is 20)");
- my_printf(TUSG, "\n -spiclkratio <val> - Core Clock / SPI Flash ");
- my_printf(TUSG, "Clocks Ratio: 1 | 2 (default is 1)");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "Note: Not relevant for npcx5mng chips family");
- my_printf(TUSG, "\n -spireadmode <type> - SPI Flash Read Mode: ");
- my_printf(TUSG, "normal|fast|dual|quad (default is normal)");
- my_printf(TUSG, "\n -unlimburst - Enable FIU Unlimited ");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "Note: Not relevant for npcx5mng chips family");
- my_printf(TUSG, "Burst for SPI Flash Accesses (default is disable).");
- my_printf(TUSG, "\n -fwloadaddr <addr> - Firmware load start ");
- my_printf(TUSG, "address (default is Start-of-RAM)");
- my_printf(TUSG, "\n Located in code RAM, ");
- my_printf(TUSG, "16-bytes aligned, hex format");
- my_printf(TUSG, "\n -usearmrst - Use the ARM reset table ");
- my_printf(TUSG, "entry as the Firmware Entry Point");
- my_printf(TUSG, "\n Can't be used with -fwep");
- my_printf(TUSG, "\n -fwep <addr> - Firmware entry ");
- my_printf(TUSG, "point (default is Firmware Entry Point)");
- my_printf(TUSG, "\n Located in firmware area,");
- my_printf(TUSG, " hex format");
- my_printf(TUSG, "\n -crcstart <offset> - Firmware CRC start offset ");
- my_printf(TUSG, "(default is 00000000)");
- my_printf(TUSG, "\n Offset from firmware image,");
- my_printf(TUSG, " 4B-aligned, for partial CRC, hex format");
- my_printf(TUSG, "\n -crcsize <val> - Firmware CRC size ");
- my_printf(TUSG, "(default is entire firmware size)");
- my_printf(TUSG, "\n 4B-aligned, for partial ");
- my_printf(TUSG, "CRC, hex format");
- my_printf(TUSG, "\n -fwlen <val> - Firmware length, ");
- my_printf(TUSG, "16B-aligned, hex format (default is file size).");
- my_printf(TUSG, "\n -flashsize <val> - Flash size, in MB: ");
- my_printf(TUSG, "1|2|4|8|16 (default is 16)");
- my_printf(TUSG, "\n -ph <offset> - Paste the Firmware ");
- my_printf(TUSG, "Header in the input file copy at the selected");
- my_printf(TUSG, "\n offset ");
- my_printf(TUSG, "(default is 00000000), hex format.");
- my_printf(TUSG, "\n The firmware itself is ");
- my_printf(TUSG, "expected to start at offset + 64 bytes.");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "\nBootLoader Header mode flags:");
- my_printf(TUSG, "\n -pointer <offset> - BootLoader Table location");
- my_printf(TUSG, " in the flash, hex format");
- my_printf(TUSG, "\n -bhoffset <offset> - BootLoader Header Offset");
- my_printf(TUSG, " in file, hex format (BH location in BT)");
- my_printf(TUSG, "\n ");
- my_printf(TUSG, "\nAPI mode flags:");
- my_printf(TUSG, "\n -apisign <type> - Signature type: ");
- my_printf(TUSG, "crc|checksum (default is OFF)");
- my_printf(TUSG, "\n\n");
-
- exit(EXIT_FAILURE);
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: copy_file_to_file()
- * Parameters: dst_file_name - Destination file name.
- * src_file_name - Source file name.
- * offset - number of bytes from the origin.
- * origin - From where to seek, START, END, or CURRENT of
- * file.
- * Return: Number of copied bytes
- * Description: Copy the source file to the end of the destination file.
- *--------------------------------------------------------------------------
- */
-int copy_file_to_file(char *dst_file_name,
- char *src_file_name,
- int offset,
- int origin)
-{
-
- int index = 0;
- int result = 0;
- unsigned char local_val;
- int src_file_size;
- FILE *dst_file;
- FILE *src_file;
-
- /* Open the destination file for append. */
- dst_file = fopen(dst_file_name, "r+b");
- if (dst_file == NULL) {
- /* destination file not exist, create it. */
- dst_file = fopen(dst_file_name, "ab");
- if (dst_file == NULL)
- return 0;
- }
-
- /* Open the source file for read. */
- src_file = fopen(src_file_name, "rb");
- if (src_file == NULL) {
- fclose(dst_file);
- return 0;
- }
-
- /* Get the source file length in bytes. */
- src_file_size = get_file_length(src_file);
-
- /* Point to the end of the destination file, and to the start */
- /* of the source file. */
- if (fseek(dst_file, offset, origin) < 0)
- goto out;
- if (fseek(src_file, 0, SEEK_SET) < 0)
- goto out;
-
- /* Loop over all destination file and write it to the source file.*/
- for (index = 0; index < src_file_size; index++) {
- /* Read byte from source file. */
- result = (int)(fread(&local_val, 1, 1, src_file));
-
- /* If byte reading pass than write it to the destination, */
- /* else exit from the reading loop. */
- if (result) {
- /* Read pass, so write it to destination file.*/
- result = fwrite(&local_val, 1, 1, dst_file);
- if (!result)
- /*
- * Write failed,
- * return with the copied bytes number.
- */
- break;
- } else
- /* Read failed, return with the copied bytes number. */
- break;
- }
-
-out:
- /* Close the files. */
- fclose(dst_file);
- fclose(src_file);
-
- /* Copy ended, return with the number of bytes that were copied. */
- return index;
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: my_printf()
- * Parameters: as in printf + error level
- * Return: none
- * Description: No Words...
- *--------------------------------------------------------------------------
- */
-void my_printf(int error_level, char *fmt, ...)
-{
- va_list argptr;
-
- if ((g_verbose == NO_VERBOSE) && (error_level == TINF))
- return;
-
- if ((g_verbose != SUPER_VERBOSE) && (error_level == TDBG))
- return;
-
- va_start(argptr, fmt);
- vprintf(fmt, argptr);
- va_end(argptr);
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: write_to_file
- * Parameters: TBD
- * Return: TRUE on successful write
- * Description: Writes to ELF or BIN files - whatever is open
- *--------------------------------------------------------------------------
- */
-int write_to_file(unsigned int write_value,
- unsigned int offset,
- unsigned char num_of_bytes,
- char *print_string)
-{
-
- int result = 0;
- int index;
- unsigned int localValue4;
- unsigned short localValue2;
- unsigned char localValue1;
-
- if (fseek(g_hfd_pointer, offset, SEEK_SET) < 0)
- return FALSE;
-
- switch (num_of_bytes) {
- case(1):
- localValue1 = (unsigned char)write_value;
- result = (int)(fwrite(&localValue1, 1,
- 1, g_hfd_pointer));
- break;
- case(2):
- localValue2 = (unsigned short)write_value;
- result = (int)(fwrite(&localValue2,
- 2,
- 1,
- g_hfd_pointer));
- break;
- case(4):
- localValue4 = write_value;
- result = (int)(fwrite(&localValue4,
- 4,
- 1,
- g_hfd_pointer));
- break;
- default:
- /* Pad the same value N times. */
- localValue1 = (unsigned char)write_value;
- for (index = 0; index < num_of_bytes; index++)
- result = (int)(fwrite(&localValue1,
- 1,
- 1,
- g_hfd_pointer));
- break;
- }
-
- my_printf(TINF, "\nIn write_to_file - %s", print_string);
-
- if (result) {
- my_printf(TINF,
- " - Offset %2d - value 0x%x",
- offset, write_value);
- } else {
- my_printf(TERR,
- "\n\nCouldn't write %x to file at %x\n\n",
- write_value, offset);
- return FALSE;
- }
-
- return TRUE;
-
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: read_from_file
- * Parameters: TBD
- * Return: TRUE on successful read
- * Description : Reads from open BIN file
- *--------------------------------------------------------------------------
- */
-int read_from_file(unsigned int offset,
- unsigned char size_to_read,
- unsigned int *read_value,
- char *print_string)
-{
- int result;
- unsigned int localValue4;
- unsigned short localValue2;
- unsigned char localValue1;
-
- if (fseek(input_file_pointer, offset, SEEK_SET) < 0)
- return FALSE;
-
- switch (size_to_read) {
- case(1):
- result = (int)(fread(&localValue1,
- 1,
- 1,
- input_file_pointer));
- *read_value = localValue1;
- break;
- case(2):
- result = (int)(fread(&localValue2,
- 2,
- 1,
- input_file_pointer));
- *read_value = localValue2;
- break;
- case(4):
- result = (int)(fread(&localValue4,
- 4,
- 1,
- input_file_pointer));
- *read_value = localValue4;
- break;
- default:
- my_printf(TERR, "\nIn read_from_file - %s", print_string);
- my_printf(TERR, "\n\nInvalid call to read_from_file\n\n");
- return FALSE;
- }
-
- my_printf(TINF, "\nIn read_from_file - %s", print_string);
-
- if (result) {
- my_printf(TINF,
- " - Offset %d - value %x",
- offset, *read_value);
- } else {
- my_printf(TERR,
- "\n\nCouldn't read from file at %x\n\n",
- offset);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: init_calculation
- * Parameters: unsigned int check_sum_crc (I\O)
- * Return:
- * Description: Initialize the variable according to the selected
- * calculation
- *--------------------------------------------------------------------------
- */
-void init_calculation(unsigned int *check_sum_crc)
-{
- switch (g_calc_type) {
- case CALC_TYPE_NONE:
- case CALC_TYPE_CHECKSUM:
- *check_sum_crc = 0;
- break;
- case CALC_TYPE_CRC:
- *check_sum_crc = initialize_crc_32();
- break;
- }
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: finalize_calculation
- * Parameters: unsigned int check_sum_crc (I\O)
- * Return:
- * Description: Finalize the variable according to the selected calculation
- *--------------------------------------------------------------------------
- */
-void finalize_calculation(unsigned int *check_sum_crc)
-{
- switch (g_calc_type) {
- case CALC_TYPE_NONE:
- case CALC_TYPE_CHECKSUM:
- /* Do nothing */
- break;
- case CALC_TYPE_CRC:
- *check_sum_crc = finalize_crc_32(*check_sum_crc);
- break;
- }
-}
-
-/*--------------------------------------------------------------------------
- * Function: update_calculation
- * Parameters: unsigned int check_sum_crc (I\O)
- * unsigned int byte_to_add (I)
- * Return:
- * Description: Calculate a new checksum\crc with the new byte_to_add
- * given the previous checksum\crc
- *--------------------------------------------------------------------------
- */
-void update_calculation(unsigned int *check_sum_crc,
- unsigned char byte_to_add)
-{
- switch (g_calc_type) {
- case CALC_TYPE_NONE:
- /* Do nothing */
- break;
- case CALC_TYPE_CHECKSUM:
- *check_sum_crc += byte_to_add;
- break;
- case CALC_TYPE_CRC:
- *check_sum_crc = update_crc_32(*check_sum_crc, byte_to_add);
- break;
- }
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: str_cmp_no_case
- * Parameters: s1, s2: Strings to compare.
- * Return: function returns an integer less than, equal to, or
- * greater than zero if s1 (or the first n bytes thereof) is
- * found, respectively, to be less than, to match, or be
- * greater than s2.
- * Description: Compare two string without case sensitive.
- *--------------------------------------------------------------------------
- */
-int str_cmp_no_case(const char *s1, const char *s2)
-{
- return strcasecmp(s1, s2);
-}
-
-/*
- *--------------------------------------------------------------------------
- * Function: get_file_length
- * Parameters: stream - Pointer to a FILE object
- * Return: File length in bytes or -1 on error
- * Description: Gets the file length in bytes.
- *--------------------------------------------------------------------------
- */
-int get_file_length(FILE *stream)
-{
- int current_position;
- int file_len;
-
- /* Store current position. */
- current_position = ftell(stream);
- if (current_position < 0)
- return -1;
-
- /* End position of the file is its length. */
- if (fseek(stream, 0, SEEK_END) < 0)
- return -1;
- file_len = ftell(stream);
-
- /* Restore the original position. */
- if (fseek(stream, current_position, SEEK_SET) < 0)
- return -1;
-
- /* return file length. */
- return file_len;
-}
-
-/*
- ***************************************************************************
- * "bt" mode Handler
- ***************************************************************************
- */
-
-/*
- ***************************************************************************
- * Function: main_bin
- * Parameters: TBD
- * Return: True for success
- * Description:
- * TBD
- ***************************************************************************
- */
-int main_bin(struct tbinparams binary_params)
-{
- unsigned int bin_file_size_bytes;
- unsigned int bin_fw_offset = 0;
- unsigned int tmp_param;
- FILE *output_file_pointer;
-
- /* If input file was not declared, then print error message. */
- if (strlen(input_file_name) == 0) {
- my_printf(TERR, "\n\nDefine input file, using -i flag\n\n");
- return FALSE;
- }
-
- /* Open input file */
- input_file_pointer = fopen(input_file_name, "r+b");
- if (input_file_pointer == NULL) {
- my_printf(TERR, "\n\nCannot open %s\n\n", input_file_name);
- return FALSE;
- }
-
- /*
- * Check Binary file size, this file contain the image itself,
- * without any header.
- */
- bin_file_size_bytes = get_file_length(input_file_pointer);
- if (bin_file_size_bytes == 0) {
- my_printf(TINF,
- "\nBIN Input file name %s is empty (size is %d)\n",
- input_file_name, bin_file_size_bytes);
- return FALSE;
- }
-
- /*
- * If the binary file contains also place for the header, then the FW
- * size is the length of the file minus the header length
- */
- if ((binary_params.bin_params & BIN_FW_HDR_OFFSET) != 0)
- bin_fw_offset = binary_params.fw_hdr_offset + HEADER_SIZE;
-
- my_printf(TINF, "\nBIN file: %s, size: %d (0x%x) bytes\n",
- input_file_name,
- bin_file_size_bytes,
- bin_file_size_bytes);
-
- /* Check validity of FW header offset. */
- if (((int)binary_params.fw_hdr_offset < 0) ||
- (binary_params.fw_hdr_offset > bin_file_size_bytes)) {
- my_printf(TERR,
- "\nFW header offset 0x%08x (%d) should be in the"
- " range of 0 and file size (%d).\n",
- binary_params.fw_hdr_offset,
- binary_params.fw_hdr_offset,
- bin_file_size_bytes);
- return FALSE;
- }
-
- /* Create the header file in the same directory as the input file. */
- if (!splice_into_path(g_hdr_input_name, input_file_name,
- sizeof(g_hdr_input_name), "hdr_"))
- return FALSE;
- g_hfd_pointer = fopen(g_hdr_input_name, "w+b");
- if (g_hfd_pointer == NULL) {
- my_printf(TERR, "\n\nCannot open %s\n\n", g_hdr_input_name);
- return FALSE;
- }
-
- if (strlen(output_file_name) == 0) {
- if (!splice_into_path(output_file_name, input_file_name,
- sizeof(output_file_name), "out_"))
- return FALSE;
- }
-
- my_printf(TINF, "Output file name: %s\n", output_file_name);
-
- /*
- *********************************************************************
- * Set the ANCHOR & Extended-ANCHOR
- *********************************************************************
- */
- /* Write the ancore. */
- if (!write_to_file(FW_HDR_ANCHOR,
- HDR_ANCHOR_OFFSET,
- 4,
- "HDR - FW Header ANCHOR "))
- return FALSE;
-
- /* Write the extended anchor. */
- if (binary_params.bin_params & BIN_FW_HDR_CRC_DISABLE) {
-
- /* Write the ancore and the extended anchor. */
- if (!write_to_file(FW_HDR_EXT_ANCHOR_DISABLE,
- HDR_EXTENDED_ANCHOR_OFFSET, 2,
- "HDR - Header EXTENDED ANCHOR "))
- return FALSE;
- } else {
- /* Write the anchor and the extended anchor. */
- if (!write_to_file(FW_HDR_EXT_ANCHOR_ENABLE,
- HDR_EXTENDED_ANCHOR_OFFSET, 2,
- "HDR - Header EXTENDED ANCHOR "))
- return FALSE;
- }
-
- /* Write the SPI flash MAX clock. */
- switch (binary_params.spi_max_clk) {
- case SPI_MAX_CLOCK_20_MHZ_VAL:
- tmp_param = SPI_MAX_CLOCK_20_MHZ;
- break;
- case SPI_MAX_CLOCK_25_MHZ_VAL:
- tmp_param = SPI_MAX_CLOCK_25_MHZ;
- break;
- case SPI_MAX_CLOCK_33_MHZ_VAL:
- tmp_param = SPI_MAX_CLOCK_33_MHZ;
- break;
- case SPI_MAX_CLOCK_40_MHZ_VAL:
- tmp_param = SPI_MAX_CLOCK_40_MHZ;
- break;
- case SPI_MAX_CLOCK_50_MHZ_VAL:
- tmp_param = SPI_MAX_CLOCK_50_MHZ;
- break;
- default:
- my_printf(TERR, "\n\nInvalid SPI Flash MAX clock (%d MHz) ",
- binary_params.spi_max_clk);
- my_printf(TERR, "- it should be 20, 25, 33, 40 or 50 MHz");
- return FALSE;
- }
-
- /* If SPI clock ratio set for MRIDER15, then it is error. */
- if ((binary_params.spi_clk_ratio != 0x00) && (is_mrider15 == TRUE)) {
-
- my_printf(TERR, "\nspiclkratio is not relevant for");
- my_printf(TERR, " npcx5mng chips family !\n");
-
- return FALSE;
- }
-
- /*
- * In case SPIU clock ratio didn't set by the user,
- * set it to its default value.
- */
- if (binary_params.spi_clk_ratio == 0x00)
- binary_params.spi_clk_ratio = SPI_CLOCK_RATIO_1_VAL;
-
- switch (binary_params.spi_clk_ratio) {
- case SPI_CLOCK_RATIO_1_VAL:
- tmp_param &= SPI_CLOCK_RATIO_1;
- break;
- case SPI_CLOCK_RATIO_2_VAL:
- tmp_param |= SPI_CLOCK_RATIO_2;
- break;
- default:
- my_printf(TERR, "\n\nInvalid SPI Core Clock Ratio (%d) ",
- binary_params.spi_clk_ratio);
- my_printf(TERR, "- it should be 1 or 2");
- return FALSE;
- }
-
- if (!write_to_file(tmp_param, HDR_SPI_MAX_CLK_OFFSET, 1,
- "HDR - SPI flash MAX Clock "))
- return FALSE;
-
- /* Write the SPI flash Read Mode. */
- tmp_param = binary_params.spi_read_mode;
- /* If needed, set the unlimited burst bit. */
- if (binary_params.bin_params & BIN_UNLIM_BURST_ENABLE) {
- if (is_mrider15 == TRUE) {
-
- my_printf(TERR, "\nunlimburst is not relevant for");
- my_printf(TERR, " npcx5mng chips family !\n");
-
- return FALSE;
- }
-
- tmp_param |= SPI_UNLIMITED_BURST_ENABLE;
- }
- if (!write_to_file(tmp_param,
- HDR_SPI_READ_MODE_OFFSET, 1,
- "HDR - SPI flash Read Mode "))
- return FALSE;
-
- /* Write the error detection configuration. */
- if (binary_params.bin_params & BIN_FW_CRC_DISABLE) {
- if (!write_to_file(FW_CRC_DISABLE,
- HDR_ERR_DETECTION_CONF_OFFSET,
- 1,
- "HDR - FW CRC Disabled "))
- return FALSE;
- } else {
- /* Write the ancore and the extended anchor. */
- if (!write_to_file(FW_CRC_ENABLE,
- HDR_ERR_DETECTION_CONF_OFFSET, 1,
- "HDR - FW CRC Enabled "))
- return FALSE;
- }
-
- /* FW entry point should be between the FW load address and RAM size */
- if ((binary_params.fw_load_addr >
- (g_ram_start_address + g_ram_size)) ||
- (binary_params.fw_load_addr < g_ram_start_address)) {
- my_printf(TERR,
- "\nFW load address (0x%08x) should be between ",
- binary_params.fw_load_addr);
- my_printf(TERR,
- "start (0x%08x) and end (0x%08x) of RAM ).",
- g_ram_start_address,
- (g_ram_start_address + g_ram_size));
-
- return FALSE;
- }
-
- /* Write the FW load start address */
- if (!write_to_file(binary_params.fw_load_addr,
- HDR_FW_LOAD_START_ADDR_OFFSET, 4,
- "HDR - FW load start address "))
- return FALSE;
-
- /*
- * Write the FW length. (MUST BE SET BEFORE fw_err_detec_e_addr)
- */
- if ((binary_params.bin_params & BIN_FW_LENGTH) == 0x00000000) {
- /*
- * In case the FW length was not set, then the FW length is the
- * size of the binary file minus the offset of the start of the
- * FW.
- */
- binary_params.fw_len = bin_file_size_bytes-bin_fw_offset;
- }
-
- if ((int)binary_params.fw_len < 0) {
- my_printf(TERR,
- "\nFW length %d (0x%08x) should be greater than 0x0.",
- binary_params.fw_len,
- binary_params.fw_len);
- return FALSE;
- }
-
- if (((int)binary_params.fw_len >
- (bin_file_size_bytes - bin_fw_offset)) ||
- ((int)binary_params.fw_len > g_ram_size)) {
- my_printf(TERR,
- "\nFW length %d (0x%08x) should be within the",
- binary_params.fw_len, binary_params.fw_len);
- my_printf(TERR,
- " input-file (related to the FW offset)");
- my_printf(TERR,
- "\n (0x%08x) and within the RAM (RAM size: 0x%08x).",
- (bin_file_size_bytes - bin_fw_offset), g_ram_size);
- return FALSE;
- }
-
- if ((binary_params.bin_params & BIN_FW_USER_ARM_RESET) != 0x00000000) {
- read_from_file((bin_fw_offset + ARM_FW_ENTRY_POINT_OFFSET),
- 4,
- &binary_params.fw_ep,
- "read FW entry point for FW image ");
-
- if ((binary_params.fw_ep <
- binary_params.fw_load_addr) ||
- (binary_params.fw_ep >
- (binary_params.fw_load_addr +
- binary_params.fw_len))) {
- my_printf(TERR,
- "\nFW entry point (0x%08x) should be between",
- binary_params.fw_ep);
- my_printf(TERR,
- " the FW load address (0x%08x) ",
- binary_params.fw_load_addr);
- my_printf(TERR,
- "and FW length (0x%08x).\n",
- (binary_params.fw_load_addr +
- binary_params.fw_len));
- return FALSE;
- }
- }
-
- /* FW entry point should be between the FW load address and RAM size */
- if ((binary_params.fw_ep <
- binary_params.fw_load_addr) ||
- (binary_params.fw_ep >
- (binary_params.fw_load_addr +
- binary_params.fw_len))) {
- if (((binary_params.bin_params & BIN_FW_ENTRY_POINT) ==
- 0x00000000) &&
- ((binary_params.bin_params &
- BIN_FW_LOAD_START_ADDR) != 0x00000000)) {
- binary_params.fw_ep =
- binary_params.fw_load_addr;
- } else {
- my_printf(TERR,
- "\nFW entry point (0x%08x) should be ",
- binary_params.fw_ep);
- my_printf(TERR,
- "\between the FW load address (0x%08x)",
- binary_params.fw_load_addr);
- my_printf(TERR,
- " and FW length (0x%08x).\n",
- (binary_params.fw_load_addr +
- binary_params.fw_len));
- return FALSE;
- }
- }
-
- /* Write the FW entry point */
- if (!write_to_file(binary_params.fw_ep,
- HDR_FW_ENTRY_POINT_OFFSET,
- 4,
- "HDR - FW Entry point "))
- return FALSE;
-
- /* Calculate the CRC end address. */
- if ((binary_params.bin_params & BIN_FW_CKS_SIZE) == 0x00000000) {
- /*
- * In case the size was not set, then CRC end address is
- * the size of the binary file.
- */
- binary_params.fw_err_detec_e_addr =
- binary_params.fw_len - 1;
- } else {
- /* CRC end address should be less than FW length. */
- if (binary_params.fw_err_detec_e_addr >
- (binary_params.fw_len - 1)) {
- my_printf(TERR,
- "\nCRC end address (0x%08x) should be less ",
- binary_params.fw_err_detec_e_addr);
- my_printf(TERR,
- "than the FW length %d (0x%08x)",
- (binary_params.fw_len),
- (binary_params.fw_len));
- return FALSE;
- }
- }
-
- /* Check CRC start and end addresses. */
- if (binary_params.fw_err_detec_s_addr >
- binary_params.fw_err_detec_e_addr) {
- my_printf(TERR,
- "\nCRC start address (0x%08x) should be less or ",
- binary_params.fw_err_detec_s_addr);
- my_printf(TERR,
- "equal to CRC end address (0x%08x)\nPlease check ",
- binary_params.fw_err_detec_e_addr);
- my_printf(TERR,
- "CRC start address and CRC size arguments.");
- return FALSE;
- }
-
- /* CRC start addr should be between the FW load address and RAM size */
- if (binary_params.fw_err_detec_s_addr >
- binary_params.fw_len) {
- my_printf(TERR, "\nCRC start address (0x%08x) should ",
- binary_params.fw_err_detec_s_addr);
- my_printf(TERR, "be FW length (0x%08x).",
- binary_params.fw_len);
- return FALSE;
- }
-
- /* Write the CRC start address */
- if (!write_to_file(binary_params.fw_err_detec_s_addr,
- HDR_FW_ERR_DETECT_START_ADDR_OFFSET,
- 4,
- "HDR - FW CRC Start "))
- return FALSE;
-
- /* CRC end addr should be between the CRC start address and RAM size */
- if ((binary_params.fw_err_detec_e_addr <
- binary_params.fw_err_detec_s_addr) ||
- (binary_params.fw_err_detec_e_addr >
- binary_params.fw_len)) {
- my_printf(TERR,
- "\nCRC end address (0x%08x) should be between the ",
- binary_params.fw_err_detec_e_addr);
- my_printf(TERR,
- "CRC start address (0x%08x) and FW length (0x%08x).",
- binary_params.fw_err_detec_s_addr,
- binary_params.fw_len);
- return FALSE;
- }
-
- /* Write the CRC end address */
- if (!write_to_file(binary_params.fw_err_detec_e_addr,
- HDR_FW_ERR_DETECT_END_ADDR_OFFSET,
- 4,
- "HDR - FW CRC End "))
- return FALSE;
-
- /* Let the FW length to be aligned to 16 */
- tmp_param = binary_params.fw_len % 16;
- if (tmp_param)
- binary_params.fw_len += (16 - tmp_param);
-
- /* FW load address + FW length should be less than the RAM size. */
- if ((binary_params.fw_load_addr +
- binary_params.fw_len) >
- (g_ram_start_address + g_ram_size)) {
- my_printf(TERR,
- "\nFW load address + FW length should (0x%08x) be ",
- (binary_params.fw_load_addr + binary_params.fw_len));
- my_printf(TERR,
- "less than the RAM size (0x%08x).",
- (g_ram_start_address + g_ram_size));
- return FALSE;
- }
-
- /* Write the FW length */
- if (!write_to_file(binary_params.fw_len,
- HDR_FW_LENGTH_OFFSET,
- 4,
- "HDR - FW Length "))
- return FALSE;
-
- /* Write the SPI flash MAX clock. */
- switch (binary_params.flash_size) {
- case FLASH_SIZE_1_MBYTES_VAL:
- tmp_param = FLASH_SIZE_1_MBYTES;
- break;
- case FLASH_SIZE_2_MBYTES_VAL:
- tmp_param = FLASH_SIZE_2_MBYTES;
- break;
- case FLASH_SIZE_4_MBYTES_VAL:
- tmp_param = FLASH_SIZE_4_MBYTES;
- break;
- case FLASH_SIZE_8_MBYTES_VAL:
- tmp_param = FLASH_SIZE_8_MBYTES;
- break;
- case FLASH_SIZE_16_MBYTES_VAL:
- tmp_param = FLASH_SIZE_16_MBYTES;
- break;
- default:
- my_printf(TERR, "\n\nInvalid Flash size (%d MBytes) -",
- binary_params.flash_size);
- my_printf(TERR, " it should be 1, 2, 4, 8 or 16 MBytes\n");
- return FALSE;
- }
- if (!write_to_file(tmp_param,
- HDR_FLASH_SIZE_OFFSET,
- 1,
- "HDR - Flash size "))
-
- return FALSE;
-
- /* Write the reserved bytes. */
- if (!write_to_file(PAD_VALUE, HDR_RESERVED, 26,
- "HDR - Reserved (26 bytes) "))
- return FALSE;
-
-
- /* Refresh the FW header bin file in order to calculate CRC */
- if (g_hfd_pointer) {
- fclose(g_hfd_pointer);
- g_hfd_pointer = fopen(g_hdr_input_name, "r+b");
- if (g_hfd_pointer == NULL) {
- my_printf(TERR,
- "\n\nCannot open %s\n\n",
- input_file_name);
- return FALSE;
- }
- }
-
- /* Calculate the FW header CRC */
- if ((binary_params.bin_params & BIN_FW_HDR_CRC_DISABLE) == 0) {
- /* Calculate ... */
- g_calc_type = CALC_TYPE_CRC;
- if (!calc_header_crc_bin(&binary_params.hdr_crc))
- return FALSE;
-
- g_calc_type = CALC_TYPE_NONE;
- } else
- binary_params.hdr_crc = 0;
-
- /* Write FW header CRC to header file */
- if (!write_to_file(binary_params.hdr_crc,
- HDR_FW_HEADER_SIG_OFFSET,
- 4,
- "HDR - Header CRC "))
- return FALSE;
-
- /* Calculate the FW CRC */
- if ((binary_params.bin_params & BIN_FW_CRC_DISABLE) == 0) {
- /* Calculate ... */
- g_calc_type = CALC_TYPE_CRC;
- if (!calc_firmware_csum_bin(&binary_params.fw_crc,
- (bin_fw_offset +
- binary_params.fw_err_detec_s_addr),
- (binary_params.fw_err_detec_e_addr -
- binary_params.fw_err_detec_s_addr+1)))
- return FALSE;
-
- g_calc_type = CALC_TYPE_NONE;
- } else
- binary_params.fw_crc = 0;
-
- /* Write the FW CRC into file header file */
- if (!write_to_file(binary_params.fw_crc,
- HDR_FW_IMAGE_SIG_OFFSET,
- 4,
- "HDR - FW CRC "))
- return FALSE;
-
- /* Close if needed... */
- if (input_file_pointer) {
- fclose(input_file_pointer);
- input_file_pointer = NULL;
- }
-
- if (g_hfd_pointer) {
- fclose(g_hfd_pointer);
- g_hfd_pointer = NULL;
- }
-
- /* Create empty output file. */
- output_file_pointer = fopen(output_file_name, "wb");
- if (output_file_pointer)
- fclose(output_file_pointer);
-
- if ((binary_params.bin_params & BIN_FW_HDR_OFFSET) != 0) {
- copy_file_to_file(output_file_name,
- input_file_name,
- 0,
- SEEK_SET);
- copy_file_to_file(output_file_name,
- g_hdr_input_name,
- binary_params.fw_hdr_offset,
- SEEK_SET);
- } else {
- copy_file_to_file(output_file_name,
- g_hdr_input_name,
- 0,
- SEEK_END);
- copy_file_to_file(output_file_name,
- input_file_name,
- 0,
- SEEK_END);
- }
-
- my_printf(TINF, "\n\n");
-
- return TRUE;
-}
-
-/*******************************************************************
- * Function: calc_header_crc_bin
- * Parameters: unsigned short header checksum (O)
- * unsigned int header offset from first byte in
- * the binary (I)
- * Return: TRUE if successful
- * Description: Go thru bin file and calculate checksum
- *******************************************************************
- */
-int calc_header_crc_bin(unsigned int *p_cksum)
-{
- int i;
- unsigned int calc_header_checksum_crc = 0;
- unsigned char g_header_array[HEADER_SIZE];
- int line_print_size = 32;
-
- init_calculation(&calc_header_checksum_crc);
-
- /* Go thru the BIN File and calculate the Checksum */
- if (fseek(g_hfd_pointer, 0x00000000, SEEK_SET) < 0)
- return FALSE;
-
- if (fread(g_header_array,
- HEADER_SIZE,
- 1,
- g_hfd_pointer) != 1)
- return FALSE;
-
- for (i = 0; i < (HEADER_SIZE - HEADER_CRC_FIELDS_SIZE); i++) {
-
- /*
- * I had once the Verbose check inside the my_printf, but
- * it made ECST run sloooowwwwwly....
- */
- if (g_verbose == SUPER_VERBOSE) {
- if (i%line_print_size == 0)
- my_printf(TDBG, "\n[%.4x]: ", i);
-
- my_printf(TDBG, "%.2x ", g_header_array[i]);
- }
-
- update_calculation(&calc_header_checksum_crc,
- g_header_array[i]);
-
- if (g_verbose == SUPER_VERBOSE) {
- if ((i + 1) % line_print_size == 0)
- my_printf(TDBG,
- "FW Header ChecksumCRC = %.8x",
- calc_header_checksum_crc);
-
- }
- }
-
- finalize_calculation(&calc_header_checksum_crc);
- *p_cksum = calc_header_checksum_crc;
-
- return TRUE;
-}
-
-/*
- *******************************************************************
- * Function: calc_firmware_csum_bin
- * Parameters: unsigned int fwStart (I)
- * unsigned int firmware size in words (I)
- * unsigned int - firmware checksum (O)
- * Return:
- * Description: TBD
- *******************************************************************
- */
-int calc_firmware_csum_bin(unsigned int *p_cksum,
- unsigned int fw_offset,
- unsigned int fw_length)
-{
-
- unsigned int i;
- unsigned int calc_read_bytes;
- unsigned int calc_num_of_bytes_to_read;
- unsigned int calc_curr_position;
- unsigned int calc_fw_checksum_crc = 0;
- unsigned char g_fw_array[BUFF_SIZE];
- int line_print_size = 32;
-
- calc_num_of_bytes_to_read = fw_length;
- calc_curr_position = fw_offset;
-
- if (g_verbose == REGULAR_VERBOSE) {
- my_printf(TINF,
- "\nFW Error Detect Start Dddress: 0x%08x",
- calc_curr_position);
- my_printf(TINF,
- "\nFW Error Detect End Dddress: 0x%08x",
- calc_curr_position + calc_num_of_bytes_to_read - 1);
- my_printf(TINF,
- "\nFW Error Detect Size: %d (0x%X)",
- calc_num_of_bytes_to_read,
- calc_num_of_bytes_to_read);
- }
-
- init_calculation(&calc_fw_checksum_crc);
-
- while (calc_num_of_bytes_to_read > 0) {
- if (calc_num_of_bytes_to_read > BUFF_SIZE)
- calc_read_bytes = BUFF_SIZE;
- else
- calc_read_bytes = calc_num_of_bytes_to_read;
-
- if (fseek(input_file_pointer,
- calc_curr_position, SEEK_SET) < 0)
- return 0;
- if (fread(g_fw_array,
- calc_read_bytes,
- 1,
- input_file_pointer) != 1)
- return 0;
-
- for (i = 0; i < calc_read_bytes; i++) {
- /*
- * I had once the Verbose check inside the my_printf,
- * but it made ECST run sloooowwwwwly....
- */
- if (g_verbose == SUPER_VERBOSE) {
- if (i%line_print_size == 0)
- my_printf(TDBG,
- "\n[%.4x]: ",
- calc_curr_position + i);
-
- my_printf(TDBG, "%.2x ", g_fw_array[i]);
- }
-
- update_calculation(&calc_fw_checksum_crc,
- g_fw_array[i]);
-
- if (g_verbose == SUPER_VERBOSE) {
- if ((i + 1) % line_print_size == 0)
- my_printf(TDBG,
- "FW Checksum= %.8x",
- calc_fw_checksum_crc);
- }
- }
- calc_num_of_bytes_to_read -= calc_read_bytes;
- calc_curr_position += calc_read_bytes;
- } /* end of while(calc_num_of_bytes_to_read > 0) */
-
- finalize_calculation(&calc_fw_checksum_crc);
- *p_cksum = calc_fw_checksum_crc;
-
- return TRUE;
-}
-
-/*
- ***************************************************************************
- * "bh" mode Handler
- ***************************************************************************
- */
-
-/*
- *******************************************************************
- * Function: main_hdr
- * Parameters: TBD
- * Return: True for success
- * Description:
- *******************************************************************
- */
-int main_hdr(void)
-{
- int result = 0;
- char tmp_file_name[NAME_SIZE + 1];
- unsigned int tmp_long_val;
- unsigned int bin_file_size_bytes;
-
- tmp_file_name[NAME_SIZE] = '\0';
-
- if (is_ptr_merge) {
- if (strlen(input_file_name) == 0) {
- my_printf(TERR, "\n\nNo input BIN file selected for");
- my_printf(TERR, " BootLoader header file.\n\n");
- return FALSE;
- }
-
- if (strlen(output_file_name) == 0)
- strncpy(tmp_file_name,
- input_file_name,
- sizeof(tmp_file_name) - 1);
- else {
- copy_file_to_file(output_file_name,
- input_file_name,
- 0,
- SEEK_END);
- strncpy(tmp_file_name,
- output_file_name,
- sizeof(tmp_file_name) - 1);
- }
-
- /* Open Header file */
- g_hdr_pointer = fopen(tmp_file_name, "r+b");
- if (g_hdr_pointer == NULL) {
- my_printf(TERR,
- "\n\nCannot open %s file.\n\n",
- tmp_file_name);
- return FALSE;
- }
-
- bin_file_size_bytes = get_file_length(g_hdr_pointer);
-
- /* Offset should be less than file size. */
- if (fw_offset > bin_file_size_bytes) {
- my_printf(TERR,
- "\n\nFW offset 0x%08x should be less than ",
- fw_offset);
- my_printf(TERR,
- "file size 0x%x (%d).\n\n",
- bin_file_size_bytes, bin_file_size_bytes);
- return FALSE;
- }
-
- /* FW table should be less than file size. */
- if (ptr_fw_addr > bin_file_size_bytes) {
- my_printf(TERR, "\n\nFW table 0x%08x should be less ",
- ptr_fw_addr);
- my_printf(TERR, "than file size 0x%x (%d).\n\n",
- bin_file_size_bytes, bin_file_size_bytes);
- return FALSE;
- }
-
- if (fseek(g_hdr_pointer, fw_offset, SEEK_SET) < 0)
- return FALSE;
-
- tmp_long_val = HDR_PTR_SIGNATURE;
- result = (int)(fwrite(&tmp_long_val,
- 4,
- 1,
- g_hdr_pointer));
- result |= (int)(fwrite(&ptr_fw_addr,
- 4,
- 1,
- g_hdr_pointer));
-
- if (result) {
- my_printf(TINF,
- "\nBootLoader Header file: %s\n",
- tmp_file_name);
- my_printf(TINF,
- " Offset: 0x%08X, Signature: 0x%08X,",
- fw_offset, HDR_PTR_SIGNATURE);
- my_printf(TINF,
- " Pointer: 0x%08X\n",
- ptr_fw_addr);
- } else {
- my_printf(TERR,
- "\n\nCouldn't write signature (%x) and "
- "pointer to BootLoader header file (%s)\n\n",
- tmp_long_val, tmp_file_name);
- return FALSE;
- }
-
- } else {
-
- if (strlen(output_file_name) == 0) {
- my_printf(TERR, "\n\nNo output file selected ");
- my_printf(TERR, "for BootLoader header file.\n\n");
- return FALSE;
- }
-
- /* Open Output file */
- g_hdr_pointer = fopen(output_file_name, "w+b");
- if (g_hdr_pointer == NULL) {
- my_printf(TERR,
- "\n\nCannot open %s file.\n\n",
- output_file_name);
- return FALSE;
- }
-
- if (fseek(g_hdr_pointer, 0L, SEEK_SET) < 0)
- return FALSE;
-
- tmp_long_val = HDR_PTR_SIGNATURE;
- result = (int)(fwrite(&tmp_long_val,
- 4,
- 1,
- g_hdr_pointer));
- result |= (int)(fwrite(&ptr_fw_addr,
- 4,
- 1,
- g_hdr_pointer));
-
- if (result) {
- my_printf(TINF,
- "\nBootLoader Header file: %s\n",
- output_file_name);
- my_printf(TINF,
- " Signature: 0x%08X, Pointer: 0x%08X\n",
- HDR_PTR_SIGNATURE,
- ptr_fw_addr);
- } else {
- my_printf(TERR,
- "\n\nCouldn't write signature (%x) and ",
- tmp_long_val);
- my_printf(TERR,
- "pointer to BootLoader header file (%s)\n\n",
- output_file_name);
- return FALSE;
- }
-
- }
-
- /* Close if needed... */
- if (g_hdr_pointer) {
- fclose(g_hdr_pointer);
- g_hdr_pointer = NULL;
- }
-
- return TRUE;
-}
-
-/*
- ***************************************************************************
- * "api" mode Handler
- ***************************************************************************
- */
-
-/*
- *******************************************************************
- * Function: main_api
- * Parameters: TBD
- * Return: True for success
- * Description:
- * TBD
- *******************************************************************
- */
-int main_api(void)
-{
- char tmp_file_name[NAME_SIZE + 1];
- int result = 0;
- unsigned int crc_checksum;
-
- tmp_file_name[NAME_SIZE] = '\0';
- api_file_size_bytes = 0;
-
- /* If API input file was not declared, then print error message. */
- if (strlen(input_file_name) == 0) {
- my_printf(TERR,
- "\n\nNeed to define API input file, using -i flag\n\n");
- return FALSE;
-
- }
-
- if (strlen(output_file_name) == 0) {
- if (!splice_into_path(tmp_file_name, input_file_name,
- sizeof(tmp_file_name), "api_"))
- return FALSE;
- } else
- strncpy(tmp_file_name, output_file_name,
- sizeof(tmp_file_name) - 1);
-
- /* Make sure that new empty file is created. */
- api_file_pointer = fopen(tmp_file_name, "w");
- if (api_file_pointer == NULL) {
- my_printf(TERR, "\n\nCannot open %s\n\n", tmp_file_name);
- return FALSE;
- }
- fclose(api_file_pointer);
-
- copy_file_to_file(tmp_file_name, input_file_name, 0, SEEK_END);
-
- /* Open API input file */
- api_file_pointer = fopen(tmp_file_name, "r+b");
- if (api_file_pointer == NULL) {
- my_printf(TERR, "\n\nCannot open %s\n\n", tmp_file_name);
- return FALSE;
- }
-
- /*
- * Check Binary file size, this file contain the image itself,
- * without any header.
- */
- api_file_size_bytes = get_file_length(api_file_pointer);
- if (api_file_size_bytes < 0)
- return FALSE;
- my_printf(TINF,
- "\nAPI file: %s, size: %d bytes (0x%x)\n",
- tmp_file_name,
- api_file_size_bytes,
- api_file_size_bytes);
-
- crc_checksum = calc_api_csum_bin();
-
- if (fseek(api_file_pointer, api_file_size_bytes, SEEK_SET) < 0)
- return FALSE;
-
- result = (int)(fwrite(&crc_checksum,
- 4,
- 1,
- api_file_pointer));
-
- if (result)
- my_printf(TINF,
- "\nIn API BIN file - Offset 0x%08X - value 0x%08X",
- api_file_size_bytes,
- crc_checksum);
- else {
- my_printf(TERR,
- "\n\nCouldn't write %x to API BIN file at %08x\n\n",
- crc_checksum, api_file_size_bytes);
- return FALSE;
- }
-
- /* Close if needed... */
- if (api_file_pointer) {
- fclose(api_file_pointer);
- api_file_pointer = NULL;
- }
-
- return TRUE;
-}
-
-
-/*
- *******************************************************************
- * Function: calc_api_csum_bin
- * Parameters:
- *
- * Return: Return the CRC \ checksum, or "0" in case of fail.
- * Description: TBD
- *******************************************************************
-*/
-unsigned int calc_api_csum_bin(void)
-{
-
- unsigned int i;
- unsigned int calc_read_bytes;
- int calc_num_of_bytes_to_read;
- unsigned int calc_curr_position;
- unsigned int calc_fw_checksum_crc = 0;
- unsigned char g_fw_array[BUFF_SIZE];
- int line_print_size = 32;
-
- calc_num_of_bytes_to_read = api_file_size_bytes;
- calc_curr_position = 0;
-
- if (g_verbose == SUPER_VERBOSE) {
- my_printf(TDBG,
- "\nAPI CRC \\ Checksum First Byte Address: 0x%08x",
- calc_curr_position);
- my_printf(TDBG,
- "\nAPI CRC \\ Checksum Size: %d (0x%X)",
- calc_num_of_bytes_to_read,
- calc_num_of_bytes_to_read);
- }
-
- init_calculation(&calc_fw_checksum_crc);
-
- while (calc_num_of_bytes_to_read > 0) {
- if (calc_num_of_bytes_to_read > BUFF_SIZE)
- calc_read_bytes = BUFF_SIZE;
- else
- calc_read_bytes = calc_num_of_bytes_to_read;
-
- if (fseek(api_file_pointer,
- calc_curr_position, SEEK_SET) < 0)
- return 0;
- if (fread(g_fw_array,
- calc_read_bytes,
- 1,
- api_file_pointer) != 1)
- return 0;
-
- for (i = 0; i < calc_read_bytes; i++) {
- /*
- * I had once the Verbose check inside the my_printf,
- * but it made ecst run sloooowwwwwly....
- */
- if (g_verbose == SUPER_VERBOSE) {
- if (i%line_print_size == 0)
- my_printf(TDBG,
- "\n[%.4x]: ",
- calc_curr_position + i);
-
- my_printf(TDBG, "%.2x ", g_fw_array[i]);
- }
-
- update_calculation(&calc_fw_checksum_crc,
- g_fw_array[i]);
-
- if (g_verbose == SUPER_VERBOSE) {
- if ((i + 1) % line_print_size == 0)
- my_printf(TDBG,
- "FW Checksum= %.8x",
- calc_fw_checksum_crc);
- }
- }
- calc_num_of_bytes_to_read -= calc_read_bytes;
- calc_curr_position += calc_read_bytes;
- } /* end of while(calc_num_of_bytes_to_read > 0) */
-
- finalize_calculation(&calc_fw_checksum_crc);
-
- return calc_fw_checksum_crc;
-
-}
-
-/*
- **************************************************************************
- * CRC Handler
- **************************************************************************
-*/
-
-/*
- *******************************************************************
- *
- * #define P_xxxx
- *
- * The CRC's are computed using polynomials. The coefficients
- * for the algorithms are defined by the following constants.
- *
- *******************************************************************
- */
-
-#define P_32 0xEDB88320L
-
-/*
- *******************************************************************
- *
- * static int crc_tab...init
- * static unsigned ... crc_tab...[]
- *
- * The algorithms use tables with pre-calculated values. This
- * speeds up the calculation dramatically. The first time the
- * CRC function is called, the table for that specific calcu-
- * lation is set up. The ...init variables are used to deter-
- * mine if the initialization has taken place. The calculated
- * values are stored in the crc_tab... arrays.
- *
- * The variables are declared static. This makes them invisible
- * for other modules of the program.
- *
- *******************************************************************
- */
-static int crc_tab32_init = FALSE;
-static unsigned int crc_tab32[256];
-
-/*
- ********************************************************************
- *
- * static void init_crc...tab();
- *
- * Three local functions are used to initialize the tables
- * with values for the algorithm.
- *
- *******************************************************************
- */
-
-static void init_crc32_tab(void);
-
-/*
- *******************************************************************
- *
- * unsigned int initialize_crc_32( void );
- *
- * The function update_crc_32 calculates a new CRC-32 value
- * based on the previous value of the CRC and the next byte
- * of the data to be checked.
- *
- *******************************************************************
- */
-
-unsigned int initialize_crc_32(void)
-{
- return 0xffffffffL;
-} /* initialize_crc_32 */
-
-/*
- *******************************************************************
- *
- * unsigned int update_crc_32( unsigned int crc, char c );
- *
- * The function update_crc_32 calculates a new CRC-32 value
- * based on the previous value of the CRC and the next byte
- * of the data to be checked.
- *
- *******************************************************************
- */
-
-unsigned int update_crc_32(unsigned int crc, char c)
-{
-
- unsigned int tmp, long_c;
-
- long_c = 0x000000ffL & (unsigned int)c;
-
- if (!crc_tab32_init)
- init_crc32_tab();
-
- tmp = crc ^ long_c;
- crc = (crc >> 8) ^ crc_tab32[tmp & 0xff];
-
- return crc;
-
-} /* update_crc_32 */
-
-/*
- *******************************************************************
- *
- * static void init_crc32_tab( void );
- *
- * The function init_crc32_tab() is used to fill the array
- * for calculation of the CRC-32 with values.
- *
- *******************************************************************
- */
-static void init_crc32_tab(void)
-{
-
- int i, j;
- unsigned int crc;
-
- for (i = 0; i < 256; i++) {
-
- crc = (unsigned int)i;
-
- for (j = 0; j < 8; j++) {
-
- if (crc & 0x00000001L)
- crc = (crc >> 1) ^ P_32;
- else
- crc = crc >> 1;
- }
-
- crc_tab32[i] = crc;
- }
-
- crc_tab32_init = TRUE;
-
-} /* init_crc32_tab */
-
-/*
- *******************************************************************
- *
- * unsigned int finalize_crc_32( unsigned int crc );
- *
- * The function finalize_crc_32 finalizes a CRC-32 calculation
- * by performing a bit convolution (bit 0 is bit 31, etc').
- *
- *******************************************************************
- */
-
-unsigned int finalize_crc_32(unsigned int crc)
-{
-
- int i;
- unsigned int result = 0;
-
- for (i = 0; i < NUM_OF_BYTES; i++)
- SET_VAR_BIT(result, NUM_OF_BYTES - (i+1), READ_VAR_BIT(crc, i));
-
- return result;
-
-} /* finalize_crc_32 */
-
diff --git a/util/ecst.h b/util/ecst.h
deleted file mode 100644
index 423f65a102..0000000000
--- a/util/ecst.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2015 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.
- */
-
-#ifndef ECST_H
-#define ECST_H
-
-/*---------------------------------------------------------------------------
- Includes
- --------------------------------------------------------------------------*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <curses.h>
-
-
-/*---------------------------------------------------------------------------
- Defines
- --------------------------------------------------------------------------*/
-
-/* For the beauty */
-#define TRUE 1
-#define FALSE 0
-
-/* CHANGEME when the version is updated */
-#define T_VER 1
-#define T_REV_MAJOR 0
-#define T_REV_MINOR 3
-
-/* Header starts by default at 0x20000 */
-#define FIRMWARE_OFFSET_FROM_HEADER 0x40
-
-#define ARM_FW_ENTRY_POINT_OFFSET 0x04
-
-/* Some useful offsets inside the header */
-#define HDR_ANCHOR_OFFSET 0
-#define HDR_EXTENDED_ANCHOR_OFFSET 4
-#define HDR_SPI_MAX_CLK_OFFSET 6
-#define HDR_SPI_READ_MODE_OFFSET 7
-#define HDR_ERR_DETECTION_CONF_OFFSET 8
-#define HDR_FW_LOAD_START_ADDR_OFFSET 9
-#define HDR_FW_ENTRY_POINT_OFFSET 13
-#define HDR_FW_ERR_DETECT_START_ADDR_OFFSET 17
-#define HDR_FW_ERR_DETECT_END_ADDR_OFFSET 21
-#define HDR_FW_LENGTH_OFFSET 25
-#define HDR_FLASH_SIZE_OFFSET 29
-#define HDR_RESERVED 30
-#define HDR_FW_HEADER_SIG_OFFSET 56
-#define HDR_FW_IMAGE_SIG_OFFSET 60
-
-
-#define FIRMW_CKSM_OFFSET 0x3C
-
-/* Header field known values */
-#define FW_HDR_ANCHOR 0x2A3B4D5E
-#define FW_HDR_EXT_ANCHOR_ENABLE 0xAB1E
-#define FW_HDR_EXT_ANCHOR_DISABLE 0x54E1
-#define FW_CRC_DISABLE 0x00
-#define FW_CRC_ENABLE 0x02
-#define HEADER_CRC_FIELDS_SIZE 8
-
-#define HDR_PTR_SIGNATURE 0x55AA650E
-
-#define CKSMCRC_INV_BIT_OFFSET 0x1
-
-/* Some common Sizes */
-#define STR_SIZE 200
-#define ARG_SIZE 100
-#define NAME_SIZE 160
-#define BUFF_SIZE 0x400
-#define HEADER_SIZE 64
-#define TMP_STR_SIZE 20
-#define PAD_VALUE 0x00
-
-
-#define MAX_ARGS 100
-
-/* Text Colors */
-#define TDBG 0x02 /* Dark Green */
-#define TPAS 0x0A /* light green */
-#define TINF 0x0B /* light turquise */
-#define TERR 0x0C /* light red */
-#define TUSG 0x0E /* light yellow */
-
-/* Indicates bin Command line parameters */
-#define BIN_FW_HDR_CRC_DISABLE 0x0001
-#define BIN_FW_CRC_DISABLE 0x0002
-#define BIN_FW_START 0x0004
-#define BIN_FW_SIZE 0x0008
-#define BIN_CK_FIRMWARE 0x0010
-#define BIN_FW_CKS_START 0x0020
-#define BIN_FW_CKS_SIZE 0x0040
-#define BIN_FW_CHANGE_SIG 0x0080
-#define BIN_FW_SPI_MAX_CLK 0x0100
-#define BIN_FW_LOAD_START_ADDR 0x0200
-#define BIN_FW_ENTRY_POINT 0x0400
-#define BIN_FW_LENGTH 0x0800
-#define BIN_FW_HDR_OFFSET 0x1000
-#define BIN_FW_USER_ARM_RESET 0x2000
-#define BIN_UNLIM_BURST_ENABLE 0x4000
-
-#define ECRP_OFFSET 0x01
-#define ECRP_INPUT_FILE 0x02
-#define ECRP_OUTPUT_FILE 0x04
-
-#define SPI_MAX_CLOCK_20_MHZ_VAL 20
-#define SPI_MAX_CLOCK_25_MHZ_VAL 25
-#define SPI_MAX_CLOCK_33_MHZ_VAL 33
-#define SPI_MAX_CLOCK_40_MHZ_VAL 40
-#define SPI_MAX_CLOCK_50_MHZ_VAL 50
-
-#define SPI_MAX_CLOCK_20_MHZ 0x00
-#define SPI_MAX_CLOCK_25_MHZ 0x01
-#define SPI_MAX_CLOCK_33_MHZ 0x02
-#define SPI_MAX_CLOCK_40_MHZ 0x03
-#define SPI_MAX_CLOCK_50_MHZ 0x04
-#define SPI_MAX_CLOCK_MASK 0xF8
-
-#define SPI_CLOCK_RATIO_1_VAL 1
-#define SPI_CLOCK_RATIO_2_VAL 2
-
-#define SPI_CLOCK_RATIO_1 0x07
-#define SPI_CLOCK_RATIO_2 0x08
-
-#define SPI_NORMAL_MODE_VAL "normal"
-#define SPI_SINGLE_MODE_VAL "fast"
-#define SPI_DUAL_MODE_VAL "dual"
-#define SPI_QUAD_MODE_VAL "quad"
-
-#define SPI_NORMAL_MODE 0x00
-#define SPI_SINGLE_MODE 0x01
-#define SPI_DUAL_MODE 0x03
-#define SPI_QUAD_MODE 0x04
-
-#define SPI_UNLIMITED_BURST_ENABLE 0x08
-
-#define FLASH_SIZE_1_MBYTES_VAL 1
-#define FLASH_SIZE_2_MBYTES_VAL 2
-#define FLASH_SIZE_4_MBYTES_VAL 4
-#define FLASH_SIZE_8_MBYTES_VAL 8
-#define FLASH_SIZE_16_MBYTES_VAL 16
-
-#define FLASH_SIZE_1_MBYTES 0x01
-#define FLASH_SIZE_2_MBYTES 0x03
-#define FLASH_SIZE_4_MBYTES 0x07
-#define FLASH_SIZE_8_MBYTES 0x0F
-#define FLASH_SIZE_16_MBYTES 0x1F
-
-/* Header fields default values. */
-#define SPI_MAX_CLOCK_DEFAULT SPI_MAX_CLOCK_20_MHZ_VAL
-#define SPI_READ_MODE_DEFAULT SPI_NORMAL_MODE
-#define FLASH_SIZE_DEFAULT FLASH_SIZE_16_MBYTES_VAL
-#define FW_CRC_START_ADDR 0x00000000
-
-#define ADDR_16_BYTES_ALIGNED_MASK 0x0000000F
-#define ADDR_4_BYTES_ALIGNED_MASK 0x00000003
-
-#define MAX_FLASH_SIZE 0x03ffffff
-
-/* Chips: convert from name to index. */
-#define NPCX5M5G 0
-#define NPCX5M6G 1
-#define NPCX7M5 2
-#define NPCX7M6 3
-#define NPCX7M7 4
-
-#define DEFAULT_CHIP NPCX5M5G
-
-#define NPCX5M5G_RAM_ADDR 0x100A8000
-#define NPCX5M5G_RAM_SIZE 0x20000
-#define NPCX5M6G_RAM_ADDR 0x10088000
-#define NPCX5M6G_RAM_SIZE 0x40000
-#define NPCX7M5X_RAM_ADDR 0x100A8000
-#define NPCX7M5X_RAM_SIZE 0x20000
-#define NPCX7M6X_RAM_ADDR 0x10090000
-#define NPCX7M6X_RAM_SIZE 0x40000
-#define NPCX7M7X_RAM_ADDR 0x10070000
-#define NPCX7M7X_RAM_SIZE 0x60000
-
-/*---------------------------------------------------------------------------
- Typedefs
- --------------------------------------------------------------------------*/
-
-/* Parameters for Binary manipulation */
-struct tbinparams {
- unsigned int anchor;
- unsigned short ext_anchor;
- unsigned char spi_max_clk;
- unsigned char spi_clk_ratio;
- unsigned char spi_read_mode;
- unsigned char err_detec_cnf;
- unsigned int fw_load_addr;
- unsigned int fw_ep;
- unsigned int fw_err_detec_s_addr;
- unsigned int fw_err_detec_e_addr;
- unsigned int fw_len;
- unsigned int flash_size;
- unsigned int hdr_crc;
- unsigned int fw_crc;
- unsigned int fw_hdr_offset;
- unsigned int bin_params;
-} bin_params_struct;
-
-enum verbose_level {
- NO_VERBOSE = 0,
- REGULAR_VERBOSE,
- SUPER_VERBOSE
-};
-
-enum calc_type {
- CALC_TYPE_NONE = 0,
- CALC_TYPE_CHECKSUM ,
- CALC_TYPE_CRC
-};
-
-struct chip_info {
- unsigned int ram_addr;
- unsigned int ram_size;
-} chip_info_struct;
-
-/*------------------------------------------------------------------------*/
-/* CRC Variable bit operation macros */
-/*------------------------------------------------------------------------*/
-#define NUM_OF_BYTES 32
-#define READ_VAR_BIT(var, nb) (((var) >> (nb)) & 0x1)
-#define SET_VAR_BIT(var, nb, val) ((var) |= ((val)<<(nb)))
-
-/*---------------------------------------------------------------------------
- Functions Declaration
- --------------------------------------------------------------------------*/
-
-/* main manipulation */
-int main_bin(struct tbinparams binary_parameters);
-int main_api(void);
-int main_hdr(void);
-
-/* General Checksum\CRC calculation */
-void init_calculation(unsigned int *check_sum_crc);
-void finalize_calculation(unsigned int *check_sum_crc);
-void update_calculation_information(unsigned char crc_con_dat);
-
-
-/* Checksum calculation etc. (BIN Specific) */
-int calc_header_crc_bin(unsigned int *pointer_header_checksum);
-int calc_firmware_csum_bin(unsigned int *p_cksum,
- unsigned int fw_offset,
- unsigned int fw_length);
-
-/* Checksum calculation etc. (ERP Specific) */
-int calc_erp_csum_bin(unsigned short *region_pointer_header_checksum,
- unsigned int region_pointer_ofs);
-
-/* No words - General */
-void exit_with_usage(void);
-int copy_file_to_file(char *dst_file_name,
- char *src_file_name,
- int offset,
- int origin);
-int write_to_file(unsigned int write_value,
- unsigned int offset,
- unsigned char num_of_bytes,
- char *print_string);
-int read_from_file(unsigned int offset,
- unsigned char size_to_read,
- unsigned int *read_value,
- char *print_string);
-
-/* Nice Particular Printf - General */
-__attribute__((__format__(__printf__, 2, 3)))
-void my_printf(int error_level, char *fmt, ...);
-
-int str_cmp_no_case(const char *s1, const char *s2);
-int get_file_length(FILE *stream);
-
-#endif /* ECST_H */
diff --git a/util/ectool.c b/util/ectool.c
deleted file mode 100644
index 32ebe478e9..0000000000
--- a/util/ectool.c
+++ /dev/null
@@ -1,9397 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdbool.h>
-
-#include "anx74xx.h"
-#include "battery.h"
-#include "comm-host.h"
-#include "chipset.h"
-#include "compile_time_macros.h"
-#include "cros_ec_dev.h"
-#include "ec_panicinfo.h"
-#include "ec_flash.h"
-#include "ec_version.h"
-#include "ectool.h"
-#include "i2c.h"
-#include "lightbar.h"
-#include "lock/gec_lock.h"
-#include "misc_util.h"
-#include "panic.h"
-#include "ps8xxx.h"
-#include "usb_pd.h"
-
-/* Maximum flash size (16 MB, conservative) */
-#define MAX_FLASH_SIZE 0x1000000
-
-/*
- * Calculate the expected response for a hello ec command.
- */
-#define HELLO_RESP(in_data) ((in_data) + 0x01020304)
-
-/* Command line options */
-enum {
- OPT_DEV = 1000,
- OPT_INTERFACE,
- OPT_NAME,
- OPT_ASCII,
- OPT_I2C_BUS,
-};
-
-static struct option long_opts[] = {
- {"dev", 1, 0, OPT_DEV},
- {"interface", 1, 0, OPT_INTERFACE},
- {"name", 1, 0, OPT_NAME},
- {"ascii", 0, 0, OPT_ASCII},
- {"i2c_bus", 1, 0, OPT_I2C_BUS},
- {NULL, 0, 0, 0}
-};
-
-#define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */
-
-const char help_str[] =
- "Commands:\n"
- " adcread <channel>\n"
- " Read an ADC channel.\n"
- " addentropy [reset]\n"
- " Add entropy to device secret\n"
- " apreset\n"
- " Issue AP reset\n"
- " autofanctrl <on>\n"
- " Turn on automatic fan speed control.\n"
- " backlight <enabled>\n"
- " Enable/disable LCD backlight\n"
- " battery\n"
- " Prints battery info\n"
- " batterycutoff [at-shutdown]\n"
- " Cut off battery output power\n"
- " batteryparam\n"
- " Read or write board-specific battery parameter\n"
- " boardversion\n"
- " Prints the board version\n"
- " cbi\n"
- " Get/Set Cros Board Info\n"
- " chargecurrentlimit\n"
- " Set the maximum battery charging current\n"
- " chargecontrol\n"
- " Force the battery to stop charging or discharge\n"
- " chargeoverride\n"
- " Overrides charge port selection logic\n"
- " chargestate\n"
- " Handle commands related to charge state v2 (and later)\n"
- " chipinfo\n"
- " Prints chip info\n"
- " cmdversions <cmd>\n"
- " Prints supported version mask for a command number\n"
- " console\n"
- " Prints the last output to the EC debug console\n"
- " cec\n"
- " Read or write CEC messages and settings\n"
- " echash [CMDS]\n"
- " Various EC hash commands\n"
- " eventclear <mask>\n"
- " Clears EC host events flags where mask has bits set\n"
- " eventclearb <mask>\n"
- " Clears EC host events flags copy B where mask has bits set\n"
- " eventget\n"
- " Prints raw EC host event flags\n"
- " eventgetb\n"
- " Prints raw EC host event flags copy B\n"
- " eventgetscimask\n"
- " Prints SCI mask for EC host events\n"
- " eventgetsmimask\n"
- " Prints SMI mask for EC host events\n"
- " eventgetwakemask\n"
- " Prints wake mask for EC host events\n"
- " eventsetscimask <mask>\n"
- " Sets the SCI mask for EC host events\n"
- " eventsetsmimask <mask>\n"
- " Sets the SMI mask for EC host events\n"
- " eventsetwakemask <mask>\n"
- " Sets the wake mask for EC host events\n"
- " extpwrlimit\n"
- " Set the maximum external power limit\n"
- " fanduty <percent>\n"
- " Forces the fan PWM to a constant duty cycle\n"
- " flasherase <offset> <size>\n"
- " Erases EC flash\n"
- " flasheraseasync <offset> <size>\n"
- " Erases EC flash asynchronously\n"
- " flashinfo\n"
- " Prints information on the EC flash\n"
- " flashspiinfo\n"
- " Prints information on EC SPI flash, if present\n"
- " flashpd <dev_id> <port> <filename>\n"
- " Flash commands over PD\n"
- " flashprotect [now] [enable | disable]\n"
- " Prints or sets EC flash protection state\n"
- " flashread <offset> <size> <outfile>\n"
- " Reads from EC flash to a file\n"
- " flashwrite <offset> <infile>\n"
- " Writes to EC flash from a file\n"
- " forcelidopen <enable>\n"
- " Forces the lid switch to open position\n"
- " fpcontext\n"
- " Sets the fingerprint sensor context\n"
- " fpencstatus\n"
- " Prints status of Fingerprint sensor encryption engine\n"
- " fpframe\n"
- " Retrieve the finger image as a PGM image\n"
- " fpinfo\n"
- " Prints information about the Fingerprint sensor\n"
- " fpmode [capture|deepsleep|fingerdown|fingerup]\n"
- " Configure/Read the fingerprint sensor current mode\n"
- " fpseed\n"
- " Sets the value of the TPM seed.\n"
- " fpstats\n"
- " Prints timing statisitcs relating to capture and matching\n"
- " fptemplate [<infile>|<index 0..2>]\n"
- " Add a template if <infile> is provided, else dump it\n"
- " gpioget <GPIO name>\n"
- " Get the value of GPIO signal\n"
- " gpioset <GPIO name>\n"
- " Set the value of GPIO signal\n"
- " hangdetect <flags> <event_msec> <reboot_msec> | stop | start\n"
- " Configure or start/stop the hang detect timer\n"
- " hello\n"
- " Checks for basic communication with EC\n"
- " hibdelay [sec]\n"
- " Set the delay before going into hibernation\n"
- " hostsleepstate\n"
- " Report host sleep state to the EC\n"
- " i2cprotect <port> [status]\n"
- " Protect EC's I2C bus\n"
- " i2cread\n"
- " Read I2C bus\n"
- " i2cwrite\n"
- " Write I2C bus\n"
- " i2cxfer <port> <slave_addr> <read_count> [write bytes...]\n"
- " Perform I2C transfer on EC's I2C bus\n"
- " infopddev <port>\n"
- " Get info about USB type-C accessory attached to port\n"
- " inventory\n"
- " Return the list of supported features\n"
- " kbfactorytest\n"
- " Scan out keyboard if any pins are shorted\n"
- " kbid\n"
- " Get keyboard ID of supported keyboards\n"
- " kbinfo\n"
- " Dump keyboard matrix dimensions\n"
- " kbpress\n"
- " Simulate key press\n"
- " keyscan <beat_us> <filename>\n"
- " Test low-level key scanning\n"
- " led <name> <query | auto | off | <color> | <color>=<value>...>\n"
- " Set the color of an LED or query brightness range\n"
- " lightbar [CMDS]\n"
- " Various lightbar control commands\n"
- " mkbpget <buttons|switches>\n"
- " Get MKBP buttons/switches supported mask and current state\n"
- " mkbpwakemask <get|set> <event|hostevent> [mask]\n"
- " Get or Set the MKBP event wake mask, or host event wake mask\n"
- " motionsense [CMDS]\n"
- " Various motion sense control commands\n"
- " panicinfo\n"
- " Prints saved panic info\n"
- " pause_in_s5 [on|off]\n"
- " Whether or not the AP should pause in S5 on shutdown\n"
- " pdcontrol [suspend|resume|reset|disable|on]\n"
- " Controls the PD chip\n"
- " pdchipinfo <port>\n"
- " Get PD chip information\n"
- " pdlog\n"
- " Prints the PD event log entries\n"
- " pdwritelog <type> <port>\n"
- " Writes a PD event log of the given <type>\n"
- " pdgetmode <port>\n"
- " Get All USB-PD alternate SVIDs and modes on <port>\n"
- " pdsetmode <port> <svid> <opos>\n"
- " Set USB-PD alternate SVID and mode on <port>\n"
- " port80flood\n"
- " Rapidly write bytes to port 80\n"
- " port80read\n"
- " Print history of port 80 write\n"
- " powerinfo\n"
- " Prints power-related information\n"
- " protoinfo\n"
- " Prints EC host protocol information\n"
- " pstoreinfo\n"
- " Prints information on the EC host persistent storage\n"
- " pstoreread <offset> <size> <outfile>\n"
- " Reads from EC host persistent storage to a file\n"
- " pstorewrite <offset> <infile>\n"
- " Writes to EC host persistent storage from a file\n"
- " pwmgetfanrpm [<index> | all]\n"
- " Prints current fan RPM\n"
- " pwmgetkblight\n"
- " Prints current keyboard backlight percent\n"
- " pwmgetnumfans\n"
- " Prints the number of fans present\n"
- " pwmgetduty\n"
- " Prints the current 16 bit duty cycle for given PWM\n"
- " pwmsetfanrpm <targetrpm>\n"
- " Set target fan RPM\n"
- " pwmsetkblight <percent>\n"
- " Set keyboard backlight in percent\n"
- " pwmsetduty\n"
- " Set 16 bit duty cycle of given PWM\n"
- " rand <num_bytes>\n"
- " generate <num_bytes> of random numbers\n"
- " readtest <patternoffset> <size>\n"
- " Reads a pattern from the EC via LPC\n"
- " reboot_ec <RO|RW|cold|hibernate|hibernate-clear-ap-off|disable-jump>"
- " [at-shutdown|switch-slot]\n"
- " Reboot EC to RO or RW\n"
- " rollbackinfo\n"
- " Print rollback block information\n"
- " rtcget\n"
- " Print real-time clock\n"
- " rtcgetalarm\n"
- " Print # of seconds before real-time clock alarm goes off.\n"
- " rtcset <time>\n"
- " Set real-time clock\n"
- " rtcsetalarm <sec>\n"
- " Set real-time clock alarm to go off in <sec> seconds\n"
- " rwhashpd <dev_id> <HASH[0] ... <HASH[4]>\n"
- " Set entry in PD MCU's device rw_hash table.\n"
- " rwsigaction\n"
- " Control the behavior of RWSIG task.\n"
- " rwsigstatus\n"
- " Run RW signature verification and get status.\n"
- " sertest\n"
- " Serial output test for COM2\n"
- " stress [reboot] [help]\n"
- " Stress test the ec host command interface.\n"
- " switches\n"
- " Prints current EC switch positions\n"
- " temps <sensorid>\n"
- " Print temperature.\n"
- " tempsinfo <sensorid>\n"
- " Print temperature sensor info.\n"
- " thermalget <platform-specific args>\n"
- " Get the threshold temperature values from the thermal engine.\n"
- " thermalset <platform-specific args>\n"
- " Set the threshold temperature values for the thermal engine.\n"
- " tpselftest\n"
- " Run touchpad self test.\n"
- " tpframeget\n"
- " Get touchpad frame data.\n"
- " tmp006cal <tmp006_index> [params...]\n"
- " Get/set TMP006 calibration\n"
- " tmp006raw <tmp006_index>\n"
- " Get raw TMP006 data\n"
- " uptimeinfo\n"
- " Get info about how long the EC has been running and the most\n"
- " recent AP resets\n"
- " usbchargemode <port> <mode> [<inhibit_charge>]\n"
- " Set USB charging mode\n"
- " usbmux <mux>\n"
- " Set USB mux switch state\n"
- " usbpd <port> <auto | "
- "[toggle|toggle-off|sink|source] [none|usb|dp|dock] "
- "[dr_swap|pr_swap|vconn_swap]>\n"
- " Control USB PD/type-C\n"
- " usbpdmuxinfo\n"
- " Get USB-C SS mux info\n"
- " usbpdpower [port]\n"
- " Get USB PD power information\n"
- " version\n"
- " Prints EC version\n"
- " waitevent <type> [<timeout>]\n"
- " Wait for the MKBP event of type and display it\n"
- " wireless <flags> [<mask> [<suspend_flags> <suspend_mask>]]\n"
- " Enable/disable WLAN/Bluetooth radio\n"
- "";
-
-/* Note: depends on enum system_image_copy_t */
-static const char * const image_names[] = {"unknown", "RO", "RW"};
-
-/* Note: depends on enum ec_led_colors */
-static const char * const led_color_names[] = {
- "red", "green", "blue", "yellow", "white", "amber"};
-BUILD_ASSERT(ARRAY_SIZE(led_color_names) == EC_LED_COLOR_COUNT);
-
-/* Note: depends on enum ec_led_id */
-static const char * const led_names[] = {
- "battery", "power", "adapter", "left", "right", "recovery_hwreinit",
- "sysrq debug" };
-BUILD_ASSERT(ARRAY_SIZE(led_names) == EC_LED_ID_COUNT);
-
-/* ASCII mode for printing, default off */
-static int ascii_mode = 0;
-
-/* Check SBS numerical value range */
-int is_battery_range(int val)
-{
- return (val >= 0 && val <= 65535) ? 1 : 0;
-}
-
-int parse_bool(const char *s, int *dest)
-{
- if (!strcasecmp(s, "off") || !strncasecmp(s, "dis", 3) ||
- tolower(*s) == 'f' || tolower(*s) == 'n') {
- *dest = 0;
- return 1;
- } else if (!strcasecmp(s, "on") || !strncasecmp(s, "ena", 3) ||
- tolower(*s) == 't' || tolower(*s) == 'y') {
- *dest = 1;
- return 1;
- } else {
- return 0;
- }
-}
-
-void print_help(const char *prog, int print_cmds)
-{
- printf("Usage: %s [--dev=n] [--interface=dev|i2c|lpc] [--i2c_bus=n]",
- prog);
- printf("[--name=cros_ec|cros_fp|cros_pd|cros_scp|cros_ish] [--ascii] ");
- printf("<command> [params]\n\n");
- printf(" --i2c_bus=n Specifies the number of an I2C bus to use. For\n"
- " example, to use /dev/i2c-7, pass --i2c_bus=7.\n"
- " Implies --interface=i2c.\n\n");
- if (print_cmds)
- puts(help_str);
- else
- printf("Use '%s help' to print a list of commands.\n", prog);
-}
-
-static uint8_t read_mapped_mem8(uint8_t offset)
-{
- int ret;
- uint8_t val;
-
- ret = ec_readmem(offset, sizeof(val), &val);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return val;
-}
-
-static uint16_t read_mapped_mem16(uint8_t offset)
-{
- int ret;
- uint16_t val;
-
- ret = ec_readmem(offset, sizeof(val), &val);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return val;
-}
-
-static uint32_t read_mapped_mem32(uint8_t offset)
-{
- int ret;
- uint32_t val;
-
- ret = ec_readmem(offset, sizeof(val), &val);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return val;
-}
-
-static int read_mapped_string(uint8_t offset, char *buffer, int max_size)
-{
- int ret;
-
- ret = ec_readmem(offset, max_size, buffer);
- if (ret <= 0) {
- fprintf(stderr, "failure in %s(): %d\n", __func__, ret);
- exit(1);
- }
- return ret;
-}
-
-int cmd_adc_read(int argc, char *argv[])
-{
- char *e;
- struct ec_params_adc_read p;
- struct ec_response_adc_read r;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <adc channel>\n", argv[0]);
- return -1;
- }
-
- p.adc_channel = (uint8_t)strtoul(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "\"%s\": invalid channel!\n", argv[1]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_ADC_READ, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv > 0) {
- printf("%s: %d\n", argv[1], r.adc_value);
- return 0;
- }
-
- return rv;
-}
-
-int cmd_add_entropy(int argc, char *argv[])
-{
- struct ec_params_rollback_add_entropy p;
- int rv;
- int tries = 100; /* Wait for 10 seconds at most */
-
- if (argc >= 2 && !strcmp(argv[1], "reset"))
- p.action = ADD_ENTROPY_RESET_ASYNC;
- else
- p.action = ADD_ENTROPY_ASYNC;
-
- rv = ec_command(EC_CMD_ADD_ENTROPY, 0, &p, sizeof(p), NULL, 0);
-
- if (rv != EC_RES_SUCCESS)
- goto out;
-
- while (tries--) {
- usleep(100000);
-
- p.action = ADD_ENTROPY_GET_RESULT;
- rv = ec_command(EC_CMD_ADD_ENTROPY, 0, &p, sizeof(p), NULL, 0);
-
- if (rv == EC_RES_SUCCESS) {
- printf("Entropy added successfully\n");
- return EC_RES_SUCCESS;
- }
-
- /* Abort if EC returns an error other than EC_RES_BUSY. */
- if (rv <= -EECRESULT && rv != -EECRESULT-EC_RES_BUSY)
- goto out;
- }
-
- rv = -EECRESULT-EC_RES_TIMEOUT;
-out:
- fprintf(stderr, "Failed to add entropy: %d\n", rv);
- return rv;
-}
-
-int cmd_hello(int argc, char *argv[])
-{
- struct ec_params_hello p;
- struct ec_response_hello r;
- int rv;
-
- p.in_data = 0xa0b0c0d0;
-
- rv = ec_command(EC_CMD_HELLO, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.out_data != 0xa1b2c3d4) {
- fprintf(stderr, "Expected response 0x%08x, got 0x%08x\n",
- 0xa1b2c3d4, r.out_data);
- return -1;
- }
-
- printf("EC says hello!\n");
- return 0;
-}
-
-int cmd_hibdelay(int argc, char *argv[])
-{
- struct ec_params_hibernation_delay p;
- struct ec_response_hibernation_delay r;
- char *e;
- int rv;
-
- if (argc < 2) {
- p.seconds = 0; /* Just read the current settings. */
- } else {
- p.seconds = strtoul(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid number\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_HIBERNATION_DELAY, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "err: rv=%d\n", rv);
- return -1;
- }
-
- printf("Hibernation delay: %u s\n", r.hibernate_delay);
- printf("Time G3: %u s\n", r.time_g3);
- printf("Time left: %u s\n", r.time_remaining);
- return 0;
-}
-
-static int get_latest_cmd_version(uint8_t cmd, int *version)
-{
- struct ec_params_get_cmd_versions p;
- struct ec_response_get_cmd_versions r;
- int rv;
-
- *version = 0;
- /* Figure out the latest version of the given command the EC supports */
- p.cmd = cmd;
- rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- if (rv == -EC_RES_INVALID_PARAM)
- printf("Command 0x%02x not supported by EC.\n",
- EC_CMD_GET_CMD_VERSIONS);
- return rv;
- }
-
- if (r.version_mask)
- *version = __fls(r.version_mask);
-
- return rv;
-}
-
-int cmd_hostsleepstate(int argc, char *argv[])
-{
- struct ec_params_host_sleep_event p;
- struct ec_params_host_sleep_event_v1 p1;
- struct ec_response_host_sleep_event_v1 r;
- void *pp = &p;
- size_t psize = sizeof(p), rsize = 0;
- char *afterscan;
- int rv;
- int version = 0, max_version = 0;
- uint32_t timeout, transitions;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s "
- "[suspend|wsuspend|resume|freeze|thaw] [timeout]\n",
- argv[0]);
- return -1;
- }
-
- rv = get_latest_cmd_version(EC_CMD_HOST_SLEEP_EVENT, &max_version);
- if (rv < 0)
- return rv;
-
- if (!strcmp(argv[1], "suspend"))
- p.sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND;
- else if (!strcmp(argv[1], "wsuspend"))
- p.sleep_event = HOST_SLEEP_EVENT_S3_WAKEABLE_SUSPEND;
- else if (!strcmp(argv[1], "resume"))
- p.sleep_event = HOST_SLEEP_EVENT_S3_RESUME;
- else if (!strcmp(argv[1], "freeze")) {
- p.sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND;
- if (max_version >= 1) {
- p1.sleep_event = p.sleep_event;
- p1.reserved = 0;
- p1.suspend_params.sleep_timeout_ms =
- EC_HOST_SLEEP_TIMEOUT_DEFAULT;
-
- if (argc > 2) {
- p1.suspend_params.sleep_timeout_ms =
- strtoul(argv[2], &afterscan, 0);
-
- if ((*afterscan != '\0') ||
- (afterscan == argv[2])) {
- fprintf(stderr,
- "Invalid value: %s\n",
- argv[2]);
-
- return -1;
- }
- }
-
- pp = &p1;
- psize = sizeof(p1);
- version = 1;
- }
-
- } else if (!strcmp(argv[1], "thaw")) {
- p.sleep_event = HOST_SLEEP_EVENT_S0IX_RESUME;
- if (max_version >= 1) {
- version = 1;
- rsize = sizeof(r);
- }
- } else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_SLEEP_EVENT, version, pp, psize, &r, rsize);
- if (rv < 0) {
- fprintf(stderr, "EC host sleep command failed: %d\n", rv);
- return rv;
- }
-
- if (rsize) {
- timeout = r.resume_response.sleep_transitions &
- EC_HOST_RESUME_SLEEP_TIMEOUT;
-
- transitions = r.resume_response.sleep_transitions &
- EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK;
-
- printf("%s%d sleep line transitions.\n",
- timeout ? "Timeout: " : "",
- transitions);
- }
-
- return 0;
-}
-
-int cmd_test(int argc, char *argv[])
-{
- struct ec_params_test_protocol p = {
- .buf = "0123456789abcdef0123456789ABCDEF"
- };
- struct ec_response_test_protocol r;
- int rv, version = 0;
- char *e;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s result length [version]\n",
- argv[0]);
- return -1;
- }
-
- p.ec_result = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid param (result)\n");
- return -1;
- }
- p.ret_len = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid param (length)\n");
- return -1;
- }
-
- if (argc > 3) {
- version = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid param (version)\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_TEST_PROTOCOL, version,
- &p, sizeof(p), &r, sizeof(r));
- printf("rv = %d\n", rv);
-
- return rv;
-}
-
-int cmd_s5(int argc, char *argv[])
-{
- struct ec_params_get_set_value p;
- struct ec_params_get_set_value r;
- int rv, param;
-
- p.flags = 0;
-
- if (argc > 1) {
- p.flags |= EC_GSV_SET;
- if (!parse_bool(argv[1], &param)) {
- fprintf(stderr, "invalid arg \"%s\"\n", argv[1]);
- return -1;
- }
- p.value = param;
- }
-
- rv = ec_command(EC_CMD_GSV_PAUSE_IN_S5, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv > 0)
- printf("%s\n", r.value ? "on" : "off");
-
- return rv < 0;
-}
-
-static const char * const ec_feature_names[] = {
- [EC_FEATURE_LIMITED] = "Limited image, load RW for more",
- [EC_FEATURE_FLASH] = "Flash",
- [EC_FEATURE_PWM_FAN] = "Direct Fan power management",
- [EC_FEATURE_PWM_KEYB] = "Keyboard backlight",
- [EC_FEATURE_LIGHTBAR] = "Lightbar",
- [EC_FEATURE_LED] = "LED",
- [EC_FEATURE_MOTION_SENSE] = "Motion Sensors",
- [EC_FEATURE_KEYB] = "Keyboard",
- [EC_FEATURE_PSTORE] = "Host Permanent Storage",
- [EC_FEATURE_PORT80] = "BIOS Port 80h access",
- [EC_FEATURE_THERMAL] = "Thermal management",
- [EC_FEATURE_BKLIGHT_SWITCH] = "Switch backlight on/off",
- [EC_FEATURE_WIFI_SWITCH] = "Switch wifi on/off",
- [EC_FEATURE_HOST_EVENTS] = "Host event",
- [EC_FEATURE_GPIO] = "GPIO",
- [EC_FEATURE_I2C] = "I2C master",
- [EC_FEATURE_CHARGER] = "Charger",
- [EC_FEATURE_BATTERY] = "Simple Battery",
- [EC_FEATURE_SMART_BATTERY] = "Smart Battery",
- [EC_FEATURE_HANG_DETECT] = "Host hang detection",
- [EC_FEATURE_PMU] = "Power Management",
- [EC_FEATURE_SUB_MCU] = "Control downstream MCU",
- [EC_FEATURE_USB_PD] = "USB Cros Power Delivery",
- [EC_FEATURE_USB_MUX] = "USB Multiplexer",
- [EC_FEATURE_MOTION_SENSE_FIFO] = "FIFO for Motion Sensors events",
- [EC_FEATURE_VSTORE] = "Temporary secure vstore",
- [EC_FEATURE_USBC_SS_MUX_VIRTUAL] = "Host-controlled USB-C SS mux",
- [EC_FEATURE_RTC] = "Real-time clock",
- [EC_FEATURE_FINGERPRINT] = "Fingerprint",
- [EC_FEATURE_TOUCHPAD] = "Touchpad",
- [EC_FEATURE_RWSIG] = "RWSIG task",
- [EC_FEATURE_DEVICE_EVENT] = "Device events reporting",
- [EC_FEATURE_UNIFIED_WAKE_MASKS] = "Unified wake masks for LPC/eSPI",
- [EC_FEATURE_HOST_EVENT64] = "64-bit host events",
- [EC_FEATURE_EXEC_IN_RAM] = "Execute code in RAM",
- [EC_FEATURE_CEC] = "Consumer Electronics Control",
- [EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS] =
- "Tight timestamp for sensors events",
- [EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS] =
- "Refined tablet mode hysteresis",
- [EC_FEATURE_ISH] = "Intel Integrated Sensor Hub",
-};
-
-int cmd_inventory(int argc, char *argv[])
-{
- struct ec_response_get_features r;
- int rv, i, j, idx;
-
- rv = ec_command(EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("EC supported features:\n");
- for (i = 0, idx = 0; i < 2; i++) {
- for (j = 0; j < 32; j++, idx++) {
- if (r.flags[i] & BIT(j)) {
- if (idx >= ARRAY_SIZE(ec_feature_names) ||
- !ec_feature_names[idx] ||
- strlen(ec_feature_names[idx]) == 0)
- printf("%-4d: Unknown feature\n", idx);
- else
- printf("%-4d: %s support\n",
- idx, ec_feature_names[idx]);
- }
- }
- }
- return 0;
-}
-
-
-int cmd_cmdversions(int argc, char *argv[])
-{
- struct ec_params_get_cmd_versions p;
- struct ec_response_get_cmd_versions r;
- char *e;
- int cmd;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <cmd>\n", argv[0]);
- return -1;
- }
- cmd = strtol(argv[1], &e, 0);
- if ((e && *e) || cmd < 0 || cmd > 0xff) {
- fprintf(stderr, "Bad command number.\n");
- return -1;
- }
-
- p.cmd = cmd;
- rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- if (rv == -EC_RES_INVALID_PARAM)
- printf("Command 0x%02x not supported by EC.\n", cmd);
-
- return rv;
- }
-
- printf("Command 0x%02x supports version mask 0x%08x\n",
- cmd, r.version_mask);
- return 0;
-}
-
-/*
- * Convert a reset cause ID to human-readable string, providing total coverage
- * of the 'cause' space. The returned string points to static storage and must
- * not be free()ed.
- */
-static const char *reset_cause_to_str(uint16_t cause)
-{
- static const char * const reset_causes[] = {
- "(reset unknown)",
- "reset: board custom",
- "reset: ap hang detected",
- "reset: console command",
- "reset: host command",
- "reset: keyboard sysreset",
- "reset: keyboard warm reboot",
- "reset: debug warm reboot",
- "reset: at AP's request",
- "reset: during EC initialization",
- "reset: AP watchdog",
- };
- BUILD_ASSERT(ARRAY_SIZE(reset_causes) == CHIPSET_RESET_COUNT);
-
- static const char * const shutdown_causes[] = {
- "shutdown: power failure",
- "shutdown: during EC initialization",
- "shutdown: board custom",
- "shutdown: battery voltage startup inhibit",
- "shutdown: power wait asserted",
- "shutdown: critical battery",
- "shutdown: by console command",
- "shutdown: entering G3",
- "shutdown: thermal",
- "shutdown: power button",
- };
- BUILD_ASSERT(ARRAY_SIZE(shutdown_causes) ==
- CHIPSET_SHUTDOWN_COUNT - CHIPSET_SHUTDOWN_BEGIN);
-
- if (cause < CHIPSET_RESET_COUNT)
- return reset_causes[cause];
-
- if (cause < CHIPSET_SHUTDOWN_BEGIN)
- return "(reset unknown)";
-
- if (cause < CHIPSET_SHUTDOWN_COUNT)
- return shutdown_causes[cause - CHIPSET_SHUTDOWN_BEGIN];
-
- return "(shutdown unknown)";
-}
-
-int cmd_uptimeinfo(int argc, char *argv[])
-{
- struct ec_response_uptime_info r;
- int rv;
- int i;
- int flag_count;
- uint32_t flag;
- static const char * const reset_flag_descs[] = {
- #include "reset_flag_desc.inc"
- };
-
- if (argc != 1) {
- fprintf(stderr, "uptimeinfo takes no arguments");
- return -1;
- }
-
- rv = ec_command(EC_CMD_GET_UPTIME_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_GET_UPTIME_INFO failed; %d\n",
- rv);
- return rv;
- }
-
- printf("EC uptime: %d.%03d seconds\n",
- r.time_since_ec_boot_ms / 1000,
- r.time_since_ec_boot_ms % 1000);
-
- printf("AP resets since EC boot: %d\n", r.ap_resets_since_ec_boot);
-
- printf("Most recent AP reset causes:\n");
- for (i = 0; i != ARRAY_SIZE(r.recent_ap_reset); ++i) {
- if (r.recent_ap_reset[i].reset_time_ms == 0)
- continue;
-
- printf("\t%d.%03d: %s\n",
- r.recent_ap_reset[i].reset_time_ms / 1000,
- r.recent_ap_reset[i].reset_time_ms % 1000,
- reset_cause_to_str(r.recent_ap_reset[i].reset_cause));
- }
-
- printf("EC reset flags at last EC boot: ");
-
- if (!r.ec_reset_flags) {
- printf("unknown\n");
- return 0;
- }
-
- flag_count = 0;
- for (flag = 0; flag < ARRAY_SIZE(reset_flag_descs); ++flag) {
- if ((r.ec_reset_flags & BIT(flag)) != 0) {
- if (flag_count)
- printf(" | ");
- printf(reset_flag_descs[flag]);
- flag_count++;
- }
- }
-
- if (r.ec_reset_flags >= BIT(flag)) {
- if (flag_count)
- printf(" | ");
- printf("no-desc");
- }
- printf("\n");
- return 0;
-}
-
-int cmd_version(int argc, char *argv[])
-{
- struct ec_response_get_version r;
- char *build_string = (char *)ec_inbuf;
- int rv;
-
- rv = ec_command(EC_CMD_GET_VERSION, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_GET_VERSION failed: %d\n", rv);
- goto exit;
- }
- rv = ec_command(EC_CMD_GET_BUILD_INFO, 0,
- NULL, 0, ec_inbuf, ec_max_insize);
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_GET_BUILD_INFO failed: %d\n",
- rv);
- goto exit;
- }
- rv = 0;
-
- /* Ensure versions are null-terminated before we print them */
- r.version_string_ro[sizeof(r.version_string_ro) - 1] = '\0';
- r.version_string_rw[sizeof(r.version_string_rw) - 1] = '\0';
- build_string[ec_max_insize - 1] = '\0';
-
- /* Print versions */
- printf("RO version: %s\n", r.version_string_ro);
- printf("RW version: %s\n", r.version_string_rw);
- printf("Firmware copy: %s\n",
- (r.current_image < ARRAY_SIZE(image_names) ?
- image_names[r.current_image] : "?"));
- printf("Build info: %s\n", build_string);
-exit:
- printf("Tool version: %s %s %s\n", CROS_ECTOOL_VERSION, DATE, BUILDER);
-
- return rv;
-}
-
-
-int cmd_read_test(int argc, char *argv[])
-{
- struct ec_params_read_test p;
- struct ec_response_read_test r;
- int offset, size;
- int errors = 0;
- int rv;
- int i;
- char *e;
- char *buf;
- uint32_t *b;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <pattern_offset> <size>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Reading %d bytes with pattern offset 0x%x...\n", size, offset);
-
- buf = (char *)malloc(size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- /* Read data in chunks */
- for (i = 0; i < size; i += sizeof(r.data)) {
- p.offset = offset + i / sizeof(uint32_t);
- p.size = MIN(size - i, sizeof(r.data));
- rv = ec_command(EC_CMD_READ_TEST, 0, &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- free(buf);
- return rv;
- }
- memcpy(buf + i, r.data, p.size);
- }
-
- /* Check data */
- for (i = 0, b = (uint32_t *)buf; i < size / 4; i++, b++) {
- if (*b != i + offset) {
- printf("Mismatch at byte offset 0x%x: "
- "expected 0x%08x, got 0x%08x\n",
- (int)(i * sizeof(uint32_t)), i + offset, *b);
- errors++;
- }
- }
-
- free(buf);
- if (errors) {
- printf("Found %d errors\n", errors);
- return -1;
- }
-
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_reboot_ec(int argc, char *argv[])
-{
- struct ec_params_reboot_ec p;
- int rv, i;
-
- if (argc < 2) {
- /*
- * No params specified so tell the EC to reboot immediately.
- * That reboots the AP as well, so unlikely we'll be around
- * to see a return code from this...
- */
- rv = ec_command(EC_CMD_REBOOT, 0, NULL, 0, NULL, 0);
- return (rv < 0 ? rv : 0);
- }
-
- /* Parse command */
- if (!strcmp(argv[1], "cancel"))
- p.cmd = EC_REBOOT_CANCEL;
- else if (!strcmp(argv[1], "RO"))
- p.cmd = EC_REBOOT_JUMP_RO;
- else if (!strcmp(argv[1], "RW"))
- p.cmd = EC_REBOOT_JUMP_RW;
- else if (!strcmp(argv[1], "cold"))
- p.cmd = EC_REBOOT_COLD;
- else if (!strcmp(argv[1], "disable-jump"))
- p.cmd = EC_REBOOT_DISABLE_JUMP;
- else if (!strcmp(argv[1], "hibernate"))
- p.cmd = EC_REBOOT_HIBERNATE;
- else if (!strcmp(argv[1], "hibernate-clear-ap-off"))
- p.cmd = EC_REBOOT_HIBERNATE_CLEAR_AP_OFF;
- else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- return -1;
- }
-
- /* Parse flags, if any */
- p.flags = 0;
- for (i = 2; i < argc; i++) {
- if (!strcmp(argv[i], "at-shutdown")) {
- p.flags |= EC_REBOOT_FLAG_ON_AP_SHUTDOWN;
- } else if (!strcmp(argv[i], "switch-slot")) {
- p.flags |= EC_REBOOT_FLAG_SWITCH_RW_SLOT;
- } else {
- fprintf(stderr, "Unknown flag: %s\n", argv[i]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_REBOOT_EC, 0, &p, sizeof(p), NULL, 0);
- return (rv < 0 ? rv : 0);
-}
-
-
-int cmd_flash_info(int argc, char *argv[])
-{
- struct ec_response_flash_info_1 r;
- int cmdver = 1;
- int rsize = sizeof(r);
- int rv;
-
- memset(&r, 0, sizeof(r));
-
- if (!ec_cmd_version_supported(EC_CMD_FLASH_INFO, cmdver)) {
- /* Fall back to version 0 command */
- cmdver = 0;
- rsize = sizeof(struct ec_response_flash_info);
- }
-
- rv = ec_command(EC_CMD_FLASH_INFO, cmdver, NULL, 0, &r, rsize);
- if (rv < 0)
- return rv;
-
- printf("FlashSize %d\nWriteSize %d\nEraseSize %d\nProtectSize %d\n",
- r.flash_size, r.write_block_size, r.erase_block_size,
- r.protect_block_size);
-
- if (cmdver >= 1) {
- /* Fields added in ver.1 available */
- printf("WriteIdealSize %d\nFlags 0x%x\n",
- r.write_ideal_size, r.flags);
- }
-
- return 0;
-}
-
-int cmd_rand(int argc, char *argv[])
-{
- struct ec_params_rand_num p;
- struct ec_response_rand_num *r;
- size_t r_size;
- int64_t num_bytes;
- int64_t i;
- char *e;
- int rv = 0;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <num_bytes>\n", argv[0]);
- return -1;
- }
-
- num_bytes = strtol(argv[1], &e, 0);
- if ((e && *e) || (errno == ERANGE)) {
- fprintf(stderr, "Invalid num_bytes argument\n");
- return -1;
- }
-
- r = ec_inbuf;
-
- for (i = 0; i < num_bytes; i += ec_max_insize) {
- p.num_rand_bytes = ec_max_insize;
- if (num_bytes - i < p.num_rand_bytes)
- p.num_rand_bytes = num_bytes - i;
-
- r_size = p.num_rand_bytes;
-
- rv = ec_command(EC_CMD_RAND_NUM, EC_VER_RAND_NUM, &p, sizeof(p),
- r, r_size);
- if (rv < 0) {
- fprintf(stderr, "Random number command failed\n");
- return -1;
- }
-
- rv = write(STDOUT_FILENO, r->rand, r_size);
- if (rv != r_size) {
- fprintf(stderr, "Failed to write stdout\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-int cmd_flash_spi_info(int argc, char *argv[])
-{
- struct ec_response_flash_spi_info r;
- int rv;
-
- memset(&r, 0, sizeof(r));
-
- /* Print SPI flash info if available */
- if (!ec_cmd_version_supported(EC_CMD_FLASH_SPI_INFO, 0)) {
- printf("EC has no info (does not use SPI flash?)\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_FLASH_SPI_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("JEDECManufacturerID 0x%02x\n", r.jedec[0]);
- printf("JEDECDeviceID 0x%02x 0x%02x\n", r.jedec[1], r.jedec[2]);
- printf("JEDECCapacity %d\n", 1 << r.jedec[2]);
- printf("ManufacturerID 0x%02x\n", r.mfr_dev_id[0]);
- printf("DeviceID 0x%02x\n", r.mfr_dev_id[1]);
- printf("StatusRegister1 0x%02x\n", r.sr1);
- printf("StatusRegister2 0x%02x\n", r.sr2);
- return 0;
-}
-
-int cmd_flash_read(int argc, char *argv[])
-{
- int offset, size;
- int rv;
- char *e;
- char *buf;
-
- if (argc < 4) {
- fprintf(stderr,
- "Usage: %s <offset> <size> <filename>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Reading %d bytes at offset %d...\n", size, offset);
-
- buf = (char *)malloc(size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- /* Read data in chunks */
- rv = ec_flash_read(buf, offset, size);
- if (rv < 0) {
- free(buf);
- return rv;
- }
-
- rv = write_file(argv[3], buf, size);
- free(buf);
- if (rv)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-int cmd_flash_write(int argc, char *argv[])
-{
- int offset, size;
- int rv;
- char *e;
- char *buf;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <offset> <filename>\n", argv[0]);
- return -1;
- }
-
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- /* Read the input file */
- buf = read_file(argv[2], &size);
- if (!buf)
- return -1;
-
- printf("Writing to offset %d...\n", offset);
-
- /* Write data in chunks */
- rv = ec_flash_write(buf, offset, size);
-
- free(buf);
-
- if (rv < 0)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-int cmd_flash_erase(int argc, char *argv[])
-{
- int offset, size;
- char *e;
- int rv;
- bool async = false;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <offset> <size>\n", argv[0]);
- return -1;
- }
-
- if (strcmp(argv[0], "flasheraseasync") == 0)
- async = true;
-
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > MAX_FLASH_SIZE) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
-
- printf("Erasing %d bytes at offset %d...\n", size, offset);
- if (async)
- rv = ec_flash_erase_async(offset, size);
- else
- rv = ec_flash_erase(offset, size);
- if (rv < 0)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-
-static void print_flash_protect_flags(const char *desc, uint32_t flags)
-{
- printf("%s 0x%08x", desc, flags);
- if (flags & EC_FLASH_PROTECT_GPIO_ASSERTED)
- printf(" wp_gpio_asserted");
- if (flags & EC_FLASH_PROTECT_RO_AT_BOOT)
- printf(" ro_at_boot");
- if (flags & EC_FLASH_PROTECT_RW_AT_BOOT)
- printf(" rw_at_boot");
- if (flags & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT)
- printf(" rollback_at_boot");
- if (flags & EC_FLASH_PROTECT_ALL_AT_BOOT)
- printf(" all_at_boot");
- if (flags & EC_FLASH_PROTECT_RO_NOW)
- printf(" ro_now");
- if (flags & EC_FLASH_PROTECT_RW_NOW)
- printf(" rw_now");
- if (flags & EC_FLASH_PROTECT_ROLLBACK_NOW)
- printf(" rollback_now");
- if (flags & EC_FLASH_PROTECT_ALL_NOW)
- printf(" all_now");
- if (flags & EC_FLASH_PROTECT_ERROR_STUCK)
- printf(" STUCK");
- if (flags & EC_FLASH_PROTECT_ERROR_INCONSISTENT)
- printf(" INCONSISTENT");
- printf("\n");
-}
-
-
-int cmd_flash_protect(int argc, char *argv[])
-{
- struct ec_params_flash_protect p;
- struct ec_response_flash_protect r;
- int rv, i;
-
- /*
- * Set up requested flags. If no flags were specified, p.mask will
- * be 0 and nothing will change.
- */
- p.mask = p.flags = 0;
- for (i = 1; i < argc; i++) {
- if (!strcasecmp(argv[i], "now")) {
- p.mask |= EC_FLASH_PROTECT_ALL_NOW;
- p.flags |= EC_FLASH_PROTECT_ALL_NOW;
- } else if (!strcasecmp(argv[i], "enable")) {
- p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT;
- p.flags |= EC_FLASH_PROTECT_RO_AT_BOOT;
- } else if (!strcasecmp(argv[i], "disable"))
- p.mask |= EC_FLASH_PROTECT_RO_AT_BOOT;
- }
-
- rv = ec_command(EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
- if (rv < sizeof(r)) {
- fprintf(stderr, "Too little data returned.\n");
- return -1;
- }
-
- /* Print returned flags */
- print_flash_protect_flags("Flash protect flags:", r.flags);
- print_flash_protect_flags("Valid flags: ", r.valid_flags);
- print_flash_protect_flags("Writable flags: ", r.writable_flags);
-
- /* Check if we got all the flags we asked for */
- if ((r.flags & p.mask) != (p.flags & p.mask)) {
- fprintf(stderr, "Unable to set requested flags "
- "(wanted mask 0x%08x flags 0x%08x)\n",
- p.mask, p.flags);
- if (p.mask & ~r.writable_flags)
- fprintf(stderr, "Which is expected, because writable "
- "mask is 0x%08x.\n", r.writable_flags);
-
- return -1;
- }
-
- return 0;
-}
-
-int cmd_rw_hash_pd(int argc, char *argv[])
-{
- struct ec_params_usb_pd_rw_hash_entry *p =
- (struct ec_params_usb_pd_rw_hash_entry *)ec_outbuf;
- int i, rv;
- char *e;
- uint32_t val;
- uint8_t *rwp;
-
- if (argc < 7) {
- fprintf(stderr, "Usage: %s <dev_id> <HASH[0]> ... <HASH[4]>\n",
- argv[0]);
- return -1;
- }
-
- p->dev_id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad device ID\n");
- return -1;
- }
-
- rwp = p->dev_rw_hash;
- for (i = 2; i < 7; i++) {
- val = strtol(argv[i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad RW hash\n");
- return -1;
- }
- rwp[0] = (uint8_t) (val >> 0) & 0xff;
- rwp[1] = (uint8_t) (val >> 8) & 0xff;
- rwp[2] = (uint8_t) (val >> 16) & 0xff;
- rwp[3] = (uint8_t) (val >> 24) & 0xff;
- rwp += 4;
- }
- rv = ec_command(EC_CMD_USB_PD_RW_HASH_ENTRY, 0, p, sizeof(*p), NULL, 0);
-
- return rv;
-}
-
-int cmd_rwsig_status(int argc, char *argv[])
-{
- int rv;
- struct ec_response_rwsig_check_status resp;
-
- rv = ec_command(EC_CMD_RWSIG_CHECK_STATUS, 0, NULL, 0,
- &resp, sizeof(resp));
- if (rv < 0)
- return rv;
-
- printf("RW signature check: %s\n", resp.status ? "OK" : "FAILED");
-
- return 0;
-}
-
-int cmd_rwsig_action(int argc, char *argv[])
-{
- struct ec_params_rwsig_action req;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s abort | continue\n", argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "abort"))
- req.action = RWSIG_ACTION_ABORT;
- else if (!strcasecmp(argv[1], "continue"))
- req.action = RWSIG_ACTION_CONTINUE;
- else
- return -1;
-
- return ec_command(EC_CMD_RWSIG_ACTION, 0, &req, sizeof(req), NULL, 0);
-}
-
-int cmd_rollback_info(int argc, char *argv[])
-{
- struct ec_response_rollback_info r;
- int rv;
-
- rv = ec_command(EC_CMD_ROLLBACK_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0) {
- fprintf(stderr, "ERROR: EC_CMD_ROLLBACK_INFO failed: %d\n", rv);
- return rv;
- }
-
- /* Print versions */
- printf("Rollback block id: %d\n", r.id);
- printf("Rollback min version: %d\n", r.rollback_min_version);
- printf("RW rollback version: %d\n", r.rw_rollback_version);
-
- return 0;
-}
-
-int cmd_apreset(int argc, char *argv[])
-{
- return ec_command(EC_CMD_AP_RESET, 0, NULL, 0, NULL, 0);
-}
-
-#define FP_FRAME_INDEX_SIMPLE_IMAGE -1
-
-/*
- * Download a frame buffer from the FPMCU.
- *
- * Might be either the finger image or a finger template depending on 'index'.
- *
- * @param info a pointer to store the struct ec_response_fp_info retrieved by
- * this command.
- * @param index the specific frame to retrieve, might be:
- * -1 (aka FP_FRAME_INDEX_SIMPLE_IMAGE) for the a single grayscale image.
- * 0 (aka FP_FRAME_INDEX_RAW_IMAGE) for the full vendor raw finger image.
- * 1..n for a finger template.
- *
- * @returns a pointer to the buffer allocated to contain the frame or NULL
- * if case of error. The caller must call free() once it no longer needs the
- * buffer.
- */
-static void *fp_download_frame(struct ec_response_fp_info *info, int index)
-{
- struct ec_params_fp_frame p;
- int rv = 0;
- size_t stride, size;
- void *buffer;
- uint8_t *ptr;
- int cmdver = ec_cmd_version_supported(EC_CMD_FP_INFO, 1) ? 1 : 0;
- int rsize = cmdver == 1 ? sizeof(*info)
- : sizeof(struct ec_response_fp_info_v0);
-
- /* templates not supported in command v0 */
- if (index > 0 && cmdver == 0)
- return NULL;
-
- rv = ec_command(EC_CMD_FP_INFO, cmdver, NULL, 0, info, rsize);
- if (rv < 0)
- return NULL;
-
- if (index == FP_FRAME_INDEX_SIMPLE_IMAGE) {
- size = (size_t)info->width * info->bpp/8 * info->height;
- index = FP_FRAME_INDEX_RAW_IMAGE;
- } else if (index == FP_FRAME_INDEX_RAW_IMAGE) {
- size = info->frame_size;
- } else {
- size = info->template_size;
- }
-
- buffer = malloc(size);
- if (!buffer) {
- fprintf(stderr, "Cannot allocate memory for the image\n");
- return NULL;
- }
-
- ptr = buffer;
- p.offset = index << FP_FRAME_INDEX_SHIFT;
- while (size) {
- stride = MIN(ec_max_insize, size);
- p.size = stride;
- rv = ec_command(EC_CMD_FP_FRAME, 0, &p, sizeof(p),
- ptr, stride);
- if (rv < 0) {
- free(buffer);
- return NULL;
- }
- p.offset += stride;
- size -= stride;
- ptr += stride;
- }
-
- return buffer;
-}
-
-int cmd_fp_mode(int argc, char *argv[])
-{
- struct ec_params_fp_mode p;
- struct ec_response_fp_mode r;
- uint32_t mode = 0;
- uint32_t capture_type = FP_CAPTURE_SIMPLE_IMAGE;
- int i, rv;
-
- if (argc == 1)
- mode = FP_MODE_DONT_CHANGE;
- for (i = 1; i < argc; i++) {
- /* modes */
- if (!strncmp(argv[i], "deepsleep", 9))
- mode |= FP_MODE_DEEPSLEEP;
- else if (!strncmp(argv[i], "fingerdown", 10))
- mode |= FP_MODE_FINGER_DOWN;
- else if (!strncmp(argv[i], "fingerup", 8))
- mode |= FP_MODE_FINGER_UP;
- else if (!strncmp(argv[i], "enroll", 6))
- mode |= FP_MODE_ENROLL_IMAGE | FP_MODE_ENROLL_SESSION;
- else if (!strncmp(argv[i], "match", 5))
- mode |= FP_MODE_MATCH;
- else if (!strncmp(argv[i], "reset_sensor", 12))
- mode = FP_MODE_RESET_SENSOR;
- else if (!strncmp(argv[i], "reset", 5))
- mode = 0;
- else if (!strncmp(argv[i], "capture", 7))
- mode |= FP_MODE_CAPTURE;
- /* capture types */
- else if (!strncmp(argv[i], "vendor", 6))
- capture_type = FP_CAPTURE_VENDOR_FORMAT;
- else if (!strncmp(argv[i], "pattern0", 8))
- capture_type = FP_CAPTURE_PATTERN0;
- else if (!strncmp(argv[i], "pattern1", 8))
- capture_type = FP_CAPTURE_PATTERN1;
- else if (!strncmp(argv[i], "qual", 4))
- capture_type = FP_CAPTURE_QUALITY_TEST;
- else if (!strncmp(argv[i], "test_reset", 10))
- capture_type = FP_CAPTURE_RESET_TEST;
- }
- if (mode & FP_MODE_CAPTURE)
- mode |= capture_type << FP_MODE_CAPTURE_TYPE_SHIFT;
-
- p.mode = mode;
- rv = ec_command(EC_CMD_FP_MODE, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("FP mode: (0x%x) ", r.mode);
- if (r.mode & FP_MODE_DEEPSLEEP)
- printf("deepsleep ");
- if (r.mode & FP_MODE_FINGER_DOWN)
- printf("finger-down ");
- if (r.mode & FP_MODE_FINGER_UP)
- printf("finger-up ");
- if (r.mode & FP_MODE_ENROLL_SESSION)
- printf("enroll%s ",
- r.mode & FP_MODE_ENROLL_IMAGE ? "+image" : "");
- if (r.mode & FP_MODE_MATCH)
- printf("match ");
- if (r.mode & FP_MODE_CAPTURE)
- printf("capture ");
- printf("\n");
- return 0;
-}
-
-int cmd_fp_seed(int argc, char *argv[])
-{
- struct ec_params_fp_seed p;
- char *seed;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <seed>\n", argv[0]);
- return 1;
- }
- seed = argv[1];
- if (strlen(seed) != FP_CONTEXT_TPM_BYTES) {
- printf("Invalid seed '%s' is %zd bytes long instead of %d.\n",
- seed, strlen(seed), FP_CONTEXT_TPM_BYTES);
- return 1;
- }
- printf("Setting seed '%s'\n", seed);
- p.struct_version = FP_TEMPLATE_FORMAT_VERSION;
- memcpy(p.seed, seed, FP_CONTEXT_TPM_BYTES);
-
- return ec_command(EC_CMD_FP_SEED, 0, &p, sizeof(p), NULL, 0);
-}
-
-int cmd_fp_stats(int argc, char *argv[])
-{
- struct ec_response_fp_stats r;
- int rv;
- unsigned long long ts;
-
- rv = ec_command(EC_CMD_FP_STATS, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- ts = (uint64_t)r.overall_t0.hi << 32 | r.overall_t0.lo;
- printf("FP stats (t0=%llu us):\n", ts);
- printf("Last capture time: ");
- if (r.timestamps_invalid & FPSTATS_CAPTURE_INV)
- printf("Invalid\n");
- else
- printf("%d us\n", r.capture_time_us);
-
- printf("Last matching time: ");
- if (r.timestamps_invalid & FPSTATS_MATCHING_INV)
- printf("Invalid\n");
- else
- printf("%d us (finger: %d)\n", r.matching_time_us,
- r.template_matched);
-
- printf("Last overall time: ");
- if (r.timestamps_invalid)
- printf("Invalid\n");
- else
- printf("%d us\n", r.overall_time_us);
-
- return 0;
-}
-
-int cmd_fp_info(int argc, char *argv[])
-{
- struct ec_response_fp_info r;
- int rv;
- int cmdver = ec_cmd_version_supported(EC_CMD_FP_INFO, 1) ? 1 : 0;
- int rsize = cmdver == 1 ? sizeof(r)
- : sizeof(struct ec_response_fp_info_v0);
- uint16_t dead;
-
- rv = ec_command(EC_CMD_FP_INFO, cmdver, NULL, 0, &r, rsize);
- if (rv < 0)
- return rv;
-
- printf("Fingerprint sensor: vendor %x product %x model %x version %x\n",
- r.vendor_id, r.product_id, r.model_id, r.version);
- printf("Image: size %dx%d %d bpp\n", r.width, r.height, r.bpp);
- printf("Error flags: %s%s%s%s\n",
- r.errors & FP_ERROR_NO_IRQ ? "NO_IRQ " : "",
- r.errors & FP_ERROR_SPI_COMM ? "SPI_COMM " : "",
- r.errors & FP_ERROR_BAD_HWID ? "BAD_HWID " : "",
- r.errors & FP_ERROR_INIT_FAIL ? "INIT_FAIL " : "");
- dead = FP_ERROR_DEAD_PIXELS(r.errors);
- if (dead == FP_ERROR_DEAD_PIXELS_UNKNOWN) {
- printf("Dead pixels: UNKNOWN\n");
- } else {
- printf("Dead pixels: %u\n", dead);
- }
-
- if (cmdver == 1) {
- printf("Templates: version %d size %d count %d/%d"
- " dirty bitmap %x\n",
- r.template_version, r.template_size, r.template_valid,
- r.template_max, r.template_dirty);
- }
-
- return 0;
-}
-
-static void print_fp_enc_flags(const char *desc, uint32_t flags)
-{
- printf("%s 0x%08x", desc, flags);
- if (flags & FP_ENC_STATUS_SEED_SET)
- printf(" FPTPM_seed_set");
- printf("\n");
-}
-
-static int cmd_fp_context(int argc, char *argv[])
-{
- struct ec_params_fp_context_v1 p;
- int rv;
- int tries = 20; /* Wait at most two seconds */
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <context>\n", argv[0]);
- return -1;
- }
-
- /*
- * Note that we treat the resulting "userid" as raw byte array, so we
- * don't want to copy the NUL from the end of the string.
- */
- if (strlen(argv[1]) != sizeof(p.userid)) {
- fprintf(stderr, "Context must be exactly %zu bytes\n",
- sizeof(p.userid));
- return -1;
- }
-
- p.action = FP_CONTEXT_ASYNC;
- memcpy(p.userid, argv[1], sizeof(p.userid));
-
- rv = ec_command(EC_CMD_FP_CONTEXT, 1, &p, sizeof(p), NULL, 0);
-
- if (rv != EC_RES_SUCCESS)
- goto out;
-
- while (tries--) {
- usleep(100000);
-
- p.action = FP_CONTEXT_GET_RESULT;
- rv = ec_command(EC_CMD_FP_CONTEXT, 1, &p, sizeof(p), NULL, 0);
-
- if (rv == EC_RES_SUCCESS) {
- printf("Set context successfully\n");
- return EC_RES_SUCCESS;
- }
-
- /* Abort if EC returns an error other than EC_RES_BUSY. */
- if (rv <= -EECRESULT && rv != -EECRESULT - EC_RES_BUSY)
- goto out;
- }
-
- rv = -EECRESULT - EC_RES_TIMEOUT;
-
-out:
- fprintf(stderr, "Failed to reset context: %d\n", rv);
- return rv;
-}
-
-int cmd_fp_enc_status(int argc, char *argv[])
-{
- int rv;
- struct ec_response_fp_encryption_status resp = { 0 };
-
- rv = ec_command(EC_CMD_FP_ENC_STATUS, 0, NULL, 0, &resp, sizeof(resp));
- if (rv < 0) {
- printf("Get FP sensor encryption status failed.\n");
- } else {
- print_fp_enc_flags("FPMCU encryption status:", resp.status);
- print_fp_enc_flags("Valid flags: ",
- resp.valid_flags);
- rv = 0;
- }
- return rv;
-}
-
-int cmd_fp_frame(int argc, char *argv[])
-{
- struct ec_response_fp_info r;
- int idx = (argc == 2 && !strcasecmp(argv[1], "raw")) ?
- FP_FRAME_INDEX_RAW_IMAGE : FP_FRAME_INDEX_SIMPLE_IMAGE;
- void *buffer = fp_download_frame(&r, idx);
- uint8_t *ptr = buffer;
- int x, y;
-
- if (!buffer) {
- fprintf(stderr, "Failed to get FP sensor frame\n");
- return -1;
- }
-
- if (idx == FP_FRAME_INDEX_RAW_IMAGE) {
- fwrite(buffer, r.frame_size, 1, stdout);
- goto frame_done;
- }
-
- /* Print 8-bpp PGM ASCII header */
- printf("P2\n%d %d\n%d\n", r.width, r.height, (1 << r.bpp) - 1);
-
- for (y = 0; y < r.height; y++) {
- for (x = 0; x < r.width; x++, ptr++)
- printf("%d ", *ptr);
- printf("\n");
- }
- printf("# END OF FILE\n");
-frame_done:
- free(buffer);
- return 0;
-}
-
-int cmd_fp_template(int argc, char *argv[])
-{
- struct ec_response_fp_info r;
- struct ec_params_fp_template *p = ec_outbuf;
- /* TODO(b/78544921): removing 32 bits is a workaround for the MCU bug */
- int max_chunk = ec_max_outsize
- - offsetof(struct ec_params_fp_template, data) - 4;
- int idx = -1;
- char *e;
- int size;
- void *buffer = NULL;
- uint32_t offset = 0;
- int rv = 0;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s [<infile>|<index>]\n", argv[0]);
- return -1;
- }
-
- idx = strtol(argv[1], &e, 0);
- if (!(e && *e)) {
- buffer = fp_download_frame(&r, idx + 1);
- if (!buffer) {
- fprintf(stderr, "Failed to get FP template %d\n", idx);
- return -1;
- }
- fwrite(buffer, r.template_size, 1, stdout);
- free(buffer);
- return 0;
- }
- /* not an index, is it a filename ? */
- buffer = read_file(argv[1], &size);
- if (!buffer) {
- fprintf(stderr, "Invalid parameter: %s\n", argv[1]);
- return -1;
- }
- printf("sending template from: %s (%d bytes)\n", argv[1], size);
- while (size) {
- uint32_t tlen = MIN(max_chunk, size);
-
- p->offset = offset;
- p->size = tlen;
- size -= tlen;
- if (!size)
- p->size |= FP_TEMPLATE_COMMIT;
- memcpy(p->data, buffer + offset, tlen);
- rv = ec_command(EC_CMD_FP_TEMPLATE, 0, p, tlen +
- offsetof(struct ec_params_fp_template, data),
- NULL, 0);
- if (rv < 0)
- break;
- offset += tlen;
- }
- if (rv < 0)
- fprintf(stderr, "Failed with %d\n", rv);
- else
- rv = 0;
- free(buffer);
- return rv;
-}
-
-/**
- * determine if in GFU mode or not.
- *
- * NOTE, Sends HOST commands that modify ec_outbuf contents.
- *
- * @opos return value of GFU mode object position or zero if not found
- * @port port number to query
- * @return 1 if in GFU mode, 0 if not, -1 if error
- */
-static int in_gfu_mode(int *opos, int port)
-{
- int i;
- struct ec_params_usb_pd_get_mode_request *p =
- (struct ec_params_usb_pd_get_mode_request *)ec_outbuf;
- struct ec_params_usb_pd_get_mode_response *r =
- (struct ec_params_usb_pd_get_mode_response *)ec_inbuf;
- p->port = port;
- p->svid_idx = 0;
- do {
- ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (!r->svid || (r->svid == USB_VID_GOOGLE))
- break;
- p->svid_idx++;
- } while (p->svid_idx < SVID_DISCOVERY_MAX);
-
- if (r->svid != USB_VID_GOOGLE) {
- fprintf(stderr, "Google VID not returned\n");
- return -1;
- }
-
- *opos = 0; /* invalid ... must be 1 thru 6 */
- for (i = 0; i < PDO_MODES; i++) {
- if (r->vdo[i] == MODE_GOOGLE_FU) {
- *opos = i + 1;
- break;
- }
- }
-
- return r->opos == *opos;
-}
-
-/**
- * Enter GFU mode.
- *
- * NOTE, Sends HOST commands that modify ec_outbuf contents.
- *
- * @port port number to enter GFU on.
- * @return 1 if entered GFU mode, 0 if not, -1 if error
- */
-static int enter_gfu_mode(int port)
-{
- int opos;
- struct ec_params_usb_pd_set_mode_request *p =
- (struct ec_params_usb_pd_set_mode_request *)ec_outbuf;
- int gfu_mode = in_gfu_mode(&opos, port);
-
- if (gfu_mode < 0) {
- fprintf(stderr, "Failed to query GFU mode support\n");
- return 0;
- } else if (!gfu_mode) {
- if (!opos) {
- fprintf(stderr, "Invalid object position %d\n", opos);
- return 0;
- }
- p->port = port;
- p->svid = USB_VID_GOOGLE;
- p->opos = opos;
- p->cmd = PD_ENTER_MODE;
-
- ec_command(EC_CMD_USB_PD_SET_AMODE, 0, p, sizeof(*p),
- NULL, 0);
- usleep(500000); /* sleep to allow time for set mode */
- gfu_mode = in_gfu_mode(&opos, port);
- }
- return gfu_mode;
-}
-
-int cmd_pd_device_info(int argc, char *argv[])
-{
- int i, rv, port;
- char *e;
- struct ec_params_usb_pd_info_request *p =
- (struct ec_params_usb_pd_info_request *)ec_outbuf;
- struct ec_params_usb_pd_rw_hash_entry *r0 =
- (struct ec_params_usb_pd_rw_hash_entry *)ec_inbuf;
- struct ec_params_usb_pd_discovery_entry *r1;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <port>\n", argv[0]);
- return -1;
- }
-
- port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p->port = port;
- r1 = (struct ec_params_usb_pd_discovery_entry *)ec_inbuf;
- rv = ec_command(EC_CMD_USB_PD_DISCOVERY, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (!r1->vid)
- printf("Port:%d has no discovered device\n", port);
- else {
- printf("Port:%d ptype:%d vid:0x%04x pid:0x%04x\n", port,
- r1->ptype, r1->vid, r1->pid);
- }
-
- if (enter_gfu_mode(port) != 1) {
- fprintf(stderr, "Failed to enter GFU mode\n");
- return -1;
- }
-
- p->port = port;
- rv = ec_command(EC_CMD_USB_PD_DEV_INFO, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (!r0->dev_id)
- printf("Port:%d has no valid device\n", port);
- else {
- uint8_t *rwp = r0->dev_rw_hash;
- printf("Port:%d DevId:%d.%d Hash:", port,
- HW_DEV_ID_MAJ(r0->dev_id), HW_DEV_ID_MIN(r0->dev_id));
- for (i = 0; i < 5; i++) {
- printf(" 0x%02x%02x%02x%02x", rwp[3], rwp[2], rwp[1],
- rwp[0]);
- rwp += 4;
- }
- printf(" CurImg:%s\n", image_names[r0->current_image]);
- }
-
- return rv;
-}
-
-int cmd_flash_pd(int argc, char *argv[])
-{
- struct ec_params_usb_pd_fw_update *p =
- (struct ec_params_usb_pd_fw_update *)ec_outbuf;
- int i, dev_id, port;
- int rv, fsize, step = 96;
- char *e;
- char *buf;
- char *data = (char *)p + sizeof(*p);
-
- if (argc < 4) {
- fprintf(stderr, "Usage: %s <dev_id> <port> <filename>\n",
- argv[0]);
- return -1;
- }
-
- dev_id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad device ID\n");
- return -1;
- }
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- if (enter_gfu_mode(port) != 1) {
- fprintf(stderr, "Failed to enter GFU mode\n");
- return -1;
- }
-
- /* Read the input file */
- buf = read_file(argv[3], &fsize);
- if (!buf)
- return -1;
-
- /* Erase the current RW RSA signature */
- fprintf(stderr, "Erasing expected RW hash\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_ERASE_SIG;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- if (rv < 0)
- goto pd_flash_error;
-
- /* Reboot */
- fprintf(stderr, "Rebooting\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_REBOOT;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- if (rv < 0)
- goto pd_flash_error;
-
- usleep(3000000); /* 3sec to reboot and get CC line idle */
-
- /* re-enter GFU after reboot */
- if (enter_gfu_mode(port) != 1) {
- fprintf(stderr, "Failed to enter GFU mode\n");
- goto pd_flash_error;
- }
-
- /* Erase RW flash */
- fprintf(stderr, "Erasing RW flash\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_FLASH_ERASE;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- /* 3 secs should allow ample time for 2KB page erases at 40ms */
- usleep(3000000);
-
- if (rv < 0)
- goto pd_flash_error;
-
- /* Write RW flash */
- fprintf(stderr, "Writing RW flash\n");
- p->dev_id = dev_id;
- p->port = port;
- p->cmd = USB_PD_FW_FLASH_WRITE;
- p->size = step;
-
- for (i = 0; i < fsize; i += step) {
- p->size = MIN(fsize - i, step);
- memcpy(data, buf + i, p->size);
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
- if (rv < 0)
- goto pd_flash_error;
-
- /*
- * TODO(crosbug.com/p/33905) throttle so EC doesn't watchdog on
- * other tasks. Remove once issue resolved.
- */
- usleep(10000);
- }
-
- /* 100msec to guarantee writes finish */
- usleep(100000);
-
- /* Reboot into new RW */
- fprintf(stderr, "Rebooting PD into new RW\n");
- p->cmd = USB_PD_FW_REBOOT;
- p->size = 0;
- rv = ec_command(EC_CMD_USB_PD_FW_UPDATE, 0,
- p, p->size + sizeof(*p), NULL, 0);
-
- if (rv < 0)
- goto pd_flash_error;
-
- free(buf);
- fprintf(stderr, "Complete\n");
- return 0;
-
-pd_flash_error:
- free(buf);
- fprintf(stderr, "PD flash error\n");
- return -1;
-}
-
-int cmd_pd_set_amode(int argc, char *argv[])
-{
- char *e;
- struct ec_params_usb_pd_set_mode_request *p =
- (struct ec_params_usb_pd_set_mode_request *)ec_outbuf;
-
- if (argc < 5) {
- fprintf(stderr, "Usage: %s <port> <svid> <opos> <cmd>\n",
- argv[0]);
- return -1;
- }
-
- p->port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p->svid = strtol(argv[2], &e, 0);
- if ((e && *e) || !p->svid) {
- fprintf(stderr, "Bad svid\n");
- return -1;
- }
-
- p->opos = strtol(argv[3], &e, 0);
- if ((e && *e) || !p->opos) {
- fprintf(stderr, "Bad opos\n");
- return -1;
- }
-
- p->cmd = strtol(argv[4], &e, 0);
- if ((e && *e) || (p->cmd >= PD_MODE_CMD_COUNT)) {
- fprintf(stderr, "Bad cmd\n");
- return -1;
- }
- return ec_command(EC_CMD_USB_PD_SET_AMODE, 0, p, sizeof(*p), NULL, 0);
-}
-
-int cmd_pd_get_amode(int argc, char *argv[])
-{
- int i;
- char *e;
- struct ec_params_usb_pd_get_mode_request *p =
- (struct ec_params_usb_pd_get_mode_request *)ec_outbuf;
- struct ec_params_usb_pd_get_mode_response *r =
- (struct ec_params_usb_pd_get_mode_response *)ec_inbuf;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <port>\n", argv[0]);
- return -1;
- }
-
- p->port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port\n");
- return -1;
- }
-
- p->svid_idx = 0;
- do {
- ec_command(EC_CMD_USB_PD_GET_AMODE, 0, p, sizeof(*p),
- ec_inbuf, ec_max_insize);
- if (!r->svid)
- break;
- printf("%cSVID:0x%04x ", (r->opos) ? '*' : ' ',
- r->svid);
- for (i = 0; i < PDO_MODES; i++) {
- printf("%c0x%08x ", (r->opos && (r->opos == i + 1)) ?
- '*' : ' ', r->vdo[i]);
- }
- printf("\n");
- p->svid_idx++;
- } while (p->svid_idx < SVID_DISCOVERY_MAX);
- return -1;
-}
-
-/* The I/O asm funcs exist only on x86. */
-#if defined(__i386__) || defined(__x86_64__)
-#include <sys/io.h>
-
-int cmd_serial_test(int argc, char *argv[])
-{
- const char *c = "COM2 sample serial output from host!\r\n";
-
- printf("Writing sample serial output to COM2\n");
-
- while (*c) {
- /* Wait for space in transmit FIFO */
- while (!(inb(0x2fd) & 0x20))
- ;
-
- /* Put the next character */
- outb(*c++, 0x2f8);
- }
-
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_port_80_flood(int argc, char *argv[])
-{
- int i;
-
- for (i = 0; i < 256; i++)
- outb(i, 0x80);
- return 0;
-}
-#else
-int cmd_serial_test(int argc, char *argv[])
-{
- printf("x86 specific command\n");
- return -1;
-}
-
-int cmd_port_80_flood(int argc, char *argv[])
-{
- printf("x86 specific command\n");
- return -1;
-}
-#endif
-
-/*
- * This boolean variable and handler are used for
- * catching signals that translate into a quit/shutdown
- * of a runtime loop.
- * This is used in cmd_stress_test.
- */
-static bool sig_quit;
-static void sig_quit_handler(int sig)
-{
- sig_quit = true;
-}
-
-int cmd_stress_test(int argc, char *argv[])
-{
- int i;
- bool reboot = false;
- time_t now;
- time_t start_time, last_update_time;
- unsigned int rand_seed = 0;
- uint64_t round = 1, attempt = 1;
- uint64_t failures = 0;
-
- const int max_sleep_usec = 1000; /* 1ms */
- const int loop_update_interval = 10000;
-
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[i], "help") == 0) {
- printf("Usage: %s [reboot] [help]\n", argv[0]);
- printf("Stress tests the host command interface by"
- " repeatedly issuing common host commands.\n");
- printf("The intent is to expose errors in kernel<->mcu"
- " communication, such as exceeding timeouts.\n");
- printf("\n");
- printf("reboot - Reboots the target before"
- " starting the stress test.\n");
- printf(" This may force restart the host,"
- " if the main ec is the target.\n");
- return 0;
- } else if (strcmp(argv[i], "reboot") == 0) {
- reboot = true;
- } else {
- fprintf(stderr, "Error - Unknown argument '%s'\n",
- argv[i]);
- return 1;
- }
- }
-
- printf("Stress test tool version: %s %s %s\n",
- CROS_ECTOOL_VERSION, DATE, BUILDER);
-
- start_time = time(NULL);
- last_update_time = start_time;
- printf("Start time: %s\n", ctime(&start_time));
-
- if (reboot) {
- printf("Issuing ec reboot. Expect a few early failed"
- " ioctl messages.\n");
- ec_command(EC_CMD_REBOOT, 0, NULL, 0, NULL, 0);
- sleep(2);
- }
-
- sig_quit = false;
- signal(SIGINT, sig_quit_handler);
- while (!sig_quit) {
- int rv;
- struct ec_response_get_version ver_r;
- char *build_string = (char *)ec_inbuf;
- struct ec_params_flash_protect flash_p;
- struct ec_response_flash_protect flash_r;
- struct ec_params_hello hello_p;
- struct ec_response_hello hello_r;
-
- /* Request EC Version Strings */
- rv = ec_command(EC_CMD_GET_VERSION, 0,
- NULL, 0, &ver_r, sizeof(ver_r));
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_GET_VERSION failed");
- }
- ver_r.version_string_ro[sizeof(ver_r.version_string_ro) - 1]
- = '\0';
- ver_r.version_string_rw[sizeof(ver_r.version_string_rw) - 1]
- = '\0';
- if (strlen(ver_r.version_string_ro) == 0) {
- failures++;
- fprintf(stderr, "RO version string is empty\n");
- }
- if (strlen(ver_r.version_string_rw) == 0) {
- failures++;
- fprintf(stderr, "RW version string is empty\n");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- /* Request EC Build String */
- rv = ec_command(EC_CMD_GET_BUILD_INFO, 0,
- NULL, 0, ec_inbuf, ec_max_insize);
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_GET_BUILD_INFO failed");
- }
- build_string[ec_max_insize - 1] = '\0';
- if (strlen(build_string) == 0) {
- failures++;
- fprintf(stderr, "Build string is empty\n");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- /* Request Flash Protect Status */
- rv = ec_command(EC_CMD_FLASH_PROTECT, EC_VER_FLASH_PROTECT,
- &flash_p, sizeof(flash_p), &flash_r,
- sizeof(flash_r));
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_FLASH_PROTECT failed");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- /* Request Hello */
- hello_p.in_data = 0xa0b0c0d0;
- rv = ec_command(EC_CMD_HELLO, 0, &hello_p, sizeof(hello_p),
- &hello_r, sizeof(hello_r));
- if (rv < 0) {
- failures++;
- perror("ERROR: EC_CMD_HELLO failed");
- }
- if (hello_r.out_data != HELLO_RESP(hello_p.in_data)) {
- failures++;
- fprintf(stderr, "Hello response was invalid.\n");
- }
-
- usleep(rand_r(&rand_seed) % max_sleep_usec);
-
- if ((attempt % loop_update_interval) == 0) {
- now = time(NULL);
- printf("Update: attempt %" PRIu64 " round %" PRIu64
- " | took %.f seconds\n",
- attempt, round,
- difftime(now, last_update_time));
- last_update_time = now;
- }
-
- if (attempt++ == UINT64_MAX)
- round++;
- }
- printf("\n");
-
- now = time(NULL);
- printf("End time: %s\n", ctime(&now));
- printf("Total runtime: %.f seconds\n",
- difftime(time(NULL), start_time));
- printf("Total failures: %" PRIu64 "\n", failures);
- return 0;
-}
-
-int read_mapped_temperature(int id)
-{
- int rv;
-
- if (!read_mapped_mem8(EC_MEMMAP_THERMAL_VERSION)) {
- /*
- * The temp_sensor_init() is not called, which implies no
- * temp sensor is defined.
- */
- rv = EC_TEMP_SENSOR_NOT_PRESENT;
- } else if (id < EC_TEMP_SENSOR_ENTRIES)
- rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR + id);
- else if (read_mapped_mem8(EC_MEMMAP_THERMAL_VERSION) >= 2)
- rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR_B +
- id - EC_TEMP_SENSOR_ENTRIES);
- else {
- /* Sensor in second bank, but second bank isn't supported */
- rv = EC_TEMP_SENSOR_NOT_PRESENT;
- }
- return rv;
-}
-
-
-int cmd_temperature(int argc, char *argv[])
-{
- int rv;
- int id;
- char *e;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <sensorid> | all\n", argv[0]);
- return -1;
- }
-
- if (strcmp(argv[1], "all") == 0) {
- for (id = 0;
- id < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES;
- id++) {
- rv = read_mapped_temperature(id);
- switch (rv) {
- case EC_TEMP_SENSOR_NOT_PRESENT:
- break;
- case EC_TEMP_SENSOR_ERROR:
- fprintf(stderr, "Sensor %d error\n", id);
- break;
- case EC_TEMP_SENSOR_NOT_POWERED:
- fprintf(stderr, "Sensor %d disabled\n", id);
- break;
- case EC_TEMP_SENSOR_NOT_CALIBRATED:
- fprintf(stderr, "Sensor %d not calibrated\n",
- id);
- break;
- default:
- printf("%d: %d K\n", id,
- rv + EC_TEMP_SENSOR_OFFSET);
- }
- }
- return 0;
- }
-
- id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor ID.\n");
- return -1;
- }
-
- if (id < 0 ||
- id >= EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES) {
- printf("Sensor ID invalid.\n");
- return -1;
- }
-
- printf("Reading temperature...");
- rv = read_mapped_temperature(id);
-
- switch (rv) {
- case EC_TEMP_SENSOR_NOT_PRESENT:
- printf("Sensor not present\n");
- return -1;
- case EC_TEMP_SENSOR_ERROR:
- printf("Error\n");
- return -1;
- case EC_TEMP_SENSOR_NOT_POWERED:
- printf("Sensor disabled/unpowered\n");
- return -1;
- case EC_TEMP_SENSOR_NOT_CALIBRATED:
- fprintf(stderr, "Sensor not calibrated\n");
- return -1;
- default:
- printf("%d K\n", rv + EC_TEMP_SENSOR_OFFSET);
- return 0;
- }
-}
-
-
-int cmd_temp_sensor_info(int argc, char *argv[])
-{
- struct ec_params_temp_sensor_get_info p;
- struct ec_response_temp_sensor_get_info r;
- int rv;
- char *e;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <sensorid> | all\n", argv[0]);
- return -1;
- }
-
- if (strcmp(argv[1], "all") == 0) {
- for (p.id = 0;
- p.id < EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES;
- p.id++) {
- if (read_mapped_temperature(p.id) ==
- EC_TEMP_SENSOR_NOT_PRESENT)
- continue;
- rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- continue;
- printf("%d: %d %s\n", p.id, r.sensor_type,
- r.sensor_name);
- }
- return 0;
- }
-
- p.id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor ID.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Sensor name: %s\n", r.sensor_name);
- printf("Sensor type: %d\n", r.sensor_type);
-
- return 0;
-}
-
-
-int cmd_thermal_get_threshold_v0(int argc, char *argv[])
-{
- struct ec_params_thermal_get_threshold p;
- struct ec_response_thermal_get_threshold r;
- char *e;
- int rv;
-
- if (argc != 3) {
- fprintf(stderr,
- "Usage: %s <sensortypeid> <thresholdid>\n", argv[0]);
- return -1;
- }
-
- p.sensor_type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor type ID.\n");
- return -1;
- }
-
- p.threshold_id = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad threshold ID.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Threshold %d for sensor type %d is %d K.\n",
- p.threshold_id, p.sensor_type, r.value);
-
- return 0;
-}
-
-
-int cmd_thermal_set_threshold_v0(int argc, char *argv[])
-{
- struct ec_params_thermal_set_threshold p;
- char *e;
- int rv;
-
- if (argc != 4) {
- fprintf(stderr,
- "Usage: %s <sensortypeid> <thresholdid> <value>\n",
- argv[0]);
- return -1;
- }
-
- p.sensor_type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad sensor type ID.\n");
- return -1;
- }
-
- p.threshold_id = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad threshold ID.\n");
- return -1;
- }
-
- p.value = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad threshold value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Threshold %d for sensor type %d set to %d.\n",
- p.threshold_id, p.sensor_type, p.value);
-
- return 0;
-}
-
-
-int cmd_thermal_get_threshold_v1(int argc, char *argv[])
-{
- struct ec_params_thermal_get_threshold_v1 p;
- struct ec_thermal_config r;
- struct ec_params_temp_sensor_get_info pi;
- struct ec_response_temp_sensor_get_info ri;
- int rv;
- int i;
-
- printf("sensor warn high halt fan_off fan_max name\n");
- for (i = 0; i < 99; i++) { /* number of sensors is unknown */
-
- /* ask for one */
- p.sensor_num = i;
- rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1,
- &p, sizeof(p), &r, sizeof(r));
- if (rv <= 0) /* stop on first failure */
- break;
-
- /* ask for its name, too */
- pi.id = i;
- rv = ec_command(EC_CMD_TEMP_SENSOR_GET_INFO, 0,
- &pi, sizeof(pi), &ri, sizeof(ri));
-
- /* print what we know */
- printf(" %2d %3d %3d %3d %3d %3d %s\n",
- i,
- r.temp_host[EC_TEMP_THRESH_WARN],
- r.temp_host[EC_TEMP_THRESH_HIGH],
- r.temp_host[EC_TEMP_THRESH_HALT],
- r.temp_fan_off, r.temp_fan_max,
- rv > 0 ? ri.sensor_name : "?");
- }
- if (i)
- printf("(all temps in degrees Kelvin)\n");
-
- return 0;
-}
-
-int cmd_thermal_set_threshold_v1(int argc, char *argv[])
-{
- struct ec_params_thermal_get_threshold_v1 p;
- struct ec_thermal_config r;
- struct ec_params_thermal_set_threshold_v1 s;
- int i, n, val, rv;
- char *e;
-
- if (argc < 3 || argc > 7) {
- printf("Usage: %s"
- " sensor warn [high [shutdown [fan_off [fan_max]]]]\n",
- argv[0]);
- return 1;
- }
-
- n = strtod(argv[1], &e);
- if (e && *e) {
- printf("arg %d is invalid\n", 1);
- return 1;
- }
-
- p.sensor_num = n;
- rv = ec_command(EC_CMD_THERMAL_GET_THRESHOLD, 1,
- &p, sizeof(p), &r, sizeof(r));
- if (rv <= 0)
- return rv;
-
- s.sensor_num = n;
- s.cfg = r;
-
- for (i = 2; i < argc; i++) {
- val = strtod(argv[i], &e);
- if (e && *e) {
- printf("arg %d is invalid\n", i);
- return 1;
- }
-
- if (val < 0)
- continue;
- switch (i) {
- case 2:
- case 3:
- case 4:
- s.cfg.temp_host[i-2] = val;
- break;
- case 5:
- s.cfg.temp_fan_off = val;
- break;
- case 6:
- s.cfg.temp_fan_max = val;
- break;
- }
- }
-
- rv = ec_command(EC_CMD_THERMAL_SET_THRESHOLD, 1,
- &s, sizeof(s), NULL, 0);
-
- return rv;
-}
-
-int cmd_thermal_get_threshold(int argc, char *argv[])
-{
- if (ec_cmd_version_supported(EC_CMD_THERMAL_GET_THRESHOLD, 1))
- return cmd_thermal_get_threshold_v1(argc, argv);
- else if (ec_cmd_version_supported(EC_CMD_THERMAL_GET_THRESHOLD, 0))
- return cmd_thermal_get_threshold_v0(argc, argv);
-
- printf("I got nuthin.\n");
- return -1;
-}
-
-int cmd_thermal_set_threshold(int argc, char *argv[])
-{
- if (ec_cmd_version_supported(EC_CMD_THERMAL_SET_THRESHOLD, 1))
- return cmd_thermal_set_threshold_v1(argc, argv);
- else if (ec_cmd_version_supported(EC_CMD_THERMAL_SET_THRESHOLD, 0))
- return cmd_thermal_set_threshold_v0(argc, argv);
-
- printf("I got nuthin.\n");
- return -1;
-}
-
-
-static int get_num_fans(void)
-{
- int idx, rv;
- struct ec_response_get_features r;
-
- /*
- * iff the EC supports the GET_FEATURES,
- * check whether it has fan support enabled.
- */
- rv = ec_command(EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
- if (rv >= 0 && !(r.flags[0] & BIT(EC_FEATURE_PWM_FAN)))
- return 0;
-
- for (idx = 0; idx < EC_FAN_SPEED_ENTRIES; idx++) {
- rv = read_mapped_mem16(EC_MEMMAP_FAN + 2 * idx);
- if (rv == EC_FAN_SPEED_NOT_PRESENT)
- break;
- }
-
- return idx;
-}
-
-int cmd_thermal_auto_fan_ctrl(int argc, char *argv[])
-{
- int rv, num_fans;
- struct ec_params_auto_fan_ctrl_v1 p_v1;
- char *e;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver)
- || (argc == 1)) {
- /* If no argument is provided then enable auto fan ctrl */
- /* for all fans by using version 0 of the host command */
-
- rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, 0,
- NULL, 0, NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Automatic fan control is now on for all fans.\n");
- return 0;
- }
-
- if (argc > 2 || !strcmp(argv[1], "help")) {
- printf("Usage: %s [idx]\n", argv[0]);
- return -1;
- }
-
- num_fans = get_num_fans();
- p_v1.fan_idx = strtol(argv[1], &e, 0);
- if ((e && *e) || (p_v1.fan_idx >= num_fans)) {
- fprintf(stderr, "Bad fan index.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_THERMAL_AUTO_FAN_CTRL, cmdver,
- &p_v1, sizeof(p_v1), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Automatic fan control is now on for fan %d\n", p_v1.fan_idx);
-
- return 0;
-}
-
-static int print_fan(int idx)
-{
- int rv = read_mapped_mem16(EC_MEMMAP_FAN + 2 * idx);
-
- switch (rv) {
- case EC_FAN_SPEED_NOT_PRESENT:
- return -1;
- case EC_FAN_SPEED_STALLED:
- printf("Fan %d stalled!\n", idx);
- break;
- default:
- printf("Fan %d RPM: %d\n", idx, rv);
- break;
- }
-
- return 0;
-}
-
-int cmd_pwm_get_num_fans(int argc, char *argv[])
-{
- int num_fans;
-
- num_fans = get_num_fans();
-
- printf("Number of fans = %d\n", num_fans);
-
- return 0;
-}
-
-int cmd_pwm_get_fan_rpm(int argc, char *argv[])
-{
- int i, num_fans;
-
- num_fans = get_num_fans();
- if (argc < 2 || !strcasecmp(argv[1], "all")) {
- /* Print all the fan speeds */
- for (i = 0; i < num_fans; i++)
- print_fan(i);
- } else {
- char *e;
- int idx;
-
- idx = strtol(argv[1], &e, 0);
- if ((e && *e) || idx < 0 || idx >= num_fans) {
- fprintf(stderr, "Bad index.\n");
- return -1;
- }
-
- print_fan(idx);
- }
-
- return 0;
-}
-
-
-int cmd_pwm_set_fan_rpm(int argc, char *argv[])
-{
- struct ec_params_pwm_set_fan_target_rpm_v1 p_v1;
- char *e;
- int rv, num_fans;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver)) {
- struct ec_params_pwm_set_fan_target_rpm_v0 p_v0;
-
- /* Fall back to command version 0 command */
- cmdver = 0;
-
- if (argc != 2) {
- fprintf(stderr,
- "Usage: %s <targetrpm>\n", argv[0]);
- return -1;
- }
- p_v0.rpm = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad RPM.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan target RPM set for all fans.\n");
- return 0;
- }
-
- if (argc > 3 || (argc == 2 && !strcmp(argv[1], "help")) || argc == 1) {
- printf("Usage: %s [idx] <targetrpm>\n", argv[0]);
- printf("'%s 0 3000' - Set fan 0 RPM to 3000\n", argv[0]);
- printf("'%s 3000' - Set all fans RPM to 3000\n", argv[0]);
- return -1;
- }
-
- num_fans = get_num_fans();
- p_v1.rpm = strtol(argv[argc - 1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad RPM.\n");
- return -1;
- }
-
- if (argc == 2) {
- /* Reuse version 0 command if we're setting targetrpm
- * for all fans */
- struct ec_params_pwm_set_fan_target_rpm_v0 p_v0;
-
- cmdver = 0;
- p_v0.rpm = p_v1.rpm;
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan target RPM set for all fans.\n");
- } else {
- p_v1.fan_idx = strtol(argv[1], &e, 0);
- if ((e && *e) || (p_v1.fan_idx >= num_fans)) {
- fprintf(stderr, "Bad fan index.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_TARGET_RPM, cmdver,
- &p_v1, sizeof(p_v1), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan %d target RPM set.\n", p_v1.fan_idx);
- }
-
- return 0;
-}
-
-int cmd_pwm_get_keyboard_backlight(int argc, char *argv[])
-{
- struct ec_response_pwm_get_keyboard_backlight r;
- int rv;
-
- rv = ec_command(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.enabled == 1)
- printf("Current keyboard backlight percent: %d\n", r.percent);
- else
- printf("Keyboard backlight disabled.\n");
-
- return 0;
-}
-
-
-int cmd_pwm_set_keyboard_backlight(int argc, char *argv[])
-{
- struct ec_params_pwm_set_keyboard_backlight p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <percent>\n", argv[0]);
- return -1;
- }
- p.percent = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad percent.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Keyboard backlight set.\n");
- return 0;
-}
-
-int cmd_pwm_get_duty(int argc, char *argv[])
-{
- struct ec_params_pwm_get_duty p;
- struct ec_response_pwm_get_duty r;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <pwm_idx> | kb | disp\n", argv[0]);
- return -1;
- }
-
- if (!strcmp(argv[1], "kb")) {
- p.pwm_type = EC_PWM_TYPE_KB_LIGHT;
- p.index = 0;
- } else if (!strcmp(argv[1], "disp")) {
- p.pwm_type = EC_PWM_TYPE_DISPLAY_LIGHT;
- p.index = 0;
- } else {
- p.pwm_type = EC_PWM_TYPE_GENERIC;
- p.index = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad pwm_idx\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_PWM_GET_DUTY, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current PWM duty: %d\n", r.duty);
- return 0;
-}
-
-
-int cmd_pwm_set_duty(int argc, char *argv[])
-{
- struct ec_params_pwm_set_duty p;
- char *e;
- int rv;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <pwm_idx> | kb | disp <duty>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcmp(argv[1], "kb")) {
- p.pwm_type = EC_PWM_TYPE_KB_LIGHT;
- p.index = 0;
- } else if (!strcmp(argv[1], "disp")) {
- p.pwm_type = EC_PWM_TYPE_DISPLAY_LIGHT;
- p.index = 0;
- } else {
- p.pwm_type = EC_PWM_TYPE_GENERIC;
- p.index = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad pwm_idx\n");
- return -1;
- }
- }
-
- p.duty = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad duty.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_DUTY, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("PWM set.\n");
- return 0;
-}
-
-int cmd_fanduty(int argc, char *argv[])
-{
- struct ec_params_pwm_set_fan_duty_v1 p_v1;
- char *e;
- int rv, num_fans;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_PWM_SET_FAN_DUTY, cmdver)) {
- struct ec_params_pwm_set_fan_duty_v0 p_v0;
-
- if (argc != 2) {
- fprintf(stderr,
- "Usage: %s <percent>\n", argv[0]);
- return -1;
- }
- p_v0.percent = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad percent arg.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, 0,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan duty cycle set.\n");
- return 0;
- }
-
- if (argc > 3 || (argc == 2 && !strcmp(argv[1], "help")) || argc == 1) {
- printf("Usage: %s [idx] <percent>\n", argv[0]);
- printf("'%s 0 50' - Set fan 0 duty cycle to 50 percent\n",
- argv[0]);
- printf("'%s 30' - Set all fans duty cycle to 30 percent\n",
- argv[0]);
- return -1;
- }
-
- num_fans = get_num_fans();
- p_v1.percent = strtol(argv[argc - 1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad percent arg.\n");
- return -1;
- }
-
- if (argc == 2) {
- /* Reuse version 0 command if we're setting duty cycle
- * for all fans */
- struct ec_params_pwm_set_fan_duty_v0 p_v0;
-
- cmdver = 0;
- p_v0.percent = p_v1.percent;
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver,
- &p_v0, sizeof(p_v0), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan duty cycle set for all fans.\n");
- } else {
- p_v1.fan_idx = strtol(argv[1], &e, 0);
- if ((e && *e) || (p_v1.fan_idx >= num_fans)) {
- fprintf(stderr, "Bad fan index.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_PWM_SET_FAN_DUTY, cmdver,
- &p_v1, sizeof(p_v1), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Fan %d duty cycle set.\n", p_v1.fan_idx);
- }
-
- return 0;
-}
-
-#define LBMSG(state) #state
-#include "lightbar_msg_list.h"
-static const char * const lightbar_cmds[] = {
- LIGHTBAR_MSG_LIST
-};
-#undef LBMSG
-
-/* Size of field <FLD> in structure <ST> */
-#define ST_FLD_SIZE(ST, FLD) sizeof(((struct ST *)0)->FLD)
-
-#define ST_CMD_SIZE ST_FLD_SIZE(ec_params_lightbar, cmd)
-#define ST_PRM_SIZE(SUBCMD) \
- (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_lightbar, SUBCMD))
-#define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_lightbar, SUBCMD)
-
-static const struct {
- uint8_t insize;
- uint8_t outsize;
-} lb_command_paramcount[] = {
- { ST_CMD_SIZE, ST_RSP_SIZE(dump) },
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, 0 },
- { ST_PRM_SIZE(set_brightness), 0},
- { ST_PRM_SIZE(seq), 0},
- { ST_PRM_SIZE(reg), 0},
- { ST_PRM_SIZE(set_rgb), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_seq) },
- { ST_PRM_SIZE(demo), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v0) },
- { ST_PRM_SIZE(set_params_v0), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(version) },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_brightness) },
- { ST_PRM_SIZE(get_rgb), ST_RSP_SIZE(get_rgb) },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_demo) },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v1) },
- { ST_PRM_SIZE(set_params_v1), 0},
- { ST_PRM_SIZE(set_program), 0},
- { ST_PRM_SIZE(manual_suspend_ctrl), 0},
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, 0 },
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_timing) },
- { ST_PRM_SIZE(set_v2par_timing), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_tap) },
- { ST_PRM_SIZE(set_v2par_tap), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_osc) },
- { ST_PRM_SIZE(set_v2par_osc), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_bright) },
- { ST_PRM_SIZE(set_v2par_bright), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_thlds) },
- { ST_PRM_SIZE(set_v2par_thlds), 0},
- { ST_CMD_SIZE, ST_RSP_SIZE(get_params_v2_colors) },
- { ST_PRM_SIZE(set_v2par_colors), 0},
-};
-BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS);
-
-#undef ST_CMD_SIZE
-#undef ST_PRM_SIZE
-#undef ST_RSP_SIZE
-
-static int lb_help(const char *cmd)
-{
- printf("Usage:\n");
- printf(" %s - dump all regs\n", cmd);
- printf(" %s off - enter standby\n", cmd);
- printf(" %s on - leave standby\n", cmd);
- printf(" %s init - load default vals\n", cmd);
- printf(" %s brightness [NUM] - get/set intensity(0-ff)\n", cmd);
- printf(" %s seq [NUM|SEQUENCE] - run given pattern"
- " (no arg for list)\n", cmd);
- printf(" %s CTRL REG VAL - set LED controller regs\n", cmd);
- printf(" %s LED RED GREEN BLUE - set color manually"
- " (LED=4 for all)\n", cmd);
- printf(" %s LED - get current LED color\n", cmd);
- printf(" %s demo [0|1] - turn demo mode on & off\n", cmd);
- printf(" %s params [setfile] - get params"
- " (or set from file)\n", cmd);
- printf(" %s params2 group [setfile] - get params by group\n"
- " (or set from file)\n", cmd);
- printf(" %s program file - load program from file\n", cmd);
- return 0;
-}
-
-static uint8_t lb_find_msg_by_name(const char *str)
-{
- uint8_t i;
- for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
- if (!strcasecmp(str, lightbar_cmds[i]))
- return i;
-
- return LIGHTBAR_NUM_SEQUENCES;
-}
-
-static int lb_do_cmd(enum lightbar_command cmd,
- struct ec_params_lightbar *in,
- struct ec_response_lightbar *out)
-{
- int rv;
- in->cmd = cmd;
- rv = ec_command(EC_CMD_LIGHTBAR_CMD, 0,
- in, lb_command_paramcount[cmd].insize,
- out, lb_command_paramcount[cmd].outsize);
- return (rv < 0 ? rv : 0);
-}
-
-static int lb_show_msg_names(void)
-{
- int i, current_state;
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
-
- i = lb_do_cmd(LIGHTBAR_CMD_GET_SEQ, &param, &resp);
- if (i < 0)
- return i;
- current_state = resp.get_seq.num;
-
- printf("sequence names:");
- for (i = 0; i < LIGHTBAR_NUM_SEQUENCES; i++)
- printf(" %s", lightbar_cmds[i]);
- printf("\nCurrent = 0x%x %s\n", current_state,
- lightbar_cmds[current_state]);
-
- return 0;
-}
-
-static int lb_read_params_v0_from_file(const char *filename,
- struct lightbar_params_v0 *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
- int i;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
-
- /* Do it */
- READ(1); p->google_ramp_up = val[0];
- READ(1); p->google_ramp_down = val[0];
- READ(1); p->s3s0_ramp_up = val[0];
- READ(1); p->s0_tick_delay[0] = val[0];
- READ(1); p->s0_tick_delay[1] = val[0];
- READ(1); p->s0a_tick_delay[0] = val[0];
- READ(1); p->s0a_tick_delay[1] = val[0];
- READ(1); p->s0s3_ramp_down = val[0];
- READ(1); p->s3_sleep_for = val[0];
- READ(1); p->s3_ramp_up = val[0];
- READ(1); p->s3_ramp_down = val[0];
- READ(1); p->new_s0 = val[0];
-
- READ(2);
- p->osc_min[0] = val[0];
- p->osc_min[1] = val[1];
- READ(2);
- p->osc_max[0] = val[0];
- p->osc_max[1] = val[1];
- READ(2);
- p->w_ofs[0] = val[0];
- p->w_ofs[1] = val[1];
-
- READ(2);
- p->bright_bl_off_fixed[0] = val[0];
- p->bright_bl_off_fixed[1] = val[1];
-
- READ(2);
- p->bright_bl_on_min[0] = val[0];
- p->bright_bl_on_min[1] = val[1];
-
- READ(2);
- p->bright_bl_on_max[0] = val[0];
- p->bright_bl_on_max[1] = val[1];
-
- READ(3);
- p->battery_threshold[0] = val[0];
- p->battery_threshold[1] = val[1];
- p->battery_threshold[2] = val[2];
-
- READ(4);
- p->s0_idx[0][0] = val[0];
- p->s0_idx[0][1] = val[1];
- p->s0_idx[0][2] = val[2];
- p->s0_idx[0][3] = val[3];
-
- READ(4);
- p->s0_idx[1][0] = val[0];
- p->s0_idx[1][1] = val[1];
- p->s0_idx[1][2] = val[2];
- p->s0_idx[1][3] = val[3];
-
- READ(4);
- p->s3_idx[0][0] = val[0];
- p->s3_idx[0][1] = val[1];
- p->s3_idx[0][2] = val[2];
- p->s3_idx[0][3] = val[3];
-
- READ(4);
- p->s3_idx[1][0] = val[0];
- p->s3_idx[1][1] = val[1];
- p->s3_idx[1][2] = val[2];
- p->s3_idx[1][3] = val[3];
-
- for (i = 0; i < ARRAY_SIZE(p->color); i++) {
- READ(3);
- p->color[i].r = val[0];
- p->color[i].g = val[1];
- p->color[i].b = val[2];
- }
-
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static void lb_show_params_v0(const struct lightbar_params_v0 *p)
-{
- int i;
-
- printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
- printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
- printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
- printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
- printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
- printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
- printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
- printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
- printf("%d\t# .s3_sleep_for\n", p->s3_sleep_for);
- printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
- printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- printf("%d\t\t# .new_s0\n", p->new_s0);
- printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
- p->osc_min[0], p->osc_min[1]);
- printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
- p->osc_max[0], p->osc_max[1]);
- printf("%d %d\t\t# .w_ofs (battery, AC)\n",
- p->w_ofs[0], p->w_ofs[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
- p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
- p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
- p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
- printf("%d %d %d\t\t# .battery_threshold\n",
- p->battery_threshold[0],
- p->battery_threshold[1],
- p->battery_threshold[2]);
- printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
- p->s0_idx[0][0], p->s0_idx[0][1],
- p->s0_idx[0][2], p->s0_idx[0][3]);
- printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
- p->s0_idx[1][0], p->s0_idx[1][1],
- p->s0_idx[1][2], p->s0_idx[1][3]);
- printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
- p->s3_idx[0][0], p->s3_idx[0][1],
- p->s3_idx[0][2], p->s3_idx[0][3]);
- printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
- p->s3_idx[1][0], p->s3_idx[1][1],
- p->s3_idx[1][2], p->s3_idx[1][3]);
- for (i = 0; i < ARRAY_SIZE(p->color); i++)
- printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
- p->color[i].r,
- p->color[i].g,
- p->color[i].b, i);
-}
-
-static int lb_read_params_v1_from_file(const char *filename,
- struct lightbar_params_v1 *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
- int i;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
-
- /* Do it */
- READ(1); p->google_ramp_up = val[0];
- READ(1); p->google_ramp_down = val[0];
- READ(1); p->s3s0_ramp_up = val[0];
- READ(1); p->s0_tick_delay[0] = val[0];
- READ(1); p->s0_tick_delay[1] = val[0];
- READ(1); p->s0a_tick_delay[0] = val[0];
- READ(1); p->s0a_tick_delay[1] = val[0];
- READ(1); p->s0s3_ramp_down = val[0];
- READ(1); p->s3_sleep_for = val[0];
- READ(1); p->s3_ramp_up = val[0];
- READ(1); p->s3_ramp_down = val[0];
- READ(1); p->tap_tick_delay = val[0];
- READ(1); p->tap_gate_delay = val[0];
- READ(1); p->tap_display_time = val[0];
-
- READ(1); p->tap_pct_red = val[0];
- READ(1); p->tap_pct_green = val[0];
- READ(1); p->tap_seg_min_on = val[0];
- READ(1); p->tap_seg_max_on = val[0];
- READ(1); p->tap_seg_osc = val[0];
- READ(3);
- p->tap_idx[0] = val[0];
- p->tap_idx[1] = val[1];
- p->tap_idx[2] = val[2];
-
- READ(2);
- p->osc_min[0] = val[0];
- p->osc_min[1] = val[1];
- READ(2);
- p->osc_max[0] = val[0];
- p->osc_max[1] = val[1];
- READ(2);
- p->w_ofs[0] = val[0];
- p->w_ofs[1] = val[1];
-
- READ(2);
- p->bright_bl_off_fixed[0] = val[0];
- p->bright_bl_off_fixed[1] = val[1];
-
- READ(2);
- p->bright_bl_on_min[0] = val[0];
- p->bright_bl_on_min[1] = val[1];
-
- READ(2);
- p->bright_bl_on_max[0] = val[0];
- p->bright_bl_on_max[1] = val[1];
-
- READ(3);
- p->battery_threshold[0] = val[0];
- p->battery_threshold[1] = val[1];
- p->battery_threshold[2] = val[2];
-
- READ(4);
- p->s0_idx[0][0] = val[0];
- p->s0_idx[0][1] = val[1];
- p->s0_idx[0][2] = val[2];
- p->s0_idx[0][3] = val[3];
-
- READ(4);
- p->s0_idx[1][0] = val[0];
- p->s0_idx[1][1] = val[1];
- p->s0_idx[1][2] = val[2];
- p->s0_idx[1][3] = val[3];
-
- READ(4);
- p->s3_idx[0][0] = val[0];
- p->s3_idx[0][1] = val[1];
- p->s3_idx[0][2] = val[2];
- p->s3_idx[0][3] = val[3];
-
- READ(4);
- p->s3_idx[1][0] = val[0];
- p->s3_idx[1][1] = val[1];
- p->s3_idx[1][2] = val[2];
- p->s3_idx[1][3] = val[3];
-
- for (i = 0; i < ARRAY_SIZE(p->color); i++) {
- READ(3);
- p->color[i].r = val[0];
- p->color[i].g = val[1];
- p->color[i].b = val[2];
- }
-
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static void lb_show_params_v1(const struct lightbar_params_v1 *p)
-{
- int i;
-
- printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
- printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
- printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
- printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
- printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
- printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
- printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
- printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
- printf("%d\t\t# .s3_sleep_for\n", p->s3_sleep_for);
- printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
- printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- printf("%d\t\t# .tap_tick_delay\n", p->tap_tick_delay);
- printf("%d\t\t# .tap_gate_delay\n", p->tap_gate_delay);
- printf("%d\t\t# .tap_display_time\n", p->tap_display_time);
- printf("%d\t\t# .tap_pct_red\n", p->tap_pct_red);
- printf("%d\t\t# .tap_pct_green\n", p->tap_pct_green);
- printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on);
- printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on);
- printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc);
- printf("%d %d %d\t\t# .tap_idx\n",
- p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]);
- printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
- p->osc_min[0], p->osc_min[1]);
- printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
- p->osc_max[0], p->osc_max[1]);
- printf("%d %d\t\t# .w_ofs (battery, AC)\n",
- p->w_ofs[0], p->w_ofs[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
- p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
- p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
- p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
- printf("%d %d %d\t# .battery_threshold\n",
- p->battery_threshold[0],
- p->battery_threshold[1],
- p->battery_threshold[2]);
- printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
- p->s0_idx[0][0], p->s0_idx[0][1],
- p->s0_idx[0][2], p->s0_idx[0][3]);
- printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
- p->s0_idx[1][0], p->s0_idx[1][1],
- p->s0_idx[1][2], p->s0_idx[1][3]);
- printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
- p->s3_idx[0][0], p->s3_idx[0][1],
- p->s3_idx[0][2], p->s3_idx[0][3]);
- printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
- p->s3_idx[1][0], p->s3_idx[1][1],
- p->s3_idx[1][2], p->s3_idx[1][3]);
- for (i = 0; i < ARRAY_SIZE(p->color); i++)
- printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
- p->color[i].r,
- p->color[i].g,
- p->color[i].b, i);
-}
-
-static int lb_rd_timing_v2par_from_file(const char *filename,
- struct lightbar_params_v2_timing *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(1); p->google_ramp_up = val[0];
- READ(1); p->google_ramp_down = val[0];
- READ(1); p->s3s0_ramp_up = val[0];
- READ(1); p->s0_tick_delay[0] = val[0];
- READ(1); p->s0_tick_delay[1] = val[0];
- READ(1); p->s0a_tick_delay[0] = val[0];
- READ(1); p->s0a_tick_delay[1] = val[0];
- READ(1); p->s0s3_ramp_down = val[0];
- READ(1); p->s3_sleep_for = val[0];
- READ(1); p->s3_ramp_up = val[0];
- READ(1); p->s3_ramp_down = val[0];
- READ(1); p->tap_tick_delay = val[0];
- READ(1); p->tap_gate_delay = val[0];
- READ(1); p->tap_display_time = val[0];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_tap_v2par_from_file(const char *filename,
- struct lightbar_params_v2_tap *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(1); p->tap_pct_red = val[0];
- READ(1); p->tap_pct_green = val[0];
- READ(1); p->tap_seg_min_on = val[0];
- READ(1); p->tap_seg_max_on = val[0];
- READ(1); p->tap_seg_osc = val[0];
- READ(3);
- p->tap_idx[0] = val[0];
- p->tap_idx[1] = val[1];
- p->tap_idx[2] = val[2];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_osc_v2par_from_file(const char *filename,
- struct lightbar_params_v2_oscillation *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(2);
- p->osc_min[0] = val[0];
- p->osc_min[1] = val[1];
- READ(2);
- p->osc_max[0] = val[0];
- p->osc_max[1] = val[1];
- READ(2);
- p->w_ofs[0] = val[0];
- p->w_ofs[1] = val[1];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_bright_v2par_from_file(const char *filename,
- struct lightbar_params_v2_brightness *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(2);
- p->bright_bl_off_fixed[0] = val[0];
- p->bright_bl_off_fixed[1] = val[1];
-
- READ(2);
- p->bright_bl_on_min[0] = val[0];
- p->bright_bl_on_min[1] = val[1];
-
- READ(2);
- p->bright_bl_on_max[0] = val[0];
- p->bright_bl_on_max[1] = val[1];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_thlds_v2par_from_file(const char *filename,
- struct lightbar_params_v2_thresholds *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(3);
- p->battery_threshold[0] = val[0];
- p->battery_threshold[1] = val[1];
- p->battery_threshold[2] = val[2];
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static int lb_rd_colors_v2par_from_file(const char *filename,
- struct lightbar_params_v2_colors *p)
-{
- FILE *fp;
- char buf[80];
- int val[4];
- int r = 1;
- int line = 0;
- int want, got;
- int i;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- /* We must read the correct number of params from each line */
-#define READ(N) do { \
- line++; \
- want = (N); \
- got = -1; \
- if (!fgets(buf, sizeof(buf), fp)) \
- goto done; \
- got = sscanf(buf, "%i %i %i %i", \
- &val[0], &val[1], &val[2], &val[3]); \
- if (want != got) \
- goto done; \
- } while (0)
-
- READ(4);
- p->s0_idx[0][0] = val[0];
- p->s0_idx[0][1] = val[1];
- p->s0_idx[0][2] = val[2];
- p->s0_idx[0][3] = val[3];
-
- READ(4);
- p->s0_idx[1][0] = val[0];
- p->s0_idx[1][1] = val[1];
- p->s0_idx[1][2] = val[2];
- p->s0_idx[1][3] = val[3];
-
- READ(4);
- p->s3_idx[0][0] = val[0];
- p->s3_idx[0][1] = val[1];
- p->s3_idx[0][2] = val[2];
- p->s3_idx[0][3] = val[3];
-
- READ(4);
- p->s3_idx[1][0] = val[0];
- p->s3_idx[1][1] = val[1];
- p->s3_idx[1][2] = val[2];
- p->s3_idx[1][3] = val[3];
- for (i = 0; i < ARRAY_SIZE(p->color); i++) {
- READ(3);
- p->color[i].r = val[0];
- p->color[i].g = val[1];
- p->color[i].b = val[2];
- }
-
-#undef READ
-
- /* Yay */
- r = 0;
-done:
- if (r)
- fprintf(stderr, "problem with line %d: wanted %d, got %d\n",
- line, want, got);
- fclose(fp);
- return r;
-}
-
-static void lb_show_v2par_timing(const struct lightbar_params_v2_timing *p)
-{
- printf("%d\t\t# .google_ramp_up\n", p->google_ramp_up);
- printf("%d\t\t# .google_ramp_down\n", p->google_ramp_down);
- printf("%d\t\t# .s3s0_ramp_up\n", p->s3s0_ramp_up);
- printf("%d\t\t# .s0_tick_delay (battery)\n", p->s0_tick_delay[0]);
- printf("%d\t\t# .s0_tick_delay (AC)\n", p->s0_tick_delay[1]);
- printf("%d\t\t# .s0a_tick_delay (battery)\n", p->s0a_tick_delay[0]);
- printf("%d\t\t# .s0a_tick_delay (AC)\n", p->s0a_tick_delay[1]);
- printf("%d\t\t# .s0s3_ramp_down\n", p->s0s3_ramp_down);
- printf("%d\t\t# .s3_sleep_for\n", p->s3_sleep_for);
- printf("%d\t\t# .s3_ramp_up\n", p->s3_ramp_up);
- printf("%d\t\t# .s3_ramp_down\n", p->s3_ramp_down);
- printf("%d\t\t# .tap_tick_delay\n", p->tap_tick_delay);
- printf("%d\t\t# .tap_gate_delay\n", p->tap_gate_delay);
- printf("%d\t\t# .tap_display_time\n", p->tap_display_time);
-}
-
-static void lb_show_v2par_tap(const struct lightbar_params_v2_tap *p)
-{
- printf("%d\t\t# .tap_pct_red\n", p->tap_pct_red);
- printf("%d\t\t# .tap_pct_green\n", p->tap_pct_green);
- printf("%d\t\t# .tap_seg_min_on\n", p->tap_seg_min_on);
- printf("%d\t\t# .tap_seg_max_on\n", p->tap_seg_max_on);
- printf("%d\t\t# .tap_seg_osc\n", p->tap_seg_osc);
- printf("%d %d %d\t\t# .tap_idx\n",
- p->tap_idx[0], p->tap_idx[1], p->tap_idx[2]);
-}
-
-static void lb_show_v2par_osc(const struct lightbar_params_v2_oscillation *p)
-{
- printf("0x%02x 0x%02x\t# .osc_min (battery, AC)\n",
- p->osc_min[0], p->osc_min[1]);
- printf("0x%02x 0x%02x\t# .osc_max (battery, AC)\n",
- p->osc_max[0], p->osc_max[1]);
- printf("%d %d\t\t# .w_ofs (battery, AC)\n",
- p->w_ofs[0], p->w_ofs[1]);
-}
-
-static void lb_show_v2par_bright(const struct lightbar_params_v2_brightness *p)
-{
- printf("0x%02x 0x%02x\t# .bright_bl_off_fixed (battery, AC)\n",
- p->bright_bl_off_fixed[0], p->bright_bl_off_fixed[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_min (battery, AC)\n",
- p->bright_bl_on_min[0], p->bright_bl_on_min[1]);
- printf("0x%02x 0x%02x\t# .bright_bl_on_max (battery, AC)\n",
- p->bright_bl_on_max[0], p->bright_bl_on_max[1]);
-}
-
-static void lb_show_v2par_thlds(const struct lightbar_params_v2_thresholds *p)
-{
- printf("%d %d %d\t# .battery_threshold\n",
- p->battery_threshold[0],
- p->battery_threshold[1],
- p->battery_threshold[2]);
-}
-
-static void lb_show_v2par_colors(const struct lightbar_params_v2_colors *p)
-{
- int i;
-
- printf("%d %d %d %d\t\t# .s0_idx[] (battery)\n",
- p->s0_idx[0][0], p->s0_idx[0][1],
- p->s0_idx[0][2], p->s0_idx[0][3]);
- printf("%d %d %d %d\t\t# .s0_idx[] (AC)\n",
- p->s0_idx[1][0], p->s0_idx[1][1],
- p->s0_idx[1][2], p->s0_idx[1][3]);
- printf("%d %d %d %d\t# .s3_idx[] (battery)\n",
- p->s3_idx[0][0], p->s3_idx[0][1],
- p->s3_idx[0][2], p->s3_idx[0][3]);
- printf("%d %d %d %d\t# .s3_idx[] (AC)\n",
- p->s3_idx[1][0], p->s3_idx[1][1],
- p->s3_idx[1][2], p->s3_idx[1][3]);
-
- for (i = 0; i < ARRAY_SIZE(p->color); i++)
- printf("0x%02x 0x%02x 0x%02x\t# color[%d]\n",
- p->color[i].r,
- p->color[i].g,
- p->color[i].b, i);
-}
-
-static int lb_load_program(const char *filename, struct lightbar_program *prog)
-{
- FILE *fp;
- size_t got;
- int rc;
-
- fp = fopen(filename, "rb");
- if (!fp) {
- fprintf(stderr, "Can't open %s: %s\n",
- filename, strerror(errno));
- return 1;
- }
-
- rc = fseek(fp, 0, SEEK_END);
- if (rc) {
- fprintf(stderr, "Couldn't find end of file %s",
- filename);
- fclose(fp);
- return 1;
- }
- rc = (int) ftell(fp);
- if (rc > EC_LB_PROG_LEN) {
- fprintf(stderr, "File %s is too long, aborting\n", filename);
- fclose(fp);
- return 1;
- }
- rewind(fp);
-
- memset(prog->data, 0, EC_LB_PROG_LEN);
- got = fread(prog->data, 1, EC_LB_PROG_LEN, fp);
- if (rc != got)
- fprintf(stderr, "Warning: did not read entire file\n");
- prog->size = got;
- fclose(fp);
- return 0;
-}
-
-static int cmd_lightbar_params_v0(int argc, char **argv)
-{
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
- int r;
-
- if (argc > 2) {
- r = lb_read_params_v0_from_file(argv[2],
- &param.set_params_v0);
- if (r)
- return r;
- return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V0,
- &param, &resp);
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V0, &param, &resp);
- if (!r)
- lb_show_params_v0(&resp.get_params_v0);
- return r;
-}
-
-static int cmd_lightbar_params_v1(int argc, char **argv)
-{
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
- int r;
-
- if (argc > 2) {
- r = lb_read_params_v1_from_file(argv[2],
- &param.set_params_v1);
- if (r)
- return r;
- return lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V1,
- &param, &resp);
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V1, &param, &resp);
- if (!r)
- lb_show_params_v1(&resp.get_params_v1);
- return r;
-}
-
-static void lb_param_v2_help(void)
-{
- printf("Usage:\n");
- printf("lightbar params2 group [setfile]\n");
- printf("group list:\n");
- printf(" timing\n");
- printf(" tap\n");
- printf(" oscillation\n");
- printf(" brightness\n");
- printf(" thresholds\n");
- printf(" colors\n");
-
- return;
-}
-
-static int cmd_lightbar_params_v2(int argc, char **argv)
-{
- struct ec_params_lightbar p;
- struct ec_response_lightbar resp;
- int r = 0;
- int set = 0;
-
- memset(&p, 0, sizeof(struct ec_params_lightbar));
- memset(&resp, 0, sizeof(struct ec_response_lightbar));
-
- if (argc < 3) {
- lb_param_v2_help();
- return 1;
- }
-
- /* Set new params if provided with a setfile */
- if (argc > 3)
- set = 1;
-
- /* Show selected v2 params */
- if (!strncasecmp(argv[2], "timing", 6)) {
- if (set) {
- r = lb_rd_timing_v2par_from_file(argv[3],
- &p.set_v2par_timing);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TIMING,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_TIMING, &p, &resp);
- if (r)
- return r;
- lb_show_v2par_timing(&resp.get_params_v2_timing);
- } else if (!strcasecmp(argv[2], "tap")) {
- if (set) {
- r = lb_rd_tap_v2par_from_file(argv[3],
- &p.set_v2par_tap);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_TAP,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_TAP, &p, &resp);
- if (r)
- return r;
- lb_show_v2par_tap(&resp.get_params_v2_tap);
- } else if (!strncasecmp(argv[2], "oscillation", 11)) {
- if (set) {
- r = lb_rd_osc_v2par_from_file(argv[3],
- &p.set_v2par_osc);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_OSCILLATION,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_OSCILLATION, &p,
- &resp);
- if (r)
- return r;
- lb_show_v2par_osc(&resp.get_params_v2_osc);
- } else if (!strncasecmp(argv[2], "brightness", 10)) {
- if (set) {
- r = lb_rd_bright_v2par_from_file(argv[3],
- &p.set_v2par_bright);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_BRIGHTNESS,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_BRIGHTNESS, &p,
- &resp);
- if (r)
- return r;
- lb_show_v2par_bright(&resp.get_params_v2_bright);
- } else if (!strncasecmp(argv[2], "thresholds", 10)) {
- if (set) {
- r = lb_rd_thlds_v2par_from_file(argv[3],
- &p.set_v2par_thlds);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_THRESHOLDS,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_THRESHOLDS, &p,
- &resp);
- if (r)
- return r;
- lb_show_v2par_thlds(&resp.get_params_v2_thlds);
- } else if (!strncasecmp(argv[2], "colors", 6)) {
- if (set) {
- r = lb_rd_colors_v2par_from_file(argv[3],
- &p.set_v2par_colors);
- if (r)
- return r;
- r = lb_do_cmd(LIGHTBAR_CMD_SET_PARAMS_V2_COLORS,
- &p, &resp);
- if (r)
- return r;
- }
- r = lb_do_cmd(LIGHTBAR_CMD_GET_PARAMS_V2_COLORS, &p, &resp);
- if (r)
- return r;
- lb_show_v2par_colors(&resp.get_params_v2_colors);
- } else {
- lb_param_v2_help();
- }
-
- return r;
-}
-
-static int cmd_lightbar(int argc, char **argv)
-{
- int i, r;
- struct ec_params_lightbar param;
- struct ec_response_lightbar resp;
-
- if (1 == argc) { /* no args = dump 'em all */
- r = lb_do_cmd(LIGHTBAR_CMD_DUMP, &param, &resp);
- if (r)
- return r;
- for (i = 0; i < ARRAY_SIZE(resp.dump.vals); i++) {
- printf(" %02x %02x %02x\n",
- resp.dump.vals[i].reg,
- resp.dump.vals[i].ic0,
- resp.dump.vals[i].ic1);
- }
- return 0;
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "init"))
- return lb_do_cmd(LIGHTBAR_CMD_INIT, &param, &resp);
-
- if (argc == 2 && !strcasecmp(argv[1], "off"))
- return lb_do_cmd(LIGHTBAR_CMD_OFF, &param, &resp);
-
- if (argc == 2 && !strcasecmp(argv[1], "on"))
- return lb_do_cmd(LIGHTBAR_CMD_ON, &param, &resp);
-
- if (!strcasecmp(argv[1], "params0"))
- return cmd_lightbar_params_v0(argc, argv);
-
- if (!strcasecmp(argv[1], "params1"))
- return cmd_lightbar_params_v1(argc, argv);
-
- if (!strcasecmp(argv[1], "params2"))
- return cmd_lightbar_params_v2(argc, argv);
-
- if (!strcasecmp(argv[1], "params")) {
- /* Just try them both */
- fprintf(stderr, "trying params1 ...\n");
- if (0 == cmd_lightbar_params_v1(argc, argv))
- return 0;
- fprintf(stderr, "trying params0 ...\n");
- return cmd_lightbar_params_v0(argc, argv);
- }
-
- if (!strcasecmp(argv[1], "version")) {
- r = lb_do_cmd(LIGHTBAR_CMD_VERSION, &param, &resp);
- if (!r)
- printf("version %d flags 0x%x\n",
- resp.version.num, resp.version.flags);
- return r;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "brightness")) {
- char *e;
- int rv;
- if (argc > 2) {
- param.set_brightness.num = 0xff &
- strtoul(argv[2], &e, 16);
- return lb_do_cmd(LIGHTBAR_CMD_SET_BRIGHTNESS,
- &param, &resp);
- }
- rv = lb_do_cmd(LIGHTBAR_CMD_GET_BRIGHTNESS,
- &param, &resp);
- if (rv)
- return rv;
- printf("%02x\n", resp.get_brightness.num);
- return 0;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "demo")) {
- int rv;
- if (argc > 2) {
- if (!strcasecmp(argv[2], "on") || argv[2][0] == '1')
- param.demo.num = 1;
- else if (!strcasecmp(argv[2], "off") ||
- argv[2][0] == '0')
- param.demo.num = 0;
- else {
- fprintf(stderr, "Invalid arg\n");
- return -1;
- }
- return lb_do_cmd(LIGHTBAR_CMD_DEMO, &param, &resp);
- }
-
- rv = lb_do_cmd(LIGHTBAR_CMD_GET_DEMO, &param, &resp);
- if (rv)
- return rv;
- printf("%s\n", resp.get_demo.num ? "on" : "off");
- return 0;
- }
-
- if (argc >= 2 && !strcasecmp(argv[1], "seq")) {
- char *e;
- uint8_t num;
- if (argc == 2)
- return lb_show_msg_names();
- num = 0xff & strtoul(argv[2], &e, 16);
- if (e && *e)
- num = lb_find_msg_by_name(argv[2]);
- if (num >= LIGHTBAR_NUM_SEQUENCES) {
- fprintf(stderr, "Invalid arg\n");
- return -1;
- }
- param.seq.num = num;
- return lb_do_cmd(LIGHTBAR_CMD_SEQ, &param, &resp);
- }
-
- if (argc >= 3 && !strcasecmp(argv[1], "program")) {
- lb_load_program(argv[2], &param.set_program);
- return lb_do_cmd(LIGHTBAR_CMD_SET_PROGRAM, &param, &resp);
- }
-
- if (argc == 4) {
- char *e;
- param.reg.ctrl = 0xff & strtoul(argv[1], &e, 16);
- param.reg.reg = 0xff & strtoul(argv[2], &e, 16);
- param.reg.value = 0xff & strtoul(argv[3], &e, 16);
- return lb_do_cmd(LIGHTBAR_CMD_REG, &param, &resp);
- }
-
- if (argc == 5) {
- char *e;
- param.set_rgb.led = strtoul(argv[1], &e, 16);
- param.set_rgb.red = strtoul(argv[2], &e, 16);
- param.set_rgb.green = strtoul(argv[3], &e, 16);
- param.set_rgb.blue = strtoul(argv[4], &e, 16);
- return lb_do_cmd(LIGHTBAR_CMD_SET_RGB, &param, &resp);
- }
-
- /* Only thing left is to try to read an LED value */
- if (argc == 2) {
- char *e;
- param.get_rgb.led = strtoul(argv[1], &e, 0);
- if (!(e && *e)) {
- r = lb_do_cmd(LIGHTBAR_CMD_GET_RGB, &param, &resp);
- if (r)
- return r;
- printf("%02x %02x %02x\n",
- resp.get_rgb.red,
- resp.get_rgb.green,
- resp.get_rgb.blue);
- return 0;
- }
- }
-
- return lb_help(argv[0]);
-}
-
-/* Create an array to store sizes of motion sense param and response structs. */
-#define ST_CMD_SIZE ST_FLD_SIZE(ec_params_motion_sense, cmd)
-#define ST_PRM_SIZE(SUBCMD) \
- (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_motion_sense, SUBCMD))
-#define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_motion_sense, SUBCMD)
-#define ST_BOTH_SIZES(SUBCMD) { ST_PRM_SIZE(SUBCMD), ST_RSP_SIZE(SUBCMD) }
-
-/*
- * For ectool only, assume no more than 16 sensors. More advanced
- * implementation would allocate the right amount of memory depending on the
- * number of sensors.
- */
-#define ECTOOL_MAX_SENSOR 16
-
-static const struct {
- uint8_t outsize;
- uint8_t insize;
-} ms_command_sizes[] = {
- {
- ST_PRM_SIZE(dump),
- ST_RSP_SIZE(dump) +
- sizeof(struct ec_response_motion_sensor_data) *
- ECTOOL_MAX_SENSOR
- },
- ST_BOTH_SIZES(info_3),
- ST_BOTH_SIZES(ec_rate),
- ST_BOTH_SIZES(sensor_odr),
- ST_BOTH_SIZES(sensor_range),
- ST_BOTH_SIZES(kb_wake_angle),
- ST_BOTH_SIZES(data),
- {
- ST_CMD_SIZE,
- ST_RSP_SIZE(fifo_info) + sizeof(uint16_t) * ECTOOL_MAX_SENSOR
- },
- ST_BOTH_SIZES(fifo_flush),
- ST_BOTH_SIZES(fifo_read),
- ST_BOTH_SIZES(perform_calib),
- ST_BOTH_SIZES(sensor_offset),
- ST_BOTH_SIZES(list_activities),
- { ST_PRM_SIZE(set_activity), 0 },
- { ST_CMD_SIZE, ST_RSP_SIZE(lid_angle) },
- ST_BOTH_SIZES(fifo_int_enable),
- ST_BOTH_SIZES(spoof),
- ST_BOTH_SIZES(tablet_mode_threshold),
- ST_BOTH_SIZES(sensor_scale),
-};
-BUILD_ASSERT(ARRAY_SIZE(ms_command_sizes) == MOTIONSENSE_NUM_CMDS);
-
-#undef ST_CMD_SIZE
-#undef ST_PRM_SIZE
-#undef ST_RSP_SIZE
-#undef ST_BOTH_SIZES
-
-static int ms_help(const char *cmd)
-{
- printf("Usage:\n");
- printf(" %s - dump all motion data\n", cmd);
- printf(" %s active - print active flag\n", cmd);
- printf(" %s info NUM - print sensor info\n", cmd);
- printf(" %s ec_rate [RATE_MS] - set/get sample rate\n", cmd);
- printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n", cmd);
- printf(" %s range NUM [RANGE [ROUNDUP]]- set/get sensor range\n", cmd);
- printf(" %s offset NUM - get sensor offset\n", cmd);
- printf(" %s kb_wake NUM - set/get KB wake ang\n", cmd);
- printf(" %s data NUM - read sensor latest data\n",
- cmd);
- printf(" %s fifo_info - print fifo info\n", cmd);
- printf(" %s fifo_int_enable [0/1] - enable/disable/get fifo "
- "interrupt status\n", cmd);
- printf(" %s fifo_read MAX_DATA - read fifo data\n", cmd);
- printf(" %s fifo_flush NUM - trigger fifo interrupt\n",
- cmd);
- printf(" %s list_activities NUM - list supported activities\n",
- cmd);
- printf(" %s set_activity NUM ACT EN - enable/disable activity\n",
- cmd);
- printf(" %s lid_angle - print lid angle\n", cmd);
- printf(" %s spoof -- NUM [0/1] [X Y Z] - enable/disable spoofing\n",
- cmd);
- printf(" %s tablet_mode_angle ANG HYS - set/get tablet mode angle\n",
- cmd);
-
- return 0;
-}
-
-static void motionsense_display_activities(uint32_t activities)
-{
- if (activities & BIT(MOTIONSENSE_ACTIVITY_SIG_MOTION))
- printf("%d: Significant motion\n",
- MOTIONSENSE_ACTIVITY_SIG_MOTION);
- if (activities & BIT(MOTIONSENSE_ACTIVITY_DOUBLE_TAP))
- printf("%d: Double tap\n",
- MOTIONSENSE_ACTIVITY_DOUBLE_TAP);
-}
-
-static int cmd_motionsense(int argc, char **argv)
-{
- int i, rv, status_only = (argc == 2);
- struct ec_params_motion_sense param;
- /* The largest size using resp as a response buffer */
- uint8_t resp_buffer[ms_command_sizes[MOTIONSENSE_CMD_DUMP].insize];
- struct ec_response_motion_sense *resp =
- (struct ec_response_motion_sense *)resp_buffer;
- char *e;
- /*
- * Warning: the following strings printed out are read in an
- * autotest. Do not change string without consulting autotest
- * for kernel_CrosECSysfsAccel.
- */
- const char *motion_status_string[2][2] = {
- { "Motion sensing inactive", "0"},
- { "Motion sensing active", "1"},
- };
-
- /* No motionsense command has more than 7 args. */
- if (argc > 7)
- return ms_help(argv[0]);
-
- if ((argc == 1) ||
- (argc == 2 && !strcasecmp(argv[1], "active"))) {
- param.cmd = MOTIONSENSE_CMD_DUMP;
- param.dump.max_sensor_count = ECTOOL_MAX_SENSOR;
- rv = ec_command(
- EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv > 0) {
- printf("%s\n", motion_status_string[
- !!(resp->dump.module_flags &
- MOTIONSENSE_MODULE_FLAG_ACTIVE)][
- status_only]);
- if (status_only)
- return 0;
-
- if (resp->dump.sensor_count > ECTOOL_MAX_SENSOR) {
- printf("Too many sensors to handle: %d",
- resp->dump.sensor_count);
- return -1;
- }
- for (i = 0; i < resp->dump.sensor_count; i++) {
- /*
- * Warning: the following string printed out
- * is read by an autotest. Do not change string
- * without consulting autotest for
- * kernel_CrosECSysfsAccel.
- */
- printf("Sensor %d: ", i);
- if (resp->dump.sensor[i].flags &
- MOTIONSENSE_SENSOR_FLAG_PRESENT)
- printf("%d\t%d\t%d\n",
- resp->dump.sensor[i].data[0],
- resp->dump.sensor[i].data[1],
- resp->dump.sensor[i].data[2]);
- else
- printf("None\n");
- }
- return 0;
- } else {
- return rv;
- }
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "info")) {
- int version = 0;
-
- rv = get_latest_cmd_version(EC_CMD_MOTION_SENSE_CMD, &version);
- if (rv < 0)
- return rv;
-
- param.cmd = MOTIONSENSE_CMD_INFO;
- param.sensor_odr.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, version,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Type: ");
- switch (resp->info.type) {
- case MOTIONSENSE_TYPE_ACCEL:
- printf("accel\n");
- break;
- case MOTIONSENSE_TYPE_GYRO:
- printf("gyro\n");
- break;
- case MOTIONSENSE_TYPE_MAG:
- printf("magnetometer\n");
- break;
- case MOTIONSENSE_TYPE_LIGHT:
- printf("light\n");
- break;
- case MOTIONSENSE_TYPE_LIGHT_RGB:
- printf("rgb light\n");
- break;
- case MOTIONSENSE_TYPE_PROX:
- printf("proximity\n");
- break;
- case MOTIONSENSE_TYPE_ACTIVITY:
- printf("activity\n");
- break;
- case MOTIONSENSE_TYPE_BARO:
- printf("barometer\n");
- break;
- case MOTIONSENSE_TYPE_SYNC:
- printf("sync\n");
- break;
- default:
- printf("unknown\n");
- }
-
- printf("Location: ");
- switch (resp->info.location) {
- case MOTIONSENSE_LOC_BASE:
- printf("base\n");
- break;
- case MOTIONSENSE_LOC_LID:
- printf("lid\n");
- break;
- case MOTIONSENSE_LOC_CAMERA:
- printf("camera\n");
- break;
- default:
- printf("unknown\n");
- }
-
- printf("Chip: ");
- switch (resp->info.chip) {
- case MOTIONSENSE_CHIP_KXCJ9:
- printf("kxcj9\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DS0:
- printf("lsm6ds0\n");
- break;
- case MOTIONSENSE_CHIP_BMI160:
- printf("bmi160\n");
- break;
- case MOTIONSENSE_CHIP_SI1141:
- printf("si1141\n");
- break;
- case MOTIONSENSE_CHIP_KX022:
- printf("kx022\n");
- break;
- case MOTIONSENSE_CHIP_L3GD20H:
- printf("l3gd20h\n");
- break;
- case MOTIONSENSE_CHIP_BMA255:
- printf("bma255\n");
- break;
- case MOTIONSENSE_CHIP_BMP280:
- printf("bmp280\n");
- break;
- case MOTIONSENSE_CHIP_OPT3001:
- printf("opt3001\n");
- break;
- case MOTIONSENSE_CHIP_BH1730:
- printf("bh1730\n");
- break;
- case MOTIONSENSE_CHIP_GPIO:
- printf("gpio\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DH:
- printf("lis2dh\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DSM:
- printf("lsm6dsm\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DE:
- printf("lis2de\n");
- break;
- case MOTIONSENSE_CHIP_LIS2MDL:
- printf("lis2mdl\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DS3:
- printf("lsm6ds3\n");
- break;
- case MOTIONSENSE_CHIP_LSM6DSO:
- printf("lsm6dso\n");
- break;
- case MOTIONSENSE_CHIP_LNG2DM:
- printf("lng2dm\n");
- break;
- case MOTIONSENSE_CHIP_TCS3400:
- printf("tcs3400\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DW12:
- printf("lis2dw12\n");
- break;
- case MOTIONSENSE_CHIP_LIS2DWL:
- printf("lis2dwl\n");
- break;
- default:
- printf("unknown\n");
- }
-
- if (version >= 3) {
- printf("Min Frequency: %d mHz\n",
- resp->info_3.min_frequency);
- printf("Max Frequency: %d mHz\n",
- resp->info_3.max_frequency);
- printf("FIFO Max Event Count: %d\n",
- resp->info_3.fifo_max_event_count);
- }
- return 0;
- }
-
- if (argc < 4 && !strcasecmp(argv[1], "ec_rate")) {
- param.cmd = MOTIONSENSE_CMD_EC_RATE;
- param.ec_rate.data = EC_MOTION_SENSE_NO_VALUE;
-
- if (argc == 3) {
- param.ec_rate.data = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->ec_rate.ret);
- return 0;
- }
-
- if (argc > 2 && !strcasecmp(argv[1], "odr")) {
- param.cmd = MOTIONSENSE_CMD_SENSOR_ODR;
- param.sensor_odr.data = EC_MOTION_SENSE_NO_VALUE;
- param.sensor_odr.roundup = 1;
-
- param.sensor_odr.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- if (argc >= 4) {
- param.sensor_odr.data = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
- }
-
- if (argc == 5) {
- param.sensor_odr.roundup = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[4]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->sensor_odr.ret);
- return 0;
- }
-
- if (argc > 2 && !strcasecmp(argv[1], "range")) {
- param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
- param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
- param.sensor_range.roundup = 1;
-
- param.sensor_range.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- if (argc >= 4) {
- param.sensor_range.data = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
- }
-
- if (argc == 5) {
- param.sensor_odr.roundup = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[4]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->sensor_range.ret);
- return 0;
- }
-
- if (argc < 4 && !strcasecmp(argv[1], "kb_wake")) {
- param.cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE;
- param.kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE;
-
- if (argc == 3) {
- param.kb_wake_angle.data = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->kb_wake_angle.ret);
- return 0;
- }
-
- if (argc < 5 && !strcasecmp(argv[1], "tablet_mode_angle")) {
- param.cmd = MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE;
- /*
- * EC_MOTION_SENSE_NO_VALUE indicates to the EC that host is
- * attempting to only read the current values.
- */
- param.tablet_mode_threshold.lid_angle =
- EC_MOTION_SENSE_NO_VALUE;
- param.tablet_mode_threshold.hys_degree =
- EC_MOTION_SENSE_NO_VALUE;
-
- if (argc == 4) {
- param.tablet_mode_threshold.lid_angle = strtol(argv[2],
- &e, 0);
-
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- param.tablet_mode_threshold.hys_degree = strtol(argv[3],
- &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
- } else if (argc != 2) {
- return ms_help(argv[0]);
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("tablet_mode_angle=%d hys=%d\n",
- resp->tablet_mode_threshold.lid_angle,
- resp->tablet_mode_threshold.hys_degree);
-
- return 0;
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "fifo_info")) {
- int sensor_count;
-
- param.cmd = MOTIONSENSE_CMD_DUMP;
- param.dump.max_sensor_count = 0;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
- sensor_count = resp->dump.sensor_count;
-
- param.cmd = MOTIONSENSE_CMD_FIFO_INFO;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Size: %d\n", resp->fifo_info.size);
- printf("Count: %d\n", resp->fifo_info.count);
- printf("Timestamp:%" PRIx32 "\n", resp->fifo_info.timestamp);
- printf("Total lost: %d\n", resp->fifo_info.total_lost);
- for (i = 0; i < sensor_count; i++) {
- int lost = resp->fifo_info.lost[i];
- if (lost != 0)
- printf("Lost %d: %d\n", i, lost);
- }
- return 0;
- }
-
- if (argc >= 2 && !strcasecmp(argv[1], "fifo_int_enable")) {
- param.cmd = MOTIONSENSE_CMD_FIFO_INT_ENABLE;
- if (argc == 3)
- param.fifo_int_enable.enable = strtol(argv[2], &e, 0);
- else
- param.fifo_int_enable.enable = EC_MOTION_SENSE_NO_VALUE;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("%d\n", resp->fifo_int_enable.ret);
- return 0;
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "fifo_read")) {
- /* large number to test fragmentation */
- struct {
- uint32_t number_data;
- struct ec_response_motion_sensor_data data[512];
- } fifo_read_buffer = {
- .number_data = -1,
- };
- int print_data = 0, max_data = strtol(argv[2], &e, 0);
-
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
- while (fifo_read_buffer.number_data != 0 &&
- print_data < max_data) {
- struct ec_response_motion_sensor_data *vector;
- param.cmd = MOTIONSENSE_CMD_FIFO_READ;
- param.fifo_read.max_data_vector =
- MIN(ARRAY_SIZE(fifo_read_buffer.data),
- max_data - print_data);
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param,
- ms_command_sizes[param.cmd].outsize,
- &fifo_read_buffer, ec_max_insize);
- if (rv < 0)
- return rv;
-
- print_data += fifo_read_buffer.number_data;
- for (i = 0; i < fifo_read_buffer.number_data; i++) {
- vector = &fifo_read_buffer.data[i];
- if (vector->flags &
- (MOTIONSENSE_SENSOR_FLAG_TIMESTAMP |
- MOTIONSENSE_SENSOR_FLAG_FLUSH)) {
- uint32_t timestamp = 0;
-
- memcpy(&timestamp, vector->data,
- sizeof(uint32_t));
- printf("Timestamp:%" PRIx32 "%s\n",
- timestamp,
- (vector->flags &
- MOTIONSENSE_SENSOR_FLAG_FLUSH ?
- " - Flush" : ""));
- } else {
- printf("Sensor %d: %d\t%d\t%d "
- "(as uint16: %u\t%u\t%u)\n",
- vector->sensor_num,
- vector->data[0],
- vector->data[1],
- vector->data[2],
- vector->data[0],
- vector->data[1],
- vector->data[2]);
- }
- }
- }
- return 0;
- }
- if (argc == 3 && !strcasecmp(argv[1], "fifo_flush")) {
- param.cmd = MOTIONSENSE_CMD_FIFO_FLUSH;
-
- param.sensor_odr.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- return rv < 0 ? rv : 0;
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "offset")) {
- param.cmd = MOTIONSENSE_CMD_SENSOR_OFFSET;
- param.sensor_offset.flags = 0;
-
- param.sensor_offset.sensor_num = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 1,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
-
- if (rv < 0)
- return rv;
-
- printf("Offset vector: X:%d, Y:%d, Z:%d\n",
- resp->sensor_offset.offset[0],
- resp->sensor_offset.offset[1],
- resp->sensor_offset.offset[2]);
- if ((uint16_t)resp->sensor_offset.temp ==
- EC_MOTION_SENSE_INVALID_CALIB_TEMP)
- printf("temperature at calibration unknown\n");
- else
- printf("temperature at calibration: %d.%02d C\n",
- resp->sensor_offset.temp / 100,
- resp->sensor_offset.temp % 100);
- return 0;
- }
-
- if (argc == 3 && !strcasecmp(argv[1], "list_activities")) {
- param.cmd = MOTIONSENSE_CMD_LIST_ACTIVITIES;
- param.list_activities.sensor_num = strtol(argv[2], &e, 0);
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Enabled:\n");
- motionsense_display_activities(resp->list_activities.enabled);
- printf("Disabled:\n");
- motionsense_display_activities(resp->list_activities.disabled);
- return 0;
- }
- if (argc == 5 && !strcasecmp(argv[1], "set_activity")) {
- param.cmd = MOTIONSENSE_CMD_SET_ACTIVITY;
- param.set_activity.sensor_num = strtol(argv[2], &e, 0);
- param.set_activity.activity = strtol(argv[3], &e, 0);
- param.set_activity.enable = strtol(argv[4], &e, 0);
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
- return 0;
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "lid_angle")) {
- param.cmd = MOTIONSENSE_CMD_LID_ANGLE;
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- printf("Lid angle: ");
- if (resp->lid_angle.value == LID_ANGLE_UNRELIABLE)
- printf("unreliable\n");
- else
- printf("%d\n", resp->lid_angle.value);
-
- return 0;
- }
-
- if (argc >= 3 && !strcasecmp(argv[1], "spoof")) {
- param.cmd = MOTIONSENSE_CMD_SPOOF;
- /* By default, just query the current spoof status. */
- param.spoof.spoof_enable = MOTIONSENSE_SPOOF_MODE_QUERY;
- param.spoof.sensor_id = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n", argv[2]);
- return -1;
- }
-
- if (argc >= 4) {
- int enable, i;
- int16_t val;
-
- enable = strtol(argv[3], &e, 0);
- if ((e && *e) || (enable != 0 && enable != 1)) {
- fprintf(stderr, "Bad %s arg.\n", argv[3]);
- return -1;
- }
-
- if ((enable == 1) && (argc == 4)) {
- /*
- * Enable spoofing, but lock to current sensor
- * values.
- */
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_LOCK_CURRENT;
- } else if ((enable == 1) && (argc == 7)) {
- /*
- * Enable spoofing, but use provided component
- * values.
- */
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_CUSTOM;
- for (i = 0; i < 3; i++) {
- val = strtol(argv[4+i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad %s arg.\n",
- argv[4+i]);
- return -1;
- }
- param.spoof.components[i] = val;
- }
- } else if (enable == 0) {
- param.spoof.spoof_enable =
- MOTIONSENSE_SPOOF_MODE_DISABLE;
- } else {
- return ms_help(argv[0]);
- }
- }
-
- rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2,
- &param, ms_command_sizes[param.cmd].outsize,
- resp, ms_command_sizes[param.cmd].insize);
- if (rv < 0)
- return rv;
-
- if (param.spoof.spoof_enable == MOTIONSENSE_SPOOF_MODE_QUERY)
- /*
- * Response is the current spoof status of the
- * sensor.
- */
- printf("Sensor %d spoof mode is %s.\n",
- param.spoof.sensor_id,
- resp->spoof.ret ? "enabled" : "disabled");
-
- return 0;
- }
-
- return ms_help(argv[0]);
-}
-
-int cmd_next_event(int argc, char *argv[])
-{
- uint8_t *rdata = (uint8_t *)ec_inbuf;
- int rv;
- int i;
-
- rv = ec_command(EC_CMD_GET_NEXT_EVENT, 0,
- NULL, 0, rdata, ec_max_insize);
- if (rv < 0)
- return rv;
-
- printf("Next event is 0x%02x\n", rdata[0]);
- if (rv > 1) {
- printf("Event data:\n");
- for (i = 1; i < rv; ++i) {
- printf("%02x ", rdata[i]);
- if (!(i & 0xf))
- printf("\n");
- }
- printf("\n");
- }
-
- return 0;
-}
-
-static int find_led_color_by_name(const char *color)
-{
- int i;
-
- for (i = 0; i < EC_LED_COLOR_COUNT; ++i)
- if (!strcasecmp(color, led_color_names[i]))
- return i;
-
- return -1;
-}
-
-static int find_led_id_by_name(const char *led)
-{
- int i;
-
- for (i = 0; i < EC_LED_ID_COUNT; ++i)
- if (!strcasecmp(led, led_names[i]))
- return i;
-
- return -1;
-}
-
-int cmd_led(int argc, char *argv[])
-{
- struct ec_params_led_control p;
- struct ec_response_led_control r;
- char *e, *ptr;
- int rv, i, j;
-
- memset(p.brightness, 0, sizeof(p.brightness));
- p.flags = 0;
-
- if (argc < 3) {
- fprintf(stderr,
- "Usage: %s <name> <query | auto | "
- "off | <color> | <color>=<value>...>\n", argv[0]);
- return -1;
- }
-
- p.led_id = find_led_id_by_name(argv[1]);
- if (p.led_id == (uint8_t)-1) {
- fprintf(stderr, "Bad LED name: %s\n", argv[1]);
- fprintf(stderr, "Valid LED names: ");
- for (i = 0; i < EC_LED_ID_COUNT; i++)
- fprintf(stderr, "%s ", led_names[i]);
- fprintf(stderr, "\n");
- return -1;
- }
-
- if (!strcasecmp(argv[2], "query")) {
- p.flags = EC_LED_FLAGS_QUERY;
- rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p),
- &r, sizeof(r));
- printf("Brightness range for LED %d:\n", p.led_id);
- if (rv < 0) {
- fprintf(stderr, "Error: Unsupported LED.\n");
- return rv;
- }
- for (i = 0; i < EC_LED_COLOR_COUNT; ++i)
- printf("\t%s\t: 0x%x\n",
- led_color_names[i],
- r.brightness_range[i]);
- return 0;
- }
-
- if (!strcasecmp(argv[2], "off")) {
- /* Brightness initialized to 0 for each color. */
- } else if (!strcasecmp(argv[2], "auto")) {
- p.flags = EC_LED_FLAGS_AUTO;
- } else if ((i = find_led_color_by_name(argv[2])) != -1) {
- p.brightness[i] = 0xff;
- } else {
- for (i = 2; i < argc; ++i) {
- ptr = strtok(argv[i], "=");
- j = find_led_color_by_name(ptr);
- if (j == -1) {
- fprintf(stderr, "Bad color name: %s\n", ptr);
- fprintf(stderr, "Valid colors: ");
- for (j = 0; j < EC_LED_COLOR_COUNT; j++)
- fprintf(stderr, "%s ",
- led_color_names[j]);
- fprintf(stderr, "\n");
- return -1;
- }
- ptr = strtok(NULL, "=");
- if (ptr == NULL) {
- fprintf(stderr, "Missing brightness value\n");
- return -1;
- }
- p.brightness[j] = strtol(ptr, &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad brightness: %s\n", ptr);
- return -1;
- }
- }
- }
-
- rv = ec_command(EC_CMD_LED_CONTROL, 1, &p, sizeof(p), &r, sizeof(r));
- return (rv < 0 ? rv : 0);
-}
-
-
-int cmd_usb_charge_set_mode(int argc, char *argv[])
-{
- struct ec_params_usb_charge_set_mode p;
- char *e;
- int rv;
-
- if (argc != 3 && argc != 4) {
- fprintf(stderr,
- "Usage: %s <port_id> <mode_id> [<inhibit_charge>]\n",
- argv[0]);
- return -1;
- }
- p.usb_port_id = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port ID.\n");
- return -1;
- }
- p.mode = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mode ID.\n");
- return -1;
- }
- p.inhibit_charge = 0;
- if (argc == 4) {
- p.inhibit_charge = strtol(argv[3], &e, 0);
- if ((e && *e) || (p.inhibit_charge != 0 &&
- p.inhibit_charge != 1)) {
- fprintf(stderr, "Bad value\n");
- return -1;
- }
- }
-
- printf("Setting port %d to mode %d inhibit_charge %d...\n",
- p.usb_port_id, p.mode, p.inhibit_charge);
-
- rv = ec_command(EC_CMD_USB_CHARGE_SET_MODE, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("USB charging mode set.\n");
- return 0;
-}
-
-
-int cmd_usb_mux(int argc, char *argv[])
-{
- struct ec_params_usb_mux p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mux>\n", argv[0]);
- return -1;
- }
-
- p.mux = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mux value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_USB_MUX, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Set USB mux to 0x%x.\n", p.mux);
-
- return 0;
-}
-
-
-int cmd_usb_pd(int argc, char *argv[])
-{
- const char *role_str[] = {"", "toggle", "toggle-off", "sink", "source",
- "freeze"};
- const char *mux_str[] = {"", "none", "usb", "dp", "dock", "auto"};
- const char *swap_str[] = {"", "dr_swap", "pr_swap", "vconn_swap"};
- struct ec_params_usb_pd_control p;
- struct ec_response_usb_pd_control_v2 *r_v2 =
- (struct ec_response_usb_pd_control_v2 *)ec_inbuf;
- struct ec_response_usb_pd_control_v1 *r_v1 =
- (struct ec_response_usb_pd_control_v1 *)ec_inbuf;
- struct ec_response_usb_pd_control *r =
- (struct ec_response_usb_pd_control *)ec_inbuf;
- int rv, i, j;
- int option_ok;
- char *e;
- int cmdver;
-
- BUILD_ASSERT(ARRAY_SIZE(role_str) == USB_PD_CTRL_ROLE_COUNT);
- BUILD_ASSERT(ARRAY_SIZE(mux_str) == USB_PD_CTRL_MUX_COUNT);
- BUILD_ASSERT(ARRAY_SIZE(swap_str) == USB_PD_CTRL_SWAP_COUNT);
- p.role = USB_PD_CTRL_ROLE_NO_CHANGE;
- p.mux = USB_PD_CTRL_MUX_NO_CHANGE;
- p.swap = USB_PD_CTRL_SWAP_NONE;
-
- if (argc < 2) {
- fprintf(stderr, "No port specified.\n");
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Invalid param (port)\n");
- return -1;
- }
-
- for (i = 2; i < argc; ++i) {
- option_ok = 0;
- if (!strcmp(argv[i], "auto")) {
- if (argc != 3) {
- fprintf(stderr, "\"auto\" may not be used "
- "with other options.\n");
- return -1;
- }
- p.role = USB_PD_CTRL_ROLE_TOGGLE_ON;
- p.mux = USB_PD_CTRL_MUX_AUTO;
- continue;
- }
-
- for (j = 0; j < ARRAY_SIZE(role_str); ++j) {
- if (!strcmp(argv[i], role_str[j])) {
- if (p.role != USB_PD_CTRL_ROLE_NO_CHANGE) {
- fprintf(stderr,
- "Only one role allowed.\n");
- return -1;
- }
- p.role = j;
- option_ok = 1;
- break;
- }
- }
- if (option_ok)
- continue;
-
- for (j = 0; j < ARRAY_SIZE(mux_str); ++j) {
- if (!strcmp(argv[i], mux_str[j])) {
- if (p.mux != USB_PD_CTRL_MUX_NO_CHANGE) {
- fprintf(stderr,
- "Only one mux type allowed.\n");
- return -1;
- }
- p.mux = j;
- option_ok = 1;
- break;
- }
- }
- if (option_ok)
- continue;
-
- for (j = 0; j < ARRAY_SIZE(swap_str); ++j) {
- if (!strcmp(argv[i], swap_str[j])) {
- if (p.swap != USB_PD_CTRL_SWAP_NONE) {
- fprintf(stderr,
- "Only one swap type allowed.\n");
- return -1;
- }
- p.swap = j;
- option_ok = 1;
- break;
- }
- }
-
-
- if (!option_ok) {
- fprintf(stderr, "Unknown option: %s\n", argv[i]);
- return -1;
- }
- }
-
- if (ec_cmd_version_supported(EC_CMD_USB_PD_CONTROL, 2))
- cmdver = 2;
- else if (ec_cmd_version_supported(EC_CMD_USB_PD_CONTROL, 1))
- cmdver = 1;
- else
- cmdver = 0;
-
- rv = ec_command(EC_CMD_USB_PD_CONTROL, cmdver, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
-
- if (rv < 0 || argc != 2)
- return (rv < 0) ? rv : 0;
-
- if (cmdver == 0) {
- printf("Port C%d is %sabled, Role:%s Polarity:CC%d State:%d\n",
- p.port, (r->enabled) ? "en" : "dis",
- r->role == PD_ROLE_SOURCE ? "SRC" : "SNK",
- r->polarity + 1, r->state);
- } else {
- printf("Port C%d: %s, %s State:%s\n"
- "Role:%s %s%s, Polarity:CC%d\n",
- p.port,
- (r_v1->enabled & PD_CTRL_RESP_ENABLED_COMMS) ?
- "enabled" : "disabled",
- (r_v1->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) ?
- "connected" : "disconnected",
- r_v1->state,
-
- (r_v1->role & PD_CTRL_RESP_ROLE_POWER) ? "SRC" : "SNK",
- (r_v1->role & PD_CTRL_RESP_ROLE_DATA) ? "DFP" : "UFP",
- (r_v1->role & PD_CTRL_RESP_ROLE_VCONN) ? " VCONN" : "",
- r_v1->polarity + 1);
-
- if (cmdver == 2) {
- printf("CC State:");
- if (r_v2->cc_state == PD_CC_NONE)
- printf("None");
- else if (r_v2->cc_state == PD_CC_UFP_AUDIO_ACC)
- printf("UFP Audio accessory");
- else if (r_v2->cc_state == PD_CC_UFP_DEBUG_ACC)
- printf("UFP Debug accessory");
- else if (r_v2->cc_state == PD_CC_UFP_ATTACHED)
- printf("UFP attached");
- else if (r_v2->cc_state == PD_CC_DFP_DEBUG_ACC)
- printf("DFP Debug accessory");
- else if (r_v2->cc_state == PD_CC_DFP_ATTACHED)
- printf("DFP attached");
- else
- printf("UNKNOWN");
- printf("\n");
-
- if (r_v2->dp_mode) {
- printf("DP pin mode:");
- if (r_v2->dp_mode == MODE_DP_PIN_A)
- printf("A");
- else if (r_v2->dp_mode == MODE_DP_PIN_B)
- printf("B");
- else if (r_v2->dp_mode == MODE_DP_PIN_C)
- printf("C");
- else if (r_v2->dp_mode == MODE_DP_PIN_D)
- printf("D");
- else if (r_v2->dp_mode == MODE_DP_PIN_E)
- printf("E");
- else if (r_v2->dp_mode == MODE_DP_PIN_F)
- printf("F");
- else
- printf("UNKNOWN");
- printf("\n");
- }
- if (r_v2->cable_type) {
- printf("Cable type:");
- if (r_v2->cable_type == IDH_PTYPE_ACABLE)
- printf("Active");
- else if (r_v2->cable_type == IDH_PTYPE_PCABLE)
- printf("Passive");
- else
- printf("UNKNOWN");
- printf("\n");
- }
- }
-
- /* If connected to a PD device, then print port partner info */
- if ((r_v1->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) &&
- (r_v1->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE))
- printf("PD Partner Capabilities:\n%s%s%s%s",
- (r_v1->role & PD_CTRL_RESP_ROLE_DR_POWER) ?
- " DR power\n" : "",
- (r_v1->role & PD_CTRL_RESP_ROLE_DR_DATA) ?
- " DR data\n" : "",
- (r_v1->role & PD_CTRL_RESP_ROLE_USB_COMM) ?
- " USB capable\n" : "",
- (r_v1->role & PD_CTRL_RESP_ROLE_EXT_POWERED) ?
- " Externally powered\n" : "");
- }
- return 0;
-}
-
-static void print_pd_power_info(struct ec_response_usb_pd_power_info *r)
-{
- switch (r->role) {
- case USB_PD_PORT_POWER_DISCONNECTED:
- printf("Disconnected");
- break;
- case USB_PD_PORT_POWER_SOURCE:
- printf("SRC");
- break;
- case USB_PD_PORT_POWER_SINK:
- printf("SNK");
- break;
- case USB_PD_PORT_POWER_SINK_NOT_CHARGING:
- printf("SNK (not charging)");
- break;
- default:
- printf("Unknown");
- }
-
- if ((r->role == USB_PD_PORT_POWER_SOURCE) &&
- (r->meas.current_max))
- printf(" %dmA", r->meas.current_max);
-
- if ((r->role == USB_PD_PORT_POWER_DISCONNECTED) ||
- (r->role == USB_PD_PORT_POWER_SOURCE)) {
- printf("\n");
- return;
- }
-
- printf(r->dualrole ? " DRP" : " Charger");
- switch (r->type) {
- case USB_CHG_TYPE_PD:
- printf(" PD");
- break;
- case USB_CHG_TYPE_C:
- printf(" Type-C");
- break;
- case USB_CHG_TYPE_PROPRIETARY:
- printf(" Proprietary");
- break;
- case USB_CHG_TYPE_BC12_DCP:
- printf(" DCP");
- break;
- case USB_CHG_TYPE_BC12_CDP:
- printf(" CDP");
- break;
- case USB_CHG_TYPE_BC12_SDP:
- printf(" SDP");
- break;
- case USB_CHG_TYPE_OTHER:
- printf(" Other");
- break;
- case USB_CHG_TYPE_VBUS:
- printf(" VBUS");
- break;
- case USB_CHG_TYPE_UNKNOWN:
- printf(" Unknown");
- break;
- }
- printf(" %dmV / %dmA, max %dmV / %dmA",
- r->meas.voltage_now, r->meas.current_lim, r->meas.voltage_max,
- r->meas.current_max);
- if (r->max_power)
- printf(" / %dmW", r->max_power / 1000);
- printf("\n");
-}
-
-int cmd_usb_pd_mux_info(int argc, char *argv[])
-{
- struct ec_params_usb_pd_mux_info p;
- struct ec_response_usb_pd_mux_info r;
- int num_ports, rv, i;
-
- rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0,
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
- num_ports = ((struct ec_response_usb_pd_ports *)ec_inbuf)->num_ports;
-
- for (i = 0; i < num_ports; i++) {
- p.port = i;
- rv = ec_command(EC_CMD_USB_PD_MUX_INFO, 0,
- &p, sizeof(p),
- &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Port %d: ", i);
- printf("USB=%d ", !!(r.flags & USB_PD_MUX_USB_ENABLED));
- printf("DP=%d ", !!(r.flags & USB_PD_MUX_DP_ENABLED));
- printf("POLARITY=%s ", r.flags & USB_PD_MUX_POLARITY_INVERTED ?
- "INVERTED" : "NORMAL");
- printf("HPD_IRQ=%d ", !!(r.flags & USB_PD_MUX_HPD_IRQ));
- printf("HPD_LVL=%d ", !!(r.flags & USB_PD_MUX_HPD_LVL));
- printf("SAFE=%d ", !!(r.flags & USB_PD_MUX_SAFE_MODE));
- printf("\n");
- }
-
- return 0;
-}
-
-int cmd_usb_pd_power(int argc, char *argv[])
-{
- struct ec_params_usb_pd_power_info p;
- struct ec_response_usb_pd_power_info *r =
- (struct ec_response_usb_pd_power_info *)ec_inbuf;
- int num_ports, i, rv;
- char *e;
-
- rv = ec_command(EC_CMD_USB_PD_PORTS, 0, NULL, 0,
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
- num_ports = ((struct ec_response_usb_pd_ports *)r)->num_ports;
-
- if (argc < 2) {
- for (i = 0; i < num_ports; i++) {
- p.port = i;
- rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0,
- &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- printf("Port %d: ", i);
- print_pd_power_info(r);
- }
- } else {
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
- rv = ec_command(EC_CMD_USB_PD_POWER_INFO, 0,
- &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- printf("Port %d: ", p.port);
- print_pd_power_info(r);
- }
-
- return 0;
-}
-
-int cmd_kbpress(int argc, char *argv[])
-{
- struct ec_params_mkbp_simulate_key p;
- char *e;
- int rv;
-
- if (argc != 4) {
- fprintf(stderr,
- "Usage: %s <row> <col> <0|1>\n", argv[0]);
- return -1;
- }
- p.row = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad row.\n");
- return -1;
- }
- p.col = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad column.\n");
- return -1;
- }
- p.pressed = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad pressed flag.\n");
- return -1;
- }
-
- printf("%s row %d col %d.\n", p.pressed ? "Pressing" : "Releasing",
- p.row,
- p.col);
-
- rv = ec_command(EC_CMD_MKBP_SIMULATE_KEY, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
- printf("Done.\n");
- return 0;
-}
-
-int cmd_keyboard_factory_test(int argc, char *argv[])
-{
- struct ec_response_keyboard_factory_test r;
- int rv;
-
- rv = ec_command(EC_CMD_KEYBOARD_FACTORY_TEST, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.shorted != 0)
- printf("Keyboard %d and %d pin are shorted.\n",
- r.shorted & 0x00ff, r.shorted >> 8);
- else
- printf("Keyboard factory test passed.\n");
-
- return 0;
-}
-
-int cmd_panic_info(int argc, char *argv[])
-{
- int rv;
- struct panic_data *pdata = (struct panic_data *)ec_inbuf;
-
- rv = ec_command(EC_CMD_GET_PANIC_INFO, 0, NULL, 0,
- ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (rv == 0) {
- printf("No panic data.\n");
- return 0;
- }
-
- return parse_panic_info(pdata);
-}
-
-
-int cmd_power_info(int argc, char *argv[])
-{
- struct ec_response_power_info_v1 r;
- int rv;
-
- rv = ec_command(EC_CMD_POWER_INFO, 1, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Power source:\t");
- switch (r.system_power_source) {
- case POWER_SOURCE_UNKNOWN:
- printf("Unknown\n");
- break;
- case POWER_SOURCE_BATTERY:
- printf("Battery\n");
- break;
- case POWER_SOURCE_AC:
- printf("AC\n");
- break;
- case POWER_SOURCE_AC_BATTERY:
- printf("AC + battery\n");
- break;
- }
-
- printf("Battery state-of-charge: %d%%\n", r.battery_soc);
- printf("Max AC power: %d Watts\n", r.ac_adapter_100pct);
- printf("Battery 1Cd rate: %d\n", r.battery_1cd);
- printf("RoP Avg: %d Watts\n", r.rop_avg);
- printf("RoP Peak: %d Watts\n", r.rop_peak);
- printf("Battery DBPT support level: %d\n",
- r.intel.batt_dbpt_support_level);
- printf("Battery DBPT Max Peak Power: %d Watts\n",
- r.intel.batt_dbpt_max_peak_power);
- printf("Battery DBPT Sus Peak Power: %d Watts\n",
- r.intel.batt_dbpt_sus_peak_power);
- return 0;
-}
-
-
-int cmd_pstore_info(int argc, char *argv[])
-{
- struct ec_response_pstore_info r;
- int rv;
-
- rv = ec_command(EC_CMD_PSTORE_INFO, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("PstoreSize %d\nAccessSize %d\n", r.pstore_size, r.access_size);
- return 0;
-}
-
-
-int cmd_pstore_read(int argc, char *argv[])
-{
- struct ec_params_pstore_read p;
- uint8_t rdata[EC_PSTORE_SIZE_MAX];
- int offset, size;
- int rv;
- int i;
- char *e;
- char *buf;
-
- if (argc < 4) {
- fprintf(stderr,
- "Usage: %s <offset> <size> <filename>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > 0x10000) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- size = strtol(argv[2], &e, 0);
- if ((e && *e) || size <= 0 || size > 0x10000) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Reading %d bytes at offset %d...\n", size, offset);
-
- buf = (char *)malloc(size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
-
- /* Read data in chunks */
- for (i = 0; i < size; i += EC_PSTORE_SIZE_MAX) {
- p.offset = offset + i;
- p.size = MIN(size - i, EC_PSTORE_SIZE_MAX);
- rv = ec_command(EC_CMD_PSTORE_READ, 0,
- &p, sizeof(p), rdata, sizeof(rdata));
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- free(buf);
- return rv;
- }
- memcpy(buf + i, rdata, p.size);
- }
-
- rv = write_file(argv[3], buf, size);
- free(buf);
- if (rv)
- return rv;
-
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_pstore_write(int argc, char *argv[])
-{
- struct ec_params_pstore_write p;
- int offset, size;
- int rv;
- int i;
- char *e;
- char *buf;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <offset> <filename>\n", argv[0]);
- return -1;
- }
- offset = strtol(argv[1], &e, 0);
- if ((e && *e) || offset < 0 || offset > 0x10000) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- /* Read the input file */
- buf = read_file(argv[2], &size);
- if (!buf)
- return -1;
-
- printf("Writing to offset %d...\n", offset);
-
- /* Write data in chunks */
- for (i = 0; i < size; i += EC_PSTORE_SIZE_MAX) {
- p.offset = offset + i;
- p.size = MIN(size - i, EC_PSTORE_SIZE_MAX);
- memcpy(p.data, buf + i, p.size);
- rv = ec_command(EC_CMD_PSTORE_WRITE, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Write error at offset %d\n", i);
- free(buf);
- return rv;
- }
- }
-
- free(buf);
- printf("done.\n");
- return 0;
-}
-
-
-int cmd_host_event_get_raw(int argc, char *argv[])
-{
- uint32_t events = read_mapped_mem32(EC_MEMMAP_HOST_EVENTS);
-
- if (events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_INVALID)) {
- printf("Current host events: invalid\n");
- return -1;
- }
-
- printf("Current host events: 0x%08x\n", events);
- return 0;
-}
-
-
-int cmd_host_event_get_b(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_B, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
- if (rv < sizeof(r)) {
- fprintf(stderr, "Insufficient data received.\n");
- return -1;
- }
-
- if (r.mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_INVALID)) {
- printf("Current host events-B: invalid\n");
- return -1;
- }
-
- printf("Current host events-B: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_get_smi_mask(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_SMI_MASK, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current host event SMI mask: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_get_sci_mask(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_SCI_MASK, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current host event SCI mask: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_get_wake_mask(int argc, char *argv[])
-{
- struct ec_response_host_event_mask r;
- int rv;
-
- rv = ec_command(EC_CMD_HOST_EVENT_GET_WAKE_MASK, 0,
- NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current host event wake mask: 0x%08x\n", r.mask);
- return 0;
-}
-
-
-int cmd_host_event_set_smi_mask(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_SET_SMI_MASK, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Mask set.\n");
- return 0;
-}
-
-
-int cmd_host_event_set_sci_mask(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_SET_SCI_MASK, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Mask set.\n");
- return 0;
-}
-
-
-int cmd_host_event_set_wake_mask(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_SET_WAKE_MASK, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Mask set.\n");
- return 0;
-}
-
-
-int cmd_host_event_clear(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_CLEAR, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Host events cleared.\n");
- return 0;
-}
-
-
-int cmd_host_event_clear_b(int argc, char *argv[])
-{
- struct ec_params_host_event_mask p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <mask>\n", argv[0]);
- return -1;
- }
- p.mask = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_HOST_EVENT_CLEAR_B, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Host events-B cleared.\n");
- return 0;
-}
-
-
-int cmd_switches(int argc, char *argv[])
-{
- uint8_t s = read_mapped_mem8(EC_MEMMAP_SWITCHES);
- printf("Current switches: 0x%02x\n", s);
- printf("Lid switch: %s\n",
- (s & EC_SWITCH_LID_OPEN ? "OPEN" : "CLOSED"));
- printf("Power button: %s\n",
- (s & EC_SWITCH_POWER_BUTTON_PRESSED ? "DOWN" : "UP"));
- printf("Write protect: %sABLED\n",
- (s & EC_SWITCH_WRITE_PROTECT_DISABLED ? "DIS" : "EN"));
- printf("Dedicated recovery: %sABLED\n",
- (s & EC_SWITCH_DEDICATED_RECOVERY ? "EN" : "DIS"));
-
- return 0;
-}
-
-
-int cmd_wireless(int argc, char *argv[])
-{
- char *e;
- int rv;
- int now_flags;
-
- if (argc < 2) {
- fprintf(stderr,
- "Usage: %s <flags> [<mask> [<susflags> <susmask>]]\n",
- argv[0]);
- fprintf(stderr, " 0x1 = WLAN radio\n"
- " 0x2 = Bluetooth radio\n"
- " 0x4 = WWAN power\n"
- " 0x8 = WLAN power\n");
- return -1;
- }
-
- now_flags = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flags.\n");
- return -1;
- }
-
- if (argc < 3) {
- /* Old-style - current flags only */
- struct ec_params_switch_enable_wireless_v0 p;
-
- p.enabled = now_flags;
- rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Success.\n");
- } else {
- /* New-style - masks and suspend flags */
- struct ec_params_switch_enable_wireless_v1 p;
- struct ec_response_switch_enable_wireless_v1 r;
-
- memset(&p, 0, sizeof(p));
-
- p.now_flags = now_flags;
-
- p.now_mask = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask.\n");
- return -1;
- }
-
- if (argc > 4) {
- p.suspend_flags = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad suspend flags.\n");
- return -1;
- }
-
- p.suspend_mask = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad suspend mask.\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_SWITCH_ENABLE_WIRELESS,
- EC_VER_SWITCH_ENABLE_WIRELESS,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Now=0x%x, suspend=0x%x\n",
- r.now_flags, r.suspend_flags);
- }
-
- return 0;
-}
-
-
-int cmd_i2c_protect(int argc, char *argv[])
-{
- struct ec_params_i2c_passthru_protect p;
- char *e;
- int rv;
-
- if (argc != 2 && (argc != 3 || strcmp(argv[2], "status"))) {
- fprintf(stderr, "Usage: %s <port> [status]\n",
- argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- if (argc == 3) {
- struct ec_response_i2c_passthru_protect r;
-
- p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_STATUS;
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
- &r, sizeof(r));
-
- if (rv < 0)
- return rv;
-
- printf("I2C port %d: %s (%d)\n", p.port,
- r.status ? "Protected" : "Unprotected", r.status);
- } else {
- p.subcmd = EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE;
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU_PROTECT, 0, &p, sizeof(p),
- NULL, 0);
-
- if (rv < 0)
- return rv;
- }
- return 0;
-}
-
-
-int do_i2c_xfer(unsigned int port, unsigned int addr,
- uint8_t *write_buf, int write_len,
- uint8_t **read_buf, int read_len) {
- struct ec_params_i2c_passthru *p =
- (struct ec_params_i2c_passthru *)ec_outbuf;
- struct ec_response_i2c_passthru *r =
- (struct ec_response_i2c_passthru *)ec_inbuf;
- struct ec_params_i2c_passthru_msg *msg = p->msg;
- uint8_t *pdata;
- int size;
- int rv;
-
- p->port = port;
- p->num_msgs = (read_len != 0) + (write_len != 0);
-
- size = sizeof(*p) + p->num_msgs * sizeof(*msg);
- if (size + write_len > ec_max_outsize) {
- fprintf(stderr, "Params too large for buffer\n");
- return -1;
- }
- if (sizeof(*r) + read_len > ec_max_insize) {
- fprintf(stderr, "Read length too big for buffer\n");
- return -1;
- }
-
- pdata = (uint8_t *)p + size;
- if (write_len) {
- msg->addr_flags = addr;
- msg->len = write_len;
-
- memcpy(pdata, write_buf, write_len);
- msg++;
- }
-
- if (read_len) {
- msg->addr_flags = addr | EC_I2C_FLAG_READ;
- msg->len = read_len;
- }
-
- rv = ec_command(EC_CMD_I2C_PASSTHRU, 0, p, size + write_len,
- r, sizeof(*r) + read_len);
- if (rv < 0)
- return rv;
-
- /* Parse response */
- if (r->i2c_status & (EC_I2C_STATUS_NAK | EC_I2C_STATUS_TIMEOUT)) {
- fprintf(stderr, "Transfer failed with status=0x%x\n",
- r->i2c_status);
- return -1;
- }
-
- if (rv < sizeof(*r) + read_len) {
- fprintf(stderr, "Truncated read response\n");
- return -1;
- }
-
- if (read_len)
- *read_buf = r->data;
-
- return 0;
-}
-
-static void cmd_i2c_help(void)
-{
- fprintf(stderr,
- " Usage: i2cread <8 | 16> <port> <addr8> <offset>\n"
- " Usage: i2cwrite <8 | 16> <port> <addr8> <offset> <data>\n"
- " Usage: i2cxfer <port> <addr7> <read_count> [bytes...]\n"
- " <port> i2c port number\n"
- " <addr8> 8-bit i2c address\n"
- " <addr7> 7-bit i2c address\n"
- " <offset> offset to read from or write to\n"
- " <data> data to write\n"
- " <read_count> number of bytes to read\n"
- " [bytes ...] data to write\n"
- );
-
-}
-
-int cmd_i2c_read(int argc, char *argv[])
-{
- unsigned int port, addr;
- int read_len, write_len;
- uint8_t write_buf[1];
- uint8_t *read_buf = NULL;
- char *e;
- int rv;
-
- if (argc != 5) {
- cmd_i2c_help();
- return -1;
- }
-
- read_len = strtol(argv[1], &e, 0);
- if ((e && *e) || (read_len != 8 && read_len != 16)) {
- fprintf(stderr, "Bad read size.\n");
- return -1;
- }
- read_len = read_len / 8;
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad address.\n");
- return -1;
- }
- /* Convert from 8-bit to 7-bit address */
- addr = addr >> 1;
-
- write_buf[0] = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- write_len = 1;
-
- rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len);
-
- if (rv < 0)
- return rv;
-
- printf("Read from I2C port %d at 0x%x offset 0x%x = 0x%x\n",
- port, addr, write_buf[0], *(uint16_t *)read_buf);
- return 0;
-}
-
-
-int cmd_i2c_write(int argc, char *argv[])
-{
- unsigned int port, addr;
- int write_len;
- uint8_t write_buf[3];
- char *e;
- int rv;
-
- if (argc != 6) {
- cmd_i2c_help();
- return -1;
- }
-
- write_len = strtol(argv[1], &e, 0);
- if ((e && *e) || (write_len != 8 && write_len != 16)) {
- fprintf(stderr, "Bad write size.\n");
- return -1;
- }
- /* Include offset (length 1) */
- write_len = 1 + write_len / 8;
-
- port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad address.\n");
- return -1;
- }
- /* Convert from 8-bit to 7-bit address */
- addr = addr >> 1;
-
- write_buf[0] = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
-
- *((uint16_t *)&write_buf[1]) = strtol(argv[5], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad data.\n");
- return -1;
- }
-
- rv = do_i2c_xfer(port, addr, write_buf, write_len, NULL, 0);
-
- if (rv < 0)
- return rv;
-
- printf("Wrote 0x%x to I2C port %d at 0x%x offset 0x%x.\n",
- *((uint16_t *)&write_buf[1]), port, addr, write_buf[0]);
- return 0;
-}
-
-int cmd_i2c_xfer(int argc, char *argv[])
-{
- unsigned int port, addr;
- int read_len, write_len;
- uint8_t *write_buf = NULL;
- uint8_t *read_buf;
- char *e;
- int rv, i;
-
- if (argc < 4) {
- cmd_i2c_help();
- return -1;
- }
-
- port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port.\n");
- return -1;
- }
-
- addr = strtol(argv[2], &e, 0) & 0x7f;
- if (e && *e) {
- fprintf(stderr, "Bad slave address.\n");
- return -1;
- }
-
- read_len = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad read length.\n");
- return -1;
- }
-
- /* Skip over params to bytes to write */
- argc -= 4;
- argv += 4;
- write_len = argc;
-
- if (write_len) {
- write_buf = malloc(write_len);
- if (write_buf == NULL)
- return -1;
- for (i = 0; i < write_len; i++) {
- write_buf[i] = strtol(argv[i], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad write byte %d\n", i);
- free(write_buf);
- return -1;
- }
- }
- }
-
- rv = do_i2c_xfer(port, addr, write_buf, write_len, &read_buf, read_len);
-
- if (write_len)
- free(write_buf);
-
- if (rv)
- return rv;
-
- if (read_len) {
- if (ascii_mode) {
- for (i = 0; i < read_len; i++)
- printf(isprint(read_buf[i]) ? "%c" : "\\x%02x",
- read_buf[i]);
- } else {
- printf("Read bytes:");
- for (i = 0; i < read_len; i++)
- printf(" %#02x", read_buf[i]);
- }
- printf("\n");
- } else {
- printf("Write successful.\n");
- }
-
- return 0;
-}
-
-static void cmd_locate_chip_help(const char *const cmd)
-{
- fprintf(stderr,
- "Usage: %s <type> <index>\n"
- " <type> is one of:\n"
- " 0: CBI_EEPROM\n"
- " 1: TCPCs\n"
- " <index> instance # of <type>\n",
- cmd);
-}
-
-static const char *bus_type[] = {
- "I2C",
- "EMBEDDED"
-};
-
-int cmd_locate_chip(int argc, char *argv[])
-{
- struct ec_params_locate_chip p;
- struct ec_response_locate_chip r = {0};
- char *e;
- int rv;
-
- if (argc != 3) {
- cmd_locate_chip_help(argv[0]);
- return -1;
- }
-
- p.type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad type.\n");
- cmd_locate_chip_help(argv[0]);
- return -1;
- }
-
- p.index = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad index.\n");
- cmd_locate_chip_help(argv[0]);
- return -1;
- }
-
- rv = ec_command(EC_CMD_LOCATE_CHIP, 0, &p, sizeof(p), &r, sizeof(r));
-
- if (rv == -EC_RES_INVALID_PARAM - EECRESULT) {
- fprintf(stderr, "Bus type %d not supported.\n", p.type);
- return rv;
- }
-
- if (rv == -EC_RES_UNAVAILABLE - EECRESULT) {
- fprintf(stderr, "Chip not found\n");
- return rv;
- }
-
- if (rv == -EC_RES_OVERFLOW - EECRESULT) {
- fprintf(stderr, "Index too large\n");
- return rv;
- }
-
- if (rv < 0)
- return rv;
-
- if (r.bus_type >= EC_BUS_TYPE_COUNT
- || r.bus_type >= ARRAY_SIZE(bus_type)) {
- fprintf(stderr, "Unknown bus type (%d)\n", r.bus_type);
- return -1;
- }
-
- /*
- * When changing the format of this print, make sure FAFT
- * (firmware_ECCbiEeprom) still passes. It may silently skip the test.
- */
- printf("Bus: %s; Port: %d; Address: 0x%02x (7-bit format)\n",
- bus_type[r.bus_type], r.i2c_info.port,
- I2C_GET_ADDR(r.i2c_info.addr_flags));
-
- printf("reserved: 0x%x\n", r.reserved);
-
- return 0;
-}
-
-int cmd_lcd_backlight(int argc, char *argv[])
-{
- struct ec_params_switch_enable_backlight p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <0|1>\n", argv[0]);
- return -1;
- }
- p.enabled = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_SWITCH_ENABLE_BKLIGHT, 0,
- &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Success.\n");
- return 0;
-}
-
-
-int cmd_ext_power_limit(int argc, char *argv[])
-{
- /* Version 1 is used, no support for obsolete version 0 */
- struct ec_params_external_power_limit_v1 p;
- char *e;
-
- if (argc != 3) {
- fprintf(stderr,
- "Usage: %s <max_current_mA> <max_voltage_mV>\n",
- argv[0]);
- return -1;
- }
-
- p.current_lim = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param1.\n");
- return -1;
- }
-
- p.voltage_lim = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param2.\n");
- return -1;
- }
-
- /* Send version 1 of command */
- return ec_command(EC_CMD_EXTERNAL_POWER_LIMIT, 1, &p, sizeof(p),
- NULL, 0);
-}
-
-
-int cmd_charge_current_limit(int argc, char *argv[])
-{
- struct ec_params_current_limit p;
- int rv;
- char *e;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <max_current_mA>\n", argv[0]);
- return -1;
- }
-
- p.limit = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_CHARGE_CURRENT_LIMIT, 0, &p, sizeof(p),
- NULL, 0);
- return rv;
-}
-
-
-int cmd_charge_control(int argc, char *argv[])
-{
- struct ec_params_charge_control p;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <normal | idle | discharge>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "normal")) {
- p.mode = CHARGE_CONTROL_NORMAL;
- } else if (!strcasecmp(argv[1], "idle")) {
- p.mode = CHARGE_CONTROL_IDLE;
- } else if (!strcasecmp(argv[1], "discharge")) {
- p.mode = CHARGE_CONTROL_DISCHARGE;
- } else {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_CHARGE_CONTROL, 1, &p, sizeof(p), NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Is AC connected?\n");
- return rv;
- }
-
- switch (p.mode) {
- case CHARGE_CONTROL_NORMAL:
- printf("Charge state machine normal mode.\n");
- break;
- case CHARGE_CONTROL_IDLE:
- printf("Charge state machine force idle.\n");
- break;
- case CHARGE_CONTROL_DISCHARGE:
- printf("Charge state machine force discharge.\n");
- break;
- default:
- break;
- }
- return 0;
-}
-
-
-#define ST_CMD_SIZE ST_FLD_SIZE(ec_params_charge_state, cmd)
-#define ST_PRM_SIZE(SUBCMD) \
- (ST_CMD_SIZE + ST_FLD_SIZE(ec_params_charge_state, SUBCMD))
-#define ST_RSP_SIZE(SUBCMD) ST_FLD_SIZE(ec_response_charge_state, SUBCMD)
-
-/* Table of subcommand sizes for EC_CMD_CHARGE_STATE */
-static const struct {
- uint8_t to_ec_size;
- uint8_t from_ec_size;
-} cs_paramcount[] = {
- /* Order must match enum charge_state_command */
- { ST_CMD_SIZE, ST_RSP_SIZE(get_state) },
- { ST_PRM_SIZE(get_param), ST_RSP_SIZE(get_param) },
- { ST_PRM_SIZE(set_param), 0},
-};
-BUILD_ASSERT(ARRAY_SIZE(cs_paramcount) == CHARGE_STATE_NUM_CMDS);
-
-#undef ST_CMD_SIZE
-#undef ST_PRM_SIZE
-#undef ST_RSP_SIZE
-
-static int cs_do_cmd(struct ec_params_charge_state *to_ec,
- struct ec_response_charge_state *from_ec)
-{
- int rv;
- int cmd = to_ec->cmd;
-
- rv = ec_command(EC_CMD_CHARGE_STATE, 0,
- to_ec, cs_paramcount[cmd].to_ec_size,
- from_ec, cs_paramcount[cmd].from_ec_size);
-
- return (rv < 0 ? 1 : 0);
-}
-
-static const char * const base_params[] = {
- "chg_voltage",
- "chg_current",
- "chg_input_current",
- "chg_status",
- "chg_option",
- "limit_power",
-};
-BUILD_ASSERT(ARRAY_SIZE(base_params) == CS_NUM_BASE_PARAMS);
-
-static int cmd_charge_state(int argc, char **argv)
-{
- struct ec_params_charge_state param;
- struct ec_response_charge_state resp;
- uint32_t p, v;
- int i, r;
- char *e;
-
- if (argc > 1 && !strcasecmp(argv[1], "show")) {
- param.cmd = CHARGE_STATE_CMD_GET_STATE;
- r = cs_do_cmd(&param, &resp);
- if (r)
- return r;
- printf("ac = %d\n", resp.get_state.ac);
- printf("chg_voltage = %dmV\n", resp.get_state.chg_voltage);
- printf("chg_current = %dmA\n", resp.get_state.chg_current);
- printf("chg_input_current = %dmA\n",
- resp.get_state.chg_input_current);
- printf("batt_state_of_charge = %d%%\n",
- resp.get_state.batt_state_of_charge);
- return 0;
- }
-
- if (argc > 1 && !strcasecmp(argv[1], "param")) {
- switch (argc) {
- case 3:
- if (!strcasecmp(argv[2], "help"))
- break;
- param.cmd = CHARGE_STATE_CMD_GET_PARAM;
- p = strtoul(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param: %s\n", argv[2]);
- return -1;
- }
- param.get_param.param = p;
- r = cs_do_cmd(&param, &resp);
- if (r)
- return r;
- v = resp.get_param.value;
- if (p < CS_NUM_BASE_PARAMS)
- printf("%d (0x%x) # %s\n", v, v,
- base_params[p]);
- else
- printf("%d (0x%x)\n", v, v);
- return 0;
- case 4:
- param.cmd = CHARGE_STATE_CMD_SET_PARAM;
- p = strtoul(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad param: %s\n", argv[2]);
- return -1;
- }
- v = strtoul(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value: %s\n", argv[3]);
- return -1;
- }
- param.set_param.param = p;
- param.set_param.value = v;
- return cs_do_cmd(&param, &resp);
- }
-
- printf("base params:\n");
- for (i = 0; i < CS_NUM_BASE_PARAMS; i++)
- printf(" %d %s\n", i, base_params[i]);
- printf("custom profile params:\n");
- printf(" 0x%x - 0x%x\n", CS_PARAM_CUSTOM_PROFILE_MIN,
- CS_PARAM_CUSTOM_PROFILE_MAX);
-
- return 0;
- }
-
- printf("Usage:\n");
- printf(" %s show - show current state\n", argv[0]);
- printf(" %s param NUM [VALUE] - get/set param NUM\n", argv[0]);
- printf(" %s param help - show known param NUMs\n", argv[0]);
- return 0;
-}
-
-int cmd_gpio_get(int argc, char *argv[])
-{
- struct ec_params_gpio_get_v1 p_v1;
- struct ec_response_gpio_get_v1 r_v1;
- int i, rv, subcmd, num_gpios;
- int cmdver = 1;
-
- if (!ec_cmd_version_supported(EC_CMD_GPIO_GET, cmdver)) {
- struct ec_params_gpio_get p;
- struct ec_response_gpio_get r;
-
- /* Fall back to version 0 command */
- cmdver = 0;
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <GPIO name>\n", argv[0]);
- return -1;
- }
-
- if (strlen(argv[1]) + 1 > sizeof(p.name)) {
- fprintf(stderr, "GPIO name too long.\n");
- return -1;
- }
- strcpy(p.name, argv[1]);
-
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p,
- sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("GPIO %s = %d\n", p.name, r.val);
- return 0;
- }
-
- if (argc > 2 || (argc == 2 && !strcmp(argv[1], "help"))) {
- printf("Usage: %s [<subcmd> <GPIO name>]\n", argv[0]);
- printf("'gpioget <GPIO_NAME>' - Get value by name\n");
- printf("'gpioget count' - Get count of GPIOS\n");
- printf("'gpioget all' - Get info for all GPIOs\n");
- return -1;
- }
-
- /* Keeping it consistent with console command behavior */
- if (argc == 1)
- subcmd = EC_GPIO_GET_INFO;
- else if (!strcmp(argv[1], "count"))
- subcmd = EC_GPIO_GET_COUNT;
- else if (!strcmp(argv[1], "all"))
- subcmd = EC_GPIO_GET_INFO;
- else
- subcmd = EC_GPIO_GET_BY_NAME;
-
- if (subcmd == EC_GPIO_GET_BY_NAME) {
- p_v1.subcmd = EC_GPIO_GET_BY_NAME;
- if (strlen(argv[1]) + 1 > sizeof(p_v1.get_value_by_name.name)) {
- fprintf(stderr, "GPIO name too long.\n");
- return -1;
- }
- strcpy(p_v1.get_value_by_name.name, argv[1]);
-
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1,
- sizeof(p_v1), &r_v1, sizeof(r_v1));
-
- if (rv < 0)
- return rv;
-
- printf("GPIO %s = %d\n", p_v1.get_value_by_name.name,
- r_v1.get_value_by_name.val);
- return 0;
- }
-
- /* Need GPIO count for EC_GPIO_GET_COUNT or EC_GPIO_GET_INFO */
- p_v1.subcmd = EC_GPIO_GET_COUNT;
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1,
- sizeof(p_v1), &r_v1, sizeof(r_v1));
- if (rv < 0)
- return rv;
-
- if (subcmd == EC_GPIO_GET_COUNT) {
- printf("GPIO COUNT = %d\n", r_v1.get_count.val);
- return 0;
- }
-
- /* subcmd EC_GPIO_GET_INFO */
- num_gpios = r_v1.get_count.val;
- p_v1.subcmd = EC_GPIO_GET_INFO;
-
- for (i = 0; i < num_gpios; i++) {
- p_v1.get_info.index = i;
-
- rv = ec_command(EC_CMD_GPIO_GET, cmdver, &p_v1,
- sizeof(p_v1), &r_v1, sizeof(r_v1));
- if (rv < 0)
- return rv;
-
- printf("%2d %-32s 0x%04X\n", r_v1.get_info.val,
- r_v1.get_info.name, r_v1.get_info.flags);
- }
-
- return 0;
-}
-
-
-int cmd_gpio_set(int argc, char *argv[])
-{
- struct ec_params_gpio_set p;
- char *e;
- int rv;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <GPIO name> <0 | 1>\n", argv[0]);
- return -1;
- }
-
- if (strlen(argv[1]) + 1 > sizeof(p.name)) {
- fprintf(stderr, "GPIO name too long.\n");
- return -1;
- }
- strcpy(p.name, argv[1]);
-
- p.val = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_GPIO_SET, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("GPIO %s set to %d\n", p.name, p.val);
- return 0;
-}
-
-void print_battery_flags(int flags)
-{
- printf(" Flags 0x%02x", flags);
- if (flags & EC_BATT_FLAG_AC_PRESENT)
- printf(" AC_PRESENT");
- if (flags & EC_BATT_FLAG_BATT_PRESENT)
- printf(" BATT_PRESENT");
- if (flags & EC_BATT_FLAG_DISCHARGING)
- printf(" DISCHARGING");
- if (flags & EC_BATT_FLAG_CHARGING)
- printf(" CHARGING");
- if (flags & EC_BATT_FLAG_LEVEL_CRITICAL)
- printf(" LEVEL_CRITICAL");
- printf("\n");
-}
-
-int get_battery_command(int index)
-{
- struct ec_params_battery_static_info static_p;
- struct ec_response_battery_static_info static_r;
- struct ec_params_battery_dynamic_info dynamic_p;
- struct ec_response_battery_dynamic_info dynamic_r;
- int rv;
-
- printf("Battery %d info:\n", index);
-
- static_p.index = index;
- rv = ec_command(EC_CMD_BATTERY_GET_STATIC, 0,
- &static_p, sizeof(static_p),
- &static_r, sizeof(static_r));
- if (rv < 0)
- return -1;
-
- dynamic_p.index = index;
- rv = ec_command(EC_CMD_BATTERY_GET_DYNAMIC, 0,
- &dynamic_p, sizeof(dynamic_p),
- &dynamic_r, sizeof(dynamic_r));
- if (rv < 0)
- return -1;
-
- if (dynamic_r.flags & EC_BATT_FLAG_INVALID_DATA) {
- printf(" Invalid data (not present?)\n");
- return -1;
- }
-
- if (!is_string_printable(static_r.manufacturer))
- goto cmd_error;
- printf(" OEM name: %s\n", static_r.manufacturer);
-
- if (!is_string_printable(static_r.model))
- goto cmd_error;
- printf(" Model number: %s\n", static_r.model);
-
- if (!is_string_printable(static_r.type))
- goto cmd_error;
- printf(" Chemistry : %s\n", static_r.type);
-
- if (!is_string_printable(static_r.serial))
- goto cmd_error;
- printf(" Serial number: %s\n", static_r.serial);
-
- if (!is_battery_range(static_r.design_capacity))
- goto cmd_error;
- printf(" Design capacity: %u mAh\n", static_r.design_capacity);
-
- if (!is_battery_range(dynamic_r.full_capacity))
- goto cmd_error;
- printf(" Last full charge: %u mAh\n", dynamic_r.full_capacity);
-
- if (!is_battery_range(static_r.design_voltage))
- goto cmd_error;
- printf(" Design output voltage %u mV\n", static_r.design_voltage);
-
- if (!is_battery_range(static_r.cycle_count))
- goto cmd_error;
- printf(" Cycle count %u\n", static_r.cycle_count);
-
- if (!is_battery_range(dynamic_r.actual_voltage))
- goto cmd_error;
- printf(" Present voltage %u mV\n", dynamic_r.actual_voltage);
-
- /* current can be negative */
- printf(" Present current %d mA\n", dynamic_r.actual_current);
-
- if (!is_battery_range(dynamic_r.remaining_capacity))
- goto cmd_error;
- printf(" Remaining capacity %u mAh\n",
- dynamic_r.remaining_capacity);
-
- if (!is_battery_range(dynamic_r.desired_voltage))
- goto cmd_error;
- printf(" Desired voltage %u mV\n", dynamic_r.desired_voltage);
-
- if (!is_battery_range(dynamic_r.desired_current))
- goto cmd_error;
- printf(" Desired current %u mA\n", dynamic_r.desired_current);
-
- print_battery_flags(dynamic_r.flags);
- return 0;
-
-cmd_error:
- fprintf(stderr, "Bad battery info value.\n");
- return -1;
-}
-
-int cmd_battery(int argc, char *argv[])
-{
- char batt_text[EC_MEMMAP_TEXT_MAX];
- int rv, val;
- char *e;
- int index = 0;
-
- if (argc > 2) {
- fprintf(stderr, "Usage: %s [index]\n", argv[0]);
- return -1;
- } else if (argc == 2) {
- index = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad battery index.\n");
- return -1;
- }
-
- if (index > 0)
- return get_battery_command(index);
- }
-
- /*
- * TODO(b:65697620): When supported/required, read battery 0 information
- * through EC commands as well.
- */
-
- val = read_mapped_mem8(EC_MEMMAP_BATTERY_VERSION);
- if (val < 1) {
- fprintf(stderr, "Battery version %d is not supported\n", val);
- return -1;
- }
-
- printf("Battery info:\n");
-
- rv = read_mapped_string(EC_MEMMAP_BATT_MFGR, batt_text,
- sizeof(batt_text));
- if (rv < 0 || !is_string_printable(batt_text))
- goto cmd_error;
- printf(" OEM name: %s\n", batt_text);
-
- rv = read_mapped_string(EC_MEMMAP_BATT_MODEL, batt_text,
- sizeof(batt_text));
- if (rv < 0 || !is_string_printable(batt_text))
- goto cmd_error;
- printf(" Model number: %s\n", batt_text);
-
- rv = read_mapped_string(EC_MEMMAP_BATT_TYPE, batt_text,
- sizeof(batt_text));
- if (rv < 0 || !is_string_printable(batt_text))
- goto cmd_error;
- printf(" Chemistry : %s\n", batt_text);
-
- rv = read_mapped_string(EC_MEMMAP_BATT_SERIAL, batt_text,
- sizeof(batt_text));
- printf(" Serial number: %s\n", batt_text);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_DCAP);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Design capacity: %u mAh\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_LFCC);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Last full charge: %u mAh\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_DVLT);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Design output voltage %u mV\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_CCNT);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Cycle count %u\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_VOLT);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Present voltage %u mV\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_RATE);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Present current %u mA\n", val);
-
- val = read_mapped_mem32(EC_MEMMAP_BATT_CAP);
- if (!is_battery_range(val))
- goto cmd_error;
- printf(" Remaining capacity %u mAh\n", val);
-
- val = read_mapped_mem8(EC_MEMMAP_BATT_FLAG);
- print_battery_flags(val);
-
- return 0;
-cmd_error:
- fprintf(stderr, "Bad battery info value. Check protocol version.\n");
- return -1;
-}
-
-int cmd_battery_cut_off(int argc, char *argv[])
-{
- struct ec_params_battery_cutoff p;
- int cmd_version;
- int rv;
-
- memset(&p, 0, sizeof(p));
- if (ec_cmd_version_supported(EC_CMD_BATTERY_CUT_OFF, 1)) {
- cmd_version = 1;
- if (argc > 1) {
- if (!strcasecmp(argv[1], "at-shutdown")) {
- p.flags = EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN;
- } else {
- fprintf(stderr, "Bad parameter: %s\n", argv[1]);
- return -1;
- }
- }
- } else {
- /* Fall back to version 0 command */
- cmd_version = 0;
- if (argc > 1) {
- if (!strcasecmp(argv[1], "at-shutdown")) {
- fprintf(stderr, "Explicit 'at-shutdown' ");
- fprintf(stderr, "parameter not supported.\n");
- } else {
- fprintf(stderr, "Bad parameter: %s\n", argv[1]);
- }
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_BATTERY_CUT_OFF, cmd_version, &p, sizeof(p),
- NULL, 0);
- rv = (rv < 0 ? rv : 0);
-
- if (rv < 0) {
- fprintf(stderr, "Failed to cut off battery, rv=%d\n", rv);
- fprintf(stderr, "It is expected if the rv is -%d "
- "(EC_RES_INVALID_COMMAND) if the battery "
- "doesn't support cut-off function.\n",
- EC_RES_INVALID_COMMAND);
- } else {
- printf("\n");
- printf("SUCCESS. The battery has arranged a cut-off.\n");
-
- if (cmd_version == 1 &&
- (p.flags & EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN))
- printf("The battery will be cut off after shutdown.\n");
- else
- printf("The system should be shutdown immediately.\n");
-
- printf("\n");
- }
- return rv;
-}
-
-int cmd_battery_vendor_param(int argc, char *argv[])
-{
- struct ec_params_battery_vendor_param p;
- struct ec_response_battery_vendor_param r;
- char *e;
- int rv;
-
- if (argc < 3)
- goto cmd_battery_vendor_param_usage;
-
- if (!strcasecmp(argv[1], "get"))
- p.mode = BATTERY_VENDOR_PARAM_MODE_GET;
- else if (!strcasecmp(argv[1], "set"))
- p.mode = BATTERY_VENDOR_PARAM_MODE_SET;
- else
- goto cmd_battery_vendor_param_usage;
-
- p.param = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Invalid param.\n");
- goto cmd_battery_vendor_param_usage;
- }
-
- if (p.mode == BATTERY_VENDOR_PARAM_MODE_SET) {
- if (argc != 4) {
- fprintf(stderr, "Missing value.\n");
- goto cmd_battery_vendor_param_usage;
- }
-
- p.value = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Invalid value.\n");
- goto cmd_battery_vendor_param_usage;
- }
- }
-
- rv = ec_command(EC_CMD_BATTERY_VENDOR_PARAM, 0, &p, sizeof(p),
- &r, sizeof(r));
-
- if (rv < 0)
- return rv;
-
- printf("0x%08x\n", r.value);
-
- return 0;
-
-cmd_battery_vendor_param_usage:
- fprintf(stderr,
- "Usage:\t %s get <param>\n"
- "\t %s set <param> <value>\n",
- argv[0], argv[0]);
- return -1;
-}
-
-int cmd_board_version(int argc, char *argv[])
-{
- struct ec_response_board_version response;
- int rv;
-
- rv = ec_command(EC_CMD_GET_BOARD_VERSION, 0, NULL, 0, &response,
- sizeof(response));
- if (rv < 0)
- return rv;
-
- printf("%d\n", response.board_version);
- return rv;
-}
-
-static void cmd_cbi_help(char *cmd)
-{
- fprintf(stderr,
- " Usage: %s get <tag> [get_flag]\n"
- " Usage: %s set <tag> <value/string> <size> [set_flag]\n"
- " <tag> is one of:\n"
- " 0: BOARD_VERSION\n"
- " 1: OEM_ID\n"
- " 2: SKU_ID\n"
- " 3: DRAM_PART_NUM (string)\n"
- " 4: OEM_NAME (string)\n"
- " 5: MODEL_ID\n"
- " <size> is the size of the data in byte. It should be zero for\n"
- " string types.\n"
- " <value/string> is an integer or a string to be set\n"
- " [get_flag] is combination of:\n"
- " 01b: Invalidate cache and reload data from EEPROM\n"
- " [set_flag] is combination of:\n"
- " 01b: Skip write to EEPROM. Use for back-to-back writes\n"
- " 10b: Set all fields to defaults first\n", cmd, cmd);
-}
-
-static int cmd_cbi_is_string_field(enum cbi_data_tag tag)
-{
- return tag == CBI_TAG_DRAM_PART_NUM || tag == CBI_TAG_OEM_NAME;
-}
-
-/*
- * Write value to CBI
- *
- * TODO: Support asynchronous write
- */
-static int cmd_cbi(int argc, char *argv[])
-{
- enum cbi_data_tag tag;
- char *e;
- int rv;
-
- if (argc < 3) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cbi_help(argv[0]);
- return -1;
- }
-
- /* Tag */
- tag = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad tag\n");
- return -1;
- }
-
- if (!strcasecmp(argv[1], "get")) {
- struct ec_params_get_cbi p = { 0 };
- uint8_t *r;
- int i;
- p.tag = tag;
- if (argc > 3) {
- p.flag = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flag\n");
- return -1;
- }
- }
- rv = ec_command(EC_CMD_GET_CROS_BOARD_INFO, 0, &p, sizeof(p),
- ec_inbuf, ec_max_insize);
- if (rv < 0) {
- fprintf(stderr, "Error code: %d\n", rv);
- return rv;
- }
- if (rv < sizeof(uint8_t)) {
- fprintf(stderr, "Invalid size: %d\n", rv);
- return -1;
- }
- r = ec_inbuf;
- if (cmd_cbi_is_string_field(tag)) {
- printf("%.*s", rv, (const char *)r);
- } else {
- if (rv <= sizeof(uint32_t))
- printf("As integer: %u (0x%x)\n", r[0], r[0]);
- printf("As binary:");
- for (i = 0; i < rv; i++) {
- if (i % 32 == 31)
- printf("\n");
- printf(" %02x", r[i]);
- }
- }
- printf("\n");
- return 0;
- } else if (!strcasecmp(argv[1], "set")) {
- struct ec_params_set_cbi *p =
- (struct ec_params_set_cbi *)ec_outbuf;
- void *val_ptr;
- uint32_t val;
- uint8_t size;
- if (argc < 5) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cbi_help(argv[0]);
- return -1;
- }
- memset(p, 0, ec_max_outsize);
- p->tag = tag;
-
- if (cmd_cbi_is_string_field(tag)) {
- val_ptr = argv[3];
- size = strlen(val_ptr) + 1;
- } else {
- val = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value\n");
- return -1;
- }
- size = strtol(argv[4], &e, 0);
- if ((e && *e) || size < 1 || 4 < size ||
- val >= (1ull << size*8)) {
- fprintf(stderr, "Bad size: %d\n", size);
- return -1;
- }
- val_ptr = &val;
- }
-
- if (size > ec_max_outsize - sizeof(*p)) {
- fprintf(stderr, "Size exceeds parameter buffer: %d\n",
- size);
- return -1;
- }
- /* Little endian */
- memcpy(p->data, val_ptr, size);
- p->size = size;
- if (argc > 5) {
- p->flag = strtol(argv[5], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flag\n");
- return -1;
- }
- }
- rv = ec_command(EC_CMD_SET_CROS_BOARD_INFO, 0,
- p, sizeof(*p) + size, NULL, 0);
- if (rv < 0) {
- if (rv == -EC_RES_ACCESS_DENIED - EECRESULT)
- fprintf(stderr, "Write-protect is enabled or "
- "EC explicitly refused to change the "
- "requested field.\n");
- else
- fprintf(stderr, "Error code: %d\n", rv);
- return rv;
- }
- return 0;
- }
-
- fprintf(stderr, "Invalid sub command: %s\n", argv[1]);
- cmd_cbi_help(argv[0]);
-
- return -1;
-}
-
-int cmd_chipinfo(int argc, char *argv[])
-{
- struct ec_response_get_chip_info info;
- int rv;
-
- printf("Chip info:\n");
-
- rv = ec_command(EC_CMD_GET_CHIP_INFO, 0, NULL, 0, &info, sizeof(info));
- if (rv < 0)
- return rv;
- printf(" vendor: %s\n", info.vendor);
- printf(" name: %s\n", info.name);
- printf(" revision: %s\n", info.revision);
-
- return 0;
-}
-
-int cmd_proto_info(int argc, char *argv[])
-{
- struct ec_response_get_protocol_info info;
- int rv;
- int i;
-
- printf("Protocol info:\n");
-
- rv = ec_command(EC_CMD_GET_PROTOCOL_INFO, 0, NULL, 0,
- &info, sizeof(info));
- if (rv < 0) {
- fprintf(stderr, "Protocol info unavailable. EC probably only "
- "supports protocol version 2.\n");
- return rv;
- }
-
- printf(" protocol versions:");
- for (i = 0; i < 32; i++) {
- if (info.protocol_versions & BIT(i))
- printf(" %d", i);
- }
- printf("\n");
-
- printf(" max request: %4d bytes\n", info.max_request_packet_size);
- printf(" max response: %4d bytes\n", info.max_response_packet_size);
- printf(" flags: 0x%08x\n", info.flags);
- if (info.flags & EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED)
- printf(" EC_RES_IN_PROGRESS supported\n");
- return 0;
-}
-
-static int ec_hash_help(const char *cmd)
-{
- printf("Usage:\n");
- printf(" %s - get last hash\n", cmd);
- printf(" %s abort - abort hashing\n", cmd);
- printf(" %s start [<offset> <size> [<nonce>]] - start hashing\n", cmd);
- printf(" %s recalc [<offset> <size> [<nonce>]] - sync rehash\n", cmd);
- printf("\n"
- "If <offset> is RO or RW, offset and size are computed\n"
- "automatically for the EC-RO or EC-RW firmware image.\n");
-
- return 0;
-}
-
-
-static int ec_hash_print(const struct ec_response_vboot_hash *r)
-{
- int i;
-
- if (r->status == EC_VBOOT_HASH_STATUS_BUSY) {
- printf("status: busy\n");
- return 0;
- } else if (r->status == EC_VBOOT_HASH_STATUS_NONE) {
- printf("status: unavailable\n");
- return 0;
- } else if (r->status != EC_VBOOT_HASH_STATUS_DONE) {
- printf("status: %d\n", r->status);
- return 0;
- }
-
- printf("status: done\n");
- if (r->hash_type == EC_VBOOT_HASH_TYPE_SHA256)
- printf("type: SHA-256\n");
- else
- printf("type: %d\n", r->hash_type);
-
- printf("offset: 0x%08x\n", r->offset);
- printf("size: 0x%08x\n", r->size);
-
- printf("hash: ");
- for (i = 0; i < r->digest_size; i++)
- printf("%02x", r->hash_digest[i]);
- printf("\n");
- return 0;
-}
-
-
-int cmd_ec_hash(int argc, char *argv[])
-{
- struct ec_params_vboot_hash p;
- struct ec_response_vboot_hash r;
- char *e;
- int rv;
-
- memset(&p, 0, sizeof(p));
- if (argc < 2) {
- /* Get hash status */
- p.cmd = EC_VBOOT_HASH_GET;
- rv = ec_command(EC_CMD_VBOOT_HASH, 0,
- &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- return ec_hash_print(&r);
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "abort")) {
- /* Abort hash calculation */
- p.cmd = EC_VBOOT_HASH_ABORT;
- rv = ec_command(EC_CMD_VBOOT_HASH, 0,
- &p, sizeof(p), &r, sizeof(r));
- return (rv < 0 ? rv : 0);
- }
-
- /* The only other commands are start and recalc */
- if (!strcasecmp(argv[1], "start"))
- p.cmd = EC_VBOOT_HASH_START;
- else if (!strcasecmp(argv[1], "recalc"))
- p.cmd = EC_VBOOT_HASH_RECALC;
- else
- return ec_hash_help(argv[0]);
-
- p.hash_type = EC_VBOOT_HASH_TYPE_SHA256;
-
- if (argc < 3) {
- fprintf(stderr, "Must specify offset\n");
- return -1;
- }
-
- if (!strcasecmp(argv[2], "ro")) {
- p.offset = EC_VBOOT_HASH_OFFSET_RO;
- p.size = 0;
- printf("Hashing EC-RO...\n");
- } else if (!strcasecmp(argv[2], "rw")) {
- p.offset = EC_VBOOT_HASH_OFFSET_ACTIVE;
- p.size = 0;
- printf("Hashing EC-RW...\n");
- } else if (argc < 4) {
- fprintf(stderr, "Must specify size\n");
- return -1;
- } else {
- p.offset = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
- return -1;
- }
- p.size = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad size.\n");
- return -1;
- }
- printf("Hashing %d bytes at offset %d...\n", p.size, p.offset);
- }
-
- if (argc == 5) {
- /*
- * Technically nonce can be any binary data up to 64 bytes,
- * but this command only supports a 32-bit value.
- */
- uint32_t nonce = strtol(argv[4], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad nonce integer.\n");
- return -1;
- }
- memcpy(p.nonce_data, &nonce, sizeof(nonce));
- p.nonce_size = sizeof(nonce);
- } else
- p.nonce_size = 0;
-
- rv = ec_command(EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- /* Start command doesn't wait for hashing to finish */
- if (p.cmd == EC_VBOOT_HASH_START)
- return 0;
-
- /* Recalc command does wait around, so a result is ready now */
- return ec_hash_print(&r);
-}
-
-
-int cmd_rtc_get(int argc, char *argv[])
-{
- struct ec_response_rtc r;
- int rv;
-
- rv = ec_command(EC_CMD_RTC_GET_VALUE, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("Current time: 0x%08x (%d)\n", r.time, r.time);
- return 0;
-}
-
-
-int cmd_rtc_set(int argc, char *argv[])
-{
- struct ec_params_rtc p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <time>\n", argv[0]);
- return -1;
- }
- p.time = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad time.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_RTC_SET_VALUE, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Time set.\n");
- return 0;
-}
-
-int cmd_rtc_set_alarm(int argc, char *argv[])
-{
- struct ec_params_rtc p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <sec>\n", argv[0]);
- return -1;
- }
- p.time = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad time.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_RTC_SET_ALARM, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
-
- if (p.time == 0)
- printf("Disabling alarm.\n");
- else
- printf("Alarm set to go off in %d secs.\n", p.time);
- return 0;
-}
-
-int cmd_rtc_get_alarm(int argc, char *argv[])
-{
- struct ec_response_rtc r;
- int rv;
-
- rv = ec_command(EC_CMD_RTC_GET_ALARM, 0, NULL, 0, &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- if (r.time == 0)
- printf("Alarm not set\n");
- else
- printf("Alarm to go off in %d secs\n", r.time);
- return 0;
-}
-
-int cmd_console(int argc, char *argv[])
-{
- char *out = (char *)ec_inbuf;
- int rv;
-
- /* Snapshot the EC console */
- rv = ec_command(EC_CMD_CONSOLE_SNAPSHOT, 0, NULL, 0, NULL, 0);
- if (rv < 0)
- return rv;
-
- /* Loop and read from the snapshot until it's done */
- while (1) {
- rv = ec_command(EC_CMD_CONSOLE_READ, 0,
- NULL, 0, ec_inbuf, ec_max_insize);
- if (rv < 0)
- return rv;
-
- /* Empty response means done */
- if (!rv || !*out)
- break;
-
- /* Make sure output is null-terminated, then dump it */
- out[ec_max_insize - 1] = '\0';
- fputs(out, stdout);
- }
- printf("\n");
- return 0;
-}
-struct param_info {
- const char *name; /* name of this parameter */
- const char *help; /* help message */
- int size; /* size in bytes */
- int offset; /* offset within structure */
-};
-
-#define FIELD(fname, field, help_str) \
- { \
- .name = fname, \
- .help = help_str, \
- .size = sizeof(((struct ec_mkbp_config *)NULL)->field), \
- .offset = __builtin_offsetof(struct ec_mkbp_config, field), \
- }
-
-static const struct param_info keyconfig_params[] = {
- FIELD("scan_period", scan_period_us, "period between scans"),
- FIELD("poll_timeout", poll_timeout_us,
- "revert to irq mode after no activity for this long"),
- FIELD("min_post_scan_delay", min_post_scan_delay_us,
- "minimum post-scan delay before starting a new scan"),
- FIELD("output_settle", output_settle_us,
- "delay to wait for output to settle"),
- FIELD("debounce_down", debounce_down_us,
- "time for debounce on key down"),
- FIELD("debounce_up", debounce_up_us, "time for debounce on key up"),
- FIELD("fifo_max_depth", fifo_max_depth,
- "maximum depth to allow for fifo (0 = disable)"),
- FIELD("flags", flags, "0 to disable scanning, 1 to enable"),
-};
-
-static const struct param_info *find_field(const struct param_info *params,
- int count, const char *name, unsigned int *nump)
-{
- const struct param_info *param;
- int i;
-
- for (i = 0, param = params; i < count; i++, param++) {
- if (0 == strcmp(param->name, name)) {
- if (nump)
- *nump = i;
- return param;
- }
- }
-
- fprintf(stderr, "Unknown parameter '%s'\n", name);
- return NULL;
-}
-
-static int get_value(const struct param_info *param, const char *config)
-{
- const char *field;
-
- field = config + param->offset;
- switch (param->size) {
- case 1:
- return *(uint8_t *)field;
- case 2:
- return *(uint16_t *)field;
- case 4:
- return *(uint32_t *)field;
- default:
- fprintf(stderr, "Internal error: unknown size %d\n",
- param->size);
- }
-
- return -1;
-}
-
-static int show_fields(struct ec_mkbp_config *config, int argc, char *argv[])
-{
- const struct param_info *param;
- uint32_t mask;
- int i;
-
- if (!argc) {
- mask = -1U; /* show all fields */
- } else {
- mask = 0;
- while (argc > 0) {
- unsigned int num;
-
- param = find_field(keyconfig_params,
- ARRAY_SIZE(keyconfig_params),
- argv[0], &num);
- if (!param)
- return -1;
- mask |= 1 << num;
- argc--;
- argv++;
- }
- }
-
- param = keyconfig_params;
- for (i = 0; i < ARRAY_SIZE(keyconfig_params); i++, param++) {
- if (mask & BIT(i)) {
- fprintf(stderr, "%-12s %u\n", param->name,
- get_value(param, (char *)config));
- }
- }
-
- return 0;
-}
-
-static int cmd_kbinfo(int argc, char *argv[])
-{
- struct ec_params_mkbp_info info = {
- .info_type = EC_MKBP_INFO_KBD,
- };
- struct ec_response_mkbp_info resp;
- int rv;
-
- if (argc > 1) {
- fprintf(stderr, "Too many args\n");
- return -1;
- }
- rv = ec_command(EC_CMD_MKBP_INFO, 0, &info, sizeof(info), &resp,
- sizeof(resp));
- if (rv < 0)
- return rv;
-
- printf("Matrix rows: %d\n", resp.rows);
- printf("Matrix columns: %d\n", resp.cols);
-
- return 0;
-}
-
-static int cmd_kbid(int argc, char *argv[])
-{
- struct ec_response_keyboard_id response;
- int rv;
-
- if (argc > 1) {
- fprintf(stderr, "Too many args\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_GET_KEYBOARD_ID, 0, NULL, 0, &response,
- sizeof(response));
- if (rv < 0)
- return rv;
- switch (response.keyboard_id) {
- case KEYBOARD_ID_UNSUPPORTED:
- /* Keyboard ID was not supported */
- printf("Keyboard doesn't support ID\n");
- break;
- case KEYBOARD_ID_UNREADABLE:
- /* Ghosting ID was detected */
- printf("Reboot and keep hands off the keyboard during"
- " next boot-up\n");
- break;
- default:
- /* Valid keyboard ID value was reported*/
- printf("%x\n", response.keyboard_id);
- }
- return rv;
-}
-
-static int cmd_keyconfig(int argc, char *argv[])
-{
- struct ec_params_mkbp_set_config req;
- int cmd;
- int rv;
-
- if (argc < 2) {
- const struct param_info *param;
- int i;
-
- fprintf(stderr, "Usage: %s get [<param>] - print params\n"
- "\t%s set [<param>> <value>]\n"
- " Available params are: (all time values are in us)",
- argv[0], argv[0]);
-
- param = keyconfig_params;
- for (i = 0; i < ARRAY_SIZE(keyconfig_params); i++, param++) {
- fprintf(stderr, "%-12s %s\n", param->name,
- param->name);
- }
- return -1;
- }
-
- /* Get the command */
- if (0 == strcmp(argv[1], "get")) {
- cmd = EC_CMD_MKBP_GET_CONFIG;
- } else if (0 == strcmp(argv[1], "set")) {
- cmd = EC_CMD_MKBP_SET_CONFIG;
- } else {
- fprintf(stderr, "Invalid command '%s\n", argv[1]);
- return -1;
- }
-
- switch (cmd) {
- case EC_CMD_MKBP_GET_CONFIG:
- /* Read the existing config */
- rv = ec_command(cmd, 0, NULL, 0, &req, sizeof(req));
- if (rv < 0)
- return rv;
- show_fields(&req.config, argc - 2, argv + 2);
- break;
- }
-
- return 0;
-}
-
-static const char * const mkbp_button_strings[] = {
- [EC_MKBP_POWER_BUTTON] = "Power",
- [EC_MKBP_VOL_UP] = "Volume up",
- [EC_MKBP_VOL_DOWN] = "Volume down",
- [EC_MKBP_RECOVERY] = "Recovery",
-};
-
-static const char * const mkbp_switch_strings[] = {
- [EC_MKBP_LID_OPEN] = "Lid open",
- [EC_MKBP_TABLET_MODE] = "Tablet mode",
- [EC_MKBP_BASE_ATTACHED] = "Base attached",
-};
-
-static int cmd_mkbp_get(int argc, char *argv[])
-{
- struct ec_params_mkbp_info p;
- union ec_response_get_next_data r;
- int rv;
- int i;
- uint32_t supported;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <buttons|switches>\n", argv[0]);
- return -1;
- }
-
- if (strncmp(argv[1], "button", 6) == 0) {
- p.event_type = EC_MKBP_EVENT_BUTTON;
- } else if (strncmp(argv[1], "switch", 6) == 0) {
- p.event_type = EC_MKBP_EVENT_SWITCH;
- } else {
- fprintf(stderr, "Invalid param: '%s'\n", argv[1]);
- return -1;
- }
-
- p.info_type = EC_MKBP_INFO_SUPPORTED;
- rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0)
- return rv;
- if (p.event_type == EC_MKBP_EVENT_BUTTON)
- supported = r.buttons;
- else if (p.event_type == EC_MKBP_EVENT_SWITCH)
- supported = r.switches;
-
- p.info_type = EC_MKBP_INFO_CURRENT;
- rv = ec_command(EC_CMD_MKBP_INFO, 0, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0)
- return rv;
-
- if (p.event_type == EC_MKBP_EVENT_BUTTON) {
- printf("MKBP buttons state: 0x%04x (supported: 0x%04x)\n",
- r.buttons, supported);
- for (i = 0; i < ARRAY_SIZE(mkbp_button_strings); i++) {
- if (supported & BIT(i) && mkbp_button_strings[i]) {
- printf("%s: %s\n", mkbp_button_strings[i],
- r.buttons & BIT(i) ? "ON" : "OFF");
- supported &= ~BIT(i);
- }
- }
- if (supported)
- printf("Unknown buttons: 0x%04x\n", supported);
- } else if (p.event_type == EC_MKBP_EVENT_SWITCH) {
- printf("MKBP switches state: 0x%04x (supported: 0x%04x)\n",
- r.switches, supported);
- for (i = 0; i < ARRAY_SIZE(mkbp_switch_strings); i++) {
- if (supported & BIT(i) && mkbp_switch_strings[i]) {
- printf("%s: %s\n", mkbp_switch_strings[i],
- r.switches & BIT(i) ? "ON" : "OFF");
- supported &= ~BIT(i);
- }
- }
- if (supported)
- printf("Unknown switches: 0x%04x\n", supported);
- }
-
- return 0;
-}
-
-static int cmd_mkbp_wake_mask(int argc, char *argv[])
-{
- struct ec_params_mkbp_event_wake_mask p;
- struct ec_response_mkbp_event_wake_mask r;
- int rv;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s get <event|hostevent>\n"
- "\t%s set <event|hostevent> <mask>\n", argv[0],
- argv[0]);
- return -1;
- }
-
- /* Determine if the user want to get or set the wake mask. */
- if (strncmp(argv[1], "get", 3) == 0) {
- p.action = GET_WAKE_MASK;
- } else if (strncmp(argv[1], "set", 3) == 0) {
- p.action = SET_WAKE_MASK;
- } else {
- fprintf(stderr, "Invalid param: '%s'\n", argv[1]);
- return -1;
- }
-
- /* Determine which mask is of interest. */
- if (strncmp(argv[2], "event", 5) == 0) {
- p.mask_type = EC_MKBP_EVENT_WAKE_MASK;
- } else if (strncmp(argv[2], "hostevent", 9) == 0) {
- p.mask_type = EC_MKBP_HOST_EVENT_WAKE_MASK;
- } else {
- fprintf(stderr, "Invalid param: '%s'\n", argv[2]);
- return -1;
- }
-
- if (p.action == SET_WAKE_MASK) {
- char *e;
-
- if (argc < 4) {
- fprintf(stderr, "Missing mask value!");
- return -1;
- }
-
- p.new_wake_mask = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad mask: '%s'", argv[1]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_MKBP_WAKE_MASK, 0, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0) {
- if (rv == -EECRESULT-EC_RES_INVALID_PARAM) {
- fprintf(stderr, "Unknown mask, or mask is not in use. "
- "You may need to enable the "
- "CONFIG_MKBP_%s_WAKEUP_MASK option in the EC.\n"
- , p.mask_type == EC_MKBP_EVENT_WAKE_MASK ?
- "EVENT" : "HOSTEVENT");
- }
- return rv;
- }
-
- if (p.action == GET_WAKE_MASK)
- printf("MBKP %s wake mask: 0x%08x\n", argv[2], r.wake_mask);
- else if (p.action == SET_WAKE_MASK)
- printf("MKBP %s wake mask set.\n", argv[2]);
-
- return 0;
-}
-
-/* Index is already checked. argv[0] is first param value */
-static int cmd_tmp006cal_v0(int idx, int argc, char *argv[])
-{
- struct ec_params_tmp006_get_calibration pg;
- struct ec_response_tmp006_get_calibration_v0 rg;
- struct ec_params_tmp006_set_calibration_v0 ps;
- float val;
- char *e;
- int i, rv;
-
- /* Get current values */
- pg.index = idx;
- rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 0,
- &pg, sizeof(pg), &rg, sizeof(rg));
- if (rv < 0)
- return rv;
-
- if (!argc) {
- /* If no new values are given, just print what we have */
- printf("S0: %e\n", rg.s0);
- printf("b0: %e\n", rg.b0);
- printf("b1: %e\n", rg.b1);
- printf("b2: %e\n", rg.b2);
- return EC_SUCCESS;
- }
-
- /* Prepare to reuse the current values */
- memset(&ps, 0, sizeof(ps));
- ps.index = idx;
- ps.s0 = rg.s0;
- ps.b0 = rg.b0;
- ps.b1 = rg.b1;
- ps.b2 = rg.b2;
-
- /* Parse up to four args, skipping any that are just "-" */
- for (i = 0; i < argc && i < 4; i++) {
- if (!strcmp(argv[i], "-"))
- continue;
- val = strtod(argv[i], &e);
- if (e && *e) {
- fprintf(stderr,
- "Bad arg \"%s\". Use \"-\" to skip a param.\n",
- argv[i]);
- return -1;
- }
- switch (i) {
- case 0:
- ps.s0 = val;
- break;
- case 1:
- ps.b0 = val;
- break;
- case 2:
- ps.b1 = val;
- break;
- case 3:
- ps.b2 = val;
- break;
- }
- }
-
- /* Set 'em */
- return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 0,
- &ps, sizeof(ps), NULL, 0);
-}
-
-/* Index is already checked. argv[0] is first param value */
-static int cmd_tmp006cal_v1(int idx, int argc, char *argv[])
-{
- struct ec_params_tmp006_get_calibration pg;
- struct ec_response_tmp006_get_calibration_v1 *rg = ec_inbuf;
- struct ec_params_tmp006_set_calibration_v1 *ps = ec_outbuf;
- float val;
- char *e;
- int i, rv, cmdsize;
-
- /* Algorithm 1 parameter names */
- static const char * const alg1_pname[] = {
- "s0", "a1", "a2", "b0", "b1", "b2", "c2",
- "d0", "d1", "ds", "e0", "e1",
- };
-
- /* Get current values */
- pg.index = idx;
- rv = ec_command(EC_CMD_TMP006_GET_CALIBRATION, 1,
- &pg, sizeof(pg), rg, ec_max_insize);
- if (rv < 0)
- return rv;
-
- if (!argc) {
- /* If no new values are given, just print what we have */
- printf("algorithm: %d\n", rg->algorithm);
- printf("params:\n");
- /* We only know about alg 1 at the moment */
- if (rg->algorithm == 1)
- for (i = 0; i < rg->num_params; i++)
- printf(" %s %e\n", alg1_pname[i], rg->val[i]);
- else
- for (i = 0; i < rg->num_params; i++)
- printf(" param%d %e\n", i, rg->val[i]);
- return EC_SUCCESS;
- }
-
- /* Prepare to reuse the current values */
- memset(ps, 0, ec_max_outsize);
- ps->index = idx;
- ps->algorithm = rg->algorithm;
- ps->num_params = rg->num_params;
- for (i = 0; i < rg->num_params; i++)
- ps->val[i] = rg->val[i];
-
- /* Parse the args, skipping any that are just "-" */
- for (i = 0; i < argc && i < rg->num_params; i++) {
- if (!strcmp(argv[i], "-"))
- continue;
- val = strtod(argv[i], &e);
- if (e && *e) {
- fprintf(stderr,
- "Bad arg \"%s\". Use \"-\" to skip a param.\n",
- argv[i]);
- return -1;
- }
- ps->val[i] = val;
- }
-
- /* Set 'em */
- cmdsize = sizeof(*ps) + ps->num_params * sizeof(ps->val[0]);
- return ec_command(EC_CMD_TMP006_SET_CALIBRATION, 1,
- ps, cmdsize, NULL, 0);
-}
-
-int cmd_tmp006cal(int argc, char *argv[])
-{
- char *e;
- int idx;
-
- if (argc < 2) {
- fprintf(stderr, "Must specify tmp006 index.\n");
- return -1;
- }
-
- idx = strtol(argv[1], &e, 0);
- if ((e && *e) || idx < 0 || idx > 255) {
- fprintf(stderr, "Bad index.\n");
- return -1;
- }
-
- /* Pass just the params (if any) to the helper function */
- argc -= 2;
- argv += 2;
-
- if (ec_cmd_version_supported(EC_CMD_TMP006_GET_CALIBRATION, 1))
- return cmd_tmp006cal_v1(idx, argc, argv);
-
- if (ec_cmd_version_supported(EC_CMD_TMP006_GET_CALIBRATION, 0))
- return cmd_tmp006cal_v0(idx, argc, argv);
-
- printf("The EC is being stupid\n");
- return -1;
-}
-
-int cmd_tmp006raw(int argc, char *argv[])
-{
- struct ec_params_tmp006_get_raw p;
- struct ec_response_tmp006_get_raw r;
- char *e;
- int idx;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Must specify tmp006 index.\n");
- return -1;
- }
-
- idx = strtol(argv[1], &e, 0);
- if ((e && *e) || idx < 0 || idx > 255) {
- fprintf(stderr, "Bad index.\n");
- return -1;
- }
-
- p.index = idx;
-
- rv = ec_command(EC_CMD_TMP006_GET_RAW, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("T: %d.%02d K\n", r.t / 100, r.t % 100);
- printf("V: %d nV\n", r.v);
- return EC_SUCCESS;
-}
-
-static int cmd_hang_detect(int argc, char *argv[])
-{
- struct ec_params_hang_detect req;
- char *e;
-
- memset(&req, 0, sizeof(req));
-
- if (argc == 2 && !strcasecmp(argv[1], "stop")) {
- req.flags = EC_HANG_STOP_NOW;
- return ec_command(EC_CMD_HANG_DETECT, 0, &req, sizeof(req),
- NULL, 0);
- }
-
- if (argc == 2 && !strcasecmp(argv[1], "start")) {
- req.flags = EC_HANG_START_NOW;
- return ec_command(EC_CMD_HANG_DETECT, 0, &req, sizeof(req),
- NULL, 0);
- }
-
- if (argc == 4) {
- req.flags = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad flags.\n");
- return -1;
- }
-
- req.host_event_timeout_msec = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad event timeout.\n");
- return -1;
- }
-
- req.warm_reboot_timeout_msec = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad reboot timeout.\n");
- return -1;
- }
-
- printf("hang flags=0x%x\n"
- "event_timeout=%d ms\n"
- "reboot_timeout=%d ms\n",
- req.flags, req.host_event_timeout_msec,
- req.warm_reboot_timeout_msec);
-
- return ec_command(EC_CMD_HANG_DETECT, 0, &req, sizeof(req),
- NULL, 0);
- }
-
- fprintf(stderr,
- "Must specify start/stop or <flags> <event_ms> <reboot_ms>\n");
- return -1;
-}
-
-enum port_80_event {
- PORT_80_EVENT_RESUME = 0x1001, /* S3->S0 transition */
- PORT_80_EVENT_RESET = 0x1002, /* RESET transition */
-};
-
-int cmd_port80_read(int argc, char *argv[])
-{
- struct ec_params_port80_read p;
- int cmdver = 1, rv;
- int i, head, tail;
- uint16_t *history;
- uint32_t writes, history_size;
- struct ec_response_port80_read rsp;
- int printed = 0;
-
- if (!ec_cmd_version_supported(EC_CMD_PORT80_READ, cmdver)) {
- /* fall back to last boot */
- struct ec_response_port80_last_boot r;
- rv = ec_command(EC_CMD_PORT80_LAST_BOOT, 0,
- NULL, 0, &r, sizeof(r));
- fprintf(stderr, "Last boot %2x\n", r.code);
- printf("done.\n");
- return 0;
- }
-
-
- /* read writes and history_size */
- p.subcmd = EC_PORT80_GET_INFO;
- rv = ec_command(EC_CMD_PORT80_READ, cmdver,
- &p, sizeof(p), &rsp, sizeof(rsp));
- if (rv < 0) {
- fprintf(stderr, "Read error at writes\n");
- return rv;
- }
- writes = rsp.get_info.writes;
- history_size = rsp.get_info.history_size;
-
- history = malloc(history_size*sizeof(uint16_t));
- if (!history) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- return -1;
- }
- /* As the history buffer is quite large, we read data in chunks, with
- size in bytes of EC_PORT80_SIZE_MAX in each chunk.
- Incrementing offset until all history buffer has been read. To
- simplify the design, chose HISTORY_LEN is always multiple of
- EC_PORT80_SIZE_MAX.
-
- offset: entry offset from the beginning of history buffer.
- num_entries: number of entries requested.
- */
- p.subcmd = EC_PORT80_READ_BUFFER;
- for (i = 0; i < history_size; i += EC_PORT80_SIZE_MAX) {
- p.read_buffer.offset = i;
- p.read_buffer.num_entries = EC_PORT80_SIZE_MAX;
- rv = ec_command(EC_CMD_PORT80_READ, cmdver,
- &p, sizeof(p), &rsp, sizeof(rsp));
- if (rv < 0) {
- fprintf(stderr, "Read error at offset %d\n", i);
- free(history);
- return rv;
- }
- memcpy((void *)(history + i), rsp.data.codes,
- EC_PORT80_SIZE_MAX*sizeof(uint16_t));
- }
-
- head = writes;
- if (head > history_size)
- tail = head - history_size;
- else
- tail = 0;
-
- fprintf(stderr, "Port 80 writes");
- for (i = tail; i < head; i++) {
- int e = history[i % history_size];
- switch (e) {
- case PORT_80_EVENT_RESUME:
- fprintf(stderr, "\n(S3->S0)");
- printed = 0;
- break;
- case PORT_80_EVENT_RESET:
- fprintf(stderr, "\n(RESET)");
- printed = 0;
- break;
- default:
- if (!(printed++ % 20))
- fprintf(stderr, "\n ");
- fprintf(stderr, " %02x", e);
- }
- }
- fprintf(stderr, " <--new\n");
-
- free(history);
- printf("done.\n");
- return 0;
-}
-
-int cmd_force_lid_open(int argc, char *argv[])
-{
- struct ec_params_force_lid_open p;
- char *e;
- int rv;
-
- if (argc != 2) {
- fprintf(stderr, "Usage: %s <0|1>\n", argv[0]);
- return -1;
- }
- p.enabled = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad value.\n");
- return -1;
- }
-
- rv = ec_command(EC_CMD_FORCE_LID_OPEN, 0, &p, sizeof(p), NULL, 0);
- if (rv < 0)
- return rv;
- printf("Success.\n");
- return 0;
-}
-
-int cmd_charge_port_override(int argc, char *argv[])
-{
- struct ec_params_charge_port_override p;
- char *e;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <port# | dontcharge | off>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "dontcharge"))
- p.override_port = OVERRIDE_DONT_CHARGE;
- else if (!strcasecmp(argv[1], "off"))
- p.override_port = OVERRIDE_OFF;
- else {
- p.override_port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad parameter.\n");
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_PD_CHARGE_PORT_OVERRIDE, 0, &p, sizeof(p),
- NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Override port set to %d\n", p.override_port);
- return 0;
-}
-
-int cmd_pd_log(int argc, char *argv[])
-{
- union {
- struct ec_response_pd_log r;
- uint32_t words[8]; /* space for the payload */
- } u;
- struct mcdp_info minfo;
- struct ec_response_usb_pd_power_info pinfo;
- int rv;
- unsigned long long milliseconds;
- unsigned seconds;
- time_t now;
- struct tm ltime;
- char time_str[64];
-
- while (1) {
- now = time(NULL);
- rv = ec_command(EC_CMD_PD_GET_LOG_ENTRY, 0,
- NULL, 0, &u, sizeof(u));
- if (rv < 0)
- return rv;
-
- if (u.r.type == PD_EVENT_NO_ENTRY) {
- printf("--- END OF LOG ---\n");
- break;
- }
-
- /* the timestamp is in 1024th of seconds */
- milliseconds = ((uint64_t)u.r.timestamp <<
- PD_LOG_TIMESTAMP_SHIFT) / 1000;
- /* the timestamp is the number of milliseconds in the past */
- seconds = (milliseconds + 999) / 1000;
- milliseconds -= seconds * 1000;
- now -= seconds;
- localtime_r(&now, &ltime);
- strftime(time_str, sizeof(time_str), "%F %T", &ltime);
- printf("%s.%03lld P%d ", time_str, -milliseconds,
- PD_LOG_PORT(u.r.size_port));
- if (u.r.type == PD_EVENT_MCU_CHARGE) {
- if (u.r.data & CHARGE_FLAGS_OVERRIDE)
- printf("override ");
- if (u.r.data & CHARGE_FLAGS_DELAYED_OVERRIDE)
- printf("pending_override ");
- memcpy(&pinfo.meas, u.r.payload,
- sizeof(struct usb_chg_measures));
- pinfo.dualrole = !!(u.r.data & CHARGE_FLAGS_DUAL_ROLE);
- pinfo.role = u.r.data & CHARGE_FLAGS_ROLE_MASK;
- pinfo.type = (u.r.data & CHARGE_FLAGS_TYPE_MASK)
- >> CHARGE_FLAGS_TYPE_SHIFT;
- pinfo.max_power = 0;
- print_pd_power_info(&pinfo);
- } else if (u.r.type == PD_EVENT_MCU_CONNECT) {
- printf("New connection\n");
- } else if (u.r.type == PD_EVENT_MCU_BOARD_CUSTOM) {
- printf("Board-custom event\n");
- } else if (u.r.type == PD_EVENT_ACC_RW_FAIL) {
- printf("RW signature check failed\n");
- } else if (u.r.type == PD_EVENT_PS_FAULT) {
- static const char * const fault_names[] = {
- "---", "OCP", "fast OCP", "OVP", "Discharge"
- };
- const char *fault = u.r.data < ARRAY_SIZE(fault_names) ?
- fault_names[u.r.data] : "???";
- printf("Power supply fault: %s\n", fault);
- } else if (u.r.type == PD_EVENT_VIDEO_DP_MODE) {
- printf("DP mode %sabled\n", (u.r.data == 1) ?
- "en" : "dis");
- } else if (u.r.type == PD_EVENT_VIDEO_CODEC) {
- memcpy(&minfo, u.r.payload,
- sizeof(struct mcdp_info));
- printf("HDMI info: family:%04x chipid:%04x "
- "irom:%d.%d.%d fw:%d.%d.%d\n",
- MCDP_FAMILY(minfo.family),
- MCDP_CHIPID(minfo.chipid),
- minfo.irom.major, minfo.irom.minor,
- minfo.irom.build, minfo.fw.major,
- minfo.fw.minor, minfo.fw.build);
- } else { /* Unknown type */
- int i;
- printf("Event %02x (%04x) [", u.r.type, u.r.data);
- for (i = 0; i < PD_LOG_SIZE(u.r.size_port); i++)
- printf("%02x ", u.r.payload[i]);
- printf("]\n");
- }
- }
-
- return 0;
-}
-
-int cmd_pd_control(int argc, char *argv[])
-{
- struct ec_params_pd_control p;
- int rv;
-
- if (argc < 2) {
- fprintf(stderr, "Missing parameter\n");
- return -1;
- }
-
- /* Parse command */
- if (!strcmp(argv[1], "reset"))
- p.subcmd = PD_RESET;
- else if (!strcmp(argv[1], "suspend"))
- p.subcmd = PD_SUSPEND;
- else if (!strcmp(argv[1], "resume"))
- p.subcmd = PD_RESUME;
- else if (!strcmp(argv[1], "disable"))
- p.subcmd = PD_CONTROL_DISABLE;
- else if (!strcmp(argv[1], "on") || !strcmp(argv[1], "chip_on"))
- p.subcmd = PD_CHIP_ON;
- else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- return -1;
- }
-
- if (argc == 2) {
- p.chip = 0;
- } else {
- char *e;
- p.chip = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port number '%s'.\n", argv[2]);
- return -1;
- }
- }
-
- rv = ec_command(EC_CMD_PD_CONTROL, 0, &p, sizeof(p), NULL, 0);
- return (rv < 0 ? rv : 0);
-}
-
-int cmd_pd_chip_info(int argc, char *argv[])
-{
- struct ec_params_pd_chip_info p;
- struct ec_response_pd_chip_info_v1 r;
- char *e;
- int rv;
- int cmdver = 1;
-
- if (argc < 2 || 3 < argc) {
- fprintf(stderr, "Usage: %s <port> [<live>]\n"
- "live parameter can take values 0 or 1\n"
- "0 -> Return hard-coded value for VID/PID and\n"
- " cached value for Firmware Version\n"
- "1 -> Return live chip value for VID/PID/FW Version\n",
- argv[0]);
- return -1;
- }
-
- p.port = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port number.\n");
- return -1;
- }
-
- p.live = 0;
- if (argc == 3) {
- p.live = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "invalid arg \"%s\"\n", argv[2]);
- return -1;
- }
- }
-
- if (!ec_cmd_version_supported(EC_CMD_PD_CHIP_INFO, cmdver))
- cmdver = 0;
-
- rv = ec_command(EC_CMD_PD_CHIP_INFO, cmdver, &p, sizeof(p), &r,
- sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("vendor_id: 0x%x\n", r.vendor_id);
- printf("product_id: 0x%x\n", r.product_id);
- printf("device_id: 0x%x\n", r.device_id);
-
- if (r.fw_version_number != -1)
- printf("fw_version: 0x%" PRIx64 "\n", r.fw_version_number);
- else
- printf("fw_version: UNSUPPORTED\n");
-
- if (cmdver >= 1)
- printf("min_req_fw_version: 0x%" PRIx64 "\n",
- r.min_req_fw_version_number);
- else
- printf("min_req_fw_version: UNSUPPORTED\n");
-
- return 0;
-}
-
-int cmd_pd_write_log(int argc, char *argv[])
-{
- struct ec_params_pd_write_log_entry p;
- char *e;
-
- if (argc < 3) {
- fprintf(stderr, "Usage: %s <log_type> <port>\n",
- argv[0]);
- return -1;
- }
-
- if (!strcasecmp(argv[1], "charge"))
- p.type = PD_EVENT_MCU_CHARGE;
- else {
- p.type = strtol(argv[1], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad log_type parameter.\n");
- return -1;
- }
- }
-
- p.port = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad port parameter.\n");
- return -1;
- }
-
- return ec_command(EC_CMD_PD_WRITE_LOG_ENTRY, 0, &p, sizeof(p), NULL, 0);
-}
-
-int cmd_tp_self_test(int argc, char* argv[])
-{
- int rv;
-
- rv = ec_command(EC_CMD_TP_SELF_TEST, 0, NULL, 0, NULL, 0);
- if (rv < 0)
- return rv;
-
- printf("Touchpad self test: %s\n",
- rv == EC_RES_SUCCESS ? "passed" : "failed");
-
- return rv;
-}
-
-int cmd_tp_frame_get(int argc, char* argv[])
-{
- int i, j;
- uint32_t remaining = 0, offset = 0;
- int rv = EC_SUCCESS;
- uint8_t *data;
- struct ec_response_tp_frame_info* r;
- struct ec_params_tp_frame_get p;
-
- data = malloc(ec_max_insize);
- r = malloc(ec_max_insize);
-
- if (data == NULL || r == NULL) {
- fprintf(stderr, "Couldn't allocate memory.\n");
- free(r);
- free(data);
- return EC_ERROR_UNKNOWN;
- }
-
- rv = ec_command(EC_CMD_TP_FRAME_INFO, 0, NULL, 0, r, ec_max_insize);
- if (rv < 0) {
- fprintf(stderr, "Failed to get touchpad frame info.\n");
- goto err;
- }
-
- rv = ec_command(EC_CMD_TP_FRAME_SNAPSHOT, 0, NULL, 0, NULL, 0);
- if (rv < 0) {
- fprintf(stderr, "Failed to snapshot frame.\n");
- goto err;
- }
-
- for (i = 0; i < r->n_frames; i++) {
- p.frame_index = i;
- offset = 0;
- remaining = r->frame_sizes[i];
-
- while (remaining > 0) {
- p.offset = offset;
- p.size = MIN(remaining, ec_max_insize);
-
- rv = ec_command(EC_CMD_TP_FRAME_GET, 0,
- &p, sizeof(p), data, p.size);
- if (rv < 0) {
- fprintf(stderr, "Failed to get frame data "
- "at offset 0x%x\n", offset);
- goto err;
- }
-
- for (j = 0; j < p.size; j++)
- printf("%02x ", data[j]);
-
- offset += p.size;
- remaining -= p.size;
- }
- printf("\n");
- }
-
-err:
- free(data);
- free(r);
-
- return rv < 0;
-}
-
-static int wait_event(long event_type,
- struct ec_response_get_next_event_v1 *buffer,
- size_t buffer_size, long timeout)
-{
- int rv;
-
- rv = ec_pollevent(1 << event_type, buffer, buffer_size, timeout);
- if (rv == 0) {
- fprintf(stderr, "Timeout waiting for MKBP event\n");
- return -ETIMEDOUT;
- } else if (rv < 0) {
- perror("Error polling for MKBP event\n");
- return -EIO;
- }
-
- return rv;
-}
-
-int cmd_wait_event(int argc, char *argv[])
-{
- int rv, i;
- struct ec_response_get_next_event_v1 buffer;
- long timeout = 5000;
- long event_type;
- char *e;
-
- if (!ec_pollevent) {
- fprintf(stderr, "Polling for MKBP event not supported\n");
- return -EINVAL;
- }
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <type> [<timeout>]\n",
- argv[0]);
- return -1;
- }
-
- event_type = strtol(argv[1], &e, 0);
- if ((e && *e) || event_type < 0 || event_type >= EC_MKBP_EVENT_COUNT) {
- fprintf(stderr, "Bad event type '%s'.\n", argv[1]);
- return -1;
- }
- if (argc >= 3) {
- timeout = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad timeout value '%s'.\n", argv[2]);
- return -1;
- }
- }
-
- rv = wait_event(event_type, &buffer, sizeof(buffer), timeout);
- if (rv < 0)
- return rv;
-
- printf("MKBP event %d data: ", buffer.event_type);
- for (i = 0; i < rv - 1; ++i)
- printf("%02x ", buffer.data.key_matrix[i]);
- printf("\n");
-
- return 0;
-}
-
-static void cmd_cec_help(const char *cmd)
-{
- fprintf(stderr,
- " Usage: %s write [write bytes...]\n"
- " Write message on the CEC bus\n"
- " Usage: %s read [timeout]\n"
- " [timeout] in seconds\n"
- " Usage: %s get <param>\n"
- " Usage: %s set <param> <val>\n"
- " <param> is one of:\n"
- " address: CEC receive address\n"
- " <val> is the new CEC address\n"
- " enable: Enable or disable CEC\n"
- " <val> is 1 to enable, 0 to disable\n",
- cmd, cmd, cmd, cmd);
-
-}
-
-static int cmd_cec_write(int argc, char *argv[])
-{
- char *e;
- long val;
- int rv, i, msg_len;
- struct ec_params_cec_write p;
- struct ec_response_get_next_event_v1 buffer;
-
- if (argc < 3 || argc > 18) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
-
- msg_len = argc - 2;
- for (i = 0; i < msg_len; i++) {
- val = strtol(argv[i + 2], &e, 16);
- if (e && *e)
- return -1;
- if (val < 0 || val > 0xff)
- return -1;
- p.msg[i] = (uint8_t)val;
- }
-
- printf("Write to CEC: ");
- for (i = 0; i < msg_len; i++)
- printf("0x%02x ", p.msg[i]);
- printf("\n");
-
- rv = ec_command(EC_CMD_CEC_WRITE_MSG, 0, &p, msg_len, NULL, 0);
- if (rv < 0)
- return rv;
-
- rv = wait_event(EC_MKBP_EVENT_CEC_EVENT, &buffer, sizeof(buffer), 1000);
- if (rv < 0)
- return rv;
-
- if (buffer.data.cec_events & EC_MKBP_CEC_SEND_OK)
- return 0;
-
- if (buffer.data.cec_events & EC_MKBP_CEC_SEND_FAILED) {
- fprintf(stderr, "Send failed\n");
- return -1;
- }
-
- fprintf(stderr, "No send result received\n");
-
- return -1;
-}
-
-static int cmd_cec_read(int argc, char *argv[])
-{
- int i, rv;
- char *e;
- struct ec_response_get_next_event_v1 buffer;
- long timeout = 5000;
-
- if (!ec_pollevent) {
- fprintf(stderr, "Polling for MKBP event not supported\n");
- return -EINVAL;
- }
-
- if (argc >= 3) {
- timeout = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad timeout value '%s'.\n", argv[2]);
- return -1;
- }
- }
-
- rv = wait_event(EC_MKBP_EVENT_CEC_MESSAGE, &buffer,
- sizeof(buffer), timeout);
- if (rv < 0)
- return rv;
-
- printf("CEC data: ");
- for (i = 0; i < rv - 1; i++)
- printf("0x%02x ", buffer.data.cec_message[i]);
- printf("\n");
-
- return 0;
-}
-
-static int cec_cmd_from_str(const char *str)
-{
- if (!strcmp("address", str))
- return CEC_CMD_LOGICAL_ADDRESS;
- if (!strcmp("enable", str))
- return CEC_CMD_ENABLE;
- return -1;
-}
-
-static int cmd_cec_set(int argc, char *argv[])
-{
- char *e;
- struct ec_params_cec_set p;
- uint8_t val;
- int cmd;
-
- if (argc != 4) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
-
- val = (uint8_t)strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad parameter '%s'.\n", argv[3]);
- return -1;
- }
-
- cmd = cec_cmd_from_str(argv[2]);
- if (cmd < 0) {
- fprintf(stderr, "Invalid command '%s'.\n", argv[2]);
- return -1;
- }
- p.cmd = cmd;
- p.val = val;
-
- return ec_command(EC_CMD_CEC_SET,
- 0, &p, sizeof(p), NULL, 0);
-}
-
-
-static int cmd_cec_get(int argc, char *argv[])
-{
- int rv, cmd;
- struct ec_params_cec_get p;
- struct ec_response_cec_get r;
-
-
- if (argc != 3) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
-
- cmd = cec_cmd_from_str(argv[2]);
- if (cmd < 0) {
- fprintf(stderr, "Invalid command '%s'.\n", argv[2]);
- return -1;
- }
- p.cmd = cmd;
-
-
- rv = ec_command(EC_CMD_CEC_GET, 0, &p, sizeof(p), &r, sizeof(r));
- if (rv < 0)
- return rv;
-
- printf("%d\n", r.val);
-
- return 0;
-}
-
-int cmd_cec(int argc, char *argv[])
-{
- if (argc < 2) {
- fprintf(stderr, "Invalid number of params\n");
- cmd_cec_help(argv[0]);
- return -1;
- }
- if (!strcmp(argv[1], "write"))
- return cmd_cec_write(argc, argv);
- if (!strcmp(argv[1], "read"))
- return cmd_cec_read(argc, argv);
- if (!strcmp(argv[1], "get"))
- return cmd_cec_get(argc, argv);
- if (!strcmp(argv[1], "set"))
- return cmd_cec_set(argc, argv);
-
- fprintf(stderr, "Invalid sub command: %s\n", argv[1]);
- cmd_cec_help(argv[0]);
-
- return -1;
-}
-
-/* NULL-terminated list of commands */
-const struct command commands[] = {
- {"adcread", cmd_adc_read},
- {"addentropy", cmd_add_entropy},
- {"apreset", cmd_apreset},
- {"autofanctrl", cmd_thermal_auto_fan_ctrl},
- {"backlight", cmd_lcd_backlight},
- {"battery", cmd_battery},
- {"batterycutoff", cmd_battery_cut_off},
- {"batteryparam", cmd_battery_vendor_param},
- {"boardversion", cmd_board_version},
- {"cbi", cmd_cbi},
- {"chargecurrentlimit", cmd_charge_current_limit},
- {"chargecontrol", cmd_charge_control},
- {"chargeoverride", cmd_charge_port_override},
- {"chargestate", cmd_charge_state},
- {"chipinfo", cmd_chipinfo},
- {"cmdversions", cmd_cmdversions},
- {"console", cmd_console},
- {"cec", cmd_cec},
- {"echash", cmd_ec_hash},
- {"eventclear", cmd_host_event_clear},
- {"eventclearb", cmd_host_event_clear_b},
- {"eventget", cmd_host_event_get_raw},
- {"eventgetb", cmd_host_event_get_b},
- {"eventgetscimask", cmd_host_event_get_sci_mask},
- {"eventgetsmimask", cmd_host_event_get_smi_mask},
- {"eventgetwakemask", cmd_host_event_get_wake_mask},
- {"eventsetscimask", cmd_host_event_set_sci_mask},
- {"eventsetsmimask", cmd_host_event_set_smi_mask},
- {"eventsetwakemask", cmd_host_event_set_wake_mask},
- {"extpwrlimit", cmd_ext_power_limit},
- {"fanduty", cmd_fanduty},
- {"flasherase", cmd_flash_erase},
- {"flasheraseasync", cmd_flash_erase},
- {"flashprotect", cmd_flash_protect},
- {"flashread", cmd_flash_read},
- {"flashwrite", cmd_flash_write},
- {"flashinfo", cmd_flash_info},
- {"flashspiinfo", cmd_flash_spi_info},
- {"flashpd", cmd_flash_pd},
- {"forcelidopen", cmd_force_lid_open},
- {"fpcontext", cmd_fp_context},
- {"fpencstatus", cmd_fp_enc_status},
- {"fpframe", cmd_fp_frame},
- {"fpinfo", cmd_fp_info},
- {"fpmode", cmd_fp_mode},
- {"fpseed", cmd_fp_seed},
- {"fpstats", cmd_fp_stats},
- {"fptemplate", cmd_fp_template},
- {"gpioget", cmd_gpio_get},
- {"gpioset", cmd_gpio_set},
- {"hangdetect", cmd_hang_detect},
- {"hello", cmd_hello},
- {"hibdelay", cmd_hibdelay},
- {"hostsleepstate", cmd_hostsleepstate},
- {"locatechip", cmd_locate_chip},
- {"i2cprotect", cmd_i2c_protect},
- {"i2cread", cmd_i2c_read},
- {"i2cwrite", cmd_i2c_write},
- {"i2cxfer", cmd_i2c_xfer},
- {"infopddev", cmd_pd_device_info},
- {"inventory", cmd_inventory},
- {"led", cmd_led},
- {"lightbar", cmd_lightbar},
- {"kbfactorytest", cmd_keyboard_factory_test},
- {"kbid", cmd_kbid},
- {"kbinfo", cmd_kbinfo},
- {"kbpress", cmd_kbpress},
- {"keyconfig", cmd_keyconfig},
- {"keyscan", cmd_keyscan},
- {"mkbpget", cmd_mkbp_get},
- {"mkbpwakemask", cmd_mkbp_wake_mask},
- {"motionsense", cmd_motionsense},
- {"nextevent", cmd_next_event},
- {"panicinfo", cmd_panic_info},
- {"pause_in_s5", cmd_s5},
- {"pdgetmode", cmd_pd_get_amode},
- {"pdsetmode", cmd_pd_set_amode},
- {"port80read", cmd_port80_read},
- {"pdlog", cmd_pd_log},
- {"pdcontrol", cmd_pd_control},
- {"pdchipinfo", cmd_pd_chip_info},
- {"pdwritelog", cmd_pd_write_log},
- {"powerinfo", cmd_power_info},
- {"protoinfo", cmd_proto_info},
- {"pstoreinfo", cmd_pstore_info},
- {"pstoreread", cmd_pstore_read},
- {"pstorewrite", cmd_pstore_write},
- {"pwmgetfanrpm", cmd_pwm_get_fan_rpm},
- {"pwmgetkblight", cmd_pwm_get_keyboard_backlight},
- {"pwmgetnumfans", cmd_pwm_get_num_fans},
- {"pwmgetduty", cmd_pwm_get_duty},
- {"pwmsetfanrpm", cmd_pwm_set_fan_rpm},
- {"pwmsetkblight", cmd_pwm_set_keyboard_backlight},
- {"pwmsetduty", cmd_pwm_set_duty},
- {"rand", cmd_rand},
- {"readtest", cmd_read_test},
- {"reboot_ec", cmd_reboot_ec},
- {"rollbackinfo", cmd_rollback_info},
- {"rtcget", cmd_rtc_get},
- {"rtcgetalarm", cmd_rtc_get_alarm},
- {"rtcset", cmd_rtc_set},
- {"rtcsetalarm", cmd_rtc_set_alarm},
- {"rwhashpd", cmd_rw_hash_pd},
- {"rwsigaction", cmd_rwsig_action},
- {"rwsigstatus", cmd_rwsig_status},
- {"sertest", cmd_serial_test},
- {"stress", cmd_stress_test},
- {"port80flood", cmd_port_80_flood},
- {"switches", cmd_switches},
- {"temps", cmd_temperature},
- {"tempsinfo", cmd_temp_sensor_info},
- {"test", cmd_test},
- {"thermalget", cmd_thermal_get_threshold},
- {"thermalset", cmd_thermal_set_threshold},
- {"tpselftest", cmd_tp_self_test},
- {"tpframeget", cmd_tp_frame_get},
- {"tmp006cal", cmd_tmp006cal},
- {"tmp006raw", cmd_tmp006raw},
- {"uptimeinfo", cmd_uptimeinfo},
- {"usbchargemode", cmd_usb_charge_set_mode},
- {"usbmux", cmd_usb_mux},
- {"usbpd", cmd_usb_pd},
- {"usbpdmuxinfo", cmd_usb_pd_mux_info},
- {"usbpdpower", cmd_usb_pd_power},
- {"version", cmd_version},
- {"waitevent", cmd_wait_event},
- {"wireless", cmd_wireless},
- {NULL, NULL}
-};
-
-int main(int argc, char *argv[])
-{
- const struct command *cmd;
- int dev = 0;
- int interfaces = COMM_ALL;
- int i2c_bus = -1;
- char device_name[41] = CROS_EC_DEV_NAME;
- int rv = 1;
- int parse_error = 0;
- char *e;
- int i;
-
- BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS);
-
- while ((i = getopt_long(argc, argv, "?", long_opts, NULL)) != -1) {
- switch (i) {
- case '?':
- /* Unhandled option */
- parse_error = 1;
- break;
-
- case OPT_DEV:
- dev = strtoul(optarg, &e, 0);
- if (!*optarg || (e && *e)) {
- fprintf(stderr, "Invalid --dev\n");
- parse_error = 1;
- }
- break;
-
- case OPT_INTERFACE:
- if (!strcasecmp(optarg, "dev")) {
- interfaces = COMM_DEV;
- } else if (!strcasecmp(optarg, "lpc")) {
- interfaces = COMM_LPC;
- } else if (!strcasecmp(optarg, "i2c")) {
- interfaces = COMM_I2C;
- } else if (!strcasecmp(optarg, "servo")) {
- interfaces = COMM_SERVO;
- } else {
- fprintf(stderr, "Invalid --interface\n");
- parse_error = 1;
- }
- break;
- case OPT_NAME:
- strncpy(device_name, optarg, 40);
- device_name[40] = '\0';
- break;
- case OPT_I2C_BUS:
- i2c_bus = strtoul(optarg, &e, 0);
- if (*optarg == '\0' || (e && *e != '\0')
- || i2c_bus < 0) {
- fprintf(stderr, "Invalid --i2c_bus\n");
- parse_error = 1;
- }
- break;
- case OPT_ASCII:
- ascii_mode = 1;
- break;
- }
- }
-
- if (i2c_bus != -1) {
- if (!(interfaces & COMM_I2C)) {
- fprintf(stderr, "--i2c_bus is specified, but --interface is set to something other than I2C\n");
- parse_error = 1;
- } else {
- interfaces = COMM_I2C;
- }
- }
-
- /* Must specify a command */
- if (!parse_error && optind == argc)
- parse_error = 1;
-
- /* 'ectool help' prints help with commands */
- if (!parse_error && !strcasecmp(argv[optind], "help")) {
- print_help(argv[0], 1);
- exit(1);
- }
-
- /* Handle sub-devices command offset */
- if (dev > 0 && dev < 4) {
- set_command_offset(EC_CMD_PASSTHRU_OFFSET(dev));
- } else if (dev == 8) {
- /* Special offset for Fingerprint MCU */
- strcpy(device_name, "cros_fp");
- } else if (dev != 0) {
- fprintf(stderr, "Bad device number %d\n", dev);
- parse_error = 1;
- }
-
- if (parse_error) {
- print_help(argv[0], 0);
- exit(1);
- }
-
- /* Prefer /dev method, which supports built-in mutex */
- if (!(interfaces & COMM_DEV) || comm_init_dev(device_name)) {
- /* If dev is excluded or isn't supported, find alternative */
- if (acquire_gec_lock(GEC_LOCK_TIMEOUT_SECS) < 0) {
- fprintf(stderr, "Could not acquire GEC lock.\n");
- exit(1);
- }
- if (comm_init_alt(interfaces, device_name, i2c_bus)) {
- fprintf(stderr, "Couldn't find EC\n");
- goto out;
- }
- }
-
- if (comm_init_buffer()) {
- fprintf(stderr, "Couldn't initialize buffers\n");
- goto out;
- }
-
- /* Handle commands */
- for (cmd = commands; cmd->name; cmd++) {
- if (!strcasecmp(argv[optind], cmd->name)) {
- rv = cmd->handler(argc - optind, argv + optind);
- goto out;
- }
- }
-
- /* If we're still here, command was unknown */
- fprintf(stderr, "Unknown command '%s'\n\n", argv[optind]);
- print_help(argv[0], 0);
-
-out:
- release_gec_lock();
- return !!rv;
-}
diff --git a/util/ectool.h b/util/ectool.h
deleted file mode 100644
index c47edbf27c..0000000000
--- a/util/ectool.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2012 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.
- */
-
-/** @brief A handler for an `ectool` command. */
-struct command {
- /** The name of the command. */
- const char *name;
-
- /**
- * The function to handle the command.
- *
- * @param argc The length of `argv`
- * @param argv The arguments passed, including the command itself but
- * not 'ectool'.
- * @return 0 if successful, or a negative `enum ec_status` value.
- */
- int (*handler)(int argc, char *argv[]);
-};
-
-/**
- * Test low-level key scanning
- *
- * ectool keyscan <beat_us> <filename>
- *
- * <beat_us> is the length of a beat in microseconds. This indicates the
- * typing speed. Typically we scan at 10ms in the EC, so the beat period
- * will typically be 1-5ms, with the scan changing only every 20-30ms at
- * most.
- * <filename> specifies a file containing keys that are depressed on each
- * beat in the following format:
- *
- * <beat> <keys_pressed>
- *
- * <beat> is a beat number (0, 1, 2). The timestamp of this event will
- * be <start_time> + <beat> * <beat_us>.
- * <keys_pressed> is a (possibly empty) list of ASCII keys
- *
- * The key matrix is read from the fdt.
- */
-int cmd_keyscan(int argc, char *argv[]);
diff --git a/util/ectool_keyscan.c b/util/ectool_keyscan.c
deleted file mode 100644
index 5d1b77c2c6..0000000000
--- a/util/ectool_keyscan.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/* Copyright 2012 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.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <endian.h>
-
-#include "comm-host.h"
-#include "keyboard_config.h"
-#include "ectool.h"
-
-enum {
- /* Alloc this many more scans when needed */
- KEYSCAN_ALLOC_STEP = 64,
- KEYSCAN_MAX_TESTS = 10, /* Maximum number of tests supported */
- KEYSCAN_MAX_INPUT_LEN = 20, /* Maximum characters we can receive */
-};
-
-/* A single entry of the key matrix */
-struct matrix_entry {
- int row; /* key matrix row */
- int col; /* key matrix column */
- int keycode; /* corresponding linux key code */
-};
-
-struct keyscan_test_item {
- uint32_t beat; /* Beat number */
- uint8_t scan[KEYBOARD_COLS_MAX]; /* Scan data */
-};
-
-/* A single test, consisting of a list of key scans and expected ascii input */
-struct keyscan_test {
- char *name; /* name of test */
- char *expect; /* resulting input we expect to see */
- int item_count; /* number of items in data */
- int item_alloced; /* number of items alloced in data */
- struct keyscan_test_item *items; /* key data for EC */
-};
-
-/* A list of tests that we can run */
-struct keyscan_info {
- unsigned int beat_us; /* length of each beat in microseconds */
- struct keyscan_test tests[KEYSCAN_MAX_TESTS]; /* the tests */
- int test_count; /* number of tests */
- struct matrix_entry *matrix; /* the key matrix info */
- int matrix_count; /* number of keys in matrix */
-};
-
-/**
- * Read the key matrix from the device tree
- *
- * Keymap entries in the fdt take the form of 0xRRCCKKKK where
- * RR=Row CC=Column KKKK=Key Code
- *
- * @param keyscan keyscan information
- * @param path path to device tree file containing data
- * @return 0 if ok, -1 on error
- */
-static int keyscan_read_fdt_matrix(struct keyscan_info *keyscan,
- const char *path)
-{
- struct stat buf;
- uint32_t word;
- int upto;
- FILE *f;
- int err;
-
- /* Allocate memory for key matrix */
- if (stat(path, &buf)) {
- fprintf(stderr, "Cannot stat key matrix file '%s'\n", path);
- return -1;
- }
- keyscan->matrix_count = buf.st_size / 4;
- keyscan->matrix = calloc(keyscan->matrix_count,
- sizeof(*keyscan->matrix));
- if (!keyscan->matrix) {
- fprintf(stderr, "Out of memory for key matrix\n");
- return -1;
- }
-
- f = fopen(path, "rb");
- if (!f) {
- fprintf(stderr, "Cannot open key matrix file '%s'\n", path);
- return -1;
- }
-
- /* Now read the data */
- upto = err = 0;
- while (fread(&word, 1, sizeof(word), f) == sizeof(word)) {
- struct matrix_entry *matrix = &keyscan->matrix[upto++];
-
- word = be32toh(word);
- matrix->row = word >> 24;
- matrix->col = (word >> 16) & 0xff;
- matrix->keycode = word & 0xffff;
-
- /* Hard-code some sanity limits for now */
- if (matrix->row >= KEYBOARD_ROWS ||
- matrix->col >= KEYBOARD_COLS_MAX) {
- fprintf(stderr, "Matrix pos out of range (%d,%d)\n",
- matrix->row, matrix->col);
- fclose(f);
- return -1;
- }
- }
- fclose(f);
- if (!err && upto != keyscan->matrix_count) {
- fprintf(stderr, "Read mismatch from matrix file '%s'\n", path);
- err = -1;
- }
-
- return err;
-}
-
-/*
- * translate Linux's KEY_... values into ascii. We change space into 0xfe
- * since we use the numeric value (&32) for space. That avoids ambiguity
- * when we see a space in a key sequence file.
- */
-static const unsigned char kbd_plain_xlate[] = {
- 0xff, 0x1b, '1', '2', '3', '4', '5', '6',
- '7', '8', '9', '0', '-', '=', '\b', '\t', /* 0x00 - 0x0f */
- 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
- 'o', 'p', '[', ']', '\r', 0xff, 'a', 's', /* 0x10 - 0x1f */
- 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
- '\'', '`', 0xff, '\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */
- 'b', 'n', 'm', ',' , '.', '/', 0xff, 0xff, 0xff,
- 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 - 0x3f */
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
- '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */
- '2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x50 - 0x5F */
- '\r', 0xff, 0xff
-};
-
-/**
- * Add a new key to a scan
- *
- * Given a new key, this looks it up in the matrix and adds it to the scan,
- * so that if this scan were reported by the EC, the AP would the given key.
- *
- * The format of keys is a list of ascii characters, or & followed by a numeric
- * ascii value, or * followed by a numeric keycode value. Spaces are ignored
- * (use '*32' for space).
- *
- * Examples:
- * a - a
- * &20 - space
- * *58 - KEY_CAPSLOCK
- *
- * @param keyscan keyscan information
- * @param keysp point to the current key string on entry; on exit it
- * is updated to point to just after the string, plus any
- * following space
- * @param path path to device tree file containing data
- * @return 0 if ok, -1 on error
- */
-static int keyscan_add_to_scan(struct keyscan_info *keyscan, char **keysp,
- uint8_t scan[])
-{
- const uint8_t *pos;
- struct matrix_entry *matrix;
- int keycode = -1, i;
- char *keys = *keysp;
- int key = ' ';
-
- if (*keys == '&') {
- /* Numeric ascii code */
- keys++;
- key = strtol(keys, &keys, 10);
- if (!key || keys == *keysp) {
- fprintf(stderr, "Invalid numeric ascii\n");
- return -1;
- }
- if (*keys == ' ')
- keys++;
- else if (*keys) {
- fprintf(stderr, "Expect space after numeric ascii\n");
- return -1;
- }
- } else if (*keys == '*') {
- /* Numeric ascii code */
- keys++;
- keycode = strtol(keys, &keys, 10);
- if (!keycode || keys == *keysp) {
- fprintf(stderr, "Invalid numeric keycode\n");
- return -1;
- }
- if (*keys == ' ')
- keys++;
- else if (*keys) {
- fprintf(stderr, "Expect space after num. keycode\n");
- return -1;
- }
- } else {
- key = *keys++;
- }
-
- /* Convert keycode to key if needed */
- if (keycode == -1) {
- pos = strchr(kbd_plain_xlate, key);
- if (!pos) {
- fprintf(stderr, "Key '%c' not found in xlate table\n",
- key);
- return -1;
- }
- keycode = pos - kbd_plain_xlate;
- }
-
- /* Look up keycode in matrix */
- for (i = 0, matrix = keyscan->matrix; i < keyscan->matrix_count;
- i++, matrix++) {
- if (matrix->keycode == keycode) {
-#ifdef DEBUG
- printf("%d: %d,%d\n", matrix->keycode, matrix->row,
- matrix->col);
-#endif
- scan[matrix->col] |= 1 << matrix->row;
- *keysp = keys;
- return 0;
- }
- }
- fprintf(stderr, "Key '%c' (keycode %d) not found in matrix\n", key,
- keycode);
-
- return -1;
-}
-
-/**
- * Add a new keyscan to the given test
- *
- * This processes a new keyscan, consisting of a beat number and a sequence
- * of keys.
- *
- * The format of keys is a beat number followed by a list of keys, each
- * either ascii characters, or & followed by a numeric ascii value, or *
- * followed by a numeric keycode value. Spaces are ignored (use '*32' for
- * space).
- *
- * Examples:
- * 0 abc - beat 0, press a, b and c
- * 4 a &20 - beat 4, press a and space
- * 8 *58 &13 - beat 8, press KEY_CAPSLOCK
- *
- * @param keyscan keyscan information
- * @param linenum line number we are reading from (for error reporting)
- * @param test test to add this scan to
- * @param keys key string to process
- * @return 0 if ok, -1 on error
- */
-static int keyscan_process_keys(struct keyscan_info *keyscan, int linenum,
- struct keyscan_test *test, char *keys)
-{
- struct keyscan_test_item *item;
- unsigned long int beat;
-
- /* Allocate more items if needed */
- if (!test->item_alloced || test->item_count == test->item_alloced) {
- int size, new_size;
-
- size = test->item_alloced * sizeof(struct keyscan_test_item);
- new_size = size + KEYSCAN_ALLOC_STEP *
- sizeof(struct keyscan_test_item);
- test->items = realloc(test->items, new_size);
- if (!test->items) {
- fprintf(stderr, "Out of memory realloc()\n");
- return -1;
- }
- memset((char *)test->items + size, '\0', new_size - size);
- test->item_alloced += KEYSCAN_ALLOC_STEP;
- new_size = size;
- }
-
- /* read the beat number */
- item = &test->items[test->item_count];
- beat = strtol(keys, &keys, 10);
- item->beat = beat;
-
- /* Read keys and add them to our scan */
- if (*keys == ' ') {
- keys++;
- while (*keys) {
- if (keyscan_add_to_scan(keyscan, &keys, item->scan)) {
- fprintf(stderr, "Line %d: Cannot parse"
- " key input '%s'\n", linenum,
- keys);
- return -1;
- }
- }
- } else if (*keys) {
- fprintf(stderr, "Line %d: Need space after beat\n",
- linenum);
- return -1;
- }
- test->item_count++;
-
- return 0;
-}
-
-/* These are the commands we understand in a key sequence file */
-enum keyscan_cmd {
- KEYSCAN_CMD_TEST, /* start a new test */
- KEYSCAN_CMD_ENDTEST, /* end a test */
- KEYSCAN_CMD_SEQ, /* add a keyscan to a test sequence */
- KEYSCAN_CMD_EXPECT, /* indicate what input is expected */
-
- KEYSCAN_CMD_COUNT
-};
-
-/* Names for each of the keyscan commands */
-static const char *keyscan_cmd_name[KEYSCAN_CMD_COUNT] = {
- "test",
- "endtest",
- "seq",
- "expect",
-};
-
-/**
- * Read a command from a string and return it
- *
- * @param str String containing command
- * @param len Length of command string
- * @return detected command, or -1 if none
- */
-static enum keyscan_cmd keyscan_read_cmd(const char *str, int len)
-{
- int i;
-
- for (i = 0; i < KEYSCAN_CMD_COUNT; i++) {
- if (!strncmp(keyscan_cmd_name[i], str, len))
- return i;
- }
-
- return -1;
-}
-
-/**
- * Process a key sequence file a build up a list of tets from it
- *
- * @param f File containing keyscan info
- * @param keyscan keyscan information
- * @return 0 if ok, -1 on error
- */
-static int keyscan_process_file(FILE *f, struct keyscan_info *keyscan)
-{
- struct keyscan_test *cur_test;
- char line[256];
- char *str;
- int linenum;
-
- keyscan->test_count = 0;
-
- linenum = 0;
- cur_test = NULL;
- while (str = fgets(line, sizeof(line), f), str) {
- char *args, *end;
- int cmd, len;
-
- linenum++;
- len = strlen(str);
-
- /* chomp the trailing newline */
- if (len > 0 && str[len - 1] == '\n') {
- len--;
- str[len] = '\0';
- }
-
- /* deal with blank lines and comments */
- if (!len || *str == '#')
- continue;
-
- /* get the command */
- for (end = str; *end && *end != ' '; end++)
- ;
-
- cmd = keyscan_read_cmd(str, end - str);
- args = end + (*end != '\0');
- switch (cmd) {
- case KEYSCAN_CMD_TEST:
- /* Start a new test */
- if (keyscan->test_count == KEYSCAN_MAX_TESTS) {
- fprintf(stderr, "KEYSCAN_MAX_TESTS "
- "exceeded\n");
- return -1;
- }
- cur_test = &keyscan->tests[keyscan->test_count];
- cur_test->name = strdup(args);
- if (!cur_test->name) {
- fprintf(stderr, "Line %d: out of memory\n",
- linenum);
- }
- break;
- case KEYSCAN_CMD_EXPECT:
- /* Get expect string */
- if (!cur_test) {
- fprintf(stderr, "Line %d: expect should be "
- "inside test\n", linenum);
- return -1;
- }
- cur_test->expect = strdup(args);
- if (!cur_test->expect) {
- fprintf(stderr, "Line %d: out of memory\n",
- linenum);
- }
- break;
- case KEYSCAN_CMD_ENDTEST:
- /* End of a test */
- keyscan->test_count++;
- cur_test = NULL;
- break;
- case KEYSCAN_CMD_SEQ:
- if (keyscan_process_keys(keyscan, linenum, cur_test,
- args)) {
- fprintf(stderr, "Line %d: Cannot parse key "
- "input '%s'\n", linenum, args);
- return -1;
- }
- break;
- default:
- fprintf(stderr, "Line %d: Uknown command '%1.*s'\n",
- linenum, (int)(end - str), str);
- return -1;
- }
- }
-
- return 0;
-}
-
-/**
- * Print out a list of all tests
- *
- * @param keyscan keyscan information
- */
-static void keyscan_print(struct keyscan_info *keyscan)
-{
- int testnum;
- int i;
-
- for (testnum = 0; testnum < keyscan->test_count; testnum++) {
- struct keyscan_test *test = &keyscan->tests[testnum];
-
- printf("Test: %s\n", test->name);
- for (i = 0; i < test->item_count; i++) {
- struct keyscan_test_item *item;
- int j;
-
- item = &test->items[i];
- printf("%2d %7d: ", i, item->beat);
- for (j = 0; j < sizeof(item->scan); j++)
- printf("%02x ", item->scan[j]);
- printf("\n");
- }
- printf("\n");
- }
-}
-
-/**
- * Set the terminal to raw mode, or cooked
- *
- * @param tty_fd Terminal file descriptor to change
- * @Param raw 0 for cooked, non-zero for raw
- */
-static void set_to_raw(int tty_fd, int raw)
-{
- struct termios tty_attr;
- int value;
-
- value = fcntl(tty_fd, F_GETFL);
-
- tcgetattr(tty_fd, &tty_attr);
- if (raw) {
- tty_attr.c_lflag &= ~ICANON;
- value |= O_NONBLOCK;
- } else {
- tty_attr.c_lflag |= ICANON;
- value &= ~O_NONBLOCK;
- }
- tcsetattr(tty_fd, TCSANOW, &tty_attr);
- fcntl(tty_fd, F_SETFL, value);
-}
-
-/**
- * Read input for a whlie until wee see no more
- *
- * @param fd File descriptor for input
- * @param input Place to put input string
- * @param max_len Maximum length of input string
- * @param wait Number of microseconds to wait for input
- */
-static void keyscan_get_input(int fd, char *input, int max_len, int wait)
-{
- int len;
-
- usleep(wait);
- input[0] = '\0';
- len = read(fd, input, max_len - 1);
- if (len > 0)
- input[len] = '\0';
-}
-
-static int keyscan_send_sequence(struct keyscan_info *keyscan,
- struct keyscan_test *test)
-{
- struct ec_params_keyscan_seq_ctrl *req;
- struct keyscan_test_item *item;
- int upto, size, rv;
-
- size = sizeof(*req) + sizeof(item->scan);
- req = (struct ec_params_keyscan_seq_ctrl *)malloc(size);
- if (!req) {
- fprintf(stderr, "Out of memory for message\n");
- return -1;
- }
- for (upto = rv = 0, item = test->items; rv >= 0 &&
- upto < test->item_count; upto++, item++) {
- req->cmd = EC_KEYSCAN_SEQ_ADD;
- req->add.time_us = item->beat * keyscan->beat_us;
- memcpy(req->add.scan, item->scan, sizeof(item->scan));
- rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, req, size, NULL, 0);
- }
- free(req);
- if (rv < 0)
- return rv;
-
- return 0;
-}
-
-/**
- * Run a single test
- *
- * @param keyscan keyscan information
- * @param test test to run
- * @return 0 if test passes, -ve if some error occurred
- */
-static int run_test(struct keyscan_info *keyscan, struct keyscan_test *test)
-{
- struct ec_params_keyscan_seq_ctrl ctrl;
- char input[KEYSCAN_MAX_INPUT_LEN];
- struct ec_result_keyscan_seq_ctrl *resp;
- int wait_us;
- int size;
- int rv;
- int fd = 0;
- int i;
-
- /* First clear the sequence */
- ctrl.cmd = EC_KEYSCAN_SEQ_CLEAR;
- rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl),
- NULL, 0);
- if (rv < 0)
- return rv;
-
- rv = keyscan_send_sequence(keyscan, test);
- if (rv < 0)
- return rv;
-
- /* Start it */
- set_to_raw(fd, 1);
- ctrl.cmd = EC_KEYSCAN_SEQ_START;
- rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl),
- NULL, 0);
- if (rv < 0)
- return rv;
-
- /* Work out how long we need to wait */
- wait_us = 100 * 1000; /* Wait 100ms to at least */
- if (test->item_count) {
- struct keyscan_test_item *ksi;
-
- ksi = &test->items[test->item_count - 1];
- wait_us += ksi->beat * keyscan->beat_us;
- }
-
- /* Wait for input */
- keyscan_get_input(fd, input, sizeof(input), wait_us);
- set_to_raw(fd, 0);
-
- /* Ask EC for results */
- size = sizeof(*resp) + test->item_count;
- resp = malloc(size);
- if (!resp) {
- fprintf(stderr, "Out of memory for results\n");
- return -1;
- }
- ctrl.cmd = EC_KEYSCAN_SEQ_COLLECT;
- ctrl.collect.start_item = 0;
- ctrl.collect.num_items = test->item_count;
- rv = ec_command(EC_CMD_KEYSCAN_SEQ_CTRL, 0, &ctrl, sizeof(ctrl),
- resp, size);
- if (rv < 0)
- return rv;
-
- /* Check what scans were skipped */
- for (i = 0; i < resp->collect.num_items; i++) {
- struct ec_collect_item *item;
- struct keyscan_test_item *ksi;
-
- item = &resp->collect.item[i];
- ksi = &test->items[i];
- if (!(item->flags & EC_KEYSCAN_SEQ_FLAG_DONE))
- printf(" [skip %d at beat %u] ", i, ksi->beat);
- }
-
- if (strcmp(input, test->expect)) {
- printf("Expected '%s', got '%s' ", test->expect, input);
- return -1;
- }
-
- return 0;
-}
-
-/**
- * Run all tests
- *
- * @param keyscan keyscan information
- * @return 0 if ok, -1 on error
- */
-static int keyscan_run_tests(struct keyscan_info *keyscan)
-{
- int testnum;
- int any_err = 0;
-
- for (testnum = 0; testnum < keyscan->test_count; testnum++) {
- struct keyscan_test *test = &keyscan->tests[testnum];
- int err;
-
- fflush(stdout);
- err = run_test(keyscan, test);
- any_err |= err;
- if (err) {
- printf("%d: %s: : FAIL\n", testnum, test->name);
- }
- }
-
- return any_err ? -1 : 0;
-}
-
-int cmd_keyscan(int argc, char *argv[])
-{
- struct keyscan_info keyscan;
- FILE *f;
- int err;
-
- argc--;
- argv++;
- if (argc < 2) {
- fprintf(stderr, "Must specify beat period and filename\n");
- return -1;
- }
- memset(&keyscan, '\0', sizeof(keyscan));
- keyscan.beat_us = atoi(argv[0]);
- if (keyscan.beat_us < 100)
- fprintf(stderr, "Warning: beat period is normally > 100us\n");
- f = fopen(argv[1], "r");
- if (!f) {
- perror("Cannot open file\n");
- return -1;
- }
-
- /* TODO(crosbug.com/p/23826): Read key matrix from fdt */
- err = keyscan_read_fdt_matrix(&keyscan, "test/test-matrix.bin");
- if (!err)
- err = keyscan_process_file(f, &keyscan);
- if (!err)
- keyscan_print(&keyscan);
- if (!err)
- err = keyscan_run_tests(&keyscan);
- fclose(f);
-
- return err;
-}
diff --git a/util/export_taskinfo.c b/util/export_taskinfo.c
deleted file mode 100644
index 4c09bafb90..0000000000
--- a/util/export_taskinfo.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright 2017 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.
- *
- * The cmd_c_to_taskinfo will compile this file with different
- * section definitions to export different tasklists.
- */
-
-#include <stdint.h>
-
-#include "config.h"
-#include "task_id.h"
-
-#ifdef SECTION_IS_RO
-#define GET_TASKINFOS_FUNC get_ro_taskinfos
-#elif defined(SECTION_IS_RW)
-#define GET_TASKINFOS_FUNC get_rw_taskinfos
-#else
-#error "Current section (RO/RW) is not defined."
-#endif
-
-struct taskinfo {
- char *name;
- char *routine;
- uint32_t stack_size;
-};
-
-#define TASK(n, r, d, s, ...) { \
- .name = #n, \
- .routine = #r, \
- .stack_size = s, \
-},
-static const struct taskinfo taskinfos[] = {
- CONFIG_TASK_LIST
-};
-#undef TASK
-
-uint32_t GET_TASKINFOS_FUNC(const struct taskinfo **infos)
-{
- *infos = taskinfos;
- /* Calculate the number of tasks */
- return sizeof(taskinfos) / sizeof(*taskinfos);
-}
diff --git a/util/flash_ec b/util/flash_ec
deleted file mode 100755
index eb5a4d8af6..0000000000
--- a/util/flash_ec
+++ /dev/null
@@ -1,1439 +0,0 @@
-#!/bin/bash
-
-# Copyright 2014 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.
-
-SCRIPT="$(readlink -f "$0")"
-SCRIPT_DIR="$(dirname "$SCRIPT")"
-
-EC_DIR="$(readlink -f "${SCRIPT_DIR}/..")"
-if [[ "$(basename "${EC_DIR}")" != "ec" ]]; then
- EC_DIR=
-fi
-
-# Loads script libraries.
-. "/usr/share/misc/shflags" || exit 1
-
-# Redirects tput to stderr, and drop any error messages.
-tput2() {
- tput "$@" 1>&2 2>/dev/null || true
-}
-
-error() {
- tput2 bold && tput2 setaf 1
- echo "ERROR: $*" >&2
- tput2 sgr0
-}
-
-
-info() {
- tput2 bold && tput2 setaf 2
- echo "INFO: $*" >&2
- tput2 sgr0
-}
-
-warn() {
- tput2 bold && tput2 setaf 3
- echo "WARNING: $*" >&2
- tput2 sgr0
-}
-
-die() {
- [ -z "$*" ] || error "$@"
- exit 1
-}
-
-
-# Include a board name to the BOARDS_${EC_CHIP} array below ONLY IF servod is
-# not aware of its 'ec_chip'. If servod becomes able to answer 'ec_chip'
-# for the board, remove it from BOARDS_XXXX array below.
-BOARDS_IT83XX=(
- glkrvp_ite
- it83xx_evb
- reef_it8320
- tglrvpu_ite
- tglrvpy_ite
-)
-
-BOARDS_STM32=(
- bloonchipper
- chell_pd
- coffeecake
- chocodile_bec
- chocodile_vpdmcu
- dartmonkey
- glados_pd
- hatch_fp
- jerry
- magnemite
- masterball
- minimuffin
- nami_fp
- nocturne_fp
- oak_pd
- pit
- plankton
- rainier
- samus_pd
- staff
- strago_pd
- wand
- whiskers
- zinger
-)
-BOARDS_STM32_PROG_EN=(
- plankton
-)
-
-BOARDS_STM32_DFU=(
- dingdong
- hoho
- twinkie
- discovery
- servo_v4
- servo_micro
- sweetberry
- polyberry
- stm32f446e-eval
- tigertail
- fluffy
-)
-
-BOARDS_NPCX_5M5G_JTAG=(
- npcx_evb
- npcx_evb_arm
-)
-
-BOARDS_NPCX_5M6G_JTAG=(
-)
-
-BOARDS_NPCX_7M6X_JTAG=(
-)
-
-BOARDS_NPCX_7M7X_JTAG=(
- npcx7_evb
-)
-
-BOARDS_NPCX_SPI=(
- glkrvp
-)
-
-BOARDS_SPI_1800MV=(
- coral
- reef
-)
-
-BOARDS_RAIDEN=(
- coral
- eve
- fizz
- flapjack
- kukui
- nami
- nautilus
- poppy
- rammus
- reef
- scarlet
- soraka
-)
-
-DEFAULT_PORT="${SERVOD_PORT:-9999}"
-BITBANG_RATE="57600" # Could be overwritten by a command line option.
-
-# Flags
-DEFINE_integer bitbang_rate "${BITBANG_RATE}" \
- "UART baud rate to use when bit bang programming, "\
-"standard UART rates from 9600 to 57600 are supported."
-DEFINE_string board "${DEFAULT_BOARD}" \
- "The board to run debugger on."
-DEFINE_string chip "" \
- "The chip to run debugger on."
-DEFINE_string image "" \
- "Full pathname of the EC firmware image to flash."
-DEFINE_string logfile "" \
- "Stm32 only: pathname of the file to store communications log."
-DEFINE_string offset "0" \
- "Offset where to program the image from."
-DEFINE_integer port "${DEFAULT_PORT}" \
- "Port to communicate to servo on."
-DEFINE_boolean raiden "${FLAGS_FALSE}" \
- "Use raiden_debug_spi programmer"
-DEFINE_string read "" "Pathname of the file to store EC firmware image."
-DEFINE_boolean ro "${FLAGS_FALSE}" \
- "Write only the read-only partition"
-DEFINE_boolean servo_micro_uart_rx_rework "${FLAGS_FALSE}" \
- "The servo micro for flashing has b/143163043#comment3 rework"
-DEFINE_integer timeout 600 \
- "Timeout for flashing the EC, measured in seconds."
-DEFINE_boolean verbose "${FLAGS_FALSE}" \
- "Verbose hw control logging"
-DEFINE_boolean verify "${FLAGS_FALSE}" \
- "Verify EC firmware image after programming."
-
-# Parse command line
-FLAGS_HELP="usage: $0 [flags]"
-FLAGS "$@" || exit 1
-eval set -- "${FLAGS_ARGV}"
-if [[ $# -gt 0 ]]; then
- die "invalid arguments: \"$*\""
-fi
-
-# Error messages
-MSG_PROGRAM_FAIL="Failed to flash EC firmware image"
-MSG_READ_FAIL="Failed to read EC firmware image"
-MSG_VERIFY_FAIL="Failed to verify EC firmware image."
-
-set -e
-
-DUT_CONTROL_CMD=( "dut-control" "--port=${FLAGS_port}" )
-DUT_CTRL_PREFIX=""
-
-function dut_control() {
- local DUT_CTRL_CML=( "${DUT_CONTROL_CMD[@]}" )
-
- for p in $@ ; do
- # Only add the prefix if the arg is a control name.
- if [[ ${p} != -* ]] ; then
- p="${DUT_CTRL_PREFIX}${p}"
- fi
- DUT_CTRL_CML+=( "$p" )
- done
-
- if [ "${FLAGS_verbose}" = ${FLAGS_TRUE} ]; then
- echo "${DUT_CTRL_CML[*]}" 1>&2
- fi
-
- "${DUT_CTRL_CML[@]}" >/dev/null
-}
-
-function dut_control_or_die {
- dut_control "$@" || die "dut-control $* exited $? (non-zero)"
-}
-
-function dut_control_get() {
- if [ $# -gt 1 ]; then
- error "${FUNCNAME[0]} failed: more than one argument: $@"
- return 1
- fi
-
- local ARGS DUT_GETVAL RETVAL
- ARGS=( "${DUT_CONTROL_CMD[@]}" "-o" "${DUT_CTRL_PREFIX}$1" )
- RETVAL=0
- # || statement is attached to avoid an exit if error exit is enabled.
- DUT_GETVAL=$( "${ARGS[@]}" ) || RETVAL="$?"
- if (( "${RETVAL}" )) ; then
- warn "${FUNCNAME[0]} failed: ${ARGS[*]} returned ${RETVAL}."
- return "${RETVAL}"
- fi
-
- echo "${DUT_GETVAL}"
-}
-
-BOARD=${FLAGS_board}
-
-in_array() {
- local n=$#
- local value=${!n}
-
- for (( i=1; i<$#; i++ )) do
- if [ "${!i}" == "${value}" ]; then
- return 0
- fi
- done
- return 1
-}
-
-declare -a SUPPORTED_CHIPS
-
-if $(in_array "${BOARDS_STM32[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("stm32")
-fi
-
-if $(in_array "${BOARDS_STM32_DFU[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("stm32_dfu")
-fi
-
-if $(in_array "${BOARDS_NPCX_5M5G_JTAG[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("npcx_5m5g_jtag")
-fi
-
-if $(in_array "${BOARDS_NPCX_5M6G_JTAG[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("npcx_5m6g_jtag")
-fi
-
-if $(in_array "${BOARDS_NPCX_7M6X_JTAG[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("npcx_7m6x_jtag")
-fi
-
-if $(in_array "${BOARDS_NPCX_7M7X_JTAG[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("npcx_7m7x_jtag")
-fi
-
-if $(in_array "${BOARDS_NPCX_SPI[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("npcx_spi")
-fi
-
-if $(in_array "${BOARDS_IT83XX[@]}" "${BOARD}"); then
- SUPPORTED_CHIPS+=("it83xx")
-fi
-
-if [[ ${#SUPPORTED_CHIPS[@]} -eq 0 && -n "${FLAGS_chip}" ]]; then
- SUPPORTED_CHIPS+="${FLAGS_chip}"
-fi
-
-if [[ ${#SUPPORTED_CHIPS[@]} -eq 0 ]]; then
- SERVO_EC_CHIP="$(dut_control_get ec_chip)"
- SERVO_EC_CHIP="${SERVO_EC_CHIP,,}"
- if [[ "${SERVO_EC_CHIP}" =~ "unknown" || -z "${SERVO_EC_CHIP}" ]]; then
- die "Please check that servod is running or," \
- "manually specify either --board or --chip."
- fi
- SUPPORTED_CHIPS+=("${SERVO_EC_CHIP}")
-fi
-
-if [[ ${#SUPPORTED_CHIPS[@]} -eq 0 ]]; then
- # This happens if ${FLAGS_board} is not known in this flash_ec yet,
- # ${FLAGS_chip} is not given, and servod doesn't know ec_chip.
- # In this case, '--chip' should be specified in the command line.
- die "board '${BOARD}' not supported." \
- "Please check that servod is running, or manually specify --chip."
-elif [[ ${#SUPPORTED_CHIPS[@]} -eq 1 ]]; then
- CHIP="${SUPPORTED_CHIPS[0]}"
-elif [ -n "${FLAGS_chip}" ]; then
- if $(in_array "${SUPPORTED_CHIPS[@]}" "${FLAGS_chip}"); then
- CHIP="${FLAGS_chip}"
- else
- die "board ${BOARD} only supports (${SUPPORTED_CHIPS[@]})," \
- "not ${FLAGS_chip}."
- fi
-else
- # Ideally, ec_chip per servo_type should be specified in servo overlay
- # file, instead of having multiple board-to-chip mapping info in this
- # script. Please refer to crrev.com/c/1496460 for example.
- die "board ${BOARD} supports multiple chips" \
- "(${FILTERED_CHIPS[@]}). Use --chip= to choose one."
-fi
-
-if [ -n "${FLAGS_chip}" -a "${CHIP}" != "${FLAGS_chip}" ]; then
- die "board ${BOARD} doesn't use chip ${FLAGS_chip}"
-fi
-
-if [[ "${CHIP}" = "stm32_dfu" ]]; then
- NEED_SERVO="no"
-fi
-
-# Servo variables management
-case "${BOARD}" in
- chocodile_bec ) MCU="usbpd" ;;
- oak_pd|samus_pd|strago_pd ) MCU="usbpd" ;;
- chell_pd|glados_pd ) MCU="usbpd" ;;
- bloonchipper|dartmonkey|hatch_fp|nami_fp|nocturne_fp ) MCU="usbpd" ;;
- dingdong|hoho|twinkie ) DUT_CONTROL_CMD=( "true" ); MCU="ec" ;;
- *) MCU="ec" ;;
-esac
-
-case "${CHIP}" in
- "stm32"|"npcx_spi"|"npcx_int_spi"|"it83xx"|"npcx_uut") ;;
- *)
- if [[ -n "${FLAGS_read}" ]]; then
- die "The flag is not yet supported on ${CHIP}."
- fi
-
- # If verification is not supported, then show a warning message.
- # Keep it running however.
- if [[ "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then
- warn "Ignoring '--verify'" \
- "since read is not supported on ${CHIP}."
- fi
- ;;
-esac
-
-SERVO_TYPE="$(dut_control_get servo_type || :)"
-if [[ ${SERVO_TYPE} =~ servo_v4_with_.*_and_.* ]] ; then
- # If there are two devices, servo v4 type will show both devices. The
- # default device is first. The other device is second.
- # servo_type:servo_v4_with_servo_micro_and_ccd_cr50
- SECOND_DEVICE="${SERVO_TYPE#*_and_}"
- ACTIVE_DEVICE="$(dut_control_get active_v4_device || :)"
- SERVO_TYPE="servo_v4_with_${ACTIVE_DEVICE}"
- # Controls sent through the default device don't have a prefix. The
- # second device controls do. If the default device isn't active, we
- # need to use the second device controls to send commands. Use the
- # prefix for all dut control commands.
- if [[ "${SECOND_DEVICE}" = "${ACTIVE_DEVICE}" ]] ; then
- DUT_CTRL_PREFIX="${ACTIVE_DEVICE}."
- fi
-fi
-
-servo_has_warm_reset() {
- dut_control -i warm_reset >/dev/null 2>&1
-}
-
-servo_has_cold_reset() {
- dut_control -i cold_reset >/dev/null 2>&1
-}
-
-servo_has_dut_i2c_mux() {
- dut_control -i dut_i2c_mux >/dev/null 2>&1
-}
-
-# reset the EC
-toad_ec_hard_reset() {
- if dut_control cold_reset 2>/dev/null ; then
- dut_control cold_reset:on
- dut_control cold_reset:off
- else
- info "you probably need to hard-reset your EC manually"
- fi
-}
-
-servo_ec_hard_reset_or_die() {
- dut_control_or_die cold_reset:on
- dut_control_or_die cold_reset:off
-}
-
-servo_ec_hard_reset() {
- dut_control cold_reset:on
- dut_control cold_reset:off
-}
-
-servo_usbpd_hard_reset() {
- dut_control usbpd_reset:on sleep:0.5 usbpd_reset:off
-}
-
-servo_sh_hard_reset() {
- dut_control sh_reset:on
- dut_control sh_reset:off
-}
-
-ccd_cr50_ec_hard_reset() {
- servo_ec_hard_reset
-}
-
-ec_reset() {
- stype=${SERVO_TYPE}
- if [[ "${SERVO_TYPE}" =~ "servo" ]] ; then
- stype=servo
- fi
-
- if [[ -n "${stype}" ]]; then
- eval ${stype}_${MCU}_hard_reset
- fi
-}
-
-# force the EC to boot in serial monitor mode
-toad_ec_boot0() {
- dut_control boot_mode:$1
-}
-
-ccd_ec_boot0() {
- info "Using CCD $2."
- dut_control ccd_ec_boot_mode_$2:$1
-}
-
-servo_micro_ec_boot0() {
- # Some devices (e.g. hatch) control the RX UART pin via an on-board
- # circuit that is controlled by the EC_FLASH_ODL pin. For those boards,
- # we want to continue to drive the EC_FLASH_ODL if they do not have the
- # servo micro rework listed below.
- if [[ "${FLAGS_servo_micro_uart_rx_rework}" == ${FLAGS_TRUE} ]]; then
- info "Servo micro $2 mode: $1 (using rx_rework)"
-
- # Setting the test point allows the EC_TX_SERVO_RX line
- # to be driven by the servo for 'on' value. 'off' value
- # lets the EC drive the EC_TX_SERVO_RX net.
- #
- # HW Rework (b/143163043#comment3):
- # - Disconnect U45.1 from ground
- # - Connected U45.1 to TP1 pad
- dut_control tp1:$1
- dut_control servo_micro_ec_boot_mode_$2:$1
- else
- info "Servo micro $2 mode: $1 (using FW_UP_L)"
- dut_control ec_boot_mode:$1
- fi
-}
-
-servo_ec_boot0() {
- dut_control ec_boot_mode:$1
-}
-
-servo_usbpd_boot0() {
- dut_control usbpd_boot_mode:$1
-}
-
-servo_micro_usbpd_boot0() {
- servo_usbpd_boot0 "$@"
-}
-
-servo_sh_boot0() {
- dut_control sh_boot_mode:$1
-}
-
-ec_switch_boot0() {
- on_value=$1
- # Enable programming GPIOs
- if $(in_array "${BOARDS_STM32_PROG_EN[@]}" "${BOARD}"); then
- servo_save_add "prog_en"
-
- dut_control prog_en:yes
- fi
- if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] ; then
- stype=ccd
- elif [[ "${SERVO_TYPE}" =~ "servo_micro" ]] ; then
- stype=servo_micro
- elif [[ "${SERVO_TYPE}" =~ "servo" ]] ; then
- stype=servo
- else
- stype=${SERVO_TYPE}
- if [[ "${SERVO_TYPE}" =~ "toad" ]] ; then
- if [[ "${on_value}" == "on" ]] ; then
- on_value="yes"
- else
- on_value="no"
- fi
- fi
- fi
- eval ${stype}_${MCU}_boot0 "${on_value}" $2
-}
-
-ec_enable_boot0() {
- ec_switch_boot0 "on" $1
-}
-
-ec_disable_boot0() {
- ec_switch_boot0 "off" $1
-}
-
-# Returns 0 on success (if on beaglebone)
-on_servov3() {
- grep -qs '^CHROMEOS_RELEASE_BOARD=beaglebone_servo' /etc/lsb-release
-}
-
-# Returns 0 on success (if raiden should be used instead of servo)
-error_reported= # Avoid double printing the error message.
-on_raiden() {
- if [[ "${SERVO_TYPE}" =~ "servo_v4" ]] || \
- [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] || \
- [[ "${SERVO_TYPE}" =~ "servo_micro" ]]; then
- return 0
- fi
- if [ -z "${BOARD}" ]; then
- [ "${FLAGS_raiden}" = ${FLAGS_TRUE} ] && return 0 || return 1
- fi
- if [ "${FLAGS_raiden}" = ${FLAGS_TRUE} ]; then
- if in_array "${BOARDS_RAIDEN[@]}" "${BOARD}"; then
- return 0
- fi
- if [ -z "${error_reported}" ]; then
- error_reported="y"
- die "raiden mode not supported on ${BOARD}" >&2
- fi
- fi
- return 1
-}
-
-declare -a DELETE_LIST # Array of file/dir names to delete at exit
-
-# Put back the servo and the system in a clean state at exit
-FROZEN_PIDS=""
-cleanup() {
- for pid in ${FROZEN_PIDS}; do
- info "Sending SIGCONT to process ${pid}!"
- kill -CONT "${pid}"
- done
-
- # Delete all files or directories in DELETE_LIST.
- for item in "${DELETE_LIST[@]}"; do
- if [[ -e "${item}" ]]; then
- rm -rf "${item}" &> /dev/null
- fi
- done
-
- if [ "${CHIP}" = "it83xx" ]; then
- if [ "${SERVO_TYPE}" = "servo_v2" ]; then
- info "Reinitializing ftdi_i2c interface"
- # Ask servod to close its FTDI I2C interface because it
- # could be open or closed at this point. Using
- # ftdii2c_cmd:close when it's already closed is okay,
- # however ftdii2c_cmd:open when it's already open
- # triggers an error.
- #
- # If there is a simple, reliable way to detect whether
- # servod FTDI I2C interface is open or closed, it would
- # be preferable to check and only re-initialize if it's
- # closed. Patches welcome.
- dut_control ftdii2c_cmd:close
- dut_control ftdii2c_cmd:init
- dut_control ftdii2c_cmd:open
- dut_control ftdii2c_cmd:setclock
- fi
-
- # Let the AP boot back up.
- if servo_has_warm_reset; then
- dut_control warm_reset:off
- fi
- fi
-
- servo_restore
-
- if [ "${CHIP}" = "stm32" -o "${CHIP}" = "npcx_uut" ]; then
- dut_control "${MCU}"_boot_mode:off
- fi
-
- if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]]; then
- dut_control ccd_ec_boot_mode_uut:off
- dut_control ccd_ec_boot_mode_bitbang:off
- fi
-
- if ! on_raiden || servo_has_cold_reset; then
- ec_reset
- fi
-}
-trap cleanup EXIT
-
-# Possible default EC images
-if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then
- EC_FILE=ec.RO.flat
-else
- EC_FILE=ec.bin
-fi
-
-LOCAL_BUILD=
-if [[ -n "${EC_DIR}" ]]; then
- if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then
- LOCAL_BUILD="${EC_DIR}/build/${BOARD}/RO/${EC_FILE}"
- else
- LOCAL_BUILD="${EC_DIR}/build/${BOARD}/${EC_FILE}"
- fi
-fi
-
-# Get baseboard from build system if present
-BASEBOARD=
-
-# We do not want to exit script if make call fails; we turn -e back on after
-# setting BASEBOARD
-set +e
-if [[ -n "${EC_DIR}" ]]; then
- BASEBOARD=$(make --quiet -C ${EC_DIR} BOARD=${BOARD} print-baseboard \
- 2>/dev/null)
-elif [[ -d "${HOME}/trunk/src/platform/ec" ]]; then
- BASEBOARD=$(make --quiet -C ${HOME}/trunk/src/platform/ec \
- BOARD=${BOARD} print-baseboard 2>/dev/null)
-else
- info "Could not find ec build folder to calculate baseboard."
-fi
-if [ $? -ne 0 ]; then
- info "EC build system didn't recognize ${BOARD}. Assuming no baseboard."
-fi
-set -e
-
-if [[ -n "${BASEBOARD}" ]]; then
- EMERGE_BUILD=/build/${BASEBOARD}/firmware/${BOARD}/${EC_FILE}
-else
- EMERGE_BUILD=/build/${BOARD}/firmware/${EC_FILE}
-fi
-
-# Find the EC image to use
-function ec_image() {
- # No image specified on the command line, try default ones
- if [[ -n "${FLAGS_image}" ]] ; then
- if [ -f "${FLAGS_image}" ] || \
- [ "${FLAGS_image}" == "-" ]; then
- echo "${FLAGS_image}"
- return
- fi
- die "Invalid image path : ${FLAGS_image}"
- else
- if [ -f "${LOCAL_BUILD}" ]; then
- echo "${LOCAL_BUILD}"
- return
- fi
- if [ -f "${EMERGE_BUILD}" ]; then
- echo "${EMERGE_BUILD}"
- return
- fi
- fi
- die "no EC image found : build one or specify one."
-}
-
-# Find the EC UART provided by servo.
-function servo_ec_uart() {
- SERVOD_FAIL="Cannot communicate with servod. Is servod running?"
- PTY=$(dut_control_get raw_${MCU}_uart_pty ||
- dut_control_get ${MCU}_uart_pty)
- if [[ -z "${PTY}" ]]; then
- die "${SERVOD_FAIL}"
- fi
- echo $PTY
-}
-
-# Not every control is supported on every servo type. Therefore, define which
-# controls are supported by each servo type.
-servo_v2_VARS=( "cold_reset" )
-servo_micro_VARS=( "cold_reset" )
-servo_v4_with_ccd_cr50_VARS=( "cold_reset" )
-
-# Some servo boards use the same controls.
-servo_v3_VARS=( "${servo_v2_VARS[@]}" )
-servo_v4_with_servo_micro_VARS=( "${servo_micro_VARS[@]}" )
-toad_VARS=( "boot_mode" )
-
-declare -a save
-
-#######################################
-# Store DUT control value to restore.
-# Arguments:
-# $1: Control name
-# $2: (optional) Value to restore for the name at exit.
-#######################################
-function servo_save_add() {
- local CTRL_RESULT=
- case $# in
- 1) CTRL_RESULT="$( "${DUT_CONTROL_CMD[@]}" \
- "${DUT_CTRL_PREFIX}$@" )"
- if [[ -n "${CTRL_RESULT}" ]]; then
- # Don't save the control with the prefix, because
- # dut_control will add the prefix again when we restore
- # the settings.
- save+=( "${CTRL_RESULT#$DUT_CTRL_PREFIX}" )
- fi
- ;;
- 2) save+=( "$1:$2" )
- ;;
- *) die "${FUNCNAME[0]} failed: arguments error"
- ;;
- esac
-}
-
-function servo_save() {
- local SERVO_VARS_NAME="${SERVO_TYPE}_VARS[@]"
- for ctrl in "${!SERVO_VARS_NAME}"; do
- servo_save_add "${ctrl}"
- done
-
- if [[ "${SERVO_TYPE}" == "servo_v2" ]]; then
- servo_save_add "i2c_mux_en"
- servo_save_add "i2c_mux"
-
- dut_control i2c_mux_en:on
- dut_control i2c_mux:remote_adc
- fi
-}
-
-function servo_restore() {
- info "Restoring servo settings..."
- for ctrl in "${save[@]}"; do
- if [[ -n "${ctrl}" ]]; then
- dut_control "${ctrl}"
- fi
- done
-}
-
-function claim_pty() {
- if grep -q cros_sdk /proc/1/cmdline; then
- die "You must run this tool in a chroot that was entered with" \
- "'cros_sdk --no-ns-pid' (see crbug.com/444931 for details)"
- fi
-
- if [[ -z "$1" ]]; then
- warn "No parameter passed to claim_pty()"
- return
- fi
-
- # Disconnect the EC-3PO interpreter from the UART since it will
- # interfere with flashing.
- servo_save_add "${MCU}_ec3po_interp_connect"
-
- dut_control ${MCU}_ec3po_interp_connect:off || \
- warn "hdctools cannot disconnect the EC-3PO interpreter from" \
- "the UART."
-
- pids=$(lsof -FR 2>/dev/null -- $1 | tr -d 'pR')
- FROZEN_PIDS=""
-
- # reverse order to SIGSTOP parents before children
- for pid in $(echo ${pids} | tac -s " "); do
- if ps -o cmd= "${pid}" | grep -qE "(servod|/sbin/init)"; then
- info "Skip stopping servod or init: process ${pid}."
- else
- info "Sending SIGSTOP to process ${pid}!"
- FROZEN_PIDS+=" ${pid}"
- sleep 0.02
- kill -STOP ${pid}
- fi
- done
-}
-
-function get_serial() {
- if [[ "${SERVO_TYPE}" =~ "servo_v4_with_servo_micro" ]]; then
- if [[ -z "${BOARD}" ]]; then
- sn_ctl="servo_micro_"
- else
- sn_ctl="servo_micro_for_${BOARD}_"
- fi
- elif [[ "${SERVO_TYPE}" =~ "_with_ccd" ]] ; then
- sn_ctl="ccd_"
- else
- # If it's none of the above, the main serialname will do.
- sn_ctl=""
- fi
-
- dut_control_get "${sn_ctl}serialname"
-}
-
-# Board specific flashing scripts
-
-# helper function for using servo v2/3 with openocd
-function flash_openocd() {
- OCD_CFG="servo.cfg"
- if [[ -z "${EC_DIR}" ]]; then
- # check if we're on beaglebone
- if [[ -e "/usr/share/ec-devutils" ]]; then
- OCD_PATH="/usr/share/ec-devutils"
- else
- die "Cannot locate openocd configs"
- fi
- else
- OCD_PATH="${EC_DIR}/util/openocd"
- fi
-
- servo_save_add "jtag_buf_on_flex_en"
- servo_save_add "jtag_buf_en"
-
- dut_control jtag_buf_on_flex_en:on
- dut_control jtag_buf_en:on
-
- sudo timeout -k 10 -s 9 "${FLAGS_timeout}" \
- openocd -s "${OCD_PATH}" -f "${OCD_CFG}" -f "${OCD_CHIP_CFG}" \
- -c "${OCD_CMDS}" || \
- die "Failed to program ${IMG}"
-}
-
-# helper function for using servo with flashrom
-function flash_flashrom() {
- TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH:/usr/sbin"
- FLASHROM=$(PATH="${TOOL_PATH}" which flashrom)
-
- if on_servov3; then
- FLASHROM_ARGS="-p linux_spi"
- elif on_raiden; then
- if [[ "${SERVO_TYPE}" =~ "servo_micro" ]]; then
- # Servo micro doesn't use the "target" parameter.
- FLASHROM_ARGS="-p raiden_debug_spi:"
- else
- FLASHROM_ARGS="-p raiden_debug_spi:target=EC,"
- fi
- else
- FLASHROM_ARGS="-p ft2232_spi:type=servo-v2,port=B,"
- fi
-
- if [ ! -x "$FLASHROM" ]; then
- die "no flashrom util found."
- fi
-
- if ! on_servov3; then
- SERIALNAME=$(get_serial)
- if [[ "$SERIALNAME" != "" ]] ; then
- FLASHROM_ARGS+="serial=${SERIALNAME}"
- fi
- fi
-
- if ! on_raiden || [[ "${SERVO_TYPE}" =~ "servo_micro" ]] ; then
- if $(in_array "${BOARDS_SPI_1800MV[@]}" "${BOARD}"); then
- SPI_VOLTAGE="pp1800"
- else
- SPI_VOLTAGE="pp3300"
- fi
-
- dut_control cold_reset:on
-
- # If spi flash is in npcx's ec, enable gang programer mode
- if [[ "${CHIP}" == "npcx_int_spi" ]]; then
- servo_save_add "fw_up" "off"
-
- # Set GP_SEL# as low then start ec
- dut_control fw_up:on
- sleep 0.1
- dut_control cold_reset:off
- fi
-
- servo_save_add "spi1_vref" "off"
- servo_save_add "spi1_buf_en" "off"
-
- # Turn on SPI1 interface on servo for SPI Flash Chip
- dut_control spi1_vref:${SPI_VOLTAGE} spi1_buf_en:on
- if [[ ! "${SERVO_TYPE}" =~ "servo_micro" ]]; then
- # Servo micro doesn't support this control.
- servo_save_add "spi1_buf_on_flex_en" "off"
- dut_control spi1_buf_on_flex_en:on
- fi
- else
- if [[ "${CHIP}" == "npcx_int_spi" ]]; then
- servo_save_add "fw_up" "off"
-
- # Set GP_SEL# as low then start ec
- dut_control cold_reset:on
- dut_control fw_up:on
- # sleep 0.1
- dut_control cold_reset:off
- else
- # Assert EC reset.
- dut_control cold_reset:on
- fi
-
- # Temp layout
- L=/tmp/flash_spi_layout_$$
- DELETE_LIST+=( "${L}" )
-
- [[ -z "${FLAGS_read}" ]] && dump_fmap -F "${IMG}" > "${L}"
-
- FLASHROM_OPTIONS="-i EC_RW -i WP_RO -l "${L}" --ignore-fmap"
- FLASHROM_OPTIONS+=" --fast-verify"
- fi
-
- # Generate the correct flashrom command base.
- FLASHROM_CMDLINE="${FLASHROM} ${FLASHROM_ARGS}"
- if [[ -z "${FLAGS_read}" ]]; then
- # Program EC image.
- # flashrom should report the image size at the end of the output.
- local FLASHROM_GETSIZE="sudo ${FLASHROM_CMDLINE} --get-size"
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- info "Running flashrom:" 1>&2
- echo " ${FLASHROM_GETSIZE}" 1>&2
- fi
- SPI_SIZE=$(${FLASHROM_GETSIZE} 2>/dev/null |\
- grep -oe '[0-9]\+$') || \
- die "Failed to determine chip size!"
- [[ ${SPI_SIZE} -eq 0 ]] && die "Chip size is 0!"
-
- PATCH_SIZE=$((${SPI_SIZE} - ${IMG_SIZE}))
-
- # Temp image
- T=/tmp/flash_spi_$$
- DELETE_LIST+=( "${T}" )
-
- if [[ "${CHIP}" =~ ^npcx(|_int)_spi$ ]] ; then
- { # Patch temp image up to SPI_SIZE
- cat "$IMG"
- if [[ ${IMG_SIZE} -lt ${SPI_SIZE} ]] ; then
- dd if=/dev/zero bs=${PATCH_SIZE} count=1 | \
- tr '\0' '\377'
- fi
- } > $T
- else
- { # Patch temp image up to SPI_SIZE
- if [[ ${IMG_SIZE} -lt ${SPI_SIZE} ]] ; then
- dd if=/dev/zero bs=${PATCH_SIZE} count=1 | \
- tr '\0' '\377'
- fi
- cat "$IMG"
- } > $T
- fi
-
- info "Programming EC firmware image."
- local FLASHROM_WRITE="${FLASHROM_CMDLINE} ${FLASHROM_OPTIONS}"
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- info "Running flashrom:" 1>&2
- echo " ${FLASHROM_WRITE} -w ${T}" 1>&2
- fi
- sudo timeout -k 10 -s 9 "${FLAGS_timeout}" \
- ${FLASHROM_WRITE} -w "${T}" \
- || die "${MSG_PROGRAM_FAIL}"
- else
- # Read EC image.
- info "Reading EC firmware image."
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- info "Running flashrom:" 1>&2
- echo " ${FLASHROM_CMDLINE} -r ${FLAGS_read}" 1>&2
- fi
- sudo timeout -k 10 -s 9 "${FLAGS_timeout}" \
- ${FLASHROM_CMDLINE} -r "${FLAGS_read}" \
- || die "${MSG_READ_FAIL}"
- fi
- if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then
- # Verify EC image.
- info "Verifying EC firmware image."
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- info "Running flashrom:" 1>&2
- echo " ${FLASHROM_CMDLINE} -v ${T}" 1>&2
- fi
- sudo timeout -k 10 -s 9 "${FLAGS_timeout}" \
- ${FLASHROM_CMDLINE} -v "${T}" \
- || die "${MSG_VERIFY_FAIL}"
- fi
-}
-
-function flash_stm32() {
- local STM32MON
- local STM32MON_OPT
-
- if ! servo_has_cold_reset; then
- die "Cold reset must be available for STM32 programming"
- fi
-
- TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH"
- STM32MON=$(PATH="${TOOL_PATH}" which stm32mon)
- EC_UART="$(servo_ec_uart)"
- if [ ! -x "$STM32MON" ]; then
- die "no stm32mon util found."
- fi
-
- info "Using serial flasher : ${STM32MON}"
- info "${MCU} UART pty : ${EC_UART}"
- claim_pty ${EC_UART}
- STM32MON_OPT="-d ${EC_UART}"
-
- # Make sure EC reboots in serial monitor mode.
- ec_enable_boot0 "bitbang"
-
- # Pulse EC reset.
- ec_reset
-
- if ! on_raiden && [[ "${SERVO_TYPE}" =~ "servo" ]] ; then
- servo_save_add "${MCU}_uart_en"
-
- dut_control ${MCU}_uart_en:on
- fi
-
- servo_save_add "${MCU}_uart_parity"
-
- dut_control ${MCU}_uart_parity:even
-
- if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] ; then
- case "${FLAGS_bitbang_rate}" in
- (9600|19200|38400|57600) : ;;
- (*)
- die "${FLAGS_bitbang_rate} is not a valid" \
- "bit bang rate"
- ;;
- esac
- info "Programming at ${FLAGS_bitbang_rate} baud"
-
- servo_save_add "${MCU}_uart_baudrate"
- servo_save_add "${MCU}_uart_bitbang_en"
-
- dut_control ${MCU}_uart_baudrate:"${FLAGS_bitbang_rate}"
- dut_control ${MCU}_uart_bitbang_en:on
- else
- servo_save_add "${MCU}_uart_baudrate"
-
- dut_control ${MCU}_uart_baudrate:115200
- fi
-
- # Add a delay long enough for cr50 to update the ccdstate. Cr50 updates
- # ccdstate once a second, so a 2 second delay should be safe.
- if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] ; then
- sleep 2
- STM32MON_OPT+=" -c"
- fi
-
- if [ -n "${FLAGS_logfile}" ]; then
- info "Saving log in ${FLAGS_logfile}"
- STM32MON_OPT+=" -L ${FLAGS_logfile}"
- fi
-
- local IMG_READ="${FLAGS_read}"
- # Program EC image.
- if [[ -z "${IMG_READ}" ]]; then
- info "Programming EC firmware image."
- # Unprotect flash, erase, and write
- local STM32MON_COMMAND="${STM32MON} ${STM32MON_OPT} -u -e -w"
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- echo "${STM32MON_COMMAND} ${IMG}"
- fi
- timeout -k 10 -s 9 "${FLAGS_timeout}" \
- ${STM32MON_COMMAND} "${IMG}" \
- || die "${MSG_PROGRAM_FAIL}"
-
- # If it is a program-verify request, then make a temporary
- # directory to store the image
- if [[ "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then
- local TEMP_SUFFIX=".$(basename ${SCRIPT}).${CHIP}"
- local TEMP_DIR="$(mktemp -d --suffix="${TEMP_SUFFIX}")"
-
- IMG_READ="${TEMP_DIR}/ec.read.bin"
- DELETE_LIST+=( "${TEMP_DIR}" )
- fi
- fi
-
- # Read EC image.
- if [[ -n "${IMG_READ}" ]]; then
- info "Reading EC firmware image."
- local STM32MON_READ_CMD="${STM32MON} ${STM32MON_OPT} -U -r"
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- echo "${STM32MON_READ_CMD} ${IMG_READ}"
- fi
- timeout -k 10 -s 9 "${FLAGS_timeout}" \
- ${STM32MON_READ_CMD} "${IMG_READ}" \
- || die "${MSG_READ_FAIL}"
- fi
-
- # Verify the flash by comparing the source image to the read image,
- # only if it was a flash write request.
- if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then
- info "Verifying EC firmware image."
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- echo "cmp -n ${IMG_SIZE} ${IMG} ${IMG_READ}"
- fi
- cmp -s -n "${IMG_SIZE}" "${IMG}" "${IMG_READ}" \
- || die "${MSG_VERIFY_FAIL}"
- fi
-
- # Remove the Application processor reset
- # TODO(crosbug.com/p/30738): we cannot rely on servo_VARS to restore it
- if servo_has_warm_reset; then
- dut_control warm_reset:off
- fi
-}
-
-function flash_stm32_dfu() {
- DFU_DEVICE=0483:df11
- ADDR=0x08000000
- DFU_UTIL='dfu-util'
- which $DFU_UTIL &> /dev/null || die \
- "no dfu-util util found. Did you 'sudo emerge dfu-util'"
-
- info "Using dfu flasher : ${DFU_UTIL}"
-
- dev_cnt=$(lsusb -d $DFU_DEVICE | wc -l)
- if [ $dev_cnt -eq 0 ] ; then
- die "unable to locate dfu device at $DFU_DEVICE"
- elif [ $dev_cnt -ne 1 ] ; then
- die "too many dfu devices (${dev_cnt}). Disconnect all but one."
- fi
-
- SIZE=$(wc -c ${IMG} | cut -d' ' -f1)
- # Remove read protection
- sudo timeout -k 10 -s 9 "${FLAGS_timeout}" $DFU_UTIL -a 0 -d "${DFU_DEVICE}" \
- -s ${ADDR}:${SIZE}:force:unprotect -D "${IMG}"
- # Wait for mass-erase and reboot after unprotection
- sleep 1
- # Actual image flashing
- sudo timeout -k 10 -s 9 "${FLAGS_timeout}" $DFU_UTIL -a 0 -d "${DFU_DEVICE}" \
- -s ${ADDR}:${SIZE} -D "${IMG}"
-}
-
-# TODO(b/130165933): Implement a dut-control command to look up the correct
-# I2C adapter number, and use that here in place of the hack of looking at
-# I2C adapter names.
-function dut_i2c_dev() {
- if [ -n "$DUT_I2C_DEV" ]; then
- [ -e "$DUT_I2C_DEV" ] ||
- die "\$DUT_I2C_DEV is a non-existent path: $DUT_I2C_DEV"
- echo "$DUT_I2C_DEV"
- return
- fi
-
- if ! (
- set -e
- cd /sys/class/i2c-dev
- # Sorting in reverse numerical order generally picks the correct
- # servod I2C bus when there are multiple servos in line to the
- # DUT, e.g. servo_v4->servo_micro, or servo_v4->CR50 (CCD).
- for dev in $(ls | grep ^i2c- | sort -s -t- -n -k2,2 -r); do
- if grep -q servod "$dev"/name; then
- echo /dev/"$dev"
- exit
- fi
- done
- false
- ); then
- die "Could not find servo I2C adapter. This could be because "\
-"the i2c-pseudo module was not loaded when servod was started."
- fi
-}
-
-function flash_it83xx() {
- local TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH"
- local ITEFLASH_BIN=$(PATH="${TOOL_PATH}" which iteflash)
-
- if [[ ! -x "$ITEFLASH_BIN" ]]; then
- die "no iteflash util found."
- fi
-
- # Now the we have enabled the I2C mux on the servo to talk to the dut,
- # we need to switch the I2C mux on the dut to allow ec programing (if
- # there is a mux on the dut)
- if servo_has_dut_i2c_mux; then
- info "Switching DUT I2C Mux to ${CHIP}"
- servo_save_add "dut_i2c_mux"
- dut_control dut_i2c_mux:ec_prog
- fi
-
- # Ensure that the AP is off while we are flashing the EC via:
- # - warm_reset:on
- # - cold_reset:on
- # - cold_reset:off
- # ...reflash EC...
- # - warm_reset:off
- if servo_has_warm_reset; then
- dut_control_or_die warm_reset:on
- fi
- if servo_has_cold_reset; then
- servo_ec_hard_reset_or_die
- fi
-
- # Send the special waveform to the ITE EC.
- if [[ "${SERVO_TYPE}" =~ "servo_micro" ]]; then
- info "Asking Servo Micro to send the dbgr special waveform to "\
-"${CHIP}"
- dut_control_or_die enable_ite_dfu
- elif [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]]; then
- local CCD_I2C_CAP="$(dut_control_get ccd_i2c_en)"
- if [[ "${CCD_I2C_CAP,,}" != "always" ]]; then
- die "CCD I2C capability is not set as 'Always'" \
- ": ${CCD_I2C_CAP}"
- fi
-
- info "Asking CR50 to send the dbgr special waveform to ${CHIP}"
- sleep 2
- dut_control_or_die cr50_i2c_ctrl:ite_debugger_mode
- sleep 3
- elif [[ "${SERVO_TYPE}" == "servo_v2" ]]; then
- info "Closing servod connection to ftdi_i2c interface"
- dut_control_or_die ftdii2c_cmd:close
- else
- die "This servo type is not yet supported: ${SERVO_TYPE}"
- fi
-
- # Build the iteflash command line.
- local ITEFLASH_ARGS=( "${ITEFLASH_BIN}" )
-
- if [[ "${SERVO_TYPE}" == "servo_v2" ]]; then
- ITEFLASH_ARGS+=( "--send-waveform=1" "--i2c-interface=ftdi" )
- else
- ITEFLASH_ARGS=( "sudo" "--" "${ITEFLASH_ARGS[@]}" \
- "--send-waveform=0" "--i2c-interface=linux" \
- "--i2c-dev-path=$(dut_i2c_dev)" )
- if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]]; then
- ITEFLASH_ARGS+=( "--block-write-size=256" )
- fi
- fi
-
- local ERROR_MSG
- if [[ -n "${FLAGS_read}" ]]; then
- ITEFLASH_ARGS+=( "--read=${FLAGS_read}" )
- info "Reading EC firmware image using iteflash..."
- ERROR_MSG="${MSG_READ_FAIL}"
- else
- ITEFLASH_ARGS+=( "--erase" "--write=${IMG}" )
- info "Programming EC firmware image using iteflash..."
- ERROR_MSG="${MSG_PROGRAM_FAIL}"
- fi
-
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- ITEFLASH_ARGS+=( "--debug" )
- echo "${ITEFLASH_ARGS[@]}"
- fi
-
- "${ITEFLASH_ARGS[@]}" || die "${ERROR_MSG}"
-}
-
-function flash_lm4() {
- OCD_CHIP_CFG="lm4_chip.cfg"
- OCD_CMDS="init; flash_lm4 ${IMG} ${FLAGS_offset}; shutdown;"
-
- flash_openocd
-
-}
-
-function flash_nrf51() {
- OCD_CHIP_CFG="nrf51_chip.cfg"
- OCD_CMDS="init; flash_nrf51 ${IMG} ${FLAGS_offset}; exit_debug_mode_nrf51; shutdown;"
-
- flash_openocd
-
- # waiting 100us for the reset pulse is not necessary, it takes ~2.5ms
- dut_control swd_reset:on swd_reset:off
-}
-
-function flash_npcx_jtag() {
- IMG_PATH="${EC_DIR}/build/${BOARD}"
- OCD_CHIP_CFG="npcx_chip.cfg"
- if [ "${FLAGS_ro}" = ${FLAGS_TRUE} ] ; then
- # Program RO region only
- OCD_CMDS="init; flash_npcx_ro ${CHIP} ${IMG_PATH} ${FLAGS_offset}; shutdown;"
- else
- # Program all EC regions
- OCD_CMDS="init; flash_npcx_all ${CHIP} ${IMG_PATH} ${FLAGS_offset}; shutdown;"
- fi
-
- # Reset the EC
- ec_reset
-
- flash_openocd
-}
-
-function flash_npcx_uut() {
- local TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH"
- local NPCX_UUT=$(PATH="${TOOL_PATH}" which uartupdatetool)
- local EC_UART="$(servo_ec_uart)"
-
- # Look for npcx_monitor.bin in multiple directories, starting with
- # the same path as the EC binary.
- local MON=""
- for dir in \
- "$(dirname "$IMG")" \
- "${EC_DIR}/build/${BOARD}/chip/npcx/spiflashfw" \
- "$(dirname "$LOCAL_BUILD")" \
- "$(dirname "$EMERGE_BUILD")" ;
- do
- if [ -f "$dir/npcx_monitor.bin" ] ; then
- MON="$dir/npcx_monitor.bin"
- break
- fi
- done
- if [ -z "${MON}" ] ; then
- echo "Failed to find npcx_monitor.bin"
- exit 1
- fi
- info "Using NPCX image : ${MON}"
-
- # The start address to restore monitor firmware binary
- local MON_ADDR="0x200C3020"
-
- if [ ! -x "$NPCX_UUT" ]; then
- die "no NPCX UART Update Tool found."
- fi
-
- info "Using: NPCX UART Update Tool"
- info "${MCU} UART pty : ${EC_UART}"
- claim_pty ${EC_UART}
-
- if [[ "${SERVO_TYPE}" =~ "ccd_cr50" ]] ; then
- servo_save_add ccd_keepalive_en
- dut_control ccd_keepalive_en:on
- fi
-
- # Force the EC to boot in UART update mode
- ec_enable_boot0 "uut"
- ec_reset
-
- # Have to wait a bit for EC boot-up
- sleep 0.1
-
- # For CCD, disable the trigger pin for normal UART operation
- ec_disable_boot0 "uut"
- sleep 0.1
-
- # Remove the prefix "/dev/" because uartupdatetool will add it.
- local UUT_ARGS=( "--port=${EC_UART#/dev/}" " --baudrate=115200" )
- local IMG_READ="${FLAGS_read}"
-
- # Program EC image.
- if [[ -z "${IMG_READ}" ]]; then
- info "Loading monitor binary."
- local UUT_MON=( "${NPCX_UUT}" "${UUT_ARGS[@]}" \
- "--opr=wr" "--addr=${MON_ADDR}" \
- "--file=${MON}" )
-
- # Load monitor binary to address 0x200C3020
- if [[ "${FLAGS_verbose}" = ${FLAGS_TRUE} ]]; then
- echo "${UUT_MON[*]}"
- fi
- timeout -k 10 -s 9 "${FLAGS_timeout}" \
- "${UUT_MON[@]}" || die "Failed to load monitor binary."
-
- info "Programming EC firmware image."
- local UUT_WR=( "${NPCX_UUT}" "${UUT_ARGS[@]}" \
- "--auto" "--offset=${FLAGS_offset}" \
- "--file=${IMG}" )
- if [[ "${FLAGS_verbose}" = ${FLAGS_TRUE} ]]; then
- echo "${UUT_WR[*]}"
- fi
- timeout -k 10 -s 9 "${FLAGS_timeout}" \
- "${UUT_WR[@]}" || die "${MSG_PROGRAM_FAIL}"
-
- # If it is a program-verify request, then make a temporary
- # directory to store the image.
- if [[ "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then
- local TEMP_SUFFIX=".$(basename ${SCRIPT}).${CHIP}.$$"
- local TEMP_DIR="$(mktemp -d --suffix="${TEMP_SUFFIX}")"
-
- IMG_READ="${TEMP_DIR}/ec.read.bin"
- DELETE_LIST+=( "${TEMP_DIR}" )
- fi
- fi
-
- # Read EC image.
- if [[ -n "${IMG_READ}" ]]; then
- info "Reading EC firmware image."
-
- local UUT_RD=( "${NPCX_UUT}" "${UUT_ARGS[@]}" \
- "--read-flash" "--file=${IMG_READ}" )
-
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- echo "${UUT_RD[*]}"
- fi
- timeout -k 10 -s 9 "${FLAGS_timeout}" \
- "${UUT_RD[@]}" || die "${MSG_READ_FAIL}"
- fi
-
- # Verify the flash by comparing the source image to the read image,
- # only if it was a flash write request.
- if [[ -z "${FLAGS_read}" && "${FLAGS_verify}" == ${FLAGS_TRUE} ]]; then
- info "Verifying EC firmware image."
-
- if [[ "${FLAGS_verbose}" == ${FLAGS_TRUE} ]]; then
- echo "cmp -n ${IMG_SIZE} ${IMG} ${IMG_READ}"
- fi
-
- cmp -s -n "${IMG_SIZE}" "${IMG}" "${IMG_READ}" \
- || die "${MSG_VERIFY_FAIL}"
- fi
-}
-
-function flash_npcx_5m5g_jtag() {
- flash_npcx_jtag
-}
-
-function flash_npcx_5m6g_jtag() {
- flash_npcx_jtag
-}
-
-function flash_npcx_7m6x_jtag() {
- flash_npcx_jtag
-}
-
-function flash_npcx_7m7x_jtag() {
- flash_npcx_jtag
-}
-
-function flash_npcx_spi() {
- flash_flashrom
-}
-
-function flash_npcx_int_spi() {
- flash_flashrom
-}
-
-function flash_mec1322() {
- flash_flashrom
-}
-
-if dut_control boot_mode 2>/dev/null ; then
- if [[ "${MCU}" != "ec" ]] ; then
- die "Toad cable can't support non-ec UARTs"
- fi
- SERVO_TYPE=toad
- info "Using a dedicated debug cable"
-fi
-info "Using ${SERVO_TYPE}."
-
-# Only if it is a flash program request, call ec_image.
-if [[ -z "${FLAGS_read}" ]]; then
- IMG="$(ec_image)"
- info "Using ${MCU} image : ${IMG}"
- IMG_SIZE=$(stat -c%s "${IMG}")
-fi
-
-if [ "${NEED_SERVO}" != "no" ] ; then
- servo_save
-fi
-
-info "Flashing chip ${CHIP}."
-flash_${CHIP}
-info "Flashing done."
diff --git a/util/flash_fp_mcu b/util/flash_fp_mcu
deleted file mode 100644
index db9004c3f8..0000000000
--- a/util/flash_fp_mcu
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/bin/bash
-# Copyright 2019 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.
-
-. /usr/share/misc/shflags
-
-DEFINE_boolean 'read' "${FLAGS_FALSE}" 'Read instead of write' 'r'
-# Both flash read and write protection are removed by default, but you
-# can optionally enable them (for testing purposes).
-DEFINE_boolean 'remove_flash_read_protect' "${FLAGS_TRUE}" \
- 'Remove flash read protection while performing command' 'U'
-DEFINE_boolean 'remove_flash_write_protect' "${FLAGS_TRUE}" \
- 'Remove flash write protection while performing command' 'u'
-FLAGS_HELP="Usage: ${0} [flags] ec.bin"
-
-# Process commandline flags
-FLAGS "${@}" || exit 1
-eval set -- "${FLAGS_ARGV}"
-
-if [[ "$#" -eq 0 ]]; then
- echo "Missing filename"
- flags_help
- exit 1
-fi
-
-# print out canonical path to differentiate between /usr/local/bin and
-# /usr/bin installs
-echo "$(readlink -f "$0")"
-
-readonly CROS_EC_SPI_MODALIAS_STR="of:NcrfpTCgoogle,cros-ec-spi"
-
-check_hardware_write_protect_disabled() {
- local hardware_write_protect_state="$(crossystem wpsw_cur)"
- if [[ "${hardware_write_protect_state}" != "0" ]]; then
- echo "Please make sure hardware write protect is disabled."
- echo "See https://www.chromium.org/chromium-os/firmware-porting-guide/firmware-ec-write-protection"
- exit 1
- fi
-}
-
-# Get the spiid for the fingerprint sensor based on the modalias
-# string: https://crbug.com/955117
-get_spiid() {
- for dev in /sys/bus/spi/devices/*; do
- if [[ "$(cat "${dev}/modalias")" == "${CROS_EC_SPI_MODALIAS_STR}" ]]; then
- echo "$(basename "${dev}")"
- exit 0
- fi
- done
-
- exit 1
-}
-
-# Taken verbatim from
-# https://chromium.googlesource.com/chromiumos/docs/+/master/lsb-release.md#shell
-# This should not be used by anything except get_platform_name.
-# See https://crbug.com/98462.
-lsbval() {
- local key="$1"
- local lsbfile="${2:-/etc/lsb-release}"
-
- if ! echo "${key}" | grep -Eq '^[a-zA-Z0-9_]+$'; then
- return 1
- fi
-
- sed -E -n -e \
- "/^[[:space:]]*${key}[[:space:]]*=/{
- s:^[^=]+=[[:space:]]*::
- s:[[:space:]]+$::
- p
- }" "${lsbfile}"
-}
-
-# Get the underlying board (reference design) that we're running on (not the
-# FPMCU or sensor).
-get_platform_name() {
- # "-l" converts to lowercase
- local -l platform_name="$(cros_config /identity platform-name)"
-
- # If we don't get any result from cros_config, then we have to possible cases:
- #
- # 1) We're running on a non-unibuild device (the only one with FP is nocturne)
- # 2) We're running on a proto device during bringup and the cros_config
- # settings haven't yet been setup.
- #
- # In either case we can fall back to /etc/lsb-release. It's not recommended
- # to do this, but we don't have any other options in this case.
- #
- # TODO(https://crbug.com/984629): cros_config should handle reading
- # /etc/lsb-release as backup for us.
- if [[ -z "${platform_name}" ]]; then
- echo "Getting platform name from cros_config failed." \
- "Falling back to /etc/lsb-release." 1>&2
- platform_name="$(lsbval "CHROMEOS_RELEASE_BOARD")"
- if [[ -z "${platform_name}" ]]; then
- exit 1
- fi
- fi
-
- echo "${platform_name}"
-}
-
-check_gpio_chip_exists() {
- local gpiochip="$1"
- if [[ ! -e "/sys/class/gpio/${gpiochip}" ]]; then
- echo "Cannot find GPIO chip: ${gpiochip}"
- exit 1
- fi
-}
-
-flash_fp_mcu_stm32() {
- local spidev="${1}"
- local gpio_nrst="${2}"
- local gpio_boot0="${3}"
- local gpio_pwren="${4}"
- local file="${5}"
- local spiid
-
- local STM32MON_READ_FLAGS=" -p -s ${spidev} -r"
- local STM32MON_WRITE_FLAGS="-p -s ${spidev} -e -w"
- local stm32mon_flags=""
-
- if [[ "${FLAGS_remove_flash_write_protect}" -eq "${FLAGS_TRUE}" ]]; then
- STM32MON_READ_FLAGS=" -u ${STM32MON_READ_FLAGS}"
- STM32MON_WRITE_FLAGS="-u ${STM32MON_WRITE_FLAGS}"
- fi
-
- if [[ "${FLAGS_remove_flash_read_protect}" -eq "${FLAGS_TRUE}" ]]; then
- STM32MON_READ_FLAGS=" -U ${STM32MON_READ_FLAGS}"
- STM32MON_WRITE_FLAGS="-U ${STM32MON_WRITE_FLAGS}"
- fi
-
- if [[ "${FLAGS_read}" -eq "${FLAGS_TRUE}" ]]; then
- if [[ -e "${file}" ]]; then
- echo "Output file already exists: ${file}"
- exit 1
- fi
- stm32mon_flags="${STM32MON_READ_FLAGS}"
- else
- if [[ ! -f "${file}" ]]; then
- echo "Invalid image file: ${file}"
- exit 1
- fi
- stm32mon_flags="${STM32MON_WRITE_FLAGS}"
- fi
-
- check_hardware_write_protect_disabled
-
- spiid="$(get_spiid)"
- if [[ $? -ne 0 ]]; then
- echo "Unable to find FP sensor SPI device: ${CROS_EC_SPI_MODALIAS_STR}"
- exit 1
- fi
-
- echo "Flashing SPI device ID: ${spiid}"
-
- # Ensure the ACPI is not cutting power when unloading cros-ec-spi
- if [[ -n "${gpio_pwren}" ]]; then
- echo "${gpio_pwren}" > /sys/class/gpio/export
- echo "out" > "/sys/class/gpio/gpio${gpio_pwren}/direction"
- echo 1 > "/sys/class/gpio/gpio${gpio_pwren}/value"
- fi
-
- # Remove cros_fp if present
- echo "${spiid}" > /sys/bus/spi/drivers/cros-ec-spi/unbind
-
- # Configure the MCU Boot0 and NRST GPIOs
- echo "${gpio_boot0}" > /sys/class/gpio/export
- echo "out" > "/sys/class/gpio/gpio${gpio_boot0}/direction"
- echo "${gpio_nrst}" > /sys/class/gpio/export
- echo "out" > "/sys/class/gpio/gpio${gpio_nrst}/direction"
-
- # Reset sequence to enter bootloader mode
- echo 1 > "/sys/class/gpio/gpio${gpio_boot0}/value"
- echo 0 > "/sys/class/gpio/gpio${gpio_nrst}/value"
- sleep 0.001
-
- # load spidev (fail on cros-ec-spi first to change modalias)
- echo "${spiid}" > /sys/bus/spi/drivers/cros-ec-spi/bind 2>/dev/null
- echo "${spiid}" > /sys/bus/spi/drivers/spidev/bind
-
- # Release reset as the SPI bus is now ready
- echo 1 > "/sys/class/gpio/gpio${gpio_nrst}/value"
- echo "in" > "/sys/class/gpio/gpio${gpio_nrst}/direction"
-
- # Print out the actual underlying command we're running and run it
- local cmd="stm32mon ${stm32mon_flags} ${file}"
- echo "${cmd}"
- ${cmd}
-
- local cmd_exit_status=$?
-
- # unload spidev
- echo "${spiid}" > /sys/bus/spi/drivers/spidev/unbind
-
- # Go back to normal mode
- echo "out" > "/sys/class/gpio/gpio${gpio_nrst}/direction"
- echo 0 > "/sys/class/gpio/gpio${gpio_boot0}/value"
- echo 0 > "/sys/class/gpio/gpio${gpio_nrst}/value"
- echo 1 > "/sys/class/gpio/gpio${gpio_nrst}/value"
-
- # Give up GPIO control
- echo "in" > "/sys/class/gpio/gpio${gpio_boot0}/direction"
- echo "in" > "/sys/class/gpio/gpio${gpio_nrst}/direction"
- echo "${gpio_boot0}" > /sys/class/gpio/unexport
- echo "${gpio_nrst}" > /sys/class/gpio/unexport
-
- # wait for FP MCU to come back up (including RWSIG delay)
- sleep 2
- # Put back cros_fp driver
- echo "${spiid}" > /sys/bus/spi/drivers/cros-ec-spi/bind
- # Kernel driver is back, we are no longer controlling power
- if [[ -n "${gpio_pwren}" ]]; then
- echo "${gpio_pwren}" > /sys/class/gpio/unexport
- fi
-
- if [[ "${cmd_exit_status}" -ne 0 ]]; then
- exit 1
- fi
-
- # Test it
- ectool --name=cros_fp version
-}
-
-config_hatch() {
- check_gpio_chip_exists "gpiochip200"
-
- readonly SPIDEV="/dev/spidev1.1"
-
- # See
- # third_party/coreboot/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h
- # for pin name to number mapping.
- # Examine `cat /sys/kernel/debug/pinctrl/INT34BB:00/gpio-ranges` on a hatch
- # device to determine gpio number from pin number.
-
- # FPMCU RST_ODL is on GPP_A12 = 200 + 12 = 212
- readonly GPIO_NRST=212
- # FPMCU BOOT0 is on GPP_A22 = 200 + 22 = 222
- readonly GPIO_BOOT0=222
- # FP_PWR_EN is on GPP_C11 = 456 + (192 - 181) = 456 + 11 = 467
- readonly GPIO_PWREN=467
-}
-
-config_nami() {
- check_gpio_chip_exists "gpiochip360"
-
- readonly SPIDEV="/dev/spidev32765.0"
- # FPMCU RST_ODL is on GPP_C9 = 360 + 57 = 417
- readonly GPIO_NRST=417
- # FPMCU BOOT0 is on GPP_D5 = 360 + 77 = 437
- readonly GPIO_BOOT0=437
- # FP_PWR_EN is on GPP_B11 = 360 + 35 = 395
- readonly GPIO_PWREN=395
-}
-
-config_nocturne() {
- check_gpio_chip_exists "gpiochip360"
-
- readonly SPIDEV="/dev/spidev32765.0"
- # FPMCU RST_ODL is on GPP_C10 = 360 + 58 = 418
- readonly GPIO_NRST=418
- # FPMCU BOOT0 is on GPP_C8 = 360 + 56 = 416
- readonly GPIO_BOOT0=416
- # FP_PWR_EN is on GPP_A11 = 360 + 11 = 371
- readonly GPIO_PWREN=371
-}
-
-# The "platform name" corresponds to the underlying board (reference design)
-# that we're running on (not the FPMCU or sensor). At the moment all of the
-# reference designs use the same GPIOs. If for some reason a design differs in
-# the future, we will want to add a nested check in the config_<platform_name>
-# function. Doing it in this manner allows us to reduce the number of
-# configurations that we have to maintain (and reduces the amount of testing
-# if we're only updating a specific config_<platform_name>).
-readonly PLATFORM_NAME="$(get_platform_name)"
-
-echo "Using config for ${PLATFORM_NAME}"
-
-# Check that the config function exists
-if [[ "$(type -t "config_${PLATFORM_NAME}")" != "function" ]]; then
- echo "No config for platform ${PLATFORM_NAME}"
- exit 1
-fi
-
-config_${PLATFORM_NAME}
-
-if [[ $? -ne 0 ]]; then
- echo "Configuration failed for platform ${PLATFORM_NAME}"
- exit 1
-fi
-
-flash_fp_mcu_stm32 \
- "${SPIDEV}" \
- "${GPIO_NRST}" \
- "${GPIO_BOOT0}" \
- "${GPIO_PWREN}" \
- "${1}"
diff --git a/util/flash_pd.py b/util/flash_pd.py
deleted file mode 100755
index f39af7f06d..0000000000
--- a/util/flash_pd.py
+++ /dev/null
@@ -1,348 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2014 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.
-"""Flash PD PSU RW firmware over the USBPD comm channel using console.
-
- Example:
- util/flash_pd.py ./build/zinger/ec.RW.bin
-"""
-
-import array
-import errno
-import logging
-import optparse
-import os
-import re
-import socket
-import sys
-import time
-
-import serial
-# TODO(tbroch): Discuss adding hdctools as an EC package RDEPENDS
-from servo import client
-from servo import multiservo
-
-VERSION = '0.0.2'
-
-# RW area is half of the 32-kB
-MAX_FW_SIZE = 16 * 1024
-# 20 first bytes of SHA-256 of RW when erased (set to all F's)
-ERASED_RW_HASH = 'd86670be 559860c7 2b2149e8 d2ae1104 9550e093'
-
-class FlashPDError(Exception):
- """Exception class for flash_pd utility."""
-
-
-class FlashPD(client.ServoClient):
- """class to flash PD MCU.
-
- Note, Some designs(samus) have multiple embedded MCUs. In that case
- the convention is to name the pty associated with usbpd as
- 'usbpd_uart_pty'. In the case where there is only one MCU we prefer
- 'usbpd_uart_pty' but will also associate 'ecu_uart_pty' with having
- capability to flash the USB-PD capable PSU(zinger).
-
- Attributes:
- _options : Values instance from optparse.
-
- Public Methods:
- expect : Examine console output for an expected response.
- flash_command : Write a PD flash command and interrogate its result.
- get_version : Retrieve current version of PD FW.
- """
-
- def __init__(self, options):
- """Constructor.
-
- Args:
- options : Values instance from optparse.
-
- Raises:
- FlashPDError: If unable to determine the console pty
- """
- super(FlashPD, self).__init__(host=options.server, port=options.port)
- self._options = options
- self._serial = None
-
- try:
- pty = self.get('usbpd_uart_pty')
- except socket.error as e:
- raise FlashPDError('Can\'t connect to servod :: %s' % e)
- except client.ServoClientError:
- pty = self.get('ec_uart_pty')
- if not pty:
- raise FlashPDError('Unable to determine EC uart from servod')
-
- logging.debug('Opening serial connection to %s', pty)
- try:
- self._serial = serial.Serial(pty, timeout=1)
- except OSError as e:
- if e.errno == errno.EAGAIN:
- # try twice if already open EAGAIN failure causes disconnect.
- self._serial = serial.Serial(pty, timeout=1)
- else:
- raise FlashPDError('%s' % e)
-
- # quiet other channels that might pollute console.
- self._serial.write('chan 1\n')
- self._serial.flushOutput()
- self._serial.flushInput()
-
- def __del__(self):
- """Deconstructor."""
- if self._serial:
- for l in self._serial:
- logging.debug('flash: %s', l)
- self._serial.write('chan 0xffffffff\n')
- self._serial.write('chan restore\n')
- self._serial.close()
-
- def expect(self, val, timeout=5):
- """Scan serial output for particular string.
-
- Args:
- val : string to look for
- timeout : integer seconds to look before timing out.
-
- Returns:
- tuple : boolean if 'val' found in console output.
- string of line that had 'val' in it.
- """
- done = False
- deadline = time.time() + timeout
- while not done and (time.time() < deadline):
- l = None
- for l in self._serial:
- done = val in l
- logging.debug('Is %s in: %s', val, l)
- if done or time.time() > deadline:
- break
- if not done:
- logging.debug("Expect '%s' missing", val)
- return (done, l)
-
- def pd_command(self, cmd, expect='DONE 0', retries=2, ignore_fail=False):
- """Send PD command and interrogate output.
-
- Args:
- cmd : string of 'pd <port>' command to execute
- expect : string of expected response after 'cmd'
- retries : integer number of times to repeat command if it fails.
- ignore_fail : boolean to ignore failure
-
- Returns:
- tuple :
- found : boolean, whether response matches expected.
- line : string of line returned by expect method.
-
- Raises:
- FlashPDError: if command failed to match expected return string after
- retries.
- """
- tries = retries + 1
- for i in xrange(tries):
- self._serial.write('pd %d %s\n' % (self._options.multiport, cmd))
- (found, line) = self.expect(expect)
- if i:
- time.sleep(1)
- logging.debug("pd cmd Retry%d for '%s'", i, cmd)
- if found:
- break
- if (i + 1) == tries and not found and not ignore_fail:
- raise FlashPDError("Failed pd cmd: '%s' after %d retries\n" %
- (cmd, retries))
- return (found, line)
-
- def flash_command(self, cmd, expect='DONE 0', retries=2, ignore_fail=False):
- """Helper method."""
- flash_cmd = 'flash %s' % cmd
- return self.pd_command(flash_cmd, expect, retries, ignore_fail)
-
- def get_version(self):
- """Retreive PSU firmware version.
-
- Looks like: 'version: zinger_v1.1.1917-bfd'
-
- Returns:
- version : string of version
- Raises:
- FlashPDError : if can't determine version
- """
- (found, line) = self.flash_command('version', expect='version:')
- logging.debug('is version in: %s', line)
- m = False
- if found:
- m = re.match(r'.*version:\s+(\w+_v\d+\.\d+\.\d+-\S+).*', line)
- if not m:
- raise FlashPDError('Unable to determine PD FW version')
- return m.group(1)
-
- def reboot(self):
- """Reboot PSU.
-
- Use 'version' to poll for success after DONE encountered.
- Raises:
- FlashPDError : If unable to reboot
- """
- self.flash_command('reboot', expect=r'DONE', retries=0)
- self.flash_command('version', retries=10)
-
-
-def flash_pd(options):
- """Flash power delivery firmware."""
-
- ec = FlashPD(options)
-
- with open(options.firmware) as fd:
- fw = fd.read()
- fw_size = len(fw)
- # The RW firmware should be already padded and signed
- if fw_size != MAX_FW_SIZE:
- raise FlashPDError('Bad RW firmware size %d/%d' % (fw_size, MAX_FW_SIZE))
-
- words = array.array('I', fw)
-
- logging.info('Current PD FW version is %s', ec.get_version())
- if options.versiononly:
- return
-
- logging.info('Flashing %d bytes', fw_size)
-
- # reset flashed signature to reboot in RO
- ec.flash_command('signature')
- # reboot in RO
- ec.reboot()
- # erase all RW partition
- ec.flash_command('erase')
-
- # try info command and guarantee we're in RO
- (done, line) = ec.flash_command('info', expect=r'INFO')
- m = re.match(r'INFO.*(18d1\S{4})', line)
- if done and m:
- done = ec.expect('DONE 0')
- in_rw = int(m.group(1), 16) & 0x1
- if in_rw:
- raise FlashPDError('Not in RO after erase')
- # Google UFP devices share their hash to DFP after info command so check it
- (done, _) = ec.pd_command('hash', expect=ERASED_RW_HASH)
-
- if not done:
- raise FlashPDError('Erase failed')
-
- logging.info('Successfully erased flash.')
-
- if options.eraseonly:
- ec.reboot()
- logging.info('After erase, FW version is %s', ec.get_version())
- return
-
- # write firmware content
- for i in xrange(len(words) / 6):
- chunk = words[i * 6: (i + 1) * 6]
- cmd = ' '.join(['%08x' % (w) for w in chunk])
- ec.flash_command(cmd)
- if not i % 0x10:
- logging.info('Chunk %d of %d done.', i, len(words) / 6)
- # write the remaining words
- chunk = words[len(words) / 6 * 6:]
- cmd = ' '.join(['%08x' % (w) for w in chunk])
- ec.flash_command(cmd)
-
- # reboot in RW
- ec.reboot()
-
- logging.info('Flashing DONE.')
- logging.info('New PD FW version is %s', ec.get_version())
-
-
-def parse_args():
- """Parse commandline arguments.
-
- Note, reads sys.argv directly
-
- Returns:
- options : dict of from optparse.parse_args().
-
- Raises:
- FlashPDError : If problems with arguments
- """
- description = (
- '%prog [<switch args>] <firmware.bin>'
- '\n'
- '%prog is a utility for flashing the USB-PD charger RW firmware over '
- 'the USB-PD communication channel using PD MCU console commands.'
- )
- examples = (
- '\nExamples:\n'
- ' %prog build/zinger/ec.RW.flat\n'
- )
- parser = optparse.OptionParser(version='%prog ' + VERSION)
- parser.description = description
- parser.add_option('-d', '--debug', action='store_true', default=False,
- help='enable debug messages.')
- parser.add_option('-s', '--server', help='host where servod is running',
- default=client.DEFAULT_HOST)
- parser.add_option('-p', '--port', default=client.DEFAULT_PORT, type=int,
- help='port servod is listening on.')
- parser.add_option('-m', '--multiport', default=0, type=int,
- help='If design has multiple type-C ports, this identifies '
- 'which one has USB PD PSU.')
- parser.add_option('', '--timeout', default=5, type=int,
- help='Timeout seconds to wait for console output.')
- parser.add_option('', '--eraseonly', action='store_true', default=False,
- help='Only erase RW portion and exit.')
- parser.add_option('-V', '--versiononly', action='store_true', default=False,
- help='Only read version and exit.')
- multiservo.add_multiservo_parser_options(parser)
-
- parser.set_usage(parser.get_usage() + examples)
- (options, args) = parser.parse_args()
-
- # TODO(tbroch) Add this once we refactor module to ease use in scripts.
- if options.name:
- raise NotImplementedError('Multiservo support TBD')
-
- # Add after to enumerate options.firmware but outside 'help' generation
- parser.add_option('-f', '', action='store', type='string', dest='firmware')
-
- if len(args) != 1:
- raise FlashPDError('Must supply power delivery firmware to write.')
-
- options.firmware = args[0]
- if not os.path.exists(options.firmware):
- raise FlashPDError('Unable to find file %s' % options.firmware)
-
- fw_size = os.path.getsize(options.firmware)
- if fw_size > MAX_FW_SIZE:
- raise FlashPDError('Firmware too large %d/%d' % (fw_size, MAX_FW_SIZE))
-
- return options
-
-
-def main_function():
- options = parse_args()
-
- loglevel = logging.INFO
- log_format = '%(asctime)s - %(name)s - %(levelname)s'
- if options.debug:
- loglevel = logging.DEBUG
- log_format += ' - %(filename)s:%(lineno)d:%(funcName)s'
- log_format += ' - %(message)s'
- logging.basicConfig(level=loglevel, format=log_format)
-
- flash_pd(options)
-
-
-def main():
- """Main function wrapper to catch exceptions properly."""
- try:
- main_function()
- except KeyboardInterrupt:
- sys.exit(0)
- except FlashPDError as e:
- print 'Error: ', e.message
- sys.exit(1)
-
-if __name__ == '__main__':
- main()
diff --git a/util/g_regs b/util/g_regs
deleted file mode 100755
index 28e6f4a53d..0000000000
--- a/util/g_regs
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/perl
-# Copyright 2015 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.
-
-use strict;
-our $opt_D;
-
-use File::Basename;
-my $progdir = dirname($0);
-my $prog = basename($0);
-
-use Getopt::Std;
-my $usage = "
-Usage: $prog [HEADER]
-
-This converts the FPGA release's generated C header file into the
-hw_regdefs.h file that is included by chip/g/registers.h.
-Mostly it just prefaces the macros with GC_ to avoid name collision.
-
-";
-getopts('D') or die $usage;
-
-
-print "/*
- * Copyright 2015 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.
- */
-
-/* This file is autogenerated by the $prog utility. Do not edit. */
-
-";
-
-while(<>)
-{
- if ( s/\b\w+_REGDEFS_H/__EC_CHIP_G_CR50_FPGA_REGDEFS_H/g )
- {
- print;
- next;
- }
-
- if ( s/__ENABLE_FLASH_DFT_DEFINITIONS__/GC__ENABLE_FLASH_DFT_DEFINITIONS__/g )
- {
- print;
- next;
- }
-
- if ( s/\bFLASH_DFT/GC_FLASH_DFT/g )
- {
- print;
- next;
- }
-
- if ( m/^#define\s+(\S+)\s+(\S+)\s*$/ )
- {
- my ($k,$v) = ($1,$2);
-
- if ($k =~ m/^IRQNUM/) {
- # irqnums must be decimal
- $v = 0 + hex($v);
- }
- $k = "GC_$k";
- printf("#define %-40s %s\n", $k, $v);
- if ( $k =~ m/0_BASE_ADDR$/ ) {
- $k =~ s/0_BASE_ADDR/_BASE_ADDR/;
- printf("#define %-40s %s\n", $k, $v);
- }
- next;
- }
-
- next if m!//!;
- next if m!/\*! .. m!\*/!;
-
- print;
-}
-
diff --git a/util/gdbinit b/util/gdbinit
deleted file mode 100644
index b40137c5a1..0000000000
--- a/util/gdbinit
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2019 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.
-
-# This file is intended to be used as a .gdbinit for an EC debugging session.
-# It defines some useful functions for analyzing the EC state.
-#
-# Setup Automatic Import:
-# ln -s util/gdbinit .gdbinit
-#
-# Environment Variables:
-# BOARD=[nocturne_fp|bloonchipper|...]
-# GDBSERVER=[segger|openocd]
-# GDBPORT=[gdb-server-port-number]
-#
-# Warning, this is a working collection that is not guaranteed to function
-# properly on all platforms. The ec-tasks functions is a good example of a
-# function that works well on most simple platforms, but may have issues on
-# platforms with data cache enabled.
-#
-# Note, this file must maintain space indention to allow easy copy/paste
-# while in active debugging. Using tabs interferes with the embedded python
-# during copy/paste.
-
-#####################################################################
-# Environment Setup and Initialization #
-#####################################################################
-
-# Setup environment and pull in object files for the particular BOARD.
-# This requires setting the environment variables mentioned above.
-python
-import os
-
-BOARD = os.getenv('BOARD', '')
-GDBSERVER = os.getenv('GDBSERVER', 'openocd')
-GDBPORT = os.getenv('GDBPORT', '3333')
-gdb.execute('set $BOARD = "%s"'%BOARD)
-gdb.execute('set $GDBSERVER = "%s"'%GDBSERVER)
-gdb.execute('set $GDBPORT = "%s"'%GDBPORT)
-
-build = 'build/' + BOARD
-if BOARD != "":
- if not os.path.isdir(build):
- print('Error - Build path "' + build + '" doesn\'t exist. Aborting.')
- gdb.execute('quit')
-
- gdb.execute('file ' + build + '/ec.obj')
- gdb.execute('add-symbol-file ' + build + '/RO/ec.RO.elf')
- gdb.execute('add-symbol-file ' + build + '/RW/ec.RW.elf')
-
-if GDBSERVER == "openocd":
- gdb.execute('set $GDBSERVER_OPENOCD = 1')
- gdb.execute('set $GDBSERVER_SEGGER = 0')
-elif GDBSERVER == "segger":
- gdb.execute('set $GDBSERVER_OPENOCD = 0')
- gdb.execute('set $GDBSERVER_SEGGER = 1')
-else:
- print('Error - GDBSERVER="' + GDBSERVER + '" is invalid.')
- gdb.execute('quit')
-end
-
-# OpenOCD specific config
-if $GDBSERVER_OPENOCD
- # Don't auto choose hw/sw breakpoints from memory-map
- set breakpoint auto-hw off
-end
-
-# Segger specific config
-if $GDBSERVER_SEGGER
- # If enabled, disable flash breakpoints.
- #monitor flash breakpoints = 0
-end
-
-# If enabled, force breakpoints to be inserted at all times.
-# They will not be reinserted on reconnects.
-#set breakpoint always-inserted on
-
-#####################################################################
-# Helper Functions #
-#####################################################################
-
-# Usage: reg32 <address> [offset]
-# Read a 32 bit register
-define reg32
- set $a = $arg0
- if $argc > 1
- set $a += $arg1
- end
- set $v = *((uint32_t *)$a)
- print $v
- print /x $v
- print /t $v
-end
-
-# Usage: ec-connect
-# Issue the overly long target connect command using the
-# specified gdb server port.
-define ec-connect
-python
- # May want to only use "target remote".
- gdb.execute('target extended-remote :%d'%GDBPORT)
-end
-end
-alias connect = ec-connect
-
-# Usage: ec-reset
-# Issue the reset sequence for the debugger to halt on boot.
-define ec-reset
- if $GDBSERVER_OPENOCD
- monitor halt
- monitor reset halt
- else
- monitor halt
- monitor reset
- end
-end
-alias reset = ec-reset
-
-# Usage: ec-tasks
-# Prints out information about current EC task set and tries to determine
-# if the task's stack has been overrun.
-# This function may not work properly if MCU data cache is enabled.
-define ec-tasks
- set $taskid_cur = current_task - tasks
- set $id = 0
- set $taskcount = sizeof(tasks)/sizeof(tasks[0])
- printf "Task Ready Name Events Time (s) StkUsed\n"
- while $id < $taskcount
- set $is_ready = (tasks_ready & (1<<$id)) ? 'R' : ' '
- set $unused = (uint32_t)0xdeadd00d
- set $stacksize = tasks_init[$id].stack_size
- set $stackused = $stacksize
- set $s = tasks[$id].stack
- while $s < (uint32_t *)tasks[$id].sp && *$s == $unused
- set $stackused -= sizeof(uint32_t)
- set $s++
- end
- printf "%4d %-5c %-16s %08x %11.6ld %3d/%3d", $id, $is_ready, task_names[$id], tasks[$id].events, tasks[$id].runtime, $stackused, tasks_init[$id].stack_size
- if $stackused == $stacksize
- printf "\t [overrun]"
- end
- if $id == $taskid_cur
- printf "\t*"
- end
- printf "\n"
- set $id++
- end
- if $taskid_cur == scratchpad
- printf "Current task is set to scratchpad\n"
- end
-end
-
-# Usage: ec-stayro
-# Adds magic breakpoint that changes the outcome of the RW signature
-# validation step that forces the MCU to stay in the RO section.
-# This function needs improvements to not be dependent on line numbers.
-define ec-stayro
- break common/rwsig.c:282
- commands
- set evt = 1
- printf "Continuing as RO\n"
- continue
- end
-end
-
-# Usage: ec-brexception
-# Set breakpoints on EC exception handlers.
-define ec-brexception
- break exception_panic
- break bus_fault_handler
- break panic_assert_fail
-end \ No newline at end of file
diff --git a/util/gen_emmc_transfer_data.c b/util/gen_emmc_transfer_data.c
deleted file mode 100644
index 98417beb9b..0000000000
--- a/util/gen_emmc_transfer_data.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright 2018 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.
- *
- * Generate transferring data from a file. The transferring data emulates the
- * eMMC protocol.
- */
-
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <compile_time_macros.h>
-
-/* eMMC transfer block size */
-#define BLOCK_SIZE 512
-#define BLOCK_RAW_DATA "bootblock_raw_data"
-
-uint16_t crc16_arg(uint8_t data, uint16_t previous_crc)
-{
- unsigned int crc = previous_crc << 8;
- int i;
-
- crc ^= (data << 16);
- for (i = 8; i; i--) {
- if (crc & 0x800000)
- crc ^= (0x11021 << 7);
- crc <<= 1;
- }
-
- return (uint16_t)(crc >> 8);
-}
-
-void header_format(FILE *fin, FILE *fout)
-{
- uint8_t data[BLOCK_SIZE];
- int blk, j;
- uint16_t crc16;
- size_t cnt = 0;
-
- fprintf(fout, "/* This file is auto-generated. Do not modify. */\n"
- "#ifndef __CROS_EC_BOOTBLOCK_DATA_H\n"
- "#define __CROS_EC_BOOTBLOCK_DATA_H\n"
- "\n"
- "#include <stdint.h>\n"
- "\n"
- );
-
- fprintf(fout,
- "static const uint8_t %s[] __attribute__((aligned(4))) =\n"
- "{\n"
- "\t0xff, 0x97, /* Acknowledge boot mode: 1 S=0 010 E=1 11 */\n"
- "\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n",
- BLOCK_RAW_DATA);
-
- for (blk = 0;; blk++) {
- crc16 = 0;
- if (fin)
- cnt = fread(data, 1, BLOCK_SIZE, fin);
-
- if (cnt == 0)
- break;
- else if (cnt < BLOCK_SIZE)
- memset(&data[cnt], 0xff, BLOCK_SIZE-cnt);
-
- fprintf(fout, "\t/* Block %d (%ld) */\n", blk, cnt);
- fprintf(fout, "\t0xff, 0xfe, /* idle, start bit. */");
- for (j = 0; j < sizeof(data); j++) {
- fprintf(fout, "%s0x%02x,",
- (j % 8) == 0 ? "\n\t" : " ", data[j]);
- crc16 = crc16_arg(data[j], crc16);
- }
- fprintf(fout, "\n");
-
- fprintf(fout, "\t0x%02x, 0x%02x, 0xff,"
- " /* CRC, end bit, idle */\n",
- crc16 >> 8, crc16 & 0xff);
- }
-
- fprintf(fout, "\t/* Last block: idle */\n");
- fprintf(fout, "\t0xff, 0xff, 0xff, 0xff\n");
- fprintf(fout, "};\n");
- fprintf(fout, "#endif /* __CROS_EC_BOOTBLOCK_DATA_H */\n");
-}
-
-int main(int argc, char **argv)
-{
- int nopt;
- int ret = 0;
- const char *output_name = NULL;
- char *input_name = NULL;
- FILE *fin = NULL;
- FILE *fout = NULL;
-
- const char short_opts[] = "i:ho:";
- const struct option long_opts[] = {
- { "input", 1, NULL, 'i' },
- { "help", 0, NULL, 'h' },
- { "out", 1, NULL, 'o' },
- { NULL }
- };
- const char usage[] = "USAGE: %s [-i <input>] -o <output>\n";
-
- while ((nopt = getopt_long(argc, argv, short_opts, long_opts,
- NULL)) != -1) {
- switch (nopt) {
- case 'i': /* -i or --input*/
- input_name = optarg;
- break;
- case 'h': /* -h or --help */
- fprintf(stdout, usage, argv[0]);
- return 0;
- case 'o': /* -o or --out */
- output_name = optarg;
- break;
- default: /* Invalid parameter. */
- fprintf(stderr, usage, argv[0]);
- return 1;
- }
- }
-
- if (output_name == NULL) {
- fprintf(stderr, usage, argv[0]);
- return 1;
- }
-
- if (input_name == NULL) {
- printf("No bootblock provided, outputting default file.\n");
- } else {
- fin = fopen(input_name, "r");
- if (!fin) {
- printf("Cannot open input file: %s\n", input_name);
- ret = 1;
- goto out;
- }
- }
-
- fout = fopen(output_name, "w");
-
- if (!fout) {
- printf("Cannot open output file: %s\n", output_name);
- ret = 1;
- goto out;
- }
-
- header_format(fin, fout);
-
- fclose(fout);
-
-out:
- if (fin)
- fclose(fin);
-
- return ret;
-}
diff --git a/util/gen_ipi_table.c b/util/gen_ipi_table.c
deleted file mode 100644
index 07a3a39be0..0000000000
--- a/util/gen_ipi_table.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2019 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.
- *
- * Generate IPI tables, and inputs come from IPI_COUNT macro in board.h.
- */
-
-#include <stdio.h>
-
-/* Prevent from including gpio configs . */
-#define __ASSEMBLER__
-
-#include "board.h"
-
-#define FPRINTF(format, args...) fprintf(fout, format, ## args)
-
-int main(int argc, char **argv)
-{
- FILE *fout;
- int i;
-
- if (argc != 2) {
- fprintf(stderr, "USAGE: %s <output>\n", argv[0]);
- return 1;
- }
-
- fout = fopen(argv[1], "w");
-
- if (!fout) {
- fprintf(stderr, "Cannot open output file %s\n", argv[1]);
- return 1;
- }
-
- FPRINTF("/* This is a generated file. Do not modify. */\n");
- FPRINTF("\n");
- FPRINTF("/*\n");
- FPRINTF(" * Table to hold all the IPI handler function pointer.\n");
- FPRINTF(" */\n");
- FPRINTF("table(ipi_handler_t, ipi_handler_table,\n");
-
- for (i = 0; i < IPI_COUNT; ++i)
- FPRINTF("ipi_x_func(handler, ipi_arguments, %d)\n", i);
-
- FPRINTF(");\n");
-
- FPRINTF("/*\n");
- FPRINTF(" * Table to hold all the wake-up bool address.\n");
- FPRINTF(" */\n");
- FPRINTF("table(int *, ipi_wakeup_table,\n");
-
- for (i = 0; i < IPI_COUNT; ++i)
- FPRINTF("ipi_x_var(wakeup, %d)\n", i);
-
- FPRINTF(");\n");
-
- fclose(fout);
- return 0;
-}
diff --git a/util/gen_touchpad_hash.c b/util/gen_touchpad_hash.c
deleted file mode 100644
index e03c4638f3..0000000000
--- a/util/gen_touchpad_hash.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Copyright 2017 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.
- */
-
-#include <err.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <openssl/sha.h>
-
-#include "config.h"
-
-static void print_hex(FILE *out, uint8_t *digest, int len, int last)
-{
- int i;
-
- fputs("{ ", out);
- for (i = 0; i < len; i++)
- fprintf(out, "0x%02x, ", digest[i]);
-
- fprintf(out, "}%c\n", last ? ';' : ',');
-}
-
-/* Output blank hashes */
-static int hash_fw_blank(FILE *hashes)
-{
- uint8_t digest[SHA256_DIGEST_LENGTH] = { 0 };
- int len;
-
- fprintf(hashes, "const uint8_t touchpad_fw_hashes[%d][%d] = {\n",
- CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE,
- SHA256_DIGEST_LENGTH);
- for (len = 0; len < CONFIG_TOUCHPAD_VIRTUAL_SIZE;
- len += CONFIG_UPDATE_PDU_SIZE) {
- print_hex(hashes, digest, sizeof(digest), 0);
- }
- fputs("};\n", hashes);
-
- fprintf(hashes, "const uint8_t touchpad_fw_full_hash[%d] =\n\t",
- SHA256_DIGEST_LENGTH);
- print_hex(hashes, digest, SHA256_DIGEST_LENGTH, 1);
-
- return 0;
-}
-
-static int hash_fw(FILE *tp_fw, FILE *hashes)
-{
- uint8_t buffer[CONFIG_UPDATE_PDU_SIZE];
- int len = 0;
- int rb;
- SHA256_CTX ctx;
- SHA256_CTX ctx_all;
- uint8_t digest[SHA256_DIGEST_LENGTH];
-
- SHA256_Init(&ctx_all);
- fprintf(hashes, "const uint8_t touchpad_fw_hashes[%d][%d] = {\n",
- CONFIG_TOUCHPAD_VIRTUAL_SIZE / CONFIG_UPDATE_PDU_SIZE,
- SHA256_DIGEST_LENGTH);
- while (1) {
- rb = fread(buffer, 1, sizeof(buffer), tp_fw);
- len += rb;
-
- if (rb == 0)
- break;
-
- /* Calculate hash for the block. */
- SHA256_Init(&ctx);
- SHA256_Update(&ctx, buffer, rb);
- SHA256_Final(digest, &ctx);
-
- SHA256_Update(&ctx_all, buffer, rb);
-
- print_hex(hashes, digest, sizeof(digest), 0);
-
- if (rb < sizeof(buffer))
- break;
- }
- fputs("};\n", hashes);
-
- SHA256_Final(digest, &ctx_all);
- fprintf(hashes, "const uint8_t touchpad_fw_full_hash[%d] =\n\t",
- SHA256_DIGEST_LENGTH);
- print_hex(hashes, digest, SHA256_DIGEST_LENGTH, 1);
-
- if (!feof(tp_fw) || ferror(tp_fw)) {
- warn("Error reading input file");
- return 1;
- }
-
- if (len != CONFIG_TOUCHPAD_VIRTUAL_SIZE) {
- warnx("Incorrect TP FW size (%d vs %d)", len,
- CONFIG_TOUCHPAD_VIRTUAL_SIZE);
- return 1;
- }
-
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- int nopt;
- int ret;
- const char *out = NULL;
- char *tp_fw_name = NULL;
- FILE *tp_fw = NULL;
- FILE *hashes;
- const char short_opt[] = "f:ho:";
- const struct option long_opts[] = {
- { "firmware", 1, NULL, 'f' },
- { "help", 0, NULL, 'h' },
- { "out", 1, NULL, 'o' },
- { NULL }
- };
- const char usage[] = "USAGE: %s -f <touchpad FW> -o <output file>\n";
-
- while ((nopt = getopt_long(argc, argv, short_opt,
- long_opts, NULL)) != -1) {
- switch (nopt) {
- case 'f': /* -f or --firmware */
- tp_fw_name = optarg;
- break;
-
- case 'h': /* -h or --help */
- fprintf(stdout, usage, argv[0]);
- return 0;
-
- case 'o': /* -o or --out */
- out = optarg;
- break;
-
- default: /* Invalid parameter. */
- fprintf(stderr, usage, argv[0]);
- return 1;
- }
- };
-
- if (out == NULL)
- return 1;
-
- hashes = fopen(out, "we");
- if (!hashes)
- err(1, "Cannot open output file");
-
- fputs("#include <stdint.h>\n\n", hashes);
- if (tp_fw_name) {
- tp_fw = fopen(tp_fw_name, "re");
-
- if (!tp_fw) {
- warn("Cannot open firmware");
- ret = 1;
- goto out;
- }
-
- ret = hash_fw(tp_fw, hashes);
-
- fclose(tp_fw);
- } else {
- printf("No touchpad FW provided, outputting blank hashes.\n");
- ret = hash_fw_blank(hashes);
- }
-
-out:
- fclose(hashes);
-
- /* In case of failure, remove output file. */
- if (ret != 0)
- unlink(out);
-
- return ret;
-}
diff --git a/util/genvif.c b/util/genvif.c
deleted file mode 100644
index ba217a4acf..0000000000
--- a/util/genvif.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/* Copyright 2017 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.
- */
-
-#define _GNU_SOURCE /* for asprintf */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <dirent.h>
-#include <limits.h>
-
-#include "config.h"
-#include "usb_pd.h"
-#include "usb_pd_tcpm.h"
-#include "charge_manager.h"
-#include "system.h"
-
-#define PD_REV_2_0 1
-#define PD_REV_3_0 2
-
-#define GENVIF_TITLE "EC GENVIF, Version 1.1"
-#define VIF_SPEC "Revision 1.22, Version 1.0"
-#define VENDOR_NAME "Google"
-#define PD_SPEC_REV PD_REV_2_0
-
-enum tab {INTRO = 0, GENERAL, USB, SOURCE, SINK, ROLE, SOP1, SOP2};
-enum dtype {SNK = 0, SRC = 3, DRP = 4};
-
-const uint32_t vdo_idh __attribute__((weak)) = 0;
-
-const uint32_t *src_pdo;
-uint32_t src_pdo_cnt;
-
-char *yes_no(int val)
-{
- return val ? "YES" : "NO";
-}
-
-enum system_image_copy_t system_get_image_copy(void)
-{
- return SYSTEM_IMAGE_RW;
-}
-
-static void write_title(FILE *vif)
-{
- fprintf(vif, ";\r\n");
- fprintf(vif, "; %s \r\n", GENVIF_TITLE);
- fprintf(vif, ";\r\n");
-}
-
-static void write_tab(FILE *vif, enum tab t)
-{
- if (!vif)
- return;
-
- fprintf(vif, "\r\n%s\r\n",
- ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
- switch (t) {
- case INTRO:
- fprintf(vif, "; Intro tab\r\n");
- break;
- case GENERAL:
- fprintf(vif, "; General PD Settings tab\r\n");
- break;
- case USB:
- fprintf(vif, "; USB Type-C tab\r\n");
- break;
- case SOURCE:
- fprintf(vif, "; Source tab\r\n");
- break;
- case SINK:
- fprintf(vif, "; Sink tab\r\n");
- break;
- case ROLE:
- fprintf(vif, "; Dual Role tab\r\n");
- break;
- case SOP1:
- fprintf(vif, "; SOP Discovery - Part One tab\r\n");
- break;
- case SOP2:
- fprintf(vif, "; SOP Discovery - Part Two tab\r\n");
- break;
- }
- fprintf(vif, "%s\r\n",
- ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
-}
-
-static void init_src_pdos(void)
-{
-#ifdef CONFIG_USB_PD_DYNAMIC_SRC_CAP
- src_pdo_cnt = charge_manager_get_source_pdo(&src_pdo, 0);
-#else
- src_pdo_cnt = pd_src_pdo_cnt;
- src_pdo = pd_src_pdo;
-#endif
-}
-
-static int is_src(void)
-{
- return src_pdo_cnt;
-}
-
-static int is_snk(void)
-{
-#ifdef CONFIG_USB_PD_DUAL_ROLE
- return pd_snk_pdo_cnt;
-#else
- return 0;
-#endif
-}
-
-static int is_extpwr(void)
-{
- if (is_src())
- return !!(src_pdo[0] & PDO_FIXED_EXTERNAL);
- else
- return 0;
-}
-
-static int is_drp(void)
-{
- if (is_src())
- return !!(src_pdo[0] & PDO_FIXED_DUAL_ROLE);
- else
- return 0;
-}
-
-#ifdef CONFIG_USB_PD_DUAL_ROLE
-static char *giveback(void)
-{
-#ifdef CONFIG_USB_PD_GIVE_BACK
- return "YES";
-#else
- return "NO";
-#endif
-}
-#endif
-
-static char *is_comms_cap(void)
-{
- if (is_src())
- return yes_no(src_pdo[0] & PDO_FIXED_COMM_CAP);
- else
- return "NO";
-}
-
-static char *dr_swap_to_ufp_supported(void)
-{
- if (is_src() && (src_pdo[0] & PDO_FIXED_DATA_SWAP))
- return yes_no(pd_check_data_swap(0, PD_ROLE_DFP));
-
- return "NO";
-}
-
-static char *dr_swap_to_dfp_supported(void)
-{
- if (is_src() && (src_pdo[0] & PDO_FIXED_DATA_SWAP))
- return yes_no(pd_check_data_swap(0, PD_ROLE_UFP));
-
- return "NO";
-}
-
-static char *vconn_swap(void)
-{
-#ifdef CONFIG_USBC_VCONN_SWAP
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static char *try_src(void)
-{
-#ifdef CONFIG_USB_PD_TRY_SRC
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static char *can_act_as_host(void)
-{
-#ifdef CONFIG_VIF_TYPE_C_CAN_ACT_AS_HOST
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static char *can_act_as_device(void)
-{
-#ifdef CONFIG_USB
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static char *captive_cable(void)
-{
-#ifdef CONFIG_VIF_CAPTIVE_CABLE
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static char *sources_vconn(void)
-{
-#ifdef CONFIG_USBC_VCONN
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static char *battery_powered(void)
-{
-#ifdef CONFIG_BATTERY
- return "YES";
-#else
- return "NO";
-#endif
-}
-
-static uint32_t product_type(void)
-{
- return PD_IDH_PTYPE(vdo_idh);
-}
-
-static uint32_t pid_sop(void)
-{
-#ifdef CONFIG_USB_PID
- return CONFIG_USB_PID;
-#else
- return 0;
-#endif
-}
-
-static uint32_t rp_value(void)
-{
-#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
- return CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT;
-#else
- return 0;
-#endif
-}
-
-static char *attempts_discov_sop(enum dtype type)
-{
-#ifdef CONFIG_USB_PD_SIMPLE_DFP
- if (type == SRC)
- return "NO";
- else
- return "YES";
-#else
- return "YES";
-#endif
-}
-
-static uint32_t bcddevice_sop(void)
-{
-#ifdef CONFIG_USB_BCD_DEV
- return CONFIG_USB_BCD_DEV;
-#else
- return 0;
-#endif
-}
-
-/* Application exits on failure */
-__attribute__((__format__(__printf__, 2, 3)))
-static void append(char **buf, const char *fmt, ...)
-{
- va_list ap1, ap2;
- int n;
- static int offset;
-
- va_start(ap1, fmt);
- va_copy(ap2, ap1);
-
- n = vsnprintf(NULL, 0, fmt, ap1) + 1;
-
- if (*buf == NULL)
- offset = 0;
-
- *buf = (char *)realloc(*buf, offset + n);
-
- if (*buf) {
- vsnprintf(*buf + offset, n, fmt, ap2);
- } else {
- fprintf(stderr, "ERROR: Out of memory.\n");
- exit(EXIT_FAILURE);
- }
-
- /* Overwrite NULL terminator the next time through. */
- offset += (n-1);
-
- va_end(ap1);
- va_end(ap2);
-}
-
-static int32_t write_pdo_to_buf(char **buf, uint32_t pdo,
- enum dtype type, uint32_t pnum)
-{
- int32_t power;
-
- if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_FIXED) {
- uint32_t current = pdo & 0x3ff;
- uint32_t voltage = (pdo >> 10) & 0x3ff;
-
- power = ((current * 10) * (voltage * 50)) / 1000;
-
- append(buf, "\t%s_PDO_Supply_Type%d: 0\r\n",
- (type == SRC) ? "Src" : "Snk", pnum);
-
- if (type == SRC)
- append(buf, "\tSrc_PDO_Peak_Current%d: 0\r\n", pnum);
-
- append(buf, "\t%s_PDO_Voltage%d: %d\r\n",
- (type == SRC) ? "Src" : "Snk", pnum, voltage);
-
- if (type == SRC)
- append(buf, "\tSrc_PDO_Max_Current%d: %d\r\n", pnum,
- current);
- else
- append(buf, "\tSnk_PDO_Op_Current%d: %d\r\n", pnum,
- current);
-
- } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
- uint32_t max_voltage = (pdo >> 20) & 0x3ff;
- uint32_t min_voltage = (pdo >> 10) & 0x3ff;
-
- power = pdo & 0x3ff;
-
- append(buf, "\t%s_PDO_Supply_Type%d: 1\r\n",
- (type == SRC) ? "Src" : "Snk", pnum);
-
- append(buf, "\t%s_PDO_Min_Voltage%d: %d\r\n",
- (type == SRC) ? "Src" : "Snk", pnum, min_voltage);
-
- append(buf, "\t%s_PDO_Max_Voltage%d: %d\r\n",
- (type == SRC) ? "Src" : "Snk", pnum, max_voltage);
-
- if (type == SRC)
- append(buf, "\tSrc_PDO_Max_Power%d: %d\r\n", pnum,
- power);
- else
- append(buf, "\tSnk_PDO_Op_Power%d: %d\r\n", pnum,
- power);
-
- } else if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_VARIABLE) {
- uint32_t max_voltage = (pdo >> 20) & 0x3ff;
- uint32_t min_voltage = (pdo >> 10) & 0x3ff;
- uint32_t current = pdo & 0x3ff;
-
- power = ((current * 10) * (max_voltage * 50)) / 1000;
-
- append(buf, "\t%s_PDO_Supply_Type%d: 2\r\n",
- (type == SRC) ? "Src" : "Snk", pnum);
-
- if (type == SRC)
- append(buf, "\tSrc_PDO_Peak_Current%d: 0\r\n", pnum);
-
- append(buf, "\t%s_PDO_Min_Voltage%d: %d\r\n",
- (type == SRC) ? "Src" : "Snk", pnum, min_voltage);
-
- append(buf, "\t%s_PDO_Max_Voltage%d: %d\r\n",
- (type == SRC) ? "Src" : "Snk", pnum, max_voltage);
-
- if (type == SRC)
- append(buf, "\tSrc_PDO_Max_Current%d: %d\r\n", pnum,
- current);
- else
- append(buf, "\tSnk_PDO_Op_Current%d: %d\r\n", pnum,
- current);
- } else {
- fprintf(stderr, "ERROR: Invalid PDO_TYPE %d.\n", pdo);
- return -1;
- }
-
- append(buf, "\r\n");
-
- return power;
-}
-
-/**
- * Carriage and line feed, '\r\n', is needed because the file is processed
- * on a Windows machine.
- */
-static int gen_vif(const char *name, const char *board,
- const char *vif_producer)
-{
- FILE *vif;
- enum dtype type;
- char *type_name;
-
- if (is_drp()) {
- type = DRP;
- type_name = "DRP";
- } else if (is_src() && is_snk()) {
- /* No DRP with SRC and SNK PDOs detected. So ignore. */
- /* ie. Twinki or Plankton */
- return 0;
- } else if (is_src()) {
- type = SRC;
- type_name = "SRC";
- } else if (is_snk()) {
- type = SNK;
- type_name = "SNK";
- } else {
- return 1;
- }
-
- /* Create VIF */
- vif = fopen(name, "w+");
- if (vif == NULL)
- return 1;
-
- /* Write VIF Title */
- write_title(vif);
-
- /* Write Intro Tab comment */
- write_tab(vif, INTRO);
-
- /* Write VIF Header */
- fprintf(vif, "$VIF_Specification: \"%s\"\r\n", VIF_SPEC);
- fprintf(vif, "$VIF_Producer: \"%s\"\r\n", vif_producer);
- fprintf(vif, "UUT_Device_Type: %d ; %s\r\n", type, type_name);
- fprintf(vif, "$Vendor_Name: \"%s\"\r\n", VENDOR_NAME);
- fprintf(vif, "$Product_Name: \"%s\"\r\n", board);
-
- /* Write General PD Settings Tab comment */
- write_tab(vif, GENERAL);
-
- fprintf(vif, "PD_Specification_Revision: %d\r\n", PD_SPEC_REV);
- fprintf(vif, "SOP_Capable: YES\r\n");
- fprintf(vif, "SOP_P_Capable: NO\r\n");
- fprintf(vif, "SOP_PP_Capable: NO\r\n");
- fprintf(vif, "SOP_P_Debug_Capable: NO\r\n");
- fprintf(vif, "SOP_PP_Debug_Capable: NO\r\n");
- fprintf(vif, "USB_Comms_Capable: %s\r\n", is_comms_cap());
- fprintf(vif, "DR_Swap_To_DFP_Supported: %s\r\n",
- dr_swap_to_dfp_supported());
- fprintf(vif, "DR_Swap_To_UFP_Supported: %s\r\n",
- dr_swap_to_ufp_supported());
- fprintf(vif, "Unconstrained_Powered: %s\r\n", yes_no(is_extpwr()));
- fprintf(vif, "VCONN_Swap_To_On_Supported: %s\r\n", vconn_swap());
- fprintf(vif, "VCONN_Swap_To_Off_Supported: %s\r\n", vconn_swap());
- fprintf(vif, "Responds_To_Discov_SOP: YES\r\n");
- fprintf(vif, "Attempts_Discov_SOP: %s\r\n", attempts_discov_sop(type));
-
- /* Write USB Type-C Tab comment */
- write_tab(vif, USB);
-
- /* set Type_C_State_Machine */
- {
- int typec;
-
- switch (type) {
- case DRP:
- typec = 2;
- break;
-
- case SNK:
- typec = 1;
- break;
-
- default:
- typec = 0;
- }
-
- fprintf(vif,
- "Type_C_State_Machine: %d ; %s\r\n", typec, type_name);
- }
-
- fprintf(vif, "Type_C_Implements_Try_SRC: %s\r\n", try_src());
- fprintf(vif, "Type_C_Implements_Try_SNK: NO\r\n");
- fprintf(vif, "Rp_Value: %d\r\n", rp_value());
- /* None of the current devices send SOP' / SOP", so NO.*/
- fprintf(vif, "Type_C_Is_VCONN_Powered_Accessory: NO\r\n");
- fprintf(vif, "Type_C_Supports_VCONN_Powered_Accessory: NO\r\n");
-
- fprintf(vif, "Type_C_Is_Debug_Target_SRC: YES\r\n");
- fprintf(vif, "Type_C_Is_Debug_Target_SNK: YES\r\n");
-
- fprintf(vif, "Type_C_Can_Act_As_Host: %s\r\n", can_act_as_host());
- /* Supports USB 3.1 when communicating as a host */
- fprintf(vif, "Type_C_Host_Speed: 4\r\n");
- fprintf(vif, "Type_C_Can_Act_As_Device: %s\r\n", can_act_as_device());
- fprintf(vif, "Type_C_Device_Speed: 4\r\n");
-
- fprintf(vif, "Type_C_Is_Alt_Mode_Controller: YES\r\n");
- fprintf(vif, "Type_C_Is_Alt_Mode_Device: NO\r\n");
-
- fprintf(vif, "Type_C_Power_Source: 2\r\n");
- fprintf(vif, "Type_C_BC_1_2_Support: 1\r\n");
- fprintf(vif, "Type_C_Battery_Powered: %s\r\n", battery_powered());
- fprintf(vif, "Type_C_Port_On_Hub: NO\r\n");
- fprintf(vif, "Type_C_Supports_Audio_Accessory: NO\r\n");
- fprintf(vif, "Captive_Cable: %s\r\n", captive_cable());
- fprintf(vif, "Type_C_Source_Vconn: %s\r\n", sources_vconn());
-
- /* Write Source Fields */
- if (type == DRP || type == SRC) {
- uint32_t max_power = 0;
- char *buf = NULL;
- int i;
- int32_t pwr;
-
- /* Write Source PDOs */
- for (i = 0; i < src_pdo_cnt; i++) {
- pwr = write_pdo_to_buf(&buf, src_pdo[i], SRC, i+1);
- if (pwr < 0) {
- fprintf(stderr, "ERROR: Out of memory.\n");
- fclose(vif);
- return 1;
- }
-
- if (pwr > max_power)
- max_power = pwr;
- }
-
- /* Write Source Tab comment */
- write_tab(vif, SOURCE);
- fprintf(vif, "PD_Power_as_Source: %d\r\n", max_power);
- fprintf(vif, "USB_Suspend_May_Be_Cleared: YES\r\n");
- fprintf(vif, "Sends_Pings: NO\r\n");
- fprintf(vif, "Num_Src_PDOs: %d\r\n", src_pdo_cnt);
- fprintf(vif, "\r\n%s\r\n", buf);
- free(buf);
- }
-
-#ifdef CONFIG_USB_PD_DUAL_ROLE
- if (type == DRP || type == SNK) {
- uint32_t max_power = 0;
- char *buf = NULL;
- int32_t pwr;
- int i;
-
- /* Write Sink PDOs */
- for (i = 0; i < pd_snk_pdo_cnt; i++) {
- pwr = write_pdo_to_buf(&buf, pd_snk_pdo[i], SNK, i+1);
-
- if (pwr < 0) {
- fprintf(stderr, "ERROR: Out of memory.\n");
- fclose(vif);
- return 1;
- }
-
- if (pwr > max_power)
- max_power = pwr;
- }
-
- /* Write Sink Tab comment */
- write_tab(vif, SINK);
- fprintf(vif, "PD_Power_as_Sink: %d\r\n", max_power);
- fprintf(vif, "USB_Suspend_May_Be_Cleared: NO\r\n");
- fprintf(vif, "GiveBack_May_Be_Set: %s\r\n", giveback());
- fprintf(vif, "Higher_Capability_Set: NO\r\n");
- fprintf(vif, "Num_Snk_PDOs: %d\r\n", pd_snk_pdo_cnt);
- fprintf(vif, "\r\n%s\r\n", buf);
- free(buf);
- }
-
- /* Write DRP Fields */
- if (type == DRP) {
- /* Write Dual Role Tab comment */
- write_tab(vif, ROLE);
- fprintf(vif, "Accepts_PR_Swap_As_Src: YES\r\n");
- fprintf(vif, "Accepts_PR_Swap_As_Snk: YES\r\n");
- fprintf(vif, "Requests_PR_Swap_As_Src: YES\r\n");
- fprintf(vif, "Requests_PR_Swap_As_Snk: YES\r\n");
- }
-#endif
-
- /* Write SOP Discovery -Part One Tab comment */
- write_tab(vif, SOP1);
- /* SOP Discovery Fields */
- fprintf(vif, "Structured_VDM_Version_SOP: 0\r\n");
- fprintf(vif, "XID_SOP: 0\r\n");
- fprintf(vif, "Data_Capable_as_USB_Host_SOP: %s\r\n",
- can_act_as_host());
- fprintf(vif, "Data_Capable_as_USB_Device_SOP: %s\r\n",
- can_act_as_device());
- fprintf(vif, "Product_Type_SOP: %d\r\n", product_type());
- fprintf(vif, "Modal_Operation_Supported_SOP: YES\r\n");
- fprintf(vif, "USB_VID_SOP: 0x%04x\r\n", USB_VID_GOOGLE);
- fprintf(vif, "PID_SOP: 0x%04x\r\n", pid_sop());
- fprintf(vif, "bcdDevice_SOP: 0x%04x\r\n", bcddevice_sop());
-
- {
- int svid_num;
-
- /* Write SOP Discovery -Part One Tab comment */
- write_tab(vif, SOP2);
-#ifdef USB_SID_DISPLAYPORT
- svid_num = 2;
-#else
- svid_num = 1;
-#endif
- fprintf(vif, "SVID_fixed_SOP: YES\r\n");
- fprintf(vif, "Num_SVIDs_min_SOP: %d\r\n", svid_num);
- fprintf(vif, "Num_SVIDs_max_SOP: %d\r\n\n", svid_num);
- }
-
- fprintf(vif, "\tSVID1_SOP: 0x%04x\r\n", USB_VID_GOOGLE);
- fprintf(vif, "\tSVID1_modes_fixed_SOP: YES\r\n");
- fprintf(vif, "\tSVID1_num_modes_min_SOP: 1\r\n");
- fprintf(vif, "\tSVID1_num_modes_max_SOP: 1\r\n");
- fprintf(vif, "\tSVID1_mode1_enter_SOP: YES\r\n\n");
-
-#ifdef USB_SID_DISPLAYPORT
- fprintf(vif, "\tSVID2_SOP: 0x%04x\r\n", USB_SID_DISPLAYPORT);
- fprintf(vif, "\tSVID2_modes_fixed_SOP: YES\r\n");
- fprintf(vif, "\tSVID2_num_modes_min_SOP: 2\r\n");
- fprintf(vif, "\tSVID2_num_modes_max_SOP: 2\r\n");
- fprintf(vif, "\tSVID2_mode1_enter_SOP: YES\r\n");
- fprintf(vif, "\tSVID2_mode2_enter_SOP: YES\r\n");
-#endif
- fclose(vif);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- int nopt;
- int ret;
- const char *out = NULL;
- const char *board = NULL;
- const char *vif_producer;
- DIR *vifdir;
- char *name;
- int name_size;
- const char * const short_opt = "hb:o:";
- const struct option long_opts[] = {
- { "help", 0, NULL, 'h' },
- { "board", 1, NULL, 'b' },
- { "out", 1, NULL, 'o' },
- { NULL }
- };
-
- vif_producer = argv[0];
-
- do {
- nopt = getopt_long(argc, argv, short_opt, long_opts, NULL);
- switch (nopt) {
- case 'h': /* -h or --help */
- printf("USAGE: %s -b <board name> -o <out directory>\n",
- vif_producer);
- return 1;
-
- case 'b': /* -b or --board */
- board = optarg;
- break;
-
- case 'o': /* -o or --out */
- out = optarg;
- break;
-
- case -1:
- break;
-
- default:
- abort();
- }
- } while (nopt != -1);
-
- if (out == NULL || board == NULL)
- return 1;
-
- /* Make sure VIF directory exists */
- vifdir = opendir(out);
- if (vifdir == NULL) {
- fprintf(stderr, "ERROR: %s directory does not exist.\n", out);
- return 1;
- }
- closedir(vifdir);
-
- init_src_pdos();
-
- name_size = asprintf(&name, "%s/%s_vif.txt", out, board);
- if (name_size < 0) {
- fprintf(stderr, "ERROR: Out of memory.\n");
- return 1;
- }
-
- ret = gen_vif(name, board, vif_producer);
-
- free(name);
-
- return ret;
-}
diff --git a/util/host_command_check.sh b/util/host_command_check.sh
deleted file mode 100755
index 62911bb0c3..0000000000
--- a/util/host_command_check.sh
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2017 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.
-
-#######################################
-# Test if the following conditions hold for the ec host command
-# The alpha numeric value of the define starts with 0x
-# The alpha numeric value of the define is 4-hex digits
-# The hex digits "A B C D E F" are capitalized
-# Arguments:
-# string - ec host command to check
-# Returns:
-# 0 if command is ok, else 1
-########################################
-check_cmd() {
- IFS=" "
- # Remove any tabs that may exist
- tts=$(echo "$1" | sed 's/\t/ /g')
- arr=( $tts )
-
- # Check for 0x
- if [[ "${arr[2]}" != 0x* ]]; then
- return 1
- fi
-
- # Check that length is 6. 0x + 4 hex digits
- if [[ ${#arr[2]} != 6 ]]; then
- return 1
- fi
-
- # Check that hex digits are valid and uppercase
- hd=${arr[2]:2}
- if ! [[ $hd =~ ^[0-9A-F]{4}$ ]]; then
- return 1
- fi
-
- # command is ok
- return 0
-}
-
-#######################################
-# Test if the string arg is in one of the following formats:
-# file.X:#define EC_CMD_X XxXXXX
-# file.X:#define EC_PRV_CMD_X XxXXXX
-# Arguments:
-# string - potential ec host command
-# Returns:
-# 0 if command is formated properly, else 1
-########################################
-should_check() {
- IFS=" "
- arr=( $1 )
-
- # Check for file.X:#define
- IFS=":"
- temp=( ${arr[0]} )
- # Check for file.X
- if [ ! -f "${temp[0]}" ]; then
- return 1
- fi
-
- # Check for #define
- if [[ "${temp[1]}" != "#define" ]]; then
- return 1
- fi
-
- # Check for EC_CMD_XXX or EC_PRV_CMD_XXX
- if [[ "${arr[1]}" != EC_CMD_* ]] && [[ "${arr[1]}" != EC_PRV_CMD_* ]]; then
- return 1
- fi
-
- # Check for EC_XXX_XXX(n)
- if [[ "${arr[1]}" =~ ')'$ ]]; then
- return 1
- fi
-
- return 0
-}
-
-main() {
-
- # Do not run the check unless an EC_[xxx]CMD change is present.
- if [[ -z "$(git diff "${PRESUBMIT_COMMIT}~" "${PRESUBMIT_COMMIT}" -U0 |
- egrep 'EC_[^ ]*CMD')" ]]; then
- exit 0
- fi
-
- ec_errors=()
- ei=0
- # Search all file occurrences of "EC_CMD" and store in array
- IFS=$'\n'
- ec_cmds=($(grep -r "EC_CMD"))
-
- # Loop through and find valid occurrences of "EC_CMD" to check
- length=${#ec_cmds[@]}
- for ((i = 0; i != length; i++)); do
- if should_check "${ec_cmds[i]}"; then
- if ! check_cmd "${ec_cmds[i]}"; then
- ec_errors[$ei]="${ec_cmds[i]}"
- ((ei++))
- fi
- fi
- done
-
- # Search all file occurrances of "EC_PRV_CMD" and store in array
- IFS=$'\n'
- ec_prv_cmds=($(grep -r "EC_PRV_CMD"))
-
- # Loop through and find valid occurrences of "EC_PRV_CMD" to check
- length=${#ec_prv_cmds[@]}
- for ((i = 0; i != length; i++)); do
- if should_check "${ec_prv_cmds[i]}"; then
- if ! check_cmd "${ec_prv_cmds[i]}"; then
- ec_errors[$ei]="${ec_prv_cmds[i]}"
- ((ei++))
- fi
- fi
- done
-
- # Check if any malformed ec host commands were found
- if [ ! $ei -eq 0 ]; then
- echo "The following host commands are malformed:"
- # print all malformed host commands
- for ((i = 0; i != ei; i++)); do
- echo "FILE: ${ec_errors[i]}"
- done
- exit 1
- fi
-
- exit 0
-}
-
-main "$@"
diff --git a/util/inject-keys.py b/util/inject-keys.py
deleted file mode 100755
index 380fc34729..0000000000
--- a/util/inject-keys.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
-#
-# Copyright 2016 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.
-
-import string
-import subprocess
-import sys
-
-
-KEYMATRIX = {'`': (3, 1), '1': (6, 1), '2': (6, 4), '3': (6, 2), '4': (6, 3),
- '5': (3, 3), '6': (3, 6), '7': (6, 6), '8': (6, 5), '9': (6, 9),
- '0': (6, 8), '-': (3, 8), '=': (0, 8), 'q': (7, 1), 'w': (7, 4),
- 'e': (7, 2), 'r': (7, 3), 't': (2, 3), 'y': (2, 6), 'u': (7, 6),
- 'i': (7, 5), 'o': (7, 9), 'p': (7, 8), '[': (2, 8), ']': (2, 5),
- '\\': (3, 11), 'a': (4, 1), 's': (4, 4), 'd': (4, 2), 'f': (4, 3),
- 'g': (1, 3), 'h': (1, 6), 'j': (4, 6), 'k': (4, 5), 'l': (4, 9),
- ';': (4, 8), '\'': (1, 8), 'z': (5, 1), 'x': (5, 4), 'c': (5, 2),
- 'v': (5, 3), 'b': (0, 3), 'n': (0, 6), 'm': (5, 6), ',': (5, 5),
- '.': (5, 9), '/': (5, 8), ' ': (5, 11), '<right>': (6, 12),
- '<alt_r>': (0, 10), '<down>': (6, 11), '<tab>': (2, 1),
- '<f10>': (0, 4), '<shift_r>': (7, 7), '<ctrl_r>': (4, 0),
- '<esc>': (1, 1), '<backspace>': (1, 11), '<f2>': (3, 2),
- '<alt_l>': (6, 10), '<ctrl_l>': (2, 0), '<f1>': (0, 2),
- '<search>': (0, 1), '<f3>': (2, 2), '<f4>': (1, 2), '<f5>': (3, 4),
- '<f6>': (2, 4), '<f7>': (1, 4), '<f8>': (2, 9), '<f9>': (1, 9),
- '<up>': (7, 11), '<shift_l>': (5, 7), '<enter>': (4, 11),
- '<left>': (7, 12)}
-
-
-UNSHIFT_TABLE = { '~': '`', '!': '1', '@': '2', '#': '3', '$': '4',
- '%': '5', '^': '6', '&': '7', '*': '8', '(': '9',
- ')': '0', '_': '-', '+': '=', '{': '[', '}': ']',
- '|': '\\',
- ':': ';', '"': "'", '<': ',', '>': '.', '?': '/'}
-
-for c in string.ascii_lowercase:
- UNSHIFT_TABLE[c.upper()] = c
-
-
-def inject_event(key, press):
- if len(key) >= 2 and key[0] != '<':
- key = '<' + key + '>'
- if key not in KEYMATRIX:
- print "%s: invalid key: %s" % (this_script, key)
- sys.exit(1)
- (row, col) = KEYMATRIX[key]
- subprocess.call(["ectool", "kbpress", str(row), str(col),
- "1" if press else "0"])
-
-
-def inject_key(key):
- inject_event(key, True)
- inject_event(key, False)
-
-
-def inject_string(string):
- for c in string:
- if c in KEYMATRIX:
- inject_key(c)
- elif c in UNSHIFT_TABLE:
- inject_event("<shift_l>", True)
- inject_key(UNSHIFT_TABLE[c])
- inject_event("<shift_l>", False)
- else:
- print "unimplemented character:", c
- sys.exit(1)
-
-
-def usage():
- print "Usage: %s [-s <string>] [-k <key>]" % this_script, \
- "[-p <pressed-key>] [-r <released-key>] ..."
- print "Examples:"
- print "%s -s MyPassw0rd -k enter" % this_script
- print "%s -p ctrl_l -p alt_l -k f3 -r alt_l -r ctrl_l" % this_script
-
-
-def help():
- usage()
- print "Valid keys are:"
- i = 0
- for key in KEYMATRIX:
- print "%12s" % key,
- i += 1
- if i % 4 == 0:
- print
- print
- print "angle brackets may be omitted"
-
-
-def usage_check(asserted_condition, message):
- if asserted_condition:
- return
- print "%s:" % this_script, message
- usage()
- sys.exit(1)
-
-
-# -- main
-
-this_script = sys.argv[0]
-arg_len = len(sys.argv)
-
-if arg_len > 1 and sys.argv[1] == "--help":
- help()
- sys.exit(0)
-
-usage_check(arg_len > 1, "not enough arguments")
-usage_check(arg_len % 2 == 1, "mismatched arguments")
-
-for i in range(1, arg_len, 2):
- usage_check(sys.argv[i] in ("-s", "-k", "-p", "-r"),
- "unknown flag: %s" % sys.argv[i])
-
-for i in range(1, arg_len, 2):
- flag = sys.argv[i]
- arg = sys.argv[i+1]
- if flag == "-s":
- inject_string(arg)
- elif flag == "-k":
- inject_key(arg)
- elif flag == "-p":
- inject_event(arg, True)
- elif flag == "-r":
- inject_event(arg, False)
diff --git a/util/iteflash.c b/util/iteflash.c
deleted file mode 100644
index fd83980c77..0000000000
--- a/util/iteflash.c
+++ /dev/null
@@ -1,2142 +0,0 @@
-/* Copyright 2013 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.
- *
- * ITE83xx SoC in-system programming tool
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <ftdi.h>
-#include <getopt.h>
-#include <linux/i2c-dev.h>
-#include <linux/i2c.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "compile_time_macros.h"
-#include "usb_if.h"
-
-/* Default FTDI device : Servo v2. */
-#define SERVO_USB_VID 0x18d1
-#define SERVO_USB_PID 0x5002
-#define SERVO_INTERFACE INTERFACE_B
-
-/* Default CCD device: Cr50. */
-#define CR50_USB_VID 0x18d1
-#define CR50_USB_PID 0x5014
-
-/* Cr50 exposed properties of the USB I2C endpoint. */
-#define CR50_I2C_SUBCLASS 82
-#define CR50_I2C_PROTOCOL 1
-
-#define CROS_CMD_ADDR 0x78 /* USB_I2C_CMD_ADDR 0xF0 >> 1 */
-#define CROS_CMD_ITE_SYNC 0
-
-/* DBGR I2C addresses */
-#define I2C_CMD_ADDR 0x5A
-#define I2C_DATA_ADDR 0x35
-#define I2C_BLOCK_ADDR 0x79
-
-#define FTDI_I2C_FREQ 400000
-
-/* I2C pins on the FTDI interface */
-#define SCL_BIT BIT(0)
-#define SDA_BIT BIT(1)
-
-/* Chip ID register value */
-#define CHIP_ID 0x8380
-
-/* Embedded flash page size */
-#define PAGE_SIZE (1<<8)
-
-/* Embedded flash block write size for different programming modes. */
-#define FTDI_BLOCK_WRITE_SIZE (1<<16)
-
-/* Embedded flash number of pages in a sector erase */
-#define SECTOR_ERASE_PAGES 4
-
-/* JEDEC SPI Flash commands */
-#define SPI_CMD_PAGE_PROGRAM 0x02
-#define SPI_CMD_WRITE_DISABLE 0x04
-#define SPI_CMD_READ_STATUS 0x05
-#define SPI_CMD_WRITE_ENABLE 0x06
-#define SPI_CMD_FAST_READ 0x0B
-#define SPI_CMD_CHIP_ERASE 0x60
-#define SPI_CMD_SECTOR_ERASE 0xD7
-#define SPI_CMD_WORD_PROGRAM 0xAD
-#define SPI_CMD_EWSR 0x50 /* Enable Write Status Register */
-#define SPI_CMD_WRSR 0x01 /* Write Status Register */
-
-/* Size for FTDI outgoing buffer */
-#define FTDI_CMD_BUF_SIZE (1<<12)
-
-/* Reset Status */
-#define RSTS_VCCDO_PW_ON 0x40
-#define RSTS_VFSPIPG 0x20
-#define RSTS_HGRST 0x08
-#define RSTS_GRST 0x04
-
-/* I2C MUX Configuration: TCA9543 or PCA9546 */
-#define I2C_MUX_CMD_ADDR 0x70
-#define I2C_MUX_CMD_NONE 0x00
-#define I2C_MUX_CMD_INAS 0x01
-#define I2C_MUX_CMD_EC 0x02
-
-static volatile sig_atomic_t exit_requested;
-
-struct i2c_interface;
-
-/* Config mostly comes from the command line. Defaults are set in main(). */
-struct iteflash_config {
- char *input_filename;
- char *output_filename;
- int send_waveform; /* boolean */
- int erase; /* boolean */
- int i2c_mux; /* boolean */
- int debug; /* boolean */
- int disable_watchdog; /* boolean */
- int disable_protect_path; /* boolean */
- int block_write_size;
- int usb_interface;
- int usb_vid;
- int usb_pid;
- char *usb_serial;
- char *i2c_dev_path;
- const struct i2c_interface *i2c_if;
- size_t range_base;
- size_t range_size;
-};
-
-struct common_hnd {
- struct iteflash_config conf;
- int flash_size;
- int flash_cmd_v2; /* boolean */
- int dbgr_addr_3bytes; /* boolean */
- union {
- int i2c_dev_fd;
- struct usb_endpoint uep;
- struct ftdi_context *ftdi_hnd;
- };
-};
-
-/* For all callback return values, zero indicates success, non-zero failure. */
-struct i2c_interface {
- /* Optional, may be NULL. */
- int (*interface_init)(struct common_hnd *chnd);
- /* Always called if non-NULL, even if special waveform is skipped! */
- /* Optional, may be NULL. */
- int (*interface_post_waveform)(struct common_hnd *chnd);
- /* Called exactly once if and only if interface_init() succeeded. */
- /* Optional, may be NULL. */
- int (*interface_shutdown)(struct common_hnd *chnd);
- /* Optional, may be NULL (unsupported for this I2C interface type). */
- int (*send_special_waveform)(struct common_hnd *chnd);
- /* Required, must not be NULL. */
- int (*byte_transfer)(struct common_hnd *chnd, uint8_t addr,
- uint8_t *data, int write, int numbytes);
- /* Required, must be positive. */
- int default_block_write_size;
-};
-
-static void null_and_free(void **ptr)
-{
- void *holder;
-
- if (*ptr) {
- holder = *ptr;
- *ptr = NULL;
- free(holder);
- }
-}
-
-/* This releases any memory owned by *conf. This does NOT free conf itself! */
-/* Not all pointers in conf necessarily point to memory owned by it. */
-static void config_release(struct iteflash_config *conf)
-{
- null_and_free((void **)&conf->input_filename);
- null_and_free((void **)&conf->output_filename);
- null_and_free((void **)&conf->usb_serial);
- null_and_free((void **)&conf->i2c_dev_path);
-}
-
-/* number of bytes to send consecutively before checking for ACKs */
-#define FTDI_TX_BUFFER_LIMIT 32
-
-static inline int i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr,
- uint8_t *data, int write, int numbytes)
-{
- return chnd->conf.i2c_if->byte_transfer(chnd, addr, data, write,
- numbytes);
-}
-
-static int linux_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr,
- uint8_t *data, int write, int numbytes)
-{
- static const int nmsgs = 1;
- int ret, extra_int;
- struct i2c_msg i2cmsg = {};
- struct i2c_rdwr_ioctl_data msgset = {};
-
- i2cmsg.addr = addr;
- if (!write)
- i2cmsg.flags |= I2C_M_RD;
- i2cmsg.buf = data;
- i2cmsg.len = numbytes;
-
- msgset.msgs = &i2cmsg;
- msgset.nmsgs = nmsgs;
-
- ret = ioctl(chnd->i2c_dev_fd, I2C_RDWR, &msgset);
- if (ret < 0) {
- extra_int = errno;
- fprintf(stderr, "%s: ioctl() failed with return value %d and "
- "errno %d\n", __func__, ret, extra_int);
- if (ret == -1 && extra_int)
- ret = -abs(extra_int);
- } else if (ret < nmsgs) {
- fprintf(stderr, "%s: failed to send %d of %d I2C messages\n",
- __func__, (nmsgs - ret), nmsgs);
- ret = -1;
- } else {
- ret = 0;
- }
- return ret;
-}
-
-static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf,
- uint8_t *ptr, uint8_t *tbuf, int tcnt, int debug)
-{
- int ret, i, j, remaining_data, ack_idx;
- int tx_buffered = 0;
- static uint8_t ack[FTDI_TX_BUFFER_LIMIT];
- uint8_t *b = ptr;
- uint8_t failed_ack = 0;
-
- for (i = 0; i < tcnt; i++) {
- /* If we got a termination signal, stop sending data */
- if (exit_requested)
- return -1;
-
- /* WORKAROUND: force SDA before sending the next byte */
- *b++ = SET_BITS_LOW; *b++ = SDA_BIT; *b++ = SCL_BIT | SDA_BIT;
- /* write byte */
- *b++ = MPSSE_DO_WRITE | MPSSE_BITMODE | MPSSE_WRITE_NEG;
- *b++ = 0x07; *b++ = *tbuf++;
- /* prepare for ACK */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT;
- /* read ACK */
- *b++ = MPSSE_DO_READ | MPSSE_BITMODE | MPSSE_LSB;
- *b++ = 0;
- *b++ = SEND_IMMEDIATE;
-
- tx_buffered++;
-
- /*
- * On the last byte, or every FTDI_TX_BUFFER_LIMIT bytes, read
- * the ACK bits.
- */
- if (i == tcnt-1 || (tx_buffered == FTDI_TX_BUFFER_LIMIT)) {
- /* write data */
- ret = ftdi_write_data(ftdi, buf, b - buf);
- if (ret < 0) {
- fprintf(stderr, "failed to write byte\n");
- return ret;
- }
-
- /* read ACK bits */
- remaining_data = tx_buffered;
- ack_idx = 0;
- do {
- ret = ftdi_read_data(ftdi, &ack[ack_idx],
- remaining_data);
- if (ret < 0) {
- fprintf(stderr, "read ACK failed\n");
- return ret;
- }
- remaining_data -= ret;
- ack_idx += ret;
- } while (remaining_data);
- for (j = 0; j < tx_buffered; j++) {
- if ((ack[j] & 0x80) != 0)
- failed_ack = ack[j];
- }
-
- /* check ACK bits */
- if (ret < 0 || failed_ack) {
- if (debug)
- fprintf(stderr,
- "write ACK fail: %d, 0x%02x\n",
- ret, failed_ack);
- return -ENXIO;
- }
-
- /* reset for next set of transactions */
- b = ptr;
- tx_buffered = 0;
- }
- }
- return 0;
-}
-
-static int i2c_add_recv_bytes(struct ftdi_context *ftdi, uint8_t *buf,
- uint8_t *ptr, uint8_t *rbuf, int rcnt)
-{
- int ret, i, rbuf_idx;
- uint8_t *b = ptr;
-
- for (i = 0; i < rcnt; i++) {
- /* set SCL low */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT;
- /* read the byte on the wire */
- *b++ = MPSSE_DO_READ; *b++ = 0; *b++ = 0;
-
- if (i == rcnt - 1) {
- /* NACK last byte */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT;
- *b++ = MPSSE_DO_WRITE | MPSSE_BITMODE | MPSSE_WRITE_NEG;
- *b++ = 0; *b++ = 0xff; *b++ = SEND_IMMEDIATE;
- } else {
- /* ACK all other bytes */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT | SDA_BIT;
- *b++ = MPSSE_DO_WRITE | MPSSE_BITMODE | MPSSE_WRITE_NEG;
- *b++ = 0; *b++ = 0; *b++ = SEND_IMMEDIATE;
- }
- }
-
- ret = ftdi_write_data(ftdi, buf, b - buf);
- if (ret < 0) {
- fprintf(stderr, "failed to prepare read\n");
- return ret;
- }
-
- rbuf_idx = 0;
- do {
- /* If we got a termination signal, stop sending data */
- if (exit_requested)
- return -1;
-
- ret = ftdi_read_data(ftdi, &rbuf[rbuf_idx], rcnt);
- if (ret < 0) {
- fprintf(stderr, "read byte failed\n");
- break;
- }
- rcnt -= ret;
- rbuf_idx += ret;
- } while (rcnt);
-
- return ret;
-}
-
-#define USB_I2C_HEADER_SIZE 4
-static int ccd_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr,
- uint8_t *data, int write, int numbytes)
-{
- uint8_t usb_buffer[USB_I2C_HEADER_SIZE + numbytes +
- (((!write * numbytes) > 0x7f) ? 2 : 0)];
- size_t response_size;
- size_t extra = 0;
-
- /* Do nothing if user wants to quit. */
- if (exit_requested)
- return -1;
-
- /*
- * Build a message following format described in ./include/usb_i2c.h.
- *
- * Hardcode port, the lowest 4 bits of the first byte, to 0; may need
- * to make this a command line option.
- */
- usb_buffer[0] = 0;
-
- usb_buffer[1] = addr;
- if (write) {
- /*
- * Write count might spill over into the top 4 bits of the
- * first byte. We trust the caller not to pass numbytes
- * exceeding (2^12 - 1).
- */
- if (numbytes > 255)
- usb_buffer[0] |= (numbytes >> 4) & 0xf0;
- usb_buffer[2] = numbytes & 0xff;
- usb_buffer[3] = 0;
- memcpy(usb_buffer + USB_I2C_HEADER_SIZE, data, numbytes);
- } else {
- usb_buffer[2] = 0;
- if (numbytes < 0x80) {
- usb_buffer[3] = numbytes;
- } else {
- usb_buffer[3] = (numbytes & 0x7f) | 0x80;
- usb_buffer[4] = numbytes >> 7;
- usb_buffer[5] = 0;
- extra = 2;
- }
- }
-
- response_size = 0;
- usb_trx(&chnd->uep, usb_buffer,
- write ? sizeof(usb_buffer) : USB_I2C_HEADER_SIZE + extra,
- usb_buffer, sizeof(usb_buffer), 1, &response_size);
-
- if (response_size < (USB_I2C_HEADER_SIZE + (write ? 0 : numbytes))) {
- fprintf(stderr, "%s: got too few bytes (%zd) in response\n",
- __func__, response_size);
- return -1;
- }
-
- if (usb_buffer[0]) {
- uint32_t rv;
-
- /*
- * Error is reported as a 16 bit value in little endian byte
- * order.
- */
- rv = usb_buffer[1];
- rv = (rv << 8) + usb_buffer[0];
-
- fprintf(stderr, "%s: usb i2c error %d\n",
- __func__,
- (((uint16_t)usb_buffer[1]) << 8) + usb_buffer[0]);
-
- return -rv;
- }
-
- if (!write)
- memcpy(data, usb_buffer + USB_I2C_HEADER_SIZE, numbytes);
-
- return 0;
-}
-
-static int ftdi_i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr,
- uint8_t *data, int write, int numbytes)
-{
- int ret, rets;
- static uint8_t buf[FTDI_CMD_BUF_SIZE];
- uint8_t *b;
- uint8_t slave_addr;
- struct ftdi_context *ftdi;
-
- ret = 0;
- b = buf;
- ftdi = chnd->ftdi_hnd;
-
- /* START condition */
- /* SCL & SDA high */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0;
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0;
- /* SCL high, SDA low */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT;
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT;
- /* SCL low, SDA low */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT | SDA_BIT;
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SCL_BIT | SDA_BIT;
-
- /* send address */
- slave_addr = (addr << 1) | (write ? 0 : 1);
- ret = i2c_add_send_byte(ftdi, buf, b, &slave_addr, 1, chnd->conf.debug);
- if (ret < 0) {
- if (chnd->conf.debug)
- fprintf(stderr, "address %02x failed\n", addr);
- ret = -ENXIO;
- goto exit_xfer;
- }
-
- b = buf;
- if (write) /* write data */
- ret = i2c_add_send_byte(ftdi, buf, b, data, numbytes,
- chnd->conf.debug);
- else /* read data */
- ret = i2c_add_recv_bytes(ftdi, buf, b, data, numbytes);
-
-exit_xfer:
- b = buf;
- /* STOP condition */
- /* SCL high, SDA low */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT;
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = SDA_BIT;
- /* SCL high, SDA high */
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0;
- *b++ = SET_BITS_LOW; *b++ = 0; *b++ = 0;
-
- rets = ftdi_write_data(ftdi, buf, b - buf);
- if (rets < 0)
- fprintf(stderr, "failed to send STOP\n");
- return ret;
-}
-
-static int i2c_write_byte(struct common_hnd *chnd, uint8_t cmd, uint8_t data)
-{
- int ret;
-
- ret = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1);
- if (ret < 0)
- return -EIO;
- ret = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &data, 1, 1);
- if (ret < 0)
- return -EIO;
-
- return 0;
-}
-
-static int i2c_read_byte(struct common_hnd *chnd, uint8_t cmd, uint8_t *data)
-{
- int ret;
-
- ret = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1);
- if (ret < 0)
- return -EIO;
- ret = i2c_byte_transfer(chnd, I2C_DATA_ADDR, data, 0, 1);
- if (ret < 0)
- return -EIO;
-
- return 0;
-}
-
-/* Configure I2C MUX to choose EC Prog channel */
-static int config_i2c_mux(struct common_hnd *chnd, uint8_t cmd)
-{
- int ret;
-
- ret = i2c_byte_transfer(chnd, I2C_MUX_CMD_ADDR, &cmd, 1, 1);
- if (ret < 0) {
- fprintf(stderr, "Failed to configure I2C MUX.");
- return -EIO;
- }
-
- return 0;
-}
-
-/* Get 3rd Byte Chip ID */
-static int get_3rd_chip_id_byte(struct common_hnd *chnd, uint8_t *chip_id)
-{
- int ret = 0;
-
- ret = i2c_write_byte(chnd, 0x80, 0xf0);
- ret |= i2c_write_byte(chnd, 0x2f, 0x20);
- ret |= i2c_write_byte(chnd, 0x2e, 0x85);
- ret |= i2c_read_byte(chnd, 0x30, chip_id);
-
- if (ret < 0)
- fprintf(stderr, "Failed to get id of 3rd byte.");
-
- return ret;
-}
-
-/* Fills in chnd->flash_size */
-static int check_chipid(struct common_hnd *chnd)
-{
- int ret;
- uint8_t ver = 0xff;
- uint32_t id = 0xffff;
- uint16_t v2[5] = {128, 192, 256, 384, 512};
- /*
- * Chip Version is mapping from bit 3-0
- * Flash size is mapping from bit 7-4
- *
- * Chip Version (bit 3-0)
- * 0: AX
- * 1: BX
- * 2: CX
- * 3: DX
- *
- * CX before flash size (bit 7-4)
- * 0:128KB
- * 4:192KB
- * 8:256KB
- *
- * DX flash size(bit 7-4)
- * 0:128KB
- * 2:192KB
- * 4:256KB
- * 6:384KB
- * 8:512KB
- *
- * flash size(bit 7-4) of it8xxx1 or it8xxx2 series
- * 0:128KB
- * 2:192KB
- * 4:256KB
- * 6:384KB
- * 8:512KB
- */
-
- ret = i2c_read_byte(chnd, 0x00, (uint8_t *)&id + 1);
- if (ret < 0)
- return ret;
- ret = i2c_read_byte(chnd, 0x01, (uint8_t *)&id);
- if (ret < 0)
- return ret;
- ret = i2c_read_byte(chnd, 0x02, &ver);
- if (ret < 0)
- return ret;
-
- if ((id & 0xff00) != (CHIP_ID & 0xff00)) {
- id |= 0xff0000;
- ret = get_3rd_chip_id_byte(chnd, (uint8_t *)&id+2);
- if (ret < 0)
- return ret;
-
- if ((id & 0xf000f) == 0x80001 || (id & 0xf000f) == 0x80002) {
- chnd->flash_cmd_v2 = 1;
- chnd->dbgr_addr_3bytes = 1;
- } else {
- fprintf(stderr, "Invalid chip id: %05x\n", id);
- return -EINVAL;
- }
- } else {
- chnd->dbgr_addr_3bytes = 0;
- if ((ver & 0x0f) >= 0x03)
- chnd->flash_cmd_v2 = 1;
- else
- chnd->flash_cmd_v2 = 0;
- }
- /* compute embedded flash size from CHIPVER field */
- if (chnd->flash_cmd_v2)
- chnd->flash_size = v2[(ver & 0xF0)>>5] * 1024;
- else
- chnd->flash_size = (128 + (ver & 0xF0)) * 1024;
-
- printf("CHIPID %05x, CHIPVER %02x, Flash size %d kB\n", id, ver,
- chnd->flash_size / 1024);
-
- return 0;
-}
-
-/* DBGR Reset */
-static int dbgr_reset(struct common_hnd *chnd, unsigned char val)
-{
- int ret = 0;
-
- /* Reset CPU only, and we keep power state until flashing is done. */
- if (chnd->dbgr_addr_3bytes)
- ret |= i2c_write_byte(chnd, 0x80, 0xf0);
-
- ret |= i2c_write_byte(chnd, 0x2f, 0x20);
- ret |= i2c_write_byte(chnd, 0x2e, 0x06);
-
- /* Enable the Reset Status by val */
- ret |= i2c_write_byte(chnd, 0x30, val);
-
- ret |= i2c_write_byte(chnd, 0x27, 0x80);
- if (ret < 0)
- fprintf(stderr, "DBGR RESET FAILED\n");
-
- return 0;
-}
-
-/* disable watchdog */
-static int dbgr_disable_watchdog(struct common_hnd *chnd)
-{
- int ret = 0;
-
- printf("Disabling watchdog...\n");
- if (chnd->dbgr_addr_3bytes)
- ret |= i2c_write_byte(chnd, 0x80, 0xf0);
-
- ret |= i2c_write_byte(chnd, 0x2f, 0x1f);
- ret |= i2c_write_byte(chnd, 0x2e, 0x05);
- ret |= i2c_write_byte(chnd, 0x30, 0x30);
-
- if (ret < 0)
- fprintf(stderr, "DBGR DISABLE WATCHDOG FAILED!\n");
-
- return ret;
-}
-
-/* disable protect path from DBGR */
-static int dbgr_disable_protect_path(struct common_hnd *chnd)
-{
- int ret = 0, i;
-
- printf("Disabling protect path...\n");
-
- if (chnd->dbgr_addr_3bytes)
- ret |= i2c_write_byte(chnd, 0x80, 0xf0);
-
- ret |= i2c_write_byte(chnd, 0x2f, 0x20);
- for (i = 0; i < 32; i++) {
- ret |= i2c_write_byte(chnd, 0x2e, 0xa0+i);
- ret |= i2c_write_byte(chnd, 0x30, 0);
- }
-
- if (ret < 0)
- fprintf(stderr, "DISABLE PROTECT PATH FROM DBGR FAILED!\n");
-
- return ret;
-}
-
-/* Enter follow mode and FSCE# high level */
-static int spi_flash_follow_mode(struct common_hnd *chnd, char *desc)
-{
- int ret = 0;
-
- ret |= i2c_write_byte(chnd, 0x07, 0x7f);
- ret |= i2c_write_byte(chnd, 0x06, 0xff);
- ret |= i2c_write_byte(chnd, 0x05, 0xfe);
- ret |= i2c_write_byte(chnd, 0x04, 0x00);
- ret |= i2c_write_byte(chnd, 0x08, 0x00);
-
- ret = (ret ? -EIO : 0);
- if (ret < 0)
- fprintf(stderr, "Flash %s enter follow mode FAILED (%d)\n",
- desc, ret);
-
- return ret;
-}
-
-/* Exit follow mode */
-static int spi_flash_follow_mode_exit(struct common_hnd *chnd, char *desc)
-{
- int ret = 0;
-
- ret |= i2c_write_byte(chnd, 0x07, 0x00);
- ret |= i2c_write_byte(chnd, 0x06, 0x00);
-
- ret = (ret ? -EIO : 0);
- if (ret < 0)
- fprintf(stderr, "Flash %s exit follow mode FAILED (%d)\n",
- desc, ret);
-
- return ret;
-}
-
-/* SPI Flash generic command, short version */
-static int spi_flash_command_short(struct common_hnd *chnd,
- uint8_t cmd, char *desc)
-{
- int ret = 0;
-
- ret |= i2c_write_byte(chnd, 0x05, 0xfe);
- ret |= i2c_write_byte(chnd, 0x08, 0x00);
- ret |= i2c_write_byte(chnd, 0x05, 0xfd);
- ret |= i2c_write_byte(chnd, 0x08, cmd);
-
- ret = (ret ? -EIO : 0);
- if (ret < 0)
- fprintf(stderr, "Flash CMD %s FAILED (%d)\n", desc, ret);
-
- return ret;
-}
-
-/* SPI Flash set erase page */
-static int spi_flash_set_erase_page(struct common_hnd *chnd,
- int page, char *desc)
-{
- int ret = 0;
-
- ret |= i2c_write_byte(chnd, 0x08, page >> 8);
- ret |= i2c_write_byte(chnd, 0x08, page & 0xff);
- ret |= i2c_write_byte(chnd, 0x08, 0);
-
- ret = (ret ? -EIO : 0);
- if (ret < 0)
- fprintf(stderr, "Flash %s set page FAILED (%d)\n", desc, ret);
-
- return ret;
-}
-
-/* Poll SPI Flash Read Status register until BUSY is reset */
-static int spi_poll_busy(struct common_hnd *chnd, char *desc)
-{
- uint8_t reg = 0xff;
- int ret = -EIO;
-
- if (spi_flash_command_short(chnd, SPI_CMD_READ_STATUS,
- "read status for busy bit") < 0) {
- fprintf(stderr, "Flash %s wait busy cleared FAILED\n", desc);
- goto failed_read_status;
- }
-
- while (1) {
- if (i2c_byte_transfer(chnd, I2C_DATA_ADDR, &reg, 0, 1) < 0) {
- fprintf(stderr, "Flash polling busy cleared FAILED\n");
- break;
- }
-
- if ((reg & 0x01) == 0) {
- /* busy bit cleared */
- ret = 0;
- break;
- }
- }
-failed_read_status:
- return ret;
-}
-
-static int spi_check_write_enable(struct common_hnd *chnd, char *desc)
-{
- uint8_t reg = 0xff;
- int ret = -EIO;
-
- if (spi_flash_command_short(chnd, SPI_CMD_READ_STATUS,
- "read status for write enable bit") < 0) {
- fprintf(stderr, "Flash %s wait WE FAILED\n", desc);
- goto failed_read_status;
- }
-
- while (1) {
- if (i2c_byte_transfer(chnd, I2C_DATA_ADDR, &reg, 0, 1) < 0) {
- fprintf(stderr, "Flash polling WE FAILED\n");
- break;
- }
-
- if ((reg & 0x03) == 2) {
- /* busy bit cleared and WE bit set */
- ret = 0;
- break;
- }
- }
-failed_read_status:
- return ret;
-}
-
-static int ftdi_config_i2c(struct ftdi_context *ftdi)
-{
- int ret;
- static const uint16_t divisor =
- 60000000 / (2 * FTDI_I2C_FREQ * 3 / 2 /* 3-phase CLK */) - 1;
- uint8_t clock_buf[] = {
- EN_3_PHASE,
- DIS_DIV_5,
- TCK_DIVISOR,
- divisor & 0xff,
- divisor >> 8};
-
- ret = ftdi_set_latency_timer(ftdi, 16 /* ms */);
- if (ret < 0)
- fprintf(stderr, "Cannot set latency\n");
-
- ret = ftdi_set_bitmode(ftdi, 0, BITMODE_RESET);
- if (ret < 0) {
- fprintf(stderr, "Cannot reset MPSSE\n");
- return -EIO;
- }
- ret = ftdi_set_bitmode(ftdi, 0, BITMODE_MPSSE);
- if (ret < 0) {
- fprintf(stderr, "Cannot enable MPSSE\n");
- return -EIO;
- }
-
- ret = ftdi_usb_purge_buffers(ftdi);
- if (ret < 0)
- fprintf(stderr, "Cannot purge buffers\n");
-
- /* configure the clock */
- ret = ftdi_write_data(ftdi, clock_buf, sizeof(clock_buf));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-/* Special waveform definition */
-#define SPECIAL_LEN_USEC 50000ULL /* us */
-#define SPECIAL_FREQ 400000ULL
-
-#define SPECIAL_PATTERN 0x0000020301010302ULL
-#define SPECIAL_PATTERN_SDA_L_SCL_L 0x0000000000000000ULL
-#define SPECIAL_PATTERN_SDA_H_SCL_L 0x0202020202020202ULL
-#define SPECIAL_PATTERN_SDA_L_SCL_H 0x0101010101010101ULL
-#define SPECIAL_PATTERN_SDA_H_SCL_H 0x0303030303030303ULL
-#define TICK_COUNT 24
-
-#define MSEC 1000
-#define USEC 1000000
-
-#define SPECIAL_BUFFER_SIZE \
- (((SPECIAL_LEN_USEC * SPECIAL_FREQ * 2 / USEC) + 7) & ~7)
-
-static int connect_to_ccd_i2c_bridge(struct common_hnd *chnd)
-{
- int rv;
-
- rv = usb_findit(chnd->conf.usb_serial, chnd->conf.usb_vid,
- chnd->conf.usb_pid, CR50_I2C_SUBCLASS,
- CR50_I2C_PROTOCOL, &chnd->uep);
-
- if (rv) {
- fprintf(stderr, "%s: usb_findit returned error %d\n",
- __func__, rv);
- }
-
- return rv;
-}
-
-static int ccd_trigger_special_waveform(struct common_hnd *chnd)
-{
- uint8_t response[20];
- size_t rsize;
- uint8_t req[] = {
- 0, /* Port 0. Might be necessary to modify. */
- CROS_CMD_ADDR, /* Chrome OS dedicated address. */
- 1, /* Will send a single byte command. */
- 0, /* No need to read back anything. */
- CROS_CMD_ITE_SYNC
- };
-
- usb_trx(&chnd->uep, req, sizeof(req), response, sizeof(response), 1,
- &rsize);
-
- if (rsize < USB_I2C_HEADER_SIZE)
- return -1;
-
- if (response[0])
- return -response[0];
- /*
- * The target is about to get reset, let's shut down the USB
- * connection.
- */
- usb_shut_down(&chnd->uep);
-
- sleep(3);
-
- return connect_to_ccd_i2c_bridge(chnd);
-}
-
-static int ftdi_send_special_waveform(struct common_hnd *chnd)
-{
- int ret;
- int i;
- uint64_t *wave;
- struct ftdi_context *ftdi = chnd->ftdi_hnd;
- uint8_t release_lines[] = {SET_BITS_LOW, 0, 0};
-
- wave = malloc(SPECIAL_BUFFER_SIZE);
- if (!wave) {
- fprintf(stderr, "malloc(%zu) failed\n",
- (size_t)SPECIAL_BUFFER_SIZE);
- return -1;
- }
-
- /* Reset the FTDI into a known state */
- ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET);
- if (ret) {
- fprintf(stderr, "failed to reset FTDI\n");
- goto free_and_return;
- }
-
- /*
- * set the clock divider, so we output a new bitbang value every
- * 2.5us.
- */
- ret = ftdi_set_baudrate(ftdi, 160000);
- if (ret) {
- fprintf(stderr, "failed to set bitbang clock\n");
- goto free_and_return;
- }
-
- /* Enable asynchronous bit-bang mode */
- ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG);
- if (ret) {
- fprintf(stderr, "failed to set bitbang mode\n");
- goto free_and_return;
- }
-
- /* do usb special waveform */
- wave[0] = 0x0;
- ftdi_write_data(ftdi, (uint8_t *)wave, 1);
- usleep(5000);
-
- /* program each special tick */
- for (i = 0; i < TICK_COUNT; ) {
- wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
- wave[i++] = SPECIAL_PATTERN_SDA_H_SCL_L;
- wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
- }
- wave[19] = SPECIAL_PATTERN_SDA_H_SCL_H;
-
- /* fill the buffer with the waveform pattern */
- for (i = TICK_COUNT; i < SPECIAL_BUFFER_SIZE / sizeof(uint64_t); i++)
- wave[i] = SPECIAL_PATTERN;
-
- ret = ftdi_write_data(ftdi, (uint8_t *)wave, SPECIAL_BUFFER_SIZE);
- if (ret < 0)
- fprintf(stderr, "Cannot output special waveform\n");
- else
- /* no error */
- ret = 0;
-
- /* clean everything to go back to regular I2C communication */
- ftdi_usb_purge_buffers(ftdi);
- ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET);
- ftdi_config_i2c(ftdi);
- ftdi_write_data(ftdi, release_lines, sizeof(release_lines));
-
- free_and_return:
- free(wave);
- return ret;
-}
-
-static int send_special_waveform(struct common_hnd *chnd)
-{
- const int max_iterations = 10;
- int ret;
- int iterations;
-
- if (!chnd->conf.i2c_if->send_special_waveform) {
- fprintf(stderr, "This binary does not support sending the ITE "
- "special waveform with the chosen I2C interface.\n");
- return -1;
- }
-
- iterations = 0;
-
- do {
- ret = chnd->conf.i2c_if->send_special_waveform(chnd);
- if (ret)
- break;
-
- /* wait for PLL stable for 5ms (plus remaining USB transfers) */
- usleep(10 * MSEC);
-
- if (spi_flash_follow_mode(chnd, "enter follow mode") >= 0) {
- spi_flash_follow_mode_exit(chnd, "exit follow mode");
- /*
- * If we can talk to chip, then we can break the retry
- * loop.
- */
- ret = check_chipid(chnd);
- } else {
- ret = -1;
- if (!(iterations % max_iterations))
- fprintf(stderr, "!please reset EC if flashing"
- " sequence is not starting!\n");
- }
- } while (ret && (iterations++ < max_iterations));
-
- if (ret)
- fprintf(stderr, "Failed to send special waveform!\n");
- else
- printf("Done with sending special waveform.\n");
-
- return ret;
-}
-
-static int windex;
-static const char wheel[] = {'|', '/', '-', '\\' };
-static void draw_spinner(uint32_t remaining, uint32_t size)
-{
- int percent = (size - remaining)*100/size;
- fprintf(stderr, "\r%c%3d%%", wheel[windex++], percent);
- windex %= sizeof(wheel);
-}
-
-static int command_read_pages(struct common_hnd *chnd, uint32_t address,
- uint32_t size, uint8_t *buffer)
-{
- int res = -EIO;
- uint32_t remaining = size;
- int cnt;
- uint8_t addr_H, addr_M;
-
- if (address & 0xFF) {
- fprintf(stderr, "page read requested at non-page boundary: "
- "0x%X\n", address);
- return -EINVAL;
- }
-
- if (spi_flash_follow_mode(chnd, "fast read") < 0)
- goto failed_read;
-
- while (remaining) {
- uint8_t cmd = 0x9;
-
- cnt = (remaining > PAGE_SIZE) ? PAGE_SIZE : remaining;
- addr_H = (address >> 16) & 0xFF;
- addr_M = (address >> 8) & 0xFF;
-
- draw_spinner(remaining, size);
-
- /* Fast Read command */
- if (spi_flash_command_short(chnd, SPI_CMD_FAST_READ,
- "fast read") < 0)
- goto failed_read;
- res = i2c_write_byte(chnd, 0x08, addr_H);
- res += i2c_write_byte(chnd, 0x08, addr_M);
- res += i2c_write_byte(chnd, 0x08, 0x00); /* addr_L */
- res += i2c_write_byte(chnd, 0x08, 0x00);
- if (res < 0) {
- fprintf(stderr, "page address set failed\n");
- goto failed_read;
- }
-
- /* read page data */
- res = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1);
- res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, buffer, 0, cnt);
- if (res < 0) {
- fprintf(stderr, "page data read failed\n");
- goto failed_read;
- }
-
- address += cnt;
- remaining -= cnt;
- buffer += cnt;
- }
- /* No error so far */
- res = size;
-failed_read:
- if (spi_flash_follow_mode_exit(chnd, "fast read") < 0)
- res = -EIO;
-
- return res;
-}
-
-static int command_write_pages(struct common_hnd *chnd, uint32_t address,
- uint32_t size, uint8_t *buffer)
-{
- int res = -EIO;
- int block_write_size = chnd->conf.block_write_size;
- uint32_t remaining = size;
- int cnt;
- uint8_t addr_H, addr_M, addr_L;
- uint8_t data;
-
- if (spi_flash_follow_mode(chnd, "AAI write") < 0)
- goto failed_write;
-
- while (remaining) {
- cnt = (remaining > block_write_size) ?
- block_write_size : remaining;
- addr_H = (address >> 16) & 0xFF;
- addr_M = (address >> 8) & 0xFF;
- addr_L = address & 0xFF;
-
- draw_spinner(remaining, size);
-
- /* Write enable */
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
- "write enable for AAI write") < 0)
- goto failed_write;
-
- /* Check write enable bit */
- if (spi_check_write_enable(chnd, "AAI write") < 0)
- goto failed_write;
-
- /* Setup write */
- if (spi_flash_command_short(chnd, SPI_CMD_WORD_PROGRAM,
- "AAI write") < 0)
- goto failed_write;
-
- /* Set eflash page address */
- res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_H, 1, 1);
- res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_M, 1, 1);
- res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_L, 1, 1);
- if (res < 0) {
- fprintf(stderr, "Flash write set page FAILED (%d)\n",
- res);
- goto failed_write;
- }
-
- /* Wait until not busy */
- if (spi_poll_busy(chnd, "AAI write") < 0)
- goto failed_write;
-
- /* Write up to block_write_size data */
- res = i2c_write_byte(chnd, 0x10, 0x20);
- res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, buffer, 1, cnt);
- buffer += cnt;
-
- if (res < 0) {
- fprintf(stderr, "Flash data write failed\n");
- goto failed_write;
- }
-
- data = 0xFF;
- res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &data, 1, 1);
- res |= i2c_write_byte(chnd, 0x10, 0x00);
- if (res < 0) {
- fprintf(stderr, "Flash end data write FAILED (%d)\n",
- res);
- goto failed_write;
- }
-
- /* Write disable */
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable for AAI write") < 0)
- goto failed_write;
-
- /* Wait until available */
- if (spi_poll_busy(chnd, "write disable for AAI write") < 0)
- goto failed_write;
-
- address += cnt;
- remaining -= cnt;
- }
- draw_spinner(remaining, size);
- /* No error so far */
- res = size;
-failed_write:
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable exit AAI write") < 0)
- res = -EIO;
-
- if (spi_flash_follow_mode_exit(chnd, "AAI write") < 0)
- res = -EIO;
-
- return res;
-}
-
-/*
- * Write another program flow to match the
- * original ITE 8903 Download board.
- */
-static int command_write_pages2(struct common_hnd *chnd, uint32_t address,
- uint32_t size, uint8_t *buffer,
- int block_write_size)
-{
- int res = 0;
- uint8_t addr_H, addr_M, addr_L;
- uint8_t data;
-
- res |= i2c_write_byte(chnd, 0x07, 0x7f);
- res |= i2c_write_byte(chnd, 0x06, 0xff);
- res |= i2c_write_byte(chnd, 0x04, 0xFF);
-
- /* SMB_SPI_Flash_Enable_Write_Status */
- if (spi_flash_command_short(chnd, SPI_CMD_EWSR,
- "Enable Write Status Register") < 0) {
- res = -EIO;
- goto failed_write;
- }
-
- /* SMB_SPI_Flash_Write_Status_Reg */
- res |= i2c_write_byte(chnd, 0x05, 0xfe);
- res |= i2c_write_byte(chnd, 0x08, 0x00);
- res |= i2c_write_byte(chnd, 0x05, 0xfd);
- res |= i2c_write_byte(chnd, 0x08, 0x01);
- res |= i2c_write_byte(chnd, 0x08, 0x00);
-
- /* SMB_SPI_Flash_Write_Enable */
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
- "SPI Command Write Enable") < 0) {
- res = -EIO;
- goto failed_write;
- }
-
- /* SMB_SST_SPI_Flash_AAI2_Program */
- if (spi_flash_command_short(chnd, SPI_CMD_WORD_PROGRAM,
- "SPI AAI2 Program") < 0) {
- res = -EIO;
- goto failed_write;
- }
-
- addr_H = (address >> 16) & 0xFF;
- addr_M = (address >> 8) & 0xFF;
- addr_L = address & 0xFF;
-
- res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_H, 1, 1);
- res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_M, 1, 1);
- res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_L, 1, 1);
- res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, buffer++, 1, 1);
- res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, buffer++, 1, 1);
-
- /* Wait until not busy */
- if (spi_poll_busy(chnd, "AAI write") < 0)
- goto failed_write;
-
- res = i2c_write_byte(chnd, 0x10, 0x20);
- res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, buffer, 1,
- block_write_size-2);
-
- /* No error so far */
- res = size;
-
- data = 0xFF;
- res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &data, 1, 1);
- res = i2c_write_byte(chnd, 0x10, 0x00);
-
-failed_write:
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable exit AAI write") < 0)
- res = -EIO;
-
- return res;
-}
-
-static int command_erase(struct common_hnd *chnd, uint32_t len, uint32_t off)
-{
- int res = -EIO;
- int page = 0;
- uint32_t remaining = len;
-
- printf("Erasing chip...\n");
-
- if (off != 0 || len != chnd->flash_size) {
- fprintf(stderr, "Only full chip erase is supported\n");
- return -EINVAL;
- }
-
- if (spi_flash_follow_mode(chnd, "erase") < 0)
- goto failed_erase;
-
- while (remaining) {
- draw_spinner(remaining, len);
-
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
- "write enable for erase") < 0)
- goto failed_erase;
-
- if (spi_check_write_enable(chnd, "erase") < 0)
- goto failed_erase;
-
- /* do chip erase */
- if (remaining == chnd->flash_size) {
- if (spi_flash_command_short(chnd, SPI_CMD_CHIP_ERASE,
- "chip erase") < 0)
- goto failed_erase;
- goto wait_busy_cleared;
- }
-
- /* do sector erase */
- if (spi_flash_command_short(chnd, SPI_CMD_SECTOR_ERASE,
- "sector erase") < 0)
- goto failed_erase;
-
- if (spi_flash_set_erase_page(chnd, page, "sector erase") < 0)
- goto failed_erase;
-
-wait_busy_cleared:
- if (spi_poll_busy(chnd, "erase") < 0)
- goto failed_erase;
-
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable for erase") < 0)
- goto failed_erase;
-
- if (remaining == chnd->flash_size) {
- remaining = 0;
- draw_spinner(remaining, len);
- } else {
- page += SECTOR_ERASE_PAGES;
- remaining -= SECTOR_ERASE_PAGES * PAGE_SIZE;
- }
- }
-
- /* No error so far */
- printf("\n\rErasing Done.\n");
- res = 0;
-
-failed_erase:
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable exit erase") < 0)
- res = -EIO;
-
- if (spi_flash_follow_mode_exit(chnd, "erase") < 0)
- res = -EIO;
-
- return res;
-}
-
-/*
- * This function can Erase First Sector or Erase All Sector by reset value
- * Some F/W will produce the H/W watchdog reset and it will happen
- * reset issue while flash.
- * Add such function to prevent the reset issue.
- */
-static int command_erase2(struct common_hnd *chnd, uint32_t len,
- uint32_t off, uint32_t reset)
-{
- int res = -EIO;
- int page = 0;
- uint32_t remaining = len;
-
- /*
- * TODOD(b/<>):
- * Using sector erase instead of chip erase
- * For some new chip , the chip erase may not work
- * well on the original flow
- */
-
- printf("Erasing flash...erase size=%d\n", len);
-
- if (off != 0 || len != chnd->flash_size) {
- fprintf(stderr, "Only full chip erase is supported\n");
- return -EINVAL;
- }
-
- if (spi_flash_follow_mode(chnd, "erase") < 0)
- goto failed_erase;
-
- while (remaining) {
-
- draw_spinner(remaining, len);
-
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
- "write enable for erase") < 0)
- goto failed_erase;
-
- if (spi_check_write_enable(chnd, "erase") < 0)
- goto failed_erase;
-
- /* do sector erase */
- if (spi_flash_command_short(chnd, SPI_CMD_SECTOR_ERASE,
- "sector erase") < 0)
- goto failed_erase;
-
- if (spi_flash_set_erase_page(chnd, page, "sector erase") < 0)
- goto failed_erase;
-
- if (spi_poll_busy(chnd, "erase") < 0)
- goto failed_erase;
-
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable for erase") < 0)
- goto failed_erase;
-
- if (reset) {
- printf("\n\rreset to prevent the watchdog reset...\n");
- break;
- }
-
- page += SECTOR_ERASE_PAGES;
- remaining -= SECTOR_ERASE_PAGES * PAGE_SIZE;
- draw_spinner(remaining, len);
-
- }
-
- /* No error so far */
- printf("\n\rErasing Done.\n");
- res = 0;
-
-failed_erase:
- if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
- "write disable exit erase") < 0)
- res = -EIO;
-
- if (spi_flash_follow_mode_exit(chnd, "erase") < 0)
- res = -EIO;
-
- return res;
-}
-
-/* Return zero on success, a negative error value on failures. */
-static int read_flash(struct common_hnd *chnd)
-{
- int res;
- FILE *hnd;
- uint8_t *buffer;
- const char *filename = chnd->conf.input_filename;
- size_t offset = chnd->conf.range_base;
- size_t size;
-
- if (!offset && !chnd->conf.range_size) {
- size = chnd->flash_size;
- } else {
- /*
- * Zero conf.range_size means the user did not enter range
- * size in the command line.
- */
- if (chnd->conf.range_size)
- size = chnd->conf.range_size;
- else
- size = chnd->flash_size - offset;
-
- if (!size) {
- fprintf(stderr,
- "Error: not reading a zero sized range!\n");
- return -EINVAL;
- }
-
- if ((size + offset) > chnd->flash_size) {
- fprintf(stderr,
- "Error: Read range exceeds flash size!\n");
- return -EINVAL;
- }
- }
-
- buffer = malloc(size);
- if (!buffer) {
- fprintf(stderr, "Cannot allocate %zd bytes\n", size);
- return -ENOMEM;
- }
-
- hnd = fopen(filename, "w");
- if (!hnd) {
- fprintf(stderr, "Cannot open file %s for writing\n", filename);
- free(buffer);
- return -EIO;
- }
-
- printf("Reading %zd bytes at %#08zx\n", size, offset);
- res = command_read_pages(chnd, offset, size, buffer);
- if (res > 0) {
- if (fwrite(buffer, res, 1, hnd) != 1)
- fprintf(stderr, "Cannot write %s\n", filename);
- }
- printf("\r %d bytes read.\n", res);
-
- fclose(hnd);
- free(buffer);
- return (res < 0) ? res : 0;
-}
-
-/* Return zero on success, a negative error value on failures. */
-static int write_flash(struct common_hnd *chnd, const char *filename,
- uint32_t offset)
-{
- int res, written;
- FILE *hnd;
- int size = chnd->flash_size;
- uint8_t *buffer = malloc(size);
-
- if (!buffer) {
- fprintf(stderr, "%s: Cannot allocate %d bytes\n", __func__,
- size);
- return -ENOMEM;
- }
-
- hnd = fopen(filename, "r");
- if (!hnd) {
- fprintf(stderr, "%s: Cannot open file %s for reading\n",
- __func__, filename);
- free(buffer);
- return -EIO;
- }
- res = fread(buffer, 1, size, hnd);
- if (res <= 0) {
- fprintf(stderr, "%s: Failed to read %d bytes from %s with "
- "ferror() %d\n", __func__, size, filename, ferror(hnd));
- free(buffer);
- fclose(hnd);
- return -EIO;
- }
- fclose(hnd);
-
- printf("Writing %d bytes at 0x%08x\n", res, offset);
- written = command_write_pages(chnd, offset, res, buffer);
- if (written != res) {
- fprintf(stderr, "%s: Error writing to flash\n", __func__);
- free(buffer);
- return -EIO;
- }
- printf("\n\rWriting Done.\n");
-
- free(buffer);
- return 0;
-}
-
-/*
- * Return zero on success, a negative error value on failures.
- *
- * Change the program command to match the ITE Download
- * The original flow may not work on the DX chip.
- *
- */
-static int write_flash2(struct common_hnd *chnd, const char *filename,
- uint32_t offset)
-{
- int res, written;
- int block_write_size = chnd->conf.block_write_size;
- FILE *hnd;
- int size = chnd->flash_size;
- int cnt;
- uint8_t *buffer = malloc(size);
-
- if (!buffer) {
- fprintf(stderr, "%s: Cannot allocate %d bytes\n", __func__,
- size);
- return -ENOMEM;
- }
-
- hnd = fopen(filename, "r");
- if (!hnd) {
- fprintf(stderr, "%s: Cannot open file %s for reading\n",
- __func__, filename);
- free(buffer);
- return -EIO;
- }
- res = fread(buffer, 1, size, hnd);
- if (res <= 0) {
- fprintf(stderr, "%s: Failed to read %d bytes from %s with "
- "ferror() %d\n", __func__, size, filename, ferror(hnd));
- fclose(hnd);
- free(buffer);
- return -EIO;
- }
- fclose(hnd);
-
- offset = 0;
- printf("Writing %d bytes at 0x%08x.......\n", res, offset);
- while (res) {
- cnt = (res > block_write_size) ? block_write_size : res;
- written = command_write_pages2(chnd, offset, cnt,
- &buffer[offset], block_write_size);
- if (written == -EIO)
- goto failed_write;
-
- res -= cnt;
- offset += cnt;
- draw_spinner(res, res + offset);
- }
-
- if (written != res) {
-failed_write:
- fprintf(stderr, "%s: Error writing to flash\n", __func__);
- free(buffer);
- return -EIO;
- }
- printf("\n\rWriting Done.\n");
- free(buffer);
-
- return 0;
-}
-
-/* Return zero on success, a non-zero value on failures. */
-static int verify_flash(struct common_hnd *chnd, const char *filename,
- uint32_t offset)
-{
- int res;
- int file_size;
- FILE *hnd;
- uint8_t *buffer = malloc(chnd->flash_size);
- uint8_t *buffer2 = malloc(chnd->flash_size);
-
- if (!buffer || !buffer2) {
- fprintf(stderr, "%s: Cannot allocate %d bytes\n", __func__,
- chnd->flash_size);
- free(buffer);
- free(buffer2);
- return -ENOMEM;
- }
-
- hnd = fopen(filename, "r");
- if (!hnd) {
- fprintf(stderr, "%s: Cannot open file %s for reading\n",
- __func__, filename);
- res = -EIO;
- goto exit;
- }
-
- file_size = fread(buffer, 1, chnd->flash_size, hnd);
- if (file_size <= 0) {
- fprintf(stderr, "%s: Failed to read %d bytes from %s with "
- "ferror() %d\n", __func__, chnd->flash_size, filename,
- ferror(hnd));
- fclose(hnd);
- res = -EIO;
- goto exit;
- }
- fclose(hnd);
-
- printf("Verify %d bytes at 0x%08x\n", file_size, offset);
- res = command_read_pages(chnd, offset, chnd->flash_size, buffer2);
- if (res > 0)
- res = memcmp(buffer, buffer2, file_size);
-
- printf("\n\rVerify %s\n", res ? "Failed!" : "Done.");
-
-exit:
- free(buffer);
- free(buffer2);
- return res;
-}
-
-static struct ftdi_context *open_ftdi_device(int vid, int pid,
- int interface, const char *serial)
-{
- struct ftdi_context *ftdi;
- int ret;
-
- ftdi = ftdi_new();
- if (!ftdi) {
- fprintf(stderr, "Cannot allocate context memory\n");
- return NULL;
- }
-
- ret = ftdi_set_interface(ftdi, interface);
- if (ret < 0) {
- fprintf(stderr, "cannot set ftdi interface %d: %s(%d)\n",
- interface, ftdi_get_error_string(ftdi), ret);
- goto open_failed;
- }
- ret = ftdi_usb_open_desc(ftdi, vid, pid, NULL, serial);
- if (ret < 0) {
- fprintf(stderr, "unable to open ftdi device: %s(%d)\n",
- ftdi_get_error_string(ftdi), ret);
- goto open_failed;
- }
- return ftdi;
-
-open_failed:
- ftdi_free(ftdi);
- return NULL;
-}
-
-static int linux_i2c_interface_init(struct common_hnd *chnd)
-{
- int err;
-
- if (!chnd->conf.i2c_dev_path) {
- fprintf(stderr, "Must set --i2c_dev_path when using "
- "Linux i2c-dev interface.\n");
- return -1;
- }
- printf("Attempting to open Linux i2c-dev path %s\n",
- chnd->conf.i2c_dev_path);
- chnd->i2c_dev_fd = open(chnd->conf.i2c_dev_path, O_RDWR);
- if (chnd->i2c_dev_fd < 0) {
- err = errno;
- perror("Failed to open Linux i2c-dev file path with error");
- fprintf(stderr, "Linux i2c-dev file path from --i2c_dev_path "
- "is: %s\n", chnd->conf.i2c_dev_path);
- return err ? err : -1;
- }
- printf("Successfully opened Linux i2c-dev path %s\n",
- chnd->conf.i2c_dev_path);
- return 0;
-}
-
-static int linux_i2c_interface_shutdown(struct common_hnd *chnd)
-{
- int err;
-
- printf("Attempting to close Linux i2c-dev file descriptor %d\n",
- chnd->i2c_dev_fd);
- if (close(chnd->i2c_dev_fd)) {
- err = errno;
- perror("Failed to close Linux i2c-dev file descriptor with "
- "error");
- return err ? err : -1;
- }
- printf("Successfully closed Linux i2c-dev file descriptor %d\n",
- chnd->i2c_dev_fd);
- return 0;
-}
-
-static int ccd_i2c_interface_init(struct common_hnd *chnd)
-{
- chnd->conf.usb_vid = CR50_USB_VID;
- chnd->conf.usb_pid = CR50_USB_PID;
- return connect_to_ccd_i2c_bridge(chnd);
-}
-
-static int ccd_i2c_interface_shutdown(struct common_hnd *chnd)
-{
- usb_shut_down(&chnd->uep);
- return 0;
-}
-
-static int ftdi_i2c_interface_init(struct common_hnd *chnd)
-{
- chnd->ftdi_hnd = open_ftdi_device(chnd->conf.usb_vid,
- chnd->conf.usb_pid, chnd->conf.usb_interface,
- chnd->conf.usb_serial);
- if (chnd->ftdi_hnd == NULL)
- return -1;
- return 0;
-}
-
-static int ftdi_i2c_interface_post_waveform(struct common_hnd *chnd)
-{
- return chnd->conf.send_waveform ? 0 : ftdi_config_i2c(chnd->ftdi_hnd);
-}
-
-/* Close the FTDI USB handle */
-static int ftdi_i2c_interface_shutdown(struct common_hnd *chnd)
-{
- ftdi_usb_close(chnd->ftdi_hnd);
- ftdi_free(chnd->ftdi_hnd);
- return 0;
-}
-
-static const struct i2c_interface linux_i2c_interface = {
- .interface_init = linux_i2c_interface_init,
- .interface_shutdown = linux_i2c_interface_shutdown,
- .byte_transfer = linux_i2c_byte_transfer,
- /*
- * 254 bytes is the largest size that works with Servo Micro as of
- * 2018-11-30. Odd numbers up to 255 result in corruption, and 256 or
- * greater fails with a timeout from the I2C bus. Fixing that so this
- * can be increased to match FTDI_BLOCK_WRITE_SIZE would be a useful
- * speedup.
- *
- * 254 byte block sizes cause corruption with Ampton (using any kind of
- * servo). 128 bytes is the largest block_write_size compatible with
- * both Ampton and Servo Micro.
- *
- * See https://issuetracker.google.com/79684405 for background.
- */
- .default_block_write_size = 128,
-};
-
-static const struct i2c_interface ccd_i2c_interface = {
- .interface_init = ccd_i2c_interface_init,
- .interface_shutdown = ccd_i2c_interface_shutdown,
- .send_special_waveform = ccd_trigger_special_waveform,
- .byte_transfer = ccd_i2c_byte_transfer,
- .default_block_write_size = PAGE_SIZE,
-};
-
-static const struct i2c_interface ftdi_i2c_interface = {
- .interface_init = ftdi_i2c_interface_init,
- .interface_post_waveform = ftdi_i2c_interface_post_waveform,
- .interface_shutdown = ftdi_i2c_interface_shutdown,
- .send_special_waveform = ftdi_send_special_waveform,
- .byte_transfer = ftdi_i2c_byte_transfer,
- .default_block_write_size = FTDI_BLOCK_WRITE_SIZE,
-};
-
-static int post_waveform_work(struct common_hnd *chnd)
-{
- int ret;
-
- if (chnd->conf.i2c_if->interface_post_waveform) {
- ret = chnd->conf.i2c_if->interface_post_waveform(chnd);
- if (ret)
- return ret;
- }
-
- if (chnd->conf.disable_watchdog) {
- ret = dbgr_disable_watchdog(chnd);
- if (ret)
- return ret;
- }
-
- if (chnd->conf.disable_protect_path) {
- ret = dbgr_disable_protect_path(chnd);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int strdup_with_errmsg(const char *source, char **dest, const char *name)
-{
- int ret = 0;
- *dest = strdup(source);
- if (!(*dest)) {
- ret = errno ? errno : -1;
- fprintf(stderr, "strdup() of %zu size string from %s failed.\n",
- strlen(source), name);
- }
- return ret;
-}
-
-static const struct option longopts[] = {
- {"block-write-size", 1, 0, 'b'},
- {"debug", 0, 0, 'd'},
- {"erase", 0, 0, 'e'},
- {"help", 0, 0, 'h'},
- {"i2c-dev-path", 1, 0, 'D'},
- {"i2c-interface", 1, 0, 'c'},
- {"i2c-mux", 0, 0, 'm'},
- {"interface", 1, 0, 'i'},
- {"nodisable-protect-path", 0, 0, 'Z'},
- {"nodisable-watchdog", 0, 0, 'z'},
- {"product", 1, 0, 'p'},
- {"range", 1, 0, 'R'},
- {"read", 1, 0, 'r'},
- {"send-waveform", 1, 0, 'W'},
- {"serial", 1, 0, 's'},
- {"vendor", 1, 0, 'v'},
- {"write", 1, 0, 'w'},
- {NULL, 0, 0, 0}
-};
-
-static void display_usage(const char *program)
-{
- fprintf(stderr, "Usage: %s [-d] [-v <VID>] [-p <PID>] \\\n"
- "\t[-c <linux|ccd|ftdi>] [-D /dev/i2c-<N>] [-i <1|2>] [-S] \\\n"
- "\t[-s <serial>] [-e] [-r <file>] [-W <0|1|false|true>] \\\n"
- "\t[-w <file>] [-R base[:size]] [-m] [-b <size>]\n",
- program);
- fprintf(stderr, "-d, --debug : Output debug traces.\n");
- fprintf(stderr, "-e, --erase : Erase all the flash content.\n");
- fprintf(stderr, "-c, --i2c-interface <linux|ccd|ftdi> : I2C interface "
- "to use\n");
- fprintf(stderr, "-D, --i2c-dev-path /dev/i2c-<N> : Path to "
- "Linux i2c-dev file e.g. /dev/i2c-5;\n"
- "\tonly applicable with --i2c-interface=linux\n");
- fprintf(stderr, "-i, --interface <1> : FTDI interface: A=1, B=2,"
- " ...\n");
- fprintf(stderr, "-m, --i2c-mux : Enable i2c-mux (to EC).\n"
- "\tSpecify this flag only if the board has an I2C MUX and\n"
- "\tyou are not using servod.\n");
- fprintf(stderr, "-b, --block-write-size <size> : Perform writes in\n"
- "\tblocks of this many bytes.\n");
- fprintf(stderr, "-p, --product <0x1234> : USB product ID\n");
- fprintf(stderr, "-R, --range base[:size] : Allow to read or write"
- " just a slice\n"
- "\tof the file, starting at <base>:<size> bytes, or til\n"
- "\tthe end of the file if <size> is not specified, expressed\n"
- "\tin hex.\n");
- fprintf(stderr, "-r, --read <file> : Read the flash content and"
- " write it into <file>.\n");
- fprintf(stderr, "-s, --serial <serialname> : USB serial string\n");
- fprintf(stderr, "-v, --vendor <0x1234> : USB vendor ID\n");
- fprintf(stderr, "-W, --send-waveform <0|1|false|true> : Send the"
- " special waveform.\n"
- "\tDefault is true. Set to false if ITE direct firmware\n"
- "\tupdate mode has already been enabled.\n");
- fprintf(stderr, "-w, --write <file> : Write <file> to flash.\n");
- fprintf(stderr, "-z, --nodisable-watchdog : Do *not* disable EC "
- "watchdog.\n");
- fprintf(stderr, "-Z, --nodisable-protect-path : Do *not* disable EC "
- "protect path.\n");
-}
-
-/*
- * Parses -R command line option parameter, returns zero on success and
- * -1 on errors (non hex values, missing values, etc.).
- */
-static int parse_range_options(char *str, struct iteflash_config *conf)
-{
- char *size;
-
- if (!str) {
- fprintf(stderr, "missing range base address specification\n");
- return -1;
- }
-
- conf->range_base = strtoul(str, &size, 16);
- if (!size || !*size)
- return 0;
-
- if (*size++ != ':') {
- fprintf(stderr, "wrong range base address specification\n");
- return -1;
- }
-
- if (!*size) {
- fprintf(stderr, "missing range size specification\n");
- return -1;
- }
-
- conf->range_size = strtoul(size, &size, 16);
- if ((size && *size) || !conf->range_size) {
- fprintf(stderr, "wrong range size specification\n");
- return -1;
- }
-
- return 0;
-}
-
-static int parse_parameters(int argc, char **argv, struct iteflash_config *conf)
-{
- int opt, idx, ret = 0;
-
- while (!ret &&
- (opt = getopt_long(argc, argv, "?b:c:D:dehi:mp:R:r:s:uv:W:w:Zz",
- longopts, &idx)) != -1) {
- switch (opt) {
- case 'b':
- conf->block_write_size = strtol(optarg, NULL, 10);
- break;
- case 'c':
- if (!strcasecmp(optarg, "linux")) {
- conf->i2c_if = &linux_i2c_interface;
- } else if (!strcasecmp(optarg, "ccd")) {
- conf->i2c_if = &ccd_i2c_interface;
- } else if (!strcasecmp(optarg, "ftdi")) {
- conf->i2c_if = &ftdi_i2c_interface;
- } else {
- fprintf(stderr, "Unexpected -c / "
- "--i2c-interface value: %s\n", optarg);
- ret = -1;
- }
- break;
- case 'D':
- ret = strdup_with_errmsg(optarg, &conf->i2c_dev_path,
- "-D / --i2c-dev-path");
- break;
- case 'd':
- conf->debug = 1;
- break;
- case 'e':
- conf->erase = 1;
- break;
- case 'h':
- case '?':
- display_usage(argv[0]);
- ret = 2;
- break;
- case 'i':
- conf->usb_interface = strtol(optarg, NULL, 10);
- break;
- case 'm':
- conf->i2c_mux = 1;
- break;
- case 'p':
- conf->usb_pid = strtol(optarg, NULL, 16);
- break;
- case 'R':
- ret = parse_range_options(optarg, conf);
- break;
- case 'r':
- ret = strdup_with_errmsg(optarg, &conf->input_filename,
- "-r / --read");
- break;
- case 's':
- ret = strdup_with_errmsg(optarg, &conf->usb_serial,
- "-s / --serial");
- break;
- case 'v':
- conf->usb_vid = strtol(optarg, NULL, 16);
- break;
- case 'W':
- if (!strcmp(optarg, "0") ||
- !strcasecmp(optarg, "false")) {
- conf->send_waveform = 0;
- break;
- }
- if (!strcmp(optarg, "1") ||
- !strcasecmp(optarg, "true")) {
- conf->send_waveform = 1;
- break;
- }
- fprintf(stderr, "Unexpected -W / --special-waveform "
- "value: %s\n", optarg);
- ret = -1;
- break;
- case 'w':
- ret = strdup_with_errmsg(optarg, &conf->output_filename,
- "-w / --write");
- break;
- case 'z':
- conf->disable_watchdog = 0;
- break;
- case 'Z':
- conf->disable_protect_path = 0;
- break;
- }
- }
-
- if (ret)
- config_release(conf);
- return ret;
-}
-
-static void sighandler(int signum)
-{
- printf("\nCaught signal %d: %s\nExiting...\n",
- signum, sys_siglist[signum]);
- exit_requested = 1;
-}
-
-static void register_sigaction(void)
-{
- struct sigaction sigact;
-
- sigact.sa_handler = sighandler;
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = 0;
- sigaction(SIGINT, &sigact, NULL);
- sigaction(SIGTERM, &sigact, NULL);
- sigaction(SIGQUIT, &sigact, NULL);
-}
-
-int main(int argc, char **argv)
-{
- int ret = 1, other_ret;
- struct common_hnd chnd = {
- /* Default flag settings. */
- .conf = {
- .send_waveform = 1,
- .disable_watchdog = 1,
- .disable_protect_path = 1,
- .usb_interface = SERVO_INTERFACE,
- .usb_vid = SERVO_USB_VID,
- .usb_pid = SERVO_USB_PID,
- .i2c_if = &ftdi_i2c_interface,
- },
- };
-
- /* Parse command line options */
- other_ret = parse_parameters(argc, argv, &chnd.conf);
- if (other_ret)
- return other_ret;
-
- /* Fill in block_write_size if not set from command line. */
- if (!chnd.conf.block_write_size)
- chnd.conf.block_write_size =
- chnd.conf.i2c_if->default_block_write_size;
-
- /* Open the communications channel. */
- if (chnd.conf.i2c_if->interface_init &&
- chnd.conf.i2c_if->interface_init(&chnd))
- goto return_after_parse;
-
- /* Register signal handler after opening the communications channel. */
- register_sigaction();
-
- if (chnd.conf.i2c_mux) {
- printf("configuring I2C MUX to EC.\n");
-
- if (config_i2c_mux(&chnd, I2C_MUX_CMD_EC))
- goto return_after_init;
- }
-
- /* Trigger embedded monitor detection */
- if (chnd.conf.send_waveform) {
- if (send_special_waveform(&chnd))
- goto return_after_init;
- } else {
- ret = check_chipid(&chnd);
- if (ret) {
- fprintf(stderr, "Failed to get ITE chip ID. This "
- "could be because the ITE direct firmware "
- "update (DFU) mode is not enabled.\n");
- goto return_after_init;
- }
- }
-
- ret = post_waveform_work(&chnd);
- if (ret)
- goto return_after_init;
-
- if (chnd.conf.input_filename) {
- ret = read_flash(&chnd);
- if (ret)
- goto return_after_init;
- }
-
- if (chnd.conf.erase) {
- if (chnd.flash_cmd_v2)
- /* Do Normal Erase Function */
- command_erase2(&chnd, chnd.flash_size, 0, 0);
- else
- command_erase(&chnd, chnd.flash_size, 0);
- /* Call DBGR Rest to clear the EC lock status after erasing */
- dbgr_reset(&chnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
- }
-
- if (chnd.conf.output_filename) {
- if (chnd.flash_cmd_v2)
- ret = write_flash2(&chnd, chnd.conf.output_filename, 0);
- else
- ret = write_flash(&chnd, chnd.conf.output_filename, 0);
- if (ret)
- goto return_after_init;
- ret = verify_flash(&chnd, chnd.conf.output_filename, 0);
- if (ret)
- goto return_after_init;
- }
-
- /* Normal exit */
- ret = 0;
-
- return_after_init:
- /* Enable EC Host Global Reset to reset EC resource and EC domain. */
- dbgr_reset(&chnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
-
- if (chnd.conf.i2c_mux) {
- printf("configuring I2C MUX to none.\n");
- config_i2c_mux(&chnd, I2C_MUX_CMD_NONE);
- }
-
- if (chnd.conf.i2c_if->interface_shutdown) {
- other_ret = chnd.conf.i2c_if->interface_shutdown(&chnd);
- if (!ret && other_ret)
- ret = other_ret;
- }
-
- return_after_parse:
- config_release(&chnd.conf);
- return ret;
-}
diff --git a/util/iteflash.md b/util/iteflash.md
deleted file mode 100644
index fb4e35dc58..0000000000
--- a/util/iteflash.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Reflashing an ITE EC
-
-This doc: [http://go/cros-ite-ec-reflash](https://goto.google.com/cros-ite-ec-reflash)
-<br>
-First written: 2019-04-02
-<br>
-Last updated: 2019-04-03
-
-Familiarity with [Chromium OS](https://www.chromium.org/chromium-os) [Embedded Controller (EC) development](../README.md) is assumed.
-
-[TOC]
-
-## Background
-
-### Terminology
-
-**ITE EC** refers to the [ITE](http://www.ite.com.tw/) [IT8320](http://www.ite.com.tw/en/product/view?mid=96) [Embedded Controller (EC)](https://en.wikipedia.org/wiki/Embedded_controller) microcontroller when used as a Chromium OS / Chrome OS EC.
-
-**CrOS** refers to Chromium OS, Chrome OS, or both, depending on the context. The distinction between Chromium OS and Chrome OS is largely immaterial to this document.
-
-**Servo** refers to a debug board providing direct debug access to various circuits on a Chrome OS device motherboard. As of this writing, the most common [servos](https://www.chromium.org/chromium-os/servo) used by CrOS developers are [CR50 (CCD)](https://www.chromium.org/chromium-os/ccd), [Servo Micro](https://www.chromium.org/chromium-os/servo/servomicro), and [Servo v2](https://www.chromium.org/chromium-os/servo/servo-v2). (Note that [Servo v4](https://www.chromium.org/chromium-os/servo/servov4) is **not** a Servo in this sense. It is a USB hub with a microcontroller that proxies Servo functionality from either CR50 or Servo Micro.) See also [Case-Closed Debug in Chromebooks and Servo Micro](https://chromium.googlesource.com/chromiumos/platform/ec/+/master/board/servo_micro/ccd.md).
-
-### How ITE EC reflashing works
-
-An ITE EC is reflashed using a Servo by:
-
-1. Sending special non-I2C waveforms over its I2C clock and data lines, to enable a debug mode / direct firmware update (DFU) mode.
-
-1. Communicating with it using I2C, including transferring the actual EC image over I2C.  The ITE EC will only respond over I2C after receiving the special waveforms.
-
-### Further reading
-
-Googlers, and Partners involved in ITE EC projects, see [The State of ITE CrOS EC Reflashing](https://docs.google.com/document/d/1fs29eBvwKrOWYozLZXTg7ObwAO5dyM4Js2Vq301EwAU/preview). That document is not public, do not request access if you lack it.
-
-## How to reflash
-
-### Prerequisites for CR50 CCD
-
-This section applies whether using CR50 CCD via [Servo v4](https://www.chromium.org/chromium-os/servo/servov4) or [SuzyQ aka SuzyQable](https://www.sparkfun.com/products/14746).
-
-CR50 MP minimum firmware version: `0.3.15`
-<br>
-CR50 pre-PVT minimum firmware version: `0.4.15`
-
-Googlers, to upgrade CR50 firmware if needed see [How to use CCD on CR50](https://docs.google.com/document/d/1MqDAoBsmGTmrFi-WNOoC5R-UFeuQK37_9kaEdCFU8QE/preview). That document is not public, do not request access if you lack it.
-
-The CR50 CCD capabilities must be set to `always`. To achieve this:
-
-1. Open CCD.
- * root shell: `$ gsctool -o`
- * CR50 console: `ccd open`
-1. Reset CCD to `factory` mode.
- * CR50 console: `ccd reset factory`
-
-Reflashing with CR50 also requires the [i2c-pseudo kernel module](#i2c-pseudo), unless using the [CR50 CCD sans servod](#ccd-sans-servod) alternative method.
-
-### Prerequisites for Servo Micro
-
-This section applies whether the [Servo Micro](https://www.chromium.org/chromium-os/servo/servomicro) is connected directly to your development host, or through a [Servo v4](https://www.chromium.org/chromium-os/servo/servov4).
-
-Servo Micro minimum firmware version: `servo_micro_v2.3.5`
-
-To upgrade Servo Micro firmware if needed:
-
-1. Enter the chroot.
- * `$ cros_sdk`
-1. Run servo_updater.
- * `$ sudo servo_updater --board=servo_micro`
-
-If that still results in too old of a firmware version, use `repo sync` and `update_chroot` to update your CrOS development environment, then try again.
-
-Reflashing with Servo Micro also requires the [i2c-pseudo kernel module](#i2c-pseudo).
-
-### Installing i2c-pseudo {#i2c-pseudo}
-
-1. Install the `i2c-pseudo` Linux kernel module. (Do this **outside** of the chroot!)
- * `$ cd src/platform/ec/extra/i2c_pseudo`
- * `$ ./install`
-
-If the above fails, your system may be missing packages necessary for building kernel modules. Consult your Linux distribution's documentation and support forums. After installing any packages that might be missing, simply try the install script again.
-
-You will need to reinstall `i2c-pseudo` after each kernel upgrade.
-
-There is an intention to [upstream i2c-pseudo](https://issuetracker.google.com/129565355), though even if accepted upstream, it may or may not become included with common Linux distribution kernels.
-
-### Common reflash instructions
-
-These instructions apply when using any kind of Servo, including those with no special prerequisites (such as [Servo v2](https://www.chromium.org/chromium-os/servo/servo-v2) with its Yoshi flex cable connected to the DUT).
-
-1. Enter the chroot (for servod).
- * `$ cros_sdk --no-ns-pid`
-1. Start servod.
- * `$ sudo servod --board=<servod_board_name>`
- * For some boards the servod board name is different than the EC codebase board name used below!
-1. Enter the chroot (for flash_ec).
- * `$ cros_sdk`
-1. Build the EC image for your board.
- * `$ cd ~/trunk/src/platform/ec`
- * `$ board=<board_name>`
- * `$ make -j BOARD="$board"`
-1. Run flash_ec from the util directory.
- * `$ util/flash_ec --board="$board" --image=build/"$board"/ec.bin`
-
-## CR50 CCD sans servod alternative {#ccd-sans-servod}
-
-This section applies whether using CR50 CCD via [Servo v4](https://www.chromium.org/chromium-os/servo/servov4) or [SuzyQ aka SuzyQable](https://www.sparkfun.com/products/14746).
-
-When using CR50 CCD, it is possible to reflash without servod, which _must not_ be running when using this method.
-
-1. Enter the chroot.
- * `$ cros_sdk`
-1. Build the EC image for your board.
- * `$ cd ~/trunk/src/platform/ec`
- * `$ board=<board_name>`
- * `$ make -j BOARD="$board"`
-1. Run iteflash from the build/\<board\>/util directory.
- * `$ build/"$board"/util/iteflash --i2c-interface=ccd --i2c-mux --send-waveform=1 --erase --write=build/"$board"/ec.bin`
-
-WARNING: The `--i2c-mux` flag is only required for some ITE EC boards. For boards without an I2C mux between CR50 and the EC, that flag _must not_ be specified. (This is handled for you when using `flash_ec` + `servod` because the latter has knowledge of which boards are expected to have the I2C mux.)
diff --git a/util/lbcc.c b/util/lbcc.c
deleted file mode 100644
index 1a201e90d8..0000000000
--- a/util/lbcc.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "compile_time_macros.h"
-#include "ec_commands.h"
-#include "lb_common.h"
-#include "lightbar.h"
-
-static const char usage[] =
- "\n"
- "Usage: %s [OPTIONS] [INFILE [OUTFILE]]\n"
- "\n"
- "This compiles or decompiles the lightbar programmable bytecode.\n"
- "\n"
- "Options:\n"
- " -d Decode binary to ascii\n"
- " -v Decode output should be verbose\n"
- "\n";
-
-/* globals */
-static int hit_errors;
-static int opt_verbose;
-static int is_jump_target[EC_LB_PROG_LEN]; /* does program jump here? */
-static int is_instruction[EC_LB_PROG_LEN]; /* instruction or operand? */
-static char *label[EC_LB_PROG_LEN]; /* labels we've seen */
-static char *reloc_label[EC_LB_PROG_LEN]; /* put label target here */
-
-static void Error(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- fprintf(stderr, "ERROR: ");
- vfprintf(stderr, format, ap);
- va_end(ap);
- hit_errors++;
-}
-
-static void Warning(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- fprintf(stderr, "Warning: ");
- vfprintf(stderr, format, ap);
- va_end(ap);
-}
-
-/* The longest line should have a label, an opcode, and the max operands */
-#define LB_PROG_MAX_OPERANDS 4
-#define MAX_WORDS (2 + LB_PROG_MAX_OPERANDS)
-
-struct safe_lightbar_program {
- struct lightbar_program p;
- uint8_t zeros[LB_PROG_MAX_OPERANDS];
-} __packed;
-
-#define OP(NAME, BYTES, MNEMONIC) NAME,
-#include "lightbar_opcode_list.h"
-enum lightbyte_opcode {
- LIGHTBAR_OPCODE_TABLE
- MAX_OPCODE
-};
-#undef OP
-
-#define OP(NAME, BYTES, MNEMONIC) BYTES,
-#include "lightbar_opcode_list.h"
-static const int num_operands[] = {
- LIGHTBAR_OPCODE_TABLE
-};
-#undef OP
-
-#define OP(NAME, BYTES, MNEMONIC) MNEMONIC,
-#include "lightbar_opcode_list.h"
-static const char * const opcode_sym[] = {
- LIGHTBAR_OPCODE_TABLE
-};
-#undef OP
-
-static const char * const control_sym[] = {
- "beg", "end", "phase", "<invalid>"
-};
-static const char * const color_sym[] = {
- "r", "g", "b", "<invalid>"
-};
-
-static void read_binary(FILE *fp, struct safe_lightbar_program *prog)
-{
- int got;
-
- memset(prog, 0, sizeof(*prog));
-
- /* Read up to one more byte than we need, so we know if it's too big */
- got = fread(prog->p.data, 1, EC_LB_PROG_LEN + 1, fp);
- if (got < 1) {
- Error("Unable to read any input: ");
- if (feof(fp))
- fprintf(stderr, "EOF\n");
- else if (ferror(fp))
- fprintf(stderr, "%s\n", strerror(errno));
- else
- fprintf(stderr, "no idea why.\n");
- } else if (got > EC_LB_PROG_LEN) {
- Warning("Truncating input at %d bytes\n", EC_LB_PROG_LEN);
- prog->zeros[0] = 0;
- got = EC_LB_PROG_LEN;
- } else {
- prog->p.size = got;
- }
-}
-
-static uint32_t val32(uint8_t *ptr)
-{
- uint32_t val;
- val = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
- return val;
-}
-
-static int is_jump(uint8_t op)
-{
- /* TODO: probably should be a field in the opcode list */
- return op >= JUMP && op <= JUMP_IF_CHARGING;
-}
-
-static void print_led_set(FILE *fp, uint8_t led)
-{
- int i, first = 1;
-
- fprintf(fp, "{");
- for (i = 0; i < NUM_LEDS; i++)
- if (led & BIT(i)) {
- if (!first)
- fprintf(fp, ",");
- fprintf(fp, "%d", i);
- first = 0;
- }
- fprintf(fp, "}");
-}
-
-/* returns number of operands consumed */
-static int print_op(FILE *fp, uint8_t addr, uint8_t cmd, uint8_t *arg)
-{
- uint8_t led, color, control;
- int i, operands;
-
- operands = num_operands[cmd];
-
- /* assume valid instruction for now */
- is_instruction[addr] = 1;
-
- if (opt_verbose) {
- fprintf(fp, "%02x: %02x", addr, cmd);
- for (i = 0; i < LB_PROG_MAX_OPERANDS; i++)
- if (i < operands)
- fprintf(fp, " %02x", arg[i]);
- else
- fprintf(fp, " ");
- fprintf(fp, "\t");
- }
- if (is_jump_target[addr])
- fprintf(fp, "L00%02x:", addr);
- fprintf(fp, "\t");
-
- if (cmd < MAX_OPCODE)
- fprintf(fp, "%s", opcode_sym[cmd]);
-
- switch (cmd) {
- case JUMP:
- case JUMP_IF_CHARGING:
- fprintf(fp, "\tL00%02x\n", arg[0]);
- break;
- case JUMP_BATTERY:
- fprintf(fp, "\tL00%02x L00%02x\n", arg[0], arg[1]);
- break;
- case SET_WAIT_DELAY:
- case SET_RAMP_DELAY:
- fprintf(fp, "\t%d\n", val32(arg));
- break;
- case SET_BRIGHTNESS:
- fprintf(fp, "\t%d\n", arg[0]);
- break;
- case SET_COLOR_SINGLE:
- led = arg[0] >> 4;
- control = (arg[0] >> 2) & 0x03;
- color = arg[0] & 0x03;
- fprintf(fp, "\t");
-
- print_led_set(fp, led);
- fprintf(fp, ".%s", control_sym[control]);
- fprintf(fp, ".%s", color_sym[color]);
- fprintf(fp, "\t0x%02x\n", arg[1]);
- break;
- case SET_COLOR_RGB:
- led = arg[0] >> 4;
- control = (arg[0] >> 2) & 0x03;
- fprintf(fp, "\t");
-
- print_led_set(fp, led);
- fprintf(fp, ".%s", control_sym[control]);
- fprintf(fp, "\t0x%02x 0x%02x 0x%02x\n", arg[1], arg[2], arg[3]);
- break;
- case ON:
- case OFF:
- case WAIT:
- case GET_COLORS:
- case SWAP_COLORS:
- case RAMP_ONCE:
- case CYCLE_ONCE:
- case CYCLE:
- case HALT:
- fprintf(fp, "\n");
- break;
- default:
- fprintf(fp, "-- invalid opcode 0x%02x --\n", cmd);
- is_instruction[addr] = 0;
- hit_errors++;
- }
-
- return operands;
-}
-
-static void set_jump_target(uint8_t targ)
-{
- if (targ >= EC_LB_PROG_LEN) {
- Warning("program jumps to 0x%02x, "
- "which out of bounds\n", targ);
- return;
- }
- is_jump_target[targ] = 1;
-}
-
-static void disassemble_prog(FILE *fp, struct safe_lightbar_program *prog)
-{
- int i;
- uint8_t *ptr, op;
-
- /* Scan the program once to identify all the jump targets,
- * so we can print the labels when we encounter them. */
- for (i = 0; i < prog->p.size; i++) {
- ptr = &prog->p.data[i];
- op = *ptr;
- if (is_jump(op))
- set_jump_target(ptr[1]);
- if (op == JUMP_BATTERY)
- set_jump_target(ptr[2]);
- i += num_operands[op];
- }
-
- /* Now disassemble */
- for (i = 0; i < prog->p.size; i++) {
- ptr = &prog->p.data[i];
- i += print_op(fp, i, *ptr, ptr + 1);
- }
-
- /* Finally, make sure the program doesn't jump to any location other
- * than a valid instruction */
- for (i = 0; i < EC_LB_PROG_LEN; i++)
- if (is_jump_target[i] && !is_instruction[i]) {
- Warning("program jumps to 0x%02x, "
- "which is not a valid instruction\n", i);
- }
-}
-
-/* We'll split each line into an array of these. */
-struct parse_s {
- char *word;
- int is_num;
- uint32_t val;
-};
-
-/* Fills in struct, returns number of words found. Note that pointers are only
- * copied. The strings they point to are not duplicated. */
-static int split_line(char *buf, char *delim, struct parse_s *elt, int max)
-{
- char *w, *ptr, *buf_savetok;
- int i;
- char *e = 0;
-
- memset(elt, 0, max * sizeof(*elt));
-
- for (ptr = buf, i = 0;
- i < max && (w = strtok_r(ptr, delim, &buf_savetok)) != 0;
- ptr = 0, i++) {
- elt[i].word = w;
- elt[i].val = (uint32_t)strtoul(w, &e, 0);
- if (!e || !*e)
- elt[i].is_num = 1;
-
- }
-
- return i;
-}
-
-/* Decode led set. Return 0 if bogus, 1 if okay. */
-static int is_led_set(char *buf, uint8_t *valp)
-{
- uint8_t led = 0;
- unsigned long int next_led;
- char *ptr;
-
- if (!buf)
- return 0;
-
- if (*buf != '{')
- return 0;
-
- buf++;
- for (;;) {
- next_led = strtoul(buf, &ptr, 0);
- if (buf == ptr) {
- if (buf[0] == '}' && buf[1] == 0) {
- *valp = led;
- return 1;
- } else
- return 0;
- }
-
- if (next_led >= NUM_LEDS)
- return 0;
-
- led |= 1 << next_led;
-
- buf = ptr;
- if (*buf == ',')
- buf++;
- }
-}
-
-/* Decode color arg based on expected control param sections.
- * Return 0 if bogus, 1 if okay.
- */
-static int is_color_arg(char *buf, int expected, uint32_t *valp)
-{
- struct parse_s token[MAX_WORDS];
- uint8_t led, control, color;
- int i;
-
- if (!buf)
- return 0;
-
- /* There should be three terms, separated with '.' */
- i = split_line(buf, ".", token, MAX_WORDS);
- if (i != expected)
- return 0;
-
- if (!is_led_set(token[0].word, &led)) {
- Error("Invalid LED set \"%s\"\n", token[0].word);
- return 0;
- }
-
- for (i = 0; i < LB_CONT_MAX; i++)
- if (!strcmp(token[1].word, control_sym[i])) {
- control = i;
- break;
- }
- if (i >= LB_CONT_MAX)
- return 0;
-
- if (expected == 3) {
- for (i = 0; i < ARRAY_SIZE(color_sym); i++)
- if (!strcmp(token[2].word, color_sym[i])) {
- color = i;
- break;
- }
- if (i >= ARRAY_SIZE(color_sym))
- return 0;
- } else
- color = 0;
-
-
- *valp = ((led & 0xF) << 4) | ((control & 0x3) << 2) | (color & 0x3);
- return 1;
-}
-
-static void fixup_symbols(struct safe_lightbar_program *prog)
-{
- int i, j;
-
- for (i = 0; i < EC_LB_PROG_LEN; i++) {
- if (reloc_label[i]) {
- /* Looking for reloc label */
- for (j = 0; j < EC_LB_PROG_LEN; j++) {
- if (label[j] && !strcmp(label[j],
- reloc_label[i])) {
- prog->p.data[i] = j;
- break;
- }
- }
- if (j >= EC_LB_PROG_LEN)
- Error("Can't find label %s\n", reloc_label[i]);
- }
- }
-}
-
-
-static void compile(FILE *fp, struct safe_lightbar_program *prog)
-{
- char buf[128];
- struct parse_s token[MAX_WORDS];
- char *s;
- int line = 0, chopping = 0;
- uint8_t addr = 0;
- int opcode;
- int wnum, wordcnt;
- int i;
-
- while (fgets(buf, sizeof(buf), fp)) {
-
- /* We truncate lines that are too long */
- s = strchr(buf, '\n');
- if (chopping) {
- if (s)
- chopping = 0;
- continue;
- }
-
- /* Got something to look at */
- line++;
- if (!s) {
- chopping = 1;
- Warning("truncating line %d\n", line);
- }
-
- /* Ignore comments */
- s = strchr(buf, '#');
- if (s)
- *s = '\0';
-
- wordcnt = split_line(buf, " \t\n", token, MAX_WORDS);
- if (!wordcnt)
- continue;
-
- wnum = 0;
-
- /* A label must be the first word, ends with a ':' (no spaces
- * before it), and doesn't start with a ':' */
- s = strchr(token[0].word, ':');
- if (s && s[1] == '\0' && s != token[0].word) {
- *s = '\0';
- label[addr] = strdup(token[0].word);
- wnum++;
- }
-
- /* How about an opcode? */
- for (opcode = 0; opcode < MAX_OPCODE; opcode++)
- if (!strcasecmp(token[wnum].word, opcode_sym[opcode]))
- break;
-
- if (opcode >= MAX_OPCODE) {
- Error("Unrecognized opcode \"%s\""
- " at line %d\n", token[wnum].word, line);
- continue;
- }
-
- /* Do we even have a place to write this opcode? */
- if (addr >= EC_LB_PROG_LEN) {
- Error("out of program space at line %d\n", line);
- break;
- }
-
- /* Got an opcode. Save it! */
- prog->p.data[addr++] = opcode;
- wnum++;
-
- /* Now we need operands. */
- switch (opcode) {
- case JUMP:
- case JUMP_IF_CHARGING:
- /* a label */
- if (token[wnum].word)
- reloc_label[addr++] = strdup(token[wnum].word);
- else
- Error("Missing jump target at line %d\n", line);
- break;
- case JUMP_BATTERY:
- /* two labels*/
- if (token[wnum].word)
- reloc_label[addr++] = strdup(token[wnum].word);
- else {
- Error("Missing first jump target "
- "at line %d\n", line);
- break;
- }
- wnum++;
- if (token[wnum].word)
- reloc_label[addr++] = strdup(token[wnum].word);
- else
- Error("Missing second jump target "
- "at line %d\n", line);
- break;
-
- case SET_BRIGHTNESS:
- /* one 8-bit arg */
- if (token[wnum].is_num)
- prog->p.data[addr++] = token[wnum].val;
- else
- Error("Missing/invalid arg at line %d\n", line);
- break;
-
- case SET_WAIT_DELAY:
- case SET_RAMP_DELAY:
- /* one 32-bit arg */
- if (token[wnum].is_num) {
- prog->p.data[addr++] =
- (token[wnum].val >> 24) & 0xff;
- prog->p.data[addr++] =
- (token[wnum].val >> 16) & 0xff;
- prog->p.data[addr++] =
- (token[wnum].val >> 8) & 0xff;
- prog->p.data[addr++] =
- token[wnum].val & 0xff;
- } else {
- Error("Missing/invalid arg at line %d\n", line);
- }
- break;
-
- case SET_COLOR_SINGLE:
- /* one magic word, then one more 8-bit arg */
- i = is_color_arg(token[wnum].word, 3, &token[wnum].val);
- if (!i) {
- Error("Missing/invalid arg at line %d\n", line);
- break;
- }
- /* save the magic number */
- prog->p.data[addr++] = token[wnum++].val;
- /* and the color immediate */
- if (token[wnum].is_num) {
- prog->p.data[addr++] =
- token[wnum++].val;
- } else {
- Error("Missing/Invalid arg "
- "at line %d\n", line);
- break;
- }
- break;
- case SET_COLOR_RGB:
- /* one magic word, then three more 8-bit args */
- i = is_color_arg(token[wnum].word, 2, &token[wnum].val);
- if (!i) {
- Error("Missing/invalid arg at line %d\n", line);
- break;
- }
- /* save the magic number */
- prog->p.data[addr++] = token[wnum++].val;
- /* and the color immediates */
- for (i = 0; i < 3; i++) {
- if (token[wnum].is_num) {
- prog->p.data[addr++] =
- token[wnum++].val;
- } else {
- Error("Missing/Invalid arg "
- "at line %d\n", line);
- break;
- }
- }
- break;
-
- default:
- /* No args needed */
- break;
- }
-
- /* Did we run past the end? */
- if (addr > EC_LB_PROG_LEN) {
- Error("out of program space at line %d\n", line);
- break;
- }
- }
- if (ferror(fp))
- Error("problem while reading input: %s\n", strerror(errno));
-
- if (!hit_errors)
- fixup_symbols(prog);
-
- if (!hit_errors)
- prog->p.size = addr;
-
- if (!prog->p.size)
- Error("input file produced no output bytes\n");
-}
-
-int main(int argc, char *argv[])
-{
- struct safe_lightbar_program safe_prog;
- int opt_decode = 0;
- int c;
- int errorcnt = 0;
- char *infile, *outfile;
- FILE *ifp, *ofp;
-
- char *progname = strrchr(argv[0], '/');
- if (progname)
- progname++;
- else
- progname = argv[0];
-
- opterr = 0; /* quiet, you */
- while ((c = getopt(argc, argv, ":dv")) != -1) {
- switch (c) {
- case 'd':
- opt_decode = 1;
- break;
- case 'v':
- opt_verbose = 1;
- break;
-
- case '?':
- fprintf(stderr, "%s: unrecognized switch: -%c\n",
- progname, optopt);
- errorcnt++;
- break;
- case ':':
- fprintf(stderr, "%s: missing argument to -%c\n",
- progname, optopt);
- errorcnt++;
- break;
- default:
- errorcnt++;
- break;
- }
- }
-
- if (errorcnt) {
- fprintf(stderr, usage, progname);
- exit(1);
- }
-
- if (argc - optind > 0) {
- infile = argv[optind];
- ifp = fopen(infile, "rb");
- if (!ifp) {
- fprintf(stderr,
- "%s: Unable to open %s for reading: %s\n",
- progname, infile, strerror(errno));
- exit(1);
- }
- } else {
- infile = "stdin";
- ifp = stdin;
- }
-
- if (argc - optind > 1) {
- outfile = argv[optind + 1];
- ofp = fopen(outfile, "wb");
- if (!ofp) {
- fprintf(stderr,
- "%s: Unable to open %s for writing: %s\n",
- progname, outfile, strerror(errno));
- exit(1);
- }
- } else {
- outfile = "stdout";
- ofp = stdout;
- }
-
- if (opt_decode) {
- read_binary(ifp, &safe_prog);
- fclose(ifp);
- if (hit_errors)
- return 1;
- fprintf(ofp, "# %s\n", infile);
- disassemble_prog(ofp, &safe_prog);
- fclose(ofp);
- } else {
- memset(&safe_prog, 0, sizeof(safe_prog));
- compile(ifp, &safe_prog);
- fclose(ifp);
- if (!hit_errors) {
- if (1 != fwrite(safe_prog.p.data,
- safe_prog.p.size, 1, ofp))
- Error("%s: Unable to write to %s: %s\n",
- progname, outfile, strerror(errno));
- else
- fprintf(stderr, "0x%02x bytes written to %s\n",
- safe_prog.p.size, outfile);
- }
- fclose(ofp);
- }
-
- return hit_errors;
-}
diff --git a/util/lbplay.c b/util/lbplay.c
deleted file mode 100644
index 9ab0564b74..0000000000
--- a/util/lbplay.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Copyright 2014 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.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#define LIGHTBAR "/sys/devices/virtual/chromeos/cros_ec/lightbar"
-
-int main(int argc, char **argv)
-{
- int major, minor, fd_v;
- int i, tries, fd_s, fd_l;
- char buf[80];
- int ret = 1;
-
- /* Check version */
- fd_v = open(LIGHTBAR "/version", O_RDONLY);
- if (fd_v < 0) {
- perror("can't open version file");
- goto out;
- }
- ret = read(fd_v, buf, sizeof(buf) - 1);
- if (ret <= 0) {
- perror("can't read version");
- close(fd_v);
- goto out;
- }
- buf[ret] = '\0';
- close(fd_v);
-
- errno = 0;
- /* Expect "MAJOR MINOR" */
- if (2 != sscanf(buf, "%d %d", &major, &minor)) {
- if (errno)
- perror("can't parse version string");
- else
- fprintf(stderr, "can't parse version string\n");
- goto out;
- }
- /* Pixel is "0 0". Minor change will be compatible, Major may not */
- if (major != 0) {
- fprintf(stderr, "Don't know how to handle version %d.%d\n",
- major, minor);
- goto out;
- }
-
- /* Take over lightbar sequencing. */
- fd_s = open(LIGHTBAR "/sequence", O_RDWR | O_SYNC);
- if (fd_s < 0) {
- perror("can't open sequence control");
- goto out;
- }
-
- /* NOTE: Cooperative locking only. Rude programs may not play nice. */
- if (flock(fd_s, LOCK_EX | LOCK_NB) < 0) {
- perror("can't lock sequence control");
- goto out_close;
- }
-
- /*
- * If power events are changing the sequence our request to stop may
- * be missed, so try a few times before giving up.
- *
- * Note that every write to a control file should be prefaced with an
- * lseek() to the beginning. sysfs files don't work quite like normal
- * files.
- */
- tries = 3;
- while (1) {
- lseek(fd_s, 0, SEEK_SET);
- if (read(fd_s, buf, sizeof(buf)) <= 0) {
- perror("can't read sequence control");
- goto out_unlock;
- }
-
- if (!strncasecmp(buf, "stop", 4))
- break;
-
- if (!tries--) {
- fprintf(stderr, "couldn't get EC to stop\n");
- goto out_unlock;
- }
-
- lseek(fd_s, 0, SEEK_SET);
- strcpy(buf, "stop");
- if (write(fd_s, buf, strlen(buf) + 1) <= 0) {
- perror("can't write sequence control");
- goto out_unlock;
- }
- }
-
- /* Turn the brightness all the way up */
- fd_l = open(LIGHTBAR "/brightness", O_WRONLY | O_SYNC);
- if (fd_l < 0) {
- perror("can't open brightness control");
- goto out_run;
- }
- strcpy(buf, "255");
- if (write(fd_l, buf, strlen(buf) + 1) < 0) {
- perror("can't write brightness control");
- goto out_led;
- }
- close(fd_l);
-
- /* Now let's drive the colors. */
- fd_l = open(LIGHTBAR "/led_rgb", O_WRONLY | O_SYNC);
- if (fd_l < 0) {
- perror("can't open led control");
- goto out_run;
- }
-
- /* Cycle through some colors. We can update multiple LEDs at once,
- * but there's a limit on how often we can send commands to the
- * lightbar. Going too fast will block, although buffering combined
- * with lseek() may just cause data to be lost. Read "/interval_msec"
- * to see what the limit is. The default is 50msec (20Hz).
- */
- for (i = 0; i < 256; i += 4) {
- sprintf(buf, "0 %d %d %d 1 %d %d %d 2 %d %d %d 3 %d %d %d",
- i, 0, 0,
- 0, 0, i,
- 255-i, 255, 0,
- 0, 255, 255-i);
- lseek(fd_l, 0, SEEK_SET);
- if (write(fd_l, buf, strlen(buf) + 1) < 0)
- perror("write to led control");
-
- usleep(100000);
- }
-
- /* all white */
- strcpy(buf, "4 255 255 255");
- lseek(fd_l, 0, SEEK_SET);
- if (write(fd_l, buf, strlen(buf) + 1) < 0)
- perror("write to led control");
-
- usleep(400000);
-
- /* Done. */
- ret = 0;
-out_led:
- close(fd_l);
-out_run:
- /* Let EC drive lightbar again */
- strcpy(buf, "run");
- lseek(fd_s, 0, SEEK_SET);
- if (write(fd_s, buf, strlen(buf) + 1) < 0)
- perror("write to sequence control");
-out_unlock:
- flock(fd_s, LOCK_UN);
-out_close:
- close(fd_s);
-out:
- return ret;
-}
diff --git a/util/linux_ec_commands_h_check.sh b/util/linux_ec_commands_h_check.sh
deleted file mode 100755
index 4c55faca0a..0000000000
--- a/util/linux_ec_commands_h_check.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019 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.
-
-set -e
-
-ec_commands_file_in="include/ec_commands.h"
-ec_commands_file_out="build/kernel/include/linux/mfd/cros_ec_commands.h"
-
-# Check if ec_commands.h has changed.
-echo ${PRESUBMIT_FILES} | grep -q "${ec_commands_file_in}" || exit 0
-
-if [ ! -f "${ec_commands_file_out}" ]; then
- echo "A new cros_ec_commands.h must be generated."
- echo 'Please run "make buildall" or "make build_cros_ec_commands"'.
- exit 1
-fi
-
-if [ "${ec_commands_file_out}" -ot "${ec_commands_file_in}" ]; then
- echo "cros_ec_commands.h is out of date."
- echo 'Please run "make buildall" or "make build_cros_ec_commands"'.
- exit 1
-fi
diff --git a/util/lock/android.c b/util/lock/android.c
deleted file mode 100644
index 8472b6db68..0000000000
--- a/util/lock/android.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- */
-
-#include <stdlib.h>
-
-#include "android.h"
-
-int in_android(void)
-{
- if (getenv("ANDROID_ROOT"))
- return 1;
-
- return 0;
-}
-
-char *android_tmpdir_path(void)
-{
- return getenv("TMPDIR");
-}
diff --git a/util/lock/android.h b/util/lock/android.h
deleted file mode 100644
index bb08486919..0000000000
--- a/util/lock/android.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- */
-
-#ifndef ANDROID_H__
-#define ANDROID_H__
-
-/*
- * in_android - Test to see if the underlying OS is Android
- *
- * returns boolean 1 to indicate true, 0 otherwise
- */
-extern int in_android(void);
-
-/**
- * Determine where temporary files go.
- *
- * @return A pointer to value of directory containing temporary files if
- * successful, or NULL otherwise
- */
-extern char *android_tmpdir_path(void);
-
-#endif
diff --git a/util/lock/build.mk b/util/lock/build.mk
deleted file mode 100644
index 65a63ab9db..0000000000
--- a/util/lock/build.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- makefile -*-
-# Copyright 2012 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.
-#
-# Lock library
-#
-
-util-lock-objs=file_lock.o gec_lock.o
-util-lock-objs+=android.o
diff --git a/util/lock/file_lock.c b/util/lock/file_lock.c
deleted file mode 100644
index 36b420d287..0000000000
--- a/util/lock/file_lock.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* Copyright 2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * file_lock.c: Implementation for a binary semaphore using a file lock.
- *
- * Warning: This relies on flock() which is known to be broken on NFS.
- *
- * The file will remain persistent once the lock has been used. Unfortunately,
- * unlinking the file can introduce a race condition so we leave the file
- * in place.
- *
- * The current process's PID will be written to the file for debug purposes.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/file.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "android.h"
-#include "ipc_lock.h"
-#include "locks.h"
-
-#define SLEEP_INTERVAL_MS 50
-
-static void msecs_to_timespec(int msecs, struct timespec *tmspec)
-{
- tmspec->tv_sec = msecs / 1000;
- tmspec->tv_nsec = (msecs % 1000) * 1000 * 1000;
-}
-
-static int lock_is_held(struct ipc_lock *lock)
-{
- return lock->is_held;
-}
-
-static int test_dir(const char *path)
-{
- struct stat s;
-
- if (lstat(path, &s) < 0) {
- fprintf(stderr, "Cannot stat %s.\n", path);
- return -1;
- }
-
- if (!S_ISDIR(s.st_mode)) {
- fprintf(stderr, "%s is not a directory.\n", path);
- return -1;
- }
-
- return 0;
-}
-
-static int file_lock_open_or_create(struct ipc_lock *lock)
-{
- char path[PATH_MAX];
-
- if (in_android()) {
- char *tmpdir;
-
- tmpdir = android_tmpdir_path();
- if (!tmpdir)
- return -1;
-
- if (snprintf(path, sizeof(path), "%s/%s",
- tmpdir, lock->filename) < 0) {
- return -1;
- }
- } else {
- const char *dir = SYSTEM_LOCKFILE_DIR;
- const char fallback[] = "/tmp";
-
- if (test_dir(dir)) {
- dir = fallback;
- fprintf(stderr, "Trying fallback directory: %s\n", dir);
- if (test_dir(dir))
- return -1;
- }
-
- if (snprintf(path, sizeof(path),
- "%s/%s", dir, lock->filename) < 0)
- return -1;
-
- }
-
- lock->fd = open(path, O_RDWR | O_CREAT, 0600);
- if (lock->fd < 0) {
- fprintf(stderr, "Cannot open lockfile %s", path);
- return -1;
- }
-
- return 0;
-}
-
-static int file_lock_get(struct ipc_lock *lock, int timeout_msecs)
-{
- int msecs_remaining = timeout_msecs;
- struct timespec sleep_interval, rem;
- int ret = -1;
-
- if (timeout_msecs == 0)
- return flock(lock->fd, LOCK_EX | LOCK_NB);
-
- msecs_to_timespec(SLEEP_INTERVAL_MS, &sleep_interval);
-
- while ((ret = flock(lock->fd, LOCK_EX | LOCK_NB)) != 0) {
- if (errno != EWOULDBLOCK) {
- fprintf(stderr, "Error obtaining lock");
- return -1;
- }
-
- if (msecs_remaining < SLEEP_INTERVAL_MS)
- msecs_to_timespec(msecs_remaining, &sleep_interval);
-
- while (nanosleep(&sleep_interval, &rem) != 0) {
- if (errno == EINTR) {
- sleep_interval = rem;
- continue;
- } else {
- fprintf(stderr, "nanosleep() failed");
- return ret;
- }
- }
-
- if (timeout_msecs < 0)
- continue;
-
- msecs_remaining -= SLEEP_INTERVAL_MS;
- if (msecs_remaining < 0)
- break;
- }
-
- if (ret != 0) {
- fprintf(stderr, "Timed out waiting for file lock.\n");
- return -1;
- }
-
- return 0;
-}
-
-static int file_lock_write_pid(struct ipc_lock *lock)
-{
- ssize_t len;
- /*
- * PIDs are usually 5 digits, but we'll reserve enough room for
- * a value of 2^32 (10 digits) out of paranoia.
- */
- char pid_str[11];
-
- if (ftruncate(lock->fd, 0) < 0) {
- fprintf(stderr, "Cannot truncate lockfile");
- return -1;
- }
-
- snprintf(pid_str, sizeof(pid_str), "%lu", (unsigned long)getpid());
- len = write(lock->fd, pid_str, strlen(pid_str));
- if (len < 0) {
- fprintf(stderr, "Cannot write PID to lockfile");
- return -1;
- }
-
- return 0;
-}
-
-static void file_lock_release(struct ipc_lock *lock)
-{
- if (flock(lock->fd, LOCK_UN) < 0)
- fprintf(stderr, "Cannot release lock");
-
- if (close(lock->fd) < 0)
- fprintf(stderr, "Cannot close lockfile");
-}
-
-/*
- * timeout <0 = no timeout (try forever)
- * timeout 0 = do not wait (return immediately)
- * timeout >0 = wait up to $timeout milliseconds
- *
- * returns 0 to indicate lock acquired
- * returns >0 to indicate lock was already held
- * returns <0 to indicate failed to acquire lock
- */
-int acquire_lock(struct ipc_lock *lock, int timeout_msecs)
-{
- /* check if it is already held */
- if (lock_is_held(lock))
- return 1;
-
- if (file_lock_open_or_create(lock))
- return -1;
-
- if (file_lock_get(lock, timeout_msecs)) {
- lock->is_held = 0;
- close(lock->fd);
- return -1;
- } else {
- lock->is_held = 1;
- }
-
- /*
- * Write PID to lockfile for debug purposes. Failure to write to
- * the file should not be considered fatal. There might be something
- * bad happening with the filesystem, but the lock has already been
- * obtained and we may need our tools for diagnostics and repairs
- * so we should continue anyway.
- */
- file_lock_write_pid(lock);
- return 0;
-}
-
-/*
- * returns 0 if lock was released successfully
- * returns -1 if lock had not been held before the call
- */
-int release_lock(struct ipc_lock *lock)
-{
- if (lock_is_held(lock)) {
- file_lock_release(lock);
- lock->is_held = 0;
- return 0;
- }
-
- return -1;
-}
diff --git a/util/lock/gec_lock.c b/util/lock/gec_lock.c
deleted file mode 100644
index d354ea08f3..0000000000
--- a/util/lock/gec_lock.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright 2012, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "gec_lock.h"
-#include "ipc_lock.h"
-#include "locks.h"
-
-static struct ipc_lock gec_lock = LOCKFILE_INIT(CROS_EC_LOCKFILE_NAME);
-
-int acquire_gec_lock(int timeout_secs)
-{
- return acquire_lock(&gec_lock, timeout_secs * 1000);
-}
-
-int release_gec_lock(void)
-{
- return release_lock(&gec_lock);
-}
diff --git a/util/lock/gec_lock.h b/util/lock/gec_lock.h
deleted file mode 100644
index 8480700ddd..0000000000
--- a/util/lock/gec_lock.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright 2012, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __UTIL_GEC_LOCK_H
-#define __UTIL_GEC_LOCK_H
-
-/*
- * acquire_gec_lock - acquire global lock
- *
- * returns 0 to indicate lock acquired
- * returns >0 to indicate lock was already held
- * returns <0 to indicate failed to acquire lock
- */
-extern int acquire_gec_lock(int timeout_secs);
-
-/*
- * release_gec_lock - release global lock
- *
- * returns 0 if lock was released successfully
- * returns -1 if lock had not been held before the call
- */
-extern int release_gec_lock(void);
-
-#endif /* __UTIL_GEC_LOCK_H */
diff --git a/util/lock/ipc_lock.h b/util/lock/ipc_lock.h
deleted file mode 100644
index ca739ac04e..0000000000
--- a/util/lock/ipc_lock.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright 2012, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __UTIL_IPC_LOCK_H
-#define __UTIL_IPC_LOCK_H
-
-struct ipc_lock {
- int is_held; /* internal */
- char *filename; /* provided by the developer */
- int fd; /* internal */
-};
-
-/* don't use C99 initializers here, so this can be used in C++ code */
-#define LOCKFILE_INIT(lockfile) \
- { \
- 0, /* is_held */ \
- lockfile, /* filename */ \
- -1, /* fd */ \
- }
-
-/*
- * acquire_lock: acquire a lock
- *
- * timeout <0 = no timeout (try forever)
- * timeout 0 = do not wait (return immediately)
- * timeout >0 = wait up to $timeout milliseconds (subject to kernel scheduling)
- *
- * return 0 = lock acquired
- * return >0 = lock was already held
- * return <0 = failed to acquire lock
- */
-extern int acquire_lock(struct ipc_lock *lock, int timeout_msecs);
-
-/*
- * release_lock: release a lock
- *
- * returns 0 if lock was released successfully
- * returns -1 if lock had not been held before the call
- */
-extern int release_lock(struct ipc_lock *lock);
-
-#endif /* __UTIL_IPC_LOCK_H */
diff --git a/util/lock/locks.h b/util/lock/locks.h
deleted file mode 100644
index 6875d91454..0000000000
--- a/util/lock/locks.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2012, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __UTIL_LOCKS_H
-#define __UTIL_LOCKS_H
-
-#define SYSTEM_LOCKFILE_DIR "/run/lock"
-#define LOCKFILE_NAME "firmware_utility_lock"
-#define CROS_EC_LOCKFILE_NAME "cros_ec_lock"
-
-#endif /* __UTIL_LOCKS_H */
diff --git a/util/make_linux_ec_commands_h.sh b/util/make_linux_ec_commands_h.sh
deleted file mode 100755
index b860e61f65..0000000000
--- a/util/make_linux_ec_commands_h.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019 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.
-
-# Generate a kernel include file from ec_commands.h.
-
-usage() {
- cat << EOF
-Generate an ec_commands.h file suitable for upstreaming to kernel.org.
-Syntax:
-$0 source_ec_commands.h target_cros_ec_commands.h
-
-source_ec_commands.h: source file, usually include/ec_commands.h
-target_cros_ec_commands.h: target file that will be upstreamed.
-EOF
-}
-
-set -e
-
-in="$1"
-out="$2"
-
-if [ $# -ne 2 ]; then
- usage
- exit 1
-fi
-
-if [ ! -d "${CROS_WORKON_SRCROOT}" ]; then
- printf "Not in Chrome OS chroot!\n\n"
- usage
- exit 0
-fi
-
-out_dir="$(dirname "${out}")"
-mkdir -p "${out_dir}"
-tmp="$(mktemp -p "${out_dir}" cros_ec_XXX.h)"
-cp "${in}" "${tmp}"
-
-cleanup() {
- rm -f "${tmp}"*
-}
-
-trap cleanup EXIT
-
-# Replace license
-patch "${tmp}" << EOF
-@@ -1,6 +1,11 @@
--/* Copyright 2014 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.
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Host communication command constants for ChromeOS EC
-+ *
-+ * Copyright (C) 2012 Google, Inc
-+ *
-+ * NOTE: This file is auto-generated from ChromeOS EC Open Source code from
-+ * https://chromium.googlesource.com/chromiumos/platform/ec/+/master/include/ec_commands.h
- */
-
- /* Host communication command constants for Chrome EC */
-EOF
-
-# Change header guards
-sed -i "s/__CROS_EC_EC_COMMANDS_H/__CROS_EC_COMMANDS_H/" "${tmp}"
-
-# Remove non kernel code to prevent checkpatch warnings and simplify the .h.
-unifdef -x2 -m -UCONFIG_HOSTCMD_ALIGNED -U__ACPI__ -D__KERNEL__ -U__cplusplus \
- -UCHROMIUM_EC "${tmp}"
-
-# Check kernel checkpatch passes.
-"${CROS_WORKON_SRCROOT}/src/repohooks/checkpatch.pl" -f "${tmp}"
-
-cp "${tmp}" "${out}"
diff --git a/util/misc_util.c b/util/misc_util.c
deleted file mode 100644
index 9813dc72b4..0000000000
--- a/util/misc_util.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* Copyright 2013 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.
- */
-
-#include <ctype.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/utsname.h>
-
-#include "comm-host.h"
-#include "misc_util.h"
-
-int write_file(const char *filename, const char *buf, int size)
-{
- FILE *f;
- int i;
-
- /* Write to file */
- f = fopen(filename, "wb");
- if (!f) {
- perror("Error opening output file");
- return -1;
- }
- i = fwrite(buf, 1, size, f);
- fclose(f);
- if (i != size) {
- perror("Error writing to file");
- return -1;
- }
-
- return 0;
-}
-
-char *read_file(const char *filename, int *size)
-{
- FILE *f = fopen(filename, "rb");
- char *buf;
- int i;
-
- if (!f) {
- perror("Error opening input file");
- return NULL;
- }
-
- fseek(f, 0, SEEK_END);
- *size = ftell(f);
- rewind(f);
- if ((*size > 0x100000) || (*size < 0)) {
- if (*size < 0)
- perror("ftell failed");
- else
- fprintf(stderr, "File seems unreasonably large\n");
- fclose(f);
- return NULL;
- }
-
- buf = (char *)malloc(*size);
- if (!buf) {
- fprintf(stderr, "Unable to allocate buffer.\n");
- fclose(f);
- return NULL;
- }
-
- printf("Reading %d bytes from %s...\n", *size, filename);
- i = fread(buf, 1, *size, f);
- fclose(f);
- if (i != *size) {
- perror("Error reading file");
- free(buf);
- return NULL;
- }
-
- return buf;
-}
-
-int is_string_printable(const char *buf)
-{
- while (*buf) {
- if (!isprint(*buf))
- return 0;
- buf++;
- }
-
- return 1;
-}
-
-/**
- * Get the versions of the command supported by the EC.
- *
- * @param cmd Command
- * @param pmask Destination for version mask; will be set to 0 on
- * error.
- * @return 0 if success, <0 if error
- */
-int ec_get_cmd_versions(int cmd, uint32_t *pmask)
-{
- struct ec_params_get_cmd_versions_v1 pver_v1;
- struct ec_params_get_cmd_versions pver;
- struct ec_response_get_cmd_versions rver;
- int rv;
-
- *pmask = 0;
-
- pver_v1.cmd = cmd;
- rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 1, &pver_v1, sizeof(pver_v1),
- &rver, sizeof(rver));
-
- if (rv < 0) {
- pver.cmd = cmd;
- rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &pver, sizeof(pver),
- &rver, sizeof(rver));
- }
-
- if (rv < 0)
- return rv;
-
- *pmask = rver.version_mask;
- return 0;
-}
-
-/**
- * Return non-zero if the EC supports the command and version
- *
- * @param cmd Command to check
- * @param ver Version to check
- * @return non-zero if command version supported; 0 if not.
- */
-int ec_cmd_version_supported(int cmd, int ver)
-{
- uint32_t mask = 0;
-
- if (ec_get_cmd_versions(cmd, &mask))
- return 0;
-
- return (mask & EC_VER_MASK(ver)) ? 1 : 0;
-}
-
-/**
- * Return 1 is the current kernel version is greater or equal to
- * <major>.<minor>.<sublevel>
- */
-int kernel_version_ge(int major, int minor, int sublevel)
-{
- struct utsname uts;
- int atoms, kmajor, kminor, ksublevel;
-
- if (uname(&uts) < 0)
- return -1;
- atoms = sscanf(uts.release, "%d.%d.%d", &kmajor, &kminor, &ksublevel);
- if (atoms < 1)
- return -1;
-
- if (kmajor > major)
- return 1;
- if (kmajor < major)
- return 0;
-
- /* kmajor == major */
- if (atoms < 2)
- return 0 == minor && 0 == sublevel;
- if (kminor > minor)
- return 1;
- if (kminor < minor)
- return 0;
-
- /* kminor == minor */
- if (atoms < 3)
- return 0 == sublevel;
-
- return ksublevel >= sublevel;
-}
-
diff --git a/util/openocd/lm4_chip.cfg b/util/openocd/lm4_chip.cfg
deleted file mode 100644
index 3dffa2dc66..0000000000
--- a/util/openocd/lm4_chip.cfg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-ftdi_layout_init 0x0018 0x009b
-
-# open collector oe only
-ftdi_layout_signal nSRST -oe 0x0020
-
-reset_config trst_only
-
-source [find target/stellaris.cfg]
-source [find lm4x_cmds.tcl]
-
diff --git a/util/openocd/lm4x_cmds.tcl b/util/openocd/lm4x_cmds.tcl
deleted file mode 100644
index 6cad874939..0000000000
--- a/util/openocd/lm4x_cmds.tcl
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2012 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.
-#
-# Command automation for Blizzard LM4F chip
-
-# Program internal flash
-
-proc flash_lm4 {path offset} {
- reset halt;
- flash write_image erase $path $offset;
- reset
-}
-
-proc flash_lm4_board {board} {
- flash_lm4 ../../../build/$board/ec.bin 0
-}
-
-proc flash_lm4_ro {board} {
- flash_lm4 ../../../build/$board/ec.RO.flat 0
-}
-
-proc flash_lm4_rw {board} {
- flash_lm4 ../../../build/$board/ec.RW.bin 131072
-}
-
-# Boards with CONFIG_FLASH_PSTATE_BANK have pstate following RO
-proc unprotect_pstate { } {
- reset halt
- flash erase_sector 0 126 127
- reset
-}
-
-# Boot a software using internal RAM only
-
-proc ramboot_lm4 {path} {
- reset halt
- load_image $path 0x20000000 bin
- reg 15 0x20000400
- resume
-}
-
-proc ramboot_lm4_board {board} {
- ramboot_lm4 ../../../build/$board/ec.RO.flat
-}
-
-proc flash_emerged_board {board} {
- set firmware_image ../../../../../../chroot/build/$board/firmware/ec.bin
-
- flash_lm4 $firmware_image 0
-}
diff --git a/util/openocd/npcx.cfg b/util/openocd/npcx.cfg
deleted file mode 100644
index 0ab2b42888..0000000000
--- a/util/openocd/npcx.cfg
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 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.
-#
-# nuvoton-m4 devices support both JTAG and SWD transports.
-#
-
-source [find target/swj-dp.tcl]
-
-if { [info exists CHIPNAME] } {
- set _CHIPNAME $CHIPNAME
-} else {
- set _CHIPNAME npcx_ec
-}
-
-if { [info exists ENDIAN] } {
- set _ENDIAN $ENDIAN
-} else {
- set _ENDIAN little
-}
-
-# Work-area is a space in RAM used for flash programming
-# By default use 16kB
-if { [info exists WORKAREASIZE] } {
- set _WORKAREASIZE $WORKAREASIZE
-} else {
- set _WORKAREASIZE 0x8000
-}
-
-#jtag scan chain
-if { [info exists CPUTAPID ] } {
- set _CPUTAPID $CPUTAPID
-} else {
- set _CPUTAPID 0x4BA00477
-}
-
-#jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
-swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position \
- $_CHIPNAME.cpu -work-area-phys 0x200C0000 \
- -work-area-size $_WORKAREASIZE
-
-# JTAG speed
-adapter_khz 100
-
-adapter_nsrst_delay 100
-jtag_ntrst_delay 100
-
-# use sysresetreq to perform a system reset
-cortex_m reset_config sysresetreq
-
-#reset configuration
-reset_config trst_and_srst
-
-$_TARGETNAME configure -event reset-start {
- echo "NPCX Reset..."
- halt
- adapter_khz 1000
-}
diff --git a/util/openocd/npcx_chip.cfg b/util/openocd/npcx_chip.cfg
deleted file mode 100644
index ddd01df5a4..0000000000
--- a/util/openocd/npcx_chip.cfg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-source [find npcx.cfg]
-source [find npcx_cmds.tcl]
-
-ftdi_layout_init 0x0018 0x009b
-
-# open collector oe only
-ftdi_layout_signal nSRST -oe 0x0020
-
-reset_config trst_only
-
diff --git a/util/openocd/npcx_cmds.tcl b/util/openocd/npcx_cmds.tcl
deleted file mode 100644
index 759e897131..0000000000
--- a/util/openocd/npcx_cmds.tcl
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright 2014 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.
-#
-# Command automation for NPCX5M5G chip
-
-# Program spi flash
-source [find mem_helper.tcl]
-
-proc flash_npcx {image_path cram_addr image_offset image_size spifw_image} {
- set UPLOAD_FLAG 0x200C4000;
- set UUT_TAG 0x200C3000;
-
- echo "*** NPCX Reset and halt CPU first ***"
- reset halt
-
- # Clear whole Code RAM
- mwb $cram_addr 0xFF $image_size
- # Upload binary image to Code RAM
- load_image $image_path $cram_addr
-
- # Upload program spi image FW to lower 16KB Data RAM
- load_image $spifw_image 0x200C3020
-
- # Set sp to upper 16KB Data RAM
- reg sp 0x200C8000
- # Set spi offset address of uploaded image
- reg r0 $image_offset
- # Set spi program size of uploaded image
- reg r1 $image_size
- # Set pc to start of spi program function
- reg pc 0x200C3021
- # Clear upload flag
- mww $UPLOAD_FLAG 0x0
-
- # Clear UUT Tag
- mww $UUT_TAG 0x0
-
- echo "*** Program ... ***"
- # Start to program spi flash
- resume
-
- # Wait for any pending flash operations to complete
- while {[expr [mrw $UPLOAD_FLAG] & 0x01] == 0} { sleep 1000 }
-
- if {[expr [mrw $UPLOAD_FLAG] & 0x02] == 0} {
- echo "*** Program Fail ***"
- } else {
- echo "*** Program Done ***"
- }
-
- # Halt CPU
- halt
-}
-
-proc flash_npcx5m5g {image_path image_offset spifw_image} {
- # 96 KB for RO & RW regions
- set fw_size 0x18000
- # Code RAM start address
- set cram_addr 0x100A8000
-
- echo "*** Start to program npcx5m5g with $image_path ***"
- flash_npcx $image_path $cram_addr $image_offset $fw_size $spifw_image
- echo "*** Finish program npcx5m5g ***\r\n"
-}
-
-proc flash_npcx5m6g {image_path image_offset spifw_image} {
- # 224 KB for RO & RW regions
- set fw_size 0x38000
- # Code RAM start address
- set cram_addr 0x10088000
-
- echo "*** Start to program npcx5m6g with $image_path ***"
- flash_npcx $image_path $cram_addr $image_offset $fw_size $spifw_image
- echo "*** Finish program npcx5m6g ***\r\n"
-}
-
-proc flash_npcx7m6x {image_path image_offset spifw_image} {
- # 192 KB for RO & RW regions
- set fw_size 0x30000
- # Code RAM start address
- set cram_addr 0x10090000
-
- echo "*** Start to program npcx7m6f/g/w with $image_path ***"
- flash_npcx $image_path $cram_addr $image_offset $fw_size $spifw_image
- echo "*** Finish program npcx7m6f/g/w ***\r\n"
-}
-
-proc flash_npcx7m7x {image_path image_offset spifw_image} {
- # 320 KB for RO & RW regions
- set fw_size 0x50000
- # Code RAM start address
- set cram_addr 0x10070000
-
- echo "*** Start to program npcx7m7f/g/w with $image_path ***"
- flash_npcx $image_path $cram_addr $image_offset $fw_size $spifw_image
- echo "*** Finish program npcx7m7f/g/w ***\r\n"
-}
-
-proc flash_npcx_ro {chip_name image_dir image_offset} {
- set MPU_RNR 0xE000ED98;
- set MPU_RASR 0xE000EDA0;
-
- # images path
- set ro_image_path $image_dir/RO/ec.RO.flat
- set spifw_image $image_dir/chip/npcx/spiflashfw/npcx_monitor.bin
-
- # Halt CPU first
- halt
-
- # disable MPU for Data RAM
- mww $MPU_RNR 0x1
- mww $MPU_RASR 0x0
-
- if {$chip_name == "npcx_5m5g_jtag"} {
- # program RO region
- flash_npcx5m5g $ro_image_path $image_offset $spifw_image
- } elseif {$chip_name == "npcx_5m6g_jtag"} {
- # program RO region
- flash_npcx5m6g $ro_image_path $image_offset $spifw_image
- } elseif {$chip_name == "npcx_7m6x_jtag"} {
- # program RO region
- flash_npcx7m6x $ro_image_path $image_offset $spifw_image
- } elseif {$chip_name == "npcx_7m7x_jtag"} {
- # program RO region
- flash_npcx7m7x $ro_image_path $image_offset $spifw_image
- } else {
- echo $chip_name "no supported."
- }
-}
-
-proc flash_npcx_all {chip_name image_dir image_offset} {
- set MPU_RNR 0xE000ED98;
- set MPU_RASR 0xE000EDA0;
-
- # images path
- set ro_image_path $image_dir/RO/ec.RO.flat
- set rw_image_path $image_dir/RW/ec.RW.bin
- set spifw_image $image_dir/chip/npcx/spiflashfw/npcx_monitor.bin
-
- # Halt CPU first
- halt
-
- # disable MPU for Data RAM
- mww $MPU_RNR 0x1
- mww $MPU_RASR 0x0
-
- if {$chip_name == "npcx_5m5g_jtag"} {
- # RW images offset - 128 KB
- set rw_image_offset [expr ($image_offset + 0x20000)]
- # program RO region
- flash_npcx5m5g $ro_image_path $image_offset $spifw_image
- # program RW region
- flash_npcx5m5g $rw_image_path $rw_image_offset $spifw_image
- } elseif {$chip_name == "npcx_5m6g_jtag"} {
- # RW images offset - 256 KB
- set rw_image_offset [expr ($image_offset + 0x40000)]
- # program RO region
- flash_npcx5m6g $ro_image_path $image_offset $spifw_image
- # program RW region
- flash_npcx5m6g $rw_image_path $rw_image_offset $spifw_image
- } elseif {$chip_name == "npcx_7m6x_jtag"} {
- # RW images offset - 256 KB
- set rw_image_offset [expr ($image_offset + 0x40000)]
- # program RO region
- flash_npcx7m6x $ro_image_path $image_offset $spifw_image
- # program RW region
- flash_npcx7m6x $rw_image_path $rw_image_offset $spifw_image
- } elseif {$chip_name == "npcx_7m7x_jtag"} {
- # RW images offset - 512 KB
- set rw_image_offset [expr ($image_offset + 0x80000)]
- # program RO region
- flash_npcx7m7x $ro_image_path $image_offset $spifw_image
- # program RW region
- flash_npcx7m7x $rw_image_path $rw_image_offset $spifw_image
- } else {
- echo $chip_name "no supported."
- }
-}
-
-proc reset_halt_cpu { } {
- echo "*** NPCX Reset and halt CPU first ***"
- reset halt
-}
diff --git a/util/openocd/nrf51_chip.cfg b/util/openocd/nrf51_chip.cfg
deleted file mode 100644
index f0e78897d6..0000000000
--- a/util/openocd/nrf51_chip.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#nRF51 uses SWD
-transport select swd
-# Since nTRST is repurposed, we need a different layout_init setting
-ftdi_layout_init 0x0008 0x009b
-
-ftdi_layout_signal SWDIO_OE -nalias nTRST
-ftdi_layout_signal SWD_EN -alias TMS
-
-#Disable fast flashing, it only works with ST-Link and CMSIS-DAP
-set WORKAREASIZE 0
-source [find target/nrf51.cfg]
-source [find nrf51_cmds.tcl]
-
diff --git a/util/openocd/nrf51_cmds.tcl b/util/openocd/nrf51_cmds.tcl
deleted file mode 100644
index 711b27574d..0000000000
--- a/util/openocd/nrf51_cmds.tcl
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2015 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.
-#
-# Command automation for Nordic nRF51 chip
-
-proc flash_nrf51 {path offset} {
- reset halt;
- program $path $offset;
-}
-
-proc unprotect_nrf51 { } {
- reset halt;
- nrf51 mass_erase;
-}
-
-# enable reset by writing 1 to the RESET register
-# This will disconnect the debugger with the following message:
-# Polling target nrf51.cpu failed, trying to reexamine
-proc exit_debug_mode_nrf51 { } {
- mww 0x40000544 1;
-}
diff --git a/util/openocd/servo.cfg b/util/openocd/servo.cfg
deleted file mode 100644
index 8331a9bc08..0000000000
--- a/util/openocd/servo.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-telnet_port 4444
-gdb_port 3333
-gdb_memory_map enable
-gdb_flash_program enable
-
-interface ftdi
-# VID/PID for servo v2, servo v3
-ftdi_vid_pid 0x18d1 0x5002 0x18d1 0x5004 0x18d1 0x500d
-# Only initialize Port A
-ftdi_channel 0
-
-# unbuffered connection data == oe
-ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010
-
diff --git a/util/powerd_lock.c b/util/powerd_lock.c
deleted file mode 100644
index df34d03c6c..0000000000
--- a/util/powerd_lock.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is ported from the flashrom project.
- *
- * Copyright 2015 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.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * powerd_lock.c: power management routines
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "powerd_lock.h"
-
-/*
- * Path to a file containing flashrom's PID. While present, powerd avoids
- * suspending or shutting down the system.
- */
-static const char lock_file_path[] =
- "/run/lock/power_override/battery_tool.lock";
-
-int disable_power_management()
-{
- FILE *lock_file;
- int rc = 0;
- lock_file = fopen(lock_file_path, "w");
- if (!lock_file)
- return POWERD_CREATE_LOCK_FILE_ERROR;
-
- if (fprintf(lock_file, "%ld", (long)getpid()) < 0)
- rc = POWERD_WRITE_LOCK_FILE_ERROR;
-
- if (fclose(lock_file) != 0)
- rc |= POWERD_CLOSE_LOCK_FILE_ERROR;
- return rc;
-}
-
-int restore_power_management()
-{
- int result = 0;
- result = unlink(lock_file_path);
- if (result != 0 && errno != ENOENT)
- return POWERD_DELETE_LOCK_FILE_ERROR;
- return 0;
-}
diff --git a/util/powerd_lock.h b/util/powerd_lock.h
deleted file mode 100644
index 86be184a19..0000000000
--- a/util/powerd_lock.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is ported from the flashrom project.
- *
- * Copyright 2015 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.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * powerd_lock.h: header file for power management routines
- */
-
-#ifndef __UTIL_POWERD_LOCK_H
-#define __UTIL_POWERD_LOCK_H 1
-
-enum POWERD_ERROR_CODE {
- POWERD_OK = 0,
- POWERD_CREATE_LOCK_FILE_ERROR = 0x1,
- POWERD_WRITE_LOCK_FILE_ERROR = 0x2,
- POWERD_CLOSE_LOCK_FILE_ERROR = 0x4,
- POWERD_DELETE_LOCK_FILE_ERROR = 0x8
-};
-
-/* Disable power management. */
-int disable_power_management(void);
-
-/* Re-enable power management. */
-int restore_power_management(void);
-
-#endif /* __UTIL_POWERD_LOCK_H */
diff --git a/util/run_ects.py b/util/run_ects.py
deleted file mode 100644
index a633430113..0000000000
--- a/util/run_ects.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright 2017 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.
-
-"""Run all eCTS tests and publish results."""
-
-
-import argparse
-import logging
-import os
-import subprocess
-import sys
-
-# List of tests to run.
-TESTS = ['meta', 'gpio', 'hook', 'i2c', 'interrupt', 'mutex', 'task', 'timer']
-
-
-class CtsRunner(object):
- """Class running eCTS tests."""
-
- def __init__(self, ec_dir, dryrun):
- self.ec_dir = ec_dir
- self.cts_py = []
- if dryrun:
- self.cts_py += ['echo']
- self.cts_py += [os.path.join(ec_dir, 'cts/cts.py')]
-
- def run_cmd(self, cmd):
- try:
- rc = subprocess.call(cmd)
- if rc != 0:
- return False
- except OSError:
- return False
- return True
-
- def run_test(self, test):
- cmd = self.cts_py + ['-m', test]
- self.run_cmd(cmd)
-
- def run(self, tests):
- for test in tests:
- logging.info('Running', test, 'test.')
- self.run_test(test)
-
- def sync(self):
- logging.info('Syncing tree...')
- os.chdir(self.ec_dir)
- cmd = ['repo', 'sync', '.']
- return self.run_cmd(cmd)
-
- def upload(self):
- logging.info('Uploading results...')
-
-
-def main():
- if not os.path.exists('/etc/cros_chroot_version'):
- logging.error('This script has to run inside chroot.')
- sys.exit(-1)
-
- ec_dir = os.path.realpath(os.path.dirname(__file__) + '/..')
-
- parser = argparse.ArgumentParser(description='Run eCTS and report results.')
- parser.add_argument('-d',
- '--dryrun',
- action='store_true',
- help='Echo commands to be executed without running them.')
- parser.add_argument('-s',
- '--sync',
- action='store_true',
- help='Sync tree before running tests.')
- parser.add_argument('-u',
- '--upload',
- action='store_true',
- help='Upload test results.')
- args = parser.parse_args()
-
- runner = CtsRunner(ec_dir, args.dryrun)
-
- if args.sync:
- if not runner.sync():
- logging.error('Failed to sync.')
- sys.exit(-1)
-
- runner.run(TESTS)
-
- if args.upload:
- runner.upload()
-
-
-if __name__ == '__main__':
- main()
diff --git a/util/stm32mon.c b/util/stm32mon.c
deleted file mode 100644
index 324f208352..0000000000
--- a/util/stm32mon.c
+++ /dev/null
@@ -1,1698 +0,0 @@
-/* Copyright 2012 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.
- *
- * STM32 SoC system monitor interface tool
- * For Serial, implement protocol v2.0 as defined in:
- * http://www.st.com/st-web-ui/static/active/en/resource/technical/\
- * document/application_note/CD00264342.pdf
- *
- * For i2C, implement protocol v1.0 as defined in:
- * http://www.st.com/st-web-ui/static/active/en/resource/technical/\
- * document/application_note/DM00072315.pdf
- *
- * For SPI, implement protocol v1.1 as defined in:
- * https://www.st.com/resource/en/application_note/dm00081379.pdf
- */
-
-/* use cfmakeraw() */
-#define _DEFAULT_SOURCE /* Newer glibc */
-#define _BSD_SOURCE /* Older glibc */
-
-#include <arpa/inet.h>
-#include <compile_time_macros.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <linux/i2c-dev.h>
-#include <linux/spi/spidev.h>
-#include <termios.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "ec_version.h"
-
-#define KBYTES_TO_BYTES 1024
-
-/*
- * Some Ubuntu versions do not export SPI_IOC_WR_MODE32 even though
- * the kernel shipped on those supports it.
- */
-#ifndef SPI_IOC_WR_MODE32
-#define SPI_IOC_WR_MODE32 _IOW(SPI_IOC_MAGIC, 5, __u32)
-#endif
-
-/* Monitor command set */
-#define CMD_INIT 0x7f /* Starts the monitor */
-
-#define CMD_GETCMD 0x00 /* Gets the allowed commands */
-#define CMD_GETVER 0x01 /* Gets the bootloader version */
-#define CMD_GETID 0x02 /* Gets the Chip ID */
-#define CMD_READMEM 0x11 /* Reads memory */
-#define CMD_GO 0x21 /* Jumps to user code */
-#define CMD_WRITEMEM 0x31 /* Writes memory (SRAM or Flash) */
-#define CMD_ERASE 0x43 /* Erases n pages of Flash memory */
-#define CMD_EXTERASE 0x44 /* Erases n pages of Flash memory */
-#define CMD_NO_STRETCH_ERASE 0x45 /* Erases while sending busy frame */
-#define CMD_WP 0x63 /* Enables write protect */
-#define CMD_WU 0x73 /* Disables write protect */
-#define CMD_RP 0x82 /* Enables the read protection */
-#define CMD_RU 0x92 /* Disables the read protection */
-
-#define RESP_NACK 0x1f
-#define RESP_ACK 0x79 /* 0b 0111 1001 */
-#define RESP_BUSY 0x76
-#define RESP_DAMAGED_ACK 0xBC /* 0b 1011 1100, 1 bit shifted REST_ACK */
-
-/* SPI Start of Frame */
-#define SOF 0x5A
-
-/* Extended erase special parameters */
-#define ERASE_ALL 0xffff
-#define ERASE_BANK1 0xfffe
-#define ERASE_BANK2 0xfffd
-
-/* Upper bound of rebooting the monitor */
-#define MAX_DELAY_REBOOT 100000 /* us */
-
-/* Standard addresses common across various ST chips */
-#define STM32_MAIN_MEMORY_ADDR 0x08000000
-#define STM32_SYSTEM_MEMORY_ADDR 0x1FFF0000
-
-#define STM32_UNIQUE_ID_SIZE_BYTES 12
-
-/*
- * Device electronic signature contains factory-programmed identification
- * and calibration data to automatically match the characteristics of the
- * microcontroller.
- */
-struct stm32_device_signature {
- /*
- * Address of the Unique Device ID register. This register contains a
- * 96-bit value that is unique across all chips.
- * Zero means ignore/unknown.
- */
- uint32_t unique_device_id_addr;
- /*
- * Address of the Flash Size register. This 16-bit register contains the
- * flash size in KB.
- * Zero means ignore/unknown.
- */
- uint32_t flash_size_addr;
- /*
- * Address of the Package Data register. This 16-bit register contains a
- * value that differentiates between package types of a given chip.
- * Zero means ignore/unknown.
- */
- uint32_t package_data_addr;
-};
-
-struct memory_info {
- /* Zero means ignore/unknown/not-applicable */
- uint32_t addr;
- /* If addr is non-zero
- * - zero here means value is dynamic and will be read from bootloader.
- * If addr is zero,
- * - zero here means ignore/unknown/not-applicable.
- */
- uint32_t size_bytes;
-};
-
-struct memory_layout {
- struct memory_info main_memory;
- struct memory_info system_memory;
- struct memory_info otp_area;
- struct memory_info option_bytes;
-};
-
-/* known STM32 SoC parameters */
-struct stm32_def {
- uint16_t id;
- const char *name;
- uint32_t flash_size;
- uint32_t page_size;
- uint32_t cmds_len[2];
- const struct memory_layout memory_layout;
- const struct stm32_device_signature device_signature;
-} chip_defs[] = {
- {0x416, "STM32L15xxB", 0x20000, 256, {13, 13}, { { 0 } }, { 0 } },
- {0x429, "STM32L15xxB-A", 0x20000, 256, {13, 13}, { { 0 } }, { 0 } },
- {0x427, "STM32L15xxC", 0x40000, 256, {13, 13}, { { 0 } }, { 0 } },
- {0x435, "STM32L44xx", 0x40000, 2048, {13, 13}, { { 0 } }, { 0 } },
- {0x420, "STM32F100xx", 0x20000, 1024, {13, 13}, { { 0 } }, { 0 } },
- {0x410, "STM32F102R8", 0x10000, 1024, {13, 13}, { { 0 } }, { 0 } },
- {0x440, "STM32F05x", 0x10000, 1024, {13, 13}, { { 0 } }, { 0 } },
- {0x444, "STM32F03x", 0x08000, 1024, {13, 13}, { { 0 } }, { 0 } },
- {0x448, "STM32F07xB", 0x20000, 2048, {13, 13}, { { 0 } }, { 0 } },
- {0x432, "STM32F37xx", 0x40000, 2048, {13, 13}, { { 0 } }, { 0 } },
- {0x442, "STM32F09x", 0x40000, 2048, {13, 13}, { { 0 } }, { 0 } },
- {0x431, "STM32F411", 0x80000, 16384, {13, 19}, { { 0 } }, { 0 } },
- {
- .id = 0x441,
- .name = "STM32F412",
- .flash_size = 0x100000,
- .page_size = 16384,
- .cmds_len = {13, 19},
- /*
- * STM32F412:
- * See https://www.st.com/resource/en/reference_manual/dm00180369.pdf
- * Section 3.3 Table 5 Flash module organization
- */
- .memory_layout = {
- .main_memory = {
- .addr = STM32_MAIN_MEMORY_ADDR,
- .size_bytes = 0, /* set by flash reg read */
- },
- .system_memory = {
- .addr = STM32_SYSTEM_MEMORY_ADDR,
- .size_bytes = 30 * KBYTES_TO_BYTES,
- },
- .otp_area = {
- .addr = 0x1FFF7800,
- .size_bytes = 528,
- },
- .option_bytes = {
- .addr = 0x1FFFC000,
- .size_bytes = 16,
- }
- },
- /*
- * STM32F412:
- * See https://www.st.com/resource/en/reference_manual/dm00180369.pdf
- * Section 31 Device electronic signature
- */
- .device_signature = {
- .unique_device_id_addr = 0x1FFF7A10,
- .flash_size_addr = 0x1FFF7A22,
- /*
- * Out of range for bootloader on this chip, so we don't
- * attempt to read.
- */
- .package_data_addr = 0, /* 0x1FFF7BF0 */
- }
- },
- {0x450, "STM32H74x", 0x200000, 131768, {13, 19}, { { 0 } }, { 0 } },
- {0x451, "STM32F76x", 0x200000, 32768, {13, 19}, { { 0 } }, { 0 } },
- {
- .id = 0x460,
- .name = "STM32G071xx",
- .flash_size = 0x20000,
- .page_size = 2048,
- .cmds_len = {13, 13},
- /*
- * STM32G0x1:
- * See https://www.st.com/resource/en/reference_manual/dm00371828.pdf
- * Section 3.3.1 Table 6 Flash module organization
- */
- .memory_layout = {
- .main_memory = {
- .addr = STM32_MAIN_MEMORY_ADDR,
- .size_bytes = 0, /* set by flash reg read */
- },
- .system_memory = {
- .addr = STM32_SYSTEM_MEMORY_ADDR,
- .size_bytes = 28 * KBYTES_TO_BYTES,
- },
- .otp_area = {
- .addr = 0x1FFF7000,
- .size_bytes = 1024,
- },
- .option_bytes = {
- .addr = 0x1FFF7800,
- .size_bytes = 128,
- }
- },
- /*
- * STM32G0x1:
- * See https://www.st.com/resource/en/reference_manual/dm00371828.pdf
- * Section 38 Device electronic signature
- */
- .device_signature = {
- .unique_device_id_addr = 0x1FFF7590,
- .flash_size_addr = 0x1FFF75E0,
- /*
- * Datasheet litst as same address as e.g. STM32F412,
- * hence declaring as zero as for that other chip.
- */
- .package_data_addr = 0, /* 0x1FFF7500 */
- }
- },
- { 0 }
-};
-
-#define DEFAULT_TIMEOUT 4 /* seconds */
-#define EXT_ERASE_TIMEOUT 20 /* seconds */
-#define DEFAULT_BAUDRATE B38400
-#define PAGE_SIZE 256
-#define INVALID_I2C_ADAPTER -1
-#define MAX_ACK_RETRY_COUNT (EXT_ERASE_TIMEOUT / DEFAULT_TIMEOUT)
-#define MAX_RETRY_COUNT 3
-
-enum interface_mode {
- MODE_SERIAL,
- MODE_I2C,
- MODE_SPI,
-} mode = MODE_SERIAL;
-
-/* I2c address the EC is listening depends on the device:
- * stm32f07xxx: 0x76
- * stm32f411xx: 0x72
- */
-#define DEFAULT_I2C_SLAVE_ADDRESS 0x76
-
-/* store custom parameters */
-speed_t baudrate = DEFAULT_BAUDRATE;
-int i2c_adapter = INVALID_I2C_ADAPTER;
-const char *spi_adapter;
-int i2c_slave_address = DEFAULT_I2C_SLAVE_ADDRESS;
-uint8_t boot_loader_version;
-const char *serial_port = "/dev/ttyUSB1";
-const char *input_filename;
-const char *output_filename;
-uint32_t offset = 0x08000000, length = 0;
-int retry_on_damaged_ack;
-
-/* STM32MON function return values */
-enum {
- STM32_SUCCESS = 0,
- STM32_EIO = -1, /* IO error */
- STM32_EINVAL = -2, /* Got a faulty response from device */
- STM32_ETIMEDOUT = -3, /* Device didn't respond in a time window. */
- STM32_ENOMEM = -4, /* Failed to allocate memory. */
- STM32_ENACK = -5, /* Got NACK. */
- STM32_EDACK = -6, /* Got a damanged ACK. */
-};
-BUILD_ASSERT(STM32_SUCCESS == 0);
-#define IS_STM32_ERROR(res) ((res) < STM32_SUCCESS)
-
-/* optional command flags */
-enum {
- FLAG_UNPROTECT = 0x01,
- FLAG_ERASE = 0x02,
- FLAG_GO = 0x04,
- FLAG_READ_UNPROTECT = 0x08,
- FLAG_CR50_MODE = 0x10,
-};
-
-typedef struct {
- int size;
- uint8_t *data;
-} payload_t;
-
-/* List all possible flash erase functions */
-typedef int command_erase_t(int fd, uint16_t count, uint16_t start);
-command_erase_t command_erase;
-command_erase_t command_ext_erase;
-command_erase_t command_erase_i2c;
-
-command_erase_t *erase;
-
-static void discard_input(int);
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-/* On user request save all data exchange with the target in this log file. */
-static FILE *log_file;
-
-/* Statistic data structure for response kind. */
-struct {
- const char * const event_name;
- uint32_t event_count;
-} stat_resp[] = {
- { "RESP_ACK", 0 },
- { "RESP_NACK", 0 },
- { "RESP_BUSY", 0 },
- { "RESP_DAMAGED_ACK", 0 },
- { "JUNK", 0 },
-};
-
-enum {
- RESP_ACK_IDX = 0,
- RESP_NACK_IDX,
- RESP_BUSY_IDX,
- RESP_DAMAGED_ACK_IDX,
- JUNK_IDX,
- MAX_EVENT_IDX
-};
-
-BUILD_ASSERT(ARRAY_SIZE(stat_resp) == MAX_EVENT_IDX);
-
-/*
- * Print data into the log file, in hex, 16 bytes per line, prefix the first
- * line with the value supplied by the caller (usually 'r' or 'w' for
- * read/write).
- */
-static void dump_log(const char *prefix, const void *data, size_t count)
-{
- size_t i;
-
- fprintf(log_file, "%s: ", prefix);
- for (i = 0; i < count; i++) {
- if (i && !(i % 16))
- fprintf(log_file, "\n ");
- fprintf(log_file, " %02x", ((uint8_t *)data)[i]);
- }
-
- if (count % 16)
- fprintf(log_file, "\n");
-
- /* Make sure all data is there even in case of aborts/crashes. */
- fflush(log_file);
-}
-
-/*
- * Wrappers for standard library read() and write() functions. Add transferred
- * data to the log if log file is opened.
- */
-static ssize_t read_wrapper(int fd, void *buf, size_t count)
-{
- ssize_t rv = read(fd, buf, count);
-
- if (log_file && (rv > 0))
- dump_log("r", buf, rv);
-
- return rv;
-}
-
-static ssize_t write_wrapper(int fd, const void *buf, size_t count)
-{
- ssize_t rv;
-
- rv = write(fd, buf, count);
-
- if (log_file && (rv > 0))
- dump_log("w", buf, rv);
-
- return rv;
-}
-
-int open_serial(const char *port, int cr50_mode)
-{
- int fd, res;
- struct termios cfg, cfg_copy;
-
- fd = open(port, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- perror("Unable to open serial port");
- return -1;
- }
-
- /* put the tty in "raw" mode at the defined baudrate */
- res = tcgetattr(fd, &cfg);
- if (res == -1) {
- perror("Cannot read tty attributes");
- close(fd);
- return -1;
- }
- cfmakeraw(&cfg);
-
- /* Don't bother setting speed and parity when programming over Cr50. */
- if (!cr50_mode) {
- cfsetspeed(&cfg, baudrate);
- /* serial mode should be 8e1 */
- cfg.c_cflag |= PARENB;
- }
-
- /* 200 ms timeout */
- cfg.c_cc[VTIME] = 2;
- cfg.c_cc[VMIN] = 0;
- memcpy(&cfg_copy, &cfg, sizeof(cfg_copy));
-
- /*
- * tcsetattr() returns success if any of the modifications succeed, so
- * its return value of zero is not an indication of success, one needs
- * to check the result explicitly.
- */
- tcsetattr(fd, TCSANOW, &cfg);
- if (tcgetattr(fd, &cfg)) {
- perror("Failed to re-read tty attributes");
- close(fd);
- return -1;
- }
-
- if (memcmp(&cfg, &cfg_copy, sizeof(cfg))) {
- /*
- * On some systems the setting which does not come through is
- * the parity. We can try continuing without it when using
- * certain interfaces, let's try.
- */
- cfg_copy.c_cflag &= ~PARENB;
- if (memcmp(&cfg, &cfg_copy, sizeof(cfg))) {
- /*
- * Something other than parity failed to get set, this
- * is an error.
- */
- perror("Cannot set tty attributes");
- close(fd);
- return -1;
- } else {
- fprintf(stderr, "Failed to enable parity\n");
- }
- }
-
- discard_input(fd); /* in case were were invoked soon after reset */
- return fd;
-}
-
-int open_i2c(const int port)
-{
- int fd;
- char filename[20];
-
- snprintf(filename, 19, "/dev/i2c-%d", port);
- fd = open(filename, O_RDWR);
- if (fd < 0) {
- perror("Unable to open i2c adapter");
- return -1;
- }
- if (ioctl(fd, I2C_SLAVE, i2c_slave_address >> 1) < 0) {
- perror("Unable to select proper address");
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-int open_spi(const char *port)
-{
- int fd;
- int res;
- uint32_t mode = SPI_MODE_0;
- uint8_t bits = 8;
-
- fd = open(port, O_RDWR);
- if (fd == -1) {
- perror("Unable to open SPI controller");
- return -1;
- }
-
- res = ioctl(fd, SPI_IOC_WR_MODE32, &mode);
- if (res == -1) {
- perror("Cannot set SPI mode");
- close(fd);
- return -1;
- }
-
- res = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
- if (res == -1) {
- perror("Cannot set SPI bits per word");
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-static void discard_input(int fd)
-{
- uint8_t buffer[64];
- int res, i;
- int count_of_zeros;
-
- /* Skip in i2c and spi modes */
- if (mode != MODE_SERIAL)
- return;
-
- /* eat trailing garbage */
- count_of_zeros = 0;
- do {
- res = read_wrapper(fd, buffer, sizeof(buffer));
- if (res > 0) {
-
- /* Discard zeros in the beginning of the buffer. */
- for (i = 0; i < res; i++)
- if (buffer[i])
- break;
-
- count_of_zeros += i;
- if (i == res) {
- /* Only zeros, nothing to print out. */
- continue;
- }
-
- /* Discard zeros in the end of the buffer. */
- while (!buffer[res - 1]) {
- count_of_zeros++;
- res--;
- }
-
- printf("Recv[%d]:", res - i);
- for (; i < res; i++)
- printf("%02x ", buffer[i]);
- printf("\n");
- }
- } while (res > 0);
-
- if (count_of_zeros)
- printf("%d zeros ignored\n", count_of_zeros);
-}
-
-int wait_for_ack(int fd)
-{
- uint8_t resp;
- int res;
- time_t deadline = time(NULL) + DEFAULT_TIMEOUT;
- const uint8_t ack = RESP_ACK;
-
- while (time(NULL) < deadline) {
- res = read_wrapper(fd, &resp, 1);
- if ((res < 0) && (errno != EAGAIN)) {
- perror("Failed to read answer");
- return STM32_EIO;
- }
-
- if (res != 1)
- continue;
-
- switch (resp) {
- case RESP_ACK:
- stat_resp[RESP_ACK_IDX].event_count++;
- if (mode == MODE_SPI) /* Ack the ACK */
- if (write_wrapper(fd, &ack, 1) != 1)
- return STM32_EIO;
- return STM32_SUCCESS;
-
- case RESP_NACK:
- stat_resp[RESP_NACK_IDX].event_count++;
- fprintf(stderr, "NACK\n");
- if (mode == MODE_SPI) /* Ack the NACK */
- if (write_wrapper(fd, &ack, 1) != 1)
- return STM32_EIO;
- discard_input(fd);
- return STM32_ENACK;
-
- case RESP_BUSY:
- stat_resp[RESP_BUSY_IDX].event_count++;
- /* I2C Boot protocol 1.1 */
- deadline = time(NULL) + DEFAULT_TIMEOUT;
- break;
-
- case RESP_DAMAGED_ACK:
- if (retry_on_damaged_ack) {
- /* It is a damaged ACK. However, device is
- * likely to believe it sent ACK, so let's not
- * treat it as junk.
- */
- stat_resp[RESP_DAMAGED_ACK_IDX].event_count++;
- fprintf(stderr, "DAMAGED_ACK\n");
- return STM32_EDACK;
- }
-
- /* Do not break so that it can be handled as junk */
- default:
- stat_resp[JUNK_IDX].event_count++;
- if (mode == MODE_SERIAL)
- fprintf(stderr, "Receive junk: %02x\n", resp);
- break;
- }
- }
- fprintf(stderr, "Timeout\n");
- return STM32_ETIMEDOUT;
-}
-
-int send_command(int fd, uint8_t cmd, payload_t *loads, int cnt,
- uint8_t *resp, int resp_size, int ack_requested)
-{
- int res, i, c;
- payload_t *p;
- int readcnt = 0;
- uint8_t cmd_frame[] = { SOF, cmd, 0xff ^ cmd }; /* XOR checksum */
- /* only the SPI mode needs the Start Of Frame byte */
- int cmd_off = mode == MODE_SPI ? 0 : 1;
- int count_damaged_ack = 0;
-
- /* Send the command index */
- res = write_wrapper(fd, cmd_frame + cmd_off,
- sizeof(cmd_frame) - cmd_off);
- if (res <= 0) {
- perror("Failed to write command frame");
- return STM32_EIO;
- }
-
- /* Wait for the ACK */
- res = wait_for_ack(fd);
- if (res == STM32_EDACK) {
- ++count_damaged_ack;
- } else if (IS_STM32_ERROR(res)) {
- fprintf(stderr, "Failed to get command 0x%02x ACK\n", cmd);
- return res;
- }
-
- /* Send the command payloads */
- for (p = loads, c = 0; c < cnt; c++, p++) {
- uint8_t crc = 0;
- int size = p->size;
- uint8_t *data = malloc(size + 1), *data_ptr;
-
- if (data == NULL) {
- fprintf(stderr,
- "Failed to allocate memory for load %d\n", c);
- return STM32_ENOMEM;
- }
- memcpy(data, p->data, size);
- for (i = 0; i < size; i++)
- crc ^= data[i];
- if (size == 1)
- crc = 0xff ^ crc;
- data[size] = crc;
- size++;
- data_ptr = data;
- while (size) {
- res = write_wrapper(fd, data_ptr, size);
- if (res < 0) {
- perror("Failed to write command payload");
- free(data);
- return STM32_EIO;
- }
- size -= res;
- data_ptr += res;
- }
- free(data);
-
- /* Wait for the ACK */
- res = wait_for_ack(fd);
- if (res == STM32_EDACK) {
- ++count_damaged_ack;
- } else if (IS_STM32_ERROR(res)) {
- if (res != STM32_ETIMEDOUT)
- fprintf(stderr,
- "payload %d ACK failed for CMD%02x\n",
- c, cmd);
- return res;
- }
- }
-
- /* Read the answer payload */
- if (resp) {
- if (mode == MODE_SPI) /* ignore dummy byte */
- if (read_wrapper(fd, resp, 1) < 0)
- return STM32_EIO;
- while ((resp_size > 0) &&
- (res = read_wrapper(fd, resp, resp_size))) {
- if (res < 0) {
- perror("Failed to read payload");
- return STM32_EIO;
- }
- readcnt += res;
- resp += res;
- resp_size -= res;
- }
-
- /* Wait for the ACK */
- if (ack_requested) {
- res = wait_for_ack(fd);
- if (res == STM32_EDACK) {
- ++count_damaged_ack;
- } else if (IS_STM32_ERROR(res)) {
- fprintf(stderr,
- "Failed to get response to command"
- " 0x%02x ACK\n", cmd);
- return res;
- }
- }
- }
-
- if (count_damaged_ack)
- return STM32_EDACK;
-
- return readcnt;
-}
-
-int send_command_retry(int fd, uint8_t cmd, payload_t *loads,
- int cnt, uint8_t *resp, int resp_size, int ack_requested)
-{
- int res;
- int retries = MAX_RETRY_COUNT;
-
- do {
- int ack_tries = MAX_ACK_RETRY_COUNT;
-
- res = send_command(fd, cmd, loads, cnt, resp, resp_size,
- ack_requested);
-
- while (res == STM32_ETIMEDOUT && ack_tries--) {
- if (cmd == CMD_WRITEMEM) {
- /* send garbage byte */
- res = write_wrapper(fd, loads->data, 1);
- /* Don't care much since it is a garbage
- * transfer to let the device not wait for
- * any missing data, if any.
- */
- if (res < 0)
- fprintf(stderr, "warn: write failed\n");
- }
- res = wait_for_ack(fd);
- }
- } while ((res == STM32_ENACK || res == STM32_EDACK) && retries--);
-
- return res;
-}
-
-struct stm32_def *command_get_id(int fd)
-{
- int res;
- uint8_t id[3];
- uint16_t chipid;
- struct stm32_def *def;
-
- res = send_command(fd, CMD_GETID, NULL, 0, id, sizeof(id), 1);
- if (res > 0) {
- if (id[0] != 1) {
- fprintf(stderr, "unknown ID : %02x %02x %02x\n",
- id[0], id[1], id[2]);
- return NULL;
- }
- chipid = (id[1] << 8) | id[2];
- for (def = chip_defs; def->id; def++)
- if (def->id == chipid)
- break;
- if (def->id == 0)
- def = NULL;
- printf("ChipID 0x%03x : %s\n", chipid, def ? def->name : "???");
- return def;
- }
-
- return NULL;
-}
-
-int init_monitor(int fd)
-{
- int res;
- uint8_t init = mode == MODE_SPI ? SOF : CMD_INIT;
-
- /* Skip in i2c mode */
- if (mode == MODE_I2C)
- return STM32_SUCCESS;
-
- printf("Waiting for the monitor startup ...");
- fflush(stdout);
-
- while (1) {
- /* Send the command index */
- res = write_wrapper(fd, &init, 1);
- if (res <= 0) {
- perror("Failed to write command");
- return STM32_EIO;
- }
- /* Wait for the ACK */
- res = wait_for_ack(fd);
- if (res == STM32_SUCCESS)
- break;
- if (res == STM32_ENACK) {
- /* we got NACK'ed, the loader might be already started
- * let's ping it to check
- */
- if (command_get_id(fd)) {
- printf("Monitor already started.\n");
- return STM32_SUCCESS;
- }
- }
- if (IS_STM32_ERROR(res) && res != STM32_ETIMEDOUT)
- return res;
- fflush(stdout);
- }
- printf("Done.\n");
-
- /* read trailing chars */
- discard_input(fd);
-
- return STM32_SUCCESS;
-}
-
-int command_get_commands(int fd, struct stm32_def *chip)
-{
- int res, i;
- uint8_t cmds[64];
-
- /*
- * For i2c, we have to request the exact amount of bytes we expect.
- */
- res = send_command(fd, CMD_GETCMD, NULL, 0, cmds,
- chip->cmds_len[(mode == MODE_I2C ? 1 : 0)], 1);
- if (res > 0) {
- if (cmds[0] > sizeof(cmds) - 2) {
- fprintf(stderr, "invalid GET answer (%02x...)\n",
- cmds[0]);
- return STM32_EINVAL;
- }
- printf("Bootloader v%d.%d, commands : ",
- cmds[1] >> 4, cmds[1] & 0xf);
- boot_loader_version = cmds[1];
-
- erase = command_erase;
- for (i = 2; i < 2 + cmds[0]; i++) {
- if (cmds[i] == CMD_EXTERASE)
- erase = command_ext_erase;
- printf("%02x ", cmds[i]);
- }
-
- if (mode == MODE_I2C)
- erase = command_erase_i2c;
- printf("\n");
-
- return STM32_SUCCESS;
- }
-
- fprintf(stderr, "Cannot get bootloader command list.\n");
- return STM32_EINVAL;
-}
-
-static int use_progressbar;
-static int windex;
-static const char wheel[] = {'|', '/', '-', '\\' };
-static void draw_spinner(uint32_t remaining, uint32_t size)
-{
- int percent = (size - remaining)*100/size;
- if (use_progressbar) {
- int dots = percent / 4;
-
- while (dots > windex) {
- putchar('#');
- windex++;
- }
- } else {
- printf("\r%c%3d%%", wheel[windex++], percent);
- windex %= sizeof(wheel);
- }
- fflush(stdout);
-}
-
-int command_read_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer)
-{
- int res;
- uint32_t remaining = size;
- uint32_t addr_be;
- uint8_t cnt;
- payload_t loads[2] = {
- {4, (uint8_t *)&addr_be},
- {1, &cnt}
- };
-
- while (remaining) {
- uint32_t bytes = MIN(remaining, PAGE_SIZE);
-
- cnt = (uint8_t) (bytes - 1);
- addr_be = htonl(address);
-
- draw_spinner(remaining, size);
-
- res = send_command_retry(fd, CMD_READMEM, loads, 2, buffer,
- bytes, 0);
- if (IS_STM32_ERROR(res))
- return STM32_EIO;
-
- buffer += bytes;
- address += bytes;
- remaining -= bytes;
- }
-
- return size;
-}
-
-int command_write_mem(int fd, uint32_t address, uint32_t size, uint8_t *buffer)
-{
- int res = 0;
- int i;
- uint32_t remaining = size;
- uint32_t addr_be;
- uint32_t cnt;
- uint8_t outbuf[257];
- payload_t loads[2] = {
- {4, (uint8_t *)&addr_be},
- {sizeof(outbuf), outbuf}
- };
-
- while (remaining) {
- cnt = MIN(remaining, PAGE_SIZE);
- /* skip empty blocks to save time */
- for (i = 0; i < cnt && buffer[i] == 0xff; i++)
- ;
- if (i != cnt) {
- addr_be = htonl(address);
- outbuf[0] = cnt - 1;
- loads[1].size = cnt + 1;
- memcpy(outbuf + 1, buffer, cnt);
-
- draw_spinner(remaining, size);
-
- res = send_command_retry(fd, CMD_WRITEMEM, loads, 2,
- NULL, 0, 1);
- if (IS_STM32_ERROR(res))
- return STM32_EIO;
- }
- buffer += cnt;
- address += cnt;
- remaining -= cnt;
- }
-
- return size;
-}
-
-int command_ext_erase(int fd, uint16_t count, uint16_t start)
-{
- int res;
- uint16_t count_be = htons(count);
- payload_t load = { 2, (uint8_t *)&count_be };
- uint16_t *pages = NULL;
-
- if (count < 0xfff0) {
- int i;
- /* not a special value : build a list of pages */
- load.size = 2 * (count + 1);
- pages = malloc(load.size);
- if (!pages)
- return STM32_ENOMEM;
- load.data = (uint8_t *)pages;
- pages[0] = htons(count - 1);
- for (i = 0; i < count; i++)
- pages[i+1] = htons(start + i);
- }
-
- printf("Erasing...\n");
- res = send_command_retry(fd, CMD_EXTERASE, &load, 1, NULL, 0, 1);
- if (!IS_STM32_ERROR(res))
- printf("Flash erased.\n");
-
- if (pages)
- free(pages);
- return res;
-}
-
-int command_erase_i2c(int fd, uint16_t count, uint16_t start)
-{
- int res;
- uint8_t erase_cmd;
- uint16_t count_be = htons(count);
- payload_t load[2] = {
- { 2, (uint8_t *)&count_be},
- { 0, NULL},
- };
- int load_cnt = 1;
- uint16_t *pages = NULL;
-
- if (count < 0xfff) {
- int i;
- /* not a special value : build a list of pages */
- /*
- * I2c protocol requires 2 messages, the count has to be acked
- * before the addresses can be sent.
- * TODO(gwendal): Still broken on i2c.
- */
- load_cnt = 2;
- load[1].size = 2 * count;
- pages = malloc(load[1].size);
- if (!pages)
- return STM32_ENOMEM;
- load[1].data = (uint8_t *)pages;
- count_be = htons(count - 1);
- for (i = 0; i < count; i++)
- pages[i] = htons(start + i);
- }
-
- erase_cmd = (boot_loader_version == 0x10) ? CMD_EXTERASE :
- CMD_NO_STRETCH_ERASE;
-
- printf("Erasing...\n");
- res = send_command(fd, erase_cmd, load, load_cnt, NULL, 0, 1);
- if (!IS_STM32_ERROR(res))
- printf("Flash erased.\n");
-
- if (pages)
- free(pages);
- return res;
-}
-
-
-int command_erase(int fd, uint16_t count, uint16_t start)
-{
- int res;
- uint8_t count_8bit = count;
- payload_t load = { 1, &count_8bit };
- uint8_t *pages = NULL;
-
- if (count < 0xff) {
- int i;
- /* not a special value : build a list of pages */
- load.size = count + 1;
- pages = malloc(load.size);
- if (!pages)
- return STM32_ENOMEM;
- load.data = (uint8_t *)pages;
- pages[0] = count - 1;
- for (i = 0; i < count; i++)
- pages[i+1] = start + i;
- }
-
- printf("Erasing...\n");
- res = send_command(fd, CMD_ERASE, &load, 1, NULL, 0, 1);
- if (!IS_STM32_ERROR(res))
- printf("Flash erased.\n");
-
- if (pages)
- free(pages);
- return res;
-}
-
-int command_read_unprotect(int fd)
-{
- int res;
- int retries = MAX_RETRY_COUNT;
-
- printf("Unprotecting flash read...\n");
-
- res = send_command(fd, CMD_RU, NULL, 0, NULL, 0, 1);
- /*
- * Read unprotect can trigger a mass erase, which can take long time
- * (e.g. 13s+ on STM32H7)
- */
- do {
- res = wait_for_ack(fd);
- } while ((res == STM32_ETIMEDOUT) && --retries);
-
- if (IS_STM32_ERROR(res)) {
- fprintf(stderr, "Failed to get read-protect ACK\n");
- return res;
- }
- printf("Flash read unprotected.\n");
-
- /*
- * This command triggers a reset.
- *
- * Wait at least the reboot delay, else we could reconnect
- * before the actual reset depending on the bootloader.
- */
- usleep(MAX_DELAY_REBOOT);
- if (init_monitor(fd) < 0) {
- fprintf(stderr, "Cannot recover after RU reset\n");
- return STM32_EIO;
- }
-
- return STM32_SUCCESS;
-}
-
-int command_write_unprotect(int fd)
-{
- int res;
-
- res = send_command(fd, CMD_WU, NULL, 0, NULL, 0, 1);
- if (IS_STM32_ERROR(res))
- return STM32_EIO;
-
- /* Wait for the ACK */
- if (wait_for_ack(fd) < 0) {
- fprintf(stderr, "Failed to get write-protect ACK\n");
- return STM32_EINVAL;
- }
- printf("Flash write unprotected.\n");
-
- /*
- * This command triggers a reset.
- *
- * Wait at least the reboot delay, else we could reconnect
- * before the actual reset depending on the bootloader.
- */
- usleep(MAX_DELAY_REBOOT);
- if (init_monitor(fd) < 0) {
- fprintf(stderr, "Cannot recover after WP reset\n");
- return STM32_EIO;
- }
-
- return STM32_SUCCESS;
-}
-
-int command_go(int fd, uint32_t address)
-{
- int res;
- uint32_t addr_be = htonl(address);
- payload_t load = { 4, (uint8_t *)&addr_be };
-
- res = send_command(fd, CMD_GO, &load, 1, NULL, 0, 1);
- if (IS_STM32_ERROR(res))
- return STM32_EIO;
-
-#if 0 /* this ACK should exist according to the documentation ... */
- /* Wait for the ACK */
- if (wait_for_ack(fd) < 0) {
- fprintf(stderr, "Failed to get GO ACK\n");
- return -EINVAL;
- }
-#endif
-
- printf("Program started at 0x%08x.\n", address);
- return STM32_SUCCESS;
-}
-
-/*
- * The bootloader does not allow reading directly from the "device signature"
- * registers. However, it does allow reading the OTP region, so this function
- * starts a read from the last byte in that region and reads an additional
- * number of bytes to read the requested register.
- *
- * Example:
- *
- * Given a chip with OTP region starting at address 0x1FFF7800 with a size of
- * 528 bytes and a register that we want to read at address 0x1FFF7A10 with a
- * size of 12 bytes:
- *
- * We start the read at the last byte in the OTP region:
- *
- * 0x1FFF7800 + 528 - 1 = 0x1FFF7A0F
- *
- * From 0x1FFF7A0F we perform a read of (12 + 1) = 13 bytes in order to read the
- * 12 bytes starting at 0x1FFF7A10 (the actual register we care about).
- *
- * Returns zero on success, negative on failure.
- */
-int read_device_signature_register(int fd, const struct stm32_def *chip,
- uint32_t addr, uint32_t size_bytes,
- uint8_t *out_buffer)
-{
- int res;
- uint8_t *buffer;
- struct memory_info otp = chip->memory_layout.otp_area;
- uint32_t otp_end_addr = otp.addr + otp.size_bytes - 1;
- uint32_t offset = addr - otp_end_addr;
- uint32_t read_size_bytes = offset + size_bytes;
-
- if (!otp.addr) {
- fprintf(stderr, "No otp_area.addr specified for given chip.\n");
- return STM32_EINVAL;
- }
-
- if (addr <= otp_end_addr) {
- fprintf(stderr, "Attempting to read from invalid address: "
- "%08X\n", addr);
- return STM32_EINVAL;
- }
-
- /*
- * The USART/SPI/I2C bootloader can only read at most 256 bytes in a
- * single read command (see AN4286 section 2.5 or AN3155 section 3.4).
- *
- * command_read_mem will correctly chunk larger requests, but the
- * subsequent reads will fail because the bootloader won't allow reads
- * from a starting address that is beyond the OTP region.
- */
- if (read_size_bytes > PAGE_SIZE) {
- fprintf(stderr,
- "Requested register 0x%08X is outside read range.\n",
- addr);
- return STM32_EINVAL;
- }
-
- buffer = malloc(read_size_bytes);
- if (!buffer) {
- fprintf(stderr, "Cannot allocate %" PRIu32 " bytes\n",
- read_size_bytes);
- return STM32_ENOMEM;
- }
-
- res = command_read_mem(fd, otp_end_addr, read_size_bytes, buffer);
- if (res == read_size_bytes)
- memcpy(out_buffer, buffer + offset, size_bytes);
- else
- fprintf(stderr,
- "Cannot read %" PRIu32 " bytes from address 0x%08X",
- read_size_bytes, otp_end_addr);
-
- free(buffer);
- return IS_STM32_ERROR(res) ? res : STM32_SUCCESS;
-}
-
-/* Return zero on success, a negative error value on failures. */
-int read_flash_size_register(int fd, struct stm32_def *chip,
- uint16_t *flash_size_kbytes)
-{
- int res;
- uint32_t flash_size_addr = chip->device_signature.flash_size_addr;
-
- if (!flash_size_addr)
- return STM32_EINVAL;
-
- res = read_device_signature_register(fd, chip,
- flash_size_addr, sizeof(*flash_size_kbytes),
- (uint8_t *)flash_size_kbytes);
-
- if (!IS_STM32_ERROR(res))
- printf("Flash size: %" PRIu16 " KB\n", *flash_size_kbytes);
- else
- fprintf(stderr,
- "Unable to read flash size register (0x%08X).\n",
- flash_size_addr);
-
- return res;
-}
-
-/* Return zero on success, a negative error value on failures. */
-int read_unique_device_id_register(int fd, struct stm32_def *chip,
- uint8_t device_id[STM32_UNIQUE_ID_SIZE_BYTES])
-{
- int i;
- int res;
- uint32_t unique_device_id_addr =
- chip->device_signature.unique_device_id_addr;
-
- if (!unique_device_id_addr)
- return STM32_EINVAL;
-
- res = read_device_signature_register(fd, chip, unique_device_id_addr,
- STM32_UNIQUE_ID_SIZE_BYTES, device_id);
-
- if (!IS_STM32_ERROR(res)) {
- printf("Unique Device ID: 0x");
- for (i = STM32_UNIQUE_ID_SIZE_BYTES - 1; i >= 0; i--)
- printf("%02X", device_id[i]);
- printf("\n");
- } else {
- fprintf(stderr,
- "Unable to read unique device ID register (0x%08X). "
- "Ignoring non-critical failure.\n",
- unique_device_id_addr);
- }
-
- return res;
-}
-
-/* Return zero on success, a negative error value on failures. */
-int read_package_data_register(int fd, struct stm32_def *chip,
- uint16_t *package_data)
-{
- int res;
- uint32_t package_data_addr = chip->device_signature.package_data_addr;
-
- if (!package_data_addr)
- return STM32_EINVAL;
-
- res = read_device_signature_register(fd, chip, package_data_addr,
- sizeof(*package_data),
- (uint8_t *)package_data);
-
- if (!IS_STM32_ERROR(res))
- printf("Package data register: %04X\n", *package_data);
- else
- fprintf(stderr,
- "Failed to read package data register (0x%08X). "
- "Ignoring non-critical failure.\n", package_data_addr);
-
- return res;
-}
-
-/* Return zero on success, a negative error value on failures. */
-int read_flash(int fd, struct stm32_def *chip, const char *filename,
- uint32_t offset, uint32_t size)
-{
- int res;
- FILE *hnd;
- uint8_t *buffer;
-
- if (!size)
- size = chip->flash_size;
- buffer = malloc(size);
- if (!buffer) {
- fprintf(stderr, "Cannot allocate %d bytes\n", size);
- return STM32_ENOMEM;
- }
-
- hnd = fopen(filename, "w");
- if (!hnd) {
- fprintf(stderr, "Cannot open file %s for writing\n", filename);
- free(buffer);
- return STM32_EIO;
- }
-
- printf("Reading %d bytes at 0x%08x\n", size, offset);
- res = command_read_mem(fd, offset, size, buffer);
- if (res > 0) {
- if (fwrite(buffer, res, 1, hnd) != 1)
- fprintf(stderr, "Cannot write %s\n", filename);
- }
- printf("\r %d bytes read.\n", res);
-
- fclose(hnd);
- free(buffer);
- return IS_STM32_ERROR(res) ? res : STM32_SUCCESS;
-}
-
-/* Return zero on success, a negative error value on failures. */
-int write_flash(int fd, struct stm32_def *chip, const char *filename,
- uint32_t offset)
-{
- int res, written;
- FILE *hnd;
- int size = chip->flash_size;
- uint8_t *buffer = malloc(size);
-
- if (!buffer) {
- fprintf(stderr, "Cannot allocate %d bytes\n", size);
- return STM32_ENOMEM;
- }
-
- if (!strncmp(filename, "-", sizeof("-")))
- hnd = fdopen(STDIN_FILENO, "r");
- else
- hnd = fopen(filename, "r");
- if (!hnd) {
- fprintf(stderr, "Cannot open file %s for reading\n", filename);
- free(buffer);
- return STM32_EIO;
- }
- res = fread(buffer, 1, size, hnd);
- fclose(hnd);
- if (res <= 0) {
- fprintf(stderr, "Cannot read %s\n", filename);
- free(buffer);
- return STM32_EIO;
- }
-
- /* faster write: skip empty trailing space */
- while (res && buffer[res - 1] == 0xff)
- res--;
- /* ensure 'res' is multiple of 4 given 'size' is and res <= size */
- res = (res + 3) & ~3;
-
- printf("Writing %d bytes at 0x%08x\n", res, offset);
- written = command_write_mem(fd, offset, res, buffer);
- if (written != res) {
- fprintf(stderr, "Error writing to flash\n");
- free(buffer);
- return STM32_EIO;
- }
- printf("\r %d bytes written.\n", written);
-
- free(buffer);
- return STM32_SUCCESS;
-}
-
-static const struct option longopts[] = {
- {"adapter", 1, 0, 'a'},
- {"baudrate", 1, 0, 'b'},
- {"cr50", 0, 0, 'c'},
- {"device", 1, 0, 'd'},
- {"erase", 0, 0, 'e'},
- {"go", 0, 0, 'g'},
- {"help", 0, 0, 'h'},
- {"length", 1, 0, 'n'},
- {"location", 1, 0, 'l'},
- {"logfile", 1, 0, 'L'},
- {"offset", 1, 0, 'o'},
- {"progressbar", 0, 0, 'p'},
- {"read", 1, 0, 'r'},
- {"spi", 1, 0, 's'},
- {"unprotect", 0, 0, 'u'},
- {"version", 0, 0, 'v'},
- {"write", 1, 0, 'w'},
- {NULL, 0, 0, 0}
-};
-
-void display_usage(char *program)
-{
- fprintf(stderr,
- "Usage: %s [-a <i2c_adapter> [-l address ]] | [-s]"
- " [-d <tty>] [-b <baudrate>]] [-u] [-e] [-U]"
- " [-r <file>] [-w <file>] [-o offset] [-n length] [-g] [-p]"
- " [-L <log_file>] [-c] [-v]\n",
- program);
- fprintf(stderr, "Can access the controller via serial port or i2c\n");
- fprintf(stderr, "Serial port mode:\n");
- fprintf(stderr, "--d[evice] <tty> : use <tty> as the serial port\n");
- fprintf(stderr, "--b[audrate] <baudrate> : set serial port speed "
- "to <baudrate> bauds\n");
- fprintf(stderr, "i2c mode:\n");
- fprintf(stderr, "--a[dapter] <id> : use i2c adapter <id>.\n");
- fprintf(stderr, "--l[ocation] <address> : use address <address>.\n");
- fprintf(stderr, "--s[pi]: use spi mode.\n");
- fprintf(stderr, "--u[nprotect] : remove flash write protect\n");
- fprintf(stderr, "--U[nprotect] : remove flash read protect\n");
- fprintf(stderr, "--e[rase] : erase all the flash content\n");
- fprintf(stderr, "--r[ead] <file> : read the flash content and "
- "write it into <file>\n");
- fprintf(stderr, "--s[pi] </dev/spi> : use SPI adapter on </dev>.\n");
- fprintf(stderr, "--w[rite] <file|-> : read <file> or\n\t"
- "standard input and write it to flash\n");
- fprintf(stderr, "--o[ffset] : offset to read/write/start from/to\n");
- fprintf(stderr, "--n[length] : amount to read/write\n");
- fprintf(stderr, "--g[o] : jump to execute flash entrypoint\n");
- fprintf(stderr, "--p[rogressbar] : use a progress bar instead of "
- "the spinner\n");
- fprintf(stderr, "-L[ogfile] <file> : save all communications exchange "
- "in a log file\n");
- fprintf(stderr, "-c[r50_mode] : consider device to be a Cr50 interface,"
- " no need to set UART port attributes\n");
- fprintf(stderr, "--v[ersion] : print version and exit\n");
-
- exit(2);
-}
-
-void display_version(const char *exe_name)
-{
- printf("%s version: %s %s %s\n", exe_name, CROS_STM32MON_VERSION, DATE,
- BUILDER);
-}
-
-speed_t parse_baudrate(const char *value)
-{
- int rate = atoi(value);
-
- switch (rate) {
- case 9600:
- return B9600;
- case 19200:
- return B19200;
- case 38400:
- return B38400;
- case 57600:
- return B57600;
- case 115200:
- return B115200;
- default:
- fprintf(stderr, "Invalid baudrate %s, using %d\n",
- value, DEFAULT_BAUDRATE);
- return DEFAULT_BAUDRATE;
- }
-}
-
-int parse_parameters(int argc, char **argv)
-{
- int opt, idx;
- int flags = 0;
- const char *log_file_name = NULL;
-
- while ((opt = getopt_long(argc, argv, "a:l:b:cd:eghL:n:o:pr:s:w:uUv?",
- longopts, &idx)) != -1) {
- switch (opt) {
- case 'a':
- i2c_adapter = atoi(optarg);
- mode = MODE_I2C;
- break;
- case 'l':
- i2c_slave_address = strtol(optarg, NULL, 0);
- break;
- case 'b':
- baudrate = parse_baudrate(optarg);
- break;
- case 'c':
- flags |= FLAG_CR50_MODE;
- break;
- case 'd':
- serial_port = optarg;
- mode = MODE_SERIAL;
- break;
- case 'e':
- flags |= FLAG_ERASE;
- break;
- case 'g':
- flags |= FLAG_GO;
- break;
- case 'h':
- case '?':
- display_usage(argv[0]);
- break;
- case 'L':
- log_file_name = optarg;
- break;
- case 'n':
- length = strtol(optarg, NULL, 0);
- break;
- case 'o':
- offset = strtol(optarg, NULL, 0);
- break;
- case 'p':
- use_progressbar = 1;
- break;
- case 'r':
- input_filename = optarg;
- break;
- case 's':
- spi_adapter = optarg;
- mode = MODE_SPI;
- break;
- case 'w':
- output_filename = optarg;
- break;
- case 'u':
- flags |= FLAG_UNPROTECT;
- break;
- case 'U':
- flags |= FLAG_READ_UNPROTECT;
- break;
- case 'v':
- display_version(argv[0]);
- exit(0);
- }
- }
-
- if (log_file_name) {
- log_file = fopen(log_file_name, "w");
- if (!log_file) {
- fprintf(stderr, "failed to open %s for writing\n",
- log_file_name);
- exit(2);
- }
- }
- return flags;
-}
-
-static void display_stat_response(void)
-{
- uint32_t total_events = MAX_EVENT_IDX;
- uint32_t idx;
-
- printf("--\n");
- for (idx = 0; idx < total_events; ++idx) {
- printf("%-18s %d\n", stat_resp[idx].event_name,
- stat_resp[idx].event_count);
- }
- printf("--\n");
-}
-
-int main(int argc, char **argv)
-{
- int ser;
- struct stm32_def *chip;
- int ret = STM32_EIO;
- int res;
- int flags;
- uint16_t flash_size_kbytes = 0;
- uint8_t unique_device_id[STM32_UNIQUE_ID_SIZE_BYTES] = { 0 };
- uint16_t package_data_reg = 0;
-
- /* Parse command line options */
- flags = parse_parameters(argc, argv);
-
- display_version(argv[0]);
-
- retry_on_damaged_ack = !!(flags & FLAG_CR50_MODE);
-
- switch (mode) {
- case MODE_SPI:
- ser = open_spi(spi_adapter);
- break;
- case MODE_I2C:
- ser = open_i2c(i2c_adapter);
- break;
- case MODE_SERIAL:
- default:
- /* Open the serial port tty */
- ser = open_serial(serial_port, !!(flags & FLAG_CR50_MODE));
- }
- if (ser < 0)
- return 1;
- /* Trigger embedded monitor detection */
- if (init_monitor(ser) < 0)
- goto terminate;
-
- chip = command_get_id(ser);
- if (!chip)
- goto terminate;
-
- /*
- * Use the actual size if we were able to read it since some chips
- * have the same chip ID, but different flash sizes based on the
- * package.
- */
- res = read_flash_size_register(ser, chip, &flash_size_kbytes);
- if (!IS_STM32_ERROR(res))
- chip->flash_size = flash_size_kbytes * KBYTES_TO_BYTES;
-
- /*
- * This is simply informative at the moment, so we don't care about the
- * return value.
- */
- (void)read_unique_device_id_register(ser, chip, unique_device_id);
-
- /*
- * This is simply informative at the moment, so we don't care about the
- * return value.
- */
- (void)read_package_data_register(ser, chip, &package_data_reg);
-
- if (command_get_commands(ser, chip) < 0)
- goto terminate;
-
- if (flags & FLAG_READ_UNPROTECT)
- command_read_unprotect(ser);
- if (flags & FLAG_UNPROTECT)
- command_write_unprotect(ser);
-
- if (flags & FLAG_ERASE || output_filename) {
- if ((!strncmp("STM32L15", chip->name, 8)) ||
- (!strncmp("STM32F411", chip->name, 9))) {
- /* Mass erase is not supported on these chips*/
- int i, page_count = chip->flash_size / chip->page_size;
- for (i = 0; i < page_count; i += 128) {
- int count = MIN(128, page_count - i);
- ret = erase(ser, count, i);
- if (IS_STM32_ERROR(ret))
- goto terminate;
- }
- } else {
- ret = erase(ser, 0xFFFF, 0);
- if (IS_STM32_ERROR(ret))
- goto terminate;
- }
- }
-
- if (input_filename) {
- ret = read_flash(ser, chip, input_filename, offset, length);
- if (IS_STM32_ERROR(ret))
- goto terminate;
- }
-
- if (output_filename) {
- ret = write_flash(ser, chip, output_filename, offset);
- if (IS_STM32_ERROR(ret))
- goto terminate;
- }
-
- /* Run the program from flash */
- if (flags & FLAG_GO)
- command_go(ser, offset);
-
- /* Normal exit */
- ret = STM32_SUCCESS;
-terminate:
- if (log_file)
- fclose(log_file);
-
- /* Close serial port */
- close(ser);
-
- if (retry_on_damaged_ack)
- display_stat_response();
-
- if (IS_STM32_ERROR(ret)) {
- fprintf(stderr, "Failed: %d\n", ret);
- return 1;
- }
-
- printf("Done.\n");
- return 0;
-}
diff --git a/util/tagbranch.sh b/util/tagbranch.sh
deleted file mode 100755
index 3e196b6f25..0000000000
--- a/util/tagbranch.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2017 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.
-#
-# Generate git strings for tagging EC branches.
-#
-# This script builds up on ideas put by vpalatin@ into util/getversion.sh
-#
-# Git allows to count number of patches between the current state of the tree
-# and any directly preceding tag in the tree. That is if we tag the first
-# patch in the current branch, we can tell how many patches are in the branch
-# above that tag. And if we tag the branch such that the tag string includes
-# the branch name, we can also say what branch we are in looking at the
-# closest tag in the tree.
-#
-# This admittedly brittle script automates the process of tagging for the EC
-# git tree in Chrome OS repo, but it could be used for any other Chrome OS
-# repo git tree just as well.
-#
-# The script is brittle because it relies on the following assumptions which
-# are true for Chrome OS repo at the time of writing:
-#
-# - the upstream branch alias name shows up in the 'git branch -a' output
-# separated by ->
-# - the upstream branch alias name has the format of
-# cros/<branch name>
-# - the remote git server name shows up in 'git config -l' output in the
-# line starting with "remote.cros.url="
-# - firmware branch names have format of firmware-<board>-XXXXXX
-# - the current branch was cut off of <remote name>/master
-#
-# The tag name generated by this script would be the XXXXX string with dots,
-# if any, replaced by underscores.
-
-# Retrieve the upstream branch alias name
-UPSTREAM="$(git branch -a | awk '/->/ {print $3}')"
-if [[ -z "${UPSTREAM}" ]]; then
- echo "Failed to determine upstream branch alias" >&2
- exit 1
-fi
-
-export ORIGIN_NAME="cros"
-ORIGIN="$(git config "remote.${ORIGIN_NAME}.url")"
-
-# The last common patch between this branch and the master.
-BRANCH_POINT="$(git merge-base "${UPSTREAM}" "${ORIGIN_NAME}/master")"
-if [[ -z "${BRANCH_POINT}" ]]; then
- echo "Failed to determine cros/master branch point" >&2
- exit 1
-fi
-
-# Derive tag base string from the upstream branch name as described above.
-TAG_BASE="$(sed 's/.*-// # drop everything up to including the last -
- s/\./_/g # replace dots and dashes with underscores
- ' <<< "${UPSTREAM}" )"
-
-if [[ "${TAG_BASE}" == "master" ]]; then
- echo "Nothing to tag in master branch" >&2
- exit 1
-fi
-
-TAG="v1.${TAG_BASE}.0"
-
-#SHA1 of the first patch of this branch
-BASE_SHA="$(git rev-list --ancestry-path "${BRANCH_POINT}".."${UPSTREAM}" |
- tail -1)"
-
-echo "Will run git tag -a -m \"firmware branch ${TAG}\" ${TAG} ${BASE_SHA}"
-if git tag -a -m "firmware branch ${TAG}" "${TAG}" "${BASE_SHA}"; then
- cat <<EOF
-
-A new tag '$TAG' has been set. Use the following command
-to push it to the server
-
-git push --tags ${ORIGIN} ${TAG}
-
-Or if you want to delete it:
-
-git tag -d $TAG
-
-EOF
-fi
diff --git a/util/temp_metrics.conf b/util/temp_metrics.conf
deleted file mode 100644
index ccd3254beb..0000000000
--- a/util/temp_metrics.conf
+++ /dev/null
@@ -1,396 +0,0 @@
-# Copyright 2012 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.
-
-description "Temporary, quick-hack metrics collection & thermal daemon"
-author "chromium-os-dev@chromium.org"
-
-# This is for quickly adding UMA stats that we may need for
-# short-term experiments, when we don't have the time to add
-# stuff to metrics_daemon. That's where it should go in the
-# long term.
-#
-# This is also currently doing a userland thermal loop to allow
-# for quick experimentation. This thermal loop will eventually
-# move to the BIOS once the data from experiments help prove its
-# efficacy.
-
-start on started system-services
-stop on stopping system-services
-respawn
-
-script
- TEMP_OFFSET=273 # difference between K (reported by EC) and C (used in UMA)
-
- # Thermal loop fields
- CPU_MAX_FREQ_FIELD=1
- CPU_MIN_FREQ_FIELD=2
- GPU_MAX_FREQ_FIELD=3
- CPU_DUTY_CYCLE_FIELD=4
- PKG_POWER_LIMIT_FIELD=5
-
- # Thermal loop steps
- all_steps="
- 1801000 800000 1150 0 0x180aa00dd8088 # no throttling
- 1801000 800000 1150 0 0x180aa00dd8080 # cap pkg to 16W
- 1801000 800000 1150 0 0x180aa00dd8078 # cap pkg to 15W
- 1801000 800000 1150 0 0x180aa00dd8070 # cap pkg to 14W
- 1801000 800000 1150 0 0x180aa00dd8068 # cap pkg to 13W
- 1800000 800000 900 0 0x180aa00dd8068 # disable turbo
- 1600000 800000 800 0 0x180aa00dd8068 # cap CPU & GPU frequency
- 1400000 800000 700 0 0x180aa00dd8068 # cap CPU & GPU frequency
- 1200000 800000 600 0 0x180aa00dd8068 # cap CPU & GPU frequency
- 1000000 800000 500 0 0x180aa00dd8068 # cap CPU & GPU frequency
- 800000 800000 400 0 0x180aa00dd8068 # cap CPU & GPU frequency
- 800000 800000 350 0 0x180aa00dd8068 # cap CPU & GPU frequency
- 800000 800000 350 0x1c 0x180aa00dd8068 # duty cycle CPU
- 800000 800000 350 0x18 0x180aa00dd8068 # duty cycle CPU
- "
- max_steps=$(($(echo "$all_steps" | wc -l) - 3))
-
- get_step() {
- row=$(($1 + 2))
- out=$(echo "$all_steps" | awk "{if (NR==$row) print}")
- echo "$out"
- }
-
- get_field() {
- out=$(echo "$2" | awk "{print \$$1}")
- echo $out
- }
-
- get_peci_temp() {
- tempk=$(ectool temps 9 | sed 's/[^0-9]//g')
- tempc=$((tempk - $TEMP_OFFSET))
- echo $tempc
- }
-
- get_sensor_temp() {
- s=$1
- tempc=0
- if out=$(ectool temps $s); then
- tempk=$(echo $out | sed 's/[^0-9]//g')
- tempc=$((tempk - $TEMP_OFFSET))
- fi
- echo $tempc
- }
-
- get_sensor_list() {
- # USB C-Object: 1 or 13
- # PCH D-Object: 3
- # Hinge C-Object: 5 or 15
- # Charger D-Object: 7
- if ectool tempsinfo 1 | grep -q "USB C-Object"; then
- usb_c_object=1
- else
- usb_c_object=13
- fi
- charger_d_object=7
- echo $usb_c_object $charger_d_object
- }
-
- set_calibration_data() {
- B0='-2.94e-5'
- B1='-5.7e-7'
- B2='4.63e-9'
-
- USB_C_S0='2.712e-14'
- PCH_D_S0='9.301e-14'
- HINGE_C_S0='-11.000e-14'
- CHARGER_D_S0='5.141e-14'
-
- # Note that the sensor numbering is different between the ectool tmp006
- # and temps/tempsinfo commands.
- USB_C="0 $USB_C_S0 $B0 $B1 $B2"
- PCH_D="1 $PCH_D_S0 $B0 $B1 $B2"
- HINGE_C="2 $HINGE_C_S0 $B0 $B1 $B2"
- CHARGER_D="3 $CHARGER_D_S0 $B0 $B1 $B2"
-
- for i in "$USB_C" "$PCH_D" "$HINGE_C" "$CHARGER_D"; do
- # Add "--" otherwise ectool will barf when trying to parse negative
- # coefficients.
- ectool tmp006cal -- $i
- done
- }
-
- max_skin_temp=0
- sensor_temperatures=
-
- get_max_skin_temp() {
- sensor_temperatures=
- max_skin_temp=0
- for i in $*; do
- t=$(get_sensor_temp $i)
- sensor_temperatures=$sensor_temperatures$i:$t:
- if [ $t -gt $max_skin_temp ]; then
- max_skin_temp=$t
- fi
- done
-
- # Record the PECI CPU temperature also.
- i=9
- t=$(get_sensor_temp $i)
- sensor_temperatures=$sensor_temperatures$i:$t:
- }
-
- set_cpu_freq() {
- max_freq=$1
- min_freq=$2
- for cpu in /sys/devices/system/cpu/cpu?/cpufreq; do
- echo 800000 > $cpu/scaling_min_freq
- echo 800000 > $cpu/scaling_max_freq
- echo $max_freq > $cpu/scaling_max_freq
- echo $min_freq > $cpu/scaling_min_freq
- done
- }
-
- set_gpu_min_freq() {
- GPU_MIN_FREQ=450
- echo $GPU_MIN_FREQ > /sys/kernel/debug/dri/0/i915_min_freq
- }
-
- set_gpu_max_freq() {
- gpu_max_freq=$1
- if [ $GPU_MIN_FREQ -gt $gpu_max_freq ]; then
- gpu_max_freq=$GPU_MIN_FREQ
- fi
- echo $gpu_max_freq > /sys/kernel/debug/dri/0/i915_max_freq
- }
-
- set_duty_cycle() {
- duty_cycle=$1
- for i in 0 1 2 3; do
- iotools wrmsr $i 0x19a $duty_cycle
- done
- }
-
- set_pkg_power_limit() {
- pwr_limit=$1
- iotools wrmsr 0 0x610 $pwr_limit
- }
-
- log_message() {
- logger -t temp_metrics "$*"
- }
-
- TEMP_THRESHOLD_1=38
- TEMP_THRESHOLD_1_WM=40
- TEMP_THRESHOLD_2=45
- TEMP_THRESHOLD_2_WM=47
- TEMP_THRESHOLD_3=50
- TEMP_THRESHOLD_3_WM=50
-
- TEMP_THRESHOLD_0_MIN_STEP=0
- TEMP_THRESHOLD_0_MAX_STEP=0
- TEMP_THRESHOLD_1_MIN_STEP=1
- TEMP_THRESHOLD_1_MAX_STEP=5
- TEMP_THRESHOLD_2_MIN_STEP=6
- TEMP_THRESHOLD_2_MAX_STEP=9
- TEMP_THRESHOLD_3_MIN_STEP=10
- TEMP_THRESHOLD_3_MAX_STEP=13
-
- current_step=1
- new_step=0
-
- thermal_loop() {
- # Hack to reset turbo activation threshold since BIOS can change it
- # underneath us.
- iotools wrmsr 0 0x64c 0x12
-
- skin_temp=$1
- if [ $skin_temp -gt $TEMP_THRESHOLD_3 ]; then
- temp_watermark=$TEMP_THRESHOLD_3_WM
- min_step=$TEMP_THRESHOLD_3_MIN_STEP
- max_step=$TEMP_THRESHOLD_3_MAX_STEP
- elif [ $skin_temp -gt $TEMP_THRESHOLD_2 ]; then
- temp_watermark=$TEMP_THRESHOLD_2_WM
- min_step=$TEMP_THRESHOLD_2_MIN_STEP
- max_step=$TEMP_THRESHOLD_2_MAX_STEP
- elif [ $skin_temp -gt $TEMP_THRESHOLD_1 ]; then
- temp_watermark=$TEMP_THRESHOLD_1_WM
- min_step=$TEMP_THRESHOLD_1_MIN_STEP
- max_step=$TEMP_THRESHOLD_1_MAX_STEP
- else
- temp_watermark=0
- min_step=$TEMP_THRESHOLD_0_MIN_STEP
- max_step=$TEMP_THRESHOLD_0_MAX_STEP
- fi
-
- if [ $skin_temp -gt $temp_watermark ]; then
- if [ $current_step -ne $max_step ]; then
- new_step=$(($current_step + 1))
- fi
- elif [ $skin_temp -lt $temp_watermark ]; then
- if [ $current_step -gt $min_step ]; then
- new_step=$(($current_step - 1))
- fi
- else
- new_step=$current_step
- fi
-
- if [ $new_step -gt $max_step ]; then
- new_step=$max_step
- elif [ $new_step -lt $min_step ]; then
- new_step=$min_step
- fi
-
- if [ $new_step -eq $current_step ]; then
- return
- fi
-
- current_step=$new_step
- step=$(get_step $new_step)
-
- log_message "Throttling (temps: $sensor_temperatures):" $step
-
- cpu_max_freq=$(get_field $CPU_MAX_FREQ_FIELD "$step")
- cpu_min_freq=$(get_field $CPU_MIN_FREQ_FIELD "$step")
- gpu_max_freq=$(get_field $GPU_MAX_FREQ_FIELD "$step")
- cpu_duty_cycle=$(get_field $CPU_DUTY_CYCLE_FIELD "$step")
- pkg_power_limit=$(get_field $PKG_POWER_LIMIT_FIELD "$step")
-
- set_cpu_freq $cpu_max_freq $cpu_min_freq
- set_gpu_max_freq $gpu_max_freq
- set_duty_cycle $cpu_duty_cycle
- set_pkg_power_limit $pkg_power_limit
- }
-
- get_fan_rpm() {
- echo $(ectool pwmgetfanrpm | sed 's/[^0-9]//g')
- }
-
- set_fan_rpm() {
- ectool pwmsetfanrpm $1
- }
-
- reset_fan_thresholds() {
- temp_low1=105
- temp_low2=105
- temp_low3=105
- temp_low4=105
- temp_low5=105
- temp_low6=105
- }
-
- last_rpm=10
- temp_low1=105
- temp_low2=105
- temp_low3=105
- temp_low4=105
- temp_low5=105
- temp_low6=105
-
- fan_loop() {
- skin_temp=$1
-
- if [ $skin_temp -gt 48 ] || [ $skin_temp -gt $temp_low1 ]; then
- rpm=9300
- reset_fan_thresholds
- temp_low1=46
- elif [ $skin_temp -gt 44 ] || [ $skin_temp -gt $temp_low2 ]; then
- rpm=8000
- reset_fan_thresholds
- temp_low2=43
- elif [ $skin_temp -gt 42 ] || [ $skin_temp -gt $temp_low3 ]; then
- rpm=7000
- reset_fan_thresholds
- temp_low3=41
- elif [ $skin_temp -gt 40 ] || [ $skin_temp -gt $temp_low4 ]; then
- rpm=5500
- reset_fan_thresholds
- temp_low4=39
- elif [ $skin_temp -gt 38 ] || [ $skin_temp -gt $temp_low5 ]; then
- rpm=4000
- reset_fan_thresholds
- temp_low5=34
- elif [ $skin_temp -gt 33 ] || [ $skin_temp -gt $temp_low6 ]; then
- rpm=3000
- reset_fan_thresholds
- temp_low6=30
- else
- rpm=0
- reset_fan_thresholds
- fi
-
- # During S0->S3->S0 transitions, the EC sets the fan RPM to 0. This script
- # isn't aware of such transitions. Read the current fan RPM again to see
- # if it got set to 0. Note that comparing the current fan RPM against last
- # requested RPM won't suffice since the actual fan RPM may not be exactly
- # what was requested.
- cur_rpm=$(get_fan_rpm)
- if ([ $cur_rpm -ne 0 ] && [ $last_rpm -eq $rpm ]) || \
- ([ $cur_rpm -eq 0 ] && [ $rpm -eq 0 ]); then
- last_rpm=$rpm
- return
- fi
-
- log_message "Setting fan RPM (temps: $sensor_temperatures): $last_rpm -> $rpm"
-
- last_rpm=$rpm
- set_fan_rpm $rpm
- }
-
- # Thermal zone 1 is for operating systems where a userland thermal loop
- # doesn't exist. Disable it.
- if [ -e /sys/class/thermal/thermal_zone1/mode ]; then
- echo -n 'disabled' > /sys/class/thermal/thermal_zone1/mode
- fi
-
- # Enable the fan in case no other code has enabled it.
- ectool fanduty 0
-
- # Get list of sensors to monitor.
- sensor_list=$(get_sensor_list)
-
- # Set sensor calibration data.
- set_calibration_data
-
- # Set minimum GPU frequency.
- set_gpu_min_freq
-
- loop_count=0
- ec_fan_loop=0
-
- while true; do
- sleep 10
- loop_count=$(($loop_count + 1))
-
- # Read the max skin temperature.
- get_max_skin_temp $sensor_list
-
- if [ $max_skin_temp -eq 0 ]; then
- if [ $ec_fan_loop -eq 0 ]; then
- log_message "Invalid max skin temp. Switching to EC fan loop."
- ectool autofanctrl
- ec_fan_loop=1
- last_rpm=10
- fi
- else
- # Run the fan loop.
- fan_loop $max_skin_temp
- ec_fan_loop=0
-
- # Run the thermal loop.
- thermal_loop $max_skin_temp
- fi
-
- # Report the metrics once every 30 seconds.
- if [ $loop_count -lt 3 ]; then
- continue
- fi
- loop_count=0
-
- ectool temps all | while read line; do
- index=$(printf "%02d" "${line%%:*}")
- tempk="${line##* }"
- tempc=$(($tempk - $TEMP_OFFSET))
- # ignore values below freezing
- if [ $tempc -lt 0 ]; then
- tempc=0
- fi
- # Use a linear histogram with 1 C buckets starting at 0.
- N_SLOTS=180
- metrics_client -e Platform.Temperature.Sensor$index $tempc $N_SLOTS
- done
- done
-end script
diff --git a/util/test-inject-keys.sh b/util/test-inject-keys.sh
deleted file mode 100755
index 031452150e..0000000000
--- a/util/test-inject-keys.sh
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2016 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.
-
-# Regression test for inject-keys.py. Works by creating a "fake" ectool
-# and comparing expected ectool commands with expected ones.
-
-TMPX=/tmp/inject-key-test$$_x
-TMPY=/tmp/inject-key-test$$_y
-
-cleanup() {
- rm -f ./ectool $TMPX $TMPY
-}
-
-fail() {
- echo $*
- exit 1
-}
-
-trap cleanup SIGINT
-
-PATH=.:$PATH
-
-if [ -e ectool ]; then
- if [ "$(echo $(cat ectool))" != '#! /bin/bash echo $*' ]; then
- echo "./ectool exists, please remove it to run this script"
- exit 1
- fi
-fi
-
-echo "#! /bin/bash" > ectool
-echo 'echo $*' >> ectool
-chmod a+x ectool
-
-# tests that should fail
-
-# bad args
-./inject-keys.py >& /dev/null && fail "undetected zero args"
-./inject-keys.py -k >& /dev/null && fail "undetected mismatched args (1)"
-./inject-keys.py -k a b >& /dev/null && fail "undetected mismatched args (2)"
-./inject-keys.py -z a >& /dev/null && fail "undetected bad flag"
-
-# bad key
-./inject-keys.py -p foobar >& /dev/null && fail "undetected bad key"
-
-# tests that should succeed with the expected output
-
-# simple string
-./inject-keys.py -s abcd > $TMPX
-
-cat > $TMPY <<EOF
-kbpress 4 1 1
-kbpress 4 1 0
-kbpress 0 3 1
-kbpress 0 3 0
-kbpress 5 2 1
-kbpress 5 2 0
-kbpress 4 2 1
-kbpress 4 2 0
-EOF
-
-cmp $TMPX $TMPY || fail $TMPX and $TMPY differ
-
-# string with shifted characters
-./inject-keys.py -s A@%Bx > $TMPX
-
-cat > $TMPY <<EOF
-kbpress 5 7 1
-kbpress 4 1 1
-kbpress 4 1 0
-kbpress 5 7 0
-kbpress 5 7 1
-kbpress 6 4 1
-kbpress 6 4 0
-kbpress 5 7 0
-kbpress 5 7 1
-kbpress 3 3 1
-kbpress 3 3 0
-kbpress 5 7 0
-kbpress 5 7 1
-kbpress 0 3 1
-kbpress 0 3 0
-kbpress 5 7 0
-kbpress 5 4 1
-kbpress 5 4 0
-EOF
-
-cmp $TMPX $TMPY || fail $TMPX and $TMPY differ
-
-# keystroke injection
-./inject-keys.py -k enter > $TMPX
-
-cat > $TMPY <<EOF
-kbpress 4 11 1
-kbpress 4 11 0
-EOF
-
-cmp $TMPX $TMPY || fail $TMPX and $TMPY differ
-
-# key event injection
-./inject-keys.py -p enter > $TMPX
-
-cat > $TMPY <<EOF
-kbpress 4 11 1
-EOF
-
-cmp $TMPX $TMPY || fail $TMPX and $TMPY differ
-
-cleanup
diff --git a/util/uart_stress_tester.py b/util/uart_stress_tester.py
deleted file mode 100755
index e2f9f278fe..0000000000
--- a/util/uart_stress_tester.py
+++ /dev/null
@@ -1,540 +0,0 @@
-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
-# Copyright 2019 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.
-
-"""ChromeOS Uart Stress Test
-
-This tester runs the command 'chargen' on EC and/or AP, captures the
-output, and compares it against the expected output to check any characters
-lost.
-
-Prerequisite:
- (1) This test needs PySerial. Please check if it is available before test.
- Can be installed by 'pip install pyserial'
- (2) If servod is running, turn uart_timestamp off before running this test.
- e.g. dut-control cr50_uart_timestamp:off
-"""
-
-from __future__ import print_function
-from chromite.lib import cros_logging as logging
-
-import argparse
-import atexit
-import serial
-import os
-import stat
-import sys
-import threading
-import time
-
-
-BAUDRATE = 115200 # Default baudrate setting for UART port
-CROS_USERNAME = 'root' # Account name to login to ChromeOS
-CROS_PASSWORD = 'test0000' # Password to login to ChromeOS
-CHARGEN_TXT = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
- # The result of 'chargen 62 62'
-CHARGEN_TXT_LEN = len(CHARGEN_TXT)
-CR = '\r' # Carriage Return
-LF = '\n' # Line Feed
-CRLF = CR + LF
-FLAG_FILENAME = '/tmp/chargen_testing'
-TPM_CMD = ('trunks_client --key_create --rsa=2048 --usage=sign'
- ' --key_blob=/tmp/blob &> /dev/null')
- # A ChromeOS TPM command for the cr50 stress
- # purpose.
-CR50_LOAD_GEN_CMD = ('while [[ -f %s ]]; do %s; done &'
- % (FLAG_FILENAME, TPM_CMD))
- # A command line to run TPM_CMD in background
- # infinitely.
-
-
-class ChargenTestError(Exception):
- """Exception for Uart Stress Test Error"""
- pass
-
-
-class UartSerial(object):
- """Test Object for a single UART serial device
-
- Attributes
- UART_DEV_PROFILES
- """
- UART_DEV_PROFILES = (
- # Kernel
- {
- 'prompt':'localhost login:',
- 'device_type':'AP',
- 'prepare_cmd':[
- CROS_USERNAME, # Login
- CROS_PASSWORD, # Password
- 'dmesg -D', # Disable console message
- 'touch ' + FLAG_FILENAME, # Create a temp file
- ],
- 'cleanup_cmd':[
- 'rm -f ' + FLAG_FILENAME, # Remove the temp file
- 'dmesg -E', # Enable console message
- 'logout', # Logout
- ],
- 'end_of_input':LF,
- },
- # EC
- {
- 'prompt':'> ',
- 'device_type':'EC',
- 'prepare_cmd':[
- 'chan save',
- 'chan 0' # Disable console message
- ],
- 'cleanup_cmd':['', 'chan restore'],
- 'end_of_input':CRLF,
- },
- )
-
- def __init__(self, port, duration, timeout=1,
- baudrate=BAUDRATE, cr50_workload=False):
- """Initialize UartSerial
-
- Args:
- port: UART device path. e.g. /dev/ttyUSB0
- duration: Time to test, in seconds
- timeout: Read timeout value.
- baudrate: Baud rate such as 9600 or 115200.
- cr50_workload: True if a workload should be generated on cr50
-
- Attributes:
- char_loss_occurrences: Number that character loss happens
- cleanup_cli: Command list to perform before the test exits
- cr50_workload: True if cr50 should be stressed, or False otherwise
- dev_prof: Dictionary of device profile
- duration: Time to keep chargen running
- eol: Characters to add at the end of input
- logger: object that store the log
- num_ch_exp: Expected number of characters in output
- num_ch_cap: Number of captured characters in output
- test_cli: Command list to run for chargen test
- test_thread: Thread object that captures the UART output
- serial: serial.Serial object
- """
-
- # Initialize serial object
- self.serial = serial.Serial()
- self.serial.port = port
- self.serial.timeout = timeout
- self.serial.baudrate = baudrate
-
- self.duration = duration
- self.cr50_workload = cr50_workload
-
- self.logger = logging.getLogger(type(self).__name__ + '| ' + port)
- self.test_thread = threading.Thread(target=self.stress_test_thread)
-
- self.dev_prof = {}
- self.cleanup_cli = []
- self.test_cli = []
- self.eol = CRLF
- self.num_ch_exp = 0
- self.num_ch_cap = 0
- self.char_loss_occurrences = 0
- atexit.register(self.cleanup)
-
- def run_command(self, command_lines, delay=0):
- """Run command(s) at UART prompt
-
- Args:
- command_lines: list of commands to run.
- delay: delay after a command in second
- """
- for cli in command_lines:
- self.logger.debug('run %r', cli)
-
- self.serial.write(cli + self.eol)
- self.serial.flush()
- if delay:
- time.sleep(delay)
-
- def cleanup(self):
- """Before termination, clean up the UART device."""
- self.logger.debug('Closing...')
-
- self.serial.open()
- self.run_command(self.cleanup_cli) # Run cleanup commands
- self.serial.close()
-
- self.logger.debug('Cleanup done')
-
- def get_output(self):
- """Capture the UART output
-
- Args:
- stop_char: Read output buffer until it reads stop_char.
-
- Returns:
- text from UART output.
- """
- if self.serial.inWaiting() == 0:
- time.sleep(1)
-
- return self.serial.read(self.serial.inWaiting())
-
- def prepare(self):
- """Prepare the test:
-
- Identify the type of UART device (EC or Kernel?), then
- decide what kind of commands to use to generate stress loads.
-
- Raises:
- ChargenTestError if UART source can't be identified.
- """
- try:
- self.logger.info('Preparing...')
-
- self.serial.open()
-
- # Prepare the device for test
- self.serial.flushInput()
- self.serial.flushOutput()
-
- self.get_output() # drain data
-
- # Give a couple of line feeds, and capture the prompt text
- self.run_command(['', ''])
- prompt_txt = self.get_output()
-
- # Detect the device source: EC or AP?
- # Detect if the device is AP or EC console based on the captured.
- for dev_prof in self.UART_DEV_PROFILES:
- if dev_prof['prompt'] in prompt_txt:
- self.dev_prof = dev_prof
- break
- else:
- # No prompt patterns were found. UART seems not responding or in
- # an undesirable status.
- if prompt_txt:
- raise ChargenTestError('%s: Got an unknown prompt text: %s\n'
- 'Check manually whether %s is available.' %
- (self.serial.port, prompt_txt,
- self.serial.port))
- else:
- raise ChargenTestError('%s: Got no input. Close any other connections'
- ' to this port, and try it again.' %
- self.serial.port)
-
- self.logger.info('Detected as %s UART', self.dev_prof['device_type'])
- # Log displays the UART type (AP|EC) instead of device filename.
- self.logger = logging.getLogger(type(self).__name__ + '| ' +
- self.dev_prof['device_type'])
-
- # Either login to AP or run some commands to prepare the device
- # for test
- self.eol = self.dev_prof['end_of_input']
- self.run_command(self.dev_prof['prepare_cmd'], delay=2)
- self.cleanup_cli += self.dev_prof['cleanup_cmd']
-
- # Check whether the command 'chargen' is available in the device.
- # 'chargen 1 4' is supposed to print '0000'
- self.get_output() # drain data
- self.run_command(['chargen 1 4'])
- tmp_txt = self.get_output()
-
- # Check whether chargen command is available.
- if '0000' not in tmp_txt:
- raise ChargenTestError('%s: Chargen got an unexpected result: %s' %
- (self.dev_prof['device_type'], tmp_txt))
-
- self.num_ch_exp = int(self.serial.baudrate * self.duration / 10)
- self.test_cli = ['chargen %d %d' % (CHARGEN_TXT_LEN, self.num_ch_exp)]
-
- self.logger.info('Ready to test')
- finally:
- self.serial.close()
-
- def stress_test_thread(self):
- """Test thread
-
- Raises:
- ChargenTestError: if broken character is found.
- """
- try:
- self.serial.open()
- self.serial.flushInput()
- self.serial.flushOutput()
-
- # Run TPM command in background to burden cr50.
- if self.dev_prof['device_type'] == 'AP' and self.cr50_workload:
- self.run_command([CR50_LOAD_GEN_CMD])
- self.logger.debug('run TPM job while %s exists', FLAG_FILENAME)
-
- # Run the command 'chargen', one time
- self.get_output() # Drain the output
- self.run_command(self.test_cli)
- self.serial.readline() # Drain the echoed command line.
-
- err_msg = '%s: Expected %r but got %s after %d char received'
-
- # Keep capturing the output until the test timer is expired.
- self.num_ch_cap = 0
- self.char_loss_occurrences = 0
- data_starve_count = 0
-
- total_num_ch = self.num_ch_exp # Expected number of characters in total
- ch_exp = CHARGEN_TXT[0]
- ch_cap = 'z' # any character value is ok for loop initial condition.
- while self.num_ch_cap < total_num_ch:
- captured = self.get_output()
-
- if captured:
- # There is some output data. Reset the data starvation count.
- data_starve_count = 0
- else:
- data_starve_count += 1
- if data_starve_count > 1:
- # If nothing was captured more than once, then terminate the test.
- self.logger.debug('No more output')
- break
-
- for ch_cap in captured:
- if ch_cap not in CHARGEN_TXT:
- # If it is not alpha-numeric, terminate the test.
- if ch_cap not in CRLF:
- # If it is neither a CR nor LF, then it is an error case.
- self.logger.error('Whole captured characters: %r', captured)
- raise ChargenTestError(err_msg % ('Broken char captured', ch_exp,
- hex(ord(ch_cap)),
- self.num_ch_cap))
-
- # Set the loop termination condition true.
- total_num_ch = self.num_ch_cap
-
- if self.num_ch_cap >= total_num_ch:
- break
-
- if ch_exp != ch_cap:
- # If it is alpha-numeric but not continuous, then some characters
- # are lost.
- self.logger.error(err_msg, 'Char loss detected',
- ch_exp, repr(ch_cap), self.num_ch_cap)
- self.char_loss_occurrences += 1
-
- # Recalculate the expected number of characters to adjust
- # termination condition. The loss might be bigger than this
- # adjustment, but it is okay since it will terminates by either
- # CR/LF detection or by data starvation.
- idx_ch_exp = CHARGEN_TXT.find(ch_exp)
- idx_ch_cap = CHARGEN_TXT.find(ch_cap)
- if idx_ch_cap < idx_ch_exp:
- idx_ch_cap += len(CHARGEN_TXT)
- total_num_ch -= (idx_ch_cap - idx_ch_exp)
-
- self.num_ch_cap += 1
-
- # Determine What character is expected next?
- ch_exp = CHARGEN_TXT[(CHARGEN_TXT.find(ch_cap) + 1) % CHARGEN_TXT_LEN]
-
- finally:
- self.serial.close()
-
- def start_test(self):
- """Start the test thread"""
- self.logger.info('Test thread starts')
- self.test_thread.start()
-
- def wait_test_done(self):
- """Wait until the test thread get done and join"""
- self.test_thread.join()
- self.logger.info('Test thread is done')
-
- def get_result(self):
- """Display the result
-
- Returns:
- Integer = the number of lost character
-
- Raises:
- ChargenTestError: if the capture is corrupted.
- """
- # If more characters than expected are captured, it means some messages
- # from other than chargen are mixed. Stop processing further.
- if self.num_ch_exp < self.num_ch_cap:
- raise ChargenTestError('%s: UART output is corrupted.' %
- self.dev_prof['device_type'])
-
- # Get the count difference between the expected to the captured
- # as the number of lost character.
- char_lost = self.num_ch_exp - self.num_ch_cap
- self.logger.info('%8d char lost / %10d (%.1f %%)',
- char_lost, self.num_ch_exp,
- char_lost * 100.0 / self.num_ch_exp)
-
- return char_lost, self.num_ch_exp, self.char_loss_occurrences
-
-
-class ChargenTest(object):
- """UART stress tester
-
- Attributes:
- cr50_workload: True if cr50 should be stressed, or False otherwise
- duration: Time to keep testing in seconds
- logger: logging object
- ports: List of Uart device filename
- serials: Dictionary where key is filename of UART device, and the value is
- UartSerial object
- """
-
- def __init__(self, ports, duration, cr50_workload=False):
- """Initialize UART stress tester
-
- Args:
- ports: List of UART ports to test.
- duration: Time to keep testing in seconds.
- cr50_workload: True if a workload should be generated on cr50
-
- Raises:
- ChargenTestError: if any of ports is not a valid character device.
- """
-
- # Save the arguments
- self.ports = ports
- for port in ports:
- try:
- mode = os.stat(port).st_mode
- except OSError as e:
- raise ChargenTestError(e)
- if not stat.S_ISCHR(mode):
- raise ChargenTestError('%s is not a character device.' % port)
-
- if duration <= 0:
- raise ChargenTestError('Input error: duration is not positive.')
- self.duration = duration
-
- self.cr50_workload = cr50_workload
-
- # Initialize logging object
- self.logger = logging.getLogger(type(self).__name__)
-
- # Create an UartSerial object per UART port
- self.serials = {} # UartSerial objects
- for port in self.ports:
- self.serials[port] = UartSerial(port=port, duration=self.duration,
- cr50_workload=self.cr50_workload)
-
- def prepare(self):
- """Prepare the test for each UART port"""
- self.logger.info('Prepare ports for test')
- for _, ser in self.serials.items():
- ser.prepare()
- self.logger.info('Ports are ready to test')
-
- def print_result(self):
- """Display the test result for each UART port
-
- Returns:
- char_lost: Total number of characters lost
- """
- char_lost = 0
- for _, ser in self.serials.items():
- (tmp_lost, _, _) = ser.get_result()
- char_lost += tmp_lost
-
- # If any characters are lost, then test fails.
- msg = 'lost %d character(s) from the test' % char_lost
- if char_lost > 0:
- self.logger.error('FAIL: %s', msg)
- else:
- self.logger.info('PASS: %s', msg)
-
- return char_lost
-
- def run(self):
- """Run the stress test on UART port(s)
-
- Raises:
- ChargenTestError: If any characters are lost.
- """
-
- # Detect UART source type, and decide which command to test.
- self.prepare()
-
- # Run the test on each UART port in thread.
- self.logger.info('Test starts')
- for _, ser in self.serials.items():
- ser.start_test()
-
- # Wait all tests to finish.
- for _, ser in self.serials.items():
- ser.wait_test_done()
-
- # Print the result.
- char_lost = self.print_result()
- if char_lost:
- raise ChargenTestError('Test failed: lost %d character(s)' %
- char_lost)
-
- self.logger.info('Test is done')
-
-def parse_args(cmdline):
- """Parse command line arguments.
-
- Args:
- cmdline: list to be parsed
-
- Returns:
- tuple (options, args) where args is a list of cmdline arguments that the
- parser was unable to match i.e. they're servod controls, not options.
- """
- description = """%(prog)s repeats sending a uart console command
-to each UART device for a given time, and check if output
-has any missing characters.
-
-Examples:
- %(prog)s /dev/ttyUSB2 --time 3600
- %(prog)s /dev/ttyUSB1 /dev/ttyUSB2 --debug
- %(prog)s /dev/ttyUSB1 /dev/ttyUSB2 --cr50
-"""
-
- parser = argparse.ArgumentParser(description=description,
- formatter_class=argparse.RawTextHelpFormatter
- )
- parser.add_argument('port', type=str, nargs="*",
- help='UART device path to test')
- parser.add_argument('-c', '--cr50', action='store_true', default=False,
- help='generate TPM workload on cr50')
- parser.add_argument('-d', '--debug', action='store_true', default=False,
- help='enable debug messages')
- parser.add_argument('-t', '--time', type=int,
- help='Test duration in second', default=300)
- return parser.parse_known_args(cmdline)
-
-
-def main():
- """Main function wrapper"""
- try:
- (options, _) = parse_args(sys.argv[1:])
-
- # Set Log format
- log_format = '%(asctime)s %(levelname)-6s | %(name)-25s'
- date_format = '%Y-%m-%d %H:%M:%S'
- if options.debug:
- log_format += ' | %(filename)s:%(lineno)4d:%(funcName)-18s'
- loglevel = logging.DEBUG
- else:
- loglevel = logging.INFO
- log_format += ' | %(message)s'
-
- logging.basicConfig(level=loglevel, format=log_format,
- datefmt=date_format)
-
- # Create a ChargenTest object
- utest = ChargenTest(options.port, options.time, options.cr50)
- utest.run() # Run
-
- except KeyboardInterrupt:
- sys.exit(0)
-
- except ChargenTestError as e:
- logging.error(str(e))
- sys.exit(1)
-
-if __name__ == '__main__':
- main()
diff --git a/util/unpack_ftb.py b/util/unpack_ftb.py
deleted file mode 100755
index 105f7044ec..0000000000
--- a/util/unpack_ftb.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python2
-# Copyright 2018 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.
-
-from __future__ import print_function
-import argparse
-import ctypes
-import os
-
-
-class Header(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ('signature', ctypes.c_uint32),
- ('ftb_ver', ctypes.c_uint32),
- ('chip_id', ctypes.c_uint32),
- ('svn_ver', ctypes.c_uint32),
- ('fw_ver', ctypes.c_uint32),
- ('config_id', ctypes.c_uint32),
- ('config_ver', ctypes.c_uint32),
- ('reserved', ctypes.c_uint8 * 8),
- ('release_info', ctypes.c_ulonglong),
- ('sec_size', ctypes.c_uint32 * 4),
- ('crc', ctypes.c_uint32),
- ]
-
-FW_HEADER_SIZE = 64
-FW_HEADER_SIGNATURE = 0xAA55AA55
-FW_FTB_VER = 0x00000001
-FW_CHIP_ID = 0x3936
-FW_BYTES_ALIGN = 4
-FW_BIN_VER_OFFSET = 16
-FW_BIN_CONFIG_ID_OFFSET = 20
-
-# Starting address in flash for each section
-FLASH_SEC_ADDR = [
- 0x0000 * 4, # CODE
- 0x7C00 * 4, # CONFIG
- 0x7000 * 4, # CX
- None # This section shouldn't exist
-]
-
-UPDATE_PDU_SIZE = 4096
-
-# Bin file format:
-# FTB header (padded to `UPDATE_PDU_SIZE`)
-# Flash sections
-# CODE
-# CX
-# CONFIG
-OUTPUT_FILE_SIZE = UPDATE_PDU_SIZE + 128 * 1024
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('--input', '-i', required=True)
- parser.add_argument('--output', '-o', required=True)
- args = parser.parse_args()
-
- with open(args.input) as f:
- bs = f.read()
-
- size = len(bs)
- if size < FW_HEADER_SIZE + FW_BYTES_ALIGN:
- raise Exception('FW size too small')
-
- print('FTB file size:', size)
-
- header = Header()
- assert ctypes.sizeof(header) == FW_HEADER_SIZE
-
- ctypes.memmove(ctypes.addressof(header), bs, ctypes.sizeof(header))
- if (header.signature != FW_HEADER_SIGNATURE or
- header.ftb_ver != FW_FTB_VER or
- header.chip_id != FW_CHIP_ID):
- raise Exception('Invalid header')
-
- for key, _ in header._fields_:
- v = getattr(header, key)
- if isinstance(v, ctypes.Array):
- print(key, map(hex, v))
- else:
- print(key, hex(v))
-
- dimension = sum(header.sec_size)
-
- assert dimension + FW_HEADER_SIZE + FW_BYTES_ALIGN == size
- data = bs[FW_HEADER_SIZE:FW_HEADER_SIZE + dimension]
-
- with open(args.output, 'wb') as f:
- # ensure the file size
- f.seek(OUTPUT_FILE_SIZE - 1, os.SEEK_SET)
- f.write('\x00')
-
- f.seek(0, os.SEEK_SET)
- f.write(bs[0 : ctypes.sizeof(header)])
-
- offset = 0
- # write each sections
- for i, addr in enumerate(FLASH_SEC_ADDR):
- size = header.sec_size[i]
- assert addr is not None or size == 0
-
- if size == 0:
- continue
-
- f.seek(UPDATE_PDU_SIZE + addr, os.SEEK_SET)
- f.write(data[offset : offset + size])
- offset += size
-
- f.flush()
-
-
-if __name__ == '__main__':
- main()
diff --git a/util/uut/cmd.c b/util/uut/cmd.c
deleted file mode 100644
index 57cf75a29e..0000000000
--- a/util/uut/cmd.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-/* This file creates the UART Program Protocol API commands. */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "cmd.h"
-#include "lib_crc.h"
-#include "main.h"
-
- /* Extracting Byte - 8 bit: MSB, LSB */
-#define MSB(u16) ((uint8_t)((uint16_t)(u16) >> 8))
-#define LSB(u16) ((uint8_t)(u16))
-
-/*----------------------------------------------------------------------------
- * SPI Flash commands
- *---------------------------------------------------------------------------
- */
-
-#define SPI_READ_JEDEC_ID_CMD 0x9F
-#define SPI_WRITE_ENABLE_CMD 0x06
-#define SPI_WRITE_DISABLE_CMD 0x04
-#define SPI_READ_STATUS_REG_CMD 0x05
-#define SPI_WRITE_STATUS_REG_CMD 0x01
-#define SPI_READ_DATA_CMD 0x03
-#define SPI_PAGE_PRGM_CMD 0x02
-#define SPI_SECTOR_ERASE_CMD 0xD8
-#define SPI_BULK_ERASE_CMD 0xC7
-#define SPI_READ_PID_CMD 0x90
-
-union cmd_addr {
- uint8_t c_adr[4];
- uint32_t h_adr;
-};
-
-/*----------------------------------------------------------------------------
- * Function implementation
- *---------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------
- * Function: cmd_create_sync
- *
- * Parameters: cmd_info - Pointer to a command buffer.
- * cmd_len - Pointer to command length.
- * Returns: none.
- * Side effects:
- * Description:
- * Create a Host to Device SYNC protocol command.
- * The total command length is written to 'cmd_len'.
- *---------------------------------------------------------------------------
- */
-void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len)
-{
- uint32_t len = 0;
-
- /* Build the command buffer */
- cmd_info[len++] = UFPP_H2D_SYNC_CMD;
-
- /* Return total command length */
- *cmd_len = len;
-}
-
-/*---------------------------------------------------------------------------
- * Function: cmd_create_write
- *
- * Parameters: addr - Memory address to write to.
- * size - Size of daya (in bytes) to write to memory.
- * data_buf - Pointer to data buffer containing raw data to write.
- * cmd_info - Pointer to a command buffer.
- * cmd_len - Pointer to command length.
- * Returns: none.
- * Side effects:
- * Description:
- * Create a WRITE protocol command.
- * The command buffer is enclosed by CRC, calculated on command
- * information and raw data.
- * The total command length is written to 'cmd_len'.
- *---------------------------------------------------------------------------
- */
-void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf,
- uint8_t *cmd_info, uint32_t *cmd_len)
-{
- uint32_t i;
- union cmd_addr adr_tr;
- uint16_t crc = 0;
- uint32_t len = 0;
-
- /* Build the command buffer */
- cmd_info[len++] = UFPP_WRITE_CMD;
- cmd_info[len++] = (uint8_t)(size - 1);
-
- /* Insert Address */
- adr_tr.h_adr = addr;
- cmd_info[len++] = adr_tr.c_adr[3];
- cmd_info[len++] = adr_tr.c_adr[2];
- cmd_info[len++] = adr_tr.c_adr[1];
- cmd_info[len++] = adr_tr.c_adr[0];
-
- /* Insert data */
- memcpy(&cmd_info[len], data_buf, size);
- len += size;
-
- /* Calculate CRC */
- for (i = 0; i < len; i++)
- crc = update_crc(crc, (char)cmd_info[i]);
-
- /* Insert CRC */
- cmd_info[len++] = MSB(crc);
- cmd_info[len++] = LSB(crc);
-
- /* Return total command length */
- *cmd_len = len;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_create_read
- *
- * Parameters: addr - Memory address to read from.
- * size - Size of daya (in bytes) to read from memory.
- * cmd_info - Pointer to a command buffer.
- * cmd_len - Pointer to command length.
- * Returns: none.
- * Side effects:
- * Description:
- * Create a READ protocol command.
- * The command buffer is enclosed by CRC, calculated on command
- * information and raw data.
- * The total command length is written to 'cmd_len'.
- *---------------------------------------------------------------------------
- */
-void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info,
- uint32_t *cmd_len)
-{
- uint32_t i;
- union cmd_addr adr_tr;
- uint16_t crc = 0;
- uint32_t len = 0;
-
- /* Build the command buffer */
- cmd_info[len++] = UFPP_READ_CMD;
- cmd_info[len++] = (uint8_t)size;
-
- /* Insert Address */
- adr_tr.h_adr = addr;
- cmd_info[len++] = adr_tr.c_adr[3];
- cmd_info[len++] = adr_tr.c_adr[2];
- cmd_info[len++] = adr_tr.c_adr[1];
- cmd_info[len++] = adr_tr.c_adr[0];
-
- /* Calculate CRC */
- for (i = 0; i < len; i++)
- crc = update_crc(crc, (char)cmd_info[i]);
-
- /* Insert CRC */
- cmd_info[len++] = MSB(crc);
- cmd_info[len++] = LSB(crc);
-
- /* Return total command length */
- *cmd_len = len;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_create_exec
- *
- * Parameters: addr - Memory address to execute from.
- * cmd_info - Pointer to a command buffer.
- * cmd_len - Pointer to command length.
- * Returns: none.
- * Side effects:
- * Description:
- * Create an FCALL protocol command.
- * The command buffer is enclosed by CRC, calculated on command
- * information and raw data.
- * The total command length is written to 'cmd_len'.
- *---------------------------------------------------------------------------
- */
-void cmd_create_exec(uint32_t addr, uint8_t *cmd_info, uint32_t *cmd_len)
-{
- uint32_t i;
- union cmd_addr adr_tr;
- uint16_t crc = 0;
- uint32_t len = 0;
-
- /* Build the command buffer */
- cmd_info[len++] = UFPP_FCALL_CMD;
- cmd_info[len++] = 0;
-
- /* Insert Address */
- adr_tr.h_adr = addr;
- cmd_info[len++] = adr_tr.c_adr[3];
- cmd_info[len++] = adr_tr.c_adr[2];
- cmd_info[len++] = adr_tr.c_adr[1];
- cmd_info[len++] = adr_tr.c_adr[0];
-
- /* Calculate CRC */
- for (i = 0; i < len; i++)
- crc = update_crc(crc, (char)cmd_info[i]);
-
- /* Insert CRC */
- cmd_info[len++] = MSB(crc);
- cmd_info[len++] = LSB(crc);
-
- /* Return total command length */
- *cmd_len = len;
-}
-
-/*---------------------------------------------------------------------------
- * Function: cmd_build_sync
- *
- * Parameters: cmd_buf - Pointer to a command buffer.
- * cmd_num - Pointer to command number.
- * Returns: none.
- * Description:
- * Build a synchronization command buffer.
- * The total command number is written to 'cmd_num'.
- *---------------------------------------------------------------------------
- */
-void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num)
-{
- uint32_t cmd = 0;
-
- cmd_create_sync(cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size);
- cmd_buf[cmd].resp_size = 1;
- cmd++;
-
- *cmd_num = cmd;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_build_exec_exit
- *
- * Parameters: addr - Memory address to execute from.
- * cmd_buf - Pointer to a command buffer.
- * cmd_num - Pointer to command number.
- * Returns: none.
- * Side effects:
- * Description:
- * Build an Excute command buffer.
- * Command does not expect the executed code to return, that is,
- * only FCALL protocol
- * command code is expected.
- * Determine the expected response size per each command.
- * The total command number is written to 'cmd_num'.
- *---------------------------------------------------------------------------
- */
-void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf,
- uint32_t *cmd_num)
-{
- uint32_t cmd = 0;
-
- cmd_create_exec(addr, cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size);
- cmd_buf[cmd].resp_size = 1;
- cmd++;
-
- *cmd_num = cmd;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_build_exec_ret
- *
- * Parameters: addr - Memory address to execute from.
- * cmd_buf - Pointer to a command buffer.
- * cmd_num - Pointer to command number.
- * Returns: none.
- * Side effects:
- * Description:
- * Build an Excute command buffer.
- * Command expects the executed code to return, that is,
- * FCALL_RSLT protocol command
- * code is expected, together with the execution result.
- * Determine the expected response size per each command.
- * The total command number is written to 'cmd_num'.
- *---------------------------------------------------------------------------
- */
-void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf,
- uint32_t *cmd_num)
-{
- uint32_t cmd = 0;
-
- cmd_create_exec(addr, cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size);
- cmd_buf[cmd].resp_size = 3;
- cmd++;
-
- *cmd_num = cmd;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_disp_sync
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * Returns: TRUE if successful, FALSE in the case of an error.
- * Side effects:
- * Description:
- * Display SYNC command response information.
- *---------------------------------------------------------------------------
- */
-bool cmd_disp_sync(uint8_t *resp_buf)
-{
- if (resp_buf[0] == (uint8_t)(UFPP_D2H_SYNC_CMD)) {
- display_color_msg(SUCCESS, "Host/Device are synchronized\n");
- return true;
- }
-
- display_color_msg(FAIL, "Host/Device synchronization failed!!!\n");
- return false;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_disp_write
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * resp_size - Response size.
- * resp_num - Response packet number.
- * Returns: TRUE if successful, FALSE in the case of an error.
- * Side effects:
- * Description:
- * Display WRITE command response information.
- *---------------------------------------------------------------------------
- */
-bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num,
- uint32_t total_size)
-{
- if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) {
- display_color_msg(SUCCESS,
- "\rTransmitted packet of size %u bytes, packet "
- "[%u]out of [%u]",
- resp_size, resp_num, total_size);
- return true;
- }
-
- display_color_msg(FAIL, "\nWrite packet [%lu] Failed\n", resp_num);
- return false;
-}
-
-/*-----------------------------------------------------------------------------
- * Function: cmd_disp_read
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * resp_size - Response size.
- * resp_num - Response packet number.
- * Returns: TRUE if successful, FALSE in the case of an error.
- * Side effects:
- * Description:
- * Display READ command response information.
- *---------------------------------------------------------------------------
- */
-bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num,
- uint32_t total_size)
-{
- if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) {
- display_color_msg(SUCCESS,
- "\rReceived packet of size %u bytes, packet [%u] out "
- "of [%u]",
- resp_size, resp_num, total_size);
- return true;
- }
-
- display_color_msg(FAIL, "\nRead packet [%u] Failed\n", resp_num);
- return false;
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_disp_data
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * resp_size - Response size.
- * Returns: none.
- * Side effects:
- * Description:
- * Display raw data, read from memory.
- *---------------------------------------------------------------------------
- */
-void cmd_disp_data(uint8_t *resp_buf, uint32_t resp_size)
-{
- uint32_t idx;
- uint32_t i;
-
- for (idx = 0; idx < resp_size; idx += 4) {
- if ((idx % 16) == 0)
- printf("\n");
-
- printf("0x");
- for (i = 4; i > 0; i--)
- printf("%02x", resp_buf[idx + i - 1]);
-
- if ((idx % 4) == 0)
- printf(" ");
- }
-
- printf("\n");
-}
-
-/*----------------------------------------------------------------------------
- * Function: cmd_disp_flash_erase_dev
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * dev_num - Flash Device Number.
- * Returns: none.
- * Side effects:
- * Description:
- * Display BULK_ERASE command response information.
- *---------------------------------------------------------------------------
- */
-void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num)
-{
- if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) {
- display_color_msg(SUCCESS,
- "Flash Erase of device [%u] Passed\n", dev_num);
- } else {
- display_color_msg(
- FAIL, "Flash Erase of device [%u] Failed\n", dev_num);
- }
-}
-
-/*---------------------------------------------------------------------------
- * Function: cmd_disp_flash_erase_sect
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * Returns: none.
- * Side effects:
- * Description:
- * Display BULK_ERASE command response information.
- *---------------------------------------------------------------------------
- */
-void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num)
-{
- if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) {
- display_color_msg(SUCCESS,
- "Sector Erase of device [%lu] Passed\n", dev_num);
- } else {
- display_color_msg(
- FAIL, "Sector Erase of device [%lu] Failed\n", dev_num);
- }
-}
-
-/*---------------------------------------------------------------------------
- * Function: cmd_disp_exec_exit
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * Returns: none.
- * Side effects:
- * Description:
- * Display Execute command response information.
- *---------------------------------------------------------------------------
- */
-void cmd_disp_exec_exit(uint8_t *resp_buf)
-{
- if (resp_buf[0] == (uint8_t)(UFPP_FCALL_CMD))
- display_color_msg(SUCCESS, "Execute Command Passed\n");
- else
- display_color_msg(FAIL, "Execute Command Failed\n");
-}
-
-/*---------------------------------------------------------------------------
- * Function: cmd_disp_exec_ret
- *
- * Parameters: resp_buf - Pointer to a response buffer.
- * Returns: none.
- * Side effects:
- * Description:
- * Display Execute Result command response information.
- *---------------------------------------------------------------------------
- */
-void cmd_disp_exec_ret(uint8_t *resp_buf)
-{
- if (resp_buf[1] == (uint8_t)(UFPP_FCALL_RSLT_CMD)) {
- display_color_msg(SUCCESS,
- "Execute Command Passed, execution result is [0x%X]\n",
- resp_buf[2]);
- } else {
- display_color_msg(FAIL,
- "Execute Command Failed [0x%X] [0x%X], rslt=[0x%X]\n",
- resp_buf[0], resp_buf[1], resp_buf[2]);
- }
-}
diff --git a/util/uut/cmd.h b/util/uut/cmd.h
deleted file mode 100644
index 44cebbe989..0000000000
--- a/util/uut/cmd.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#ifndef __UTIL_UUT_CMD_H
-#define __UTIL_UUT_CMD_H
-
-#include <stdbool.h>
-
-/*---------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-
-#define MAX_CMD_BUF_SIZE 10
-#define MAX_RESP_BUF_SIZE 512
-
-enum uart_protocol_cmd {
- UFPP_H2D_SYNC_CMD = 0x55, /* Single-Byte Host to Device */
- /* synchronization command */
- UFPP_D2H_SYNC_CMD = 0x5A, /* Single-Byte Device to Host */
- /* synchronization response */
- UFPP_WRITE_CMD = 0x07, /* Write command and response */
- UFPP_READ_CMD = 0x1C, /* Read command and response */
- UFPP_READ_CRC_CMD = 0x89, /* Read CRC command and response */
- UFPP_FCALL_CMD = 0x70, /* Call function command */
- UFPP_FCALL_RSLT_CMD = 0x73, /* Call function response */
- UFPP_SPI_CMD = 0x92, /* SPI specific command */
- UFPP_ERROR_CMD = 0xFF /* Error response */
-};
-
-struct command_node {
- uint8_t cmd[512];
- uint32_t cmd_size;
- uint32_t resp_size;
-};
-
-/*---------------------------------------------------------------------------
- * Functions prototypes
- *---------------------------------------------------------------------------
- */
-
-void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len);
-void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf,
- uint8_t *cmd_info, uint32_t *cmd_len);
-void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info,
- uint32_t *cmd_len);
-void cmd_create_exec(uint32_t addr, uint8_t *cmd_info, uint32_t *cmd_len);
-
-void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num);
-void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf,
- uint32_t *cmd_num);
-void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf,
- uint32_t *cmd_num);
-
-bool cmd_disp_sync(uint8_t *resp_buf);
-bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num,
- uint32_t total_size);
-bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num,
- uint32_t total_size);
-void cmd_disp_data(uint8_t *resp_buf, uint32_t resp_size);
-void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num);
-void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num);
-void cmd_disp_exec_exit(uint8_t *resp_buf);
-void cmd_disp_exec_ret(uint8_t *resp_buf);
-
-#endif /* __UTIL_UUT_CMD_H */
diff --git a/util/uut/com_port.h b/util/uut/com_port.h
deleted file mode 100644
index 36331f2fb6..0000000000
--- a/util/uut/com_port.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-/* This file defines the ComPort interface header file. */
-
-#ifndef __UTIL_UUT_COM_PORT_H
-#define __UTIL_UUT_COM_PORT_H
-
-#include <stdbool.h>
-#include <termios.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*---------------------------------------------------------------------------
- * ComPort INTERFACE
- *---------------------------------------------------------------------------
- */
-
-/*---------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-#define INVALID_HANDLE_VALUE -1
-
-/*---------------------------------------------------------------------------
- * Type definitions
- *---------------------------------------------------------------------------
- */
-#define COMP_PORT_PREFIX_1 "ttyS"
-#define COMP_PORT_PREFIX_2 "ttyUSB"
-#define COMP_PORT_PREFIX_3 "pts"
-
-struct comport_fields {
- uint32_t baudrate; /* Baudrate at which running */
- tcflag_t byte_size; /* Number of bits/byte, 4-8 */
- tcflag_t parity; /* 0-4=None,Odd,Even,Mark,Space */
- uint8_t stop_bits; /* 0,1,2 = 1, 1.5, 2 */
- uint8_t flow_control; /* 0-none, 1-SwFlowControl,2-HwFlowControl */
-};
-
-/*---------------------------------------------------------------------------
- * Function: int com_port_open()
- *
- * Purpose: Open the specified ComPort device.
- *
- * Params: com_port_dev_name - The name of the device to open
- * com_port_fields - a struct filled with Comport settings, see
- * definition above.
- *
- * Returns: INVALID_HANDLE_VALUE (-1) - invalid handle.
- * Other value - Handle to be used in other Comport APIs
- *
- * Comments: The returned handle can be used for other Win32 API communication
- * function by casting it to HANDLE.
- *
- *---------------------------------------------------------------------------
- */
-int com_port_open(const char *com_port_dev_name,
- struct comport_fields com_port_fields);
-
-/*---------------------------------------------------------------------------
- * Function: int com_config_uart()
- *
- * Purpose: Configures the Uart port properties.
- *
- * Params: h_dev_drv - the opened handle returned by com_port_open()
- * com_port_fields - a struct filled with Comport settings, see
- * definition above.
- *
- * Returns: 1 if successful
- * 0 in the case of an error.
- *
- *---------------------------------------------------------------------------
- */
-bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields);
-
-/*---------------------------------------------------------------------------
- * Function: bool ComPortClose()
- *
- * Purpose: Close the ComPort device specified by Handle
- *
- * Params: device_id - the opened handle returned by com_port_open()
- *
- * Returns: 1 if successful
- * 0 in the case of an error.
- *
- *---------------------------------------------------------------------------
- */
-bool com_port_close(int device_id);
-
-/*---------------------------------------------------------------------------
- * Function: bool com_port_write_bin()
- *
- * Purpose: Send binary data through Comport
- *
- * Params: device_id - the opened handle returned by com_port_open()
- * buffer - contains the binary data to send
- * buf_size - the size of data to send
- *
- * Returns: 1 if successful
- * 0 in the case of an error.
- *
- * Comments: The caller must ensure that buf_size is not bigger than
- * Buffer size.
- *
- *---------------------------------------------------------------------------
- */
-bool com_port_write_bin(int device_id, const uint8_t *buffer,
- uint32_t buf_size);
-
-/*---------------------------------------------------------------------------
- * Function: uint32_t com_port_read_bin()
- *
- * Purpose: Read a binary data from Comport
- *
- * Params: device_id - the opened handle returned by com_port_open()
- * buffer - this buffer will contain the arrived data
- * buf_size - maximum data size to read
- *
- * Returns: The number of bytes read.
- *
- * Comments: The caller must ensure that Size is not bigger than Buffer size.
- *
- *---------------------------------------------------------------------------
- */
-uint32_t com_port_read_bin(int device_id, uint8_t *buffer, uint32_t buf_size);
-
-/*---------------------------------------------------------------------------
- * Function: uint32_t com_port_wait_read()
- *
- * Purpose: Wait until a byte is received for read
- *
- * Params: device_id - the opened handle returned by com_port_open()
- *
- * Returns: The number of bytes that are waiting in RX queue.
- *
- *---------------------------------------------------------------------------
- */
-uint32_t com_port_wait_read(int device_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __UTIL_UUT_COM_PORT_H */
diff --git a/util/uut/l_com_port.c b/util/uut/l_com_port.c
deleted file mode 100644
index 018dec9950..0000000000
--- a/util/uut/l_com_port.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "com_port.h"
-#include "main.h"
-
-/*---------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-
-#define INBUFSIZE 2048
-#define OUTBUFSIZE 2048
-#define LOWER_THRESHOLD 16
-#define UPPER_THRESHOLD 512
-#define XOFF_CHAR 0x13
-#define XON_CHAR 0x11
-
-#define UART_FIFO_SIZE 16
-
-#define COMMAND_TIMEOUT 10000 /* 10 seconds */
-
-/*---------------------------------------------------------------------------
- * Global variables
- *---------------------------------------------------------------------------
- */
-static struct termios savetty;
-
-/*---------------------------------------------------------------------------
- * Functions prototypes
- *---------------------------------------------------------------------------
- */
-
-/*--------------------------------------------------------------------------
- * Local Function implementation
- *--------------------------------------------------------------------------
- */
-
-/*--------------------------------------------------------------------------
- * Function: convert_baudrate_to_baudrate_mask
- *
- * Parameters:
- * baudrate - Bauderate value.
- *
- * Returns: Baudrate mask.
- * Side effects:
- * Description:
- * This routine convert from baudrate mode to paudrate mask.
- *--------------------------------------------------------------------------
- */
-static speed_t convert_baudrate_to_baudrate_mask(uint32_t baudrate)
-{
- switch (baudrate) {
- case 9600:
- return B9600;
- case 19200:
- return B19200;
- case 38400:
- return B38400;
- case 57600:
- return B57600;
- case 115200:
- return B115200;
- default:
- return B0;
- }
-}
-
-/*-------------------------------------------------------------------------
- * Function: set_read_blocking
- *
- * Parameters:
- * dev_drv - The opened handle returned by com_port_open()
- * block - TRUE means read in blocking mode
- * FALSE means read in non-blocking mode.
- *
- * Returns: none
- * Side effects:
- * Description:
- * This routine set/unset read blocking mode.
- *--------------------------------------------------------------------------
- */
-void set_read_blocking(int dev_drv, bool block)
-{
- struct termios tty;
-
- memset(&tty, 0, sizeof(tty));
-
- if (tcgetattr(dev_drv, &tty) != 0) {
- display_color_msg(FAIL,
- "set_read_blocking Error: %d Fail to get attribute "
- "from Device number %d.\n",
- errno, dev_drv);
- return;
- }
-
- tty.c_cc[VMIN] = block;
- tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */
-
- if (tcsetattr(dev_drv, TCSANOW, &tty) != 0) {
- display_color_msg(FAIL,
- "set_read_blocking Error: %d Fail to set attribute to "
- "Device number %d.\n",
- errno, dev_drv);
- }
-}
-
-/*--------------------------------------------------------------------------
- * Global Function implementation
- *--------------------------------------------------------------------------
- */
-
-/******************************************************************************
- * Function: int com_config_uart()
- *
- * Purpose: Configures the Uart port properties.
- *
- * Params: h_dev_drv - the opened handle returned by com_port_open()
- * com_port_fields - a struct filled with Comport settings, see
- * definition above.
- *
- * Returns: 1 if successful
- * 0 in the case of an error.
- *
- *****************************************************************************
- */
-bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields)
-{
- struct termios tty;
- speed_t baudrate;
-
- memset(&tty, 0, sizeof(tty));
-
- if (tcgetattr(h_dev_drv, &tty) != 0) {
- display_color_msg(FAIL,
- "com_config_uart Error: Fail to get attribute from "
- "Device number %d.\n",
- h_dev_drv);
- return false;
- }
-
- baudrate = convert_baudrate_to_baudrate_mask(com_port_fields.baudrate);
- cfsetospeed(&tty, baudrate);
- cfsetispeed(&tty, baudrate);
-
- tty.c_cflag |= baudrate;
-
- tty.c_cflag |= com_port_fields.byte_size;
-
- /*
- * disable IGNBRK for mismatched speed tests; otherwise receive break
- * as \000 chars
- */
-
- /* Set port to be in a "raw" mode. */
- tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |
- ICRNL | IXON);
- tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
-
- tty.c_oflag = ~OPOST;
- tty.c_cc[VMIN] = 0; /* read doesn't block */
- tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */
-
- tty.c_iflag |= (com_port_fields.flow_control == 0x01)
- ? (IXON | IXOFF)
- : 0x00; /* xon/xoff ctrl */
-
- tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
- /* enable reading */
- tty.c_cflag &= ~(PARENB | PARODD); /* shut off parity */
- tty.c_cflag |= com_port_fields.parity;
- /* Stop bits */
- tty.c_cflag |= (com_port_fields.stop_bits == 0x02) ? CSTOPB : 0x00;
- /* HW flow control */
- tty.c_cflag |= (com_port_fields.flow_control == 0x02) ? CRTSCTS : 0x00;
-
- /* Flush Port, then applies attributes */
- tcflush(h_dev_drv, TCIFLUSH);
-
- if (tcsetattr(h_dev_drv, TCSANOW, &tty) != 0) {
- display_color_msg(FAIL,
- "com_config_uart Error: %d setting port handle %d: %s.\n",
- errno, h_dev_drv, strerror(errno));
- return false;
- }
-
- return true;
-}
-
-/**
- * Drain the console RX buffer before programming. The device should be in
- * programming mode and shouldn't be printing anything. Anything that's
- * currently in the buffer could interfere with programming. discard_input
- * will discard everything currently in the buffer. It prints any non zero
- * characters and returns when the console is empty and ready for programming.
- *
- * This is the same as discard_input in stm32mon.
- * TODO: create common library for initializing serial consoles.
- */
-static void discard_input(int fd)
-{
- uint8_t buffer[64];
- int res, i;
- int count_of_zeros;
-
- /* Keep track of discarded zeros */
- count_of_zeros = 0;
- do {
- res = read(fd, buffer, sizeof(buffer));
- if (res > 0) {
-
- /* Discard zeros in the beginning of the buffer. */
- for (i = 0; i < res; i++)
- if (buffer[i])
- break;
-
- count_of_zeros += i;
- if (i == res) {
- /* Only zeros, nothing to print out. */
- continue;
- }
-
- /* Discard zeros in the end of the buffer. */
- while (!buffer[res - 1]) {
- count_of_zeros++;
- res--;
- }
-
- printf("Recv[%d]:", res - i);
- for (; i < res; i++)
- printf("%02x ", buffer[i]);
- printf("\n");
- }
- } while (res > 0);
-
- if (count_of_zeros)
- printf("%d zeros ignored\n", count_of_zeros);
-}
-
-
-/******************************************************************************
- * Function: int com_port_open()
- *
- * Purpose: Open the specified ComPort device and return its handle.
- *
- * Params: com_port_dev_name - The name of the device to open
- * com_port_fields - a struct filled with Comport settings
- *
- * Returns: INVALID_HANDLE_VALUE (-1) - invalid handle.
- * Other value - Handle to be used in other Comport APIs
- *
- * Comments: The returned handle can be used for other Win32 API communication
- * function.
- *
- *****************************************************************************
- */
-int com_port_open(const char *com_port_dev_name,
- struct comport_fields com_port_fields)
-{
- int port_handler;
-
- port_handler = open(com_port_dev_name, O_RDWR | O_NOCTTY);
-
- if (port_handler < 0) {
- display_color_msg(FAIL,
- "com_port_open Error %d opening %s: %s\n",
- errno, com_port_dev_name, strerror(errno));
- return INVALID_HANDLE_VALUE;
- }
-
- tcgetattr(port_handler, &savetty);
-
- if (!com_config_uart(port_handler, com_port_fields)) {
- display_color_msg(FAIL,
- "com_port_open() Error %d, Failed on com_config_uart() %s, "
- "%s\n",
- errno, com_port_dev_name, strerror(errno));
- close(port_handler);
- return INVALID_HANDLE_VALUE;
- }
-
- /*
- * Drain the console, so what ever is already in the EC console wont
- * interfere with programming.
- */
- discard_input(port_handler);
-
- return port_handler;
-}
-
-/******************************************************************************
- * Function: com_port_close()
- *
- * Purpose: Close the ComPort device specified by Handle
- *
- * Params: device_id - the opened handle returned by com_port_open()
- *
- * Returns: 1 if successful
- * 0 in the case of an error.
- *
- *****************************************************************************
- */
-bool com_port_close(int device_id)
-{
- tcsetattr(device_id, TCSANOW, &savetty);
-
- if (close(device_id) == INVALID_HANDLE_VALUE) {
- display_color_msg(FAIL,
- "com_port_close() Error: %d Device com%u was not opened, "
- "%s.\n",
- errno, (uint32_t)device_id, strerror(errno));
- return false;
- }
-
- return true;
-}
-
-/******************************************************************************
- * Function: com_port_write_bin()
- *
- * Purpose: Send binary data through Comport
- *
- * Params: device_id - the opened handle returned by com_port_open()
- * buffer - contains the binary data to send
- * buf_size - the size of data to send
- *
- * Returns: 1 if successful
- * 0 in the case of an error.
- *
- * Comments: The caller must ensure that buf_size is not bigger than
- * buffer size.
- *
- *****************************************************************************
- */
-bool com_port_write_bin(int device_id, const uint8_t *buffer,
- uint32_t buf_size)
-{
- uint32_t bytes_written;
-
- bytes_written = write(device_id, buffer, buf_size);
- if (bytes_written != buf_size) {
- display_color_msg(FAIL,
- "com_port_write_bin() Error: %d Failed to write data to "
- "Uart Port %d, %s.\n",
- errno, (uint32_t)device_id, strerror(errno));
-
- return false;
- }
-
- return true;
-}
-
-/******************************************************************************
- * Function: uint32_t com_port_read_bin()
- *
- * Purpose: Read a binary data from Comport
- *
- * Params: device_id - the opened handle returned by com_port_open()
- * buffer - this buffer will contain the arrived data
- * buf_size - maximum data size to read
- *
- * Returns: The number of bytes read.
- *
- * Comments: The caller must ensure that Size is not bigger than buffer size.
- *
- *****************************************************************************
- */
-uint32_t com_port_read_bin(int device_id, uint8_t *buffer, uint32_t buf_size)
-{
- int32_t read_bytes;
-
- /* Reset read blocking mode */
- set_read_blocking(device_id, false);
-
- read_bytes = read(device_id, buffer, buf_size);
-
- if (read_bytes == -1) {
- display_color_msg(FAIL,
- "%s() Error: %d Device number %u was not "
- "opened, %s.\n",
- __func__, errno, (uint32_t)device_id, strerror(errno));
- }
-
- return read_bytes;
-}
-
-/******************************************************************************
- * Function: uint32_t com_port_wait_read()
- *
- * Purpose: Wait until a byte is received for read
- *
- * Params: device_id - the opened handle returned by com_port_open()
- *
- * Returns: The number of bytes that are waiting in RX queue.
- *
- *****************************************************************************
- */
-uint32_t com_port_wait_read(int device_id)
-{
- int32_t bytes;
- int32_t ret_val;
- struct pollfd fds;
-
- /* Set read blocking mode */
- set_read_blocking(device_id, true);
-
- /* Wait up to 10 sec until byte is received for read. */
- fds.fd = device_id;
- fds.events = POLLIN;
- ret_val = poll(&fds, 1, COMMAND_TIMEOUT);
- if (ret_val < 0) {
- display_color_msg(FAIL,
- "%s() Error: %d Device number %u %s\n",
- __func__, errno, (uint32_t)device_id, strerror(errno));
- return 0;
- }
-
- bytes = 0;
-
- /* If data is ready for read. */
- if (ret_val > 0) {
- /* Get number of bytes that are ready to be read. */
- if (ioctl(device_id, FIONREAD, &bytes) < 0) {
- display_color_msg(FAIL,
- "com_port_wait_for_read() Error: %d Device number "
- "%u %s\n",
- errno, (uint32_t)device_id, strerror(errno));
- return 0;
- }
- }
-
- return bytes;
-}
diff --git a/util/uut/lib_crc.c b/util/uut/lib_crc.c
deleted file mode 100644
index 176e91327c..0000000000
--- a/util/uut/lib_crc.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-/*
- * The file lib_crc.c contains the functions used for the calculation of
- * CRC-16 cyclic redundancy values.
- */
-
-#include "lib_crc.h"
-
-/*********************************************************************
- * *
- * Library : lib_crc *
- * File : lib_crc.c *
- * Author : Lammert Bies 1999-2005 *
- * E-mail : info@lammertbies.nl *
- * Language : ANSI C *
- * *
- * *
- * Description *
- * =========== *
- * *
- * The file lib_crc.c contains the private and public func- *
- * tions used for the calculation of CRC-16, CRC-CCITT and *
- * CRC-32 cyclic redundancy values. *
- * *
- * *
- * Dependencies *
- * ============ *
- * *
- * lib_crc.h CRC definitions and prototypes *
- * *
- * *
- * Modification history *
- * ==================== *
- * *
- * Date Version Comment *
- * *
- * 2005-05-14 1.12 Added CRC-CCITT with start value 0 *
- * *
- * 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
- * *
- * 2005-02-04 1.10 Added CRC-DNP routines *
- * *
- * 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
- * *
- * 1999-01-22 1.00 Initial source *
- * *
- *********************************************************************
- */
-
-/* CRC16 lookup table for polynom 0xA001 */
-static const unsigned short crc16_tab[256] = {
- 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
- 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
- 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
- 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
- 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
- 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
- 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
- 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
- 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
- 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
- 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
- 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
- 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
- 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
- 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
- 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
- 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
- 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
- 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
- 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
- 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
- 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
- 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
- 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
- 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
- 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
- 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
- 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
- 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
- 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
- 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
- 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
-};
-
-/*********************************************************************
- * *
- * unsigned short update_crc( unsigned long crc, unsigned char c ) *
- * *
- * The function update_crc calculates a new CRC-16 value *
- * based on the previous value of the CRC and the next byte *
- * of the data to be checked. *
- * *
- *********************************************************************
- */
-unsigned short update_crc(unsigned short crc, unsigned char c)
-{
- unsigned short tmp;
-
- tmp = crc ^ (0x00ff & (unsigned short)c);
- crc = (crc >> 8) ^ crc16_tab[tmp & 0xff];
-
- return crc;
-}
diff --git a/util/uut/lib_crc.h b/util/uut/lib_crc.h
deleted file mode 100644
index 58db81c4e5..0000000000
--- a/util/uut/lib_crc.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-/*
- * This file contains public definitions and prototypes for the CRC functions.
- */
-
-#ifndef __UTIL_UUT_LIB_CRC_H
-#define __UTIL_UUT_LIB_CRC_H
-
-/*-------------------------------------------------------------------*\
- * *
- * Library : lib_crc *
- * File : lib_crc.h *
- * Author : Lammert Bies 1999-2005 *
- * E-mail : info@lammertbies.nl *
- * Language : ANSI C *
- * *
- * *
- * Description *
- * =========== *
- * *
- * The file lib_crc.h contains public definitions and proto- *
- * types for the CRC functions present in lib_crc.c. *
- * *
- * *
- * Dependencies *
- * ============ *
- * *
- * none *
- * *
- * *
- * Modification history *
- * ==================== *
- * *
- * Date Version Comment *
- * *
- * 2005-02-14 1.12 Added CRC-CCITT with initial value 0 *
- * *
- * 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
- * *
- * 2005-02-04 1.10 Added CRC-DNP routines *
- * *
- * 2005-01-07 1.02 Changes in tst_crc.c *
- * *
- * 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
- * *
- * 1999-01-22 1.00 Initial source *
- * *
- *-------------------------------------------------------------------*
- */
-
-/*---------------------------------------------------------------------------
- * CRC library constant definitions
- *---------------------------------------------------------------------------
- */
-#define CRC_VERSION "1.12"
-
-/*---------------------------------------------------------------------------
- * CRC library API
- *---------------------------------------------------------------------------
- */
-unsigned short update_crc(unsigned short crc, unsigned char c);
-
-#endif /* __UTIL_UUT_LIB_CRC_H */
diff --git a/util/uut/main.c b/util/uut/main.c
deleted file mode 100644
index 3ac8032739..0000000000
--- a/util/uut/main.c
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#include <errno.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#include "com_port.h"
-#include "compile_time_macros.h"
-#include "main.h"
-#include "misc_util.h"
-#include "opr.h"
-
-/*----------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-
-#define MAX_FILE_NAME_SIZE 512
-#define MAX_PARAM_SIZE 32
-#define MAX_MSG_SIZE 128
-#define MAX_SYNC_RETRIES 3
-
-/* Default values */
-#define DEFAULT_BAUD_RATE 115200
-#define DEFAULT_PORT_NAME "ttyS0"
-#define DEFAULT_DEV_NUM 0
-#define DEFAULT_FLASH_OFFSET 0
-
-/* The magic number in monitor header */
-#define MONITOR_HDR_TAG 0xA5075001
-/* The location of monitor header */
-#define MONITOR_HDR_ADDR 0x200C3000
-/* The start address of the monitor little firmware to execute */
-#define MONITOR_ADDR 0x200C3020
-/* The start address to store the firmware segment to be programmed */
-#define FIRMWARE_START_ADDR 0x10090000
-/* Divide the ec firmware image into 4K byte */
-#define FIRMWARE_SEGMENT 0x1000
-/* Register address for chip ID */
-#define NPCX_SRID_CR 0x400C101C
-/* Register address for device ID */
-#define NPCX_DEVICE_ID_CR 0x400C1022
-#define NPCX_FLASH_BASE_ADDR 0x64000000
-
-/*---------------------------------------------------------------------------
- * Global variables
- *---------------------------------------------------------------------------
- */
-bool verbose;
-bool console;
-struct comport_fields port_cfg;
-
-/*---------------------------------------------------------------------------
- * Local variables
- *---------------------------------------------------------------------------
- */
-
-static const char tool_name[] = {"LINUX UART Update Tool"};
-static const char tool_version[] = {"2.0.1"};
-
-static char port_name[MAX_PARAM_SIZE];
-static char opr_name[MAX_PARAM_SIZE];
-static char file_name[MAX_FILE_NAME_SIZE];
-static char addr_str[MAX_PARAM_SIZE];
-static char size_str[MAX_PARAM_SIZE];
-static uint32_t baudrate;
-static uint32_t dev_num;
-static uint32_t flash_offset;
-static bool auto_mode;
-static bool read_flash_flag;
-
-struct npcx_chip_info {
- uint8_t device_id;
- uint8_t chip_id;
- uint32_t flash_size;
-};
-
-const static struct npcx_chip_info chip_info[] = {
- {
- /* NPCX796FA */
- .device_id = 0x21,
- .chip_id = 0x06,
- .flash_size = 1024 * 1024,
- },
-
- {
- /* NPCX796FB */
- .device_id = 0x21,
- .chip_id = 0x07,
- .flash_size = 1024 * 1024,
- },
-
- {
- /* NPCX797WB */
- .device_id = 0x24,
- .chip_id = 0x07,
- .flash_size = 1024 * 1024,
- },
-
- {
- /* NPCX796FC */
- .device_id = 0x29,
- .chip_id = 0x07,
- .flash_size = 512 * 1024,
- },
-
- {
- /* NPCX797WC */
- .device_id = 0x2C,
- .chip_id = 0x07,
- .flash_size = 512 * 1024,
- },
-};
-/*---------------------------------------------------------------------------
- * Functions prototypes
- *---------------------------------------------------------------------------
- */
-
-static void param_parse_cmd_line(int argc, char *argv[]);
-static void param_check_opr_num(const char *opr);
-static uint32_t param_get_file_size(const char *file_name);
-static uint32_t param_get_str_size(char *string);
-static void main_print_version(void);
-static void tool_usage(void);
-static void exit_uart_app(int32_t exit_status);
-
-enum EXIT_CODE {
- EC_OK = 0x00,
- EC_PORT_ERR = 0x01,
- EC_BAUDRATE_ERR = 0x02,
- EC_SYNC_ERR = 0x03,
- EC_DEV_NUM_ERR = 0x04,
- EC_OPR_MUM_ERR = 0x05,
- EC_ALIGN_ERR = 0x06,
- EC_FILE_ERR = 0x07,
- EC_UNSUPPORTED_CMD_ERR = 0x08
-};
-
-/*---------------------------------------------------------------------------
- * Function implementation
- *---------------------------------------------------------------------------
- */
-
-/*---------------------------------------------------------------------------
- * Function: image_auto_write
- *
- * Parameters: offset - The start address of the flash to write the firmware
- * to.
- * buffer - The buffer holds data of the firmware.
- * file_size - the size to be programmed.
- * Returns: 1 for a successful operation, 0 otherwise.
- * Side effects:
- * Description:
- * Divide the firmware to segments and program them one by one.
- *---------------------------------------------------------------------------
- */
-static bool image_auto_write(uint32_t offset, uint8_t *buffer,
- uint32_t file_size)
-{
- uint32_t data_buf[4];
- uint32_t addr, chunk_remain, file_seg, flash_index, seg;
- uint32_t count, percent, total;
- uint32_t i;
-
- flash_index = offset;
- /* Monitor tag */
- data_buf[0] = MONITOR_HDR_TAG;
-
- file_seg = file_size;
- total = 0;
- while (file_seg) {
- seg = (file_seg > FIRMWARE_SEGMENT) ?
- FIRMWARE_SEGMENT : file_seg;
- /*
- * Check if the content of the segment is all 0xff.
- * If yes, there is no need to write.
- * Call the monitor to erase the segment only for
- * time efficiency.
- */
- for (i = 0; i < seg && buffer[i] == 0xFF; i++)
- ;
- if (i == seg) {
- data_buf[1] = seg;
- /*
- * Set src_addr = 0 as a flag. When the monitor read 0
- * from this field, it will do sector erase only.
- */
- data_buf[2] = 0;
- data_buf[3] = flash_index;
- opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR,
- sizeof(data_buf));
- if (opr_execute_return(MONITOR_ADDR) != true)
- return false;
- file_seg -= seg;
- flash_index += seg;
- buffer += seg;
- total += seg;
- percent = total * 100 / file_size;
- printf("\r[%d%%] %d/%d", percent, total, file_size);
- fflush(stdout);
- continue;
- }
- chunk_remain = seg;
- addr = FIRMWARE_START_ADDR;
- /* the size to be programmed */
- data_buf[1] = seg;
- /* The source(RAM) address where the firmware is stored. */
- data_buf[2] = FIRMWARE_START_ADDR;
- /*
- * The offset of the flash where the segment to be programmed.
- */
- data_buf[3] = flash_index;
- /* Write the monitor header to RAM */
- opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR,
- sizeof(data_buf));
- while (chunk_remain) {
- count = (chunk_remain > MAX_RW_DATA_SIZE) ?
- MAX_RW_DATA_SIZE : chunk_remain;
- if (opr_write_chunk(buffer, addr, count) != true)
- return false;
-
- addr += count;
- buffer += count;
- chunk_remain -= count;
- total += count;
- percent = total * 100 / file_size;
- printf("\r[%d%%] %d/%d", percent, total, file_size);
- }
- fflush(stdout);
- if (opr_execute_return(MONITOR_ADDR) != true)
- return false;
- file_seg -= seg;
- flash_index += seg;
- }
- printf("\n");
- /* Clear the UUT header tag */
- data_buf[0] = 0;
- opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR, 4);
- return true;
-}
-
-static bool get_flash_size(uint32_t *flash_size)
-{
- uint8_t dev_id, chip_id, i;
-
- if (opr_read_chunk(&dev_id, NPCX_DEVICE_ID_CR, 1) != true)
- return false;
-
- if (opr_read_chunk(&chip_id, NPCX_SRID_CR, 1) != true)
- return false;
-
- for (i = 0; i < ARRAY_SIZE(chip_info); i++) {
- if (chip_info[i].device_id == dev_id &&
- chip_info[i].chip_id == chip_id) {
- *flash_size = chip_info[i].flash_size;
- return true;
- }
- }
- printf("Unknown NPCX device ID:0x%02x chip ID:0x%02x\n",
- dev_id, chip_id);
-
- return false;
-}
-
-/*---------------------------------------------------------------------------
- * Function: read_input_file
- *
- * Parameters: size - The size of input file.
- * file_name - The name if input file.
- * Returns: The address of the buffer allocated to stroe file content.
- * Side effects:
- * Description:
- * Read the file content into an allocated buffer.
- *---------------------------------------------------------------------------
- */
-static uint8_t *read_input_file(uint32_t size, const char *file_name)
-{
- uint8_t *buffer;
- FILE *input_fp;
-
- buffer = malloc(size);
- if (!buffer) {
- fprintf(stderr, "Cannot allocate %d bytes\n", size);
- return NULL;
- }
- input_fp = fopen(file_name, "r");
- if (!input_fp) {
- display_color_msg(FAIL,
- "ERROR: cannot open file %s\n", file_name);
- free(buffer);
- return NULL;
- }
- if (fread(buffer, size, 1, input_fp) != 1) {
- fprintf(stderr, "Cannot read %s\n", file_name);
- fclose(input_fp);
- free(buffer);
- return NULL;
- }
- fclose(input_fp);
- return buffer;
-}
-
-/*---------------------------------------------------------------------------
- * Function: main
- *
- * Parameters: argc - Argument Count.
- * argv - Argument Vector.
- * Returns: 1 for a successful operation, 0 otherwise.
- * Side effects:
- * Description:
- * Console application main operation.
- *---------------------------------------------------------------------------
- */
-int main(int argc, char *argv[])
-{
- char *stop_str;
- char aux_buf[MAX_FILE_NAME_SIZE];
- uint32_t size = 0;
- uint32_t addr = 0;
- enum sync_result sr;
- uint8_t *buffer;
- int sync_cnt;
-
- if (argc <= 1)
- exit(EC_UNSUPPORTED_CMD_ERR);
-
- /* Setup defaults */
- strncpy(port_name, DEFAULT_PORT_NAME, sizeof(port_name));
- baudrate = DEFAULT_BAUD_RATE;
- dev_num = DEFAULT_DEV_NUM;
- flash_offset = DEFAULT_FLASH_OFFSET;
- opr_name[0] = '\0';
- verbose = true;
- console = false;
- auto_mode = false;
- read_flash_flag = false;
-
- param_parse_cmd_line(argc, argv);
-
- /* Configure COM Port parameters */
- port_cfg.baudrate = MAX(baudrate, BR_LOW_LIMIT);
- port_cfg.byte_size = CS8;
- port_cfg.flow_control = 0;
- port_cfg.parity = 0;
- port_cfg.stop_bits = 0;
-
- /*
- * Open a ComPort device. If user haven't specified such, use ComPort 1
- */
- if (opr_open_port(port_name, port_cfg) != true)
- exit(EC_PORT_ERR);
-
- if (baudrate == 0) { /* Scan baud rate range */
- opr_scan_baudrate();
- exit_uart_app(EC_OK);
- }
-
- /* Verify Host and Device are synchronized */
- DISPLAY_MSG(("Performing a Host/Device synchronization check...\n"));
- for (sync_cnt = 1; sync_cnt <= MAX_SYNC_RETRIES; sync_cnt++) {
- sr = opr_check_sync(baudrate);
- if (sr == SR_OK)
- break;
- /*
- * If it fails, try it again up to three times.
- * It might fail for garbage data drainage from H1, or
- * for timeout due to unstable data transfer yet.
- */
- display_color_msg(FAIL,
- "Host/Device synchronization failed, error = %d,"
- " fail count = %d\n", sr, sync_cnt);
- }
- if (sync_cnt > MAX_SYNC_RETRIES)
- exit_uart_app(EC_SYNC_ERR);
-
- if (auto_mode) {
- size = param_get_file_size(file_name);
- if (size == 0)
- exit_uart_app(EC_FILE_ERR);
-
- buffer = read_input_file(size, file_name);
- if (!buffer)
- exit_uart_app(EC_FILE_ERR);
-
- printf("Write file %s at %d with %d bytes\n",
- file_name, flash_offset, size);
- if (image_auto_write(flash_offset, buffer, size)) {
- printf("Flash Done.\n");
- free(buffer);
- exit_uart_app(EC_OK);
- }
- free(buffer);
- exit_uart_app(-1);
- }
-
- if (read_flash_flag) {
- uint32_t flash_size;
-
- if (get_flash_size(&flash_size)) {
- printf("Read %d bytes from flash...\n", flash_size);
- opr_read_mem(file_name, NPCX_FLASH_BASE_ADDR,
- flash_size);
- exit_uart_app(EC_OK);
- }
-
- printf("Fail to read the flash size\n");
- exit_uart_app(-1);
- }
-
- param_check_opr_num(opr_name);
-
- /* Write buffer data to chosen address */
- if (strcmp(opr_name, OPR_WRITE_MEM) == 0) {
- addr = strtoul(addr_str, &stop_str, 0);
-
- if (console) {
- /*
- * Copy the input string to an auxiliary buffer, since
- * string is altered by param_get_str_size
- */
- memcpy(aux_buf, file_name, sizeof(file_name));
- /* Retrieve input size */
- size = param_get_str_size(file_name);
- /* Ensure non-zero size */
- if (size == 0)
- exit_uart_app(EC_FILE_ERR);
- opr_write_mem(aux_buf, addr, size);
- } else {
- size = param_get_file_size(file_name);
- if (size == 0)
- exit_uart_app(EC_FILE_ERR);
- buffer = read_input_file(size, file_name);
- if (!buffer)
- exit_uart_app(EC_FILE_ERR);
- opr_write_mem(buffer, addr, size);
- free(buffer);
- }
- } else if (strcmp(opr_name, OPR_READ_MEM) == 0) {
- /* Read data to chosen address */
-
- addr = strtoul(addr_str, &stop_str, 0);
- size = strtoul(size_str, &stop_str, 0);
-
- opr_read_mem(file_name, addr, size);
- } else if (strcmp(opr_name, OPR_EXECUTE_EXIT) == 0) {
- /* Execute From Address a non-return code */
-
- addr = strtoul(addr_str, &stop_str, 0);
-
- opr_execute_exit(addr);
- exit_uart_app(EC_OK);
- } else if (strcmp(opr_name, OPR_EXECUTE_CONT) == 0) {
- /* Execute From Address a returnable code */
-
- addr = strtoul(addr_str, &stop_str, 0);
-
- opr_execute_return(addr);
- } else {
- exit_uart_app(EC_UNSUPPORTED_CMD_ERR);
- }
-
- exit_uart_app(EC_OK);
- return 0;
-}
-
-/*---------------------------------------------------------------------------
- * Function: param_parse_cmd_line
- *
- * Parameters: argc - Argument Count.
- * argv - Argument Vector.
- * Returns: None.
- * Side effects:
- * Description:
- * Parse command line parameters.
- *---------------------------------------------------------------------------
- */
-
-static const struct option long_opts[] = {
- {"version", 0, 0, 'v'},
- {"help", 0, 0, 'h'},
- {"quiet", 0, 0, 'q'},
- {"console", 0, 0, 'c'},
- {"auto", 0, 0, 'A'},
- {"read-flash", 0, 0, 'r'},
- {"baudrate", 1, 0, 'b'},
- {"opr", 1, 0, 'o'},
- {"port", 1, 0, 'p'},
- {"file", 1, 0, 'f'},
- {"addr", 1, 0, 'a'},
- {"size", 1, 0, 's'},
- {"offset", 1, 0, 'O'},
- {NULL, 0, 0, 0}
-};
-
-static char *short_opts = "vhqcArb:o:p:f:a:s:O:?";
-
-static void param_parse_cmd_line(int argc, char *argv[])
-{
- int opt, idx;
-
- while ((opt = getopt_long(argc, argv, short_opts,
- long_opts, &idx)) != -1) {
-
- switch (opt) {
- case 'v':
- main_print_version();
- exit(EC_OK);
- case 'h':
- case '?':
- tool_usage();
- opr_usage();
- exit(EC_OK);
- case 'q':
- verbose = false;
- break;
- case 'c':
- console = true;
- break;
- case 'A':
- auto_mode = true;
- break;
- case 'r':
- read_flash_flag = true;
- break;
- case 'b':
- if (sscanf(optarg, "%du", &baudrate) == 0)
- exit(EC_BAUDRATE_ERR);
- break;
- case 'o':
- strncpy(opr_name, optarg, sizeof(opr_name));
- opr_name[sizeof(opr_name)-1] = '\0';
- break;
- case 'p':
- strncpy(port_name, optarg, sizeof(port_name));
- port_name[sizeof(port_name)-1] = '\0';
- break;
- case 'f':
- strncpy(file_name, optarg, sizeof(file_name));
- file_name[sizeof(file_name)-1] = '\0';
- break;
- case 'a':
- strncpy(addr_str, optarg, sizeof(addr_str));
- addr_str[sizeof(addr_str)-1] = '\0';
- break;
- case 's':
- strncpy(size_str, optarg, sizeof(size_str));
- size_str[sizeof(size_str)-1] = '\0';
- break;
- case 'O':
- flash_offset = strtol(optarg, NULL, 0);
- break;
- }
- }
-}
-
-/*---------------------------------------------------------------------------
- * Function: param_check_opr_num
- *
- * Parameters: opr - Operation Number.
- * Returns: none.
- * Side effects:
- * Description:
- * Verify the validity of operation Number.
- *---------------------------------------------------------------------------
- */
-static void param_check_opr_num(const char *opr)
-{
-
- if ((strcasecmp(opr, OPR_WRITE_MEM) != 0) &&
- (strcasecmp(opr, OPR_READ_MEM) != 0) &&
- (strcasecmp(opr, OPR_EXECUTE_EXIT) != 0) &&
- (strcasecmp(opr, OPR_EXECUTE_CONT) != 0)) {
- display_color_msg(FAIL,
- "ERROR: Operation %s not supported, Supported "
- "operations are %s, %s, %s & %s\n",
- opr, OPR_WRITE_MEM, OPR_READ_MEM, OPR_EXECUTE_EXIT,
- OPR_EXECUTE_CONT);
- exit_uart_app(EC_OPR_MUM_ERR);
- }
-}
-
-/*---------------------------------------------------------------------------
- * Function: param_get_file_size
- *
- * Parameters: file_name - input file name.
- * Returns: size of file (in bytes).
- * Side effects:
- * Description:
- * Retrieve the size (in bytes) of a given file.
- *--------------------------------------------------------------------------
- */
-static uint32_t param_get_file_size(const char *file_name)
-{
- struct stat fst;
-
- if (stat(file_name, &fst)) {
- display_color_msg(FAIL,
- "ERROR: Could not stat file [%s]\n", file_name);
- return 0;
- }
- return fst.st_size;
-
-}
-
-/*---------------------------------------------------------------------------
- * Function: param_get_str_size
- *
- * Parameters: string - input string.
- * Returns: size of double-words (in bytes).
- * Side effects:
- * Description:
- * Retrieve the size (in bytes) of double-word values in a given string.
- * E.g., given the string "1234 AB5678 FF", return 12 (for three
- * double-words).
- *---------------------------------------------------------------------------
- */
-static uint32_t param_get_str_size(char *string)
-{
- uint32_t str_size = 0;
- char seps[] = " ";
- char *token = NULL;
-
- /* Verify string is non-NULL */
- if ((string == NULL) || (strlen(string) == 0)) {
- display_color_msg(FAIL,
- "ERROR: Zero length input string provided\n");
- return 0;
- }
-
- /* Read first token from string */
- token = strtok(string, seps);
-
- /* Loop while there are tokens in "string" */
- while (token != NULL) {
- str_size++;
- token = strtok(NULL, seps);
- }
-
- /* Refer to each token as a double-word */
- str_size *= sizeof(uint32_t);
- return str_size;
-}
-
-/*--------------------------------------------------------------------------
- * Function: tool_usage
- *
- * Parameters: none.
- * Returns: none.
- * Side effects:
- * Description:
- * Prints the console application help menu.
- *--------------------------------------------------------------------------
- */
-static void tool_usage(void)
-{
- printf("%s version %s\n\n", tool_name, tool_version);
- printf("General switches:\n");
- printf(" -v, --version - Print version\n");
- printf(" -h, --help - Help menu\n");
- printf(" -q, --quiet - Suppress verbose mode (default is "
- "verbose ON)\n");
- printf(" -c, --console - Print data to console (default is "
- "print to file)\n");
- printf(" -p, --port <name> - Serial port name (default is %s)\n",
- DEFAULT_PORT_NAME);
- printf(" -b, --baudrate <num> - COM Port baud-rate (default is %d)\n",
- DEFAULT_BAUD_RATE);
- printf(" -A, --auto - Enable auto mode. (default is off)\n");
- printf(" -O, --offset <num> - With --auto, assign the offset of");
- printf(" flash where the image to be written.\n");
- printf(" -r, --read-flash - With --file=<file>, Read the whole"
- " flash content and write it to <file>.\n");
- printf("\n");
- printf("Operation specific switches:\n");
- printf(" -o, --opr <name> - Operation number (see list below)\n");
- printf(" -f, --file <name> - Input/output file name\n");
- printf(" -a, --addr <num> - Start memory address\n");
- printf(" -s, --size <num> - Size of data to read\n");
- printf("\n");
-}
-
-/*--------------------------------------------------------------------------
- * Function: main_print_version
- *
- * Parameters: none
- * Returns: none
- * Side effects:
- * Description:
- * This routine prints the tool version
- *--------------------------------------------------------------------------
- */
-static void main_print_version(void)
-{
- printf("%s version %s\n\n", tool_name, tool_version);
-}
-
-/*---------------------------------------------------------------------------
- * Function: exit_uart_app
- *
- * Parameters: none.
- * Returns: none.
- * Side effects:
- * Description:
- * Exit "nicely" the application.
- *---------------------------------------------------------------------------
- */
-static void exit_uart_app(int32_t exit_status)
-{
- if (opr_close_port() != true)
- display_color_msg(FAIL, "ERROR: Port close failed.\n");
-
- exit(exit_status);
-}
-
-/*---------------------------------------------------------------------------
- * Function: display_color_msg
- *
- * Parameters:
- * success - SUCCESS for successful message, FAIL for erroneous
- * massage.
- * fmt - Massage to dispaly (format and arguments).
- *
- * Returns: none
- * Side effects: Using DISPLAY_MSG macro.
- * Description:
- * This routine displays a message using color attributes:
- * In case of a successful message, use green foreground text on
- * black background.
- * In case of an erroneous message, use red foreground text on
- * black background.
- *---------------------------------------------------------------------------
- */
-void display_color_msg(bool success, char *fmt, ...)
-{
- va_list argptr;
-
- va_start(argptr, fmt);
- vprintf(fmt, argptr);
- va_end(argptr);
-}
diff --git a/util/uut/main.h b/util/uut/main.h
deleted file mode 100644
index 10c1391136..0000000000
--- a/util/uut/main.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#ifndef __UTIL_UUT_MAIN_H
-#define __UTIL_UUT_MAIN_H
-
-#include <stdbool.h>
-
-/*---------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-/* Maximum Read/Write data size per packet */
-#define MAX_RW_DATA_SIZE 256
-
-/* Base for string conversion */
-#define BASE_DECIMAL 10
-#define BASE_HEXADECIMAL 16
-
-/* Verbose control messages display */
-#define DISPLAY_MSG(msg) \
-{ \
- if (verbose) \
- printf msg; \
-}
-
-#define SUCCESS true
-#define FAIL false
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*--------------------------------------------------------------------------
- * Global variables
- *--------------------------------------------------------------------------
- */
-
-extern bool verbose;
-extern bool console;
-
-/*--------------------------------------------------------------------------
- * Global functions
- *--------------------------------------------------------------------------
- */
-
-/*---------------------------------------------------------------------------
- * Function: display_color_msg
- *
- * Parameters:
- * success - SUCCESS for successful message, FAIL for erroneous
- * massage.
- * fmt - Massage to dispaly (format and arguments).
- *
- * Returns: none
- * Side effects: Using DISPLAY_MSG macro.
- * Description:
- * This routine displays a message using color attributes:
- * In case of a successful message, use green foreground text on
- * black background.
- * In case of an erroneous message, use red foreground text on
- * black background.
- *--------------------------------------------------------------------------
- */
-void display_color_msg(bool success, char *fmt, ...);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __UTIL_UUT_MAIN_H */
diff --git a/util/uut/opr.c b/util/uut/opr.c
deleted file mode 100644
index 81a711cf75..0000000000
--- a/util/uut/opr.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-/* This file implements the UART console application operations. */
-#define _GNU_SOURCE
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "com_port.h"
-#include "cmd.h"
-#include "main.h"
-#include "misc_util.h"
-#include "opr.h"
-
-/*----------------------------------------------------------------------------
- * Global Variables
- *---------------------------------------------------------------------------
- */
-int port_handle = INVALID_HANDLE_VALUE;
-
-/*----------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-#define MAX_PORT_NAME_SIZE 32
-#define OPR_TIMEOUT 10L /* 10 seconds */
-#define FLASH_ERASE_TIMEOUT 120L /* 120 seconds */
-
-#define STS_MSG_MIN_SIZE 8
-#define STS_MSG_APP_END 0x09
-#define DUMMY_SIZE 2
-
-#define MAX_SYNC_TRIALS 3
-
-/*----------------------------------------------------------------------------
- * Global variables
- *---------------------------------------------------------------------------
- */
-struct command_node cmd_buf[MAX_CMD_BUF_SIZE];
-uint8_t resp_buf[MAX_RESP_BUF_SIZE];
-
-/*---------------------------------------------------------------------------
- * Functions prototypes
- *---------------------------------------------------------------------------
- */
-static bool opr_send_cmds(struct command_node *cmd_buf, uint32_t cmd_num);
-
-/*----------------------------------------------------------------------------
- * Function implementation
- *----------------------------------------------------------------------------
- */
-
-/*----------------------------------------------------------------------------
- * Function: opr_usage
- *
- * Parameters: none.
- * Returns: none.
- * Side effects:
- * Description:
- * Prints the console application operation menu.
- *---------------------------------------------------------------------------
- */
-void opr_usage(void)
-{
- printf("Operations:\n");
- printf(" %s\t\t- Write To Memory/Flash\n", OPR_WRITE_MEM);
- printf(" %s\t\t- Read From Memory/Flash\n", OPR_READ_MEM);
- printf(" %s\t\t- Execute a non-return code\n", OPR_EXECUTE_EXIT);
- printf(" %s\t\t- Execute a returnable code\n", OPR_EXECUTE_CONT);
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_close_port
- *
- * Parameters: none
- * Returns:
- * Side effects:
- * Description:
- * This routine closes the opened COM port by the application
- *---------------------------------------------------------------------------
- */
-bool opr_close_port(void)
-{
- return com_port_close(port_handle);
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_open_port
- *
- * Parameters: port_name - COM Port name.
- * port_cfg - COM Port configuration structure.
- * Returns: 1 if successful, 0 in the case of an error.
- * Side effects:
- * Description:
- * Open a specified ComPort device.
- *---------------------------------------------------------------------------
- */
-bool opr_open_port(const char *port_name, struct comport_fields port_cfg)
-{
- char *full_port_name;
-
- if (asprintf(&full_port_name, "/dev/%s", port_name) == -1)
- return false;
-
- if (port_handle > 0)
- com_port_close(port_handle);
-
- port_handle = com_port_open((const char *)full_port_name, port_cfg);
-
- if (port_handle <= 0) {
- display_color_msg(FAIL, "\nERROR: COM Port failed to open.\n");
- DISPLAY_MSG(
- ("Please select the right serial port or check if "
- "other serial\n"));
- DISPLAY_MSG(("communication applications are opened.\n"));
- return false;
- }
-
- display_color_msg(SUCCESS, "Port %s Opened\n", full_port_name);
-
- return true;
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_write_chunk
- *
- * Parameters:
- * buffer - Input data buffer.
- * addr - Memory address to write to.
- * size - Data size to write.
- * Returns: true if successful, false in the case of an error.
- * Side effects:
- * Description:
- * Write data to RAM, starting from the given address (addr).
- * Data size is limited to the max chunk size (256 bytes).
- *---------------------------------------------------------------------------
- */
-bool opr_write_chunk(uint8_t *buffer, uint32_t addr, uint32_t size)
-{
- struct command_node wr_cmd_buf;
-
- if (size > MAX_RW_DATA_SIZE) {
- display_color_msg(FAIL,
- "ERROR: Block cannot exceed %d\n", MAX_RW_DATA_SIZE);
- }
- /* Initialize response size */
- wr_cmd_buf.resp_size = 1;
- cmd_create_write(addr, size, buffer,
- wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size);
- return opr_send_cmds(&wr_cmd_buf, 1);
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_read_chunk
- *
- * Parameters:
- * buffer - Data read buffer.
- * addr - Memory address to read from.
- * size - Data size to read.
- * Returns: true if successful, false in the case of an error.
- * Side effects:
- * Description:
- * Read data from RAM, starting from the given address (addr).
- * Data size is limited to the max chunk size (256 bytes).
- *---------------------------------------------------------------------------
- */
-bool opr_read_chunk(uint8_t *buffer, uint32_t addr, uint32_t size)
-{
- struct command_node rd_cmd_buf;
-
- if (size > MAX_RW_DATA_SIZE) {
- display_color_msg(FAIL,
- "ERROR: Block cannot exceed %d\n", MAX_RW_DATA_SIZE);
- return false;
- }
-
- cmd_create_read(addr, ((uint8_t)size - 1),
- rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size);
- rd_cmd_buf.resp_size = size + 3;
- if (opr_send_cmds(&rd_cmd_buf, 1)) {
- if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) {
- memcpy(buffer, &resp_buf[1], size);
- return true;
- }
- }
- return false;
-}
-/*----------------------------------------------------------------------------
- * Function: opr_write_mem
- *
- * Parameters: input - Input (file-name/console), containing data to write.
- * addr - Memory address to write to.
- * size - Data size to write.
- * Returns: none.
- * Side effects:
- * Description:
- * Write data to memory, starting from a given address.
- * Memory may be Flash (SPI), DRAM (DDR) or SRAM.
- * The data is retrieved either from an input file or from a console.
- * Data size is not limited.
- * Data is sent in 256 bytes chunks (file mode) or 4 bytes chunks
- * (console mode).
- *---------------------------------------------------------------------------
- */
-void opr_write_mem(uint8_t *buffer, uint32_t addr, uint32_t size)
-{
- uint32_t cur_addr = addr;
- uint8_t data_buf[256];
- uint32_t write_size, size_remain;
- uint32_t cmd_idx = 1;
- char seps[] = " ";
- char *token = NULL;
- char *stop_str;
- uint32_t block_size = (console) ? sizeof(uint32_t) : MAX_RW_DATA_SIZE;
- struct command_node wr_cmd_buf;
-
- /* Initialize response size */
- wr_cmd_buf.resp_size = 1;
-
- DISPLAY_MSG(("Writing [%d] bytes in [%d] packets\n", size,
- ((size + (block_size - 1)) / block_size)));
-
- /* Read first token from string */
- if (console)
- token = strtok(buffer, seps);
-
- size_remain = size;
- /* Main write loop */
- while (true) {
- if (console) {
- /*
- * Invert token to double-word and insert the value to
- * data buffer
- */
- (*(uint32_t *)data_buf) =
- strtoul(token, &stop_str, BASE_HEXADECIMAL);
-
- /* Prepare the next iteration */
- token = strtok(NULL, seps);
- }
- write_size = (size_remain > block_size) ?
- block_size : size_remain;
- if (console) {
- cmd_create_write(cur_addr, write_size, data_buf,
- wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size);
- } else {
- cmd_create_write(cur_addr, write_size, buffer,
- wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size);
- buffer += write_size;
- }
- if (opr_send_cmds(&wr_cmd_buf, 1) != true)
- break;
-
- cmd_disp_write(resp_buf, write_size, cmd_idx,
- ((size + (block_size - 1)) / block_size));
- cur_addr += write_size;
- size_remain -= write_size;
- cmd_idx++;
- if (size_remain == 0)
- break;
- }
-
- DISPLAY_MSG(("\n"));
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_read_mem
- *
- * Parameters: output - Output file name, containing data that was read.
- * addr - Memory address to read from.
- * size - Data size to read.
- * Returns: none.
- * Side effects:
- * Description:
- * Read data from memory, starting from a given address.
- * Memory may be Flash (SPI), DRAM (DDR) or SRAM.
- * The data is written into an output file, data size is limited
- * as specified.
- * Data is received in 256 bytes chunks.
- *---------------------------------------------------------------------------
- */
-void opr_read_mem(char *output, uint32_t addr, uint32_t size)
-{
- FILE *output_file_id = NULL;
- uint32_t cur_addr;
- uint32_t bytes_left;
- uint32_t read_size;
- uint32_t cmd_idx = 1;
- struct command_node rd_cmd_buf;
-
- if (!console) {
- output_file_id = fopen(output, "w+b");
-
- if (output_file_id == NULL) {
- display_color_msg(FAIL,
- "ERROR: could not open output file [%s]\n",
- output);
- return;
- }
- }
-
- DISPLAY_MSG(("Reading [%d] bytes in [%d] packets\n", size,
- ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE)));
-
- for (cur_addr = addr; cur_addr < (addr + size);
- cur_addr += MAX_RW_DATA_SIZE) {
- bytes_left = (uint32_t)(addr + size - cur_addr);
- read_size = MIN(bytes_left, MAX_RW_DATA_SIZE);
-
- cmd_create_read(cur_addr, ((uint8_t)read_size - 1),
- rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size);
- rd_cmd_buf.resp_size = read_size + 3;
-
- if (opr_send_cmds(&rd_cmd_buf, 1) != true)
- break;
-
- cmd_disp_read(resp_buf, read_size, cmd_idx,
- ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE));
-
- if (console)
- cmd_disp_data((resp_buf + 1), read_size);
- else
- fwrite((resp_buf + 1), 1, read_size, output_file_id);
-
- cmd_idx++;
- }
-
- DISPLAY_MSG(("\n"));
- if (!console)
- fclose(output_file_id);
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_execute_exit
- *
- * Parameters: addr - Start address to execute from.
- * Returns: none.
- * Side effects: ROM-Code is not in UART command mode anymore.
- * Description:
- * Execute code starting from a given address.
- * Memory address may be in Flash (SPI), DRAM (DDR) or SRAM.
- * No further communication with thr ROM-Code is expected at this point.
- *---------------------------------------------------------------------------
- */
-void opr_execute_exit(uint32_t addr)
-{
- uint32_t cmd_num;
-
- cmd_build_exec_exit(addr, cmd_buf, &cmd_num);
- if (opr_send_cmds(cmd_buf, cmd_num) != true)
- return;
-
- cmd_disp_exec_exit(resp_buf);
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_execute_return
- *
- * Parameters: addr - Start address to execute from.
- * Returns: true if successful, false in the case of an error.
- * Side effects:
- * Description:
- * Execute code starting from the given address and then check the result.
- * The executed code should return with the execution result.
- *---------------------------------------------------------------------------
- */
-bool opr_execute_return(uint32_t addr)
-{
- uint32_t cmd_num;
-
- cmd_build_exec_ret(addr, cmd_buf, &cmd_num);
- if (opr_send_cmds(cmd_buf, cmd_num) != true)
- return false;
-
- /*
- * Check the response command code is UFPP_FCALL_RSLT_CMD and
- * the return value from monitor is 0x03. (program finish and verify ok)
- */
- if (resp_buf[1] != (uint8_t)(UFPP_FCALL_RSLT_CMD)
- || resp_buf[2] != 0x03)
- return false;
- return true;
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_check_sync
- *
- * Parameters:
- * baudrate - baud rate to check
- *
- * Returns:
- * Side effects:
- * Description:
- * Checks whether the Host and the Core are synchoronized in the
- * specified baud rate
- *---------------------------------------------------------------------------
- */
-enum sync_result opr_check_sync(uint32_t baudrate)
-{
- uint32_t cmd_num;
- struct command_node *cur_cmd = cmd_buf;
- uint32_t bytes_read = 0;
- uint32_t i;
-
- port_cfg.baudrate = baudrate;
- if (!com_config_uart(port_handle, port_cfg))
- return SR_ERROR;
-
- cmd_build_sync(cmd_buf, &cmd_num);
-
- if (!com_port_write_bin(port_handle, cur_cmd->cmd, cur_cmd->cmd_size))
- return SR_ERROR;
-
- /* Allow several SYNC trials */
- for (i = 0; i < MAX_SYNC_TRIALS; i++) {
- bytes_read = com_port_read_bin(port_handle, resp_buf, 1);
-
- /* Quit if succeeded to read a response */
- if (bytes_read == 1)
- break;
- /* Otherwise give the ROM-Code time to answer */
- sleep(1);
- }
-
- if (bytes_read == 0)
- /*
- * Unable to read a response from ROM-Code in a reasonable
- * time
- */
- return SR_TIMEOUT;
-
- if (resp_buf[0] != (uint8_t)(UFPP_D2H_SYNC_CMD))
- /* ROM-Code response is not as expected */
- return SR_WRONG_DATA;
-
- /* Good response */
- return SR_OK;
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_scan_baudrate
- *
- * Parameters: none
- * Returns:
- * Side effects:
- * Description:
- * Scans the baud rate range by sending sync request to the core
- * and prints the response
- *---------------------------------------------------------------------------
- */
-bool opr_scan_baudrate(void)
-{
- uint32_t baud = 0;
- uint32_t step;
- enum sync_result sr;
- bool synched = false;
- bool data_received = false;
-
- /* Scan with HUGE STEPS */
- /* BR_BIG_STEP is percents */
- step = (BR_LOW_LIMIT * BR_BIG_STEP) / 100;
- for (baud = BR_LOW_LIMIT; baud < BR_HIGH_LIMIT; baud += step) {
- sr = opr_check_sync(baud);
- step = (baud * BR_BIG_STEP) / 100;
- if (sr == SR_OK) {
- printf("SR_OK: Baud rate - %d, resp_buf - 0x%x\n",
- baud, resp_buf[0]);
- synched = true;
- step = (baud * BR_SMALL_STEP) / 100;
- } else if (sr == SR_WRONG_DATA) {
- printf("SR_WRONG_DATA: Baud rate - %d, resp_buf - "
- "0x%x\n", baud, resp_buf[0]);
- data_received = true;
- step = (baud * BR_MEDIUM_STEP) / 100;
- } else if (sr == SR_TIMEOUT) {
- printf("SR_TIMEOUT: Baud rate - %d, resp_buf - 0x%x\n",
- baud, resp_buf[0]);
-
- if (synched || data_received)
- break;
- } else if (sr == SR_ERROR) {
- printf("SR_ERROR: Baud rate - %d, resp_buf - 0x%x\n",
- baud, resp_buf[0]);
- if (synched || data_received)
- break;
- } else
- printf("Unknown error code: Baud rate - %d, resp_buf - "
- "0x%x\n", baud, resp_buf[0]);
- }
-
- return true;
-}
-
-/*----------------------------------------------------------------------------
- * Function: opr_send_cmds
- *
- * Parameters: cmd_buf - Pointer to a Command Buffer.
- * cmd_num - Number of commands to send.
- * Returns: 1 if successful, 0 in the case of an error.
- * Side effects:
- * Description:
- * Send a group of commands through COM port.
- * A command is sent only after a valid response for the previous command
- * was received.
- *---------------------------------------------------------------------------
- */
-static bool opr_send_cmds(struct command_node *cmd_buf, uint32_t cmd_num)
-{
- struct command_node *cur_cmd = cmd_buf;
- uint32_t cmd;
- uint32_t read;
- time_t start;
- double elapsed_time;
-
- for (cmd = 0; cmd < cmd_num; cmd++, cur_cmd++) {
- if (com_port_write_bin(port_handle, cur_cmd->cmd,
- cur_cmd->cmd_size) == true) {
- time(&start);
-
- do {
- read = com_port_wait_read(port_handle);
- elapsed_time = difftime(time(NULL), start);
- } while ((read < cur_cmd->resp_size) &&
- (elapsed_time <= OPR_TIMEOUT));
- com_port_read_bin(port_handle, resp_buf,
- cur_cmd->resp_size);
-
- if (elapsed_time > OPR_TIMEOUT)
- display_color_msg(FAIL,
- "ERROR: [%d] bytes received for read, "
- "[%d] bytes are expected\n",
- read, cur_cmd->resp_size);
- } else {
- display_color_msg(FAIL,
- "ERROR: Failed to send Command number %d\n",
- cmd);
- return false;
- }
- }
-
- return true;
-}
-
diff --git a/util/uut/opr.h b/util/uut/opr.h
deleted file mode 100644
index 3b166f0c7e..0000000000
--- a/util/uut/opr.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-/* This file defines the UART console application operations. */
-
-#ifndef __UTIL_UUT_OPR_H
-#define __UTIL_UUT_OPR_H
-
-/*---------------------------------------------------------------------------
- * Constant definitions
- *---------------------------------------------------------------------------
- */
-
-/* Baud rate scan steps: */
-#define BR_BIG_STEP 20 /* in percents from current baud rate */
-#define BR_MEDIUM_STEP 10 /* in percents from current baud rate */
-#define BR_SMALL_STEP 1 /* in percents from current baud rate */
-#define BR_MIN_STEP 5 /* in absolute baud rate units */
-#define BR_LOW_LIMIT 400 /* Automatic BR detection starts at this value */
-#define BR_HIGH_LIMIT 150000 /* Automatic BR detection ends at this value */
-
-#define OPR_WRITE_MEM "wr" /* Write To Memory/Flash */
-#define OPR_READ_MEM "rd" /* Read From Memory/Flash */
-#define OPR_EXECUTE_EXIT "go" /* Execute a non-return code */
-#define OPR_EXECUTE_CONT "call" /* Execute returnable code */
-
-enum sync_result {
- SR_OK = 0x00,
- SR_WRONG_DATA = 0x01,
- SR_TIMEOUT = 0x02,
- SR_ERROR = 0x03
-};
-
-/*----------------------------------------------------------------------------
- * External Variables
- *---------------------------------------------------------------------------
- */
-extern struct comport_fields port_cfg;
-
-/*---------------------------------------------------------------------------
- * Functions prototypes
- *---------------------------------------------------------------------------
- */
-
-void opr_usage(void);
-bool opr_close_port(void);
-bool opr_open_port(const char *port_name, struct comport_fields port_cfg);
-bool opr_write_chunk(uint8_t *buffer, uint32_t addr, uint32_t size);
-bool opr_read_chunk(uint8_t *buffer, uint32_t addr, uint32_t size);
-void opr_write_mem(uint8_t *buffer, uint32_t addr, uint32_t size);
-void opr_read_mem(char *output, uint32_t addr, uint32_t size);
-void opr_execute_exit(uint32_t addr);
-bool opr_execute_return(uint32_t addr);
-bool opr_scan_baudrate(void);
-enum sync_result opr_check_sync(uint32_t baudrate);
-#endif /* __UTIL_UUT_OPR_H */