Star, There is a typo in SerialSetAttributes() function header comment block.
There are also a couple changes I recommend be done to SerialDxeInitialize() and moving a couple global variable to top of file. Best regards, Mike > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Star > Zeng > Sent: Tuesday, November 17, 2015 3:07 AM > To: edk2-devel@lists.01.org > Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Tian, Feng > <feng.t...@intel.com>; Gao, Liming <liming....@intel.com> > Subject: [edk2] [PATCH V2 04/12] MdeModulePkg: Upstream SerialDxe from > EmbeddedPkg > > This Serial driver layers on top of a Serial Port Library instance to produce > serial IO protocol. > > There is also another SerialDxe implementation in CorebootPayloadPkg, but > SerialDxe from EmbeddedPkg should be better that also > consumes the extended interfaces GetControl/SetControl/SetAttributes in > EmbeddedPkg/Include/Library/SerialPortExtLib.h for serial > IO protocol. > And the extended interfaces GetControl/SetControl/SetAttributes in > EmbeddedPkg/Include/Library/SerialPortExtLib.h has been > upstream to MdePkg/Include/Library/SerialPortLib.h. > > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Liming Gao <liming....@intel.com> > Cc: Feng Tian <feng.t...@intel.com> > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Star Zeng <star.z...@intel.com> > --- > MdeModulePkg/MdeModulePkg.dsc | 2 + > MdeModulePkg/Universal/SerialDxe/SerialDxe.inf | 48 +++ > MdeModulePkg/Universal/SerialDxe/SerialDxe.uni | Bin 0 -> 1892 bytes > .../Universal/SerialDxe/SerialDxeExtra.uni | Bin 0 -> 1324 bytes > MdeModulePkg/Universal/SerialDxe/SerialIo.c | 394 > +++++++++++++++++++++ > 5 files changed, 444 insertions(+) > create mode 100644 MdeModulePkg/Universal/SerialDxe/SerialDxe.inf > create mode 100644 MdeModulePkg/Universal/SerialDxe/SerialDxe.uni > create mode 100644 MdeModulePkg/Universal/SerialDxe/SerialDxeExtra.uni > create mode 100644 MdeModulePkg/Universal/SerialDxe/SerialIo.c > > diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc > index 5c28fab..ebbb73d 100644 > --- a/MdeModulePkg/MdeModulePkg.dsc > +++ b/MdeModulePkg/MdeModulePkg.dsc > @@ -374,6 +374,8 @@ [Components] > > > MdeModulePkg/Universal/PropertiesTableAttributesDxe/PropertiesTableAttributesDxe.inf > > + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf > + > [Components.IA32, Components.X64, Components.IPF] > MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf > MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf > diff --git a/MdeModulePkg/Universal/SerialDxe/SerialDxe.inf > b/MdeModulePkg/Universal/SerialDxe/SerialDxe.inf > new file mode 100644 > index 0000000..7500266 > --- /dev/null > +++ b/MdeModulePkg/Universal/SerialDxe/SerialDxe.inf > @@ -0,0 +1,48 @@ > +#/** @file > +# Serial driver that layers on top of a Serial Port Library instance. > +# > +# Copyright (c) 2008 - 2015, Intel Corporation. All rights > +reserved.<BR> # This program and the accompanying materials # are > +licensed and made available under the terms and conditions of the BSD > +License # which accompanies this distribution. The full text of the > +license may be found at # > +http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > +BASIS, # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS > OR IMPLIED. > +# > +#**/ > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = SerialDxe > + FILE_GUID = D3987D4B-971A-435F-8CAF-4967EB627241 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + > + ENTRY_POINT = SerialDxeInitialize > + > +[Sources.common] > + SerialIo.c > + > +[Packages] > + MdePkg/MdePkg.dec > + > +[LibraryClasses] > + UefiDriverEntryPoint > + UefiBootServicesTableLib > + DebugLib > + PcdLib > + SerialPortLib > + > +[Protocols] > + gEfiSerialIoProtocolGuid > + gEfiDevicePathProtocolGuid > + > +[Pcd] > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits > + > +[Depex] > + TRUE > diff --git a/MdeModulePkg/Universal/SerialDxe/SerialDxe.uni > b/MdeModulePkg/Universal/SerialDxe/SerialDxe.uni > new file mode 100644 > index > 0000000000000000000000000000000000000000..9df8bea8aaae0a1f5a77571fc823eb758a43dd0e > GIT binary patch > literal 1892 > zcmdUv-HX#u5XI+N@P7#17nR*s1wll_){Pp}P3Z@#Pm;FVZeZI=8h7nKzw7VJZIf0i > z_@)waKju!(oH;W$cegETS;YH@C$iTzwcM`k!tUEWtUBwnE3jtRBb)g8+HH}Qc8R^j > ze#N|Y>x$jd7K|nHH{VSeGv0lyF6V`R{So{T>x_4eU(WX{PBP{(sLhJczt8K9XT5fv > zX6Pez9+1UD=BM_U=Q*pB&F+akvt!l?nU-WKjfGI4oJOgevs$1*WNpsnp?U;tsa^2h > z%C%QrCV0NIj`i%-0o4XD%JGiCFTkC7j5&L0Jz-W&FML0S_0r~e>TK;*nQ=0AR&`gb > zsyIRs8}&o(l~WzXsm9mWlTCzc*6O#6>Z|J_`|d1+T{Dp`1yRL%%Tmn5H?Q;weWy;_ > zX3(MEPT8xw)J1_y-9b05#h6jJ``PCB3sG1>FU3+%O8XH!ck3cm#eRxCR7jkE;G?^+ > z%V}Siprtx~wE2FyQ9z8!9bMH&C6##Lw^H{i<RkyWvuhHmpq{N?v|nKv!F)o`?MH8d > za>-jOGO+g+!=_93r1p-nZJ*dDC>f!p<^k4({u;81UEiUdF~`^=YyqLxKB1puJo=8D > zvQi&wY%mK~s14?h@3lML;dIWqP*aZ>**RW4XLg1?0aX~ONAIx{ci9wkfUkTMHF&+n > zSJA&Pf8a#Sb^qc`l#oSipDUaiJwb~u-K3bO2meX>i?*D*G}U`l^~{3W=np9UzJip3 > zF$67U*CzLH(nhTTe!qK;sG;t_jJjux>N<7830Pv<V61QE-}+xSDh>WDe|1lv%+*=l > Rs$z#U_&@S*Qip8^`~=5~DT)99 > > literal 0 > HcmV?d00001 > > diff --git a/MdeModulePkg/Universal/SerialDxe/SerialDxeExtra.uni > b/MdeModulePkg/Universal/SerialDxe/SerialDxeExtra.uni > new file mode 100644 > index > 0000000000000000000000000000000000000000..bfb8420d055ce7cbf6dbdd8268a9d7d99257d2ac > GIT binary patch > literal 1324 > zcmZvcTW`}q5QXO%iT|()FM!$vkdP2Uh=v%jC{2_mDm+C_LQ_k*R89&FKOXqbtS?PL > zmiIDy_RQI{WB>Wxv5p1ar#!*l*`?*SwD0!N9uU>qIkSRjM!aXY%z~ZT#%3PL?H7@` > z<93c)+rqZYGh2K7J=nGFK&h>Gt3H_4uWj#p7j^|E*kjnA(7&)}Jg*oXm$T>g(vBFX > zCFhc{7z#MlX6(;BW1E!|Gz%g9kz2|Nv}}0``{CN#_Qtw4w736JH$qYF=eY*Ifkio1 > zuvF*UfsiK|nr9$ZDAC%Ueexm@k*dbUZJkHEq$Z#;XSY0(GWl8YYxmqS8G18tOWG-| > z_T8{Us|DjqNzAo6xCJQ_GOzuS6C3Wk+1KT+d(2M{v@|#M)4iC{{(IUS4Pumr=$CSB > znalerI`7_#T$TDu;_-&0`4-H5O^3cjFZZCP<^E0SfD|>=72x0TT-$4}VpUl5R`|l5 > zZgcvA`{~^CeoJJE@;Nnkn7s|l6>sCn$Ua$ungP|*w~w?Z_Jw(hlL0T)kBFw!*O*b_ > z{*LX8J|P~6MTW-vlzL7;oI7)$k?L4&i(b59ZP9mquG!HYO&6?-weJ~&U4R<8vNPf- > ztm5c<_8~KAS4=raV1-fEi249l*}u_$W<|>N{Uv3Vc#6cn);tY+iWdW_NjZDgt~ECP > z>95oAxMGj$dWqjn^lnnRJAh?apI`!aAJ#GaiA~TY=XDp6N#BTAZs-?YE4u$<@X{wt > Vi&67UR)4mh*Q@>u1qk7)_b(`Z%trtK > > literal 0 > HcmV?d00001 > > diff --git a/MdeModulePkg/Universal/SerialDxe/SerialIo.c > b/MdeModulePkg/Universal/SerialDxe/SerialIo.c > new file mode 100644 > index 0000000..04699f8 > --- /dev/null > +++ b/MdeModulePkg/Universal/SerialDxe/SerialIo.c > @@ -0,0 +1,394 @@ > +/** @file > + Serial driver that layers on top of a Serial Port Library instance. > + > + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> > + Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR> Copyright > + (c) 2015, Intel Corporation. All rights reserved.<BR> > + > + This program and the accompanying materials are licensed and made > + available under the terms and conditions of the BSD License which > + accompanies this distribution. The full text of the license may be > + found at http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR > IMPLIED. > + > +**/ > + > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/SerialPortLib.h> > +#include <Library/DebugLib.h> > +#include <Library/PcdLib.h> > + > +#include <Protocol/SerialIo.h> > +#include <Protocol/DevicePath.h> > + > +typedef struct { > + VENDOR_DEVICE_PATH Guid; > + UART_DEVICE_PATH Uart; > + EFI_DEVICE_PATH_PROTOCOL End; > +} SERIAL_DEVICE_PATH; > + > +SERIAL_DEVICE_PATH mSerialDevicePath = { > + { > + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} > }, > + EFI_CALLER_ID_GUID // Use the driver's GUID > + }, > + { > + { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0} }, > + 0, // Reserved > + 0, // BaudRate > + 0, // DataBits > + 0, // Parity > + 0 // StopBits > + }, > + { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof > +(EFI_DEVICE_PATH_PROTOCOL), 0 } } }; > + > +EFI_HANDLE mSerialHandle = NULL; > + > +/** > + Reset the serial device. > + > + @param This Protocol instance pointer. > + > + @retval EFI_SUCCESS The device was reset. > + @retval EFI_DEVICE_ERROR The serial device could not be reset. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialReset ( > + IN EFI_SERIAL_IO_PROTOCOL *This > + ) > +{ > + EFI_STATUS Status; > + EFI_TPL Tpl; > + > + Status = SerialPortInitialize (); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Set the Serial I/O mode and update the device path // > + > + Tpl = gBS->RaiseTPL (TPL_NOTIFY); > + > + // > + // Set the Serial I/O mode > + // > + This->Mode->ReceiveFifoDepth = 1; > + This->Mode->Timeout = 0; > + This->Mode->BaudRate = PcdGet64 (PcdUartDefaultBaudRate); > + This->Mode->DataBits = (UINT32) PcdGet8 (PcdUartDefaultDataBits); > + This->Mode->Parity = (UINT32) PcdGet8 (PcdUartDefaultParity); > + This->Mode->StopBits = (UINT32) PcdGet8 (PcdUartDefaultStopBits); > + > + // > + // Check if the device path has actually changed // if > + (mSerialDevicePath.Uart.BaudRate == This->Mode->BaudRate && > + mSerialDevicePath.Uart.DataBits == (UINT8) This->Mode->DataBits && > + mSerialDevicePath.Uart.Parity == (UINT8) This->Mode->Parity && > + mSerialDevicePath.Uart.StopBits == (UINT8) This->Mode->StopBits > + ) { > + gBS->RestoreTPL (Tpl); > + return EFI_SUCCESS; > + } > + > + // > + // Update the device path > + // > + mSerialDevicePath.Uart.BaudRate = This->Mode->BaudRate; > + mSerialDevicePath.Uart.DataBits = (UINT8) This->Mode->DataBits; > + mSerialDevicePath.Uart.Parity = (UINT8) This->Mode->Parity; > + mSerialDevicePath.Uart.StopBits = (UINT8) This->Mode->StopBits; > + > + Status = gBS->ReinstallProtocolInterface ( > + mSerialHandle, > + &gEfiDevicePathProtocolGuid, > + &mSerialDevicePath, > + &mSerialDevicePath > + ); > + > + gBS->RestoreTPL (Tpl); > + > + return Status; > +} > + > +/** > + Sets the baud rate, receive FIFO depth, transmit/receive time out, > +parity, > + data buts, and stop bits on a serial device. Typo in comment above. Should be "data bits". > + > + @param This Protocol instance pointer. > + @param BaudRate The requested baud rate. A BaudRate value of 0 > will use the the > + device's default interface speed. > + @param ReceiveFifoDepth The requested depth of the FIFO on the receive > side of the > + serial interface. A ReceiveFifoDepth value of 0 > will use > + the device's default FIFO depth. > + @param Timeout The requested time out for a single character in > microseconds. > + This timeout applies to both the transmit and > receive side of the > + interface. A Timeout value of 0 will use the > device's default time > + out value. > + @param Parity The type of parity to use on this serial device. > A Parity value of > + DefaultParity will use the device's default > parity value. > + @param DataBits The number of data bits to use on the serial > device. A DataBits > + value of 0 will use the device's default data bit > setting. > + @param StopBits The number of stop bits to use on this serial > device. A StopBits > + value of DefaultStopBits will use the device's > default number of > + stop bits. > + > + @retval EFI_SUCCESS The device was reset. > + @retval EFI_DEVICE_ERROR The serial device could not be reset. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialSetAttributes ( > + IN EFI_SERIAL_IO_PROTOCOL *This, > + IN UINT64 BaudRate, > + IN UINT32 ReceiveFifoDepth, > + IN UINT32 Timeout, > + IN EFI_PARITY_TYPE Parity, > + IN UINT8 DataBits, > + IN EFI_STOP_BITS_TYPE StopBits > + ) > +{ > + EFI_STATUS Status; > + EFI_TPL Tpl; > + > + Status = SerialPortSetAttributes (&BaudRate, &ReceiveFifoDepth, > + &Timeout, &Parity, &DataBits, &StopBits); if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Set the Serial I/O mode and update the device path // > + > + Tpl = gBS->RaiseTPL (TPL_NOTIFY); > + > + // > + // Set the Serial I/O mode > + // > + This->Mode->ReceiveFifoDepth = ReceiveFifoDepth; > + This->Mode->Timeout = Timeout; > + This->Mode->BaudRate = BaudRate; > + This->Mode->DataBits = (UINT32) DataBits; > + This->Mode->Parity = (UINT32) Parity; > + This->Mode->StopBits = (UINT32) StopBits; > + > + // > + // Check if the device path has actually changed // if > + (mSerialDevicePath.Uart.BaudRate == BaudRate && > + mSerialDevicePath.Uart.DataBits == DataBits && > + mSerialDevicePath.Uart.Parity == (UINT8) Parity && > + mSerialDevicePath.Uart.StopBits == (UINT8) StopBits > + ) { > + gBS->RestoreTPL (Tpl); > + return EFI_SUCCESS; > + } > + > + // > + // Update the device path > + // > + mSerialDevicePath.Uart.BaudRate = BaudRate; > + mSerialDevicePath.Uart.DataBits = DataBits; > + mSerialDevicePath.Uart.Parity = (UINT8) Parity; > + mSerialDevicePath.Uart.StopBits = (UINT8) StopBits; > + > + Status = gBS->ReinstallProtocolInterface ( > + mSerialHandle, > + &gEfiDevicePathProtocolGuid, > + &mSerialDevicePath, > + &mSerialDevicePath > + ); > + > + gBS->RestoreTPL (Tpl); > + > + return Status; > +} > + > +/** > + Set the control bits on a serial device > + > + @param This Protocol instance pointer. > + @param Control Set the bits of Control that are settable. > + > + @retval EFI_SUCCESS The new control bits were set on the serial > device. > + @retval EFI_UNSUPPORTED The serial device does not support this operation. > + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialSetControl ( > + IN EFI_SERIAL_IO_PROTOCOL *This, > + IN UINT32 Control > + ) > +{ > + return SerialPortSetControl (Control); } > + > +/** > + Retrieves the status of the control bits on a serial device > + > + @param This Protocol instance pointer. > + @param Control A pointer to return the current Control signals > from the serial device. > + > + @retval EFI_SUCCESS The control bits were read from the serial > device. > + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialGetControl ( > + IN EFI_SERIAL_IO_PROTOCOL *This, > + OUT UINT32 *Control > + ) > +{ > + return SerialPortGetControl (Control); } > + > +/** > + Writes data to a serial device. > + > + @param This Protocol instance pointer. > + @param BufferSize On input, the size of the Buffer. On output, the > amount of > + data actually written. > + @param Buffer The buffer of data to write > + > + @retval EFI_SUCCESS The data was written. > + @retval EFI_DEVICE_ERROR The device reported an error. > + @retval EFI_TIMEOUT The data write was stopped due to a timeout. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialWrite ( > + IN EFI_SERIAL_IO_PROTOCOL *This, > + IN OUT UINTN *BufferSize, > + IN VOID *Buffer > + ) > +{ > + UINTN Count; > + > + Count = SerialPortWrite (Buffer, *BufferSize); > + > + if (Count != *BufferSize) { > + *BufferSize = Count; > + return EFI_TIMEOUT; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Reads data from a serial device. > + > + @param This Protocol instance pointer. > + @param BufferSize On input, the size of the Buffer. On output, the > amount of > + data returned in Buffer. > + @param Buffer The buffer to return the data into. > + > + @retval EFI_SUCCESS The data was read. > + @retval EFI_DEVICE_ERROR The device reported an error. > + @retval EFI_TIMEOUT The data write was stopped due to a timeout. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialRead ( > + IN EFI_SERIAL_IO_PROTOCOL *This, > + IN OUT UINTN *BufferSize, > + OUT VOID *Buffer > + ) > +{ > + UINTN Count = 0; > + > + if (SerialPortPoll()) { > + Count = SerialPortRead (Buffer, *BufferSize); } > + > + if (Count != *BufferSize) { > + *BufferSize = Count; > + return EFI_TIMEOUT; > + } > + > + return EFI_SUCCESS; > +} > + > +// > +// Template used to initialize the Serial IO protocols. > +// > +EFI_SERIAL_IO_MODE mSerialIoMode = { > + 0, // ControlMask > + 0, // Timeout > + 0, // BaudRate > + 1, // ReceiveFifoDepth > + 0, // DataBits > + 0, // Parity > + 0 // StopBits > +}; Global variables should be moved to top of file before first function implementation. > + > +EFI_SERIAL_IO_PROTOCOL mSerialIoTemplate = { > + SERIAL_IO_INTERFACE_REVISION, > + SerialReset, > + SerialSetAttributes, > + SerialSetControl, > + SerialGetControl, > + SerialWrite, > + SerialRead, > + &mSerialIoMode > +}; Global variables should be moved to top of file before first function implementation. > + > +/** > + Initialization for the Serial Io Protocol. > + > + @param[in] ImageHandle The firmware allocated handle for the EFI image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The entry point is executed successfully. > + @retval other Some error occurs when executing this entry > point. > + > +**/ > +EFI_STATUS > +EFIAPI > +SerialDxeInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + Status = SerialPortInitialize (); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Make a new handle with Serial IO protocol and its device path on it. > + // > + Status = gBS->InstallMultipleProtocolInterfaces ( > + &mSerialHandle, > + &gEfiSerialIoProtocolGuid, &mSerialIoTemplate, > + &gEfiDevicePathProtocolGuid, &mSerialDevicePath, > + NULL > + ); > + ASSERT_EFI_ERROR (Status); > + > + mSerialIoMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate); > + mSerialIoMode.DataBits = (UINT32) PcdGet8 (PcdUartDefaultDataBits); > + mSerialIoMode.Parity = (UINT32) PcdGet8 (PcdUartDefaultParity); > + mSerialIoMode.StopBits = (UINT32) PcdGet8 (PcdUartDefaultStopBits); > + mSerialDevicePath.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate); > + mSerialDevicePath.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits); > + mSerialDevicePath.Uart.Parity = PcdGet8 (PcdUartDefaultParity); > + mSerialDevicePath.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits); The fields of the device path protocol and Serial I/O Mode structure should be set before the Protocols are installed just in case another module has a Register Protocol Notify and uses these protocols before they are fully initialized. > + > + return Status; > +} > + > -- > 1.9.5.msysgit.0 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel