297 lines
9.7 KiB
C
297 lines
9.7 KiB
C
/*++
|
|
|
|
Copyright (c) 1999 Intel Corporation
|
|
|
|
Module Name:
|
|
|
|
pci.c
|
|
|
|
Abstract:
|
|
|
|
|
|
|
|
|
|
Revision History
|
|
|
|
--*/
|
|
|
|
#include "shelle.h"
|
|
#include "pci22.h"
|
|
|
|
EFI_STATUS
|
|
PciDump (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
);
|
|
|
|
#define HEADER_TYPE_MULTI_FUNCTION 0x80
|
|
|
|
|
|
typedef struct _PCI_CLASS_CODE {
|
|
UINT8 Class;
|
|
CHAR16 *Str;
|
|
struct _PCI_CLASS_CODE *SubClass;
|
|
} PCI_CLASS_CODE;
|
|
|
|
|
|
VOID
|
|
PciPrintClassCode (
|
|
IN PCI_DEVICE_INDEPENDENT_REGION *Pci
|
|
);
|
|
|
|
|
|
PCI_CLASS_CODE PciMassStoreSubClass[] = {
|
|
0x00, L"SCSI Bus", NULL,
|
|
0x01, L"IDE", NULL,
|
|
0x02, L"Floppy", NULL,
|
|
0x03, L"IPI", NULL,
|
|
0x04, L"RAID", NULL,
|
|
0x80, L"Other", NULL,
|
|
0xff, L"ERROR", NULL
|
|
};
|
|
|
|
PCI_CLASS_CODE PciNetworkSubClass[] = {
|
|
0x00, L"Ethernet", NULL,
|
|
0x01, L"Token Ring", NULL,
|
|
0x02, L"FDDI", NULL,
|
|
0x03, L"ATM", NULL,
|
|
0x80, L"Other", NULL,
|
|
0xff, L"ERROR", NULL
|
|
};
|
|
|
|
PCI_CLASS_CODE PciDisplayControllerClass[] = {
|
|
0x00, L"VGA", NULL,
|
|
0x01, L"XVGA", NULL,
|
|
0x02, L"3D", NULL,
|
|
0x80, L"Other", NULL,
|
|
0xff, L"ERROR", NULL
|
|
};
|
|
|
|
PCI_CLASS_CODE PciBridgeSubClass[] = {
|
|
0x00, L"Host", NULL,
|
|
0x01, L"ISA", NULL,
|
|
0x02, L"EISA", NULL,
|
|
0x03, L"MC", NULL,
|
|
0x04, L"PCI to PCI", NULL,
|
|
0x05, L"PCMCIA", NULL,
|
|
0x06, L"NuBus", NULL,
|
|
0x07, L"CardBus", NULL,
|
|
0x08, L"RACEway", NULL,
|
|
0xff, L"ERROR", NULL
|
|
};
|
|
|
|
PCI_CLASS_CODE PciSysPeriphSubClass[] = {
|
|
0x00, L"Interrupt Controller", NULL,
|
|
0x01, L"DMA", NULL,
|
|
0x02, L"System Timer", NULL,
|
|
0x03, L"RTC", NULL,
|
|
0x80, L"Other", NULL,
|
|
0xff, L"ERROR", NULL
|
|
};
|
|
|
|
PCI_CLASS_CODE PciSerialBusSubClass[] = {
|
|
0x00, L"1394", NULL,
|
|
0x01, L"ACCESS Bus", NULL,
|
|
0x02, L"SSA", NULL,
|
|
0x03, L"USB", NULL,
|
|
0x04, L"Fibre Channel", NULL,
|
|
0x05, L"SMBus", NULL,
|
|
0x80, L"Other", NULL,
|
|
0xff, L"ERROR", NULL
|
|
};
|
|
|
|
/*
|
|
* BugBug: I got tired of typing, so this is only partial PCI info.
|
|
*/
|
|
PCI_CLASS_CODE PciClassCodes[] = {
|
|
0x00, L"Backward Compatible", NULL,
|
|
0x01, L"Mass Storage Controller", PciMassStoreSubClass,
|
|
0x02, L"Network Controller", PciNetworkSubClass,
|
|
0x03, L"Display Controller", PciDisplayControllerClass,
|
|
0x04, L"Multimedia Device", NULL,
|
|
0x05, L"Memory Controller", NULL,
|
|
0x06, L"PCI Bridge Device", PciBridgeSubClass,
|
|
0x07, L"Communications Controller", NULL,
|
|
0x08, L"Generic System Peripheral", PciSysPeriphSubClass,
|
|
0x09, L"Input Devices", NULL,
|
|
0x0a, L"Docking Stations", NULL,
|
|
0x0b, L"Processors", NULL,
|
|
0x0c, L"Serial Bus Controller", PciSerialBusSubClass,
|
|
0x0d, L"Wireless Controller", NULL,
|
|
0x0e, L"I2O", NULL,
|
|
0x0f, L"Satellite Controller", NULL,
|
|
0x10, L"Encryption Controller", NULL,
|
|
0x11, L"Data Acquisition", NULL,
|
|
0xff, L"No Class", NULL
|
|
};
|
|
|
|
|
|
VOID
|
|
PciPrintClassCode (
|
|
IN PCI_DEVICE_INDEPENDENT_REGION *Pci
|
|
)
|
|
{
|
|
UINT16 *BaseClass, *SubClass;
|
|
UINTN i,j;
|
|
PCI_CLASS_CODE *ClassTable;
|
|
|
|
BaseClass = SubClass = NULL;
|
|
for (i=0; PciClassCodes[i].Class != 0xff; i++) {
|
|
if (Pci->ClassCode[2] == PciClassCodes[i].Class) {
|
|
BaseClass = PciClassCodes[i].Str;
|
|
if (PciClassCodes[i].SubClass) {
|
|
ClassTable = PciClassCodes[i].SubClass;
|
|
for (j=0; ClassTable->Class != 0xff; j++, ClassTable++) {
|
|
if (Pci->ClassCode[1] == ClassTable->Class) {
|
|
SubClass = ClassTable->Str;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Print (L"%s - %s", BaseClass, (SubClass == NULL ? L"" : SubClass));
|
|
}
|
|
|
|
EFI_DRIVER_ENTRY_POINT(PciDump)
|
|
|
|
EFI_STATUS
|
|
PciDump (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
/*+++
|
|
|
|
pci [bus dev] [func]
|
|
|
|
---*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Buffer[64];
|
|
EFI_DEVICE_IO_INTERFACE *IoDev;
|
|
UINT64 Address, FuncAddress;
|
|
UINT16 Bus, Device, Func;
|
|
EFI_HANDLE Handle;
|
|
EFI_DEVICE_PATH *DevicePath;
|
|
PCI_DEVICE_INDEPENDENT_REGION PciHeader;
|
|
PCI_CONFIG_ACCESS_CF8 Pci;
|
|
DEFIO_PCI_ADDR Defio;
|
|
UINTN ScreenCount;
|
|
UINTN TempColumn;
|
|
UINTN ScreenSize;
|
|
CHAR16 ReturnStr[1];
|
|
|
|
InstallInternalShellCommand (
|
|
ImageHandle, SystemTable, PciDump,
|
|
L"pci", /* command */
|
|
L"pci [bus dev] [func]", /* command syntax */
|
|
L"Display PCI device(s) info", /* 1 line descriptor */
|
|
NULL /* command help page */
|
|
);
|
|
|
|
|
|
InitializeShellApplication (ImageHandle, SystemTable);
|
|
|
|
/*
|
|
* The End Device Path represents the Root of the tree, thus get the global IoDev
|
|
* for the system
|
|
*/
|
|
DevicePath = EndDevicePath;
|
|
Status = BS->LocateDevicePath (&DeviceIoProtocol, &DevicePath, &Handle);
|
|
if (!EFI_ERROR(Status)) {
|
|
Status = BS->HandleProtocol (Handle, &DeviceIoProtocol, (VOID*)&IoDev);
|
|
}
|
|
if (EFI_ERROR(Status)) {
|
|
Print (L"%E - handle protocol error %r%N", Status);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if ( SI->Argc < 3 ) {
|
|
ST->ConOut->QueryMode (ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
|
|
ScreenCount = 0;
|
|
|
|
Print (L"\n Bus Dev Func");
|
|
Print (L"\n --- --- ----");
|
|
ScreenSize -= 4;
|
|
|
|
for (Bus = 0; Bus <= PCI_MAX_BUS; Bus++) {
|
|
for (Device = 0; Device < 32; Device++) {
|
|
Address = (Bus << 24) + (Device << 16);
|
|
for (Func = 0; Func < 8; Func++) {
|
|
FuncAddress = Address + (Func << 8);
|
|
IoDev->Pci.Read (IoDev, IO_UINT16, FuncAddress, 1, &PciHeader.VendorId);
|
|
if (PciHeader.VendorId != 0xffff) {
|
|
IoDev->Pci.Read (IoDev, IO_UINT32, FuncAddress, sizeof(PciHeader)/sizeof(UINT32), &PciHeader);
|
|
Print (L"%E");
|
|
Print (L"\n %02x %02x %02x ==> %N", Bus, Device, Func);
|
|
PciPrintClassCode (&PciHeader);
|
|
Print (L"\n Vendor 0x%04x Device 0x%04x Prog Interface %x", PciHeader.VendorId, PciHeader.DeviceId, PciHeader.ClassCode[0]);
|
|
if (Func == 0) {
|
|
if ((PciHeader.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00) {
|
|
/*
|
|
* If this is not a multifucntion device leave the loop
|
|
*/
|
|
Func = 8;
|
|
}
|
|
}
|
|
ScreenCount += 2;
|
|
if (ScreenCount >= ScreenSize && ScreenSize != 0) {
|
|
/*
|
|
* If ScreenSize == 0 we have the console redirected so don't
|
|
* block updates
|
|
*/
|
|
ScreenCount = 0;
|
|
Print (L"\nPress Return to contiue :");
|
|
Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
|
|
Print (L"\n Bus Dev Func");
|
|
Print (L"\n --- --- ----");
|
|
}
|
|
} else {
|
|
/*
|
|
* If Func 0 does not exist there are no sub fucntions
|
|
*/
|
|
Func = 8;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Print (L"\n");
|
|
return EFI_SUCCESS;
|
|
}
|
|
Bus = (UINT16) xtoi(SI->Argv[1]);
|
|
Device = (UINT16) xtoi(SI->Argv[2]);
|
|
if (SI->Argc > 3) {
|
|
Func = (UINT16) xtoi(SI->Argv[3]);
|
|
} else {
|
|
Func = 0;
|
|
}
|
|
|
|
Address = (Bus << 24) + (Device << 16) + (Func << 8);
|
|
CopyMem (&Defio, &Address, sizeof(Address));
|
|
Pci.Reg = Defio.Register;
|
|
Pci.Func = Defio.Function;
|
|
Pci.Dev = Defio.Device;
|
|
Pci.Bus = Defio.Bus;
|
|
Pci.Reserved = 0;
|
|
Pci.Enable = 1;
|
|
|
|
Print (L"%H PCI Bus %02x Device %02x Func %02x%N [0xcf8(0x%08x) EFI 0x00%02x%02x%02x00]\n", Bus, Device, Func, Pci, Bus, Device, Func);
|
|
|
|
/*
|
|
* Dump standard header
|
|
*/
|
|
IoDev->Pci.Read (IoDev, IO_UINT32, Address, 16, Buffer);
|
|
DumpHex (2, 0, 16*sizeof(UINT32), Buffer);
|
|
Print(L"\n");
|
|
|
|
/*
|
|
* Dump Device Dependent Header
|
|
*/
|
|
IoDev->Pci.Read (IoDev, IO_UINT32, Address + 0x40, 48, Buffer);
|
|
DumpHex (2, 0x40, 48*sizeof(UINT32), Buffer);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|