• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
8import logging
9import os
10import subprocess
11
12
13class ChipUtilsError(Exception):
14    """Error in the chip_utils module."""
15
16
17
18class 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
57class ps8751(generic_chip):
58
59    """The PS8751 TCPC chip."""
60
61    chip_name = 'ps8751'
62    fw_name = 'ps8751_a3'
63    extension = '.bin'
64    hash_extension = '.hash'
65    cbfs_bin_name = fw_name + extension
66    cbfs_hash_name = fw_name + hash_extension
67
68    def fw_ver_from_hash(self, blob):
69        """Return the firmware version encoded in the firmware hash."""
70
71        return blob[1]
72
73    def compute_hash_bytes(self):
74        """Generates the firmware blob hash."""
75
76        if self.fw_ver is None:
77            raise ChipUtilsError('fw_ver not initialized')
78
79        h = bytearray(2)
80        h[0] = 0xa3
81        h[1] = self.fw_ver
82        return h
83
84
85class anx3429(generic_chip):
86
87    """The ANX3429 TCPC chip."""
88
89    chip_name = 'anx3429'
90    fw_name = 'anx3429_ocm'
91    extension = '.bin'
92    hash_extension = '.hash'
93    cbfs_bin_name = fw_name + extension
94    cbfs_hash_name = fw_name + hash_extension
95
96    def fw_ver_from_hash(self, blob):
97        """Return the firmware version encoded in the passed-in hash content."""
98        return blob[0]
99
100    def compute_hash_bytes(self):
101        """Generates the firmware blob hash."""
102
103        if self.fw_ver is None:
104            raise ChipUtilsError('fw_ver not initialized')
105
106        h = bytearray(1)
107        h[0] = self.fw_ver
108        return h
109
110
111class ecrw(generic_chip):
112
113    """Chrome EC RW portion."""
114
115    chip_name = 'ecrw'
116    fw_name = 'ecrw'
117    extension = ''
118    hash_extension = '.hash'
119    cbfs_bin_name = fw_name
120    cbfs_hash_name = fw_name + hash_extension
121
122    def compute_hash_bytes(self):
123        """Generates the firmware blob hash."""
124
125        if self.fw_file_name is None:
126            raise ChipUtilsError('fw_file_name not initialized')
127
128        if not os.path.exists(self.fw_file_name):
129            raise ChipUtilsError('%s does not exist' % self.fw_file_name)
130
131        # openssl outputs the result to stdout
132        cmd = 'openssl dgst -sha256 -binary %s' % self.fw_file_name
133        result = subprocess.check_output(cmd, shell=True)
134        return bytearray(result)
135
136
137chip_id_map = {
138        'ecrw': ecrw,
139        '0x8751': ps8751,
140        '0x3429': anx3429,
141}
142