memimg.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. ** This file is part of fsusb_picdem
  3. **
  4. ** fsusb_picdem is free software; you can redistribute it and/or
  5. ** modify it under the terms of the GNU General Public License as
  6. ** published by the Free Software Foundation; either version 2 of the
  7. ** License, or (at your option) any later version.
  8. **
  9. ** fsusb_picdem is distributed in the hope that it will be useful, but
  10. ** WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ** General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with fsusb_picdem; if not, write to the Free Software
  16. ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. ** 02110-1301, USA
  18. */
  19. #include "memimg.h"
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. /* mi_make_patch: Allocate and initialize a mi_patch
  24. */
  25. mi_patch *mi_make_patch(unsigned long base, unsigned long top)
  26. {
  27. mi_patch *pat;
  28. pat=malloc(sizeof(mi_patch));
  29. if(pat == NULL) {
  30. return NULL;
  31. }
  32. pat->base=base;
  33. pat->top=top;
  34. pat->contents=malloc(sizeof(mi_byte_t)*(top-base));
  35. if(pat->contents == NULL) {
  36. free(pat);
  37. return NULL;
  38. }
  39. memset(pat->contents, 0xff, sizeof(mi_byte_t)*(top-base));
  40. pat->mask=malloc(sizeof(char)*(top-base));
  41. if(pat->mask == NULL) {
  42. free(pat->contents);
  43. free(pat);
  44. return NULL;
  45. }
  46. memset(pat->mask, 0, sizeof(char)*(top-base));
  47. return pat;
  48. }
  49. /* mi_free_patch: Free a mi_patch and its buffers
  50. */
  51. void mi_free_patch(mi_patch *p)
  52. {
  53. if(p == NULL) {
  54. return;
  55. }
  56. free(p->contents);
  57. free(p->mask);
  58. free(p);
  59. }
  60. /* mi_free_image: Free a mi_patch and its contents
  61. */
  62. void mi_free_image(mi_image *i)
  63. {
  64. if(i == NULL) {
  65. return;
  66. }
  67. mi_free_patch(i->program);
  68. mi_free_patch(i->id);
  69. mi_free_patch(i->config);
  70. mi_free_patch(i->devid);
  71. mi_free_patch(i->eeprom);
  72. free(i);
  73. }
  74. /* mi_modify_patch: Modify patch contents, tagging it as changed
  75. */
  76. void mi_modify_patch(mi_patch *p, int base, int len, mi_byte_t *data)
  77. {
  78. int i;
  79. if(p == NULL) {
  80. return;
  81. }
  82. if(base<p->base || base+len-1 > p->top) {
  83. printf("*** mi_modify_patch(): patch out of range\n");
  84. return;
  85. }
  86. for(i=0;i<len;i++) {
  87. p->contents[base - p->base + i]=data[i];
  88. p->mask[base - p->base + i]=0xff;
  89. }
  90. }
  91. /* mi_image: Create a mi_image from the contents of filename
  92. */
  93. mi_image *mi_load_hexfile(char *filename)
  94. {
  95. mi_image *img;
  96. hex_record *r;
  97. FILE *f;
  98. hex_file *hf;
  99. if(filename == NULL) {
  100. return NULL;
  101. }
  102. f=fopen(filename, "r");
  103. if(f == NULL) {
  104. return NULL;
  105. }
  106. hf=hex_open(f);
  107. if(hf == NULL) {
  108. fclose(f);
  109. return NULL;
  110. }
  111. img=malloc(sizeof(mi_image));
  112. if(img == NULL) {
  113. fclose(f);
  114. free(hf);
  115. return NULL;
  116. }
  117. /* These nulls may not be required, but make me feel safer when
  118. * using free_image() on an error
  119. */
  120. img->program = NULL;
  121. img->id = NULL;
  122. img->config = NULL;
  123. img->devid = NULL;
  124. img->eeprom = NULL;
  125. img->program=mi_make_patch(MI_PROGRAM_BASE, MI_PROGRAM_TOP);
  126. img->id=mi_make_patch(MI_ID_BASE, MI_ID_TOP);
  127. img->config=mi_make_patch(MI_CONFIG_BASE, MI_CONFIG_TOP);
  128. img->devid=mi_make_patch(MI_DEVID_BASE, MI_DEVID_TOP);
  129. img->eeprom=mi_make_patch(MI_EEPROM_BASE, MI_EEPROM_TOP);
  130. if(img->program == NULL || img->id == NULL || img->config == NULL
  131. || img->devid == NULL || img->eeprom == NULL) {
  132. fclose(f);
  133. free(hf);
  134. mi_free_image(img);
  135. return NULL;
  136. }
  137. while((r=hex_read(hf))) {
  138. if(r->type == 0) {
  139. /*
  140. printf("file: %.2i@0x%.8X:\t", r->datlen, r->addr);
  141. for(i=0;i<r->datlen;i++) {
  142. printf("%.2x", r->data[i]);
  143. }
  144. printf("\n");
  145. */
  146. if(r->addr >= MI_PROGRAM_BASE && r->addr <= MI_PROGRAM_TOP) {
  147. // printf("Program memory\n");
  148. mi_modify_patch(img->program, r->addr, r->datlen, r->data);
  149. }
  150. if(r->addr >= MI_ID_BASE && r->addr <= MI_ID_TOP) {
  151. // printf("ID memory\n");
  152. mi_modify_patch(img->id, r->addr, r->datlen, r->data);
  153. }
  154. if(r->addr >= MI_CONFIG_BASE && r->addr <= MI_CONFIG_TOP) {
  155. // printf("Config memory\n");
  156. mi_modify_patch(img->config, r->addr, r->datlen, r->data);
  157. }
  158. if(r->addr >= MI_DEVID_BASE && r->addr <= MI_DEVID_TOP) {
  159. // printf("Devid memory\n");
  160. mi_modify_patch(img->devid, r->addr, r->datlen, r->data);
  161. }
  162. }
  163. free(r);
  164. // printf("\n");
  165. }
  166. free(hf);
  167. fclose(f);
  168. return img;
  169. }