📄 pci_serv.c
字号:
int multifunction = FALSE;
USHORT vendid, devid;
ULONG bus, device, function;
UCHAR header_type;
if (vendor_id == 0xffff) return (BAD_VENDOR_ID);
found = 0;
for (bus = 0; bus <= lastbus; bus++)
{
for (device = 0; device < MAX_DEVICE_NUMBER; device++)
{
for (function = 0; function < MAX_FUNCTION_NUMBER; function++)
{
/* before we go beyond function 0, make sure that the
device is truly a multi-function device, otherwise we may
get aliasing */
if (function == 0)
{
sys_read_config_byte (bus,device,function,HEADER_TYPE_OFFSET,&header_type);
if (!(header_type & MULTIFUNCTION_DEVICE))
multifunction = FALSE;
else multifunction = TRUE;
}
/* If no device there, go on to next device */
if ((sys_read_config_word (bus,device,function,VENDOR_ID_OFFSET,&vendid)== ERROR) ||
(sys_read_config_word (bus,device,function,DEVICE_ID_OFFSET,&devid)== ERROR))
{
break; /* go on to next device */
}
/* If not a match */
if ((devid != device_id) || (vendid != vendor_id))
{
if (multifunction == FALSE) break; /* go on to next device */
else continue; /* go on to next function */
}
/* If we've gotten this far we've found a match */
/* check to see if we need to look for another occurrance */
if (index-- != 0)
{
if (multifunction == FALSE) break; /* go on to next device */
else continue; /* go on to next function */
}
/* found the correct occurrance (index) */
else
{
devloc->bus_number = bus;
devloc->device_number = device;
devloc->function_number = function;
return (OK);
}
} /* function */
} /* device */
} /* bus */
/* If we haven't returned by this point, no match was found */
return (DEVICE_NOT_FOUND);
}
/******************************************************************************
* sys_find_pci_class_code - find a PCI device based on a specific Class Code
*
* This function returns the location of PCI devices that have a specific
* Class Code. Given a Class Code and an Index, the function returns the Bus
* Number, Device Number, and Function Number of the Nth Device/Function whose
* Class Code matches the input parameters.
*
* Calling software can find all devices having the same Class Code
* by making successive calls to this function starting with the index set to 0,
* and incrementing the index until the function returns DEVICE_NOT_FOUND.
*
*/
STATUS sys_find_pci_class_code (
int class_code,
int index,
PCI_DEVICE_LOCATION *devloc
)
{
USHORT vendid;
ULONG bus, device, function;
UCHAR dev_class, header_type;
int multifunction = FALSE;
for (bus = 0; bus <= lastbus; bus++)
{
for (device = 0; device <= MAX_DEVICE_NUMBER; device++)
{
for (function = 0; function < MAX_FUNCTION_NUMBER; function++)
{
/* before we go beyond function 0, make sure that the
device is truly a multi-function device, otherwise we may
get aliasing */
if (function == 0)
{
sys_read_config_byte (bus,device,function,HEADER_TYPE_OFFSET,&header_type);
if (!(header_type & MULTIFUNCTION_DEVICE)) multifunction = FALSE;
else multifunction = TRUE;
}
/* If no device there, go on to next device */
if ((sys_read_config_word (bus,device,function,VENDOR_ID_OFFSET,&vendid)== ERROR) ||
(sys_read_config_byte (bus,device,function,BASE_CLASS_OFFSET,&dev_class)== ERROR))
{
break; /* go on to next device */
}
/* If not a match */
if (dev_class != class_code)
{
if (multifunction == FALSE) break; /* go on to next device */
else continue; /* go on to next function */
}
/* If we've gotten this far we've found a match */
/* check to see if we need to look for another occurrance */
if (index-- != 0)
{
if (multifunction == FALSE) break; /* go on to next device */
else continue; /* go on to next function */
}
/* found the correct occurrance (index) */
else
{
devloc->bus_number = bus;
devloc->device_number = device;
devloc->function_number = function;
return (OK);
}
}
}
}
/* If we haven't returned by this point, no match was found */
return (DEVICE_NOT_FOUND);
}
/******************************************************************************
* sys_pci_bios_present - determine if a PCI BIOS is present
*
* This function allows the caller to determine whether the PCI BIOS interface
* function set is present, and what the current interface version level is.
* It also provides information about what hardware mechanism is used for
* accessing configuration space and whether or not the hardware supports
* generation of PCI Special Cycles.
*
*/
STATUS sys_pci_bios_present (PCI_BIOS_INFO *info)
{
/* 0x00 indicates PCI BIOS functions present */
info->present_status = 0x00;
/* Config types 0 or 1, no special cycle mechanisms */
info->hardware_mech_config = CONFIG_MECHANISM_1 | CONFIG_MECHANISM_2;
info->hardware_mech_special = 0x00;
info->if_level_major_ver = 0x02;
info->if_level_minor_ver = 0x01;
info->last_pci_bus = lastbus;
return (OK);
}
/******************************************************************************
* sys_generate_special_cycle - generate a PCI Special Cycle
*
* This function allows for generation of PCI Special Cycles. The generated
* special cycle will be broadcast on a specific PCI Bus in the system.
*
* PCI Special Cycles are not supported by Cyclone Hardware.
*
*/
STATUS sys_generate_special_cycle (int bus_number, int special_cycle_data)
{
return (FUNC_NOT_SUPPORTED);
}
/******************************************************************************
* sys_get_irq_routing_options - get the PCI interrupt routing options
*
* The PCI Interrupt routing fabric on the Cyclone Hardware is not
* reconfigurable (fixed mapping relationships).
*
*/
STATUS sys_get_irq_routing_options (PCI_IRQ_ROUTING_TABLE *table)
{
return (FUNC_NOT_SUPPORTED);
}
/******************************************************************************
* sys_set_pci_irq - connect a PCI interrupt to a processor IRQ.
*
* The PCI Interrupt routing fabric on the Cyclone Hardware is not
* reconfigurable (fixed mapping relationships) and therefore, this function
* is not supported.
*
*/
STATUS sys_set_pci_irq (
int int_pin,
int irq_num,
int bus_dev
)
{
return (FUNC_NOT_SUPPORTED);
}
/******************************************************************************
*
* print_config_space - print contents of config space
*
* This function prints out the contents of the PCI configuration space for
* the selected PCI device. The local RN functions are accessible using bus= -1
* and function=0 for the Bridge and bus = -1 function=1 for the ATU.
*
*/
void print_config_space (int busno, int devno, int function)
{
ULONG offset;
UINT32 long_data;
UINT16 short_data;
UINT8 byte_data;
register PCI_CONFIG_SPACE *cptr = 0;
USHORT vendor_id = 0xffff;
USHORT device_id = 0xffff;
USHORT subvendor_id = 0xffff;
USHORT subdevice_id = 0xffff;
int header_type;
if ((busno > (int)lastbus) || (busno < -1))
{
printf("Invalid bus number = %d\n", busno);
return;
}
if (devno < -1)
{
printf("Invalid device number = %d\n", devno);
return;
}
if ((busno == -1) && (devno == -1) && (function == 0)) /* local Bridge device */
{
cptr = (PCI_CONFIG_SPACE *) VIDR_ADDR;
printf("\n\n\nReading Configuration Space for 80960RN PCI-PCI Bridge\n");
}
else if ((busno == -1) && (devno == -1) && (function == 1)) /* local ATU device */
{
cptr = (PCI_CONFIG_SPACE *) ATUVID_ADDR;
printf("\n\n\nReading Configuration Space for 80960RN ATU\n");
}
if ((busno == -1) && (devno == -1) && (function == 0))
{
/* this is the bridge function */
printf("-----------------------------------------------------------------\n\n");
printf("Vendor ID = 0x%04X ",cptr->pci1_config.vendor_id);
printf("Device ID = 0x%04X\n",cptr->pci1_config.device_id);
printf("Command Register = 0x%04X ",cptr->pci1_config.command);
printf("Status Register = 0x%04X\n",cptr->pci1_config.status);
printf("Revision ID = 0x%02X ",cptr->pci1_config.revision_id);
printf("Programming Interface = 0x%02X\n",cptr->pci1_config.prog_if);
printf("Sub Class = 0x%02X ",cptr->pci1_config.sub_class);
printf("Base Class = 0x%02X\n",cptr->pci1_config.base_class);
printf("Cache Line Size = 0x%02X ",cptr->pci1_config.cache_line_size);
printf("Latency Timer = 0x%02X\n",cptr->pci1_config.latency_timer);
printf("Header Type = 0x%02X ",cptr->pci1_config.header_type);
printf("BIST = 0x%02X\n",cptr->pci1_config.bist);
printf("Primary Bus Number = 0x%02X ",cptr->pci1_config.primary_busno);
printf("Secondary Bus Number = 0x%02X\n",cptr->pci1_config.secondary_busno);
printf("Sub Bus Number = 0x%02X ",cptr->pci1_config.subordinate_busno);
printf("Secondary Latency = 0x%02X\n",cptr->pci1_config.secondary_latency_timer);
printf("Secondary I/O Base = 0x%02X ",cptr->pci1_config.io_base);
printf("Secondary I/O Limit = 0x%02X\n",cptr->pci1_config.io_limit);
printf("Secondary Status = 0x%04X ",cptr->pci1_config.secondary_status);
printf("Secondary Memory Base = 0x%04X\n",cptr->pci1_config.mem_base);
printf("Secondary Mem Limit = 0x%04X ",cptr->pci1_config.mem_limit);
printf("Prefetch Memory Base = 0x%04X\n",cptr->pci1_config.pfmem_base);
printf("Prefetch Memory Limit = 0x%04X ",cptr->pci1_config.pfmem_limit);
printf("I/O Base (Upper) = 0x%04X\n",cptr->pci1_config.iobase_upper16);
printf("I/O Limit (Upper) = 0x%04X ",cptr->pci1_config.iolimit_upper16);
printf("Subsystem Vendor ID = 0x%04X\n",cptr->pci1_config.sub_vendor_id);
printf("Subsystem ID = 0x%04X ",cptr->pci1_config.sub_device_id);
printf("Interrupt Line = 0x%02X\n",cptr->pci1_config.int_line);
printf("Interrupt Pin = 0x%02X ",cptr->pci1_config.int_pin);
printf("Bridge Control = 0x%04X\n",cptr->pci1_config.bridge_control);
printf("PCI Range 0 Base = 0x%08X\n",cptr->pci1_config.pcibase_addr0);
printf("PCI Range 1 Base = 0x%08X\n",cptr->pci1_config.pcibase_addr1);
printf("Prefetch Base (Upper) = 0x%08X\n",cptr->pci1_config.pfbase_upper32);
printf("Prefetch Limit(Upper) = 0x%08X\n",cptr->pci1_config.pflimit_upper32);
printf("Expansion ROM Base = 0x%08X\n",cptr->pci1_config.pcibase_exp_rom);
}
else if ((busno == -1) && (devno == -1) && (function == 1))
{
/* this is the ATU function */
printf("------------------------------------------------------------------\n\n");
printf("Vendor ID = 0x%04X ",cptr->pci0_config.vendor_id);
printf("Device ID = 0x%04X\n",cptr->pci0_config.device_id);
printf("Command Register = 0x%04X ",cptr->pci0_config.command);
printf("Status Register = 0x%04X\n",cptr->pci0_config.status);
printf("Revision ID = 0x%02X ",cptr->pci0_config.revision_id);
printf("Programming Interface = 0x%02X\n",cptr->pci0_config.prog_if);
printf("Sub Class = 0x%02X ",cptr->pci0_config.sub_class);
printf("Base Class = 0x%02X\n",cptr->pci0_config.base_class);
printf("Cache Line Size = 0x%02X ",cptr->pci0_config.cache_line_size);
printf("Latency Timer = 0x%02X\n",cptr->pci0_config.latency_timer);
printf("Header Type = 0x%02X ",cptr->pci0_config.header_type);
printf("BIST = 0x%02X\n",cptr->pci0_config.bist);
printf("Interrupt Line = 0x%02X ",cptr->pci0_config.int_line);
printf("Interrupt Pin = 0x%02X\n",cptr->pci0_config.int_pin);
printf("Minimum Grant = 0x%02X ",cptr->pci0_config.min_gnt);
printf("Maximum Latency = 0x%02X\n",cptr->pci0_config.max_lat);
printf("Subsystem Vendor ID = 0x%04X ",cptr->pci0_config.sub_vendor_id);
printf("Subsystem ID = 0x%04X\n",cptr->pci0_config.sub_device_id);
printf("Base Address 0 = 0x%08X\n",cptr->pci0_config.pcibase_addr0);
printf("Base Address 1 = 0x%08X\n",cptr->pci0_config.pcibase_addr1);
printf("Base Address 2 = 0x%08X\n",cptr->pci0_config.pcibase_addr2);
printf("Base Address 3 = 0x%08X\n",cptr->pci0_config.pcibase_addr3);
printf("Base Address 4 = 0x%08X\n",cptr->pci0_config.pcibase_addr4);
printf("Base Address 5 = 0x%08X\n",cptr->pci0_config.pcibase_addr5);
printf("Cardbus CIS Pointer = 0x%08X\n",cptr->pci0_config.cardbus_cis_ptr);
printf("Expansion ROM Base = 0x%08X\n",cptr->pci0_config.pcibase_exp_rom);
}
else /* device on PCI bus */
{
printf("\n\n\nReading Configuration Space for PCI Bus 0x%02X, Device 0x%02X, Function 0x%02X\n",
busno, devno, function);
printf("------------------------------------------------------------------------\n\n");
/* get Vendor Id */
offset = VENDOR_ID_OFFSET;
if (sys_read_config_word (busno,devno,function,offset,&short_data)
== ERROR)
{
printf("Error reading Vendor Id\n");
return;
}
if (short_data == 0xffff) /* non-existant device */
{
printf("No such device.\n");
return;
}
printf("Vendor ID = 0x%04X ",short_data);
vendor_id = short_data;
/* get Device Id */
offset = DEVICE_ID_OFFSET;
if (sys_read_config_word (busno,devno,function,offset,&short_data)
== ERROR)
{
printf("Error reading Device Id\n");
return;
}
printf("Device ID = 0x%04X\n",short_data);
device_id = short_data;
/* get Command Register */
offset = COMMAND_OFFSET;
if (sys_read_config_word (busno,devno,function,offset,&short_data)
== ERROR)
{
printf("Error reading Command Register\n");
return;
}
printf("Command Register = 0x%04X ",short_data);
/* get Status Register */
offset = STATUS_OFFSET;
if (sys_read_config_word (busno,devno,function,offset,&short_data)
== ERROR)
{
printf("Error reading Status Register\n");
return;
}
printf("Status Register = 0x%04X\n",short_data);
/* get Revision Id */
offset = REVISION_OFFSET;
if (sys_read_config_byte (busno,devno,function,offset,&byte_data)
== ERROR)
{
printf("Error reading Revision Id\n");
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -