Home | History | Annotate | Download | only in cros
      1 # Copyright 2017 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """A collection of classes representing TCPC firmware blobs.
      6 """
      7 
      8 import logging
      9 import os
     10 import subprocess
     11 
     12 
     13 class ChipUtilsError(Exception):
     14     """Error in the chip_utils module."""
     15 
     16 
     17 
     18 class generic_chip(object):
     19 
     20     """A chip we don't actually support."""
     21 
     22     chip_name = 'unknown'
     23     fw_name = None
     24 
     25     def __init__(self):
     26         self.fw_ver = None
     27         self.fw_file_name = None
     28 
     29     def set_fw_ver_from_string(self, version):
     30         """Sets version property from string."""
     31         self.fw_ver = int(version, 0)
     32 
     33     def set_from_file(self, file_name):
     34         """Sets chip params from file name.
     35 
     36         The typical firmware blob file name format is: <chip>_0x00.bin
     37 
     38         Args:
     39             file_name: Firmware blob file name.
     40 
     41         Raises:
     42             ValueError: Failed to decompose firmware file name.
     43         """
     44 
     45         basename = os.path.basename(file_name)
     46         if not basename.startswith(self.chip_name):
     47             raise ValueError('filename did not start with %s' % self.chip_name)
     48         fname = basename.split('.')[0]
     49         if '_' in fname:
     50             rev = fname.split('_')[-1]
     51             self.set_fw_ver_from_string(rev)
     52         else:
     53             logging.info('No fw ver found in filename %s', basename)
     54         self.fw_file_name = file_name
     55 
     56 
     57 class ps8751(generic_chip):
     58 
     59     """The PS8751 TCPC chip."""
     60 
     61     chip_name = 'ps8751'
     62     fw_name = 'ps8751_a3'
     63     cbfs_bin_name = fw_name + '.bin'
     64     cbfs_hash_name = fw_name + '.hash'
     65 
     66     def fw_ver_from_hash(self, blob):
     67         """Return the firmware version encoded in the firmware hash."""
     68 
     69         return blob[1]
     70 
     71     def compute_hash_bytes(self):
     72         """Generates the firmware blob hash."""
     73 
     74         if self.fw_ver is None:
     75             raise ChipUtilsError('fw_ver not initialized')
     76 
     77         h = bytearray(2)
     78         h[0] = 0xa3
     79         h[1] = self.fw_ver
     80         return h
     81 
     82 
     83 class anx3429(generic_chip):
     84 
     85     """The ANX3429 TCPC chip."""
     86 
     87     chip_name = 'anx3429'
     88     fw_name = 'anx3429_ocm'
     89     cbfs_bin_name = fw_name + '.bin'
     90     cbfs_hash_name = fw_name + '.hash'
     91 
     92     def fw_ver_from_hash(self, blob):
     93         """Return the firmware version encoded in the firmware hash."""
     94 
     95         return blob[0]
     96 
     97     def compute_hash_bytes(self):
     98         """Generates the firmware blob hash."""
     99 
    100         if self.fw_ver is None:
    101             raise ChipUtilsError('fw_ver not initialized')
    102 
    103         h = bytearray(1)
    104         h[0] = self.fw_ver
    105         return h
    106 
    107 
    108 class ecrw(generic_chip):
    109 
    110     """Chrome EC RW portion."""
    111 
    112     chip_name = 'ecrw'
    113     fw_name = 'ecrw'
    114     cbfs_bin_name = fw_name
    115     cbfs_hash_name = fw_name + '.hash'
    116 
    117     def compute_hash_bytes(self):
    118         """Generates the firmware blob hash."""
    119 
    120         if self.fw_file_name is None:
    121             raise ChipUtilsError('fw_file_name not initialized')
    122 
    123         if not os.path.exists(self.fw_file_name):
    124             raise ChipUtilsError('%s does not exist' % self.fw_file_name)
    125 
    126         # openssl outputs the result to stdout
    127         cmd = 'openssl dgst -sha256 -binary %s' % self.fw_file_name
    128         return subprocess.check_output(cmd, shell=True)
    129 
    130 
    131 chip_id_map = {
    132     '0x8751': ps8751,
    133     '0x3429': anx3429,
    134 }
    135