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