All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
@ 2015-03-19 18:52 Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 01/26] acpi: add aml_or() term Marcel Apfelbaum
                   ` (28 more replies)
  0 siblings, 29 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Notes:
 - I realize that this qualifies as a late submission, but the code was arround
   a lot of time and got lots of reviews and it also tested (by Gerd), so should be mature enough.
 - This series is not that big, patches 1-8 are really small and can be submitted
   separately, however I preferred to keep them here to get the whole picture.

The series is fully functional.
 - Limitations:
   - Pxb's bus does not support hotplug. It will be addressed on top of this series
     because is already getting to big.
 - You are more than welcome to try using:
       -device pxb-device,id=pxb,bus_nr=4,numa_node=1 -device e1000,bus=pxb,addr=0x1 -bios <patched with the above series>

v5->v6:
 - This version includes a lot of refactoring requested by Michael S. Tsirking,
   but no new/different functionality:
   - Removed the HOST_BRIDGE_FOR_EACH loop because it too generic
   - Reduced the generic "extra pci roots" aproach to a more "non-generic"
     root bus having snooping buses listening to its configuration space.
     Instead of going over all host bridges, we go only over the snooping
     host bridges associated with the main host bridge.
   - The current implementation made i440fx the only a "snooped" host bridge
 - Addressed Michael S. Tsirkin's review:
   - Replaced qmp queries with native pci ones.
   - Squashed later patches into their places
   - Tweaked a few comments
 - Addressed Shannon Zhao's review:
   - Used build_append_byte instead of build_append_int
 - Addressed Gerd's review:
   - Reduced the "Line over 80" warnings.
 - Rebased on pci branch, tree: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git
   - a few days before, I hope is enough
 - Changed some patches order

v4->v5:
 - Rebased on pci branch, tree: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git
 - Added PXB documentation (patch 28/28)
 - Addressed Gerd Hoffmann's review:
   - fix PXB behaviour if used with unsupported BIOS (patch 27/28)
 - Addressed Michael S. Tsirkin's review:
   - Removed assert in aml_index (patch 5/28)
   - Renamed pci_ functions to crs_ (patch 12/28)
   - used uint64_t variables instead of signed ones (patch 12/28)
   - Emit MEM/IO AML only for PXBs and i440fx (patch 26/28)
 - Addressed Shannon Zhao's review:
   - Changed build_append_int to  build_append_byte in aml_or (patch 2/25)
 - Thanks to Igor and Kevin for reviews

v3->v4:
 - Addressed Michael S. Tsirkin's review:
   - refactored build_prt method (patch 11/25) 
     hw/apci: add _PRT method for extra PCI root busses
 - Addressed Igor Mammedov's reiew
   - add assert to aml_index (patch 5/25)
 - Fixed aml_equal implementation (patch 1/25)

v2->v3:
 - Rebased on Michael S. Tsirkin's pci branch (that includes now all the dependencies)
 - Refactored acpi terms patch into multiple patches to match Igor's design.

v1->v2:
 - Add support for multiple pxb devices.
 - Attach pxb's bus to specific NUMA node.
 - Got rid of the hacks from prev version.
 - Tested also for Win7 and Fedora 20, and for virtio blk devices.
 - Several bug-fixes resulting in a stable version ready for submission.

Reasoning:
We need multiple primary busess for a few reasons, the most important one
is to be able to associate a pass-trough device with a guest NUMA node.
The OS-es are able to associate a NUMA node only to a primary bus, not to
a specific PCI device or a pci-2-pci bridge.
PC machines support multiple NUMA nodes for CPUs and memory, however the IO
was not yet supported.

patch 1-8 adds the necessary acpi constructs based on Igor's series
patch 9 separates the pci_bus code into a designated file 
patch 10-11 implement some supporting methods
patch 12-13 Introduces the interfaces used to bind host bridges to the snooping ones
patch 14 made i440fx a snooped host bridge
patch 15-18 acpi support for snooping buses
patch 19 a qmp fix for multiple host bridgesi
patch 20 handles the actual implementation of the PXB devices
patch 21-22 enables the device
patch 23-24 adds NUMA support
patch 25 Backward compatibility with SeaBIOS
patch 26 PXB Documentation

Marcel Apfelbaum (26):
  acpi: add aml_or() term
  acpi: add aml_add() term
  acpi: add aml_lless() term
  acpi: add aml_index() term
  acpi: add aml_shiftleft() term
  acpi: add aml_shiftright() term
  acpi: add aml_increment() term
  acpi: add aml_while() term
  hw/pci: move pci bus related code to separate files
  hw/pci: made pci_bus_is_root a PCIBusClass method
  hw/pci: made pci_bus_num a PCIBusClass method
  hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  hw/pci-host/piix: implement TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  hw/acpi: add support for i440fx 'snooping' root busses
  hw/apci: add _PRT method for extra PCI root busses
  hw/acpi: add _CRS method for extra root busses
  hw/acpi: remove from root bus 0 the crs resources used by other busses.
  hw/pci: removed 'rootbus nr is 0' assumption from qmp_pci_query
  hw/pci: introduce PCI Expander Bridge (PXB)
  hw/pci: inform bios if the system has extra pci root buses
  hw/pxb: add map_irq func
  hw/pci_bus: add support for NUMA nodes
  hw/pxb: add numa_node parameter
  apci: fix PXB behaviour if used with unsupported BIOS
  docs: Add PXB documentation

 arch_init.c                         |   1 +
 docs/pci_expander_bridge.txt        |  52 ++++
 hw/acpi/aml-build.c                 |  75 ++++++
 hw/alpha/typhoon.c                  |   1 +
 hw/i386/acpi-build.c                | 377 ++++++++++++++++++++++++--
 hw/i386/kvm/pci-assign.c            |   1 +
 hw/i386/pc.c                        |  13 +
 hw/mips/gt64xxx_pci.c               |   1 +
 hw/pci-bridge/Makefile.objs         |   1 +
 hw/pci-bridge/pci_expander_bridge.c | 207 +++++++++++++++
 hw/pci-host/bonito.c                |   1 +
 hw/pci-host/grackle.c               |   1 +
 hw/pci-host/piix.c                  | 128 ++++++++-
 hw/pci-host/ppce500.c               |   1 +
 hw/pci-host/q35.c                   |   5 +
 hw/pci-host/uninorth.c              |   1 +
 hw/pci/Makefile.objs                |   2 +-
 hw/pci/pci.c                        | 493 +---------------------------------
 hw/pci/pci_bus.c                    | 517 ++++++++++++++++++++++++++++++++++++
 hw/pci/pci_host.c                   |  42 +++
 hw/ppc/ppc4xx_pci.c                 |   1 +
 hw/scsi/megasas.c                   |   1 +
 hw/sh4/r2d.c                        |   1 +
 hw/sh4/sh_pci.c                     |   1 +
 hw/vfio/pci.c                       |   1 +
 hw/xen/xen_pt.c                     |   1 +
 include/hw/acpi/aml-build.h         |   8 +
 include/hw/i386/pc.h                |   8 +-
 include/hw/pci/pci.h                |   6 +-
 include/hw/pci/pci_bus.h            |  35 +++
 include/hw/pci/pci_host.h           |  34 +++
 include/sysemu/sysemu.h             |   1 +
 32 files changed, 1508 insertions(+), 510 deletions(-)
 create mode 100644 docs/pci_expander_bridge.txt
 create mode 100644 hw/pci-bridge/pci_expander_bridge.c
 create mode 100644 hw/pci/pci_bus.c

-- 
2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* [Qemu-devel]  [PATCH V6 for-2.3 01/26] acpi: add aml_or() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 02/26] acpi: add aml_add() term Marcel Apfelbaum
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefOr Opcode.

Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 10 ++++++++++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 6242908..daba474 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -453,6 +453,16 @@ Aml *aml_and(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
+Aml *aml_or(Aml *arg1, Aml *arg2)
+{
+    Aml *var = aml_opcode(0x7D /* OrOp */);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    build_append_byte(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
 Aml *aml_notify(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 17d3beb..c0eb691 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -137,6 +137,7 @@ Aml *aml_int(const uint64_t val);
 Aml *aml_arg(int pos);
 Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
+Aml *aml_or(Aml *arg1, Aml *arg2);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
 Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel]  [PATCH V6 for-2.3 02/26] acpi: add aml_add() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 01/26] acpi: add aml_or() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 03/26] acpi: add aml_lless() term Marcel Apfelbaum
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefAdd Opcode.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 10 ++++++++++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index daba474..b01fb99 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -463,6 +463,16 @@ Aml *aml_or(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
+Aml *aml_add(Aml *arg1, Aml *arg2)
+{
+    Aml *var = aml_opcode(0x72 /* AddOp */);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    build_append_byte(var->buf, 0x00 /* NullNameOp */);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
 Aml *aml_notify(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index c0eb691..d7a3d0f 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -138,6 +138,7 @@ Aml *aml_arg(int pos);
 Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
 Aml *aml_or(Aml *arg1, Aml *arg2);
+Aml *aml_add(Aml *arg1, Aml *arg2);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
 Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel]  [PATCH V6 for-2.3 03/26] acpi: add aml_lless() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 01/26] acpi: add aml_or() term Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 02/26] acpi: add aml_add() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 04/26] acpi: add aml_index() term Marcel Apfelbaum
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefLLess Opcode.

Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 9 +++++++++
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index b01fb99..e44a221 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -463,6 +463,15 @@ Aml *aml_or(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
+Aml *aml_lless(Aml *arg1, Aml *arg2)
+{
+    Aml *var = aml_opcode(0x95 /* LLessOp */);
+    aml_append(var, arg1);
+    aml_append(var, arg2);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
 Aml *aml_add(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index d7a3d0f..8a79e7f 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -138,6 +138,7 @@ Aml *aml_arg(int pos);
 Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
 Aml *aml_or(Aml *arg1, Aml *arg2);
+Aml *aml_lless(Aml *arg1, Aml *arg2);
 Aml *aml_add(Aml *arg1, Aml *arg2);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
 Aml *aml_call1(const char *method, Aml *arg1);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel]  [PATCH V6 for-2.3 04/26] acpi: add aml_index() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (2 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 03/26] acpi: add aml_lless() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 05/26] acpi: add aml_shiftleft() term Marcel Apfelbaum
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefIndex Opcode.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 10 ++++++++++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index e44a221..ad8c04d 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -482,6 +482,16 @@ Aml *aml_add(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
+Aml *aml_index(Aml *arg1, Aml *idx)
+{
+    Aml *var = aml_opcode(0x88 /* IndexOp */);
+    aml_append(var, arg1);
+    aml_append(var, idx);
+    build_append_byte(var->buf, 0x00 /* NullNameOp */);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
 Aml *aml_notify(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 8a79e7f..d5a2697 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -140,6 +140,7 @@ Aml *aml_and(Aml *arg1, Aml *arg2);
 Aml *aml_or(Aml *arg1, Aml *arg2);
 Aml *aml_lless(Aml *arg1, Aml *arg2);
 Aml *aml_add(Aml *arg1, Aml *arg2);
+Aml *aml_index(Aml *arg1, Aml *idx);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
 Aml *aml_call1(const char *method, Aml *arg1);
 Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 05/26] acpi: add aml_shiftleft() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (3 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 04/26] acpi: add aml_index() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 06/26] acpi: add aml_shiftright() term Marcel Apfelbaum
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefShiftLeft Opcode.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 10 ++++++++++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index ad8c04d..428ea47 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -463,6 +463,16 @@ Aml *aml_or(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */
+Aml *aml_shiftleft(Aml *arg1, Aml *count)
+{
+    Aml *var = aml_opcode(0x79 /* ShiftLeftOp */);
+    aml_append(var, arg1);
+    aml_append(var, count);
+    build_append_byte(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
 Aml *aml_lless(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index d5a2697..26eff03 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -138,6 +138,7 @@ Aml *aml_arg(int pos);
 Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
 Aml *aml_or(Aml *arg1, Aml *arg2);
+Aml *aml_shiftleft(Aml *arg1, Aml *count);
 Aml *aml_lless(Aml *arg1, Aml *arg2);
 Aml *aml_add(Aml *arg1, Aml *arg2);
 Aml *aml_index(Aml *arg1, Aml *idx);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 06/26] acpi: add aml_shiftright() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (4 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 05/26] acpi: add aml_shiftleft() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 07/26] acpi: add aml_increment() term Marcel Apfelbaum
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefShiftRight Opcode.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 10 ++++++++++
 include/hw/acpi/aml-build.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 428ea47..64b129b 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -473,6 +473,16 @@ Aml *aml_shiftleft(Aml *arg1, Aml *count)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */
+Aml *aml_shiftright(Aml *arg1, Aml *count)
+{
+    Aml *var = aml_opcode(0x7A /* ShiftRightOp */);
+    aml_append(var, arg1);
+    aml_append(var, count);
+    build_append_byte(var->buf, 0x00); /* NullNameOp */
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
 Aml *aml_lless(Aml *arg1, Aml *arg2)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 26eff03..ead0cc9 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -139,6 +139,7 @@ Aml *aml_store(Aml *val, Aml *target);
 Aml *aml_and(Aml *arg1, Aml *arg2);
 Aml *aml_or(Aml *arg1, Aml *arg2);
 Aml *aml_shiftleft(Aml *arg1, Aml *count);
+Aml *aml_shiftright(Aml *arg1, Aml *count);
 Aml *aml_lless(Aml *arg1, Aml *arg2);
 Aml *aml_add(Aml *arg1, Aml *arg2);
 Aml *aml_index(Aml *arg1, Aml *idx);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 07/26] acpi: add aml_increment() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (5 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 06/26] acpi: add aml_shiftright() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 08/26] acpi: add aml_while() term Marcel Apfelbaum
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefIncrement Opcode.

Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 8 ++++++++
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 64b129b..757d611 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -502,6 +502,14 @@ Aml *aml_add(Aml *arg1, Aml *arg2)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */
+Aml *aml_increment(Aml *arg)
+{
+    Aml *var = aml_opcode(0x75 /* IncrementOp */);
+    aml_append(var, arg);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
 Aml *aml_index(Aml *arg1, Aml *idx)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index ead0cc9..6c68125 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -142,6 +142,7 @@ Aml *aml_shiftleft(Aml *arg1, Aml *count);
 Aml *aml_shiftright(Aml *arg1, Aml *count);
 Aml *aml_lless(Aml *arg1, Aml *arg2);
 Aml *aml_add(Aml *arg1, Aml *arg2);
+Aml *aml_increment(Aml *arg);
 Aml *aml_index(Aml *arg1, Aml *idx);
 Aml *aml_notify(Aml *arg1, Aml *arg2);
 Aml *aml_call1(const char *method, Aml *arg1);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel]  [PATCH V6 for-2.3 08/26] acpi: add aml_while() term
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (6 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 07/26] acpi: add aml_increment() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files Marcel Apfelbaum
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Add encoding for ACPI DefWhile Opcode.

Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/acpi/aml-build.c         | 8 ++++++++
 include/hw/acpi/aml-build.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 757d611..cbb3f8d 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -625,6 +625,14 @@ Aml *aml_if(Aml *predicate)
     return var;
 }
 
+/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefWhile */
+Aml *aml_while(Aml *predicate)
+{
+    Aml *var = aml_bundle(0xA2 /* WhileOp */, AML_PACKAGE);
+    aml_append(var, predicate);
+    return var;
+}
+
 /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
 Aml *aml_method(const char *name, int arg_count)
 {
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 6c68125..7bb72c0 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -189,6 +189,7 @@ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2);
 Aml *aml_method(const char *name, int arg_count);
 Aml *aml_if(Aml *predicate);
+Aml *aml_while(Aml *predicate);
 Aml *aml_package(uint8_t num_elements);
 Aml *aml_buffer(void);
 Aml *aml_resource_template(void);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (7 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 08/26] acpi: add aml_while() term Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-04-27 11:14   ` Michael S. Tsirkin
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method Marcel Apfelbaum
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

This refactoring moves all the code needed (recursively)
to register TYPE_PCI_BUS type to a new file hw/pci/pci_bus.c .
This allows to properly add new functionality to the pci bus class.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 arch_init.c              |   1 +
 hw/alpha/typhoon.c       |   1 +
 hw/mips/gt64xxx_pci.c    |   1 +
 hw/pci-host/bonito.c     |   1 +
 hw/pci-host/grackle.c    |   1 +
 hw/pci-host/piix.c       |   1 +
 hw/pci-host/ppce500.c    |   1 +
 hw/pci-host/q35.c        |   1 +
 hw/pci-host/uninorth.c   |   1 +
 hw/pci/Makefile.objs     |   2 +-
 hw/pci/pci.c             | 472 +--------------------------------------------
 hw/pci/pci_bus.c         | 491 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/ppc/ppc4xx_pci.c      |   1 +
 hw/sh4/r2d.c             |   1 +
 hw/sh4/sh_pci.c          |   1 +
 include/hw/pci/pci.h     |   3 +-
 include/hw/pci/pci_bus.h |   8 +
 17 files changed, 514 insertions(+), 474 deletions(-)
 create mode 100644 hw/pci/pci_bus.c

diff --git a/arch_init.c b/arch_init.c
index 691b5e2..cbebf6d 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -37,6 +37,7 @@
 #include "audio/audio.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/audio/audio.h"
 #include "sysemu/kvm.h"
 #include "migration/migration.h"
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 62af946..d3fad5d 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -8,6 +8,7 @@
 
 #include "cpu.h"
 #include "hw/hw.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/devices.h"
 #include "sysemu/sysemu.h"
 #include "alpha_sys.h"
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 10fcca3..c4ca6f3 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -25,6 +25,7 @@
 #include "hw/hw.h"
 #include "hw/mips/mips.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "hw/i386/pc.h"
 #include "exec/address-spaces.h"
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 8bdd569..49e1122 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -41,6 +41,7 @@
 
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/i386/pc.h"
 #include "hw/mips/mips.h"
 #include "hw/pci/pci_host.h"
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index bfe707a..89745cd 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -26,6 +26,7 @@
 #include "hw/pci/pci_host.h"
 #include "hw/ppc/mac.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 
 /* debug Grackle */
 //#define DEBUG_GRACKLE
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 723836f..292b6e9 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -25,6 +25,7 @@
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 613ba73..4363951 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -17,6 +17,7 @@
 #include "hw/hw.h"
 #include "hw/ppc/e500-ccsr.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "qemu/bswap.h"
 #include "hw/pci-host/ppce500.h"
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index c8827cc..5dd559e 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -28,6 +28,7 @@
  * THE SOFTWARE.
  */
 #include "hw/hw.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci-host/q35.h"
 #include "qapi/visitor.h"
 
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 53f2b59..1406b42 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -24,6 +24,7 @@
 #include "hw/hw.h"
 #include "hw/ppc/mac.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 
 /* debug UniNorth */
diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 9f905e6..a05cca0 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o
+common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bus.o
 common-obj-$(CONFIG_PCI) += msix.o msi.o
 common-obj-$(CONFIG_PCI) += shpc.o
 common-obj-$(CONFIG_PCI) += slotid_cap.o
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 6941a82..cb63a21 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -45,11 +45,6 @@
 # define PCI_DPRINTF(format, ...)       do { } while (0)
 #endif
 
-static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
-static char *pcibus_get_dev_path(DeviceState *dev);
-static char *pcibus_get_fw_dev_path(DeviceState *dev);
-static void pcibus_reset(BusState *qbus);
-
 static Property pci_props[] = {
     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
     DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
@@ -61,58 +56,11 @@ static Property pci_props[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
-static const VMStateDescription vmstate_pcibus = {
-    .name = "PCIBUS",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT32_EQUAL(nirq, PCIBus),
-        VMSTATE_VARRAY_INT32(irq_count, PCIBus,
-                             nirq, 0, vmstate_info_int32,
-                             int32_t),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void pci_bus_realize(BusState *qbus, Error **errp)
-{
-    PCIBus *bus = PCI_BUS(qbus);
-
-    vmstate_register(NULL, -1, &vmstate_pcibus, bus);
-}
-
-static void pci_bus_unrealize(BusState *qbus, Error **errp)
-{
-    PCIBus *bus = PCI_BUS(qbus);
-
-    vmstate_unregister(NULL, &vmstate_pcibus, bus);
-}
-
-static void pci_bus_class_init(ObjectClass *klass, void *data)
-{
-    BusClass *k = BUS_CLASS(klass);
-
-    k->print_dev = pcibus_dev_print;
-    k->get_dev_path = pcibus_get_dev_path;
-    k->get_fw_dev_path = pcibus_get_fw_dev_path;
-    k->realize = pci_bus_realize;
-    k->unrealize = pci_bus_unrealize;
-    k->reset = pcibus_reset;
-}
-
-static const TypeInfo pci_bus_info = {
-    .name = TYPE_PCI_BUS,
-    .parent = TYPE_BUS,
-    .instance_size = sizeof(PCIBus),
-    .class_init = pci_bus_class_init,
-};
-
 static const TypeInfo pcie_bus_info = {
     .name = TYPE_PCIE_BUS,
     .parent = TYPE_PCI_BUS,
 };
 
-static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
 static void pci_update_mappings(PCIDevice *d);
 static void pci_irq_handler(void *opaque, int irq_num, int level);
 static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, Error **);
@@ -185,7 +133,7 @@ void pci_device_deassert_intx(PCIDevice *dev)
     }
 }
 
-static void pci_do_device_reset(PCIDevice *dev)
+void pci_do_device_reset(PCIDevice *dev)
 {
     int r;
 
@@ -230,27 +178,6 @@ void pci_device_reset(PCIDevice *dev)
     pci_do_device_reset(dev);
 }
 
-/*
- * Trigger pci bus reset under a given bus.
- * Called via qbus_reset_all on RST# assert, after the devices
- * have been reset qdev_reset_all-ed already.
- */
-static void pcibus_reset(BusState *qbus)
-{
-    PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
-        if (bus->devices[i]) {
-            pci_do_device_reset(bus->devices[i]);
-        }
-    }
-
-    for (i = 0; i < bus->nirq; i++) {
-        assert(bus->irq_count[i] == 0);
-    }
-}
-
 static void pci_host_bus_register(PCIBus *bus, DeviceState *parent)
 {
     PCIHostState *host_bridge = PCI_HOST_BRIDGE(parent);
@@ -1301,74 +1228,6 @@ int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin)
     return (pin + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS;
 }
 
-/***********************************************************/
-/* monitor info on PCI */
-
-typedef struct {
-    uint16_t class;
-    const char *desc;
-    const char *fw_name;
-    uint16_t fw_ign_bits;
-} pci_class_desc;
-
-static const pci_class_desc pci_class_descriptions[] =
-{
-    { 0x0001, "VGA controller", "display"},
-    { 0x0100, "SCSI controller", "scsi"},
-    { 0x0101, "IDE controller", "ide"},
-    { 0x0102, "Floppy controller", "fdc"},
-    { 0x0103, "IPI controller", "ipi"},
-    { 0x0104, "RAID controller", "raid"},
-    { 0x0106, "SATA controller"},
-    { 0x0107, "SAS controller"},
-    { 0x0180, "Storage controller"},
-    { 0x0200, "Ethernet controller", "ethernet"},
-    { 0x0201, "Token Ring controller", "token-ring"},
-    { 0x0202, "FDDI controller", "fddi"},
-    { 0x0203, "ATM controller", "atm"},
-    { 0x0280, "Network controller"},
-    { 0x0300, "VGA controller", "display", 0x00ff},
-    { 0x0301, "XGA controller"},
-    { 0x0302, "3D controller"},
-    { 0x0380, "Display controller"},
-    { 0x0400, "Video controller", "video"},
-    { 0x0401, "Audio controller", "sound"},
-    { 0x0402, "Phone"},
-    { 0x0403, "Audio controller", "sound"},
-    { 0x0480, "Multimedia controller"},
-    { 0x0500, "RAM controller", "memory"},
-    { 0x0501, "Flash controller", "flash"},
-    { 0x0580, "Memory controller"},
-    { 0x0600, "Host bridge", "host"},
-    { 0x0601, "ISA bridge", "isa"},
-    { 0x0602, "EISA bridge", "eisa"},
-    { 0x0603, "MC bridge", "mca"},
-    { 0x0604, "PCI bridge", "pci-bridge"},
-    { 0x0605, "PCMCIA bridge", "pcmcia"},
-    { 0x0606, "NUBUS bridge", "nubus"},
-    { 0x0607, "CARDBUS bridge", "cardbus"},
-    { 0x0608, "RACEWAY bridge"},
-    { 0x0680, "Bridge"},
-    { 0x0700, "Serial port", "serial"},
-    { 0x0701, "Parallel port", "parallel"},
-    { 0x0800, "Interrupt controller", "interrupt-controller"},
-    { 0x0801, "DMA controller", "dma-controller"},
-    { 0x0802, "Timer", "timer"},
-    { 0x0803, "RTC", "rtc"},
-    { 0x0900, "Keyboard", "keyboard"},
-    { 0x0901, "Pen", "pen"},
-    { 0x0902, "Mouse", "mouse"},
-    { 0x0A00, "Dock station", "dock", 0x00ff},
-    { 0x0B00, "i386 cpu", "cpu", 0x00ff},
-    { 0x0c00, "Fireware contorller", "fireware"},
-    { 0x0c01, "Access bus controller", "access-bus"},
-    { 0x0c02, "SSA controller", "ssa"},
-    { 0x0c03, "USB controller", "usb"},
-    { 0x0c04, "Fibre channel controller", "fibre-channel"},
-    { 0x0c05, "SMBus"},
-    { 0, NULL}
-};
-
 static void pci_for_each_device_under_bus(PCIBus *bus,
                                           void (*fn)(PCIBus *b, PCIDevice *d,
                                                      void *opaque),
@@ -1396,161 +1255,6 @@ void pci_for_each_device(PCIBus *bus, int bus_num,
     }
 }
 
-static const pci_class_desc *get_class_desc(int class)
-{
-    const pci_class_desc *desc;
-
-    desc = pci_class_descriptions;
-    while (desc->desc && class != desc->class) {
-        desc++;
-    }
-
-    return desc;
-}
-
-static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
-
-static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
-{
-    PciMemoryRegionList *head = NULL, *cur_item = NULL;
-    int i;
-
-    for (i = 0; i < PCI_NUM_REGIONS; i++) {
-        const PCIIORegion *r = &dev->io_regions[i];
-        PciMemoryRegionList *region;
-
-        if (!r->size) {
-            continue;
-        }
-
-        region = g_malloc0(sizeof(*region));
-        region->value = g_malloc0(sizeof(*region->value));
-
-        if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
-            region->value->type = g_strdup("io");
-        } else {
-            region->value->type = g_strdup("memory");
-            region->value->has_prefetch = true;
-            region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
-            region->value->has_mem_type_64 = true;
-            region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
-        }
-
-        region->value->bar = i;
-        region->value->address = r->addr;
-        region->value->size = r->size;
-
-        /* XXX: waiting for the qapi to support GSList */
-        if (!cur_item) {
-            head = cur_item = region;
-        } else {
-            cur_item->next = region;
-            cur_item = region;
-        }
-    }
-
-    return head;
-}
-
-static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
-                                           int bus_num)
-{
-    PciBridgeInfo *info;
-
-    info = g_malloc0(sizeof(*info));
-
-    info->bus.number = dev->config[PCI_PRIMARY_BUS];
-    info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
-    info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
-
-    info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
-    info->bus.io_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
-    info->bus.io_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
-
-    info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
-    info->bus.memory_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
-    info->bus.memory_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
-
-    info->bus.prefetchable_range = g_malloc0(sizeof(*info->bus.prefetchable_range));
-    info->bus.prefetchable_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
-    info->bus.prefetchable_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
-
-    if (dev->config[PCI_SECONDARY_BUS] != 0) {
-        PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]);
-        if (child_bus) {
-            info->has_devices = true;
-            info->devices = qmp_query_pci_devices(child_bus, dev->config[PCI_SECONDARY_BUS]);
-        }
-    }
-
-    return info;
-}
-
-static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
-                                           int bus_num)
-{
-    const pci_class_desc *desc;
-    PciDeviceInfo *info;
-    uint8_t type;
-    int class;
-
-    info = g_malloc0(sizeof(*info));
-    info->bus = bus_num;
-    info->slot = PCI_SLOT(dev->devfn);
-    info->function = PCI_FUNC(dev->devfn);
-
-    class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
-    info->class_info.q_class = class;
-    desc = get_class_desc(class);
-    if (desc->desc) {
-        info->class_info.has_desc = true;
-        info->class_info.desc = g_strdup(desc->desc);
-    }
-
-    info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
-    info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
-    info->regions = qmp_query_pci_regions(dev);
-    info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
-
-    if (dev->config[PCI_INTERRUPT_PIN] != 0) {
-        info->has_irq = true;
-        info->irq = dev->config[PCI_INTERRUPT_LINE];
-    }
-
-    type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
-    if (type == PCI_HEADER_TYPE_BRIDGE) {
-        info->has_pci_bridge = true;
-        info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
-    }
-
-    return info;
-}
-
-static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
-{
-    PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
-    PCIDevice *dev;
-    int devfn;
-
-    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
-        dev = bus->devices[devfn];
-        if (dev) {
-            info = g_malloc0(sizeof(*info));
-            info->value = qmp_query_pci_device(dev, bus, bus_num);
-
-            /* XXX: waiting for the qapi to support GSList */
-            if (!cur_item) {
-                head = cur_item = info;
-            } else {
-                cur_item->next = info;
-                cur_item = info;
-            }
-        }
-    }
-
-    return head;
-}
-
 static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num)
 {
     PciInfo *info = NULL;
@@ -1684,50 +1388,6 @@ PCIDevice *pci_vga_init(PCIBus *bus)
     }
 }
 
-/* Whether a given bus number is in range of the secondary
- * bus of the given bridge device. */
-static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
-{
-    return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
-             PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ &&
-        dev->config[PCI_SECONDARY_BUS] < bus_num &&
-        bus_num <= dev->config[PCI_SUBORDINATE_BUS];
-}
-
-static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
-{
-    PCIBus *sec;
-
-    if (!bus) {
-        return NULL;
-    }
-
-    if (pci_bus_num(bus) == bus_num) {
-        return bus;
-    }
-
-    /* Consider all bus numbers in range for the host pci bridge. */
-    if (!pci_bus_is_root(bus) &&
-        !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
-        return NULL;
-    }
-
-    /* try child bus */
-    for (; bus; bus = sec) {
-        QLIST_FOREACH(sec, &bus->child, sibling) {
-            assert(!pci_bus_is_root(sec));
-            if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
-                return sec;
-            }
-            if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
-                break;
-            }
-        }
-    }
-
-    return NULL;
-}
-
 void pci_for_each_bus_depth_first(PCIBus *bus,
                                   void *(*begin)(PCIBus *bus, void *parent_state),
                                   void (*end)(PCIBus *bus, void *state),
@@ -2140,135 +1800,6 @@ uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id)
     return pci_find_capability_list(pdev, cap_id, NULL);
 }
 
