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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [or1ksim/] [peripheral/] [generic.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1745 jeremybenn
/* generic.c -- Generic external peripheral
2
 
3
   Copyright (C) 2008 Embecosm Limited
4
 
5
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
6
 
7
   This file is part of OpenRISC 1000 Architectural Simulator.
8
 
9
   This program is free software; you can redistribute it and/or modify it
10
   under the terms of the GNU General Public License as published by the Free
11
   Software Foundation; either version 3 of the License, or (at your option)
12
   any later version.
13
 
14
   This program is distributed in the hope that it will be useful, but WITHOUT
15
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17
   more details.
18
 
19
   You should have received a copy of the GNU General Public License along
20
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
21
 
22 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
23
   with Doxygen. */
24 1745 jeremybenn
 
25 1756 jeremybenn
 
26 1745 jeremybenn
/* This is functional simulation of any external peripheral. It's job is to
27
 * trap accesses in a specific range, so that the simulator can drive an
28
 * external device.
29 1756 jeremybenn
 *
30
 * A note on endianess. All external communication is done using HOST
31
 * endianess. A set of functions are provided to convert between host and
32
 * model endianess (htoml, htoms, mtohl, mtohs).
33 1745 jeremybenn
 */
34
 
35 1748 jeremybenn
/* Autoconf and/or portability configuration */
36
#include "config.h"
37
 
38
/* System includes */
39 1745 jeremybenn
#include <stdlib.h>
40
#include <stdio.h>
41
 
42 1748 jeremybenn
/* Package includes */
43 1745 jeremybenn
#include "arch.h"
44 1748 jeremybenn
#include "sim-config.h"
45 1745 jeremybenn
#include "abstract.h"
46 1748 jeremybenn
#include "toplevel-support.h"
47
#include "sim-cmd.h"
48 1745 jeremybenn
 
49
 
50 1748 jeremybenn
/*! State associated with the generic device. */
51
struct dev_generic
52
{
53 1745 jeremybenn
 
54 1748 jeremybenn
  /* Info about a particular transaction */
55 1745 jeremybenn
 
56 1748 jeremybenn
  enum
57
  {                             /* Direction of the access */
58
    GENERIC_READ,
59
    GENERIC_WRITE
60
  } trans_direction;
61 1745 jeremybenn
 
62 1748 jeremybenn
  enum
63
  {                             /* Size of the access */
64
    GENERIC_BYTE,
65
    GENERIC_HW,
66
    GENERIC_WORD
67
  } trans_size;
68
 
69
  uint32_t value;               /* The value to read/write */
70
 
71
  /* Configuration */
72
 
73
  int enabled;                  /* Device enabled */
74
  int byte_enabled;             /* Byte R/W allowed */
75
  int hw_enabled;               /* Half word R/W allowed */
76
  int word_enabled;             /* Full word R/W allowed */
77
  char *name;                   /* Name of the device */
78
  oraddr_t baseaddr;            /* Base address of device */
79
  uint32_t size;                /* Address space size (bytes) */
80
 
81
};
82
 
83
 
84 1756 jeremybenn
/* Convert a 32-bit value from host to model endianess */
85
static unsigned long int
86
htoml (unsigned long int  host_val)
87
{
88
  unsigned char  model_array[4];
89
 
90
#ifdef OR32_BIG_ENDIAN
91
  model_array[0] = (host_val >> 24) & 0xff;
92
  model_array[1] = (host_val >> 16) & 0xff;
93
  model_array[2] = (host_val >>  8) & 0xff;
94
  model_array[3] = (host_val      ) & 0xff;
95
#else
96
  model_array[0] = (host_val      ) & 0xff;
97
  model_array[1] = (host_val >>  8) & 0xff;
98
  model_array[2] = (host_val >> 16) & 0xff;
99
  model_array[3] = (host_val >> 24) & 0xff;
100
#endif
101
 
102
  return *((unsigned long int *)model_array);
103
 
104
}       /* htoml () */
105
 
106
 
107
/* Convert a 16-bit value from host to model endianess */
108
static unsigned short int
109
htoms (unsigned short int  host_val)
110
{
111
  unsigned char  model_array[2];
112
 
113
#ifdef OR32_BIG_ENDIAN
114
  model_array[0] = (host_val >>  8) & 0xff;
115
  model_array[1] = (host_val      ) & 0xff;
116
#else
117
  model_array[0] = (host_val      ) & 0xff;
118
  model_array[1] = (host_val >>  8) & 0xff;
119
#endif
120
 
121
  return *((unsigned short int *)model_array);
122
 
123
}       /* htoms () */
124
 
125
 
126
/* Convert a 32-bit value from model to host endianess */
127
static unsigned long int
128
mtohl (unsigned long int  model_val)
129
{
130
  unsigned char     *model_array = (unsigned char *)(&model_val);
131
  unsigned long int  host_val;
132
 
133
#ifdef OR32_BIG_ENDIAN
134
  host_val =                   model_array[0];
135
  host_val = (host_val << 8) | model_array[1];
136
  host_val = (host_val << 8) | model_array[2];
137
  host_val = (host_val << 8) | model_array[3];
138
#else
139
  host_val =                   model_array[3];
140
  host_val = (host_val << 8) | model_array[2];
141
  host_val = (host_val << 8) | model_array[1];
142
  host_val = (host_val << 8) | model_array[0];
143
#endif
144
 
145
  return  host_val;
146
 
147
}       /* mtohl () */
148
 
149
 
150
/* Convert a 32-bit value from model to host endianess */
151
static unsigned short int
152
mtohs (unsigned short int  model_val)
153
{
154
  unsigned char      *model_array = (unsigned char *)(&model_val);
155
  unsigned short int  host_val;
156
 
157
#ifdef OR32_BIG_ENDIAN
158
  host_val =                   model_array[0];
159
  host_val = (host_val << 8) | model_array[1];
160
#else
161
  host_val =                   model_array[1];
162
  host_val = (host_val << 8) | model_array[0];
163
#endif
164
 
165
  return  host_val;
166
 
167
}       /* mtohs () */
168
 
169
 
170 1745 jeremybenn
/* Generic read and write upcall routines. Note the address here is absolute,
171 1756 jeremybenn
   not relative to the device. The mask uses host endianess, not Or1ksim
172
   endianess. */
173 1745 jeremybenn
 
174 1748 jeremybenn
static unsigned long int
175 1756 jeremybenn
ext_read (unsigned long int  addr,
176
          unsigned long int  mask)
177 1745 jeremybenn
{
178 1748 jeremybenn
  return config.ext.read_up (config.ext.class_ptr, addr, mask);
179 1745 jeremybenn
 
180 1748 jeremybenn
}                               /* ext_callback() */
181 1745 jeremybenn
 
182
 
183
/* Generic read and write upcall routines. Note the address here is absolute,
184 1756 jeremybenn
   not relative to the device. The mask and value use host endianess, not
185
   Or1ksim endianess. */
186 1745 jeremybenn
 
187 1748 jeremybenn
static void
188 1756 jeremybenn
ext_write (unsigned long int  addr,
189
           unsigned long int  mask,
190
           unsigned long int  value)
191 1745 jeremybenn
{
192 1748 jeremybenn
  config.ext.write_up (config.ext.class_ptr, addr, mask, value);
193 1745 jeremybenn
 
194 1748 jeremybenn
}                               /* ext_callback() */
195 1745 jeremybenn
 
196 1748 jeremybenn
 
197 1745 jeremybenn
/* I/O routines. Note that address is relative to start of address space. */
198
 
199 1748 jeremybenn
static uint8_t
200
generic_read_byte (oraddr_t addr, void *dat)
201 1745 jeremybenn
{
202 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
203 1745 jeremybenn
 
204 1748 jeremybenn
  if (!config.ext.class_ptr)
205
    {
206
      fprintf (stderr, "Byte read from disabled generic device\n");
207
      return 0;
208
    }
209
  else if (addr >= dev->size)
210
    {
211
      fprintf (stderr, "Byte read  out of range for generic device %s "
212
               "(addr %" PRIxADDR ")\n", dev->name, addr);
213
      return 0;
214
    }
215
  else
216
    {
217 1756 jeremybenn
      unsigned long  fulladdr = (unsigned long int) (addr + dev->baseaddr);
218
      unsigned long  wordaddr = fulladdr & 0xfffffffc;
219
      unsigned long  bytenum  = fulladdr & 0x00000003;
220 1745 jeremybenn
 
221 1756 jeremybenn
      uint8_t        mask_array[4];
222
      unsigned long  res;
223
      uint8_t       *res_array;
224 1745 jeremybenn
 
225 1756 jeremybenn
      /* This works whatever the host endianess */
226
      memset (mask_array, 0, 4);
227
      mask_array[bytenum] = 0xff;
228 1745 jeremybenn
 
229 1756 jeremybenn
      res       = ext_read (wordaddr, *((unsigned int *)mask_array));
230
      res_array = (uint8_t *)(&res);
231
 
232
      return  res_array[bytenum];
233 1748 jeremybenn
    }
234
}                               /* generic_read_byte() */
235 1745 jeremybenn
 
236
 
237 1748 jeremybenn
static void
238
generic_write_byte (oraddr_t addr, uint8_t value, void *dat)
239 1745 jeremybenn
{
240 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
241 1745 jeremybenn
 
242 1748 jeremybenn
  if (!config.ext.class_ptr)
243
    {
244
      fprintf (stderr, "Byte write to disabled generic device\n");
245
    }
246
  else if (addr >= dev->size)
247
    {
248
      fprintf (stderr, "Byte written out of range for generic device %s "
249
               "(addr %" PRIxADDR ")\n", dev->name, addr);
250
    }
251
  else
252
    {
253 1756 jeremybenn
      unsigned long  fulladdr = (unsigned long int) (addr + dev->baseaddr);
254
      unsigned long  wordaddr = fulladdr & 0xfffffffc;
255 1745 jeremybenn
 
256 1756 jeremybenn
      unsigned long  bytenum  = fulladdr & 0x00000003;
257
      uint8_t        mask_array[4];
258
      uint8_t        value_array[4];
259 1745 jeremybenn
 
260 1756 jeremybenn
      /* This works whatever the host endianess */
261
      memset (mask_array, 0, 4);
262
      mask_array[bytenum] = 0xff;
263
      memset (value_array, 0, 4);
264
      value_array[bytenum] = value;
265
 
266
      ext_write (wordaddr, *((unsigned long int *)mask_array),
267
                 *((unsigned long int *)value_array));
268 1748 jeremybenn
    }
269
}                               /* generic_write_byte() */
270 1745 jeremybenn
 
271
 
272 1756 jeremybenn
/* Result is in model endianess */
273 1748 jeremybenn
static uint16_t
274
generic_read_hw (oraddr_t addr, void *dat)
275 1745 jeremybenn
{
276 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
277 1745 jeremybenn
 
278 1748 jeremybenn
  if (!config.ext.class_ptr)
279
    {
280
      fprintf (stderr, "Half word read from disabled generic device\n");
281
      return 0;
282
    }
283
  else if (addr >= dev->size)
284
    {
285
      fprintf (stderr, "Half-word read  out of range for generic device %s "
286
               "(addr %" PRIxADDR ")\n", dev->name, addr);
287
      return 0;
288
    }
289
  else if (addr & 0x1)
290
    {
291
      fprintf (stderr,
292
               "Unaligned half word read from 0x%" PRIxADDR " ignored\n",
293
               addr);
294
      return 0;
295
    }
296
  else
297
    {
298 1756 jeremybenn
      unsigned long   fulladdr = (unsigned long int) (addr + dev->baseaddr);
299
      unsigned long   wordaddr = fulladdr & 0xfffffffc;
300
      unsigned long   bytenum  = fulladdr & 0x00000002;
301 1745 jeremybenn
 
302 1756 jeremybenn
      uint8_t         mask_array[4];
303
      unsigned long   res;
304
      uint8_t        *res_array;
305
      uint8_t         hwres_array[2];
306 1745 jeremybenn
 
307 1756 jeremybenn
      /* This works whatever the host endianess */
308
      memset (mask_array, 0, 4);
309
      mask_array[bytenum]     = 0xff;
310
      mask_array[bytenum + 1] = 0xff;
311 1745 jeremybenn
 
312 1756 jeremybenn
      res       = ext_read (wordaddr, *((unsigned int *)mask_array));
313
      res_array = (uint8_t *)(&res);
314
 
315
      hwres_array[0] = res_array[bytenum];
316
      hwres_array[1] = res_array[bytenum + 1];
317
 
318
      return htoms (*((uint16_t *)hwres_array));
319 1748 jeremybenn
    }
320
}                               /* generic_read_hw() */
321 1745 jeremybenn
 
322
 
323 1756 jeremybenn
/* Value is in model endianness */
324 1748 jeremybenn
static void
325
generic_write_hw (oraddr_t addr, uint16_t value, void *dat)
326 1745 jeremybenn
{
327 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
328 1745 jeremybenn
 
329 1748 jeremybenn
  if (!config.ext.class_ptr)
330
    {
331
      fprintf (stderr, "Half word write to disabled generic device\n");
332
    }
333
  else if (addr >= dev->size)
334
    {
335
      fprintf (stderr, "Half-word written  out of range for generic device %s "
336
               "(addr %" PRIxADDR ")\n", dev->name, addr);
337
    }
338
  else if (addr & 0x1)
339
    {
340
      fprintf (stderr,
341
               "Unaligned half word write to 0x%" PRIxADDR " ignored\n", addr);
342
    }
343
  else
344
    {
345 1756 jeremybenn
      uint16_t       host_value = mtohs (value);
346 1745 jeremybenn
 
347 1756 jeremybenn
      unsigned long  fulladdr = (unsigned long int) (addr + dev->baseaddr);
348
      unsigned long  wordaddr = fulladdr & 0xfffffffc;
349
      unsigned long  bytenum  = fulladdr & 0x00000002;
350 1745 jeremybenn
 
351 1756 jeremybenn
      uint8_t        mask_array[4];
352
      uint8_t        value_array[4];
353
      uint8_t       *hw_value_array;
354
 
355
      /* This works whatever the host endianess */
356
      memset (mask_array, 0, 4);
357
      mask_array[bytenum]     = 0xff;
358
      mask_array[bytenum + 1] = 0xff;
359
 
360
      memset (value_array, 0, 4);
361
      hw_value_array           = (uint8_t *)(&host_value);
362
      value_array[bytenum]     = hw_value_array[0];
363
      value_array[bytenum + 1] = hw_value_array[1];
364
 
365
      ext_write (wordaddr, *((unsigned long int *)mask_array),
366
                 *((unsigned long int *)value_array));
367 1748 jeremybenn
    }
368
}                               /* generic_write_hw() */
369 1745 jeremybenn
 
370
 
371 1748 jeremybenn
static uint32_t
372
generic_read_word (oraddr_t addr, void *dat)
373 1745 jeremybenn
{
374 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
375 1745 jeremybenn
 
376 1748 jeremybenn
  if (!config.ext.class_ptr)
377
    {
378
      fprintf (stderr, "Full word read from disabled generic device\n");
379
      return 0;
380
    }
381
  else if (addr >= dev->size)
382
    {
383
      fprintf (stderr, "Full word read  out of range for generic device %s "
384
               "(addr %" PRIxADDR ")\n", dev->name, addr);
385
      return 0;
386
    }
387
  else if (0 != (addr & 0x3))
388
    {
389
      fprintf (stderr,
390
               "Unaligned full word read from 0x%" PRIxADDR " ignored\n",
391
               addr);
392
      return 0;
393
    }
394
  else
395
    {
396
      unsigned long wordaddr = (unsigned long int) (addr + dev->baseaddr);
397 1745 jeremybenn
 
398 1756 jeremybenn
      return (uint32_t) htoml (ext_read (wordaddr, 0xffffffff));
399 1748 jeremybenn
    }
400
}                               /* generic_read_word() */
401 1745 jeremybenn
 
402
 
403 1748 jeremybenn
static void
404
generic_write_word (oraddr_t addr, uint32_t value, void *dat)
405 1745 jeremybenn
{
406 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
407 1745 jeremybenn
 
408 1748 jeremybenn
  if (!config.ext.class_ptr)
409
    {
410
      fprintf (stderr, "Full word write to disabled generic device\n");
411
    }
412
  else if (addr >= dev->size)
413
    {
414
      fprintf (stderr, "Full word written  out of range for generic device %s "
415
               "(addr %" PRIxADDR ")\n", dev->name, addr);
416
    }
417
  else if (0 != (addr & 0x3))
418
    {
419
      fprintf (stderr,
420
               "Unaligned full word write to 0x%" PRIxADDR " ignored\n", addr);
421
    }
422
  else
423
    {
424 1756 jeremybenn
      unsigned long host_value = mtohl (value);
425
      unsigned long wordaddr   = (unsigned long int) (addr + dev->baseaddr);
426 1745 jeremybenn
 
427 1756 jeremybenn
      ext_write (wordaddr, 0xffffffff, host_value);
428 1748 jeremybenn
    }
429
}                               /* generic_write_word() */
430 1745 jeremybenn
 
431
 
432
/* Reset is a null operation */
433
 
434 1748 jeremybenn
static void
435
generic_reset (void *dat)
436 1745 jeremybenn
{
437
  return;
438
 
439 1748 jeremybenn
}                               /* generic_reset() */
440 1745 jeremybenn
 
441
 
442
/* Status report can only advise of configuration. */
443
 
444 1748 jeremybenn
static void
445
generic_status (void *dat)
446 1745 jeremybenn
{
447 1748 jeremybenn
  struct dev_generic *dev = (struct dev_generic *) dat;
448 1745 jeremybenn
 
449 1748 jeremybenn
  PRINTF ("\nGeneric device \"%s\" at 0x%" PRIxADDR ":\n", dev->name,
450
          dev->baseaddr);
451
  PRINTF ("  Size 0x%" PRIx32 "\n", dev->size);
452 1745 jeremybenn
 
453 1748 jeremybenn
  if (dev->byte_enabled)
454
    {
455
      PRINTF ("  Byte R/W enabled\n");
456
    }
457 1745 jeremybenn
 
458 1748 jeremybenn
  if (dev->hw_enabled)
459
    {
460
      PRINTF ("  Half word R/W enabled\n");
461
    }
462 1745 jeremybenn
 
463 1748 jeremybenn
  if (dev->word_enabled)
464
    {
465
      PRINTF ("  Full word R/W enabled\n");
466
    }
467 1745 jeremybenn
 
468 1748 jeremybenn
  PRINTF ("\n");
469 1745 jeremybenn
 
470 1748 jeremybenn
}                               /* generic_status() */
471 1745 jeremybenn
 
472
 
473
/* Functions to set configuration */
474
 
475 1748 jeremybenn
static void
476
generic_enabled (union param_val val, void *dat)
477 1745 jeremybenn
{
478 1748 jeremybenn
  ((struct dev_generic *) dat)->enabled = val.int_val;
479 1745 jeremybenn
 
480 1748 jeremybenn
}                               /* generic_enabled() */
481 1745 jeremybenn
 
482
 
483 1748 jeremybenn
static void
484
generic_byte_enabled (union param_val val, void *dat)
485 1745 jeremybenn
{
486 1748 jeremybenn
  ((struct dev_generic *) dat)->byte_enabled = val.int_val;
487 1745 jeremybenn
 
488 1748 jeremybenn
}                               /* generic_byte_enabled() */
489 1745 jeremybenn
 
490
 
491 1748 jeremybenn
static void
492
generic_hw_enabled (union param_val val, void *dat)
493 1745 jeremybenn
{
494 1748 jeremybenn
  ((struct dev_generic *) dat)->hw_enabled = val.int_val;
495 1745 jeremybenn
 
496 1748 jeremybenn
}                               /* generic_hw_enabled() */
497 1745 jeremybenn
 
498
 
499 1748 jeremybenn
static void
500
generic_word_enabled (union param_val val, void *dat)
501 1745 jeremybenn
{
502 1748 jeremybenn
  ((struct dev_generic *) dat)->word_enabled = val.int_val;
503 1745 jeremybenn
 
504 1748 jeremybenn
}                               /* generic_word_enabled() */
505 1745 jeremybenn
 
506
 
507 1748 jeremybenn
static void
508
generic_name (union param_val val, void *dat)
509 1745 jeremybenn
{
510 1748 jeremybenn
  ((struct dev_generic *) dat)->name = strdup (val.str_val);
511 1745 jeremybenn
 
512 1748 jeremybenn
  if (!((struct dev_generic *) dat)->name)
513
    {
514
      fprintf (stderr, "Peripheral 16450: name \"%s\": Run out of memory\n",
515
               val.str_val);
516
      exit (-1);
517
    }
518
}                               /* generic_name() */
519 1745 jeremybenn
 
520
 
521 1748 jeremybenn
static void
522
generic_baseaddr (union param_val val, void *dat)
523 1745 jeremybenn
{
524 1748 jeremybenn
  ((struct dev_generic *) dat)->baseaddr = val.addr_val;
525 1745 jeremybenn
 
526 1748 jeremybenn
}                               /* generic_baseaddr() */
527 1745 jeremybenn
 
528
 
529 1748 jeremybenn
static void
530
generic_size (union param_val val, void *dat)
531 1745 jeremybenn
{
532 1748 jeremybenn
  ((struct dev_generic *) dat)->size = val.int_val;
533 1745 jeremybenn
 
534 1748 jeremybenn
}                               /* generic_size() */
535 1745 jeremybenn
 
536
 
537
/* Start of new generic section */
538
 
539 1748 jeremybenn
static void *
540
generic_sec_start ()
541 1745 jeremybenn
{
542
  struct dev_generic *new =
543 1748 jeremybenn
    (struct dev_generic *) malloc (sizeof (struct dev_generic));
544 1745 jeremybenn
 
545 1748 jeremybenn
  if (0 == new)
546
    {
547
      fprintf (stderr, "Generic peripheral: Run out of memory\n");
548
      exit (-1);
549
    }
550 1745 jeremybenn
 
551
  /* Default names */
552
 
553 1748 jeremybenn
  new->enabled = 1;
554 1745 jeremybenn
  new->byte_enabled = 1;
555 1748 jeremybenn
  new->hw_enabled = 1;
556 1745 jeremybenn
  new->word_enabled = 1;
557 1748 jeremybenn
  new->name = "anonymous external peripheral";
558
  new->baseaddr = 0;
559
  new->size = 0;
560 1745 jeremybenn
 
561 1748 jeremybenn
  return new;
562 1745 jeremybenn
 
563 1748 jeremybenn
}                               /* generic_sec_start() */
564 1745 jeremybenn
 
565
 
566
/* End of new generic section */
567
 
568 1748 jeremybenn
static void
569
generic_sec_end (void *dat)
570 1745 jeremybenn
{
571 1748 jeremybenn
  struct dev_generic *generic = (struct dev_generic *) dat;
572
  struct mem_ops ops;
573 1745 jeremybenn
 
574
  /* Give up if not enabled, or if size is zero, or if no access size is
575
     enabled. */
576
 
577 1748 jeremybenn
  if (!generic->enabled)
578
    {
579
      free (dat);
580
      return;
581
    }
582 1745 jeremybenn
 
583 1748 jeremybenn
  if (0 == generic->size)
584
    {
585
      fprintf (stderr, "Generic peripheral \"%s\" has size 0: ignoring",
586
               generic->name);
587
      free (dat);
588
      return;
589
    }
590 1745 jeremybenn
 
591 1748 jeremybenn
  if (!generic->byte_enabled &&
592
      !generic->hw_enabled && !generic->word_enabled)
593
    {
594
      fprintf (stderr, "Generic peripheral \"%s\" has no access: ignoring",
595
               generic->name);
596
      free (dat);
597
      return;
598
    }
599 1745 jeremybenn
 
600
  /* Zero all the ops, then set the ones we care about. Read/write delays will
601
   * come from the peripheral if desired.
602
   */
603
 
604 1748 jeremybenn
  memset (&ops, 0, sizeof (struct mem_ops));
605 1745 jeremybenn
 
606 1748 jeremybenn
  if (generic->byte_enabled)
607
    {
608
      ops.readfunc8 = generic_read_byte;
609
      ops.writefunc8 = generic_write_byte;
610
      ops.read_dat8 = dat;
611
      ops.write_dat8 = dat;
612
    }
613 1745 jeremybenn
 
614 1748 jeremybenn
  if (generic->hw_enabled)
615
    {
616
      ops.readfunc16 = generic_read_hw;
617
      ops.writefunc16 = generic_write_hw;
618
      ops.read_dat16 = dat;
619
      ops.write_dat16 = dat;
620
    }
621 1745 jeremybenn
 
622 1748 jeremybenn
  if (generic->word_enabled)
623
    {
624
      ops.readfunc32 = generic_read_word;
625
      ops.writefunc32 = generic_write_word;
626
      ops.read_dat32 = dat;
627
      ops.write_dat32 = dat;
628
    }
629 1745 jeremybenn
 
630
  /* Register everything */
631
 
632 1748 jeremybenn
  reg_mem_area (generic->baseaddr, generic->size, 0, &ops);
633 1745 jeremybenn
 
634 1748 jeremybenn
  reg_sim_reset (generic_reset, dat);
635
  reg_sim_stat (generic_status, dat);
636 1745 jeremybenn
 
637 1748 jeremybenn
}                               /* generic_sec_end() */
638 1745 jeremybenn
 
639
 
640
/* Register a generic section. */
641
 
642 1748 jeremybenn
void
643
reg_generic_sec (void)
644 1745 jeremybenn
{
645 1748 jeremybenn
  struct config_section *sec = reg_config_sec ("generic",
646 1745 jeremybenn
                                               generic_sec_start,
647 1748 jeremybenn
                                               generic_sec_end);
648 1745 jeremybenn
 
649 1748 jeremybenn
  reg_config_param (sec, "enabled", paramt_int, generic_enabled);
650
  reg_config_param (sec, "byte_enabled", paramt_int, generic_byte_enabled);
651
  reg_config_param (sec, "hw_enabled", paramt_int, generic_hw_enabled);
652
  reg_config_param (sec, "word_enabled", paramt_int, generic_word_enabled);
653
  reg_config_param (sec, "name", paramt_str, generic_name);
654
  reg_config_param (sec, "baseaddr", paramt_addr, generic_baseaddr);
655
  reg_config_param (sec, "size", paramt_int, generic_size);
656 1745 jeremybenn
 
657 1748 jeremybenn
}                               /* reg_generic_sec */

powered by: WebSVN 2.1.0

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