hw/pci-assign: split pci-assign.c
We will try to reuse assign_dev_load_option_rom in xen side, and especially its a good beginning to unify pci assign codes both on kvm and xen in the future. [Fix build for Windows] Signed-off-by: Tiejun Chen <tiejun.chen@intel.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Acked-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
		
							parent
							
								
									595a4f07d6
								
							
						
					
					
						commit
						bcd7461e7e
					
				| @ -7,6 +7,7 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/ | ||||
| 
 | ||||
| obj-y += kvmvapic.o | ||||
| obj-y += acpi-build.o | ||||
| obj-y += pci-assign-load-rom.o | ||||
| 
 | ||||
| gen-hex-y += hw/i386/acpi-dsdt.hex | ||||
| gen-hex-y += hw/i386/q35-acpi-dsdt.hex | ||||
|  | ||||
| @ -37,6 +37,7 @@ | ||||
| #include "hw/pci/pci.h" | ||||
| #include "hw/pci/msi.h" | ||||
| #include "kvm_i386.h" | ||||
| #include "hw/pci/pci-assign.h" | ||||
| 
 | ||||
| #define MSIX_PAGE_SIZE 0x1000 | ||||
| 
 | ||||
| @ -48,17 +49,6 @@ | ||||
| #define IORESOURCE_PREFETCH 0x00002000  /* No side effects */ | ||||
| #define IORESOURCE_MEM_64   0x00100000 | ||||
| 
 | ||||
| //#define DEVICE_ASSIGNMENT_DEBUG
 | ||||
| 
 | ||||
| #ifdef DEVICE_ASSIGNMENT_DEBUG | ||||
| #define DEBUG(fmt, ...)                                       \ | ||||
|     do {                                                      \ | ||||
|         fprintf(stderr, "%s: " fmt, __func__ , __VA_ARGS__);  \ | ||||
|     } while (0) | ||||
| #else | ||||
| #define DEBUG(fmt, ...) | ||||
| #endif | ||||
| 
 | ||||