-static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
-{
-    PCIDevice *d = (PCIDevice *)dev;
-    const pci_class_desc *desc;
-    char ctxt[64];
-    PCIIORegion *r;
-    int i, class;
-
-    class = pci_get_word(d->config + PCI_CLASS_DEVICE);
-    desc = pci_class_descriptions;
-    while (desc->desc && class != desc->class)
-        desc++;
-    if (desc->desc) {
-        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
-    } else {
-        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
-    }
-
-    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
-                   "pci id %04x:%04x (sub %04x:%04x)\n",
-                   indent, "", ctxt, pci_bus_num(d->bus),
-                   PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
-                   pci_get_word(d->config + PCI_VENDOR_ID),
-                   pci_get_word(d->config + PCI_DEVICE_ID),
-                   pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
-                   pci_get_word(d->config + PCI_SUBSYSTEM_ID));
-    for (i = 0; i < PCI_NUM_REGIONS; i++) {
-        r = &d->io_regions[i];
-        if (!r->size)
-            continue;
-        monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
-                       " [0x%"FMT_PCIBUS"]\n",
-                       indent, "",
-                       i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
-                       r->addr, r->addr + r->size - 1);
-    }
-}
-
-static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
-{
-    PCIDevice *d = (PCIDevice *)dev;
-    const char *name = NULL;
-    const pci_class_desc *desc =  pci_class_descriptions;
-    int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
-
-    while (desc->desc &&
-          (class & ~desc->fw_ign_bits) !=
-          (desc->class & ~desc->fw_ign_bits)) {
-        desc++;
-    }
-
-    if (desc->desc) {
-        name = desc->fw_name;
-    }
-
-    if (name) {
-        pstrcpy(buf, len, name);
-    } else {
-        snprintf(buf, len, "pci%04x,%04x",
-                 pci_get_word(d->config + PCI_VENDOR_ID),
-                 pci_get_word(d->config + PCI_DEVICE_ID));
-    }
-
-    return buf;
-}
-
-static char *pcibus_get_fw_dev_path(DeviceState *dev)
-{
-    PCIDevice *d = (PCIDevice *)dev;
-    char path[50], name[33];
-    int off;
-
-    off = snprintf(path, sizeof(path), "%s@%x",
-                   pci_dev_fw_name(dev, name, sizeof name),
-                   PCI_SLOT(d->devfn));
-    if (PCI_FUNC(d->devfn))
-        snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
-    return g_strdup(path);
-}
-
-static char *pcibus_get_dev_path(DeviceState *dev)
-{
-    PCIDevice *d = container_of(dev, PCIDevice, qdev);
-    PCIDevice *t;
-    int slot_depth;
-    /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
-     * 00 is added here to make this format compatible with
-     * domain:Bus:Slot.Func for systems without nested PCI bridges.
-     * Slot.Function list specifies the slot and function numbers for all
-     * devices on the path from root to the specific device. */
-    const char *root_bus_path;
-    int root_bus_len;
-    char slot[] = ":SS.F";
-    int slot_len = sizeof slot - 1 /* For '\0' */;
-    int path_len;
-    char *path, *p;
-    int s;
-
-    root_bus_path = pci_root_bus_path(d);
-    root_bus_len = strlen(root_bus_path);
-
-    /* Calculate # of slots on path between device and root. */;
-    slot_depth = 0;
-    for (t = d; t; t = t->bus->parent_dev) {
-        ++slot_depth;
-    }
-
-    path_len = root_bus_len + slot_len * slot_depth;
-
-    /* Allocate memory, fill in the terminating null byte. */
-    path = g_malloc(path_len + 1 /* For '\0' */);
-    path[path_len] = '\0';
-
-    memcpy(path, root_bus_path, root_bus_len);
-
-    /* Fill in slot numbers. We walk up from device to root, so need to print
-     * them in the reverse order, last to first. */
-    p = path + path_len;
-    for (t = d; t; t = t->bus->parent_dev) {
-        p -= slot_len;
-        s = snprintf(slot, sizeof slot, ":%02x.%x",
-                     PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
-        assert(s == slot_len);
-        memcpy(p, slot, slot_len);
-    }
-
-    return path;
-}
-
 static int pci_qdev_find_recursive(PCIBus *bus,
                                    const char *id, PCIDevice **pdev)
 {
@@ -2414,7 +1945,6 @@ static const TypeInfo pci_device_type_info = {
 
 static void pci_register_types(void)
 {
-    type_register_static(&pci_bus_info);
     type_register_static(&pcie_bus_info);
     type_register_static(&pci_device_type_info);
 }
diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
new file mode 100644
index 0000000..d156194
--- /dev/null
+++ b/hw/pci/pci_bus.c
@@ -0,0 +1,491 @@
+/*
+ * PCI Bus
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * Authors:
+ *   Marcel Apfelbaum <marcel.a@redhat.com> (split out from pci.c)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_bridge.h"
+#include "monitor/monitor.h"
+
+typedef struct {
+    uint16_t class;
+    const char *desc;
+    const char *fw_name;
+    uint16_t fw_ign_bits;
+} pci_class_desc;
+
+static const pci_class_desc pci_class_descriptions[] = {
+    { 0x0001, "VGA controller", "display"},
+    { 0x0100, "SCSI controller", "scsi"},
+    { 0x0101, "IDE controller", "ide"},
+    { 0x0102, "Floppy controller", "fdc"},
+    { 0x0103, "IPI controller", "ipi"},
+    { 0x0104, "RAID controller", "raid"},
+    { 0x0106, "SATA controller"},
+    { 0x0107, "SAS controller"},
+    { 0x0180, "Storage controller"},
+    { 0x0200, "Ethernet controller", "ethernet"},
+    { 0x0201, "Token Ring controller", "token-ring"},
+    { 0x0202, "FDDI controller", "fddi"},
+    { 0x0203, "ATM controller", "atm"},
+    { 0x0280, "Network controller"},
+    { 0x0300, "VGA controller", "display", 0x00ff},
+    { 0x0301, "XGA controller"},
+    { 0x0302, "3D controller"},
+    { 0x0380, "Display controller"},
+    { 0x0400, "Video controller", "video"},
+    { 0x0401, "Audio controller", "sound"},
+    { 0x0402, "Phone"},
+    { 0x0403, "Audio controller", "sound"},
+    { 0x0480, "Multimedia controller"},
+    { 0x0500, "RAM controller", "memory"},
+    { 0x0501, "Flash controller", "flash"},
+    { 0x0580, "Memory controller"},
+    { 0x0600, "Host bridge", "host"},
+    { 0x0601, "ISA bridge", "isa"},
+    { 0x0602, "EISA bridge", "eisa"},
+    { 0x0603, "MC bridge", "mca"},
+    { 0x0604, "PCI bridge", "pci-bridge"},
+    { 0x0605, "PCMCIA bridge", "pcmcia"},
+    { 0x0606, "NUBUS bridge", "nubus"},
+    { 0x0607, "CARDBUS bridge", "cardbus"},
+    { 0x0608, "RACEWAY bridge"},
+    { 0x0680, "Bridge"},
+    { 0x0700, "Serial port", "serial"},
+    { 0x0701, "Parallel port", "parallel"},
+    { 0x0800, "Interrupt controller", "interrupt-controller"},
+    { 0x0801, "DMA controller", "dma-controller"},
+    { 0x0802, "Timer", "timer"},
+    { 0x0803, "RTC", "rtc"},
+    { 0x0900, "Keyboard", "keyboard"},
+    { 0x0901, "Pen", "pen"},
+    { 0x0902, "Mouse", "mouse"},
+    { 0x0A00, "Dock station", "dock", 0x00ff},
+    { 0x0B00, "i386 cpu", "cpu", 0x00ff},
+    { 0x0c00, "Fireware contorller", "fireware"},
+    { 0x0c01, "Access bus controller", "access-bus"},
+    { 0x0c02, "SSA controller", "ssa"},
+    { 0x0c03, "USB controller", "usb"},
+    { 0x0c04, "Fibre channel controller", "fibre-channel"},
+    { 0x0c05, "SMBus"},
+    { 0, NULL}
+};
+
+/* Whether a given bus number is in range of the secondary
+ * bus of the given bridge device. */
+static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
+{
+    return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
+             PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ &&
+        dev->config[PCI_SECONDARY_BUS] < bus_num &&
+        bus_num <= dev->config[PCI_SUBORDINATE_BUS];
+}
+
+PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
+{
+    PCIBus *sec;
+
+    if (!bus) {
+        return NULL;
+    }
+
+    if (pci_bus_num(bus) == bus_num) {
+        return bus;
+    }
+
+    /* Consider all bus numbers in range for the host pci bridge. */
+    if (!pci_bus_is_root(bus) &&
+        !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
+        return NULL;
+    }
+
+    /* try child bus */
+    for (; bus; bus = sec) {
+        QLIST_FOREACH(sec, &bus->child, sibling) {
+            assert(!pci_bus_is_root(sec));
+            if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
+                return sec;
+            }
+            if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
+                break;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+static const pci_class_desc *get_class_desc(int class)
+{
+    const pci_class_desc *desc;
+
+    desc = pci_class_descriptions;
+    while (desc->desc && class != desc->class) {
+        desc++;
+    }
+
+    return desc;
+}
+
+static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
+{
+    PciMemoryRegionList *head = NULL, *cur_item = NULL;
+    int i;
+
+    for (i = 0; i < PCI_NUM_REGIONS; i++) {
+        const PCIIORegion *r = &dev->io_regions[i];
+        PciMemoryRegionList *region;
+
+        if (!r->size) {
+            continue;
+        }
+
+        region = g_malloc0(sizeof(*region));
+        region->value = g_malloc0(sizeof(*region->value));
+
+        if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+            region->value->type = g_strdup("io");
+        } else {
+            region->value->type = g_strdup("memory");
+            region->value->has_prefetch = true;
+            region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
+            region->value->has_mem_type_64 = true;
+            region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
+        }
+
+        region->value->bar = i;
+        region->value->address = r->addr;
+        region->value->size = r->size;
+
+        /* XXX: waiting for the qapi to support GSList */
+        if (!cur_item) {
+            head = cur_item = region;
+        } else {
+            cur_item->next = region;
+            cur_item = region;
+        }
+    }
+
+    return head;
+}
+
+static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
+                                           int bus_num)
+{
+    PciBridgeInfo *info;
+
+    info = g_malloc0(sizeof(*info));
+
+    info->bus.number = dev->config[PCI_PRIMARY_BUS];
+    info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
+    info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
+
+    info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
+    info->bus.io_range->base = pci_bridge_get_base(dev,
+                    PCI_BASE_ADDRESS_SPACE_IO);
+    info->bus.io_range->limit =
+                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
+
+    info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
+    info->bus.memory_range->base =
+                    pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
+    info->bus.memory_range->limit =
+                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
+
+    info->bus.prefetchable_range =
+                    g_malloc0(sizeof(*info->bus.prefetchable_range));
+    info->bus.prefetchable_range->base =
+                    pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+    info->bus.prefetchable_range->limit =
+                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+
+    if (dev->config[PCI_SECONDARY_BUS] != 0) {
+        PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]);
+        if (child_bus) {
+            info->has_devices = true;
+            info->devices = qmp_query_pci_devices(child_bus,
+                                                  dev->config[PCI_SECONDARY_BUS]);
+        }
+    }
+
+    return info;
+}
+
+static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
+                                           int bus_num)
+{
+    const pci_class_desc *desc;
+    PciDeviceInfo *info;
+    uint8_t type;
+    int class;
+
+    info = g_malloc0(sizeof(*info));
+    info->bus = bus_num;
+    info->slot = PCI_SLOT(dev->devfn);
+    info->function = PCI_FUNC(dev->devfn);
+
+    class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
+    info->class_info.q_class = class;
+    desc = get_class_desc(class);
+    if (desc->desc) {
+        info->class_info.has_desc = true;
+        info->class_info.desc = g_strdup(desc->desc);
+    }
+
+    info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
+    info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
+    info->regions = qmp_query_pci_regions(dev);
+    info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
+
+    if (dev->config[PCI_INTERRUPT_PIN] != 0) {
+        info->has_irq = true;
+        info->irq = dev->config[PCI_INTERRUPT_LINE];
+    }
+
+    type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
+    if (type == PCI_HEADER_TYPE_BRIDGE) {
+        info->has_pci_bridge = true;
+        info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
+    }
+
+    return info;
+}
+
+PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
+{
+    PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
+    PCIDevice *dev;
+    int devfn;
+
+    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+        dev = bus->devices[devfn];
+        if (dev) {
+            info = g_malloc0(sizeof(*info));
+            info->value = qmp_query_pci_device(dev, bus, bus_num);
+
+            /* XXX: waiting for the qapi to support GSList */
+            if (!cur_item) {
+                head = cur_item = info;
+            } else {
+                cur_item->next = info;
+                cur_item = info;
+            }
+        }
+    }
+
+    return head;
+}
+
+
+static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
+{
+    PCIDevice *d = (PCIDevice *)dev;
+    const pci_class_desc *desc;
+    char ctxt[64];
+    PCIIORegion *r;
+    int i, class;
+
+    class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+    desc = pci_class_descriptions;
+    while (desc->desc && class != desc->class) {
+        desc++;
+    }
+    if (desc->desc) {
+        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
+    } else {
+        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
+    }
+
+    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
+                   "pci id %04x:%04x (sub %04x:%04x)\n",
+                   indent, "", ctxt, pci_bus_num(d->bus),
+                   PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
+                   pci_get_word(d->config + PCI_VENDOR_ID),
+                   pci_get_word(d->config + PCI_DEVICE_ID),
+                   pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
+                   pci_get_word(d->config + PCI_SUBSYSTEM_ID));
+    for (i = 0; i < PCI_NUM_REGIONS; i++) {
+        r = &d->io_regions[i];
+        if (!r->size) {
+            continue;
+        }
+        monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
+                       " [0x%"FMT_PCIBUS"]\n",
+                       indent, "",
+                       i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
+                       r->addr, r->addr + r->size - 1);
+    }
+}
+
+static char *pcibus_get_dev_path(DeviceState *dev)
+{
+    PCIDevice *d = container_of(dev, PCIDevice, qdev);
+    PCIDevice *t;
+    int slot_depth;
+    /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
+     * 00 is added here to make this format compatible with
+     * domain:Bus:Slot.Func for systems without nested PCI bridges.
+     * Slot.Function list specifies the slot and function numbers for all
+     * devices on the path from root to the specific device. */
+    const char *root_bus_path;
+    int root_bus_len;
+    char slot[] = ":SS.F";
+    int slot_len = sizeof slot - 1 /* For '\0' */;
+    int path_len;
+    char *path, *p;
+    int s;
+
+    root_bus_path = pci_root_bus_path(d);
+    root_bus_len = strlen(root_bus_path);
+
+    /* Calculate # of slots on path between device and root. */;
+    slot_depth = 0;
+    for (t = d; t; t = t->bus->parent_dev) {
+        ++slot_depth;
+    }
+
+    path_len = root_bus_len + slot_len * slot_depth;
+
+    /* Allocate memory, fill in the terminating null byte. */
+    path = g_malloc(path_len + 1 /* For '\0' */);
+    path[path_len] = '\0';
+
+    memcpy(path, root_bus_path, root_bus_len);
+
+    /* Fill in slot numbers. We walk up from device to root, so need to print
+     * them in the reverse order, last to first. */
+    p = path + path_len;
+    for (t = d; t; t = t->bus->parent_dev) {
+        p -= slot_len;
+        s = snprintf(slot, sizeof slot, ":%02x.%x",
+                     PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
+        assert(s == slot_len);
+        memcpy(p, slot, slot_len);
+    }
+
+    return path;
+}
+
+static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
+{
+    PCIDevice *d = (PCIDevice *)dev;
+    const char *name = NULL;
+    const pci_class_desc *desc =  pci_class_descriptions;
+    int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+
+    while (desc->desc &&
+          (class & ~desc->fw_ign_bits) !=
+          (desc->class & ~desc->fw_ign_bits)) {
+        desc++;
+    }
+
+    if (desc->desc) {
+        name = desc->fw_name;
+    }
+
+    if (name) {
+        pstrcpy(buf, len, name);
+    } else {
+        snprintf(buf, len, "pci%04x,%04x",
+                 pci_get_word(d->config + PCI_VENDOR_ID),
+                 pci_get_word(d->config + PCI_DEVICE_ID));
+    }
+
+    return buf;
+}
+
+static char *pcibus_get_fw_dev_path(DeviceState *dev)
+{
+    PCIDevice *d = (PCIDevice *)dev;
+    char path[50], name[33];
+    int off;
+
+    off = snprintf(path, sizeof(path), "%s@%x",
+                   pci_dev_fw_name(dev, name, sizeof name),
+                   PCI_SLOT(d->devfn));
+    if (PCI_FUNC(d->devfn)) {
+        snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
+    }
+    return g_strdup(path);
+}
+
+static const VMStateDescription vmstate_pcibus = {
+    .name = "PCIBUS",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT32_EQUAL(nirq, PCIBus),
+        VMSTATE_VARRAY_INT32(irq_count, PCIBus,
+                             nirq, 0, vmstate_info_int32,
+                             int32_t),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void pci_bus_realize(BusState *qbus, Error **errp)
+{
+    PCIBus *bus = PCI_BUS(qbus);
+
+    vmstate_register(NULL, -1, &vmstate_pcibus, bus);
+}
+
+static void pci_bus_unrealize(BusState *qbus, Error **errp)
+{
+    PCIBus *bus = PCI_BUS(qbus);
+
+    vmstate_unregister(NULL, &vmstate_pcibus, bus);
+}
+
+/*
+ * Trigger pci bus reset under a given bus.
+ * Called via qbus_reset_all on RST# assert, after the devices
+ * have been reset qdev_reset_all-ed already.
+ */
+static void pcibus_reset(BusState *qbus)
+{
+    PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
+        if (bus->devices[i]) {
+            pci_do_device_reset(bus->devices[i]);
+        }
+    }
+
+    for (i = 0; i < bus->nirq; i++) {
+        assert(bus->irq_count[i] == 0);
+    }
+}
+
+static void pci_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->print_dev = pcibus_dev_print;
+    k->get_dev_path = pcibus_get_dev_path;
+    k->get_fw_dev_path = pcibus_get_fw_dev_path;
+    k->realize = pci_bus_realize;
+    k->unrealize = pci_bus_unrealize;
+    k->reset = pcibus_reset;
+}
+
+static const TypeInfo pci_bus_info = {
+    .name = TYPE_PCI_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(PCIBus),
+    .class_init = pci_bus_class_init,
+};
+
+static void pci_bus_register_types(void)
+{
+    type_register_static(&pci_bus_info);
+}
+
+type_init(pci_bus_register_types)
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 0bb3cdb..f5847bc 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -23,6 +23,7 @@
 #include "hw/ppc/ppc.h"
 #include "hw/ppc/ppc4xx.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "exec/address-spaces.h"
 
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index d1d0847..8dd2ce3 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -30,6 +30,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/boards.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "net/net.h"
 #include "sh7750_regs.h"
 #include "hw/ide.h"
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index a2f6d9e..f02e998 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -24,6 +24,7 @@
 #include "hw/sysbus.h"
 #include "hw/sh4/sh.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_host.h"
 #include "qemu/bswap.h"
 #include "exec/address-spaces.h"
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index be2d9b8..47077cd 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -337,8 +337,6 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
 typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
 
-#define TYPE_PCI_BUS "PCI"
-#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
 #define TYPE_PCIE_BUS "PCIE"
 
 bool pci_bus_is_express(PCIBus *bus);
@@ -370,6 +368,7 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
 void pci_device_set_intx_routing_notifier(PCIDevice *dev,
                                           PCIINTxRoutingNotifier notifier);
 void pci_device_reset(PCIDevice *dev);
+void pci_do_device_reset(PCIDevice *dev);
 
 PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
                                const char *default_model,
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index fabaeee..ea427a3 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -1,6 +1,8 @@
 #ifndef QEMU_PCI_BUS_H
 #define QEMU_PCI_BUS_H
 
+#include "hw/pci/pci.h"
+
 /*
  * PCI Bus and Bridge datastructures.
  *
@@ -8,6 +10,12 @@
  * use accessor functions in pci.h, pci_bridge.h
  */
 
+PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
+PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
+
+#define TYPE_PCI_BUS "PCI"
+#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
+
 struct PCIBus {
     BusState qbus;
     PCIIOMMUFunc iommu_fn;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (8 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-04-27 11:37   ` Michael S. Tsirkin
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 11/26] hw/pci: made pci_bus_num " Marcel Apfelbaum
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

From: Marcel Apfelbaum <marcel.a@redhat.com>

Refactoring it as a method of PCIBusClass will allow
different implementations for subclasses.

Removed the assumption that the root bus does not
have a parent device because is specific only
to the default class implementation.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci/pci.c             | 11 ++++-------
 hw/pci/pci_bus.c         |  9 +++++++++
 hw/vfio/pci.c            |  1 +
 include/hw/pci/pci.h     |  1 -
 include/hw/pci/pci_bus.h | 15 +++++++++++++++
 5 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index cb63a21..376b42d 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -205,7 +205,10 @@ PCIBus *pci_device_root_bus(const PCIDevice *d)
 {
     PCIBus *bus = d->bus;
 
-    while ((d = bus->parent_dev) != NULL) {
+    while (!pci_bus_is_root(bus)) {
+        d = bus->parent_dev;
+        assert(d != NULL);
+
         bus = d->bus;
     }
 
@@ -218,7 +221,6 @@ const char *pci_root_bus_path(PCIDevice *dev)
     PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent);
     PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
 
-    assert(!rootbus->parent_dev);
     assert(host_bridge->bus == rootbus);
 
     if (hc->root_bus_path) {
@@ -250,11 +252,6 @@ bool pci_bus_is_express(PCIBus *bus)
     return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
 }
 
-bool pci_bus_is_root(PCIBus *bus)
-{
-    return !bus->parent_dev;
-}
-
 void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
index d156194..0922a75 100644
--- a/hw/pci/pci_bus.c
+++ b/hw/pci/pci_bus.c
@@ -464,9 +464,15 @@ static void pcibus_reset(BusState *qbus)
     }
 }
 
+static bool pcibus_is_root(PCIBus *bus)
+{
+    return !bus->parent_dev;
+}
+
 static void pci_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *k = BUS_CLASS(klass);
+    PCIBusClass *pbc = PCI_BUS_CLASS(klass);
 
     k->print_dev = pcibus_dev_print;
     k->get_dev_path = pcibus_get_dev_path;
@@ -474,11 +480,14 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
     k->realize = pci_bus_realize;
     k->unrealize = pci_bus_unrealize;
     k->reset = pcibus_reset;
+
+    pbc->is_root = pcibus_is_root;
 }
 
 static const TypeInfo pci_bus_info = {
     .name = TYPE_PCI_BUS,
     .parent = TYPE_BUS,
+    .class_size = sizeof(PCIBusClass),
     .instance_size = sizeof(PCIBus),
     .class_init = pci_bus_class_init,
 };
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 6b80539..7b08d03 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -32,6 +32,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "qemu-common.h"
 #include "qemu/error-report.h"
 #include "qemu/event_notifier.h"
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 47077cd..ae2c4a5 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -340,7 +340,6 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
 #define TYPE_PCIE_BUS "PCIE"
 
 bool pci_bus_is_express(PCIBus *bus);
-bool pci_bus_is_root(PCIBus *bus);
 void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index ea427a3..306ef10 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -15,6 +15,16 @@ PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
 
 #define TYPE_PCI_BUS "PCI"
 #define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
+#define PCI_BUS_CLASS(klass) OBJECT_CLASS_CHECK(PCIBusClass, (klass), TYPE_PCI_BUS)
+#define PCI_BUS_GET_CLASS(obj) OBJECT_GET_CLASS(PCIBusClass, (obj), TYPE_PCI_BUS)
+
+typedef struct PCIBusClass {
+    /*< private >*/
+    BusClass parent_class;
+    /*< public >*/
+
+    bool (*is_root)(PCIBus *bus);
+} PCIBusClass;
 
 struct PCIBus {
     BusState qbus;
@@ -39,6 +49,11 @@ struct PCIBus {
     int *irq_count;
 };
 
+static inline bool pci_bus_is_root(PCIBus *bus)
+{
+    return PCI_BUS_GET_CLASS(bus)->is_root(bus);
+}
+
 typedef struct PCIBridgeWindows PCIBridgeWindows;
 
 /*
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 11/26] hw/pci: made pci_bus_num a PCIBusClass method
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (9 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface Marcel Apfelbaum
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

From: Marcel Apfelbaum <marcel.a@redhat.com>

Refactoring it as a method of PCIBusClass will allow
different implementations for subclasses.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/kvm/pci-assign.c |  1 +
 hw/pci/pci.c             |  7 -------
 hw/pci/pci_bus.c         | 10 ++++++++++
 hw/scsi/megasas.c        |  1 +
 hw/xen/xen_pt.c          |  1 +
 include/hw/pci/pci.h     |  1 -
 include/hw/pci/pci_bus.h |  6 ++++++
 7 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 9db7c77..ad573ec 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -35,6 +35,7 @@
 #include "qemu/range.h"
 #include "sysemu/sysemu.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci/msi.h"
 #include "kvm_i386.h"
 
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 376b42d..3570431 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -301,13 +301,6 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
     return bus;
 }
 
-int pci_bus_num(PCIBus *s)
-{
-    if (pci_bus_is_root(s))
-        return 0;       /* pci host bridge */
-    return s->parent_dev->config[PCI_SECONDARY_BUS];
-}
-
 static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
 {
     PCIDevice *s = container_of(pv, PCIDevice, config);
diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
index 0922a75..ed99208 100644
--- a/hw/pci/pci_bus.c
+++ b/hw/pci/pci_bus.c
@@ -469,6 +469,15 @@ static bool pcibus_is_root(PCIBus *bus)
     return !bus->parent_dev;
 }
 
+static int pcibus_num(PCIBus *bus)
+{
+    if (pcibus_is_root(bus)) {
+        return 0;       /* pci host bridge */
+    }
+
+    return bus->parent_dev->config[PCI_SECONDARY_BUS];
+}
+
 static void pci_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *k = BUS_CLASS(klass);
@@ -482,6 +491,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
     k->reset = pcibus_reset;
 
     pbc->is_root = pcibus_is_root;
+    pbc->bus_num = pcibus_num;
 }
 
 static const TypeInfo pci_bus_info = {
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 4852237..fa4e3d0 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -20,6 +20,7 @@
 
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "sysemu/dma.h"
 #include "sysemu/block-backend.h"
 #include "hw/pci/msi.h"
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index f2893b2..cf56a48 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -55,6 +55,7 @@
 #include <sys/ioctl.h>
 
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/xen/xen.h"
 #include "hw/xen/xen_backend.h"
 #include "xen_pt.h"
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index ae2c4a5..a69cf94 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -375,7 +375,6 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
 
 PCIDevice *pci_vga_init(PCIBus *bus);
 
-int pci_bus_num(PCIBus *s);
 void pci_for_each_device(PCIBus *bus, int bus_num,
                          void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque),
                          void *opaque);
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 306ef10..553814e 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -24,6 +24,7 @@ typedef struct PCIBusClass {
     /*< public >*/
 
     bool (*is_root)(PCIBus *bus);
+    int (*bus_num)(PCIBus *bus);
 } PCIBusClass;
 
 struct PCIBus {
@@ -54,6 +55,11 @@ static inline bool pci_bus_is_root(PCIBus *bus)
     return PCI_BUS_GET_CLASS(bus)->is_root(bus);
 }
 
+static inline int pci_bus_num(PCIBus *bus)
+{
+    return PCI_BUS_GET_CLASS(bus)->bus_num(bus);
+}
+
 typedef struct PCIBridgeWindows PCIBridgeWindows;
 
 /*
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (10 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 11/26] hw/pci: made pci_bus_num " Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-04-27 11:24   ` Michael S. Tsirkin
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface Marcel Apfelbaum
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

From: Marcel Apfelbaum <marcel.a@redhat.com>

This is a marker interface used to differentiate the
"default" host bridge on a system with multiple host bridges.
This differentiation is required only for pc machines for now
by the ACPI subsystem.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c      | 9 ++++++---
 hw/pci-host/piix.c        | 5 +++++
 hw/pci-host/q35.c         | 4 ++++
 hw/pci/pci_host.c         | 6 ++++++
 include/hw/pci/pci_host.h | 7 +++++++
 5 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d0a5c85..86e474a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
     Object *pci_host;
     bool ambiguous;
 
-    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
+    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
+                                        &ambiguous);
     g_assert(!ambiguous);
     g_assert(pci_host);
 
@@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
             PCIBus *bus = NULL;
             bool ambiguous;
 
-            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
+            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
+                                                &ambiguous);
             if (!ambiguous && pci_host) {
                 bus = PCI_HOST_BRIDGE(pci_host)->bus;
             }
@@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
     QObject *o;
     bool ambiguous;
 
-    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
+    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
+                                        &ambiguous);
     g_assert(!ambiguous);
     g_assert(pci_host);
 
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 292b6e9..0033ab4 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
     .instance_size = sizeof(I440FXState),
     .instance_init = i440fx_pcihost_initfn,
     .class_init    = i440fx_pcihost_class_init,
+    .interfaces    = (InterfaceInfo[]) {
+        { TYPE_PCI_MAIN_HOST_BRIDGE },
+        { }
+    }
+
 };
 
 static void i440fx_register_types(void)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 5dd559e..e35b3a2 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
     .instance_size = sizeof(Q35PCIHost),
     .instance_init = q35_host_initfn,
     .class_init = q35_host_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_PCI_MAIN_HOST_BRIDGE },
+        { }
+    }
 };
 
 /****************************************************************************
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 3e26f92..87180c8 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
     .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static const TypeInfo pci_main_host_interface_info = {
+    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
+    .parent        = TYPE_INTERFACE,
+};
+
 static const TypeInfo pci_host_type_info = {
     .name = TYPE_PCI_HOST_BRIDGE,
     .parent = TYPE_SYS_BUS_DEVICE,
@@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
 
 static void pci_host_register_types(void)
 {
+    type_register_static(&pci_main_host_interface_info);
     type_register_static(&pci_host_type_info);
 }
 
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index ba31595..3c72e26 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -30,6 +30,13 @@
 
 #include "hw/sysbus.h"
 
+/**
+ * Marker interface for classes whose instances can
+ * be main host bridges. It is intended to be used
+ * when the QOM tree includes multiple host bridges.
+ */
+#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
+
 #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
 #define PCI_HOST_BRIDGE(obj) \
     OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (11 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-04-27 12:14   ` Michael S. Tsirkin
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement " Marcel Apfelbaum
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
whose configuration registers are snooped by other host bridges
to complete their configuration cycles.

The interface exposes a list of snooping host bridges that
shall be used by the hosts implementing this interface
in order to emulate a snooping mechanism.

The way that the snooping hosts are registered or how
the snooping is implemented are out of the interface scope,
it only provides a way to determine if a host bridge has
snooping hosts and list them.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci/pci_host.c         |  8 ++++++++
 include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 87180c8..288e74c 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
     .parent        = TYPE_INTERFACE,
 };
 
+static const TypeInfo pci_host_bridge_snooped_interface_info = {
+    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
+    .parent = TYPE_INTERFACE,
+    .class_size = sizeof(PCIHostBridgeSnoopedClass),
+};
+
 static const TypeInfo pci_host_type_info = {
     .name = TYPE_PCI_HOST_BRIDGE,
     .parent = TYPE_SYS_BUS_DEVICE,
@@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
 static void pci_host_register_types(void)
 {
     type_register_static(&pci_main_host_interface_info);
+    type_register_static(&pci_host_bridge_snooped_interface_info);
     type_register_static(&pci_host_type_info);
+
 }
 
 type_init(pci_host_register_types)
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index 3c72e26..a041919 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
     const char *(*root_bus_path)(PCIHostState *, PCIBus *);
 } PCIHostBridgeClass;
 
+/**
+ * A special case of host bridge whose configuration registers
+ * are snooped by other host bridges to complete their
+ * configuration cycles.
+ */
+#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
+#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
+                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
+#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
+                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
+#define PCI_HOST_BRIDGE_SNOOPED(obj) \
+     INTERFACE_CHECK(PCIHostState, (obj), \
+                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
+
+typedef struct PCIHostBridgeSnoopedClass {
+    /* <private> */
+    InterfaceClass parent_class;
+
+    /* <public> */
+    GPtrArray *(*snooping_hosts)(PCIHostState *);
+} PCIHostBridgeSnoopedClass;
+
 /* common internal helpers for PCI/PCIe hosts, cut off overflows */
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
                                   uint32_t limit, uint32_t val, uint32_t len);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (12 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-04-27 12:23   ` Michael S. Tsirkin
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 15/26] hw/acpi: add support for i440fx 'snooping' root busses Marcel Apfelbaum
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

The PIIX holds a list of snooping host bridges that is populated
by a registration function that shall be used by any host bridge
that needs to use PIIX configuration space to complete their
configuration cycles.

PIIX monitors acceses to configuration registers and passes them
to the corresponding host bridge if the input bus number is
in its bus range.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci-host/piix.c        | 118 +++++++++++++++++++++++++++++++++++++++++++++-
 hw/pci/pci_host.c         |  28 +++++++++++
 include/hw/i386/pc.h      |   6 +++
 include/hw/pci/pci_host.h |   3 ++
 4 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 0033ab4..f512765 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -50,6 +50,12 @@ typedef struct I440FXState {
     PcPciInfo pci_info;
     uint64_t pci_hole64_size;
     uint32_t short_root_bus;
+
+    /*
+     * List of PCI host bridges listening to
+     * the same configuration registers.
+     */
+    GPtrArray *snooping_hosts;
 } I440FXState;
 
 #define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
@@ -255,14 +261,80 @@ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
     visit_type_uint64(v, &w64.end, name, errp);
 }
 
+static PCIBus *i440fx_find_target_bus(I440FXState *i440fx, uint8_t bus_num)
+{
+    PCIHostState *host = PCI_HOST_BRIDGE(i440fx);
+    PCIBus *target_bus = NULL;
+
+    if (bus_num == pci_bus_num(host->bus)) {
+        target_bus = host->bus;
+    } else {
+        int i;
+
+        for (i = 0; i < i440fx->snooping_hosts->len; i++) {
+            PCIHostState *s_host = g_ptr_array_index(i440fx->snooping_hosts, i);
+            Range r = pci_host_get_buses_range(s_host);
+
+            if (r.begin <= bus_num && r.end >= bus_num) {
+                target_bus = s_host->bus;
+            }
+
+        }
+    }
+
+    return target_bus;
+}
+
+static void i440fx_pcihost_data_write(void *opaque, hwaddr addr,
+                                      uint64_t val, unsigned len)
+{
+    uint32_t config_reg = PCI_HOST_BRIDGE(opaque)->config_reg;
+
+    if (config_reg & (1u << 31)) {
+        uint8_t bus_num = (config_reg >> 16) & 0xFF;
+        I440FXState *i440fx = I440FX_PCI_HOST_BRIDGE(opaque);
+        PCIBus *target_bus = i440fx_find_target_bus(i440fx, bus_num);
+
+        if (target_bus) {
+            pci_data_write(target_bus, config_reg | (addr & 3), val, len);
+        }
+    }
+}
+
+static uint64_t i440fx_pcihost_data_read(void *opaque,
+                                         hwaddr addr, unsigned len)
+{
+    uint32_t config_reg = PCI_HOST_BRIDGE(opaque)->config_reg;
+
+    if (config_reg & (1U << 31)) {
+        int bus_num = (config_reg >> 16) & 0xFF;
+        I440FXState *i440fx = I440FX_PCI_HOST_BRIDGE(opaque);
+        PCIBus *target_bus = i440fx_find_target_bus(i440fx, bus_num);
+
+        if (target_bus) {
+            return pci_data_read(target_bus, config_reg | (addr & 3), len);
+        }
+    }
+
+    return 0xffffffff;
+}
+
+const MemoryRegionOps i440fx_pcihost_data_le_ops = {
+    .read = i440fx_pcihost_data_read,
+    .write = i440fx_pcihost_data_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static void i440fx_pcihost_initfn(Object *obj)
 {
     PCIHostState *s = PCI_HOST_BRIDGE(obj);
     I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
 
+    d->snooping_hosts = g_ptr_array_new();
+
     memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
                           "pci-conf-idx", 4);
-    memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
+    memory_region_init_io(&s->data_mem, obj, &i440fx_pcihost_data_le_ops, s,
                           "pci-conf-data", 4);
 
     object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
@@ -400,6 +472,40 @@ PCIBus *find_i440fx(void)
     return s ? s->bus : NULL;
 }
 
+/*
+ * Returns 0 on successs, -1 if i440fx host was not
+ * found or the bus number is already in use.
+ */
+int i440fx_register_snooping_host(PCIHostState *host)
+{
+    I440FXState *s = OBJECT_CHECK(I440FXState,
+                                  object_resolve_path("/machine/i440fx", NULL),
+                                  TYPE_I440FX_PCI_HOST_BRIDGE);
+    uint8_t bus_num = pci_bus_num(host->bus);
+    int i;
+
+    /* i440fx host not found */
+    if (!s) {
+        return -1;
+    }
+
+    /* 0 is reserved for i440fx host bridge */
+    if (bus_num == 0) {
+        return -1;
+    }
+
+    /* check if the bus number is unique */
+    for (i = 0; i < s->snooping_hosts->len; i++) {
+        PCIHostState *s_host = g_ptr_array_index(s->snooping_hosts, i);
+        if (bus_num == pci_bus_num(s_host->bus)) {
+            return -1;
+        }
+    }
+
+    g_ptr_array_add(s->snooping_hosts, host);
+    return 0;
+}
+
 /* PIIX3 PCI to ISA bridge */
 static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
 {
@@ -742,6 +848,13 @@ static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
     return "0000:00";
 }
 
