]> Git Repo - u-boot.git/blob - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sh
[u-boot.git] / arch / arm / mach-stm32mp / cmd_stm32prog / stm32prog_serial.c
1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4  */
5
6 #include <console.h>
7 #include <dm.h>
8 #include <dfu.h>
9 #include <malloc.h>
10 #include <serial.h>
11 #include <time.h>
12 #include <watchdog.h>
13 #include <asm/arch/sys_proto.h>
14 #include <dm/lists.h>
15 #include <dm/device-internal.h>
16 #include <linux/delay.h>
17 #include <linux/printk.h>
18 #include <asm/global_data.h>
19 #include "stm32prog.h"
20
21 /* - configuration part -----------------------------*/
22 #define USART_BL_VERSION        0x40    /* USART bootloader version V4.0*/
23 #define UBOOT_BL_VERSION        0x03    /* bootloader version V0.3*/
24
25 #define USART_RAM_BUFFER_SIZE   256     /* Size of USART_RAM_Buf buffer*/
26
27 /* - Commands -----------------------------*/
28 #define GET_CMD_COMMAND         0x00    /* Get CMD command*/
29 #define GET_VER_COMMAND         0x01    /* Get Version command*/
30 #define GET_ID_COMMAND          0x02    /* Get ID command*/
31 #define GET_PHASE_COMMAND       0x03    /* Get Phase command*/
32 #define RM_COMMAND              0x11    /* Read Memory command*/
33 #define READ_PART_COMMAND       0x12    /* Read Partition command*/
34 #define START_COMMAND           0x21    /* START command (Go)*/
35 #define DOWNLOAD_COMMAND        0x31    /* Download command*/
36 /* existing command for other STM32 but not used */
37 /* ERASE                        0x43 */
38 /* EXTENDED_ERASE               0x44 */
39 /* WRITE_UNPROTECTED            0x73 */
40 /* READOUT_PROTECT              0x82 */
41 /* READOUT_UNPROTECT            0x92 */
42
43 /* - miscellaneous defines ----------------------------------------*/
44 #define INIT_BYTE               0x7F    /*Init Byte ID*/
45 #define ACK_BYTE                0x79    /*Acknowlede Byte ID*/
46 #define NACK_BYTE               0x1F    /*No Acknowlede Byte ID*/
47 #define ABORT_BYTE              0x5F    /*ABORT*/
48
49 struct udevice *down_serial_dev;
50
51 const u8 cmd_id[] = {
52         GET_CMD_COMMAND,
53         GET_VER_COMMAND,
54         GET_ID_COMMAND,
55         GET_PHASE_COMMAND,
56         RM_COMMAND,
57         READ_PART_COMMAND,
58         START_COMMAND,
59         DOWNLOAD_COMMAND
60 };
61
62 #define NB_CMD sizeof(cmd_id)
63
64 /* with 115200 bauds, 20 ms allow to receive the 256 bytes buffer */
65 #define TIMEOUT_SERIAL_BUFFER   30
66
67 /* DFU support for serial *********************************************/
68 static struct dfu_entity *stm32prog_get_entity(struct stm32prog_data *data)
69 {
70         int alt_id;
71
72         if (!data->cur_part)
73                 if (data->phase == PHASE_FLASHLAYOUT)
74                         alt_id = 0;
75                 else
76                         return NULL;
77         else
78                 alt_id = data->cur_part->alt_id;
79
80         return dfu_get_entity(alt_id);
81 }
82
83 static int stm32prog_write(struct stm32prog_data *data, u8 *buffer,
84                            u32 buffer_size)
85 {
86         struct dfu_entity *dfu_entity;
87         u8 ret = 0;
88
89         dfu_entity = stm32prog_get_entity(data);
90         if (!dfu_entity)
91                 return -ENODEV;
92
93         ret = dfu_write(dfu_entity,
94                         buffer,
95                         buffer_size,
96                         data->dfu_seq);
97
98         if (ret) {
99                 stm32prog_err("DFU write failed [%d] cnt: %d",
100                               ret, data->dfu_seq);
101         }
102         data->dfu_seq++;
103         /* handle rollover as in driver/dfu/dfu.c */
104         data->dfu_seq &= 0xffff;
105         if (buffer_size == 0)
106                 data->dfu_seq = 0; /* flush done */
107
108         return ret;
109 }
110
111 static int stm32prog_read(struct stm32prog_data *data, u8 phase, u32 offset,
112                           u8 *buffer, u32 buffer_size)
113 {
114         struct dfu_entity *dfu_entity;
115         struct stm32prog_part_t *part;
116         u32 size;
117         int ret, i;
118
119         if (data->dfu_seq) {
120                 stm32prog_err("DFU write pending for phase %d, seq %d",
121                               data->phase, data->dfu_seq);
122                 return -EINVAL;
123         }
124         if (phase == PHASE_FLASHLAYOUT || phase > PHASE_LAST_USER) {
125                 stm32prog_err("read failed : phase %d is invalid", phase);
126                 return -EINVAL;
127         }
128         if (data->read_phase <= PHASE_LAST_USER &&
129             phase != data->read_phase) {
130                 /* clear previous read session */
131                 dfu_entity = dfu_get_entity(data->read_phase - 1);
132                 if (dfu_entity)
133                         dfu_transaction_cleanup(dfu_entity);
134         }
135
136         dfu_entity = NULL;
137         /* found partition for the expected phase */
138         for (i = 0; i < data->part_nb; i++) {
139                 part = &data->part_array[i];
140                 if (part->id == phase)
141                         dfu_entity = dfu_get_entity(part->alt_id);
142         }
143         if (!dfu_entity) {
144                 stm32prog_err("read failed : phase %d is unknown", phase);
145                 return -ENODEV;
146         }
147
148         /* clear pending read before to force offset */
149         if (dfu_entity->inited &&
150             (data->read_phase != phase || data->offset != offset))
151                 dfu_transaction_cleanup(dfu_entity);
152
153         /* initiate before to force offset */
154         if (!dfu_entity->inited) {
155                 ret = dfu_transaction_initiate(dfu_entity, true);
156                         if (ret < 0) {
157                                 stm32prog_err("DFU read init failed [%d] phase = %d offset = 0x%08x",
158                                               ret, phase, offset);
159                         return ret;
160                 }
161         }
162         /* force new offset */
163         if (dfu_entity->offset != offset)
164                 dfu_entity->offset = offset;
165         data->offset = offset;
166         data->read_phase = phase;
167         log_debug("\nSTM32 download read %s offset=0x%x\n",
168                   dfu_entity->name, offset);
169         ret = dfu_read(dfu_entity, buffer, buffer_size,
170                        dfu_entity->i_blk_seq_num);
171         if (ret < 0) {
172                 stm32prog_err("DFU read failed [%d] phase = %d offset = 0x%08x",
173                               ret, phase, offset);
174                 return ret;
175         }
176
177         size = ret;
178
179         if (size < buffer_size) {
180                 data->offset = 0;
181                 data->read_phase = PHASE_END;
182                 memset(buffer + size, 0, buffer_size - size);
183         } else {
184                 data->offset += size;
185         }
186
187         return ret;
188 }
189
190 /* UART access ***************************************************/
191 int stm32prog_serial_init(struct stm32prog_data *data, int link_dev)
192 {
193         struct udevice *dev = NULL;
194         struct dm_serial_ops *ops;
195         /* no parity, 8 bits, 1 stop */
196         u32 serial_config = SERIAL_DEFAULT_CONFIG;
197
198         down_serial_dev = NULL;
199
200         if (uclass_get_device_by_seq(UCLASS_SERIAL, link_dev, &dev)) {
201                 log_err("serial %d device not found\n", link_dev);
202                 return -ENODEV;
203         }
204
205         down_serial_dev = dev;
206
207         /* force silent console on uart only when used */
208         if (gd->cur_serial_dev == down_serial_dev)
209                 gd->flags |= GD_FLG_DISABLE_CONSOLE | GD_FLG_SILENT;
210         else
211                 gd->flags &= ~(GD_FLG_DISABLE_CONSOLE | GD_FLG_SILENT);
212
213         ops = serial_get_ops(down_serial_dev);
214
215         if (!ops) {
216                 log_err("serial %d = %s missing ops\n", link_dev, dev->name);
217                 return -ENODEV;
218         }
219         if (!ops->setconfig) {
220                 log_err("serial %d = %s missing setconfig\n", link_dev, dev->name);
221                 return -ENODEV;
222         }
223
224         clrsetbits_le32(&serial_config, SERIAL_PAR_MASK, SERIAL_PAR_EVEN);
225
226         data->buffer = memalign(CONFIG_SYS_CACHELINE_SIZE,
227                                 USART_RAM_BUFFER_SIZE);
228
229         return ops->setconfig(down_serial_dev, serial_config);
230 }
231
232 static void stm32prog_serial_flush(void)
233 {
234         struct dm_serial_ops *ops = serial_get_ops(down_serial_dev);
235         int err;
236
237         do {
238                 err = ops->getc(down_serial_dev);
239         } while (err != -EAGAIN);
240 }
241
242 static int stm32prog_serial_getc_err(void)
243 {
244         struct dm_serial_ops *ops = serial_get_ops(down_serial_dev);
245         int err;
246
247         do {
248                 err = ops->getc(down_serial_dev);
249                 if (err == -EAGAIN) {
250                         ctrlc();
251                         schedule();
252                 }
253         } while ((err == -EAGAIN) && (!had_ctrlc()));
254
255         return err;
256 }
257
258 static u8 stm32prog_serial_getc(void)
259 {
260         int err;
261
262         err = stm32prog_serial_getc_err();
263
264         return err >= 0 ? err : 0;
265 }
266
267 static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count)
268 {
269         struct dm_serial_ops *ops = serial_get_ops(down_serial_dev);
270         int err;
271         ulong start = get_timer(0);
272
273         do {
274                 err = ops->getc(down_serial_dev);
275                 if (err >= 0) {
276                         *buffer++ = err;
277                         *count -= 1;
278                 } else if (err == -EAGAIN) {
279                         ctrlc();
280                         schedule();
281                         if (get_timer(start) > TIMEOUT_SERIAL_BUFFER) {
282                                 err = -ETIMEDOUT;
283                                 break;
284                         }
285                 } else {
286                         break;
287                 }
288         } while (*count && !had_ctrlc());
289
290         return !!(err < 0);
291 }
292
293 static void stm32prog_serial_putc(u8 w_byte)
294 {
295         struct dm_serial_ops *ops = serial_get_ops(down_serial_dev);
296         int err;
297
298         do {
299                 err = ops->putc(down_serial_dev, w_byte);
300         } while (err == -EAGAIN);
301 }
302
303 /* Helper function ************************************************/
304 static u8 stm32prog_start(struct stm32prog_data *data, uintptr_t address)
305 {
306         u8 ret = 0;
307         struct dfu_entity *dfu_entity;
308
309         if (address < 0x100) {
310                 if (address == PHASE_OTP)
311                         return stm32prog_otp_start(data);
312
313                 if (address == PHASE_PMIC)
314                         return stm32prog_pmic_start(data);
315
316                 if (address == PHASE_RESET || address == PHASE_END) {
317                         data->cur_part = NULL;
318                         data->dfu_seq = 0;
319                         data->phase = address;
320                         return 0;
321                 }
322                 if (address != data->phase) {
323                         stm32prog_err("invalid received phase id %d, current phase is %d",
324                                       (u8)address, (u8)data->phase);
325                         return -EINVAL;
326                 }
327         }
328         /* check the last loaded partition */
329         if (address == DEFAULT_ADDRESS || address == data->phase) {
330                 switch (data->phase) {
331                 case PHASE_END:
332                 case PHASE_RESET:
333                 case PHASE_DO_RESET:
334                         data->cur_part = NULL;
335                         data->phase = PHASE_DO_RESET;
336                         return 0;
337                 }
338                 dfu_entity = stm32prog_get_entity(data);
339                 if (!dfu_entity)
340                         return -ENODEV;
341
342                 ret = dfu_flush(dfu_entity, NULL, 0, data->dfu_seq);
343                 if (ret) {
344                         stm32prog_err("DFU flush failed [%d]", ret);
345                         return ret;
346                 }
347                 data->dfu_seq = 0;
348
349                 printf("\n  received length = 0x%x\n", data->cursor);
350
351                 /* update DFU with received flashlayout */
352                 if (data->phase == PHASE_FLASHLAYOUT)
353                         stm32prog_dfu_init(data);
354         } else {
355                 void (*entry)(void) = (void *)address;
356
357                 printf("## Starting application at 0x%p ...\n", (void *)address);
358                 (*entry)();
359                 printf("## Application terminated\n");
360                 ret = -ENOEXEC;
361         }
362
363         return ret;
364 }
365
366 /**
367  * get_address() - Get address if it is valid
368  *
369  * @tmp_xor:            Current xor value to update
370  * Return: The address area
371  */
372 static uintptr_t get_address(u8 *tmp_xor)
373 {
374         uintptr_t address = 0x0;
375         u8 data;
376
377         data = stm32prog_serial_getc();
378         *tmp_xor ^= data;
379         address |= ((u32)data) << 24;
380
381         data = stm32prog_serial_getc();
382         address |= ((u32)data) << 16;
383         *tmp_xor ^= data;
384
385         data = stm32prog_serial_getc();
386         address |= ((u32)data) << 8;
387         *tmp_xor ^= data;
388
389         data = stm32prog_serial_getc();
390         address |= ((u32)data);
391         *tmp_xor ^= data;
392
393         return address;
394 }
395
396 static void stm32prog_serial_result(u8 result)
397 {
398         /* always flush fifo before to send result */
399         stm32prog_serial_flush();
400         stm32prog_serial_putc(result);
401 }
402
403 /* Command -----------------------------------------------*/
404 /**
405  * get_cmd_command() - Respond to Get command
406  *
407  * @data:               Current command context
408  */
409 static void get_cmd_command(struct stm32prog_data *data)
410 {
411         u32 counter = 0x0;
412
413         stm32prog_serial_putc(NB_CMD);
414         stm32prog_serial_putc(USART_BL_VERSION);
415
416         for (counter = 0; counter < NB_CMD; counter++)
417                 stm32prog_serial_putc(cmd_id[counter]);
418
419         stm32prog_serial_result(ACK_BYTE);
420 }
421
422 /**
423  * get_version_command() - Respond to Get Version command
424  *
425  * @data:               Current command context
426  */
427 static void get_version_command(struct stm32prog_data *data)
428 {
429         stm32prog_serial_putc(UBOOT_BL_VERSION);
430         stm32prog_serial_result(ACK_BYTE);
431 }
432
433 /**
434  * get_id_command() - Respond to Get ID command
435  *
436  * @data:               Current command context
437  */
438 static void get_id_command(struct stm32prog_data *data)
439 {
440         u32 cpu = get_cpu_dev();
441
442         /* Send Device IDCode */
443         stm32prog_serial_putc(0x1);
444         stm32prog_serial_putc((cpu >> 8) & 0xFF);
445         stm32prog_serial_putc(cpu & 0xFF);
446         stm32prog_serial_result(ACK_BYTE);
447 }
448
449 /**
450  * get_phase_command() - Respond to Get phase
451  *
452  * @data:               Current command context
453  */
454 static void get_phase_command(struct stm32prog_data *data)
455 {
456         char *err_msg = NULL;
457         u8 i, length = 0;
458         u32 destination = DEFAULT_ADDRESS; /* destination address */
459         int phase = data->phase;
460
461         if (phase == PHASE_RESET || phase == PHASE_DO_RESET) {
462                 err_msg = stm32prog_get_error(data);
463                 length = strlen(err_msg);
464         }
465         if (phase == PHASE_FLASHLAYOUT)
466                 destination = CONFIG_SYS_LOAD_ADDR;
467
468         stm32prog_serial_putc(length + 5);           /* Total length */
469         stm32prog_serial_putc(phase & 0xFF);         /* partition ID */
470         stm32prog_serial_putc(destination);          /* byte 1 of address */
471         stm32prog_serial_putc(destination >> 8);     /* byte 2 of address */
472         stm32prog_serial_putc(destination >> 16);    /* byte 3 of address */
473         stm32prog_serial_putc(destination >> 24);    /* byte 4 of address */
474
475         stm32prog_serial_putc(length);               /* Information length */
476         for (i = 0; i < length; i++)
477                 stm32prog_serial_putc(err_msg[i]);
478         stm32prog_serial_result(ACK_BYTE);
479
480         if (phase == PHASE_RESET)
481                 stm32prog_do_reset(data);
482 }
483
484 /**
485  * read_memory_command() - Read data from memory
486  *
487  * @data:               Current command context
488  */
489 static void read_memory_command(struct stm32prog_data *data)
490 {
491         uintptr_t address = 0x0;
492         u8 rcv_data = 0x0, tmp_xor = 0x0;
493         u32 counter = 0x0;
494
495         /* Read memory address */
496         address = get_address(&tmp_xor);
497
498         /* If address memory is not received correctly */
499         rcv_data = stm32prog_serial_getc();
500         if (rcv_data != tmp_xor) {
501                 stm32prog_serial_result(NACK_BYTE);
502                 return;
503         }
504
505         stm32prog_serial_result(ACK_BYTE);
506
507         /* Read the number of bytes to be received:
508          * Max NbrOfData = Data + 1 = 256
509          */
510         rcv_data = stm32prog_serial_getc();
511         tmp_xor = ~rcv_data;
512         if (stm32prog_serial_getc() != tmp_xor) {
513                 stm32prog_serial_result(NACK_BYTE);
514                 return;
515         }
516
517         /* If checksum is correct send ACK */
518         stm32prog_serial_result(ACK_BYTE);
519
520         /* Send data to the host:
521          * Number of data to read = data + 1
522          */
523         for (counter = (rcv_data + 1); counter != 0; counter--)
524                 stm32prog_serial_putc(*(u8 *)(address++));
525 }
526
527 /**
528  * start_command() - Respond to start command
529  *
530  * Jump to user application in RAM or partition check
531  *
532  * @data:               Current command context
533  */
534 static void start_command(struct stm32prog_data *data)
535 {
536         uintptr_t address = 0;
537         u8 tmp_xor = 0x0;
538         u8 ret, rcv_data;
539
540         /* Read memory address */
541         address = get_address(&tmp_xor);
542
543         /* If address memory is not received correctly */
544         rcv_data = stm32prog_serial_getc();
545         if (rcv_data != tmp_xor) {
546                 stm32prog_serial_result(NACK_BYTE);
547                 return;
548         }
549         /* validate partition */
550         ret = stm32prog_start(data, address);
551
552         if (ret)
553                 stm32prog_serial_result(ABORT_BYTE);
554         else
555                 stm32prog_serial_result(ACK_BYTE);
556 }
557
558 /**
559  * download_command() - Respond to download command
560  *
561  * Write data to not volatile memory, Flash
562  *
563  * @data:               Current command context
564  */
565 static void download_command(struct stm32prog_data *data)
566 {
567         u32 address = 0x0;
568         u8 my_xor = 0x0;
569         u8 rcv_xor;
570         u32 counter = 0x0, codesize = 0x0;
571         u8 *ramaddress = 0;
572         u8 rcv_data = 0x0;
573         u32 cursor = data->cursor;
574         long size = 0;
575         u8 operation;
576         u32 packet_number;
577         u32 result = ACK_BYTE;
578         u8 ret;
579         bool error;
580         int rcv;
581
582         address = get_address(&my_xor);
583
584         /* If address memory is not received correctly */
585         rcv_xor = stm32prog_serial_getc();
586         if (rcv_xor != my_xor) {
587                 result = NACK_BYTE;
588                 goto end;
589         }
590
591         /* If address valid send ACK */
592         stm32prog_serial_result(ACK_BYTE);
593
594         /* get packet number and operation type */
595         operation = (u8)((u32)address >> 24);
596         packet_number = ((u32)(((u32)address << 8))) >> 8;
597
598         switch (operation) {
599         /* supported operation */
600         case PHASE_FLASHLAYOUT:
601         case PHASE_OTP:
602         case PHASE_PMIC:
603                 break;
604         default:
605                 result = NACK_BYTE;
606                 goto end;
607         }
608         /* check the packet number */
609         if (packet_number == 0) {
610                 /* erase: re-initialize the image_header struct */
611                 data->packet_number = 0;
612                 cursor = 0;
613                 data->cursor = 0;
614                 /*idx = cursor;*/
615         } else {
616                 data->packet_number++;
617         }
618
619         /* Check with the number of current packet if the device receive
620          * the true packet
621          */
622         if (packet_number != data->packet_number) {
623                 data->packet_number--;
624                 result = NACK_BYTE;
625                 goto end;
626         }
627
628         /*-- Read number of bytes to be written and data -----------*/
629
630         /* Read the number of bytes to be written:
631          * Max NbrOfData = data + 1 <= 256
632          */
633         rcv_data = stm32prog_serial_getc();
634
635         /* NbrOfData to write = data + 1 */
636         codesize = rcv_data + 0x01;
637
638         if (codesize > USART_RAM_BUFFER_SIZE) {
639                 result = NACK_BYTE;
640                 goto end;
641         }
642
643         /* Checksum Initialization */
644         my_xor = rcv_data;
645
646         /* UART receive data and send to Buffer */
647         counter = codesize;
648         error = stm32prog_serial_get_buffer(data->buffer, &counter);
649
650         /* read checksum */
651         if (!error) {
652                 rcv = stm32prog_serial_getc_err();
653                 error = !!(rcv < 0);
654                 rcv_xor = rcv;
655         }
656
657         if (error) {
658                 printf("transmission error on packet %d, byte %d\n",
659                        packet_number, codesize - counter);
660                 /* waiting end of packet before flush & NACK */
661                 mdelay(TIMEOUT_SERIAL_BUFFER);
662                 data->packet_number--;
663                 result = NACK_BYTE;
664                 goto end;
665         }
666
667         /* Compute Checksum */
668         ramaddress = data->buffer;
669         for (counter = codesize; counter != 0; counter--)
670                 my_xor ^= *(ramaddress++);
671
672         /* If Checksum is incorrect */
673         if (rcv_xor != my_xor) {
674                 printf("checksum error on packet %d\n",
675                        packet_number);
676                 /* wait to be sure that all data are received
677                  * in the FIFO before flush
678                  */
679                 mdelay(TIMEOUT_SERIAL_BUFFER);
680                 data->packet_number--;
681                 result = NACK_BYTE;
682                 goto end;
683         }
684
685         switch (operation) {
686         case PHASE_OTP:
687                 size = codesize;
688                 ret = stm32prog_otp_write(data, cursor, data->buffer, &size);
689                 break;
690
691         case PHASE_PMIC:
692                 size = codesize;
693                 ret = stm32prog_pmic_write(data, cursor, data->buffer, &size);
694                 break;
695
696         default:
697                 ret = stm32prog_write(data, data->buffer, codesize);
698                 break;
699         }
700
701         if (ret)
702                 result = ABORT_BYTE;
703         else
704                 /* Update current position in buffer */
705                 data->cursor += codesize;
706
707 end:
708         stm32prog_serial_result(result);
709 }
710
711 /**
712  * read_partition() - Respond to read command
713  *
714  * Read data from not volatile memory, Flash
715  *
716  * @data:               Current command context
717  */
718 static void read_partition_command(struct stm32prog_data *data)
719 {
720         u32 i, part_id, codesize, offset = 0, rcv_data;
721         long size;
722         u8 tmp_xor;
723         int res;
724         u8 buffer[256];
725
726         part_id = stm32prog_serial_getc();
727         tmp_xor = part_id;
728
729         offset = get_address(&tmp_xor);
730
731         rcv_data = stm32prog_serial_getc();
732         if (rcv_data != tmp_xor) {
733                 log_debug("1st checksum received = %x, computed %x\n",
734                           rcv_data, tmp_xor);
735                 goto error;
736         }
737         stm32prog_serial_putc(ACK_BYTE);
738
739         /* NbrOfData to read = data + 1 */
740         rcv_data = stm32prog_serial_getc();
741         codesize = rcv_data + 0x01;
742         tmp_xor = rcv_data;
743
744         rcv_data = stm32prog_serial_getc();
745         if ((rcv_data ^ tmp_xor) != 0xFF) {
746                 log_debug("2nd checksum received = %x, computed %x\n",
747                           rcv_data, tmp_xor);
748                 goto error;
749         }
750
751         log_debug("%s : %x\n", __func__, part_id);
752         rcv_data = 0;
753         switch (part_id) {
754         case PHASE_OTP:
755                 size = codesize;
756                 if (!stm32prog_otp_read(data, offset, buffer, &size))
757                         rcv_data = size;
758                 break;
759         case PHASE_PMIC:
760                 size = codesize;
761                 if (!stm32prog_pmic_read(data, offset, buffer, &size))
762                         rcv_data = size;
763                 break;
764         default:
765                 res = stm32prog_read(data, part_id, offset,
766                                      buffer, codesize);
767                 if (res > 0)
768                         rcv_data = res;
769                 break;
770         }
771         if (rcv_data > 0) {
772                 stm32prog_serial_putc(ACK_BYTE);
773                 /*----------- Send data to the host -----------*/
774                 for (i = 0; i < rcv_data; i++)
775                         stm32prog_serial_putc(buffer[i]);
776                 /*----------- Send filler to the host -----------*/
777                 for (; i < codesize; i++)
778                         stm32prog_serial_putc(0x0);
779                 return;
780         }
781         stm32prog_serial_result(ABORT_BYTE);
782         return;
783
784 error:
785         stm32prog_serial_result(NACK_BYTE);
786 }
787
788 /* MAIN function = SERIAL LOOP ***********************************************/
789
790 /**
791  * stm32prog_serial_loop() - USART bootloader Loop routine
792  *
793  * @data:               Current command context
794  * Return: true if reset is needed after loop
795  */
796 bool stm32prog_serial_loop(struct stm32prog_data *data)
797 {
798         u32 counter = 0x0;
799         u8 command = 0x0;
800         u8 found;
801         int phase = data->phase;
802
803         /* element of cmd_func need to aligned with cmd_id[]*/
804         void (*cmd_func[NB_CMD])(struct stm32prog_data *) = {
805                 /* GET_CMD_COMMAND */   get_cmd_command,
806                 /* GET_VER_COMMAND */   get_version_command,
807                 /* GET_ID_COMMAND */    get_id_command,
808                 /* GET_PHASE_COMMAND */ get_phase_command,
809                 /* RM_COMMAND */        read_memory_command,
810                 /* READ_PART_COMMAND */ read_partition_command,
811                 /* START_COMMAND */     start_command,
812                 /* DOWNLOAD_COMMAND */  download_command
813         };
814
815         /* flush and NACK pending command received during u-boot init
816          * request command reemit
817          */
818         stm32prog_serial_result(NACK_BYTE);
819
820         clear_ctrlc(); /* forget any previous Control C */
821         while (!had_ctrlc()) {
822                 phase = data->phase;
823
824                 if (phase == PHASE_DO_RESET)
825                         return true;
826
827                 /* Get the user command: read first byte */
828                 command = stm32prog_serial_getc();
829
830                 if (command == INIT_BYTE) {
831                         puts("\nConnected\n");
832                         stm32prog_serial_result(ACK_BYTE);
833                         continue;
834                 }
835
836                 found = 0;
837                 for (counter = 0; counter < NB_CMD; counter++)
838                         if (cmd_id[counter] == command) {
839                                 found = 1;
840                                 break;
841                         }
842                 if (found)
843                         if ((command ^ stm32prog_serial_getc()) != 0xFF)
844                                 found = 0;
845                 if (!found) {
846                         /* wait to be sure that all data are received
847                          * in the FIFO before flush (CMD and XOR)
848                          */
849                         mdelay(3);
850                         stm32prog_serial_result(NACK_BYTE);
851                 } else {
852                         stm32prog_serial_result(ACK_BYTE);
853                         cmd_func[counter](data);
854                 }
855                 schedule();
856         }
857
858         /* clean device */
859         if (gd->cur_serial_dev == down_serial_dev) {
860                 /* restore console on uart */
861                 gd->flags &= ~(GD_FLG_DISABLE_CONSOLE | GD_FLG_SILENT);
862         }
863         down_serial_dev = NULL;
864
865         return false; /* no reset after ctrlc */
866 }
This page took 0.082124 seconds and 4 git commands to generate.