Hello, 

I have a question regarding how Qemu PCIe devices handle Config Transactions vs 
Memory Transactions (assuming the PCI device is setup to act as 
PCI_BASE_ADDRESS_SPACE_MEMORY).


I'm using portions of hw/cirrus_vga.c to make my point,



static PCIDeviceInfo cirrus_vga_info = {
    .qdev.name    = "cirrus-vga",
    .qdev.desc    = "Cirrus CLGD 54xx VGA",
    .qdev.size    = sizeof(PCICirrusVGAState),
    .qdev.vmsd    = &vmstate_pci_cirrus_vga,
    .init         = pci_cirrus_vga_initfn,
    .romfile      = VGABIOS_CIRRUS_FILENAME,
    .config_write = pci_cirrus_write_config,
};


PCIDeviceInfo allows for custom .config_write (& config_read) handler as shown 
above. Any pci config operations operations initiated via legacy I/O operations 
will use these config handlers.


The MMIO regions and handlers are mapped as shown below:



static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
{
:
} and so on for the other mmio handlers




static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
    cirrus_vga_mem_readb,
    cirrus_vga_mem_readw,
    cirrus_vga_mem_readl,
};


static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
    cirrus_vga_mem_writeb,
    cirrus_vga_mem_writew,
    cirrus_vga_mem_writel,
};


static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)

{
:
:

    s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
                                                  cirrus_vga_mem_write, s);
:
}



static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
    pcibus_t addr, pcibus_t size, int type)
{
    CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;


    cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
     s->cirrus_mmio_io_addr);
}



static int pci_cirrus_vga_initfn(PCIDevice *dev)
{
:
:
     cirrus_init_common(..)
:
     if (device_id == CIRRUS_ID_CLGD5446) {
         pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
                          PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map);
     }
     return 0;
}


I have some questions about PCIe operations sssuming the device has MMIO 
handlers involved (as shown above).
1. Will all PCIe config operations ALWAYS use the installed config handlers? Or 
can PCIe config operations use the MMIO handlers?
2. Assuming that both PCI config and MMIO operations can use the MMIO handlers, 
is there any way I can identify if a transaction is a config or a memory 
transaction?
3.a. What address is passed on the MMIO handlers for config and MMIO 
operations? From pci_data_write in pci_host.c, it appears that config 
operations send only the offset into the config region. I couldn't determine 
what address is passed for MMIO operations.
   b. Is it an offset from the BAR for MMIO operations?
   c. How do I get the full physical address?
   d. What address does a PCIe device expect to see - physical or offset for?
   e. Is there anyway I can find out what the bus and device numbers are once 
inside the config and MMIO handlers? i.e once the execution has reached the 
pci_cirrus_write_config() or cirrus_vga_mem_readb(..) from the code above?


Thanks


Adnan

Reply via email to