Dear coreboot developers,

With Raptor Lake, we introduced the Pre-Memory Sign-of-Life feature which 
displays an on-screen message while firmware components such as coreboot, 
Firmware Support Package Memory (FSP-M) or, CSME perform long time operations 
during pre-memory stages.

We propose to take advantage of a proprietary driver Intel already supports, 
validates and includes in FSP silicon: the Intel Graphics PEIM (Pre-EFI 
Initialization Module) driver also known as the GOP (Graphical Output Protocol) 
driver.

This driver is designed to run in post-memory initialization stages. Therefore, 
we derived a new version capable of running in pre-memory stages which we 
called microGOP. This version is specifically designed to perform graphics 
legacy VGA initialization.

We intend to keep providing such a binary base solution on the long run as it 
addresses our software convergence goals and is compatible with early platform 
development stage constraints. [libgfxinit] supports can always be added later 
by the open-source community once the Graphics Programmer Reference Manuals are 
published.

Below, we present the work we performed to run this microGOP driver from 
coreboot romstage. It allows to initialize graphics with a very similar flow 
compared to [libgfxinit] use.

Our goal is to start collecting feedback. We will release all the patches on 
coreboot.org under the [ugop] topic soon.


[libgfxinit] <https://github.com/coreboot/libgfxinit>

[ugop] <https://review.coreboot.org/q/topic:ugop>


1 microGOP driver interface
===========================

The uGOP PEIM provides the following PEIM-to-PEIM protocol under the 
`31a4622d-0e21-40a2-80db-c44208fce1b5' GUID.

,----
| #define PEI_PREMEM_GRAPHICS_PPI_GUID \
| { \
|   0x31a4622d, 0x0e21, 0x40a2, 0x80, 0xdb, 0xc4, 0x42, 0x08, 0xfc, 0xe1, 0xb5 \
| };
`----

The protocol is composed of three fields.

,----
| struct {
|   UINT32                    Version;
|   PREMEM_PEI_GRAPHICS_INIT  PreMemGraphicsPpiInit;
|   PREMEM_PEI_GRAPHICS_EXIT  PreMemGraphicsPpiExit;
| } PEI_MICRO_GRAPHICS_PPI;
`----

1. The current `Version' is `0x00010000'. Where the upper 16 bits represent the 
major (1) and the lower 16 bits represent the minor number.
2. `PreMemGraphicsPpiInit()'
   ,----
   | typedef
   | EFI_STATUS
   | (EFIAPI *PREMEM_PEI_GRAPHICS_INIT) (
   |   IN  VOID  *Vbt
   | );
   `----
   The `PreMemGraphicsPpiInit()' should be supplied with a pointer to the Video 
BIOS Table.
3. `PreMemGraphicsPpiExit()' does not take any parameters. This function must 
be called to disable VGA graphics configuration once not necessary anymore. Not 
performing this operation may lead to undesirable behaviour when other graphics 
stack starts (GOP in FSP-S or Operating System driver).


2 Integration
=============

As we intend to run microGOP driver in romstage, we want to keep the required 
coreboot code as small and efficient as possible. For this reason, we discarded 
re-using the EDK2 code which would have a major impact on the romstage binary 
size in addition to adding complication to the build scripts. Instead, we 
implemented a limited set of Pre-EFI Initialization services. The code is small 
and designed to accommodate a simple PEIM driver such as microGOP.


2.1 PEI services
~~~~~~~~~~~~~~~~

microGOP depends on a limited of PEI services:
1. `InstallPpi()' to install the PEIM Graphics PPI
2. `LocatePpi()' to access PEIM-to-PEIM Interface (PPI) Dependencies
3. `AllocatePool()' to dynamically allocate memory to handle internal data 
structure such as display information ...
4. `GetHobList()' and  `CreateHob()' to access Hand Off Blocks (HOB) holding 
runtime data
5. `ReportStatusCode()' to report debug information which coreboot prints using 
`printk'.
Those services implemented in coreboot are pretty straightforward and fit in 
less than 300 lines of code.


2.2 PEI services pointer
~~~~~~~~~~~~~~~~~~~~~~~~

microGOP expects to find the PEI services pointer in the architecture size word 
immediately preceding the Interrupt Descriptor Table (IDT) (cf. [Platform 
Initialization (PI) Specification] *5.4 PEI Services Table Retrieval*). Since 
[coreboot x86/exception] module already sets up the IDT and as we do not want 
to disrupt this configuration we create a copy of the IDT. But we include an 
extra architecture size word preceding the table to store the PEI services 
pointer.

Note that FSP memory installs its own IDT but it backups and restores the one 
we have set up. Therefore, there is no risk of having PEI services pointer 
conflicts.


[Platform Initialization (PI) Specification] 
<https://uefi.org/sites/default/files/resources/PI_Spec_1_6.pdf>

[coreboot x86/exception] 
<https://github.com/coreboot/coreboot/blob/master/src/arch/x86/exception.c>


