aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-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 8150395..f23cc36 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);