contrib: replace the BSD-3-Clause license tag
[fw/openocd] / contrib / loaders / flash / cc26xx / main.c
1 /* SPDX-License-Identifier: BSD-3-Clause */
2
3 /******************************************************************************
4 *
5 * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
6 *
7 ******************************************************************************/
8
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "flashloader.h"
12
13 /* Data buffers used by host to communicate with flashloader */
14
15 /* Flashloader parameter structure. */
16 __attribute__ ((section(".buffers.g_cfg")))
17 volatile struct flash_params g_cfg[2];
18 /* Data buffer 1. */
19 __attribute__ ((section(".buffers.g_buf1")))
20 uint8_t g_buf1[BUFFER_LEN];
21 /* Data buffer 2. */
22 __attribute__ ((section(".buffers.g_buf2")))
23 uint8_t g_buf2[BUFFER_LEN];
24
25 /* Buffer used for program with retain feature */
26 __attribute__ ((section(".buffers.g_retain_buf")))
27 uint8_t g_retain_buf[BUFFER_LEN];
28
29 uint32_t g_curr_buf; /* Current buffer used. */
30 uint32_t g_vims_ctl; /* Saved flash cache state. */
31
32 /******************************************************************************
33 *
34 * This function stores the current VIMS configuration before
35 * - disabling VIMS flash cache
36 * - flushing the flash line buffers.
37 *
38 * Note Not using driverlib calls because it requires using "NO_ROM" define in
39 *      order to work for both Cha. R1 and R2 using the same code. Manually
40 *      doing the steps to minimize code footprint.
41 *
42 ******************************************************************************/
43 static void disable_flash_cache()
44 {
45         /* 1. Make sure VIMS is not currently changing mode (VIMS:STAT register) */
46         while ((HWREG(0x40034000) & 0x00000008) == 0x8)
47                 ;
48
49         /* Save current VIMS:CTL state */
50         g_vims_ctl = HWREG(0x40034004);
51
52         /* 2. Set VIMS mode to OFF and disable flash line buffers */
53         uint32_t new_vims_ctl = g_vims_ctl | 0x33;
54         HWREG(0x40034004) = new_vims_ctl;
55
56         /* 3. Wait for VIMS to have changed mode (VIMS:STAT register) */
57         while ((HWREG(0x40034000) & 0x00000008) == 0x8)
58                 ;
59 }
60
61 /******************************************************************************
62 *
63 * This function restores the VIMS configuration saved off by
64 * disable_flash_cache().
65 *
66 * Note Not using driverlib calls because it requires using "NO_ROM" define in
67 *      order to work for both Cha. R1 and R2 using the same code. Manually
68 *      doing the steps to minimize code footprint.
69 *
70 ******************************************************************************/
71 static void restore_cache_state()
72 {
73         HWREG(0x40034004) = g_vims_ctl;
74
75         /* Wait for VIMS to have changed mode (VIMS:STAT register) */
76         while ((HWREG(0x40034000) & 0x00000008) == 0x8)
77                 ;
78 }
79
80 /******************************************************************************
81 *
82 * CC13xx/CC26xx flashloader main function.
83 *
84 ******************************************************************************/
85 int main(void)
86 {
87         flashloader_init((struct flash_params *)g_cfg, g_buf1, g_buf2);
88
89         g_curr_buf = 0; /* start with the first buffer */
90         uint32_t status;
91
92         while (1) {
93                 /* Wait for host to signal buffer is ready */
94                 while (g_cfg[g_curr_buf].full == BUFFER_EMPTY)
95                         ;
96
97                 disable_flash_cache();
98
99                 /* Perform requested task */
100                 switch (g_cfg[g_curr_buf].cmd) {
101                         case CMD_ERASE_ALL:
102                                 status = flashloader_erase_all();
103                                 break;
104                         case CMD_PROGRAM:
105                                 status =
106                                         flashloader_program(
107                                                 (uint8_t *)g_cfg[g_curr_buf].buf_addr,
108                                                 g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
109                                 break;
110                         case CMD_ERASE_AND_PROGRAM:
111                                 status =
112                                         flashloader_erase_and_program(
113                                                 (uint8_t *)g_cfg[g_curr_buf].buf_addr,
114                                                 g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
115                                 break;
116                         case CMD_ERASE_AND_PROGRAM_WITH_RETAIN:
117                                 status =
118                                         flashloader_program_with_retain(
119                                                 (uint8_t *)g_cfg[g_curr_buf].buf_addr,
120                                                 g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
121                                 break;
122                         case CMD_ERASE_SECTORS:
123                                 status =
124                                         flashloader_erase_sectors(g_cfg[g_curr_buf].dest,
125                                                 g_cfg[g_curr_buf].len);
126                                 break;
127                         default:
128                                 status = STATUS_FAILED_UNKNOWN_COMMAND;
129                                 break;
130                 }
131
132                 restore_cache_state();
133
134                 /* Enter infinite loop on error condition */
135                 if (status != STATUS_OK) {
136                         g_cfg[g_curr_buf].full = status;
137                         while (1)
138                                 ;
139                 }
140
141                 /* Mark current task complete, and begin looking at next buffer */
142                 g_cfg[g_curr_buf].full = BUFFER_EMPTY;
143                 g_curr_buf ^= 1;
144         }
145 }
146
147 void _exit(int status)
148 {
149         /* Enter infinite loop on hitting an exit condition */
150         (void)status; /* Unused parameter */
151         while (1)
152                 ;
153 }