cros_ec_python.commands.general
General / test commands
1""" 2General / test commands 3""" 4 5from typing import Final, Literal 6import struct 7from ..baseclass import CrosEcClass 8from ..constants.COMMON import * 9from ..exceptions import ECError 10 11EC_CMD_PROTO_VERSION: Final = 0x0000 12 13 14def proto_version(ec: CrosEcClass) -> UInt32: 15 """ 16 Get protocol version, used to deal with non-backward compatible protocol changes. 17 :param ec: The CrOS_EC object. 18 :return: The protocol version as a uint32. 19 """ 20 resp = ec.command(0, EC_CMD_PROTO_VERSION, 0, 4) 21 return struct.unpack("<I", resp)[0] 22 23 24EC_CMD_HELLO: Final = 0x0001 25 26 27def hello(ec: CrosEcClass, in_data: UInt32) -> UInt32: 28 """ 29 Hello. This is a simple command to test the EC is responsive to commands. 30 :param ec: The CrOS_EC object. 31 :param in_data: Pass anything here. Max value is 0xFFFFFFFF (uint32). 32 :return: Output will be in_data + 0x01020304. 33 """ 34 data = struct.pack("<I", in_data) 35 resp = ec.command(0, EC_CMD_HELLO, len(data), 4, data) 36 return struct.unpack("<I", resp)[0] 37 38 39EC_CMD_GET_VERSION: Final = 0x0002 40 41 42def get_version(ec: CrosEcClass, version: Literal[0, 1] = 0) -> dict[str, str | int]: 43 """ 44 Get version number 45 :param ec: The CrOS_EC object. 46 :param version: The command version to use. Default is 0. 47 :return: The EC version as strings, and the RW status. 48 """ 49 match version: 50 case 0: 51 resp = ec.command(version, EC_CMD_GET_VERSION, 0, 32 + 32 + 32 + 4) 52 unpacked = struct.unpack("<32s32s32sI", resp) 53 return { 54 "version_string_ro": unpacked[0].decode("utf-8").rstrip("\x00"), 55 "version_string_rw": unpacked[1].decode("utf-8").rstrip("\x00"), 56 "reserved": unpacked[2].decode("utf-8").rstrip("\x00"), 57 "current_image": unpacked[3] 58 } 59 case 1: 60 resp = ec.command(version, EC_CMD_GET_VERSION, 0, 32 + 32 + 32 + 4 + 32) 61 unpacked = struct.unpack("<32s32s32sI32s", resp) 62 return { 63 "version_string_ro": unpacked[0].decode("utf-8").rstrip("\x00"), 64 "version_string_rw": unpacked[1].decode("utf-8").rstrip("\x00"), 65 "cros_fwid_ro": unpacked[2].decode("utf-8").rstrip("\x00"), 66 "current_image": unpacked[3], 67 "crod_fwid_rw": unpacked[4].decode("utf-8").rstrip("\x00") 68 } 69 case _: 70 raise NotImplementedError 71 72 73# Read test - OBSOLETE 74EC_CMD_READ_TEST: Final = 0x0003 75 76EC_CMD_GET_BUILD_INFO: Final = 0x0004 77 78 79def get_build_info(ec: CrosEcClass) -> str: 80 """ 81 Get build information 82 :param ec: The CrOS_EC object. 83 :return: The build info as a string. 84 """ 85 # 0xEC is the max command size on some platforms 86 resp = ec.command(0, EC_CMD_GET_BUILD_INFO, 0, 0xEC, warn=False) 87 return resp.decode("utf-8").rstrip("\x00") 88 89 90EC_CMD_GET_CHIP_INFO: Final = 0x0005 91 92 93def get_chip_info(ec: CrosEcClass) -> dict[str, str]: 94 """ 95 Get chip info 96 :param ec: The CrOS_EC object. 97 :return: The chip vendor, name, and revision as strings. 98 """ 99 resp = ec.command(0, EC_CMD_GET_CHIP_INFO, 0, 32 + 32 + 32) 100 unpacked = struct.unpack("<32s32s32s", resp) 101 return { 102 "vendor": unpacked[0].decode("utf-8").rstrip("\x00"), 103 "name": unpacked[1].decode("utf-8").rstrip("\x00"), 104 "revision": unpacked[2].decode("utf-8").rstrip("\x00") 105 } 106 107 108EC_CMD_GET_BOARD_VERSION: Final = 0x0006 109 110 111def get_board_version(ec: CrosEcClass) -> UInt16: 112 """ 113 Get board HW version 114 :param ec: The CrOS_EC object. 115 :return: The board version as a uint16. 116 """ 117 resp = ec.command(0, EC_CMD_GET_BOARD_VERSION, 0, 2) 118 return struct.unpack("<H", resp)[0] 119 120 121# use the CrOS_EC.memmap method instead 122EC_CMD_READ_MEMMAP: Final = 0x0007 123 124EC_CMD_GET_CMD_VERSIONS: Final = 0x0008 125 126 127def get_cmd_versions(ec: CrosEcClass, cmd: UInt8 | UInt16, version: Literal[0, 1] | None = None) -> UInt32 | None: 128 """ 129 Read versions supported for a command. 130 :param ec: The CrOS_EC object. 131 :param cmd: The command to get the supported versions of. 132 :param version: The command version to use. Default is guess. 0 supports 8 bit commands, 1 supports 16 bit commands. 133 :return: The supported versions as a bitmask. Bit 0 is version 0, bit 1 is version 1, etc. None if the command is not supported. 134 """ 135 if version is None: 136 version = int(cmd > 0xFF) 137 try: 138 match version: 139 case 0: 140 resp = ec.command(version, EC_CMD_GET_CMD_VERSIONS, 1, 4, struct.pack("<B", cmd)) 141 return struct.unpack("<I", resp)[0] 142 case 1: 143 resp = ec.command(version, EC_CMD_GET_CMD_VERSIONS, 2, 4, struct.pack("<H", cmd)) 144 return struct.unpack("<I", resp)[0] 145 case _: 146 raise NotImplementedError 147 except ECError as e: 148 # EC_CMD_GET_CMD_VERSIONS throws EC_RES_INVALID_PARAM if the command is not supported 149 # Catch this and return None 150 if e.status == EcStatus.EC_RES_INVALID_PARAM.value: 151 return None 152 # Otherwise, raise the exception 153 raise e 154 155 156EC_CMD_GET_COMMS_STATUS: Final = 0x0009 157 158EC_CMD_TEST_PROTOCOL: Final = 0x000A 159 160 161def test_protocol(ec: CrosEcClass, result: UInt32, ret_len: UInt32, buf: bytes, in_size: Int32 | None = None) -> bytes: 162 """ 163 Fake a variety of responses, purely for testing purposes. 164 :param ec: The CrOS_EC object. 165 :param result: Result for the EC to return. 166 :param ret_len: Length of return data. 167 :param buf: Data to return. Max length is 32 bytes. 168 :param in_size: Max number of bytes to accept from the EC. None to use ret_len. 169 :return: The data returned. 170 """ 171 data = struct.pack("<II", result, ret_len) + buf 172 resp = ec.command(0, EC_CMD_TEST_PROTOCOL, len(data), in_size or ret_len, data) 173 return resp 174 175 176EC_CMD_GET_PROTOCOL_INFO: Final = 0x000B 177 178 179def get_protocol_info(ec: CrosEcClass) -> dict[str, int]: 180 """ 181 Get protocol info 182 :param ec: The CrOS_EC object. 183 :return: The protocol info as a dictionary. 184 """ 185 resp = ec.command(0, EC_CMD_GET_PROTOCOL_INFO, 0, 12) 186 unpacked = struct.unpack("<IHHI", resp) 187 return { 188 "protocol_versions": unpacked[0], 189 "max_request_packet_size": unpacked[1], 190 "max_response_packet_size": unpacked[2], 191 "flags": unpacked[3] 192 }
15def proto_version(ec: CrosEcClass) -> UInt32: 16 """ 17 Get protocol version, used to deal with non-backward compatible protocol changes. 18 :param ec: The CrOS_EC object. 19 :return: The protocol version as a uint32. 20 """ 21 resp = ec.command(0, EC_CMD_PROTO_VERSION, 0, 4) 22 return struct.unpack("<I", resp)[0]
Get protocol version, used to deal with non-backward compatible protocol changes.
Parameters
- ec: The CrOS_EC object.
Returns
The protocol version as a uint32.
28def hello(ec: CrosEcClass, in_data: UInt32) -> UInt32: 29 """ 30 Hello. This is a simple command to test the EC is responsive to commands. 31 :param ec: The CrOS_EC object. 32 :param in_data: Pass anything here. Max value is 0xFFFFFFFF (uint32). 33 :return: Output will be in_data + 0x01020304. 34 """ 35 data = struct.pack("<I", in_data) 36 resp = ec.command(0, EC_CMD_HELLO, len(data), 4, data) 37 return struct.unpack("<I", resp)[0]
Hello. This is a simple command to test the EC is responsive to commands.
Parameters
- ec: The CrOS_EC object.
- in_data: Pass anything here. Max value is 0xFFFFFFFF (uint32).
Returns
Output will be in_data + 0x01020304.
43def get_version(ec: CrosEcClass, version: Literal[0, 1] = 0) -> dict[str, str | int]: 44 """ 45 Get version number 46 :param ec: The CrOS_EC object. 47 :param version: The command version to use. Default is 0. 48 :return: The EC version as strings, and the RW status. 49 """ 50 match version: 51 case 0: 52 resp = ec.command(version, EC_CMD_GET_VERSION, 0, 32 + 32 + 32 + 4) 53 unpacked = struct.unpack("<32s32s32sI", resp) 54 return { 55 "version_string_ro": unpacked[0].decode("utf-8").rstrip("\x00"), 56 "version_string_rw": unpacked[1].decode("utf-8").rstrip("\x00"), 57 "reserved": unpacked[2].decode("utf-8").rstrip("\x00"), 58 "current_image": unpacked[3] 59 } 60 case 1: 61 resp = ec.command(version, EC_CMD_GET_VERSION, 0, 32 + 32 + 32 + 4 + 32) 62 unpacked = struct.unpack("<32s32s32sI32s", resp) 63 return { 64 "version_string_ro": unpacked[0].decode("utf-8").rstrip("\x00"), 65 "version_string_rw": unpacked[1].decode("utf-8").rstrip("\x00"), 66 "cros_fwid_ro": unpacked[2].decode("utf-8").rstrip("\x00"), 67 "current_image": unpacked[3], 68 "crod_fwid_rw": unpacked[4].decode("utf-8").rstrip("\x00") 69 } 70 case _: 71 raise NotImplementedError
Get version number
Parameters
- ec: The CrOS_EC object.
- version: The command version to use. Default is 0.
Returns
The EC version as strings, and the RW status.
80def get_build_info(ec: CrosEcClass) -> str: 81 """ 82 Get build information 83 :param ec: The CrOS_EC object. 84 :return: The build info as a string. 85 """ 86 # 0xEC is the max command size on some platforms 87 resp = ec.command(0, EC_CMD_GET_BUILD_INFO, 0, 0xEC, warn=False) 88 return resp.decode("utf-8").rstrip("\x00")
Get build information
Parameters
- ec: The CrOS_EC object.
Returns
The build info as a string.
94def get_chip_info(ec: CrosEcClass) -> dict[str, str]: 95 """ 96 Get chip info 97 :param ec: The CrOS_EC object. 98 :return: The chip vendor, name, and revision as strings. 99 """ 100 resp = ec.command(0, EC_CMD_GET_CHIP_INFO, 0, 32 + 32 + 32) 101 unpacked = struct.unpack("<32s32s32s", resp) 102 return { 103 "vendor": unpacked[0].decode("utf-8").rstrip("\x00"), 104 "name": unpacked[1].decode("utf-8").rstrip("\x00"), 105 "revision": unpacked[2].decode("utf-8").rstrip("\x00") 106 }
Get chip info
Parameters
- ec: The CrOS_EC object.
Returns
The chip vendor, name, and revision as strings.
112def get_board_version(ec: CrosEcClass) -> UInt16: 113 """ 114 Get board HW version 115 :param ec: The CrOS_EC object. 116 :return: The board version as a uint16. 117 """ 118 resp = ec.command(0, EC_CMD_GET_BOARD_VERSION, 0, 2) 119 return struct.unpack("<H", resp)[0]
Get board HW version
Parameters
- ec: The CrOS_EC object.
Returns
The board version as a uint16.
128def get_cmd_versions(ec: CrosEcClass, cmd: UInt8 | UInt16, version: Literal[0, 1] | None = None) -> UInt32 | None: 129 """ 130 Read versions supported for a command. 131 :param ec: The CrOS_EC object. 132 :param cmd: The command to get the supported versions of. 133 :param version: The command version to use. Default is guess. 0 supports 8 bit commands, 1 supports 16 bit commands. 134 :return: The supported versions as a bitmask. Bit 0 is version 0, bit 1 is version 1, etc. None if the command is not supported. 135 """ 136 if version is None: 137 version = int(cmd > 0xFF) 138 try: 139 match version: 140 case 0: 141 resp = ec.command(version, EC_CMD_GET_CMD_VERSIONS, 1, 4, struct.pack("<B", cmd)) 142 return struct.unpack("<I", resp)[0] 143 case 1: 144 resp = ec.command(version, EC_CMD_GET_CMD_VERSIONS, 2, 4, struct.pack("<H", cmd)) 145 return struct.unpack("<I", resp)[0] 146 case _: 147 raise NotImplementedError 148 except ECError as e: 149 # EC_CMD_GET_CMD_VERSIONS throws EC_RES_INVALID_PARAM if the command is not supported 150 # Catch this and return None 151 if e.status == EcStatus.EC_RES_INVALID_PARAM.value: 152 return None 153 # Otherwise, raise the exception 154 raise e
Read versions supported for a command.
Parameters
- ec: The CrOS_EC object.
- cmd: The command to get the supported versions of.
- version: The command version to use. Default is guess. 0 supports 8 bit commands, 1 supports 16 bit commands.
Returns
The supported versions as a bitmask. Bit 0 is version 0, bit 1 is version 1, etc. None if the command is not supported.
162def test_protocol(ec: CrosEcClass, result: UInt32, ret_len: UInt32, buf: bytes, in_size: Int32 | None = None) -> bytes: 163 """ 164 Fake a variety of responses, purely for testing purposes. 165 :param ec: The CrOS_EC object. 166 :param result: Result for the EC to return. 167 :param ret_len: Length of return data. 168 :param buf: Data to return. Max length is 32 bytes. 169 :param in_size: Max number of bytes to accept from the EC. None to use ret_len. 170 :return: The data returned. 171 """ 172 data = struct.pack("<II", result, ret_len) + buf 173 resp = ec.command(0, EC_CMD_TEST_PROTOCOL, len(data), in_size or ret_len, data) 174 return resp
Fake a variety of responses, purely for testing purposes.
Parameters
- ec: The CrOS_EC object.
- result: Result for the EC to return.
- ret_len: Length of return data.
- buf: Data to return. Max length is 32 bytes.
- in_size: Max number of bytes to accept from the EC. None to use ret_len.
Returns
The data returned.
180def get_protocol_info(ec: CrosEcClass) -> dict[str, int]: 181 """ 182 Get protocol info 183 :param ec: The CrOS_EC object. 184 :return: The protocol info as a dictionary. 185 """ 186 resp = ec.command(0, EC_CMD_GET_PROTOCOL_INFO, 0, 12) 187 unpacked = struct.unpack("<IHHI", resp) 188 return { 189 "protocol_versions": unpacked[0], 190 "max_request_packet_size": unpacked[1], 191 "max_response_packet_size": unpacked[2], 192 "flags": unpacked[3] 193 }
Get protocol info
Parameters
- ec: The CrOS_EC object.
Returns
The protocol info as a dictionary.