Fix up mix of man(7)/mdoc(7).
[netbsd-mini2440.git] / gnu / dist / gdb6 / sim / m68hc11 / dv-nvram.c
blob1a8a91a6804cd6fec714f12b85b5362abe7924e0
1 /* dv-nvram.c -- Generic driver for a non volatile ram (battery saved)
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
4 (From a driver model Contributed by Cygnus Solutions.)
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "sim-main.h"
24 #include "hw-main.h"
25 #include "sim-assert.h"
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <errno.h>
32 /* DEVICE
34 nvram - Non Volatile Ram
37 DESCRIPTION
39 Implements a generic battery saved CMOS ram. This ram device does
40 not contain any realtime clock and does not generate any interrupt.
41 The ram content is loaded from a file and saved when it is changed.
42 It is intended to be generic.
45 PROPERTIES
47 reg <base> <length>
49 Base and size of the non-volatile ram bank.
51 file <path>
53 Path where the memory must be saved or loaded when we start.
55 mode {map | save-modified | save-all}
57 Controls how to load and save the memory content.
59 map The file is mapped in memory
60 save-modified The simulator keeps an open file descriptor to
61 the file and saves portion of memory which are
62 modified.
63 save-all The simulator saves the complete memory each time
64 it's modified (it does not keep an open file
65 descriptor).
68 PORTS
70 None.
73 NOTES
75 This device is independent of the Motorola 68hc11.
81 /* static functions */
83 /* Control of how to access the ram and save its content. */
85 enum nvram_mode
87 /* Save the complete ram block each time it's changed.
88 We don't keep an open file descriptor. This should be
89 ok for small memory banks. */
90 NVRAM_SAVE_ALL,
92 /* Save only the memory bytes which are modified.
93 This mode means that we have to keep an open file
94 descriptor (O_RDWR). It's good for middle sized memory banks. */
95 NVRAM_SAVE_MODIFIED,
97 /* Map file in memory (not yet implemented).
98 This mode is suitable for large memory banks. We don't allocate
99 a buffer to represent the ram, instead it's mapped in memory
100 with mmap. */
101 NVRAM_MAP_FILE
104 struct nvram
106 address_word base_address; /* Base address of ram. */
107 unsigned size; /* Size of ram. */
108 unsigned8 *data; /* Pointer to ram memory. */
109 const char *file_name; /* Path of ram file. */
110 int fd; /* File description of opened ram file. */
111 enum nvram_mode mode; /* How load/save ram file. */
116 /* Finish off the partially created hw device. Attach our local
117 callbacks. Wire up our port names etc. */
119 static hw_io_read_buffer_method nvram_io_read_buffer;
120 static hw_io_write_buffer_method nvram_io_write_buffer;
124 static void
125 attach_nvram_regs (struct hw *me, struct nvram *controller)
127 unsigned_word attach_address;
128 int attach_space;
129 unsigned attach_size;
130 reg_property_spec reg;
131 int result, oerrno;
133 /* Get ram bank description (base and size). */
134 if (hw_find_property (me, "reg") == NULL)
135 hw_abort (me, "Missing \"reg\" property");
137 if (!hw_find_reg_array_property (me, "reg", 0, &reg))
138 hw_abort (me, "\"reg\" property must contain one addr/size entry");
140 hw_unit_address_to_attach_address (hw_parent (me),
141 &reg.address,
142 &attach_space,
143 &attach_address,
144 me);
145 hw_unit_size_to_attach_size (hw_parent (me),
146 &reg.size,
147 &attach_size, me);
149 hw_attach_address (hw_parent (me), 0,
150 attach_space, attach_address, attach_size,
151 me);
153 controller->mode = NVRAM_SAVE_ALL;
154 controller->base_address = attach_address;
155 controller->size = attach_size;
156 controller->fd = -1;
158 /* Get the file where the ram content must be loaded/saved. */
159 if(hw_find_property (me, "file") == NULL)
160 hw_abort (me, "Missing \"file\" property");
162 controller->file_name = hw_find_string_property (me, "file");
164 /* Get the mode which defines how to save the memory. */
165 if(hw_find_property (me, "mode") != NULL)
167 const char *value = hw_find_string_property (me, "mode");
169 if (strcmp (value, "map") == 0)
170 controller->mode = NVRAM_MAP_FILE;
171 else if (strcmp (value, "save-modified") == 0)
172 controller->mode = NVRAM_SAVE_MODIFIED;
173 else if (strcmp (value, "save-all") == 0)
174 controller->mode = NVRAM_SAVE_ALL;
175 else
176 hw_abort (me, "illegal value for mode parameter `%s': "
177 "use map, save-modified or save-all", value);
180 /* Initialize the ram by loading/mapping the file in memory.
181 If the file does not exist, create and give it some content. */
182 switch (controller->mode)
184 case NVRAM_MAP_FILE:
185 hw_abort (me, "'map' mode is not yet implemented, use 'save-modified'");
186 break;
188 case NVRAM_SAVE_MODIFIED:
189 case NVRAM_SAVE_ALL:
190 controller->data = (char*) hw_malloc (me, attach_size);
191 if (controller->data == 0)
192 hw_abort (me, "Not enough memory, try to use the mode 'map'");
194 memset (controller->data, 0, attach_size);
195 controller->fd = open (controller->file_name, O_RDWR);
196 if (controller->fd < 0)
198 controller->fd = open (controller->file_name,
199 O_RDWR | O_CREAT, 0644);
200 if (controller->fd < 0)
201 hw_abort (me, "Cannot open or create file '%s'",
202 controller->file_name);
203 result = write (controller->fd, controller->data, attach_size);
204 if (result != attach_size)
206 oerrno = errno;
207 hw_free (me, controller->data);
208 close (controller->fd);
209 errno = oerrno;
210 hw_abort (me, "Failed to save the ram content");
213 else
215 result = read (controller->fd, controller->data, attach_size);
216 if (result != attach_size)
218 oerrno = errno;
219 hw_free (me, controller->data);
220 close (controller->fd);
221 errno = oerrno;
222 hw_abort (me, "Failed to load the ram content");
225 if (controller->mode == NVRAM_SAVE_ALL)
227 close (controller->fd);
228 controller->fd = -1;
230 break;
232 default:
233 break;
238 static void
239 nvram_finish (struct hw *me)
241 struct nvram *controller;
243 controller = HW_ZALLOC (me, struct nvram);
245 set_hw_data (me, controller);
246 set_hw_io_read_buffer (me, nvram_io_read_buffer);
247 set_hw_io_write_buffer (me, nvram_io_write_buffer);
249 /* Attach ourself to our parent bus. */
250 attach_nvram_regs (me, controller);
255 /* generic read/write */
257 static unsigned
258 nvram_io_read_buffer (struct hw *me,
259 void *dest,
260 int space,
261 unsigned_word base,
262 unsigned nr_bytes)
264 struct nvram *controller = hw_data (me);
266 HW_TRACE ((me, "read 0x%08lx %d [%ld]",
267 (long) base, (int) nr_bytes,
268 (long) (base - controller->base_address)));
270 base -= controller->base_address;
271 if (base + nr_bytes > controller->size)
272 nr_bytes = controller->size - base;
274 memcpy (dest, &controller->data[base], nr_bytes);
275 return nr_bytes;
280 static unsigned
281 nvram_io_write_buffer (struct hw *me,
282 const void *source,
283 int space,
284 unsigned_word base,
285 unsigned nr_bytes)
287 struct nvram *controller = hw_data (me);
289 HW_TRACE ((me, "write 0x%08lx %d [%ld]",
290 (long) base, (int) nr_bytes,
291 (long) (base - controller->base_address)));
293 base -= controller->base_address;
294 if (base + nr_bytes > controller->size)
295 nr_bytes = controller->size - base;
297 switch (controller->mode)
299 case NVRAM_SAVE_ALL:
301 int fd, result, oerrno;
303 fd = open (controller->file_name, O_WRONLY, 0644);
304 if (fd < 0)
306 return 0;
309 memcpy (&controller->data[base], source, nr_bytes);
310 result = write (fd, controller->data, controller->size);
311 oerrno = errno;
312 close (fd);
313 errno = oerrno;
315 if (result != controller->size)
317 return 0;
319 return nr_bytes;
322 case NVRAM_SAVE_MODIFIED:
324 off_t pos;
325 int result;
327 pos = lseek (controller->fd, (off_t) base, SEEK_SET);
328 if (pos != (off_t) base)
329 return 0;
331 result = write (controller->fd, source, nr_bytes);
332 if (result < 0)
333 return 0;
335 nr_bytes = result;
336 break;
339 default:
340 break;
342 memcpy (&controller->data[base], source, nr_bytes);
343 return nr_bytes;
347 const struct hw_descriptor dv_nvram_descriptor[] = {
348 { "nvram", nvram_finish, },
349 { NULL },