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