2.3 Portable Executable Relocation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As we need to execute the microGOP binary in place, we need to perform a 
relocation operation of the Portable Executable binary. Since memory space is 
limited in the pre-memory stages, it is preferable to perform a static 
relocation operation during the firmware stitching operation.

Fortunately, most of the logic and code is already available as this operation 
is performed on the FSP-M binary. We only have to add explicit support for EFI 
binaries (cf. [76762 cbfstool: Add relocation support for EFI binaries]).


[76762 cbfstool: Add relocation support for EFI binaries] 
<https://review.coreboot.org/c/coreboot/+/76762>


2.4 Uncompressed VBT
~~~~~~~~~~~~~~~~~~~~

As microGOP requires the Video BIOS Table (VBT) and since memory space is 
limited in the pre-memory stages, it is preferable to keep VBT in uncompressed 
form in CBFS. We introduced the `CONFIG_VBT_CBFS_COMPRESSION' configuration 
entry to allow this (cf. [76816 drivers/intel/gma/Kconfig: Add VBT compression 
configuration entry]).


[76816 drivers/intel/gma/Kconfig: Add VBT compression configuration entry] 
<https://review.coreboot.org/c/coreboot/+/76816>


3 Code flow
===========

<file:./code-flow.svg>


4 Performances analysis
=======================

The analysis below is based on a microGOP binary with eDP and HDMI support.


4.1 Size impact
~~~~~~~~~~~~~~~

When `CONFIG_UGOP_EARLY_GRAPHICS' is set
1. `ugop.efi' is included as a CBFS file
2. `romstage' includes extra code: `pei.c', `ugop.c' and `ux.c'
3. `vbt.bin' is stored uncompressed instead of lzma compressed

 CBFS File  UGOP_EARLY_GRAPHICS=n (bytes)  UGOP_EARLY_GRAPHICS=y (bytes)  Delta 
(bytes) 
----------------------------------------------------------------------------------------
 microGOP                               0                          68448        
  68448 
 romstage                          126128                         136256        
  10128 
 vbt.bin                             1264                           9216        
   7952 
----------------------------------------------------------------------------------------
 *Total*                           127392                         213920        
*86528* 

The use of microGOP in coreboot represents a size increase of around 84 KB per 
region (`COREBOOT', `FW_MAIN_A' and `FW_MAIN_B').


4.2 Regular Boot time impact (no Sign-of-Life)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On a Meteor Lake Google Rex board, we performed 5 warm reset cycles (without 
and with `CONFIG_UGOP_EARLY_GRAPHICS'  set) and we collected the `cbmem -t' 
outputs. We computed the median time of each duration (time between two 
timestamps) and then performed a comparison with a threshold of 0.5 ms.

 Start ID  Start Description                                End ID  End 
Description                           Delta (ms) 
-------------------------------------------------------------------------------------------------------------------------
      947  CSE received 'CPU Reset Done Ack sent' from PMC     991  Die 
Management Unit (DMU) load completed        +1.0 
      507  starting to verify body (load+SHA2+RSA)             508  finished 
loading body                           +4.7 
      510  finished verifying body signature (RSA)             511  starting 
TPM PCR extend                         -0.8 
     1030  finished EC verification                           1040  finished 
storage device initialization          +1.4 

The only relevant impact is the verification of the image (507 -> 508): +4.7 ms 
and it can be explained by the 84 KB size increase of the image.

Overall the boot time impact is about 5 ms and concentrated on `verstage'.


4.3 Cache-As-Ram
~~~~~~~~~~~~~~~~

For microGOP to execute properly, we have to provide some memory allocation 
services (`allocate_pool' and `create_hob'). These services relies on 
cache-as-ram memory reservation (`.bss' section). We looked at the two new 
object files:

 Object file  .bss section size (bytes) 
----------------------------------------
 pei.o                             6730 
 ugop.o                               9 
----------------------------------------
                                 *6739* 

With microGOP sign-of-life, there is an extra 7 KB cache-as-ram use.


4.4 Conclusion
~~~~~~~~~~~~~~

The SPINOR and cache-as-RAM space use along with the boot performance penalty 
are limited and comparable to what it would be with libgfxinit.

We also noticed that microGOP is faster to bring-up graphics than libgfxinit. 
Indeed, according to previously captured numbers on Raptor Lake compared to 
some number of microGOP on Meteor Lake, microGOP is three times faster to bring 
up graphics than libgfxinit on an eDP panel (119 ms vs 373 ms).


5 Summary
=========

This Sign-of-Life microGOP driver based implementation presents the following 
advantages:
- it needs a limited code addition
- it has a limited impact on the performance
- its flow and boot performance impact is comparable to libgfxinit solution
- it is compatible with our software convergence goals
- it can be available during new platform development early stages which help 
our partners to test the feature and stabilize the platform

Regards,

-- 
*Jeremy*
/One Emacs to rule them all/
_______________________________________________
coreboot mailing list -- coreboot@coreboot.org
To unsubscribe send an email to coreboot-le...@coreboot.org

Reply via email to