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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [common/] [hw-properties.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program psim.
2
 
3
    Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
 
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.
9
 
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.
14
 
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.
18
 
19
    */
20
 
21
#include "hw-main.h"
22
#include "hw-base.h"
23
 
24
#include "sim-io.h"
25
#include "sim-assert.h"
26
 
27
#ifdef HAVE_STRING_H
28
#include <string.h>
29
#else
30
#ifdef HAVE_STRINGS_H
31
#include <strings.h>
32
#endif
33
#endif
34
 
35
#define TRACE(A,B)
36
 
37
/* property entries */
38
 
39
struct hw_property_data {
40
  struct hw_property_data *next;
41
  struct hw_property *property;
42
  const void *init_array;
43
  unsigned sizeof_init_array;
44
};
45
 
46
void
47
create_hw_property_data (struct hw *me)
48
{
49
}
50
 
51
void
52
delete_hw_property_data (struct hw *me)
53
{
54
}
55
 
56
 
57
/* Device Properties: */
58
 
59
static struct hw_property_data *
60
find_property_data (struct hw *me,
61
                    const char *property)
62
{
63
  struct hw_property_data *entry;
64
  ASSERT (property != NULL);
65
  entry = me->properties_of_hw;
66
  while (entry != NULL)
67
    {
68
      if (strcmp (entry->property->name, property) == 0)
69
        return entry;
70
      entry = entry->next;
71
    }
72
  return NULL;
73
}
74
 
75
 
76
static void
77
hw_add_property (struct hw *me,
78
                 const char *property,
79
                 hw_property_type type,
80
                 const void *init_array,
81
                 unsigned sizeof_init_array,
82
                 const void *array,
83
                 unsigned sizeof_array,
84
                 const struct hw_property *original,
85
                 object_disposition disposition)
86
{
87
  struct hw_property_data *new_entry = NULL;
88
  struct hw_property *new_value = NULL;
89
 
90
  /* find the list end */
91
  struct hw_property_data **insertion_point = &me->properties_of_hw;
92
  while (*insertion_point != NULL)
93
    {
94
      if (strcmp ((*insertion_point)->property->name, property) == 0)
95
        return;
96
      insertion_point = &(*insertion_point)->next;
97
    }
98
 
99
  /* create a new value */
100
  new_value = HW_ZALLOC (me, struct hw_property);
101
  new_value->name = (char *) strdup (property);
102
  new_value->type = type;
103
  if (sizeof_array > 0)
104
    {
105
      void *new_array = hw_zalloc (me, sizeof_array);
106
      memcpy (new_array, array, sizeof_array);
107
      new_value->array = new_array;
108
      new_value->sizeof_array = sizeof_array;
109
    }
110
  new_value->owner = me;
111
  new_value->original = original;
112
  new_value->disposition = disposition;
113
 
114
  /* insert the value into the list */
115
  new_entry = HW_ZALLOC (me, struct hw_property_data);
116
  *insertion_point = new_entry;
117
  if (sizeof_init_array > 0)
118
    {
119
      void *new_init_array = hw_zalloc (me, sizeof_init_array);
120
      memcpy (new_init_array, init_array, sizeof_init_array);
121
      new_entry->init_array = new_init_array;
122
      new_entry->sizeof_init_array = sizeof_init_array;
123
    }
124
  new_entry->property = new_value;
125
}
126
 
127
 
128
static void
129
hw_set_property (struct hw *me,
130
                 const char *property,
131
                 hw_property_type type,
132
                 const void *array,
133
                 int sizeof_array)
134
{
135
  /* find the property */
136
  struct hw_property_data *entry = find_property_data (me, property);
137
  if (entry != NULL)
138
    {
139
      /* existing property - update it */
140
      void *new_array = 0;
141
      struct hw_property *value = entry->property;
142
      /* check the type matches */
143
      if (value->type != type)
144
        hw_abort (me, "conflict between type of new and old value for property %s", property);
145
      /* replace its value */
146
      if (value->array != NULL)
147
        hw_free (me, (void*)value->array);
148
      new_array = (sizeof_array > 0
149
                   ? hw_zalloc (me, sizeof_array)
150
                   : (void*)0);
151
      value->array = new_array;
152
      value->sizeof_array = sizeof_array;
153
      if (sizeof_array > 0)
154
        memcpy (new_array, array, sizeof_array);
155
      return;
156
    }
157
  else
158
    {
159
      /* new property - create it */
160
      hw_add_property (me, property, type,
161
                       NULL, 0, array, sizeof_array,
162
                       NULL, temporary_object);
163
    }
164
}
165
 
166
 
167
#if 0
168
static void
169
clean_hw_properties (struct hw *me)
170
{
171
  struct hw_property_data **delete_point = &me->properties_of_hw;
172
  while (*delete_point != NULL)
173
    {
174
      struct hw_property_data *current = *delete_point;
175
      switch (current->property->disposition)
176
        {
177
        case permenant_object:
178
          /* zap the current value, will be initialized later */
179
          ASSERT (current->init_array != NULL);
180
          if (current->property->array != NULL)
181
            {
182
              hw_free (me, (void*)current->property->array);
183
              current->property->array = NULL;
184
            }
185
          delete_point = &(*delete_point)->next;
186
          break;
187
        case temporary_object:
188
          /* zap the actual property, was created during simulation run */
189
          ASSERT (current->init_array == NULL);
190
          *delete_point = current->next;
191
          if (current->property->array != NULL)
192
            hw_free (me, (void*)current->property->array);
193
          hw_free (me, current->property);
194
          hw_free (me, current);
195
          break;
196
        }
197
    }
198
}
199
#endif
200
 
201
#if 0
202
void
203
hw_init_static_properties (SIM_DESC sd,
204
                           struct hw *me,
205
                           void *data)
206
{
207
  struct hw_property_data *property;
208
  for (property = me->properties_of_hw;
209
       property != NULL;
210
       property = property->next)
211
    {
212
      ASSERT (property->init_array != NULL);
213
      ASSERT (property->property->array == NULL);
214
      ASSERT(property->property->disposition == permenant_object);
215
      switch (property->property->type)
216
        {
217
        case array_property:
218
        case boolean_property:
219
        case range_array_property:
220
        case reg_array_property:
221
        case string_property:
222
        case string_array_property:
223
        case integer_property:
224
          /* delete the property, and replace it with the original */
225
          hw_set_property (me, property->property->name,
226
                           property->property->type,
227
                           property->init_array,
228
                           property->sizeof_init_array);
229
          break;
230
#if 0
231
        case ihandle_property:
232
          break;
233
#endif
234
        }
235
    }
236
}
237
#endif
238
 
239
 
240
#if 0
241
void
242
hw_init_runtime_properties (SIM_DESC sd,
243
                            struct hw *me,
244
                            void *data)
245
{
246
  struct hw_property_data *property;
247
  for (property = me->properties_of_hw;
248
       property != NULL;
249
       property = property->next)
250
    {
251
      switch (property->property->disposition)
252
        {
253
        case permenant_object:
254
          switch (property->property->type)
255
            {
256
#if 0
257
            case ihandle_property:
258
              {
259
                struct hw_instance *ihandle;
260
                ihandle_runtime_property_spec spec;
261
                ASSERT (property->init_array != NULL);
262
                ASSERT (property->property->array == NULL);
263
                hw_find_ihandle_runtime_property (me, property->property->name, &spec);
264
                ihandle = tree_instance (me, spec.full_path);
265
                hw_set_ihandle_property (me, property->property->name, ihandle);
266
                break;
267
              }
268
#endif
269
            case array_property:
270
            case boolean_property:
271
            case range_array_property:
272
            case integer_property:
273
            case reg_array_property:
274
            case string_property:
275
            case string_array_property:
276
              ASSERT (property->init_array != NULL);
277
              ASSERT (property->property->array != NULL);
278
              break;
279
            }
280
          break;
281
        case temporary_object:
282
          ASSERT (property->init_array == NULL);
283
          ASSERT (property->property->array != NULL);
284
          break;
285
        }
286
    }
287
}
288
#endif
289
 
290
 
291
 
292
const struct hw_property *
293
hw_next_property (const struct hw_property *property)
294
{
295
  /* find the property in the list */
296
  struct hw *owner = property->owner;
297
  struct hw_property_data *entry = owner->properties_of_hw;
298
  while (entry != NULL && entry->property != property)
299
    entry = entry->next;
300
  /* now return the following property */
301
  ASSERT (entry != NULL); /* must be a member! */
302
  if (entry->next != NULL)
303
    return entry->next->property;
304
  else
305
    return NULL;
306
}
307
 
308
 
309
const struct hw_property *
310
hw_find_property (struct hw *me,
311
                  const char *property)
312
{
313
  if (me == NULL)
314
    {
315
      return NULL;
316
    }
317
  else if (property == NULL || strcmp (property, "") == 0)
318
    {
319
      if (me->properties_of_hw == NULL)
320
        return NULL;
321
      else
322
        return me->properties_of_hw->property;
323
    }
324
  else
325
    {
326
      struct hw_property_data *entry = find_property_data (me, property);
327
      if (entry != NULL)
328
        return entry->property;
329
    }
330
  return NULL;
331
}
332
 
333
 
334
void
335
hw_add_array_property (struct hw *me,
336
                       const char *property,
337
                       const void *array,
338
                       int sizeof_array)
339
{
340
  hw_add_property (me, property, array_property,
341
                   array, sizeof_array, array, sizeof_array,
342
                   NULL, permenant_object);
343
}
344
 
345
void
346
hw_set_array_property (struct hw *me,
347
                       const char *property,
348
                       const void *array,
349
                       int sizeof_array)
350
{
351
  hw_set_property (me, property, array_property, array, sizeof_array);
352
}
353
 
354
const struct hw_property *
355
hw_find_array_property (struct hw *me,
356
                        const char *property)
357
{
358
  const struct hw_property *node;
359
  node = hw_find_property (me, property);
360
  if (node == NULL)
361
    hw_abort (me, "property \"%s\" not found", property);
362
  if (node->type != array_property)
363
    hw_abort (me, "property \"%s\" of wrong type (array)", property);
364
  return node;
365
}
366
 
367
 
368
 
369
void
370
hw_add_boolean_property (struct hw *me,
371
                         const char *property,
372
                         int boolean)
373
{
374
  signed32 new_boolean = (boolean ? -1 : 0);
375
  hw_add_property (me, property, boolean_property,
376
                   &new_boolean, sizeof(new_boolean),
377
                   &new_boolean, sizeof(new_boolean),
378
                   NULL, permenant_object);
379
}
380
 
381
int
382
hw_find_boolean_property (struct hw *me,
383
                          const char *property)
384
{
385
  const struct hw_property *node;
386
  unsigned_cell boolean;
387
  node = hw_find_property (me, property);
388
  if (node == NULL)
389
    hw_abort (me, "property \"%s\" not found", property);
390
  if (node->type != boolean_property)
391
    hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
392
  ASSERT (sizeof (boolean) == node->sizeof_array);
393
  memcpy (&boolean, node->array, sizeof (boolean));
394
  return boolean;
395
}
396
 
397
 
398
 
399
#if 0
400
void
401
hw_add_ihandle_runtime_property (struct hw *me,
402
                                 const char *property,
403
                                 const ihandle_runtime_property_spec *ihandle)
404
{
405
  /* enter the full path as the init array */
406
  hw_add_property (me, property, ihandle_property,
407
                   ihandle->full_path, strlen(ihandle->full_path) + 1,
408
                   NULL, 0,
409
                   NULL, permenant_object);
410
}
411
#endif
412
 
413
#if 0
414
void
415
hw_find_ihandle_runtime_property (struct hw *me,
416
                                  const char *property,
417
                                  ihandle_runtime_property_spec *ihandle)
418
{
419
  struct hw_property_data *entry = find_property_data (me, property);
420
  TRACE (trace_devices,
421
         ("hw_find_ihandle_runtime_property(me=0x%lx, property=%s)\n",
422
          (long)me, property));
423
  if (entry == NULL)
424
    hw_abort (me, "property \"%s\" not found", property);
425
  if (entry->property->type != ihandle_property
426
      || entry->property->disposition != permenant_object)
427
    hw_abort (me, "property \"%s\" of wrong type", property);
428
  ASSERT (entry->init_array != NULL);
429
  /* the full path */
430
  ihandle->full_path = entry->init_array;
431
}
432
#endif
433
 
434
 
435
 
436
#if 0
437
void
438
hw_set_ihandle_property (struct hw *me,
439
                         const char *property,
440
                         hw_instance *ihandle)
441
{
442
  unsigned_cell cells;
443
  cells = H2BE_cell (hw_instance_to_external (ihandle));
444
  hw_set_property (me, property, ihandle_property,
445
                   &cells, sizeof (cells));
446
 
447
}
448
#endif
449
 
450
#if 0
451
hw_instance *
452
hw_find_ihandle_property (struct hw *me,
453
                          const char *property)
454
{
455
  const hw_property_data *node;
456
  unsigned_cell ihandle;
457
  hw_instance *instance;
458
 
459
  node = hw_find_property (me, property);
460
  if (node == NULL)
461
    hw_abort (me, "property \"%s\" not found", property);
462
  if (node->type != ihandle_property)
463
    hw_abort(me, "property \"%s\" of wrong type (ihandle)", property);
464
  if (node->array == NULL)
465
    hw_abort(me, "runtime property \"%s\" not yet initialized", property);
466
 
467
  ASSERT (sizeof(ihandle) == node->sizeof_array);
468
  memcpy (&ihandle, node->array, sizeof(ihandle));
469
  instance = external_to_hw_instance (me, BE2H_cell(ihandle));
470
  ASSERT (instance != NULL);
471
  return instance;
472
}
473
#endif
474
 
475
 
476
void
477
hw_add_integer_property (struct hw *me,
478
                         const char *property,
479
                         signed_cell integer)
480
{
481
  H2BE (integer);
482
  hw_add_property (me, property, integer_property,
483
                   &integer, sizeof(integer),
484
                   &integer, sizeof(integer),
485
                   NULL, permenant_object);
486
}
487
 
488
signed_cell
489
hw_find_integer_property (struct hw *me,
490
                          const char *property)
491
{
492
  const struct hw_property *node;
493
  signed_cell integer;
494
  TRACE (trace_devices,
495
         ("hw_find_integer(me=0x%lx, property=%s)\n",
496
          (long)me, property));
497
  node = hw_find_property (me, property);
498
  if (node == NULL)
499
    hw_abort (me, "property \"%s\" not found", property);
500
  if (node->type != integer_property)
501
    hw_abort (me, "property \"%s\" of wrong type (integer)", property);
502
  ASSERT (sizeof(integer) == node->sizeof_array);
503
  memcpy (&integer, node->array, sizeof (integer));
504
  return BE2H_cell (integer);
505
}
506
 
507
int
508
hw_find_integer_array_property (struct hw *me,
509
                                const char *property,
510
                                unsigned index,
511
                                signed_cell *integer)
512
{
513
  const struct hw_property *node;
514
  int sizeof_integer = sizeof (*integer);
515
  signed_cell *cell;
516
  TRACE (trace_devices,
517
         ("hw_find_integer(me=0x%lx, property=%s)\n",
518
          (long)me, property));
519
 
520
  /* check things sane */
521
  node = hw_find_property (me, property);
522
  if (node == NULL)
523
    hw_abort (me, "property \"%s\" not found", property);
524
  if (node->type != integer_property
525
      && node->type != array_property)
526
    hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
527
  if ((node->sizeof_array % sizeof_integer) != 0)
528
    hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
529
  if (node->sizeof_array <= sizeof_integer * index)
530
    return 0;
531
 
532
  /* Find and convert the value */
533
  cell = ((signed_cell*)node->array) + index;
534
  *integer = BE2H_cell (*cell);
535
 
536
  return node->sizeof_array / sizeof_integer;
537
}
538
 
539
 
540
static unsigned_cell *
541
unit_address_to_cells (const hw_unit *unit,
542
                       unsigned_cell *cell,
543
                       int nr_cells)
544
{
545
  int i;
546
  ASSERT(nr_cells == unit->nr_cells);
547
  for (i = 0; i < unit->nr_cells; i++)
548
    {
549
      *cell = H2BE_cell (unit->cells[i]);
550
      cell += 1;
551
    }
552
  return cell;
553
}
554
 
555
 
556
static const unsigned_cell *
557
cells_to_unit_address (const unsigned_cell *cell,
558
                       hw_unit *unit,
559
                       int nr_cells)
560
{
561
  int i;
562
  memset(unit, 0, sizeof(*unit));
563
  unit->nr_cells = nr_cells;
564
  for (i = 0; i < unit->nr_cells; i++)
565
    {
566
      unit->cells[i] = BE2H_cell (*cell);
567
      cell += 1;
568
    }
569
  return cell;
570
}
571
 
572
 
573
static unsigned
574
nr_range_property_cells (struct hw *me,
575
                         int nr_ranges)
576
{
577
  return ((hw_unit_nr_address_cells (me)
578
           + hw_unit_nr_address_cells (hw_parent (me))
579
           + hw_unit_nr_size_cells (me))
580
          ) * nr_ranges;
581
}
582
 
583
void
584
hw_add_range_array_property (struct hw *me,
585
                             const char *property,
586
                             const range_property_spec *ranges,
587
                             unsigned nr_ranges)
588
{
589
  unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
590
                           * sizeof (unsigned_cell));
591
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
592
  unsigned_cell *cell;
593
  int i;
594
 
595
  /* copy the property elements over */
596
  cell = cells;
597
  for (i = 0; i < nr_ranges; i++)
598
    {
599
      const range_property_spec *range = &ranges[i];
600
      /* copy the child address */
601
      cell = unit_address_to_cells (&range->child_address, cell,
602
                                    hw_unit_nr_address_cells (me));
603
      /* copy the parent address */
604
      cell = unit_address_to_cells (&range->parent_address, cell,
605
                                    hw_unit_nr_address_cells (hw_parent (me)));
606
      /* copy the size */
607
      cell = unit_address_to_cells (&range->size, cell,
608
                                    hw_unit_nr_size_cells (me));
609
    }
610
  ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
611
 
612
  /* add it */
613
  hw_add_property (me, property, range_array_property,
614
                   cells, sizeof_cells,
615
                   cells, sizeof_cells,
616
                   NULL, permenant_object);
617
 
618
  hw_free (me, cells);
619
}
620
 
