Commit b6203fdf48 for qemu.org

commit b6203fdf4824b14460ed077793afe8f2bb49b336
Author: Craig Lalley <mr_lalley@yahoo.com>
Date:   Mon Sep 28 09:12:42 2026 -0700

    hw/hppa: Place the second Elroy of the A400 on rope 2

    On the A400 (and A500) the second Elroy PCI host bridge is connected
    to Astro rope 2 at HPA 0xfed34000 (hardware path [0:2]), not to rope 1
    at 0xfed32000 as on the C3700.

    Add an Astro property "elroy1-on-rope2" which places the second Elroy
    at 0xfed34000 on rope 2, including its LMMIO and GMMIO windows, and
    set it for the A400.  The C3700 is unchanged.

    This pairs with the SeaBIOS-hppa change "parisc/a400: Second Elroy is
    at 0xfed34000 on rope 2", which reports the Elroy at that address.  No
    PCI devices are attached behind the second Elroy by default.

    Signed-off-by: Craig Lalley <mr_lalley@yahoo.com>
    Signed-off-by: Helge Deller <deller@gmx.de>

diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h
index e2b2faa4a3..615b422865 100644
--- a/hw/hppa/hppa_hardware.h
+++ b/hw/hppa/hppa_hardware.h
@@ -31,6 +31,7 @@
 #define ASTRO_HPA       0xfed00000
 #define ELROY0_HPA      0xfed30000
 #define ELROY2_HPA      0xfed32000
+#define ELROY4_HPA      0xfed34000      /* second Elroy on A400/A500, rope 2 */
 #define ELROY8_HPA      0xfed38000
 #define ELROYc_HPA      0xfed3c000
 #define ASTRO_MEMORY_HPA 0xfed10200
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index df25877cb1..fb3ef25f04 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -740,6 +740,8 @@ static AstroState *astro_init(bool is_a400)
                             &error_abort);
     object_property_set_bool(OBJECT(dev), "rotate-pci-pins", is_a400,
                              &error_abort);
+    object_property_set_bool(OBJECT(dev), "elroy1-on-rope2", is_a400,
+                             &error_abort);
     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

     return ASTRO_CHIP(dev);
diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c
index c024dab858..c688418ded 100644
--- a/hw/pci-host/astro.c
+++ b/hw/pci-host/astro.c
@@ -41,6 +41,23 @@ static const int elroy_hpa_offsets[ELROY_NUM] = {
 static const char elroy_rope_nr[ELROY_NUM] = {
             0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */

+/* On the A400 the second Elroy is connected to rope 2 */
+static int astro_elroy_hpa_offset(AstroState *s, int i)
+{
+    if (i == 1 && s->elroy1_on_rope2) {
+        return ELROY4_HPA - ASTRO_HPA;
+    }
+    return elroy_hpa_offsets[i];
+}
+
+static int astro_elroy_rope_nr(AstroState *s, int i)
+{
+    if (i == 1 && s->elroy1_on_rope2) {
+        return 2;
+    }
+    return elroy_rope_nr[i];
+}
+
 /* Astro version numbers */
 enum { ID_ASTRO_1_0 = 0, ID_ASTRO_2_1 = 9, ID_ASTRO_3_0 = 2 };

@@ -589,7 +606,7 @@ static void adjust_LMMIO_mapping(AstroState *s)

         elroy = s->elroy[i];
         alias = &elroy->lmmio_alias;
-        rope = elroy_rope_nr[i];
+        rope = astro_elroy_rope_nr(s, i);
         if (alias->enabled) {
             memory_region_set_enabled(alias, false);
         }
@@ -715,7 +732,7 @@ static void adjust_GMMIO_mapping(AstroState *s)

         elroy = s->elroy[i];
         alias = &elroy->gmmio_alias;
-        rope = elroy_rope_nr[i];
+        rope = astro_elroy_rope_nr(s, i);
         if (alias->enabled) {
             memory_region_set_enabled(alias, false);
         }
@@ -1017,8 +1034,8 @@ static void astro_realize(DeviceState *obj, Error **errp)
         uint64_t map_size;
         int rope;

-        addr_offset = elroy_hpa_offsets[i];
-        rope = elroy_rope_nr[i];
+        addr_offset = astro_elroy_hpa_offset(s, i);
+        rope = astro_elroy_rope_nr(s, i);

         elroy = elroy_init(i);
         s->elroy[i] = elroy;
@@ -1070,6 +1087,7 @@ static void astro_realize(DeviceState *obj, Error **errp)
 static const Property astro_props[] = {
     DEFINE_PROP_UINT8("phys-addr-bits", AstroState, phys_addr_bits, 32),
     DEFINE_PROP_BOOL("rotate-pci-pins", AstroState, rotate_pci_pins, false),
+    DEFINE_PROP_BOOL("elroy1-on-rope2", AstroState, elroy1_on_rope2, false),
 };

 static void astro_class_init(ObjectClass *klass, const void *data)
diff --git a/include/hw/pci-host/astro.h b/include/hw/pci-host/astro.h
index 3297cd2e62..30d7a0b332 100644
--- a/include/hw/pci-host/astro.h
+++ b/include/hw/pci-host/astro.h
@@ -85,6 +85,7 @@ struct AstroState {

     uint8_t phys_addr_bits;
     bool rotate_pci_pins;       /* PCI INTx pin rotation (A400) */
+    bool elroy1_on_rope2;       /* second Elroy on rope 2 (A400) */

     struct ElroyState *elroy[ELROY_NUM];