On Fri, 17 Apr 2026 20:48:35 +0200,
Kirill A. Korinsky <[email protected]> wrote:
> 
> bugs@,
> 
> I'd like to share that little that I do have for now with attempt to boot
> bsd.rd from todays snapshot at Juniper Networks SRX300 which smeels like a
> corrupted memory:
> 

No, it isn't corrupted memory.

This device needs serial with 9660 only, and cn30xxuart had hardcoded
115200, and as soon as kernel replaces console from bootloader's 9600 to
kernel's hardcoded 115200 garbage came.

Here a patch where I read the programmed UART divisor instead and derive
comconsrate from it, so the kernel preserves the bootloader console
configuration.

Tested on SRX300 which boots, and does not break serial at EdgeRouter USG
which needs 115200.

Ok?

Index: sys/arch/octeon/dev/cn30xxuart.c
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/cn30xxuart.c,v
diff -u -p -r1.13 cn30xxuart.c
--- sys/arch/octeon/dev/cn30xxuart.c    6 Apr 2022 18:59:27 -0000       1.13
+++ sys/arch/octeon/dev/cn30xxuart.c    18 Apr 2026 21:35:56 -0000
@@ -66,6 +66,7 @@ cons_decl(octuart);
 
 /* XXX: What is this used for? Removed from stand/boot/uart.c -r1.2 */
 static int delay_changed = 1;
+static int cn30xxuart_get_divisor(void);
 int cn30xxuart_delay(void);
 void cn30xxuart_wait_txhr_empty(int);
 
@@ -85,10 +86,16 @@ bus_space_t uartbus_tag = {
 void
 com_fdt_init_cons(void)
 {
+       int divisor;
+
        comconsiot = &uartbus_tag;
        comconsaddr = OCTEON_UART0_BASE;
        comconsfreq = octeon_ioclock_speed();
-       comconsrate = B115200;
+       divisor = cn30xxuart_get_divisor();
+       if (divisor > 0)
+               comconsrate = comconsfreq / 16 / divisor;
+       else
+               comconsrate = TTYDEF_SPEED;
        comconscflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8;
 }
 
@@ -161,21 +168,30 @@ cn30xxuart_intr(void *arg)
  * Early console routines.
  */
 
-int
-cn30xxuart_delay(void)
+static int
+cn30xxuart_get_divisor(void)
 {
        int divisor;
        u_char lcr;
-       static int d = 0;
 
-       if (!delay_changed)
-               return d;
-       delay_changed = 0;
        lcr = octeon_xkphys_read_8(MIO_UART0_LCR);
        octeon_xkphys_write_8(MIO_UART0_LCR, lcr | LCR_DLAB);
        divisor = octeon_xkphys_read_8(MIO_UART0_DLL) |
                octeon_xkphys_read_8(MIO_UART0_DLH) << 8;
        octeon_xkphys_write_8(MIO_UART0_LCR, lcr);
+
+       return divisor;
+}
+
+int
+cn30xxuart_delay(void)
+{
+       static int d = 0;
+
+       if (!delay_changed)
+               return d;
+       delay_changed = 0;
+       (void)cn30xxuart_get_divisor();
 
        return 10; /* return an approx delay value */
 }



-- 
wbr, Kirill

Reply via email to