621
int
622
hw_find_range_array_property (struct hw *me,
623
                              const char *property,
624
                              unsigned index,
625
                              range_property_spec *range)
626
{
627
  const struct hw_property *node;
628
  unsigned sizeof_entry = (nr_range_property_cells (me, 1)
629
                           * sizeof (unsigned_cell));
630
  const unsigned_cell *cells;
631
 
632
  /* locate the property */
633
  node = hw_find_property (me, property);
634
  if (node == NULL)
635
    hw_abort (me, "property \"%s\" not found", property);
636
  if (node->type != range_array_property)
637
    hw_abort (me, "property \"%s\" of wrong type (range array)", property);
638
 
639
  /* aligned ? */
640
  if ((node->sizeof_array % sizeof_entry) != 0)
641
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
642
              property);
643
 
644
  /* within bounds? */
645
  if (node->sizeof_array < sizeof_entry * (index + 1))
646
    return 0;
647
 
648
  /* find the range of interest */
649
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
650
 
651
  /* copy the child address out - converting as we go */
652
  cells = cells_to_unit_address (cells, &range->child_address,
653
                                 hw_unit_nr_address_cells (me));
654
 
655
  /* copy the parent address out - converting as we go */
656
  cells = cells_to_unit_address (cells, &range->parent_address,
657
                                 hw_unit_nr_address_cells (hw_parent (me)));
