qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] PATCH/RFC: PCI memory mapping


From: Brian Wheeler
Subject: [Qemu-devel] PATCH/RFC: PCI memory mapping
Date: Thu, 02 Apr 2009 10:57:18 -0400

[first off, if there's an easier way to do this, let me know!]

This patch adds an address mapping function to the PCI bus so the host
chipset can remap PCI generated addresses to the appropriate physical
addresses.  

It adds two parameters to pci_register_bus:

PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                         qemu_irq *pic, int devfn_min, int nirq,
                         pci_map_addr_fn map_addr, void *map_addr_opaque)

The map_addr is a function which has the prototype:

typedef target_phys_addr_t (*pci_map_addr_fn)(void *opaque, int bus_num, 
                                              target_phys_addr_t addr);


and the map_addr_opaque data is a pointer to the IOTLB buffer in the
chipset.

When a pci device is doing dma or needs to write to the system, it can
use the

target_phys_addr_t pci_phys_addr(PCIDevice *device,
                                 target_phys_addr_t addr);

function to get the mapped target address.  

If map_addr is NULL the function just returns the address it was passed.
Otherwise the map_addr function is called and the address is translated.

Thoughts/comments/etc?

Brian

--- qemu/hw/pci.c       2009-03-25 15:00:23.000000000 -0400
+++ qemu-alpha-20090330/hw/pci.c        2009-04-02 10:19:31.000000000 -0400
@@ -29,12 +29,15 @@
 #include "sysemu.h"
 
 //#define DEBUG_PCI
+//#define DEBUG_PCI_MAP_ADDR
 
 struct PCIBus {
     int bus_num;
     int devfn_min;
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
+    pci_map_addr_fn map_addr;
+    void *map_addr_opaque;
     uint32_t config_reg; /* XXX: suppress */
     /* low level pic */
     SetIRQFunc *low_set_irq;
@@ -57,6 +60,7 @@
 static int pci_irq_index;
 static PCIBus *first_bus;
 
+
 static void pcibus_save(QEMUFile *f, void *opaque)
 {
     PCIBus *bus = (PCIBus *)opaque;
@@ -89,7 +93,8 @@
 }
 
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         qemu_irq *pic, int devfn_min, int nirq)
+                         qemu_irq *pic, int devfn_min, int nirq,
+                        pci_map_addr_fn map_addr, void *map_addr_opaque)
 {
     PCIBus *bus;
     static int nbus = 0;
@@ -100,6 +105,8 @@
     bus->irq_opaque = pic;
     bus->devfn_min = devfn_min;
     bus->nirq = nirq;
+    bus->map_addr = map_addr;
+    bus->map_addr_opaque = map_addr_opaque;
     first_bus = bus;
     register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
     return bus;
@@ -656,6 +663,24 @@
 }
 
 /***********************************************************/
+/* Generic pci memory mapping support */
+target_phys_addr_t pci_phys_addr(PCIDevice *device,
+                                target_phys_addr_t addr) {
+  target_phys_addr_t physaddr;
+  PCIBus *bus = device->bus;
+  if(bus->map_addr == NULL)
+    physaddr = addr + pci_mem_base;
+  else 
+    physaddr = bus->map_addr(bus->map_addr_opaque, bus->bus_num, addr);
+
+#ifdef DEBUG_PCI_MAP_ADDR
+  printf("PCI Physical Memory mapping:  %08lx -> %08lx\n", addr, physaddr);
+#endif
+  return physaddr;
+}
+
+
+/***********************************************************/
 /* monitor info on PCI */
 
 typedef struct {
--- qemu/hw/pci.h       2009-03-25 15:00:23.000000000 -0400
+++ qemu-alpha-20090330/hw/pci.h        2009-04-02 10:19:07.000000000 -0400
@@ -169,8 +176,10 @@
 
 typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
+typedef target_phys_addr_t (*pci_map_addr_fn)(void *opaque, int bus_num, 
+                                             target_phys_addr_t addr);
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
-                         qemu_irq *pic, int devfn_min, int nirq);
+                         qemu_irq *pic, int devfn_min, int nirq, 
pci_map_addr_fn map_addr, void *map_addr_opaque);
 
 PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn,
                   const char *default_model);
@@ -205,6 +214,9 @@
 {
     cpu_to_le16wu((uint16_t *)&pci_config[PCI_CLASS_DEVICE], val);
 }
+target_phys_addr_t pci_phys_addr(PCIDevice *device,
+                                target_phys_addr_t addr);
+
 
 /* lsi53c895a.c */
 #define LSI_MAX_DEVS 7






reply via email to

[Prev in Thread] Current Thread [Next in Thread]