Source to ./pci_dev.h
/*
* Cisco router simulation platform.
* Copyright (c) 2005,2006 Christophe Fillot ([email protected])
*/
#ifndef __PCI_DEV_H__
#define __PCI_DEV_H__
#include "utils.h"
#define PCI_BUS_ADDR 0xcf8
#define PCI_BUS_DATA 0xcfc
/* PCI ID (Vendor + Device) register */
#define PCI_REG_ID 0x00
/* PCI Base Address Registers (BAR) */
#define PCI_REG_BAR0 0x10
#define PCI_REG_BAR1 0x14
#define PCI_REG_BAR2 0x18
#define PCI_REG_BAR3 0x1c
#define PCI_REG_BAR4 0x20
#define PCI_REG_BAR5 0x24
/* Forward declaration for PCI device */
typedef struct pci_device pci_dev_t;
/* PCI function prototypes */
typedef void (*pci_init_t)(pci_dev_t *dev);
typedef m_uint32_t (*pci_reg_read_t)(cpu_gen_t *cpu,pci_dev_t *dev,int reg);
typedef void (*pci_reg_write_t)(cpu_gen_t *cpu,pci_dev_t *dev,int reg,
m_uint32_t value);
/* PCI device */
struct pci_device {
char *name;
u_int vendor_id,product_id;
int device,function,irq;
void *priv_data;
/* Parent bus */
struct pci_bus *pci_bus;
pci_init_t init;
pci_reg_read_t read_register;
pci_reg_write_t write_register;
struct pci_device *next,**pprev;
};
/* PCI bus */
struct pci_bus {
char *name;
m_uint32_t pci_addr;
/* Bus number */
int bus;
/* PCI device list on this bus */
struct pci_device *dev_list;
/* PCI bridges to access other busses */
struct pci_bridge *bridge_list;
};
/* PCI bridge */
struct pci_bridge {
int pri_bus; /* Primary Bus */
int sec_bus; /* Secondary Bus */
int sub_bus; /* Subordinate Bus */
int skip_bus_check;
/* Bus configuration register */
m_uint32_t cfg_reg_bus;
/* PCI bridge device */
struct pci_device *pci_dev;
/* Secondary PCI bus */
struct pci_bus *pci_bus;
/* Fallback handlers to read/write config registers */
pci_reg_read_t fallback_read;
pci_reg_write_t fallback_write;
struct pci_bridge *next,**pprev;
};
/* PCI IO device */
struct pci_io_device {
m_uint32_t start,end;
struct vdevice *real_dev;
dev_handler_t handler;
struct pci_io_device *next,**pprev;
};
/* Trigger a PCI device IRQ */
void pci_dev_trigger_irq(vm_instance_t *vm,struct pci_device *dev);
/* Clear a PCI device IRQ */
void pci_dev_clear_irq(vm_instance_t *vm,struct pci_device *dev);
/* PCI bus lookup */
struct pci_bus *pci_bus_lookup(struct pci_bus *pci_bus_root,int bus);
/* PCI device local lookup */
struct pci_device *pci_dev_lookup_local(struct pci_bus *pci_bus,
int device,int function);
/* PCI device lookup */
struct pci_device *pci_dev_lookup(struct pci_bus *pci_bus_root,
int bus,int device,int function);
/* Handle the address register access */
void pci_dev_addr_handler(cpu_gen_t *cpu,struct pci_bus *pci_bus,
u_int op_type,int swap,m_uint64_t *data);
/* Handle the data register access */
void pci_dev_data_handler(cpu_gen_t *cpu,struct pci_bus *pci_bus,
u_int op_type,int swap,m_uint64_t *data);
/* Add a PCI bridge */
struct pci_bridge *pci_bridge_add(struct pci_bus *pci_bus);
/* Remove a PCI bridge */
void pci_bridge_remove(struct pci_bridge *bridge);
/* Map secondary bus to a PCI bridge */
void pci_bridge_map_bus(struct pci_bridge *bridge,struct pci_bus *pci_bus);
/* Set PCI bridge bus info */
void pci_bridge_set_bus_info(struct pci_bridge *bridge,
int pri_bus,int sec_bus,int sub_bus);
/* Add a PCI device */
struct pci_device *
pci_dev_add(struct pci_bus *pci_bus,
char *name,u_int vendor_id,u_int product_id,
int device,int function,int irq,
void *priv_data,pci_init_t init,
pci_reg_read_t read_register,
pci_reg_write_t write_register);
/* Add a basic PCI device that just returns a Vendor/Product ID */
struct pci_device *
pci_dev_add_basic(struct pci_bus *pci_bus,
char *name,u_int vendor_id,u_int product_id,
int device,int function);
/* Remove a PCI device */
void pci_dev_remove(struct pci_device *dev);
/* Remove a PCI device given its ID (bus,device,function) */
int pci_dev_remove_by_id(struct pci_bus *pci_bus,
int bus,int device,int function);
/* Remove a PCI device given its name */
int pci_dev_remove_by_name(struct pci_bus *pci_bus,char *name);
/* Create a PCI bus */
struct pci_bus *pci_bus_create(char *name,int bus);
/* Delete a PCI bus */
void pci_bus_remove(struct pci_bus *pci_bus);
/* Create a PCI bridge device */
struct pci_device *pci_bridge_create_dev(struct pci_bus *pci_bus,char *name,
u_int vendor_id,u_int product_id,
int device,int function,
struct pci_bus *sec_bus,
pci_reg_read_t fallback_read,
pci_reg_write_t fallback_write);
/* Show PCI device list */
void pci_dev_show_list(struct pci_bus *pci_bus);
#endif