public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Pete Batard" <pete@akeo.ie>
To: Ard Biesheuvel <ard.biesheuvel@arm.com>, devel@edk2.groups.io
Cc: leif@nuviainc.com, awarkentin@vmware.com,
	Andrei Warkentin <andrey.warkentin@gmail.com>
Subject: Re: [edk2-platforms][PATCH 2/3] Platform/RPi/DualSerialPortLib: Fix miniUART serial divisor computation
Date: Tue, 5 May 2020 13:09:41 +0100	[thread overview]
Message-ID: <f23ea6e7-aeb7-ce92-6cd0-c4ad0e54177c@akeo.ie> (raw)
In-Reply-To: <0e6ad129-cb7d-7f25-077f-7a3bb7e8c050@arm.com>

On 2020.05.05 13:05, Ard Biesheuvel wrote:
> On 5/5/20 1:54 PM, Pete Batard wrote:
>> Hi Ard,
>>
>> On 2020.05.05 11:05, Ard Biesheuvel wrote:
>>> On 5/4/20 1:15 PM, Pete Batard wrote:
>>>> From: Andrei Warkentin <andrey.warkentin@gmail.com>
>>>>
>>>> Fix for https://github.com/raspberrypi/firmware/issues/1376.
>>>>
>>>> For the Pi 3, to properly configure miniUART, we need the core clock,
>>>> which can be vary between VideoCore firmare release or config.txt 
>>>> options.
>>>>
>>>> Unfortunately, it's painful to get - it's only available via the 
>>>> mailbox
>>>> interface. Additionally, SerialLib is a very limited environment, even
>>>> when linked in a DXE-mode component, because as part of a DebugLib
>>>> implementation it ends being the base prerequisite of everything.
>>>> That means a "normal" mailbox implementation like the one from
>>>> RpiFirmwareDxe (with dependencies on DmaLib) is out of the question.
>>>> Using a basic implementation such as the one in PlatformLib doesn't 
>>>> work
>>>> either because it operates in both environments with MMU on (DXE phase)
>>>> and MMU off (SEC/PrePi).
>>>>
>>>> Ideally, we read the value via mbox exactly once at boot (PlatformLib),
>>>> and then somehow stash it. A GUID Hob sounds appropriate, yet when
>>>> SerialPortLib operates in DXE components, we can't use the HobLib to
>>>> *locate* the Hob list itself (remember, SerialPortLib initializes
>>>> before any of HobLib's dependencies, like UeflLib...).
>>>>
>>>
>>> Yeah, the gift that keeps on giving :-) NXP are struggling with a 
>>> similar issue.
>>>
>>> So the problem is that SerialPortInitialize() is called before we 
>>> know what value to program, and we cannot rely on other libraries to 
>>> discover this value because they may not work before their 
>>> constructor has been called.
>>
>> I wouldn't qualify the problem that way.
>>
>> The problem is that we have everything we need to program the UART by 
>> the time we get into SerialPortInitialize(), because 
>> ArmPlatformPeiBootAction() has long retrieved that one variable/value 
>> we need, which everything downstream relies on, but sharing that one 
>> variable properly, so that it available in both PEI and DXE by the 
>> time it is needed, is a headache.
>>
>> For all intent and purposes, we always have the value we need, because 
>> that's pretty much the very first thing we query. On the other hand, 
>> directing that value to the places that consume it is problematic 
>> because most of the mechanisms we have to do that have some kind of 
>> reliance that serial output would already have been initialized...
>>
>> So we have been treating it as mere problem of sharing a global 
>> variable between PEI and DXE and nothing else, hence the proposal. As 
>> a matter of fact, we started with an alternate solution where we just 
>> added an extra page on top of the NvStorage reserved region, and 
>> stored the variable there at an address that DualSerialPortLib could 
>> easily retrieve in either PEI or DXE mode (with no need for the extra 
>> PlatformPeiLib then). Hob is just the natural progression of that, to 
>> achieve it in a more EDK2-like way.
>>
>>> So can we break the contents of SerialPortInitialize() into things 
>>> that need to happen once (program the divisors etc) and things that 
>>> need to  > happen each and every time (figure out which UART we are 
>>> using in the
>>> first place)?
>>
>> I'm trying to understand what you're getting at here.
>>
>> By once and multiple time, I am assuming that you're referring to the 
>> various instantiations of the library, because I only expect 
>> SerialPortInitialize() to be called once per instance for DebugLib 
>> related uses, so technically, everything from SerialPortInitialize() 
>> could be considered a one-time operation.
>>
>> So I guess what you're suggesting is that we somehow drop setting up 
>> the baudrate in DXE phase and just assume that it has already been set 
>> from PEI.
>>
>>> If the second set does not suffer from the same issue, can we just 
>>> move the entire logic that programs the UART block into PrePi, so 
>>> that all subsequent users don't have to touch those registers at all?
>>
>> Well, someone can and will want to switch baudrate from Shell, which 
>> means we need to compute a dynamic divisor from the base serial clock 
>> frequency. So the only way I can see your idea work is if we re-query 
>> the mbox to obtain the base serial clock frequency in 
>> SerialPortSetAttributes(), but that means that, for the compiler to be 
>> happy, it will need to set up a DXE dependency with RpiFirmwareDxe, 
>> which we can't have in PEI phase...
>>
>>> This means we may need two versions of DualSerialPortLib,
>>
>> Unless there exists a compile time macros that indicate whether code 
>> is compiling in PEI or DXE phase (and even then I suspect that .inf 
>> sections will not cooperate that easily), then I don't see how we can 
>> avoid having two separate versions of DualSerialPortLib indeed, and I 
>> see that as becoming more of a headache than what we're proposing here...
>>
>>> where the one that PrePi uses may need to be attached to SerialDxe as 
>>> well, so that it can reprogram the baud rate as needed. But for all 
>>> the remaining DebugLib related uses, we don't really need to 
>>> reprogram the UART at all afaics.
>>
>>  From a design standpoint, this may look fine, but from an 
>> implementation standpoint, when, again, the one problem we are really 
>> trying to solve is the sharing of a global variable, I fear that we 
>> are going to shoot ourselves in the foot if we try to go in that 
>> direction, because duplication of code, when it can be avoided, 
>> doesn't strike me like a good idea.
>>
>> If we are going to push for something like that, I'd much rather work 
>> on another EDK2 library that solves the problem of early global 
>> variable sharing between DXE and PEI, than something that's custom to 
>> RPi and that's not going to help anybody else in the process.
>>
>> However, considering the time that has already spent trying to solve 
>> this issue, I'd rather not have to do either of these, really, because 
>> I don't think there is much to gain from adding bells and whistle to a 
>> problem that really boils down to "We need to share a global variable, 
>> that we set in early PEI, between PEI and DXE" and which we have 
>> solved using what I believe to be the mandated EDK2 way of doing it 
>> (HOBs).
>>
>> Now, if you are *really* that opposed to the current solution, I can 
>> see what's achievable. But I'd rather only have to do that on a major 
>> objection ("This proposal may create problems in the long run because 
>> X, Y...") rather than preference of how things may look be better 
>> organized if we did it in this other fashion...
>>
>> Besides the need to add an extra PlatformPeiLib and the small hack we 
>> had to use to get to the Hob in early DXE phase, do you have specific 
>> concerns about the current proposal that you identify as reasonable 
>> ground to want to push it back?
>>
> 
> I'll have a stab at coding it up myself.
> 

Obviously, that works for me. :)

Thanks!

/Pete

  reply	other threads:[~2020-05-05 12:09 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-04 11:15 [edk2-platforms][PATCH 0/3] Platform/RPi: Fix compatibility with recent start.elf Pete Batard
2020-05-04 11:15 ` [edk2-platforms][PATCH 1/3] Platform/RPi: Fortify mailbox code Pete Batard
2020-05-06 12:39   ` Ard Biesheuvel
2020-05-04 11:15 ` [edk2-platforms][PATCH 2/3] Platform/RPi/DualSerialPortLib: Fix miniUART serial divisor computation Pete Batard
2020-05-05 10:05   ` Ard Biesheuvel
2020-05-05 11:54     ` Pete Batard
2020-05-05 12:05       ` Ard Biesheuvel
2020-05-05 12:09         ` Pete Batard [this message]
2020-05-04 11:15 ` [edk2-platforms][PATCH 3/3] Platform/RPi: Report core clock frequency during early init Pete Batard
2020-05-04 11:37   ` [edk2-devel] " Philippe Mathieu-Daudé
2020-05-05  6:04   ` Andrei Warkentin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f23ea6e7-aeb7-ce92-6cd0-c4ad0e54177c@akeo.ie \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox