public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: "David A. Van Arnem" <dvanarnem@cmlab.biz>,
	"edk2-devel@ml01.01.org" <edk2-devel@ml01.01.org>
Subject: Re: Print from DXE_DRIVER
Date: Thu, 9 Feb 2017 01:15:32 +0100	[thread overview]
Message-ID: <09c11a95-99e2-eb82-304b-c294b4785841@redhat.com> (raw)
In-Reply-To: <4a3de604-5e60-7ed2-e520-29ab6b551c33@cmlab.biz>

On 02/08/17 23:10, David A. Van Arnem wrote:
> Hello,
> 
> I am working on a DXE_DRIVER for a custom device.  I like to use Print()
> statements to trace code execution during development.  Thus I have put
> a print statement in each of my Supported(), Start(), and Stop()
> functions for the driver binding protocol.  Currently I am building the
> driver as part of the UefiCpuPkg, with no changes to the current
> UefiCpuPkg.dsc except for adding my driver under [Components].  I have
> also added the PrintLib and UefiLib to the [LibraryClasses] section in
> my driver's INF file, and included the necessary headers.
> 
> When I load the driver from the shell (load <drivername>.efi), I get a
> message indicating it loaded successfully, but no output from the
> Print() messages.  The documentation for the shell says load should test
> both the Supported() and Start() functions, so I would expect to see the
> output, but I am not sure I am using the correct library instances to
> accomplish this.  Is it possible to use Print() from a DXE_DRIVER, and
> which library instance should I use in the UefiCpuPkg.dsc file?  If not,
> would changing it to a UEFI_DRIVER help?  Any other recommendations?
> 
> If there is an example in edk2 that does this that you could point me
> to, that would be sufficient as well.  Thanks!
> 

I never tried to use Print() from drivers, only applications
(UEFI_APPLICATION modules). In drivers I always use DEBUG, which, based
on the DebugLib instance in use, can be routed to some debug port,
serial port, etc.

But, I think Print() can be made work too. The only Print() function
that should matter is in "MdePkg/Library/UefiLib/UefiLibPrint.c". It uses

  gST->ConOut

as output console. Since this comes from the UEFI system table, it's
clear that you shouldn't be writing a DXE_DRIVER, since those can run
much earlier than the UEFI architectural protocols become available.
DXE_DRIVER modules are practically platform drivers; they are not
governed by the UEFI spec by the PI spec, but the system table is
defined in the UEFI spec. (The above sounds a bit hand-wavy, but it
should work for this discussion.)

Another sign that you should be writing on a UEFI_DRIVER module is that
the Start(), Stop(), and Supported() member functions belong to the
driver binding protocol, which exists for UEFI drivers that conform to
the UEFI driver model. IOW, you're not only working on a UEFI_DRIVER
already, but one that falls into a specific class of UEFI_DRIVERs.

The third sign that your module type should be UEFI_DRIVER is the intro
text in "MdePkg/Library/UefiLib/UefiLib.inf", to which library Print()
belongs. Rewrapped here for readability:

#  The UEFI Library provides functions and macros that simplify the
#  development of UEFI Drivers and UEFI Applications.  These functions
#  and macros help manage EFI events, build simple locks utilizing EFI
#  Task Priority Levels (TPLs), install EFI Driver Model related
#  protocols, manage Unicode string tables for UEFI Drivers, and print
#  messages on the console output and standard error devices.

I recommend always reading the INF file comments, they are very-very
useful most of the time.

Finally, just loading a UEFI_DRIVER into memory and running it will do
nothing for binding devices (as long as the driver conforms to the UEFI
driver model, which I assume your driver does, based on the above). Such
drivers only install their driver binding protocol instance(s) in their
entry points, and then exit. Those Supported(), Start(), and Stop()
functions have to be called by something. They are called by the
gBS->ConnectController() boot service, which in turn is exposed in the
shell with the CONNECT command. Please see the documentation / help text
on it.

So I recommend:
- flip your module type to UEFI_DRIVER,
- once the driver is loaded, try a recursive CONNECT from the shell.

Hope this helps,
Laszlo


  reply	other threads:[~2017-02-09  0:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-08 22:10 Print from DXE_DRIVER David A. Van Arnem
2017-02-09  0:15 ` Laszlo Ersek [this message]
2017-02-09  0:41   ` David A. Van Arnem
2017-02-09  0:49     ` Andrew Fish
2017-02-09  0:43 ` Andrew Fish
2017-02-09  0:49   ` David A. Van Arnem
2017-02-09  1:04     ` Andrew Fish
2017-02-09  2:16       ` Gao, Liming
2017-02-09  2:55   ` Rebecca Cran
2017-02-09  2:59     ` Tim Lewis
2017-02-09 20:38       ` David A. Van Arnem

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=09c11a95-99e2-eb82-304b-c294b4785841@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