Save/load PCI-device, PCI-bus and PIIX3 irq-related state (patches by Uri Lublin.
Note that other PCI bridges are not fixed here. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3793 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									b26177d7ec
								
							
						
					
					
						commit
						52fc1d83bc
					
				
							
								
								
									
										51
									
								
								hw/pci.c
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								hw/pci.c
									
									
									
									
									
								
							| @ -42,6 +42,7 @@ struct PCIBus { | ||||
|     PCIBus *next; | ||||
|     /* The bus IRQ state is the logical OR of the connected devices.
 | ||||
|        Keep a count of the number of devices with raised IRQs.  */ | ||||
|     int nirq; | ||||
|     int irq_count[]; | ||||
| }; | ||||
| 
 | ||||
| @ -52,16 +53,51 @@ target_phys_addr_t pci_mem_base; | ||||
| static int pci_irq_index; | ||||
| static PCIBus *first_bus; | ||||
| 
 | ||||
| static void pcibus_save(QEMUFile *f, void *opaque) | ||||
| { | ||||
|     PCIBus *bus = (PCIBus *)opaque; | ||||
|     int i; | ||||
| 
 | ||||
|     qemu_put_be32(f, bus->nirq); | ||||
|     for (i = 0; i < bus->nirq; i++) | ||||
|         qemu_put_be32(f, bus->irq_count[i]); | ||||
| } | ||||
| 
 | ||||
| static int  pcibus_load(QEMUFile *f, void *opaque, int version_id) | ||||
| { | ||||
|     PCIBus *bus = (PCIBus *)opaque; | ||||
|     int i, nirq; | ||||
| 
 | ||||
|     if (version_id != 1) | ||||
|         return -EINVAL; | ||||
| 
 | ||||
|     nirq = qemu_get_be32(f); | ||||
|     if (bus->nirq != nirq) { | ||||
|         fprintf(stderr, "pcibus_load: nirq mismatch: src=%d dst=%d\n", | ||||
|                 nirq, bus->nirq); | ||||
|         return -EINVAL; | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < nirq; i++) | ||||
|         bus->irq_count[i] = qemu_get_be32(f); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, | ||||
|                          qemu_irq *pic, int devfn_min, int nirq) | ||||
| { | ||||
|     PCIBus *bus; | ||||
|     static int nbus = 0; | ||||
| 
 | ||||
|     bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int))); | ||||
|     bus->set_irq = set_irq; | ||||
|     bus->map_irq = map_irq; | ||||
|     bus->irq_opaque = pic; | ||||
|     bus->devfn_min = devfn_min; | ||||
|     bus->nirq = nirq; | ||||
|     first_bus = bus; | ||||
|     register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus); | ||||
|     return bus; | ||||
| } | ||||
| 
 | ||||
| @ -83,18 +119,29 @@ int pci_bus_num(PCIBus *s) | ||||
| 
 | ||||
| void pci_device_save(PCIDevice *s, QEMUFile *f) | ||||
| { | ||||
|     qemu_put_be32(f, 1); /* PCI device version */ | ||||
|     int i; | ||||
| 
 | ||||
|     qemu_put_be32(f, 2); /* PCI device version */ | ||||
|     qemu_put_buffer(f, s->config, 256); | ||||
|     for (i = 0; i < 4; i++) | ||||
|         qemu_put_be32(f, s->irq_state[i]); | ||||
| } | ||||
| 
 | ||||
| int pci_device_load(PCIDevice *s, QEMUFile *f) | ||||
| { | ||||
|     uint32_t version_id; | ||||
|     int i; | ||||
| 
 | ||||
|     version_id = qemu_get_be32(f); | ||||
|     if (version_id != 1) | ||||
|     if (version_id > 2) | ||||
|         return -EINVAL; | ||||
|     qemu_get_buffer(f, s->config, 256); | ||||
|     pci_update_mappings(s); | ||||
| 
 | ||||
|     if (version_id >= 2) | ||||
|         for (i = 0; i < 4; i ++) | ||||
|             s->irq_state[i] = qemu_get_be32(f); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -57,6 +57,7 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) | ||||
| 
 | ||||
| static uint32_t isa_page_descs[384 / 4]; | ||||
| static uint8_t smm_enabled; | ||||
| static int pci_irq_levels[4]; | ||||
| 
 | ||||
| static void update_pam(PCIDevice *d, uint32_t start, uint32_t end, int r) | ||||
| { | ||||
| @ -139,22 +140,32 @@ static void i440fx_write_config(PCIDevice *d, | ||||
| static void i440fx_save(QEMUFile* f, void *opaque) | ||||
| { | ||||
|     PCIDevice *d = opaque; | ||||
|     int i; | ||||
| 
 | ||||
|     pci_device_save(d, f); | ||||
|     qemu_put_8s(f, &smm_enabled); | ||||
| 
 | ||||
|     for (i = 0; i < 4; i++) | ||||
|         qemu_put_be32(f, pci_irq_levels[i]); | ||||
| } | ||||
| 
 | ||||
| static int i440fx_load(QEMUFile* f, void *opaque, int version_id) | ||||
| { | ||||
|     PCIDevice *d = opaque; | ||||
|     int ret; | ||||
|     int ret, i; | ||||
| 
 | ||||
|     if (version_id != 1) | ||||
|     if (version_id > 2) | ||||
|         return -EINVAL; | ||||
|     ret = pci_device_load(d, f); | ||||
|     if (ret < 0) | ||||
|         return ret; | ||||
|     i440fx_update_memory_mappings(d); | ||||
|     qemu_get_8s(f, &smm_enabled); | ||||
| 
 | ||||
|     if (version_id >= 2) | ||||
|         for (i = 0; i < 4; i++) | ||||
|             pci_irq_levels[i] = qemu_get_be32(f); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| @ -192,7 +203,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) | ||||
| 
 | ||||
|     d->config[0x72] = 0x02; /* SMRAM */ | ||||
| 
 | ||||
|     register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d); | ||||
|     register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d); | ||||
|     *pi440fx_state = d; | ||||
|     return b; | ||||
| } | ||||
| @ -205,8 +216,6 @@ PCIDevice *piix4_dev; | ||||
| /* just used for simpler irq handling. */ | ||||
| #define PCI_IRQ_WORDS   ((PCI_DEVICES_MAX + 31) / 32) | ||||
| 
 | ||||
| static int pci_irq_levels[4]; | ||||
| 
 | ||||
| static void piix3_set_irq(qemu_irq *pic, int irq_num, int level) | ||||
| { | ||||
|     int i, pic_irq, pic_level; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 balrog
						balrog