On 2019.10.10 17:43, Leif Lindholm wrote:
On Thu, Oct 10, 2019 at 01:41:06PM +0100, Pete Batard wrote:
Hi Leif,
On 2019.10.10 09:39, Leif Lindholm wrote:
On Tue, Oct 08, 2019 at 01:38:37PM +0100, Pete Batard wrote:
This patch introduces the capability to also query the Model Name/
Manufacturer Name/CPU Name/Firmware Revision using the RpiFirmware
protocol. This is aims at making the driver more suitable to cater
for platforms other than the Raspberry Pi 3 as well as simplifying
the population of entries in PlatformSmbiosDxe.
Signed-off-by: Pete Batard <p...@akeo.ie>
---
Platform/RaspberryPi/RPi3/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c | 155
+++++++++++++++++++-
Platform/RaspberryPi/RPi3/Include/Protocol/RpiFirmware.h | 58
++++++--
2 files changed, 196 insertions(+), 17 deletions(-)
diff --git a/Platform/RaspberryPi/RPi3/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
b/Platform/RaspberryPi/RPi3/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
index 9b5ee1946279..378c99bcba05 100644
--- a/Platform/RaspberryPi/RPi3/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
+++ b/Platform/RaspberryPi/RPi3/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
@@ -461,7 +461,7 @@ typedef struct {
RPI_FW_TAG_HEAD TagHead;
RPI_FW_MODEL_REVISION_TAG TagBody;
UINT32 EndTag;
-} RPI_FW_GET_MODEL_REVISION_CMD;
+} RPI_FW_GET_REVISION_CMD;
#pragma pack()
STATIC
@@ -471,7 +471,7 @@ RpiFirmwareGetModelRevision (
OUT UINT32 *Revision
)
{
- RPI_FW_GET_MODEL_REVISION_CMD *Cmd;
+ RPI_FW_GET_REVISION_CMD *Cmd;
EFI_STATUS Status;
UINT32 Result;
@@ -506,6 +506,153 @@ RpiFirmwareGetModelRevision (
return EFI_SUCCESS;
}
+STATIC
+EFI_STATUS
+EFIAPI
+RpiFirmwareGetFirmwareRevision (
+ OUT UINT32 *Revision
+ )
+{
+ RPI_FW_GET_REVISION_CMD *Cmd;
+ EFI_STATUS Status;
+ UINT32 Result;
+
+ if (!AcquireSpinLockOrFail (&mMailboxLock)) {
+ DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__));
+ return EFI_DEVICE_ERROR;
+ }
+
+ Cmd = mDmaBuffer;
+ ZeroMem (Cmd, sizeof (*Cmd));
+
+ Cmd->BufferHead.BufferSize = sizeof (*Cmd);
+ Cmd->BufferHead.Response = 0;
+ Cmd->TagHead.TagId = RPI_MBOX_GET_REVISION;
+ Cmd->TagHead.TagSize = sizeof (Cmd->TagBody);
+ Cmd->TagHead.TagValueSize = 0;
+ Cmd->EndTag = 0;
+
+ Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_CHANNEL,
&Result);
+
+ ReleaseSpinLock (&mMailboxLock);
+
+ if (EFI_ERROR (Status) ||
+ Cmd->BufferHead.Response != RPI_MBOX_RESP_SUCCESS) {
+ DEBUG ((DEBUG_ERROR,
+ "%a: mailbox transaction error: Status == %r, Response == 0x%x\n",
+ __FUNCTION__, Status, Cmd->BufferHead.Response));
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Revision = Cmd->TagBody.Revision;
+ return EFI_SUCCESS;
+}
+
+STATIC
+CHAR8*
+EFIAPI
+RpiFirmwareGetModelName (
+ IN INTN ModelId
+ )
+{
+ UINT32 Revision;
+
+ // If a negative ModelId is passed, detect it.
+ if ((ModelId < 0) && (RpiFirmwareGetModelRevision (&Revision) ==
EFI_SUCCESS))
Style-wise, please always use {} with if-statements.
Will do.
Beyond that, this pattern repeats identcally in three functions in
this file. Meanwhile, there is never any error handling of
RpiFirmwareGetModelRevision other than if not successful, we leave it
as negative.
Yes, because then we'll get the default case (that returns "Unknown ..."),
which is precisely what we want if we can't access the model revision for
any reason.
Are there other intended uses of that function, or could
we move this logic there?
I'm not sure how that would work, since ModelId, ManufacturerId, and CpuId
are for different parts of the bit fields, so, if I understand what you're
suggesting correctly (but I'm not really sure I do) trying to move the check
for negative value into RpiFirmwareGetModelRevision () wouldn't work that
great. Plus then the function name would become a misnommer.
Are you really seeing a functional issue with the current code, or something
that would make a possible contributor wanting to modify this section
puzzled as to what we're trying to accomplish here (which I think is pretty
clear, but then again, I wrote the code so maybe I'm not the most impartial?
Because if not, I'd rather save my limited supply of time, and just go with
a v3 that only adds the {} suggested.
I see no functional issues with the code, but with my own limited
supply of time I try to ensure the code stays as simple as possible so
I don't need to stop and think where there isn't actually anything
complicated going on (like here). I am after all a bear of very little
brain.
I also will *always* trigger on seeing a near-identical pattern
repeated many times in the same file.
In this instance, I find myself spending way too much time untangling
what is actually going on. I see
- SysInfoUpdateSmbiosType1 () calling mFwProtocol->GetModelRevision (),
and then using the result from that to determine which parameters to
pass to mFwProtocol->GetModelName() and
mFwProtocol->GetManufacturerName().
- Both of which if the GetModelRevision () call was unsuccessful get
passed -1.
The whole point is to create new generic calls that may be used by any
driver that needs them, and not only PlatformSmbiosDxe. That's our
starting point. And the idea is that, unlike what currently happens in
SysInfoUpdateSmbiosType1 (), not all of these calls may also happen to
be calling GetModelRevision ().
As such, I believe it makes a lot of sense to have the new calls
designed as they are, else we find ourselves trying to cover the case of
minimizing calls to GetModelRevision (), either in PlatformSmbiosDxe or
RpiFirmwareDxe, which seems an unwarranted micro optimization goal to me.
- Now, when the parameter is -1, they both call straight into
GetModelRevision (). Why are we expecting the second call to succeed
when the first one fails?
We're not expecting anything. We're receiving a call from a driver, of
which we have no idea what actions it performed beforehand, that may
happens to ask us to replicate some of these actions. And, in a generic
manner, and regardless of a state we should not have any idea about due
to encapsulation, we do issue a call to GetModelRevision ().
Or, let me put it this way: From
PlatformSmbiosDxe:SysInfoUpdateSmbiosType1 ()'s perspective, the call to
RpiFirmwareDxe:GetModelName () is supposed to be a black box that
returns a result it can use. And from RpiFirmwareDxe:GetModelName ()'s
perspective, what potentially duplicated actions the caller did
beforehand is also a black box.
Ideally, this is intended to make both drivers, with their better
abstracted goals, easier to understand and maintain, so I can't help but
feel quite dismayed that it's the very opposite that appears to be
occurring here. Still, if anything, I would assert that any action that
aims at reducing calls to GetModelRevision () should be reported against
PlatformSmbiosDxe rather than the lower level (and therefore more
generic) RpiFirmwareDxe.
Regards,
/Pete
Am I completely misreading what this code does?
Does GetModelRevision() return different values depending on when you
call it?
Best Regards,
Leif
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#48747): https://edk2.groups.io/g/devel/message/48747
Mute This Topic: https://groups.io/mt/34441816/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-