On 15 January 2016 at 17:39, Laszlo Ersek <ler...@redhat.com> wrote:
> On 01/15/16 18:33, Ryan Harkin wrote:
>> On 15 January 2016 at 17:05, Laszlo Ersek <ler...@redhat.com> wrote:
>>> Hi,
>>>
>>> snipping context liberally...
>>>
>>>>>>>>>>>> Whilst simple text input seems to work ok, cursor support does not.
>>>>>>>>>>>> And we need cursor support for Intel BDS.
>>>
>>> (1) I think this is important. See below.
>>>
>>>> When trying to revert your patch on the latest trunk code, the build
>>>> fails because your patch is doing too many things in one step.  It
>>>> should have been three (or more) patches, in my opinion.
>>>
>>> (2)
>>>
>>> (Caveat: what I'm about to say / reference here may not apply fully.)
>>>
>>> I just want to say that I followed / partially reviewed Star's patch series 
>>> (earlier versions of it than v4), and I had the exact same impression (= 
>>> "this is too big"), about the patch that did more or less the same for 
>>> ArmVirtPkg.
>>>
>>> Surprisingly :), I was wrong. Please see the message of commit
>>>
>>> commit ad7f6bc2e1163125cdb26f6b0e6695554028626a
>>> Author: Star Zeng <star.z...@intel.com>
>>> Date:   Thu Nov 26 08:52:12 2015 +0000
>>>
>>>     ArmVirtPkg: Use SerialDxe in MdeModulePkg instead of EmbeddedPkg
>>>
>>> Also, this sub-thread could be interesting:
>>>
>>> http://thread.gmane.org/gmane.comp.bios.edk2.devel/4582/focus=4593
>>>
>>
>> I don't think this is the same as ARM platform support.  I think there
>> could have been a single patch to move the code from ExtLib to Lib.
>> Another to remove ExtLib and another to change from to MdeModulePkg.
>>
>>
>>>>
>>>> Instead of reverting, I manually added back PL011SerialPortExtLib and
>>>> removed the code from PL011SerialPortLib at the same time.  Then, the
>>>> code did not compile.
>>>>
>>>> So I changed my patch to also make PL011SerialPortLib return 0 instead
>>>> of calling the PL011 functions.  And everything started to work.  I
>>>> assumed this was because I added back the ExtLib, not because I
>>>> changed the added code.  I was wrong.
>>>>
>>>> I've just pushed a new branch, serialdxe-fix-006, that only changes
>>>> PL011SerialPortLib.c to "return 0;" for all the new functions - and
>>>> that works also.
>>>>
>>>> So I don't need PL011SerialPortExtLib at all.  I guess it was never
>>>> called from there?  When you moved the code to PL011SerialPortLib, it
>>>> started getting called - and the code is causing problems.
>>>>
>>>>
>>>>> Could you check out to *SHA-1: 1b96428d92c01383dc437717db679f57cf70d980*
>>>>> that just before my SerialDxe series changes, and help to confirm if there
>>>>> is regression?
>>>>>
>>>>
>>>> I already checked out the commit before yours [1] and it works fine.
>>>>
>>>> [1] git checkout 921e987b2b26602dc85eaee856d494b97b6e02b0^
>>>
>>> (3) Alright, so SVN r18974 (git 1bccab910700) is the commit that removes 
>>> the old SerialDxe from EmbeddedPkg. At that stage, all client packages have 
>>> been converted to the new driver in MdeModulePkg. Therefore, if we want to 
>>> compare the two *drivers*, we have to check out the parent of this commit 
>>> (that is, check out SVN r18973 == git 1bccab910700^ == git ad7f6bc2e1), and 
>>> compare the following files:
>>>
>>> - EmbeddedPkg/SerialDxe/SerialIo.c
>>> - MdeModulePkg/Universal/SerialDxe/SerialIo.c
>>>
>>> I don't recommend to diff them -- instead, open them both side by side, and 
>>> read them in parallel.
>>>
>>> This way I noticed the following difference:
>>>
>>> (a) In the EmbeddedPkg driver, we have the following *initial* values (not 
>>> quoting everything, just what I think is relevant):
>>>
>>>   EFI_SERIAL_IO_PROTOCOL.Mode->Timeout          = 0
>>>   EFI_SERIAL_IO_PROTOCOL.Mode->ReceiveFifoDepth = 1
>>>
>>> (see gSerialIoTemplate and gSerialIoMode), however the SerialReset() 
>>> function (implementing the Reset protocol member) sets the following, 
>>> different values:
>>>
>>>   EFI_SERIAL_IO_PROTOCOL.Mode->Timeout          = 1000000
>>>   EFI_SERIAL_IO_PROTOCOL.Mode->ReceiveFifoDepth = 0
>>>
>>> Inconsistent, right? But that's not the difference I think is relevant:
>>>
>>> (b) The MdeModulePkg driver stores the following settings *both* at driver 
>>> initialization and in SerialReset():
>>>
>>>   EFI_SERIAL_IO_PROTOCOL.Mode->Timeout          = 0
>>>   EFI_SERIAL_IO_PROTOCOL.Mode->ReceiveFifoDepth = 1
>>>
>>> (See mSerialIoTemplate and mSerialIoMode.)
>>>
>>> That is, the initial state for Mode is identical between the (a) old and 
>>> (b) new drivers. However, these relevant-looking fields *differ* between 
>>> old and new driver after a client calls EFI_SERIAL_IO_PROTOCOL.Reset(). 
>>> Then the old driver sets a ReceiveFifoDepth of zero, while the new driver 
>>> sets 1. (I'll ignore Timeout for now.)
>>>
>>> The UEFI spec says the following about ReceiveFifoDepth:
>>>
>>>     ReceiveFifoDepth    The number of characters the device will buffer on 
>>> input.
>>>
>>>     [...]
>>>
>>>     The default attributes for all UART-style serial device interfaces
>>>     are: 115,200 baud, a 1 byte receive FIFO, a 1,000,000 microsecond
>>>     timeout per character, no parity, 8 data bits, and 1 stop bit. [...]
>>>
>>>     Special care must be taken if a significant amount of data is going
>>>     to be read from a serial device. Since UEFI drivers are polled mode
>>>     drivers, characters received on a serial device might be missed. It
>>>     is the responsibility of the software that uses the protocol to
>>>     check for new data often enough to guarantee that no characters will
>>>     be missed. The required polling frequency depends on the baud rate
>>>     of the connection and the depth of the receive FIFO.
>>>
>>> Okay, thus far it seems that the *new* driver is the correct one; the old 
>>> ReceiveFifoDepth=0 setting, after Reset() was incorrect.
>>>
>>> Let's see though if that zero value is special in some way.
>>>
>>> Both old and new drivers depend on SerialPortLib. If I understand 
>>> correctly, this class is resolved in both cases to the 
>>> ArmPlatformPkg/Library/PL011SerialPortLib instance. That instance in turn 
>>> depends on PL011UartLib.
>>>
>>> PL011UartLib is resolved, by 
>>> "ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc", to 
>>> "ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf". This DSC include file 
>>> seems to be used by the Juno platform. So in the end we should look at how 
>>> "ArmPlatformPkg/Drivers/PL011Uart" handles ReceiveFifoDepth.
>>>
>>> In PL011UartInitializePort(), we have:
>>>
>>>   // The PL011 supports a buffer of 1, 16 or 32 chars. Therefore we can 
>>> accept
>>>   // 1 char buffer as the minimum fifo size. Because everything can be 
>>> rounded down,
>>>   // there is no maximum fifo size.
>>>   if ((*ReceiveFifoDepth == 0) || (*ReceiveFifoDepth >= 32)) {
>>>     LineControl |= PL011_UARTLCR_H_FEN;
>>>     if (PL011_UARTPID2_VER (MmioRead32 (UartBase + UARTPID2)) > 
>>> PL011_VER_R1P4)
>>>       *ReceiveFifoDepth = 32;
>>>     else
>>>       *ReceiveFifoDepth = 16;
>>>   } else {
>>>     ASSERT (*ReceiveFifoDepth < 32);
>>>     // Nothing else to do. 1 byte fifo is default.
>>>     *ReceiveFifoDepth = 1;
>>>   }
>>>
>>> Now, I didn't even *try* to trace the actual control flow, but, 
>>> post-Reset(),
>>> - with the old driver we seem to have room for at least 16 characters in 
>>> the receive FIFO, and the PL011_UARTLCR_H_FEN (== "FIFOs Enable") bit gets 
>>> set,
>>> - whereas with the new driver, we end up with a single-byte buffer, and the 
>>> "FIFOs Enable" bit is cleared in the line control register.
>>>
>>> I think this looks quite consistent with the facts that:
>>> - simple text input (= single byte "scan codes", with human-scale pauses 
>>> between them) works,
>>> - but cursor movement (= multibyte escape sequences, produced in 
>>> machine-scale bursts) breaks.
>>>
>>> (4) My opinion:
>>>
>>> - The new driver's ReceiveFifoDepth setting, on init and on Reset, is 
>>> correct. (Conforms to the spec.)
>>>
>>> - The Timeout defaults seem wrong however: 1 million usecs should be set.
>>>
>>> - Whatever *uses* the Serial IO Protocol directly, should explicitly set 
>>> some ReceiveFifoDepth (with the SetAttributes() member function), such that 
>>> the depth accommodates the longest escape sequence that the client wishes 
>>> to handle. I believe this requirement falls on the TerminalDxe driver, 
>>> doesn't it?
>>>
>>> In any case, the explicitly configured FIFO depth can be "zero", 
>>> apparently, for selecting the device's "default" FIFO depth. (See the 
>>> documentation of SetAttributes()).
>>>
>>> (BTW, the SetAttributes() spec also explains the "everything can be rounded 
>>> down" comment from PL011UartInitializePort(): "The nearest FIFO size 
>>> supported by the serial device will be selected without exceeding the 
>>> ReceiveFifoDepth parameter.")
>>>
>>> Ryan, can you please test the following patch?
>>>
>>>> diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c 
>>>> b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>>>> index 6fde3b2..e1a6527 100644
>>>> --- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>>>> +++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
>>>> @@ -806,7 +806,7 @@ TerminalDriverBindingStart (
>>>>      Status = TerminalDevice->SerialIo->SetAttributes (
>>>>                                          TerminalDevice->SerialIo,
>>>>                                          Mode->BaudRate,
>>>> -                                        Mode->ReceiveFifoDepth,
>>>> +                                        0, // device's default FIFO depth.
>>>>                                          (UINT32) SerialInTimeOut,
>>>>                                          (EFI_PARITY_TYPE) (Mode->Parity),
>>>>                                          (UINT8) Mode->DataBits,
>>>> diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c 
>>>> b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>>>> index 3be877b..ffdc8f2 100644
>>>> --- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>>>> +++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
>>>> @@ -547,7 +547,7 @@ TerminalConInTimerHandler (
>>>>      Status = SerialIo->SetAttributes (
>>>>                          SerialIo,
>>>>                          Mode->BaudRate,
>>>> -                        Mode->ReceiveFifoDepth,
>>>> +                        0, // device's default FIFO depth.
>>>>                          (UINT32) SerialInTimeOut,
>>>>                          (EFI_PARITY_TYPE) (Mode->Parity),
>>>>                          (UINT8) Mode->DataBits,
>>>
>>
>> Yes, this works for me.
>
> Thanks for the testing (to Ard too)!
>
>> So what do you think the proper solution is?  Is Ard's patch not what
>> you were thinking?
>
> I think the UEFI spec is clear enough on EFI_SERIAL_IO_PROTOCOL that we
> can derive what the right thing is:
>
> - SerialDxe needs a fix so that not only its ReceiveFifoDepth defaults
> are correct (beause they are correct now!), but also the Timeout defaults.
>
> - TerminalDxe needs a fix too: it should recognize the defaults set by
> SerialDxe (as per UEFI spec requirements), and set ReceiveFifoDepth
> explicitly, with a SetAttributes() call. A good value for that looks
> like zero (= device's default FIFO depth). I believe the value zero also
> happens to restore the previous behavior, in practice -- it's just not
> SerialDxe's responsibility.
>

The problem I have is that is someone decides that TerminalDxe needs
to set the depth to 1 again, or some other value, the ARM platforms
will break, because they clearly can set that value, but it isn't
useful/usable.  So perhaps PL011 needs to use the device's default
value, irrespective of what TerminalDxe asks for?

> Thanks
> Laszlo
>
>>
>>> I expect the following call chain:
>>>
>>> TerminalDriverBindingStart() | TerminalConInTimerHandler() 
>>> [MdeModulePkg/Universal/Console/TerminalDxe]
>>>   SerialSetAttributes()                                    
>>> [MdeModulePkg/Universal/SerialDxe/SerialIo.c]
>>>     SerialPortSetAttributes()                              
>>> [ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c]
>>>       PL011UartInitializePort()                            
>>> [ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c]
>>>
>>> Thanks!
>>> Laszlo
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to