+static GPtrArray *i440fx_snooping_hosts(PCIHostState *host_bridge)
+{
+    I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
+
+    return s->snooping_hosts;
+}
+
 static Property i440fx_props[] = {
     DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
                      pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
@@ -753,11 +866,13 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
+    PCIHostBridgeSnoopedClass *sc = TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass);
 
     hc->root_bus_path = i440fx_pcihost_root_bus_path;
     dc->realize = i440fx_pcihost_realize;
     dc->fw_name = "pci";
     dc->props = i440fx_props;
+    sc->snooping_hosts = i440fx_snooping_hosts;
 }
 
 static const TypeInfo i440fx_pcihost_info = {
@@ -768,6 +883,7 @@ static const TypeInfo i440fx_pcihost_info = {
     .class_init    = i440fx_pcihost_class_init,
     .interfaces    = (InterfaceInfo[]) {
         { TYPE_PCI_MAIN_HOST_BRIDGE },
+        { TYPE_PCI_HOST_BRIDGE_SNOOPED },
         { }
     }
 
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 288e74c..35e462b 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -20,6 +20,8 @@
 
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
+#include "hw/pci/pci_bus.h"
+#include "qemu/range.h"
 #include "trace.h"
 
 /* debug PCI */
@@ -32,6 +34,32 @@ do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0)
 #define PCI_DPRINTF(fmt, ...)
 #endif
 
+Range pci_host_get_buses_range(PCIHostState *host)
+{
+    uint8_t root_bus_num = pci_bus_num(host->bus);
+    Range r = {root_bus_num, root_bus_num};
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(host->bus->devices); ++i) {
+        PCIDevice *dev = host->bus->devices[i];
+        PCIDeviceClass *pc;
+
+        if (!dev) {
+            continue;
+        }
+
+        pc = PCI_DEVICE_GET_CLASS(dev);
+
+        if (pc->is_bridge) {
+            uint8_t subordinate = dev->config[PCI_SUBORDINATE_BUS];
+            if (subordinate > r.end) {
+                r.end = subordinate;
+            }
+        }
+    }
+
+    return r;
+}
 /*
  * PCI address
  * bit 16 - 24: bus number
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 1b35168..a918a61 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -241,6 +241,12 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
                     MemoryRegion *ram_memory);
 
 PCIBus *find_i440fx(void);
+/*
+ * Register hosts without their own configuration registers
+ * to i440fx main PCI host bridge
+ */
+int i440fx_register_snooping_host(PCIHostState *host);
+
 /* piix4.c */
 extern PCIDevice *piix4_dev;
 int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn);
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index a041919..dc7ccb2 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -87,6 +87,9 @@ typedef struct PCIHostBridgeSnoopedClass {
     GPtrArray *(*snooping_hosts)(PCIHostState *);
 } PCIHostBridgeSnoopedClass;
 
+/* Returns the buses interval owned by the input host */
+Range pci_host_get_buses_range(PCIHostState *host);
+
 /* common internal helpers for PCI/PCIe hosts, cut off overflows */
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
                                   uint32_t limit, uint32_t val, uint32_t len);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 15/26] hw/acpi: add support for i440fx 'snooping' root busses
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (13 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement " Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 16/26] hw/apci: add _PRT method for extra PCI " Marcel Apfelbaum
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

If the machine has extra root busses that are snooping to
the i440fx host bridge, we need to add them to
acpi in order to be properly detected by guests.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c | 30 ++++++++++++++++++++++++++++--
 hw/pci-host/piix.c   |  4 ++--
 include/hw/i386/pc.h |  2 +-
 3 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 86e474a..ecd5684 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -60,6 +60,8 @@
 #include "qom/qom-qobject.h"
 #include "exec/ram_addr.h"
 
+#include "qmp-commands.h"
+
 /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
  * -M pc-i440fx-2.0.  Even if the actual amount of AML generated grows
  * a little bit, there should be plenty of free space since the DSDT
@@ -491,10 +493,11 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
 
 static void acpi_set_pci_info(void)
 {
-    PCIBus *bus = find_i440fx(); /* TODO: Q35 support */
+    PCIHostState *host = find_i440fx();
     unsigned bsel_alloc = 0;
 
-    if (bus) {
+    if (host) {
+        PCIBus *bus = host->bus; /* TODO: Q35 support */
         /* Scan all PCI buses. Set property to enable acpi based hotplug. */
         pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
     }
@@ -660,6 +663,7 @@ build_ssdt(GArray *table_data, GArray *linker,
     uint32_t nr_mem = machine->ram_slots;
     unsigned acpi_cpus = guest_info->apic_id_limit;
     Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx;
+    PCIHostState *snooped_host;
     int i;
 
     ssdt = init_aml_allocator();
@@ -671,6 +675,28 @@ build_ssdt(GArray *table_data, GArray *linker,
     /* Reserve space for header */
     acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));
 
+    /* Snooping mechanism is implemented only for i440fx */
+    snooped_host = find_i440fx();
+    if (snooped_host) {
+        PCIHostBridgeSnoopedClass *snooped_class =
+            PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(snooped_host);
+        GPtrArray *snooping_hosts = snooped_class->snooping_hosts(snooped_host);
+
+        for (i = 0; i < snooping_hosts->len; i++) {
+            PCIHostState *host = g_ptr_array_index(snooping_hosts, i);
+            uint8_t bus_num = pci_bus_num(host->bus);
+
+            scope = aml_scope("\\_SB");
+            dev = aml_device("PC%.02X", bus_num);
+            aml_append(dev,
+                       aml_name_decl("_UID", aml_string("PC%.02X", bus_num)));
+            aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A03")));
+            aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
+            aml_append(scope, dev);
+            aml_append(ssdt, scope);
+        }
+    }
+
     scope = aml_scope("\\_SB.PCI0");
     /* build PCI0._CRS */
     crs = aml_resource_template();
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index f512765..50418ca 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -464,12 +464,12 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     return b;
 }
 
-PCIBus *find_i440fx(void)
+PCIHostState *find_i440fx(void)
 {
     PCIHostState *s = OBJECT_CHECK(PCIHostState,
                                    object_resolve_path("/machine/i440fx", NULL),
                                    TYPE_PCI_HOST_BRIDGE);
-    return s ? s->bus : NULL;
+    return s;
 }
 
 /*
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index a918a61..7c89fae 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -240,7 +240,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
                     MemoryRegion *pci_memory,
                     MemoryRegion *ram_memory);
 
-PCIBus *find_i440fx(void);
+PCIHostState *find_i440fx(void);
 /*
  * Register hosts without their own configuration registers
  * to i440fx main PCI host bridge
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 16/26] hw/apci: add _PRT method for extra PCI root busses
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (14 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 15/26] hw/acpi: add support for i440fx 'snooping' root busses Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 17/26] hw/acpi: add _CRS method for extra " Marcel Apfelbaum
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ecd5684..4964d6b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -654,6 +654,86 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
     aml_append(parent_scope, method);
 }
 
+/*
+ * initialize_route - Initialize the interrupt routing rule
+ * through a specific LINK:
+ *  if (lnk_idx == idx)
+ *      route using link 'link_name'
+ */
+static Aml *initialize_route(Aml *route, const char *link_name,
+                             Aml *lnk_idx, int idx)
+{
+    Aml *if_ctx = aml_if(aml_equal(lnk_idx, aml_int(idx)));
+    Aml *pkg = aml_package(4);
+
+    aml_append(pkg, aml_int(0));
+    aml_append(pkg, aml_int(0));
+    aml_append(pkg, aml_name("%s", link_name));
+    aml_append(pkg, aml_int(0));
+    aml_append(if_ctx, aml_store(pkg, route));
+
+    return if_ctx;
+}
+
+/*
+ * build_prt - Define interrupt rounting rules
+ *
+ * Returns an array of 128 routes, one for each device,
+ * based on device location.
+ * The main goal is to equaly distribute the interrupts
+ * over the 4 existing ACPI links (works only for i440fx).
+ * The hash function is  (slot + pin) & 3 -> "LNK[D|A|B|C]".
+ *
+ */
+static Aml *build_prt(void)
+{
+    Aml *method, *while_ctx, *pin, *res;
+
+    method = aml_method("_PRT", 0);
+    res = aml_local(0);
+    pin = aml_local(1);
+    aml_append(method, aml_store(aml_package(128), res));
+    aml_append(method, aml_store(aml_int(0), pin));
+
+    /* while (pin < 128) */
+    while_ctx = aml_while(aml_lless(pin, aml_int(128)));
+    {
+        Aml *slot = aml_local(2);
+        Aml *lnk_idx = aml_local(3);
+        Aml *route = aml_local(4);
+
+        /* slot = pin >> 2 */
+        aml_append(while_ctx,
+                   aml_store(aml_shiftright(pin, aml_int(2)), slot));
+        /* lnk_idx = (slot + pin) & 3 */
+        aml_append(while_ctx,
+                   aml_store(aml_and(aml_add(pin, slot), aml_int(3)), lnk_idx));
+
+        /* route[2] = "LNK[D|A|B|C]", selection based on pin % 3  */
+        aml_append(while_ctx, initialize_route(route, "LNKD", lnk_idx, 0));
+        aml_append(while_ctx, initialize_route(route, "LNKA", lnk_idx, 1));
+        aml_append(while_ctx, initialize_route(route, "LNKB", lnk_idx, 2));
+        aml_append(while_ctx, initialize_route(route, "LNKC", lnk_idx, 3));
+
+        /* route[0] = 0x[slot]FFFF */
+        aml_append(while_ctx,
+            aml_store(aml_or(aml_shiftleft(slot, aml_int(16)), aml_int(0xFFFF)),
+                      aml_index(route, aml_int(0))));
+        /* route[1] = pin & 3 */
+        aml_append(while_ctx,
+            aml_store(aml_and(pin, aml_int(3)), aml_index(route, aml_int(1))));
+        /* res[pin] = route */
+        aml_append(while_ctx, aml_store(route, aml_index(res, pin)));
+        /* pin++ */
+        aml_append(while_ctx, aml_increment(pin));
+    }
+    aml_append(method, while_ctx);
+    /* return res*/
+    aml_append(method, aml_return(res));
+
+    return method;
+}
+
 static void
 build_ssdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
@@ -692,6 +772,7 @@ build_ssdt(GArray *table_data, GArray *linker,
                        aml_name_decl("_UID", aml_string("PC%.02X", bus_num)));
             aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A03")));
             aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
+            aml_append(dev, build_prt());
             aml_append(scope, dev);
             aml_append(ssdt, scope);
         }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 17/26] hw/acpi: add _CRS method for extra root busses
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (15 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 16/26] hw/apci: add _PRT method for extra PCI " Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 18/26] hw/acpi: remove from root bus 0 the crs resources used by other busses Marcel Apfelbaum
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Save the IO/mem/bus numbers ranges assigned to the extra root busses
to be removed from the root bus 0 range.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4964d6b..fe9bb5c 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -734,6 +734,137 @@ static Aml *build_prt(void)
     return method;
 }
 
+typedef struct CrsRangeEntry {
+    uint64_t base;
+    uint64_t limit;
+} CrsRangeEntry;
+
+static void crs_range_insert(GPtrArray *ranges, uint64_t base, uint64_t limit)
+{
+    CrsRangeEntry *entry;
+
+    entry = g_malloc(sizeof(*entry));
+    entry->base = base;
+    entry->limit = limit;
+
+    g_ptr_array_add(ranges, entry);
+}
+
+static void crs_range_free(gpointer data)
+{
+    CrsRangeEntry *entry = (CrsRangeEntry *)data;
+    g_free(entry);
+}
+
+static Aml *build_crs(PCIHostState *host,
+                      GPtrArray *io_ranges, GPtrArray *mem_ranges)
+{
+    Aml *crs = aml_resource_template();
+    uint8_t max_bus = pci_bus_num(host->bus);
+    uint8_t type;
+    int devfn;
+
+    for (devfn = 0; devfn < ARRAY_SIZE(host->bus->devices); devfn++) {
+        int i;
+        uint64_t range_base, range_limit;
+        PCIDevice *dev = host->bus->devices[devfn];
+
+        if (!dev) {
+            continue;
+        }
+
+        for (i = 0; i < PCI_NUM_REGIONS; i++) {
+            PCIIORegion *r = &dev->io_regions[i];
+
+            range_base = r->addr;
+            range_limit = r->addr + r->size - 1;
+
+            if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+                aml_append(crs,
+                    aml_word_io(aml_min_fixed, aml_max_fixed,
+                                aml_pos_decode, aml_entire_range,
+                                0,
+                                range_base,
+                                range_limit,
+                                0,
+                                range_limit - range_base + 1));
+                crs_range_insert(io_ranges, range_base, range_limit);
+            } else { /* "memory" */
+                aml_append(crs,
+                    aml_dword_memory(aml_pos_decode, aml_min_fixed,
+                                     aml_max_fixed, aml_non_cacheable,
+                                     aml_ReadWrite,
+                                     0,
+                                     range_base,
+                                     range_limit,
+                                     0,
+                                     range_limit - range_base + 1));
+                crs_range_insert(mem_ranges, range_base, range_limit);
+            }
+        }
+
+        type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
+        if (type == PCI_HEADER_TYPE_BRIDGE) {
+            uint8_t subordinate = dev->config[PCI_SUBORDINATE_BUS];
+            if (subordinate > max_bus) {
+                max_bus = subordinate;
+            }
+
+            range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
+            range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
+            aml_append(crs,
+                aml_word_io(aml_min_fixed, aml_max_fixed,
+                            aml_pos_decode, aml_entire_range,
+                            0,
+                            range_base,
+                            range_limit,
+                            0,
+                            range_limit - range_base + 1));
+            crs_range_insert(io_ranges, range_base, range_limit);
+
+            range_base =
+                pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
+            range_limit =
+                pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
+            aml_append(crs,
+                aml_dword_memory(aml_pos_decode, aml_min_fixed,
+                                 aml_max_fixed, aml_non_cacheable,
+                                 aml_ReadWrite,
+                                 0,
+                                 range_base,
+                                 range_limit,
+                                 0,
+                                 range_limit - range_base + 1));
+            crs_range_insert(mem_ranges, range_base, range_limit);
+
+            range_base =
+                pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+            range_limit =
+                pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
+            aml_append(crs,
+                aml_dword_memory(aml_pos_decode, aml_min_fixed,
+                                 aml_max_fixed, aml_non_cacheable,
+                                 aml_ReadWrite,
+                                 0,
+                                 range_base,
+                                 range_limit,
+                                 0,
+                                 range_limit - range_base + 1));
+            crs_range_insert(mem_ranges, range_base, range_limit);
+        }
+    }
+
+    aml_append(crs,
+        aml_word_bus_number(aml_min_fixed, aml_max_fixed, aml_pos_decode,
+                            0,
+                            pci_bus_num(host->bus),
+                            max_bus,
+                            0,
+                            max_bus - pci_bus_num(host->bus) + 1));
+
+    return crs;
+}
+
 static void
 build_ssdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
@@ -744,6 +875,8 @@ build_ssdt(GArray *table_data, GArray *linker,
     unsigned acpi_cpus = guest_info->apic_id_limit;
     Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx;
     PCIHostState *snooped_host;
+    GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
+    GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     int i;
 
     ssdt = init_aml_allocator();
@@ -773,9 +906,14 @@ build_ssdt(GArray *table_data, GArray *linker,
             aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A03")));
             aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
             aml_append(dev, build_prt());
+            crs = build_crs(host, io_ranges, mem_ranges);
+            aml_append(dev, aml_name_decl("_CRS", crs));
             aml_append(scope, dev);
             aml_append(ssdt, scope);
         }
+
+        g_ptr_array_free(io_ranges, true);
+        g_ptr_array_free(mem_ranges, true);
     }
 
     scope = aml_scope("\\_SB.PCI0");
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 18/26] hw/acpi: remove from root bus 0 the crs resources used by other busses.
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (16 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 17/26] hw/acpi: add _CRS method for extra " Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 19/26] hw/pci: removed 'rootbus nr is 0' assumption from qmp_pci_query Marcel Apfelbaum
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

If multiple root busses are used, root bus 0 cannot use all the
pci holes ranges. Remove the IO/mem ranges used by the other
primary busses.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c | 90 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 77 insertions(+), 13 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index fe9bb5c..ab7ebeb 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -756,6 +756,50 @@ static void crs_range_free(gpointer data)
     g_free(entry);
 }
 
+static gint crs_range_compare(gconstpointer a, gconstpointer b)
+{
+     CrsRangeEntry *entry_a = *(CrsRangeEntry **)a;
+     CrsRangeEntry *entry_b = *(CrsRangeEntry **)b;
+
+     return (int64_t)entry_a->base - (int64_t)entry_b->base;
+}
+
+/*
+ * crs_replace_with_free_ranges - given the 'used' ranges within [start - end]
+ * interval, computes the 'free' ranges from the same interval.
+ * Example: If the input array is { [a1 - a2],[b1 - b2] }, the function
+ * will return { [base - a1], [a2 - b1], [b2 - limit] }.
+ */
+static void crs_replace_with_free_ranges(GPtrArray *ranges,
+                                         uint64_t start, uint64_t end)
+{
+    GPtrArray *free_ranges = g_ptr_array_new_with_free_func(crs_range_free);
+    uint64_t free_base = start;
+    int i;
+
+    g_ptr_array_sort(ranges, crs_range_compare);
+    for (i = 0; i < ranges->len; i++) {
+        CrsRangeEntry *used = g_ptr_array_index(ranges, i);
+
+        if (free_base < used->base) {
+            crs_range_insert(free_ranges, free_base, used->base - 1);
+        }
+
+        free_base = used->limit + 1;
+    }
+
+    if (free_base < end) {
+        crs_range_insert(free_ranges, free_base, end);
+    }
+
+    g_ptr_array_set_size(ranges, 0);
+    for (i = 0; i < free_ranges->len; i++) {
+        g_ptr_array_add(ranges, g_ptr_array_index(free_ranges, i));
+    }
+
+    g_ptr_array_free(free_ranges, false);
+}
+
 static Aml *build_crs(PCIHostState *host,
                       GPtrArray *io_ranges, GPtrArray *mem_ranges)
 {
@@ -877,6 +921,8 @@ build_ssdt(GArray *table_data, GArray *linker,
     PCIHostState *snooped_host;
     GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
+    CrsRangeEntry *entry;
+    int root_bus_limit = 0xFF;
     int i;
 
     ssdt = init_aml_allocator();
@@ -899,6 +945,10 @@ build_ssdt(GArray *table_data, GArray *linker,
             PCIHostState *host = g_ptr_array_index(snooping_hosts, i);
             uint8_t bus_num = pci_bus_num(host->bus);
 
+            if (bus_num < root_bus_limit) {
+                root_bus_limit = bus_num - 1;
+            }
+
             scope = aml_scope("\\_SB");
             dev = aml_device("PC%.02X", bus_num);
             aml_append(dev,
@@ -911,9 +961,6 @@ build_ssdt(GArray *table_data, GArray *linker,
             aml_append(scope, dev);
             aml_append(ssdt, scope);
         }
-
-        g_ptr_array_free(io_ranges, true);
-        g_ptr_array_free(mem_ranges, true);
     }
 
     scope = aml_scope("\\_SB.PCI0");
@@ -921,26 +968,40 @@ build_ssdt(GArray *table_data, GArray *linker,
     crs = aml_resource_template();
     aml_append(crs,
         aml_word_bus_number(aml_min_fixed, aml_max_fixed, aml_pos_decode,
-                            0x0000, 0x0000, 0x00FF, 0x0000, 0x0100));
+                            0x0000, 0x0, root_bus_limit,
+                            0x0000, root_bus_limit + 1));
     aml_append(crs, aml_io(aml_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
 
     aml_append(crs,
         aml_word_io(aml_min_fixed, aml_max_fixed,
                     aml_pos_decode, aml_entire_range,
                     0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
-    aml_append(crs,
-        aml_word_io(aml_min_fixed, aml_max_fixed,
-                    aml_pos_decode, aml_entire_range,
-                    0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300));
+
+    crs_replace_with_free_ranges(io_ranges, 0x0D00, 0xFFFF);
+    for (i = 0; i < io_ranges->len; i++) {
+        entry = g_ptr_array_index(io_ranges, i);
+        aml_append(crs,
+            aml_word_io(aml_min_fixed, aml_max_fixed,
+                        aml_pos_decode, aml_entire_range,
+                        0x0000, entry->base, entry->limit,
+                        0x0000, entry->limit - entry->base + 1));
+    }
+
     aml_append(crs,
         aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
                          aml_cacheable, aml_ReadWrite,
                          0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
-    aml_append(crs,
-        aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
-                         aml_non_cacheable, aml_ReadWrite,
-                         0, pci->w32.begin, pci->w32.end - 1, 0,
-                         pci->w32.end - pci->w32.begin));
+
+    crs_replace_with_free_ranges(mem_ranges, pci->w32.begin, pci->w32.end - 1);
+    for (i = 0; i < mem_ranges->len; i++) {
+        entry = g_ptr_array_index(mem_ranges, i);
+        aml_append(crs,
+            aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
+                             aml_non_cacheable, aml_ReadWrite,
+                             0, entry->base, entry->limit,
+                             0, entry->limit - entry->base + 1));
+    }
+
     if (pci->w64.begin) {
         aml_append(crs,
             aml_qword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
@@ -963,6 +1024,9 @@ build_ssdt(GArray *table_data, GArray *linker,
     aml_append(dev, aml_name_decl("_CRS", crs));
     aml_append(scope, dev);
 
+    g_ptr_array_free(io_ranges, true);
+    g_ptr_array_free(mem_ranges, true);
+
     /* reserve PCIHP resources */
     if (pm->pcihp_io_len) {
         dev = aml_device("PHPR");
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 19/26] hw/pci: removed 'rootbus nr is 0' assumption from qmp_pci_query
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (17 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 18/26] hw/acpi: remove from root bus 0 the crs resources used by other busses Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 20/26] hw/pci: introduce PCI Expander Bridge (PXB) Marcel Apfelbaum
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

From: Marcel Apfelbaum <marcel.a@redhat.com>

Use the newer pci_bus_num to correctly get the root bus number.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci/pci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 3570431..59369ab 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1266,7 +1266,8 @@ PciInfoList *qmp_query_pci(Error **errp)
 
     QLIST_FOREACH(host_bridge, &pci_host_bridges, next) {
         info = g_malloc0(sizeof(*info));
-        info->value = qmp_query_pci_bus(host_bridge->bus, 0);
+        info->value = qmp_query_pci_bus(host_bridge->bus,
+                                        pci_bus_num(host_bridge->bus));
 
         /* XXX: waiting for the qapi to support GSList */
         if (!cur_item) {
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 20/26] hw/pci: introduce PCI Expander Bridge (PXB)
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (18 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 19/26] hw/pci: removed 'rootbus nr is 0' assumption from qmp_pci_query Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 21/26] hw/pci: inform bios if the system has extra pci root buses Marcel Apfelbaum
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

From: Marcel Apfelbaum <marcel.a@redhat.com>

PXB is a "light-weight" host bridge whose purpose is to enable
the main host bridge to support multiple PCI root buses
for pc machines.

As oposed to PCI-2-PCI bridge's secondary bus, PXB's bus
is a primary bus and can be associated with a NUMA node
(different from the main host bridge) allowing the guest OS
to recognize the proximity of a pass-through device to
other resources as RAM and CPUs.

The PXB is composed from:
 - A primary PCI bus (can be associated with a NUMA node)
   Acts like a normal pci bus and from the functionality point
   of view is an "expansion" of the bus behind the
   main host bridge.
 - A pci-2-pci bridge behind the primary PCI bus where the actual
   devices will be attached.
 - A host-bridge PCI device
   Situated on the bus behind the main host bridge, allows
   the BIOS to configure the bus number and IO/mem resources.
   It does not have its own config/data register for configuration
   cycles, this being handled by the main host bridge.
-  A host-bridge sysbus to comply with QEMU current design.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci-bridge/Makefile.objs         |   1 +
 hw/pci-bridge/pci_expander_bridge.c | 171 ++++++++++++++++++++++++++++++++++++
 include/hw/pci/pci.h                |   1 +
 3 files changed, 173 insertions(+)
 create mode 100644 hw/pci-bridge/pci_expander_bridge.c

diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index 96c596e..f2adfe3 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -1,4 +1,5 @@
 common-obj-y += pci_bridge_dev.o
+common-obj-y += pci_expander_bridge.o
 common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
 common-obj-$(CONFIG_IOH3420) += ioh3420.o
 common-obj-$(CONFIG_I82801B11) += i82801b11.o
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
new file mode 100644
index 0000000..e789220
--- /dev/null
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -0,0 +1,171 @@
+/*
+ * PCI Expander Bridge Device Emulation
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * Authors:
+ *   Marcel Apfelbaum <marcel.a@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/i386/pc.h"
+#include "qemu/range.h"
+#include "qemu/error-report.h"
+
+#define TYPE_PXB_BUS "pxb-bus"
+#define PXB_BUS(obj) OBJECT_CHECK(PXBBus, (obj), TYPE_PXB_BUS)
+
+typedef struct PXBBus {
+    /*< private >*/
+    PCIBus parent_obj;
+    /*< public >*/
+
+    char bus_path[8];
+} PXBBus;
+
+#define TYPE_PXB_DEVICE "pxb-device"
+#define PXB_DEV(obj) OBJECT_CHECK(PXBDev, (obj), TYPE_PXB_DEVICE)
+
+typedef struct PXBDev {
+    /*< private >*/
+    PCIDevice parent_obj;
+    /*< public >*/
+
+    uint8_t bus_nr;
+} PXBDev;
+
+#define TYPE_PXB_HOST "pxb-host"
+
+static int pxb_bus_num(PCIBus *bus)
+{
+    PXBDev *pxb = PXB_DEV(bus->parent_dev);
+
+    return pxb->bus_nr;
+}
+
+static bool pxb_is_root(PCIBus *bus)
+{
+    return true; /* by definition */
+}
+
+static void pxb_bus_class_init(ObjectClass *class, void *data)
+{
+    PCIBusClass *pbc = PCI_BUS_CLASS(class);
+
+    pbc->bus_num = pxb_bus_num;
+    pbc->is_root = pxb_is_root;
+}
+
+static const TypeInfo pxb_bus_info = {
+    .name          = TYPE_PXB_BUS,
+    .parent        = TYPE_PCI_BUS,
+    .instance_size = sizeof(PXBBus),
+    .class_init    = pxb_bus_class_init,
+};
+
+static const char *pxb_host_root_bus_path(PCIHostState *host_bridge,
+                                          PCIBus *rootbus)
+{
+    PXBBus *bus = PXB_BUS(rootbus);
+
+    snprintf(bus->bus_path, 8, "0000:%02x", pxb_bus_num(rootbus));
+    return bus->bus_path;
+}
+
+static void pxb_host_class_init(ObjectClass *class, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(class);
+    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class);
+
+    dc->fw_name = "pci";
+    hc->root_bus_path = pxb_host_root_bus_path;
+}
+
+static const TypeInfo pxb_host_info = {
+    .name          = TYPE_PXB_HOST,
+    .parent        = TYPE_PCI_HOST_BRIDGE,
+    .class_init    = pxb_host_class_init,
+};
+
+static int pxb_dev_initfn(PCIDevice *dev)
+{
+    PXBDev *pxb = PXB_DEV(dev);
+    DeviceState *ds, *bds;
+    PCIBus *bus;
+    const char *dev_name = NULL;
+
+    if (dev->qdev.id && *dev->qdev.id) {
+        dev_name = dev->qdev.id;
+    }
+
+    ds = qdev_create(NULL, TYPE_PXB_HOST);
+    bus = pci_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
+
+    bus->parent_dev = dev;
+    bus->address_space_mem = dev->bus->address_space_mem;
+    bus->address_space_io = dev->bus->address_space_io;
+    bus->map_irq = pci_swizzle_map_irq_fn;
+
+    bds = qdev_create(BUS(bus), "pci-bridge");
+    bds->id = dev_name;
+    qdev_prop_set_uint8(bds, "chassis_nr", pxb->bus_nr);
+
+    PCI_HOST_BRIDGE(ds)->bus = bus;
+
+    if (i440fx_register_snooping_host(PCI_HOST_BRIDGE(ds))) {
+        error_report("Bus nr %d is already used or i440fx host not found.",
+                     pxb->bus_nr);
+        return -EINVAL;
+    }
+
+    qdev_init_nofail(ds);
+    qdev_init_nofail(bds);
+
+    pci_word_test_and_set_mask(dev->config + PCI_STATUS,
+                               PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);
+    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST);
+
+    return 0;
+}
+
+static Property pxb_dev_properties[] = {
+    /* Note: 0 is not a legal a PXB bus number. */
+    DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pxb_dev_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pxb_dev_initfn;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT;
+    k->device_id = PCI_DEVICE_ID_REDHAT_PXB;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+
+    dc->desc = "PCI Expander Bridge";
+    dc->props = pxb_dev_properties;
+}
+
+static const TypeInfo pxb_dev_info = {
+    .name          = TYPE_PXB_DEVICE,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PXBDev),
+    .class_init    = pxb_dev_class_init,
+};
+
+static void pxb_register_types(void)
+{
+    type_register_static(&pxb_bus_info);
+    type_register_static(&pxb_host_info);
+    type_register_static(&pxb_dev_info);
+}
+
+type_init(pxb_register_types)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index a69cf94..4325784 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -90,6 +90,7 @@
 #define PCI_DEVICE_ID_REDHAT_TEST        0x0005
 #define PCI_DEVICE_ID_REDHAT_SDHCI       0x0007
 #define PCI_DEVICE_ID_REDHAT_PCIE_HOST   0x0008
+#define PCI_DEVICE_ID_REDHAT_PXB         0x0009
 #define PCI_DEVICE_ID_REDHAT_QXL         0x0100
 
 #define FMT_PCIBUS                      PRIx64
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 21/26] hw/pci: inform bios if the system has extra pci root buses
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (19 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 20/26] hw/pci: introduce PCI Expander Bridge (PXB) Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 22/26] hw/pxb: add map_irq func Marcel Apfelbaum
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

From: Marcel Apfelbaum <marcel.a@redhat.com>

The bios looks for 'etc/extra-pci-roots' to decide if
is going to scan further buses after bus 0 tree.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/pc.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 79eaad5..7a8c6dd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1076,6 +1076,19 @@ void pc_guest_info_machine_done(Notifier *notifier, void *data)
     PcGuestInfoState *guest_info_state = container_of(notifier,
                                                       PcGuestInfoState,
                                                       machine_done);
+    PCIHostState *snooped_host = find_i440fx();
+    PCIHostBridgeSnoopedClass *snooped_class =
+        PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(snooped_host);
+    GPtrArray *snooping_hosts = snooped_class->snooping_hosts(snooped_host);
+    int extra_hosts = snooping_hosts->len;
+
+    if (extra_hosts && guest_info_state->info.fw_cfg) {
+        uint64_t *val = g_malloc(sizeof(*val));
+        *val = cpu_to_le64(extra_hosts);
+        fw_cfg_add_file(guest_info_state->info.fw_cfg,
+                        "etc/extra-pci-roots", val, sizeof(*val));
+    }
+
     acpi_setup(&guest_info_state->info);
 }
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel]  [PATCH V6 for-2.3 22/26] hw/pxb: add map_irq func
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (20 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 21/26] hw/pci: inform bios if the system has extra pci root buses Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 23/26] hw/pci_bus: add support for NUMA nodes Marcel Apfelbaum
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

The bios does not index the pxb slot number when
it computes the IRQ because it resides on bus 0
and not on the current bus.
However Qemu routes the irq through bus 0 and adds
the pxb slot to the IRQ computation of the PXB device.

Synchronize between bios and Qemu by canceling
pxb's effect.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci-bridge/pci_expander_bridge.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index e789220..3e350e6 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -93,6 +93,25 @@ static const TypeInfo pxb_host_info = {
     .class_init    = pxb_host_class_init,
 };
 
+
+static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
+{
+    PCIDevice *pxb = pci_dev->bus->parent_dev;
+
+    /*
+     * The bios does not index the pxb slot number when
+     * it computes the IRQ because it resides on bus 0
+     * and not on the current bus.
+     * However QEMU routes the irq through bus 0 and adds
+     * the pxb slot to the IRQ computation of the PXB
+     * device.
+     *
+     * Synchronize between bios and QEMU by canceling
+     * pxb's effect.
+     */
+    return pin - PCI_SLOT(pxb->devfn);
+}
+
 static int pxb_dev_initfn(PCIDevice *dev)
 {
     PXBDev *pxb = PXB_DEV(dev);
@@ -110,7 +129,7 @@ static int pxb_dev_initfn(PCIDevice *dev)
     bus->parent_dev = dev;
     bus->address_space_mem = dev->bus->address_space_mem;
     bus->address_space_io = dev->bus->address_space_io;
-    bus->map_irq = pci_swizzle_map_irq_fn;
+    bus->map_irq = pxb_map_irq_fn;
 
     bds = qdev_create(BUS(bus), "pci-bridge");
     bds->id = dev_name;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 23/26] hw/pci_bus: add support for NUMA nodes
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (21 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 22/26] hw/pxb: add map_irq func Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 24/26] hw/pxb: add numa_node parameter Marcel Apfelbaum
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

PCI root buses can be attached to a specific NUMA node.
PCI buses are not attached be default to a NUMA node.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/pci/pci_bus.c         | 7 +++++++
 include/hw/pci/pci_bus.h | 6 ++++++
 include/sysemu/sysemu.h  | 1 +
 3 files changed, 14 insertions(+)

diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
index ed99208..15882a7 100644
--- a/hw/pci/pci_bus.c
+++ b/hw/pci/pci_bus.c
@@ -13,6 +13,7 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pci_bridge.h"
 #include "monitor/monitor.h"
