1 /*
2 * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include <stdlib.h>
8 #include "stub_commands.h"
9 #include "stub_flasher.h"
10 #include "rom_functions.h"
11 #include "slip.h"
12 #include "soc_support.h"
13 #include "stub_io.h"
14
15 #if defined(ESP32S3) && !defined(ESP32S3BETA2)
SPIRead4B(int spi_num,uint32_t flash_addr,uint8_t * buf,int len)16 static esp_rom_spiflash_result_t SPIRead4B(int spi_num, uint32_t flash_addr, uint8_t* buf, int len)
17 {
18 uint8_t cmd_len = 8;
19
20 esp_rom_opiflash_wait_idle();
21 while (len > 0) {
22 int rd_length;
23 if (len > 16 ) { //16 = read_sub_len
24 rd_length = 16;
25 } else {
26 rd_length = len;
27 }
28 esp_rom_opiflash_exec_cmd(spi_num, SPI_FLASH_FASTRD_MODE,
29 CMD_FSTRD4B, cmd_len,
30 flash_addr, 32,
31 8,
32 NULL, 0,
33 buf, 8 * rd_length,
34 ESP_ROM_OPIFLASH_SEL_CS0,
35 false);
36
37 len -= rd_length;
38 buf += rd_length;
39 flash_addr += rd_length;
40 }
41 return ESP_ROM_SPIFLASH_RESULT_OK;
42 }
43 #endif // ESP32S3
44
handle_flash_erase(uint32_t addr,uint32_t len)45 int handle_flash_erase(uint32_t addr, uint32_t len) {
46 if (addr % FLASH_SECTOR_SIZE != 0) return 0x32;
47 if (len % FLASH_SECTOR_SIZE != 0) return 0x33;
48 if (SPIUnlock() != 0) return 0x34;
49
50 while (len > 0 && (addr % FLASH_BLOCK_SIZE != 0)) {
51 #if defined(ESP32S3) && !defined(ESP32S3BETA2)
52 if (large_flash_mode) {
53 if (esp_rom_opiflash_erase_sector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
54 } else {
55 if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
56 }
57 #else
58 if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x35;
59 #endif // ESP32S3
60 len -= FLASH_SECTOR_SIZE;
61 addr += FLASH_SECTOR_SIZE;
62 }
63
64 while (len > FLASH_BLOCK_SIZE) {
65 #if defined(ESP32S3) && !defined(ESP32S3BETA2)
66 if (large_flash_mode) {
67 if (esp_rom_opiflash_erase_block_64k(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
68 } else {
69 if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
70 }
71 #else
72 if (SPIEraseBlock(addr / FLASH_BLOCK_SIZE) != 0) return 0x36;
73 #endif // ESP32S3
74 len -= FLASH_BLOCK_SIZE;
75 addr += FLASH_BLOCK_SIZE;
76 }
77
78 while (len > 0) {
79 #if defined(ESP32S3) && !defined(ESP32S3BETA2)
80 if (large_flash_mode) {
81 if (esp_rom_opiflash_erase_sector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
82 } else {
83 if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
84 }
85 #else
86 if (SPIEraseSector(addr / FLASH_SECTOR_SIZE) != 0) return 0x37;
87 #endif // ESP32S3
88 len -= FLASH_SECTOR_SIZE;
89 addr += FLASH_SECTOR_SIZE;
90 }
91
92 return 0;
93 }
94
handle_flash_read(uint32_t addr,uint32_t len,uint32_t block_size,uint32_t max_in_flight)95 void handle_flash_read(uint32_t addr, uint32_t len, uint32_t block_size,
96 uint32_t max_in_flight) {
97 uint8_t buf[FLASH_SECTOR_SIZE];
98 uint8_t digest[16];
99 struct MD5Context ctx;
100 uint32_t num_sent = 0, num_acked = 0;
101 uint8_t res = 0;
102
103 /* This is one routine where we still do synchronous I/O */
104 stub_rx_async_enable(false);
105
106 if (block_size > sizeof(buf)) {
107 return;
108 }
109 MD5Init(&ctx);
110 while (num_acked < len && num_acked <= num_sent) {
111 while (num_sent < len && num_sent - num_acked < max_in_flight) {
112 uint32_t n = len - num_sent;
113 if (n > block_size) n = block_size;
114 #if defined(ESP32S3) && !defined(ESP32S3BETA2)
115 if (large_flash_mode) {
116 res = SPIRead4B(1, addr, buf, n);
117 } else {
118 res = SPIRead(addr, (uint32_t *)buf, n);
119 }
120 #else
121 res = SPIRead(addr, (uint32_t *)buf, n);
122 #endif // ESP32S3
123 if (res != 0) {
124 break;
125 }
126 SLIP_send(buf, n);
127 MD5Update(&ctx, buf, n);
128 addr += n;
129 num_sent += n;
130 }
131 int r = SLIP_recv(&num_acked, sizeof(num_acked));
132 if (r != 4) {
133 break;
134 }
135 }
136 MD5Final(digest, &ctx);
137 SLIP_send(digest, sizeof(digest));
138
139 /* Go back to async RX */
140 stub_rx_async_enable(true);
141 }
142
handle_flash_get_md5sum(uint32_t addr,uint32_t len)143 int handle_flash_get_md5sum(uint32_t addr, uint32_t len) {
144 uint8_t buf[FLASH_SECTOR_SIZE];
145 uint8_t digest[16];
146 uint8_t res = 0;
147 struct MD5Context ctx;
148 MD5Init(&ctx);
149 while (len > 0) {
150 uint32_t n = len;
151 if (n > FLASH_SECTOR_SIZE) {
152 n = FLASH_SECTOR_SIZE;
153 }
154 #if defined(ESP32S3) && !defined(ESP32S3BETA2)
155 if (large_flash_mode) {
156 res = SPIRead4B(1, addr, buf, n);
157 } else {
158 res = SPIRead(addr, (uint32_t *)buf, n);
159 }
160 #else
161 res = SPIRead(addr, (uint32_t *)buf, n);
162 #endif // ESP32S3
163 if (res != 0) {
164 return 0x63;
165 }
166 MD5Update(&ctx, buf, n);
167 addr += n;
168 len -= n;
169 }
170 MD5Final(digest, &ctx);
171 /* ESP32 ROM sends as hex, but we just send raw bytes - esptool.py can handle either. */
172 SLIP_send_frame_data_buf(digest, sizeof(digest));
173 return 0;
174 }
175
handle_spi_set_params(uint32_t * args,int * status)176 esp_command_error handle_spi_set_params(uint32_t *args, int *status)
177 {
178 *status = SPIParamCfg(args[0], args[1], args[2], args[3], args[4], args[5]);
179 return *status ? ESP_FAILED_SPI_OP : ESP_OK;
180 }
181
handle_spi_attach(uint32_t hspi_config_arg)182 esp_command_error handle_spi_attach(uint32_t hspi_config_arg)
183 {
184 #ifdef ESP8266
185 /* ESP8266 doesn't yet support SPI flash on HSPI, but could:
186 see https://github.com/themadinventor/esptool/issues/98 */
187 SelectSpiFunction();
188 #else
189 /* Stub calls spi_flash_attach automatically when it boots,
190 therefore, we need to "unattach" the flash before attaching again
191 with different configuration to avoid issues. */
192
193 // Configure the SPI flash pins back as classic GPIOs
194 PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICLK_U, FUNC_GPIO);
195 PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPIQ_U, FUNC_GPIO);
196 PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPID_U, FUNC_GPIO);
197 PIN_FUNC_SELECT(PERIPHS_IO_MUX_SPICS0_U, FUNC_GPIO);
198
199 /* spi_flash_attach calls SelectSpiFunction() and another
200 function to initialise SPI flash interface.
201
202 Second argument 'legacy' mode is not currently supported.
203 */
204 spi_flash_attach(hspi_config_arg, 0);
205 #endif
206 return ESP_OK; /* neither function/attach command takes an arg */
207 }
208
209 static uint32_t *mem_offset;
210 static uint32_t mem_remaining;
211
handle_mem_begin(uint32_t size,uint32_t offset)212 esp_command_error handle_mem_begin(uint32_t size, uint32_t offset)
213 {
214 mem_offset = (uint32_t *)offset;
215 mem_remaining = size;
216 return ESP_OK;
217 }
218
handle_mem_data(void * data,uint32_t length)219 esp_command_error handle_mem_data(void *data, uint32_t length)
220 {
221 uint32_t *data_words = (uint32_t *)data;
222 if (mem_offset == NULL && length > 0) {
223 return ESP_NOT_IN_FLASH_MODE;
224 }
225 if (length > mem_remaining) {
226 return ESP_TOO_MUCH_DATA;
227 }
228 if (length % 4 != 0) {
229 return ESP_BAD_DATA_LEN;
230 }
231
232 for(int i = 0; i < length; i+= 4) {
233 *mem_offset++ = *data_words++;
234 mem_remaining -= 4;
235 }
236 return ESP_OK;
237 }
238
handle_mem_finish()239 esp_command_error handle_mem_finish()
240 {
241 esp_command_error res = mem_remaining > 0 ? ESP_NOT_ENOUGH_DATA : ESP_OK;
242 mem_remaining = 0;
243 mem_offset = NULL;
244 return res;
245 }
246
handle_write_reg(const write_reg_args_t * cmds,uint32_t num_commands)247 esp_command_error handle_write_reg(const write_reg_args_t *cmds, uint32_t num_commands)
248 {
249 for (uint32_t i = 0; i < num_commands; i++) {
250 const write_reg_args_t *cmd = &cmds[i];
251 ets_delay_us(cmd->delay_us);
252 uint32_t v = cmd->value & cmd->mask;
253 if (cmd->mask != UINT32_MAX) {
254 v |= READ_REG(cmd->addr) & ~cmd->mask;
255 }
256 WRITE_REG(cmd->addr, v);
257 }
258 return ESP_OK;
259 }
260
261 #if ESP32S2_OR_LATER
handle_get_security_info()262 esp_command_error handle_get_security_info()
263 {
264 uint8_t buf[SECURITY_INFO_BYTES];
265 esp_command_error ret;
266
267 #ifdef ESP32C3
268 if (_rom_eco_version >= 7)
269 ret = GetSecurityInfoProcNewEco(NULL, NULL, buf);
270 else
271 ret = GetSecurityInfoProc(NULL, NULL, buf);
272 #else
273 ret = GetSecurityInfoProc(NULL, NULL, buf);
274 #endif // ESP32C3
275 if (ret == ESP_OK)
276 SLIP_send_frame_data_buf(buf, sizeof(buf));
277 return ret;
278 }
279 #endif // ESP32S2_OR_LATER
280