Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / tools / dropin / finddropin.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: finddropin.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * id: @(#)finddropin.c 1.1 03/04/01
46 * purpose:
47 * copyright: Copyright 2000, 2003 Sun Microsystems, Inc. All Rights Reserved
48 * copyright: Use is subject to license terms.
49 */
50
51#include <sys/dilib.h>
52#include <strings.h>
53#include <stdlib.h>
54#include <unistd.h>
55#include <stdio.h>
56
57caddr_t
58extract_string(dropin_data_t *data)
59{
60 int32_t len = data->size+1;
61 static char str[0x80];
62
63 if (len > 0x80) {
64 return (NULL);
65 }
66 memset(str, 0, len);
67 strncpy(str, (caddr_t)data->data, data->size);
68 return (strdup(str));
69}
70
71static uchar_t *
72do_lempel_ziv(uchar_t *src, int32_t len, int32_t dlen, int32_t verbose)
73{
74 uchar_t *data, *dbuf;
75 int32_t nlen = 0;
76
77 dbuf = (uchar_t *)malloc(dlen);
78 if (dbuf == NULL) {
79 di_bail("Malloc Failed");
80 return (0);
81 }
82 nlen = di_decomp(src, len, dbuf);
83 if (verbose > 0) {
84 printf("Decompress: %d/%d bytes, [%d], ratio %2.2f:1\n",
85 len, dlen, nlen, (((float)dlen)/((float)len)));
86 }
87 data = (uchar_t *)malloc(dlen);
88 if (data == NULL) {
89 di_bail("Malloc Failed");
90 return (0);
91 }
92 memcpy(data, dbuf, dlen);
93 free(dbuf);
94 return (data);
95}
96
97int32_t
98di_getdata(obmd_t *src, int32_t verbose, dropin_data_t *rdata)
99{
100 uint32_t *dptr = (uint32_t *)((caddr_t)src + OBMD_HDR);
101 uchar_t *data = (uchar_t *)dptr;
102 int32_t dlen = src->size;
103 compresshdr *chdr = (compresshdr *) dptr;
104
105 if ((chdr->magic == COMP_MAGIC) && (src->size == chdr->comp_size)) {
106 int32_t clen = chdr->comp_size;
107 int32_t type = chdr->type;
108 dlen = chdr->decomp_size;
109
110 switch (type) {
111 case COMP_MAGIC:
112 if (verbose > 0) {
113 printf("[COMP: %x,%x]\n", clen, dlen);
114 }
115 data = do_lempel_ziv(data+sizeof (compresshdr),
116 clen, dlen, (verbose-1));
117 dptr = (uint32_t *)data;
118 break;
119
120 default:
121 printf("Unknown compression type: %d\n", type);
122 break;
123 }
124 }
125
126 rdata->data = data;
127 rdata->size = dlen;
128 if (dptr[0] == OBME_MAGIC) {
129 rdata->data += sizeof (obme_t);
130 rdata->size -= sizeof (obme_t);
131 }
132 return (0);
133}
134
135int32_t
136di_isdropin(obmd_t *src)
137{
138 return (strncmp((caddr_t)src, "OBMD", 4) == 0);
139}
140
141int32_t
142di_islevel2(obmd_t *src)
143{
144 uchar_t *bdata = ((uchar_t *)src)+OBMD_HDR;
145 int32_t *data = (int32_t *)bdata;
146 return (di_isdropin(src) && (data[0] == OBME_MAGIC));
147}
148
149static obmd_t *
150di_iterate(caddr_t name, obmd_t *src, int32_t size, int32_t verbose,
151 int32_t instance)
152{
153 int32_t dlen, bytes = 0;
154 int32_t num_found = 1;
155 obmd_t *found = NULL;
156 uchar_t *next;
157
158
159 if (verbose > 0) {
160 printf("di_iterate: '%s'\n", name);
161 }
162 /*
163 * Iterate through the chunk looking for dropins
164 */
165 while ((found == NULL) && (bytes < size) && (num_found <= instance)) {
166 next = (uchar_t *)src;
167 while (*next == 1) {
168 next++;
169 bytes++;
170 }
171 src = (obmd_t *)next;
172 if (!di_isdropin(src)) break;
173 if (verbose > 0) {
174 printf("..di: '%s' [%d]\n", src->name, src->size);
175 printf("instance = %i\n", instance);
176 }
177 if (strcmp(name, src->name) == 0) {
178 if (instance == num_found)
179 found = src;
180 else {
181 num_found++;
182 dlen = src->size + OBMD_HDR;
183 next += dlen;
184 bytes += dlen;
185 src = (obmd_t *)next;
186 }
187 } else {
188 dlen = src->size + OBMD_HDR;
189 next += dlen;
190 bytes += dlen;
191 src = (obmd_t *)next;
192 }
193 }
194 return (found);
195}
196
197obmd_t *
198di_finddropin(caddr_t name, obmd_t *src, int32_t filesize,
199 int32_t verbose, int32_t instance)
200{
201 caddr_t dir;
202 obmd_t *data = NULL;
203 caddr_t container;
204 caddr_t slash;
205 uchar_t *shift;
206 uchar_t *next;
207 dropin_data_t dropin_data;
208 int32_t i = 0;
209 int32_t size = filesize;
210
211
212
213 shift = (uchar_t *)src;
214 while (*shift == 1) {
215 if (verbose > 0) printf("x");
216 shift++;
217 }
218 src = (obmd_t *)shift;
219 if (*name == '/') {
220 name++;
221 di_getdata(src, (verbose-1), &dropin_data);
222 src = (obmd_t *)dropin_data.data;
223 size = dropin_data.size;
224 }
225 if (*name == 0) {
226 if (verbose > 0) {
227 printf("<empty filename>\n");
228 }
229 return (NULL);
230 }
231 if (!di_isdropin(src)) {
232 if (verbose > 0) {
233 printf("<Not a dropin>\n");
234 }
235 return (NULL);
236 }
237 if (size <= 0) {
238 if (verbose > 0) {
239 printf("<no more bytes>\n");
240 }
241 return (NULL);
242 }
243 container = strdup(name);
244 dir = slash = strchr(container, '/');
245 if (slash) {
246 *slash = 0;
247 dir = slash+1;
248 }
249 if (verbose > 0) {
250 printf("Path: %s [%x]\n", name, size);
251 }
252
253 next = (uchar_t *)src;
254 while ((++i <= instance) && (src != NULL)) {
255 data = di_iterate(container, src, filesize, (verbose-1), 1);
256 next += (src->size + OBMD_HDR);
257 src = (obmd_t *)next;
258 }
259
260 if (data != NULL) {
261 obmd_t *new;
262 int32_t new_size;
263 /*
264 * we found it
265 */
266 if (verbose > 0) {
267 printf("Dropin: '%s', [%d]\n", data->name, data->size);
268 }
269 if (dir) {
270 di_getdata(data, (verbose-1), &dropin_data);
271 new = (obmd_t *)dropin_data.data;
272 new_size = dropin_data.size;
273 if (verbose > 0) {
274 printf("Descending into: %s [%d]\n",
275 data->name, data->size);
276 }
277 data = di_finddropin(dir, new, new_size,
278 (verbose-1), 1);
279 }
280 }
281 return (data);
282}