📄 pci.c
字号:
printf("BAR%d : 0x%08lx", barnum,bar);
}
printf(" Size: 0x");
if (!(implemented & BASEADDRESS_IO) && (implemented & TYPE_64)) {
printf("%08lx%08lx ",sizehi,sizelo);
rtot = 2;
}
else {
printf("%08lx ",sizelo);
rtot = 1;
}
if (bar & BASEADDRESS_IO) {
printf("IO");
}
else {
printf("MEM %sbit",bar & TYPE_64 ? "64" : "32");
}
if (bar & PREFETCHABLE)
printf(" prefetchable");
putchar('\n');
return(rtot);
}
void
dumpRawCfg(long interface,long bus,long device,long func,char *range,
char* varname)
{
int gotone;
long regno;
ulong value;
value = 0;
gotone = 0;
for(regno=0;regno<64;regno++) {
if (inRange(range,regno)) {
value = pciCfgRead(interface,bus,device,func,regno);
printf("Cfg reg #%02ld: 0x%08lx\n",regno,value);
gotone = 1;
}
}
if ((varname) && (gotone))
shell_sprintf(varname,"0x%08lx",value);
}
void
dumpConfig(long interface,long bus,long device,long func)
{
int i;
char *multifunc, *type;
ulong hdrtype, values[16];
for(i=0;i<16;i++)
values[i] = pciCfgRead(interface,bus,device,func,i);
hdrtype = values[3] & HDR_MASK;
if (hdrtype & HDR_MULTIFUNC) {
multifunc = "multi-function ";
hdrtype &= ~HDR_MULTIFUNC;
}
else {
multifunc = "";
}
switch(hdrtype) {
case HDR_PCI2PCI:
type = "PCI-to-PCI";
break;
case HDR_CARDBUS:
type = "CardBus";
break;
case HDR_STANDARD:
type = "Standard";
break;
default:
printf("dumpConfig(): hdrtype 0x%08lx not supported\n",hdrtype);
return;
}
printf("%s %sconfig...\n",type,multifunc);
printf("DevId/VendorId: 0x%04lx/%04lx\n",
(values[0] & 0xffff0000) >> 16,values[0] & 0xffff);
printf("Status/Command: 0x%04lx/%04lx\n",
(values[1] & 0xffff0000) >> 16,values[1] & 0xffff);
printf("ClassCode/RevId: 0x%06lx/%02lx\n",
(values[2] & 0xffffff00) >> 8,values[2] & 0xff);
printf("BIST/HdrType/LatencyTmr/CacheLnSz: 0x%02lx/%02lx/%02lx/%02lx\n",
(values[3] & 0xff000000) >> 24, (values[3] & 0xff0000) >> 16,
(values[3] & 0xff00) >> 8,values[3] & 0xff);
if (showBar(0,interface,bus,device,func) == 1)
showBar(1,interface,bus,device,func);
if (hdrtype == HDR_STANDARD) {
if (showBar(2,interface,bus,device,func) == 1)
showBar(3,interface,bus,device,func);
if (showBar(4,interface,bus,device,func) == 1)
showBar(5,interface,bus,device,func);
printf("Cardbus CIS Ptr: 0x%08lx\n",values[10]);
printf("SubSysId/SubVendorId: 0x%04lx/%04lx\n",
(values[11] & 0xffff0000) >> 16,values[11] & 0xffff);
printf("Expansion ROM BaseAddr: 0x%08lx\n",values[12]);
}
else if (hdrtype == HDR_PCI2PCI) {
printf("Secondary Latency Tmr: 0x%02lx\n",
(values[6] & 0xff000000) >> 24);
printf("BusNum Subordinate/Secondary/Primary: 0x%02lx/%02lx/%02lx\n",
(values[6] & 0xff0000) >> 16,
(values[6] & 0xff00) >> 8,values[6] & 0xff);
printf("Secondary Status: 0x%04lx\n",
(values[7] & 0xffff0000) >> 16);
printf("IO Limit/Base: 0x%02lx/%02lx\n",
(values[7] & 0xff00) >> 8,(values[7] & 0xff));
printf("Memory Limit/Base: 0x%04lx/%04lx\n",
(values[8] & 0xffff0000) >> 16,values[8] & 0xffff);
printf("Prefetchable Memory Limit/Base: 0x%04lx/%04lx\n",
(values[9] & 0xffff0000) >> 16,values[9] & 0xffff);
printf("Prefetchable Base Upper 32 bits: 0x%08lx\n",values[10]);
printf("Prefetchable Limit Upper 32 bits: 0x%08lx\n",values[11]);
printf("IO Upper 16 Bits Limit/Base: 0x%04lx/%04lx\n",
(values[12] & 0xffff0000) >> 16,values[12] & 0xffff);
}
printf("Capabilities Ptr: 0x%02lx\n",values[13] & 0xff);
if (hdrtype == HDR_STANDARD) {
printf("MaxLat/MinGnt: 0x%02lx/%02lx\n",
(values[15] & 0xff000000) >> 24, (values[15] & 0xff0000) >> 16);
}
else {
printf("Expansion ROM BaseAddr: 0x%08lx\n",
values[14]);
printf("BridgeControl: 0x%04lx\n",
(values[15] & 0xffff0000) >> 16);
}
printf("Interrupt Pin/Line: 0x%02lx/%02lx\n",
(values[15] & 0xff00) >> 8, values[15] & 0xff);
}
char *PciHelp[] = {
"PCI Config Interface",
"-[b:d:f:i:v] {operation} [args]",
#if INCLUDE_VERBOSEHELP
"Options:",
" -b{###} bus #",
" -d{###} device #",
" -f{###} function #",
" -i{###} interface #",
" -v verbose",
"Operations:",
" scan, enum, bist, show, size {bar#}",
" crd [reg#] [varname], cwr {reg#} {value}",
"Note:",
" bus, device, function & interface default to zero",
#endif
0
};
/* PciCmd():
* General purpose command to provide access to the config portion of
* a PCI interface.
*
* Notice that there is reference to an "interface number" as well as a
* "bus number". In most systems, there will be one host-to-pci interface.
* and one pci bus. Some targets will have more than one host-to-pci
* interface (galileo 64260A, for example, has 2 distinct host-to-PCI
* interface). Some targets will have more than one bus (depends on whether
* or not there is a pci-to-pci bridge hanging off the bus).
*
*/
int
PciCmd(int argc, char *argv[])
{
ulong value, bar;
long bus, device, interface, regno, func;
int enumerate, opt;
bus = 0;
func = 0;
device = 0;
enumerate = 0;
interface = 0;
pciVerbose = 0;
while ((opt=getopt(argc,argv,"b:d:f:i:v")) != -1) {
switch(opt) {
case 'b':
bus = atoi(optarg);
break;
case 'd':
device = atoi(optarg);
break;
case 'f':
func = atoi(optarg);
break;
case 'i': /* Most systems will only have 1 interface */
interface = atoi(optarg);
break;
case 'v':
pciVerbose = 1;
break;
default:
return(CMD_FAILURE);
}
}
if (argc < optind+1)
return(CMD_PARAM_ERROR);
/* The "scan" and "enum" commands are very similar. They both use
* the pciscan() function.
*
* Scan: look at the devices on the specified bus.
* Enum: a recursive scan... start with bus 0 and attempt to query
* all devices on all busses, making the necessary bus-number assignments
* along the way.
*/
/* For scan, the device number is ignored, all devices on a particular
* interface/bus are checked. If ths bus number is something other than
* zero, then this function assumes that the appropriate pci-to-pci
* bridge device has already had its bus numbers assigned.
*/
if (!strcmp(argv[optind],"scan")) {
if (argc != optind+1)
return(CMD_PARAM_ERROR);
pciscan(interface,bus,func,1,0);
return(CMD_SUCCESS);
}
/* For enum, we start with bus 0, and attempt to enumerate all busses...
*/
if (!strcmp(argv[optind],"enum")) {
if (argc != optind+1)
return(CMD_PARAM_ERROR);
pciscan(interface,0,func,1,1);
return(CMD_SUCCESS);
}
if (!strcmp(argv[optind],"size")) { /* See pg 204 of PCI2.2 spec */
int barnum;
ulong implemented, sizehi, sizelo;
if (argc != optind+2)
return(CMD_PARAM_ERROR);
/* The argument to size is the BAR #. The value can be a single
* digit or a range specification...
*/
printf(" Bar Type Value Size\n");
for(barnum=0;barnum<6;barnum++) {
if (inRange(argv[optind+1],barnum)) {
/* Disable decoding through the command register:
* See section 6.2.2, pg 193.
*/
value = pciCfgRead(interface,bus,device,func,1);
pciCfgWrite(interface,bus,device,0,1,
value & ~(IO_SPACE | MEMORY_SPACE));
bar = pciCfgRead(interface,bus,device,func,barnum+4);
implemented = getBarInfo(interface,bus,device,func,
barnum,&sizehi,&sizelo);
printf(" %d ",barnum);
if (implemented) {
printf("%s 0x%08lx ",
implemented & BASEADDRESS_IO ? "io " : "mem", bar);
if (implemented & TYPE_64)
printf("0x%08lx%08lx",sizehi,sizelo);
else
printf("0x%08lx",sizelo);
if (implemented & PREFETCHABLE)
printf(" (prefetchable)");
putchar('\n');
}
else
printf("not implemented\n");
}
}
}
else if (!strcmp(argv[optind],"bist")) {
if (argc != optind+1)
return(CMD_PARAM_ERROR);
value = pciCfgRead(interface,bus,device,func,3);
if (value & BIST_CAPABLE) {
/* Set the BIST_START bit to begin the test, then wait for
* the BIST_START bit to clear as an indication that the
* test has completed.
*/
pciCfgWrite(interface,bus,device,func,3,value | BIST_START);
while(1) {
value = pciCfgRead(interface,bus,device,func,3);
if ((value & BIST_START) != BIST_START)
break;
}
if ((value & BIST_COMPCODE_MASK) != 0)
printf("BIST failed: 0x%lx\n",value & BIST_COMPCODE_MASK);
else
printf("BIST passed\n");
}
else {
printf("Device %ld is not BIST-capable\n",device);
}
}
else if (!strcmp(argv[optind],"crd")) {
char *varname = (char *)0;
if (argc == optind+3) { /* varname specified ? */
varname = argv[optind+2];
argc--;
}
if (argc == optind+2) {
dumpRawCfg(interface,bus,device,func,argv[optind+1],varname);
}
else if (argc == optind+1) {
dumpConfig(interface,bus,device,func);
}
else
return(CMD_PARAM_ERROR);
}
else if (!strcmp(argv[optind],"cwr")) {
if (argc != optind+3)
return(CMD_PARAM_ERROR);
regno = atoi(argv[optind+1]);
value = strtol(argv[optind+2],0,0);
pciCfgWrite(interface,bus,device,func,regno,value);
}
else if (!strcmp(argv[optind],"init")) {
pciCtrl(interface,PCICTRL_INIT,0,0);
}
else if (!strcmp(argv[optind],"show")) {
pciShow(interface);
}
else
return(CMD_PARAM_ERROR);
return(CMD_SUCCESS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -