[SeaBIOS] [PATCH v5 1/4] hw/pci: introduce pcie-pci-bridge device

2017-08-10 Thread Aleksandr Bezzubikov
Introduce a new PCIExpress-to-PCI Bridge device,
which is a hot-pluggable PCI Express device and
supports devices hot-plug with SHPC.

This device is intended to replace the DMI-to-PCI Bridge.

Signed-off-by: Aleksandr Bezzubikov 
---
 hw/pci-bridge/Makefile.objs |   2 +-
 hw/pci-bridge/pcie_pci_bridge.c | 192 
 include/hw/pci/pci.h|   1 +
 3 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 hw/pci-bridge/pcie_pci_bridge.c

diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index c4683cf..666db37 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y += pci_bridge_dev.o
+common-obj-y += pci_bridge_dev.o pcie_pci_bridge.o
 common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o
 common-obj-$(CONFIG_PXB) += pci_expander_bridge.o
 common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c
new file mode 100644
index 000..9aa5cc3
--- /dev/null
+++ b/hw/pci-bridge/pcie_pci_bridge.c
@@ -0,0 +1,192 @@
+/*
+ * QEMU Generic PCIE-PCI Bridge
+ *
+ * Copyright (c) 2017 Aleksandr Bezzubikov
+ *
+ * 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 "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/shpc.h"
+#include "hw/pci/slotid_cap.h"
+
+typedef struct PCIEPCIBridge {
+/*< private >*/
+PCIBridge parent_obj;
+
+OnOffAuto msi;
+MemoryRegion shpc_bar;
+/*< public >*/
+} PCIEPCIBridge;
+
+#define TYPE_PCIE_PCI_BRIDGE_DEV "pcie-pci-bridge"
+#define PCIE_PCI_BRIDGE_DEV(obj) \
+OBJECT_CHECK(PCIEPCIBridge, (obj), TYPE_PCIE_PCI_BRIDGE_DEV)
+
+static void pcie_pci_bridge_realize(PCIDevice *d, Error **errp)
+{
+PCIBridge *br = PCI_BRIDGE(d);
+PCIEPCIBridge *pcie_br = PCIE_PCI_BRIDGE_DEV(d);
+int rc, pos;
+
+pci_bridge_initfn(d, TYPE_PCI_BUS);
+
+d->config[PCI_INTERRUPT_PIN] = 0x1;
+memory_region_init(_br->shpc_bar, OBJECT(d), "shpc-bar",
+   shpc_bar_size(d));
+rc = shpc_init(d, >sec_bus, _br->shpc_bar, 0, errp);
+if (rc) {
+goto error;
+}
+
+rc = pcie_cap_init(d, 0, PCI_EXP_TYPE_PCI_BRIDGE, 0, errp);
+if (rc < 0) {
+goto cap_error;
+}
+
+pos = pci_add_capability(d, PCI_CAP_ID_PM, 0, PCI_PM_SIZEOF, errp);
+if (pos < 0) {
+goto pm_error;
+}
+d->exp.pm_cap = pos;
+pci_set_word(d->config + pos + PCI_PM_PMC, 0x3);
+
+pcie_cap_arifwd_init(d);
+pcie_cap_deverr_init(d);
+
+rc = pcie_aer_init(d, PCI_ERR_VER, 0x100, PCI_ERR_SIZEOF, errp);
+if (rc < 0) {
+goto aer_error;
+}
+
+if (pcie_br->msi != ON_OFF_AUTO_OFF) {
+rc = msi_init(d, 0, 1, true, true, errp);
+if (rc < 0) {
+goto msi_error;
+}
+}
+pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_TYPE_64, _br->shpc_bar);
+return;
+
+msi_error:
+pcie_aer_exit(d);
+aer_error:
+pm_error:
+pcie_cap_exit(d);
+cap_error:
+shpc_free(d);
+error:
+pci_bridge_exitfn(d);
+}
+
+static void pcie_pci_bridge_exit(PCIDevice *d)
+{
+PCIEPCIBridge *bridge_dev = PCIE_PCI_BRIDGE_DEV(d);
+pcie_cap_exit(d);
+shpc_cleanup(d, _dev->shpc_bar);
+pci_bridge_exitfn(d);
+}
+
+static void pcie_pci_bridge_reset(DeviceState *qdev)
+{
+PCIDevice *d = PCI_DEVICE(qdev);
+pci_bridge_reset(qdev);
+msi_reset(d);
+shpc_reset(d);
+}
+
+static void pcie_pci_bridge_write_config(PCIDevice *d,
+uint32_t address, uint32_t val, int len)
+{
+pci_bridge_write_config(d, address, val, len);
+msi_write_config(d, address, val, len);
+shpc_cap_write_config(d, address, val, len);
+}
+
+static Property pcie_pci_bridge_dev_properties[] = {
+DEFINE_PROP_ON_OFF_AUTO("msi", PCIEPCIBridge, msi, ON_OFF_AUTO_ON),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription pcie_pci_bridge_dev_vmstate = {
+.name = TYPE_PCIE_PCI_BRIDGE_DEV,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
+SHPC_VMSTATE(shpc, PCIDevice, NULL),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void pcie_pci_bridge_hotplug_cb(HotplugHandler *hotplug_dev,
+  DeviceState *dev, Error **errp)
+{
+PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
+
+if (!shpc_present(pci_hotplug_dev)) {
+error_setg(errp, "standard hotplug controller has been disabled for "
+   "this %s", TYPE_PCIE_PCI_BRIDGE_DEV);
+return;
+}
+shpc_device_hotplug_cb(hotplug_dev, dev, errp);
+}
+
+static void 

[SeaBIOS] [PATCH v5 0/4] Generic PCIE-PCI Bridge

2017-08-10 Thread Aleksandr Bezzubikov
This series introduces a new device - Generic PCI Express to PCI bridge,
and also makes all necessary changes to enable hotplug of the bridge itself
and any device into the bridge.

Changes v4->v5:
1. Change PCIE-PCI Bridge license (addresses Marcel's comment)
2. The capability layout changes (adress Laszlo' comments): 
- separate pref_mem into pref_mem_32 and pref_mem_64 fields (SeaBIOS side 
has the same changes)
- accordingly change the Generic Root Port's properties
3. Do not add the capability to the root port if no valid values are provided 
(adresses Michael's comment)
4. Rename the capability type to 'RESOURCE_RESERVE' (addresses Marcel's comment)
5. Remove shpc_present check function (addresses Marcel's comment)
6. Fix the 4th patch message (adresses Michael's comment)
7. Patch for SHPC enabling in _OSC method has been already merged

Changes v3->v4:
1. PCIE-PCI Bridge device: "msi_enable"->"msi", "shpc"->"shpc_bar", remove 
local_err,
   make "msi" property OnOffAuto, shpc_present() is still here 
   to avoid SHPC_VMSTATE refactoring (address Marcel's comments). 
2. Change QEMU PCI capability layout (SeaBIOS side has the same changes):
  - change reservation fields types: bus_res - uint32_t, others - uint64_t
  - rename 'non_pref' and 'pref' fields
  - interpret -1 value as 'ignore'
3. Use parent_realize in Generic PCI Express Root Port properly.
4. Fix documentation: fully replace the DMI-PCI bridge references with the new 
PCIE-PCI bridge,
"PCIE"->"PCI Express", small mistakes and typos - address Laszlo's and Marcel's 
comments.
5. Rename QEMU PCI cap creation fucntion - addresses Marcel's comment.

Changes v2->v3:
(0). 'do_not_use' capability field flag is still _not_ in here since we haven't 
come to consesus on it yet.
1. Merge commits 5 (bus_reserve property creation) and 6 (property usage) 
together - addresses Michael's comment.
2. Add 'bus_reserve' property and QEMU PCI capability only to Generic PCIE Root 
Port - addresses Michael's and Marcel's comments.
3. Change 'bus_reserve' property's default value to 0 - addresses Michael's 
comment.
4. Rename QEMU bridge-specific PCI capability creation function - addresses 
Michael's comment.
5. Init the whole QEMU PCI capability with zeroes - addresses Michael's and 
Laszlo's comments.
6. Change QEMU PCI capability layout (SeaBIOS side has the same changes)
  - add 'type' field to distinguish multiple 
RedHat-specific capabilities - addresses Michael's comment
  - do not mimiс PCI Config space register layout, but use mutually exclusive 
differently
sized fields for IO and prefetchable memory limits - addresses Laszlo's 
comment
7. Correct error handling in PCIE-PCI bridge realize function.
8. Replace a '2' constant with PCI_CAP_FLAGS in the capability creation 
function - addresses Michael's comment.
9. Remove a comment on _OSC which isn't correct anymore - address Marcel's 
comment.
10. Add documentation for the Generic PCIE-PCI Bridge and QEMU PCI capability - 
addresses Michael's comment.

Changes v1->v2:
1. Enable SHPC for the bridge.
2. Enable SHPC support for the Q35 machine (ACPI stuff).
3. Introduce PCI capability to help firmware on the system init.
   This allows the bridge to be hotpluggable. Now it's supported 
   only for pcie-root-port. Now it's supposed to used with 
   SeaBIOS only, look at the SeaBIOS corresponding series
   "Allow RedHat PCI bridges reserve more buses than necessary during init".

Aleksandr Bezzubikov (4):
  hw/pci: introduce pcie-pci-bridge device
  hw/pci: introduce bridge-only vendor-specific capability to provide
some hints to firmware
  hw/pci: add QEMU-specific PCI capability to the Generic PCI Express
Root Port
  docs: update documentation considering PCIE-PCI bridge

 docs/pcie.txt  |  49 +-
 docs/pcie_pci_bridge.txt   | 115 ++
 hw/pci-bridge/Makefile.objs|   2 +-
 hw/pci-bridge/gen_pcie_root_port.c |  36 +++
 hw/pci-bridge/pcie_pci_bridge.c| 192 +
 hw/pci/pci_bridge.c|  54 +++
 include/hw/pci/pci.h   |   1 +
 include/hw/pci/pci_bridge.h|  24 +
 include/hw/pci/pcie_port.h |   1 +
 9 files changed, 450 insertions(+), 24 deletions(-)
 create mode 100644 docs/pcie_pci_bridge.txt
 create mode 100644 hw/pci-bridge/pcie_pci_bridge.c

-- 
2.7.4


___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios

[SeaBIOS] [PATCH v5 4/4] docs: update documentation considering PCIE-PCI bridge

2017-08-10 Thread Aleksandr Bezzubikov
Signed-off-by: Aleksandr Bezzubikov 
---
 docs/pcie.txt|  49 ++--
 docs/pcie_pci_bridge.txt | 115 +++
 2 files changed, 141 insertions(+), 23 deletions(-)
 create mode 100644 docs/pcie_pci_bridge.txt

diff --git a/docs/pcie.txt b/docs/pcie.txt
index 5bada24..76b85ec 100644
--- a/docs/pcie.txt
+++ b/docs/pcie.txt
@@ -46,7 +46,7 @@ Place only the following kinds of devices directly on the 
Root Complex:
 (2) PCI Express Root Ports (ioh3420), for starting exclusively PCI Express
 hierarchies.
 
-(3) DMI-PCI Bridges (i82801b11-bridge), for starting legacy PCI
+(3) PCI Express to PCI Bridge (pcie-pci-bridge), for starting legacy PCI
 hierarchies.
 
 (4) Extra Root Complexes (pxb-pcie), if multiple PCI Express Root Buses
@@ -55,18 +55,18 @@ Place only the following kinds of devices directly on the 
Root Complex:
pcie.0 bus

 |||  |
-   ---   --   --   --
-   | PCI Dev |   | PCIe Root Port |   | DMI-PCI Bridge |   |  pxb-pcie  |
-   ---   --   --   --
+   ---   --   ---   --
+   | PCI Dev |   | PCIe Root Port |   | PCIe-PCI Bridge |   |  pxb-pcie  |
+   ---   --   ---   --
 
 2.1.1 To plug a device into pcie.0 as a Root Complex Integrated Endpoint use:
   -device [,bus=pcie.0]
 2.1.2 To expose a new PCI Express Root Bus use:
   -device pxb-pcie,id=pcie.1,bus_nr=x[,numa_node=y][,addr=z]
-  Only PCI Express Root Ports and DMI-PCI bridges can be connected
-  to the pcie.1 bus:
+  PCI Express Root Ports and PCI Express to PCI bridges can be
+  connected to the pcie.1 bus:
   -device 
ioh3420,id=root_port1[,bus=pcie.1][,chassis=x][,slot=y][,addr=z]
 \
-  -device i82801b11-bridge,id=dmi_pci_bridge1,bus=pcie.1
+  -device pcie-pci-bridge,id=pcie_pci_bridge1,bus=pcie.1
 
 
 2.2 PCI Express only hierarchy
@@ -130,24 +130,24 @@ Notes:
 Legacy PCI devices can be plugged into pcie.0 as Integrated Endpoints,
 but, as mentioned in section 5, doing so means the legacy PCI
 device in question will be incapable of hot-unplugging.
-Besides that use DMI-PCI Bridges (i82801b11-bridge) in combination
-with PCI-PCI Bridges (pci-bridge) to start PCI hierarchies.
+Besides that use PCI Express to PCI Bridges (pcie-pci-bridge) in
+combination with PCI-PCI Bridges (pci-bridge) to start PCI hierarchies.
 
-Prefer flat hierarchies. For most scenarios a single DMI-PCI Bridge
+Prefer flat hierarchies. For most scenarios a single PCI Express to PCI Bridge
 (having 32 slots) and several PCI-PCI Bridges attached to it
 (each supporting also 32 slots) will support hundreds of legacy devices.
-The recommendation is to populate one PCI-PCI Bridge under the DMI-PCI Bridge
-until is full and then plug a new PCI-PCI Bridge...
+The recommendation is to populate one PCI-PCI Bridge under the
+PCI Express to PCI Bridge until is full and then plug a new PCI-PCI Bridge...
 
pcie.0 bus
--
 ||
-   ---   --
-   | PCI Dev |   | DMI-PCI BRIDGE |
-   ----
+   ---   ---
+   | PCI Dev |   | PCIe-PCI Bridge |
+   ---   ---
||
   ----
-  | PCI-PCI Bridge || PCI-PCI Bridge |   ...
+  | PCI-PCI Bridge || PCI-PCI Bridge |
   ----
  |   |
   --- ---
@@ -157,11 +157,11 @@ until is full and then plug a new PCI-PCI Bridge...
 2.3.1 To plug a PCI device into pcie.0 as an Integrated Endpoint use:
   -device [,bus=pcie.0]
 2.3.2 Plugging a PCI device into a PCI-PCI Bridge:
-  -device i82801b11-bridge,id=dmi_pci_bridge1[,bus=pcie.0] 
   \
-  -device 
pci-bridge,id=pci_bridge1,bus=dmi_pci_bridge1[,chassis_nr=x][,addr=y]   \
+  -device pcie-pci-bridge,id=pcie_pci_bridge1[,bus=pcie.0] \
+  -device 
pci-bridge,id=pci_bridge1,bus=pcie_pci_bridge1[,chassis_nr=x][,addr=y] \
   -device ,bus=pci_bridge1[,addr=x]
   Note that 'addr' cannot be 0 unless shpc=off parameter is passed to
-  the PCI Bridge.
+  the PCI Bridge/PCI Express to PCI Bridge.
 
 3. IO space issues
 ===
@@ -219,14 +219,16 @@ do not support hot-plug, so 

[SeaBIOS] [PATCH v5 3/4] hw/pci: add QEMU-specific PCI capability to the Generic PCI Express Root Port

2017-08-10 Thread Aleksandr Bezzubikov
To enable hotplugging of a newly created pcie-pci-bridge,
we need to tell firmware (e.g. SeaBIOS) to reserve
additional buses or IO/MEM/PREF space for pcie-root-port.
Additional bus reservation allows us to hotplug pcie-pci-bridge into this root 
port.
The number of buses and IO/MEM/PREF space to reserve are provided to the device 
via
a corresponding property, and to the firmware via new PCI capability.
The properties' default values are -1 to keep default behavior unchanged.

Signed-off-by: Aleksandr Bezzubikov 
Reviewed-by: Marcel Apfelbaum 
---
 hw/pci-bridge/gen_pcie_root_port.c | 36 
 include/hw/pci/pcie_port.h |  1 +
 2 files changed, 37 insertions(+)

diff --git a/hw/pci-bridge/gen_pcie_root_port.c 
b/hw/pci-bridge/gen_pcie_root_port.c
index cb694d6..bd65479 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -16,6 +16,8 @@
 #include "hw/pci/pcie_port.h"
 
 #define TYPE_GEN_PCIE_ROOT_PORT"pcie-root-port"
+#define GEN_PCIE_ROOT_PORT(obj) \
+OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT)
 
 #define GEN_PCIE_ROOT_PORT_AER_OFFSET   0x100
 #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR   1
@@ -26,6 +28,13 @@ typedef struct GenPCIERootPort {
 /*< public >*/
 
 bool migrate_msix;
+
+/* additional resources to reserve on firmware init */
+uint32_t bus_reserve;
+uint64_t io_reserve;
+uint32_t mem_reserve;
+uint32_t pref32_reserve;
+uint64_t pref64_reserve;
 } GenPCIERootPort;
 
 static uint8_t gen_rp_aer_vector(const PCIDevice *d)
@@ -60,6 +69,24 @@ static bool gen_rp_test_migrate_msix(void *opaque, int 
version_id)
 return rp->migrate_msix;
 }
 
+static void gen_rp_realize(DeviceState *dev, Error **errp)
+{
+PCIDevice *d = PCI_DEVICE(dev);
+GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d);
+PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
+
+rpc->parent_realize(dev, errp);
+
+int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve,
+grp->io_reserve, grp->mem_reserve, grp->pref32_reserve,
+grp->pref64_reserve, errp);
+
+if (rc < 0) {
+rpc->parent_class.exit(d);
+return;
+}
+}
+
 static const VMStateDescription vmstate_rp_dev = {
 .name = "pcie-root-port",
 .version_id = 1,
@@ -78,6 +105,11 @@ static const VMStateDescription vmstate_rp_dev = {
 
 static Property gen_rp_props[] = {
 DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true),
+DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1),
+DEFINE_PROP_UINT64("io-reserve", GenPCIERootPort, io_reserve, -1),
+DEFINE_PROP_UINT32("mem-reserve", GenPCIERootPort, mem_reserve, -1),
+DEFINE_PROP_UINT32("pref32-reserve", GenPCIERootPort, pref32_reserve, -1),
+DEFINE_PROP_UINT64("pref64-reserve", GenPCIERootPort, pref64_reserve, -1),
 DEFINE_PROP_END_OF_LIST()
 };
 
@@ -92,6 +124,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void 
*data)
 dc->desc = "PCI Express Root Port";
 dc->vmsd = _rp_dev;
 dc->props = gen_rp_props;
+
+rpc->parent_realize = dc->realize;
+dc->realize = gen_rp_realize;
+
 rpc->aer_vector = gen_rp_aer_vector;
 rpc->interrupts_init = gen_rp_interrupts_init;
 rpc->interrupts_uninit = gen_rp_interrupts_uninit;
diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index 1333266..0736014 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s);
 
 typedef struct PCIERootPortClass {
 PCIDeviceClass parent_class;
+DeviceRealize parent_realize;
 
 uint8_t (*aer_vector)(const PCIDevice *dev);
 int (*interrupts_init)(PCIDevice *dev, Error **errp);
-- 
2.7.4


___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios


[SeaBIOS] [PATCH v5 2/4] hw/pci: introduce bridge-only vendor-specific capability to provide some hints to firmware

2017-08-10 Thread Aleksandr Bezzubikov
On PCI init PCI bridges may need some extra info about bus number,
IO, memory and prefetchable memory to reserve. QEMU can provide this
with a special vendor-specific PCI capability.

Signed-off-by: Aleksandr Bezzubikov 
Reviewed-by: Marcel Apfelbaum 
---
 hw/pci/pci_bridge.c | 54 +
 include/hw/pci/pci_bridge.h | 24 
 2 files changed, 78 insertions(+)

diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index 720119b..2495a51 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -408,6 +408,60 @@ void pci_bridge_map_irq(PCIBridge *br, const char* 
bus_name,
 br->bus_name = bus_name;
 }
 
+
+int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
+  uint32_t bus_reserve, uint64_t io_reserve,
+  uint32_t mem_non_pref_reserve,
+  uint32_t mem_pref_32_reserve,
+  uint64_t mem_pref_64_reserve,
+  Error **errp)
+{
+if (mem_pref_32_reserve != (uint32_t)-1 &&
+mem_pref_64_reserve != (uint64_t) -1) {
+error_setg(errp,
+   "PCI resource reserve cap: PREF32 and PREF64 conflict");
+return -EINVAL;
+}
+
+if (bus_reserve == (uint32_t)-1 &&
+io_reserve == (uint64_t)-1 &&
+mem_non_pref_reserve == (uint32_t)-1 &&
+mem_pref_32_reserve == (uint32_t)-1 &&
+mem_pref_64_reserve == (uint64_t)-1) {
+return 0;
+}
+
+size_t cap_len = sizeof(PCIBridgeQemuCap);
+PCIBridgeQemuCap cap = {
+.len = cap_len,
+.type = REDHAT_PCI_CAP_RESOURCE_RESERVE,
+.bus_res = bus_reserve,
+.io = io_reserve,
+.mem = mem_non_pref_reserve,
+.mem_pref_32 = (uint32_t)-1,
+.mem_pref_64 = (uint64_t)-1
+};
+
+if (mem_pref_32_reserve != (uint32_t)-1 &&
+mem_pref_64_reserve == (uint64_t)-1) {
+cap.mem_pref_32 = mem_pref_32_reserve;
+} else if (mem_pref_32_reserve == (uint32_t)-1 &&
+mem_pref_64_reserve != (uint64_t)-1) {
+cap.mem_pref_64 = mem_pref_64_reserve;
+}
+
+int offset = pci_add_capability(dev, PCI_CAP_ID_VNDR,
+cap_offset, cap_len, errp);
+if (offset < 0) {
+return offset;
+}
+
+memcpy(dev->config + offset + PCI_CAP_FLAGS,
+(char *) + PCI_CAP_FLAGS,
+cap_len - PCI_CAP_FLAGS);
+return 0;
+}
+
 static const TypeInfo pci_bridge_type_info = {
 .name = TYPE_PCI_BRIDGE,
 .parent = TYPE_PCI_DEVICE,
diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
index ff7cbaa..2d8c635 100644
--- a/include/hw/pci/pci_bridge.h
+++ b/include/hw/pci/pci_bridge.h
@@ -67,4 +67,28 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
 #define  PCI_BRIDGE_CTL_DISCARD_STATUS 0x400   /* Discard timer status */
 #define  PCI_BRIDGE_CTL_DISCARD_SERR   0x800   /* Discard timer SERR# enable */
 
+typedef struct PCIBridgeQemuCap {
+uint8_t id; /* Standard PCI capability header field */
+uint8_t next;   /* Standard PCI capability header field */
+uint8_t len;/* Standard PCI vendor-specific capability header field */
+uint8_t type;   /* Red Hat vendor-specific capability type.
+   Types are defined with REDHAT_PCI_CAP_ prefix */
+
+uint32_t bus_res;   /* Minimum number of buses to reserve */
+uint64_t io;/* IO space to reserve */
+uint32_t mem;   /* Non-prefetchable memory to reserve */
+/* This two fields are mutually exclusive */
+uint32_t mem_pref_32; /* Prefetchable memory to reserve (32-bit MMIO) */
+uint64_t mem_pref_64; /* Prefetchable memory to reserve (64-bit MMIO) */
+} PCIBridgeQemuCap;
+
+#define REDHAT_PCI_CAP_RESOURCE_RESERVE 1
+
+int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset,
+  uint32_t bus_reserve, uint64_t io_reserve,
+  uint32_t mem_non_pref_reserve,
+  uint32_t mem_pref_32_reserve,
+  uint64_t mem_pref_64_reserve,
+  Error **errp);
+
 #endif /* QEMU_PCI_BRIDGE_H */
-- 
2.7.4


___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios


Re: [SeaBIOS] [PATCH v5 1/3] pci: refactor pci_find_capapibilty to get bdf as the first argument instead of the whole pci_device

2017-08-10 Thread Aleksandr Bezzubikov
>From the previous versions:

Reviewed-by: Marcel Apfelbaum 

2017-08-11 2:21 GMT+03:00 Aleksandr Bezzubikov :
> Refactor pci_find_capability function to get bdf instead of
> a whole pci_device* as the only necessary field for this function
> is still bdf.
>
> Signed-off-by: Aleksandr Bezzubikov 
> ---
>  src/fw/pciinit.c|  4 ++--
>  src/hw/pci.c| 25 +
>  src/hw/pci.h|  1 +
>  src/hw/pcidevice.c  | 24 
>  src/hw/pcidevice.h  |  1 -
>  src/hw/virtio-pci.c |  6 +++---
>  6 files changed, 31 insertions(+), 30 deletions(-)
>
> diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
> index 08221e6..864954f 100644
> --- a/src/fw/pciinit.c
> +++ b/src/fw/pciinit.c
> @@ -762,7 +762,7 @@ static int pci_bus_hotplug_support(struct pci_bus *bus, 
> u8 pcie_cap)
>  return downstream_port && slot_implemented;
>  }
>
> -shpc_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_SHPC, 0);
> +shpc_cap = pci_find_capability(bus->bus_dev->bdf, PCI_CAP_ID_SHPC, 0);
>  return !!shpc_cap;
>  }
>
> @@ -844,7 +844,7 @@ static int pci_bios_check_devices(struct pci_bus *busses)
>   */
>  parent = [0];
>  int type;
> -u8 pcie_cap = pci_find_capability(s->bus_dev, PCI_CAP_ID_EXP, 0);
> +u8 pcie_cap = pci_find_capability(s->bus_dev->bdf, PCI_CAP_ID_EXP, 
> 0);
>  int hotplug_support = pci_bus_hotplug_support(s, pcie_cap);
>  for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
>  u64 align = (type == PCI_REGION_TYPE_IO) ?
> diff --git a/src/hw/pci.c b/src/hw/pci.c
> index 8e3d617..50d9d2d 100644
> --- a/src/hw/pci.c
> +++ b/src/hw/pci.c
> @@ -58,6 +58,30 @@ pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on)
>  pci_config_writew(bdf, addr, val);
>  }
>
> +u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap)
> +{
> +int i;
> +u16 status = pci_config_readw(bdf, PCI_STATUS);
> +
> +if (!(status & PCI_STATUS_CAP_LIST))
> +return 0;
> +
> +if (cap == 0) {
> +/* find first */
> +cap = pci_config_readb(bdf, PCI_CAPABILITY_LIST);
> +} else {
> +/* find next */
> +cap = pci_config_readb(bdf, cap + PCI_CAP_LIST_NEXT);
> +}
> +for (i = 0; cap && i <= 0xff; i++) {
> +if (pci_config_readb(bdf, cap + PCI_CAP_LIST_ID) == cap_id)
> +return cap;
> +cap = pci_config_readb(bdf, cap + PCI_CAP_LIST_NEXT);
> +}
> +
> +return 0;
> +}
> +
>  // Helper function for foreachbdf() macro - return next device
>  int
>  pci_next(int bdf, int bus)
> @@ -107,3 +131,4 @@ pci_reboot(void)
>  outb(v|6, PORT_PCI_REBOOT); /* Actually do the reset */
>  udelay(50);
>  }
> +
> diff --git a/src/hw/pci.h b/src/hw/pci.h
> index ee6e196..2e30e28 100644
> --- a/src/hw/pci.h
> +++ b/src/hw/pci.h
> @@ -39,6 +39,7 @@ u32 pci_config_readl(u16 bdf, u32 addr);
>  u16 pci_config_readw(u16 bdf, u32 addr);
>  u8 pci_config_readb(u16 bdf, u32 addr);
>  void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on);
> +u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap);
>  int pci_next(int bdf, int bus);
>  int pci_probe_host(void);
>  void pci_reboot(void);
> diff --git a/src/hw/pcidevice.c b/src/hw/pcidevice.c
> index cfebf66..8853cf7 100644
> --- a/src/hw/pcidevice.c
> +++ b/src/hw/pcidevice.c
> @@ -134,30 +134,6 @@ pci_find_init_device(const struct pci_device_id *ids, 
> void *arg)
>  return NULL;
>  }
>
> -u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap)
> -{
> -int i;
> -u16 status = pci_config_readw(pci->bdf, PCI_STATUS);
> -
> -if (!(status & PCI_STATUS_CAP_LIST))
> -return 0;
> -
> -if (cap == 0) {
> -/* find first */
> -cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST);
> -} else {
> -/* find next */
> -cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
> -}
> -for (i = 0; cap && i <= 0xff; i++) {
> -if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id)
> -return cap;
> -cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
> -}
> -
> -return 0;
> -}
> -
>  // Enable PCI bus-mastering (ie, DMA) support on a pci device
>  void
>  pci_enable_busmaster(struct pci_device *pci)
> diff --git a/src/hw/pcidevice.h b/src/hw/pcidevice.h
> index 354b549..225d545 100644
> --- a/src/hw/pcidevice.h
> +++ b/src/hw/pcidevice.h
> @@ -69,7 +69,6 @@ int pci_init_device(const struct pci_device_id *ids
>  , struct pci_device *pci, void *arg);
>  struct pci_device *pci_find_init_device(const struct pci_device_id *ids
>  , void *arg);
> -u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap);
>  void pci_enable_busmaster(struct pci_device *pci);
>  u16 pci_enable_iobar(struct pci_device *pci, u32 addr);
>  void *pci_enable_membar(struct pci_device *pci, u32 

[SeaBIOS] [PATCH v5 2/3] pci: add QEMU-specific PCI capability structure

2017-08-10 Thread Aleksandr Bezzubikov
On PCI init PCI bridge devices may need some
extra info about bus number to reserve, IO, memory and
prefetchable memory limits. QEMU can provide this
with special vendor-specific PCI capability.

This capability is intended to be used only
for Red Hat PCI bridges, i.e. QEMU cooperation.

Signed-off-by: Aleksandr Bezzubikov 
---
 src/fw/dev-pci.h | 52 
 1 file changed, 52 insertions(+)
 create mode 100644 src/fw/dev-pci.h

diff --git a/src/fw/dev-pci.h b/src/fw/dev-pci.h
new file mode 100644
index 000..cf16b2e
--- /dev/null
+++ b/src/fw/dev-pci.h
@@ -0,0 +1,52 @@
+#ifndef _PCI_CAP_H
+#define _PCI_CAP_H
+
+#include "types.h"
+
+/*
+ *
+ * QEMU-specific vendor(Red Hat)-specific capability.
+ * It's intended to provide some hints for firmware to init PCI devices.
+ *
+ * Its structure is shown below:
+ *
+ * Header:
+ *
+ * u8 id;   Standard PCI Capability Header field
+ * u8 next; Standard PCI Capability Header field
+ * u8 len;  Standard PCI Capability Header field
+ * u8 type; Red Hat vendor-specific capability type
+ * Data:
+ *
+ * u32 bus_res; minimum bus number to reserve;
+ *  this is necessary for PCI Express Root Ports
+ *  to support PCI bridges hotplug
+ * u64 io;  IO space to reserve
+ * u32 mem; non-prefetchable memory to reserve
+ *
+ * this two fields are mutually exclusive:
+ * u32 prefetchable_mem_32; prefetchable memory to reserve (32-bit MMIO)
+ * u64 prefetchable_mem_64; prefetchable memory to reserve (64-bit MMIO)
+ *
+ *
+ * If any field value in Data section is 0xFF...F,
+ * it means that such kind of reservation is not needed and must be ignored.
+ *
+*/
+
+/* Offset of vendor-specific capability type field */
+#define PCI_CAP_REDHAT_TYPE_OFFSET  3
+
+/* List of valid Red Hat vendor-specific capability types */
+#define REDHAT_CAP_RESOURCE_RESERVE1
+
+
+/* Offsets of RESOURCE_RESERVE capability fields */
+#define RES_RESERVE_BUS_RES4
+#define RES_RESERVE_IO 8
+#define RES_RESERVE_MEM16
+#define RES_RESERVE_PREF_MEM_3220
+#define RES_RESERVE_PREF_MEM_6424
+#define RES_RESERVE_CAP_SIZE   32
+
+#endif /* _PCI_CAP_H */
-- 
2.7.4


___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios


[SeaBIOS] [PATCH v5 1/3] pci: refactor pci_find_capapibilty to get bdf as the first argument instead of the whole pci_device

2017-08-10 Thread Aleksandr Bezzubikov
Refactor pci_find_capability function to get bdf instead of
a whole pci_device* as the only necessary field for this function
is still bdf.

Signed-off-by: Aleksandr Bezzubikov 
---
 src/fw/pciinit.c|  4 ++--
 src/hw/pci.c| 25 +
 src/hw/pci.h|  1 +
 src/hw/pcidevice.c  | 24 
 src/hw/pcidevice.h  |  1 -
 src/hw/virtio-pci.c |  6 +++---
 6 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index 08221e6..864954f 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -762,7 +762,7 @@ static int pci_bus_hotplug_support(struct pci_bus *bus, u8 
pcie_cap)
 return downstream_port && slot_implemented;
 }
 
-shpc_cap = pci_find_capability(bus->bus_dev, PCI_CAP_ID_SHPC, 0);
+shpc_cap = pci_find_capability(bus->bus_dev->bdf, PCI_CAP_ID_SHPC, 0);
 return !!shpc_cap;
 }
 
@@ -844,7 +844,7 @@ static int pci_bios_check_devices(struct pci_bus *busses)
  */
 parent = [0];
 int type;
-u8 pcie_cap = pci_find_capability(s->bus_dev, PCI_CAP_ID_EXP, 0);
+u8 pcie_cap = pci_find_capability(s->bus_dev->bdf, PCI_CAP_ID_EXP, 0);
 int hotplug_support = pci_bus_hotplug_support(s, pcie_cap);
 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
 u64 align = (type == PCI_REGION_TYPE_IO) ?
diff --git a/src/hw/pci.c b/src/hw/pci.c
index 8e3d617..50d9d2d 100644
--- a/src/hw/pci.c
+++ b/src/hw/pci.c
@@ -58,6 +58,30 @@ pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on)
 pci_config_writew(bdf, addr, val);
 }
 
+u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap)
+{
+int i;
+u16 status = pci_config_readw(bdf, PCI_STATUS);
+
+if (!(status & PCI_STATUS_CAP_LIST))
+return 0;
+
+if (cap == 0) {
+/* find first */
+cap = pci_config_readb(bdf, PCI_CAPABILITY_LIST);
+} else {
+/* find next */
+cap = pci_config_readb(bdf, cap + PCI_CAP_LIST_NEXT);
+}
+for (i = 0; cap && i <= 0xff; i++) {
+if (pci_config_readb(bdf, cap + PCI_CAP_LIST_ID) == cap_id)
+return cap;
+cap = pci_config_readb(bdf, cap + PCI_CAP_LIST_NEXT);
+}
+
+return 0;
+}
+
 // Helper function for foreachbdf() macro - return next device
 int
 pci_next(int bdf, int bus)
@@ -107,3 +131,4 @@ pci_reboot(void)
 outb(v|6, PORT_PCI_REBOOT); /* Actually do the reset */
 udelay(50);
 }
+
diff --git a/src/hw/pci.h b/src/hw/pci.h
index ee6e196..2e30e28 100644
--- a/src/hw/pci.h
+++ b/src/hw/pci.h
@@ -39,6 +39,7 @@ u32 pci_config_readl(u16 bdf, u32 addr);
 u16 pci_config_readw(u16 bdf, u32 addr);
 u8 pci_config_readb(u16 bdf, u32 addr);
 void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on);
+u8 pci_find_capability(u16 bdf, u8 cap_id, u8 cap);
 int pci_next(int bdf, int bus);
 int pci_probe_host(void);
 void pci_reboot(void);
diff --git a/src/hw/pcidevice.c b/src/hw/pcidevice.c
index cfebf66..8853cf7 100644
--- a/src/hw/pcidevice.c
+++ b/src/hw/pcidevice.c
@@ -134,30 +134,6 @@ pci_find_init_device(const struct pci_device_id *ids, void 
*arg)
 return NULL;
 }
 
-u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap)
-{
-int i;
-u16 status = pci_config_readw(pci->bdf, PCI_STATUS);
-
-if (!(status & PCI_STATUS_CAP_LIST))
-return 0;
-
-if (cap == 0) {
-/* find first */
-cap = pci_config_readb(pci->bdf, PCI_CAPABILITY_LIST);
-} else {
-/* find next */
-cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
-}
-for (i = 0; cap && i <= 0xff; i++) {
-if (pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_ID) == cap_id)
-return cap;
-cap = pci_config_readb(pci->bdf, cap + PCI_CAP_LIST_NEXT);
-}
-
-return 0;
-}
-
 // Enable PCI bus-mastering (ie, DMA) support on a pci device
 void
 pci_enable_busmaster(struct pci_device *pci)
diff --git a/src/hw/pcidevice.h b/src/hw/pcidevice.h
index 354b549..225d545 100644
--- a/src/hw/pcidevice.h
+++ b/src/hw/pcidevice.h
@@ -69,7 +69,6 @@ int pci_init_device(const struct pci_device_id *ids
 , struct pci_device *pci, void *arg);
 struct pci_device *pci_find_init_device(const struct pci_device_id *ids
 , void *arg);
-u8 pci_find_capability(struct pci_device *pci, u8 cap_id, u8 cap);
 void pci_enable_busmaster(struct pci_device *pci);
 u16 pci_enable_iobar(struct pci_device *pci, u32 addr);
 void *pci_enable_membar(struct pci_device *pci, u32 addr);
diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c
index e5c2c33..96f9c6b 100644
--- a/src/hw/virtio-pci.c
+++ b/src/hw/virtio-pci.c
@@ -19,7 +19,7 @@
 #include "malloc.h" // free
 #include "output.h" // dprintf
 #include "pci.h" // pci_config_readl
-#include "pcidevice.h" // pci_find_capability
+#include "pcidevice.h" // struct pci_device
 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
 #include 

[SeaBIOS] [PATCH v5 3/3] pci: enable RedHat PCI bridges to reserve additional resource on PCI init

2017-08-10 Thread Aleksandr Bezzubikov
In case of Red Hat Generic PCIE Root Port reserve additional buses
and/or IO/MEM/PREF space, which values are provided in a vendor-specific 
capability.

Signed-off-by: Aleksandr Bezzubikov 
---
 src/fw/dev-pci.h |   2 +-
 src/fw/pciinit.c | 125 +--
 src/hw/pci_ids.h |   3 ++
 3 files changed, 116 insertions(+), 14 deletions(-)

diff --git a/src/fw/dev-pci.h b/src/fw/dev-pci.h
index cf16b2e..99ccc12 100644
--- a/src/fw/dev-pci.h
+++ b/src/fw/dev-pci.h
@@ -38,7 +38,7 @@
 #define PCI_CAP_REDHAT_TYPE_OFFSET  3
 
 /* List of valid Red Hat vendor-specific capability types */
-#define REDHAT_CAP_RESOURCE_RESERVE1
+#define REDHAT_CAP_RESOURCE_RESERVE 1
 
 
 /* Offsets of RESOURCE_RESERVE capability fields */
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index 864954f..d9aef56 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -15,6 +15,7 @@
 #include "hw/pcidevice.h" // pci_probe_devices
 #include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL
 #include "hw/pci_regs.h" // PCI_COMMAND
+#include "fw/dev-pci.h" // REDHAT_CAP_RESOURCE_RESERVE
 #include "list.h" // struct hlist_node
 #include "malloc.h" // free
 #include "output.h" // dprintf
@@ -522,6 +523,32 @@ static void pci_bios_init_platform(void)
 }
 }
 
+static u8 pci_find_resource_reserve_capability(u16 bdf)
+{
+if (pci_config_readw(bdf, PCI_VENDOR_ID) == PCI_VENDOR_ID_REDHAT &&
+pci_config_readw(bdf, PCI_DEVICE_ID) ==
+PCI_DEVICE_ID_REDHAT_ROOT_PORT) {
+u8 cap = 0;
+do {
+cap = pci_find_capability(bdf, PCI_CAP_ID_VNDR, cap);
+} while (cap &&
+ pci_config_readb(bdf, cap + PCI_CAP_REDHAT_TYPE_OFFSET) !=
+REDHAT_CAP_RESOURCE_RESERVE);
+if (cap) {
+u8 cap_len = pci_config_readb(bdf, cap + PCI_CAP_FLAGS);
+if (cap_len < RES_RESERVE_CAP_SIZE) {
+dprintf(1, "PCI: QEMU resource reserve cap length %d is 
invalid\n",
+cap_len);
+}
+} else {
+dprintf(1, "PCI: invalid QEMU resource reserve cap offset\n");
+}
+return cap;
+} else {
+dprintf(1, "PCI: QEMU resource reserve cap not found\n");
+return 0;
+}
+}
 
 /
  * Bus initialization
@@ -578,9 +605,28 @@ pci_bios_init_bus_rec(int bus, u8 *pci_bus)
 pci_bios_init_bus_rec(secbus, pci_bus);
 
 if (subbus != *pci_bus) {
+u8 res_bus = 0;
+u8 cap = pci_find_resource_reserve_capability(bdf);
+
+if (cap) {
+u32 tmp_res_bus = pci_config_readl(bdf,
+cap + RES_RESERVE_BUS_RES);
+if (tmp_res_bus != (u32)-1) {
+res_bus = tmp_res_bus & 0xFF;
+if ((u8)(res_bus + secbus) < secbus ||
+(u8)(res_bus + secbus) < res_bus) {
+dprintf(1, "PCI: bus_reserve value %d is invalid\n",
+res_bus);
+res_bus = 0;
+}
+}
+res_bus = (*pci_bus > secbus + res_bus) ? *pci_bus
+: secbus + res_bus;
+}
 dprintf(1, "PCI: subordinate bus = 0x%x -> 0x%x\n",
-subbus, *pci_bus);
-subbus = *pci_bus;
+subbus, res_bus);
+subbus = res_bus;
+*pci_bus = res_bus;
 } else {
 dprintf(1, "PCI: subordinate bus = 0x%x\n", subbus);
 }
@@ -844,22 +890,74 @@ static int pci_bios_check_devices(struct pci_bus *busses)
  */
 parent = [0];
 int type;
-u8 pcie_cap = pci_find_capability(s->bus_dev->bdf, PCI_CAP_ID_EXP, 0);
+u16 bdf = s->bus_dev->bdf;
+u8 pcie_cap = pci_find_capability(bdf, PCI_CAP_ID_EXP, 0);
+u8 qemu_cap = pci_find_resource_reserve_capability(bdf);
+
 int hotplug_support = pci_bus_hotplug_support(s, pcie_cap);
 for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
 u64 align = (type == PCI_REGION_TYPE_IO) ?
-PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
 if (!pci_bridge_has_region(s->bus_dev, type))
 continue;
-if (pci_region_align(>r[type]) > align)
- align = pci_region_align(>r[type]);
-u64 sum = pci_region_sum(>r[type]);
-int resource_optional = pcie_cap && (type == PCI_REGION_TYPE_IO);
-if (!sum && hotplug_support && !resource_optional)
-sum = align; /* reserve min size for hot-plug */
-u64 size = ALIGN(sum, align);
-int is64 = pci_bios_bridge_region_is64(>r[type],
-s->bus_dev, type);
+

[SeaBIOS] [PATCH v5 0/3] Red Hat PCI bridge resource reserve capability (was: Allow RedHat PCI bridges reserve more buses than necessary during init)

2017-08-10 Thread Aleksandr Bezzubikov
Now PCI bridges get a bus range number on a system init,
basing on currently plugged devices. That's why when one wants to hotplug 
another bridge,
it needs his child bus, which the parent is unable to provide (speaking about 
virtual device).
The suggested workaround is to have vendor-specific capability in Red Hat PCI 
bridges
that contains number of additional bus to reserve (as well as IO/MEM/PREF space 
limit hints) 
on BIOS PCI init.
So this capability is intended only for pure QEMU->SeaBIOS usage.

Considering all aforesaid, this series is directly connected with
QEMU series "Generic PCIE-PCI Bridge".

Although the new PCI capability is supposed to contain various limits along with
bus number to reserve, now only its full layout is proposed. And
only bus_reserve field is used in QEMU and BIOS. Limits usage
is still a subject for implementation as now
the main goal of this series to provide necessary support from the 
firmware side to PCIE-PCI bridge hotplug. 

