summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2011-11-13 17:19:01 +0000
committerAlexander Graf <agraf@suse.de>2011-11-18 14:22:46 +0100
commit3feef8ad17af7307373b9e88b9d7ecb98eeb99da (patch)
treed5f4f07c19d97aa51336c2095fbf3dcb62fe5760 /hw
parent5afdec404e73a578c37221b9ea226d582814acb5 (diff)
downloadqemu-3feef8ad17af7307373b9e88b9d7ecb98eeb99da.tar.gz
pseries: Allow kernel's early debug output to work
The PAPR specification defines a virtual TTY/console interface for guest OSes to use via the H_PUT_TERM_CHAR and H_GET_TERM_CHAR hypercalls. There can be multiple virtual ttys, so these take a "termno" parameter. This encodes which vty to use as the 'reg' property on the device tree node associated with that vty. However, with the early debug options enabled, the Linux kernel will attempt debugging output through the vty very early, before it has read the device tree. In this case it always uses a termno of 0. This works on the existing PowerVM hypervisor, so we assume there must be a hack / feature in there which interprets termno==0 to mean the default primary console. To help with debugging kernels, including existing distribution kernels, this patch implements a similar feature / hack in qemu. If termno==0 is supplied to H_{GET,PUT}_TERM_CHAR, they use the first available vty device instead. We need to be careful in the case that the user has manually created an spapr-vty at address 0. So first we search for the specified reg and only if that doesn't match do we fall back. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Alexander Graf <agraf@suse.de>
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 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);