Fri Sep 15 15:44:20 2023 UTC ()
Pull up following revision(s) (requested by rin in ticket #1897):

	sys/arch/i386/stand/efiboot/Makefile.efiboot: revision 1.22
	sys/arch/i386/stand/efiboot/eficpufunc.c: revision 1.1
	sys/arch/i386/stand/efiboot/eficpufunc.h: revision 1.1
	sys/arch/i386/stand/efiboot/eficons.c: revision 1.13
	sys/arch/i386/stand/efiboot/eficons.c: revision 1.14

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

efiboot/x86: eficons.c: Explicitly include params.h for howmany()

NFC for -current and netbsd-10, but necessary for netbsd-[89] to
pull up raw IO serial port support (PR port-amd64/57523).


(martin)
diff -r1.9.2.5 -r1.9.2.6 src/sys/arch/i386/stand/efiboot/Makefile.efiboot
diff -r1.4.2.6 -r1.4.2.7 src/sys/arch/i386/stand/efiboot/eficons.c
diff -r0 -r1.1.6.2 src/sys/arch/i386/stand/efiboot/eficpufunc.c
diff -r0 -r1.1.6.2 src/sys/arch/i386/stand/efiboot/eficpufunc.h

cvs diff -r1.9.2.5 -r1.9.2.6 src/sys/arch/i386/stand/efiboot/Makefile.efiboot (expand / switch to unified diff)

--- src/sys/arch/i386/stand/efiboot/Makefile.efiboot 2019/09/18 17:30:05 1.9.2.5
+++ src/sys/arch/i386/stand/efiboot/Makefile.efiboot 2023/09/15 15:44:20 1.9.2.6
@@ -1,28 +1,30 @@ @@ -1,28 +1,30 @@
1# $NetBSD: Makefile.efiboot,v 1.9.2.5 2019/09/18 17:30:05 martin Exp $ 1# $NetBSD: Makefile.efiboot,v 1.9.2.6 2023/09/15 15:44:20 martin Exp $
2 2
3S= ${.CURDIR}/../../../../.. 3S= ${.CURDIR}/../../../../..
4 4
5NOMAN= # defined 5NOMAN= # defined
6PROG?= boot.efi 6PROG?= boot.efi
7NEWVERSWHAT?= "EFI Boot" 7NEWVERSWHAT?= "EFI Boot"
8 8
9AFLAGS.start.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:} 9AFLAGS.start.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
10 10
11SOURCES= start.S boot.c conf.c devopen.c dev_net.c self_reloc.c panic.c 11SOURCES= start.S boot.c conf.c devopen.c dev_net.c self_reloc.c panic.c
12SOURCES+= efiboot.c efichar.c eficons.c efidelay.c efidev.c 12SOURCES+= efiboot.c efichar.c eficons.c efidelay.c efidev.c
 13SOURCES+= eficpufunc.c
13SOURCES+= efidisk.c efidisk_ll.c efigetsecs.c efimemory.c 14SOURCES+= efidisk.c efidisk_ll.c efigetsecs.c efimemory.c
14SOURCES+= efinet.c efipxe.c 15SOURCES+= efinet.c efipxe.c
15LIBI386SRCS= biosdisk.c bootinfo.c bootinfo_biosgeom.c bootmenu.c 16LIBI386SRCS= biosdisk.c bootinfo.c bootinfo_biosgeom.c bootmenu.c
 17LIBI386SRCS+= comio_direct.c
16LIBI386SRCS+= diskbuf.c exec.c menuutils.c parseutils.c pread.c 18LIBI386SRCS+= diskbuf.c exec.c menuutils.c parseutils.c pread.c
17LIBI386SRCS+= exec_multiboot1.c exec_multiboot2.c 19LIBI386SRCS+= exec_multiboot1.c exec_multiboot2.c
18# use our own nfs implementation 20# use our own nfs implementation
19LIBSASRCS+= nfs.c 21LIBSASRCS+= nfs.c
20SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS} ${LIBSASRCS} 22SRCS= ${SOURCES} ${EXTRA_SOURCES} ${LIBI386SRCS} ${LIBSASRCS}
21 23
22PIE_CFLAGS= 24PIE_CFLAGS=
23PIE_LDFLAGS= 25PIE_LDFLAGS=
24PIE_AFLAGS= 26PIE_AFLAGS=
25 27
26.include <bsd.own.mk> 28.include <bsd.own.mk>
27 29
28STRIPFLAG= # nothing 30STRIPFLAG= # nothing

cvs diff -r1.4.2.6 -r1.4.2.7 src/sys/arch/i386/stand/efiboot/eficons.c (expand / switch to unified diff)

