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;