[PATCH 22/57][Arm][GAS] Add support for MVE instructions: vmlaldav, vmlalv, vmlsldav...
[binutils-gdb.git] / sim / common / dv-cfi.c
blob67011846e80fdae462bf97c26d1dae9c49e6c2a3
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
5 Copyright (C) 2010-2019 Free Software Foundation, Inc.
6 Contributed by Analog Devices, Inc.
8 This file is part of simulators.
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.
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.
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/>. */
23 /* TODO: support vendor query tables. */
25 #include "config.h"
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
36 #include "sim-main.h"
37 #include "hw-base.h"
38 #include "hw-main.h"
39 #include "dv-cfi.h"
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
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,
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.
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
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
76 /* Voltage levels. */
77 unsigned char voltages[4];
78 struct
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;
90 union
92 /* Operational timeouts. */
93 unsigned char timeouts[8];
94 struct
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;
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;*/
127 /* Flashes may have regions with different erase sizes. There is one
128 structure per erase region. */
129 struct cfi_erase_region
131 unsigned blocks;
132 unsigned size;
133 unsigned start;
134 unsigned end;
137 struct cfi;
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
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);
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
159 unsigned width, dev_size, status;
160 enum cfi_state state;
161 unsigned char *data, *mmap;
163 struct cfi_query query;
164 const struct cfi_cmdset *cmdset;
166 unsigned char *erase_region_info;
167 struct cfi_erase_region *erase_regions;
170 /* Helpful strings which are used with HW_TRACE. */
171 static const char * const state_names[] =
173 "READ", "READ_ID", "CFI_QUERY", "PROTECT", "STATUS", "ERASE", "WRITE",
174 "WRITE_BUFFER", "WRITE_BUFFER_CONFIRM",
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)
181 unsigned i;
182 struct cfi_erase_region *region;
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);
189 for (i = 0; i < cfi->query.num_erase_regions; ++i)
191 region = &cfi->erase_regions[i];
193 if (offset >= region->end)
194 continue;
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;
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)
210 switch (cfi->width)
212 case 4: addr >>= 1; /* fallthrough. */
213 case 2: addr >>= 1;
215 return addr;
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)
223 data[0] = num;
224 data[1] = num >> 8;
227 /* The functions required to implement the Intel command set. */
229 static bool
230 cmdset_intel_write (struct hw *me, struct cfi *cfi, const void *source,
231 unsigned offset, unsigned value, unsigned nr_bytes)
233 switch (cfi->state)
235 case CFI_STATE_READ:
236 case CFI_STATE_READ_ID:
237 switch (value)
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;
255 break;
257 case CFI_STATE_ERASE:
258 if (value == INTEL_CMD_ERASE_CONFIRM)
260 cfi_erase_block (me, cfi, offset);
261 cfi->status &= ~(INTEL_SR_PS | INTEL_SR_ES);
263 else
264 cfi->status |= INTEL_SR_PS | INTEL_SR_ES;
265 cfi->state = CFI_STATE_STATUS;
266 break;
268 case CFI_STATE_PROTECT:
269 switch (value)
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;
281 cfi->state = CFI_STATE_STATUS;
282 break;
284 default:
285 return false;
288 return true;
291 static bool
292 cmdset_intel_read (struct hw *me, struct cfi *cfi, void *dest,
293 unsigned offset, unsigned shifted_offset, unsigned nr_bytes)
295 unsigned char *sdest = dest;
297 switch (cfi->state)
299 case CFI_STATE_STATUS:
300 case CFI_STATE_ERASE:
301 *sdest = cfi->status;
302 break;
304 case CFI_STATE_READ_ID:
305 switch (shifted_offset & 0x1ff)
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;
324 break;
326 default:
327 return false;
330 return true;
333 static void
334 cmdset_intel_setup (struct hw *me, struct cfi *cfi)
336 cfi->status = INTEL_SR_DWS;
339 static const struct cfi_cmdset cfi_cmdset_intel =
341 CFI_CMDSET_INTEL, cmdset_intel_setup, cmdset_intel_write, cmdset_intel_read,
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[] =
348 &cfi_cmdset_intel,
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)
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;
364 offset = addr & (cfi->dev_size - 1);
365 shifted_offset = cfi_unshift_addr (cfi, offset);
367 if (cfi->width != nr_bytes)
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;
374 if (cfi->state == CFI_STATE_WRITE)
376 /* NOR flash can only go from 1 to 0. */
377 unsigned i;
379 HW_TRACE ((me, "program %#x length %u", offset, nr_bytes));
381 for (i = 0; i < nr_bytes; ++i)
382 cfi->data[offset + i] &= ssource[i];
384 cfi->state = CFI_STATE_STATUS;
386 return nr_bytes;
389 value = ssource[0];
391 old_state = cfi->state;
393 if (value == CFI_CMD_READ || value == CFI_CMD_RESET)
395 cfi->state = CFI_STATE_READ;
396 goto done;
399 switch (cfi->state)
401 case CFI_STATE_READ:
402 case CFI_STATE_READ_ID:
403 if (value == CFI_CMD_CFI_QUERY)
405 if (shifted_offset == CFI_ADDR_CFI_QUERY_START)
406 cfi->state = CFI_STATE_CFI_QUERY;
407 goto done;
410 if (value == CFI_CMD_READ_ID)
412 cfi->state = CFI_STATE_READ_ID;
413 goto done;
416 /* Fall through. */
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;
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]));
432 return nr_bytes;
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)
444 struct cfi *cfi = hw_data (me);
445 unsigned char *sdest = dest;
446 unsigned offset, shifted_offset;
448 offset = addr & (cfi->dev_size - 1);
449 shifted_offset = cfi_unshift_addr (cfi, offset);
451 /* XXX: Is this OK to enforce ? */
452 #if 0
453 if (cfi->state != CFI_STATE_READ && cfi->width != nr_bytes)
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;
459 #endif
461 HW_TRACE ((me, "%s read 0x%08lx length %u",
462 state_names[cfi->state], (unsigned long) addr, nr_bytes));
464 switch (cfi->state)
466 case CFI_STATE_READ:
467 memcpy (dest, cfi->data + offset, nr_bytes);
468 break;
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))
475 unsigned char *qry;
477 shifted_offset -= CFI_ADDR_CFI_QUERY_RESULT;
478 if (shifted_offset >= sizeof (cfi->query))
480 qry = cfi->erase_region_info;
481 shifted_offset -= sizeof (cfi->query);
483 else
484 qry = (void *) &cfi->query;
486 sdest[0] = qry[shifted_offset];
487 memset (sdest + 1, 0, nr_bytes - 1);
489 break;
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;
498 return nr_bytes;
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)
506 #ifdef HAVE_MMAP
507 struct cfi *cfi = hw_data (me);
509 if (cfi->mmap)
510 munmap (cfi->mmap, cfi->dev_size);
511 #endif
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)
519 unsigned num_regions = cfi->query.num_erase_regions;
520 struct cfi_erase_region *region;
521 unsigned char *qry_region;
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);
533 /* Regions are 4 bytes long. */
534 qry_region = cfi->erase_region_info + 4 * num_regions;
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);
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);
546 /* Yet another region. */
547 cfi->query.num_erase_regions = num_regions + 1;
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
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)
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;
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");
592 if (!hw_find_reg_array_property (me, "reg", 0, &reg))
593 hw_abort (me, "\"reg\" property must contain three addr/size entries");
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);
600 hw_attach_address (hw_parent (me),
601 0, attach_space, attach_address, attach_size, me);
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);
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);
615 if (ret == 2)
617 hw_find_integer_array_property (me, "cmdset", 1, &ival);
618 cfi_encode_16bit (cfi->query.a_id, ival);
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);
628 /* Extract the desired flash width. */
629 if (hw_find_property (me, "width"))
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);
635 else
636 /* Default to 8 bit. */
637 cfi->width = 8;
638 /* Turn 8/16/32 into 1/2/4. */
639 cfi->width /= 8;
641 /* Extract optional write buffer size. */
642 if (hw_find_property (me, "write_size"))
644 ival = hw_find_integer_property (me, "write_size");
645 cfi_encode_16bit (cfi->query.max_buf_write_len, log2 (ival));
648 /* Extract optional erase regions. */
649 if (hw_find_property (me, "erase_regions"))
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");
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);
658 for (i = 0; i < ret; i += 2)
660 unsigned blocks, size;
662 hw_find_integer_array_property (me, "erase_regions", i, &ival);
663 blocks = ival;
665 hw_find_integer_array_property (me, "erase_regions", i + 1, &ival);
666 size = ival;
668 cfi_add_erase_region (me, cfi, blocks, size);
672 /* Extract optional voltages. */
673 if (hw_find_property (me, "voltage"))
675 unsigned num = ARRAY_SIZE (cfi->query.voltages);
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);
681 for (i = 0; i < ret; ++i)
683 hw_find_integer_array_property (me, "voltage", i, &ival);
684 cfi->query.voltages[i] = ival;
688 /* Extract optional timeouts. */
689 if (hw_find_property (me, "timeout"))
691 unsigned num = ARRAY_SIZE (cfi->query.timeouts);
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);
697 for (i = 0; i < ret; ++i)
699 hw_find_integer_array_property (me, "timeout", i, &ival);
700 cfi->query.timeouts[i] = ival;
704 /* Extract optional file. */
705 fd = -1;
706 fd_writable = false;
707 if (hw_find_property (me, "file"))
709 const char *file;
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)
716 const char *writable;
718 hw_find_string_array_property (me, "file", 1, &writable);
719 fd_writable = !strcmp (writable, "rw");
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));
727 /* Figure out where our initial flash data is coming from. */
728 if (fd != -1 && fd_writable)
730 #if defined (HAVE_MMAP) && defined (HAVE_POSIX_FALLOCATE)
731 posix_fallocate (fd, 0, cfi->dev_size);
733 cfi->mmap = mmap (NULL, cfi->dev_size,
734 PROT_READ | (fd_writable ? PROT_WRITE : 0),
735 MAP_SHARED, fd, 0);
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
746 if (!cfi->data)
748 size_t read_len;
750 cfi->data = HW_NALLOC (me, unsigned char, cfi->dev_size);
752 if (fd != -1)
754 /* Use stdio to avoid EINTR issues with read(). */
755 FILE *fp = fdopen (fd, "r");
757 if (fp)
758 read_len = fread (cfi->data, 1, cfi->dev_size, fp);
759 else
760 read_len = 0;
762 /* Don't need to fclose() with fdopen("r"). */
764 else
765 read_len = 0;
767 memset (cfi->data, 0xff, cfi->dev_size - read_len);
770 close (fd);
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)
779 struct cfi *cfi;
781 cfi = HW_ZALLOC (me, struct cfi);
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);
788 attach_cfi_regs (me, cfi);
790 /* Initialize the CFI. */
791 cfi->state = CFI_STATE_READ;
792 memcpy (cfi->query.qry, "QRY", 3);
793 cfi->cmdset->setup (me, cfi);
796 /* Every device is required to declare this. */
797 const struct hw_descriptor dv_cfi_descriptor[] =
799 {"cfi", cfi_finish,},
800 {NULL, NULL},