From nobody Sat Jul 6 18:36:09 2024 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4WGfGz6q4qz5PNsH for ; Sat, 06 Jul 2024 18:36:27 +0000 (UTC) (envelope-from john@sanren.ac.za) Received: from mail-oi1-x22c.google.com (mail-oi1-x22c.google.com [IPv6:2607:f8b0:4864:20::22c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "WR4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4WGfGy4CYLz3xpq for ; Sat, 6 Jul 2024 18:36:25 +0000 (UTC) (envelope-from john@sanren.ac.za) Authentication-Results: mx1.freebsd.org; dkim=pass header.d=sanren-ac-za.20230601.gappssmtp.com header.s=20230601 header.b=r0qhUgKg; dmarc=none; spf=pass (mx1.freebsd.org: domain of john@sanren.ac.za designates 2607:f8b0:4864:20::22c as permitted sender) smtp.mailfrom=john@sanren.ac.za Received: by mail-oi1-x22c.google.com with SMTP id 5614622812f47-3c9cc66c649so1360552b6e.1 for ; Sat, 06 Jul 2024 11:36:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sanren-ac-za.20230601.gappssmtp.com; s=20230601; t=1720290984; x=1720895784; darn=freebsd.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=WQj0F7bcb+Ii1BL5ygypWb1cYHxd31doRGIk+qpQ3aM=; b=r0qhUgKgQrVWErN7PGNi3xqHhe08ZbDzEQXeS+xataI0UfshpWHZkJJ1AL9D2usCel iMpckZG7FgRyM0w05urcBI4hLaOmb5LvhgRej3hTQ97aPyNYpyaeAUnlNUORMefSf6HP DXoANYmGolIh6rpeVPka+GCaTA7cfakP9+dwMQFJSz+lN7QiF11h60jOc8qkpmmdCIWp Wugz06vSCiWM+UI+4BfGy0th5enUhveJWHezjqMh7HP4HO+C8ZE566hJgSJn/nE2s2Ht Pcmi0CXO4YotJIAjtRya0LchaLPVrv8VYS19IRQU1wIsOt9EAA5gqWywksFD7Toj0tpv iiPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720290984; x=1720895784; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=WQj0F7bcb+Ii1BL5ygypWb1cYHxd31doRGIk+qpQ3aM=; b=K6S8O/Gd0u+YcV0q0pWCzzOXgdLiWrPplnAora837r08Mt5UasvTVoC/gkzZwQ8L+Y UE9nnRjJdSo8IS1luZGQGlJ9ieuVsEKQ+tDlAi8rsXU4HirZjlW5K/AaEkYDq1YH+kBP Rajc6Ri58XxcCnbiWqHTY6c90GemCz5zXBEYPzKXLfFjfBvvQYa4R1P2mMYqLiuyTUc4 UzgAYfQyxFKX1FfmJHNd3VpXH00Kf4IKylCEM5Lwuc8pqOpFqlAHCWKhJGrTTH55oSem W8mx5+ySbgAbXJe31oi7EXr/0MkZcgQ4p4M/ZJtY6Hx1pylYn6AmN2dqfUXSxudgF4MK Or6Q== X-Gm-Message-State: AOJu0YyVuNHKIB7PeFxEbKfSa829/7zNyBCqm9eC9MOpLVRA+FvAZiJa aRadvSlD8cP3jjKF55pJlbUVhezeOl3VZE8Ip+93aAjDbf8MO2Ert1qaOaCfus7tD9ydJ8YjHO5 RgDoLfHAHlXWAqWltDKi4ch8ejJtyUDejA9E9Z60tDrKvmPdrw9CMRw== X-Google-Smtp-Source: AGHT+IEOmxdEHNKXBPSs3C1O8RJ7vRD99QIXGJiDPZgyOyZ1TZCyYUCBTMWrhqNKosl8mBFC8ukJQ2+nYdQpWdMgR0s= X-Received: by 2002:a05:6808:2e4f:b0:3d9:20c3:cdc3 with SMTP id 5614622812f47-3d920c3d323mr5897964b6e.48.1720290982434; Sat, 06 Jul 2024 11:36:22 -0700 (PDT) List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@FreeBSD.org MIME-Version: 1.0 From: John Hay Date: Sat, 6 Jul 2024 20:36:09 +0200 Message-ID: Subject: ns8250: UART FCR is broken, message might be misleading To: freebsd-hackers@freebsd.org Content-Type: multipart/alternative; boundary="000000000000eb39e8061c987479" X-Spamd-Bar: --- X-Spamd-Result: default: False [-3.50 / 15.00]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_SHORT(-1.00)[-1.000]; R_SPF_ALLOW(-0.20)[+ip6:2607:f8b0:4000::/36]; R_DKIM_ALLOW(-0.20)[sanren-ac-za.20230601.gappssmtp.com:s=20230601]; MIME_GOOD(-0.10)[multipart/alternative,text/plain]; RCPT_COUNT_ONE(0.00)[1]; ASN(0.00)[asn:15169, ipnet:2607:f8b0::/32, country:US]; RCVD_COUNT_ONE(0.00)[1]; MISSING_XM_UA(0.00)[]; MIME_TRACE(0.00)[0:+,1:+,2:~]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; DMARC_NA(0.00)[sanren.ac.za]; MLMMJ_DEST(0.00)[freebsd-hackers@freebsd.org]; TO_DN_NONE(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; RCVD_IN_DNSWL_NONE(0.00)[2607:f8b0:4864:20::22c:from]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_TLS_LAST(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; DKIM_TRACE(0.00)[sanren-ac-za.20230601.gappssmtp.com:+] X-Rspamd-Queue-Id: 4WGfGy4CYLz3xpq --000000000000eb39e8061c987479 Content-Type: text/plain; charset="UTF-8" Hi, I have 3 machines running FreeBSD 14.0. (I have upgraded one to 14.1 recently). All 3 have a uart with a GPS behind it, but no program reading from the uart. I see the "ns8250: UART FCR is broken" on all of them on average a little less than one per day. For example, the one machine has an uptime of 48 days. In that time the message was printed 44 times, but there was 12846 overruns according to the below sysctl: dev.uart.2.rx_overruns: 12846 If the FCR was really broken, I would have expected the message to be printed for every overrun. The 16550d documentation that I could find on the internet has this about Bit 1 of the Fifo Control Register (FCR): Bit 1 Writing a 1 to FCR1 clears all bytes in the RCVR FIFO and resets its counter logic to 0 The shift register is not cleared The 1 that is written to this bit position is self-clear-ing So what I think is happening is that occasionally when the RCVR FIFO is cleared, a character is almost received and between the RCVR is cleared and LSR bit LSR_RXRDY is checked, the new character is there. The piece of code in ns8250_flush() looks like this: uart_setreg(bas, REG_FCR, fcr); uart_barrier(bas); /* * Detect and work around emulated UARTs which don't implement the * FCR register; on these systems we need to drain the FIFO since * the flush we request doesn't happen. One such system is the * Firecracker VMM, aka. the rust-vmm/vm-superio emulation code: * https://github.com/rust-vmm/vm-superio/issues/83 */ lsr = uart_getreg(bas, REG_LSR); if (((lsr & LSR_TEMT) == 0) && (what & UART_FLUSH_TRANSMITTER)) drain |= UART_DRAIN_TRANSMITTER; if ((lsr & LSR_RXRDY) && (what & UART_FLUSH_RECEIVER)) drain |= UART_DRAIN_RECEIVER; if (drain != 0) { printf("ns8250: UART FCR is broken\n"); ns8250_drain(bas, drain); } So how to distinguish between a real FCR error and this case? Maybe if ns8250_drain() returned the number of bytes it drained instead and it returned one, then it isn't an FCR error. Currently ns8250_drain() returns 0 on no error or EIO if there is a hardware problem. Maybe that can be changed to return -EIO and handled properly where its return value is used? Note that these uarts are implemented on Xilinx/AMD FPGAs using the v2.0 IP in this link, but I do think it can probably happen on other 16x50 uarts too. https://docs.amd.com/v/u/en-US/pg143-axi-uart16550 Regards John --000000000000eb39e8061c987479 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

I have 3 machines runnin= g FreeBSD 14.0. (I have upgraded one to 14.1 recently). All 3 have a uart w= ith a GPS behind it, but no program reading from the uart. I see the "= ns8250: UART FCR is broken" on all of them on average a little less th= an one per day.

For example, the one machine has a= n uptime of 48 days. In that time the message was printed 44 times, but the= re was 12846 overruns according to the below sysctl:

dev.uart.2.rx_overruns: 12846

If the FCR was re= ally broken, I would have expected the message to be printed for every over= run.

The 16550d documentation that I could find on= the internet has this about Bit 1 of the Fifo Control Register (FCR):

Bit 1 Writing a 1 to FCR1 clears all bytes in the RCVR= FIFO
and resets its counter logic to 0 The shift register is not
cle= ared The 1 that is written to this bit position is self-clear-ing

So what I think is happening is that occasionally when the = RCVR FIFO is cleared, a character is almost received and between the RCVR i= s cleared and LSR bit LSR_RXRDY is checked, the new character is there.

The piece of code in ns8250_flush() looks like this:<= /div>
<snip>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uart_setre= g(bas, REG_FCR, fcr);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uart_barrier(bas);
=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* D= etect and work around emulated UARTs which don't implement the
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* FCR register; on these systems we need to = drain the FIFO since
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* the flush we re= quest doesn't happen.=C2=A0 One such system is the
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0* Firecracker VMM, aka. the rust-vmm/vm-superio emulation = code:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* https://github.com/rust-vmm/vm-superio/issue= s/83
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 lsr =3D uart_getreg(bas, REG_LSR);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if= (((lsr & LSR_TEMT) =3D=3D 0) && (what & UART_FLUSH_TRANSMI= TTER))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 drain |= =3D UART_DRAIN_TRANSMITTER;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ((lsr & L= SR_RXRDY) && (what & UART_FLUSH_RECEIVER))
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 drain |=3D UART_DRAIN_RECEIVER;
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (drain !=3D 0) {
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 printf("ns8250: UART FCR is broken\n&q= uot;);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ns8250_dr= ain(bas, drain);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
</snip>

So how to distinguish between a real FCR error and = this case? Maybe if ns8250_drain() returned the number of bytes it drained = instead and it returned one, then it isn't an FCR error. Currently ns82= 50_drain() returns 0 on no error or EIO if there is a hardware problem. May= be that can be changed to return -EIO and handled properly where its return= value is used?

Note that these uarts are implemen= ted on Xilinx/AMD FPGAs using the v2.0 IP in this link, but I do think it c= an probably happen on other 16x50 uarts too. https://docs.amd.com/v/u/en-US/pg143-axi-u= art16550

Regards

John=



--000000000000eb39e8061c987479--