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