From: "Ard Biesheuvel" <ard.biesheuvel@arm.com>
To: Pete Batard <pete@akeo.ie>, 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 14:05:43 +0200 [thread overview]
Message-ID: <0e6ad129-cb7d-7f25-077f-7a3bb7e8c050@arm.com> (raw)
In-Reply-To: <107b231b-e119-2e80-35d8-35ed27dc0cf7@akeo.ie>
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.
next prev parent reply other threads:[~2020-05-05 12:05 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 [this message]
2020-05-05 12:09 ` Pete Batard
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=0e6ad129-cb7d-7f25-077f-7a3bb7e8c050@arm.com \
--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