1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <endian.h> 9*91f16700Schasinglulu #include <errno.h> 10*91f16700Schasinglulu #include <string.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <arch_helpers.h> 13*91f16700Schasinglulu #include <common/debug.h> 14*91f16700Schasinglulu #include <drivers/delay_timer.h> 15*91f16700Schasinglulu #include <drivers/st/stm32_iwdg.h> 16*91f16700Schasinglulu #include <drivers/st/stm32_uart.h> 17*91f16700Schasinglulu #include <drivers/st/stm32_uart_regs.h> 18*91f16700Schasinglulu #include <lib/mmio.h> 19*91f16700Schasinglulu #include <tools_share/firmware_image_package.h> 20*91f16700Schasinglulu 21*91f16700Schasinglulu #include <platform_def.h> 22*91f16700Schasinglulu #include <stm32cubeprogrammer.h> 23*91f16700Schasinglulu 24*91f16700Schasinglulu /* USART bootloader protocol version V4.0 */ 25*91f16700Schasinglulu #define USART_BL_VERSION 0x40U 26*91f16700Schasinglulu 27*91f16700Schasinglulu /* Command definition */ 28*91f16700Schasinglulu #define GET_CMD_COMMAND 0x00U 29*91f16700Schasinglulu #define GET_VER_COMMAND 0x01U 30*91f16700Schasinglulu #define GET_ID_COMMAND 0x02U 31*91f16700Schasinglulu #define PHASE_COMMAND 0x03U 32*91f16700Schasinglulu #define READ_PART_COMMAND 0x12U 33*91f16700Schasinglulu #define START_COMMAND 0x21U 34*91f16700Schasinglulu #define DOWNLOAD_COMMAND 0x31U 35*91f16700Schasinglulu 36*91f16700Schasinglulu /* Answer defines */ 37*91f16700Schasinglulu #define INIT_BYTE 0x7FU 38*91f16700Schasinglulu #define ACK_BYTE 0x79U 39*91f16700Schasinglulu #define NACK_BYTE 0x1FU 40*91f16700Schasinglulu #define ABORT 0x5FU 41*91f16700Schasinglulu 42*91f16700Schasinglulu #define UNDEFINED_DOWN_ADDR U(0xFFFFFFFF) 43*91f16700Schasinglulu #define PROGRAMMER_TIMEOUT_US 20000U 44*91f16700Schasinglulu 45*91f16700Schasinglulu static const uint8_t command_tab[] = { 46*91f16700Schasinglulu GET_CMD_COMMAND, 47*91f16700Schasinglulu GET_VER_COMMAND, 48*91f16700Schasinglulu GET_ID_COMMAND, 49*91f16700Schasinglulu PHASE_COMMAND, 50*91f16700Schasinglulu START_COMMAND, 51*91f16700Schasinglulu DOWNLOAD_COMMAND 52*91f16700Schasinglulu }; 53*91f16700Schasinglulu 54*91f16700Schasinglulu /* STM32CubeProgrammer over UART handle */ 55*91f16700Schasinglulu struct stm32prog_uart_handle_s { 56*91f16700Schasinglulu struct stm32_uart_handle_s uart; 57*91f16700Schasinglulu uint32_t packet; 58*91f16700Schasinglulu uint8_t *addr; 59*91f16700Schasinglulu uint32_t len; 60*91f16700Schasinglulu uint8_t phase; 61*91f16700Schasinglulu /* Error msg buffer: max 255 in UART protocol, reduced in TF-A */ 62*91f16700Schasinglulu uint8_t error[64]; 63*91f16700Schasinglulu } handle; 64*91f16700Schasinglulu 65*91f16700Schasinglulu /* Trace and handle unrecoverable UART protocol error */ 66*91f16700Schasinglulu #define STM32PROG_ERROR(...) \ 67*91f16700Schasinglulu { \ 68*91f16700Schasinglulu ERROR(__VA_ARGS__); \ 69*91f16700Schasinglulu if (handle.phase != PHASE_RESET) { \ 70*91f16700Schasinglulu snprintf((char *)&handle.error, sizeof(handle.error), __VA_ARGS__); \ 71*91f16700Schasinglulu handle.phase = PHASE_RESET; \ 72*91f16700Schasinglulu handle.addr = (uint8_t *)UNDEFINED_DOWN_ADDR; \ 73*91f16700Schasinglulu handle.len = 0U; \ 74*91f16700Schasinglulu handle.packet = 0U; \ 75*91f16700Schasinglulu } \ 76*91f16700Schasinglulu } 77*91f16700Schasinglulu 78*91f16700Schasinglulu static int uart_write(const uint8_t *addr, uint16_t size) 79*91f16700Schasinglulu { 80*91f16700Schasinglulu while (size != 0U) { 81*91f16700Schasinglulu if (stm32_uart_putc(&handle.uart, *addr) != 0) { 82*91f16700Schasinglulu return -EIO; 83*91f16700Schasinglulu } 84*91f16700Schasinglulu size--; 85*91f16700Schasinglulu addr++; 86*91f16700Schasinglulu } 87*91f16700Schasinglulu 88*91f16700Schasinglulu return 0; 89*91f16700Schasinglulu } 90*91f16700Schasinglulu 91*91f16700Schasinglulu static int uart_write_8(uint8_t byte) 92*91f16700Schasinglulu { 93*91f16700Schasinglulu return stm32_uart_putc(&handle.uart, byte); 94*91f16700Schasinglulu } 95*91f16700Schasinglulu 96*91f16700Schasinglulu static int uart_write_32(uint32_t value) 97*91f16700Schasinglulu { 98*91f16700Schasinglulu return uart_write((uint8_t *)&value, 4U); 99*91f16700Schasinglulu } 100*91f16700Schasinglulu 101*91f16700Schasinglulu static int uart_read_8(uint8_t *byte) 102*91f16700Schasinglulu { 103*91f16700Schasinglulu int ret; 104*91f16700Schasinglulu uint64_t timeout_ref = timeout_init_us(PROGRAMMER_TIMEOUT_US); 105*91f16700Schasinglulu 106*91f16700Schasinglulu do { 107*91f16700Schasinglulu ret = stm32_uart_getc(&handle.uart); 108*91f16700Schasinglulu if (ret == -EAGAIN) { 109*91f16700Schasinglulu if (timeout_elapsed(timeout_ref)) { 110*91f16700Schasinglulu return -ETIMEDOUT; 111*91f16700Schasinglulu } 112*91f16700Schasinglulu } else if (ret < 0) { 113*91f16700Schasinglulu return ret; 114*91f16700Schasinglulu } 115*91f16700Schasinglulu } while (ret == -EAGAIN); 116*91f16700Schasinglulu 117*91f16700Schasinglulu *byte = (uint8_t)ret; 118*91f16700Schasinglulu 119*91f16700Schasinglulu return 0; 120*91f16700Schasinglulu } 121*91f16700Schasinglulu 122*91f16700Schasinglulu static int uart_send_result(uint8_t byte) 123*91f16700Schasinglulu { 124*91f16700Schasinglulu int ret; 125*91f16700Schasinglulu 126*91f16700Schasinglulu /* Always flush fifo before to send result = read all pending data */ 127*91f16700Schasinglulu do { 128*91f16700Schasinglulu ret = stm32_uart_getc(&handle.uart); 129*91f16700Schasinglulu } while (ret >= 0); 130*91f16700Schasinglulu 131*91f16700Schasinglulu return uart_write_8(byte); 132*91f16700Schasinglulu } 133*91f16700Schasinglulu 134*91f16700Schasinglulu static bool is_valid_header(fip_toc_header_t *header) 135*91f16700Schasinglulu { 136*91f16700Schasinglulu return (header->name == TOC_HEADER_NAME) && 137*91f16700Schasinglulu (header->serial_number != 0U); 138*91f16700Schasinglulu } 139*91f16700Schasinglulu 140*91f16700Schasinglulu static int uart_receive_command(uint8_t *command) 141*91f16700Schasinglulu { 142*91f16700Schasinglulu uint8_t byte = 0U; 143*91f16700Schasinglulu uint8_t xor = 0U; 144*91f16700Schasinglulu unsigned int count; 145*91f16700Schasinglulu bool found = false; 146*91f16700Schasinglulu int ret; 147*91f16700Schasinglulu 148*91f16700Schasinglulu /* Repeat read until something is received */ 149*91f16700Schasinglulu do { 150*91f16700Schasinglulu stm32_iwdg_refresh(); 151*91f16700Schasinglulu ret = uart_read_8(&byte); 152*91f16700Schasinglulu } while (ret == -ETIMEDOUT); 153*91f16700Schasinglulu 154*91f16700Schasinglulu if (ret != 0) { 155*91f16700Schasinglulu return ret; 156*91f16700Schasinglulu } 157*91f16700Schasinglulu 158*91f16700Schasinglulu /* Handle reconnection request */ 159*91f16700Schasinglulu if (byte == INIT_BYTE) { 160*91f16700Schasinglulu *command = byte; 161*91f16700Schasinglulu return 0; 162*91f16700Schasinglulu } 163*91f16700Schasinglulu 164*91f16700Schasinglulu for (count = 0U; count < ARRAY_SIZE(command_tab); count++) { 165*91f16700Schasinglulu if (command_tab[count] == byte) { 166*91f16700Schasinglulu found = true; 167*91f16700Schasinglulu break; 168*91f16700Schasinglulu } 169*91f16700Schasinglulu } 170*91f16700Schasinglulu if (!found) { 171*91f16700Schasinglulu VERBOSE("UART: Command unknown (byte=0x%x)\n", byte); 172*91f16700Schasinglulu return -EPROTO; 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu ret = uart_read_8(&xor); 176*91f16700Schasinglulu if (ret != 0) { 177*91f16700Schasinglulu return ret; 178*91f16700Schasinglulu } 179*91f16700Schasinglulu if ((byte ^ xor) != 0xFF) { 180*91f16700Schasinglulu VERBOSE("UART: Command XOR check fail (byte=0x%x, xor=0x%x)\n", 181*91f16700Schasinglulu byte, xor); 182*91f16700Schasinglulu return -EPROTO; 183*91f16700Schasinglulu } 184*91f16700Schasinglulu 185*91f16700Schasinglulu *command = byte; 186*91f16700Schasinglulu 187*91f16700Schasinglulu return 0; 188*91f16700Schasinglulu } 189*91f16700Schasinglulu 190*91f16700Schasinglulu static int get_cmd_command(void) 191*91f16700Schasinglulu { 192*91f16700Schasinglulu const uint8_t msg[2] = { 193*91f16700Schasinglulu sizeof(command_tab), /* Length of data - 1 */ 194*91f16700Schasinglulu USART_BL_VERSION 195*91f16700Schasinglulu }; 196*91f16700Schasinglulu int ret; 197*91f16700Schasinglulu 198*91f16700Schasinglulu ret = uart_write(msg, sizeof(msg)); 199*91f16700Schasinglulu if (ret != 0) { 200*91f16700Schasinglulu return ret; 201*91f16700Schasinglulu } 202*91f16700Schasinglulu 203*91f16700Schasinglulu return uart_write(command_tab, sizeof(command_tab)); 204*91f16700Schasinglulu } 205*91f16700Schasinglulu 206*91f16700Schasinglulu static int get_version_command(void) 207*91f16700Schasinglulu { 208*91f16700Schasinglulu return uart_write_8(STM32_TF_VERSION); 209*91f16700Schasinglulu } 210*91f16700Schasinglulu 211*91f16700Schasinglulu static int get_id_command(void) 212*91f16700Schasinglulu { 213*91f16700Schasinglulu uint8_t msg[3] = { 214*91f16700Schasinglulu sizeof(msg) - 1 /* Length of data - 1 */ 215*91f16700Schasinglulu }; 216*91f16700Schasinglulu uint32_t chip_id = stm32mp_get_chip_dev_id(); 217*91f16700Schasinglulu 218*91f16700Schasinglulu be16enc(&msg[1], chip_id); 219*91f16700Schasinglulu 220*91f16700Schasinglulu return uart_write(msg, sizeof(msg)); 221*91f16700Schasinglulu } 222*91f16700Schasinglulu 223*91f16700Schasinglulu static int uart_send_phase(uint32_t address) 224*91f16700Schasinglulu { 225*91f16700Schasinglulu int ret; 226*91f16700Schasinglulu uint8_t msg_size = 5U; /* Length of data - 1 */ 227*91f16700Schasinglulu uint8_t error_size = 0U; 228*91f16700Schasinglulu 229*91f16700Schasinglulu /* Additional information only for RESET phase */ 230*91f16700Schasinglulu if (handle.phase == PHASE_RESET) { 231*91f16700Schasinglulu error_size = strnlen((char *)&handle.error, sizeof(handle.error)); 232*91f16700Schasinglulu } 233*91f16700Schasinglulu ret = uart_write_8(msg_size + error_size); 234*91f16700Schasinglulu if (ret != 0) { 235*91f16700Schasinglulu return ret; 236*91f16700Schasinglulu } 237*91f16700Schasinglulu 238*91f16700Schasinglulu /* Send the ID of next partition */ 239*91f16700Schasinglulu ret = uart_write_8(handle.phase); 240*91f16700Schasinglulu if (ret != 0) { 241*91f16700Schasinglulu return ret; 242*91f16700Schasinglulu } 243*91f16700Schasinglulu 244*91f16700Schasinglulu /* Destination address */ 245*91f16700Schasinglulu ret = uart_write_32(address); 246*91f16700Schasinglulu if (ret != 0) { 247*91f16700Schasinglulu return ret; 248*91f16700Schasinglulu } 249*91f16700Schasinglulu 250*91f16700Schasinglulu ret = uart_write_8(error_size); 251*91f16700Schasinglulu if (ret != 0) { 252*91f16700Schasinglulu return ret; 253*91f16700Schasinglulu } 254*91f16700Schasinglulu 255*91f16700Schasinglulu /* Additional information: message error */ 256*91f16700Schasinglulu if (error_size > 0U) { 257*91f16700Schasinglulu ret = uart_write(handle.error, error_size); 258*91f16700Schasinglulu } 259*91f16700Schasinglulu 260*91f16700Schasinglulu return ret; 261*91f16700Schasinglulu } 262*91f16700Schasinglulu 263*91f16700Schasinglulu static int uart_download_part(void) 264*91f16700Schasinglulu { 265*91f16700Schasinglulu uint8_t operation = 0U; 266*91f16700Schasinglulu uint8_t xor; 267*91f16700Schasinglulu uint8_t byte = 0U; 268*91f16700Schasinglulu uint32_t packet_number = 0U; 269*91f16700Schasinglulu uint32_t packet_size = 0U; 270*91f16700Schasinglulu uint32_t i = 0U; 271*91f16700Schasinglulu int ret; 272*91f16700Schasinglulu 273*91f16700Schasinglulu /* Get operation number */ 274*91f16700Schasinglulu ret = uart_read_8(&operation); 275*91f16700Schasinglulu if (ret != 0) { 276*91f16700Schasinglulu return ret; 277*91f16700Schasinglulu } 278*91f16700Schasinglulu 279*91f16700Schasinglulu xor = operation; 280*91f16700Schasinglulu 281*91f16700Schasinglulu /* Get packet number */ 282*91f16700Schasinglulu for (i = 3U; i != 0U; i--) { 283*91f16700Schasinglulu ret = uart_read_8(&byte); 284*91f16700Schasinglulu if (ret != 0) { 285*91f16700Schasinglulu return ret; 286*91f16700Schasinglulu } 287*91f16700Schasinglulu 288*91f16700Schasinglulu xor ^= byte; 289*91f16700Schasinglulu packet_number = (packet_number << 8) | byte; 290*91f16700Schasinglulu } 291*91f16700Schasinglulu 292*91f16700Schasinglulu if (packet_number != handle.packet) { 293*91f16700Schasinglulu WARN("UART: Bad packet number receive: %u, expected %u\n", 294*91f16700Schasinglulu packet_number, handle.packet); 295*91f16700Schasinglulu return -EPROTO; 296*91f16700Schasinglulu } 297*91f16700Schasinglulu 298*91f16700Schasinglulu /* Checksum */ 299*91f16700Schasinglulu ret = uart_read_8(&byte); 300*91f16700Schasinglulu if (ret != 0) { 301*91f16700Schasinglulu return ret; 302*91f16700Schasinglulu } 303*91f16700Schasinglulu if (xor != byte) { 304*91f16700Schasinglulu VERBOSE("UART: Download Command checksum xor: %x, received %x\n", 305*91f16700Schasinglulu xor, byte); 306*91f16700Schasinglulu return -EPROTO; 307*91f16700Schasinglulu } 308*91f16700Schasinglulu 309*91f16700Schasinglulu ret = uart_send_result(ACK_BYTE); 310*91f16700Schasinglulu if (ret != 0) { 311*91f16700Schasinglulu return ret; 312*91f16700Schasinglulu } 313*91f16700Schasinglulu 314*91f16700Schasinglulu ret = uart_read_8(&byte); 315*91f16700Schasinglulu if (ret != 0) { 316*91f16700Schasinglulu return ret; 317*91f16700Schasinglulu } 318*91f16700Schasinglulu xor = byte; 319*91f16700Schasinglulu packet_size = byte + 1U; 320*91f16700Schasinglulu if (handle.len < packet_size) { 321*91f16700Schasinglulu STM32PROG_ERROR("Download overflow at %p\n", handle.addr + packet_size); 322*91f16700Schasinglulu return 0; 323*91f16700Schasinglulu } 324*91f16700Schasinglulu 325*91f16700Schasinglulu for (i = 0U; i < packet_size; i++) { 326*91f16700Schasinglulu ret = uart_read_8(&byte); 327*91f16700Schasinglulu if (ret != 0) { 328*91f16700Schasinglulu return ret; 329*91f16700Schasinglulu } 330*91f16700Schasinglulu 331*91f16700Schasinglulu *(handle.addr + i) = byte; 332*91f16700Schasinglulu xor ^= byte; 333*91f16700Schasinglulu } 334*91f16700Schasinglulu 335*91f16700Schasinglulu /* Checksum */ 336*91f16700Schasinglulu ret = uart_read_8(&byte) != 0; 337*91f16700Schasinglulu if (ret != 0) { 338*91f16700Schasinglulu return ret; 339*91f16700Schasinglulu } 340*91f16700Schasinglulu if (xor != byte) { 341*91f16700Schasinglulu VERBOSE("UART: Download Data checksum xor: %x, received %x\n", 342*91f16700Schasinglulu xor, byte); 343*91f16700Schasinglulu return -EPROTO; 344*91f16700Schasinglulu } 345*91f16700Schasinglulu 346*91f16700Schasinglulu /* Packet treated */ 347*91f16700Schasinglulu handle.packet++; 348*91f16700Schasinglulu handle.addr += packet_size; 349*91f16700Schasinglulu handle.len -= packet_size; 350*91f16700Schasinglulu 351*91f16700Schasinglulu return 0; 352*91f16700Schasinglulu } 353*91f16700Schasinglulu 354*91f16700Schasinglulu static int uart_start_cmd(uintptr_t buffer) 355*91f16700Schasinglulu { 356*91f16700Schasinglulu uint8_t byte = 0U; 357*91f16700Schasinglulu uint8_t xor = 0U; 358*91f16700Schasinglulu uint32_t i; 359*91f16700Schasinglulu uint32_t start_address = 0U; 360*91f16700Schasinglulu int ret; 361*91f16700Schasinglulu 362*91f16700Schasinglulu /* Get address */ 363*91f16700Schasinglulu for (i = 4U; i != 0U; i--) { 364*91f16700Schasinglulu ret = uart_read_8(&byte); 365*91f16700Schasinglulu if (ret != 0U) { 366*91f16700Schasinglulu return ret; 367*91f16700Schasinglulu } 368*91f16700Schasinglulu 369*91f16700Schasinglulu xor ^= byte; 370*91f16700Schasinglulu start_address = (start_address << 8) | byte; 371*91f16700Schasinglulu } 372*91f16700Schasinglulu 373*91f16700Schasinglulu /* Checksum */ 374*91f16700Schasinglulu ret = uart_read_8(&byte); 375*91f16700Schasinglulu if (ret != 0) { 376*91f16700Schasinglulu return ret; 377*91f16700Schasinglulu } 378*91f16700Schasinglulu 379*91f16700Schasinglulu if (xor != byte) { 380*91f16700Schasinglulu VERBOSE("UART: Start Command checksum xor: %x, received %x\n", 381*91f16700Schasinglulu xor, byte); 382*91f16700Schasinglulu return -EPROTO; 383*91f16700Schasinglulu } 384*91f16700Schasinglulu 385*91f16700Schasinglulu if (start_address != UNDEFINED_DOWN_ADDR) { 386*91f16700Schasinglulu STM32PROG_ERROR("Invalid start at %x, for phase %u\n", 387*91f16700Schasinglulu start_address, handle.phase); 388*91f16700Schasinglulu return 0; 389*91f16700Schasinglulu } 390*91f16700Schasinglulu 391*91f16700Schasinglulu if (!is_valid_header((fip_toc_header_t *)buffer)) { 392*91f16700Schasinglulu STM32PROG_ERROR("FIP Header check failed %lx, for phase %u\n", 393*91f16700Schasinglulu buffer, handle.phase); 394*91f16700Schasinglulu return -EIO; 395*91f16700Schasinglulu } 396*91f16700Schasinglulu VERBOSE("FIP header looks OK.\n"); 397*91f16700Schasinglulu 398*91f16700Schasinglulu return 0; 399*91f16700Schasinglulu } 400*91f16700Schasinglulu 401*91f16700Schasinglulu static int uart_read(uint8_t id, uintptr_t buffer, size_t length) 402*91f16700Schasinglulu { 403*91f16700Schasinglulu bool start_done = false; 404*91f16700Schasinglulu int ret; 405*91f16700Schasinglulu uint8_t command = 0U; 406*91f16700Schasinglulu 407*91f16700Schasinglulu handle.phase = id; 408*91f16700Schasinglulu handle.packet = 0U; 409*91f16700Schasinglulu handle.addr = (uint8_t *)buffer; 410*91f16700Schasinglulu handle.len = length; 411*91f16700Schasinglulu 412*91f16700Schasinglulu INFO("UART: read phase %u at 0x%lx size 0x%zx\n", 413*91f16700Schasinglulu id, buffer, length); 414*91f16700Schasinglulu while (!start_done) { 415*91f16700Schasinglulu ret = uart_receive_command(&command); 416*91f16700Schasinglulu if (ret != 0) { 417*91f16700Schasinglulu /* Delay to wait STM32CubeProgrammer end of transmission */ 418*91f16700Schasinglulu mdelay(3); 419*91f16700Schasinglulu 420*91f16700Schasinglulu ret = uart_send_result(NACK_BYTE); 421*91f16700Schasinglulu if (ret != 0U) { 422*91f16700Schasinglulu return ret; 423*91f16700Schasinglulu } 424*91f16700Schasinglulu 425*91f16700Schasinglulu continue; 426*91f16700Schasinglulu } 427*91f16700Schasinglulu 428*91f16700Schasinglulu uart_send_result(ACK_BYTE); 429*91f16700Schasinglulu 430*91f16700Schasinglulu switch (command) { 431*91f16700Schasinglulu case INIT_BYTE: 432*91f16700Schasinglulu INFO("UART: Connected\n"); 433*91f16700Schasinglulu /* Nothing to do */ 434*91f16700Schasinglulu continue; 435*91f16700Schasinglulu 436*91f16700Schasinglulu case GET_CMD_COMMAND: 437*91f16700Schasinglulu ret = get_cmd_command(); 438*91f16700Schasinglulu break; 439*91f16700Schasinglulu 440*91f16700Schasinglulu case GET_VER_COMMAND: 441*91f16700Schasinglulu ret = get_version_command(); 442*91f16700Schasinglulu break; 443*91f16700Schasinglulu 444*91f16700Schasinglulu case GET_ID_COMMAND: 445*91f16700Schasinglulu ret = get_id_command(); 446*91f16700Schasinglulu break; 447*91f16700Schasinglulu 448*91f16700Schasinglulu case PHASE_COMMAND: 449*91f16700Schasinglulu ret = uart_send_phase((uint32_t)buffer); 450*91f16700Schasinglulu if ((ret == 0) && (handle.phase == PHASE_RESET)) { 451*91f16700Schasinglulu start_done = true; 452*91f16700Schasinglulu INFO("UART: Reset\n"); 453*91f16700Schasinglulu } 454*91f16700Schasinglulu break; 455*91f16700Schasinglulu 456*91f16700Schasinglulu case DOWNLOAD_COMMAND: 457*91f16700Schasinglulu ret = uart_download_part(); 458*91f16700Schasinglulu break; 459*91f16700Schasinglulu 460*91f16700Schasinglulu case START_COMMAND: 461*91f16700Schasinglulu ret = uart_start_cmd(buffer); 462*91f16700Schasinglulu if ((ret == 0) && (handle.phase == id)) { 463*91f16700Schasinglulu INFO("UART: Start phase %u\n", handle.phase); 464*91f16700Schasinglulu start_done = true; 465*91f16700Schasinglulu } 466*91f16700Schasinglulu break; 467*91f16700Schasinglulu 468*91f16700Schasinglulu default: 469*91f16700Schasinglulu WARN("UART: Unknown command\n"); 470*91f16700Schasinglulu ret = -EINVAL; 471*91f16700Schasinglulu break; 472*91f16700Schasinglulu } 473*91f16700Schasinglulu 474*91f16700Schasinglulu if (ret == 0) { 475*91f16700Schasinglulu ret = uart_send_result(ACK_BYTE); 476*91f16700Schasinglulu } else { 477*91f16700Schasinglulu ret = uart_send_result(NACK_BYTE); 478*91f16700Schasinglulu } 479*91f16700Schasinglulu if (ret != 0) { 480*91f16700Schasinglulu return ret; 481*91f16700Schasinglulu } 482*91f16700Schasinglulu } 483*91f16700Schasinglulu 484*91f16700Schasinglulu stm32_uart_flush(&handle.uart); 485*91f16700Schasinglulu 486*91f16700Schasinglulu return 0; 487*91f16700Schasinglulu } 488*91f16700Schasinglulu 489*91f16700Schasinglulu /* Init UART: 115200, 8bit 1stop parity even and enable FIFO mode */ 490*91f16700Schasinglulu const struct stm32_uart_init_s init = { 491*91f16700Schasinglulu .baud_rate = STM32MP_UART_BAUDRATE, 492*91f16700Schasinglulu .word_length = STM32_UART_WORDLENGTH_9B, 493*91f16700Schasinglulu .stop_bits = STM32_UART_STOPBITS_1, 494*91f16700Schasinglulu .parity = STM32_UART_PARITY_EVEN, 495*91f16700Schasinglulu .hw_flow_control = STM32_UART_HWCONTROL_NONE, 496*91f16700Schasinglulu .mode = STM32_UART_MODE_TX_RX, 497*91f16700Schasinglulu .fifo_mode = STM32_UART_FIFOMODE_EN, 498*91f16700Schasinglulu }; 499*91f16700Schasinglulu 500*91f16700Schasinglulu int stm32cubeprog_uart_load(uintptr_t instance, uintptr_t base, size_t len) 501*91f16700Schasinglulu { 502*91f16700Schasinglulu int ret; 503*91f16700Schasinglulu 504*91f16700Schasinglulu if (stm32_uart_init(&handle.uart, instance, &init) != 0) { 505*91f16700Schasinglulu return -EIO; 506*91f16700Schasinglulu } 507*91f16700Schasinglulu 508*91f16700Schasinglulu /* 509*91f16700Schasinglulu * The following NACK_BYTE is written because STM32CubeProgrammer has 510*91f16700Schasinglulu * already sent its command before TF-A has reached this point, and 511*91f16700Schasinglulu * because FIFO was not configured by BootROM. 512*91f16700Schasinglulu * The byte in the UART_RX register is then the checksum and not the 513*91f16700Schasinglulu * command. NACK_BYTE has to be written, so that the programmer will 514*91f16700Schasinglulu * re-send the good command. 515*91f16700Schasinglulu */ 516*91f16700Schasinglulu ret = uart_send_result(NACK_BYTE); 517*91f16700Schasinglulu if (ret != 0) { 518*91f16700Schasinglulu return ret; 519*91f16700Schasinglulu } 520*91f16700Schasinglulu 521*91f16700Schasinglulu return uart_read(PHASE_SSBL, base, len); 522*91f16700Schasinglulu } 523