From: Jonas Weståker <jo...@retotech.se>

Signed-off-by: Jonas Weståker <jo...@retotech.se>
---
 inmates/lib/arm/Makefile              |  1 +
 inmates/lib/arm/include/arch/inmate.h | 33 +++++++++++++++++
 inmates/lib/arm/pci.c                 | 70 +++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)
 create mode 100644 inmates/lib/arm/pci.c

diff --git a/inmates/lib/arm/Makefile b/inmates/lib/arm/Makefile
index daabd63..85cc3ec 100644
--- a/inmates/lib/arm/Makefile
+++ b/inmates/lib/arm/Makefile
@@ -45,3 +45,4 @@ ccflags-y := -ffunction-sections
 
 lib-y := $(COMMON_OBJECTS)
 lib-y += header.o
+lib-y += pci.o
diff --git a/inmates/lib/arm/include/arch/inmate.h 
b/inmates/lib/arm/include/arch/inmate.h
index 5d65edf..ade8095 100644
--- a/inmates/lib/arm/include/arch/inmate.h
+++ b/inmates/lib/arm/include/arch/inmate.h
@@ -36,6 +36,35 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define HEAP_BASE 0x0
+
+#define PAGE_SIZE              (4 * 1024UL)
+#define PAGE_MASK              (~(PAGE_SIZE - 1))
+
+// The PCI configuration space provided by Jailhouse is 1MiB (1<<20).
+#define PCI_CFG_SIZE           0x00100000
+// Each PCI device has 256B (1<<8) of BDf (Bus, Device, Function)
+// configuration space.
+#define PCI_BDF_SIZE           0x00000100
+#define PCI_CFG_VENDOR_ID      0x000
+#define PCI_CFG_DEVICE_ID      0x002
+#define PCI_CFG_COMMAND                0x004
+# define PCI_CMD_IO            (1 << 0)
+# define PCI_CMD_MEM           (1 << 1)
+# define PCI_CMD_MASTER                (1 << 2)
+# define PCI_CMD_INTX_OFF      (1 << 10)
+#define PCI_CFG_STATUS         0x006
+# define PCI_STS_INT           (1 << 3)
+# define PCI_STS_CAPS          (1 << 4)
+#define PCI_CFG_BAR            0x010
+# define PCI_BAR_64BIT         0x4
+#define PCI_CFG_CAP_PTR                0x034
+
+#define PCI_ID_ANY             0xffff
+
+#define PCI_DEV_CLASS_OTHER    0xff
+
+
 /*
  * To ease the debugging, we can send a spurious hypercall, which should return
  * -ENOSYS, but appear in the hypervisor stats for this cell.
@@ -52,3 +81,7 @@ static inline void heartbeat(void)
 }
 
 void __attribute__((interrupt("IRQ"), used)) vector_irq(void);
+
+int pci_cfg_find_device(u32 base, u16 vendor, u16 device, u16 start_bdf);
+u32 pci_cfg_read(u32 base, u16 bdf, unsigned int offset, unsigned int size);
+void pci_cfg_write(u32 base, u16 bdf, unsigned int offset, u32 value, unsigned 
int size);
diff --git a/inmates/lib/arm/pci.c b/inmates/lib/arm/pci.c
new file mode 100644
index 0000000..810ce77
--- /dev/null
+++ b/inmates/lib/arm/pci.c
@@ -0,0 +1,70 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2014
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kis...@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <inmate.h>
+
+int pci_cfg_find_device(u32 base, u16 vendor, u16 device, u16 start_bdf)
+{
+       unsigned int bdf;
+       u32 addr;
+       u16 id;
+
+       for (addr = base + start_bdf * PCI_BDF_SIZE, bdf = start_bdf;
+            addr < base + PCI_CFG_SIZE;
+            addr += PCI_BDF_SIZE, bdf++)
+       {
+               id = pci_cfg_read(addr, bdf, PCI_CFG_VENDOR_ID, 2);
+               if (id == PCI_ID_ANY || (vendor != PCI_ID_ANY && vendor != id))
+               {
+                       continue;
+               }
+               if (device == PCI_ID_ANY ||
+                   pci_cfg_read(addr, bdf, PCI_CFG_DEVICE_ID, 2) == device)
+               {
+                       return bdf;
+               }
+       }
+       return -1;
+}
+
+u32 pci_cfg_read(u32 base, u16 bdf, unsigned int addr, unsigned int size)
+{
+       u32 reg_addr = base | ((u32)bdf << 8) | (addr & 0xfc);
+       //printk("%s(bdf:0x%x, addr:%p, size:0x%x), reg_addr0x%x\n", __func__, 
bdf, addr, size, reg_addr);
+       switch (size) {
+       case 1:
+               return mmio_read8((u8 *)(reg_addr + (addr & 0x3)));
+       case 2:
+               return mmio_read16((u16 *)(reg_addr + (addr & 0x3)));
+       case 4:
+               return mmio_read32((u32 *)(reg_addr));
+       default:
+               return -1;
+       }
+}
+
+void pci_cfg_write(u32 base, u16 bdf, unsigned int addr, u32 value, unsigned 
int size)
+{
+       u32 reg_addr = base | ((u32)bdf << 8) | (addr & 0xfc);
+       //printk("%s(bdf:0x%x, addr:%p, value:0x%x, size:0x%x), 
reg_addr0x%x\n", __func__, bdf, addr, value, size, reg_addr);
+       switch (size) {
+       case 1:
+               mmio_write8((u8 *)(reg_addr + (addr & 0x3)), value);
+               break;
+       case 2:
+               mmio_write16((u16 *)(reg_addr + (addr & 0x3)), value);
+               break;
+       case 4:
+               mmio_write32((u32 *)(reg_addr), value);
+               break;
+       }
+}
-- 
2.7.4

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to