OSDN Git Service

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