1 /* This file is part of the program psim.
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 #ifndef STATIC_INLINE_HW_EEPROM
26 #define STATIC_INLINE_HW_EEPROM STATIC_INLINE
29 #include "device_table.h"
39 /* EEPROM - electricaly erasable programable memory
43 This device implements a small byte addressable EEPROM.
44 Programming is performed using the same write sequences as used by
45 modern EEPROM components. Writes occure in real time, the device
46 returning a progress value until the programing has been completed.
50 reg = <address> <size>. Determine where the device lives in the
51 parents address space.
53 nr-sectors = <integer>. When erasing an entire sector is cleared
54 at a time. This specifies the number of sectors in the EEPROM
57 byte-write-delay = <integer>. Number of clock ticks before the
58 programming of a single byte completes.
60 sector-start-delay = <integer>. When erasing sectors, the number
61 of clock ticks after the sector has been specified and the actual
62 erase process commences.
64 erase-delay = <intger>. Number of clock ticks before an erase
76 chip_erase, chip_erasing,
77 sector_erase, sector_erasing,
82 typedef struct _eeprom_device {
84 unsigned sizeof_memory;
87 unsigned byte_write_delay;
88 unsigned sector_start_delay;
90 signed64 programme_start_time;
91 unsigned program_byte_address;
96 eeprom_create(const char *name,
97 const device_unit *unit_address,
101 eeprom_device *eeprom = ZALLOC(eeprom_device);
105 typedef struct _eeprom_reg_spec {
111 eeprom_init_address(device *me,
114 eeprom_device *eeprom = (eeprom_device*)device_data(me);
115 const device_property *reg = device_find_array_property(me, "reg");
116 const eeprom_reg_spec *spec = reg->array;
117 int nr_entries = reg->sizeof_array / sizeof(*spec);
119 if ((reg->sizeof_array % sizeof(*spec)) != 0)
120 error("devices/%s reg property of incorrect size\n", device_name(me));
122 error("devices/%s reg property contains multiple specs\n",
125 /* initialize the eeprom */
126 if (eeprom->memory == NULL) {
127 eeprom->sizeof_memory = BE2H_4(spec->size);
128 eeprom->memory = zalloc(eeprom->sizeof_memory);
131 memset(eeprom->memory, eeprom->sizeof_memory, 0);
133 /* figure out the sectors in the eeprom */
134 eeprom->nr_sectors = device_find_integer_property(me, "nr-sectors");
135 eeprom->sector_size = eeprom->sizeof_memory / eeprom->nr_sectors;
136 if (eeprom->sector_size * eeprom->nr_sectors != eeprom->sizeof_memory)
137 error("device/%s nr-sectors does not evenly divide eeprom\n",
141 eeprom->byte_write_delay = device_find_integer_property(me, "byte-write-delay");
142 eeprom->sector_start_delay = device_find_integer_property(me, "sector-start-delay");
143 eeprom->erase_delay = device_find_integer_property(me, "erase-delay");
145 device_attach_address(device_parent(me),
150 eeprom->sizeof_memory,
151 access_read_write_exec,
157 eeprom_io_read_buffer(device *me,
165 eeprom_device *eeprom = (eeprom_device*)device_data(me);
167 for (i = 0; i < nr_bytes; i++) {
168 unsigned_word address = (addr + nr_bytes) % eeprom->sizeof_memory;
169 eeprom->memory[address] = eeprom_io_read_byte(address);
175 eeprom_io_write_byte()
179 if (address == 0x5555 && data = 0xaa)
185 if (address == 0x2aaa && data == 0x55)
186 state = second_write;
188 state = read_reset; /* issue warning */
191 if (address == 0x5555 && data == 0xf0)
193 else if (address == 0x5555 && data == 0x90)
195 else if (address == 0x5555 && data == 0xa0)
196 state = byte_program;
197 else if (address == 0x5555 && data == 0x80)
203 if (address == 0x5555 && data == 0xaa)
209 if (address == 0x2aaa && data == 0x55)
215 if (address == 0x5555 && data == 0x10)
223 else if (address == 0x5555 && data == 0xaa)
224 state = second_write;
226 state = read_reset; /* issue warning */
230 state = sector_erase_suspend;
232 state = sector_erase; /* ignore */
234 case sector_erase_suspend:
236 state = sector_erase;
238 state = sector_erase_suspend; /* ignore */
241 /* perform the byte program */
242 program_address = address;
243 program_start = some_time();
245 /* but only make things `0' and never 1 */
246 byte[address] = data;
247 state = byte_programming;
249 case byte_programming:
253 state = byte_programming;
259 eeprom_io_write_buffer(device *me,
267 eeprom_device *eeprom = (eeprom_device*)device_data(me);
269 for (i = 0; i < nr_bytes; i++) {
270 unsigned_word address = (addr + nr_bytes) % eeprom->sizeof_memory;
271 eeprom_io_read_byte(address, eeprom->memory[address]);
278 static device_callbacks const eeprom_callbacks = {
279 { eeprom_init_address, },
280 { NULL, }, /* address */
281 { eeprom_io_read_buffer, eeprom_io_write_buffer }, /* IO */
284 const device_descriptor eeprom_device_descriptor[] = {
285 { "eeprom", eeprom_create, &eeprom_callbacks },
289 #endif /* _HW_EEPROM_C_ */