trouble setting IRQs for COM ports

FreeBSD 15.0-RELEASE
Supermicro E101-60
Nuvoton NCT6106D Super IO (LPC Bus)

My BIOS supposedly lets me set the IRQs for the 4 COM ports on my machine - but I can't seem to get it to work:
com1 bios settings.jpg
com2 bios settings.jpg
com3 bios settings.jpg
com4 bios settings.jpg


In /boot/device.hints I have added these lines per 29.2.2 of the Manual and device.hints:

Code:
hint.uart.0.at="isa"
hint.uart.0.port="0x3f8"
hint.uart.0.irq="4"
hint.uart.1.at="isa"
hint.uart.1.port="0x2f8"
hint.uart.1.irq="3"
hint.uart.2.at="isa"
hint.uart.2.port="0x3e8"
hint.uart.2.irq="5"
hint.uart.3.at="isa"
hint.uart.3.port="0x2e8"
hint.uart.3.irq="9"

vmstat -i:
Code:
interrupt                          total       rate
irq3: uart0                         8620         93
irq4: uart1                         8586         93
irq5: uart2 uart3                  15950        173
cpu0:timer                         19154        208
cpu1:timer                         18637        202
cpu2:timer                         17393        188
cpu3:timer                         17740        192
irq129: ahci0                       8129         88
irq131: igb0:rxq0                    295          3
irq132: igb0:rxq1                    475          5
irq133: igb0:aq                        4          0
irq134: hdac0                         17          0
irq135: em0:irq0                     508          6
Total                             115508       1252

dmesg | grep -i uart:
Code:
uart0: <16950 or compatible> port 0x3f8-0x3ff irq 3 on acpi0
uart0: forcing active-hi polarity for IRQ 3
uart1: <16950 or compatible> port 0x2f8-0x2ff irq 4 on acpi0
uart1: forcing active-hi polarity for IRQ 4
uart2: <16950 or compatible> port 0x3e8-0x3ef irq 5 on acpi0
uart2: forcing active-hi polarity for IRQ 5
uart3: <16950 or compatible> port 0x2e8-0x2ef irq 5 on acpi0
uart3: forcing active-hi polarity for IRQ 5


What am I not getting?
 
what's not working, specifically? how are you accessing the serial port? freebsd distinguishes between call-out serial ports and call-in serial ports — /dev/cuau0 should be what your BIOS calls COM0.

we also note via your pics that you have COM0 on IRQ 3 but your boot hints put it on 4, and similar flips on the other UART configs. Double-check those mappings :)
 
The IRQs I set in the hints aren't being assigned to the COM ports

I'm trying to avoid IRQ conflicts and assign
IRQ 4 to COM 1 (uart0)
IRQ 3 to COM 2 (uart1)
IRQ 5 to COM 3 (uart2)
IRQ 9 to COM 4 (uart3)
 
well, the hints you're trying to assign are not the right IRQs according to your BIOS config, so i don't think that'll help. what happens if you remove the hints entirely and adjust the com4 in your BIOS to irq 9? it looks like the system autodetected from your BIOS setup.
 
Removing the hints:

vmstat -i:
Code:
interrupt                          total       rate
irq3: uart0                        12564         82
irq4: uart1                        12468         82
irq5: uart2 uart3                  23362        153
cpu0:timer                         23354        153
cpu1:timer                         21116        138
cpu2:timer                         22558        148
cpu3:timer                         22146        145
irq129: ahci0                       9414         62
irq131: igb0:rxq0                    689          5
irq132: igb0:rxq1                   1491         10
irq133: igb0:aq                        4          0
irq134: hdac0                         13          0
irq135: em0:irq0                     379          2
Total                             149558        979

dmesg | grep -i uart:
Code:
uart0: <16950 or compatible> port 0x3f8-0x3ff irq 3 on acpi0
uart0: forcing active-hi polarity for IRQ 3
uart1: <16950 or compatible> port 0x2f8-0x2ff irq 4 on acpi0
uart1: forcing active-hi polarity for IRQ 4
uart2: <16950 or compatible> port 0x3e8-0x3ef irq 5 on acpi0
uart2: forcing active-hi polarity for IRQ 5
uart3: <16950 or compatible> port 0x2e8-0x2ef irq 5 on acpi0
uart3: forcing active-hi polarity for IRQ 5

Doesn't look like the hints make any difference

