summary refs log tree commit diff stats
path: root/hw/spapr_vty.c
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-11-19 11:17:11 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-11-19 11:17:11 +0000
commit05a86f23e5ca83348eface349429341cefb8697b (patch)
tree6c33ddc0703342c418e697eaba72b6b0c1fafbb9 /hw/spapr_vty.c
parent15d4a723381bb57dc31007ca46661f42eb67a100 (diff)
parent1e34d859d01a408dc8479b1858bb103aa3b4f9a7 (diff)
downloadfocaccia-qemu-05a86f23e5ca83348eface349429341cefb8697b.tar.gz
focaccia-qemu-05a86f23e5ca83348eface349429341cefb8697b.zip
Merge branch 'ppc-1.0' of git://repo.or.cz/qemu/agraf
* 'ppc-1.0' of git://repo.or.cz/qemu/agraf:
  pseries: Fix qdev.id handling in the VIO bus code
  pseries: Allow kernel's early debug output to work
  pseries: Default reg for vty should be SPAPR_VTY_BASE_ADDRESS
  pseries: Check we have a chardev in spapr_vty_init()
  pseries: Fix buggy spapr_vio_find_by_reg()
  pseries: Correct RAM size check for SLOF
  PPC: Fix for the gdb single step problem on an rfi instruction
  tcg-ppc64: Fix compile errors for userspace only builds with gcc 4.6
  pseries: Fix initialization of sPAPREnvironment structure
Diffstat (limited to 'hw/spapr_vty.c')
-rw-r--r--hw/spapr_vty.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index a9d4b035e2..f23cc36231 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -58,12 +58,20 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
 {
     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
 
+    if (!dev->chardev) {
+        fprintf(stderr, "spapr-vty: Can't create vty without a chardev!\n");
+        exit(1);
+    }
+
     qemu_chr_add_handlers(dev->chardev, vty_can_receive,
                           vty_receive, NULL, dev);
 
     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)
 {
@@ -71,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;
     }
@@ -97,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;
     }
@@ -140,12 +150,35 @@ static VIOsPAPRDeviceInfo spapr_vty = {
     .qdev.name = "spapr-vty",
     .qdev.size = sizeof(VIOsPAPRVTYDevice),
     .qdev.props = (Property[]) {
-        DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, 0, 0),
+        DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
         DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
 
+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);