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