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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [m68hc11/] [dv-nvram.c] - Blame information for rev 227

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/*  dv-nvram.c -- Generic driver for a non volatile ram (battery saved)
2
    Copyright (C) 1999, 2000, 2007, 2008, 2009, 2010
3
    Free Software Foundation, Inc.
4
    Written by Stephane Carrez (stcarrez@worldnet.fr)
5
    (From a driver model Contributed by Cygnus Solutions.)
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 3 of the License, or
10
    (at your option) any later version.
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 
20
    */
21
 
22
 
23
#include "sim-main.h"
24
#include "hw-main.h"
25
#include "sim-assert.h"
26
 
27
#include <unistd.h>
28
#include <fcntl.h>
29
#include <errno.h>
30
 
31
 
32
/* DEVICE
33
 
34
        nvram - Non Volatile Ram
35
 
36
 
37
   DESCRIPTION
38
 
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.
43
 
44
 
45
   PROPERTIES
46
 
47
   reg <base> <length>
48
 
49
        Base and size of the non-volatile ram bank.
50
 
51
   file <path>
52
 
53
        Path where the memory must be saved or loaded when we start.
54
 
55
   mode {map | save-modified | save-all}
56
 
57
        Controls how to load and save the memory content.
58
 
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).
66
 
67
 
68
   PORTS
69
 
70
        None.
71
 
72
 
73
   NOTES
74
 
75
        This device is independent of the Motorola 68hc11.
76
 
77
   */
78
 
79
 
80
 
81
/* static functions */
82
 
83
/* Control of how to access the ram and save its content.  */
84
 
85
enum nvram_mode
86
{
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,
91
 
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,
96
 
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
102
};
103
 
104
struct nvram
105
{
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.  */
112
};
113
 
114
 
115
 
116
/* Finish off the partially created hw device.  Attach our local
117
   callbacks.  Wire up our port names etc.  */
118
 
119
static hw_io_read_buffer_method  nvram_io_read_buffer;
120
static hw_io_write_buffer_method nvram_io_write_buffer;
121
 
122
 
123
 
124
static void
125
attach_nvram_regs (struct hw *me, struct nvram *controller)
126
{
127
  unsigned_word attach_address;
128
  int attach_space;
129
  unsigned attach_size;
130
  reg_property_spec reg;
131
  int result, oerrno;
132
 
133
  /* Get ram bank description (base and size).  */
134
  if (hw_find_property (me, "reg") == NULL)
135
    hw_abort (me, "Missing \"reg\" property");
136
 
137
  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
138
    hw_abort (me, "\"reg\" property must contain one addr/size entry");
139
 
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);
148
 
149
  hw_attach_address (hw_parent (me), 0,
150
                     attach_space, attach_address, attach_size,
151
                     me);
152
 
153
  controller->mode         = NVRAM_SAVE_ALL;
154
  controller->base_address = attach_address;
155
  controller->size         = attach_size;
156
  controller->fd           = -1;
157
 
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");
161
 
162
  controller->file_name = hw_find_string_property (me, "file");
163
 
164
  /* Get the mode which defines how to save the memory.  */
165
  if(hw_find_property (me, "mode") != NULL)
166
    {
167
      const char *value = hw_find_string_property (me, "mode");
168
 
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);
178
    }
179
 
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)
183
    {
184
    case NVRAM_MAP_FILE:
185
      hw_abort (me, "'map' mode is not yet implemented, use 'save-modified'");
186
      break;
187
 
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'");
193
 
194
      memset (controller->data, 0, attach_size);
195
      controller->fd = open (controller->file_name, O_RDWR);
196
      if (controller->fd < 0)
197
        {
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)
205
            {
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");
211
            }
212
        }
213
      else
214
        {
215
          result = read (controller->fd, controller->data, attach_size);
216
          if (result != attach_size)
217
            {
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");
223
            }
224
        }
225
      if (controller->mode == NVRAM_SAVE_ALL)
226
        {
227
          close (controller->fd);
228
          controller->fd = -1;
229
        }
230
      break;
231
 
232
    default:
233
      break;
234
    }
235
}
236
 
237
 
238
static void
239
nvram_finish (struct hw *me)
240
{
241
  struct nvram *controller;
242
 
243
  controller = HW_ZALLOC (me, struct nvram);
244
 
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);
248
 
249
  /* Attach ourself to our parent bus.  */
250
  attach_nvram_regs (me, controller);
251
}
252
 
253
 
254
 
255
/* generic read/write */
256
 
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)
263
{
264
  struct nvram *controller = hw_data (me);
265
 
266
  HW_TRACE ((me, "read 0x%08lx %d [%ld]",
267
             (long) base, (int) nr_bytes,
268
             (long) (base - controller->base_address)));
269
 
270
  base -= controller->base_address;
271
  if (base + nr_bytes > controller->size)
272
    nr_bytes = controller->size - base;
273
 
274
  memcpy (dest, &controller->data[base], nr_bytes);
275
  return nr_bytes;
276
}
277
 
278
 
279
 
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)
286
{
287
  struct nvram *controller = hw_data (me);
288
 
289
  HW_TRACE ((me, "write 0x%08lx %d [%ld]",
290
             (long) base, (int) nr_bytes,
291
             (long) (base - controller->base_address)));
292
 
293
  base -= controller->base_address;
294
  if (base + nr_bytes > controller->size)
295
    nr_bytes = controller->size - base;
296
 
297
  switch (controller->mode)
298
    {
299
    case NVRAM_SAVE_ALL:
300
      {
301
        int fd, result, oerrno;
302
 
303
        fd = open (controller->file_name, O_WRONLY, 0644);
304
        if (fd < 0)
305
          {
306
            return 0;
307
          }
308
 
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;
314
 
315
        if (result != controller->size)
316
          {
317
            return 0;
318
          }
319
        return nr_bytes;
320
      }
321
 
322
    case NVRAM_SAVE_MODIFIED:
323
      {
324
        off_t pos;
325
        int result;
326
 
327
        pos = lseek (controller->fd, (off_t) base, SEEK_SET);
328
        if (pos != (off_t) base)
329
          return 0;
330
 
331
        result = write (controller->fd, source, nr_bytes);
332
        if (result < 0)
333
          return 0;
334
 
335
        nr_bytes = result;
336
        break;
337
      }
338
 
339
    default:
340
      break;
341
    }
342
  memcpy (&controller->data[base], source, nr_bytes);
343
  return nr_bytes;
344
}
345
 
346
 
347
const struct hw_descriptor dv_nvram_descriptor[] = {
348
  { "nvram", nvram_finish, },
349
  { NULL },
350
};
351
 

powered by: WebSVN 2.1.0

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