658
 
659
  /* copy the size - converting as we go */
660
  cells = cells_to_unit_address (cells, &range->size,
661
                                 hw_unit_nr_size_cells (me));
662
 
663
  return node->sizeof_array / sizeof_entry;
664
}
665
 
666
 
667
static unsigned
668
nr_reg_property_cells (struct hw *me,
669
                       int nr_regs)
670
{
671
  return (hw_unit_nr_address_cells (hw_parent(me))
672
          + hw_unit_nr_size_cells (hw_parent(me))
673
          ) * nr_regs;
674
}
675
 
676
void
677
hw_add_reg_array_property (struct hw *me,
678
                           const char *property,
679
                           const reg_property_spec *regs,
680
                           unsigned nr_regs)
681
{
682
  unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
683
                           * sizeof (unsigned_cell));
684
  unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
685
  unsigned_cell *cell;
686
  int i;
687
 
688
  /* copy the property elements over */
689
  cell = cells;
690
  for (i = 0; i < nr_regs; i++)
691
    {
692
      const reg_property_spec *reg = &regs[i];
693
      /* copy the address */
694
      cell = unit_address_to_cells (&reg->address, cell,
695
                                    hw_unit_nr_address_cells (hw_parent (me)));
696
      /* copy the size */
697
      cell = unit_address_to_cells (&reg->size, cell,
698
                                    hw_unit_nr_size_cells (hw_parent (me)));
699
    }
