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

📄 pci.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 3 页
字号:
	pcii->u.h1.secondary_bus =       read_pci_config(bus, dev, func, PCI_secondary_bus, 1);	pcii->u.h1.secondary_latency =   read_pci_config(bus, dev, func, PCI_secondary_latency, 1);	pcii->u.h1.secondary_status =    read_pci_config(bus, dev, func, PCI_secondary_status, 2);	pcii->u.h1.subordinate_bus =     read_pci_config(bus, dev, func, PCI_subordinate_bus, 1);	pcii->u.h1.memory_base =         read_pci_config(bus, dev, func, PCI_memory_base, 2);	pcii->u.h1.memory_limit =        read_pci_config(bus, dev, func, PCI_memory_limit, 2);	pcii->u.h1.prefetchable_memory_base =  read_pci_config(bus, dev, func, PCI_prefetchable_memory_base, 2);	pcii->u.h1.prefetchable_memory_limit = read_pci_config(bus, dev, func, PCI_prefetchable_memory_limit, 2);	pcii->u.h1.bridge_control =      read_pci_config(bus, dev, func, PCI_bridge_control, 1);	pcii->u.h1.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_sub_vendor_id_1, 2);	pcii->u.h1.subsystem_id        = read_pci_config(bus, dev, func, PCI_sub_device_id_1, 2);	pcii->u.h1.interrupt_line =      read_pci_config(bus, dev, func, PCI_interrupt_line, 1);	pcii->u.h1.interrupt_pin =       read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask;	{		struct pci_device *pd = pci_devices;		while (pd && pd->next)			pd = pd->next;		if (pd)			pd->next = pcid;		else			pci_devices = pcid;	}	{		struct pci_bus *pb = pci_busses;		while (pb && pb->next)			pb = pb->next;		if (pb)			pb->next = pcib;		else			pci_busses = pcib;	}	show_pci_details(pcii);pci_bridge_skip_infolist:	command |= 0x03;	write_pci_config(bus, dev, func, PCI_command, 2, command);	return;}/** This is a very, very brief 2 liner for a device... */static voiddebug_show_device(pci_info *pcii){	uint16 status = read_pci_config(pcii->bus, pcii->device, pcii->function, PCI_status, 2);	dprintf("device @ %d:%d:%d > %s [%04x:%04x]\n", pcii->bus, pcii->device,	        pcii->function,	        decode_class(pcii->class_base, pcii->class_sub),	        pcii->vendor_id, pcii->device_id);	if ((status & PCI_status_capabilities)) {		dprintf("Capabilities: ");		if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_agp, NULL))			dprintf("AGP ");		if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_pm, NULL))			dprintf("Pwr Mgmt ");		if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_vpd, NULL))			dprintf("VPD ");		if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_slotid, NULL))			dprintf("slotID ");		if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_msi, NULL))			dprintf("MSI ");		if (pci_get_capability(pcii->bus, pcii->device, pcii->function, PCI_cap_id_hotplug, NULL))			dprintf("hotplug ");		dprintf("\n");	} else		dprintf("\t(No capabilities exist for this device)\n");}static voidpci_device_probe(uint8 bus, uint8 dev, uint8 func){	uint8 base_class, sub_class;	uint8 type;	pci_info *pcii;	struct pci_device *pcid;	TRACE(("pci_device_probe()\n"));	if (func > 0) {		uint16 vend = read_pci_config(bus, dev, func, PCI_vendor_id, 2);		if (vend == 0xffff)			return;	}	type = read_pci_config(bus, dev, func, PCI_header_type, 1);	type &= PCI_header_type_mask;	base_class = read_pci_config(bus, dev, func, PCI_class_base, 1);	sub_class  = read_pci_config(bus, dev, func, PCI_class_sub, 1);	if (base_class == PCI_bridge) {		fixup_bridge(bus, dev, func);		if (sub_class == PCI_pci) {			pci_bridge(bus, dev, func);			return;		}	}	/* If we get here then it's not a bridge, so we add it... */	pcii = (pci_info *)kmalloc(sizeof(pci_info));	if (!pcii)		return;	pcid = (struct pci_device *)kmalloc(sizeof(struct pci_device));	if (!pcid) {		kfree(pcii);		return;	}	pcid->info = pcii;	pcid->type = PCI_DEVICE;	pcid->next = NULL;	pcii->bus = bus;	pcii->device = dev;	pcii->function = func;	fill_basic_pci_structure(pcii);	if (pcii->class_base == PCI_bridge && pcii->class_sub == PCI_host)		pcid->type = PCI_HOST_BUS;	pcii->u.h0.cardbus_cis =         read_pci_config(bus, dev, func, PCI_cardbus_cis, 4);	pcii->u.h0.subsystem_id =        read_pci_config(bus, dev, func, PCI_subsystem_id, 2);	pcii->u.h0.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_subsystem_vendor_id, 2);	pcii->u.h0.rom_base_pci =        read_pci_config(bus, dev, func, PCI_rom_base, 4);	pcii->u.h0.interrupt_line =      read_pci_config(bus, dev, func, PCI_interrupt_line, 1);	pcii->u.h0.interrupt_pin =       read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask;	pcii->u.h0.max_latency =         read_pci_config(bus, dev, func, PCI_max_latency, 1);	pcii->u.h0.min_grant =           read_pci_config(bus, dev, func, PCI_min_grant, 1);	/* now add to list (at end) */	{		struct pci_device *pd = pci_devices;		while (pd && pd->next)			pd = pd->next;		if (pd)			pd->next = pcid;		else			pci_devices = pcid;	}	pci_set_power_state(bus, dev, func, PCI_pm_state_d0);	// if the device appears to want to be a bus master, we'll set	// it as one.	// XXX This may not be the right place to do this, but as nowhere else	//     seems to attempt to do configuration of the device beyond powering	//     up, and that's done here, it seems like as good a place as any.	if (pcii->u.h0.max_latency != 0 && pcii->u.h0.min_grant != 0)		pci_set_bus_master(bus, dev, func);	debug_show_device(pcii);}/**	Scan a bus for PCI devices. For each device that's a possible *	we get the vendor_id. If it's 0xffff then it's not a valid *	device so we move on. *	Valid devices then have their header_type checked to detrmine how *	many functions we need to check. However, some devices that support *	multiple functions have a header_type of 0 (generic) so we also check *	for these using pci_quirk_multifunction(). *	If it's a multifunction device we scan all 8 possible functions, *	otherwise we just probe the first one. */static voidpci_scan_bus(uint8 bus){	uint8 dev = 0, func = 0;	uint16 vend = 0;	TRACE(("pci_scan_bus()\n"));	for (dev = 0; dev < 32; dev++) {		vend = read_pci_config(bus, dev, 0, PCI_vendor_id, 2);		if (vend != 0xffff) {			uint16 device = read_pci_config(bus, dev, func, PCI_device_id, 2);			uint8 type = read_pci_config(bus, dev, func, PCI_header_type, 1);			uint8 nfunc = 8;			type &= PCI_header_type_mask;			if ((type & PCI_multifunction) == 0				&& !pci_quirk_multifunction(vend, device))				nfunc = 1;			for (func = 0; func < nfunc; func++)				pci_device_probe(bus, dev, func);		}	}}// unused#if 0static voidscan_pci(void){	int bus, dev, func;	TRACE(("scan_pci()\n"));	/* We can have up to 255 busses */	for (bus = 0; bus < 255; bus++) {		/* Each bus can have up to 'bus_max_devices' devices on it */		for (dev = 0; dev <= bus_max_devices; dev++) {			/* Each device can have up to 8 functions */			uint16 sv_vendor_id = 0, sv_device_id = 0;			for (func = 0; func < 8; func++) {				pci_info *pcii = NULL;				uint16 vendor_id = read_pci_config(bus, dev, func, 0, 2);				uint16 device_id;				uint8 offset;				/* If we get 0xffff then there is no device here. As there can't				 * be any gaps in function allocation this tells us that we				 * can move onto the next device/bus				 */				if (vendor_id == 0xffff)					break;				device_id = read_pci_config(bus, dev, func, PCI_device_id, 2);				/* Is this a new device? As we're scanning the functions here, many devices				 * will supply identical information for all 8 accesses! Try to catch this and				 * simply move past duplicates. We need to continue scanning in case we miss				 * a different device at the end.				 * XXX - is this correct????				 */				if (vendor_id == sv_vendor_id && sv_device_id == device_id) {					/* It's a duplicate */					continue;				}				sv_vendor_id = vendor_id;				sv_device_id = device_id;				/* At present we will add a device to our list if we get here,				 * but we may want to review if we need to add 8 version of the				 * same device if only the functions differ?				 */				if ((pcii = (pci_info *)kmalloc(sizeof(pci_info))) == NULL) {					dprintf("Failed to get memory for a pic_info structure in scan_pci\n");					return;				}				if (pci_get_capability(bus, dev, func, PCI_cap_id_agp, &offset))					dprintf("Device @ %d:%d:%d has AGP capability\n", bus, dev, func);				pci_set_power_state(bus, dev, func, PCI_pm_state_d0);				/* basic header */				pcii->bus = bus;				pcii->device = dev;				pcii->function = func;				pcii->vendor_id = vendor_id;				pcii->device_id = device_id;				pcii->revision =    read_pci_config(bus, dev, func, PCI_revision, 1);				pcii->class_api =   read_pci_config(bus, dev, func, PCI_class_api, 1);				pcii->class_sub =   read_pci_config(bus, dev, func, PCI_class_sub, 1);				pcii->class_base =  read_pci_config(bus, dev, func, PCI_class_base, 1);				pcii->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1);				pcii->header_type &= PCI_header_type_mask;			}		}	}}#endifstatic voidfill_basic_pci_structure(pci_info *pcii){	uint8 bus = pcii->bus, dev = pcii->device, func = pcii->function;	uint8 int_line = 0, int_pin = 0;	int i;	pcii->vendor_id =   read_pci_config(bus, dev, func, PCI_vendor_id, 2);	pcii->device_id =   read_pci_config(bus, dev, func, PCI_device_id, 2);	pcii->revision =    read_pci_config(bus, dev, func, PCI_revision, 1);	pcii->class_api =   read_pci_config(bus, dev, func, PCI_class_api, 1);	pcii->class_sub =   read_pci_config(bus, dev, func, PCI_class_sub, 1);	pcii->class_base =  read_pci_config(bus, dev, func, PCI_class_base, 1);	pcii->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1);	pcii->header_type &= PCI_header_type_mask;	pcii->latency =     read_pci_config(bus, dev, func, PCI_latency, 1);	pcii->bist =        read_pci_config(bus, dev, func, PCI_bist, 1);	pcii->line_size =   read_pci_config(bus, dev, func, PCI_line_size, 1);	if(pcii->header_type == 0) {		for(i = 0; i < 6; i++) {			uint32 temp, temp2;			temp = read_pci_config(bus, dev, func, PCI_base_registers + i*4, 4);			if(temp) {				write_pci_config(bus, dev, func, PCI_base_registers + i*4, 4, 0xffffffff);				temp2 = read_pci_config(bus, dev, func, PCI_base_registers + i*4, 4) & 0xfffffff0;				write_pci_config(bus, dev, func, PCI_base_registers + i*4, 4, temp);				temp2 = 1 + ~temp2;				if(temp & 1) {					pcii->u.h0.base_registers[i] = temp & 0xfff0;					pcii->u.h0.base_register_sizes[i] = temp2 & 0xffff;				} else {					pcii->u.h0.base_registers[i] = temp & 0xfffffff0;					pcii->u.h0.base_register_sizes[i] = temp2;				}			} else {				pcii->u.h0.base_registers[i] = 0;				pcii->u.h0.base_register_sizes[i] = 0;			}//			dprintf("basereg %d:%d:%d 0x%x\n", bus, dev, func, pcii->u.h0.base_registers[i]);//			dprintf("size    %d:%d:%d 0x%x\n", bus, dev, func, pcii->u.h0.base_register_sizes[i]);		}	}	int_line =          read_pci_config(bus, dev, func, PCI_interrupt_line, 1);	int_pin =           read_pci_config(bus, dev, func, PCI_interrupt_pin, 1);	int_pin &= PCI_pin_mask;}static longget_nth_pci_info(long index, pci_info *copyto){	struct pci_device *pd = pci_devices;	while (index-- > 0 && pd)		pd = pd->next;	if (index > 0 || !pd || !pd->info)		return ERR_NOT_FOUND;	TRACE(("pci_nth_pci_info: returning %d:%d:%d\n", pd->info->bus, pd->info->device, pd->info->function));	memcpy(copyto, pd->info, sizeof(pci_info));	return 0;}/* I/O routines */static uint8pci_read_io_8(int mapped_io_addr){	return in8(mapped_io_addr);}static voidpci_write_io_8(int mapped_io_addr, uint8 value){	out8(value, mapped_io_addr);}static uint16pci_read_io_16(int mapped_io_addr){	return in16(mapped_io_addr);}static voidpci_write_io_16(int mapped_io_addr, uint16 value){	out16(value, mapped_io_addr);}static uint32pci_read_io_32(int mapped_io_addr ){	return in32(mapped_io_addr);}static voidpci_write_io_32(int mapped_io_addr, uint32 value){	out32(value, mapped_io_addr);}/* pci_module_init * This is where we start all the PCI work, or not as the case may be. * We start by trying to detect and set the correct configuration mechanism * to use. We don't handle PCI BIOS's as that method seems to be falling out * of fashion and is Intel specific. * * Next we try to check if we have working PCI on this machine. check_pci() * isn't the smartest routine as it essentially just looks for a Host-PCI * bridge, but it will show us if we can continue. * NB Until this has been tested with a wider audience we don't consider *    success/failure here but spew a large debug message and try to continue. * XXX - once we're happy with check_pci() make failing a criminal offense! * * Next we check to see if we can find a PIR table. * NB This is Intel specific and currently included here as a test. * * Finally we scan for devices starting at bus 0. */static intpci_module_init(void){	struct pir_table *pirt = NULL;	TRACE(("pci_module_init()\n"));	if (set_pci_mechanism() == -1) {		return -1;	}	check_pci();	pci_region = vm_map_physical_memory(vm_get_kernel_aspace_id(),	                                    "pci_bios", &pci_bios_ptr,	                                    REGION_ADDR_ANY_ADDRESS,	                                    0x10000,	                                    LOCK_RO | LOCK_KERNEL,	                                    (addr_t)0xf0000);	pirt = find_pir_table();	if (pirt) {		dprintf("PCI IRQ Routing table found\n");#if TRACE_PCI		print_pir_table(pirt);#endif	}	pci_scan_bus(0);	return 0;}/**	Finish the module by releasing the memory we grabbed for *	the pci_bios :) */static intpci_module_uninit(void){	vm_delete_region(vm_get_kernel_aspace_id(), pci_region);	return 0;}static struct pci_module_hooks pci_mod_hooks = {	&pci_read_io_8,	&pci_write_io_8,	&pci_read_io_16,	&pci_write_io_16,	&pci_read_io_32,	&pci_write_io_32,	&get_nth_pci_info,	&read_pci_config,	&write_pci_config,	NULL,	//	&ram_address};static module_header pci_module_header = {	PCI_BUS_MODULE_NAME,	MODULE_CURR_VERSION,	MODULE_KEEP_LOADED,	&pci_mod_hooks,	&pci_module_init,	&pci_module_uninit};module_header *modules[]  = {	&pci_module_header,	NULL};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -