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.