ReadFlashMemory2.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. #ifndef READFLASHMEMORY2_SOURCE
  9. #define READFLASHMEMORY2_SOURCE
  10. #include <stdint.h>
  11. #include <unistd.h>
  12. #include <memory.h>
  13. #include "../tools/error.h"
  14. #include "../tools/files.h"
  15. #include "../tools/endian.h"
  16. #include "../tools/memory.h"
  17. #include "../tools/symbol.h"
  18. #include "../ram/nvram.h"
  19. #include "../plc/plc.h"
  20. #include "../nda/nda.h"
  21. /*====================================================================*
  22. *
  23. * signed ReadFlash (struct plc * plc, struct _file_ * file, uint32_t offset, uint32_t extent);
  24. *
  25. * plc.h
  26. *
  27. * Read raw flash memory;
  28. *
  29. * Contributor(s):
  30. * Charles Maier <cmaier@qca.qualcomm.com>
  31. *
  32. *--------------------------------------------------------------------*/
  33. static signed ReadFlash (struct plc * plc, struct _file_ * file, uint32_t offset, uint32_t extent)
  34. {
  35. struct channel * channel = (struct channel *) (plc->channel);
  36. struct message * message = (struct message *) (plc->message);
  37. #ifndef __GNUC__
  38. #pragma pack (push,1)
  39. #endif
  40. struct __packed vs_module_operation_read_request
  41. {
  42. struct ethernet_hdr ethernet;
  43. struct qualcomm_hdr qualcomm;
  44. uint32_t RESERVED;
  45. uint8_t NUM_OP_DATA;
  46. struct __packed
  47. {
  48. uint16_t MOD_OP;
  49. uint16_t MOD_OP_DATA_LEN;
  50. uint32_t MOD_OP_RSVD;
  51. uint16_t MODULE_ID;
  52. uint16_t MODULE_SUB_ID;
  53. uint16_t MODULE_LENGTH;
  54. uint32_t MODULE_OFFSET;
  55. }
  56. MODULE_SPEC;
  57. }
  58. * request = (struct vs_module_operation_read_request *) (message);
  59. struct __packed vs_module_operation_read_confirm
  60. {
  61. struct ethernet_hdr ethernet;
  62. struct qualcomm_hdr qualcomm;
  63. uint16_t MSTATUS;
  64. uint16_t ERR_REC_CODE;
  65. uint32_t RESERVED;
  66. uint8_t NUM_OP_DATA;
  67. struct __packed
  68. {
  69. uint16_t MOD_OP;
  70. uint16_t MOD_OP_DATA_LEN;
  71. uint32_t MOD_OP_RSVD;
  72. uint16_t MODULE_ID;
  73. uint16_t MODULE_SUB_ID;
  74. uint16_t MODULE_LENGTH;
  75. uint32_t MODULE_OFFSET;
  76. }
  77. MODULE_SPEC;
  78. uint8_t MODULE_DATA [PLC_MODULE_SIZE];
  79. }
  80. * confirm = (struct vs_module_operation_read_confirm *) (message);
  81. #ifndef __GNUC__
  82. #pragma pack (pop)
  83. #endif
  84. unsigned length = PLC_MODULE_SIZE;
  85. unsigned timeout = channel->timeout;
  86. Request (plc, "Reading Flash Memory");
  87. while (extent)
  88. {
  89. memset (message, 0, sizeof (* message));
  90. EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
  91. QualcommHeader (& request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ));
  92. plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  93. if (length > extent)
  94. {
  95. length = extent;
  96. }
  97. request->NUM_OP_DATA = 1;
  98. request->MODULE_SPEC.MOD_OP = HTOLE16 (PLC_MOD_OP_READ_FLASH);
  99. request->MODULE_SPEC.MOD_OP_DATA_LEN = HTOLE16 (sizeof (request->MODULE_SPEC));
  100. request->MODULE_SPEC.MOD_OP_RSVD = HTOLE32 (0);
  101. request->MODULE_SPEC.MODULE_ID = HTOLE16 (PLC_MODULEID_RESERVED1);
  102. request->MODULE_SPEC.MODULE_SUB_ID = HTOLE16 (0);
  103. request->MODULE_SPEC.MODULE_LENGTH = HTOLE16 (length);
  104. request->MODULE_SPEC.MODULE_OFFSET = HTOLE32 (offset);
  105. #if 0
  106. #if defined (__GNUC__)
  107. #warning "Debug code active in module ModuleRead"
  108. #endif
  109. fprintf (stderr, "----- \n");
  110. fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (request->RESERVED));
  111. fprintf (stderr, "NUM_OP_DATA %d\n", request->NUM_OP_DATA);
  112. fprintf (stderr, "MOD_OP 0x%02X\n", LE16TOH (request->MODULE_SPEC.MOD_OP));
  113. fprintf (stderr, "MOD_OP_DATA_LEN %d\n", LE16TOH (request->MODULE_SPEC.MOD_OP_DATA_LEN));
  114. fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (request->MODULE_SPEC.MOD_OP_RSVD));
  115. fprintf (stderr, "MODULE_ID 0x%04X\n", LE16TOH (request->MODULE_SPEC.MODULE_ID));
  116. fprintf (stderr, "MODULE_SUB_ID 0x%04X\n", LE16TOH (request->MODULE_SPEC.MODULE_SUB_ID));
  117. fprintf (stderr, "MODULE_LENGTH %d\n", LE16TOH (request->MODULE_SPEC.MODULE_LENGTH));
  118. fprintf (stderr, "MODULE_OFFSET 0x%08X\n", LE32TOH (request->MODULE_SPEC.MODULE_OFFSET));
  119. fprintf (stderr, "\n");
  120. #endif
  121. if (SendMME (plc) <= 0)
  122. {
  123. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  124. return (-1);
  125. }
  126. channel->timeout = PLC_MODULE_READ_TIMEOUT;
  127. if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0)
  128. {
  129. error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
  130. return (-1);
  131. }
  132. channel->timeout = timeout;
  133. #if 0
  134. #if defined (__GNUC__)
  135. #warning "Debug code active in module ModuleRead"
  136. #endif
  137. fprintf (stderr, "MSTATUS 0x%04X\n", LE16TOH (confirm->MSTATUS));
  138. fprintf (stderr, "ERROR_REC_CODE %d\n", LE16TOH (confirm->ERR_REC_CODE));
  139. fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (confirm->RESERVED));
  140. fprintf (stderr, "NUM_OP_DATA %d\n", confirm->NUM_OP_DATA);
  141. fprintf (stderr, "MOD_OP 0x%02X\n", LE16TOH (confirm->MODULE_SPEC.MOD_OP));
  142. fprintf (stderr, "MOD_OP_DATA_LEN %d\n", LE16TOH (confirm->MODULE_SPEC.MOD_OP_DATA_LEN));
  143. fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (confirm->MODULE_SPEC.MOD_OP_RSVD));
  144. fprintf (stderr, "MODULE_ID 0x%04X\n", LE16TOH (confirm->MODULE_SPEC.MODULE_ID));
  145. fprintf (stderr, "MODULE_SUB_ID 0x%04X\n", LE16TOH (confirm->MODULE_SPEC.MODULE_SUB_ID));
  146. fprintf (stderr, "MODULE_LENGTH %d\n", LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH));
  147. fprintf (stderr, "MODULE_OFFSET 0x%08X\n", LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET));
  148. fprintf (stderr, "\n");
  149. #endif
  150. if (LE16TOH (confirm->MSTATUS))
  151. {
  152. Failure (plc, PLC_WONTDOIT);
  153. return (-1);
  154. }
  155. length = LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH);
  156. offset = LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET);
  157. if (write (file->file, confirm->MODULE_DATA, length) != (signed) (length))
  158. {
  159. error (PLC_EXIT (plc), errno, FILE_CANTSAVE, file->name);
  160. return (-1);
  161. }
  162. offset += length;
  163. extent -= length;
  164. }
  165. return (0);
  166. }
  167. /*====================================================================*
  168. *
  169. * signed ReadFlashMemory2 (struct plc * plc);
  170. *
  171. * plc.h
  172. *
  173. * determine the overall size of flash memory with VS_GET_NVM then
  174. * erase flash memory by writing 0xFF to all of flash memory using
  175. * VS_MODULE_OPERATION messages; force flash but do not reset;
  176. *
  177. * struct vs_module_spec is defined in plc.h;
  178. *
  179. * Contributor(s):
  180. * Charles Maier <cmaier@qca.qualcomm.com>
  181. *
  182. *--------------------------------------------------------------------*/
  183. signed ReadFlashMemory2 (struct plc * plc)
  184. {
  185. struct channel * channel = (struct channel *) (plc->channel);
  186. struct message * message = (struct message *) (plc->message);
  187. #ifndef __GNUC__
  188. #pragma pack (push,1)
  189. #endif
  190. struct __packed vs_get_nvm_request
  191. {
  192. struct ethernet_hdr ethernet;
  193. struct qualcomm_hdr qualcomm;
  194. }
  195. * request = (struct vs_get_nvm_request *) (message);
  196. struct __packed vs_get_nvm_confirm
  197. {
  198. struct ethernet_hdr ethernet;
  199. struct qualcomm_hdr qualcomm;
  200. uint8_t MSTATUS;
  201. struct config_nvram config_nvram;
  202. }
  203. * confirm = (struct vs_get_nvm_confirm *) (message);
  204. #ifndef __GNUC__
  205. #pragma pack (pop)
  206. #endif
  207. memcpy (channel->peer, message->ethernet.OSA, sizeof (channel->peer));
  208. Request (plc, "Probing Flash Memory");
  209. memset (message, 0, sizeof (* message));
  210. EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
  211. QualcommHeader (& request->qualcomm, 0, (VS_GET_NVM | MMTYPE_REQ));
  212. plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
  213. if (SendMME (plc) <= 0)
  214. {
  215. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  216. return (-1);
  217. }
  218. if (ReadMME (plc, 0, (VS_GET_NVM | MMTYPE_CNF)) <= 0)
  219. {
  220. error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
  221. return (-1);
  222. }
  223. if (confirm->MSTATUS)
  224. {
  225. Failure (plc, PLC_WONTDOIT);
  226. return (-1);
  227. }
  228. if (ReadFlash (plc, & plc->nvm, 0, LE32TOH (confirm->config_nvram.NVRAMSIZE)))
  229. {
  230. return (-1);
  231. }
  232. return (0);
  233. }
  234. #endif