Changes v4->v5:
1. Rename capability-related #defines
2. Move capability IO/MEM/PREF fields values usage to the regions creation 
stage (addresses Marcel's comment)
3. The capability layout change: separate pref_mem into pref_mem_32 and 
pref_mem_64 fields (QEMU side has the same changes) (addresses Laszlo's comment)
4. Extract the capability lookup and check to the separate function (addresses 
Marcel's comment)
- despite of Marcel's comment do not extract field check for -1 since 
it increases code length
  and doesn't look nice because of different field types 
5. Fix the capability's comment (addresses Marcel's comment)
6. Fix the 3rd patch message

Changes v3->v4:
1. Use all QEMU PCI capability fields - addresses Michael's comment
2. Changes of the capability layout (QEMU side has the same changes):
- change reservation fields types: bus_res - uint32_t, others - uint64_t
- interpret -1 value as 'ignore'

Changes v2->v3:
1. Merge commit 2 (Red Hat vendor ID) into commit 4 - addresses Marcel's 
comment,
and add Generic PCIE Root Port device ID - addresses Michael's comment.
2. Changes of the capability layout  (QEMU side has the same changes):
- add 'type' field to distinguish multiple 
RedHat-specific capabilities - addresses Michael's comment
- do not mimiс PCI Config space register layout, but use mutually 
exclusive differently
sized fields for IO and prefetchable memory limits - addresses 
Laszlo's comment
- use defines instead of structure and offsetof - addresses Michael's 
comment
3. Interpret 'bus_reserve' field as a minimum necessary
 range to reserve - addresses Gerd's comment
4. pci_find_capability moved to pci.c - addresses Kevin's comment
5. Move capability layout header to src/fw/dev-pci.h - addresses Kevin's comment
6. Add the capability documentation - addresses Michael's comment
7. Add capability length and bus_reserve field sanity checks - addresses 
Michael's comment

Changes v1->v2:
1. New #define for Red Hat vendor added (addresses Konrad's comment).
2. Refactored pci_find_capability function (addresses Marcel's comment).
3. Capability reworked:
- data type added;
- reserve space in a structure for IO, memory and 
  prefetchable memory limits.

Aleksandr Bezzubikov (3):
  pci: refactor pci_find_capapibilty to get bdf as the first argument
instead of the whole pci_device
  pci: add QEMU-specific PCI capability structure
  pci: enable RedHat PCI bridges to reserve additional resource on PCI
init

 src/fw/dev-pci.h|  52 +
 src/fw/pciinit.c| 127 ++--
 src/hw/pci.c|  25 +++
 src/hw/pci.h|   1 +
 src/hw/pci_ids.h|   3 ++
 src/hw/pcidevice.c  |  24 --
 src/hw/pcidevice.h  |   1 -
 src/hw/virtio-pci.c |   6 +--
 8 files changed, 197 insertions(+), 42 deletions(-)
 create mode 100644 src/fw/dev-pci.h

-- 
2.7.4


___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios

[SeaBIOS] GCC 7.1 warning in `tcgbios.c`: `'hleo.eventnumber' may be used uninitialized in this function`

2017-08-10 Thread Paul Menzel

Dear SeaBIOS folks,


GCC 7.1 warns about a maybe uninitialized struct member.

```
src/tcgbios.c: In function 'tpm_interrupt_handler32':
src/tcgbios.c:1232:30: warning: 'hleo.eventnumber' may be used 
uninitialized in this function [-Wmaybe-uninitialized]

 hleeo->eventnumber = hleo.eventnumber;
  ^~~~
  Compiling whole program out/ccode32flat.o
In file included from out/ccode32flat.o.tmp.c:52:0:
./src/tcgbios.c: In function 'tpm_interrupt_handler32':
./src/tcgbios.c:1232:30: warning: 'hleo.eventnumber' may be used 
uninitialized in this function [-Wmaybe-uninitialized]

 hleeo->eventnumber = hleo.eventnumber;
  ^~~~
```

It looks valid, as in the beginning the struct hleo is only declared.

```
1189 struct hleo hleo;
```


Kind regards,

Paul

___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios


Re: [SeaBIOS] Seabios unable to boot Fedora-based instances

2017-08-10 Thread Kevin O'Connor
On Thu, Aug 10, 2017 at 11:18:32AM +0200, Maciej Józefczyk wrote:
> Hello,
> 
> Environment: Seabios master dd9bba5b9c1d5175a2757f3fdc9d554b4c8eea3a
> Qemu: 1:2.5+dfsg-5ubuntu10.14
> OS: Ubuntu 16.04
> 
> We found that newest Seabios (dd9bba5b9c1d5175a2757f3fdc9d554b4c8eea3a)
> is not working with latest Fedora 26 - image taken from:
> https://download.fedoraproject.org/pub/fedora/linux/releases/26/CloudImages/x86_64/images/Fedora-Cloud-Base-26-1.5.x86_64.qcow2
> 
> Each time it hangs on "Probing EDD (edd=off to disable)... OK".
> 
> We discovered that rollback to version 4902b8a7 solves the problem. It
> seems that something is wrong with 4902b8a7. After fetch lastest master
> and rollback of 4902b8a7 - Fedora is able to boot.
> 
> Ubuntu is booting all the time without problem.
> 
> Could you take a look on this?

Thanks.  I do see a defect in 4902b8a7 - it is not generating linesize
correctly (see patch below).

-Kevin


--- a/vgasrc/stdvga.c
+++ b/vgasrc/stdvga.c
@@ -324,7 +324,7 @@ stdvga_set_dacformat(struct vgamode_s *vmode_g, int val)
 int
 stdvga_get_linesize(struct vgamode_s *vmode_g)
 {
-return DIV_ROUND_UP(vmode_g->width * vga_bpp(vmode_g), 8);
+return DIV_ROUND_UP(GET_GLOBAL(vmode_g->width) * vga_bpp(vmode_g), 8);
 }
 
 /

___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios


[SeaBIOS] Seabios unable to boot Fedora-based instances

2017-08-10 Thread Maciej Józefczyk
Hello,

Environment: Seabios master dd9bba5b9c1d5175a2757f3fdc9d554b4c8eea3a
Qemu: 1:2.5+dfsg-5ubuntu10.14
OS: Ubuntu 16.04

We found that newest Seabios (dd9bba5b9c1d5175a2757f3fdc9d554b4c8eea3a)
is not working with latest Fedora 26 - image taken from:
https://download.fedoraproject.org/pub/fedora/linux/releases/26/CloudImages/x86_64/images/Fedora-Cloud-Base-26-1.5.x86_64.qcow2

Each time it hangs on "Probing EDD (edd=off to disable)... OK".

We discovered that rollback to version 4902b8a7 solves the problem. It
seems that something is wrong with 4902b8a7. After fetch lastest master
and rollback of 4902b8a7 - Fedora is able to boot.

Ubuntu is booting all the time without problem.

Could you take a look on this?

Best regards
Maciej


-- 

Maciej Józefczyk
maciej.jozefc...@corp.ovh.com



___
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios