stand: efi create eficom console device.

Fix the 'renaming kludge' that we absolutely cannot do going forward
(it's cost us days of engineering time).

console=comconsole talks to the hardware directly. This is available
only on amd64. It is not available anywhere else (and so requires
changes for people doing comconsole on aarch64)

console=eficom talks to the console via EFI protocols.  It's available
on amd64, aarch64 and riscv64. It's the first port that we find, though
it can be overriden by efi_com_port (which should be set to the UID of
the serial port, not the I/O port, despite the name). devinfo -v
will give the UID to uartX mapping.

This is an incompatible change for HYPER-V on amd64. It only works with
eficom console, so you'll need to change your configuration in
loader.conf. No compatibility hack will ever be provided for this (since
it requires renamig, which the loader cannot reliably do).

It's also an incompatible change for aarch64. comconsole will need to
change to eficom. There might be a comconsole "shim" for this.

All the interlock to keep only eficom and comconsole from both attaching
have been removed.

RelNotes:		Yes
Sponsored by:		Netflix
Discussed with:		kevans
Differential Revision:	https://reviews.freebsd.org/D39982
This commit is contained in:
Warner Losh 2023-05-11 14:03:17 -06:00
parent 86c31aca33
commit 2f131435bc
3 changed files with 39 additions and 72 deletions

View File

@ -80,22 +80,18 @@ struct netif_driver *netif_drivers[] = {
};
extern struct console efi_console;
extern struct console comconsole;
#if defined(__amd64__)
extern struct console eficomconsole;
#endif
extern struct console eficom;
#if defined(__amd64__) || defined(__i386__)
extern struct console comconsole;
extern struct console nullconsole;
extern struct console spinconsole;
#endif
struct console *consoles[] = {
&efi_console,
#if defined(__amd64__)
&eficomconsole,
#endif
&comconsole,
&eficom,
#if defined(__amd64__) || defined(__i386__)
&comconsole,
&nullconsole,
&spinconsole,
#endif

View File

@ -69,14 +69,9 @@ static int comc_speed_set(struct env_var *, int, const void *);
static struct serial *comc_port;
extern struct console efi_console;
bool efi_comconsole_avail = false;
#if defined(__amd64__)
#define comconsole eficomconsole
#endif
struct console comconsole = {
.c_name = "comconsole",
struct console eficom = {
.c_name = "eficom",
.c_desc = "serial port",
.c_flags = 0,
.c_probe = comc_probe,
@ -259,18 +254,6 @@ comc_probe(struct console *sc)
char *env, *buf, *ep;
size_t sz;
#if defined(__amd64__)
/*
* For x86-64, don't use this driver if not running in Hyper-V.
*/
env = getenv("smbios.bios.version");
if (env == NULL || strncmp(env, "Hyper-V", 7) != 0) {
/* Disable being seen as "comconsole". */
comconsole.c_name = "efiserialio";
return;
}
#endif
if (comc_port == NULL) {
comc_port = calloc(1, sizeof (struct serial));
if (comc_port == NULL)
@ -339,13 +322,9 @@ comc_probe(struct console *sc)
env_setenv("efi_com_speed", EV_VOLATILE, value,
comc_speed_set, env_nounset);
comconsole.c_flags = 0;
eficom.c_flags = 0;
if (comc_setup()) {
sc->c_flags = C_PRESENTIN | C_PRESENTOUT;
efi_comconsole_avail = true;
} else {
/* disable being seen as "comconsole" */
comconsole.c_name = "efiserialio";
}
}
@ -356,7 +335,7 @@ comc_init(int arg __unused)
if (comc_setup())
return (CMD_OK);
comconsole.c_flags = 0;
eficom.c_flags = 0;
return (CMD_ERROR);
}
@ -522,35 +501,41 @@ comc_setup(void)
if (comc_port->sio == NULL)
return (false);
status = comc_port->sio->Reset(comc_port->sio);
if (EFI_ERROR(status))
return (false);
ev = getenv("smbios.bios.version");
if (ev != NULL && strncmp(ev, "Hyper-V", 7) == 0) {
status = comc_port->sio->SetAttributes(comc_port->sio,
0, 0, 0, DefaultParity, 0, DefaultStopBits);
} else {
status = comc_port->sio->SetAttributes(comc_port->sio,
comc_port->baudrate, comc_port->receivefifodepth,
comc_port->timeout, comc_port->parity,
comc_port->databits, comc_port->stopbits);
if (comc_port->sio->Reset != NULL) {
status = comc_port->sio->Reset(comc_port->sio);
if (EFI_ERROR(status))
return (false);
}
if (EFI_ERROR(status))
return (false);
if (comc_port->sio->SetAttributes != NULL) {
ev = getenv("smbios.bios.version");
if (ev != NULL && strncmp(ev, "Hyper-V", 7) == 0) {
status = comc_port->sio->SetAttributes(comc_port->sio,
0, 0, 0, DefaultParity, 0, DefaultStopBits);
} else {
status = comc_port->sio->SetAttributes(comc_port->sio,
comc_port->baudrate, comc_port->receivefifodepth,
comc_port->timeout, comc_port->parity,
comc_port->databits, comc_port->stopbits);
}
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;
if (EFI_ERROR(status))
return (false);
}
if (comc_port->sio->GetControl != NULL && comc_port->sio->SetControl != NULL) {
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);
}
(void) comc_port->sio->SetControl(comc_port->sio, control);
/* Mark this port usable. */
comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT);
eficom.c_flags |= (C_PRESENTIN | C_PRESENTOUT);
return (true);
}

View File

@ -85,20 +85,6 @@ comc_probe(struct console *cp)
int speed, port;
uint32_t locator;
#if defined(__amd64__)
extern bool efi_comconsole_avail;
if (efi_comconsole_avail) {
/*
* If EFI provides serial I/O, then don't use this legacy
* com driver to avoid conflicts with the firmware's driver.
* Change c_name so that it cannot be found in the lookup.
*/
comconsole.c_name = "xcomconsole";
return;
}
#endif
if (comc_curspeed == 0) {
comc_curspeed = COMSPEED;
/*