From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=60019 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OjYVo-00037a-6E for qemu-devel@nongnu.org; Thu, 12 Aug 2010 10:12:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OjYUE-00011Z-6c for qemu-devel@nongnu.org; Thu, 12 Aug 2010 10:10:27 -0400 Received: from smtp02.citrix.com ([66.165.176.63]:51011) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OjYUE-0000vb-1C for qemu-devel@nongnu.org; Thu, 12 Aug 2010 10:10:26 -0400 From: stefano.stabellini@eu.citrix.com Date: Thu, 12 Aug 2010 15:09:59 +0100 Message-Id: <1281622202-3453-12-git-send-email-stefano.stabellini@eu.citrix.com> In-Reply-To: References: Subject: [Qemu-devel] [PATCH 12/15] piix_pci: introduce a write_config notifier List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony.Perard@citrix.com, Anthony PERARD , xen-devel@lists.xensource.com, Stefano Stabellini From: Anthony PERARD Introduce a write config notifier in piix_pci, so that clients can be notified every time a pci config write happens. The patch also makes use of the notification mechanism in xen_machine_fv. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini --- hw/pc.h | 1 + hw/piix_pci.c | 28 ++++++++++++++++++++++++++++ hw/xen_machine_fv.c | 16 ++++++++++++++++ 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/hw/pc.h b/hw/pc.h index ee562cd..3a745ae 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -141,6 +141,7 @@ typedef struct PCII440FXState PCII440FXState; void piix3_register_set_irq(pci_set_irq_fn set_irq); void piix3_register_map_irq(pci_map_irq_fn map_irq); +void piix_pci_register_write_config_notifier(PCII440FXState *d, PCIConfigWriteFunc *write_config); PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 56e3f61..afa9e9d 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -49,6 +49,13 @@ struct PCII440FXState { PIIX3State *piix3; }; +typedef struct PCII440FXWriteConfigNotifier { + PCIConfigWriteFunc *write_config; + QLIST_ENTRY(PCII440FXWriteConfigNotifier) next; +} PCII440FXWriteConfigNotifier; + +static QLIST_HEAD(write_config_list, PCII440FXWriteConfigNotifier) write_config_list + = QLIST_HEAD_INITIALIZER(write_config_list); #define I440FX_PAM 0x59 #define I440FX_PAM_SIZE 7 @@ -71,6 +78,25 @@ void piix3_register_map_irq(pci_map_irq_fn map_irq) piix3_map_irq_handler = map_irq; } +void piix_pci_register_write_config_notifier(PCII440FXState *d, PCIConfigWriteFunc *write_config) +{ + PCII440FXWriteConfigNotifier *new_notifier; + + assert(write_config); + new_notifier = qemu_mallocz(sizeof(PCII440FXWriteConfigNotifier)); + new_notifier->write_config = write_config; + QLIST_INSERT_HEAD(&write_config_list, new_notifier, next); +} + +static void piix_pci_notify_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len) +{ + PCII440FXWriteConfigNotifier *notifier; + + QLIST_FOREACH(notifier, &write_config_list, next) { + notifier->write_config(dev, address, val, len); + } +} + /* return the global irq number corresponding to a given device irq pin. We could also use the bus number to have a more precise mapping. */ @@ -157,6 +183,8 @@ static void i440fx_write_config(PCIDevice *dev, { PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev); + piix_pci_notify_write_config(dev, address, val, len); + /* XXX: implement SMRAM.D_LOCK */ pci_default_write_config(dev, address, val, len); if (ranges_overlap(address, len, I440FX_PAM, I440FX_PAM_SIZE) || diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c index 5d553b6..77563db 100644 --- a/hw/xen_machine_fv.c +++ b/hw/xen_machine_fv.c @@ -61,6 +61,21 @@ static void xen_piix3_set_irq(void *opaque, int irq_num, int level) irq_num & 3, level); } +static void xen_piix_pci_write_config_client(PCIDevice *dev, + uint32_t address, uint32_t val, int len) +{ + int i; + + /* Scan for updates to PCI link routes (0x60-0x63). */ + for (i = 0; i < len; i++) { + uint8_t v = (val >> (8*i)) & 0xff; + if (v & 0x80) + v = 0; + v &= 0xf; + if (((address+i) >= 0x60) && ((address+i) <= 0x63)) + xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v); + } +} static void xen_init_fv(ram_addr_t ram_size, const char *boot_device, @@ -141,6 +156,7 @@ static void xen_init_fv(ram_addr_t ram_size, piix3_register_set_irq(xen_piix3_set_irq); piix3_register_map_irq(xen_piix3_map_irq); pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); + piix_pci_register_write_config_notifier(i440fx_state, xen_piix_pci_write_config_client); isa_bus_irqs(isa_irq); pc_register_ferr_irq(isa_reserve_irq(13)); -- 1.7.0.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: stefano.stabellini@eu.citrix.com Subject: [PATCH 12/15] piix_pci: introduce a write_config notifier Date: Thu, 12 Aug 2010 15:09:59 +0100 Message-ID: <1281622202-3453-12-git-send-email-stefano.stabellini@eu.citrix.com> References: Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: qemu-devel@nongnu.org Cc: Anthony.Perard@citrix.com, Anthony PERARD , xen-devel@lists.xensource.com, Anthony Liguori , Stefano Stabellini List-Id: xen-devel@lists.xenproject.org From: Anthony PERARD Introduce a write config notifier in piix_pci, so that clients can be notified every time a pci config write happens. The patch also makes use of the notification mechanism in xen_machine_fv. Signed-off-by: Anthony PERARD Signed-off-by: Stefano Stabellini --- hw/pc.h | 1 + hw/piix_pci.c | 28 ++++++++++++++++++++++++++++ hw/xen_machine_fv.c | 16 ++++++++++++++++ 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/hw/pc.h b/hw/pc.h index ee562cd..3a745ae 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -141,6 +141,7 @@ typedef struct PCII440FXState PCII440FXState; void piix3_register_set_irq(pci_set_irq_fn set_irq); void piix3_register_map_irq(pci_map_irq_fn map_irq); +void piix_pci_register_write_config_notifier(PCII440FXState *d, PCIConfigWriteFunc *write_config); PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 56e3f61..afa9e9d 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -49,6 +49,13 @@ struct PCII440FXState { PIIX3State *piix3; }; +typedef struct PCII440FXWriteConfigNotifier { + PCIConfigWriteFunc *write_config; + QLIST_ENTRY(PCII440FXWriteConfigNotifier) next; +} PCII440FXWriteConfigNotifier; + +static QLIST_HEAD(write_config_list, PCII440FXWriteConfigNotifier) write_config_list + = QLIST_HEAD_INITIALIZER(write_config_list); #define I440FX_PAM 0x59 #define I440FX_PAM_SIZE 7 @@ -71,6 +78,25 @@ void piix3_register_map_irq(pci_map_irq_fn map_irq) piix3_map_irq_handler = map_irq; } +void piix_pci_register_write_config_notifier(PCII440FXState *d, PCIConfigWriteFunc *write_config) +{ + PCII440FXWriteConfigNotifier *new_notifier; + + assert(write_config); + new_notifier = qemu_mallocz(sizeof(PCII440FXWriteConfigNotifier)); + new_notifier->write_config = write_config; + QLIST_INSERT_HEAD(&write_config_list, new_notifier, next); +} + +static void piix_pci_notify_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len) +{ + PCII440FXWriteConfigNotifier *notifier; + + QLIST_FOREACH(notifier, &write_config_list, next) { + notifier->write_config(dev, address, val, len); + } +} + /* return the global irq number corresponding to a given device irq pin. We could also use the bus number to have a more precise mapping. */ @@ -157,6 +183,8 @@ static void i440fx_write_config(PCIDevice *dev, { PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev); + piix_pci_notify_write_config(dev, address, val, len); + /* XXX: implement SMRAM.D_LOCK */ pci_default_write_config(dev, address, val, len); if (ranges_overlap(address, len, I440FX_PAM, I440FX_PAM_SIZE) || diff --git a/hw/xen_machine_fv.c b/hw/xen_machine_fv.c index 5d553b6..77563db 100644 --- a/hw/xen_machine_fv.c +++ b/hw/xen_machine_fv.c @@ -61,6 +61,21 @@ static void xen_piix3_set_irq(void *opaque, int irq_num, int level) irq_num & 3, level); } +static void xen_piix_pci_write_config_client(PCIDevice *dev, + uint32_t address, uint32_t val, int len) +{ + int i; + + /* Scan for updates to PCI link routes (0x60-0x63). */ + for (i = 0; i < len; i++) { + uint8_t v = (val >> (8*i)) & 0xff; + if (v & 0x80) + v = 0; + v &= 0xf; + if (((address+i) >= 0x60) && ((address+i) <= 0x63)) + xc_hvm_set_pci_link_route(xen_xc, xen_domid, address + i - 0x60, v); + } +} static void xen_init_fv(ram_addr_t ram_size, const char *boot_device, @@ -141,6 +156,7 @@ static void xen_init_fv(ram_addr_t ram_size, piix3_register_set_irq(xen_piix3_set_irq); piix3_register_map_irq(xen_piix3_map_irq); pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); + piix_pci_register_write_config_notifier(i440fx_state, xen_piix_pci_write_config_client); isa_bus_irqs(isa_irq); pc_register_ferr_irq(isa_reserve_irq(13)); -- 1.7.0.4