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 BLUEKITCHEN 24 * GMBH 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 <stdio.h> 42 #include <inttypes.h> 43 44 #include "btstack_chipset_intel_firmware.h" 45 46 #include "bluetooth.h" 47 #include "btstack_debug.h" 48 #include "btstack_event.h" 49 #include "btstack_run_loop.h" 50 #include "btstack_util.h" 51 #include "hci.h" 52 #include "hci_cmd.h" 53 #include "hci_dump.h" 54 55 #ifdef _MSC_VER 56 // ignore deprecated warning for fopen 57 #pragma warning(disable : 4996) 58 #endif 59 60 // assert outgoing and incoming hci packet buffers can hold max hci command resp. event packet 61 #if HCI_OUTGOING_PACKET_BUFFER_SIZE < (HCI_CMD_HEADER_SIZE + 255) 62 #error "HCI_OUTGOING_PACKET_BUFFER_SIZE to small. Outgoing HCI packet buffer to small for largest HCI Command packet. Please set HCI_ACL_PAYLOAD_SIZE to 258 or higher." 63 #endif 64 #if HCI_INCOMING_PACKET_BUFFER_SIZE < (HCI_EVENT_HEADER_SIZE_HEADER_SIZE + 255) 65 #error "HCI_INCOMING_PACKET_BUFFER_SIZE to small. Incoming HCI packet buffer to small for largest HCI Event packet. Please set HCI_ACL_PAYLOAD_SIZE to 257 or higher." 66 #endif 67 68 // Vendor specific structs 69 70 typedef struct { 71 uint8_t status; 72 uint8_t hw_platform; 73 uint8_t hw_variant; 74 uint8_t hw_revision; 75 uint8_t fw_variant; 76 uint8_t fw_revision; 77 uint8_t fw_build_num; 78 uint8_t fw_build_ww; 79 uint8_t fw_build_yy; 80 uint8_t fw_patch_num; 81 } intel_version_t; 82 83 typedef struct { 84 uint8_t status; 85 uint8_t otp_format; 86 uint8_t otp_content; 87 uint8_t otp_patch; 88 uint16_t dev_revid; 89 uint8_t secure_boot; 90 uint8_t key_from_hdr; 91 uint8_t key_type; 92 uint8_t otp_lock; 93 uint8_t api_lock; 94 uint8_t debug_lock; 95 bd_addr_t otp_bdaddr; 96 uint8_t min_fw_build_nn; 97 uint8_t min_fw_build_cw; 98 uint8_t min_fw_build_yy; 99 uint8_t limited_cce; 100 uint8_t unlocked_state; 101 } intel_boot_params_t; 102 103 // Vendor sepcific commands 104 105 static const hci_cmd_t hci_intel_read_version = { 106 0xfc05, "1" 107 }; 108 static const hci_cmd_t hci_intel_read_secure_boot_params = { 109 0xfc0d, "" 110 }; 111 112 static const hci_cmd_t hci_intel_reset_param = { 113 0xfc01, "11111111" 114 }; 115 116 static const hci_cmd_t hci_intel_set_event_mask = { 117 0xfc52, "11111111" 118 }; 119 120 static const hci_cmd_t hci_intel_fc9f = { 121 0xfc9f, "1" 122 }; 123 124 // state 125 126 const char * firmware_path = "."; 127 128 const hci_transport_t * transport; 129 130 static int state = 0; 131 132 static uint8_t hci_outgoing[300]; 133 static uint8_t fw_buffer[300]; 134 135 static uint8_t hw_variant; 136 static uint16_t dev_revid; 137 138 static FILE * fw_file; 139 static size_t fw_offset; 140 141 static void (*done)(int result); 142 143 // functions 144 145 static int transport_send_packet(uint8_t packet_type, const uint8_t * packet, uint16_t size){ 146 hci_dump_packet(HCI_COMMAND_DATA_PACKET, 0, (uint8_t*) packet, size); 147 return transport->send_packet(packet_type, (uint8_t *) packet, size); 148 } 149 150 static int transport_send_cmd_va_arg(const hci_cmd_t *cmd, va_list argptr){ 151 uint8_t * packet = hci_outgoing; 152 uint16_t size = hci_cmd_create_from_template(packet, cmd, argptr); 153 return transport_send_packet(HCI_COMMAND_DATA_PACKET, packet, size); 154 } 155 156 static int transport_send_cmd(const hci_cmd_t *cmd, ...){ 157 va_list argptr; 158 va_start(argptr, cmd); 159 int res = transport_send_cmd_va_arg(cmd, argptr); 160 va_end(argptr); 161 return res; 162 } 163 164 static int transport_send_intel_secure(uint8_t fragment_type, const uint8_t * data, uint8_t len){ 165 little_endian_store_16(hci_outgoing, 0, 0xfc09); 166 hci_outgoing[2] = 1 + len; 167 hci_outgoing[3] = fragment_type; 168 memcpy(&hci_outgoing[4], data, len); 169 uint16_t size = 3 + 1 + len; 170 return transport_send_packet(HCI_ACL_DATA_PACKET, hci_outgoing, size); 171 } 172 173 static int transport_send_intel_ddc(const uint8_t * data, uint8_t len){ 174 little_endian_store_16(hci_outgoing, 0, 0xfc8b); 175 hci_outgoing[2] = len; 176 memcpy(&hci_outgoing[3], data, len); 177 uint16_t size = 3 + len; 178 return transport_send_packet(HCI_COMMAND_DATA_PACKET, hci_outgoing, size); 179 } 180 181 static void state_machine(uint8_t * packet); 182 183 // read data from fw file and send it via intel_secure + update state 184 static int intel_send_fragment(uint8_t fragment_type, uint8_t len){ 185 size_t res = fread(fw_buffer, 1, len, fw_file); 186 log_info("offset %6" PRId32 ", read %3u -> res %" PRId32 "", (int32_t)fw_offset, len, (int32_t)res); 187 fw_offset += res; 188 state++; 189 return transport_send_intel_secure(fragment_type, fw_buffer, len); 190 } 191 192 // read data from ddc file and send iva intel ddc command 193 // @returns -1 on eof 194 static int intel_send_ddc(void){ 195 size_t res; 196 // read len 197 res = fread(fw_buffer, 1, 1, fw_file); 198 log_info("offset %6" PRId32 ", read 1 -> res %" PRId32 "", (int32_t)fw_offset, (int32_t)res); 199 if (res == 0) return -1; 200 uint8_t len = fw_buffer[0]; 201 fw_offset += 1; 202 res = fread(&fw_buffer[1], 1, len, fw_file); 203 log_info("offset %6" PRId32 ", read %u -> res %" PRId32 "", (int32_t)fw_offset, 1, (int32_t)res); 204 return transport_send_intel_ddc(fw_buffer, 1 + len); 205 } 206 207 static void dump_intel_version(intel_version_t * version){ 208 log_info("status 0x%02x", version->status); 209 log_info("hw_platform 0x%02x", version->hw_platform); 210 log_info("hw_variant 0x%02x", version->hw_variant); 211 log_info("hw_revision 0x%02x", version->hw_revision); 212 log_info("fw_variant 0x%02x", version->fw_variant); 213 log_info("fw_revision 0x%02x", version->fw_revision); 214 log_info("fw_build_num 0x%02x", version->fw_build_num); 215 log_info("fw_build_ww 0x%02x", version->fw_build_ww); 216 log_info("fw_build_yy 0x%02x", version->fw_build_yy); 217 log_info("fw_patch_num 0x%02x", version->fw_patch_num); 218 } 219 220 static void dump_intel_boot_params(intel_boot_params_t * boot_params){ 221 bd_addr_t addr; 222 reverse_bd_addr(boot_params->otp_bdaddr, addr); 223 log_info("Device revision: %u", dev_revid); 224 log_info("Secure Boot: %s", boot_params->secure_boot ? "enabled" : "disabled"); 225 log_info("OTP lock: %s", boot_params->otp_lock ? "enabled" : "disabled"); 226 log_info("API lock: %s", boot_params->api_lock ? "enabled" : "disabled"); 227 log_info("Debug lock: %s", boot_params->debug_lock ? "enabled" : "disabled"); 228 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); 229 log_info("OTC BD_ADDR: %s", bd_addr_to_str(addr)); 230 } 231 232 static int vendor_firmware_complete_received; 233 static int waiting_for_command_complete; 234 235 static void state_machine(uint8_t * packet){ 236 intel_version_t * version; 237 intel_boot_params_t * boot_params; 238 size_t res; 239 size_t buffer_offset; 240 bd_addr_t addr; 241 char fw_path[300]; 242 243 if (packet){ 244 // firmware upload complete event? 245 if (packet[0] == 0xff && packet[2] == 0x06) { 246 vendor_firmware_complete_received = 1; 247 } 248 249 // command complete 250 if (packet[0] == 0x0e){ 251 waiting_for_command_complete = 0; 252 } 253 } 254 255 switch (state){ 256 case 0: 257 state++; 258 transport_send_cmd(&hci_reset); 259 break; 260 case 1: 261 // check if HCI Reset was supported 262 if (packet[0] == 0x0e && packet[1] == 0x04 && packet[3] == 0x03 && packet[4] == 0x0c && packet[5] == 0x00){ 263 log_info("HCI Reset was successful, no need for firmware upload / or not an Intel chipset"); 264 (*done)(0); 265 break; 266 } 267 268 // Read Intel Version 269 state++; 270 transport_send_cmd(&hci_intel_read_version, 0xff); 271 break; 272 case 2: 273 version = (intel_version_t*) hci_event_command_complete_get_return_parameters(packet); 274 dump_intel_version(version); 275 276 hw_variant = version->hw_variant; 277 278 // fw_variant = 0x06 bootloader mode / 0x23 operational mode 279 if (version->fw_variant == 0x23) { 280 (*done)(0); 281 break; 282 } 283 284 if (version->fw_variant != 0x06){ 285 log_error("unknown fw_variant 0x%02x", version->fw_variant); 286 break; 287 } 288 289 // Read Intel Secure Boot Params 290 state++; 291 transport_send_cmd(&hci_intel_read_secure_boot_params); 292 break; 293 case 3: 294 boot_params = (intel_boot_params_t *) hci_event_command_complete_get_return_parameters(packet); 295 dump_intel_boot_params(boot_params); 296 297 reverse_bd_addr(boot_params->otp_bdaddr, addr); 298 dev_revid = little_endian_read_16((uint8_t*)&boot_params->dev_revid, 0); 299 300 // assert commmand complete is required 301 if (boot_params->limited_cce != 0) break; 302 303 // firmware file 304 snprintf(fw_path, sizeof(fw_path), "%s/ibt-%u-%u.sfi", firmware_path, hw_variant, dev_revid); 305 log_info("Open firmware %s", fw_path); 306 printf("Firwmare %s\n", fw_path); 307 308 // open firmware file 309 fw_offset = 0; 310 fw_file = fopen(fw_path, "rb"); 311 if (!fw_file){ 312 log_error("can't open file %s", fw_path); 313 (*done)(1); 314 return; 315 } 316 317 vendor_firmware_complete_received = 0; 318 319 // send CCS segment - offset 0 320 intel_send_fragment(0x00, 128); 321 break; 322 case 4: 323 // send public key / part 1 - offset 128 324 intel_send_fragment(0x03, 128); 325 break; 326 case 5: 327 // send public key / part 2 - offset 384 328 intel_send_fragment(0x03, 128); 329 break; 330 case 6: 331 // skip 4 bytes 332 res = fread(fw_buffer, 1, 4, fw_file); 333 log_info("read res %d", (int)res); 334 fw_offset += res; 335 336 // send signature / part 1 - offset 388 337 intel_send_fragment(0x02, 128); 338 break; 339 case 7: 340 // send signature / part 2 - offset 516 341 intel_send_fragment(0x02, 128); 342 break; 343 case 8: 344 // send firmware chunks - offset 644 345 // chunk len must be 4 byte aligned 346 // multiple commands can be combined 347 buffer_offset = 0; 348 do { 349 res = fread(&fw_buffer[buffer_offset], 1, 3, fw_file); 350 log_info("fw_offset %6" PRId32 ", buffer_offset %" PRId32 ", read %3u -> res %" PRId32 "", (int32_t)fw_offset, (int32_t)buffer_offset, 3, (int32_t)res); 351 fw_offset += res; 352 if (res == 0 ){ 353 // EOF 354 log_info("End of file"); 355 fclose(fw_file); 356 fw_file = NULL; 357 state++; 358 break; 359 } 360 int param_len = fw_buffer[buffer_offset + 2]; 361 buffer_offset += 3; 362 if (param_len){ 363 res = fread(&fw_buffer[buffer_offset], 1, param_len, fw_file); 364 fw_offset += res; 365 buffer_offset += res; 366 } 367 } while ((buffer_offset & 3) != 0); 368 369 if (buffer_offset == 0) break; 370 371 waiting_for_command_complete = 1; 372 transport_send_intel_secure(0x01, fw_buffer, (uint8_t) buffer_offset); 373 break; 374 375 case 9: 376 // expect Vendor Specific Event 0x06 377 if (!vendor_firmware_complete_received) break; 378 379 printf("Firmware upload complete\n"); 380 log_info("Vendor Event 0x06 - firmware complete"); 381 382 // Reset Params - constants from Windows Intel driver 383 state++; 384 transport_send_cmd(&hci_intel_reset_param, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x04, 0x00); 385 break; 386 387 case 10: 388 // expect Vendor Specific Event 0x02 389 if (packet[0] != 0xff) break; 390 if (packet[2] != 0x02) break; 391 392 printf("Firmware operational\n"); 393 log_info("Vendor Event 0x02 - firmware operational"); 394 395 // Read Intel Version 396 state++; 397 transport_send_cmd(&hci_intel_read_version); 398 break; 399 400 case 11: 401 version = (intel_version_t*) hci_event_command_complete_get_return_parameters(packet); 402 dump_intel_version(version); 403 404 // ddc config 405 snprintf(fw_path, sizeof(fw_path), "%s/ibt-%u-%u.ddc", firmware_path, hw_variant, dev_revid); 406 log_info("Open DDC %s", fw_path); 407 408 // open ddc file 409 fw_offset = 0; 410 fw_file = fopen(fw_path, "rb"); 411 if (!fw_file){ 412 log_error("can't open file %s", fw_path); 413 414 (*done)(1); 415 return; 416 } 417 418 // load ddc 419 state++; 420 421 /* fall through */ 422 423 case 12: 424 res = intel_send_ddc(); 425 if (res == 0) break; 426 427 // DDC download complete 428 state++; 429 log_info("Load DDC Complete"); 430 431 432 // Set Intel event mask 0xfc52 433 state++; 434 transport_send_cmd(&hci_intel_set_event_mask, 0x87, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 435 break; 436 437 case 13: 438 // 9F FC 01 00 439 state++; 440 transport_send_cmd(&hci_intel_fc9f, 0x00); 441 break; 442 443 case 14: 444 (*done)(0); 445 break; 446 447 default: 448 break; 449 } 450 } 451 452 static void transport_packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ 453 UNUSED(packet_type); 454 // we also get events with packet_type ACL from the controller 455 hci_dump_packet(HCI_EVENT_PACKET, 1, packet, size); 456 switch (hci_event_packet_get_type(packet)){ 457 case HCI_EVENT_COMMAND_COMPLETE: 458 case HCI_EVENT_VENDOR_SPECIFIC: 459 state_machine(packet); 460 break; 461 default: 462 break; 463 } 464 } 465 466 void btstack_chipset_intel_set_firmware_path(const char * path){ 467 firmware_path = path; 468 } 469 470 void btstack_chipset_intel_download_firmware(const hci_transport_t * hci_transport, void (*callback)(int result)){ 471 472 done = callback; 473 474 transport = hci_transport;; 475 // transport->init(NULL); 476 transport->register_packet_handler(&transport_packet_handler); 477 transport->open(); 478 479 // get started 480 state = 0; 481 state_machine(NULL); 482 } 483