1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  PCI Commands				File: ui_pcicmds.c
5    *
6    *  PCI user interface routines
7    *
8    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47
48#include "lib_types.h"
49#include "lib_string.h"
50#include "lib_queue.h"
51#include "lib_malloc.h"
52#include "lib_printf.h"
53
54#include "cfe_iocb.h"
55#include "cfe_device.h"
56#include "cfe_console.h"
57#include "env_subr.h"
58#include "ui_command.h"
59#include "cfe.h"
60
61#include "pcivar.h"
62#include "pcireg.h"
63
64#include "bsp_config.h"
65
66int ui_init_pcicmds(void);
67
68#if CFG_PCI
69static int pci_print_summary(pcitag_t tag)
70{
71    pcireg_t id, class;
72    char devinfo[256];
73
74    class = pci_conf_read(tag, PCI_CLASS_REG);
75    id = pci_conf_read(tag, PCI_ID_REG);
76
77    pci_devinfo(id, class, 1, devinfo);
78    pci_tagprintf (tag, "%s\n", devinfo);
79
80    return 0;
81}
82
83static int pci_print_concise(pcitag_t tag)
84{
85    pci_tagprintf (tag, "\n");
86    pci_conf_print(tag);
87
88    return 0;
89}
90
91static int ui_cmd_pci(ui_cmdline_t *cmd,int argc,char *argv[])
92{
93    char *argp;
94
95    if (cmd_sw_isset(cmd,"-init")) {
96	pci_configure(PCI_FLG_LDT_PREFETCH | PCI_FLG_NORMAL);
97	return 0;
98	}
99
100    argp = cmd_getarg(cmd,0);
101
102    if (argp == NULL) {
103	if (cmd_sw_isset(cmd,"-v")) {
104	    pci_foreachdev(pci_print_concise);
105	    }
106	else {
107	    pci_foreachdev(pci_print_summary);
108	    }
109	}
110    else {
111	/* parse the tuple */
112	int n, port, bus, dev, func;
113	pcitag_t tag;
114	char *p;
115
116	port = bus = dev = func = 0;
117	p = argp;  n = 0;
118
119	while (*p >= '0' && *p <= '9') {
120	    n = n*10 + (*p - '0');
121	    p++;
122	    }
123	if (*p == '/')
124	    bus = n;
125	else  if (*p == ':') {
126	    port = n;
127	    p++;
128	    while (*p >= '0' && *p <= '9') {
129		bus = bus*10 + (*p - '0');
130		p++;
131		}
132	    }
133	else
134	    goto fail;
135	p++;
136	while (*p >= '0' && *p <= '9') {
137	    dev = dev*10 + (*p - '0');
138	    p++;
139	    }
140	if (*p != '/')
141	    goto fail;
142	p++;
143	while (*p >= '0' && *p <= '9') {
144	    func = func*10 + (*p - '0');
145	    p++;
146	    }
147	if (*p != '\000')
148	    goto fail;
149
150	tag = pci_make_tag(port,bus,dev,func);
151
152	pci_print_concise(tag);
153	}
154
155    return 0;
156
157fail:
158    printf("invalid PCI tuple %s\n", argp);
159    return -1;
160}
161
162
163static uint64_t parse_hex(const char *num)
164{
165    uint64_t x = 0;
166    unsigned int digit;
167
168    if ((*num == '0') && (*(num+1) == 'x')) num += 2;
169
170    while (*num) {
171        if ((*num >= '0') && (*num <= '9')) {
172            digit = *num - '0';
173            }
174        else if ((*num >= 'A') && (*num <= 'F')) {
175            digit = 10 + *num - 'A';
176            }
177        else if ((*num >= 'a') && (*num <= 'f')) {
178            digit = 10 + *num - 'a';
179            }
180        else {
181            break;
182            }
183        x *= 16;
184        x += digit;
185        num++;
186        }
187
188    return x;
189}
190
191static int ui_cmd_map_pci(ui_cmdline_t *cmd,int argc,char *argv[])
192{
193    unsigned long offset, size;
194    uint64_t paddr;
195    int l2ca, endian;
196    int enable;
197    int result;
198
199    enable = !cmd_sw_isset(cmd, "-off");
200    if (enable) {
201	offset = parse_hex(cmd_getarg(cmd, 0));
202	size = parse_hex(cmd_getarg(cmd, 1));
203	paddr = parse_hex(cmd_getarg(cmd, 2));
204	l2ca = cmd_sw_isset(cmd,"-l2ca");
205	endian = cmd_sw_isset(cmd, "-matchbits");
206	result = pci_map_window(paddr, offset, size, l2ca, endian);
207	}
208    else {
209	offset = parse_hex(cmd_getarg(cmd, 0));
210	size = parse_hex(cmd_getarg(cmd, 1));
211	result = pci_unmap_window(offset, size);
212	}
213
214    return result;
215}
216#endif
217
218#ifdef CFG_VGACONSOLE
219
220extern int vga_biosinit(void);
221extern int vga_probe(void);
222extern void vgaraw_dump(char *tail);
223
224static int ui_cmd_vgainit(ui_cmdline_t *cmd,int argc,char *argv[])
225{
226    int res;
227
228    if (vga_probe() == 0) {
229	res = vga_biosinit();
230	xprintf("vgabios_init returns %d\n",res);
231	}
232    else
233	xprintf("vga_probe found no suitable adapter\n");
234
235    return 0;
236}
237
238static int ui_cmd_vgadump(ui_cmdline_t *cmd,int argc,char *argv[])
239{
240    char *x;
241
242    x = cmd_getarg(cmd,0);
243    if (x == NULL) x = "";
244    vgaraw_dump(x);
245
246    return 0;
247}
248#endif /* CFG_VGACONSOLE */
249
250
251int ui_init_pcicmds(void)
252{
253
254#if CFG_PCI
255    cmd_addcmd("show pci",
256	       ui_cmd_pci,
257	       NULL,
258	       "Display information about PCI buses and devices",
259	       "show pci [-v] [bus/dev/func]\n\n"
260	       "Displays information about PCI and LDT buses and devices in the\n"
261	       "system.  If you specify a bus/dev/func triplet, only that device\n"
262	       " will be displayed.",
263	       "-v;Display verbose information|"
264	       "-init;Reinitialize and rescan the PCI bus");
265    cmd_addcmd("map pci",
266	       ui_cmd_map_pci,
267	       NULL,
268	       "Define a BAR0 window available to PCI devices",
269	       "map pci offset size paddr [-off] [-l2ca] [-matchbits]\n\n"
270	       "Map the region of size bytes starting at paddr to appear\n"
271	       "at offset relative to BAR0\n",
272	       "-off;Remove the region|"
273	       "-l2ca;Make L2 cachable|"
274	       "-matchbits;Use match bits policy");
275
276#ifdef CFG_VGACONSOLE
277    cmd_addcmd("vga init",
278	       ui_cmd_vgainit,
279	       NULL,
280	       "Initialize the VGA adapter.",
281	       "vgainit",
282	       "");
283    cmd_addcmd("vga dumpbios",
284	       ui_cmd_vgadump,
285	       NULL,
286	       "Dump the VGA BIOS to the console",
287	       "vga dumpbios",
288	       "");
289#endif /* CFG_VGACONSOLE */
290#endif
291    return 0;
292}
293