700
  ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
701
 
702
  /* add it */
703
  hw_add_property (me, property, reg_array_property,
704
                   cells, sizeof_cells,
705
                   cells, sizeof_cells,
706
                   NULL, permenant_object);
707
 
708
  hw_free (me, cells);
709
}
710
 
711
int
712
hw_find_reg_array_property (struct hw *me,
713
                            const char *property,
714
                            unsigned index,
715
                            reg_property_spec *reg)
716
{
717
  const struct hw_property *node;
718
  unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
719
                           * sizeof (unsigned_cell));
720
  const unsigned_cell *cells;
721
 
722
  /* locate the property */
723
  node = hw_find_property (me, property);
724
  if (node == NULL)
725
    hw_abort (me, "property \"%s\" not found", property);
726
  if (node->type != reg_array_property)
727
    hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
728
 
729
  /* aligned ? */
730
  if ((node->sizeof_array % sizeof_entry) != 0)
731
    hw_abort (me, "property \"%s\" contains an incomplete number of entries",
732
              property);
733
 
734
  /* within bounds? */
735
  if (node->sizeof_array < sizeof_entry * (index + 1))
736
    return 0;
737
 
738
  /* find the range of interest */
739
  cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
740
 
741
  /* copy the address out - converting as we go */
742
  cells = cells_to_unit_address (cells, &reg->address,
743
                                 hw_unit_nr_address_cells (hw_parent (me)));
