1 /* 2 * Copyright (C) 2018 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "btstack_chipset_intel_firmware.c" 39 40 #include <fcntl.h> 41 #include <unistd.h> 42 #include <stdio.h> 43 44 #include "btstack_chipset_intel_firmware.h" 45 #include "hci_cmd.h" 46 #include "bluetooth.h" 47 #include "hci_dump.h" 48 #include "btstack_event.h" 49 #include "btstack_debug.h" 50 #include "btstack_util.h" 51 #include "btstack_run_loop.h" 52 53 // Vendor specific structs 54 55 typedef struct { 56 uint8_t status; 57 uint8_t hw_platform; 58 uint8_t hw_variant; 59 uint8_t hw_revision; 60 uint8_t fw_variant; 61 uint8_t fw_revision; 62 uint8_t fw_build_num; 63 uint8_t fw_build_ww; 64 uint8_t fw_build_yy; 65 uint8_t fw_patch_num; 66 } intel_version_t; 67 68 typedef struct { 69 uint8_t status; 70 uint8_t otp_format; 71 uint8_t otp_content; 72 uint8_t otp_patch; 73 uint16_t dev_revid; 74 uint8_t secure_boot; 75 uint8_t key_from_hdr; 76 uint8_t key_type; 77 uint8_t otp_lock; 78 uint8_t api_lock; 79 uint8_t debug_lock; 80 bd_addr_t otp_bdaddr; 81 uint8_t min_fw_build_nn; 82 uint8_t min_fw_build_cw; 83 uint8_t min_fw_build_yy; 84 uint8_t limited_cce; 85 uint8_t unlocked_state; 86 } intel_boot_params_t; 87 88 // Vendor sepcific commands 89 90 static const hci_cmd_t hci_intel_read_version = { 91 0xfc05, "" 92 }; 93 static const hci_cmd_t hci_intel_read_secure_boot_params = { 94 0xfc0d, "" 95 }; 96 97 static const hci_cmd_t hci_intel_reset_param = { 98 0xfc01, "11111111" 99 }; 100 101 static const hci_cmd_t hci_intel_set_event_mask = { 102 0xfc52, "11111111" 103 }; 104 105 static const hci_cmd_t hci_intel_fc9f = { 106 0xfc9f, "1" 107 }; 108 109 // state 110 111 const char * firmware_path = "."; 112 113 const hci_transport_t * transport; 114 115 static int state = 0; 116 117 static uint8_t hci_outgoing[300]; 118 static uint8_t fw_buffer[300]; 119 120 static uint8_t hw_variant; 121 static uint16_t dev_revid; 122 123 static FILE * fw_file; 124 static uint32_t fw_offset; 125 126 static void (*done)(int result); 127 128 // functions 129 130 static int transport_send_packet(uint8_t packet_type, const uint8_t * packet, uint16_t size){ 131 hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t*) packet, size); 132 return transport->send_packet(packet_type, (uint8_t *) packet, size); 133 } 134 135 static int transport_send_cmd_va_arg(const hci_cmd_t *cmd, va_list argptr){ 136 uint8_t * packet = hci_outgoing; 137 uint16_t size = hci_cmd_create_from_template(packet, cmd, argptr); 138 return transport_send_packet(HCI_COMMAND_DATA_PACKET, packet, size); 139 } 140 141 static int transport_send_cmd(const hci_cmd_t *cmd, ...){ 142 va_list argptr; 143 va_start(argptr, cmd); 144 int res = transport_send_cmd_va_arg(cmd, argptr); 145 va_end(argptr); 146 return res; 147 } 148 149 static int transport_send_intel_secure(uint8_t fragment_type, const uint8_t * data, uint16_t len){ 150 little_endian_store_16(hci_outgoing, 0, 0xfc09); 151 hci_outgoing[2] = 1 + len; 152 hci_outgoing[3] = fragment_type; 153 memcpy(&hci_outgoing[4], data, len); 154 uint16_t size = 3 + 1 + len; 155 return transport_send_packet(HCI_ACL_DATA_PACKET, hci_outgoing, size); 156 } 157 158 static int transport_send_intel_ddc(const uint8_t * data, uint16_t len){ 159 little_endian_store_16(hci_outgoing, 0, 0xfc8b); 160 hci_outgoing[2] = len; 161 memcpy(&hci_outgoing[3], data, len); 162 uint16_t size = 3 + len; 163 return transport_send_packet(HCI_COMMAND_DATA_PACKET, hci_outgoing, size); 164 } 165 166 static void state_machine(uint8_t * packet); 167 168 // read data from fw file and send it via intel_secure + update state 169 static int intel_send_fragment(uint8_t fragment_type, uint16_t len){ 170 int res = fread(fw_buffer, 1, len, fw_file); 171 log_info("offset %6u, read %3u -> res %d", fw_offset, len, res); 172 fw_offset += res; 173 state++; 174 return transport_send_intel_secure(fragment_type, fw_buffer, len); 175 } 176 177 // read data from ddc file and send iva intel ddc command 178 // @returns -1 on eof 179 static int intel_send_ddc(void){ 180 int res; 181 // read len 182 res = fread(fw_buffer, 1, 1, fw_file); 183 log_info("offset %6u, read 1 -> res %d", fw_offset, res); 184 if (res == 0) return -1; 185 uint8_t len = fw_buffer[0]; 186 fw_offset += 1; 187 res = fread(&fw_buffer[1], 1, len, fw_file); 188 log_info("offset %6u, read %u -> res %d", fw_offset, 1, res); 189 return transport_send_intel_ddc(fw_buffer, 1 + len); 190 } 191 192 static void dump_intel_version(intel_version_t * version){ 193 log_info("status 0x%02x", version->status); 194 log_info("hw_platform 0x%02x", version->hw_platform); 195 log_info("hw_variant 0x%02x", version->hw_variant); 196 log_info("hw_revision 0x%02x", version->hw_revision); 197 log_info("fw_variant 0x%02x", version->fw_variant); 198 log_info("fw_revision 0x%02x", version->fw_revision); 199 log_info("fw_build_num 0x%02x", version->fw_build_num); 200 log_info("fw_build_ww 0x%02x", version->fw_build_ww); 201 log_info("fw_build_yy 0x%02x", version->fw_build_yy); 202 log_info("fw_patch_num 0x%02x", version->fw_patch_num); 203 } 204 205 static void dump_intel_boot_params(intel_boot_params_t * boot_params){ 206 bd_addr_t addr; 207 reverse_bd_addr(boot_params->otp_bdaddr, addr); 208 log_info("Device revision: %u", dev_revid); 209 log_info("Secure Boot: %s", boot_params->secure_boot ? "enabled" : "disabled"); 210 log_info("OTP lock: %s", boot_params->otp_lock ? "enabled" : "disabled"); 211 log_info("API lock: %s", boot_params->api_lock ? "enabled" : "disabled"); 212 log_info("Debug lock: %s", boot_params->debug_lock ? "enabled" : "disabled"); 213 log_info("Minimum firmware build %u week %u %u", boot_params->min_fw_build_nn, boot_params->min_fw_build_cw, 2000 + boot_params->min_fw_build_yy); 214 log_info("OTC BD_ADDR: %s", bd_addr_to_str(addr)); 215 } 216 217 static int vendor_firmware_complete_received; 218 static int waiting_for_command_complete; 219 220 static void state_machine(uint8_t * packet){ 221 intel_version_t * version; 222 intel_boot_params_t * boot_params; 223 int res; 224 uint16_t buffer_offset; 225 bd_addr_t addr; 226 char fw_path[300]; 227 228 if (packet){ 229 // firmware upload complete event? 230 if (packet[0] == 0xff && packet[2] == 0x06) { 231 vendor_firmware_complete_received = 1; 232 } 233 234 // command complete 235 if (packet[0] == 0x0e){ 236 waiting_for_command_complete = 0; 237 } 238 } 239 240 switch (state){ 241 case 0: 242 state++; 243 transport_send_cmd(&hci_reset); 244 break; 245 case 1: 246 // check if HCI Reset was supported 247 if (packet[0] == 0x0e && packet[1] == 0x04 && packet[3] == 0x03 && packet[4] == 0x0c && packet[5] == 0x00){ 248 log_info("HCI Reset was successful, no need for firmware upload / or not an Intel chipset"); 249 (*done)(0); 250 break; 251 } 252 253 // Read Intel Version 254 state++; 255 transport_send_cmd(&hci_intel_read_version); 256 break; 257 case 2: 258 version = (intel_version_t*) hci_event_command_complete_get_return_parameters(packet); 259 dump_intel_version(version); 260 261 hw_variant = version->hw_variant; 262 263 // fw_variant = 0x06 bootloader mode / 0x23 operational mode 264 if (version->fw_variant == 0x23) { 265 (*done)(0); 266 break; 267 } 268 269 if (version->fw_variant != 0x06){ 270 log_error("unknown fw_variant 0x%02x", version->fw_variant); 271 break; 272 } 273 274 // Read Intel Secure Boot Params 275 state++; 276 transport_send_cmd(&hci_intel_read_secure_boot_params); 277 break; 278 case 3: 279 boot_params = (intel_boot_params_t *) hci_event_command_complete_get_return_parameters(packet); 280 dump_intel_boot_params(boot_params); 281 282 reverse_bd_addr(boot_params->otp_bdaddr, addr); 283 dev_revid = little_endian_read_16((uint8_t*)&boot_params->dev_revid, 0); 284 285 // assert commmand complete is required 286 if (boot_params->limited_cce != 0) break; 287 288 // firmware file 289 snprintf(fw_path, sizeof(fw_path), "%s/ibt-%u-%u.sfi", firmware_path, hw_variant, dev_revid); 290 log_info("Open firmware %s", fw_path); 291 printf("Firwmare %s\n", fw_path); 292 293 // open firmware file 294 fw_offset = 0; 295 fw_file = fopen(fw_path, "rb"); 296 if (!fw_file){ 297 log_error("can't open file %s", fw_path); 298 (*done)(1); 299 return; 300 } 301 302 vendor_firmware_complete_received = 0; 303 304 // send CCS segment - offset 0 305 intel_send_fragment(0x00, 128); 306 break; 307 case 4: 308 // send public key / part 1 - offset 128 309 intel_send_fragment(0x03, 128); 310 break; 311 case 5: 312 // send public key / part 2 - offset 384 313 intel_send_fragment(0x03, 128); 314 break; 315 case 6: 316 // skip 4 bytes 317 res = fread(fw_buffer, 1, 4, fw_file); 318 log_info("read res %d", res); 319 fw_offset += res; 320 321 // send signature / part 1 - offset 388 322 intel_send_fragment(0x02, 128); 323 break; 324 case 7: 325 // send signature / part 2 - offset 516 326 intel_send_fragment(0x02, 128); 327 break; 328 case 8: 329 // send firmware chunks - offset 644 330 // chunk len must be 4 byte aligned 331 // multiple commands can be combined 332 buffer_offset = 0; 333 do { 334 res = fread(&fw_buffer[buffer_offset], 1, 3, fw_file); 335 log_info("fw_offset %6u, buffer_offset %u, read %3u -> res %d", fw_offset, buffer_offset, 3, res); 336 fw_offset += res; 337 if (res == 0 ){ 338 // EOF 339 log_info("End of file"); 340 fclose(fw_file); 341 fw_file = NULL; 342 state++; 343 break; 344 } 345 int param_len = fw_buffer[buffer_offset + 2]; 346 buffer_offset += 3; 347 if (param_len){ 348 res = fread(&fw_buffer[buffer_offset], 1, param_len, fw_file); 349 fw_offset += res; 350 buffer_offset += res; 351 } 352 } while ((buffer_offset & 3) != 0); 353 354 if (buffer_offset == 0) break; 355 356 waiting_for_command_complete = 1; 357 transport_send_intel_secure(0x01, fw_buffer, buffer_offset); 358 break; 359 360 case 9: 361 // expect Vendor Specific Event 0x06 362 if (!vendor_firmware_complete_received) break; 363 364 printf("Firmware upload complete\n"); 365 log_info("Vendor Event 0x06 - firmware complete"); 366 367 // Reset Params - constants from Windows Intel driver 368 state++; 369 transport_send_cmd(&hci_intel_reset_param, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x04, 0x00); 370 break; 371 372 case 10: 373 // expect Vendor Specific Event 0x02 374 if (packet[0] != 0xff) break; 375 if (packet[2] != 0x02) break; 376 377 printf("Firmware operational\n"); 378 log_info("Vendor Event 0x02 - firmware operational"); 379 380 // Read Intel Version 381 state++; 382 transport_send_cmd(&hci_intel_read_version); 383 break; 384 385 case 11: 386 version = (intel_version_t*) hci_event_command_complete_get_return_parameters(packet); 387 dump_intel_version(version); 388 389 // ddc config 390 snprintf(fw_path, sizeof(fw_path), "%s/ibt-%u-%u.ddc", firmware_path, hw_variant, dev_revid); 391 log_info("Open DDC %s", fw_path); 392 393 // open ddc file 394 fw_offset = 0; 395 fw_file = fopen(fw_path, "rb"); 396 if (!fw_file){ 397 log_error("can't open file %s", fw_path); 398 399 (*done)(1); 400 return; 401 } 402 403 // load ddc 404 state++; 405 406 /* fall through */ 407 408 case 12: 409 res = intel_send_ddc(); 410 if (res == 0) break; 411 412 // DDC download complete 413 state++; 414 log_info("Load DDC Complete"); 415 416 417 // Set Intel event mask 0xfc52 418 state++; 419 transport_send_cmd(&hci_intel_set_event_mask, 0x87, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 420 break; 421 422 case 13: 423 // 9F FC 01 00 424 state++; 425 transport_send_cmd(&hci_intel_fc9f, 0x00); 426 break; 427 428 case 14: 429 (*done)(0); 430 break; 431 432 default: 433 break; 434 } 435 } 436 437 static void transport_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 438 UNUSED(packet_type); 439 // we also get events with packet_type ACL from the controller 440 hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size); 441 switch (hci_event_packet_get_type(packet)){ 442 case HCI_EVENT_COMMAND_COMPLETE: 443 case HCI_EVENT_VENDOR_SPECIFIC: 444 state_machine(packet); 445 break; 446 default: 447 break; 448 } 449 } 450 451 void btstack_chipset_intel_set_firmware_path(const char * path){ 452 firmware_path = path; 453 } 454 455 void btstack_chipset_intel_download_firmware(const hci_transport_t * hci_transport, void (*callback)(int result)){ 456 457 done = callback; 458 459 transport = hci_transport;; 460 // transport->init(NULL); 461 transport->register_packet_handler(&transport_packet_handler); 462 transport->open(); 463 464 // get started 465 state = 0; 466 state_machine(NULL); 467 } 468