The branch main has been updated by imp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=dea3eef94cafb3bb1e5f04bc96b5636ffca92ee7

commit dea3eef94cafb3bb1e5f04bc96b5636ffca92ee7
Author:     Warner Losh <i...@freebsd.org>
AuthorDate: 2025-01-15 02:17:46 +0000
Commit:     Warner Losh <i...@freebsd.org>
CommitDate: 2025-01-15 02:24:35 +0000

    uart: Ingore pl011 historic mistakes
    
    Some veresions of EDK-II and QEMU reported the wrong values for the
    register shift and the region I/O size. Detect those and set it to the
    correct values. In general, anything other than a shift of 2 and a
    regio width of 4 (bytes, or 32 bits) is a mistake. However, allow
    for overrides in the future by only overriding the buggy values.
    Otherwise, we will fail to boot.
    
    PR:                     282936
    Sponsored by:           Netflix
    Reviewed by:            emaste
    Differential Revision:  https://reviews.freebsd.org/D47946
---
 sys/dev/uart/uart_dev_pl011.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c
index 4f946f7c5f36..e7a2ff7a85f1 100644
--- a/sys/dev/uart/uart_dev_pl011.c
+++ b/sys/dev/uart/uart_dev_pl011.c
@@ -172,6 +172,27 @@ static int
 uart_pl011_probe(struct uart_bas *bas)
 {
 
+       /*
+        * Versions of QEMU before 41f7b58b634e (8.3) reported bogus values for
+        * this tabel. The PL011 IP is always 32-bits wide and should be shifted
+        * 2 to match the 4-byte size of the data. QEMU reported these values
+        * incorrectly before that.
+        * 
https://github.com/qemu/qemu/commit/41f7b58b634ec3b60ae874375d2bbb61d790971e
+        *
+        * In additon, other hardware vendors also reported this value
+        * incorrectly. It's not tied to what the ACPI device node is, but was a
+        * misunderstanding coupled with a Linux driver that didn't need the
+        * right values. Quirks used to be used to ignore the bad values, now we
+        * detect the historic mistake and override (to allow for a future where
+        * we may need to override these values).
+        *
+        * PL011 Docs: https://developer.arm.com/documentation/ddi0183/latest/
+        */
+       if (bas->regshft == 0 || bas->regiowidth == 1) {
+               bas->regshft = 2;
+               bas->regiowidth = 4;
+       }
+
        return (0);
 }
 
@@ -356,7 +377,8 @@ static struct uart_class uart_pl011_class = {
        .uc_ops = &uart_pl011_ops,
        .uc_range = 0x48,
        .uc_rclk = 0,
-       .uc_rshift = 2
+       .uc_rshift = 2,
+       .uc_riowidth = 4,
 };
 UART_CLASS(uart_pl011_class);
 

Reply via email to