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