Serial port on PCIEX and using it in UEFI
Serial port on PCIEX and using it in UEFI
I'm having some issues with setting up and communicating with a serial port on a PCI Express card while in UEFI mode
When I boot in old compatibility mode I can scan for the pci device (vendor 0x1415) and find the port assigned (0xf010) and initialize it and work with it fine (sending and receiving is ok
But when I boot in UEFI mode the same code for controlling the serial port doesn't work anymore. (I checked with a uefi tool to enum the devices and it's still on the same port)
I'm guessing it's ACPI or something related but it'd help if I knew where to look (perhaps the pci card is powered down and it needs to be turned on, or the pcie card runs a csm firmware at boot ?)
When I boot in old compatibility mode I can scan for the pci device (vendor 0x1415) and find the port assigned (0xf010) and initialize it and work with it fine (sending and receiving is ok
But when I boot in UEFI mode the same code for controlling the serial port doesn't work anymore. (I checked with a uefi tool to enum the devices and it's still on the same port)
I'm guessing it's ACPI or something related but it'd help if I knew where to look (perhaps the pci card is powered down and it needs to be turned on, or the pcie card runs a csm firmware at boot ?)
Re: Serial port on PCIEX and using it in UEFI
you are not supposed to program any peripheral device controller in UEFI, unless you write a UEFI driver for it, which you don't. instead, you should be using UEFI protocols for accessing appropriate hardware. you find your device handle, that supports the protocol, you need and you use functions of that protocol. read the UEFI spec. in your case, the protocols are input/output text protocols. the UEFI driver of the serial port controller creates handle for this port and attaches instances of these protocols to it, you search for them the common UEFI way - again, read the spec, it's described there way better, than anyone here would retell it. and I totally forgot, that in this case, you don't even need to search for anything - the active input/output devices are given to you through the EFI system table (ConsoleInHandle, ConIn, ConsoleOutHandle, ConOut)!
Re: Serial port on PCIEX and using it in UEFI
I tested the COM ports under UEFI Shell. To get UEFI Shell serial console in Putty on second PC you need to load appropriate .efi drivers:zaval wrote:you don't even need to search for anything - the active input/output devices are given to you through the EFI system table (ConsoleInHandle, ConIn, ConsoleOutHandle, ConOut)!
1. Integrated COM port on the motherboard:
Code: Select all
load TerminalDxe.efi PciSioSerialDxe.efi
Code: Select all
load TerminalDxe.efi FtdiUsbSerialDxe.efi
I try the same with the RS232 PCIe card SER5427A but it doesn't work
Why is it not working? The driver PciSioSerialDxe.efi source code clearly states that it is intended for both Super I/O and PCI card:
https://github.com/tianocore/edk2/blob/ ... ialDxe.inf
## @file
# Serial driver for standard UARTS on a SIO chip or PCI/PCIE card.
#
# Produces the Serial I/O protocol for standard UARTS using Super I/O or PCI I/O.
#
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
- Attachments
-
- ftdi_uefi.zip
- (22.21 KiB) Downloaded 141 times
Re: Serial port on PCIEX and using it in UEFI
I managed to run the redirect of the UEFI Shell console through the serial port on the PCIe card - instead of a PciSioSerialDxe.efi driver, I used SerialDxe.efi but using the BaseSerialPortLib16550.inf instead BaseSerialPortLibNull.inf library
Spec my PCIe SER5427A serial card:
to
In MdeModulePkg.dec file, change I/O port 03F8 to D000 and clock rate 1843200 to 14745600:
Now at UEFI Shell, just write a EFI\Boot\startup.nsh script that enable I/O access PCIe serial card and loads SerialDxe.efi and TerminalDxe.efi drivers:
On the second PC we start Putty with baud rate 115200
P.S. Probably instead of enabling I/O access under UEFI Shell you need to properly configure the option PCI Serial Device Info at MdeModulePkg.dec - default is 0xFF:
I tried this way: {0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF} but after loading the SerialDxe.efi I have Device error
Dev 1C, Func 01 > PCI Express Root
Dev 00, Func 00 > Bridge PCI to PCI
Dev 00, Func 00 > My PCIe serial card
Spec my PCIe SER5427A serial card:
- one serial port
- card are drived by a higher CLK (14.7456 Mhz), thus the actual baudarate is 8 times higher than the BIOS/DOS baudrate (default UART clock is 1843200 Hz)
- access Port-Mapped I/O (PMIO) - in my configuration it is the port of D000 - under pure UEFI disabled by default
- in my configuration PCIe serial card is on Bus Device Function 04 00 00
Code: Select all
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
Code: Select all
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
Code: Select all
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xD000|UINT64|0x00020002
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|14745600|UINT32|0x00010066
Code: Select all
@echo -off
echo Switch ON PCIe Serial Card I/O access & load drivers
mm 04000004 1 ;PCI :1
load fs0:\SerialDxe_D000_Clock.efi fs0:\TerminalDxe.efi
P.S. Probably instead of enabling I/O access under UEFI Shell you need to properly configure the option PCI Serial Device Info at MdeModulePkg.dec - default is 0xFF:
Code: Select all
## PCI Serial Device Info. It is an array of Device, Function, and Power Management
# information that describes the path that contains zero or more PCI to PCI briges
# followed by a PCI serial device. Each array entry is 4-bytes in length. The
# first byte is the PCI Device Number, then second byte is the PCI Function Number,
# and the last two bytes are the offset to the PCI power management capabilities
# register used to manage the D0-D3 states. If a PCI power management capabilities
# register is not present, then the last two bytes in the offset is set to 0. The
# array is terminated by an array entry with a PCI Device Number of 0xFF. For a
# non-PCI fixed address serial device, such as an ISA serial device, the value is 0xFF.
# @Prompt Pci Serial Device Info
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0xFF}|VOID*|0x00010067
Dev 1C, Func 01 > PCI Express Root
Dev 00, Func 00 > Bridge PCI to PCI
Dev 00, Func 00 > My PCIe serial card
-
- Member
- Posts: 5560
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Serial port on PCIEX and using it in UEFI
You need four bytes for each device.jzef wrote:I tried this way: {0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF} but after loading the SerialDxe.efi I have Device errorCode: Select all
# followed by a PCI serial device. Each array entry is 4-bytes in length. The
Re: Serial port on PCIEX and using it in UEFI
Thank you very much - I fixed source code and now it works good - no need use mm 04000004 1 -pci anymoreOctocontrabass wrote: You need four bytes for each device.
MdeModulePkg.dec
Code: Select all
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xD000|UINT64|0x00020002
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|14745600|UINT32|0x00010066
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo|{0x1C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}|VOID*|0x00010067
Code: Select all
@echo -off
echo Load drivers for PCIe Serial Card & run UefiSeven
load fs0:\SerialDxe_D000_Clock_Info.efi fs0:\TerminalDxe.efi
UefiSeven.efi
Code: Select all
SerialDxe_PCIe.efi
fs0:\> dh 155
Handle 155 (7906DD18)
Image (79109E40) File:\/SerialDxe_PCIe.efi
ParentHandle..: 79DA8818
SystemTable...: 7D74CF18
DeviceHandle..: 7A156118
FilePath......: \/SerialDxe_PCIe.efi
PdbFileName...: /root/MyWorkspace/Build/MdeModule/RELEASE_GCC49/X64/MdeModulePkg/Universal/SerialDxe/SerialDxe/DEBUG/SerialDxe.dll
ImageBase.....: 7BB75000 - 7BB77380
ImageSize.....: 2380
CodeType......: BS_code
DataType......: BS_data
ImageDpath (7906C918)
ACPI Device Path for Acpi
HID PNP0A03, UID 0
Hardware Device Path for PCI
Function (2) Device (1F)
Messaging Device Path for SATA
Media Device Path for Hard Drive
Partition (1) Start (0000000000000800) Size (0000000000032000)
Media Device Path for File Path
File '\'
Media Device Path for File Path
File 'SerialDxe_PCIe.efi'
AsStr: 'PciRoot(0x0)/Pci(0x1f,0x2)/Sata(0x0,0x0)/HD(1,MBR,0x343daba5,0x800,0x32000)/\/SerialDxe_PCIe.efi'
PCIe card:
fs0:\> dh 12b -d
12B: DevPath (..1)/Pci(0x0,0x0)/Pci(0x0,0x0))PciIo
Controller Name : <UNKNOWN>
Device Path : PciRoot(0x0)/Pci(0x1c,0x1)/Pci(0x0,0x0)/Pci(0x0,0x0)
Controller Type : DEVICE
Configuration : NO
Diagnostics : NO
Managed by : <NONE>
Parent Controllers :
Parent[50] : PciRoot(0x0)
Child Controllers : <NONE>
fs0:\> sermode
156(7906DB18) - (115200, N, 8, 1)
fs0:\> dh 156 -d
156: DevPath (..eb627241)/Uart(115200,8,N,1))SerialIo
Controller Name : <UNKNOWN>
Device Path : VenHw(d3987d4b-971a-435f-8caf-4967eb627241)/Uart(115200,8,N,1)
Controller Type : ROOT
Configuration : NO
Diagnostics : NO
Managed by :
Drv[157] : Serial Terminal Driver
Parent Controllers : <NONE>
Child Controllers :
Child[158] : PC-ANSI Serial Console
Code: Select all
Vendor ID(0): 1FD4 Device ID(2): 1999
Command(4): 0001
(00)I/O space access enabled: 1 (01)Memory space access enabled: 0
(02)Behave as bus master: 0 (03)Monitor special cycle enabled: 0
(04)Mem Write & Invalidate enabled: 0 (05)Palette snooping is enabled: 0
(06)Assert PERR# when parity error: 0 (07)Do address/data stepping: 0
(08)SERR# driver enabled: 0 (09)Fast back-to-back transact...: 0
Last edited by jzef on Mon Oct 02, 2023 7:17 am, edited 1 time in total.
Re: Serial port on PCIEX and using it in UEFI
I was able to compile the correct PciSioSerialDxe.efi driver for my PCIe SER5427A serial card
It is not important what library BaseSerialPortLibNull.inf or BaseSerialPortLib16550.inf is in MdeModulePkg.dsc because the driver does not use any of them.
To make the driver work, all you need to configure the PCIe card in MdeModulePkg.dec accordingly in PcdPciSerialParameters:
Vendor, Device and ClockRate must be given as little-endian:
Vendor Device 1FD4 1999 > D4 1F 99 19
ClockRate my card 14745600 Hz > E10000 > 00 00 E1
That's all because my card have only I/O access address in BAR0
No need to configure PcdSerialRegisterBase, PcdSerialClockRate and PcdSerialPciDeviceInfo in MdeModulePkg.dec -defaults is 0x03F8, 1843200 and 0xFF because is not consumed by PciSioSerialDxe.inf - only consumed PcdPciSerialParameters:
It is not important what library BaseSerialPortLibNull.inf or BaseSerialPortLib16550.inf is in MdeModulePkg.dsc because the driver does not use any of them.
To make the driver work, all you need to configure the PCIe card in MdeModulePkg.dec accordingly in PcdPciSerialParameters:
Code: Select all
gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters|{0xD4,0x1F, 0x99,0x19, 0x00,0x00,0xE1,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0xFF,0xFF}|VOID*|0x00010071
Code: Select all
--Vendor- --Device- -----ClockRate----- ----------------Offset----------------- -Bar Stde --RxFIFO- --TxFIFO- -Reserved Terminate
0xD4,0x1F, 0x99,0x19, 0x00,0x00,0xE1,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00, 0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0xFF,0xFF
Vendor Device 1FD4 1999 > D4 1F 99 19
ClockRate my card 14745600 Hz > E10000 > 00 00 E1
That's all because my card have only I/O access address in BAR0
No need to configure PcdSerialRegisterBase, PcdSerialClockRate and PcdSerialPciDeviceInfo in MdeModulePkg.dec -defaults is 0x03F8, 1843200 and 0xFF because is not consumed by PciSioSerialDxe.inf - only consumed PcdPciSerialParameters:
Code: Select all
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8 ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1 ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|1843200 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters ## CONSUMES
Code: Select all
PciSioSerialDxe_PCIe.efi
fs0:\> dh 155 -d
155: Image(\/PciSioSerialDxe_PCIe.efi) ImageDevPath (..)/\/PciSioSerialDxe_PCIe.efi)DriverBinding ComponentName
Driver Name : PCI SIO Serial Driver
Image Name : \/PciSioSerialDxe_PCIe.efi
Driver Version : 0000000A
Driver Type : BUS
Configuration : NO
Diagnostics : NO
Managing :
Ctrl[12B] : PciRoot(0x0)/Pci(0x1c,0x1)/Pci(0x0,0x0)/Pci(0x0,0x0)
Child[156] : PCI Serial Port #0
PCIe card:
fs0:\> dh 12b -d
12B: DevPath (..1)/Pci(0x0,0x0)/Pci(0x0,0x0))PciIo
Controller Name : <UNKNOWN>
Device Path : PciRoot(0x0)/Pci(0x1c,0x1)/Pci(0x0,0x0)/Pci(0x0,0x0)
Controller Type : BUS
Configuration : NO
Diagnostics : NO
Managed by :
Drv[155] : PCI SIO Serial Driver
Parent Controllers :
Parent[50] : PciRoot(0x0)
Child Controllers :
Child[156] : PCI Serial Port #0
fs0:\> sermode
156(7906D698) - (115200, N, 8, 1)
fs0:\> dh 156 -d
156: DevPath (..(0x0,0x0)/Uart(115200,8,N,1))SerialIo
Controller Name : PCI Serial Port #0
Device Path : PciRoot(0x0)/Pci(0x1c,0x1)/Pci(0x0,0x0)/Pci(0x0,0x0)/Uart(115200,8,N,1)
Controller Type : BUS
Configuration : NO
Diagnostics : NO
Managed by :
Drv[157] : Serial Terminal Driver
Parent Controllers :
Parent[12B] : PciRoot(0x0)/Pci(0x1c,0x1)/Pci(0x0,0x0)/Pci(0x0,0x0)
Child Controllers :
Child[158] : PC-ANSI Serial Console
Re: Serial port on PCIEX and using it in UEFI
Summary:
PCIe serial card with I/O access:
SerialDxe.efi need:
P.S. Please test your cards and pass the report whether it works or not in this topic or other
PCIe serial card with I/O access:
SerialDxe.efi need:
- BaseSerialPortLib16550.inf
- gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate (if non standard)
- gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo
- gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters (ClockRate inside)
P.S. Please test your cards and pass the report whether it works or not in this topic or other