debuggers.hg
changeset 17913:97e02365a781
ioemu: generic PCI device config-space emulation
This patch is an extension for qemu-dm to enable emulation of generic
PCI devices. The information for the PCI devices can be passed by
command line parameter.
The command line parameter is "-pciemulation" followed by the
information which contains a label and hex value of the configuration
registers separated by ":".
The configuration registers for each PCI device are below.
vendorid
deviceid
command
status
revision
classcode
headertype
subvendorid
subsystemid
interruputline
interruptpin
This is an example of command line parameter.
-pciemulation hba1:1240:0780:0002:0:0:010000:0:10b5:0777:05:1
Signed-off-by: Shinji Matsumoto <smatsumoto@marathontechnologies.com>
This patch is an extension for qemu-dm to enable emulation of generic
PCI devices. The information for the PCI devices can be passed by
command line parameter.
The command line parameter is "-pciemulation" followed by the
information which contains a label and hex value of the configuration
registers separated by ":".
The configuration registers for each PCI device are below.
vendorid
deviceid
command
status
revision
classcode
headertype
subvendorid
subsystemid
interruputline
interruptpin
This is an example of command line parameter.
-pciemulation hba1:1240:0780:0002:0:0:010000:0:10b5:0777:05:1
Signed-off-by: Shinji Matsumoto <smatsumoto@marathontechnologies.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Jun 18 09:40:39 2008 +0100 (2008-06-18) |
parents | 9493a853df9e |
children | 666f5196f0fc |
files | tools/ioemu/Makefile.target tools/ioemu/hw/pc.c tools/ioemu/hw/pci_emulation.c tools/ioemu/hw/pci_emulation.h tools/ioemu/vl.c tools/ioemu/vl.h |
line diff
1.1 --- a/tools/ioemu/Makefile.target Wed Jun 18 09:39:14 2008 +0100 1.2 +++ b/tools/ioemu/Makefile.target Wed Jun 18 09:40:39 2008 +0100 1.3 @@ -441,6 +441,7 @@ ifdef CONFIG_STUBDOM 1.4 VL_OBJS+= xenfbfront.o 1.5 endif 1.6 VL_OBJS+= xen_console.o 1.7 +VL_OBJS+= pci_emulation.o 1.8 ifndef CONFIG_STUBDOM 1.9 VL_OBJS+= tpm_tis.o 1.10 VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
2.1 --- a/tools/ioemu/hw/pc.c Wed Jun 18 09:39:14 2008 +0100 2.2 +++ b/tools/ioemu/hw/pc.c Wed Jun 18 09:40:39 2008 +0100 2.3 @@ -1090,6 +1090,13 @@ static void pc_init1(uint64_t ram_size, 2.4 } 2.5 } 2.6 #endif /* !CONFIG_DM */ 2.7 + 2.8 + if (pci_enabled) { 2.9 + PCI_EMULATION_INFO *p; 2.10 + for (p = PciEmulationInfoHead; p != NULL; p = p->next) { 2.11 + pci_emulation_init(pci_bus, p); 2.12 + } 2.13 + } 2.14 } 2.15 2.16 static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device,
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/ioemu/hw/pci_emulation.c Wed Jun 18 09:40:39 2008 +0100 3.3 @@ -0,0 +1,118 @@ 3.4 +/* 3.5 + * Changes to PCI emulation made by Marathon Technologies, June 2008 3.6 + */ 3.7 + 3.8 +#include "vl.h" 3.9 + 3.10 +typedef struct { 3.11 + PCIDevice dev; 3.12 +} PCI_EMULATION_State; 3.13 + 3.14 +void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info) 3.15 +{ 3.16 + char *p; 3.17 + int i; 3.18 + int ret; 3.19 + for (p = config_text, i = 0; *p != '\0'; p++) { 3.20 + if (*p == ':') { 3.21 + break; 3.22 + } 3.23 + if (i < sizeof(pci_emulation_info->name) - 1) { 3.24 + pci_emulation_info->name[i] = *p; 3.25 + i++; 3.26 + } 3.27 + } 3.28 + pci_emulation_info->name[i] = '\0'; 3.29 + if (*p == '\0') return; 3.30 + p++; 3.31 + ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x", 3.32 + &(pci_emulation_info->vendorid), 3.33 + &(pci_emulation_info->deviceid), 3.34 + &(pci_emulation_info->command), 3.35 + &(pci_emulation_info->status), 3.36 + &(pci_emulation_info->revision), 3.37 + &(pci_emulation_info->classcode), 3.38 + &(pci_emulation_info->headertype), 3.39 + &(pci_emulation_info->subvendorid), 3.40 + &(pci_emulation_info->subsystemid), 3.41 + &(pci_emulation_info->interruputline), 3.42 + &(pci_emulation_info->interruputpin)); 3.43 +#ifdef DEBUG 3.44 + fprintf(logfile, "qemu: pciemulation %s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n", 3.45 + pci_emulation_info->name, 3.46 + pci_emulation_info->vendorid, 3.47 + pci_emulation_info->deviceid, 3.48 + pci_emulation_info->command, 3.49 + pci_emulation_info->status, 3.50 + pci_emulation_info->revision, 3.51 + pci_emulation_info->classcode, 3.52 + pci_emulation_info->headertype, 3.53 + pci_emulation_info->subvendorid, 3.54 + pci_emulation_info->subsystemid, 3.55 + pci_emulation_info->interruputline, 3.56 + pci_emulation_info->interruputpin); 3.57 +#endif 3.58 + return; 3.59 +} 3.60 + 3.61 +static void pci_emulation_save(QEMUFile *f, void *opaque) 3.62 +{ 3.63 + PCIDevice *d = opaque; 3.64 + 3.65 + pci_device_save(d, f); 3.66 +} 3.67 + 3.68 +static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id) 3.69 +{ 3.70 + PCIDevice *d = opaque; 3.71 + 3.72 + if (version_id != 1) 3.73 + return -EINVAL; 3.74 + 3.75 + return pci_device_load(d, f); 3.76 +} 3.77 + 3.78 + 3.79 +void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info) 3.80 +{ 3.81 + int instance_id; 3.82 + PCI_EMULATION_State *d; 3.83 + uint8_t *pci_conf; 3.84 + 3.85 +#ifdef DEBUG 3.86 + fprintf(logfile, "qemu: pciinit\n"); 3.87 +#endif 3.88 + 3.89 + d = (PCI_EMULATION_State *)pci_register_device(bus, 3.90 + pci_emulation_info->name, 3.91 + sizeof(PCI_EMULATION_State), 3.92 + -1, 3.93 + NULL, NULL); 3.94 + pci_conf = d->dev.config; 3.95 + pci_conf[0x00] = pci_emulation_info->vendorid & 0xff; 3.96 + pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8; 3.97 + pci_conf[0x02] = pci_emulation_info->deviceid & 0xff; 3.98 + pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8; 3.99 + pci_conf[0x04] = pci_emulation_info->command & 0xff; 3.100 + pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8; 3.101 + pci_conf[0x06] = pci_emulation_info->status & 0xff; 3.102 + pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8; 3.103 + pci_conf[0x08] = pci_emulation_info->revision & 0xff; 3.104 + pci_conf[0x09] = pci_emulation_info->classcode & 0xff; 3.105 + pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8; 3.106 + pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16; 3.107 + pci_conf[0x0e] = pci_emulation_info->headertype & 0xff; 3.108 + pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff; 3.109 + pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8; 3.110 + pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff; 3.111 + pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8; 3.112 + pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff; 3.113 + pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff; 3.114 + 3.115 + instance_id = pci_bus_num(bus) << 8 | d->dev.devfn; 3.116 + register_savevm(pci_emulation_info->name, instance_id, 3.117 + 1, pci_emulation_save, pci_emulation_load, d); 3.118 + 3.119 + 3.120 + return; 3.121 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/tools/ioemu/hw/pci_emulation.h Wed Jun 18 09:40:39 2008 +0100 4.3 @@ -0,0 +1,24 @@ 4.4 +/* 4.5 + * Changes to PCI emulation made by Marathon Technologies, June 2008 4.6 + */ 4.7 + 4.8 +typedef struct PCI_EMULATION_INFO_t { 4.9 + struct PCI_EMULATION_INFO_t *next; 4.10 + char name[32]; 4.11 + unsigned int vendorid; 4.12 + unsigned int deviceid; 4.13 + unsigned int command; 4.14 + unsigned int status; 4.15 + unsigned int revision; 4.16 + unsigned int classcode; 4.17 + unsigned int headertype; 4.18 + unsigned int subvendorid; 4.19 + unsigned int subsystemid; 4.20 + unsigned int interruputline; 4.21 + unsigned int interruputpin; 4.22 +} PCI_EMULATION_INFO; 4.23 + 4.24 +void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info); 4.25 +void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info); 4.26 + 4.27 +extern PCI_EMULATION_INFO *PciEmulationInfoHead;
5.1 --- a/tools/ioemu/vl.c Wed Jun 18 09:39:14 2008 +0100 5.2 +++ b/tools/ioemu/vl.c Wed Jun 18 09:40:39 2008 +0100 5.3 @@ -137,6 +137,9 @@ 5.4 /* XXX: use a two level table to limit memory usage */ 5.5 #define MAX_IOPORTS 65536 5.6 5.7 +/* Max number of PCI emulation */ 5.8 +#define MAX_PCI_EMULATION 32 5.9 + 5.10 const char *bios_dir = CONFIG_QEMU_SHAREDIR; 5.11 void *ioport_opaque[MAX_IOPORTS]; 5.12 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; 5.13 @@ -212,6 +215,8 @@ int xc_handle; 5.14 char domain_name[64] = "Xen-no-name"; 5.15 extern int domid; 5.16 5.17 +PCI_EMULATION_INFO *PciEmulationInfoHead = NULL; 5.18 + 5.19 /***********************************************************/ 5.20 /* x86 ISA bus support */ 5.21 5.22 @@ -4399,6 +4404,17 @@ void do_pci_add(char *devname) 5.23 #endif 5.24 } 5.25 5.26 +static int pci_emulation_add(char *config_text) 5.27 +{ 5.28 + PCI_EMULATION_INFO *new; 5.29 + if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) { 5.30 + return -1; 5.31 + } 5.32 + parse_pci_emulation_info(config_text, new); 5.33 + new->next = PciEmulationInfoHead; 5.34 + PciEmulationInfoHead = new; 5.35 + return 0; 5.36 +} 5.37 5.38 /***********************************************************/ 5.39 /* pid file */ 5.40 @@ -6590,6 +6606,7 @@ void help(void) 5.41 #endif 5.42 "-option-rom rom load a file, rom, into the option ROM space\n" 5.43 "-acpi disable or enable ACPI of HVM domain \n" 5.44 + "-pciemulation name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n" 5.45 "\n" 5.46 "During emulation, the following keys are useful:\n" 5.47 "ctrl-alt-f toggle full screen\n" 5.48 @@ -6688,6 +6705,7 @@ enum { 5.49 QEMU_OPTION_vncviewer, 5.50 QEMU_OPTION_vncunused, 5.51 QEMU_OPTION_pci, 5.52 + QEMU_OPTION_pci_emulation, 5.53 }; 5.54 5.55 typedef struct QEMUOption { 5.56 @@ -6789,6 +6807,7 @@ const QEMUOption qemu_options[] = { 5.57 { "vcpus", 1, QEMU_OPTION_vcpus }, 5.58 { "acpi", 0, QEMU_OPTION_acpi }, 5.59 { "pci", HAS_ARG, QEMU_OPTION_pci}, 5.60 + { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation }, 5.61 { NULL }, 5.62 }; 5.63 5.64 @@ -7073,6 +7092,8 @@ int main(int argc, char **argv) 5.65 sigset_t set; 5.66 char qemu_dm_logfilename[128]; 5.67 const char *direct_pci = direct_pci_str; 5.68 + int nb_pci_emulation = 0; 5.69 + char pci_emulation_config_text[MAX_PCI_EMULATION][256]; 5.70 5.71 #if !defined(__sun__) && !defined(CONFIG_STUBDOM) 5.72 /* Maximise rlimits. Needed where default constraints are tight (*BSD). */ 5.73 @@ -7598,6 +7619,16 @@ int main(int argc, char **argv) 5.74 case QEMU_OPTION_vncunused: 5.75 vncunused++; 5.76 break; 5.77 + case QEMU_OPTION_pci_emulation: 5.78 + if (nb_pci_emulation >= MAX_PCI_EMULATION) { 5.79 + fprintf(stderr, "Too many PCI emulations\n"); 5.80 + exit(1); 5.81 + } 5.82 + pstrcpy(pci_emulation_config_text[nb_pci_emulation], 5.83 + sizeof(pci_emulation_config_text[0]), 5.84 + optarg); 5.85 + nb_pci_emulation++; 5.86 + break; 5.87 } 5.88 } 5.89 } 5.90 @@ -7897,6 +7928,13 @@ int main(int argc, char **argv) 5.91 } 5.92 } 5.93 5.94 + for (i = 0; i < nb_pci_emulation; i++) { 5.95 + if(pci_emulation_add(pci_emulation_config_text[i]) < 0) { 5.96 + fprintf(stderr, "Warning: could not add PCI device %s\n", 5.97 + pci_emulation_config_text[i]); 5.98 + } 5.99 + } 5.100 + 5.101 qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL); 5.102 5.103 machine->init(ram_size, vga_ram_size, boot_device,
6.1 --- a/tools/ioemu/vl.h Wed Jun 18 09:39:14 2008 +0100 6.2 +++ b/tools/ioemu/vl.h Wed Jun 18 09:40:39 2008 +0100 6.3 @@ -1560,6 +1560,10 @@ void timeoffset_get(void); 6.4 void pci_xen_platform_init(PCIBus *bus); 6.5 #endif 6.6 6.7 +/* pci_emulation.c */ 6.8 +#ifndef QEMU_TOOL 6.9 +#include "hw/pci_emulation.h" 6.10 +#endif 6.11 6.12 void kqemu_record_dump(void); 6.13