From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id EA6A881F3D for ; Wed, 8 Feb 2017 16:15:34 -0800 (PST) Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4CD092E6076; Thu, 9 Feb 2017 00:15:35 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-31.phx2.redhat.com [10.3.116.31]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v190FXVw021860; Wed, 8 Feb 2017 19:15:34 -0500 To: "David A. Van Arnem" , "edk2-devel@ml01.01.org" References: <4a3de604-5e60-7ed2-e520-29ab6b551c33@cmlab.biz> From: Laszlo Ersek Message-ID: <09c11a95-99e2-eb82-304b-c294b4785841@redhat.com> Date: Thu, 9 Feb 2017 01:15:32 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: <4a3de604-5e60-7ed2-e520-29ab6b551c33@cmlab.biz> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 09 Feb 2017 00:15:35 +0000 (UTC) Subject: Re: Print from DXE_DRIVER X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Feb 2017 00:15:35 -0000 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit 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 .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