From owner-svn-src-head@freebsd.org Sun Mar 29 06:40:52 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 89C9F2747E4; Sun, 29 Mar 2020 06:40:52 +0000 (UTC) (envelope-from ruslanngaripov@gmail.com) Received: from mail-lf1-x144.google.com (mail-lf1-x144.google.com [IPv6:2a00:1450:4864:20::144]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48qmFD4LFtz4WQP; Sun, 29 Mar 2020 06:40:47 +0000 (UTC) (envelope-from ruslanngaripov@gmail.com) Received: by mail-lf1-x144.google.com with SMTP id u15so2142525lfi.3; Sat, 28 Mar 2020 23:40:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=7kwk+v1dPh7F8O8JghtrbxoLGEoRvd/3pRoRZoXae+E=; b=go8KTLr4Gg06j393IG71X1FfT8cVXbEVntEjo3qS038d1ZnX3whwikrm2A6cvXN//e k7MkQ37ttQJbMIQM7JA9Z/sVGcHnq4Vl0okivpnSZJ8gNzAk4YSMVEUZBc294Wq8AFxR mNvPl6nMHQJJRIGKrgPZ5OkbNN7lxQlAJOf0HeaNKd0KVGcwBtsUxurlBBUVM7Ol7MDL pTukUjGsErchLI4536QvbHX0+nPJnxkeBiEtFUaXjk5df04x0ZOEunAGVmnzqnmsCPe4 pgwRtD4BDjQ/+rkvWnEw6bFU75V96pWztoBD2eO6BZxDk3/UderYdGw7ptw/VL0OKOzT hj/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=7kwk+v1dPh7F8O8JghtrbxoLGEoRvd/3pRoRZoXae+E=; b=llkubIHSJgL1sJ23QGF+1pNw5Ix3O1MsJCZPLDWeCLExOEZjoOb9898Y9MAP1NMb2i aFZ97RDRMqRUQBy/N5nAxpPb5yYtw8FapKTjqLnCYCpfduRnF/30PzutaaaRjGnzB6Oy drGGR59W9SM43EE5E0Bwe3xlhgMvxxW5yFsDRQ4bkdfQGHowBmaLGkrThu3VdM7IlACy Owr5ealbOoiuldoSTMsX7HBoH1eagOb0ifgn1AWUlEbOyuZ8SZ4kRgag9J6t/nswWYzn gArVL7pZ9YoEz9aNx+WsrCHGNuO5sF/1nu4JeQS7Z8F6o54DeziJqNhFdxSFrdeQHDVz SNHg== X-Gm-Message-State: AGi0Pub71xwK+gMaTlfRo8qhC2t6iRk/BpSlc/FCDv05wzuksAZp/j1p AdTrHJmpsSxQZ4xhC9aJasABqMugR4Q= X-Google-Smtp-Source: APiQypK7Tva8VkU4N4dQlqbHNQ8iH30x67NRWRSBATDxedmbmp+hdD59eJRMMuVP1AqHG+D/N0BGwg== X-Received: by 2002:a19:c388:: with SMTP id t130mr4619334lff.175.1585464039169; Sat, 28 Mar 2020 23:40:39 -0700 (PDT) Received: from [192.168.1.3] ([46.48.69.183]) by smtp.gmail.com with ESMTPSA id u30sm5622422lfn.2.2020.03.28.23.40.37 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 28 Mar 2020 23:40:38 -0700 (PDT) Subject: Re: svn commit: r358989 - in head/stand/efi: libefi loader loader/arch/arm loader/arch/arm64 To: Toomas Soome Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org References: <202003140636.02E6a3NS020671@repo.freebsd.org> <95805806-b577-d81a-c709-7244d3fea4eb@gmail.com> <35478B22-4EEE-4DE2-B441-7838F676ED68@me.com> From: Ruslan Garipov Message-ID: <1860c146-7f49-37a6-740f-ad0f33b1df79@gmail.com> Date: Sun, 29 Mar 2020 11:40:33 +0500 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: <35478B22-4EEE-4DE2-B441-7838F676ED68@me.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 48qmFD4LFtz4WQP X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org; dkim=pass header.d=gmail.com header.s=20161025 header.b=go8KTLr4; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (mx1.freebsd.org: domain of ruslanngaripov@gmail.com designates 2a00:1450:4864:20::144 as permitted sender) smtp.mailfrom=ruslanngaripov@gmail.com X-Spamd-Result: default: False [-3.00 / 15.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; R_DKIM_ALLOW(-0.20)[gmail.com:s=20161025]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[4]; R_SPF_ALLOW(-0.20)[+ip6:2a00:1450:4000::/36:c]; FREEMAIL_FROM(0.00)[gmail.com]; MIME_GOOD(-0.10)[text/plain]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; TO_DN_SOME(0.00)[]; RCVD_COUNT_THREE(0.00)[3]; IP_SCORE(0.00)[ip: (2.60), ipnet: 2a00:1450::/32(-2.38), asn: 15169(-0.46), country: US(-0.05)]; DKIM_TRACE(0.00)[gmail.com:+]; DMARC_POLICY_ALLOW(-0.50)[gmail.com,none]; RCVD_IN_DNSWL_NONE(0.00)[4.4.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.4.6.8.4.0.5.4.1.0.0.a.2.list.dnswl.org : 127.0.5.0]; IP_SCORE_FREEMAIL(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; FREEMAIL_ENVFROM(0.00)[gmail.com]; ASN(0.00)[asn:15169, ipnet:2a00:1450::/32, country:US]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_TLS_ALL(0.00)[]; DWL_DNSWL_NONE(0.00)[gmail.com.dwl.dnswl.org : 127.0.5.0] X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 29 Mar 2020 06:40:53 -0000 On 3/27/2020 8:07 PM, Toomas Soome wrote: > > >> On 27. Mar 2020, at 16:39, Ruslan Garipov wrote: >> >> On 3/14/2020 11:36 AM, Toomas Soome wrote: >>> Author: tsoome >>> Date: Sat Mar 14 06:36:03 2020 >>> New Revision: 358989 >>> URL: https://svnweb.freebsd.org/changeset/base/358989 >>> >>> Log: >>> loader: add comconsole implementation on top of SIO protocol >>> >>> Provide comconsole on top of SIO for arm platforms (x86 does use bios version). >>> >>> Added: >>> head/stand/efi/loader/efiserialio.c (contents, props changed) >>> Modified: >>> head/stand/efi/libefi/efi_console.c >>> head/stand/efi/loader/arch/arm/Makefile.inc >>> head/stand/efi/loader/arch/arm64/Makefile.inc >>> head/stand/efi/loader/conf.c >>> head/stand/efi/loader/main.c >>> >>> Modified: head/stand/efi/libefi/efi_console.c >>> ============================================================================== >>> --- head/stand/efi/libefi/efi_console.c Sat Mar 14 05:57:22 2020 (r358988) >>> +++ head/stand/efi/libefi/efi_console.c Sat Mar 14 06:36:03 2020 (r358989) >>> @@ -377,9 +377,22 @@ efi_cons_respond(void *s __unused, const void *buf __u >>> { >>> } >>> >>> +/* >>> + * Set up conin/conout/coninex to make sure we have input ready. >>> + */ >>> static void >>> efi_cons_probe(struct console *cp) >>> { >>> + EFI_STATUS status; >>> + >>> + conout = ST->ConOut; >>> + conin = ST->ConIn; >>> + >>> + status = BS->OpenProtocol(ST->ConsoleInHandle, &simple_input_ex_guid, >>> + (void **)&coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); >>> + if (status != EFI_SUCCESS) >>> + coninex = NULL; >>> + >>> cp->c_flags |= C_PRESENTIN | C_PRESENTOUT; >>> } >>> >>> @@ -889,15 +902,7 @@ efi_cons_init(int arg) >>> if (conin != NULL) >>> return (0); >>> >>> - conout = ST->ConOut; >>> - conin = ST->ConIn; >>> - >>> conout->EnableCursor(conout, TRUE); >>> - status = BS->OpenProtocol(ST->ConsoleInHandle, &simple_input_ex_guid, >>> - (void **)&coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); >>> - if (status != EFI_SUCCESS) >>> - coninex = NULL; >>> - >>> if (efi_cons_update_mode()) >>> return (0); >> Hello, Toomas! >> >> I have to return to this revision once again. >> >> Speaking in advance, the problem I'll describe isn't a fatal one. I >> want to find a solution/root cause by myself... well, I had tried to do >> that but failed, therefore, I need some tips from you, if you have free >> time for that. >> >> The loader started to ignore teken.fg_color after r358989. >> >> I like to have green text on black console. Therefore, I have this: >> >> teken.fg_color="green" > > > Oh cool, at least it is useful for someone:) > > I am sorry, yes this is my bug, I somehow missed the second probe and assumed we do probe only once.. And yes, your analysis is correct, the environment with callback should be treated carefully. > > What probe must do is to set up conin/coninex so the efiserial can use workaround for buggy SIO, the rest is not that important. > > >> >> in my /boot/loader.conf. Before r358989 everything worked just like I >> wanted: not only vt(4) had green text on black, but the loader menu >> also. After r358989 vt(4) still renders greeen text on black, but the >> loader doesn't. It use default white on black. The variable is >> assigned but doesn't affect the output: >> >> OK show teken.fg_color >> green >> >> That started to happen after the changes from above: when code from the >> efi_cons_init() was moved to the efi_cons_probe() >> (stand/efi/libefi/efi_console.c). Therefore, if I revert those only >> changes, the loader starts to draw green text on black. >> >> If I read the sources correctly, the cons_probe() function in >> stand/common/console.c calls both those functions. Moreover, the >> efi_cons_probe() is called twice: first time when the cons_probe() >> probes all available consoles, and then when it searches an "online" >> console. And then the cons_probe() calls the efi_cons_init(). I see >> nothing between those calls which may cause the loader to ignore >> teken.fg_color (or any other variable). >> >> I believe that the efi_set_colors() function from >> stand/efi/libefi/efi_console.c is not call being the hook function for >> the teken.fg_color variable. The efi_cons_update_mode() sets the >> efi_set_colors() as the callback for teken.fg_color, but it's never >> called. The only reason for that, according to code of the env_setenv() >> in stand/libsa/environment.c, is that teken.fg_color was already created >> (without the hook function, of course) when the efi_cons_update_mode() >> tries to assign the efi_set_colors() hook. Or, the >> efi_cons_update_mode() failed to allocate the buffer, and, therefore, >> didn't set teken.fg_color at all. And later teken.fg_color is read from >> /boot/loader.conf. >> >> One more evidence that efi_set_colors() is not called: setting >> teken.fg_color from the loader prompt to something incorrect: >> >> OK set teken.fg_color=foobar >> >> doesn't print error message "Allowed values are either ansi color name >> or number from range ..." >> >> Thoomas, is ignoring of teken.fg_color by the loader caused by failing >> to allocate the buffer within the efi_cons_update_mode()? > > That definitely can be the case. If you do not set any custom values, missing tem.* variables would confirm that. > > Now, there is still an question, why in your system that allocation does fail? Is there a way I can help you to figure that out? I'm afraid I will not have an access to my systems during the following week, but even so. > ou, I found I haven't pushed the workaround for buggy Mode information… > > rgds, > toomas > > >> >>> >>> >>> Modified: head/stand/efi/loader/arch/arm/Makefile.inc >>> ============================================================================== >>> --- head/stand/efi/loader/arch/arm/Makefile.inc Sat Mar 14 05:57:22 2020 (r358988) >>> +++ head/stand/efi/loader/arch/arm/Makefile.inc Sat Mar 14 06:36:03 2020 (r358989) >>> @@ -1,6 +1,7 @@ >>> # $FreeBSD$ >>> >>> SRCS+= exec.c \ >>> + efiserialio.c \ >>> start.S >>> >>> HAVE_FDT=yes >>> >>> Modified: head/stand/efi/loader/arch/arm64/Makefile.inc >>> ============================================================================== >>> --- head/stand/efi/loader/arch/arm64/Makefile.inc Sat Mar 14 05:57:22 2020 (r358988) >>> +++ head/stand/efi/loader/arch/arm64/Makefile.inc Sat Mar 14 06:36:03 2020 (r358989) >>> @@ -3,6 +3,7 @@ >>> HAVE_FDT=yes >>> >>> SRCS+= exec.c \ >>> + efiserialio.c \ >>> start.S >>> >>> .PATH: ${BOOTSRC}/arm64/libarm64 >>> >>> Modified: head/stand/efi/loader/conf.c >>> ============================================================================== >>> --- head/stand/efi/loader/conf.c Sat Mar 14 05:57:22 2020 (r358988) >>> +++ head/stand/efi/loader/conf.c Sat Mar 14 06:36:03 2020 (r358989) >>> @@ -73,16 +73,16 @@ struct netif_driver *netif_drivers[] = { >>> }; >>> >>> extern struct console efi_console; >>> -#if defined(__amd64__) || defined(__i386__) >>> extern struct console comconsole; >>> +#if defined(__amd64__) || defined(__i386__) >>> extern struct console nullconsole; >>> extern struct console spinconsole; >>> #endif >>> >>> struct console *consoles[] = { >>> &efi_console, >>> -#if defined(__amd64__) || defined(__i386__) >>> &comconsole, >>> +#if defined(__amd64__) || defined(__i386__) >>> &nullconsole, >>> &spinconsole, >>> #endif >>> >>> Added: head/stand/efi/loader/efiserialio.c >>> ============================================================================== >>> --- /dev/null 00:00:00 1970 (empty, because file is newly added) >>> +++ head/stand/efi/loader/efiserialio.c Sat Mar 14 06:36:03 2020 (r358989) >>> @@ -0,0 +1,518 @@ >>> +/*- >>> + * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) >>> + * >>> + * Redistribution and use in source and binary forms, with or without >>> + * modification, are permitted provided that the following conditions >>> + * are met: >>> + * 1. Redistributions of source code must retain the above copyright >>> + * notice, this list of conditions and the following disclaimer. >>> + * 2. Redistributions in binary form must reproduce the above copyright >>> + * notice, this list of conditions and the following disclaimer in the >>> + * documentation and/or other materials provided with the distribution. >>> + * >>> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >>> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >>> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >>> + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >>> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >>> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >>> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >>> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >>> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >>> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >>> + * SUCH DAMAGE. >>> + */ >>> + >>> +#include >>> +__FBSDID("$FreeBSD$"); >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +#include >>> +#include >>> + >>> +#include "loader_efi.h" >>> + >>> +static EFI_GUID serial = SERIAL_IO_PROTOCOL; >>> + >>> +#define COMC_TXWAIT 0x40000 /* transmit timeout */ >>> + >>> +#ifndef COMSPEED >>> +#define COMSPEED 9600 >>> +#endif >>> + >>> +#define PNP0501 0x501 /* 16550A-compatible COM port */ >>> + >>> +struct serial { >>> + uint64_t baudrate; >>> + uint8_t databits; >>> + EFI_PARITY_TYPE parity; >>> + EFI_STOP_BITS_TYPE stopbits; >>> + uint8_t ignore_cd; /* boolean */ >>> + uint8_t rtsdtr_off; /* boolean */ >>> + int ioaddr; /* index in handles array */ >>> + EFI_HANDLE currdev; /* current serial device */ >>> + EFI_HANDLE condev; /* EFI Console device */ >>> + SERIAL_IO_INTERFACE *sio; >>> +}; >>> + >>> +static void comc_probe(struct console *); >>> +static int comc_init(int); >>> +static void comc_putchar(int); >>> +static int comc_getchar(void); >>> +static int comc_ischar(void); >>> +static bool comc_setup(void); >>> +static int comc_parse_intval(const char *, unsigned *); >>> +static int comc_port_set(struct env_var *, int, const void *); >>> +static int comc_speed_set(struct env_var *, int, const void *); >>> + >>> +static struct serial *comc_port; >>> +extern struct console efi_console; >>> + >>> +struct console comconsole = { >>> + .c_name = "comconsole", >>> + .c_desc = "serial port", >>> + .c_flags = 0, >>> + .c_probe = comc_probe, >>> + .c_init = comc_init, >>> + .c_out = comc_putchar, >>> + .c_in = comc_getchar, >>> + .c_ready = comc_ischar, >>> +}; >>> + >>> +static EFI_STATUS >>> +efi_serial_init(EFI_HANDLE **handlep, int *nhandles) >>> +{ >>> + UINTN bufsz = 0; >>> + EFI_STATUS status; >>> + EFI_HANDLE *handles; >>> + >>> + /* >>> + * get buffer size >>> + */ >>> + *nhandles = 0; >>> + handles = NULL; >>> + status = BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, handles); >>> + if (status != EFI_BUFFER_TOO_SMALL) >>> + return (status); >>> + >>> + if ((handles = malloc(bufsz)) == NULL) >>> + return (ENOMEM); >>> + >>> + *nhandles = (int)(bufsz / sizeof (EFI_HANDLE)); >>> + /* >>> + * get handle array >>> + */ >>> + status = BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, handles); >>> + if (EFI_ERROR(status)) { >>> + free(handles); >>> + *nhandles = 0; >>> + } else >>> + *handlep = handles; >>> + return (status); >>> +} >>> + >>> +/* >>> + * Find serial device number from device path. >>> + * Return -1 if not found. >>> + */ >>> +static int >>> +efi_serial_get_index(EFI_DEVICE_PATH *devpath, int idx) >>> +{ >>> + ACPI_HID_DEVICE_PATH *acpi; >>> + CHAR16 *text; >>> + >>> + while (!IsDevicePathEnd(devpath)) { >>> + if (DevicePathType(devpath) == MESSAGING_DEVICE_PATH && >>> + DevicePathSubType(devpath) == MSG_UART_DP) >>> + return (idx); >>> + >>> + if (DevicePathType(devpath) == ACPI_DEVICE_PATH && >>> + (DevicePathSubType(devpath) == ACPI_DP || >>> + DevicePathSubType(devpath) == ACPI_EXTENDED_DP)) { >>> + >>> + acpi = (ACPI_HID_DEVICE_PATH *)devpath; >>> + if (acpi->HID == EISA_PNP_ID(PNP0501)) { >>> + return (acpi->UID); >>> + } >>> + } >>> + >>> + devpath = NextDevicePathNode(devpath); >>> + } >>> + return (-1); >>> +} >>> + >>> +/* >>> + * The order of handles from LocateHandle() is not known, we need to >>> + * iterate handles, pick device path for handle, and check the device >>> + * number. >>> + */ >>> +static EFI_HANDLE >>> +efi_serial_get_handle(int port, EFI_HANDLE condev) >>> +{ >>> + EFI_STATUS status; >>> + EFI_HANDLE *handles, handle; >>> + EFI_DEVICE_PATH *devpath; >>> + int index, nhandles; >>> + >>> + if (port == -1) >>> + return (NULL); >>> + >>> + handles = NULL; >>> + nhandles = 0; >>> + status = efi_serial_init(&handles, &nhandles); >>> + if (EFI_ERROR(status)) >>> + return (NULL); >>> + >>> + /* >>> + * We have console handle, set ioaddr for it. >>> + */ >>> + if (condev != NULL) { >>> + for (index = 0; index < nhandles; index++) { >>> + if (condev == handles[index]) { >>> + devpath = efi_lookup_devpath(condev); >>> + comc_port->ioaddr = >>> + efi_serial_get_index(devpath, index); >>> + efi_close_devpath(condev); >>> + free(handles); >>> + return (condev); >>> + } >>> + } >>> + } >>> + >>> + handle = NULL; >>> + for (index = 0; handle == NULL && index < nhandles; index++) { >>> + devpath = efi_lookup_devpath(handles[index]); >>> + if (port == efi_serial_get_index(devpath, index)) >>> + handle = (handles[index]); >>> + efi_close_devpath(handles[index]); >>> + } >>> + >>> + /* >>> + * In case we did fail to identify the device by path, use port as >>> + * array index. Note, we did check port == -1 above. >>> + */ >>> + if (port < nhandles && handle == NULL) >>> + handle = handles[port]; >>> + >>> + free(handles); >>> + return (handle); >>> +} >>> + >>> +static EFI_HANDLE >>> +comc_get_con_serial_handle(const char *name) >>> +{ >>> + EFI_HANDLE handle; >>> + EFI_DEVICE_PATH *node; >>> + EFI_STATUS status; >>> + char *buf, *ep; >>> + size_t sz; >>> + >>> + buf = NULL; >>> + sz = 0; >>> + status = efi_global_getenv(name, buf, &sz); >>> + if (status == EFI_BUFFER_TOO_SMALL) { >>> + buf = malloc(sz); >>> + if (buf != NULL) >>> + status = efi_global_getenv(name, buf, &sz); >>> + } >>> + if (status != EFI_SUCCESS) { >>> + free(buf); >>> + return (NULL); >>> + } >>> + >>> + ep = buf + sz; >>> + node = (EFI_DEVICE_PATH *)buf; >>> + while ((char *)node < ep) { >>> + status = BS->LocateDevicePath(&serial, &node, &handle); >>> + if (status == EFI_SUCCESS) { >>> + free(buf); >>> + return (handle); >>> + } >>> + if (IsDevicePathEndType(node) && >>> + DevicePathSubType(node) == >>> + END_INSTANCE_DEVICE_PATH_SUBTYPE) { >>> + /* >>> + * Start of next device path in list. >>> + */ >>> + node = NextDevicePathNode(node); >>> + continue; >>> + } >>> + if (IsDevicePathEnd(node)) >>> + break; >>> + } >>> + free(buf); >>> + return (NULL); >>> +} >>> + >>> +static void >>> +comc_probe(struct console *sc) >>> +{ >>> + EFI_STATUS status; >>> + EFI_HANDLE handle; >>> + char name[20]; >>> + char value[20]; >>> + unsigned val; >>> + char *env, *buf, *ep; >>> + size_t sz; >>> + >>> + if (comc_port == NULL) { >>> + comc_port = malloc(sizeof (struct serial)); >>> + if (comc_port == NULL) >>> + return; >>> + } >>> + comc_port->baudrate = COMSPEED; >>> + comc_port->ioaddr = 0; /* default port */ >>> + comc_port->databits = 8; /* 8,n,1 */ >>> + comc_port->parity = NoParity; /* 8,n,1 */ >>> + comc_port->stopbits = OneStopBit; /* 8,n,1 */ >>> + comc_port->ignore_cd = 1; /* ignore cd */ >>> + comc_port->rtsdtr_off = 0; /* rts-dtr is on */ >>> + comc_port->sio = NULL; >>> + >>> + handle = NULL; >>> + env = getenv("efi_com_port"); >>> + if (comc_parse_intval(env, &val) == CMD_OK) { >>> + comc_port->ioaddr = val; >>> + } else { >>> + /* >>> + * efi_com_port is not set, we need to select default. >>> + * First, we consult ConOut variable to see if >>> + * we have serial port redirection. If not, we just >>> + * pick first device. >>> + */ >>> + handle = comc_get_con_serial_handle("ConOut"); >>> + comc_port->condev = handle; >>> + } >>> + >>> + handle = efi_serial_get_handle(comc_port->ioaddr, handle); >>> + if (handle != NULL) { >>> + comc_port->currdev = handle; >>> + status = BS->OpenProtocol(handle, &serial, >>> + (void**)&comc_port->sio, IH, NULL, >>> + EFI_OPEN_PROTOCOL_GET_PROTOCOL); >>> + >>> + if (EFI_ERROR(status)) >>> + comc_port->sio = NULL; >>> + } >>> + >>> + if (env != NULL) >>> + unsetenv("efi_com_port"); >>> + snprintf(value, sizeof (value), "%u", comc_port->ioaddr); >>> + env_setenv("efi_com_port", EV_VOLATILE, value, >>> + comc_port_set, env_nounset); >>> + >>> + env = getenv("efi_com_speed"); >>> + if (comc_parse_intval(env, &val) == CMD_OK) >>> + comc_port->baudrate = val; >>> + >>> + if (env != NULL) >>> + unsetenv("efi_com_speed"); >>> + snprintf(value, sizeof (value), "%ju", (uintmax_t)comc_port->baudrate); >>> + env_setenv("efi_com_speed", EV_VOLATILE, value, >>> + comc_speed_set, env_nounset); >>> + >>> + comconsole.c_flags = 0; >>> + if (comc_setup()) >>> + sc->c_flags = C_PRESENTIN | C_PRESENTOUT; >>> +} >>> + >>> +static int >>> +comc_init(int arg __unused) >>> +{ >>> + >>> + if (comc_setup()) >>> + return (CMD_OK); >>> + >>> + comconsole.c_flags = 0; >>> + return (CMD_ERROR); >>> +} >>> + >>> +static void >>> +comc_putchar(int c) >>> +{ >>> + int wait; >>> + EFI_STATUS status; >>> + UINTN bufsz = 1; >>> + char cb = c; >>> + >>> + if (comc_port->sio == NULL) >>> + return; >>> + >>> + for (wait = COMC_TXWAIT; wait > 0; wait--) { >>> + status = comc_port->sio->Write(comc_port->sio, &bufsz, &cb); >>> + if (status != EFI_TIMEOUT) >>> + break; >>> + } >>> +} >>> + >>> +static int >>> +comc_getchar(void) >>> +{ >>> + EFI_STATUS status; >>> + UINTN bufsz = 1; >>> + char c; >>> + >>> + >>> + /* >>> + * if this device is also used as ConIn, some firmwares >>> + * fail to return all input via SIO protocol. >>> + */ >>> + if (comc_port->currdev == comc_port->condev) { >>> + if ((efi_console.c_flags & C_ACTIVEIN) == 0) >>> + return (efi_console.c_in()); >>> + return (-1); >>> + } >>> + >>> + if (comc_port->sio == NULL) >>> + return (-1); >>> + >>> + status = comc_port->sio->Read(comc_port->sio, &bufsz, &c); >>> + if (EFI_ERROR(status) || bufsz == 0) >>> + return (-1); >>> + >>> + return (c); >>> +} >>> + >>> +static int >>> +comc_ischar(void) >>> +{ >>> + EFI_STATUS status; >>> + uint32_t control; >>> + >>> + /* >>> + * if this device is also used as ConIn, some firmwares >>> + * fail to return all input via SIO protocol. >>> + */ >>> + if (comc_port->currdev == comc_port->condev) { >>> + if ((efi_console.c_flags & C_ACTIVEIN) == 0) >>> + return (efi_console.c_ready()); >>> + return (0); >>> + } >>> + >>> + if (comc_port->sio == NULL) >>> + return (0); >>> + >>> + status = comc_port->sio->GetControl(comc_port->sio, &control); >>> + if (EFI_ERROR(status)) >>> + return (0); >>> + >>> + return (!(control & EFI_SERIAL_INPUT_BUFFER_EMPTY)); >>> +} >>> + >>> +static int >>> +comc_parse_intval(const char *value, unsigned *valp) >>> +{ >>> + unsigned n; >>> + char *ep; >>> + >>> + if (value == NULL || *value == '\0') >>> + return (CMD_ERROR); >>> + >>> + errno = 0; >>> + n = strtoul(value, &ep, 10); >>> + if (errno != 0 || *ep != '\0') >>> + return (CMD_ERROR); >>> + *valp = n; >>> + >>> + return (CMD_OK); >>> +} >>> + >>> +static int >>> +comc_port_set(struct env_var *ev, int flags, const void *value) >>> +{ >>> + unsigned port; >>> + SERIAL_IO_INTERFACE *sio; >>> + EFI_HANDLE handle; >>> + EFI_STATUS status; >>> + >>> + if (value == NULL) >>> + return (CMD_ERROR); >>> + >>> + if (comc_parse_intval(value, &port) != CMD_OK) >>> + return (CMD_ERROR); >>> + >>> + handle = efi_serial_get_handle(port, NULL); >>> + if (handle == NULL) { >>> + printf("no handle\n"); >>> + return (CMD_ERROR); >>> + } >>> + >>> + status = BS->OpenProtocol(handle, &serial, >>> + (void**)&sio, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); >>> + >>> + if (EFI_ERROR(status)) { >>> + printf("OpenProtocol: %lu\n", EFI_ERROR_CODE(status)); >>> + return (CMD_ERROR); >>> + } >>> + >>> + comc_port->currdev = handle; >>> + comc_port->ioaddr = port; >>> + comc_port->sio = sio; >>> + >>> + (void) comc_setup(); >>> + >>> + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); >>> + return (CMD_OK); >>> +} >>> + >>> +static int >>> +comc_speed_set(struct env_var *ev, int flags, const void *value) >>> +{ >>> + unsigned speed; >>> + >>> + if (value == NULL) >>> + return (CMD_ERROR); >>> + >>> + if (comc_parse_intval(value, &speed) != CMD_OK) >>> + return (CMD_ERROR); >>> + >>> + comc_port->baudrate = speed; >>> + (void) comc_setup(); >>> + >>> + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); >>> + >>> + return (CMD_OK); >>> +} >>> + >>> +/* >>> + * In case of error, we also reset ACTIVE flags, so the console >>> + * framefork will try alternate consoles. >>> + */ >>> +static bool >>> +comc_setup(void) >>> +{ >>> + EFI_STATUS status; >>> + UINT32 control; >>> + >>> + /* port is not usable */ >>> + if (comc_port->sio == NULL) >>> + return (false); >>> + >>> + status = comc_port->sio->Reset(comc_port->sio); >>> + if (EFI_ERROR(status)) >>> + return (false); >>> + >>> + status = comc_port->sio->SetAttributes(comc_port->sio, >>> + comc_port->baudrate, 0, 0, comc_port->parity, >>> + comc_port->databits, comc_port->stopbits); >>> + if (EFI_ERROR(status)) >>> + return (false); >>> + >>> + status = comc_port->sio->GetControl(comc_port->sio, &control); >>> + if (EFI_ERROR(status)) >>> + return (false); >>> + if (comc_port->rtsdtr_off) { >>> + control &= ~(EFI_SERIAL_REQUEST_TO_SEND | >>> + EFI_SERIAL_DATA_TERMINAL_READY); >>> + } else { >>> + control |= EFI_SERIAL_REQUEST_TO_SEND; >>> + } >>> + (void) comc_port->sio->SetControl(comc_port->sio, control); >>> + /* Mark this port usable. */ >>> + comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT); >>> + return (true); >>> +} >>> >>> Modified: head/stand/efi/loader/main.c >>> ============================================================================== >>> --- head/stand/efi/loader/main.c Sat Mar 14 05:57:22 2020 (r358988) >>> +++ head/stand/efi/loader/main.c Sat Mar 14 06:36:03 2020 (r358989) >>> @@ -722,7 +722,8 @@ parse_uefi_con_out(void) >>> while ((char *)node < ep) { >>> pci_pending = false; >>> if (DevicePathType(node) == ACPI_DEVICE_PATH && >>> - DevicePathSubType(node) == ACPI_DP) { >>> + (DevicePathSubType(node) == ACPI_DP || >>> + DevicePathSubType(node) == ACPI_EXTENDED_DP)) { >>> /* Check for Serial node */ >>> acpi = (void *)node; >>> if (EISA_ID_TO_NUM(acpi->HID) == 0x501) { >>> @@ -731,7 +732,7 @@ parse_uefi_con_out(void) >>> } >>> } else if (DevicePathType(node) == MESSAGING_DEVICE_PATH && >>> DevicePathSubType(node) == MSG_UART_DP) { >>> - >>> + com_seen = ++seen; >>> uart = (void *)node; >>> setenv_int("efi_com_speed", uart->BaudRate); >>> } else if (DevicePathType(node) == ACPI_DEVICE_PATH && >>> @@ -897,6 +898,11 @@ main(int argc, CHAR16 *argv[]) >>> * changes to take effect, regardless of where they come from. >>> */ >>> setenv("console", "efi", 1); >>> + uhowto = parse_uefi_con_out(); >>> +#if defined(__aarch64__) || defined(__arm__) >>> + if ((uhowto & RB_SERIAL) != 0) >>> + setenv("console", "comconsole", 1); >>> +#endif >>> cons_probe(); >>> >>> /* Init the time source */ >>> @@ -930,7 +936,6 @@ main(int argc, CHAR16 *argv[]) >>> if (!has_kbd && (howto & RB_PROBE)) >>> howto |= RB_SERIAL | RB_MULTIPLE; >>> howto &= ~RB_PROBE; >>> - uhowto = parse_uefi_con_out(); >>> >>> /* >>> * Read additional environment variables from the boot device's >>> _______________________________________________ >>> svn-src-head@freebsd.org mailing list >>> https://lists.freebsd.org/mailman/listinfo/svn-src-head >>> To unsubscribe, send any mail to "svn-src-head-unsubscribe@freebsd.org" >>> >