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 2 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, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include "device_table.h"
39 eeprom - JEDEC? compatible electricaly erasable programable device
45 This device implements a small byte addressable EEPROM.
46 Programming is performed using the same write sequences as used by
47 standard modern EEPROM components. Writes occure in real time, the
48 device returning a progress value until the programing has been
51 It is based on the AMD 29F040 component.
57 reg = <address> <size> (required)
59 Determine where the device lives in the parents address space.
62 nr-sectors = <integer> (required)
64 When erasing an entire sector is cleared at a time. This specifies
65 the number of sectors in the EEPROM component.
68 sector-size = <integer> (required)
70 The number of bytes in a sector. When erasing, memory chunks of
71 this size are cleared.
73 NOTE: The product nr-sectors * sector-size does not need to map the
74 size specified in the reg property. If the specified size is
75 smaller part of the eeprom will not be accessible while if it is
76 larger the addresses will wrap.
79 byte-write-delay = <integer> (required)
81 Number of clock ticks before the programming of a single byte
85 sector-start-delay = <integer> (required)
87 When erasing sectors, the number of clock ticks after the sector
88 has been specified that the actual erase process commences.
91 erase-delay = <intger> (required)
93 Number of clock ticks before an erase program completes
96 manufacture-code = <integer> (required)
98 The one byte value returned when the auto-select manufacturer code
102 device-code = <integer> (required)
104 The one byte value returned when the auto-select device code is
108 input-file = <file-name> (optional)
110 Initialize the eeprom using the specified binary file.
113 output-file = <file-name> (optional)
115 When ever the eeprom is updated, save the modified image into the
122 Enable tracing of the eeprom:
124 | bash$ psim -t eeprom-device \
127 Configure something very like the Amd Am29F040 - 512byte EEPROM
130 | -o '/eeprom@0xfff00000/reg 0xfff00000 0x80000' \
131 | -o '/eeprom@0xfff00000/nr-sectors 8' \
132 | -o '/eeprom@0xfff00000/sector-size 0x10000' \
133 | -o '/eeprom@0xfff00000/byte-write-delay 1000' \
134 | -o '/eeprom@0xfff00000/sector-start-delay 100' \
135 | -o '/eeprom@0xfff00000/erase-delay 1000' \
136 | -o '/eeprom@0xfff00000/manufacture-code 0x01' \
137 | -o '/eeprom@0xfff00000/device-code 0xa4' \
140 Initialize the eeprom from the file <</dev/zero>>:
142 | -o '/eeprom@0xfff00000/input-file /dev/zero'
161 sector_erase_suspend,
166 state2a(hw_eeprom_states state)
169 case read_reset: return "read_reset";
170 case write_nr_2: return "write_nr_2";
171 case write_nr_3: return "write_nr_3";
172 case write_nr_4: return "write_nr_4";
173 case write_nr_5: return "write_nr_5";
174 case write_nr_6: return "write_nr_6";
175 case byte_program: return "byte_program";
176 case byte_programming: return "byte_programming";
177 case chip_erase: return "chip_erase";
178 case sector_erase: return "sector_erase";
179 case sector_erase_suspend: return "sector_erase_suspend";
180 case autoselect: return "autoselect";
185 typedef struct _hw_eeprom_device {
187 hw_eeprom_states state;
189 unsigned sizeof_memory;
190 unsigned erase_delay;
191 signed64 program_start_time;
192 signed64 program_finish_time;
193 unsigned8 manufacture_code;
194 unsigned8 device_code;
195 unsigned8 toggle_bit;
197 const char *input_file_name;
198 const char *output_file_name;
199 /* for sector and sector programming */
200 hw_eeprom_states sector_state;
203 unsigned sizeof_sector;
204 unsigned sector_start_delay;
205 unsigned sector_start_time;
206 /* byte and byte programming */
207 unsigned byte_write_delay;
208 unsigned_word byte_program_address;
209 unsigned8 byte_program_byte;
212 typedef struct _hw_eeprom_reg_spec {
215 } hw_eeprom_reg_spec;
218 hw_eeprom_init_data(device *me)
220 hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
222 /* have we any input or output files */
223 if (device_find_property(me, "input-file") != NULL)
224 eeprom->input_file_name = device_find_string_property(me, "input-file");
225 if (device_find_property(me, "output-file") != NULL)
226 eeprom->input_file_name = device_find_string_property(me, "output-file");
228 /* figure out the sectors in the eeprom */
229 if (eeprom->sectors == NULL) {
230 eeprom->nr_sectors = device_find_integer_property(me, "nr-sectors");
231 eeprom->sizeof_sector = device_find_integer_property(me, "sector-size");
232 eeprom->sectors = zalloc(eeprom->nr_sectors);
235 memset(eeprom->sectors, 0, eeprom->nr_sectors);
237 /* initialize the eeprom */
238 if (eeprom->memory == NULL) {
239 eeprom->sizeof_memory = eeprom->sizeof_sector * eeprom->nr_sectors;
240 eeprom->memory = zalloc(eeprom->sizeof_memory);
243 memset(eeprom->memory, 0, eeprom->sizeof_memory);
244 if (eeprom->input_file_name != NULL) {
246 FILE *input_file = fopen(eeprom->input_file_name, "r");
247 if (input_file == NULL) {
249 device_error(me, "Failed to open input file %s\n", eeprom->input_file_name);
251 for (i = 0; i < eeprom->sizeof_memory; i++) {
252 if (fread(&eeprom->memory[i], 1, 1, input_file) != 1)
259 eeprom->byte_write_delay = device_find_integer_property(me, "byte-write-delay");
260 eeprom->sector_start_delay = device_find_integer_property(me, "sector-start-delay");
261 eeprom->erase_delay = device_find_integer_property(me, "erase-delay");
264 eeprom->manufacture_code = device_find_integer_property(me, "manufacture-code");
265 eeprom->device_code = device_find_integer_property(me, "device-code");
270 invalid_read(device *me,
271 hw_eeprom_states state,
272 unsigned_word address,
275 DTRACE(eeprom, ("Invalid read to 0x%lx while in state %s (%s)\n",
276 (unsigned long)address,
282 invalid_write(device *me,
283 hw_eeprom_states state,
284 unsigned_word address,
288 DTRACE(eeprom, ("Invalid write of 0x%lx to 0x%lx while in state %s (%s)\n",
290 (unsigned long)address,
296 dump_eeprom(device *me,
297 hw_eeprom_device *eeprom)
299 if (eeprom->output_file_name != NULL) {
301 FILE *output_file = fopen(eeprom->output_file_name, "w");
302 if (output_file == NULL) {
304 device_error(me, "Failed to open output file %s\n",
305 eeprom->output_file_name);
307 for (i = 0; i < eeprom->sizeof_memory; i++) {
308 if (fwrite(&eeprom->memory[i], 1, 1, output_file) != 1)
316 /* program a single byte of eeprom */
319 start_programming_byte(device *me,
320 hw_eeprom_device *eeprom,
321 unsigned_word address,
324 unsigned8 old_byte = eeprom->memory[address];
325 DTRACE(eeprom, ("start-programing-byte - address 0x%lx, new 0x%lx, old 0x%lx\n",
326 (unsigned long)address,
327 (unsigned long)new_byte,
328 (unsigned long)old_byte));
329 eeprom->byte_program_address = address;
330 /* : old new : ~old : new&~old
332 : 0 1 : 1 : 1 -- can not set a bit
335 if (~old_byte & new_byte)
336 invalid_write(me, eeprom->state, address, new_byte, "setting cleared bit");
337 /* : old new : old&new
342 eeprom->byte_program_byte = new_byte & old_byte;
343 eeprom->memory[address] = ~new_byte & ~0x24; /* LE-bits 5:3 zero */
344 eeprom->program_start_time = device_event_queue_time(me);
345 eeprom->program_finish_time = (eeprom->program_start_time
346 + eeprom->byte_write_delay);
350 finish_programming_byte(device *me,
351 hw_eeprom_device *eeprom)
353 DTRACE(eeprom, ("finish-programming-byte - address 0x%lx, byte 0x%lx\n",
354 (unsigned long)eeprom->byte_program_address,
355 (unsigned long)eeprom->byte_program_byte));
356 eeprom->memory[eeprom->byte_program_address] = eeprom->byte_program_byte;
357 dump_eeprom(me, eeprom);
361 /* erase the eeprom completly */
364 start_erasing_chip(device *me,
365 hw_eeprom_device *eeprom)
367 DTRACE(eeprom, ("start-erasing-chip\n"));
368 memset(eeprom->memory, 0, eeprom->sizeof_memory);
369 eeprom->program_start_time = device_event_queue_time(me);
370 eeprom->program_finish_time = (eeprom->program_start_time
371 + eeprom->erase_delay);
375 finish_erasing_chip(device *me,
376 hw_eeprom_device *eeprom)
378 DTRACE(eeprom, ("finish-erasing-chip\n"));
379 memset(eeprom->memory, 0xff, eeprom->sizeof_memory);
380 dump_eeprom(me, eeprom);
384 /* erase a single sector of the eeprom */
387 start_erasing_sector(device *me,
388 hw_eeprom_device *eeprom,
389 unsigned_word address)
391 int sector = address / eeprom->sizeof_sector;
392 DTRACE(eeprom, ("start-erasing-sector - address 0x%lx, sector %d\n",
393 (unsigned long)address, sector));
394 ASSERT(sector < eeprom->nr_sectors);
395 eeprom->sectors[sector] = 1;
396 memset(eeprom->memory + sector * eeprom->sizeof_sector,
397 0x4, eeprom->sizeof_sector);
398 eeprom->program_start_time = device_event_queue_time(me);
399 eeprom->sector_start_time = (eeprom->program_start_time
400 + eeprom->sector_start_delay);
401 eeprom->program_finish_time = (eeprom->sector_start_time
402 + eeprom->erase_delay);
407 finish_erasing_sector(device *me,
408 hw_eeprom_device *eeprom)
411 DTRACE(eeprom, ("finish-erasing-sector\n"));
412 for (sector = 0; sector < eeprom->nr_sectors; sector++) {
413 if (eeprom->sectors[sector]) {
414 eeprom->sectors[sector] = 0;
415 memset(eeprom->memory + sector * eeprom->sizeof_sector,
416 0xff, eeprom->sizeof_sector);
419 dump_eeprom(me, eeprom);
426 toggle(hw_eeprom_device *eeprom,
429 eeprom->toggle_bit = eeprom->toggle_bit ^ 0x40; /* le-bit 6 */
430 return eeprom->toggle_bit ^ byte;
434 read_byte(device *me,
435 hw_eeprom_device *eeprom,
436 unsigned_word address)
438 /* may need multiple iterations of this */
440 switch (eeprom->state) {
443 return eeprom->memory[address];
446 if ((address & 0xff) == 0x00)
447 return eeprom->manufacture_code;
448 else if ((address & 0xff) == 0x01)
449 return eeprom->device_code;
451 return 0; /* not certain about this */
453 case byte_programming:
454 if (device_event_queue_time(me) > eeprom->program_finish_time) {
455 finish_programming_byte(me, eeprom);
456 eeprom->state = read_reset;
459 else if (address == eeprom->byte_program_address) {
460 return toggle(eeprom, eeprom->memory[address]);
463 /* trash that memory location */
464 invalid_read(me, eeprom->state, address, "not byte program address");
465 eeprom->memory[address] = (eeprom->memory[address]
466 & eeprom->byte_program_byte);
467 return toggle(eeprom, eeprom->memory[eeprom->byte_program_address]);
471 if (device_event_queue_time(me) > eeprom->program_finish_time) {
472 finish_erasing_chip(me, eeprom);
473 eeprom->state = read_reset;
477 return toggle(eeprom, eeprom->memory[address]);
481 if (device_event_queue_time(me) > eeprom->program_finish_time) {
482 finish_erasing_sector(me, eeprom);
483 eeprom->state = read_reset;
486 else if (!eeprom->sectors[address / eeprom->sizeof_sector]) {
487 /* read to wrong sector */
488 invalid_read(me, eeprom->state, address, "sector not being erased");
489 return toggle(eeprom, eeprom->memory[address]) & ~0x8;
491 else if (device_event_queue_time(me) > eeprom->sector_start_time) {
492 return toggle(eeprom, eeprom->memory[address]) | 0x8;
495 return toggle(eeprom, eeprom->memory[address]) & ~0x8;
498 case sector_erase_suspend:
499 if (!eeprom->sectors[address / eeprom->sizeof_sector]) {
500 return eeprom->memory[address];
503 invalid_read(me, eeprom->state, address, "sector being erased");
504 return eeprom->memory[address];
508 invalid_read(me, eeprom->state, address, "invalid state");
509 return eeprom->memory[address];
517 hw_eeprom_io_read_buffer(device *me,
525 hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
527 for (i = 0; i < nr_bytes; i++) {
528 unsigned_word address = (addr + i) % eeprom->sizeof_memory;
529 unsigned8 byte = read_byte(me, eeprom, address);
530 ((unsigned8*)dest)[i] = byte;
539 write_byte(device *me,
540 hw_eeprom_device *eeprom,
541 unsigned_word address,
544 /* may need multiple transitions to process a write */
546 switch (eeprom->state) {
549 if (address == 0x5555 && data == 0xaa)
550 eeprom->state = write_nr_2;
551 else if (data == 0xf0)
552 eeprom->state = read_reset;
554 invalid_write(me, eeprom->state, address, data, "unexpected");
555 eeprom->state = read_reset;
560 if (address == 0x2aaa && data == 0x55)
561 eeprom->state = write_nr_3;
563 invalid_write(me, eeprom->state, address, data, "unexpected");
564 eeprom->state = read_reset;
569 if (address == 0x5555 && data == 0xf0)
570 eeprom->state = read_reset;
571 else if (address == 0x5555 && data == 0x90)
572 eeprom->state = autoselect;
573 else if (address == 0x5555 && data == 0xa0) {
574 eeprom->state = byte_program;
576 else if (address == 0x5555 && data == 0x80)
577 eeprom->state = write_nr_4;
579 invalid_write(me, eeprom->state, address, data, "unexpected");
580 eeprom->state = read_reset;
585 if (address == 0x5555 && data == 0xaa)
586 eeprom->state = write_nr_5;
588 invalid_write(me, eeprom->state, address, data, "unexpected");
589 eeprom->state = read_reset;
594 if (address == 0x2aaa && data == 0x55)
595 eeprom->state = write_nr_6;
597 invalid_write(me, eeprom->state, address, data, "unexpected");
598 eeprom->state = read_reset;
603 if (address == 0x5555 && data == 0x10) {
604 start_erasing_chip(me, eeprom);
605 eeprom->state = chip_erase;
608 start_erasing_sector(me, eeprom, address);
609 eeprom->sector_state = read_reset;
610 eeprom->state = sector_erase;
616 eeprom->state = read_reset;
617 else if (address == 0x5555 && data == 0xaa)
618 eeprom->state = write_nr_2;
620 invalid_write(me, eeprom->state, address, data, "unsupported address");
621 eeprom->state = read_reset;
626 start_programming_byte(me, eeprom, address, data);
627 eeprom->state = byte_programming;
630 case byte_programming:
631 if (device_event_queue_time(me) > eeprom->program_finish_time) {
632 finish_programming_byte(me, eeprom);
633 eeprom->state = read_reset;
640 if (device_event_queue_time(me) > eeprom->program_finish_time) {
641 finish_erasing_chip(me, eeprom);
642 eeprom->state = read_reset;
649 if (device_event_queue_time(me) > eeprom->program_finish_time) {
650 finish_erasing_sector(me, eeprom);
651 eeprom->state = eeprom->sector_state;
654 else if (device_event_queue_time(me) > eeprom->sector_start_time
656 eeprom->sector_state = read_reset;
657 eeprom->state = sector_erase_suspend;
660 if (eeprom->sector_state == read_reset
661 && address == 0x5555 && data == 0xaa)
662 eeprom->sector_state = write_nr_2;
663 else if (eeprom->sector_state == write_nr_2
664 && address == 0x2aaa && data == 0x55)
665 eeprom->sector_state = write_nr_3;
666 else if (eeprom->sector_state == write_nr_3
667 && address == 0x5555 && data == 0x80)
668 eeprom->sector_state = write_nr_4;
669 else if (eeprom->sector_state == write_nr_4
670 && address == 0x5555 && data == 0xaa)
671 eeprom->sector_state = write_nr_5;
672 else if (eeprom->sector_state == write_nr_5
673 && address == 0x2aaa && data == 0x55)
674 eeprom->sector_state = write_nr_6;
675 else if (eeprom->sector_state == write_nr_6
676 && address != 0x5555 && data == 0x30) {
677 if (device_event_queue_time(me) > eeprom->sector_start_time) {
678 DTRACE(eeprom, ("sector erase command after window closed\n"));
679 eeprom->sector_state = read_reset;
682 start_erasing_sector(me, eeprom, address);
683 eeprom->sector_state = read_reset;
687 invalid_write(me, eeprom->state, address, data, state2a(eeprom->sector_state));
688 eeprom->state = read_reset;
693 case sector_erase_suspend:
695 eeprom->state = sector_erase;
697 invalid_write(me, eeprom->state, address, data, "not resume command");
698 eeprom->state = read_reset;
707 hw_eeprom_io_write_buffer(device *me,
715 hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
717 for (i = 0; i < nr_bytes; i++) {
718 unsigned_word address = (addr + i) % eeprom->sizeof_memory;
719 unsigned8 byte = ((unsigned8*)source)[i];
720 write_byte(me, eeprom, address, byte);
726 /* An instance of the eeprom */
728 typedef struct _hw_eeprom_instance {
730 hw_eeprom_device *eeprom;
732 } hw_eeprom_instance;
735 hw_eeprom_instance_delete(device_instance *instance)
737 hw_eeprom_instance *data = device_instance_data(instance);
742 hw_eeprom_instance_read(device_instance *instance,
746 hw_eeprom_instance *data = device_instance_data(instance);
748 if (data->eeprom->state != read_reset)
749 DITRACE(eeprom, ("eeprom not idle during instance read\n"));
750 for (i = 0; i < len; i++) {
751 ((unsigned8*)buf)[i] = data->eeprom->memory[data->pos];
752 data->pos = (data->pos + 1) % data->eeprom->sizeof_memory;
758 hw_eeprom_instance_write(device_instance *instance,
762 hw_eeprom_instance *data = device_instance_data(instance);
764 if (data->eeprom->state != read_reset)
765 DITRACE(eeprom, ("eeprom not idle during instance write\n"));
766 for (i = 0; i < len; i++) {
767 data->eeprom->memory[data->pos] = ((unsigned8*)buf)[i];
768 data->pos = (data->pos + 1) % data->eeprom->sizeof_memory;
770 dump_eeprom(data->me, data->eeprom);
775 hw_eeprom_instance_seek(device_instance *instance,
776 unsigned_word pos_hi,
777 unsigned_word pos_lo)
779 hw_eeprom_instance *data = device_instance_data(instance);
780 if (pos_lo >= data->eeprom->sizeof_memory)
781 device_error(data->me, "seek value 0x%lx out of range\n",
782 (unsigned long)pos_lo);
787 static const device_instance_callbacks hw_eeprom_instance_callbacks = {
788 hw_eeprom_instance_delete,
789 hw_eeprom_instance_read,
790 hw_eeprom_instance_write,
791 hw_eeprom_instance_seek,
794 static device_instance *
795 hw_eeprom_create_instance(device *me,
799 hw_eeprom_device *eeprom = device_data(me);
800 hw_eeprom_instance *data = ZALLOC(hw_eeprom_instance);
801 data->eeprom = eeprom;
803 return device_create_instance_from(me, NULL,
806 &hw_eeprom_instance_callbacks);
811 static device_callbacks const hw_eeprom_callbacks = {
812 { generic_device_init_address,
813 hw_eeprom_init_data },
814 { NULL, }, /* address */
815 { hw_eeprom_io_read_buffer,
816 hw_eeprom_io_write_buffer }, /* IO */
818 { NULL, }, /* interrupt */
819 { NULL, }, /* unit */
820 hw_eeprom_create_instance,
824 hw_eeprom_create(const char *name,
825 const device_unit *unit_address,
828 hw_eeprom_device *eeprom = ZALLOC(hw_eeprom_device);
834 const device_descriptor hw_eeprom_device_descriptor[] = {
835 { "eeprom", hw_eeprom_create, &hw_eeprom_callbacks },
839 #endif /* _HW_EEPROM_C_ */