<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="ProgId" content="Word.Document">
<meta name="Generator" content="Microsoft Word 15">
<meta name="Originator" content="Microsoft Word 15">
<link rel="File-List" href="cid:filelist.xml@01D6B80B.823CC4E0"><link rel="Edit-Time-Data" href="cid:editdata.mso"><!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:Zoom>130</w:Zoom>
<w:DocumentKind>DocumentEmail</w:DocumentKind>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:EnvelopeVis/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:DoNotExpandShiftReturn/>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false" DefSemiHidden="false" DefQFormat="false" DefPriority="99" LatentStyleCount="376">
<w:LsdException Locked="false" Priority="0" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index 9"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" Name="toc 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footnote text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="header"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footer"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="index heading"/>
<w:LsdException Locked="false" Priority="35" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="table of figures"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="envelope address"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="envelope return"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="footnote reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="line number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="page number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="endnote reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="endnote text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="table of authorities"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="macro"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="toa heading"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Bullet 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Number 5"/>
<w:LsdException Locked="false" Priority="10" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Closing"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Signature"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="true" UnhideWhenUsed="true" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="List Continue 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Message Header"/>
<w:LsdException Locked="false" Priority="11" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Salutation"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Date"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text First Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text First Indent 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Note Heading"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Body Text Indent 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Block Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Hyperlink"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="FollowedHyperlink"/>
<w:LsdException Locked="false" Priority="22" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Document Map"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Plain Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="E-mail Signature"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Top of Form"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Bottom of Form"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Normal (Web)"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Acronym"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Address"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Cite"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Code"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Definition"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Keyboard"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Preformatted"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Sample"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Typewriter"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="HTML Variable"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="annotation subject"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="No List"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Outline List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Simple 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Classic 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Colorful 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Columns 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Grid 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table List 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table 3D effects 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Contemporary"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Elegant"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Professional"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Subtle 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Subtle 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Table Web 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Balloon Text"/>
<w:LsdException Locked="false" Priority="39" Name="Table Grid"/>
<w:LsdException Locked="false" SemiHidden="true" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" SemiHidden="true" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" QFormat="true" Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" QFormat="true" Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" QFormat="true" Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" QFormat="true" Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" QFormat="true" Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" QFormat="true" Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" SemiHidden="true" UnhideWhenUsed="true" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true" UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
<w:LsdException Locked="false" Priority="41" Name="Plain Table 1"/>
<w:LsdException Locked="false" Priority="42" Name="Plain Table 2"/>
<w:LsdException Locked="false" Priority="43" Name="Plain Table 3"/>
<w:LsdException Locked="false" Priority="44" Name="Plain Table 4"/>
<w:LsdException Locked="false" Priority="45" Name="Plain Table 5"/>
<w:LsdException Locked="false" Priority="40" Name="Grid Table Light"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 1"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 1"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 1"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 1"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 1"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 2"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 2"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 2"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 2"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 2"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 3"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 3"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 3"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 3"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 3"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 4"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 4"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 4"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 4"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 4"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 5"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 5"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 5"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 5"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 5"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light Accent 6"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 6"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 6"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 6"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 6"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 1"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 1"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 1"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 1"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 1"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 2"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 2"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 2"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 2"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 2"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 3"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 3"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 3"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 3"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 3"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 4"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 4"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 4"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 4"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 4"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 5"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 5"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 5"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 5"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 5"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light Accent 6"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 6"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 6"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 6"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 6"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful Accent 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Mention"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Smart Hyperlink"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Hashtag"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Unresolved Mention"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true" Name="Smart Link"/>
</w:LatentStyles>
</xml><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;
        mso-font-alt:"Calisto MT";
        mso-font-charset:0;
        mso-generic-font-family:roman;
        mso-font-pitch:variable;
        mso-font-signature:-536869121 1107305727 33554432 0 415 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;
        mso-font-alt:Calibri;
        mso-font-charset:0;
        mso-generic-font-family:swiss;
        mso-font-pitch:variable;
        mso-font-signature:-469750017 -1073732485 9 0 511 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {mso-style-unhide:no;
        mso-style-qformat:yes;
        mso-style-parent:"";
        margin:0in;
        margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-font-family:Calibri;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;
        text-underline:single;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-noshow:yes;
        mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;
        text-underline:single;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-style-unhide:no;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        mso-pagination:widow-orphan;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-font-family:Calibri;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        mso-style-noshow:yes;
        mso-style-unhide:no;
        mso-ansi-font-size:11.0pt;
        mso-bidi-font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-ascii-font-family:Calibri;
        mso-fareast-font-family:Calibri;
        mso-hansi-font-family:Calibri;
        mso-bidi-font-family:"Times New Roman";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        mso-default-props:yes;
        font-size:10.0pt;
        mso-ansi-font-size:10.0pt;
        mso-bidi-font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;
        mso-header-margin:.5in;
        mso-footer-margin:.5in;
        mso-paper-source:0;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 10]><style>/* Style Definitions */
table.MsoNormalTable
        {mso-style-name:"Table Normal";
        mso-tstyle-rowband-size:0;
        mso-tstyle-colband-size:0;
        mso-style-noshow:yes;
        mso-style-priority:99;
        mso-style-parent:"";
        mso-padding-alt:0in 5.4pt 0in 5.4pt;
        mso-para-margin:0in;
        mso-para-margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:10.0pt;
        font-family:"Times New Roman",serif;}