I cannot set a specific IRQ in the BIOS, only a range - in this instance 3,4,5,6,7,9,10,11,12
My understanding from Supermicro support is the selection of the IRQ needs to be done in the OS from this range
 
check your forth graphic. you didn't change uart4 to be irq9. what I see in previous post is exactly as I would expect. also, the fact that your dmesg output understands the non-standard irq assigments tells me that a hints file probly isn't needed.
 
check your forth graphic. you didn't change uart4 to be irq9. what I see in previous post is exactly as I would expect. also, the fact that your dmesg output understands the non-standard irq assigments tells me that a hints file probly isn't needed.

So there are 3 lines in that BIOS screen:
Serial Port
Device Settings
Change Settings

Serial Port can be enabled or disabled - user selectable
Device Settings is only an output - I cannot select/change anything there - and I do not know why it shows IRQ 5
Change Settings is user selectable - I can run in auto mode, or select the IO/Port and and left with a range of IRQ's - but I cannot select a specific IRQ

1766588759043.png


also, have you actually tried using these ports under autoconfiguration?
Yes - the ports work when everything is set to auto - however I want to move to independent IRQ's to reduce jitter on the lines and make the timing more predictable, application is NTP server with GPS receivers and precise pulses on the DCD pin
 
If what OP says is correct then lets address this from a different angle. Why do you care if uarts share an interrupt? the bandwidth fill should be relatively low unless you are using a toy CPU. I "assume" BSD drivers allow for shared interrupts and will poll all relevant uarts if an int is triggered. Now, OTOH, if you think you're going to run a multi-port terminal server with speeds in the mb/s range then...well...good luck. uarts ints are triggered per/char so you can quickly saturate the io channel by stacking too many noisy uarts. The math to know how many are too many is left as an exercise for the reader.
 
Yes - the ports work when everything is set to auto - however I want to move to independent IRQ's to reduce jitter on the lines and make the timing more predictable, application is NTP server with GPS receivers and precise pulses on the DCD pin
Now that I see the intended app...I don't believe spreading the IRQs will make a difference. Existing NTP/GPS integration should be "well enough", provided the heavy lifting is done in drivers and not in userland processes. Just how precise to you intend to achieve? Have you read any academic articles about what can be expected, or just experimenting? Any why would you need multiple uarts at all? having more than one GPS receiver on the machine is "superfluous" at best.
 
What is the expected Baud Rate of these serial connections? Something like 115,200 bit/s ? I am currently assuming you are using 8-N-1 ?
 
what's not working, specifically? how are you accessing the serial port? freebsd distinguishes between call-out serial ports and call-in serial ports — /dev/cuau0 should be what your BIOS calls COM0.

Ya that was my question too.. Have you tested with cu(1) (Call Unix) or minicom(1). I (used) to use minicom(1) a lot when I was running a UUCP node to (call out) on my modem or just to send "stuff" over a serial line to test it. That also included over NULL MODEM cables (if applicable).

If these connections are inbound do you have getty(8) set up on these ports (if applicable?).

You might also consider what LOCK files are associated with these serial ports as well.. "In the Old Days" Unix would create a LOCK file when a serial port was busy to prevent the "system" or other users from using (that) serial port while someone else was using it. Both cu(1) and minicom(1) create and destroy LOCK files system defined places. For FreeBSD systems (maybe others?) that is under: /var/spool/lock/LCK..* (see man 1 cu)
 
Oh - 1 more tip. If you have a dialup modem lying around somewhere - I would hook it up to each of your COM ports and then connect to it over a modem cable. Then send standard Hayes AT commands to it and check for "OK" coming back. This will prove the serial ports WORK and then you can go forward with more advanced stuff.

Of course the dialup modem (DOES NOT) have to connect to a "real telephone line" -- you are just testing that the modem understands you. This will also help you test LOCK files (see above) and see if those are getting created correctly on the file system. Sending something like "AT" should get "OK" back from the modem. If you want to go DEEPER you can view the Hayes AT command set here: Hayes AT Commands

Try different serial port baud rates, bit size, parity and stop bit values too (example: 7E1 is common).

Good Luck !
 
I would be curious to see the jitter numbers for NCT6106 on other platforms. Maybe Supermicro has a noisy LPC implementation.
What is the WhiskeyLake SOC here? Board?