+#include "sysemu/sysemu.h"
 
 typedef struct {
     uint16_t class;
@@ -478,6 +479,11 @@ static int pcibus_num(PCIBus *bus)
     return bus->parent_dev->config[PCI_SECONDARY_BUS];
 }
 
+static uint16_t pcibus_numa_node(PCIBus *bus)
+{
+    return NUMA_NODE_UNASSIGNED;
+}
+
 static void pci_bus_class_init(ObjectClass *klass, void *data)
 {
     BusClass *k = BUS_CLASS(klass);
@@ -492,6 +498,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
 
     pbc->is_root = pcibus_is_root;
     pbc->bus_num = pcibus_num;
+    pbc->numa_node = pcibus_numa_node;
 }
 
 static const TypeInfo pci_bus_info = {
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 553814e..75cd1fa 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -25,6 +25,7 @@ typedef struct PCIBusClass {
 
     bool (*is_root)(PCIBus *bus);
     int (*bus_num)(PCIBus *bus);
+    uint16_t (*numa_node)(PCIBus *bus);
 } PCIBusClass;
 
 struct PCIBus {
@@ -60,6 +61,11 @@ static inline int pci_bus_num(PCIBus *bus)
     return PCI_BUS_GET_CLASS(bus)->bus_num(bus);
 }
 
+static inline int pci_bus_numa_node(PCIBus *bus)
+{
+    return PCI_BUS_GET_CLASS(bus)->numa_node(bus);
+}
+
 typedef struct PCIBridgeWindows PCIBridgeWindows;
 
 /*
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 6e85097..3897535 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -136,6 +136,7 @@ extern const char *mem_path;
 extern int mem_prealloc;
 
 #define MAX_NODES 128
+#define NUMA_NODE_UNASSIGNED MAX_NODES
 
 /* The following shall be true for all CPUs:
  *   cpu->cpu_index < max_cpus <= MAX_CPUMASK_BITS
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 24/26] hw/pxb: add numa_node parameter
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (22 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 23/26] hw/pci_bus: add support for NUMA nodes Marcel Apfelbaum
@ 2015-03-19 18:52 ` Marcel Apfelbaum
  2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS Marcel Apfelbaum
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

The pxb can be attach to and existing numa node by specifying
numa_node option that equals the desired numa nodeid.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c                |  6 ++++++
 hw/pci-bridge/pci_expander_bridge.c | 17 +++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ab7ebeb..36888ae 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -944,6 +944,7 @@ build_ssdt(GArray *table_data, GArray *linker,
         for (i = 0; i < snooping_hosts->len; i++) {
             PCIHostState *host = g_ptr_array_index(snooping_hosts, i);
             uint8_t bus_num = pci_bus_num(host->bus);
+            uint8_t numa_node = pci_bus_numa_node(host->bus);
 
             if (bus_num < root_bus_limit) {
                 root_bus_limit = bus_num - 1;
@@ -955,6 +956,11 @@ build_ssdt(GArray *table_data, GArray *linker,
                        aml_name_decl("_UID", aml_string("PC%.02X", bus_num)));
             aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A03")));
             aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));
+
+            if (numa_node != NUMA_NODE_UNASSIGNED) {
+                aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));
+            }
+
             aml_append(dev, build_prt());
             crs = build_crs(host, io_ranges, mem_ranges);
             aml_append(dev, aml_name_decl("_CRS", crs));
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 3e350e6..7d9242b 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -17,6 +17,7 @@
 #include "hw/i386/pc.h"
 #include "qemu/range.h"
 #include "qemu/error-report.h"
+#include "sysemu/numa.h"
 
 #define TYPE_PXB_BUS "pxb-bus"
 #define PXB_BUS(obj) OBJECT_CHECK(PXBBus, (obj), TYPE_PXB_BUS)
@@ -38,6 +39,7 @@ typedef struct PXBDev {
     /*< public >*/
 
     uint8_t bus_nr;
+    uint16_t numa_node;
 } PXBDev;
 
 #define TYPE_PXB_HOST "pxb-host"
@@ -54,12 +56,20 @@ static bool pxb_is_root(PCIBus *bus)
     return true; /* by definition */
 }
 
+static uint16_t pxb_bus_numa_node(PCIBus *bus)
+{
+    PXBDev *pxb = PXB_DEV(bus->parent_dev);
+
+    return pxb->numa_node;
+}
+
 static void pxb_bus_class_init(ObjectClass *class, void *data)
 {
     PCIBusClass *pbc = PCI_BUS_CLASS(class);
 
     pbc->bus_num = pxb_bus_num;
     pbc->is_root = pxb_is_root;
+    pbc->numa_node = pxb_bus_numa_node;
 }
 
 static const TypeInfo pxb_bus_info = {
@@ -119,6 +129,12 @@ static int pxb_dev_initfn(PCIDevice *dev)
     PCIBus *bus;
     const char *dev_name = NULL;
 
+    if (pxb->numa_node != NUMA_NODE_UNASSIGNED &&
+        pxb->numa_node >= nb_numa_nodes) {
+        error_report("Illegal numa node %d.", pxb->numa_node);
+        return -EINVAL;
+    }
+
     if (dev->qdev.id && *dev->qdev.id) {
         dev_name = dev->qdev.id;
     }
@@ -156,6 +172,7 @@ static int pxb_dev_initfn(PCIDevice *dev)
 static Property pxb_dev_properties[] = {
     /* Note: 0 is not a legal a PXB bus number. */
     DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0),
+    DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED),
     DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (23 preceding siblings ...)
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 24/26] hw/pxb: add numa_node parameter Marcel Apfelbaum
@ 2015-03-19 18:53 ` Marcel Apfelbaum
  2015-04-27 11:19   ` Michael S. Tsirkin
  2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 26/26] docs: Add PXB documentation Marcel Apfelbaum
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

PXB does not work with unsupported bioses, but should
not interfere with normal OS operation.
We don't ship them anymore, but it's reasonable
to keep the work-around until we update the bios in qemu.