</style><![endif]--><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="#954F72" style="tab-interval:.5in">
<div class="WordSection1">
<p class="MsoNormal"><span style="mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:"Times New Roman"">Hi Kilian,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:"Times New Roman""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:"Times New Roman"">2983 was resolved by a previous commit.<span style="mso-spacerun:yes"> 
</span>Thank you for the reminder to update the BZ with the details.<span style="mso-spacerun:yes"> 
</span>It is closed now.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:"Times New Roman""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:"Times New Roman"">Mike<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-bidi-font-family:"Times New Roman""><o:p> </o:p></span></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="mso-fareast-font-family:"Times New Roman"">From:</span></b><span style="mso-fareast-font-family:"Times New Roman""> devel@edk2.groups.io <devel@edk2.groups.io>
<b>On Behalf Of </b>Kilian Kegel<br>
<b>Sent:</b> Tuesday, November 10, 2020 8:17 PM<br>
<b>To:</b> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>; Michael Kubacki <michael.kubacki@outlook.com><br>
<b>Cc:</b> Qian, Yi <yi.qian@intel.com>; Sun, Zailiang <zailiang.sun@intel.com><br>
<b>Subject:</b> Re: [edk2-devel] [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="DE" style="mso-ansi-language:DE">Hi all,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="DE" style="mso-ansi-language:DE"><o:p> </o:p></span></p>
<p class="MsoNormal">if this patch also affects <a href="https://bugzilla.tianocore.org/show_bug.cgi?id=2983">
https://bugzilla.tianocore.org/show_bug.cgi?id=2983</a>, please close it.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal">Kilian<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-outline-level:1"><b>Von: </b><a href="mailto:michael.d.kinney@intel.com">Michael D Kinney</a><br>
<b>Gesendet: </b>Wednesday, November 11, 2020 4:03 AM<br>
<b>An: </b><a href="mailto:michael.kubacki@outlook.com">Michael Kubacki</a>; <a href="mailto:devel@edk2.groups.io">
devel@edk2.groups.io</a>; <a href="mailto:michael.d.kinney@intel.com">Kinney, Michael D</a><br>
<b>Cc: </b><a href="mailto:yi.qian@intel.com">Qian, Yi</a>; <a href="mailto:zailiang.sun@intel.com">
Sun, Zailiang</a><br>
<b>Betreff: </b>Re: [edk2-devel] [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt">Hi Michael,<br>
<br>
This patch has been merged.<br>
<br>
Thanks,<br>
<br>
Mike<br>
<br>
> -----Original Message-----<br>
> From: Michael Kubacki <<a href="mailto:michael.kubacki@outlook.com">michael.kubacki@outlook.com</a>><br>
> Sent: Thursday, November 5, 2020 12:36 PM<br>
> To: Kinney, Michael D <<a href="mailto:michael.d.kinney@intel.com">michael.d.kinney@intel.com</a>>;
<a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a><br>
> Cc: Qian, Yi <<a href="mailto:yi.qian@intel.com">yi.qian@intel.com</a>>; Sun, Zailiang <<a href="mailto:zailiang.sun@intel.com">zailiang.sun@intel.com</a>><br>
> Subject: Re: [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility<br>
> <br>
> Hi Mike,<br>
> <br>
> I saw other Vlv2TbltDevicePkg patches were merged yesterday. Do you know<br>
> when this patch will be merged?<br>
> <br>
> Thanks,<br>
> Michael<br>
> <br>
> On 10/28/2020 6:12 PM, Kinney, Michael D wrote:<br>
> > Reviewed-by: Michael D Kinney <<a href="mailto:michael.d.kinney@intel.com">michael.d.kinney@intel.com</a>><br>
> ><br>
> > I also verified build and boot and FMP based capsule updates work as expected.<br>
> ><br>
> > Tested-by: Michael D Kinney <<a href="mailto:Michael.d.kinney@intel.com">Michael.d.kinney@intel.com</a>><br>
> ><br>
> > Thanks,<br>
> ><br>
> > Mike<br>
> ><br>
> ><br>
> >> -----Original Message-----<br>
> >> From: <a href="mailto:michael.kubacki@outlook.com">michael.kubacki@outlook.com</a> <<a href="mailto:michael.kubacki@outlook.com">michael.kubacki@outlook.com</a>><br>
> >> Sent: Thursday, October 1, 2020 2:59 PM<br>
> >> To: <a href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a><br>
> >> Cc: Kinney, Michael D <<a href="mailto:michael.d.kinney@intel.com">michael.d.kinney@intel.com</a>>; Qian, Yi <<a href="mailto:yi.qian@intel.com">yi.qian@intel.com</a>>; Sun, Zailiang<br>
> <<a href="mailto:zailiang.sun@intel.com">zailiang.sun@intel.com</a>><br>
> >> Subject: [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility<br>
> >><br>
> >> From: Michael Kubacki <<a href="mailto:michael.kubacki@microsoft.com">michael.kubacki@microsoft.com</a>><br>
> >><br>
> >> Makes the changes necessary for these library instances of<br>
> >> FmpDeviceLib to be compatible with new functions added recently<br>
> >> to FmpDeviceLib.<br>
> >><br>
> >> Two new functions were introduced in FmpDeviceLib to allow a<br>
> >> library instance to return a Last Attempt Status code during<br>
> >> check image and set image operations:<br>
> >>    1. FmpDeviceCheckImageWithStatus ( )<br>
> >>    2. FmpDeviceSetImageWithStatus ( )<br>
> >><br>
> >> FmpDxe (in FmpDevicePkg) will begin calling these new functions<br>
> >> instead of the previous functions. Therefore, this change:<br>
> >>    1. Adds these functions to Vlv2TbltDevicePkg implementations<br>
> >>    2. Moves the main functionality to these new functions<br>
> >>    3. Updates the old functions to call the new functions<br>
> >>       (for backward compatibility)<br>
> >><br>
> >> Note: As of this commit, the Vlv2TbltDevicePkg build is broken<br>
> >> due to:<br>
> >>    1. A required RngLib library instance not defined by the platform<br>
> >>    2. Other FMP libraries not being defined by the platform<br>
> >>       (e.g. FmpDependencyLib, FmpDependencyCheckLib, etc.)<br>
> >><br>
> >> Those changes were fixed locally to test the changes in this commit<br>
> >> but maintainers should make the proper changes for those issues.<br>
> >><br>
> >> Cc: Michael D Kinney <<a href="mailto:michael.d.kinney@intel.com">michael.d.kinney@intel.com</a>><br>
> >> Cc: Yi Qian <<a href="mailto:yi.qian@intel.com">yi.qian@intel.com</a>><br>
> >> Cc: Zailiang Sun <<a href="mailto:zailiang.sun@intel.com">zailiang.sun@intel.com</a>><br>
> >> Signed-off-by: Michael Kubacki <<a href="mailto:michael.kubacki@microsoft.com">michael.kubacki@microsoft.com</a>><br>
> >> ---<br>
> >><br>
> >> Notes:<br>
> >>      Only build was checked, I do not have access to a<br>
> >>      VLV2 device for testing.<br>
> >><br>
> >>   Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c       | 299 +++++++++++++++-----<br>
> >>   Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c | 284 ++++++++++++++-----<br>
> >>   2 files changed, 446 insertions(+), 137 deletions(-)<br>
> >><br>
> >> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c<br>
> >> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c<br>
> >> index d8c9036012ad..df8a36d9854c 100644<br>
> >> --- a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c<br>
> >> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c<br>
> >> @@ -1,6 +1,6 @@<br>
> >>   /**<br>
> >><br>
> >> -Copyright (c) 2016, Microsoft Corporation.  All rights reserved.<br>
> >> +Copyright (c) Microsoft Corporation.<BR><br>
> >>   Copyright (c) 2019, Intel Corporation.  All rights reserved.<br>
> >><br>
> >>   SPDX-License-Identifier: BSD-2-Clause-Patent<br>
> >> @@ -8,7 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent<br>
> >>   **/<br>
> >><br>
> >>   #include <PiDxe.h><br>
> >> -<br>
> >> +#include <LastAttemptStatus.h><br>
> >> +#include <Guid/SystemResourceTable.h><br>
> >>   #include <Library/FmpDeviceLib.h><br>
> >><br>
> >>   #include <Library/DebugLib.h><br>
> >> @@ -444,20 +445,17 @@ FmpDeviceGetImage (<br>
> >>   }<br>
> >><br>
> >>   /**<br>
> >> -  Updates the firmware image of the device.<br>
> >> -<br>
> >> -  This function updates the hardware with the new firmware image.  This function<br>
> >> -  returns EFI_UNSUPPORTED if the firmware image is not updatable.  If the<br>
> >> -  firmware image is updatable, the function should perform the following minimal<br>
> >> -  validations before proceeding to do the firmware image update.<br>
> >> -    - Validate the image is a supported image for this device.  The function<br>
> >> -      returns EFI_ABORTED if the image is unsupported.  The function can<br>
> >> -      optionally provide more detailed information on why the image is not a<br>
> >> -      supported image.<br>
> >> -    - Validate the data from VendorCode if not null.  Image validation must be<br>
> >> -      performed before VendorCode data validation.  VendorCode data is ignored<br>
> >> -      or considered invalid if image validation failed.  The function returns<br>
> >> -      EFI_ABORTED if the data is invalid.<br>
> >> +  Updates a firmware device with a new firmware image.  This function returns<br>
> >> +  EFI_UNSUPPORTED if the firmware image is not updatable.  If the firmware image<br>
> >> +  is updatable, the function should perform the following minimal validations<br>
> >> +  before proceeding to do the firmware image update.<br>
> >> +    - Validate that the image is a supported image for this firmware device.<br>
> >> +      Return EFI_ABORTED if the image is not supported.  Additional details<br>
> >> +      on why the image is not a supported image may be returned in AbortReason.<br>
> >> +    - Validate the data from VendorCode if is not NULL.  Firmware image<br>
> >> +      validation must be performed before VendorCode data validation.<br>
> >> +      VendorCode data is ignored or considered invalid if image validation<br>
> >> +      fails.  Return EFI_ABORTED if the VendorCode data is invalid.<br>
> >><br>
> >>     VendorCode enables vendor to implement vendor-specific firmware image update<br>
> >>     policy.  Null if the caller did not specify the policy or use the default<br>
> >> @@ -470,38 +468,56 @@ FmpDeviceGetImage (<br>
> >>     have the option to provide a more detailed description of the abort reason to<br>
> >>     the caller.<br>
> >><br>
> >> -  @param[in]  Image             Points to the new image.<br>
> >> -  @param[in]  ImageSize         Size of the new image in bytes.<br>
> >> +  @param[in]  Image             Points to the new firmware image.<br>
> >> +  @param[in]  ImageSize         Size, in bytes, of the new firmware image.<br>
> >>     @param[in]  VendorCode        This enables vendor to implement vendor-specific<br>
> >> -                                firmware image update policy. Null indicates the<br>
> >> -                                caller did not specify the policy or use the<br>
> >> +                                firmware image update policy.  NULL indicates<br>
> >> +                                the caller did not specify the policy or use the<br>
> >>                                   default policy.<br>
> >> -  @param[in]  Progress          A function used by the driver to report the<br>
> >> -                                progress of the firmware update.<br>
> >> -  @param[in]  CapsuleFwVersion  FMP Payload Header version of the image.<br>
> >> -  @param[out] AbortReason       A pointer to a pointer to a null-terminated<br>
> >> -                                string providing more details for the aborted<br>
> >> -                                operation. The buffer is allocated by this<br>
> >> -                                function with AllocatePool(), and it is the<br>
> >> -                                caller's responsibility to free it with a call<br>
> >> -                                to FreePool().<br>
> >> +  @param[in]  Progress          A function used to report the progress of<br>
> >> +                                updating the firmware device with the new<br>
> >> +                                firmware image.<br>
> >> +  @param[in]  CapsuleFwVersion  The version of the new firmware image from the<br>
> >> +                                update capsule that provided the new firmware<br>
> >> +                                image.<br>
> >> +  @param[out] AbortReason       A pointer to a pointer to a Null-terminated<br>
> >> +                                Unicode string providing more details on an<br>
> >> +                                aborted operation. The buffer is allocated by<br>
> >> +                                this function with<br>
> >> +                                EFI_BOOT_SERVICES.AllocatePool().  It is the<br>
> >> +                                caller's responsibility to free this buffer with<br>
> >> +                                EFI_BOOT_SERVICES.FreePool().<br>
> >> +  @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt<br>
> >> +                                status to report back to the ESRT table in case<br>
> >> +                                of error. This value will only be checked when this<br>
> >> +                                function returns an error.<br>
> >><br>
> >> -  @retval EFI_SUCCESS            The device was successfully updated with the<br>
> >> -                                 new image.<br>
> >> -  @retval EFI_ABORTED            The operation is aborted.<br>
> >> +                                The return status code must fall in the range of<br>
> >> +                                LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to<br>
> >> +                                LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE.<br>
> >> +<br>
> >> +                                If the value falls outside this range, it will be converted<br>
> >> +                                to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL.<br>
> >> +<br>
> >> +  @retval EFI_SUCCESS            The firmware device was successfully updated<br>
> >> +                                 with the new firmware image.<br>
> >> +  @retval EFI_ABORTED            The operation is aborted.  Additional details<br>
> >> +                                 are provided in AbortReason.<br>
> >>     @retval EFI_INVALID_PARAMETER  The Image was NULL.<br>
> >> +  @retval EFI_INVALID_PARAMETER  LastAttemptStatus was NULL.<br>
> >>     @retval EFI_UNSUPPORTED        The operation is not supported.<br>
> >><br>
> >>   **/<br>
> >>   EFI_STATUS<br>
> >>   EFIAPI<br>
> >> -FmpDeviceSetImage (<br>
> >> +FmpDeviceSetImageWithStatus (<br>
> >>     IN  CONST VOID                                     *Image,<br>
> >>     IN  UINTN                                          ImageSize,<br>
> >> -  IN  CONST VOID                                     *VendorCode,<br>
> >> -  IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,<br>
> >> +  IN  CONST VOID                                     *VendorCode,       OPTIONAL<br>
> >> +  IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,          OPTIONAL<br>
> >>     IN  UINT32                                         CapsuleFwVersion,<br>
> >> -  OUT CHAR16                                         **AbortReason<br>
> >> +  OUT CHAR16                                         **AbortReason,<br>
> >> +  OUT UINT32                                         *LastAttemptStatus<br>
> >>     )<br>
> >>   {<br>
> >>     EFI_STATUS          Status;<br>
> >> @@ -513,25 +529,27 @@ FmpDeviceSetImage (<br>
> >>     UINTN               BytesWritten;<br>
> >><br>
> >>     Updateable = 0;<br>
> >> -  Status = FmpDeviceCheckImage (Image, ImageSize, &Updateable);<br>
> >> +  Status = FmpDeviceCheckImageWithStatus (Image, ImageSize, &Updateable, LastAttemptStatus);<br>
> >>     if (EFI_ERROR (Status)) {<br>
> >> -    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image failed with %r.\n", Status));<br>
> >> +    DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Check Image failed with %r.\n", Status));<br>
> >>       return Status;<br>
> >>     }<br>
> >><br>
> >>     if (Updateable != IMAGE_UPDATABLE_VALID) {<br>
> >> -    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image returned that the Image was not valid for update.  Updatable<br>
> >> value = 0x%X.\n", Updateable));<br>
> >> +    DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Check Image returned that the Image was not valid for update.<br>
> >> Updatable value = 0x%X.\n", Updateable));<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >>       return EFI_ABORTED;<br>
> >>     }<br>
> >><br>
> >>     if (Progress == NULL) {<br>
> >> -    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Invalid progress callback\n"));<br>
> >> +    DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Invalid progress callback\n"));<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >>       return EFI_INVALID_PARAMETER;<br>
> >>     }<br>
> >><br>
> >>     Status = Progress (15);<br>
> >>     if (EFI_ERROR (Status)) {<br>
> >> -    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status));<br>
> >> +    DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback failed with Status %r.\n", Status));<br>
> >>     }<br>
> >><br>
> >>     //<br>
> >> @@ -539,7 +557,7 @@ FmpDeviceSetImage (<br>
> >>     //<br>
> >>     Progress (20);<br>
> >>     if (EFI_ERROR (Status)) {<br>
> >> -    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status));<br>
> >> +    DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback failed with Status %r.\n", Status));<br>
> >>     }<br>
> >><br>
> >>     //<br>
> >> @@ -553,11 +571,11 @@ FmpDeviceSetImage (<br>
> >><br>
> >>   //    Progress (Percentage);<br>
> >>   //    if (EFI_ERROR (Status)) {<br>
> >> -//      DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status));<br>
> >> +//      DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback failed with Status %r.\n", Status));<br>
> >>   //    }<br>
> >>     }<br>
> >><br>
> >> -  DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %d Images ...\n", ARRAY_SIZE (mUpdateConfigData)));<br>
> >> +  DEBUG ((DEBUG_INFO, "FmpDeviceSetImageWithStatus - %d Images ...\n", ARRAY_SIZE (mUpdateConfigData)));<br>
> >><br>
> >>     if (ARRAY_SIZE (mUpdateConfigData) == 0) {<br>
> >>       DEBUG((DEBUG_INFO, "PlatformUpdate: BaseAddress - 0x%lx ImageOffset - 0x%x Length - 0x%x\n", 0, 0, ImageSize));<br>
> >> @@ -605,11 +623,173 @@ FmpDeviceSetImage (<br>
> >>       BytesWritten += ConfigData->Length;<br>
> >>     }<br>
> >><br>
> >> -  DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %r\n", Status));<br>
> >> +  DEBUG ((DEBUG_INFO, "FmpDeviceSetImageWithStatus - %r\n", Status));<br>
> >> +<br>
> >> +  if (EFI_ERROR (Status)) {<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +  }<br>
> >><br>
> >>     return Status;<br>
> >>   }<br>
> >><br>
> >> +/**<br>
> >> +  Updates the firmware image of the device.<br>
> >> +<br>
> >> +  This function updates the hardware with the new firmware image.  This function<br>
> >> +  returns EFI_UNSUPPORTED if the firmware image is not updatable.  If the<br>
> >> +  firmware image is updatable, the function should perform the following minimal<br>
> >> +  validations before proceeding to do the firmware image update.<br>
> >> +    - Validate the image is a supported image for this device.  The function<br>
> >> +      returns EFI_ABORTED if the image is unsupported.  The function can<br>
> >> +      optionally provide more detailed information on why the image is not a<br>
> >> +      supported image.<br>
> >> +    - Validate the data from VendorCode if not null.  Image validation must be<br>
> >> +      performed before VendorCode data validation.  VendorCode data is ignored<br>
> >> +      or considered invalid if image validation failed.  The function returns<br>
> >> +      EFI_ABORTED if the data is invalid.<br>
> >> +<br>
> >> +  VendorCode enables vendor to implement vendor-specific firmware image update<br>
> >> +  policy.  Null if the caller did not specify the policy or use the default<br>
> >> +  policy.  As an example, vendor can implement a policy to allow an option to<br>
> >> +  force a firmware image update when the abort reason is due to the new firmware<br>
> >> +  image version is older than the current firmware image version or bad image<br>
> >> +  checksum.  Sensitive operations such as those wiping the entire firmware image<br>
> >> +  and render the device to be non-functional should be encoded in the image<br>
> >> +  itself rather than passed with the VendorCode.  AbortReason enables vendor to<br>
> >> +  have the option to provide a more detailed description of the abort reason to<br>
> >> +  the caller.<br>
> >> +<br>
> >> +  @param[in]  Image             Points to the new image.<br>
> >> +  @param[in]  ImageSize         Size of the new image in bytes.<br>
> >> +  @param[in]  VendorCode        This enables vendor to implement vendor-specific<br>
> >> +                                firmware image update policy. Null indicates the<br>
> >> +                                caller did not specify the policy or use the<br>
> >> +                                default policy.<br>
> >> +  @param[in]  Progress          A function used by the driver to report the<br>
> >> +                                progress of the firmware update.<br>
> >> +  @param[in]  CapsuleFwVersion  FMP Payload Header version of the image.<br>
> >> +  @param[out] AbortReason       A pointer to a pointer to a null-terminated<br>
> >> +                                string providing more details for the aborted<br>
> >> +                                operation. The buffer is allocated by this<br>
> >> +                                function with AllocatePool(), and it is the<br>
> >> +                                caller's responsibility to free it with a call<br>
> >> +                                to FreePool().<br>
> >> +<br>
> >> +  @retval EFI_SUCCESS            The device was successfully updated with the<br>
> >> +                                 new image.<br>
> >> +  @retval EFI_ABORTED            The operation is aborted.<br>
> >> +  @retval EFI_INVALID_PARAMETER  The Image was NULL.<br>
> >> +  @retval EFI_UNSUPPORTED        The operation is not supported.<br>
> >> +<br>
> >> +**/<br>
> >> +EFI_STATUS<br>
> >> +EFIAPI<br>
> >> +FmpDeviceSetImage (<br>
> >> +  IN  CONST VOID                                     *Image,<br>
> >> +  IN  UINTN                                          ImageSize,<br>
> >> +  IN  CONST VOID                                     *VendorCode,<br>
> >> +  IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,<br>
> >> +  IN  UINT32                                         CapsuleFwVersion,<br>
> >> +  OUT CHAR16                                         **AbortReason<br>
> >> +  )<br>
> >> +{<br>
> >> +  UINT32  LastAttemptStatus;<br>
> >> +<br>
> >> +  return  FmpDeviceSetImageWithStatus (<br>
> >> +            Image,<br>
> >> +            ImageSize,<br>
> >> +            VendorCode,<br>
> >> +            Progress,<br>
> >> +            CapsuleFwVersion,<br>
> >> +            AbortReason,<br>
> >> +            &LastAttemptStatus<br>
> >> +            );<br>
> >> +}<br>
> >> +<br>
> >> +/**<br>
> >> +  Checks if a new firmware image is valid for the firmware device.  This<br>
> >> +  function allows firmware update operation to validate the firmware image<br>
> >> +  before FmpDeviceSetImage() is called.<br>
> >> +<br>
> >> +  @param[in]  Image               Points to a new firmware image.<br>
> >> +  @param[in]  ImageSize           Size, in bytes, of a new firmware image.<br>
> >> +  @param[out] ImageUpdatable      Indicates if a new firmware image is valid for<br>
> >> +                                  a firmware update to the firmware device.  The<br>
> >> +                                  following values from the Firmware Management<br>
> >> +                                  Protocol are supported:<br>
> >> +                                    IMAGE_UPDATABLE_VALID<br>
> >> +                                    IMAGE_UPDATABLE_INVALID<br>
> >> +                                    IMAGE_UPDATABLE_INVALID_TYPE<br>
> >> +                                    IMAGE_UPDATABLE_INVALID_OLD<br>
> >> +                                    IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE<br>
> >> +  @param[out] LastAttemptStatus   A pointer to a UINT32 that holds the last attempt<br>
> >> +                                  status to report back to the ESRT table in case<br>
> >> +                                  of error. This value will only be checked when this<br>
> >> +                                  function returns an error.<br>
> >> +<br>
> >> +                                  The return status code must fall in the range of<br>
> >> +                                  LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to<br>
> >> +                                  LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE.<br>
> >> +<br>
> >> +                                  If the value falls outside this range, it will be converted<br>
> >> +                                  to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL.<br>
> >> +<br>
> >> +  @retval EFI_SUCCESS            The image was successfully checked.  Additional<br>
> >> +                                 status information is returned in<br>
> >> +                                 ImageUpdatable.<br>
> >> +  @retval EFI_INVALID_PARAMETER  Image is NULL.<br>
> >> +  @retval EFI_INVALID_PARAMETER  ImageUpdatable is NULL.<br>
> >> +  @retval EFI_INVALID_PARAMETER  LastAttemptStatus is NULL.<br>
> >> +<br>
> >> +**/<br>
> >> +EFI_STATUS<br>
> >> +EFIAPI<br>
> >> +FmpDeviceCheckImageWithStatus (<br>
> >> +  IN  CONST VOID  *Image,<br>
> >> +  IN  UINTN       ImageSize,<br>
> >> +  OUT UINT32      *ImageUpdatable,<br>
> >> +  OUT UINT32      *LastAttemptStatus<br>
> >> +  )<br>
> >> +{<br>
> >> +  if (LastAttemptStatus == NULL) {<br>
> >> +    DEBUG ((DEBUG_ERROR, "CheckImageWithStatus - LastAttemptStatus Pointer Parameter is NULL.\n"));<br>
> >> +    return EFI_INVALID_PARAMETER;<br>
> >> +  }<br>
> >> +  *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;<br>
> >> +<br>
> >> +  if (ImageUpdatable == NULL) {<br>
> >> +    DEBUG((DEBUG_ERROR, "CheckImageWithStatus - ImageUpdatable Pointer Parameter is NULL.\n"));<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +    return EFI_INVALID_PARAMETER;<br>
> >> +  }<br>
> >> +<br>
> >> +  //<br>
> >> +  //Set to valid and then if any tests fail it will update this flag.<br>
> >> +  //<br>
> >> +  *ImageUpdatable = IMAGE_UPDATABLE_VALID;<br>
> >> +<br>
> >> +  if (Image == NULL) {<br>
> >> +    DEBUG((DEBUG_ERROR, "CheckImageWithStatus - Image Pointer Parameter is NULL.\n"));<br>
> >> +    //<br>
> >> +    // Not sure if this is needed<br>
> >> +    //<br>
> >> +    *ImageUpdatable = IMAGE_UPDATABLE_INVALID;<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +    return EFI_INVALID_PARAMETER;<br>
> >> +  }<br>
> >> +<br>
> >> +  //<br>
> >> +  // Make sure the image size is correct<br>
> >> +  //<br>
> >> +  if (ImageSize != PcdGet32 (PcdBiosRomSize)) {<br>
> >> +    *ImageUpdatable = IMAGE_UPDATABLE_INVALID;<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +    return EFI_INVALID_PARAMETER;<br>
> >> +  }<br>
> >> +<br>
> >> +  return EFI_SUCCESS;<br>
> >> +}<br>
> >> +<br>
> >>   /**<br>
> >>   Checks if the firmware image is valid for the device.<br>
> >><br>
> >> @@ -633,34 +813,9 @@ FmpDeviceCheckImage (<br>
> >>     OUT UINT32      *ImageUpdateable<br>
> >>     )<br>
> >>   {<br>
> >> -  if (ImageUpdateable == NULL) {<br>
> >> -    DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is NULL.\n"));<br>
> >> -    return EFI_INVALID_PARAMETER;<br>
> >> -  }<br>
> >> +  UINT32  LastAttemptStatus;<br>
> >><br>
> >> -  //<br>
> >> -  //Set to valid and then if any tests fail it will update this flag.<br>
> >> -  //<br>
> >> -  *ImageUpdateable = IMAGE_UPDATABLE_VALID;<br>
> >> -<br>
> >> -  if (Image == NULL) {<br>
> >> -    DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n"));<br>
> >> -    //<br>
> >> -    // Not sure if this is needed<br>
> >> -    //<br>
> >> -    *ImageUpdateable = IMAGE_UPDATABLE_INVALID;<br>
> >> -    return EFI_INVALID_PARAMETER;<br>
> >> -  }<br>
> >> -<br>
> >> -  //<br>
> >> -  // Make sure the image size is correct<br>
> >> -  //<br>
> >> -  if (ImageSize != PcdGet32 (PcdBiosRomSize)) {<br>
> >> -    *ImageUpdateable = IMAGE_UPDATABLE_INVALID;<br>
> >> -    return EFI_INVALID_PARAMETER;<br>
> >> -  }<br>
> >> -<br>
> >> -  return EFI_SUCCESS;<br>
> >> +  return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdateable, &LastAttemptStatus);<br>
> >>   }<br>
> >><br>
> >>   /**<br>
> >> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c<br>
> >> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c<br>
> >> index db0f238ea534..132b60844ad4 100644<br>
> >> --- a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c<br>
> >> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c<br>
> >> @@ -1,6 +1,6 @@<br>
> >>   /**<br>
> >><br>
> >> -Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR><br>
> >> +Copyright (c) Microsoft Corporation.<BR><br>
> >>   Copyright (c) 2019, Intel Corporation. All rights reserved.<BR><br>
> >><br>
> >>   SPDX-License-Identifier: BSD-2-Clause-Patent<br>
> >> @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent<br>
> >><br>
> >><br>
> >>   #include <PiDxe.h><br>
> >> +#include <LastAttemptStatus.h><br>
> >> +#include <Guid/SystemResourceTable.h><br>
> >>   #include <Library/DebugLib.h><br>
> >>   #include <Protocol/FirmwareManagement.h><br>
> >>   #include <Library/BaseLib.h><br>
> >> @@ -345,6 +347,131 @@ Return Value:<br>
> >>   }//GetImage()<br>
> >><br>
> >><br>
> >> +/**<br>
> >> +  Updates a firmware device with a new firmware image.  This function returns<br>
> >> +  EFI_UNSUPPORTED if the firmware image is not updatable.  If the firmware image<br>
> >> +  is updatable, the function should perform the following minimal validations<br>
> >> +  before proceeding to do the firmware image update.<br>
> >> +    - Validate that the image is a supported image for this firmware device.<br>
> >> +      Return EFI_ABORTED if the image is not supported.  Additional details<br>
> >> +      on why the image is not a supported image may be returned in AbortReason.<br>
> >> +    - Validate the data from VendorCode if is not NULL.  Firmware image<br>
> >> +      validation must be performed before VendorCode data validation.<br>
> >> +      VendorCode data is ignored or considered invalid if image validation<br>
> >> +      fails.  Return EFI_ABORTED if the VendorCode data is invalid.<br>
> >> +<br>
> >> +  VendorCode enables vendor to implement vendor-specific firmware image update<br>
> >> +  policy.  Null if the caller did not specify the policy or use the default<br>
> >> +  policy.  As an example, vendor can implement a policy to allow an option to<br>
> >> +  force a firmware image update when the abort reason is due to the new firmware<br>
> >> +  image version is older than the current firmware image version or bad image<br>
> >> +  checksum.  Sensitive operations such as those wiping the entire firmware image<br>
> >> +  and render the device to be non-functional should be encoded in the image<br>
> >> +  itself rather than passed with the VendorCode.  AbortReason enables vendor to<br>
> >> +  have the option to provide a more detailed description of the abort reason to<br>
> >> +  the caller.<br>
> >> +<br>
> >> +  @param[in]  Image             Points to the new firmware image.<br>
> >> +  @param[in]  ImageSize         Size, in bytes, of the new firmware image.<br>
> >> +  @param[in]  VendorCode        This enables vendor to implement vendor-specific<br>
> >> +                                firmware image update policy.  NULL indicates<br>
> >> +                                the caller did not specify the policy or use the<br>
> >> +                                default policy.<br>
> >> +  @param[in]  Progress          A function used to report the progress of<br>
> >> +                                updating the firmware device with the new<br>
> >> +                                firmware image.<br>
> >> +  @param[in]  CapsuleFwVersion  The version of the new firmware image from the<br>
> >> +                                update capsule that provided the new firmware<br>
> >> +                                image.<br>
> >> +  @param[out] AbortReason       A pointer to a pointer to a Null-terminated<br>
> >> +                                Unicode string providing more details on an<br>
> >> +                                aborted operation. The buffer is allocated by<br>
> >> +                                this function with<br>
> >> +                                EFI_BOOT_SERVICES.AllocatePool().  It is the<br>
> >> +                                caller's responsibility to free this buffer with<br>
> >> +                                EFI_BOOT_SERVICES.FreePool().<br>
> >> +  @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt<br>
> >> +                                status to report back to the ESRT table in case<br>
> >> +                                of error. This value will only be checked when this<br>
> >> +                                function returns an error.<br>
> >> +<br>
> >> +                                The return status code must fall in the range of<br>
> >> +                                LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to<br>
> >> +                                LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE.<br>
> >> +<br>
> >> +                                If the value falls outside this range, it will be converted<br>
> >> +                                to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL.<br>
> >> +<br>
> >> +  @retval EFI_SUCCESS            The firmware device was successfully updated<br>
> >> +                                 with the new firmware image.<br>
> >> +  @retval EFI_ABORTED            The operation is aborted.  Additional details<br>
> >> +                                 are provided in AbortReason.<br>
> >> +  @retval EFI_INVALID_PARAMETER  The Image was NULL.<br>
> >> +  @retval EFI_INVALID_PARAMETER  LastAttemptStatus was NULL.<br>
> >> +  @retval EFI_UNSUPPORTED        The operation is not supported.<br>
> >> +<br>
> >> +**/<br>
> >> +EFI_STATUS<br>
> >> +EFIAPI<br>
> >> +FmpDeviceSetImageWithStatus (<br>
> >> +  IN  CONST VOID                                     *Image,<br>
> >> +  IN  UINTN                                          ImageSize,<br>
> >> +  IN  CONST VOID                                     *VendorCode,       OPTIONAL<br>
> >> +  IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,          OPTIONAL<br>
> >> +  IN  UINT32                                         CapsuleFwVersion,<br>
> >> +  OUT CHAR16                                         **AbortReason,<br>
> >> +  OUT UINT32                                         *LastAttemptStatus<br>
> >> +  )<br>
> >> +{<br>
> >> +    EFI_STATUS Status                         = EFI_SUCCESS;<br>
> >> +    UINT32 Updateable                         = 0;<br>
> >> +<br>
> >> +    Status = FmpDeviceCheckImageWithStatus (Image, ImageSize, &Updateable, LastAttemptStatus);<br>
> >> +    if (EFI_ERROR(Status))<br>
> >> +    {<br>
> >> +        DEBUG((DEBUG_ERROR, "SetImageWithStatus  - Check Image failed with %r.\n", Status));<br>
> >> +        goto cleanup;<br>
> >> +    }<br>
> >> +<br>
> >> +    if (Updateable != IMAGE_UPDATABLE_VALID)<br>
> >> +    {<br>
> >> +        DEBUG((DEBUG_ERROR, "SetImageWithStatus  - Check Image returned that the Image was not valid for update.<br>
> >> Updatable value = 0x%X.\n", Updateable));<br>
> >> +        Status = EFI_ABORTED;<br>
> >> +        goto cleanup;<br>
> >> +    }<br>
> >> +<br>
> >> +    if (Progress == NULL)<br>
> >> +    {<br>
> >> +        DEBUG((DEBUG_ERROR, "SetImageWithStatus  - Invalid progress callback\n"));<br>
> >> +        Status = EFI_INVALID_PARAMETER;<br>
> >> +        goto cleanup;<br>
> >> +    }<br>
> >> +<br>
> >> +    Status = Progress(15);<br>
> >> +    if (EFI_ERROR(Status))<br>
> >> +    {<br>
> >> +        DEBUG((DEBUG_ERROR, "SetImageWithStatus  - Progress Callback failed with Status %r.\n", Status));<br>
> >> +    }<br>
> >> +<br>
> >> +    {<br>
> >> +      UINTN  p;<br>
> >> +<br>
> >> +      for (p = 20; p < 100; p++) {<br>
> >> +        gBS->Stall (100000);  //us  = 0.1 seconds<br>
> >> +        Progress (p);<br>
> >> +      }<br>
> >> +    }<br>
> >> +<br>
> >> +    //TODO: add support for VendorCode, and AbortReason<br>
> >> +cleanup:<br>
> >> +    if (EFI_ERROR (Status)) {<br>
> >> +      *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +    }<br>
> >> +<br>
> >> +    return Status;<br>
> >> +}// SetImageWithStatus()<br>
> >> +<br>
> >> +<br>
> >>   /**<br>
> >>   Updates the firmware image of the device.<br>
> >><br>
> >> @@ -396,51 +523,98 @@ IN  UINT32                                           CapsuleFwVersion,<br>
> >>   OUT CHAR16                                           **AbortReason<br>
> >>   )<br>
> >>   {<br>
> >> -    EFI_STATUS Status                         = EFI_SUCCESS;<br>
> >> -    UINT32 Updateable                         = 0;<br>
> >> -<br>
> >> -    Status = FmpDeviceCheckImage(Image, ImageSize, &Updateable);<br>
> >> -    if (EFI_ERROR(Status))<br>
> >> -    {<br>
> >> -        DEBUG((DEBUG_ERROR, "SetImage - Check Image failed with %r.\n", Status));<br>
> >> -        goto cleanup;<br>
> >> -    }<br>
> >> -<br>
> >> -    if (Updateable != IMAGE_UPDATABLE_VALID)<br>
> >> -    {<br>
> >> -        DEBUG((DEBUG_ERROR, "SetImage - Check Image returned that the Image was not valid for update.  Updatable value<br>
> =<br>
> >> 0x%X.\n", Updateable));<br>
> >> -        Status = EFI_ABORTED;<br>
> >> -        goto cleanup;<br>
> >> -    }<br>
> >> -<br>
> >> -    if (Progress == NULL)<br>
> >> -    {<br>
> >> -        DEBUG((DEBUG_ERROR, "SetImage - Invalid progress callback\n"));<br>
> >> -        Status = EFI_INVALID_PARAMETER;<br>
> >> -        goto cleanup;<br>
> >> -    }<br>
> >> -<br>
> >> -    Status = Progress(15);<br>
> >> -    if (EFI_ERROR(Status))<br>
> >> -    {<br>
> >> -        DEBUG((DEBUG_ERROR, "SetImage - Progress Callback failed with Status %r.\n", Status));<br>
> >> -    }<br>
> >> -<br>
> >> -    {<br>
> >> -      UINTN  p;<br>
> >> -<br>
> >> -      for (p = 20; p < 100; p++) {<br>
> >> -        gBS->Stall (100000);  //us  = 0.1 seconds<br>
> >> -        Progress (p);<br>
> >> -      }<br>
> >> -    }<br>
> >> -<br>
> >> -    //TODO: add support for VendorCode, and AbortReason<br>
> >> -cleanup:<br>
> >> -    return Status;<br>
> >> +  UINT32  LastAttemptStatus;<br>
> >> +<br>
> >> +  return  FmpDeviceSetImageWithStatus (<br>
> >> +            Image,<br>
> >> +            ImageSize,<br>
> >> +            VendorCode,<br>
> >> +            Progress,<br>
> >> +            CapsuleFwVersion,<br>
> >> +            AbortReason,<br>
> >> +            &LastAttemptStatus<br>
> >> +            );<br>
> >>   }// SetImage()<br>
> >><br>
> >><br>
> >> +/**<br>
> >> +  Checks if a new firmware image is valid for the firmware device.  This<br>
> >> +  function allows firmware update operation to validate the firmware image<br>
> >> +  before FmpDeviceSetImage() is called.<br>
> >> +<br>
> >> +  @param[in]  Image               Points to a new firmware image.<br>
> >> +  @param[in]  ImageSize           Size, in bytes, of a new firmware image.<br>
> >> +  @param[out] ImageUpdatable      Indicates if a new firmware image is valid for<br>
> >> +                                  a firmware update to the firmware device.  The<br>
> >> +                                  following values from the Firmware Management<br>
> >> +                                  Protocol are supported:<br>
> >> +                                    IMAGE_UPDATABLE_VALID<br>
> >> +                                    IMAGE_UPDATABLE_INVALID<br>
> >> +                                    IMAGE_UPDATABLE_INVALID_TYPE<br>
> >> +                                    IMAGE_UPDATABLE_INVALID_OLD<br>
> >> +                                    IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE<br>
> >> +  @param[out] LastAttemptStatus   A pointer to a UINT32 that holds the last attempt<br>
> >> +                                  status to report back to the ESRT table in case<br>
> >> +                                  of error. This value will only be checked when this<br>
> >> +                                  function returns an error.<br>
> >> +<br>
> >> +                                  The return status code must fall in the range of<br>
> >> +                                  LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to<br>
> >> +                                  LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE.<br>
> >> +<br>
> >> +                                  If the value falls outside this range, it will be converted<br>
> >> +                                  to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL.<br>
> >> +<br>
> >> +  @retval EFI_SUCCESS            The image was successfully checked.  Additional<br>
> >> +                                 status information is returned in<br>
> >> +                                 ImageUpdatable.<br>
> >> +  @retval EFI_INVALID_PARAMETER  Image is NULL.<br>
> >> +  @retval EFI_INVALID_PARAMETER  ImageUpdatable is NULL.<br>
> >> +  @retval EFI_INVALID_PARAMETER  LastAttemptStatus is NULL.<br>
> >> +<br>
> >> +**/<br>
> >> +EFI_STATUS<br>
> >> +EFIAPI<br>
> >> +FmpDeviceCheckImageWithStatus (<br>
> >> +  IN  CONST VOID  *Image,<br>
> >> +  IN  UINTN       ImageSize,<br>
> >> +  OUT UINT32      *ImageUpdatable,<br>
> >> +  OUT UINT32      *LastAttemptStatus<br>
> >> +  )<br>
> >> +{<br>
> >> +    EFI_STATUS status = EFI_SUCCESS;<br>
> >> +<br>
> >> +    if (LastAttemptStatus == NULL) {<br>
> >> +      DEBUG ((DEBUG_ERROR, "CheckImageWithStatus - LastAttemptStatus Pointer Parameter is NULL.\n"));<br>
> >> +      return EFI_INVALID_PARAMETER;<br>
> >> +    }<br>
> >> +    *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;<br>
> >> +<br>
> >> +    if (ImageUpdatable == NULL)<br>
> >> +    {<br>
> >> +        DEBUG((DEBUG_ERROR, "CheckImageWithStatus - ImageUpdatable Pointer Parameter is NULL.\n"));<br>
> >> +        *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +        status = EFI_INVALID_PARAMETER;<br>
> >> +        goto cleanup;<br>
> >> +    }<br>
> >> +<br>
> >> +    //<br>
> >> +    //Set to valid and then if any tests fail it will update this flag.<br>
> >> +    //<br>
> >> +    *ImageUpdatable = IMAGE_UPDATABLE_VALID;<br>
> >> +<br>
> >> +    if (Image == NULL)<br>
> >> +    {<br>
> >> +        DEBUG((DEBUG_ERROR, "CheckImageWithStatus - Image Pointer Parameter is NULL.\n"));<br>
> >> +        *ImageUpdatable = IMAGE_UPDATABLE_INVALID; //not sure if this is needed<br>
> >> +        *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE;<br>
> >> +        return EFI_INVALID_PARAMETER;<br>
> >> +    }<br>
> >> +<br>
> >> +cleanup:<br>
> >> +    return status;<br>
> >> +}// CheckImageWithStatus()<br>
> >> +<br>
> >><br>
> >>   /**<br>
> >>   Checks if the firmware image is valid for the device.<br>
> >> @@ -465,29 +639,9 @@ IN  UINTN                             ImageSize,<br>
> >>   OUT UINT32                            *ImageUpdateable<br>
> >>   )<br>
> >>   {<br>
> >> -    EFI_STATUS status = EFI_SUCCESS;<br>
> >> +  UINT32  LastAttemptStatus;<br>
> >><br>
> >> -    if (ImageUpdateable == NULL)<br>
> >> -    {<br>
> >> -        DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is NULL.\n"));<br>
> >> -        status = EFI_INVALID_PARAMETER;<br>
> >> -        goto cleanup;<br>
> >> -    }<br>
> >> -<br>
> >> -    //<br>
> >> -    //Set to valid and then if any tests fail it will update this flag.<br>
> >> -    //<br>
> >> -    *ImageUpdateable = IMAGE_UPDATABLE_VALID;<br>
> >> -<br>
> >> -    if (Image == NULL)<br>
> >> -    {<br>
> >> -        DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n"));<br>
> >> -        *ImageUpdateable = IMAGE_UPDATABLE_INVALID; //not sure if this is needed<br>
> >> -        return EFI_INVALID_PARAMETER;<br>
> >> -    }<br>
> >> -<br>
> >> -cleanup:<br>
> >> -    return status;<br>
> >> +  return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdateable, &LastAttemptStatus);<br>
> >>   }// CheckImage()<br>
> >><br>
> >>   /**<br>
> >> --<br>
> >> 2.28.0.windows.1<br>
> ><br>
<br>
<br style="mso-special-character:line-break">
<![if !supportLineBreakNewLine]><br style="mso-special-character:line-break">
<![endif]><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal"></o:p></span></p>
</div>
</div>
</body>
</html>


 <div width="1" style="color:white;clear:both">_._,_._,_</div> <hr> Groups.io Links:<p>   You receive all messages sent to this group.    <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/67293">View/Reply Online (#67293)</a> |    |  <a target="_blank" href="https://groups.io/mt/77251053/1813853">Mute This Topic</a>  | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>    <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |  <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>  [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>