I agree with the sediment here you should disable all COM ports except for the one you want accuracy on. Then add ports back as needed with testing.
If there are COM ports that only support RS232 I would use those. Ones with RS485 support might get weird.
From your images Ports 1 and 2 have settings for COM ports. Ports 3 and 4 do not. RS232 only.
I would use Port 3 for testing. Native BIOS settings. Disable other ports. Use the default hints.
Then if high jitter numbers look at ways to mitigate. I think you can limit IRQ's. Maybe ACPI has a say.

I always thought the hint here of linking COM port here to /dev/gps1 was a brilliant solution.
 
Some of the stuff on that linked page are outdated or not recommended. SSH root for one.
Regardless 15 years later there are good parts. Link to GPS and disabling TTY's. What if the TTY locks being fought by software are causing problems.
 
If what OP says is correct then lets address this from a different angle. Why do you care if uarts share an interrupt? the bandwidth fill should be relatively low unless you are using a toy CPU. I "assume" BSD drivers allow for shared interrupts and will poll all relevant uarts if an int is triggered. Now, OTOH, if you think you're going to run a multi-port terminal server with speeds in the mb/s range then...well...good luck. uarts ints are triggered per/char so you can quickly saturate the io channel by stacking too many noisy uarts. The math to know how many are too many is left as an exercise for the reader.
Now that I see the intended app...I don't believe spreading the IRQs will make a difference. Existing NTP/GPS integration should be "well enough", provided the heavy lifting is done in drivers and not in userland processes. Just how precise to you intend to achieve? Have you read any academic articles about what can be expected, or just experimenting? Any why would you need multiple uarts at all? having more than one GPS receiver on the machine is "superfluous" at best.

The GPS Receivers are ublox LEA-M8T's with a pulse jitter of ±11 ns and accuracy of ≤ 20 ns
https://www.u-blox.com/sites/default/files/products/documents/NEO-LEA-M8T_ProductSummary_(UBX-16000801).pdf

I've read almost all the David Mills material I could get my hands on, some from John Ackermann (N8UR), and various other material.
I haven't come across testing in this particular setup.

As to having multiple receivers, RFC8633 and NTP both recommend at least 3:
https://www.rfc-editor.org/rfc/rfc8633.html#section-3.2
https://www.ntp.org/ntpfaq/ntp-s-algo-real/#532-why-should-i-have-more-than-one-clock

What is the expected Baud Rate of these serial connections? Something like 115,200 bit/s ? I am currently assuming you are using 8-N-1 ?
Yes
1766599955047.png


Ya that was my question too.. Have you tested with cu(1) (Call Unix) or minicom(1). I (used) to use minicom(1) a lot when I was running a UUCP node to (call out) on my modem or just to send "stuff" over a serial line to test it. That also included over NULL MODEM cables (if applicable).

If these connections are inbound do you have getty(8) set up on these ports (if applicable?).

You might also consider what LOCK files are associated with these serial ports as well.. "In the Old Days" Unix would create a LOCK file when a serial port was busy to prevent the "system" or other users from using (that) serial port while someone else was using it. Both cu(1) and minicom(1) create and destroy LOCK files system defined places. For FreeBSD systems (maybe others?) that is under: /var/spool/lock/LCK..* (see man 1 cu)

The COM/uart ports are accessed by GPSD through /dev/cuau* which creates a SOCK connection for Chrony to use.
The COM ports have been tested and confirmed working.
I'm at the optimization stage now.

I would be curious to see the jitter numbers for NCT6106 on other platforms. Maybe Supermicro has a noisy LPC implementation.
What is the WhiskeyLake SOC here? Board?

I agree with the sediment here you should disable all COM ports except for the one you want accuracy on. Then add ports back as needed with testing.
If there are COM ports that only support RS232 I would use those. Ones with RS485 support might get weird.
From your images Ports 1 and 2 have settings for COM ports. Ports 3 and 4 do not. RS232 only.
I would use Port 3 for testing. Native BIOS settings. Disable other ports. Use the default hints.
Then if high jitter numbers look at ways to mitigate. I think you can limit IRQ's. Maybe ACPI has a say.

I always thought the hint here of linking COM port here to /dev/gps1 was a brilliant solution.
Board is Supermicro X11SSN-H-WOHS
https://www.supermicro.com/en/products/motherboard/X11SSN-H-WOHS

I have done previous testing with only individual COM ports enabled, the delay/jitter I'm seeing does not change, and is tied to specific COM ports.
 
