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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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