<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MachineHunter</title>
    <description>The latest articles on DEV Community by MachineHunter (@machinehunter).</description>
    <link>https://dev.to/machinehunter</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F862447%2Feb55498b-2f2a-42d5-b956-a06fb23ff36b.png</url>
      <title>DEV Community: MachineHunter</title>
      <link>https://dev.to/machinehunter</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/machinehunter"/>
    <language>en</language>
    <item>
      <title>How to Reverse UEFI modules (DXE Driver)</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Wed, 09 Nov 2022 16:27:36 +0000</pubDate>
      <link>https://dev.to/machinehunter/how-to-reverse-uefi-modules-dxe-driver-54fb</link>
      <guid>https://dev.to/machinehunter/how-to-reverse-uefi-modules-dxe-driver-54fb</guid>
      <description>&lt;p&gt;Unlike executables running above OS, UEFI modules doesn't have import functions or systemcalls which is usually the important factor in reverse engineering. Therefore, things to focus on when reversing UEFI modules and executables above OS are quite different.&lt;br&gt;
In this post, I'll explain what factors am I focusing on when reversing UEFI modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;The important factors, which I think should be focused on are below.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;UEFI Services&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UEFI Protocols&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Register and those IO types info of devices&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;UEFI Services and Protocols are the most valuable information&lt;/strong&gt; (just like Windows API and system call when reversing above OS executables) and this can be auto-analyzed by plugins of decompilers such as Ghidra and IDA. Therefore, I'll mostly focus around device-specific register here. &lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Setup
&lt;/h2&gt;

&lt;p&gt;UEFI Services and Protocols can be auto-analyzed by below plugins. &lt;strong&gt;I'll be using Ghidra+efiseek&lt;/strong&gt; in this post.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/DSecurity/efiSeek" rel="noopener noreferrer"&gt;efiseek&lt;/a&gt; (for Ghidra)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/binarly-io/efiXplorer" rel="noopener noreferrer"&gt;efiXplorer&lt;/a&gt; (for IDA Pro)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  UEFI Services
&lt;/h2&gt;

&lt;p&gt;While Protocols are mostly for accessing devices' functionality, UEFI Services are for offering more general functionality. Therefore, if you want to reverse &lt;strong&gt;malware&lt;/strong&gt; that infect boot chains or &lt;strong&gt;UEFI applications&lt;/strong&gt; (not DXE drivers or the modules before DXE), UEFI Services are the most important factor to focus on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entrypoint of UEFI modules
&lt;/h3&gt;

&lt;p&gt;Most UEFI modules derives EFI_SYSTEM_TABLE as a second parameter of entrypoint.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="n"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;UEFI Services can be accessed from this EFI_SYSTEM_TABLE.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SystemTable-&amp;gt;BootServices&lt;/li&gt;
&lt;li&gt;SystemTable-&amp;gt;RuntimeServices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most cases, these BootServices and RuntimeServices are stored in a global variable like below. (When developing UEFI modules in EDK2, people mostly include &lt;code&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/code&gt; and these offeres &lt;code&gt;gBS&lt;/code&gt; and &lt;code&gt;gRT&lt;/code&gt;)&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jf5ym8fjrzsk9m28c03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jf5ym8fjrzsk9m28c03.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
You also can see HOBs and DXE Service Tables are stored in global variables &lt;code&gt;DAT_8000f120&lt;/code&gt; and &lt;code&gt;DAT_8000f128&lt;/code&gt;. These can be seen in DXE driver's entrypoint. Main function is the function that has the above feature (refer ghidra comment).&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing UEFI Services
&lt;/h3&gt;

&lt;p&gt;For this, just google the UEFI Service you want to analyze and rename arguments. In this post, I'll just explain below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Memory Allocation (AllocatePool, AllocatePages)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Protocol (LocateProtocol, InstallMultipleProtocolInterfaces)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events (CreateEvent, CreateEventEx, RegisterProtocolNotify)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll explain Protocol in the Protocol section so I'm going to explain the other two.&lt;/p&gt;

&lt;h4&gt;
  
  
  Memory Allocation
&lt;/h4&gt;

&lt;p&gt;This is like UEFI version of heap allocation.&lt;br&gt;
In UEFI, memory is seperated into several regions and these can be referenced by &lt;code&gt;gBS-&amp;gt;GetMemoryMap&lt;/code&gt;. You can specify where in this region to allocate by &lt;a href="https://dox.ipxe.org/UefiMultiPhase_8h.html#a0e2cdd0290e753cca604d3977cbe8bb9" rel="noopener noreferrer"&gt;EFI_MEMORY_TYPE&lt;/a&gt; argument of below function.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gBS-&amp;gt;AllocatePool (for small 8B aligned buffer)&lt;/li&gt;
&lt;li&gt;gBS-&amp;gt;AllocatePages (for large 4KB aligned buffer)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Events
&lt;/h4&gt;

&lt;p&gt;UEFI Events are created by these 2 BootServices.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#a136cb7690540176a224528745133f019" rel="noopener noreferrer"&gt;gBS-&amp;gt;CreateEvent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#a78fd81bb75ad0d912af92ecae5ae968d" rel="noopener noreferrer"&gt;gBS-&amp;gt;CreateEventEx&lt;/a&gt; (Ex can specify event groups named by GUID)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For both functions, &lt;strong&gt;it will execute the 3rd argument (EFI_EVENT_NOTIFY) function when the events specified by last &lt;br&gt;
argument (EFI_EVENT) is signaled&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;There are actually 2 types of event &lt;code&gt;EVT_NOTIFY_SIGNAL(0x200)&lt;/code&gt; and &lt;code&gt;EVT_NOTIFY_WAIT(0x100)&lt;/code&gt; which can be specified in the 1st argument. The way of signaling the event differs among this argument as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EVT_NOTIFY_SIGNAL(0x200): &lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#aa3ff2b58c5fcbf0d37c87d336d1475e1" rel="noopener noreferrer"&gt;gBS-&amp;gt;SignalEvent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;EVT_NOTIFY_WAIT(0x100): &lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#adf8e6c79edb3a20647fc489d22e329a2" rel="noopener noreferrer"&gt;gBS-&amp;gt;CheckEvent&lt;/a&gt;, &lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#aaba96f688dc14bb2154ce5aceb793493" rel="noopener noreferrer"&gt;gBS-&amp;gt;WaitForEvent&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But mostly in DXE drivers, you'll see &lt;code&gt;gBS-&amp;gt;RegisterProtocolNotify&lt;/code&gt; used as a set with &lt;code&gt;gBS-&amp;gt;CreateEvent&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuiku91lyer8u27uv3nm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiuiku91lyer8u27uv3nm.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#afd363625c194ad93f8786cee87a877f7" rel="noopener noreferrer"&gt;gBS-&amp;gt;RegisterProtocolNotify&lt;/a&gt; is a function that signals 2nd argument (EFI_EVENT) when protocol specified with the 1st argument (EFI_GUID) is installed&lt;/strong&gt;. &lt;br&gt;
More detailed information about UEFI Events can be found &lt;a href="https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/5_uefi_services/51_services_that_uefi_drivers_commonly_use/515_event_services" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  UEFI Protocols
&lt;/h2&gt;

&lt;p&gt;If you want to analyze some device specific functions or DXE driver, the most important factor is UEFI Protocol.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing Protocol's function usage
&lt;/h3&gt;

&lt;p&gt;If you want to see the use of Protocol's function, you can search by the GUID of protocol, and use xref to find &lt;code&gt;gBS-&amp;gt;LocateProtocol&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug3dqm1fsq52pioxrpo0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug3dqm1fsq52pioxrpo0.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Then the handle of that protocol is stored in the last argument of LocateProtocol, so you can see if any function call is made like &lt;code&gt;handleOfProtocol[offset](args...)&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing Protocol's functions
&lt;/h3&gt;

&lt;p&gt;If you want to analyze specific function of a protocol, you first have to look for the &lt;strong&gt;installation of that protocol&lt;/strong&gt;. This can be done by searching binary with protocol's GUID and refer to that xref to find the &lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#a83a71b62d2e3a933d91031e98741aeca" rel="noopener noreferrer"&gt;gBS-&amp;gt;InstallProtocolInterface&lt;/a&gt; or &lt;a href="https://dox.ipxe.org/UefiSpec_8h.html#a8f07efa92b97aba461dd125c132214c3" rel="noopener noreferrer"&gt;gBS-&amp;gt;InstallMultipleProtocolInterfaces&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In most cases, you can find a list of protocols that the DXE driver produces by looking for &lt;code&gt;InstallMultipleProtocolInterfaces&lt;/code&gt; called mostly in the driver's entrypoint.&lt;/p&gt;

&lt;p&gt;For example, if we have below lines, it means,&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj58t2f4d9mcuzmkbw7t5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj58t2f4d9mcuzmkbw7t5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DAT_80000518: function list of EFI_TREE_PROTOCOL&lt;/li&gt;
&lt;li&gt;DAT_80000550: function list of Protocol that has GUID in DAT_800003f0&lt;/li&gt;
&lt;li&gt;DAT_80000560: function list of Protocol that has GUID in DAT_80000400&lt;/li&gt;
&lt;li&gt;DAT_80000590: function list of EFI_TCG_PRIVATE_INTERFACE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Actually, efiseek is a bit old. It's not TreeProtocol which is for TPM1.2 but it's Tcg2Protocol for TPM2.0)&lt;/p&gt;

