1 /* This file is part of the program psim.
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
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.
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.
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/>.
24 #include "device_table.h"
32 eeprom - JEDEC? compatible electricaly erasable programable device
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
44 It is based on the AMD 29F040 component.
50 reg = <address> <size> (required)
52 Determine where the device lives in the parents address space.
55 nr-sectors = <integer> (required)
57 When erasing an entire sector is cleared at a time. This specifies
58 the number of sectors in the EEPROM component.
61 sector-size = <integer> (required)
63 The number of bytes in a sector. When erasing, memory chunks of
64 this size are cleared.
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.
72 byte-write-delay = <integer> (required)
74 Number of clock ticks before the programming of a single byte
78 sector-start-delay = <integer> (required)
80 When erasing sectors, the number of clock ticks after the sector
81 has been specified that the actual erase process commences.
84 erase-delay = <intger> (required)
86 Number of clock ticks before an erase program completes
89 manufacture-code = <integer> (required)
91 The one byte value returned when the auto-select manufacturer code
95 device-code = <integer> (required)
97 The one byte value returned when the auto-select device code is
101 input-file = <file-name> (optional)
103 Initialize the eeprom using the specified binary file.
106 output-file = <file-name> (optional)
108 When ever the eeprom is updated, save the modified image into the
115 Enable tracing of the eeprom:
117 | bash$ psim -t eeprom-device \
120 Configure something very like the Amd Am29F040 - 512byte EEPROM
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' \
133 Initialize the eeprom from the file <</dev/zero>>:
135 | -o '/eeprom@0xfff00000/input-file /dev/zero'
154 sector_erase_suspend
,
159 state2a(hw_eeprom_states 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";
178 typedef struct _hw_eeprom_device
{
180 hw_eeprom_states state
;
182 unsigned sizeof_memory
;
183 unsigned erase_delay
;
184 int64_t program_start_time
;
185 int64_t program_finish_time
;
186 uint8_t manufacture_code
;
190 const char *input_file_name
;
191 const char *output_file_name
;
192 /* for sector and sector programming */
193 hw_eeprom_states sector_state
;
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 uint8_t byte_program_byte
;
205 typedef struct _hw_eeprom_reg_spec
{
208 } hw_eeprom_reg_spec
;
211 hw_eeprom_init_data(device
*me
)
213 hw_eeprom_device
*eeprom
= (hw_eeprom_device
*)device_data(me
);
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");
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
);
228 memset(eeprom
->sectors
, 0, eeprom
->nr_sectors
);
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
);
236 memset(eeprom
->memory
, 0, eeprom
->sizeof_memory
);
237 if (eeprom
->input_file_name
!= NULL
) {
239 FILE *input_file
= fopen(eeprom
->input_file_name
, "r");
240 if (input_file
== NULL
) {
242 device_error(me
, "Failed to open input file %s\n", eeprom
->input_file_name
);
244 for (i
= 0; i
< eeprom
->sizeof_memory
; i
++) {
245 if (fread(&eeprom
->memory
[i
], 1, 1, input_file
) != 1)
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");
257 eeprom
->manufacture_code
= device_find_integer_property(me
, "manufacture-code");
258 eeprom
->device_code
= device_find_integer_property(me
, "device-code");
263 invalid_read(device
*me
,
264 hw_eeprom_states state
,
265 unsigned_word address
,
268 DTRACE(eeprom
, ("Invalid read to 0x%lx while in state %s (%s)\n",
269 (unsigned long)address
,
275 invalid_write(device
*me
,
276 hw_eeprom_states state
,
277 unsigned_word address
,
281 DTRACE(eeprom
, ("Invalid write of 0x%lx to 0x%lx while in state %s (%s)\n",
283 (unsigned long)address
,
289 dump_eeprom(device
*me
,
290 hw_eeprom_device
*eeprom
)
292 if (eeprom
->output_file_name
!= NULL
) {
294 FILE *output_file
= fopen(eeprom
->output_file_name
, "w");
295 if (output_file
== NULL
) {
297 device_error(me
, "Failed to open output file %s\n",
298 eeprom
->output_file_name
);
300 for (i
= 0; i
< eeprom
->sizeof_memory
; i
++) {
301 if (fwrite(&eeprom
->memory
[i
], 1, 1, output_file
) != 1)
309 /* program a single byte of eeprom */
312 start_programming_byte(device
*me
,
313 hw_eeprom_device
*eeprom
,
314 unsigned_word address
,
317 uint8_t 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
325 : 0 1 : 1 : 1 -- can not set a bit
328 if (~old_byte
& new_byte
)
329 invalid_write(me
, eeprom
->state
, address
, new_byte
, "setting cleared bit");
330 /* : old new : old&new
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
);
343 finish_programming_byte(device
*me
,
344 hw_eeprom_device
*eeprom
)
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
);
354 /* erase the eeprom completly */
357 start_erasing_chip(device
*me
,
358 hw_eeprom_device
*eeprom
)
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
);
368 finish_erasing_chip(device
*me
,
369 hw_eeprom_device
*eeprom
)
371 DTRACE(eeprom
, ("finish-erasing-chip\n"));
372 memset(eeprom
->memory
, 0xff, eeprom
->sizeof_memory
);
373 dump_eeprom(me
, eeprom
);
377 /* erase a single sector of the eeprom */
380 start_erasing_sector(device
*me
,
381 hw_eeprom_device
*eeprom
,
382 unsigned_word address
)
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
);
400 finish_erasing_sector(device
*me
,
401 hw_eeprom_device
*eeprom
)
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
);
412 dump_eeprom(me
, eeprom
);
419 toggle(hw_eeprom_device
*eeprom
,
422 eeprom
->toggle_bit
= eeprom
->toggle_bit
^ 0x40; /* le-bit 6 */
423 return eeprom
->toggle_bit
^ byte
;
427 read_byte(device
*me
,
428 hw_eeprom_device
*eeprom
,
429 unsigned_word address
)
431 /* may need multiple iterations of this */
433 switch (eeprom
->state
) {
436 return eeprom
->memory
[address
];
439 if ((address
& 0xff) == 0x00)
440 return eeprom
->manufacture_code
;
441 else if ((address
& 0xff) == 0x01)
442 return eeprom
->device_code
;
444 return 0; /* not certain about this */
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
;
452 else if (address
== eeprom
->byte_program_address
) {
453 return toggle(eeprom
, eeprom
->memory
[address
]);
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
]);
464 if (device_event_queue_time(me
) > eeprom
->program_finish_time
) {
465 finish_erasing_chip(me
, eeprom
);
466 eeprom
->state
= read_reset
;
470 return toggle(eeprom
, eeprom
->memory
[address
]);
474 if (device_event_queue_time(me
) > eeprom
->program_finish_time
) {
475 finish_erasing_sector(me
, eeprom
);
476 eeprom
->state
= read_reset
;
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;
484 else if (device_event_queue_time(me
) > eeprom
->sector_start_time
) {
485 return toggle(eeprom
, eeprom
->memory
[address
]) | 0x8;
488 return toggle(eeprom
, eeprom
->memory
[address
]) & ~0x8;
491 case sector_erase_suspend
:
492 if (!eeprom
->sectors
[address
/ eeprom
->sizeof_sector
]) {
493 return eeprom
->memory
[address
];
496 invalid_read(me
, eeprom
->state
, address
, "sector being erased");
497 return eeprom
->memory
[address
];
501 invalid_read(me
, eeprom
->state
, address
, "invalid state");
502 return eeprom
->memory
[address
];
510 hw_eeprom_io_read_buffer(device
*me
,
518 hw_eeprom_device
*eeprom
= (hw_eeprom_device
*)device_data(me
);
520 for (i
= 0; i
< nr_bytes
; i
++) {
521 unsigned_word address
= (addr
+ i
) % eeprom
->sizeof_memory
;
522 uint8_t byte
= read_byte(me
, eeprom
, address
);
523 ((uint8_t*)dest
)[i
] = byte
;
532 write_byte(device
*me
,
533 hw_eeprom_device
*eeprom
,
534 unsigned_word address
,
537 /* may need multiple transitions to process a write */
539 switch (eeprom
->state
) {
542 if (address
== 0x5555 && data
== 0xaa)
543 eeprom
->state
= write_nr_2
;
544 else if (data
== 0xf0)
545 eeprom
->state
= read_reset
;
547 invalid_write(me
, eeprom
->state
, address
, data
, "unexpected");
548 eeprom
->state
= read_reset
;
553 if (address
== 0x2aaa && data
== 0x55)
554 eeprom
->state
= write_nr_3
;
556 invalid_write(me
, eeprom
->state
, address
, data
, "unexpected");
557 eeprom
->state
= read_reset
;
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
;
569 else if (address
== 0x5555 && data
== 0x80)
570 eeprom
->state
= write_nr_4
;
572 invalid_write(me
, eeprom
->state
, address
, data
, "unexpected");
573 eeprom
->state
= read_reset
;
578 if (address
== 0x5555 && data
== 0xaa)
579 eeprom
->state
= write_nr_5
;
581 invalid_write(me
, eeprom
->state
, address
, data
, "unexpected");
582 eeprom
->state
= read_reset
;
587 if (address
== 0x2aaa && data
== 0x55)
588 eeprom
->state
= write_nr_6
;
590 invalid_write(me
, eeprom
->state
, address
, data
, "unexpected");
591 eeprom
->state
= read_reset
;
596 if (address
== 0x5555 && data
== 0x10) {
597 start_erasing_chip(me
, eeprom
);
598 eeprom
->state
= chip_erase
;
601 start_erasing_sector(me
, eeprom
, address
);
602 eeprom
->sector_state
= read_reset
;
603 eeprom
->state
= sector_erase
;
609 eeprom
->state
= read_reset
;
610 else if (address
== 0x5555 && data
== 0xaa)
611 eeprom
->state
= write_nr_2
;
613 invalid_write(me
, eeprom
->state
, address
, data
, "unsupported address");
614 eeprom
->state
= read_reset
;
619 start_programming_byte(me
, eeprom
, address
, data
);
620 eeprom
->state
= byte_programming
;
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
;
633 if (device_event_queue_time(me
) > eeprom
->program_finish_time
) {
634 finish_erasing_chip(me
, eeprom
);
635 eeprom
->state
= read_reset
;
642 if (device_event_queue_time(me
) > eeprom
->program_finish_time
) {
643 finish_erasing_sector(me
, eeprom
);
644 eeprom
->state
= eeprom
->sector_state
;
647 else if (device_event_queue_time(me
) > eeprom
->sector_start_time
649 eeprom
->sector_state
= read_reset
;
650 eeprom
->state
= sector_erase_suspend
;
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
;
675 start_erasing_sector(me
, eeprom
, address
);
676 eeprom
->sector_state
= read_reset
;
680 invalid_write(me
, eeprom
->state
, address
, data
, state2a(eeprom
->sector_state
));
681 eeprom
->state
= read_reset
;
686 case sector_erase_suspend
:
688 eeprom
->state
= sector_erase
;
690 invalid_write(me
, eeprom
->state
, address
, data
, "not resume command");
691 eeprom
->state
= read_reset
;
700 hw_eeprom_io_write_buffer(device
*me
,
708 hw_eeprom_device
*eeprom
= (hw_eeprom_device
*)device_data(me
);
710 for (i
= 0; i
< nr_bytes
; i
++) {
711 unsigned_word address
= (addr
+ i
) % eeprom
->sizeof_memory
;
712 uint8_t byte
= ((uint8_t*)source
)[i
];
713 write_byte(me
, eeprom
, address
, byte
);
719 /* An instance of the eeprom */
721 typedef struct _hw_eeprom_instance
{
723 hw_eeprom_device
*eeprom
;
725 } hw_eeprom_instance
;
728 hw_eeprom_instance_delete(device_instance
*instance
)
730 hw_eeprom_instance
*data
= device_instance_data(instance
);
735 hw_eeprom_instance_read(device_instance
*instance
,
739 hw_eeprom_instance
*data
= device_instance_data(instance
);
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 ((uint8_t*)buf
)[i
] = data
->eeprom
->memory
[data
->pos
];
745 data
->pos
= (data
->pos
+ 1) % data
->eeprom
->sizeof_memory
;
751 hw_eeprom_instance_write(device_instance
*instance
,
755 hw_eeprom_instance
*data
= device_instance_data(instance
);
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
] = ((uint8_t*)buf
)[i
];
761 data
->pos
= (data
->pos
+ 1) % data
->eeprom
->sizeof_memory
;
763 dump_eeprom(data
->me
, data
->eeprom
);
768 hw_eeprom_instance_seek(device_instance
*instance
,
769 unsigned_word pos_hi
,
770 unsigned_word pos_lo
)
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
);
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
,
787 static device_instance
*
788 hw_eeprom_create_instance(device
*me
,
792 hw_eeprom_device
*eeprom
= device_data(me
);
793 hw_eeprom_instance
*data
= ZALLOC(hw_eeprom_instance
);
794 data
->eeprom
= eeprom
;
796 return device_create_instance_from(me
, NULL
,
799 &hw_eeprom_instance_callbacks
);
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 */
811 { NULL
, }, /* interrupt */
812 { NULL
, }, /* unit */
813 hw_eeprom_create_instance
,
817 hw_eeprom_create(const char *name
,
818 const device_unit
*unit_address
,
821 hw_eeprom_device
*eeprom
= ZALLOC(hw_eeprom_device
);
827 const device_descriptor hw_eeprom_device_descriptor
[] = {
828 { "eeprom", hw_eeprom_create
, &hw_eeprom_callbacks
},
832 #endif /* _HW_EEPROM_C_ */