| typedef struct PCIRegion { | ||||
|     int type;           /* Memory or port I/O */ | ||||
|     int valid; | ||||
| @ -1896,73 +1886,15 @@ static void assign_register_types(void) | ||||
| 
 | ||||
| type_init(assign_register_types) | ||||
| 
 | ||||
| /*
 | ||||
|  * Scan the assigned devices for the devices that have an option ROM, and then | ||||
|  * load the corresponding ROM data to RAM. If an error occurs while loading an | ||||
|  * option ROM, we just ignore that option ROM and continue with the next one. | ||||
|  */ | ||||
| static void assigned_dev_load_option_rom(AssignedDevice *dev) | ||||
| { | ||||
|     char name[32], rom_file[64]; | ||||
|     FILE *fp; | ||||
|     uint8_t val; | ||||
|     struct stat st; | ||||
|     void *ptr; | ||||
|     int size = 0; | ||||
| 
 | ||||
|     /* If loading ROM from file, pci handles it */ | ||||
|     if (dev->dev.romfile || !dev->dev.rom_bar) { | ||||
|         return; | ||||
|     pci_assign_dev_load_option_rom(&dev->dev, OBJECT(dev), &size, | ||||
|                                    dev->host.domain, dev->host.bus, | ||||
|                                    dev->host.slot, dev->host.function); | ||||
| 
 | ||||
|     if (!size) { | ||||
|         error_report("pci-assign: Invalid ROM."); | ||||
|     } | ||||
| 
 | ||||
|     snprintf(rom_file, sizeof(rom_file), | ||||
|              "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom", | ||||
|              dev->host.domain, dev->host.bus, dev->host.slot, | ||||
|              dev->host.function); | ||||
| 
 | ||||
|     if (stat(rom_file, &st)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (access(rom_file, F_OK)) { | ||||
|         error_report("pci-assign: Insufficient privileges for %s", rom_file); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     /* Write "1" to the ROM file to enable it */ | ||||
|     fp = fopen(rom_file, "r+"); | ||||
|     if (fp == NULL) { | ||||
|         return; | ||||
|     } | ||||
|     val = 1; | ||||
|     if (fwrite(&val, 1, 1, fp) != 1) { | ||||
|         goto close_rom; | ||||
|     } | ||||
|     fseek(fp, 0, SEEK_SET); | ||||
| 
 | ||||
|     snprintf(name, sizeof(name), "%s.rom", | ||||
|             object_get_typename(OBJECT(dev))); | ||||
|     memory_region_init_ram(&dev->dev.rom, OBJECT(dev), name, st.st_size, | ||||
|                            &error_abort); | ||||
|     vmstate_register_ram(&dev->dev.rom, &dev->dev.qdev); | ||||
|     ptr = memory_region_get_ram_ptr(&dev->dev.rom); | ||||
|     memset(ptr, 0xff, st.st_size); | ||||
| 
 | ||||
|     if (!fread(ptr, 1, st.st_size, fp)) { | ||||
|         error_report("pci-assign: Cannot read from host %s", rom_file); | ||||
|         error_printf("Device option ROM contents are probably invalid " | ||||
|                      "(check dmesg).\nSkip option ROM probe with rombar=0, " | ||||
|                      "or load from file with romfile=\n"); | ||||
|         goto close_rom; | ||||
|     } | ||||
| 
 | ||||
|     pci_register_bar(&dev->dev, PCI_ROM_SLOT, 0, &dev->dev.rom); | ||||
|     dev->dev.has_rom = true; | ||||
| close_rom: | ||||
|     /* Write "0" to disable ROM */ | ||||
|     fseek(fp, 0, SEEK_SET); | ||||
|     val = 0; | ||||
|     if (!fwrite(&val, 1, 1, fp)) { | ||||
|         DEBUG("%s\n", "Failed to disable pci-sysfs rom file"); | ||||
|     } | ||||
|     fclose(fp); | ||||
| } | ||||
|  | ||||
							
								
								
									
										91
									
								
								hw/i386/pci-assign-load-rom.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								hw/i386/pci-assign-load-rom.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,91 @@ | ||||
| /*
 | ||||
|  * This is splited from hw/i386/kvm/pci-assign.c | ||||
|  */ | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include "hw/hw.h" | ||||
| #include "hw/i386/pc.h" | ||||
| #include "qemu/error-report.h" | ||||
| #include "ui/console.h" | ||||
| #include "hw/loader.h" | ||||
| #include "monitor/monitor.h" | ||||
| #include "qemu/range.h" | ||||
| #include "sysemu/sysemu.h" | ||||
| #include "hw/pci/pci.h" | ||||
| #include "hw/pci/pci-assign.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * Scan the assigned devices for the devices that have an option ROM, and then | ||||
|  * load the corresponding ROM data to RAM. If an error occurs while loading an | ||||
|  * option ROM, we just ignore that option ROM and continue with the next one. | ||||
|  */ | ||||
| void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner, | ||||
|                                      int *size, unsigned int domain, | ||||
|                                      unsigned int bus, unsigned int slot, | ||||
|                                      unsigned int function) | ||||
| { | ||||
|     char name[32], rom_file[64]; | ||||
|     FILE *fp; | ||||
|     uint8_t val; | ||||
|     struct stat st; | ||||
|     void *ptr = NULL; | ||||
| 
 | ||||
|     /* If loading ROM from file, pci handles it */ | ||||
|     if (dev->romfile || !dev->rom_bar) { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     snprintf(rom_file, sizeof(rom_file), | ||||
|              "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/rom", | ||||
|              domain, bus, slot, function); | ||||
| 
 | ||||
|     if (stat(rom_file, &st)) { | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     if (access(rom_file, F_OK)) { | ||||
|         error_report("pci-assign: Insufficient privileges for %s", rom_file); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     /* Write "1" to the ROM file to enable it */ | ||||
|     fp = fopen(rom_file, "r+"); | ||||
|     if (fp == NULL) { | ||||
|         return NULL; | ||||
|     } | ||||
|     val = 1; | ||||
|     if (fwrite(&val, 1, 1, fp) != 1) { | ||||
|         goto close_rom; | ||||
|     } | ||||
|     fseek(fp, 0, SEEK_SET); | ||||
| 
 | ||||
|     snprintf(name, sizeof(name), "%s.rom", object_get_typename(owner)); | ||||
|     memory_region_init_ram(&dev->rom, owner, name, st.st_size, &error_abort); | ||||
|     vmstate_register_ram(&dev->rom, &dev->qdev); | ||||
|     ptr = memory_region_get_ram_ptr(&dev->rom); | ||||
|     memset(ptr, 0xff, st.st_size); | ||||
| 
 | ||||
|     if (!fread(ptr, 1, st.st_size, fp)) { | ||||
|         error_report("pci-assign: Cannot read from host %s", rom_file); | ||||
|         error_printf("Device option ROM contents are probably invalid " | ||||
|                      "(check dmesg).\nSkip option ROM probe with rombar=0, " | ||||
|                      "or load from file with romfile=\n"); | ||||
|         goto close_rom; | ||||
|     } | ||||
| 
 | ||||
|     pci_register_bar(dev, PCI_ROM_SLOT, 0, &dev->rom); | ||||
|     dev->has_rom = true; | ||||
|     *size = st.st_size; | ||||
| close_rom: | ||||
|     /* Write "0" to disable ROM */ | ||||
|     fseek(fp, 0, SEEK_SET); | ||||
|     val = 0; | ||||
|     if (!fwrite(&val, 1, 1, fp)) { | ||||
|         DEBUG("%s\n", "Failed to disable pci-sysfs rom file"); | ||||
|     } | ||||
|     fclose(fp); | ||||
| 
 | ||||
|     return ptr; | ||||
| } | ||||
							
								
								
									
										27
									
								
								include/hw/pci/pci-assign.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								include/hw/pci/pci-assign.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| /*
 | ||||
|  * This work is licensed under the terms of the GNU GPL, version 2.  See | ||||
|  * the COPYING file in the top-level directory. | ||||
|  * | ||||
|  * Just split from hw/i386/kvm/pci-assign.c. | ||||
|  */ | ||||
| #ifndef PCI_ASSIGN_H | ||||
| #define PCI_ASSIGN_H | ||||
| 
 | ||||
| #include "hw/pci/pci.h" | ||||
| 
 | ||||
| //#define DEVICE_ASSIGNMENT_DEBUG
 | ||||
| 
 | ||||
| #ifdef DEVICE_ASSIGNMENT_DEBUG | ||||
| #define DEBUG(fmt, ...)                                       \ | ||||
|     do {                                                      \ | ||||
|         fprintf(stderr, "%s: " fmt, __func__ , __VA_ARGS__);  \ | ||||
|     } while (0) | ||||
| #else | ||||
| #define DEBUG(fmt, ...) | ||||
| #endif | ||||
| 
 | ||||
| void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner, | ||||
|                                      int *size, unsigned int domain, | ||||
|                                      unsigned int bus, unsigned int slot, | ||||
|                                      unsigned int function); | ||||
| #endif /* PCI_ASSIGN_H */ | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tiejun Chen
						Tiejun Chen