OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 4:01 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sat Jul 08, 2017 4:14 pm 
Offline

Joined: Fri Apr 28, 2017 6:09 am
Posts: 3
Hi everyone!

Having a serial port is a nice feature for an osdev programmer; unfortunately many modern PCs and laptops lack it. My Latitude E5470 happens to have an UART port right in the middle of it's motherboard so I've decided to make use of it.

The machine's EFI firmware provides 2 options for this supposedly debug port in the NVRAM Setup variable: enabling UART as a simple serial port available somewhere in ACPI namespace (I guess, in that case the port is detected via DSDT/SSDT tables; I haven't found that detection code in linux kernel yet though) or as a Debug Port specified in DBGP/DBG2 tables (those are used by the Windows SoC for debugging). Needless to say, using debug port tables is much easier than interpreting AML-coded ACPI tables. However, linux kernel doesn't support using DBGP tables to enable /dev/tty*, only as an early_printk debugging interface and only USB EHCI/XHCI debug ports. There are a couple of patches enabling it for MMIO & IO ports however they were prevented from getting to mainline because of Microsoft-connected licensing concerns (sic!); yet they're not easy to be used as a reference implementation; you can find these patches in linux kernel mailing lists.

After soldering an external port to the internal UART pins I have managed to use it (both RXD and TXD communications with other computer) as a simple /dev/ttyS0 by enabling it as a serial port, so I know the port is actually working. ;-)

There's very little information available on this topic, so I'm very curious about others' experiences with it. I have tried accessing MMIO registers specified in DBGP using same offsets from IO COM ports but it has given no result so far. Are offsets the same for IO and MMIO ports? How are memory mapped serial ports usually handled?

Ilya

_________________
working on a minimal hypervisor: https://github.com/jinet-vm/vmm (be warned: WIP)
I'm not a native English speaker so feel free to correct all my mistakes — especially grammar ones.


Last edited by ilya101010 on Sun Jul 09, 2017 3:28 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sat Jul 08, 2017 4:41 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 27, 2014 9:11 am
Posts: 901
Location: Maadi, Cairo, Egypt
First off, I have never heard of memory-mapped serial ports, and I doubt the ACPI DBGP/DBG2 tables you mention (that I have never heard of either) have anything to do with serial ports, because I doubt your laptop has serial ports for the purpose of debugging. Instead, the laptop probably has serial ports because it's old and serial ports were the USB of the 90's (or 80's?)

Second off, EFI/UEFI are modern firmware interfaces, and to be perfectly honest I don't know much about them, but I seriously doubt EFI/UEFI has a mechanism for detecting the base I/O ports of the serial port.

For systems running on BIOS firmware, you can read the base address of the first serial port (COM1) from physical memory address 0x400, which is probably 99% of the time 0x3F8 if a serial port is present. For EFI/UEFI, there is no mechanism for detecting serial ports. So if I were you, I would detect serial ports on EFI/UEFI systems by attempting to configure the serial port at I/O ports 0x3F8, and then reading back the values to check if they are valid. If they are, I'd assume a serial port exists, if not, then a serial port doesn't.

Since I don't know a few details here, maybe someone can give a more accurate answer.

_________________
You know your OS is advanced when you stop using the Intel programming guide as a reference.


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sat Jul 08, 2017 4:56 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 642
Location: Ukraine, Bachmut
omarrx024 wrote:
First off, I have never heard of memory-mapped serial ports, and I doubt the ACPI DBGP/DBG2 tables you mention (that I have never heard of either) have anything to do with serial ports, because I doubt your laptop has serial ports for the purpose of debugging. Instead, the laptop probably has serial ports because it's old and serial ports were the USB of the 90's (or 80's?)

Second off, EFI/UEFI are modern firmware interfaces, and to be perfectly honest I don't know much about them, but I seriously doubt EFI/UEFI has a mechanism for detecting the base I/O ports of the serial port.

For systems running on BIOS firmware, you can read the base address of the first serial port (COM1) from physical memory address 0x400, which is probably 99% of the time 0x3F8 if a serial port is present. For EFI/UEFI, there is no mechanism for detecting serial ports. So if I were you, I would detect serial ports on EFI/UEFI systems by attempting to configure the serial port at I/O ports 0x3F8, and then reading back the values to check if they are valid. If they are, I'd assume a serial port exists, if not, then a serial port doesn't.

Since I don't know a few details here, maybe someone can give a more accurate answer.

There is. It's called straight - Serial I/O Protocol. And is described in the section 11.8 of the specification.

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sat Jul 08, 2017 4:58 pm 
Offline

Joined: Fri Apr 28, 2017 6:09 am
Posts: 3
omarrx024 wrote:
First off, I have never heard of memory-mapped serial ports, and I doubt the ACPI DBGP/DBG2 tables you mention (that I have never heard of either) have anything to do with serial ports, because I doubt your laptop has serial ports for the purpose of debugging. Instead, the laptop probably has serial ports because it's old and serial ports were the USB of the 90's (or 80's?)

Serial ports nowadays are mostly used for debugging facilities and USB is used for peripheral devices so it's not the same. The thing you're talking is a COM port, typically a bulky DB9 connector unimaginable in modern thin laptops. A serial port is a wider term. In my case it describes pins right on the board, not a full external port like USB or VGA (although having com port in a modern laptop would be very handy). See guys from defcon showcasing uses of uart in modern devices here (spoiler: they're amazing).

_________________
working on a minimal hypervisor: https://github.com/jinet-vm/vmm (be warned: WIP)
I'm not a native English speaker so feel free to correct all my mistakes — especially grammar ones.


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sat Jul 08, 2017 5:06 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 642
Location: Ukraine, Bachmut
ilya101010 wrote:
How are memory mapped serial ports usually handled?

reading/writing from/to its registers.
Here is a live example of a very basic initialization and use of such a UART on a mips machine, made in the very beginning of the FW start.
Code:
/* UART4 */
/* configure UART4 TxD, RxD pins - GPIO bank C ports 10 and 20, set as pins of device function 2. */
   li   $t1, (PIN_UART4_TXD | PIN_UART4_RXD)
   sw   $t1, (GPIO_C + GPIO_INTC)($s0)      /* interrupt clear, not an interrupt */
   sw   $t1, (GPIO_C + GPIO_MSKC)($s0)      /* mask clear, port is a pin of device, not gpio */
   sw   $t1, (GPIO_C + GPIO_PAT1S)($s0)      /* patern1 set, port is function 2 or 3 */
   sw   $t1, (GPIO_C + GPIO_PAT0C)($s0)      /* patern0 clear, port is function 2 */
   sw   $t1, (GPIO_C + GPIO_PEC)($s0)

/* Enable UART4 clock. UARTs are clocked from EXTCLK: no PLL required. */
   la   $s0, CPM_BASE            /* read-modify-write sequence for */
   lw   $t2, CPM_CLKGR1($s0)
   andi   $t3, $t2, %lo(~CLKGR1_UART4)      /* clear the UART4 clock gate bit */
   sw   $t3, CPM_CLKGR1($s0)         /* ungating the clock for UART4 */

/* Uart4Init */
   lui   $s0, %hi(UART4_BASE)
   ori   $s0, %lo(UART4_BASE)

1:   lw   $t0, UART_ULSR($s0)
   andi   $t0, $t0, ULSR_TEMP         /* TEMP is set when UTHR  and shift register are empty */
   beq   $zero, $t0, 1b
   nop

   sw   $zero, UART_UIER($s0)         /* disable interrupts */

   li    $t3, (ULCR_DLAB | ULCR_WLS_8)
   sw   $t3, UART_ULCR($s0)
   sw   $zero, UART_UDLLR($s0)
   sw   $zero, UART_UDLHR($s0)
   li   $t3, ULCR_WLS_8
   sw   $t3, UART_ULCR($s0)

   li   $t1, UMCR_RTS
   sw   $t1, UART_UMCR($s0)         /* modem control: RTS - Request To Send */

   li   $t2, (UFCR_FME | UFCR_RFRT | UFCR_TFRT | UFCR_UME)
   sw   $t2, UART_UFCR($s0)         /* Enable FIFO, reset Rx, Tx, enable the module */

   li   $t3, (ULCR_DLAB | ULCR_WLS_8)      /* Divisor Latch Access Bit and Word Length Select set */
   sw   $t3, UART_ULCR($s0)         /* Now we can access DLLR and DLHR to setup the baud rate */
   li   $t4, (UART_DIVISOR & 0x00ff)      /* lower byte into DLLR */
   sw   $t4, UART_UDLLR($s0)
   li   $t5, ((UART_DIVISOR & 0x0000ff00) >> 8)   /* higher byte into DLHR */
   sw   $t5, UART_UDLHR($s0)
   li   $t6, ULCR_WLS_8
   sw   $t6, UART_ULCR($s0)         /* DLAB bit clear */

/* say hello */
   lui   $a0, %hi(szHello)
   jal   PutString
   ori   $a0, %lo(szHello)

you asked. :mrgreen:

So basically you need to know what kind of UART it is, and register positions. How to do this with a laptop, I don't know, I got that from a SoC vendor manual.

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sat Jul 08, 2017 9:33 pm 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 384
So you have two setups for the UART, "serial" or "debug" port, and as "serial" it can be found by Linux and used?

The reason you're not a fan of that is because of ACPI/AML, right? I'm not 100% sure but might it be possible to do the ACPI/AML stuff in Linux, get the MMIO (or IO port) "sequence" for using the UART then use those as hardcoded values in your OS?

Think of it like "reverse engineering" the UART with ACPI/AML under Linux, then once you know the addresses and how to use the UART you create a "MoBo driver" that has the knowledge on how to drive the UART on that specific MoBo, so there's no ugly hacks in your OS but also you don't need ACPI/AML support.

I don't know feasible the above is, just a suggestion if nothing else works..


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sun Jul 09, 2017 2:52 am 
Offline
Member
Member

Joined: Sat Jul 02, 2016 7:02 am
Posts: 210
ilya101010 wrote:
I have tried accessing MMIO registers specified in DBGP using same offsets from IO COM ports but it has give no result so far. Are offsets the same for IO and MMIO ports? How are memory mapped serial ports usually handled?


A byte-sized device register, accessible on the IO space at an offset x, may be accessible on the MEM space at an offset = x << shift.

See Serial parameters.

If the laptop contains processor and chipset corresponding to Intel Skylake microarchitecture, and the UART being referred to here in the post is the PCI-based PCH UART device, then its memory-mapped registers are accessible at 4-byte offsets from the base, unless one programs the GEN_REGRW7 register to force 1-byte offsets.

Search for the document "Skylake Platform Controller Hub H and LP".


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sun Jul 09, 2017 3:27 am 
Offline

Joined: Fri Apr 28, 2017 6:09 am
Posts: 3
LtG wrote:
Think of it like "reverse engineering" the UART with ACPI/AML under Linux, then once you know the addresses and how to use the UART you create a "MoBo driver" that has the knowledge on how to drive the UART on that specific MoBo, so there's no ugly hacks in your OS but also you don't need ACPI/AML support.


That's exactly what I have been doing so far, specifically studying early_printk (see here: https://github.com/torvalds/linux/blob/master/arch/x86/kernel/early_printk.c).

linuxyne wrote:
If the laptop contains processor and chipset corresponding to Intel Skylake microarchitecture, and the UART being referred to here in the post is the PCI-based PCH UART device, then its memory-mapped registers are accessible at 4-byte offsets from the base, unless one programs the GEN_REGRW7 register to force 1-byte offsets.

Search for the document "Skylake Platform Controller Hub H and LP".


The document is exactly the one I sought. Thank you!

_________________
working on a minimal hypervisor: https://github.com/jinet-vm/vmm (be warned: WIP)
I'm not a native English speaker so feel free to correct all my mistakes — especially grammar ones.


Top
 Profile  
 
 Post subject: Re: MMIO serial ports & DBGP/DBG2 ACPI tables
PostPosted: Sun Jul 09, 2017 4:16 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
omarrx024 wrote:
First off, I have never heard of memory-mapped serial ports, and I doubt the ACPI DBGP/DBG2 tables you mention (that I have never heard of either) have anything to do with serial ports, because I doubt your laptop has serial ports for the purpose of debugging. Instead, the laptop probably has serial ports because it's old and serial ports were the USB of the 90's (or 80's?)

Pretty much every chipset (also every modern one) has serial ports for debugging. Most boards do not have DE-9 connectors but pretty much all of them do have some serial port pins. The serial port is the most widespread peripheral device that is available.

In addition to that PCI defines a debugging port capability that enables extremely simple serial output.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: SemrushBot [Bot] and 153 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group