Module Name: src Committed By: rin Date: Mon Jul 24 01:56:59 UTC 2023
Modified Files: src/sys/arch/i386/stand/efiboot: Makefile.efiboot eficons.c Added Files: src/sys/arch/i386/stand/efiboot: eficpufunc.c eficpufunc.h Log Message: efiboot/x86: Add serial console support via raw I/O port access Unfortunately, some (most?) UEFI implementations do not support com ports by ``Serial I/O Protocol''. ``PNP0501-0'' and friends are not recognized also. In this case, if user explicitly requires to switch to serial console by ``consdev'' command, try to use raw I/O port access. Ugly, but what FreeBSD does, at least. Proposed as PR port-amd64/57523 To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 src/sys/arch/i386/stand/efiboot/Makefile.efiboot cvs rdiff -u -r1.12 -r1.13 src/sys/arch/i386/stand/efiboot/eficons.c cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/stand/efiboot/eficpufunc.c \ src/sys/arch/i386/stand/efiboot/eficpufunc.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/efiboot/Makefile.efiboot diff -u src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.21 src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.22 --- src/sys/arch/i386/stand/efiboot/Makefile.efiboot:1.21 Sat Jun 3 08:52:56 2023 +++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot Mon Jul 24 01:56:59 2023 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.efiboot,v 1.21 2023/06/03 08:52:56 lukem Exp $ +# $NetBSD: Makefile.efiboot,v 1.22 2023/07/24 01:56:59 rin Exp $ S= ${.CURDIR}/../../../../.. @@ -14,9 +14,11 @@ AFLAGS.start.S= ${${ACTIVE_CC} == "clang SOURCES= start.S boot.c conf.c devopen.c dev_net.c self_reloc.c panic.c SOURCES+= efiboot.c efichar.c eficons.c efidelay.c efidev.c +SOURCES+= eficpufunc.c SOURCES+= efidisk.c efidisk_ll.c efigetsecs.c efimemory.c SOURCES+= efinet.c efipxe.c LIBI386SRCS= biosdisk.c bootinfo.c bootinfo_biosgeom.c bootmenu.c +LIBI386SRCS+= comio_direct.c LIBI386SRCS+= diskbuf.c exec.c menuutils.c parseutils.c pread.c LIBI386SRCS+= exec_multiboot1.c exec_multiboot2.c # use our own nfs implementation Index: src/sys/arch/i386/stand/efiboot/eficons.c diff -u src/sys/arch/i386/stand/efiboot/eficons.c:1.12 src/sys/arch/i386/stand/efiboot/eficons.c:1.13 --- src/sys/arch/i386/stand/efiboot/eficons.c:1.12 Thu Oct 28 06:13:13 2021 +++ src/sys/arch/i386/stand/efiboot/eficons.c Mon Jul 24 01:56:59 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: eficons.c,v 1.12 2021/10/28 06:13:13 kim Exp $ */ +/* $NetBSD: eficons.c,v 1.13 2023/07/24 01:56:59 rin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -29,6 +29,8 @@ #include <sys/bitops.h> #include <sys/stdint.h> +#include <comio_direct.h> + #include "efiboot.h" #include "bootinfo.h" @@ -60,6 +62,8 @@ static u_char serbuf[16]; static int serbuf_read = 0; static int serbuf_write = 0; +static int raw_com_addr = 0; + static void eficons_init_video(void); static void efi_switch_video_to_text_mode(void); @@ -76,6 +80,12 @@ static int efi_com_putc(int); static int efi_com_status(int); static int efi_com_waitforinputevent(uint64_t); +static int raw_com_init(int, int); +static int raw_com_getc(void); +static int raw_com_putc(int); +static int raw_com_status(int); +static int raw_com_waitforinputevent(uint64_t); + static int efi_find_gop_mode(char *); static int iodev; @@ -134,11 +144,8 @@ ok: case CONSDEV_COM3: iodev = dev; btinfo_console.addr = ioport; - if (btinfo_console.addr == 0) { - if (!efi_valid_com(iodev)) - goto nocom; + if (btinfo_console.addr == 0) btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0); - } if (speed != 0) btinfo_console.speed = speed; efi_com_init(btinfo_console.addr, btinfo_console.speed); @@ -149,8 +156,6 @@ ok: case CONSDEV_COM2KBD: case CONSDEV_COM3KBD: iodev = dev - CONSDEV_COM0KBD + CONSDEV_COM0; - if (!efi_valid_com(iodev)) - goto nocom; btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0); efi_cons_putc('0' + iodev - CONSDEV_COM0); @@ -869,7 +874,7 @@ efi_com_init(int addr, int speed) return 0; if (!efi_valid_com(iodev)) - return 0; + return raw_com_init(addr, speed); serio = serios[iodev - CONSDEV_COM0]; @@ -885,6 +890,7 @@ efi_com_init(int addr, int speed) } } + raw_com_addr = 0; default_comspeed = speed; internal_getchar = efi_com_getc; internal_putchar = efi_com_putc; @@ -1019,3 +1025,65 @@ efi_com_waitforinputevent(uint64_t timeo return ETIMEDOUT; return EINVAL; } + +static int +raw_com_init(int addr, int speed) +{ + + if (addr == 0 || speed <= 0) + return 0; + + speed = cominit_d(addr, speed); + + raw_com_addr = addr; + default_comspeed = speed; + internal_getchar = raw_com_getc; + internal_putchar = raw_com_putc; + internal_iskey = raw_com_status; + internal_waitforinputevent = raw_com_waitforinputevent; + + return speed; +} + +static int +raw_com_getc(void) +{ + + if (raw_com_addr == 0) + panic("%s: Invalid serial port", __func__); + return comgetc_d(raw_com_addr); +} + +static int +raw_com_putc(int c) +{ + + if (raw_com_addr == 0) + panic("%s: Invalid serial port", __func__); + return computc_d(c, raw_com_addr); +} + +static int +raw_com_status(int intr) +{ + + if (raw_com_addr == 0) + panic("%s: Invalid serial port", __func__); + return comstatus_d(raw_com_addr); +} + +static int +raw_com_waitforinputevent(uint64_t timeout /* in 0.1 usec */) +{ + uint64_t ms; + + if (raw_com_addr == 0) + panic("%s: Invalid serial port", __func__); + + for (ms = howmany(timeout, 10 * 1000); ms != 0; ms--) { + if (raw_com_status(0)) + return 0; + uefi_call_wrapper(BS->Stall, 1, 1000); + } + return ETIMEDOUT; +} Added files: Index: src/sys/arch/i386/stand/efiboot/eficpufunc.c diff -u /dev/null src/sys/arch/i386/stand/efiboot/eficpufunc.c:1.1 --- /dev/null Mon Jul 24 01:56:59 2023 +++ src/sys/arch/i386/stand/efiboot/eficpufunc.c Mon Jul 24 01:56:59 2023 @@ -0,0 +1,48 @@ +/* $NetBSD: eficpufunc.c,v 1.1 2023/07/24 01:56:59 rin Exp $ */ + +/*- + * Copyright (c) 2023 The NetBSD Foundation, Inc. + * All rights reserved. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> +#include <sys/types.h> + +#include "eficpufunc.h" + +uint8_t +inb(uint32_t addr) +{ + uint8_t c; + + __asm volatile ("inb %%dx, %%al" : "=a"(c) : "d"(addr)); + return c; +} + +void +outb(uint32_t addr, uint8_t c) +{ + + __asm volatile ("outb %%al, %%dx" : : "a"(c), "d"(addr)); +} Index: src/sys/arch/i386/stand/efiboot/eficpufunc.h diff -u /dev/null src/sys/arch/i386/stand/efiboot/eficpufunc.h:1.1 --- /dev/null Mon Jul 24 01:56:59 2023 +++ src/sys/arch/i386/stand/efiboot/eficpufunc.h Mon Jul 24 01:56:59 2023 @@ -0,0 +1,38 @@ +/* $NetBSD: eficpufunc.h,v 1.1 2023/07/24 01:56:59 rin Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Functions compatible to i386/stand/lib/cpufunc.h with UEFI ABI. + * Currently, only used for raw console I/O by eficons.c. + */ + +uint8_t inb(uint32_t); +void outb(uint32_t, uint8_t);