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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [common/] [hw-properties.c] - Blame information for rev 855

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

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

powered by: WebSVN 2.1.0

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