OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [m68hc11/] [dv-nvram.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/*  dv-nvram.c -- Generic driver for a non volatile ram (battery saved)
2
    Copyright (C) 1999, 2000, 2007, 2008 Free Software Foundation, Inc.
3
    Written by Stephane Carrez (stcarrez@worldnet.fr)
4
    (From a driver model Contributed by Cygnus Solutions.)
5
 
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 3 of the License, or
9
    (at your option) any later version.
10
 
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.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
19
    */
20
 
21
 
22
#include "sim-main.h"
23
#include "hw-main.h"
24
#include "sim-assert.h"
25
 
26
#include <unistd.h>
27
#include <fcntl.h>
28
#include <errno.h>
29
 
30
 
31
/* DEVICE
32
 
33
        nvram - Non Volatile Ram
34
 
35
 
36
   DESCRIPTION
37
 
38
        Implements a generic battery saved CMOS ram. This ram device does
39
        not contain any realtime clock and does not generate any interrupt.
40
        The ram content is loaded from a file and saved when it is changed.
41
        It is intended to be generic.
42
 
43
 
44
   PROPERTIES
45
 
46
   reg <base> <length>
47
 
48
        Base and size of the non-volatile ram bank.
49
 
50
   file <path>
51
 
52
        Path where the memory must be saved or loaded when we start.
53
 
54
   mode {map | save-modified | save-all}
55
 
56
        Controls how to load and save the memory content.
57
 
58
           map            The file is mapped in memory
59
           save-modified  The simulator keeps an open file descriptor to
60
                          the file and saves portion of memory which are
61
                          modified.
62
           save-all       The simulator saves the complete memory each time
63
                          it's modified (it does not keep an open file
64
                          descriptor).
65
 
66
 
67
   PORTS
68
 
69
        None.
70
 
71
 
72
   NOTES
73
 
74
        This device is independent of the Motorola 68hc11.
75
 
76
   */
77
 
78
 
79
 
80
/* static functions */
81
 
82
/* Control of how to access the ram and save its content.  */
83
 
84
enum nvram_mode
85
{
86
  /* Save the complete ram block each time it's changed.
87
     We don't keep an open file descriptor.  This should be
88
     ok for small memory banks.  */
89
  NVRAM_SAVE_ALL,
90
 
91
  /* Save only the memory bytes which are modified.
92
     This mode means that we have to keep an open file
93
     descriptor (O_RDWR).  It's good for middle sized memory banks.  */
94
  NVRAM_SAVE_MODIFIED,
95
 
96
  /* Map file in memory (not yet implemented).
97
     This mode is suitable for large memory banks.  We don't allocate
98
     a buffer to represent the ram, instead it's mapped in memory
99
     with mmap.  */
100
  NVRAM_MAP_FILE
101
};
102
 
103
struct nvram
104
{
105
  address_word    base_address; /* Base address of ram.  */
106
  unsigned        size;         /* Size of ram.  */
107
  unsigned8       *data;        /* Pointer to ram memory.  */
108
  const char      *file_name;   /* Path of ram file.  */
109
  int             fd;           /* File description of opened ram file.  */
110
  enum nvram_mode mode;         /* How load/save ram file.  */
111
};
112
 
113
 
114
 
115
/* Finish off the partially created hw device.  Attach our local
116
   callbacks.  Wire up our port names etc.  */
117
 
118
static hw_io_read_buffer_method  nvram_io_read_buffer;
119
static hw_io_write_buffer_method nvram_io_write_buffer;
120
 
121
 
122
 
123
static void
124
attach_nvram_regs (struct hw *me, struct nvram *controller)
125
{
126
  unsigned_word attach_address;
127
  int attach_space;
128
  unsigned attach_size;
129
  reg_property_spec reg;
130
  int result, oerrno;
131
 
132
  /* Get ram bank description (base and size).  */
133
  if (hw_find_property (me, "reg") == NULL)
134
    hw_abort (me, "Missing \"reg\" property");
135
 
136
  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
137
    hw_abort (me, "\"reg\" property must contain one addr/size entry");
138
 
139
  hw_unit_address_to_attach_address (hw_parent (me),
140
                                     &reg.address,
141
                                     &attach_space,
142
                                     &attach_address,
143
                                     me);
144
  hw_unit_size_to_attach_size (hw_parent (me),
145
                               &reg.size,
146
                               &attach_size, me);
147
 
148
  hw_attach_address (hw_parent (me), 0,
149
                     attach_space, attach_address, attach_size,
150
                     me);
151
 
152
  controller->mode         = NVRAM_SAVE_ALL;
153
  controller->base_address = attach_address;
154
  controller->size         = attach_size;
155
  controller->fd           = -1;
156
 
157
  /* Get the file where the ram content must be loaded/saved.  */
158
  if(hw_find_property (me, "file") == NULL)
159
    hw_abort (me, "Missing \"file\" property");
160
 
161
  controller->file_name = hw_find_string_property (me, "file");
162
 
163
  /* Get the mode which defines how to save the memory.  */
164
  if(hw_find_property (me, "mode") != NULL)
165
    {
166
      const char *value = hw_find_string_property (me, "mode");
167
 
168
      if (strcmp (value, "map") == 0)
169
        controller->mode = NVRAM_MAP_FILE;
170
      else if (strcmp (value, "save-modified") == 0)
171
        controller->mode = NVRAM_SAVE_MODIFIED;
172
      else if (strcmp (value, "save-all") == 0)
173
        controller->mode = NVRAM_SAVE_ALL;
174
      else
175
        hw_abort (me, "illegal value for mode parameter `%s': "
176
                  "use map, save-modified or save-all", value);
177
    }
178
 
179
  /* Initialize the ram by loading/mapping the file in memory.
180
     If the file does not exist, create and give it some content.  */
181
  switch (controller->mode)
182
    {
183
    case NVRAM_MAP_FILE:
184
      hw_abort (me, "'map' mode is not yet implemented, use 'save-modified'");
185
      break;
186
 
187
    case NVRAM_SAVE_MODIFIED:
188
    case NVRAM_SAVE_ALL:
189
      controller->data = (char*) hw_malloc (me, attach_size);
190
      if (controller->data == 0)
191
        hw_abort (me, "Not enough memory, try to use the mode 'map'");
192
 
193
      memset (controller->data, 0, attach_size);
194
      controller->fd = open (controller->file_name, O_RDWR);
195
      if (controller->fd < 0)
196
        {
197
          controller->fd = open (controller->file_name,
198
                                 O_RDWR | O_CREAT, 0644);
199
          if (controller->fd < 0)
200
            hw_abort (me, "Cannot open or create file '%s'",
201
                      controller->file_name);
202
          result = write (controller->fd, controller->data, attach_size);
203
          if (result != attach_size)
204
            {
205
              oerrno = errno;
206
              hw_free (me, controller->data);
207
              close (controller->fd);
208
              errno = oerrno;
209
              hw_abort (me, "Failed to save the ram content");
210
            }
211
        }
212
      else
213
        {
214
          result = read (controller->fd, controller->data, attach_size);
215
          if (result != attach_size)
216
            {
217
              oerrno = errno;
218
              hw_free (me, controller->data);
219
              close (controller->fd);
220
              errno = oerrno;
221
              hw_abort (me, "Failed to load the ram content");
222
            }
223
        }
224
      if (controller->mode == NVRAM_SAVE_ALL)
225
        {
226
          close (controller->fd);
227
          controller->fd = -1;
228
        }
229
      break;
230
 
231
    default:
232
      break;
233
    }
234
}
235
 
236
 
237
static void
238
nvram_finish (struct hw *me)
239
{
240
  struct nvram *controller;
241
 
242
  controller = HW_ZALLOC (me, struct nvram);
243
 
244
  set_hw_data (me, controller);
245
  set_hw_io_read_buffer (me, nvram_io_read_buffer);
246
  set_hw_io_write_buffer (me, nvram_io_write_buffer);
247
 
248
  /* Attach ourself to our parent bus.  */
249
  attach_nvram_regs (me, controller);
250
}
251
 
252
 
253
 
254
/* generic read/write */
255
 
256
static unsigned
257
nvram_io_read_buffer (struct hw *me,
258
                      void *dest,
259
                      int space,
260
                      unsigned_word base,
261
                      unsigned nr_bytes)
262
{
263
  struct nvram *controller = hw_data (me);
264
 
265
  HW_TRACE ((me, "read 0x%08lx %d [%ld]",
266
             (long) base, (int) nr_bytes,
267
             (long) (base - controller->base_address)));
268
 
269
  base -= controller->base_address;
270
  if (base + nr_bytes > controller->size)
271
    nr_bytes = controller->size - base;
272
 
273
  memcpy (dest, &controller->data[base], nr_bytes);
274
  return nr_bytes;
275
}
276
 
277
 
278
 
279
static unsigned
280
nvram_io_write_buffer (struct hw *me,
281
                       const void *source,
282
                       int space,
283
                       unsigned_word base,
284
                       unsigned nr_bytes)
285
{
286
  struct nvram *controller = hw_data (me);
287
 
288
  HW_TRACE ((me, "write 0x%08lx %d [%ld]",
289
             (long) base, (int) nr_bytes,
290
             (long) (base - controller->base_address)));
291
 
292
  base -= controller->base_address;
293
  if (base + nr_bytes > controller->size)
294
    nr_bytes = controller->size - base;
295
 
296
  switch (controller->mode)
297
    {
298
    case NVRAM_SAVE_ALL:
299
      {
300
        int fd, result, oerrno;
301
 
302
        fd = open (controller->file_name, O_WRONLY, 0644);
303
        if (fd < 0)
304
          {
305
            return 0;
306
          }
307
 
308
        memcpy (&controller->data[base], source, nr_bytes);
309
        result = write (fd, controller->data, controller->size);
310
        oerrno = errno;
311
        close (fd);
312
        errno = oerrno;
313
 
314
        if (result != controller->size)
315
          {
316
            return 0;
317
          }
318
        return nr_bytes;
319
      }
320
 
321
    case NVRAM_SAVE_MODIFIED:
322
      {
323
        off_t pos;
324
        int result;
325
 
326
        pos = lseek (controller->fd, (off_t) base, SEEK_SET);
327
        if (pos != (off_t) base)
328
          return 0;
329
 
330
        result = write (controller->fd, source, nr_bytes);
331
        if (result < 0)
332
          return 0;
333
 
334
        nr_bytes = result;
335
        break;
336
      }
337
 
338
    default:
339
      break;
340
    }
341
  memcpy (&controller->data[base], source, nr_bytes);
342
  return nr_bytes;
343
}
344
 
345
 
346
const struct hw_descriptor dv_nvram_descriptor[] = {
347
  { "nvram", nvram_finish, },
348
  { NULL },
349
};
350
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.