git: 8ea7fa16d9fe - main - uart: Don't change settings or throttle putc for Hyper-V

From: Wei Hu <whu_at_FreeBSD.org>
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 */