Fix this by not adding PXB mem/IO chunks to _CRS
if they weren't configured by BIOS.

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 hw/i386/acpi-build.c | 87 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 58 insertions(+), 29 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 36888ae..219b1b6 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -823,6 +823,14 @@ static Aml *build_crs(PCIHostState *host,
             range_base = r->addr;
             range_limit = r->addr + r->size - 1;
 
+            /*
+             * Work-around for old bioses
+             * that do not support multiple root buses
+             */
+            if (!range_base || range_base > range_limit) {
+                continue;
+            }
+
             if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
                 aml_append(crs,
                     aml_word_io(aml_min_fixed, aml_max_fixed,
@@ -856,45 +864,66 @@ static Aml *build_crs(PCIHostState *host,
 
             range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
             range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
-            aml_append(crs,
-                aml_word_io(aml_min_fixed, aml_max_fixed,
-                            aml_pos_decode, aml_entire_range,
-                            0,
-                            range_base,
-                            range_limit,
-                            0,
-                            range_limit - range_base + 1));
-            crs_range_insert(io_ranges, range_base, range_limit);
+
+            /*
+             * Work-around for old bioses
+             * that do not support multiple root buses
+             */
+            if (range_base || range_base > range_limit) {
+                aml_append(crs,
+                           aml_word_io(aml_min_fixed, aml_max_fixed,
+                                       aml_pos_decode, aml_entire_range,
+                                       0,
+                                       range_base,
+                                       range_limit,
+                                       0,
+                                       range_limit - range_base + 1));
+                crs_range_insert(io_ranges, range_base, range_limit);
+            }
 
             range_base =
                 pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
             range_limit =
                 pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
-            aml_append(crs,
-                aml_dword_memory(aml_pos_decode, aml_min_fixed,
-                                 aml_max_fixed, aml_non_cacheable,
-                                 aml_ReadWrite,
-                                 0,
-                                 range_base,
-                                 range_limit,
-                                 0,
-                                 range_limit - range_base + 1));
-            crs_range_insert(mem_ranges, range_base, range_limit);
+
+            /*
+             * Work-around for old bioses
+             * that do not support multiple root buses
+             */
+            if (range_base || range_base > range_limit) {
+                aml_append(crs,
+                           aml_dword_memory(aml_pos_decode, aml_min_fixed,
+                                            aml_max_fixed, aml_non_cacheable,
+                                            aml_ReadWrite,
+                                            0,
+                                            range_base,
+                                            range_limit,
+                                            0,
+                                            range_limit - range_base + 1));
+                crs_range_insert(mem_ranges, range_base, range_limit);
+          }
 
             range_base =
                 pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
             range_limit =
                 pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
-            aml_append(crs,
-                aml_dword_memory(aml_pos_decode, aml_min_fixed,
-                                 aml_max_fixed, aml_non_cacheable,
-                                 aml_ReadWrite,
-                                 0,
-                                 range_base,
-                                 range_limit,
-                                 0,
-                                 range_limit - range_base + 1));
-            crs_range_insert(mem_ranges, range_base, range_limit);
+
+            /*
+             * Work-around for old bioses
+             * that do not support multiple root buses
+             */
+            if (range_base || range_base > range_limit) {
+                aml_append(crs,
+                           aml_dword_memory(aml_pos_decode, aml_min_fixed,
+                                            aml_max_fixed, aml_non_cacheable,
+                                            aml_ReadWrite,
+                                            0,
+                                            range_base,
+                                            range_limit,
+                                            0,
+                                            range_limit - range_base + 1));
+                crs_range_insert(mem_ranges, range_base, range_limit);
+            }
         }
     }
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [Qemu-devel] [PATCH V6 for-2.3 26/26] docs: Add PXB documentation
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (24 preceding siblings ...)
  2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS Marcel Apfelbaum
@ 2015-03-19 18:53 ` Marcel Apfelbaum
  2015-03-19 21:45 ` [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Paolo Bonzini
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-19 18:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: kraxel, mst, quintela, agraf, marcel, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
---
 docs/pci_expander_bridge.txt | 52 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 docs/pci_expander_bridge.txt

diff --git a/docs/pci_expander_bridge.txt b/docs/pci_expander_bridge.txt
new file mode 100644
index 0000000..58bf7a8
--- /dev/null
+++ b/docs/pci_expander_bridge.txt
@@ -0,0 +1,52 @@
+PCI EXPANDER BRIDGE (PXB)
+=========================
+
+Description
+===========
+PXB is a "light-weight" host bridge in the same PCI domain
+as the main host bridge whose purpose is to enable
+the main host bridge to support multiple PCI root buses.
+It is implemented only for i440fx.
+
+As opposed to PCI-2-PCI bridge's secondary bus, PXB's bus
+is a primary bus and can be associated with a NUMA node
+(different from the main host bridge) allowing the guest OS
+to recognize the proximity of a pass-through device to
+other resources as RAM and CPUs.
+
+Usage
+=====
+A detailed command line would be:
+
+[qemu-bin + storage options]
+-bios [seabios-dir]/out/bios.bin -L [seabios-dir]/out/
+-m 2G
+-object memory-backend-ram,size=1024M,policy=bind,host-nodes=0,id=ram-node0 -numa node,nodeid=0,cpus=0,memdev=ram-node0
+-object memory-backend-ram,size=1024M,policy=interleave,host-nodes=0,id=ram-node1 -numa node,nodeid=1,cpus=1,memdev=ram-node1
+-device pxb-device,id=bridge1,bus=pci.0,numa_node=1,bus_nr=4 -netdev user,id=nd-device e1000,bus=bridge1,addr=0x4,netdev=nd
+-device pxb-device,id=bridge2,bus=pci.0,numa_node=0,bus_nr=8 -device e1000,bus=bridge2,addr=0x3
+-device pxb-device,id=bridge3,bus=pci.0,bus_nr=40 -drive if=none,id=drive0,file=[img] -device virtio-blk-pci,drive=drive0,scsi=off,bus=bridge3,addr=1
+
+Here you have:
+ - 2 NUMA nodes for the guest, 0 and 1. (both mapped to the same NUMA node in host, but you can and should put it in different host NUMA nodes)
+ - a pxb host bridge attached to NUMA 1 with an e1000 behind it
+ - a pxb host bridge attached to NUMA 0 with an e1000 behind it
+ - a pxb host bridge not attached to any NUMA with a hard drive behind it.
+
+Implementation
+==============
+The PXB is composed by:
+- HostBridge (TYPE_PXB_HOST)
+  The host bridge allows to register and query the PXB's rPCI root bus in QEMU.
+- PXBDev(TYPE_PXB_DEVICE)
+  It is a regular PCI Device that resides on the piix host-bridge bus and its bus uses the same PCI domain.
+  However, the bus behind is exposed through ACPI as a primary PCI bus and starts a new PCI hierarchy.
+  The interrupts from devices behind the PXB are routed through this device the same as if it were a
+  PCI-2-PCI bridge. The _PRT follows the i440fx model.
+- PCIBridgeDev(TYPE_PCI_BRIDGE_DEV)
+  Created automatically as part of init sequence.
+  When adding a device to PXB it is attached to the bridge for two reasons:
+  - Using the bridge will enable hotplug support
+  - All the devices behind the bridge will use bridge's IO/MEM windows compacting
+    the PCI address space.
+
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (25 preceding siblings ...)
  2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 26/26] docs: Add PXB documentation Marcel Apfelbaum
@ 2015-03-19 21:45 ` Paolo Bonzini
  2015-03-20  8:37   ` Marcel Apfelbaum
  2015-03-20  7:44 ` Gerd Hoffmann
  2015-03-21 18:49 ` Michael S. Tsirkin
  28 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2015-03-19 21:45 UTC (permalink / raw)
  To: Marcel Apfelbaum, qemu-devel
  Cc: quintela, mst, agraf, alex.williamson, kevin, kraxel, amit.shah,
	imammedo, rth, leon.alrae, aurelien, hare



On 19/03/2015 19:52, Marcel Apfelbaum wrote:
>  hw/pci-host/piix.c                  | 128 ++++++++-
>  hw/pci-host/ppce500.c               |   1 +
>  hw/pci-host/q35.c                   |   5 +
>  hw/pci-host/uninorth.c              |   1 +
>  hw/pci/Makefile.objs                |   2 +-
>  hw/pci/pci.c                        | 493 +---------------------------------
>  hw/pci/pci_bus.c                    | 517 ++++++++++++++++++++++++++++++++++++
>  hw/pci/pci_host.c                   |  42 +++
>  hw/ppc/ppc4xx_pci.c                 |   1 +
>  hw/scsi/megasas.c                   |   1 +
>  hw/sh4/r2d.c                        |   1 +
>  hw/sh4/sh_pci.c                     |   1 +
>  hw/vfio/pci.c                       |   1 +
>  hw/xen/xen_pt.c                     |   1 +
>  include/hw/acpi/aml-build.h         |   8 +
>  include/hw/i386/pc.h                |   8 +-
>  include/hw/pci/pci.h                |   6 +-
>  include/hw/pci/pci_bus.h            |  35 +++
>  include/hw/pci/pci_host.h           |  34 +++
>  include/sysemu/sysemu.h             |   1 +
>  32 files changed, 1508 insertions(+), 510 deletions(-)

I think this should not be committed to 2.3 after -rc0.

Paolo

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (26 preceding siblings ...)
  2015-03-19 21:45 ` [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Paolo Bonzini
@ 2015-03-20  7:44 ` Gerd Hoffmann
  2015-03-20  8:25   ` Marcel Apfelbaum
  2015-03-21 18:49 ` Michael S. Tsirkin
  28 siblings, 1 reply; 61+ messages in thread
From: Gerd Hoffmann @ 2015-03-20  7:44 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: mst, quintela, qemu-devel, agraf, alex.williamson, kevin, hare,
	imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

  Hi,

>  - You are more than welcome to try using:
>        -bios <patched with the above series>

Not needed any more, the seabios-1.8.1 release in master should work
just fine.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-20  7:44 ` Gerd Hoffmann
@ 2015-03-20  8:25   ` Marcel Apfelbaum
  0 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-20  8:25 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: mst, quintela, qemu-devel, agraf, alex.williamson, kevin, hare,
	imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 03/20/2015 09:44 AM, Gerd Hoffmann wrote:
>    Hi,
>
>>   - You are more than welcome to try using:
>>         -bios <patched with the above series>
>
> Not needed any more, the seabios-1.8.1 release in master should work
> just fine.
Good to know, thanks!
Marcel

>
> cheers,
>    Gerd
>
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-19 21:45 ` [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Paolo Bonzini
@ 2015-03-20  8:37   ` Marcel Apfelbaum
  2015-03-20 17:56     ` Paolo Bonzini
  0 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-03-20  8:37 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel
  Cc: quintela, mst, agraf, alex.williamson, kevin, kraxel, amit.shah,
	imammedo, rth, leon.alrae, aurelien, hare

On 03/19/2015 11:45 PM, Paolo Bonzini wrote:
>
>
> On 19/03/2015 19:52, Marcel Apfelbaum wrote:
>>   hw/pci-host/piix.c                  | 128 ++++++++-
>>   hw/pci-host/ppce500.c               |   1 +
>>   hw/pci-host/q35.c                   |   5 +
>>   hw/pci-host/uninorth.c              |   1 +
>>   hw/pci/Makefile.objs                |   2 +-
>>   hw/pci/pci.c                        | 493 +---------------------------------
>>   hw/pci/pci_bus.c                    | 517 ++++++++++++++++++++++++++++++++++++
>>   hw/pci/pci_host.c                   |  42 +++
>>   hw/ppc/ppc4xx_pci.c                 |   1 +
>>   hw/scsi/megasas.c                   |   1 +
>>   hw/sh4/r2d.c                        |   1 +
>>   hw/sh4/sh_pci.c                     |   1 +
>>   hw/vfio/pci.c                       |   1 +
>>   hw/xen/xen_pt.c                     |   1 +
>>   include/hw/acpi/aml-build.h         |   8 +
>>   include/hw/i386/pc.h                |   8 +-
>>   include/hw/pci/pci.h                |   6 +-
>>   include/hw/pci/pci_bus.h            |  35 +++
>>   include/hw/pci/pci_host.h           |  34 +++
>>   include/sysemu/sysemu.h             |   1 +
>>   32 files changed, 1508 insertions(+), 510 deletions(-)
>
> I think this should not be committed to 2.3 after -rc0.
While I agree that looking at the above the series do not
fit for 2.3, I still think the risk is not big because:
- The biggest amount of modifications are in pci_bus/pci_host
   and *is only*  a movement of code into a new file,
   no changes at all (This cover almost half of the series changes)
- The series does not intervene with usual process, meaning if
   pxb is not used, it will work exactly like before
- The bios already supports pxb for this release, is a pity to wait
   for another QEMU version.
- The series were in mailing list for more than a month before rc,
   but the real review process started at rc time.
   (begging the question what a non-maintainer must do to get its code in time)
- The series is mature, rebased on the latest QEMU
   and was reviewed in depth and tested by the community.

The above being said, I'll agree with whatever the maintainers will decide.

Thanks,
Marcel

>
> Paolo
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-20  8:37   ` Marcel Apfelbaum
@ 2015-03-20 17:56     ` Paolo Bonzini
  2015-03-20 18:07       ` Peter Maydell
  0 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2015-03-20 17:56 UTC (permalink / raw)
  To: Marcel Apfelbaum, qemu-devel
  Cc: quintela, mst, agraf, alex.williamson, kevin, kraxel, amit.shah,
	imammedo, rth, leon.alrae, aurelien, hare



On 20/03/2015 09:37, Marcel Apfelbaum wrote:
>> I think this should not be committed to 2.3 after -rc0.
> While I agree that looking at the above the series do not
> fit for 2.3, I still think the risk is not big because:
> - The biggest amount of modifications are in pci_bus/pci_host
>   and *is only*  a movement of code into a new file,
>   no changes at all (This cover almost half of the series changes)
> - The series does not intervene with usual process, meaning if
>   pxb is not used, it will work exactly like before
> - The bios already supports pxb for this release, is a pity to wait
>   for another QEMU version.
> - The series were in mailing list for more than a month before rc,
>   but the real review process started at rc time.
>   (begging the question what a non-maintainer must do to get its code in
> time)
> - The series is mature, rebased on the latest QEMU
>   and was reviewed in depth and tested by the community.

I understand, but you have to draw a line somewhere.  The easiest place
to draw the line is 2.3.0-rc0.

Maintainers can already prepare branches with patches destined to 2.4,
and these 26 can be included there.  As far as you are concerned, if the
code is ready you can stop worrying about it.

The problem isn't non-maintainer vs. maintainer.  There was a dependency
on Igor's series, which took some time to get in---partly because it was
included in a 100-patch pull request, which isn't exactly the preferred
way to send pull request in absence of a serious effort on continuous
integration of maintainer branches.

Paolo

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-20 17:56     ` Paolo Bonzini
@ 2015-03-20 18:07       ` Peter Maydell
  0 siblings, 0 replies; 61+ messages in thread
From: Peter Maydell @ 2015-03-20 18:07 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Michael S. Tsirkin, Hannes Reinecke, Juan Quintela,
	Alexander Graf, QEMU Developers, Amit Shah, Alex Williamson,
	Kevin OConnor, Gerd Hoffmann, Marcel Apfelbaum, Igor Mammedov,
	Leon Alrae, Aurelien Jarno, Richard Henderson

On 20 March 2015 at 17:56, Paolo Bonzini <pbonzini@redhat.com> wrote:
> I understand, but you have to draw a line somewhere.  The easiest place
> to draw the line is 2.3.0-rc0.

I definitely agree -- looking at the diffstat and the scope
of the patch, this is definitely not suitable for committing
to master after hardfreeze.

Yes, sometimes code doesn't get in for the release you were
hoping for through no fault of the developers involved, and
that sucks. But the release model we have is "every three
to four months, time based", which means that (a) we need to
avoid delays to releases, which means being fairly strict
about what we permit into the tree during freeze, but also
(b) even if you do miss a release, the next one will be
along fairly shortly.

-- PMM

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines
  2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
                   ` (27 preceding siblings ...)
  2015-03-20  7:44 ` Gerd Hoffmann
@ 2015-03-21 18:49 ` Michael S. Tsirkin
  28 siblings, 0 replies; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-03-21 18:49 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:52:35PM +0200, Marcel Apfelbaum wrote:
> Notes:
>  - I realize that this qualifies as a late submission, but the code was arround
>    a lot of time and got lots of reviews and it also tested (by Gerd), so should be mature enough.
>  - This series is not that big, patches 1-8 are really small and can be submitted
>    separately, however I preferred to keep them here to get the whole picture.

Sorry, I have agree with other maintainers here: this doesn't look
like 2.3 material to me, we are in a fixes only period now.

This doesn't mean I won't merge it though: this time around
I opened pci-next and will queue patches there, so no
extra effort on your side should be required.

> 
> The series is fully functional.
>  - Limitations:
>    - Pxb's bus does not support hotplug. It will be addressed on top of this series
>      because is already getting to big.

Absolutely, and it's a reasonable thing to do normally, but not
when we are trying to finalize a release.
Looks like another reason to defer this to 2.4.

>  - You are more than welcome to try using:
>        -device pxb-device,id=pxb,bus_nr=4,numa_node=1 -device e1000,bus=pxb,addr=0x1 -bios <patched with the above series>

-- 
MST

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files Marcel Apfelbaum
@ 2015-04-27 11:14   ` Michael S. Tsirkin
  2015-04-27 11:35     ` Paolo Bonzini
  2015-04-27 12:26     ` Marcel Apfelbaum
  0 siblings, 2 replies; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 11:14 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:52:44PM +0200, Marcel Apfelbaum wrote:
> @@ -2414,7 +1945,6 @@ static const TypeInfo pci_device_type_info = {
>  
>  static void pci_register_types(void)
>  {
> -    type_register_static(&pci_bus_info);
>      type_register_static(&pcie_bus_info);
>      type_register_static(&pci_device_type_info);
>  }

So pcie bus is not moved.  This seems pretty inconsistent.


> diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
> new file mode 100644
> index 0000000..d156194
> --- /dev/null
> +++ b/hw/pci/pci_bus.c
> @@ -0,0 +1,491 @@
> +/*
> + * PCI Bus
> + *
> + * Copyright (C) 2014 Red Hat Inc

It's 2015 isn't it?

> + *
> + * Authors:
> + *   Marcel Apfelbaum <marcel.a@redhat.com> (split out from pci.c)

You don't become the only Author just by moving code around.
Better drop this line.



> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.

The file you are moving this from is GPL only.
You will need to find who contributed this code you are moving
and get ack from them ...

> + */
> +#include "hw/pci/pci.h"
> +#include "hw/pci/pci_bus.h"
> +#include "hw/pci/pci_bridge.h"
> +#include "monitor/monitor.h"
> +
> +typedef struct {
> +    uint16_t class;
> +    const char *desc;
> +    const char *fw_name;
> +    uint16_t fw_ign_bits;
> +} pci_class_desc;
> +
> +static const pci_class_desc pci_class_descriptions[] = {
> +    { 0x0001, "VGA controller", "display"},
> +    { 0x0100, "SCSI controller", "scsi"},
> +    { 0x0101, "IDE controller", "ide"},
> +    { 0x0102, "Floppy controller", "fdc"},
> +    { 0x0103, "IPI controller", "ipi"},
> +    { 0x0104, "RAID controller", "raid"},
> +    { 0x0106, "SATA controller"},
> +    { 0x0107, "SAS controller"},
> +    { 0x0180, "Storage controller"},
> +    { 0x0200, "Ethernet controller", "ethernet"},
> +    { 0x0201, "Token Ring controller", "token-ring"},
> +    { 0x0202, "FDDI controller", "fddi"},
> +    { 0x0203, "ATM controller", "atm"},
> +    { 0x0280, "Network controller"},
> +    { 0x0300, "VGA controller", "display", 0x00ff},
> +    { 0x0301, "XGA controller"},
> +    { 0x0302, "3D controller"},
> +    { 0x0380, "Display controller"},
> +    { 0x0400, "Video controller", "video"},
> +    { 0x0401, "Audio controller", "sound"},
> +    { 0x0402, "Phone"},
> +    { 0x0403, "Audio controller", "sound"},
> +    { 0x0480, "Multimedia controller"},
> +    { 0x0500, "RAM controller", "memory"},
> +    { 0x0501, "Flash controller", "flash"},
> +    { 0x0580, "Memory controller"},
> +    { 0x0600, "Host bridge", "host"},
> +    { 0x0601, "ISA bridge", "isa"},
> +    { 0x0602, "EISA bridge", "eisa"},
> +    { 0x0603, "MC bridge", "mca"},
> +    { 0x0604, "PCI bridge", "pci-bridge"},
> +    { 0x0605, "PCMCIA bridge", "pcmcia"},
> +    { 0x0606, "NUBUS bridge", "nubus"},
> +    { 0x0607, "CARDBUS bridge", "cardbus"},
> +    { 0x0608, "RACEWAY bridge"},
> +    { 0x0680, "Bridge"},
> +    { 0x0700, "Serial port", "serial"},
> +    { 0x0701, "Parallel port", "parallel"},
> +    { 0x0800, "Interrupt controller", "interrupt-controller"},
> +    { 0x0801, "DMA controller", "dma-controller"},
> +    { 0x0802, "Timer", "timer"},
> +    { 0x0803, "RTC", "rtc"},
> +    { 0x0900, "Keyboard", "keyboard"},
> +    { 0x0901, "Pen", "pen"},
> +    { 0x0902, "Mouse", "mouse"},
> +    { 0x0A00, "Dock station", "dock", 0x00ff},
> +    { 0x0B00, "i386 cpu", "cpu", 0x00ff},
> +    { 0x0c00, "Fireware contorller", "fireware"},
> +    { 0x0c01, "Access bus controller", "access-bus"},
> +    { 0x0c02, "SSA controller", "ssa"},
> +    { 0x0c03, "USB controller", "usb"},
> +    { 0x0c04, "Fibre channel controller", "fibre-channel"},
> +    { 0x0c05, "SMBus"},
> +    { 0, NULL}
> +};
> +
> +/* Whether a given bus number is in range of the secondary
> + * bus of the given bridge device. */
> +static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
> +{
> +    return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
> +             PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ &&
> +        dev->config[PCI_SECONDARY_BUS] < bus_num &&
> +        bus_num <= dev->config[PCI_SUBORDINATE_BUS];
> +}
> +
> +PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
> +{
> +    PCIBus *sec;
> +
> +    if (!bus) {
> +        return NULL;
> +    }
> +
> +    if (pci_bus_num(bus) == bus_num) {
> +        return bus;
> +    }
> +
> +    /* Consider all bus numbers in range for the host pci bridge. */
> +    if (!pci_bus_is_root(bus) &&
> +        !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
> +        return NULL;
> +    }
> +
> +    /* try child bus */
> +    for (; bus; bus = sec) {
> +        QLIST_FOREACH(sec, &bus->child, sibling) {
> +            assert(!pci_bus_is_root(sec));
> +            if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
> +                return sec;
> +            }
> +            if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
> +                break;
> +            }
> +        }
> +    }
> +
> +    return NULL;
> +}
> +
> +static const pci_class_desc *get_class_desc(int class)
> +{
> +    const pci_class_desc *desc;
> +
> +    desc = pci_class_descriptions;
> +    while (desc->desc && class != desc->class) {
> +        desc++;
> +    }
> +
> +    return desc;
> +}
> +
> +static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
> +{
> +    PciMemoryRegionList *head = NULL, *cur_item = NULL;
> +    int i;
> +
> +    for (i = 0; i < PCI_NUM_REGIONS; i++) {
> +        const PCIIORegion *r = &dev->io_regions[i];
> +        PciMemoryRegionList *region;
> +
> +        if (!r->size) {
> +            continue;
> +        }
> +
> +        region = g_malloc0(sizeof(*region));
> +        region->value = g_malloc0(sizeof(*region->value));
> +
> +        if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
> +            region->value->type = g_strdup("io");
> +        } else {
> +            region->value->type = g_strdup("memory");
> +            region->value->has_prefetch = true;
> +            region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
> +            region->value->has_mem_type_64 = true;
> +            region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
> +        }
> +
> +        region->value->bar = i;
> +        region->value->address = r->addr;
> +        region->value->size = r->size;
> +
> +        /* XXX: waiting for the qapi to support GSList */
> +        if (!cur_item) {
> +            head = cur_item = region;
> +        } else {
> +            cur_item->next = region;
> +            cur_item = region;
> +        }
> +    }
> +
> +    return head;
> +}
> +
> +static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
> +                                           int bus_num)
> +{
> +    PciBridgeInfo *info;
> +
> +    info = g_malloc0(sizeof(*info));
> +
> +    info->bus.number = dev->config[PCI_PRIMARY_BUS];
> +    info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
> +    info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
> +
> +    info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
> +    info->bus.io_range->base = pci_bridge_get_base(dev,
> +                    PCI_BASE_ADDRESS_SPACE_IO);
> +    info->bus.io_range->limit =
> +                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
> +
> +    info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
> +    info->bus.memory_range->base =
> +                    pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
> +    info->bus.memory_range->limit =
> +                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
> +
> +    info->bus.prefetchable_range =
> +                    g_malloc0(sizeof(*info->bus.prefetchable_range));
> +    info->bus.prefetchable_range->base =
> +                    pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
> +    info->bus.prefetchable_range->limit =
> +                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
> +
> +    if (dev->config[PCI_SECONDARY_BUS] != 0) {
> +        PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]);
> +        if (child_bus) {
> +            info->has_devices = true;
> +            info->devices = qmp_query_pci_devices(child_bus,
> +                                                  dev->config[PCI_SECONDARY_BUS]);
> +        }
> +    }
> +
> +    return info;
> +}
> +
> +static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
> +                                           int bus_num)
> +{
> +    const pci_class_desc *desc;
> +    PciDeviceInfo *info;
> +    uint8_t type;
> +    int class;
> +
> +    info = g_malloc0(sizeof(*info));
> +    info->bus = bus_num;
> +    info->slot = PCI_SLOT(dev->devfn);
> +    info->function = PCI_FUNC(dev->devfn);
> +
> +    class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
> +    info->class_info.q_class = class;
> +    desc = get_class_desc(class);
> +    if (desc->desc) {
> +        info->class_info.has_desc = true;
> +        info->class_info.desc = g_strdup(desc->desc);
> +    }
> +
> +    info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
> +    info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
> +    info->regions = qmp_query_pci_regions(dev);
> +    info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
> +
> +    if (dev->config[PCI_INTERRUPT_PIN] != 0) {
> +        info->has_irq = true;
> +        info->irq = dev->config[PCI_INTERRUPT_LINE];
> +    }
> +
> +    type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
> +    if (type == PCI_HEADER_TYPE_BRIDGE) {
> +        info->has_pci_bridge = true;
> +        info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
> +    }
> +
> +    return info;
> +}
> +
> +PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
> +{
> +    PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
> +    PCIDevice *dev;
> +    int devfn;
> +
> +    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
> +        dev = bus->devices[devfn];
> +        if (dev) {
> +            info = g_malloc0(sizeof(*info));
> +            info->value = qmp_query_pci_device(dev, bus, bus_num);
> +
> +            /* XXX: waiting for the qapi to support GSList */
> +            if (!cur_item) {
> +                head = cur_item = info;
> +            } else {
> +                cur_item->next = info;
> +                cur_item = info;
> +            }
> +        }
> +    }
> +
> +    return head;
> +}
> +
> +
> +static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
> +{
> +    PCIDevice *d = (PCIDevice *)dev;
> +    const pci_class_desc *desc;
> +    char ctxt[64];
> +    PCIIORegion *r;
> +    int i, class;
> +
> +    class = pci_get_word(d->config + PCI_CLASS_DEVICE);
> +    desc = pci_class_descriptions;
> +    while (desc->desc && class != desc->class) {
> +        desc++;
> +    }
> +    if (desc->desc) {
> +        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
> +    } else {
> +        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
> +    }
> +
> +    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
> +                   "pci id %04x:%04x (sub %04x:%04x)\n",
> +                   indent, "", ctxt, pci_bus_num(d->bus),
> +                   PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
> +                   pci_get_word(d->config + PCI_VENDOR_ID),
> +                   pci_get_word(d->config + PCI_DEVICE_ID),
> +                   pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
> +                   pci_get_word(d->config + PCI_SUBSYSTEM_ID));
> +    for (i = 0; i < PCI_NUM_REGIONS; i++) {
> +        r = &d->io_regions[i];
> +        if (!r->size) {
> +            continue;
> +        }
> +        monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
> +                       " [0x%"FMT_PCIBUS"]\n",
> +                       indent, "",
> +                       i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
> +                       r->addr, r->addr + r->size - 1);
> +    }
> +}
> +
> +static char *pcibus_get_dev_path(DeviceState *dev)
> +{
> +    PCIDevice *d = container_of(dev, PCIDevice, qdev);
> +    PCIDevice *t;
> +    int slot_depth;
> +    /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
> +     * 00 is added here to make this format compatible with
> +     * domain:Bus:Slot.Func for systems without nested PCI bridges.
> +     * Slot.Function list specifies the slot and function numbers for all
> +     * devices on the path from root to the specific device. */
> +    const char *root_bus_path;
> +    int root_bus_len;
> +    char slot[] = ":SS.F";
> +    int slot_len = sizeof slot - 1 /* For '\0' */;
> +    int path_len;
> +    char *path, *p;
> +    int s;
> +
> +    root_bus_path = pci_root_bus_path(d);
> +    root_bus_len = strlen(root_bus_path);
> +
> +    /* Calculate # of slots on path between device and root. */;
> +    slot_depth = 0;
> +    for (t = d; t; t = t->bus->parent_dev) {
> +        ++slot_depth;
> +    }
> +
> +    path_len = root_bus_len + slot_len * slot_depth;
> +
> +    /* Allocate memory, fill in the terminating null byte. */
> +    path = g_malloc(path_len + 1 /* For '\0' */);
> +    path[path_len] = '\0';
> +
> +    memcpy(path, root_bus_path, root_bus_len);
> +
> +    /* Fill in slot numbers. We walk up from device to root, so need to print
> +     * them in the reverse order, last to first. */
> +    p = path + path_len;
> +    for (t = d; t; t = t->bus->parent_dev) {
> +        p -= slot_len;
> +        s = snprintf(slot, sizeof slot, ":%02x.%x",
> +                     PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
> +        assert(s == slot_len);
> +        memcpy(p, slot, slot_len);
> +    }
> +
> +    return path;
> +}
> +
> +static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
> +{
> +    PCIDevice *d = (PCIDevice *)dev;
> +    const char *name = NULL;
> +    const pci_class_desc *desc =  pci_class_descriptions;
> +    int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
> +
> +    while (desc->desc &&
> +          (class & ~desc->fw_ign_bits) !=
> +          (desc->class & ~desc->fw_ign_bits)) {
> +        desc++;
> +    }
> +
> +    if (desc->desc) {
> +        name = desc->fw_name;
> +    }
> +
> +    if (name) {
> +        pstrcpy(buf, len, name);
> +    } else {
> +        snprintf(buf, len, "pci%04x,%04x",
> +                 pci_get_word(d->config + PCI_VENDOR_ID),
> +                 pci_get_word(d->config + PCI_DEVICE_ID));
> +    }
> +
> +    return buf;
> +}
> +
> +static char *pcibus_get_fw_dev_path(DeviceState *dev)
> +{
> +    PCIDevice *d = (PCIDevice *)dev;
> +    char path[50], name[33];
> +    int off;
> +
> +    off = snprintf(path, sizeof(path), "%s@%x",
> +                   pci_dev_fw_name(dev, name, sizeof name),
> +                   PCI_SLOT(d->devfn));
> +    if (PCI_FUNC(d->devfn)) {
> +        snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
> +    }
> +    return g_strdup(path);
> +}
> +
> +static const VMStateDescription vmstate_pcibus = {
> +    .name = "PCIBUS",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_INT32_EQUAL(nirq, PCIBus),
> +        VMSTATE_VARRAY_INT32(irq_count, PCIBus,
> +                             nirq, 0, vmstate_info_int32,
> +                             int32_t),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static void pci_bus_realize(BusState *qbus, Error **errp)
> +{
> +    PCIBus *bus = PCI_BUS(qbus);
> +
> +    vmstate_register(NULL, -1, &vmstate_pcibus, bus);
> +}
> +
> +static void pci_bus_unrealize(BusState *qbus, Error **errp)
> +{
> +    PCIBus *bus = PCI_BUS(qbus);
> +
> +    vmstate_unregister(NULL, &vmstate_pcibus, bus);
> +}
> +
> +/*
> + * Trigger pci bus reset under a given bus.
> + * Called via qbus_reset_all on RST# assert, after the devices
> + * have been reset qdev_reset_all-ed already.
> + */
> +static void pcibus_reset(BusState *qbus)
> +{
> +    PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
> +        if (bus->devices[i]) {
> +            pci_do_device_reset(bus->devices[i]);
> +        }
> +    }
> +
> +    for (i = 0; i < bus->nirq; i++) {
> +        assert(bus->irq_count[i] == 0);
> +    }
> +}
> +
> +static void pci_bus_class_init(ObjectClass *klass, void *data)
> +{
> +    BusClass *k = BUS_CLASS(klass);
> +
> +    k->print_dev = pcibus_dev_print;
> +    k->get_dev_path = pcibus_get_dev_path;
> +    k->get_fw_dev_path = pcibus_get_fw_dev_path;
> +    k->realize = pci_bus_realize;
> +    k->unrealize = pci_bus_unrealize;
> +    k->reset = pcibus_reset;
> +}
> +
> +static const TypeInfo pci_bus_info = {
> +    .name = TYPE_PCI_BUS,
> +    .parent = TYPE_BUS,
> +    .instance_size = sizeof(PCIBus),
> +    .class_init = pci_bus_class_init,
> +};
> +
> +static void pci_bus_register_types(void)
> +{
> +    type_register_static(&pci_bus_info);
> +}
> +
> +type_init(pci_bus_register_types)
> diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
> index 0bb3cdb..f5847bc 100644
> --- a/hw/ppc/ppc4xx_pci.c
> +++ b/hw/ppc/ppc4xx_pci.c
> @@ -23,6 +23,7 @@
>  #include "hw/ppc/ppc.h"
>  #include "hw/ppc/ppc4xx.h"
>  #include "hw/pci/pci.h"
> +#include "hw/pci/pci_bus.h"
>  #include "hw/pci/pci_host.h"
>  #include "exec/address-spaces.h"
>  
> diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
> index d1d0847..8dd2ce3 100644
> --- a/hw/sh4/r2d.c
> +++ b/hw/sh4/r2d.c
> @@ -30,6 +30,7 @@
>  #include "sysemu/sysemu.h"
>  #include "hw/boards.h"
>  #include "hw/pci/pci.h"
> +#include "hw/pci/pci_bus.h"
>  #include "net/net.h"
>  #include "sh7750_regs.h"
>  #include "hw/ide.h"
> diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
> index a2f6d9e..f02e998 100644
> --- a/hw/sh4/sh_pci.c
> +++ b/hw/sh4/sh_pci.c
> @@ -24,6 +24,7 @@
>  #include "hw/sysbus.h"
>  #include "hw/sh4/sh.h"
>  #include "hw/pci/pci.h"
> +#include "hw/pci/pci_bus.h"
>  #include "hw/pci/pci_host.h"
>  #include "qemu/bswap.h"
>  #include "exec/address-spaces.h"
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index be2d9b8..47077cd 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -337,8 +337,6 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
>  typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
>  typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
>  
> -#define TYPE_PCI_BUS "PCI"
> -#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
>  #define TYPE_PCIE_BUS "PCIE"
>  
>  bool pci_bus_is_express(PCIBus *bus);
> @@ -370,6 +368,7 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
>  void pci_device_set_intx_routing_notifier(PCIDevice *dev,
>                                            PCIINTxRoutingNotifier notifier);
>  void pci_device_reset(PCIDevice *dev);
> +void pci_do_device_reset(PCIDevice *dev);

I don't like it that there are two reset functions now.

>  
>  PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
>                                 const char *default_model,
> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
> index fabaeee..ea427a3 100644
> --- a/include/hw/pci/pci_bus.h
> +++ b/include/hw/pci/pci_bus.h
> @@ -1,6 +1,8 @@
>  #ifndef QEMU_PCI_BUS_H
>  #define QEMU_PCI_BUS_H
>  
> +#include "hw/pci/pci.h"
> +
>  /*
>   * PCI Bus and Bridge datastructures.
>   *
> @@ -8,6 +10,12 @@
>   * use accessor functions in pci.h, pci_bridge.h
>   */
>  
> +PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
> +PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
> +
> +#define TYPE_PCI_BUS "PCI"
> +#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
> +
>  struct PCIBus {
>      BusState qbus;
>      PCIIOMMUFunc iommu_fn;


Can we drop this patch, do refactoring on top later?

> -- 
> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS
  2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS Marcel Apfelbaum
@ 2015-04-27 11:19   ` Michael S. Tsirkin
  2015-04-27 11:51     ` Gerd Hoffmann
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 11:19 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:53:00PM +0200, Marcel Apfelbaum wrote:
> PXB does not work with unsupported bioses, but should
> not interfere with normal OS operation.
> We don't ship them anymore, but it's reasonable
> to keep the work-around until we update the bios in qemu.

Can be dropped now we have updated the bios?

> Fix this by not adding PXB mem/IO chunks to _CRS
> if they weren't configured by BIOS.
> 
> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> ---
>  hw/i386/acpi-build.c | 87 ++++++++++++++++++++++++++++++++++------------------
>  1 file changed, 58 insertions(+), 29 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 36888ae..219b1b6 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -823,6 +823,14 @@ static Aml *build_crs(PCIHostState *host,
>              range_base = r->addr;
>              range_limit = r->addr + r->size - 1;
>  
> +            /*
> +             * Work-around for old bioses
> +             * that do not support multiple root buses
> +             */
> +            if (!range_base || range_base > range_limit) {
> +                continue;
> +            }
> +
>              if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
>                  aml_append(crs,
>                      aml_word_io(aml_min_fixed, aml_max_fixed,
> @@ -856,45 +864,66 @@ static Aml *build_crs(PCIHostState *host,
>  
>              range_base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
>              range_limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
> -            aml_append(crs,
> -                aml_word_io(aml_min_fixed, aml_max_fixed,
> -                            aml_pos_decode, aml_entire_range,
> -                            0,
> -                            range_base,
> -                            range_limit,
> -                            0,
> -                            range_limit - range_base + 1));
> -            crs_range_insert(io_ranges, range_base, range_limit);
> +
> +            /*
> +             * Work-around for old bioses
> +             * that do not support multiple root buses
> +             */
> +            if (range_base || range_base > range_limit) {
> +                aml_append(crs,
> +                           aml_word_io(aml_min_fixed, aml_max_fixed,
> +                                       aml_pos_decode, aml_entire_range,
> +                                       0,
> +                                       range_base,
> +                                       range_limit,
> +                                       0,
> +                                       range_limit - range_base + 1));
> +                crs_range_insert(io_ranges, range_base, range_limit);
> +            }
>  
>              range_base =
>                  pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
>              range_limit =
>                  pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
> -            aml_append(crs,
> -                aml_dword_memory(aml_pos_decode, aml_min_fixed,
> -                                 aml_max_fixed, aml_non_cacheable,
> -                                 aml_ReadWrite,
> -                                 0,
> -                                 range_base,
> -                                 range_limit,
> -                                 0,
> -                                 range_limit - range_base + 1));
> -            crs_range_insert(mem_ranges, range_base, range_limit);
> +
> +            /*
> +             * Work-around for old bioses
> +             * that do not support multiple root buses
> +             */
> +            if (range_base || range_base > range_limit) {
> +                aml_append(crs,
> +                           aml_dword_memory(aml_pos_decode, aml_min_fixed,
> +                                            aml_max_fixed, aml_non_cacheable,
> +                                            aml_ReadWrite,
> +                                            0,
> +                                            range_base,
> +                                            range_limit,
> +                                            0,
> +                                            range_limit - range_base + 1));
> +                crs_range_insert(mem_ranges, range_base, range_limit);
> +          }
>  
>              range_base =
>                  pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
>              range_limit =
>                  pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
> -            aml_append(crs,
> -                aml_dword_memory(aml_pos_decode, aml_min_fixed,
> -                                 aml_max_fixed, aml_non_cacheable,
> -                                 aml_ReadWrite,
> -                                 0,
> -                                 range_base,
> -                                 range_limit,
> -                                 0,
> -                                 range_limit - range_base + 1));
> -            crs_range_insert(mem_ranges, range_base, range_limit);
> +
> +            /*
> +             * Work-around for old bioses
> +             * that do not support multiple root buses
> +             */
> +            if (range_base || range_base > range_limit) {
> +                aml_append(crs,
> +                           aml_dword_memory(aml_pos_decode, aml_min_fixed,
> +                                            aml_max_fixed, aml_non_cacheable,
> +                                            aml_ReadWrite,
> +                                            0,
> +                                            range_base,
> +                                            range_limit,
> +                                            0,
> +                                            range_limit - range_base + 1));
> +                crs_range_insert(mem_ranges, range_base, range_limit);
> +            }
>          }
>      }
>  
> -- 
> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface Marcel Apfelbaum
@ 2015-04-27 11:24   ` Michael S. Tsirkin
  2015-04-27 12:30     ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 11:24 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:52:47PM +0200, Marcel Apfelbaum wrote:
> From: Marcel Apfelbaum <marcel.a@redhat.com>
> 
> This is a marker interface used to differentiate the
> "default" host bridge on a system with multiple host bridges.
> This differentiation is required only for pc machines for now
> by the ACPI subsystem.
> 
> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>

Fixing hotplug for pxb almost for sure means we'll need
to drop this later. How about an interface to
iterate over objects by type?
You can then blacklist pxbs for now.

> ---
>  hw/i386/acpi-build.c      | 9 ++++++---
>  hw/pci-host/piix.c        | 5 +++++
>  hw/pci-host/q35.c         | 4 ++++
>  hw/pci/pci_host.c         | 6 ++++++
>  include/hw/pci/pci_host.h | 7 +++++++
>  5 files changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index d0a5c85..86e474a 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
>      Object *pci_host;
>      bool ambiguous;
>  
> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> +                                        &ambiguous);
>      g_assert(!ambiguous);
>      g_assert(pci_host);
>  
> @@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
>              PCIBus *bus = NULL;
>              bool ambiguous;
>  
> -            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> +            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> +                                                &ambiguous);
>              if (!ambiguous && pci_host) {
>                  bus = PCI_HOST_BRIDGE(pci_host)->bus;
>              }
> @@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>      QObject *o;
>      bool ambiguous;
>  
> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> +                                        &ambiguous);
>      g_assert(!ambiguous);
>      g_assert(pci_host);
>  
> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index 292b6e9..0033ab4 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
>      .instance_size = sizeof(I440FXState),
>      .instance_init = i440fx_pcihost_initfn,
>      .class_init    = i440fx_pcihost_class_init,
> +    .interfaces    = (InterfaceInfo[]) {
> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
> +        { }
> +    }
> +
>  };
>  
>  static void i440fx_register_types(void)
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index 5dd559e..e35b3a2 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
>      .instance_size = sizeof(Q35PCIHost),
>      .instance_init = q35_host_initfn,
>      .class_init = q35_host_class_init,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
> +        { }
> +    }
>  };
>  
>  /****************************************************************************
> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> index 3e26f92..87180c8 100644
> --- a/hw/pci/pci_host.c
> +++ b/hw/pci/pci_host.c
> @@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
>      .endianness = DEVICE_BIG_ENDIAN,
>  };
>  
> +static const TypeInfo pci_main_host_interface_info = {
> +    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
> +    .parent        = TYPE_INTERFACE,
> +};
> +
>  static const TypeInfo pci_host_type_info = {
>      .name = TYPE_PCI_HOST_BRIDGE,
>      .parent = TYPE_SYS_BUS_DEVICE,
> @@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
>  
>  static void pci_host_register_types(void)
>  {
> +    type_register_static(&pci_main_host_interface_info);
>      type_register_static(&pci_host_type_info);
>  }
>  
> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> index ba31595..3c72e26 100644
> --- a/include/hw/pci/pci_host.h
> +++ b/include/hw/pci/pci_host.h
> @@ -30,6 +30,13 @@
>  
>  #include "hw/sysbus.h"
>  
> +/**
> + * Marker interface for classes whose instances can
> + * be main host bridges. It is intended to be used
> + * when the QOM tree includes multiple host bridges.
> + */
> +#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
> +
>  #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
>  #define PCI_HOST_BRIDGE(obj) \
>      OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
> -- 
> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-27 11:14   ` Michael S. Tsirkin
@ 2015-04-27 11:35     ` Paolo Bonzini
  2015-04-27 11:49       ` Marcel Apfelbaum
  2015-04-28  7:31       ` Markus Armbruster
  2015-04-27 12:26     ` Marcel Apfelbaum
  1 sibling, 2 replies; 61+ messages in thread
From: Paolo Bonzini @ 2015-04-27 11:35 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum
  Cc: quintela, qemu-devel, agraf, alex.williamson, kevin, kraxel,
	amit.shah, imammedo, rth, leon.alrae, aurelien, hare


On 27/04/2015 13:14, Michael S. Tsirkin wrote:
>> + *
>> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> > + * See the COPYING file in the top-level directory.
> The file you are moving this from is GPL only.

It's BSD.

> You will need to find who contributed this code you are moving
> and get ack from them ...

Simpler to keep BSD.

Paolo

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method Marcel Apfelbaum
@ 2015-04-27 11:37   ` Michael S. Tsirkin
  2015-04-27 11:49     ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 11:37 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:52:45PM +0200, Marcel Apfelbaum wrote:
> From: Marcel Apfelbaum <marcel.a@redhat.com>
> 
> Refactoring it as a method of PCIBusClass will allow
> different implementations for subclasses.
> 
> Removed the assumption that the root bus does not
> have a parent device because is specific only
> to the default class implementation.
> 
> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>

Or just add bool is_root there?
Won't that be simpler?

> ---
>  hw/pci/pci.c             | 11 ++++-------
>  hw/pci/pci_bus.c         |  9 +++++++++
>  hw/vfio/pci.c            |  1 +
>  include/hw/pci/pci.h     |  1 -
>  include/hw/pci/pci_bus.h | 15 +++++++++++++++
>  5 files changed, 29 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index cb63a21..376b42d 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -205,7 +205,10 @@ PCIBus *pci_device_root_bus(const PCIDevice *d)
>  {
>      PCIBus *bus = d->bus;
>  
> -    while ((d = bus->parent_dev) != NULL) {
> +    while (!pci_bus_is_root(bus)) {
> +        d = bus->parent_dev;
> +        assert(d != NULL);
> +
>          bus = d->bus;
>      }
>  
> @@ -218,7 +221,6 @@ const char *pci_root_bus_path(PCIDevice *dev)
>      PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent);
>      PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
>  
> -    assert(!rootbus->parent_dev);
>      assert(host_bridge->bus == rootbus);
>  
>      if (hc->root_bus_path) {
> @@ -250,11 +252,6 @@ bool pci_bus_is_express(PCIBus *bus)
>      return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
>  }
>  
> -bool pci_bus_is_root(PCIBus *bus)
> -{
> -    return !bus->parent_dev;
> -}
> -
>  void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
>                           const char *name,
>                           MemoryRegion *address_space_mem,
> diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
> index d156194..0922a75 100644
> --- a/hw/pci/pci_bus.c
> +++ b/hw/pci/pci_bus.c
> @@ -464,9 +464,15 @@ static void pcibus_reset(BusState *qbus)
>      }
>  }
>  
> +static bool pcibus_is_root(PCIBus *bus)
> +{
> +    return !bus->parent_dev;
> +}
> +
>  static void pci_bus_class_init(ObjectClass *klass, void *data)
>  {
>      BusClass *k = BUS_CLASS(klass);
> +    PCIBusClass *pbc = PCI_BUS_CLASS(klass);
>  
>      k->print_dev = pcibus_dev_print;
>      k->get_dev_path = pcibus_get_dev_path;
> @@ -474,11 +480,14 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
>      k->realize = pci_bus_realize;
>      k->unrealize = pci_bus_unrealize;
>      k->reset = pcibus_reset;
> +
> +    pbc->is_root = pcibus_is_root;
>  }
>  
>  static const TypeInfo pci_bus_info = {
>      .name = TYPE_PCI_BUS,
>      .parent = TYPE_BUS,
> +    .class_size = sizeof(PCIBusClass),
>      .instance_size = sizeof(PCIBus),
>      .class_init = pci_bus_class_init,
>  };
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 6b80539..7b08d03 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -32,6 +32,7 @@
>  #include "hw/pci/msi.h"
>  #include "hw/pci/msix.h"
>  #include "hw/pci/pci.h"
> +#include "hw/pci/pci_bus.h"
>  #include "qemu-common.h"
>  #include "qemu/error-report.h"
>  #include "qemu/event_notifier.h"
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 47077cd..ae2c4a5 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -340,7 +340,6 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
>  #define TYPE_PCIE_BUS "PCIE"
>  
>  bool pci_bus_is_express(PCIBus *bus);
> -bool pci_bus_is_root(PCIBus *bus);
>  void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
>                           const char *name,
>                           MemoryRegion *address_space_mem,
> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
> index ea427a3..306ef10 100644
> --- a/include/hw/pci/pci_bus.h
> +++ b/include/hw/pci/pci_bus.h
> @@ -15,6 +15,16 @@ PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
>  
>  #define TYPE_PCI_BUS "PCI"
>  #define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
> +#define PCI_BUS_CLASS(klass) OBJECT_CLASS_CHECK(PCIBusClass, (klass), TYPE_PCI_BUS)
> +#define PCI_BUS_GET_CLASS(obj) OBJECT_GET_CLASS(PCIBusClass, (obj), TYPE_PCI_BUS)
> +
> +typedef struct PCIBusClass {
> +    /*< private >*/
> +    BusClass parent_class;
> +    /*< public >*/
> +
> +    bool (*is_root)(PCIBus *bus);
> +} PCIBusClass;
>  
>  struct PCIBus {
>      BusState qbus;
> @@ -39,6 +49,11 @@ struct PCIBus {
>      int *irq_count;
>  };
>  
> +static inline bool pci_bus_is_root(PCIBus *bus)
> +{
> +    return PCI_BUS_GET_CLASS(bus)->is_root(bus);
> +}
> +
>  typedef struct PCIBridgeWindows PCIBridgeWindows;
>  
>  /*
> -- 
> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-27 11:35     ` Paolo Bonzini
@ 2015-04-27 11:49       ` Marcel Apfelbaum
  2015-04-27 12:24         ` Michael S. Tsirkin
  2015-04-28  7:31       ` Markus Armbruster
  1 sibling, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-27 11:49 UTC (permalink / raw)
  To: Paolo Bonzini, Michael S. Tsirkin
  Cc: quintela, qemu-devel, agraf, alex.williamson, kevin, kraxel,
	amit.shah, imammedo, rth, leon.alrae, aurelien, hare

On 04/27/2015 02:35 PM, Paolo Bonzini wrote:
>
> On 27/04/2015 13:14, Michael S. Tsirkin wrote:
>>> + *
>>>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>>>> + * See the COPYING file in the top-level directory.
>> The file you are moving this from is GPL only.
>
> It's BSD.
>
>> You will need to find who contributed this code you are moving
>> and get ack from them ...
>
> Simpler to keep BSD.
Sure, will do.

Thanks,
Marcel
>
> Paolo
>

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method
  2015-04-27 11:37   ` Michael S. Tsirkin
@ 2015-04-27 11:49     ` Marcel Apfelbaum
  0 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-27 11:49 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 02:37 PM, Michael S. Tsirkin wrote:
> On Thu, Mar 19, 2015 at 08:52:45PM +0200, Marcel Apfelbaum wrote:
>> From: Marcel Apfelbaum <marcel.a@redhat.com>
>>
>> Refactoring it as a method of PCIBusClass will allow
>> different implementations for subclasses.
>>
>> Removed the assumption that the root bus does not
>> have a parent device because is specific only
>> to the default class implementation.
>>
>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>
> Or just add bool is_root there?
> Won't that be simpler?
A field instead of a method? I am not sure it will be less code lines.

Thanks,
Marcel

>
>> ---
>>   hw/pci/pci.c             | 11 ++++-------
>>   hw/pci/pci_bus.c         |  9 +++++++++
>>   hw/vfio/pci.c            |  1 +
>>   include/hw/pci/pci.h     |  1 -
>>   include/hw/pci/pci_bus.h | 15 +++++++++++++++
>>   5 files changed, 29 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
>> index cb63a21..376b42d 100644
>> --- a/hw/pci/pci.c
>> +++ b/hw/pci/pci.c
>> @@ -205,7 +205,10 @@ PCIBus *pci_device_root_bus(const PCIDevice *d)
>>   {
>>       PCIBus *bus = d->bus;
>>
>> -    while ((d = bus->parent_dev) != NULL) {
>> +    while (!pci_bus_is_root(bus)) {
>> +        d = bus->parent_dev;
>> +        assert(d != NULL);
>> +
>>           bus = d->bus;
>>       }
>>
>> @@ -218,7 +221,6 @@ const char *pci_root_bus_path(PCIDevice *dev)
>>       PCIHostState *host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent);
>>       PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_GET_CLASS(host_bridge);
>>
>> -    assert(!rootbus->parent_dev);
>>       assert(host_bridge->bus == rootbus);
>>
>>       if (hc->root_bus_path) {
>> @@ -250,11 +252,6 @@ bool pci_bus_is_express(PCIBus *bus)
>>       return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
>>   }
>>
>> -bool pci_bus_is_root(PCIBus *bus)
>> -{
>> -    return !bus->parent_dev;
>> -}
>> -
>>   void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
>>                            const char *name,
>>                            MemoryRegion *address_space_mem,
>> diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
>> index d156194..0922a75 100644
>> --- a/hw/pci/pci_bus.c
>> +++ b/hw/pci/pci_bus.c
>> @@ -464,9 +464,15 @@ static void pcibus_reset(BusState *qbus)
>>       }
>>   }
>>
>> +static bool pcibus_is_root(PCIBus *bus)
>> +{
>> +    return !bus->parent_dev;
>> +}
>> +
>>   static void pci_bus_class_init(ObjectClass *klass, void *data)
>>   {
>>       BusClass *k = BUS_CLASS(klass);
>> +    PCIBusClass *pbc = PCI_BUS_CLASS(klass);
>>
>>       k->print_dev = pcibus_dev_print;
>>       k->get_dev_path = pcibus_get_dev_path;
>> @@ -474,11 +480,14 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
>>       k->realize = pci_bus_realize;
>>       k->unrealize = pci_bus_unrealize;
>>       k->reset = pcibus_reset;
>> +
>> +    pbc->is_root = pcibus_is_root;
>>   }
>>
>>   static const TypeInfo pci_bus_info = {
>>       .name = TYPE_PCI_BUS,
>>       .parent = TYPE_BUS,
>> +    .class_size = sizeof(PCIBusClass),
>>       .instance_size = sizeof(PCIBus),
>>       .class_init = pci_bus_class_init,
>>   };
>> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>> index 6b80539..7b08d03 100644
>> --- a/hw/vfio/pci.c
>> +++ b/hw/vfio/pci.c
>> @@ -32,6 +32,7 @@
>>   #include "hw/pci/msi.h"
>>   #include "hw/pci/msix.h"
>>   #include "hw/pci/pci.h"
>> +#include "hw/pci/pci_bus.h"
>>   #include "qemu-common.h"
>>   #include "qemu/error-report.h"
>>   #include "qemu/event_notifier.h"
>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>> index 47077cd..ae2c4a5 100644
>> --- a/include/hw/pci/pci.h
>> +++ b/include/hw/pci/pci.h
>> @@ -340,7 +340,6 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
>>   #define TYPE_PCIE_BUS "PCIE"
>>
>>   bool pci_bus_is_express(PCIBus *bus);
>> -bool pci_bus_is_root(PCIBus *bus);
>>   void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
>>                            const char *name,
>>                            MemoryRegion *address_space_mem,
>> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
>> index ea427a3..306ef10 100644
>> --- a/include/hw/pci/pci_bus.h
>> +++ b/include/hw/pci/pci_bus.h
>> @@ -15,6 +15,16 @@ PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
>>
>>   #define TYPE_PCI_BUS "PCI"
>>   #define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
>> +#define PCI_BUS_CLASS(klass) OBJECT_CLASS_CHECK(PCIBusClass, (klass), TYPE_PCI_BUS)
>> +#define PCI_BUS_GET_CLASS(obj) OBJECT_GET_CLASS(PCIBusClass, (obj), TYPE_PCI_BUS)
>> +
>> +typedef struct PCIBusClass {
>> +    /*< private >*/
>> +    BusClass parent_class;
>> +    /*< public >*/
>> +
>> +    bool (*is_root)(PCIBus *bus);
>> +} PCIBusClass;
>>
>>   struct PCIBus {
>>       BusState qbus;
>> @@ -39,6 +49,11 @@ struct PCIBus {
>>       int *irq_count;
>>   };
>>
>> +static inline bool pci_bus_is_root(PCIBus *bus)
>> +{
>> +    return PCI_BUS_GET_CLASS(bus)->is_root(bus);
>> +}
>> +
>>   typedef struct PCIBridgeWindows PCIBridgeWindows;
>>
>>   /*
>> --
>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS
  2015-04-27 11:19   ` Michael S. Tsirkin
@ 2015-04-27 11:51     ` Gerd Hoffmann
  0 siblings, 0 replies; 61+ messages in thread
From: Gerd Hoffmann @ 2015-04-27 11:51 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: quintela, qemu-devel, agraf, amit.shah, alex.williamson, kevin,
	hare, imammedo, Marcel Apfelbaum, pbonzini, leon.alrae, aurelien,
	rth

On Mo, 2015-04-27 at 13:19 +0200, Michael S. Tsirkin wrote:
> On Thu, Mar 19, 2015 at 08:53:00PM +0200, Marcel Apfelbaum wrote:
> > PXB does not work with unsupported bioses, but should
> > not interfere with normal OS operation.
> > We don't ship them anymore, but it's reasonable
> > to keep the work-around until we update the bios in qemu.
> 
> Can be dropped now we have updated the bios?

I'd much prefer to keep it for robustness reasons.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface Marcel Apfelbaum
@ 2015-04-27 12:14   ` Michael S. Tsirkin
  2015-04-27 13:01     ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 12:14 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
> TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
> whose configuration registers are snooped by other host bridges
> to complete their configuration cycles.
> 
> The interface exposes a list of snooping host bridges that
> shall be used by the hosts implementing this interface
> in order to emulate a snooping mechanism.
> 
> The way that the snooping hosts are registered or how
> the snooping is implemented are out of the interface scope,
> it only provides a way to determine if a host bridge has
> snooping hosts and list them.



> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> ---
>  hw/pci/pci_host.c         |  8 ++++++++
>  include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> index 87180c8..288e74c 100644
> --- a/hw/pci/pci_host.c
> +++ b/hw/pci/pci_host.c
> @@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
>      .parent        = TYPE_INTERFACE,
>  };
>  
> +static const TypeInfo pci_host_bridge_snooped_interface_info = {
> +    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
> +    .parent = TYPE_INTERFACE,
> +    .class_size = sizeof(PCIHostBridgeSnoopedClass),
> +};
> +
>  static const TypeInfo pci_host_type_info = {
>      .name = TYPE_PCI_HOST_BRIDGE,
>      .parent = TYPE_SYS_BUS_DEVICE,
> @@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
>  static void pci_host_register_types(void)
>  {
>      type_register_static(&pci_main_host_interface_info);
> +    type_register_static(&pci_host_bridge_snooped_interface_info);
>      type_register_static(&pci_host_type_info);
> +

extra empty line

>  }
>  
>  type_init(pci_host_register_types)
> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> index 3c72e26..a041919 100644
> --- a/include/hw/pci/pci_host.h
> +++ b/include/hw/pci/pci_host.h
> @@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
>      const char *(*root_bus_path)(PCIHostState *, PCIBus *);
>  } PCIHostBridgeClass;
>  
> +/**
> + * A special case of host bridge whose configuration registers
> + * are snooped by other host bridges to complete their
> + * configuration cycles.
> + */
> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
> +     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
> +                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
> +#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
> +     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
> +                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
> +#define PCI_HOST_BRIDGE_SNOOPED(obj) \
> +     INTERFACE_CHECK(PCIHostState, (obj), \
> +                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
> +
> +typedef struct PCIHostBridgeSnoopedClass {
> +    /* <private> */
> +    InterfaceClass parent_class;
> +
> +    /* <public> */
> +    GPtrArray *(*snooping_hosts)(PCIHostState *);

Why not just add GPtrArray here directly, and add an API to
register/deregister?

> +} PCIHostBridgeSnoopedClass;
> +
>  /* common internal helpers for PCI/PCIe hosts, cut off overflows */
>  void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
>                                    uint32_t limit, uint32_t val, uint32_t len);
> -- 
> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement " Marcel Apfelbaum
@ 2015-04-27 12:23   ` Michael S. Tsirkin
  0 siblings, 0 replies; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 12:23 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Thu, Mar 19, 2015 at 08:52:49PM +0200, Marcel Apfelbaum wrote:
> The PIIX holds a list of snooping host bridges that is populated
> by a registration function that shall be used by any host bridge
> that needs to use PIIX configuration space to complete their
> configuration cycles.
> 
> PIIX monitors acceses to configuration registers and passes them
> to the corresponding host bridge if the input bus number is
> in its bus range.
> 
> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> ---
>  hw/pci-host/piix.c        | 118 +++++++++++++++++++++++++++++++++++++++++++++-
>  hw/pci/pci_host.c         |  28 +++++++++++
>  include/hw/i386/pc.h      |   6 +++
>  include/hw/pci/pci_host.h |   3 ++
>  4 files changed, 154 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index 0033ab4..f512765 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -50,6 +50,12 @@ typedef struct I440FXState {
>      PcPciInfo pci_info;
>      uint64_t pci_hole64_size;
>      uint32_t short_root_bus;
> +
> +    /*
> +     * List of PCI host bridges listening to
> +     * the same configuration registers.
> +     */
> +    GPtrArray *snooping_hosts;
>  } I440FXState;
>  
>  #define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
> @@ -255,14 +261,80 @@ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
>      visit_type_uint64(v, &w64.end, name, errp);
>  }
>  
> +static PCIBus *i440fx_find_target_bus(I440FXState *i440fx, uint8_t bus_num)
> +{
> +    PCIHostState *host = PCI_HOST_BRIDGE(i440fx);
> +    PCIBus *target_bus = NULL;
> +
> +    if (bus_num == pci_bus_num(host->bus)) {
> +        target_bus = host->bus;
> +    } else {
> +        int i;
> +
> +        for (i = 0; i < i440fx->snooping_hosts->len; i++) {
> +            PCIHostState *s_host = g_ptr_array_index(i440fx->snooping_hosts, i);
> +            Range r = pci_host_get_buses_range(s_host);
> +
> +            if (r.begin <= bus_num && r.end >= bus_num) {
> +                target_bus = s_host->bus;
> +            }
> +


extra empty line

> +        }
> +    }
> +
> +    return target_bus;
> +}
> +
> +static void i440fx_pcihost_data_write(void *opaque, hwaddr addr,
> +                                      uint64_t val, unsigned len)
> +{
> +    uint32_t config_reg = PCI_HOST_BRIDGE(opaque)->config_reg;
> +
> +    if (config_reg & (1u << 31)) {
> +        uint8_t bus_num = (config_reg >> 16) & 0xFF;
> +        I440FXState *i440fx = I440FX_PCI_HOST_BRIDGE(opaque);
> +        PCIBus *target_bus = i440fx_find_target_bus(i440fx, bus_num);
> +
> +        if (target_bus) {
> +            pci_data_write(target_bus, config_reg | (addr & 3), val, len);
> +        }
> +    }
> +}
> +
> +static uint64_t i440fx_pcihost_data_read(void *opaque,
> +                                         hwaddr addr, unsigned len)
> +{
> +    uint32_t config_reg = PCI_HOST_BRIDGE(opaque)->config_reg;
> +
> +    if (config_reg & (1U << 31)) {
> +        int bus_num = (config_reg >> 16) & 0xFF;
> +        I440FXState *i440fx = I440FX_PCI_HOST_BRIDGE(opaque);
> +        PCIBus *target_bus = i440fx_find_target_bus(i440fx, bus_num);
> +
> +        if (target_bus) {
> +            return pci_data_read(target_bus, config_reg | (addr & 3), len);
> +        }
> +    }
> +
> +    return 0xffffffff;
> +}
> +
> +const MemoryRegionOps i440fx_pcihost_data_le_ops = {
> +    .read = i440fx_pcihost_data_read,
> +    .write = i440fx_pcihost_data_write,
> +    .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +

Can't you just add pxb as a child bus?
If you do, pci_find_bus_nr will do the right thing
more or less automatically, no?


>  static void i440fx_pcihost_initfn(Object *obj)
>  {
>      PCIHostState *s = PCI_HOST_BRIDGE(obj);
>      I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
>  
> +    d->snooping_hosts = g_ptr_array_new();
> +
>      memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
>                            "pci-conf-idx", 4);
> -    memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
> +    memory_region_init_io(&s->data_mem, obj, &i440fx_pcihost_data_le_ops, s,
>                            "pci-conf-data", 4);
>  
>      object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
> @@ -400,6 +472,40 @@ PCIBus *find_i440fx(void)
>      return s ? s->bus : NULL;
>  }
>  
> +/*
> + * Returns 0 on successs, -1 if i440fx host was not
> + * found or the bus number is already in use.
> + */
> +int i440fx_register_snooping_host(PCIHostState *host)
> +{
> +    I440FXState *s = OBJECT_CHECK(I440FXState,
> +                                  object_resolve_path("/machine/i440fx", NULL),
> +                                  TYPE_I440FX_PCI_HOST_BRIDGE);
> +    uint8_t bus_num = pci_bus_num(host->bus);
> +    int i;
> +
> +    /* i440fx host not found */
> +    if (!s) {
> +        return -1;
> +    }
> +
> +    /* 0 is reserved for i440fx host bridge */
> +    if (bus_num == 0) {
> +        return -1;
> +    }
> +
> +    /* check if the bus number is unique */
> +    for (i = 0; i < s->snooping_hosts->len; i++) {
> +        PCIHostState *s_host = g_ptr_array_index(s->snooping_hosts, i);
> +        if (bus_num == pci_bus_num(s_host->bus)) {
> +            return -1;
> +        }
> +    }
> +
> +    g_ptr_array_add(s->snooping_hosts, host);
> +    return 0;
> +}
> +
>  /* PIIX3 PCI to ISA bridge */
>  static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
>  {
> @@ -742,6 +848,13 @@ static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
>      return "0000:00";
>  }
>  
> +static GPtrArray *i440fx_snooping_hosts(PCIHostState *host_bridge)
> +{
> +    I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
> +
> +    return s->snooping_hosts;
> +}
> +
>  static Property i440fx_props[] = {
>      DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
>                       pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
> @@ -753,11 +866,13 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>      PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
> +    PCIHostBridgeSnoopedClass *sc = TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass);
>  
>      hc->root_bus_path = i440fx_pcihost_root_bus_path;
>      dc->realize = i440fx_pcihost_realize;
>      dc->fw_name = "pci";
>      dc->props = i440fx_props;
> +    sc->snooping_hosts = i440fx_snooping_hosts;
>  }
>  
>  static const TypeInfo i440fx_pcihost_info = {
> @@ -768,6 +883,7 @@ static const TypeInfo i440fx_pcihost_info = {
>      .class_init    = i440fx_pcihost_class_init,
>      .interfaces    = (InterfaceInfo[]) {
>          { TYPE_PCI_MAIN_HOST_BRIDGE },
> +        { TYPE_PCI_HOST_BRIDGE_SNOOPED },
>          { }
>      }
>  
> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> index 288e74c..35e462b 100644
> --- a/hw/pci/pci_host.c
> +++ b/hw/pci/pci_host.c
> @@ -20,6 +20,8 @@
>  
>  #include "hw/pci/pci.h"
>  #include "hw/pci/pci_host.h"
> +#include "hw/pci/pci_bus.h"
> +#include "qemu/range.h"
>  #include "trace.h"
>  
>  /* debug PCI */
> @@ -32,6 +34,32 @@ do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0)
>  #define PCI_DPRINTF(fmt, ...)
>  #endif
>  
> +Range pci_host_get_buses_range(PCIHostState *host)

new api, needs documentation.


> +{
> +    uint8_t root_bus_num = pci_bus_num(host->bus);
> +    Range r = {root_bus_num, root_bus_num};
> +    int i;
> +
> +    for (i = 0; i < ARRAY_SIZE(host->bus->devices); ++i) {
> +        PCIDevice *dev = host->bus->devices[i];
> +        PCIDeviceClass *pc;
> +
> +        if (!dev) {
> +            continue;
> +        }
> +
> +        pc = PCI_DEVICE_GET_CLASS(dev);
> +
> +        if (pc->is_bridge) {
> +            uint8_t subordinate = dev->config[PCI_SUBORDINATE_BUS];
> +            if (subordinate > r.end) {
> +                r.end = subordinate;
> +            }
> +        }
> +    }
> +
> +    return r;
> +}
>  /*
>   * PCI address
>   * bit 16 - 24: bus number
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 1b35168..a918a61 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -241,6 +241,12 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
>                      MemoryRegion *ram_memory);
>  
>  PCIBus *find_i440fx(void);
> +/*
> + * Register hosts without their own configuration registers
> + * to i440fx main PCI host bridge
> + */
> +int i440fx_register_snooping_host(PCIHostState *host);
> +
>  /* piix4.c */
>  extern PCIDevice *piix4_dev;
>  int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn);
> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> index a041919..dc7ccb2 100644
> --- a/include/hw/pci/pci_host.h
> +++ b/include/hw/pci/pci_host.h
> @@ -87,6 +87,9 @@ typedef struct PCIHostBridgeSnoopedClass {
>      GPtrArray *(*snooping_hosts)(PCIHostState *);
>  } PCIHostBridgeSnoopedClass;
>  
> +/* Returns the buses interval owned by the input host */
> +Range pci_host_get_buses_range(PCIHostState *host);
> +
>  /* common internal helpers for PCI/PCIe hosts, cut off overflows */
>  void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
>                                    uint32_t limit, uint32_t val, uint32_t len);
> -- 
> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-27 11:49       ` Marcel Apfelbaum
@ 2015-04-27 12:24         ` Michael S. Tsirkin
  0 siblings, 0 replies; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 12:24 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: quintela, qemu-devel, agraf, alex.williamson, kevin, kraxel,
	imammedo, amit.shah, Paolo Bonzini, rth, leon.alrae, aurelien,
	hare

On Mon, Apr 27, 2015 at 02:49:16PM +0300, Marcel Apfelbaum wrote:
> On 04/27/2015 02:35 PM, Paolo Bonzini wrote:
> >
> >On 27/04/2015 13:14, Michael S. Tsirkin wrote:
> >>>+ *
> >>>>+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
> >>>>+ * See the COPYING file in the top-level directory.
> >>The file you are moving this from is GPL only.
> >
> >It's BSD.
> >
> >>You will need to find who contributed this code you are moving
> >>and get ack from them ...
> >
> >Simpler to keep BSD.
> Sure, will do.
> 
> Thanks,
> Marcel

I'd say just keep it within pci.c for now, the smaller the patchset the
better. Refactor later.

> >
> >Paolo
> >

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-27 11:14   ` Michael S. Tsirkin
  2015-04-27 11:35     ` Paolo Bonzini
@ 2015-04-27 12:26     ` Marcel Apfelbaum
  2015-04-28  8:30       ` Michael S. Tsirkin
  1 sibling, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-27 12:26 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 02:14 PM, Michael S. Tsirkin wrote:
> On Thu, Mar 19, 2015 at 08:52:44PM +0200, Marcel Apfelbaum wrote:
>> @@ -2414,7 +1945,6 @@ static const TypeInfo pci_device_type_info = {
>>
>>   static void pci_register_types(void)
>>   {
>> -    type_register_static(&pci_bus_info);
>>       type_register_static(&pcie_bus_info);
>>       type_register_static(&pci_device_type_info);
>>   }
>
> So pcie bus is not moved.  This seems pretty inconsistent.
There were a lot of code dependencies. I moved the minimum code in order
to be able to add code specific to PCIBus.

>
>
>> diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c
>> new file mode 100644
>> index 0000000..d156194
>> --- /dev/null
>> +++ b/hw/pci/pci_bus.c
>> @@ -0,0 +1,491 @@
>> +/*
>> + * PCI Bus
>> + *
>> + * Copyright (C) 2014 Red Hat Inc
>
> It's 2015 isn't it?
Well, now yes :)

>
>> + *
>> + * Authors:
>> + *   Marcel Apfelbaum <marcel.a@redhat.com> (split out from pci.c)
>
> You don't become the only Author just by moving code around.
> Better drop this line.
I was following an example of the latest code movement at that time in QEMU.
Anyway, I will remove that line.

>
>
>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>
> The file you are moving this from is GPL only.
> You will need to find who contributed this code you are moving
> and get ack from them ...
I'll keep it as BSD as Paolo suggested.


>
>> + */
>> +#include "hw/pci/pci.h"
>> +#include "hw/pci/pci_bus.h"
>> +#include "hw/pci/pci_bridge.h"
>> +#include "monitor/monitor.h"
>> +
>> +typedef struct {
>> +    uint16_t class;
>> +    const char *desc;
>> +    const char *fw_name;
>> +    uint16_t fw_ign_bits;
>> +} pci_class_desc;
>> +
>> +static const pci_class_desc pci_class_descriptions[] = {
>> +    { 0x0001, "VGA controller", "display"},
>> +    { 0x0100, "SCSI controller", "scsi"},
>> +    { 0x0101, "IDE controller", "ide"},
>> +    { 0x0102, "Floppy controller", "fdc"},
>> +    { 0x0103, "IPI controller", "ipi"},
>> +    { 0x0104, "RAID controller", "raid"},
>> +    { 0x0106, "SATA controller"},
>> +    { 0x0107, "SAS controller"},
>> +    { 0x0180, "Storage controller"},
>> +    { 0x0200, "Ethernet controller", "ethernet"},
>> +    { 0x0201, "Token Ring controller", "token-ring"},
>> +    { 0x0202, "FDDI controller", "fddi"},
>> +    { 0x0203, "ATM controller", "atm"},
>> +    { 0x0280, "Network controller"},
>> +    { 0x0300, "VGA controller", "display", 0x00ff},
>> +    { 0x0301, "XGA controller"},
>> +    { 0x0302, "3D controller"},
>> +    { 0x0380, "Display controller"},
>> +    { 0x0400, "Video controller", "video"},
>> +    { 0x0401, "Audio controller", "sound"},
>> +    { 0x0402, "Phone"},
>> +    { 0x0403, "Audio controller", "sound"},
>> +    { 0x0480, "Multimedia controller"},
>> +    { 0x0500, "RAM controller", "memory"},
>> +    { 0x0501, "Flash controller", "flash"},
>> +    { 0x0580, "Memory controller"},
>> +    { 0x0600, "Host bridge", "host"},
>> +    { 0x0601, "ISA bridge", "isa"},
>> +    { 0x0602, "EISA bridge", "eisa"},
>> +    { 0x0603, "MC bridge", "mca"},
>> +    { 0x0604, "PCI bridge", "pci-bridge"},
>> +    { 0x0605, "PCMCIA bridge", "pcmcia"},
>> +    { 0x0606, "NUBUS bridge", "nubus"},
>> +    { 0x0607, "CARDBUS bridge", "cardbus"},
>> +    { 0x0608, "RACEWAY bridge"},
>> +    { 0x0680, "Bridge"},
>> +    { 0x0700, "Serial port", "serial"},
>> +    { 0x0701, "Parallel port", "parallel"},
>> +    { 0x0800, "Interrupt controller", "interrupt-controller"},
>> +    { 0x0801, "DMA controller", "dma-controller"},
>> +    { 0x0802, "Timer", "timer"},
>> +    { 0x0803, "RTC", "rtc"},
>> +    { 0x0900, "Keyboard", "keyboard"},
>> +    { 0x0901, "Pen", "pen"},
>> +    { 0x0902, "Mouse", "mouse"},
>> +    { 0x0A00, "Dock station", "dock", 0x00ff},
>> +    { 0x0B00, "i386 cpu", "cpu", 0x00ff},
>> +    { 0x0c00, "Fireware contorller", "fireware"},
>> +    { 0x0c01, "Access bus controller", "access-bus"},
>> +    { 0x0c02, "SSA controller", "ssa"},
>> +    { 0x0c03, "USB controller", "usb"},
>> +    { 0x0c04, "Fibre channel controller", "fibre-channel"},
>> +    { 0x0c05, "SMBus"},
>> +    { 0, NULL}
>> +};
>> +
>> +/* Whether a given bus number is in range of the secondary
>> + * bus of the given bridge device. */
>> +static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num)
>> +{
>> +    return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) &
>> +             PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ &&
>> +        dev->config[PCI_SECONDARY_BUS] < bus_num &&
>> +        bus_num <= dev->config[PCI_SUBORDINATE_BUS];
>> +}
>> +
>> +PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num)
>> +{
>> +    PCIBus *sec;
>> +
>> +    if (!bus) {
>> +        return NULL;
>> +    }
>> +
>> +    if (pci_bus_num(bus) == bus_num) {
>> +        return bus;
>> +    }
>> +
>> +    /* Consider all bus numbers in range for the host pci bridge. */
>> +    if (!pci_bus_is_root(bus) &&
>> +        !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) {
>> +        return NULL;
>> +    }
>> +
>> +    /* try child bus */
>> +    for (; bus; bus = sec) {
>> +        QLIST_FOREACH(sec, &bus->child, sibling) {
>> +            assert(!pci_bus_is_root(sec));
>> +            if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) {
>> +                return sec;
>> +            }
>> +            if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) {
>> +                break;
>> +            }
>> +        }
>> +    }
>> +
>> +    return NULL;
>> +}
>> +
>> +static const pci_class_desc *get_class_desc(int class)
>> +{
>> +    const pci_class_desc *desc;
>> +
>> +    desc = pci_class_descriptions;
>> +    while (desc->desc && class != desc->class) {
>> +        desc++;
>> +    }
>> +
>> +    return desc;
>> +}
>> +
>> +static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
>> +{
>> +    PciMemoryRegionList *head = NULL, *cur_item = NULL;
>> +    int i;
>> +
>> +    for (i = 0; i < PCI_NUM_REGIONS; i++) {
>> +        const PCIIORegion *r = &dev->io_regions[i];
>> +        PciMemoryRegionList *region;
>> +
>> +        if (!r->size) {
>> +            continue;
>> +        }
>> +
>> +        region = g_malloc0(sizeof(*region));
>> +        region->value = g_malloc0(sizeof(*region->value));
>> +
>> +        if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
>> +            region->value->type = g_strdup("io");
>> +        } else {
>> +            region->value->type = g_strdup("memory");
>> +            region->value->has_prefetch = true;
>> +            region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
>> +            region->value->has_mem_type_64 = true;
>> +            region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
>> +        }
>> +
>> +        region->value->bar = i;
>> +        region->value->address = r->addr;
>> +        region->value->size = r->size;
>> +
>> +        /* XXX: waiting for the qapi to support GSList */
>> +        if (!cur_item) {
>> +            head = cur_item = region;
>> +        } else {
>> +            cur_item->next = region;
>> +            cur_item = region;
>> +        }
>> +    }
>> +
>> +    return head;
>> +}
>> +
>> +static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
>> +                                           int bus_num)
>> +{
>> +    PciBridgeInfo *info;
>> +
>> +    info = g_malloc0(sizeof(*info));
>> +
>> +    info->bus.number = dev->config[PCI_PRIMARY_BUS];
>> +    info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
>> +    info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
>> +
>> +    info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
>> +    info->bus.io_range->base = pci_bridge_get_base(dev,
>> +                    PCI_BASE_ADDRESS_SPACE_IO);
>> +    info->bus.io_range->limit =
>> +                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
>> +
>> +    info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
>> +    info->bus.memory_range->base =
>> +                    pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
>> +    info->bus.memory_range->limit =
>> +                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
>> +
>> +    info->bus.prefetchable_range =
>> +                    g_malloc0(sizeof(*info->bus.prefetchable_range));
>> +    info->bus.prefetchable_range->base =
>> +                    pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
>> +    info->bus.prefetchable_range->limit =
>> +                    pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
>> +
>> +    if (dev->config[PCI_SECONDARY_BUS] != 0) {
>> +        PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]);
>> +        if (child_bus) {
>> +            info->has_devices = true;
>> +            info->devices = qmp_query_pci_devices(child_bus,
>> +                                                  dev->config[PCI_SECONDARY_BUS]);
>> +        }
>> +    }
>> +
>> +    return info;
>> +}
>> +
>> +static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
>> +                                           int bus_num)
>> +{
>> +    const pci_class_desc *desc;
>> +    PciDeviceInfo *info;
>> +    uint8_t type;
>> +    int class;
>> +
>> +    info = g_malloc0(sizeof(*info));
>> +    info->bus = bus_num;
>> +    info->slot = PCI_SLOT(dev->devfn);
>> +    info->function = PCI_FUNC(dev->devfn);
>> +
>> +    class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
>> +    info->class_info.q_class = class;
>> +    desc = get_class_desc(class);
>> +    if (desc->desc) {
>> +        info->class_info.has_desc = true;
>> +        info->class_info.desc = g_strdup(desc->desc);
>> +    }
>> +
>> +    info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
>> +    info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
>> +    info->regions = qmp_query_pci_regions(dev);
>> +    info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
>> +
>> +    if (dev->config[PCI_INTERRUPT_PIN] != 0) {
>> +        info->has_irq = true;
>> +        info->irq = dev->config[PCI_INTERRUPT_LINE];
>> +    }
>> +
>> +    type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
>> +    if (type == PCI_HEADER_TYPE_BRIDGE) {
>> +        info->has_pci_bridge = true;
>> +        info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
>> +    }
>> +
>> +    return info;
>> +}
>> +
>> +PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
>> +{
>> +    PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
>> +    PCIDevice *dev;
>> +    int devfn;
>> +
>> +    for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
>> +        dev = bus->devices[devfn];
>> +        if (dev) {
>> +            info = g_malloc0(sizeof(*info));
>> +            info->value = qmp_query_pci_device(dev, bus, bus_num);
>> +
>> +            /* XXX: waiting for the qapi to support GSList */
>> +            if (!cur_item) {
>> +                head = cur_item = info;
>> +            } else {
>> +                cur_item->next = info;
>> +                cur_item = info;
>> +            }
>> +        }
>> +    }
>> +
>> +    return head;
>> +}
>> +
>> +
>> +static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
>> +{
>> +    PCIDevice *d = (PCIDevice *)dev;
>> +    const pci_class_desc *desc;
>> +    char ctxt[64];
>> +    PCIIORegion *r;
>> +    int i, class;
>> +
>> +    class = pci_get_word(d->config + PCI_CLASS_DEVICE);
>> +    desc = pci_class_descriptions;
>> +    while (desc->desc && class != desc->class) {
>> +        desc++;
>> +    }
>> +    if (desc->desc) {
>> +        snprintf(ctxt, sizeof(ctxt), "%s", desc->desc);
>> +    } else {
>> +        snprintf(ctxt, sizeof(ctxt), "Class %04x", class);
>> +    }
>> +
>> +    monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
>> +                   "pci id %04x:%04x (sub %04x:%04x)\n",
>> +                   indent, "", ctxt, pci_bus_num(d->bus),
>> +                   PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
>> +                   pci_get_word(d->config + PCI_VENDOR_ID),
>> +                   pci_get_word(d->config + PCI_DEVICE_ID),
>> +                   pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID),
>> +                   pci_get_word(d->config + PCI_SUBSYSTEM_ID));
>> +    for (i = 0; i < PCI_NUM_REGIONS; i++) {
>> +        r = &d->io_regions[i];
>> +        if (!r->size) {
>> +            continue;
>> +        }
>> +        monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS
>> +                       " [0x%"FMT_PCIBUS"]\n",
>> +                       indent, "",
>> +                       i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem",
>> +                       r->addr, r->addr + r->size - 1);
>> +    }
>> +}
>> +
>> +static char *pcibus_get_dev_path(DeviceState *dev)
>> +{
>> +    PCIDevice *d = container_of(dev, PCIDevice, qdev);
>> +    PCIDevice *t;
>> +    int slot_depth;
>> +    /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
>> +     * 00 is added here to make this format compatible with
>> +     * domain:Bus:Slot.Func for systems without nested PCI bridges.
>> +     * Slot.Function list specifies the slot and function numbers for all
>> +     * devices on the path from root to the specific device. */
>> +    const char *root_bus_path;
>> +    int root_bus_len;
>> +    char slot[] = ":SS.F";
>> +    int slot_len = sizeof slot - 1 /* For '\0' */;
>> +    int path_len;
>> +    char *path, *p;
>> +    int s;
>> +
>> +    root_bus_path = pci_root_bus_path(d);
>> +    root_bus_len = strlen(root_bus_path);
>> +
>> +    /* Calculate # of slots on path between device and root. */;
>> +    slot_depth = 0;
>> +    for (t = d; t; t = t->bus->parent_dev) {
>> +        ++slot_depth;
>> +    }
>> +
>> +    path_len = root_bus_len + slot_len * slot_depth;
>> +
>> +    /* Allocate memory, fill in the terminating null byte. */
>> +    path = g_malloc(path_len + 1 /* For '\0' */);
>> +    path[path_len] = '\0';
>> +
>> +    memcpy(path, root_bus_path, root_bus_len);
>> +
>> +    /* Fill in slot numbers. We walk up from device to root, so need to print
>> +     * them in the reverse order, last to first. */
>> +    p = path + path_len;
>> +    for (t = d; t; t = t->bus->parent_dev) {
>> +        p -= slot_len;
>> +        s = snprintf(slot, sizeof slot, ":%02x.%x",
>> +                     PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
>> +        assert(s == slot_len);
>> +        memcpy(p, slot, slot_len);
>> +    }
>> +
>> +    return path;
>> +}
>> +
>> +static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len)
>> +{
>> +    PCIDevice *d = (PCIDevice *)dev;
>> +    const char *name = NULL;
>> +    const pci_class_desc *desc =  pci_class_descriptions;
>> +    int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
>> +
>> +    while (desc->desc &&
>> +          (class & ~desc->fw_ign_bits) !=
>> +          (desc->class & ~desc->fw_ign_bits)) {
>> +        desc++;
>> +    }
>> +
>> +    if (desc->desc) {
>> +        name = desc->fw_name;
>> +    }
>> +
>> +    if (name) {
>> +        pstrcpy(buf, len, name);
>> +    } else {
>> +        snprintf(buf, len, "pci%04x,%04x",
>> +                 pci_get_word(d->config + PCI_VENDOR_ID),
>> +                 pci_get_word(d->config + PCI_DEVICE_ID));
>> +    }
>> +
>> +    return buf;
>> +}
>> +
>> +static char *pcibus_get_fw_dev_path(DeviceState *dev)
>> +{
>> +    PCIDevice *d = (PCIDevice *)dev;
>> +    char path[50], name[33];
>> +    int off;
>> +
>> +    off = snprintf(path, sizeof(path), "%s@%x",
>> +                   pci_dev_fw_name(dev, name, sizeof name),
>> +                   PCI_SLOT(d->devfn));
>> +    if (PCI_FUNC(d->devfn)) {
>> +        snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn));
>> +    }
>> +    return g_strdup(path);
>> +}
>> +
>> +static const VMStateDescription vmstate_pcibus = {
>> +    .name = "PCIBUS",
>> +    .version_id = 1,
>> +    .minimum_version_id = 1,
>> +    .fields = (VMStateField[]) {
>> +        VMSTATE_INT32_EQUAL(nirq, PCIBus),
>> +        VMSTATE_VARRAY_INT32(irq_count, PCIBus,
>> +                             nirq, 0, vmstate_info_int32,
>> +                             int32_t),
>> +        VMSTATE_END_OF_LIST()
>> +    }
>> +};
>> +
>> +static void pci_bus_realize(BusState *qbus, Error **errp)
>> +{
>> +    PCIBus *bus = PCI_BUS(qbus);
>> +
>> +    vmstate_register(NULL, -1, &vmstate_pcibus, bus);
>> +}
>> +
>> +static void pci_bus_unrealize(BusState *qbus, Error **errp)
>> +{
>> +    PCIBus *bus = PCI_BUS(qbus);
>> +
>> +    vmstate_unregister(NULL, &vmstate_pcibus, bus);
>> +}
>> +
>> +/*
>> + * Trigger pci bus reset under a given bus.
>> + * Called via qbus_reset_all on RST# assert, after the devices
>> + * have been reset qdev_reset_all-ed already.
>> + */
>> +static void pcibus_reset(BusState *qbus)
>> +{
>> +    PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
>> +    int i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
>> +        if (bus->devices[i]) {
>> +            pci_do_device_reset(bus->devices[i]);
>> +        }
>> +    }
>> +
>> +    for (i = 0; i < bus->nirq; i++) {
>> +        assert(bus->irq_count[i] == 0);
>> +    }
>> +}
>> +
>> +static void pci_bus_class_init(ObjectClass *klass, void *data)
>> +{
>> +    BusClass *k = BUS_CLASS(klass);
>> +
>> +    k->print_dev = pcibus_dev_print;
>> +    k->get_dev_path = pcibus_get_dev_path;
>> +    k->get_fw_dev_path = pcibus_get_fw_dev_path;
>> +    k->realize = pci_bus_realize;
>> +    k->unrealize = pci_bus_unrealize;
>> +    k->reset = pcibus_reset;
>> +}
>> +
>> +static const TypeInfo pci_bus_info = {
>> +    .name = TYPE_PCI_BUS,
>> +    .parent = TYPE_BUS,
>> +    .instance_size = sizeof(PCIBus),
>> +    .class_init = pci_bus_class_init,
>> +};
>> +
>> +static void pci_bus_register_types(void)
>> +{
>> +    type_register_static(&pci_bus_info);
>> +}
>> +
>> +type_init(pci_bus_register_types)
>> diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
>> index 0bb3cdb..f5847bc 100644
>> --- a/hw/ppc/ppc4xx_pci.c
>> +++ b/hw/ppc/ppc4xx_pci.c
>> @@ -23,6 +23,7 @@
>>   #include "hw/ppc/ppc.h"
>>   #include "hw/ppc/ppc4xx.h"
>>   #include "hw/pci/pci.h"
>> +#include "hw/pci/pci_bus.h"
>>   #include "hw/pci/pci_host.h"
>>   #include "exec/address-spaces.h"
>>
>> diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
>> index d1d0847..8dd2ce3 100644
>> --- a/hw/sh4/r2d.c
>> +++ b/hw/sh4/r2d.c
>> @@ -30,6 +30,7 @@
>>   #include "sysemu/sysemu.h"
>>   #include "hw/boards.h"
>>   #include "hw/pci/pci.h"
>> +#include "hw/pci/pci_bus.h"
>>   #include "net/net.h"
>>   #include "sh7750_regs.h"
>>   #include "hw/ide.h"
>> diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
>> index a2f6d9e..f02e998 100644
>> --- a/hw/sh4/sh_pci.c
>> +++ b/hw/sh4/sh_pci.c
>> @@ -24,6 +24,7 @@
>>   #include "hw/sysbus.h"
>>   #include "hw/sh4/sh.h"
>>   #include "hw/pci/pci.h"
>> +#include "hw/pci/pci_bus.h"
>>   #include "hw/pci/pci_host.h"
>>   #include "qemu/bswap.h"
>>   #include "exec/address-spaces.h"
>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
>> index be2d9b8..47077cd 100644
>> --- a/include/hw/pci/pci.h
>> +++ b/include/hw/pci/pci.h
>> @@ -337,8 +337,6 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
>>   typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
>>   typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
>>
>> -#define TYPE_PCI_BUS "PCI"
>> -#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
>>   #define TYPE_PCIE_BUS "PCIE"
>>
>>   bool pci_bus_is_express(PCIBus *bus);
>> @@ -370,6 +368,7 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
>>   void pci_device_set_intx_routing_notifier(PCIDevice *dev,
>>                                             PCIINTxRoutingNotifier notifier);
>>   void pci_device_reset(PCIDevice *dev);
>> +void pci_do_device_reset(PCIDevice *dev);
>
> I don't like it that there are two reset functions now.
It always was like that. We need this because of the code movement.

>
>>
>>   PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
>>                                  const char *default_model,
>> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
>> index fabaeee..ea427a3 100644
>> --- a/include/hw/pci/pci_bus.h
>> +++ b/include/hw/pci/pci_bus.h
>> @@ -1,6 +1,8 @@
>>   #ifndef QEMU_PCI_BUS_H
>>   #define QEMU_PCI_BUS_H
>>
>> +#include "hw/pci/pci.h"
>> +
>>   /*
>>    * PCI Bus and Bridge datastructures.
>>    *
>> @@ -8,6 +10,12 @@
>>    * use accessor functions in pci.h, pci_bridge.h
>>    */
>>
>> +PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
>> +PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
>> +
>> +#define TYPE_PCI_BUS "PCI"
>> +#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
>> +
>>   struct PCIBus {
>>       BusState qbus;
>>       PCIIOMMUFunc iommu_fn;
>
>
> Can we drop this patch, do refactoring on top later?
There are several patches on this series depending on this.
Of course I can manually apply them, does it worth it?

Thanks,
Marcel

>
>> --
>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-04-27 11:24   ` Michael S. Tsirkin
@ 2015-04-27 12:30     ` Marcel Apfelbaum
  2015-04-27 12:48       ` Michael S. Tsirkin
  0 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-27 12:30 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 02:24 PM, Michael S. Tsirkin wrote:
> On Thu, Mar 19, 2015 at 08:52:47PM +0200, Marcel Apfelbaum wrote:
>> From: Marcel Apfelbaum <marcel.a@redhat.com>
>>
>> This is a marker interface used to differentiate the
>> "default" host bridge on a system with multiple host bridges.
>> This differentiation is required only for pc machines for now
>> by the ACPI subsystem.
>>
>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>
> Fixing hotplug for pxb almost for sure means we'll need
> to drop this later.
Not really, I am not sure how it is related. I'll go over the pxb pci devices
for this hotplug. I have no intention to drop this later.
This interface denotes the main/default/bus 0 host bridge.


  How about an interface to
> iterate over objects by type?
> You can then blacklist pxbs for now.
Less elegant in my opinion,
>
>> ---
>>   hw/i386/acpi-build.c      | 9 ++++++---
>>   hw/pci-host/piix.c        | 5 +++++
>>   hw/pci-host/q35.c         | 4 ++++
>>   hw/pci/pci_host.c         | 6 ++++++
>>   include/hw/pci/pci_host.h | 7 +++++++
>>   5 files changed, 28 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index d0a5c85..86e474a 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
>>       Object *pci_host;
>>       bool ambiguous;
>>
>> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>> +                                        &ambiguous);
>>       g_assert(!ambiguous);
>>       g_assert(pci_host);
>>
>> @@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
>>               PCIBus *bus = NULL;
>>               bool ambiguous;
>>
>> -            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>> +            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>> +                                                &ambiguous);
>>               if (!ambiguous && pci_host) {
>>                   bus = PCI_HOST_BRIDGE(pci_host)->bus;
>>               }
>> @@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>>       QObject *o;
>>       bool ambiguous;
>>
>> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>> +                                        &ambiguous);
>>       g_assert(!ambiguous);
>>       g_assert(pci_host);
>>
>> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
>> index 292b6e9..0033ab4 100644
>> --- a/hw/pci-host/piix.c
>> +++ b/hw/pci-host/piix.c
>> @@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
>>       .instance_size = sizeof(I440FXState),
>>       .instance_init = i440fx_pcihost_initfn,
>>       .class_init    = i440fx_pcihost_class_init,
>> +    .interfaces    = (InterfaceInfo[]) {
>> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
>> +        { }
>> +    }
>> +
>>   };
>>
>>   static void i440fx_register_types(void)
>> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
>> index 5dd559e..e35b3a2 100644
>> --- a/hw/pci-host/q35.c
>> +++ b/hw/pci-host/q35.c
>> @@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
>>       .instance_size = sizeof(Q35PCIHost),
>>       .instance_init = q35_host_initfn,
>>       .class_init = q35_host_class_init,
>> +    .interfaces = (InterfaceInfo[]) {
>> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
>> +        { }
>> +    }
>>   };
>>
>>   /****************************************************************************
>> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>> index 3e26f92..87180c8 100644
>> --- a/hw/pci/pci_host.c
>> +++ b/hw/pci/pci_host.c
>> @@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
>>       .endianness = DEVICE_BIG_ENDIAN,
>>   };
>>
>> +static const TypeInfo pci_main_host_interface_info = {
>> +    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
>> +    .parent        = TYPE_INTERFACE,
>> +};
>> +
>>   static const TypeInfo pci_host_type_info = {
>>       .name = TYPE_PCI_HOST_BRIDGE,
>>       .parent = TYPE_SYS_BUS_DEVICE,
>> @@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
>>
>>   static void pci_host_register_types(void)
>>   {
>> +    type_register_static(&pci_main_host_interface_info);
>>       type_register_static(&pci_host_type_info);
>>   }
>>
>> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
>> index ba31595..3c72e26 100644
>> --- a/include/hw/pci/pci_host.h
>> +++ b/include/hw/pci/pci_host.h
>> @@ -30,6 +30,13 @@
>>
>>   #include "hw/sysbus.h"
>>
>> +/**
>> + * Marker interface for classes whose instances can
>> + * be main host bridges. It is intended to be used
>> + * when the QOM tree includes multiple host bridges.
>> + */
>> +#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
>> +
>>   #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
>>   #define PCI_HOST_BRIDGE(obj) \
>>       OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
>> --
>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-04-27 12:30     ` Marcel Apfelbaum
@ 2015-04-27 12:48       ` Michael S. Tsirkin
  2015-04-27 13:04         ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 12:48 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Mon, Apr 27, 2015 at 03:30:01PM +0300, Marcel Apfelbaum wrote:
