git: 8ea7fa16d9fe - main - uart: Don't change settings or throttle putc for Hyper-V
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 18 Mar 2023 07:20:34 UTC
The branch main has been updated by whu:
URL: https://cgit.FreeBSD.org/src/commit/?id=8ea7fa16d9fe5acb7d42a223efbfa23627aa5e0c
commit 8ea7fa16d9fe5acb7d42a223efbfa23627aa5e0c
Author: Wei Hu <whu@FreeBSD.org>
AuthorDate: 2023-03-14 15:49:33 +0000
Commit: Wei Hu <whu@FreeBSD.org>
CommitDate: 2023-03-18 07:07:54 +0000
uart: Don't change settings or throttle putc for Hyper-V
Azure setup does not like it when FreeBSD overrides the settings of the
UART device. When Hyper-V is detected, don't do this and also don't
throttle putc() output. This is a workaround for the early boot hang
of FreeBSD on Azure.
Tested on Azure, ESXi (VM with serial port), and SG-8200
PR: 264267
Reviewed by: kevans, whu
Tested by: whu
Obtained from: Rubicon Communications, LLC (Netgate)
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (Netgate)
---
sys/dev/uart/uart_dev_ns8250.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 475ab5d4425e..2c44e9e34b8b 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -249,6 +249,10 @@ ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int divisor;
uint8_t lcr;
+ /* Don't change settings when running on Hyper-V */
+ if (vm_guest == VM_GUEST_HV)
+ return (0);
+
lcr = 0;
if (databits >= 8)
lcr |= LCR_8BITS;
@@ -374,9 +378,11 @@ ns8250_putc(struct uart_bas *bas, int c)
{
int limit;
- limit = 250000;
- while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit)
- DELAY(4);
+ if (vm_guest != VM_GUEST_HV) {
+ limit = 250000;
+ while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit)
+ DELAY(4);
+ }
uart_setreg(bas, REG_DATA, c);
uart_barrier(bas);
}
@@ -532,15 +538,15 @@ ns8250_bus_attach(struct uart_softc *sc)
#endif
if (!resource_int_value("uart", device_get_unit(sc->sc_dev), "flags",
&ivar)) {
- if (UART_FLAGS_FCR_RX_LOW(ivar))
+ if (UART_FLAGS_FCR_RX_LOW(ivar))
ns8250->fcr |= FCR_RX_LOW;
- else if (UART_FLAGS_FCR_RX_MEDL(ivar))
+ else if (UART_FLAGS_FCR_RX_MEDL(ivar))
ns8250->fcr |= FCR_RX_MEDL;
- else if (UART_FLAGS_FCR_RX_HIGH(ivar))
+ else if (UART_FLAGS_FCR_RX_HIGH(ivar))
ns8250->fcr |= FCR_RX_HIGH;
else
ns8250->fcr |= FCR_RX_MEDH;
- } else
+ } else
ns8250->fcr |= FCR_RX_MEDH;
/* Get IER mask */