sim: cfi: new flash device simulation
[deliverable/binutils-gdb.git] / sim / common / dv-cfi.c
1 /* Common Flash Memory Interface (CFI) model.
2 http://www.spansion.com/Support/AppNotes/CFI_Spec_AN_03.pdf
3 http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
4
5 Copyright (C) 2010-2011 Free Software Foundation, Inc.
6 Contributed by Analog Devices, Inc.
7
8 This file is part of simulators.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22
23 /* TODO: support vendor query tables. */
24
25 #include "cconfig.h"
26
27 #include <math.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #ifdef HAVE_SYS_MMAN_H
32 #include <sys/mman.h>
33 #endif
34
35 #include "sim-main.h"
36 #include "devices.h"
37 #include "dv-cfi.h"
38
39 /* Flashes are simple state machines, so here we cover all the
40 different states a device might be in at any particular time. */
41 enum cfi_state
42 {
43 CFI_STATE_READ,
44 CFI_STATE_READ_ID,
45 CFI_STATE_CFI_QUERY,
46 CFI_STATE_PROTECT,
47 CFI_STATE_STATUS,
48 CFI_STATE_ERASE,
49 CFI_STATE_WRITE,
50 CFI_STATE_WRITE_BUFFER,
51 CFI_STATE_WRITE_BUFFER_CONFIRM,
52 };
53
54 /* This is the structure that all CFI conforming devices must provided
55 when asked for it. This allows a single driver to dynamically support
56 different flash geometries without having to hardcode specs.
57
58 If you want to start mucking about here, you should just grab the
59 CFI spec and review that (see top of this file for URIs). */
60 struct cfi_query
61 {
62 /* This is always 'Q' 'R' 'Y'. */
63 unsigned char qry[3];
64 /* Primary vendor ID. */
65 unsigned char p_id[2];
66 /* Primary query table address. */
67 unsigned char p_adr[2];
68 /* Alternate vendor ID. */
69 unsigned char a_id[2];
70 /* Alternate query table address. */
71 unsigned char a_adr[2];
72 union
73 {
74 /* Voltage levels. */
75 unsigned char voltages[4];
76 struct
77 {
78 /* Normal min voltage level. */
79 unsigned char vcc_min;
80 /* Normal max voltage level. */
81 unsigned char vcc_max;
82 /* Programming min volage level. */
83 unsigned char vpp_min;
84 /* Programming max volage level. */
85 unsigned char vpp_max;
86 };
87 };
88 union
89 {
90 /* Operational timeouts. */
91 unsigned char timeouts[8];
92 struct
93 {
94 /* Typical timeout for writing a single "unit". */
95 unsigned char timeout_typ_unit_write;
96 /* Typical timeout for writing a single "buffer". */
97 unsigned char timeout_typ_buf_write;
98 /* Typical timeout for erasing a block. */
99 unsigned char timeout_typ_block_erase;
100 /* Typical timeout for erasing the chip. */
101 unsigned char timeout_typ_chip_erase;
102 /* Max timeout for writing a single "unit". */
103 unsigned char timeout_max_unit_write;
104 /* Max timeout for writing a single "buffer". */
105 unsigned char timeout_max_buf_write;
106 /* Max timeout for erasing a block. */
107 unsigned char timeout_max_block_erase;
108 /* Max timeout for erasing the chip. */
109 unsigned char timeout_max_chip_erase;
110 };
111 };
112 /* Flash size is 2^dev_size bytes. */
113 unsigned char dev_size;
114 /* Flash device interface description. */
115 unsigned char iface_desc[2];
116 /* Max length of a single buffer write is 2^max_buf_write_len bytes. */
117 unsigned char max_buf_write_len[2];
118 /* Number of erase regions. */
119 unsigned char num_erase_regions;
120 /* The erase regions would now be an array after this point, but since
121 it is dynamic, we'll provide that from "struct cfi" when requested. */
122 /*unsigned char erase_region_info;*/
123 };
124
125 /* Flashes may have regions with different erase sizes. There is one
126 structure per erase region. */
127 struct cfi_erase_region
128 {
129 unsigned blocks;
130 unsigned size;
131 unsigned start;
132 unsigned end;
133 };
134
135 struct cfi;
136
137 /* Flashes are accessed via commands -- you write a certain number to
138 a special address to change the flash state and access info other
139 than the data. Diff companies have implemented their own command
140 set. This structure abstracts the different command sets so that
141 we can support multiple ones with just a single sim driver. */
142 struct cfi_cmdset
143 {
144 unsigned id;
145 void (*setup) (struct hw *me, struct cfi *cfi);
146 bool (*write) (struct hw *me, struct cfi *cfi, const void *source,
147 unsigned offset, unsigned value, unsigned nr_bytes);
148 bool (*read) (struct hw *me, struct cfi *cfi, void *dest,
149 unsigned offset, unsigned shifted_offset, unsigned nr_bytes);
150 };
151
152 /* The per-flash state. Much of this comes from the device tree which
153 people declare themselves. See top of attach_cfi_regs() for more
154 info. */
155 struct cfi
156 {
157 unsigned width, dev_size, status;
158 enum cfi_state state;
159 unsigned char *data, *mmap;
160
161 struct cfi_query query;
162 const struct cfi_cmdset *cmdset;
163
164 unsigned char *erase_region_info;
165 struct cfi_erase_region *erase_regions;
166 };
167
168 /* Helpful strings which are used with HW_TRACE. */
169 static const char * const state_names[] =
170 {
171 "READ", "READ_ID", "CFI_QUERY", "PROTECT", "STATUS", "ERASE", "WRITE",
172 "WRITE_BUFFER", "WRITE_BUFFER_CONFIRM",
173 };
174 \f
175 /* Erase the block specified by the offset into the given CFI flash. */
176 static void
177 cfi_erase_block (struct hw *me, struct cfi *cfi, unsigned offset)
178 {
179 unsigned i;
180 struct cfi_erase_region *region;
181
182 /* If no erase regions, then we can only do whole chip erase. */
183 /* XXX: Is this within spec ? Or must there always be at least one ? */
184 if (!cfi->query.num_erase_regions)
185 memset (cfi->data, 0xff, cfi->dev_size);
186
187 for (i = 0; i < cfi->query.num_erase_regions; ++i)
188 {
189 region = &cfi->erase_regions[i];
190
191 if (offset >= region->end)
192 continue;
193
194 /* XXX: Does spec require the erase addr to be erase block aligned ?
195 Maybe this is check is overly cautious ... */
196 offset &= ~(region->size - 1);
197 memset (cfi->data + offset, 0xff, region->size);
198 break;
199 }
200 }
201
202 /* Depending on the bus width, addresses might be bit shifted. This
203 helps us normalize everything without cluttering up the rest of
204 the code. */
205 static unsigned
206 cfi_unshift_addr (struct cfi *cfi, unsigned addr)
207 {
208 switch (cfi->width)
209 {
210 case 4: addr >>= 1; /* fallthrough. */
211 case 2: addr >>= 1;
212 }
213 return addr;
214 }
215
216 /* CFI requires all values to be little endian in its structure, so
217 this helper writes a 16bit value into a little endian byte buffer. */
218 static void
219 cfi_encode_16bit (unsigned char *data, unsigned num)
220 {
221 data[0] = num;
222 data[1] = num >> 8;
223 }
224 \f
225 /* The functions required to implement the Intel command set. */
226
227 static bool
228 cmdset_intel_write (struct hw *me, struct cfi *cfi, const void *source,
229 unsigned offset, unsigned value, unsigned nr_bytes)
230 {
231 switch (cfi->state)
232 {
233 case CFI_STATE_READ:
234 case CFI_STATE_READ_ID:
235 switch (value)
236 {
237 case INTEL_CMD_ERASE_BLOCK:
238 cfi->state = CFI_STATE_ERASE;
239 break;
240 case INTEL_CMD_WRITE:
241 case INTEL_CMD_WRITE_ALT:
242 cfi->state = CFI_STATE_WRITE;
243 break;
244 case INTEL_CMD_STATUS_CLEAR:
245 cfi->status = INTEL_SR_DWS;
246 break;
247 case INTEL_CMD_LOCK_SETUP:
248 cfi->state = CFI_STATE_PROTECT;
249 break;
250 default:
251 return false;
252 }
253 break;
254
255 case CFI_STATE_ERASE:
256 if (value == INTEL_CMD_ERASE_CONFIRM)
257 {
258 cfi_erase_block (me, cfi, offset);
259 cfi->status &= ~(INTEL_SR_PS | INTEL_SR_ES);
260 }
261 else
262 cfi->status |= INTEL_SR_PS | INTEL_SR_ES;
263 cfi->state = CFI_STATE_STATUS;
264 break;
265
266 case CFI_STATE_PROTECT:
267 switch (value)
268 {
269 case INTEL_CMD_LOCK_BLOCK:
270 case INTEL_CMD_UNLOCK_BLOCK:
271 case INTEL_CMD_LOCK_DOWN_BLOCK:
272 /* XXX: Handle the command. */
273 break;
274 default:
275 /* Kick out. */
276 cfi->status |= INTEL_SR_PS | INTEL_SR_ES;
277 break;
278 }
279 cfi->state = CFI_STATE_STATUS;
280 break;
281
282 default:
283 return false;
284 }
285
286 return true;
287 }
288
289 static bool
290 cmdset_intel_read (struct hw *me, struct cfi *cfi, void *dest,
291 unsigned offset, unsigned shifted_offset, unsigned nr_bytes)
292 {
293 unsigned char *sdest = dest;
294
295 switch (cfi->state)
296 {
297 case CFI_STATE_STATUS:
298 case CFI_STATE_ERASE:
299 *sdest = cfi->status;
300 break;
301
302 case CFI_STATE_READ_ID:
303 switch (shifted_offset & 0x1ff)
304 {
305 case 0x00: /* Manufacturer Code. */
306 cfi_encode_16bit (dest, INTEL_ID_MANU);
307 break;
308 case 0x01: /* Device ID Code. */
309 /* XXX: Push to device tree ? */
310 cfi_encode_16bit (dest, 0xad);
311 break;
312 case 0x02: /* Block lock state. */
313 /* XXX: This is per-block ... */
314 *sdest = 0x00;
315 break;
316 case 0x05: /* Read Configuration Register. */
317 cfi_encode_16bit (dest, (1 << 15));
318 break;
319 default:
320 return false;
321 }
322 break;
323
324 default:
325 return false;
326 }
327
328 return true;
329 }
330
331 static void
332 cmdset_intel_setup (struct hw *me, struct cfi *cfi)
333 {
334 cfi->status = INTEL_SR_DWS;
335 }
336
337 static const struct cfi_cmdset cfi_cmdset_intel =
338 {
339 CFI_CMDSET_INTEL, cmdset_intel_setup, cmdset_intel_write, cmdset_intel_read,
340 };
341 \f
342 /* All of the supported command sets get listed here. We then walk this
343 array to see if the user requested command set is implemented. */
344 static const struct cfi_cmdset * const cfi_cmdsets[] =
345 {
346 &cfi_cmdset_intel,
347 };
348 \f
349 /* All writes to the flash address space come here. Using the state
350 machine, we figure out what to do with this specific write. All
351 common code sits here and if there is a request we can't process,
352 we hand it off to the command set-specific write function. */
353 static unsigned
354 cfi_io_write_buffer (struct hw *me, const void *source, int space,
355 address_word addr, unsigned nr_bytes)
356 {
357 struct cfi *cfi = hw_data (me);
358 const unsigned char *ssource = source;
359 enum cfi_state old_state;
360 unsigned offset, shifted_offset, value;
361
362 offset = addr & (cfi->dev_size - 1);
363 shifted_offset = cfi_unshift_addr (cfi, offset);
364
365 if (cfi->width != nr_bytes)
366 {
367 HW_TRACE ((me, "write 0x%08lx length %u does not match flash width %u",
368 (unsigned long) addr, nr_bytes, cfi->width));
369 return nr_bytes;
370 }
371
372 if (cfi->state == CFI_STATE_WRITE)
373 {
374 /* NOR flash can only go from 1 to 0. */
375 unsigned i;
376
377 HW_TRACE ((me, "program %#x length %u", offset, nr_bytes));
378
379 for (i = 0; i < nr_bytes; ++i)
380 cfi->data[offset + i] &= ssource[i];
381
382 cfi->state = CFI_STATE_STATUS;
383
384 return nr_bytes;
385 }
386
387 value = ssource[0];
388
389 old_state = cfi->state;
390
391 if (value == CFI_CMD_READ || value == CFI_CMD_RESET)
392 {
393 cfi->state = CFI_STATE_READ;
394 goto done;
395 }
396
397 switch (cfi->state)
398 {
399 case CFI_STATE_READ:
400 case CFI_STATE_READ_ID:
401 if (value == CFI_CMD_CFI_QUERY)
402 {
403 if (shifted_offset == CFI_ADDR_CFI_QUERY_START)
404 cfi->state = CFI_STATE_CFI_QUERY;
405 goto done;
406 }
407
408 if (value == CFI_CMD_READ_ID)
409 {
410 cfi->state = CFI_STATE_READ_ID;
411 goto done;
412 }
413
414 /* Fall through. */
415
416 default:
417 if (!cfi->cmdset->write (me, cfi, source, offset, value, nr_bytes))
418 HW_TRACE ((me, "unhandled command %#x at %#x", value, offset));
419 break;
420 }
421
422 done:
423 HW_TRACE ((me, "write 0x%08lx command {%#x,%#x,%#x,%#x}; state %s -> %s",
424 (unsigned long) addr, ssource[0],
425 nr_bytes > 1 ? ssource[1] : 0,
426 nr_bytes > 2 ? ssource[2] : 0,
427 nr_bytes > 3 ? ssource[3] : 0,
428 state_names[old_state], state_names[cfi->state]));
429
430 return nr_bytes;
431 }
432
433 /* All reads to the flash address space come here. Using the state
434 machine, we figure out what to return -- actual data stored in the
435 flash, the CFI query structure, some status info, or something else ?
436 Any requests that we can't handle are passed to the command set-
437 specific read function. */
438 static unsigned
439 cfi_io_read_buffer (struct hw *me, void *dest, int space,
440 address_word addr, unsigned nr_bytes)
441 {
442 struct cfi *cfi = hw_data (me);
443 unsigned char *sdest = dest;
444 unsigned offset, shifted_offset;
445
446 offset = addr & (cfi->dev_size - 1);
447 shifted_offset = cfi_unshift_addr (cfi, offset);
448
449 /* XXX: Is this OK to enforce ? */
450 #if 0
451 if (cfi->state != CFI_STATE_READ && cfi->width != nr_bytes)
452 {
453 HW_TRACE ((me, "read 0x%08lx length %u does not match flash width %u",
454 (unsigned long) addr, nr_bytes, cfi->width));
455 return nr_bytes;
456 }
457 #endif
458
459 HW_TRACE ((me, "%s read 0x%08lx length %u",
460 state_names[cfi->state], (unsigned long) addr, nr_bytes));
461
462 switch (cfi->state)
463 {
464 case CFI_STATE_READ:
465 memcpy (dest, cfi->data + offset, nr_bytes);
466 break;
467
468 case CFI_STATE_CFI_QUERY:
469 if (shifted_offset >= CFI_ADDR_CFI_QUERY_RESULT &&
470 shifted_offset < CFI_ADDR_CFI_QUERY_RESULT + sizeof (cfi->query) +
471 (cfi->query.num_erase_regions * 4))
472 {
473 unsigned char *qry;
474
475 shifted_offset -= CFI_ADDR_CFI_QUERY_RESULT;
476 if (shifted_offset >= sizeof (cfi->query))
477 {
478 qry = cfi->erase_region_info;
479 shifted_offset -= sizeof (cfi->query);
480 }
481 else
482 qry = (void *) &cfi->query;
483
484 sdest[0] = qry[shifted_offset];
485 memset (sdest + 1, 0, nr_bytes - 1);
486
487 break;
488 }
489
490 default:
491 if (!cfi->cmdset->read (me, cfi, dest, offset, shifted_offset, nr_bytes))
492 HW_TRACE ((me, "unhandled state %s", state_names[cfi->state]));
493 break;
494 }
495
496 return nr_bytes;
497 }
498
499 /* Clean up any state when this device is removed (e.g. when shutting
500 down, or when reloading via gdb). */
501 static void
502 cfi_delete_callback (struct hw *me)
503 {
504 #ifdef HAVE_MMAP
505 struct cfi *cfi = hw_data (me);
506
507 if (cfi->mmap)
508 munmap (cfi->mmap, cfi->dev_size);
509 #endif
510 }
511
512 /* Helper function to easily add CFI erase regions to the existing set. */
513 static void
514 cfi_add_erase_region (struct hw *me, struct cfi *cfi,
515 unsigned blocks, unsigned size)
516 {
517 unsigned num_regions = cfi->query.num_erase_regions;
518 struct cfi_erase_region *region;
519 unsigned char *qry_region;
520
521 /* Store for our own usage. */
522 region = &cfi->erase_regions[num_regions];
523 region->blocks = blocks;
524 region->size = size;
525 if (num_regions == 0)
526 region->start = 0;
527 else
528 region->start = region[-1].end;
529 region->end = region->start + (blocks * size);
530
531 /* Regions are 4 bytes long. */
532 qry_region = cfi->erase_region_info + 4 * num_regions;
533
534 /* [0][1] = number erase blocks - 1 */
535 if (blocks > 0xffff + 1)
536 hw_abort (me, "erase blocks %u too big to fit into region info", blocks);
537 cfi_encode_16bit (&qry_region[0], blocks - 1);
538
539 /* [2][3] = block size / 256 bytes */
540 if (size > 0xffff * 256)
541 hw_abort (me, "erase size %u too big to fit into region info", size);
542 cfi_encode_16bit (&qry_region[2], size / 256);
543
544 /* Yet another region. */
545 cfi->query.num_erase_regions = num_regions + 1;
546 }
547
548 /* Device tree options:
549 Required:
550 .../reg <addr> <len>
551 .../cmdset <primary; integer> [alt; integer]
552 Optional:
553 .../size <device size (must be pow of 2)>
554 .../width <8|16|32>
555 .../write_size <integer (must be pow of 2)>
556 .../erase_regions <number blocks> <block size> \
557 [<number blocks> <block size> ...]
558 .../voltage <vcc min> <vcc max> <vpp min> <vpp max>
559 .../timeouts <typ unit write> <typ buf write> \
560 <typ block erase> <typ chip erase> \
561 <max unit write> <max buf write> \
562 <max block erase> <max chip erase>
563 .../file <file> [ro|rw]
564 Defaults:
565 size: <len> from "reg"
566 width: 8
567 write_size: 0 (not supported)
568 erase_region: 1 (can only erase whole chip)
569 voltage: 0.0V (for all)
570 timeouts: typ: 1µs, not supported, 1ms, not supported
571 max: 1µs, 1ms, 1ms, not supported
572
573 TODO: Verify user args are valid (e.g. voltage is 8 bits). */
574 static void
575 attach_cfi_regs (struct hw *me, struct cfi *cfi)
576 {
577 address_word attach_address;
578 int attach_space;
579 unsigned attach_size;
580 reg_property_spec reg;
581 bool fd_writable;
582 int i, ret, fd;
583 signed_cell ival;
584
585 if (hw_find_property (me, "reg") == NULL)
586 hw_abort (me, "Missing \"reg\" property");
587 if (hw_find_property (me, "cmdset") == NULL)
588 hw_abort (me, "Missing \"cmdset\" property");
589
590 if (!hw_find_reg_array_property (me, "reg", 0, &reg))
591 hw_abort (me, "\"reg\" property must contain three addr/size entries");
592
593 hw_unit_address_to_attach_address (hw_parent (me),
594 &reg.address,
595 &attach_space, &attach_address, me);
596 hw_unit_size_to_attach_size (hw_parent (me), &reg.size, &attach_size, me);
597
598 hw_attach_address (hw_parent (me),
599 0, attach_space, attach_address, attach_size, me);
600
601 /* Extract the desired flash command set. */
602 ret = hw_find_integer_array_property (me, "cmdset", 0, &ival);
603 if (ret != 1 && ret != 2)
604 hw_abort (me, "\"cmdset\" property takes 1 or 2 entries");
605 cfi_encode_16bit (cfi->query.p_id, ival);
606
607 for (i = 0; i < ARRAY_SIZE (cfi_cmdsets); ++i)
608 if (cfi_cmdsets[i]->id == ival)
609 cfi->cmdset = cfi_cmdsets[i];
610 if (cfi->cmdset == NULL)
611 hw_abort (me, "cmdset %u not supported", ival);
612
613 if (ret == 2)
614 {
615 hw_find_integer_array_property (me, "cmdset", 1, &ival);
616 cfi_encode_16bit (cfi->query.a_id, ival);
617 }
618
619 /* Extract the desired device size. */
620 if (hw_find_property (me, "size"))
621 cfi->dev_size = hw_find_integer_property (me, "size");
622 else
623 cfi->dev_size = attach_size;
624 cfi->query.dev_size = log2 (cfi->dev_size);
625
626 /* Extract the desired flash width. */
627 if (hw_find_property (me, "width"))
628 {
629 cfi->width = hw_find_integer_property (me, "width");
630 if (cfi->width != 8 && cfi->width != 16 && cfi->width != 32)
631 hw_abort (me, "\"width\" must be 8 or 16 or 32, not %u", cfi->width);
632 }
633 else
634 /* Default to 8 bit. */
635 cfi->width = 8;
636 /* Turn 8/16/32 into 1/2/4. */
637 cfi->width /= 8;
638
639 /* Extract optional write buffer size. */
640 if (hw_find_property (me, "write_size"))
641 {
642 ival = hw_find_integer_property (me, "write_size");
643 cfi_encode_16bit (cfi->query.max_buf_write_len, log2 (ival));
644 }
645
646 /* Extract optional erase regions. */
647 if (hw_find_property (me, "erase_regions"))
648 {
649 ret = hw_find_integer_array_property (me, "erase_regions", 0, &ival);
650 if (ret % 2)
651 hw_abort (me, "\"erase_regions\" must be specified in sets of 2");
652
653 cfi->erase_region_info = HW_NALLOC (me, unsigned char, ret / 2);
654 cfi->erase_regions = HW_NALLOC (me, struct cfi_erase_region, ret / 2);
655
656 for (i = 0; i < ret; i += 2)
657 {
658 unsigned blocks, size;
659
660 hw_find_integer_array_property (me, "erase_regions", i, &ival);
661 blocks = ival;
662
663 hw_find_integer_array_property (me, "erase_regions", i + 1, &ival);
664 size = ival;
665
666 cfi_add_erase_region (me, cfi, blocks, size);
667 }
668 }
669
670 /* Extract optional voltages. */
671 if (hw_find_property (me, "voltage"))
672 {
673 unsigned num = ARRAY_SIZE (cfi->query.voltages);
674
675 ret = hw_find_integer_array_property (me, "voltage", 0, &ival);
676 if (ret > num)
677 hw_abort (me, "\"voltage\" may have only %u arguments", num);
678
679 for (i = 0; i < ret; ++i)
680 {
681 hw_find_integer_array_property (me, "voltage", i, &ival);
682 cfi->query.voltages[i] = ival;
683 }
684 }
685
686 /* Extract optional timeouts. */
687 if (hw_find_property (me, "timeout"))
688 {
689 unsigned num = ARRAY_SIZE (cfi->query.timeouts);
690
691 ret = hw_find_integer_array_property (me, "timeout", 0, &ival);
692 if (ret > num)
693 hw_abort (me, "\"timeout\" may have only %u arguments", num);
694
695 for (i = 0; i < ret; ++i)
696 {
697 hw_find_integer_array_property (me, "timeout", i, &ival);
698 cfi->query.timeouts[i] = ival;
699 }
700 }
701
702 /* Extract optional file. */
703 fd = -1;
704 fd_writable = false;
705 if (hw_find_property (me, "file"))
706 {
707 const char *file;
708
709 ret = hw_find_string_array_property (me, "file", 0, &file);
710 if (ret > 2)
711 hw_abort (me, "\"file\" may take only one argument");
712 if (ret == 2)
713 {
714 const char *writable;
715
716 hw_find_string_array_property (me, "file", 1, &writable);
717 fd_writable = !strcmp (writable, "rw");
718 }
719
720 fd = open (file, fd_writable ? O_RDWR : O_RDONLY);
721 if (fd < 0)
722 hw_abort (me, "unable to read file `%s': %s", file, strerror (errno));
723 }
724
725 /* Figure out where our initial flash data is coming from. */
726 if (fd != -1 && fd_writable)
727 {
728 #ifdef HAVE_MMAP
729 posix_fallocate (fd, 0, cfi->dev_size);
730
731 cfi->mmap = mmap (NULL, cfi->dev_size,
732 PROT_READ | (fd_writable ? PROT_WRITE : 0),
733 MAP_SHARED, fd, 0);
734
735 if (cfi->mmap == MAP_FAILED)
736 cfi->mmap = NULL;
737 else
738 cfi->data = cfi->mmap;
739 #else
740 sim_io_eprintf (hw_system (me),
741 "cfi: sorry, file write support requires mmap()\n");
742 #endif
743 }
744 if (!cfi->data)
745 {
746 size_t read_len;
747
748 cfi->data = HW_NALLOC (me, unsigned char, cfi->dev_size);
749
750 if (fd != -1)
751 {
752 /* Use stdio to avoid EINTR issues with read(). */
753 FILE *fp = fdopen (fd, "r");
754
755 if (fp)
756 read_len = fread (cfi->data, 1, cfi->dev_size, fp);
757 else
758 read_len = 0;
759
760 /* Don't need to fclose() with fdopen("r"). */
761 }
762 else
763 read_len = 0;
764
765 memset (cfi->data, 0xff, cfi->dev_size - read_len);
766 }
767
768 close (fd);
769 }
770
771 /* Once we've been declared in the device tree, this is the main
772 entry point. So allocate state, attach memory addresses, and
773 all that fun stuff. */
774 static void
775 cfi_finish (struct hw *me)
776 {
777 struct cfi *cfi;
778
779 cfi = HW_ZALLOC (me, struct cfi);
780
781 set_hw_data (me, cfi);
782 set_hw_io_read_buffer (me, cfi_io_read_buffer);
783 set_hw_io_write_buffer (me, cfi_io_write_buffer);
784 set_hw_delete (me, cfi_delete_callback);
785
786 attach_cfi_regs (me, cfi);
787
788 /* Initialize the CFI. */
789 cfi->state = CFI_STATE_READ;
790 memcpy (cfi->query.qry, "QRY", 3);
791 cfi->cmdset->setup (me, cfi);
792 }
793
794 /* Every device is required to declare this. */
795 const struct hw_descriptor dv_cfi_descriptor[] =
796 {
797 {"cfi", cfi_finish,},
798 {NULL, NULL},
799 };
This page took 0.05687 seconds and 4 git commands to generate.