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