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