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 #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_ */