mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-08-22 13:37:29 +00:00
b59816369a
For the MMIO and PCI buses, drivers typically allocate an IRQ line for their device before registering the device with the device tree for the relevant bus. This patch moves the IRQ allocation into the bus code, which is then called directly by the device tree when a new device is registered. IOPORT devices, however, tend to use hardcoded IRQs for legacy reasons, so they are still required to deal with their interrupts (which also require remapping for non-x86 architectures). Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
97 lines
2.3 KiB
C
97 lines
2.3 KiB
C
#ifndef KVM__PCI_H
|
|
#define KVM__PCI_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/kvm.h>
|
|
#include <linux/pci_regs.h>
|
|
#include <endian.h>
|
|
|
|
#include "kvm/devices.h"
|
|
#include "kvm/kvm.h"
|
|
#include "kvm/msi.h"
|
|
|
|
/*
|
|
* PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
|
|
* ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for
|
|
* details.
|
|
*/
|
|
#define PCI_CONFIG_ADDRESS 0xcf8
|
|
#define PCI_CONFIG_DATA 0xcfc
|
|
#define PCI_CONFIG_BUS_FORWARD 0xcfa
|
|
#define PCI_IO_SIZE 0x100
|
|
#define PCI_CFG_SIZE (1ULL << 24)
|
|
|
|
union pci_config_address {
|
|
struct {
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
unsigned reg_offset : 2; /* 1 .. 0 */
|
|
unsigned register_number : 6; /* 7 .. 2 */
|
|
unsigned function_number : 3; /* 10 .. 8 */
|
|
unsigned device_number : 5; /* 15 .. 11 */
|
|
unsigned bus_number : 8; /* 23 .. 16 */
|
|
unsigned reserved : 7; /* 30 .. 24 */
|
|
unsigned enable_bit : 1; /* 31 */
|
|
#else
|
|
unsigned enable_bit : 1; /* 31 */
|
|
unsigned reserved : 7; /* 30 .. 24 */
|
|
unsigned bus_number : 8; /* 23 .. 16 */
|
|
unsigned device_number : 5; /* 15 .. 11 */
|
|
unsigned function_number : 3; /* 10 .. 8 */
|
|
unsigned register_number : 6; /* 7 .. 2 */
|
|
unsigned reg_offset : 2; /* 1 .. 0 */
|
|
#endif
|
|
};
|
|
u32 w;
|
|
};
|
|
|
|
struct msix_table {
|
|
struct msi_msg msg;
|
|
u32 ctrl;
|
|
};
|
|
|
|
struct msix_cap {
|
|
u8 cap;
|
|
u8 next;
|
|
u16 ctrl;
|
|
u32 table_offset;
|
|
u32 pba_offset;
|
|
};
|
|
|
|
struct pci_device_header {
|
|
u16 vendor_id;
|
|
u16 device_id;
|
|
u16 command;
|
|
u16 status;
|
|
u8 revision_id;
|
|
u8 class[3];
|
|
u8 cacheline_size;
|
|
u8 latency_timer;
|
|
u8 header_type;
|
|
u8 bist;
|
|
u32 bar[6];
|
|
u32 card_bus;
|
|
u16 subsys_vendor_id;
|
|
u16 subsys_id;
|
|
u32 exp_rom_bar;
|
|
u8 capabilities;
|
|
u8 reserved1[3];
|
|
u32 reserved2;
|
|
u8 irq_line;
|
|
u8 irq_pin;
|
|
u8 min_gnt;
|
|
u8 max_lat;
|
|
struct msix_cap msix;
|
|
u8 empty[136]; /* Rest of PCI config space */
|
|
u32 bar_size[6];
|
|
} __attribute__((packed));
|
|
|
|
int pci__init(struct kvm *kvm);
|
|
int pci__exit(struct kvm *kvm);
|
|
struct pci_device_header *pci__find_dev(u8 dev_num);
|
|
u32 pci_get_io_space_block(u32 size);
|
|
void pci__assign_irq(struct device_header *dev_hdr);
|
|
void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
|
|
void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
|
|
|
|
#endif /* KVM__PCI_H */
|