summary refs log tree commit diff stats
path: root/hw/spapr_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/spapr_vty.c')
-rw-r--r--hw/spapr_vty.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 815039501f..f23cc36231 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -69,6 +69,9 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
     return 0;
 }
 
+/* Forward declaration */
+static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
+
 static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
@@ -76,9 +79,10 @@ static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
     target_ulong len = args[1];
     target_ulong char0_7 = args[2];
     target_ulong char8_15 = args[3];
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev;
     uint8_t buf[16];
 
+    sdev = vty_lookup(spapr, reg);
     if (!sdev) {
         return H_PARAMETER;
     }
@@ -102,9 +106,10 @@ static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr,
     target_ulong *len = args + 0;
     target_ulong *char0_7 = args + 1;
     target_ulong *char8_15 = args + 2;
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    VIOsPAPRDevice *sdev;
     uint8_t buf[16];
 
+    sdev = vty_lookup(spapr, reg);
     if (!sdev) {
         return H_PARAMETER;
     }
@@ -151,6 +156,29 @@ static VIOsPAPRDeviceInfo spapr_vty = {
     },
 };
 
+static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
+{
+    VIOsPAPRDevice *sdev;
+
+    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
+    if (!sdev && reg == 0) {
+        DeviceState *qdev;
+
+        /* Hack for kernel early debug, which always specifies reg==0.
+         * We search all VIO devices, and grab the first available vty
+         * device.  This attempts to mimic existing PowerVM behaviour
+         * (early debug does work there, despite having no vty with
+         * reg==0. */
+        QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
+            if (qdev->info == &spapr_vty.qdev) {
+                return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
+            }
+        }
+    }
+
+    return sdev;
+}
+
 static void spapr_vty_register(void)
 {
     spapr_vio_bus_register_withprop(&spapr_vty);