⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_serv.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -