From: Laszlo Ersek <lersek@redhat.com>
To: Leif Lindholm <leif.lindholm@linaro.org>
Cc: "Kinney, Michael D" <michael.d.kinney@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"Gao, Liming" <liming.gao@intel.com>
Subject: Re: [PATCH] MdePkg: add big-endian MMIO BaseBeIoLib
Date: Mon, 16 Apr 2018 21:32:44 +0200 [thread overview]
Message-ID: <b15c2da8-abfa-488e-c98c-2916b5a56596@redhat.com> (raw)
In-Reply-To: <20180416100712.6v642ycksvmoffvt@bivouac.eciton.net>
On 04/16/18 12:07, Leif Lindholm wrote:
> On Fri, Apr 13, 2018 at 11:32:35PM +0000, Kinney, Michael D wrote:
>> Leif,
>>
>> I am curious why a Swap class/instances is not sufficient.
>>
>> Currently EDK II follows the UEFI/PI specs, which for all supported
>> CPU architectures use little endian ABI. The BaseIoLib follows the
>> endianness of the CPU. If UEFI/PI added a CPU that was big endian, I
>> would expect BaseIoLib when built for that CPU would perform big
>> endian operations.
>>
>> Am I missing something?
>
> If you did add a big-endian CPU, you could then find yourself in the
> exact opposite situation and require a little-endian i/o access
> library. Which would be implemented exactly as the contents of
> IoLibSwap.c.
>
> The header file necessarily needs to be endianness-specific, and if
> the coding style had permitted functions in header files, my automatic
> reaction would have been to make all of these static inline helper
> functions (even with the code duplication).
First, to remind myself of the previous discussion (and please correct
me if I remember incorrectly): whether swapping is needed or not depends
on both CPU byte order and device byte order. However, the library API
names that device drivers use should reflect device byte order *only*
(regardless of CPU byte order). This way,
(a) developers that write device drivers can focus on the devices,
regardless of what CPU the driver is compiled for,
(b) library classes for both LE and BE devices can be used together in
the same driver module,
(c) assuming we introduce a CPU with BE byte order, the same driver
source will work (for both LE and BE devices), only the lib
instances will have to be switched around. (This might even happen
dynamically, via function pointers.)
Now, after staring at this patch long and hard, here's my understanding.
Crucially, you take the IoLib class to mean "it doesn't swap". You don't
take it to mean "it talks to LE devices". This is evident from the
source file "IoLibSwap.c", where you add the swapping on top of IoLib.
That's fine, but it will have consequences:
(1) We need a separate library class called IoSwapLib (not IoLibSwap),
implemented under "MdePkg/Library/BaseIoSwapLib/BaseIoSwapLib.c",
and without the preprocessor trickery. There should be one library
instance only, adding nothing but byte swapping on top of IoLib.
(2) We need separate library classes called BeIoLib and LeIoLib. These
provide the ultimate APIs that I describe near the top. In total we
should have four library instances that are explicit about device
endianness. This means four INF files, and a single shared C source
file, *with* the preprocessor trickery.
(2.1) BaseBeIoLib.inf: implements the BeIoLib functions on top of IoLib,
that is, without swapping -- this means that it is suitable for
talking to BE devices on BE CPUs.
(2.2) BaseBeIoLibSwap.inf: implements the BeIoLib functions on top of
IoSwapLib -- talks to BE devices on LE CPUs.
(2.3) BaseLeIoLib.inf: implements LeIoLib functions on top of IoLib --
talks to LE devices on LE CPUs.
(2.4) BaseLeIoLibSwap.inf: implements LeIoLib functions on top of
IoSwapLib -- talks to LE devices on BE CPUs.
IMO, it's fine if you only want to add the BeIoLib class now, with its
BaseBeIoLibSwap instance only. But the IoSwapLib and BeIoLib classes
must exist separately nonetheless. And that's because your currently
proposed C source file is unable to express case (2.1): you can generate
the "Be" prefix alright, but the internals will always swap, and do that
on top of IoLib (which *never* swaps). So you will end up swapping once
in the Be*() functions, which is wrong for talking to BE devices on BE
CPUs.
I guess -- relaxing my initial point a bit -- it's also OK if you do not
introduce the BeIoLib class at all (let alone LeIoLib), saying that
drivers are generally expected to compute at startup whether they need
to byte-swap or not (considering both CPU and device byte order), and
then they need to flip a few function pointers between IoLib versus
IoSwapLib for all further use. In that case however the patch should not
say "Be" or "Le" in any lib class, instance, or API names, at all.
Some other random comments I have:
(3) You mention that no UNI file is being duplicated, but I do see one.
(4) Please consider adopting
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-10
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-23
so that patches roughly advance from "abstract" to "concrete".
(5) You skipped the following family of functions:
MmioBitField(Read|Write|Or|And|AndThenOr)(16|32|64). I don't think
that's right: the mask values at the least are expressed in host
byte order, and they'll need conversion. An earlier (independent)
discussion was at:
http://mid.mail-archive.com/48d7d1a9-503f-2a72-803d-f63a8bc67e9c@redhat.com
(6) Please don't use "__" and "_C" prefixes for identifiers (see
__CONCATENATE and _CONCATENATE); according to the C standard, "All
identifiers that begin with an underscore and either an uppercase
letter or another underscore are always reserved for any use".
I know Linux uses "__" prefixes liberally; that doesn't make them
any less wrong :)
... Obviously I don't insist on these patches being implemented "my
way"; I'm stating my opinion because you CC'd me :) (Thanks for that!)
Thanks,
Laszlo
next prev parent reply other threads:[~2018-04-16 19:32 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-13 17:42 [PATCH] MdePkg: add big-endian MMIO BaseBeIoLib Leif Lindholm
2018-04-13 19:24 ` Kinney, Michael D
2018-04-13 19:31 ` Leif Lindholm
2018-04-13 23:32 ` Kinney, Michael D
2018-04-16 10:07 ` Leif Lindholm
2018-04-16 14:10 ` Kinney, Michael D
2018-04-16 14:34 ` Michael Brown
2018-04-16 20:42 ` Laszlo Ersek
2018-04-16 22:14 ` Michael Brown
2018-04-17 8:01 ` Laszlo Ersek
2018-04-17 8:24 ` Michael Brown
2018-04-17 9:57 ` Laszlo Ersek
2018-04-17 13:26 ` Leif Lindholm
2018-04-17 15:20 ` Kinney, Michael D
2018-04-17 6:57 ` Udit Kumar
2018-04-16 19:32 ` Laszlo Ersek [this message]
2018-04-17 8:15 ` Udit Kumar
2018-04-17 9:42 ` Laszlo Ersek
2018-04-17 10:32 ` Udit Kumar
2018-04-17 13:55 ` (spawning off more style discussion) Leif Lindholm
2018-04-18 8:51 ` Laszlo Ersek
2018-04-16 4:39 ` [PATCH] MdePkg: add big-endian MMIO BaseBeIoLib Udit Kumar
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=b15c2da8-abfa-488e-c98c-2916b5a56596@redhat.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