> On 04/27/2015 02:24 PM, Michael S. Tsirkin wrote:
> >On Thu, Mar 19, 2015 at 08:52:47PM +0200, Marcel Apfelbaum wrote:
> >>From: Marcel Apfelbaum <marcel.a@redhat.com>
> >>
> >>This is a marker interface used to differentiate the
> >>"default" host bridge on a system with multiple host bridges.
> >>This differentiation is required only for pc machines for now
> >>by the ACPI subsystem.
> >>
> >>Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> >
> >Fixing hotplug for pxb almost for sure means we'll need
> >to drop this later.
> Not really, I am not sure how it is related. I'll go over the pxb pci devices
> for this hotplug. I have no intention to drop this later.
> This interface denotes the main/default/bus 0 host bridge.

It's related since you will want to describe all host bridges in acpi.

> 
>  How about an interface to
> >iterate over objects by type?
> >You can then blacklist pxbs for now.
> Less elegant in my opinion,

Right but it will be needed in the future anyway.

> >
> >>---
> >>  hw/i386/acpi-build.c      | 9 ++++++---
> >>  hw/pci-host/piix.c        | 5 +++++
> >>  hw/pci-host/q35.c         | 4 ++++
> >>  hw/pci/pci_host.c         | 6 ++++++
> >>  include/hw/pci/pci_host.h | 7 +++++++
> >>  5 files changed, 28 insertions(+), 3 deletions(-)
> >>
> >>diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> >>index d0a5c85..86e474a 100644
> >>--- a/hw/i386/acpi-build.c
> >>+++ b/hw/i386/acpi-build.c
> >>@@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
> >>      Object *pci_host;
> >>      bool ambiguous;
> >>
> >>-    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> >>+    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> >>+                                        &ambiguous);
> >>      g_assert(!ambiguous);
> >>      g_assert(pci_host);
> >>
> >>@@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
> >>              PCIBus *bus = NULL;
> >>              bool ambiguous;
> >>
> >>-            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> >>+            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> >>+                                                &ambiguous);
> >>              if (!ambiguous && pci_host) {
> >>                  bus = PCI_HOST_BRIDGE(pci_host)->bus;
> >>              }
> >>@@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
> >>      QObject *o;
> >>      bool ambiguous;
> >>
> >>-    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> >>+    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> >>+                                        &ambiguous);
> >>      g_assert(!ambiguous);
> >>      g_assert(pci_host);
> >>
> >>diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> >>index 292b6e9..0033ab4 100644
> >>--- a/hw/pci-host/piix.c
> >>+++ b/hw/pci-host/piix.c
> >>@@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
> >>      .instance_size = sizeof(I440FXState),
> >>      .instance_init = i440fx_pcihost_initfn,
> >>      .class_init    = i440fx_pcihost_class_init,
> >>+    .interfaces    = (InterfaceInfo[]) {
> >>+        { TYPE_PCI_MAIN_HOST_BRIDGE },
> >>+        { }
> >>+    }
> >>+
> >>  };
> >>
> >>  static void i440fx_register_types(void)
> >>diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> >>index 5dd559e..e35b3a2 100644
> >>--- a/hw/pci-host/q35.c
> >>+++ b/hw/pci-host/q35.c
> >>@@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
> >>      .instance_size = sizeof(Q35PCIHost),
> >>      .instance_init = q35_host_initfn,
> >>      .class_init = q35_host_class_init,
> >>+    .interfaces = (InterfaceInfo[]) {
> >>+        { TYPE_PCI_MAIN_HOST_BRIDGE },
> >>+        { }
> >>+    }
> >>  };
> >>
> >>  /****************************************************************************
> >>diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> >>index 3e26f92..87180c8 100644
> >>--- a/hw/pci/pci_host.c
> >>+++ b/hw/pci/pci_host.c
> >>@@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
> >>      .endianness = DEVICE_BIG_ENDIAN,
> >>  };
> >>
> >>+static const TypeInfo pci_main_host_interface_info = {
> >>+    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
> >>+    .parent        = TYPE_INTERFACE,
> >>+};
> >>+
> >>  static const TypeInfo pci_host_type_info = {
> >>      .name = TYPE_PCI_HOST_BRIDGE,
> >>      .parent = TYPE_SYS_BUS_DEVICE,
> >>@@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
> >>
> >>  static void pci_host_register_types(void)
> >>  {
> >>+    type_register_static(&pci_main_host_interface_info);
> >>      type_register_static(&pci_host_type_info);
> >>  }
> >>
> >>diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> >>index ba31595..3c72e26 100644
> >>--- a/include/hw/pci/pci_host.h
> >>+++ b/include/hw/pci/pci_host.h
> >>@@ -30,6 +30,13 @@
> >>
> >>  #include "hw/sysbus.h"
> >>
> >>+/**
> >>+ * Marker interface for classes whose instances can
> >>+ * be main host bridges. It is intended to be used
> >>+ * when the QOM tree includes multiple host bridges.
> >>+ */
> >>+#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
> >>+
> >>  #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
> >>  #define PCI_HOST_BRIDGE(obj) \
> >>      OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
> >>--
> >>2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-04-27 12:14   ` Michael S. Tsirkin
@ 2015-04-27 13:01     ` Marcel Apfelbaum
  2015-04-27 14:45       ` Michael S. Tsirkin
  0 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-27 13:01 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 03:14 PM, Michael S. Tsirkin wrote:
> On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
>> TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
>> whose configuration registers are snooped by other host bridges
>> to complete their configuration cycles.
>>
>> The interface exposes a list of snooping host bridges that
>> shall be used by the hosts implementing this interface
>> in order to emulate a snooping mechanism.
>>
>> The way that the snooping hosts are registered or how
>> the snooping is implemented are out of the interface scope,
>> it only provides a way to determine if a host bridge has
>> snooping hosts and list them.
>
>
>
>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>> ---
>>   hw/pci/pci_host.c         |  8 ++++++++
>>   include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
>>   2 files changed, 32 insertions(+)
>>
>> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>> index 87180c8..288e74c 100644
>> --- a/hw/pci/pci_host.c
>> +++ b/hw/pci/pci_host.c
>> @@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
>>       .parent        = TYPE_INTERFACE,
>>   };
>>
>> +static const TypeInfo pci_host_bridge_snooped_interface_info = {
>> +    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
>> +    .parent = TYPE_INTERFACE,
>> +    .class_size = sizeof(PCIHostBridgeSnoopedClass),
>> +};
>> +
>>   static const TypeInfo pci_host_type_info = {
>>       .name = TYPE_PCI_HOST_BRIDGE,
>>       .parent = TYPE_SYS_BUS_DEVICE,
>> @@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
>>   static void pci_host_register_types(void)
>>   {
>>       type_register_static(&pci_main_host_interface_info);
>> +    type_register_static(&pci_host_bridge_snooped_interface_info);
>>       type_register_static(&pci_host_type_info);
>> +
>
> extra empty line
Will take care of it, thanks.

>
>>   }
>>
>>   type_init(pci_host_register_types)
>> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
>> index 3c72e26..a041919 100644
>> --- a/include/hw/pci/pci_host.h
>> +++ b/include/hw/pci/pci_host.h
>> @@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
>>       const char *(*root_bus_path)(PCIHostState *, PCIBus *);
>>   } PCIHostBridgeClass;
>>
>> +/**
>> + * A special case of host bridge whose configuration registers
>> + * are snooped by other host bridges to complete their
>> + * configuration cycles.
>> + */
>> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
>> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
>> +     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
>> +                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
>> +#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
>> +     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
>> +                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
>> +#define PCI_HOST_BRIDGE_SNOOPED(obj) \
>> +     INTERFACE_CHECK(PCIHostState, (obj), \
>> +                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
>> +
>> +typedef struct PCIHostBridgeSnoopedClass {
>> +    /* <private> */
>> +    InterfaceClass parent_class;
>> +
>> +    /* <public> */
>> +    GPtrArray *(*snooping_hosts)(PCIHostState *);
>
> Why not just add GPtrArray here directly, and add an API to
> register/deregister?
The interface concentrates on usage, letting the way to fill the snooping
hosts to the specific implementation.

Thanks,
Marcel

>
>> +} PCIHostBridgeSnoopedClass;
>> +
>>   /* common internal helpers for PCI/PCIe hosts, cut off overflows */
>>   void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
>>                                     uint32_t limit, uint32_t val, uint32_t len);
>> --
>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-04-27 12:48       ` Michael S. Tsirkin
@ 2015-04-27 13:04         ` Marcel Apfelbaum
  2015-04-27 20:54           ` Michael S. Tsirkin
  0 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-27 13:04 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 03:48 PM, Michael S. Tsirkin wrote:
