On 15 January 2016 at 18: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
>
>>
>> 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,
>
> 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]
>

This patch also fixes the problem for me.

Thanks,
Ard.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to