152 |
152 |
|
153 |
153 |
int pci_device_load(PCIDevice *s, QEMUFile *f)
|
154 |
154 |
{
|
|
155 |
uint8_t config[PCI_CONFIG_SPACE_SIZE];
|
155 |
156 |
uint32_t version_id;
|
156 |
157 |
int i;
|
157 |
158 |
|
158 |
159 |
version_id = qemu_get_be32(f);
|
159 |
160 |
if (version_id > 2)
|
160 |
161 |
return -EINVAL;
|
161 |
|
qemu_get_buffer(f, s->config, 256);
|
|
162 |
qemu_get_buffer(f, config, sizeof config);
|
|
163 |
for (i = 0; i < sizeof config; ++i)
|
|
164 |
if ((config[i] ^ s->config[i]) & s->cmask[i] & ~s->wmask[i])
|
|
165 |
return -EINVAL;
|
|
166 |
memcpy(s->config, config, sizeof config);
|
|
167 |
|
162 |
168 |
pci_update_mappings(s);
|
163 |
169 |
|
164 |
170 |
if (version_id >= 2)
|
... | ... | |
254 |
260 |
return pci_find_bus(bus);
|
255 |
261 |
}
|
256 |
262 |
|
|
263 |
static void pci_init_cmask(PCIDevice *dev)
|
|
264 |
{
|
|
265 |
pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
|
|
266 |
pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff);
|
|
267 |
dev->cmask[PCI_STATUS] = PCI_STATUS_CAP_LIST;
|
|
268 |
dev->cmask[PCI_REVISION_ID] = 0xff;
|
|
269 |
dev->cmask[PCI_CLASS_PROG] = 0xff;
|
|
270 |
pci_set_word(dev->cmask + PCI_CLASS_DEVICE, 0xffff);
|
|
271 |
dev->cmask[PCI_HEADER_TYPE] = 0xff;
|
|
272 |
dev->cmask[PCI_CAPABILITY_LIST] = 0xff;
|
|
273 |
}
|
|
274 |
|
257 |
275 |
static void pci_init_wmask(PCIDevice *dev)
|
258 |
276 |
{
|
259 |
277 |
int i;
|
... | ... | |
286 |
304 |
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
|
287 |
305 |
memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state));
|
288 |
306 |
pci_set_default_subsystem_id(pci_dev);
|
|
307 |
pci_init_cmask(pci_dev);
|
289 |
308 |
pci_init_wmask(pci_dev);
|
290 |
309 |
|
291 |
310 |
if (!config_read)
|
... | ... | |
385 |
404 |
}
|
386 |
405 |
*(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type);
|
387 |
406 |
*(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask);
|
|
407 |
*(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff;
|
388 |
408 |
}
|
389 |
409 |
|
390 |
410 |
static void pci_update_mappings(PCIDevice *d)
|
... | ... | |
939 |
959 |
memset(pdev->used + offset, 0xFF, size);
|
940 |
960 |
/* Make capability read-only by default */
|
941 |
961 |
memset(pdev->wmask + offset, 0, size);
|
|
962 |
/* Check capability by default */
|
|
963 |
memset(pdev->cmask + offset, 0xFF, size);
|
942 |
964 |
return offset;
|
943 |
965 |
}
|
944 |
966 |
|
... | ... | |
951 |
973 |
pdev->config[prev] = pdev->config[offset + PCI_CAP_LIST_NEXT];
|
952 |
974 |
/* Make capability writeable again */
|
953 |
975 |
memset(pdev->wmask + offset, 0xff, size);
|
|
976 |
/* Clear cmask as device-specific registers can't be checked */
|
|
977 |
memset(pdev->cmask + offset, 0, size);
|
954 |
978 |
memset(pdev->used + offset, 0, size);
|
955 |
979 |
|
956 |
980 |
if (!pdev->config[PCI_CAPABILITY_LIST])
|