yeah i don't think mucking with IRQs is going to get you anywhere. this isn't an ISA machine in 1994, after all.
 
yeah i don't think mucking with IRQs is going to get you anywhere. this isn't an ISA machine in 1994, after all.
Perhaps, but if two interrupts come in at the same time from the DCD pins on two different com ports, I'm not sure how accurate the timestamp will be
 
This (might?) help. So basically with serial line communication UARTS and CABLES are the typically the key to performance. I used to put 16550 UARTs into my boxes when I was actively doing serial line stuff -- but that was yahren's ago (in Battlestar Galatica speak).

Since that time - UART technology has improved and you can increase your serial line baud rate (apparently? :cool: ) if you have UARTs that support larger FIFOs. (link): According to (this) article - your 16950 UARTs "should have" 128 byte UART FIFOs -- which (if they actually work and have a cache and so forth) is pretty cool.

(In thory) this means you can set your baud rate way up -- well over the 115,200 baud you have set right now -- (maybe? 921.60 kbit/s ?). Dunno -- this is (NEW WATER) for me :) -- but maybe someone else on this Forum knows?

(I think?) you also need to consider the quality of serial cable(s) being used, the serial device you are talking to (and what it can and can't do), what kind of error correction is going on between the FreeBSD and the target device (if any?) and so forth. It's great to "speak fast" during computer communication -- but if (a lot of the chatter) on the line is ending up causing errors and retransmissions back and forth -- then it's not worth it.

Hope that helps
 
hm, have you got the latest BIOS from supermicro? might have better options for pinning ports to IRQs. https://www.supermicro.com/en/support/resources/downloadcenter/firmware/MBD-X11SSN-H/BIOS
yes - I recently updated from rev 2.5 to rev 2.6 - running some testing to see how much of a difference there is

This (might?) help. So basically with serial line communication UARTS and CABLES are the typically the key to performance. I used to put 16550 UARTs into my boxes when I was actively doing serial line stuff -- but that was yahren's ago (in Battlestar Galatica speak).

Since that time - UART technology has improved and you can increase your serial line baud rate (apparently? :cool: ) if you have UARTs that support larger FIFOs. (link): According to (this) article - your 16950 UARTs "should have" 128 byte UART FIFOs -- which (if they actually work and have a cache and so forth) is pretty cool.

(In thory) this means you can set your baud rate way up -- well over the 115,200 baud you have set right now -- (maybe? 921.60 kbit/s ?). Dunno -- this is (NEW WATER) for me :) -- but maybe someone else on this Forum knows?

(I think?) you also need to consider the quality of serial cable(s) being used, the serial device you are talking to (and what it can and can't do), what kind of error correction is going on between the FreeBSD and the target device (if any?) and so forth. It's great to "speak fast" during computer communication -- but if (a lot of the chatter) on the line is ending up causing errors and retransmissions back and forth -- then it's not worth it.

Hope that helps

So my understanding is there is an interrupt when the pulse hits the DCD pin, and interrupts as the FIFO fills up and is emptied

Supermicro's and Nuvoton's documentation both confirm 128 byte FIFO

1766632626208.png
1766632662281.png



The uart manpage says:
In /boot/device.hints:
hint.uart.0.disabled="1"
hint.uart.0.baud="38400"
hint.uart.0.port="0x3f8"
hint.uart.0.flags="0x10"

With flags encoded as:
0x00010 device is potential system console
0x00080 use this port for remote kernel debugging
0x00100 set RX FIFO trigger level to ``low'' (NS8250 only)
0x00200 set RX FIFO trigger level to ``medium low'' (NS8250 only)
0x00400 set RX FIFO trigger level to ``medium high'' (default, NS8250 only)
0x00800 set RX FIFO trigger level to ``high'' (NS8250 only)

If I limit the traffic to 100 bytes on the RX pin, and a single pulse on the DCD pin at a frequency of 1 hz - then I think we're dealing with 2 interrupts per second per COM port - 1 for the data and 1 for the pulse (100 bytes of data should fit in a 128 byte FIFO)

What are the sizes of the four different trigger levels (low, medium low, medium high, high)?

Does NS8250 only mean it won't work with my 16550?

As far as cables - I'm using custom made in USA 1ft long cables to cross CTS-DCD pins - the TTL to RS-232 converters I'm using are TX/RX/CTS/RTS and I wanted to interface with DCD on the PC

1766633362211.png
 
Back
Top