• 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    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
83class 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
108class 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
131chip_id_map = {
132    '0x8751': ps8751,
133    '0x3429': anx3429,
134}
135