> On Mon, Apr 27, 2015 at 03:30:01PM +0300, Marcel Apfelbaum wrote:
>> On 04/27/2015 02:24 PM, Michael S. Tsirkin wrote:
>>> On Thu, Mar 19, 2015 at 08:52:47PM +0200, Marcel Apfelbaum wrote:
>>>> From: Marcel Apfelbaum <marcel.a@redhat.com>
>>>>
>>>> This is a marker interface used to differentiate the
>>>> "default" host bridge on a system with multiple host bridges.
>>>> This differentiation is required only for pc machines for now
>>>> by the ACPI subsystem.
>>>>
>>>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>>>
>>> Fixing hotplug for pxb almost for sure means we'll need
>>> to drop this later.
>> Not really, I am not sure how it is related. I'll go over the pxb pci devices
>> for this hotplug. I have no intention to drop this later.
>> This interface denotes the main/default/bus 0 host bridge.
>
> It's related since you will want to describe all host bridges in acpi.
When I'll submit the pxb hotplug support it will be more clear,
Basically, I'll go over the pxbs leaving the default host bridge alone.

>
>>
>>   How about an interface to
>>> iterate over objects by type?
>>> You can then blacklist pxbs for now.
>> Less elegant in my opinion,
>
> Right but it will be needed in the future anyway.
I think we should leave this for when we'll need it, this series
is already long enough without adding a new QOM iteration type.

Thanks,
Marcel

>
>>>
>>>> ---
>>>>   hw/i386/acpi-build.c      | 9 ++++++---
>>>>   hw/pci-host/piix.c        | 5 +++++
>>>>   hw/pci-host/q35.c         | 4 ++++
>>>>   hw/pci/pci_host.c         | 6 ++++++
>>>>   include/hw/pci/pci_host.h | 7 +++++++
>>>>   5 files changed, 28 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>>>> index d0a5c85..86e474a 100644
>>>> --- a/hw/i386/acpi-build.c
>>>> +++ b/hw/i386/acpi-build.c
>>>> @@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
>>>>       Object *pci_host;
>>>>       bool ambiguous;
>>>>
>>>> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>>>> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>>>> +                                        &ambiguous);
>>>>       g_assert(!ambiguous);
>>>>       g_assert(pci_host);
>>>>
>>>> @@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
>>>>               PCIBus *bus = NULL;
>>>>               bool ambiguous;
>>>>
>>>> -            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>>>> +            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>>>> +                                                &ambiguous);
>>>>               if (!ambiguous && pci_host) {
>>>>                   bus = PCI_HOST_BRIDGE(pci_host)->bus;
>>>>               }
>>>> @@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>>>>       QObject *o;
>>>>       bool ambiguous;
>>>>
>>>> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>>>> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>>>> +                                        &ambiguous);
>>>>       g_assert(!ambiguous);
>>>>       g_assert(pci_host);
>>>>
>>>> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
>>>> index 292b6e9..0033ab4 100644
>>>> --- a/hw/pci-host/piix.c
>>>> +++ b/hw/pci-host/piix.c
>>>> @@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
>>>>       .instance_size = sizeof(I440FXState),
>>>>       .instance_init = i440fx_pcihost_initfn,
>>>>       .class_init    = i440fx_pcihost_class_init,
>>>> +    .interfaces    = (InterfaceInfo[]) {
>>>> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
>>>> +        { }
>>>> +    }
>>>> +
>>>>   };
>>>>
>>>>   static void i440fx_register_types(void)
>>>> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
>>>> index 5dd559e..e35b3a2 100644
>>>> --- a/hw/pci-host/q35.c
>>>> +++ b/hw/pci-host/q35.c
>>>> @@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
>>>>       .instance_size = sizeof(Q35PCIHost),
>>>>       .instance_init = q35_host_initfn,
>>>>       .class_init = q35_host_class_init,
>>>> +    .interfaces = (InterfaceInfo[]) {
>>>> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
>>>> +        { }
>>>> +    }
>>>>   };
>>>>
>>>>   /****************************************************************************
>>>> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>>>> index 3e26f92..87180c8 100644
>>>> --- a/hw/pci/pci_host.c
>>>> +++ b/hw/pci/pci_host.c
>>>> @@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
>>>>       .endianness = DEVICE_BIG_ENDIAN,
>>>>   };
>>>>
>>>> +static const TypeInfo pci_main_host_interface_info = {
>>>> +    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
>>>> +    .parent        = TYPE_INTERFACE,
>>>> +};
>>>> +
>>>>   static const TypeInfo pci_host_type_info = {
>>>>       .name = TYPE_PCI_HOST_BRIDGE,
>>>>       .parent = TYPE_SYS_BUS_DEVICE,
>>>> @@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
>>>>
>>>>   static void pci_host_register_types(void)
>>>>   {
>>>> +    type_register_static(&pci_main_host_interface_info);
>>>>       type_register_static(&pci_host_type_info);
>>>>   }
>>>>
>>>> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
>>>> index ba31595..3c72e26 100644
>>>> --- a/include/hw/pci/pci_host.h
>>>> +++ b/include/hw/pci/pci_host.h
>>>> @@ -30,6 +30,13 @@
>>>>
>>>>   #include "hw/sysbus.h"
>>>>
>>>> +/**
>>>> + * Marker interface for classes whose instances can
>>>> + * be main host bridges. It is intended to be used
>>>> + * when the QOM tree includes multiple host bridges.
>>>> + */
>>>> +#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
>>>> +
>>>>   #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
>>>>   #define PCI_HOST_BRIDGE(obj) \
>>>>       OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
>>>> --
>>>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-04-27 13:01     ` Marcel Apfelbaum
@ 2015-04-27 14:45       ` Michael S. Tsirkin
  2015-04-28  8:39         ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 14:45 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Mon, Apr 27, 2015 at 04:01:16PM +0300, Marcel Apfelbaum wrote:
> On 04/27/2015 03:14 PM, Michael S. Tsirkin wrote:
> >On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
> >>TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
> >>whose configuration registers are snooped by other host bridges
> >>to complete their configuration cycles.
> >>
> >>The interface exposes a list of snooping host bridges that
> >>shall be used by the hosts implementing this interface
> >>in order to emulate a snooping mechanism.
> >>
> >>The way that the snooping hosts are registered or how
> >>the snooping is implemented are out of the interface scope,
> >>it only provides a way to determine if a host bridge has
> >>snooping hosts and list them.
> >
> >
> >
> >>Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> >>---
> >>  hw/pci/pci_host.c         |  8 ++++++++
> >>  include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
> >>  2 files changed, 32 insertions(+)
> >>
> >>diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> >>index 87180c8..288e74c 100644
> >>--- a/hw/pci/pci_host.c
> >>+++ b/hw/pci/pci_host.c
> >>@@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
> >>      .parent        = TYPE_INTERFACE,
> >>  };
> >>
> >>+static const TypeInfo pci_host_bridge_snooped_interface_info = {
> >>+    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
> >>+    .parent = TYPE_INTERFACE,
> >>+    .class_size = sizeof(PCIHostBridgeSnoopedClass),
> >>+};
> >>+
> >>  static const TypeInfo pci_host_type_info = {
> >>      .name = TYPE_PCI_HOST_BRIDGE,
> >>      .parent = TYPE_SYS_BUS_DEVICE,
> >>@@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
> >>  static void pci_host_register_types(void)
> >>  {
> >>      type_register_static(&pci_main_host_interface_info);
> >>+    type_register_static(&pci_host_bridge_snooped_interface_info);
> >>      type_register_static(&pci_host_type_info);
> >>+
> >
> >extra empty line
> Will take care of it, thanks.
> 
> >
> >>  }
> >>
> >>  type_init(pci_host_register_types)
> >>diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> >>index 3c72e26..a041919 100644
> >>--- a/include/hw/pci/pci_host.h
> >>+++ b/include/hw/pci/pci_host.h
> >>@@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
> >>      const char *(*root_bus_path)(PCIHostState *, PCIBus *);
> >>  } PCIHostBridgeClass;
> >>
> >>+/**
> >>+ * A special case of host bridge whose configuration registers
> >>+ * are snooped by other host bridges to complete their
> >>+ * configuration cycles.
> >>+ */
> >>+#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
> >>+#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
> >>+     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
> >>+                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>+#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
> >>+     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
> >>+                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>+#define PCI_HOST_BRIDGE_SNOOPED(obj) \
> >>+     INTERFACE_CHECK(PCIHostState, (obj), \
> >>+                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>+
> >>+typedef struct PCIHostBridgeSnoopedClass {
> >>+    /* <private> */
> >>+    InterfaceClass parent_class;
> >>+
> >>+    /* <public> */
> >>+    GPtrArray *(*snooping_hosts)(PCIHostState *);
> >
> >Why not just add GPtrArray here directly, and add an API to
> >register/deregister?
> The interface concentrates on usage, letting the way to fill the snooping
> hosts to the specific implementation.
> 
> Thanks,
> Marcel

IMO this is overdoing abstractions.

But all this might be moot, it's probably better to just
add everyone to the child bus list, and drop the
concept of snooping config cycles.


> >
> >>+} PCIHostBridgeSnoopedClass;
> >>+
> >>  /* common internal helpers for PCI/PCIe hosts, cut off overflows */
> >>  void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
> >>                                    uint32_t limit, uint32_t val, uint32_t len);
> >>--
> >>2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-04-27 13:04         ` Marcel Apfelbaum
@ 2015-04-27 20:54           ` Michael S. Tsirkin
  2015-04-28  8:33             ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-27 20:54 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Mon, Apr 27, 2015 at 04:04:38PM +0300, Marcel Apfelbaum wrote:
> On 04/27/2015 03:48 PM, Michael S. Tsirkin wrote:
> >On Mon, Apr 27, 2015 at 03:30:01PM +0300, Marcel Apfelbaum wrote:
> >>On 04/27/2015 02:24 PM, Michael S. Tsirkin wrote:
> >>>On Thu, Mar 19, 2015 at 08:52:47PM +0200, Marcel Apfelbaum wrote:
> >>>>From: Marcel Apfelbaum <marcel.a@redhat.com>
> >>>>
> >>>>This is a marker interface used to differentiate the
> >>>>"default" host bridge on a system with multiple host bridges.
> >>>>This differentiation is required only for pc machines for now
> >>>>by the ACPI subsystem.
> >>>>
> >>>>Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> >>>
> >>>Fixing hotplug for pxb almost for sure means we'll need
> >>>to drop this later.
> >>Not really, I am not sure how it is related. I'll go over the pxb pci devices
> >>for this hotplug. I have no intention to drop this later.
> >>This interface denotes the main/default/bus 0 host bridge.
> >
> >It's related since you will want to describe all host bridges in acpi.
> When I'll submit the pxb hotplug support it will be more clear,
> Basically, I'll go over the pxbs leaving the default host bridge alone.

So instead, just go over all roots.

> >
> >>
> >>  How about an interface to
> >>>iterate over objects by type?
> >>>You can then blacklist pxbs for now.
> >>Less elegant in my opinion,
> >
> >Right but it will be needed in the future anyway.
> I think we should leave this for when we'll need it, this series
> is already long enough without adding a new QOM iteration type.
> 
> Thanks,
> Marcel

Do you have hotplug working?
Maybe wait until it's there, then we can discuss.

> >
> >>>
> >>>>---
> >>>>  hw/i386/acpi-build.c      | 9 ++++++---
> >>>>  hw/pci-host/piix.c        | 5 +++++
> >>>>  hw/pci-host/q35.c         | 4 ++++
> >>>>  hw/pci/pci_host.c         | 6 ++++++
> >>>>  include/hw/pci/pci_host.h | 7 +++++++
> >>>>  5 files changed, 28 insertions(+), 3 deletions(-)
> >>>>
> >>>>diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> >>>>index d0a5c85..86e474a 100644
> >>>>--- a/hw/i386/acpi-build.c
> >>>>+++ b/hw/i386/acpi-build.c
> >>>>@@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
> >>>>      Object *pci_host;
> >>>>      bool ambiguous;
> >>>>
> >>>>-    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> >>>>+    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> >>>>+                                        &ambiguous);
> >>>>      g_assert(!ambiguous);
> >>>>      g_assert(pci_host);
> >>>>
> >>>>@@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
> >>>>              PCIBus *bus = NULL;
> >>>>              bool ambiguous;
> >>>>
> >>>>-            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> >>>>+            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> >>>>+                                                &ambiguous);
> >>>>              if (!ambiguous && pci_host) {
> >>>>                  bus = PCI_HOST_BRIDGE(pci_host)->bus;
> >>>>              }
> >>>>@@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
> >>>>      QObject *o;
> >>>>      bool ambiguous;
> >>>>
> >>>>-    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
> >>>>+    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
> >>>>+                                        &ambiguous);
> >>>>      g_assert(!ambiguous);
> >>>>      g_assert(pci_host);
> >>>>
> >>>>diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> >>>>index 292b6e9..0033ab4 100644
> >>>>--- a/hw/pci-host/piix.c
> >>>>+++ b/hw/pci-host/piix.c
> >>>>@@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
> >>>>      .instance_size = sizeof(I440FXState),
> >>>>      .instance_init = i440fx_pcihost_initfn,
> >>>>      .class_init    = i440fx_pcihost_class_init,
> >>>>+    .interfaces    = (InterfaceInfo[]) {
> >>>>+        { TYPE_PCI_MAIN_HOST_BRIDGE },
> >>>>+        { }
> >>>>+    }
> >>>>+
> >>>>  };
> >>>>
> >>>>  static void i440fx_register_types(void)
> >>>>diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> >>>>index 5dd559e..e35b3a2 100644
> >>>>--- a/hw/pci-host/q35.c
> >>>>+++ b/hw/pci-host/q35.c
> >>>>@@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
> >>>>      .instance_size = sizeof(Q35PCIHost),
> >>>>      .instance_init = q35_host_initfn,
> >>>>      .class_init = q35_host_class_init,
> >>>>+    .interfaces = (InterfaceInfo[]) {
> >>>>+        { TYPE_PCI_MAIN_HOST_BRIDGE },
> >>>>+        { }
> >>>>+    }
> >>>>  };
> >>>>
> >>>>  /****************************************************************************
> >>>>diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> >>>>index 3e26f92..87180c8 100644
> >>>>--- a/hw/pci/pci_host.c
> >>>>+++ b/hw/pci/pci_host.c
> >>>>@@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
> >>>>      .endianness = DEVICE_BIG_ENDIAN,
> >>>>  };
> >>>>
> >>>>+static const TypeInfo pci_main_host_interface_info = {
> >>>>+    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
> >>>>+    .parent        = TYPE_INTERFACE,
> >>>>+};
> >>>>+
> >>>>  static const TypeInfo pci_host_type_info = {
> >>>>      .name = TYPE_PCI_HOST_BRIDGE,
> >>>>      .parent = TYPE_SYS_BUS_DEVICE,
> >>>>@@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
> >>>>
> >>>>  static void pci_host_register_types(void)
> >>>>  {
> >>>>+    type_register_static(&pci_main_host_interface_info);
> >>>>      type_register_static(&pci_host_type_info);
> >>>>  }
> >>>>
> >>>>diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> >>>>index ba31595..3c72e26 100644
> >>>>--- a/include/hw/pci/pci_host.h
> >>>>+++ b/include/hw/pci/pci_host.h
> >>>>@@ -30,6 +30,13 @@
> >>>>
> >>>>  #include "hw/sysbus.h"
> >>>>
> >>>>+/**
> >>>>+ * Marker interface for classes whose instances can
> >>>>+ * be main host bridges. It is intended to be used
> >>>>+ * when the QOM tree includes multiple host bridges.
> >>>>+ */
> >>>>+#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
> >>>>+
> >>>>  #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
> >>>>  #define PCI_HOST_BRIDGE(obj) \
> >>>>      OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
> >>>>--
> >>>>2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-27 11:35     ` Paolo Bonzini
  2015-04-27 11:49       ` Marcel Apfelbaum
@ 2015-04-28  7:31       ` Markus Armbruster
  2015-04-28  8:25         ` Marcel Apfelbaum
  1 sibling, 1 reply; 61+ messages in thread
From: Markus Armbruster @ 2015-04-28  7:31 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: quintela, hare, Michael S. Tsirkin, agraf, qemu-devel, amit.shah,
	alex.williamson, kevin, kraxel, Marcel Apfelbaum, imammedo,
	leon.alrae, aurelien, rth

Paolo Bonzini <pbonzini@redhat.com> writes:

> On 27/04/2015 13:14, Michael S. Tsirkin wrote:
>>> + *
>>> > + * This work is licensed under the terms of the GNU GPL, version
>>> > 2 or later.
>>> > + * See the COPYING file in the top-level directory.
>> The file you are moving this from is GPL only.
>
> It's BSD.
>
>> You will need to find who contributed this code you are moving
>> and get ack from them ...
>
> Simpler to keep BSD.

Just for completeness: you're free to GPL a derived work.  The folks who
BSD-licensed it to you may consider that offensive, but the law doesn't
consider it wrong.

You may care a whole lot more for how these folks feel about you than
what the law permits you to do.

I'd consider switching to GPL only if I made substantial changes.

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-28  7:31       ` Markus Armbruster
@ 2015-04-28  8:25         ` Marcel Apfelbaum
  0 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-28  8:25 UTC (permalink / raw)
  To: Markus Armbruster, Paolo Bonzini
  Cc: quintela, hare, Michael S. Tsirkin, agraf, qemu-devel,
	alex.williamson, kevin, kraxel, amit.shah, imammedo, leon.alrae,
	aurelien, rth

On 04/28/2015 10:31 AM, Markus Armbruster wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> On 27/04/2015 13:14, Michael S. Tsirkin wrote:
>>>> + *
>>>>> + * This work is licensed under the terms of the GNU GPL, version
>>>>> 2 or later.
>>>>> + * See the COPYING file in the top-level directory.
>>> The file you are moving this from is GPL only.
>>
>> It's BSD.
>>
>>> You will need to find who contributed this code you are moving
>>> and get ack from them ...
>>
>> Simpler to keep BSD.
>
> Just for completeness: you're free to GPL a derived work.  The folks who
> BSD-licensed it to you may consider that offensive, but the law doesn't
> consider it wrong.
>
> You may care a whole lot more for how these folks feel about you than
> what the law permits you to do.
>
> I'd consider switching to GPL only if I made substantial changes.
>
Thanks Markus,
Since I only moved some code around, I'll keep it BSD.

Marcel

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-27 12:26     ` Marcel Apfelbaum
@ 2015-04-28  8:30       ` Michael S. Tsirkin
  2015-04-28  8:30         ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-28  8:30 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Mon, Apr 27, 2015 at 03:26:44PM +0300, Marcel Apfelbaum wrote:
