sim: constify prog_name
[external/binutils.git] / sim / ppc / hw_eeprom.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 3 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, see <http://www.gnu.org/licenses/>.
17  
18     */
19
20
21 #ifndef _HW_EEPROM_C_
22 #define _HW_EEPROM_C_
23
24 #include "device_table.h"
25
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #else
29 #ifdef HAVE_STRINGS_H
30 #include <strings.h>
31 #endif
32 #endif
33
34
35 /* DEVICE
36
37
38    eeprom - JEDEC? compatible electricaly erasable programable device
39
40
41    DESCRIPTION
42
43
44    This device implements a small byte addressable EEPROM.
45    Programming is performed using the same write sequences as used by
46    standard modern EEPROM components.  Writes occure in real time, the
47    device returning a progress value until the programing has been
48    completed.
49
50    It is based on the AMD 29F040 component.
51
52
53    PROPERTIES
54
55
56    reg = <address> <size> (required)
57
58    Determine where the device lives in the parents address space.
59
60
61    nr-sectors = <integer> (required)
62
63    When erasing an entire sector is cleared at a time.  This specifies
64    the number of sectors in the EEPROM component.
65
66
67    sector-size = <integer> (required)
68
69    The number of bytes in a sector.  When erasing, memory chunks of
70    this size are cleared.
71
72    NOTE: The product nr-sectors * sector-size does not need to map the
73    size specified in the reg property.  If the specified size is
74    smaller part of the eeprom will not be accessible while if it is
75    larger the addresses will wrap.
76
77
78    byte-write-delay = <integer> (required)
79
80    Number of clock ticks before the programming of a single byte
81    completes.
82
83
84    sector-start-delay = <integer> (required)
85
86    When erasing sectors, the number of clock ticks after the sector
87    has been specified that the actual erase process commences.
88
89
90    erase-delay = <intger> (required)
91
92    Number of clock ticks before an erase program completes
93
94
95    manufacture-code = <integer> (required)
96
97    The one byte value returned when the auto-select manufacturer code
98    is read.
99
100
101    device-code = <integer> (required)
102
103    The one byte value returned when the auto-select device code is
104    read.
105
106
107    input-file = <file-name> (optional)
108
109    Initialize the eeprom using the specified binary file.
110
111
112    output-file = <file-name> (optional)
113
114    When ever the eeprom is updated, save the modified image into the
115    specified file.
116
117
118    EXAMPLES
119
120
121    Enable tracing of the eeprom:
122
123    |  bash$ psim -t eeprom-device \
124
125
126    Configure something very like the Amd Am29F040 - 512byte EEPROM
127    (but a bit faster):
128
129    |  -o '/eeprom@0xfff00000/reg 0xfff00000 0x80000' \
130    |  -o '/eeprom@0xfff00000/nr-sectors 8' \
131    |  -o '/eeprom@0xfff00000/sector-size 0x10000' \
132    |  -o '/eeprom@0xfff00000/byte-write-delay 1000' \
133    |  -o '/eeprom@0xfff00000/sector-start-delay 100' \
134    |  -o '/eeprom@0xfff00000/erase-delay 1000' \
135    |  -o '/eeprom@0xfff00000/manufacture-code 0x01' \
136    |  -o '/eeprom@0xfff00000/device-code 0xa4' \
137
138
139    Initialize the eeprom from the file <</dev/zero>>:
140
141    |  -o '/eeprom@0xfff00000/input-file /dev/zero'
142
143
144    BUGS
145
146
147    */
148
149 typedef enum {
150   read_reset,
151   write_nr_2,
152   write_nr_3,
153   write_nr_4,
154   write_nr_5,
155   write_nr_6,
156   byte_program,
157   byte_programming,
158   chip_erase,
159   sector_erase,
160   sector_erase_suspend,
161   autoselect,
162 } hw_eeprom_states;
163
164 static const char *
165 state2a(hw_eeprom_states state)
166 {
167   switch (state) {
168   case read_reset: return "read_reset";
169   case write_nr_2: return "write_nr_2";
170   case write_nr_3: return "write_nr_3";
171   case write_nr_4: return "write_nr_4";
172   case write_nr_5: return "write_nr_5";
173   case write_nr_6: return "write_nr_6";
174   case byte_program: return "byte_program";
175   case byte_programming: return "byte_programming";
176   case chip_erase: return "chip_erase";
177   case sector_erase: return "sector_erase";
178   case sector_erase_suspend: return "sector_erase_suspend";
179   case autoselect: return "autoselect";
180   }
181   return NULL;
182 }
183
184 typedef struct _hw_eeprom_device {
185   /* general */
186   hw_eeprom_states state;
187   unsigned8 *memory;
188   unsigned sizeof_memory;
189   unsigned erase_delay;
190   signed64 program_start_time;
191   signed64 program_finish_time;
192   unsigned8 manufacture_code;
193   unsigned8 device_code;
194   unsigned8 toggle_bit;
195   /* initialization */
196   const char *input_file_name;
197   const char *output_file_name;
198   /* for sector and sector programming */
199   hw_eeprom_states sector_state;
200   unsigned8 *sectors;
201   unsigned nr_sectors;
202   unsigned sizeof_sector;
203   unsigned sector_start_delay;
204   unsigned sector_start_time;
205   /* byte and byte programming */
206   unsigned byte_write_delay;
207   unsigned_word byte_program_address;
208   unsigned8 byte_program_byte;
209 } hw_eeprom_device;
210
211 typedef struct _hw_eeprom_reg_spec {
212   unsigned32 base;
213   unsigned32 size;
214 } hw_eeprom_reg_spec;
215
216 static void
217 hw_eeprom_init_data(device *me)
218 {
219   hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
220
221   /* have we any input or output files */
222   if (device_find_property(me, "input-file") != NULL)
223     eeprom->input_file_name = device_find_string_property(me, "input-file");
224   if (device_find_property(me, "output-file") != NULL)
225     eeprom->input_file_name = device_find_string_property(me, "output-file");
226
227   /* figure out the sectors in the eeprom */
228   if (eeprom->sectors == NULL) {
229     eeprom->nr_sectors = device_find_integer_property(me, "nr-sectors");
230     eeprom->sizeof_sector = device_find_integer_property(me, "sector-size");
231     eeprom->sectors = zalloc(eeprom->nr_sectors);
232   }
233   else
234     memset(eeprom->sectors, 0, eeprom->nr_sectors);
235
236   /* initialize the eeprom */
237   if (eeprom->memory == NULL) {
238     eeprom->sizeof_memory = eeprom->sizeof_sector * eeprom->nr_sectors;
239     eeprom->memory = zalloc(eeprom->sizeof_memory);
240   }
241   else
242     memset(eeprom->memory, 0, eeprom->sizeof_memory);
243   if (eeprom->input_file_name != NULL) {
244     int i;
245     FILE *input_file = fopen(eeprom->input_file_name, "r");
246     if (input_file == NULL) {
247       perror("eeprom");
248       device_error(me, "Failed to open input file %s\n", eeprom->input_file_name);
249     }
250     for (i = 0; i < eeprom->sizeof_memory; i++) {
251       if (fread(&eeprom->memory[i], 1, 1, input_file) != 1)
252         break;
253     }
254     fclose(input_file);
255   }
256
257   /* timing */
258   eeprom->byte_write_delay = device_find_integer_property(me, "byte-write-delay");
259   eeprom->sector_start_delay = device_find_integer_property(me, "sector-start-delay");
260   eeprom->erase_delay = device_find_integer_property(me, "erase-delay");
261
262   /* misc */
263   eeprom->manufacture_code = device_find_integer_property(me, "manufacture-code");
264   eeprom->device_code = device_find_integer_property(me, "device-code");
265 }
266
267
268 static void
269 invalid_read(device *me,
270              hw_eeprom_states state,
271              unsigned_word address,
272              const char *reason)
273 {
274   DTRACE(eeprom, ("Invalid read to 0x%lx while in state %s (%s)\n",
275                   (unsigned long)address,
276                   state2a(state),
277                   reason));
278 }
279
280 static void
281 invalid_write(device *me,
282               hw_eeprom_states state,
283               unsigned_word address,
284               unsigned8 data,
285               const char *reason)
286 {
287   DTRACE(eeprom, ("Invalid write of 0x%lx to 0x%lx while in state %s (%s)\n",
288                   (unsigned long)data,
289                   (unsigned long)address,
290                   state2a(state),
291                   reason));
292 }
293
294 static void
295 dump_eeprom(device *me,
296             hw_eeprom_device *eeprom)
297 {
298   if (eeprom->output_file_name != NULL) {
299     int i;
300     FILE *output_file = fopen(eeprom->output_file_name, "w");
301     if (output_file == NULL) {
302       perror("eeprom");
303       device_error(me, "Failed to open output file %s\n",
304                    eeprom->output_file_name);
305     }
306     for (i = 0; i < eeprom->sizeof_memory; i++) {
307       if (fwrite(&eeprom->memory[i], 1, 1, output_file) != 1)
308         break;
309     }
310     fclose(output_file);
311   }
312 }
313
314
315 /* program a single byte of eeprom */
316
317 static void
318 start_programming_byte(device *me,
319                        hw_eeprom_device *eeprom,
320                        unsigned_word address,
321                        unsigned8 new_byte)
322 {
323   unsigned8 old_byte = eeprom->memory[address];
324   DTRACE(eeprom, ("start-programing-byte - address 0x%lx, new 0x%lx, old 0x%lx\n",
325                   (unsigned long)address,
326                   (unsigned long)new_byte,
327                   (unsigned long)old_byte));
328   eeprom->byte_program_address = address;
329   /* : old new : ~old : new&~old
330      :  0   0  :   1  :    0
331      :  0   1  :   1  :    1     -- can not set a bit
332      :  1   0  :   0  :    0
333      :  1   1  :   0  :    0 */
334   if (~old_byte & new_byte)
335     invalid_write(me, eeprom->state, address, new_byte, "setting cleared bit");
336   /* : old new : old&new
337      :  0   0  :    0
338      :  0   1  :    0
339      :  1   0  :    0
340      :  1   1  :    1 */
341   eeprom->byte_program_byte = new_byte & old_byte;
342   eeprom->memory[address] = ~new_byte & ~0x24; /* LE-bits 5:3 zero */
343   eeprom->program_start_time = device_event_queue_time(me);
344   eeprom->program_finish_time = (eeprom->program_start_time
345                                  + eeprom->byte_write_delay);
346 }
347
348 static void
349 finish_programming_byte(device *me,
350                         hw_eeprom_device *eeprom)
351 {
352   DTRACE(eeprom, ("finish-programming-byte - address 0x%lx, byte 0x%lx\n",
353                   (unsigned long)eeprom->byte_program_address,
354                   (unsigned long)eeprom->byte_program_byte));
355   eeprom->memory[eeprom->byte_program_address] = eeprom->byte_program_byte;
356   dump_eeprom(me, eeprom);
357 }
358
359
360 /* erase the eeprom completly */
361
362 static void
363 start_erasing_chip(device *me,
364                    hw_eeprom_device *eeprom)
365 {
366   DTRACE(eeprom, ("start-erasing-chip\n"));
367   memset(eeprom->memory, 0, eeprom->sizeof_memory);
368   eeprom->program_start_time = device_event_queue_time(me);
369   eeprom->program_finish_time = (eeprom->program_start_time
370                                  + eeprom->erase_delay);
371 }
372
373 static void
374 finish_erasing_chip(device *me,
375                     hw_eeprom_device *eeprom)
376 {
377   DTRACE(eeprom, ("finish-erasing-chip\n"));
378   memset(eeprom->memory, 0xff, eeprom->sizeof_memory);
379   dump_eeprom(me, eeprom);
380 }
381
382
383 /* erase a single sector of the eeprom */
384
385 static void
386 start_erasing_sector(device *me,
387                      hw_eeprom_device *eeprom,
388                      unsigned_word address)
389 {
390   int sector = address / eeprom->sizeof_sector;
391   DTRACE(eeprom, ("start-erasing-sector - address 0x%lx, sector %d\n",
392                   (unsigned long)address, sector));
393   ASSERT(sector < eeprom->nr_sectors);
394   eeprom->sectors[sector] = 1;
395   memset(eeprom->memory + sector * eeprom->sizeof_sector,
396          0x4, eeprom->sizeof_sector);
397   eeprom->program_start_time = device_event_queue_time(me);
398   eeprom->sector_start_time = (eeprom->program_start_time
399                                + eeprom->sector_start_delay);
400   eeprom->program_finish_time = (eeprom->sector_start_time
401                                  + eeprom->erase_delay);
402
403 }
404
405 static void
406 finish_erasing_sector(device *me,
407                       hw_eeprom_device *eeprom)
408 {
409   int sector;
410   DTRACE(eeprom, ("finish-erasing-sector\n"));
411   for (sector = 0; sector < eeprom->nr_sectors; sector++) {
412     if (eeprom->sectors[sector]) {
413       eeprom->sectors[sector] = 0;
414       memset(eeprom->memory + sector * eeprom->sizeof_sector,
415              0xff, eeprom->sizeof_sector);
416     }
417   }
418   dump_eeprom(me, eeprom);
419 }
420
421
422 /* eeprom reads */
423
424 static unsigned8
425 toggle(hw_eeprom_device *eeprom,
426        unsigned8 byte)
427 {
428   eeprom->toggle_bit = eeprom->toggle_bit ^ 0x40; /* le-bit 6 */
429   return eeprom->toggle_bit ^ byte;
430 }
431
432 static unsigned8
433 read_byte(device *me,
434           hw_eeprom_device *eeprom,
435           unsigned_word address)
436 {
437   /* may need multiple iterations of this */
438   while (1) {
439     switch (eeprom->state) {
440
441     case read_reset:
442       return eeprom->memory[address];
443
444     case autoselect:
445       if ((address & 0xff) == 0x00)
446         return eeprom->manufacture_code;
447       else if ((address & 0xff) == 0x01)
448         return eeprom->device_code;
449       else
450         return 0; /* not certain about this */
451
452     case byte_programming:
453       if (device_event_queue_time(me) > eeprom->program_finish_time) {
454         finish_programming_byte(me, eeprom);
455         eeprom->state = read_reset;
456         continue;
457       }
458       else if (address == eeprom->byte_program_address) {
459         return toggle(eeprom, eeprom->memory[address]);
460       }
461       else {
462         /* trash that memory location */
463         invalid_read(me, eeprom->state, address, "not byte program address");
464         eeprom->memory[address] = (eeprom->memory[address]
465                                    & eeprom->byte_program_byte);
466         return toggle(eeprom, eeprom->memory[eeprom->byte_program_address]);
467       }
468
469     case chip_erase:
470       if (device_event_queue_time(me) > eeprom->program_finish_time) {
471         finish_erasing_chip(me, eeprom);
472         eeprom->state = read_reset;
473         continue;
474       }
475       else {
476         return toggle(eeprom, eeprom->memory[address]);
477       }
478
479     case sector_erase:
480       if (device_event_queue_time(me) > eeprom->program_finish_time) {
481         finish_erasing_sector(me, eeprom);
482         eeprom->state = read_reset;
483         continue;
484       }
485       else if (!eeprom->sectors[address / eeprom->sizeof_sector]) {
486         /* read to wrong sector */
487         invalid_read(me, eeprom->state, address, "sector not being erased");
488         return toggle(eeprom, eeprom->memory[address]) & ~0x8;
489       }
490       else if (device_event_queue_time(me) > eeprom->sector_start_time) {
491         return toggle(eeprom, eeprom->memory[address]) | 0x8;
492       }
493       else {
494         return toggle(eeprom, eeprom->memory[address]) & ~0x8;
495       }
496
497     case sector_erase_suspend:
498       if (!eeprom->sectors[address / eeprom->sizeof_sector]) {
499         return eeprom->memory[address];
500       }
501       else {
502         invalid_read(me, eeprom->state, address, "sector being erased");
503         return eeprom->memory[address];
504       }
505
506     default:
507       invalid_read(me, eeprom->state, address, "invalid state");
508       return eeprom->memory[address];
509
510     }
511   }
512   return 0;
513 }
514                        
515 static unsigned
516 hw_eeprom_io_read_buffer(device *me,
517                          void *dest,
518                          int space,
519                          unsigned_word addr,
520                          unsigned nr_bytes,
521                          cpu *processor,
522                          unsigned_word cia)
523 {
524   hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
525   int i;
526   for (i = 0; i < nr_bytes; i++) {
527     unsigned_word address = (addr + i) % eeprom->sizeof_memory;
528     unsigned8 byte = read_byte(me, eeprom, address);
529     ((unsigned8*)dest)[i] = byte;
530   }
531   return nr_bytes;
532 }
533
534
535 /* eeprom writes */
536
537 static void
538 write_byte(device *me,
539            hw_eeprom_device *eeprom,
540            unsigned_word address,
541            unsigned8 data)
542 {
543   /* may need multiple transitions to process a write */
544   while (1) {
545     switch (eeprom->state) {
546
547     case read_reset:
548       if (address == 0x5555 && data == 0xaa)
549         eeprom->state = write_nr_2;
550       else if (data == 0xf0)
551         eeprom->state = read_reset;
552       else {
553         invalid_write(me, eeprom->state, address, data, "unexpected");
554         eeprom->state = read_reset;
555       }
556       return;
557
558     case write_nr_2:
559       if (address == 0x2aaa && data == 0x55)
560         eeprom->state = write_nr_3;
561       else {
562         invalid_write(me, eeprom->state, address, data, "unexpected");
563         eeprom->state = read_reset;
564       }
565       return;
566
567     case write_nr_3:
568       if (address == 0x5555 && data == 0xf0)
569         eeprom->state = read_reset;
570       else if (address == 0x5555 && data == 0x90)
571         eeprom->state = autoselect;
572       else if (address == 0x5555 && data == 0xa0) {
573         eeprom->state = byte_program;
574       }
575       else if (address == 0x5555 && data == 0x80)
576         eeprom->state = write_nr_4;
577       else {
578         invalid_write(me, eeprom->state, address, data, "unexpected");
579         eeprom->state = read_reset;
580       }
581       return;
582
583     case write_nr_4:
584       if (address == 0x5555 && data == 0xaa)
585         eeprom->state = write_nr_5;
586       else {
587         invalid_write(me, eeprom->state, address, data, "unexpected");
588         eeprom->state = read_reset;
589       }
590       return;
591
592     case write_nr_5:
593       if (address == 0x2aaa && data == 0x55)
594         eeprom->state = write_nr_6;
595       else {
596         invalid_write(me, eeprom->state, address, data, "unexpected");
597         eeprom->state = read_reset;
598       }
599       return;
600
601     case write_nr_6:
602       if (address == 0x5555 && data == 0x10) {
603         start_erasing_chip(me, eeprom);
604         eeprom->state = chip_erase;
605       }
606       else {
607         start_erasing_sector(me, eeprom, address);
608         eeprom->sector_state = read_reset;
609         eeprom->state = sector_erase;
610       }
611       return;
612
613     case autoselect:
614       if (data == 0xf0)
615         eeprom->state = read_reset;
616       else if (address == 0x5555 && data == 0xaa)
617         eeprom->state = write_nr_2;
618       else {
619         invalid_write(me, eeprom->state, address, data, "unsupported address");
620         eeprom->state = read_reset;
621       }
622       return;
623
624     case byte_program:
625       start_programming_byte(me, eeprom, address, data);
626       eeprom->state = byte_programming;
627       return;
628
629     case byte_programming:
630       if (device_event_queue_time(me) > eeprom->program_finish_time) {
631         finish_programming_byte(me, eeprom);
632         eeprom->state = read_reset;
633         continue;
634       }
635       /* ignore it */
636       return;
637
638     case chip_erase:
639       if (device_event_queue_time(me) > eeprom->program_finish_time) {
640         finish_erasing_chip(me, eeprom);
641         eeprom->state = read_reset;
642         continue;
643       }
644       /* ignore it */
645       return;
646
647     case sector_erase:
648       if (device_event_queue_time(me) > eeprom->program_finish_time) {
649         finish_erasing_sector(me, eeprom);
650         eeprom->state = eeprom->sector_state;
651         continue;
652       }
653       else if (device_event_queue_time(me) > eeprom->sector_start_time
654                && data == 0xb0) {
655         eeprom->sector_state = read_reset;
656         eeprom->state = sector_erase_suspend;
657       }
658       else {
659         if (eeprom->sector_state == read_reset
660             && address == 0x5555 && data == 0xaa)
661           eeprom->sector_state = write_nr_2;
662         else if (eeprom->sector_state == write_nr_2
663                  && address == 0x2aaa && data == 0x55)
664           eeprom->sector_state = write_nr_3;
665         else if (eeprom->sector_state == write_nr_3
666                  && address == 0x5555 && data == 0x80)
667           eeprom->sector_state = write_nr_4;
668         else if (eeprom->sector_state == write_nr_4
669                  && address == 0x5555 && data == 0xaa)
670           eeprom->sector_state = write_nr_5;
671         else if (eeprom->sector_state == write_nr_5
672                  && address == 0x2aaa && data == 0x55)
673           eeprom->sector_state = write_nr_6;
674         else if (eeprom->sector_state == write_nr_6
675                  && address != 0x5555 && data == 0x30) {
676           if (device_event_queue_time(me) > eeprom->sector_start_time) {
677             DTRACE(eeprom, ("sector erase command after window closed\n"));
678             eeprom->sector_state = read_reset;
679           }
680           else {
681             start_erasing_sector(me, eeprom, address);
682             eeprom->sector_state = read_reset;
683           }
684         }
685         else {
686           invalid_write(me, eeprom->state, address, data, state2a(eeprom->sector_state));
687           eeprom->state = read_reset;
688         }
689       }
690       return;
691
692     case sector_erase_suspend:
693       if (data == 0x30)
694         eeprom->state = sector_erase;
695       else {
696         invalid_write(me, eeprom->state, address, data, "not resume command");
697         eeprom->state = read_reset;
698       }
699       return;
700
701     }
702   }
703 }
704
705 static unsigned
706 hw_eeprom_io_write_buffer(device *me,
707                           const void *source,
708                           int space,
709                           unsigned_word addr,
710                           unsigned nr_bytes,
711                           cpu *processor,
712                           unsigned_word cia)
713 {
714   hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
715   int i;
716   for (i = 0; i < nr_bytes; i++) {
717     unsigned_word address = (addr + i) % eeprom->sizeof_memory;
718     unsigned8 byte = ((unsigned8*)source)[i];
719     write_byte(me, eeprom, address, byte);
720   }
721   return nr_bytes;
722 }
723
724
725 /* An instance of the eeprom */
726
727 typedef struct _hw_eeprom_instance {
728   unsigned_word pos;
729   hw_eeprom_device *eeprom;
730   device *me;
731 } hw_eeprom_instance;
732
733 static void
734 hw_eeprom_instance_delete(device_instance *instance)
735 {
736   hw_eeprom_instance *data = device_instance_data(instance);
737   free(data);
738 }
739
740 static int
741 hw_eeprom_instance_read(device_instance *instance,
742                         void *buf,
743                         unsigned_word len)
744 {
745   hw_eeprom_instance *data = device_instance_data(instance);
746   int i;
747   if (data->eeprom->state != read_reset)
748     DITRACE(eeprom, ("eeprom not idle during instance read\n"));
749   for (i = 0; i < len; i++) {
750     ((unsigned8*)buf)[i] = data->eeprom->memory[data->pos];
751     data->pos = (data->pos + 1) % data->eeprom->sizeof_memory;
752   }
753   return len;
754 }
755
756 static int
757 hw_eeprom_instance_write(device_instance *instance,
758                          const void *buf,
759                          unsigned_word len)
760 {
761   hw_eeprom_instance *data = device_instance_data(instance);
762   int i;
763   if (data->eeprom->state != read_reset)
764     DITRACE(eeprom, ("eeprom not idle during instance write\n"));
765   for (i = 0; i < len; i++) {
766     data->eeprom->memory[data->pos] = ((unsigned8*)buf)[i];
767     data->pos = (data->pos + 1) % data->eeprom->sizeof_memory;
768   }
769   dump_eeprom(data->me, data->eeprom);
770   return len;
771 }
772
773 static int
774 hw_eeprom_instance_seek(device_instance *instance,
775                       unsigned_word pos_hi,
776                       unsigned_word pos_lo)
777 {
778   hw_eeprom_instance *data = device_instance_data(instance);
779   if (pos_lo >= data->eeprom->sizeof_memory)
780     device_error(data->me, "seek value 0x%lx out of range\n",
781                  (unsigned long)pos_lo);
782   data->pos = pos_lo;
783   return 0;
784 }
785
786 static const device_instance_callbacks hw_eeprom_instance_callbacks = {
787   hw_eeprom_instance_delete,
788   hw_eeprom_instance_read,
789   hw_eeprom_instance_write,
790   hw_eeprom_instance_seek,
791 };
792
793 static device_instance *
794 hw_eeprom_create_instance(device *me,
795                           const char *path,
796                           const char *args)
797 {
798   hw_eeprom_device *eeprom = device_data(me);
799   hw_eeprom_instance *data = ZALLOC(hw_eeprom_instance);
800   data->eeprom = eeprom;
801   data->me = me;
802   return device_create_instance_from(me, NULL,
803                                      data,
804                                      path, args,
805                                      &hw_eeprom_instance_callbacks);
806 }
807
808
809
810 static device_callbacks const hw_eeprom_callbacks = {
811   { generic_device_init_address,
812     hw_eeprom_init_data },
813   { NULL, }, /* address */
814   { hw_eeprom_io_read_buffer,
815     hw_eeprom_io_write_buffer }, /* IO */
816   { NULL, }, /* DMA */
817   { NULL, }, /* interrupt */
818   { NULL, }, /* unit */
819   hw_eeprom_create_instance,
820 };
821
822 static void *
823 hw_eeprom_create(const char *name,
824                  const device_unit *unit_address,
825                  const char *args)
826 {
827   hw_eeprom_device *eeprom = ZALLOC(hw_eeprom_device);
828   return eeprom;
829 }
830
831
832
833 const device_descriptor hw_eeprom_device_descriptor[] = {
834   { "eeprom", hw_eeprom_create, &hw_eeprom_callbacks },
835   { NULL },
836 };
837
838 #endif /* _HW_EEPROM_C_ */