protocol.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /* Copyright 2020-2023 Espressif Systems (Shanghai) CO LTD
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include "protocol.h"
  16. #include "esp_loader_io.h"
  17. #include "slip.h"
  18. #include <stddef.h>
  19. #include <string.h>
  20. #define CMD_SIZE(cmd) ( sizeof(cmd) - sizeof(command_common_t) )
  21. static uint32_t s_sequence_number = 0;
  22. static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size);
  23. static uint8_t compute_checksum(const uint8_t *data, uint32_t size)
  24. {
  25. uint8_t checksum = 0xEF;
  26. while (size--) {
  27. checksum ^= *data++;
  28. }
  29. return checksum;
  30. }
  31. static esp_loader_error_t send_cmd(const void *cmd_data, uint32_t size, uint32_t *reg_value)
  32. {
  33. response_t response;
  34. command_t command = ((const command_common_t *)cmd_data)->command;
  35. RETURN_ON_ERROR( SLIP_send_delimiter() );
  36. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, size) );
  37. RETURN_ON_ERROR( SLIP_send_delimiter() );
  38. return check_response(command, reg_value, &response, sizeof(response));
  39. }
  40. static esp_loader_error_t send_cmd_with_data(const void *cmd_data, size_t cmd_size,
  41. const void *data, size_t data_size)
  42. {
  43. response_t response;
  44. command_t command = ((const command_common_t *)cmd_data)->command;
  45. RETURN_ON_ERROR( SLIP_send_delimiter() );
  46. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
  47. RETURN_ON_ERROR( SLIP_send(data, data_size) );
  48. RETURN_ON_ERROR( SLIP_send_delimiter() );
  49. return check_response(command, NULL, &response, sizeof(response));
  50. }
  51. static esp_loader_error_t send_cmd_md5(const void *cmd_data, size_t cmd_size, uint8_t md5_out[MD5_SIZE])
  52. {
  53. rom_md5_response_t response;
  54. command_t command = ((const command_common_t *)cmd_data)->command;
  55. RETURN_ON_ERROR( SLIP_send_delimiter() );
  56. RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
  57. RETURN_ON_ERROR( SLIP_send_delimiter() );
  58. RETURN_ON_ERROR( check_response(command, NULL, &response, sizeof(response)) );
  59. memcpy(md5_out, response.md5, MD5_SIZE);
  60. return ESP_LOADER_SUCCESS;
  61. }
  62. static void log_loader_internal_error(error_code_t error)
  63. {
  64. loader_port_debug_print("Error: ");
  65. switch (error) {
  66. case INVALID_CRC: loader_port_debug_print("INVALID_CRC"); break;
  67. case INVALID_COMMAND: loader_port_debug_print("INVALID_COMMAND"); break;
  68. case COMMAND_FAILED: loader_port_debug_print("COMMAND_FAILED"); break;
  69. case FLASH_WRITE_ERR: loader_port_debug_print("FLASH_WRITE_ERR"); break;
  70. case FLASH_READ_ERR: loader_port_debug_print("FLASH_READ_ERR"); break;
  71. case READ_LENGTH_ERR: loader_port_debug_print("READ_LENGTH_ERR"); break;
  72. case DEFLATE_ERROR: loader_port_debug_print("DEFLATE_ERROR"); break;
  73. default: loader_port_debug_print("UNKNOWN ERROR"); break;
  74. }
  75. loader_port_debug_print("\n");
  76. }
  77. static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size)
  78. {
  79. esp_loader_error_t err;
  80. common_response_t *response = (common_response_t *)resp;
  81. do {
  82. err = SLIP_receive_packet(resp, resp_size);
  83. if (err != ESP_LOADER_SUCCESS) {
  84. return err;
  85. }
  86. } while ((response->direction != READ_DIRECTION) || (response->command != cmd));
  87. response_status_t *status = (response_status_t *)((uint8_t *)resp + resp_size - sizeof(response_status_t));
  88. if (status->failed) {
  89. log_loader_internal_error(status->error);
  90. return ESP_LOADER_ERROR_INVALID_RESPONSE;
  91. }
  92. if (reg_value != NULL) {
  93. *reg_value = response->value;
  94. }
  95. return ESP_LOADER_SUCCESS;
  96. }
  97. esp_loader_error_t loader_flash_begin_cmd(uint32_t offset,
  98. uint32_t erase_size,
  99. uint32_t block_size,
  100. uint32_t blocks_to_write,
  101. bool encryption)
  102. {
  103. uint32_t encryption_size = encryption ? sizeof(uint32_t) : 0;
  104. flash_begin_command_t flash_begin_cmd = {
  105. .common = {
  106. .direction = WRITE_DIRECTION,
  107. .command = FLASH_BEGIN,
  108. .size = CMD_SIZE(flash_begin_cmd) - encryption_size,
  109. .checksum = 0
  110. },
  111. .erase_size = erase_size,
  112. .packet_count = blocks_to_write,
  113. .packet_size = block_size,
  114. .offset = offset,
  115. .encrypted = 0
  116. };
  117. s_sequence_number = 0;
  118. return send_cmd(&flash_begin_cmd, sizeof(flash_begin_cmd) - encryption_size, NULL);
  119. }
  120. esp_loader_error_t loader_flash_data_cmd(const uint8_t *data, uint32_t size)
  121. {
  122. data_command_t data_cmd = {
  123. .common = {
  124. .direction = WRITE_DIRECTION,
  125. .command = FLASH_DATA,
  126. .size = CMD_SIZE(data_cmd) + size,
  127. .checksum = compute_checksum(data, size)
  128. },
  129. .data_size = size,
  130. .sequence_number = s_sequence_number++,
  131. };
  132. return send_cmd_with_data(&data_cmd, sizeof(data_cmd), data, size);
  133. }
  134. esp_loader_error_t loader_flash_end_cmd(bool stay_in_loader)
  135. {
  136. flash_end_command_t end_cmd = {
  137. .common = {
  138. .direction = WRITE_DIRECTION,
  139. .command = FLASH_END,
  140. .size = CMD_SIZE(end_cmd),
  141. .checksum = 0
  142. },
  143. .stay_in_loader = stay_in_loader
  144. };
  145. return send_cmd(&end_cmd, sizeof(end_cmd), NULL);
  146. }
  147. esp_loader_error_t loader_mem_begin_cmd(uint32_t offset, uint32_t size, uint32_t blocks_to_write, uint32_t block_size)
  148. {
  149. mem_begin_command_t mem_begin_cmd = {
  150. .common = {
  151. .direction = WRITE_DIRECTION,
  152. .command = MEM_BEGIN,
  153. .size = CMD_SIZE(mem_begin_cmd),
  154. .checksum = 0
  155. },
  156. .total_size = size,
  157. .blocks = blocks_to_write,
  158. .block_size = block_size,
  159. .offset = offset
  160. };
  161. s_sequence_number = 0;
  162. return send_cmd(&mem_begin_cmd, sizeof(mem_begin_cmd), NULL);
  163. }
  164. esp_loader_error_t loader_mem_data_cmd(const uint8_t *data, uint32_t size)
  165. {
  166. data_command_t data_cmd = {
  167. .common = {
  168. .direction = WRITE_DIRECTION,
  169. .command = MEM_DATA,
  170. .size = CMD_SIZE(data_cmd) + size,
  171. .checksum = compute_checksum(data, size)
  172. },
  173. .data_size = size,
  174. .sequence_number = s_sequence_number++,
  175. };
  176. return send_cmd_with_data(&data_cmd, sizeof(data_cmd), data, size);
  177. }
  178. esp_loader_error_t loader_mem_end_cmd(uint32_t entrypoint)
  179. {
  180. mem_end_command_t end_cmd = {
  181. .common = {
  182. .direction = WRITE_DIRECTION,
  183. .command = MEM_END,
  184. .size = CMD_SIZE(end_cmd),
  185. },
  186. .stay_in_loader = (entrypoint == 0),
  187. .entry_point_address = entrypoint
  188. };
  189. return send_cmd(&end_cmd, sizeof(end_cmd), NULL);
  190. }
  191. esp_loader_error_t loader_sync_cmd(void)
  192. {
  193. sync_command_t sync_cmd = {
  194. .common = {
  195. .direction = WRITE_DIRECTION,
  196. .command = SYNC,
  197. .size = CMD_SIZE(sync_cmd),
  198. .checksum = 0
  199. },
  200. .sync_sequence = {
  201. 0x07, 0x07, 0x12, 0x20,
  202. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  203. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  204. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  205. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  206. }
  207. };
  208. return send_cmd(&sync_cmd, sizeof(sync_cmd), NULL);
  209. }
  210. esp_loader_error_t loader_write_reg_cmd(uint32_t address, uint32_t value,
  211. uint32_t mask, uint32_t delay_us)
  212. {
  213. write_reg_command_t write_cmd = {
  214. .common = {
  215. .direction = WRITE_DIRECTION,
  216. .command = WRITE_REG,
  217. .size = CMD_SIZE(write_cmd),
  218. .checksum = 0
  219. },
  220. .address = address,
  221. .value = value,
  222. .mask = mask,
  223. .delay_us = delay_us
  224. };
  225. return send_cmd(&write_cmd, sizeof(write_cmd), NULL);
  226. }
  227. esp_loader_error_t loader_read_reg_cmd(uint32_t address, uint32_t *reg)
  228. {
  229. read_reg_command_t read_cmd = {
  230. .common = {
  231. .direction = WRITE_DIRECTION,
  232. .command = READ_REG,
  233. .size = CMD_SIZE(read_cmd),
  234. .checksum = 0
  235. },
  236. .address = address,
  237. };
  238. return send_cmd(&read_cmd, sizeof(read_cmd), reg);
  239. }
  240. esp_loader_error_t loader_spi_attach_cmd(uint32_t config)
  241. {
  242. spi_attach_command_t attach_cmd = {
  243. .common = {
  244. .direction = WRITE_DIRECTION,
  245. .command = SPI_ATTACH,
  246. .size = CMD_SIZE(attach_cmd),
  247. .checksum = 0
  248. },
  249. .configuration = config,
  250. .zero = 0
  251. };
  252. return send_cmd(&attach_cmd, sizeof(attach_cmd), NULL);
  253. }
  254. esp_loader_error_t loader_change_baudrate_cmd(uint32_t baudrate)
  255. {
  256. change_baudrate_command_t baudrate_cmd = {
  257. .common = {
  258. .direction = WRITE_DIRECTION,
  259. .command = CHANGE_BAUDRATE,
  260. .size = CMD_SIZE(baudrate_cmd),
  261. .checksum = 0
  262. },
  263. .new_baudrate = baudrate,
  264. .old_baudrate = 0 // ESP32 ROM only
  265. };
  266. return send_cmd(&baudrate_cmd, sizeof(baudrate_cmd), NULL);
  267. }
  268. esp_loader_error_t loader_md5_cmd(uint32_t address, uint32_t size, uint8_t *md5_out)
  269. {
  270. spi_flash_md5_command_t md5_cmd = {
  271. .common = {
  272. .direction = WRITE_DIRECTION,
  273. .command = SPI_FLASH_MD5,
  274. .size = CMD_SIZE(md5_cmd),
  275. .checksum = 0
  276. },
  277. .address = address,
  278. .size = size,
  279. .reserved_0 = 0,
  280. .reserved_1 = 0
  281. };
  282. return send_cmd_md5(&md5_cmd, sizeof(md5_cmd), md5_out);
  283. }
  284. esp_loader_error_t loader_spi_parameters(uint32_t total_size)
  285. {
  286. write_spi_command_t spi_cmd = {
  287. .common = {
  288. .direction = WRITE_DIRECTION,
  289. .command = SPI_SET_PARAMS,
  290. .size = 24,
  291. .checksum = 0
  292. },
  293. .id = 0,
  294. .total_size = total_size,
  295. .block_size = 64 * 1024,
  296. .sector_size = 4 * 1024,
  297. .page_size = 0x100,
  298. .status_mask = 0xFFFF,
  299. };
  300. return send_cmd(&spi_cmd, sizeof(spi_cmd), NULL);
  301. }
  302. __attribute__ ((weak)) void loader_port_debug_print(const char *str)
  303. {
  304. }