1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  PCI Table Generator			File: mkpcidb.c
5    *
6    *  Author:  Mitch Lichtenberg
7    *
8    *  This program munges the PCI table into a form that uses
9    *  fewer embedded pointers.  Pointers are evil for the
10    *  relocatable version of CFE since they chew up valuable
11    *  initialized data segment space, and we only have
12    *  64KB of that.
13    *
14    *********************************************************************
15    *
16    *  Copyright 2000,2001,2002,2003
17    *  Broadcom Corporation. All rights reserved.
18    *
19    *  This software is furnished under license and may be used and
20    *  copied only in accordance with the following terms and
21    *  conditions.  Subject to these conditions, you may download,
22    *  copy, install, use, modify and distribute modified or unmodified
23    *  copies of this software in source and/or binary form.  No title
24    *  or ownership is transferred hereby.
25    *
26    *  1) Any source code used, modified or distributed must reproduce
27    *     and retain this copyright notice and list of conditions
28    *     as they appear in the source file.
29    *
30    *  2) No right is granted to use any trade name, trademark, or
31    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
32    *     name may not be used to endorse or promote products derived
33    *     from this software without the prior written permission of
34    *     Broadcom Corporation.
35    *
36    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
37    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
38    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
40    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
41    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
42    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
44    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
45    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
46    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
47    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
48    *     THE POSSIBILITY OF SUCH DAMAGE.
49    ********************************************************************* */
50
51#include <assert.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55
56typedef unsigned short pci_vendor_id_t;
57typedef unsigned short pci_product_id_t;
58
59struct pci_knowndev {
60    pci_vendor_id_t     vendor;
61    pci_product_id_t    product;
62    int                 flags;
63    char                *vendorname, *productname;
64};
65
66#include "pcidevs.h"
67#define PCI_KNOWNDEV_NOPROD 0x01
68#include "pcidevs_data.h"
69
70
71
72struct pci_knowndev2 {
73    pci_vendor_id_t vendor;
74    pci_product_id_t product;
75    int vendorname;
76    int productname;
77};
78
79#define MAXPCIDEVS 5000
80#define MAXSTRINGTABLE (1024*1024)
81
82struct pci_knowndev2 knowndevs[MAXPCIDEVS];
83char stringtable[MAXSTRINGTABLE];
84int curstringptr = 0;
85
86static void initintern (void);
87static int intern (char *string);
88
89int main(int argc,char *argv[])
90{
91    struct pci_knowndev2 *outdev;
92    const struct pci_knowndev *indev;
93    char *stringoff_type;
94    int cnt = 0;
95    int idx;
96
97    indev = pci_knowndevs;
98    outdev = knowndevs;
99    cnt = 0;
100
101    initintern();
102
103    while (indev->vendorname) {
104	assert (cnt < MAXPCIDEVS);
105	outdev->vendor = indev->vendor;
106	outdev->product = indev->product;
107	outdev->vendorname = intern(indev->vendorname);
108	outdev->productname = intern(indev->productname);
109	cnt++;
110	indev++;
111	outdev++;
112	}
113
114    outdev->vendor = 0;
115    outdev->product = 0;
116    outdev->vendorname = -1;
117    outdev->productname = -1;
118    cnt++;
119
120    if (curstringptr <= 65534)
121      stringoff_type = "unsigned short";
122    else
123      stringoff_type = "unsigned int";
124
125    fprintf(stderr,"%d total devices (%d bytes), %d bytes of strings\n",
126	   cnt,
127	   cnt * (4 + 2 * (curstringptr <= 65534 ? 2 : 4)),
128	   curstringptr);
129
130    printf("struct pci_knowndev2 {\n");
131    printf("    pci_vendor_id_t     vendor;\n");
132    printf("    pci_product_id_t    product;\n");
133    printf("    %s vendorname, productname;\n", stringoff_type);
134    printf("};\n");
135
136    printf("\n\n\n");
137    printf("const static struct pci_knowndev2 _pci_knowndevs[] __attribute__ ((section (\".text\"))) = {\n");
138    for (idx = 0; idx < cnt; idx++) {
139	printf("\t{0x%04X,0x%04X,%d,%d},\n",
140	       knowndevs[idx].vendor,
141	       knowndevs[idx].product,
142	       knowndevs[idx].vendorname,
143	       knowndevs[idx].productname);
144	}
145    printf("};\n\n\n");
146    printf("const static char _pci_knowndevs_text[] __attribute__ ((section (\".text\"))) = {\n");
147    for (idx = 0; idx < curstringptr; idx++) {
148	if ((idx % 16) == 0) printf("\t");
149	printf("0x%02X,",stringtable[idx]);
150	if ((idx % 16) == 15) printf("\n");
151	}
152    printf("};\n\n");
153
154    printf("static const struct pci_knowndev2 *pci_knowndevs = _pci_knowndevs;\n");
155    printf("static const char *pci_knowndevs_text = _pci_knowndevs_text;\n");
156    printf("#define PCI_STRING_NULL ((%s)-1)\n", stringoff_type);
157    printf("#define PCI_STRING(x) (&pci_knowndevs_text[(x)])\n\n");
158
159
160
161    exit(0);
162}
163
164
165/*
166 * Internalize strings so that duplicates aren't emitted to the string
167 * table.
168 */
169char *istrings[MAXPCIDEVS * 2];
170int nistrings;
171
172static void
173initintern(void)
174{
175    nistrings = 0;
176}
177
178static int
179intern(char *string)
180{
181    int ptr;
182    int si;
183
184    if (!string) return -1;
185
186    /* This is N^2, but will usually hit in the first entry checked if
187       it hits at all.  */
188    for (si = nistrings - 1; si >= 0; si--) {
189      if (strcmp(string, istrings[si]) == 0)
190        return (istrings[si] - stringtable);
191    }
192
193    assert (si < (MAXPCIDEVS * 2));
194
195    ptr = curstringptr;
196    istrings[nistrings++] = &stringtable[ptr];
197
198    strcpy(&stringtable[ptr],string);
199    curstringptr += strlen(string)+1;
200
201    return ptr;
202}
203