pci设备算是学习qemu必须要掌握的一类设备的模拟,单独提出来说一下。这里以qemu的pci教学程序为基础讲解,源码路径:hw/misc/edu.c
1.设备的定义
typedef struct {
PCIDevice pdev;
MemoryRegion mmio;
QemuThread thread;
QemuMutex thr_mutex;
QemuCond thr_cond;
bool stopping;
uint32_t addr4;
uint32_t fact;
#define EDU_STATUS_COMPUTING 0x01
#define EDU_STATUS_IRQFACT 0x80
uint32_t status;
uint32_t irq_status;
#define EDU_DMA_RUN 0x1
#define EDU_DMA_DIR(cmd) (((cmd) & 0x2) >> 1)
# define EDU_DMA_FROM_PCI 0
# define EDU_DMA_TO_PCI 1
#define EDU_DMA_IRQ 0x4
struct dma_state {
dma_addr_t src;
dma_addr_t dst;
dma_addr_t cnt;
dma_addr_t cmd;
} dma;
QEMUTimer dma_timer;
char dma_buf[DMA_SIZE];
uint64_t dma_mask;
} EduState;
这个设备有一个dma,继承自PCIDevice,初始化过后是PCIDeviceClass类型,来看一下PCIDeviceClass
typedef struct PCIDeviceClass {
DeviceClass parent_class;
void (*realize)(PCIDevice *dev, Error **errp);
PCIUnregisterFunc *exit;
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
uint16_t vendor_id;
uint16_t device_id;
uint8_t revision;
uint16_t class_id;
uint16_t subsystem_vendor_id; /* only for header type = 0 */
uint16_t subsystem_id; /* only for header type = 0 */
/*
* pci-to-pci bridge or normal device.
* This doesn't mean pci host switch.
* When card bus bridge is supported, this would be enhanced.
*/
int is_bridge;
/* rom bar */
const char *romfile;
} PCIDeviceClass;
主要关注config_read、config_write、vendor_id、device_id、revision、class_id
config_read、config_write两个函数不需要我们自己去实现,pci框架里面已经实现好了。框架会模拟好config的读写。
2.类的初始化
static void edu_class_init(ObjectClass *class, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(class);
k->realize = pci_edu_realize;
k->exit = pci_edu_uninit;
k->vendor_id = PCI_VENDOR_ID_QEMU;
k->device_id = 0x11e8;
k->revision = 0x10;
k->class_id = PCI_CLASS_OTHERS;
}
static void pci_edu_register_types(void)
{
static InterfaceInfo interfaces[] = {
{
INTERFACE_CONVENTIONAL_PCI_DEVICE },
{
},
};
static const TypeInfo edu_info = {
.name = TYPE_PCI_EDU_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(EduState),
.instance_init = edu_instance_init,
.class_init = edu_class_init,
.interfaces = interfaces,
};
type_register_static(&edu_info
648




被折叠的 条评论
为什么被折叠?



