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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [common/] [hw-properties.c] - Blame information for rev 227

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

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

powered by: WebSVN 2.1.0

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