VirtualBox

Ignore:
Timestamp:
Aug 28, 2012 4:04:45 AM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
80355
Message:

EFI/OVMF: introduces NVRAM mechanism in DevOVMF.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/DevOVMF.cpp

    r42443 r43021  
    3838#include <iprt/string.h>
    3939#include <iprt/mp.h>
     40#include <iprt/list.h>
    4041#ifdef DEBUG
    4142# include <iprt/stream.h>
     
    4344#endif
    4445
     46#define VBOX_WITH_OVMF
    4547#include "Firmware2/VBoxPkg/Include/DevEFI.h"
    4648#include "VBoxDD.h"
     
    5355#include <Common/PiFirmwareVolume.h>
    5456#include <Common/PiFirmwareFile.h>
    55 
    5657/*******************************************************************************
    5758*   Structures and Typedefs                                                    *
    5859*******************************************************************************/
     60typedef struct {
     61        RTLISTNODE List;
     62        EFIVAROP enmOp;
     63        uint32_t u32Status;
     64        RTUUID   uuid;
     65        char     szVariableName[1024];
     66        uint32_t cbVariableName;
     67        uint8_t  au8Value[1024];
     68        uint32_t cbValue;
     69        uint32_t u32Attribute;
     70        uint32_t idxOpBuffer;
     71} EFIVAR, *PEFIVAR;
     72
     73typedef PEFIVAR *PPEFIVAR;
     74
    5975typedef struct DEVEFI
    6076{
     
    127143    uint32_t        u32UgaHorisontal;
    128144    uint32_t        u32UgaVertical;
     145    uint32_t        idxVariableName;
     146    EFIVAR          OperationVarOp;
     147    RTLISTANCHOR    NVRAMVariableList;
     148    PEFIVAR         pCurrentVarOp;
    129149} DEVEFI;
    130150typedef DEVEFI *PDEVEFI;
     
    143163}
    144164
    145 
     165/**
     166 * This function looks up variable in NVRAM list
     167 */
     168static int nvramLookupVariableByUuidAndName(PDEVEFI pThis, char *pszVariableName, PCRTUUID pUuid, PPEFIVAR ppEfiVar)
     169{
     170    int rc = VERR_NOT_FOUND;
     171    PEFIVAR pEfiVar = NULL;
     172    LogFlowFunc(("pszVariableName:%s, pUuid:%RTuuid\n", pszVariableName, pUuid));
     173    RTListForEach((PRTLISTNODE)&pThis->NVRAMVariableList, pEfiVar, EFIVAR, List)
     174    {
     175        LogFlowFunc(("pEfiVar:%p\n", pEfiVar));
     176        if (   pEfiVar
     177            && RTUuidCompare(pUuid, &pEfiVar->uuid) == 0
     178            && RTStrCmp(pszVariableName, pEfiVar->szVariableName) == 0)
     179        {
     180            *ppEfiVar = pEfiVar;
     181            rc = VINF_SUCCESS;
     182            break;
     183        }
     184    }
     185    LogFlowFuncLeaveRC(rc);
     186    return rc;
     187}
    146188static uint32_t efiInfoSize(PDEVEFI pThis)
    147189{
     
    266308            return VINF_SUCCESS;
    267309
    268        case EFI_PANIC_PORT:
     310        case EFI_PANIC_PORT:
    269311#ifdef IN_RING3
    270312           LogRel(("Panic port read!\n"));
     
    275317           return VINF_IOM_R3_IOPORT_READ;
    276318#endif
     319        case EFI_VARIABLE_OP:
     320            switch (pThis->OperationVarOp.enmOp)
     321            {
     322                case EFI_VM_VARIABLE_OP_START:
     323                /* @todo: nop ? */
     324                    *pu32 = pThis->OperationVarOp.u32Status;
     325                break;
     326                case EFI_VM_VARIABLE_OP_END:
     327                break;
     328                case EFI_VM_VARIABLE_OP_INDEX:
     329                break;
     330                case EFI_VM_VARIABLE_OP_GUID:
     331                    *pu32 = pThis->OperationVarOp.uuid.au8[pThis->OperationVarOp.idxOpBuffer];
     332                    pThis->OperationVarOp.idxOpBuffer++;
     333                break;
     334                case EFI_VM_VARIABLE_OP_ATTRIBUTE:
     335                    *pu32 = pThis->OperationVarOp.u32Attribute;
     336                break;
     337                case EFI_VM_VARIABLE_OP_NAME:
     338                    *pu32 = pThis->OperationVarOp.szVariableName[pThis->OperationVarOp.idxOpBuffer];
     339                    pThis->OperationVarOp.idxOpBuffer++;
     340                break;
     341                case EFI_VM_VARIABLE_OP_NAME_LENGTH:
     342                    *pu32 = pThis->OperationVarOp.cbVariableName;
     343                break;
     344                case EFI_VM_VARIABLE_OP_VALUE:
     345                    //LogFlowFunc(("OperationVarOp:idxOpBuffer:%d\n", pThis->OperationVarOp.idxOpBuffer));
     346                    *pu32 = pThis->OperationVarOp.au8Value[pThis->OperationVarOp.idxOpBuffer];
     347                    pThis->OperationVarOp.idxOpBuffer++;
     348                break;
     349                case EFI_VM_VARIABLE_OP_VALUE_LENGTH:
     350                    LogFlowFunc(("cbValue: %d\n", pThis->OperationVarOp.cbValue));
     351                    *pu32 = pThis->OperationVarOp.cbValue;
     352                break;
     353                default:
     354                break;
     355            }
     356            //*pu32 = pThis->OperationVarOp.u32Status;
     357            return VINF_SUCCESS;
     358        case EFI_VARIABLE_PARAM:
     359        {
     360            break;
     361        }
     362        return VINF_SUCCESS;
    277363    }
    278364
     
    404490            break;
    405491        }
     492        case EFI_VARIABLE_OP:
     493        {
     494            /* clear buffer index */
     495            Assert(u32 < EFI_VM_VARIABLE_OP_MAX);
     496            if (u32 >= EFI_VM_VARIABLE_OP_MAX)
     497            {
     498                u32 = EFI_VARIABLE_OP_STATUS_ERROR;
     499                break;
     500            }
     501            pThis->OperationVarOp.idxOpBuffer = 0;
     502            pThis->OperationVarOp.enmOp = (EFIVAROP)u32;
     503        }
     504        break;
     505        case EFI_VARIABLE_PARAM:
     506        {
     507            switch (pThis->OperationVarOp.enmOp)
     508            {
     509                case EFI_VM_VARIABLE_OP_START:
     510                {
     511                    pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_BSY;
     512                    switch (u32)
     513                    {
     514                        case EFI_VARIABLE_OP_QUERY:
     515                        {
     516                            LogRel(("EFI: variable lookup %RTuuid, %s\n",
     517                                    &pThis->OperationVarOp.uuid,
     518                                    pThis->OperationVarOp.szVariableName));
     519                            pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_BSY;
     520                            PEFIVAR pEfiVar = NULL;
     521                            memset(pThis->OperationVarOp.au8Value, 0, 1024);
     522                            int nvramRc = nvramLookupVariableByUuidAndName(
     523                                                pThis,
     524                                                pThis->OperationVarOp.szVariableName,
     525                                                &pThis->OperationVarOp.uuid,
     526                                                &pEfiVar);
     527                            if (RT_SUCCESS(nvramRc))
     528                            {
     529                                pThis->OperationVarOp.u32Attribute = pEfiVar->u32Attribute;
     530                                pThis->OperationVarOp.cbVariableName = pEfiVar->cbVariableName;
     531                                pThis->OperationVarOp.cbValue = pEfiVar->cbValue;
     532                                memcpy(pThis->OperationVarOp.au8Value,
     533                                       pEfiVar->au8Value, pEfiVar->cbValue);
     534                                pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_OK;
     535                                pThis->pCurrentVarOp = pEfiVar;
     536                                LogFlowFunc(("OperationVar: au8Value:%.*Rhxs\n",
     537                                              pThis->OperationVarOp.cbValue,
     538                                              pThis->OperationVarOp.au8Value));
     539                            }
     540                            else
     541                                pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_NOT_FOUND;
     542                        }
     543                        break;
     544                        case EFI_VARIABLE_OP_ADD:
     545                        {
     546                            LogRel(("EFI: variable add %RTuuid, %s\n", &pThis->OperationVarOp.uuid, pThis->OperationVarOp.szVariableName));
     547                            PEFIVAR pEfiVar = NULL;
     548                            LogFlowFunc(("OperationVar: au8Value:%.*Rhxs\n",
     549                                          pThis->OperationVarOp.cbValue,
     550                                          pThis->OperationVarOp.au8Value));
     551                            int nvramRc = nvramLookupVariableByUuidAndName(
     552                                                pThis,
     553                                                pThis->OperationVarOp.szVariableName,
     554                                                &pThis->OperationVarOp.uuid,
     555                                                &pEfiVar);
     556                            if (RT_SUCCESS(nvramRc))
     557                            {
     558                                /* delete or update ? */
     559                                /* @todo: check whether pEfiVar is WP */
     560                                LogFlowFunc(("pEfiVar: au8Value:%.*Rhxs\n",
     561                                             pEfiVar->cbValue,
     562                                             pEfiVar->au8Value));
     563                                if (pThis->OperationVarOp.cbValue == 0)
     564                                {
     565                                    /* delete */
     566                                    RTListNodeRemove(&pEfiVar->List);
     567                                    RTMemFree(pEfiVar);
     568                                    pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_OK;
     569                                }
     570                                else
     571                                {
     572                                    /* update */
     573                                    pEfiVar->cbValue = pThis->OperationVarOp.cbValue;
     574                                    memcpy(pEfiVar->au8Value, pThis->OperationVarOp.au8Value, pEfiVar->cbValue);
     575                                    pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_OK;
     576                                }
     577                            }
     578                            else
     579                            {
     580                                if (pThis->OperationVarOp.cbValue != 0)
     581                                {
     582                                    pEfiVar = (PEFIVAR)RTMemAllocZ(sizeof(EFIVAR));
     583                                    if (!pEfiVar)
     584                                    {
     585                                        pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_ERROR;
     586                                        break;
     587                                    }
     588                                }
     589                                else
     590                                {
     591                                    pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_OK;
     592                                    break;
     593                                }
     594
     595                                memcpy(pEfiVar, &pThis->OperationVarOp, sizeof(EFIVAR));
     596                                RTListInit(&pEfiVar->List);
     597                                RTListAppend(&pThis->NVRAMVariableList, &pEfiVar->List);
     598                                pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_OK;
     599                            }
     600                        }
     601                        break;
     602                        case EFI_VARIABLE_OP_QUERY_NEXT:
     603                        {
     604                            PEFIVAR pEfiVar = RTListNodeGetNext(&pThis->pCurrentVarOp->List, EFIVAR, List);
     605                            if (pEfiVar)
     606                            {
     607                                memcpy(&pThis->OperationVarOp, pEfiVar, sizeof(EFIVAR));
     608                                pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_OK;
     609                            }
     610                            else
     611                                pThis->OperationVarOp.u32Status = EFI_VARIABLE_OP_STATUS_NOT_FOUND;
     612                        }
     613                        break;
     614                        default:
     615                            /* @todo: return error */
     616                            break;
     617                    }
     618                }
     619                case EFI_VM_VARIABLE_OP_END:
     620                break;
     621                case EFI_VM_VARIABLE_OP_INDEX:
     622                break;
     623                case EFI_VM_VARIABLE_OP_GUID:
     624                    pThis->OperationVarOp.uuid.au8[pThis->OperationVarOp.idxOpBuffer] = (uint8_t)u32;
     625                    pThis->OperationVarOp.idxOpBuffer++;
     626                break;
     627                case EFI_VM_VARIABLE_OP_ATTRIBUTE:
     628                    pThis->OperationVarOp.u32Attribute = u32;
     629                break;
     630                case EFI_VM_VARIABLE_OP_NAME:
     631                    pThis->OperationVarOp.szVariableName[pThis->OperationVarOp.idxOpBuffer] = (uint8_t)u32;
     632                    pThis->OperationVarOp.idxOpBuffer++;
     633                break;
     634                case EFI_VM_VARIABLE_OP_NAME_LENGTH:
     635                    pThis->OperationVarOp.cbVariableName = u32;
     636                    memset(pThis->OperationVarOp.szVariableName, 0, 1024);
     637                break;
     638                case EFI_VM_VARIABLE_OP_VALUE:
     639                    pThis->OperationVarOp.au8Value[pThis->OperationVarOp.idxOpBuffer] = (uint8_t)u32;
     640                    pThis->OperationVarOp.idxOpBuffer++;
     641                break;
     642                case EFI_VM_VARIABLE_OP_VALUE_LENGTH:
     643                    pThis->OperationVarOp.cbValue = u32;
     644                    memset(pThis->OperationVarOp.au8Value, 0, 1024);
     645                break;
     646                default:
     647                break;
     648            }
     649        }
     650        break;
    406651
    407652        default:
     
    8271072    uuid.Gen.u16TimeHiAndVersion = RT_H2BE_U16(uuid.Gen.u16TimeHiAndVersion);
    8281073    memcpy(&pThis->aUuid, &uuid, sizeof pThis->aUuid);
     1074    RTListInit((PRTLISTNODE)&pThis->NVRAMVariableList);
     1075    //pThis->pCurrentVarOp = RTListGetFirst((PRTLISTNODE)&pThis->NVRAMVariableList, List);
    8291076
    8301077
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette