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-2013 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 
177 /* Erase the block specified by the offset into the given CFI flash.  */
178 static void
cfi_erase_block(struct hw * me,struct cfi * cfi,unsigned offset)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
cfi_unshift_addr(struct cfi * cfi,unsigned addr)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
cfi_encode_16bit(unsigned char * data,unsigned num)221 cfi_encode_16bit (unsigned char *data, unsigned num)
222 {
223   data[0] = num;
224   data[1] = num >> 8;
225 }
226 
227 /* The functions required to implement the Intel command set.  */
228 
229 static bool
cmdset_intel_write(struct hw * me,struct cfi * cfi,const void * source,unsigned offset,unsigned value,unsigned nr_bytes)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
cmdset_intel_read(struct hw * me,struct cfi * cfi,void * dest,unsigned offset,unsigned shifted_offset,unsigned nr_bytes)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
cmdset_intel_setup(struct hw * me,struct cfi * cfi)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 
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 
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
cfi_io_write_buffer(struct hw * me,const void * source,int space,address_word addr,unsigned nr_bytes)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
cfi_io_read_buffer(struct hw * me,void * dest,int space,address_word addr,unsigned nr_bytes)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
cfi_delete_callback(struct hw * me)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
cfi_add_erase_region(struct hw * me,struct cfi * cfi,unsigned blocks,unsigned size)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
attach_cfi_regs(struct hw * me,struct cfi * cfi)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
cfi_finish(struct hw * me)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 };
802