Date: Sun, 29 Mar 2020 11:40:33 +0500 From: Ruslan Garipov <ruslanngaripov@gmail.com> To: Toomas Soome <tsoome@FreeBSD.org> Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r358989 - in head/stand/efi: libefi loader loader/arch/arm loader/arch/arm64 Message-ID: <1860c146-7f49-37a6-740f-ad0f33b1df79@gmail.com> In-Reply-To: <35478B22-4EEE-4DE2-B441-7838F676ED68@me.com> References: <202003140636.02E6a3NS020671@repo.freebsd.org> <95805806-b577-d81a-c709-7244d3fea4eb@gmail.com> <35478B22-4EEE-4DE2-B441-7838F676ED68@me.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 3/27/2020 8:07 PM, Toomas Soome wrote: > > >> On 27. Mar 2020, at 16:39, Ruslan Garipov <ruslanngaripov@gmail.com> 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 <sys/cdefs.h> >>> +__FBSDID("$FreeBSD$"); >>> + >>> +#include <stand.h> >>> +#include <sys/errno.h> >>> +#include <bootstrap.h> >>> +#include <stdbool.h> >>> + >>> +#include <efi.h> >>> +#include <efilib.h> >>> + >>> +#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" >>> >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1860c146-7f49-37a6-740f-ad0f33b1df79>