xref: /btstack/chipset/intel/btstack_chipset_intel_firmware.c (revision 046b44372d25c7bd6fe78e5cf6e5176a1979f437)
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