1 | /* |
---|
2 | * Copyright (c) 2006 Kolja Waschk rtemsdev/ixo.de |
---|
3 | * |
---|
4 | * The license and distribution terms for this file may be |
---|
5 | * found in the file LICENSE in this distribution or at |
---|
6 | * http://www.rtems.com/license/LICENSE. |
---|
7 | * |
---|
8 | * $Id$ |
---|
9 | */ |
---|
10 | |
---|
11 | #include <stdio.h> |
---|
12 | #include <stdlib.h> |
---|
13 | #include <string.h> |
---|
14 | |
---|
15 | #include "ptf.h" |
---|
16 | #include "bridges.h" |
---|
17 | #include "devices.h" |
---|
18 | |
---|
19 | void add_device(device_desc **dl, struct ptf *dev) |
---|
20 | { |
---|
21 | device_desc *eds; |
---|
22 | |
---|
23 | for(eds = *dl; eds; eds = eds->next) |
---|
24 | { |
---|
25 | if(eds->ptf == dev) |
---|
26 | { |
---|
27 | eds->slaves++; |
---|
28 | return; |
---|
29 | }; |
---|
30 | }; |
---|
31 | |
---|
32 | eds = (device_desc *)malloc(sizeof(device_desc)); |
---|
33 | eds->slaves = 1; |
---|
34 | eds->ptf = dev; |
---|
35 | eds->next = *dl; |
---|
36 | *dl = eds; |
---|
37 | } |
---|
38 | |
---|
39 | void check_and_add_device(struct ptf_item *pi, void *arg) |
---|
40 | { |
---|
41 | struct ptf *module = pi->item[pi->level-3]; |
---|
42 | struct ptf *sysinfo = pi->item[pi->level-2]; |
---|
43 | char *master_name = pi->item[pi->level]->value; |
---|
44 | |
---|
45 | struct { char *dm; char *im; device_desc **dl; bus_bridge_pair *bridges; } *dinfo = arg; |
---|
46 | |
---|
47 | if(is_bridged(dinfo->dm, master_name, dinfo->bridges) || |
---|
48 | is_bridged(dinfo->im, master_name, dinfo->bridges)) |
---|
49 | { |
---|
50 | struct ptf *ni = ptf_alloc_item(item, "N2G_Selected", "1"); |
---|
51 | if(ni != NULL) |
---|
52 | { |
---|
53 | ni->next = sysinfo->sub; |
---|
54 | sysinfo->sub = ni; |
---|
55 | }; |
---|
56 | add_device(dinfo->dl, module); |
---|
57 | }; |
---|
58 | } |
---|
59 | |
---|
60 | void set_dev_cfgname(struct ptf_item *pi, void *arg) |
---|
61 | { |
---|
62 | device_desc *dev = arg; |
---|
63 | dev->cfgname = pi->item[pi->level]->name; |
---|
64 | } |
---|
65 | |
---|
66 | |
---|
67 | device_desc *find_devices( |
---|
68 | struct ptf *ptf, |
---|
69 | struct ptf *cfg, |
---|
70 | struct ptf *cpu, |
---|
71 | bus_bridge_pair *bridges) |
---|
72 | { |
---|
73 | struct ptf system = { section, "SYSTEM", 0, 0, 0 }; |
---|
74 | struct ptf module = { section, "MODULE", 0, 0, 0 }; |
---|
75 | struct ptf slave = { section, "SLAVE", 0, 0, 0 }; |
---|
76 | struct ptf syb = { section, "SYSTEM_BUILDER_INFO", 0, 0, 0 }; |
---|
77 | struct ptf maby = { section, "MASTERED_BY", 0, 0, 0 }; |
---|
78 | struct ptf_item brdg = { 5, &system, &module, &slave, &syb, &maby }; |
---|
79 | |
---|
80 | struct ptf modules = { section, "MODULES", 0, 0, 0 }; |
---|
81 | struct ptf named = { item, 0, 0, 0, 0}; |
---|
82 | struct ptf_item devcf = { 2, &modules, &named }; |
---|
83 | |
---|
84 | struct { char *dm; char *im; device_desc **dl; bus_bridge_pair *bridges; } dinfo; |
---|
85 | |
---|
86 | device_desc *found, *reverse; |
---|
87 | |
---|
88 | found = NULL; |
---|
89 | |
---|
90 | add_device(&found, cpu); /* The CPU is "self-connected", add it */ |
---|
91 | |
---|
92 | dinfo.dl = &found; |
---|
93 | dinfo.bridges = bridges; |
---|
94 | dinfo.dm = (char *)malloc(strlen(cpu->value)+13); |
---|
95 | dinfo.im = (char *)malloc(strlen(cpu->value)+20); |
---|
96 | |
---|
97 | strcpy(dinfo.im, cpu->value); |
---|
98 | strcat(dinfo.im, "/"); |
---|
99 | strcpy(dinfo.dm, dinfo.im); |
---|
100 | strcat(dinfo.dm, "data_master"); |
---|
101 | strcat(dinfo.im, "instruction_master"); |
---|
102 | |
---|
103 | /* "Available" is any MODULE with a SLAVE section that is MASTERED_BY |
---|
104 | either instr_master or data_master of selected CPU, either directly |
---|
105 | or through a bridge. See code above for more info about bridges. |
---|
106 | */ |
---|
107 | |
---|
108 | ptf_match(ptf, &brdg, check_and_add_device, &dinfo); |
---|
109 | |
---|
110 | free(dinfo.dm); |
---|
111 | free(dinfo.im); |
---|
112 | |
---|
113 | /* Reverse the linked list */ |
---|
114 | |
---|
115 | reverse = NULL; |
---|
116 | while(found) |
---|
117 | { |
---|
118 | device_desc *tmp = found; |
---|
119 | found = found->next; |
---|
120 | |
---|
121 | tmp->next = reverse; |
---|
122 | reverse = tmp; |
---|
123 | |
---|
124 | named.value = tmp->ptf->value; |
---|
125 | tmp->cfgname = NULL; |
---|
126 | ptf_match(cfg, &devcf, set_dev_cfgname, tmp); |
---|
127 | if(tmp->cfgname == NULL) tmp->cfgname = ptf_defused_name(tmp->ptf->value); |
---|
128 | }; |
---|
129 | |
---|
130 | return reverse; |
---|
131 | } |
---|
132 | |
---|