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