FreeCalypso > hg > freecalypso-sw
comparison loadtools/flutil.c @ 403:7602443edf0d
fc-loadtool flash: CFI query code implemented, compiles
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 15 Jun 2014 22:06:46 +0000 |
parents | f027c6fbe37e |
children | a212b4968b29 |
comparison
equal
deleted
inserted
replaced
402:582b5052c86d | 403:7602443edf0d |
---|---|
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include "flash.h" | 9 #include "flash.h" |
10 | 10 |
11 extern struct flash_bank_info flash_bank_info[2]; | 11 extern struct flash_bank_info flash_bank_info[2]; |
12 | 12 |
13 static int | |
14 cfi_read_byte(bi, off, ret16p) | |
15 struct flash_bank_info *bi; | |
16 int off; | |
17 uint16_t *ret16p; | |
18 { | |
19 return do_r16(bi->base_addr + (off << 1), ret16p); | |
20 } | |
21 | |
22 static int | |
23 cfi_read_twobyte(bi, off, retptr) | |
24 struct flash_bank_info *bi; | |
25 int off; | |
26 uint16_t *retptr; | |
27 { | |
28 uint16_t lo, hi; | |
29 | |
30 if (cfi_read_byte(bi, off, &lo) < 0) | |
31 return(-1); | |
32 lo &= 0xFF; | |
33 if (cfi_read_byte(bi, off + 1, &hi) < 0) | |
34 return(-1); | |
35 hi &= 0xFF; | |
36 *retptr = (hi << 8) | lo; | |
37 return(0); | |
38 } | |
39 | |
40 static int | |
41 cfi_id_return_to_read_mode(bi) | |
42 struct flash_bank_info *bi; | |
43 { | |
44 if (do_w16(bi->base_addr + 0xAAA, 0xF0)) { | |
45 fprintf(stderr, | |
46 "unexpected response to w16 when resetting flash to read mode!\n"); | |
47 return(-1); | |
48 } | |
49 return(0); | |
50 } | |
51 | |
13 flash_get_cfi(bank) | 52 flash_get_cfi(bank) |
14 { | 53 { |
15 struct flash_bank_info *bi; | 54 struct flash_bank_info *bi; |
55 struct cfi_info *cfi; | |
56 struct flash_region_desc *reg; | |
57 int nr; | |
58 uint16_t rdval; | |
59 uint32_t size_check; | |
16 | 60 |
17 bi = flash_bank_info + bank; | 61 bi = flash_bank_info + bank; |
18 if (bi->cfi) | 62 if (bi->cfi) |
19 return(0); | 63 return(0); |
20 printf("Error: CFI info retrieval not implemented yet\n"); | 64 printf("Performing CFI query\n"); |
21 return(-1); | 65 if (do_w16(bi->base_addr + 0xAA, 0x98)) { |
66 fprintf(stderr, "unexpected response to w16 - aborting\n"); | |
67 return(-1); | |
68 } | |
69 /* if do_r16() returns -1, error msg has already been printed */ | |
70 if (cfi_read_byte(bi, 0x10, &rdval) < 0) | |
71 return(-1); | |
72 if (rdval != 'Q') { | |
73 noqry: fprintf(stderr, "error: no QRY response from flash\n"); | |
74 cfi_id_return_to_read_mode(bi); | |
75 return(-1); | |
76 } | |
77 if (cfi_read_byte(bi, 0x11, &rdval) < 0) | |
78 return(-1); | |
79 if (rdval != 'R') | |
80 goto noqry; | |
81 if (cfi_read_byte(bi, 0x12, &rdval) < 0) | |
82 return(-1); | |
83 if (rdval != 'Y') | |
84 goto noqry; | |
85 cfi = malloc(sizeof(struct cfi_info)); | |
86 if (!cfi) { | |
87 fprintf(stderr, | |
88 "unable to malloc buffer for flash bank %d CFI structure\n", | |
89 bank); | |
90 cfi_id_return_to_read_mode(bi); | |
91 return(-1); | |
92 } | |
93 if (cfi_read_twobyte(bi, 0x13, &cfi->cmdset_style) < 0) { | |
94 free_and_immed_out: | |
95 free(cfi); | |
96 return(-1); | |
97 } | |
98 /* total device size */ | |
99 if (cfi_read_byte(bi, 0x27, &rdval) < 0) | |
100 goto free_and_immed_out; | |
101 if (rdval < 20 || rdval > 24) { | |
102 fprintf(stderr, | |
103 "error: CFI reports unreasonable device size\n"); | |
104 free_and_clean_out: | |
105 free(cfi); | |
106 cfi_id_return_to_read_mode(bi); | |
107 return(-1); | |
108 } | |
109 cfi->total_size = 1 << rdval; | |
110 if (cfi->total_size > bi->bank_desc->align_size) { | |
111 fprintf(stderr, | |
112 "error: CFI device size 0x%lx exceeds configured maximum 0x%lx\n", | |
113 (u_long) cfi->total_size, bi->bank_desc->align_size); | |
114 goto free_and_clean_out; | |
115 } | |
116 if (cfi_read_byte(bi, 0x2C, &rdval) < 0) | |
117 goto free_and_immed_out; | |
118 if (rdval < 1 || rdval > CFI_MAX_REGIONS) { | |
119 fprintf(stderr, | |
120 "error: CFI reports unreasonable # of erase regions\n"); | |
121 goto free_and_clean_out; | |
122 } | |
123 cfi->nregions = rdval; | |
124 cfi->total_sectors = 0; | |
125 size_check = 0; | |
126 for (nr = 0; nr < cfi->nregions; nr++) { | |
127 reg = cfi->regions + nr; | |
128 if (cfi_read_twobyte(bi, 0x2D + nr*4, &rdval) < 0) | |
129 goto free_and_immed_out; | |
130 if (rdval > 255) { | |
131 fprintf(stderr, | |
132 "error: CFI reports unreasonable # of sectors in region %d\n", | |
133 nr); | |
134 goto free_and_clean_out; | |
135 } | |
136 reg->nsectors = rdval + 1; | |
137 cfi->total_sectors += reg->nsectors; | |
138 if (cfi_read_twobyte(bi, 0x2F + nr*4, &rdval) < 0) | |
139 goto free_and_immed_out; | |
140 if (rdval < 0x20 || rdval > 0x400) { | |
141 fprintf(stderr, | |
142 "error: CFI reports unreasonable sector size in region %d\n", | |
143 nr); | |
144 goto free_and_clean_out; | |
145 } | |
146 reg->sector_size = rdval << 8; | |
147 size_check += reg->sector_size * reg->nsectors; | |
148 } | |
149 if (cfi_id_return_to_read_mode(bi) < 0) { | |
150 /* error msg already printed */ | |
151 free(cfi); | |
152 return(-1); | |
153 } | |
154 if (size_check != cfi->total_size) { | |
155 fprintf(stderr, | |
156 "CFI error: added size of erase regions (%lx) != reported devive size (%lx)\n", | |
157 (u_long) size_check, (u_long) cfi->total_size); | |
158 free(cfi); | |
159 return(-1); | |
160 } | |
161 /* all checks passed */ | |
162 bi->cfi = cfi; | |
163 printf( | |
164 "CFI query successful: total size %lx, %u sectors, command set style %04X\n\n", | |
165 (u_long) cfi->total_size, cfi->total_sectors, | |
166 cfi->cmdset_style); | |
167 return(1); | |
22 } | 168 } |
23 | 169 |
24 get_flash_sector_table(bank) | 170 get_flash_sector_table(bank) |
25 { | 171 { |
26 struct flash_bank_info *bi; | 172 struct flash_bank_info *bi; |