* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[deliverable/binutils-gdb.git] / sim / common / hw-properties.c
CommitLineData
e5f0d498
AC
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21#include "sim-main.h"
69be0d4c 22#include "hw-base.h"
e5f0d498
AC
23
24#include "sim-assert.h"
25
26#ifdef HAVE_STRING_H
27#include <string.h>
28#else
29#ifdef HAVE_STRINGS_H
30#include <strings.h>
31#endif
32#endif
33
34#define TRACE(A,B)
35
36/* property entries */
37
38struct 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
325a1ba8
AC
45void
46create_hw_property_data (struct hw *me)
47{
48}
49
50void
51delete_hw_property_data (struct hw *me)
52{
53}
54
55
e5f0d498
AC
56/* Device Properties: */
57
58static struct hw_property_data *
59find_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
75static void
76hw_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
127static void
128hw_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
167static void
168clean_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
201void
202hw_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
240void
241hw_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
291const struct hw_property *
292hw_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
308const struct hw_property *
309hw_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
333void
334hw_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
344void
345hw_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
353const struct hw_property *
354hw_find_array_property (struct hw *me,
355 const char *property)
356{
357 const struct hw_property *node;
358 node = hw_find_property (me, property);
69be0d4c
AC
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);
e5f0d498
AC
363 return node;
364}
365
366
367
368void
369hw_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
380int
381hw_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);
69be0d4c
AC
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);
e5f0d498
AC
391 ASSERT (sizeof (boolean) == node->sizeof_array);
392 memcpy (&boolean, node->array, sizeof (boolean));
393 return boolean;
394}
395
396
397
398#if 0
399void
400hw_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
413void
414hw_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 TRACE (trace_devices,
420 ("hw_find_ihandle_runtime_property(me=0x%lx, property=%s)\n",
421 (long)me, property));
69be0d4c
AC
422 if (entry == NULL)
423 hw_abort (me, "property \"%s\" not found", property);
424 if (entry->property->type != ihandle_property
e5f0d498 425 || entry->property->disposition != permenant_object)
69be0d4c 426 hw_abort (me, "property \"%s\" of wrong type", property);
e5f0d498
AC
427 ASSERT (entry->init_array != NULL);
428 /* the full path */
429 ihandle->full_path = entry->init_array;
430}
431#endif
432
433
434
435#if 0
436void
437hw_set_ihandle_property (struct hw *me,
438 const char *property,
439 hw_instance *ihandle)
440{
441 unsigned_cell cells;
442 cells = H2BE_cell (hw_instance_to_external (ihandle));
443 hw_set_property (me, property, ihandle_property,
444 &cells, sizeof (cells));
445
446}
447#endif
448
449#if 0
450hw_instance *
451hw_find_ihandle_property (struct hw *me,
452 const char *property)
453{
454 const hw_property_data *node;
455 unsigned_cell ihandle;
456 hw_instance *instance;
457
458 node = hw_find_property (me, property);
69be0d4c
AC
459 if (node == NULL)
460 hw_abort (me, "property \"%s\" not found", property);
461 if (node->type != ihandle_property)
462 hw_abort(me, "property \"%s\" of wrong type (ihandle)", property);
e5f0d498 463 if (node->array == NULL)
69be0d4c 464 hw_abort(me, "runtime property \"%s\" not yet initialized", property);
e5f0d498
AC
465
466 ASSERT (sizeof(ihandle) == node->sizeof_array);
467 memcpy (&ihandle, node->array, sizeof(ihandle));
468 instance = external_to_hw_instance (me, BE2H_cell(ihandle));
469 ASSERT (instance != NULL);
470 return instance;
471}
472#endif
473
474
475void
476hw_add_integer_property (struct hw *me,
477 const char *property,
478 signed_cell integer)
479{
480 H2BE (integer);
481 hw_add_property (me, property, integer_property,
482 &integer, sizeof(integer),
483 &integer, sizeof(integer),
484 NULL, permenant_object);
485}
486
487signed_cell
488hw_find_integer_property (struct hw *me,
489 const char *property)
490{
491 const struct hw_property *node;
492 signed_cell integer;
493 TRACE (trace_devices,
494 ("hw_find_integer(me=0x%lx, property=%s)\n",
495 (long)me, property));
496 node = hw_find_property (me, property);
69be0d4c
AC
497 if (node == NULL)
498 hw_abort (me, "property \"%s\" not found", property);
499 if (node->type != integer_property)
500 hw_abort (me, "property \"%s\" of wrong type (integer)", property);
e5f0d498
AC
501 ASSERT (sizeof(integer) == node->sizeof_array);
502 memcpy (&integer, node->array, sizeof (integer));
503 return BE2H_cell (integer);
504}
505
506int
507hw_find_integer_array_property (struct hw *me,
508 const char *property,
509 unsigned index,
510 signed_cell *integer)
511{
512 const struct hw_property *node;
513 int sizeof_integer = sizeof (*integer);
514 signed_cell *cell;
515 TRACE (trace_devices,
516 ("hw_find_integer(me=0x%lx, property=%s)\n",
517 (long)me, property));
518
519 /* check things sane */
520 node = hw_find_property (me, property);
69be0d4c
AC
521 if (node == NULL)
522 hw_abort (me, "property \"%s\" not found", property);
523 if (node->type != integer_property
524 && node->type != array_property)
525 hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
e5f0d498 526 if ((node->sizeof_array % sizeof_integer) != 0)
69be0d4c 527 hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
e5f0d498
AC
528 if (node->sizeof_array <= sizeof_integer * index)
529 return 0;
530
531 /* Find and convert the value */
532 cell = ((signed_cell*)node->array) + index;
533 *integer = BE2H_cell (*cell);
534
535 return node->sizeof_array / sizeof_integer;
536}
537
538
539static unsigned_cell *
540unit_address_to_cells (const hw_unit *unit,
541 unsigned_cell *cell,
542 int nr_cells)
543{
544 int i;
545 ASSERT(nr_cells == unit->nr_cells);
546 for (i = 0; i < unit->nr_cells; i++)
547 {
548 *cell = H2BE_cell (unit->cells[i]);
549 cell += 1;
550 }
551 return cell;
552}
553
554
555static const unsigned_cell *
556cells_to_unit_address (const unsigned_cell *cell,
557 hw_unit *unit,
558 int nr_cells)
559{
560 int i;
561 memset(unit, 0, sizeof(*unit));
562 unit->nr_cells = nr_cells;
563 for (i = 0; i < unit->nr_cells; i++)
564 {
565 unit->cells[i] = BE2H_cell (*cell);
566 cell += 1;
567 }
568 return cell;
569}
570
571
572static unsigned
573nr_range_property_cells (struct hw *me,
574 int nr_ranges)
575{
576 return ((hw_unit_nr_address_cells (me)
577 + hw_unit_nr_address_cells (hw_parent (me))
578 + hw_unit_nr_size_cells (me))
579 ) * nr_ranges;
580}
581
582void
583hw_add_range_array_property (struct hw *me,
584 const char *property,
585 const range_property_spec *ranges,
586 unsigned nr_ranges)
587{
588 unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
589 * sizeof (unsigned_cell));
590 unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
591 unsigned_cell *cell;
592 int i;
593
594 /* copy the property elements over */
595 cell = cells;
596 for (i = 0; i < nr_ranges; i++)
597 {
598 const range_property_spec *range = &ranges[i];
599 /* copy the child address */
600 cell = unit_address_to_cells (&range->child_address, cell,
601 hw_unit_nr_address_cells (me));
602 /* copy the parent address */
603 cell = unit_address_to_cells (&range->parent_address, cell,
604 hw_unit_nr_address_cells (hw_parent (me)));
605 /* copy the size */
606 cell = unit_address_to_cells (&range->size, cell,
607 hw_unit_nr_size_cells (me));
608 }
609 ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
610
611 /* add it */
612 hw_add_property (me, property, range_array_property,
613 cells, sizeof_cells,
614 cells, sizeof_cells,
615 NULL, permenant_object);
616
617 hw_free (me, cells);
618}
619
620int
621hw_find_range_array_property (struct hw *me,
622 const char *property,
623 unsigned index,
624 range_property_spec *range)
625{
626 const struct hw_property *node;
627 unsigned sizeof_entry = (nr_range_property_cells (me, 1)
628 * sizeof (unsigned_cell));
629 const unsigned_cell *cells;
630
631 /* locate the property */
632 node = hw_find_property (me, property);
69be0d4c
AC
633 if (node == NULL)
634 hw_abort (me, "property \"%s\" not found", property);
635 if (node->type != range_array_property)
636 hw_abort (me, "property \"%s\" of wrong type (range array)", property);
e5f0d498
AC
637
638 /* aligned ? */
639 if ((node->sizeof_array % sizeof_entry) != 0)
69be0d4c 640 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
e5f0d498
AC
641 property);
642
643 /* within bounds? */
644 if (node->sizeof_array < sizeof_entry * (index + 1))
645 return 0;
646
647 /* find the range of interest */
648 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
649
650 /* copy the child address out - converting as we go */
651 cells = cells_to_unit_address (cells, &range->child_address,
652 hw_unit_nr_address_cells (me));
653
654 /* copy the parent address out - converting as we go */
655 cells = cells_to_unit_address (cells, &range->parent_address,
656 hw_unit_nr_address_cells (hw_parent (me)));
657
658 /* copy the size - converting as we go */
659 cells = cells_to_unit_address (cells, &range->size,
660 hw_unit_nr_size_cells (me));
661
662 return node->sizeof_array / sizeof_entry;
663}
664
665
666static unsigned
667nr_reg_property_cells (struct hw *me,
668 int nr_regs)
669{
670 return (hw_unit_nr_address_cells (hw_parent(me))
671 + hw_unit_nr_size_cells (hw_parent(me))
672 ) * nr_regs;
673}
674
675void
676hw_add_reg_array_property (struct hw *me,
677 const char *property,
678 const reg_property_spec *regs,
679 unsigned nr_regs)
680{
681 unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
682 * sizeof (unsigned_cell));
683 unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
684 unsigned_cell *cell;
685 int i;
686
687 /* copy the property elements over */
688 cell = cells;
689 for (i = 0; i < nr_regs; i++)
690 {
691 const reg_property_spec *reg = &regs[i];
692 /* copy the address */
693 cell = unit_address_to_cells (&reg->address, cell,
694 hw_unit_nr_address_cells (hw_parent (me)));
695 /* copy the size */
696 cell = unit_address_to_cells (&reg->size, cell,
697 hw_unit_nr_size_cells (hw_parent (me)));
698 }
699 ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
700
701 /* add it */
702 hw_add_property (me, property, reg_array_property,
703 cells, sizeof_cells,
704 cells, sizeof_cells,
705 NULL, permenant_object);
706
707 hw_free (me, cells);
708}
709
710int
711hw_find_reg_array_property (struct hw *me,
712 const char *property,
713 unsigned index,
714 reg_property_spec *reg)
715{
716 const struct hw_property *node;
717 unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
718 * sizeof (unsigned_cell));
719 const unsigned_cell *cells;
720
721 /* locate the property */
722 node = hw_find_property (me, property);
69be0d4c
AC
723 if (node == NULL)
724 hw_abort (me, "property \"%s\" not found", property);
725 if (node->type != reg_array_property)
726 hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
e5f0d498
AC
727
728 /* aligned ? */
729 if ((node->sizeof_array % sizeof_entry) != 0)
69be0d4c 730 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
e5f0d498
AC
731 property);
732
733 /* within bounds? */
734 if (node->sizeof_array < sizeof_entry * (index + 1))
735 return 0;
736
737 /* find the range of interest */
738 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
739
740 /* copy the address out - converting as we go */
741 cells = cells_to_unit_address (cells, &reg->address,
742 hw_unit_nr_address_cells (hw_parent (me)));
743
744 /* copy the size out - converting as we go */
745 cells = cells_to_unit_address (cells, &reg->size,
746 hw_unit_nr_size_cells (hw_parent (me)));
747
748 return node->sizeof_array / sizeof_entry;
749}
750
751
752void
753hw_add_string_property (struct hw *me,
754 const char *property,
755 const char *string)
756{
757 hw_add_property (me, property, string_property,
758 string, strlen(string) + 1,
759 string, strlen(string) + 1,
760 NULL, permenant_object);
761}
762
763const char *
764hw_find_string_property (struct hw *me,
765 const char *property)
766{
767 const struct hw_property *node;
768 const char *string;
769 node = hw_find_property (me, property);
69be0d4c
AC
770 if (node == NULL)
771 hw_abort (me, "property \"%s\" not found", property);
772 if (node->type != string_property)
773 hw_abort (me, "property \"%s\" of wrong type (string)", property);
e5f0d498
AC
774 string = node->array;
775 ASSERT (strlen(string) + 1 == node->sizeof_array);
776 return string;
777}
778
779void
780hw_add_string_array_property (struct hw *me,
781 const char *property,
782 const string_property_spec *strings,
783 unsigned nr_strings)
784{
785 int sizeof_array;
786 int string_nr;
787 char *array;
788 char *chp;
789 if (nr_strings == 0)
69be0d4c 790 hw_abort (me, "property \"%s\" must be non-null", property);
e5f0d498
AC
791 /* total up the size of the needed array */
792 for (sizeof_array = 0, string_nr = 0;
793 string_nr < nr_strings;
794 string_nr ++)
795 {
796 sizeof_array += strlen (strings[string_nr]) + 1;
797 }
798 /* create the array */
799 array = (char*) hw_zalloc (me, sizeof_array);
800 chp = array;
801 for (string_nr = 0;
802 string_nr < nr_strings;
803 string_nr++)
804 {
805 strcpy (chp, strings[string_nr]);
806 chp += strlen (chp) + 1;
807 }
808 ASSERT (chp == array + sizeof_array);
809 /* now enter it */
810 hw_add_property (me, property, string_array_property,
811 array, sizeof_array,
812 array, sizeof_array,
813 NULL, permenant_object);
814}
815
816int
817hw_find_string_array_property (struct hw *me,
818 const char *property,
819 unsigned index,
820 string_property_spec *string)
821{
822 const struct hw_property *node;
823 node = hw_find_property (me, property);
824 if (node == NULL)
69be0d4c 825 hw_abort (me, "property \"%s\" not found", property);
e5f0d498
AC
826 switch (node->type)
827 {
828 default:
69be0d4c 829 hw_abort (me, "property \"%s\" of wrong type", property);
e5f0d498
AC
830 break;
831 case string_property:
832 if (index == 0)
833 {
834 *string = node->array;
835 ASSERT (strlen(*string) + 1 == node->sizeof_array);
836 return 1;
837 }
838 break;
839 case array_property:
840 if (node->sizeof_array == 0
841 || ((char*)node->array)[node->sizeof_array - 1] != '\0')
69be0d4c 842 hw_abort (me, "property \"%s\" invalid for string array", property);
e5f0d498
AC
843 /* FALL THROUGH */
844 case string_array_property:
845 ASSERT (node->sizeof_array > 0);
846 ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
847 {
848 const char *chp = node->array;
849 int nr_entries = 0;
850 /* count the number of strings, keeping an eye out for the one
851 we're looking for */
852 *string = chp;
853 do
854 {
855 if (*chp == '\0')
856 {
857 /* next string */
858 nr_entries++;
859 chp++;
860 if (nr_entries == index)
861 *string = chp;
862 }
863 else
864 {
865 chp++;
866 }
867 } while (chp < (char*)node->array + node->sizeof_array);
868 if (index < nr_entries)
869 return nr_entries;
870 else
871 {
872 *string = NULL;
873 return 0;
874 }
875 }
876 break;
877 }
878 return 0;
879}
880
881void
882hw_add_duplicate_property (struct hw *me,
883 const char *property,
884 const struct hw_property *original)
885{
886 struct hw_property_data *master;
887 TRACE (trace_devices,
888 ("hw_add_duplicate_property(me=0x%lx, property=%s, ...)\n",
889 (long)me, property));
890 if (original->disposition != permenant_object)
891 hw_abort (me, "Can only duplicate permenant objects");
892 /* find the original's master */
893 master = original->owner->properties_of_hw;
894 while (master->property != original)
895 {
896 master = master->next;
897 ASSERT(master != NULL);
898 }
899 /* now duplicate it */
900 hw_add_property (me, property,
901 original->type,
902 master->init_array, master->sizeof_init_array,
903 original->array, original->sizeof_array,
904 original, permenant_object);
905}
This page took 0.165358 seconds and 4 git commands to generate.