From owner-svn-src-head@freebsd.org Fri Mar 27 15:15:58 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 50FC42783D0 for ; Fri, 27 Mar 2020 15:15:58 +0000 (UTC) (envelope-from tsoome@me.com) Received: from pv50p00im-ztdg10021801.me.com (pv50p00im-ztdg10021801.me.com [17.58.6.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 48plmM0bDHz4Db8 for ; Fri, 27 Mar 2020 15:15:46 +0000 (UTC) (envelope-from tsoome@me.com) Received: from nazgul.lan (148-52-235-80.sta.estpak.ee [80.235.52.148]) by pv50p00im-ztdg10021801.me.com (Postfix) with ESMTPSA id 8531B3604E8; Fri, 27 Mar 2020 15:07:55 +0000 (UTC) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: svn commit: r358989 - in head/stand/efi: libefi loader loader/arch/arm loader/arch/arm64 From: Toomas Soome In-Reply-To: <95805806-b577-d81a-c709-7244d3fea4eb@gmail.com> Date: Fri, 27 Mar 2020 17:07:43 +0200 Cc: Toomas Soome , src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Content-Transfer-Encoding: quoted-printable Message-Id: <35478B22-4EEE-4DE2-B441-7838F676ED68@me.com> References: <202003140636.02E6a3NS020671@repo.freebsd.org> <95805806-b577-d81a-c709-7244d3fea4eb@gmail.com> To: Ruslan Garipov X-Mailer: Apple Mail (2.3608.80.23.2.2) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2020-03-27_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1908290000 definitions=main-2003270138 X-Rspamd-Queue-Id: 48plmM0bDHz4Db8 X-Spamd-Bar: --- X-Spamd-Result: default: False [-3.60 / 15.00]; RCVD_VIA_SMTP_AUTH(0.00)[]; TO_DN_SOME(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:17.58.0.0/16]; FREEMAIL_FROM(0.00)[me.com]; MV_CASE(0.50)[]; RCPT_COUNT_FIVE(0.00)[5]; DKIM_TRACE(0.00)[me.com:+]; DMARC_POLICY_ALLOW(-0.50)[me.com,quarantine]; FREEMAIL_TO(0.00)[gmail.com]; RCVD_IN_DNSWL_LOW(-0.10)[56.6.58.17.list.dnswl.org : 127.0.5.1]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; FREEMAIL_ENVFROM(0.00)[me.com]; ASN(0.00)[asn:714, ipnet:17.58.0.0/20, country:US]; MID_RHS_MATCH_FROM(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[148.52.235.80.khpj7ygk5idzvmvt5x4ziurxhy.zen.dq.spamhaus.net : 127.0.0.10]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000,0]; R_DKIM_ALLOW(-0.20)[me.com:s=1a1hai]; FROM_HAS_DN(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[text/plain]; IP_SCORE(0.00)[ip: (-5.23), ipnet: 17.58.0.0/20(-2.04), asn: 714(-2.41), country: US(-0.05)]; IP_SCORE_FREEMAIL(0.00)[]; DWL_DNSWL_LOW(-1.00)[me.com.dwl.dnswl.org : 127.0.5.1]; TO_MATCH_ENVRCPT_SOME(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[] 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: Fri, 27 Mar 2020 15:15:58 -0000 > On 27. Mar 2020, at 16:39, Ruslan Garipov = wrote: >=20 > 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 >>=20 >> Log: >> loader: add comconsole implementation on top of SIO protocol >>=20 >> Provide comconsole on top of SIO for arm platforms (x86 does use = bios version). >>=20 >> 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 >>=20 >> Modified: head/stand/efi/libefi/efi_console.c >> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >> --- 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 >> { >> } >>=20 >> +/* >> + * Set up conin/conout/coninex to make sure we have input ready. >> + */ >> static void >> efi_cons_probe(struct console *cp) >> { >> + EFI_STATUS status; >> + >> + conout =3D ST->ConOut; >> + conin =3D ST->ConIn; >> + >> + status =3D BS->OpenProtocol(ST->ConsoleInHandle, = &simple_input_ex_guid, >> + (void **)&coninex, IH, NULL, = EFI_OPEN_PROTOCOL_GET_PROTOCOL); >> + if (status !=3D EFI_SUCCESS) >> + coninex =3D NULL; >> + >> cp->c_flags |=3D C_PRESENTIN | C_PRESENTOUT; >> } >>=20 >> @@ -889,15 +902,7 @@ efi_cons_init(int arg) >> if (conin !=3D NULL) >> return (0); >>=20 >> - conout =3D ST->ConOut; >> - conin =3D ST->ConIn; >> - >> conout->EnableCursor(conout, TRUE); >> - status =3D BS->OpenProtocol(ST->ConsoleInHandle, = &simple_input_ex_guid, >> - (void **)&coninex, IH, NULL, = EFI_OPEN_PROTOCOL_GET_PROTOCOL); >> - if (status !=3D EFI_SUCCESS) >> - coninex =3D NULL; >> - >> if (efi_cons_update_mode()) >> return (0); > Hello, Toomas! >=20 > I have to return to this revision once again. >=20 > 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. >=20 > The loader started to ignore teken.fg_color after r358989. >=20 > I like to have green text on black console. Therefore, I have this: >=20 > teken.fg_color=3D"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. >=20 > 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: >=20 > OK show teken.fg_color > green >=20 > 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. >=20 > 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). >=20 > 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. >=20 > One more evidence that efi_set_colors() is not called: setting > teken.fg_color from the loader prompt to something incorrect: >=20 > OK set teken.fg_color=3Dfoobar >=20 > doesn't print error message "Allowed values are either ansi color name > or number from range ..." >=20 > 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? ou, I found I haven't pushed the workaround for buggy Mode = information=E2=80=A6 rgds, toomas >=20 >>=20 >>=20 >> Modified: head/stand/efi/loader/arch/arm/Makefile.inc >> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >> --- 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$ >>=20 >> SRCS+=3D exec.c \ >> + efiserialio.c \ >> start.S >>=20 >> HAVE_FDT=3Dyes >>=20 >> Modified: head/stand/efi/loader/arch/arm64/Makefile.inc >> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >> --- 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=3Dyes >>=20 >> SRCS+=3D exec.c \ >> + efiserialio.c \ >> start.S >>=20 >> .PATH: ${BOOTSRC}/arm64/libarm64 >>=20 >> Modified: head/stand/efi/loader/conf.c >> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >> --- 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[] =3D { >> }; >>=20 >> 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 >>=20 >> struct console *consoles[] =3D { >> &efi_console, >> -#if defined(__amd64__) || defined(__i386__) >> &comconsole, >> +#if defined(__amd64__) || defined(__i386__) >> &nullconsole, >> &spinconsole, >> #endif >>=20 >> Added: head/stand/efi/loader/efiserialio.c >> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >> --- /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 =3D 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 =3D { >> + .c_name =3D "comconsole", >> + .c_desc =3D "serial port", >> + .c_flags =3D 0, >> + .c_probe =3D comc_probe, >> + .c_init =3D comc_init, >> + .c_out =3D comc_putchar, >> + .c_in =3D comc_getchar, >> + .c_ready =3D comc_ischar, >> +}; >> + >> +static EFI_STATUS >> +efi_serial_init(EFI_HANDLE **handlep, int *nhandles) >> +{ >> + UINTN bufsz =3D 0; >> + EFI_STATUS status; >> + EFI_HANDLE *handles; >> + >> + /* >> + * get buffer size >> + */ >> + *nhandles =3D 0; >> + handles =3D NULL; >> + status =3D BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, = handles); >> + if (status !=3D EFI_BUFFER_TOO_SMALL) >> + return (status); >> + >> + if ((handles =3D malloc(bufsz)) =3D=3D NULL) >> + return (ENOMEM); >> + >> + *nhandles =3D (int)(bufsz / sizeof (EFI_HANDLE)); >> + /* >> + * get handle array >> + */ >> + status =3D BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, = handles); >> + if (EFI_ERROR(status)) { >> + free(handles); >> + *nhandles =3D 0; >> + } else >> + *handlep =3D 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) =3D=3D MESSAGING_DEVICE_PATH = && >> + DevicePathSubType(devpath) =3D=3D MSG_UART_DP) >> + return (idx); >> + >> + if (DevicePathType(devpath) =3D=3D ACPI_DEVICE_PATH && >> + (DevicePathSubType(devpath) =3D=3D ACPI_DP || >> + DevicePathSubType(devpath) =3D=3D ACPI_EXTENDED_DP)) = { >> + >> + acpi =3D (ACPI_HID_DEVICE_PATH *)devpath; >> + if (acpi->HID =3D=3D EISA_PNP_ID(PNP0501)) { >> + return (acpi->UID); >> + } >> + } >> + >> + devpath =3D 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 =3D=3D -1) >> + return (NULL); >> + >> + handles =3D NULL; >> + nhandles =3D 0; >> + status =3D efi_serial_init(&handles, &nhandles); >> + if (EFI_ERROR(status)) >> + return (NULL); >> + >> + /* >> + * We have console handle, set ioaddr for it. >> + */ >> + if (condev !=3D NULL) { >> + for (index =3D 0; index < nhandles; index++) { >> + if (condev =3D=3D handles[index]) { >> + devpath =3D efi_lookup_devpath(condev); >> + comc_port->ioaddr =3D >> + efi_serial_get_index(devpath, = index); >> + efi_close_devpath(condev); >> + free(handles); >> + return (condev); >> + } >> + } >> + } >> + >> + handle =3D NULL; >> + for (index =3D 0; handle =3D=3D NULL && index < nhandles; = index++) { >> + devpath =3D efi_lookup_devpath(handles[index]); >> + if (port =3D=3D efi_serial_get_index(devpath, index)) >> + handle =3D (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 =3D=3D -1 above. >> + */ >> + if (port < nhandles && handle =3D=3D NULL) >> + handle =3D 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 =3D NULL; >> + sz =3D 0; >> + status =3D efi_global_getenv(name, buf, &sz); >> + if (status =3D=3D EFI_BUFFER_TOO_SMALL) { >> + buf =3D malloc(sz); >> + if (buf !=3D NULL) >> + status =3D efi_global_getenv(name, buf, &sz); >> + } >> + if (status !=3D EFI_SUCCESS) { >> + free(buf); >> + return (NULL); >> + } >> + >> + ep =3D buf + sz; >> + node =3D (EFI_DEVICE_PATH *)buf; >> + while ((char *)node < ep) { >> + status =3D BS->LocateDevicePath(&serial, &node, = &handle); >> + if (status =3D=3D EFI_SUCCESS) { >> + free(buf); >> + return (handle); >> + } >> + if (IsDevicePathEndType(node) && >> + DevicePathSubType(node) =3D=3D >> + END_INSTANCE_DEVICE_PATH_SUBTYPE) { >> + /* >> + * Start of next device path in list. >> + */ >> + node =3D 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 =3D=3D NULL) { >> + comc_port =3D malloc(sizeof (struct serial)); >> + if (comc_port =3D=3D NULL) >> + return; >> + } >> + comc_port->baudrate =3D COMSPEED; >> + comc_port->ioaddr =3D 0; /* default port = */ >> + comc_port->databits =3D 8; /* 8,n,1 */ >> + comc_port->parity =3D NoParity; /* 8,n,1 */ >> + comc_port->stopbits =3D OneStopBit; /* 8,n,1 */ >> + comc_port->ignore_cd =3D 1; /* ignore cd */ >> + comc_port->rtsdtr_off =3D 0; /* rts-dtr is on */ >> + comc_port->sio =3D NULL; >> + >> + handle =3D NULL; >> + env =3D getenv("efi_com_port"); >> + if (comc_parse_intval(env, &val) =3D=3D CMD_OK) { >> + comc_port->ioaddr =3D 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 =3D comc_get_con_serial_handle("ConOut"); >> + comc_port->condev =3D handle; >> + } >> + >> + handle =3D efi_serial_get_handle(comc_port->ioaddr, handle); >> + if (handle !=3D NULL) { >> + comc_port->currdev =3D handle; >> + status =3D BS->OpenProtocol(handle, &serial, >> + (void**)&comc_port->sio, IH, NULL, >> + EFI_OPEN_PROTOCOL_GET_PROTOCOL); >> + >> + if (EFI_ERROR(status)) >> + comc_port->sio =3D NULL; >> + } >> + >> + if (env !=3D NULL)=20 >> + 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 =3D getenv("efi_com_speed"); >> + if (comc_parse_intval(env, &val) =3D=3D CMD_OK) >> + comc_port->baudrate =3D val; >> + >> + if (env !=3D 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 =3D 0; >> + if (comc_setup()) >> + sc->c_flags =3D C_PRESENTIN | C_PRESENTOUT; >> +} >> + >> +static int >> +comc_init(int arg __unused) >> +{ >> + >> + if (comc_setup()) >> + return (CMD_OK); >> + >> + comconsole.c_flags =3D 0; >> + return (CMD_ERROR); >> +} >> + >> +static void >> +comc_putchar(int c) >> +{ >> + int wait; >> + EFI_STATUS status; >> + UINTN bufsz =3D 1; >> + char cb =3D c; >> + >> + if (comc_port->sio =3D=3D NULL) >> + return; >> + >> + for (wait =3D COMC_TXWAIT; wait > 0; wait--) { >> + status =3D comc_port->sio->Write(comc_port->sio, &bufsz, = &cb); >> + if (status !=3D EFI_TIMEOUT) >> + break; >> + } >> +} >> + >> +static int >> +comc_getchar(void) >> +{ >> + EFI_STATUS status; >> + UINTN bufsz =3D 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 =3D=3D comc_port->condev) { >> + if ((efi_console.c_flags & C_ACTIVEIN) =3D=3D 0) >> + return (efi_console.c_in()); >> + return (-1); >> + } >> + >> + if (comc_port->sio =3D=3D NULL) >> + return (-1); >> + >> + status =3D comc_port->sio->Read(comc_port->sio, &bufsz, &c); >> + if (EFI_ERROR(status) || bufsz =3D=3D 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 =3D=3D comc_port->condev) { >> + if ((efi_console.c_flags & C_ACTIVEIN) =3D=3D 0) >> + return (efi_console.c_ready()); >> + return (0); >> + } >> + >> + if (comc_port->sio =3D=3D NULL) >> + return (0); >> + >> + status =3D 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 =3D=3D NULL || *value =3D=3D '\0') >> + return (CMD_ERROR); >> + >> + errno =3D 0; >> + n =3D strtoul(value, &ep, 10); >> + if (errno !=3D 0 || *ep !=3D '\0') >> + return (CMD_ERROR); >> + *valp =3D 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 =3D=3D NULL) >> + return (CMD_ERROR); >> + >> + if (comc_parse_intval(value, &port) !=3D CMD_OK)=20 >> + return (CMD_ERROR); >> + >> + handle =3D efi_serial_get_handle(port, NULL); >> + if (handle =3D=3D NULL) { >> + printf("no handle\n"); >> + return (CMD_ERROR); >> + } >> + >> + status =3D 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 =3D handle; >> + comc_port->ioaddr =3D port; >> + comc_port->sio =3D sio; >> +=09 >> + (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 =3D=3D NULL) >> + return (CMD_ERROR); >> + >> + if (comc_parse_intval(value, &speed) !=3D CMD_OK)=20 >> + return (CMD_ERROR); >> + >> + comc_port->baudrate =3D 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 =3D=3D NULL) >> + return (false); >> + >> + status =3D comc_port->sio->Reset(comc_port->sio); >> + if (EFI_ERROR(status)) >> + return (false); >> + >> + status =3D 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 =3D comc_port->sio->GetControl(comc_port->sio, &control); >> + if (EFI_ERROR(status)) >> + return (false); >> + if (comc_port->rtsdtr_off) { >> + control &=3D ~(EFI_SERIAL_REQUEST_TO_SEND | >> + EFI_SERIAL_DATA_TERMINAL_READY); >> + } else { >> + control |=3D EFI_SERIAL_REQUEST_TO_SEND; >> + } >> + (void) comc_port->sio->SetControl(comc_port->sio, control); >> + /* Mark this port usable. */ >> + comconsole.c_flags |=3D (C_PRESENTIN | C_PRESENTOUT); >> + return (true); >> +} >>=20 >> Modified: head/stand/efi/loader/main.c >> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >> --- 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 =3D false; >> if (DevicePathType(node) =3D=3D ACPI_DEVICE_PATH && >> - DevicePathSubType(node) =3D=3D ACPI_DP) { >> + (DevicePathSubType(node) =3D=3D ACPI_DP || >> + DevicePathSubType(node) =3D=3D ACPI_EXTENDED_DP)) { >> /* Check for Serial node */ >> acpi =3D (void *)node; >> if (EISA_ID_TO_NUM(acpi->HID) =3D=3D 0x501) { >> @@ -731,7 +732,7 @@ parse_uefi_con_out(void) >> } >> } else if (DevicePathType(node) =3D=3D = MESSAGING_DEVICE_PATH && >> DevicePathSubType(node) =3D=3D MSG_UART_DP) { >> - >> + com_seen =3D ++seen; >> uart =3D (void *)node; >> setenv_int("efi_com_speed", uart->BaudRate); >> } else if (DevicePathType(node) =3D=3D 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 =3D parse_uefi_con_out(); >> +#if defined(__aarch64__) || defined(__arm__) >> + if ((uhowto & RB_SERIAL) !=3D 0) >> + setenv("console", "comconsole", 1); >> +#endif >> cons_probe(); >>=20 >> /* Init the time source */ >> @@ -930,7 +936,6 @@ main(int argc, CHAR16 *argv[]) >> if (!has_kbd && (howto & RB_PROBE)) >> howto |=3D RB_SERIAL | RB_MULTIPLE; >> howto &=3D ~RB_PROBE; >> - uhowto =3D parse_uefi_con_out(); >>=20 >> /* >> * 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" >>=20