1 | #ifndef FLASH_GLUE_INTERFACE_H |
---|
2 | #define FLASH_GLUE_INTERFACE_H |
---|
3 | |
---|
4 | |
---|
5 | /* Trivial flash programmer (for restrictions see below) */ |
---|
6 | |
---|
7 | /* Author: Till Straumann <strauman@slac.stanford.edu>, 2006 */ |
---|
8 | |
---|
9 | /* DO NOT INCLUDE THIS HEADER FROM APPLICATION CODE */ |
---|
10 | |
---|
11 | /* |
---|
12 | * Glue interface -- to be used only internally by BSP |
---|
13 | * and chip drivers: |
---|
14 | * - BSP provides info about what chip drivers to use |
---|
15 | * as well as 'wiring' info (how many devices are |
---|
16 | * operated in parallel etc). |
---|
17 | * - Chip drivers provide low-level 'methods' / 'ops' |
---|
18 | * for performing basic operations which are used |
---|
19 | * by the code in 'flash.c'. |
---|
20 | */ |
---|
21 | |
---|
22 | /* To keep things simple, this API makes a few assumptions about the |
---|
23 | * hardware: |
---|
24 | * |
---|
25 | * - devices operate with 16-bit data width |
---|
26 | * - two devices are used in parallel (stride 4) to |
---|
27 | * provide 32-bit data. I.e., the devices are |
---|
28 | * organized like this: |
---|
29 | * unsigned short flash[FLASH_SIZE][2]; |
---|
30 | * - no endianness issues (i.e., flash endianness == CPU endianness) |
---|
31 | * - fixed block size |
---|
32 | * - fixed buffer size |
---|
33 | * - all devices in a bank are identical |
---|
34 | * - NOT THREAD SAFE; no locking scheme is implemented. |
---|
35 | * - cannot copy within same flash bank. |
---|
36 | * - write-timeout uses polling/busy-wait |
---|
37 | * |
---|
38 | * FIXME: code should be revised to remove assumptions on stride and 16-bit |
---|
39 | * width to make it more generic. |
---|
40 | */ |
---|
41 | |
---|
42 | /* |
---|
43 | * Authorship |
---|
44 | * ---------- |
---|
45 | * This software was created by |
---|
46 | * Till Straumann <strauman@slac.stanford.edu>, 2005-2007, |
---|
47 | * Stanford Linear Accelerator Center, Stanford University. |
---|
48 | * |
---|
49 | * Acknowledgement of sponsorship |
---|
50 | * ------------------------------ |
---|
51 | * The software was produced by |
---|
52 | * the Stanford Linear Accelerator Center, Stanford University, |
---|
53 | * under Contract DE-AC03-76SFO0515 with the Department of Energy. |
---|
54 | * |
---|
55 | * Government disclaimer of liability |
---|
56 | * ---------------------------------- |
---|
57 | * Neither the United States nor the United States Department of Energy, |
---|
58 | * nor any of their employees, makes any warranty, express or implied, or |
---|
59 | * assumes any legal liability or responsibility for the accuracy, |
---|
60 | * completeness, or usefulness of any data, apparatus, product, or process |
---|
61 | * disclosed, or represents that its use would not infringe privately owned |
---|
62 | * rights. |
---|
63 | * |
---|
64 | * Stanford disclaimer of liability |
---|
65 | * -------------------------------- |
---|
66 | * Stanford University makes no representations or warranties, express or |
---|
67 | * implied, nor assumes any liability for the use of this software. |
---|
68 | * |
---|
69 | * Stanford disclaimer of copyright |
---|
70 | * -------------------------------- |
---|
71 | * Stanford University, owner of the copyright, hereby disclaims its |
---|
72 | * copyright and all other rights in this software. Hence, anyone may |
---|
73 | * freely use it for any purpose without restriction. |
---|
74 | * |
---|
75 | * Maintenance of notices |
---|
76 | * ---------------------- |
---|
77 | * In the interest of clarity regarding the origin and status of this |
---|
78 | * SLAC software, this and all the preceding Stanford University notices |
---|
79 | * are to remain affixed to any copy or derivative of this software made |
---|
80 | * or distributed by the recipient and are to be affixed to any copy of |
---|
81 | * software made or distributed by the recipient that contains a copy or |
---|
82 | * derivative of this software. |
---|
83 | * |
---|
84 | * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 |
---|
85 | */ |
---|
86 | |
---|
87 | #include <stdint.h> |
---|
88 | |
---|
89 | #define NumberOf(arr) (sizeof(arr)/sizeof(arr[0])) |
---|
90 | |
---|
91 | #define FLASH_STRIDE(b) 4 /* bytes; currently fixed */ |
---|
92 | #define FLASH_WIDTH(b) ((b)->width) |
---|
93 | #define FLASH_NDEVS(b) (FLASH_STRIDE(b)/FLASH_WIDTH(b)) |
---|
94 | |
---|
95 | /* Type declarations */ |
---|
96 | |
---|
97 | /* Registers */ |
---|
98 | typedef uint8_t _u8_a_t __attribute__((may_alias)); |
---|
99 | typedef uint16_t _u16_a_t __attribute__((may_alias)); |
---|
100 | typedef uint32_t _u32_a_t __attribute__((may_alias)); |
---|
101 | |
---|
102 | /* Register addresses */ |
---|
103 | typedef volatile _u8_a_t *A8; |
---|
104 | typedef volatile _u16_a_t *A16; |
---|
105 | typedef volatile _u32_a_t *A32; |
---|
106 | |
---|
107 | struct flash_bank_ops; |
---|
108 | |
---|
109 | /* |
---|
110 | * Description of a flash bank. Multiple |
---|
111 | * devices that are used in parallel to |
---|
112 | * make up words of FLASH_STRIDE bytes |
---|
113 | * are a 'physical' bank. |
---|
114 | * |
---|
115 | * A bank can even be a 'logical' bank |
---|
116 | * if it includes chip-select logic, i.e., |
---|
117 | * int can contain multiple adjacent |
---|
118 | * 'physical' banks |
---|
119 | * |
---|
120 | * The BSP must provide an array of 'bankdesc' |
---|
121 | * structs and it must initialize the fields |
---|
122 | * |
---|
123 | * 'start' |
---|
124 | * size of bank; may be set to zero to instruct |
---|
125 | * the driver to scan a bank of 'max_size' for |
---|
126 | * devices (i.e., bank may not be fully populated) |
---|
127 | * 'max_size' |
---|
128 | * size of fully populated bank (defines address range |
---|
129 | * that is scanned for devices). |
---|
130 | * If 'max_size' is negative then scanning starts from |
---|
131 | * the top rather than from the bottom. |
---|
132 | * 'width' |
---|
133 | * width of a single device (in bytes). E.g., if |
---|
134 | * 2 16-bit devices are used to form a (ATM fixed) |
---|
135 | * stride of 4 then 'width = 2'. If four 8-bit |
---|
136 | * devices are employed then 'width=1'. |
---|
137 | * 'knownVendors' |
---|
138 | * array of vendors descriptions to use for scanning |
---|
139 | * the bank. |
---|
140 | * |
---|
141 | */ |
---|
142 | struct bankdesc { |
---|
143 | uint32_t start; /* start of bank (CPU address) */ |
---|
144 | uint32_t size; /* in bytes (figured out automatically) */ |
---|
145 | int max_size; /* in case multiple banks are adjacent; |
---|
146 | * if max_size < 0 then the bank is scanned |
---|
147 | * backwards (from top->bottom) for devices |
---|
148 | */ |
---|
149 | int width; /* FIXME there might be implicit assumptions still |
---|
150 | * that width == 2 |
---|
151 | */ |
---|
152 | struct vendesc *knownVendors; |
---|
153 | /* TODO: we assume identical devices within a bank... */ |
---|
154 | |
---|
155 | /* The next three variables cache information obtained |
---|
156 | * from the applicable vendor and device descriptions. |
---|
157 | * They are written by BSP_flashCheckId(). |
---|
158 | */ |
---|
159 | uint32_t fblksz; /* block size in bytes; includes counting |
---|
160 | * parallel 16-bit devices, i.e., if a |
---|
161 | * single device has a block-size of xxx |
---|
162 | * then fblksz = xxx*ndevs. |
---|
163 | */ |
---|
164 | struct devdesc *dd; |
---|
165 | struct flash_bank_ops *ops; |
---|
166 | }; |
---|
167 | |
---|
168 | struct devdesc { |
---|
169 | uint32_t id; /* numerical ID (matched against |
---|
170 | * ID read from device). |
---|
171 | */ |
---|
172 | char *name; /* informational name */ |
---|
173 | uint32_t size; /* bytes */ |
---|
174 | uint32_t bufsz; /* size of write buffer (bytes) */ |
---|
175 | uint32_t fblksz; /* sector/block size (bytes) */ |
---|
176 | }; |
---|
177 | |
---|
178 | struct vendesc { |
---|
179 | uint32_t id; /* numerical ID (matched against |
---|
180 | * ID read from device). |
---|
181 | */ |
---|
182 | char *name; /* informational name */ |
---|
183 | |
---|
184 | /* array of supported devices; |
---|
185 | * the 'ops' specified below |
---|
186 | * are used to access these devices |
---|
187 | */ |
---|
188 | struct devdesc *known_devs; |
---|
189 | /* access methods for talking to |
---|
190 | * devices associated with this |
---|
191 | * vendor description. |
---|
192 | */ |
---|
193 | struct flash_bank_ops *ops; |
---|
194 | }; |
---|
195 | |
---|
196 | /* Device Access Methods ('ops'); these must be |
---|
197 | * implemented by low-level chip drivers |
---|
198 | */ |
---|
199 | |
---|
200 | struct flash_bank_ops { |
---|
201 | /* Read vendor/device ID; Return 0 on success, nonzero if unable to read id */ |
---|
202 | int (*get_id)(struct bankdesc *b, uint32_t addr, uint32_t *pVendorId, uint32_t *pDeviceId); |
---|
203 | /* Unlock block holding 'addr'ess |
---|
204 | * |
---|
205 | * NOTES: - device switched back to array mode on exit. |
---|
206 | * - 'addr' must be 32-bit aligned. |
---|
207 | */ |
---|
208 | |
---|
209 | void (*unlock_block)(struct bankdesc *b, uint32_t addr); |
---|
210 | /* Lock block holding 'addr'ess |
---|
211 | * |
---|
212 | * NOTES: - device switched back to array mode on exit. |
---|
213 | * - 'addr' must be 32-bit aligned. |
---|
214 | */ |
---|
215 | |
---|
216 | void (*lock_block)(struct bankdesc *b, uint32_t addr); |
---|
217 | /* Erase single block holding 'addr'ess. The routine may |
---|
218 | * assume that the address is block/sector aligned. |
---|
219 | * |
---|
220 | * RETURNS: zero on error, device status on failure. |
---|
221 | * |
---|
222 | * NOTES: - device switched back to array mode on exit. |
---|
223 | * - 'addr' must be 32-bit aligned. |
---|
224 | */ |
---|
225 | int (*erase_block)(struct bankdesc *b, uint32_t addr); |
---|
226 | /* Query the status of the device and assert it's readiness |
---|
227 | * leave off in array-reading mode. |
---|
228 | * |
---|
229 | * RETURNS: 0 on success, error status (result of status query) on error. |
---|
230 | * |
---|
231 | * NOTES: - error message is printed to stderr. |
---|
232 | * - device switched back to array mode on exit. |
---|
233 | * - 'addr' must be 32-bit aligned. |
---|
234 | */ |
---|
235 | uint32_t (*check_ready)(struct bankdesc *b, uint32_t addr); |
---|
236 | /* Dump status bits (F_CMD_RD_STA results); |
---|
237 | * 'verbose' prints non-error bits, too |
---|
238 | */ |
---|
239 | void (*print_stat)(struct bankdesc *b, uint32_t sta, int verbose); |
---|
240 | /* Switch to array mode; 'addr' can be assumed to be stride-aligned */ |
---|
241 | void (*array_mode)(struct bankdesc *b, uint32_t addr); |
---|
242 | /* Write N bytes from 'src' to flash: |
---|
243 | * 'src[0] .. src[N-1]' -> addr[0]..addr[N-1]. |
---|
244 | * N may be assumed to be a multiple of 'stride' |
---|
245 | * RETURNS: failure status or zero on success. |
---|
246 | */ |
---|
247 | uint32_t (*write_line)(struct bankdesc *b, uint32_t addr, char *src, uint32_t N); |
---|
248 | }; |
---|
249 | |
---|
250 | /* BSP ops (detect banks, handle write-protection on board); |
---|
251 | * these must be implemented by the BSP. |
---|
252 | */ |
---|
253 | |
---|
254 | struct flash_bsp_ops { |
---|
255 | /* Return descriptor for bank # 'bank' or NULL (invalid arg) */ |
---|
256 | struct bankdesc *(*bankcheck)(int bank, int quiet); |
---|
257 | /* set (enbl:1), clear (enbl:0) or query (enbl:-1) |
---|
258 | * on-board write protection. |
---|
259 | * |
---|
260 | * RETURNS 0 on success, nonzero on error. |
---|
261 | */ |
---|
262 | int (*flash_wp)(int bank, int enbl); |
---|
263 | /* read a running us clock (for polling timeout) */ |
---|
264 | uint32_t (*read_us_timer)(); |
---|
265 | }; |
---|
266 | |
---|
267 | /* This must be provided by the BSP */ |
---|
268 | extern struct flash_bsp_ops BSP_flashBspOps; |
---|
269 | |
---|
270 | /* Available low-level flash drivers, so far */ |
---|
271 | extern struct vendesc BSP_flash_vendor_intel[]; |
---|
272 | extern struct vendesc BSP_flash_vendor_spansion[]; |
---|
273 | |
---|
274 | #endif |
---|