&lt;p&gt;So, if we want to analyze this &lt;code&gt;SubmitCommand&lt;/code&gt; of Tcg2Protocol,&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgx4d0wluzsu7q8yszbj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgx4d0wluzsu7q8yszbj.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
you have to look at below's address &lt;code&gt;0x800034CC&lt;/code&gt;.&lt;br&gt;
(My Ghidra's ImageBase is &lt;code&gt;0x80000000&lt;/code&gt;)&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27zr0g0zmkf4c2pdwqk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27zr0g0zmkf4c2pdwqk0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, if you jump to that address, there will be the content of SubmitCommand as below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmftt64rqqc2ctlfu1re.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmftt64rqqc2ctlfu1re.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Register and those IO types info of devices
&lt;/h2&gt;

&lt;p&gt;When you want to see the actual interaction with the device, you first need to know what kind of &lt;strong&gt;register&lt;/strong&gt; does that device has, and how can we access to that register (the &lt;strong&gt;IO type&lt;/strong&gt;).&lt;br&gt;
As an example, I will use TPM and analyze the above SubmitCommand function (Tcg2Protocol's function).&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowing Device's registers
&lt;/h3&gt;

&lt;p&gt;You have to refer to that device's specification for this (though, some devices specify the way to IO in their spec). For TPM, the list of registers are defined in &lt;a href="https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p05p_r14_pub.pdf#page=47" rel="noopener noreferrer"&gt;here (PTP spec)&lt;/a&gt;.&lt;br&gt;
(There are FIFO and CRB columns but you can ignore CRB)&lt;/p&gt;

&lt;p&gt;Each register's explanaitions are written in the following page of the link above. There are tons of registers so you can refer to this when you actually see the access to that register.&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowing Device's IO types
&lt;/h3&gt;

&lt;p&gt;For this, you actually have to see the platform (SoC) specification not the device's specification. Because the "connection" between device and the cpu is defined in SoC like below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5tc9x1d8oti2berbk31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5tc9x1d8oti2berbk31.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
(This is from "Intel® Pentium® and Celeron® Processor N- and J- Series Datasheet")&lt;/p&gt;

&lt;p&gt;In this SoC specification, the IO of every device is listed like below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5w95ud0vp8lj54odxa4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5w95ud0vp8lj54odxa4.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
We can see here that, TPM's IO type is &lt;strong&gt;MMIO (Memory Mapped IO)&lt;/strong&gt;.  MMIO is an IO that maps device's register to the specific memory range, so that you can read/write register values by read/write to that memory address.&lt;/p&gt;

&lt;p&gt;We also can see from the specification that the TPM is mapped to the memory address &lt;code&gt;0xFED40000&lt;/code&gt; (We have 2 TPM in the spec but ignore the &lt;code&gt;0xFED41000&lt;/code&gt; one).&lt;/p&gt;

&lt;h3&gt;
  
  
  Reversing SubmitCommand
&lt;/h3&gt;

&lt;p&gt;Now we know that the TPM's register is mapped to &lt;code&gt;0xFED40000&lt;/code&gt; and we know where to look at for each register's definition. Then you can reverse the function below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feu0hk1awhfl9wxevqsee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feu0hk1awhfl9wxevqsee.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
We see the exact same address above. Let's see inside &lt;code&gt;FUN_8000d1bc&lt;/code&gt; to see how this address specified in the first argument is used.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds01lb0s1cz340a35baz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds01lb0s1cz340a35baz.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
We can see a lots of &lt;code&gt;*TpmMmioBase &amp;amp; 0x20&lt;/code&gt; here. &lt;code&gt;*TpmMmioBase&lt;/code&gt; means it's referring the first content of the mapped register so let's look at the PTP spec to find out this register.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52lvtjxz562ehm56453a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52lvtjxz562ehm56453a.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
It's &lt;code&gt;TPM_ACCESS_0&lt;/code&gt; so &lt;code&gt;*TpmMmioBase &amp;amp; 0x20&lt;/code&gt; is equivalent to &lt;code&gt;TpmMmioBase-&amp;gt;TPM_ACCESS_0 &amp;amp; 0x20&lt;/code&gt;. &lt;code&gt;0x20 = 0b00100000&lt;/code&gt; so it's checking the 6th bit of TPM_ACCESS_0 register is set or not.&lt;br&gt;
Therefore, let's look at the 6th bit of TPM_ACCESS_0 register in the same spec.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd34u93yqzz1tbns44970.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd34u93yqzz1tbns44970.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Now We can see that it's checking if this &lt;code&gt;activeLocality&lt;/code&gt; is set or not.&lt;/p&gt;

&lt;p&gt;You can create struct refering to the spec to make decompile more readable. As an example, it will get clean like this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Before
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx34xv15gqk8quwyvzz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frx34xv15gqk8quwyvzz5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  After
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91ghv7epogct53wba91r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91ghv7epogct53wba91r.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(By the way, EFI_STATUS values can be found referring &lt;a href="https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Uefi/UefiBaseType.h#L110" rel="noopener noreferrer"&gt;UefiBaseType.h&lt;/a&gt; and &lt;a href="https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Base.h#L962-L1165" rel="noopener noreferrer"&gt;Base.h&lt;/a&gt; of EDK2.)&lt;/p&gt;

</description>
      <category>uefi</category>
      <category>dxe</category>
      <category>tpm</category>
      <category>ghidra</category>
    </item>
    <item>
      <title>How to make custom UEFI Protocol</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Sun, 31 Jul 2022 09:13:02 +0000</pubDate>
      <link>https://dev.to/machinehunter/how-to-make-custom-uefi-protocol-3ikp</link>
      <guid>https://dev.to/machinehunter/how-to-make-custom-uefi-protocol-3ikp</guid>
      <description>&lt;p&gt;DXE Driver's main task is to create and install Protocols. In this post, I will explain how to create Protocol in EDK2 and how to use that protocol from other UEFI module.&lt;/p&gt;

&lt;h2&gt;
  
  
  UEFI Protocol Explanation
&lt;/h2&gt;

&lt;p&gt;DXE Driver abstract the access to the device by creating &lt;strong&gt;Protocols&lt;/strong&gt;. For example, you can use Tcg2Protocol to access TPM2.0 functionality rather than accessing it via things like MMIO or Port IO. Protocols are &lt;strong&gt;data structures containing function pointers&lt;/strong&gt; and the actual function's contents are in the DXE Driver which installed that Protocol. The Protocol (data structure) itself is also in that DXE Driver (usually in .data section).&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq0jh93g1a4qzcxgy7gzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq0jh93g1a4qzcxgy7gzl.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
(Image from &lt;a href="https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles/362_protocol_interface_structure" rel="noopener noreferrer"&gt;EDK2 UEFI Driver Writer's Guide 3.6.2&lt;/a&gt;) &lt;/p&gt;

&lt;p&gt;Each Protocol has its own GUID and this is used for other UEFI modules to locate this Protocol. Several Protocols can be grouped and this group is identified by Handle. Therefore, you can use &lt;code&gt;gBS-&amp;gt;LocateHandle&lt;/code&gt; first to locate Handle and then locate the Protocol inside. However, it might be more simpler to use &lt;code&gt;gBS-&amp;gt;LocateProtocol&lt;/code&gt; to locate Protocol by GUID directly.&lt;/p&gt;

&lt;p&gt;Protocols are stored into a single database because it has to be accessible via any UEFI modules. In order to store the protocol to this database, the DXE Driver which create the protocol has to use &lt;code&gt;gBS-&amp;gt;InstallMultipleProtocolInterfaces&lt;/code&gt; inside.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  MyDxe2.inf
&lt;/h3&gt;

&lt;p&gt;Let's start with the inf file. The main point is to write &lt;code&gt;gEfiDummyProtocol&lt;/code&gt; to the &lt;code&gt;[Protocols]&lt;/code&gt;. We have to write the Protocols this DXE Driver produce and also consume.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;[Defines]&lt;br&gt;
  INF_VERSION                    = 0x00010006&lt;br&gt;
  BASE_NAME                      = MyDxe2&lt;br&gt;
  FILE_GUID                      = 9d46dccd-ea11-4808-93e9-9b7021889b2d&lt;br&gt;
  MODULE_TYPE                    = DXE_DRIVER&lt;br&gt;
  VERSION_STRING                 = 1.0&lt;br&gt;
  ENTRY_POINT                    = MyDxeEntry&lt;/p&gt;

&lt;p&gt;[Sources]&lt;br&gt;
    MyDxe2.h&lt;br&gt;
    MyDxe2.c&lt;/p&gt;

&lt;p&gt;[Packages]&lt;br&gt;
    MdePkg/MdePkg.dec&lt;br&gt;
    MdeModulePkg/MdeModulePkg.dec&lt;/p&gt;

&lt;p&gt;[LibraryClasses]&lt;br&gt;
    UefiDriverEntryPoint&lt;br&gt;
    UefiRuntimeServicesTableLib&lt;br&gt;
    UefiBootServicesTableLib&lt;br&gt;
    UefiLib&lt;br&gt;
    PrintLib&lt;/p&gt;

&lt;p&gt;[Protocols]&lt;br&gt;
    gEfiDummyProtocolGuid   ## PRODUCES&lt;/p&gt;

&lt;p&gt;[Depex]&lt;br&gt;
    TRUE&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  MyDxe2.h&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;This is the header file. This mainly defines &lt;em&gt;types&lt;/em&gt; like &lt;code&gt;EFI_DUMMY_PROTOCOL&lt;/code&gt; or &lt;code&gt;DUMMY_FUNC1&lt;/code&gt;, so that you can use it in MyDxe2.c. Definition of &lt;code&gt;gEfiDummyProtocolGuid&lt;/code&gt; will be defined in the separate place.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/PrintLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiDriverEntryPoint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;br&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="o"&gt;&lt;em&gt;&lt;/em&gt;&lt;/span&gt;&lt;span class="n"&gt;DUMMY_FUNC1&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="nf"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="o"&gt;&lt;/span&gt;&lt;span class="n"&gt;DUMMY_FUNC2&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c1"&gt;// e9811f61-14bd-4637-8d17-aec540d8f508&lt;/span&gt;&lt;br&gt;
&lt;span class="cp"&gt;#define EFI_DUMMY_PROTOCOL_GUID \&lt;br&gt;
    { 0xe9811f61, 0x14bd, 0x4637, { 0x8d, 0x17, 0xae, 0xc5, 0x40, 0xd8, 0xf5, 0x08 } }&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="n"&gt;EFI_GUID&lt;/span&gt; &lt;span class="n"&gt;gEfiDummyProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;_EFI_DUMMY_PROTOCOL&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;DUMMY_FUNC1&lt;/span&gt; &lt;span class="n"&gt;DummyFunc1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;DUMMY_FUNC2&lt;/span&gt; &lt;span class="n"&gt;DummyFunc2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;EFI_DUMMY_PROTOCOL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  MyDxe2.c&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;This is the DXE Driver's contents. &lt;code&gt;mDummy&lt;/code&gt; is the actual data structure of this Protocol and this Protocol is installed by &lt;code&gt;gBS-&amp;gt;InstallMultipleProtocolInterfaces&lt;/code&gt;. The content of &lt;code&gt;DummyFunc1&lt;/code&gt; and &lt;code&gt;DummyFunc2&lt;/code&gt; can be any, but in this example, I'm storing the message "DummyFuncN called" in UEFI variable called &lt;code&gt;MyDxeStatus&lt;/code&gt;, so that, you can check if the Protocols is really running correctly.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"MyDxe2.h"&lt;/span&gt;&lt;span class="cp"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;myvarSize&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;CHAR8&lt;/span&gt;  &lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;CHAR16&lt;/span&gt; &lt;span class="n"&gt;myvarName&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;L"MyDxeStatus"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c1"&gt;// eefbd379-9f5c-4a92-a157-ae4079eb1448&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;EFI_GUID&lt;/span&gt; &lt;span class="n"&gt;myvarGUID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xeefbd379&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x9f5c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x4a92&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0xa1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x57&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xae&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x79&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xeb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x48&lt;/span&gt; &lt;span class="p"&gt;}};&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;mDummyHandle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;DummyFunc1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;AsciiSPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DummyFunc1 called"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;myvarName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;myvarGUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;myvarSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;DummyFunc2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;AsciiSPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DummyFunc2 called"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;myvarName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;myvarGUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;myvarSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
            &lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;EFI_DUMMY_PROTOCOL&lt;/span&gt; &lt;span class="n"&gt;mDummy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;DummyFunc1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;DummyFunc2&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;};&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;MyDxeEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;gBS&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;InstallMultipleProtocolInterfaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mDummyHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiDummyProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mDummy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;EFI_TIME&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;time&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;gRT&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;GetTime&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;time&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="nb"&amp;gt;NULL&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;AsciiSPrint&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mi"&amp;gt;12&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="s"&amp;gt;"%2d/%2d %2d:%2d"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;time&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;Month&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;time&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;Day&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;time&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;Hour&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;time&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;.&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;Minute&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class="n"&amp;gt;gRT&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;SetVariable&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;
        &amp;lt;span class="n"&amp;gt;myvarName&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;myvarGUID&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="n"&amp;gt;EFI_VARIABLE_NON_VOLATILE&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;|&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;|&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;EFI_VARIABLE_RUNTIME_ACCESS&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="n"&amp;gt;myvarSize&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class="k"&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;EFI_SUCCESS&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  MdeModulePkg.dec&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;We should define &lt;code&gt;gEfiDummyProtocolGuid&lt;/code&gt; to MdeModulePkg.dec in order to use &lt;code&gt;gEfiDummyProtocolGuid&lt;/code&gt; in the other UEFI module. Inside MdeModulePkg.dec, add the definition like below.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;[Protocols]&lt;br&gt;
...&lt;br&gt;
  ## MyDxe/MyDxe2.h&lt;br&gt;
  gEfiDummyProtocolGuid = { 0xe9811f61, 0x14bd, 0x4637, { 0x8d, 0x17, 0xae, 0xc5, 0x40, 0xd8, 0xf5, 0x08 } }&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  MdeModulePkg.dsc&lt;br&gt;
&lt;/h3&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;[Components]&lt;br&gt;
  MdeModulePkg/MyDxe/MyDxe2.inf&lt;br&gt;
  ...&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Build it&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Make sure you have &lt;code&gt;ACTIVE_PLATFORM = MdeModulePkg/MdeModulePkg.dsc&lt;/code&gt; in &lt;code&gt;Conf/target.txt&lt;/code&gt; and let's build it. Then, construct FFS file like I explained in the &lt;a href="https://dev.to/machinehunter/how-to-build-dxe-driver-by-edk2-11h8"&gt;previous post&lt;/a&gt;, add the FFS file to the BIOS image, and flash the SPI flash chip with that image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using DummyProtocol
&lt;/h2&gt;

&lt;p&gt;Next, let's write a module that uses this Protocol. I will be writing a UEFI module that runs from a USB memory in BDS phase, so that I can print the output to the screen easily.&lt;br&gt;
Create a folder named &lt;code&gt;AppPkg/&lt;/code&gt; under &lt;code&gt;edk2/&lt;/code&gt; and will be creating these files.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;AppPkg/&lt;br&gt;
├── AppPkg.dec&lt;br&gt;
├── AppPkg.dsc&lt;br&gt;
└── Applications/&lt;br&gt;
    └── UseDummyProtocol/&lt;br&gt;
        ├── UseDummyProtocol.c&lt;br&gt;
        └── UseDummyProtocol.inf&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  AppPkg.dec&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;FirstPkg&lt;/code&gt; can be any name.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;[Defines]&lt;br&gt;
  DEC_SPECIFICATION              = 0x00010005&lt;br&gt;
  PACKAGE_NAME                   = FirstPkg&lt;br&gt;
  PACKAGE_GUID                   = 75281f80-8657-4cf2-837f-04d73179c590&lt;br&gt;
  PACKAGE_VERSION                = 0.1&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  AppPkg.dsc&lt;br&gt;
&lt;/h3&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;[Defines]&lt;br&gt;
  PLATFORM_NAME                  = FirstPkg&lt;br&gt;
  PLATFORM_GUID                  = 7b86cb02-9fbb-4f77-8d93-35c8c90f2488&lt;br&gt;
  PLATFORM_VERSION               = 0.1&lt;br&gt;
  DSC_SPECIFICATION              = 0x00010005&lt;br&gt;
  OUTPUT_DIRECTORY               = Build/FirstPkg$(ARCH)&lt;br&gt;
  SUPPORTED_ARCHITECTURES        = IA32|X64&lt;br&gt;
  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT&lt;br&gt;
  DEFINE DEBUG_ENABLE_OUTPUT     = TRUE&lt;/p&gt;

&lt;p&gt;[LibraryClasses]&lt;br&gt;
  # Entry point&lt;br&gt;
  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf&lt;br&gt;
  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf&lt;/p&gt;

&lt;p&gt;# Common Libraries&lt;br&gt;
  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf&lt;br&gt;
  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf&lt;br&gt;
  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf&lt;br&gt;
  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf&lt;br&gt;
  !if $(DEBUG_ENABLE_OUTPUT)&lt;br&gt;
    DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf&lt;br&gt;
    DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf&lt;br&gt;
  !else   ## DEBUG_ENABLE_OUTPUT&lt;br&gt;
    DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf&lt;br&gt;
  !endif  ## DEBUG_ENABLE_OUTPUT&lt;/p&gt;

&lt;p&gt;UefiLib|MdePkg/Library/UefiLib/UefiLib.inf&lt;br&gt;
  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf&lt;br&gt;
  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf&lt;br&gt;
  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf&lt;br&gt;
  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf&lt;br&gt;
  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf&lt;br&gt;
  RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf&lt;/p&gt;

&lt;p&gt;[Components]&lt;br&gt;
  AppPkg/Applications/UseDummyProtocol/UseDummyProtocol.inf&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  UseDummyProtocol.inf&lt;br&gt;
&lt;/h3&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;[Defines]&lt;br&gt;
  INF_VERSION                    = 0x00010006&lt;br&gt;
  BASE_NAME                      = UseDummyProtocol&lt;br&gt;
  FILE_GUID                      = 5765e8dd-c97a-4ce2-891e-9e24b94d654b&lt;br&gt;
  MODULE_TYPE                    = UEFI_APPLICATION&lt;br&gt;
  VERSION_STRING                 = 0.1&lt;br&gt;
  ENTRY_POINT                    = UefiMain&lt;/p&gt;

&lt;p&gt;[Sources]&lt;br&gt;
  UseDummyProtocol.c&lt;/p&gt;

&lt;p&gt;[Packages]&lt;br&gt;
  MdePkg/MdePkg.dec&lt;br&gt;
  MdeModulePkg/MdeModulePkg.dec&lt;/p&gt;

&lt;p&gt;[LibraryClasses]&lt;br&gt;
  UefiLib&lt;br&gt;
  ShellCEntryLib&lt;br&gt;
  UefiBootServicesTableLib&lt;br&gt;
  UefiRuntimeServicesTableLib&lt;/p&gt;

&lt;p&gt;[Protocols]&lt;br&gt;
  gEfiDummyProtocolGuid  ## CONSUME&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  UseDummyProtocol.c&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;This is checking UEFI variable &lt;code&gt;MyDxeStatus&lt;/code&gt; by &lt;code&gt;GetVariable&lt;/code&gt; before and after calling &lt;code&gt;DummyFunc1&lt;/code&gt; (the DummyProtocol's function). &lt;code&gt;DummyFunc1&lt;/code&gt; will change the value of &lt;code&gt;MyDxeStatus&lt;/code&gt; to a &lt;code&gt;DummyFunc1 called&lt;/code&gt; which was originally the current time set when this DXE Driver was executed.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;MyDxe/MyDxe2.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;
&lt;h1&gt;
  
  
  include &lt;span class="cpf"&gt;&amp;lt;Library/BaseMemoryLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;br&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;&lt;em&gt;&lt;/em&gt;&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;EFI_DUMMY_PROTOCOL&lt;/span&gt; &lt;span class="o"&gt;&lt;/span&gt;&lt;span class="n"&gt;DummyProtocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;gBS&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;LocateProtocol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiDummyProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOID&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;DummyProtocol&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="n"&amp;gt;CHAR8&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;[&amp;lt;/span&amp;gt;&amp;lt;span class="mi"&amp;gt;30&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;];&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;UINT64&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;myvarSize&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="mi"&amp;gt;30&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;UINT32&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;Attributes&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;EFI_VARIABLE_NON_VOLATILE&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;|&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;|&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;EFI_VARIABLE_RUNTIME_ACCESS&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;EFI_GUID&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;myvarGUID&amp;lt;/span&amp;gt; &amp;lt;span class="o"&amp;gt;=&amp;lt;/span&amp;gt; &amp;lt;span class="p"&amp;gt;{&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0xeefbd379&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x9f5c&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x4a92&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="p"&amp;gt;{&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0xa1&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x57&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0xae&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x40&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x79&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0xeb&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x14&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="mh"&amp;gt;0x48&amp;lt;/span&amp;gt; &amp;lt;span class="p"&amp;gt;}};&amp;lt;/span&amp;gt;

&amp;lt;span class="n"&amp;gt;Print&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;L"[Before Calling Protocol] MyDxeStatus:&amp;lt;/span&amp;gt;&amp;lt;span class="se"&amp;gt;\r\n&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;gRT&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;GetVariable&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;L"MyDxeStatus"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;myvarGUID&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;Attributes&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;myvarSize&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class="n"&amp;gt;AsciiPrint&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"%a&amp;lt;/span&amp;gt;&amp;lt;span class="se"&amp;gt;\n\n&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class="n"&amp;gt;DummyProtocol&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;DummyFunc1&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;();&amp;lt;/span&amp;gt;

&amp;lt;span class="n"&amp;gt;Print&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;L"[After Calling Protocol] MyDxeStatus:&amp;lt;/span&amp;gt;&amp;lt;span class="se"&amp;gt;\r\n&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class="n"&amp;gt;gRT&amp;lt;/span&amp;gt;&amp;lt;span class="o"&amp;gt;-&amp;amp;gt;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;GetVariable&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;
        &amp;lt;span class="s"&amp;gt;L"MyDxeStatus"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;myvarGUID&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;Attributes&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="o"&amp;gt;&amp;amp;amp;&amp;lt;/span&amp;gt;&amp;lt;span class="n"&amp;gt;myvarSize&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt;
        &amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class="n"&amp;gt;AsciiPrint&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"%a&amp;lt;/span&amp;gt;&amp;lt;span class="se"&amp;gt;\n&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;"&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;,&amp;lt;/span&amp;gt; &amp;lt;span class="n"&amp;gt;myvarValue&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;

&amp;lt;span class="k"&amp;gt;while&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;(&amp;lt;/span&amp;gt;&amp;lt;span class="mi"&amp;gt;1&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;);&amp;lt;/span&amp;gt;
&amp;lt;span class="k"&amp;gt;return&amp;lt;/span&amp;gt; &amp;lt;span class="mi"&amp;gt;0&amp;lt;/span&amp;gt;&amp;lt;span class="p"&amp;gt;;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Build and Execute it&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Before build, change to &lt;code&gt;ACTIVE_PLATFORM = AppPkg/AppPkg.dsc&lt;/code&gt; in the &lt;code&gt;Conf/target.txt&lt;/code&gt;. Then, build it.&lt;br&gt;
This time, I will store the generated UseDummyProtocol.efi to the USB memory. In USB memory, make a directory &lt;code&gt;EFI/BOOT/&lt;/code&gt; and rename UseDummyProtocol.efi into bootx64.efi and put that into the folder.&lt;/p&gt;

&lt;p&gt;Plug the USB into the PC you flashed the BIOS before, and boot that machine. If you see below output, then it's a success.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxd1kxhi05m673pd9qzaz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxd1kxhi05m673pd9qzaz.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
(I missed specifing the string length...)&lt;/p&gt;

</description>
      <category>uefi</category>
      <category>dxe</category>
      <category>edk2</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using Intel DCI on ISS to debug UEFI module</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Tue, 26 Jul 2022 11:09:51 +0000</pubDate>
      <link>https://dev.to/machinehunter/using-intel-dci-on-iss-to-debug-uefi-module-l6o</link>
      <guid>https://dev.to/machinehunter/using-intel-dci-on-iss-to-debug-uefi-module-l6o</guid>
      <description>&lt;p&gt;In the previous post, I explained what is Intel DCI and how to setup Intel System Debugger (ISS). In this post, I'll explain how to use ISS to debug UEFI modules. Usage is not really different from other debugger, but it's good to see examples to get the image what it is like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking at target UEFI module
&lt;/h2&gt;

&lt;p&gt;First of all, there are lots of UEFI modules running in the bootphase. Considering this, the easiest way to break at the UEFI module you want to debug is to &lt;strong&gt;put dead-loop at the top of the module&lt;/strong&gt;. You can just put &lt;code&gt;EB FE&lt;/code&gt; at the place you want to break and the execution will stop there. Then, you can use "Move To Line" to exit dead-loop.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljzxffn893mudnxef3qm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljzxffn893mudnxef3qm.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Unstable DCI Problem
&lt;/h2&gt;

&lt;p&gt;In some platform or BIOS, DCI maybe unstable. For example, if you suspend the machine, put breakpoint somewhere and resume, then the ISS will say that the system is already running. Also there might be cases, DCI connection resets repeatedly. Several reasons for unstable DCI connection are stated in the Intel System Debugger manual's "Limitation of JTAG Debugging" section which can be found at &lt;code&gt;IntelSWTools/system_studio_2020/documentation_2020/en/debugger/system_studio_2020/system_debugger/system_debug/User_Guide.pdf&lt;/code&gt;. But I think most of the cases is because of &lt;strong&gt;WatchDog Timers (WDT)&lt;/strong&gt;. This timer checks platform's "heartbeat" condition, and if the "heartbeat" is stopped, platform will reset. Debugger stops execution so WDT will think something went wrong and makes platform resets, which closes the DCI connection. Therefore, you might want to &lt;strong&gt;disable WDT&lt;/strong&gt; if your DCI connection is unstable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Preparing desired window in ISS
&lt;/h2&gt;

&lt;p&gt;You can get your desired window here.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvv9jengvcphg29rg4ef4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvv9jengvcphg29rg4ef4.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Connect/Disconnect/Resume/Suspend/Reset/Debug
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1bzgmx3g2jfwc5b6nap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1bzgmx3g2jfwc5b6nap.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Breakpoints
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Software Breakpoint
&lt;/h3&gt;

&lt;p&gt;You can just double click the narrow space next to the address you want to set a software BP like below (the red square). You can see the list of BPs in the Breakpoints window.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbj2pxkf3m4enqrutqai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbj2pxkf3m4enqrutqai.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Hardware Breakpoint
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvp9kth9uqo63ka3i6z26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvp9kth9uqo63ka3i6z26.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory Breakpoint (Watchpoint)
&lt;/h3&gt;

&lt;p&gt;There are no such thing called &lt;em&gt;Memory Breakpoint&lt;/em&gt; in ISS, but you can use ISS's special BP called Watchpoint to do similar thing. To add Watchpoint, press the below red squared button.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmeocnq7epimvx2sn22o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmeocnq7epimvx2sn22o.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
If you want to break when there was a write on the address &lt;code&gt;0xcafebabe&lt;/code&gt;, you can set it like below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu0z6r935h7db6hhxlpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu0z6r935h7db6hhxlpo.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, you can also use Watchpoint to break on read, and also specify address with range.&lt;/p&gt;
&lt;h2&gt;
  
  
  Modifing Registers
&lt;/h2&gt;

&lt;p&gt;You can just double click to change value like this in the Registers window.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s24phjznkqc5rzfv5mm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s24phjznkqc5rzfv5mm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Memory Browser (Hex View)
&lt;/h2&gt;

&lt;p&gt;You can use Memory Browser window to check hex view around specified address.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q2gepg71nqbvtdzbux2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q2gepg71nqbvtdzbux2.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
You can change the cell size like below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbl87zvne9jl71qprnwgm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbl87zvne9jl71qprnwgm.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
I couldn't find Stack view in ISS, but you can put rsp value in this Memory Browser to see the stack instead.&lt;/p&gt;
&lt;h2&gt;
  
  
  ISD Shell (Python Scripts)
&lt;/h2&gt;

&lt;p&gt;You can use ISD Shell to automate operations by python scripts. However, I couldn't find any documentation explaining about the API, so I refered the source code in &lt;code&gt;C:\IntelSWTools\system_studio_2020\tools\&lt;/code&gt; to find out objects or functions, and also used python functions like &lt;code&gt;dir(Object)&lt;/code&gt; to check what methods are in that object. I'll leave some of the codes that I used personally, just to get the image how the code will look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Writing value 1 to MSR 0x1d9
&lt;/span&gt;&lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;msr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x1d9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Setting 0x7764e7d7 to RIP
&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;registers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x7764e7d7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c1"&gt;# Resume
&lt;/span&gt;&lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;runcontrol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Trace
&lt;/h2&gt;

&lt;h3&gt;
  
  
  LBR Trace
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;LBR (Last Branch Record)&lt;/strong&gt; is a feature of Intel CPU to record branch trace to MSR. This is hardware mechanism and could be easily enabled by setting MSR &lt;code&gt;IA32_DEBUGCTL (0x1d9)&lt;/code&gt; to 1. &lt;a href="https://sorami-chi.hateblo.jp/entry/2017/12/17/230000" rel="noopener noreferrer"&gt;This article&lt;/a&gt; is a good reference to look at about LBR tracing. &lt;/p&gt;

&lt;p&gt;To use LBR Trace in ISS, open Instruction Trace View window, and click the red squared button.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsp0293pof4setkxzccxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsp0293pof4setkxzccxs.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Then, change the type to "LBR" and click OK.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5ha7y6zg00un8vdrecb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5ha7y6zg00un8vdrecb.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
After that, click below button to start capturing.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgbnhektgjdkmfszjdgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgbnhektgjdkmfszjdgn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's try it. Put some BP somewhere and press resume. After you hit the BP, you'll see the results shown like this.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fol7hjp96y0wfornsegvo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fol7hjp96y0wfornsegvo.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
You can maximize the view by clicking above button (Press "Restore" to go back to the original view). &lt;/p&gt;

&lt;h3&gt;
  
  
  Intel Processor Trace (Intel PT)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Intel PT&lt;/strong&gt; stores trace record to memory rather than MSR. Therefore, this could store far more record than LBR &lt;em&gt;at a time&lt;/em&gt;. But actually, it doesn't really matter because ISS can read LBR and keep the data in the memory of analysis machine.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;advantages&lt;/strong&gt; of using PT is that, PT allows you to configure the trace options more specifically. This is stated in &lt;em&gt;Intel® System Debugger - System Debug User and Reference Guide&lt;/em&gt;, but in my ISS, somehow there were no place to configure these options...&lt;br&gt;
The &lt;strong&gt;disadvantages&lt;/strong&gt; of using PT is that, since PT uses memory to store trace information, it's a bit troublesome to enable it (do below two).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;set MSR &lt;code&gt;IA32_RTIT_CTL (0x570)&lt;/code&gt; to 1&lt;/li&gt;
&lt;li&gt;enable PT in the BIOS SETUP screen and allocate enough size of memory you need&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use PT in ISS, you only have to select "PT" in this configuration window.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzupp4smbgdo677t4wurl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzupp4smbgdo677t4wurl.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

</description>
      <category>dci</category>
      <category>debug</category>
      <category>iss</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Reading PCR value from UEFI</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Mon, 25 Jul 2022 12:15:28 +0000</pubDate>
      <link>https://dev.to/machinehunter/reading-pcr-value-from-uefi-4a82</link>
      <guid>https://dev.to/machinehunter/reading-pcr-value-from-uefi-4a82</guid>
      <description>&lt;p&gt;PCR is one of the most-used TPM functionality in UEFI security. Measured boot which ensures integrity of UEFI firmware is a good example of the use of PCR. In this post, I will explain how to read PCR value from UEFI module.&lt;br&gt;
If you are not familiar with TPM programming from UEFI, it might be better to start with my &lt;a href="https://dev.to/machinehunter/series/18231"&gt;Accessing TPM2.0 from UEFI module Series&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  PCR explanaition
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PCRs (Platform Configuration Registers) in TPM holds measurements of software states&lt;/strong&gt;. UEFI uses this value to ensure if none of the code during the bootphase are modified. Value in PCR is actually a hash and this can only be updated by an operation called &lt;em&gt;extend&lt;/em&gt; (or system reset). Before executing the next program (e.g. DxeCore, bootloader), the caller &lt;em&gt;extend&lt;/em&gt; the PCR value by calculating &lt;code&gt;PCR[i] = H(PCR[i]||m)&lt;/code&gt;. &lt;code&gt;PCR[i]&lt;/code&gt; is the &lt;em&gt;i&lt;/em&gt; th PCR's value, &lt;code&gt;H()&lt;/code&gt; is the hash function and &lt;code&gt;m&lt;/code&gt; is the new measurement of the next program going to be executed.&lt;/p&gt;

&lt;p&gt;TPM allows you to &lt;strong&gt;control access towards entities depending on PCR value&lt;/strong&gt;. For example, if you want to have a key which is only accessible during specific part in the bootphase, you can authenticate the key with a policy which only allows reading operation when PCR has specific value.&lt;/p&gt;

&lt;p&gt;There are at least &lt;strong&gt;24 PCRs&lt;/strong&gt; on any platform. Each PCRs are meant to store different software's measurements, and typical example is like below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvug3dztteg0w9c69ihg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvug3dztteg0w9c69ihg.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
(Image from &lt;a href="https://ebrary.net/24779/computer_science/platform_configuration_registers" rel="noopener noreferrer"&gt;A Practical Guide to TPM 2.0&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The actual allocation depends on PC client, but in this post, I'll read the value of &lt;strong&gt;PCR[0]&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PCR bank&lt;/strong&gt; is a group of PCR with same hash algorithm. Simple example is like below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

PCR bank 0 (sha1)
  * PCR[0]: sha1 value
  * ...
  * PCR[23]: sha1 value

PCR bank 1 (sha256)
  * PCR[0]: sha256 value
  * ...
  * PCR[23]: sha256 value


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is to handle issues like compatibility for old application only using old hash, or new application restricting to use only strong hash. When extending PCR[i] value, TPM should extend each bank's PCR[i] if that PCR is present in bank. There are cases when PCR[i] is implemented in bank0 but not in bank1. I will be reading from PCR bank with &lt;strong&gt;sha256&lt;/strong&gt; hash.&lt;/p&gt;

&lt;p&gt;For further description of PCR, you can refer to &lt;a href="https://trustedcomputinggroup.org/resource/tpm-library-specification/" rel="noopener noreferrer"&gt;TCG spec&lt;/a&gt; part1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;I will be using &lt;a href="https://github.com/tianocore/edk2" rel="noopener noreferrer"&gt;EDK2&lt;/a&gt; to build the UEFI module. There are actually two ways to access PCR from UEFI.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using &lt;code&gt;Tcg2Protocol.GetActivePcrBanks&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;Tcg2Protocol.SubmitCommand&lt;/code&gt; to send &lt;code&gt;TPM2_PCR_Read&lt;/code&gt; command
I will be using 2 in this post.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  TPM2_PCR_Read format
&lt;/h3&gt;

&lt;p&gt;Looking at &lt;a href="https://trustedcomputinggroup.org/resource/tpm-library-specification/" rel="noopener noreferrer"&gt;TCG spec&lt;/a&gt; part3, you can check the command's format as follows.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hal3qu9hzcyciaz329v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hal3qu9hzcyciaz329v.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  TPML_PCR_SELECTION
&lt;/h4&gt;

&lt;p&gt;Structure's definition can be found at TCG spec part2, and the actual definition of the structure in EDK2 can be found in &lt;code&gt;MdePkg/Include/IndustryStandard/Tpm20.h&lt;/code&gt;. To summarize the &lt;code&gt;TPML_PCR_SELECTION&lt;/code&gt; structure, it is like follows.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

* [TPML_PCR_SELECTION] pcrSelectionIn/pcrSelectionOut
   * [UINT32]             count
   * [TPMS_PCR_SELECTION] pcrSelections[count] (max: HASH_COUNT)
      * [TPMI_ALG_HASH][TPM_ALG_ID][UINT16] hash
      * [UINT8]                             sizeofSelect (min: PCR_SELECT_MIN)
      * [BYTE]                              pcrSelect[sizeofSelect] (max: PCR_SELECT_MAX)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Below are the related constants.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="n"&gt;HASH_COUNT&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;PCR_SELECT_MIN&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;PLATFORM_PCR&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;PLATFORM_PCR&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;PCR_SELECT_MAX&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;IMPLEMENTATION_PCR&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;IMPLEMENTATION_PCR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;IMPLEMENTATION_PCR&lt;/code&gt; maybe the actual number of PCR in your PC client, and since EDK2 doesn't know it, you have to change it to the appropriate value. But since we're only accessing only PCR[0], it doesn't matter to keep it this way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each &lt;code&gt;pcrSelections&lt;/code&gt; specify PCR bank, and each bit in &lt;code&gt;pcrSelect&lt;/code&gt; specify PCR&lt;/strong&gt;. You might wonder why &lt;code&gt;PCR_SELECT_MIN&lt;/code&gt; and &lt;code&gt;PCR_SELECT_MAX&lt;/code&gt; are 3, but &lt;code&gt;BYTE&lt;/code&gt; is 8bit and &lt;code&gt;3*8=24&lt;/code&gt;, which means, each bit specifies the PCR index you want to read. So for example, if you want PCR[0] and PCR[10], you will set &lt;code&gt;pcrSelect&lt;/code&gt; for &lt;code&gt;pcrSelectIn&lt;/code&gt; like the following (Omitting SwapBytes for simplicity).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

pcrSelect[0] = 00000001 = 1
pcrSelect[1] = 00000100 = 4
pcrSelect[2] = 00000000 = 0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  TPML_DIGEST
&lt;/h4&gt;

&lt;p&gt;This is where you get the actual value of PCR specified in the &lt;code&gt;pcrSelectionIn&lt;/code&gt;. This structure is way simpler than &lt;code&gt;TPML_PCR_SELECTION&lt;/code&gt; because it is just a list of &lt;code&gt;digest&lt;/code&gt;. But, it might be confusing if you requested multiple PCR values: what value is in what index of digest. This order is actually noted in the description of &lt;code&gt;TPM2_PCR_Read&lt;/code&gt; in the spec.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;TPM will process the list of TPMS_PCR_SELECTION in pcrSelectionIn in order&lt;/li&gt;
&lt;li&gt;Within each
TPMS_PCR_SELECTION, the TPM will process the bits in the pcrSelect array in ascending PCR order&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Source code
&lt;/h3&gt;

&lt;p&gt;Here is the whole source code getting PCR[0] value from sha256 PCR bank.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Protocol/Tcg2Protocol.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;IndustryStandard/Tpm20.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack(1)
&lt;/span&gt;    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMS_PCR_SELECTION&lt;/span&gt; &lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;ORIG_TPML_PCR_SELECTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_COMMAND_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ORIG_TPML_PCR_SELECTION&lt;/span&gt; &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_PCR_READ_COMMAND&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_RESPONSE_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;pcrUpdateCounter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ORIG_TPML_PCR_SELECTION&lt;/span&gt; &lt;span class="n"&gt;pcrSelectionOut&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPML_DIGEST&lt;/span&gt; &lt;span class="n"&gt;pcrValues&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_PCR_READ_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack()
&lt;/span&gt;

&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;EFI_TCG2_PROTOCOL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;BootServices&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;LocateProtocol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiTcg2ProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOID&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;ORIG_TPML_PCR_SELECTION&lt;/span&gt; &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;                         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ALG_SHA256&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;sizeofSelect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PCR_SELECT_MIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PCR_SELECT_MIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;pcrSelect&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PLATFORM_PCR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;pcrSelect&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pcrId&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="n"&gt;TPM2_PCR_READ_COMMAND&lt;/span&gt; &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;TPM2_PCR_READ_RESPONSE&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ST_NO_SESSIONS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commandCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CC_PCR_Read&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelectionIn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"sending TPM command...&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SubmitCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"SubmitCommand Success!&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"stats: 0x%x (EFI_DEVICE_ERROR:0x%x, EFI_INVALID_PARAMETER:0x%x, EFI_BUFFER_TOO_SMALL:0x%x)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_DEVICE_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_INVALID_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_BUFFER_TOO_SMALL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// parse response&lt;/span&gt;
    &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"ResponseCode is %d (0x%X)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;pcrUpdateCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrUpdateCounter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Pcr Update Counter: %d (0x%X)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pcrUpdateCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pcrUpdateCounter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;cntSelectionOut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelectionOut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"pcrSelectionOut.count (should be 1): %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cntSelectionOut&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;TPMS_PCR_SELECTION&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pcrSelections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPMS_PCR_SELECTION&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelectionOut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cntSelectionOut&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;UINT8&lt;/span&gt; &lt;span class="n"&gt;sizeofSelect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;sizeofSelect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"pcrSelections[%d].sizeofSelect (should be 3): %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sizeofSelect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;sizeofSelect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"pcrSelections[%d].pcrSelect[%d]: %1x&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pcrSelections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;pcrSelect&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;cntDigest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"Number of digests: %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cntDigest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;TPM2B_DIGEST&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;digests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM2B_DIGEST&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pcrValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;digests&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cntDigest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digests&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;BYTE&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;digests&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"pcrValues.digest[%d] (size %d):&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"%2X"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;digests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM2B_DIGEST&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)(((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;digests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>uefi</category>
      <category>tpm2</category>
      <category>edk2</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to add DXE Driver to BIOS image</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Sun, 26 Jun 2022 15:24:53 +0000</pubDate>
      <link>https://dev.to/machinehunter/how-to-add-dxe-driver-to-bios-image-556p</link>
      <guid>https://dev.to/machinehunter/how-to-add-dxe-driver-to-bios-image-556p</guid>
      <description>&lt;p&gt;In my previous post, I showed you how to make DXE Driver which stores current time in UEFI variable, and convert that into FFS file. To execute this DXE Driver, I'll show you how to add this FFS file into extracted BIOS image from &lt;a href="https://up-shop.org/up-squared-pro-atom-quad-core-0464.html"&gt;UP2 Pro Board&lt;/a&gt;. I will be using followings in this post.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://up-shop.org/up-squared-pro-atom-quad-core-0464.html"&gt;UP Squared Pro ATOM Quad Core 04/64 (UP2 board)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dediprog.com/product/SF100"&gt;SF100 SPI NOR Flash Programmer (SF100)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dediprog.com/product/ISP-TC-8"&gt;ISP Testclip SO8 (TestClip)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/LongSoft/UEFITool/releases/tag/0.28.0"&gt;UEFITool&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;UEFI Shell (which is installed by default on UP2 board)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Download UEFITool
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/LongSoft/UEFITool/releases/tag/0.28.0"&gt;UEFITool&lt;/a&gt; is an opensource tool to parse and edit UEFI image. I will be using this tool to add FFS file into UEFI image. Don't use the version with "&lt;em&gt;NE&lt;/em&gt;" in the name because this version has some restricted functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extract UEFI image by SF100
&lt;/h2&gt;

&lt;p&gt;First you need to extract UEFI image from UP2 board. You can do this by using SF100, and I explained how to do this in &lt;a href="https://dev.to/machinehunter/readwrite-bios-image-using-dediprog-sf100-spi-nor-flash-programmer-3pm3"&gt;my previous post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Insert FFS file by UEFITool
&lt;/h2&gt;

&lt;p&gt;Open UEFITool and Drag&amp;amp;Drop UEFI image file extracted by SF100. Then, locate DXE Volume which is a volume that DXE Drivers are stored by searching the string "DXE" by &lt;code&gt;Ctrl-F&lt;/code&gt; and double-clicking one of the results.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TkRjxmPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1b2ww8zmejn90n2esu2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TkRjxmPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1b2ww8zmejn90n2esu2t.png" alt="Image description" width="880" height="603"&gt;&lt;/a&gt;&lt;br&gt;
Go to the last DXE Driver in the volume and right click that.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MGAvES1K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ua4qw31kzt15pt6yskv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MGAvES1K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ua4qw31kzt15pt6yskv3.png" alt="Image description" width="880" height="375"&gt;&lt;/a&gt;&lt;br&gt;
You will see "Insert after..." if you have downloaded the right version of UEFITool so click on that and select the ffs file generated in the previous post. If successfully added, you will see the result like below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--us1IM0U3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bv00drzkmd3qvixh2zyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--us1IM0U3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bv00drzkmd3qvixh2zyi.png" alt="Image description" width="880" height="213"&gt;&lt;/a&gt;&lt;br&gt;
Press &lt;code&gt;Ctrl-S&lt;/code&gt; and save this BIOS image somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flashing the UEFI with SF100
&lt;/h2&gt;

&lt;p&gt;Again using SF100, flash the modified UEFI image to the UP2 board. This is also explained in &lt;a href="https://dev.to/machinehunter/readwrite-bios-image-using-dediprog-sf100-spi-nor-flash-programmer-3pm3"&gt;my previous post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking MyDxeStatus Variable to see if DXE Driver executed successfully
&lt;/h2&gt;

&lt;p&gt;Power on the board and see if it boots successfully first. If display won't show up, then there might be some errors in DXE Driver. You can debug DXE Driver by using Intel DCI and I also explained this method in &lt;a href="https://dev.to/machinehunter/setup-intel-dci-debugging-on-up-squared-board-46id"&gt;my previous post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If diplay does show up, it's time to check the UEFI variable. You can execute &lt;code&gt;dmpstore &amp;lt;UEFI variable name&amp;gt;&lt;/code&gt; to check UEFI variable values from UEFI Shell.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VQcBUenN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1rbjby64yypzcdsxzf1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VQcBUenN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f1rbjby64yypzcdsxzf1.jpg" alt="Image description" width="880" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>uefi</category>
      <category>dxe</category>
      <category>edk2</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to build DXE Driver by EDK2</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Sun, 26 Jun 2022 14:47:00 +0000</pubDate>
      <link>https://dev.to/machinehunter/how-to-build-dxe-driver-by-edk2-11h8</link>
      <guid>https://dev.to/machinehunter/how-to-build-dxe-driver-by-edk2-11h8</guid>
      <description>&lt;p&gt;In this series, I will show you how to build custom DXE Driver by EDK2 and execute it on &lt;a href="https://up-shop.org/up-squared-pro-atom-quad-core-0464.html"&gt;UP2 Pro&lt;/a&gt; (Single Board Computer). To check if it was executed successfully, this DXE Driver will store current time in UEFI Variable so that, you can check if the time was stored correctly from UEFI Shell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing EDK2
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;sudo apt install build-essential uuid-dev iasl nasm git python python3-distutils python3-apt acpica-tools&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;go to your project's folder and &lt;code&gt;git clone https://github.com/tianocore/edk2.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd edk2&lt;/code&gt; and &lt;code&gt;git submodule update --init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make -C BaseTools&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;source edksetup.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://edk2-docs.gitbook.io/edk-ii-basetools-user-guides/build"&gt;BaseTool&lt;/a&gt; is a set of tools to build UEFI modules and format the module to EFI_SECTION, FFS, FV and so on. By executing &lt;code&gt;edksetup.sh&lt;/code&gt;, you can execute commands in BaseTool without specifying 'PATH'. You might want to take a brief look at the link to know what kind of tools are in BaseTools and what kind of arguments you can specify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration of EDK2 for making DXE Drivers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1: Editing target.txt
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;edk2/Conf/target.txt&lt;/code&gt; like this (Comments excluded).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ACTIVE_PLATFORM = MdeModulePkg/MdeModulePkg.dsc
TARGET          = DEBUG
TARGET_ARCH     = X64
TOOL_CHAIN_CONF = Conf/tools_def.txt
TOOL_CHAIN_TAG  = GCC5
BUILD_RULE_CONF = Conf/build_rule.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might want to execute &lt;code&gt;build&lt;/code&gt; in &lt;code&gt;edk2/&lt;/code&gt; and see if it returns &lt;code&gt;- Done -&lt;/code&gt;. If you got any fails at this point, then some configs on your edk2 are wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  2: Making necessary files
&lt;/h3&gt;

&lt;p&gt;Make folder for your DXE Driver inside &lt;code&gt;edk2/MdeModulePkg/&lt;/code&gt; and prepare two files inside it like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;MyDxe
├── MyDxe.c
└── MyDxe.inf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3: Editing MdeModulePkg.dsc
&lt;/h3&gt;

&lt;p&gt;Add your module under the &lt;code&gt;[Component]&lt;/code&gt; section inside &lt;code&gt;edk2/MdeModulePkg/MdeModulePkg.dsc&lt;/code&gt; like followings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Components]
  MdeModulePkg/MyDxe/MyDxe.inf # add only this
  MdeModulePkg/Application/HelloWorld/HelloWorld.inf
  MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
  MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring MyDxe.inf
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = MyDxe
  FILE_GUID                      = &amp;lt;put your GUID generated by uuidgen&amp;gt;
  MODULE_TYPE                    = DXE_DRIVER
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = MyDxeEntry

[Sources]
    MyDxe.c

[Packages]
    MdePkg/MdePkg.dec
    MdeModulePkg/MdeModulePkg.dec

[LibraryClasses]
    UefiDriverEntryPoint
    UefiRuntimeServicesTableLib
    UefiLib
    PrintLib

[Protocols]

[Depex]
    TRUE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm not using any Protocols in this DXE Driver so I left &lt;code&gt;[Protocols]&lt;/code&gt; blank. If this DXE Driver has to be executed after specific Protocols are installed, you have to put that into &lt;code&gt;[Depex]&lt;/code&gt;, but I'm not using any Protocols so I just put &lt;code&gt;TRUE&lt;/code&gt;. For further details, you can check &lt;a href="https://winraid.level1techs.com/t/what-is-depex-dxe-section/32234/5"&gt;CodeRush's post in Win-Raid Forum&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code of DXE Driver (MyDxe.c)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/PrintLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiDriverEntryPoint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiRuntimeServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;MyDxeEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;myvarSize&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;CHAR8&lt;/span&gt;  &lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;CHAR16&lt;/span&gt; &lt;span class="n"&gt;myvarName&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;L"MyDxeStatus"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;EFI_TIME&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 11223344-5566-7788-99aa-bbccddeeff00&lt;/span&gt;
    &lt;span class="n"&gt;EFI_GUID&lt;/span&gt; &lt;span class="n"&gt;myvarGUID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0x11223344&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x5566&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x7788&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mh"&gt;0x99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xaa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xbb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xcc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xdd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0xff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt; &lt;span class="p"&gt;}};&lt;/span&gt;

    &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;GetTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;AsciiSPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%2d/%2d %2d:%2d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Minute&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;gRT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SetVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;myvarName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;myvarGUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;EFI_VARIABLE_NON_VOLATILE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_BOOTSERVICE_ACCESS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EFI_VARIABLE_RUNTIME_ACCESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;myvarSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;myvarValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create UEFI variable named "MyDxeStatus" and stores current time derived by &lt;code&gt;GetTime&lt;/code&gt; function in the Runtime Services. To prepare format string, I used &lt;code&gt;AsciiSPrint&lt;/code&gt; from &lt;br&gt;
PrintLib Library.&lt;/p&gt;
&lt;h2&gt;
  
  
  Build DXE Driver
&lt;/h2&gt;

&lt;p&gt;You can execute &lt;code&gt;build&lt;/code&gt; to build this driver. If there were no errors, it will show &lt;code&gt;Done&lt;/code&gt; at the end and output files can be found in &lt;code&gt;edk2/Build/MdeModule/DEBUG_GCC5/X64/MdeModulePkg/MyDxe/MyDxe/OUTPUT&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Generating FFS File from the DXE Driver
&lt;/h2&gt;

&lt;p&gt;If you want to add this DXE Driver into BIOS image, you have to convert this into &lt;strong&gt;Fimware FileSystem (FFS)&lt;/strong&gt; format. FFS is consisted of &lt;strong&gt;EFI_SECTION&lt;/strong&gt; Files, which in most case are below 4 sections.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DXE dependency section&lt;/li&gt;
&lt;li&gt;PE32 image section&lt;/li&gt;
&lt;li&gt;User interface section&lt;/li&gt;
&lt;li&gt;Version section&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can refer to &lt;a href="https://edk2-docs.gitbook.io/edk-ii-build-specification/2_design_discussion/22_uefipi_firmware_images"&gt;EDK2 Build Specification&lt;/a&gt; for the information related to these. But anyway, you have to first generate these section files and then, combine them to construct FFS File. Generating section files can be done by using &lt;code&gt;GenSec&lt;/code&gt; command from BaseTools. Also, there is &lt;code&gt;GenFfs&lt;/code&gt; command from BaseTools to combine them into FFS file.&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;edk2/Build/MdeModule/DEBUG_GCC5/X64/MdeModulePkg/MyDxe/MyDxe/OUTPUT/&lt;/code&gt;, I made a folder "FFS" and put the generated files there. Section files are generated by the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GenSec MyDxe.efi &lt;span class="nt"&gt;-S&lt;/span&gt; EFI_SECTION_PE32 &lt;span class="nt"&gt;-o&lt;/span&gt; FFS/MyDxe.pe32
GenSec MyDxe.efi &lt;span class="nt"&gt;-S&lt;/span&gt; EFI_SECTION_USER_INTERFACE &lt;span class="nt"&gt;-o&lt;/span&gt; FFS/MyDxe.ui &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"MyDxe"&lt;/span&gt;
GenSec MyDxe.efi &lt;span class="nt"&gt;-S&lt;/span&gt; EFI_SECTION_VERSION &lt;span class="nt"&gt;-o&lt;/span&gt; FFS/MyDxe.ver

&lt;span class="nb"&gt;cd &lt;/span&gt;FFS
GenFfs &lt;span class="nt"&gt;-t&lt;/span&gt; EFI_FV_FILETYPE_DRIVER &lt;span class="nt"&gt;-d&lt;/span&gt; 1 &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s2"&gt;"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; MyDxe.pe32 &lt;span class="nt"&gt;-i&lt;/span&gt; MyDxe.ui &lt;span class="nt"&gt;-i&lt;/span&gt; MyDxe.ver &lt;span class="nt"&gt;-o&lt;/span&gt; MyDxe.ffs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to generate GUID for this FFS and specify it in &lt;code&gt;GenFfs&lt;/code&gt;. In this DXE Driver, I didn't use DEPEX so I didn't put that, but if you have, you can execute &lt;code&gt;GenSec MyDxe.depex -S EFI_SECTION_DXE_DEPEX -o FFS/MyDxe.depex&lt;/code&gt; (MyDxe.depex is already built with &lt;code&gt;build&lt;/code&gt; command in the OUTPUT folder) and specify that with &lt;code&gt;-i&lt;/code&gt; option in &lt;code&gt;GenFfs&lt;/code&gt; command.&lt;/p&gt;

</description>
      <category>uefi</category>
      <category>edk2</category>
      <category>dxe</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Serial Output from UART on UP2 Pro Board</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Sat, 04 Jun 2022 20:51:53 +0000</pubDate>
      <link>https://dev.to/machinehunter/getting-serial-output-from-uart-on-up2-pro-board-4c3m</link>
      <guid>https://dev.to/machinehunter/getting-serial-output-from-uart-on-up2-pro-board-4c3m</guid>
      <description>&lt;p&gt;If you have UART debug port on your device, you can retrieve various information from there. If you are dealing with IoT, you can access to the shell via UART on some device. Also, if you are dealing with PC, you can retrieve output from the UEFI/BIOS early in the boot phase. Retrieving outputs from serial connection is often better because, such interface like HDMI aren't accessible until late in the boot phase.&lt;br&gt;
In this post, I'll explain how to get the serial output from UART on UP squared pro Atom board.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;p&gt;I will be using followings in this article (hereinafter, these are called by the terms in parentheses).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows 10 PC that has USB 3.0 port (Host PC)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://up-shop.org/up-squared-pro-atom-quad-core-0464.html"&gt;UP Squared Pro Atom Quad Core 04/64 (UP2 board)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.co.jp/dp/B004LBXO2A?psc=1&amp;amp;smid=A1MXYT4C6UUW35&amp;amp;ref_=chk_typ_imgToDp"&gt;USB to 3.3v TTL Header (USB to TTL cable)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://up-shop.org/usb-2-0-pin-header-cable.html"&gt;USB 2.0 pin header cable EP-CBUSB10PFL01 (pin header cable)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Male-to-Male Jumper Wire 3x (jumper wire)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Followings are needed for flashing the BIOS to the one that's build with DEBUG mode.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.dediprog.com/product/SF100"&gt;SF100 SPI NOR Flash Programmer (SF100)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dediprog.com/product/ISP-TC-8"&gt;ISP Testclip SO8 (TestClip)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install FTDI Driver
&lt;/h2&gt;

&lt;p&gt;In order to use USB to TTL cable, you have to install FTDI Driver in your Host PC if you don't have one. You can download from &lt;a href="https://www.gearmo.com/shop/usb-to-3-3v-ttl-pin-header-cable-gm-ttl3vt/"&gt;here&lt;/a&gt; by clicking "Windows FTDI Driver" under "Software &amp;amp; Drivers". This is because the above cable uses FTDI chip for handling USB. FTDI chip is one of the most popular USB to TTL converter IC, and this helps converting USB signal to UART signal (FTDI is a company name).&lt;/p&gt;

&lt;p&gt;You will see the following installer so execute it to install the FTDI Driver.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RARR0_5d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28wliklzevp8rdhwc0c6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RARR0_5d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28wliklzevp8rdhwc0c6.png" alt="Image description" width="429" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check if you have installed it correctly, connect USB to TTL cable to your Host PC and open device manager. If you have "USB Serial Converter", then the installation is success.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HvDHKEpB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g68ybqdupujienrp9ylp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HvDHKEpB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g68ybqdupujienrp9ylp.png" alt="Image description" width="880" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Flashing BIOS to the DEBUG built image
&lt;/h2&gt;

&lt;p&gt;BIOS image built with DEBUG mode often outputs debug info to the serial output. This step is not necessary if you have some module that outputs message to the serial output, but if you don't have any, you can use this to check if the setup is successful.&lt;/p&gt;

&lt;p&gt;The BIOS image I will be using is &lt;a href="https://www.intel.com/content/www/us/en/download/674509/intel-atom-processor-e3900-series-apollo-lake-up-squared-board-flash-images-r-71.html"&gt;Intel Atom® Processor E3900 Series (Apollo Lake) Up Squared Board Flash Images R .71&lt;/a&gt;. You will see two images included in the file, one with "R" and one with "D" in the name. Use the image with "D" in and flash that image to UP2 board. How to flash BIOS is explained in my &lt;a href="https://dev.to/machinehunter/readwrite-bios-image-using-dediprog-sf100-spi-nor-flash-programmer-3pm3"&gt;previous post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the UART connection
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H1RR5rZg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpp2uq4y7amef58bmhv0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H1RR5rZg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dpp2uq4y7amef58bmhv0.jpg" alt="Image description" width="880" height="660"&gt;&lt;/a&gt; &lt;br&gt;
Connect just like the above image. The pins which is important when using UART is GND, TXD, and RXD. Looking at &lt;a href="https://github.com/up-board/up-community/wiki/Serial-console#using-the-provided-adapter"&gt;up-community wiki&lt;/a&gt;, it says black cable is GND, white cable is TXD, and red cable is RXD. You have to connect to the coresponding pin shown below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iXXRdMn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfvj3w28x3guxqeb8tgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iXXRdMn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfvj3w28x3guxqeb8tgf.png" alt="Image description" width="540" height="497"&gt;&lt;/a&gt; &lt;br&gt;
(image from &lt;a href="https://www.gearmo.com/shop/usb-to-serial-uart-5v-ttl-header-cable/"&gt;Gearmo Site&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Other important information to use UART besides pin is baudrate. This is the speed of serial connection. It says on the wiki that the baudrate is 115200bps for this board.&lt;/p&gt;

&lt;p&gt;After connecting, you need to configure serial client. Download &lt;a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html"&gt;PuTTY&lt;/a&gt; on your Windows host if you don't have one. Open PuTTY and select "Session" from the Category. Then, configure it like below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gx2kpBDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzl7u1c796f2urxy2upl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gx2kpBDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzl7u1c796f2urxy2upl.png" alt="Image description" width="528" height="449"&gt;&lt;/a&gt;&lt;br&gt;
For serial line, you can check the device manager to see what COM port it is. In my case, it was "COM3".&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M7ihapar--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqrzyx9pqcw7rntnqurp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M7ihapar--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqrzyx9pqcw7rntnqurp.png" alt="Image description" width="308" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, select "Serial" under "Connection" in the Category and configure it like below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O-NjwxTW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nokjt2xbu8z58q584321.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O-NjwxTW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nokjt2xbu8z58q584321.png" alt="Image description" width="524" height="451"&gt;&lt;/a&gt;&lt;br&gt;
These configurations are written in the wiki. &lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Now let's give it a shot. Make sure you plugged the USB to TTL cable to your Host PC and had the PuTTY configured. Click "Open" button in the PuTTY window, and if all the configuration are successful, black screen will show up without any errors. After that, power on UP2 board and see if it outputs tons of debug information.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ruk0mgvo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vu3wu8459y3p7rdx281l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ruk0mgvo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vu3wu8459y3p7rdx281l.jpg" alt="Image description" width="880" height="660"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/up-board/up-community/wiki/Serial-console"&gt;up-community/wiki/Serial-console&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.huawei.com/enterprise/en/doc/EDOC1100093459/e486f98/logging-in-to-the-server-over-a-serial-port-using-putty"&gt;Logging In to the Server over a Serial Port Using PuTTY&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>uefi</category>
      <category>uart</category>
      <category>hardware</category>
    </item>
    <item>
      <title>Setup Intel DCI Debugging on UP Squared Board</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Wed, 25 May 2022 09:00:00 +0000</pubDate>
      <link>https://dev.to/machinehunter/setup-intel-dci-debugging-on-up-squared-board-46id</link>
      <guid>https://dev.to/machinehunter/setup-intel-dci-debugging-on-up-squared-board-46id</guid>
      <description>&lt;p&gt;Using Intel DCI (Direct Connect Interface), you can debug a whole system including the boot phase via USB cable. In this post, I'll first summarize the related technology of Intel DCI. After that, I'll show you how I setup the environment for Intel DCI Debugging on UP Squared board.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intel DCI and its surroundings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Intel Trace Hub
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZYhT-AVW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cykannijglytvyz6d9ps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZYhT-AVW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cykannijglytvyz6d9ps.png" alt="img" width="880" height="560"&gt;&lt;/a&gt;&lt;br&gt;
(image from &lt;a href="https://www.asset-intertech.com/resources/blog/2021/09/using-the-intel-trace-hub-for-at-speed-printf/"&gt;Using the Intel Trace Hub for at-speed printf&lt;/a&gt; by Alan Sguigna)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intel Trace Hub&lt;/strong&gt; is a mechanism that collects hardware/software events for the entire system, formats them with a time stamp, and  records them in the trace destination. It acts like a PCI device and consisted of below 4 components.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trace Source&lt;/strong&gt;: sources of log such as internal hw signals, SoC performance data, software/firmware trace, and debug data from the Software Trace Hub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trace Destination&lt;/strong&gt;: It can be MTB, system memory, or DCI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Trace Hub&lt;/strong&gt;: routes the data from the trace sources to the trace destinations according to the user’s configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger Unit&lt;/strong&gt;: controls the starting and stopping of tracing operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, DCI is possible based on log information of the entire system provided by Intel Trace Hub.&lt;/p&gt;

&lt;h3&gt;
  
  
  JTAG
&lt;/h3&gt;

&lt;p&gt;JTAG is a mechanism to communicate with IC by serial communication. The interface specifications are defined by IEEE 11149.1, but in reality, semiconductor manufacturers extend them using private instructions and option registers. Functions such as CPU debugging and FPGA/CPLD sequences are realized using private instructions and option registers, so in many cases, only the semiconductor manufacturer and a third party that sined NDA can know.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intel DCI
&lt;/h3&gt;

&lt;p&gt;Intel DCI is a function that allows you to debug the whole system including SMM and reset vector with just USB. More specifically, this allows you to JTAG debug a Intel CPU, with a trace data sent by Intel Trace Hub via USB.&lt;/p&gt;

&lt;p&gt;You can connect target device and the analysis PC with a USB debug cable, and run &lt;strong&gt;Intel System Debugger&lt;/strong&gt; on the analysis PC to debug. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e-5DzjwU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dr1vt9y94sq5o28ljs2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e-5DzjwU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dr1vt9y94sq5o28ljs2f.png" alt="Image description" width="880" height="186"&gt;&lt;/a&gt;&lt;br&gt;
(image from &lt;a href="https://youtu.be/1NEtUxjJ9XM?t=134"&gt;OSFC 2019 - Debugging Intel Firmware using DCI &amp;amp; USB 3.0&lt;/a&gt; by OSFC)&lt;br&gt;
As you can see, there are two types of connections.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;out-of-band (DCI OOB)&lt;/strong&gt;: This method uses USB but don't use USB protocol or USB controller, so we need external adapter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;in-band (USB Debug Class)&lt;/strong&gt;: This method uses USB protocol. Supported in 7th gen and later&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Intel SVT CCA (Silicon View Technology Closed Chassis Adaptor)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XE6En7Fg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qixgg3ex4wgx1ryygid4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XE6En7Fg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qixgg3ex4wgx1ryygid4.png" alt="Image description" width="389" height="288"&gt;&lt;/a&gt;&lt;br&gt;
(image from &lt;a href="https://slimbootloader.github.io/developer-guides/debugging-with-cca.html"&gt;Source Level Debugging with Intel(R) SVT CCA&lt;/a&gt; by Slim Bootloader) &lt;/p&gt;

&lt;p&gt;DCI OOB requires this adapter. This allows access to JTAG or Run-Control via USB3 port on silicon or platform which DCI is enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  ISS (Intel System Studio)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aXv1cr00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihgbf9nu2bbyeyw613p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aXv1cr00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihgbf9nu2bbyeyw613p.png" alt="Image description" width="880" height="288"&gt;&lt;/a&gt;&lt;br&gt;
(image from &lt;a href="https://www.intel.com/content/www/us/en/developer/videos/introduction-of-system-debug-and-trace-in-intel-system-studio-2018.html"&gt;Introduction of System Debug and Trace in Intel® System Studio 2018&lt;/a&gt; by Intel)&lt;/p&gt;

&lt;p&gt;You have to install &lt;strong&gt;Intel System Debug&lt;/strong&gt; in your analysis PC (host PC) to debug using Intel DCI, and System Debug is part of the tools in ISS. ISS debug tools includes the followings.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System Debug&lt;/strong&gt;: For source-level debugging of EFI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Trace&lt;/strong&gt;: Realtime capture of logs of BIOS and CSME&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intel Debug Extension for Windbg&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Methods of connecting target and host
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XS25a6XA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzs81r6vtzzykmdd727j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XS25a6XA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzs81r6vtzzykmdd727j.png" alt="Image description" width="880" height="401"&gt;&lt;/a&gt;&lt;br&gt;
(image from &lt;a href="https://www.intel.com/content/www/us/en/developer/videos/introduction-of-system-debug-and-trace-in-intel-system-studio-2018.html"&gt;Introduction of System Debug and Trace in Intel® System Studio 2018&lt;/a&gt; by Intel)&lt;/p&gt;

&lt;p&gt;ISS provides below 3 methods to connect target and host.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ITP-XDP3&lt;/strong&gt;: Oldest methods. Directly connect to the JTAG socket. Costs about 3000 USD.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CCA (Closed Chassis Adapter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DbC (DCI USB Native Debug Class)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup Intel DCI Environment on UP2 board
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Environment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Windows PC that has USB 3.0 port (Host PC)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://up-shop.org/up-squared-board-atom-x7-e3950-8gb-memory-64gb-emmc.html"&gt;UP Squared ATOM Quad Core 08/64 (UP2 board)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.dediprog.com/product/SF100"&gt;SF100 SPI NOR Flash Programmer (SF100)&lt;/a&gt; + &lt;a href="https://www.dediprog.com/product/ISP-TC-8"&gt;ISP Testclip SO8 (TestClip)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/LongSoft/UEFITool/releases/tag/0.28.0"&gt;UEFITool v2.8 (UEFITool)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ghidra&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registrationcenter-download.intel.com/akdlm/irc_nas/emb/17152/system_studio_2020_u3_ultimate_edition_offline.iso"&gt;Intel System Studio (ISS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.datapro.net/products/usb-3-0-super-speed-a-a-debugging-cable.html"&gt;USB3.0 Debug Cable (Debug Cable)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  DCI Support on UP2 board
&lt;/h3&gt;

&lt;p&gt;In order to use Intel DCI, your BIOS needs to support DCI. Looking at the &lt;a href="https://github.com/up-board/up-community/wiki/UP_Squared_BIOS_History"&gt;BIOS history of UP2 board&lt;/a&gt;, we can see that the DCI Debug Interface is supported since UPA1AM31. However, it is disabled as a default for formal release version since UPA1AM36.  My board had UPA1AM52 flashed (I found out by looking at BIOS SETUP screen), so we have to enable DCI in BIOS configuration first. &lt;/p&gt;

&lt;p&gt;Usually, there is a configuration called &lt;strong&gt;HDCIEN&lt;/strong&gt; in the BIOS SETUP, and by enabling this, it should set the bit inside IA32_DEBUG_INTERFACE MSR and enable DCI. However, on this BIOS, enabling HDCIEN which was under &lt;code&gt;[CRB Setup] &amp;gt; [CRB Chipset] &amp;gt; [South Cluster Configuration] &amp;gt; [Miscellaneous Configuration] &amp;gt; [DCI enabled (HDCIEN)]&lt;/code&gt; doesn't seem like to enable specific bit in the IA32_DEBUG_INTERFACE.&lt;/p&gt;

&lt;p&gt;Intel has open source BIOS image &lt;a href="https://www.intel.com/content/www/us/en/download/674509/intel-atom-processor-e3900-series-apollo-lake-up-squared-board-flash-images-r-71.html"&gt;here&lt;/a&gt;, which is supposed to enable DCI on UP2 Atom board. However, it seems to not boot when I flash the BIOS with this image. Also, it seems like a common problem as the same problem is discussed in &lt;a href="https://forum.up-community.org/discussion/4806/opensource-uefi-bios-by-intel-appears-to-be-unusable-now"&gt;up2 forum&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, I asked Tanda-san (the questioner of the above forum) how he managed to solve this problem, and he gave me a &lt;em&gt;hacky&lt;/em&gt; solution. That is, to patch MSR initialization code to set the bit of IA32_DEBUG_INTERFACE on UP2 BIOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enabling DCI on UP2 board
&lt;/h3&gt;

&lt;p&gt;I used SF100 to extract/write BIOS and the method is explained in my &lt;a href="https://dev.to/machinehunter/readwrite-bios-image-using-dediprog-sf100-spi-nor-flash-programmer-3pm3"&gt;previous post&lt;/a&gt;, so I will skip the details of this.&lt;/p&gt;

&lt;p&gt;After you extracted UPA1AM52 BIOS image from UP2 board and saved as a &lt;code&gt;.bin&lt;/code&gt; file, you can look at what kind of modules are included in that image by using UEFITool. If you look for the byte sequence &lt;code&gt;b9 80 0c 00 00&lt;/code&gt; (&lt;code&gt;mov ecx, 0xc80&lt;/code&gt; while &lt;code&gt;0xc80&lt;/code&gt; is the number of MSR IA32_DEBUG_INTERFACE), you'll probably find 2 hits like below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z0gUdIRY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0ks99fceyzdg5xjhpov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z0gUdIRY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0ks99fceyzdg5xjhpov.png" alt="Image description" width="880" height="701"&gt;&lt;/a&gt;&lt;br&gt;
If you double click the result, youl'll find that they are both in the same PEI module.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eVDcf2SG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjnmjg1llv5788zpdmw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eVDcf2SG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjnmjg1llv5788zpdmw9.png" alt="Image description" width="709" height="140"&gt;&lt;/a&gt;&lt;br&gt;
UEFITool v2.8 can replace module in the image, but it has a disadvantage that it's hard to understand what module it is. By using different version of UEFITool, you can see that the PEI module is called SiInit PEI module.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hNUSa4Uk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u56zy6zovtcgbi7uw9j6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hNUSa4Uk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u56zy6zovtcgbi7uw9j6.png" alt="Image description" width="770" height="136"&gt;&lt;/a&gt;&lt;br&gt;
Let's extract SiInit PEI module by right clicking &lt;code&gt;TE image section&lt;/code&gt; and selecting &lt;code&gt;Extract body&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, we open this module in ghidra. Ghidra recognizes this module as &lt;code&gt;Raw binary&lt;/code&gt; but just go on with it, select &lt;code&gt;x86 64bit Visual Studio&lt;/code&gt; and analyze. After that, again, search for the byte pattern &lt;code&gt;b9 80 0c 00 00&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Disassembling around the first search result, you should get something like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D9T4XTRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ah5lpgnkpn2efygc10pp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D9T4XTRZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ah5lpgnkpn2efygc10pp.png" alt="Image description" width="809" height="154"&gt;&lt;/a&gt;&lt;br&gt;
We have bits that enables DCI on the first bit of IA32_DEBUG_INTERFACE, so lets modify &lt;code&gt;0x40000000&lt;/code&gt; to &lt;code&gt;0x40000001&lt;/code&gt; (you can patch instruction on ghidra by &lt;code&gt;Ctrl-Shift-G&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Also, the second result looks like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nJ8b5ABg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/udhw7l6xgggsjhtusc6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nJ8b5ABg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/udhw7l6xgggsjhtusc6t.png" alt="Image description" width="880" height="115"&gt;&lt;/a&gt;&lt;br&gt;
Samely, modify &lt;code&gt;0x40000000&lt;/code&gt; to &lt;code&gt;0x40000001&lt;/code&gt;.&lt;br&gt;
After that, &lt;code&gt;File &amp;gt; Export Program&lt;/code&gt;, set &lt;code&gt;Binary&lt;/code&gt; as a format and save this patched PEI module to somewhere.&lt;/p&gt;

&lt;p&gt;Now let's go back to the UEFITool and locate that SiInit module again. Right click on the TE image section and select &lt;code&gt;Replace Body&lt;/code&gt;, then select the patched module.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UFVx4JXK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imbkj8p30njj1mz3t7dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UFVx4JXK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imbkj8p30njj1mz3t7dg.png" alt="Image description" width="592" height="333"&gt;&lt;/a&gt;&lt;br&gt;
Once succeeded, you'll see some &lt;code&gt;Rebuild&lt;/code&gt; displayed on the other module but that's normal behavior, so just &lt;code&gt;Ctrl-S&lt;/code&gt; to save this.&lt;/p&gt;

&lt;p&gt;Now, you made the patched UPA1AM52 BIOS image that has IA32_DEBUG_INTERFACE[0] set. Flash the BIOS with this image and you are ready to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intel System Debugger Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ISS Installation
&lt;/h3&gt;

&lt;p&gt;You can download ISO installer from &lt;a href="https://registrationcenter-download.intel.com/akdlm/irc_nas/emb/17152/system_studio_2020_u3_ultimate_edition_offline.iso"&gt;this download link&lt;/a&gt;. If you look inside iso file, you'll see some files like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qZe7PmPH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xh9rakchgwtxamwjh7gk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qZe7PmPH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xh9rakchgwtxamwjh7gk.png" alt="Image description" width="880" height="414"&gt;&lt;/a&gt;&lt;br&gt;
Double click &lt;code&gt;install.exe&lt;/code&gt;, click Next a bunch of time and install ISS.&lt;/p&gt;

&lt;p&gt;Usage of ISS are documented in &lt;code&gt;C:/IntelSWTools/system_studio_2020/documentation_2020/&lt;/code&gt; (though it depends where you installed IntelSWTools). Some path of documents that I found useful are the followings.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Target Indicator&lt;/strong&gt;: &lt;code&gt;documentation_2020/en/debugger/system_studio_2020/system_debugger/target_indicator/TargetIndicator.pdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How to connect System Debugger&lt;/strong&gt;: &lt;code&gt;documentation_2020/en/debugger/system_studio_2020/system_debugger/system_debug/Getting_Started.pdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How to use System Debug&lt;/strong&gt;: &lt;code&gt;documentation_2020/en/debugger/system_studio_2020/system_debugger/system_debug/User_Guide.pdf&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Connecting Intel System Debugger
&lt;/h3&gt;

&lt;p&gt;First, make sure your UP2 board is powered on. Then, on the host PC, run &lt;strong&gt;Intel System Debugger Target Indicator 2020&lt;/strong&gt;. When you run Target Indicator, it seems nothings happened but it's actually executed in the background.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Os3UX1tp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nypbg0mtza87k5642aw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Os3UX1tp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nypbg0mtza87k5642aw9.png" alt="Image description" width="480" height="256"&gt;&lt;/a&gt;&lt;br&gt;
If you right click the red square icon and select &lt;code&gt;Intel(R) System Debugger Target Indicator&lt;/code&gt;, you can check the current status of the connection.&lt;/p&gt;

&lt;p&gt;Then, connect the UP2 board and host PC with USB3.0 debug cable (I always connect target first and then to host). UP2 board have 3 USB3.0 port and not all the port works for this. In my UP2 board, it only recognizes when I plugged it to the port below.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9c-RKnfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdusv0b2p3wn8xlqp4a6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9c-RKnfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qdusv0b2p3wn8xlqp4a6.png" alt="Image description" width="880" height="660"&gt;&lt;/a&gt;&lt;br&gt;
I had trouble recognizing it first, but after I pull out debug cable from the host, reboot the target with the debug cable still plugged in and then, connect to the host again, it worked. Other methods of solving unrecognizing issue were stated &lt;a href="https://docs.microsoft.com/ja-jp/windows-hardware/drivers/debugger/setting-up-a-usb-3-0-debug-cable-connection#usb-device-not-recognized"&gt;here&lt;/a&gt; but I haven't tried that out.&lt;/p&gt;

&lt;p&gt;If connection works, Target Indicator should appear like follows.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ixpPF-6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvfcqout7vrlhnwb5ilj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ixpPF-6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvfcqout7vrlhnwb5ilj.png" alt="Image description" width="865" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, run Intel System Studio.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cbOqdQD---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/da6glk2hue8ug8rch53t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cbOqdQD---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/da6glk2hue8ug8rch53t.png" alt="Image description" width="880" height="566"&gt;&lt;/a&gt;&lt;br&gt;
After closing the "Getting Started", we'll define connection like follows.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o8SUrV0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0suebmqt7038xfk5iui8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o8SUrV0F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0suebmqt7038xfk5iui8.png" alt="Image description" width="880" height="525"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MABNkcE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59vypzzyj7lgdy7kx3m9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MABNkcE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59vypzzyj7lgdy7kx3m9.png" alt="Image description" width="871" height="898"&gt;&lt;/a&gt;&lt;br&gt;
If the connection is established, you will see something like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wf-BJe1L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brfh2z95v2rpnrmca5tr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wf-BJe1L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brfh2z95v2rpnrmca5tr.png" alt="Image description" width="869" height="904"&gt;&lt;/a&gt;&lt;br&gt;
If it didn't detect the target properly, you can "Manually Select Target" or try with different USB3.0 port on the target.&lt;/p&gt;

&lt;p&gt;If you press Finish, you'll see the screen as follows.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--na7UGaFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgd51csq3dzntmif4zgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--na7UGaFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgd51csq3dzntmif4zgw.png" alt="Image description" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you have to setup &lt;strong&gt;Debug Configuration&lt;/strong&gt;. Open the Debug Configuration as follows.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8PkiPgLd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tce0jbfm8qh9c4vdwpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8PkiPgLd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tce0jbfm8qh9c4vdwpi.png" alt="Image description" width="424" height="191"&gt;&lt;/a&gt;&lt;br&gt;
Select Intel System Debugger and click Apply without changing any configuration.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AH98Tzec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8udk4q1hrxkf5kdzb226.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AH98Tzec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8udk4q1hrxkf5kdzb226.png" alt="Image description" width="880" height="701"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xSLlQOrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck5egl27kd4l869l9q23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xSLlQOrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck5egl27kd4l869l9q23.png" alt="Image description" width="880" height="503"&gt;&lt;/a&gt;&lt;br&gt;
You will see a popup like this, so click Switch.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3F-Yo8C---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65v0sjiuyqqtyhgako3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3F-Yo8C---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/65v0sjiuyqqtyhgako3h.png" alt="Image description" width="681" height="279"&gt;&lt;/a&gt;&lt;br&gt;
Eventually, you'll get this kind of screen.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PSOt8G6---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5f11xl5owd1dpe1wtiqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PSOt8G6---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5f11xl5owd1dpe1wtiqj.png" alt="Image description" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Try suspending PC from System Debugger
&lt;/h3&gt;

&lt;p&gt;Now if you click Suspend like below, and target freezes, then it's a success! Assembly will be displayed after you suspended.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7vNohTQb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6u8n7vozkood8zbqnosa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7vNohTQb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6u8n7vozkood8zbqnosa.png" alt="Image description" width="493" height="446"&gt;&lt;/a&gt;&lt;br&gt;
If you want to debug boot phase, you can just reboot target.&lt;/p&gt;

&lt;h3&gt;
  
  
  Second time connecting Intel System Debugger
&lt;/h3&gt;

&lt;p&gt;For the second time debugging, you can follow these.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Power on UP2 board&lt;/li&gt;
&lt;li&gt;Run Target Indicator on host&lt;/li&gt;
&lt;li&gt;Connect debug cable&lt;/li&gt;
&lt;li&gt;Open ISS and use previous workspace&lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Verify Connected Target&lt;/code&gt; to see if successfully connected&lt;/li&gt;
&lt;li&gt;Click "Connect Button" to connect (tiny green icon)&lt;/li&gt;
&lt;li&gt;Click icon with a "bug" to run with the previous Debug Configuration&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Acknowledgement
&lt;/h2&gt;

&lt;p&gt;Again, great thanks to &lt;a href="https://github.com/tandasat?tab=repositories"&gt;Satoshi Tanda&lt;/a&gt; for the support.&lt;/p&gt;

</description>
      <category>uefi</category>
      <category>debug</category>
      <category>firmware</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Read&amp;Write BIOS Image using Dediprog SF100 SPI NOR Flash Programmer</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Tue, 24 May 2022 14:33:55 +0000</pubDate>
      <link>https://dev.to/machinehunter/readwrite-bios-image-using-dediprog-sf100-spi-nor-flash-programmer-3pm3</link>
      <guid>https://dev.to/machinehunter/readwrite-bios-image-using-dediprog-sf100-spi-nor-flash-programmer-3pm3</guid>
      <description>&lt;p&gt;SPI flash stores most of the module executed by UEFI BIOS. If you want to extract actual UEFI module to take a look at, or modify some of the content, &lt;strong&gt;SPI flash programmer&lt;/strong&gt; is a perfect solution. Moreover, some BIOS images are distributed as &lt;code&gt;.bin&lt;/code&gt; file, and you can use SPI flash programmer to update BIOS with those image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;p&gt;I will be using followings in this article.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows PC that has USB 3.0 port (Host PC)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://up-shop.org/up-squared-board-atom-x7-e3950-8gb-memory-64gb-emmc.html"&gt;UP Squared ATOM Quad Core 08/64 (UP2 board)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dediprog.com/product/SF100"&gt;SF100 SPI NOR Flash Programmer (SF100)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dediprog.com/product/ISP-TC-8"&gt;ISP Testclip SO8 (TestClip)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Finding SPI Flash Chip and detecting Device ID
&lt;/h2&gt;

&lt;p&gt;For UP2 board, you first have to take off heatsink like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i8opTa5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ybt4lobtujykbhp0l23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i8opTa5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ybt4lobtujykbhp0l23.png" alt="Image description" width="880" height="414"&gt;&lt;/a&gt;&lt;br&gt;
Most SPI flash chip is manufactured by &lt;a href="https://www.winbond.com/hq"&gt;winbond&lt;/a&gt;, so it is one way to find a chip that has a letter "winbond" written. In my UP2 board, it was located here. It first had a seal on so I had to take off the seal to find this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qqIrFin9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30u9z76dahzsej8n9ok3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qqIrFin9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30u9z76dahzsej8n9ok3.png" alt="Image description" width="768" height="706"&gt;&lt;/a&gt;&lt;br&gt;
It's too small to look from above picture, but it says &lt;code&gt;winbond 25Q128JWSQ 2117&lt;/code&gt; which we can tell that the device ID for this chip is &lt;code&gt;W25Q128JW&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup for using SF100
&lt;/h2&gt;

&lt;p&gt;Download the following three items from &lt;a href="https://www.dediprog.com/product/SF100#download"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latest version of software for using SF100

&lt;ul&gt;
&lt;li&gt;I downloaded version &lt;code&gt;7.3.90.46&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;USB driver&lt;/li&gt;
&lt;li&gt;USB Driver User Guide for Win 8/8.1/10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will be asked to enter your email and serial number when downloading. The serial number is written on the back of the SF100.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MUq4l0YG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3afms425wuxgkvj95vfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MUq4l0YG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3afms425wuxgkvj95vfb.png" alt="Image description" width="343" height="620"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once downloaded, run &lt;code&gt;.msi&lt;/code&gt; installer to install the software. If the following 4 app shortcuts are generated on the desktop (note that I have moved contents to a folder), then the installation is complete.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AjCNmLxP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w49iesuncz1oemlhagj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AjCNmLxP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w49iesuncz1oemlhagj2.png" alt="Image description" width="757" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you have to setup the USB driver. &lt;br&gt;
Let's connect SF100 and TestClip like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bAsDSJqw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhtcmqqeergfqcrm45mb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bAsDSJqw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhtcmqqeergfqcrm45mb.png" alt="Image description" width="880" height="489"&gt;&lt;/a&gt;&lt;br&gt;
You can referer to the "USB Driver User Guide" from now on, but here's what I did. First, connect the above to the Host PC (which you will be using for manipulating SF100) and check the device manager. It should be like this.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YaTWaROv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yoi7l5d28mt27ehvan5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YaTWaROv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8yoi7l5d28mt27ehvan5.png" alt="Image description" width="276" height="104"&gt;&lt;/a&gt;&lt;br&gt;
Right click the above "SF100-ISP" and select "Update Driver Software...". Then follow the steps below.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Browse my computer for driver software&lt;/li&gt;
&lt;li&gt;Let me pick from a list of device drivers on my computer&lt;/li&gt;
&lt;li&gt;Click Next without selecting any&lt;/li&gt;
&lt;li&gt;Click Have Disk&lt;/li&gt;
&lt;li&gt;Browse and locate the USB driver we downloaded before &lt;code&gt;dediprog.inf&lt;/code&gt; and click OK&lt;/li&gt;
&lt;li&gt;Select "DediProg SF Programmer driver" and click Next&lt;/li&gt;
&lt;li&gt;Installation will start and if nothing goes wrong, "Window has successfully updated your driver software" will be shown.&lt;/li&gt;
&lt;li&gt;Again if you open device manager and see this, then it's a success
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yRk_I6eo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrgl6bwgvyj4c3h761cg.png" alt="Image description" width="513" height="229"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Recognize SPI flash from Host PC
&lt;/h2&gt;

&lt;p&gt;Now let's clip the SPI flash with the TestClip. Looking closely, you will see a dot on flash chip, and small white paintings on the TestClip. Make sure you clip it the right way, so that the white paint and the dot on the chip are in the same position.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HojfONge--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4whnse1x5863ikpryxir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HojfONge--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4whnse1x5863ikpryxir.png" alt="Image description" width="880" height="704"&gt;&lt;/a&gt;&lt;br&gt;
After that, connect USB cable to the host PC and run the software "DediProg Engineering" which is one of the 4 shortcuts created after installation.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z38rgUtz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l06hs6lazxj1pizwiw1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z38rgUtz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l06hs6lazxj1pizwiw1u.png" alt="Image description" width="880" height="574"&gt;&lt;/a&gt;&lt;br&gt;
If it recognized correctly, the software asks you to select SPI flash Chip ID. You have found out that the device ID was &lt;code&gt;W25Q128JW&lt;/code&gt; so select that. If there's no error, then the recognition is success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading SPI flash
&lt;/h2&gt;

&lt;p&gt;( The usage of SF100 software is written in "DediProg Help" which is one of the four desktop shortcuts created at installation )&lt;/p&gt;

&lt;p&gt;To read the SPI flash content, click the &lt;code&gt;Edit&lt;/code&gt; icon and then, press &lt;code&gt;Read...&lt;/code&gt;. While reading, busy lamp glows orange on SF100, and the percentage of progress will be displayed on the place where &lt;code&gt;Read...&lt;/code&gt; button was located.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PcjzHHua--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzwllffqiq0ueij56q6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PcjzHHua--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzwllffqiq0ueij56q6e.png" alt="Image description" width="880" height="581"&gt;&lt;/a&gt;&lt;br&gt;
After reading is complete, you can press &lt;code&gt;Chip Buffer to File&lt;/code&gt; to save image as a &lt;code&gt;.bin&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;After saving file, you might get an error message like &lt;code&gt;an unnamed file contains ...&lt;/code&gt;, but you can ignore that. If you are not sure you've read the flash contents successfully, check if the contents start with the flash descriptor's magic byte &lt;code&gt;5A A5 F0 0F&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing SPI flash
&lt;/h2&gt;

&lt;p&gt;Click &lt;code&gt;Config&lt;/code&gt; icon and select/check the following two items.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Download a whole file to chip (Without Blank Check)…&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Reload file each time&lt;/code&gt;
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yvHyk3WE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/az5vfuf3m8ehptd13p9g.png" alt="Image description" width="880" height="554"&gt;
Then, press OK. There will be about two warning messages showing up, but you can ignore those. Next, click &lt;code&gt;File&lt;/code&gt; icon and do the followings.&lt;/li&gt;
&lt;li&gt;click &lt;code&gt;Find&lt;/code&gt; and select the BIOS image file you want to write in&lt;/li&gt;
&lt;li&gt;select &lt;code&gt;Raw Binary&lt;/code&gt; and make sure you don't check &lt;code&gt;Trucate file to...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After pressing OK, check if you have &lt;code&gt;Operation completed&lt;/code&gt;. Finally, press the &lt;code&gt;Batch&lt;/code&gt; icon and start flashing.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mTeD5E3Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5anhhs5t2dhusuw713io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mTeD5E3Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5anhhs5t2dhusuw713io.png" alt="Image description" width="880" height="660"&gt;&lt;/a&gt;&lt;br&gt;
You can check if flashing is over by seeing if busy lamp becomes pass. You will see this kind of log output if it succeeded.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--499BYLZN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nyljo3x1rci70crssi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--499BYLZN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nyljo3x1rci70crssi1.png" alt="Image description" width="880" height="654"&gt;&lt;/a&gt;&lt;br&gt;
If you want to restore it, you can use the flash content file read in the previous section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgement
&lt;/h2&gt;

&lt;p&gt;Great thanks to &lt;a href="https://github.com/tandasat?tab=repositories"&gt;Satoshi Tanda&lt;/a&gt; for the support and for introducing this wonderful topic.&lt;/p&gt;

</description>
      <category>uefi</category>
      <category>bios</category>
      <category>hardware</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>TPM2_NV_DefineSpace from UEFI</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Tue, 24 May 2022 00:24:49 +0000</pubDate>
      <link>https://dev.to/machinehunter/tpm2nvdefinespace-from-uefi-4ffd</link>
      <guid>https://dev.to/machinehunter/tpm2nvdefinespace-from-uefi-4ffd</guid>
      <description>&lt;p&gt;We can say that the most complicated part of TPM2.0 is authentication/session. My previous post's TPM2_GetRandom and TPM2_GetCapability didn't require session (as we specified TPM_ST_NO_SESSIONS in the Header tag) so it was relatively easy to implement. However, commands which requires session are much more difficult than those. In this article, we will define 128bit (16byte) of space in NVRAM of TPM by using TPM2_NV_DefineSpace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parameters of TPM2_NV_DefineSpace
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnurvaxwlz8szq8dz0e6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnurvaxwlz8szq8dz0e6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sessions
&lt;/h3&gt;

&lt;p&gt;If command requires session, we have to specify &lt;strong&gt;TPM_ST_SESSIONS&lt;/strong&gt; in the &lt;em&gt;tag&lt;/em&gt; of Command Header. Session in TPM is quite a complex concept. For details, I want you to look at TCG spec Part1 19.5 or other materials. In this case, session is used for authorization of the use of &lt;em&gt;authHandle&lt;/em&gt; because it has &lt;code&gt;@&lt;/code&gt; mark.&lt;/p&gt;

&lt;p&gt;Now, one of the trickiest pitfall here is that, &lt;strong&gt;where to write the actual content of the session&lt;/strong&gt;. It is not &lt;em&gt;explicitly&lt;/em&gt; written in the above table, but looking at TCG spec Part1 18.9 and 18.10, it says that we have to insert some authorization-related structure like below. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2oshfl3d4f6qfm47vdjc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2oshfl3d4f6qfm47vdjc.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesmcbnl5l2txzdt2jm6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesmcbnl5l2txzdt2jm6g.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
These structures are defined as TPMS_AUTH_COMMAND and TPMS_AUTH_RESPONSE. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lcb7k7bb1i22kft7h2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lcb7k7bb1i22kft7h2g.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
When sending command, we have to put TPMS_AUTH_COMMAND (the actual content of the session) above the thick line which is between handle and command-specific parameters. For the response, there will be only &lt;em&gt;parameterSize&lt;/em&gt; above the thick line and other information (TPMS_AUTH_RESPONSE) is appended at last. These authorization-related structures will exists for any command which requires sessions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The whole code will be as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiBootServicesTableLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Protocol/Tcg2Protocol.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;IndustryStandard/Tpm20.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack(1)
&lt;/span&gt;    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPMI_SH_AUTH_SESSION&lt;/span&gt; &lt;span class="n"&gt;sessionHandle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;nonceSizeZero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMA_SESSION&lt;/span&gt; &lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;hmacSizeZero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;ORIG_AUTH_AREA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMI_RH_NV_INDEX&lt;/span&gt; &lt;span class="n"&gt;nvIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMI_ALG_HASH&lt;/span&gt; &lt;span class="n"&gt;nameAlg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="cm"&gt;/*TPMA_NV attributes;*/&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;authPolicySizeZero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;ORIG_NV_PUBLIC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_COMMAND_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMI_RH_PROVISION&lt;/span&gt; &lt;span class="n"&gt;authHandle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;authSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ORIG_AUTH_AREA&lt;/span&gt; &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="cm"&gt;/*TPM2B_AUTH auth;*/&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;authSizeZero&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="cm"&gt;/*TPM2B_NV_PUBLIC publicInfo;*/&lt;/span&gt;
        &lt;span class="n"&gt;ORIG_NV_PUBLIC&lt;/span&gt; &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_NV_DEFINE_SPACE_COMMAND&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_RESPONSE_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_NV_DEFINE_SPACE_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack()
&lt;/span&gt;

&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;EFI_TCG2_PROTOCOL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;BootServices&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;LocateProtocol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiTcg2ProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOID&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// Auth Area&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;authSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;ORIG_AUTH_AREA&lt;/span&gt; &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionHandle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_RS_PW&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nonceSizeZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;continueSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auditExclusive&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auditReset&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reserved3_4&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decrypt&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encrypt&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sessionAttributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;audit&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hmacSizeZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;authSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// publicInfo area&lt;/span&gt;
    &lt;span class="n"&gt;ORIG_NV_PUBLIC&lt;/span&gt; &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NV_INDEX_FIRST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nameAlg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ALG_SHA1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="cm"&gt;/*
     *TPMA_NV attributes;
     *attributes.TPMA_NV_PPWRITE        = 1;
     *attributes.TPMA_NV_OWNERWRITE     = 1;
   *attributes.TPMA_NV_AUTHWRITE      = 1;
   *attributes.TPMA_NV_POLICYWRITE    = 1;
   *attributes.TPMA_NV_COUNTER        = 0;
   *attributes.TPMA_NV_BITS           = 0;
   *attributes.TPMA_NV_EXTEND         = 0;
   *attributes.reserved7_9            = 000;
   *attributes.TPMA_NV_POLICY_DELETE  = 0;
   *attributes.TPMA_NV_WRITELOCKED    = 0;
   *attributes.TPMA_NV_WRITEALL       = 1;
   *attributes.TPMA_NV_WRITEDEFINE    = 0;
   *attributes.TPMA_NV_WRITE_STCLEAR  = 1;
   *attributes.TPMA_NV_GLOBALLOCK     = 0;
   *attributes.TPMA_NV_PPREAD         = 1;
   *attributes.TPMA_NV_OWNERREAD      = 1;
   *attributes.TPMA_NV_AUTHREAD       = 1;
   *attributes.TPMA_NV_POLICYREAD     = 1;
   *attributes.reserved20_24          = 00000;
   *attributes.TPMA_NV_NO_DA          = 1;
   *attributes.TPMA_NV_ORDERLY        = 0;
   *attributes.TPMA_NV_CLEAR_STCLEAR  = 0;
   *attributes.TPMA_NV_READLOCKED     = 0;
   *attributes.TPMA_NV_WRITTEN        = 0;
   *attributes.TPMA_NV_PLATFORMCREATE = 0;
   *attributes.TPMA_NV_READ_STCLEAR   = 0;
   * =&amp;gt; 00000010000011110101000000001111
     * =&amp;gt; 0x20f500f
     */&lt;/span&gt;
    &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x20f500f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authPolicySizeZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;


    &lt;span class="n"&gt;TPM2_NV_DEFINE_SPACE_COMMAND&lt;/span&gt; &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;TPM2_NV_DEFINE_SPACE_RESPONSE&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// set parameters&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ST_SESSIONS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commandCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CC_NV_DefineSpace&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authHandle&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_RH_OWNER&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authSize&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authArea&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authSizeZero&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publicInfo&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authArea&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authSizeZero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publicInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// send TPM command&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"sending TPM command...&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SubmitCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"SubmitCommand Success!&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"stats: 0x%x (EFI_DEVICE_ERROR:0x%x, EFI_INVALID_PARAMETER:0x%x, EFI_BUFFER_TOO_SMALL:0x%x)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_DEVICE_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_INVALID_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_BUFFER_TOO_SMALL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"responseCode is %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  TPMS_AUTH_COMMAND
&lt;/h3&gt;

&lt;p&gt;This is the session content mentioned above. There are 3 ways of authentication in TPM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password&lt;/li&gt;
&lt;li&gt;HMAC&lt;/li&gt;
&lt;li&gt;Policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this example, I'm using password (TPM_RS_PW) which is the easiest authentication method.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When using tpm2-tool and you didn't specify any of these authentication, it defaults to use password authentication with blank password.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may notice I'm not using TPMS_AUTH_COMMAND even though it's defined in Tpm20.h. Most of the attributes are same as TPMS_AUTH_COMMAND, but &lt;em&gt;nounceSizeZero&lt;/em&gt; and &lt;em&gt;hmacSizeZero&lt;/em&gt; are redefined. This is actually one of the pitfalls: &lt;strong&gt;TPM's canonicalization&lt;/strong&gt;. For example, &lt;em&gt;nonce&lt;/em&gt; has a type of TPM2B_NONCE which is same as TPM2B_DIGEST, and if you lookup this definition in Tpm20.h, it's defined like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;UINT16&lt;/span&gt;    &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;BYTE&lt;/span&gt;      &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPMT_HA&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2B_DATA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, if you set &lt;code&gt;size=0&lt;/code&gt; and &lt;code&gt;buffer=NULL&lt;/code&gt;, total size of data actually sent will be &lt;code&gt;sizeof(UINT16)+sizeof(TPMT_HA)&lt;/code&gt;. However, in TPM, size of data sent will only be &lt;code&gt;sizeof(UINT16)&lt;/code&gt;. If &lt;code&gt;size=2&lt;/code&gt; and &lt;code&gt;buffer="A\0"&lt;/code&gt; then the data size sent will be &lt;code&gt;sizeof(UINT16)+2&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Therefore, &lt;strong&gt;if you have structures with TPM2B_ prefix, you have to redefine that structure and adjust the size of &lt;em&gt;buffer&lt;/em&gt; field to the actual data size you're trying to put&lt;/strong&gt;. This is called canonicalization.&lt;/p&gt;

&lt;h3&gt;
  
  
  auth parameter
&lt;/h3&gt;

&lt;p&gt;If you read authorization-related section of TCG spec or Practical Guide to TPM2.0, you will see a lots of word &lt;strong&gt;&lt;em&gt;authValue&lt;/em&gt;&lt;/strong&gt;. This is roughly an input for authorization, so in password authentication, this value is the actual password. Also, &lt;em&gt;authValue&lt;/em&gt; is specified by different parameter in different commands. In TPM2_NV_DefineSpace, the parameter for &lt;em&gt;authValue&lt;/em&gt; is &lt;em&gt;auth&lt;/em&gt; parameter.&lt;/p&gt;

&lt;p&gt;I wanted to use blank password for this authentication so that is why I redefined &lt;code&gt;TPM2B_AUTH auth&lt;/code&gt; to &lt;code&gt;UINT16 authSizeZero&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  publicInfo Area
&lt;/h3&gt;

&lt;p&gt;This parameter is the configuration of NVRAM space we're trying to define. To expand TPM2B_NV_PUBLIC structure, it will be like follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* TPM2B_NV_PUBLIC
  * UINT16 size
  * TPMS_NV_PUBLIC nvPublic
    * [UINT32] [TPM_HANDLE] TPMI_RH_NV_INDEX nvIndex
    * [UINT16] [TPM_ALG_ID] TPMI_ALG_HASH nameAlg
    * [UINT32 bitfield] TPMA_NV attributes
    * TPM2B_DIGEST authPolicy
      * UINT16 size
      * BYTE buffer[]
    * UINT16 dataSize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  NV Index and Name
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;NV Index&lt;/strong&gt; is something like a handle for the specific NVRAM space. There are constants NV_INDEX_FIRST and NV_INDEX_LAST so you can specify any value in this range for &lt;em&gt;nvIndex&lt;/em&gt;. TPM uses &lt;strong&gt;"Name"&lt;/strong&gt; as an unique identifier for TPM entities. We must specify by what algorithm we generate Name so there is &lt;em&gt;nameAlg&lt;/em&gt; parameter.&lt;/p&gt;

&lt;h4&gt;
  
  
  TPMA_NV
&lt;/h4&gt;

&lt;p&gt;We have to take roundabout method to send TPMA_ structure. Since TPM require us to send data in big endian, we have to SwapBytes TPMA_, but SwapBytes32 doesn't allow UINT32 bitfield. You can use union to cast it into UINT32 or just do it manually like above code.&lt;/p&gt;

&lt;p&gt;TPMA_NV determines the core configuration of the NV Index we're trying to create. For detailed meanings of each bit, you can look at TCG spec Part2, and here, I will just explain the points.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are mainly &lt;strong&gt;4 types&lt;/strong&gt; of NV Index: Ordinary, Bit Field, Extend, Hybrid NV Indexes.&lt;/li&gt;
&lt;li&gt;I'm specifying NV Ordinary Index which is a type we can put unstructured data with any size&lt;/li&gt;
&lt;li&gt;We can specify separate authorization for the read and write to this NV Index&lt;/li&gt;
&lt;li&gt;NV Index can be locked to prevent read or write&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running the code
&lt;/h2&gt;

&lt;p&gt;You will get this kind of output if it succeeded. My response code is &lt;code&gt;332&lt;/code&gt; which means the NV Index I specified is already in use and actually it is, but if it isn't, you should get response code 0. Also, after defining this, you can run this program again and see if you get &lt;code&gt;332&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flela2detizavoqq7qwn2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flela2detizavoqq7qwn2.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This article was mainly about how to implement TPM commands which requires authorization and session.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If command requires session, we have to specify TPM_ST_SESSIONS in the &lt;em&gt;tag&lt;/em&gt; of Command Header&lt;/li&gt;
&lt;li&gt;session is required to authorize the use of parameter which has &lt;code&gt;@&lt;/code&gt; mark&lt;/li&gt;
&lt;li&gt;TPMS_AUTH_COMMAND and TPMS_AUTH_RESPONSE should be placed as written in TCG spec Part1 18.9 and 18.10&lt;/li&gt;
&lt;li&gt;TPMS_AUTH_COMMAND and TPMS_AUTH_RESPONSE is required for &lt;em&gt;every&lt;/em&gt; command that requires session&lt;/li&gt;
&lt;li&gt;There are 3 ways of authentication in TPM: Password, HMAC, and Policy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canonicalization&lt;/strong&gt;: TPM sends only &lt;code&gt;sizeof(UINT16)&lt;/code&gt; if you specify 0 for &lt;em&gt;size&lt;/em&gt;, even though you had &lt;code&gt;buffer[MAX_...]&lt;/code&gt; in the structure&lt;/li&gt;
&lt;li&gt;We have to redefine structure if we have struct with TPM2B_ prefix due to canonicalization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;authValue&lt;/em&gt;&lt;/strong&gt; is roughly an input required for authorization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NV Index&lt;/strong&gt; is something like a handle for the specific NVRAM space&lt;/li&gt;
&lt;li&gt;TPM uses &lt;strong&gt;"Name"&lt;/strong&gt; as an unique identifier for TPM entities&lt;/li&gt;
&lt;li&gt;How to swap bytes of TPMA_ object and broad explanation of TPMA_NV&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>uefi</category>
      <category>tpm2</category>
      <category>edk2</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>TPM2_GetCapability from UEFI</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Sun, 22 May 2022 19:58:03 +0000</pubDate>
      <link>https://dev.to/machinehunter/accessing-tpm20-from-uefi-module-tpm2getcapability-444p</link>
      <guid>https://dev.to/machinehunter/accessing-tpm20-from-uefi-module-tpm2getcapability-444p</guid>
      <description>&lt;p&gt;In my &lt;a href="https://dev.to/machinehunter/accessing-tpm20-from-uefi-module-sending-tpm2getrandom-140b"&gt;previous post&lt;/a&gt;, I introduced how to submit very easy command TPM2_GetRandom to TPM from UEFI. TPM2_GetCapability is also an easy command, but we need to specify more parameters and those meanings are bit more complex than TPM2_GetRandom. TPM2_GetCapability is a command frequently used to check the current status of your TPM, so it is helpful to have one program already implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  parameters of TPM2_GetCapability
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AmErpg-T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cn5d0ydypal3hkc63sx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AmErpg-T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1cn5d0ydypal3hkc63sx.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;br&gt;
Put simply, we specify what kind of information we want in &lt;em&gt;capability&lt;/em&gt;. and request the result in the range of [&lt;em&gt;property&lt;/em&gt;:&lt;em&gt;property+propertyCount&lt;/em&gt;].&lt;/p&gt;

&lt;p&gt;The types of &lt;em&gt;capability&lt;/em&gt; we can specify is listed in the command desription.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uFBYSBxd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egr1gyx1frqzh5eaipy9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uFBYSBxd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egr1gyx1frqzh5eaipy9.png" alt="Image description" width="880" height="590"&gt;&lt;/a&gt;&lt;br&gt;
In this post, &lt;strong&gt;we will use TPM2_GetCapability to list out supported commands by specifying TPM_CAP_COMMANDS as a &lt;em&gt;capability&lt;/em&gt; parameter&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The whole code looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Protocol/Tcg2Protocol.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;IndustryStandard/Tpm20.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack(1)
&lt;/span&gt;    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_COMMAND_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPM_CAP&lt;/span&gt; &lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;propertyCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_GET_CAPABILITY_COMMAND&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_RESPONSE_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMI_YES_NO&lt;/span&gt; &lt;span class="n"&gt;moreData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPMS_CAPABILITY_DATA&lt;/span&gt; &lt;span class="n"&gt;capabilityData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_GET_CAPABILITY_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack()
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;EFI_TCG2_PROTOCOL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;BootServices&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;LocateProtocol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiTcg2ProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOID&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="n"&gt;TPM2_GET_CAPABILITY_COMMAND&lt;/span&gt; &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;TPM2_GET_CAPABILITY_RESPONSE&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// set command parameters&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ST_NO_SESSIONS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commandCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CC_GetCapability&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CAP_COMMANDS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CAP_FIRST&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyCount&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAX_CAP_CC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;propertyCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// send TPM command&lt;/span&gt;
    &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SubmitCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"SubmitCommand Success!&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"stats: 0x%x (EFI_DEVICE_ERROR:0x%x, EFI_INVALID_PARAMETER:0x%x, EFI_BUFFER_TOO_SMALL:0x%x)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_DEVICE_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_INVALID_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_BUFFER_TOO_SMALL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// parse response&lt;/span&gt;
    &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"ResponseCode is %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"moreData: %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moreData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capabilityData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"--- %d commands supported ---&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;TPMA_CC&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;tpmacc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPMA_CC&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capabilityData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commandAttributes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;tpma_cc_uint32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;TPMA_CC&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;castbuf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;castbuf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tpmacc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;tpmacc32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;castbuf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tpma_cc_uint32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;UINT16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;tpmacc32&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;TPM_CC_NV_DefineSpace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"TPM2_NV_DefineSpace is supported: %X&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tpmacc32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  command parameter description
&lt;/h3&gt;

&lt;p&gt;Again, we have to send data in BigEndian to TPM so there are lots of &lt;code&gt;SwapBytes&lt;/code&gt;. Macros like TPM_CAP_COMMANDS and TPM_CAP_FIRST are searched in the Tpm20.h which is located in &lt;code&gt;MdePkg/Include/IndustryStandard/Tpm20.h&lt;/code&gt;. Notice we're requesting MAX_CAP_CC as &lt;em&gt;propertyCount&lt;/em&gt; parameter, which we can guess &lt;em&gt;moreData&lt;/em&gt; parameter in the response will be 0.&lt;/p&gt;

&lt;h3&gt;
  
  
  response description
&lt;/h3&gt;

&lt;p&gt;Parsing response is the main part of this article.&lt;br&gt;
We can find out &lt;code&gt;typedef BYTE TPMI_YES_NO;&lt;/code&gt; in Tpm20.h and since it says "YES_NO", we can easily tell &lt;em&gt;moreData&lt;/em&gt; takes 1 or 0 as a value. However, &lt;em&gt;capabilityData&lt;/em&gt; parameter which has a type TPMS_CAPABILITY_DATA is more complex. By looking it up on Tpm20.h, we can find out TPMS_CAPABILITY_DATA structure is as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* [struct] TPMS_CAPABILITY_DATA
  * [UINT32] TPM_CAP capability
  * [union] TPMU_CAPABILITIES
    * [struct] TPML_ALG_PROPERTY algorithms;
      * [UINT32] UINT32 count
      * [struct] TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS];
        * [UINT16] TPM_ALG_ID alg
        * [UINT32(bitfield)] TPMA_ALGORITHM algProperties
    * ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Name Prefix Convention
&lt;/h4&gt;

&lt;p&gt;Looking at TPM macros above, we notice there are some convention in the prefix of its name. Name Prefix Convention is defined in TCG spec Part2 4.16. Here are the part of it.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ha0lT1oE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avogo7nhtjbjkybxutes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ha0lT1oE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avogo7nhtjbjkybxutes.png" alt="Image description" width="880" height="711"&gt;&lt;/a&gt;&lt;br&gt;
The prefix you must be aware of is &lt;strong&gt;TPM2B_&lt;/strong&gt; prefix. Structures with this prefix vary in size depending on the data they hold. There aren't any in TPMS_CAPABILITY_DATA, but if this structure is included, you can't just define response structure and access via that structure just like what I'm doing in the above code. This will be described afterwards when this actually appears. For now, it is enough to know that, you can know what type of data it is from the prefix.&lt;/p&gt;
&lt;h4&gt;
  
  
  bitfield to UINT32
&lt;/h4&gt;

&lt;p&gt;This is not TPM specific thing, but we often see bitfield (the one with TPMA_ prefix) in TPM structure. Since TPM treats data in big endians, we have to swap it, but SwapBytes32 is for UINT32 and not for UINT32 bitfields. Therefore, we need to first convert it to UINT32. In order to convert bitfield to UINT32, you can define union as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;tpma_cc_uint32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;TPMA_CC&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;castbuf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;castbuf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="cm"&gt;/*TPMA_CC object*/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;castbuf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tpma_cc_uint32&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the code
&lt;/h2&gt;

&lt;p&gt;You will get this kind of output if it succeeded. If you get errors, you can check my previous posts on how to evaluate them.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rHttLWfL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n94486lp08x672wje76u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rHttLWfL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n94486lp08x672wje76u.jpg" alt="Image description" width="880" height="242"&gt;&lt;/a&gt;&lt;br&gt;
&lt;code&gt;0x240012A&lt;/code&gt; is &lt;code&gt;00 0 0 001 0 0 1 000000 0000000100101010&lt;/code&gt; so TPMA_CC values for TPM2_NV_DefineSpace are as follows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;commandIndex: 0x12A&lt;/li&gt;
&lt;li&gt;nv: 1&lt;/li&gt;
&lt;li&gt;extensive: 0&lt;/li&gt;
&lt;li&gt;flushed: 0&lt;/li&gt;
&lt;li&gt;cHandles: 1&lt;/li&gt;
&lt;li&gt;rHandle: 0&lt;/li&gt;
&lt;li&gt;V: 0&lt;/li&gt;
&lt;li&gt;Res: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TPM2_GetCapability is a command frequently used to check the current status of TPM&lt;/li&gt;
&lt;li&gt;How to set parameters of TPM2_GetCapability&lt;/li&gt;
&lt;li&gt;Name Prefix Convention of TPM macros&lt;/li&gt;
&lt;li&gt;How to convert bitfields to integer value in order to swap bytes&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>uefi</category>
      <category>tpm2</category>
      <category>edk2</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>TPM2_GetRandom from UEFI</title>
      <dc:creator>MachineHunter</dc:creator>
      <pubDate>Wed, 18 May 2022 18:39:30 +0000</pubDate>
      <link>https://dev.to/machinehunter/accessing-tpm20-from-uefi-module-sending-tpm2getrandom-140b</link>
      <guid>https://dev.to/machinehunter/accessing-tpm20-from-uefi-module-sending-tpm2getrandom-140b</guid>
      <description>&lt;p&gt;Using TPM2.0 from UEFI module is a painstaking task.&lt;br&gt;
TPM offers APIs called TSS (TCG Software Stack) for software to easily communicate with TPM. Also there are tools to interact with TPM via command line (i.e. &lt;a href="https://tpm2-tools.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;tpm2-tools&lt;/a&gt;). However, both runs above kernel so we can't use them from UEFI module.&lt;/p&gt;

&lt;p&gt;UEFI access to various devices via "protocol". TPM is also a device, so UEFI provides &lt;strong&gt;Tcg2Protocol&lt;/strong&gt; for communicating TPM. To let TPM do something, we need to send "TPM command" to the TPM. Tcg2Protocol has a function called "SubmitCommand" to do this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To be more precise, fTPM is not a physical device but you can use Tcg2Protocol to communicate with them just like discrete TPM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The format of TPM Command is defined in &lt;a href="https://trustedcomputinggroup.org/resource/tpm-library-specification/" rel="noopener noreferrer"&gt;TCG spec&lt;/a&gt;. TCG spec is consisted of 4 part so make sure to download all of these (Part 3 &amp;amp; 4 has two specs but using only the one which involves code is fine).&lt;/p&gt;

&lt;p&gt;Learning about TPM is also hard, since there are only few resources out there. Most popular resource you can use to understand about TPM is maybe &lt;a href="https://www.amazon.co.jp/Practical-Guide-TPM-2-0-2015-01-24/dp/B011DAFMK8" rel="noopener noreferrer"&gt;Practical Guide to TPM2.0&lt;/a&gt; which you can download kindle version from amazon for free, but both TCG spec and this book doesn't provides us &lt;strong&gt;sample code&lt;/strong&gt;. Therefore, it often takes you long time to write the first working code.&lt;/p&gt;

&lt;p&gt;It took me really long time to be able to write code accessing TPM from UEFI module, so I hope this series of article helps someone who is also having trouble.&lt;/p&gt;
&lt;h2&gt;
  
  
  Starting with very easy command: TPM2_GetRandom
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I strongly recommend implementing easy TPM command first&lt;/strong&gt;.　Implementation difficulty varies greatly between TPM commands, but even with easy TPM command, there are several &lt;em&gt;pitfalls&lt;/em&gt; that you must be aware of.&lt;/p&gt;

&lt;p&gt;I will be using &lt;a href="https://github.com/tianocore/edk2" rel="noopener noreferrer"&gt;EDK2&lt;/a&gt; to build UEFI module. Also, make sure the machine you're running this module has TPM2.0 (either fTPM or discrete TPM) and the bios supports TCG2 protocol.&lt;/p&gt;
&lt;h3&gt;
  
  
  EDK2 settings to use Tcg2Protocol
&lt;/h3&gt;

&lt;p&gt;Just add this in &lt;code&gt;.inf&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Protocols]
  gEfiTcg2ProtocolGuid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you can start using Tcg2Protocol like this (I will put the whole source code at the end).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Protocol/Tcg2Protocol.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;IndustryStandard/Tpm20.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;EFI_TCG2_PROTOCOL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;BootServices&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;LocateProtocol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiTcg2ProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOID&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SubmitCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Looking for TPM2_GetRandom format in TCG spec
&lt;/h3&gt;

&lt;p&gt;You can check the format in Part3 spec. Just Ctrl-F with command name, in this case, TPM2_GetRandom. You will see table like this.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvuvripunmg4ycdxdh1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvuvripunmg4ycdxdh1a.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Writing the code
&lt;/h3&gt;

&lt;p&gt;I recommend you to start with defining the structure just like the table above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#pragma pack(1)                                     
&lt;/span&gt;  &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;TPM2_COMMAND_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;bytesRequested&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_GET_RANDOM_COMMAND&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;TPM2_RESPONSE_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;TPM2B_DIGEST&lt;/span&gt; &lt;span class="n"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_GET_RANDOM_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                       
&lt;span class="cp"&gt;#pragma pack()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parameters in the header are common to all TPM command so specific struct is defined in Tpm20.h. Tpm20.h is located in &lt;code&gt;MdePkg/Include/IndustryStandard/Tpm20.h&lt;/code&gt; and I recommend looking this while writing.&lt;br&gt;
Also, &lt;strong&gt;using &lt;code&gt;#pragma pack(1)&lt;/code&gt; to disable alignment is one of the pitfalls&lt;/strong&gt; so don't forget this.&lt;/p&gt;

&lt;p&gt;Next, assign the Command parameters as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;TPM2_GET_RANDOM_COMMAND&lt;/span&gt; &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;TPM2_GET_RANDOM_RESPONSE&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ST_NO_SESSIONS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commandCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CC_GetRandom&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytesRequested&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;CmdBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytesRequested&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Session" is some authorization related thing, but we don't need this in this command. We request 16 bytes of random value in this command.&lt;br&gt;
&lt;strong&gt;You can see &lt;code&gt;SwapBytes&lt;/code&gt; in the code and this is another one of the pitfalls.&lt;/strong&gt; We have to send data to TPM in &lt;strong&gt;BIG ENDIAN&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SwapBytes&lt;/code&gt; is a EDK2 specific function and we need to specify bits at the end. In the spec's table it says, &lt;code&gt;TPC_CC_GetRandom&lt;/code&gt; has a type of &lt;code&gt;TPM_CC&lt;/code&gt; and I found out this is 32bit by searching &lt;code&gt;TPM_CC&lt;/code&gt; in Tpm20.h. It should be defined like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Table 11 - TPM_CC Constants (Numeric Order)&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;TPM_CC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, send command and parse response like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// send&lt;/span&gt;
&lt;span class="n"&gt;RecvBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SubmitCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"SubmitCommand Success!&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"stats: 0x%x (EFI_DEVICE_ERROR:0x%x, EFI_INVALID_PARAMETER:0x%x, EFI_BUFFER_TOO_SMALL:0x%x)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_DEVICE_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_INVALID_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_BUFFER_TOO_SMALL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// show result&lt;/span&gt;
&lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"ResponseCode is %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"generated value: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"%X"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't get &lt;code&gt;EFI_SUCCESS&lt;/code&gt;, then you might not have TPM2.0 or something is wrong with the TPM (I also had a problem that TPM2_CreatePrimary returns EFI_DEVICE_ERROR on fTPM). Other than that, &lt;strong&gt;all the error information is in the response code&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running the code
&lt;/h3&gt;

&lt;p&gt;If you get screen like this, then it's a success! (response code should be 0 if any command succeeded).&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu7ghie50qzip1fv57l0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu7ghie50qzip1fv57l0.jpg" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Evaluating errors
&lt;/h2&gt;

&lt;p&gt;Mostly, you'll get errors and response code will not be 0. It's hard to identify what is wrong since the only information given is this response code, but you can follow these steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decode response code by tpm2_rc_decode to know the abstract information of error&lt;/li&gt;
&lt;li&gt;Read each command's "Detailed Actions" section in TCG spec Part3 to know exactly where in the process you're stuck at&lt;/li&gt;
&lt;li&gt;Read the index of subsections in the TCG spec Part3 Chapter5 Command Processing to know what process you have passed and what you haven't&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Decode response code by tpm2_rc_decode to know the abstract information of error
&lt;/h3&gt;

&lt;p&gt;Firstly, you have to parse this response code. The most easy way is to use &lt;strong&gt;&lt;a href="https://tpm2-tools.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;tpm2-tools&lt;/a&gt;'s &lt;code&gt;tpm2_rc_decode&lt;/code&gt; command&lt;/strong&gt;. You can install tpm2-tools by &lt;code&gt;apt install tpm2-tools&lt;/code&gt;. For example, if the response code was &lt;code&gt;725&lt;/code&gt; in decimal, you can use this command like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;tpm2_rc_decode 725
tpm:parameter&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt;:structure is the wrong size
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can know that the second parameter's size is wrong from this message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read each command's "Detailed Actions" section in TCG spec Part3 to know exactly where in the process you're stuck at
&lt;/h3&gt;

&lt;p&gt;If this information is not enough, you can see each command's "Detailed Actions". Taking TPM2_NV_DefineSpace as an example, if you got an error &lt;code&gt;tpm:handle(1):inconsistent attributes&lt;/code&gt;, you can look at the "Detailed Actions" and find out what condition you didn't pass.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cn4gb7mk7r3550db6dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cn4gb7mk7r3550db6dm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Read the index of subsections in the TCG spec Part3 Chapter5 Command Processing to know what process you have passed and what you haven't
&lt;/h3&gt;

&lt;p&gt;You might also wonder, what part did you passed and what you didn't. Command Processing order can be found out by looking at index of Chapter5 of TCG spec Part3.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibwmst0k7d4focp9u9gb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibwmst0k7d4focp9u9gb.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
So, if you had parameter related error, it means you have passed all of the above part such as header validation or authorization checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;That's it for this post. Below is the summary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can't use tpm2-tools or TSS from UEFI&lt;/li&gt;
&lt;li&gt;How to setup EDK2 to use Tcg2Protocol&lt;/li&gt;
&lt;li&gt;You can use &lt;code&gt;Tcg2Protocol-&amp;gt;SubmitCommand&lt;/code&gt; to send command to TPM from UEFI&lt;/li&gt;
&lt;li&gt;Looking at TCG spec and Tpm20.h while writing the code is recommended&lt;/li&gt;
&lt;li&gt;You have to send data in Big Endian to TPM&lt;/li&gt;
&lt;li&gt;You have to disable alignment by &lt;code&gt;#pragma pack(1)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to evaluate error&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Full source code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Uefi.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Library/UefiLib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;Protocol/Tcg2Protocol.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;IndustryStandard/Tpm20.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack(1)
&lt;/span&gt;    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_COMMAND_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;bytesRequested&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_GET_RANDOM_COMMAND&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;TPM2_RESPONSE_HEADER&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;TPM2B_DIGEST&lt;/span&gt; &lt;span class="n"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;TPM2_GET_RANDOM_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;#pragma pack()
&lt;/span&gt;
&lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="nf"&gt;UefiMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_HANDLE&lt;/span&gt; &lt;span class="n"&gt;ImageHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_SYSTEM_TABLE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;EFI_TCG2_PROTOCOL&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;BootServices&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;LocateProtocol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gEfiTcg2ProtocolGuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VOID&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;TPM2_GET_RANDOM_COMMAND&lt;/span&gt; &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;TPM2_GET_RANDOM_RESPONSE&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_ST_NO_SESSIONS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commandCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TPM_CC_GetRandom&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytesRequested&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bytesRequested&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// send&lt;/span&gt;
    &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;EFI_STATUS&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;SubmitCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tcg2Protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CmdBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CmdBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT8&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;EFI_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"SubmitCommand Success!&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"stats: 0x%x (EFI_DEVICE_ERROR:0x%x, EFI_INVALID_PARAMETER:0x%x, EFI_BUFFER_TOO_SMALL:0x%x)&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_DEVICE_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_INVALID_PARAMETER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EFI_BUFFER_TOO_SMALL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="c1"&gt;// show result&lt;/span&gt;
    &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responseCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"ResponseCode is %d&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;UINT16&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SwapBytes16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"generated value: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"%X"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RecvBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;L"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>uefi</category>
      <category>tpm2</category>
      <category>edk2</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