--- src/sys/arch/i386/stand/efiboot/eficons.c 2020/03/09 09:48:00 1.4.2.6
+++ src/sys/arch/i386/stand/efiboot/eficons.c 2023/09/15 15:44:20 1.4.2.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: eficons.c,v 1.4.2.6 2020/03/09 09:48:00 martin Exp $ */ 1/* $NetBSD: eficons.c,v 1.4.2.7 2023/09/15 15:44:20 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org> 4 * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -16,29 +16,32 @@ @@ -16,29 +16,32 @@
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
 29#include <sys/param.h>
29#include <sys/bitops.h> 30#include <sys/bitops.h>
30#include <sys/stdint.h> 31#include <sys/stdint.h>
31 32
 33#include <comio_direct.h>
 34
32#include "efiboot.h" 35#include "efiboot.h"
33 36
34#include "bootinfo.h" 37#include "bootinfo.h"
35#include "vbe.h" 38#include "vbe.h"
36 39
37#ifndef DEFAULT_GOP_MODE 40#ifndef DEFAULT_GOP_MODE
38#define DEFAULT_GOP_MODE "1024x768" 41#define DEFAULT_GOP_MODE "1024x768"
39#endif 42#endif
40#define FALLBACK_GOP_MODE 0 43#define FALLBACK_GOP_MODE 0
41 44
42extern struct x86_boot_params boot_params; 45extern struct x86_boot_params boot_params;
43 46
44struct btinfo_console btinfo_console; 47struct btinfo_console btinfo_console;
@@ -50,42 +53,50 @@ static int keybuf_read = 0; @@ -50,42 +53,50 @@ static int keybuf_read = 0;
50static int keybuf_write = 0; 53static int keybuf_write = 0;
51 54
52static SERIAL_IO_INTERFACE *serios[4]; 55static SERIAL_IO_INTERFACE *serios[4];
53static int default_comspeed = 56static int default_comspeed =
54#if defined(CONSPEED) 57#if defined(CONSPEED)
55 CONSPEED; 58 CONSPEED;
56#else 59#else
57 9600; 60 9600;
58#endif 61#endif
59static u_char serbuf[16]; 62static u_char serbuf[16];
60static int serbuf_read = 0; 63static int serbuf_read = 0;
61static int serbuf_write = 0; 64static int serbuf_write = 0;
62 65
 66static int raw_com_addr = 0;
 67
63static void eficons_init_video(void); 68static void eficons_init_video(void);
64static void efi_switch_video_to_text_mode(void); 69static void efi_switch_video_to_text_mode(void);
65 70
66static int efi_cons_getc(void); 71static int efi_cons_getc(void);
67static int efi_cons_putc(int); 72static int efi_cons_putc(int);
68static int efi_cons_iskey(int); 73static int efi_cons_iskey(int);
69static int efi_cons_waitforinputevent(uint64_t); 74static int efi_cons_waitforinputevent(uint64_t);
70 75
71static void efi_com_probe(void); 76static void efi_com_probe(void);
72static bool efi_valid_com(int); 77static bool efi_valid_com(int);
73static int efi_com_init(int, int); 78static int efi_com_init(int, int);
74static int efi_com_getc(void); 79static int efi_com_getc(void);
75static int efi_com_putc(int); 80static int efi_com_putc(int);
76static int efi_com_status(int); 81static int efi_com_status(int);
77static int efi_com_waitforinputevent(uint64_t); 82static int efi_com_waitforinputevent(uint64_t);
78 83
 84static int raw_com_init(int, int);
 85static int raw_com_getc(void);
 86static int raw_com_putc(int);
 87static int raw_com_status(int);
 88static int raw_com_waitforinputevent(uint64_t);
 89
79static int efi_find_gop_mode(char *); 90static int efi_find_gop_mode(char *);
80 91
81static int iodev; 92static int iodev;
82static int (*internal_getchar)(void) = efi_cons_getc; 93static int (*internal_getchar)(void) = efi_cons_getc;
83static int (*internal_putchar)(int) = efi_cons_putc; 94static int (*internal_putchar)(int) = efi_cons_putc;
84static int (*internal_iskey)(int) = efi_cons_iskey; 95static int (*internal_iskey)(int) = efi_cons_iskey;
85static int (*internal_waitforinputevent)(uint64_t) = efi_cons_waitforinputevent; 96static int (*internal_waitforinputevent)(uint64_t) = efi_cons_waitforinputevent;
86 97
87static int 98static int
88getcomaddr(int idx) 99getcomaddr(int idx)
89{ 100{
90 static const short comioport[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; 101 static const short comioport[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
91 102
@@ -124,43 +135,38 @@ efi_consinit(int dev, int ioport, int sp @@ -124,43 +135,38 @@ efi_consinit(int dev, int ioport, int sp
124 awaitkey(7, 0)) 135 awaitkey(7, 0))
125 goto ok; 136 goto ok;
126 } 137 }
127 goto nocom; 138 goto nocom;
128ok: 139ok:
129 break; 140 break;
130 141
131 case CONSDEV_COM0: 142 case CONSDEV_COM0:
132 case CONSDEV_COM1: 143 case CONSDEV_COM1:
133 case CONSDEV_COM2: 144 case CONSDEV_COM2:
134 case CONSDEV_COM3: 145 case CONSDEV_COM3:
135 iodev = dev; 146 iodev = dev;
136 btinfo_console.addr = ioport; 147 btinfo_console.addr = ioport;
137 if (btinfo_console.addr == 0) { 148 if (btinfo_console.addr == 0)
138 if (!efi_valid_com(iodev)) 
139 goto nocom; 
140 btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0); 149 btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0);
141 } 
142 if (speed != 0) 150 if (speed != 0)
143 btinfo_console.speed = speed; 151 btinfo_console.speed = speed;
144 efi_com_init(btinfo_console.addr, btinfo_console.speed); 152 efi_com_init(btinfo_console.addr, btinfo_console.speed);
145 break; 153 break;
146 154
147 case CONSDEV_COM0KBD: 155 case CONSDEV_COM0KBD:
148 case CONSDEV_COM1KBD: 156 case CONSDEV_COM1KBD:
149 case CONSDEV_COM2KBD: 157 case CONSDEV_COM2KBD:
150 case CONSDEV_COM3KBD: 158 case CONSDEV_COM3KBD:
151 iodev = dev - CONSDEV_COM0KBD + CONSDEV_COM0; 159 iodev = dev - CONSDEV_COM0KBD + CONSDEV_COM0;
152 if (!efi_valid_com(iodev)) 
153 goto nocom; 
154 btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0); 160 btinfo_console.addr = getcomaddr(iodev - CONSDEV_COM0);
155 161
156 efi_cons_putc('0' + iodev - CONSDEV_COM0); 162 efi_cons_putc('0' + iodev - CONSDEV_COM0);
157 efi_com_init(btinfo_console.addr, btinfo_console.speed); 163 efi_com_init(btinfo_console.addr, btinfo_console.speed);
158 /* check for: 164 /* check for:
159 * 1. successful output 165 * 1. successful output
160 * 2. optionally, keypress within 7s 166 * 2. optionally, keypress within 7s
161 */ 167 */
162 if (efi_com_putc(':') && 168 if (efi_com_putc(':') &&
163 efi_com_putc('-') && 169 efi_com_putc('-') &&
164 efi_com_putc('(') && 170 efi_com_putc('(') &&
165 awaitkey(7, 0)) 171 awaitkey(7, 0))
166 goto kbd; 172 goto kbd;
@@ -858,42 +864,43 @@ efi_valid_com(int dev) @@ -858,42 +864,43 @@ efi_valid_com(int dev)
858 getcomaddr(idx) != 0; 864 getcomaddr(idx) != 0;
859} 865}
860 866
861static int 867static int
862efi_com_init(int addr, int speed) 868efi_com_init(int addr, int speed)
863{ 869{
864 EFI_STATUS status; 870 EFI_STATUS status;
865 SERIAL_IO_INTERFACE *serio; 871 SERIAL_IO_INTERFACE *serio;
866 872
867 if (speed <= 0) 873 if (speed <= 0)
868 return 0; 874 return 0;
869 875
870 if (!efi_valid_com(iodev)) 876 if (!efi_valid_com(iodev))
871 return 0; 877 return raw_com_init(addr, speed);
872 878
873 serio = serios[iodev - CONSDEV_COM0]; 879 serio = serios[iodev - CONSDEV_COM0];
874 880
875 if (serio->Mode->BaudRate != btinfo_console.speed) { 881 if (serio->Mode->BaudRate != btinfo_console.speed) {
876 status = uefi_call_wrapper(serio->SetAttributes, 7, serio, 882 status = uefi_call_wrapper(serio->SetAttributes, 7, serio,
877 speed, serio->Mode->ReceiveFifoDepth, 883 speed, serio->Mode->ReceiveFifoDepth,
878 serio->Mode->Timeout, serio->Mode->Parity, 884 serio->Mode->Timeout, serio->Mode->Parity,
879 serio->Mode->DataBits, serio->Mode->StopBits); 885 serio->Mode->DataBits, serio->Mode->StopBits);
880 if (EFI_ERROR(status)) { 886 if (EFI_ERROR(status)) {
881 printf("com%d: SetAttribute() failed with status=%" PRIxMAX 887 printf("com%d: SetAttribute() failed with status=%" PRIxMAX
882 "\n", iodev - CONSDEV_COM0, (uintmax_t)status); 888 "\n", iodev - CONSDEV_COM0, (uintmax_t)status);
883 return 0; 889 return 0;
884 } 890 }
885 } 891 }
886 892
 893 raw_com_addr = 0;
887 default_comspeed = speed; 894 default_comspeed = speed;
888 internal_getchar = efi_com_getc; 895 internal_getchar = efi_com_getc;
889 internal_putchar = efi_com_putc; 896 internal_putchar = efi_com_putc;
890 internal_iskey = efi_com_status; 897 internal_iskey = efi_com_status;
891 internal_waitforinputevent = efi_com_waitforinputevent; 898 internal_waitforinputevent = efi_com_waitforinputevent;
892 memset(serbuf, 0, sizeof(serbuf)); 899 memset(serbuf, 0, sizeof(serbuf));
893 serbuf_read = serbuf_write = 0; 900 serbuf_read = serbuf_write = 0;
894 901
895 return speed; 902 return speed;
896} 903}
897 904
898static int 905static int
899efi_com_getc(void) 906efi_com_getc(void)
@@ -1008,13 +1015,75 @@ efi_com_waitforinputevent(uint64_t timeo @@ -1008,13 +1015,75 @@ efi_com_waitforinputevent(uint64_t timeo
1008 uefi_call_wrapper(BS->CloseEvent, 1, timer); 1015 uefi_call_wrapper(BS->CloseEvent, 1, timer);
1009 return EINVAL; 1016 return EINVAL;
1010 } 1017 }
1011 status = WaitForSingleEvent(&timer, timeout); 1018 status = WaitForSingleEvent(&timer, timeout);
1012 uefi_call_wrapper(BS->SetTimer, 3, periodic, TimerCancel, 0); 1019 uefi_call_wrapper(BS->SetTimer, 3, periodic, TimerCancel, 0);
1013 uefi_call_wrapper(BS->CloseEvent, 1, periodic); 1020 uefi_call_wrapper(BS->CloseEvent, 1, periodic);
1014 uefi_call_wrapper(BS->CloseEvent, 1, timer); 1021 uefi_call_wrapper(BS->CloseEvent, 1, timer);
1015 if (!EFI_ERROR(status)) 1022 if (!EFI_ERROR(status))
1016 return 0; 1023 return 0;
1017 if (status == EFI_TIMEOUT) 1024 if (status == EFI_TIMEOUT)
1018 return ETIMEDOUT; 1025 return ETIMEDOUT;
1019 return EINVAL; 1026 return EINVAL;
1020} 1027}
 1028
 1029static int
 1030raw_com_init(int addr, int speed)
 1031{
 1032
 1033 if (addr == 0 || speed <= 0)
 1034 return 0;
 1035
 1036 speed = cominit_d(addr, speed);
 1037
 1038 raw_com_addr = addr;
 1039 default_comspeed = speed;
 1040 internal_getchar = raw_com_getc;
 1041 internal_putchar = raw_com_putc;
 1042 internal_iskey = raw_com_status;
 1043 internal_waitforinputevent = raw_com_waitforinputevent;
 1044
 1045 return speed;
 1046}
 1047
 1048static int
 1049raw_com_getc(void)
 1050{
 1051
 1052 if (raw_com_addr == 0)
 1053 panic("%s: Invalid serial port", __func__);
 1054 return comgetc_d(raw_com_addr);
 1055}
 1056
 1057static int
 1058raw_com_putc(int c)
 1059{
 1060
 1061 if (raw_com_addr == 0)
 1062 panic("%s: Invalid serial port", __func__);
 1063 return computc_d(c, raw_com_addr);
 1064}
 1065
 1066static int
 1067raw_com_status(int intr)
 1068{
 1069
 1070 if (raw_com_addr == 0)
 1071 panic("%s: Invalid serial port", __func__);
 1072 return comstatus_d(raw_com_addr);
 1073}
 1074
 1075static int
 1076raw_com_waitforinputevent(uint64_t timeout /* in 0.1 usec */)
 1077{
 1078 uint64_t ms;
 1079
 1080 if (raw_com_addr == 0)
 1081 panic("%s: Invalid serial port", __func__);
 1082
 1083 for (ms = howmany(timeout, 10 * 1000); ms != 0; ms--) {
 1084 if (raw_com_status(0))
 1085 return 0;
 1086 uefi_call_wrapper(BS->Stall, 1, 1000);
 1087 }
 1088 return ETIMEDOUT;
 1089}

File Added: src/sys/arch/i386/stand/efiboot/eficpufunc.c
/*	$NetBSD: eficpufunc.c,v 1.1.6.2 2023/09/15 15:44:20 martin 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));
}

File Added: src/sys/arch/i386/stand/efiboot/eficpufunc.h
/*	$NetBSD: eficpufunc.h,v 1.1.6.2 2023/09/15 15:44:20 martin 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);