744
 
745
  /* copy the size out - converting as we go */
746
  cells = cells_to_unit_address (cells, &reg->size,
747
                                 hw_unit_nr_size_cells (hw_parent (me)));
748
 
749
  return node->sizeof_array / sizeof_entry;
750
}
751
 
752
 
753
void
754
hw_add_string_property (struct hw *me,
755
                        const char *property,
756
                        const char *string)
757
{
758
  hw_add_property (me, property, string_property,
759
                   string, strlen(string) + 1,
760
                   string, strlen(string) + 1,
761
                   NULL, permenant_object);
762
}
763
 
764
const char *
765
hw_find_string_property (struct hw *me,
766
                         const char *property)
767
{
768
  const struct hw_property *node;
769
  const char *string;
770
  node = hw_find_property (me, property);
771
  if (node == NULL)
772
    hw_abort (me, "property \"%s\" not found", property);
773
  if (node->type != string_property)
774
    hw_abort (me, "property \"%s\" of wrong type (string)", property);
775
  string = node->array;
776
  ASSERT (strlen(string) + 1 == node->sizeof_array);
777
  return string;
778
}
779
 
780
void
781
hw_add_string_array_property (struct hw *me,
782
                              const char *property,
783
                              const string_property_spec *strings,
784
                              unsigned nr_strings)
785
{
786
  int sizeof_array;
787
  int string_nr;
788
  char *array;
789
  char *chp;
790
  if (nr_strings == 0)
791
    hw_abort (me, "property \"%s\" must be non-null", property);
792
  /* total up the size of the needed array */
793
  for (sizeof_array = 0, string_nr = 0;
794
       string_nr < nr_strings;
795
       string_nr ++)
796
    {
797
      sizeof_array += strlen (strings[string_nr]) + 1;
798
    }
799
  /* create the array */
800
  array = (char*) hw_zalloc (me, sizeof_array);
801
  chp = array;
802
  for (string_nr = 0;
803
       string_nr < nr_strings;
804
       string_nr++)
805
    {
806
      strcpy (chp, strings[string_nr]);
807
      chp += strlen (chp) + 1;
808
    }
809
  ASSERT (chp == array + sizeof_array);
810
  /* now enter it */
811
  hw_add_property (me, property, string_array_property,
812
                   array, sizeof_array,
813
                   array, sizeof_array,
814
                   NULL, permenant_object);
815
}
816
 
817
int
818
hw_find_string_array_property (struct hw *me,
819
                               const char *property,
820
                               unsigned index,
821
                               string_property_spec *string)
822
{
823
  const struct hw_property *node;
824
  node = hw_find_property (me, property);
825
  if (node == NULL)
826
    hw_abort (me, "property \"%s\" not found", property);
827
  switch (node->type)
828
    {
829
    default:
830
      hw_abort (me, "property \"%s\" of wrong type", property);
831
      break;
832
    case string_property:
833
      if (index == 0)
834
        {
835
          *string = node->array;
836
          ASSERT (strlen(*string) + 1 == node->sizeof_array);
837
          return 1;
838
        }
839
      break;
840
    case array_property:
841
      if (node->sizeof_array == 0
842
          || ((char*)node->array)[node->sizeof_array - 1] != '\0')
843
        hw_abort (me, "property \"%s\" invalid for string array", property);
844
      /* FALL THROUGH */
845
    case string_array_property:
846
      ASSERT (node->sizeof_array > 0);
847
      ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
848
      {
849
        const char *chp = node->array;
850
        int nr_entries = 0;
851
        /* count the number of strings, keeping an eye out for the one
852
           we're looking for */
853
        *string = chp;
854
        do
855
          {
856
            if (*chp == '\0')
857
              {
858
                /* next string */
859
                nr_entries++;
860
                chp++;
861
                if (nr_entries == index)
862
                  *string = chp;
863
              }
864
            else
865
              {
866
                chp++;
867
              }
868
          } while (chp < (char*)node->array + node->sizeof_array);
869
        if (index < nr_entries)
870
          return nr_entries;
871
        else
872
          {
873
            *string = NULL;
874
            return 0;
875
          }
876
      }
877
      break;
878
    }
879
  return 0;
880
}
881
 
882
void
883
hw_add_duplicate_property (struct hw *me,
884
                           const char *property,
885
                           const struct hw_property *original)
886
{
887
  struct hw_property_data *master;
888
  TRACE (trace_devices,
889
         ("hw_add_duplicate_property(me=0x%lx, property=%s, ...)\n",
890
          (long)me, property));
891
  if (original->disposition != permenant_object)
892
    hw_abort (me, "Can only duplicate permenant objects");
893
  /* find the original's master */
894
  master = original->owner->properties_of_hw;
895
  while (master->property != original)
896
    {
897
      master = master->next;
898
      ASSERT(master != NULL);
899
    }
900
  /* now duplicate it */
901
  hw_add_property (me, property,
902
                   original->type,
903
                   master->init_array, master->sizeof_init_array,
904
                   original->array, original->sizeof_array,
905
                   original, permenant_object);
906
}

powered by: WebSVN 2.1.0

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