From patchwork Wed Jun 8 06:28:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 631984 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rPdn62rqwz9sCg for ; Wed, 8 Jun 2016 16:28:58 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b=oqaCjET4; dkim-atps=neutral Received: from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3rPdn61kq3zDqV3 for ; Wed, 8 Jun 2016 16:28:58 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b=oqaCjET4; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Received: from mendozajonas.com (mendozajonas.com [188.166.185.233]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3rPdmf6CHDzDq5m for ; Wed, 8 Jun 2016 16:28:33 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b=oqaCjET4; dkim-atps=neutral Received: from skellige.ozlabs.ibm.com (unknown [122.99.82.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) (Authenticated sender: sam@mendozajonas.com) by mendozajonas.com (Postfix) with ESMTPSA id 020EA1442E9 for ; Wed, 8 Jun 2016 14:28:28 +0800 (SGT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mendozajonas.com; s=mail; t=1465367309; bh=BT0fywc6Dscr27vvR7AxcIPqn2gyWvJiJikujPoj+iE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oqaCjET4Gs4NiWUUTYzM+ZepAStaQOF4cSaL60a2Tf2npHM5lgQ+PK29TDtKGVhq9 rflBhmSgBQPpVNF4Fo4S5r05tWFAZN3LG75xbVqvvSTylLFuQD4/5jZWfBt9KoROam omc66TxYbEBegk9DxAuSmrb1ccoUQ857/6ov8hMM= From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [PATCH 6/6] utils/hooks: Set linux,stdout-path for primary console Date: Wed, 8 Jun 2016 16:28:12 +1000 Message-Id: <20160608062812.14480-7-sam@mendozajonas.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160608062812.14480-1-sam@mendozajonas.com> References: <20160608062812.14480-1-sam@mendozajonas.com> X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" If the boot_tty environment variable is set, determine which device path to set in the linux,stdout-path property, which will instruct the next kernel to use it as the primary console. Signed-off-by: Samuel Mendoza-Jonas --- utils/hooks/30-add-offb.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/utils/hooks/30-add-offb.c b/utils/hooks/30-add-offb.c index c635409..cc88922 100644 --- a/utils/hooks/30-add-offb.c +++ b/utils/hooks/30-add-offb.c @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -441,6 +442,121 @@ static int populate_devicetree(struct offb_ctx *ctx) return 0; } +/* + * Find the device tree path assoicated with a hvc device. + * On OPAL all hvc consoles have a 'serial@X' node under ibm,opal/consoles, + * so we make a simplifying assumption that a hvcX is associated with a + * serial@X node. + */ +static char *get_hvc_path(struct offb_ctx *ctx, unsigned int termno) +{ + char *serial; + int node; + + serial = talloc_asprintf(ctx, "serial@%u", termno); + if (!serial) + return NULL; + + node = fdt_subnode_offset(ctx->dtb, 0, "ibm,opal"); + if (node <= 0) { + fprintf(stderr, "Couldn't find ibm,opal\n"); + return NULL; + } + node = fdt_subnode_offset(ctx->dtb, node, "consoles"); + if (node <= 0) { + fprintf(stderr, "Couldn't find ibm,opal/consoles\n"); + return NULL; + } + + node = fdt_subnode_offset(ctx->dtb, node, serial); + if (node <= 0) { + fprintf(stderr, "Could not locate hvc%u\n", termno); + return NULL; + } + + return talloc_asprintf(ctx, "ibm,opal/consoles/%s", serial); +} + +/* + * Find the device tree path of the vga device. On OPAL we assume there is only + * one of these that represents any 'tty' console. + */ +static char *get_vga_path(struct offb_ctx *ctx) +{ + char *root, *vga_path; + + root = strstr(ctx->path, "/pciex@"); + if (!root) { + fprintf(stderr, "Can't find root path for vga device in below:\n"); + fprintf(stderr, "%s\n", ctx->path); + return NULL; + } + + vga_path = talloc_strdup(ctx, root); + fprintf(stderr, "VGA target at '%s'\n", vga_path); + + return vga_path; +} + +static int set_stdout(struct offb_ctx *ctx) +{ + const char *boot_tty, *ptr; + long unsigned int termno; + const fdt32_t *prop; + int node, prop_len; + char *stdout_path; + + boot_tty = getenv("boot_tty"); + if (!boot_tty) { + fprintf(stderr, "boot_tty not set, using default stdout for boot\n"); + return 0; + } + + if (strstr(boot_tty, "tty") != NULL) { + fprintf(stderr, "TTY recognised: %s\n", boot_tty); + stdout_path = get_vga_path(ctx); + } else { + ptr = strstr(boot_tty, "hvc"); + if (!ptr || strlen(ptr) <= strlen("hvc")) { + fprintf(stderr, "Unrecognised console: %s\n", boot_tty); + return 0; + } + ptr += strlen("hvc"); + errno = 0; + termno = strtoul(ptr, NULL, 0); + if (errno) { + fprintf(stderr, "Couldn't parse termno from %s\n", boot_tty); + return 0; + } + fprintf(stderr, "HVC recognised: %s\n", boot_tty); + stdout_path = get_hvc_path(ctx, termno); + } + + if (!stdout_path) { + fprintf(stderr, "Couldn't parse %s into a path", boot_tty); + return -1; + } + + fprintf(stderr, "stdout-path: %s", stdout_path); + + node = fdt_subnode_offset(ctx->dtb, 0, "chosen"); + if (node <= 0) { + fprintf(stderr, "Failed to find chosen\n"); + return -1; + } + + prop = fdt_getprop(ctx->dtb, node, "linux,stdout-path", &prop_len); + if (!prop) { + fprintf(stderr, "Failed to find linux,stdout-path\n"); + return -1; + } + + fdt_set_check(ctx->dtb, node, fdt_setprop_string, "linux,stdout-path", + stdout_path); + + return 0; +} + static int write_devicetree(struct offb_ctx *ctx) { int rc; @@ -484,6 +600,10 @@ int main(void) if (rc) goto out; + rc = set_stdout(ctx); + if (rc) + goto out; + rc = write_devicetree(ctx); out: