blob: ad315c8fdabca90243f04994a73a658ba6a183f7 [file] [log] [blame]
Uwe Hermann7eb845e2008-11-02 17:01:06 +00001/*
2 * This file is part of the bayou project.
3 *
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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.
Uwe Hermann7eb845e2008-11-02 17:01:06 +000014 */
15
16#include "bayou.h"
17
18struct bayoucfg bayoucfg;
19
20static int add_payload(struct LAR *lar, struct larent *larent)
21{
22 struct payload *payload;
23 int plen;
24 u8 *params = NULL;
25 u8 *fptr;
26
27 if (bayoucfg.n_entries == BAYOU_MAX_ENTRIES)
28 return -1;
29
30 payload = &bayoucfg.entries[bayoucfg.n_entries];
31
32 if (strncmp((char *)larent->name, "payload/", 8))
33 return -1;
34
35 if (larstat(lar, (const char *)larent->name, &payload->stat))
36 return -1;
37
38 /* Make sure the LAR entry is valid. */
39 if (!lfverify(lar, (const char *)larent->name))
40 return -1;
41
42 /* Get a pointer to the start of the file. */
43 fptr = larfptr(lar, (const char *)larent->name);
44
45 if (fptr == NULL)
46 return -1;
47
48 if (!verify_self(fptr))
49 return -1;
50
51 payload->pentry.index = bayoucfg.n_entries;
52 payload->pentry.parent = 0;
53 payload->pentry.type = BPT_TYPE_CHOOSER;
54 payload->pentry.flags = 0;
55
56 plen = self_get_params(fptr, &params);
57 payload_parse_params(payload, params, plen);
58
59 payload->fptr = fptr;
60
61 bayoucfg.n_entries++;
62
63 return 0;
64}
65
66static int lar_walk_files(struct LAR *lar,
67 int (*cb) (struct LAR *, struct larent *))
68{
69 struct larent *larent;
70 int ret = 0;
71
72 rewindlar(lar);
73
74 while ((larent = readlar(lar)) != NULL) {
75 if ((ret = cb(lar, larent)))
76 break;
77 }
78
79 return ret;
80}
81
82/**
83 * If reading the bayou_payload_table fails for some reason, then construct
84 * a dummy table. All valid payloads in the lar are added as chooser items.
85 */
86static void build_dummy_table(struct LAR *lar)
87{
88 bayoucfg.timeout = 0xFF;
89 bayoucfg.n_entries = 0;
90
91 lar_walk_files(lar, add_payload);
92}
93
94int get_configuration(struct LAR *lar)
95{
96 struct larstat stat;
97 struct bpt_config *bptcfg;
98 u8 *fptr, *ptr;
99 int i;
100
101 /*
102 * If bayou_payload_table doesn't exist, then dummy up
103 * a table from the LAR contents.
104 */
105 if (larstat(lar, "bayou_payload_table", &stat) ||
106 !lfverify(lar, "bayou_payload_table"))
107 build_dummy_table(lar);
108
109 /* Open up the BPT and get the creamy goodness within. */
110
111 fptr = larfptr(lar, "bayou_payload_table");
112
113 if (fptr == NULL)
114 build_dummy_table(lar);
115
116 bptcfg = (struct bpt_config *)fptr;
117 bayoucfg.timeout = bptcfg->timeout;
118
119 bayoucfg.n_entries = bptcfg->entries;
120
121 if (bayoucfg.n_entries > BAYOU_MAX_ENTRIES) {
122 printf("W: Limiting the number of entries to %d\n",
123 BAYOU_MAX_ENTRIES);
124 bayoucfg.n_entries = BAYOU_MAX_ENTRIES;
125 }
126
127 ptr = fptr + sizeof(struct bpt_config);
128
129 for (i = 0; i < bayoucfg.n_entries; i++) {
130 struct bpt_pentry *entry = (struct bpt_pentry *)ptr;
131 struct payload *p = &(bayoucfg.entries[i]);
132 int plen;
133 u8 *params = NULL;
134
135 memcpy(&p->pentry, entry, sizeof(struct bpt_pentry));
136
137 if (entry->type != BPT_TYPE_CHAIN) {
138 char *lname = (char *)ptr + sizeof(struct bpt_pentry);
139
140 if (larstat(lar, (const char *)lname, &p->stat))
141 build_dummy_table(lar);
142
143 if (!lfverify(lar, (const char *)lname))
144 build_dummy_table(lar);
145
146 fptr = larfptr(lar, (const char *)lname);
147
148 if (verify_self(fptr))
149 p->fptr = fptr;
150 else
151 build_dummy_table(lar);
152
153 plen = self_get_params(fptr, &params);
154 payload_parse_params(p, params, plen);
155 }
156
157 ptr += sizeof(struct bpt_pentry) + entry->nlen;
158 }
159
160 return 0;
161}