> On 04/27/2015 02:14 PM, Michael S. Tsirkin wrote:
> >On Thu, Mar 19, 2015 at 08:52:44PM +0200, Marcel Apfelbaum wrote:
> >>@@ -2414,7 +1945,6 @@ static const TypeInfo pci_device_type_info = {
> >>
> >>  static void pci_register_types(void)
> >>  {
> >>-    type_register_static(&pci_bus_info);
> >>      type_register_static(&pcie_bus_info);
> >>      type_register_static(&pci_device_type_info);
> >>  }
> >
> >So pcie bus is not moved.  This seems pretty inconsistent.
> There were a lot of code dependencies. I moved the minimum code in order
> to be able to add code specific to PCIBus.

Interfaces need to make sense, this one feels like you randomly moved out
parts that your patch happens to need.
Just keep it all in pci.c for now.

-- 
MST

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files
  2015-04-28  8:30       ` Michael S. Tsirkin
@ 2015-04-28  8:30         ` Marcel Apfelbaum
  0 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-28  8:30 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/28/2015 11:30 AM, Michael S. Tsirkin wrote:
> On Mon, Apr 27, 2015 at 03:26:44PM +0300, Marcel Apfelbaum wrote:
>> On 04/27/2015 02:14 PM, Michael S. Tsirkin wrote:
>>> On Thu, Mar 19, 2015 at 08:52:44PM +0200, Marcel Apfelbaum wrote:
>>>> @@ -2414,7 +1945,6 @@ static const TypeInfo pci_device_type_info = {
>>>>
>>>>   static void pci_register_types(void)
>>>>   {
>>>> -    type_register_static(&pci_bus_info);
>>>>       type_register_static(&pcie_bus_info);
>>>>       type_register_static(&pci_device_type_info);
>>>>   }
>>>
>>> So pcie bus is not moved.  This seems pretty inconsistent.
>> There were a lot of code dependencies. I moved the minimum code in order
>> to be able to add code specific to PCIBus.
>
> Interfaces need to make sense, this one feels like you randomly moved out
> parts that your patch happens to need.
> Just keep it all in pci.c for now.
>
OK, I'll make the changes for next version.

Thanks,
Marcel

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface
  2015-04-27 20:54           ` Michael S. Tsirkin
@ 2015-04-28  8:33             ` Marcel Apfelbaum
  0 siblings, 0 replies; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-28  8:33 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 11:54 PM, Michael S. Tsirkin wrote:
> On Mon, Apr 27, 2015 at 04:04:38PM +0300, Marcel Apfelbaum wrote:
>> On 04/27/2015 03:48 PM, Michael S. Tsirkin wrote:
>>> On Mon, Apr 27, 2015 at 03:30:01PM +0300, Marcel Apfelbaum wrote:
>>>> On 04/27/2015 02:24 PM, Michael S. Tsirkin wrote:
>>>>> On Thu, Mar 19, 2015 at 08:52:47PM +0200, Marcel Apfelbaum wrote:
>>>>>> From: Marcel Apfelbaum <marcel.a@redhat.com>
>>>>>>
>>>>>> This is a marker interface used to differentiate the
>>>>>> "default" host bridge on a system with multiple host bridges.
>>>>>> This differentiation is required only for pc machines for now
>>>>>> by the ACPI subsystem.
>>>>>>
>>>>>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>>>>>
>>>>> Fixing hotplug for pxb almost for sure means we'll need
>>>>> to drop this later.
>>>> Not really, I am not sure how it is related. I'll go over the pxb pci devices
>>>> for this hotplug. I have no intention to drop this later.
>>>> This interface denotes the main/default/bus 0 host bridge.
>>>
>>> It's related since you will want to describe all host bridges in acpi.
>> When I'll submit the pxb hotplug support it will be more clear,
>> Basically, I'll go over the pxbs leaving the default host bridge alone.
>
> So instead, just go over all roots.
I am not sure it will work that way. We'll know more after I will work on hotplug.
>
>>>
>>>>
>>>>   How about an interface to
>>>>> iterate over objects by type?
>>>>> You can then blacklist pxbs for now.
>>>> Less elegant in my opinion,
>>>
>>> Right but it will be needed in the future anyway.
>> I think we should leave this for when we'll need it, this series
>> is already long enough without adding a new QOM iteration type.
>>
>> Thanks,
>> Marcel
>
> Do you have hotplug working?
> Maybe wait until it's there, then we can discuss.
I agree, I hope I'll have something next week.
For next version I'll keep this around.

Thanks,
Marcel
>
>>>
>>>>>
>>>>>> ---
>>>>>>   hw/i386/acpi-build.c      | 9 ++++++---
>>>>>>   hw/pci-host/piix.c        | 5 +++++
>>>>>>   hw/pci-host/q35.c         | 4 ++++
>>>>>>   hw/pci/pci_host.c         | 6 ++++++
>>>>>>   include/hw/pci/pci_host.h | 7 +++++++
>>>>>>   5 files changed, 28 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>>>>>> index d0a5c85..86e474a 100644
>>>>>> --- a/hw/i386/acpi-build.c
>>>>>> +++ b/hw/i386/acpi-build.c
>>>>>> @@ -249,7 +249,8 @@ static void acpi_get_pci_info(PcPciInfo *info)
>>>>>>       Object *pci_host;
>>>>>>       bool ambiguous;
>>>>>>
>>>>>> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>>>>>> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>>>>>> +                                        &ambiguous);
>>>>>>       g_assert(!ambiguous);
>>>>>>       g_assert(pci_host);
>>>>>>
>>>>>> @@ -993,7 +994,8 @@ build_ssdt(GArray *table_data, GArray *linker,
>>>>>>               PCIBus *bus = NULL;
>>>>>>               bool ambiguous;
>>>>>>
>>>>>> -            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>>>>>> +            pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>>>>>> +                                                &ambiguous);
>>>>>>               if (!ambiguous && pci_host) {
>>>>>>                   bus = PCI_HOST_BRIDGE(pci_host)->bus;
>>>>>>               }
>>>>>> @@ -1338,7 +1340,8 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
>>>>>>       QObject *o;
>>>>>>       bool ambiguous;
>>>>>>
>>>>>> -    pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
>>>>>> +    pci_host = object_resolve_path_type("", TYPE_PCI_MAIN_HOST_BRIDGE,
>>>>>> +                                        &ambiguous);
>>>>>>       g_assert(!ambiguous);
>>>>>>       g_assert(pci_host);
>>>>>>
>>>>>> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
>>>>>> index 292b6e9..0033ab4 100644
>>>>>> --- a/hw/pci-host/piix.c
>>>>>> +++ b/hw/pci-host/piix.c
>>>>>> @@ -766,6 +766,11 @@ static const TypeInfo i440fx_pcihost_info = {
>>>>>>       .instance_size = sizeof(I440FXState),
>>>>>>       .instance_init = i440fx_pcihost_initfn,
>>>>>>       .class_init    = i440fx_pcihost_class_init,
>>>>>> +    .interfaces    = (InterfaceInfo[]) {
>>>>>> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
>>>>>> +        { }
>>>>>> +    }
>>>>>> +
>>>>>>   };
>>>>>>
>>>>>>   static void i440fx_register_types(void)
>>>>>> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
>>>>>> index 5dd559e..e35b3a2 100644
>>>>>> --- a/hw/pci-host/q35.c
>>>>>> +++ b/hw/pci-host/q35.c
>>>>>> @@ -193,6 +193,10 @@ static const TypeInfo q35_host_info = {
>>>>>>       .instance_size = sizeof(Q35PCIHost),
>>>>>>       .instance_init = q35_host_initfn,
>>>>>>       .class_init = q35_host_class_init,
>>>>>> +    .interfaces = (InterfaceInfo[]) {
>>>>>> +        { TYPE_PCI_MAIN_HOST_BRIDGE },
>>>>>> +        { }
>>>>>> +    }
>>>>>>   };
>>>>>>
>>>>>>   /****************************************************************************
>>>>>> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>>>>>> index 3e26f92..87180c8 100644
>>>>>> --- a/hw/pci/pci_host.c
>>>>>> +++ b/hw/pci/pci_host.c
>>>>>> @@ -175,6 +175,11 @@ const MemoryRegionOps pci_host_data_be_ops = {
>>>>>>       .endianness = DEVICE_BIG_ENDIAN,
>>>>>>   };
>>>>>>
>>>>>> +static const TypeInfo pci_main_host_interface_info = {
>>>>>> +    .name          = TYPE_PCI_MAIN_HOST_BRIDGE,
>>>>>> +    .parent        = TYPE_INTERFACE,
>>>>>> +};
>>>>>> +
>>>>>>   static const TypeInfo pci_host_type_info = {
>>>>>>       .name = TYPE_PCI_HOST_BRIDGE,
>>>>>>       .parent = TYPE_SYS_BUS_DEVICE,
>>>>>> @@ -185,6 +190,7 @@ static const TypeInfo pci_host_type_info = {
>>>>>>
>>>>>>   static void pci_host_register_types(void)
>>>>>>   {
>>>>>> +    type_register_static(&pci_main_host_interface_info);
>>>>>>       type_register_static(&pci_host_type_info);
>>>>>>   }
>>>>>>
>>>>>> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
>>>>>> index ba31595..3c72e26 100644
>>>>>> --- a/include/hw/pci/pci_host.h
>>>>>> +++ b/include/hw/pci/pci_host.h
>>>>>> @@ -30,6 +30,13 @@
>>>>>>
>>>>>>   #include "hw/sysbus.h"
>>>>>>
>>>>>> +/**
>>>>>> + * Marker interface for classes whose instances can
>>>>>> + * be main host bridges. It is intended to be used
>>>>>> + * when the QOM tree includes multiple host bridges.
>>>>>> + */
>>>>>> +#define TYPE_PCI_MAIN_HOST_BRIDGE "pci-main-host-bridge"
>>>>>> +
>>>>>>   #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
>>>>>>   #define PCI_HOST_BRIDGE(obj) \
>>>>>>       OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
>>>>>> --
>>>>>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-04-27 14:45       ` Michael S. Tsirkin
@ 2015-04-28  8:39         ` Marcel Apfelbaum
  2015-04-28  8:43           ` Michael S. Tsirkin
  0 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-28  8:39 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/27/2015 05:45 PM, Michael S. Tsirkin wrote:
> On Mon, Apr 27, 2015 at 04:01:16PM +0300, Marcel Apfelbaum wrote:
>> On 04/27/2015 03:14 PM, Michael S. Tsirkin wrote:
>>> On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
>>>> TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
>>>> whose configuration registers are snooped by other host bridges
>>>> to complete their configuration cycles.
>>>>
>>>> The interface exposes a list of snooping host bridges that
>>>> shall be used by the hosts implementing this interface
>>>> in order to emulate a snooping mechanism.
>>>>
>>>> The way that the snooping hosts are registered or how
>>>> the snooping is implemented are out of the interface scope,
>>>> it only provides a way to determine if a host bridge has
>>>> snooping hosts and list them.
>>>
>>>
>>>
>>>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>>>> ---
>>>>   hw/pci/pci_host.c         |  8 ++++++++
>>>>   include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
>>>>   2 files changed, 32 insertions(+)
>>>>
>>>> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>>>> index 87180c8..288e74c 100644
>>>> --- a/hw/pci/pci_host.c
>>>> +++ b/hw/pci/pci_host.c
>>>> @@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
>>>>       .parent        = TYPE_INTERFACE,
>>>>   };
>>>>
>>>> +static const TypeInfo pci_host_bridge_snooped_interface_info = {
>>>> +    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
>>>> +    .parent = TYPE_INTERFACE,
>>>> +    .class_size = sizeof(PCIHostBridgeSnoopedClass),
>>>> +};
>>>> +
>>>>   static const TypeInfo pci_host_type_info = {
>>>>       .name = TYPE_PCI_HOST_BRIDGE,
>>>>       .parent = TYPE_SYS_BUS_DEVICE,
>>>> @@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
>>>>   static void pci_host_register_types(void)
>>>>   {
>>>>       type_register_static(&pci_main_host_interface_info);
>>>> +    type_register_static(&pci_host_bridge_snooped_interface_info);
>>>>       type_register_static(&pci_host_type_info);
>>>> +
>>>
>>> extra empty line
>> Will take care of it, thanks.
>>
>>>
>>>>   }
>>>>
>>>>   type_init(pci_host_register_types)
>>>> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
>>>> index 3c72e26..a041919 100644
>>>> --- a/include/hw/pci/pci_host.h
>>>> +++ b/include/hw/pci/pci_host.h
>>>> @@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
>>>>       const char *(*root_bus_path)(PCIHostState *, PCIBus *);
>>>>   } PCIHostBridgeClass;
>>>>
>>>> +/**
>>>> + * A special case of host bridge whose configuration registers
>>>> + * are snooped by other host bridges to complete their
>>>> + * configuration cycles.
>>>> + */
>>>> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
>>>> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
>>>> +     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
>>>> +                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
>>>> +#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
>>>> +     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
>>>> +                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
>>>> +#define PCI_HOST_BRIDGE_SNOOPED(obj) \
>>>> +     INTERFACE_CHECK(PCIHostState, (obj), \
>>>> +                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
>>>> +
>>>> +typedef struct PCIHostBridgeSnoopedClass {
>>>> +    /* <private> */
>>>> +    InterfaceClass parent_class;
>>>> +
>>>> +    /* <public> */
>>>> +    GPtrArray *(*snooping_hosts)(PCIHostState *);
>>>
>>> Why not just add GPtrArray here directly, and add an API to
>>> register/deregister?
>> The interface concentrates on usage, letting the way to fill the snooping
>> hosts to the specific implementation.
>>
>> Thanks,
>> Marcel
>
> IMO this is overdoing abstractions.
It will provide us with enough elasticity when we'll try the same for Q35.
Also this interface is used in several places and it will serve us when we'll go for Q35.

>
> But all this might be moot, it's probably better to just
> add everyone to the child bus list, and drop the
> concept of snooping config cycles.
Well, this will be a problem, since the whole concept of the PXB is to snoop
on the configuration cycles and this interface gives us a more easy
way to understand the implementation.

We already discussed this approach and was accepted.
The code is small and concise and the use of QOM makes sense in my opinion.
I prefer not to re-open it now.

Thanks,
Marcel
>
>
>>>
>>>> +} PCIHostBridgeSnoopedClass;
>>>> +
>>>>   /* common internal helpers for PCI/PCIe hosts, cut off overflows */
>>>>   void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
>>>>                                     uint32_t limit, uint32_t val, uint32_t len);
>>>> --
>>>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-04-28  8:39         ` Marcel Apfelbaum
@ 2015-04-28  8:43           ` Michael S. Tsirkin
  2015-04-28 10:21             ` Marcel Apfelbaum
  0 siblings, 1 reply; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-28  8:43 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Tue, Apr 28, 2015 at 11:39:42AM +0300, Marcel Apfelbaum wrote:
> On 04/27/2015 05:45 PM, Michael S. Tsirkin wrote:
> >On Mon, Apr 27, 2015 at 04:01:16PM +0300, Marcel Apfelbaum wrote:
> >>On 04/27/2015 03:14 PM, Michael S. Tsirkin wrote:
> >>>On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
> >>>>TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
> >>>>whose configuration registers are snooped by other host bridges
> >>>>to complete their configuration cycles.
> >>>>
> >>>>The interface exposes a list of snooping host bridges that
> >>>>shall be used by the hosts implementing this interface
> >>>>in order to emulate a snooping mechanism.
> >>>>
> >>>>The way that the snooping hosts are registered or how
> >>>>the snooping is implemented are out of the interface scope,
> >>>>it only provides a way to determine if a host bridge has
> >>>>snooping hosts and list them.
> >>>
> >>>
> >>>
> >>>>Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> >>>>---
> >>>>  hw/pci/pci_host.c         |  8 ++++++++
> >>>>  include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
> >>>>  2 files changed, 32 insertions(+)
> >>>>
> >>>>diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> >>>>index 87180c8..288e74c 100644
> >>>>--- a/hw/pci/pci_host.c
> >>>>+++ b/hw/pci/pci_host.c
> >>>>@@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
> >>>>      .parent        = TYPE_INTERFACE,
> >>>>  };
> >>>>
> >>>>+static const TypeInfo pci_host_bridge_snooped_interface_info = {
> >>>>+    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
> >>>>+    .parent = TYPE_INTERFACE,
> >>>>+    .class_size = sizeof(PCIHostBridgeSnoopedClass),
> >>>>+};
> >>>>+
> >>>>  static const TypeInfo pci_host_type_info = {
> >>>>      .name = TYPE_PCI_HOST_BRIDGE,
> >>>>      .parent = TYPE_SYS_BUS_DEVICE,
> >>>>@@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
> >>>>  static void pci_host_register_types(void)
> >>>>  {
> >>>>      type_register_static(&pci_main_host_interface_info);
> >>>>+    type_register_static(&pci_host_bridge_snooped_interface_info);
> >>>>      type_register_static(&pci_host_type_info);
> >>>>+
> >>>
> >>>extra empty line
> >>Will take care of it, thanks.
> >>
> >>>
> >>>>  }
> >>>>
> >>>>  type_init(pci_host_register_types)
> >>>>diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> >>>>index 3c72e26..a041919 100644
> >>>>--- a/include/hw/pci/pci_host.h
> >>>>+++ b/include/hw/pci/pci_host.h
> >>>>@@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
> >>>>      const char *(*root_bus_path)(PCIHostState *, PCIBus *);
> >>>>  } PCIHostBridgeClass;
> >>>>
> >>>>+/**
> >>>>+ * A special case of host bridge whose configuration registers
> >>>>+ * are snooped by other host bridges to complete their
> >>>>+ * configuration cycles.
> >>>>+ */
> >>>>+#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
> >>>>+#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
> >>>>+     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
> >>>>+                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>>>+#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
> >>>>+     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
> >>>>+                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>>>+#define PCI_HOST_BRIDGE_SNOOPED(obj) \
> >>>>+     INTERFACE_CHECK(PCIHostState, (obj), \
> >>>>+                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>>>+
> >>>>+typedef struct PCIHostBridgeSnoopedClass {
> >>>>+    /* <private> */
> >>>>+    InterfaceClass parent_class;
> >>>>+
> >>>>+    /* <public> */
> >>>>+    GPtrArray *(*snooping_hosts)(PCIHostState *);
> >>>
> >>>Why not just add GPtrArray here directly, and add an API to
> >>>register/deregister?
> >>The interface concentrates on usage, letting the way to fill the snooping
> >>hosts to the specific implementation.
> >>
> >>Thanks,
> >>Marcel
> >
> >IMO this is overdoing abstractions.
> It will provide us with enough elasticity when we'll try the same for Q35.
> Also this interface is used in several places and it will serve us when we'll go for Q35.

I don't see how it helps, we don't just stick a virtual function
in front of all new code we write on the assumption it
helps elasticity.

> >
> >But all this might be moot, it's probably better to just
> >add everyone to the child bus list, and drop the
> >concept of snooping config cycles.
> Well, this will be a problem, since the whole concept of the PXB is to snoop
> on the configuration cycles and this interface gives us a more easy
> way to understand the implementation.
> 
> We already discussed this approach and was accepted.
> The code is small and concise and the use of QOM makes sense in my opinion.
> I prefer not to re-open it now.
> 
> Thanks,
> Marcel

I'm talking about the implementation here.
We already scan the child bus list on config
transactions. Why not add your entry there,
then you can snoop to your heart's content.



> >
> >
> >>>
> >>>>+} PCIHostBridgeSnoopedClass;
> >>>>+
> >>>>  /* common internal helpers for PCI/PCIe hosts, cut off overflows */
> >>>>  void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
> >>>>                                    uint32_t limit, uint32_t val, uint32_t len);
> >>>>--
> >>>>2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-04-28  8:43           ` Michael S. Tsirkin
@ 2015-04-28 10:21             ` Marcel Apfelbaum
  2015-04-28 10:44               ` Michael S. Tsirkin
  0 siblings, 1 reply; 61+ messages in thread
From: Marcel Apfelbaum @ 2015-04-28 10:21 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On 04/28/2015 11:43 AM, Michael S. Tsirkin wrote:
> On Tue, Apr 28, 2015 at 11:39:42AM +0300, Marcel Apfelbaum wrote:
>> On 04/27/2015 05:45 PM, Michael S. Tsirkin wrote:
>>> On Mon, Apr 27, 2015 at 04:01:16PM +0300, Marcel Apfelbaum wrote:
>>>> On 04/27/2015 03:14 PM, Michael S. Tsirkin wrote:
>>>>> On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
>>>>>> TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
>>>>>> whose configuration registers are snooped by other host bridges
>>>>>> to complete their configuration cycles.
>>>>>>
>>>>>> The interface exposes a list of snooping host bridges that
>>>>>> shall be used by the hosts implementing this interface
>>>>>> in order to emulate a snooping mechanism.
>>>>>>
>>>>>> The way that the snooping hosts are registered or how
>>>>>> the snooping is implemented are out of the interface scope,
>>>>>> it only provides a way to determine if a host bridge has
>>>>>> snooping hosts and list them.
>>>>>
>>>>>
>>>>>
>>>>>> Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
>>>>>> ---
>>>>>>   hw/pci/pci_host.c         |  8 ++++++++
>>>>>>   include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
>>>>>>   2 files changed, 32 insertions(+)
>>>>>>
>>>>>> diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
>>>>>> index 87180c8..288e74c 100644
>>>>>> --- a/hw/pci/pci_host.c
>>>>>> +++ b/hw/pci/pci_host.c
>>>>>> @@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
>>>>>>       .parent        = TYPE_INTERFACE,
>>>>>>   };
>>>>>>
>>>>>> +static const TypeInfo pci_host_bridge_snooped_interface_info = {
>>>>>> +    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
>>>>>> +    .parent = TYPE_INTERFACE,
>>>>>> +    .class_size = sizeof(PCIHostBridgeSnoopedClass),
>>>>>> +};
>>>>>> +
>>>>>>   static const TypeInfo pci_host_type_info = {
>>>>>>       .name = TYPE_PCI_HOST_BRIDGE,
>>>>>>       .parent = TYPE_SYS_BUS_DEVICE,
>>>>>> @@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
>>>>>>   static void pci_host_register_types(void)
>>>>>>   {
>>>>>>       type_register_static(&pci_main_host_interface_info);
>>>>>> +    type_register_static(&pci_host_bridge_snooped_interface_info);
>>>>>>       type_register_static(&pci_host_type_info);
>>>>>> +
>>>>>
>>>>> extra empty line
>>>> Will take care of it, thanks.
>>>>
>>>>>
>>>>>>   }
>>>>>>
>>>>>>   type_init(pci_host_register_types)
>>>>>> diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
>>>>>> index 3c72e26..a041919 100644
>>>>>> --- a/include/hw/pci/pci_host.h
>>>>>> +++ b/include/hw/pci/pci_host.h
>>>>>> @@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
>>>>>>       const char *(*root_bus_path)(PCIHostState *, PCIBus *);
>>>>>>   } PCIHostBridgeClass;
>>>>>>
>>>>>> +/**
>>>>>> + * A special case of host bridge whose configuration registers
>>>>>> + * are snooped by other host bridges to complete their
>>>>>> + * configuration cycles.
>>>>>> + */
>>>>>> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
>>>>>> +#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
>>>>>> +     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
>>>>>> +                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
>>>>>> +#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
>>>>>> +     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
>>>>>> +                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
>>>>>> +#define PCI_HOST_BRIDGE_SNOOPED(obj) \
>>>>>> +     INTERFACE_CHECK(PCIHostState, (obj), \
>>>>>> +                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
>>>>>> +
>>>>>> +typedef struct PCIHostBridgeSnoopedClass {
>>>>>> +    /* <private> */
>>>>>> +    InterfaceClass parent_class;
>>>>>> +
>>>>>> +    /* <public> */
>>>>>> +    GPtrArray *(*snooping_hosts)(PCIHostState *);
>>>>>
>>>>> Why not just add GPtrArray here directly, and add an API to
>>>>> register/deregister?
>>>> The interface concentrates on usage, letting the way to fill the snooping
>>>> hosts to the specific implementation.
>>>>
>>>> Thanks,
>>>> Marcel
>>>
>>> IMO this is overdoing abstractions.
>> It will provide us with enough elasticity when we'll try the same for Q35.
>> Also this interface is used in several places and it will serve us when we'll go for Q35.
>
> I don't see how it helps, we don't just stick a virtual function
> in front of all new code we write on the assumption it
> helps elasticity.
It helps by letting us querying the interface instead of asking:
Is this host-bridge PIIX ? look for child buses and see if there are roots
else: is this host-bridge ...

>
>>>
>>> But all this might be moot, it's probably better to just
>>> add everyone to the child bus list, and drop the
>>> concept of snooping config cycles.
>> Well, this will be a problem, since the whole concept of the PXB is to snoop
>> on the configuration cycles and this interface gives us a more easy
>> way to understand the implementation.
>>
>> We already discussed this approach and was accepted.
>> The code is small and concise and the use of QOM makes sense in my opinion.
>> I prefer not to re-open it now.
>>
>> Thanks,
>> Marcel
>
> I'm talking about the implementation here.
> We already scan the child bus list on config
> transactions. Why not add your entry there,
> then you can snoop to your heart's content.
Maybe I didn't fully understand what you want.
Do you want to add the new root buses as child buses of root bus 0?
This interface is not used in this context, is used in other scenarios:
[PATCH V6 for-2.3 21/26] hw/pci: inform bios if the system has extra pci root buses
[PATCH V6 for-2.3 15/26] hw/acpi: add support for i440fx 'snooping' root busses

I can look for other usages, can you tell me how it will look without this interface?

Other thing, in config we have pci_data_write calling (in the end) pci_find_bus_nr that does  not support
multiple root buses.
Changing it could affect a lot of functionality and also looking at the function it will not be pretty or clear.
Keeping it at host-bridge level (see  [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement TYPE_PCI_HOST_BRIDGE_SNOOPED interface)
and having piix query its pxbs for the extra root buses seems a good fit.


Thanks,
Marce
>
>
>
>>>
>>>
>>>>>
>>>>>> +} PCIHostBridgeSnoopedClass;
>>>>>> +
>>>>>>   /* common internal helpers for PCI/PCIe hosts, cut off overflows */
>>>>>>   void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
>>>>>>                                     uint32_t limit, uint32_t val, uint32_t len);
>>>>>> --
>>>>>> 2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface
  2015-04-28 10:21             ` Marcel Apfelbaum
@ 2015-04-28 10:44               ` Michael S. Tsirkin
  0 siblings, 0 replies; 61+ messages in thread
From: Michael S. Tsirkin @ 2015-04-28 10:44 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: kraxel, quintela, qemu-devel, agraf, alex.williamson, kevin,
	hare, imammedo, amit.shah, pbonzini, leon.alrae, aurelien, rth

On Tue, Apr 28, 2015 at 01:21:14PM +0300, Marcel Apfelbaum wrote:
> On 04/28/2015 11:43 AM, Michael S. Tsirkin wrote:
> >On Tue, Apr 28, 2015 at 11:39:42AM +0300, Marcel Apfelbaum wrote:
> >>On 04/27/2015 05:45 PM, Michael S. Tsirkin wrote:
> >>>On Mon, Apr 27, 2015 at 04:01:16PM +0300, Marcel Apfelbaum wrote:
> >>>>On 04/27/2015 03:14 PM, Michael S. Tsirkin wrote:
> >>>>>On Thu, Mar 19, 2015 at 08:52:48PM +0200, Marcel Apfelbaum wrote:
> >>>>>>TYPE_PCI_HOST_BRIDGE_SNOOPED is a special case of host bridge
> >>>>>>whose configuration registers are snooped by other host bridges
> >>>>>>to complete their configuration cycles.
> >>>>>>
> >>>>>>The interface exposes a list of snooping host bridges that
> >>>>>>shall be used by the hosts implementing this interface
> >>>>>>in order to emulate a snooping mechanism.
> >>>>>>
> >>>>>>The way that the snooping hosts are registered or how
> >>>>>>the snooping is implemented are out of the interface scope,
> >>>>>>it only provides a way to determine if a host bridge has
> >>>>>>snooping hosts and list them.
> >>>>>
> >>>>>
> >>>>>
> >>>>>>Signed-off-by: Marcel Apfelbaum <marcel@redhat.com>
> >>>>>>---
> >>>>>>  hw/pci/pci_host.c         |  8 ++++++++
> >>>>>>  include/hw/pci/pci_host.h | 24 ++++++++++++++++++++++++
> >>>>>>  2 files changed, 32 insertions(+)
> >>>>>>
> >>>>>>diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> >>>>>>index 87180c8..288e74c 100644
> >>>>>>--- a/hw/pci/pci_host.c
> >>>>>>+++ b/hw/pci/pci_host.c
> >>>>>>@@ -180,6 +180,12 @@ static const TypeInfo pci_main_host_interface_info = {
> >>>>>>      .parent        = TYPE_INTERFACE,
> >>>>>>  };
> >>>>>>
> >>>>>>+static const TypeInfo pci_host_bridge_snooped_interface_info = {
> >>>>>>+    .name = TYPE_PCI_HOST_BRIDGE_SNOOPED,
> >>>>>>+    .parent = TYPE_INTERFACE,
> >>>>>>+    .class_size = sizeof(PCIHostBridgeSnoopedClass),
> >>>>>>+};
> >>>>>>+
> >>>>>>  static const TypeInfo pci_host_type_info = {
> >>>>>>      .name = TYPE_PCI_HOST_BRIDGE,
> >>>>>>      .parent = TYPE_SYS_BUS_DEVICE,
> >>>>>>@@ -191,7 +197,9 @@ static const TypeInfo pci_host_type_info = {
> >>>>>>  static void pci_host_register_types(void)
> >>>>>>  {
> >>>>>>      type_register_static(&pci_main_host_interface_info);
> >>>>>>+    type_register_static(&pci_host_bridge_snooped_interface_info);
> >>>>>>      type_register_static(&pci_host_type_info);
> >>>>>>+
> >>>>>
> >>>>>extra empty line
> >>>>Will take care of it, thanks.
> >>>>
> >>>>>
> >>>>>>  }
> >>>>>>
> >>>>>>  type_init(pci_host_register_types)
> >>>>>>diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
> >>>>>>index 3c72e26..a041919 100644
> >>>>>>--- a/include/hw/pci/pci_host.h
> >>>>>>+++ b/include/hw/pci/pci_host.h
> >>>>>>@@ -63,6 +63,30 @@ typedef struct PCIHostBridgeClass {
> >>>>>>      const char *(*root_bus_path)(PCIHostState *, PCIBus *);
> >>>>>>  } PCIHostBridgeClass;
> >>>>>>
> >>>>>>+/**
> >>>>>>+ * A special case of host bridge whose configuration registers
> >>>>>>+ * are snooped by other host bridges to complete their
> >>>>>>+ * configuration cycles.
> >>>>>>+ */
> >>>>>>+#define TYPE_PCI_HOST_BRIDGE_SNOOPED "pci-host-bridge-snooped"
> >>>>>>+#define TYPE_PCI_HOST_BRIDGE_SNOOPED_CLASS(klass) \
> >>>>>>+     OBJECT_CLASS_CHECK(PCIHostBridgeSnoopedClass, (klass), \
> >>>>>>+                        TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>>>>>+#define PCI_HOST_BRIDGE_SNOOPED_GET_CLASS(obj) \
> >>>>>>+     OBJECT_GET_CLASS(PCIHostBridgeSnoopedClass, (obj), \
> >>>>>>+                      TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>>>>>+#define PCI_HOST_BRIDGE_SNOOPED(obj) \
> >>>>>>+     INTERFACE_CHECK(PCIHostState, (obj), \
> >>>>>>+                     TYPE_PCI_HOST_BRIDGE_SNOOPED)
> >>>>>>+
> >>>>>>+typedef struct PCIHostBridgeSnoopedClass {
> >>>>>>+    /* <private> */
> >>>>>>+    InterfaceClass parent_class;
> >>>>>>+
> >>>>>>+    /* <public> */
> >>>>>>+    GPtrArray *(*snooping_hosts)(PCIHostState *);
> >>>>>
> >>>>>Why not just add GPtrArray here directly, and add an API to
> >>>>>register/deregister?
> >>>>The interface concentrates on usage, letting the way to fill the snooping
> >>>>hosts to the specific implementation.
> >>>>
> >>>>Thanks,
> >>>>Marcel
> >>>
> >>>IMO this is overdoing abstractions.
> >>It will provide us with enough elasticity when we'll try the same for Q35.
> >>Also this interface is used in several places and it will serve us when we'll go for Q35.
> >
> >I don't see how it helps, we don't just stick a virtual function
> >in front of all new code we write on the assumption it
> >helps elasticity.
> It helps by letting us querying the interface instead of asking:
> Is this host-bridge PIIX ? look for child buses and see if there are roots
> else: is this host-bridge ...

But what does not help is all the indirection and hiding.


> >
> >>>
> >>>But all this might be moot, it's probably better to just
> >>>add everyone to the child bus list, and drop the
> >>>concept of snooping config cycles.
> >>Well, this will be a problem, since the whole concept of the PXB is to snoop
> >>on the configuration cycles and this interface gives us a more easy
> >>way to understand the implementation.
> >>
> >>We already discussed this approach and was accepted.
> >>The code is small and concise and the use of QOM makes sense in my opinion.
> >>I prefer not to re-open it now.
> >>
> >>Thanks,
> >>Marcel
> >
> >I'm talking about the implementation here.
> >We already scan the child bus list on config
> >transactions. Why not add your entry there,
> >then you can snoop to your heart's content.
> Maybe I didn't fully understand what you want.
> Do you want to add the new root buses as child buses of root bus 0?
> This interface is not used in this context, is used in other scenarios:
> [PATCH V6 for-2.3 21/26] hw/pci: inform bios if the system has extra pci root buses
> [PATCH V6 for-2.3 15/26] hw/acpi: add support for i440fx 'snooping' root busses
> 
> I can look for other usages, can you tell me how it will look without this interface?
> 
> Other thing, in config we have pci_data_write calling (in the end) pci_find_bus_nr that does  not support
> multiple root buses.
> Changing it could affect a lot of functionality and also looking at the function it will not be pretty or clear.
> Keeping it at host-bridge level (see  [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement TYPE_PCI_HOST_BRIDGE_SNOOPED interface)
> and having piix query its pxbs for the extra root buses seems a good fit.
> 
> 
> Thanks,
> Marce

Really ideally we would just have a P2P bridge.
This is what we wanted originally: declare a bridge as
a pci host in ACPI.
Unfortunately you tried, and said this confuses guests, so we don't make
this device look like a bridge to guests.  But it still can/should make
it look just like a bridge to qemu, and all the machinery for forwarding
config transactions will mostly work.

One thing that won't work is the funky unrolled recursion in
pci_find_bus_nr, since that assumes each bridge has
a bus range. I guess we'll just have to make it recursive.


> >
> >
> >
> >>>
> >>>
> >>>>>
> >>>>>>+} PCIHostBridgeSnoopedClass;
> >>>>>>+
> >>>>>>  /* common internal helpers for PCI/PCIe hosts, cut off overflows */
> >>>>>>  void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
> >>>>>>                                    uint32_t limit, uint32_t val, uint32_t len);
> >>>>>>--
> >>>>>>2.1.0

^ permalink raw reply	[flat|nested] 61+ messages in thread

end of thread, other threads:[~2015-04-28 10:45 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-19 18:52 [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 01/26] acpi: add aml_or() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 02/26] acpi: add aml_add() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 03/26] acpi: add aml_lless() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 04/26] acpi: add aml_index() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 05/26] acpi: add aml_shiftleft() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 06/26] acpi: add aml_shiftright() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 07/26] acpi: add aml_increment() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 08/26] acpi: add aml_while() term Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files Marcel Apfelbaum
2015-04-27 11:14   ` Michael S. Tsirkin
2015-04-27 11:35     ` Paolo Bonzini
2015-04-27 11:49       ` Marcel Apfelbaum
2015-04-27 12:24         ` Michael S. Tsirkin
2015-04-28  7:31       ` Markus Armbruster
2015-04-28  8:25         ` Marcel Apfelbaum
2015-04-27 12:26     ` Marcel Apfelbaum
2015-04-28  8:30       ` Michael S. Tsirkin
2015-04-28  8:30         ` Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 10/26] hw/pci: made pci_bus_is_root a PCIBusClass method Marcel Apfelbaum
2015-04-27 11:37   ` Michael S. Tsirkin
2015-04-27 11:49     ` Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 11/26] hw/pci: made pci_bus_num " Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 12/26] hw/pci: introduce TYPE_PCI_MAIN_HOST_BRIDGE interface Marcel Apfelbaum
2015-04-27 11:24   ` Michael S. Tsirkin
2015-04-27 12:30     ` Marcel Apfelbaum
2015-04-27 12:48       ` Michael S. Tsirkin
2015-04-27 13:04         ` Marcel Apfelbaum
2015-04-27 20:54           ` Michael S. Tsirkin
2015-04-28  8:33             ` Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 13/26] hw/pci-host: introduce TYPE_PCI_HOST_BRIDGE_SNOOPED interface Marcel Apfelbaum
2015-04-27 12:14   ` Michael S. Tsirkin
2015-04-27 13:01     ` Marcel Apfelbaum
2015-04-27 14:45       ` Michael S. Tsirkin
2015-04-28  8:39         ` Marcel Apfelbaum
2015-04-28  8:43           ` Michael S. Tsirkin
2015-04-28 10:21             ` Marcel Apfelbaum
2015-04-28 10:44               ` Michael S. Tsirkin
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 14/26] hw/pci-host/piix: implement " Marcel Apfelbaum
2015-04-27 12:23   ` Michael S. Tsirkin
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 15/26] hw/acpi: add support for i440fx 'snooping' root busses Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 16/26] hw/apci: add _PRT method for extra PCI " Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 17/26] hw/acpi: add _CRS method for extra " Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 18/26] hw/acpi: remove from root bus 0 the crs resources used by other busses Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 19/26] hw/pci: removed 'rootbus nr is 0' assumption from qmp_pci_query Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 20/26] hw/pci: introduce PCI Expander Bridge (PXB) Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 21/26] hw/pci: inform bios if the system has extra pci root buses Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 22/26] hw/pxb: add map_irq func Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 23/26] hw/pci_bus: add support for NUMA nodes Marcel Apfelbaum
2015-03-19 18:52 ` [Qemu-devel] [PATCH V6 for-2.3 24/26] hw/pxb: add numa_node parameter Marcel Apfelbaum
2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 25/26] apci: fix PXB behaviour if used with unsupported BIOS Marcel Apfelbaum
2015-04-27 11:19   ` Michael S. Tsirkin
2015-04-27 11:51     ` Gerd Hoffmann
2015-03-19 18:53 ` [Qemu-devel] [PATCH V6 for-2.3 26/26] docs: Add PXB documentation Marcel Apfelbaum
2015-03-19 21:45 ` [Qemu-devel] [PATCH V6 for-2.3 00/26] hw/pc: implement multiple primary busses for pc machines Paolo Bonzini
2015-03-20  8:37   ` Marcel Apfelbaum
2015-03-20 17:56     ` Paolo Bonzini
2015-03-20 18:07       ` Peter Maydell
2015-03-20  7:44 ` Gerd Hoffmann
2015-03-20  8:25   ` Marcel Apfelbaum
2015-03-21 18:49 ` Michael S. Tsirkin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.