]> git.ipfire.org Git - thirdparty/u-boot.git/blame - arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / arch / arm / mach-stm32mp / cmd_stm32prog / stm32prog_serial.c
CommitLineData
468f0508
PD
1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
4 */
5
d678a59d 6#include <common.h>
468f0508 7#include <console.h>
a00867b4 8#include <dm.h>
468f0508
PD
9#include <dfu.h>
10#include <malloc.h>
11#include <serial.h>
12#include <watchdog.h>
69446dee 13#include <asm/arch/sys_proto.h>
468f0508
PD
14#include <dm/lists.h>
15#include <dm/device-internal.h>
c05ed00a 16#include <linux/delay.h>
1e94b46f 17#include <linux/printk.h>
401d1c4f 18#include <asm/global_data.h>
468f0508
PD
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*/
69446dee 24
468f0508
PD
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
49struct udevice *down_serial_dev;
50
51const 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
d4358a64
PD
64/* with 115200 bauds, 20 ms allow to receive the 256 bytes buffer */
65#define TIMEOUT_SERIAL_BUFFER 30
66
468f0508
PD
67/* DFU support for serial *********************************************/
68static 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
83static 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
111static 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;
711b5bc0
PD
167 log_debug("\nSTM32 download read %s offset=0x%x\n",
168 dfu_entity->name, offset);
468f0508
PD
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 ***************************************************/
191int stm32prog_serial_init(struct stm32prog_data *data, int link_dev)
192{
193 struct udevice *dev = NULL;
468f0508
PD
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
f49eb16c
PD
200 if (uclass_get_device_by_seq(UCLASS_SERIAL, link_dev, &dev)) {
201 log_err("serial %d device not found\n", link_dev);
468f0508
PD
202 return -ENODEV;
203 }
204
f49eb16c
PD
205 down_serial_dev = dev;
206
468f0508
PD
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) {
f49eb16c 216 log_err("serial %d = %s missing ops\n", link_dev, dev->name);
468f0508
PD
217 return -ENODEV;
218 }
219 if (!ops->setconfig) {
f49eb16c 220 log_err("serial %d = %s missing setconfig\n", link_dev, dev->name);
468f0508
PD
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
232static 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
242static 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();
29caf930 251 schedule();
468f0508
PD
252 }
253 } while ((err == -EAGAIN) && (!had_ctrlc()));
254
255 return err;
256}
257
258static 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
267static 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;
d4358a64 271 ulong start = get_timer(0);
468f0508
PD
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();
29caf930 280 schedule();
d4358a64
PD
281 if (get_timer(start) > TIMEOUT_SERIAL_BUFFER) {
282 err = -ETIMEDOUT;
283 break;
284 }
468f0508
PD
285 } else {
286 break;
287 }
288 } while (*count && !had_ctrlc());
289
290 return !!(err < 0);
291}
292
293static 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 ************************************************/
3df19b8b 304static u8 stm32prog_start(struct stm32prog_data *data, uintptr_t address)
468f0508
PD
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
751f918b
PD
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;
468f0508 346 }
751f918b
PD
347 data->dfu_seq = 0;
348
468f0508 349 printf("\n received length = 0x%x\n", data->cursor);
468f0508
PD
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
3df19b8b 357 printf("## Starting application at 0x%p ...\n", (void *)address);
468f0508
PD
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
185f812c 370 * Return: The address area
468f0508 371 */
3df19b8b 372static uintptr_t get_address(u8 *tmp_xor)
468f0508 373{
3df19b8b 374 uintptr_t address = 0x0;
468f0508
PD
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
396static 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 */
409static 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 */
427static 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 */
438static void get_id_command(struct stm32prog_data *data)
439{
69446dee
PD
440 u32 cpu = get_cpu_dev();
441
468f0508
PD
442 /* Send Device IDCode */
443 stm32prog_serial_putc(0x1);
69446dee
PD
444 stm32prog_serial_putc((cpu >> 8) & 0xFF);
445 stm32prog_serial_putc(cpu & 0xFF);
468f0508
PD
446 stm32prog_serial_result(ACK_BYTE);
447}
448
449/**
450 * get_phase_command() - Respond to Get phase
451 *
452 * @data: Current command context
453 */
454static 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)
ada8fe0c 466 destination = CONFIG_SYS_LOAD_ADDR;
468f0508
PD
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 */
489static void read_memory_command(struct stm32prog_data *data)
490{
3df19b8b 491 uintptr_t address = 0x0;
468f0508
PD
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 */
534static void start_command(struct stm32prog_data *data)
535{
3df19b8b 536 uintptr_t address = 0;
468f0508
PD
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 */
3df19b8b 550 ret = stm32prog_start(data, address);
468f0508
PD
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 */
565static 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;
468f0508
PD
573 u32 cursor = data->cursor;
574 long size = 0;
575 u8 operation;
576 u32 packet_number;
577 u32 result = ACK_BYTE;
578 u8 ret;
468f0508
PD
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;
468f0508
PD
612 cursor = 0;
613 data->cursor = 0;
468f0508
PD
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 */
d4358a64 661 mdelay(TIMEOUT_SERIAL_BUFFER);
468f0508
PD
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 */
d4358a64 679 mdelay(TIMEOUT_SERIAL_BUFFER);
468f0508
PD
680 data->packet_number--;
681 result = NACK_BYTE;
682 goto end;
683 }
684
5f14e2fe
PD
685 switch (operation) {
686 case PHASE_OTP:
687 size = codesize;
688 ret = stm32prog_otp_write(data, cursor, data->buffer, &size);
689 break;
468f0508 690
5f14e2fe
PD
691 case PHASE_PMIC:
692 size = codesize;
693 ret = stm32prog_pmic_write(data, cursor, data->buffer, &size);
694 break;
468f0508 695
5f14e2fe
PD
696 default:
697 ret = stm32prog_write(data, data->buffer, codesize);
698 break;
468f0508
PD
699 }
700
468f0508
PD
701 if (ret)
702 result = ABORT_BYTE;
5f14e2fe
PD
703 else
704 /* Update current position in buffer */
705 data->cursor += codesize;
468f0508
PD
706
707end:
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 */
718static 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) {
711b5bc0
PD
733 log_debug("1st checksum received = %x, computed %x\n",
734 rcv_data, tmp_xor);
468f0508
PD
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) {
711b5bc0
PD
746 log_debug("2nd checksum received = %x, computed %x\n",
747 rcv_data, tmp_xor);
468f0508
PD
748 goto error;
749 }
750
711b5bc0 751 log_debug("%s : %x\n", __func__, part_id);
468f0508
PD
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
784error:
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
185f812c 794 * Return: true if reset is needed after loop
468f0508
PD
795 */
796bool 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 }
29caf930 855 schedule();
468f0508
PD
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}