match recent Intel CPUs in fw_update(8)
Intel CPUs used to have strings like cpu0: Intel(R) Pentium(R) M processor 1200MHz ("GenuineIntel" 686-class) 1.20 GHz cpu0: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz, 2494.61 MHz, 06-3d-04 recent CPUs use cpu0: 11th Gen Intel(R) Core(TM) i5-1130G7 @ 1.10GHz, 30009.37 MHz, 06-8c-01 cpu0: 12th Gen Intel(R) Core(TM) i5-12400, 4390.71 MHz, 06-97-02 cpu0: 12th Gen Intel(R) Core(TM) i7-1260P, 1995.55 MHz, 06-9a-03 Index: patterns.c === RCS file: /cvs/src/usr.sbin/fw_update/patterns.c,v retrieving revision 1.3 diff -u -p -r1.3 patterns.c --- patterns.c 10 Mar 2022 07:12:13 - 1.3 +++ patterns.c 21 Jun 2022 04:31:24 - @@ -94,7 +94,7 @@ main(void) printf("%s\n", "bwfm"); printf("%s\n", "bwi"); printf("%s\n", "intel"); - printf("%s\n", "intel ^cpu0: Intel"); + printf("%s\n", "intel ^cpu0:*Intel(R)"); printf("%s\n", "inteldrm"); print_devices("inteldrm", i915_devices, nitems(i915_devices)); printf("%s\n", "ipw");
Re: pipex(4): protect global lists with mutex(9)
Hi, Only pppoe sessions are affected. Unfortunately, netlock is required for pipex(4) pppoe output processing, and we can’t enforce netlock state anymore for pppoe related (*if_qstart)(). We use netlock to protect pipex(4) global list and the dereference of `session’ pointers. Now we can’t rely on netlock state while we perform (*if_qstart)() and the `session’ dereference is unsafe because it could be killed by concurrent thread. The diff I posted to this thread only fixes this problem. I’ll fix pppoe output with the future diffs. > On 20 Jun 2022, at 21:47, Hrvoje Popovski wrote: > > On 20.6.2022. 16:46, Vitaliy Makkoveev wrote: >> And use this mutex(9) to make the `session' dereference safe. >> >> Hrvoje Popovski pointed me, he triggered netlock assertion with pipex(4) >> pppoe sessions: >> > > Hi, > > I can trigger this splassert with plain snapshot and with only pppoe > clients. npppd setup is without pf. > > r420-1# ifconfig ix0 > ix0: flags=8843 mtu 1500 >lladdr 90:e2:ba:19:29:a8 >index 1 priority 0 llprio 3 >media: Ethernet autoselect (10GSFP+Cu full-duplex,rxpause,txpause) >status: active >inet 192.168.100.205 netmask 0xff00 broadcast 192.168.100.255 > > > > r420-1# cat /etc/npppd/npppd.conf > authentication LOCAL type local { >users-file "/etc/npppd/npppd-users" > } > tunnel PPTP protocol pptp { > } > tunnel L2TP protocol l2tp { >authentication-method pap chap mschapv2 > } > tunnel PPPOE protocol pppoe { >listen on interface ix0 >authentication-method pap chap > } > > ipcp IPCP-L2TP { >pool-address 10.53.251.10-10.53.251.100 >dns-servers 161.53.2.69 > } > ipcp IPCP-PPTP { >pool-address 10.53.252.10-10.53.252.100 >dns-servers 161.53.2.69 > } > ipcp IPCP-PPPOE { >pool-address 10.53.253.10-10.53.253.100 > } > > interface pppac0 address 10.53.251.1 ipcp IPCP-L2TP > interface pppac1 address 10.53.252.1 ipcp IPCP-PPTP > interface pppac2 address 10.53.253.1 ipcp IPCP-PPPOE > > bind tunnel from L2TP authenticated by LOCAL to pppac0 > bind tunnel from PPTP authenticated by LOCAL to pppac1 > bind tunnel from PPPOE authenticated by LOCAL to pppac2 > > > r420-1# npppctl ses bri > Ppp Id Assigned IPv4 Username Proto Tunnel From > -- --- - > - > 0 10.53.253.11hrvojepppoe11PPPoE 90:e2:ba:33:af:ec > 1 10.53.253.12hrvojepppoe12PPPoE ec:f4:bb:c8:e9:88 > > > I'm generating traffic with iperf3 from pppoe hosts to hosts in > 192.168.100.0/24 network and at same time generating traffic between > pppoe hosts. > This triggers splassert after half a hour or so ... > > r420-1# splassert: pipex_ppp_output: want 2 have 0 > Starting stack trace... > pipex_ppp_output(fd80a45eaa00,800022782400,21) at > pipex_ppp_output+0x5e > pppac_qstart(80ec0ab0) at pppac_qstart+0x96 > ifq_serialize(80ec0ab0,80ec0b90) at ifq_serialize+0xfd > taskq_thread(80030080) at taskq_thread+0x100 > end trace frame: 0x0, count: 253 > End of stack trace. > > > >>> >>> r420-1# splassert: pipex_ppp_output: want 2 have 0 >>> Starting stack trace... >>> pipex_ppp_output(fd80cb7c9500,800022761200,21) at >>> pipex_ppp_output+0x5e >>> pppac_qstart(80e80ab0) at pppac_qstart+0x96 >>> ifq_serialize(80e80ab0,80e80b90) at ifq_serialize+0xfd >>> taskq_thread(80030080) at taskq_thread+0x100 >>> end trace frame: 0x0, count: 253 >>> End of stack trace. >>> splassert: pipex_ppp_output: want 2 have 0 >>> Starting stack trace... >>> pipex_ppp_output(fd80c53b2300,800022761200,21) at >>> pipex_ppp_output+0x5e >>> pppac_qstart(80e80ab0) at pppac_qstart+0x96 >>> ifq_serialize(80e80ab0,80e80b90) at ifq_serialize+0xfd >>> taskq_thread(80030080) at taskq_thread+0x100 >>> end trace frame: 0x0, count: 253 >>> End of stack trace. >>> >>> >>> r420-1# npppctl ses bri >>> Ppp Id Assigned IPv4 Username Proto Tunnel From >>> -- --- - >>> - >>> 7 10.53.251.22r6202L2TP 192.168.100.12:1701 >>> 1 10.53.253.11hrvojepppoe11PPPoE 90:e2:ba:33:af:ec >>> 0 10.53.253.12hrvojepppoe12PPPoE ec:f4:bb:da:f7:f8 >> >> This means the hack we use to enforce pppac_qstart() and >> pppx_if_qstart() be called with netlock held doesn't work anymore for >> pppoe sessions: >> >> /* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */ >> ifq_set_maxlen(>if_snd, 1); >> >> pptp and l2tp sessions are not affected, because the pcb layer is still >> accessed with exclusive netlock held, but the code is common for all >> session types. This mean we can't rely on netlock and should rework >> pipex(4) locking. >> >> The diff below introduces `pipex_list_mtx' mutex(9)
Re: pipex(4): protect global lists with mutex(9)
On 20.6.2022. 16:46, Vitaliy Makkoveev wrote: > And use this mutex(9) to make the `session' dereference safe. > > Hrvoje Popovski pointed me, he triggered netlock assertion with pipex(4) > pppoe sessions: > Hi, I can trigger this splassert with plain snapshot and with only pppoe clients. npppd setup is without pf. r420-1# ifconfig ix0 ix0: flags=8843 mtu 1500 lladdr 90:e2:ba:19:29:a8 index 1 priority 0 llprio 3 media: Ethernet autoselect (10GSFP+Cu full-duplex,rxpause,txpause) status: active inet 192.168.100.205 netmask 0xff00 broadcast 192.168.100.255 r420-1# cat /etc/npppd/npppd.conf authentication LOCAL type local { users-file "/etc/npppd/npppd-users" } tunnel PPTP protocol pptp { } tunnel L2TP protocol l2tp { authentication-method pap chap mschapv2 } tunnel PPPOE protocol pppoe { listen on interface ix0 authentication-method pap chap } ipcp IPCP-L2TP { pool-address 10.53.251.10-10.53.251.100 dns-servers 161.53.2.69 } ipcp IPCP-PPTP { pool-address 10.53.252.10-10.53.252.100 dns-servers 161.53.2.69 } ipcp IPCP-PPPOE { pool-address 10.53.253.10-10.53.253.100 } interface pppac0 address 10.53.251.1 ipcp IPCP-L2TP interface pppac1 address 10.53.252.1 ipcp IPCP-PPTP interface pppac2 address 10.53.253.1 ipcp IPCP-PPPOE bind tunnel from L2TP authenticated by LOCAL to pppac0 bind tunnel from PPTP authenticated by LOCAL to pppac1 bind tunnel from PPPOE authenticated by LOCAL to pppac2 r420-1# npppctl ses bri Ppp Id Assigned IPv4 Username Proto Tunnel From -- --- - - 0 10.53.253.11hrvojepppoe11PPPoE 90:e2:ba:33:af:ec 1 10.53.253.12hrvojepppoe12PPPoE ec:f4:bb:c8:e9:88 I'm generating traffic with iperf3 from pppoe hosts to hosts in 192.168.100.0/24 network and at same time generating traffic between pppoe hosts. This triggers splassert after half a hour or so ... r420-1# splassert: pipex_ppp_output: want 2 have 0 Starting stack trace... pipex_ppp_output(fd80a45eaa00,800022782400,21) at pipex_ppp_output+0x5e pppac_qstart(80ec0ab0) at pppac_qstart+0x96 ifq_serialize(80ec0ab0,80ec0b90) at ifq_serialize+0xfd taskq_thread(80030080) at taskq_thread+0x100 end trace frame: 0x0, count: 253 End of stack trace. >> >> r420-1# splassert: pipex_ppp_output: want 2 have 0 >> Starting stack trace... >> pipex_ppp_output(fd80cb7c9500,800022761200,21) at >> pipex_ppp_output+0x5e >> pppac_qstart(80e80ab0) at pppac_qstart+0x96 >> ifq_serialize(80e80ab0,80e80b90) at ifq_serialize+0xfd >> taskq_thread(80030080) at taskq_thread+0x100 >> end trace frame: 0x0, count: 253 >> End of stack trace. >> splassert: pipex_ppp_output: want 2 have 0 >> Starting stack trace... >> pipex_ppp_output(fd80c53b2300,800022761200,21) at >> pipex_ppp_output+0x5e >> pppac_qstart(80e80ab0) at pppac_qstart+0x96 >> ifq_serialize(80e80ab0,80e80b90) at ifq_serialize+0xfd >> taskq_thread(80030080) at taskq_thread+0x100 >> end trace frame: 0x0, count: 253 >> End of stack trace. >> >> >> r420-1# npppctl ses bri >> Ppp Id Assigned IPv4 Username Proto Tunnel From >> -- --- - >> - >> 7 10.53.251.22r6202L2TP 192.168.100.12:1701 >> 1 10.53.253.11hrvojepppoe11PPPoE 90:e2:ba:33:af:ec >> 0 10.53.253.12hrvojepppoe12PPPoE ec:f4:bb:da:f7:f8 > > This means the hack we use to enforce pppac_qstart() and > pppx_if_qstart() be called with netlock held doesn't work anymore for > pppoe sessions: > > /* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */ > ifq_set_maxlen(>if_snd, 1); > > pptp and l2tp sessions are not affected, because the pcb layer is still > accessed with exclusive netlock held, but the code is common for all > session types. This mean we can't rely on netlock and should rework > pipex(4) locking. > > The diff below introduces `pipex_list_mtx' mutex(9) to protect global > pipex(4) lists and made `session' dereference safe. It doesn't fix the > assertion, but only makes us sure the pppoe session can't be killed > concurrently while stack processes it. > > I'll protect pipex(4) session data and rework pipex(4) output with next > diffs. > > ok? > > Index: sys/net/if_ethersubr.c > === > RCS file: /cvs/src/sys/net/if_ethersubr.c,v > retrieving revision 1.279 > diff -u -p -r1.279 if_ethersubr.c > --- sys/net/if_ethersubr.c22 Apr 2022 12:10:57 - 1.279 > +++ sys/net/if_ethersubr.c20 Jun 2022 14:44:03 - > @@ -545,11 +545,14 @@ ether_input(struct ifnet *ifp, struct mb > if (pipex_enable) { > struct
Re: pluart(4): change baud rate
On Mon, Jun 20, 2022 at 02:42:52PM +, Visa Hankala wrote: > On Sun, Jun 19, 2022 at 03:06:47PM +0200, Anton Lindqvist wrote: > > This allows the pluart baud rate to be changed. There's one potential > > pitfall with this change as users will have the wrong baud rate in their > > /etc/ttys if not installed after revision 1.11 of dev/ic/pluart.c which > > landed today. This will make the serial console unusable until the > > expected baud rate in /etc/ttys is changed to 115200. > > An upgrade note would be good. I can prepare something for current.html. > > Comments? OK? > > > > diff --git sys/dev/fdt/pluart_fdt.c sys/dev/fdt/pluart_fdt.c > > index 969018eccdc..ac2467bdf47 100644 > > --- sys/dev/fdt/pluart_fdt.c > > +++ sys/dev/fdt/pluart_fdt.c > > @@ -27,6 +27,7 @@ > > > > #include > > #include > > +#include > > #include > > > > intpluart_fdt_match(struct device *, void *, void *); > > @@ -70,8 +71,12 @@ pluart_fdt_attach(struct device *parent, struct device > > *self, void *aux) > > return; > > } > > > > - if (OF_is_compatible(faa->fa_node, "arm,sbsa-uart")) > > + if (OF_is_compatible(faa->fa_node, "arm,sbsa-uart")) { > > sc->sc_hwflags |= COM_HW_SBSA; > > + } else { > > + clock_enable_all(faa->fa_node); > > + sc->sc_clkfreq = clock_get_frequency(faa->fa_node, "uartclk"); > > + } > > > > periphid = OF_getpropint(faa->fa_node, "arm,primecell-periphid", 0); > > if (periphid != 0) > > diff --git sys/dev/ic/pluart.c sys/dev/ic/pluart.c > > index 40e2b1976fb..aa4301e8fb0 100644 > > --- sys/dev/ic/pluart.c > > +++ sys/dev/ic/pluart.c > > @@ -71,9 +71,9 @@ > > #define UART_ILPR 0x20/* IrDA low-power counter > > register */ > > #define UART_ILPR_ILPDVSR ((x) & 0xf) /* IrDA low-power divisor */ > > #define UART_IBRD 0x24/* Integer baud rate register */ > > -#define UART_IBRD_DIVINT ((x) & 0xff)/* Integer baud rate divisor */ > > +#define UART_IBRD_DIVINT(x)((x) & 0xff)/* Integer baud rate > > divisor */ > > This mask should be 0x. Thanks, fixed. > > #define UART_FBRD 0x28/* Fractional baud rate > > register */ > > -#define UART_FBRD_DIVFRAC ((x) & 0x3f)/* Fractional baud rate divisor > > */ > > +#define UART_FBRD_DIVFRAC(x) ((x) & 0x3f)/* Fractional baud rate > > divisor */ > > #define UART_LCR_H 0x2c/* Line control register */ > > #define UART_LCR_H_BRK (1 << 0)/* Send break */ > > #define UART_LCR_H_PEN (1 << 1)/* Parity enable */ > > @@ -338,7 +338,9 @@ pluart_param(struct tty *tp, struct termios *t) > > /* lower dtr */ > > } > > > > - if (ospeed != 0) { > > + if (ospeed != 0 && sc->sc_clkfreq != 0 && tp->t_ospeed != ospeed) { > > + int div, lcr; > > + > > while (ISSET(tp->t_state, TS_BUSY)) { > > ++sc->sc_halt; > > error = ttysleep(tp, >t_outq, > > @@ -349,7 +351,40 @@ pluart_param(struct tty *tp, struct termios *t) > > return (error); > > } > > } > > - /* set speed */ > > + > > + /* > > +* Writes to IBRD and FBRD are made effective first when LCR_H > > +* is written. > > +*/ > > + lcr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, UART_LCR_H); > > + > > + /* The UART must be disabled while changing the baud rate. */ > > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_CR, 0); > > I think this should save original CR for restoring later, and set CR > with UARTEN masked out. > > cr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, UART_CR); > bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_CR, > cr & ~UART_CR_UARTEN); > > The PL011 manual says that reserved bits in CR should not be modified. > > > + > > + /* > > +* The baud rate divisor is expressed relative to the UART clock > > +* frequency where IBRD represents the quotient using 16 bits > > +* and FBRD the remainder using 6 bits. The PL011 specification > > +* provides the following formula: > > +* > > +* uartclk/(16 * baudrate) > > +* > > +* The formula can be estimated by scaling it with the > > +* precision 64 (2^6) and letting the resulting upper 16 bits > > +* represents the quotient and the lower 6 bits the remainder: > > +* > > +* 64 * uartclk/(16 * baudrate) = 4 * uartclk/baudrate > > +*/ > > + div = 4 * sc->sc_clkfreq / ospeed; > > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_IBRD, > > + UART_IBRD_DIVINT(div >> 6)); > > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_FBRD, > > +
Add note about locks with taskq, timeout and SMR barriers
The taskq, timeout and SMR barrier routines require that the thing that is being synchronized with is able to make progress. Consequently, the callers of these routines must not hold locks that can prevent that progress. The patch below documents this. OK? Index: smr_call.9 === RCS file: src/share/man/man9/smr_call.9,v retrieving revision 1.3 diff -u -p -r1.3 smr_call.9 --- smr_call.9 25 Feb 2020 16:53:25 - 1.3 +++ smr_call.9 20 Jun 2022 16:11:53 - @@ -96,6 +96,12 @@ but the system is forced to process the The use of this function is discouraged because of the heavy impact on system performance. .Pp +To avoid deadlocks, the caller of +.Fn smr_barrier +or +.Fn smr_flush +must not hold locks that can block the processing of SMR callbacks. +.Pp The SMR implementation does not limit the number of deferred calls. It is important to prevent arbitrary call rate of .Fn smr_call . Index: task_add.9 === RCS file: src/share/man/man9/task_add.9,v retrieving revision 1.22 diff -u -p -r1.22 task_add.9 --- task_add.9 8 Jun 2020 00:29:51 - 1.22 +++ task_add.9 20 Jun 2022 16:11:53 - @@ -108,6 +108,13 @@ from the list of pending tasks on the .Fa tq taskq, or waits until any running task has completed. .Pp +The caller of +.Fn taskq_barrier +or +.Fn taskq_del_barrier +must not hold locks that can block the taskq. +Otherwise, the system can deadlock. +.Pp It is the responsibility of the caller to provide the .Fn task_set , .Fn task_add , Index: timeout.9 === RCS file: src/share/man/man9/timeout.9,v retrieving revision 1.54 diff -u -p -r1.54 timeout.9 --- timeout.9 31 Mar 2022 17:27:23 - 1.54 +++ timeout.9 20 Jun 2022 16:11:53 - @@ -195,6 +195,13 @@ ensures that any current execution of th .Fa to has completed before returning. .Pp +The caller of +.Fn timeout_barrier +or +.Fn timeout_del_barrier +must not hold locks that can block processing in the timeout's context. +Otherwise, the system can deadlock. +.Pp The .Fn timeout_pending macro can be used to check if a timeout is scheduled to run.
pipex(4): protect global lists with mutex(9)
And use this mutex(9) to make the `session' dereference safe. Hrvoje Popovski pointed me, he triggered netlock assertion with pipex(4) pppoe sessions: > > r420-1# splassert: pipex_ppp_output: want 2 have 0 > Starting stack trace... > pipex_ppp_output(fd80cb7c9500,800022761200,21) at > pipex_ppp_output+0x5e > pppac_qstart(80e80ab0) at pppac_qstart+0x96 > ifq_serialize(80e80ab0,80e80b90) at ifq_serialize+0xfd > taskq_thread(80030080) at taskq_thread+0x100 > end trace frame: 0x0, count: 253 > End of stack trace. > splassert: pipex_ppp_output: want 2 have 0 > Starting stack trace... > pipex_ppp_output(fd80c53b2300,800022761200,21) at > pipex_ppp_output+0x5e > pppac_qstart(80e80ab0) at pppac_qstart+0x96 > ifq_serialize(80e80ab0,80e80b90) at ifq_serialize+0xfd > taskq_thread(80030080) at taskq_thread+0x100 > end trace frame: 0x0, count: 253 > End of stack trace. > > > r420-1# npppctl ses bri > Ppp Id Assigned IPv4 Username Proto Tunnel From > -- --- - > - > 7 10.53.251.22r6202L2TP 192.168.100.12:1701 > 1 10.53.253.11hrvojepppoe11PPPoE 90:e2:ba:33:af:ec > 0 10.53.253.12hrvojepppoe12PPPoE ec:f4:bb:da:f7:f8 This means the hack we use to enforce pppac_qstart() and pppx_if_qstart() be called with netlock held doesn't work anymore for pppoe sessions: /* XXXSMP: be sure pppac_qstart() called with NET_LOCK held */ ifq_set_maxlen(>if_snd, 1); pptp and l2tp sessions are not affected, because the pcb layer is still accessed with exclusive netlock held, but the code is common for all session types. This mean we can't rely on netlock and should rework pipex(4) locking. The diff below introduces `pipex_list_mtx' mutex(9) to protect global pipex(4) lists and made `session' dereference safe. It doesn't fix the assertion, but only makes us sure the pppoe session can't be killed concurrently while stack processes it. I'll protect pipex(4) session data and rework pipex(4) output with next diffs. ok? Index: sys/net/if_ethersubr.c === RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.279 diff -u -p -r1.279 if_ethersubr.c --- sys/net/if_ethersubr.c 22 Apr 2022 12:10:57 - 1.279 +++ sys/net/if_ethersubr.c 20 Jun 2022 14:44:03 - @@ -545,11 +545,14 @@ ether_input(struct ifnet *ifp, struct mb if (pipex_enable) { struct pipex_session *session; + mtx_enter(_list_mtx); if ((session = pipex_pppoe_lookup_session(m)) != NULL) { pipex_pppoe_input(m, session); + mtx_leave(_list_mtx); KERNEL_UNLOCK(); return; } + mtx_leave(_list_mtx); } #endif if (etype == ETHERTYPE_PPPOEDISC) Index: sys/net/if_gre.c === RCS file: /cvs/src/sys/net/if_gre.c,v retrieving revision 1.171 diff -u -p -r1.171 if_gre.c --- sys/net/if_gre.c10 Mar 2021 10:21:47 - 1.171 +++ sys/net/if_gre.c20 Jun 2022 14:44:03 - @@ -973,10 +973,18 @@ gre_input_1(struct gre_tunnel *key, stru if (pipex_enable) { struct pipex_session *session; + mtx_enter(_list_mtx); session = pipex_pptp_lookup_session(m); - if (session != NULL && - pipex_pptp_input(m, session) == NULL) - return (NULL); + if (session != NULL) { + struct mbuf *m0; + + m0 = pipex_pptp_input(m, session); + mtx_leave(_list_mtx); + + if (m0 == NULL) + return (NULL); + } + mtx_leave(_list_mtx); } #endif break; Index: sys/net/if_pppx.c === RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.114 diff -u -p -r1.114 if_pppx.c --- sys/net/if_pppx.c 22 Feb 2022 01:15:02 - 1.114 +++ sys/net/if_pppx.c 20 Jun 2022 14:44:03 - @@ -1322,9 +1322,7 @@ pppacclose(dev_t dev, int flags, int mod splx(s); pool_put(_session_pool, sc->sc_multicast_session); - NET_LOCK(); pipex_destroy_all_sessions(sc); - NET_UNLOCK(); LIST_REMOVE(sc, sc_entry); free(sc, M_DEVBUF, sizeof(*sc)); @@ -1384,11 +1382,15 @@ pppac_del_session(struct pppac_softc *sc { struct
Re: pluart(4): change baud rate
On Sun, Jun 19, 2022 at 03:06:47PM +0200, Anton Lindqvist wrote: > This allows the pluart baud rate to be changed. There's one potential > pitfall with this change as users will have the wrong baud rate in their > /etc/ttys if not installed after revision 1.11 of dev/ic/pluart.c which > landed today. This will make the serial console unusable until the > expected baud rate in /etc/ttys is changed to 115200. An upgrade note would be good. > Comments? OK? > > diff --git sys/dev/fdt/pluart_fdt.c sys/dev/fdt/pluart_fdt.c > index 969018eccdc..ac2467bdf47 100644 > --- sys/dev/fdt/pluart_fdt.c > +++ sys/dev/fdt/pluart_fdt.c > @@ -27,6 +27,7 @@ > > #include > #include > +#include > #include > > int pluart_fdt_match(struct device *, void *, void *); > @@ -70,8 +71,12 @@ pluart_fdt_attach(struct device *parent, struct device > *self, void *aux) > return; > } > > - if (OF_is_compatible(faa->fa_node, "arm,sbsa-uart")) > + if (OF_is_compatible(faa->fa_node, "arm,sbsa-uart")) { > sc->sc_hwflags |= COM_HW_SBSA; > + } else { > + clock_enable_all(faa->fa_node); > + sc->sc_clkfreq = clock_get_frequency(faa->fa_node, "uartclk"); > + } > > periphid = OF_getpropint(faa->fa_node, "arm,primecell-periphid", 0); > if (periphid != 0) > diff --git sys/dev/ic/pluart.c sys/dev/ic/pluart.c > index 40e2b1976fb..aa4301e8fb0 100644 > --- sys/dev/ic/pluart.c > +++ sys/dev/ic/pluart.c > @@ -71,9 +71,9 @@ > #define UART_ILPR0x20/* IrDA low-power counter > register */ > #define UART_ILPR_ILPDVSR((x) & 0xf) /* IrDA low-power divisor */ > #define UART_IBRD0x24/* Integer baud rate register */ > -#define UART_IBRD_DIVINT ((x) & 0xff)/* Integer baud rate divisor */ > +#define UART_IBRD_DIVINT(x) ((x) & 0xff)/* Integer baud rate divisor */ This mask should be 0x. > #define UART_FBRD0x28/* Fractional baud rate > register */ > -#define UART_FBRD_DIVFRAC((x) & 0x3f)/* Fractional baud rate divisor > */ > +#define UART_FBRD_DIVFRAC(x) ((x) & 0x3f)/* Fractional baud rate divisor > */ > #define UART_LCR_H 0x2c/* Line control register */ > #define UART_LCR_H_BRK (1 << 0)/* Send break */ > #define UART_LCR_H_PEN (1 << 1)/* Parity enable */ > @@ -338,7 +338,9 @@ pluart_param(struct tty *tp, struct termios *t) > /* lower dtr */ > } > > - if (ospeed != 0) { > + if (ospeed != 0 && sc->sc_clkfreq != 0 && tp->t_ospeed != ospeed) { > + int div, lcr; > + > while (ISSET(tp->t_state, TS_BUSY)) { > ++sc->sc_halt; > error = ttysleep(tp, >t_outq, > @@ -349,7 +351,40 @@ pluart_param(struct tty *tp, struct termios *t) > return (error); > } > } > - /* set speed */ > + > + /* > + * Writes to IBRD and FBRD are made effective first when LCR_H > + * is written. > + */ > + lcr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, UART_LCR_H); > + > + /* The UART must be disabled while changing the baud rate. */ > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_CR, 0); I think this should save original CR for restoring later, and set CR with UARTEN masked out. cr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, UART_CR); bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_CR, cr & ~UART_CR_UARTEN); The PL011 manual says that reserved bits in CR should not be modified. > + > + /* > + * The baud rate divisor is expressed relative to the UART clock > + * frequency where IBRD represents the quotient using 16 bits > + * and FBRD the remainder using 6 bits. The PL011 specification > + * provides the following formula: > + * > + * uartclk/(16 * baudrate) > + * > + * The formula can be estimated by scaling it with the > + * precision 64 (2^6) and letting the resulting upper 16 bits > + * represents the quotient and the lower 6 bits the remainder: > + * > + * 64 * uartclk/(16 * baudrate) = 4 * uartclk/baudrate > + */ > + div = 4 * sc->sc_clkfreq / ospeed; > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_IBRD, > + UART_IBRD_DIVINT(div >> 6)); > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_FBRD, > + UART_FBRD_DIVFRAC(div)); > + /* Commit baud rate change. */ > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, UART_LCR_H, lcr); > + /* Enable UART. */ > + bus_space_write_4(sc->sc_iot, sc->sc_ioh, > +