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