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